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