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