平头哥E90X的head.S分析
- RISC-V
- 2024-05-09
- 103热度
- 0评论
关闭中断
/* disable interrupt */
li t0, MR_MIE --- t0=0x08
csrc mstatus, t0 --- mstatus = mstatus | ~t0
csrw mie, zero --- mie = zero
mstatus第4bit清0,mie清0。
设置异常处理入口
/* setup the address of exception handler */
la a0, risc_v_trap_handler
ori a0, a0, 3
csrw mtvec, a0
E90X异常和中断使用了CLINT和CLIC两个控制器,对于异常的服务程序入口函数有MTVEC寄存器指定,这里的异常指的是同步异常,这类异常没法屏蔽,通常是执行指令、取指令、非法内存访问等的异常。MTVEC寄存器的低2位,设置为3,表示使用模式3,该模式下CPU使用MTVEC[31:6]<<6作为异常(同步异常)的服务程序入口地址并跳转执行。
设置中断处理入口
/* setup the address of vector interrupt handler */
la a0, interrupt_vectors
csrw mtvt, a0
当MTVEC的低两位设置MODE[1:0]=3时,CPU使用MTVEC[31:6]<<6作为异常(同步异常)的服务程序入口地址并跳转执行,而对于中断服务程序入口分两种情况,当使能了CLIC.CLICINTATTR中的shv域设置是否为硬件矢量中断,如果是硬件矢量中断,CPU首先使用MTVT+4*中断ID为地址,去取中断服务程序入口地址,并跳转到该入口地址执行,如果是非矢量中断,CPU使用MTVEC[31:6]<<作为中断服务程序入口地址并跳转执行。MTVT为矢量中断基址寄存器,在CLIC模式存在。在E907中MODE[1:0]硬件固定设置为3,软件不可设置。
中断向量表
.section .vectors, \"xx\", @progbits
.balign 64
.globl clic_interrupt_vectors
.type clic_interrupt_vectors, @object
clic_interrupt_vectors:
.rept (PLAT_CLIC_IRQ_CNT)
.long clic_interrupt_handler
.endr
.text
这里默认设置为中断硬件矢量模式,所以需要注册向量表,但是这里向量表统一入口为clic_interrupt_handler。
清除BSS段
# clear mscratch register.
csrw mscratch,zero
/* Clear bss section */
la a0, __bss_start__
la a1, __bss_end__
bgeu a0, a1, 2f --- 2f标签后面跟着一个字符(如f)是一种常见的命名约定,帮助区分不同类型的标签,这里暗示这是一个向前跳转的目标(forward jump target),如果a0>=a1,向前跳转到标签2的地方。
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b ---1bb也是一个标签,但与之前的2f不同,它指示了一个向后跳转(backward jump)的目标。这里的b后缀表明这是一个向后的跳转,意味着如果条件满足(即a0 < a1)
2:
xxxx
上面的汇编代码的作用就是获取到bss段的起始地址,然后写入0;
设置栈SP
/* setup stack pointer for C runtime environment */
la sp, __init_process_stack_end__
init_process_stack_end是在链接脚本中栈空间结束地址,这里直接复制为sp即可。