📄 switch.s
字号:
;; MShowTec - www.mshowtec.com
;; msLinux switch.s ver1.0
;; 20051221 lmjx create limiao@mshowtec.com
;;
;;
;; MSLINUX_SWITCH_S
CODE32
AREA |C$$code|, CODE, READONLY
OFFSET_SP EQU 0
OFFSET_TOPSP EQU 4
MODE_MASK EQU 0x1F
USR_MODE EQU 0x10
FIQ_MODE EQU 0x11
IRQ_MODE EQU 0x12
SVC_MODE EQU 0x13
ABORT_MODE EQU 0x17
UNDEF_MODE EQU 0x1B
SYSTEM_MODE EQU 0x1F
IRQ_MASK EQU 0x80
IRQ_DISABLE EQU 0x80
FIQ_MASK EQU 0x40
FIQ_DISABLE EQU 0x40
INT_MASK EQU IRQ_MASK:OR:FIQ_MASK
INT_DISABLE EQU IRQ_MASK:OR:FIQ_MASK
THUMB_BIT EQU 0x20
; IRQ interrupt management
;--------------------------
EXPORT mslinux_enable_irq
mslinux_enable_irq
mrs r0, CPSR ; Load current status register
bic r0, r0,#IRQ_MASK; Clear the allowed interrupt bits
msr CPSR_cf, r0 ; Write back to status register
bx lr ; Branch back to previous mode
EXPORT mslinux_save_disable_irq
mslinux_save_disable_irq
mrs r0, CPSR ; Load current status register
orr r1, r0, #IRQ_MASK; Set the interrupt bits
msr CPSR_cf, r1 ; Write back to status register
bx lr ; Branch back to previous mode
EXPORT mslinux_restore_irq
mslinux_restore_irq
and r0,r0,#IRQ_MASK ; Only Interrupt bits are not masked
mrs r1,CPSR ; Load current status register
bic r1,r1,#IRQ_MASK ; Clear interrupt mask bits
orr r0,r0,r1 ; Restore interrupt mask bits
msr CPSR_cf, r0 ; and write in status register
bx lr ; Branch back to previous mode
EXPORT mslinux_get_sp
mslinux_get_sp
mov r0,sp
bx lr
EXPORT mslinux_get_cprs
mslinux_get_cprs
mrs r0,CPSR
bx lr
; Task switch management
;--------------------------
EXPORT switch_to
IMPORT errno_print
IMPORT current
IMPORT next
switch_to
; We are in the mode of the interrupted task
stmfd sp!, {r0-r12, lr} ; Save all registers
mrs v1, CPSR
stmfd sp!, {v1} ; Save the current status register
ldr r0,=current; r0 = ¤t
ldr r1, [r0] ; r1 = CurrentTask
str sp, [r1,#4] ; Save old stack pointer
; Perform stack checking
ldr r1, [r1,#0] ; Get pointer to bottom of stack
ldrb r1, [r1] ; Get value at bottom of stack
cmp r1, #0x55 ; Is the bottom still 0x55?
bne %0
; Get pointer to next task
ldr r2, =next ; r2 <- &NextTask
ldr r1, [r2] ; r1 = NextTask
str r1, [r0] ; CurrentTask = a2 = NextTask
ldr sp, [r1,#4] ; Load new stack pointer
ldmfd sp!, {v1} ; Restore the current status register
msr CPSR_cf, v1
ldmfd sp!, {r0-r12, lr} ; Restore all registers
bx lr ; Return
0
mov r0,#3 ;3 for task stack over
bl errno_print
EXPORT move_to_user_mode
move_to_user_mode
ldr a3,=Task0_SwitchAddress
str pc,[a3]
; Go into System Mode, INTS disabled
mov a3,#(SYSTEM_MODE | INT_DISABLE)
msr CPSR_cf,a3
mov sp,a1 ; Load new stack pointer
bx a2 ; Jump to provided function
AREA |C$$data|
Task0_SwitchAddress
% 4
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -