1/* $OpenBSD: ofwreal.S,v 1.9 2022/12/08 01:25:45 guenther Exp $ */ 2/* $NetBSD: ofwreal.S,v 1.1 1996/09/30 16:34:51 ws Exp $ */ 3 4/* 5 * Copyright (C) 1996 Wolfgang Solfrank. 6 * Copyright (C) 1996 TooLs GmbH. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by TooLs GmbH. 20 * 4. The name of TooLs GmbH may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35/* 36 * This file provides a real-mode client interface on machines, that 37 * (incorrectly) only implement virtual mode client interface. 38 * 39 * It assumes though, that any actual memory in the machine is 40 * mapped 1:1 even by the virtual mode OpenFirmware. 41 * Furthermore it assumes that addresses returned by OpenFirmware are not 42 * accessed by the client. 43 * 44 */ 45#include <machine/asm.h> 46#include <machine/psl.h> 47#include <machine/trap.h> 48#include <machine/param.h> 49 50#define CACHELINE 32 /* Note that this value is really hardwired */ 51 52 .data 53ofentry: .long 0 /* actual entry to firmware in virtual mode */ 54 55#define SRSIZE (16*4+4) 56#define SPRGSIZE (4*4) 57#define SDR1SIZE 4 58#define MSRSIZE 4 59#define SVSIZE (SRSIZE+SPRGSIZE+SDR1SIZE+MSRSIZE) 60#define BATSIZE (16*4) 61 62 .global fwcall 63fwcall: .long 0 64 65.lcomm fwsave,SVSIZE,8 66.lcomm fwbatsave,BATSIZE,8 67.lcomm clsave,SVSIZE,8 68.lcomm clbatsave,BATSIZE,8 69.lcomm ofsrsave,16*4,4 /* 16 words of 4 bytes to store OF segment registers */ 70.lcomm srsave,16*4,4 /* 16 words of 4 bytes to swap OF segment registers*/ 71 .globl ofmsr 72ofmsr: .long 0 /* area to store msr for openfirmware*/ 73 74 .text 75_ENTRY(ofw_init) 76 mflr %r31 /* save return address */ 77 78 mr %r13,%r6 /* save args (only pointer used) */ 79 lis %r8,ofentry@ha 80 stw %r5,ofentry@l(%r8) /* save virtual mode firmware entry */ 81 82 lis %r4,fwcall@ha /* call ofw directly until vm setup */ 83 stw %r5,fwcall@l(%r4) 84 85 mfmsr %r5 86 lis %r4,ofmsr@ha /* save msr from openfirmware */ 87 stw %r5,ofmsr@l(%r4) 88#if 0 89 lis %r0,(0x80001ffe)@ha 90 addi %r0,%r0,(0x80001ffe)@l 91 mtdbatu 0,%r0 92 lis %r0,(0x80000022)@ha 93 addi %r0,%r0,(0x80000022)@l 94 mtdbatl 0,%r0 95#endif 96 97 lis %r3,fwsave@ha /* save the mmu values of the firmware */ 98 addi %r3,%r3,fwsave@l 99 lis %r4,fwbatsave@ha 100 addi %r4,%r4,fwbatsave@l 101 bl savemmu 102 103 /* save openfirmware address mappings */ 104 bl save_ofw_mapping 105 106#if 0 107 /* dont really need the bats from firmware saved, 0 to disable */ 108 lis %r3,fwbatsave@ha 109 addi %r3,%r3,fwbatsave@l 110 li %r4,64 111 li %r5,0 1121: subi %r4,%r4,%r4 113 stwx %r5,%r4,%r3 114 cmpi 4,0,0 115 bne 1b 116#endif 117 118 mr %r6,%r13 /* restore args pointer */ 119 mtlr %r31 /* restore return address */ 120 blr 121 122/* 123 * Save everything related to the mmu to the savearea pointed to by r3. 124 */ 125 .type savemmu,@function 126savemmu: 127 RETGUARD_SETUP(savemmu, %r11, %r12) 128 mr %r6,%r4 /* r4 holds pointer to BAT save area */ 129 130 li %r4,0 /* save SRs */ 1311: 132 addis %r4,%r4,-0x10000000@ha 133 or. %r4,%r4,%r4 134 mfsrin %r5,%r4 135 stwu %r5,4(%r3) 136 bne 1b 137 138 mfibatl %r4,0 /* save BATs */ 139 stw %r4,0(%r6) 140 mfibatu %r4,0 141 stw %r4,4(%r6) 142 mfibatl %r4,1 143 stw %r4,8(%r6) 144 mfibatu %r4,1 145 stw %r4,0xc(%r6) 146 mfibatl %r4,2 147 stw %r4,0x10(%r6) 148 mfibatu %r4,2 149 stw %r4,0x14(%r6) 150 mfibatl %r4,3 151 stw %r4,0x18(%r6) 152 mfibatu %r4,3 153 stw %r4,0x1c(%r6) 154 mfdbatl %r4,0 155 stw %r4,0x20(%r6) 156 mfdbatu %r4,0 157 stw %r4,0x24(%r6) 158 mfdbatl %r4,1 159 stw %r4,0x28(%r6) 160 mfdbatu %r4,1 161 stw %r4,0x2c(%r6) 162 mfdbatl %r4,2 163 stw %r4,0x30(%r6) 164 mfdbatu %r4,2 165 stw %r4,0x34(%r6) 166 mfdbatl %r4,3 167 stw %r4,0x38(%r6) 168 mfdbatu %r4,3 169 stw %r4,0x3c(%r6) 170 171 mfsprg %r4,0 /* save SPRGs */ 172 stw %r4,4(%r3) 173 mfsprg %r4,1 174 stw %r4,8(%r3) 175 mfsprg %r4,2 176 stw %r4,12(%r3) 177 mfsprg %r4,3 178 stw %r4,16(%r3) 179 180 mfsdr1 %r4 /* save SDR1 */ 181 stw %r4,20(%r3) 182 183 addi %r4,%r3,24 184 185 mfmsr %r4 186 stw %r4,24(%r3) 187 188 sync 189 isync 190 191 RETGUARD_CHECK(savemmu, %r11, %r12) 192 blr 193 194/* 195 * Restore everything related to the mmu from the savearea pointed to by r3. 196 * and bats pointed to by r4. 197 */ 198 .type restoremmu,@function 199restoremmu: 200 RETGUARD_SETUP(restoremmu, %r11, %r12) 201 li %r0,0 202 mtmsr %r0 203 mr %r6,%r4 /* pointer to sr to restore */ 204 li %r4,0 /* restore SRs */ 2051: 206 lwzu %r5,4(%r3) 207 addis %r4,%r4,-0x10000000@ha 208 or. %r4,%r4,%r4 209 mtsrin %r5,%r4 210 bne 1b 211 212 mfmsr %r4 213 lis %r5,(PSL_IR|PSL_DR)@h /* turn off MMU */ 214 ori %r5,%r5,(PSL_IR|PSL_DR)@l /* turn off MMU */ 215 andc %r4,%r4,%r5 /* turn off MMU */ 216 mtmsr %r4 217 isync 218 219 li %r4,0 /* first, invalidate BATs */ 220 mtibatu 0,%r4 221 mtibatu 1,%r4 222 mtibatu 2,%r4 223 mtibatu 3,%r4 224 mtdbatu 0,%r4 225 mtdbatu 1,%r4 226 mtdbatu 2,%r4 227 mtdbatu 3,%r4 228 229 lwz %r4,0(%r6) 230 mtibatl 0,%r4 /* restore BATs */ 231 lwz %r4,4(%r6) 232 mtibatu 0,%r4 233 lwz %r4,8(%r6) 234 mtibatl 1,%r4 235 lwz %r4,12(%r6) 236 mtibatu 1,%r4 237 lwz %r4,16(%r6) 238 mtibatl 2,%r4 239 lwz %r4,20(%r6) 240 mtibatu 2,%r4 241 lwz %r4,24(%r6) 242 mtibatl 3,%r4 243 lwz %r4,28(%r6) 244 mtibatu 3,%r4 245 lwz %r4,32(%r6) 246 mtdbatl 0,%r4 247 lwz %r4,36(%r6) 248 mtdbatu 0,%r4 249 lwz %r4,40(%r6) 250 mtdbatl 1,%r4 251 lwz %r4,44(%r6) 252 mtdbatu 1,%r4 253 lwz %r4,48(%r6) 254 mtdbatl 2,%r4 255 lwz %r4,52(%r6) 256 mtdbatu 2,%r4 257 lwz %r4,56(%r6) 258 mtdbatl 3,%r4 259 lwz %r4,60(%r6) 260 mtdbatu 3,%r4 261 262 lwz %r4,4(%r3) 263 mtsprg 0,4 /* restore SPRGs */ 264 lwz %r4,8(%r3) 265 mtsprg 1,4 266 lwz %r4,12(%r3) 267 mtsprg 2,4 268 lwz %r4,16(%r3) 269 mtsprg 3,4 270 271 sync /* remove everything from tlb */ 272 lis %r4,0x40000@ha 273 li %r5,0x1000 2741: 275 subf. %r4,%r5,%r4 276 tlbie %r4 277 bne 1b 278 279 sync 280 tlbsync 281 sync 282 283 lwz %r4,20(%r3) 284 sync 285 mtsdr1 %r4 /* restore SDR1 */ 286 287 288 /* tlbia */ 289 sync 290 li %r5,0x40 291 mtctr %r5 292 li %r4,0 293 1: 294 tlbie %r4 295 addi %r4,%r4,0x1000 296 bdnz 1b 297 sync 298 tlbsync 299 sync 300 301 lwz %r4,24(%r3) 302 mtmsr %r4 303 isync 304 305 RETGUARD_CHECK(restoremmu, %r11, %r12) 306 blr 307 308 309_ENTRY(fwentry) 310 mflr %r4 311 RETGUARD_SETUP_LATE(fwentry, %r11, %r4) 312 stwu %r1,-16(%r1) 313 stw %r4,20(%r1) 314 stw %r3,12(%r1) /* save arg */ 315 RETGUARD_SAVE(%r11, 8(%r1)) 316 317 lis %r3,clsave@ha /* save mmu values of client */ 318 addi %r3,%r3,clsave@l 319 lis %r4,clbatsave@ha /* save mmu values of client */ 320 addi %r4,%r4,clbatsave@l 321 bl savemmu 322 323 lis %r3,fwsave@ha /* restore mmu values of firmware */ 324 addi %r3,%r3,fwsave@l 325 lis %r4,fwbatsave@ha 326 addi %r4,%r4,fwbatsave@l 327 bl restoremmu 328 329 lis %r3,ofentry@ha 330 lwz %r3,ofentry@l(%r3) /* get actual firmware entry */ 331 mtlr %r3 332 333 mfmsr %r4 334 ori %r4,%r4,PSL_IR|PSL_DR /* turn on MMU */ 335 mtmsr %r4 336 isync 337 338 lwz %r3,12(%r1) /* restore arg */ 339 blrl /* do actual firmware call */ 340 341 stw %r3,12(%r1) /* save return value */ 342 343 lis %r3,fwsave@ha /* save mmu values of firmware */ 344 addi %r3,%r3,fwsave@l /* (might not be necessary, but... */ 345 lis %r4,fwbatsave@ha 346 addi %r4,%r4,fwbatsave@l 347 bl savemmu 348 349 lis %r3,clsave@ha /* restore mmu values of client */ 350 addi %r3,%r3,clsave@l 351 lis %r4,clbatsave@ha /* save mmu values of client */ 352 addi %r4,%r4,clbatsave@l 353 bl restoremmu 354 355 lwz %r4,20(%r1) 356 lwz %r3,12(%r1) /* restore return value */ 357 RETGUARD_LOAD(%r11, 8(%r1)) 358 359 mtlr %r4 360 addi %r1,%r1,16 361 RETGUARD_CHECK(fwentry, %r11, %r4) 362 blr 363 364.lcomm firmstk,NBPG,16 365.comm OF_buf,NBPG 366 367/* 368 * OpenFirmware entry point 369 * 370 * Note: caller has to set the machine state register (msr) 371 * to be correct for OpenFirmware. 372 */ 373_ENTRY(openfirmware) 374 mflr %r0 375 RETGUARD_SETUP_LATE(openfirmware, %r11, %r0) 376 stw %r0,4(%r1) /* save return address */ 377 378 /* switch to OpenFirmware real mode stack */ 379 lis %r7,firmstk+NBPG-16@ha 380 addi %r7,%r7,firmstk+NBPG-16@l 381 stw %r1,0(%r7) 382 RETGUARD_SAVE(%r11, 8(%r7)) 383 mr %r1,%r7 384 385 lis %r4,fwcall@ha 386 lwz %r4,fwcall@l(%r4) 387 388 mtctr %r4 389 bctrl 390 391 RETGUARD_LOAD(%r11, 8(%r1)) 392 lwz %r1,0(%r1) /* get callers original stack pointer */ 393 lwz %r0,4(%r1) 394 mtlr %r0 395 RETGUARD_CHECK(openfirmware, %r11, %r0) 396 blr 397