SH4/SH4A有两个处理器模式:用户模式(User Mode)和特权模式(Privileged Mode)。SH4一般运行在用户模式下,当一个异常或中断发生时,CPU就跳到特权模式里。
之前我们谈了SH4的MMU(内存管理单元),知道CPU在用户模式下只能访问U0区(H'00000000 ~ H'80000000),如果访问U0之外的其他地址,则发生地址错误。如图所示:
SH4的所有片上外设寄存器位于高端地址0XFF000000地址以上,比如看门狗计数寄存器在特权模式下的地址是0xFFC00008,如果要操作看门狗,是不能直接访问0XFFC00008这个地址的,只能进入特权模式去访问它。
从用户模式进入特权模式,最好的方式是使用软中断指令TRAPA,比如执行TRAPA #32之后,系统会跳到向量号为32的中断处理程序里,这样就进入了特权模式,类似于linux的系统调用。
SuperH编译器提供了一个软中断函数trapa_svc(),该函数为可变参数,如下:
int trapa_svc(int trap_no, int index, type1 para1, type2 para2, type2 para3, type4 para4);
描述:系统调用
when trapa_svc is executed, index is specified in R0,
...and para1 to para4 in R4 to R7, respectively.
...Then, TRAPA #trap_no is executed.
比如执行trapa_svc(32, 3, 0x11, 0x22)时,参数3放到寄存器R0,之后的2个参数0x11,0x22依次放到R4,R5里,然后执行TRAPA #32指令。
因此,我们模仿linux系统调用机制,设置一个函数指针数组,存放特权模式下要执行的函数。CPU在用户模式下执行trapa_svc后进入特权模式,在中断子程序里根据trapa_svc传入的参数,查找数组,找到对应的函数地址,再执行该函数。函数执行完毕,中断返回时,CPU又切回到用户模式。
; system_call为软中断处理程序
_system_call:
MOVML.L R14,@-R15
MOV.L #sys_call_table, R10 ; get the address of the function table
SHLL2 R0 ; index = index * 4
ADD R0,R10 ; element address = sys_call_table + index * 4
MOV.L @R10,R10 ; get the address of the corresponding function in table
JSR @R10 ; call the corresponding routine
NOP
MOVML.L @R15+,R14
RTE ;中断返回,切换到用户模式
NOP
; 函数指针数组,4字节对齐
.section D,DATA,ALIGN=4
sys_call_table:
.DATA.L _sys_fun0 ; index 0
.DATA.L _sys_fun1 ; index 1
.DATA.L _sys_fun2 ; index 2
.DATA.L _sys_fun3 ; index 3
.DATA.L _sys_fun4 ; index 4
.DATA.L _sys_fun5 ; index 5
.DATA.L _sys_fun6 ; index 6
后记:
SH4在用户模式下对2G~4G的空间进行保护,这样可以防止应用程序破坏该区域的内容。
一般来说,内核和驱动的代码位于3G~4G的空间,在用户模式下访问内核和驱动,只能通过软中断进入到特权模式才能执行内核或驱动程序。
文章评论(0条评论)
登录后参与讨论