56 lines
1.5 KiB
C
56 lines
1.5 KiB
C
#include <stdint.h>
|
|
|
|
#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_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);
|
|
return ((uint64_t)high << 32) | low;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|