? arch/sgimips/dev/dp8573areg.h
? arch/sgimips/dev/dpclock.c
? arch/sgimips/dev/dsclock.c
? dev/microcode/ral/obj
? dev/microcode/rum/obj
? dev/microcode/zyd/obj
Index: arch/sgimips/conf/GENERIC32_IP12
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/conf/GENERIC32_IP12,v
retrieving revision 1.4
diff -p -u -r1.4 GENERIC32_IP12
--- arch/sgimips/conf/GENERIC32_IP12	17 Oct 2007 19:57:03 -0000	1.4
+++ arch/sgimips/conf/GENERIC32_IP12	10 Feb 2009 08:16:53 -0000
@@ -1,21 +1,304 @@
-#	$NetBSD: GENERIC32_IP12,v 1.4 2007/10/17 19:57:03 garbled Exp $
+#	$NetBSD: GENERIC32_IP2x,v 1.78 2009/01/24 05:06:07 mrg Exp $
 #
-# sgimips GENERIC kernel for IP12
+# GENERIC32_IP12 machine description file
+# 
+# This machine description file is used to generate the default NetBSD
+# kernel.  The generic kernel does not include all options, subsystems
+# and device drivers, but should be useful for most applications.
 #
-# The IP12 is very, very similar to the IP2x, with two important differences:
-# it is MIPS1 and has a different memory map. This means that while we can
-# produce a kernel that works on both CPU architectures, our start addresses
-# must differ.
+# The machine description file can be customised for your specific
+# machine to reduce the kernel size and improve its performance.
 #
-# To keep things simple, include the IP2x kernel config and "no option" the
-# offending bits.
+# For further information on compiling NetBSD kernels, see the config(8)
+# man page.
+#
+# For further information on hardware support for this architecture, see
+# the intro(4) man page.  For further information about kernel options
+# for this architecture, see the options(4) man page.  For an explanation
+# of each device driver in this file see the section 4 man page for the
+# device.
+#
+#
+# Currently this config file supports Personal IRIS 4D/2x (IP6/IP10),
+# Personal IRIS 4D/3x (IP12) and Indigo R3k (IP12).
+#
+# Note that to load at beginning of memory, the kernel _must_ be under
+# 3.5MB in size to avoid stomping on (or being stomped on by) the PROM.
+#
+
+include		"arch/sgimips/conf/std.sgimips"
+
+makeoptions	TEXTADDR=0x80002000	# entry point
+
+options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
+
+#ident		"GENERIC32-IP2x-$Revision: 1.78 $"
+
+maxusers	32
+
+# CPU related options
+options 	MIPS1			# MIPS1 support
+
+makeoptions	WANT_ECOFF="yes"	# Create an ECOFF kernel in addition
+					# to an ELF kernel -- required for
+					# booting from the PROM. 
+
+options 	BLINK		# blinkenlitzen
+
+# Standard system options
+#options 	INSECURE	# disable kernel security levels
+
+#options 	NTP		# NTP phase/frequence locked loop
+options 	KTRACE		# system call tracing via ktrace(1)
+
+options 	SYSVMSG		# System V message queues
+options 	SYSVSEM		# System V semaphores
+options 	SYSVSHM		# System V shared memory
+options 	P1003_1B_SEMAPHORE # p1003.1b semaphore support
+
+
+options 	USERCONF	# userconf(4) support
+#options 	PIPE_SOCKETPAIR	# smaller, but slower pipe(2)
+options 	SYSCTL_INCLUDE_DESCR	# Include sysctl descriptions in kernel
+
+# Enable experimental buffer queue strategy for better responsiveness under 
+# high disk I/O load. Use it with caution - it's not proven to be stable yet.
+#options 	BUFQ_READPRIO
+#options 	BUFQ_PRIOCSCAN
+
+# Diagnostic/debugging support options
+#options 	DIAGNOSTIC	# expensive kernel consistency checks
+#options 	DEBUG		# expensive debugging checks/support
+#options 	KMEMSTATS	# kernel memory statistics (vmstat -m)
+options 	DDB		# in-kernel debugger
+options 	DDB_HISTORY_SIZE=512	# enable history editing in DDB
+#options 	KGDB		# remote debugger
+#options 	KGDB_DEV=0x2301		# KGDB port - this is Serial(1)
+#options 	KGDB_DEVRATE=19200	# KGDB Baud Rate
+#makeoptions	DEBUG="-g"	# compile full symbol table
+
+# Compatibility options
+options 	COMPAT_15	# NetBSD 1.5
+options 	COMPAT_16	# NetBSD 1.6
+options 	COMPAT_20	# NetBSD 2.0
+options 	COMPAT_30	# NetBSD 3.0
+options 	COMPAT_40	# NetBSD 4.0 compatibility.
+options 	COMPAT_50	# NetBSD 5.0 compatibility.
+#options 	TCP_COMPAT_42	# 4.2BSD TCP/IP bug compat. Not recommended.
+
+options 	COMPAT_IRIX	# binary compatibility with IRIX
+#options 	COMPAT_LINUX	# binary compatibility with Linux
+#options 	COMPAT_ULTRIX	# binary compatibility with Ultrix 
+options 	COMPAT_BSDPTY	# /dev/[pt]ty?? ptys.
+
+# File systems
+file-system 	FFS		# UFS
+#file-system 	EXT2FS		# second extended file system (linux)
+#file-system 	LFS		# log-structured file system
+file-system 	MFS		# memory file system
+file-system 	NFS		# Network File System client
+#file-system 	NTFS		# Windows/NT file system (experimental)
+file-system 	CD9660		# ISO 9660 + Rock Ridge file system
+file-system 	MSDOSFS		# MS-DOS file system
+#file-system 	FDESC		# /dev/fd
+file-system 	KERNFS		# /kern
+#file-system 	NULLFS		# loopback file system
+#file-system 	OVERLAY		# overlay file system
+#file-system 	PORTAL		# portal filesystem (still experimental)
+file-system 	PROCFS		# /proc
+#file-system 	UMAPFS		# NULLFS + uid and gid remapping
+#file-system 	UNION		# union file system
+#file-system	CODA		# Coda File System; also needs vcoda (below)
+file-system	PTYFS		# /dev/pts/N support
+file-system	TMPFS		# Efficient memory file-system
+#file-system	UDF		# experimental - OSTA UDF CD/DVD file-system
+file-system	EFS		# Silicon Graphics Extent File System
+
+# File system options
+options 	QUOTA		# UFS quotas
+#options 	FFS_EI		# FFS Endian Independent support
+options 	WAPBL		# File system journaling support - Experimental
+#options 	UFS_DIRHASH	# UFS Large Directory Hashing - Experimental
+options 	NFSSERVER	# Network File System server
+#options 	FFS_NO_SNAPSHOT	# No FFS snapshot support
+#options 	EXT2FS_SYSTEM_FLAGS # makes ext2fs file flags (append and
+				# immutable) behave as system flags.
 
-# Pull in standard `install' config
-include 	"arch/sgimips/conf/GENERIC32_IP2x"
+# Networking options
+#options 	GATEWAY		# packet forwarding
+options 	INET		# IP + ICMP + TCP + UDP
+#options 	INET6		# IPV6
+#options 	IPSEC		# IP security
+#options 	IPSEC_ESP	# IP security (encryption part; define w/IPSEC)
+#options 	IPSEC_NAT_T	# IPsec NAT traversal (NAT-T)
+#options 	IPSEC_DEBUG	# debug for IP security
+#options 	MROUTING	# IP multicast routing
+#options 	PIM		# Protocol Independent Multicast
+#options 	ISO,TPIP	# OSI
+#options 	EON		# OSI tunneling over IP
+#options 	NETATALK	# AppleTalk networking protocols
+#options 	PPP_BSDCOMP	# BSD-Compress compression support for PPP
+#options 	PPP_DEFLATE	# Deflate compression support for PPP
+#options 	PPP_FILTER	# Active filter support for PPP (requires bpf)
+options 	PFIL_HOOKS	# pfil(9) packet filter hooks
+options 	IPFILTER_LOG	# ipmon(8) log support
+options 	IPFILTER_LOOKUP	# ippool(8) support
+#options 	IPFILTER_DEFAULT_BLOCK	# block all packets by default
+#options 	TCP_DEBUG	# Record last TCP_NDEBUG packets with SO_DEBUG
 
-no options	MIPS3
-options		MIPS1
-no options	INDY_R4600_CACHE
+#options 	ALTQ		# Manipulate network interfaces' output queues
+#options 	ALTQ_BLUE	# Stochastic Fair Blue
+#options 	ALTQ_CBQ	# Class-Based Queueing
+#options 	ALTQ_CDNR	# Diffserv Traffic Conditioner
+#options 	ALTQ_FIFOQ	# First-In First-Out Queue
+#options 	ALTQ_FLOWVALVE	# RED/flow-valve (red-penalty-box)
+#options 	ALTQ_HFSC	# Hierarchical Fair Service Curve
+#options 	ALTQ_LOCALQ	# Local queueing discipline
+#options 	ALTQ_PRIQ	# Priority Queueing
+#options 	ALTQ_RED	# Random Early Detection
+#options 	ALTQ_RIO	# RED with IN/OUT
+#options 	ALTQ_WFQ	# Weighted Fair Queueing
 
-no makeoptions	TEXTADDR
-makeoptions	TEXTADDR=0x80002000
+# These options enable verbose messages for several subsystems.
+# Warning, these may compile large string tables into the kernel!
+#options 	MIIVERBOSE	# verbose PHY autoconfig messages
+#options 	SCSIVERBOSE	# human readable SCSI error messages
+
+options 	NFS_BOOT_DHCP,NFS_BOOT_BOOTPARAM
+
+#options 	MEMORY_DISK_HOOKS
+#options 	MEMORY_DISK_IS_ROOT
+#options 	MEMORY_DISK_SERVER=0
+#options 	MINIROOTSIZE=8192
+
+#options 	SCSI_DELAY=5
+
+#
+# wscons options
+#
+# builtin terminal emulations
+#options 	WSEMUL_SUN		# sun terminal emulation
+options 	WSEMUL_VT100		# VT100 / VT220 emulation
+# different kernel output - see dev/wscons/wsdisplayvar.h
+options 	WS_KERNEL_FG=WSCOL_GREEN
+#options 	WS_KERNEL_BG=WSCOL_BLACK
+# compatibility to other console drivers
+options 	WSDISPLAY_COMPAT_RAWKBD		# can get raw scancodes
+# see dev/pckbport/wskbdmap_mfii.c for implemented layouts
+#options 	PCKBD_LAYOUT="(KB_DE | KB_NODEAD)"
+
+
+# Kernel root file system and dump configuration.
+config		netbsd	root on ? type ?
+
+# Main bus and CPU
+mainbus0 	at root
+cpu0 		at mainbus?
+
+sd*     at scsibus? target ? lun ?	# SCSI disks
+st*     at scsibus? target ? lun ?	# SCSI tapes
+cd*     at scsibus? target ? lun ?	# SCSI CD-ROMs
+ch*     at scsibus? target ? lun ?	# SCSI changer devices
+ss*     at scsibus? target ? lun ?	# SCSI scanners
+ses*    at scsibus? target ? lun ?	# SCSI SES/SAF-TE devices
+uk*     at scsibus? target ? lun ?	# unknown SCSI
+
+# Common devices
+int0		at mainbus0			# Interrupt controller
+scsibus*	at scsi?			# HPC or IOC SCSI
+
+# IP6/10 devices
+ctl0		at mainbus0 addr 0x1f800000	# Memory controller
+oioc0		at mainbus0 addr 0x1f900000	# 'Old' I/O Controller
+dpclock0	at mainbus0 addr 0x1fbc0000	# RTC
+scn0		at mainbus0 addr 0x1fb80004	# Signetics 2681 Serial Port
+oiocsc* 	at oioc? offset ?		# On-board WD33C93 SCSI
+le*		at oioc? offset ?		# AMD LANCE AM7990 Ethernet
+
+# Personal Iris / Indigo R3k devices
+pic0		at mainbus0 addr 0x1fa00000	# Memory Controller
+gio0		at pic0				# GIO32 bus
+dpclock0	at mainbus0 addr 0x1fb80e00	# RTC
+hpc0 		at gio? addr 0x1fb80000		# High-perf. Peripheral. Ctrlers
+hpc1 		at gio? addr 0x1fb00000
+hpc2 		at gio? addr 0x1f980000
+grtwo*		at gio?				# Express (GR2) graphics
+wsdisplay*	at grtwo? console ?
+light*		at gio?			# Light/Starter/Entry (LG1/LG2) graphics
+wsdisplay*	at light? console ?
+sq* 		at hpc? offset ?	# On-board ethernet / E++ adapter
+wdsc* 		at hpc? offset ?	# On-board SCSI / GIO32 SCSI adapter
+wskbd*		at zskbd? console ?
+wsmouse*	at zsms? mux 0
+zsc0 		at hpc0 offset ?
+zstty*		at zsc0 channel ?
+zsc1 		at hpc0 offset ?	# IP12 keyboard/mouse
+zskbd0		at zsc1 channel 0
+zsms0		at zsc1 channel 1
+
+# Pseudo-Devices
+
+# disk/mass storage pseudo-devices
+pseudo-device	ccd		4	# concatenated/striped disk devices
+#pseudo-device	cgd		4	# cryptographic disk devices
+#pseudo-device	raid		4	# RAIDframe disk driver
+#options 	RAID_AUTOCONFIG		# auto-configuration of RAID components
+pseudo-device	fss		4	# file system snapshot device
+pseudo-device	md		1	# memory disk device (ramdisk)
+pseudo-device	vnd			# disk-like interface to files
+#options 	VND_COMPRESSION		# compressed vnd(4)
+
+# network pseudo-devices
+pseudo-device	bpfilter		# Berkeley packet filter
+#pseudo-device	carp			# Common Address Redundancy Protocol
+pseudo-device	ipfilter		# IP filter (firewall) and NAT
+pseudo-device	loop			# network loopback
+#pseudo-device	ppp			# Point-to-Point Protocol
+pseudo-device	sl			# Serial Line IP
+#pseudo-device	strip			# Starmode Radio IP (Metricom)
+pseudo-device	tun			# network tunneling over tty
+pseudo-device	tap			# virtual Ethernet
+pseudo-device	gre			# generic L3 over IP tunnel
+pseudo-device	gif			# IPv[46] over IPv[46] tunnel (RFC1933)
+#pseudo-device	faith			# IPv[46] tcp relay translation i/f
+#pseudo-device	stf			# 6to4 IPv6 over IPv4 encapsulation
+pseudo-device	vlan			# IEEE 802.1q encapsulation
+pseudo-device	bridge			# simple inter-network bridging
+pseudo-device	agr			# IEEE 802.3ad link aggregation
+#options 	BRIDGE_IPF		# bridge uses IP/IPv6 pfil hooks too
+#pseudo-device	pf			# PF packet filter
+#pseudo-device	pflog			# PF log if
+#pseudo-device   accf_data		# "dataready" accept filter
+#pseudo-device   accf_http		# "httpready" accept filter
+
+# miscellaneous pseudo-devices
+pseudo-device	pty			# pseudo-terminals
+pseudo-device	sequencer	1	# MIDI sequencer
+pseudo-device	rnd			# /dev/random and in-kernel generator
+pseudo-device	clockctl		# user control of clock subsystem
+pseudo-device	ksyms			# /dev/ksyms
+pseudo-device	wsmux                   # mouse & keyboard multiplexor
+pseudo-device	wsfont
+
+# a pseudo device needed for Coda	# also needs CODA (above)
+#pseudo-device	vcoda		4	# coda minicache <-> venus comm.
+
+# pseudo devices used for IRIX binary compatibility
+pseudo-device	irix_kmem		# IRIX /dev/kmem
+pseudo-device	irix_usema		# IRIX /dev/usema
+
+# Veriexec
+#
+# a pseudo device needed for veriexec
+#pseudo-device	veriexec		1
+#
+# Uncomment the fingerprint methods below that are desired. Note that
+# removing fingerprint methods will have almost no impact on the kernel
+# code size.
+#
+#options VERIFIED_EXEC_FP_RMD160
+#options VERIFIED_EXEC_FP_SHA256
+#options VERIFIED_EXEC_FP_SHA384
+#options VERIFIED_EXEC_FP_SHA512
+#options VERIFIED_EXEC_FP_SHA1
+#options VERIFIED_EXEC_FP_MD5
Index: arch/sgimips/conf/GENERIC32_IP2x
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/conf/GENERIC32_IP2x,v
retrieving revision 1.78
diff -p -u -r1.78 GENERIC32_IP2x
--- arch/sgimips/conf/GENERIC32_IP2x	24 Jan 2009 05:06:07 -0000	1.78
+++ arch/sgimips/conf/GENERIC32_IP2x	10 Feb 2009 08:16:53 -0000
@@ -211,8 +211,13 @@ gio0		at pic0
 imc0 		at mainbus0 addr 0x1fa00000
 gio0 		at imc0
 eisa0 		at imc0
