diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-05-16 23:06:28 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-05-16 23:06:28 +0000 |
commit | 727d09692dc7e3e62f503b2a3240a000b7c137e5 (patch) | |
tree | 131a4811a4538735ce022bd4b3cf66fad45b2244 /sys | |
parent | 2813c27d5c2617d5e9aec7f89798c20e608c25f1 (diff) |
Get memory information from the device tree.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/powerpc64/conf/ld.script | 3 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/machdep.c | 127 |
2 files changed, 118 insertions, 12 deletions
diff --git a/sys/arch/powerpc64/conf/ld.script b/sys/arch/powerpc64/conf/ld.script index 9fafeef6564..16e63274dc4 100644 --- a/sys/arch/powerpc64/conf/ld.script +++ b/sys/arch/powerpc64/conf/ld.script @@ -1,4 +1,4 @@ -/* $OpenBSD: ld.script,v 1.1 2020/05/16 17:11:14 kettenis Exp $ */ +/* $OpenBSD: ld.script,v 1.2 2020/05/16 23:06:27 kettenis Exp $ */ /* * Copyright (c) 2013 Mark Kettenis <kettenis@openbsd.org> @@ -52,4 +52,5 @@ SECTIONS *(.bss) } PROVIDE (end = .); + PROVIDE (_end = .); } diff --git a/sys/arch/powerpc64/powerpc64/machdep.c b/sys/arch/powerpc64/powerpc64/machdep.c index bc264cadc34..7ae41387f3e 100644 --- a/sys/arch/powerpc64/powerpc64/machdep.c +++ b/sys/arch/powerpc64/powerpc64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.1 2020/05/16 17:11:14 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.2 2020/05/16 23:06:27 kettenis Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -19,6 +19,7 @@ #include <sys/param.h> #include <sys/exec.h> #include <sys/exec_elf.h> +#include <sys/extent.h> #include <uvm/uvm_extern.h> @@ -46,20 +47,29 @@ extern void opal_cec_reboot(void); void opal_printf(const char *fmt, ...); +extern char _start[], _end[]; extern char __bss_start[]; -extern char end[]; extern uint64_t opal_base; extern uint64_t opal_entry; +struct fdt_reg memreg[VM_PHYSSEG_MAX]; +int nmemreg; + +void memreg_add(const struct fdt_reg *); +void memreg_remove(const struct fdt_reg *); + void init_powernv(void *fdt) { + struct fdt_reg reg; char *prop; void *node; + int len; + int i; /* Clear BSS. */ - memset(__bss_start, 0, end - __bss_start); + memset(__bss_start, 0, _end - __bss_start); if (!fdt_init(fdt) || fdt_get_size(fdt) == 0) panic("%s: no FDT\r\n", __func__); @@ -71,13 +81,15 @@ init_powernv(void *fdt) fdt_node_property(node, "opal-entry-address", &prop); opal_entry = bemtoh64((uint64_t *)prop); fdt_node_property(node, "compatible", &prop); - printf("%s\n", prop); } node = fdt_find_node("/"); fdt_node_property(node, "compatible", &prop); printf("%s\n", prop); + fdt_node_property(node, "model-name", &prop); + printf("%s\n", prop); + fdt_node_property(node, "model", &prop); printf("%s\n", prop); @@ -85,10 +97,6 @@ init_powernv(void *fdt) __asm volatile("mfspr %0,287" : "=r"(pvr)); printf("PVR %x\n", pvr); - uint32_t hid; - __asm volatile("mfspr %0,1008" : "=r"(hid)); - printf("HID %x\n", hid); - uint64_t lpcr; __asm volatile("mfspr %0,318" : "=r"(lpcr)); printf("LPCR %llx\n", lpcr); @@ -101,14 +109,111 @@ init_powernv(void *fdt) __asm volatile("mfmsr %0" : "=r"(msr)); printf("MSR %llx\n", msr); - uint64_t toc; - __asm volatile("mr %0, %%r2" : "=r"(toc)); - printf("TOC %llx\n", toc); + /* Add all memory. */ + node = fdt_find_node("/"); + for (node = fdt_child_node(node); node; node = fdt_next_node(node)) { + len = fdt_node_property(node, "device_type", &prop); + if (len <= 0) + continue; + if (strcmp(prop, "memory") != 0) + continue; + for (i = 0; nmemreg < nitems(memreg); i++) { + if (fdt_get_reg(node, i, ®)) + break; + if (reg.size == 0) + continue; + memreg_add(®); + } + } + + /* Remove reserved memory. */ + node = fdt_find_node("/reserved-memory"); + if (node) { + for (node = fdt_child_node(node); node; + node = fdt_next_node(node)) { + if (fdt_get_reg(node, 0, ®)) + continue; + if (reg.size == 0) + continue; + memreg_remove(®); + } + } + + /* Remove kernel. */ + reg.addr = trunc_page((paddr_t)_start); + reg.size = round_page((paddr_t)_end) - reg.addr; + memreg_remove(®); + + /* Remove FDT. */ + reg.addr = trunc_page((paddr_t)fdt); + reg.size = round_page((paddr_t)fdt + fdt_get_size(fdt)) - reg.addr; + memreg_remove(®); + + for (i = 0; i < nmemreg; i++) { + paddr_t start = memreg[i].addr; + paddr_t end = start + memreg[i].size; + + printf("0x%016lx - 0x%016lx\n", start, end - 1); +#ifdef notyet + uvm_page_physload(atop(start), atop(end), + atop(start), atop(end), 0); +#endif + physmem += atop(end - start); + } printf("Hello, World!\n"); opal_cec_reboot(); } +void +memreg_add(const struct fdt_reg *reg) +{ + memreg[nmemreg++] = *reg; +} + +void +memreg_remove(const struct fdt_reg *reg) +{ + uint64_t start = reg->addr; + uint64_t end = reg->addr + reg->size; + int i, j; + + for (i = 0; i < nmemreg; i++) { + uint64_t memstart = memreg[i].addr; + uint64_t memend = memreg[i].addr + memreg[i].size; + + if (end <= memstart) + continue; + if (start >= memend) + continue; + + if (start <= memstart) + memstart = MIN(end, memend); + if (end >= memend) + memend = MAX(start, memstart); + + if (start > memstart && end < memend) { + if (nmemreg < nitems(memreg)) { + memreg[nmemreg].addr = end; + memreg[nmemreg].size = memend - end; + nmemreg++; + } + memend = start; + } + memreg[i].addr = memstart; + memreg[i].size = memend - memstart; + } + + /* Remove empty slots. */ + for (i = nmemreg - 1; i >= 0; i--) { + if (memreg[i].size == 0) { + for (j = i; (j + 1) < nmemreg; j++) + memreg[j] = memreg[j + 1]; + nmemreg--; + } + } +} + #define R_PPC64_RELATIVE 22 #define ELF_R_TYPE_RELATIVE R_PPC64_RELATIVE |