Module Name:    src
Committed By:   tsutsui
Date:           Sat Jan 12 16:44:48 UTC 2019

Modified Files:
        src/sys/arch/sgimips: README.IPn TODO
        src/sys/arch/sgimips/stand: Makefile Makefile.booters
Added Files:
        src/sys/arch/sgimips/stand/bootiris: Makefile version
        src/sys/arch/sgimips/stand/common: iris_autoconf.c iris_boot.c
            iris_conf.c iris_cons.c iris_cons.h iris_devopen.c iris_disk.c
            iris_machdep.h iris_parse.c iris_prf.c iris_scsi.c iris_scsicmd.h
            iris_scsictl.c iris_scsireg.h iris_scsivar.h iris_start.S iris_zs.c
            iris_zs.h

Log Message:
Import irisboot, yet another bootloader for pre-ARC sgimips machines.

This bootloader adds support for Personal IRIS 4D/25 (IP6),
Personal IRIS 4D/35 (IP12), and Indigo R3000 (IP12) etc. and
optionally supports R4000 Indy and Indigo R4000 (ARCS machine)
using standalone WD33C93 SCSI driver.

Submitted by Naruaki Etomi via PR port-sgimips/53539,
and reviewed by tsutsui@.  See also port-sgimips@ ML thread:
 https://mail-index.netbsd.org/port-sgimips/2018/09/16/msg000778.html


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/sgimips/README.IPn
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/sgimips/TODO
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/sgimips/stand/Makefile
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/sgimips/stand/Makefile.booters
cvs rdiff -u -r0 -r1.1 src/sys/arch/sgimips/stand/bootiris/Makefile \
    src/sys/arch/sgimips/stand/bootiris/version
cvs rdiff -u -r0 -r1.1 src/sys/arch/sgimips/stand/common/iris_autoconf.c \
    src/sys/arch/sgimips/stand/common/iris_boot.c \
    src/sys/arch/sgimips/stand/common/iris_conf.c \
    src/sys/arch/sgimips/stand/common/iris_cons.c \
    src/sys/arch/sgimips/stand/common/iris_cons.h \
    src/sys/arch/sgimips/stand/common/iris_devopen.c \
    src/sys/arch/sgimips/stand/common/iris_disk.c \
    src/sys/arch/sgimips/stand/common/iris_machdep.h \
    src/sys/arch/sgimips/stand/common/iris_parse.c \
    src/sys/arch/sgimips/stand/common/iris_prf.c \
    src/sys/arch/sgimips/stand/common/iris_scsi.c \
    src/sys/arch/sgimips/stand/common/iris_scsicmd.h \
    src/sys/arch/sgimips/stand/common/iris_scsictl.c \
    src/sys/arch/sgimips/stand/common/iris_scsireg.h \
    src/sys/arch/sgimips/stand/common/iris_scsivar.h \
    src/sys/arch/sgimips/stand/common/iris_start.S \
    src/sys/arch/sgimips/stand/common/iris_zs.c \
    src/sys/arch/sgimips/stand/common/iris_zs.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sgimips/README.IPn
diff -u src/sys/arch/sgimips/README.IPn:1.10 src/sys/arch/sgimips/README.IPn:1.11
--- src/sys/arch/sgimips/README.IPn:1.10	Tue Feb 10 06:12:27 2009
+++ src/sys/arch/sgimips/README.IPn	Sat Jan 12 16:44:47 2019
@@ -1,4 +1,4 @@
-$NetBSD: README.IPn,v 1.10 2009/02/10 06:12:27 rumble Exp $
+$NetBSD: README.IPn,v 1.11 2019/01/12 16:44:47 tsutsui Exp $
 
 Arch (kernel)	Models				Codename
 -------------	------				--------
@@ -30,6 +30,7 @@ IP35		SN1 (?)
 
 Architecture	ABI	Bootstrap Load Address	Kernel Load Address
 ------------	---	----------------------	-------------------
+IP12		32	0x80368000		0x80002000
 IP19 IP21 IP25	32	0x80004000		0x80100000
 IP19 IP21 IP25	64	0xa800000000004000	0xa800000000180000
 IP20 IP22 IP24	32	0x88002000		0x88069000

Index: src/sys/arch/sgimips/TODO
diff -u src/sys/arch/sgimips/TODO:1.6 src/sys/arch/sgimips/TODO:1.7
--- src/sys/arch/sgimips/TODO:1.6	Sun Mar 25 00:49:31 2007
+++ src/sys/arch/sgimips/TODO	Sat Jan 12 16:44:47 2019
@@ -6,7 +6,6 @@ Things to be done:
 
 (sekiya)
 * grtwo needs cursor and hardware color fill support
-* ip12 needs ROM-based bootloader
 * hpc devices need real probe routines
 * port newport driver to x.org
 

Index: src/sys/arch/sgimips/stand/Makefile
diff -u src/sys/arch/sgimips/stand/Makefile:1.5 src/sys/arch/sgimips/stand/Makefile:1.6
--- src/sys/arch/sgimips/stand/Makefile:1.5	Sun Dec 11 12:18:58 2005
+++ src/sys/arch/sgimips/stand/Makefile	Sat Jan 12 16:44:47 2019
@@ -1,5 +1,5 @@
-#	$NetBSD: Makefile,v 1.5 2005/12/11 12:18:58 christos Exp $
+#	$NetBSD: Makefile,v 1.6 2019/01/12 16:44:47 tsutsui Exp $
 
-SUBDIR=	boot boot64 sgivol
+SUBDIR=	boot boot64 bootiris sgivol
 
 .include <bsd.subdir.mk>

Index: src/sys/arch/sgimips/stand/Makefile.booters
diff -u src/sys/arch/sgimips/stand/Makefile.booters:1.24 src/sys/arch/sgimips/stand/Makefile.booters:1.25
--- src/sys/arch/sgimips/stand/Makefile.booters:1.24	Sat Apr  8 19:53:22 2017
+++ src/sys/arch/sgimips/stand/Makefile.booters	Sat Jan 12 16:44:47 2019
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.booters,v 1.24 2017/04/08 19:53:22 christos Exp $
+# $NetBSD: Makefile.booters,v 1.25 2019/01/12 16:44:47 tsutsui Exp $
 
 # PROG set by parent.
 NOMAN=		# defined
@@ -22,7 +22,9 @@ LIBCRTEND=
 realall: ${PROG}
 
 .PATH:		${.CURDIR}/../common
+.if !defined(PRE_ARCS)
 .PATH.S:	${S}/dev/arcbios
+.endif
 AFLAGS+=	-D_LOCORE -D_KERNEL -mno-abicalls
 CPPFLAGS+=	-nostdinc -D_STANDALONE -DNO_ABICALLS -I${.OBJDIR} -I${S}
 # compiler flags for smallest code size
@@ -40,13 +42,16 @@ CPPFLAGS+=	-DNETBSD_VERS='"${NETBSD_VERS
 
 CPPFLAGS+=	-Dsgimips
 
+.if !defined(PRE_ARCS)
 .include "${S}/dev/arcbios/Makefile.inc"
+.endif
 
 # We load the kernel at 420K in from the start of RAM to give the boot
 # loader plenty of breathing room.  Load the boot loader starting at
 # the second page of RAM.
 # A warm thank-you to SGI for making load addresses different :)
 LOAD_ADDRESS?=		0x88002000
+LOAD_ADDRESS_IP12?=	0x80368000
 LOAD_ADDRESS_IP32?=	0x80002000
 
 .include "${S}/conf/newvers_stand.mk"

Added files:

Index: src/sys/arch/sgimips/stand/bootiris/Makefile
diff -u /dev/null src/sys/arch/sgimips/stand/bootiris/Makefile:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/bootiris/Makefile	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,58 @@
+#	$NetBSD: Makefile,v 1.1 2019/01/12 16:44:47 tsutsui Exp $
+
+# Silicon Graphics "IRIS" series MIPS processors machine.
+STRIPFLAG=
+# If you try to use ARCBIOS(Indy or Indigo R4000) machine, Please comment it out!
+# Be sure to edit /sgimips/stand/common/iris_machdep.h!
+PRE_ARCS= yes
+
+.if defined(PRE_ARCS)
+SRCS=   iris_start.S 
+.else
+SRCS=   start.S arcbios_calls.S
+.endif
+
+SRCS+=  iris_boot.c
+SRCS+=  bootinfo.c
+SRCS+=  iris_prf.c iris_cons.c iris_zs.c
+SRCS+=  iris_parse.c
+SRCS+=  iris_autoconf.c iris_scsi.c
+SRCS+=  iris_disk.c
+SRCS+=  iris_scsictl.c
+SRCS+=  iris_conf.c
+SRCS+=  iris_devopen.c
+
+PROG=	irisboot
+${PROG}: ip12boot
+.if ${MACHINE_ARCH} == "mipseb"
+	cp ip12boot ip12boot.tmp
+	${MIPS_ELF2ECOFF} ip12boot.tmp ${.TARGET}
+.else
+	touch ${.TARGET}
+.endif
+
+# XXX Temporary hack to install the ELF version, too.
+FILES+=		ip12boot
+CLEANFILES+=	ip12boot ip12boot.elf
+
+CLEANFILES+=	ip12boot.map
+
+CLEANFILES+=	ip12boot.tmp
+
+.include "../Makefile.booters"
+
+ip12boot: ${OBJS} ${LIBS}
+	${_MKTARGET_LINK}
+.if defined(PRE_ARCS)
+	${LD} -Map ${.TARGET}.map -N -x -Ttext ${LOAD_ADDRESS_IP12} ${LDBUG} \
+	    -m elf32btsmip -e start -o ${.TARGET}.elf ${OBJS} ${LIBS}
+.else
+	${LD} -Map ${.TARGET}.map -N -x -Ttext ${LOAD_ADDRESS} ${LDBUG} \
+	    -m elf32btsmip -e start -o ${.TARGET}.elf ${OBJS} ${LIBS}
+.endif
+	@${STRIP} -s ${.TARGET}.elf -o ${.TARGET}
+	@${SIZE} ${.TARGET}
+
+cleandir distclean: .WAIT cleanlibdir
+cleanlibdir:
+	-rm -rf lib
Index: src/sys/arch/sgimips/stand/bootiris/version
diff -u /dev/null src/sys/arch/sgimips/stand/bootiris/version:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/bootiris/version	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,5 @@
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
+file is important - make sure the entries are appended on end, last item
+is taken as the current.
+
+1.0:	Initial sgimips "IRIS" series MIPS processors machine booter

