? 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 @@ -52,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: int.c,v 1.19 #include +#include #include #include @@ -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 #include -#include +#include #define _ARCEMU_PRIVATE #include #include -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 #include -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 #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) */