From 3e94e1121254b5213fff6af561c45136ff645d6d Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Thu, 30 Oct 2025 22:36:50 +0100 Subject: [PATCH] RTC work --- kern/rtc.c | 63 +++++++++++++++++++++++++++++++----------------------- kern/rtc.h | 9 ++++++-- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/kern/rtc.c b/kern/rtc.c index f7d92a0..e351d8a 100644 --- a/kern/rtc.c +++ b/kern/rtc.c @@ -1,3 +1,6 @@ +#include "stdio.h" +#include +#include #include #define VIRT_RTC_BASE 0x0101000UL @@ -8,49 +11,55 @@ #define RTC_ALARM_LOW 0x08 #define RTC_ALARM_HIGH 0x0c -#define RTC_IRQ_ENABLED 0x10 -#define RTC_CLEAR_ALARM 0x14 -#define RTC_ALARM_STATUS 0x18 -#define RTC_CLEAR_INTERRUPT 0x1c +#define RTC_ALARM_STATUS 0x18 +#define RTC_CLEAR_ALARM 0x14 -static inline uint32_t mmio_read32(uintptr_t addr) { - return *(volatile uint32_t *)addr; -} +#define RTC_IRQ_ENABLED 0x10 +#define RTC_IRQ_CLEAR 0x1c -static inline void mmio_write32(uintptr_t addr, uint32_t value) { - *(volatile uint32_t *)addr = value; -} +#define REG32(addr) (*((volatile uint32_t *)(addr))) +#define REG64(addr) (*((volatile uint64_t *)(addr))) +#define GF_REG32(offset) (REG32(VIRT_RTC_BASE + offset)) +#define GF_REG64(offset) (REG64(VIRT_RTC_BASE + offset)) +/* Read the current time of the RTC */ uint64_t rtc_time_read(void) { - uint32_t low = mmio_read32(VIRT_RTC_BASE + RTC_TIME_LOW); - uint32_t high = mmio_read32(VIRT_RTC_BASE + RTC_TIME_HIGH); + uint32_t low = GF_REG32(RTC_TIME_LOW); // mmio_read32(VIRT_RTC_BASE + RTC_TIME_LOW); + uint32_t high = GF_REG32(RTC_TIME_HIGH); return ((uint64_t)high << 32) | low; } +/* Set the time of the RTC */ void rtc_time_set(uint64_t ns) { - mmio_write32(VIRT_RTC_BASE + RTC_TIME_LOW, ns); - mmio_write32(VIRT_RTC_BASE + RTC_TIME_HIGH, ns); + GF_REG32(RTC_TIME_HIGH) = ns >> 32; + GF_REG32(RTC_TIME_LOW) = ns & 0xFFFFFFFF; } +/* Set the alarm. this will automatically enable it. */ void rtc_alarm_set(uint64_t ns) { - mmio_write32(VIRT_RTC_BASE + RTC_ALARM_HIGH, ns >> 32); - mmio_write32(VIRT_RTC_BASE + RTC_ALARM_LOW, ns & 0xffffffff); + /* Order matters here, low write starts the alarm */ + GF_REG32(RTC_ALARM_HIGH) = ns >> 32; + GF_REG32(RTC_ALARM_LOW) = ns & 0xFFFFFFFF; } uint64_t rtc_alarm_read(void) { - uint32_t low = mmio_read32(VIRT_RTC_BASE + RTC_ALARM_LOW); - uint32_t high = mmio_read32(VIRT_RTC_BASE + RTC_ALARM_HIGH); + uint32_t low = GF_REG32(RTC_ALARM_LOW); + uint32_t high = GF_REG32(RTC_ALARM_HIGH); return ((uint64_t)high << 32) | low; } -void rtc_alarm_enable(void) { - mmio_write32(VIRT_RTC_BASE + RTC_IRQ_ENABLED, 1); -} - -void rtc_alarm_disable(void) { - mmio_write32(VIRT_RTC_BASE + RTC_IRQ_ENABLED, 0); -} - uint32_t rtc_alarm_status(void) { - return mmio_read32(VIRT_RTC_BASE + RTC_IRQ_ENABLED); + return GF_REG32(RTC_ALARM_STATUS) & 0x1; +} + +void rtc_alarm_clear(void) { + GF_REG32(RTC_CLEAR_ALARM) = 1; +} + +void rtc_irq_clear(void) { + GF_REG32(RTC_IRQ_CLEAR) = 1; +} + +uint32_t rtc_irq_enabled(void) { + return GF_REG32(RTC_IRQ_ENABLED) & 0x1; } diff --git a/kern/rtc.h b/kern/rtc.h index b33c748..026db70 100644 --- a/kern/rtc.h +++ b/kern/rtc.h @@ -3,6 +3,9 @@ #include +#define MS_TO_NS(ms) ((uint64_t)(ms) * 1000ULL * 1000ULL) +#define NS_TO_MS(ms) ((uint64_t)(ms) / (1000ULL * 1000ULL)) + struct rtc_class_ops { uint64_t (*read_time)(void); void (*set_time)(uint64_t); @@ -16,8 +19,10 @@ void rtc_time_set(uint64_t ns); void rtc_alarm_set(uint64_t ns); uint64_t rtc_alarm_read(void); -void rtc_alarm_enable(void); -void rtc_alarm_disable(void); uint32_t rtc_alarm_status(void); +void rtc_alarm_clear(void); + +void rtc_irq_clear(void); +uint32_t rtc_irq_enabled(void); #endif // RTC_H