+
 int0		at mainbus0		# Interrupt controller
 
+# Some clocks actually in HPC space, but not all
+dpclock0	at mainbus0 addr 0x1fb80e00	# IP12 / IP20
+dsclock0	at mainbus0 addr 0x1fbe0000	# IP22 / 24
+
 hpc0 		at gio? addr 0x1fb80000
 hpc1 		at gio? addr 0x1fb00000
 hpc2 		at gio? addr 0x1f980000
@@ -241,8 +246,6 @@ tlphy*		at mii? phy ?		 # ThunderLAN PHY
 # HPC devices
 sq* 		at hpc? offset ?	# On-board ethernet / E++ adapter
 wdsc* 		at hpc? offset ?	# On-board SCSI / GIO32 SCSI adapter
-dpclock*	at hpc0 offset ?	# IP12 / IP20
-dsclock*	at hpc0 offset ?	# IP22 / 24
 haltwo*         at hpc0 offset ?	# IP22 / 24
 pckbc*		at hpc0 offset ?
 
Index: arch/sgimips/conf/files.sgimips
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/conf/files.sgimips,v
retrieving revision 1.47
diff -p -u -r1.47 files.sgimips
--- arch/sgimips/conf/files.sgimips	20 Feb 2008 21:43:35 -0000	1.47
+++ arch/sgimips/conf/files.sgimips	10 Feb 2009 08:16:53 -0000
@@ -4,8 +4,7 @@ maxpartitions 16
 
 maxusers 2 8 64
 
-# XXX: arcemu needs smc93cx6, so put it here pending a better solution
-device mainbus {[addr = -1]}: smc93cx6
+device mainbus {[addr = -1]}
 attach mainbus at root
 file arch/sgimips/sgimips/mainbus.c	mainbus
 
@@ -34,8 +33,8 @@ file dev/md_root.c			memory_disk_hooks
 file dev/cons.c
 
 # Machine-dependent drivers
-include "arch/sgimips/ioc/files.ioc"
 include "arch/sgimips/dev/files.dev"
+include "arch/sgimips/ioc/files.ioc"		# depends on int0 (files.dev)
 defflag opt_sgimace.h MACE_NEEDS_DELAYS
 include "arch/sgimips/mace/files.mace"
 
Index: arch/sgimips/conf/majors.sgimips
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/conf/majors.sgimips,v
retrieving revision 1.21
diff -p -u -r1.21 majors.sgimips
--- arch/sgimips/conf/majors.sgimips	12 Nov 2008 12:36:06 -0000	1.21
+++ arch/sgimips/conf/majors.sgimips	10 Feb 2009 08:16:53 -0000
@@ -11,6 +11,8 @@ device-major	vnd		char 4   block 4	vnd
 device-major	raid		char 5   block 5	raid
 device-major	cgd		char 6   block 6	cgd
 
+device-major	scn		char 8			scn
+
 device-major	sd		char 10  block 10	sd
 device-major	st		char 11  block 11	st
 device-major	cd		char 12  block 12	cd
Index: arch/sgimips/dev/files.dev
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/dev/files.dev,v
retrieving revision 1.9
diff -p -u -r1.9 files.dev
--- arch/sgimips/dev/files.dev	17 Oct 2007 19:57:04 -0000	1.9
+++ arch/sgimips/dev/files.dev	10 Feb 2009 08:16:53 -0000
@@ -2,25 +2,42 @@
 
 define giobus {}
 
-device int
-attach int at mainbus
-file arch/sgimips/dev/int.c		int
-
-device imc: giobus, eisabus
-attach imc at mainbus
-file arch/sgimips/dev/imc.c		imc needs-flag
-
-device pic: giobus
-attach pic at mainbus
-file arch/sgimips/dev/pic.c		pic needs-flag
-
-device crime
-attach crime at mainbus
-file arch/sgimips/dev/crime.c		crime needs-flag
-
-device crmfb: wsemuldisplaydev, vcons, rasops8, rasops16, rasops32
-attach crmfb at mainbus
-file arch/sgimips/dev/crmfb.c		crmfb needs-flag
+# `int' should be first, as it provides intr_establish and other platform hooks
+device	int
+attach	int at mainbus
+file	arch/sgimips/dev/int.c		int
+
+device	ctl
+attach	ctl at mainbus
+file	arch/sgimips/dev/ctl.c
+
+device	imc: giobus, eisabus
+attach	imc at mainbus
+file	arch/sgimips/dev/imc.c		imc needs-flag
+
+device	pic: giobus
+attach	pic at mainbus
+file	arch/sgimips/dev/pic.c		pic needs-flag
+
+device	dpclock
+attach	dpclock at mainbus
+file	arch/sgimips/dev/dpclock.c	dpclock
+
+device	dsclock
+attach	dsclock at mainbus 
+file	arch/sgimips/dev/dsclock.c	dsclock
+
+device	crime
+attach	crime at mainbus
+file	arch/sgimips/dev/crime.c		crime needs-flag
+
+device	crmfb: wsemuldisplaydev, vcons, rasops8, rasops16, rasops32
+attach	crmfb at mainbus
+file	arch/sgimips/dev/crmfb.c		crmfb needs-flag
+
+device	scn: tty
+attach	scn at mainbus
+file	arch/sgimips/dev/scn.c			scn needs-flag
 
 device	zsc {[channel = -1]}
 device	zstty: tty
Index: arch/sgimips/dev/int.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/dev/int.c,v
retrieving revision 1.19
diff -p -u -r1.19 int.c
--- arch/sgimips/dev/int.c	23 Aug 2008 17:25:54 -0000	1.19
+++ arch/sgimips/dev/int.c	10 Feb 2009 08:16:53 -0000
@@ -1,6 +1,7 @@
 /*	$NetBSD: int.c,v 1.19 2008/08/23 17:25:54 tsutsui Exp $	*/
 
 /*
+ * Copyright (c) 2009 Stephen M. Rumble 
  * Copyright (c) 2004 Christopher SEKIYA
  * All rights reserved.
  *
@@ -28,7 +29,7 @@
  */
 
 /*
- * INT/INT2/INT3 interrupt controller (used in Indy's, Indigo's, etc..)
+ * INT1/INT2/INT3 interrupt controllers (IP6, IP10, IP12, IP20, IP22, IP24...)
  */
 
 #include <sys/cdefs.h>
@@ -52,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: int.c,v 1.19
 
 #include <mips/cache.h>
 
+#include <sgimips/dev/int1reg.h>
 #include <sgimips/dev/int2reg.h>
 #include <sgimips/dev/int2var.h>
 
