RTX5: fixed nesting interrupt handling (Cortex-A)

pull/7032/head
Vladimir Umek 2018-04-10 09:34:51 +02:00 committed by TomoYamanaka
parent b6c4139328
commit 165c663871
3 changed files with 60 additions and 30 deletions

View File

@ -178,6 +178,11 @@ IRQ_Handler\
CPS #MODE_SVC ; Change to SVC mode
PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers
LDR R3, =IRQ_NestLevel
LDR R2, [R3]
ADD R2, R2, #1 ; Increment IRQ nesting level
STR R2, [R3]
MOV R3, SP ; Move SP into R3
AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment
SUB SP, SP, R3 ; Adjust stack
@ -186,11 +191,6 @@ IRQ_Handler\
BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0
MOV R4, R0 ; Move interrupt ID to R4
LDR R1, =IRQ_NestLevel
LDR R3, [R1] ; Load IRQ nest level and increment it
ADD R3, R3, #1
STR R3, [R1]
BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID
CMP R0, #0 ; Check if handler address is 0
BEQ IRQ_End ; If 0, end interrupt and return
@ -203,11 +203,10 @@ IRQ_End
MOV R0, R4 ; Move interrupt ID to R0
BLX IRQ_EndOfInterrupt ; Signal end of interrupt
LDR R2, =IRQ_NestLevel
LDR R1, [R2] ; Load IRQ nest level and
SUBS R1, R1, #1 ; decrement it
STR R1, [R2]
BNE IRQ_Exit ; Not zero, exit from IRQ handler
LDR R3, =IRQ_NestLevel
LDR R2, [R3] ; Load IRQ nest level
CMP R2, #1
BNE IRQ_Exit ; Nesting interrupts, exit from IRQ handler
LDR R0, =SVC_Active
LDRB R0, [R0] ; Load SVC_Active flag
@ -252,12 +251,23 @@ IRQ_SwitchCheck
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
ADD SP, SP, R3 ; Unadjust stack
LDR R3, =IRQ_NestLevel
LDR R2, [R3]
SUBS R2, R2, #1 ; Decrement IRQ nesting level
STR R2, [R3]
B osRtxContextSwitch
IRQ_Exit
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
ADD SP, SP, R3 ; Unadjust stack
LDR R3, =IRQ_NestLevel
LDR R2, [R3]
SUBS R2, R2, #1 ; Decrement IRQ nesting level
STR R2, [R3]
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
RFEFD SP! ; Return from IRQ handler

View File

@ -184,6 +184,11 @@ IRQ_Handler:
CPS #MODE_SVC // Change to SVC mode
PUSH {R0-R3, R12, LR} // Save APCS corruptible registers
LDR R3, =IRQ_NestLevel
LDR R2, [R3]
ADD R2, R2, #1 // Increment IRQ nesting level
STR R2, [R3]
MOV R3, SP // Move SP into R3
AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment
SUB SP, SP, R3 // Adjust stack
@ -192,11 +197,6 @@ IRQ_Handler:
BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0
MOV R4, R0 // Move interrupt ID to R4
LDR R1, =IRQ_NestLevel
LDR R3, [R1] // Load IRQ nest level and increment it
ADD R3, R3, #1
STR R3, [R1]
BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID
CMP R0, #0 // Check if handler address is 0
BEQ IRQ_End // If 0, end interrupt and return
@ -209,11 +209,10 @@ IRQ_End:
MOV R0, R4 // Move interrupt ID to R0
BLX IRQ_EndOfInterrupt // Signal end of interrupt
LDR R2, =IRQ_NestLevel
LDR R1, [R2] // Load IRQ nest level and
SUBS R1, R1, #1 // decrement it
STR R1, [R2]
BNE IRQ_Exit // Not zero, exit from IRQ handler
LDR R3, =IRQ_NestLevel
LDR R2, [R3] // Load IRQ nest level
CMP R2, #1
BNE IRQ_Exit // Nesting interrupts, exit from IRQ handler
LDR R0, =SVC_Active
LDRB R0, [R0] // Load SVC_Active flag
@ -258,12 +257,23 @@ IRQ_SwitchCheck:
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
ADD SP, SP, R3 // Unadjust stack
LDR R3, =IRQ_NestLevel
LDR R2, [R3]
SUBS R2, R2, #1 // Decrement IRQ nesting level
STR R2, [R3]
B osRtxContextSwitch
IRQ_Exit:
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
ADD SP, SP, R3 // Unadjust stack
LDR R3, =IRQ_NestLevel
LDR R2, [R3]
SUBS R2, R2, #1 // Decrement IRQ nesting level
STR R2, [R3]
POP {R0-R3, R12, LR} // Restore stacked APCS registers
RFEFD SP! // Return from IRQ handler

View File

@ -169,6 +169,11 @@ IRQ_Handler
CPS #MODE_SVC ; Change to SVC mode
PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers
LDR R3, =IRQ_NestLevel
LDR R2, [R3]
ADD R2, R2, #1 ; Increment IRQ nesting level
STR R2, [R3]
MOV R3, SP ; Move SP into R3
AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment
SUB SP, SP, R3 ; Adjust stack
@ -177,11 +182,6 @@ IRQ_Handler
BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0
MOV R4, R0 ; Move interrupt ID to R4
LDR R1, =IRQ_NestLevel
LDR R3, [R1] ; Load IRQ nest level and increment it
ADD R3, R3, #1
STR R3, [R1]
BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID
CMP R0, #0 ; Check if handler address is 0
BEQ IRQ_End ; If 0, end interrupt and return
@ -194,11 +194,10 @@ IRQ_End
MOV R0, R4 ; Move interrupt ID to R0
BLX IRQ_EndOfInterrupt ; Signal end of interrupt
LDR R2, =IRQ_NestLevel
LDR R1, [R2] ; Load IRQ nest level and
SUBS R1, R1, #1 ; decrement it
STR R1, [R2]
BNE IRQ_Exit ; Not zero, exit from IRQ handler
LDR R3, =IRQ_NestLevel
LDR R2, [R3] ; Load IRQ nest level
CMP R2, #1
BNE IRQ_Exit ; Nesting interrupts, exit from IRQ handler
LDR R0, =SVC_Active
LDRB R0, [R0] ; Load SVC_Active flag
@ -243,12 +242,23 @@ IRQ_SwitchCheck
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
ADD SP, SP, R3 ; Unadjust stack
LDR R3, =IRQ_NestLevel
LDR R2, [R3]
SUBS R2, R2, #1 ; Decrement IRQ nesting level
STR R2, [R3]
B osRtxContextSwitch
IRQ_Exit
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
ADD SP, SP, R3 ; Unadjust stack
LDR R3, =IRQ_NestLevel
LDR R2, [R3]
SUBS R2, R2, #1 ; Decrement IRQ nesting level
STR R2, [R3]
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
RFEFD SP! ; Return from IRQ handler