-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimer.c
More file actions
41 lines (31 loc) · 1.33 KB
/
timer.c
File metadata and controls
41 lines (31 loc) · 1.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdint.h>
#include "kernel.h"
// --- Hardware Definitions (CLINT Timer) ---
#define CLINT_BASE 0x02000000UL
// Use direct pointers instead of MMIO helpers for maximum reliability
#define MTIMECMP_PTR (volatile uint64_t *)(CLINT_BASE + 0x4000)
#define MTIME_PTR (volatile uint64_t *)(CLINT_BASE + 0xBFF8)
// Assuming 10 MHz clock frequency for QEMU's CLINT
#define CLOCKS_PER_SEC 10000000UL
// Interrupt 10 times per second (100ms interval)
#define TIMER_INTERVAL (CLOCKS_PER_SEC / 10)
// --- Timer Logic ---
void set_next_timer_interrupt() {
// Read current time
uint64_t now = *MTIME_PTR;
// Set mtimecmp to the current time + the interval
uint64_t next_tick = now + TIMER_INTERVAL;
// Write the next comparison value
*MTIMECMP_PTR = next_tick;
}
void timer_init() {
// 1. CRITICAL: Clear any pending M-mode software interrupts (MSIP)
// This is often needed when transitioning to S-mode
asm volatile("csrc mip, %0" : : "r" (1UL << 3)); // Clear MSIP (bit 3)
// 2. Set the first interrupt
set_next_timer_interrupt();
// 3. Enable Machine-mode Timer Interrupt (MTIE) in the MIE CSR
// OpenSBI will delegate this signal to S-mode
asm volatile("csrs mie, %0" : : "r" (1UL << 7));
// uart_puts removed to prevent hang if timer.c is running before UART is initialized
}