mirror of
https://github.com/cccriscv/mini-riscv-os.git
synced 2025-11-16 12:34:33 +00:00
37 lines
931 B
C
37 lines
931 B
C
#include "timer.h"
|
|
|
|
#define interval 10000000 // cycles; about 1 second in qemu.
|
|
|
|
void timer_init()
|
|
{
|
|
// each CPU has a separate source of timer interrupts.
|
|
int id = r_mhartid();
|
|
|
|
// ask the CLINT for a timer interrupt.
|
|
*(reg_t*)CLINT_MTIMECMP(id) = *(reg_t*)CLINT_MTIME + interval;
|
|
|
|
// set the machine-mode trap handler.
|
|
w_mtvec((reg_t)sys_timer);
|
|
|
|
// enable machine-mode interrupts.
|
|
w_mstatus(r_mstatus() | MSTATUS_MIE);
|
|
|
|
// enable machine-mode timer interrupts.
|
|
w_mie(r_mie() | MIE_MTIE);
|
|
}
|
|
|
|
static int timer_count = 0;
|
|
|
|
reg_t timer_handler(reg_t epc, reg_t cause)
|
|
{
|
|
reg_t return_pc = epc;
|
|
// disable machine-mode timer interrupts.
|
|
w_mie(~((~r_mie()) | (1 << 7)));
|
|
lib_printf("timer_handler: %d\n", ++timer_count);
|
|
int id = r_mhartid();
|
|
*(reg_t *)CLINT_MTIMECMP(id) = *(reg_t *)CLINT_MTIME + interval;
|
|
// enable machine-mode timer interrupts.
|
|
w_mie(r_mie() | MIE_MTIE);
|
|
return return_pc;
|
|
}
|