1 /* $NetBSD: bootxx.c,v 1.17 2009/03/14 15:36:09 dsl Exp $ */
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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
45 int32_t __attribute__((aligned(16))) stack
[8192 + 8];
47 struct shared_bbinfo bbinfo
= {
48 { MACPPC_BBINFO_MAGIC
},
50 SHARED_BBINFO_MAXBLOCKS
,
54 #ifndef DEFAULT_ENTRY_POINT
55 #define DEFAULT_ENTRY_POINT 0xE00000
58 void (*entry_point
)(int, int, void *) = (void *)DEFAULT_ENTRY_POINT
;
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) */
74 " addi %r8,%r8,0x20 \n"
82 " li %r8,0x1ffe \n" /* map the lowest 256MB */
83 " li %r9,0x22 \n" /* BAT_I */
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 */
102 OF_finddevice(char *name
)
123 OF_getprop(int handle
, char *prop
, void *buf
, int buflen
)
140 args
.phandle
= handle
;
143 args
.buflen
= buflen
;
171 OF_read(int handle
, void *addr
, int len
)
187 args
.ihandle
= handle
;
196 OF_seek(int handle
, u_quad_t pos
)
212 args
.handle
= handle
;
213 args
.poshi
= (int)(pos
>> 32);
214 args
.poslo
= (int)pos
;
221 OF_write(int handle
, const void *addr
, int len
)
237 args
.ihandle
= handle
;
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)
258 startup(int arg1
, int arg2
, void *openfirm
)
260 int fd
, blk
, chosen
, options
, j
;
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
))
280 * "scsi/sd@0:0" --> "scsi/sd@0"
282 for (i
= 0; i
< sizeof(bootpath
); i
++) {
283 if (bootpath
[i
] == ':')
285 if (bootpath
[i
] == 0)
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)
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");
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 */