ofw_subr.S revision 1.1 1 /* $NetBSD: ofw_subr.S,v 1.1 2003/02/03 17:10:10 matt 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
35 .local firmstk
36 .local openfirmware_entry
37 .local ofwsrsave
38 .local OF_buffer
39
40 .data
41 GLOBAL(ofmsr)
42 .long 0,0,0,0,0 /* msr & sprg[0-3] used in OF */
43
44 GLOBAL(ofwsprg0save)
45 .long 0
46
47 .comm firmstk,NBPG,8
48 .comm OF_buffer,NBPG,4
49 .comm openfirmware_entry,4,4 /* openfirmware entry point */
50 .comm ofwsrsave,64,4 /* openfirmware SR savearea */
51
52 /*
53 * Called by start to save the initial OFW state so we can restore it
54 * when call back to OFW.
55 */
56 ENTRY_NOPROFILE(ofwinit)
57 #ifdef FIRMWORKSBUGS
58 mfmsr 0
59 andi. 0,0,PSL_IR|PSL_DR
60 beq 1f
61
62 mflr 30
63 bl _C_LABEL(ofwr_init)
64 mtlr 30
65 1:
66 #endif
67 lis 8,openfirmware_entry@ha
68 stw 5,openfirmware_entry@l(8) /* save client interface handler*/
69
70 mfmsr 0
71 lis 9,ofmsr@ha
72 stwu 0,ofmsr@l(9) /* save initial MSR value */
73
74 mfsprg 0,0 /* save SPRGs */
75 stwu 0,4(9)
76 mfsprg 0,1
77 stwu 0,4(9)
78 mfsprg 0,2
79 stwu 0,4(9)
80 mfsprg 0,3
81 stw 0,4(9)
82
83 lis 0,OF_buffer@ha
84 addi 0,0,OF_buffer@l
85 lis 9,_C_LABEL(OF_buf)@ha
86 stw 0,_C_LABEL(OF_buf)@l(9)
87
88 blr
89
90 /*
91 * OpenFirmware entry point
92 */
93 .text
94 ENTRY(openfirmware)
95 mflr 0 /* save return address */
96 stw 0,4(1)
97 stwu 1,-16(1) /* setup stack frame */
98
99 mfmsr 4 /* save msr */
100 stw 4,8(1)
101
102 lis 4,openfirmware_entry@ha /* get firmware entry point */
103 lwz 4,openfirmware_entry@l(4)
104 mtlr 4
105
106 li 0,0 /* clear battable translations */
107 mtdbatu 2,0
108 mtdbatu 3,0
109 mtibatu 2,0
110 mtibatu 3,0
111
112 lis 4,ofwsrsave@ha /* save current SRs */
113 addi 4,4,ofwsrsave@l
114 li 5,0
115 1: mfsrin 0,5
116 stw 0,0(4)
117 addi 4,4,4
118 addis 5,5,0x10000000@h
119 cmpwi 5,0
120 bne 1b
121
122 mfsprg 5,0 /* save current sprg0 (curcpu) */
123 lis 4,ofwsprg0save@ha
124 addi 4,4,ofwsprg0save@l
125 stw 5,0(4)
126
127 lis 4,_C_LABEL(ofw_pmap)@ha /* load OFW SR */
128 addi 4,4,_C_LABEL(ofw_pmap)@l
129 lwz 0,PM_KERNELSR(4)
130 cmpwi 0,0 /* pm_sr[KERNEL_SR] == 0? */
131 beq 2f /* then skip (not initialized yet) */
132 li 5,0
133 1: lwz 0,0(4)
134 mtsrin 0,5
135 addi 4,4,4
136 addis 5,5,0x10000000@h
137 cmpwi 5,0
138 bne 1b
139 2:
140 lis 4,ofmsr@ha /* Open Firmware msr + sprg[0-3] */
141 lwzu 5,ofmsr+16@l(4)
142 mtsprg 3,5
143 lwzu 5,-4(4)
144 mtsprg 2,5
145 lwzu 5,-4(4)
146 mtsprg 1,5
147 lwzu 5,-4(4)
148 mtsprg 0,5
149 lwz 5,-4(4)
150 mtmsr 5
151 isync
152
153 blrl /* call Open Firmware */
154
155 lis 4,ofwsprg0save@ha /* restore saved sprg0 (curcpu) */
156 addi 4,4,ofwsprg0save@l
157 lwz 5,0(4)
158 mtsprg 0,5
159
160 lis 4,ofwsrsave@ha /* restore saved SRs */
161 addi 4,4,ofwsrsave@l
162 li 5,0
163 1: lwz 0,0(4)
164 mtsrin 0,5
165 addi 4,4,4
166 addis 5,5,0x10000000@h
167 cmpwi 5,0
168 bne 1b
169
170 lwz 4,8(1) /* restore msr */
171 mtmsr 4
172 isync
173
174 lwz 1,0(1) /* and return */
175 lwz 0,4(1)
176 mtlr 0
177 blr
178
179 /*
180 * Switch to/from OpenFirmware real mode stack
181 *
182 * Note: has to be called as the very first thing in OpenFirmware interface
183 * routines.
184 * E.g.:
185 * int
186 * OF_xxx(arg1, arg2)
187 * type arg1, arg2;
188 * {
189 * static struct {
190 * char *name;
191 * int nargs;
192 * int nreturns;
193 * char *method;
194 * int arg1;
195 * int arg2;
196 * int ret;
197 * } args = {
198 * "xxx",
199 * 2,
200 * 1,
201 * };
202 *
203 * ofw_stack();
204 * args.arg1 = arg1;
205 * args.arg2 = arg2;
206 * if (openfirmware(&args) < 0)
207 * return -1;
208 * return args.ret;
209 * }
210 */
211
212 ENTRY(ofw_stack)
213 mfmsr 8 /* turn off interrupts */
214 andi. 0,8,~(PSL_EE|PSL_RI)@l
215 mtmsr 0
216 stw 8,4(1) /* abuse return address slot */
217
218 lwz 5,0(1) /* get length of stack frame */
219 subf 5,1,5
220
221 lis 7,firmstk+NBPG-8@ha
222 addi 7,7,firmstk+NBPG-8@l
223 lis 6,ofw_back@ha
224 addi 6,6,ofw_back@l
225 subf 4,5,7 /* make room for stack frame on
226 new stack */
227 stw 6,-4(7) /* setup return pointer */
228 stwu 1,-8(7)
229
230 stw 7,-8(4)
231
232 addi 3,1,8
233 addi 1,4,-8
234 subi 5,5,8
235
236 b _C_LABEL(ofbcopy) /* and copy it */
237
238 ofw_back:
239 lwz 1,0(1) /* get callers original stack pointer */
240
241 lwz 0,4(1) /* get saved msr from abused slot */
242 mtmsr 0
243
244 lwz 1,0(1) /* return */
245 lwz 0,4(1)
246 mtlr 0
247 blr
248