📄 except.s
字号:
; except.s - low-level interrupt handler
; This code is written as a very selfish interrupt handler that doesn't
; perform chaining. If the C handler doesn't clear down the cause of the
; irq then bad things happen. Also note that nothing is done to allow
; software stack checking to work, so all routines called from the
; handler must have stack checking turned off. For your system, you
; may have to re-code this to swap in the appropriate value into the
; stack limit register.
;
; Different code is required for interworking systems to that required
; for straight ARM systems. Note that if we are assembling using tasm,
; we force the assembler into ARM mode anyway. The test for interworking
; is somewhat bogus - we assume that if you are compiling for a 4T
; architecture, then you are interworking.
[ {CODESIZE}=16
CODE32 ; Force ARM mode
]
IMPORT timer0_handler
EXPORT timer0_IRQ_handler
IMPORT Uart0isr
EXPORT Uart0_IRQ_handler
IMPORT UART16C550_isr_receive
EXPORT UART16C550_IRQ_handler
IMPORT OSIntEnter
IMPORT OSIntExit
IMPORT OSTCBCur
FBit EQU &40
IBit EQU &80
LOCKOUT EQU &C0 ;Interrupt lockout value
MODE_MASK EQU &1F ;Processor Mode Mask
UDF_MODE EQU &1B ;Undefine Mode(UDF)
ABT_MODE EQU &17 ;Abort Mode(ABT)
SUP_MODE EQU &13 ;Supervisor Mode (SVC)
IRQ_MODE EQU &12 ;Interrupt Mode (IRQ)
FIQ_MODE EQU &11 ;Fast Interrupt Mode (FIQ)
USR_MODE EQU &10 ;User Mode(USR)
AIC_BASE EQU 0xFFFFF000
AIC_EOICR EQU 0x130
AREA |C$$code|, CODE, READONLY
EXPORT |cpu_int_enable|
|cpu_int_enable|
msr cpsr_c,a1
bx lr
EXPORT |cpu_int_disable|
|cpu_int_disable|
mrs r0,cpsr
stmfd sp!,{r0}
orr r0,r0,#LOCKOUT
msr cpsr_c,r0
ldmfd sp!,{r0}
bx lr
EXPORT int_enable
int_enable
stmfd sp!,{r0}
mrs r0, cpsr
bic r0, r0, #0x80
msr cpsr_c, r0
ldmfd sp!,{r0}
bx lr
EXPORT int_disable
int_disable
stmfd sp!,{r0}
mrs r0, cpsr
orr r0, r0, #0x80
msr cpsr_c, r0
ldmfd sp!,{r0}
bx lr
MACRO
IRQ_ENTRY
sub r14, r14, #4
stmfd sp!, {r14} ; Adjust and save LR of current mode in current stack
mrs r14, SPSR
stmfd sp!, {r0, r14} ; Save SPSR and r0 in current stack
mrs r14, CPSR
bic r14, r14, #I_BIT ; Read Modify Write the CPSR to Enable the Core Interrupt
orr r14, r14, #ARM_MODE_SYS
msr CPSR, r14 ; and Switch in SYS Mode ( same LR and stack than USR Mode )
stmfd sp!, {r1-r3, r12, r14} ; Save used registers and LR_usr in the System/User Stack
MEND
MACRO
IRQ_EXIT
ldmfd sp!, {r1-r3, r12, r14} ; Restore used registers and LR_usr from the System/User Stack
mrs r0, CPSR ; Read Modify Write the CPSR to disable interrupts
bic r0, r0, #ARM_MODE_SYS
orr r0, r0, #I_BIT:OR:ARM_MODE_IRQ
msr CPSR, r0 ; and to go back in the mode corresponding to the exception
ldr r0, = AIC_BASE ; Mark the End of Interrupt on the interrupt controller
str r0, [r0, #AIC_EOICR]
ldmfd sp!, {r0, r14} ; Restore SPSR_irq and r0 from the IRQ stack
msr SPSR, r14
ldmfd sp!, {pc}^ ; Restore ajusted LR_irq from IRQ stack directly in the PC
MEND
timer0_IRQ_handler
sub r14, r14, #4
stmfd sp!, {r14}
mrs r14, SPSR
stmfd sp!, {r14}
stmfd sp!, {r0-r12, r14}
bl timer0_handler
ldr r0, = AIC_BASE
str r0, [r0, #AIC_EOICR]
ldmfd sp!, {r0-r12, r14}
ldmfd sp!, {r14}
msr SPSR_cfxs, r14
ldmfd sp!, {pc}^
Uart0_IRQ_handler
sub r14, r14, #4
stmfd sp!, {r14}
mrs r14, SPSR
stmfd sp!, {r14}
stmfd sp!, {r0-r12, r14}
bl OSIntEnter
bl Uart0isr
ldr r0, = AIC_BASE
str r0, [r0, #AIC_EOICR]
bl OSIntExit
ldmfd sp!, {r0-r12, r14}
ldmfd sp!, {r14}
msr SPSR_cfxs, r14
ldmfd sp!, {pc}^
UART16C550_IRQ_handler
sub r14, r14, #4
stmfd sp!, {r14}
mrs r14, SPSR
stmfd sp!, {r14}
stmfd sp!, {r0-r12, r14}
bl OSIntEnter
bl UART16C550_isr_receive
ldr r0, = AIC_BASE
str r0, [r0, #AIC_EOICR]
bl OSIntExit
ldmfd sp!, {r0-r12, r14}
ldmfd sp!, {r14}
msr SPSR_cfxs, r14
ldmfd sp!, {pc}^
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -