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
This commit is contained in:
patacongo 2011-06-18 20:02:40 +00:00
parent fe7a627a50
commit 58a68260c3
3 changed files with 74 additions and 60 deletions

View file

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

View file

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

View file

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