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