bootxx.c revision 1.4 1 1.4 tsubai /* $NetBSD: bootxx.c,v 1.4 1998/07/13 17:35:55 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.4 tsubai #define MAXBLOCKNUM 30
41 1.1 tsubai
42 1.4 tsubai void (*entry_point)(int, int, void *) = (void *)0;
43 1.1 tsubai int block_size = 0;
44 1.1 tsubai int block_count = MAXBLOCKNUM;
45 1.1 tsubai int block_table[MAXBLOCKNUM] = { 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
63 1.3 tsubai li 0,0
64 1.3 tsubai mtdbatu 3,0
65 1.3 tsubai mtibatu 3,0
66 1.3 tsubai isync
67 1.1 tsubai li 8,0x1ffe /* map the lowest 256MB */
68 1.1 tsubai li 9,0x22 /* BAT_I */
69 1.3 tsubai mtdbatl 3,9
70 1.1 tsubai mtdbatu 3,8
71 1.3 tsubai mtibatl 3,9
72 1.1 tsubai mtibatu 3,8
73 1.1 tsubai isync
74 1.1 tsubai
75 1.4 tsubai li 1,(stack+4096)@l /* setup 4KB of stack */
76 1.1 tsubai
77 1.1 tsubai b startup
78 1.1 tsubai ");
79 1.1 tsubai
80 1.1 tsubai
81 1.1 tsubai static __inline int
82 1.1 tsubai OF_finddevice(name)
83 1.1 tsubai char *name;
84 1.1 tsubai {
85 1.1 tsubai static struct {
86 1.1 tsubai char *name;
87 1.1 tsubai int nargs;
88 1.1 tsubai int nreturns;
89 1.1 tsubai char *device;
90 1.1 tsubai int phandle;
91 1.1 tsubai } args = {
92 1.1 tsubai "finddevice",
93 1.1 tsubai 1,
94 1.1 tsubai 1,
95 1.1 tsubai };
96 1.1 tsubai
97 1.1 tsubai args.device = name;
98 1.1 tsubai openfirmware(&args);
99 1.1 tsubai
100 1.1 tsubai return args.phandle;
101 1.1 tsubai }
102 1.1 tsubai
103 1.1 tsubai static __inline int
104 1.1 tsubai OF_getprop(handle, prop, buf, buflen)
105 1.1 tsubai int handle;
106 1.1 tsubai char *prop;
107 1.1 tsubai void *buf;
108 1.1 tsubai int buflen;
109 1.1 tsubai {
110 1.1 tsubai static struct {
111 1.1 tsubai char *name;
112 1.1 tsubai int nargs;
113 1.1 tsubai int nreturns;
114 1.1 tsubai int phandle;
115 1.1 tsubai char *prop;
116 1.1 tsubai void *buf;
117 1.1 tsubai int buflen;
118 1.1 tsubai int size;
119 1.1 tsubai } args = {
120 1.1 tsubai "getprop",
121 1.1 tsubai 4,
122 1.1 tsubai 1,
123 1.1 tsubai };
124 1.1 tsubai
125 1.1 tsubai args.phandle = handle;
126 1.1 tsubai args.prop = prop;
127 1.1 tsubai args.buf = buf;
128 1.1 tsubai args.buflen = buflen;
129 1.1 tsubai openfirmware(&args);
130 1.1 tsubai
131 1.1 tsubai return args.size;
132 1.1 tsubai }
133 1.1 tsubai
134 1.1 tsubai static __inline int
135 1.1 tsubai OF_open(dname)
136 1.1 tsubai char *dname;
137 1.1 tsubai {
138 1.1 tsubai static struct {
139 1.1 tsubai char *name;
140 1.1 tsubai int nargs;
141 1.1 tsubai int nreturns;
142 1.1 tsubai char *dname;
143 1.1 tsubai int handle;
144 1.1 tsubai } args = {
145 1.1 tsubai "open",
146 1.1 tsubai 1,
147 1.1 tsubai 1,
148 1.1 tsubai };
149 1.1 tsubai
150 1.1 tsubai args.dname = dname;
151 1.1 tsubai openfirmware(&args);
152 1.1 tsubai
153 1.1 tsubai return args.handle;
154 1.1 tsubai }
155 1.1 tsubai
156 1.1 tsubai static __inline int
157 1.1 tsubai OF_read(handle, addr, len)
158 1.1 tsubai int handle;
159 1.1 tsubai void *addr;
160 1.1 tsubai int len;
161 1.1 tsubai {
162 1.1 tsubai static struct {
163 1.1 tsubai char *name;
164 1.1 tsubai int nargs;
165 1.1 tsubai int nreturns;
166 1.1 tsubai int ihandle;
167 1.1 tsubai void *addr;
168 1.1 tsubai int len;
169 1.1 tsubai int actual;
170 1.1 tsubai } args = {
171 1.1 tsubai "read",
172 1.1 tsubai 3,
173 1.1 tsubai 1,
174 1.1 tsubai };
175 1.1 tsubai
176 1.1 tsubai args.ihandle = handle;
177 1.1 tsubai args.addr = addr;
178 1.1 tsubai args.len = len;
179 1.1 tsubai openfirmware(&args);
180 1.1 tsubai
181 1.1 tsubai return args.actual;
182 1.1 tsubai }
183 1.1 tsubai
184 1.1 tsubai static __inline int
185 1.1 tsubai OF_seek(handle, pos)
186 1.1 tsubai int handle;
187 1.1 tsubai u_quad_t pos;
188 1.1 tsubai {
189 1.1 tsubai static struct {
190 1.1 tsubai char *name;
191 1.1 tsubai int nargs;
192 1.1 tsubai int nreturns;
193 1.1 tsubai int handle;
194 1.1 tsubai int poshi;
195 1.1 tsubai int poslo;
196 1.1 tsubai int status;
197 1.1 tsubai } args = {
198 1.1 tsubai "seek",
199 1.1 tsubai 3,
200 1.1 tsubai 1,
201 1.1 tsubai };
202 1.1 tsubai
203 1.1 tsubai args.handle = handle;
204 1.1 tsubai args.poshi = (int)(pos >> 32);
205 1.1 tsubai args.poslo = (int)pos;
206 1.1 tsubai openfirmware(&args);
207 1.1 tsubai
208 1.1 tsubai return args.status;
209 1.1 tsubai }
210 1.1 tsubai
211 1.1 tsubai void
212 1.1 tsubai startup(arg1, arg2, openfirm)
213 1.1 tsubai int arg1, arg2;
214 1.1 tsubai void *openfirm;
215 1.1 tsubai {
216 1.4 tsubai int fd, blk, chosen, options;
217 1.4 tsubai int i, bs;
218 1.1 tsubai char *addr;
219 1.4 tsubai char bootpath[128];
220 1.4 tsubai
221 1.1 tsubai openfirmware = openfirm;
222 1.1 tsubai
223 1.1 tsubai chosen = OF_finddevice("/chosen");
224 1.4 tsubai if (OF_getprop(chosen, "bootpath", bootpath, sizeof(bootpath)) == 1) {
225 1.4 tsubai /*
226 1.4 tsubai * buggy firmware doesn't set bootpath...
227 1.4 tsubai */
228 1.4 tsubai options = OF_finddevice("/options");
229 1.4 tsubai OF_getprop(options, "boot-device", bootpath, sizeof(bootpath));
230 1.4 tsubai }
231 1.1 tsubai
232 1.1 tsubai /*
233 1.1 tsubai * "scsi/sd@0:0" --> "scsi/sd@0"
234 1.1 tsubai */
235 1.1 tsubai for (i = 0; i < sizeof(bootpath); i++)
236 1.1 tsubai if (bootpath[i] == ':')
237 1.1 tsubai bootpath[i] = 0;
238 1.1 tsubai
239 1.1 tsubai fd = OF_open(bootpath);
240 1.1 tsubai
241 1.2 tsubai addr = (char *)entry_point;
242 1.4 tsubai bs = block_size;
243 1.1 tsubai for (i = 0; i < block_count; i++) {
244 1.1 tsubai blk = block_table[i];
245 1.1 tsubai
246 1.1 tsubai OF_seek(fd, (u_quad_t)blk * 512);
247 1.4 tsubai OF_read(fd, addr, bs);
248 1.4 tsubai addr += bs;
249 1.1 tsubai }
250 1.1 tsubai
251 1.1 tsubai /*
252 1.1 tsubai * enable D/I cache
253 1.1 tsubai */
254 1.1 tsubai asm("
255 1.1 tsubai mtdbatu 3,%0
256 1.1 tsubai mtdbatl 3,%1
257 1.1 tsubai mtibatu 3,%0
258 1.1 tsubai mtibatl 3,%1
259 1.1 tsubai isync
260 1.1 tsubai " :: "r"(BATU(0)), "r"(BATL(0, 0)));
261 1.1 tsubai
262 1.2 tsubai entry_point(0, 0, openfirm);
263 1.4 tsubai for (;;); /* just in case */
264 1.1 tsubai }
265