Home | History | Annotate | Line # | Download | only in bootxx
bootxx.c revision 1.5.12.1
      1  1.5.12.1  nathanw /*	$NetBSD: bootxx.c,v 1.5.12.1 2002/06/20 03:39:41 nathanw Exp $	*/
      2       1.1   tsubai 
      3       1.1   tsubai /*
      4       1.1   tsubai  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
      5       1.1   tsubai  * Copyright (C) 1995, 1996 TooLs GmbH.
      6       1.1   tsubai  * All rights reserved.
      7       1.1   tsubai  *
      8       1.1   tsubai  * Redistribution and use in source and binary forms, with or without
      9       1.1   tsubai  * modification, are permitted provided that the following conditions
     10       1.1   tsubai  * are met:
     11       1.1   tsubai  * 1. Redistributions of source code must retain the above copyright
     12       1.1   tsubai  *    notice, this list of conditions and the following disclaimer.
     13       1.1   tsubai  * 2. Redistributions in binary form must reproduce the above copyright
     14       1.1   tsubai  *    notice, this list of conditions and the following disclaimer in the
     15       1.1   tsubai  *    documentation and/or other materials provided with the distribution.
     16       1.1   tsubai  * 3. All advertising materials mentioning features or use of this software
     17       1.1   tsubai  *    must display the following acknowledgement:
     18       1.1   tsubai  *	This product includes software developed by TooLs GmbH.
     19       1.1   tsubai  * 4. The name of TooLs GmbH may not be used to endorse or promote products
     20       1.1   tsubai  *    derived from this software without specific prior written permission.
     21       1.1   tsubai  *
     22       1.1   tsubai  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
     23       1.1   tsubai  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24       1.1   tsubai  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25       1.1   tsubai  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26       1.1   tsubai  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     27       1.1   tsubai  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     28       1.1   tsubai  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     29       1.1   tsubai  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     30       1.1   tsubai  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     31       1.1   tsubai  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32       1.1   tsubai  */
     33       1.1   tsubai 
     34       1.1   tsubai #include <sys/types.h>
     35       1.1   tsubai #include <machine/bat.h>
     36       1.1   tsubai 
     37  1.5.12.1  nathanw #include <sys/bootblock.h>
     38  1.5.12.1  nathanw 
     39       1.1   tsubai int (*openfirmware)(void *);
     40       1.1   tsubai 
     41  1.5.12.1  nathanw 				/*
     42  1.5.12.1  nathanw 				 * 32 KB of stack with 32 bytes overpad
     43  1.5.12.1  nathanw 				 * (see below)
     44  1.5.12.1  nathanw 				 */
     45  1.5.12.1  nathanw int32_t __attribute__((aligned(16))) stack[8192 + 8];
     46  1.5.12.1  nathanw 
     47  1.5.12.1  nathanw struct shared_bbinfo bbinfo = {
     48  1.5.12.1  nathanw 	{ MACPPC_BBINFO_MAGIC },
     49  1.5.12.1  nathanw 	0,
     50  1.5.12.1  nathanw 	SHARED_BBINFO_MAXBLOCKS,
     51  1.5.12.1  nathanw 	{ 0 }
     52  1.5.12.1  nathanw };
     53  1.5.12.1  nathanw 
     54  1.5.12.1  nathanw #ifndef DEFAULT_ENTRY_POINT
     55  1.5.12.1  nathanw #define	DEFAULT_ENTRY_POINT	0x600000
     56  1.5.12.1  nathanw #endif
     57  1.5.12.1  nathanw 
     58  1.5.12.1  nathanw void (*entry_point)(int, int, void *) = (void *)DEFAULT_ENTRY_POINT;
     59       1.1   tsubai 
     60       1.1   tsubai 
     61       1.1   tsubai asm("
     62       1.1   tsubai 	.text
     63       1.1   tsubai 	.align 2
     64       1.1   tsubai 	.globl	_start
     65       1.1   tsubai _start:
     66       1.1   tsubai 
     67  1.5.12.1  nathanw 	lis	8,(_start)@ha
     68  1.5.12.1  nathanw 	addi	8,8,(_start)@l
     69  1.5.12.1  nathanw 	li	9,0x40		/* loop 64 times (for 2048 bytes of bootxx) */
     70       1.1   tsubai 	mtctr	9
     71       1.1   tsubai 1:
     72       1.1   tsubai 	dcbf	0,8
     73       1.1   tsubai 	icbi	0,8
     74       1.1   tsubai 	addi	8,8,0x20
     75       1.1   tsubai 	bdnz	1b
     76       1.1   tsubai 	sync
     77       1.1   tsubai 
     78       1.3   tsubai 	li	0,0
     79       1.3   tsubai 	mtdbatu	3,0
     80       1.3   tsubai 	mtibatu	3,0
     81       1.3   tsubai 	isync
     82       1.1   tsubai 	li	8,0x1ffe	/* map the lowest 256MB */
     83       1.1   tsubai 	li	9,0x22		/* BAT_I */
     84       1.3   tsubai 	mtdbatl	3,9
     85       1.1   tsubai 	mtdbatu	3,8
     86       1.3   tsubai 	mtibatl	3,9
     87       1.1   tsubai 	mtibatu	3,8
     88       1.1   tsubai 	isync
     89       1.1   tsubai 
     90  1.5.12.1  nathanw 				/*
     91  1.5.12.1  nathanw 				 * setup 32 KB of stack with 32 bytes overpad
     92  1.5.12.1  nathanw 				 * (see above)
     93  1.5.12.1  nathanw 				 */
     94  1.5.12.1  nathanw 	lis	1,(stack  + 4 * 8192)@ha
     95  1.5.12.1  nathanw 	addi	1,1,(stack+ 4 * 8192)@l
     96  1.5.12.1  nathanw 	stw	0,0(1)		/* terminate the frame link chain */
     97       1.1   tsubai 
     98       1.1   tsubai 	b	startup
     99       1.1   tsubai ");
    100       1.1   tsubai 
    101       1.1   tsubai 
    102       1.1   tsubai static __inline int
    103       1.1   tsubai OF_finddevice(name)
    104       1.1   tsubai 	char *name;
    105       1.1   tsubai {
    106       1.1   tsubai 	static struct {
    107       1.1   tsubai 		char *name;
    108       1.1   tsubai 		int nargs;
    109       1.1   tsubai 		int nreturns;
    110       1.1   tsubai 		char *device;
    111       1.1   tsubai 		int phandle;
    112       1.1   tsubai 	} args = {
    113       1.1   tsubai 		"finddevice",
    114       1.1   tsubai 		1,
    115       1.1   tsubai 		1,
    116       1.1   tsubai 	};
    117       1.1   tsubai 
    118       1.1   tsubai 	args.device = name;
    119       1.1   tsubai 	openfirmware(&args);
    120       1.1   tsubai 
    121       1.1   tsubai 	return args.phandle;
    122       1.1   tsubai }
    123       1.1   tsubai 
    124       1.1   tsubai static __inline int
    125       1.1   tsubai OF_getprop(handle, prop, buf, buflen)
    126       1.1   tsubai 	int handle;
    127       1.1   tsubai 	char *prop;
    128       1.1   tsubai 	void *buf;
    129       1.1   tsubai 	int buflen;
    130       1.1   tsubai {
    131       1.1   tsubai 	static struct {
    132       1.1   tsubai 		char *name;
    133       1.1   tsubai 		int nargs;
    134       1.1   tsubai 		int nreturns;
    135       1.1   tsubai 		int phandle;
    136       1.1   tsubai 		char *prop;
    137       1.1   tsubai 		void *buf;
    138       1.1   tsubai 		int buflen;
    139       1.1   tsubai 		int size;
    140       1.1   tsubai 	} args = {
    141       1.1   tsubai 		"getprop",
    142       1.1   tsubai 		4,
    143       1.1   tsubai 		1,
    144       1.1   tsubai 	};
    145       1.1   tsubai 
    146       1.1   tsubai 	args.phandle = handle;
    147       1.1   tsubai 	args.prop = prop;
    148       1.1   tsubai 	args.buf = buf;
    149       1.1   tsubai 	args.buflen = buflen;
    150       1.1   tsubai 	openfirmware(&args);
    151       1.1   tsubai 
    152       1.1   tsubai 	return args.size;
    153       1.1   tsubai }
    154       1.1   tsubai 
    155       1.1   tsubai static __inline int
    156       1.1   tsubai OF_open(dname)
    157       1.1   tsubai 	char *dname;
    158       1.1   tsubai {
    159       1.1   tsubai 	static struct {
    160       1.1   tsubai 		char *name;
    161       1.1   tsubai 		int nargs;
    162       1.1   tsubai 		int nreturns;
    163       1.1   tsubai 		char *dname;
    164       1.1   tsubai 		int handle;
    165       1.1   tsubai 	} args = {
    166       1.1   tsubai 		"open",
    167       1.1   tsubai 		1,
    168       1.1   tsubai 		1,
    169       1.1   tsubai 	};
    170       1.1   tsubai 
    171       1.1   tsubai 	args.dname = dname;
    172       1.1   tsubai 	openfirmware(&args);
    173       1.1   tsubai 
    174       1.1   tsubai 	return args.handle;
    175       1.1   tsubai }
    176       1.1   tsubai 
    177       1.1   tsubai static __inline int
    178       1.1   tsubai OF_read(handle, addr, len)
    179       1.1   tsubai 	int handle;
    180       1.1   tsubai 	void *addr;
    181       1.1   tsubai 	int len;
    182       1.1   tsubai {
    183       1.1   tsubai 	static struct {
    184       1.1   tsubai 		char *name;
    185       1.1   tsubai 		int nargs;
    186       1.1   tsubai 		int nreturns;
    187       1.1   tsubai 		int ihandle;
    188       1.1   tsubai 		void *addr;
    189       1.1   tsubai 		int len;
    190       1.1   tsubai 		int actual;
    191       1.1   tsubai 	} args = {
    192       1.1   tsubai 		"read",
    193       1.1   tsubai 		3,
    194       1.1   tsubai 		1,
    195       1.1   tsubai 	};
    196       1.1   tsubai 
    197       1.1   tsubai 	args.ihandle = handle;
    198       1.1   tsubai 	args.addr = addr;
    199       1.1   tsubai 	args.len = len;
    200       1.1   tsubai 	openfirmware(&args);
    201       1.1   tsubai 
    202       1.1   tsubai 	return args.actual;
    203       1.1   tsubai }
    204       1.1   tsubai 
    205       1.1   tsubai static __inline int
    206       1.1   tsubai OF_seek(handle, pos)
    207       1.1   tsubai 	int handle;
    208       1.1   tsubai 	u_quad_t pos;
    209       1.1   tsubai {
    210       1.1   tsubai 	static struct {
    211       1.1   tsubai 		char *name;
    212       1.1   tsubai 		int nargs;
    213       1.1   tsubai 		int nreturns;
    214       1.1   tsubai 		int handle;
    215       1.1   tsubai 		int poshi;
    216       1.1   tsubai 		int poslo;
    217       1.1   tsubai 		int status;
    218       1.1   tsubai 	} args = {
    219       1.1   tsubai 		"seek",
    220       1.1   tsubai 		3,
    221       1.1   tsubai 		1,
    222       1.1   tsubai 	};
    223       1.1   tsubai 
    224       1.1   tsubai 	args.handle = handle;
    225       1.1   tsubai 	args.poshi = (int)(pos >> 32);
    226       1.1   tsubai 	args.poslo = (int)pos;
    227       1.1   tsubai 	openfirmware(&args);
    228       1.1   tsubai 
    229       1.1   tsubai 	return args.status;
    230       1.1   tsubai }
    231       1.1   tsubai 
    232  1.5.12.1  nathanw static __inline int
    233  1.5.12.1  nathanw OF_write(handle, addr, len)
    234  1.5.12.1  nathanw 	int handle;
    235  1.5.12.1  nathanw 	void *addr;
    236  1.5.12.1  nathanw 	int len;
    237  1.5.12.1  nathanw {
    238  1.5.12.1  nathanw 	static struct {
    239  1.5.12.1  nathanw 		char *name;
    240  1.5.12.1  nathanw 		int nargs;
    241  1.5.12.1  nathanw 		int nreturns;
    242  1.5.12.1  nathanw 		int ihandle;
    243  1.5.12.1  nathanw 		void *addr;
    244  1.5.12.1  nathanw 		int len;
    245  1.5.12.1  nathanw 		int actual;
    246  1.5.12.1  nathanw 	} args = {
    247  1.5.12.1  nathanw 		"write",
    248  1.5.12.1  nathanw 		3,
    249  1.5.12.1  nathanw 		1,
    250  1.5.12.1  nathanw 	};
    251  1.5.12.1  nathanw 
    252  1.5.12.1  nathanw 	args.ihandle = handle;
    253  1.5.12.1  nathanw 	args.addr = addr;
    254  1.5.12.1  nathanw 	args.len = len;
    255  1.5.12.1  nathanw 	openfirmware(&args);
    256  1.5.12.1  nathanw 
    257  1.5.12.1  nathanw 	return args.actual;
    258  1.5.12.1  nathanw }
    259  1.5.12.1  nathanw 
    260  1.5.12.1  nathanw int stdout;
    261  1.5.12.1  nathanw 
    262  1.5.12.1  nathanw void
    263  1.5.12.1  nathanw putstrn(const char *s, size_t n)
    264  1.5.12.1  nathanw {
    265  1.5.12.1  nathanw 	OF_write(stdout, s, n);
    266  1.5.12.1  nathanw }
    267  1.5.12.1  nathanw 
    268  1.5.12.1  nathanw #define putstr(x)	putstrn((x),sizeof(x)-1)
    269  1.5.12.1  nathanw #define putc(x)		do { char __x = (x) ; putstrn(&__x, 1); } while (0)
    270  1.5.12.1  nathanw 
    271  1.5.12.1  nathanw 
    272       1.1   tsubai void
    273       1.1   tsubai startup(arg1, arg2, openfirm)
    274       1.1   tsubai 	int arg1, arg2;
    275       1.1   tsubai 	void *openfirm;
    276       1.1   tsubai {
    277  1.5.12.1  nathanw 	int fd, blk, chosen, options, i;
    278       1.1   tsubai 	char *addr;
    279       1.4   tsubai 	char bootpath[128];
    280       1.4   tsubai 
    281       1.1   tsubai 	openfirmware = openfirm;
    282       1.1   tsubai 
    283       1.1   tsubai 	chosen = OF_finddevice("/chosen");
    284       1.4   tsubai 	if (OF_getprop(chosen, "bootpath", bootpath, sizeof(bootpath)) == 1) {
    285       1.4   tsubai 		/*
    286       1.4   tsubai 		 * buggy firmware doesn't set bootpath...
    287       1.4   tsubai 		 */
    288       1.4   tsubai 		options = OF_finddevice("/options");
    289       1.4   tsubai 		OF_getprop(options, "boot-device", bootpath, sizeof(bootpath));
    290       1.4   tsubai 	}
    291  1.5.12.1  nathanw 	if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout))
    292  1.5.12.1  nathanw 	    != sizeof(stdout))
    293  1.5.12.1  nathanw 		stdout = -1;
    294       1.1   tsubai 
    295       1.1   tsubai 	/*
    296       1.1   tsubai 	 * "scsi/sd@0:0" --> "scsi/sd@0"
    297       1.1   tsubai 	 */
    298  1.5.12.1  nathanw 	for (i = 0; i < sizeof(bootpath); i++) {
    299       1.1   tsubai 		if (bootpath[i] == ':')
    300       1.1   tsubai 			bootpath[i] = 0;
    301  1.5.12.1  nathanw 		if (bootpath[i] == 0)
    302  1.5.12.1  nathanw 			break;
    303  1.5.12.1  nathanw 	}
    304       1.1   tsubai 
    305  1.5.12.1  nathanw 	putstr("\r\nOF_open bootpath=");
    306  1.5.12.1  nathanw 	putstrn(bootpath, i);
    307       1.1   tsubai 	fd = OF_open(bootpath);
    308       1.1   tsubai 
    309       1.2   tsubai 	addr = (char *)entry_point;
    310  1.5.12.1  nathanw 	putstr("\r\nread stage 2 blocks: ");
    311  1.5.12.1  nathanw 	for (i = 0; i < bbinfo.bbi_block_count; i++) {
    312  1.5.12.1  nathanw 		if ((blk = bbinfo.bbi_block_table[i]) == 0)
    313  1.5.12.1  nathanw 			break;
    314  1.5.12.1  nathanw 		putc('0' + i % 10);
    315       1.1   tsubai 		OF_seek(fd, (u_quad_t)blk * 512);
    316  1.5.12.1  nathanw 		OF_read(fd, addr, bbinfo.bbi_block_size);
    317  1.5.12.1  nathanw 		addr += bbinfo.bbi_block_size;
    318       1.1   tsubai 	}
    319  1.5.12.1  nathanw 	putstr(". done!\r\nstarting stage 2...\r\n");
    320       1.1   tsubai 
    321       1.1   tsubai 	/*
    322       1.1   tsubai 	 * enable D/I cache
    323       1.1   tsubai 	 */
    324       1.1   tsubai 	asm("
    325       1.1   tsubai 		mtdbatu	3,%0
    326       1.1   tsubai 		mtdbatl	3,%1
    327       1.1   tsubai 		mtibatu	3,%0
    328       1.1   tsubai 		mtibatl	3,%1
    329       1.1   tsubai 		isync
    330       1.5  thorpej 	" :: "r"(BATU(0, BAT_BL_256M, BAT_Vs)),
    331       1.5  thorpej 	     "r"(BATL(0, 0, BAT_PP_RW)));
    332       1.1   tsubai 
    333       1.2   tsubai 	entry_point(0, 0, openfirm);
    334       1.4   tsubai 	for (;;);			/* just in case */
    335       1.1   tsubai }
    336