@@ -65,24 +67,28 @@ struct int_softc {
 
 static int	int_match(struct device *, struct cfdata *, void *);
 static void	int_attach(struct device *, struct device *, void *);
-static void 	int_local0_intr(uint32_t, uint32_t, uint32_t, uint32_t);
-static void	int_local1_intr(uint32_t, uint32_t, uint32_t, uint32_t);
-static int 	int_mappable_intr(void *);
-static void    *int_intr_establish(int, int, int (*)(void *), void *);
+static void	int1_local_intr(uint32_t, uint32_t, uint32_t, uint32_t);
+static void    *int1_intr_establish(int, int, int (*)(void *), void *);
+static void    *int2_intr_establish(int, int, int (*)(void *), void *);
+static void 	int2_local0_intr(uint32_t, uint32_t, uint32_t, uint32_t);
+static void	int2_local1_intr(uint32_t, uint32_t, uint32_t, uint32_t);
+static int 	int2_mappable_intr(void *);
+static void    *int2_intr_establish(int, int, int (*)(void *), void *);
 static void	int_8254_cal(void);
 static u_int	int_8254_get_timecount(struct timecounter *);
 static void	int_8254_intr0(uint32_t, uint32_t, uint32_t, uint32_t);
 static void	int_8254_intr1(uint32_t, uint32_t, uint32_t, uint32_t);
 
 #ifdef MIPS3
-static u_long	int_cal_timer(void);
+static u_long	int2_cpu_freq(struct device *);
+static u_long	int2_cal_timer(void);
 #endif
 
 static struct timecounter int_8254_timecounter = {
 	int_8254_get_timecount,	/* get_timecount */
 	0,			/* no poll_pps */
 	~0u,			/* counter_mask */
-	500000,			/* frequency */
+	0,			/* frequency; set in int_8254_cal */
 	"int i8254",		/* name */
 	100,			/* quality */
 	NULL,			/* prev */
@@ -98,9 +104,13 @@ static int
 int_match(struct device *parent, struct cfdata *match, void *aux)
 {
 
-	if ((mach_type == MACH_SGI_IP12) || (mach_type == MACH_SGI_IP20) ||
-	    (mach_type == MACH_SGI_IP22) )
+	switch (mach_type) {
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
+	case MACH_SGI_IP12:
+	case MACH_SGI_IP20:
+	case MACH_SGI_IP22:
 		return 1;
+	}
 
 	return 0;
 }
@@ -110,78 +120,98 @@ int_attach(struct device *parent, struct
 {
 	uint32_t address;
 
-	if (mach_type == MACH_SGI_IP12)
-		address = INT_IP12;
-	else if (mach_type == MACH_SGI_IP20)
-		address = INT_IP20;
-	else if (mach_type == MACH_SGI_IP22) {
+	switch (mach_type) {
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
+		address = INT1_IP6_IP10;
+		break;
+
+	case MACH_SGI_IP12:
+		address = INT2_IP12;
+		break;
+
+	case MACH_SGI_IP20:
+		address = INT2_IP20;
+		break;
+
+	case MACH_SGI_IP22:
 		if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
-			address = INT_IP22;
+			address = INT2_IP22;
 		else
-			address = INT_IP24;
-	} else
+			address = INT2_IP24;
+		break;
+
+	default:
 		panic("\nint0: passed match, but failed attach?");
+	}
 
 	printf(" addr 0x%x\n", address);
 
 	bus_space_map(iot, address, 0, 0, &ioh);
 	iot = SGIMIPS_BUS_SPACE_NORMAL;
 
-	/* Clean out interrupt masks */
-	bus_space_write_4(iot, ioh, INT2_LOCAL0_MASK, 0);
-	bus_space_write_4(iot, ioh, INT2_LOCAL1_MASK, 0);
-	bus_space_write_4(iot, ioh, INT2_MAP_MASK0, 0);
-	bus_space_write_4(iot, ioh, INT2_MAP_MASK1, 0);
-
-	/* Reset timer interrupts */
-	bus_space_write_4(iot, ioh, INT2_TIMER_CLEAR, 0x03);
-
 	switch (mach_type) {
-	case MACH_SGI_IP12:
-		platform.intr1 = int_local0_intr;
-		platform.intr2 = int_local1_intr;
-		platform.intr3 = int_8254_intr0;
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
+		/* Clean out interrupt masks */
+		bus_space_write_1(iot, ioh, INT1_LOCAL_MASK, 0);
+
+		/* Turn off timers and clear interrupts */
+		bus_space_write_1(iot, ioh, INT1_TIMER_CONTROL,
+		    (TIMER_SEL0 | TIMER_16BIT | TIMER_SWSTROBE));
+		bus_space_write_1(iot, ioh, INT1_TIMER_CONTROL,
+		    (TIMER_SEL1 | TIMER_16BIT | TIMER_SWSTROBE));
+		bus_space_write_1(iot, ioh, INT1_TIMER_CONTROL,
+		    (TIMER_SEL2 | TIMER_16BIT | TIMER_SWSTROBE));
+		wbflush();
+		delay(4);
+		bus_space_read_1(iot, ioh, INT1_TIMER_0_ACK);
+		bus_space_read_1(iot, ioh, INT1_TIMER_1_ACK);
+
+		platform.intr_establish = int1_intr_establish;
+		platform.intr1 = int1_local_intr;
+		platform.intr2 = int_8254_intr0;
 		platform.intr4 = int_8254_intr1;
 		int_8254_cal();
-		tc_init(&int_8254_timecounter);
 		break;
-#ifdef MIPS3
+
+	case MACH_SGI_IP12:
 	case MACH_SGI_IP20:
 	case MACH_SGI_IP22:
-	{
-		int i;
-		unsigned long cps;
-		unsigned long ctrdiff[3];
-
-		platform.intr0 = int_local0_intr;
-		platform.intr1 = int_local1_intr;
-
-		/* calibrate timer */
-		int_cal_timer();
-
-		cps = 0;
-		for (i = 0; i < sizeof(ctrdiff) / sizeof(ctrdiff[0]); i++) {
-			do {
-				ctrdiff[i] = int_cal_timer();
-			} while (ctrdiff[i] == 0);
-
-			cps += ctrdiff[i];
+		/* Clean out interrupt masks */
+		bus_space_write_1(iot, ioh, INT2_LOCAL0_MASK, 0);
+		bus_space_write_1(iot, ioh, INT2_LOCAL1_MASK, 0);
+		bus_space_write_1(iot, ioh, INT2_MAP_MASK0, 0);
+		bus_space_write_1(iot, ioh, INT2_MAP_MASK1, 0);
+
+		/* Reset timer interrupts */
+		bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL,
+		    (TIMER_SEL0 | TIMER_16BIT | TIMER_SWSTROBE));
+		bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL,
+		    (TIMER_SEL1 | TIMER_16BIT | TIMER_SWSTROBE));
+		bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL,
+		    (TIMER_SEL2 | TIMER_16BIT | TIMER_SWSTROBE));
+		wbflush();
+		delay(4);
+		bus_space_write_1(iot, ioh, INT2_TIMER_CLEAR, 0x03);
+
+		if (mach_type == MACH_SGI_IP12) {
+			platform.intr_establish = int2_intr_establish;
+			platform.intr1 = int2_local0_intr;
+			platform.intr2 = int2_local1_intr;
+			platform.intr3 = int_8254_intr0;
+			platform.intr4 = int_8254_intr1;
+			int_8254_cal();
+		} else {
+			platform.intr_establish = int2_intr_establish;
+			platform.intr0 = int2_local0_intr;
+			platform.intr1 = int2_local1_intr;
+#ifdef MIPS3
+			curcpu()->ci_cpu_freq = int2_cpu_freq(self);
+#endif
 		}
-
-		cps = cps / (sizeof(ctrdiff) / sizeof(ctrdiff[0]));
-
-		printf("%s: bus %luMHz, CPU %luMHz\n",
-		    self->dv_xname, cps / 10000, cps / 5000);
-
-		/* R4k/R4400/R4600/R5k count at half CPU frequency */
-		curcpu()->ci_cpu_freq = 2 * cps * hz;
-	}
-#endif /* MIPS3 */
-
 		break;
+
 	default:
 		panic("int0: unsupported machine type %i\n", mach_type);
-		break;
 	}
 
 	curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / (2 * hz);
@@ -189,18 +219,16 @@ int_attach(struct device *parent, struct
 
 	if (mach_type == MACH_SGI_IP22) {
 		/* Wire interrupts 7, 11 to mappable interrupt 0,1 handlers */
-		intrtab[7].ih_fun = int_mappable_intr;
+		intrtab[7].ih_fun = int2_mappable_intr;
 		intrtab[7].ih_arg = (void*) 0;
 
-		intrtab[11].ih_fun = int_mappable_intr;
+		intrtab[11].ih_fun = int2_mappable_intr;
 		intrtab[11].ih_arg = (void*) 1;
 	}
-
-	platform.intr_establish = int_intr_establish;
 }
 
 int
-int_mappable_intr(void *arg)
+int2_mappable_intr(void *arg)
 {
 	int i;
 	int ret;
@@ -211,8 +239,8 @@ int_mappable_intr(void *arg)
 	struct sgimips_intrhand *ih;
 
 	ret = 0;
-	mstat = bus_space_read_4(iot, ioh, INT2_MAP_STATUS);
-	mmask = bus_space_read_4(iot, ioh, INT2_MAP_MASK0 + (which << 2));
+	mstat = bus_space_read_1(iot, ioh, INT2_MAP_STATUS);
+	mmask = bus_space_read_1(iot, ioh, INT2_MAP_MASK0 + (which << 2));
 
 	mstat &= mmask;
 
@@ -233,16 +261,43 @@ int_mappable_intr(void *arg)
 	return ret;
 }
 
+static void
+int1_local_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipend)
+{
+	int i;
+	uint16_t stat;
+	uint8_t  mask;
+	struct sgimips_intrhand *ih;
+
+	stat = bus_space_read_2(iot, ioh, INT1_LOCAL_STATUS);
+	mask = bus_space_read_1(iot, ioh, INT1_LOCAL_MASK);
+
+	/* for STATUS, a 0 bit means interrupt is pending */
+	stat = ~stat & mask;
+
+	for (i = 0; i < 16; i++) {
+		if (stat & (1 << i)) {
+			for (ih = &intrtab[i]; ih != NULL; ih = ih->ih_next) {
+				if (ih->ih_fun != NULL)
+					(ih->ih_fun)(ih->ih_arg);
+				else
+					printf("int0: unexpected local "
+					       "interrupt %d\n", i);
+			}
+		}
+	}
+}
+
 void
-int_local0_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending)
+int2_local0_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipend)
 {
 	int i;
 	uint32_t l0stat;
 	uint32_t l0mask;
 	struct sgimips_intrhand *ih;
 
-	l0stat = bus_space_read_4(iot, ioh, INT2_LOCAL0_STATUS);
-	l0mask = bus_space_read_4(iot, ioh, INT2_LOCAL0_MASK);
+	l0stat = bus_space_read_1(iot, ioh, INT2_LOCAL0_STATUS);
+	l0mask = bus_space_read_1(iot, ioh, INT2_LOCAL0_MASK);
 
 	l0stat &= l0mask;
 
@@ -260,15 +315,15 @@ int_local0_intr(uint32_t status, uint32_
 }
 
 void
-int_local1_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending)
+int2_local1_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipend)
 {
 	int i;
 	uint32_t l1stat;
 	uint32_t l1mask;
 	struct sgimips_intrhand *ih;
 
-	l1stat = bus_space_read_4(iot, ioh, INT2_LOCAL1_STATUS);
-	l1mask = bus_space_read_4(iot, ioh, INT2_LOCAL1_MASK);
+	l1stat = bus_space_read_1(iot, ioh, INT2_LOCAL1_STATUS);
+	l1mask = bus_space_read_1(iot, ioh, INT2_LOCAL1_MASK);
 
 	l1stat &= l1mask;
 
@@ -286,7 +341,51 @@ int_local1_intr(uint32_t status, uint32_
 }
 
 void *
-int_intr_establish(int level, int ipl, int (*handler) (void *), void *arg)
+int1_intr_establish(int level, int ipl, int (*handler) (void *), void *arg)
+{
+	uint8_t mask;
+
+	if (level < 0 || level >= NINTR)
+		panic("invalid interrupt level");
+
+	if (intrtab[level].ih_fun == NULL) {
+		intrtab[level].ih_fun = handler;
+		intrtab[level].ih_arg = arg;
+		intrtab[level].ih_next = NULL;
+	} else {
+		struct sgimips_intrhand *n, *ih;
+
+		ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
+		if (ih == NULL) {
+			printf("int0: can't allocate handler\n");
+			return (void *)NULL;
+		}
+
+		ih->ih_fun = handler;
+		ih->ih_arg = arg;
+		ih->ih_next = NULL;
+
+		for (n = &intrtab[level]; n->ih_next != NULL; n = n->ih_next)
+			;
+
+		n->ih_next = ih;
+
+		return NULL;	/* vector already set */
+	}
+
+	if (level < 8) {
+		mask = bus_space_read_1(iot, ioh, INT1_LOCAL_MASK);
+		mask |= (1 << level);
+		bus_space_write_1(iot, ioh, INT1_LOCAL_MASK, mask);
+	} else {
+		printf("int0: level >= 16 (%d)\n", level);
+	}
+
+	return NULL;
+}
+
+void *
+int2_intr_establish(int level, int ipl, int (*handler) (void *), void *arg)
 {
 	uint32_t mask;
 
@@ -302,7 +401,7 @@ int_intr_establish(int level, int ipl, i
 
 		ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
 		if (ih == NULL) {
-			printf("int_intr_establish: can't allocate handler\n");
+			printf("int0: can't allocate handler\n");
 			return NULL;
 		}
 
@@ -318,33 +417,32 @@ int_intr_establish(int level, int ipl, i
 		return NULL;	/* vector already set */
 	}
 
-
 	if (level < 8) {
-		mask = bus_space_read_4(iot, ioh, INT2_LOCAL0_MASK);
+		mask = bus_space_read_1(iot, ioh, INT2_LOCAL0_MASK);
 		mask |= (1 << level);
-		bus_space_write_4(iot, ioh, INT2_LOCAL0_MASK, mask);
+		bus_space_write_1(iot, ioh, INT2_LOCAL0_MASK, mask);
 	} else if (level < 16) {
-		mask = bus_space_read_4(iot, ioh, INT2_LOCAL1_MASK);
+		mask = bus_space_read_1(iot, ioh, INT2_LOCAL1_MASK);
 		mask |= (1 << (level - 8));
-		bus_space_write_4(iot, ioh, INT2_LOCAL1_MASK, mask);
+		bus_space_write_1(iot, ioh, INT2_LOCAL1_MASK, mask);
 	} else if (level < 24) {
 		/* Map0 interrupt maps to l0 bit 7, so turn that on too */
-		mask = bus_space_read_4(iot, ioh, INT2_LOCAL0_MASK);
+		mask = bus_space_read_1(iot, ioh, INT2_LOCAL0_MASK);
 		mask |= (1 << 7);
-		bus_space_write_4(iot, ioh, INT2_LOCAL0_MASK, mask);
+		bus_space_write_1(iot, ioh, INT2_LOCAL0_MASK, mask);
 
-		mask = bus_space_read_4(iot, ioh, INT2_MAP_MASK0);
+		mask = bus_space_read_1(iot, ioh, INT2_MAP_MASK0);
 		mask |= (1 << (level - 16));
-		bus_space_write_4(iot, ioh, INT2_MAP_MASK0, mask);
+		bus_space_write_1(iot, ioh, INT2_MAP_MASK0, mask);
 	} else {
 		/* Map1 interrupt maps to l1 bit 3, so turn that on too */
-		mask = bus_space_read_4(iot, ioh, INT2_LOCAL1_MASK);
+		mask = bus_space_read_1(iot, ioh, INT2_LOCAL1_MASK);
 		mask |= (1 << 3);
-		bus_space_write_4(iot, ioh, INT2_LOCAL1_MASK, mask);
+		bus_space_write_1(iot, ioh, INT2_LOCAL1_MASK, mask);
 
-		mask = bus_space_read_4(iot, ioh, INT2_MAP_MASK1);
+		mask = bus_space_read_1(iot, ioh, INT2_MAP_MASK1);
 		mask |= (1 << (level - 24));
-		bus_space_write_4(iot, ioh, INT2_MAP_MASK1, mask);
+		bus_space_write_1(iot, ioh, INT2_MAP_MASK1, mask);
 	}
 
 	return NULL;
@@ -352,7 +450,36 @@ int_intr_establish(int level, int ipl, i
 
 #ifdef MIPS3
 static u_long
-int_cal_timer(void)
+int2_cpu_freq(struct device *self)
+{
+	int i;
+	unsigned long cps;
+	unsigned long ctrdiff[3];
+
+	/* calibrate timer */
+	int2_cal_timer();
+
+	cps = 0;
+	for (i = 0;
+	    i < sizeof(ctrdiff) / sizeof(ctrdiff[0]); i++) {
+		do {
+			ctrdiff[i] = int2_cal_timer();
+		} while (ctrdiff[i] == 0);
+
+		cps += ctrdiff[i];
+	}
+
+	cps = cps / (sizeof(ctrdiff) / sizeof(ctrdiff[0]));
+
+	printf("%s: bus %luMHz, CPU %luMHz\n",
+	    self->dv_xname, cps / 10000, cps / 5000);
+
+	/* R4k/R4400/R4600/R5k count at half CPU frequency */
+	return (2 * cps * hz);
+}
+
+static u_long
+int2_cal_timer(void)
 {
 	int s;
 	int roundtime;
@@ -362,7 +489,7 @@ int_cal_timer(void)
 
 	/*
 	 * NOTE: HZ must be greater than 15 for this to work, as otherwise
-	 * we'll overflow the counter.  We round the answer to hearest 1
+	 * we'll overflow the counter.  We round the answer to nearest 1
 	 * MHz of the master (2x) clock.
 	 */
 	roundtime = (1000000 / hz) / 2;
@@ -371,24 +498,24 @@ int_cal_timer(void)
 
 	s = splhigh();
 
-	bus_space_write_4(iot, ioh, INT2_TIMER_CONTROL,
+	bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL,
 	    (TIMER_SEL2 | TIMER_16BIT | TIMER_RATEGEN));
-	bus_space_write_4(iot, ioh, INT2_TIMER_2, (sampletime & 0xff));
-	bus_space_write_4(iot, ioh, INT2_TIMER_2, (sampletime >> 8));
+	bus_space_write_1(iot, ioh, INT2_TIMER_2, (sampletime & 0xff));
+	bus_space_write_1(iot, ioh, INT2_TIMER_2, (sampletime >> 8));
 
 	startctr = mips3_cp0_count_read();
 
 	/* Wait for the MSB to count down to zero */
 	do {
-		bus_space_write_4(iot, ioh, INT2_TIMER_CONTROL, TIMER_SEL2);
-		lsb = bus_space_read_4(iot, ioh, INT2_TIMER_2) & 0xff;
-		msb = bus_space_read_4(iot, ioh, INT2_TIMER_2) & 0xff;
+		bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL, TIMER_SEL2);
+		lsb = bus_space_read_1(iot, ioh, INT2_TIMER_2) & 0xff;
+		msb = bus_space_read_1(iot, ioh, INT2_TIMER_2) & 0xff;
 
 		endctr = mips3_cp0_count_read();
 	} while (msb);
 
 	/* Turn off timer */
-	bus_space_write_4(iot, ioh, INT2_TIMER_CONTROL,
+	bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL,
 	    (TIMER_SEL2 | TIMER_16BIT | TIMER_SWSTROBE));
 
 	splx(s);
@@ -398,67 +525,115 @@ int_cal_timer(void)
 #endif /* MIPS3 */
 
 /*
- * A 1.000MHz master clock is wired to TIMER2, which in turn clocks the two
- * other timers. On IP12 TIMER1 interrupts on MIPS interrupt 1 and TIMER2
- * on MIPS interrupt 2.
+ * A master clock is wired to TIMER_2, which in turn clocks the two other
+ * timers. The master frequencies are as follows:
+ *     IP6,  IP10:		3.6864MHz
+ *     IP12, IP20, IP22:	1MHz
+ *     IP17:			10MHz
  *
- * Apparently int2 doesn't like counting down from one, but two works, so
- * we get a good 500000Hz.
+ * TIMER_0 and TIMER_1 interrupts are tied to MIPS interrupts as follows:
+ *     IP6,  IP10:		TIMER_0: INT2, TIMER_1: INT4
+ *     IP12:			TIMER_0: INT3, TIMER_1: INT4
+ *     IP17, IP20, IP22:	TIMER_0: INT2, TIMER_1: INT3
+ *
+ * NB: Apparently int2 doesn't like counting down from one, but two works.
  */
 void
 int_8254_cal(void)
 {
+	bus_size_t timer_control, timer_0, timer_1, timer_2;
 	int s;
 
+	switch (mach_type) {
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
+		int_8254_timecounter.tc_frequency = 3686400 / 8;
+		timer_control	= INT1_TIMER_CONTROL;
+		timer_0		= INT1_TIMER_0;
+		timer_1		= INT1_TIMER_1;
+		timer_2		= INT1_TIMER_2;
+		break;
+
+	case MACH_SGI_IP12:
+		int_8254_timecounter.tc_frequency = 1000000 / 8;
+		timer_control	= INT2_TIMER_CONTROL;
+		timer_0		= INT2_TIMER_0;
+		timer_1		= INT2_TIMER_1;
+		timer_2		= INT2_TIMER_2;
+		break;
+
+	default:
+		panic("int_8254_cal");
+	}
+
 	s = splhigh();
 
-	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 15,
-	    TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
-	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 3, (500000 / hz) % 256);
+	/* Timer0 is our hz. */
+	bus_space_write_1(iot, ioh, timer_control,
+	    TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+	bus_space_write_1(iot, ioh, timer_0,
+	    (int_8254_timecounter.tc_frequency / hz) % 256);
 	wbflush();
 	delay(4);
-	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 3, (500000 / hz) / 256);
+	bus_space_write_1(iot, ioh, timer_0,
+	    (int_8254_timecounter.tc_frequency / hz) / 256);
 
-	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 15,
-	    TIMER_SEL1|TIMER_RATEGEN|TIMER_16BIT);
-	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 7, 0xff);
+	/* Timer1 is for timecounting. */
+	bus_space_write_1(iot, ioh, timer_control,
+	    TIMER_SEL1 | TIMER_RATEGEN | TIMER_16BIT);
+	bus_space_write_1(iot, ioh, timer_1, 0xff);
 	wbflush();
 	delay(4);
-	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 7, 0xff);
+	bus_space_write_1(iot, ioh, timer_1, 0xff);
 
-	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 15,
-	    TIMER_SEL2|TIMER_RATEGEN|TIMER_16BIT);
-	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 11, 2);
+	/* Timer2 clocks timer0 and timer1. */
+	bus_space_write_1(iot, ioh, timer_control,
+	    TIMER_SEL2 | TIMER_RATEGEN | TIMER_16BIT);
+	bus_space_write_1(iot, ioh, timer_2, 8);
 	wbflush();
 	delay(4);
