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