No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / macppc / stand / bootxx / bootxx.c
blobe3999f152420488ebac1477cb8c0f192c4314353
1 /* $NetBSD: bootxx.c,v 1.17 2009/03/14 15:36:09 dsl Exp $ */
3 /*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved.
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.
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.
34 #include <sys/types.h>
35 #include <powerpc/oea/bat.h>
37 #include <sys/bootblock.h>
39 int (*openfirmware)(void *);
42 * 32 KB of stack with 32 bytes overpad
43 * (see below)
45 int32_t __attribute__((aligned(16))) stack[8192 + 8];
47 struct shared_bbinfo bbinfo = {
48 { MACPPC_BBINFO_MAGIC },
50 SHARED_BBINFO_MAXBLOCKS,
51 { 0 }
54 #ifndef DEFAULT_ENTRY_POINT
55 #define DEFAULT_ENTRY_POINT 0xE00000
56 #endif
58 void (*entry_point)(int, int, void *) = (void *)DEFAULT_ENTRY_POINT;
61 __asm(
62 " .text \n"
63 " .align 2 \n"
64 " .globl _start \n"
65 "_start: \n"
67 " lis %r8,(_start)@ha \n"
68 " addi %r8,8,(_start)@l\n"
69 " li %r9,0x40 \n" /* loop 64 times (for 2048 bytes of bootxx) */
70 " mtctr %r9 \n"
71 "1: \n"
72 " dcbf %r0,%r8 \n"
73 " icbi %r0,%r8 \n"
74 " addi %r8,%r8,0x20 \n"
75 " bdnz 1b \n"
76 " sync \n"
78 " li %r0,0 \n"
79 " mtdbatu 3,%r0 \n"
80 " mtibatu 3,%r0 \n"
81 " isync \n"
82 " li %r8,0x1ffe \n" /* map the lowest 256MB */
83 " li %r9,0x22 \n" /* BAT_I */
84 " mtdbatl 3,%r9 \n"
85 " mtdbatu 3,%r8 \n"
86 " mtibatl 3,%r9 \n"
87 " mtibatu 3,%r8 \n"
88 " isync \n"
91 * setup 32 KB of stack with 32 bytes overpad (see above)
93 " lis %r1,(stack+32768)@ha\n"
94 " addi %r1,%r1,(stack+32768)@l\n"
95 " stw %r0,0(%r1) \n" /* terminate the frame link chain */
97 " b startup \n"
101 static inline int
102 OF_finddevice(char *name)
104 static struct {
105 char *name;
106 int nargs;
107 int nreturns;
108 char *device;
109 int phandle;
110 } args = {
111 "finddevice",
116 args.device = name;
117 openfirmware(&args);
119 return args.phandle;
122 static inline int
123 OF_getprop(int handle, char *prop, void *buf, int buflen)
125 static struct {
126 char *name;
127 int nargs;
128 int nreturns;
129 int phandle;
130 char *prop;
131 void *buf;
132 int buflen;
133 int size;
134 } args = {
135 "getprop",
140 args.phandle = handle;
141 args.prop = prop;
142 args.buf = buf;
143 args.buflen = buflen;
144 openfirmware(&args);
146 return args.size;
149 static inline int
150 OF_open(char *dname)
152 static struct {
153 char *name;
154 int nargs;
155 int nreturns;
156 char *dname;
157 int handle;
158 } args = {
159 "open",
164 args.dname = dname;
165 openfirmware(&args);
167 return args.handle;
170 static inline int
171 OF_read(int handle, void *addr, int len)
173 static struct {
174 char *name;
175 int nargs;
176 int nreturns;
177 int ihandle;
178 void *addr;
179 int len;
180 int actual;
181 } args = {
182 "read",
187 args.ihandle = handle;
188 args.addr = addr;
189 args.len = len;
190 openfirmware(&args);
192 return args.actual;
195 static inline int
196 OF_seek(int handle, u_quad_t pos)
198 static struct {
199 char *name;
200 int nargs;
201 int nreturns;
202 int handle;
203 int poshi;
204 int poslo;
205 int status;
206 } args = {
207 "seek",
212 args.handle = handle;
213 args.poshi = (int)(pos >> 32);
214 args.poslo = (int)pos;
215 openfirmware(&args);
217 return args.status;
220 static inline int
221 OF_write(int handle, const void *addr, int len)
223 static struct {
224 char *name;
225 int nargs;
226 int nreturns;
227 int ihandle;
228 const void *addr;
229 int len;
230 int actual;
231 } args = {
232 "write",
237 args.ihandle = handle;
238 args.addr = addr;
239 args.len = len;
240 openfirmware(&args);
242 return args.actual;
245 int stdout;
247 void
248 putstrn(const char *s, size_t n)
250 OF_write(stdout, s, n);
253 #define putstr(x) putstrn((x),sizeof(x)-1)
254 #define putc(x) do { char __x = (x) ; putstrn(&__x, 1); } while (0)
257 void
258 startup(int arg1, int arg2, void *openfirm)
260 int fd, blk, chosen, options, j;
261 size_t i;
262 char *addr;
263 char bootpath[128];
265 openfirmware = openfirm;
267 chosen = OF_finddevice("/chosen");
268 if (OF_getprop(chosen, "bootpath", bootpath, sizeof(bootpath)) == 1) {
270 * buggy firmware doesn't set bootpath...
272 options = OF_finddevice("/options");
273 OF_getprop(options, "boot-device", bootpath, sizeof(bootpath));
275 if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout))
276 != sizeof(stdout))
277 stdout = -1;
280 * "scsi/sd@0:0" --> "scsi/sd@0"
282 for (i = 0; i < sizeof(bootpath); i++) {
283 if (bootpath[i] == ':')
284 bootpath[i] = 0;
285 if (bootpath[i] == 0)
286 break;
289 putstr("\r\nOF_open bootpath=");
290 putstrn(bootpath, i);
291 fd = OF_open(bootpath);
293 addr = (char *)entry_point;
294 putstr("\r\nread stage 2 blocks: ");
295 for (j = 0; j < bbinfo.bbi_block_count; j++) {
296 if ((blk = bbinfo.bbi_block_table[j]) == 0)
297 break;
298 putc('0' + j % 10);
299 OF_seek(fd, (u_quad_t)blk * 512);
300 OF_read(fd, addr, bbinfo.bbi_block_size);
301 addr += bbinfo.bbi_block_size;
303 putstr(". done!\r\nstarting stage 2...\r\n");
306 * enable D/I cache
308 __asm(
309 "mtdbatu 3,%0\n\t"
310 "mtdbatl 3,%1\n\t"
311 "mtibatu 3,%0\n\t"
312 "mtibatl 3,%1\n\t"
313 "isync"
314 :: "r"(BATU(0, BAT_BL_256M, BAT_Vs)),
315 "r"(BATL(0, 0, BAT_PP_RW)));
317 entry_point(0, 0, openfirm);
318 for (;;); /* just in case */