Add (and use) some new PIC32MX CP0 macros

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4079 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-11-03 01:50:57 +00:00
parent 88fde06d5b
commit 2308f64512
3 changed files with 210 additions and 11 deletions

View File

@ -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
****************************************************************************/

View File

@ -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
****************************************************************************/

View File

@ -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 */