mirror of
https://github.com/cccriscv/mini-riscv-os.git
synced 2025-11-16 04:24:33 +00:00
39 lines
1.1 KiB
C
39 lines
1.1 KiB
C
#include "timer.h"
|
|
|
|
// a scratch area per CPU for machine-mode timer interrupts.
|
|
reg_t timer_scratch[NCPU][5];
|
|
|
|
#define interval 20000000 // cycles; about 2 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.
|
|
// int interval = 1000000; // cycles; about 1/10th second in qemu.
|
|
|
|
*(reg_t *)CLINT_MTIMECMP(id) = *(reg_t *)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.
|
|
reg_t *scratch = &timer_scratch[id][0];
|
|
scratch[3] = CLINT_MTIMECMP(id);
|
|
scratch[4] = interval;
|
|
w_mscratch((reg_t)scratch);
|
|
|
|
// enable machine-mode timer interrupts.
|
|
w_mie(r_mie() | MIE_MTIE);
|
|
}
|
|
|
|
static int timer_count = 0;
|
|
|
|
void timer_handler()
|
|
{
|
|
lib_printf("timer_handler: %d\n", ++timer_count);
|
|
int id = r_mhartid();
|
|
*(reg_t *)CLINT_MTIMECMP(id) = *(reg_t *)CLINT_MTIME + interval;
|
|
}
|