ofw_subr.S revision 1.8.36.1 1 1.8.36.1 cherry /* $NetBSD: ofw_subr.S,v 1.8.36.1 2011/06/23 14:19:32 cherry Exp $ */
2 1.1 matt
3 1.1 matt /*
4 1.1 matt * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 1.1 matt * Copyright (C) 1995, 1996 TooLs GmbH.
6 1.1 matt * All rights reserved.
7 1.1 matt *
8 1.1 matt * Redistribution and use in source and binary forms, with or without
9 1.1 matt * modification, are permitted provided that the following conditions
10 1.1 matt * are met:
11 1.1 matt * 1. Redistributions of source code must retain the above copyright
12 1.1 matt * notice, this list of conditions and the following disclaimer.
13 1.1 matt * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 matt * notice, this list of conditions and the following disclaimer in the
15 1.1 matt * documentation and/or other materials provided with the distribution.
16 1.1 matt * 3. All advertising materials mentioning features or use of this software
17 1.1 matt * must display the following acknowledgement:
18 1.1 matt * This product includes software developed by TooLs GmbH.
19 1.1 matt * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 1.1 matt * derived from this software without specific prior written permission.
21 1.1 matt *
22 1.1 matt * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 1.1 matt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 1.1 matt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 1.1 matt * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 1.1 matt * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 1.1 matt * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 1.1 matt * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 1.1 matt * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 1.1 matt * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 1.1 matt * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.1 matt */
33 1.1 matt
34 1.1 matt
35 1.1 matt .local firmstk
36 1.3 sanjayl .globl openfirmware_entry
37 1.1 matt .local ofwsrsave
38 1.1 matt .local OF_buffer
39 1.1 matt
40 1.8.36.1 cherry .lcomm firmstk,NBPG,16
41 1.8.36.1 cherry .lcomm OF_buffer,NBPG,4
42 1.1 matt .comm openfirmware_entry,4,4 /* openfirmware entry point */
43 1.8.36.1 cherry .lcomm ofwsrsave,64,4 /* openfirmware SR savearea */
44 1.8.36.1 cherry .lcomm ofwmsr,20,4 /* msr & sprg[0-3] used in OF */
45 1.8.36.1 cherry .comm ofwreal_incharge,4,4
46 1.1 matt
47 1.1 matt /*
48 1.1 matt * Called by start to save the initial OFW state so we can restore it
49 1.1 matt * when call back to OFW.
50 1.1 matt */
51 1.1 matt ENTRY_NOPROFILE(ofwinit)
52 1.1 matt #ifdef FIRMWORKSBUGS
53 1.7 garbled mfmsr %r0
54 1.7 garbled andi. %r0,%r0,PSL_IR|PSL_DR
55 1.1 matt beq 1f
56 1.1 matt
57 1.7 garbled li %r8,1
58 1.7 garbled lis %r9,ofwreal_incharge@ha
59 1.8.36.1 cherry stw %r8,ofwreal_incharge@l(%r9)
60 1.4 aymeric
61 1.7 garbled mflr %r30
62 1.1 matt bl _C_LABEL(ofwr_init)
63 1.7 garbled mtlr %r30
64 1.1 matt 1:
65 1.1 matt #endif
66 1.7 garbled lis %r8,openfirmware_entry@ha
67 1.7 garbled stw %r5,openfirmware_entry@l(%r8) /* save client interface handler*/
68 1.1 matt
69 1.7 garbled mfmsr %r0
70 1.8.36.1 cherry li %r8,PSL_IP
71 1.8.36.1 cherry andc %r0,%r0,%r8 /* make sure PSL_IP is off */
72 1.8.36.1 cherry lis %r9,ofwmsr@ha
73 1.8.36.1 cherry stwu %r0,ofwmsr@l(%r9) /* save initial MSR value */
74 1.8.36.1 cherry
75 1.8.36.1 cherry mfsprg0 %r0 /* save SPRGs */
76 1.8.36.1 cherry stw %r0,4(%r9)
77 1.8.36.1 cherry mfsprg1 %r0
78 1.8.36.1 cherry stw %r0,8(%r9)
79 1.8.36.1 cherry mfsprg2 %r0
80 1.8.36.1 cherry stw %r0,12(%r9)
81 1.8.36.1 cherry mfsprg3 %r0
82 1.8.36.1 cherry stw %r0,16(%r9)
83 1.7 garbled
84 1.7 garbled lis %r8,OF_buffer@ha
85 1.7 garbled addi %r8,%r8,OF_buffer@l
86 1.7 garbled lis %r9,_C_LABEL(OF_buf)@ha
87 1.7 garbled stw %r8,_C_LABEL(OF_buf)@l(%r9)
88 1.1 matt
89 1.1 matt blr
90 1.1 matt
91 1.1 matt /*
92 1.1 matt * OpenFirmware entry point
93 1.1 matt */
94 1.1 matt .text
95 1.1 matt ENTRY(openfirmware)
96 1.7 garbled mflr %r0 /* save return address */
97 1.7 garbled stw %r0,4(%r1)
98 1.8.36.1 cherry stwu %r1,-32(%r1) /* setup stack frame */
99 1.7 garbled
100 1.7 garbled lis %r4,openfirmware_entry@ha /* get firmware entry point */
101 1.7 garbled lwz %r4,openfirmware_entry@l(%r4)
102 1.7 garbled mtlr %r4
103 1.7 garbled
104 1.8.36.1 cherry mfsprg0 %r5 /* save current sprg0 (curcpu) */
105 1.8.36.1 cherry stw %r5,16(%r1)
106 1.8.36.1 cherry mfsprg1 %r5 /* save current sprg1 */
107 1.8.36.1 cherry stw %r5,20(%r1)
108 1.8.36.1 cherry mfsprg2 %r5 /* save current sprg1 */
109 1.8.36.1 cherry stw %r5,24(%r1)
110 1.8.36.1 cherry mfsprg3 %r5 /* save current sprg3 */
111 1.8.36.1 cherry stw %r5,28(%r1)
112 1.4 aymeric
113 1.4 aymeric #ifdef FIRMWORKSBUGS
114 1.7 garbled lis %r4,ofwreal_incharge@ha
115 1.7 garbled lwz %r4,ofwreal_incharge@l(%r4)
116 1.7 garbled cmpwi %r4,1
117 1.4 aymeric bne 1f
118 1.4 aymeric blrl
119 1.6 garbled b 4f
120 1.4 aymeric 1:
121 1.6 garbled #endif
122 1.7 garbled mfmsr %r4 /* save msr */
123 1.7 garbled stw %r4,8(%r1)
124 1.4 aymeric
125 1.7 garbled li %r0,0 /* clear battable translations */
126 1.8 garbled mtmsr %r0
127 1.6 garbled #if defined (PPC_OEA) || defined (PPC_OEA64_BRIDGE)
128 1.7 garbled mtdbatu 2,%r0
129 1.7 garbled mtdbatu 3,%r0
130 1.7 garbled mtibatu 2,%r0
131 1.7 garbled mtibatu 3,%r0
132 1.3 sanjayl #endif /* PPC_OEA */
133 1.1 matt
134 1.7 garbled lis %r4,ofwsrsave@ha /* save current SRs */
135 1.7 garbled addi %r4,%r4,ofwsrsave@l
136 1.7 garbled li %r5,0
137 1.7 garbled 1: mfsrin %r0,%r5
138 1.7 garbled stw %r0,0(%r4)
139 1.7 garbled addi %r4,%r4,4
140 1.7 garbled addis %r5,%r5,0x10000000@h
141 1.7 garbled cmpwi %r5,0
142 1.1 matt bne 1b
143 1.1 matt
144 1.7 garbled lis %r4,_C_LABEL(ofw_pmap)@ha /* load OFW SR */
145 1.7 garbled addi %r4,%r4,_C_LABEL(ofw_pmap)@l
146 1.7 garbled lwz %r0,PM_KERNELSR(%r4)
147 1.7 garbled cmpwi %r0,0 /* pm_sr[KERNEL_SR] == 0? */
148 1.1 matt beq 2f /* then skip (not initialized yet) */
149 1.7 garbled li %r5,0
150 1.7 garbled 1: lwz %r0,0(%r4)
151 1.7 garbled mtsrin %r0,%r5
152 1.7 garbled addi %r4,%r4,4
153 1.7 garbled addis %r5,%r5,0x10000000@h
154 1.7 garbled cmpwi %r5,0
155 1.1 matt bne 1b
156 1.1 matt 2:
157 1.8.36.1 cherry lis %r4,ofwmsr+16@ha /* Open Firmware msr + sprg[0-3] */
158 1.8.36.1 cherry lwzu %r5,ofwmsr+16@l(%r4)
159 1.8.36.1 cherry mtsprg3 %r5
160 1.7 garbled lwz %r5,-4(%r4)
161 1.8.36.1 cherry mtsprg2 %r5
162 1.8.36.1 cherry lwz %r5,-8(%r4)
163 1.8.36.1 cherry mtsprg1 %r5
164 1.8.36.1 cherry lwz %r5,-12(%r4)
165 1.8.36.1 cherry mtsprg0 %r5
166 1.8.36.1 cherry lwz %r5,-16(%r4)
167 1.7 garbled mtmsr %r5
168 1.1 matt isync
169 1.1 matt
170 1.1 matt blrl /* call Open Firmware */
171 1.1 matt
172 1.7 garbled lis %r4,ofwsrsave@ha /* restore saved SRs */
173 1.7 garbled addi %r4,%r4,ofwsrsave@l
174 1.7 garbled li %r5,0
175 1.7 garbled 1: lwz %r0,0(%r4)
176 1.7 garbled mtsrin %r0,%r5
177 1.7 garbled addi %r4,%r4,4
178 1.7 garbled addis %r5,%r5,0x10000000@h
179 1.7 garbled cmpwi %r5,0
180 1.1 matt bne 1b
181 1.1 matt
182 1.7 garbled lwz %r4,8(%r1) /* restore msr */
183 1.7 garbled mtmsr %r4
184 1.1 matt isync
185 1.6 garbled 4:
186 1.8.36.1 cherry lwz %r5,16(%r1) /* restore saved sprgs (curcpu) */
187 1.8.36.1 cherry mtsprg0 %r5
188 1.8.36.1 cherry lwz %r5,20(%r1)
189 1.8.36.1 cherry mtsprg1 %r5
190 1.8.36.1 cherry lwz %r5,24(%r1)
191 1.8.36.1 cherry mtsprg2 %r5
192 1.8.36.1 cherry lwz %r5,28(%r1)
193 1.8.36.1 cherry mtsprg3 %r5
194 1.7 garbled
195 1.7 garbled lwz %r1,0(%r1) /* and return */
196 1.7 garbled lwz %r0,4(%r1)
197 1.7 garbled mtlr %r0
198 1.1 matt blr
199 1.1 matt
200 1.1 matt /*
201 1.1 matt * Switch to/from OpenFirmware real mode stack
202 1.1 matt *
203 1.1 matt * Note: has to be called as the very first thing in OpenFirmware interface
204 1.1 matt * routines.
205 1.1 matt * E.g.:
206 1.1 matt * int
207 1.1 matt * OF_xxx(arg1, arg2)
208 1.1 matt * type arg1, arg2;
209 1.1 matt * {
210 1.1 matt * static struct {
211 1.1 matt * char *name;
212 1.1 matt * int nargs;
213 1.1 matt * int nreturns;
214 1.1 matt * char *method;
215 1.1 matt * int arg1;
216 1.1 matt * int arg2;
217 1.1 matt * int ret;
218 1.1 matt * } args = {
219 1.1 matt * "xxx",
220 1.1 matt * 2,
221 1.1 matt * 1,
222 1.1 matt * };
223 1.1 matt *
224 1.1 matt * ofw_stack();
225 1.1 matt * args.arg1 = arg1;
226 1.1 matt * args.arg2 = arg2;
227 1.1 matt * if (openfirmware(&args) < 0)
228 1.1 matt * return -1;
229 1.1 matt * return args.ret;
230 1.1 matt * }
231 1.1 matt */
232 1.1 matt
233 1.1 matt ENTRY(ofw_stack)
234 1.7 garbled mfmsr %r8 /* turn off interrupts */
235 1.7 garbled andi. %r0,%r8,~(PSL_EE|PSL_RI)@l
236 1.7 garbled mtmsr %r0
237 1.7 garbled stw %r8,4(%r1) /* abuse return address slot */
238 1.7 garbled
239 1.7 garbled lwz %r5,0(%r1) /* get length of stack frame */
240 1.7 garbled subf %r5,%r1,%r5
241 1.7 garbled
242 1.7 garbled lis %r7,firmstk+NBPG-8@ha
243 1.7 garbled addi %r7,%r7,firmstk+NBPG-8@l
244 1.7 garbled lis %r6,ofw_back@ha
245 1.7 garbled addi %r6,%r6,ofw_back@l
246 1.7 garbled subf %r4,%r5,%r7 /* make room for stack frame on
247 1.1 matt new stack */
248 1.7 garbled stw %r6,-4(%r7) /* setup return pointer */
249 1.7 garbled stwu %r1,-8(%r7)
250 1.1 matt
251 1.7 garbled stw %r7,-8(%r4)
252 1.1 matt
253 1.7 garbled addi %r3,%r1,8
254 1.7 garbled addi %r1,%r4,-8
255 1.7 garbled subi %r5,%r5,8
256 1.1 matt
257 1.1 matt b _C_LABEL(ofbcopy) /* and copy it */
258 1.1 matt
259 1.1 matt ofw_back:
260 1.7 garbled lwz %r1,0(%r1) /* get callers original stack pointer */
261 1.1 matt
262 1.7 garbled lwz %r0,4(%r1) /* get saved msr from abused slot */
263 1.7 garbled mtmsr %r0
264 1.1 matt
265 1.7 garbled lwz %r1,0(%r1) /* return */
266 1.7 garbled lwz %r0,4(%r1)
267 1.7 garbled mtlr %r0
268 1.1 matt blr
269