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