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