ofw_subr.S revision 1.15 1 1.15 thorpej /* $NetBSD: ofw_subr.S,v 1.15 2021/02/18 18:31:22 thorpej 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.12 rin #ifdef _KERNEL_OPT
35 1.12 rin #include "opt_ppcarch.h"
36 1.12 rin #endif
37 1.1 matt
38 1.14 thorpej /* Stack used to call into OpenFirmware. */
39 1.14 thorpej .lcomm firmstk,NBPG,16
40 1.1 matt
41 1.14 thorpej /* Buffer used to pass data to/from OpenFirmware. */
42 1.11 macallan .lcomm OF_buffer,NBPG + 36,4
43 1.14 thorpej
44 1.14 thorpej /* The OpenFirmware entry point, provided by OpenFirmware. */
45 1.14 thorpej .lcomm ofentry,4,4
46 1.14 thorpej
47 1.14 thorpej /* Entry trampoline used by openfirmware(). */
48 1.14 thorpej .lcomm oftramp,4,4
49 1.14 thorpej
50 1.14 thorpej /* OpenFirmware SR save area */
51 1.14 thorpej .lcomm ofwsrsave,64,4
52 1.14 thorpej
53 1.14 thorpej /* MSR and SPRG[0-3] used in OpenFirmware */
54 1.14 thorpej .globl ofwmsr
55 1.14 thorpej .comm ofwmsr,20,4
56 1.1 matt
57 1.1 matt /*
58 1.1 matt * Called by start to save the initial OFW state so we can restore it
59 1.1 matt * when call back to OFW.
60 1.14 thorpej *
61 1.14 thorpej * We expect the registers to be as for the entry point into the kernel:
62 1.14 thorpej *
63 1.14 thorpej * %r1 Stack provided by OpenFirmware / boot loader
64 1.14 thorpej * %r5 OpenFirmware client entry point
65 1.14 thorpej *
66 1.14 thorpej * (others -- don't care)
67 1.1 matt */
68 1.1 matt ENTRY_NOPROFILE(ofwinit)
69 1.14 thorpej /* Save return address, Push a stack frame. */
70 1.14 thorpej mflr %r0
71 1.14 thorpej stw %r0,4(%r1)
72 1.14 thorpej stwu %r1,-16(%r1)
73 1.14 thorpej
74 1.14 thorpej #ifdef FIRMWORKSBUGS
75 1.7 garbled mfmsr %r0
76 1.7 garbled andi. %r0,%r0,PSL_IR|PSL_DR
77 1.1 matt beq 1f
78 1.1 matt
79 1.7 garbled li %r8,1
80 1.7 garbled lis %r9,ofwreal_incharge@ha
81 1.9 matt stw %r8,ofwreal_incharge@l(%r9)
82 1.4 aymeric
83 1.1 matt bl _C_LABEL(ofwr_init)
84 1.1 matt 1:
85 1.1 matt #endif
86 1.1 matt
87 1.14 thorpej lis %r8,ofentry@ha
88 1.14 thorpej stw %r5,ofentry@l(%r8) /* save client interface handler */
89 1.14 thorpej
90 1.14 thorpej /*
91 1.14 thorpej * Call directly into OpenFirmware until we're ready to use
92 1.14 thorpej * the trampoline.
93 1.14 thorpej */
94 1.14 thorpej lis %r8,oftramp@ha
95 1.14 thorpej stw %r5,oftramp@l(%r8)
96 1.14 thorpej
97 1.14 thorpej /* Save the MSR that OpenFirmware is using. */
98 1.7 garbled mfmsr %r0
99 1.9 matt lis %r9,ofwmsr@ha
100 1.14 thorpej stwu %r0,ofwmsr@l(%r9)
101 1.9 matt
102 1.9 matt mfsprg0 %r0 /* save SPRGs */
103 1.9 matt stw %r0,4(%r9)
104 1.9 matt mfsprg1 %r0
105 1.9 matt stw %r0,8(%r9)
106 1.9 matt mfsprg2 %r0
107 1.9 matt stw %r0,12(%r9)
108 1.9 matt mfsprg3 %r0
109 1.9 matt stw %r0,16(%r9)
110 1.7 garbled
111 1.7 garbled lis %r8,OF_buffer@ha
112 1.7 garbled addi %r8,%r8,OF_buffer@l
113 1.7 garbled lis %r9,_C_LABEL(OF_buf)@ha
114 1.7 garbled stw %r8,_C_LABEL(OF_buf)@l(%r9)
115 1.1 matt
116 1.15 thorpej /*
117 1.15 thorpej * Call into C code to perform additional early initialization.
118 1.15 thorpej */
119 1.15 thorpej lis %r8,_C_LABEL(ofw_bootstrap)@ha
120 1.15 thorpej addi %r8,%r8,_C_LABEL(ofw_bootstrap)@l
121 1.15 thorpej mtctr %r8
122 1.15 thorpej bctrl
123 1.14 thorpej
124 1.14 thorpej /*
125 1.14 thorpej * Jump off the trampoline for all subsequent calls
126 1.14 thorpej * into OpenFirmware.
127 1.14 thorpej */
128 1.14 thorpej lis %r5,_C_LABEL(openfirmware_trampoline)@ha
129 1.14 thorpej addi %r5,%r5,_C_LABEL(openfirmware_trampoline)@l
130 1.14 thorpej lis %r8,oftramp@ha
131 1.14 thorpej stw %r5,oftramp@l(%r8)
132 1.14 thorpej
133 1.14 thorpej /* Retrieve LR, pop stack frame. */
134 1.14 thorpej addi %r1,%r1,16
135 1.14 thorpej lwz %r0,4(%r1)
136 1.14 thorpej mtlr %r0
137 1.14 thorpej
138 1.1 matt blr
139 1.1 matt
140 1.1 matt /*
141 1.14 thorpej * OpenFirmware trampoline. We are already on the OpenFirmware stack.
142 1.1 matt */
143 1.14 thorpej ENTRY_NOPROFILE(openfirmware_trampoline)
144 1.13 thorpej mflr %r0
145 1.13 thorpej stw %r0,4(%r1) /* save return address */
146 1.13 thorpej
147 1.13 thorpej /*
148 1.14 thorpej * Push stack frame and save area:
149 1.13 thorpej *
150 1.14 thorpej * [SP+8 save area]
151 1.14 thorpej * [SP+4 slot for saved LR in callee]
152 1.14 thorpej * [SP+0 saved SP]
153 1.13 thorpej */
154 1.14 thorpej stwu %r1,-48(%r1)
155 1.7 garbled
156 1.14 thorpej lis %r4,ofentry@ha /* get firmware entry point */
157 1.14 thorpej lwz %r4,ofentry@l(%r4)
158 1.7 garbled mtlr %r4
159 1.7 garbled
160 1.9 matt mfsprg0 %r5 /* save current sprg0 (curcpu) */
161 1.9 matt stw %r5,16(%r1)
162 1.9 matt mfsprg1 %r5 /* save current sprg1 */
163 1.9 matt stw %r5,20(%r1)
164 1.9 matt mfsprg2 %r5 /* save current sprg1 */
165 1.9 matt stw %r5,24(%r1)
166 1.9 matt mfsprg3 %r5 /* save current sprg3 */
167 1.9 matt stw %r5,28(%r1)
168 1.4 aymeric
169 1.4 aymeric #ifdef FIRMWORKSBUGS
170 1.7 garbled lis %r4,ofwreal_incharge@ha
171 1.7 garbled lwz %r4,ofwreal_incharge@l(%r4)
172 1.7 garbled cmpwi %r4,1
173 1.4 aymeric bne 1f
174 1.4 aymeric blrl
175 1.6 garbled b 4f
176 1.4 aymeric 1:
177 1.6 garbled #endif
178 1.7 garbled mfmsr %r4 /* save msr */
179 1.7 garbled stw %r4,8(%r1)
180 1.4 aymeric
181 1.7 garbled li %r0,0 /* clear battable translations */
182 1.8 garbled mtmsr %r0
183 1.6 garbled #if defined (PPC_OEA) || defined (PPC_OEA64_BRIDGE)
184 1.7 garbled mtdbatu 2,%r0
185 1.7 garbled mtdbatu 3,%r0
186 1.7 garbled mtibatu 2,%r0
187 1.7 garbled mtibatu 3,%r0
188 1.3 sanjayl #endif /* PPC_OEA */
189 1.1 matt
190 1.7 garbled lis %r4,ofwsrsave@ha /* save current SRs */
191 1.7 garbled addi %r4,%r4,ofwsrsave@l
192 1.7 garbled li %r5,0
193 1.7 garbled 1: mfsrin %r0,%r5
194 1.7 garbled stw %r0,0(%r4)
195 1.7 garbled addi %r4,%r4,4
196 1.7 garbled addis %r5,%r5,0x10000000@h
197 1.7 garbled cmpwi %r5,0
198 1.1 matt bne 1b
199 1.1 matt
200 1.7 garbled lis %r4,_C_LABEL(ofw_pmap)@ha /* load OFW SR */
201 1.7 garbled addi %r4,%r4,_C_LABEL(ofw_pmap)@l
202 1.7 garbled lwz %r0,PM_KERNELSR(%r4)
203 1.7 garbled cmpwi %r0,0 /* pm_sr[KERNEL_SR] == 0? */
204 1.1 matt beq 2f /* then skip (not initialized yet) */
205 1.7 garbled li %r5,0
206 1.7 garbled 1: lwz %r0,0(%r4)
207 1.7 garbled mtsrin %r0,%r5
208 1.7 garbled addi %r4,%r4,4
209 1.7 garbled addis %r5,%r5,0x10000000@h
210 1.7 garbled cmpwi %r5,0
211 1.1 matt bne 1b
212 1.1 matt 2:
213 1.9 matt lis %r4,ofwmsr+16@ha /* Open Firmware msr + sprg[0-3] */
214 1.9 matt lwzu %r5,ofwmsr+16@l(%r4)
215 1.9 matt mtsprg3 %r5
216 1.7 garbled lwz %r5,-4(%r4)
217 1.9 matt mtsprg2 %r5
218 1.9 matt lwz %r5,-8(%r4)
219 1.9 matt mtsprg1 %r5
220 1.9 matt lwz %r5,-12(%r4)
221 1.9 matt mtsprg0 %r5
222 1.9 matt lwz %r5,-16(%r4)
223 1.7 garbled mtmsr %r5
224 1.1 matt isync
225 1.1 matt
226 1.1 matt blrl /* call Open Firmware */
227 1.1 matt
228 1.7 garbled lis %r4,ofwsrsave@ha /* restore saved SRs */
229 1.7 garbled addi %r4,%r4,ofwsrsave@l
230 1.7 garbled li %r5,0
231 1.7 garbled 1: lwz %r0,0(%r4)
232 1.7 garbled mtsrin %r0,%r5
233 1.7 garbled addi %r4,%r4,4
234 1.7 garbled addis %r5,%r5,0x10000000@h
235 1.7 garbled cmpwi %r5,0
236 1.1 matt bne 1b
237 1.1 matt
238 1.7 garbled lwz %r4,8(%r1) /* restore msr */
239 1.7 garbled mtmsr %r4
240 1.1 matt isync
241 1.6 garbled 4:
242 1.9 matt lwz %r5,16(%r1) /* restore saved sprgs (curcpu) */
243 1.9 matt mtsprg0 %r5
244 1.9 matt lwz %r5,20(%r1)
245 1.9 matt mtsprg1 %r5
246 1.9 matt lwz %r5,24(%r1)
247 1.9 matt mtsprg2 %r5
248 1.9 matt lwz %r5,28(%r1)
249 1.9 matt mtsprg3 %r5
250 1.7 garbled
251 1.14 thorpej addi %r1,%r1,48 /* pop stack frame and save area */
252 1.14 thorpej lwz %r0,4(%r1) /* return address */
253 1.14 thorpej mtlr %r0
254 1.14 thorpej blr
255 1.14 thorpej
256 1.14 thorpej /*
257 1.14 thorpej * Call into OpenFirmware.
258 1.14 thorpej */
259 1.14 thorpej ENTRY_NOPROFILE(openfirmware)
260 1.14 thorpej mflr %r0
261 1.14 thorpej stw %r0,4(%r1) /* save return address */
262 1.14 thorpej
263 1.14 thorpej /* Switch to OpenFirmware stack. */
264 1.14 thorpej lis %r7,firmstk+NBPG-16@ha
265 1.14 thorpej addi %r7,%r7,firmstk+NBPG-16@l
266 1.14 thorpej stw %r1,0(%r7) /* stash away prev stack pointer */
267 1.14 thorpej mr %r1,%r7
268 1.14 thorpej
269 1.14 thorpej lis %r4,oftramp@ha
270 1.14 thorpej lwz %r4,oftramp@l(%r4)
271 1.14 thorpej
272 1.14 thorpej mtctr %r4
273 1.14 thorpej bctrl
274 1.14 thorpej
275 1.14 thorpej lwz %r1,0(%r1) /* restore previous stack pointer */
276 1.13 thorpej lwz %r0,4(%r1) /* return address */
277 1.7 garbled mtlr %r0
278 1.1 matt blr
279