Compare commits

..

16 commits

Author SHA1 Message Date
Imbus
cea6d7505f Include endian.h 2025-10-01 02:54:15 +02:00
Imbus
65d7cfe584 Test badrand in start.c 2025-10-01 02:53:40 +02:00
Imbus
2223a42488 Test rtc in main 2025-10-01 02:53:33 +02:00
Imbus
8d8ad077ce Include rtc... 2025-10-01 02:53:13 +02:00
Imbus
f6e543b64d Free the freelist allocation in start.c test, better logging messages 2025-10-01 02:53:03 +02:00
Imbus
cc24fb66eb Test hexdump in start.c 2025-10-01 02:52:20 +02:00
Imbus
795cf84a07 Fix format specifier that doesnt exist in neptune 2025-10-01 02:51:37 +02:00
Imbus
1ed4b57882 hexdump.[ch]: utility function for dumping memory regions as hex 2025-10-01 02:48:32 +02:00
Imbus
f4342ab221 ctype.h: include isprint 2025-10-01 02:48:03 +02:00
Imbus
802ac9c012 Seed badrand with an rtc read xored with itself (its called BADrand for a reason) 2025-10-01 02:42:45 +02:00
Imbus
0dbb13fea0 Extend badrand with badrand_buf 2025-10-01 02:41:09 +02:00
Imbus
6c3d50b6a5 Allow unused for now 2025-10-01 02:40:50 +02:00
Imbus
6a2c1f4ea9 Include rtc in build 2025-10-01 02:40:43 +02:00
Imbus
2fd62c52b4 Replace __sync compiler intrinsics with 'modern' __atomic 2025-10-01 02:40:30 +02:00
Imbus
9d6c9a8bc5 Initial RTC driver for google goldfish 2025-10-01 02:40:06 +02:00
Imbus
111d41d610 Buddy bugfix 2025-10-01 02:39:49 +02:00
10 changed files with 173 additions and 8 deletions

View file

@ -28,6 +28,7 @@ LDFLAGS += -m elf64lriscv
CFLAGS = -Wall -Werror -O
CFLAGS += -Wno-unused-result
CFLAGS += -Wno-unused-variable
CFLAGS += -mcmodel=medany
CFLAGS += -march=rv64gc -mabi=lp64
CFLAGS += -ffreestanding
@ -55,6 +56,7 @@ quickstart:
KERNEL_OBJ := \
kern/entry.o \
kern/start.o \
kern/rtc.o \
kern/libkern/freelist.o \
kern/libkern/string.o \
kern/libkern/proc.o \
@ -65,7 +67,8 @@ KERNEL_OBJ := \
kern/libkern/mini-printf.o \
kern/libkern/stdio.o \
kern/libkern/buddy.o \
kern/libkern/badrand.o
kern/libkern/badrand.o \
kern/libkern/hexdump.o
kern/kernel.elf: $(KERNEL_OBJ)
@echo LD $@

View file

