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