#include #define VIRT_RTC_BASE 0x0101000UL #define VIRT_RTC_SIZE 0x1000 #define RTC_TIME_LOW 0x00 #define RTC_TIME_HIGH 0x04 #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 static inline uint32_t mmio_read32(uintptr_t addr) { return *(volatile uint32_t *)addr; } static inline void mmio_write32(uintptr_t addr, uint32_t value) { *(volatile uint32_t *)addr = value; } uint64_t rtc_read_time(void) { uint32_t low = mmio_read32(VIRT_RTC_BASE + RTC_TIME_LOW); uint32_t high = mmio_read32(VIRT_RTC_BASE + RTC_TIME_HIGH); return ((uint64_t)high << 32) | low; } 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); } 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); 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); }