Newer
Older
.file "context-switch.s"
.text
.align 2
.global kerent
.type kerent, %function
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 1, uses_anonymous_args = 0
@ switch to system mode
msr cpsr_c, #0xdf
@ push regs onto users stack
stmfd sp!, {r1-r12,r14}
@ save spsr to r2
mrs r2, spsr
@ copy sp to r1 for later saving on to td
mov r1, sp
@ switch to svc mode
@ create vague register to set td->RetVal, it doesn't matter the val
mov r3, #0
@ mov args from r0 to r4
mov r4, r0
@ mov sp from r1 to r0
mov r0, r1
@ mov lr_svc to r1
mov r1, lr
@ load Task from kernel sp into r5
ldmfd sp!, {r5}
@ store sp_usr(r0), lr_svc(r1), spsr(r2),retval(r3),args(r4) onto Task
@ first subtract td value
add r5, r5, #20
@ then store
stmfd r5, {r0-r4}
@ get swi number into r0
ldr r0, [lr, #-4]
@ mask off high bits
bic r0, r0, #0xff000000
/*
mov r0, #1
mov r1, #6
bl bwputr(PLT)
*/
@ pop kernels stack
ldmfd sp!, {r1-r12,pc}
.size kerent, .-kerent
@==================================================================================
.align 2
.global kerxit
.type kerxit, %function
kerxit:
@ this is equi to activate, an entry point in the kernel to which it goes
@ when its ready to restart the active task
@ frame_needed = 1, uses_anonymous_args = 0
@ r0 = Task
@ push kernel's registers, Task saved on kernels stack
stmfd sp!, {r0-r12, r14}
@ r0 is Task, get sp_user, lr, cpsr_user, retval
ldmfd r0, {r0-r3}
@ get lr(int r1) into r14(lr_svc)
mov lr, r1
@ load user's cpsr(in r2) to spsr
msr spsr, r2
@ mov sp_usr from r0 to r2
mov r2, r0
@ return value from r3 into r0
mov r0, r3
@ switch to system mode
msr cpsr_c, #0xdf
@ set user sp
mov sp, r2
@ restore user's registers
ldmfd sp!, {r1-r12, r14}
@ switch back to svc mode
msr cpsr_c, #0xd3