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