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