13
#include <asm/interrupts.h>
15
#include <framework/mod/options.h>
18
#include <hal/system.h>
19
#include <kernel/irq.h>
20
#include <kernel/time/clock_source.h>
21
#include <kernel/time/time.h>
22
#include <drivers/interrupt/riscv_clint.h>
24
#define COUNT_OFFSET (RTC_CLOCK / JIFFIES_PERIOD)
25
#define RTC_CLOCK OPTION_GET(NUMBER, rtc_freq)
27
#define OPENSBI_TIMER 0x54494D45
29
static int clock_handler(unsigned int irq_nr, void *dev_id) {
32
register uintptr_t a7 asm("a7") = (uintptr_t)(OPENSBI_TIMER);
33
register uintptr_t a6 asm("a6") = (uintptr_t)(0);
34
register uintptr_t a0 asm("a0") = 0;
35
asm volatile("rdtime a0");
36
a0 = a0 + COUNT_OFFSET;
39
asm volatile("ecall");
41
clint_set_mtimecmp(clint_get_mtime() + COUNT_OFFSET);
43
clock_tick_handler(dev_id);
48
static int riscv_clock_setup(struct clock_source *cs) {
50
register uintptr_t a7 asm("a7") = (uintptr_t)(OPENSBI_TIMER);
51
register uintptr_t a6 asm("a6") = (uintptr_t)(0);
52
register uintptr_t a0 asm("a0") = 0;
53
asm volatile("rdtime a0");
54
a0 = a0 + COUNT_OFFSET;
57
asm volatile("ecall");
59
clint_set_mtimecmp(clint_get_mtime() + COUNT_OFFSET);
62
enable_timer_interrupts();
67
static struct time_event_device riscv_event_device = {
68
.set_periodic = riscv_clock_setup,
73
CLOCK_SOURCE_DEF(riscv_clk, NULL, NULL, &riscv_event_device, NULL);
75
RISCV_TIMER_IRQ_DEF(clock_handler, &CLOCK_SOURCE_NAME(riscv_clk));