ofw_subr.S revision 1.2 1 1.2 matt /* $NetBSD: ofw_subr.S,v 1.2 2003/02/13 15:02:49 matt 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.1 matt .local 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.1 matt mtdbatu 2,0
108 1.1 matt mtdbatu 3,0
109 1.1 matt mtibatu 2,0
110 1.1 matt mtibatu 3,0
111 1.1 matt
112 1.1 matt lis 4,ofwsrsave@ha /* save current SRs */
113 1.1 matt addi 4,4,ofwsrsave@l
114 1.1 matt li 5,0
115 1.1 matt 1: mfsrin 0,5
116 1.1 matt stw 0,0(4)
117 1.1 matt addi 4,4,4
118 1.1 matt addis 5,5,0x10000000@h
119 1.1 matt cmpwi 5,0
120 1.1 matt bne 1b
121 1.1 matt
122 1.1 matt mfsprg 5,0 /* save current sprg0 (curcpu) */
123 1.1 matt lis 4,ofwsprg0save@ha
124 1.1 matt addi 4,4,ofwsprg0save@l
125 1.1 matt stw 5,0(4)
126 1.1 matt
127 1.1 matt lis 4,_C_LABEL(ofw_pmap)@ha /* load OFW SR */
128 1.1 matt addi 4,4,_C_LABEL(ofw_pmap)@l
129 1.1 matt lwz 0,PM_KERNELSR(4)
130 1.1 matt cmpwi 0,0 /* pm_sr[KERNEL_SR] == 0? */
131 1.1 matt beq 2f /* then skip (not initialized yet) */
132 1.1 matt li 5,0
133 1.1 matt 1: lwz 0,0(4)
134 1.1 matt mtsrin 0,5
135 1.1 matt addi 4,4,4
136 1.1 matt addis 5,5,0x10000000@h
137 1.1 matt cmpwi 5,0
138 1.1 matt bne 1b
139 1.1 matt 2:
140 1.1 matt lis 4,ofmsr@ha /* Open Firmware msr + sprg[0-3] */
141 1.1 matt lwzu 5,ofmsr+16@l(4)
142 1.1 matt mtsprg 3,5
143 1.1 matt lwzu 5,-4(4)
144 1.1 matt mtsprg 2,5
145 1.1 matt lwzu 5,-4(4)
146 1.1 matt mtsprg 1,5
147 1.1 matt lwzu 5,-4(4)
148 1.1 matt mtsprg 0,5
149 1.1 matt lwz 5,-4(4)
150 1.1 matt mtmsr 5
151 1.1 matt isync
152 1.1 matt
153 1.1 matt blrl /* call Open Firmware */
154 1.1 matt
155 1.1 matt lis 4,ofwsprg0save@ha /* restore saved sprg0 (curcpu) */
156 1.1 matt addi 4,4,ofwsprg0save@l
157 1.1 matt lwz 5,0(4)
158 1.1 matt mtsprg 0,5
159 1.1 matt
160 1.1 matt lis 4,ofwsrsave@ha /* restore saved SRs */
161 1.1 matt addi 4,4,ofwsrsave@l
162 1.1 matt li 5,0
163 1.1 matt 1: lwz 0,0(4)
164 1.1 matt mtsrin 0,5
165 1.1 matt addi 4,4,4
166 1.1 matt addis 5,5,0x10000000@h
167 1.1 matt cmpwi 5,0
168 1.1 matt bne 1b
169 1.1 matt
170 1.1 matt lwz 4,8(1) /* restore msr */
171 1.1 matt mtmsr 4
172 1.1 matt isync
173 1.1 matt
174 1.1 matt lwz 1,0(1) /* and return */
175 1.1 matt lwz 0,4(1)
176 1.1 matt mtlr 0
177 1.1 matt blr
178 1.1 matt
179 1.1 matt /*
180 1.1 matt * Switch to/from OpenFirmware real mode stack
181 1.1 matt *
182 1.1 matt * Note: has to be called as the very first thing in OpenFirmware interface
183 1.1 matt * routines.
184 1.1 matt * E.g.:
185 1.1 matt * int
186 1.1 matt * OF_xxx(arg1, arg2)
187 1.1 matt * type arg1, arg2;
188 1.1 matt * {
189 1.1 matt * static struct {
190 1.1 matt * char *name;
191 1.1 matt * int nargs;
192 1.1 matt * int nreturns;
193 1.1 matt * char *method;
194 1.1 matt * int arg1;
195 1.1 matt * int arg2;
196 1.1 matt * int ret;
197 1.1 matt * } args = {
198 1.1 matt * "xxx",
199 1.1 matt * 2,
200 1.1 matt * 1,
201 1.1 matt * };
202 1.1 matt *
203 1.1 matt * ofw_stack();
204 1.1 matt * args.arg1 = arg1;
205 1.1 matt * args.arg2 = arg2;
206 1.1 matt * if (openfirmware(&args) < 0)
207 1.1 matt * return -1;
208 1.1 matt * return args.ret;
209 1.1 matt * }
210 1.1 matt */
211 1.1 matt
212 1.1 matt ENTRY(ofw_stack)
213 1.1 matt mfmsr 8 /* turn off interrupts */
214 1.1 matt andi. 0,8,~(PSL_EE|PSL_RI)@l
215 1.1 matt mtmsr 0
216 1.1 matt stw 8,4(1) /* abuse return address slot */
217 1.1 matt
218 1.1 matt lwz 5,0(1) /* get length of stack frame */
219 1.1 matt subf 5,1,5
220 1.1 matt
221 1.1 matt lis 7,firmstk+NBPG-8@ha
222 1.1 matt addi 7,7,firmstk+NBPG-8@l
223 1.1 matt lis 6,ofw_back@ha
224 1.1 matt addi 6,6,ofw_back@l
225 1.1 matt subf 4,5,7 /* make room for stack frame on
226 1.1 matt new stack */
227 1.1 matt stw 6,-4(7) /* setup return pointer */
228 1.1 matt stwu 1,-8(7)
229 1.1 matt
230 1.1 matt stw 7,-8(4)
231 1.1 matt
232 1.1 matt addi 3,1,8
233 1.1 matt addi 1,4,-8
234 1.1 matt subi 5,5,8
235 1.1 matt
236 1.1 matt b _C_LABEL(ofbcopy) /* and copy it */
237 1.1 matt
238 1.1 matt ofw_back:
239 1.1 matt lwz 1,0(1) /* get callers original stack pointer */
240 1.1 matt
241 1.1 matt lwz 0,4(1) /* get saved msr from abused slot */
242 1.1 matt mtmsr 0
243 1.1 matt
244 1.1 matt lwz 1,0(1) /* return */
245 1.1 matt lwz 0,4(1)
246 1.1 matt mtlr 0
247 1.1 matt blr
248