diff --git a/.clang-format b/.clang-format index 1edc97c..f98c612 100644 --- a/.clang-format +++ b/.clang-format @@ -8,11 +8,11 @@ AllowShortFunctionsOnASingleLine: false AlwaysBreakTemplateDeclarations: true BreakConstructorInitializers: BeforeComma AlignConsecutiveDeclarations: - Enabled: true + Enabled: true AcrossEmptyLines: false AcrossComments: false AlignCompound: false - AlignFunctionPointers: false + AlignFunctionPointers: true PadOperators: false AlignConsecutiveMacros: true AllowShortCaseLabelsOnASingleLine: true diff --git a/Makefile b/Makefile index 5622f00..3e7e62a 100644 --- a/Makefile +++ b/Makefile @@ -26,11 +26,13 @@ ASFLAGS = -march=rv64gc -mabi=lp64 LDFLAGS = -Tkern/kernel.ld LDFLAGS += -m elf64lriscv -CFLAGS = -Wall -Werror -O -CFLAGS += -Wno-unused-result -CFLAGS += -Wno-unused-variable +# See: https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/RISC-V-Options.html#index-march-14 CFLAGS += -mcmodel=medany CFLAGS += -march=rv64gc -mabi=lp64 + +CFLAGS += -Wall -Werror -O +CFLAGS += -Wno-unused-result +CFLAGS += -Wno-unused-variable CFLAGS += -ffreestanding CFLAGS += -fno-common CFLAGS += -nostdlib diff --git a/kern/libkern/badrand.c b/kern/libkern/badrand.c index f7c06f8..2f35c34 100644 --- a/kern/libkern/badrand.c +++ b/kern/libkern/badrand.c @@ -1,4 +1,5 @@ #include "badrand.h" +#include "stdio.h" #include #include @@ -49,4 +50,30 @@ void sbadrand(uint64_t s) { } } +/* Simple but dumb sanity check for randomness */ +int looks_random(char *buf, size_t len) { + int counts[256] = {0}; + int run = 1, max_run = 1; + + for (size_t i = 0; i < len; i++) { + counts[(unsigned int)buf[i]]++; + if (i > 0 && buf[i] == buf[i - 1]) { + if (++run > max_run) + max_run = run; + } else { + run = 1; + } + } + + for (int i = 0; i < 256; i++) { + if (counts[i] > (int)(len * 1 / 10)) + return 0; + } + + if (max_run > 16) + return 0; + + return 1; +} + #undef PRAND_BUILD_SEED diff --git a/kern/libkern/badrand.h b/kern/libkern/badrand.h index 6710b89..ee1b173 100644 --- a/kern/libkern/badrand.h +++ b/kern/libkern/badrand.h @@ -45,4 +45,6 @@ uint64_t badrand_range(uint64_t min, uint64_t max); */ void badrand_buf(char *buf, size_t len); +int looks_random(char *buf, size_t len); + #endif // BADRAND_H diff --git a/kern/libkern/hexdump.c b/kern/libkern/hexdump.c index 6eaa377..ceeb2d1 100644 --- a/kern/libkern/hexdump.c +++ b/kern/libkern/hexdump.c @@ -1,5 +1,5 @@ -#include #include +#include #include void hexdump(const void *data, size_t size) { diff --git a/kern/rtc.c b/kern/rtc.c index acc4c09..f7d92a0 100644 --- a/kern/rtc.c +++ b/kern/rtc.c @@ -21,12 +21,17 @@ static inline void mmio_write32(uintptr_t addr, uint32_t value) { *(volatile uint32_t *)addr = value; } -uint64_t rtc_read_time(void) { +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); diff --git a/kern/rtc.h b/kern/rtc.h index 656cf04..b33c748 100644 --- a/kern/rtc.h +++ b/kern/rtc.h @@ -3,7 +3,16 @@ #include -uint64_t rtc_read_time(void); +struct rtc_class_ops { + uint64_t (*read_time)(void); + void (*set_time)(uint64_t); + uint64_t (*read_alarm)(uint64_t); + void (*set_alarm)(uint64_t); + void (*alarm_irq_enable)(void); +}; + +uint64_t rtc_time_read(void); +void rtc_time_set(uint64_t ns); void rtc_alarm_set(uint64_t ns); uint64_t rtc_alarm_read(void); diff --git a/kern/start.c b/kern/start.c index 38f2922..0452aef 100644 --- a/kern/start.c +++ b/kern/start.c @@ -1,11 +1,11 @@ -#include -#include -#include #include +#include #include #include #include +#include #include +#include #include #include #include @@ -49,7 +49,7 @@ void start() { memory_sweep(heap_start, heap_end); buddy_init(heap_start, heap_end); spinlock_init(&sl); - sbadrand(rtc_read_time() ^ swap64(rtc_read_time())); + 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,8 +83,8 @@ void start() { buddy_free(mem); } { - uint64_t time = rtc_read_time(); - time = rtc_read_time(); + uint64_t time = rtc_time_read(); + time = rtc_time_read(); rtc_alarm_set(time + 3000000000); uint64_t alrm = rtc_alarm_read(); assert(alrm > time); @@ -100,8 +100,10 @@ void start() { } { char buffer[128]; + memset(buffer, 0, 128); + assert(!looks_random(buffer, 128)); badrand_buf(buffer, 128); - hexdump(buffer, 128); + assert(looks_random(buffer, 128)); } kprintf("To exit qemu, press CTRL+a followed by x\n");