diff options
Diffstat (limited to 'src/main.c')
| -rw-r--r-- | src/main.c | 92 |
1 files changed, 69 insertions, 23 deletions
@@ -19,6 +19,54 @@ #include <arch/smp.h> #include <libfdt.h> +static pm_t __fdt_ram_base(void *fdt) +{ + int mem_offset = fdt_path_offset(fdt, "/memory"); + const void *mem_reg = fdt_getprop(fdt, mem_offset, "reg", NULL); + + struct cell_info ci = get_cellinfo(fdt, mem_offset); + return (pm_t)fdt_load_reg_addr(ci, mem_reg, 0); +} + +static pm_t __fdt_ram_size(void *fdt) +{ + int mem_offset = fdt_path_offset(fdt, "/memory"); + const void *mem_reg = fdt_getprop(fdt, mem_offset, "reg", NULL); + + /* here we actually want the root offset because /memory itself doesn't + * have children, I guess? */ + struct cell_info ci = get_cellinfo(fdt, fdt_path_offset(fdt, "/")); + return (pm_t)fdt_load_reg_size(ci, mem_reg, 0); +} + +void kernel(void *fdt, uintptr_t load_addr, struct vmem *d) +{ + fdt = __va(fdt); + + /* dbg uses direct mapping at this point */ + init_dbg(fdt); + /* start up debugging in kernel IO */ + setup_io_dbg(d); + + dbg_fdt(fdt); + + setup_arch(fdt); + + init_pmem(fdt, load_addr); + + init_irq(fdt); + init_timer(fdt); + + vm_t proc_fdt = 0, proc_initrd = 0; + init_proc(fdt, &proc_fdt, &proc_initrd); + + /* try to bring up other cores on system */ + smp_bringup(d, fdt); + + /* start running init program */ + run_init(cur_tcb(), proc_fdt, proc_initrd); +} + /** * Boot entry of kernel actual. * @@ -29,35 +77,33 @@ * @param ram_base RAM base. * @return Should not. */ -void __main main(void *fdt, uintptr_t ram_base) +void main(unsigned long hart, void *fdt, uintptr_t load_addr) { - set_ram_base(ram_base); + /* we have our own ways to get the current hart when we need it, but we + * have to get the function signature right */ + (void)hart; - /* convert physical address to virtual address */ - fdt = __va(fdt); - - /* dbg uses direct mapping at this point */ - init_dbg(fdt); - setup_dmap_dbg(); - dbg_fdt(fdt); + pm_t ram_base = __fdt_ram_base(fdt); + pm_t ram_size = __fdt_ram_size(fdt); + set_ram_base(ram_base); + set_ram_size(ram_size); - setup_arch(fdt); + init_mem(fdt); - init_pmem(fdt); - /* setup temporary virtual memory */ - struct vmem *b = init_vmem(fdt); + struct vmem *d = direct_mapping(); - /* start up debugging in kernel IO */ - setup_io_dbg(b); + to_kernelspace(fdt, load_addr, d, ram_base, VM_DMAP); + unreachable(); +} - init_irq(fdt); - init_timer(fdt); - init_proc(fdt); +#if GENERIC_UBOOT +void main_go(size_t argc, char *argv[], uintptr_t load_addr) +{ + if (argc != 2) + return; - /* try to bring up other cores on system */ - smp_bringup(b, fdt); + void *fdt = (void *)strtouintptr(argv[1]); - /* start running init program */ - void *initrd = (void *)get_initrdbase(fdt); - run_init(cur_tcb(), fdt, initrd); + main(0, fdt, load_addr); } +#endif |
