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