feat: implement basic timer
This commit is contained in:
parent
f76ca1ee31
commit
ebdd572f8e
6 changed files with 83 additions and 4 deletions
|
|
@ -6,6 +6,8 @@
|
|||
#include <kernel/plic.h>
|
||||
#include <kernel/interrupts.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/timer.h>
|
||||
|
||||
|
||||
void interrupt_init()
|
||||
{
|
||||
|
|
@ -111,9 +113,7 @@ void handle_interrupt(unsigned long code)
|
|||
switch (code)
|
||||
{
|
||||
case 7:
|
||||
static volatile uint64_t *mtime = (uint64_t *)CLINT_MTIME;
|
||||
static volatile uint64_t *mtimecmp = (uint64_t *)CLINT_MTIMECMP(0);
|
||||
*mtimecmp = *mtime + 100000;
|
||||
timer_tick();
|
||||
break;
|
||||
case 11:
|
||||
volatile uint32_t *claim_reg = (uint32_t *)PLIC_CLAIM(0);
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@
|
|||
#include <kernel/plic.h>
|
||||
#include <kernel/interrupts.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/timer.h>
|
||||
|
||||
void kmain()
|
||||
{
|
||||
zero_bss();
|
||||
plic_init();
|
||||
timer_init();
|
||||
uart_init();
|
||||
page_init();
|
||||
interrupt_init();
|
||||
|
|
@ -17,4 +19,12 @@ void kmain()
|
|||
kprintf("Hello, from %s!", "SquidgeOS");
|
||||
kputs("----------------------");
|
||||
knewline();
|
||||
while (1) {
|
||||
uint64_t ticks = timer_get_ms();
|
||||
kputchar('T');
|
||||
kputchar(':'); // Print "T:1234" every second
|
||||
kprint_int(ticks);
|
||||
knewline();
|
||||
delay_ms(1000);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,13 @@ void plic_init()
|
|||
// This is a bitmask, so we shift 1 by the IRQ number.
|
||||
*PLIC_ENABLE(hart) = (1 << UART_IRQ);
|
||||
|
||||
// Set priority for CLINT timer interrupt (IRQ 5)
|
||||
*PLIC_PRIORITY(TIMER_IRQ) = 1; // Lowest priority
|
||||
|
||||
// Enable CLINT timer interrupt for Hart 0
|
||||
*PLIC_ENABLE(hart) |= (1 << TIMER_IRQ);
|
||||
|
||||
// 3. Set the priority threshold for Hart 0
|
||||
// We set this to 0 so that ANY interrupt with priority > 0 gets through.
|
||||
*PLIC_THRESHOLD(hart) = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#define PLIC_CLAIM(hart) ((volatile uint32_t *)(PLIC_BASE + 0x200004 + (hart) * 0x1000))
|
||||
|
||||
#define UART_IRQ 10
|
||||
#define TIMER_IRQ 5
|
||||
|
||||
void plic_init();
|
||||
|
||||
|
|
|
|||
39
src/kernel/timer.c
Normal file
39
src/kernel/timer.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include <stdint.h>
|
||||
#include "timer.h"
|
||||
#include "plic.h"
|
||||
#include "interrupts.h"
|
||||
|
||||
_Atomic uint64_t sys_ticks = 0;
|
||||
const uint64_t tick_delta = 1000;
|
||||
|
||||
void timer_init() {
|
||||
timer_tick();
|
||||
}
|
||||
|
||||
void timer_tick() {
|
||||
// Set the first timer interrupt to fire after 1ms
|
||||
static volatile uint64_t *mtime = (uint64_t *)CLINT_MTIME;
|
||||
static volatile uint64_t *mtimecmp = (uint64_t *)CLINT_MTIMECMP(0);
|
||||
*mtimecmp = *mtime + tick_delta;
|
||||
sys_ticks++;
|
||||
}
|
||||
|
||||
// Get current time in milliseconds
|
||||
uint64_t timer_get_ms() {
|
||||
return sys_ticks;
|
||||
}
|
||||
|
||||
// Delay for 'ms' milliseconds (blocking)
|
||||
void delay_ms(uint64_t ms) {
|
||||
if (ms == 0) return;
|
||||
uint64_t end = sys_ticks + ms;
|
||||
while (sys_ticks < end) {
|
||||
asm volatile("wfi");
|
||||
}
|
||||
}
|
||||
|
||||
// Sleep for 'ms' milliseconds (non-blocking, if possible)
|
||||
// For now, just call delay_ms (can be improved later)
|
||||
void sleep_ms(uint64_t ms) {
|
||||
delay_ms(ms);
|
||||
}
|
||||
23
src/kernel/timer.h
Normal file
23
src/kernel/timer.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
#include <stdint.h>
|
||||
|
||||
extern _Atomic uint64_t sys_ticks;
|
||||
extern const uint64_t tick_delta;
|
||||
|
||||
// Initialize timer (1ms ticks)
|
||||
void timer_init();
|
||||
|
||||
// Increment the system tick counter
|
||||
void timer_tick();
|
||||
|
||||
// Get current time in milliseconds
|
||||
uint64_t timer_get_ms();
|
||||
|
||||
// Delay for 'ms' milliseconds (blocking)
|
||||
void delay_ms(uint64_t ms);
|
||||
|
||||
// Sleep for 'ms' milliseconds (non-blocking, if possible)
|
||||
void sleep_ms(uint64_t ms);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue