1 /* $NetBSD: boot.c,v 1.6 2008/04/28 20:23:18 martin Exp $ */
4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <lib/libsa/stand.h>
33 #include <lib/libkern/libkern.h>
39 #include <machine/sbd.h>
40 #include <machine/pdinfo.h>
41 #include <machine/vtoc.h>
46 extern const char bootprog_name
[];
47 extern const char bootprog_rev
[];
48 extern const char bootprog_kernrev
[];
50 struct cmd_batch_tab cmd_batch_tab
[] = {
51 /* func argc argp... */
53 { cmd_boot
, 1, { "mem:", 0, 0, 0, 0, 0, 0 } },
54 { cmd_boot
, 1, { "sd0k:netbsd", 0, 0, 0, 0, 0, 0 } },
55 { cmd_load_binary
, 1, { "0x80001000", 0, 0, 0, 0, 0, 0 } },
56 { cmd_jump
, 2, { "0x80001000", "0x80001000", 0, 0, 0, 0, 0 } },
58 { NULL
, 0, { 0, 0, 0, 0, 0, 0, 0 } } /* terminate */
61 struct ipl_args ipl_args
;
62 struct device_capability DEVICE_CAPABILITY
;
63 void set_device_capability(void);
64 bool guess_boot_kernel(char *, size_t, int);
65 extern int kernel_binary_size
;
68 main(int a0
, int v0
, int v1
)
70 extern char edata
[], end
[];
72 char *args
[CMDARG_MAX
];
75 memset(edata
, 0, end
- edata
);
76 /* Save args for chain-boot to iopboot */
84 printf("%s boot, Revision %s (from NetBSD %s)\n",
85 bootprog_name
, bootprog_rev
, bootprog_kernrev
);
88 /* Inquire IPL activated device */
89 set_device_capability();
91 if (!guess_boot_kernel(boot_kernel
, sizeof boot_kernel
, 0))
94 ">> Press return to boot now, any other key for boot console.\n");
96 for (i
= 5000; i
>= 0; i
--) {
99 printf("booting %s - starting %d\r",
100 boot_kernel
, i
/ 1000);
101 if ((c
= cnscan()) == -1) {
110 printf("\n[non-interactive mode]\n");
112 args
[1] = boot_kernel
;
113 cmd_boot(2, args
, false);
116 printf("\ntype \"help\" for help.\n");
117 console_cursor(true);
123 guess_boot_kernel(char *name
, size_t len
, int pri
)
125 extern struct vtoc_sector vtoc
;
126 struct ux_partition
*partition
;
129 if (!DEVICE_CAPABILITY
.active
)
132 unit
= DEVICE_CAPABILITY
.booted_unit
;
134 switch (DEVICE_CAPABILITY
.booted_device
) {
137 case NVSRAM_BOOTDEV_FLOPPYDISK
:
138 strncpy(name
, "fd:netbsd", len
); /* ustarfs */
141 case NVSRAM_BOOTDEV_HARDDISK
:
142 snprintf(name
, len
, "sd%d:netbsd", unit
); /* ustarfs */
146 partition
= vtoc
.partition
;
147 for (i
= 0; i
< VTOC_MAXPARTITIONS
; i
++, partition
++) {
148 if (partition
->tag
!= __VTOC_TAG_BSDFFS
)
151 snprintf(name
, len
, "sd%d%c:netbsd", unit
, 'a' + i
);
156 case NVSRAM_BOOTDEV_CGMT
:
158 case NVSRAM_BOOTDEV_NETWORK
:
160 case NVSRAM_BOOTDEV_NETWORK_T_AND_D
:
161 if (kernel_binary_size
) {
162 strncpy(name
, "mem:", len
); /* datafs */
165 if (DEVICE_CAPABILITY
.network_enabled
) {
166 strncpy(name
, "nfs:netbsd", len
); /* nfs */
176 cmd_info(int argc
, char *argp
[], int interactive
)
178 extern char _ftext
[], _etext
[], _fdata
[], _edata
[];
179 extern char _fbss
[], end
[];
182 struct sbdinfo
*sbd
= SBD_INFO
;
184 printf("\n>> %s boot, Revision %s (from NetBSD %s) <<\n",
185 bootprog_name
, bootprog_rev
, bootprog_kernrev
);
187 printf("IPL args: 0x%x 0x%x 0x%x\n", ipl_args
.a0
, ipl_args
.v0
,
189 printf("\ttext : %p-%p\n\tdata : %p-%p\n\t"
190 "bss : %p-%p\n\tstack: %p\n\theap : %p\n",
191 _ftext
, _etext
, _fdata
, _edata
,
192 _fbss
, end
, _ftext
, end
);
196 printf("Memory Area:\n\t");
197 for (i
= 0; i
< 8; i
++, m
>>= 4) {
198 size
= m
& 0xf ? ((m
& 0xf) << 4) : 0;
201 printf("M%d=%dMB ", i
, size
);
203 printf(" total %dMB\n", total
);
205 printf("Board Revision:\n");
206 printf("\tmachine=0x%x, ", sbd
->machine
);
207 printf("model=0x%x\n", sbd
->model
);
208 printf("\tpmmu=%d, ", sbd
->mmu
);
209 printf("cache=%d, ", sbd
->cache
);
210 printf("panel=%d, ", sbd
->panel
);
211 printf("fdd=%d\n", sbd
->fdd
);
212 printf("\tcpu=%d, fpp=%d, fpa=%d, iop=%d\n",
213 sbd
->cpu
, sbd
->fpp
, sbd
->fpa
, sbd
->iop
);
214 printf("\tclock=%d\n", sbd
->clock
);
215 printf("\tipl=%d, cpu_ex=%d, fpp_ex=%d\n",
216 sbd
->ipl
, sbd
->cpu_ex
, sbd
->fpp_ex
);
217 printf("\tkbms=%d, sio=%d, battery=%d, scsi=%d\n",
218 sbd
->kbms
, sbd
->sio
, sbd
->battery
, sbd
->scsi
);
219 printf("model name=%s\n", sbd
->model_name
);
225 cmd_reboot(int argc
, char *argp
[], int interactive
)
230 bootdev
= strtoul(argp
[1], 0, 0); /* next boot device. */
231 if (bootdev
!= NVSRAM_BOOTDEV_FLOPPYDISK
&&
232 bootdev
!= NVSRAM_BOOTDEV_HARDDISK
&&
233 bootdev
!= NVSRAM_BOOTDEV_CGMT
&&
234 bootdev
!= NVSRAM_BOOTDEV_NETWORK
) {
235 printf("invalid boot device.");
239 switch (SBD_INFO
->machine
) {
242 *(uint8_t *)0xbe493030 = bootdev
;
243 *(volatile uint32_t *)0xbe000064 |= 0x80000000;
244 *(volatile uint8_t *)0xba000004 = 1;
245 *(uint8_t *)0xbfbffffc = 255;
249 *(uint8_t *)0xbb023030 = bootdev
;
250 *(volatile uint32_t *)0xbfb00000 |= 0x10;
256 while (/*CONSTCOND*/1)
263 set_device_capability(void)
265 const char *devname
[] = {
276 int booted_device
, booted_unit
, fd_format
;
278 boot_device(&booted_device
, &booted_unit
, &fd_format
);
279 if (booted_device
> NVSRAM_BOOTDEV_MAX
||
280 booted_device
< NVSRAM_BOOTDEV_MIN
) {
282 "invalid booted device. NVSRAM information isn't valid\n");
284 DEVICE_CAPABILITY
.booted_device
= booted_device
;
286 DEVICE_CAPABILITY
.booted_unit
= booted_unit
;
288 switch (SBD_INFO
->machine
) {
290 DEVICE_CAPABILITY
.active
= true;
291 /* boot has LANCE driver */
292 DEVICE_CAPABILITY
.network_enabled
= true;
295 DEVICE_CAPABILITY
.active
= true;
298 DEVICE_CAPABILITY
.active
= false;
302 DEVICE_CAPABILITY
.fd_enabled
= true; /* always enabled */
304 if (DEVICE_CAPABILITY
.active
) {
306 * When NETWORK IPL, FD IPL doesn't activate ROM DISK routine.
308 if (DEVICE_CAPABILITY
.booted_device
== NVSRAM_BOOTDEV_HARDDISK
)
309 DEVICE_CAPABILITY
.disk_enabled
= true;
312 printf("FD[%c] DISK[%c] NETWORK[%c] COMPILED[%c]\n",
313 DEVICE_CAPABILITY
.fd_enabled
? 'x' : '_',
314 DEVICE_CAPABILITY
.disk_enabled
? 'x' : '_',
315 DEVICE_CAPABILITY
.network_enabled
? 'x' : '_',
316 kernel_binary_size
? 'x' : '_');
318 printf("booted from %s IPL", devname
[DEVICE_CAPABILITY
.booted_device
]);
319 if ((DEVICE_CAPABILITY
.booted_device
== NVSRAM_BOOTDEV_NETWORK
) ||
320 (DEVICE_CAPABILITY
.booted_device
== NVSRAM_BOOTDEV_NETWORK_T_AND_D
))
324 printf(" unit %d\n", DEVICE_CAPABILITY
.booted_unit
);
329 cmd_test(int argc
, char *argp
[], int interactive
)
332 /* MISC TEST ROUTINE */
333 extern int fdd_test(void);
338 printf("argc=%d\n", argc
);
339 for (i
= 0; i
< argc
; i
++)
340 printf("[%d] %s\n", i
, argp
[i
]);
342 #if 0 /* Recover my 360ADII NVSRAM.. */
343 uint8_t *p
= (uint8_t *)0xbe490000;
344 uint8_t *q
= nvsram_tr2a
;
347 for (i
= 0; i
< sizeof nvsram_tr2a
; i
++) {
353 #if 0 /* ROM PUTC test */
354 char a
[]= "ohayotest!";
356 for (i
= 0; i
< 10; i
++)
357 ROM_PUTC(120 + i
* 12, 24 * 10, a
[i
]);
359 #if 0 /* ROM SCSI disk routine test TR2 */
364 printf("type=%d\n", *(uint8_t *)0xbb023034);
365 memset(buf
, 0, sizeof buf
);
366 p
= (uint8_t *)(((uint32_t)buf
+ 511) & ~511);
367 i
= ROM_DK_READ(0, 0, 1, p
);
368 printf("err=%d\n", i
);
369 for (i
= 0; i
< 64; i
++) {
371 if (((i
+ 1) & 0xf) == 0)
380 "mtc0 $4, $16;" /* Config */
394 "mtc0 %0, $12;" /* Cu1 */
402 printf("FPUId: %x\n", v
);