From 4efafd333e840b2fcfa8f50d2d6db56f0b1c1a3b Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 3 Nov 2011 01:50:57 +0000 Subject: [PATCH] Add (and use) some new PIC32MX CP0 macros git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4079 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/arch/mips/include/mips32/irq.h | 68 +++++++++++- nuttx/arch/mips/include/pic32mx/irq.h | 120 ++++++++++++++++++++++ nuttx/arch/mips/src/pic32mx/pic32mx-irq.c | 33 ++++-- 3 files changed, 210 insertions(+), 11 deletions(-) diff --git a/nuttx/arch/mips/include/mips32/irq.h b/nuttx/arch/mips/include/mips32/irq.h index 7b869a3b9..27f55beba 100755 --- a/nuttx/arch/mips/include/mips32/irq.h +++ b/nuttx/arch/mips/include/mips32/irq.h @@ -338,7 +338,7 @@ struct xcptcontext * Name: cp0_getstatus * * Description: - * Disable interrupts + * Read the CP0 STATUS register * * Input Parameters: * None @@ -355,7 +355,7 @@ static inline irqstate_t cp0_getstatus(void) ( "\t.set push\n" "\t.set noat\n" - "\t mfc0 %0,$12\n" /* Get CP0 status register */ + "\t mfc0 %0, $12, 0\n" /* Get CP0 status register */ "\t.set pop\n" : "=r" (status) : @@ -369,7 +369,7 @@ static inline irqstate_t cp0_getstatus(void) * Name: cp0_putstatus * * Description: - * Disable interrupts + * Write the CP0 STATUS register * * Input Parameters: * None @@ -386,7 +386,7 @@ static inline void cp0_putstatus(irqstate_t status) "\t.set push\n" "\t.set noat\n" "\t.set noreorder\n" - "\tmtc0 %0,$12\n" /* Set the status to the provided value */ + "\tmtc0 %0, $12, 0\n" /* Set the status to the provided value */ "\tnop\n" /* MTC0 status hazard: */ "\tnop\n" /* Recommended spacing: 3 */ "\tnop\n" @@ -398,6 +398,66 @@ static inline void cp0_putstatus(irqstate_t status) ); } +/**************************************************************************** + * Name: cp0_getcause + * + * Description: + * Get the CP0 CAUSE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t cp0_getcause(void) +{ + register irqstate_t cause; + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t mfc0 %0, $13, 0\n" /* Get CP0 cause register */ + "\t.set pop\n" + : "=r" (cause) + : + : "memory" + ); + + return cause; +} + +/**************************************************************************** + * Name: cp0_putcause + * + * Description: + * Write the CP0 CAUSE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp0_putcause(uint32_t cause) +{ + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t.set noreorder\n" + "\tmtc0 %0, $13, 0\n" /* Set the cause to the provided value */ + "\t.set pop\n" + : + : "r" (cause) + : "memory" + ); +} + /**************************************************************************** * Public Variables ****************************************************************************/ diff --git a/nuttx/arch/mips/include/pic32mx/irq.h b/nuttx/arch/mips/include/pic32mx/irq.h index 064dd72c5..e4c39e36e 100755 --- a/nuttx/arch/mips/include/pic32mx/irq.h +++ b/nuttx/arch/mips/include/pic32mx/irq.h @@ -67,6 +67,126 @@ * Inline functions ****************************************************************************/ +/**************************************************************************** + * Name: cp0_getintctl + * + * Description: + * Get the CP0 IntCtl register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t cp0_getintctl(void) +{ + register irqstate_t ebase; + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t mfc0 %0, $12, 1\n" /* Get CP0 IntCtl register */ + "\t.set pop\n" + : "=r" (ebase) + : + : "memory" + ); + + return cause; +} + +/**************************************************************************** + * Name: cp0_putintctl + * + * Description: + * Write the CP0 IntCtl register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp0_putintctl(uint32_t ebase) +{ + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t.set noreorder\n" + "\tmtc0 %0, $12, 1\n" /* Set the IntCtl to the provided value */ + "\t.set pop\n" + : + : "r" (ebase) + : "memory" + ); +} + +/**************************************************************************** + * Name: cp0_getebase + * + * Description: + * Get the CP0 EBASE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline uint32_t cp0_getebase(void) +{ + register irqstate_t ebase; + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t mfc0 %0, $15, 1\n" /* Get CP0 EBASE register */ + "\t.set pop\n" + : "=r" (ebase) + : + : "memory" + ); + + return cause; +} + +/**************************************************************************** + * Name: cp0_putebase + * + * Description: + * Write the CP0 EBASE register + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void cp0_putebase(uint32_t ebase) +{ + __asm__ __volatile__ + ( + "\t.set push\n" + "\t.set noat\n" + "\t.set noreorder\n" + "\tmtc0 %0, $15, 1\n" /* Set the EBASE to the provided value */ + "\t.set pop\n" + : + : "r" (ebase) + : "memory" + ); +} + /**************************************************************************** * Public Variables ****************************************************************************/ diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c b/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c index 1681673fa..51b6467b5 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c @@ -107,14 +107,33 @@ void up_irqinitialize(void) { (void)up_prioritize_irq(irq, (INT_ICP_MID_PRIORITY << 2)); } - - /* Set the CP0 cause IV bit meaning that the interrupt exception uses - * the "special interrupt vector" - */ - - asm volatile("\tmfc0 %0,$13,0\n" : "=r"(regval)); + + /* Set the BEV bit in the STATUS register */ + + regval = cp0_getstatus(); + regval |= CP0_STATUS_BEV; + cp0_putstatus(regval); + + /* Set the EBASE value to the beginning of boot FLASH */ + + cp0_putebase(0xbfc00000); + + /* Set the INTCTL vector spacing to non-zero */ + + cp0_putintctl(0x00000020); + + /* Set the IV bit in the CAUSE register */ + + regval = cp0_getcause(); regval |= CP0_CAUSE_IV; - asm volatile("\tmtc0 %0,$13,0\n" : : "r"(regval)); + cp0_putcause(regval); + + /* Clear the EXL bit in the STATUS register */ + + regval = cp0_getstatus(); +//regval &= ~CP0_STATUS_BEV; + regval &= ~CP0_STATUS_EXL; + cp0_putstatus(regval); /* Configure multi- or single- vector interrupts */