diff options
author | Krystian Hebel <krystian.hebel@3mdeb.com> | 2020-09-23 14:40:45 +0200 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2022-02-11 13:54:26 +0000 |
commit | e527c713bd3533858054fe389ec2a5c93f6d6726 (patch) | |
tree | 0c188b15f4d0dcf9a75e054d1db1eed9a51b775f /src/arch | |
parent | 707e5452e7037bfc918862901401608469d2e86a (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.inc | 3 | ||||
-rw-r--r-- | src/arch/ppc64/bootblock.S | 10 | ||||
-rw-r--r-- | src/arch/ppc64/bootblock_crt0.S | 92 |
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 |