Compare commits
4 commits
cb0ad6a2a5
...
31ecdffa7e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31ecdffa7e | ||
|
|
3e94e11212 | ||
|
|
623f3e8335 | ||
|
|
6e266e0905 |
4 changed files with 59 additions and 42 deletions
|
|
@ -30,8 +30,7 @@ void badrand_buf(char *buf, size_t len) {
|
|||
unsigned char *p = (unsigned char *)buf;
|
||||
|
||||
while (len >= 8) {
|
||||
uint64_t r = badrand();
|
||||
memcpy(p, &r, 8);
|
||||
*(uint64_t *)p = badrand();
|
||||
p += 8;
|
||||
len -= 8;
|
||||
}
|
||||
|
|
|
|||
63
kern/rtc.c
63
kern/rtc.c
|
|
@ -1,3 +1,6 @@
|
|||
#include "stdio.h"
|
||||
#include <assert.h>
|
||||
#include <rtc.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
|
|
|
|||
26
kern/start.c
26
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,16 +83,20 @@ void start() {
|
|||
buddy_free(mem);
|
||||
}
|
||||
{
|
||||
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);
|
||||
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 rn = badrand();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue