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