Attention is currently required from: Ron Minnich. Sergii Dmytruk has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/57084 )
Change subject: src/arch/ppc64/*: pass FDT address to payload ......................................................................
src/arch/ppc64/*: pass FDT address to payload
It's available in %r3 in bootblock and needs to be passed first to romstage, then to ramstage, where it's put into CMBEM to be read on starting payload.
Change-Id: I0911f4b534c6f8cacfa057a5bad7576fec711637 Signed-off-by: Sergii Dmytruk sergii.dmytruk@3mdeb.com --- M src/arch/ppc64/boot.c M src/arch/ppc64/bootblock_crt0.S A src/arch/ppc64/fdt.h M src/arch/ppc64/stages.c 4 files changed, 87 insertions(+), 6 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/84/57084/1
diff --git a/src/arch/ppc64/boot.c b/src/arch/ppc64/boot.c index bbd0d39..59ac60e 100644 --- a/src/arch/ppc64/boot.c +++ b/src/arch/ppc64/boot.c @@ -1,7 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0-only */
+#include <cbmem.h> +#include <console/console.h> #include <program_loading.h>
+#include "fdt.h" + +/* Set in bootblock_crt0.S (ENV_BOOTBLOCK) or stages.c (ENV_ROMSTAGE) */ +uintptr_t fdt_address; + #if ENV_PAYLOAD_LOADER
/* @@ -10,6 +17,17 @@ */ void arch_prog_run(struct prog *prog) { + uintptr_t fdt; + const struct cbmem_entry *entry; + + /* Extract FDT address stored by ramstage */ + entry = cbmem_entry_find(CBMEM_ID_FDT_ADDRESS); + if (entry == NULL) + die("Failed to find FDT address entry in CBMEM on loading payload!"); + memcpy(&fdt, cbmem_entry_start(entry), sizeof(fdt)); + + asm("ld 27,%0" :: "m"(fdt) : "27"); + asm volatile( "mtctr %1\n" "mr 3, %0\n" @@ -17,6 +35,34 @@ :: "r"(prog_entry_arg(prog)), "r"(prog_entry(prog)) : "memory"); }
+#elif ENV_BOOTBLOCK + +void arch_prog_run(struct prog *prog) +{ + void (*doit)(void *) = prog_entry(prog); + + prog_set_arg(prog, (void *)fdt_address); + + doit(prog_entry_arg(prog)); +} + +#elif ENV_ROMSTAGE + +void arch_prog_run(struct prog *prog) +{ + const struct cbmem_entry *entry; + void (*doit)(void *) = prog_entry(prog); + + /* Store FDB address to pass it to payload */ + entry = cbmem_entry_add(CBMEM_ID_FDT_ADDRESS, sizeof(fdt_address)); + if (entry == NULL) + die("Failed to add FDT address entry in CBMEM at romstage!"); + + memcpy(cbmem_entry_start(entry), &fdt_address, sizeof(fdt_address)); + + doit(prog_entry_arg(prog)); +} + #else
void arch_prog_run(struct prog *prog) diff --git a/src/arch/ppc64/bootblock_crt0.S b/src/arch/ppc64/bootblock_crt0.S index 98ee56c..c19f03d 100644 --- a/src/arch/ppc64/bootblock_crt0.S +++ b/src/arch/ppc64/bootblock_crt0.S @@ -25,6 +25,8 @@ oris r,r, (e)@h; \ ori r,r, (e)@l;
+.globl fdt_address + .section ".text._start", "ax", %progbits .globl _start _start: @@ -35,6 +37,11 @@ nop FIXUP_ENDIAN
+ /* Store FDT address that's available in %r3 for use in + * arch_prog_run() */ + LOAD_IMM64(%r5, fdt_address) + std %r3, 0(%r5) + /* Set program priority to medium */ or %r2, %r2, %r2
diff --git a/src/arch/ppc64/fdt.h b/src/arch/ppc64/fdt.h new file mode 100644 index 0000000..1b4459c --- /dev/null +++ b/src/arch/ppc64/fdt.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _FDT_H +#define _FDT_H + +#include <stdint.h> + +/* Used to pass FDT address from ramstage to payload */ +#define CBMEM_ID_FDT_ADDRESS 0x46445441 // "FDTA" + +/* Used to pass FDT address to arch_prog_run() */ +extern uintptr_t fdt_address; + +#endif /* _FDT_H */ diff --git a/src/arch/ppc64/stages.c b/src/arch/ppc64/stages.c index 01b9efa..aed1c54 100644 --- a/src/arch/ppc64/stages.c +++ b/src/arch/ppc64/stages.c @@ -15,21 +15,35 @@ #include <arch/stages.h> #include <cpu/power/spr.h>
+#if ENV_RAMSTAGE + void stage_entry(uintptr_t stage_arg) { -#if ENV_RAMSTAGE uint64_t hrmor; -#endif
- if (!ENV_ROMSTAGE_OR_BEFORE) - _cbmem_top_ptr = stage_arg; + _cbmem_top_ptr = stage_arg;
-#if ENV_RAMSTAGE hrmor = read_spr(SPR_HRMOR); asm volatile("sync; isync" ::: "memory"); write_spr(SPR_HRMOR, 0); asm volatile("or 1,1,%0; slbia 7; sync; isync" :: "r"(hrmor) : "memory"); -#endif
main(); } + +#else + +#include "fdt.h" + +void stage_entry(uintptr_t stage_arg) +{ + if (ENV_ROMSTAGE_OR_BEFORE) + /* Pass the value to arch_prog_run() */ + fdt_address = stage_arg; + else + _cbmem_top_ptr = stage_arg; + + main(); +} + +#endif