Skip to content
Snippets Groups Projects
context-switch.s 1.62 KiB
Newer Older
	.file	"context-switch.s"
	.text
	.align	2
	.global	kerent
	.type	kerent, %function
kerent:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0

@movs pc, lr
@ debug print
@@mov r0, #1
@@mov r1, #123
@@bl bwputr(PLT)

@ save spsr to r1
mrs r1, spsr
@ switch to sysmode
msr cpsr_c, #0xdf



@ save user status
stmfd sp!, {r3-r12,r14,r1}

@ copy sp to r2 for later saving 
mov r2, sp

@ move sp downward by 1
sub sp, sp, #4

	@ switch to svc mode
	msr cpsr_c, #0xd3
@ store lr_svc onto sp_usr
stmfd r2!, {lr}

@ move Args to r1
mov r1, r0

@ get swi number into r0
ldr r0, [lr, #-4]
         @ mask off high bits
         bic r0, r0, #0xff000000
	@ pop kernels stack
	ldmfd sp!, {r3-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
	@ args = 0, pretend = 0, frame = 8
	@ frame_needed = 1, uses_anonymous_args = 0
	@ push kernel's registers
stmfd sp!, {r3-r12, r14}
	@ stmfd sp_svc!, {r0-r14} TODO
	@ switching to system mode
	msr cpsr_c, #0xdf 

	@ get task->sp_usr from arg 0 
        mov sp, r0
@ load spsr to r0, lr_svc to r2
ldmfd sp!, {r0, r2}
@ move sp up 2 slot
add sp, sp, #8

	@ switch back to svc mode
msr cpsr_c, #0xd3
@ set spsr to r0
msr spsr, r0
@ set lr_svc to r2
mov lr, r2
@switch back to sys mode
msr cpsr_c, #0xdf
	@ restore user's registers
	ldmfd sp!, {r3-r12, r14}
@get back to svc mode
msr cpsr_c, #0xd3
@load return value into r0
mov r0, r1
	@ go to usr program
	movs pc, lr
        .size kerxit, .-kerxit
        .ident "GCC: (GNU) 4.0.2"