1 /* $NetBSD: Locore.c,v 1.8 2002/10/25 18:19:43 briggs 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 #include <lib/libsa/stand.h> 35 36 #include <machine/cpu.h> 37 38 #include "openfirm.h" 39 40 static int (*openfirmware_entry) __P((void *)); 41 static int openfirmware __P((void *)); 42 43 static void startup __P((void *, int, int (*)(void *), char *, int)); 44 static void setup __P((void)); 45 46 static int stack[8192/4 + 4]; 47 48 asm(" 49 .text 50 .globl _start 51 _start: 52 li 8,0 53 li 9,0x100 54 mtctr 9 55 1: 56 dcbf 0,8 57 icbi 0,8 58 addi 8,8,0x20 59 bdnz 1b 60 sync 61 isync 62 63 lis 1,stack@ha 64 addi 1,1,stack@l 65 addi 1,1,8192 66 b startup 67 "); 68 69 static int 70 openfirmware(arg) 71 void *arg; 72 { 73 74 asm volatile ("sync; isync"); 75 openfirmware_entry(arg); 76 asm volatile ("sync; isync"); 77 } 78 79 static void 80 startup(vpd, res, openfirm, arg, argl) 81 void *vpd; 82 int res; 83 int (*openfirm)(void *); 84 char *arg; 85 int argl; 86 { 87 extern char etext[], _end[], _edata[]; 88 89 memset(_edata, 0, (_end - _edata)); 90 openfirmware_entry = openfirm; 91 setup(); 92 main(); 93 OF_exit(); 94 } 95 96 __dead void 97 OF_exit() 98 { 99 static struct { 100 char *name; 101 int nargs; 102 int nreturns; 103 } args = { 104 "exit", 105 0, 106 0 107 }; 108 109 openfirmware(&args); 110 for (;;); /* just in case */ 111 } 112 113 __dead void 114 OF_boot(bootspec) 115 char *bootspec; 116 { 117 static struct { 118 char *name; 119 int nargs; 120 int nreturns; 121 char *bootspec; 122 } args = { 123 "boot", 124 1, 125 0, 126 }; 127 128 args.bootspec = bootspec; 129 openfirmware(&args); 130 for (;;); /* just is case */ 131 } 132 133 int 134 OF_finddevice(name) 135 char *name; 136 { 137 static struct { 138 char *name; 139 int nargs; 140 int nreturns; 141 char *device; 142 int phandle; 143 } args = { 144 "finddevice", 145 1, 146 1, 147 }; 148 149 args.device = name; 150 if (openfirmware(&args) == -1) 151 return -1; 152 return args.phandle; 153 } 154 155 int 156 OF_instance_to_package(ihandle) 157 int ihandle; 158 { 159 static struct { 160 char *name; 161 int nargs; 162 int nreturns; 163 int ihandle; 164 int phandle; 165 } args = { 166 "instance-to-package", 167 1, 168 1, 169 }; 170 171 args.ihandle = ihandle; 172 if (openfirmware(&args) == -1) 173 return -1; 174 return args.phandle; 175 } 176 177 int 178 OF_getprop(handle, prop, buf, buflen) 179 int handle; 180 char *prop; 181 void *buf; 182 int buflen; 183 { 184 static struct { 185 char *name; 186 int nargs; 187 int nreturns; 188 int phandle; 189 char *prop; 190 void *buf; 191 int buflen; 192 int size; 193 } args = { 194 "getprop", 195 4, 196 1, 197 }; 198 199 args.phandle = handle; 200 args.prop = prop; 201 args.buf = buf; 202 args.buflen = buflen; 203 if (openfirmware(&args) == -1) 204 return -1; 205 return args.size; 206 } 207 208 #ifdef __notyet__ /* Has a bug on FirePower */ 209 int 210 OF_setprop(handle, prop, buf, len) 211 int handle; 212 char *prop; 213 void *buf; 214 int len; 215 { 216 static struct { 217 char *name; 218 int nargs; 219 int nreturns; 220 int phandle; 221 char *prop; 222 void *buf; 223 int len; 224 int size; 225 } args = { 226 "setprop", 227 4, 228 1, 229 }; 230 231 args.phandle = handle; 232 args.prop = prop; 233 args.buf = buf; 234 args.len = len; 235 if (openfirmware(&args) == -1) 236 return -1; 237 return args.size; 238 } 239 #endif 240 241 int 242 OF_open(dname) 243 char *dname; 244 { 245 static struct { 246 char *name; 247 int nargs; 248 int nreturns; 249 char *dname; 250 int handle; 251 } args = { 252 "open", 253 1, 254 1, 255 }; 256 257 #ifdef OFW_DEBUG 258 printf("OF_open(%s) -> ", dname); 259 #endif 260 args.dname = dname; 261 if (openfirmware(&args) == -1 || 262 args.handle == 0) { 263 #ifdef OFW_DEBUG 264 printf("lose\n"); 265 #endif 266 return -1; 267 } 268 #ifdef OFW_DEBUG 269 printf("%d\n", args.handle); 270 #endif 271 return args.handle; 272 } 273 274 void 275 OF_close(handle) 276 int handle; 277 { 278 static struct { 279 char *name; 280 int nargs; 281 int nreturns; 282 int handle; 283 } args = { 284 "close", 285 1, 286 0, 287 }; 288 289 #ifdef OFW_DEBUG 290 printf("OF_close(%d)\n", handle); 291 #endif 292 args.handle = handle; 293 openfirmware(&args); 294 } 295 296 int 297 OF_write(handle, addr, len) 298 int handle; 299 void *addr; 300 int len; 301 { 302 static struct { 303 char *name; 304 int nargs; 305 int nreturns; 306 int ihandle; 307 void *addr; 308 int len; 309 int actual; 310 } args = { 311 "write", 312 3, 313 1, 314 }; 315 316 #ifdef OFW_DEBUG 317 if (len != 1) 318 printf("OF_write(%d, %x, %x) -> ", handle, addr, len); 319 #endif 320 args.ihandle = handle; 321 args.addr = addr; 322 args.len = len; 323 if (openfirmware(&args) == -1) { 324 #ifdef OFW_DEBUG 325 printf("lose\n"); 326 #endif 327 return -1; 328 } 329 #ifdef OFW_DEBUG 330 if (len != 1) 331 printf("%x\n", args.actual); 332 #endif 333 return args.actual; 334 } 335 336 int 337 OF_read(handle, addr, len) 338 int handle; 339 void *addr; 340 int len; 341 { 342 static struct { 343 char *name; 344 int nargs; 345 int nreturns; 346 int ihandle; 347 void *addr; 348 int len; 349 int actual; 350 } args = { 351 "read", 352 3, 353 1, 354 }; 355 356 #ifdef OFW_DEBUG 357 if (len != 1) 358 printf("OF_read(%d, %x, %x) -> ", handle, addr, len); 359 #endif 360 args.ihandle = handle; 361 args.addr = addr; 362 args.len = len; 363 if (openfirmware(&args) == -1) { 364 #ifdef OFW_DEBUG 365 printf("lose\n"); 366 #endif 367 return -1; 368 } 369 #ifdef OFW_DEBUG 370 if (len != 1) 371 printf("%x\n", args.actual); 372 #endif 373 return args.actual; 374 } 375 376 int 377 OF_seek(handle, pos) 378 int handle; 379 u_quad_t pos; 380 { 381 static struct { 382 char *name; 383 int nargs; 384 int nreturns; 385 int handle; 386 int poshi; 387 int poslo; 388 int status; 389 } args = { 390 "seek", 391 3, 392 1, 393 }; 394 395 #ifdef OFW_DEBUG 396 printf("OF_seek(%d, %x, %x) -> ", handle, (int)(pos >> 32), (int)pos); 397 #endif 398 args.handle = handle; 399 args.poshi = (int)(pos >> 32); 400 args.poslo = (int)pos; 401 if (openfirmware(&args) == -1) { 402 #ifdef OFW_DEBUG 403 printf("lose\n"); 404 #endif 405 return -1; 406 } 407 #ifdef OFW_DEBUG 408 printf("%d\n", args.status); 409 #endif 410 return args.status; 411 } 412 413 void * 414 OF_claim(virt, size, align) 415 void *virt; 416 u_int size; 417 u_int align; 418 { 419 static struct { 420 char *name; 421 int nargs; 422 int nreturns; 423 void *virt; 424 u_int size; 425 u_int align; 426 void *baseaddr; 427 } args = { 428 "claim", 429 3, 430 1, 431 }; 432 433 #ifdef OFW_DEBUG 434 printf("OF_claim(%x, %x, %x) -> ", virt, size, align); 435 #endif 436 args.virt = virt; 437 args.size = size; 438 args.align = align; 439 if (openfirmware(&args) == -1) { 440 #ifdef OFW_DEBUG 441 printf("lose\n"); 442 #endif 443 return (void *)-1; 444 } 445 #ifdef OFW_DEBUG 446 printf("%x\n", args.baseaddr); 447 #endif 448 return args.baseaddr; 449 } 450 451 void 452 OF_release(virt, size) 453 void *virt; 454 u_int size; 455 { 456 static struct { 457 char *name; 458 int nargs; 459 int nreturns; 460 void *virt; 461 u_int size; 462 } args = { 463 "release", 464 2, 465 0, 466 }; 467 468 #ifdef OFW_DEBUG 469 printf("OF_release(%x, %x)\n", virt, size); 470 #endif 471 args.virt = virt; 472 args.size = size; 473 openfirmware(&args); 474 } 475 476 int 477 OF_milliseconds() 478 { 479 static struct { 480 char *name; 481 int nargs; 482 int nreturns; 483 int ms; 484 } args = { 485 "milliseconds", 486 0, 487 1, 488 }; 489 490 openfirmware(&args); 491 return args.ms; 492 } 493 494 #ifdef __notyet__ 495 void 496 OF_chain(virt, size, entry, arg, len) 497 void *virt; 498 u_int size; 499 void (*entry)(); 500 void *arg; 501 u_int len; 502 { 503 static struct { 504 char *name; 505 int nargs; 506 int nreturns; 507 void *virt; 508 u_int size; 509 void (*entry)(); 510 void *arg; 511 u_int len; 512 } args = { 513 "chain", 514 5, 515 0, 516 }; 517 518 args.virt = virt; 519 args.size = size; 520 args.entry = entry; 521 args.arg = arg; 522 args.len = len; 523 openfirmware(&args); 524 } 525 #else 526 void 527 OF_chain(virt, size, entry, arg, len) 528 void *virt; 529 u_int size; 530 void (*entry)(); 531 void *arg; 532 u_int len; 533 { 534 /* 535 * This is a REALLY dirty hack till the firmware gets this going 536 */ 537 #if 1 538 OF_release(virt, size); 539 #endif 540 entry(0, 0, openfirmware_entry, arg, len); 541 } 542 #endif 543 544 static int stdin; 545 static int stdout; 546 547 static void 548 setup() 549 { 550 int chosen; 551 552 if ((chosen = OF_finddevice("/chosen")) == -1) 553 OF_exit(); 554 if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) != 555 sizeof(stdin) || 556 OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) != 557 sizeof(stdout)) 558 OF_exit(); 559 } 560 561 void 562 putchar(c) 563 int c; 564 { 565 char ch = c; 566 567 if (c == '\n') 568 putchar('\r'); 569 OF_write(stdout, &ch, 1); 570 } 571 572 int 573 getchar() 574 { 575 unsigned char ch = '\0'; 576 int l; 577 578 while ((l = OF_read(stdin, &ch, 1)) != 1) 579 if (l != -2 && l != 0) 580 return -1; 581 return ch; 582 } 583