1 1.35 thorpej /* $NetBSD: Locore.c,v 1.35 2021/02/28 20:27:40 thorpej Exp $ */ 2 1.1 tsubai 3 1.1 tsubai /* 4 1.1 tsubai * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 1.1 tsubai * Copyright (C) 1995, 1996 TooLs GmbH. 6 1.1 tsubai * All rights reserved. 7 1.1 tsubai * 8 1.1 tsubai * Redistribution and use in source and binary forms, with or without 9 1.1 tsubai * modification, are permitted provided that the following conditions 10 1.1 tsubai * are met: 11 1.1 tsubai * 1. Redistributions of source code must retain the above copyright 12 1.1 tsubai * notice, this list of conditions and the following disclaimer. 13 1.1 tsubai * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 tsubai * notice, this list of conditions and the following disclaimer in the 15 1.1 tsubai * documentation and/or other materials provided with the distribution. 16 1.1 tsubai * 3. All advertising materials mentioning features or use of this software 17 1.1 tsubai * must display the following acknowledgement: 18 1.1 tsubai * This product includes software developed by TooLs GmbH. 19 1.1 tsubai * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 1.1 tsubai * derived from this software without specific prior written permission. 21 1.1 tsubai * 22 1.1 tsubai * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 1.1 tsubai * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 1.1 tsubai * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 1.1 tsubai * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 1.1 tsubai * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 1.1 tsubai * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 1.1 tsubai * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 1.1 tsubai * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 1.1 tsubai * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 1.1 tsubai * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 tsubai */ 33 1.1 tsubai 34 1.30 uwe #include <sys/param.h> 35 1.1 tsubai #include <lib/libsa/stand.h> 36 1.1 tsubai 37 1.1 tsubai #include <machine/cpu.h> 38 1.32 macallan #include <powerpc/oea/spr.h> 39 1.1 tsubai 40 1.1 tsubai #include "openfirm.h" 41 1.1 tsubai 42 1.15 aymeric static int (*openfirmware)(void *); 43 1.1 tsubai 44 1.20 uwe static void startup(void *, int, int (*)(void *), char *, int) 45 1.20 uwe __attribute__((__used__)); 46 1.15 aymeric static void setup(void); 47 1.1 tsubai 48 1.30 uwe #ifdef HEAP_VARIABLE 49 1.30 uwe #ifndef HEAP_SIZE 50 1.30 uwe #define HEAP_SIZE 0x20000 51 1.30 uwe #endif 52 1.30 uwe char *heapspace; 53 1.30 uwe #endif 54 1.30 uwe 55 1.20 uwe static int stack[8192/4 + 4] __attribute__((__used__)); 56 1.1 tsubai 57 1.1 tsubai #ifdef XCOFF_GLUE 58 1.18 perry __asm( 59 1.12 matt " .text \n" 60 1.12 matt " .globl _entry \n" 61 1.12 matt "_entry: \n" 62 1.12 matt " .long _start,0,0 \n" 63 1.12 matt ); 64 1.20 uwe #endif /* XCOFF_GLUE */ 65 1.1 tsubai 66 1.18 perry __asm( 67 1.12 matt " .text \n" 68 1.12 matt " .globl _start \n" 69 1.12 matt "_start: \n" 70 1.12 matt " sync \n" 71 1.12 matt " isync \n" 72 1.12 matt " lis %r1,stack@ha \n" 73 1.12 matt " addi %r1,%r1,stack@l \n" 74 1.12 matt " addi %r1,%r1,8192 \n" 75 1.12 matt " \n" 76 1.12 matt " mfmsr %r8 \n" 77 1.12 matt " li %r0,0 \n" 78 1.12 matt " mtmsr %r0 \n" 79 1.12 matt " isync \n" 80 1.12 matt " \n" 81 1.25 macallan " \n" /* test for 601 */ 82 1.27 tsutsui " mfspr %r0,287 \n" /* mfpvbr %r0 PVR = 287 */ 83 1.27 tsutsui " srwi %r0,%r0,0x10 \n" 84 1.33 scole " cmplwi %r0,0x02 \n" /* 601 CPU = 0x0001 */ 85 1.32 macallan " blt 2f \n" /* skip over non-601 BAT setup */ 86 1.33 scole " cmplwi %r0,0x39 \n" /* PPC970 */ 87 1.32 macallan " blt 0f \n" 88 1.33 scole " cmplwi %r0,0x45 \n" /* PPC970GX */ 89 1.32 macallan " ble 1f \n" 90 1.27 tsutsui /* non PPC 601 BATs */ 91 1.32 macallan "0: li %r0,0 \n" 92 1.12 matt " mtibatu 0,%r0 \n" 93 1.12 matt " mtibatu 1,%r0 \n" 94 1.12 matt " mtibatu 2,%r0 \n" 95 1.12 matt " mtibatu 3,%r0 \n" 96 1.12 matt " mtdbatu 0,%r0 \n" 97 1.12 matt " mtdbatu 1,%r0 \n" 98 1.12 matt " mtdbatu 2,%r0 \n" 99 1.12 matt " mtdbatu 3,%r0 \n" 100 1.12 matt " \n" 101 1.27 tsutsui " li %r9,0x12 \n" /* BATL(0, BAT_M, BAT_PP_RW) */ 102 1.12 matt " mtibatl 0,%r9 \n" 103 1.12 matt " mtdbatl 0,%r9 \n" 104 1.12 matt " li %r9,0x1ffe \n" /* BATU(0, BAT_BL_256M, BAT_Vs) */ 105 1.12 matt " mtibatu 0,%r9 \n" 106 1.12 matt " mtdbatu 0,%r9 \n" 107 1.32 macallan " b 3f \n" 108 1.32 macallan /* 970 initialization stuff */ 109 1.32 macallan "1: \n" 110 1.32 macallan /* make sure we're in bridge mode */ 111 1.32 macallan " clrldi %r8,%r8,3 \n" 112 1.32 macallan " mtmsrd %r8 \n" 113 1.32 macallan " isync \n" 114 1.32 macallan /* clear HID5 DCBZ bits (56/57), need to do this early */ 115 1.32 macallan " mfspr %r9,0x3f6 \n" 116 1.32 macallan " rldimi %r9,0,6,56 \n" 117 1.32 macallan " sync \n" 118 1.32 macallan " mtspr 0x3f6,%r9 \n" 119 1.32 macallan " isync \n" 120 1.32 macallan " sync \n" 121 1.32 macallan /* Setup HID1 features, prefetch + i-cacheability controlled by PTE */ 122 1.32 macallan " mfspr %r9,0x3f1 \n" 123 1.32 macallan " li %r11,0x1200 \n" 124 1.32 macallan " sldi %r11,%r11,44 \n" 125 1.32 macallan " or %r9,%r9,%r11 \n" 126 1.32 macallan " mtspr 0x3f1,%r9 \n" 127 1.32 macallan " isync \n" 128 1.32 macallan " sync \n" 129 1.32 macallan " b 3f \n" 130 1.27 tsutsui /* PPC 601 BATs */ 131 1.32 macallan "2: li %r0,0 \n" 132 1.26 tsutsui " mtibatu 0,%r0 \n" 133 1.27 tsutsui " mtibatu 1,%r0 \n" 134 1.27 tsutsui " mtibatu 2,%r0 \n" 135 1.27 tsutsui " mtibatu 3,%r0 \n" 136 1.27 tsutsui " \n" 137 1.27 tsutsui " li %r9,0x7f \n" 138 1.27 tsutsui " mtibatl 0,%r9 \n" 139 1.27 tsutsui " li %r9,0x1a \n" 140 1.27 tsutsui " mtibatu 0,%r9 \n" 141 1.27 tsutsui " \n" 142 1.27 tsutsui " lis %r9,0x80 \n" 143 1.27 tsutsui " addi %r9,%r9,0x7f \n" 144 1.27 tsutsui " mtibatl 1,%r9 \n" 145 1.27 tsutsui " lis %r9,0x80 \n" 146 1.27 tsutsui " addi %r9,%r9,0x1a \n" 147 1.27 tsutsui " mtibatu 1,%r9 \n" 148 1.27 tsutsui " \n" 149 1.27 tsutsui " lis %r9,0x100 \n" 150 1.27 tsutsui " addi %r9,%r9,0x7f \n" 151 1.27 tsutsui " mtibatl 2,%r9 \n" 152 1.27 tsutsui " lis %r9,0x100 \n" 153 1.27 tsutsui " addi %r9,%r9,0x1a \n" 154 1.27 tsutsui " mtibatu 2,%r9 \n" 155 1.27 tsutsui " \n" 156 1.27 tsutsui " lis %r9,0x180 \n" 157 1.27 tsutsui " addi %r9,%r9,0x7f \n" 158 1.27 tsutsui " mtibatl 3,%r9 \n" 159 1.27 tsutsui " lis %r9,0x180 \n" 160 1.27 tsutsui " addi %r9,%r9,0x1a \n" 161 1.27 tsutsui " mtibatu 3,%r9 \n" 162 1.25 macallan " \n" 163 1.32 macallan "3: isync \n" 164 1.12 matt " \n" 165 1.12 matt " mtmsr %r8 \n" 166 1.12 matt " isync \n" 167 1.12 matt " \n" 168 1.16 wrstuden /* 169 1.16 wrstuden * Make sure that .bss is zeroed 170 1.16 wrstuden */ 171 1.16 wrstuden " \n" 172 1.16 wrstuden " li %r0,0 \n" 173 1.16 wrstuden " lis %r8,_edata@ha \n" 174 1.16 wrstuden " addi %r8,%r8,_edata@l\n" 175 1.16 wrstuden " lis %r9,_end@ha \n" 176 1.16 wrstuden " addi %r9,%r9,_end@l \n" 177 1.16 wrstuden " \n" 178 1.16 wrstuden "5: cmpw 0,%r8,%r9 \n" 179 1.16 wrstuden " bge 6f \n" 180 1.33 scole /* 181 1.33 scole * clear by bytes to avoid ppc601 alignment exceptions 182 1.33 scole */ 183 1.33 scole " stb %r0,0(%r8) \n" 184 1.33 scole " stb %r0,1(%r8) \n" 185 1.33 scole " stb %r0,2(%r8) \n" 186 1.33 scole " stb %r0,3(%r8) \n" 187 1.16 wrstuden " addi %r8,%r8,4 \n" 188 1.16 wrstuden " b 5b \n" 189 1.16 wrstuden " \n" 190 1.16 wrstuden "6: b startup \n" 191 1.12 matt ); 192 1.1 tsubai 193 1.1 tsubai #if 0 194 1.1 tsubai static int 195 1.15 aymeric openfirmware(void *arg) 196 1.1 tsubai { 197 1.1 tsubai 198 1.18 perry __asm volatile ("sync; isync"); 199 1.1 tsubai openfirmware_entry(arg); 200 1.18 perry __asm volatile ("sync; isync"); 201 1.1 tsubai } 202 1.1 tsubai #endif 203 1.1 tsubai 204 1.35 thorpej int ofw_real_mode; 205 1.35 thorpej int ofw_address_cells; 206 1.35 thorpej int ofw_size_cells; 207 1.35 thorpej 208 1.35 thorpej int ofw_root; /* / */ 209 1.35 thorpej int ofw_options; /* /options */ 210 1.35 thorpej int ofw_openprom; /* /openprom */ 211 1.35 thorpej int ofw_chosen; /* /chosen (package) */ 212 1.35 thorpej int ofw_stdin; /* /chosen/stdin */ 213 1.35 thorpej int ofw_stdout; /* /chosen/stdout */ 214 1.35 thorpej int ofw_memory_ihandle; /* /chosen/memory */ 215 1.35 thorpej int ofw_mmu_ihandle; /* /chosen/mmu */ 216 1.35 thorpej 217 1.35 thorpej bool 218 1.35 thorpej ofw_option_truefalse(const char *prop, int proplen) 219 1.35 thorpej { 220 1.35 thorpej /* These are all supposed to be strings. */ 221 1.35 thorpej switch (prop[0]) { 222 1.35 thorpej case 'y': 223 1.35 thorpej case 'Y': 224 1.35 thorpej case 't': 225 1.35 thorpej case 'T': 226 1.35 thorpej case '1': 227 1.35 thorpej return true; 228 1.35 thorpej } 229 1.35 thorpej return false; 230 1.35 thorpej } 231 1.35 thorpej 232 1.1 tsubai static void 233 1.15 aymeric startup(void *vpd, int res, int (*openfirm)(void *), char *arg, int argl) 234 1.1 tsubai { 235 1.1 tsubai 236 1.1 tsubai openfirmware = openfirm; 237 1.1 tsubai setup(); 238 1.1 tsubai main(); 239 1.1 tsubai OF_exit(); 240 1.1 tsubai } 241 1.1 tsubai 242 1.31 uwe #if 0 243 1.31 uwe void 244 1.31 uwe OF_enter(void) 245 1.31 uwe { 246 1.31 uwe static struct { 247 1.31 uwe const char *name; 248 1.31 uwe int nargs; 249 1.31 uwe int nreturns; 250 1.31 uwe } args = { 251 1.31 uwe "enter", 252 1.31 uwe 0, 253 1.31 uwe 0 254 1.31 uwe }; 255 1.31 uwe 256 1.31 uwe openfirmware(&args); 257 1.31 uwe } 258 1.31 uwe #endif /* OF_enter */ 259 1.31 uwe 260 1.1 tsubai __dead void 261 1.15 aymeric OF_exit(void) 262 1.1 tsubai { 263 1.1 tsubai static struct { 264 1.19 uwe const char *name; 265 1.1 tsubai int nargs; 266 1.1 tsubai int nreturns; 267 1.1 tsubai } args = { 268 1.1 tsubai "exit", 269 1.1 tsubai 0, 270 1.1 tsubai 0 271 1.1 tsubai }; 272 1.1 tsubai 273 1.1 tsubai openfirmware(&args); 274 1.1 tsubai for (;;); /* just in case */ 275 1.1 tsubai } 276 1.1 tsubai 277 1.1 tsubai int 278 1.19 uwe OF_finddevice(const char *name) 279 1.1 tsubai { 280 1.1 tsubai static struct { 281 1.19 uwe const char *name; 282 1.1 tsubai int nargs; 283 1.1 tsubai int nreturns; 284 1.19 uwe const char *device; 285 1.1 tsubai int phandle; 286 1.1 tsubai } args = { 287 1.1 tsubai "finddevice", 288 1.1 tsubai 1, 289 1.1 tsubai 1, 290 1.10 tsutsui }; 291 1.10 tsutsui 292 1.1 tsubai args.device = name; 293 1.1 tsubai if (openfirmware(&args) == -1) 294 1.1 tsubai return -1; 295 1.1 tsubai return args.phandle; 296 1.1 tsubai } 297 1.1 tsubai 298 1.1 tsubai int 299 1.15 aymeric OF_instance_to_package(int ihandle) 300 1.1 tsubai { 301 1.1 tsubai static struct { 302 1.19 uwe const char *name; 303 1.1 tsubai int nargs; 304 1.1 tsubai int nreturns; 305 1.1 tsubai int ihandle; 306 1.1 tsubai int phandle; 307 1.1 tsubai } args = { 308 1.1 tsubai "instance-to-package", 309 1.1 tsubai 1, 310 1.1 tsubai 1, 311 1.1 tsubai }; 312 1.10 tsutsui 313 1.1 tsubai args.ihandle = ihandle; 314 1.1 tsubai if (openfirmware(&args) == -1) 315 1.1 tsubai return -1; 316 1.1 tsubai return args.phandle; 317 1.1 tsubai } 318 1.1 tsubai 319 1.1 tsubai int 320 1.19 uwe OF_getprop(int handle, const char *prop, void *buf, int buflen) 321 1.1 tsubai { 322 1.1 tsubai static struct { 323 1.19 uwe const char *name; 324 1.1 tsubai int nargs; 325 1.1 tsubai int nreturns; 326 1.1 tsubai int phandle; 327 1.19 uwe const char *prop; 328 1.1 tsubai void *buf; 329 1.1 tsubai int buflen; 330 1.1 tsubai int size; 331 1.1 tsubai } args = { 332 1.1 tsubai "getprop", 333 1.1 tsubai 4, 334 1.1 tsubai 1, 335 1.1 tsubai }; 336 1.10 tsutsui 337 1.1 tsubai args.phandle = handle; 338 1.1 tsubai args.prop = prop; 339 1.1 tsubai args.buf = buf; 340 1.1 tsubai args.buflen = buflen; 341 1.1 tsubai if (openfirmware(&args) == -1) 342 1.1 tsubai return -1; 343 1.1 tsubai return args.size; 344 1.1 tsubai } 345 1.1 tsubai 346 1.1 tsubai #ifdef __notyet__ /* Has a bug on FirePower */ 347 1.1 tsubai int 348 1.21 uwe OF_setprop(int handle, const char *prop, void *buf, int len) 349 1.1 tsubai { 350 1.1 tsubai static struct { 351 1.19 uwe const char *name; 352 1.1 tsubai int nargs; 353 1.1 tsubai int nreturns; 354 1.1 tsubai int phandle; 355 1.21 uwe const char *prop; 356 1.1 tsubai void *buf; 357 1.1 tsubai int len; 358 1.1 tsubai int size; 359 1.1 tsubai } args = { 360 1.1 tsubai "setprop", 361 1.1 tsubai 4, 362 1.1 tsubai 1, 363 1.1 tsubai }; 364 1.10 tsutsui 365 1.1 tsubai args.phandle = handle; 366 1.1 tsubai args.prop = prop; 367 1.1 tsubai args.buf = buf; 368 1.1 tsubai args.len = len; 369 1.1 tsubai if (openfirmware(&args) == -1) 370 1.1 tsubai return -1; 371 1.1 tsubai return args.size; 372 1.1 tsubai } 373 1.1 tsubai #endif 374 1.1 tsubai 375 1.1 tsubai int 376 1.21 uwe OF_open(const char *dname) 377 1.1 tsubai { 378 1.1 tsubai static struct { 379 1.19 uwe const char *name; 380 1.1 tsubai int nargs; 381 1.1 tsubai int nreturns; 382 1.21 uwe const char *dname; 383 1.1 tsubai int handle; 384 1.1 tsubai } args = { 385 1.1 tsubai "open", 386 1.1 tsubai 1, 387 1.1 tsubai 1, 388 1.1 tsubai }; 389 1.10 tsutsui 390 1.1 tsubai #ifdef OFW_DEBUG 391 1.1 tsubai printf("OF_open(%s) -> ", dname); 392 1.1 tsubai #endif 393 1.1 tsubai args.dname = dname; 394 1.1 tsubai if (openfirmware(&args) == -1 || 395 1.1 tsubai args.handle == 0) { 396 1.1 tsubai #ifdef OFW_DEBUG 397 1.1 tsubai printf("lose\n"); 398 1.1 tsubai #endif 399 1.1 tsubai return -1; 400 1.1 tsubai } 401 1.1 tsubai #ifdef OFW_DEBUG 402 1.1 tsubai printf("%d\n", args.handle); 403 1.1 tsubai #endif 404 1.1 tsubai return args.handle; 405 1.1 tsubai } 406 1.1 tsubai 407 1.1 tsubai void 408 1.15 aymeric OF_close(int handle) 409 1.1 tsubai { 410 1.1 tsubai static struct { 411 1.19 uwe const char *name; 412 1.1 tsubai int nargs; 413 1.1 tsubai int nreturns; 414 1.1 tsubai int handle; 415 1.1 tsubai } args = { 416 1.1 tsubai "close", 417 1.1 tsubai 1, 418 1.1 tsubai 0, 419 1.1 tsubai }; 420 1.10 tsutsui 421 1.1 tsubai #ifdef OFW_DEBUG 422 1.1 tsubai printf("OF_close(%d)\n", handle); 423 1.1 tsubai #endif 424 1.1 tsubai args.handle = handle; 425 1.1 tsubai openfirmware(&args); 426 1.1 tsubai } 427 1.1 tsubai 428 1.1 tsubai int 429 1.15 aymeric OF_write(int handle, void *addr, int len) 430 1.1 tsubai { 431 1.1 tsubai static struct { 432 1.19 uwe const char *name; 433 1.1 tsubai int nargs; 434 1.1 tsubai int nreturns; 435 1.1 tsubai int ihandle; 436 1.1 tsubai void *addr; 437 1.1 tsubai int len; 438 1.1 tsubai int actual; 439 1.1 tsubai } args = { 440 1.1 tsubai "write", 441 1.1 tsubai 3, 442 1.1 tsubai 1, 443 1.1 tsubai }; 444 1.1 tsubai 445 1.1 tsubai #ifdef OFW_DEBUG 446 1.1 tsubai if (len != 1) 447 1.15 aymeric printf("OF_write(%d, %p, %x) -> ", handle, addr, len); 448 1.1 tsubai #endif 449 1.1 tsubai args.ihandle = handle; 450 1.1 tsubai args.addr = addr; 451 1.1 tsubai args.len = len; 452 1.1 tsubai if (openfirmware(&args) == -1) { 453 1.1 tsubai #ifdef OFW_DEBUG 454 1.1 tsubai printf("lose\n"); 455 1.1 tsubai #endif 456 1.1 tsubai return -1; 457 1.1 tsubai } 458 1.1 tsubai #ifdef OFW_DEBUG 459 1.1 tsubai if (len != 1) 460 1.1 tsubai printf("%x\n", args.actual); 461 1.1 tsubai #endif 462 1.1 tsubai return args.actual; 463 1.1 tsubai } 464 1.1 tsubai 465 1.1 tsubai int 466 1.15 aymeric OF_read(int handle, void *addr, int len) 467 1.1 tsubai { 468 1.1 tsubai static struct { 469 1.19 uwe const char *name; 470 1.1 tsubai int nargs; 471 1.1 tsubai int nreturns; 472 1.1 tsubai int ihandle; 473 1.1 tsubai void *addr; 474 1.1 tsubai int len; 475 1.1 tsubai int actual; 476 1.1 tsubai } args = { 477 1.1 tsubai "read", 478 1.1 tsubai 3, 479 1.1 tsubai 1, 480 1.1 tsubai }; 481 1.1 tsubai 482 1.1 tsubai #ifdef OFW_DEBUG 483 1.1 tsubai if (len != 1) 484 1.15 aymeric printf("OF_read(%d, %p, %x) -> ", handle, addr, len); 485 1.1 tsubai #endif 486 1.1 tsubai args.ihandle = handle; 487 1.1 tsubai args.addr = addr; 488 1.1 tsubai args.len = len; 489 1.1 tsubai if (openfirmware(&args) == -1) { 490 1.1 tsubai #ifdef OFW_DEBUG 491 1.1 tsubai printf("lose\n"); 492 1.1 tsubai #endif 493 1.1 tsubai return -1; 494 1.1 tsubai } 495 1.1 tsubai #ifdef OFW_DEBUG 496 1.1 tsubai if (len != 1) 497 1.1 tsubai printf("%x\n", args.actual); 498 1.1 tsubai #endif 499 1.1 tsubai return args.actual; 500 1.1 tsubai } 501 1.1 tsubai 502 1.1 tsubai int 503 1.15 aymeric OF_seek(int handle, u_quad_t pos) 504 1.1 tsubai { 505 1.1 tsubai static struct { 506 1.19 uwe const char *name; 507 1.1 tsubai int nargs; 508 1.1 tsubai int nreturns; 509 1.1 tsubai int handle; 510 1.1 tsubai int poshi; 511 1.1 tsubai int poslo; 512 1.1 tsubai int status; 513 1.1 tsubai } args = { 514 1.1 tsubai "seek", 515 1.1 tsubai 3, 516 1.1 tsubai 1, 517 1.1 tsubai }; 518 1.10 tsutsui 519 1.1 tsubai #ifdef OFW_DEBUG 520 1.1 tsubai printf("OF_seek(%d, %x, %x) -> ", handle, (int)(pos >> 32), (int)pos); 521 1.1 tsubai #endif 522 1.1 tsubai args.handle = handle; 523 1.1 tsubai args.poshi = (int)(pos >> 32); 524 1.1 tsubai args.poslo = (int)pos; 525 1.1 tsubai if (openfirmware(&args) == -1) { 526 1.1 tsubai #ifdef OFW_DEBUG 527 1.1 tsubai printf("lose\n"); 528 1.1 tsubai #endif 529 1.1 tsubai return -1; 530 1.1 tsubai } 531 1.1 tsubai #ifdef OFW_DEBUG 532 1.1 tsubai printf("%d\n", args.status); 533 1.1 tsubai #endif 534 1.1 tsubai return args.status; 535 1.1 tsubai } 536 1.1 tsubai 537 1.1 tsubai void * 538 1.15 aymeric OF_claim(void *virt, u_int size, u_int align) 539 1.1 tsubai { 540 1.1 tsubai static struct { 541 1.19 uwe const char *name; 542 1.1 tsubai int nargs; 543 1.1 tsubai int nreturns; 544 1.1 tsubai void *virt; 545 1.1 tsubai u_int size; 546 1.1 tsubai u_int align; 547 1.1 tsubai void *baseaddr; 548 1.1 tsubai } args = { 549 1.1 tsubai "claim", 550 1.1 tsubai 3, 551 1.1 tsubai 1, 552 1.1 tsubai }; 553 1.1 tsubai 554 1.1 tsubai #ifdef OFW_DEBUG 555 1.15 aymeric printf("OF_claim(%p, %x, %x) -> ", virt, size, align); 556 1.1 tsubai #endif 557 1.1 tsubai args.virt = virt; 558 1.1 tsubai args.size = size; 559 1.1 tsubai args.align = align; 560 1.1 tsubai if (openfirmware(&args) == -1) { 561 1.1 tsubai #ifdef OFW_DEBUG 562 1.1 tsubai printf("lose\n"); 563 1.1 tsubai #endif 564 1.1 tsubai return (void *)-1; 565 1.1 tsubai } 566 1.1 tsubai #ifdef OFW_DEBUG 567 1.15 aymeric printf("%p\n", args.baseaddr); 568 1.1 tsubai #endif 569 1.1 tsubai return args.baseaddr; 570 1.1 tsubai } 571 1.1 tsubai 572 1.1 tsubai void 573 1.15 aymeric OF_release(void *virt, u_int size) 574 1.1 tsubai { 575 1.1 tsubai static struct { 576 1.19 uwe const char *name; 577 1.1 tsubai int nargs; 578 1.1 tsubai int nreturns; 579 1.1 tsubai void *virt; 580 1.1 tsubai u_int size; 581 1.1 tsubai } args = { 582 1.1 tsubai "release", 583 1.1 tsubai 2, 584 1.1 tsubai 0, 585 1.1 tsubai }; 586 1.10 tsutsui 587 1.1 tsubai #ifdef OFW_DEBUG 588 1.15 aymeric printf("OF_release(%p, %x)\n", virt, size); 589 1.1 tsubai #endif 590 1.1 tsubai args.virt = virt; 591 1.1 tsubai args.size = size; 592 1.1 tsubai openfirmware(&args); 593 1.1 tsubai } 594 1.1 tsubai 595 1.1 tsubai int 596 1.15 aymeric OF_milliseconds(void) 597 1.1 tsubai { 598 1.1 tsubai static struct { 599 1.19 uwe const char *name; 600 1.1 tsubai int nargs; 601 1.1 tsubai int nreturns; 602 1.1 tsubai int ms; 603 1.1 tsubai } args = { 604 1.1 tsubai "milliseconds", 605 1.1 tsubai 0, 606 1.1 tsubai 1, 607 1.1 tsubai }; 608 1.10 tsutsui 609 1.1 tsubai openfirmware(&args); 610 1.1 tsubai return args.ms; 611 1.1 tsubai } 612 1.1 tsubai 613 1.1 tsubai #ifdef __notyet__ 614 1.1 tsubai void 615 1.15 aymeric OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) 616 1.1 tsubai { 617 1.1 tsubai static struct { 618 1.19 uwe const char *name; 619 1.1 tsubai int nargs; 620 1.1 tsubai int nreturns; 621 1.1 tsubai void *virt; 622 1.1 tsubai u_int size; 623 1.1 tsubai void (*entry)(); 624 1.1 tsubai void *arg; 625 1.1 tsubai u_int len; 626 1.1 tsubai } args = { 627 1.1 tsubai "chain", 628 1.1 tsubai 5, 629 1.1 tsubai 0, 630 1.1 tsubai }; 631 1.1 tsubai 632 1.1 tsubai args.virt = virt; 633 1.1 tsubai args.size = size; 634 1.1 tsubai args.entry = entry; 635 1.1 tsubai args.arg = arg; 636 1.1 tsubai args.len = len; 637 1.1 tsubai openfirmware(&args); 638 1.1 tsubai } 639 1.1 tsubai #else 640 1.1 tsubai void 641 1.15 aymeric OF_chain(void *virt, u_int size, boot_entry_t entry, void *arg, u_int len) 642 1.1 tsubai { 643 1.1 tsubai /* 644 1.1 tsubai * This is a REALLY dirty hack till the firmware gets this going 645 1.1 tsubai */ 646 1.1 tsubai #if 0 647 1.1 tsubai OF_release(virt, size); 648 1.1 tsubai #endif 649 1.1 tsubai entry(0, 0, openfirmware, arg, len); 650 1.1 tsubai } 651 1.1 tsubai #endif 652 1.5 tsubai 653 1.5 tsubai int 654 1.35 thorpej OF_call_method(const char *method, int ihandle, int nargs, int nreturns, 655 1.35 thorpej int *cells) 656 1.5 tsubai { 657 1.5 tsubai static struct { 658 1.19 uwe const char *name; 659 1.5 tsubai int nargs; 660 1.5 tsubai int nreturns; 661 1.21 uwe const char *method; 662 1.5 tsubai int ihandle; 663 1.5 tsubai int args_n_results[12]; 664 1.5 tsubai } args = { 665 1.5 tsubai "call-method", 666 1.5 tsubai 2, 667 1.5 tsubai 1, 668 1.5 tsubai }; 669 1.5 tsubai int *ip, n; 670 1.5 tsubai 671 1.5 tsubai if (nargs > 6) 672 1.5 tsubai return -1; 673 1.35 thorpej 674 1.5 tsubai args.nargs = nargs + 2; 675 1.5 tsubai args.nreturns = nreturns + 1; 676 1.5 tsubai args.method = method; 677 1.5 tsubai args.ihandle = ihandle; 678 1.35 thorpej 679 1.5 tsubai for (ip = args.args_n_results + (n = nargs); --n >= 0;) 680 1.35 thorpej *--ip = *cells++; 681 1.5 tsubai 682 1.9 wiz if (openfirmware(&args) == -1) { 683 1.5 tsubai return -1; 684 1.9 wiz } 685 1.35 thorpej 686 1.9 wiz if (args.args_n_results[nargs]) { 687 1.5 tsubai return args.args_n_results[nargs]; 688 1.9 wiz } 689 1.35 thorpej 690 1.5 tsubai for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) 691 1.35 thorpej *cells++ = *--ip; 692 1.35 thorpej 693 1.5 tsubai return 0; 694 1.5 tsubai } 695 1.1 tsubai 696 1.1 tsubai static void 697 1.15 aymeric setup(void) 698 1.1 tsubai { 699 1.35 thorpej char prop[32]; 700 1.35 thorpej int proplen; 701 1.35 thorpej const char *reason = NULL; 702 1.1 tsubai 703 1.35 thorpej if ((ofw_chosen = OF_finddevice("/chosen")) == -1) 704 1.1 tsubai OF_exit(); 705 1.35 thorpej if (OF_getprop(ofw_chosen, "stdin", &ofw_stdin, sizeof(ofw_stdin)) != 706 1.35 thorpej sizeof(ofw_stdin) || 707 1.35 thorpej OF_getprop(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) != 708 1.35 thorpej sizeof(ofw_stdout)) 709 1.1 tsubai OF_exit(); 710 1.30 uwe 711 1.35 thorpej if (ofw_stdout == 0) { 712 1.34 rin /* screen should be console, but it is not open */ 713 1.35 thorpej ofw_stdout = OF_open("screen"); 714 1.34 rin } 715 1.34 rin 716 1.30 uwe #ifdef HEAP_VARIABLE 717 1.32 macallan uint32_t pvr, vers, hsize = HEAP_SIZE; 718 1.32 macallan 719 1.32 macallan __asm volatile ("mfpvr %0" : "=r"(pvr)); 720 1.32 macallan vers = pvr >> 16; 721 1.32 macallan if (vers >= IBM970 && vers <= IBM970GX) hsize = 0x800000; 722 1.32 macallan 723 1.32 macallan heapspace = OF_claim(0, hsize, NBPG); 724 1.30 uwe if (heapspace == (char *)-1) { 725 1.30 uwe panic("Failed to allocate heap"); 726 1.30 uwe } 727 1.30 uwe 728 1.30 uwe setheap(heapspace, heapspace + HEAP_SIZE); 729 1.30 uwe #endif /* HEAP_VARIABLE */ 730 1.35 thorpej 731 1.35 thorpej ofw_root = OF_finddevice("/"); 732 1.35 thorpej ofw_options = OF_finddevice("/options"); 733 1.35 thorpej ofw_openprom = OF_finddevice("/openprom"); 734 1.35 thorpej ofw_chosen = OF_finddevice("/chosen"); 735 1.35 thorpej 736 1.35 thorpej if (ofw_root == -1) { 737 1.35 thorpej reason = "No root node"; 738 1.35 thorpej goto bad_environment; 739 1.35 thorpej } 740 1.35 thorpej if (ofw_chosen == -1) { 741 1.35 thorpej reason = "No chosen node"; 742 1.35 thorpej goto bad_environment; 743 1.35 thorpej } 744 1.35 thorpej 745 1.35 thorpej if (ofw_options != -1) { 746 1.35 thorpej proplen = OF_getprop(ofw_options, "real-mode?", prop, 747 1.35 thorpej sizeof(prop)); 748 1.35 thorpej if (proplen > 0) { 749 1.35 thorpej ofw_real_mode = ofw_option_truefalse(prop, proplen); 750 1.35 thorpej } 751 1.35 thorpej } 752 1.35 thorpej 753 1.35 thorpej /* 754 1.35 thorpej * Get #address-cells and #size-cells. 755 1.35 thorpej */ 756 1.35 thorpej ofw_address_cells = 1; 757 1.35 thorpej ofw_size_cells = 1; 758 1.35 thorpej OF_getprop(ofw_root, "#address-cells", &ofw_address_cells, 759 1.35 thorpej sizeof(ofw_address_cells)); 760 1.35 thorpej OF_getprop(ofw_root, "#size-cells", &ofw_size_cells, 761 1.35 thorpej sizeof(ofw_size_cells)); 762 1.35 thorpej 763 1.35 thorpej /* See loadfile_machdep.c */ 764 1.35 thorpej if (ofw_size_cells != 1) { 765 1.35 thorpej printf("#size-cells = %d not yet supported\n", ofw_size_cells); 766 1.35 thorpej reason = "unsupported #size-cells"; 767 1.35 thorpej goto bad_environment; 768 1.35 thorpej } 769 1.35 thorpej 770 1.35 thorpej /* 771 1.35 thorpej * Get the ihandle on /chosen/memory and /chosen/mmu. 772 1.35 thorpej */ 773 1.35 thorpej ofw_memory_ihandle = -1; 774 1.35 thorpej ofw_mmu_ihandle = -1; 775 1.35 thorpej OF_getprop(ofw_chosen, "memory", &ofw_memory_ihandle, 776 1.35 thorpej sizeof(ofw_memory_ihandle)); 777 1.35 thorpej OF_getprop(ofw_chosen, "mmu", &ofw_mmu_ihandle, 778 1.35 thorpej sizeof(ofw_mmu_ihandle)); 779 1.35 thorpej if (ofw_memory_ihandle == -1) { 780 1.35 thorpej reason = "no /chosen/memory"; 781 1.35 thorpej goto bad_environment; 782 1.35 thorpej } 783 1.35 thorpej if (ofw_mmu_ihandle == -1) { 784 1.35 thorpej reason = "no /chosen/mmu"; 785 1.35 thorpej goto bad_environment; 786 1.35 thorpej } 787 1.35 thorpej 788 1.35 thorpej return; 789 1.35 thorpej 790 1.35 thorpej bad_environment: 791 1.35 thorpej if (reason == NULL) { 792 1.35 thorpej reason = "unknown reason"; 793 1.35 thorpej } 794 1.35 thorpej printf("Invalid Openfirmware environment: %s\n", reason); 795 1.35 thorpej OF_exit(); 796 1.1 tsubai } 797 1.1 tsubai 798 1.1 tsubai void 799 1.15 aymeric putchar(int c) 800 1.1 tsubai { 801 1.1 tsubai char ch = c; 802 1.1 tsubai 803 1.1 tsubai if (c == '\n') 804 1.1 tsubai putchar('\r'); 805 1.35 thorpej OF_write(ofw_stdout, &ch, 1); 806 1.1 tsubai } 807 1.1 tsubai 808 1.1 tsubai int 809 1.15 aymeric getchar(void) 810 1.1 tsubai { 811 1.1 tsubai unsigned char ch = '\0'; 812 1.1 tsubai int l; 813 1.1 tsubai 814 1.35 thorpej while ((l = OF_read(ofw_stdin, &ch, 1)) != 1) 815 1.1 tsubai if (l != -2 && l != 0) 816 1.1 tsubai return -1; 817 1.1 tsubai return ch; 818 1.1 tsubai } 819