diff --git a/kern/libkern/badrand.c b/kern/libkern/badrand.c index b4937b6..2f35c34 100644 --- a/kern/libkern/badrand.c +++ b/kern/libkern/badrand.c @@ -30,7 +30,8 @@ void badrand_buf(char *buf, size_t len) { unsigned char *p = (unsigned char *)buf; while (len >= 8) { - *(uint64_t *)p = badrand(); + uint64_t r = badrand(); + memcpy(p, &r, 8); p += 8; len -= 8; } diff --git a/kern/rtc.c b/kern/rtc.c index e351d8a..f7d92a0 100644 --- a/kern/rtc.c +++ b/kern/rtc.c @@ -1,6 +1,3 @@ -#include "stdio.h" -#include -#include #include #define VIRT_RTC_BASE 0x0101000UL @@ -11,55 +8,49 @@ #define RTC_ALARM_LOW 0x08 #define RTC_ALARM_HIGH 0x0c -#define RTC_ALARM_STATUS 0x18 -#define RTC_CLEAR_ALARM 0x14 +#define RTC_IRQ_ENABLED 0x10 +#define RTC_CLEAR_ALARM 0x14 +#define RTC_ALARM_STATUS 0x18 +#define RTC_CLEAR_INTERRUPT 0x1c -#define RTC_IRQ_ENABLED 0x10 -#define RTC_IRQ_CLEAR 0x1c +static inline uint32_t mmio_read32(uintptr_t addr) { + return *(volatile uint32_t *)addr; +} -#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)) +static inline void mmio_write32(uintptr_t addr, uint32_t value) { + *(volatile uint32_t *)addr = value; +} -/* Read the current time of the RTC */ uint64_t rtc_time_read(void) { - uint32_t low = GF_REG32(RTC_TIME_LOW); // mmio_read32(VIRT_RTC_BASE + RTC_TIME_LOW); - uint32_t high = GF_REG32(RTC_TIME_HIGH); + 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; } -/* Set the time of the RTC */ void rtc_time_set(uint64_t ns) { - GF_REG32(RTC_TIME_HIGH) = ns >> 32; - GF_REG32(RTC_TIME_LOW) = ns & 0xFFFFFFFF; + mmio_write32(VIRT_RTC_BASE + RTC_TIME_LOW, ns); + mmio_write32(VIRT_RTC_BASE + RTC_TIME_HIGH, ns); } -/* Set the alarm. this will automatically enable it. */ void rtc_alarm_set(uint64_t ns) { - /* Order matters here, low write starts the alarm */ - GF_REG32(RTC_ALARM_HIGH) = ns >> 32; - GF_REG32(RTC_ALARM_LOW) = ns & 0xFFFFFFFF; + 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 = GF_REG32(RTC_ALARM_LOW); - uint32_t high = GF_REG32(RTC_ALARM_HIGH); + 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 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; + return mmio_read32(VIRT_RTC_BASE + RTC_IRQ_ENABLED); } diff --git a/kern/rtc.h b/kern/rtc.h index 026db70..b33c748 100644 --- a/kern/rtc.h +++ b/kern/rtc.h @@ -3,9 +3,6 @@ #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); @@ -19,10 +16,8 @@ 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 diff --git a/kern/start.c b/kern/start.c index ce37c30..0452aef 100644 --- a/kern/start.c +++ b/kern/start.c @@ -46,10 +46,10 @@ void start() { if (unlikely(id == 0)) { /* Here we will do a bunch of initialization steps */ - sbadrand(rtc_time_read() ^ swap64(rtc_time_read())); memory_sweep(heap_start, heap_end); buddy_init(heap_start, heap_end); spinlock_init(&sl); + sbadrand(rtc_time_read() ^ swap64(rtc_time_read())); for (int i = 0; i < banner_len; i++) uart_putc(banner[i]); __sync_synchronize(); hold = 0; @@ -83,20 +83,16 @@ void start() { buddy_free(mem); } { - const uint64_t time = rtc_time_read(); - - /* Set alarm and check that its correct */ - rtc_alarm_set(time + MS_TO_NS(1000)); - const uint64_t alrm = rtc_alarm_read(); - assert(alrm == time + MS_TO_NS(1000)); - - /* Should be one provided alarm is not elapsed */ - assert(rtc_alarm_status() == 1); - rtc_alarm_clear(); - assert(rtc_alarm_status() == 0); - - /* Time should have passed */ - assert(time != rtc_time_read()); + uint64_t time = rtc_time_read(); + time = rtc_time_read(); + rtc_alarm_set(time + 3000000000); + uint64_t alrm = rtc_alarm_read(); + assert(alrm > time); + uint32_t astatus = rtc_alarm_status(); + assert(astatus == 0); + rtc_alarm_enable(); + astatus = rtc_alarm_status(); + assert(astatus == 1); } { uint64_t rn = badrand();