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