📄 intasm.s
字号:
INCLUDE AT91RM9200.inc
;-------------------------------------------------------------------------------
;- IRQ Handler Macro Definition -
;----------------------------- -
;- Just disable FIQ and Saves context. Not support interrupt nesting. -
;-------------------------------------------------------------------------------
Macro
IRQ_HDLR $c_handler, $s_handler
IMPORT $c_handler
EXPORT $s_handler
$s_handler
;-------------------------------------------------------------------------------
;- Enter Interrupt
;-
;- Save context in current (IRQ / FIQ) stack, According to ATPCS, only r0 - r3
;- and lr should be saved, others will be saved by compiler in C codes
;- when needed.
;-------------------------------------------------------------------------------
stmfd sp!, {r0 - r3, lr};
;-------------------------------------------------------------------------------
;- Exit Interrupt
;- Diable IRQ and FIQ
;-------------------------------------------------------------------------------
mrs r0, CPSR
orr r0, I_BIT:OR:F_BIT
msr CPSR_c, r0
;-------------------------------------------------------------------------------
;- Hadle Interrupt
;- Jump to c intterupt handler
;-------------------------------------------------------------------------------
ldr r0, =$c_handler
mov lr, pc
bx r0
;-------------------------------------------------------------------------------
;- Mark the end of intterupt on AIC
;-------------------------------------------------------------------------------
ldr r0, =AT91C_BASE_AIC
str r0, [r0, #AIC_EOICR]
;-------------------------------------------------------------------------------
;- Restore context from stack
;-------------------------------------------------------------------------------
ldmfd sp!, {r0 - r3, pc}^
MEND
IMPORT OSIntNesting
IMPORT OSTCBCur
IMPORT OSIntExit
;-------------------------------------------------------------------------------
;- OS FRQ Handler Macro Definition -
;----------------------------- -
;- Notify OS of entering fast interrupt, Support interrupt nestint. -
;-------------------------------------------------------------------------------
MACRO
OS_IRQ_HDLR $c_handler, $s_handler
IMPORT $c_handler
EXPORT $s_handler
$s_handler ROUT
MEND
;-------------------------------------------------------------------------------
;- OS IRQ Handler Macro Definition -
;----------------------------- -
;- Notify OS of entering interrupt, Support interrupt nestint. -
;-------------------------------------------------------------------------------
MACRO
OS_IRQ_HDLR $c_handler, $s_handler
IMPORT $c_handler
EXPORT $s_handler
$s_handler ROUT
;-------------------------------------------------------------------------------
;- Enter Interrupt
;-
;- Save context
;- Task-s stack orgernized like below, that is a full decrease stack.
;- All task runs in SVC mode, task stack pointer is put in SP_svc
;- SP --> LR_irq (PC for return)
;- LR
;- R12
;- R11
;- R10
;- R9
;- R8
;- R7
;- R6
;- R5
;- R4
;- R3
;- R2
;- R1
;- R0
;- SPSR_irq (CPSR_svc)-
;-------------------------------------------------------------------------------
stmfd sp, {r0-r3} ;- Store r0-r3 in irq stack temporiarily
sub r0, lr, #0x04 ;- copy task-s PC(lr_irq)-
mrs r1, SPSR ;- copy task-s CPSR(SPSR_irq)-
sub r2, sp, #0x10 ;- copy IRQ mode stack pointer
msr CPSR_c, #ARM_MODE_SVC:OR:I_BIT:OR:F_BIT ;- Switch back to SVC mode with IRQ and FIQ disabled
;- Store task context in task stack
stmfd sp!, {r0} ;- Store task-s PC(lr_irq) in task-s stack
stmfd sp!, {r4-r12, lr} ;- Store task-s register r4-r12, lr
ldmfd r2!, {r4-r7} ;- Move task-s register r0-r3 to task
stmfd sp!, {r4-r7} ;- stack from IRQ stack-
stmfd sp!, {r1} ;- Store task-s CPSR(SPSR_irq) in task stack
;-------------------------------------------------------------------------------
;- OSIntNesting++
;- These codes are relative with OS
;-------------------------------------------------------------------------------
ldr r0, =OSIntNesting
ldrb r1, [r0]
add r1, r1, #1
strb r1, [r0]
;-------------------------------------------------------------------------------
;- If OSIntNesting == 1, OSTCBCur->OSTCBStkPtr = SP
;- These codes are relative with OS
;-------------------------------------------------------------------------------
cmp r1, #1
bne %55
ldr r4, =OSTCBCur
ldr r5, [r4]
str sp, [r5]
;-------------------------------------------------------------------------------
;- Enable IRQ and FIQ
;-------------------------------------------------------------------------------
55
msr CPSR_c, #ARM_MODE_SVC
;-------------------------------------------------------------------------------
;- Hadle Interrupt
;- Jump to c intterupt handler
;-------------------------------------------------------------------------------
ldr r0, =$c_handler
mov lr, pc
bx r0
;-------------------------------------------------------------------------------
;- Exit Interrupt
;- Switch back to SVC mode, at the same time diable IRQ and FIQ
;-------------------------------------------------------------------------------
msr CPSR_c, #ARM_MODE_SVC:OR:I_BIT:OR:F_BIT
;-------------------------------------------------------------------------------
;- Mark the end of intterupt on AIC
;-------------------------------------------------------------------------------
ldr r0, =AT91C_BASE_AIC
str r0, [r0, #AIC_EOICR]
;-------------------------------------------------------------------------------
;- OSIntExit()
;- Call this function will cause task switch if neccessery
;- These codes are relative with OS
;------------------------------------------------------------------------------
ldr r0, =OSIntExit
mov lr, pc
bx r0
;-------------------------------------------------------------------------------
;- Restore context from stack
;-------------------------------------------------------------------------------
ldmfd sp!, {r0}
msr SPSR_cxsf, r0
ldmfd sp!, {r0-r12, lr, pc}^
MEND
;-------------------------------------------------------------------------------
;- Interrupt definitions
;-
;-------------------------------------------------------------------------------
AREA IntAsmHandlers, CODE, READONLY
CODE32
OS_IRQ_HDLR EtherInt, EtherIntHandler
OS_IRQ_HDLR PTimerInt, PTimerIntHandler
OS_IRQ_HDLR TC1Int, TC1IntHandler
OS_IRQ_HDLR TC2Int, TC2IntHandler
OS_IRQ_HDLR SttInt, SttIntHandler
OS_IRQ_HDLR SpuriousInt, SpuriousHandler
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -