From a3c174ee4c08d1d5e7a89ce187f52e3c0807a7eb Mon Sep 17 00:00:00 2001 From: stefan Date: Sun, 23 Apr 2023 17:00:14 -0400 Subject: memory detection --- include/stdint.h | 6 ++++++ mainboard/virt/conf/mainboard.conf | 2 +- sys/dev/dev_init.c | 42 +++++++++++++++++++++++++++++++------- sys/include/asm.h | 6 ++++++ sys/include/dev.h | 32 ++++++++++++++++++++++++++++- sys/include/kalloc.h | 2 +- sys/include/sbi.h | 8 ++++++++ sys/include/vm.h | 6 ++++++ sys/sys/init.c | 10 ++++++--- sys/sys/mm/kalloc.c | 14 ++++++++----- sys/sys/vm/vm.c | 10 +++++++++ 11 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 sys/include/vm.h create mode 100644 sys/sys/vm/vm.c diff --git a/include/stdint.h b/include/stdint.h index c811a87..1eb35a1 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -14,6 +14,12 @@ typedef long int64_t; typedef unsigned long uintptr_t; +#if __riscv_xlen == 32 +typedef unsigned int uintptr_t; +#elif __riscv_xlen == 64 +typedef unsigned long uintptr_t; +#endif + #define INT16_MIN (-1-0x7fff) #define INT32_MIN (-1-0x7fffffff) #define INT64_MIN (-1-0x7fffffffffffffff) diff --git a/mainboard/virt/conf/mainboard.conf b/mainboard/virt/conf/mainboard.conf index 1812b3b..fab89a7 100644 --- a/mainboard/virt/conf/mainboard.conf +++ b/mainboard/virt/conf/mainboard.conf @@ -1,4 +1,4 @@ LOAD_ADDR=0x80200000 PAGE_SIZE=4096 NPROC=2 -DEBUG=qemu-system-riscv64 -nographic -machine virt -smp ${NPROC} -m 128M -bios default -gdb tcp::${GDB_PORT} -kernel +DEBUG=qemu-system-riscv64 -nographic -machine virt -smp ${NPROC} -m 128M -bios default -device virtio-gpu-device -gdb tcp::${GDB_PORT} -kernel diff --git a/sys/dev/dev_init.c b/sys/dev/dev_init.c index fc70853..9933c2a 100644 --- a/sys/dev/dev_init.c +++ b/sys/dev/dev_init.c @@ -5,18 +5,46 @@ #include #include -void -dev_init(struct fdt_header *fdt) + +static void +mem_init(struct fdt_header *fdt, struct devicetree *dt) { + + int memory = fdt_path_offset(fdt, "/memory"); + if (memory < 0) + printf("[dev_init] failed to find memory node\n"); + + int len; + + struct _reg *val = fdt_getprop(fdt, memory, "reg", &len); + /* bad idea */ + dt->memory.origin = fdt64_to_cpu(val->address); + dt->memory.size = fdt64_to_cpu(val->size); + printf("[mem_init] found %dMB of memory at %p\n", dt->memory.size >> 20, dt->memory.origin); + + int n = fdt_num_mem_rsv(fdt); + printf("[mem_init] found %d memory reserve map entries\n", n); +} + + +struct devicetree +dev_init(struct fdt_header *fdt) +{ + struct devicetree dt = {0}; + if (fdt_check_header(fdt) == 0) printf("[dev_init] valid fdt at %p\n", fdt); else printf("[dev_init] error: fdt_check_header()\n"); - int offset = fdt_next_node(fdt, offset, 0); - do { - printf("[dev_init] found %s\n", fdt_get_name(fdt, offset, NULL)); - offset = fdt_next_node(fdt, offset, 0); - } while (offset != -FDT_ERR_NOTFOUND); + printf("[dev_init] detecting memory...\n"); + mem_init(fdt, &dt); + +// int offset = fdt_next_node(fdt, offset, 0); +// do { +// printf("[dev_init] found %s\n", fdt_get_name(fdt, offset, 0)); +// offset = fdt_next_node(fdt, offset, 0); +// } while (offset != -FDT_ERR_NOTFOUND); + return dt; } diff --git a/sys/include/asm.h b/sys/include/asm.h index 0995f88..d345712 100644 --- a/sys/include/asm.h +++ b/sys/include/asm.h @@ -53,4 +53,10 @@ read_tp(void) return x; } +static inline void +csrw_satp(uint64_t x) +{ + asm volatile("csrw satp, %0" : : "r"(x)); +} + #endif /* _ASM_H */ diff --git a/sys/include/dev.h b/sys/include/dev.h index b8bfef8..657c04c 100644 --- a/sys/include/dev.h +++ b/sys/include/dev.h @@ -2,7 +2,37 @@ #define _DEV_H #include +#include -void dev_init(struct fdt_header* fdt); +enum { DT_MMUTYPE_SV32, DT_MMUTYPE_SV39, DT_MMUTYPE_SV48 }; + +struct _reg { + fdt64_t address; + fdt64_t size; +}; +/* unflattend device tree */ +struct devicetree { + const char *compat; + const char *model; + int nproc; + /* main cpu, monitor/alternative cores will be ignored for now */ + struct { + short mmu_type; + const char *isa; + unsigned int freq; + } cpu; + struct { + uintptr_t origin; + uintptr_t size; + } memory; + struct { + unsigned int freq; + const char *compat; + int interrupt; + struct _reg reg; + } uart; +}; + +struct devicetree dev_init(struct fdt_header* fdt); #endif /* _DEV_H */ diff --git a/sys/include/kalloc.h b/sys/include/kalloc.h index 10adbda..5553d94 100644 --- a/sys/include/kalloc.h +++ b/sys/include/kalloc.h @@ -7,7 +7,7 @@ void *kzalloc(void); void kfree(void *); -void kalloc_init(void); +void kalloc_init(size_t); void walkfree(void); diff --git a/sys/include/sbi.h b/sys/include/sbi.h index 94c3749..86ca295 100644 --- a/sys/include/sbi.h +++ b/sys/include/sbi.h @@ -1,6 +1,8 @@ #ifndef _SBI_H #define _SBI_H +#include + struct sbiret { long err; long val; @@ -58,6 +60,12 @@ sbi_console_putchar(int c) sbi_ecall(1, 0, c, 0, 0, 0, 0, 0); } +static inline void +sbi_debug_console_write_byte(uint8_t byte) +{ + sbi_ecall(0x4442434E, 0x2, 'c', 0, 0, 0, 0, 0); +} + static inline void sbi_shutdown(void) { diff --git a/sys/include/vm.h b/sys/include/vm.h new file mode 100644 index 0000000..1883ea7 --- /dev/null +++ b/sys/include/vm.h @@ -0,0 +1,6 @@ +#ifndef _VM_H +#define _VM_H + +void vminit(void); + +#endif /* _VM_H */ diff --git a/sys/sys/init.c b/sys/sys/init.c index 48aeb97..05e8d49 100644 --- a/sys/sys/init.c +++ b/sys/sys/init.c @@ -20,12 +20,16 @@ init(unsigned long hartid, struct fdt_header *fdt) printf("booting from hart #%d\n", hartid); - printf("setting up the heap at %p\n", HEAP_START); - kalloc_init(); printf_init(); printf("done!\n"); - dev_init(fdt); + struct devicetree dt = dev_init(fdt); + + printf("setting up page frame allocator at %p\n", HEAP_START); + kalloc_init(dt.memory.origin + dt.memory.size); + printf("done!\n"); + +// walkfree(); printf("bringing up other harts...\n"); for (int i = 0; i < NPROC; ++i) { diff --git a/sys/sys/mm/kalloc.c b/sys/sys/mm/kalloc.c index 6cf888a..db2bea8 100644 --- a/sys/sys/mm/kalloc.c +++ b/sys/sys/mm/kalloc.c @@ -6,13 +6,15 @@ #include #include +#define ALIGNPG(n) (((n) + (uintptr_t)PAGE_SIZE - 1) & ~((uintptr_t)PAGE_SIZE)) + extern uint64_t HEAP_START; typedef struct freenode { struct freenode *next; } freenode_t; -freenode_t *head = NULL; +freenode_t *head = {0}; static spinlock_t mutex; void * @@ -40,8 +42,9 @@ kzalloc(void) void kfree(void *p) { - if (p == NULL || (uint64_t)p % (uint64_t)PAGE_SIZE) + if (p == NULL) { return; + } acquire(&mutex); freenode_t *tmp = head; @@ -51,11 +54,12 @@ kfree(void *p) } void -kalloc_init(void) +kalloc_init(uintptr_t end) { initlock(&mutex); freenode_t *p = (freenode_t*)HEAP_START; - for (;(unsigned long)p + PAGE_SIZE <= (HEAP_START + 0x100000); p += PAGE_SIZE) { + end = ALIGNPG(end); + for (;(unsigned long)p + PAGE_SIZE <= end; p += PAGE_SIZE) { kfree(p); } } @@ -65,7 +69,7 @@ walkfree(void) { freenode_t *node = head; int nfree = 0; - while (node) { + while (node != NULL) { printf("freenode at %p\n", node); node = node->next; nfree++; diff --git a/sys/sys/vm/vm.c b/sys/sys/vm/vm.c new file mode 100644 index 0000000..a9173be --- /dev/null +++ b/sys/sys/vm/vm.c @@ -0,0 +1,10 @@ +#include +#include + +#define SV39 (8L << 60) + +void +vminit(void) +{ + csrw_satp(SATP, (uint64_t)pt >> 12); +} -- cgit v1.2.3