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