diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | arch/riscv/init/init.c | 78 | ||||
| -rw-r--r-- | arch/riscv/kernel/main.c | 7 | ||||
| -rw-r--r-- | arch/riscv/source.mk | 3 | ||||
| -rw-r--r-- | common/debug.c | 32 | ||||
| -rw-r--r-- | common/fdt.c | 24 | ||||
| -rw-r--r-- | include/apos/debug.h | 6 | ||||
| -rw-r--r-- | include/libfdt.h | 9 |
8 files changed, 89 insertions, 72 deletions
@@ -19,7 +19,7 @@ OBJCOPY ?= objcopy # This makes sure .bss is loaded into the binary OBJCOPY_FLAGS ?= -Obinary --set-section-flags .bss=alloc,load,contents -COMMON_SOURCES != echo common/*.c +COMMON_SOURCES != echo common/*.c lib/fdt*.c KERNEL_SOURCES != echo kernel/*.c $(COMMON_SOURCES) INIT_SOURCES := $(COMMON_SOURCES) CLEANUP := build deps.mk kernel.* init.* apos.bin diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c index f1a4697..0217c79 100644 --- a/arch/riscv/init/init.c +++ b/arch/riscv/init/init.c @@ -12,45 +12,14 @@ #include <vmem.h> #include <csr.h> -struct pmem_layout { +struct pmem_layout_t { paddr_t base; paddr_t top; }; -struct cell_info { - uint32_t size_cells; - uint32_t addr_cells; -}; - -static struct cell_info get_cellinfo(void *fdt, int offset) -{ - struct cell_info ret = { - fdt_size_cells(fdt, offset), - fdt_address_cells(fdt, offset) - }; - - return ret; - -} - -/* How "reg" is interpreted depends on the parent node */ -static struct cell_info get_reginfo(void *fdt, const char *path) -{ - 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) +static struct pmem_layout_t get_memlayout(void *fdt) { - struct cell_info ci = get_reginfo(fdt, "/memory"); + struct cell_info_t 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); @@ -66,42 +35,15 @@ static struct pmem_layout get_memlayout(void *fdt) /* -1 because base is a legitimate memory address */ paddr_t top = (paddr_t)fdt_load_int_ptr(ci.size_cells, mem_reg) + base - 1; - return (struct pmem_layout){base, top}; + return (struct pmem_layout_t){base, top}; } #ifdef DEBUG -/* this should probably be improved in the future, possibly also moved - * somewhere? */ -static enum serial_dev_t serial_dev_enum(const char *dev_name) -{ - if (strncmp("ns16550", dev_name, 7) == 0) - return NS16550A; - - return -1; -} - static void init_debug(void *fdt) { - int chosen_offset = fdt_path_offset(fdt, "/chosen"); - const char *stdout = fdt_getprop(fdt, chosen_offset, - "stdout-path", NULL); - - int stdout_offset = fdt_path_offset(fdt, stdout); - - /* get serial device type */ - const char *dev_name = (const char *)fdt_getprop(fdt, stdout_offset, - "compatible", NULL); - - enum serial_dev_t dev = serial_dev_enum(dev_name); - - /* get serial device address */ - struct cell_info ci = get_reginfo(fdt, stdout); - void *reg_ptr = (void *)fdt_getprop(fdt, stdout_offset, "reg", NULL); - - void *uart_ptr = (void *)(paddr_t)fdt_load_int_ptr(ci.addr_cells, reg_ptr); - - dbg_init(uart_ptr, dev); + struct dbg_info_t dbg = dbg_from_fdt(fdt); + dbg_init(dbg.dbg_ptr, dbg.dev); } #else @@ -120,7 +62,7 @@ static paddr_t get_kerneltop() static paddr_t get_initrdtop(void *fdt) { int chosen_offset = fdt_path_offset(fdt, "/chosen"); - struct cell_info ci = get_cellinfo(fdt, chosen_offset); + struct cell_info_t ci = get_cellinfo(fdt, chosen_offset); void *initrd_end_ptr = (void *)fdt_getprop(fdt, chosen_offset, "linux,initrd-end", NULL); @@ -131,7 +73,7 @@ static paddr_t get_initrdtop(void *fdt) static paddr_t get_initrdbase(void *fdt) { int chosen_offset = fdt_path_offset(fdt, "/chosen"); - struct cell_info ci = get_cellinfo(fdt, chosen_offset); + struct cell_info_t ci = get_cellinfo(fdt, chosen_offset); void *initrd_base_ptr = (void *)fdt_getprop(fdt, chosen_offset, "linux,initrd-start", NULL); @@ -169,7 +111,7 @@ static void mark_area_used(paddr_t base, paddr_t top) static void mark_reserved_mem(void *fdt) { int rmem_offset = fdt_path_offset(fdt, "/reserved-memory/mmode_resv0"); - struct cell_info ci = get_reginfo(fdt, "/reserved-memory/mmode_resv0"); + struct cell_info_t ci = get_reginfo(fdt, "/reserved-memory/mmode_resv0"); uint8_t *rmem_reg = (uint8_t *)fdt_getprop(fdt, rmem_offset, "reg", NULL); paddr_t base = (paddr_t)fdt_load_int_ptr(ci.addr_cells, rmem_reg); @@ -185,7 +127,7 @@ static void mark_reserved_mem(void *fdt) static void setup_pmem(void *fdt) { - struct pmem_layout pmem = get_memlayout(fdt); + struct pmem_layout_t pmem = get_memlayout(fdt); paddr_t initrd_top = get_initrdtop(fdt); paddr_t kernel_top = get_kerneltop(); diff --git a/arch/riscv/kernel/main.c b/arch/riscv/kernel/main.c index 3575ceb..5566d63 100644 --- a/arch/riscv/kernel/main.c +++ b/arch/riscv/kernel/main.c @@ -4,11 +4,16 @@ void __main main(struct init_data_t d) { /* TODO: approximate order of business: - * setup debugging in vmem + * setup debugging in vmem (requires mapping fdt) * free unnecessary init * setup interrupts (should this be done in init?) * load init from initrd * setup init environment (thread control blocks etc.) * jumpstart init (free stack init setup) */ + + /* functionality that should be implemented: + * figure out best continuous run of memory (pmap etc) + * arbitrary mapping and kernel mapping (memory) + */ } diff --git a/arch/riscv/source.mk b/arch/riscv/source.mk index 4733efa..b1dd361 100644 --- a/arch/riscv/source.mk +++ b/arch/riscv/source.mk @@ -2,8 +2,7 @@ KERNEL_LOCAL != echo arch/riscv/kernel/*.[cS] arch/riscv/common/*.[cS] KERNEL_SOURCES += $(KERNEL_LOCAL) INIT_LOCAL != echo arch/riscv/init/*.[cS] arch/riscv/common/*.[cS] -INIT_FDT != echo lib/fdt*.c -INIT_SOURCES += $(INIT_LOCAL) $(INIT_FDT) +INIT_SOURCES += $(INIT_LOCAL) CLEANUP_CMD := ./arch/riscv/conf/rmimage.sh diff --git a/common/debug.c b/common/debug.c index c82377c..523ae7b 100644 --- a/common/debug.c +++ b/common/debug.c @@ -1,6 +1,8 @@ #include <apos/types.h> #include <apos/debug.h> #include <apos/bits.h> +#include <apos/pmem.h> +#include <libfdt.h> #include <stdarg.h> #ifdef DEBUG @@ -56,6 +58,36 @@ static void __putchar(char c) port->data = c; } +static enum serial_dev_t serial_dev_enum(const char *dev_name) +{ + if (strncmp("ns16550", dev_name, 7) == 0) + return NS16550A; + + return -1; +} + +struct dbg_info_t dbg_from_fdt(void *fdt) +{ + int chosen_offset = fdt_path_offset(fdt, "/chosen"); + const char *stdout = fdt_getprop(fdt, chosen_offset, "stdout-path", NULL); + + int stdout_offset = fdt_path_offset(fdt, stdout); + + /* get serial device type */ + const char *dev_name = (const char *)fdt_getprop(fdt, stdout_offset, + "compatible", NULL); + + enum serial_dev_t dev = serial_dev_enum(dev_name); + + /* get serial device address */ + struct cell_info_t ci = get_reginfo(fdt, stdout); + void *reg_ptr = (void *)fdt_getprop(fdt, stdout_offset, "reg", NULL); + + void *dbg_ptr = (void *)(paddr_t)fdt_load_int_ptr(ci.addr_cells, reg_ptr); + + return (struct dbg_info_t){dbg_ptr, dev}; +} + void dbg_init(void *pt, enum serial_dev_t dev) { switch (dev) { diff --git a/common/fdt.c b/common/fdt.c new file mode 100644 index 0000000..c554b25 --- /dev/null +++ b/common/fdt.c @@ -0,0 +1,24 @@ +#include <libfdt.h> + +struct cell_info_t get_cellinfo(void *fdt, int offset) +{ + return (struct cell_info_t){ + fdt_size_cells(fdt, offset), + fdt_address_cells(fdt, offset) + }; +} + +/* how "reg" is interpreted depends on the parent node */ +struct cell_info_t get_reginfo(void *fdt, const char *path) +{ + const char *i = strrchr(path, '/'); + if(!i) + return (struct cell_info_t){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)); +} diff --git a/include/apos/debug.h b/include/apos/debug.h index 021612d..5830c45 100644 --- a/include/apos/debug.h +++ b/include/apos/debug.h @@ -9,8 +9,14 @@ enum serial_dev_t { NS16550A, }; +struct dbg_info_t { + void *dbg_ptr; + enum serial_dev_t dev; +}; + void __fmt(1, 2) dbg(const char *fmt, ...); void dbg_init(void *pt, enum serial_dev_t dev); +struct dbg_info_t dbg_from_fdt(void *fdt); #else diff --git a/include/libfdt.h b/include/libfdt.h index 406b6d7..aa95bd3 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -2,6 +2,15 @@ #define APOS_LIBFDT_H #include "../dtc/libfdt/libfdt.h" +/* apos additions, implementation can be found in common/fdt.c */ +struct cell_info_t { + uint32_t size_cells; + uint32_t addr_cells; +}; + +struct cell_info_t get_cellinfo(void *fdt, int offset); +struct cell_info_t get_reginfo(void *fdt, const char *path); + #if defined(DEBUG) void __dbg_fdt(void *fdt, int node_offset, int depth); #define dbg_fdt(fdt) __dbg_fdt(fdt, 0, 0) |
