From d8c0a8d500ee6ccf3e421c2985314f0492c5fbe8 Mon Sep 17 00:00:00 2001 From: Saurabh Singh Date: Sat, 18 May 2024 23:55:40 -0400 Subject: [PATCH] add timer driver and testcase --- sw/examples/interrupt/Makefile.include | 2 ++ sw/examples/interrupt/interrupt.c | 35 ++++++++++++++++++++++++++ sw/lib/include/timer.h | 8 ++++++ sw/lib/libcatom/hydrogensoc/timer.c | 27 ++++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 sw/examples/interrupt/Makefile.include create mode 100644 sw/examples/interrupt/interrupt.c create mode 100644 sw/lib/include/timer.h create mode 100644 sw/lib/libcatom/hydrogensoc/timer.c diff --git a/sw/examples/interrupt/Makefile.include b/sw/examples/interrupt/Makefile.include new file mode 100644 index 0000000..ef4eb5d --- /dev/null +++ b/sw/examples/interrupt/Makefile.include @@ -0,0 +1,2 @@ +src_files = interrupt.c +executable = interrupt.elf \ No newline at end of file diff --git a/sw/examples/interrupt/interrupt.c b/sw/examples/interrupt/interrupt.c new file mode 100644 index 0000000..bda3792 --- /dev/null +++ b/sw/examples/interrupt/interrupt.c @@ -0,0 +1,35 @@ +#include +#include +#include + +#define TIMER_INTERRUPT_DELAY 1000 + +void timer_interrupt_handler(){ + // Clear interrupt + timer_clear_interrupt(); + puts("!!! Caught timer interrupt !!!\n"); +} + +void setup_timer_interrupt() { + // Register Interrupt handler + register_interrupt_handler(7, timer_interrupt_handler); + + // Request timer interrupt + timer_get_interrupt(TIMER_INTERRUPT_DELAY); + + // Enable interrupts in core + arch_en_mti(); + arch_en_int(); +} + +void main() +{ + serial_init(UART_BAUD_115200); + puts("Before interrupt\n"); + + setup_timer_interrupt(); + asm volatile("wfi"); // wait for interrupt + + puts("After interrupt\n"); + return; +} diff --git a/sw/lib/include/timer.h b/sw/lib/include/timer.h new file mode 100644 index 0000000..9f88c46 --- /dev/null +++ b/sw/lib/include/timer.h @@ -0,0 +1,8 @@ +#pragma once +#include + +uint64_t timer_get_time(); + +void timer_get_interrupt(uint64_t time); + +void timer_clear_interrupt(); diff --git a/sw/lib/libcatom/hydrogensoc/timer.c b/sw/lib/libcatom/hydrogensoc/timer.c new file mode 100644 index 0000000..4f95b8e --- /dev/null +++ b/sw/lib/libcatom/hydrogensoc/timer.c @@ -0,0 +1,27 @@ +#include +#include +#include + +#define TIMER_REG_MTIME 0x0 +#define TIMER_REG_MTIMEH 0x4 +#define TIMER_REG_MTIMECMP 0x8 +#define TIMER_REG_MTIMECMPH 0xc + +uint64_t timer_get_time() { + uint64_t time = (uint64_t) REG32(TIMER_ADDR, TIMER_REG_MTIMEH); + time = (time << 32 ) | (uint64_t) REG32(TIMER_ADDR, TIMER_REG_MTIME); + return time; +} + +void timer_get_interrupt(uint64_t time){ + uint64_t curtime = (uint64_t) REG32(TIMER_ADDR, TIMER_REG_MTIMEH); + curtime = (curtime << 32 ) | (uint64_t) REG32(TIMER_ADDR, TIMER_REG_MTIME); + uint64_t exp_time = curtime + time; + REG32(TIMER_ADDR, TIMER_REG_MTIMECMPH) = 0xffffffff & (exp_time >> 32); + REG32(TIMER_ADDR, TIMER_REG_MTIMECMP) = 0xffffffff & exp_time; +} + +void timer_clear_interrupt(){ + REG32(TIMER_ADDR, TIMER_REG_MTIMECMPH) = (uint32_t)-1; + REG32(TIMER_ADDR, TIMER_REG_MTIMECMP) = (uint32_t)-1; +} \ No newline at end of file