-	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 11, 0);
+	bus_space_write_1(iot, ioh, timer_2, 0);
 
 	splx(s);
-}
 
+	tc_init(&int_8254_timecounter);
+}
 
 static u_int
 int_8254_get_timecount(struct timecounter *tc)
 {
 	int s;
 	u_int count;
-	uint8_t lo, hi;
+	u_char lo, hi;
 
 	s = splhigh();
 
-        bus_space_write_1(iot, ioh, INT2_TIMER_0 + 15,
-	    TIMER_SEL1 | TIMER_LATCH);
-	lo = bus_space_read_1(iot, ioh, INT2_TIMER_0 + 7);
-	hi = bus_space_read_1(iot, ioh, INT2_TIMER_0 + 7);
-	count = 0xffff - ((hi << 8) | lo);
+	switch (mach_type) {
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
+		bus_space_write_1(iot, ioh, INT1_TIMER_CONTROL,
+		    TIMER_SEL1 | TIMER_LATCH);
+		lo = bus_space_read_1(iot, ioh, INT1_TIMER_1);
+		hi = bus_space_read_1(iot, ioh, INT1_TIMER_1);
+		break;
+
+	case MACH_SGI_IP12:
+		bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL,
+		    TIMER_SEL1 | TIMER_LATCH);
+		lo = bus_space_read_1(iot, ioh, INT2_TIMER_1);
+		hi = bus_space_read_1(iot, ioh, INT2_TIMER_1);
+		break;
 
+	default:
+		panic("int_8254_get_timecount");
+	}
+
+	count = 0xffff - ((hi << 8) | lo);
 	splx(s);
 
-	return int_8254_tc_count + count;
+	return (int_8254_tc_count + count);
 }
 
 static void
-int_8254_intr0(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending)
+int_8254_intr0(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipend)
 {
 	struct clockframe cf;
 
@@ -467,19 +642,40 @@ int_8254_intr0(uint32_t status, uint32_t
 
 	hardclock(&cf);
 
-	bus_space_write_4(iot, ioh, INT2_TIMER_CLEAR, 1);
-}
+	switch (mach_type) {
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
+		bus_space_read_1(iot, ioh, INT1_TIMER_0_ACK);
+		break;
 
+	case MACH_SGI_IP12:
+		bus_space_write_1(iot, ioh, INT2_TIMER_CLEAR, 0x01);
+		break;
+
+	default:
+		panic("int_8254_intr0");
+	}
+}
 
 static void
-int_8254_intr1(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending)
+int_8254_intr1(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipend)
 {
 	int s;
 
 	s = splhigh();
 
 	int_8254_tc_count += 0xffff;
-	bus_space_write_4(iot, ioh, INT2_TIMER_CLEAR, 2);
+	switch (mach_type) {
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
+		bus_space_read_1(iot, ioh, INT1_TIMER_1_ACK);
+		break;
+
+	case MACH_SGI_IP12:
+		bus_space_write_1(iot, ioh, INT2_TIMER_CLEAR, 0x02);
+		break;
+
+	default:
+		panic("int_8254_intr1");
+	}
 
 	splx(s);
 }
@@ -491,6 +687,6 @@ int2_wait_fifo(uint32_t flag)
 	if (ioh == 0)
 		delay(5000);
 	else
-		while (bus_space_read_4(iot, ioh, INT2_LOCAL0_STATUS) & flag)
+		while (bus_space_read_1(iot, ioh, INT2_LOCAL0_STATUS) & flag)
 			;
 }
Index: arch/sgimips/dev/int1reg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/dev/int1reg.h,v
retrieving revision 1.1
diff -p -u -r1.1 int1reg.h
--- arch/sgimips/dev/int1reg.h	10 Feb 2009 06:04:56 -0000	1.1
+++ arch/sgimips/dev/int1reg.h	10 Feb 2009 08:16:53 -0000
@@ -32,7 +32,7 @@
 
 /*
  * NB: The STATUS register is backwards w.r.t. INT2: a bit set implies
- *     no pending interrupt. The MASK register is like INT2; a bit
+ *     no pending interrupt. The MASK register is like INT2: a bit
  *     set implies that the interrupt is enabled.
  */
 #define INT1_LOCAL_STATUS	0x000002	/* 16-bit */
Index: arch/sgimips/dev/int2reg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/dev/int2reg.h,v
retrieving revision 1.4
diff -p -u -r1.4 int2reg.h
--- arch/sgimips/dev/int2reg.h	11 Dec 2005 12:18:52 -0000	1.4
+++ arch/sgimips/dev/int2reg.h	10 Feb 2009 08:16:53 -0000
@@ -31,26 +31,27 @@
 #define	_ARCH_SGIMIPS_DEV_INT2_H_
 
 /* The INT has known locations on all SGI machines */
-#define	INT_IP12		0x1fb801c0
-#define	INT_IP20		0x1fb801c0
-#define	INT_IP22		0x1fbd9000
-#define	INT_IP24		0x1fbd9880
+#define	INT2_IP12		0x1fb801c0
+#define	INT2_IP20		0x1fb801c0
+#define	INT2_IP22		0x1fbd9000
+#define	INT2_IP24		0x1fbd9880
 
-#define INT2_LOCAL0_STATUS	0x00
+/* The following registers are all 8 bit. */
+#define INT2_LOCAL0_STATUS	0x03
 #define INT2_LOCAL0_STATUS_FIFO	0x01
-#define INT2_LOCAL0_MASK	0x04
-#define INT2_LOCAL1_STATUS	0x08
-#define INT2_LOCAL1_MASK	0x0c
-#define INT2_MAP_STATUS		0x10
-#define INT2_MAP_MASK0		0x14
-#define INT2_MAP_MASK1		0x18
-#define INT2_MAP_POL		0x1c
-#define INT2_TIMER_CLEAR	0x20
-#define INT2_ERROR_STATUS	0x24
-#define INT2_TIMER_0		0x30
-#define	INT2_TIMER_1		0x34
-#define	INT2_TIMER_2		0x38
-#define INT2_TIMER_CONTROL	0x3c
+#define INT2_LOCAL0_MASK	0x07
+#define INT2_LOCAL1_STATUS	0x0b
+#define INT2_LOCAL1_MASK	0x0f
+#define INT2_MAP_STATUS		0x13
+#define INT2_MAP_MASK0		0x17
+#define INT2_MAP_MASK1		0x1b
+#define INT2_MAP_POL		0x1f
+#define INT2_TIMER_CLEAR	0x23
+#define INT2_ERROR_STATUS	0x27
+#define INT2_TIMER_0		0x33
+#define	INT2_TIMER_1		0x37
+#define	INT2_TIMER_2		0x3b
+#define INT2_TIMER_CONTROL	0x3f
 
 #endif /* _ARCH_SGIMIPS_DEV_INT2_H_ */
 
Index: arch/sgimips/dev/zs.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/dev/zs.c,v
retrieving revision 1.35
diff -p -u -r1.35 zs.c
--- arch/sgimips/dev/zs.c	13 Jun 2008 12:27:26 -0000	1.35
+++ arch/sgimips/dev/zs.c	10 Feb 2009 08:16:53 -0000
@@ -127,7 +127,12 @@ struct consdev zs_cn = {
 	zscninit,
 	zscngetc,
 	zscnputc,
-	zscnpollc
+	zscnpollc,
+	NULL,
+	NULL,
+	NULL,
+	NODEV,
+	CN_NORMAL
 };
 
 /* Flags from cninit() */
Index: arch/sgimips/gio/files.gio
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/gio/files.gio,v
retrieving revision 1.9
diff -p -u -r1.9 files.gio
--- arch/sgimips/gio/files.gio	29 Dec 2006 00:42:01 -0000	1.9
+++ arch/sgimips/gio/files.gio	10 Feb 2009 08:16:53 -0000
@@ -5,7 +5,7 @@ attach	gio at giobus
 
 file	arch/sgimips/gio/gio.c		gio needs-flag
 
