diff options
Diffstat (limited to 'machine')
-rw-r--r-- | machine/fdt.c | 57 | ||||
-rw-r--r-- | machine/fdt.h | 5 | ||||
-rw-r--r-- | machine/minit.c | 3 |
3 files changed, 65 insertions, 0 deletions
diff --git a/machine/fdt.c b/machine/fdt.c index 061b19e..27f5462 100644 --- a/machine/fdt.c +++ b/machine/fdt.c @@ -548,6 +548,63 @@ void filter_compat(uintptr_t fdt, const char *compat) fdt_scan(fdt, &cb); } +//////////////////////////////////////////// CHOSEN SCAN //////////////////////////////////////// + +struct chosen_scan { + const struct fdt_scan_node *chosen; + void* kernel_start; + void* kernel_end; +}; + +static void chosen_open(const struct fdt_scan_node *node, void *extra) +{ + struct chosen_scan *scan = (struct chosen_scan *)extra; + if (!strcmp(node->name, "chosen")) { + scan->chosen = node; + } +} + +static int chosen_close(const struct fdt_scan_node *node, void *extra) +{ + struct chosen_scan *scan = (struct chosen_scan *)extra; + if (scan->chosen && scan->chosen == node) { + scan->chosen = NULL; + } + return 0; +} + +static void chosen_prop(const struct fdt_scan_prop *prop, void *extra) +{ + struct chosen_scan *scan = (struct chosen_scan *)extra; + uint64_t val; + if (!scan->chosen) return; + if (!strcmp(prop->name, "riscv,kernel-start")) { + fdt_get_address(prop->node->parent, prop->value, &val); + scan->kernel_start = (void*)val; + } else if (!strcmp(prop->name, "riscv,kernel-end")) { + fdt_get_address(prop->node->parent, prop->value, &val); + scan->kernel_end = (void*)val; + } +} + +void query_chosen(uintptr_t fdt) +{ + struct fdt_cb cb; + struct chosen_scan chosen; + + memset(&cb, 0, sizeof(cb)); + cb.open = chosen_open; + cb.close = chosen_close; + cb.prop = chosen_prop; + + memset(&chosen, 0, sizeof(chosen)); + cb.extra = &chosen; + + fdt_scan(fdt, &cb); + kernel_start = chosen.kernel_start; + kernel_end = chosen.kernel_end; +} + //////////////////////////////////////////// HART FILTER //////////////////////////////////////// struct hart_filter { diff --git a/machine/fdt.h b/machine/fdt.h index d436778..6c8a6fe 100644 --- a/machine/fdt.h +++ b/machine/fdt.h @@ -59,6 +59,7 @@ void query_mem(uintptr_t fdt); void query_harts(uintptr_t fdt); void query_plic(uintptr_t fdt); void query_clint(uintptr_t fdt); +void query_chosen(uintptr_t fdt); // Remove information from FDT void filter_harts(uintptr_t fdt, long *disabled_hart_mask); @@ -68,6 +69,10 @@ void filter_compat(uintptr_t fdt, const char *compat); // The hartids of available harts extern uint64_t hart_mask; +// Optional FDT preloaded external payload +extern void* kernel_start; +extern void* kernel_end; + #ifdef PK_PRINT_DEVICE_TREE // Prints the device tree to the console as a DTS void fdt_print(uintptr_t fdt); diff --git a/machine/minit.c b/machine/minit.c index 32c6fd7..ceae6b7 100644 --- a/machine/minit.c +++ b/machine/minit.c @@ -16,6 +16,8 @@ uintptr_t mem_size; volatile uint64_t* mtime; volatile uint32_t* plic_priorities; size_t plic_ndevs; +void* kernel_start; +void* kernel_end; static void mstatus_init() { @@ -162,6 +164,7 @@ void init_first_hart(uintptr_t hartid, uintptr_t dtb) query_harts(dtb); query_clint(dtb); query_plic(dtb); + query_chosen(dtb); wake_harts(); |