aboutsummaryrefslogtreecommitdiff
path: root/machine
diff options
context:
space:
mode:
Diffstat (limited to 'machine')
-rw-r--r--machine/fdt.c57
-rw-r--r--machine/fdt.h5
-rw-r--r--machine/minit.c3
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();