diff options
author | Anup Patel <anup.patel@wdc.com> | 2020-05-24 10:03:13 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2020-06-05 09:02:34 +0530 |
commit | 86ec5341e421b3f6ac39c75da648b7a22e56f248 (patch) | |
tree | cfb4031238ab67050302a1eadd8eaa84eb8e71fe | |
parent | 4ce6b7a82ac2c9f57186c00f23223dd39067555b (diff) |
firmware: Allow fw_platform_init() to return updated FDT location
Currently, the fw_platform_init() does not return anything but we can
further improve by allowing fw_platform_init() to return updated FDT
location.
It is certainly not mandatory for fw_platform_init() to return a new
location of FDT (or modify FDT). In fact, the fw_platform_init() can
always return the original FDT location (i.e. 'arg1') unmodified.
This new capability of fw_platform_init() will allow platforms to:
1. Have multiple built-in FDTs and select one
2. Modify FDT before using based on platform specific straps or OTP
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
-rw-r--r-- | firmware/fw_base.S | 3 | ||||
-rw-r--r-- | platform/generic/platform.c | 13 |
2 files changed, 12 insertions, 4 deletions
diff --git a/firmware/fw_base.S b/firmware/fw_base.S index b354cb8..b66ac41 100644 --- a/firmware/fw_base.S +++ b/firmware/fw_base.S @@ -198,7 +198,9 @@ _prev_arg1_override_done: */ MOV_5R s0, a0, s1, a1, s2, a2, s3, a3, s4, a4 call fw_platform_init + add t0, a0, zero MOV_5R a0, s0, a1, s1, a2, s2, a3, s3, a4, s4 + add a1, t0, zero /* Preload HART details * s7 -> HART Count @@ -475,6 +477,7 @@ _start_hang: .globl fw_platform_init .weak fw_platform_init fw_platform_init: + add a0, a1, zero ret .section .entry, "ax", %progbits diff --git a/platform/generic/platform.c b/platform/generic/platform.c index a4a07e3..57058ff 100644 --- a/platform/generic/platform.c +++ b/platform/generic/platform.c @@ -62,10 +62,14 @@ static u32 generic_hart_index2id[SBI_HARTMASK_MAX_BITS] = { 0 }; * The arguments passed to fw_platform_init() function are boot time state * of A0 to A4 register. The "arg0" will be boot HART id and "arg1" will * be address of FDT passed by previous booting stage. + * + * The return value of fw_platform_init() function is the FDT location. If + * FDT is unchanged (or FDT is modified in-place) then fw_platform_init() + * can always return the original FDT location (i.e. 'arg1') unmodified. */ -void fw_platform_init(unsigned long arg0, unsigned long arg1, - unsigned long arg2, unsigned long arg3, - unsigned long arg4) +unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1, + unsigned long arg2, unsigned long arg3, + unsigned long arg4) { const char *model, *mmu_type; void *fdt = (void *)arg1; @@ -106,7 +110,8 @@ void fw_platform_init(unsigned long arg0, unsigned long arg1, platform.hart_count = hart_count; - return; + /* Return original FDT pointer */ + return arg1; fail: while (1) |