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