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