summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/ppc64/bootblock_crt0.S6
-rw-r--r--src/include/cpu/power/spr.h3
-rw-r--r--src/mainboard/emulation/qemu-power9/Makefile.inc2
-rw-r--r--src/mainboard/emulation/qemu-power9/ramstage.c21
4 files changed, 32 insertions, 0 deletions
diff --git a/src/arch/ppc64/bootblock_crt0.S b/src/arch/ppc64/bootblock_crt0.S
index 3988583bee..5a9496024e 100644
--- a/src/arch/ppc64/bootblock_crt0.S
+++ b/src/arch/ppc64/bootblock_crt0.S
@@ -3,6 +3,8 @@
* Early initialization code for POWER8/POWER9.
*/
+#include <cpu/power/spr.h>
+
#define FIXUP_ENDIAN \
tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \
b $+44; /* Skip trampoline if endian is good */ \
@@ -35,6 +37,10 @@ _start:
nop
FIXUP_ENDIAN
+ /* Store FDT address provided by QEMU in %r3 to pass it later to
+ * payload */
+ mtspr SPR_HSPRG0, %r3
+
/* Set program priority to medium */
or %r2, %r2, %r2
diff --git a/src/include/cpu/power/spr.h b/src/include/cpu/power/spr.h
index f22a6cab3d..3b229f73a3 100644
--- a/src/include/cpu/power/spr.h
+++ b/src/include/cpu/power/spr.h
@@ -9,6 +9,9 @@
#define SPR_PVR_REV_MASK (PPC_BITMASK(52, 55) | PPC_BITMASK(60, 63))
#define SPR_PVR_REV(maj, min) (PPC_SHIFT((maj), 55) | PPC_SHIFT((min), 63))
+#define SPR_HSPRG0 0x130
+#define SPR_HSPRG1 0x131
+
#define SPR_HRMOR 0x139
#define SPR_HMER 0x150
diff --git a/src/mainboard/emulation/qemu-power9/Makefile.inc b/src/mainboard/emulation/qemu-power9/Makefile.inc
index bd905a3029..ace00a75b7 100644
--- a/src/mainboard/emulation/qemu-power9/Makefile.inc
+++ b/src/mainboard/emulation/qemu-power9/Makefile.inc
@@ -2,3 +2,5 @@
romstage-y += cbmem.c
romstage-y += romstage.c
+
+ramstage-y += ramstage.c
diff --git a/src/mainboard/emulation/qemu-power9/ramstage.c b/src/mainboard/emulation/qemu-power9/ramstage.c
new file mode 100644
index 0000000000..c92587b696
--- /dev/null
+++ b/src/mainboard/emulation/qemu-power9/ramstage.c
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <cpu/power/spr.h>
+#include <program_loading.h>
+
+/*
+ * Payload's entry point is an offset to the real entry point, not to OPD
+ * (Official Procedure Descriptor) for entry point.
+ *
+ * Also pass FDT address to payload stored in SPR_HSPRG0 by bootblock.
+ */
+void platform_prog_run(struct prog *prog)
+{
+ asm volatile(
+ "mfspr %%r27, %0\n" /* pass pointer to FDT */
+ "mtctr %2\n"
+ "mr 3, %1\n"
+ "bctr\n"
+ :: "i"(SPR_HSPRG0), "r"(prog_entry_arg(prog)), "r"(prog_entry(prog))
+ : "memory");
+}