-device	hpc {[offset = -1]}
+device	hpc {[offset = -1]}: smc93cx6
 attach	hpc at gio
 file	arch/sgimips/hpc/hpc.c		hpc
 
@@ -31,6 +31,4 @@ device	giopci: pcibus
 attach	giopci at gio
 file	arch/sgimips/gio/pci_gio.c	giopci
 
-# Challenge/S mezzanine I/O board..
-
 # Other GIO boards..
Index: arch/sgimips/hpc/files.hpc
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/hpc/files.hpc,v
retrieving revision 1.12
diff -p -u -r1.12 files.hpc
--- arch/sgimips/hpc/files.hpc	27 Aug 2006 10:05:23 -0000	1.12
+++ arch/sgimips/hpc/files.hpc	10 Feb 2009 08:16:53 -0000
@@ -11,14 +11,6 @@ device	wdsc: wd33c93, scsi, hpcdma
 attach	wdsc at hpc
 file	arch/sgimips/hpc/wdsc.c		wdsc
 
-device	dpclock
-attach	dpclock at hpc
-file	arch/sgimips/hpc/dpclock_hpc.c	dpclock
-
-device	dsclock
-attach	dsclock at hpc
-file	arch/sgimips/hpc/dsclock_hpc.c	dsclock
-
 device	haltwo: audiobus, auconv, mulaw
 attach	haltwo at hpc
 file	arch/sgimips/hpc/haltwo.c	haltwo
Index: arch/sgimips/hpc/hpc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/hpc/hpc.c,v
retrieving revision 1.60
diff -p -u -r1.60 hpc.c
--- arch/sgimips/hpc/hpc.c	17 Oct 2007 19:57:04 -0000	1.60
+++ arch/sgimips/hpc/hpc.c	10 Feb 2009 08:16:53 -0000
@@ -144,12 +144,6 @@ static const struct hpc_device hpc1_devi
 	  23,
 	  HPCDEV_IP24 },
 
-	{ "dpclock",	/* Personal Iris/Indigo clock */
-	  HPC_BASE_ADDRESS_0,
-	  HPC1_PBUS_BBRAM, 0,
-	  -1,
-	  HPCDEV_IP12 | HPCDEV_IP20 },
-
 	{ NULL,
 	  0,
 	  0, 0,
@@ -196,12 +190,6 @@ static const struct hpc_device hpc3_devi
 	  2,	/* XXX 2 = IRQ_LOCAL0 + 2 */
 	  HPCDEV_IP22 },
 
