aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorKrystian Hebel <krystian.hebel@3mdeb.com>2020-09-23 14:40:45 +0200
committerFelix Held <felix-coreboot@felixheld.de>2022-02-11 13:54:26 +0000
commite527c713bd3533858054fe389ec2a5c93f6d6726 (patch)
tree0c188b15f4d0dcf9a75e054d1db1eed9a51b775f /src/arch
parent707e5452e7037bfc918862901401608469d2e86a (diff)
ppc64/bootblock_crt0.S: minimal implementation for bootblock C environment
BSS is loaded as part of the bootblock, it is zeroed in the file so it doesn't have to be cleared explicitly by the code. Code for clearing is left as a comment along with a warning about alignment requirements. Vector operations are sometimes generated for code such as 'uint8_t x[32] = {0}', this results in an exception when vector registers (VR) are not enabled. VSR (vector-scalar register) operations are also enabled, there is no reason not to. Change-Id: I878ef61619eb4a191805c8911d001312a0d717a0 Signed-off-by: Krystian Hebel <krystian.hebel@3mdeb.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/57076 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/ppc64/Makefile.inc3
-rw-r--r--src/arch/ppc64/bootblock.S10
-rw-r--r--src/arch/ppc64/bootblock_crt0.S92
3 files changed, 94 insertions, 11 deletions
diff --git a/src/arch/ppc64/Makefile.inc b/src/arch/ppc64/Makefile.inc
index 13b61673bd..8ccd62bfab 100644
--- a/src/arch/ppc64/Makefile.inc
+++ b/src/arch/ppc64/Makefile.inc
@@ -9,7 +9,8 @@ ppc64_asm_flags =
################################################################################
ifeq ($(CONFIG_ARCH_BOOTBLOCK_PPC64),y)
-bootblock-y = bootblock.S stages.c
+bootblock-y = bootblock_crt0.S
+bootblock-y += arch_timer.c
bootblock-y += boot.c
bootblock-y += rom_media.c
bootblock-y += \
diff --git a/src/arch/ppc64/bootblock.S b/src/arch/ppc64/bootblock.S
deleted file mode 100644
index b443f056d1..0000000000
--- a/src/arch/ppc64/bootblock.S
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Early initialization code for POWER8.
- */
-
-.section ".text._start", "ax", %progbits
-.globl _start
-.org 0x100, 0xff
-_start:
- b _start
diff --git a/src/arch/ppc64/bootblock_crt0.S b/src/arch/ppc64/bootblock_crt0.S
new file mode 100644
index 0000000000..3988583bee
--- /dev/null
+++ b/src/arch/ppc64/bootblock_crt0.S
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Early initialization code for POWER8/POWER9.
+ */
+
+#define FIXUP_ENDIAN \
+ tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \
+ b $+44; /* Skip trampoline if endian is good */ \
+ .long 0xa600607d; /* mfmsr r11 */ \
+ .long 0x01006b69; /* xori r11,r11,1 */ \
+ .long 0x00004039; /* li r10,0 */ \
+ .long 0x6401417d; /* mtmsrd r10,1 */ \
+ .long 0x05009f42; /* bcl 20,31,$+4 */ \
+ .long 0xa602487d; /* mflr r10 */ \
+ .long 0x14004a39; /* addi r10,r10,20 */ \
+ .long 0xa6035a7d; /* mtsrr0 r10 */ \
+ .long 0xa6037b7d; /* mtsrr1 r11 */ \
+ .long 0x2400004c /* rfid */
+
+/* Load an immediate 64-bit value into a register */
+#define LOAD_IMM64(r, e) \
+ lis r,(e)@highest; \
+ ori r,r,(e)@higher; \
+ rldicr r,r, 32, 31; \
+ oris r,r, (e)@h; \
+ ori r,r, (e)@l;
+
+.section ".text._start", "ax", %progbits
+.globl _start
+_start:
+ /* QEMU with hb-mode=on starts at address 0x10, while hardware at 0x0 */
+ nop
+ nop
+ nop
+ nop
+ FIXUP_ENDIAN
+
+ /* Set program priority to medium */
+ or %r2, %r2, %r2
+
+ /* Stack */
+ lis %r1, _estack@ha
+ addi %r1, %r1, _estack@l
+
+ /* Clear .bss section */
+ /* Currently not needed, .bss is zeroed in the file. If it were to be
+ * used, make sure that .bss is 128B aligned (size of cache line),
+ * otherwise dcbz will clear (part of) .opd section! */
+/*
+ lis %r5, _bss@ha
+ addi %r5, %r5, _bss@l
+ lis %r6, _ebss@ha
+ addi %r6, %r6, _ebss@l
+ addi %r6, %r6, -1
+1:
+ dcbz 0, %r5
+ addi %r5, %r5, 128
+ cmpld cr7, %r5, %r6
+ blt cr7, 1b
+*/
+
+ /* This is tested by checkstack() just before jumping to payload */
+ LOAD_IMM64(%r3, 0xDEADBEEFDEADBEEF)
+ lis %r5, _stack@ha
+ addi %r5, %r5, _stack@l
+ subi %r5, %r5, 8
+ sub %r4, %r1, %r5
+ sradi %r4, %r4, 3 /* Divide by 8 */
+ mtctr %r4
+1:
+ stdu %r3, 8(%r5)
+ bc 25, 0, 1b
+
+ /* Enable floating point and vector operations */
+ /* Vector operations are sometimes generated for code like
+ * 'uint8_t x[32] = {0}', this results in an exception when vector
+ * registers (VEC) are not enabled. VSX (vector-scalar extension) is
+ * also enabled, there is no reason not to. Floating point must also be
+ * enabled for VSX.
+ */
+ mfmsr %r3
+ ori %r3, %r3, 0x2000 /* FP = 1 */
+ oris %r3, %r3, 0x0280 /* VEC = 1, VSX = 1 */
+ mtmsr %r3
+
+ /* Load official procedure descriptor address for main() */
+ lis %r12, main@ha
+ addi %r12, %r12, main@l
+
+ /* Load TOC pointer and jump to main() */
+ ld %r2, 8(%r12)
+ b main