Index: src/sys/arch/sgimips/stand/common/iris_autoconf.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_autoconf.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_autoconf.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,42 @@
+/*	$NetBSD: iris_autoconf.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ * Find and init devices.
+ */
+
+#include <mips/cpuregs.h>
+#include "iris_machdep.h"
+
+void
+find_devs(void)
+{
+
+	wd33c93_init((void *)MIPS_PHYS_TO_KSEG1(SCSIA_ADDR),
+	    (void *)MIPS_PHYS_TO_KSEG1(SCSID_ADDR));
+}
Index: src/sys/arch/sgimips/stand/common/iris_boot.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_boot.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_boot.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,157 @@
+/*	$NetBSD: iris_boot.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ *
+ * Notes:
+ *   The amount of physical memory space available to
+ *   the system is 3661820 (0x80002000 - 0x8037fffc) bytes.
+ *   This space is too tight for kernel and bootloader.
+ *   So we keep it simple.
+ */
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/loadfile.h>
+#include <lib/libkern/libkern.h>
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/exec_elf.h>
+#include <sys/boot_flag.h>
+
+#ifndef	INDIGO_R3K_MODE
+#include <dev/arcbios/arcbios.h>
+#endif
+
+#include "iris_machdep.h"
+
+#include "common.h"
+#include "bootinfo.h"
+
+int main(int, char **);
+
+/* Storage must be static. */
+struct btinfo_symtab bi_syms;
+struct btinfo_bootpath bi_bpath;
+
+static uint8_t bootinfo[BOOTINFO_SIZE];
+
+/*
+ * This gets arguments from the PROM monitor.
+ * argv[0] will be path to the bootloader (i.e., "dksc(X,Y,8)/bootiris").
+ *
+ * argv[1] through argv[n] will contain arguments passed from the PROM, if any.
+ */
+
+int
+main(int argc, char **argv)
+{
+	char kernelname[1 + 32];
+	void (*entry) (int, char *[], int, void *);
+	u_long marks[MARK_MAX];
+	int win = 0;
+	int zs_addr, speed;
+
+	cninit(&zs_addr, &speed);
+
+ 	/* print a banner */
+	printf("\n");
+	printf("%s " NETBSD_VERS " Yet another Bootstrap, Revision %s\n",
+	    bootprog_name, bootprog_rev);
+	printf("\n");
+
+	memset(marks, 0, sizeof marks);
+
+	/* initialise bootinfo structure early */
+	bi_init(bootinfo);
+
+	switch (argc) {
+#ifdef INDIGO_R3K_MODE
+	case 1:
+		again();
+		break;
+#endif
+	case 2:
+		/* To specify HDD on Indigo R3K */ 
+		if (strstr(argv[1], "dksc(")) {
+			parse(argv, kernelname);
+		} else {
+			again();
+		}
+		break;
+	default:
+		/* To specify HDD on Indigo R4K and Indy */ 
+		if (strstr(argv[1], "dksc(")) {
+			parse(argv, kernelname);
+		} else {
+			again();
+		}
+		break;
+	}
+
+	find_devs();
+
+	win = loadfile(kernelname, marks, LOAD_KERNEL);
+
+	if (win < 0) {
+		printf("Boot failed!  Halting...\n");
+		reboot();
+	}
+
+	strlcpy(bi_bpath.bootpath, kernelname, BTINFO_BOOTPATH_LEN);
+	bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath));
+
+	bi_syms.nsym = marks[MARK_NSYM];
+	bi_syms.ssym = marks[MARK_SYM];
+	bi_syms.esym = marks[MARK_END];
+	bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms));
+	entry = (void *)marks[MARK_ENTRY];
+
+	(*entry)(argc, argv, BOOTINFO_MAGIC, bootinfo);
+
+	printf("Kernel returned!  Halting...\n");
+	return 0;
+}
+
+void
+again(void)
+{
+	printf("Invalid argument\n");
+	printf("i.e., dksc(0,X,8)loader dksc(0,X,0)/kernel\n");
+	reboot();
+}
+
+void
+reboot(void)
+{
+#ifdef INDIGO_R3K_MODE
+	romrestart();
+#else
+	arcbios_Reboot();
+#endif
+}
Index: src/sys/arch/sgimips/stand/common/iris_conf.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_conf.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_conf.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,55 @@
+/*	$NetBSD: iris_conf.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <lib/libsa/stand.h>
+#include <lib/libsa/ufs.h>
+#include <lib/libsa/lfs.h>
+
+#include "../common/disk.h"
+
+#define diskioctl /*(()(struct open_file*, u_long, void*))*/0
+
+struct devsw devsw[] = {
+	{ "dksc", diskstrategy, diskopen, diskclose, diskioctl },
+};
+
+int	ndevs = __arraycount(devsw);
+
+struct fs_ops file_system[] = {
+	FS_OPS(ffsv1),
+	FS_OPS(ffsv2),
+	FS_OPS(lfsv1),
+	FS_OPS(lfsv2),
+};
+
+int nfsys = __arraycount(file_system);
Index: src/sys/arch/sgimips/stand/common/iris_cons.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_cons.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_cons.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,141 @@
+/*	$NetBSD: iris_cons.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ * Front end of Zilog Z8530 Dual UART driver.
+ */
+
+#include <lib/libsa/stand.h>
+
+#include <machine/cpu.h>
+
+#include "iris_machdep.h"
+#include "iris_cons.h"
+#include "iris_zs.h"
+
+void zscnprobe(struct consdev *);
+void zscninit(struct consdev *);
+void zscnputchar(void *, int);
+int zscngetchar(void *);
+int zscnscan(void *);
+
+#define ZSCHAN 0x0
+#define ZSSPEED 9600
+
+struct consdev constab[] = {
+	{ "zs", ZSCHAN, ZSSPEED,
+		zscnprobe, zscninit, zscngetchar, zscnputchar, zscnscan },
+	{ 0 }
+};
+
+struct consdev *cn_tab;
+
+char *
+cninit(int *addr, int *speed)
+{
+	struct consdev *cp;
+
+	cn_tab = NULL;
+	for (cp = constab; cp->cn_probe; cp++) {
+		(*cp->cn_probe)(cp);
+		if (cp->cn_pri > CN_DEAD &&
+		    (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
+			cn_tab = cp;
+	}
+	if (cn_tab) {
+		(*cn_tab->cn_init)(cn_tab);
+		*addr = cn_tab->address;
+		*speed = cn_tab->speed;
+		return cn_tab->cn_name;
+	}
+
+	return NULL;
+}
+
+int
+cngetc(void)
+{
+
+	if (cn_tab)
+		return (*cn_tab->cn_getc)(cn_tab->cn_dev);
+	return 0;
+}
+
+void
+cnputc(int c)
+{
+
+	if (cn_tab)
+		(*cn_tab->cn_putc)(cn_tab->cn_dev, c);
+}
+
+int
+cnscan(void)
+{
+
+	if (cn_tab)
+		return (*cn_tab->cn_scan)(cn_tab->cn_dev);
+	return -1;
+}
+
+void
+zscnprobe(struct consdev *cp)
+{
+
+	cp->cn_pri = CN_REMOTE;
+}
+
+void
+zscninit(struct consdev *cp)
+{
+
+	cp->cn_dev = zs_init(cp->address, cp->speed);
+}
+
+int
+zscngetchar(void *dev)
+{
+
+	return zscngetc(dev);
+}
+
+void
+zscnputchar(void *dev, int c)
+{
+
+	if (c == '\n')
+		zscnputc(dev, '\r');
+	zscnputc(dev, c);
+}
+
+int
+zscnscan(void *dev)
+{
+
+	return zscnscanc(dev);
+}
Index: src/sys/arch/sgimips/stand/common/iris_cons.h
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_cons.h:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_cons.h	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,54 @@
+/*	$NetBSD: iris_cons.h,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ */
+
+struct consdev {
+	char	*cn_name;	/* console device name */
+	int	address;	/* address */
+	int	speed;		/* speed(serial only) */
+	void	(*cn_probe)	/* probe hardware and fill in consdev info */
+		    (struct consdev *);
+	void	(*cn_init)	/* turn on as console */
+		    (struct consdev *);
+	int	(*cn_getc)	/* getchar interface */
+		    (void *);
+	void	(*cn_putc)	/* putchar interface */
+		    (void *, int);
+	int	(*cn_scan)	/* scan interface */
+		    (void *);
+	int	cn_pri;		/* pecking order; the higher the better */
+	void	*cn_dev;	/* device data tag */
+};
+
+/* values for cn_pri - reflect our policy for console selection */
+#define CN_DEAD		0	/* device doesn't exist */
+#define CN_NORMAL	1	/* device exists but is nothing special */
+#define CN_INTERNAL	2	/* "internal" bit-mapped display */
+#define CN_REMOTE	3	/* serial interface with remote bit set */
Index: src/sys/arch/sgimips/stand/common/iris_devopen.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_devopen.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_devopen.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,59 @@
+/*	$NetBSD: iris_devopen.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ */
+
+#include <lib/libsa/stand.h>
+#include <lib/libkern/libkern.h>
+#include "iris_machdep.h"
+
+int
+devopen(struct open_file *f, const char *fname, char **file)
+{
+	int error;
+	const char *cp;
+
+	struct devsw *dp;
+
+	cp = fname;
+
+	dp = &devsw[0];
+
+	error = (dp->dv_open)(f, fname);
+
+	if (error)
+		return error;
+
+	f->f_dev = dp;
+
+	if (file && *cp != '\0')
+		*file = (char *)cp;	/* XXX */
+
+	return 0;
+}
Index: src/sys/arch/sgimips/stand/common/iris_disk.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_disk.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_disk.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,234 @@
+/*	$NetBSD: iris_disk.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory and the Systems
+ * Programming Group of the University of Utah Computer Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah $Hdr: sd.c 1.9 92/12/21$
+ *
+ *	@(#)sd.c	8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ * Disk I/O API routine.
+ * Most of the following was adapted from /sys/arch/hp300/stand/common/sd.c.
+ *	NetBSD: sd.c,v 1.11 2011/07/17 20:54:40 joerg Exp
+ */
+
+#include <lib/libsa/stand.h>
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+
+#ifndef	INDIGO_R3K_MODE
+#include <dev/arcbios/arcbios.h>
+#endif
+
+#include "disk.h"
+
+#include "iris_machdep.h"
+#include "iris_scsivar.h"
+
+struct	disk_softc {
+	int	sc_part;		/* disk partition number */
+	char	sc_retry;
+	char	sc_alive;
+	short	sc_blkshift;
+	struct	disklabel sc_label;	/* disk label for this disk */
+};
+
+static int diskinit(struct disk_softc *);
+
+#define DISKRETRY  2
+
+int
+diskstrategy(void *devdata, int rw, daddr_t bn, size_t reqcnt, void *addr,
+    size_t *cnt)
+{
+	struct disk_softc *sc;
+	struct disklabel *lp;
+	uint8_t *buf;
+	daddr_t blk;
+	u_int nblk;
+	int stat;
+
+	sc = devdata;
+
+	buf = addr;
+	lp = &sc->sc_label;
+	blk = bn + (lp->d_partitions[sc->sc_part].p_offset >> sc->sc_blkshift);
+	nblk = reqcnt >> sc->sc_blkshift;
+
+	sc->sc_retry = 0;
+	
+ retry:
+	stat = scsi_read(buf, reqcnt, blk, nblk);
+
+	if (stat) {
+		DELAY(1000000);
+		if (++sc->sc_retry > DISKRETRY) {
+			return EIO;
+		}
+		printf("diskstrategy retry\n");
+		goto retry;
+	}
+
+	*cnt = reqcnt;
+
+	return 0;
+}
+
+static int
+diskinit(struct disk_softc *sc)
+{
+	uint8_t capbuf[2];
+
+	uint8_t stat;
+
+	stat = scsi_test_unit_rdy();
+
+	if (stat != 0) {
+		/* drive may be doing RTZ - wait a bit */
+		DELAY(1000000);
+		stat = scsi_test_unit_rdy();
+
+		if (stat != 0) {
+			printf("diskinit abort!\n");
+			printf("Boot failed!  Halting...\n");
+			reboot();
+		}
+	}
+
+	/*
+	 * try to get the drive block size.
+	 */
+	capbuf[0] = 0;
+	capbuf[1] = 0;
+
+	stat = scsi_read_capacity((uint8_t *)capbuf, sizeof(capbuf));
+
+	if (stat == 0) {
+		if (capbuf[1] > DEV_BSIZE)
+			for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1)
+				++sc->sc_blkshift;
+	}
+
+	sc->sc_alive = 1;
+	return 1;
+}
+
+int
+diskopen(struct open_file *f, ...)
+{
+	struct disk_softc *sc;
+	struct disklabel *lp;
+	size_t cnt;
+	char *msg, buf[DEV_BSIZE];
+	int error;
+
+	cnt = 0;
+
+	sc = alloc(sizeof(struct disk_softc));
+	memset(sc, 0, sizeof(struct disk_softc));
+	f->f_devdata = (void *)sc;
+
+	sc->sc_part = scsi_part;
+
+	if (sc->sc_alive == 0) {
+		if (diskinit(sc) == 0)
+			return ENXIO;
+	}
+
+	/* try to read disk label and partition table information */
+	lp = &sc->sc_label;
+	lp->d_secsize = DEV_BSIZE;
+	lp->d_secpercyl = 1;
+	lp->d_npartitions = MAXPARTITIONS;
+	lp->d_partitions[scsi_part].p_offset = 0;
+	lp->d_partitions[scsi_part].p_size = 0x7fffffff;
+
+	error = diskstrategy(sc, F_READ, (daddr_t)LABELSECTOR, DEV_BSIZE, buf,
+	    &cnt);
+
+	if (error || cnt != DEV_BSIZE) {
+		printf("diskstrategy error...\n");
+		dealloc(sc, sizeof(struct disk_softc));
+		return ENXIO;
+	}
+
+	msg = getdisklabel(buf, lp);
+
+	if (msg) {
+		/* If no label, just assume 0 and return */
+		printf("No disklabel...\n");
+		reboot();
+	}
+
+	return 0;
+}
+
+int
+diskclose(struct open_file *f)
+{
+	struct disk_softc *sc = f->f_devdata;
+
+	dealloc(sc, sizeof *sc);
+	f->f_devdata = NULL;
+
+	return 0;
+}
Index: src/sys/arch/sgimips/stand/common/iris_machdep.h
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_machdep.h:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_machdep.h	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,100 @@
+/*	$NetBSD: iris_machdep.h,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ */
+
+#include <sys/param.h>
+#include <lib/libsa/stand.h>
+#include "iris_scsivar.h"
+
+/* iris_boot.c */
+void again(void);
+void reboot(void);
+
+/* iris_parse.c */
+void parse(char **, char *);
+
+/* iris_autoconf.c */
+void find_devs(void);
+
+/* iris_start.S */
+void romrestart(void);
+
+ /* iris_cons.c */
+char *cninit(int *, int *);
+int   cngetc(void);
+void  cnputc(int);
+int   cnscan(void);
+
+/* iris_scsi.c */
+void wd33c93_init(void *, void*);
+int wd33c93_go(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *, size_t *);
+
+/* iris_scsictl.c */
+int scsi_test_unit_rdy(void);
+int scsi_read_capacity(uint8_t *, size_t);
+int scsi_read(uint8_t *, size_t, daddr_t, size_t);
+int scsi_write(uint8_t *, size_t, daddr_t, size_t);
+
+#define INDIGO_R3K_MODE
+
+#ifdef INDIGO_R3K_MODE
+#define ZS_ADDR		0x1fb80d10
+#define SCSIA_ADDR	0x1FB80122
+#define SCSID_ADDR	0x1FB80126
+
+/* Target is Personal IRIS R3000 36MHz. */
+#define CPUSPEED	36
+#endif
+
+#ifdef INDIGO_R4K_MODE
+#define ZS_ADDR		0x1fb80d10
+#define SCSIA_ADDR	0x1FB80122
+#define SCSID_ADDR	0x1FB80126
+
+/* Target is IRIS Indigo R4000 100MHz. */
+#define CPUSPEED	100
+#endif
+
+#ifdef INDY_MODE
+#define ZS_ADDR		0x1fbd9830
+#define SCSIA_ADDR	0x1FBC0003
+#define SCSID_ADDR	0x1FBC0007
+
+/* Target is Indy 180MHz. */
+#define CPUSPEED	180
+#endif
+
+#define DELAY(n)							\
+do {									\
+        register int __N = (CPUSPEED) / 2 * n;				\
+        do {								\
+                __asm("addiu %0,%1,-1" : "=r" (__N) : "0" (__N));	\
+        } while (__N > 0);						\
+} while (/* CONSTCOND */ 0)
Index: src/sys/arch/sgimips/stand/common/iris_parse.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_parse.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_parse.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,82 @@
+/*	$NetBSD: iris_parse.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ * Parse argv argument vector.
+ */
+
+#include <lib/libsa/stand.h>
+#include <lib/libkern/libkern.h>
+
+#include "iris_machdep.h"
+#include "iris_scsivar.h"
+
+uint8_t scsi_ctlr = 255, scsi_id = 255, scsi_part = 255;
+
+void
+parse(char *argv[], char *kernelname)
+{
+	char disksetting[1 + 32];
+	char bootpath[1 + 64];
+	int i;
+
+	char *ep = strcpy(bootpath, argv[1]);
+	ep = strrchr(bootpath, '/');
+	if (ep == NULL)
+		again();
+
+	strcpy(kernelname, ep + 1);
+
+	i =  ep - bootpath;
+	bootpath[i - 1] = '\0';
+
+	ep = strchr(bootpath, '(');
+	if (ep == NULL)
+		/* horrible! */
+		again();
+
+	/* ctlr,id,part */
+	strcpy(disksetting, ep + 1);
+
+	i = 0;
+
+	while (disksetting[i] != '\0') {
+		if (disksetting[i] >= '0' && disksetting[i] <= '9') {
+			if (i == 0)
+				scsi_ctlr = atoi(&disksetting[i]);
+			if (i == 2)
+				scsi_id = atoi(&disksetting[i]);
+			if (i == 4)
+				scsi_part = atoi(&disksetting[i]);
+		}
+		i++;
+	}
+
+	if ((scsi_ctlr == 255) || (scsi_id == 255) || (scsi_part == 255))
+		again();
+}
Index: src/sys/arch/sgimips/stand/common/iris_prf.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_prf.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_prf.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,47 @@
+/*	$NetBSD: iris_prf.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ */
+
+#include <lib/libsa/stand.h>
+#include "iris_machdep.h"
+
+void
+putchar(int c)
+{
+
+	cnputc(c);
+}
+
+int
+getchar(void)
+{
+
+	return cngetc();
+}
Index: src/sys/arch/sgimips/stand/common/iris_scsi.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_scsi.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_scsi.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,838 @@
+/*	$NetBSD: iris_scsi.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ * WD33C93 SCSI bus driver for standalone programs.
+ */
+
+#include <sys/cdefs.h>
+#include <lib/libsa/stand.h>
+
+#ifndef	INDIGO_R3K_MODE
+#include <dev/arcbios/arcbios.h>
+#endif
+
+#include "iris_machdep.h"
+#include "iris_scsivar.h"
+#include "iris_scsireg.h"
+#include "iris_scsicmd.h"
+#include <dev/scsipi/scsi_message.h>
+
+#define SBIC_WAIT(regs, until, timeo) wd33c93_wait(regs, until, timeo)
+
+/*
+ * Timeouts
+ */
+int	wd33c93_cmd_wait	= SBIC_CMD_WAIT;
+int	wd33c93_data_wait	= SBIC_DATA_WAIT;
+int	wd33c93_init_wait	= SBIC_INIT_WAIT;
+
+#define STATUS_UNKNOWN	0xff
+
+void	wd33c93_reset(struct wd33c93_softc *);
+int	wd33c93_wait(struct wd33c93_softc *, uint8_t, int);
+uint8_t	wd33c93_selectbus(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
+	    size_t *);
+void	wd33c93_setsync(struct wd33c93_softc *);
+int	wd33c93_nextstate(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
+	    size_t *, uint8_t, uint8_t);
+size_t	wd33c93_xfout(struct wd33c93_softc *, void *, size_t *);
+int	wd33c93_intr(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
+	    size_t *);
+size_t	wd33c93_xfin(struct wd33c93_softc *, void *, size_t *);
+void	wd33c93_xferdone(struct wd33c93_softc *);
+int	wd33c93_abort(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
+	    size_t *);
+int	wd33c93_poll(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
+	    size_t *);
+void	wd33c93_timeout(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
+	    size_t *);
+int	wd33c93_msgin_phase(struct wd33c93_softc *);
+void	wd33c93_scsistart(struct wd33c93_softc *);
+void	wd33c93_scsidone(struct wd33c93_softc *);
+void	wd33c93_error(struct wd33c93_softc *);
+
+/*
+ * Initialize SPC & Data Structure
+ */
+void
+wd33c93_init(void *aaddr, void *daddr)
+{
+	struct wd33c93_softc *sc;
+
+	sc = &wd33c93_softc[scsi_ctlr];
+
+	sc->sc_asr_regh = aaddr;
+	sc->sc_data_regh = daddr;
+	sc->sc_target = scsi_id;
+
+	sc->sc_flags = 0;
+	sc->sc_state = SBIC_IDLE;
+
+	wd33c93_reset(sc);
+}
+
+void
+wd33c93_reset(struct wd33c93_softc *sc)
+{
+	u_int my_id;
+	uint8_t csr;
+
+	SET_SBIC_cmd(sc, SBIC_CMD_ABORT);
+	WAIT_CIP(sc);
+
+	my_id = sc->sc_target & SBIC_ID_MASK;
+
+	/* Set Clock == 20.0 MHz */
+	my_id |= SBIC_ID_FS_8_10;
+	sc->sc_syncperiods = 2 * 2 * 1250 / SCSI_CLKFREQ;
+
+	SET_SBIC_myid(sc, my_id);
+
+	/* Reset the chip */
+	SET_SBIC_cmd(sc, SBIC_CMD_RESET);
+	DELAY(25);
+	SBIC_WAIT(sc, SBIC_ASR_INT, 0);
+
+	/* PIO  mode */
+	SBIC_TC_PUT(sc, 0);
+	SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
+
+	/* clears interrupt also */
+	GET_SBIC_csr(sc, csr);
+	__USE(csr);
+
+	SET_SBIC_rselid(sc, SBIC_RID_ER);
+	SET_SBIC_syn(sc, 0);
+
+	sc->sc_flags = 0;
+	sc->sc_state = SBIC_IDLE;
+}
+
+int
+wd33c93_wait(struct wd33c93_softc *sc, uint8_t until, int timeo)
+{
+	uint8_t val;
+
+	if (timeo == 0)
+		/* some large value.. */
+		timeo = 1000000;
+
+	GET_SBIC_asr(sc, val);
+
+	while ((val & until) == 0) {
+		if (timeo-- == 0) {
+			return val;
+			break;
+		}
+		DELAY(1);
+		GET_SBIC_asr(sc, val);
+	}
+	return val;
+}
+
+/* SCSI command entry point */
+int
+wd33c93_go(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen, uint8_t *buf,
+    size_t *lenp)
+{
+	int	i;
+	uint8_t	csr, asr;
+
+	wd33c93_scsistart(sc);
+
+	sc->sc_status = STATUS_UNKNOWN;
+	sc->sc_flags = 0;
+	/* select the SCSI bus (it's an error if bus isn't free) */
+	if ((csr = wd33c93_selectbus(sc, cbuf, clen, buf, lenp)) == 0)
+		/* Not done: needs to be rescheduled */
+		return 1;
+
+	/*
+	 * Lets cycle a while then let the interrupt handler take over.
+	 */
+	GET_SBIC_asr(sc, asr);
+	do {
+		/* Handle the new phase */
+		i = wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr, asr);
+		WAIT_CIP(sc);		/* XXX */
+		if (sc->sc_state == SBIC_CONNECTED) {
+			GET_SBIC_asr(sc, asr);
+
+			if ((asr & SBIC_ASR_LCI) != 0)
+				DELAY(5000);
+
+			if ((asr & SBIC_ASR_INT) != 0)
+				GET_SBIC_csr(sc, csr);
+		}
+
+	} while (sc->sc_state == SBIC_CONNECTED &&
+	    (asr & (SBIC_ASR_INT|SBIC_ASR_LCI)) != 0);
+
+	if (i == SBIC_STATE_DONE) {
+		if (sc->sc_status == STATUS_UNKNOWN) {
+			printf("wd33c93_go: stat == UNKNOWN\n");
+			return 1;
+		}
+	}
+
+	if (wd33c93_poll(sc, cbuf, clen, buf, lenp)) {
+		wd33c93_timeout(sc, cbuf, clen, buf, lenp);
+		if (wd33c93_poll(sc, cbuf, clen, buf, lenp)) {
+			wd33c93_timeout(sc, cbuf, clen, buf, lenp);
+		}
+	}
+	return 0;
+}
+
+/*
+ * select the bus, return when selected or error.
+ *
+ * Returns the current CSR following selection and optionally MSG out phase.
+ * i.e. the returned CSR *should* indicate CMD phase...
+ * If the return value is 0, some error happened.
+ */
+uint8_t
+wd33c93_selectbus(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
+    uint8_t *buf, size_t *lenp)
+{
+	uint8_t asr, csr, id, lun, target;
+	static int i = 0;
+
+	sc->sc_state = SBIC_SELECTING;
+
+	target = sc->sc_target;
+	lun = SCSI_LUN;
+
+	/*
+	 * issue select
+	 */
+	SBIC_TC_PUT(sc, 0);
+	SET_SBIC_selid(sc, target);
+	SET_SBIC_timeo(sc, SBIC_TIMEOUT(250, SCSI_CLKFREQ));
+
+	GET_SBIC_asr(sc, asr);
+
+	if ((asr & (SBIC_ASR_INT|SBIC_ASR_BSY)) != 0) {
+		return 0;
+	}
+
+	SET_SBIC_cmd(sc, SBIC_CMD_SEL_ATN);
+	WAIT_CIP(sc);
+
+	/*
+	 * wait for select (merged from separate function may need
+	 * cleanup)
+	 */
+	do {
+		asr = SBIC_WAIT(sc, SBIC_ASR_INT | SBIC_ASR_LCI, 0);
+
+		if ((asr & SBIC_ASR_LCI) != 0) {
+			return 0;
+		}
+
+		/* Clear interrupt */
+		GET_SBIC_csr(sc, csr);
+
+		/* Reselected from under our feet? */
+		if (csr == SBIC_CSR_RSLT_NI || csr == SBIC_CSR_RSLT_IFY) {
+			/*
+			 * We need to handle this now so we don't lock up later
+			 */
+			wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr, asr);
+			return 0;
+		}
+		/* Whoops! */
+		if (csr == SBIC_CSR_SLT || csr == SBIC_CSR_SLT_ATN) {
+			return 0;
+		}
+	} while (csr != (SBIC_CSR_MIS_2 | MESG_OUT_PHASE) &&
+	    csr != (SBIC_CSR_MIS_2 | CMD_PHASE) &&
+	    csr != SBIC_CSR_SEL_TIMEO);
+
+	/* Anyone at home? */
+	if (csr == SBIC_CSR_SEL_TIMEO) {
+		return 0;
+	}
+
+	/* Assume we're now selected */
+	GET_SBIC_selid(sc, id);
+
+	if (id != target) {
+		/* Something went wrong - wrong target was select */
+		printf("wd33c93_selectbus: wrong target selected WANTED %d GOT %d \n",
+		    target, id);
+		printf("Boot failed!  Halting...\n");
+		reboot();
+	}
+
+	sc->sc_flags |= SBICF_SELECTED;
+	sc->sc_state  = SBIC_CONNECTED;
+
+	/* setup correct sync mode for this target */
+	wd33c93_setsync(sc);
+	SET_SBIC_rselid(sc, SBIC_RID_ER);
+
+	/*
+	 * We only really need to do anything when the target goes to MSG out
+	 * If the device ignored ATN, it's probably old and brain-dead,
+	 * but we'll try to support it anyhow.
+	 * If it doesn't support message out, it definately doesn't
+	 * support synchronous transfers, so no point in even asking...
+	 */
+
+	if (csr == (SBIC_CSR_MIS_2 | MESG_OUT_PHASE)) {
+		if (i < 6) {
+			SEND_BYTE(sc, MSG_IDENTIFY(lun, 0));
+			DELAY(200000);
+			i++;
+		} else {
+			/*
+		 	 * setup scsi message sync message request
+		 	 */
+			sc->sc_omsg[0] = MSG_IDENTIFY(lun, 0);
+			sc->sc_omsg[1] = MSG_EXTENDED;
+			sc->sc_omsg[2] = MSG_EXT_SDTR_LEN;
+			sc->sc_omsg[3] = MSG_EXT_SDTR;
+			sc->sc_omsg[4] = sc->sc_syncperiods;
+			sc->sc_omsg[5] = SBIC_SYN_93AB_MAX_OFFSET;
+
+			size_t foo = 6;
+			size_t *bar;
+			bar = &foo;
+
+			wd33c93_xfout(sc, sc->sc_omsg, bar);
+			sc->sc_flags  |= SBICF_SYNCNEGO;
+		}
+
+		SBIC_WAIT(sc, SBIC_ASR_INT , 0);
+		GET_SBIC_csr(sc, csr);
+	}
+	return csr;
+}
+
+/*
+ * Setup sync mode for given target
+ */
+void
+wd33c93_setsync(struct wd33c93_softc *sc)
+{
+	uint8_t syncreg;
+
+	syncreg = SBIC_SYN(0, 0, 0);
+
+	SET_SBIC_syn(sc, syncreg);
+}
+
+/*
+ * wd33c93_nextstate()
+ * return:
+ *	SBIC_STATE_DONE		== done
+ *	SBIC_STATE_RUNNING	== working
+ *	SBIC_STATE_DISCONNECT	== disconnected
+ *	SBIC_STATE_ERROR	== error
+ */
+int
+wd33c93_nextstate(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
+    uint8_t *buf, size_t *lenp, uint8_t csr, uint8_t asr)
+{
+	size_t *clenp;
+	size_t resid;
+
+	switch (csr) {
+	case SBIC_CSR_XFERRED | CMD_PHASE:
+	case SBIC_CSR_MIS     | CMD_PHASE:
+	case SBIC_CSR_MIS_1   | CMD_PHASE:
+	case SBIC_CSR_MIS_2   | CMD_PHASE:
+		clenp = &clen;
+
+		if (wd33c93_xfout(sc, cbuf, clenp))
+			goto abort;
+		break;
+
+	case SBIC_CSR_XFERRED | STATUS_PHASE:
+	case SBIC_CSR_MIS     | STATUS_PHASE:
+	case SBIC_CSR_MIS_1   | STATUS_PHASE:
+	case SBIC_CSR_MIS_2   | STATUS_PHASE:
+		SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
+
+		/*
+		 * this should be the normal i/o completion case.
+		 * get the status & cmd complete msg then let the
+		 * device driver look at what happened.
+		 */
+		wd33c93_xferdone(sc);
+		wd33c93_scsidone(sc);
+
+		return SBIC_STATE_DONE;
+
+	case SBIC_CSR_XFERRED | DATA_IN_PHASE:
+	case SBIC_CSR_MIS     | DATA_IN_PHASE:
+	case SBIC_CSR_MIS_1   | DATA_IN_PHASE:
+	case SBIC_CSR_MIS_2   | DATA_IN_PHASE:
+	case SBIC_CSR_XFERRED | DATA_OUT_PHASE:
+	case SBIC_CSR_MIS     | DATA_OUT_PHASE:
+	case SBIC_CSR_MIS_1   | DATA_OUT_PHASE:
+	case SBIC_CSR_MIS_2   | DATA_OUT_PHASE:
+		/*
+		 * Should we transfer using PIO or DMA ?
+		 */
+		/* Perfrom transfer using PIO */
+		if (SBIC_PHASE(csr) == DATA_IN_PHASE){
+			/* data in */
+			resid = wd33c93_xfin(sc, buf, lenp);
+			*lenp = resid;
+			wd33c93_intr(sc, cbuf, clen, buf, lenp);
+		} else {	/* data out */
+			resid = wd33c93_xfout(sc, buf, lenp);
+			*lenp = resid;
+		}
+		break;
+
+	case SBIC_CSR_XFERRED | MESG_IN_PHASE:
+	case SBIC_CSR_MIS     | MESG_IN_PHASE:
+	case SBIC_CSR_MIS_1   | MESG_IN_PHASE:
+	case SBIC_CSR_MIS_2   | MESG_IN_PHASE:
+		/* Handle a single message in... */
+		return wd33c93_msgin_phase(sc);
+
+	case SBIC_CSR_MSGIN_W_ACK:
+		/*
+		 * We should never see this since it's handled in
+		 * 'wd33c93_msgin_phase()' but just for the sake of paranoia...
+		 */
+		SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
+		break;
+
+	case SBIC_CSR_XFERRED | MESG_OUT_PHASE:
+	case SBIC_CSR_MIS     | MESG_OUT_PHASE:
+	case SBIC_CSR_MIS_1   | MESG_OUT_PHASE:
+	case SBIC_CSR_MIS_2   | MESG_OUT_PHASE:
+		/*
+		 * Message out phase.  ATN signal has been asserted
+		 */
+		return SBIC_STATE_RUNNING;
+
+	case SBIC_CSR_DISC:
+	case SBIC_CSR_DISC_1:
+		sc->sc_state = SBIC_IDLE;
+		sc->sc_flags = 0;
+
+		return SBIC_STATE_DISCONNECT;
+
+	case SBIC_CSR_RSLT_NI:
+	case SBIC_CSR_RSLT_IFY:
+	{
+		sc->sc_state = SBIC_RESELECTED;
+
+		if (csr == SBIC_CSR_RSLT_IFY)
+			SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
+		break;
+	}
+
+	default:
+	abort:
+		/* Something unexpected happend -- deal with it. */
+		printf("wd33c93_nextstate:abort\n");
+		printf("Boot failed!  Halting...\n");
+		reboot();
+	}
+	return SBIC_STATE_RUNNING;
+}
+
+/*
+ * Information Transfer *to* a SCSI Target.
+ *
+ * Note: Don't expect there to be an interrupt immediately after all
+ * the data is transferred out. The WD spec sheet says that the Transfer-
+ * Info command for non-MSG_IN phases only completes when the target
+ * next asserts 'REQ'. That is, when the SCSI bus changes to a new state.
+ *
+ * This can have a nasty effect on commands which take a relatively long
+ * time to complete, for example a START/STOP unit command may remain in
+ * CMD phase until the disk has spun up. Only then will the target change
+ * to STATUS phase. This is really only a problem for immediate commands
+ * since we don't allow disconnection for them (yet).
+ */
+size_t
+wd33c93_xfout(struct wd33c93_softc *sc, void *bp, size_t *lenp)
+{
+
+	int wait = wd33c93_data_wait;
+	uint8_t asr, *buf = bp;
+	size_t len = *lenp;
+
+	/*
+	 * sigh.. WD-PROTO strikes again.. sending the command in one go
+	 * causes the chip to lock up if talking to certain (misbehaving?)
+	 * targets. Anyway, this procedure should work for all targets, but
+	 * it's slightly slower due to the overhead
+	 */
+
+	SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
+	SBIC_TC_PUT(sc, (unsigned int)len);
+
+	WAIT_CIP(sc);
+	SET_SBIC_cmd(sc, SBIC_CMD_XFER_INFO);
+
+	/*
+	 * Loop for each byte transferred
+	 */
+	do {
+		GET_SBIC_asr(sc, asr);
+
+		if ((asr & SBIC_ASR_DBR) != 0) {
+			if (len != 0) {
+				SET_SBIC_data(sc, *buf);
+				buf++;
+				len--;
+			} else {
+				SET_SBIC_data(sc, 0);
+			}
+			wait = wd33c93_data_wait;
+		}
+	} while (len != 0 && (asr & SBIC_ASR_INT) == 0 && wait-- > 0);
+
+	/*
+	 * Normally, an interrupt will be pending when this routing returns.
+	 */
+	return len;
+}
+
+int
+wd33c93_intr(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
+    uint8_t *buf, size_t *lenp)
+{
+	uint8_t	asr, csr;
+
+	/*
+	 * pending interrupt?
+	 */
+	GET_SBIC_asr(sc, asr);
+	if ((asr & SBIC_ASR_INT) == 0)
+		return 0;
+
+	GET_SBIC_csr(sc, csr);
+
+	do {
+
+		(void)wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr, asr);
+		WAIT_CIP(sc);
+		if (sc->sc_state == SBIC_CONNECTED) {
+			GET_SBIC_asr(sc, asr);
+
+			if ((asr & SBIC_ASR_INT) != 0)
+				GET_SBIC_csr(sc, csr);
+		}
+	} while (sc->sc_state == SBIC_CONNECTED &&
+	    (asr & (SBIC_ASR_INT|SBIC_ASR_LCI)) != 0);
+
+	return 1;
+}
+
+/*
+ * Information Transfer *from* a Scsi Target
+ * returns # bytes left to read
+ */
+size_t
+wd33c93_xfin(struct wd33c93_softc *sc, void *bp, size_t *lenp)
+{
+	size_t len = *lenp;
+
+	int 	wait = wd33c93_data_wait;
+	uint8_t	*buf = bp;
+	uint8_t	asr;
+
+	SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
+	SBIC_TC_PUT(sc, (unsigned int)len);
+
+	WAIT_CIP(sc);
+	SET_SBIC_cmd(sc, SBIC_CMD_XFER_INFO);
+
+	/*
+	 * Loop for each byte transferred
+	 */
+	do {
+		GET_SBIC_asr(sc, asr);
+
+		if ((asr & SBIC_ASR_DBR) != 0) {
+			if (len != 0) {
+				GET_SBIC_data(sc, *buf);
+				buf++;
+				len--;
+			} else {
+				uint8_t foo;
+				GET_SBIC_data(sc, foo);
+				__USE(foo);
+			}
+			wait = wd33c93_data_wait;
+		}
+
+	} while ((asr & SBIC_ASR_INT) == 0 && wait-- > 0);
+
+	SBIC_TC_PUT(sc, 0);
+
+	/*
+	 * this leaves with one csr to be read
+	 */
+	return len;
+}
+
+/*
+ * Finish SCSI xfer command:  After the completion interrupt from
+ * a read/write operation, sequence through the final phases in
+ * programmed i/o.
+ */
+void
+wd33c93_xferdone(struct wd33c93_softc *sc)
+{
+	uint8_t	phase, csr;
+
+	/*
+	 * have the wd33c93 complete on its own
+	 */
+	SBIC_TC_PUT(sc, 0);
+	SET_SBIC_cmd_phase(sc, 0x46);
+	SET_SBIC_cmd(sc, SBIC_CMD_SEL_ATN_XFER);
+
+	do {
+		SBIC_WAIT(sc, SBIC_ASR_INT, 0);
+		GET_SBIC_csr(sc, csr);
+	} while ((csr != SBIC_CSR_DISC) &&
+		 (csr != SBIC_CSR_DISC_1) &&
+		 (csr != SBIC_CSR_S_XFERRED));
+
+	sc->sc_flags &= ~SBICF_SELECTED;
+	sc->sc_state = SBIC_DISCONNECT;
+
+	GET_SBIC_cmd_phase(sc, phase);
+
+	if (phase == 0x60)
+		GET_SBIC_tlun(sc, sc->sc_status);
+	else
+		wd33c93_error(sc);
+}
+
+int
+wd33c93_abort(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
+    uint8_t *buf, size_t *lenp)
+{
+	uint8_t csr, asr;
+
+	GET_SBIC_asr(sc, asr);
+	GET_SBIC_csr(sc, csr);
+
+	/*
+	 * Clean up chip itself
+	 */
+	wd33c93_timeout(sc, cbuf, clen, buf, lenp);
+
+	while ((asr & SBIC_ASR_DBR) != 0) {
+		/*
+		 * wd33c93 is jammed w/data. need to clear it
+		 * But we don't know what direction it needs to go
+		 */
+		GET_SBIC_data(sc, asr);
+		GET_SBIC_asr(sc, asr);
+		if ((asr & SBIC_ASR_DBR) != 0)
+			 /* Not the read direction */
+			SET_SBIC_data(sc, asr);
+		GET_SBIC_asr(sc, asr);
+	}
+
+	WAIT_CIP(sc);
+	SET_SBIC_cmd(sc, SBIC_CMD_ABORT);
+	WAIT_CIP(sc);
+
+	GET_SBIC_asr(sc, asr);
+
+	if ((asr & (SBIC_ASR_BSY|SBIC_ASR_LCI)) != 0) {
+		/*
+		 * ok, get more drastic..
+		 */
+		wd33c93_reset(sc);
+	} else {
+		SET_SBIC_cmd(sc, SBIC_CMD_DISC);
+		WAIT_CIP(sc);
+
+		do {
+			SBIC_WAIT(sc, SBIC_ASR_INT, 0);
+			GET_SBIC_asr(sc, asr);
+			GET_SBIC_csr(sc, csr);
+		} while ((csr != SBIC_CSR_DISC) &&
+		    (csr != SBIC_CSR_DISC_1) &&
+		    (csr != SBIC_CSR_CMD_INVALID));
+
+	sc->sc_state = SBIC_ERROR;
+	sc->sc_flags = 0;
+	}
+	return SBIC_STATE_ERROR;
+}
+
+void
+wd33c93_timeout(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
+    uint8_t *buf, size_t *lenp)
+{
+	uint8_t asr;
+
+	GET_SBIC_asr(sc, asr);
+
+	if ((asr & SBIC_ASR_INT) != 0) {
+		/* We need to service a missed IRQ */
+		wd33c93_intr(sc, cbuf, clen, buf, lenp);
+	} else {
+		wd33c93_abort(sc, cbuf, clen, buf, lenp);
+	}
+}
+
+/*
+ * Complete current command using polled I/O.Used when interrupt driven
+ * I/O is not allowed (ie. during boot and shutdown)
+ *
+ * Polled I/O is very processor intensive
+ */
+int
+wd33c93_poll(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
+    uint8_t *buf, size_t *lenp)
+{
+	uint8_t	asr, csr = 0;
+	int	count;
+
+	SBIC_WAIT(sc, SBIC_ASR_INT, wd33c93_cmd_wait);
+	for (count = SBIC_ABORT_TIMEOUT; count;) {
+		GET_SBIC_asr(sc, asr);
+		if ((asr & SBIC_ASR_LCI) != 0)
+			DELAY(5000);
+
+		if ((asr & SBIC_ASR_INT) != 0) {
+			GET_SBIC_csr(sc, csr);
+			(void)wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr,
+			    asr);
+			WAIT_CIP(sc);
+		} else {
+			DELAY(5000);
+			count--;
+		}
+
+		if ((sc->xs_status & XS_STS_DONE) != 0)
+			return 0;
+	}
+	return 1;
+}
+
+static inline int
+__verify_msg_format(uint8_t *p, int len)
+{
+
+	if (len == 1 && MSG_IS1BYTE(p[0]))
+		return 1;
+	if (len == 2 && MSG_IS2BYTE(p[0]))
+		return 1;
+	if (len >= 3 && MSG_ISEXTENDED(p[0]) &&
+	    len == p[1] + 2)
+		return 1;
+	return 0;
+}
+
+/*
+ * Handle message_in phase
+ */
+int
+wd33c93_msgin_phase(struct wd33c93_softc *sc)
+{
+	int len;
+	uint8_t asr, csr, *msg;
+
+	GET_SBIC_asr(sc, asr);
+	__USE(asr);
+
+	GET_SBIC_selid(sc, csr);
+	SET_SBIC_selid(sc, csr | SBIC_SID_FROM_SCSI);
+
+	SBIC_TC_PUT(sc, 0);
+
+	SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
+
+	msg = sc->sc_imsg;
+	len = 0;
+
+	do {
+		/* Fetch the next byte of the message */
+		RECV_BYTE(sc, *msg++);
+		len++;
+
+		/*
+		 * get the command completion interrupt, or we
+		 * can't send a new command (LCI)
+		 */
+		SBIC_WAIT(sc, SBIC_ASR_INT, 0);
+		GET_SBIC_csr(sc, csr);
+
+		if (__verify_msg_format(sc->sc_imsg, len))
+			/* Complete message received */
+			break;
+
+		/*
+		 * Clear ACK, and wait for the interrupt
+		 * for the next byte or phase change
+		 */
+		SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
+		SBIC_WAIT(sc, SBIC_ASR_INT, 0);
+
+		GET_SBIC_csr(sc, csr);
+	} while (len < SBIC_MAX_MSGLEN);
+
+	/*
+	 * Clear ACK, and wait for the interrupt
+	 * for the phase change
+	 */
+	SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
+	SBIC_WAIT(sc, SBIC_ASR_INT, 0);
+
+	/* Should still have one CSR to read */
+	return SBIC_STATE_RUNNING;
+}
+
+void
+wd33c93_scsistart(struct wd33c93_softc *sc)
+{
+
+	sc->xs_status = 0;
+}
+
+void
+wd33c93_scsidone(struct wd33c93_softc *sc)
+{
+
+	sc->xs_status = XS_STS_DONE;
+}
+
+void
+wd33c93_error(struct wd33c93_softc *sc)
+{
+}
Index: src/sys/arch/sgimips/stand/common/iris_scsicmd.h
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_scsicmd.h:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_scsicmd.h	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,100 @@
+/*	$NetBSD: iris_scsicmd.h,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ */
+
+/*
+ * scsipi_xfer status flags
+ */
+#define XS_STS_DONE		0x00000001
+
+/* SCSI Commands */
+#define CMD_TEST_UNIT_READY		0x00
+#define CMD_REQUEST_SENSE		0x03
+#define CMD_INQUIRY			0x12
+#define CMD_SEND_DIAGNOSTIC		0x1D
+
+#define CMD_REWIND			0x01
+#define CMD_REZERO			0x01
+#define CMD_FORMAT_UNIT			0x04
+#define CMD_READ_BLOCK_LIMITS		0x05
+#define CMD_REASSIGN_BLOCKS		0x07
+#define CMD_READ			0x08
+#define CMD_WRITE			0x0A
+#define CMD_WRITE_FILEMARK		0x10
+#define CMD_SPACE			0x11
+#define CMD_MODE_SELECT			0x15
+#define CMD_RELEASE_UNIT		0x17
+#define CMD_ERASE			0x19
+#define CMD_MODE_SENSE			0x1A
+#define CMD_LOADUNLOAD			0x1B
+#define CMD_RECEIVE_DIAG		0x1C
+#define CMD_SEND_DIAG			0x1D
+#define CMD_P_A_MEDIA_REMOVAL		0x1E
+#define CMD_READ_CAPACITY		0x25
+#define CMD_READ_EXT			0x28
+#define CMD_WRITE_EXT			0x2A
+#define CMD_READ_DEFECT_DATA		0x37
+#define 	SD_MANUFAC_DEFECTS	0x14000000
+#define 	SD_GROWN_DEFECTS	0x0c000000
+#define CMD_READ_BUFFER			0x3B
+#define CMD_WRITE_BUFFER		0x3C
+#define CMD_READ_FULL			0xF0
+#define CMD_MEDIA_TEST			0xF1
+#define CMD_ACCESS_LOG			0xF2
+#define CMD_WRITE_FULL			0xFC
+#define CMD_MANAGE_PRIMARY		0xFD
+#define CMD_EXECUTE_DATA		0xFE
+
+/* command descriptor blocks */
+
+struct scsi_cdb6 {
+	uint8_t	cmd;		/* command code */
+	uint8_t	lun:  3,	/* logical unit on ctlr */
+		lbah: 5;	/* msb of read/write logical block addr */
+	uint8_t	lbam;		/* middle byte of l.b.a. */
+	uint8_t	lbal;		/* lsb of l.b.a. */
+	uint8_t	len;		/* transfer length */
+	uint8_t	xtra;
+};
+
+struct scsi_cdb10 {
+	uint8_t	cmd;		/* command code */
+	uint8_t	lun: 3,		/* logical unit on ctlr */
+		   : 4,
+		rel: 1;		/* l.b.a. is relative addr if =1 */
+	uint8_t	lbah;		/* msb of read/write logical block addr */
+	uint8_t	lbahm;		/* high middle byte of l.b.a. */
+	uint8_t	lbalm;		/* low middle byte of l.b.a. */
+	uint8_t	lbal;		/* lsb of l.b.a. */
+	uint8_t	reserved;
+	uint8_t	lenh;		/* msb transfer length */
+	uint8_t	lenl;		/* lsb transfer length */
+	uint8_t	xtra;
+};
Index: src/sys/arch/sgimips/stand/common/iris_scsictl.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_scsictl.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_scsictl.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,109 @@
+/*	$NetBSD: iris_scsictl.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ * Front end of SCSI commands driver.
+ */
+
+#include <lib/libsa/stand.h>
+
+#include "iris_machdep.h"
+#include "iris_scsivar.h"
+#include "iris_scsicmd.h"
+
+int
+scsi_test_unit_rdy(void)
+{
+	struct wd33c93_softc *sc = &wd33c93_softc[scsi_ctlr];
+	static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
+
+	return wd33c93_go(sc, (uint8_t *)&cdb, sizeof(cdb), NULL, NULL);
+}
+
+int
+scsi_read_capacity(uint8_t *buf, size_t olen)
+{
+	size_t len = olen;
+	size_t *lenp;
+	lenp = &len;
+	struct wd33c93_softc *sc = &wd33c93_softc[scsi_ctlr];
+	static struct scsi_cdb10 cdb = { CMD_READ_CAPACITY };
+
+	return wd33c93_go(sc, (uint8_t *)&cdb, sizeof(cdb), buf, lenp);
+}
+
+int
+scsi_read(uint8_t *buf, size_t olen, daddr_t blk, u_int nblk)
+{
+	size_t len = olen;
+	size_t *lenp;
+	lenp = &len;
+	struct wd33c93_softc *sc = &wd33c93_softc[scsi_ctlr];
+	struct scsi_cdb10 cdb;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.cmd = CMD_READ_EXT;
+	cdb.lbah = blk >> 24;
+	cdb.lbahm = blk >> 16;
+	cdb.lbalm = blk >> 8;
+	cdb.lbal = blk;
+	cdb.lenh = nblk >> (8 + DEV_BSHIFT);
+	cdb.lenl = nblk >> DEV_BSHIFT;
+	wd33c93_go(sc, (uint8_t *)&cdb, sizeof(cdb), buf, lenp);
+
+	if (*lenp == olen)
+		return 1;
+
+	return 0;
+}
+
+int
+scsi_write(uint8_t *buf, size_t olen, daddr_t blk, u_int nblk)
+{
+	size_t len = olen;
+	size_t *lenp;
+	lenp = &len;
+
+	struct wd33c93_softc *sc = &wd33c93_softc[scsi_ctlr];
+	struct scsi_cdb10 cdb;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.cmd = CMD_WRITE_EXT;
+	cdb.lbah = blk >> 24;
+	cdb.lbahm = blk >> 16;
+	cdb.lbalm = blk >> 8;
+	cdb.lbal = blk;
+	cdb.lenh = nblk >> (8 + DEV_BSHIFT);
+	cdb.lenl = nblk >> DEV_BSHIFT;
+	wd33c93_go(sc, (uint8_t *)&cdb, sizeof(cdb), buf, lenp);
+
+	if (*lenp == olen)
+		return 1;
+
+	return 0;
+}
Index: src/sys/arch/sgimips/stand/common/iris_scsireg.h
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_scsireg.h:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_scsireg.h	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,505 @@
+/*	$NetBSD: iris_scsireg.h,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *  @(#)scsireg.h   7.3 (Berkeley) 2/5/91
+ */
+
+/*
+ * Copyright (c) 2001 Wayne Knowles
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *  This product includes software developed by the University of
+ *  California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *  @(#)scsireg.h   7.3 (Berkeley) 2/5/91
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ * WD33C93 SCSI interface hardware description.
+ * Most of the following was adapted from sys/dev/ic/wd33c93reg.h.
+ *	NetBSD: wd33c93reg.h,v 1.4 2009/02/12 06:24:45 rumble Exp
+ */
+
+#define SBIC_myid 		0
+#define SBIC_cdbsize		0
+#define SBIC_control		1
+#define SBIC_timeo 		2
+#define SBIC_cdb1 		3
+#define SBIC_tsecs 		3
+#define SBIC_cdb2 		4
+#define SBIC_theads 		4
+#define SBIC_cdb3 		5
+#define SBIC_tcyl_hi		5
+#define SBIC_cdb4 		6
+#define SBIC_tcyl_lo		6
+#define SBIC_cdb5 		7
+#define SBIC_addr_hi		7
+#define SBIC_cdb6 		8
+#define SBIC_addr_2 		8
+#define SBIC_cdb7 		9
+#define SBIC_addr_3 		9
+#define SBIC_cdb8 		10
+#define SBIC_addr_lo 		10
+#define SBIC_cdb9 		11
+#define SBIC_secno		11
+#define SBIC_cdb10		12
+#define SBIC_headno		12
+#define SBIC_cdb11		13
+#define SBIC_cylno_hi		13
+#define SBIC_cdb12		14
+#define SBIC_cylno_lo		14
+#define SBIC_tlun		15
+#define SBIC_cmd_phase		16
+#define SBIC_syn		17
+#define SBIC_count_hi		18
+#define SBIC_count_med		19
+#define SBIC_count_lo		20
+#define SBIC_selid		21
+#define SBIC_rselid		22
+#define SBIC_csr		23
+#define SBIC_cmd		24
+#define SBIC_data		25
+#define SBIC_queue_tag		26
+#define SBIC_aux_status		27
+
+/* wd33c93_asr is addressed directly */
+
+/*
+ *  Register defines
+ */
+
+/*
+ * Auxiliary Status Register
+ */
+
+#define SBIC_ASR_INT		0x80	/* Interrupt pending */
+#define SBIC_ASR_LCI		0x40	/* Last command ignored */
+#define SBIC_ASR_BSY		0x20	/* Busy, only cmd/data/asr readable */
+#define SBIC_ASR_CIP		0x10	/* Busy, cmd unavail also */
+#define SBIC_ASR_xxx		0x0c
+#define SBIC_ASR_PE		0x02	/* Parity error (even) */
+#define SBIC_ASR_DBR		0x01	/* Data Buffer Ready */
+
+/*
+ * My ID register, and/or CDB Size
+ */
+
+#define SBIC_ID_FS_8_10		0x00	/* Input clock is  8-10 MHz */
+										/* 11 MHz is invalid */
+#define SBIC_ID_FS_12_15	0x40	/* Input clock is 12-15 MHz */
+#define SBIC_ID_FS_16_20	0x80	/* Input clock is 16-20 MHz */
+#define SBIC_ID_RAF		0x20	/* Enable Really Advanced Features */
+#define SBIC_ID_EHP		0x10	/* Enable host parity */
+#define SBIC_ID_EAF		0x08	/* Enable Advanced Features */
+#define SBIC_ID_MASK		0x07
+#define SBIC_ID_CBDSIZE_MASK	0x0f	/* if unk SCSI cmd group */
+
+/*
+ * Control register
+ */
+
+#define SBIC_CTL_DMA		0x80	/* Single byte dma */
+#define SBIC_CTL_DBA_DMA	0x40	/* direct buffer access (bus master) */
+#define SBIC_CTL_BURST_DMA	0x20	/* continuous mode (8237) */
+#define SBIC_CTL_NO_DMA		0x00	/* Programmed I/O */
+#define SBIC_CTL_HHP		0x10	/* Halt on host parity error */
+#define SBIC_CTL_EDI		0x08	/* Ending disconnect interrupt */
+#define SBIC_CTL_IDI		0x04	/* Intermediate disconnect interrupt*/
+#define SBIC_CTL_HA		0x02	/* Halt on ATN */
+#define SBIC_CTL_scP		0x01	/* Halt on SCSI parity error */
+
+/*
+ * Timeout period register
+ * [val in msecs, input clk in 0.1 MHz]
+ */
+
+#define SBIC_TIMEOUT(val,clk)	((((val) * (clk)) / 800) + 1)
+
+/*
+ * CDBn registers, note that
+ *  cdb11 is used for status byte in target mode (send-status-and-cc)
+ *  cdb12 sez if linked command complete, and w/flag if so
+ */
+
+/*
+ * Target LUN register
+ * [holds target status when select-and-xfer]
+ */
+
+#define SBIC_TLUN_VALID		0x80	/* did we receive an Identify msg */
+#define SBIC_TLUN_DOK		0x40	/* Disconnect OK */
+#define SBIC_TLUN_xxx		0x38
+#define SBIC_TLUN_MASK		0x07
+
+/*
+ * Command Phase register
+ */
+
+#define SBIC_CPH_MASK		0x7f	/* values/restarts are cmd specific */
+#define SBIC_CPH(p)		((p) & SBIC_CPH_MASK)
+
+/*
+ * FIFO register
+ */
+
+#define SBIC_FIFO_93_DEPTH	5
+#define SBIC_FIFO_93AB_DEPTH	12
+
+/*
+ * maximum possible size in TC registers. Since this is 24 bit, it's easy
+ */
+#define SBIC_TC_MAX		((1 << 24) - 1)
+
+/*
+ * Synchronous xfer register
+ *
+ * NB: SBIC_SYN_FSS only valid on WD33C93B with 16-20MHz clock.
+ */
+
+#define SBIC_SYN_OFF_MASK	0x0f
+#define SBIC_SYN_93_MAX_OFFSET	(SBIC_FIFO_93_DEPTH - 1) /* 4 is recommended */
+#define SBIC_SYN_93AB_MAX_OFFSET SBIC_FIFO_93AB_DEPTH
+#define SBIC_SYN_PER_MASK	0x70
+#define SBIC_SYN_MIN_PERIOD	2	/* upto 8, encoded as 0 */
+#define SBIC_SYN_FSS		0x80	/* Enable Fast SCSI Transfers (10MB/s)*/
+
+#define SBIC_SYN(o, p, f)						\
+    (((o) & SBIC_SYN_OFF_MASK) | (((p) << 4) & SBIC_SYN_PER_MASK) |	\
+     ((f) ? SBIC_SYN_FSS : 0))
+
+/*
+ * Transfer count register
+ * optimal access macros depend on addressing
+ */
+
+/*
+ * Destination ID (selid) register
+ */
+
+#define SBIC_SID_SCC		0x80	/* Select command chaining (tgt) */
+#define SBIC_SID_DPD		0x40	/* Data phase direction (inittor) */
+#define SBIC_SID_FROM_SCSI	0x40
+#define SBIC_SID_TO_SCSI	0x00
+#define SBIC_SID_xxx		0x38
+#define SBIC_SID_IDMASK		0x07
+
+/*
+ * Source ID (rselid) register
+ */
+
+#define SBIC_RID_ER		0x80	/* Enable reselection */
+#define SBIC_RID_ES		0x40	/* Enable selection */
+#define SBIC_RID_DSP		0x20	/* Disable select parity */
+#define SBIC_RID_SIV		0x08	/* Source ID valid */
+#define SBIC_RID_MASK		0x07
+
+/*
+ * Status register
+ */
+
+#define SBIC_CSR_CAUSE		0xf0
+#define SBIC_CSR_RESET		0x00	/* chip was reset */
+#define SBIC_CSR_CMD_DONE	0x10	/* cmd completed */
+#define SBIC_CSR_CMD_STOPPED	0x20	/* interrupted or abrted*/
+#define SBIC_CSR_CMD_ERR	0x40	/* end with error */
+#define SBIC_CSR_BUS_SERVICE	0x80	/* REQ pending on the bus */
+
+
+#define SBIC_CSR_QUALIFIER	0x0f
+/* Reset State Interrupts */
+#define SBIC_CSR_RESET		0x00	/* reset w/advanced features*/
+#define SBIC_CSR_RESET_AM	0x01	/* reset w/advanced features*/
+/* Successful Completion Interrupts */
+#define SBIC_CSR_TARGET		0x10	/* reselect complete */
+#define SBIC_CSR_INITIATOR	0x11	/* select complete */
+#define SBIC_CSR_WO_ATN		0x13	/* tgt mode completion */
+#define SBIC_CSR_W_ATN		0x14	/* ditto */
+#define SBIC_CSR_XLATED		0x15	/* translate address cmd */
+#define SBIC_CSR_S_XFERRED	0x16	/* initiator mode completion*/
+#define SBIC_CSR_XFERRED	0x18	/* phase in low bits */
+/* Paused or Aborted Interrupts */
+#define SBIC_CSR_MSGIN_W_ACK	0x20	/* (I) msgin, ACK asserted*/
+#define SBIC_CSR_SDP		0x21	/* (I) SDP msg received */
+#define SBIC_CSR_SEL_ABRT	0x22	/* sel/resel aborted */
+#define SBIC_CSR_XFR_PAUSED	0x23	/* (T) no ATN */
+#define SBIC_CSR_XFR_PAUSED_ATN	0x24	/* (T) ATN is asserted */
+#define SBIC_CSR_RSLT_AM	0x27	/* (I) lost selection (AM) */
+#define SBIC_CSR_MIS		0x28	/* (I) xfer aborted, ph mis */
+/* Terminated Interrupts */
+#define SBIC_CSR_CMD_INVALID	0x40
+#define SBIC_CSR_DISC		0x41	/* (I) tgt disconnected */
+#define SBIC_CSR_SEL_TIMEO	0x42
+#define SBIC_CSR_PE		0x43	/* parity error */
+#define SBIC_CSR_PE_ATN		0x44	/* ditto, ATN is asserted */
+#define SBIC_CSR_XLATE_TOOBIG	0x45
+#define SBIC_CSR_RSLT_NOAM	0x46	/* (I) lost sel, no AM mode */
+#define SBIC_CSR_BAD_STATUS	0x47	/* status byte was nok */
+#define SBIC_CSR_MIS_1		0x48	/* ph mis, see low bits */
+/* Service Required Interrupts */
+#define SBIC_CSR_RSLT_NI	0x80	/* reselected, no ify msg */
+#define SBIC_CSR_RSLT_IFY	0x81	/* ditto, AM mode, got ify */
+#define SBIC_CSR_SLT		0x82	/* selected, no ATN */
+#define SBIC_CSR_SLT_ATN	0x83	/* selected with ATN */
+#define SBIC_CSR_ATN		0x84	/* (T) ATN asserted */
+#define SBIC_CSR_DISC_1		0x85	/* (I) bus is free */
+#define SBIC_CSR_UNK_GROUP	0x87	/* strange CDB1 */
+#define SBIC_CSR_MIS_2		0x88	/* (I) ph mis, see low bits */
+
+#define SBIC_PHASE(csr)		SCSI_PHASE(csr)
+
+/*
+ * Command register (command codes)
+ */
+#define SBIC_CMD_SBT		0x80	/* Single byte xfer qualifier */
+#define SBIC_CMD_MASK		0x7f
+
+		    /* Miscellaneous */
+#define SBIC_CMD_RESET		0x00	/* (DTI) lev I */
+#define SBIC_CMD_ABORT		0x01	/* (DTI) lev I */
+#define SBIC_CMD_DISC		0x04	/* ( TI) lev I */
+#define SBIC_CMD_SSCC		0x0d	/* ( TI) lev I */
+#define SBIC_CMD_SET_IDI	0x0f	/* (DTI) lev I */
+#define SBIC_CMD_XLATE		0x18	/* (DT ) lev II */
+
+		    /* Initiator state */
+#define SBIC_CMD_SET_ATN	0x02	/* (  I) lev I */
+#define SBIC_CMD_CLR_ACK	0x03	/* (  I) lev I */
+#define SBIC_CMD_XFER_PAD	0x19	/* (  I) lev II */
+#define SBIC_CMD_XFER_INFO	0x20	/* (  I) lev II */
+
+		    /* Target state */
+#define SBIC_CMD_SND_DISC	0x0e	/* ( T ) lev II */
+#define SBIC_CMD_RCV_CMD	0x10	/* ( T ) lev II */
+#define SBIC_CMD_RCV_DATA	0x11	/* ( T ) lev II */
+#define SBIC_CMD_RCV_MSG_OUT	0x12	/* ( T ) lev II */
+#define SBIC_CMD_RCV		0x13	/* ( T ) lev II */
+#define SBIC_CMD_SND_STATUS	0x14	/* ( T ) lev II */
+#define SBIC_CMD_SND_DATA	0x15	/* ( T ) lev II */
+#define SBIC_CMD_SND_MSG_IN	0x16	/* ( T ) lev II */
+#define SBIC_CMD_SND		0x17	/* ( T ) lev II */
+
+		    /* Disconnected state */
+#define SBIC_CMD_RESELECT	0x05	/* (D  ) lev II */
+#define SBIC_CMD_SEL_ATN	0x06	/* (D  ) lev II */
+#define SBIC_CMD_SEL		0x07	/* (D  ) lev II */
+#define SBIC_CMD_SEL_ATN_XFER	0x08	/* (D I) lev II */
+#define SBIC_CMD_SEL_XFER	0x09	/* (D I) lev II */
+#define SBIC_CMD_RESELECT_RECV	0x0a	/* (DT ) lev II */
+#define SBIC_CMD_RESELECT_SEND	0x0b	/* (DT ) lev II */
+#define SBIC_CMD_WAIT_SEL_RECV	0x0c	/* (DT ) lev II */
+
+
+#define PHASE_MASK		0x07	/* mask for psns/pctl phase */
+#define DATA_OUT_PHASE		0x00
+#define DATA_IN_PHASE		0x01
+#define CMD_PHASE		0x02
+#define STATUS_PHASE		0x03
+#define BUS_FREE_PHASE		0x04
+#define ARB_SEL_PHASE		0x05	/* Fuji chip combines bus arb with sel. */
+#define MESG_OUT_PHASE		0x06
+#define MESG_IN_PHASE		0x07
+
+#define SCSI_PHASE(reg)	((reg) & PHASE_MASK)
+
+#define SCSI_STATUS_MASK	0x3e	/* Mask unused bits in status byte */
+
+/*
+ * WD33C93 has two registers:
+ *    ASR  - r : Aux Status Register, w : desired register no
+ *    DATA - rw: register value
+ *
+ * We access them via separate handles because some people *cough*SGI*cough*
+ * like to keep them apart.
+ */
+
+#define wd33c93_read_reg(sc, regno, val)				\
+	do {								\
+		*(volatile uint8_t *)(sc)->sc_asr_regh = (regno);	\
+		(val) = *(volatile uint8_t *)(sc)->sc_data_regh;	\
+	} while (/* CONSTCOND */0)
+
+#define wd33c93_write_reg(sc, regno, val)				\
+	do {								\
+		*(volatile uint8_t *)(sc)->sc_asr_regh = (regno);	\
+		*(volatile uint8_t *)(sc)->sc_data_regh = (val);	\
+	} while (/* CONSTCOND */0)
+
+#define SET_SBIC_myid(sc,val)		wd33c93_write_reg(sc,SBIC_myid,val)
+#define GET_SBIC_myid(sc,val)		wd33c93_read_reg(sc,SBIC_myid,val)
+#define SET_SBIC_cdbsize(sc,val)	wd33c93_write_reg(sc,SBIC_cdbsize,val)
+#define GET_SBIC_cdbsize(sc,val)	wd33c93_read_reg(sc,SBIC_cdbsize,val)
+#define SET_SBIC_control(sc,val)	wd33c93_write_reg(sc,SBIC_control,val)
+#define GET_SBIC_control(sc,val)	wd33c93_read_reg(sc,SBIC_control,val)
+#define SET_SBIC_timeo(sc,val)		wd33c93_write_reg(sc,SBIC_timeo,val)
+#define GET_SBIC_timeo(sc,val)		wd33c93_read_reg(sc,SBIC_timeo,val)
+#define SET_SBIC_cdb1(sc,val)		wd33c93_write_reg(sc,SBIC_cdb1,val)
+#define GET_SBIC_cdb1(sc,val)		wd33c93_read_reg(sc,SBIC_cdb1,val)
+#define SET_SBIC_cdb2(sc,val)		wd33c93_write_reg(sc,SBIC_cdb2,val)
+#define GET_SBIC_cdb2(sc,val)		wd33c93_read_reg(sc,SBIC_cdb2,val)
+#define SET_SBIC_cdb3(sc,val)		wd33c93_write_reg(sc,SBIC_cdb3,val)
+#define GET_SBIC_cdb3(sc,val)		wd33c93_read_reg(sc,SBIC_cdb3,val)
+#define SET_SBIC_cdb4(sc,val)		wd33c93_write_reg(sc,SBIC_cdb4,val)
+#define GET_SBIC_cdb4(sc,val)		wd33c93_read_reg(sc,SBIC_cdb4,val)
+#define SET_SBIC_cdb5(sc,val)		wd33c93_write_reg(sc,SBIC_cdb5,val)
+#define GET_SBIC_cdb5(sc,val)		wd33c93_read_reg(sc,SBIC_cdb5,val)
+#define SET_SBIC_cdb6(sc,val)		wd33c93_write_reg(sc,SBIC_cdb6,val)
+#define GET_SBIC_cdb6(sc,val)		wd33c93_read_reg(sc,SBIC_cdb6,val)
+#define SET_SBIC_cdb7(sc,val)		wd33c93_write_reg(sc,SBIC_cdb7,val)
+#define GET_SBIC_cdb7(sc,val)		wd33c93_read_reg(sc,SBIC_cdb7,val)
+#define SET_SBIC_cdb8(sc,val)		wd33c93_write_reg(sc,SBIC_cdb8,val)
+#define GET_SBIC_cdb8(sc,val)		wd33c93_read_reg(sc,SBIC_cdb8,val)
+#define SET_SBIC_cdb9(sc,val)		wd33c93_write_reg(sc,SBIC_cdb9,val)
+#define GET_SBIC_cdb9(sc,val)		wd33c93_read_reg(sc,SBIC_cdb9,val)
+#define SET_SBIC_cdb10(sc,val)		wd33c93_write_reg(sc,SBIC_cdb10,val)
+#define GET_SBIC_cdb10(sc,val)		wd33c93_read_reg(sc,SBIC_cdb10,val)
+#define SET_SBIC_cdb11(sc,val)		wd33c93_write_reg(sc,SBIC_cdb11,val)
+#define GET_SBIC_cdb11(sc,val)		wd33c93_read_reg(sc,SBIC_cdb11,val)
+#define SET_SBIC_cdb12(sc,val)		wd33c93_write_reg(sc,SBIC_cdb12,val)
+#define GET_SBIC_cdb12(sc,val)		wd33c93_read_reg(sc,SBIC_cdb12,val)
+#define SET_SBIC_tlun(sc,val)		wd33c93_write_reg(sc,SBIC_tlun,val)
+#define GET_SBIC_tlun(sc,val)		wd33c93_read_reg(sc,SBIC_tlun,val)
+#define SET_SBIC_cmd_phase(sc,val)	wd33c93_write_reg(sc,SBIC_cmd_phase,val)
+#define GET_SBIC_cmd_phase(sc,val)	wd33c93_read_reg(sc,SBIC_cmd_phase,val)
+#define SET_SBIC_syn(sc,val)		wd33c93_write_reg(sc,SBIC_syn,val)
+#define GET_SBIC_syn(sc,val)		wd33c93_read_reg(sc,SBIC_syn,val)
+#define SET_SBIC_count_hi(sc,val)	wd33c93_write_reg(sc,SBIC_count_hi,val)
+#define GET_SBIC_count_hi(sc,val)	wd33c93_read_reg(sc,SBIC_count_hi,val)
+#define SET_SBIC_count_med(sc,val)	wd33c93_write_reg(sc,SBIC_count_med,val)
+#define GET_SBIC_count_med(sc,val)	wd33c93_read_reg(sc,SBIC_count_med,val)
+#define SET_SBIC_count_lo(sc,val)	wd33c93_write_reg(sc,SBIC_count_lo,val)
+#define GET_SBIC_count_lo(sc,val)	wd33c93_read_reg(sc,SBIC_count_lo,val)
+#define SET_SBIC_selid(sc,val)		wd33c93_write_reg(sc,SBIC_selid,val)
+#define GET_SBIC_selid(sc,val)		wd33c93_read_reg(sc,SBIC_selid,val)
+#define SET_SBIC_rselid(sc,val)		wd33c93_write_reg(sc,SBIC_rselid,val)
+#define GET_SBIC_rselid(sc,val)		wd33c93_read_reg(sc,SBIC_rselid,val)
+#define SET_SBIC_csr(sc,val)		wd33c93_write_reg(sc,SBIC_csr,val)
+#define GET_SBIC_csr(sc,val)		wd33c93_read_reg(sc,SBIC_csr,val)
+#define SET_SBIC_cmd(sc,val)		wd33c93_write_reg(sc,SBIC_cmd,val)
+#define GET_SBIC_cmd(sc,val)		wd33c93_read_reg(sc,SBIC_cmd,val)
+#define SET_SBIC_data(sc,val)		wd33c93_write_reg(sc,SBIC_data,val)
+#define GET_SBIC_data(sc,val)		wd33c93_read_reg(sc,SBIC_data,val)
+#define SET_SBIC_queue_tag(sc,val)	wd33c93_write_reg(sc,SBIC_queue_tag,val)
+#define GET_SBIC_queue_tag(sc,val)	wd33c93_read_reg(sc,SBIC_queue_tag,val)
+
+#define SBIC_TC_PUT(sc, val)						\
+	do {								\
+		wd33c93_write_reg(sc, SBIC_count_hi, ((val) >> 16));	\
+		*(volatile uint8_t *)(sc)->sc_data_regh = (val) >> 8; 	\
+		*(volatile uint8_t *)(sc)->sc_data_regh = (val);	\
+	} while (/* CONSTCOND */0)
+
+#define GET_SBIC_asr(sc, val)						\
+	do {								\
+		(val) = *(volatile uint8_t *)(sc)->sc_asr_regh;		\
+	} while (/* CONSTCOND */0)
+
+#define WAIT_CIP(sc)							\
+	do {								\
+		while (*(volatile uint8_t *)(sc)->sc_asr_regh & SBIC_ASR_CIP) \
+			continue;					\
+	} while (/* CONSTCOND */0)
+
+/*
+ * transmit a byte in programmed I/O mode
+ */
+#define SEND_BYTE(sc, ch)						\
+	do {								\
+		WAIT_CIP(sc);						\
+		SET_SBIC_cmd(sc, SBIC_CMD_SBT | SBIC_CMD_XFER_INFO);	\
+		SBIC_WAIT(sc, SBIC_ASR_DBR, 0);				\
+		SET_SBIC_data(sc, ch);					\
+	} while (/* CONSTCOND */0)
+
+/*
+ * receive a byte in programmed I/O mode
+ */
+#define RECV_BYTE(sc, ch)						\
+	do {								\
+		WAIT_CIP(sc);						\
+		SET_SBIC_cmd(sc, SBIC_CMD_SBT | SBIC_CMD_XFER_INFO);	\
+		SBIC_WAIT(sc, SBIC_ASR_DBR, 0);				\
+		GET_SBIC_data(sc, ch);					\
+	} while (/* CONSTCOND */0)
Index: src/sys/arch/sgimips/stand/common/iris_scsivar.h
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_scsivar.h:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_scsivar.h	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,123 @@
+/*	$NetBSD: iris_scsivar.h,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ * WD33C93 SCSI interface parameter description.
+ */
+
+#ifndef _SCSIVAR_H_
+#define _SCSIVAR_H_
+
+#define SBIC_MAX_MSGLEN	8
+#define SBIC_ABORT_TIMEOUT	2000	/* time to wait for abort */
+
+/*
+ * SCSI delays
+ * In u-seconds, primarily for state changes on the SPC.
+ */
+#define SBIC_CMD_WAIT	50000	/* wait per step of 'immediate' cmds */
+#define SBIC_DATA_WAIT	50000	/* wait per data in/out step */
+#define SBIC_INIT_WAIT	50000	/* wait per step (both) during init */
+
+#define NSCSI			1
+#define SCSI_LUN		0
+#define SCSI_CLKFREQ		20
+
+struct	wd33c93_softc {
+	volatile uint8_t *sc_asr_regh;	/* address register */
+	volatile uint8_t *sc_data_regh;	/* data register */
+	uint8_t sc_target;		/* Currently active target */
+	uint8_t sc_syncperiods;		/* Sync transfer periods (4ns units) */
+	u_short	sc_state;
+	u_short	sc_status;
+	int	sc_flags;
+	uint8_t	sc_imsg[SBIC_MAX_MSGLEN];
+	uint8_t	sc_omsg[SBIC_MAX_MSGLEN];
+	volatile int xs_status;		/* status flags */
+};
+
+struct wd33c93_softc wd33c93_softc[NSCSI];
+
+extern uint8_t scsi_ctlr, scsi_id, scsi_part;
+
+/* values for sc_flags */
+#define SBICF_SELECTED	0x01	/* bus is in selected state. */
+#define SBICF_NODMA	0x02	/* Polled transfer */
+#define SBICF_INDMA	0x04	/* DMA I/O in progress */
+#define SBICF_SYNCNEGO	0x08	/* Sync negotiation in progress */
+#define SBICF_ABORTING	0x10	/* Aborting */
+
+/* values for sc_state */
+#define SBIC_UNINITIALIZED	0	/* Driver not initialized */
+#define SBIC_IDLE		1	/* waiting for something to do */
+#define SBIC_SELECTING		2	/* SCSI command is arbiting */
+#define SBIC_RESELECTED		3	/* Has been reselected */
+#define SBIC_IDENTIFIED		4	/* Has gotten IFY but not TAG */
+#define SBIC_CONNECTED		5	/* Actively using the SCSI bus */
+#define SBIC_DISCONNECT		6	/* MSG_DISCONNECT received */
+#define SBIC_CMDCOMPLETE 	7	/* MSG_CMDCOMPLETE received */
+#define SBIC_ERROR		8	/* Error has occurred */
+#define SBIC_SELTIMEOUT		9	/* Select Timeout */
+#define SBIC_CLEANING		10	/* Scrubbing ACB's */
+#define SBIC_BUSRESET		11	/* SCSI RST has been issued */
+
+/* values for sc_msgout */
+#define SEND_DEV_RESET		0x0001
+#define SEND_PARITY_ERROR	0x0002
+#define SEND_INIT_DET_ERR	0x0004
+#define SEND_REJECT		0x0008
+#define SEND_IDENTIFY		0x0010
+#define SEND_ABORT		0x0020
+#define SEND_WDTR		0x0040
+#define SEND_SDTR		0x0080
+#define SEND_TAG		0x0100
+
+#define STS_CHECKCOND		0x02	/* Check Condition (ie., read sense) */
+
+/*
+ * States returned by our state machine
+ */
+#define SBIC_STATE_ERROR	-1
+#define SBIC_STATE_DONE		0
+#define SBIC_STATE_RUNNING	1
+#define SBIC_STATE_DISCONNECT	2
+
+#define DEBUG_ACBS	0x01
+#define DEBUG_INTS	0x02
+#define DEBUG_CMDS	0x04
+#define DEBUG_MISC	0x08
+#define DEBUG_TRAC	0x10
+#define DEBUG_RSEL	0x20
+#define DEBUG_PHASE	0x40
+#define DEBUG_DMA	0x80
+#define DEBUG_CCMDS	0x100
+#define DEBUG_MSGS	0x200
+#define DEBUG_TAGS	0x400
+#define DEBUG_SYNC	0x800
+
+#endif /* _SCSIVAR_H_ */
Index: src/sys/arch/sgimips/stand/common/iris_start.S
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_start.S:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_start.S	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,67 @@
+/*	$NetBSD: iris_start.S,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ */
+
+#include <mips/asm.h>
+#include <mips/cpuregs.h>
+
+	.globl	start
+start:
+	.set	noreorder
+#ifdef __GP_SUPPORT__
+	la	gp, _C_LABEL(_gp)
+#endif
+	/*
+	 * We assume the bootprom isn't expecting us to preserve the saved
+	 * registers.
+	 */
+	move	s0, a0				# save argc
+	move	s1, a1				# save argv
+	move	s2, a2				# save envp
+	move	s3, ra				# save RA
+
+	la	a0, _C_LABEL(edata)		# clear BSS
+	move	a1, zero
+	la	a2, _C_LABEL(end)
+	jal	_C_LABEL(memset)		# memset(edata, 0, end - edata)
+	 subu	a2, a2, a0
+
+	move	a0, s0				# restore argc
+	move	a1, s1				# restore argv
+	move	a2, s2				# restore envp
+	j	_C_LABEL(main)			# main(argc, argv)
+	 move	ra, s3				# restore RA
+
+LEAF(romrestart)
+XLEAF(_rtt)
+	PTR_LA	v0, 0xBFC00000			# indigo RESET
+	j	v0
+	 nop
+END(romrestart)
Index: src/sys/arch/sgimips/stand/common/iris_zs.c
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_zs.c:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_zs.c	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,261 @@
+/*	$NetBSD: iris_zs.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1996, 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gordon W. Ross and Wayne Knowles
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ * Zilog Z8530 Dual UART driver.
+ * Most of the following was adapted from /sys/arch/sgimips/dev/zs.c.
+ *	NetBSD: zs.c,v 1.39 2015/02/18 16:47:58 macallan Exp
+ */
+
+#include <lib/libsa/stand.h>
+#include <lib/libkern/libkern.h>
+
+#include <dev/ic/z8530reg.h>
+
+#include <mips/cpuregs.h>
+#include <machine/cpu.h>
+
+#include "iris_machdep.h"
+#include "iris_zs.h"
+
+#define ZSCLOCK		3672000	 /* PCLK pin input clock rate */
+#define ZS_DELAY()	DELAY(3)
+#define ZS_DEFSPEED	9600
+
+static void zs_write(void *, uint8_t);
+static void zs_write_reg(void *, uint8_t, uint8_t);
+static void zs_reset(void *);
+static struct zschan *zs_get_chan_addr(int zs_unit, int channel);
+int	zs_getc(void *);
+void	zs_putc(void *, int);
+int	zs_scan(void *);
+
+static int cons_port;
+
+static void
+zs_write(void *dev, uint8_t val)
+{
+	struct zschan *zc = dev;
+
+	zc->zc_csr = val;
+	ZS_DELAY();
+}
+
+static void
+zs_write_reg(void *dev, uint8_t reg, uint8_t val)
+{
+
+	zs_write(dev, reg);
+	zs_write(dev, val);
+}
+
+static void
+zs_reset(void *dev)
+{
+
+	/* clear errors */
+	zs_write_reg(dev,  9, 0);
+	/* hardware reset */
+	zs_write_reg(dev,  9, ZSWR9_HARD_RESET);
+	DELAY(1000);
+
+	/* disable all inerttupts */
+	zs_write_reg(dev,  1, 0);
+
+	/* set TX/RX misc parameters and modes */
+	zs_write_reg(dev,  4, ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP);
+	zs_write_reg(dev, 10, ZSWR10_NRZ);
+	zs_write_reg(dev,  3, ZSWR3_RX_8);
+	zs_write_reg(dev,  5, ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_RTS);
+
+	/* sync registers unused */
+	zs_write_reg(dev,  6, 0);
+	zs_write_reg(dev,  7, 0);
+
+	/* set clock mode */
+	zs_write_reg(dev, 11,
+	    ZSWR11_RXCLK_BAUD | ZSWR11_TXCLK_BAUD | ZSWR11_TRXC_OUT_ENA);
+
+	/* set baud rate constant */
+	zs_write_reg(dev, 12, BPS_TO_TCONST(ZSCLOCK / 16, ZS_DEFSPEED));
+	zs_write_reg(dev, 13, 0);
+
+	/* enable baud rate generator */
+	zs_write_reg(dev, 14, ZSWR14_BAUD_ENA);
+
+	/* disable all external interrupts */
+	zs_write_reg(dev, 15, 0);
+
+	/* reset external status twice (see src/sys/dev/ic/z8530sc.c) */
+	zs_write(dev, ZSWR0_RESET_STATUS);
+	zs_write(dev, ZSWR0_RESET_STATUS);
+
+	/* enable TX and RX */
+	zs_write_reg(dev,  3, ZSWR3_RX_8 | ZSWR3_RX_ENABLE);
+	zs_write_reg(dev,  5,
+	    ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_RTS | ZSWR5_TX_ENABLE);
+}
+
+static struct zschan *
+zs_get_chan_addr(int zs_unit, int channel)
+{
+	struct zsdevice *addr;
+	struct zschan *zc;
+
+	addr = (struct zsdevice *)MIPS_PHYS_TO_KSEG1(ZS_ADDR);
+
+	zc = &addr->zs_chan_b;
+
+	return zc;
+}
+
+void *
+zs_init(int addr, int speed)
+{
+	struct zschan *zs;
+	cons_port = 0;
+
+	zs = zs_get_chan_addr(1, cons_port);
+
+	zs_reset(zs);
+
+	return zs;
+}
+
+void
+zscnputc(void *dev, int c)
+{
+	struct zschan *zs;
+
+	zs = zs_get_chan_addr(1, cons_port);
+
+	zs_putc(zs, c);
+}
+
+void
+zs_putc(void *arg, int c)
+{
+	register volatile struct zschan *zc = arg;
+	register int rr0;
+
+	/* Wait for transmitter to become ready. */
+	do {
+		rr0 = zc->zc_csr;
+		ZS_DELAY();
+	} while ((rr0 & ZSRR0_TX_READY) == 0);
+
+	zc->zc_data = c;
+	ZS_DELAY();
+}
+
+int
+zscngetc(void *dev)
+{
+	struct zschan *zs;
+
+	zs = zs_get_chan_addr(1, cons_port);
+
+	return zs_getc(zs);
+}
+
+int
+zs_getc(void *arg)
+{
+	struct zschan *zc = arg;
+	int c, rr0;
+
+	/* Wait for a character to arrive. */
+	do {
+		rr0 = zc->zc_csr;
+		ZS_DELAY();
+	} while ((rr0 & ZSRR0_RX_READY) == 0);
+
+	c = zc->zc_data;
+	ZS_DELAY();
+
+	return c;
+}
+
+int
+zscnscanc(void *dev)
+{
+	struct zschan *zs;
+
+	zs = zs_get_chan_addr(1, cons_port);
+
+	return zs_scan(zs);
+}
+
+int
+zs_scan(void *arg)
+{
+	struct zschan *zc = arg;
+	int c, rr0;
+
+	/* Wait for a character to arrive. */
+	rr0 = zc->zc_csr;
+	ZS_DELAY();
+
+	if ((rr0 & ZSRR0_RX_READY) == 0) {
+		return -1;
+	}
+
+	c = zc->zc_data;
+	ZS_DELAY();
+
+	return c;
+}
Index: src/sys/arch/sgimips/stand/common/iris_zs.h
diff -u /dev/null src/sys/arch/sgimips/stand/common/iris_zs.h:1.1
--- /dev/null	Sat Jan 12 16:44:48 2019
+++ src/sys/arch/sgimips/stand/common/iris_zs.h	Sat Jan 12 16:44:47 2019
@@ -0,0 +1,48 @@
+/*	$NetBSD: iris_zs.h,v 1.1 2019/01/12 16:44:47 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2018 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
+ */
+
+/* The layout of this is hardware-dependent (padding, order). */
+struct zschan {
+	uint8_t pad1[3];
+	volatile uint8_t zc_csr;	/* ctrl,status, and indirect access */
+	uint8_t pad2[3];
+	volatile uint8_t zc_data;	/* data */
+};
+
+struct zsdevice {
+	struct	zschan zs_chan_b;
+	struct	zschan zs_chan_a;
+};
+
+void *zs_init(int, int);
+int  zscngetc(void *);
+void zscnputc(void *, int);
+int  zscnscanc(void *);

Reply via email to