bootxx.c revision 1.5.12.2 1 1.5.12.2 nathanw /* $NetBSD: bootxx.c,v 1.5.12.2 2002/11/11 22:00:16 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.5.12.2 nathanw asm(
62 1.5.12.2 nathanw " .text \n"
63 1.5.12.2 nathanw " .align 2 \n"
64 1.5.12.2 nathanw " .globl _start \n"
65 1.5.12.2 nathanw "_start: \n"
66 1.5.12.2 nathanw
67 1.5.12.2 nathanw " lis %r8,(_start)@ha \n"
68 1.5.12.2 nathanw " addi %r8,8,(_start)@l\n"
69 1.5.12.2 nathanw " li %r9,0x40 \n" /* loop 64 times (for 2048 bytes of bootxx) */
70 1.5.12.2 nathanw " mtctr %r9 \n"
71 1.5.12.2 nathanw "1: \n"
72 1.5.12.2 nathanw " dcbf %r0,%r8 \n"
73 1.5.12.2 nathanw " icbi %r0,%r8 \n"
74 1.5.12.2 nathanw " addi %r8,%r8,0x20 \n"
75 1.5.12.2 nathanw " bdnz 1b \n"
76 1.5.12.2 nathanw " sync \n"
77 1.5.12.2 nathanw
78 1.5.12.2 nathanw " li %r0,0 \n"
79 1.5.12.2 nathanw " mtdbatu 3,%r0 \n"
80 1.5.12.2 nathanw " mtibatu 3,%r0 \n"
81 1.5.12.2 nathanw " isync \n"
82 1.5.12.2 nathanw " li %r8,0x1ffe \n" /* map the lowest 256MB */
83 1.5.12.2 nathanw " li %r9,0x22 \n" /* BAT_I */
84 1.5.12.2 nathanw " mtdbatl 3,%r9 \n"
85 1.5.12.2 nathanw " mtdbatu 3,%r8 \n"
86 1.5.12.2 nathanw " mtibatl 3,%r9 \n"
87 1.5.12.2 nathanw " mtibatu 3,%r8 \n"
88 1.5.12.2 nathanw " isync \n"
89 1.5.12.2 nathanw
90 1.5.12.2 nathanw /*
91 1.5.12.2 nathanw * setup 32 KB of stack with 32 bytes overpad (see above)
92 1.5.12.2 nathanw */
93 1.5.12.2 nathanw " lis %r1,(stack+32768)@ha\n"
94 1.5.12.2 nathanw " addi %r1,%r1,(stack+32768)@l\n"
95 1.5.12.2 nathanw " stw %r0,0(%r1) \n" /* terminate the frame link chain */
96 1.1 tsubai
97 1.5.12.2 nathanw " b startup \n"
98 1.5.12.2 nathanw );
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 int
177 1.1 tsubai OF_read(handle, addr, len)
178 1.1 tsubai int handle;
179 1.1 tsubai void *addr;
180 1.1 tsubai int len;
181 1.1 tsubai {
182 1.1 tsubai static struct {
183 1.1 tsubai char *name;
184 1.1 tsubai int nargs;
185 1.1 tsubai int nreturns;
186 1.1 tsubai int ihandle;
187 1.1 tsubai void *addr;
188 1.1 tsubai int len;
189 1.1 tsubai int actual;
190 1.1 tsubai } args = {
191 1.1 tsubai "read",
192 1.1 tsubai 3,
193 1.1 tsubai 1,
194 1.1 tsubai };
195 1.1 tsubai
196 1.1 tsubai args.ihandle = handle;
197 1.1 tsubai args.addr = addr;
198 1.1 tsubai args.len = len;
199 1.1 tsubai openfirmware(&args);
200 1.1 tsubai
201 1.1 tsubai return args.actual;
202 1.1 tsubai }
203 1.1 tsubai
204 1.1 tsubai static __inline int
205 1.1 tsubai OF_seek(handle, pos)
206 1.1 tsubai int handle;
207 1.1 tsubai u_quad_t pos;
208 1.1 tsubai {
209 1.1 tsubai static struct {
210 1.1 tsubai char *name;
211 1.1 tsubai int nargs;
212 1.1 tsubai int nreturns;
213 1.1 tsubai int handle;
214 1.1 tsubai int poshi;
215 1.1 tsubai int poslo;
216 1.1 tsubai int status;
217 1.1 tsubai } args = {
218 1.1 tsubai "seek",
219 1.1 tsubai 3,
220 1.1 tsubai 1,
221 1.1 tsubai };
222 1.1 tsubai
223 1.1 tsubai args.handle = handle;
224 1.1 tsubai args.poshi = (int)(pos >> 32);
225 1.1 tsubai args.poslo = (int)pos;
226 1.1 tsubai openfirmware(&args);
227 1.1 tsubai
228 1.1 tsubai return args.status;
229 1.1 tsubai }
230 1.1 tsubai
231 1.5.12.1 nathanw static __inline int
232 1.5.12.1 nathanw OF_write(handle, addr, len)
233 1.5.12.1 nathanw int handle;
234 1.5.12.1 nathanw void *addr;
235 1.5.12.1 nathanw int len;
236 1.5.12.1 nathanw {
237 1.5.12.1 nathanw static struct {
238 1.5.12.1 nathanw char *name;
239 1.5.12.1 nathanw int nargs;
240 1.5.12.1 nathanw int nreturns;
241 1.5.12.1 nathanw int ihandle;
242 1.5.12.1 nathanw void *addr;
243 1.5.12.1 nathanw int len;
244 1.5.12.1 nathanw int actual;
245 1.5.12.1 nathanw } args = {
246 1.5.12.1 nathanw "write",
247 1.5.12.1 nathanw 3,
248 1.5.12.1 nathanw 1,
249 1.5.12.1 nathanw };
250 1.5.12.1 nathanw
251 1.5.12.1 nathanw args.ihandle = handle;
252 1.5.12.1 nathanw args.addr = addr;
253 1.5.12.1 nathanw args.len = len;
254 1.5.12.1 nathanw openfirmware(&args);
255 1.5.12.1 nathanw
256 1.5.12.1 nathanw return args.actual;
257 1.5.12.1 nathanw }
258 1.5.12.1 nathanw
259 1.5.12.1 nathanw int stdout;
260 1.5.12.1 nathanw
261 1.5.12.1 nathanw void
262 1.5.12.1 nathanw putstrn(const char *s, size_t n)
263 1.5.12.1 nathanw {
264 1.5.12.1 nathanw OF_write(stdout, s, n);
265 1.5.12.1 nathanw }
266 1.5.12.1 nathanw
267 1.5.12.1 nathanw #define putstr(x) putstrn((x),sizeof(x)-1)
268 1.5.12.1 nathanw #define putc(x) do { char __x = (x) ; putstrn(&__x, 1); } while (0)
269 1.5.12.1 nathanw
270 1.5.12.1 nathanw
271 1.1 tsubai void
272 1.1 tsubai startup(arg1, arg2, openfirm)
273 1.1 tsubai int arg1, arg2;
274 1.1 tsubai void *openfirm;
275 1.1 tsubai {
276 1.5.12.1 nathanw int fd, blk, chosen, options, i;
277 1.1 tsubai char *addr;
278 1.4 tsubai char bootpath[128];
279 1.4 tsubai
280 1.1 tsubai openfirmware = openfirm;
281 1.1 tsubai
282 1.1 tsubai chosen = OF_finddevice("/chosen");
283 1.4 tsubai if (OF_getprop(chosen, "bootpath", bootpath, sizeof(bootpath)) == 1) {
284 1.4 tsubai /*
285 1.4 tsubai * buggy firmware doesn't set bootpath...
286 1.4 tsubai */
287 1.4 tsubai options = OF_finddevice("/options");
288 1.4 tsubai OF_getprop(options, "boot-device", bootpath, sizeof(bootpath));
289 1.4 tsubai }
290 1.5.12.1 nathanw if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout))
291 1.5.12.1 nathanw != sizeof(stdout))
292 1.5.12.1 nathanw stdout = -1;
293 1.1 tsubai
294 1.1 tsubai /*
295 1.1 tsubai * "scsi/sd@0:0" --> "scsi/sd@0"
296 1.1 tsubai */
297 1.5.12.1 nathanw for (i = 0; i < sizeof(bootpath); i++) {
298 1.1 tsubai if (bootpath[i] == ':')
299 1.1 tsubai bootpath[i] = 0;
300 1.5.12.1 nathanw if (bootpath[i] == 0)
301 1.5.12.1 nathanw break;
302 1.5.12.1 nathanw }
303 1.1 tsubai
304 1.5.12.1 nathanw putstr("\r\nOF_open bootpath=");
305 1.5.12.1 nathanw putstrn(bootpath, i);
306 1.1 tsubai fd = OF_open(bootpath);
307 1.1 tsubai
308 1.2 tsubai addr = (char *)entry_point;
309 1.5.12.1 nathanw putstr("\r\nread stage 2 blocks: ");
310 1.5.12.1 nathanw for (i = 0; i < bbinfo.bbi_block_count; i++) {
311 1.5.12.1 nathanw if ((blk = bbinfo.bbi_block_table[i]) == 0)
312 1.5.12.1 nathanw break;
313 1.5.12.1 nathanw putc('0' + i % 10);
314 1.1 tsubai OF_seek(fd, (u_quad_t)blk * 512);
315 1.5.12.1 nathanw OF_read(fd, addr, bbinfo.bbi_block_size);
316 1.5.12.1 nathanw addr += bbinfo.bbi_block_size;
317 1.1 tsubai }
318 1.5.12.1 nathanw putstr(". done!\r\nstarting stage 2...\r\n");
319 1.1 tsubai
320 1.1 tsubai /*
321 1.1 tsubai * enable D/I cache
322 1.1 tsubai */
323 1.1 tsubai asm("
324 1.1 tsubai mtdbatu 3,%0
325 1.1 tsubai mtdbatl 3,%1
326 1.1 tsubai mtibatu 3,%0
327 1.1 tsubai mtibatl 3,%1
328 1.1 tsubai isync
329 1.5 thorpej " :: "r"(BATU(0, BAT_BL_256M, BAT_Vs)),
330 1.5 thorpej "r"(BATL(0, 0, BAT_PP_RW)));
331 1.1 tsubai
332 1.2 tsubai entry_point(0, 0, openfirm);
333 1.4 tsubai for (;;); /* just in case */
334 1.1 tsubai }
335