Home | History | Annotate | Line # | Download | only in bootxx
bootxx.c revision 1.2
      1 /*	$NetBSD: bootxx.c,v 1.2 1998/06/26 12:29:28 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 <sys/types.h>
     35 #include <machine/bat.h>
     36 
     37 int (*openfirmware)(void *);
     38 int stack[1024];
     39 
     40 #define MAXBLOCKNUM 32
     41 
     42 int block_size = 0;
     43 int block_count = MAXBLOCKNUM;
     44 int block_table[MAXBLOCKNUM] = { 0 };
     45 void (*entry_point)(int, int, void *) = (void *)0;
     46 
     47 asm("
     48 	.text
     49 	.align 2
     50 	.globl	_start
     51 _start:
     52 
     53 	li	8,0x4000	/* _start */
     54 	li	9,0x100
     55 	mtctr	9
     56 1:
     57 	dcbf	0,8
     58 	icbi	0,8
     59 	addi	8,8,0x20
     60 	bdnz	1b
     61 	sync
     62 	isync
     63 
     64 	li	8,0x1ffe	/* map the lowest 256MB */
     65 	li	9,0x22		/* BAT_I */
     66 	mtdbatu	3,8
     67 	mtdbatl	3,9
     68 	mtibatu	3,8
     69 	mtibatl	3,9
     70 	isync
     71 
     72 	lis	1,stack@ha	/* setup 4KB of stack */
     73 	addi	1,1,stack@l
     74 	addi	1,1,4096
     75 
     76 	b	startup
     77 ");
     78 
     79 
     80 static __inline void
     81 OF_exit()
     82 {
     83 	static struct {
     84 		char *name;
     85 		int nargs;
     86 		int nreturns;
     87 	} args = {
     88 		"exit",
     89 		0,
     90 		0
     91 	};
     92 
     93 	openfirmware(&args);
     94 	for (;;);			/* just in case */
     95 }
     96 
     97 static __inline int
     98 OF_finddevice(name)
     99 	char *name;
    100 {
    101 	static struct {
    102 		char *name;
    103 		int nargs;
    104 		int nreturns;
    105 		char *device;
    106 		int phandle;
    107 	} args = {
    108 		"finddevice",
    109 		1,
    110 		1,
    111 	};
    112 
    113 	args.device = name;
    114 	openfirmware(&args);
    115 
    116 	return args.phandle;
    117 }
    118 
    119 static __inline int
    120 OF_getprop(handle, prop, buf, buflen)
    121 	int handle;
    122 	char *prop;
    123 	void *buf;
    124 	int buflen;
    125 {
    126 	static struct {
    127 		char *name;
    128 		int nargs;
    129 		int nreturns;
    130 		int phandle;
    131 		char *prop;
    132 		void *buf;
    133 		int buflen;
    134 		int size;
    135 	} args = {
    136 		"getprop",
    137 		4,
    138 		1,
    139 	};
    140 
    141 	args.phandle = handle;
    142 	args.prop = prop;
    143 	args.buf = buf;
    144 	args.buflen = buflen;
    145 	openfirmware(&args);
    146 
    147 	return args.size;
    148 }
    149 
    150 static __inline int
    151 OF_open(dname)
    152 	char *dname;
    153 {
    154 	static struct {
    155 		char *name;
    156 		int nargs;
    157 		int nreturns;
    158 		char *dname;
    159 		int handle;
    160 	} args = {
    161 		"open",
    162 		1,
    163 		1,
    164 	};
    165 
    166 	args.dname = dname;
    167 	openfirmware(&args);
    168 
    169 	return args.handle;
    170 }
    171 
    172 static __inline void
    173 OF_close(handle)
    174 	int handle;
    175 {
    176 	static struct {
    177 		char *name;
    178 		int nargs;
    179 		int nreturns;
    180 		int handle;
    181 	} args = {
    182 		"close",
    183 		1,
    184 		0,
    185 	};
    186 
    187 	args.handle = handle;
    188 	openfirmware(&args);
    189 }
    190 
    191 static __inline int
    192 OF_read(handle, addr, len)
    193 	int handle;
    194 	void *addr;
    195 	int len;
    196 {
    197 	static struct {
    198 		char *name;
    199 		int nargs;
    200 		int nreturns;
    201 		int ihandle;
    202 		void *addr;
    203 		int len;
    204 		int actual;
    205 	} args = {
    206 		"read",
    207 		3,
    208 		1,
    209 	};
    210 
    211 	args.ihandle = handle;
    212 	args.addr = addr;
    213 	args.len = len;
    214 	openfirmware(&args);
    215 
    216 	return args.actual;
    217 }
    218 
    219 static __inline int
    220 OF_seek(handle, pos)
    221 	int handle;
    222 	u_quad_t pos;
    223 {
    224 	static struct {
    225 		char *name;
    226 		int nargs;
    227 		int nreturns;
    228 		int handle;
    229 		int poshi;
    230 		int poslo;
    231 		int status;
    232 	} args = {
    233 		"seek",
    234 		3,
    235 		1,
    236 	};
    237 
    238 	args.handle = handle;
    239 	args.poshi = (int)(pos >> 32);
    240 	args.poslo = (int)pos;
    241 	openfirmware(&args);
    242 
    243 	return args.status;
    244 }
    245 
    246 
    247 char bootpath[128];
    248 
    249 void
    250 startup(arg1, arg2, openfirm)
    251 	int arg1, arg2;
    252 	void *openfirm;
    253 {
    254 	int fd, blk, chosen;
    255 	int i;
    256 	char *addr;
    257 
    258 	openfirmware = openfirm;
    259 
    260 	chosen = OF_finddevice("/chosen");
    261 	OF_getprop(chosen, "bootpath", bootpath, sizeof(bootpath));
    262 
    263 	/*
    264 	 * "scsi/sd@0:0" --> "scsi/sd@0"
    265 	 */
    266 	for (i = 0; i < sizeof(bootpath); i++)
    267 		if (bootpath[i] == ':')
    268 			bootpath[i] = 0;
    269 
    270 	fd = OF_open(bootpath);
    271 
    272 	addr = (char *)entry_point;
    273 	for (i = 0; i < block_count; i++) {
    274 		blk = block_table[i];
    275 
    276 		OF_seek(fd, (u_quad_t)blk * 512);
    277 		OF_read(fd, addr, block_size);
    278 		addr += block_size;
    279 	}
    280 
    281 	/*
    282 	 * enable D/I cache
    283 	 */
    284 	asm("
    285 		mtdbatu	3,%0
    286 		mtdbatl	3,%1
    287 		mtibatu	3,%0
    288 		mtibatl	3,%1
    289 		isync
    290 	" :: "r"(BATU(0)), "r"(BATL(0, 0)));
    291 
    292 	entry_point(0, 0, openfirm);
    293 
    294 	OF_exit();
    295 	for (;;);
    296 }
    297