From 68fcd6d027b88581992b4fb10ee1edc301e30678 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Mon, 20 Sep 2021 14:17:18 +0300 Subject: Some slight robustness improvements and obo errors --- TODO.txt | 1 + arch/riscv/init/init.c | 36 ++++++++++++++++++++++++++---------- common/string.c | 20 +++++++++----------- include/apos/utils.h | 17 +++++++++++++++++ include/libfdt.h | 4 ++-- 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/TODO.txt b/TODO.txt index 1d84441..012fba9 100644 --- a/TODO.txt +++ b/TODO.txt @@ -11,3 +11,4 @@ + Mark fdt, reserved mem, kernel, init and initrd in vmem. Remember to remove init from vmem when jumping to vmem + Figure out best way to tell the init how large out kernel is ++ Make code more robust, error checking etc 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 */ } diff --git a/common/string.c b/common/string.c index af9c54a..0870b78 100644 --- a/common/string.c +++ b/common/string.c @@ -93,12 +93,11 @@ __weak int strncmp(const char *str1, const char *str2, size_t num) __weak char *strchr(const char *str, int chr) { const char *s1 = str; - size_t num = strlen(s1); + ssize_t num = strlen(s1); while (num-- && *(s1--) != chr) ; - num++; - if (!num) + if (num < 0) return 0; return (char *)(s1 + 1); @@ -162,16 +161,15 @@ __weak char *strstr(const char *str1, const char *str2) #undef strrchr __weak char *strrchr(const char *str, int chr) { - size_t num = strlen(str); - const char *s1 = str + num; + ssize_t num = strlen(str); + const char *s1 = (str + num) - 1; while (num-- && *(s1--) != chr) ; - num++; - if (!num) + if (num < 0) return 0; - return (char *)s1; + return (char *)(s1 + 1); } #undef strpbrk @@ -262,12 +260,12 @@ __weak void *memset(void *ptr, int value, size_t num) __weak void *memchr(const void *ptr, int val, size_t num) { const char *p1 = (char *)ptr; + ssize_t n = num; char c = (char)val; - while (num-- && *(p1++) != c) ; + while (n-- && *(p1++) != c) ; - num++; - if (!num) + if (n < 0) return 0; return (void *)(p1 - 1); diff --git a/include/apos/utils.h b/include/apos/utils.h index 45e7194..3855a37 100644 --- a/include/apos/utils.h +++ b/include/apos/utils.h @@ -11,4 +11,21 @@ #define MIN4(a, b, c, d) (MIN3(a, b, c) <= MIN3(b, c, d) ? MIN3(a, b, c) : MIN3(b, c, d)) /* etc... */ +#include + +static inline size_t align_up(size_t val, size_t a) +{ + size_t rem = val % a; + + if (rem == 0) + return val; + + return val + a - rem; +} + +static inline size_t align_down(size_t val, size_t a) +{ + return val - (val % a); +} + #endif /* APOS_UTILS_H */ diff --git a/include/libfdt.h b/include/libfdt.h index 7425aef..406b6d7 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -9,7 +9,7 @@ void __dbg_fdt(void *fdt, int node_offset, int depth); #define dbg_fdt(...) #endif -#define fdt_load_int_ptr(t, c, p)\ - ((c) == 2 ? (t)fdt64_to_cpu(*(fdt64_t *)(p)) : (t)fdt32_to_cpu(*(fdt32_t *)(p))) +#define fdt_load_int_ptr(c, p)\ + ((c) == 2 ? fdt64_to_cpu(*(fdt64_t *)(p)) : fdt32_to_cpu(*(fdt32_t *)(p))) #endif -- cgit v1.3