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