网站建设成本计划,安阳信息网,宿迁房产网签备案查询系统,wordpress页面表格阅读材料
Xv6代码#xff1a;memlayout.h、start.c、kernelvec.S教材5.4节
CLINT内存映射
实际上#xff0c;CLINT还包括若干个MSIP寄存器#xff0c;用来触发软件中断#xff0c;但是在Xv6中不考虑软件中断#xff0c;因此这些寄存器也不用考虑
// core local interr…阅读材料
Xv6代码memlayout.h、start.c、kernelvec.S教材5.4节
CLINT内存映射
实际上CLINT还包括若干个MSIP寄存器用来触发软件中断但是在Xv6中不考虑软件中断因此这些寄存器也不用考虑
// core local interruptor (CLINT), which contains the timer.
#define CLINT 0x2000000L
#define CLINT_MTIMECMP(hartid) (CLINT 0x4000 8*(hartid))
#define CLINT_MTIME (CLINT 0xBFF8) // cycles since boot.
time_scratch数组
timer_scratch二维数组为每个HART分配了40字节的内存内存的作用如下图所示
// a scratch area per CPU for machine-mode timer interrupts.
uint64 timer_scratch[NCPU][5]; 时钟初始化
该函数被start()函数调用此时系统还处于M模式下。该函数完成下列工作
初始化mtimecmp寄存器保存mtimecmp寄存器MMIO映射到的物理地址到scratch[3]中保存时钟间隔到scratch[4]将scratch的地址保存到mscratch寄存器当中将timervec汇编函数的地址写入mtvec当中使能M模式下的时钟中断和M模式下的全局中断开关
void timerinit()
{// each CPU has a separate source of timer interrupts.int id r_mhartid();// ask the CLINT for a timer interrupt.int interval 1000000; // cycles; about 1/10th second in qemu.*(uint64*)CLINT_MTIMECMP(id) *(uint64*)CLINT_MTIME interval;// prepare information in scratch[] for timervec.// scratch[0..2] : space for timervec to save registers.// scratch[3] : address of CLINT MTIMECMP register.// scratch[4] : desired interval (in cycles) between timer interrupts.uint64 *scratch timer_scratch[id][0];scratch[3] CLINT_MTIMECMP(id);scratch[4] interval;w_mscratch((uint64)scratch);// set the machine-mode trap handler.w_mtvec((uint64)timervec);// enable machine-mode interrupts.w_mstatus(r_mstatus() | MSTATUS_MIE);// enable machine-mode timer interrupts.w_mie(r_mie() | MIE_MTIE);
} 时钟中断处理程序
当发生时钟中断的时候会跳转到该汇编函数。该函数处理流程如下
原子交换a0和mscratch寄存器这样a0将持有sratch数组的首地址保存a1、a2、a3寄存器的值到sratch数组中因为我们后续要用到这3个寄存器给mtimecmp寄存器加上时钟间隔用于下次的时钟中断手动触发S模式下的软件中断恢复a1、a2、a3寄存器和mscratch寄存器执行mret指令返回操作系统 ## machine-mode timer interrupt.#
.globl timervec
.align 4
timervec:# start.c has set up the memory that mscratch points to:# scratch[0,8,16] : register save area.# scratch[24] : address of CLINTs MTIMECMP register.# scratch[32] : desired interval between interrupts.csrrw a0, mscratch, a0sd a1, 0(a0)sd a2, 8(a0)sd a3, 16(a0)# schedule the next timer interrupt# by adding interval to mtimecmp.ld a1, 24(a0) # CLINT_MTIMECMP(hart)ld a2, 32(a0) # intervalld a3, 0(a1)add a3, a3, a2sd a3, 0(a1)# arrange for a supervisor software interrupt# after this handler returns.li a1, 2csrw sip, a1ld a3, 16(a0)ld a2, 8(a0)ld a1, 0(a0)csrrw a0, mscratch, a0mret
参考资料
3. 处理时钟中断 | XV6 源代码阅读指南 (gitbook.io)
The xv6 Kernel-13 entry.S start.c_哔哩哔哩_bilibili