summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstefan <stefan@s00.xyz>2023-04-23 17:00:14 -0400
committerstefan <stefan@s00.xyz>2023-04-23 17:00:14 -0400
commita3c174ee4c08d1d5e7a89ce187f52e3c0807a7eb (patch)
treebad1c1d9026e7de550a1e69863acdf9a8213b2b7
parent386ad4f82955d389ae347bc50f7efca5edb9d9a8 (diff)
downloadsv-a3c174ee4c08d1d5e7a89ce187f52e3c0807a7eb.tar.gz
memory detection
-rw-r--r--include/stdint.h6
-rw-r--r--mainboard/virt/conf/mainboard.conf2
-rw-r--r--sys/dev/dev_init.c42
-rw-r--r--sys/include/asm.h6
-rw-r--r--sys/include/dev.h32
-rw-r--r--sys/include/kalloc.h2
-rw-r--r--sys/include/sbi.h8
-rw-r--r--sys/include/vm.h6
-rw-r--r--sys/sys/init.c10
-rw-r--r--sys/sys/mm/kalloc.c14
-rw-r--r--sys/sys/vm/vm.c10
11 files changed, 120 insertions, 18 deletions
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 <string.h>
#include <stdint.h>
-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 <libfdt.h>
+#include <stdint.h>
-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 <stdint.h>
+
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 <kalloc.h>
#include <stdio.h>
+#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 <vm.h>
+#include <asm.h>
+
+#define SV39 (8L << 60)
+
+void
+vminit(void)
+{
+ csrw_satp(SATP, (uint64_t)pt >> 12);
+}