-	{ "dsclock",	/* Indigo2/Indy/Challenge S/Challenge M clock */
-	  HPC_BASE_ADDRESS_0,
-	  HPC3_PBUS_BBRAM, 0,
-	  -1,
-	  HPCDEV_IP22 | HPCDEV_IP24 },
-
 	{ "haltwo",	/* Indigo2/Indy onboard audio */
 	  HPC_BASE_ADDRESS_0,
 	  HPC3_PBUS_CH0_DEVREGS, HPC3_PBUS_DMAREGS,
@@ -384,12 +372,15 @@ hpc_match(struct device *parent, struct 
 {
 	struct gio_attach_args* ga = aux;
 
-	/* Make sure it's actually there and readable */
-	if (platform.badaddr((void*)MIPS_PHYS_TO_KSEG1(ga->ga_addr),
-	    sizeof(u_int32_t)))
-		return 0;
+	if (mach_type == MACH_SGI_IP12 || mach_type == MACH_SGI_IP20 ||
+	    mach_type == MACH_SGI_IP22) {
+		/* Make sure it's actually there and readable */
+		if (!platform.badaddr((void*)MIPS_PHYS_TO_KSEG1(ga->ga_addr),
+		    sizeof(u_int32_t)))
+			return 1;
+	}
 
-	return 1;
+	return 0;
 }
 
 static void
@@ -528,14 +519,9 @@ hpc_attach(struct device *parent, struct
 			ha.hpc_regs = &hpc1_values;
 		ha.hpc_regs->revision = hpctype;
 
-		/* XXXgross! avoid complaining in E++ and GIO32 SCSI cases */
-		if (hpctype != 3 && sc->sc_base != HPC_BASE_ADDRESS_0) {
-			(void)config_found_sm_loc(self, "hpc", NULL, &ha,
-			    NULL, hpc_submatch);
-		} else {
-			(void)config_found_sm_loc(self, "hpc", NULL, &ha,
-			    hpc_print, hpc_submatch);
-		}
+/***** XXX - NIX THE CHANGES I  MADE HERE!!! *******/
+		(void)config_found_sm_loc(self, "hpc", NULL, &ha,
+		    hpc_print, hpc_submatch);
 	}
 
 	/*
Index: arch/sgimips/hpc/wdsc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/hpc/wdsc.c,v
retrieving revision 1.27
diff -p -u -r1.27 wdsc.c
--- arch/sgimips/hpc/wdsc.c	27 Jan 2009 11:26:15 -0000	1.27
+++ arch/sgimips/hpc/wdsc.c	10 Feb 2009 08:16:53 -0000
@@ -150,10 +150,14 @@ wdsc_attach(device_t parent, device_t se
 	wsc->sc_hpcdma.hpc = haa->hpc_regs;
 
 	if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh,
-					haa->ha_devoff,
-					wsc->sc_hpcdma.hpc->scsi0_devregs_size,
-					&sc->sc_regh)) != 0) {
-		printf(": unable to map regs, err=%d\n", err);
+	    haa->ha_devoff + 0, 4, &sc->sc_asr_regh)) != 0) {
+		printf(": unable to map asr reg, err=%d\n", err);
+		return;
+	}
+
+	if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh,
+	    haa->ha_devoff + 4,  4, &sc->sc_data_regh)) != 0) {
+		printf(": unable to map asr reg, err=%d\n", err);
 		return;
 	}
 
Index: arch/sgimips/ioc/files.ioc
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/ioc/files.ioc,v
retrieving revision 1.2
diff -p -u -r1.2 files.ioc
--- arch/sgimips/ioc/files.ioc	11 Dec 2005 12:18:53 -0000	1.2
+++ arch/sgimips/ioc/files.ioc	10 Feb 2009 08:16:53 -0000
@@ -1,6 +1,16 @@
 # $NetBSD: files.ioc,v 1.2 2005/12/11 12:18:53 christos Exp $
 
-device ioc {[offset = -1], [intr = -1] }
-attach ioc at mainbus
-file arch/sgimips/ioc/ioc.c			ioc
+device	ioc {[offset = -1], [intr = -1] }
+attach	ioc at mainbus
+file	arch/sgimips/ioc/ioc.c			ioc
 
+device	oioc {[offset = -1], [intr = -1] }
+attach	oioc at mainbus
+file	arch/sgimips/ioc/oioc.c			oioc
+
+attach	le at oioc: le24
+file	arch/sgimips/ioc/if_le_oioc.c		le
+
+device	oiocsc: wd33c93, scsi
+attach	oiocsc at oioc
+file	arch/sgimips/ioc/oiocsc.c		oiocsc
Index: arch/sgimips/sgimips/arcemu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/sgimips/arcemu.c,v
retrieving revision 1.17
diff -p -u -r1.17 arcemu.c
--- arch/sgimips/sgimips/arcemu.c	17 Oct 2007 19:57:05 -0000	1.17
+++ arch/sgimips/sgimips/arcemu.c	10 Feb 2009 08:16:53 -0000
@@ -42,17 +42,17 @@ __KERNEL_RCSID(0, "$NetBSD: arcemu.c,v 1
 #include <dev/arcbios/arcbios.h>
 #include <dev/arcbios/arcbiosvar.h>
 
-#include <dev/ic/smc93cx6var.h>
+#include <dev/ic/wd33c93reg.h>
 
 #define _ARCEMU_PRIVATE
 #include <sgimips/sgimips/arcemu.h>
 #include <sgimips/dev/picreg.h>
 
-static struct consdev arcemu_ip12_cn = {
+static struct consdev arcemu_cn = {
 	NULL,			/* probe */
 	NULL,			/* init */
 	NULL,			/* getc */ /* XXX: this would be nice */
-	arcemu_ip12_putc,	/* putc */
+	arcemu_prom_putc,	/* putc */
 	nullcnpollc,		/* pollc */
 	NULL,			/* bell */
 	NULL,
@@ -109,9 +109,10 @@ static struct arcbios_fv arcemu_v = {
 int
 arcemu_init(const char **env)
 {
-	switch (arcemu_identify()) {
+	switch ((mach_type = arcemu_identify())) {
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
 	case MACH_SGI_IP12:
-		arcemu_ip12_init(ARCEMU_IP12_ENVOK(env) ? env : NULL);
+		arcemu_ipN_init(ARCEMU_ENVOK(env) ? env : NULL);
 		break;
 
 	default:
@@ -123,16 +124,30 @@ arcemu_init(const char **env)
 	return (0);
 }
 
-/* Attempt to identify the SGI IP%d platform. */
+/*
+ * Attempt to identify the SGI IP%d platform. This is extra ugly since
+ * we don't yet have badaddr to fall back on.
+ */
 static int
 arcemu_identify()
 {
+	int mach;
 
 	/*
-	 * XXX - identifying an HPC should be sufficient for IP12
-	 *       since it's the only non-ARCS offering with one.
+	 * Try to write a value to one of IP12's pic(4) graphics DMA registers.
+	 * This is at the same location as four byte parity strobes on IP6,
+	 * which appear to always read 0.
 	 */
-	return (MACH_SGI_IP12); /* boy, that was easy! */
+	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(0x1faa0000) = 0xdeadbeef;
+	DELAY(1000);
+	if (*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(0x1faa0000) == 0xdeadbeef)
+		mach = MACH_SGI_IP12;
+	else
+		mach = MACH_SGI_IP6;
+	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(0x1faa0000) = 0;
+	(void)*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(0x1faa0000);
+
+	return (mach);
 }
 
 static boolean_t
@@ -154,20 +169,16 @@ extractenv(const char **env, const char 
 	return (false);
 }
 
-/*
- * IP12 specific
- */
-
 /* Prom Vectors */
-static void   (*ip12_prom_reset)(void) = (void *)MIPS_PHYS_TO_KSEG1(0x1fc00000);
-static void   (*ip12_prom_reinit)(void) =(void *)MIPS_PHYS_TO_KSEG1(0x1fc00018);
-static int    (*ip12_prom_printf)(const char *, ...) =
+static void   (*sgi_prom_reset)(void) = (void *)MIPS_PHYS_TO_KSEG1(0x1fc00000);
+static void   (*sgi_prom_reinit)(void) =(void *)MIPS_PHYS_TO_KSEG1(0x1fc00018);
+static int    (*sgi_prom_printf)(const char *, ...) =
 					 (void *)MIPS_PHYS_TO_KSEG1(0x1fc00080);
 
 /*
- * The following matches IP12 NVRAM memory layout
+ * The following matches IP6's and IP12's NVRAM memory layout
  */
-static struct arcemu_ip12_nvramdata {
+static struct arcemu_nvramdata {
 	char bootmode;
 	char state;
 	char netaddr[16];
@@ -186,10 +197,11 @@ static struct arcemu_ip12_nvramdata {
 	char passwd[17];
 	char volume[3];
 	uint8_t enaddr[6];
-} ip12nvram;
-static char ip12enaddr[18];
+} nvram;
+
+static char enaddr[18];
 
-static struct arcemu_ip12env {
+static struct arcemu_sgienv {
 	char dbaud[5];
 	char rbaud[5];
 	char bootmode;
@@ -201,122 +213,162 @@ static struct arcemu_ip12env {
 	char netaddr[32];
 	char dlserver[32];
 	char osloadoptions[32];
-} ip12env;
+} sgienv;
 
+/*
+ * EEPROM reading routines. IP6's wiring is sufficiently ugly and the routine
+ * sufficiently small that we just roll our own, rather than contorting the MD
+ * driver.
+ */
 static void
-arcemu_ip12_eeprom_read()
-{
-	struct seeprom_descriptor sd;
-	bus_space_handle_t bsh;
-	bus_space_tag_t tag;
-	u_int32_t reg;
-
-	tag = SGIMIPS_BUS_SPACE_NORMAL;
-	bus_space_map(tag, 0x1fa00000 + 0x1801bf, 1, 0, &bsh);
-
-	/*
-	 * 4D/3x and VIP12 sport a smaller EEPROM than Indigo HP1/HPLC.
-	 * We're only interested in the first 64 half-words in either
-	 * case, but the seeprom driver has to know how many addressing
-	 * bits to feed the chip.
-	 */
-
-	/* 
-	 * This appears to not be the case on my 4D/35.  We'll assume that
-	 * we use eight-bit addressing mode for all IP12 variants.
-	 */
+eeprom_read(uint8_t *eeprom_buf, size_t len, int is_cs56,
+    void (*set_pre)(int), void (*set_cs)(int), void (*set_sk)(int),
+    int (*get_do)(void), void (*set_di)(int))
+{
+	int i, j;
+
+	for (i = 0; i < (len / 2); i++) {
+		uint16_t instr = 0xc000 | (i << ((is_cs56) ? 5 : 7));
+		uint16_t bitword = 0;
+
+		set_di(0);
+		set_sk(0);
+		set_pre(0);
+		set_cs(0);
+		set_cs(1);
+		set_sk(1);
+
+		for (j = 0; j < ((is_cs56) ? 11 : 9); j++) {
+			set_di(instr & 0x8000);
+			set_sk(0);
+			set_sk(1);
+			instr <<= 1;
+		}
 
-	reg = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000);
+		set_di(0);
 
-#if 0
-	if ((reg & 0x8000) == 0)
-		sd.sd_chip = C46;
-	else
-		sd.sd_chip = C56_66;
-#endif
+		for (j = 0; j < 17; j++) {
+			bitword = (bitword << 1) | get_do();
+			set_sk(0);
+			set_sk(1);
+		}
 
-	sd.sd_chip = C56_66;
+		eeprom_buf[i * 2 + 0] = bitword >> 8;
+		eeprom_buf[i * 2 + 1] = bitword & 0xff;
+	
+		set_sk(0);
+		set_cs(0);
+	}
+}
 
-	sd.sd_tag = tag;
-	sd.sd_bsh = bsh;
-	sd.sd_regsize = 1;
-	sd.sd_control_offset = 0;
-	sd.sd_status_offset = 0;
-	sd.sd_dataout_offset = 0;
-	sd.sd_DI = 0x10;	/* EEPROM -> CPU */
-	sd.sd_DO = 0x08;	/* CPU -> EEPROM */
-	sd.sd_CK = 0x04;
-	sd.sd_CS = 0x02;
-	sd.sd_MS = 0;
-	sd.sd_RDY = 0;
+/*
+ * Read the EEPROM. It's not clear which machines have which parts, and
+ * there's a difference in instruction length between the two. We'll try
+ * both and see which doesn't give us garbage.
+ */
+static void
+arcemu_eeprom_read()
+{
+	int i;
 
-	if (read_seeprom(&sd, (uint16_t *)&ip12nvram, 0, 64) != 1)
-		panic("arcemu: NVRAM read failed");
+	/* try long instruction length first (the only one I've seen) */
+	for (i = 1; i >= 0; i--) {
+		if (mach_type == (MACH_SGI_IP6 | MACH_SGI_IP10)) {
+			eeprom_read((uint8_t *)&nvram, sizeof(nvram), i,
+			    ip6_set_pre, ip6_set_cs, ip6_set_sk,
+			    ip6_get_do,  ip6_set_di);
+		} else {
+			eeprom_read((uint8_t *)&nvram, sizeof(nvram), i,
+			    ip12_set_pre, ip12_set_cs, ip12_set_sk,
+			    ip12_get_do,  ip12_set_di);
+		}
 
-	bus_space_unmap(tag, bsh, 1); /* play technically nice */
+		if (nvram.enaddr[0] == 0x08 && nvram.enaddr[1] == 0x00 &&
+		    nvram.enaddr[2] == 0x69)
+			break;
+
+		if (memcmp(nvram.lbaud, "9600\x0", 5) == 0)
+			break;
+
+		if (memcmp(nvram.bootfile, "dksc(", 5) == 0 ||
+		    memcmp(nvram.bootfile, "bootp(", 6) == 0)
+			break;
+	}
 
 	/* cache enaddr string */
-	sprintf(ip12enaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
-	    ip12nvram.enaddr[0],
-	    ip12nvram.enaddr[1],
-	    ip12nvram.enaddr[2],
-	    ip12nvram.enaddr[3],
-	    ip12nvram.enaddr[4],
-	    ip12nvram.enaddr[5]);
+	sprintf(enaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
+	    nvram.enaddr[0],
+	    nvram.enaddr[1],
+	    nvram.enaddr[2],
+	    nvram.enaddr[3],
+	    nvram.enaddr[4],
+	    nvram.enaddr[5]);
 }
 
 static void
-arcemu_ip12_init(const char **env)
+arcemu_ipN_init(const char **env)
 {
 
-	arcemu_v.GetPeer =		  arcemu_ip12_GetPeer;
-	arcemu_v.GetChild =		  arcemu_ip12_GetChild;
-	arcemu_v.GetEnvironmentVariable = arcemu_ip12_GetEnvironmentVariable;
-	arcemu_v.GetMemoryDescriptor =    arcemu_ip12_GetMemoryDescriptor;
-	arcemu_v.Reboot =                 (void *)ip12_prom_reset; 
-	arcemu_v.PowerDown =		  (void *)ip12_prom_reinit; 
-	arcemu_v.EnterInteractiveMode =   (void *)ip12_prom_reinit;	
-
-	cn_tab = &arcemu_ip12_cn;
-	arcemu_ip12_eeprom_read();
-
-	memset(&ip12env, 0, sizeof(ip12env));
-	extractenv(env, "dbaud", ip12env.dbaud, sizeof(ip12env.dbaud));
-	extractenv(env, "rbaud", ip12env.rbaud, sizeof(ip12env.rbaud));
-	extractenv(env, "bootmode",&ip12env.bootmode, sizeof(ip12env.bootmode));
-	extractenv(env, "console", &ip12env.console, sizeof(ip12env.console));
-	extractenv(env, "diskless",&ip12env.diskless, sizeof(ip12env.diskless));
-	extractenv(env, "volume", ip12env.volume, sizeof(ip12env.volume));
-	extractenv(env, "cpufreq", ip12env.cpufreq, sizeof(ip12env.cpufreq));
-	extractenv(env, "gfx", ip12env.gfx, sizeof(ip12env.gfx));
-	extractenv(env, "netaddr", ip12env.netaddr, sizeof(ip12env.netaddr));
-	extractenv(env, "dlserver", ip12env.dlserver, sizeof(ip12env.dlserver));
-	extractenv(env, "osloadoptions", ip12env.osloadoptions,
-	    sizeof(ip12env.osloadoptions));
+	arcemu_v.GetPeer =		  arcemu_GetPeer;
+	arcemu_v.GetChild =		  arcemu_GetChild;
+	arcemu_v.GetEnvironmentVariable = arcemu_GetEnvironmentVariable;
+
+	if (mach_type == MACH_SGI_IP6 || mach_type == MACH_SGI_IP10)
+		arcemu_v.GetMemoryDescriptor = arcemu_ip6_GetMemoryDescriptor;
+	else if (mach_type == MACH_SGI_IP12)
+		arcemu_v.GetMemoryDescriptor = arcemu_ip12_GetMemoryDescriptor;
+
+	arcemu_v.Reboot =                 (void *)sgi_prom_reset; 
+	arcemu_v.PowerDown =		  (void *)sgi_prom_reinit; 
+	arcemu_v.EnterInteractiveMode =   (void *)sgi_prom_reinit;	
+
+	cn_tab = &arcemu_cn;
+
+	arcemu_eeprom_read();
+
+	memset(&sgienv, 0, sizeof(sgienv));
+	extractenv(env, "dbaud", sgienv.dbaud, sizeof(sgienv.dbaud));
+	extractenv(env, "rbaud", sgienv.rbaud, sizeof(sgienv.rbaud));
+	extractenv(env, "bootmode",&sgienv.bootmode, sizeof(sgienv.bootmode));
+	extractenv(env, "console", &sgienv.console, sizeof(sgienv.console));
+	extractenv(env, "diskless",&sgienv.diskless, sizeof(sgienv.diskless));
+	extractenv(env, "volume", sgienv.volume, sizeof(sgienv.volume));
+	extractenv(env, "cpufreq", sgienv.cpufreq, sizeof(sgienv.cpufreq));
+	extractenv(env, "gfx", sgienv.gfx, sizeof(sgienv.gfx));
+	extractenv(env, "netaddr", sgienv.netaddr, sizeof(sgienv.netaddr));
+	extractenv(env, "dlserver", sgienv.dlserver, sizeof(sgienv.dlserver));
+	extractenv(env, "osloadoptions", sgienv.osloadoptions,
+	    sizeof(sgienv.osloadoptions));
 
-	strcpy(arcbios_system_identifier, "SGI-IP12");
 	strcpy(arcbios_sysid_vendor, "SGI");
-	strcpy(arcbios_sysid_product, "IP12");
+	if (mach_type == MACH_SGI_IP6 || mach_type == MACH_SGI_IP10) {
+		strcpy(arcbios_system_identifier, "SGI-IP6");
+		strcpy(arcbios_sysid_product, "IP6");
+	} else if (mach_type == MACH_SGI_IP12) {
+		strcpy(arcbios_system_identifier, "SGI-IP12");
+		strcpy(arcbios_sysid_product, "IP12");
+	}
 }
 
 static void *
-arcemu_ip12_GetPeer(void *node)
+arcemu_GetPeer(void *node)
 {
 	int i;
 
 	if (node == NULL)
 		return (NULL);
 
-	for (i = 0; ip12_tree[i].Class != -1; i++) {
-		if (&ip12_tree[i] == node && ip12_tree[i+1].Class != -1)
-			return (&ip12_tree[i+1]);
+	for (i = 0; arcemu_component_tree[i].Class != -1; i++) {
+		if (&arcemu_component_tree[i] == node &&
+		     arcemu_component_tree[i+1].Class != -1)
+			return (&arcemu_component_tree[i+1]);
 	}
 
 	return (NULL);
 }
 
 static void *
-arcemu_ip12_GetChild(void *node)
+arcemu_GetChild(void *node)
 {
 
 	/*
@@ -324,13 +376,13 @@ arcemu_ip12_GetChild(void *node)
 	 * emulated tree as a single level and avoid messy hierarchies. 
 	 */
 	if (node == NULL)
-		return (&ip12_tree[0]);
+		return (&arcemu_component_tree[0]);
 
 	return (NULL);
 }
 
 static const char *
-arcemu_ip12_GetEnvironmentVariable(const char *var)
+arcemu_GetEnvironmentVariable(const char *var)
 {
 
 	/* 'd'ebug (serial), 'g'raphics, 'G'raphics w/ logo */
@@ -338,10 +390,10 @@ arcemu_ip12_GetEnvironmentVariable(const
 	/* XXX This does not indicate the actual current console */
 	if (strcasecmp("ConsoleOut", var) == 0) {
 		/* if no keyboard is attached, we should default to serial */
-		if (strstr(ip12env.gfx, "dead") != NULL)
+		if (strstr(sgienv.gfx, "dead") != NULL)
 			return "serial(0)";
 
-		switch (ip12nvram.console) {
+		switch (nvram.console) {
 		case 'd':
 		case 'D':
 		case 's':
@@ -352,27 +404,32 @@ arcemu_ip12_GetEnvironmentVariable(const
 			return "video()";
 		default:
 			printf("arcemu: unknown console \"%c\", using serial\n",
-			    ip12nvram.console);
+			    nvram.console);
 			return "serial(0)";
 		}
 	}
 
 	if (strcasecmp("cpufreq", var) == 0) {
-		if (ip12env.cpufreq[0] != '\0')
-			return (ip12env.cpufreq);
-		else
-			return ("33");
+		if (sgienv.cpufreq[0] != '\0')
+			return (sgienv.cpufreq);
+
+		/* IP6 is 12, IP10 is 20 */
+		if (mach_type == MACH_SGI_IP6 || mach_type == MACH_SGI_IP10)
+			return ("16");
+			
+		/* IP12 is 30, 33 or 36 */
+		return ("33");
 	}
 
 	if (strcasecmp("dbaud", var) == 0)
-		return (ip12nvram.lbaud);
+		return (nvram.lbaud);
 
 	if (strcasecmp("eaddr", var) == 0)
-		return (ip12enaddr);
+		return (enaddr);
 
 	if (strcasecmp("gfx", var) == 0) {
-		if (ip12env.gfx[0] != '\0')
-			return (ip12env.gfx);
+		if (sgienv.gfx[0] != '\0')
+			return (sgienv.gfx);
 	}
 
 	/*
@@ -388,17 +445,17 @@ arcemu_ip12_GetEnvironmentVariable(const
 	if (strcasecmp("OSLoadPartition", var) == 0) {
 		char *hack;
 
-		hack = strstr(ip12nvram.bootfile, ",8)");
+		hack = strstr(nvram.bootfile, ",8)");
 		if (hack != NULL)
 			hack[1] = '0';
-		return (ip12nvram.bootfile);
+		return (nvram.bootfile);
 	}
 
 	/* pull filename from e.g.: "dksc(0,1,0)netbsd" */
 	if (strcasecmp("OSLoadFilename", var) == 0) {
 		char *file;
 
-		if ((file = strrchr(ip12nvram.bootfile, ')')) != NULL)
+		if ((file = strrchr(nvram.bootfile, ')')) != NULL)
 			return (file + 1);
 		else	
 			return (NULL);
@@ -411,16 +468,101 @@ arcemu_ip12_GetEnvironmentVariable(const
 	 * something other than "auto".
 	 */
 	if (strcasecmp("OSLoadOptions", var) == 0) {
-		if (ip12env.osloadoptions[0] == '\0')
+		if (sgienv.osloadoptions[0] == '\0')
 			return ("auto");
 		else
-			return (ip12env.osloadoptions);
+			return (sgienv.osloadoptions);
 	}
 
 	return (NULL);
 }
 
 static void *
+arcemu_ip6_GetMemoryDescriptor(void *mem)
+{
+	static struct arcbios_mem am;
+	static int invoc;
+
+	unsigned int pages;
+	u_int8_t memcfg;
+
+	if (mem == NULL) {
+		/*
+		 * We know pages 0, 1 are occupied, emulate the reserved space.
+		 */
+		am.Type = ARCBIOS_MEM_ExceptionBlock;
+		am.BasePage = 0;
+		am.PageCount = 2;
+
+		invoc = 0;
+		return (&am);
+	}
+
+	memcfg = *(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1f800000) & 0x1f;
+	pages = (memcfg & 0x0f) + 1;
+
+	/* 4MB or 1MB units? */
+	if (memcfg & 0x10) {
+		pages *= 4096;
+
+#if 0 // may cause an an exception and bring us down in flames; disable until tested
+		/* check for aliasing and adjust page count if necessary */
+		volatile uint8_t *tp1, *tp2;
+		uint8_t tmp;
+
+		tp1 = (volatile uint8_t *)MIPS_PHYS_TO_KSEG1((pages - 4096) << 12);
+		tp2 = tp1 + (4 * 1024 * 1024);
+
+		tmp = *tp1;
+		*tp2 = ~tmp;
+		if (*tp1 != tmp)
+			pages -= (3 * 1024);
+#endif
+	} else {
+		pages *= 1024;
+	}
+
+	/*
+	 * It appears that the PROM's stack is at 0x400000 in physical memory.
+	 * Don't destroy it, and assume (based on IP12 specs), that the prom bss
+	 * is below it at 0x380000. This is probably overly conservative.
+	 *
+	 * Also note that we preserve the first two pages.
+	 */
+	switch (invoc) {
+	case 0:
+		/* free: pages [2, 896) */
+		am.BasePage = 2;
+		am.PageCount = 894;
+		am.Type = ARCBIOS_MEM_FreeContiguous; 
+		break;
+
+	case 1:
+		/* prom bss/stack: pages [896, 1023) */
+		am.BasePage = 896;
+		am.PageCount = 128;
+		am.Type = ARCBIOS_MEM_FirmwareTemporary;
+		break;
+
+	case 2:
+		/* free: pages [1024, ...) */
+		am.BasePage = 1024;
+		if (pages < 1024)
+			am.PageCount = 0;
+		else
+			am.PageCount = pages - 1024;
+		am.Type = ARCBIOS_MEM_FreeContiguous; 
+		break;
+
+	default:
+		return (NULL);
+	}
+
+	invoc++;
+	return (&am);
+}
+
+static void *
 arcemu_ip12_GetMemoryDescriptor(void *mem)
 {
 	static int bank;
@@ -429,36 +571,38 @@ arcemu_ip12_GetMemoryDescriptor(void *me
 
 	if (mem == NULL) {
 		/*
-		 * We know page 0 is occupied, emulate the reserved space.
+		 * We know pages 0, 1 are occupied, emulate the reserved space.
 		 */
 		am.Type = ARCBIOS_MEM_ExceptionBlock;
 		am.BasePage = 0;
-		am.PageCount = 1;
+		am.PageCount = 2;
 
 		bank = 0;
 		return (&am);
-	} else if (bank > 3)
+	}
+
+	if (bank > 3)
 		return (NULL);
 
 	switch (bank) {
 	case 0:
-		memcfg = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(PIC_MEMCFG0_PHYSADDR)
-		    >>16;
+		memcfg = *(u_int32_t *)
+		    MIPS_PHYS_TO_KSEG1(PIC_MEMCFG0_PHYSADDR) >> 16;
 		break;
 
 	case 1:
-		memcfg = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(PIC_MEMCFG0_PHYSADDR)
-		    & 0xffff;
+		memcfg = *(u_int32_t *)
+		    MIPS_PHYS_TO_KSEG1(PIC_MEMCFG0_PHYSADDR) & 0xffff;
 		break;
 
 	case 2:
-		memcfg = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(PIC_MEMCFG1_PHYSADDR)
-		    >> 16;
+		memcfg = *(u_int32_t *)
+		    MIPS_PHYS_TO_KSEG1(PIC_MEMCFG1_PHYSADDR) >> 16;
 		break;
 
 	case 3:
-		memcfg = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(PIC_MEMCFG1_PHYSADDR)
-		    & 0xffff;
+		memcfg = *(u_int32_t *)
+		    MIPS_PHYS_TO_KSEG1(PIC_MEMCFG1_PHYSADDR) & 0xffff;
 		break;
 
 	default:
@@ -475,10 +619,10 @@ arcemu_ip12_GetMemoryDescriptor(void *me
 		am.BasePage = PIC_MEMCFG_ADDR(memcfg) / ARCBIOS_PAGESIZE;
 		am.PageCount = PIC_MEMCFG_SIZ(memcfg) / ARCBIOS_PAGESIZE;
 
-		/* page 0 is occupied (if clause before switch), compensate */
+		/* pages 0, 1 are occupied (if clause before switch), compensate */
 		if (am.BasePage == 0) {
-			am.BasePage = 1;
-			am.PageCount--;	/* won't overflow */
+			am.BasePage = 2;
+			am.PageCount -= 2;	/* won't overflow */
 		}
 	}
 
@@ -490,9 +634,9 @@ arcemu_ip12_GetMemoryDescriptor(void *me
  * If this breaks.. well.. then it breaks.
  */
 static void
-arcemu_ip12_putc(dev_t dummy, int c)
+arcemu_prom_putc(dev_t dummy, int c)
 {
-	ip12_prom_printf("%c", c);
+	sgi_prom_printf("%c", c);
 }
 
 /* Unimplemented Vector */
Index: arch/sgimips/sgimips/arcemu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/sgimips/arcemu.h,v
retrieving revision 1.10
diff -p -u -r1.10 arcemu.h
--- arch/sgimips/sgimips/arcemu.h	17 Oct 2007 19:57:05 -0000	1.10
+++ arch/sgimips/sgimips/arcemu.h	10 Feb 2009 08:16:53 -0000
@@ -35,7 +35,7 @@
 #include <dev/arcbios/arcbios.h>
 #include <dev/arcbios/arcbiosvar.h>
 
-int arcemu_init(const char **env);
+int arcemu_init(const char **);
 
 #ifdef _ARCEMU_PRIVATE
 
@@ -46,25 +46,27 @@ static int	arcemu_identify(void);
 static boolean_t extractenv(const char **, const char *, char *, int);
 
 /*
- * IP12 Emulation 
+ * IP6, IP12 ARCS Emulation 
  */
 
 /* Prom Emulators */
-static void	arcemu_ip12_init(const char **);
-static void *	arcemu_ip12_GetPeer(void *);
-static void *	arcemu_ip12_GetChild(void *);
-static const char *	arcemu_ip12_GetEnvironmentVariable(const char *); 
+static void	arcemu_ipN_init(const char **);
+static void *	arcemu_GetPeer(void *);
+static void *	arcemu_GetChild(void *);
+static const char *
+		arcemu_GetEnvironmentVariable(const char *); 
+static void *	arcemu_ip6_GetMemoryDescriptor(void *mem);
 static void *	arcemu_ip12_GetMemoryDescriptor(void *mem);
 
-static void	arcemu_ip12_eeprom_read(void);
-static void	arcemu_ip12_putc(dev_t, int);
+static void	arcemu_eeprom_read(void);
+static void	arcemu_prom_putc(dev_t, int);
 
-#define ARCEMU_IP12_ENVOK(_x) 			\
-    (MIPS_PHYS_TO_KSEG1((_x)) >= 0xa0380000 &&	\
-     MIPS_PHYS_TO_KSEG1((_x)) <  0xa0400000)
+#define ARCEMU_ENVOK(_x) 			\
+    (MIPS_PHYS_TO_KSEG1((_x)) >= 0xa0000000 &&	\
+     MIPS_PHYS_TO_KSEG1((_x)) <  0xa0800000)
 
 /* ARCBIOS Component Tree. Represented in linear fashion. */
-static struct arcbios_component ip12_tree[] = {
+static struct arcbios_component arcemu_component_tree[] = {
 	{	COMPONENT_CLASS_ProcessorClass,	COMPONENT_TYPE_CPU,
 		-1, -1, -1, -1, -1, -1, -1, NULL			},
 
@@ -76,6 +78,109 @@ static struct arcbios_component ip12_tre
 #define ARCEMU_UNIMPL ((void *)arcemu_unimpl)
 static void	arcemu_unimpl(void);
 
+/*
+ * EEPROM bit access functions.
+ */
+
+static inline void
+ip6_set_pre(int raise)
+{
+	if (raise)
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1f8e0000) |= 0x10;
+	else
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1f8e0000) &= ~0x10;
+	DELAY(4);
+}
+
+static inline void
+ip6_set_cs(int raise)
+{
+	if (raise)
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1f8e0000) |= 0x20;
+	else
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1f8e0000) &= ~0x20;
+	DELAY(4);
+}
+
+static inline void
+ip6_set_sk(int raise)
+{
+	if (raise)
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1f8e0000) |= 0x40;
+	else
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1f8e0000) &= ~0x40;
+	DELAY(4);
+}
+
+static inline int
+ip6_get_do(void)
+{
+	DELAY(4);
+	if (*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1f800001) & 0x01)
+		return (1);
+	return (0);
+}
+
+static inline void
+ip6_set_di(int raise)
+{
+	if (raise)	
+		*(volatile uint16_t *)MIPS_PHYS_TO_KSEG1(0x1f880002) |= 0x0100;
+	else
+		*(volatile uint16_t *)MIPS_PHYS_TO_KSEG1(0x1f880002) &= ~0x0100;
+	DELAY(4);
+}
+
+static inline void
+ip12_set_pre(int raise)
+{
+	if (raise)
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000) |= 0x01;
+	else
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000) &= ~0x01;
+	DELAY(4);
+}
+
+static inline void
+ip12_set_cs(int raise)
+{
+	if (raise)
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000) |= 0x02;
+	else
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000) &= ~0x02;
+	DELAY(4);
+}
+
+static inline void
+ip12_set_sk(int raise)
+{
+	if (raise)
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000) |= 0x04;
+	else
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000) &= ~0x04;
+	DELAY(4);
+}
+
+static inline int
+ip12_get_do(void)
+{
+	DELAY(4);
+	if (*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000) & 0x08)
+		return (1);
+	return (0);
+}
+
+static inline void
+ip12_set_di(int raise)
+{
+	if (raise)	
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000) |= 0x10;
+	else
+		*(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000) &= ~0x10;
+	DELAY(4);
+}
+
+
 #endif /* _ARCEMU_PRIVATE */
 
 #endif /* _ARCEMU_H_ */
Index: arch/sgimips/sgimips/bus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/sgimips/bus.c,v
retrieving revision 1.55
diff -p -u -r1.55 bus.c
--- arch/sgimips/sgimips/bus.c	4 Jun 2008 12:41:41 -0000	1.55
+++ arch/sgimips/sgimips/bus.c	10 Feb 2009 08:16:53 -0000
@@ -82,6 +82,7 @@ sgimips_bus_dma_init(void)
 {
 	switch (mach_type) {
 	/* R2000/R3000 */
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
 	case MACH_SGI_IP12:
 		sgimips_default_bus_dma_tag._dmamap_sync =
 		    _bus_dmamap_sync_mips1;
@@ -110,6 +111,8 @@ bus_space_read_1(bus_space_tag_t t, bus_
 	switch (t) {
 	case SGIMIPS_BUS_SPACE_NORMAL:
 		return *(volatile u_int8_t *)(vaddr_t)(h + o);
+	case SGIMIPS_BUS_SPACE_IP6_DPCLOCK:
+		return *(volatile u_int8_t *)(vaddr_t)(h + (o << 2));
 	case SGIMIPS_BUS_SPACE_HPC:
 		return *(volatile u_int8_t *)(vaddr_t)(h + (o << 2) + 3);
 	case SGIMIPS_BUS_SPACE_MEM:
@@ -129,6 +132,9 @@ bus_space_write_1(bus_space_tag_t t, bus
 	case SGIMIPS_BUS_SPACE_NORMAL:
 		*(volatile u_int8_t *)(vaddr_t)(h + o) = v;
 		break;
+	case SGIMIPS_BUS_SPACE_IP6_DPCLOCK:
+		*(volatile u_int8_t *)(vaddr_t)(h + (o << 2)) = v;
+		break;
 	case SGIMIPS_BUS_SPACE_HPC:
 		*(volatile u_int8_t *)(vaddr_t)(h + (o << 2) + 3) = v;
 		break;
Index: arch/sgimips/sgimips/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/sgimips/clock.c,v
retrieving revision 1.20
diff -p -u -r1.20 clock.c
--- arch/sgimips/sgimips/clock.c	29 Dec 2006 07:00:11 -0000	1.20
+++ arch/sgimips/sgimips/clock.c	10 Feb 2009 08:16:53 -0000
@@ -126,6 +126,7 @@ cpu_initclocks()
 
 	switch (mach_type) {
 #if defined(MIPS1)
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
 	case MACH_SGI_IP12:
 		/* int(4) will take care of our clocks */
 		/* enable hardware interrupts including hardclock(9) */
Index: arch/sgimips/sgimips/console.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/sgimips/console.c,v
retrieving revision 1.36
diff -p -u -r1.36 console.c
--- arch/sgimips/sgimips/console.c	12 Apr 2007 13:10:59 -0000	1.36
+++ arch/sgimips/sgimips/console.c	10 Feb 2009 08:16:53 -0000
@@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: console.c,v 
 #include <sgimips/mace/macereg.h>
 
 #include "com.h"
+#include "scn.h"
 #include "zsc.h"
 #include "gio.h"
 #include "pckbc.h"
@@ -64,6 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: console.c,v 
 #endif
 int comcnmode = CONMODE;
 
+extern struct consdev scn_cn;
 extern struct consdev zs_cn;
 
 extern void	zs_kgdb_init(void);
@@ -73,6 +75,7 @@ extern int	crmfb_probe(void);
 #endif
 
 void		kgdb_port_init(void);
+static int	scn_serial_init(const char *);
 static int	zs_serial_init(const char *);
 static int	gio_video_init(const char *);
 static int	mace_serial_init(const char *);
@@ -91,6 +94,11 @@ consinit()
 	}
 
 	switch (mach_type) {
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
+		if (scn_serial_init(consdev))
+			return;
+		break;
+
 	case MACH_SGI_IP12:
 	case MACH_SGI_IP20:
 	case MACH_SGI_IP22:
@@ -127,6 +135,22 @@ consinit()
 }
 
 static int
+scn_serial_init(const char *consdev)
+{
+#if (NSCN > 0)
+	if ((strlen(consdev) == 9) && (!strncmp(consdev, "serial", 6)) &&
+	    (consdev[7] == '0' || consdev[7] == '1')) {
+		cn_tab = &scn_cn;
+		(*cn_tab->cn_init)(cn_tab);
+			
+		return (1);
+	}
+#endif
+	
+	return (0);
+}
+
+static int
 zs_serial_init(const char *consdev)
 {
 #if (NZSC > 0)
Index: arch/sgimips/sgimips/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/sgimips/machdep.c,v
retrieving revision 1.124
diff -p -u -r1.124 machdep.c
--- arch/sgimips/sgimips/machdep.c	30 Nov 2008 18:21:35 -0000	1.124
+++ arch/sgimips/sgimips/machdep.c	10 Feb 2009 08:16:53 -0000
@@ -119,9 +119,9 @@ struct cpu_info cpu_info_store;
 struct vm_map *mb_map = NULL;
 struct vm_map *phys_map = NULL;
 
-int mach_type;		/* IPxx type */
-int mach_subtype;	/* subtype: eg., Guinness/Fullhouse for IP22 */
-int mach_boardrev;	/* machine board revision, in case it matters */
+int mach_type = 0;	/* IPxx type */
+int mach_subtype = 0;	/* subtype: eg., Guinness/Fullhouse for IP22 */
+int mach_boardrev = 0;	/* machine board revision, in case it matters */
 
 int physmem;		/* Total physical memory */
 int arcsmem;		/* Memory used by the ARCS firmware */
@@ -132,32 +132,72 @@ int ncpus;
 const int *ipl2spl_table;
 
 #define	IPL2SPL_TABLE_COMMON \
-	[IPL_SOFTCLOCK] = MIPS_SOFT_INT_MASK_1, \
-	[IPL_HIGH] = MIPS_INT_MASK,
+	[IPL_SOFTCLOCK]	= MIPS_SOFT_INT_MASK_1, \
+	[IPL_HIGH]	= MIPS_INT_MASK,
 
 #if defined(MIPS1)
+static const int sgi_ip6_ipl2spl_table[] = {
+	IPL2SPL_TABLE_COMMON
+
+	[IPL_VM]	= MIPS_INT_MASK_1 |
+			  MIPS_INT_MASK_0 |
+			  MIPS_SOFT_INT_MASK_1,
+			  MIPS_SOFT_INT_MASK_0,
+
+	[IPL_SCHED]	= MIPS_INT_MASK_4 |
+			  MIPS_INT_MASK_2 |
+			  MIPS_INT_MASK_1 |
+			  MIPS_INT_MASK_0 |
+			  MIPS_SOFT_INT_MASK_1,
+			  MIPS_SOFT_INT_MASK_0,
+};
 static const int sgi_ip12_ipl2spl_table[] = {
 	IPL2SPL_TABLE_COMMON
-	[IPL_VM] = MIPS_INT_MASK_2|MIPS_INT_MASK_1|MIPS_INT_MASK_0|
-	    MIPS_SOFT_INT_MASK_0,
-	[IPL_SCHED] = MIPS_INT_MASK_4|MIPS_INT_MASK_3|MIPS_INT_MASK_2|
-	    MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK_0,
+
+	[IPL_VM]	= MIPS_INT_MASK_2 |
+			  MIPS_INT_MASK_1 |
+			  MIPS_INT_MASK_0 |
+			  MIPS_SOFT_INT_MASK_1,
+	    		  MIPS_SOFT_INT_MASK_0,
+
+	[IPL_SCHED]	= MIPS_INT_MASK_4 |
+			  MIPS_INT_MASK_3 |
+			  MIPS_INT_MASK_2 |
+	    		  MIPS_INT_MASK_1 |
+			  MIPS_INT_MASK_0 |
+			  MIPS_SOFT_INT_MASK_1,
+			  MIPS_SOFT_INT_MASK_0,
 };
 #endif /* defined(MIPS1) */
+
 #if defined(MIPS3)
 static const int sgi_ip2x_ipl2spl_table[] = {
 	IPL2SPL_TABLE_COMMON
-	[IPL_VM] = MIPS_INT_MASK_1|MIPS_INT_MASK_0|
-	    MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0,
-	[IPL_SCHED] = MIPS_INT_MASK_5|MIPS_INT_MASK_3|MIPS_INT_MASK_2|
-	    MIPS_INT_MASK_1|MIPS_INT_MASK_0|
-	    MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0,
+
+	[IPL_VM]	= MIPS_INT_MASK_1 |
+			  MIPS_INT_MASK_0 |
+			  MIPS_SOFT_INT_MASK_1 |
+			  MIPS_SOFT_INT_MASK_0,
+
+	[IPL_SCHED]	= MIPS_INT_MASK_5 |
+			  MIPS_INT_MASK_3 |
+			  MIPS_INT_MASK_2 |
+			  MIPS_INT_MASK_1 |
+			  MIPS_INT_MASK_0 |
+			  MIPS_SOFT_INT_MASK_1 |
+			  MIPS_SOFT_INT_MASK_0,
 };
 static const int sgi_ip3x_ipl2spl_table[] = {
 	IPL2SPL_TABLE_COMMON
-	[IPL_VM] = MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0,
-	[IPL_SCHED] = MIPS_INT_MASK_5|MIPS_INT_MASK_0|
-	    MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0,
+
+	[IPL_VM]	= MIPS_INT_MASK_0 | 
+			  MIPS_SOFT_INT_MASK_1 |
+			  MIPS_SOFT_INT_MASK_0,
+
+	[IPL_SCHED]	= MIPS_INT_MASK_5 |
+			  MIPS_INT_MASK_0 |
+	    		  MIPS_SOFT_INT_MASK_1 |
+			  MIPS_SOFT_INT_MASK_0,
 };
 #endif /* defined(MIPS3) */
 
@@ -342,7 +382,8 @@ mach_init(int argc, char *argv[], u_int 
 	 * in arcemu_ip12_init().
 	 */
 	for (i = 0; arcbios_system_identifier[i] != '\0'; i++) {
-		if (arcbios_system_identifier[i] >= '0' &&
+		if (mach_type == 0 &&
+		    arcbios_system_identifier[i] >= '0' &&
 		    arcbios_system_identifier[i] <= '9') {
 			mach_type = strtoul(&arcbios_system_identifier[i],
 			    NULL, 10);
@@ -507,6 +548,11 @@ mach_init(int argc, char *argv[], u_int 
 
 	switch (mach_type) {
 #if defined(MIPS1)
+	case MACH_SGI_IP6 | MACH_SGI_IP10:
+		ipl2spl_table = sgi_ip6_ipl2spl_table;
+		platform.intr3 = mips1_fpu_intr;
+		break;
+
 	case MACH_SGI_IP12:
 		i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000);
         	mach_boardrev = (i & 0x7000) >> 12; 
Index: dev/ic/wd33c93.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wd33c93.c,v
retrieving revision 1.22
diff -p -u -r1.22 wd33c93.c
--- dev/ic/wd33c93.c	27 Jan 2009 11:26:15 -0000	1.22
+++ dev/ic/wd33c93.c	10 Feb 2009 08:16:53 -0000
@@ -463,7 +463,8 @@ wd33c93_setsync(struct wd33c93_softc *sc
 int
 wd33c93_dmaok(struct wd33c93_softc *sc, struct scsipi_xfer *xs)
 {
-	if (wd33c93_nodma || (xs->xs_control & XS_CTL_POLL) || xs->datalen == 0)
+	if (wd33c93_nodma || sc->sc_dmamode == SBIC_CTL_NO_DMA ||
+	    (xs->xs_control & XS_CTL_POLL) || xs->datalen == 0)
 		return (0);
 	return(1);
 }
Index: dev/ic/wd33c93reg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wd33c93reg.h,v
retrieving revision 1.3
diff -p -u -r1.3 wd33c93reg.h
--- dev/ic/wd33c93reg.h	8 May 2007 00:29:30 -0000	1.3
+++ dev/ic/wd33c93reg.h	10 Feb 2009 08:16:53 -0000
@@ -156,7 +156,7 @@
  */
 
 #define SBIC_CTL_DMA		0x80	/* Single byte dma */
-#define SBIC_CTL_DBA_DMA	0x40	/* direct buffer acces (bus master)*/
+#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 */
@@ -367,27 +367,25 @@
 #define PAD(n)	char n;
 #define SBIC_MACHINE_DMA_MODE	SBIC_CTL_DMA
 
-typedef struct {
-	volatile unsigned char	wd33c93_asr;	/* r : Aux Status Register */
-#define wd33c93_address		wd33c93_asr	/* w : desired register no */
-	volatile unsigned char	wd33c93_value; /* rw: register value */
-} wd33c93_padded_ind_regmap_t;
-typedef volatile wd33c93_padded_ind_regmap_t *wd33c93_regmap_p;
-
-#define	SBIC_ASR		0	/* offset to ASC register */
-#define	SBIC_ADDR		0	/* offset to address reg */
-#define	SBIC_VAL		1	/* offset to data register */
+/*
+ * 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 {								\
-	bus_space_write_1((sc)->sc_regt,(sc)->sc_regh,SBIC_ADDR,(regno)); \
-	(val) = bus_space_read_1((sc)->sc_regt,(sc)->sc_regh,SBIC_VAL);	\
+	bus_space_write_1((sc)->sc_regt,(sc)->sc_asr_regh, 0, (regno)); \
+	(val) = bus_space_read_1((sc)->sc_regt,(sc)->sc_data_regh, 0);	\
     } while (0)
 
-#define wd33c93_write_reg(sc,regno,val)					\
-    do {								\
-	bus_space_write_1((sc)->sc_regt, (sc)->sc_regh, SBIC_ADDR, (regno)); \
-	bus_space_write_1((sc)->sc_regt, (sc)->sc_regh, SBIC_VAL,  (val)); \
+#define wd33c93_write_reg(sc,regno,val)					 \
+    do {								 \
+	bus_space_write_1((sc)->sc_regt, (sc)->sc_asr_regh, 0, (regno)); \
+	bus_space_write_1((sc)->sc_regt, (sc)->sc_data_regh, 0,  (val)); \
     } while (0)
 
 #define SET_SBIC_myid(sc,val)		wd33c93_write_reg(sc,SBIC_myid,val)
@@ -450,19 +448,19 @@ typedef volatile wd33c93_padded_ind_regm
 #define SBIC_TC_PUT(sc,val)						\
     do {								\
 	wd33c93_write_reg(sc,SBIC_count_hi,((val)>>16));		\
-	bus_space_write_1((sc)->sc_regt, (sc)->sc_regh,			\
-			  SBIC_VAL, (val)>>8); 				\
-	bus_space_write_1((sc)->sc_regt, (sc)->sc_regh,			\
-			  SBIC_VAL, (val)); 				\
+	bus_space_write_1((sc)->sc_regt, (sc)->sc_data_regh, 0,		\
+			  (val)>>8); 					\
+	bus_space_write_1((sc)->sc_regt, (sc)->sc_data_regh, 0,		\
+			  (val)); 					\
     } while (0)
 
 #define SBIC_TC_GET(sc,val)						\
     do {								\
 	wd33c93_read_reg(sc,SBIC_count_hi,(val));			\
 	(val) = ((val)<<8) | bus_space_read_1((sc)->sc_regt,		\
-				(sc)->sc_regh,SBIC_VAL);		\
+				(sc)->sc_data_regh, 0);			\
 	(val) = ((val)<<8) | bus_space_read_1((sc)->sc_regt,		\
-				(sc)->sc_regh,SBIC_VAL);		\
+				(sc)->sc_data_regh, 0);			\
     } while (0)
 
 #define SBIC_LOAD_COMMAND(sc,cmd,cmdsize)				\
@@ -471,20 +469,20 @@ typedef volatile wd33c93_padded_ind_regm
 	char *ptr = (char *)(cmd);					\
 	wd33c93_write_reg(regs, SBIC_cdb1, *ptr++);			\
 	while(n-- > 0)							\
-		bus_space_write_1((sc)->sc_regt, (sc)->sc_regh,		\
-			  SBIC_VAL, *ptr++); /* XXX write_multi */	\
+		bus_space_write_1((sc)->sc_regt, (sc)->sc_data_regh,	\
+			  0, *ptr++); /* XXX write_multi */		\
     } while (0)
 
 #define GET_SBIC_asr(sc,val)						\
     do {								\
-	(val) = bus_space_read_1((sc)->sc_regt,(sc)->sc_regh,SBIC_ASR);	\
+	(val) = bus_space_read_1((sc)->sc_regt,(sc)->sc_asr_regh, 0);	\
     } while (0)
 
 
 #define WAIT_CIP(sc)							\
     do {								\
-	while (bus_space_read_1((sc)->sc_regt,(sc)->sc_regh,		\
-			SBIC_ASR) & SBIC_ASR_CIP) 			\
+	while (bus_space_read_1((sc)->sc_regt,(sc)->sc_asr_regh,	\
+			0) & SBIC_ASR_CIP) 				\
 		/*nop*/;						\
     } while (0)
 
Index: dev/ic/wd33c93var.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wd33c93var.h,v
retrieving revision 1.8
diff -p -u -r1.8 wd33c93var.h
--- dev/ic/wd33c93var.h	25 Jan 2009 15:23:42 -0000	1.8
+++ dev/ic/wd33c93var.h	10 Feb 2009 08:16:53 -0000
@@ -131,7 +131,8 @@ struct wd33c93_softc {
 
 	/* WD33c93 registers */
 	bus_space_tag_t 	sc_regt;
-	bus_space_handle_t 	sc_regh;
+	bus_space_handle_t 	sc_asr_regh;
+	bus_space_handle_t 	sc_data_regh;
 
 
 	/* Data about the current nexus (updated for every cmd switch) */
