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