Home | History | Annotate | Line # | Download | only in ofwboot
Locore.c revision 1.21.2.1
      1 /*	$NetBSD: Locore.c,v 1.21.2.1 2006/09/09 02:41:14 rpaulo 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)(void *);
     42 
     43 static void startup(void *, int, int (*)(void *), char *, int)
     44 		__attribute__((__used__));
     45 static void setup(void);
     46 
     47 static int stack[8192/4 + 4] __attribute__((__used__));
     48 
     49 #ifdef XCOFF_GLUE
     50 __asm(
     51 "	.text			\n"
     52 "	.globl	_entry		\n"
     53 "_entry:			\n"
     54 "	.long	_start,0,0	\n"
     55 );
     56 #endif /* XCOFF_GLUE */
     57 
     58 __asm(
     59 "	.text			\n"
     60 "	.globl	_start		\n"
     61 "_start:			\n"
     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 "				\n"
     68 "	mfmsr	%r8		\n"
     69 "	li	%r0,0		\n"
     70 "	mtmsr	%r0		\n"
     71 "	isync			\n"
     72 "				\n"
     73 #if 0
     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 #endif /* 0 */
     91 "				\n"
     92 "	mtmsr	%r8		\n"
     93 "	isync			\n"
     94 "				\n"
     95 	/*
     96 	 * Make sure that .bss is zeroed
     97 	 */
     98 "				\n"
     99 "	li	%r0,0		\n"
    100 "	lis	%r8,_edata@ha	\n"
    101 "	addi	%r8,%r8,_edata@l\n"
    102 "	lis	%r9,_end@ha	\n"
    103 "	addi	%r9,%r9,_end@l	\n"
    104 "				\n"
    105 "5:	cmpw	0,%r8,%r9	\n"
    106 "	bge	6f		\n"
    107 "	stw	%r0,0(%r8)	\n"
    108 "	addi	%r8,%r8,4	\n"
    109 "	b	5b		\n"
    110 "				\n"
    111 "6:	b	startup		\n"
    112 );
    113 
    114 #if 0
    115 static int
    116 openfirmware(void *arg)
    117 {
    118 
    119 	__asm volatile ("sync; isync");
    120 	openfirmware_entry(arg);
    121 	__asm volatile ("sync; isync");
    122 }
    123 #endif
    124 
    125 static void
    126 startup(void *vpd, int res, int (*openfirm)(void *), char *arg, int argl)
    127 {
    128 
    129 	openfirmware = openfirm;
    130 	setup();
    131 	main();
    132 	OF_exit();
    133 }
    134 
    135 __dead void
    136 OF_exit(void)
    137 {
    138 	static struct {
    139 		const char *name;
    140 		int nargs;
    141 		int nreturns;
    142 	} args = {
    143 		"exit",
    144 		0,
    145 		0
    146 	};
    147 
    148 	openfirmware(&args);
    149 	for (;;);			/* just in case */
    150 }
    151 
    152 int
    153 OF_finddevice(const char *name)
    154 {
    155 	static struct {
    156 		const char *name;
    157 		int nargs;
    158 		int nreturns;
    159 		const char *device;
    160 		int phandle;
    161 	} args = {
    162 		"finddevice",
    163 		1,
    164 		1,
    165 	};
    166 
    167 	args.device = name;
    168 	if (openfirmware(&args) == -1)
    169 		return -1;
    170 	return args.phandle;
    171 }
    172 
    173 int
    174 OF_instance_to_package(int ihandle)
    175 {
    176 	static struct {
    177 		const char *name;
    178 		int nargs;
    179 		int nreturns;
    180 		int ihandle;
    181 		int phandle;
    182 	} args = {
    183 		"instance-to-package",
    184 		1,
    185 		1,
    186 	};
    187 
    188 	args.ihandle = ihandle;
    189 	if (openfirmware(&args) == -1)
    190 		return -1;
    191 	return args.phandle;
    192 }
    193 
    194 int
    195 OF_getprop(int handle, const char *prop, void *buf, int buflen)
    196 {
    197 	static struct {
    198 		const char *name;
    199 		int nargs;
    200 		int nreturns;
    201 		int phandle;
    202 		const 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(int handle, const char *prop, void *buf, int len)
    224 {
    225 	static struct {
    226 		const char *name;
    227 		int nargs;
    228 		int nreturns;
    229 		int phandle;
    230 		const 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(const char *dname)
    252 {
    253 	static struct {
    254 		const char *name;
    255 		int nargs;
    256 		int nreturns;
    257 		const 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(int handle)
    284 {
    285 	static struct {
    286 		const char *name;
    287 		int nargs;
    288 		int nreturns;
    289 		int handle;
    290 	} args = {
    291 		"close",
    292 		1,
    293 		0,
    294 	};
    295 
    296 #ifdef OFW_DEBUG
    297 	printf("OF_close(%d)\n", handle);
    298 #endif
    299 	args.handle = handle;
    300 	openfirmware(&args);
    301 }
    302 
    303 int
    304 OF_write(int handle, void *addr, int len)
    305 {
    306 	static struct {
    307 		const char *name;
    308 		int nargs;
    309 		int nreturns;
    310 		int ihandle;
    311 		void *addr;
    312 		int len;
    313 		int actual;
    314 	} args = {
    315 		"write",
    316 		3,
    317 		1,
    318 	};
    319 
    320 #ifdef OFW_DEBUG
    321 	if (len != 1)
    322 		printf("OF_write(%d, %p, %x) -> ", handle, addr, len);
    323 #endif
    324 	args.ihandle = handle;
    325 	args.addr = addr;
    326 	args.len = len;
    327 	if (openfirmware(&args) == -1) {
    328 #ifdef OFW_DEBUG
    329 		printf("lose\n");
    330 #endif
    331 		return -1;
    332 	}
    333 #ifdef OFW_DEBUG
    334 	if (len != 1)
    335 		printf("%x\n", args.actual);
    336 #endif
    337 	return args.actual;
    338 }
    339 
    340 int
    341 OF_read(int handle, void *addr, int len)
    342 {
    343 	static struct {
    344 		const char *name;
    345 		int nargs;
    346 		int nreturns;
    347 		int ihandle;
    348 		void *addr;
    349 		int len;
    350 		int actual;
    351 	} args = {
    352 		"read",
    353 		3,
    354 		1,
    355 	};
    356 
    357 #ifdef OFW_DEBUG
    358 	if (len != 1)
    359 		printf("OF_read(%d, %p, %x) -> ", handle, addr, len);
    360 #endif
    361 	args.ihandle = handle;
    362 	args.addr = addr;
    363 	args.len = len;
    364 	if (openfirmware(&args) == -1) {
    365 #ifdef OFW_DEBUG
    366 		printf("lose\n");
    367 #endif
    368 		return -1;
    369 	}
    370 #ifdef OFW_DEBUG
    371 	if (len != 1)
    372 		printf("%x\n", args.actual);
    373 #endif
    374 	return args.actual;
    375 }
    376 
    377 int
    378 OF_seek(int handle, u_quad_t pos)
    379 {
    380 	static struct {
    381 		const char *name;
    382 		int nargs;
    383 		int nreturns;
    384 		int handle;
    385 		int poshi;
    386 		int poslo;
    387 		int status;
    388 	} args = {
    389 		"seek",
    390 		3,
    391 		1,
    392 	};
    393 
    394 #ifdef OFW_DEBUG
    395 	printf("OF_seek(%d, %x, %x) -> ", handle, (int)(pos >> 32), (int)pos);
    396 #endif
    397 	args.handle = handle;
    398 	args.poshi = (int)(pos >> 32);
    399 	args.poslo = (int)pos;
    400 	if (openfirmware(&args) == -1) {
    401 #ifdef OFW_DEBUG
    402 		printf("lose\n");
    403 #endif
    404 		return -1;
    405 	}
    406 #ifdef OFW_DEBUG
    407 	printf("%d\n", args.status);
    408 #endif
    409 	return args.status;
    410 }
    411 
    412 void *
    413 OF_claim(void *virt, u_int size, u_int align)
    414 {
    415 	static struct {
    416 		const char *name;
    417 		int nargs;
    418 		int nreturns;
    419 		void *virt;
    420 		u_int size;
    421 		u_int align;
    422 		void *baseaddr;
    423 	} args = {
    424 		"claim",
    425 		3,
    426 		1,
    427 	};
    428 
    429 #ifdef OFW_DEBUG
    430 	printf("OF_claim(%p, %x, %x) -> ", virt, size, align);
    431 #endif
    432 	args.virt = virt;
    433 	args.size = size;
    434 	args.align = align;
    435 	if (openfirmware(&args) == -1) {
    436 #ifdef OFW_DEBUG
    437 		printf("lose\n");
    438 #endif
    439 		return (void *)-1;
    440 	}
    441 #ifdef OFW_DEBUG
    442 	printf("%p\n", args.baseaddr);
    443 #endif
    444 	return args.baseaddr;
    445 }
    446 
    447 void
    448 OF_release(void *virt, u_int size)
    449 {
    450 	static struct {
    451 		const char *name;
    452 		int nargs;
    453 		int nreturns;
    454 		void *virt;
    455 		u_int size;
    456 	} args = {
    457 		"release",
    458 		2,
    459 		0,
    460 	};
    461 
    462 #ifdef OFW_DEBUG
    463 	printf("OF_release(%p, %x)\n", virt, size);
    464 #endif
    465 	args.virt = virt;
    466 	args.size = size;
    467 	openfirmware(&args);
    468 }
    469 
    470 int
    471 OF_milliseconds(void)
    472 {
    473 	static struct {
    474 		const char *name;
    475 		int nargs;
    476 		int nreturns;
    477 		int ms;
    478 	} args = {
    479 		"milliseconds",
    480 		0,
    481 		1,
    482 	};
    483 
    484 	openfirmware(&args);
    485 	return args.ms;
    486 }
    487 
    488 #ifdef	__notyet__
    489 void
    490 OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len)
    491 {
    492 	static struct {
    493 		const char *name;
    494 		int nargs;
    495 		int nreturns;
    496 		void *virt;
    497 		u_int size;
    498 		void (*entry)();
    499 		void *arg;
    500 		u_int len;
    501 	} args = {
    502 		"chain",
    503 		5,
    504 		0,
    505 	};
    506 
    507 	args.virt = virt;
    508 	args.size = size;
    509 	args.entry = entry;
    510 	args.arg = arg;
    511 	args.len = len;
    512 	openfirmware(&args);
    513 }
    514 #else
    515 void
    516 OF_chain(void *virt, u_int size, boot_entry_t entry, void *arg, u_int len)
    517 {
    518 	/*
    519 	 * This is a REALLY dirty hack till the firmware gets this going
    520 	 */
    521 #if 0
    522 	OF_release(virt, size);
    523 #endif
    524 	entry(0, 0, openfirmware, arg, len);
    525 }
    526 #endif
    527 
    528 int
    529 OF_call_method(const char *method, int ihandle, int nargs, int nreturns, ...)
    530 {
    531 	va_list ap;
    532 	static struct {
    533 		const char *name;
    534 		int nargs;
    535 		int nreturns;
    536 		const char *method;
    537 		int ihandle;
    538 		int args_n_results[12];
    539 	} args = {
    540 		"call-method",
    541 		2,
    542 		1,
    543 	};
    544 	int *ip, n;
    545 
    546 	if (nargs > 6)
    547 		return -1;
    548 	args.nargs = nargs + 2;
    549 	args.nreturns = nreturns + 1;
    550 	args.method = method;
    551 	args.ihandle = ihandle;
    552 	va_start(ap, nreturns);
    553 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
    554 		*--ip = va_arg(ap, int);
    555 
    556 	if (openfirmware(&args) == -1) {
    557 		va_end(ap);
    558 		return -1;
    559 	}
    560 	if (args.args_n_results[nargs]) {
    561 		va_end(ap);
    562 		return args.args_n_results[nargs];
    563 	}
    564 	for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
    565 		*va_arg(ap, int *) = *--ip;
    566 	va_end(ap);
    567 	return 0;
    568 }
    569 
    570 static int stdin;
    571 static int stdout;
    572 
    573 static void
    574 setup(void)
    575 {
    576 	int chosen;
    577 
    578 	if ((chosen = OF_finddevice("/chosen")) == -1)
    579 		OF_exit();
    580 	if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) !=
    581 	    sizeof(stdin) ||
    582 	    OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) !=
    583 	    sizeof(stdout))
    584 		OF_exit();
    585 }
    586 
    587 void
    588 putchar(int c)
    589 {
    590 	char ch = c;
    591 
    592 	if (c == '\n')
    593 		putchar('\r');
    594 	OF_write(stdout, &ch, 1);
    595 }
    596 
    597 int
    598 getchar(void)
    599 {
    600 	unsigned char ch = '\0';
    601 	int l;
    602 
    603 	while ((l = OF_read(stdin, &ch, 1)) != 1)
    604 		if (l != -2 && l != 0)
    605 			return -1;
    606 	return ch;
    607 }
    608