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