Home | History | Annotate | Line # | Download | only in common
boot.c revision 1.5.46.1
      1  1.5.46.1     yamt /*	$NetBSD: boot.c,v 1.5.46.1 2008/05/16 02:22:20 yamt Exp $	*/
      2       1.1  tsutsui 
      3       1.1  tsutsui /*-
      4       1.1  tsutsui  * Copyright (c) 2004 The NetBSD Foundation, Inc.
      5       1.1  tsutsui  * All rights reserved.
      6       1.1  tsutsui  *
      7       1.1  tsutsui  * This code is derived from software contributed to The NetBSD Foundation
      8       1.1  tsutsui  * by UCHIYAMA Yasushi.
      9       1.1  tsutsui  *
     10       1.1  tsutsui  * Redistribution and use in source and binary forms, with or without
     11       1.1  tsutsui  * modification, are permitted provided that the following conditions
     12       1.1  tsutsui  * are met:
     13       1.1  tsutsui  * 1. Redistributions of source code must retain the above copyright
     14       1.1  tsutsui  *    notice, this list of conditions and the following disclaimer.
     15       1.1  tsutsui  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1  tsutsui  *    notice, this list of conditions and the following disclaimer in the
     17       1.1  tsutsui  *    documentation and/or other materials provided with the distribution.
     18       1.1  tsutsui  *
     19       1.1  tsutsui  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20       1.1  tsutsui  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21       1.1  tsutsui  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22       1.1  tsutsui  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23       1.1  tsutsui  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24       1.1  tsutsui  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25       1.1  tsutsui  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26       1.1  tsutsui  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27       1.1  tsutsui  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28       1.1  tsutsui  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29       1.1  tsutsui  * POSSIBILITY OF SUCH DAMAGE.
     30       1.1  tsutsui  */
     31       1.1  tsutsui 
     32       1.1  tsutsui #include <lib/libsa/stand.h>
     33       1.1  tsutsui #include <lib/libkern/libkern.h>
     34       1.1  tsutsui 
     35       1.1  tsutsui #include "local.h"
     36       1.1  tsutsui #include "cmd.h"
     37       1.1  tsutsui #include "common.h"
     38       1.1  tsutsui 
     39       1.1  tsutsui #include <machine/sbd.h>
     40       1.1  tsutsui #include <machine/pdinfo.h>
     41       1.1  tsutsui #include <machine/vtoc.h>
     42       1.1  tsutsui 
     43       1.1  tsutsui #include "console.h"
     44       1.1  tsutsui 
     45       1.1  tsutsui 
     46       1.1  tsutsui extern const char bootprog_name[];
     47       1.1  tsutsui extern const char bootprog_rev[];
     48       1.1  tsutsui extern const char bootprog_date[];
     49       1.1  tsutsui extern const char bootprog_maker[];
     50       1.1  tsutsui 
     51       1.1  tsutsui struct cmd_batch_tab cmd_batch_tab[] = {
     52       1.1  tsutsui 	/* func    argc   argp... */
     53       1.1  tsutsui #if 0
     54       1.1  tsutsui 	{ cmd_boot, 1, { "mem:", 0, 0, 0, 0, 0, 0 } },
     55       1.1  tsutsui 	{ cmd_boot, 1, { "sd0k:netbsd", 0, 0, 0, 0, 0, 0 } },
     56       1.1  tsutsui 	{ cmd_load_binary, 1, { "0x80001000", 0, 0, 0, 0, 0, 0 } },
     57       1.1  tsutsui 	{ cmd_jump, 2, { "0x80001000", "0x80001000", 0, 0, 0, 0, 0 } },
     58       1.1  tsutsui #endif
     59       1.1  tsutsui 	{ NULL, 0, { 0, 0, 0, 0, 0, 0, 0 } } /* terminate */
     60       1.1  tsutsui };
     61       1.1  tsutsui 
     62       1.1  tsutsui struct ipl_args ipl_args;
     63       1.1  tsutsui struct device_capability DEVICE_CAPABILITY;
     64       1.1  tsutsui void set_device_capability(void);
     65       1.4  thorpej bool guess_boot_kernel(char *, size_t, int);
     66       1.1  tsutsui extern int kernel_binary_size;
     67       1.1  tsutsui 
     68       1.1  tsutsui void
     69       1.1  tsutsui main(int a0, int v0, int v1)
     70       1.1  tsutsui {
     71       1.1  tsutsui 	extern char edata[], end[];
     72       1.1  tsutsui 	char boot_kernel[32];
     73       1.1  tsutsui 	char *args[CMDARG_MAX];
     74       1.1  tsutsui 	int i;
     75       1.1  tsutsui 
     76       1.1  tsutsui 	memset(edata, 0, end - edata);
     77       1.1  tsutsui 	/* Save args for chain-boot to iopboot */
     78       1.1  tsutsui 	ipl_args.a0 = a0;
     79       1.1  tsutsui 	ipl_args.v0 = v0;
     80       1.1  tsutsui 	ipl_args.v1 = v1;
     81       1.1  tsutsui 
     82       1.1  tsutsui 	console_init();
     83       1.1  tsutsui 
     84       1.1  tsutsui 	printf("\n");
     85       1.1  tsutsui 	printf("%s boot, Revision %s\n", bootprog_name, bootprog_rev);
     86       1.1  tsutsui 	printf("(%s, %s)\n", bootprog_date, bootprog_maker);
     87       1.1  tsutsui 
     88       1.1  tsutsui 
     89       1.1  tsutsui 	/* Inquire IPL activated device */
     90       1.1  tsutsui 	set_device_capability();
     91       1.1  tsutsui 
     92       1.1  tsutsui 	if (!guess_boot_kernel(boot_kernel, sizeof boot_kernel, 0))
     93       1.1  tsutsui 		goto prompt;
     94       1.1  tsutsui 	printf(
     95       1.1  tsutsui 	    ">> Press return to boot now, any other key for boot console.\n");
     96       1.1  tsutsui 
     97       1.1  tsutsui 	for (i = 5000; i >= 0; i--) {
     98       1.1  tsutsui 		int c;
     99       1.1  tsutsui 		if (i % 1000 == 0)
    100       1.1  tsutsui 			printf("booting %s - starting %d\r",
    101       1.1  tsutsui 			    boot_kernel, i / 1000);
    102       1.1  tsutsui 		if ((c = cnscan()) == -1) {
    103       1.1  tsutsui 			delay(10);
    104       1.1  tsutsui 			continue;
    105       1.1  tsutsui 		}
    106       1.1  tsutsui 		else if (c == '\r')
    107       1.1  tsutsui 			break;
    108       1.1  tsutsui 		else
    109       1.1  tsutsui 			goto prompt;
    110       1.1  tsutsui 	}
    111       1.1  tsutsui 	printf("\n[non-interactive mode]\n");
    112       1.1  tsutsui 	args[0] = "boot";
    113       1.1  tsutsui 	args[1] = boot_kernel;
    114       1.5  thorpej 	cmd_boot(2, args, false);
    115       1.1  tsutsui  prompt:
    116       1.1  tsutsui 
    117       1.1  tsutsui 	printf("\ntype \"help\" for help.\n");
    118       1.5  thorpej 	console_cursor(true);
    119       1.1  tsutsui 	prompt();
    120       1.1  tsutsui 	/* NOTREACHED */
    121       1.1  tsutsui }
    122       1.1  tsutsui 
    123       1.4  thorpej bool
    124       1.1  tsutsui guess_boot_kernel(char *name, size_t len, int pri)
    125       1.1  tsutsui {
    126       1.1  tsutsui 	extern struct vtoc_sector vtoc;
    127       1.1  tsutsui 	struct ux_partition *partition;
    128       1.1  tsutsui 	int i, unit;
    129       1.1  tsutsui 
    130       1.1  tsutsui 	if (!DEVICE_CAPABILITY.active)
    131       1.5  thorpej 		return false;
    132       1.1  tsutsui 
    133       1.1  tsutsui 	unit = DEVICE_CAPABILITY.booted_unit;
    134       1.1  tsutsui 
    135       1.1  tsutsui 	switch (DEVICE_CAPABILITY.booted_device) {
    136       1.1  tsutsui 	default:
    137       1.5  thorpej 		return false;
    138       1.1  tsutsui 	case NVSRAM_BOOTDEV_FLOPPYDISK:
    139       1.1  tsutsui 		strncpy(name, "fd:netbsd", len);	/* ustarfs */
    140       1.5  thorpej 		return true;
    141       1.1  tsutsui 
    142       1.1  tsutsui 	case NVSRAM_BOOTDEV_HARDDISK:
    143       1.1  tsutsui 		snprintf(name, len, "sd%d:netbsd", unit); /* ustarfs */
    144       1.1  tsutsui 		if (!read_vtoc())
    145       1.5  thorpej 			return true;
    146       1.1  tsutsui 
    147       1.1  tsutsui 		partition = vtoc.partition;
    148       1.1  tsutsui 		for (i = 0; i < VTOC_MAXPARTITIONS; i++, partition++) {
    149       1.1  tsutsui 			if (partition->tag != __VTOC_TAG_BSDFFS)
    150       1.1  tsutsui 				continue;
    151       1.1  tsutsui 			/* ffs */
    152       1.1  tsutsui 			snprintf(name, len, "sd%d%c:netbsd", unit, 'a' + i);
    153       1.5  thorpej 			return true;
    154       1.1  tsutsui 		}
    155       1.5  thorpej 		return true;
    156       1.1  tsutsui 
    157       1.1  tsutsui 	case NVSRAM_BOOTDEV_CGMT:
    158       1.1  tsutsui 		break;
    159       1.1  tsutsui 	case NVSRAM_BOOTDEV_NETWORK:
    160       1.1  tsutsui 		/*FALLTHROUGH*/
    161       1.1  tsutsui 	case NVSRAM_BOOTDEV_NETWORK_T_AND_D:
    162       1.1  tsutsui 		if (kernel_binary_size) {
    163       1.1  tsutsui 			strncpy(name, "mem:", len);	/* datafs */
    164       1.5  thorpej 			return true;
    165       1.1  tsutsui 		}
    166       1.1  tsutsui 		if (DEVICE_CAPABILITY.network_enabled) {
    167       1.1  tsutsui 			strncpy(name, "nfs:netbsd", len);	/* nfs */
    168       1.5  thorpej 			return true;
    169       1.1  tsutsui 		}
    170       1.1  tsutsui 		break;
    171       1.1  tsutsui 	}
    172       1.1  tsutsui 
    173       1.5  thorpej 	return false;
    174       1.1  tsutsui }
    175       1.1  tsutsui 
    176       1.1  tsutsui int
    177       1.1  tsutsui cmd_info(int argc, char *argp[], int interactive)
    178       1.1  tsutsui {
    179       1.1  tsutsui 	extern char _ftext[], _etext[], _fdata[], _edata[];
    180       1.1  tsutsui 	extern char _fbss[], end[];
    181       1.1  tsutsui 	uint32_t m;
    182       1.1  tsutsui 	int i, size, total;
    183       1.1  tsutsui 	struct sbdinfo *sbd = SBD_INFO;
    184       1.1  tsutsui 
    185       1.1  tsutsui 	printf("\n>> %s boot, rev. %s [%s, %s] <<\n", bootprog_name,
    186       1.1  tsutsui 	    bootprog_rev, bootprog_date, bootprog_maker);
    187       1.1  tsutsui 
    188       1.1  tsutsui 	printf("IPL args: 0x%x 0x%x 0x%x\n", ipl_args.a0, ipl_args.v0,
    189       1.1  tsutsui 	    ipl_args.v1);
    190       1.1  tsutsui 	printf("\ttext : %p-%p\n\tdata : %p-%p\n\t"
    191       1.1  tsutsui 	    "bss  : %p-%p\n\tstack: %p\n\theap : %p\n",
    192       1.1  tsutsui 	       _ftext, _etext, _fdata, _edata,
    193       1.1  tsutsui 	       _fbss, end, _ftext, end);
    194       1.1  tsutsui 
    195       1.1  tsutsui 	m = ipl_args.v1;
    196       1.1  tsutsui 	total = 0;
    197       1.1  tsutsui 	printf("Memory Area:\n\t");
    198       1.1  tsutsui 	for (i = 0; i < 8; i++, m >>= 4) {
    199       1.1  tsutsui 		size = m & 0xf ? ((m & 0xf) << 4) : 0;
    200       1.1  tsutsui 		total += size;
    201       1.1  tsutsui 		if (size)
    202       1.1  tsutsui 			printf("M%d=%dMB ", i, size);
    203       1.1  tsutsui 	}
    204       1.1  tsutsui 	printf(" total %dMB\n", total);
    205       1.1  tsutsui 
    206       1.1  tsutsui 	printf("Board Revision:\n");
    207       1.1  tsutsui 	printf("\tmachine=0x%x, ", sbd->machine);
    208       1.1  tsutsui 	printf("model=0x%x\n", sbd->model);
    209       1.1  tsutsui 	printf("\tpmmu=%d, ", sbd->mmu);
    210       1.1  tsutsui 	printf("cache=%d, ", sbd->cache);
    211       1.1  tsutsui 	printf("panel=%d, ", sbd->panel);
    212       1.1  tsutsui 	printf("fdd=%d\n", sbd->fdd);
    213       1.1  tsutsui 	printf("\tcpu=%d, fpp=%d, fpa=%d, iop=%d\n",
    214       1.1  tsutsui 	    sbd->cpu, sbd->fpp, sbd->fpa, sbd->iop);
    215       1.1  tsutsui 	printf("\tclock=%d\n", sbd->clock);
    216       1.1  tsutsui 	printf("\tipl=%d, cpu_ex=%d, fpp_ex=%d\n",
    217       1.1  tsutsui 	    sbd->ipl, sbd->cpu_ex, sbd->fpp_ex);
    218       1.1  tsutsui 	printf("\tkbms=%d, sio=%d, battery=%d, scsi=%d\n",
    219       1.1  tsutsui 	    sbd->kbms, sbd->sio, sbd->battery, sbd->scsi);
    220       1.1  tsutsui 	printf("model name=%s\n", sbd->model_name);
    221       1.1  tsutsui 
    222       1.1  tsutsui 	return 0;
    223       1.1  tsutsui }
    224       1.1  tsutsui 
    225       1.1  tsutsui int
    226       1.1  tsutsui cmd_reboot(int argc, char *argp[], int interactive)
    227       1.1  tsutsui {
    228       1.1  tsutsui 	int bootdev = -1;
    229       1.1  tsutsui 
    230       1.1  tsutsui 	if (argc > 1)
    231       1.1  tsutsui 		bootdev = strtoul(argp[1], 0, 0); /* next boot device. */
    232       1.1  tsutsui 	if (bootdev != NVSRAM_BOOTDEV_FLOPPYDISK &&
    233       1.1  tsutsui 	    bootdev != NVSRAM_BOOTDEV_HARDDISK &&
    234       1.1  tsutsui 	    bootdev != NVSRAM_BOOTDEV_CGMT &&
    235       1.1  tsutsui 	    bootdev != NVSRAM_BOOTDEV_NETWORK) {
    236       1.1  tsutsui 		printf("invalid boot device.");
    237       1.1  tsutsui 		bootdev = -1;
    238       1.1  tsutsui 	}
    239       1.1  tsutsui 
    240       1.1  tsutsui 	switch (SBD_INFO->machine) {
    241       1.1  tsutsui 	case MACHINE_TR2A:
    242       1.1  tsutsui 		if (bootdev != -1)
    243       1.1  tsutsui 			*(uint8_t *)0xbe493030 = bootdev;
    244       1.1  tsutsui 		*(volatile uint32_t *)0xbe000064 |= 0x80000000;
    245       1.1  tsutsui 		*(volatile uint8_t *)0xba000004 = 1;
    246       1.1  tsutsui 		*(uint8_t *)0xbfbffffc = 255;
    247       1.1  tsutsui 		break;
    248       1.1  tsutsui 	case MACHINE_TR2:
    249       1.1  tsutsui 		if (bootdev != -1)
    250       1.1  tsutsui 			*(uint8_t *)0xbb023030 = bootdev;
    251       1.1  tsutsui 		*(volatile uint32_t *)0xbfb00000 |= 0x10;
    252       1.1  tsutsui 		break;
    253       1.1  tsutsui 	default:
    254       1.1  tsutsui 		ROM_MONITOR();
    255       1.1  tsutsui 	}
    256       1.1  tsutsui 
    257       1.1  tsutsui 	while (/*CONSTCOND*/1)
    258       1.1  tsutsui 		;
    259       1.1  tsutsui 	/* NOTREACHED */
    260       1.1  tsutsui 	return 0;
    261       1.1  tsutsui }
    262       1.1  tsutsui 
    263       1.1  tsutsui void
    264       1.1  tsutsui set_device_capability(void)
    265       1.1  tsutsui {
    266       1.1  tsutsui 	const char *devname[] = {
    267       1.1  tsutsui 		"Floppy disk",
    268       1.1  tsutsui 		"Unknown",
    269       1.1  tsutsui 		"Hard disk",
    270       1.1  tsutsui 		"Unknown",
    271       1.1  tsutsui 		"CGMT",
    272       1.1  tsutsui 		"Unknown",
    273       1.1  tsutsui 		"Network",
    274       1.1  tsutsui 		"Unknown",
    275       1.1  tsutsui 		"Network T&D"
    276       1.1  tsutsui 	};
    277       1.1  tsutsui 	int booted_device, booted_unit, fd_format;
    278       1.1  tsutsui 
    279       1.1  tsutsui 	boot_device(&booted_device, &booted_unit, &fd_format);
    280       1.1  tsutsui 	if (booted_device > NVSRAM_BOOTDEV_MAX ||
    281       1.1  tsutsui 	    booted_device < NVSRAM_BOOTDEV_MIN) {
    282       1.1  tsutsui 		printf(
    283       1.3      wiz 		    "invalid booted device. NVSRAM information isn't valid\n");
    284       1.1  tsutsui 	} else {
    285       1.1  tsutsui 		DEVICE_CAPABILITY.booted_device = booted_device;
    286       1.1  tsutsui 	}
    287       1.1  tsutsui 	DEVICE_CAPABILITY.booted_unit = booted_unit;
    288       1.1  tsutsui 
    289       1.1  tsutsui 	switch (SBD_INFO->machine) {
    290       1.1  tsutsui 	case MACHINE_TR2A:
    291       1.5  thorpej 		DEVICE_CAPABILITY.active = true;
    292       1.1  tsutsui 		/* boot has LANCE driver */
    293       1.5  thorpej 		DEVICE_CAPABILITY.network_enabled = true;
    294       1.1  tsutsui 		break;
    295       1.1  tsutsui 	case MACHINE_TR2:
    296       1.5  thorpej 		DEVICE_CAPABILITY.active = true;
    297       1.1  tsutsui 		break;
    298       1.1  tsutsui 	default:
    299       1.5  thorpej 		DEVICE_CAPABILITY.active = false;
    300       1.1  tsutsui 		break;
    301       1.1  tsutsui 	}
    302       1.1  tsutsui 
    303       1.5  thorpej 	DEVICE_CAPABILITY.fd_enabled = true;	/* always enabled */
    304       1.1  tsutsui 
    305       1.1  tsutsui 	if (DEVICE_CAPABILITY.active) {
    306       1.1  tsutsui 		/*
    307       1.1  tsutsui 		 * When NETWORK IPL, FD IPL doesn't activate ROM DISK routine.
    308       1.1  tsutsui 		 */
    309       1.1  tsutsui 		if (DEVICE_CAPABILITY.booted_device == NVSRAM_BOOTDEV_HARDDISK)
    310       1.5  thorpej 			DEVICE_CAPABILITY.disk_enabled = true;
    311       1.1  tsutsui 	}
    312       1.1  tsutsui 
    313       1.1  tsutsui 	printf("FD[%c] DISK[%c] NETWORK[%c] COMPILED[%c]\n",
    314       1.1  tsutsui 	    DEVICE_CAPABILITY.fd_enabled ? 'x' : '_',
    315       1.1  tsutsui 	    DEVICE_CAPABILITY.disk_enabled ? 'x' : '_',
    316       1.1  tsutsui 	    DEVICE_CAPABILITY.network_enabled ? 'x' : '_',
    317       1.1  tsutsui 	    kernel_binary_size ? 'x' : '_');
    318       1.1  tsutsui 
    319       1.2  tsutsui 	printf("booted from %s IPL", devname[DEVICE_CAPABILITY.booted_device]);
    320       1.1  tsutsui 	if ((DEVICE_CAPABILITY.booted_device == NVSRAM_BOOTDEV_NETWORK) ||
    321       1.1  tsutsui 	    (DEVICE_CAPABILITY.booted_device == NVSRAM_BOOTDEV_NETWORK_T_AND_D))
    322       1.1  tsutsui 	{
    323       1.1  tsutsui 		printf("\n");
    324       1.1  tsutsui 	} else {
    325       1.1  tsutsui 		printf(" unit %d\n", DEVICE_CAPABILITY.booted_unit);
    326       1.1  tsutsui 	}
    327       1.1  tsutsui }
    328       1.1  tsutsui 
    329       1.1  tsutsui int
    330       1.1  tsutsui cmd_test(int argc, char *argp[], int interactive)
    331       1.1  tsutsui {
    332       1.1  tsutsui 
    333       1.1  tsutsui 	/* MISC TEST ROUTINE */
    334       1.1  tsutsui 	extern int fdd_test(void);
    335       1.1  tsutsui 	fdd_test();
    336       1.1  tsutsui #if 0
    337       1.1  tsutsui 	int i;
    338       1.1  tsutsui 
    339       1.1  tsutsui 	printf("argc=%d\n", argc);
    340       1.1  tsutsui 	for (i = 0; i < argc; i++)
    341       1.1  tsutsui 		printf("[%d] %s\n", i, argp[i]);
    342       1.1  tsutsui #endif
    343       1.1  tsutsui #if 0	/* Recover my 360ADII NVSRAM.. */
    344       1.1  tsutsui 	uint8_t *p = (uint8_t *)0xbe490000;
    345       1.1  tsutsui 	uint8_t *q = nvsram_tr2a;
    346       1.1  tsutsui 	int i;
    347       1.1  tsutsui 
    348       1.1  tsutsui 	for (i = 0; i < sizeof nvsram_tr2a; i++) {
    349       1.1  tsutsui 		*p = *q;
    350       1.1  tsutsui 		p += 4;
    351       1.1  tsutsui 		q += 1;
    352       1.1  tsutsui 	}
    353       1.1  tsutsui #endif
    354       1.1  tsutsui #if 0	/* ROM PUTC test */
    355       1.1  tsutsui 	char a[]= "ohayotest!";
    356       1.1  tsutsui 	int i;
    357       1.1  tsutsui 	for (i = 0; i < 10; i++)
    358       1.1  tsutsui 		ROM_PUTC(120 + i * 12, 24 * 10, a[i]);
    359       1.1  tsutsui #endif
    360       1.1  tsutsui #if 0	/* ROM SCSI disk routine test TR2 */
    361       1.1  tsutsui 	uint8_t buf[512*2];
    362       1.1  tsutsui 	uint8_t *p;
    363       1.1  tsutsui 	int i;
    364       1.1  tsutsui 
    365       1.1  tsutsui 	printf("type=%d\n", *(uint8_t *)0xbb023034);
    366       1.1  tsutsui 	memset(buf, 0, sizeof buf);
    367       1.1  tsutsui 	p = (uint8_t *)(((uint32_t)buf + 511) & ~511);
    368       1.1  tsutsui 	i = ROM_DK_READ(0, 0, 1, p);
    369       1.1  tsutsui 	printf("err=%d\n", i);
    370       1.1  tsutsui 	for (i = 0; i < 64; i++) {
    371       1.1  tsutsui 		printf("%x ", p[i]);
    372       1.1  tsutsui 		if (((i + 1) & 0xf) == 0)
    373       1.1  tsutsui 			printf("\n");
    374       1.1  tsutsui 	}
    375       1.1  tsutsui #endif
    376       1.1  tsutsui #if 0
    377       1.1  tsutsui 	/*XXX failed. */
    378       1.1  tsutsui 	__asm volatile(
    379       1.1  tsutsui 		".set noreorder;"
    380       1.1  tsutsui 		"li	$4, 2;"
    381       1.1  tsutsui 		"mtc0	$4, $16;" /* Config */
    382       1.1  tsutsui 		"lui	$4, 0xbfc2;"
    383       1.1  tsutsui 		"jr	$4;"
    384       1.1  tsutsui 		"nop;"
    385       1.1  tsutsui 		".set reorder");
    386       1.1  tsutsui 	/* NOTREACHED */
    387       1.1  tsutsui #endif
    388       1.1  tsutsui #if 0
    389       1.1  tsutsui 	/* FPU test */
    390       1.1  tsutsui 	{
    391       1.1  tsutsui 		int v;
    392       1.1  tsutsui 		__asm volatile(
    393       1.1  tsutsui 			".set noreorder;"
    394       1.1  tsutsui 			"lui	%0, 0x2000;"
    395       1.1  tsutsui 			"mtc0	%0, $12;" /* Cu1 */
    396       1.1  tsutsui 			"nop;"
    397       1.1  tsutsui 			"nop;"
    398       1.1  tsutsui 			"cfc1	%0, $%1;"
    399       1.1  tsutsui 			"nop;"
    400       1.1  tsutsui 			"nop;"
    401       1.1  tsutsui 			".set reorder"
    402       1.1  tsutsui 			: "=r"(v) : "i"(0));
    403       1.1  tsutsui 		printf("FPUId: %x\n", v);
    404       1.1  tsutsui 	}
    405       1.1  tsutsui #endif
    406       1.1  tsutsui 	return 0;
    407       1.1  tsutsui }
    408