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