diff -Naurp linux-2.6.14.5.orig/arch/mips/Kconfig linux-2.6.14.5/arch/mips/Kconfig --- linux-2.6.14.5.orig/arch/mips/Kconfig 2006-01-01 03:05:08.000000000 -0500 +++ linux-2.6.14.5/arch/mips/Kconfig 2006-01-01 03:27:23.000000000 -0500 @@ -579,6 +579,26 @@ config SGI_IP27 workstations. To compile a Linux kernel that runs on these, say Y here. +config SGI_IP28 + bool "Support for SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)" + depends EXPERIMENTAL + select ARC + select ARC64 + select DMA_NONCOHERENT + select IRQ_CPU + select SWAP_IO_SPACE + select HW_HAS_EISA + select CPU_R10000 + select XKPHYS_KERNEL + select BUILD_ELF64 + select BOOT_ELF64 + select SYS_HAS_CPU_R10000 + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + help + This is the SGI Indigo2 with R10000 processor. To compile a Linux + kernel that runs on these, say Y here. + config SGI_IP32 bool "Support for SGI IP32 (O2) (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -1022,7 +1042,7 @@ config VR4181 config ARC_CONSOLE bool "ARC console support" - depends on SGI_IP22 || SNI_RM200_PCI + depends on SGI_IP22 || SNI_RM200_PCI || SGI_IP28 config ARC_MEMORY bool @@ -1031,7 +1051,7 @@ config ARC_MEMORY config ARC_PROMLIB bool - depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32 + depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP28 || SGI_IP32 default y config ARC64 @@ -1475,6 +1495,14 @@ config 64BIT_PHYS_ADDR bool "Support for 64-bit physical address space" depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_RM9000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32_R1 || CPU_MIPS64_R1) && 32BIT +config XKPHYS_KERNEL + bool "Allow kernel to run from 64-bit segments" + depends on 64BIT + help + This option allows to locate the kernel in 64-bit unmapped memory + space (xkphys). This is required for Octane (IP30) or Indigo2 R10k + (IP28) machines. + config CPU_ADVANCED bool "Override CPU Options" depends on 32BIT diff -Naurp linux-2.6.14.5.orig/arch/mips/Makefile linux-2.6.14.5/arch/mips/Makefile --- linux-2.6.14.5.orig/arch/mips/Makefile 2006-01-01 03:05:08.000000000 -0500 +++ linux-2.6.14.5/arch/mips/Makefile 2006-01-01 03:27:09.000000000 -0500 @@ -645,6 +645,19 @@ endif endif # +# SGI IP28 (Indigo2 R10k) +# +# Set the load address to >= 0xa800000020080000 if you want to leave space for +# symmon, 0xa800000020004000 for production kernels ? Note that the value must +# be 16kb aligned or the handling of the current variable will break. +# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys +# +#core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/ arch/mips/arc/arc_con.o +core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/ +cflags-$(CONFIG_SGI_IP28) += -mip28-cache-barrier -Iinclude/asm-mips/mach-ip28 +load-$(CONFIG_SGI_IP28) += 0xa800000020004000 + +# # SGI-IP32 (O2) # # Set the load address to >= 80069000 if you want to leave space for symmon, diff -Naurp linux-2.6.14.5.orig/arch/mips/configs/ip28_defconfig linux-2.6.14.5/arch/mips/configs/ip28_defconfig --- linux-2.6.14.5.orig/arch/mips/configs/ip28_defconfig 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.14.5/arch/mips/configs/ip28_defconfig 2006-01-01 03:27:09.000000000 -0500 @@ -0,0 +1,1177 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.14-rc2-mipscvs-20050925 +# Wed Oct 12 20:20:44 2005 +# +CONFIG_MIPS=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="-ip28" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_MIPS_MTX1 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_PB1550 is not set +# CONFIG_MIPS_PB1200 is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_DB1550 is not set +# CONFIG_MIPS_DB1200 is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_3 is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_PNX8550_V2PCI is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +CONFIG_SGI_IP28=y +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARC=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_ARC_CONSOLE=y +CONFIG_ARC_PROMLIB=y +CONFIG_ARC64=y +CONFIG_BOOT_ELF64=y + +# +# CPU selection +# +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +CONFIG_CPU_R10000=y +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_MIPS_MT is not set +CONFIG_XKPHYS_KERNEL=y +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_MIPS_INSANE_LARGE is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_EISA=y +CONFIG_ISA=y +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_MMU=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BUILD_ELF64=y +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_TUNNEL=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_NETLINK is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_NETBIOS_NS is not set +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +# CONFIG_IP_NF_PPTP is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +# CONFIG_IP_NF_MATCH_DCCP is not set +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_CONNMARK=m +# CONFIG_IP_NF_MATCH_CONNBYTES is not set +CONFIG_IP_NF_MATCH_HASHLIMIT=m +# CONFIG_IP_NF_MATCH_STRING is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +# CONFIG_IP_NF_TARGET_TTL is not set +CONFIG_IP_NF_TARGET_CONNMARK=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +# CONFIG_IP6_NF_TARGET_REJECT is not set +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_RAW=m + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +CONFIG_NET_SCHED=y +# CONFIG_NET_SCH_CLK_JIFFIES is not set +CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y +# CONFIG_NET_SCH_CLK_CPU is not set +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +# CONFIG_CLS_U32_PERF is not set +# CONFIG_NET_CLS_IND is not set +# CONFIG_CLS_U32_MARK is not set +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_POLICE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +# CONFIG_PARPORT_PC is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_1284 is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=m +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +CONFIG_SGIWD93_SCSI=y +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_EQUALIZER=m +CONFIG_TUN=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_NET_VENDOR_3COM=y +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +CONFIG_VORTEX=m +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set +CONFIG_SGISEEQ=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IP22_ZILOG=y +CONFIG_SERIAL_IP22_ZILOG_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_INDYDOG=y + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set +# CONFIG_RTC is not set +CONFIG_SGI_DS1286=y +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_IMPACT=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_LOGO_SGI_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +CONFIG_SOUND_HAL2=m +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_AD1980 is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# + +# +# SN Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_EXPORT=y +CONFIG_XFS_QUOTA=m +CONFIG_XFS_SECURITY=y +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +CONFIG_MINIX_FS=m +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EFS_FS=m +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_NFSD_TCP=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Profiling support +# +CONFIG_PROFILING=y +# CONFIG_OPROFILE is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="" + +# +# Security options +# +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_TEST=m + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Naurp linux-2.6.14.5.orig/arch/mips/kernel/proc.c linux-2.6.14.5/arch/mips/kernel/proc.c --- linux-2.6.14.5.orig/arch/mips/kernel/proc.c 2006-01-01 03:05:08.000000000 -0500 +++ linux-2.6.14.5/arch/mips/kernel/proc.c 2006-01-01 03:27:09.000000000 -0500 @@ -142,6 +142,11 @@ static int show_cpuinfo(struct seq_file seq_printf(m, fmt, 'D', vced_count); seq_printf(m, fmt, 'I', vcei_count); +#ifdef CONFIG_SGI_IP28 + { extern int ip28_show_be_info(struct seq_file*); + ip28_show_be_info(m); + } +#endif return 0; } diff -Naurp linux-2.6.14.5.orig/arch/mips/lib/memcpy.S linux-2.6.14.5/arch/mips/lib/memcpy.S --- linux-2.6.14.5.orig/arch/mips/lib/memcpy.S 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/arch/mips/lib/memcpy.S 2006-01-01 03:27:09.000000000 -0500 @@ -32,6 +32,14 @@ #include #include +#ifdef CONFIG_SGI_IP28 +/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ +# include +# define R10KCBARRIER(addr) cache Cache_Barrier, addr; +#else +# define R10KCBARRIER(addr) +#endif + #define dst a0 #define src a1 #define len a2 @@ -195,6 +203,7 @@ FEXPORT(__copy_user) */ #define rem t8 + R10KCBARRIER(0(ra)) /* hopefully inhibits speculative store prefetch */ /* * The "issue break"s below are very approximate. * Issue delays for dcache fills will perturb the schedule, as will @@ -227,6 +236,7 @@ both_aligned: PREF( 1, 3*32(dst) ) .align 4 1: + R10KCBARRIER(0(ra)) /* ra must be valid anyway */ EXC( LOAD t0, UNIT(0)(src), l_exc) EXC( LOAD t1, UNIT(1)(src), l_exc_copy) EXC( LOAD t2, UNIT(2)(src), l_exc_copy) @@ -268,6 +278,7 @@ EXC( LOAD t2, UNIT(2)(src), l_exc_copy) EXC( LOAD t3, UNIT(3)(src), l_exc_copy) SUB len, len, 4*NBYTES ADD src, src, 4*NBYTES + R10KCBARRIER(0(ra)) EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) @@ -281,6 +292,7 @@ less_than_4units: beq rem, len, copy_bytes nop 1: + R10KCBARRIER(0(ra)) EXC( LOAD t0, 0(src), l_exc) ADD src, src, NBYTES SUB len, len, NBYTES @@ -326,6 +338,7 @@ EXC( LDFIRST t3, FIRST(0)(src), l_exc) EXC( LDREST t3, REST(0)(src), l_exc_copy) SUB t2, t2, t1 # t2 = number of bytes copied xor match, t0, t1 + R10KCBARRIER(0(ra)) EXC( STFIRST t3, FIRST(0)(dst), s_exc) beq len, t2, done SUB len, len, t2 @@ -346,6 +359,7 @@ src_unaligned_dst_aligned: * It's OK to load FIRST(N+1) before REST(N) because the two addresses * are to the same unit (unless src is aligned, but it's not). */ + R10KCBARRIER(0(ra)) EXC( LDFIRST t0, FIRST(0)(src), l_exc) EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) SUB len, len, 4*NBYTES @@ -374,6 +388,7 @@ cleanup_src_unaligned: beq rem, len, copy_bytes nop 1: + R10KCBARRIER(0(ra)) EXC( LDFIRST t0, FIRST(0)(src), l_exc) EXC( LDREST t0, REST(0)(src), l_exc_copy) ADD src, src, NBYTES @@ -387,6 +402,7 @@ copy_bytes_checklen: nop copy_bytes: /* 0 < len < NBYTES */ + R10KCBARRIER(0(ra)) #define COPY_BYTE(N) \ EXC( lb t0, N(src), l_exc); \ SUB len, len, 1; \ @@ -499,6 +515,7 @@ LEAF(__rmemcpy) /* a0=dst a1=src a2= ADD a1, a2 # src = src + len r_end_bytes: + R10KCBARRIER(0(ra)) lb t0, -1(a1) SUB a2, a2, 0x1 sb t0, -1(a0) @@ -511,6 +528,7 @@ r_out: move a2, zero r_end_bytes_up: + R10KCBARRIER(0(ra)) lb t0, (a1) SUB a2, a2, 0x1 sb t0, (a0) diff -Naurp linux-2.6.14.5.orig/arch/mips/lib/strncpy_user.S linux-2.6.14.5/arch/mips/lib/strncpy_user.S --- linux-2.6.14.5.orig/arch/mips/lib/strncpy_user.S 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/arch/mips/lib/strncpy_user.S 2006-01-01 03:27:09.000000000 -0500 @@ -5,11 +5,20 @@ * * Copyright (c) 1996, 1999 by Ralf Baechle */ +#include #include #include #include #include +#ifdef CONFIG_SGI_IP28 +/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ +# include +# define R10KCBARRIER(addr) cache Cache_Barrier, addr; +#else +# define R10KCBARRIER(addr) +#endif + #define EX(insn,reg,addr,handler) \ 9: insn reg, addr; \ .section __ex_table,"a"; \ @@ -38,6 +47,7 @@ FEXPORT(__strncpy_from_user_nocheck_asm) .set noreorder 1: EX(lbu, t0, (v1), fault) PTR_ADDIU v1, 1 + R10KCBARRIER(0(ra)) beqz t0, 2f sb t0, (a0) PTR_ADDIU v0, 1 diff -Naurp linux-2.6.14.5.orig/arch/mips/lib-64/memset.S linux-2.6.14.5/arch/mips/lib-64/memset.S --- linux-2.6.14.5.orig/arch/mips/lib-64/memset.S 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/arch/mips/lib-64/memset.S 2006-01-01 03:27:09.000000000 -0500 @@ -6,10 +6,19 @@ * Copyright (C) 1998, 1999, 2000 by Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ +#include #include #include #include +#ifdef CONFIG_SGI_IP28 +/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ +# include +# define R10KCBARRIER(addr) cache Cache_Barrier, addr; +#else +# define R10KCBARRIER(addr) +#endif + #define EX(insn,reg,addr,handler) \ 9: insn reg, addr; \ .section __ex_table,"a"; \ @@ -57,6 +66,7 @@ FEXPORT(__bzero) beqz t0, 1f PTR_SUBU t0, LONGSIZE /* alignment in bytes */ + R10KCBARRIER(0(ra)) #ifdef __MIPSEB__ EX(sdl, a1, (a0), first_fixup) /* make dword aligned */ #endif @@ -74,11 +84,13 @@ FEXPORT(__bzero) PTR_ADDU t1, a0 /* end address */ .set reorder 1: PTR_ADDIU a0, 64 + R10KCBARRIER(0(ra)) f_fill64 a0, -64, a1, fwd_fixup bne t1, a0, 1b .set noreorder memset_partial: + R10KCBARRIER(0(ra)) PTR_LA t1, 2f /* where to start */ .set noat dsrl AT, t0, 1 @@ -96,6 +108,7 @@ memset_partial: beqz a2, 1f PTR_ADDU a0, a2 /* What's left */ + R10KCBARRIER(0(ra)) #ifdef __MIPSEB__ EX(sdr, a1, -1(a0), last_fixup) #endif @@ -110,6 +123,7 @@ small_memset: PTR_ADDU t1, a0, a2 1: PTR_ADDIU a0, 1 /* fill bytewise */ + R10KCBARRIER(0(ra)) bne t1, a0, 1b sb a1, -1(a0) diff -Naurp linux-2.6.14.5.orig/arch/mips/mm/c-r4k.c linux-2.6.14.5/arch/mips/mm/c-r4k.c --- linux-2.6.14.5.orig/arch/mips/mm/c-r4k.c 2006-01-01 03:05:08.000000000 -0500 +++ linux-2.6.14.5/arch/mips/mm/c-r4k.c 2006-01-01 03:27:09.000000000 -0500 @@ -671,6 +671,27 @@ static void r4k_dma_cache_inv(unsigned l bc_inv(addr, size); } + +#ifdef CONFIG_CPU_R10000 +static void r10k_dma_cache_inv(unsigned long addr, unsigned long size) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + unsigned long end, a; + + /* Catch bad driver code */ + BUG_ON(size == 0); + //BUG_ON(!cpu_has_subset_pcaches); + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + invalidate_scache_line(a); /* Hit_Invalidate_SD/S */ + if (a == end) + break; + a += sc_lsize; + } +} +#endif /* CONFIG_CPU_R10000 */ #endif /* CONFIG_DMA_NONCOHERENT */ /* @@ -1227,7 +1248,16 @@ void __init r4k_cache_init(void) #ifdef CONFIG_DMA_NONCOHERENT _dma_cache_wback_inv = r4k_dma_cache_wback_inv; _dma_cache_wback = r4k_dma_cache_wback_inv; - _dma_cache_inv = r4k_dma_cache_inv; + switch (current_cpu_data.cputype) { +#ifdef CONFIG_CPU_R10000 + case CPU_R10000: + case CPU_R12000: + _dma_cache_inv = r10k_dma_cache_inv; + break; +#endif + default: + _dma_cache_inv = r4k_dma_cache_inv; + } #endif build_clear_page(); diff -Naurp linux-2.6.14.5.orig/arch/mips/mm/cache.c linux-2.6.14.5/arch/mips/mm/cache.c --- linux-2.6.14.5.orig/arch/mips/mm/cache.c 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/arch/mips/mm/cache.c 2006-01-01 03:27:09.000000000 -0500 @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -61,8 +62,26 @@ asmlinkage int sys_cacheflush(unsigned l if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes)) return -EFAULT; - flush_icache_range(addr, addr + bytes); - + switch (cache) { + case DCACHE: + if (bytes > 0) + (*_dma_cache_wback_inv)(addr, bytes); + break; + case ICACHE: + flush_icache_range(addr, addr + bytes); + break; + case BCACHE: +#if 0 /* Hmm, the same address in both I- and D-cache ? */ + if (bytes > 0) + (*_dma_cache_wback_inv)(addr, bytes); + flush_icache_range(addr, addr + bytes); +#else + (*flush_cache_all)(); +#endif + break; + default: + return -EINVAL; + } return 0; } diff -Naurp linux-2.6.14.5.orig/arch/mips/mm/init.c linux-2.6.14.5/arch/mips/mm/init.c --- linux-2.6.14.5.orig/arch/mips/mm/init.c 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/arch/mips/mm/init.c 2006-01-01 03:27:09.000000000 -0500 @@ -225,6 +225,7 @@ void __init mem_init(void) if (PageReserved(mem_map+tmp)) reservedpages++; } + num_physpages = ram; #ifdef CONFIG_HIGHMEM for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) { @@ -241,6 +242,7 @@ void __init mem_init(void) set_page_count(page, 1); __free_page(page); totalhigh_pages++; + ++num_physpages; } totalram_pages += totalhigh_pages; #endif @@ -266,8 +268,8 @@ void free_initrd_mem(unsigned long start { #ifdef CONFIG_64BIT /* Switch from KSEG0 to XKPHYS addresses */ - start = (unsigned long)phys_to_virt(CPHYSADDR(start)); - end = (unsigned long)phys_to_virt(CPHYSADDR(end)); + start = (unsigned long)phys_to_virt(kernel_physaddr(start)); + end = (unsigned long)phys_to_virt(kernel_physaddr(end)); #endif if (start < end) printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", @@ -293,7 +295,7 @@ void free_initmem(void) addr = (unsigned long) &__init_begin; while (addr < (unsigned long) &__init_end) { #ifdef CONFIG_64BIT - page = PAGE_OFFSET | CPHYSADDR(addr); + page = PAGE_OFFSET | kernel_physaddr(addr); #else page = addr; #endif diff -Naurp linux-2.6.14.5.orig/arch/mips/sgi-ip22/Makefile linux-2.6.14.5/arch/mips/sgi-ip22/Makefile --- linux-2.6.14.5.orig/arch/mips/sgi-ip22/Makefile 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/arch/mips/sgi-ip22/Makefile 2006-01-01 03:27:09.000000000 -0500 @@ -3,9 +3,11 @@ # under Linux. # -obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ +obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o \ ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o +obj-$(CONFIG_SGI_IP28) += ip28-berr.o +obj-$(CONFIG_SGI_IP22) += ip22-berr.o obj-$(CONFIG_EISA) += ip22-eisa.o EXTRA_AFLAGS := $(CFLAGS) diff -Naurp linux-2.6.14.5.orig/arch/mips/sgi-ip22/ip22-mc.c linux-2.6.14.5/arch/mips/sgi-ip22/ip22-mc.c --- linux-2.6.14.5.orig/arch/mips/sgi-ip22/ip22-mc.c 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/arch/mips/sgi-ip22/ip22-mc.c 2006-01-01 03:27:09.000000000 -0500 @@ -4,6 +4,7 @@ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) + * Copyright (C) 2004 Peter Fuerst (pf@net.alphadv.de) - IP28 */ #include @@ -16,6 +17,8 @@ #include #include #include +#include +#include struct sgimc_regs *sgimc; @@ -112,6 +115,10 @@ void __init sgimc_init(void) sgimc = (struct sgimc_regs *) ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); +#ifdef CONFIG_SGI_IP28 + printk(KERN_INFO "Silicon Graphics Indigo2 R10k (IP28)" + " support: (c) 2004 peter fuerst.\n"); +#endif printk(KERN_INFO "MC: SGI memory controller Revision %d\n", (int) sgimc->systemid & SGIMC_SYSID_MASKREV); @@ -138,8 +145,20 @@ void __init sgimc_init(void) * zero. */ tmp = sgimc->cpuctrl0; - tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | - SGIMC_CCTRL0_R4KNOCHKPARR); +#ifndef CONFIG_SGI_IP28 + /* IP28 prom left us cpuctrl0 set to 3d802412: + * SGIMC_CCTRL0_GIOBTOB, SGIMC_CCTRL0_R4KNOCHKPARR, + * SGIMC_CCTRL0_GFXRESET, SGIMC_CCTRL0_EREFRESH, 31800002 + * FIXME: + * We do not attempt to override IP28-prom's parity checking, + * since SGIMC_CCTRL0_EPERRGIO will trigger a CPU parity error + * (IP[6]) on reading sgioc->sysid below, while ..EPERRMEM will + * trigger the same somewhere in prom-code (ffffffff9fc431cc) + * when ArcGetEnvironmentVariable() is called :-( + */ + tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM); +#endif + tmp |= SGIMC_CCTRL0_R4KNOCHKPARR; sgimc->cpuctrl0 = tmp; /* Step 3: Setup the MC write buffer depth, this is controlled @@ -148,6 +167,12 @@ void __init sgimc_init(void) tmp = sgimc->cpuctrl1; tmp &= ~0xf; tmp |= 0xd; +#ifdef CONFIG_SGI_IP28 + /* IP28 prom left us cpuctrl1 set to 00000016: + * SGIMC_CCTRL1_EGIOTIMEO | 00000006 + tmp = tmp & ~0xf | 6; + */ +#endif sgimc->cpuctrl1 = tmp; /* Step 4: Initialize the RPSS divider register to run as fast @@ -165,6 +190,11 @@ void __init sgimc_init(void) * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101 */ sgimc->divider = 0x101; +#ifdef CONFIG_SGI_IP28 + /* IP28 prom left us divider set to 00000104 + sgimc->divider = 0x104; + */ +#endif /* Step 5: Initialize GIO64 arbitrator configuration register. * @@ -177,6 +207,20 @@ void __init sgimc_init(void) tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */ tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */ +#ifdef CONFIG_SGI_IP28 + /* IP28 prom left us giopar set to 0000ce23: + * SGIMC_GIOPAR_PLINEEXP0, SGIMC_GIOPAR_PLINEEXP1, + * SGIMC_GIOPAR_MASTERGFX, SGIMC_GIOPAR_MASTEREISA, + * SGIMC_GIOPAR_ONEBUS, SGIMC_GIOPAR_GFX64, + * SGIMC_GIOPAR_HPC264, SGIMC_GIOPAR_HPC64 + */ + tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC at 64bits */ + tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp0 pipelines */ + tmp |= SGIMC_GIOPAR_PLINEEXP1; /* exp1 pipelines */ + tmp |= SGIMC_GIOPAR_MASTERGFX; /* GFX can act as a bus master */ + tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as bus master */ + tmp |= SGIMC_GIOPAR_GFX64; /* GFX talks to GIO using 64-bits */ +#else if (ip22_is_fullhouse()) { /* Fullhouse specific settings. */ if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) { @@ -196,9 +240,14 @@ void __init sgimc_init(void) tmp |= SGIMC_GIOPAR_EISA64; /* MC talks to EISA at 64bits */ tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */ } +#endif sgimc->giopar = tmp; /* poof */ + printk(KERN_INFO "MC: Boardrev. %d, Chiprev. %d\n", + SGIOC_SYSID_BOARDREV(sgioc->sysid), + SGIOC_SYSID_CHIPREV(sgioc->sysid)); probe_memory(); + ip2628_return_ucmem(0); /* see below. */ } void __init prom_meminit(void) {} @@ -206,3 +255,107 @@ unsigned long __init prom_free_prom_memo { return 0; } + +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) +/* + * Handling uncached writes on IP26/IP28, see IRIX man-page ip26_ucmem(D3) + * and Device Driver Programmer's Guide (007-0911-210), Chapter I.1. + */ + +static inline int _r10k_real_sync ( volatile struct sgimc_regs *sgimc ) +{ + /* See MIPS R10000 User's Manual (SGI 007-2490-001), Chapter 4.5 */ + int dummy = sgimc->cstat; + __asm__ __volatile__ ("sync"); + return dummy; +} + +static unsigned long +ip28_set_ucmem ( volatile struct sgimc_regs *sgimc, unsigned short enable ) +{ /* + * Reading `modereg' only provides random values, so we start with + * guessing (from WR_COL), which state the machine is initially in + * and do our own bookkeeping from then on. + */ + const unsigned long modereg = PHYS_TO_XKSEG_UNCACHED(0x60000000); + static unsigned oldstate = -1; + unsigned long flags; + unsigned tmp; + spinlock_t lock; + u32 mconfig1, cmacc, oldcmacc; + + if (enable == oldstate) + return (long)enable; + + /* This has to be done as early as possible ! */ + spin_lock_irqsave(&lock, flags); + + oldcmacc = sgimc->cmacc; + cmacc = (enable ? 6:4) | (oldcmacc & ~0xf); + + /* increase WR_COL before (if at all) */ + sgimc->cmacc = cmacc | 7; + + /* enable memory bank 3 at 0x60000000 */ + mconfig1 = sgimc->mconfig1; + sgimc->mconfig1 = mconfig1 & 0xffff0000 | 0x2060; + _r10k_real_sync(sgimc); + + /* set mode to "slow" or "normal" */ + *(volatile unsigned long*)modereg = enable ? 0x10000:0; + _r10k_real_sync(sgimc); + + /* restore memory bank configuration */ + sgimc->mconfig1 = mconfig1; + + /* decrease WR_COL only after */ + sgimc->cmacc = cmacc; + _r10k_real_sync(sgimc); + + if (-1 == oldstate) + oldstate = (oldcmacc & 0xf) > 4; + + tmp = oldstate; + oldstate = enable; + _r10k_real_sync(sgimc); + + spin_unlock_irqrestore(&lock, flags); + return tmp; +} +#endif + +unsigned long ip2628_enable_ucmem (void) +{ +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) + if (!sgimc) + sgimc = (struct sgimc_regs *) + ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); + return ip28_set_ucmem(sgimc,1); +#else + return 0; +#endif +} + +void ip2628_return_ucmem ( unsigned long oldstate ) +{ +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) + if (!sgimc) + sgimc = (struct sgimc_regs *) + ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); + ip28_set_ucmem(sgimc,!!oldstate); +#else + (void)oldstate; +#endif +} + +int r10k_real_sync (void) +{ +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) + if (!sgimc) + sgimc = (struct sgimc_regs *) + ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); + return _r10k_real_sync(sgimc); +#else + return 0; +#endif +} diff -Naurp linux-2.6.14.5.orig/arch/mips/sgi-ip22/ip22-setup.c linux-2.6.14.5/arch/mips/sgi-ip22/ip22-setup.c --- linux-2.6.14.5.orig/arch/mips/sgi-ip22/ip22-setup.c 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/arch/mips/sgi-ip22/ip22-setup.c 2006-01-01 03:27:09.000000000 -0500 @@ -143,4 +143,32 @@ void __init plat_setup(void) } } #endif +#if defined(CONFIG_FB_IMPACT) || defined(CONFIG_SGI_IP28) + { + /* Get graphics info before it is overwritten... + * E.g. @ 9000000020f02f78: ffffffff9fc6d770,900000001f000000 + */ + ULONG* (*__vec)(void) = (typeof(__vec)) +#ifdef CONFIG_ARC64 + ((ULONG*)PROMBLOCK->pvector)[8]; +#else + (long) ((int*)PROMBLOCK->pvector)[8]; +#endif + ULONG *gfxinfo = (*__vec)(); + ULONG a = gfxinfo[1]; + + if ((a & 0xffffffff80000000L) == 0xffffffff80000000L) + sgi_gfxaddr = a & (6L<<28) ? 0:CPHYSADDR(a); /* CKSEG[01] */ + else if ((a & (1L<<63)) && (a & 0xb80000001fffffffL) == a) + sgi_gfxaddr = XPHYSADDR(a); /* lower 512MB of XKPHYS */ + else /* rubbish... */ + sgi_gfxaddr = 0; + if (sgi_gfxaddr < 0x1f000000) + sgi_gfxaddr = 0; + + printk(KERN_DEBUG "ARCS gfx info @ %08lx: %08lx,%08lx\n", + gfxinfo, gfxinfo[0], gfxinfo[1]); + printk(KERN_INFO "SGI graphics system @ 0x%08lx\n", sgi_gfxaddr); + } +#endif } diff -Naurp linux-2.6.14.5.orig/arch/mips/sgi-ip22/ip28-berr.c linux-2.6.14.5/arch/mips/sgi-ip22/ip28-berr.c --- linux-2.6.14.5.orig/arch/mips/sgi-ip22/ip28-berr.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.14.5/arch/mips/sgi-ip22/ip28-berr.c 2006-01-01 03:27:09.000000000 -0500 @@ -0,0 +1,696 @@ +/* + * ip28-berr.c: Bus error handling. + * + * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org) + * Copyright (C) 2005 Peter Fuerst (pf@net.alphadv.de) - IP28 + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned count_be_is_fixup = 0; +static unsigned count_be_handler = 0; +static unsigned count_be_interrupt = 0; +static int debug_be_interrupt = 0; + +static unsigned int cpu_err_stat; /* Status reg for CPU */ +static unsigned int gio_err_stat; /* Status reg for GIO */ +static unsigned int cpu_err_addr; /* Error address reg for CPU */ +static unsigned int gio_err_addr; /* Error address reg for GIO */ +static unsigned int extio_stat; +static unsigned int hpc3_berr_stat; /* Bus error interrupt status */ + +struct hpc3_stat { + unsigned int addr; + unsigned int ctrl; + unsigned int cbp; + unsigned int ndptr; +}; + +static struct { + struct hpc3_stat pbdma[8]; + struct hpc3_stat scsi[2]; + struct hpc3_stat ethrx, ethtx; +} hpc3; + +static struct { + unsigned long err_addr; + struct { unsigned lo; unsigned hi; } /* Cache tag High/Low */ + tags[1][2], tagd[4][2], tagi[4][2]; /* Way 0/1 */ +} cache_tags; + +static inline void save_cache_tags(unsigned busaddr) +{ + unsigned long addr = CAC_BASE | busaddr; + unsigned i; + cache_tags.err_addr = addr; + + /* + * Starting with a bus-address, save secondary cache (indexed by + * PA[23..18:7..6]) tags first. + */ + addr &= ~1L; + #define tag cache_tags.tags[0] + cache_op(Index_Load_Tag_S, addr); + tag[0].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */ + tag[0].hi = read_c0_taghi(); /* PA[39:36] */ + cache_op(Index_Load_Tag_S, addr | 1L); + tag[1].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */ + tag[1].hi = read_c0_taghi(); /* PA[39:36] */ + #undef tag + + /* + * Save all primary data cache (indexed by VA[13:5]) tags which + * might fit to this bus-address, knowing that VA[11:0] == PA[11:0]. + * Saving all tags and evaluating them later is easier and safer + * than relying on VA[13:12] from the secondary cache tags to pick + * matching primary tags here already. + */ + addr &= (0xffL << 56) | ((1 << 12) - 1); + #define tag cache_tags.tagd[i] + for (i = 0; i < 4; ++i, addr += (1 << 12)) + { cache_op(Index_Load_Tag_D, addr); + tag[0].lo = read_c0_taglo(); /* PA[35:12] */ + tag[0].hi = read_c0_taghi(); /* PA[39:36] */ + cache_op(Index_Load_Tag_D, addr | 1L); + tag[1].lo = read_c0_taglo(); /* PA[35:12] */ + tag[1].hi = read_c0_taghi(); /* PA[39:36] */ + } + #undef tag + + /* + * Save primary instruction cache (indexed by VA[13:6]) tags + * the same way. + */ + addr &= (0xffL << 56) | ((1 << 12) - 1); + #define tag cache_tags.tagi[i] + for (i = 0; i < 4; ++i, addr += (1 << 12)) + { cache_op(Index_Load_Tag_I, addr); + tag[0].lo = read_c0_taglo(); /* PA[35:12] */ + tag[0].hi = read_c0_taghi(); /* PA[39:36] */ + cache_op(Index_Load_Tag_I, addr | 1L); + tag[1].lo = read_c0_taglo(); /* PA[35:12] */ + tag[1].hi = read_c0_taghi(); /* PA[39:36] */ + } + #undef tag +} + +#define GIO_ERRMASK 0xff00 +#define CPU_ERRMASK 0x3f00 + +static void save_and_clear_buserr(void) +{ + unsigned i; + + /* save status registers */ + cpu_err_addr = sgimc->cerr; + cpu_err_stat = sgimc->cstat; + gio_err_addr = sgimc->gerr; + gio_err_stat = sgimc->gstat; + //BUG_ON(!ip22_is_fullhouse()); + extio_stat = sgioc->extio; + hpc3_berr_stat = hpc3c0->bestat; + + hpc3.scsi[0].addr = &hpc3c0->scsi_chan0; + hpc3.scsi[0].ctrl = hpc3c0->scsi_chan0.ctrl; /* HPC3_SCTRL_ACTIVE ? */ + hpc3.scsi[0].cbp = hpc3c0->scsi_chan0.cbptr; + hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr; + + hpc3.scsi[1].addr = &hpc3c0->scsi_chan1; + hpc3.scsi[1].ctrl = hpc3c0->scsi_chan1.ctrl; /* HPC3_SCTRL_ACTIVE ? */ + hpc3.scsi[1].cbp = hpc3c0->scsi_chan1.cbptr; + hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr; + + hpc3.ethrx.addr = &hpc3c0->ethregs.rx_cbptr; + hpc3.ethrx.ctrl = hpc3c0->ethregs.rx_ctrl; /* HPC3_ERXCTRL_ACTIVE ? */ + hpc3.ethrx.cbp = hpc3c0->ethregs.rx_cbptr; + hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr; + + hpc3.ethtx.addr = &hpc3c0->ethregs.tx_cbptr; + hpc3.ethtx.ctrl = hpc3c0->ethregs.tx_ctrl; /* HPC3_ETXCTRL_ACTIVE ? */ + hpc3.ethtx.cbp = hpc3c0->ethregs.tx_cbptr; + hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr; + + for (i = 0; i < 8; ++i) { + /* HPC3_PDMACTRL_ISACT ? */ + hpc3.pbdma[i].addr = &hpc3c0->pbdma[i]; + hpc3.pbdma[i].ctrl = hpc3c0->pbdma[i].pbdma_ctrl; + hpc3.pbdma[i].cbp = hpc3c0->pbdma[i].pbdma_bptr; + hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr; + } + i = 0; + if (gio_err_stat & CPU_ERRMASK) + i = gio_err_addr; + if (cpu_err_stat & CPU_ERRMASK) + i = cpu_err_addr; + save_cache_tags(i); + + sgimc->cstat = sgimc->gstat = 0; +} + +static void print_cache_tags(void) +{ + unsigned i, scb, scw; + + printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr); + + /* PA[31:12] shifted to PTag0 (PA[35:12]) format */ + scw = (cache_tags.err_addr >> 4) & 0x0fffff00; + + scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1); + for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */ + if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw && + (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw) + continue; + printk(KERN_ERR "D: 0: %08x %08x, 1: %08x %08x (VA[13:5] %04x)\n", + cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo, + cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo, + scb | (1 << 12)*i); + } + scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1); + for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */ + if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw && + (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw) + continue; + printk(KERN_ERR "I: 0: %08x %08x, 1: %08x %08x (VA[13:6] %04x)\n", + cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo, + cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo, + scb | (1 << 12)*i); + } + i = read_c0_config(); + scb = i & (1 << 13) ? 7:6; /* scblksize = 2^[7..6] */ + scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */ + + i = ((1 << scw) - 1) & ~((1 << scb) - 1); + printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x (PA[%u:%u] %05x)\n", + cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo, + cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo, + scw-1, scb, i & (unsigned)cache_tags.err_addr); +} + +static inline const char *cause_excode_text(int cause) +{ + static const char *txt[32] = + { "Interrupt", + "TLB modification", + "TLB (load or instruction fetch)", + "TLB (store)", + "Address error (load or instruction fetch)", + "Address error (store)", + "Bus error (instruction fetch)", + "Bus error (data: load or store)", + "Syscall", + "Breakpoint", + "Reserved instruction", + "Coprocessor unusable", + "Arithmetic Overflow", + "Trap", + "14", + "Floating-Point", + "16", "17", "18", "19", "20", "21", "22", + "Watch Hi/Lo", + "24", "25", "26", "27", "28", "29", "30", "31", + }; + return txt[(cause & 0x7c) >> 2]; +} + +static void print_buserr(struct pt_regs *regs) +{ + const int field = 2 * sizeof(unsigned long); + int error = 0; + + if (extio_stat & EXTIO_MC_BUSERR) { + printk(KERN_ERR "MC Bus Error\n"); + error |= 1; + } + if (extio_stat & EXTIO_HPC3_BUSERR) { + printk(KERN_ERR "HPC3 Bus Error 0x%x:\n", + hpc3_berr_stat, + (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >> + HPC3_BESTAT_PIDSHIFT, + (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA", + hpc3_berr_stat & HPC3_BESTAT_BLMASK); + error |= 2; + } + if (extio_stat & EXTIO_EISA_BUSERR) { + printk(KERN_ERR "EISA Bus Error\n"); + error |= 4; + } + if (cpu_err_stat & CPU_ERRMASK) { + printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n", + cpu_err_stat, + cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "", + cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "", + cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "", + cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "", + cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "", + cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "", + cpu_err_addr); + error |= 8; + } + if (gio_err_stat & GIO_ERRMASK) { + printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n", + gio_err_stat, + gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "", + gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "", + gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "", + gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "", + gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "", + gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "", + gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "", + gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "", + gio_err_addr); + error |= 16; + } + if (!error) + printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n"); + else { + printk(KERN_ERR "CP0: config %08x, " + "MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n" + "MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n", + read_c0_config(), + sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar, + sgimc->cmacc, sgimc->gmacc, + sgimc->mconfig0, sgimc->mconfig1); + print_cache_tags(); + } + printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n", + cause_excode_text(regs->cp0_cause), + field, regs->cp0_epc, field, regs->regs[31]); +} + +/* + * Try to find out, whether the bus error is caused by the instruction + * at EPC, otherwise we have an asynchronous error. + * + * Doc1: "MIPS IV Instruction Set", Rev 3.2 (SGI 007-2597-001) + * Doc2: "MIPS R10000 Microporcessor User's Manual", Ver 2.0 (SGI 007-2490-001) + * Doc3: "MIPS R4000 Microporcessor User's Manual", 2nd Ed. (SGI 007-2489-001) + */ + +#define JMP_INDEX26_OP 1 +#define JMP_REGISTER_OP 2 +#define JMP_PCREL16_OP 3 +#define BASE_OFFSET_OP 4 +#define BASE_IDXREG_OP 5 + +/* Match virtual address in an insn with physical error address */ + +static int match_addr(unsigned paddr, unsigned long vaddr) +{ + unsigned uaddr; + + if ((vaddr & 0xffffffff80000000L) == 0xffffffff80000000L) + uaddr = (unsigned) CPHYSADDR(vaddr); + else if ((vaddr >> 62) == 2) + uaddr = (unsigned) XPHYSADDR(vaddr); + else + { unsigned long eh = vaddr & ~0x1fffL; + eh |= read_c0_entryhi() & 0xff; + write_c0_entryhi(eh); + tlb_probe(); + if (read_c0_index() & 0x80000000) + return 0; + tlb_read(); + if (vaddr & (1L << PAGE_SHIFT)) + uaddr = (unsigned) read_c0_entrylo1(); + else + uaddr = (unsigned) read_c0_entrylo0(); + uaddr <<= 6; + uaddr &= ~PAGE_MASK; + uaddr |= vaddr & PAGE_MASK; + } + return ((uaddr & ~0x7f) == (paddr & ~0x7f)); +} + +/* Check, which kind of memory reference is triggered by `insn' */ + +static int check_special(unsigned insn) +{ + /* See Doc1, page A-180 */ + unsigned func = insn & 0x3f; + + if (8 == func || 8+1 == func) /* JR, JALR */ + return JMP_REGISTER_OP; + + return 0; +} + +static int check_regimm(unsigned insn) +{ + /* See Doc1, page A-180 */ + unsigned rt = (insn >> 19) & 3; /* bits 20..19[..16] */ + + /* BLTZ, BGEZ, BLTZL, BBGEZL || BLTZAL, BGEZAL, BLTZALL, BBGEZALL */ + if (!rt || 2 == rt) + return JMP_PCREL16_OP; + + return 0; +} + +static int check_cop0(unsigned insn) +{ + /* See Doc2, pages 287 ff., 187 ff. */ + if ((insn >> 26) == 5*8+7) /* CACHE */ + switch ((insn >> 16) & 0x1f) { + case Index_Writeback_Inv_D: + case Hit_Writeback_Inv_D: + case Index_Writeback_Inv_S: + case Hit_Writeback_Inv_S: + return BASE_OFFSET_OP; + } + return 0; +} + +static int check_cop1(unsigned insn) +{ + /* See Doc1, pages B-108 ff. */ + unsigned fmt = (insn >> 21) & 0x1f; /* bits 25..21 */ + + if (8 == fmt) /* BC1* */ + return JMP_PCREL16_OP; + + return 0; +} + +static int check_cop1x(unsigned insn) +{ + /* See Doc1, pages B-108 ff. */ + switch (insn & 0x3f) { + case 0: /* LWXC1 */ + case 1: /* LDXC1 */ + case 8: /* SWXC1 */ + case 8+1: /* SDXC1 */ + return BASE_IDXREG_OP; + } + return 0; +} + +static int check_plain(unsigned insn) +{ + /* See Doc1, page A-180 */ + unsigned opcode = insn >> 26; + + if (2 == opcode || 3 == opcode) /* J, JAL */ + return JMP_INDEX26_OP; + + if (4 <= opcode && opcode <= 7 || /* BEQ, BNE, BLEZ, BGTZ */ + 4+2*8 <= opcode && opcode <= 7+2*8) /* BEQL, BNEL, BLEZL, BGTZL */ + return JMP_PCREL16_OP; + + if (6*8+3 == opcode) /* PREF */ + return 0; + + if (3*8+2 == opcode || 3*8+3 == opcode || /* LDL, LDR */ + 4*8 <= opcode) /* misc. LOAD, STORE */ + return BASE_OFFSET_OP; + + return 0; +} + +/* Check, whether the insn at EPC causes a memory access at `paddr' */ + +static int check_addr_in_insn(unsigned paddr, struct pt_regs *regs) +{ + unsigned long epc; + unsigned insn; + int typ; + + epc = regs->cp0_cause & CAUSEF_BD ? regs->cp0_epc:regs->cp0_epc+4; + + /* show_code() from kernel/traps.c */ + if (__get_user(insn, (unsigned*) epc)) + return 1; + + /* See Doc1, pages A-180, B-108 ff. */ + switch (insn >> 26) + { case 0: + typ = check_special(insn); + break; + case 1: + typ = check_regimm(insn); + break; + case 2*8: /* COP0 */ + case 5*8+7: /* CACHE */ + typ = check_cop0(insn); + break; + case 2*8+1: + typ = check_cop1(insn); + break; + case 2*8+3: + typ = check_cop1x(insn); + break; + default: + typ = check_plain(insn); + } + switch (typ) + { unsigned long a; + case JMP_INDEX26_OP: + a = (regs->cp0_epc + 4) & ~0xfffffff; + a |= (insn & 0x3ffffff) << 2; + return match_addr(paddr, a); + case JMP_REGISTER_OP: + a = regs->regs[(insn >> 21) & 0x1f]; + return match_addr(paddr, a); + case JMP_PCREL16_OP: + a = regs->cp0_epc + 4 + ((insn & 0xffff) << 2); + return match_addr(paddr, a); + case BASE_OFFSET_OP: + a = regs->regs[(insn >> 21) & 0x1f] + (insn & 0xffff); + return match_addr(paddr, a); + case BASE_IDXREG_OP: + a = regs->regs[(insn >> 21) & 0x1f]; + a += regs->regs[(insn >> 16) & 0x1f]; + return match_addr(paddr, a); + case 0: + return 0; + } + /* Assume it would be too dangerous to continue ... */ + return 1; +} + +/* + * Check, whether MC's (virtual) DMA address caused the bus error. + * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI + */ + +static int addr_is_ram (unsigned long addr, unsigned sz) +{ + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + unsigned long a = boot_mem_map.map[i].addr; + if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size) + return 1; + } + return 0; +} + +static int check_microtlb (unsigned hi, unsigned lo, unsigned vaddr) +{ + /* This is likely rather similar to correct code ;-) */ + + vaddr &= 0x7fffffff; /* Doc. states that top bit is ignored */ + + /* If tlb-entry is valid and VPN-high (bits [30:21] ?) matches... */ + if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) { + unsigned ctl = sgimc->dma_ctrl; + //BUG_ON(!(ctl & 1)); /* Oops, 32bit page table ! */ + if (ctl & 1) { + unsigned pgsz = (ctl & 2) ? 14:12; /* 16k:4k */ + /* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */ + unsigned long pte = (lo >> 6) << 12; /* PTEBase */ + pte += 8*((vaddr >> pgsz) & 0x1ff); + if ( addr_is_ram(pte,8) ) { + /* + * Note: Since DMA hardware does look up + * translation on its own, this PTE *must* + * match the TLB/EntryLo-register format ! + */ + unsigned long a = *(unsigned long*) + PHYS_TO_XKSEG_UNCACHED(pte); + a = (a & 0x3f) << 6; /* PFN */ + a += vaddr & ((1 << pgsz) - 1); + return (cpu_err_addr == a); + } + } + } + return 0; +} + +static int check_vdma_memaddr (void) +{ + if (cpu_err_stat & CPU_ERRMASK) { + unsigned a = sgimc->maddronly; + + if ( !(sgimc->dma_ctrl & 0x100) ) /* Xlate-bit clear ? */ + return (cpu_err_addr == a); + + if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) || + check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) || + check_microtlb(sgimc->dtlb_hi2, sgimc->dtlb_lo2, a) || + check_microtlb(sgimc->dtlb_hi3, sgimc->dtlb_lo3, a)) + return 1; + } + return 0; +} + +static int check_vdma_gioaddr (void) +{ + if (gio_err_stat & GIO_ERRMASK) { + unsigned a = sgimc->gio_dma_trans; + a = sgimc->gmaddronly & ~a | sgimc->gio_dma_sbits & a; + return (gio_err_addr == a); + } + return 0; +} + +/* + * MC sends an interrupt whenever bus or parity errors occur. In addition, + * if the error happened during a CPU read, it also asserts the bus error + * pin on the R4K. Code in bus error handler save the MC bus error registers + * and then clear the interrupt when this happens. + */ + +static int ip28_be_interrupt(struct pt_regs *regs) +{ + unsigned i; + + save_and_clear_buserr(); + /* + * Try to find out, whether we got here by a mispredicted speculative + * load/store operation. If so, it's not fatal, we can go on. + */ + /* Any cause other than "Interrupt" (ExcCode 0) is fatal. */ + if (regs->cp0_cause & CAUSEF_EXCCODE) + goto mips_be_fatal; + + /* Any cause other than "Bus error interrupt" (IP6) is weird. */ + if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6) + goto mips_be_fatal; + + if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR)) + goto mips_be_fatal; + + /* Any state other than "Memory bus error" is fatal. */ + if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR) + goto mips_be_fatal; + + /* Any state other than "GIO transaction bus timed out" is fatal. */ + if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME) + goto mips_be_fatal; + + /* Finding `cpu_err_addr' in the insn at EPC is fatal. */ + if ((cpu_err_stat & CPU_ERRMASK) && check_addr_in_insn(cpu_err_addr,regs)) + goto mips_be_fatal; + + /* Finding `gio_err_addr' in the insn at EPC is fatal. */ + if ((gio_err_stat & GIO_ERRMASK) && check_addr_in_insn(gio_err_addr,regs)) + goto mips_be_fatal; + /* + * Now we have an asynchronous bus error, speculatively or DMA caused. + * Need to search all DMA descriptors for the error address. + */ + for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) { + struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i; + if ((cpu_err_stat & CPU_ERRMASK) && + (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp)) + break; + if ((gio_err_stat & GIO_ERRMASK) && + (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp)) + break; + } + if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) { + struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i; + printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:" + " ctl %08x, ndp %08x, cbp %08x\n", + CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp); + goto mips_be_fatal; + } + /* Check MC's virtual DMA stuff. */ + if ( check_vdma_memaddr() ) { + printk(KERN_ERR "at GIO DMA: mem address 0x%08x.\n", + sgimc->maddronly); + goto mips_be_fatal; + } + if ( check_vdma_gioaddr() ) { + printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n", + sgimc->gmaddronly); + goto mips_be_fatal; + } + /* A speculative bus error... */ + if (debug_be_interrupt) { + print_buserr(regs); + printk(KERN_ERR "discarded!\n"); + } + return MIPS_BE_DISCARD; + +mips_be_fatal: + print_buserr(regs); + return MIPS_BE_FATAL; +} + +void ip22_be_interrupt(int irq, struct pt_regs *regs) +{ + count_be_interrupt++; + + if (ip28_be_interrupt(regs) != MIPS_BE_DISCARD) { + /* Assume it would be too dangerous to continue ... */ + die_if_kernel("Oops", regs); + force_sig(SIGBUS, current); + } else if (debug_be_interrupt) { + show_regs(regs); + show_code((unsigned int *) regs->cp0_epc); + } +} + +static int ip28_be_handler(struct pt_regs *regs, int is_fixup) +{ + /* + * We arrive here only in the unusual case of do_be() invocation, + * i.e. by a bus error exception without a bus error interrupt. + */ + if (is_fixup) { + count_be_is_fixup++; + save_and_clear_buserr(); + return MIPS_BE_FIXUP; + } + count_be_handler++; + return ip28_be_interrupt(regs); +} + +void __init ip22_be_init(void) +{ + board_be_handler = ip28_be_handler; +} + +int ip28_show_be_info(struct seq_file *m) +{ + seq_printf(m, "IP28 be fixups\t\t: %u\n", count_be_is_fixup); + seq_printf(m, "IP28 be interrupts\t: %u\n", count_be_interrupt); + seq_printf(m, "IP28 be handler\t\t: %u\n", count_be_handler); + + return 0; +} + +static int __init debug_be_setup(char *str) +{ + debug_be_interrupt++; + return 1; +} +__setup("ip28_debug_be", debug_be_setup); + diff -Naurp linux-2.6.14.5.orig/drivers/char/Kconfig linux-2.6.14.5/drivers/char/Kconfig --- linux-2.6.14.5.orig/drivers/char/Kconfig 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/drivers/char/Kconfig 2006-01-01 03:27:09.000000000 -0500 @@ -762,7 +762,7 @@ config RTC config SGI_DS1286 tristate "SGI DS1286 RTC support" - depends on SGI_IP22 + depends on (SGI_IP22 || SGI_IP28) help If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff -Naurp linux-2.6.14.5.orig/drivers/char/tty_io.c linux-2.6.14.5/drivers/char/tty_io.c --- linux-2.6.14.5.orig/drivers/char/tty_io.c 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/drivers/char/tty_io.c 2006-01-01 03:27:09.000000000 -0500 @@ -744,6 +744,7 @@ static struct file *redirect; void tty_wakeup(struct tty_struct *tty) { + if (tty) { struct tty_ldisc *ld; if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { @@ -755,6 +756,7 @@ void tty_wakeup(struct tty_struct *tty) } } wake_up_interruptible(&tty->write_wait); + } } EXPORT_SYMBOL_GPL(tty_wakeup); diff -Naurp linux-2.6.14.5.orig/drivers/char/watchdog/Kconfig linux-2.6.14.5/drivers/char/watchdog/Kconfig --- linux-2.6.14.5.orig/drivers/char/watchdog/Kconfig 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/drivers/char/watchdog/Kconfig 2006-01-01 03:27:09.000000000 -0500 @@ -427,7 +427,7 @@ config WATCHDOG_RTAS config INDYDOG tristate "Indy/I2 Hardware Watchdog" - depends on WATCHDOG && SGI_IP22 + depends on WATCHDOG && (SGI_IP22 || SGI_IP28) help Hardwaredriver for the Indy's/I2's watchdog. This is a watchdog timer that will reboot the machine after a 60 second diff -Naurp linux-2.6.14.5.orig/drivers/input/serio/i8042.c linux-2.6.14.5/drivers/input/serio/i8042.c --- linux-2.6.14.5.orig/drivers/input/serio/i8042.c 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/drivers/input/serio/i8042.c 2006-01-01 03:27:09.000000000 -0500 @@ -656,7 +656,13 @@ static int __init i8042_check_aux(void) if (i8042_command(¶m, I8042_CMD_AUX_ENABLE)) return -1; if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS)) +#ifdef CONFIG_SGI_IP28 + /* Seems we need to invert the CTR_AUXDIS-test on this machine: + * CMD_AUX_DISABLE -> rctr 0xcf, CMD_AUX_ENABLE -> rctr 0xef */ + printk(KERN_WARNING "Failed to enable AUX port, but continuing anyway... ;)\n"); +#else return -1; +#endif /* * Disable the interface. diff -Naurp linux-2.6.14.5.orig/drivers/input/serio/i8042.h linux-2.6.14.5/drivers/input/serio/i8042.h --- linux-2.6.14.5.orig/drivers/input/serio/i8042.h 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/drivers/input/serio/i8042.h 2006-01-01 03:27:09.000000000 -0500 @@ -17,7 +17,7 @@ #if defined(CONFIG_MACH_JAZZ) #include "i8042-jazzio.h" -#elif defined(CONFIG_SGI_IP22) +#elif defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28) #include "i8042-ip22io.h" #elif defined(CONFIG_PPC) #include "i8042-ppcio.h" diff -Naurp linux-2.6.14.5.orig/drivers/net/Kconfig linux-2.6.14.5/drivers/net/Kconfig --- linux-2.6.14.5.orig/drivers/net/Kconfig 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/drivers/net/Kconfig 2006-01-01 03:27:09.000000000 -0500 @@ -1736,7 +1736,7 @@ config DE620 config SGISEEQ tristate "SGI Seeq ethernet controller support" - depends on NET_ETHERNET && SGI_IP22 + depends on NET_ETHERNET && (SGI_IP22 || SGI_IP26 || SGI_IP28) help Say Y here if you have an Seeq based Ethernet network card. This is used in many Silicon Graphics machines. diff -Naurp linux-2.6.14.5.orig/drivers/net/sgiseeq.c linux-2.6.14.5/drivers/net/sgiseeq.c --- linux-2.6.14.5.orig/drivers/net/sgiseeq.c 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/drivers/net/sgiseeq.c 2006-01-01 03:27:09.000000000 -0500 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,34 @@ static char *sgiseeqstr = "SGI Seeq8003"; +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) +/* see SGI documents: 007-0911-210, Chapter I.1. and man ip26_ucmem(D3) */ +# define DMA_NONCOHERENT_CODE(code...) code +/* (Extra) code for memory-mode switch and uncached writes to memory. */ +# define IP28_IP26_CODE(code...) code +#else +# if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_NONCOHERENT_IO) +# define DMA_NONCOHERENT_CODE(code...) code +# else +# define DMA_NONCOHERENT_CODE(code...) +# endif +# define IP28_IP26_CODE(code...) +#endif + +#ifdef TO_PHYS /* mach-ip28/spaces.h, mach-ip22/spaces.h/MIPS64, ... */ +# define SEEQCAC(p) TO_CAC( (unsigned long)(p)) +# define SEEQUNCAC(p) TO_UNCAC((unsigned long)(p)) +# define SEEQPHYS(p) TO_PHYS( (unsigned long)(p)) +#else /* mach-ip22/spaces.h/MIPS32, ... */ +# define SEEQCAC(p) CKSEG0ADDR(p) +# define SEEQUNCAC(p) CKSEG1ADDR(p) +# define SEEQPHYS(p) CPHYSADDR(p) +#endif + +/* Alignment to the largest IP2X cacheblock. */ +#define CACHLIGNDN(x) ((x) & ~0x7f) +#define CACHLIGNUP(x) CACHLIGNDN((x)+0x7f) + /* * If you want speed, you do something silly, it always has worked for me. So, * with that in mind, I've decided to make this driver look completely like a @@ -43,8 +72,11 @@ static char *sgiseeqstr = "SGI Seeq8003" * how a stupid idea like this can pay off in performance, not to mention * making this driver 2,000 times easier to write. ;-) */ - -/* Tune these if we tend to run out often etc. */ +/* + * Tune these if we tend to run out often etc. + * But please don't break the follwing NEXT/PREV macros (i.e. use 16*2^N) + * Btw: doing so, keeps both arrays cacheline-aligned too ;-) + */ #define SEEQ_RX_BUFFERS 16 #define SEEQ_TX_BUFFERS 16 @@ -63,17 +95,21 @@ static char *sgiseeqstr = "SGI Seeq8003" struct sgiseeq_rx_desc { volatile struct hpc_dma_desc rdma; - volatile signed int buf_vaddr; + int _padding[3]; + unsigned long buf_vaddr; + }; struct sgiseeq_tx_desc { volatile struct hpc_dma_desc tdma; - volatile signed int buf_vaddr; + int _padding[3]; + unsigned long buf_vaddr; + }; /* * Warning: This structure is layed out in a certain way because HPC dma - * descriptors must be 8-byte aligned. So don't touch this without + * descriptors must be 16-byte aligned. So don't touch this without * some care. */ struct sgiseeq_init_block { /* Note the name ;-) */ @@ -109,6 +145,7 @@ struct sgiseeq_private { /* A list of all installed seeq devices, for removing the driver module. */ static struct net_device *root_sgiseeq_dev; + static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) { hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ; @@ -166,6 +203,8 @@ static int sgiseeq_set_mac_address(struc static int seeq_init_ring(struct net_device *dev) { struct sgiseeq_private *sp = netdev_priv(dev); + struct sgiseeq_tx_desc *td; + struct sgiseeq_rx_desc *rd; int i; netif_stop_queue(dev); @@ -175,33 +214,60 @@ static int seeq_init_ring(struct net_dev __sgiseeq_set_mac_address(dev); /* Setup tx ring. */ + td = sp->tx_desc; + IP28_IP26_CODE( + /* Here it's best to avoid uncached writes altogether. */ + td = (typeof(td)) SEEQCAC(td); + ) for(i = 0; i < SEEQ_TX_BUFFERS; i++) { - if (!sp->tx_desc[i].tdma.pbuf) { + if (!td[i].tdma.pbuf) { unsigned long buffer; - buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL); + /* Align buffer (start and size) to largest cacheblock. */ + buffer = (unsigned long) + kmalloc(CACHLIGNUP(PKT_BUF_SZ), GFP_KERNEL); if (!buffer) return -ENOMEM; - sp->tx_desc[i].buf_vaddr = CKSEG1ADDR(buffer); - sp->tx_desc[i].tdma.pbuf = CPHYSADDR(buffer); + DMA_NONCOHERENT_CODE( + dma_cache_inv(buffer,PKT_BUF_SZ); + ) + td[i].buf_vaddr = SEEQUNCAC(buffer); + td[i].tdma.pbuf = SEEQPHYS(buffer); } - sp->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT; + td[i].tdma.cntinfo = TCNTINFO_INIT; } - + IP28_IP26_CODE( + dma_cache_wback_inv((unsigned long)sp->srings->txvector, + sizeof(sp->srings->txvector)); + ) /* And now the rx ring. */ + rd = sp->rx_desc; + IP28_IP26_CODE( + /* Here it's best to avoid uncached writes altogether. */ + rd = (typeof(rd)) SEEQCAC(rd); + ) for (i = 0; i < SEEQ_RX_BUFFERS; i++) { - if (!sp->rx_desc[i].rdma.pbuf) { + if (!rd[i].rdma.pbuf) { unsigned long buffer; - buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL); + /* Align buffer (start and size) to largest cacheblock. */ + buffer = (unsigned long) + kmalloc(CACHLIGNUP(PKT_BUF_SZ), GFP_KERNEL); if (!buffer) return -ENOMEM; - sp->rx_desc[i].buf_vaddr = CKSEG1ADDR(buffer); - sp->rx_desc[i].rdma.pbuf = CPHYSADDR(buffer); + DMA_NONCOHERENT_CODE( + dma_cache_inv(buffer,PKT_BUF_SZ); + ) + rd[i].buf_vaddr = SEEQUNCAC(buffer); + rd[i].rdma.pbuf = SEEQPHYS(buffer); } - sp->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT; + rd[i].rdma.cntinfo = RCNTINFO_INIT; } - sp->rx_desc[i - 1].rdma.cntinfo |= HPCDMA_EOR; + rd[i - 1].rdma.cntinfo |= HPCDMA_EOR; + IP28_IP26_CODE( + dma_cache_wback_inv((unsigned long)sp->srings->rxvector, + sizeof(sp->srings->rxvector)); + ) return 0; } @@ -271,8 +337,8 @@ static int init_seeq(struct net_device * sregs->tstat = TSTAT_INIT_SEEQ; } - hregs->rx_ndptr = CPHYSADDR(sp->rx_desc); - hregs->tx_ndptr = CPHYSADDR(sp->tx_desc); + hregs->rx_ndptr = SEEQPHYS(sp->rx_desc); + hregs->tx_ndptr = SEEQPHYS(sp->tx_desc); seeq_go(sp, hregs, sregs); return 0; @@ -297,7 +363,7 @@ static inline void rx_maybe_restart(stru struct sgiseeq_regs *sregs) { if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) { - hregs->rx_ndptr = CPHYSADDR(sp->rx_desc + sp->rx_new); + hregs->rx_ndptr = SEEQPHYS(sp->rx_desc + sp->rx_new); seeq_go(sp, hregs, sregs); } } @@ -311,21 +377,23 @@ static inline void sgiseeq_rx(struct net struct sgiseeq_regs *sregs) { struct sgiseeq_rx_desc *rd; - struct sk_buff *skb = 0; - unsigned char pkt_status; - unsigned char *pkt_pointer = 0; - int len = 0; unsigned int orig_end = PREV_RX(sp->rx_new); - + + IP28_IP26_CODE( + unsigned long ucmemstat = ip2628_enable_ucmem(); + ) /* Service every received packet. */ for_each_rx(rd, sp) { - len = PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3; + unsigned char pkt_status; + const unsigned char *pkt_pointer; + int len = PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3; pkt_pointer = (unsigned char *)(long)rd->buf_vaddr; pkt_status = pkt_pointer[len + 2]; + - if (pkt_status & SEEQ_RSTAT_FIG) { + if (len > 0 && (pkt_status & SEEQ_RSTAT_FIG)) { /* Packet is OK. */ - skb = dev_alloc_skb(len + 2); + struct sk_buff *skb = dev_alloc_skb(len + 2); if (skb) { skb->dev = dev; @@ -358,9 +426,14 @@ static inline void sgiseeq_rx(struct net /* Return the entry to the ring pool. */ rd->rdma.cntinfo = RCNTINFO_INIT; sp->rx_new = NEXT_RX(sp->rx_new); + } - sp->rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR); - sp->rx_desc[PREV_RX(sp->rx_new)].rdma.cntinfo |= HPCDMA_EOR; + rd = sp->rx_desc; + + rd[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR); + rd[PREV_RX(sp->rx_new)].rdma.cntinfo |= HPCDMA_EOR; + + IP28_IP26_CODE( ip2628_return_ucmem(ucmemstat); ) rx_maybe_restart(sp, hregs, sregs); } @@ -373,7 +446,7 @@ static inline void tx_maybe_reset_collis } } -static inline void kick_tx(struct sgiseeq_tx_desc *td, +static inline void kick_tx(const volatile struct sgiseeq_tx_desc *td, struct hpc3_ethregs *hregs) { /* If the HPC aint doin nothin, and there are more packets @@ -384,9 +457,9 @@ static inline void kick_tx(struct sgisee */ while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) == (HPCDMA_XIU | HPCDMA_ETXD)) - td = (struct sgiseeq_tx_desc *)(long) CKSEG1ADDR(td->tdma.pnext); + td = (typeof(td))(long) SEEQUNCAC(td->tdma.pnext); if (td->tdma.cntinfo & HPCDMA_XIU) { - hregs->tx_ndptr = CPHYSADDR(td); + hregs->tx_ndptr = SEEQPHYS(td); hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE; } } @@ -398,6 +471,8 @@ static inline void sgiseeq_tx(struct net struct sgiseeq_tx_desc *td; unsigned long status = hregs->tx_ctrl; int j; + IP28_IP26_CODE( unsigned long ucmemstat; ) + tx_maybe_reset_collisions(sp, sregs); @@ -411,6 +486,7 @@ static inline void sgiseeq_tx(struct net sp->stats.collisions++; } + IP28_IP26_CODE( ucmemstat = ip2628_enable_ucmem(); ) /* Ack 'em... */ for (j = sp->tx_old; j != sp->tx_new; j = NEXT_TX(j)) { td = &sp->tx_desc[j]; @@ -419,16 +495,22 @@ static inline void sgiseeq_tx(struct net break; if (!(td->tdma.cntinfo & (HPCDMA_ETXD))) { if (!(status & HPC3_ETXCTRL_ACTIVE)) { - hregs->tx_ndptr = CPHYSADDR(td); + + hregs->tx_ndptr = SEEQPHYS(td); hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE; } break; } + sp->stats.tx_packets++; sp->tx_old = NEXT_TX(sp->tx_old); td->tdma.cntinfo &= ~(HPCDMA_XIU | HPCDMA_XIE); td->tdma.cntinfo |= HPCDMA_EOX; + + } + + IP28_IP26_CODE( ip2628_return_ucmem(ucmemstat); ) } static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -457,6 +539,14 @@ static irqreturn_t sgiseeq_interrupt(int return IRQ_HANDLED; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void sgiseeq_poll(struct net_device *dev) +{ + disable_irq(dev->irq); + sgiseeq_interrupt(dev->irq, dev, NULL); + enable_irq(dev->irq); +} +#endif static int sgiseeq_open(struct net_device *dev) { @@ -528,6 +618,8 @@ static int sgiseeq_start_xmit(struct sk_ unsigned long flags; struct sgiseeq_tx_desc *td; int skblen, len, entry; + char *vbuf; + IP28_IP26_CODE( unsigned long ucmemstat; ) spin_lock_irqsave(&sp->tx_lock, flags); @@ -551,17 +643,28 @@ static int sgiseeq_start_xmit(struct sk_ * entry and the HPC got to the end of the chain before we * added this new entry and restarted it. */ - memcpy((char *)(long)td->buf_vaddr, skb->data, skblen); + vbuf = (char *)(long)td->buf_vaddr; + IP28_IP26_CODE( vbuf = (typeof(vbuf)) SEEQCAC(vbuf); ) + memcpy(vbuf, skb->data, skblen); if (len != skblen) - memset((char *)(long)td->buf_vaddr + skb->len, 0, len-skblen); + memset(vbuf + skb->len, 0, len-skblen); + IP28_IP26_CODE( + dma_cache_wback_inv((unsigned long)vbuf, len); + + ucmemstat = ip2628_enable_ucmem(); + ) td->tdma.cntinfo = (len & HPCDMA_BCNT) | HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX; if (sp->tx_old != sp->tx_new) { struct sgiseeq_tx_desc *backend; backend = &sp->tx_desc[PREV_TX(sp->tx_new)]; + backend->tdma.cntinfo &= ~HPCDMA_EOX; + } + + IP28_IP26_CODE( ip2628_return_ucmem(ucmemstat); ) sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */ /* Maybe kick the HPC back into motion. */ @@ -619,11 +722,11 @@ static inline void setup_tx_ring(struct int i = 0; while (i < (nbufs - 1)) { - buf[i].tdma.pnext = CPHYSADDR(buf + i + 1); + buf[i].tdma.pnext = SEEQPHYS(buf + i + 1); buf[i].tdma.pbuf = 0; i++; } - buf[i].tdma.pnext = CPHYSADDR(buf); + buf[i].tdma.pnext = SEEQPHYS(buf); } static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs) @@ -631,12 +734,12 @@ static inline void setup_rx_ring(struct int i = 0; while (i < (nbufs - 1)) { - buf[i].rdma.pnext = CPHYSADDR(buf + i + 1); + buf[i].rdma.pnext = SEEQPHYS(buf + i + 1); buf[i].rdma.pbuf = 0; i++; } buf[i].rdma.pbuf = 0; - buf[i].rdma.pnext = CPHYSADDR(buf); + buf[i].rdma.pnext = SEEQPHYS(buf); } #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) @@ -648,6 +751,24 @@ static int sgiseeq_init(struct hpc3_regs struct net_device *dev; int err, i; + /* Optimized away, if these objects are properly sized/aligned... */ + if (ALIGNED(sizeof(*sr->rxvector)) != sizeof(*sr->rxvector) || + ALIGNED(sizeof(*sr->txvector)) != sizeof(*sr->txvector) || + ALIGNED(offsetof(typeof(*sr), rxvector)) + != offsetof(typeof(*sr), rxvector) || + ALIGNED(offsetof(typeof(*sr), txvector)) + != offsetof(typeof(*sr), txvector)) { + printk(KERN_ERR "Sgiseeq: FIXME: HPC dma descriptors " + "must be %d-byte aligned.\n", ALIGNED(1)); + err = -ENOMEM; + goto err_out; + } + if (PAGE_SIZE < sizeof(*sr)) { + printk(KERN_ERR "Sgiseeq: FIXME: Too many dma descriptors " + "to fit in page.\n"); + err = -ENOMEM; + goto err_out; + } dev = alloc_etherdev(sizeof (struct sgiseeq_private)); if (!dev) { printk(KERN_ERR "Sgiseeq: Etherdev alloc failed, aborting.\n"); @@ -682,18 +803,15 @@ static int sgiseeq_init(struct hpc3_regs sp->name = sgiseeqstr; sp->mode = SEEQ_RCMD_RBCAST; - sp->rx_desc = (struct sgiseeq_rx_desc *) - CKSEG1ADDR(ALIGNED(&sp->srings->rxvector[0])); - dma_cache_wback_inv((unsigned long)&sp->srings->rxvector, - sizeof(sp->srings->rxvector)); - sp->tx_desc = (struct sgiseeq_tx_desc *) - CKSEG1ADDR(ALIGNED(&sp->srings->txvector[0])); - dma_cache_wback_inv((unsigned long)&sp->srings->txvector, - sizeof(sp->srings->txvector)); + sp->rx_desc = (typeof(sp->rx_desc)) SEEQUNCAC(&sr->rxvector[0]); + sp->tx_desc = (typeof(sp->tx_desc)) SEEQUNCAC(&sr->txvector[0]); /* A couple calculations now, saves many cycles later. */ - setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS); - setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS); + setup_rx_ring(sr->rxvector, SEEQ_RX_BUFFERS); + setup_tx_ring(sr->txvector, SEEQ_TX_BUFFERS); + + dma_cache_wback_inv((unsigned long)&sr->rxvector, sizeof(sr->rxvector)); + dma_cache_wback_inv((unsigned long)&sr->txvector, sizeof(sr->txvector)); /* Setup PIO and DMA transfer timing */ sp->hregs->pconfig = 0x161; @@ -718,6 +836,9 @@ static int sgiseeq_init(struct hpc3_regs dev->set_multicast_list = sgiseeq_set_multicast; dev->set_mac_address = sgiseeq_set_mac_address; dev->irq = irq; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = sgiseeq_poll; +#endif if (register_netdev(dev)) { printk(KERN_ERR "Sgiseeq: Cannot register net device, " @@ -736,7 +857,7 @@ static int sgiseeq_init(struct hpc3_regs return 0; err_out_free_page: - free_page((unsigned long) sp->srings); + free_page((unsigned long) sr); err_out_free_dev: kfree(dev); diff -Naurp linux-2.6.14.5.orig/drivers/scsi/Kconfig linux-2.6.14.5/drivers/scsi/Kconfig --- linux-2.6.14.5.orig/drivers/scsi/Kconfig 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/drivers/scsi/Kconfig 2006-01-01 03:27:09.000000000 -0500 @@ -249,7 +249,7 @@ menu "SCSI low-level drivers" config SGIWD93_SCSI tristate "SGI WD93C93 SCSI Driver" - depends on SGI_IP22 && SCSI + depends on (SGI_IP22 || SGI_IP26 || SGI_IP28) && SCSI help If you have a Western Digital WD93 SCSI controller on an SGI MIPS system, say Y. Otherwise, say N. diff -Naurp linux-2.6.14.5.orig/drivers/scsi/sgiwd93.c linux-2.6.14.5/drivers/scsi/sgiwd93.c --- linux-2.6.14.5.orig/drivers/scsi/sgiwd93.c 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/drivers/scsi/sgiwd93.c 2006-01-01 03:27:09.000000000 -0500 @@ -7,6 +7,7 @@ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) * Copyright (C) 2001 Florian Lohoff (flo@rfc822.org) * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2004 Peter Fuerst (pf@net.alphadv.de) - IP28 * * (In all truth, Jed Schimmel wrote all this code.) */ @@ -42,6 +43,34 @@ #define DPRINTK(args...) #endif +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) +/* see SGI documents: 007-0911-210, Chapter I.1. and man ip26_ucmem(D3) */ +# define DMA_NONCOHERENT_CODE(code...) code +/* (Extra) code for cached writes to memory with coherency operations. */ +# define IP28_IP26_CODE(code...) code +#else +# if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_NONCOHERENT_IO) +# define DMA_NONCOHERENT_CODE(code...) code +# else +# define DMA_NONCOHERENT_CODE(code...) +# endif +# define IP28_IP26_CODE(code...) +#endif + +#ifdef TO_PHYS /* mach-ip28/spaces.h, mach-ip22/spaces.h/MIPS64, ... */ +# define WD93CAC(p) TO_CAC( (unsigned long)(p)) +# define WD93UNCAC(p) TO_UNCAC((unsigned long)(p)) +# define WD93PHYS(p) TO_PHYS( (unsigned long)(p)) +#else /* mach-ip22/spaces.h/MIPS32, ... */ +# define WD93CAC(p) CKSEG0ADDR(p) +# define WD93UNCAC(p) CKSEG1ADDR(p) +# define WD93PHYS(p) CPHYSADDR(p) +#endif + +/* Alignment to the largest IP2X cacheblock. */ +#define CACHLIGNDN(x) ((x) & ~0x7f) +#define CACHLIGNUP(x) CACHLIGNDN((x)+0x7f) + #define HDATA(ptr) ((struct ip22_hostdata *)((ptr)->hostdata)) struct ip22_hostdata { @@ -49,6 +78,16 @@ struct ip22_hostdata { struct hpc_data { dma_addr_t dma; void * cpu; + /* + * A cacheline-aligned intermediate dma read buffer for all + * the small, not cacheline-aligned Scsi_Cmnd input buffers. + */ + char (*buf)[PAGE_SIZE]; + struct { + char *scp; + char *rbp; + unsigned len; + } rb; } hd; }; @@ -57,6 +96,9 @@ struct hpc_chunk { u32 _padding; /* align to quadword boundary */ }; +static dma_addr_t sgiwd93_dma_map(Scsi_Cmnd*); +static void sgiwd93_dma_unmap(Scsi_Cmnd*); + struct Scsi_Host *sgiwd93_host; struct Scsi_Host *sgiwd93_host1; @@ -98,20 +140,31 @@ static irqreturn_t sgiwd93_intr(int irq, } static inline -void fill_hpc_entries(struct hpc_chunk *hcp, Scsi_Cmnd *cmd, int datainp) +int fill_hpc_entries(struct hpc_chunk *hcp, Scsi_Cmnd *cmd) { unsigned long len = cmd->SCp.this_residual; - void *addr = cmd->SCp.ptr; dma_addr_t physaddr; unsigned long count; + IP28_IP26_CODE( int nc; struct hpc_chunk *hcpstart; ) + - physaddr = dma_map_single(NULL, addr, len, cmd->sc_data_direction); - cmd->SCp.dma_handle = physaddr; + physaddr = sgiwd93_dma_map(cmd); + if (!physaddr) + return 1; + + IP28_IP26_CODE( + hcpstart = hcp = (typeof(hcp)) WD93CAC(hcp); + nc = 1 + (len + 8191) / 8192; + nc = CACHLIGNUP(sizeof(*hcp)*nc); + /* dma_cache_inv((unsigned long) hcp, nc); */ + ) while (len) { /* * even cntinfo could be up to 16383, without * magic only 8192 works correctly + * (even much less than 8192 may fail, since + * pbuf must not cross any page boundaries !) */ count = len > 8192 ? 8192 : len; hcp->desc.pbuf = physaddr; @@ -128,6 +181,10 @@ void fill_hpc_entries(struct hpc_chunk * */ hcp->desc.pbuf = 0; hcp->desc.cntinfo = HPCDMA_EOX; + + IP28_IP26_CODE( dma_cache_wback_inv((unsigned long)hcpstart, nc); ) + + return 0; } static int dma_setup(Scsi_Cmnd *cmd, int datainp) @@ -139,6 +196,11 @@ static int dma_setup(Scsi_Cmnd *cmd, int DPRINTK("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); + if (datainp && cmd->sc_data_direction != DMA_FROM_DEVICE || + !datainp && cmd->sc_data_direction != DMA_TO_DEVICE) + DPRINTK(KERN_WARNING "sgiwd93: DMA direction mismatch: " + "data %sput vs. sc_data_direction %d !\n", + datainp ? "in":"out", cmd->sc_data_direction); hdata->wh.dma_dir = datainp; /* @@ -147,11 +209,14 @@ static int dma_setup(Scsi_Cmnd *cmd, int * obvious). IMHO a better fix would be, not to do these dma setups * in the first place. */ - if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) + if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) { + DPRINTK("\n"); return 1; - - fill_hpc_entries(hcp, cmd, datainp); - + } + if (fill_hpc_entries(hcp, cmd)) { + DPRINTK("\n"); + return 1; + } DPRINTK(" HPCGO\n"); /* Start up the HPC. */ @@ -171,7 +236,7 @@ static void dma_stop(struct Scsi_Host *i struct hpc3_scsiregs *hregs; if (!SCpnt) - return; + return; /* really ignore wd33c93_host_reset() ? */ hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base; @@ -184,8 +249,7 @@ static void dma_stop(struct Scsi_Host *i barrier(); } hregs->ctrl = 0; - dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, - SCpnt->sc_data_direction); + sgiwd93_dma_unmap(SCpnt); DPRINTK("\n"); } @@ -204,17 +268,26 @@ static inline void init_hpc_chain(struct struct hpc_chunk *hcp = (struct hpc_chunk *) hd->cpu; struct hpc_chunk *dma = (struct hpc_chunk *) hd->dma; unsigned long start, end; + + IP28_IP26_CODE( hcp = (typeof(hcp)) WD93CAC(hcp); ) start = (unsigned long) hcp; end = start + PAGE_SIZE; + while (start < end) { hcp->desc.pnext = (u32) (dma + 1); hcp->desc.cntinfo = HPCDMA_EOX; hcp++; dma++; start += sizeof(struct hpc_chunk); - }; + } hcp--; hcp->desc.pnext = hd->dma; + + IP28_IP26_CODE( + /* Force flush to memory and purge cached references ! */ + dma_cache_wback_inv(WD93CAC(hd->cpu), PAGE_SIZE); + ) + } static struct Scsi_Host * __init sgiwd93_setup_scsi( @@ -233,13 +306,20 @@ static struct Scsi_Host * __init sgiwd93 host->irq = irq; hdata = HDATA(host); - hdata->hd.cpu = dma_alloc_coherent(NULL, PAGE_SIZE, &hdata->hd.dma, - GFP_KERNEL); + hdata->hd.cpu = dma_alloc_coherent(NULL, DMA_NONCOHERENT_CODE(2*)PAGE_SIZE, + &hdata->hd.dma, GFP_KERNEL); if (!hdata->hd.cpu) { printk(KERN_WARNING "sgiwd93: Could not allocate memory for " "host %d buffer.\n", unit); goto out_unregister; } + hdata->hd.rb.rbp = 0; + hdata->hd.rb.scp = 0; + hdata->hd.rb.len = 0; + hdata->hd.buf = 0; + DMA_NONCOHERENT_CODE( + hdata->hd.buf = (void*) ((char*)hdata->hd.cpu + PAGE_SIZE); + ) init_hpc_chain(&hdata->hd); regs.SASR = wdregs + 3; @@ -257,7 +337,8 @@ static struct Scsi_Host * __init sgiwd93 return host; out_free: - dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); + dma_free_coherent(NULL, DMA_NONCOHERENT_CODE(2*)PAGE_SIZE, + hdata->hd.cpu, hdata->hd.dma); wd33c93_release(); out_unregister: @@ -300,7 +381,8 @@ int sgiwd93_release(struct Scsi_Host *in irq = SGI_WD93_1_IRQ; free_irq(irq, sgiwd93_intr); - dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); + dma_free_coherent(NULL, DMA_NONCOHERENT_CODE(2*)PAGE_SIZE, + hdata->hd.cpu, hdata->hd.dma); wd33c93_release(); return 1; @@ -320,6 +402,96 @@ static int sgiwd93_bus_reset(Scsi_Cmnd * return SUCCESS; } +static dma_addr_t sgiwd93_dma_map( Scsi_Cmnd *cmd ) +{ + struct ip22_hostdata *hdata = HDATA(cmd->device->host); + unsigned len = cmd->SCp.this_residual; + void *addr = cmd->SCp.ptr; + /* + * We cannot use 'cmd->sc_data_direction' here, since we are called + * for an explicit dma-direction, and it is mere *concidence*, if + * 'sc_data_direction' is consistent with this direction ! + * (tracing shows, 'sc_...' isn't well defined at all...) + */ + int dmadir = hdata->wh.dma_dir ? DMA_FROM_DEVICE:DMA_TO_DEVICE; + + DMA_NONCOHERENT_CODE( + if (hdata->hd.rb.rbp) { + printk(KERN_ERR "sgiwd93_dma_map: %s: discarding stale input buffer!" + " (%p)\n", hdata->wh.dma_dir ? "in":"out", hdata->hd.rb.scp); + if (hdata->hd.rb.rbp != hdata->hd.buf) + kfree(hdata->hd.rb.rbp); + } + hdata->hd.rb.scp = addr; + hdata->hd.rb.rbp = 0; + hdata->hd.rb.len = len; + if (hdata->wh.dma_dir) { + /* + * (at least by now) it seems, we cannot safely avoid + * to intercept *all* input-buffers on IP28. + */ + if (IP28_IP26_CODE(1 || )CACHLIGNUP(len) != len || + CACHLIGNDN((unsigned)addr) != (unsigned)addr) { + len = CACHLIGNUP(len); + if (len <= sizeof(*hdata->hd.buf)) { + hdata->hd.rb.rbp = addr = hdata->hd.buf; + /* Sigh... Screw it, to make dma_map_single() work. */ + addr = phys_to_virt( WD93PHYS(addr) ); + } else { + if ( !(addr = kmalloc(len, GFP_KERNEL)) ) + return (cmd->SCp.dma_handle = 0); + hdata->hd.rb.rbp = addr; + } + } + }) + cmd->SCp.dma_handle = dma_map_single(NULL, addr, len, dmadir); + return cmd->SCp.dma_handle; +} + +static void sgiwd93_dma_unmap( Scsi_Cmnd *cmd ) +{ + struct ip22_hostdata *hdata = HDATA(cmd->device->host); + unsigned len = cmd->SCp.this_residual; + +#ifdef CONFIG_CPU_R10000 + /* R10000 on non-cachecoherent systems needs special care */ + DMA_NONCOHERENT_CODE( + if (hdata->hd.rb.rbp) + dma_cache_inv(WD93CAC(hdata->hd.rb.rbp), + CACHLIGNUP(hdata->hd.rb.len)); + else if (hdata->wh.dma_dir) + dma_cache_inv((unsigned long)cmd->SCp.ptr, len); + ) +#endif + DMA_NONCOHERENT_CODE( + /* We had dma_map'ed an aligned input buffer ! */ + if (hdata->wh.dma_dir) len = CACHLIGNUP(len); + ) + dma_unmap_single(NULL, cmd->SCp.dma_handle, len, + hdata->wh.dma_dir ? DMA_FROM_DEVICE:DMA_TO_DEVICE); + + DMA_NONCOHERENT_CODE( + if (cmd->SCp.ptr != hdata->hd.rb.scp) + printk(KERN_ERR "sgiwd93_dma_map: %s: mismatched SCp! (%p,%p)\n", + hdata->wh.dma_dir ? "in":"out", hdata->hd.rb.scp, + cmd->SCp.ptr); + if (hdata->hd.rb.rbp) { + if (!hdata->wh.dma_dir) + printk(KERN_ERR "sgiwd93_dma_unmap: out: discarding " + "stale input buffer! (%p)\n", hdata->hd.rb.scp); + else /* if (cmd->SCp.ptr == hdata->hd.rb.scp) */ + memcpy(hdata->hd.rb.scp, hdata->hd.rb.rbp, + hdata->hd.rb.len); + + if (hdata->hd.rb.rbp != hdata->hd.buf) + kfree(hdata->hd.rb.rbp); + } + hdata->hd.rb.scp = 0; + hdata->hd.rb.rbp = 0; + hdata->hd.rb.len = 0; + ) +} + /* * Kludge alert - the SCSI code calls the abort and reset method with int * arguments not with pointers. So this is going to blow up beautyfully diff -Naurp linux-2.6.14.5.orig/drivers/scsi/wd33c93.c linux-2.6.14.5/drivers/scsi/wd33c93.c --- linux-2.6.14.5.orig/drivers/scsi/wd33c93.c 2005-10-27 20:02:08.000000000 -0400 +++ linux-2.6.14.5/drivers/scsi/wd33c93.c 2006-01-01 03:27:09.000000000 -0500 @@ -1460,7 +1460,7 @@ reset_wd33c93(struct Scsi_Host *instance const wd33c93_regs regs = hostdata->regs; uchar sr; -#ifdef CONFIG_SGI_IP22 +#if defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28) { int busycount = 0; extern void sgiwd93_reset(unsigned long); diff -Naurp linux-2.6.14.5.orig/drivers/serial/Kconfig linux-2.6.14.5/drivers/serial/Kconfig --- linux-2.6.14.5.orig/drivers/serial/Kconfig 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/drivers/serial/Kconfig 2006-01-01 03:27:09.000000000 -0500 @@ -555,16 +555,18 @@ config SERIAL_SUNSAB_CONSOLE config SERIAL_IP22_ZILOG tristate "IP22 Zilog8530 serial support" - depends on SGI_IP22 + depends on (SGI_IP22 || SGI_IP28) select SERIAL_CORE + default y if SGI_IP28 help - This driver supports the Zilog8530 serial ports found on SGI IP22 + This driver supports the Zilog8530 serial ports found on SGI IP22-IP28 systems. Say Y or M if you want to be able to these serial ports. config SERIAL_IP22_ZILOG_CONSOLE - bool "Console on IP22 Zilog8530 serial port" + bool "Console on IP22/IP28 Zilog8530 serial port" depends on SERIAL_IP22_ZILOG=y select SERIAL_CORE_CONSOLE + default y if SGI_IP28 config V850E_UART bool "NEC V850E on-chip UART support" diff -Naurp linux-2.6.14.5.orig/drivers/video/Kconfig linux-2.6.14.5/drivers/video/Kconfig --- linux-2.6.14.5.orig/drivers/video/Kconfig 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/drivers/video/Kconfig 2006-01-01 03:27:09.000000000 -0500 @@ -568,6 +568,13 @@ config FB_GBE_MEM This is the amount of memory reserved for the framebuffer, which can be any value between 1MB and 8MB. +config FB_IMPACT + tristate "SGI Indigo2 Impact graphics support" + depends on FB && (SGI_IP22 || SGI_IP26 || SGI_IP28) + select FB_SOFT_CURSOR + help + SGI Indigo2 Impact (SI/HI/MI) graphics card support. + config BUS_I2C bool depends on (FB = y) && VISWS diff -Naurp linux-2.6.14.5.orig/drivers/video/Makefile linux-2.6.14.5/drivers/video/Makefile --- linux-2.6.14.5.orig/drivers/video/Makefile 2006-01-01 03:05:07.000000000 -0500 +++ linux-2.6.14.5/drivers/video/Makefile 2006-01-01 03:27:09.000000000 -0500 @@ -97,6 +97,7 @@ obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxf obj-$(CONFIG_FB_IMX) += imxfb.o obj-$(CONFIG_FB_SMIVGX) += smivgxfb.o obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o +obj-$(CONFIG_FB_IMPACT) += impact.o # Platform or fallback drivers go here obj-$(CONFIG_FB_VESA) += vesafb.o diff -Naurp linux-2.6.14.5.orig/drivers/video/impact.c linux-2.6.14.5/drivers/video/impact.c --- linux-2.6.14.5.orig/drivers/video/impact.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.6.14.5/drivers/video/impact.c 2006-01-01 03:27:09.000000000 -0500 @@ -0,0 +1,1018 @@ +/* + * linux/drivers/video/impactsr.c -- SGI Octane MardiGras (IMPACTSR) graphics + * linux/drivers/video/impact.c -- SGI Indigo2 MardiGras (IMPACT) graphics + * + * Copyright (c) 2004 by Stanislaw Skowronek + * Adapted to Indigo2 by pf, 2005 + * + * Based on linux/drivers/video/skeletonfb.c + * + * This driver, as most of the IP30 (SGI Octane) port, is a result of massive + * amounts of reverse engineering and trial-and-error. If anyone is interested + * in helping with it, please contact me: . + * + * The basic functions of this driver are filling and blitting rectangles. + * To achieve the latter, two DMA operations are used on Impact. It is unclear + * to me, why is it so, but even Xsgi (the IRIX X11 server) does it this way. + * It seems that fb->fb operations are not operational on these cards. + * + * For this purpose, a kernel DMA pool is allocated (pool number 0). This pool + * is (by default) 64kB in size. An ioctl could be used to set the value at + * run-time. Applications can use this pool, however proper locking has to be + * guaranteed. Kernel should be locked out from this pool by an ioctl. + * + * The IMPACTSR is quite well worked-out currently, except for the Geometry + * Engines (GE11). Any information about use of those devices would be very + * useful. It would enable a Linux OpenGL driver, as most of OpenGL calls are + * supported directly by the hardware. So far, I can't initialize the GE11. + * Verification of microcode crashes the graphics. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include