xref: /openbsd/sys/arch/macppc/macppc/ofwreal.S (revision 81621933)
1/*	$OpenBSD: ofwreal.S,v 1.9 2022/12/08 01:25:45 guenther Exp $	*/
2/*	$NetBSD: ofwreal.S,v 1.1 1996/09/30 16:34:51 ws Exp $	*/
3
4/*
5 * Copyright (C) 1996 Wolfgang Solfrank.
6 * Copyright (C) 1996 TooLs GmbH.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *	This product includes software developed by TooLs GmbH.
20 * 4. The name of TooLs GmbH may not be used to endorse or promote products
21 *    derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/*
36 * This file provides a real-mode client interface on machines, that
37 * (incorrectly) only implement virtual mode client interface.
38 *
39 * It assumes though, that any actual memory in the machine is
40 * mapped 1:1 even by the virtual mode OpenFirmware.
41 * Furthermore it assumes that addresses returned by OpenFirmware are not
42 * accessed by the client.
43 *
44 */
45#include <machine/asm.h>
46#include <machine/psl.h>
47#include <machine/trap.h>
48#include <machine/param.h>
49
50#define	CACHELINE	32		/* Note that this value is really hardwired */
51
52	.data
53ofentry:	.long	0		/* actual entry to firmware in virtual mode */
54
55#define	SRSIZE		(16*4+4)
56#define	SPRGSIZE	(4*4)
57#define	SDR1SIZE	4
58#define MSRSIZE		4
59#define	SVSIZE		(SRSIZE+SPRGSIZE+SDR1SIZE+MSRSIZE)
60#define BATSIZE		(16*4)
61
62	.global fwcall
63fwcall: .long 0
64
65.lcomm	fwsave,SVSIZE,8
66.lcomm	fwbatsave,BATSIZE,8
67.lcomm	clsave,SVSIZE,8
68.lcomm	clbatsave,BATSIZE,8
69.lcomm	ofsrsave,16*4,4	/* 16 words of 4 bytes to store OF segment registers */
70.lcomm	srsave,16*4,4	/* 16 words of 4 bytes to swap OF segment registers*/
71	.globl ofmsr
72ofmsr:			.long	0	/* area to store msr for openfirmware*/
73
74	.text
75_ENTRY(ofw_init)
76	mflr	%r31			/* save return address */
77
78	mr	%r13,%r6		/* save args (only pointer used) */
79	lis	%r8,ofentry@ha
80	stw	%r5,ofentry@l(%r8)	/* save virtual mode firmware entry */
81
82	lis	%r4,fwcall@ha		/* call ofw directly until vm setup */
83	stw	%r5,fwcall@l(%r4)
84
85	mfmsr	%r5
86	lis	%r4,ofmsr@ha		/* save msr from openfirmware */
87	stw	%r5,ofmsr@l(%r4)
88#if 0
89	lis	%r0,(0x80001ffe)@ha
90	addi	%r0,%r0,(0x80001ffe)@l
91	mtdbatu 0,%r0
92	lis	%r0,(0x80000022)@ha
93	addi	%r0,%r0,(0x80000022)@l
94	mtdbatl 0,%r0
95#endif
96
97	lis	%r3,fwsave@ha	/* save the mmu values of the firmware */
98	addi	%r3,%r3,fwsave@l
99	lis	%r4,fwbatsave@ha
100	addi	%r4,%r4,fwbatsave@l
101	bl	savemmu
102
103	/* save openfirmware address mappings */
104	bl	save_ofw_mapping
105
106#if 0
107	/* dont really need the bats from firmware saved, 0 to disable */
108	lis	%r3,fwbatsave@ha
109	addi	%r3,%r3,fwbatsave@l
110	li	%r4,64
111	li	%r5,0
1121:	subi	%r4,%r4,%r4
113	stwx	%r5,%r4,%r3
114	cmpi	4,0,0
115	bne	1b
116#endif
117
118	mr	%r6,%r13		/* restore args pointer */
119	mtlr	%r31			/* restore return address */
120	blr
121
122/*
123 * Save everything related to the mmu to the savearea pointed to by r3.
124 */
125	.type	savemmu,@function
126savemmu:
127	RETGUARD_SETUP(savemmu, %r11, %r12)
128	mr	%r6,%r4	/* r4 holds pointer to BAT save area */
129
130	li	%r4,0			/* save SRs */
1311:
132	addis	%r4,%r4,-0x10000000@ha
133	or.	%r4,%r4,%r4
134	mfsrin	%r5,%r4
135	stwu	%r5,4(%r3)
136	bne	1b
137
138	mfibatl	%r4,0			/* save BATs */
139	stw	%r4,0(%r6)
140	mfibatu	%r4,0
141	stw	%r4,4(%r6)
142	mfibatl	%r4,1
143	stw	%r4,8(%r6)
144	mfibatu	%r4,1
145	stw	%r4,0xc(%r6)
146	mfibatl	%r4,2
147	stw	%r4,0x10(%r6)
148	mfibatu	%r4,2
149	stw	%r4,0x14(%r6)
150	mfibatl	%r4,3
151	stw	%r4,0x18(%r6)
152	mfibatu	%r4,3
153	stw	%r4,0x1c(%r6)
154	mfdbatl	%r4,0
155	stw	%r4,0x20(%r6)
156	mfdbatu	%r4,0
157	stw	%r4,0x24(%r6)
158	mfdbatl	%r4,1
159	stw	%r4,0x28(%r6)
160	mfdbatu	%r4,1
161	stw	%r4,0x2c(%r6)
162	mfdbatl	%r4,2
163	stw	%r4,0x30(%r6)
164	mfdbatu	%r4,2
165	stw	%r4,0x34(%r6)
166	mfdbatl	%r4,3
167	stw	%r4,0x38(%r6)
168	mfdbatu	%r4,3
169	stw	%r4,0x3c(%r6)
170
171	mfsprg	%r4,0			/* save SPRGs */
172	stw	%r4,4(%r3)
173	mfsprg	%r4,1
174	stw	%r4,8(%r3)
175	mfsprg	%r4,2
176	stw	%r4,12(%r3)
177	mfsprg	%r4,3
178	stw	%r4,16(%r3)
179
180	mfsdr1	%r4			/* save SDR1 */
181	stw	%r4,20(%r3)
182
183	addi	%r4,%r3,24
184
185	mfmsr	%r4
186	stw	%r4,24(%r3)
187
188	sync
189	isync
190
191	RETGUARD_CHECK(savemmu, %r11, %r12)
192	blr
193
194/*
195 * Restore everything related to the mmu from the savearea pointed to by r3.
196 * and bats pointed to by r4.
197 */
198	.type	restoremmu,@function
199restoremmu:
200	RETGUARD_SETUP(restoremmu, %r11, %r12)
201	li	%r0,0
202	mtmsr	%r0
203	mr	%r6,%r4			/* pointer to sr to restore */
204	li	%r4,0			/* restore SRs */
2051:
206	lwzu	%r5,4(%r3)
207	addis	%r4,%r4,-0x10000000@ha
208	or.	%r4,%r4,%r4
209	mtsrin	%r5,%r4
210	bne	1b
211
212	mfmsr	%r4
213	lis	%r5,(PSL_IR|PSL_DR)@h		/* turn off MMU */
214	ori	%r5,%r5,(PSL_IR|PSL_DR)@l	/* turn off MMU */
215	andc	%r4,%r4,%r5				/* turn off MMU */
216	mtmsr	%r4
217	isync
218
219	li	%r4,0			/* first, invalidate BATs */
220	mtibatu	0,%r4
221	mtibatu	1,%r4
222	mtibatu	2,%r4
223	mtibatu	3,%r4
224	mtdbatu	0,%r4
225	mtdbatu	1,%r4
226	mtdbatu	2,%r4
227	mtdbatu	3,%r4
228
229	lwz	%r4,0(%r6)
230	mtibatl	0,%r4			/* restore BATs */
231	lwz	%r4,4(%r6)
232	mtibatu	0,%r4
233	lwz	%r4,8(%r6)
234	mtibatl	1,%r4
235	lwz	%r4,12(%r6)
236	mtibatu	1,%r4
237	lwz	%r4,16(%r6)
238	mtibatl	2,%r4
239	lwz	%r4,20(%r6)
240	mtibatu	2,%r4
241	lwz	%r4,24(%r6)
242	mtibatl	3,%r4
243	lwz	%r4,28(%r6)
244	mtibatu	3,%r4
245	lwz	%r4,32(%r6)
246	mtdbatl	0,%r4
247	lwz	%r4,36(%r6)
248	mtdbatu	0,%r4
249	lwz	%r4,40(%r6)
250	mtdbatl	1,%r4
251	lwz	%r4,44(%r6)
252	mtdbatu	1,%r4
253	lwz	%r4,48(%r6)
254	mtdbatl	2,%r4
255	lwz	%r4,52(%r6)
256	mtdbatu	2,%r4
257	lwz	%r4,56(%r6)
258	mtdbatl	3,%r4
259	lwz	%r4,60(%r6)
260	mtdbatu	3,%r4
261
262	lwz	%r4,4(%r3)
263	mtsprg	0,4			/* restore SPRGs */
264	lwz	%r4,8(%r3)
265	mtsprg	1,4
266	lwz	%r4,12(%r3)
267	mtsprg	2,4
268	lwz	%r4,16(%r3)
269	mtsprg	3,4
270
271	sync				/* remove everything from tlb */
272	lis	%r4,0x40000@ha
273	li	%r5,0x1000
2741:
275	subf.	%r4,%r5,%r4
276	tlbie	%r4
277	bne	1b
278
279	sync
280	tlbsync
281	sync
282
283	lwz	%r4,20(%r3)
284	sync
285	mtsdr1	%r4			/* restore SDR1 */
286
287
288	/* tlbia */
289	sync
290	li	%r5,0x40
291	mtctr	%r5
292	li	%r4,0
293    1:
294	tlbie	%r4
295	addi	%r4,%r4,0x1000
296	bdnz	1b
297	sync
298	tlbsync
299	sync
300
301	lwz	%r4,24(%r3)
302	mtmsr	%r4
303	isync
304
305	RETGUARD_CHECK(restoremmu, %r11, %r12)
306	blr
307
308
309_ENTRY(fwentry)
310	mflr	%r4
311	RETGUARD_SETUP_LATE(fwentry, %r11, %r4)
312	stwu	%r1,-16(%r1)
313	stw	%r4,20(%r1)
314	stw	%r3,12(%r1)			/* save arg */
315	RETGUARD_SAVE(%r11, 8(%r1))
316
317	lis	%r3,clsave@ha		/* save mmu values of client */
318	addi	%r3,%r3,clsave@l
319	lis	%r4,clbatsave@ha	/* save mmu values of client */
320	addi	%r4,%r4,clbatsave@l
321	bl	savemmu
322
323	lis	%r3,fwsave@ha		/* restore mmu values of firmware */
324	addi	%r3,%r3,fwsave@l
325	lis	%r4,fwbatsave@ha
326	addi	%r4,%r4,fwbatsave@l
327	bl	restoremmu
328
329	lis	%r3,ofentry@ha
330	lwz	%r3,ofentry@l(%r3)	/* get actual firmware entry */
331	mtlr	%r3
332
333	mfmsr	%r4
334	ori	%r4,%r4,PSL_IR|PSL_DR	/* turn on MMU */
335	mtmsr	%r4
336	isync
337
338	lwz	%r3,12(%r1)		/* restore arg */
339	blrl				/* do actual firmware call */
340
341	stw	%r3,12(%r1)		/* save return value */
342
343	lis	%r3,fwsave@ha		/* save mmu values of firmware */
344	addi	%r3,%r3,fwsave@l	/* (might not be necessary, but... */
345	lis	%r4,fwbatsave@ha
346	addi	%r4,%r4,fwbatsave@l
347	bl	savemmu
348
349	lis	%r3,clsave@ha		/* restore mmu values of client */
350	addi	%r3,%r3,clsave@l
351	lis	%r4,clbatsave@ha	/* save mmu values of client */
352	addi	%r4,%r4,clbatsave@l
353	bl	restoremmu
354
355	lwz	%r4,20(%r1)
356	lwz	%r3,12(%r1)		/* restore return value */
357	RETGUARD_LOAD(%r11, 8(%r1))
358
359	mtlr	%r4
360	addi	%r1,%r1,16
361	RETGUARD_CHECK(fwentry, %r11, %r4)
362	blr
363
364.lcomm	firmstk,NBPG,16
365.comm	OF_buf,NBPG
366
367/*
368 * OpenFirmware entry point
369 *
370 * Note: caller has to set the machine state register (msr)
371 * to be correct for OpenFirmware.
372 */
373_ENTRY(openfirmware)
374	mflr	%r0
375	RETGUARD_SETUP_LATE(openfirmware, %r11, %r0)
376	stw	%r0,4(%r1)		/* save return address */
377
378	/* switch to OpenFirmware real mode stack */
379	lis	%r7,firmstk+NBPG-16@ha
380	addi	%r7,%r7,firmstk+NBPG-16@l
381	stw	%r1,0(%r7)
382	RETGUARD_SAVE(%r11, 8(%r7))
383	mr	%r1,%r7
384
385	lis	%r4,fwcall@ha
386	lwz	%r4,fwcall@l(%r4)
387
388	mtctr	%r4
389	bctrl
390
391	RETGUARD_LOAD(%r11, 8(%r1))
392	lwz	%r1,0(%r1)		/* get callers original stack pointer */
393	lwz	%r0,4(%r1)
394	mtlr	%r0
395	RETGUARD_CHECK(openfirmware, %r11, %r0)
396	blr
397