xref: /netbsd-src/sys/arch/powerpc/oea/ofw_subr.S (revision 4dff67b13d5627050077ab00a28bee221c010d7f)
1/*	$NetBSD: ofw_subr.S,v 1.20 2021/02/28 19:01:11 thorpej Exp $	*/
2
3/*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifdef _KERNEL_OPT
35#include "opt_ppcarch.h"
36#endif
37
38	/* Stack used to call into OpenFirmware. */
39	.lcomm	firmstk,NBPG,16
40
41	/* Buffer used to pass data to/from OpenFirmware. */
42	.lcomm	OF_buffer,NBPG + 36,4
43
44	/* The OpenFirmware entry point, provided by OpenFirmware. */
45	.lcomm	ofentry,4,4
46
47	/* Entry trampoline used by openfirmware(). */
48	.lcomm	oftramp,4,4
49
50	/* Client SR save area */
51	.lcomm	clsrsave,64,4
52
53	/* MSR used in OpenFirmware */
54	.globl	ofwmsr
55	.comm	ofwmsr,4,4
56
57#ifdef FIRMWORKSBUGS
58	.lcomm	ofwreal_incharge,4,4
59#endif
60
61/*
62 * Called by start to save the initial OFW state so we can restore it
63 * when call back to OFW.
64 *
65 * We expect the registers to be as for the entry point into the kernel:
66 *
67 *	%r1	Stack provided by OpenFirmware / boot loader
68 *	%r5	OpenFirmware client entry point
69 *
70 * (others -- don't care)
71 */
72ENTRY_NOPROFILE(ofwinit)
73	/* Save return address, Push a stack frame. */
74	mflr	%r0
75	stw	%r0,4(%r1)
76	stwu	%r1,-16(%r1)
77
78#ifdef FIRMWORKSBUGS
79	mfmsr	%r0
80	andi.	%r0,%r0,PSL_IR|PSL_DR
81	beq	1f
82
83	li	%r8,1
84	lis	%r9,ofwreal_incharge@ha
85	stw	%r8,ofwreal_incharge@l(%r9)
86
87	bl	_C_LABEL(ofwr_init)
881:
89#endif
90
91	lis	%r8,ofentry@ha
92	stw	%r5,ofentry@l(%r8)	/* save client interface handler */
93
94	/*
95	 * Call directly into OpenFirmware until we're ready to use
96	 * the trampoline.
97	 */
98	lis	%r8,oftramp@ha
99	stw	%r5,oftramp@l(%r8)
100
101	/* Save the MSR that OpenFirmware is using. */
102	mfmsr	%r0
103	lis	%r9,ofwmsr@ha
104	stw	%r0,ofwmsr@l(%r9)
105
106	lis	%r8,OF_buffer@ha
107	addi	%r8,%r8,OF_buffer@l
108	lis	%r9,_C_LABEL(OF_buf)@ha
109	stw	%r8,_C_LABEL(OF_buf)@l(%r9)
110
111	/*
112	 * Call into C code to perform additional early initialization.
113	 */
114	lis	%r8,_C_LABEL(ofw_bootstrap)@ha
115	addi	%r8,%r8,_C_LABEL(ofw_bootstrap)@l
116	mtctr	%r8
117	bctrl
118
119	/*
120	 * Jump off the trampoline for all subsequent calls
121	 * into OpenFirmware.
122	 */
123	lis	%r5,_C_LABEL(openfirmware_trampoline)@ha
124	addi	%r5,%r5,_C_LABEL(openfirmware_trampoline)@l
125	lis	%r8,oftramp@ha
126	stw	%r5,oftramp@l(%r8)
127
128	/* Retrieve LR, pop stack frame. */
129	addi	%r1,%r1,16
130	lwz	%r0,4(%r1)
131	mtlr	%r0
132
133	blr
134
135/*
136 * OpenFirmware trampoline.  We are already on the OpenFirmware stack.
137 */
138ENTRY_NOPROFILE(openfirmware_trampoline)
139	mflr	%r0
140	stw	%r0,4(%r1)		/* save return address */
141
142	/*
143	 * Push stack frame and save area:
144	 *
145	 * [SP+8 save area]
146	 * [SP+4 slot for saved LR in callee]
147	 * [SP+0 saved SP]
148	 */
149	stwu	%r1,-48(%r1)
150
151#ifdef FIRMWORKSBUGS
152	lis	%r4,ofwreal_incharge@ha
153	lwz	%r4,ofwreal_incharge@l(%r4)
154	cmpwi	%r4,1
155	bne	1f
156	blrl
157	b	4f
1581:
159#endif
160	mfmsr	%r4			/* save msr */
161	stw	%r4,8(%r1)
162
163	li	%r0,0			/* disable MMU */
164	mtmsr	%r0
165	isync
166
167#if defined (PPC_OEA) || defined (PPC_OEA64_BRIDGE)
168	/* clear BAT translations */
169	mtdbatu	2,%r0
170	mtdbatu	3,%r0
171	mtibatu	2,%r0
172	mtibatu	3,%r0
173#endif /* PPC_OEA */
174
175	lis	%r4,clsrsave@ha		/* save current SRs */
176	addi	%r4,%r4,clsrsave@l
177	li	%r5,0
1781:	mfsrin	%r0,%r5
179	stw	%r0,0(%r4)
180	addi	%r4,%r4,4
181	addis	%r5,%r5,0x10000000@h
182	cmpwi	%r5,0
183	bne	1b
184
185	lis	%r4,_C_LABEL(ofw_pmap)@ha	/* load OFW SR */
186	addi	%r4,%r4,_C_LABEL(ofw_pmap)@l
187	lwz	%r0,PM_KERNELSR(%r4)
188	cmpwi	%r0,0			/* pm_sr[KERNEL_SR] == 0? */
189	beq	2f			/* then skip (not initialized yet) */
190	li	%r5,0
1911:	lwz	%r0,0(%r4)
192	mtsrin	%r0,%r5
193	addi	%r4,%r4,4
194	addis	%r5,%r5,0x10000000@h
195	cmpwi	%r5,0
196	bne	1b
1972:
198	/* curcpu()->ci_battable = &ofw_battable */
199	GET_CPUINFO(%r4)
200	lis	%r5,_C_LABEL(ofw_battable)@ha
201	addi	%r5,%r5,_C_LABEL(ofw_battable)@l
202	stw	%r5,CI_BATTABLE(%r4)
203
204	lis	%r4,ofentry@ha		/* get firmware entry point */
205	lwz	%r4,ofentry@l(%r4)
206	mtlr	%r4
207
208	lis	%r4,ofwmsr@ha		/* load Open Firmware MSR */
209	lwz	%r5,ofwmsr@l(%r4)
210	mtmsr	%r5
211	isync
212
213	blrl				/* call Open Firmware */
214
215	li	%r0,0			/* ensure disable MMU is disabled */
216	mtmsr	%r0
217	isync
218
219	/* curcpu()->ci_battable = &battable */
220	GET_CPUINFO(%r4)
221	lis	%r5,_C_LABEL(battable)@ha
222	addi	%r5,%r5,_C_LABEL(battable)@l
223	stw	%r5,CI_BATTABLE(%r4)
224
225	lis	%r4,clsrsave@ha		/* restore saved SRs */
226	addi	%r4,%r4,clsrsave@l
227	li	%r5,0
2281:	lwz	%r0,0(%r4)
229	mtsrin	%r0,%r5
230	addi	%r4,%r4,4
231	addis	%r5,%r5,0x10000000@h
232	cmpwi	%r5,0
233	bne	1b
234
235	lwz	%r4,8(%r1)		/* restore msr */
236	mtmsr	%r4
237	isync
2384:
239	addi	%r1,%r1,48		/* pop stack frame and save area */
240	lwz	%r0,4(%r1)		/* return address */
241	mtlr	%r0
242	blr
243
244/*
245 * Call into OpenFirmware.
246 */
247ENTRY_NOPROFILE(openfirmware)
248	mflr	%r0
249	stw	%r0,4(%r1)		/* save return address */
250
251	/* Switch to OpenFirmware stack. */
252	lis	%r7,firmstk+NBPG-16@ha
253	addi	%r7,%r7,firmstk+NBPG-16@l
254	stw	%r1,0(%r7)		/* stash away prev stack pointer */
255	mr	%r1,%r7
256
257	lis	%r4,oftramp@ha
258	lwz	%r4,oftramp@l(%r4)
259
260	mtctr	%r4
261	bctrl
262
263	lwz	%r1,0(%r1)		/* restore previous stack pointer */
264	lwz	%r0,4(%r1)		/* return address */
265	mtlr	%r0
266	blr
267