📄 except.s
字号:
PRESERVE8
EXPORT init_system
EXPORT handler_svc
EXPORT rescheduleFromInterrupt
EXPORT rescheduleRequired
EXPORT interruptCount
EXPORT save_user_state
EXPORT restore_user_state
EXPORT os_result_exit
EXPORT os_void_exit
EXPORT irqSP
IMPORT handle_system_call
IMPORT os_task_select
AREA exception, CODE, READONLY
GET saveregisters.s
;-----------------------------------------------------------------------
; init_system(unsigned char *superstacktop, unsigned char *irqstacktop);
;-----------------------------------------------------------------------
init_system
; In OS20 original project it was used to initialize either superSP/irqSP
; variables and stacks IRQ/SVC. and only at the end it goes in USER_MODE.
; New init_system function only initilize superSP/irqSP.
; save SVC mode stack in superSP
LDR r2, =superSP ; r2 = &superSP
STR r0, [r2] ; *r2 = r0 (= superstacktop)
;
; save IRQ mode stack in irqSP
LDR r2, =irqSP ; r2 = &irqSP
STR r1, [r2] ; *r2 = r1 (= irqstacktop)
;
;continue into user mode with interrupts enabled and restore lr
MOV pc, lr ;return
;-------------
; handler_svc
;-------------
handler_svc
; reset supervisor stack, left in a mess by os_exit
LDR sp, =superSP
LDR sp, [sp]
STMFD sp!, {r0-r2} ;save some scratch registers
; get the SWI operand
LDR r0, [lr,#-4] ;load the SWI instruction into r0
BIC r0, r0, #0xff000000 ;mask off the top 8 bits to give SWI instruction number
;>>>>>>>> JUMP TABLE
MRS r2 , spsr ; Save SPSR
CMP r0,#0x100 ;check if OS20call
BLT OS20call
SUB r0,r0,#0x100
ADD r0,r0,#0x40000000
LDR lr,[r0,#0]
TST lr , #0x01 ; Thumb Procedure ?
BNE THUMB_LBL
MSR spsr_cf , r2
LDMFD sp!, {r0-r2} ;put saved registers back
MOVS pc , lr ;this will return from exception to
THUMB_LBL
ORR r2 , r2 , #0x20 ;Set T Flag
MSR spsr_cf , r2
LDMFD sp!, {r0-r2} ;put saved registers back
MOVS pc , lr
;
OS20call
;
;>>>>>>>> JUMP TABLE
notSemiHost
;
; deal with interrupt disable/enable directly (using the funky conditional instructions)
;
MRS r2, spsr ;get the spsr value (saved cpsr)
TEQ r0, #0x0 ;intdis_e
ORREQ r2, r2, #0x80
BEQ isintop
TEQ r0, #0x1 ;intenb_e
BICEQ r2, r2, #0x80
BNE notintop
isintop
MSR spsr_cf, r2
LDMFD sp!, {r0-r2} ;put saved registers back
MOVS pc, lr ;return from exception
notintop
SAVE_REGISTERS
BL handle_system_call ;handle_system_call(swi,regs[numregs])
;should never come back here...
;---------------------------------
; rescheduleFromInterrupt
;---------------------------------
; pre: running in IRQ mode on IRQ stack
; user state intact
rescheduleFromInterrupt
;
; get the registers into a state so that SAVE_REGISTERS can be called
;
STMFD sp!, {r0-r2} ;save some scratch registers
MRS r2, spsr ;put saved psr into r2
SAVE_REGISTERS
;
; rescheduleRequired = 0
;
MOV r0, #0
LDR r1, =rescheduleRequired
STR r0, [r1]
BL os_task_select
;should never come back here....
;---------------------------------
; unsigned *save_user_state(void)
;---------------------------------
save_user_state
LDR r0, =savedUserSP;
LDR r0, [r0]
MOV pc, lr ;return
;-------------------------------------
; void restore_user_state(unsigned *)
;-------------------------------------
restore_user_state
LDR r1, =savedUserSP;
STR r0, [r1];
MOV pc, lr ;return
;---------------------------------
; void os_result_exit(int result)
;---------------------------------
os_result_exit
LDR r1, =savedUserSP;
LDR r1, [r1];
STR r0, [r1];
;---------------------
; void os_void_exit()
;---------------------
os_void_exit
;
; rescheduleRequired = 0
;
;MOV r0, #0
;LDR r1, =rescheduleRequired
;STR r0, [r1]
;
; if(mode==IRQ)
; sp = irqSP
; else
; sp = superSP
;
MRS r0, CPSR
AND r0, r0, #0x1f ; mask off mode bits
TEQ r0, #0x13 ; test eq to SVC mode
LDRNE r1, =irqSP
LDREQ r1, =superSP
LDR sp, [r1]
;
; r1 = savedUserSP
;
LDR r1, =savedUserSP
LDR r1, [r1] ;r1 contains pointer to registers, r1/*0*/[0] = register 0 etc
;
; spsr = savedUserSP[psr]
;
LDR r0, [r1,#16*4] ;get cpsr value
MSR spsr_cf, r0 ;and restore into spsr
;
; lr = savedUserSP[pc]
;
LDR lr, [r1,#15*4]
;
; r{0..14} = savedUserSP[0..14]
;
LDMFD r1, {r0 - r14}^
NOP
;
; move into user mode with PC = lr
;
MOVS pc, lr
AREA var, DATA, READWRITE
savedUserSP
DCD 0x00000000 ;Current task user stack pointer
superSP
DCD 0x00000000 ;contains supervisor stack pointer
irqSP
DCD 0x00000000 ;contains irq stack pointer
interruptCount
DCD 0x00000000 ;interrupt nesting count
rescheduleRequired
DCD 0x00000000 ;a reschedule has been requested from an interrupt handler
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -