LM32: Fix implementation of up_irq_save() and up_irq_restore()

This commit is contained in:
Ramtin Amin
2016-11-04 10:54:10 -06:00
committed by Gregory Nutt
parent ddd8716189
commit b2126738cd
7 changed files with 90 additions and 24 deletions
+6 -1
View File
@@ -82,10 +82,11 @@
#define REG_X29_NDX 29 /* General-purpose/return address */
#define REG_X30_NDX 30 /* Exception address */
#define REG_X31_NDX 31 /* Breakpoint address */
#define REG_X32_NDX 32 /* Reg IE */
/* Interrupt Context register */
#define XCPTCONTEXT_REGS 32
#define XCPTCONTEXT_REGS 33
#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
#ifdef __ASSEMBLY__
@@ -121,6 +122,7 @@
# define REG_X29 (4*REG_X29_NDX)
# define REG_X30 (4*REG_X30_NDX)
# define REG_X31 (4*REG_X31_NDX)
# define REG_INT_CTX (4*REG_X32_NDX)
#else
# define REG_X0 REG_X0_NDX
# define REG_X1 REG_X1_NDX
@@ -154,6 +156,7 @@
# define REG_X29 REG_X29_NDX
# define REG_X30 REG_X30_NDX
# define REG_X31 REG_X31_NDX
# define REG_INT_CTX REG_X32_NDX
#endif
/* Register aliases */
@@ -176,6 +179,8 @@
#define REG_A6 REG_X7
#define REG_A7 REG_X8
#define REG_IE REG_INT_CTX
/****************************************************************************
* Public Types
****************************************************************************/
+1 -3
View File
@@ -58,9 +58,7 @@
uint32_t *lm32_doirq(int irq, uint32_t *regs)
{
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* g_current_regs is also used to manage interrupt level context switches.
*
+4
View File
@@ -99,6 +99,10 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[REG_EPC] = (uint32_t)tcb->start;
/* Initial state of IE: Interrupts enabled */
xcp->regs[REG_INT_CTX] = 1;
/* If this task is running PIC, then set the PIC base register to the
* address of the allocated D-Space region.
*/
+24 -8
View File
@@ -69,7 +69,7 @@ void lm32_irq_initialize(void)
g_current_regs = NULL;
/* Enable interrupt */
/* Enable interrupts */
irq_setie(1);
}
@@ -77,15 +77,22 @@ void lm32_irq_initialize(void)
irqstate_t up_irq_save(void)
{
irqstate_t flags;
irq_setie(0);
#warning Return value MUST be the previous IE value. Returning 1 will not work.
return 1;
/* Get the previous value of IE */
flags = irq_getie();
/* Disable interrupts and return the previous interrupt state */
irq_setie(0);
return flags;
}
void up_irq_restore(irqstate_t flags)
{
irq_setie(1);
/* Restore the interrupt state returned by up_save_irq() */
irq_setie(flags);
}
/****************************************************************************
@@ -99,8 +106,13 @@ void up_irq_restore(irqstate_t flags)
void up_disable_irq(int irq)
{
irqstate_t flags;
flags = irq_getmask();
flags &= ~(1 <<irq);
DEBUGASSERT(irq >= 0 && irq < NR_IRQS);
/* Disable interrupts by clearing the bit that corresponds to the irq */
flags = irq_getmask();
flags &= ~(1 << irq);
irq_setmask(flags);
}
@@ -115,7 +127,11 @@ void up_disable_irq(int irq)
void up_enable_irq(int irq)
{
irqstate_t flags;
flags = irq_getmask();
DEBUGASSERT(irq >= 0 && irq < NR_IRQS);
/* Enable interrupts by setting the bit that corresponds to the irq */
flags = irq_getmask();
flags |= (1 << irq);
irq_setmask(flags);
}
+1
View File
@@ -326,5 +326,6 @@ uint32_t *lm32_swint(int irq, FAR void *context)
*/
g_current_regs = NULL;
return regs;
}
+9 -4
View File
@@ -151,7 +151,7 @@ _do_reset:
bi os_start
.save_all:
addi sp, sp, -132
addi sp, sp, -136
sw (sp+REG_X0), r0
sw (sp+REG_X1), r1
sw (sp+REG_X2), r2
@@ -190,11 +190,14 @@ _do_reset:
/* ra needs to be moved from initial stack location */
lw r1, (sp+ 132)
lw r1, (sp+ 136)
sw (sp+REG_RA), r1
/* the 2nd argument is the regs pointer */
/* get IE/REG_INT_CTX */
rcsr r1, IE
sw (sp+REG_INT_CTX), r1
/* the 2nd argument is the regs pointer */
addi r2, sp, 0
ret
@@ -231,8 +234,10 @@ _do_reset:
lw r29, (r1+REG_RA)
lw r30, (r1+REG_EA)
lw r31, (r1+REG_BA)
lw r1, (r1+REG_INT_CTX)
wcsr IE, r1
lw r1, (r1+REG_X1)
addi sp, sp, 132
addi sp, sp, 136
eret
/* This global variable is unsigned long g_idle_topstack and is