- 论坛徽章:
- 0
|
使用SWI实现系统功能调用的过程有点类似于IRQ处理,不同的是SWI有调用参数,而中断处理程序没有,因此它们的代码区别甚小,SWI处理例程代码如下:
.func __swi_handler
__swi_handler:
stmfd sp!, {lr} @save return address firstly (pc).
stmfd sp, {r0-r14}^ @save user regisers.
sub sp, sp, #60 @r0-r15 offset.
mrs r5, spsr @save cpsr
stmfd sp!, {r5} @save cpsr
@@-----------call task save ----------@@
mov r5, r0
mov r6, r1
mov r7, r2
mov r8, r3
@@load dst address;
ldr r0, =g_curr_tcb_p @@load g_curr_task_p address
ldr r0, [r0] @@load TCB address
@@load src address;
mov r1, sp @@base address;
bl tcb_save @@save task.
mov r0, r5
mov r1, r6
mov r2, r7
mov r3, r8
@@-----------call system routines ----------@@
bl main_swi_handler @(u_int32 val0,u_int32 val1,u_int32 val2,u_int32 val3)
@@-----------call task load ----------@@
@@load dst address;
mov r0, sp @@base address;
@@load src address;
ldr r1, =g_curr_tcb_p @@load g_curr_task_p address
ldr r1, [r1] @@load TCB address
bl tcb_save @load task.
@@-----------restore TCB ----------@@
ldmfd sp!, {r0} @pop spsr
msr spsr, r0 @restore spsr
ldmfd sp, {r0-r14}^ @restore r0-r12
add sp, sp, #60 @skip user sp.
ldmfd sp!, {lr} @restore user pc.
movs pc, lr @return;
.endfunc
.size __swi_handler, . - __swi_handler
这里的main_swi_handler为系统调用处理函数的入口,在调用main_swi_handler函数之前,我们需要将调用参数传递给服务程序,采用ATPCS标准时,r0-r3为传递参数的寄存器,而在调用tcb_save函数保存进程TCB时,r0-r3已经被tcb_save修改了,因此,在调用tcb_save之前,我们需要保存r0-r3,在tcb_save退出后,恢复r0-r3,由于r5-r8在tcb_save中不会被使用,即使使用也会被保存(ATPCS标准),因此,将r0-r3保存在r5-r8是个不错的注意,效能更好,代码也更简洁,因材在swi的处理例程中采用这个办法来保存swi调用参数。除此以外,swi与irq的代码是完全相同---因为swi调用和irq中断都可能导致进程切换。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/94507/showart_1933245.html |
|