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