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