@ -1,5 +1,6 @@
#include "badrand.h"
#include <stdint.h>
#include <string.h>
#define PRAND_BUILD_SEED \
((uint64_t)(__TIME__[0]) * (uint64_t)(__TIME__[1]) * (uint64_t)(__TIME__[3]) * (uint64_t)(__TIME__[4]) * \
@ -24,7 +25,23 @@ uint64_t badrand_range(uint64_t min, uint64_t max) {
return min + (x % range);
}
void sbadprand(uint64_t s) {
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);
p += 8;
len -= 8;
}
if (len > 0) {
uint64_t r = badrand();
memcpy(p, &r, len);
}
}
void sbadrand(uint64_t s) {
if (s) {
seed ^= (s * 0x9e3779b97f4a7c15ULL) + (seed << 6) + (seed >> 2);
} else {

View file

@ -40,4 +40,9 @@ uint64_t badrand();
*/
uint64_t badrand_range(uint64_t min, uint64_t max);
/**
* @brief Fills buffer with random data
*/
void badrand_buf(char *buf, size_t len);
#endif // BADRAND_H

View file

@ -104,7 +104,7 @@ int buddy_free(void *ptr) {
block_header_t *hdr = (block_header_t *)ptr - 1;
int order = hdr->order;
assert_msg(order != MAX_ORDER, "The buddy freelist header seems to have been corrupted.");
assert_msg(order <= MAX_ORDER, "The buddy freelist header seems to have been corrupted.");
uintptr_t addr = (uintptr_t)ptr;

8
kern/libkern/ctype.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef CTYPE_H
#define CTYPE_H
static inline int isprint(int c) {
return (unsigned)c - 0x20 < 0x5f;
}
#endif // CTYPE_H

34
kern/libkern/hexdump.c Normal file
View file

@ -0,0 +1,34 @@
#include <stddef.h>
#include <ctype.h>
#include <stdio.h>
void hexdump(const void *data, size_t size) {
const unsigned char *p = (const unsigned char *)data;
size_t i, j;
for (i = 0; i < size; i += 16) {
// Print offset
kprintf("%08x ", i);
// Print hex bytes
for (j = 0; j < 16; j++) {
if (i + j < size) {
kprintf("%02X ", p[i + j]);
} else {
kprintf(" "); // padding for incomplete lines
}
if (j == 7)
kprintf(" "); // extra space in middle
}
kprintf(" |");
// Print ASCII characters
for (j = 0; j < 16 && i + j < size; j++) {
unsigned char c = p[i + j];
kprintf("%c", isprint(c) ? c : '.');
}
kprintf("|\n");
}
}

8
kern/libkern/hexdump.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef HEXDUMP_H
#define HEXDUMP_H
#include <stddef.h>
void hexdump(const void *data, size_t size);
#endif // HEXDUMP_H

51
kern/rtc.c Normal file
View file

@ -0,0 +1,51 @@
#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_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);
}

14
kern/rtc.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef RTC_H
#define RTC_H
#include <stdint.h>
uint64_t rtc_read_time(void);
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);
#endif // RTC_H

View file

@ -1,3 +1,6 @@
#include <endian.h>
#include <badrand.h>
#include <hexdump.h>
#include <assert.h>
#include <banner.h>
#include <buddy.h>
@ -7,6 +10,7 @@
#include <panic.h>
#include <proc.h>
#include <riscv.h>
#include <rtc.h>
#include <spinlock.h>
#include <stdint.h>
#include <stdio.h>
@ -30,8 +34,7 @@ volatile int max_hart = 0;
/* This is where entry.S drops us of. All cores land here */
void start() {
// Do this first
__sync_fetch_and_add(&max_hart, 1);
__sync_synchronize();
__atomic_fetch_add(&max_hart, 1, __ATOMIC_SEQ_CST);
u64 id = read_mhartid();
@ -46,6 +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()));
for (int i = 0; i < banner_len; i++) uart_putc(banner[i]);
__sync_synchronize();
hold = 0;
@ -68,16 +72,37 @@ void start() {
fl_init(&fl, (uintptr_t)mem, 4096, sizeof(int));
uint32_t *hello = fl_alloc(&fl);
*hello = UINT32_MAX;
fl_free(&fl, hello);
int a = fl_available(&fl);
assert_msg(fl_check(&fl) > 0, "FreeList checking failed, might be corrupt.");
kprintf("Available: %d\n", a);
kprintf("Size: %d\n", fl.size);
kprintf("Freelist available: %d\n", a);
kprintf("Freelist item size: %d\n", fl.size);
buddy_free(mem);
}
{
uint64_t time = rtc_read_time();
time = rtc_read_time();
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();
assert(rn != badrand());
}
{
char buffer[128];
badrand_buf(buffer, 128);
hexdump(buffer, 128);
}
kprintf("To exit qemu, press CTRL+a followed by x\n");
spin_unlock(&sl);