Annotation of sys/arch/macppc/macppc/ofwreal.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ofwreal.S,v 1.3 2003/10/16 05:03:22 deraadt 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
53: ofentry: .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 _C_LABEL(fwcall)
63: _C_LABEL(fwcall): .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 _C_LABEL(ofmsr)
72: _C_LABEL(ofmsr): .long 0 /* area to store msr for openfirmware*/
73:
74: .text
75: _ENTRY(_C_LABEL(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,_C_LABEL(ofmsr)@ha /* save msr from openfirmware */
87: stw %r5,_C_LABEL(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 _C_LABEL(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
112: 1: 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 everyting related to the mmu to the saveare pointed to by r3.
124: */
125: .type savemmu,@function
126: savemmu:
127:
128: mr %r6,%r4 /* r4 holds pointer to BAT save area */
129:
130: li %r4,0 /* save SRs */
131: 1:
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: blr
192:
193: /*
194: * Restore everyting related to the mmu from the savearea pointed to by r3.
195: * and bats pointed to by r4.
196: */
197: .type restoremmu,@function
198: restoremmu:
199:
200: li %r0,0
201: mtmsr %r0
202: mr %r6,%r4 /* pointer to sr to restore */
203: li %r4,0 /* restore SRs */
204: 1:
205: lwzu %r5,4(%r3)
206: addis %r4,%r4,-0x10000000@ha
207: or. %r4,%r4,%r4
208: mtsrin %r5,%r4
209: bne 1b
210:
211: mfmsr %r4
212: lis %r5,(PSL_IR|PSL_DR)@h /* turn off MMU */
213: ori %r5,%r5,(PSL_IR|PSL_DR)@l /* turn off MMU */
214: andc %r4,%r4,%r5 /* turn off MMU */
215: mtmsr %r4
216: isync
217:
218: li %r4,0 /* first, invalidate BATs */
219: mtibatu 0,%r4
220: mtibatu 1,%r4
221: mtibatu 2,%r4
222: mtibatu 3,%r4
223: mtdbatu 0,%r4
224: mtdbatu 1,%r4
225: mtdbatu 2,%r4
226: mtdbatu 3,%r4
227:
228: lwz %r4,0(%r6)
229: mtibatl 0,%r4 /* restore BATs */
230: lwz %r4,4(%r6)
231: mtibatu 0,%r4
232: lwz %r4,8(%r6)
233: mtibatl 1,%r4
234: lwz %r4,12(%r6)
235: mtibatu 1,%r4
236: lwz %r4,16(%r6)
237: mtibatl 2,%r4
238: lwz %r4,20(%r6)
239: mtibatu 2,%r4
240: lwz %r4,24(%r6)
241: mtibatl 3,%r4
242: lwz %r4,28(%r6)
243: mtibatu 3,%r4
244: lwz %r4,32(%r6)
245: mtdbatl 0,%r4
246: lwz %r4,36(%r6)
247: mtdbatu 0,%r4
248: lwz %r4,40(%r6)
249: mtdbatl 1,%r4
250: lwz %r4,44(%r6)
251: mtdbatu 1,%r4
252: lwz %r4,48(%r6)
253: mtdbatl 2,%r4
254: lwz %r4,52(%r6)
255: mtdbatu 2,%r4
256: lwz %r4,56(%r6)
257: mtdbatl 3,%r4
258: lwz %r4,60(%r6)
259: mtdbatu 3,%r4
260:
261: lwz %r4,4(%r3)
262: mtsprg 0,4 /* restore SPRGs */
263: lwz %r4,8(%r3)
264: mtsprg 1,4
265: lwz %r4,12(%r3)
266: mtsprg 2,4
267: lwz %r4,16(%r3)
268: mtsprg 3,4
269:
270: sync /* remove everything from tlb */
271: lis %r4,0x40000@ha
272: li %r5,0x1000
273: 1:
274: subf. %r4,%r5,%r4
275: tlbie %r4
276: bne 1b
277:
278: sync
279: tlbsync
280: sync
281:
282: lwz %r4,20(%r3)
283: sync
284: mtsdr1 %r4 /* restore SDR1 */
285:
286:
287: /* tlbia */
288: sync
289: li %r5,0x40
290: mtctr %r5
291: li %r4,0
292: 1:
293: tlbie %r4
294: addi %r4,%r4,0x1000
295: bdnz 1b
296: sync
297: tlbsync
298: sync
299:
300: lwz %r4,24(%r3)
301: mtmsr %r4
302: isync
303:
304: blr
305:
306:
307: _ENTRY(_C_LABEL(fwentry))
308: stwu %r1,-16(%r1)
309: mflr %r4
310: stw %r4,20(%r1)
311: stw %r3,12(%r1) /* save arg */
312:
313: lis %r3,clsave@ha /* save mmu values of client */
314: addi %r3,%r3,clsave@l
315: lis %r4,clbatsave@ha /* save mmu values of client */
316: addi %r4,%r4,clbatsave@l
317: bl savemmu
318:
319: lis %r3,fwsave@ha /* restore mmu values of firmware */
320: addi %r3,%r3,fwsave@l
321: lis %r4,fwbatsave@ha
322: addi %r4,%r4,fwbatsave@l
323: bl restoremmu
324:
325: lis %r3,ofentry@ha
326: lwz %r3,ofentry@l(%r3) /* get actual firmware entry */
327: mtlr %r3
328:
329: mfmsr %r4
330: ori %r4,%r4,PSL_IR|PSL_DR /* turn on MMU */
331: mtmsr %r4
332: isync
333:
334: lwz %r3,12(%r1) /* restore arg */
335: blrl /* do actual firmware call */
336:
337: stw %r3,12(%r1) /* save return value */
338:
339: lis %r3,fwsave@ha /* save mmu values of firmare */
340: addi %r3,%r3,fwsave@l /* (might not be necessary, but... */
341: lis %r4,fwbatsave@ha
342: addi %r4,%r4,fwbatsave@l
343: bl savemmu
344:
345: lis %r3,clsave@ha /* restore mmu values of client */
346: addi %r3,%r3,clsave@l
347: lis %r4,clbatsave@ha /* save mmu values of client */
348: addi %r4,%r4,clbatsave@l
349: bl restoremmu
350:
351: lwz %r4,20(%r1)
352: lwz %r3,12(%r1) /* restore return value */
353:
354: mtlr %r4
355: addi %r1,%r1,16
356: blr
357:
358: /*
359: * OpenFirmware entry point
360: */
361: _ENTRY(_C_LABEL(openfirmware))
362: stwu %r1,-16(%r1)
363: mflr %r0 /* save return address */
364: stw %r0,20(%r1)
365:
366: lis %r4,fwcall@ha
367: lwz %r4,fwcall@l(%r4)
368:
369: mtlr %r4
370: blrl
371:
372: lwz %r0,20(%r1)
373: mtlr %r0
374: lwz %r1,0(%r1)
375: blr
376:
377: /*
378: * Switch to/from OpenFirmware real mode stack
379: *
380: * Note: has to be called as the very first thing in OpenFirmware interface routines.
381: * E.g.:
382: * int
383: * OF_xxx(arg1, arg2)
384: * type arg1, arg2;
385: * {
386: * static struct {
387: * char *name;
388: * int nargs;
389: * int nreturns;
390: * char *method;
391: * int arg1;
392: * int arg2;
393: * int ret;
394: * } args = {
395: * "xxx",
396: * 2,
397: * 1,
398: * };
399: *
400: * ofw_stack();
401: * args.arg1 = arg1;
402: * args.arg2 = arg2;
403: * if (openfirmware(&args) < 0)
404: * return -1;
405: * return args.ret;
406: * }
407: */
408: .lcomm firmstk,NBPG,16
409: .comm _C_LABEL(OF_buf),NBPG,PGOFSET
410:
411: _ENTRY(_C_LABEL(ofw_stack))
412: mfmsr %r8 /* turn off interrupts */
413: andi. %r0,%r8,~(PSL_EE|PSL_RI)@l
414: mtmsr %r0
415: stw %r8,4(%r1) /* abuse return address slot */
416:
417: lwz %r5,0(%r1) /* get length of stack frame */
418: subf %r5,%r1,%r5
419:
420: lis %r7,firmstk+NBPG-8@ha
421: addi %r7,%r7,firmstk+NBPG-8@l
422: li %r6,0xf
423: andc %r7,%r7,%r6
424: lis %r6,ofw_back@ha
425: addi %r6,%r6,ofw_back@l
426: subf %r4,%r5,%r7 /* make room for stack frame on new stack */
427: stwu %r1,-16(%r7)
428: stw %r6,4(%r7) /* setup return pointer */
429:
430: stw %r7,-16(%r4)
431:
432: addi %r3,%r1,%r8
433: addi %r1,%r4,-16
434: subi %r5,%r5,%r8
435: subi %r4,%r4,%r8
436:
437: b _C_LABEL(ofbcopy) /* and copy it */
438:
439: .type ofw_back,@function
440: ofw_back:
441: lwz %r1,0(%r1) /* get callers original stack pointer */
442:
443: lwz %r0,4(%r1) /* get saved msr from abused slot */
444: mtmsr %r0
445:
446: lwz %r1,0(%r1) /* return */
447: lwz %r0,4(%r1)
448: mtlr %r0
449: blr
450:
CVSweb