1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Early initialization code for POWER8/POWER9. 4 */ 5 6#include <cpu/power/spr.h> 7 8#define FIXUP_ENDIAN \ 9 tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ 10 b $+44; /* Skip trampoline if endian is good */ \ 11 .long 0xa600607d; /* mfmsr r11 */ \ 12 .long 0x01006b69; /* xori r11,r11,1 */ \ 13 .long 0x00004039; /* li r10,0 */ \ 14 .long 0x6401417d; /* mtmsrd r10,1 */ \ 15 .long 0x05009f42; /* bcl 20,31,$+4 */ \ 16 .long 0xa602487d; /* mflr r10 */ \ 17 .long 0x14004a39; /* addi r10,r10,20 */ \ 18 .long 0xa6035a7d; /* mtsrr0 r10 */ \ 19 .long 0xa6037b7d; /* mtsrr1 r11 */ \ 20 .long 0x2400004c /* rfid */ 21 22/* Load an immediate 64-bit value into a register */ 23#define LOAD_IMM64(r, e) \ 24 lis r,(e)@highest; \ 25 ori r,r,(e)@higher; \ 26 rldicr r,r, 32, 31; \ 27 oris r,r, (e)@h; \ 28 ori r,r, (e)@l; 29 30.section ".text._start", "ax", %progbits 31.globl _start 32_start: 33 /* QEMU with hb-mode=on starts at address 0x10, while hardware at 0x0 */ 34 nop 35 nop 36 nop 37 nop 38 FIXUP_ENDIAN 39 40 /* Store FDT address provided by QEMU in %r3 to pass it later to 41 * payload */ 42 mtspr SPR_HSPRG0, %r3 43 44 /* Set program priority to medium */ 45 or %r2, %r2, %r2 46 47 /* Stack */ 48 lis %r1, _estack@ha 49 addi %r1, %r1, _estack@l 50 51 /* Clear .bss section */ 52 /* Currently not needed, .bss is zeroed in the file. If it were to be 53 * used, make sure that .bss is 128B aligned (size of cache line), 54 * otherwise dcbz will clear (part of) .opd section! */ 55/* 56 lis %r5, _bss@ha 57 addi %r5, %r5, _bss@l 58 lis %r6, _ebss@ha 59 addi %r6, %r6, _ebss@l 60 addi %r6, %r6, -1 611: 62 dcbz 0, %r5 63 addi %r5, %r5, 128 64 cmpld cr7, %r5, %r6 65 blt cr7, 1b 66*/ 67 68 /* This is tested by checkstack() just before jumping to payload */ 69 LOAD_IMM64(%r3, 0xDEADBEEFDEADBEEF) 70 lis %r5, _stack@ha 71 addi %r5, %r5, _stack@l 72 subi %r5, %r5, 8 73 sub %r4, %r1, %r5 74 sradi %r4, %r4, 3 /* Divide by 8 */ 75 mtctr %r4 761: 77 stdu %r3, 8(%r5) 78 bc 25, 0, 1b 79 80 /* Enable floating point and vector operations */ 81 /* Vector operations are sometimes generated for code like 82 * 'uint8_t x[32] = {0}', this results in an exception when vector 83 * registers (VEC) are not enabled. VSX (vector-scalar extension) is 84 * also enabled, there is no reason not to. Floating point must also be 85 * enabled for VSX. 86 */ 87 mfmsr %r3 88 ori %r3, %r3, 0x2000 /* FP = 1 */ 89 oris %r3, %r3, 0x0280 /* VEC = 1, VSX = 1 */ 90 mtmsr %r3 91 92 /* Load official procedure descriptor address for main() */ 93 lis %r12, main@ha 94 addi %r12, %r12, main@l 95 96 /* Load TOC pointer and jump to main() */ 97 ld %r2, 8(%r12) 98 b main 99