From 58a68260c377481cb138217c4f1c3feb985b51fb Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 18 Jun 2011 20:02:40 +0000 Subject: [PATCH] Fix an error that caused interrupts to become disabled git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3724 42af7a65-404d-4744-a932-0658087f49c3 --- arch/avr/include/avr/irq.h | 52 +++++++++++----------- arch/avr/src/avr/excptmacros.h | 80 +++++++++++++++++++--------------- mm/mm_sem.c | 2 + 3 files changed, 74 insertions(+), 60 deletions(-) diff --git a/arch/avr/include/avr/irq.h b/arch/avr/include/avr/irq.h index d3026c1853..242114e98e 100644 --- a/arch/avr/include/avr/irq.h +++ b/arch/avr/include/avr/irq.h @@ -61,33 +61,33 @@ #define REG_R30 5 #define REG_R29 6 #define REG_R28 7 -#define REG_R25 8 /* r25 */ -#define REG_R23 9 /* r2-r23 */ -#define REG_R22 10 -#define REG_R21 11 -#define REG_R20 12 -#define REG_R19 13 -#define REG_R18 14 -#define REG_R17 15 -#define REG_R16 16 -#define REG_R15 17 -#define REG_R14 18 -#define REG_R13 19 -#define REG_R12 20 -#define REG_R11 21 -#define REG_R10 22 -#define REG_R9 23 -#define REG_R8 24 -#define REG_R7 25 -#define REG_R6 26 -#define REG_R5 27 -#define REG_R4 28 -#define REG_R3 29 -#define REG_R2 30 -#define REG_R1 31 /* r1 - the "zero" register */ +#define REG_R23 8 /* r2-r23 */ +#define REG_R22 9 +#define REG_R21 10 +#define REG_R20 11 +#define REG_R19 12 +#define REG_R18 13 +#define REG_R17 14 +#define REG_R16 15 +#define REG_R15 16 +#define REG_R14 17 +#define REG_R13 18 +#define REG_R12 19 +#define REG_R11 20 +#define REG_R10 21 +#define REG_R9 22 +#define REG_R8 23 +#define REG_R7 24 +#define REG_R6 25 +#define REG_R5 26 +#define REG_R4 27 +#define REG_R3 28 +#define REG_R2 29 +#define REG_R1 30 /* r1 - the "zero" register */ +#define REG_R0 31 /* r0 */ #define REG_SREG 32 /* Status register */ -#define REG_R0 33 /* r0 */ -#define REG_R24 34 /* r24 */ +#define REG_R25 33 /* r24-r25 */ +#define REG_R24 34 /* The program counter is automatically pushed when the interrupt occurs */ diff --git a/arch/avr/src/avr/excptmacros.h b/arch/avr/src/avr/excptmacros.h index b1d9583b80..2d55a81095 100755 --- a/arch/avr/src/avr/excptmacros.h +++ b/arch/avr/src/avr/excptmacros.h @@ -147,18 +147,22 @@ .macro EXCPT_PROLOGUE - /* Save R0 -- the scratch register */ + /* Save R25 */ - push r0 + push r25 /* Save the status register on the stack */ - in r0, _SFR_IO_ADDR(SREG) /* Save the status register */ - cli /* Disable interrupts */ + in r25, _SFR_IO_ADDR(SREG) /* Save the status register */ + cli /* Disable interrupts (not necessary) */ + ori r25, (1 << SREG_I) /* Interrupts re-enabled on restore */ + push r25 + + /* Save R0 -- the scratch register and the zero register (which may not be zero). R1 + * must be zero for our purposes + */ + push r0 - - /* Save R1 -- the zero register (which may not be zero). R1 must be zero for our purposes */ - push r1 clr r1 @@ -182,7 +186,7 @@ push r17 /* Save r18-r27 - Call-used, "volatile" registers (r24 was saved by - * HANDLER, r26-r27 saved later, out of sequence) + * HANDLER, r15 was saved above, and r26-r27 saved later, out of sequence) */ push r18 @@ -191,7 +195,6 @@ push r21 push r22 push r23 - push r25 /* Save r28-r29 - Call-saved, "static" registers */ @@ -210,17 +213,17 @@ /* Finally, save the stack pointer. BUT we want the value of the stack pointer as * it was just BEFORE the exception. We'll have to add to get that value. - * The value to add is the size of the register save area including the bytes - * pushed by the interrupt handler (2), by the HANDLER macro (1), and the 32 - * registers pushed above. That is, the entire size of the register save structure - * MINUS two bytes for the stack pointer which has not yet been saved. + * The value to add is the size of the register save area including the bytes + * pushed by the interrupt handler (2), by the HANDLER macro (1), and the 32 + * registers pushed above. That is, the entire size of the register save structure + * MINUS two bytes for the stack pointer which has not yet been saved. */ in r26, _SFR_IO_ADDR(SPL) in r27, _SFR_IO_ADDR(SPH) adiw r26, XCPTCONTEXT_REGS-2 - push r26 /* SPL then SPH */ + push r26 /* SPL then SPH */ push r27 .endm @@ -245,8 +248,8 @@ /* We don't need to restore the stack pointer */ - pop r27 /* Discard SPH */ - pop r26 /* Discard SPL */ + pop r27 /* Discard SPH */ + pop r26 /* Discard SPL */ /* Restore r26-r27 */ @@ -264,10 +267,9 @@ pop r28 /* Restore r18-r27 - Call-used, "volatile" registers (r26-r27 already - * restored, r24 will be restored later) + * restored, r24 and r25 will be restored later) */ - pop r25 pop r23 pop r22 pop r21 @@ -294,18 +296,20 @@ pop r3 pop r2 - /* Restore r1 - the "zero" register (that may not be zero) */ + /* Restore r0 - the scratch register and r1- the "zero" register (that may not be zero) */ pop r1 + pop r0 /* Restore the status register (probably enabling interrupts) */ - pop r0 /* Restore the status register */ - out _SFR_IO_ADDR(SREG), r0 + pop r24 /* Restore the status register */ + andi r24, ~(1 << SREG_I) /* but keeping interrupts disabled until the reti */ + out _SFR_IO_ADDR(SREG), r24 - /* Finally, restore r0 and r24 - the scratch and IRQ number registers */ + /* Finally, restore r24-r25 - the temporary and IRQ number registers */ - pop r0 + pop r25 pop r24 .endm @@ -351,9 +355,10 @@ st x+, r28 /* Skip over r18-r27 - Call-used, "volatile" registers (r26-r27 have - * already been skipped, r24 is saved elsewhere) */ + * already been skipped, r24 and r25 are saved elsewhere) + */ - adiw r26, 7 /* Seven registers: r18-23, r25 */ + adiw r26, 6 /* Seven registers: r18-23 */ /* Save r2-r17 - Call-saved, "static" registers */ @@ -379,14 +384,18 @@ clr r1 st x+, r1 + /* Skip over r0 -- the scratch register */ + + adiw r26, 1 + /* Save the status register (probably not necessary since interrupts are disabled) */ in r0, _SFR_IO_ADDR(SREG) st x+, r0 - /* Skip R0 and r24 - These are scratch register and Call-used, "volatile" registers */ + /* Skip r24-r25 - These are scratch register and Call-used, "volatile" registers */ - adiw r26, 2 /* Two registers: r0, r24 */ + adiw r26, 2 /* Two registers: r24-r25 */ /* Save the return address that we have saved in r18:19*/ @@ -425,7 +434,7 @@ /* Fetch and set the new stack pointer */ ld r25, x+ /* Fetch stack pointer (post-incrementing) */ - out _SFR_IO_ADDR(SPH), r25 /* (SPH then SPL) */ + out _SFR_IO_ADDR(SPH), r25 /* (SPH then SPL) */ ld r24, x+ out _SFR_IO_ADDR(SPL), r24 @@ -468,10 +477,9 @@ ld r28, x+ /* Restore r18-r27 - Call-used, "volatile" registers (r26-r27 have been - * moved and r24 will be restore later) + * moved and r24-r25 will be restore later) */ - ld r25, x+ ld r23, x+ ld r22, x+ ld r21, x+ @@ -502,14 +510,18 @@ ld r1, x+ - /* Restore the status register (probably enabling interrupts) */ + /* Restore r0 - the scratch register */ ld r0, x+ - out _SFR_IO_ADDR(SREG), r0 - /* Restore r0 and r24 - The scratch and IRQ number registers */ + /* Restore the status register (probably re-enabling interrupts) */ - ld r0, x+ + ld r24, x+ + out _SFR_IO_ADDR(SREG), r24 + + /* Restore r24-r25 - The temporary and IRQ number registers */ + + ld r25, x+ ld r24, x+ /* Finally, recover X [r26-r27] from the the new stack. The PC remains on the new diff --git a/mm/mm_sem.c b/mm/mm_sem.c index e8c669e4de..4b7563c0b5 100644 --- a/mm/mm_sem.c +++ b/mm/mm_sem.c @@ -200,7 +200,9 @@ void mm_takesemaphore(void) void mm_givesemaphore(void) { +#ifdef CONFIG_DEBUG pid_t my_pid = getpid(); +#endif /* I better be holding at least one reference to the semaphore */