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