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