xref: /aosp_15_r20/external/coreboot/src/arch/ppc64/bootblock_crt0.S (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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