summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/board-qemu/llfw/startup.S
blob: bbd3ce3ac51bf7f6fabbbe0de76dab8915bd536f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/******************************************************************************
 * Copyright (c) 2004, 2011 IBM Corporation
 * All rights reserved.
 * This program and the accompanying materials
 * are made available under the terms of the BSD License
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/bsd-license.php
 *
 * Contributors:
 *     IBM Corporation - initial implementation
 *****************************************************************************/

/* SLOF for QEMU -- boot code.
 * Initial entry point
 */

#include <xvect.h>
#include <cpu.h>
#include <macros.h>

	/* qemu entry:
	 *
	 * __start loaded at 0x100
	 *
	 * CPU 0 starts at 0 with GPR3 pointing to the flat devtree
	 *
	 * All other CPUs are held in stopped state by qemu and are
	 * started via RTAS
	 */
	.text
	.globl __start
__start:
	b	_start
	.long 0xDEADBEE0
	.long 0x0       /* size */ 
	.long 0x0       /* crc  */
	.long relTag - __start

	/* Some exception vectors
	 *	
	 * FIXME: Also need 0280, 0380, 0f20, etc.
	 */

	.irp i, 0x0100,0x0180,0x0200,0x0280,0x0300,0x0380,0x0400,0x0500, \
	        0x0600,0x0700,0x0800,0x0900,0x0a00,0x0b00,0x0c00,0x0d00, \
	        0x0e00,0x0f00,0x1000,0x1100,0x1200,0x1300,0x1400,0x1500, \
	        0x1600,0x1700, \
		0x1800,0x1900,0x1a00,0x1b00,0x1c00,0x1d00,0x1e00,0x1f00, \
		0x2000,0x2100,0x2200,0x2300,0x2400,0x2500,0x2600,0x2700, \
		0x2800,0x2900,0x2a00,0x2b00,0x2c00,0x2d00,0x2e00
	. = \i

	/* enable this if you get exceptions before the console works    */
	/* this will allow using the hardware debugger to see where      */
	/* it traps, and with what register values etc.                  */
	// b	$

	mtsprg	0,r0
	mfctr	r0
	mtsprg  2,r0
	mflr	r0
// 10
	mtsprg  3,r0
	ld	r0, (\i + 0x60)(0)
	mtctr	r0
	li	r0, \i + 0x100
// 20
	bctr

	. = \i + 0x60
	.quad	intHandler2C
	.endr

	. = XVECT_M_HANDLER - 0x100
	.quad	0x00
	.text

	/* Here's the startup code for the master CPU */
	.org 0x4000 - 0x100
_start:
	/* Save device-tree pointer */
	mr	r31,r3

	/* Switch to 64-bit mode with 64-bit exceptions */
#define MSR_SF_LG	63              /* Enable 64 bit mode */
#define MSR_ISF_LG	61              /* Interrupt 64b mode valid on 630 */
#define __MASK(X)	(1<<(X))
#define MSR_SF		__MASK(MSR_SF_LG)	/* Enable 64 bit mode */
#define MSR_ISF		__MASK(MSR_ISF_LG)	/* Interrupt 64b mode */
	mfmsr	r11			/* grab the current MSR */
	li	r12,(MSR_SF | MSR_ISF)@highest
	sldi	r12,r12,48
	or	r11,r11,r12
	mtmsrd	r11
	isync

	/* Early greet */
	li	r3,10
	bl	putc
	li	r3,13
	bl	putc
	li	r3,10
	bl	putc
	li	r3,'S'
	bl	putc

	li	r3,'L'
	bl	putc
	li	r3,'O'
	bl	putc
	li	r3,'F'
	bl	putc

	bl	print_version

	/* go! */
	li	r3,__startC@l
	mtctr	r3
	bctrl
	
	/* write a character to the HV console */
putc:	sldi	r6,r3,(24+32)
	li	r3,0x58
	li	r4,0
	li	r5,1
	.long	0x44000022
	blr

relTag:
	.ascii  RELEASE
	.ascii	"\0"
	.align	2

C_ENTRY(proceedInterrupt)

	ld      r3,exception_stack_frame@got(r2)
	ld	r1,0(r3)

	.irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \
	        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
		27, 28, 29, 30, 31
	ld	r\i, 0x30+\i*8 (r1)
	.endr

	ld	r14,0x138(r1);
	mtsrr0	r14

	ld	r14,0x140(r1);
	mtsrr1	r14

	ld	r14,0x148(r1);
	mtcr	r14

	ld	0,XVECT_M_HANDLER(0)
	mtctr	0

	ld	r0,0x30(r1); # restore vector number
	ld	r1,0x38(r1);

	bctr

intHandler2C:
	mtctr	r1 # save old stack pointer
	lis	r1,0x4
	stdu	r1, -0x160(r1)
	.irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \
	        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
		27, 28, 29, 30, 31
	std	r\i, 0x30+\i*8 (r1)
	.endr

	std	r0,0x30(r1);  # save vector number

	mfctr	r14
	std	r14,0x38(r1); # save old r1

	mfsrr0	r14
	std	r14,0x138(r1);

	mfsrr1	r14
	std	r14,0x140(r1);

	mfcr	r14
	std	r14,0x148(r1);

	mfxer	r14
	std	r14,0x150(r1);

	bl	toc_init

	ld      r3,exception_stack_frame@got(r2)
	std     r1,0(r3)


	mr 	r3,r0
	bl	.c_interrupt

	ld	r14,0x138(r1);
	mtsrr0	r14

	ld	r14,0x140(r1);
	mtsrr1	r14

	ld	r14,0x148(r1);
	mtcr	r14

	ld	r14,0x150(r1);
	mtxer	r14


	.irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \
	        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
		27, 28, 29, 30, 31
	ld	r\i, 0x30+\i*8 (r1)
	.endr

	ld	r1,0x38(r1);

	mfsprg	r0,2
	mtctr	r0
	mfsprg	r0,3
	mtlr	r0
	mfsprg	r0,0
	rfid

/* Set exception handler for given exception vector.  
	r3:	exception vector offset
	r4:	exception handler
*/
	.globl .set_exception
.set_exception:
	.globl set_exception
set_exception:
	ld r4,0x0(r4)
	.globl .set_exception_asm
.set_exception_asm:
	.globl set_exception_asm
set_exception_asm:
	std	r4, 0x60(r3)	# fixme diff 1f - 0b
	blr