ofw_subr.S revision 1.13 1 /* $NetBSD: ofw_subr.S,v 1.13 2021/02/13 01:48:33 thorpej Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifdef _KERNEL_OPT
35 #include "opt_ppcarch.h"
36 #endif
37
38 .local firmstk
39 .globl openfirmware_entry
40 .globl ofwmsr
41 .local ofwsrsave
42 .local OF_buffer
43
44 .lcomm firmstk,NBPG,16
45 .lcomm OF_buffer,NBPG + 36,4
46 .comm openfirmware_entry,4,4 /* openfirmware entry point */
47 .lcomm ofwsrsave,64,4 /* openfirmware SR savearea */
48 .comm ofwmsr,20,4 /* msr & sprg[0-3] used in OF */
49 .comm ofwreal_incharge,4,4
50
51 /*
52 * Called by start to save the initial OFW state so we can restore it
53 * when call back to OFW.
54 */
55 ENTRY_NOPROFILE(ofwinit)
56 #ifdef FIRMWORKSBUGS
57 mfmsr %r0
58 andi. %r0,%r0,PSL_IR|PSL_DR
59 beq 1f
60
61 li %r8,1
62 lis %r9,ofwreal_incharge@ha
63 stw %r8,ofwreal_incharge@l(%r9)
64
65 mflr %r30
66 bl _C_LABEL(ofwr_init)
67 mtlr %r30
68 1:
69 #endif
70 lis %r8,openfirmware_entry@ha
71 stw %r5,openfirmware_entry@l(%r8) /* save client interface handler*/
72
73 mfmsr %r0
74 /*
75 * XXX
76 * doing this here instead of later on in ofwoea_initppc() after setting
77 * up the console and such makes my PowerBook 3400c hang.
78 * Probably just another OF 2.0 weirdness
79 */
80 /*li %r8,PSL_IP*/
81 /*andc %r0,%r0,%r8*/ /* make sure PSL_IP is off */
82 lis %r9,ofwmsr@ha
83 stwu %r0,ofwmsr@l(%r9) /* save initial MSR value */
84
85 mfsprg0 %r0 /* save SPRGs */
86 stw %r0,4(%r9)
87 mfsprg1 %r0
88 stw %r0,8(%r9)
89 mfsprg2 %r0
90 stw %r0,12(%r9)
91 mfsprg3 %r0
92 stw %r0,16(%r9)
93
94 lis %r8,OF_buffer@ha
95 addi %r8,%r8,OF_buffer@l
96 lis %r9,_C_LABEL(OF_buf)@ha
97 stw %r8,_C_LABEL(OF_buf)@l(%r9)
98
99 blr
100
101 /*
102 * OpenFirmware entry point
103 */
104 .text
105 ENTRY(openfirmware)
106 mflr %r0
107 stw %r0,4(%r1) /* save return address */
108
109 /*
110 * Switch to OpenFirmware stack.
111 *
112 * -48 == -16 to stack old SP and align, -32 for save area
113 */
114 lis %r7,firmstk+NBPG-48@ha
115 addi %r7,%r7,firmstk+NBPG-48@l
116 stw %r1,32(%r7) /* stash away prev stack pointer */
117 mr %r1,%r7
118
119 lis %r4,openfirmware_entry@ha /* get firmware entry point */
120 lwz %r4,openfirmware_entry@l(%r4)
121 mtlr %r4
122
123 mfsprg0 %r5 /* save current sprg0 (curcpu) */
124 stw %r5,16(%r1)
125 mfsprg1 %r5 /* save current sprg1 */
126 stw %r5,20(%r1)
127 mfsprg2 %r5 /* save current sprg1 */
128 stw %r5,24(%r1)
129 mfsprg3 %r5 /* save current sprg3 */
130 stw %r5,28(%r1)
131
132 #ifdef FIRMWORKSBUGS
133 lis %r4,ofwreal_incharge@ha
134 lwz %r4,ofwreal_incharge@l(%r4)
135 cmpwi %r4,1
136 bne 1f
137 blrl
138 b 4f
139 1:
140 #endif
141 mfmsr %r4 /* save msr */
142 stw %r4,8(%r1)
143
144 li %r0,0 /* clear battable translations */
145 mtmsr %r0
146 #if defined (PPC_OEA) || defined (PPC_OEA64_BRIDGE)
147 mtdbatu 2,%r0
148 mtdbatu 3,%r0
149 mtibatu 2,%r0
150 mtibatu 3,%r0
151 #endif /* PPC_OEA */
152
153 lis %r4,ofwsrsave@ha /* save current SRs */
154 addi %r4,%r4,ofwsrsave@l
155 li %r5,0
156 1: mfsrin %r0,%r5
157 stw %r0,0(%r4)
158 addi %r4,%r4,4
159 addis %r5,%r5,0x10000000@h
160 cmpwi %r5,0
161 bne 1b
162
163 lis %r4,_C_LABEL(ofw_pmap)@ha /* load OFW SR */
164 addi %r4,%r4,_C_LABEL(ofw_pmap)@l
165 lwz %r0,PM_KERNELSR(%r4)
166 cmpwi %r0,0 /* pm_sr[KERNEL_SR] == 0? */
167 beq 2f /* then skip (not initialized yet) */
168 li %r5,0
169 1: lwz %r0,0(%r4)
170 mtsrin %r0,%r5
171 addi %r4,%r4,4
172 addis %r5,%r5,0x10000000@h
173 cmpwi %r5,0
174 bne 1b
175 2:
176 lis %r4,ofwmsr+16@ha /* Open Firmware msr + sprg[0-3] */
177 lwzu %r5,ofwmsr+16@l(%r4)
178 mtsprg3 %r5
179 lwz %r5,-4(%r4)
180 mtsprg2 %r5
181 lwz %r5,-8(%r4)
182 mtsprg1 %r5
183 lwz %r5,-12(%r4)
184 mtsprg0 %r5
185 lwz %r5,-16(%r4)
186 mtmsr %r5
187 isync
188
189 blrl /* call Open Firmware */
190
191 lis %r4,ofwsrsave@ha /* restore saved SRs */
192 addi %r4,%r4,ofwsrsave@l
193 li %r5,0
194 1: lwz %r0,0(%r4)
195 mtsrin %r0,%r5
196 addi %r4,%r4,4
197 addis %r5,%r5,0x10000000@h
198 cmpwi %r5,0
199 bne 1b
200
201 lwz %r4,8(%r1) /* restore msr */
202 mtmsr %r4
203 isync
204 4:
205 lwz %r5,16(%r1) /* restore saved sprgs (curcpu) */
206 mtsprg0 %r5
207 lwz %r5,20(%r1)
208 mtsprg1 %r5
209 lwz %r5,24(%r1)
210 mtsprg2 %r5
211 lwz %r5,28(%r1)
212 mtsprg3 %r5
213
214 lwz %r1,32(%r1) /* restore previous stack pointer */
215 lwz %r0,4(%r1) /* return address */
216 mtlr %r0
217 blr
218