aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2021-09-20 14:17:18 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2021-09-20 14:17:18 +0300
commit68fcd6d027b88581992b4fb10ee1edc301e30678 (patch)
treec75ce91b2db43e562447b88958cff6eebaa96c98 /arch
parent64405594929502951624942e2a9ca53077aba2ae (diff)
downloadkmi-68fcd6d027b88581992b4fb10ee1edc301e30678.tar.gz
kmi-68fcd6d027b88581992b4fb10ee1edc301e30678.zip
Some slight robustness improvements and obo errors
Diffstat (limited to 'arch')
-rw-r--r--arch/riscv/init/init.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c
index c389e3b..5612d0b 100644
--- a/arch/riscv/init/init.c
+++ b/arch/riscv/init/init.c
@@ -31,26 +31,40 @@ static struct cell_info get_cellinfo(void *fdt, int offset)
}
-static struct pmem_layout get_memlayout(void *fdt)
+/* How "reg" is interpreted depends on the parent node */
+static struct cell_info get_reginfo(void *fdt, const char *path)
{
- struct cell_info ci = get_cellinfo(fdt, 0);
+ const char *i = strrchr(path, '/');
+ if(!i)
+ return (struct cell_info){0, 0};
+
+ size_t baselen = i - path;
+ if(i == 0)
+ /* root node */
+ baselen = 1;
+
+ return get_cellinfo(fdt, fdt_path_offset_namelen(fdt, path, baselen));
+}
+static struct pmem_layout get_memlayout(void *fdt)
+{
+ struct cell_info ci = get_reginfo(fdt, "/memory");
int mem_offset = fdt_path_offset(fdt, "/memory");
uint8_t *mem_reg =
(uint8_t *) fdt_getprop(fdt, mem_offset, "reg", NULL);
/* if riscv128 comes around we will probably see addr_cells == 4, but
* I'm not too concerned about it at the moment */
- pm_t base = fdt_load_int_ptr(pm_t, ci.addr_cells, mem_reg);
+ pm_t base = (pm_t)fdt_load_int_ptr(ci.addr_cells, mem_reg);
if(ci.addr_cells == 2)
mem_reg += sizeof(fdt64_t);
else
mem_reg += sizeof(fdt32_t);
- pm_t top = fdt_load_int_ptr(pm_t, ci.size_cells, mem_reg) + base;
- struct pmem_layout ret = { base, top };
- return ret;
+ /* -1 because base is a legitimate memory address */
+ pm_t top = (pm_t)fdt_load_int_ptr(ci.size_cells, mem_reg) + base - 1;
+ return (struct pmem_layout){base, top};
}
#ifdef DEBUG
@@ -80,11 +94,11 @@ static void init_debug(void *fdt)
enum serial_dev_t dev = serial_dev_enum(dev_name);
/* get serial device address */
- struct cell_info ci = get_cellinfo(fdt, stdout_offset);
+ struct cell_info ci = get_reginfo(fdt, stdout);
void *reg_ptr = (void *)fdt_getprop(fdt, stdout_offset, "reg", NULL);
void *uart_ptr = 0;
- uart_ptr = (void *)fdt_load_int_ptr(pm_t, ci.addr_cells, reg_ptr);
+ uart_ptr = (void *)(pm_t)fdt_load_int_ptr(ci.addr_cells, reg_ptr);
dbg_init(uart_ptr, dev);
}
@@ -110,7 +124,7 @@ static pm_t get_initrdtop(void *fdt)
void *initrd_end_ptr = (void *)fdt_getprop(fdt, chosen_offset,
"linux,initrd-end", NULL);
- return fdt_load_int_ptr(pm_t, ci.addr_cells, initrd_end_ptr);
+ return (pm_t)fdt_load_int_ptr(ci.addr_cells, initrd_end_ptr);
}
static pm_t get_fdttop(void *fdt)
@@ -132,7 +146,9 @@ static void setup_pmem(void *fdt)
dbg("kernel_top:\t%#lx\n", kernel_top);
dbg("fdt_top:\t%#lx\n", fdt_top);
- populate_pmap(pmem.base, pmem.top - pmem.base, top + 1);
+ /* riscv handles two byte boundaries better than one byte, so align
+ * upwards */
+ populate_pmap(pmem.base, pmem.top - pmem.base, align_up(top + 1, 2));
/* TODO: mark used pages */
}