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