summaryrefslogtreecommitdiffstats
path: root/arch/alpha
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-10-09 00:00:47 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-10-09 00:00:47 +0000
commitd6434e1042f3b0a6dfe1b1f615af369486f9b1fa (patch)
treee2be02f33984c48ec019c654051d27964e42c441 /arch/alpha
parent609d1e803baf519487233b765eb487f9ec227a18 (diff)
Merge with 2.3.19.
Diffstat (limited to 'arch/alpha')
-rw-r--r--arch/alpha/Makefile6
-rw-r--r--arch/alpha/config.in17
-rw-r--r--arch/alpha/defconfig114
-rw-r--r--arch/alpha/kernel/Makefile26
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c13
-rw-r--r--arch/alpha/kernel/bios32.c1355
-rw-r--r--arch/alpha/kernel/core_apecs.c325
-rw-r--r--arch/alpha/kernel/core_cia.c589
-rw-r--r--arch/alpha/kernel/core_lca.c232
-rw-r--r--arch/alpha/kernel/core_mcpcia.c621
-rw-r--r--arch/alpha/kernel/core_polaris.c180
-rw-r--r--arch/alpha/kernel/core_pyxis.c407
-rw-r--r--arch/alpha/kernel/core_t2.c403
-rw-r--r--arch/alpha/kernel/core_tsunami.c318
-rw-r--r--arch/alpha/kernel/entry.S24
-rw-r--r--arch/alpha/kernel/es1888.c2
-rw-r--r--arch/alpha/kernel/head.S18
-rw-r--r--arch/alpha/kernel/irq.c195
-rw-r--r--arch/alpha/kernel/irq_impl.h (renamed from arch/alpha/kernel/irq.h)18
-rw-r--r--arch/alpha/kernel/machvec_impl.h (renamed from arch/alpha/kernel/machvec.h)98
-rw-r--r--arch/alpha/kernel/ns87312.c38
-rw-r--r--arch/alpha/kernel/osf_sys.c16
-rw-r--r--arch/alpha/kernel/pci.c226
-rw-r--r--arch/alpha/kernel/pci_impl.h (renamed from arch/alpha/kernel/bios32.h)77
-rw-r--r--arch/alpha/kernel/process.c42
-rw-r--r--arch/alpha/kernel/proto.h157
-rw-r--r--arch/alpha/kernel/ptrace.c31
-rw-r--r--arch/alpha/kernel/semaphore.c129
-rw-r--r--arch/alpha/kernel/setup.c72
-rw-r--r--arch/alpha/kernel/signal.c6
-rw-r--r--arch/alpha/kernel/smp.c117
-rw-r--r--arch/alpha/kernel/sys_alcor.c38
-rw-r--r--arch/alpha/kernel/sys_cabriolet.c104
-rw-r--r--arch/alpha/kernel/sys_dp264.c112
-rw-r--r--arch/alpha/kernel/sys_eb64p.c41
-rw-r--r--arch/alpha/kernel/sys_jensen.c15
-rw-r--r--arch/alpha/kernel/sys_miata.c53
-rw-r--r--arch/alpha/kernel/sys_mikasa.c144
-rw-r--r--arch/alpha/kernel/sys_noritake.c59
-rw-r--r--arch/alpha/kernel/sys_rawhide.c55
-rw-r--r--arch/alpha/kernel/sys_ruffian.c57
-rw-r--r--arch/alpha/kernel/sys_rx164.c45
-rw-r--r--arch/alpha/kernel/sys_sable.c37
-rw-r--r--arch/alpha/kernel/sys_sio.c213
-rw-r--r--arch/alpha/kernel/sys_sx164.c27
-rw-r--r--arch/alpha/kernel/sys_takara.c37
-rw-r--r--arch/alpha/kernel/time.c12
-rw-r--r--arch/alpha/kernel/traps.c16
-rw-r--r--arch/alpha/lib/Makefile2
-rw-r--r--arch/alpha/lib/io.c91
-rw-r--r--arch/alpha/lib/memchr.S164
-rw-r--r--arch/alpha/math-emu/fp-emul.c4
-rw-r--r--arch/alpha/math-emu/ieee-math.c21
-rw-r--r--arch/alpha/math-emu/ieee-math.h2
-rw-r--r--arch/alpha/mm/fault.c62
-rw-r--r--arch/alpha/mm/init.c22
-rw-r--r--arch/alpha/vmlinux.lds45
57 files changed, 2849 insertions, 4501 deletions
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index d48c8e09f..90013b3fb 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -59,10 +59,10 @@ ifeq ($(have_mcpu),y)
endif
# For TSUNAMI, we must have the assembler not emulate our instructions.
-# The same is true for POLARIS.
+# The same is true for POLARIS, and now PYXIS.
# BWX is most important, but we don't really want any emulation ever.
ifeq ($(old_gas),y)
- ifneq ($(CONFIG_ALPHA_GENERIC)$(CONFIG_ALPHA_TSUNAMI)$(CONFIG_ALPHA_POLARIS),)
+ ifneq ($(CONFIG_ALPHA_GENERIC)$(CONFIG_ALPHA_TSUNAMI)$(CONFIG_ALPHA_POLARIS)$(CONFIG_ALPHA_PYXIS),)
# How do we do #error in make?
CFLAGS := --error-please-upgrade-your-assembler
endif
@@ -71,7 +71,7 @@ else
CFLAGS := $(CFLAGS) -Wa,-mev6
endif
ifeq ($(CONFIG_ALPHA_PYXIS),y)
- CFLAGS := $(CFLAGS) -Wa,-m21164a -DBWIO_ENABLED
+ CFLAGS := $(CFLAGS) -Wa,-m21164a
endif
ifeq ($(CONFIG_ALPHA_POLARIS),y)
CFLAGS := $(CFLAGS) -Wa,-m21164pc
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index eb9752970..7cb20bee3 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -150,11 +150,6 @@ if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
-o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" ]
then
bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- if [ "$CONFIG_ALPHA_SRM" = "y" ]; then
- bool ' Use SRM PCI setup' CONFIG_ALPHA_SRM_SETUP
- fi
- fi
fi
if [ "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" \
@@ -173,13 +168,6 @@ then
bool 'Symmetric multi-processing support' CONFIG_SMP
fi
-if [ "$CONFIG_PCI" = "y" ]; then
- bool 'PCI quirks' CONFIG_PCI_QUIRKS
- if [ "$CONFIG_PCI_QUIRKS" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool 'PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
- fi
- bool 'Backward-compatible /proc/pci' CONFIG_PCI_OLD_PROC
-fi
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
@@ -188,7 +176,7 @@ tristate 'Kernel support for a.out (ECOFF) binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
tristate 'Kernel support for Linux/Intel ELF binaries' CONFIG_BINFMT_EM86
-source drivers/misc/Config.in
+source drivers/parport/Config.in
endmenu
source drivers/pnp/Config.in
@@ -216,6 +204,9 @@ if [ "$CONFIG_NET" = "y" ]; then
bool 'Network device support' CONFIG_NETDEVICES
if [ "$CONFIG_NETDEVICES" = "y" ]; then
source drivers/net/Config.in
+ if [ "$CONFIG_ATM" = "y" ]; then
+ source drivers/atm/Config.in
+ fi
fi
endmenu
fi
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig
index c557d66ec..186505eda 100644
--- a/arch/alpha/defconfig
+++ b/arch/alpha/defconfig
@@ -17,7 +17,6 @@ CONFIG_MODULES=y
#
# General setup
#
-CONFIG_NATIVE=y
CONFIG_ALPHA_GENERIC=y
# CONFIG_ALPHA_ALCOR is not set
# CONFIG_ALPHA_XL is not set
@@ -39,14 +38,12 @@ CONFIG_ALPHA_GENERIC=y
# CONFIG_ALPHA_P2K is not set
# CONFIG_ALPHA_RAWHIDE is not set
# CONFIG_ALPHA_RUFFIAN is not set
+# CONFIG_ALPHA_RX164 is not set
# CONFIG_ALPHA_SX164 is not set
# CONFIG_ALPHA_SABLE is not set
# CONFIG_ALPHA_TAKARA is not set
-# CONFIG_SMP is not set
CONFIG_PCI=y
-CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y
-# CONFIG_PCI_QUIRKS is not set
-CONFIG_PCI_OLD_PROC=y
+# CONFIG_SMP is not set
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
@@ -58,9 +55,10 @@ CONFIG_BINFMT_EM86=y
# CONFIG_PARPORT is not set
#
-# Plug and Play support
+# Plug and Play configuration
#
# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
#
# Block devices
@@ -72,6 +70,7 @@ CONFIG_BLK_DEV_FD=y
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
#
# Additional Block Devices
@@ -83,6 +82,7 @@ CONFIG_BLK_DEV_FD=y
# CONFIG_BLK_DEV_XD is not set
CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
#
@@ -90,7 +90,7 @@ CONFIG_PARIDE_PARPORT=y
#
# CONFIG_PACKET is not set
# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
+# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
@@ -106,8 +106,6 @@ CONFIG_INET=y
#
# (it is safe to leave these untouched)
#
-# CONFIG_INET_RARP is not set
-CONFIG_IP_NOSR=y
CONFIG_SKB_LARGE=y
#
@@ -141,6 +139,7 @@ CONFIG_SCSI_CONSTANTS=y
# SCSI low-level drivers
#
# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
@@ -148,23 +147,29 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_DMA is not set
# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
CONFIG_SCSI_QLOGIC_ISP=y
+# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_SEAGATE is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
@@ -175,9 +180,18 @@ CONFIG_SCSI_QLOGIC_ISP=y
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
# CONFIG_ARCNET is not set
CONFIG_DUMMY=m
# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -194,14 +208,26 @@ CONFIG_DE4X5=y
# CONFIG_EEXPRESS_PRO100 is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
-# CONFIG_DLCI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_RADIO is not set
+
+#
+# Token ring devices
+#
# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
# CONFIG_HOSTESS_SV11 is not set
+# CONFIG_COSA is not set
+# CONFIG_SEALEVEL_4021 is not set
+# CONFIG_DLCI is not set
# CONFIG_WAN_DRIVERS is not set
# CONFIG_LAPBETHER is not set
# CONFIG_X25_ASY is not set
@@ -217,7 +243,7 @@ CONFIG_DE4X5=y
# CONFIG_ISDN is not set
#
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+# Old CD-ROM drivers (not SCSI, not IDE)
#
# CONFIG_CD_NO_IDESCSI is not set
@@ -232,20 +258,30 @@ CONFIG_SERIAL=y
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
-CONFIG_MOUSE=y
-# CONFIG_ATIXL_BUSMOUSE is not set
+
+#
+# Mice
+#
# CONFIG_BUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
-# CONFIG_UMISC is not set
# CONFIG_QIC02_TAPE is not set
# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
# CONFIG_VIDEO_DEV is not set
-# CONFIG_NVRAM is not set
+
+#
+# Joystick support
+#
# CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
#
# Ftape, the floppy tape device driver
@@ -256,31 +292,43 @@ CONFIG_PSMOUSE=y
# Filesystems
#
# CONFIG_QUOTA is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
CONFIG_NFS_FS=y
-# CONFIG_NFSD is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
-# CONFIG_CODA_FS is not set
# CONFIG_SMB_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_UFS_FS is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_MAC_PARTITION is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_OSF_PARTITION=y
+# CONFIG_SMD_DISKLABEL is not set
+# CONFIG_SGI_DISKLABEL is not set
# CONFIG_NLS is not set
#
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index 4032c8c0e..282147e72 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -16,7 +16,7 @@ all: kernel.o head.o
O_TARGET := kernel.o
O_OBJS := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \
- bios32.o ptrace.o time.o fpreg.o
+ ptrace.o time.o fpreg.o semaphore.o
OX_OBJS := alpha_ksyms.o
@@ -28,9 +28,13 @@ O_OBJS += core_apecs.o core_cia.o core_lca.o core_mcpcia.o core_pyxis.o \
sys_jensen.o sys_miata.o sys_mikasa.o sys_noritake.o \
sys_rawhide.o sys_ruffian.o sys_sable.o sys_sio.o \
sys_sx164.o sys_takara.o sys_rx164.o \
- es1888.o smc37c669.o smc37c93x.o
+ es1888.o smc37c669.o smc37c93x.o ns87312.o pci.o
else
+ifdef CONFIG_PCI
+O_OBJS += pci.o
+endif
+
# Core logic support
ifdef CONFIG_ALPHA_APECS
O_OBJS += core_apecs.o
@@ -62,10 +66,10 @@ ifneq ($(CONFIG_ALPHA_ALCOR)$(CONFIG_ALPHA_XLT),)
O_OBJS += sys_alcor.o
endif
ifneq ($(CONFIG_ALPHA_CABRIOLET)$(CONFIG_ALPHA_EB164)$(CONFIG_ALPHA_EB66P)$(CONFIG_ALPHA_LX164)$(CONFIG_ALPHA_PC164),)
-O_OBJS += sys_cabriolet.o
+O_OBJS += sys_cabriolet.o ns87312.o
endif
ifdef CONFIG_ALPHA_DP264
-O_OBJS += sys_dp264.o
+O_OBJS += sys_dp264.o es1888.o smc37c669.o
endif
ifneq ($(CONFIG_ALPHA_EB64P)$(CONFIG_ALPHA_EB66),)
O_OBJS += sys_eb64p.o
@@ -74,7 +78,7 @@ ifdef CONFIG_ALPHA_JENSEN
O_OBJS += sys_jensen.o
endif
ifdef CONFIG_ALPHA_MIATA
-O_OBJS += sys_miata.o
+O_OBJS += sys_miata.o es1888.o smc37c669.o
endif
ifdef CONFIG_ALPHA_MIKASA
O_OBJS += sys_mikasa.o
@@ -95,22 +99,16 @@ ifdef CONFIG_ALPHA_SABLE
O_OBJS += sys_sable.o
endif
ifneq ($(CONFIG_ALPHA_BOOK1)$(CONFIG_ALPHA_AVANTI)$(CONFIG_ALPHA_NONAME)$(CONFIG_ALPHA_P2K)$(CONFIG_ALPHA_XL),)
-O_OBJS += sys_sio.o
+O_OBJS += sys_sio.o ns87312.o
endif
ifdef CONFIG_ALPHA_SX164
-O_OBJS += sys_sx164.o
+O_OBJS += sys_sx164.o smc37c669.o
endif
ifdef CONFIG_ALPHA_TAKARA
-O_OBJS += sys_takara.o
+O_OBJS += sys_takara.o ns87312.o
endif
# Device support
-ifdef CONFIG_ALPHA_MIATA
-O_OBJS += es1888.o
-endif
-ifneq ($(CONFIG_ALPHA_SX164)$(CONFIG_ALPHA_MIATA)$(CONFIG_ALPHA_DP264),)
-O_OBJS += smc37c669.o
-endif
ifneq ($(CONFIG_ALPHA_PC164)$(CONFIG_ALPHA_LX164),)
O_OBJS += smc37c93x.o
endif
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index cba493d09..d8e1082d8 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -36,6 +36,7 @@
extern struct hwrpb_struct *hwrpb;
extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
+extern void ___delay(void);
/* these are C runtime functions with special calling conventions: */
extern void __divl (void);
@@ -48,8 +49,6 @@ extern void __divqu (void);
extern void __remqu (void);
EXPORT_SYMBOL(alpha_mv);
-EXPORT_SYMBOL(local_bh_count);
-EXPORT_SYMBOL(local_irq_count);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(disable_irq_nosync);
@@ -107,7 +106,7 @@ EXPORT_SYMBOL(alpha_read_fp_reg);
EXPORT_SYMBOL(alpha_write_fp_reg);
/* In-kernel system calls. */
-EXPORT_SYMBOL(__kernel_thread);
+EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(sys_open);
EXPORT_SYMBOL(sys_dup);
EXPORT_SYMBOL(sys_exit);
@@ -149,6 +148,11 @@ EXPORT_SYMBOL_NOVERS(__down_failed);
EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
EXPORT_SYMBOL_NOVERS(__up_wakeup);
+/*
+ * This is called specially from __delay.
+ */
+EXPORT_SYMBOL_NOVERS(___delay);
+
/*
* SMP-specific symbols.
*/
@@ -178,6 +182,9 @@ EXPORT_SYMBOL(debug_spin_trylock);
EXPORT_SYMBOL(write_lock);
EXPORT_SYMBOL(read_lock);
#endif
+#else /* __SMP__ */
+EXPORT_SYMBOL(__local_bh_count);
+EXPORT_SYMBOL(__local_irq_count);
#endif /* __SMP__ */
/*
diff --git a/arch/alpha/kernel/bios32.c b/arch/alpha/kernel/bios32.c
deleted file mode 100644
index 1c7823397..000000000
--- a/arch/alpha/kernel/bios32.c
+++ /dev/null
@@ -1,1355 +0,0 @@
-/*
- * bios32.c - PCI BIOS functions for Alpha systems not using BIOS
- * emulation code.
- *
- * Written by Dave Rusling (david.rusling@reo.mts.dec.com)
- *
- * Adapted to 64-bit kernel and then rewritten by David Mosberger
- * (davidm@cs.arizona.edu)
- *
- * For more information, please consult
- *
- * PCI BIOS Specification Revision
- * PCI Local Bus Specification
- * PCI System Design Guide
- *
- * PCI Special Interest Group
- * M/S HF3-15A
- * 5200 N.E. Elam Young Parkway
- * Hillsboro, Oregon 97124-6497
- * +1 (503) 696-2000
- * +1 (800) 433-5177
- *
- * Manuals are $25 each or $50 for all three, plus $7 shipping
- * within the United States, $35 abroad.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/tasks.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <asm/pci.h>
-#include <asm/dma.h>
-
-#include "proto.h"
-#include "bios32.h"
-
-#define DEBUG_DEVS 0
-#define DEBUG_HOSE 0
-
-#if DEBUG_DEVS
-# define DBG_DEVS(args) printk args
-#else
-# define DBG_DEVS(args)
-#endif
-
-#if DEBUG_HOSE
-# define DBG_HOSE(args) printk args
-#else
-# define DBG_HOSE(args)
-#endif
-
-#ifndef CONFIG_PCI
-
-asmlinkage int sys_pciconfig_read() { return -ENOSYS; }
-asmlinkage int sys_pciconfig_write() { return -ENOSYS; }
-void reset_for_srm(void) { }
-
-#else /* CONFIG_PCI */
-
-#include <linux/malloc.h>
-#include <linux/mm.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/segment.h>
-#include <asm/system.h>
-
-/*
- * PCI public interfaces.
- */
-
-#define MAJOR_REV 0
-#define MINOR_REV 4 /* minor revision 4, add multi-PCI handling */
-
-struct linux_hose_info *bus2hose[256];
-struct linux_hose_info *hose_head, **hose_tail = &hose_head;
-int hose_count;
-int pci_probe_enabled;
-
-static void layout_hoses(void);
-
-int
-pcibios_present(void)
-{
- return alpha_mv.hose_read_config_byte != NULL;
-}
-
-void __init
-pcibios_init(void)
-{
- if (!pcibios_present())
- return;
-
- printk("Alpha PCI BIOS32 revision %d.%02d\n", MAJOR_REV, MINOR_REV);
- if (alpha_use_srm_setup)
- printk(" NOT modifying existing (SRM) PCI configuration\n");
-}
-
-char * __init
-pcibios_setup(char *str)
-{
- return str;
-}
-
-void __init
-pcibios_fixup(void)
-{
- alpha_mv.pci_fixup();
-}
-
-void __init
-pcibios_fixup_bus(struct pci_bus *bus)
-{
-}
-
-int
-pcibios_read_config_byte (u8 bus, u8 dev, u8 where, u8 *value)
-{
- int r = PCIBIOS_FUNC_NOT_SUPPORTED;
- *value = 0xff;
- if (alpha_mv.hose_read_config_byte) {
- r = (alpha_mv.hose_read_config_byte
- (bus, dev, where, value, bus2hose[bus]));
- }
- return r;
-}
-
-int
-pcibios_read_config_word (u8 bus, u8 dev, u8 where, u16 *value)
-{
- int r = PCIBIOS_FUNC_NOT_SUPPORTED;
- *value = 0xffff;
- if (alpha_mv.hose_read_config_word) {
- r = PCIBIOS_BAD_REGISTER_NUMBER;
- if (!(where & 1))
- r = (alpha_mv.hose_read_config_word
- (bus, dev, where, value, bus2hose[bus]));
- }
- return r;
-}
-
-int
-pcibios_read_config_dword (u8 bus, u8 dev, u8 where, u32 *value)
-{
- int r = PCIBIOS_FUNC_NOT_SUPPORTED;
- *value = 0xffffffff;
- if (alpha_mv.hose_read_config_dword) {
- r = PCIBIOS_BAD_REGISTER_NUMBER;
- if (!(where & 3))
- r = (alpha_mv.hose_read_config_dword
- (bus, dev, where, value, bus2hose[bus]));
- }
- return r;
-}
-
-int
-pcibios_write_config_byte (u8 bus, u8 dev, u8 where, u8 value)
-{
- int r = PCIBIOS_FUNC_NOT_SUPPORTED;
- if (alpha_mv.hose_write_config_byte) {
- r = (alpha_mv.hose_write_config_byte
- (bus, dev, where, value, bus2hose[bus]));
- }
- return r;
-}
-
-int
-pcibios_write_config_word (u8 bus, u8 dev, u8 where, u16 value)
-{
- int r = PCIBIOS_FUNC_NOT_SUPPORTED;
- if (alpha_mv.hose_write_config_word) {
- r = PCIBIOS_BAD_REGISTER_NUMBER;
- if (!(where & 1))
- r = (alpha_mv.hose_write_config_word
- (bus, dev, where, value, bus2hose[bus]));
- }
- return r;
-}
-
-int
-pcibios_write_config_dword (u8 bus, u8 dev, u8 where, u32 value)
-{
- int r = PCIBIOS_FUNC_NOT_SUPPORTED;
- if (alpha_mv.hose_write_config_dword) {
- r = PCIBIOS_BAD_REGISTER_NUMBER;
- if (!(where & 3))
- r = (alpha_mv.hose_write_config_dword
- (bus, dev, where, value, bus2hose[bus]));
- }
- return r;
-}
-
-asmlinkage int
-sys_pciconfig_read(unsigned long bus, unsigned long dfn,
- unsigned long off, unsigned long len,
- unsigned char *buf)
-{
- unsigned char ubyte;
- unsigned short ushort;
- unsigned int uint;
- long err = 0;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (!pcibios_present())
- return -ENOSYS;
-
- switch (len) {
- case 1:
- err = pcibios_read_config_byte(bus, dfn, off, &ubyte);
- put_user(ubyte, buf);
- break;
- case 2:
- err = pcibios_read_config_word(bus, dfn, off, &ushort);
- put_user(ushort, (unsigned short *)buf);
- break;
- case 4:
- err = pcibios_read_config_dword(bus, dfn, off, &uint);
- put_user(uint, (unsigned int *)buf);
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-asmlinkage int
-sys_pciconfig_write(unsigned long bus, unsigned long dfn,
- unsigned long off, unsigned long len,
- unsigned char *buf)
-{
- unsigned char ubyte;
- unsigned short ushort;
- unsigned int uint;
- long err = 0;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (!pcibios_present())
- return -ENOSYS;
-
- switch (len) {
- case 1:
- err = get_user(ubyte, buf);
- if (err)
- break;
- err = pcibios_write_config_byte(bus, dfn, off, ubyte);
- if (err != PCIBIOS_SUCCESSFUL) {
- err = -EFAULT;
- }
- break;
- case 2:
- err = get_user(ushort, (unsigned short *)buf);
- if (err)
- break;
- err = pcibios_write_config_word(bus, dfn, off, ushort);
- if (err != PCIBIOS_SUCCESSFUL) {
- err = -EFAULT;
- }
- break;
- case 4:
- err = get_user(uint, (unsigned int *)buf);
- if (err)
- break;
- err = pcibios_write_config_dword(bus, dfn, off, uint);
- if (err != PCIBIOS_SUCCESSFUL) {
- err = -EFAULT;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-
-/*
- * Gory details start here...
- */
-
-/*
- * Align VAL to ALIGN, which must be a power of two.
- */
-#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
-
-
-/*
- * The following structure records initial configuration of devices
- * so that we can reset them on shutdown and so enable clean reboots
- * on SRM. It is more trouble than it iw worth to conditionalize this.
- */
-
-struct srm_irq_reset {
- struct srm_irq_reset *next;
- struct pci_dev *dev;
- u8 irq;
-} *srm_irq_resets;
-
-struct srm_io_reset {
- struct srm_io_reset *next;
- struct pci_dev *dev;
- u32 io;
- u8 reg;
-} *srm_io_resets;
-
-/* Apply the collected reset modifications. */
-
-void
-reset_for_srm(void)
-{
- struct srm_irq_reset *qreset;
- struct srm_io_reset *ireset;
-
- /* Reset any IRQs that we changed. */
- for (qreset = srm_irq_resets; qreset ; qreset = qreset->next) {
- pcibios_write_config_byte(qreset->dev->bus->number,
- qreset->dev->devfn,
- PCI_INTERRUPT_LINE,
- qreset->irq);
-#if 1
- printk("reset_for_srm: bus %d slot 0x%x "
- "SRM IRQ 0x%x changed back from 0x%x\n",
- qreset->dev->bus->number,
- PCI_SLOT(qreset->dev->devfn),
- qreset->irq, qreset->dev->irq);
-#endif
- }
-
- /* Reset any IO addresses that we changed. */
- for (ireset = srm_io_resets; ireset ; ireset = ireset->next) {
- pcibios_write_config_dword(ireset->dev->bus->number,
- ireset->dev->devfn,
- ireset->reg, ireset->io);
-#if 1
- printk("reset_for_srm: bus %d slot 0x%x "
- "SRM MEM/IO restored to 0x%x\n",
- ireset->dev->bus->number,
- PCI_SLOT(ireset->dev->devfn),
- ireset->io);
-#endif
- }
-}
-
-static void
-new_irq_reset(struct pci_dev *dev, u8 irq)
-{
- struct srm_irq_reset *n;
- n = kmalloc(sizeof(*n), GFP_KERNEL);
-
- n->next = srm_irq_resets;
- n->dev = dev;
- n->irq = irq;
- srm_irq_resets = n;
-}
-
-static void
-new_io_reset(struct pci_dev *dev, u8 reg, u32 io)
-{
- struct srm_io_reset *n;
- n = kmalloc(sizeof(*n), GFP_KERNEL);
-
- n->next = srm_io_resets;
- n->dev = dev;
- n->reg = reg;
- n->io = io;
- srm_io_resets = n;
-}
-
-
-/*
- * Disable PCI device DEV so that it does not respond to I/O or memory
- * accesses.
- */
-static void __init
-disable_dev(struct pci_dev *dev)
-{
- struct pci_bus *bus;
- unsigned short cmd;
-
- /*
- * HACK: the PCI-to-EISA bridge does not seem to identify
- * itself as a bridge... :-(
- */
- if (dev->vendor == PCI_VENDOR_ID_INTEL &&
- dev->device == PCI_DEVICE_ID_INTEL_82375) {
- dev->class = PCI_CLASS_BRIDGE_EISA;
- DBG_DEVS(("disable_dev: ignoring PCEB...\n"));
- return;
- }
-
- if (dev->vendor == PCI_VENDOR_ID_INTEL &&
- dev->device == PCI_DEVICE_ID_INTEL_82378) {
- dev->class = PCI_CLASS_BRIDGE_ISA;
- DBG_DEVS(("disable_dev: ignoring SIO...\n"));
- return;
- }
-
- /*
- * We don't have code that will init the CYPRESS bridge correctly
- * so we do the next best thing, and depend on the previous
- * console code to do the right thing, and ignore it here... :-\
- */
- if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
- dev->device == PCI_DEVICE_ID_CONTAQ_82C693) {
- DBG_DEVS(("disable_dev: ignoring CYPRESS bridge...\n"));
- return;
- }
-
-#if DEBUG_DEVS && 0
- /* Worse HACK: Don't disable the video card, so I can see where
- it is *really* falling over. */
- if (dev->class >> 16 == PCI_BASE_CLASS_DISPLAY) {
- DBG_DEVS(("disable_dev: ignoring video card %04x:%04x\n",
- dev->vendor, dev->device));
- return;
- }
-#endif
-
- DBG_DEVS(("disable_dev: disabling %04x:%04x\n",
- dev->vendor, dev->device));
-
- bus = dev->bus;
- pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
-
- /* hack, turn it off first... */
- cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER);
- pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND, cmd);
-}
-
-
-/*
- * Layout memory and I/O for a device:
- */
-#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))
-
-static unsigned int io_base;
-static unsigned int mem_base;
-
-static void __init
-layout_dev(struct pci_dev *dev)
-{
- struct pci_bus *bus;
- unsigned short cmd;
- unsigned int base, mask, size, off, idx;
- unsigned int orig_base;
- unsigned int alignto;
- unsigned long handle;
-
- /*
- * HACK: the PCI-to-EISA bridge does not seem to identify
- * itself as a bridge... :-(
- */
- if (dev->vendor == PCI_VENDOR_ID_INTEL &&
- dev->device == PCI_DEVICE_ID_INTEL_82375) {
- dev->class = PCI_CLASS_BRIDGE_EISA;
- DBG_DEVS(("layout_dev: ignoring PCEB...\n"));
- return;
- }
-
- if (dev->vendor == PCI_VENDOR_ID_INTEL &&
- dev->device == PCI_DEVICE_ID_INTEL_82378) {
- dev->class = PCI_CLASS_BRIDGE_ISA;
- DBG_DEVS(("layout_dev: ignoring SIO...\n"));
- return;
- }
-
- /*
- * We don't have code that will init the CYPRESS bridge correctly
- * so we do the next best thing, and depend on the previous
- * console code to do the right thing, and ignore it here... :-\
- */
- if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
- dev->device == PCI_DEVICE_ID_CONTAQ_82C693) {
- DBG_DEVS(("layout_dev: ignoring CYPRESS bridge...\n"));
- return;
- }
-
- bus = dev->bus;
- pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
-
- for (idx = 0; idx <= 5; idx++) {
- off = PCI_BASE_ADDRESS_0 + 4*idx;
- /*
- * Figure out how much space and of what type this
- * device wants.
- */
- pcibios_read_config_dword(bus->number, dev->devfn, off,
- &orig_base);
- pcibios_write_config_dword(bus->number, dev->devfn, off,
- 0xffffffff);
- pcibios_read_config_dword(bus->number, dev->devfn, off, &base);
- if (!base) {
- /* this base-address register is unused */
- dev->base_address[idx] = 0;
- continue;
- }
-
- DBG_DEVS(("layout_dev: slot %d fn %d off 0x%x base 0x%x\n",
- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
- off, base));
-
- /*
- * We've read the base address register back after
- * writing all ones and so now we must decode it.
- */
- if (base & PCI_BASE_ADDRESS_SPACE_IO) {
- /*
- * I/O space base address register.
- */
- cmd |= PCI_COMMAND_IO;
-
- base &= PCI_BASE_ADDRESS_IO_MASK;
- mask = (~base << 1) | 0x1;
- size = (mask & base) & 0xffffffff;
- /*
- * Aligning to 0x800 rather than the minimum base of
- * 0x400 is an attempt to avoid having devices in
- * any 0x?C?? range, which is where the de4x5 driver
- * probes for EISA cards.
- *
- * Adaptecs, especially, resent such intrusions.
- */
- alignto = MAX(0x800, size);
- base = ALIGN(io_base, alignto);
- io_base = base + size;
-
- pcibios_write_config_dword(bus->number, dev->devfn,
- off, base | 0x1);
- new_io_reset(dev, off, orig_base);
-
- handle = PCI_HANDLE(bus->number) | base | 1;
- dev->base_address[idx] = handle;
-
- DBG_DEVS(("layout_dev: dev 0x%x IO @ 0x%lx (0x%x)\n",
- dev->device, handle, size));
- } else {
- unsigned int type;
- /*
- * Memory space base address register.
- */
- cmd |= PCI_COMMAND_MEMORY;
- type = base & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
- base &= PCI_BASE_ADDRESS_MEM_MASK;
- mask = (~base << 1) | 0x1;
- size = (mask & base) & 0xffffffff;
- switch (type) {
- case PCI_BASE_ADDRESS_MEM_TYPE_32:
- case PCI_BASE_ADDRESS_MEM_TYPE_64:
- break;
-
- case PCI_BASE_ADDRESS_MEM_TYPE_1M:
- /*
- * Allocating memory below 1MB is *very*
- * tricky, as there may be all kinds of
- * ISA devices lurking that we don't know
- * about. For now, we just cross fingers
- * and hope nobody tries to do this on an
- * Alpha (or that the console has set it
- * up properly).
- */
- printk("bios32 WARNING: slot %d, function %d"
- " requests memory below 1MB---don't"
- " know how to do that.\n",
- PCI_SLOT(dev->devfn),
- PCI_FUNC(dev->devfn));
- continue;
- }
- /*
- * The following holds at least for the Low Cost
- * Alpha implementation of the PCI interface:
- *
- * In sparse memory address space, the first
- * octant (16MB) of every 128MB segment is
- * aliased to the very first 16 MB of the
- * address space (i.e., it aliases the ISA
- * memory address space). Thus, we try to
- * avoid allocating PCI devices in that range.
- * Can be allocated in 2nd-7th octant only.
- * Devices that need more than 112MB of
- * address space must be accessed through
- * dense memory space only!
- */
- /* align to multiple of size of minimum base */
- alignto = MAX(0x1000, size);
- base = ALIGN(mem_base, alignto);
- if (size > 7 * 16*MB) {
- printk("bios32 WARNING: slot %d, function %d"
- " requests 0x%x bytes of contiguous"
- " address space---don't use sparse"
- " memory accesses on this device!!\n",
- PCI_SLOT(dev->devfn),
- PCI_FUNC(dev->devfn), size);
- } else {
- if (((base / (16*MB)) & 0x7) == 0) {
- base &= ~(128*MB - 1);
- base += 16*MB;
- base = ALIGN(base, alignto);
- }
- if (base/(128*MB) != (base + size)/(128*MB)) {
- base &= ~(128*MB - 1);
- base += (128 + 16)*MB;
- base = ALIGN(base, alignto);
- }
- }
- mem_base = base + size;
-
- pcibios_write_config_dword(bus->number, dev->devfn,
- off, base);
- new_io_reset(dev, off, orig_base);
-
- handle = PCI_HANDLE(bus->number) | base;
- dev->base_address[idx] = handle;
-
- /*
- * Currently for 64-bit cards, we simply do the usual
- * for setup of the first register (low) of the pair,
- * and then clear out the second (high) register, as
- * we are not yet able to do 64-bit addresses, and
- * setting the high register to 0 allows 32-bit SAC
- * addresses to be used.
- */
- if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
- unsigned int orig_base2;
- pcibios_read_config_dword(bus->number,
- dev->devfn,
- off+4, &orig_base2);
- if (0 != orig_base2) {
- pcibios_write_config_dword(bus->number,
- dev->devfn,
- off+4, 0);
- new_io_reset (dev, off+4, orig_base2);
- }
- /* Bypass hi reg in the loop. */
- dev->base_address[++idx] = 0;
-
- printk("bios32 WARNING: "
- "handling 64-bit device in "
- "slot %d, function %d: \n",
- PCI_SLOT(dev->devfn),
- PCI_FUNC(dev->devfn));
- }
-
- DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%lx (0x%x)\n",
- dev->device, handle, size));
- }
- }
-
- /* Enable device: */
- if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED ||
- dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA ||
- dev->class >> 8 == PCI_CLASS_STORAGE_IDE ||
- dev->class >> 16 == PCI_BASE_CLASS_DISPLAY)
- {
- /*
- * All of these (may) have I/O scattered all around
- * and may not use i/o-base address registers at all.
- * So we just have to always enable I/O to these
- * devices.
- */
- cmd |= PCI_COMMAND_IO;
- }
-
- pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND,
- cmd | PCI_COMMAND_MASTER);
-
- DBG_DEVS(("layout_dev: bus %d slot %d VID 0x%x DID 0x%x"
- " class 0x%x cmd 0 x%x\n",
- bus->number, PCI_SLOT(dev->devfn), dev->vendor,
- dev->device, dev->class, cmd|PCI_COMMAND_MASTER));
-}
-
-static int __init
-layout_bus(struct pci_bus *bus)
-{
- unsigned int l, tio, bio, tmem, bmem;
- struct pci_bus *child;
- struct pci_dev *dev;
- int found_vga = 0;
-
- DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
-
- if (!bus->devices && !bus->children)
- return 0;
-
- /*
- * Align the current bases on appropriate boundaries (4K for
- * IO and 1MB for memory).
- */
- bio = io_base = ALIGN(io_base, 4*KB);
- bmem = mem_base = ALIGN(mem_base, 1*MB);
-
- /*
- * There are times when the PCI devices have already been
- * setup (e.g., by MILO or SRM). In these cases there is a
- * window during which two devices may have an overlapping
- * address range. To avoid this causing trouble, we first
- * turn off the I/O and memory address decoders for all PCI
- * devices. They'll be re-enabled only once all address
- * decoders are programmed consistently.
- */
- DBG_DEVS(("layout_bus: disable_dev for bus %d\n", bus->number));
-
- for (dev = bus->devices; dev; dev = dev->sibling) {
- if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
- (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) {
- disable_dev(dev);
- }
- }
-
- /*
- * Allocate space to each device:
- */
- DBG_DEVS(("layout_bus: starting bus %d devices\n", bus->number));
-
- for (dev = bus->devices; dev; dev = dev->sibling) {
- if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
- (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) {
- layout_dev(dev);
- }
- if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
- found_vga = 1;
- }
- /*
- * Recursively allocate space for all of the sub-buses:
- */
- DBG_DEVS(("layout_bus: starting bus %d children\n", bus->number));
-
- for (child = bus->children; child; child = child->next) {
- found_vga += layout_bus(child);
- }
- /*
- * Align the current bases on 4K and 1MB boundaries:
- */
- tio = io_base = ALIGN(io_base, 4*KB);
- tmem = mem_base = ALIGN(mem_base, 1*MB);
-
- if (bus->self) {
- struct pci_dev *bridge = bus->self;
-
- DBG_DEVS(("layout_bus: config bus %d bridge\n", bus->number));
-
- /*
- * Set up the top and bottom of the PCI I/O segment
- * for this bus.
- */
- pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
- PCI_IO_BASE, &l);
- l &= 0xffff0000;
- l |= ((bio >> 8) & 0x00f0) | ((tio - 1) & 0xf000);
- pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
- PCI_IO_BASE, l);
-
- /*
- * Clear out the upper 16 bits of IO base/limit.
- * Clear out the upper 32 bits of PREF base/limit.
- */
- pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
- PCI_IO_BASE_UPPER16, 0);
- pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
- PCI_PREF_BASE_UPPER32, 0);
- pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
- PCI_PREF_LIMIT_UPPER32, 0);
-
- /*
- * Set up the top and bottom of the PCI Memory segment
- * for this bus.
- */
- l = ((bmem & 0xfff00000) >> 16) | ((tmem - 1) & 0xfff00000);
- pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
- PCI_MEMORY_BASE, l);
-
- /*
- * Turn off downstream PF memory address range, unless
- * there is a VGA behind this bridge, in which case, we
- * enable the PREFETCH range to include BIOS ROM at C0000.
- *
- * NOTE: this is a bit of a hack, done with PREFETCH for
- * simplicity, rather than having to add it into the above
- * non-PREFETCH range, which could then be bigger than we want.
- * We might assume that we could relocate the BIOS ROM, but
- * that would depend on having it found by those who need it
- * (the DEC BIOS emulator would find it, but I do not know
- * about the Xservers). So, we do it this way for now... ;-}
- */
- l = (found_vga) ? 0 : 0x0000ffff;
- pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
- PCI_PREF_MEMORY_BASE, l);
-
- /*
- * Tell bridge that there is an ISA bus in the system,
- * and (possibly) a VGA as well.
- */
- l = (found_vga) ? 0x0c : 0x04;
- pcibios_write_config_byte(bridge->bus->number, bridge->devfn,
- PCI_BRIDGE_CONTROL, l);
-
- /*
- * Clear status bits,
- * turn on I/O enable (for downstream I/O),
- * turn on memory enable (for downstream memory),
- * turn on master enable (for upstream memory and I/O).
- */
- pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
- PCI_COMMAND, 0xffff0007);
- }
- DBG_DEVS(("layout_bus: bus %d finished\n", bus->number));
- return found_vga;
-}
-
-void __init
-layout_all_busses(unsigned long default_io_base,
- unsigned long default_mem_base)
-{
- struct pci_bus *cur;
-
- layout_hoses();
-
- /*
- * Scan the tree, allocating PCI memory and I/O space.
- */
- /*
- * Sigh; check_region() will need changing to accept a PCI_HANDLE,
- * if we allocate I/O space addresses on a per-bus basis.
- * For now, make the I/O bases unique across all busses, so
- * that check_region() will not get confused... ;-}
- */
- io_base = default_io_base;
- for (cur = &pci_root; cur; cur = cur->next) {
- mem_base = default_mem_base;
- DBG_DEVS(("layout_all_busses: calling layout_bus()\n"));
- layout_bus(cur);
- }
- DBG_DEVS(("layout_all_busses: done.\n"));
-}
-
-
-/*
- * The SRM console *disables* the IDE interface, this code ensures it's
- * enabled.
- *
- * This code bangs on a control register of the 87312 Super I/O chip
- * that implements parallel port/serial ports/IDE/FDI. Depending on
- * the motherboard, the Super I/O chip can be configured through a
- * pair of registers that are located either at I/O ports 0x26e/0x26f
- * or 0x398/0x399. Unfortunately, autodetecting which base address is
- * in use works only once (right after a reset). The Super I/O chip
- * has the additional quirk that configuration register data must be
- * written twice (I believe this is a safety feature to prevent
- * accidental modification---fun, isn't it?).
- */
-
-void __init
-enable_ide(long ide_base)
-{
- int data;
- unsigned long flags;
-
- __save_and_cli(flags);
- outb(0, ide_base); /* set the index register for reg #0 */
- data = inb(ide_base+1); /* read the current contents */
- outb(0, ide_base); /* set the index register for reg #0 */
- outb(data | 0x40, ide_base+1); /* turn on IDE */
- outb(data | 0x40, ide_base+1); /* turn on IDE, really! */
- __restore_flags(flags);
-}
-
-/* Look for mis-configured devices' I/O space addresses behind bridges. */
-static void
-check_behind_io(struct pci_dev *dev)
-{
- struct pci_bus *bus = dev->bus;
- unsigned int reg, orig_base, new_base, found_one = 0;
-
- for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
- /* Read the current setting, check for I/O space and >= 64K */
- pcibios_read_config_dword(bus->number, dev->devfn,
- reg, &orig_base);
-
- if (!orig_base || !(orig_base & PCI_BASE_ADDRESS_SPACE_IO))
- continue; /* unused or non-IO */
-
- if (orig_base < 64*1024) {
-#if 1
-printk("check_behind_io: ALREADY OK! bus %d slot %d base 0x%x\n",
- bus->number, PCI_SLOT(dev->devfn), orig_base);
-#endif
- if (orig_base & ~1)
- continue; /* OK! */
- orig_base = 0x12001; /* HACK! FIXME!! */
- }
-
- /* HACK ALERT! for now, just subtract 32K from the
- original address, which should give us addresses
- in the range 0x8000 and up */
- new_base = orig_base - 0x8000;
-#if 1
-printk("check_behind_io: ALERT! bus %d slot %d old 0x%x new 0x%x\n",
- bus->number, PCI_SLOT(dev->devfn), orig_base, new_base);
-#endif
- pcibios_write_config_dword(bus->number, dev->devfn,
- reg, new_base);
-
- new_io_reset(dev, reg, orig_base);
- found_one++;
- }
-
- /* If any were modified, gotta hack the bridge IO limits too. */
- if (found_one) {
- if (bus->self) {
- struct pci_dev *bridge = bus->self;
- unsigned int l;
- /*
- * Set up the top and bottom of the PCI I/O segment
- * for this bus.
- */
- pcibios_read_config_dword(bridge->bus->number,
- bridge->devfn, 0x1c, &l);
-#if 1
-printk("check_behind_io: ALERT! bus %d slot %d oldLIM 0x%x\n",
- bus->number, PCI_SLOT(bridge->devfn), l);
-#endif
- l = (l & 0xffff0000U) | 0xf080U; /* give it ALL */
- pcibios_write_config_dword(bridge->bus->number,
- bridge->devfn, 0x1c, l);
- pcibios_write_config_dword(bridge->bus->number,
- bridge->devfn,
- 0x3c, 0x00040000);
- pcibios_write_config_dword(bridge->bus->number,
- bridge->devfn,
- 0x4, 0xffff0007);
- } else
- printk("check_behind_io: WARNING! bus->self NULL\n");
- }
-}
-
-
-/*
- * Most boards share most of the fixup code, which is isolated here.
- */
-
-void __init
-common_pci_fixup(int (*map_irq)(struct pci_dev *dev, int slot, int pin),
- int (*swizzle)(struct pci_dev *dev, int *pin))
-{
- struct pci_dev *dev;
- u8 pin, slot, irq_orig;
- int irq;
-
- /*
- * Go through all devices, fixing up irqs as we see fit.
- */
- for (dev = pci_devices; dev; dev = dev->next) {
- if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
- (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
- continue;
-
- /*
- * We don't have code that will init the CYPRESS bridge
- * correctly so we do the next best thing, and depend on
- * the previous console code to do the right thing, and
- * ignore it here... :-\
- */
- if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
- dev->device == PCI_DEVICE_ID_CONTAQ_82C693) {
- DBG_DEVS(("common_pci_fixup: ignoring CYPRESS bridge...\n"));
- continue;
- }
-
- /*
- * This device is not on the primary bus, we need
- * to figure out which interrupt pin it will come
- * in on. We know which slot it will come in on
- * 'cos that slot is where the bridge is. Each
- * time the interrupt line passes through a PCI-PCI
- * bridge we must apply the swizzle function (see
- * the inline static routine above).
- */
- dev->irq = 0;
-
- pcibios_read_config_byte(dev->bus->number, dev->devfn,
- PCI_INTERRUPT_PIN, &pin);
- /* Cope with 0 and illegal. */
- if (pin == 0 || pin > 4)
- pin = 1;
-
- if (!DEV_IS_ON_PRIMARY(dev)) {
- /* Follow the chain of bridges, swizzling as we go. */
-
- int spill = pin;
- slot = (*swizzle)(dev, &spill);
- pin = spill;
-
- /* Must make sure that SRM didn't screw up
- and allocate an address > 64K for I/O
- space behind a PCI-PCI bridge. */
- if (alpha_use_srm_setup)
- check_behind_io(dev);
- } else {
- /* Just a device on a primary bus. */
- slot = PCI_SLOT(dev->devfn);
- }
-
- irq = (*map_irq)(dev, slot, pin);
-
- DBG_DEVS(("common_pci_fixup: bus %d slot %d "
- "pin %d irq %d\n",
- dev->bus->number, slot, pin, irq));
-
- if (irq != -1)
- dev->irq = irq;
-
- if (alpha_using_srm) {
- /* Read the original SRM-set IRQ and tell. */
- pcibios_read_config_byte(dev->bus->number,
- dev->devfn,
- PCI_INTERRUPT_LINE,
- &irq_orig);
-
- if (irq_orig != dev->irq) {
- DBG_DEVS(("common_pci_fixup: bus %d "
- "slot 0x%x SRM IRQ 0x%x "
- "changed to 0x%x\n",
- dev->bus->number,
- PCI_SLOT(dev->devfn),
- irq_orig, dev->irq));
-
- new_irq_reset(dev, irq_orig);
- }
- }
-
- /* Always tell the device, so the driver knows what is
- the real IRQ to use; the device does not use it. */
- pcibios_write_config_byte(dev->bus->number, dev->devfn,
- PCI_INTERRUPT_LINE, dev->irq);
-
- DBG_DEVS(("common_pci_fixup: bus %d slot 0x%x"
- " VID 0x%x DID 0x%x\n"
- " int_slot 0x%x pin 0x%x"
- " pirq 0x%x\n",
- dev->bus->number, PCI_SLOT(dev->devfn),
- dev->vendor, dev->device,
- slot, pin, dev->irq));
-
- /*
- * If it's a VGA, enable its BIOS ROM at C0000.
- */
- if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
- /* But if its a Cirrus 543x/544x DISABLE it,
- since enabling ROM disables the memory... */
- if ((dev->vendor == PCI_VENDOR_ID_CIRRUS) &&
- (dev->device >= 0x00a0) &&
- (dev->device <= 0x00ac)) {
- pcibios_write_config_dword(
- dev->bus->number,
- dev->devfn,
- PCI_ROM_ADDRESS,
- 0x00000000);
- } else {
- pcibios_write_config_dword(
- dev->bus->number,
- dev->devfn,
- PCI_ROM_ADDRESS,
- 0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
- }
- }
- /*
- * If it's a SCSI, disable its BIOS ROM.
- */
- if ((dev->class >> 8) == PCI_CLASS_STORAGE_SCSI) {
- pcibios_write_config_dword(dev->bus->number,
- dev->devfn,
- PCI_ROM_ADDRESS,
- 0x0000000);
- }
- }
-}
-
-/* Most Alphas have straight-forward swizzling needs. */
-
-int __init
-common_swizzle(struct pci_dev *dev, int *pinp)
-{
- int pin = *pinp;
- do {
- pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
- /* Move up the chain of bridges. */
- dev = dev->bus->self;
- } while (dev->bus->self);
- *pinp = pin;
-
- /* The slot is the slot of the last bridge. */
- return PCI_SLOT(dev->devfn);
-}
-
-/*
- * On multiple bus machines, in order to cope with a somewhat deficient
- * API, we must map the 8-bit bus identifier so that it is unique across
- * multiple interfaces (hoses). At the same time we do this, chain the
- * other hoses off of pci_root so that they will be found during normal
- * PCI probing and layout.
- */
-
-#define PRIMARY(b) ((b)&0xff)
-#define SECONDARY(b) (((b)>>8)&0xff)
-#define SUBORDINATE(b) (((b)>>16)&0xff)
-
-static int __init
-hose_scan_bridges(struct linux_hose_info *hose, unsigned char bus)
-{
- unsigned int devfn, l, class;
- unsigned char hdr_type = 0;
- unsigned int found = 0;
-
- for (devfn = 0; devfn < 0xff; ++devfn) {
- if (PCI_FUNC(devfn) == 0) {
- alpha_mv.hose_read_config_byte(bus, devfn,
- PCI_HEADER_TYPE,
- &hdr_type, hose);
- } else if (!(hdr_type & 0x80)) {
- /* not a multi-function device */
- continue;
- }
-
- /* Check if there is anything here. */
- alpha_mv.hose_read_config_dword(bus, devfn, PCI_VENDOR_ID,
- &l, hose);
- if (l == 0xffffffff || l == 0x00000000) {
- hdr_type = 0;
- continue;
- }
-
- /* See if this is a bridge device. */
- alpha_mv.hose_read_config_dword(bus, devfn, PCI_CLASS_REVISION,
- &class, hose);
-
- if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) {
- unsigned int busses;
-
- found++;
-
- alpha_mv.hose_read_config_dword(bus, devfn,
- PCI_PRIMARY_BUS,
- &busses, hose);
-
- DBG_HOSE(("hose_scan_bridges: hose %d bus %d "
- "slot %d busses 0x%x\n",
- hose->pci_hose_index, bus, PCI_SLOT(devfn),
- busses));
-
- /*
- * Do something with first_busno and last_busno
- */
- if (hose->pci_first_busno > PRIMARY(busses)) {
- hose->pci_first_busno = PRIMARY(busses);
- DBG_HOSE(("hose_scan_bridges: hose %d bus %d "
- "slot %d change first to %d\n",
- hose->pci_hose_index, bus,
- PCI_SLOT(devfn), PRIMARY(busses)));
- }
- if (hose->pci_last_busno < SUBORDINATE(busses)) {
- hose->pci_last_busno = SUBORDINATE(busses);
- DBG_HOSE(("hose_scan_bridges: hose %d bus %d "
- "slot %d change last to %d\n",
- hose->pci_hose_index, bus,
- PCI_SLOT(devfn),
- SUBORDINATE(busses)));
- }
- /*
- * Now scan everything underneath the bridge.
- */
- hose_scan_bridges(hose, SECONDARY(busses));
- }
- }
- return found;
-}
-
-static void __init
-hose_reconfigure_bridges(struct linux_hose_info *hose, unsigned char bus)
-{
- unsigned int devfn, l, class;
- unsigned char hdr_type = 0;
-
- for (devfn = 0; devfn < 0xff; ++devfn) {
- if (PCI_FUNC(devfn) == 0) {
- alpha_mv.hose_read_config_byte(bus, devfn,
- PCI_HEADER_TYPE,
- &hdr_type, hose);
- } else if (!(hdr_type & 0x80)) {
- /* not a multi-function device */
- continue;
- }
-
- /* Check if there is anything here. */
- alpha_mv.hose_read_config_dword(bus, devfn, PCI_VENDOR_ID,
- &l, hose);
- if (l == 0xffffffff || l == 0x00000000) {
- hdr_type = 0;
- continue;
- }
-
- /* See if this is a bridge device. */
- alpha_mv.hose_read_config_dword(bus, devfn, PCI_CLASS_REVISION,
- &class, hose);
-
- if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) {
- unsigned int busses;
-
- alpha_mv.hose_read_config_dword(bus, devfn,
- PCI_PRIMARY_BUS,
- &busses, hose);
-
- /*
- * First reconfigure everything underneath the bridge.
- */
- hose_reconfigure_bridges(hose, (busses >> 8) & 0xff);
-
- /*
- * Unconfigure this bridges bus numbers,
- * pci_scan_bus() will fix this up properly.
- */
- busses &= 0xff000000;
- alpha_mv.hose_write_config_dword(bus, devfn,
- PCI_PRIMARY_BUS,
- busses, hose);
- }
- }
-}
-
-static void __init
-hose_fixup_busno(struct linux_hose_info *hose, unsigned char bus)
-{
- int nbus;
-
- /*
- * First, scan for all bridge devices underneath this hose,
- * to determine the first and last busnos.
- */
- DBG_HOSE(("hose_fixup_busno: before hose_scan_bridges()\n"));
-
- if (!hose_scan_bridges(hose, 0)) {
- /* none found, exit */
- hose->pci_first_busno = bus;
- hose->pci_last_busno = bus;
- } else {
- /*
- * Reconfigure all bridge devices underneath this hose.
- */
- DBG_HOSE(("hose_fixup_busno: before hose_reconfigure_bridges\n"));
- hose_reconfigure_bridges(hose, hose->pci_first_busno);
- }
-
- /*
- * Now reconfigure the hose to it's new bus number and set up
- * our bus2hose mapping for this hose.
- */
- nbus = hose->pci_last_busno - hose->pci_first_busno;
-
- hose->pci_first_busno = bus;
-
- DBG_HOSE(("hose_fixup_busno: hose %d startbus %d nbus %d\n",
- hose->pci_hose_index, bus, nbus));
-
- do {
- bus2hose[bus++] = hose;
- } while (nbus-- > 0);
- DBG_HOSE(("hose_fixup_busno: returning...\n"));
-}
-
-static void __init
-layout_one_hose(struct linux_hose_info *hose)
-{
- static struct pci_bus *pchain = NULL;
- struct pci_bus *pbus = &hose->pci_bus;
- static unsigned char busno = 0;
-
- DBG_HOSE(("layout_one_hose: entry\n"));
-
- /*
- * Hoses include child PCI bridges in bus-range property,
- * but we don't scan each of those ourselves, Linux generic PCI
- * probing code will find child bridges and link them into this
- * hose's root PCI device hierarchy.
- */
-
- pbus->number = pbus->secondary = busno;
- pbus->sysdata = hose;
-
- DBG_HOSE(("layout_one_hose: before hose_fixup_busno()\n"));
-
- hose_fixup_busno(hose, busno);
-
- DBG_HOSE(("layout_one_hose: before pci_scan_bus()\n"));
-
- pbus->subordinate = pci_scan_bus(pbus); /* the original! */
-
- /*
- * Set the maximum subordinate bus of this hose.
- */
- hose->pci_last_busno = pbus->subordinate;
-#if 0
- alpha_mv.hose_write_config_byte(busno, 0, 0x41, hose->pci_last_busno,
- hose);
-#endif
- busno = pbus->subordinate + 1;
-
- /*
- * Fixup the chain of primary PCI busses.
- */
- if (pchain) {
- pchain->next = &hose->pci_bus;
- pchain = pchain->next;
- } else {
- pchain = &pci_root;
- memcpy(pchain, &hose->pci_bus, sizeof(pci_root));
- }
- DBG_HOSE(("layout_one_hose: returning...\n"));
-}
-
-static void __init
-layout_hoses(void)
-{
- struct linux_hose_info * hose;
- int i;
-
- /* On multiple bus machines, we play games with pci_root in order
- that all of the busses are probed as part of the normal PCI
- setup. The existance of the busses was determined in init_arch. */
-
- if (hose_head) {
- /* Multi-bus machines did not yet wish to allow bus
- accesses. We now do our own thing after the normal
- pci_scan_bus is over. This mechanism is relatively
- broken but will be fixed later. */
- pci_probe_enabled = 1;
-
- for (hose = hose_head; hose; hose = hose->next)
- layout_one_hose(hose);
- } else {
- /* For the benefit of single-bus machines, emulate a
- multi-bus machine to the (limited) extent necessary.
- Init all bus2hose entries to point to a dummy. */
- hose = kmalloc(sizeof(*hose), GFP_KERNEL);
- memset(hose, 0, sizeof(*hose));
- for (i = 0; i < 256; ++i)
- bus2hose[i] = hose;
- }
-}
-
-#endif /* CONFIG_PCI */
diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c
index fa23a4cf6..46378b762 100644
--- a/arch/alpha/kernel/core_apecs.c
+++ b/arch/alpha/kernel/core_apecs.c
@@ -1,22 +1,24 @@
/*
* linux/arch/alpha/kernel/core_apecs.c
*
- * Code common to all APECS core logic chips.
- *
* Rewritten for Apecs from the lca.c from:
*
* Written by David Mosberger (davidm@cs.arizona.edu) with some code
* taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
* bios code.
+ *
+ * Code common to all APECS core logic chips.
*/
+
#include <linux/kernel.h>
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/system.h>
#include <asm/ptrace.h>
+#include <asm/smp.h>
+#include <asm/pci.h>
#define __EXTERN_INLINE inline
#include <asm/io.h>
@@ -24,6 +26,7 @@
#undef __EXTERN_INLINE
#include "proto.h"
+#include "pci_impl.h"
/*
* NOTE: Herein lie back-to-back mb instructions. They are magic.
@@ -35,19 +38,16 @@
* BIOS32-style PCI interface:
*/
-#ifdef DEBUG
-# define DBG(args) printk args
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
+# define DBGC(args) printk args
#else
-# define DBG(args)
+# define DBGC(args)
#endif
#define vuip volatile unsigned int *
-volatile unsigned int apecs_mcheck_expected = 0;
-volatile unsigned int apecs_mcheck_taken = 0;
-static unsigned int apecs_jd, apecs_jd1, apecs_jd2;
-
-
/*
* Given a bus, device, and function number, compute resulting
* configuration space address and setup the APECS_HAXR2 register
@@ -91,14 +91,16 @@ static unsigned int apecs_jd, apecs_jd1, apecs_jd2;
*/
static int
-mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
unsigned long addr;
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
- DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
- " pci_addr=0x%p, type1=0x%p)\n",
- bus, device_fn, where, pci_addr, type1));
+ DBGC(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
+ " pci_addr=0x%p, type1=0x%p)\n",
+ bus, device_fn, where, pci_addr, type1));
if (bus == 0) {
int device = device_fn >> 3;
@@ -106,8 +108,8 @@ mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
/* type 0 configuration cycle: */
if (device > 20) {
- DBG(("mk_conf_addr: device (%d) > 20, returning -1\n",
- device));
+ DBGC(("mk_conf_addr: device (%d) > 20, returning -1\n",
+ device));
return -1;
}
@@ -119,7 +121,7 @@ mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
addr = (bus << 16) | (device_fn << 8) | (where);
}
*pci_addr = addr;
- DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+ DBGC(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
return 0;
}
@@ -132,25 +134,25 @@ conf_read(unsigned long addr, unsigned char type1)
__save_and_cli(flags); /* avoid getting hit by machine check */
- DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
+ DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
/* Reset status register to avoid losing errors. */
stat0 = *(vuip)APECS_IOC_DCSR;
*(vuip)APECS_IOC_DCSR = stat0;
mb();
- DBG(("conf_read: APECS DCSR was 0x%x\n", stat0));
+ DBGC(("conf_read: APECS DCSR was 0x%x\n", stat0));
/* If Type1 access, must set HAE #2. */
if (type1) {
haxr2 = *(vuip)APECS_IOC_HAXR2;
mb();
*(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
- DBG(("conf_read: TYPE1 access\n"));
+ DBGC(("conf_read: TYPE1 access\n"));
}
draina();
- apecs_mcheck_expected = 1;
- apecs_mcheck_taken = 0;
+ mcheck_expected(0) = 1;
+ mcheck_taken(0) = 0;
mb();
/* Access configuration space. */
@@ -159,12 +161,12 @@ conf_read(unsigned long addr, unsigned char type1)
asm volatile("ldl %0,%1; mb; mb" : "=r"(value) : "m"(*(vuip)addr)
: "$9", "$10", "$11", "$12", "$13", "$14", "memory");
- if (apecs_mcheck_taken) {
- apecs_mcheck_taken = 0;
+ if (mcheck_taken(0)) {
+ mcheck_taken(0) = 0;
value = 0xffffffffU;
mb();
}
- apecs_mcheck_expected = 0;
+ mcheck_expected(0) = 0;
mb();
#if 1
@@ -178,7 +180,7 @@ conf_read(unsigned long addr, unsigned char type1)
/* Now look for any errors. */
stat0 = *(vuip)APECS_IOC_DCSR;
- DBG(("conf_read: APECS DCSR after read 0x%x\n", stat0));
+ DBGC(("conf_read: APECS DCSR after read 0x%x\n", stat0));
/* Is any error bit set? */
if (stat0 & 0xffe0U) {
@@ -214,7 +216,6 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
__save_and_cli(flags); /* avoid getting hit by machine check */
-
/* Reset status register to avoid losing errors. */
stat0 = *(vuip)APECS_IOC_DCSR;
*(vuip)APECS_IOC_DCSR = stat0;
@@ -228,14 +229,14 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
}
draina();
- apecs_mcheck_expected = 1;
+ mcheck_expected(0) = 1;
mb();
/* Access configuration space. */
*(vuip)addr = value;
mb();
mb(); /* magic */
- apecs_mcheck_expected = 0;
+ mcheck_expected(0) = 0;
mb();
#if 1
@@ -272,162 +273,106 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
__restore_flags(flags);
}
-int
-apecs_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
- struct linux_hose_info *hose)
+static int
+apecs_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- unsigned long addr = APECS_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
-
+ addr = (pci_addr << 5) + 0x00 + APECS_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
-
return PCIBIOS_SUCCESSFUL;
}
-int
-apecs_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
- struct linux_hose_info *hose)
+static int
+apecs_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- unsigned long addr = APECS_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x08;
-
+ addr = (pci_addr << 5) + 0x08 + APECS_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
-int
-apecs_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
- struct linux_hose_info *hose)
+static int
+apecs_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- unsigned long addr = APECS_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x18;
+ addr = (pci_addr << 5) + 0x18 + APECS_CONF;
*value = conf_read(addr, type1);
return PCIBIOS_SUCCESSFUL;
}
-int
-apecs_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
- struct linux_hose_info *hose)
+static int
+apecs_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
- unsigned long addr = APECS_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
+ addr = (pci_addr << 5) + mask + APECS_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
}
-int
-apecs_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
- struct linux_hose_info *hose)
+static int
+apecs_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
- unsigned long addr = APECS_CONF;
- unsigned long pci_addr;
- unsigned char type1;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr |= (pci_addr << 5) + 0x08;
- conf_write(addr, value << ((where & 3) * 8), type1);
- return PCIBIOS_SUCCESSFUL;
+ return apecs_write_config(dev, where, value, 0x00);
}
-int
-apecs_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
- struct linux_hose_info *hose)
+static int
+apecs_write_config_word(struct pci_dev *dev, int where, u16 value)
{
- unsigned long addr = APECS_CONF;
- unsigned long pci_addr;
- unsigned char type1;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ return apecs_write_config(dev, where, value, 0x08);
+}
- addr |= (pci_addr << 5) + 0x18;
- conf_write(addr, value << ((where & 3) * 8), type1);
- return PCIBIOS_SUCCESSFUL;
+static int
+apecs_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ return apecs_write_config(dev, where, value, 0x18);
}
+struct pci_ops apecs_pci_ops =
+{
+ read_byte: apecs_read_config_byte,
+ read_word: apecs_read_config_word,
+ read_dword: apecs_read_config_dword,
+ write_byte: apecs_write_config_byte,
+ write_word: apecs_write_config_word,
+ write_dword: apecs_write_config_dword
+};
+
void __init
apecs_init_arch(unsigned long *mem_start, unsigned long *mem_end)
{
- switch (alpha_use_srm_setup)
- {
- default:
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
- /* Check window 1 for enabled and mapped to 0. */
- if ((*(vuip)APECS_IOC_PB1R & (1U<<19))
- && (*(vuip)APECS_IOC_TB1R == 0)) {
- APECS_DMA_WIN_BASE = *(vuip)APECS_IOC_PB1R & 0xfff00000U;
- APECS_DMA_WIN_SIZE = *(vuip)APECS_IOC_PM1R & 0xfff00000U;
- APECS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("apecs_init: using Window 1 settings\n");
- printk("apecs_init: PB1R 0x%x PM1R 0x%x TB1R 0x%x\n",
- *(vuip)APECS_IOC_PB1R,
- *(vuip)APECS_IOC_PM1R,
- *(vuip)APECS_IOC_TB1R);
-#endif
- break;
- }
+ struct pci_controler *hose;
- /* Check window 2 for enabled and mapped to 0. */
- if ((*(vuip)APECS_IOC_PB2R & (1U<<19))
- && (*(vuip)APECS_IOC_TB2R == 0)) {
- APECS_DMA_WIN_BASE = *(vuip)APECS_IOC_PB2R & 0xfff00000U;
- APECS_DMA_WIN_SIZE = *(vuip)APECS_IOC_PM2R & 0xfff00000U;
- APECS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("apecs_init: using Window 2 settings\n");
- printk("apecs_init: PB2R 0x%x PM2R 0x%x TB2R 0x%x\n",
- *(vuip)APECS_IOC_PB2R,
- *(vuip)APECS_IOC_PM2R,
- *(vuip)APECS_IOC_TB2R);
-#endif
- break;
- }
-
- /* Otherwise, we must use our defaults. */
- APECS_DMA_WIN_BASE = APECS_DMA_WIN_BASE_DEFAULT;
- APECS_DMA_WIN_SIZE = APECS_DMA_WIN_SIZE_DEFAULT;
-#endif
- case 0:
- /*
- * Set up the PCI->physical memory translation windows.
- * For now, window 2 is disabled. In the future, we may
- * want to use it to do scatter/gather DMA. Window 1
- * goes at 1 GB and is 1 GB large.
- */
- *(vuip)APECS_IOC_PB2R = 0U; /* disable window 2 */
-
- *(vuip)APECS_IOC_PB1R = 1U<<19 | (APECS_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
- *(vuip)APECS_IOC_PM1R = (APECS_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U;
- *(vuip)APECS_IOC_TB1R = 0;
- break;
- }
+ /*
+ * Set up the PCI->physical memory translation windows.
+ * For now, window 2 is disabled. In the future, we may
+ * want to use it to do scatter/gather DMA. Window 1
+ * goes at 1 GB and is 1 GB large.
+ */
+ *(vuip)APECS_IOC_PB1R = 1UL << 19 | (APECS_DMA_WIN_BASE & 0xfff00000U);
+ *(vuip)APECS_IOC_PM1R = (APECS_DMA_WIN_SIZE - 1) & 0xfff00000U;
+ *(vuip)APECS_IOC_TB1R = 0;
+
+ *(vuip)APECS_IOC_PB2R = 0U; /* disable window 2 */
/*
* Finally, clear the HAXR2 register, which gets used
@@ -435,23 +380,35 @@ apecs_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* we want to use it, and we do not want to depend on
* what ARC or SRM might have left behind...
*/
- *(vuip)APECS_IOC_HAXR2 = 0; mb();
+ *(vuip)APECS_IOC_HAXR2 = 0;
+ mb();
+
+ /*
+ * Create our single hose.
+ */
+
+ hose = alloc_pci_controler(mem_start);
+ hose->io_space = &ioport_resource;
+ hose->mem_space = &iomem_resource;
+ hose->config_space = APECS_CONF;
+ hose->index = 0;
}
-int
+void
apecs_pci_clr_err(void)
{
- apecs_jd = *(vuip)APECS_IOC_DCSR;
- if (apecs_jd & 0xffe0L) {
- apecs_jd1 = *(vuip)APECS_IOC_SEAR;
- *(vuip)APECS_IOC_DCSR = apecs_jd | 0xffe1L;
- apecs_jd = *(vuip)APECS_IOC_DCSR;
+ unsigned int jd;
+
+ jd = *(vuip)APECS_IOC_DCSR;
+ if (jd & 0xffe0L) {
+ *(vuip)APECS_IOC_SEAR;
+ *(vuip)APECS_IOC_DCSR = jd | 0xffe1L;
mb();
+ *(vuip)APECS_IOC_DCSR;
}
*(vuip)APECS_IOC_TBIA = (unsigned int)APECS_IOC_TBIA;
- apecs_jd2 = *(vuip)APECS_IOC_TBIA;
mb();
- return 0;
+ *(vuip)APECS_IOC_TBIA;
}
void
@@ -461,8 +418,6 @@ apecs_machine_check(unsigned long vector, unsigned long la_ptr,
struct el_common *mchk_header;
struct el_apecs_procdata *mchk_procdata;
struct el_apecs_sysdata_mcheck *mchk_sysdata;
- unsigned long *ptr;
- int i;
mchk_header = (struct el_common *)la_ptr;
@@ -473,66 +428,16 @@ apecs_machine_check(unsigned long vector, unsigned long la_ptr,
mchk_sysdata = (struct el_apecs_sysdata_mcheck *)
(la_ptr + mchk_header->sys_offset);
-#ifdef DEBUG
- printk("apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr);
- printk(" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset);
- printk("apecs_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
- apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
- mchk_sysdata->epic_pear);
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
- printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
- }
-#endif
- /*
- * Check if machine check is due to a badaddr() and if so,
- * ignore the machine check.
- */
+ /* Clear the error before any reporting. */
+ mb();
+ mb(); /* magic */
+ draina();
+ apecs_pci_clr_err();
+ wrmces(0x7); /* reset machine check pending flag */
+ mb();
- if (apecs_mcheck_expected
- && (mchk_sysdata->epic_dcsr & 0x0c00UL)) {
- apecs_mcheck_expected = 0;
- apecs_mcheck_taken = 1;
- mb();
- mb(); /* magic */
- apecs_pci_clr_err();
- wrmces(0x7);
- mb();
- draina();
- DBG(("apecs_machine_check: EXPECTED\n"));
- }
- else if (vector == 0x620 || vector == 0x630) {
- /* Disable correctable from now on. */
- wrmces(0x1f);
- mb();
- draina();
- printk("apecs_machine_check: HW correctable (0x%lx)\n",
- vector);
- }
- else {
- printk(KERN_CRIT "APECS machine check:\n");
- printk(KERN_CRIT " vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr);
- printk(KERN_CRIT
- " pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset);
- printk(KERN_CRIT " expected %d DCSR 0x%lx PEAR 0x%lx\n",
- apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
- mchk_sysdata->epic_pear);
-
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
- printk(KERN_CRIT " +%lx %lx %lx\n",
- i*sizeof(long), ptr[i], ptr[i+1]);
- }
-#if 0
- /* doesn't work with MILO */
- show_regs(regs);
-#endif
- }
+ process_mcheck_info(vector, la_ptr, regs, "APECS",
+ (mcheck_expected(0)
+ && (mchk_sysdata->epic_dcsr & 0x0c00UL)));
}
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
index eef315826..5821db09d 100644
--- a/arch/alpha/kernel/core_cia.c
+++ b/arch/alpha/kernel/core_cia.c
@@ -1,14 +1,17 @@
/*
* linux/arch/alpha/kernel/core_cia.c
*
- * Code common to all CIA core logic chips.
- *
* Written by David A Rusling (david.rusling@reo.mts.dec.com).
* December 1995.
*
+ * Copyright (C) 1995 David A Rusling
+ * Copyright (C) 1997, 1998 Jay Estabrook
+ * Copyright (C) 1998, 1999 Richard Henderson
+ *
+ * Code common to all CIA core logic chips.
*/
+
#include <linux/kernel.h>
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/sched.h>
@@ -16,6 +19,7 @@
#include <asm/system.h>
#include <asm/ptrace.h>
+#include <asm/pci.h>
#define __EXTERN_INLINE inline
#include <asm/io.h>
@@ -23,6 +27,8 @@
#undef __EXTERN_INLINE
#include "proto.h"
+#include "pci_impl.h"
+
/*
* NOTE: Herein lie back-to-back mb instructions. They are magic.
@@ -31,30 +37,12 @@
*/
/*
- * Machine check reasons. Defined according to PALcode sources
- * (osf.h and platform.h).
- */
-#define MCHK_K_TPERR 0x0080
-#define MCHK_K_TCPERR 0x0082
-#define MCHK_K_HERR 0x0084
-#define MCHK_K_ECC_C 0x0086
-#define MCHK_K_ECC_NC 0x0088
-#define MCHK_K_OS_BUGCHECK 0x008A
-#define MCHK_K_PAL_BUGCHECK 0x0090
-
-/*
* BIOS32-style PCI interface:
*/
-#define DEBUG_MCHECK 0
#define DEBUG_CONFIG 0
-/* #define DEBUG_DUMP_REGS */
+#define DEBUG_DUMP_REGS 0
-#if DEBUG_MCHECK
-# define DBGM(args) printk args
-#else
-# define DBGM(args)
-#endif
#if DEBUG_CONFIG
# define DBGC(args) printk args
#else
@@ -63,11 +51,6 @@
#define vuip volatile unsigned int *
-static volatile unsigned int CIA_mcheck_expected = 0;
-static volatile unsigned int CIA_mcheck_taken = 0;
-static unsigned int CIA_jd;
-
-
/*
* Given a bus, device, and function number, compute resulting
* configuration space address and setup the CIA_HAXR2 register
@@ -111,10 +94,12 @@ static unsigned int CIA_jd;
*/
static int
-mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
unsigned long addr;
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
DBGC(("mk_conf_addr(bus=%d, device_fn=0x%x, where=0x%x, "
"pci_addr=0x%p, type1=0x%p)\n",
@@ -173,46 +158,22 @@ conf_read(unsigned long addr, unsigned char type1)
mb();
draina();
- CIA_mcheck_expected = 1;
- CIA_mcheck_taken = 0;
+ mcheck_expected(0) = 1;
+ mcheck_taken(0) = 0;
mb();
/* Access configuration space. */
value = *(vuip)addr;
mb();
mb(); /* magic */
- if (CIA_mcheck_taken) {
- CIA_mcheck_taken = 0;
+ if (mcheck_taken(0)) {
+ mcheck_taken(0) = 0;
value = 0xffffffffU;
mb();
}
- CIA_mcheck_expected = 0;
+ mcheck_expected(0) = 0;
mb();
-#if 0
- /* This code might be necessary if machine checks aren't taken,
- but I can't get it to work on CIA-2, so its disabled. */
- draina();
-
- /* Now look for any errors. */
- stat0 = *(vuip)CIA_IOC_CIA_ERR;
- DBGC(("conf_read: CIA ERR after read 0x%x\n", stat0));
-
- /* Is any error bit set? */
- if (stat0 & 0x8FEF0FFFU) {
- /* If not MAS_ABT, print status. */
- if (!(stat0 & 0x0080)) {
- printk("CIA.c:conf_read: got stat0=%x\n", stat0);
- }
-
- /* reset error status: */
- *(vuip)CIA_IOC_CIA_ERR = stat0;
- mb();
- wrmces(0x7); /* reset machine check */
- value = 0xffffffff;
- }
-#endif
-
/* If Type1 access, must reset IOC CFG so normal IO space ops work. */
if (type1) {
*(vuip)CIA_IOC_CFG = cia_cfg & ~1;
@@ -249,7 +210,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
}
draina();
- CIA_mcheck_expected = 1;
+ mcheck_expected(0) = 1;
mb();
/* Access configuration space. */
@@ -257,33 +218,9 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
mb();
mb(); /* magic */
- CIA_mcheck_expected = 0;
+ mcheck_expected(0) = 0;
mb();
-#if 0
- /* This code might be necessary if machine checks aren't taken,
- but I can't get it to work on CIA-2, so its disabled. */
- draina();
-
- /* Now look for any errors */
- stat0 = *(vuip)CIA_IOC_CIA_ERR;
- DBGC(("conf_write: CIA ERR after write 0x%x\n", stat0));
-
- /* Is any error bit set? */
- if (stat0 & 0x8FEF0FFFU) {
- /* If not MAS_ABT, print status */
- if (!(stat0 & 0x0080)) {
- printk("CIA.c:conf_read: got stat0=%x\n", stat0);
- }
-
- /* Reset error status. */
- *(vuip)CIA_IOC_CIA_ERR = stat0;
- mb();
- wrmces(0x7); /* reset machine check */
- value = 0xffffffff;
- }
-#endif
-
/* If Type1 access, must reset IOC CFG so normal IO space ops work. */
if (type1) {
*(vuip)CIA_IOC_CFG = cia_cfg & ~1;
@@ -294,260 +231,179 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
__restore_flags(flags);
}
-int
-cia_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
- struct linux_hose_info *hose)
+static int
+cia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- unsigned long addr = CIA_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
+ addr = (pci_addr << 5) + 0x00 + CIA_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
-int
-cia_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
- struct linux_hose_info *hose)
+static int
+cia_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- unsigned long addr = CIA_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x08;
+ addr = (pci_addr << 5) + 0x08 + CIA_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
-int
-cia_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
- struct linux_hose_info *hose)
+static int
+cia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- unsigned long addr = CIA_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x18;
+ addr = (pci_addr << 5) + 0x18 + CIA_CONF;
*value = conf_read(addr, type1);
return PCIBIOS_SUCCESSFUL;
}
-int
-cia_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
- struct linux_hose_info *hose)
+static int
+cia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
- unsigned long addr = CIA_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
+ addr = (pci_addr << 5) + mask + CIA_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
}
-int
-cia_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
- struct linux_hose_info *hose)
+static int
+cia_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
- unsigned long addr = CIA_CONF;
- unsigned long pci_addr;
- unsigned char type1;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr |= (pci_addr << 5) + 0x08;
- conf_write(addr, value << ((where & 3) * 8), type1);
- return PCIBIOS_SUCCESSFUL;
+ return cia_write_config(dev, where, value, 0x00);
}
-int
-cia_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
- struct linux_hose_info *hose)
+static int
+cia_write_config_word(struct pci_dev *dev, int where, u16 value)
{
- unsigned long addr = CIA_CONF;
- unsigned long pci_addr;
- unsigned char type1;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ return cia_write_config(dev, where, value, 0x08);
+}
- addr |= (pci_addr << 5) + 0x18;
- conf_write(addr, value << ((where & 3) * 8), type1);
- return PCIBIOS_SUCCESSFUL;
+static int
+cia_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ return cia_write_config(dev, where, value, 0x18);
}
+struct pci_ops cia_pci_ops =
+{
+ read_byte: cia_read_config_byte,
+ read_word: cia_read_config_word,
+ read_dword: cia_read_config_dword,
+ write_byte: cia_write_config_byte,
+ write_word: cia_write_config_word,
+ write_dword: cia_write_config_dword
+};
+
void __init
cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
{
- unsigned int cia_tmp;
-
-#ifdef DEBUG_DUMP_REGS
- {
- unsigned int temp;
- temp = *(vuip)CIA_IOC_CIA_REV; mb();
- printk("cia_init: CIA_REV was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_PCI_LAT; mb();
- printk("cia_init: CIA_PCI_LAT was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
- printk("cia_init: CIA_CTRL was 0x%x\n", temp);
- temp = *(vuip)0xfffffc8740000140UL; mb();
- printk("cia_init: CIA_CTRL1 was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_HAE_MEM; mb();
- printk("cia_init: CIA_HAE_MEM was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_HAE_IO; mb();
- printk("cia_init: CIA_HAE_IO was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_CFG; mb();
- printk("cia_init: CIA_CFG was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_CACK_EN; mb();
- printk("cia_init: CIA_CACK_EN was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_CFG; mb();
- printk("cia_init: CIA_CFG was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_CIA_DIAG; mb();
- printk("cia_init: CIA_DIAG was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_DIAG_CHECK; mb();
- printk("cia_init: CIA_DIAG_CHECK was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_PERF_MONITOR; mb();
- printk("cia_init: CIA_PERF_MONITOR was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_PERF_CONTROL; mb();
- printk("cia_init: CIA_PERF_CONTROL was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_CIA_ERR; mb();
- printk("cia_init: CIA_ERR was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_CIA_STAT; mb();
- printk("cia_init: CIA_STAT was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_MCR; mb();
- printk("cia_init: CIA_MCR was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
- printk("cia_init: CIA_CTRL was 0x%x\n", temp);
- temp = *(vuip)CIA_IOC_ERR_MASK; mb();
- printk("cia_init: CIA_ERR_MASK was 0x%x\n", temp);
- temp = *((vuip)CIA_IOC_PCI_W0_BASE); mb();
- printk("cia_init: W0_BASE was 0x%x\n", temp);
- temp = *((vuip)CIA_IOC_PCI_W1_BASE); mb();
- printk("cia_init: W1_BASE was 0x%x\n", temp);
- temp = *((vuip)CIA_IOC_PCI_W2_BASE); mb();
- printk("cia_init: W2_BASE was 0x%x\n", temp);
- temp = *((vuip)CIA_IOC_PCI_W3_BASE); mb();
- printk("cia_init: W3_BASE was 0x%x\n", temp);
- }
+ struct pci_controler *hose;
+ struct resource *hae_mem;
+ unsigned int temp;
+
+#if DEBUG_DUMP_REGS
+ temp = *(vuip)CIA_IOC_CIA_REV; mb();
+ printk("cia_init: CIA_REV was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_PCI_LAT; mb();
+ printk("cia_init: CIA_PCI_LAT was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
+ printk("cia_init: CIA_CTRL was 0x%x\n", temp);
+ temp = *(vuip)0xfffffc8740000140UL; mb();
+ printk("cia_init: CIA_CTRL1 was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_HAE_MEM; mb();
+ printk("cia_init: CIA_HAE_MEM was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_HAE_IO; mb();
+ printk("cia_init: CIA_HAE_IO was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_CFG; mb();
+ printk("cia_init: CIA_CFG was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_CACK_EN; mb();
+ printk("cia_init: CIA_CACK_EN was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_CFG; mb();
+ printk("cia_init: CIA_CFG was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_CIA_DIAG; mb();
+ printk("cia_init: CIA_DIAG was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_DIAG_CHECK; mb();
+ printk("cia_init: CIA_DIAG_CHECK was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_PERF_MONITOR; mb();
+ printk("cia_init: CIA_PERF_MONITOR was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_PERF_CONTROL; mb();
+ printk("cia_init: CIA_PERF_CONTROL was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_CIA_ERR; mb();
+ printk("cia_init: CIA_ERR was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_CIA_STAT; mb();
+ printk("cia_init: CIA_STAT was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_MCR; mb();
+ printk("cia_init: CIA_MCR was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
+ printk("cia_init: CIA_CTRL was 0x%x\n", temp);
+ temp = *(vuip)CIA_IOC_ERR_MASK; mb();
+ printk("cia_init: CIA_ERR_MASK was 0x%x\n", temp);
+ temp = *((vuip)CIA_IOC_PCI_W0_BASE); mb();
+ printk("cia_init: W0_BASE was 0x%x\n", temp);
+ temp = *((vuip)CIA_IOC_PCI_W1_BASE); mb();
+ printk("cia_init: W1_BASE was 0x%x\n", temp);
+ temp = *((vuip)CIA_IOC_PCI_W2_BASE); mb();
+ printk("cia_init: W2_BASE was 0x%x\n", temp);
+ temp = *((vuip)CIA_IOC_PCI_W3_BASE); mb();
+ printk("cia_init: W3_BASE was 0x%x\n", temp);
#endif /* DEBUG_DUMP_REGS */
/*
* Set up error reporting.
*/
- cia_tmp = *(vuip)CIA_IOC_CIA_ERR;
- cia_tmp |= 0x180; /* master, target abort */
- *(vuip)CIA_IOC_CIA_ERR = cia_tmp;
+ temp = *(vuip)CIA_IOC_CIA_ERR;
+ temp |= 0x180; /* master, target abort */
+ *(vuip)CIA_IOC_CIA_ERR = temp;
mb();
- cia_tmp = *(vuip)CIA_IOC_CIA_CTRL;
- cia_tmp |= 0x400; /* turn on FILL_ERR to get mchecks */
- *(vuip)CIA_IOC_CIA_CTRL = cia_tmp;
+ temp = *(vuip)CIA_IOC_CIA_CTRL;
+ temp |= 0x400; /* turn on FILL_ERR to get mchecks */
+ *(vuip)CIA_IOC_CIA_CTRL = temp;
mb();
- switch (alpha_use_srm_setup)
- {
- default:
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
- /* Check window 0 for enabled and mapped to 0 */
- if (((*(vuip)CIA_IOC_PCI_W0_BASE & 3) == 1)
- && (*(vuip)CIA_IOC_PCI_T0_BASE == 0)) {
- CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W0_BASE & 0xfff00000U;
- CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W0_MASK & 0xfff00000U;
- CIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("cia_init: using Window 0 settings\n");
- printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)CIA_IOC_PCI_W0_BASE,
- *(vuip)CIA_IOC_PCI_W0_MASK,
- *(vuip)CIA_IOC_PCI_T0_BASE);
-#endif
- break;
- }
-
- /* Check window 1 for enabled and mapped to 0. */
- if (((*(vuip)CIA_IOC_PCI_W1_BASE & 3) == 1)
- && (*(vuip)CIA_IOC_PCI_T1_BASE == 0)) {
- CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W1_BASE & 0xfff00000U;
- CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W1_MASK & 0xfff00000U;
- CIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("cia_init: using Window 1 settings\n");
- printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)CIA_IOC_PCI_W1_BASE,
- *(vuip)CIA_IOC_PCI_W1_MASK,
- *(vuip)CIA_IOC_PCI_T1_BASE);
-#endif
- break;
- }
-
- /* Check window 2 for enabled and mapped to 0. */
- if (((*(vuip)CIA_IOC_PCI_W2_BASE & 3) == 1)
- && (*(vuip)CIA_IOC_PCI_T2_BASE == 0)) {
- CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W2_BASE & 0xfff00000U;
- CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W2_MASK & 0xfff00000U;
- CIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("cia_init: using Window 2 settings\n");
- printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)CIA_IOC_PCI_W2_BASE,
- *(vuip)CIA_IOC_PCI_W2_MASK,
- *(vuip)CIA_IOC_PCI_T2_BASE);
-#endif
- break;
- }
-
- /* Check window 3 for enabled and mapped to 0. */
- if (((*(vuip)CIA_IOC_PCI_W3_BASE & 3) == 1)
- && (*(vuip)CIA_IOC_PCI_T3_BASE == 0)) {
- CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W3_BASE & 0xfff00000U;
- CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W3_MASK & 0xfff00000U;
- CIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("cia_init: using Window 3 settings\n");
- printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)CIA_IOC_PCI_W3_BASE,
- *(vuip)CIA_IOC_PCI_W3_MASK,
- *(vuip)CIA_IOC_PCI_T3_BASE);
-#endif
- break;
- }
+ /*
+ * Set up the PCI->physical memory translation windows.
+ * For now, windows 2 and 3 are disabled. In the future,
+ * we may want to use them to do scatter/gather DMA.
+ *
+ * Window 0 goes at 1 GB and is 1 GB large.
+ * Window 1 goes at 2 GB and is 1 GB large.
+ */
- /* Otherwise, we must use our defaults. */
- CIA_DMA_WIN_BASE = CIA_DMA_WIN_BASE_DEFAULT;
- CIA_DMA_WIN_SIZE = CIA_DMA_WIN_SIZE_DEFAULT;
-#endif
- case 0:
- /*
- * Set up the PCI->physical memory translation windows.
- * For now, windows 1,2 and 3 are disabled. In the future,
- * we may want to use them to do scatter/gather DMA.
- *
- * Window 0 goes at 1 GB and is 1 GB large.
- */
-
- *(vuip)CIA_IOC_PCI_W0_BASE = 1U | (CIA_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
- *(vuip)CIA_IOC_PCI_W0_MASK = (CIA_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U;
- *(vuip)CIA_IOC_PCI_T0_BASE = 0;
-
- *(vuip)CIA_IOC_PCI_W1_BASE = 0x0;
- *(vuip)CIA_IOC_PCI_W2_BASE = 0x0;
- *(vuip)CIA_IOC_PCI_W3_BASE = 0x0;
- break;
- }
+ *(vuip)CIA_IOC_PCI_W0_BASE = CIA_DMA_WIN0_BASE_DEFAULT | 1U;
+ *(vuip)CIA_IOC_PCI_W0_MASK = (CIA_DMA_WIN0_SIZE_DEFAULT - 1) &
+ 0xfff00000U;
+ *(vuip)CIA_IOC_PCI_T0_BASE = CIA_DMA_WIN0_TRAN_DEFAULT >> 2;
+
+ *(vuip)CIA_IOC_PCI_W1_BASE = CIA_DMA_WIN1_BASE_DEFAULT | 1U;
+ *(vuip)CIA_IOC_PCI_W1_MASK = (CIA_DMA_WIN1_SIZE_DEFAULT - 1) &
+ 0xfff00000U;
+ *(vuip)CIA_IOC_PCI_T1_BASE = CIA_DMA_WIN1_TRAN_DEFAULT >> 2;
+
+ *(vuip)CIA_IOC_PCI_W2_BASE = 0x0;
+ *(vuip)CIA_IOC_PCI_W3_BASE = 0x0;
+ mb();
/*
* Next, clear the CIA_CFG register, which gets used
@@ -557,164 +413,55 @@ cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
*/
*((vuip)CIA_IOC_CFG) = 0; mb();
+ /*
+ * Zero the HAEs.
+ */
+ *((vuip)CIA_IOC_HAE_MEM) = 0; mb();
+ *((vuip)CIA_IOC_HAE_MEM); /* read it back. */
+ *((vuip)CIA_IOC_HAE_IO) = 0; mb();
+ *((vuip)CIA_IOC_HAE_IO); /* read it back. */
/*
- * Sigh... For the SRM setup, unless we know apriori what the HAE
- * contents will be, we need to setup the arbitrary region bases
- * so we can test against the range of addresses and tailor the
- * region chosen for the SPARSE memory access.
- *
- * See include/asm-alpha/cia.h for the SPARSE mem read/write.
+ * Create our single hose.
*/
- if (alpha_use_srm_setup) {
- unsigned int cia_hae_mem = *((vuip)CIA_IOC_HAE_MEM);
-
- alpha_mv.sm_base_r1 = (cia_hae_mem ) & 0xe0000000UL;
- alpha_mv.sm_base_r2 = (cia_hae_mem << 16) & 0xf8000000UL;
- alpha_mv.sm_base_r3 = (cia_hae_mem << 24) & 0xfc000000UL;
-
- /*
- * Set the HAE cache, so that setup_arch() code
- * will use the SRM setting always. Our readb/writeb
- * code in cia.h expects never to have to change
- * the contents of the HAE.
- */
- alpha_mv.hae_cache = cia_hae_mem;
-
- alpha_mv.mv_readb = cia_srm_readb;
- alpha_mv.mv_readw = cia_srm_readw;
- alpha_mv.mv_writeb = cia_srm_writeb;
- alpha_mv.mv_writew = cia_srm_writew;
- } else {
- *((vuip)CIA_IOC_HAE_MEM) = 0; mb();
- *((vuip)CIA_IOC_HAE_MEM); /* read it back. */
- *((vuip)CIA_IOC_HAE_IO) = 0; mb();
- *((vuip)CIA_IOC_HAE_IO); /* read it back. */
- }
+
+ hose = alloc_pci_controler(mem_start);
+ hae_mem = alloc_resource(mem_start);
+
+ hose->io_space = &ioport_resource;
+ hose->mem_space = hae_mem;
+ hose->config_space = CIA_CONF;
+ hose->index = 0;
+
+ hae_mem->start = 0;
+ hae_mem->end = CIA_MEM_R1_MASK;
+ hae_mem->name = pci_hae0_name;
+
+ request_resource(&iomem_resource, hae_mem);
}
-static int
+static inline void
cia_pci_clr_err(void)
{
- CIA_jd = *(vuip)CIA_IOC_CIA_ERR;
- DBGM(("CIA_pci_clr_err: CIA ERR after read 0x%x\n", CIA_jd));
- *(vuip)CIA_IOC_CIA_ERR = CIA_jd;
+ unsigned int jd;
+
+ jd = *(vuip)CIA_IOC_CIA_ERR;
+ *(vuip)CIA_IOC_CIA_ERR = jd;
mb();
- return 0;
+ *(vuip)CIA_IOC_CIA_ERR; /* re-read to force write. */
}
void
cia_machine_check(unsigned long vector, unsigned long la_ptr,
struct pt_regs * regs)
{
- struct el_common *mchk_header;
- struct el_CIA_procdata *mchk_procdata;
- struct el_CIA_sysdata_mcheck *mchk_sysdata;
- unsigned long * ptr;
- const char * reason;
- char buf[128];
- long i;
-
- mchk_header = (struct el_common *)la_ptr;
-
- mchk_procdata = (struct el_CIA_procdata *)
- (la_ptr + mchk_header->proc_offset);
-
- mchk_sysdata = (struct el_CIA_sysdata_mcheck *)
- (la_ptr + mchk_header->sys_offset);
-
- DBGM(("cia_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr));
- DBGM((" pc=0x%lx size=0x%x procoffset=0x%x "
- "sysoffset 0x%x\n", regs->pc, mchk_header->size,
- mchk_header->proc_offset, mchk_header->sys_offset));
- DBGM(("cia_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
- CIA_mcheck_expected, mchk_sysdata->epic_dcsr,
- mchk_sysdata->epic_pear));
-
-#if DEBUG_MCHECK
- {
- unsigned long *ptr;
- int i;
-
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
- printk(" +%lx %lx %lx\n", i*sizeof(long),
- ptr[i], ptr[i+1]);
- }
- }
-#endif
-
- /*
- * Check if machine check is due to a badaddr() and if so,
- * ignore the machine check.
- */
- mb();
- mb(); /* magic */
- if (CIA_mcheck_expected) {
- DBGM(("CIA machine check expected\n"));
- CIA_mcheck_expected = 0;
- CIA_mcheck_taken = 1;
- mb();
- mb(); /* magic */
- draina();
- cia_pci_clr_err();
- wrmces(0x7);
- mb();
- return;
- }
-
- switch ((unsigned int) mchk_header->code) {
- case MCHK_K_TPERR: reason = "tag parity error"; break;
- case MCHK_K_TCPERR: reason = "tag control parity error"; break;
- case MCHK_K_HERR: reason = "generic hard error"; break;
- case MCHK_K_ECC_C: reason = "correctable ECC error"; break;
- case MCHK_K_ECC_NC: reason = "uncorrectable ECC error"; break;
- case MCHK_K_OS_BUGCHECK: reason = "OS-specific PAL bugcheck"; break;
- case MCHK_K_PAL_BUGCHECK: reason = "callsys in kernel mode"; break;
- case 0x96: reason = "i-cache read retryable error"; break;
- case 0x98: reason = "processor detected hard error"; break;
-
- /* System specific (these are for Alcor, at least): */
- case 0x203: reason = "system detected uncorrectable ECC error"; break;
- case 0x205: reason = "parity error detected by CIA"; break;
- case 0x207: reason = "non-existent memory error"; break;
- case 0x209: reason = "PCI SERR detected"; break;
- case 0x20b: reason = "PCI data parity error detected"; break;
- case 0x20d: reason = "PCI address parity error detected"; break;
- case 0x20f: reason = "PCI master abort error"; break;
- case 0x211: reason = "PCI target abort error"; break;
- case 0x213: reason = "scatter/gather PTE invalid error"; break;
- case 0x215: reason = "flash ROM write error"; break;
- case 0x217: reason = "IOA timeout detected"; break;
- case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
- case 0x21b: reason = "EISA fail-safe timer timeout"; break;
- case 0x21d: reason = "EISA bus time-out"; break;
- case 0x21f: reason = "EISA software generated NMI"; break;
- case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
- default:
- sprintf(buf, "reason for machine-check unknown (0x%x)",
- (unsigned int) mchk_header->code);
- reason = buf;
- break;
- }
+ /* Clear the error before any reporting. */
mb();
mb(); /* magic */
draina();
cia_pci_clr_err();
- wrmces(rdmces()); /* reset machine check pending flag */
+ wrmces(rdmces()); /* reset machine check pending flag. */
mb();
- printk(KERN_CRIT "CIA machine check: %s%s\n",
- reason, mchk_header->retry ? " (retryable)" : "");
- printk(KERN_CRIT " vector=0x%lx la_ptr=0x%lx pc=0x%lx\n",
- vector, la_ptr, regs->pc);
-
- /* Dump the logout area to give all info. */
-
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
- printk(KERN_CRIT " +%8lx %016lx %016lx\n",
- i*sizeof(long), ptr[i], ptr[i+1]);
- }
+ process_mcheck_info(vector, la_ptr, regs, "CIA", mcheck_expected(0));
}
diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c
index 8a529f27a..13172b708 100644
--- a/arch/alpha/kernel/core_lca.c
+++ b/arch/alpha/kernel/core_lca.c
@@ -1,14 +1,14 @@
/*
* linux/arch/alpha/kernel/core_lca.c
*
- * Code common to all LCA core logic chips.
- *
* Written by David Mosberger (davidm@cs.arizona.edu) with some code
* taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
* bios code.
+ *
+ * Code common to all LCA core logic chips.
*/
+
#include <linux/kernel.h>
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/init.h>
@@ -17,6 +17,7 @@
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/smp.h>
+#include <asm/pci.h>
#define __EXTERN_INLINE inline
#include <asm/io.h>
@@ -24,6 +25,8 @@
#undef __EXTERN_INLINE
#include "proto.h"
+#include "pci_impl.h"
+
/*
* BIOS32-style PCI interface:
@@ -97,9 +100,11 @@
*/
static int
-mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr)
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr)
{
unsigned long addr;
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
if (bus == 0) {
int device = device_fn >> 3;
@@ -194,154 +199,103 @@ conf_write(unsigned long addr, unsigned int value)
__restore_flags(flags);
}
-int
-lca_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
- struct linux_hose_info *hose)
+static int
+lca_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- unsigned long addr = LCA_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+ if (mk_conf_addr(dev, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
+ addr = (pci_addr << 5) + 0x00 + LCA_CONF;
*value = conf_read(addr) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
-int
-lca_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
- struct linux_hose_info *hose)
+static int
+lca_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- unsigned long addr = LCA_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+ if (mk_conf_addr(dev, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x08;
+ addr = (pci_addr << 5) + 0x08 + LCA_CONF;
*value = conf_read(addr) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
-int
-lca_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
- struct linux_hose_info *hose)
+static int
+lca_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- unsigned long addr = LCA_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+ if (mk_conf_addr(dev, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x18;
+ addr = (pci_addr << 5) + 0x18 + LCA_CONF;
*value = conf_read(addr);
return PCIBIOS_SUCCESSFUL;
}
-int
-lca_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
- struct linux_hose_info *hose)
+static int
+lca_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
- unsigned long addr = LCA_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+ if (mk_conf_addr(dev, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
+ addr = (pci_addr << 5) + mask + LCA_CONF;
conf_write(addr, value << ((where & 3) * 8));
return PCIBIOS_SUCCESSFUL;
}
-int
-lca_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
- struct linux_hose_info *hose)
+static int
+lca_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
- unsigned long addr = LCA_CONF;
- unsigned long pci_addr;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr |= (pci_addr << 5) + 0x08;
- conf_write(addr, value << ((where & 3) * 8));
- return PCIBIOS_SUCCESSFUL;
+ return lca_write_config(dev, where, value, 0x00);
}
-int
-lca_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
- struct linux_hose_info *hose)
+static int
+lca_write_config_word(struct pci_dev *dev, int where, u16 value)
{
- unsigned long addr = LCA_CONF;
- unsigned long pci_addr;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ return lca_write_config(dev, where, value, 0x08);
+}
- addr |= (pci_addr << 5) + 0x18;
- conf_write(addr, value << ((where & 3) * 8));
- return PCIBIOS_SUCCESSFUL;
+static int
+lca_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ return lca_write_config(dev, where, value, 0x18);
}
+struct pci_ops lca_pci_ops =
+{
+ read_byte: lca_read_config_byte,
+ read_word: lca_read_config_word,
+ read_dword: lca_read_config_dword,
+ write_byte: lca_write_config_byte,
+ write_word: lca_write_config_word,
+ write_dword: lca_write_config_dword
+};
+
void __init
lca_init_arch(unsigned long *mem_start, unsigned long *mem_end)
{
- switch (alpha_use_srm_setup)
- {
- default:
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
- /* Check window 0 for enabled and mapped to 0. */
- if ((*(vulp)LCA_IOC_W_BASE0 & (1UL<<33))
- && (*(vulp)LCA_IOC_T_BASE0 == 0)) {
- LCA_DMA_WIN_BASE = *(vulp)LCA_IOC_W_BASE0 & 0xffffffffUL;
- LCA_DMA_WIN_SIZE = *(vulp)LCA_IOC_W_MASK0 & 0xffffffffUL;
- LCA_DMA_WIN_SIZE += 1;
-#if 0
- printk("lca_init: using Window 0 settings\n");
- printk("lca_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
- *(vulp)LCA_IOC_W_BASE0,
- *(vulp)LCA_IOC_W_MASK0,
- *(vulp)LCA_IOC_T_BASE0);
-#endif
- break;
- }
+ struct pci_controler *hose;
- /* Check window 2 for enabled and mapped to 0. */
- if ((*(vulp)LCA_IOC_W_BASE1 & (1UL<<33))
- && (*(vulp)LCA_IOC_T_BASE1 == 0)) {
- LCA_DMA_WIN_BASE = *(vulp)LCA_IOC_W_BASE1 & 0xffffffffUL;
- LCA_DMA_WIN_SIZE = *(vulp)LCA_IOC_W_MASK1 & 0xffffffffUL;
- LCA_DMA_WIN_SIZE += 1;
-#if 1
- printk("lca_init: using Window 1 settings\n");
- printk("lca_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
- *(vulp)LCA_IOC_W_BASE1,
- *(vulp)LCA_IOC_W_MASK1,
- *(vulp)LCA_IOC_T_BASE1);
-#endif
- break;
- }
+ /*
+ * Set up the PCI->physical memory translation windows.
+ * For now, window 1 is disabled. In the future, we may
+ * want to use it to do scatter/gather DMA.
+ *
+ * Window 0 goes at 1 GB and is 1 GB large.
+ */
+ *(vulp)LCA_IOC_W_BASE0 = 1UL << 33 | LCA_DMA_WIN_BASE;
+ *(vulp)LCA_IOC_W_MASK0 = LCA_DMA_WIN_SIZE - 1;
+ *(vulp)LCA_IOC_T_BASE0 = 0;
- /* Otherwise, we must use our defaults. */
- LCA_DMA_WIN_BASE = LCA_DMA_WIN_BASE_DEFAULT;
- LCA_DMA_WIN_SIZE = LCA_DMA_WIN_SIZE_DEFAULT;
-#endif
- case 0:
- /*
- * Set up the PCI->physical memory translation windows.
- * For now, window 1 is disabled. In the future, we may
- * want to use it to do scatter/gather DMA.
- *
- * Window 0 goes at 1 GB and is 1 GB large.
- */
- *(vulp)LCA_IOC_W_BASE1 = 0UL<<33;
-
- *(vulp)LCA_IOC_W_BASE0 = 1UL<<33 | LCA_DMA_WIN_BASE_DEFAULT;
- *(vulp)LCA_IOC_W_MASK0 = LCA_DMA_WIN_SIZE_DEFAULT - 1;
- *(vulp)LCA_IOC_T_BASE0 = 0;
- break;
- }
+ *(vulp)LCA_IOC_W_BASE1 = 0UL;
/*
* Disable PCI parity for now. The NCR53c810 chip has
@@ -349,6 +303,16 @@ lca_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* data parity errors.
*/
*(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
+
+ /*
+ * Create our single hose.
+ */
+
+ hose = alloc_pci_controler(mem_start);
+ hose->io_space = &ioport_resource;
+ hose->mem_space = &iomem_resource;
+ hose->config_space = LCA_CONF;
+ hose->index = 0;
}
/*
@@ -376,7 +340,7 @@ lca_init_arch(unsigned long *mem_start, unsigned long *mem_end)
#define IOC_P_NBR ((__u32) ~((1<<13) - 1))
static void
-mem_error (unsigned long esr, unsigned long ear)
+mem_error(unsigned long esr, unsigned long ear)
{
printk(" %s %s error to %s occurred at address %x\n",
((esr & ESR_CEE) ? "Correctable" :
@@ -399,7 +363,7 @@ mem_error (unsigned long esr, unsigned long ear)
}
static void
-ioc_error (__u32 stat0, __u32 stat1)
+ioc_error(__u32 stat0, __u32 stat1)
{
static const char * const pci_cmd[] = {
"Interrupt Acknowledge", "Special", "I/O Read", "I/O Write",
@@ -430,18 +394,18 @@ ioc_error (__u32 stat0, __u32 stat1)
}
void
-lca_machine_check (unsigned long vector, unsigned long la,
- struct pt_regs *regs)
+lca_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs *regs)
{
- unsigned long * ptr;
const char * reason;
union el_lca el;
- char buf[128];
- long i;
- printk(KERN_CRIT "lca: machine check (la=0x%lx,pc=0x%lx)\n",
- la, regs->pc);
- el.c = (struct el_common *) la;
+ el.c = (struct el_common *) la_ptr;
+
+ wrmces(rdmces()); /* reset machine check pending flag */
+
+ printk(KERN_CRIT "LCA machine check: vector=%#lx pc=%#lx code=%#x\n",
+ vector, regs->pc, (unsigned int) el.c->code);
/*
* The first quadword after the common header always seems to
@@ -450,13 +414,13 @@ lca_machine_check (unsigned long vector, unsigned long la,
* logout frame, the upper 32 bits is the machine check
* revision level, which we ignore for now.
*/
- switch (el.c->code & 0xffffffff) {
+ switch ((unsigned int) el.c->code) {
case MCHK_K_TPERR: reason = "tag parity error"; break;
case MCHK_K_TCPERR: reason = "tag control parity error"; break;
case MCHK_K_HERR: reason = "access to non-existent memory"; break;
case MCHK_K_ECC_C: reason = "correctable ECC error"; break;
case MCHK_K_ECC_NC: reason = "non-correctable ECC error"; break;
- case MCHK_K_CACKSOFT: reason = "MCHK_K_CACKSOFT"; break; /* what's this? */
+ case MCHK_K_CACKSOFT: reason = "MCHK_K_CACKSOFT"; break;
case MCHK_K_BUGCHECK: reason = "illegal exception in PAL mode"; break;
case MCHK_K_OS_BUGCHECK: reason = "callsys in kernel mode"; break;
case MCHK_K_DCPERR: reason = "d-cache parity error"; break;
@@ -465,19 +429,13 @@ lca_machine_check (unsigned long vector, unsigned long la,
case MCHK_K_SIO_IOCHK: reason = "SIO IOCHK occurred on ISA bus"; break;
case MCHK_K_DCSR: reason = "MCHK_K_DCSR"; break;
case MCHK_K_UNKNOWN:
- default:
- sprintf(buf, "reason for machine-check unknown (0x%lx)",
- el.c->code & 0xffffffff);
- reason = buf;
- break;
+ default: reason = "unknown"; break;
}
- wrmces(rdmces()); /* reset machine check pending flag */
-
switch (el.c->size) {
case sizeof(struct el_lca_mcheck_short):
printk(KERN_CRIT
- " Reason: %s (short frame%s, dc_stat=%lx):\n",
+ " Reason: %s (short frame%s, dc_stat=%#lx):\n",
reason, el.c->retry ? ", retryable" : "",
el.s->dc_stat);
if (el.s->esr & ESR_EAV) {
@@ -492,9 +450,9 @@ lca_machine_check (unsigned long vector, unsigned long la,
printk(KERN_CRIT " Reason: %s (long frame%s):\n",
reason, el.c->retry ? ", retryable" : "");
printk(KERN_CRIT
- " reason: %lx exc_addr: %lx dc_stat: %lx\n",
+ " reason: %#lx exc_addr: %#lx dc_stat: %#lx\n",
el.l->pt[0], el.l->exc_addr, el.l->dc_stat);
- printk(KERN_CRIT " car: %lx\n", el.l->car);
+ printk(KERN_CRIT " car: %#lx\n", el.l->car);
if (el.l->esr & ESR_EAV) {
mem_error(el.l->esr, el.l->ear);
}
@@ -508,12 +466,16 @@ lca_machine_check (unsigned long vector, unsigned long la,
}
/* Dump the logout area to give all info. */
-
- ptr = (unsigned long *) la;
- for (i = 0; i < el.c->size / sizeof(long); i += 2) {
- printk(KERN_CRIT " +%8lx %016lx %016lx\n",
- i*sizeof(long), ptr[i], ptr[i+1]);
+#if DEBUG_MCHECK > 1
+ {
+ unsigned long * ptr = (unsigned long *) la_ptr;
+ long i;
+ for (i = 0; i < el.c->size / sizeof(long); i += 2) {
+ printk(KERN_CRIT " +%8lx %016lx %016lx\n",
+ i*sizeof(long), ptr[i], ptr[i+1]);
+ }
}
+#endif
}
/*
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
index 6e24dca07..ac86d5255 100644
--- a/arch/alpha/kernel/core_mcpcia.c
+++ b/arch/alpha/kernel/core_mcpcia.c
@@ -1,12 +1,11 @@
/*
* linux/arch/alpha/kernel/core_mcpcia.c
*
- * Code common to all MCbus-PCI Adaptor core logic chipsets
- *
* Based on code written by David A Rusling (david.rusling@reo.mts.dec.com).
*
+ * Code common to all MCbus-PCI Adaptor core logic chipsets
*/
-#include <linux/config.h>
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
@@ -25,7 +24,7 @@
#undef __EXTERN_INLINE
#include "proto.h"
-#include "bios32.h"
+#include "pci_impl.h"
/*
* NOTE: Herein lie back-to-back mb instructions. They are magic.
@@ -37,28 +36,20 @@
* BIOS32-style PCI interface:
*/
-#undef DEBUG_CFG
+#define DEBUG_CFG 0
-#ifdef DEBUG_CFG
+#if DEBUG_CFG
# define DBG_CFG(args) printk args
#else
# define DBG_CFG(args)
#endif
+#define MCPCIA_MAX_HOSES 2
-#define DEBUG_MCHECK
-
-#ifdef DEBUG_MCHECK
-# define DBG_MCK(args) printk args
-#else
-# define DBG_MCK(args)
-#endif
+/* Dodge has PCI0 and PCI1 at MID 4 and 5 respectively. Durango adds
+ PCI2 and PCI3 at MID 6 and 7 respectively. */
-static volatile unsigned int MCPCIA_mcheck_expected[NR_CPUS];
-static volatile unsigned int MCPCIA_mcheck_taken[NR_CPUS];
-static unsigned int MCPCIA_jd[NR_CPUS];
-
-#define MCPCIA_MAX_HOSES 2
+#define hose2mid(h) ((h) + 4)
/*
@@ -105,10 +96,10 @@ static unsigned int MCPCIA_jd[NR_CPUS];
static unsigned int
conf_read(unsigned long addr, unsigned char type1,
- struct linux_hose_info *hose)
+ struct pci_controler *hose)
{
unsigned long flags;
- unsigned long hoseno = hose->pci_hose_index;
+ unsigned long mid = hose2mid(hose->index);
unsigned int stat0, value, temp, cpu;
cpu = smp_processor_id();
@@ -116,18 +107,20 @@ conf_read(unsigned long addr, unsigned char type1,
__save_and_cli(flags);
DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n",
- addr, type1, hoseno));
+ addr, type1, mid));
/* Reset status register to avoid losing errors. */
- stat0 = *(vuip)MCPCIA_CAP_ERR(hoseno);
- *(vuip)MCPCIA_CAP_ERR(hoseno) = stat0; mb();
- temp = *(vuip)MCPCIA_CAP_ERR(hoseno);
- DBG_CFG(("conf_read: MCPCIA CAP_ERR(%d) was 0x%x\n", hoseno, stat0));
+ stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
+ *(vuip)MCPCIA_CAP_ERR(mid) = stat0;
+ mb();
+ temp = *(vuip)MCPCIA_CAP_ERR(mid);
+ DBG_CFG(("conf_read: MCPCIA_CAP_ERR(%d) was 0x%x\n", mid, stat0));
mb();
draina();
- MCPCIA_mcheck_expected[cpu] = 1;
- MCPCIA_mcheck_taken[cpu] = 0;
+ mcheck_expected(cpu) = 1;
+ mcheck_taken(cpu) = 0;
+ mcheck_extra(cpu) = mid;
mb();
/* Access configuration space. */
@@ -135,12 +128,12 @@ conf_read(unsigned long addr, unsigned char type1,
mb();
mb(); /* magic */
- if (MCPCIA_mcheck_taken[cpu]) {
- MCPCIA_mcheck_taken[cpu] = 0;
+ if (mcheck_taken(cpu)) {
+ mcheck_taken(cpu) = 0;
value = 0xffffffffU;
mb();
}
- MCPCIA_mcheck_expected[cpu] = 0;
+ mcheck_expected(cpu) = 0;
mb();
DBG_CFG(("conf_read(): finished\n"));
@@ -151,10 +144,10 @@ conf_read(unsigned long addr, unsigned char type1,
static void
conf_write(unsigned long addr, unsigned int value, unsigned char type1,
- struct linux_hose_info *hose)
+ struct pci_controler *hose)
{
unsigned long flags;
- unsigned long hoseno = hose->pci_hose_index;
+ unsigned long mid = hose2mid(hose->index);
unsigned int stat0, temp, cpu;
cpu = smp_processor_id();
@@ -162,21 +155,22 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1,
__save_and_cli(flags); /* avoid getting hit by machine check */
/* Reset status register to avoid losing errors. */
- stat0 = *(vuip)MCPCIA_CAP_ERR(hoseno);
- *(vuip)MCPCIA_CAP_ERR(hoseno) = stat0; mb();
- temp = *(vuip)MCPCIA_CAP_ERR(hoseno);
- DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", hoseno, stat0));
+ stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
+ *(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb();
+ temp = *(vuip)MCPCIA_CAP_ERR(mid);
+ DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", mid, stat0));
draina();
- MCPCIA_mcheck_expected[cpu] = 1;
+ mcheck_expected(cpu) = 1;
+ mcheck_extra(cpu) = mid;
mb();
/* Access configuration space. */
*((vuip)addr) = value;
mb();
mb(); /* magic */
- temp = *(vuip)MCPCIA_CAP_ERR(hoseno); /* read to force the write */
- MCPCIA_mcheck_expected[cpu] = 0;
+ temp = *(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */
+ mcheck_expected(cpu) = 0;
mb();
DBG_CFG(("conf_write(): finished\n"));
@@ -184,71 +178,71 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1,
}
static int
-mk_conf_addr(struct linux_hose_info *hose,
- u8 bus, u8 device_fn, u8 where,
+mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose,
unsigned long *pci_addr, unsigned char *type1)
{
+ u8 bus = dev->bus->number;
+ u8 devfn = dev->devfn;
unsigned long addr;
- if (!pci_probe_enabled)
- return -1;
-
- DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
+ DBG_CFG(("mk_conf_addr(bus=%d,devfn=0x%x,hose=%d,where=0x%x,"
" pci_addr=0x%p, type1=0x%p)\n",
- bus, device_fn, where, pci_addr, type1));
+ bus, devfn, hose->index, where, pci_addr, type1));
/* Type 1 configuration cycle for *ALL* busses. */
*type1 = 1;
- if (hose->pci_first_busno == bus)
+ if (dev->bus->number == hose->first_busno)
bus = 0;
- addr = (bus << 16) | (device_fn << 8) | (where);
+ addr = (bus << 16) | (devfn << 8) | (where);
addr <<= 5; /* swizzle for SPARSE */
- addr |= hose->pci_config_space;
+ addr |= hose->config_space;
*pci_addr = addr;
DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
return 0;
}
-int
-mcpcia_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
- struct linux_hose_info *hose)
+static int
+mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- unsigned long addr;
+ struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ unsigned long addr, w;
unsigned char type1;
- if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+ if (mk_conf_addr(dev, where, hose, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr |= 0x00;
- *value = conf_read(addr, type1, hose) >> ((where & 3) * 8);
+ w = conf_read(addr, type1, hose);
+ *value = __kernel_extbl(w, where & 3);
return PCIBIOS_SUCCESSFUL;
}
-int
-mcpcia_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
- struct linux_hose_info *hose)
+static int
+mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- unsigned long addr;
+ struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ unsigned long addr, w;
unsigned char type1;
- if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+ if (mk_conf_addr(dev, where, hose, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr |= 0x08;
- *value = conf_read(addr, type1, hose) >> ((where & 3) * 8);
+ w = conf_read(addr, type1, hose);
+ *value = __kernel_extwl(w, where & 3);
return PCIBIOS_SUCCESSFUL;
}
-int
-mcpcia_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
- struct linux_hose_info *hose)
+static int
+mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
+ struct pci_controler *hose = dev->sysdata ? : probing_hose;
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+ if (mk_conf_addr(dev, where, hose, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr |= 0x18;
@@ -256,317 +250,213 @@ mcpcia_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
return PCIBIOS_SUCCESSFUL;
}
-int
-mcpcia_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
- struct linux_hose_info *hose)
+static int
+mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
+ struct pci_controler *hose = dev->sysdata ? : probing_hose;
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+ if (mk_conf_addr(dev, where, hose, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= 0x00;
- conf_write(addr, value << ((where & 3) * 8), type1, hose);
+ addr |= mask;
+ value = __kernel_insql(value, where & 3);
+ conf_write(addr, value, type1, hose);
return PCIBIOS_SUCCESSFUL;
}
-int
-mcpcia_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
- struct linux_hose_info *hose)
+static int
+mcpcia_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr |= 0x08;
- conf_write(addr, value << ((where & 3) * 8), type1, hose);
- return PCIBIOS_SUCCESSFUL;
+ return mcpcia_write_config(dev, where, value, 0x00);
}
-int
-mcpcia_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
- struct linux_hose_info *hose)
+static int
+mcpcia_write_config_word(struct pci_dev *dev, int where, u16 value)
{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ return mcpcia_write_config(dev, where, value, 0x08);
+}
- addr |= 0x18;
- conf_write(addr, value << ((where & 3) * 8), type1, hose);
- return PCIBIOS_SUCCESSFUL;
+static int
+mcpcia_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ return mcpcia_write_config(dev, where, value, 0x18);
}
-void __init
-mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+struct pci_ops mcpcia_pci_ops =
{
- extern asmlinkage void entInt(void);
- struct linux_hose_info *hose;
- unsigned int mcpcia_err;
+ read_byte: mcpcia_read_config_byte,
+ read_word: mcpcia_read_config_word,
+ read_dword: mcpcia_read_config_dword,
+ write_byte: mcpcia_write_config_byte,
+ write_word: mcpcia_write_config_word,
+ write_dword: mcpcia_write_config_dword
+};
+
+static int __init
+mcpcia_probe_hose(int h)
+{
+ int cpu = smp_processor_id();
+ int mid = hose2mid(h);
unsigned int pci_rev;
- int h, cpu;
- /* Ho hum.. init_arch is called before init_IRQ, but we need to be
- able to handle machine checks. So install the handler now. */
- wrent(entInt, 0);
-
- /* Align memory to cache line; we'll be allocating from it. */
- *mem_start = (*mem_start | 31) + 1;
-
- cpu = smp_processor_id();
+ /* Gotta be REAL careful. If hose is absent, we get an mcheck. */
- /* First, find how many hoses we have. */
- for (h = 0; h < MCPCIA_MAX_HOSES; h++) {
+ mb();
+ mb();
+ draina();
+ mcheck_expected(cpu) = 1;
+ mcheck_taken(cpu) = 0;
+ mcheck_extra(cpu) = mid;
+ mb();
- /* Gotta be REAL careful. If hose is absent, we get a
- machine check. */
+ /* Access the bus revision word. */
+ pci_rev = *(vuip)MCPCIA_REV(mid);
+ mb();
+ mb(); /* magic */
+ if (mcheck_taken(cpu)) {
+ mcheck_taken(cpu) = 0;
+ pci_rev = 0xffffffff;
mb();
- mb();
- draina();
- MCPCIA_mcheck_expected[cpu] = 1;
- MCPCIA_mcheck_taken[cpu] = 0;
- mb();
+ }
+ mcheck_expected(cpu) = 0;
+ mb();
+
+ return (pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST;
+}
- /* Access the bus revision word. */
- pci_rev = *(vuip)MCPCIA_REV(h);
+static void __init
+mcpcia_new_hose(unsigned long *mem_start, int h)
+{
+ struct pci_controler *hose;
+ struct resource *io, *mem, *hae_mem;
+ int mid = hose2mid(h);
+
+ hose = alloc_pci_controler(mem_start);
+ io = alloc_resource(mem_start);
+ mem = alloc_resource(mem_start);
+ hae_mem = alloc_resource(mem_start);
+
+ hose->io_space = io;
+ hose->mem_space = hae_mem;
+ hose->config_space = MCPCIA_CONF(mid);
+ hose->index = h;
+
+ io->start = MCPCIA_IO(mid) - MCPCIA_IO_BIAS;
+ io->end = io->start + 0xffff;
+ io->name = pci_io_names[h];
+
+ mem->start = MCPCIA_DENSE(mid) - MCPCIA_MEM_BIAS;
+ mem->end = mem->start + 0xffffffff;
+ mem->name = pci_mem_names[h];
+
+ hae_mem->start = mem->start;
+ hae_mem->end = mem->start + MCPCIA_MEM_MASK;
+ hae_mem->name = pci_hae0_name;
+
+ request_resource(&ioport_resource, io);
+ request_resource(&iomem_resource, mem);
+ request_resource(mem, hae_mem);
+}
- mb();
- mb(); /* magic */
- if (MCPCIA_mcheck_taken[cpu]) {
- MCPCIA_mcheck_taken[cpu] = 0;
- pci_rev = 0xffffffff;
- mb();
- }
- MCPCIA_mcheck_expected[cpu] = 0;
- mb();
+static void __init
+mcpcia_startup_hose(struct pci_controler *hose)
+{
+ int mid = hose2mid(hose->index);
+ unsigned int tmp;
+ /*
+ * Set up error reporting. Make sure CPU_PE is OFF in the mask.
+ */
#if 0
- printk("mcpcia_init_arch: got 0x%x for PCI_REV for hose %d\n",
- pci_rev, h);
+ tmp = *(vuip)MCPCIA_ERR_MASK(mid);
+ tmp &= ~4;
+ *(vuip)MCPCIA_ERR_MASK(mid) = tmp;
+ mb();
+ tmp = *(vuip)MCPCIA_ERR_MASK(mid);
#endif
- if ((pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST) {
- hose_count++;
- hose = (struct linux_hose_info *)*mem_start;
- *mem_start = (unsigned long)(hose + 1);
+ tmp = *(vuip)MCPCIA_CAP_ERR(mid);
+ tmp |= 0x0006; /* master/target abort */
+ *(vuip)MCPCIA_CAP_ERR(mid) = tmp;
+ mb();
+ tmp = *(vuip)MCPCIA_CAP_ERR(mid);
- memset(hose, 0, sizeof(*hose));
+ /*
+ * Set up the PCI->physical memory translation windows.
+ * For now, windows 1,2 and 3 are disabled. In the
+ * future, we may want to use them to do scatter/
+ * gather DMA.
+ *
+ * Window 0 goes at 2 GB and is 2 GB large.
+ */
- *hose_tail = hose;
- hose_tail = &hose->next;
+ *(vuip)MCPCIA_W0_BASE(mid) = 1U | (MCPCIA_DMA_WIN_BASE & 0xfff00000U);
+ *(vuip)MCPCIA_W0_MASK(mid) = (MCPCIA_DMA_WIN_SIZE - 1) & 0xfff00000U;
+ *(vuip)MCPCIA_T0_BASE(mid) = 0;
- hose->pci_io_space = MCPCIA_IO(h);
- hose->pci_mem_space = MCPCIA_DENSE(h);
- hose->pci_config_space = MCPCIA_CONF(h);
- hose->pci_sparse_space = MCPCIA_SPARSE(h);
- hose->pci_hose_index = h;
- hose->pci_first_busno = 255;
- hose->pci_last_busno = 0;
- }
- }
+ *(vuip)MCPCIA_W1_BASE(mid) = 0x0;
+ *(vuip)MCPCIA_W2_BASE(mid) = 0x0;
+ *(vuip)MCPCIA_W3_BASE(mid) = 0x0;
-#if 1
- printk("mcpcia_init_arch: found %d hoses\n", hose_count);
-#endif
+ *(vuip)MCPCIA_HBASE(mid) = 0x0;
+ mb();
- /* Now do init for each hose. */
- for (hose = hose_head; hose; hose = hose->next) {
- h = hose->pci_hose_index;
#if 0
- printk("mcpcia_init_arch: -------- hose %d --------\n",h);
- printk("MCPCIA_REV 0x%x\n", *(vuip)MCPCIA_REV(h));
- printk("MCPCIA_WHOAMI 0x%x\n", *(vuip)MCPCIA_WHOAMI(h));
- printk("MCPCIA_HAE_MEM 0x%x\n", *(vuip)MCPCIA_HAE_MEM(h));
- printk("MCPCIA_HAE_IO 0x%x\n", *(vuip)MCPCIA_HAE_IO(h));
- printk("MCPCIA_HAE_DENSE 0x%x\n", *(vuip)MCPCIA_HAE_DENSE(h));
- printk("MCPCIA_INT_CTL 0x%x\n", *(vuip)MCPCIA_INT_CTL(h));
- printk("MCPCIA_INT_REQ 0x%x\n", *(vuip)MCPCIA_INT_REQ(h));
- printk("MCPCIA_INT_TARG 0x%x\n", *(vuip)MCPCIA_INT_TARG(h));
- printk("MCPCIA_INT_ADR 0x%x\n", *(vuip)MCPCIA_INT_ADR(h));
- printk("MCPCIA_INT_ADR_EXT 0x%x\n", *(vuip)MCPCIA_INT_ADR_EXT(h));
- printk("MCPCIA_INT_MASK0 0x%x\n", *(vuip)MCPCIA_INT_MASK0(h));
- printk("MCPCIA_INT_MASK1 0x%x\n", *(vuip)MCPCIA_INT_MASK1(h));
- printk("MCPCIA_HBASE 0x%x\n", *(vuip)MCPCIA_HBASE(h));
+ tmp = *(vuip)MCPCIA_INT_CTL(mid);
+ printk("mcpcia_init_arch: INT_CTL was 0x%x\n", tmp);
+ *(vuip)MCPCIA_INT_CTL(mid) = 1U;
+ mb();
+ tmp = *(vuip)MCPCIA_INT_CTL(mid);
#endif
- /*
- * Set up error reporting. Make sure CPU_PE is OFF in the mask.
- */
-#if 0
- mcpcia_err = *(vuip)MCPCIA_ERR_MASK(h);
- mcpcia_err &= ~4;
- *(vuip)MCPCIA_ERR_MASK(h) = mcpcia_err;
- mb();
- mcpcia_err = *(vuip)MCPCIA_ERR_MASK;
-#endif
+ *(vuip)MCPCIA_HAE_MEM(mid) = 0U;
+ mb();
+ *(vuip)MCPCIA_HAE_MEM(mid); /* read it back. */
+ *(vuip)MCPCIA_HAE_IO(mid) = 0;
+ mb();
+ *(vuip)MCPCIA_HAE_IO(mid); /* read it back. */
+}
- mcpcia_err = *(vuip)MCPCIA_CAP_ERR(h);
- mcpcia_err |= 0x0006; /* master/target abort */
- *(vuip)MCPCIA_CAP_ERR(h) = mcpcia_err;
- mb() ;
- mcpcia_err = *(vuip)MCPCIA_CAP_ERR(h);
-
- switch (alpha_use_srm_setup)
- {
- default:
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
- /* Check window 0 for enabled and mapped to 0. */
- if (((*(vuip)MCPCIA_W0_BASE(h) & 3) == 1)
- && (*(vuip)MCPCIA_T0_BASE(h) == 0)
- && ((*(vuip)MCPCIA_W0_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
- MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W0_BASE(h) & 0xfff00000U;
- MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W0_MASK(h) & 0xfff00000U;
- MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("mcpcia_init_arch: using Window 0 settings\n");
- printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)MCPCIA_W0_BASE(h),
- *(vuip)MCPCIA_W0_MASK(h),
- *(vuip)MCPCIA_T0_BASE(h));
-#endif
- break;
- }
-
- /* Check window 1 for enabled and mapped to 0. */
- if (((*(vuip)MCPCIA_W1_BASE(h) & 3) == 1)
- && (*(vuip)MCPCIA_T1_BASE(h) == 0)
- && ((*(vuip)MCPCIA_W1_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
- MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W1_BASE(h) & 0xfff00000U;
- MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W1_MASK(h) & 0xfff00000U;
- MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("mcpcia_init_arch: using Window 1 settings\n");
- printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)MCPCIA_W1_BASE(h),
- *(vuip)MCPCIA_W1_MASK(h),
- *(vuip)MCPCIA_T1_BASE(h));
-#endif
- break;
- }
-
- /* Check window 2 for enabled and mapped to 0. */
- if (((*(vuip)MCPCIA_W2_BASE(h) & 3) == 1)
- && (*(vuip)MCPCIA_T2_BASE(h) == 0)
- && ((*(vuip)MCPCIA_W2_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
- MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W2_BASE(h) & 0xfff00000U;
- MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W2_MASK(h) & 0xfff00000U;
- MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("mcpcia_init_arch: using Window 2 settings\n");
- printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)MCPCIA_W2_BASE(h),
- *(vuip)MCPCIA_W2_MASK(h),
- *(vuip)MCPCIA_T2_BASE(h));
-#endif
- break;
- }
-
- /* Check window 3 for enabled and mapped to 0. */
- if (((*(vuip)MCPCIA_W3_BASE(h) & 3) == 1)
- && (*(vuip)MCPCIA_T3_BASE(h) == 0)
- && ((*(vuip)MCPCIA_W3_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
- MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W3_BASE(h) & 0xfff00000U;
- MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W3_MASK(h) & 0xfff00000U;
- MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("mcpcia_init_arch: using Window 3 settings\n");
- printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)MCPCIA_W3_BASE(h),
- *(vuip)MCPCIA_W3_MASK(h),
- *(vuip)MCPCIA_T3_BASE(h));
-#endif
- break;
- }
+void __init
+mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+ extern asmlinkage void entInt(void);
+ struct pci_controler *hose;
+ int h, hose_count = 0;
- /* Otherwise, we must use our defaults. */
- MCPCIA_DMA_WIN_BASE = MCPCIA_DMA_WIN_BASE_DEFAULT;
- MCPCIA_DMA_WIN_SIZE = MCPCIA_DMA_WIN_SIZE_DEFAULT;
-#endif
- case 0:
- /*
- * Set up the PCI->physical memory translation windows.
- * For now, windows 1,2 and 3 are disabled. In the
- * future, we may want to use them to do scatter/
- * gather DMA.
- *
- * Window 0 goes at 2 GB and is 2 GB large.
- */
-
- *(vuip)MCPCIA_W0_BASE(h) = 1U | (MCPCIA_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
- *(vuip)MCPCIA_W0_MASK(h) = (MCPCIA_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U;
- *(vuip)MCPCIA_T0_BASE(h) = 0;
-
- *(vuip)MCPCIA_W1_BASE(h) = 0x0 ;
- *(vuip)MCPCIA_W2_BASE(h) = 0x0 ;
- *(vuip)MCPCIA_W3_BASE(h) = 0x0 ;
-
- *(vuip)MCPCIA_HBASE(h) = 0x0 ;
- mb();
- break;
- }
-#if 0
- {
- unsigned int mcpcia_int_ctl = *((vuip)MCPCIA_INT_CTL(h));
- printk("mcpcia_init_arch: INT_CTL was 0x%x\n", mcpcia_int_ctl);
- *(vuip)MCPCIA_INT_CTL(h) = 1U; mb();
- mcpcia_int_ctl = *(vuip)MCPCIA_INT_CTL(h);
- }
-#endif
+ /* Ho hum.. init_arch is called before init_IRQ, but we need to be
+ able to handle machine checks. So install the handler now. */
+ wrent(entInt, 0);
+
+ /* With multiple PCI busses, we play with I/O as physical addrs. */
+ ioport_resource.end = ~0UL;
+ iomem_resource.end = ~0UL;
- /*
- * Sigh... For the SRM setup, unless we know apriori what the HAE
- * contents will be, we need to setup the arbitrary region bases
- * so we can test against the range of addresses and tailor the
- * region chosen for the SPARSE memory access.
- *
- * See include/asm-alpha/mcpcia.h for the SPARSE mem read/write.
- */
- if (alpha_use_srm_setup) {
- unsigned int mcpcia_hae_mem = *(vuip)MCPCIA_HAE_MEM(h);
-
- alpha_mv.sm_base_r1 = (mcpcia_hae_mem ) & 0xe0000000UL;
- alpha_mv.sm_base_r2 = (mcpcia_hae_mem << 16) & 0xf8000000UL;
- alpha_mv.sm_base_r3 = (mcpcia_hae_mem << 24) & 0xfc000000UL;
-
- /*
- * Set the HAE cache, so that setup_arch() code
- * will use the SRM setting always. Our readb/writeb
- * code in mcpcia.h expects never to have to change
- * the contents of the HAE.
- */
- alpha_mv.hae_cache = mcpcia_hae_mem;
-
- alpha_mv.mv_readb = mcpcia_srm_readb;
- alpha_mv.mv_readw = mcpcia_srm_readw;
- alpha_mv.mv_writeb = mcpcia_srm_writeb;
- alpha_mv.mv_writew = mcpcia_srm_writew;
- } else {
- *(vuip)MCPCIA_HAE_MEM(h) = 0U; mb();
- *(vuip)MCPCIA_HAE_MEM(h); /* read it back. */
- *(vuip)MCPCIA_HAE_IO(h) = 0; mb();
- *(vuip)MCPCIA_HAE_IO(h); /* read it back. */
+ /* First, find how many hoses we have. */
+ for (h = 0; h < MCPCIA_MAX_HOSES; ++h) {
+ if (mcpcia_probe_hose(h)) {
+ mcpcia_new_hose(mem_start, h);
+ hose_count++;
}
}
+
+ printk("mcpcia_init_arch: found %d hoses\n", hose_count);
+
+ /* Now do init for each hose. */
+ for (hose = hose_head; hose; hose = hose->next)
+ mcpcia_startup_hose(hose);
}
-static int
-mcpcia_pci_clr_err(int h)
+static void
+mcpcia_pci_clr_err(int mid)
{
- unsigned int cpu = smp_processor_id();
-
- MCPCIA_jd[cpu] = *(vuip)MCPCIA_CAP_ERR(h);
-#if 0
- DBG_MCK(("MCPCIA_pci_clr_err: MCPCIA CAP_ERR(%d) after read 0x%x\n",
- h, MCPCIA_jd[cpu]));
-#endif
- *(vuip)MCPCIA_CAP_ERR(h) = 0xffffffff; mb(); /* clear them all */
- MCPCIA_jd[cpu] = *(vuip)MCPCIA_CAP_ERR(h);
- return 0;
+ *(vuip)MCPCIA_CAP_ERR(mid);
+ *(vuip)MCPCIA_CAP_ERR(mid) = 0xffffffff; /* Clear them all. */
+ mb();
+ *(vuip)MCPCIA_CAP_ERR(mid); /* Re-read for force write. */
}
static void
@@ -642,70 +532,35 @@ mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
}
void
-mcpcia_machine_check(unsigned long type, unsigned long la_ptr,
+mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
struct pt_regs * regs)
{
-#if 0
- printk("mcpcia machine check ignored\n") ;
-#else
struct el_common *mchk_header;
struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout;
unsigned int cpu = smp_processor_id();
- int h = 0;
mchk_header = (struct el_common *)la_ptr;
mchk_logout = (struct el_MCPCIA_uncorrected_frame_mcheck *)la_ptr;
-#if 0
- DBG_MCK(("mcpcia_machine_check: type=0x%lx la_ptr=0x%lx\n",
- type, la_ptr));
- DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset));
-#endif
- /*
- * Check if machine check is due to a badaddr() and if so,
- * ignore the machine check.
- */
mb();
mb(); /* magic */
- if (MCPCIA_mcheck_expected[cpu]) {
-#if 0
- DBG_MCK(("MCPCIA machine check expected\n"));
-#endif
- MCPCIA_mcheck_expected[cpu] = 0;
- MCPCIA_mcheck_taken[cpu] = 1;
- mb();
- mb(); /* magic */
- draina();
- mcpcia_pci_clr_err(h);
- wrmces(0x7);
- mb();
+ draina();
+ if (mcheck_expected(cpu)) {
+ mcpcia_pci_clr_err(mcheck_extra(cpu));
+ } else {
+ /* FIXME: how do we figure out which hose the error was on? */
+ struct pci_controler *hose;
+ for (hose = hose_head; hose; hose = hose->next)
+ mcpcia_pci_clr_err(hose2mid(hose->index));
}
-#if 1
- else {
- printk("MCPCIA machine check NOT expected on CPU %d\n", cpu);
- DBG_MCK(("mcpcia_machine_check: type=0x%lx pc=0x%lx"
- " code=0x%lx\n",
- type, regs->pc, mchk_header->code));
-
- MCPCIA_mcheck_expected[cpu] = 0;
- MCPCIA_mcheck_taken[cpu] = 1;
- mb();
- mb(); /* magic */
- draina();
- mcpcia_pci_clr_err(h);
- wrmces(0x7);
- mb();
-#ifdef DEBUG_MCHECK_DUMP
- if (type == 0x620)
- printk("MCPCIA machine check: system CORRECTABLE!\n");
- else if (type == 0x630)
- printk("MCPCIA machine check: processor CORRECTABLE!\n");
- else
-#endif /* DEBUG_MCHECK_DUMP */
+ wrmces(0x7);
+ mb();
+
+ if (mcheck_expected(cpu)) {
+ process_mcheck_info(vector, la_ptr, regs, "MCPCIA", 1);
+ } else {
+ process_mcheck_info(vector, la_ptr, regs, "MCPCIA", 0);
+ if (vector != 0x620 && vector != 0x630)
mcpcia_print_uncorrectable(mchk_logout);
}
-#endif
-#endif
}
diff --git a/arch/alpha/kernel/core_polaris.c b/arch/alpha/kernel/core_polaris.c
index b9945402f..39ae36f8e 100644
--- a/arch/alpha/kernel/core_polaris.c
+++ b/arch/alpha/kernel/core_polaris.c
@@ -2,8 +2,8 @@
* linux/arch/alpha/kernel/core_polaris.c
*
* POLARIS chip-specific code
- *
*/
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
@@ -20,29 +20,20 @@
#undef __EXTERN_INLINE
#include "proto.h"
-#include "bios32.h"
+#include "pci_impl.h"
/*
* BIOS32-style PCI interface:
*/
-#ifdef DEBUG_CONFIG
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
# define DBG_CFG(args) printk args
#else
# define DBG_CFG(args)
#endif
-#define DEBUG_MCHECK
-#ifdef DEBUG_MCHECK
-# define DBG_MCK(args) printk args
-/* #define DEBUG_MCHECK_DUMP */
-#else
-# define DBG_MCK(args)
-#endif
-
-static volatile unsigned int POLARIS_mcheck_expected = 0;
-static volatile unsigned int POLARIS_mcheck_taken = 0;
-static volatile unsigned short POLARIS_jd = 0;
/*
* Given a bus, device, and function number, compute resulting
@@ -75,8 +66,11 @@ static volatile unsigned short POLARIS_jd = 0;
*/
static int
-mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr, u8 *type1)
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, u8 *type1)
{
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
+
*type1 = (bus == 0) ? 0 : 1;
*pci_addr = (bus << 16) | (device_fn << 8) | (where) |
POLARIS_DENSE_CONFIG_BASE;
@@ -88,59 +82,52 @@ mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr, u8 *type1)
return 0;
}
-int
-polaris_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
- struct linux_hose_info *hose)
+static int
+polaris_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
unsigned long pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = __kernel_ldbu(*(vucp)pci_addr);
return PCIBIOS_SUCCESSFUL;
}
-
-int
-polaris_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
- struct linux_hose_info *hose)
+static int
+polaris_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
unsigned long pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = __kernel_ldwu(*(vusp)pci_addr);
return PCIBIOS_SUCCESSFUL;
}
-
-int
-polaris_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
- struct linux_hose_info *hose)
+static int
+polaris_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = *(vuip)pci_addr;
return PCIBIOS_SUCCESSFUL;
}
-
-int
-polaris_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
- struct linux_hose_info *hose)
+static int
+polaris_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
unsigned long pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stb(value, *(vucp)pci_addr);
@@ -149,15 +136,13 @@ polaris_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
return PCIBIOS_SUCCESSFUL;
}
-
-int
-polaris_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
- struct linux_hose_info *hose)
+static int
+polaris_write_config_word(struct pci_dev *dev, int where, u16 value)
{
unsigned long pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stw(value, *(vusp)pci_addr);
@@ -166,15 +151,13 @@ polaris_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
return PCIBIOS_SUCCESSFUL;
}
-
-int
-polaris_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
- struct linux_hose_info *hose)
+static int
+polaris_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
unsigned long pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*(vuip)pci_addr = value;
@@ -183,9 +166,21 @@ polaris_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
return PCIBIOS_SUCCESSFUL;
}
+struct pci_ops polaris_pci_ops =
+{
+ read_byte: polaris_read_config_byte,
+ read_word: polaris_read_config_word,
+ read_dword: polaris_read_config_dword,
+ write_byte: polaris_write_config_byte,
+ write_word: polaris_write_config_word,
+ write_dword: polaris_write_config_dword
+};
+
void __init
polaris_init_arch(unsigned long *mem_start, unsigned long *mem_end)
{
+ struct pci_controler *hose;
+
/* May need to initialize error reporting (see PCICTL0/1), but
* for now assume that the firmware has done the right thing
* already.
@@ -193,83 +188,40 @@ polaris_init_arch(unsigned long *mem_start, unsigned long *mem_end)
#if 0
printk("polaris_init_arch(): trusting firmware for setup\n");
#endif
+
+ /*
+ * Create our single hose.
+ */
+
+ hose = alloc_pci_controler(mem_start);
+ hose->io_space = &ioport_resource;
+ hose->mem_space = &iomem_resource;
+ hose->config_space = POLARIS_DENSE_CONFIG_BASE;
+ hose->index = 0;
}
-int polaris_pci_clr_err(void)
+static inline void
+polaris_pci_clr_err(void)
{
- POLARIS_jd = *((vusp)POLARIS_W_STATUS);
- DBG_MCK(("POLARIS_pci_clr_err: POLARIS_W_STATUS after read 0x%x\n",
- POLARIS_jd));
+ *(vusp)POLARIS_W_STATUS;
/* Write 1's to settable bits to clear errors */
- *((vusp)POLARIS_W_STATUS) = 0x7800; mb();
- POLARIS_jd = *((vusp)POLARIS_W_STATUS);
- return 0;
+ *(vusp)POLARIS_W_STATUS = 0x7800;
+ mb();
+ *(vusp)POLARIS_W_STATUS;
}
-void polaris_machine_check(unsigned long vector, unsigned long la_ptr,
- struct pt_regs * regs)
+void
+polaris_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs * regs)
{
- struct el_common *mchk_header;
- struct el_POLARIS_sysdata_mcheck *mchk_sysdata;
-
- mchk_header = (struct el_common *)la_ptr;
-
- mchk_sysdata =
- (struct el_POLARIS_sysdata_mcheck *)(la_ptr+mchk_header->sys_offset);
-
-#if 0
- DBG_MCK(("polaris_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr));
- DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset));
- DBG_MCK(("polaris_machine_check: expected %d status 0x%lx\n",
- POLARIS_mcheck_expected, mchk_sysdata->psc_status));
-#endif
-#ifdef DEBUG_MCHECK_DUMP
- {
- unsigned long *ptr;
- int i;
-
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
- printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
- }
- }
-#endif /* DEBUG_MCHECK_DUMP */
- /*
- * Check if machine check is due to a badaddr() and if so,
- * ignore the machine check.
- */
+ /* Clear the error before any reporting. */
mb();
mb();
- if (POLARIS_mcheck_expected) {
- DBG_MCK(("POLARIS machine check expected\n"));
- POLARIS_mcheck_expected = 0;
- POLARIS_mcheck_taken = 1;
- mb();
- mb();
- draina();
- polaris_pci_clr_err();
- wrmces(0x7);
- mb();
- }
-#if 1
- else {
- printk("POLARIS machine check NOT expected\n") ;
- DBG_MCK(("polaris_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr));
- DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset));
- POLARIS_mcheck_expected = 0;
- POLARIS_mcheck_taken = 1;
- mb();
- mb();
- draina();
- polaris_pci_clr_err();
- wrmces(0x7);
- mb();
- }
-#endif
+ draina();
+ polaris_pci_clr_err();
+ wrmces(0x7);
+ mb();
+
+ process_mcheck_info(vector, la_ptr, regs, "POLARIS",
+ mcheck_expected(0));
}
diff --git a/arch/alpha/kernel/core_pyxis.c b/arch/alpha/kernel/core_pyxis.c
index f0a5c3eb8..88a3e37c9 100644
--- a/arch/alpha/kernel/core_pyxis.c
+++ b/arch/alpha/kernel/core_pyxis.c
@@ -1,12 +1,11 @@
/*
* linux/arch/alpha/kernel/core_pyxis.c
*
- * Code common to all PYXIS core logic chips.
- *
* Based on code written by David A Rusling (david.rusling@reo.mts.dec.com).
*
+ * Code common to all PYXIS core logic chips.
*/
-#include <linux/config.h>
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
@@ -15,6 +14,7 @@
#include <asm/ptrace.h>
#include <asm/system.h>
+#include <asm/pci.h>
#define __EXTERN_INLINE inline
#include <asm/io.h>
@@ -22,6 +22,8 @@
#undef __EXTERN_INLINE
#include "proto.h"
+#include "pci_impl.h"
+
/* NOTE: Herein are back-to-back mb instructions. They are magic.
One plausible explanation is that the I/O controller does not properly
@@ -32,7 +34,6 @@
*/
#define DEBUG_CONFIG 0
-#define DEBUG_MCHECK 0
#if DEBUG_CONFIG
# define DBG_CNF(args) printk args
@@ -40,18 +41,6 @@
# define DBG_CNF(args)
#endif
-#if DEBUG_MCHECK
-# define DBG_MCK(args) printk args
-# define DEBUG_MCHECK_DUMP
-#else
-# define DBG_MCK(args)
-#endif
-
-
-static volatile unsigned int PYXIS_mcheck_expected = 0;
-static volatile unsigned int PYXIS_mcheck_taken = 0;
-static unsigned int PYXIS_jd;
-
/*
* Given a bus, device, and function number, compute resulting
@@ -96,9 +85,12 @@ static unsigned int PYXIS_jd;
*/
static int
-mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
+
*type1 = (bus == 0) ? 0 : 1;
*pci_addr = (bus << 16) | (device_fn << 8) | (where);
@@ -132,8 +124,8 @@ conf_read(unsigned long addr, unsigned char type1)
mb();
draina();
- PYXIS_mcheck_expected = 1;
- PYXIS_mcheck_taken = 0;
+ mcheck_expected(0) = 1;
+ mcheck_taken(0) = 0;
mb();
/* Access configuration space. */
@@ -141,12 +133,12 @@ conf_read(unsigned long addr, unsigned char type1)
mb();
mb(); /* magic */
- if (PYXIS_mcheck_taken) {
- PYXIS_mcheck_taken = 0;
+ if (mcheck_taken(0)) {
+ mcheck_taken(0) = 0;
value = 0xffffffffU;
mb();
}
- PYXIS_mcheck_expected = 0;
+ mcheck_expected(0) = 0;
mb();
/* If Type1 access, must reset IOC CFG so normal IO space ops work. */
@@ -186,15 +178,15 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
mb();
draina();
- PYXIS_mcheck_expected = 1;
- PYXIS_mcheck_taken = 0;
+ mcheck_expected(0) = 1;
+ mcheck_taken(0) = 0;
mb();
/* Access configuration space. */
*(vuip)addr = value;
mb();
temp = *(vuip)addr; /* read back to force the write */
- PYXIS_mcheck_expected = 0;
+ mcheck_expected(0) = 0;
mb();
/* If Type1 access, must reset IOC CFG so normal IO space ops work. */
@@ -209,106 +201,95 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
addr, value, type1));
}
-int
-pyxis_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
- struct linux_hose_info *hose)
+static int
+pyxis_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- unsigned long addr = PYXIS_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
+ addr = (pci_addr << 5) + 0x00 + PYXIS_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
-int
-pyxis_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
- struct linux_hose_info *hose)
+static int
+pyxis_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- unsigned long addr = PYXIS_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x08;
+ addr = (pci_addr << 5) + 0x08 + PYXIS_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
-int
-pyxis_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
- struct linux_hose_info *hose)
+static int
+pyxis_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- unsigned long addr = PYXIS_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x18;
+ addr = (pci_addr << 5) + 0x18 + PYXIS_CONF;
*value = conf_read(addr, type1);
return PCIBIOS_SUCCESSFUL;
}
-int
-pyxis_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
- struct linux_hose_info *hose)
+static int
+pyxis_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
- unsigned long addr = PYXIS_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
+ addr = (pci_addr << 5) + mask + PYXIS_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
}
-int
-pyxis_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
- struct linux_hose_info *hose)
+static int
+pyxis_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
- unsigned long addr = PYXIS_CONF;
- unsigned long pci_addr;
- unsigned char type1;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr |= (pci_addr << 5) + 0x08;
- conf_write(addr, value << ((where & 3) * 8), type1);
- return PCIBIOS_SUCCESSFUL;
+ return pyxis_write_config(dev, where, value, 0x00);
}
-int
-pyxis_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
- struct linux_hose_info *hose)
+static int
+pyxis_write_config_word(struct pci_dev *dev, int where, u16 value)
{
- unsigned long addr = PYXIS_CONF;
- unsigned long pci_addr;
- unsigned char type1;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ return pyxis_write_config(dev, where, value, 0x08);
+}
- addr |= (pci_addr << 5) + 0x18;
- conf_write(addr, value << ((where & 3) * 8), type1);
- return PCIBIOS_SUCCESSFUL;
+static int
+pyxis_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ return pyxis_write_config(dev, where, value, 0x18);
}
+struct pci_ops pyxis_pci_ops =
+{
+ read_byte: pyxis_read_config_byte,
+ read_word: pyxis_read_config_word,
+ read_dword: pyxis_read_config_dword,
+ write_byte: pyxis_write_config_byte,
+ write_word: pyxis_write_config_word,
+ write_dword: pyxis_write_config_dword
+};
+
void __init
-pyxis_enable_errors (void)
+pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
{
- unsigned int pyxis_err;
+ struct pci_controler *hose;
+ unsigned int temp;
#if 0
printk("pyxis_init: PYXIS_ERR_MASK 0x%x\n", *(vuip)PYXIS_ERR_MASK);
@@ -324,126 +305,37 @@ pyxis_enable_errors (void)
/*
* Set up error reporting. Make sure CPU_PE is OFF in the mask.
*/
- pyxis_err = *(vuip)PYXIS_ERR_MASK;
- pyxis_err &= ~4;
- *(vuip)PYXIS_ERR_MASK = pyxis_err; mb();
- pyxis_err = *(vuip)PYXIS_ERR_MASK; /* re-read to force write */
-
- pyxis_err = *(vuip)PYXIS_ERR ;
- pyxis_err |= 0x180; /* master/target abort */
- *(vuip)PYXIS_ERR = pyxis_err; mb();
- pyxis_err = *(vuip)PYXIS_ERR; /* re-read to force write */
-}
+ temp = *(vuip)PYXIS_ERR_MASK;
+ temp &= ~4;
+ *(vuip)PYXIS_ERR_MASK = temp; mb();
+ temp = *(vuip)PYXIS_ERR_MASK; /* re-read to force write */
-int __init
-pyxis_srm_window_setup (void)
-{
- switch (alpha_use_srm_setup)
- {
- default:
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
- /* Check window 0 for enabled and mapped to 0. */
- if (((*(vuip)PYXIS_W0_BASE & 3) == 1)
- && (*(vuip)PYXIS_T0_BASE == 0)
- && ((*(vuip)PYXIS_W0_MASK & 0xfff00000U) > 0x0ff00000U)) {
- PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W0_BASE & 0xfff00000U;
- PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W0_MASK & 0xfff00000U;
- PYXIS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("pyxis_init: using Window 0 settings\n");
- printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)PYXIS_W0_BASE,
- *(vuip)PYXIS_W0_MASK,
- *(vuip)PYXIS_T0_BASE);
-#endif
- break;
- }
-
- /* Check window 1 for enabled and mapped to 0. */
- if (((*(vuip)PYXIS_W1_BASE & 3) == 1)
- && (*(vuip)PYXIS_T1_BASE == 0)
- && ((*(vuip)PYXIS_W1_MASK & 0xfff00000U) > 0x0ff00000U)) {
- PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W1_BASE & 0xfff00000U;
- PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W1_MASK & 0xfff00000U;
- PYXIS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("pyxis_init: using Window 1 settings\n");
- printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)PYXIS_W1_BASE,
- *(vuip)PYXIS_W1_MASK,
- *(vuip)PYXIS_T1_BASE);
-#endif
- break;
- }
+ temp = *(vuip)PYXIS_ERR ;
+ temp |= 0x180; /* master/target abort */
+ *(vuip)PYXIS_ERR = temp; mb();
+ temp = *(vuip)PYXIS_ERR; /* re-read to force write */
- /* Check window 2 for enabled and mapped to 0. */
- if (((*(vuip)PYXIS_W2_BASE & 3) == 1)
- && (*(vuip)PYXIS_T2_BASE == 0)
- && ((*(vuip)PYXIS_W2_MASK & 0xfff00000U) > 0x0ff00000U)) {
- PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W2_BASE & 0xfff00000U;
- PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W2_MASK & 0xfff00000U;
- PYXIS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("pyxis_init: using Window 2 settings\n");
- printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)PYXIS_W2_BASE,
- *(vuip)PYXIS_W2_MASK,
- *(vuip)PYXIS_T2_BASE);
-#endif
- break;
- }
-
- /* Check window 3 for enabled and mapped to 0. */
- if (((*(vuip)PYXIS_W3_BASE & 3) == 1)
- && (*(vuip)PYXIS_T3_BASE == 0)
- && ((*(vuip)PYXIS_W3_MASK & 0xfff00000U) > 0x0ff00000U)) {
- PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W3_BASE & 0xfff00000U;
- PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W3_MASK & 0xfff00000U;
- PYXIS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
- printk("pyxis_init: using Window 3 settings\n");
- printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
- *(vuip)PYXIS_W3_BASE,
- *(vuip)PYXIS_W3_MASK,
- *(vuip)PYXIS_T3_BASE);
-#endif
- break;
- }
-
- /* Otherwise, we must use our defaults. */
- PYXIS_DMA_WIN_BASE = PYXIS_DMA_WIN_BASE_DEFAULT;
- PYXIS_DMA_WIN_SIZE = PYXIS_DMA_WIN_SIZE_DEFAULT;
-#endif
- case 0:
- return 0;
- }
- return 1;
-}
-
-void __init
-pyxis_native_window_setup(void)
-{
/*
* Set up the PCI->physical memory translation windows.
- * For now, windows 1,2 and 3 are disabled. In the future, we may
+ * For now, windows 2 and 3 are disabled. In the future, we may
* want to use them to do scatter/gather DMA.
*
- * Window 0 goes at 1 GB and is 1 GB large.
+ * Window 0 goes at 2 GB and is 1 GB large.
+ * Window 1 goes at 3 GB and is 1 GB large.
*/
- *(vuip)PYXIS_W0_BASE = 1U | (PYXIS_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
- *(vuip)PYXIS_W0_MASK = (PYXIS_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U;
- *(vuip)PYXIS_T0_BASE = 0;
+ *(vuip)PYXIS_W0_BASE = PYXIS_DMA_WIN0_BASE_DEFAULT | 1U;
+ *(vuip)PYXIS_W0_MASK = (PYXIS_DMA_WIN0_SIZE_DEFAULT - 1) & 0xfff00000U;
+ *(vuip)PYXIS_T0_BASE = PYXIS_DMA_WIN0_TRAN_DEFAULT >> 2;
+
+ *(vuip)PYXIS_W1_BASE = PYXIS_DMA_WIN1_BASE_DEFAULT | 1U;
+ *(vuip)PYXIS_W1_MASK = (PYXIS_DMA_WIN1_SIZE_DEFAULT - 1) & 0xfff00000U;
+ *(vuip)PYXIS_T1_BASE = PYXIS_DMA_WIN1_TRAN_DEFAULT >> 2;
- *(vuip)PYXIS_W1_BASE = 0x0 ;
- *(vuip)PYXIS_W2_BASE = 0x0 ;
- *(vuip)PYXIS_W3_BASE = 0x0 ;
+ *(vuip)PYXIS_W2_BASE = 0x0;
+ *(vuip)PYXIS_W3_BASE = 0x0;
mb();
-}
-void __init
-pyxis_finish_init_arch(void)
-{
/*
* Next, clear the PYXIS_CFG register, which gets used
* for PCI Config Space accesses. That is the way
@@ -462,42 +354,11 @@ pyxis_finish_init_arch(void)
}
}
- /*
- * Sigh... For the SRM setup, unless we know apriori what the HAE
- * contents will be, we need to setup the arbitrary region bases
- * so we can test against the range of addresses and tailor the
- * region chosen for the SPARSE memory access.
- *
- * See include/asm-alpha/pyxis.h for the SPARSE mem read/write.
- */
- if (alpha_use_srm_setup) {
- unsigned int pyxis_hae_mem = *(vuip)PYXIS_HAE_MEM;
-
- alpha_mv.sm_base_r1 = (pyxis_hae_mem ) & 0xe0000000UL;
- alpha_mv.sm_base_r2 = (pyxis_hae_mem << 16) & 0xf8000000UL;
- alpha_mv.sm_base_r3 = (pyxis_hae_mem << 24) & 0xfc000000UL;
-
- /*
- * Set the HAE cache, so that setup_arch() code
- * will use the SRM setting always. Our readb/writeb
- * code in pyxis.h expects never to have to change
- * the contents of the HAE.
- */
- alpha_mv.hae_cache = pyxis_hae_mem;
-
-#ifndef CONFIG_ALPHA_GENERIC
- /* In a generic kernel, we can always use BWIO. */
- alpha_mv.mv_readb = pyxis_srm_readb;
- alpha_mv.mv_readw = pyxis_srm_readw;
- alpha_mv.mv_writeb = pyxis_srm_writeb;
- alpha_mv.mv_writew = pyxis_srm_writew;
-#endif
- } else {
- *(vuip)PYXIS_HAE_MEM = 0U; mb();
- *(vuip)PYXIS_HAE_MEM; /* re-read to force write */
- *(vuip)PYXIS_HAE_IO = 0; mb();
- *(vuip)PYXIS_HAE_IO; /* re-read to force write */
- }
+ /* Zero the HAE. */
+ *(vuip)PYXIS_HAE_MEM = 0U; mb();
+ *(vuip)PYXIS_HAE_MEM; /* re-read to force write */
+ *(vuip)PYXIS_HAE_IO = 0; mb();
+ *(vuip)PYXIS_HAE_IO; /* re-read to force write */
/*
* Finally, check that the PYXIS_CTRL1 has IOA_BEN set for
@@ -514,94 +375,38 @@ pyxis_finish_init_arch(void)
ctrl1 = *(vuip)PYXIS_CTRL1; /* re-read */
}
}
-}
-void __init
-pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
-{
- pyxis_enable_errors();
- if (!pyxis_srm_window_setup())
- pyxis_native_window_setup();
- pyxis_finish_init_arch();
+ /*
+ * Create our single hose.
+ */
+
+ hose = alloc_pci_controler(mem_start);
+ hose->io_space = &ioport_resource;
+ hose->mem_space = &iomem_resource;
+ hose->config_space = PYXIS_CONF;
+ hose->index = 0;
}
-static int
+static inline void
pyxis_pci_clr_err(void)
{
- PYXIS_jd = *(vuip)PYXIS_ERR;
- DBG_MCK(("PYXIS_pci_clr_err: PYXIS ERR after read 0x%x\n", PYXIS_jd));
- *(vuip)PYXIS_ERR = 0x0180; mb();
- PYXIS_jd = *(vuip)PYXIS_ERR; /* re-read to force write */
- return 0;
+ *(vuip)PYXIS_ERR;
+ *(vuip)PYXIS_ERR = 0x0180;
+ mb();
+ *(vuip)PYXIS_ERR; /* re-read to force write */
}
void
pyxis_machine_check(unsigned long vector, unsigned long la_ptr,
struct pt_regs * regs)
{
- struct el_common *mchk_header;
- struct el_PYXIS_sysdata_mcheck *mchk_sysdata;
-
- mchk_header = (struct el_common *)la_ptr;
-
- mchk_sysdata = (struct el_PYXIS_sysdata_mcheck *)
- (la_ptr + mchk_header->sys_offset);
-
-#if 0
- DBG_MCK(("pyxis_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr));
- DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset));
- DBG_MCK(("pyxis_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
- PYXIS_mcheck_expected, mchk_sysdata->epic_dcsr,
- mchk_sysdata->epic_pear));
-#endif
-
- /*
- * Check if machine check is due to a badaddr() and if so,
- * ignore the machine check.
- */
+ /* Clear the error before reporting anything. */
mb();
mb(); /* magic */
- if (PYXIS_mcheck_expected) {
- DBG_MCK(("PYXIS machine check expected\n"));
- PYXIS_mcheck_expected = 0;
- PYXIS_mcheck_taken = 1;
- mb();
- mb(); /* magic */
- draina();
- pyxis_pci_clr_err();
- wrmces(0x7);
- mb();
- }
- else {
- printk("PYXIS machine check NOT expected\n") ;
- DBG_MCK(("pyxis_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr));
- DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x"
- " sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset));
- PYXIS_mcheck_expected = 0;
- PYXIS_mcheck_taken = 1;
- mb();
- mb(); /* magic */
- draina();
- pyxis_pci_clr_err();
- wrmces(0x7);
- mb();
-
-#ifdef DEBUG_MCHECK_DUMP
- {
- unsigned long *ptr = (unsigned long *)la_ptr;;
- long n = mchk_header->size / (2*sizeof(long));
+ draina();
+ pyxis_pci_clr_err();
+ wrmces(0x7);
+ mb();
- do
- printk(" +%lx %lx %lx\n", i*sizeof(long),
- ptr[i], ptr[i+1]);
- while (--i);
- }
-#endif
- }
+ process_mcheck_info(vector, la_ptr, regs, "PYXIS", mcheck_expected(0));
}
diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c
index c7ec2b6ee..43103f8eb 100644
--- a/arch/alpha/kernel/core_t2.c
+++ b/arch/alpha/kernel/core_t2.c
@@ -1,15 +1,14 @@
/*
* linux/arch/alpha/kernel/core_t2.c
*
- * Code common to all T2 core logic chips.
- *
* Written by Jay A Estabrook (jestabro@amt.tay1.dec.com).
* December 1996.
*
* based on CIA code by David A Rusling (david.rusling@reo.mts.dec.com)
*
+ * Code common to all T2 core logic chips.
*/
-#include <linux/config.h>
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
@@ -18,6 +17,7 @@
#include <asm/ptrace.h>
#include <asm/system.h>
+#include <asm/pci.h>
#define __EXTERN_INLINE
#include <asm/io.h>
@@ -25,6 +25,8 @@
#undef __EXTERN_INLINE
#include "proto.h"
+#include "pci_impl.h"
+
/*
* NOTE: Herein lie back-to-back mb instructions. They are magic.
@@ -33,36 +35,17 @@
*/
/*
- * Machine check reasons. Defined according to PALcode sources
- * (osf.h and platform.h).
- */
-#define MCHK_K_TPERR 0x0080
-#define MCHK_K_TCPERR 0x0082
-#define MCHK_K_HERR 0x0084
-#define MCHK_K_ECC_C 0x0086
-#define MCHK_K_ECC_NC 0x0088
-#define MCHK_K_OS_BUGCHECK 0x008A
-#define MCHK_K_PAL_BUGCHECK 0x0090
-
-/*
* BIOS32-style PCI interface:
*/
-#ifdef DEBUG_CONF
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
# define DBG(args) printk args
#else
# define DBG(args)
#endif
-#ifdef DEBUG_MCHECK
-# define DBGMC(args) printk args
-#else
-# define DBGMC(args)
-#endif
-
-static volatile unsigned int T2_mcheck_expected[NR_CPUS];
-static volatile unsigned int T2_mcheck_taken[NR_CPUS];
-
/*
* Given a bus, device, and function number, compute resulting
@@ -107,10 +90,12 @@ static volatile unsigned int T2_mcheck_taken[NR_CPUS];
*/
static int
-mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
unsigned long addr;
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
DBG(("mk_conf_addr(bus=%d, dfn=0x%x, where=0x%x,"
" addr=0x%lx, type1=0x%x)\n",
@@ -173,8 +158,8 @@ conf_read(unsigned long addr, unsigned char type1)
mb();
draina();
- T2_mcheck_expected[cpu] = 1;
- T2_mcheck_taken[cpu] = 0;
+ mcheck_expected(cpu) = 1;
+ mcheck_taken(cpu) = 0;
mb();
/* Access configuration space. */
@@ -182,12 +167,12 @@ conf_read(unsigned long addr, unsigned char type1)
mb();
mb(); /* magic */
- if (T2_mcheck_taken[cpu]) {
- T2_mcheck_taken[cpu] = 0;
+ if (mcheck_taken(cpu)) {
+ mcheck_taken(cpu) = 0;
value = 0xffffffffU;
mb();
}
- T2_mcheck_expected[cpu] = 0;
+ mcheck_expected(cpu) = 0;
mb();
/* If Type1 access, must reset T2 CFG so normal IO space ops work. */
@@ -233,7 +218,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
mb();
draina();
- T2_mcheck_expected[cpu] = 1;
+ mcheck_expected(cpu) = 1;
mb();
/* Access configuration space. */
@@ -241,7 +226,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
mb();
mb(); /* magic */
- T2_mcheck_expected[cpu] = 0;
+ mcheck_expected(cpu) = 0;
mb();
/* If Type1 access, must reset T2 CFG so normal IO space ops work. */
@@ -253,110 +238,99 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
__restore_flags(flags);
}
-int
-t2_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
- struct linux_hose_info *hose)
+static int
+t2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- unsigned long addr = T2_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
+ addr = (pci_addr << 5) + 0x00 + T2_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
-int
-t2_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
- struct linux_hose_info *hose)
+static int
+t2_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- unsigned long addr = T2_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x08;
+ addr = (pci_addr << 5) + 0x08 + T2_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
-int
-t2_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
- struct linux_hose_info *hose)
+static int
+t2_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- unsigned long addr = T2_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x18;
+ addr = (pci_addr << 5) + 0x18 + T2_CONF;
*value = conf_read(addr, type1);
return PCIBIOS_SUCCESSFUL;
}
-int
-t2_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
- struct linux_hose_info *hose)
+static int
+t2_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
- unsigned long addr = T2_CONF;
- unsigned long pci_addr;
+ unsigned long addr, pci_addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+ if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= (pci_addr << 5) + 0x00;
+ addr = (pci_addr << 5) + mask + T2_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
}
-int
-t2_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
- struct linux_hose_info *hose)
+static int
+t2_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
- unsigned long addr = T2_CONF;
- unsigned long pci_addr;
- unsigned char type1;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr |= (pci_addr << 5) + 0x08;
- conf_write(addr, value << ((where & 3) * 8), type1);
- return PCIBIOS_SUCCESSFUL;
+ return t2_write_config(dev, where, value, 0x00);
}
-int
-t2_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
- struct linux_hose_info *hose)
+static int
+t2_write_config_word(struct pci_dev *dev, int where, u16 value)
{
- unsigned long addr = T2_CONF;
- unsigned long pci_addr;
- unsigned char type1;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ return t2_write_config(dev, where, value, 0x08);
+}
- addr |= (pci_addr << 5) + 0x18;
- conf_write(addr, value << ((where & 3) * 8), type1);
- return PCIBIOS_SUCCESSFUL;
+static int
+t2_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ return t2_write_config(dev, where, value, 0x18);
}
+struct pci_ops t2_pci_ops =
+{
+ read_byte: t2_read_config_byte,
+ read_word: t2_read_config_word,
+ read_dword: t2_read_config_dword,
+ write_byte: t2_write_config_byte,
+ write_word: t2_write_config_word,
+ write_dword: t2_write_config_dword
+};
+
void __init
t2_init_arch(unsigned long *mem_start, unsigned long *mem_end)
{
+ struct pci_controler *hose;
unsigned int i;
for (i = 0; i < NR_CPUS; i++) {
- T2_mcheck_expected[i] = 0;
- T2_mcheck_taken[i] = 0;
+ mcheck_expected(i) = 0;
+ mcheck_taken(i) = 0;
}
#if 0
@@ -383,125 +357,59 @@ t2_init_arch(unsigned long *mem_start, unsigned long *mem_end)
*(vulp)T2_TBASE2);
#endif
- switch (alpha_use_srm_setup)
- {
- default:
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
- /* Check window 1 for enabled and mapped to 0. */
- if (((*(vulp)T2_WBASE1 & (3UL<<18)) == (2UL<<18))
- && (*(vulp)T2_TBASE1 == 0)) {
- T2_DMA_WIN_BASE = *(vulp)T2_WBASE1 & 0xfff00000UL;
- T2_DMA_WIN_SIZE = *(vulp)T2_WMASK1 & 0xfff00000UL;
- T2_DMA_WIN_SIZE += 0x00100000UL;
- /* DISABLE window 2!! ?? */
-#if 1
- printk("t2_init: using Window 1 settings\n");
- printk("t2_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
- *(vulp)T2_WBASE1,
- *(vulp)T2_WMASK1,
- *(vulp)T2_TBASE1);
-#endif
- break;
- }
+ /*
+ * Set up the PCI->physical memory translation windows.
+ * For now, window 2 is disabled. In the future, we may
+ * want to use it to do scatter/gather DMA.
+ *
+ * Window 1 goes at 1 GB and is 1 GB large.
+ */
- /* Check window 2 for enabled and mapped to 0. */
- if (((*(vulp)T2_WBASE2 & (3UL<<18)) == (2UL<<18))
- && (*(vulp)T2_TBASE2 == 0)) {
- T2_DMA_WIN_BASE = *(vulp)T2_WBASE2 & 0xfff00000UL;
- T2_DMA_WIN_SIZE = *(vulp)T2_WMASK2 & 0xfff00000UL;
- T2_DMA_WIN_SIZE += 0x00100000UL;
- /* DISABLE window 1!! ?? */
-#if 1
- printk("t2_init: using Window 2 settings\n");
- printk("t2_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
- *(vulp)T2_WBASE2,
- *(vulp)T2_WMASK2,
- *(vulp)T2_TBASE2);
-#endif
- break;
- }
+ /* WARNING!! must correspond to the DMA_WIN params!!! */
+ *(vulp)T2_WBASE1 = 0x400807ffU;
+ *(vulp)T2_WMASK1 = 0x3ff00000U;
+ *(vulp)T2_TBASE1 = 0;
+
+ *(vulp)T2_WBASE2 = 0x0;
+ *(vulp)T2_HBASE = 0x0;
- /* Otherwise, we must use our defaults. */
- T2_DMA_WIN_BASE = T2_DMA_WIN_BASE_DEFAULT;
- T2_DMA_WIN_SIZE = T2_DMA_WIN_SIZE_DEFAULT;
+ /* Zero HAE. */
+ *(vulp)T2_HAE_1 = 0; mb();
+ *(vulp)T2_HAE_2 = 0; mb();
+ *(vulp)T2_HAE_3 = 0; mb();
+#if 0
+ *(vulp)T2_HAE_4 = 0; mb(); /* do not touch this */
#endif
- case 0:
- /*
- * Set up the PCI->physical memory translation windows.
- * For now, window 2 is disabled. In the future, we may
- * want to use it to do scatter/gather DMA.
- *
- * Window 1 goes at 1 GB and is 1 GB large.
- */
-
- /* WARNING!! must correspond to the DMA_WIN params!!! */
- *(vulp)T2_WBASE1 = 0x400807ffU;
- *(vulp)T2_WMASK1 = 0x3ff00000U;
- *(vulp)T2_TBASE1 = 0;
-
- *(vulp)T2_WBASE2 = 0x0;
- *(vulp)T2_HBASE = 0x0;
- break;
- }
/*
- * Sigh... For the SRM setup, unless we know apriori what the HAE
- * contents will be, we need to setup the arbitrary region bases
- * so we can test against the range of addresses and tailor the
- * region chosen for the SPARSE memory access.
- *
- * See include/asm-alpha/t2.h for the SPARSE mem read/write.
+ * Create our single hose.
*/
- if (alpha_use_srm_setup) {
- unsigned long t2_hae_1 = *(vulp)T2_HAE_1;
-
- alpha_mv.sm_base_r1 = (t2_hae_1 << 27) & 0xf8000000UL;
-
- /*
- * Set the HAE cache, so that setup_arch() code
- * will use the SRM setting always. Our readb/writeb
- * code in .h expects never to have to change
- * the contents of the HAE.
- */
- alpha_mv.hae_cache = t2_hae_1;
-
- alpha_mv.mv_readb = t2_srm_readb;
- alpha_mv.mv_readw = t2_srm_readw;
- alpha_mv.mv_writeb = t2_srm_writeb;
- alpha_mv.mv_writew = t2_srm_writew;
- } else {
- *(vulp)T2_HAE_1 = 0; mb();
- *(vulp)T2_HAE_2 = 0; mb();
- *(vulp)T2_HAE_3 = 0; mb();
-#if 0
- *(vulp)T2_HAE_4 = 0; mb(); /* do not touch this */
-#endif
- }
+
+ hose = alloc_pci_controler(mem_start);
+ hose->io_space = &ioport_resource;
+ hose->mem_space = &iomem_resource;
+ hose->config_space = T2_CONF;
+ hose->index = 0;
}
#define SIC_SEIC (1UL << 33) /* System Event Clear */
-static int
-t2_clear_errors(void)
+static void
+t2_clear_errors(int cpu)
{
- unsigned int cpu = smp_processor_id();
- static struct sable_cpu_csr *cpu_regs = NULL;
-
- switch (cpu)
- {
- case 0: cpu_regs = (struct sable_cpu_csr *)T2_CPU0_BASE; break;
- case 1: cpu_regs = (struct sable_cpu_csr *)T2_CPU1_BASE; break;
- case 2: cpu_regs = (struct sable_cpu_csr *)T2_CPU2_BASE; break;
- case 3: cpu_regs = (struct sable_cpu_csr *)T2_CPU3_BASE; break;
- }
-
- DBGMC(("???????? t2_clear_errors\n"));
-
+ struct sable_cpu_csr *cpu_regs;
+
+ cpu_regs = (struct sable_cpu_csr *)T2_CPU0_BASE;
+ if (cpu == 1)
+ cpu_regs = (struct sable_cpu_csr *)T2_CPU1_BASE;
+ if (cpu == 2)
+ cpu_regs = (struct sable_cpu_csr *)T2_CPU2_BASE;
+ if (cpu == 3)
+ cpu_regs = (struct sable_cpu_csr *)T2_CPU3_BASE;
+
cpu_regs->sic &= ~SIC_SEIC;
- /*
- * clear CPU errors
- */
+ /* Clear CPU errors. */
cpu_regs->bcce |= cpu_regs->bcce;
cpu_regs->cbe |= cpu_regs->cbe;
cpu_regs->bcue |= cpu_regs->bcue;
@@ -512,116 +420,21 @@ t2_clear_errors(void)
mb();
mb(); /* magic */
- return 0;
}
void
t2_machine_check(unsigned long vector, unsigned long la_ptr,
struct pt_regs * regs)
{
- struct el_t2_logout_header *mchk_header;
- struct el_t2_procdata_mcheck *mchk_procdata;
- struct el_t2_sysdata_mcheck *mchk_sysdata;
- unsigned long * ptr;
- const char * reason;
- char buf[128];
- long i;
- unsigned int cpu = smp_processor_id();
-
- DBGMC(("t2_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr));
-
- mchk_header = (struct el_t2_logout_header *)la_ptr;
-
- DBGMC(("t2_machine_check: susoffset=0x%lx procoffset=0x%lx\n",
- mchk_header->elfl_sysoffset, mchk_header->elfl_procoffset));
-
- mchk_sysdata = (struct el_t2_sysdata_mcheck *)
- (la_ptr + mchk_header->elfl_sysoffset);
- mchk_procdata = (struct el_t2_procdata_mcheck *)
- (la_ptr + mchk_header->elfl_procoffset - sizeof(unsigned long)*32);
-
- DBGMC((" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->elfl_size, mchk_header->elfl_procoffset,
- mchk_header->elfl_sysoffset));
- DBGMC(("t2_machine_check: expected %d\n", T2_mcheck_expected[cpu]));
-
-#ifdef DEBUG_DUMP
- {
- unsigned long *ptr;
- int i;
+ int cpu = smp_processor_id();
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->elfl_size/sizeof(long); i += 2) {
- printk(" +%lx %lx %lx\n", i*sizeof(long),
- ptr[i], ptr[i+1]);
- }
- }
-#endif /* DEBUG_DUMP */
-
- /*
- * Check if machine check is due to a badaddr() and if so,
- * ignore the machine check.
- */
+ /* Clear the error before any reporting. */
mb();
mb(); /* magic */
- if (T2_mcheck_expected[cpu]) {
- DBGMC(("T2 machine check expected\n"));
- T2_mcheck_taken[cpu] = 1;
- t2_clear_errors();
- T2_mcheck_expected[cpu] = 0;
- mb();
- mb(); /* magic */
- wrmces(rdmces()|1);/* ??? */
- draina();
- return;
- }
-
- switch ((unsigned int) mchk_header->elfl_error_type) {
- case MCHK_K_TPERR: reason = "tag parity error"; break;
- case MCHK_K_TCPERR: reason = "tag control parity error"; break;
- case MCHK_K_HERR: reason = "generic hard error"; break;
- case MCHK_K_ECC_C: reason = "correctable ECC error"; break;
- case MCHK_K_ECC_NC: reason = "uncorrectable ECC error"; break;
- case MCHK_K_OS_BUGCHECK: reason = "OS-specific PAL bugcheck"; break;
- case MCHK_K_PAL_BUGCHECK: reason = "callsys in kernel mode"; break;
- case 0x96: reason = "i-cache read retryable error"; break;
- case 0x98: reason = "processor detected hard error"; break;
-
- /* System specific (these are for Alcor, at least): */
- case 0x203: reason = "system detected uncorrectable ECC error"; break;
- case 0x205: reason = "parity error detected by T2"; break;
- case 0x207: reason = "non-existent memory error"; break;
- case 0x209: reason = "PCI SERR detected"; break;
- case 0x20b: reason = "PCI data parity error detected"; break;
- case 0x20d: reason = "PCI address parity error detected"; break;
- case 0x20f: reason = "PCI master abort error"; break;
- case 0x211: reason = "PCI target abort error"; break;
- case 0x213: reason = "scatter/gather PTE invalid error"; break;
- case 0x215: reason = "flash ROM write error"; break;
- case 0x217: reason = "IOA timeout detected"; break;
- case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
- case 0x21b: reason = "EISA fail-safe timer timeout"; break;
- case 0x21d: reason = "EISA bus time-out"; break;
- case 0x21f: reason = "EISA software generated NMI"; break;
- case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
- default:
- sprintf(buf, "reason for machine-check unknown (0x%x)",
- (unsigned int) mchk_header->elfl_error_type);
- reason = buf;
- break;
- }
- wrmces(rdmces()|1); /* reset machine check pending flag */
+ draina();
+ t2_clear_errors(cpu);
+ wrmces(rdmces()|1); /* ??? */
mb();
- printk(KERN_CRIT " T2 machine check: %s%s\n",
- reason, mchk_header->elfl_retry ? " (retryable)" : "");
-
- /* Dump the logout area to give all info. */
-
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->elfl_size / sizeof(long); i += 2) {
- printk(KERN_CRIT " +%8lx %016lx %016lx\n",
- i*sizeof(long), ptr[i], ptr[i+1]);
- }
+ process_mcheck_info(vector, la_ptr, regs, "T2", mcheck_expected(cpu));
}
diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c
index efcce56d5..c0d7c867d 100644
--- a/arch/alpha/kernel/core_tsunami.c
+++ b/arch/alpha/kernel/core_tsunami.c
@@ -1,13 +1,11 @@
/*
* linux/arch/alpha/kernel/core_tsunami.c
*
- * Code common to all TSUNAMI core logic chips.
- *
* Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
*
+ * Code common to all TSUNAMI core logic chips.
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
@@ -17,6 +15,7 @@
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/pci.h>
+#include <asm/smp.h>
#define __EXTERN_INLINE inline
#include <asm/io.h>
@@ -24,7 +23,9 @@
#undef __EXTERN_INLINE
#include "proto.h"
-#include "bios32.h"
+#include "pci_impl.h"
+
+int TSUNAMI_bootcpu;
/*
* NOTE: Herein lie back-to-back mb instructions. They are magic.
@@ -36,24 +37,15 @@
* BIOS32-style PCI interface:
*/
-#ifdef DEBUG_CONFIG
+#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
# define DBG_CFG(args) printk args
#else
# define DBG_CFG(args)
#endif
-#define DEBUG_MCHECK
-#ifdef DEBUG_MCHECK
-# define DBG_MCK(args) printk args
-#define DEBUG_MCHECK_DUMP
-#else
-# define DBG_MCK(args)
-#endif
-
-static volatile unsigned int TSUNAMI_mcheck_expected[NR_CPUS];
-static volatile unsigned int TSUNAMI_mcheck_taken[NR_CPUS];
-static unsigned int TSUNAMI_jd[NR_CPUS];
-int TSUNAMI_bootcpu;
/*
* Given a bus, device, and function number, compute resulting
@@ -90,115 +82,118 @@ int TSUNAMI_bootcpu;
*/
static int
-mk_conf_addr(u8 bus, u8 device_fn, u8 where, struct linux_hose_info *hose,
- unsigned long *pci_addr, unsigned char *type1)
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
+ unsigned char *type1)
{
+ struct pci_controler *hose = dev->sysdata ? : probing_hose;
unsigned long addr;
-
- if (!pci_probe_enabled)
- return -1;
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
"pci_addr=0x%p, type1=0x%p)\n",
bus, device_fn, where, pci_addr, type1));
- *type1 = (bus != 0);
-
- if (hose->pci_first_busno == bus)
+ if (hose->first_busno == dev->bus->number)
bus = 0;
+ *type1 = (bus != 0);
addr = (bus << 16) | (device_fn << 8) | where;
- addr |= hose->pci_config_space;
+ addr |= hose->config_space;
*pci_addr = addr;
DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
return 0;
}
-int
-tsunami_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
- struct linux_hose_info *hose)
+static int
+tsunami_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
+ if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = __kernel_ldbu(*(vucp)addr);
return PCIBIOS_SUCCESSFUL;
}
-int
-tsunami_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
- struct linux_hose_info *hose)
+static int
+tsunami_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
+ if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = __kernel_ldwu(*(vusp)addr);
return PCIBIOS_SUCCESSFUL;
}
-int
-tsunami_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
- struct linux_hose_info *hose)
+static int
+tsunami_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
+ if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = *(vuip)addr;
return PCIBIOS_SUCCESSFUL;
}
-int
-tsunami_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
- struct linux_hose_info *hose)
+static int
+tsunami_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
+ if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stb(value, *(vucp)addr);
return PCIBIOS_SUCCESSFUL;
}
-int
-tsunami_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
- struct linux_hose_info *hose)
+static int
+tsunami_write_config_word(struct pci_dev *dev, int where, u16 value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
+ if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stw(value, *(vusp)addr);
return PCIBIOS_SUCCESSFUL;
}
-int
-tsunami_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
- struct linux_hose_info *hose)
+static int
+tsunami_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
+ if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*(vuip)addr = value;
return PCIBIOS_SUCCESSFUL;
}
+struct pci_ops tsunami_pci_ops =
+{
+ read_byte: tsunami_read_config_byte,
+ read_word: tsunami_read_config_word,
+ read_dword: tsunami_read_config_dword,
+ write_byte: tsunami_write_config_byte,
+ write_word: tsunami_write_config_word,
+ write_dword: tsunami_write_config_dword
+};
+
#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
static long
tsunami_probe_read(volatile unsigned long *vaddr)
@@ -207,13 +202,14 @@ tsunami_probe_read(volatile unsigned long *vaddr)
int cpu = smp_processor_id();
int s = swpipl(6); /* Block everything but machine checks. */
- TSUNAMI_mcheck_taken[cpu] = 0;
- TSUNAMI_mcheck_expected[cpu] = 1;
+ mcheck_taken(cpu) = 0;
+ mcheck_expected(cpu) = 1;
+ mb();
dont_care = *vaddr;
draina();
- TSUNAMI_mcheck_expected[cpu] = 0;
- probe_result = !TSUNAMI_mcheck_taken[cpu];
- TSUNAMI_mcheck_taken[cpu] = 0;
+ mcheck_expected(cpu) = 0;
+ probe_result = !mcheck_taken(cpu);
+ mcheck_taken(cpu) = 0;
setipl(s);
printk("dont_care == 0x%lx\n", dont_care);
@@ -251,77 +247,51 @@ static void __init
tsunami_init_one_pchip(tsunami_pchip *pchip, int index,
unsigned long *mem_start)
{
- struct linux_hose_info *hose;
- int i;
+ struct pci_controler *hose;
if (tsunami_probe_read(&pchip->pctl.csr) == 0)
return;
- hose = (struct linux_hose_info *)*mem_start;
- *mem_start = (unsigned long)(hose + 1);
- memset(hose, 0, sizeof(*hose));
-
- *hose_tail = hose;
- hose_tail = &hose->next;
-
- hose->pci_io_space = TSUNAMI_IO(index);
- hose->pci_mem_space = TSUNAMI_MEM(index);
- hose->pci_config_space = TSUNAMI_CONF(index);
- hose->pci_sparse_space = 0;
- hose->pci_hose_index = index;
-
- switch (alpha_use_srm_setup)
- {
- default:
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
- for (i = 0; i < 4; ++i) {
- if ((pchip->wsba[i].csr & 3) == 1
- && pchip->tba[i].csr == 0
- && (pchip->wsm[i].csr & 0xfff00000) > 0x0ff00000) {
- TSUNAMI_DMA_WIN_BASE = pchip->wsba[i].csr & 0xfff00000;
- TSUNAMI_DMA_WIN_SIZE = pchip->wsm[i].csr & 0xfff00000;
- TSUNAMI_DMA_WIN_SIZE += 0x00100000;
-#if 1
- printk("%s: using Window %d settings\n", FN, i);
- printk("%s: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
- FN, pchip->wsba[i].csr, pchip->wsm[i].csr,
- pchip->tba[i].csr);
-#endif
- goto found;
- }
- }
+ hose = alloc_pci_controler(mem_start);
+ hose->io_space = alloc_resource(mem_start);
+ hose->mem_space = alloc_resource(mem_start);
- /* Otherwise, we must use our defaults. */
- TSUNAMI_DMA_WIN_BASE = TSUNAMI_DMA_WIN_BASE_DEFAULT;
- TSUNAMI_DMA_WIN_SIZE = TSUNAMI_DMA_WIN_SIZE_DEFAULT;
-#endif
- case 0:
- /*
- * Set up the PCI->physical memory translation windows.
- * For now, windows 1,2 and 3 are disabled. In the future,
- * we may want to use them to do scatter/gather DMA.
- *
- * Window 0 goes at 1 GB and is 1 GB large, mapping to 0.
- */
-
- pchip->wsba[0].csr = 1L | (TSUNAMI_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
- pchip->wsm[0].csr = (TSUNAMI_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000UL;
- pchip->tba[0].csr = 0;
+ hose->config_space = TSUNAMI_CONF(index);
+ hose->index = index;
-#if 0
- pchip->wsba[1].csr = 0;
-#else
- /* make the second window at 2Gb for 1Gb mapping to 1Gb */
- pchip->wsba[1].csr = 1L | ((0x80000000U) & 0xfff00000U);
- pchip->wsm[1].csr = (0x40000000UL - 1) & 0xfff00000UL;
- pchip->tba[1].csr = 0x40000000;
-#endif
+ hose->io_space->start = TSUNAMI_IO(index) - TSUNAMI_IO_BIAS;
+ hose->io_space->end = hose->io_space->start + 0xffff;
+ hose->io_space->name = pci_io_names[index];
- pchip->wsba[2].csr = 0;
- pchip->wsba[3].csr = 0;
- mb();
- }
-found:;
+ hose->mem_space->start = TSUNAMI_MEM(index) - TSUNAMI_MEM_BIAS;
+ hose->mem_space->end = hose->mem_space->start + 0xffffffff;
+ hose->mem_space->name = pci_mem_names[index];
+
+ request_resource(&ioport_resource, hose->io_space);
+ request_resource(&iomem_resource, hose->mem_space);
+
+ /*
+ * Set up the PCI->physical memory translation windows.
+ * For now, windows 1,2 and 3 are disabled. In the future,
+ * we may want to use them to do scatter/gather DMA.
+ *
+ * Window 0 goes at 1 GB and is 1 GB large, mapping to 0.
+ * Window 1 goes at 2 GB and is 1 GB large, mapping to 1GB.
+ */
+
+ pchip->wsba[0].csr = TSUNAMI_DMA_WIN0_BASE_DEFAULT | 1UL;
+ pchip->wsm[0].csr = (TSUNAMI_DMA_WIN0_SIZE_DEFAULT - 1) &
+ 0xfff00000UL;
+ pchip->tba[0].csr = TSUNAMI_DMA_WIN0_TRAN_DEFAULT;
+
+ pchip->wsba[1].csr = TSUNAMI_DMA_WIN1_BASE_DEFAULT | 1UL;
+ pchip->wsm[1].csr = (TSUNAMI_DMA_WIN1_SIZE_DEFAULT - 1) &
+ 0xfff00000UL;
+ pchip->tba[1].csr = TSUNAMI_DMA_WIN1_TRAN_DEFAULT;
+
+ pchip->wsba[2].csr = 0;
+ pchip->wsba[3].csr = 0;
+ mb();
}
void __init
@@ -360,111 +330,53 @@ tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
printk("%s: CSR_STR 0x%lx\n", FN, TSUNAMI_dchip->str.csr);
printk("%s: CSR_DREV 0x%lx\n", FN, TSUNAMI_dchip->drev.csr);
#endif
+ TSUNAMI_bootcpu = __hard_smp_processor_id();
- /* Align memory to cache line; we'll be allocating from it. */
- *mem_start = (*mem_start | 31) + 1;
+ /* With multiple PCI busses, we play with I/O as physical addrs. */
+ ioport_resource.end = ~0UL;
+ iomem_resource.end = ~0UL;
+
+ /* Find how many hoses we have, and initialize them. TSUNAMI
+ and TYPHOON can have 2, but might only have 1 (DS10). */
- /* Find how many hoses we have, and initialize them. */
tsunami_init_one_pchip(TSUNAMI_pchip0, 0, mem_start);
- /* must change this for TYPHOON which may have 4 */
if (TSUNAMI_cchip->csc.csr & 1L<<14)
- tsunami_init_one_pchip(TSUNAMI_pchip1, 1, mem_start);
+ tsunami_init_one_pchip(TSUNAMI_pchip1, 1, mem_start);
}
static inline void
-tsunami_pci_clr_err_1(tsunami_pchip *pchip, int cpu)
+tsunami_pci_clr_err_1(tsunami_pchip *pchip)
{
- TSUNAMI_jd[cpu] = pchip->perror.csr;
- DBG_MCK(("TSUNAMI_pci_clr_err: PERROR after read 0x%x\n",
- TSUNAMI_jd[cpu]));
+ unsigned int jd;
+
+ jd = pchip->perror.csr;
pchip->perror.csr = 0x040;
mb();
- TSUNAMI_jd[cpu] = pchip->perror.csr;
+ jd = pchip->perror.csr;
}
-static int
+static inline void
tsunami_pci_clr_err(void)
{
- int cpu = smp_processor_id();
- tsunami_pci_clr_err_1(TSUNAMI_pchip0, cpu);
- /* must change this for TYPHOON which may have 4 */
+ tsunami_pci_clr_err_1(TSUNAMI_pchip0);
+
+ /* TSUNAMI and TYPHOON can have 2, but might only have 1 (DS10) */
if (TSUNAMI_cchip->csc.csr & 1L<<14)
- tsunami_pci_clr_err_1(TSUNAMI_pchip1, cpu);
- return 0;
+ tsunami_pci_clr_err_1(TSUNAMI_pchip1);
}
void
tsunami_machine_check(unsigned long vector, unsigned long la_ptr,
struct pt_regs * regs)
{
-#if 0
- printk("TSUNAMI machine check ignored\n") ;
-#else
- struct el_common *mchk_header;
- struct el_TSUNAMI_sysdata_mcheck *mchk_sysdata;
- unsigned int cpu = smp_processor_id();
-
- mb();
- mchk_header = (struct el_common *)la_ptr;
-
- mchk_sysdata = (struct el_TSUNAMI_sysdata_mcheck *)
- (la_ptr + mchk_header->sys_offset);
-
-#if 0
- DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr));
- DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset));
- DBG_MCK(("tsunami_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
- TSUNAMI_mcheck_expected[cpu], mchk_sysdata->epic_dcsr,
- mchk_sysdata->epic_pear));
-#endif
-#ifdef DEBUG_MCHECK_DUMP
- {
- unsigned long *ptr;
- int i;
-
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
- printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
- }
- }
-#endif /* DEBUG_MCHECK_DUMP */
- /*
- * Check if machine check is due to a badaddr() and if so,
- * ignore the machine check.
- */
+ /* Clear error before any reporting. */
mb();
mb(); /* magic */
- if (TSUNAMI_mcheck_expected[cpu]) {
- DBG_MCK(("TSUNAMI machine check expected\n"));
- TSUNAMI_mcheck_expected[cpu] = 0;
- TSUNAMI_mcheck_taken[cpu] = 1;
- mb();
- mb(); /* magic */
- draina();
- tsunami_pci_clr_err();
- wrmces(0x7);
- mb();
- }
-#if 1
- else {
- printk("TSUNAMI machine check NOT expected\n") ;
- DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr));
- DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset));
- TSUNAMI_mcheck_expected[cpu] = 0;
- TSUNAMI_mcheck_taken[cpu] = 1;
- mb();
- mb(); /* magic */
- draina();
- tsunami_pci_clr_err();
- wrmces(0x7);
- mb();
- }
-#endif
-#endif
+ draina();
+ tsunami_pci_clr_err();
+ wrmces(0x7);
+ mb();
+
+ process_mcheck_info(vector, la_ptr, regs, "TSUNAMI",
+ mcheck_expected(smp_processor_id()));
}
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index b4e71bf56..1e34d5a33 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -8,7 +8,7 @@
#define SIGCHLD 20
-#define NR_SYSCALLS 371
+#define NR_SYSCALLS 373
/*
* These offsets must match with alpha_mv in <asm/machvec.h>.
@@ -38,6 +38,8 @@
*/
#define PF_PTRACED 0x00000010
+#define CLONE_VM 0x00000100
+
/*
* This defines the normal kernel pt-regs layout.
*
@@ -225,21 +227,23 @@ kernel_clone:
.end kernel_clone
/*
- * __kernel_thread(clone_flags, fn, arg)
+ * kernel_thread(fn, arg, clone_flags)
*/
.align 3
-.globl __kernel_thread
-.ent __kernel_thread
-__kernel_thread:
+.globl kernel_thread
+.ent kernel_thread
+kernel_thread:
ldgp $29,0($27) /* we can be called from a module */
.frame $30, 4*8, $26
subq $30,4*8,$30
stq $10,16($30)
stq $9,8($30)
+ lda $0,CLONE_VM
stq $26,0($30)
.prologue 1
- mov $17,$9 /* save fn */
- mov $18,$10 /* save arg */
+ mov $16,$9 /* save fn */
+ mov $17,$10 /* save arg */
+ or $18,$0,$16 /* shuffle flags to front; add CLONE_VM. */
bsr $26,kernel_clone
bne $20,1f /* $20 is non-zero in child */
ldq $26,0($30)
@@ -257,7 +261,7 @@ __kernel_thread:
mov $0,$16
mov $31,$26
jsr $31,sys_exit
-.end __kernel_thread
+.end kernel_thread
/*
* __kernel_execve(path, argv, envp, regs)
@@ -1092,7 +1096,7 @@ sys_call_table:
.quad sys_munlockall
.quad sys_sysinfo
.quad sys_sysctl
- .quad sys_idle /* 320 */
+ .quad sys_ni_syscall /* 320 */
.quad sys_oldumount
.quad sys_swapon
.quad sys_times
@@ -1143,3 +1147,5 @@ sys_call_table:
.quad sys_capget
.quad sys_capset
.quad sys_sendfile /* 370 */
+ .quad sys_setresgid
+ .quad sys_getresgid
diff --git a/arch/alpha/kernel/es1888.c b/arch/alpha/kernel/es1888.c
index 10115ac8d..d584c85fe 100644
--- a/arch/alpha/kernel/es1888.c
+++ b/arch/alpha/kernel/es1888.c
@@ -32,6 +32,7 @@ es1888_init(void)
continue;
inb(0x022a); /* pause */
outb(0xc6, 0x022c); /* enable extended mode */
+ inb(0x022a); /* pause, also forces the write */
while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
continue;
outb(0xb1, 0x022c); /* setup for write to Interrupt CR */
@@ -44,4 +45,5 @@ es1888_init(void)
while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
continue;
outb(0x18, 0x022c); /* set DMA channel 1 */
+ inb(0x022c); /* force the write */
}
diff --git a/arch/alpha/kernel/head.S b/arch/alpha/kernel/head.S
index 3b004b7f6..e410e2684 100644
--- a/arch/alpha/kernel/head.S
+++ b/arch/alpha/kernel/head.S
@@ -95,3 +95,21 @@ halt:
.prologue 0
call_pal PAL_halt
.end halt
+
+ #
+ # Having the delay loop out of line guarantees that we wont
+ # run into weird alignment conditions (on new processors)
+ # that vary the speed of the loop.
+ #
+ .align 5
+ .globl ___delay
+ .ent ___delay
+___delay:
+ .set noat
+ .frame $30,0,$28,0
+ .prologue 0
+1: subq $0,1,$0
+ bge $0,1b
+ ret $31,($28),0
+ .set at
+ .end ___delay
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index d53f7ffea..43da6affd 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -30,14 +30,17 @@
#include <asm/machvec.h>
#include "proto.h"
-#include "irq.h"
+#include "irq_impl.h"
#define vulp volatile unsigned long *
#define vuip volatile unsigned int *
-unsigned int local_irq_count[NR_CPUS];
-unsigned int local_bh_count[NR_CPUS];
-unsigned long hardirq_no[NR_CPUS];
+/* Only uniprocessor needs this IRQ/BH locking depth, on SMP it lives
+ in the per-cpu structure for cache reasons. */
+#ifndef __SMP__
+int __local_irq_count;
+int __local_bh_count;
+#endif
#if NR_IRQS > 64
# error Unable to handle more than 64 irq levels.
@@ -64,7 +67,7 @@ unsigned long alpha_irq_mask = ~0UL;
*/
void
-generic_ack_irq(unsigned long irq)
+common_ack_irq(unsigned long irq)
{
if (irq < 16) {
/* Ack the interrupt making it the lowest priority */
@@ -384,6 +387,8 @@ static void *previous_irqholder = NULL;
static void show(char * str, void *where);
+#define SYNC_OTHER_CPUS(x) udelay((x)+1);
+
static inline void
wait_on_irq(int cpu, void *where)
{
@@ -397,8 +402,8 @@ wait_on_irq(int cpu, void *where)
* already executing in one..
*/
if (!atomic_read(&global_irq_count)) {
- if (local_bh_count[cpu] ||
- !atomic_read(&global_bh_count))
+ if (local_bh_count(cpu)
+ || !atomic_read(&global_bh_count))
break;
}
@@ -412,19 +417,15 @@ wait_on_irq(int cpu, void *where)
count = MAXCOUNT;
}
__sti();
-#if 0
- SYNC_OTHER_CORES(cpu);
-#else
- udelay(cpu+1);
-#endif
+ SYNC_OTHER_CPUS(cpu);
__cli();
if (atomic_read(&global_irq_count))
continue;
- if (global_irq_lock.lock)
+ if (spin_is_locked(&global_irq_lock))
continue;
- if (!local_bh_count[cpu] &&
- atomic_read(&global_bh_count))
+ if (!local_bh_count(cpu)
+ && atomic_read(&global_bh_count))
continue;
if (spin_trylock(&global_irq_lock))
break;
@@ -469,14 +470,14 @@ get_irqlock(int cpu, void* where)
void
__global_cli(void)
{
- int cpu;
+ int cpu = smp_processor_id();
void *where = __builtin_return_address(0);
/*
* Maximize ipl. If ipl was previously 0 and if this thread
* is not in an irq, then take global_irq_lock.
*/
- if ((swpipl(7) == 0) && !local_irq_count[cpu = smp_processor_id()])
+ if (swpipl(7) == 0 && !local_irq_count(cpu))
get_irqlock(cpu, where);
}
@@ -485,9 +486,8 @@ __global_sti(void)
{
int cpu = smp_processor_id();
- if (!local_irq_count[cpu]) {
+ if (!local_irq_count(cpu))
release_irqlock(cpu);
- }
__sti();
}
@@ -512,7 +512,7 @@ __global_save_flags(void)
retval = 2 + local_enabled;
/* Check for global flags if we're not in an interrupt. */
- if (!local_irq_count[cpu]) {
+ if (!local_irq_count(cpu)) {
if (local_enabled)
retval = 1;
if (global_irq_holder == cpu)
@@ -550,7 +550,7 @@ __global_restore_flags(unsigned long flags)
#define STUCK \
if (!--stuck) { \
printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n", \
- irq, cpu,global_irq_holder); \
+ irq, cpu, global_irq_holder); \
stuck = INIT_STUCK; \
}
@@ -566,11 +566,11 @@ irq_enter(int cpu, int irq)
hardirq_enter(cpu, irq);
barrier();
- while (global_irq_lock.lock) {
+ while (spin_is_locked(&global_irq_lock)) {
if (cpu == global_irq_holder) {
- int globl_locked = global_irq_lock.lock;
+ int globl_locked = spin_is_locked(&global_irq_lock);
int globl_icount = atomic_read(&global_irq_count);
- int local_count = local_irq_count[cpu];
+ int local_count = local_irq_count(cpu);
/* It is very important that we load the state
variables before we do the first call to
@@ -609,19 +609,16 @@ show(char * str, void *where)
#endif
int cpu = smp_processor_id();
- int global_count = atomic_read(&global_irq_count);
- int local_count0 = local_irq_count[0];
- int local_count1 = local_irq_count[1];
- long hardirq_no0 = hardirq_no[0];
- long hardirq_no1 = hardirq_no[1];
-
printk("\n%s, CPU %d: %p\n", str, cpu, where);
- printk("irq: %d [%d(0x%016lx) %d(0x%016lx)]\n", global_count,
- local_count0, hardirq_no0, local_count1, hardirq_no1);
+ printk("irq: %d [%d %d]\n",
+ atomic_read(&global_irq_count),
+ cpu_data[0].irq_count,
+ cpu_data[1].irq_count);
printk("bh: %d [%d %d]\n",
- atomic_read(&global_bh_count), local_bh_count[0],
- local_bh_count[1]);
+ atomic_read(&global_bh_count),
+ cpu_data[0].bh_count,
+ cpu_data[1].bh_count);
#if 0
stack = (unsigned long *) &str;
for (i = 40; i ; i--) {
@@ -644,6 +641,7 @@ wait_on_bh(void)
count = ~0;
}
/* nothing .. wait for the other bh's to go away */
+ barrier();
} while (atomic_read(&global_bh_count) != 0);
}
@@ -658,12 +656,8 @@ wait_on_bh(void)
void
synchronize_bh(void)
{
- if (atomic_read(&global_bh_count)) {
- int cpu = smp_processor_id();
- if (!local_irq_count[cpu] && !local_bh_count[cpu]) {
- wait_on_bh();
- }
- }
+ if (atomic_read(&global_bh_count) && !in_interrupt())
+ wait_on_bh();
}
/*
@@ -680,6 +674,8 @@ synchronize_bh(void)
void
synchronize_irq(void)
{
+#if 0
+ /* Joe's version. */
int cpu = smp_processor_id();
int local_count;
int global_count;
@@ -688,7 +684,7 @@ synchronize_irq(void)
mb();
do {
- local_count = local_irq_count[cpu];
+ local_count = local_irq_count(cpu);
global_count = atomic_read(&global_irq_count);
if (DEBUG_SYNCHRONIZE_IRQ && (--countdown == 0)) {
printk("%d:%d/%d\n", cpu, local_count, global_count);
@@ -696,12 +692,19 @@ synchronize_irq(void)
break;
}
} while (global_count != local_count);
+#else
+ /* Jay's version. */
+ if (atomic_read(&global_irq_count)) {
+ cli();
+ sti();
+ }
+#endif
}
#else /* !__SMP__ */
-#define irq_enter(cpu, irq) (++local_irq_count[cpu])
-#define irq_exit(cpu, irq) (--local_irq_count[cpu])
+#define irq_enter(cpu, irq) (++local_irq_count(cpu))
+#define irq_exit(cpu, irq) (--local_irq_count(cpu))
#endif /* __SMP__ */
@@ -868,31 +871,23 @@ do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
- unsigned long flags;
-
switch (type) {
case 0:
#ifdef __SMP__
- __save_and_cli(flags);
handle_ipi(&regs);
- __restore_flags(flags);
return;
#else
printk("Interprocessor interrupt? You must be kidding\n");
#endif
break;
case 1:
- __save_and_cli(flags);
handle_irq(RTC_IRQ, -1, &regs);
- __restore_flags(flags);
return;
case 2:
alpha_mv.machine_check(vector, la_ptr, &regs);
return;
case 3:
- __save_and_cli(flags);
alpha_mv.device_interrupt(vector, &regs);
- __restore_flags(flags);
return;
case 4:
perf_irq(vector, &regs);
@@ -909,3 +904,101 @@ init_IRQ(void)
wrent(entInt, 0);
alpha_mv.init_irq();
}
+
+
+/*
+ */
+#define MCHK_K_TPERR 0x0080
+#define MCHK_K_TCPERR 0x0082
+#define MCHK_K_HERR 0x0084
+#define MCHK_K_ECC_C 0x0086
+#define MCHK_K_ECC_NC 0x0088
+#define MCHK_K_OS_BUGCHECK 0x008A
+#define MCHK_K_PAL_BUGCHECK 0x0090
+
+#ifndef __SMP__
+struct mcheck_info __mcheck_info;
+#endif
+
+void
+process_mcheck_info(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs *regs, const char *machine,
+ int expected)
+{
+ struct el_common *mchk_header;
+ const char *reason;
+
+ /*
+ * See if the machine check is due to a badaddr() and if so,
+ * ignore it.
+ */
+
+#if DEBUG_MCHECK > 0
+ printk(KERN_CRIT "%s machine check %s\n", machine,
+ expected ? "expected." : "NOT expected!!!");
+#endif
+
+ if (expected) {
+ int cpu = smp_processor_id();
+ mcheck_expected(cpu) = 0;
+ mcheck_taken(cpu) = 1;
+ return;
+ }
+
+ mchk_header = (struct el_common *)la_ptr;
+
+ printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%lx\n",
+ machine, vector, regs->pc, mchk_header->code);
+
+ switch ((unsigned int) mchk_header->code) {
+ /* Machine check reasons. Defined according to PALcode sources. */
+ case 0x80: reason = "tag parity error"; break;
+ case 0x82: reason = "tag control parity error"; break;
+ case 0x84: reason = "generic hard error"; break;
+ case 0x86: reason = "correctable ECC error"; break;
+ case 0x88: reason = "uncorrectable ECC error"; break;
+ case 0x8A: reason = "OS-specific PAL bugcheck"; break;
+ case 0x90: reason = "callsys in kernel mode"; break;
+ case 0x96: reason = "i-cache read retryable error"; break;
+ case 0x98: reason = "processor detected hard error"; break;
+
+ /* System specific (these are for Alcor, at least): */
+ case 0x203: reason = "system detected uncorrectable ECC error"; break;
+ case 0x204: reason = "SIO SERR occurred on PCI bus"; break;
+ case 0x205: reason = "parity error detected by CIA"; break;
+ case 0x206: reason = "SIO IOCHK occurred on ISA bus"; break;
+ case 0x207: reason = "non-existent memory error"; break;
+ case 0x208: reason = "MCHK_K_DCSR"; break;
+ case 0x209: reason = "PCI SERR detected"; break;
+ case 0x20b: reason = "PCI data parity error detected"; break;
+ case 0x20d: reason = "PCI address parity error detected"; break;
+ case 0x20f: reason = "PCI master abort error"; break;
+ case 0x211: reason = "PCI target abort error"; break;
+ case 0x213: reason = "scatter/gather PTE invalid error"; break;
+ case 0x215: reason = "flash ROM write error"; break;
+ case 0x217: reason = "IOA timeout detected"; break;
+ case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
+ case 0x21b: reason = "EISA fail-safe timer timeout"; break;
+ case 0x21d: reason = "EISA bus time-out"; break;
+ case 0x21f: reason = "EISA software generated NMI"; break;
+ case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
+ default: reason = "unknown"; break;
+ }
+
+ printk(KERN_CRIT "machine check type: %s%s\n",
+ reason, mchk_header->retry ? " (retryable)" : "");
+
+ dik_show_regs(regs, NULL);
+
+#if DEBUG_MCHECK > 1
+ {
+ /* Dump the logout area to give all info. */
+ unsigned long *ptr = (unsigned long *)la_ptr;
+ long i;
+ for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+ printk(KERN_CRIT " +%8lx %016lx %016lx\n",
+ i*sizeof(long), ptr[i], ptr[i+1]);
+ }
+ }
+#endif
+}
diff --git a/arch/alpha/kernel/irq.h b/arch/alpha/kernel/irq_impl.h
index 6849e830b..bc8854212 100644
--- a/arch/alpha/kernel/irq.h
+++ b/arch/alpha/kernel/irq_impl.h
@@ -18,7 +18,7 @@
extern unsigned long alpha_irq_mask;
-extern void generic_ack_irq(unsigned long irq);
+extern void common_ack_irq(unsigned long irq);
extern void isa_device_interrupt(unsigned long vector, struct pt_regs * regs);
extern void srm_device_interrupt(unsigned long vector, struct pt_regs * regs);
@@ -31,3 +31,19 @@ extern void handle_irq(int irq, int ack, struct pt_regs * regs);
#define TIMER_IRQ RTC_IRQ /* timer is the rtc */
#endif
+extern char _stext;
+static inline void alpha_do_profile (unsigned long pc)
+{
+ if (prof_buffer && current->pid) {
+ pc -= (unsigned long) &_stext;
+ pc >>= prof_shift;
+ /*
+ * Don't ignore out-of-bounds PC values silently,
+ * put them into the last histogram slot, so if
+ * present, they will show up as a sharp peak.
+ */
+ if (pc > prof_len - 1)
+ pc = prof_len - 1;
+ atomic_inc((atomic_t *)&prof_buffer[pc]);
+ }
+}
diff --git a/arch/alpha/kernel/machvec.h b/arch/alpha/kernel/machvec_impl.h
index 1e11c046e..a0ff70dcc 100644
--- a/arch/alpha/kernel/machvec.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -8,16 +8,19 @@
#include <linux/config.h>
-/* Whee. TSUNAMI doesn't have an HAE. Fix things up for the GENERIC
- kernel by defining the HAE address to be that of the cache. Now
- we can read and write it as we like. ;-) */
+/* Whee. Both TSUNAMI and POLARIS don't have an HAE. Fix things up for
+ the GENERIC kernel by defining the HAE address to be that of the cache.
+ Now we can read and write it as we like. ;-) */
#define TSUNAMI_HAE_ADDRESS (&alpha_mv.hae_cache)
-
-/* Whee. POLARIS doesn't have an HAE. Fix things up for the GENERIC
- kernel by defining the HAE address to be that of the cache. Now
- we can read and write it as we like. ;-) */
#define POLARIS_HAE_ADDRESS (&alpha_mv.hae_cache)
+#if CIA_ONE_HAE_WINDOW
+#define CIA_HAE_ADDRESS (&alpha_mv.hae_cache)
+#endif
+#if MCPCIA_ONE_HAE_WINDOW
+#define MCPCIA_HAE_ADDRESS (&alpha_mv.hae_cache)
+#endif
+
/* Only a few systems don't define IACK_SC, handling all interrupts through
the SRM console. But splitting out that one case from IO() below
seems like such a pain. Define this to get things to compile. */
@@ -36,66 +39,63 @@
#define DO_EV4_MMU \
max_asn: EV4_MAX_ASN, \
- mv_get_mmu_context: ev4_get_mmu_context, \
+ mv_switch_mm: ev4_switch_mm, \
+ mv_activate_mm: ev4_activate_mm, \
mv_flush_tlb_current: ev4_flush_tlb_current, \
mv_flush_tlb_other: ev4_flush_tlb_other, \
mv_flush_tlb_current_page: ev4_flush_tlb_current_page
#define DO_EV5_MMU \
max_asn: EV5_MAX_ASN, \
- mv_get_mmu_context: ev5_get_mmu_context, \
+ mv_switch_mm: ev5_switch_mm, \
+ mv_activate_mm: ev5_activate_mm, \
mv_flush_tlb_current: ev5_flush_tlb_current, \
mv_flush_tlb_other: ev5_flush_tlb_other, \
mv_flush_tlb_current_page: ev5_flush_tlb_current_page
#define DO_EV6_MMU \
max_asn: EV6_MAX_ASN, \
- mv_get_mmu_context: ev5_get_mmu_context, \
+ mv_switch_mm: ev5_switch_mm, \
+ mv_activate_mm: ev5_activate_mm, \
mv_flush_tlb_current: ev5_flush_tlb_current, \
mv_flush_tlb_other: ev5_flush_tlb_other, \
mv_flush_tlb_current_page: ev5_flush_tlb_current_page
-#define IO_LITE(UP,low1,low2) \
+#define IO_LITE(UP,low) \
hae_register: (unsigned long *) CAT(UP,_HAE_ADDRESS), \
iack_sc: CAT(UP,_IACK_SC), \
- mv_inb: CAT(low1,_inb), \
- mv_inw: CAT(low1,_inw), \
- mv_inl: CAT(low1,_inl), \
- mv_outb: CAT(low1,_outb), \
- mv_outw: CAT(low1,_outw), \
- mv_outl: CAT(low1,_outl), \
- mv_readb: CAT(low1,_readb), \
- mv_readw: CAT(low1,_readw), \
- mv_readl: CAT(low1,_readl), \
- mv_readq: CAT(low1,_readq), \
- mv_writeb: CAT(low1,_writeb), \
- mv_writew: CAT(low1,_writew), \
- mv_writel: CAT(low1,_writel), \
- mv_writeq: CAT(low1,_writeq), \
- mv_dense_mem: CAT(low2,_dense_mem)
-
-#define IO(UP,low1,low2) \
- IO_LITE(UP,low1,low2), \
- hose_read_config_byte: CAT(low2,_hose_read_config_byte), \
- hose_read_config_word: CAT(low2,_hose_read_config_word), \
- hose_read_config_dword: CAT(low2,_hose_read_config_dword), \
- hose_write_config_byte: CAT(low2,_hose_write_config_byte), \
- hose_write_config_word: CAT(low2,_hose_write_config_word), \
- hose_write_config_dword: CAT(low2,_hose_write_config_dword), \
- dma_win_base: CAT(UP,_DMA_WIN_BASE_DEFAULT), \
- dma_win_size: CAT(UP,_DMA_WIN_SIZE_DEFAULT)
+ mv_inb: CAT(low,_inb), \
+ mv_inw: CAT(low,_inw), \
+ mv_inl: CAT(low,_inl), \
+ mv_outb: CAT(low,_outb), \
+ mv_outw: CAT(low,_outw), \
+ mv_outl: CAT(low,_outl), \
+ mv_readb: CAT(low,_readb), \
+ mv_readw: CAT(low,_readw), \
+ mv_readl: CAT(low,_readl), \
+ mv_readq: CAT(low,_readq), \
+ mv_writeb: CAT(low,_writeb), \
+ mv_writew: CAT(low,_writew), \
+ mv_writel: CAT(low,_writel), \
+ mv_writeq: CAT(low,_writeq), \
+ mv_ioremap: CAT(low,_ioremap), \
+ mv_is_ioaddr: CAT(low,_is_ioaddr)
+
+#define IO(UP,low) \
+ IO_LITE(UP,low), \
+ pci_ops: &CAT(low,_pci_ops)
/* Any assembler that can generate a GENERIC kernel can generate BWX
instructions. So always use them for PYXIS I/O. */
-#define DO_APECS_IO IO(APECS,apecs,apecs)
-#define DO_CIA_IO IO(CIA,cia,cia)
-#define DO_LCA_IO IO(LCA,lca,lca)
-#define DO_MCPCIA_IO IO(MCPCIA,mcpcia,mcpcia)
-#define DO_PYXIS_IO IO(PYXIS,pyxis_bw,pyxis)
-#define DO_POLARIS_IO IO(POLARIS,polaris,polaris)
-#define DO_T2_IO IO(T2,t2,t2)
-#define DO_TSUNAMI_IO IO(TSUNAMI,tsunami,tsunami)
+#define DO_APECS_IO IO(APECS,apecs)
+#define DO_CIA_IO IO(CIA,cia)
+#define DO_LCA_IO IO(LCA,lca)
+#define DO_MCPCIA_IO IO(MCPCIA,mcpcia)
+#define DO_PYXIS_IO IO(PYXIS,pyxis)
+#define DO_POLARIS_IO IO(POLARIS,polaris)
+#define DO_T2_IO IO(T2,t2)
+#define DO_TSUNAMI_IO IO(TSUNAMI,tsunami)
#define BUS(which) \
mv_virt_to_bus: CAT(which,_virt_to_bus), \
@@ -136,5 +136,11 @@
/* GCC actually has a syntax for defining aliases, but is under some
delusion that you shouldn't be able to declare it extern somewhere
else beforehand. Fine. We'll do it ourselves. */
-#define ALIAS_MV(system) asm(".global alpha_mv\nalpha_mv = " #system "_mv");
+#if 0
+#define ALIAS_MV(system) \
+ struct alpha_machine_vector alpha_mv __attribute__((alias(#system "_mv")));
+#else
+#define ALIAS_MV(system) \
+ asm(".global alpha_mv\nalpha_mv = " #system "_mv");
#endif
+#endif /* GENERIC */
diff --git a/arch/alpha/kernel/ns87312.c b/arch/alpha/kernel/ns87312.c
new file mode 100644
index 000000000..8f690e43e
--- /dev/null
+++ b/arch/alpha/kernel/ns87312.c
@@ -0,0 +1,38 @@
+/*
+ * linux/arch/alpha/kernel/ns87312.c
+ */
+
+#include <linux/init.h>
+#include <asm/io.h>
+#include "proto.h"
+
+
+/*
+ * The SRM console *disables* the IDE interface, this code ensures it's
+ * enabled.
+ *
+ * This code bangs on a control register of the 87312 Super I/O chip
+ * that implements parallel port/serial ports/IDE/FDI. Depending on
+ * the motherboard, the Super I/O chip can be configured through a
+ * pair of registers that are located either at I/O ports 0x26e/0x26f
+ * or 0x398/0x399. Unfortunately, autodetecting which base address is
+ * in use works only once (right after a reset). The Super I/O chip
+ * has the additional quirk that configuration register data must be
+ * written twice (I believe this is a safety feature to prevent
+ * accidental modification---fun, isn't it?).
+ */
+
+void __init
+ns87312_enable_ide(long ide_base)
+{
+ int data;
+ unsigned long flags;
+
+ __save_and_cli(flags);
+ outb(0, ide_base); /* set the index register for reg #0 */
+ data = inb(ide_base+1); /* read the current contents */
+ outb(0, ide_base); /* set the index register for reg #0 */
+ outb(data | 0x40, ide_base+1); /* turn on IDE */
+ outb(data | 0x40, ide_base+1); /* turn on IDE, really! */
+ __restore_flags(flags);
+}
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 9ff616afa..e888c91e3 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -895,11 +895,12 @@ asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer,
w = ieee_fpcr_to_swcr(fpcr);
if (!(fpcr & FPCR_UNDZ)) {
w &= ~IEEE_TRAP_ENABLE_UNF;
- w |= current->tss.flags & IEEE_TRAP_ENABLE_UNF;
+ w |= (current->thread.flags
+ & IEEE_TRAP_ENABLE_UNF);
}
} else {
/* Otherwise we are forced to do everything in sw. */
- w = current->tss.flags & IEEE_SW_MASK;
+ w = current->thread.flags & IEEE_SW_MASK;
}
if (put_user(w, (unsigned long *) buffer))
@@ -917,7 +918,7 @@ asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer,
case GSI_UACPROC:
if (nbytes < sizeof(unsigned int))
return -EINVAL;
- w = (current->tss.flags >> UAC_SHIFT) & UAC_BITMASK;
+ w = (current->thread.flags >> UAC_SHIFT) & UAC_BITMASK;
if (put_user(w, (unsigned int *)buffer))
return -EFAULT;
return 1;
@@ -927,6 +928,7 @@ asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer,
return -EINVAL;
cpu = (struct percpu_struct*)
((char*)hwrpb + hwrpb->processor_offset);
+ w = cpu->type;
if (put_user(w, (unsigned long *)buffer))
return -EFAULT;
return 1;
@@ -963,8 +965,8 @@ asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer,
/* Update softare trap enable bits. */
if (get_user(swcr, (unsigned long *)buffer))
return -EFAULT;
- current->tss.flags &= ~IEEE_SW_MASK;
- current->tss.flags |= swcr & IEEE_SW_MASK;
+ current->thread.flags &= ~IEEE_SW_MASK;
+ current->thread.flags |= swcr & IEEE_SW_MASK;
/* Update the real fpcr. Keep UNFD off if not UNDZ. */
fpcr = rdfpcr();
@@ -996,9 +998,9 @@ asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer,
return -EFAULT;
switch (v) {
case SSIN_UACPROC:
- current->tss.flags &=
+ current->thread.flags &=
~(UAC_BITMASK << UAC_SHIFT);
- current->tss.flags |=
+ current->thread.flags |=
(w & UAC_BITMASK) << UAC_SHIFT;
break;
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
new file mode 100644
index 000000000..a81ba4093
--- /dev/null
+++ b/arch/alpha/kernel/pci.c
@@ -0,0 +1,226 @@
+/*
+ * linux/arch/alpha/kernel/pci.c
+ *
+ * Extruded from code written by
+ * Dave Rusling (david.rusling@reo.mts.dec.com)
+ * David Mosberger (davidm@cs.arizona.edu)
+ */
+
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/pci.h>
+#include <asm/machvec.h>
+
+#include "proto.h"
+#include "pci_impl.h"
+
+
+/*
+ * Some string constants used by the various core logics.
+ */
+
+const char *const pci_io_names[] = {
+ "PCI IO bus 0", "PCI IO bus 1", "PCI IO bus 2", "PCI IO bus 3"
+};
+
+const char *const pci_mem_names[] = {
+ "PCI mem bus 0", "PCI mem bus 1", "PCI mem bus 2", "PCI mem bus 3"
+};
+
+const char pci_hae0_name[] = "HAE0";
+
+
+/*
+ * The PCI controler list.
+ */
+
+struct pci_controler *hose_head, **hose_tail = &hose_head;
+struct pci_controler *probing_hose;
+
+/*
+ * Quirks.
+ */
+
+static void __init
+quirk_eisa_bridge(struct pci_dev *dev)
+{
+ dev->class = PCI_CLASS_BRIDGE_EISA;
+}
+
+static void __init
+quirk_isa_bridge(struct pci_dev *dev)
+{
+ dev->class = PCI_CLASS_BRIDGE_ISA;
+}
+
+struct pci_fixup pcibios_fixups[] __initdata = {
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375,
+ quirk_eisa_bridge },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378,
+ quirk_isa_bridge },
+ { 0 }
+};
+
+
+/*
+ * Pre-layout host-independant device initialization.
+ */
+
+static void __init
+pcibios_assign_special(void)
+{
+ struct pci_dev *dev;
+ int i;
+
+ /* The first three resources of an IDE controler are often magic,
+ so leave them unchanged. This is true, for instance, of the
+ Contaq 82C693 as seen on SX164 and DP264. */
+
+ for (dev = pci_devices; dev; dev = dev->next) {
+ if (dev->class >> 8 != PCI_CLASS_STORAGE_IDE)
+ continue;
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ if (dev->resource[i].flags)
+ pci_claim_resource(dev, i);
+ }
+ }
+}
+
+
+void __init
+pcibios_init(void)
+{
+ if (!alpha_mv.init_pci)
+ return;
+ alpha_mv.init_pci();
+}
+
+char * __init
+pcibios_setup(char *str)
+{
+ return str;
+}
+
+void __init
+pcibios_fixup_bus(struct pci_bus *bus)
+{
+ /* Propogate hose info into the subordinate devices. */
+
+ struct pci_controler *hose = probing_hose;
+ struct pci_dev *dev;
+
+ bus->resource[0] = hose->io_space;
+ bus->resource[1] = hose->mem_space;
+ for (dev = bus->devices; dev; dev = dev->sibling)
+ dev->sysdata = hose;
+}
+
+void __init
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+ struct resource *res, int resource)
+{
+ unsigned long where, size;
+ u32 reg;
+
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
+ size = res->end - res->start;
+ pci_read_config_dword(dev, where, &reg);
+ reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+ pci_write_config_dword(dev, where, reg);
+
+ /* ??? FIXME -- record old value for shutdown. */
+}
+
+void __init
+pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+
+ /* ??? FIXME -- record old value for shutdown. */
+}
+
+/* Most Alphas have straight-forward swizzling needs. */
+
+u8 __init
+common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+ struct pci_controler *hose = dev->sysdata;
+
+ if (dev->bus->number != hose->first_busno) {
+ u8 pin = *pinp;
+ do {
+ pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+ /* Move up the chain of bridges. */
+ dev = dev->bus->self;
+ } while (dev->bus->self);
+ *pinp = pin;
+
+ /* The slot is the slot of the last bridge. */
+ }
+
+ return PCI_SLOT(dev->devfn);
+}
+
+void __init
+common_init_pci(void)
+{
+ struct pci_controler *hose;
+ struct pci_bus *bus;
+ int next_busno;
+
+ /* Scan all of the recorded PCI controlers. */
+ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
+ hose->first_busno = next_busno;
+ hose->last_busno = 0xff;
+ probing_hose = hose;
+ bus = pci_scan_bus(next_busno, alpha_mv.pci_ops, hose);
+ hose->bus = bus;
+ next_busno = hose->last_busno = bus->subordinate;
+ next_busno += 1;
+ }
+ probing_hose = NULL;
+
+ pcibios_assign_special();
+ pci_assign_unassigned_resources(alpha_mv.min_io_address,
+ alpha_mv.min_mem_address);
+ pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
+ pci_set_bus_ranges();
+}
+
+
+struct pci_controler * __init
+alloc_pci_controler(unsigned long *mem_start)
+{
+ unsigned long start = *mem_start;
+ struct pci_controler *hose;
+ if (start & 31)
+ start = (start | 31) + 1;
+ hose = (void *) start;
+ start = (unsigned long) (hose + 1);
+ *mem_start = start;
+
+ memset(hose, 0, sizeof(*hose));
+
+ *hose_tail = hose;
+ hose_tail = &hose->next;
+
+ return hose;
+}
+
+struct resource * __init
+alloc_resource(unsigned long *mem_start)
+{
+ unsigned long start = *mem_start;
+ struct resource *res;
+ if (start & 31)
+ start = (start | 31) + 1;
+ res = (void *) start;
+ start = (unsigned long) (res + 1);
+ *mem_start = start;
+
+ memset(res, 0, sizeof(*res));
+
+ return res;
+}
diff --git a/arch/alpha/kernel/bios32.h b/arch/alpha/kernel/pci_impl.h
index 8850517ba..c7c97f096 100644
--- a/arch/alpha/kernel/bios32.h
+++ b/arch/alpha/kernel/pci_impl.h
@@ -1,14 +1,13 @@
/*
- * linux/arch/alpha/kernel/bios32.h
+ * linux/arch/alpha/kernel/pci_impl.h
*
* This file contains declarations and inline functions for interfacing
- * with the PCI initialization routines in bios32.c.
+ * with the PCI initialization routines.
*/
+struct pci_dev;
+struct pci_controler;
-#define KB 1024
-#define MB (1024*KB)
-#define GB (1024*MB)
/*
* We can't just blindly use 64K for machines with EISA busses; they
@@ -21,15 +20,10 @@
* accesses to probe the bus. If a device's registers appear at 0xC000,
* it may see an INx/OUTx at that address during BIOS emulation of the
* VGA BIOS, and some cards, notably Adaptec 2940UW, take mortal offense.
- *
- * Note that we may need this stuff for SRM_SETUP also, since certain
- * SRM consoles screw up and allocate I/O space addresses > 64K behind
- * PCI-to_PCI bridges, which can't pass I/O addresses larger than 64K,
- * AFAIK.
*/
-#define EISA_DEFAULT_IO_BASE 0x9000 /* start above 8th slot */
-#define DEFAULT_IO_BASE 0x8000 /* start at 8th slot */
+#define EISA_DEFAULT_IO_BASE 0x9000 /* start above 8th slot */
+#define DEFAULT_IO_BASE 0x8000 /* start at 8th slot */
/*
* We try to make the DEFAULT_MEM_BASE addresses *always* have more than
@@ -49,13 +43,13 @@
* We accept the risk that a broken Myrinet card will be put into a true XL
* and thus can more easily run into the problem described below.
*/
-#define XL_DEFAULT_MEM_BASE (16*MB + 2*MB) /* 16M to 64M-1 is avail */
+#define XL_DEFAULT_MEM_BASE ((16+2)*1024*1024) /* 16M to 64M-1 is avail */
/*
* APECS and LCA have only 34 bits for physical addresses, thus limiting PCI
* bus memory addresses for SPARSE access to be less than 128Mb.
*/
-#define APECS_AND_LCA_DEFAULT_MEM_BASE (64*MB + 2*MB)
+#define APECS_AND_LCA_DEFAULT_MEM_BASE ((32+2)*1024*1024)
/*
* Because the MCPCIA core logic supports more bits for physical addresses,
@@ -63,37 +57,17 @@
* However, we do not use them all, in order to avoid the HAE manipulation
* that would be needed.
*/
-#define RAWHIDE_DEFAULT_MEM_BASE (64*MB + 2*MB)
+#define MCPCIA_DEFAULT_MEM_BASE ((32+2)*1024*1024)
/*
* Because CIA and PYXIS and T2 have more bits for physical addresses,
* they support an expanded range of SPARSE memory addresses.
*/
-#define DEFAULT_MEM_BASE (128*MB + 16*MB)
+#define DEFAULT_MEM_BASE ((128+16)*1024*1024)
+/* ??? Experimenting with no HAE for CIA. */
+#define CIA_DEFAULT_MEM_BASE ((32+2)*1024*1024)
-/*
- * PCI_MODIFY
- *
- * If this 0, then do not write to any of the PCI registers, merely
- * read them (i.e., use configuration as determined by SRM). The SRM
- * seem do be doing a less than perfect job in configuring PCI
- * devices, so for now we do it ourselves. Reconfiguring PCI devices
- * breaks console (RPB) callbacks, but those don't work properly with
- * 64 bit addresses anyways.
- *
- * The accepted convention seems to be that the console (POST
- * software) should fully configure boot devices and configure the
- * interrupt routing of *all* devices. In particular, the base
- * addresses of non-boot devices need not be initialized. For
- * example, on the AXPpci33 board, the base address a #9 GXE PCI
- * graphics card reads as zero (this may, however, be due to a bug in
- * the graphics card---there have been some rumor that the #9 BIOS
- * incorrectly resets that address to 0...).
- */
-
-#define PCI_MODIFY (!alpha_use_srm_setup)
-
/*
* A small note about bridges and interrupts. The DECchip 21050 (and
@@ -133,22 +107,11 @@
* couple boards that do strange things, so we define this here.
*/
-static inline unsigned char
-bridge_swizzle(unsigned char pin, unsigned int slot)
+static inline u8 bridge_swizzle(u8 pin, u8 slot)
{
return (((pin-1) + slot) % 4) + 1;
}
-extern void layout_all_busses(unsigned long io_base, unsigned long mem_base);
-extern void enable_ide(long ide_base);
-
-struct pci_dev;
-
-extern void
-common_pci_fixup(int (*map_irq)(struct pci_dev *dev, int slot, int pin),
- int (*swizzle)(struct pci_dev *dev, int *pin));
-
-extern int common_swizzle(struct pci_dev *dev, int *pinp);
/* The following macro is used to implement the table-based irq mapping
function for all single-bus Alphas. */
@@ -161,6 +124,14 @@ extern int common_swizzle(struct pci_dev *dev, int *pinp);
/* The hose list. */
-extern struct linux_hose_info *hose_head, **hose_tail;
-extern int hose_count;
-extern int pci_probe_enabled;
+extern struct pci_controler *hose_head, **hose_tail;
+extern struct pci_controler *probing_hose;
+
+extern void common_init_pci(void);
+extern u8 common_swizzle(struct pci_dev *, u8 *);
+extern struct pci_controler *alloc_pci_controler(unsigned long *);
+extern struct resource *alloc_resource(unsigned long *);
+
+extern const char *const pci_io_names[];
+extern const char *const pci_mem_names[];
+extern const char pci_hae0_name[];
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index ecd4387ae..354597ba2 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -43,7 +43,7 @@
#include <asm/fpu.h>
#include "proto.h"
-#include "bios32.h"
+#include "pci_impl.h"
/*
* Initial task structure. Make this a per-architecture thing,
@@ -55,7 +55,6 @@
unsigned long init_user_stack[1024] = { STACK_MAGIC, };
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
-static struct file * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM(init_mm);
@@ -75,9 +74,8 @@ sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2,
return 0;
}
-#ifdef __SMP__
void
-cpu_idle(void *unused)
+cpu_idle(void)
{
/* An endless idle loop with no priority at all. */
current->priority = 0;
@@ -95,30 +93,9 @@ cpu_idle(void *unused)
}
}
}
-#endif
-
-asmlinkage int
-sys_idle(void)
-{
- if (current->pid != 0)
- return -EPERM;
-
- /* An endless idle loop with no priority at all. */
- current->priority = 0;
- current->counter = -100;
- init_idle();
-
- while (1) {
- /* FIXME -- EV6 and LCA45 know how to power down
- the CPU. */
-
- schedule();
- check_pgt_cache();
- }
-}
void
-generic_kill_arch (int mode, char *restart_cmd)
+common_kill_arch (int mode, char *restart_cmd)
{
/* The following currently only has any effect on SRM. We should
fix MILO to understand it. Should be pretty easy. Also we can
@@ -153,7 +130,7 @@ generic_kill_arch (int mode, char *restart_cmd)
cpup->flags = flags;
mb();
- reset_for_srm();
+ /* reset_for_srm(); */
set_hae(srm_hae);
#ifdef CONFIG_DUMMY_CONSOLE
@@ -255,7 +232,7 @@ void flush_thread(void)
that EV6 defines UNFD valid only with UNDZ, which we don't want
for IEEE conformance -- so that disabled bit remains in software. */
- current->tss.flags &= ~IEEE_SW_MASK;
+ current->thread.flags &= ~IEEE_SW_MASK;
wrfpcr(FPCR_DYN_NORMAL | FPCR_INVD | FPCR_DZED | FPCR_OVFD | FPCR_INED);
}
@@ -325,11 +302,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
#else
childstack->r26 = (unsigned long) ret_from_sys_call;
#endif
- p->tss.usp = usp;
- p->tss.ksp = (unsigned long) childstack;
- p->tss.pal_flags = 1; /* set FEN, clear everything else */
- p->tss.flags = current->tss.flags;
- p->tss.mm_context = p->tss.asn = 0;
+ p->thread.usp = usp;
+ p->thread.ksp = (unsigned long) childstack;
+ p->thread.pal_flags = 1; /* set FEN, clear everything else */
+ p->thread.flags = current->thread.flags;
return 0;
}
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 8fa1fd7ea..2a196efa1 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -6,141 +6,48 @@
#define vuip volatile unsigned int *
#define vulp volatile unsigned long *
-struct linux_hose_info;
+struct pt_regs;
+struct task_struct;
+struct pci_dev;
/* core_apecs.c */
-extern int apecs_hose_read_config_byte (u8, u8, u8, u8 *value,
- struct linux_hose_info *hose);
-extern int apecs_hose_read_config_word (u8, u8, u8, u16 *value,
- struct linux_hose_info *hose);
-extern int apecs_hose_read_config_dword (u8, u8, u8, u32 *value,
- struct linux_hose_info *hose);
-extern int apecs_hose_write_config_byte (u8, u8, u8, u8 value,
- struct linux_hose_info *hose);
-extern int apecs_hose_write_config_word (u8, u8, u8, u16 value,
- struct linux_hose_info *hose);
-extern int apecs_hose_write_config_dword (u8, u8, u8, u32 value,
- struct linux_hose_info *hose);
+extern struct pci_ops apecs_pci_ops;
extern void apecs_init_arch(unsigned long *, unsigned long *);
-
-extern volatile unsigned int apecs_mcheck_expected;
-extern volatile unsigned int apecs_mcheck_taken;
-extern int apecs_pci_clr_err(void);
+extern void apecs_pci_clr_err(void);
extern void apecs_machine_check(u64, u64, struct pt_regs *);
/* core_cia.c */
-extern int cia_hose_read_config_byte (u8, u8, u8, u8 *value,
- struct linux_hose_info *hose);
-extern int cia_hose_read_config_word (u8, u8, u8, u16 *value,
- struct linux_hose_info *hose);
-extern int cia_hose_read_config_dword (u8, u8, u8, u32 *value,
- struct linux_hose_info *hose);
-extern int cia_hose_write_config_byte (u8, u8, u8, u8 value,
- struct linux_hose_info *hose);
-extern int cia_hose_write_config_word (u8, u8, u8, u16 value,
- struct linux_hose_info *hose);
-extern int cia_hose_write_config_dword (u8, u8, u8, u32 value,
- struct linux_hose_info *hose);
+extern struct pci_ops cia_pci_ops;
extern void cia_init_arch(unsigned long *, unsigned long *);
extern void cia_machine_check(u64, u64, struct pt_regs *);
/* core_lca.c */
-extern int lca_hose_read_config_byte (u8, u8, u8, u8 *value,
- struct linux_hose_info *hose);
-extern int lca_hose_read_config_word (u8, u8, u8, u16 *value,
- struct linux_hose_info *hose);
-extern int lca_hose_read_config_dword (u8, u8, u8, u32 *value,
- struct linux_hose_info *hose);
-extern int lca_hose_write_config_byte (u8, u8, u8, u8 value,
- struct linux_hose_info *hose);
-extern int lca_hose_write_config_word (u8, u8, u8, u16 value,
- struct linux_hose_info *hose);
-extern int lca_hose_write_config_dword (u8, u8, u8, u32 value,
- struct linux_hose_info *hose);
+extern struct pci_ops lca_pci_ops;
extern void lca_init_arch(unsigned long *, unsigned long *);
extern void lca_machine_check(u64, u64, struct pt_regs *);
/* core_mcpcia.c */
-extern int mcpcia_hose_read_config_byte (u8, u8, u8, u8 *value,
- struct linux_hose_info *hose);
-extern int mcpcia_hose_read_config_word (u8, u8, u8, u16 *value,
- struct linux_hose_info *hose);
-extern int mcpcia_hose_read_config_dword (u8, u8, u8, u32 *value,
- struct linux_hose_info *hose);
-extern int mcpcia_hose_write_config_byte (u8, u8, u8, u8 value,
- struct linux_hose_info *hose);
-extern int mcpcia_hose_write_config_word (u8, u8, u8, u16 value,
- struct linux_hose_info *hose);
-extern int mcpcia_hose_write_config_dword (u8, u8, u8, u32 value,
- struct linux_hose_info *hose);
+extern struct pci_ops mcpcia_pci_ops;
extern void mcpcia_init_arch(unsigned long *, unsigned long *);
extern void mcpcia_machine_check(u64, u64, struct pt_regs *);
/* core_polaris.c */
-extern int polaris_hose_read_config_byte (u8, u8, u8, u8 *value,
- struct linux_hose_info *hose);
-extern int polaris_hose_read_config_word (u8, u8, u8, u16 *value,
- struct linux_hose_info *hose);
-extern int polaris_hose_read_config_dword (u8, u8, u8, u32 *value,
- struct linux_hose_info *hose);
-extern int polaris_hose_write_config_byte (u8, u8, u8, u8 value,
- struct linux_hose_info *hose);
-extern int polaris_hose_write_config_word (u8, u8, u8, u16 value,
- struct linux_hose_info *hose);
-extern int polaris_hose_write_config_dword (u8, u8, u8, u32 value,
- struct linux_hose_info *hose);
+extern struct pci_ops polaris_pci_ops;
extern void polaris_init_arch(unsigned long *, unsigned long *);
extern void polaris_machine_check(u64, u64, struct pt_regs *);
/* core_pyxis.c */
-extern int pyxis_hose_read_config_byte (u8, u8, u8, u8 *value,
- struct linux_hose_info *hose);
-extern int pyxis_hose_read_config_word (u8, u8, u8, u16 *value,
- struct linux_hose_info *hose);
-extern int pyxis_hose_read_config_dword (u8, u8, u8, u32 *value,
- struct linux_hose_info *hose);
-extern int pyxis_hose_write_config_byte (u8, u8, u8, u8 value,
- struct linux_hose_info *hose);
-extern int pyxis_hose_write_config_word (u8, u8, u8, u16 value,
- struct linux_hose_info *hose);
-extern int pyxis_hose_write_config_dword (u8, u8, u8, u32 value,
- struct linux_hose_info *hose);
-extern void pyxis_enable_errors (void);
-extern int pyxis_srm_window_setup (void);
-extern void pyxis_native_window_setup(void);
-extern void pyxis_finish_init_arch(void);
+extern struct pci_ops pyxis_pci_ops;
extern void pyxis_init_arch(unsigned long *, unsigned long *);
extern void pyxis_machine_check(u64, u64, struct pt_regs *);
/* core_t2.c */
-extern int t2_hose_read_config_byte (u8, u8, u8, u8 *value,
- struct linux_hose_info *hose);
-extern int t2_hose_read_config_word (u8, u8, u8, u16 *value,
- struct linux_hose_info *hose);
-extern int t2_hose_read_config_dword (u8, u8, u8, u32 *value,
- struct linux_hose_info *hose);
-extern int t2_hose_write_config_byte (u8, u8, u8, u8 value,
- struct linux_hose_info *hose);
-extern int t2_hose_write_config_word (u8, u8, u8, u16 value,
- struct linux_hose_info *hose);
-extern int t2_hose_write_config_dword (u8, u8, u8, u32 value,
- struct linux_hose_info *hose);
+extern struct pci_ops t2_pci_ops;
extern void t2_init_arch(unsigned long *, unsigned long *);
extern void t2_machine_check(u64, u64, struct pt_regs *);
/* core_tsunami.c */
-extern int tsunami_hose_read_config_byte (u8, u8, u8, u8 *value,
- struct linux_hose_info *hose);
-extern int tsunami_hose_read_config_word (u8, u8, u8, u16 *value,
- struct linux_hose_info *hose);
-extern int tsunami_hose_read_config_dword (u8, u8, u8, u32 *value,
- struct linux_hose_info *hose);
-extern int tsunami_hose_write_config_byte (u8, u8, u8, u8 value,
- struct linux_hose_info *hose);
-extern int tsunami_hose_write_config_word (u8, u8, u8, u16 value,
- struct linux_hose_info *hose);
-extern int tsunami_hose_write_config_dword (u8, u8, u8, u32 value,
- struct linux_hose_info *hose);
+extern struct pci_ops tsunami_pci_ops;
extern void tsunami_init_arch(unsigned long *, unsigned long *);
extern void tsunami_machine_check(u64, u64, struct pt_regs *);
@@ -155,12 +62,12 @@ extern void smp_percpu_timer_interrupt(struct pt_regs *);
extern int smp_boot_cpuid;
/* bios32.c */
-extern void reset_for_srm(void);
+/* extern void reset_for_srm(void); */
/* time.c */
extern void timer_interrupt(int irq, void *dev, struct pt_regs * regs);
extern void rtc_init_pit(void);
-extern void generic_init_pit(void);
+extern void common_init_pit(void);
extern unsigned long est_cycle_freq;
/* smc37c93x.c */
@@ -172,6 +79,9 @@ extern void SMC669_Init(int);
/* es1888.c */
extern void es1888_init(void);
+/* ns87312.c */
+extern void ns87312_enable_ide(long ide_base);
+
/* fpregs.c */
extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
extern unsigned long alpha_read_fp_reg (unsigned long reg);
@@ -192,12 +102,41 @@ extern void entUna(void);
extern void entDbg(void);
/* process.c */
-extern void generic_kill_arch (int mode, char *reboot_cmd);
-extern void cpu_idle(void *) __attribute__((noreturn));
+extern void common_kill_arch (int mode, char *reboot_cmd);
+extern void cpu_idle(void) __attribute__((noreturn));
/* ptrace.c */
extern int ptrace_set_bpt (struct task_struct *child);
extern int ptrace_cancel_bpt (struct task_struct *child);
+/* traps.c */
+extern void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15);
+extern void die_if_kernel(char *, struct pt_regs *, long, unsigned long *);
+
/* ../mm/init.c */
void srm_paging_stop(void);
+
+/* irq.h */
+
+#ifdef __SMP__
+#define mcheck_expected(cpu) (cpu_data[cpu].mcheck_expected)
+#define mcheck_taken(cpu) (cpu_data[cpu].mcheck_taken)
+#define mcheck_extra(cpu) (cpu_data[cpu].mcheck_extra)
+#else
+extern struct mcheck_info
+{
+ unsigned char expected __attribute__((aligned(8)));
+ unsigned char taken;
+ unsigned char extra;
+} __mcheck_info;
+
+#define mcheck_expected(cpu) (__mcheck_info.expected)
+#define mcheck_taken(cpu) (__mcheck_info.taken)
+#define mcheck_extra(cpu) (__mcheck_info.extra)
+#endif
+
+#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */
+
+extern void process_mcheck_info(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs *regs, const char *machine,
+ int expected);
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index b590c0bdb..333bb63ec 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -106,7 +106,7 @@ get_reg_addr(struct task_struct * task, unsigned long regno)
long *addr;
if (regno == 30) {
- addr = &task->tss.usp;
+ addr = &task->thread.usp;
} else if (regno == 31 || regno > 64) {
zero = 0;
addr = &zero;
@@ -175,31 +175,31 @@ ptrace_set_bpt(struct task_struct * child)
* branch (emulation can be tricky for fp branches).
*/
displ = ((s32)(insn << 11)) >> 9;
- child->tss.bpt_addr[nsaved++] = pc + 4;
+ child->thread.bpt_addr[nsaved++] = pc + 4;
if (displ) /* guard against unoptimized code */
- child->tss.bpt_addr[nsaved++] = pc + 4 + displ;
+ child->thread.bpt_addr[nsaved++] = pc + 4 + displ;
DBG(DBG_BPT, ("execing branch\n"));
} else if (op_code == 0x1a) {
reg_b = (insn >> 16) & 0x1f;
- child->tss.bpt_addr[nsaved++] = get_reg(child, reg_b);
+ child->thread.bpt_addr[nsaved++] = get_reg(child, reg_b);
DBG(DBG_BPT, ("execing jump\n"));
} else {
- child->tss.bpt_addr[nsaved++] = pc + 4;
+ child->thread.bpt_addr[nsaved++] = pc + 4;
DBG(DBG_BPT, ("execing normal insn\n"));
}
/* install breakpoints: */
for (i = 0; i < nsaved; ++i) {
- res = read_int(child, child->tss.bpt_addr[i], &insn);
+ res = read_int(child, child->thread.bpt_addr[i], &insn);
if (res < 0)
return res;
- child->tss.bpt_insn[i] = insn;
- DBG(DBG_BPT, (" -> next_pc=%lx\n", child->tss.bpt_addr[i]));
- res = write_int(child, child->tss.bpt_addr[i], BREAKINST);
+ child->thread.bpt_insn[i] = insn;
+ DBG(DBG_BPT, (" -> next_pc=%lx\n", child->thread.bpt_addr[i]));
+ res = write_int(child, child->thread.bpt_addr[i], BREAKINST);
if (res < 0)
return res;
}
- child->tss.bpt_nsaved = nsaved;
+ child->thread.bpt_nsaved = nsaved;
return 0;
}
@@ -210,9 +210,9 @@ ptrace_set_bpt(struct task_struct * child)
int
ptrace_cancel_bpt(struct task_struct * child)
{
- int i, nsaved = child->tss.bpt_nsaved;
+ int i, nsaved = child->thread.bpt_nsaved;
- child->tss.bpt_nsaved = 0;
+ child->thread.bpt_nsaved = 0;
if (nsaved > 2) {
printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
@@ -220,8 +220,8 @@ ptrace_cancel_bpt(struct task_struct * child)
}
for (i = 0; i < nsaved; ++i) {
- write_int(child, child->tss.bpt_addr[i],
- child->tss.bpt_insn[i]);
+ write_int(child, child->thread.bpt_addr[i],
+ child->thread.bpt_insn[i]);
}
return (nsaved != 0);
}
@@ -231,7 +231,6 @@ sys_ptrace(long request, long pid, long addr, long data,
int a4, int a5, struct pt_regs regs)
{
struct task_struct *child;
- unsigned long tmp;
long ret;
lock_kernel();
@@ -366,7 +365,7 @@ sys_ptrace(long request, long pid, long addr, long data,
ret = -EIO;
if ((unsigned long) data > _NSIG)
goto out;
- child->tss.bpt_nsaved = -1; /* mark single-stepping */
+ child->thread.bpt_nsaved = -1; /* mark single-stepping */
child->flags &= ~PF_TRACESYS;
wake_up_process(child);
child->exit_code = data;
diff --git a/arch/alpha/kernel/semaphore.c b/arch/alpha/kernel/semaphore.c
new file mode 100644
index 000000000..d62b355e1
--- /dev/null
+++ b/arch/alpha/kernel/semaphore.c
@@ -0,0 +1,129 @@
+/*
+ * Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/sched.h>
+#include <asm/semaphore-helper.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit. ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore. The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+ wake_one_more(sem);
+ wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function. Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible. This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return. If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+#define DOWN_VAR \
+ struct task_struct *tsk = current; \
+ wait_queue_t wait; \
+ init_waitqueue_entry(&wait, tsk);
+
+#define DOWN_HEAD(task_state) \
+ \
+ \
+ tsk->state = (task_state); \
+ add_wait_queue(&sem->wait, &wait); \
+ \
+ /* \
+ * Ok, we're set up. sem->count is known to be less than zero \
+ * so we must wait. \
+ * \
+ * We can let go the lock for purposes of waiting. \
+ * We re-acquire it after awaking so as to protect \
+ * all semaphore operations. \
+ * \
+ * If "up()" is called before we call waking_non_zero() then \
+ * we will catch it right away. If it is called later then \
+ * we will have to go through a wakeup cycle to catch it. \
+ * \
+ * Multiple waiters contend for the semaphore lock to see \
+ * who gets to gate through and who has to wait some more. \
+ */ \
+ for (;;) {
+
+#define DOWN_TAIL(task_state) \
+ tsk->state = (task_state); \
+ } \
+ tsk->state = TASK_RUNNING; \
+ remove_wait_queue(&sem->wait, &wait);
+
+void __down(struct semaphore * sem)
+{
+ DOWN_VAR
+ DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+ if (waking_non_zero(sem))
+ break;
+ schedule();
+ DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+ int ret = 0;
+ DOWN_VAR
+ DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+ ret = waking_non_zero_interruptible(sem, tsk);
+ if (ret)
+ {
+ if (ret == 1)
+ /* ret != 0 only if we get interrupted -arca */
+ ret = 0;
+ break;
+ }
+ schedule();
+ DOWN_TAIL(TASK_INTERRUPTIBLE)
+ return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+ return waking_non_zero_trylock(sem);
+}
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 6c13fea3f..47a86c9fe 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -25,6 +25,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/string.h>
+#include <linux/ioport.h>
#ifdef CONFIG_RTC
#include <linux/timex.h>
@@ -39,16 +40,18 @@
#include <asm/hwrpb.h>
#include <asm/dma.h>
#include <asm/io.h>
-
+#include <asm/pci.h>
#include "proto.h"
+#include "pci_impl.h"
+
struct hwrpb_struct *hwrpb;
unsigned long srm_hae;
#ifdef CONFIG_ALPHA_GENERIC
struct alpha_machine_vector alpha_mv;
-int alpha_using_srm, alpha_use_srm_setup;
+int alpha_using_srm;
#endif
unsigned char aux_device_present = 0xaa;
@@ -90,6 +93,7 @@ struct screen_info screen_info = {
orig_video_points: 16
};
+
/*
* Declare all of the machine vectors.
*/
@@ -136,6 +140,47 @@ WEAK(xlt_mv);
#undef WEAK
+/*
+ * I/O resources inherited from PeeCees. Except for perhaps the
+ * turbochannel alphas, everyone has these on some sort of SuperIO chip.
+ *
+ * ??? If this becomes less standard, move the struct out into the
+ * machine vector.
+ */
+
+static void __init
+reserve_std_resources(void)
+{
+ static struct resource standard_io_resources[] = {
+ { "rtc", -1, -1 },
+ { "dma1", 0x00, 0x1f },
+ { "pic1", 0x20, 0x3f },
+ { "timer", 0x40, 0x5f },
+ { "keyboard", 0x60, 0x6f },
+ { "dma page reg", 0x80, 0x8f },
+ { "pic2", 0xa0, 0xbf },
+ { "dma2", 0xc0, 0xdf },
+ };
+
+ struct resource *io = &ioport_resource;
+ long i;
+
+ if (hose_head) {
+ struct pci_controler *hose;
+ for (hose = hose_head; hose; hose = hose->next)
+ if (hose->index == 0) {
+ io = hose->io_space;
+ break;
+ }
+ }
+
+ /* Fix up for the Jensen's queer RTC placement. */
+ standard_io_resources[0].start = RTC_PORT(0);
+ standard_io_resources[0].end = RTC_PORT(0) + 0x10;
+
+ for (i = 0; i < N(standard_io_resources); ++i)
+ request_resource(io, standard_io_resources+i);
+}
void __init
setup_arch(char **cmdline_p, unsigned long * memory_start_p,
@@ -171,20 +216,10 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
*/
for (p = strtok(command_line, " \t"); p ; p = strtok(NULL, " \t")) {
-#ifndef alpha_use_srm_setup
- /* Allow a command-line option to respect the
- SRM's configuration. */
- if (strncmp(p, "srm_setup=", 10) == 0) {
- alpha_use_srm_setup = (p[10] != '0');
- continue;
- }
-#endif
-
if (strncmp(p, "alpha_mv=", 9) == 0) {
vec = get_sysvec_byname(p+9);
continue;
}
-
if (strncmp(p, "cycle=", 6) == 0) {
est_cycle_freq = simple_strtol(p+6, NULL, 0);
continue;
@@ -224,9 +259,15 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
#endif
- printk("Booting on %s%s%s using machine vector %s\n",
+ printk("Booting "
+#ifdef CONFIG_ALPHA_GENERIC
+ "GENERIC "
+#endif
+ "on %s%s%s using machine vector %s from %s\n",
type_name, (*var_name ? " variation " : ""),
- var_name, alpha_mv.vector_name);
+ var_name, alpha_mv.vector_name,
+ (alpha_using_srm ? "SRM" : "MILO"));
+
printk("Command line: %s\n", command_line);
/*
@@ -265,6 +306,9 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
if (alpha_mv.init_arch)
alpha_mv.init_arch(memory_start_p, memory_end_p);
+ /* Reserve standard resources. */
+ reserve_std_resources();
+
/* Initialize the timers. */
/* ??? There is some circumstantial evidence that this needs
to be done now rather than later in time_init, which would
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 832d72ee0..cd8f6e0ad 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -688,12 +688,8 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */
default:
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index eef452e57..e35dd7c7e 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -7,12 +7,13 @@
#include <linux/kernel_stat.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/tasks.h>
+#include <linux/threads.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/spinlock.h>
#include <asm/hwrpb.h>
#include <asm/ptrace.h>
@@ -22,7 +23,6 @@
#include <asm/irq.h>
#include <asm/bitops.h>
#include <asm/pgtable.h>
-#include <asm/spinlock.h>
#include <asm/hardirq.h>
#include <asm/softirq.h>
@@ -30,7 +30,7 @@
#include <asm/unistd.h>
#include "proto.h"
-#include "irq.h"
+#include "irq_impl.h"
#define DEBUG_SMP 0
@@ -75,18 +75,23 @@ extern void calibrate_delay(void);
extern asmlinkage void entInt(void);
-/*
- * Process bootcommand SMP options, like "nosmp" and "maxcpus=".
- */
-void __init
-smp_setup(char *str, int *ints)
+static int __init nosmp(char *str)
+{
+ max_cpus = 0;
+ return 1;
+}
+
+__setup("nosmp", nosmp);
+
+static int __init maxcpus(char *str)
{
- if (ints && ints[0] > 0)
- max_cpus = ints[1];
- else
- max_cpus = 0;
+ get_option(&str, &max_cpus);
+ return 1;
}
+__setup("maxcpus", maxcpus);
+
+
/*
* Called by both boot and secondaries to move global data into
* per-processor storage.
@@ -97,6 +102,8 @@ smp_store_cpu_info(int cpuid)
cpu_data[cpuid].loops_per_sec = loops_per_sec;
cpu_data[cpuid].last_asn
= (cpuid << WIDTH_HARDWARE_ASN) + ASN_FIRST_VERSION;
+ cpu_data[cpuid].irq_count = 0;
+ cpu_data[cpuid].bh_count = 0;
}
/*
@@ -107,12 +114,6 @@ smp_setup_percpu_timer(int cpuid)
{
cpu_data[cpuid].prof_counter = 1;
cpu_data[cpuid].prof_multiplier = 1;
-
-#ifdef NOT_YET_PROFILING
- load_profile_irq(mid_xlate[cpu], lvl14_resolution);
- if (cpu == smp_boot_cpuid)
- enable_pil_irq(14);
-#endif
}
/*
@@ -137,6 +138,10 @@ smp_callin(void)
/* Setup the scheduler for this processor. */
init_idle();
+ /* ??? This should be in init_idle. */
+ atomic_inc(&init_mm.mm_count);
+ current->active_mm = &init_mm;
+
/* Get our local ticker going. */
smp_setup_percpu_timer(cpuid);
@@ -157,7 +162,7 @@ smp_callin(void)
cpuid, current));
/* Do nothing. */
- cpu_idle(NULL);
+ cpu_idle();
}
@@ -339,21 +344,21 @@ secondary_cpu_start(int cpuid, struct task_struct *idle)
/* Initialize the CPU's HWPCB to something just good enough for
us to get started. Immediately after starting, we'll swpctx
- to the target idle task's tss. Reuse the stack in the mean
+ to the target idle task's ptb. Reuse the stack in the mean
time. Precalculate the target PCBB. */
hwpcb->ksp = (unsigned long) idle + sizeof(union task_union) - 16;
hwpcb->usp = 0;
- hwpcb->ptbr = idle->tss.ptbr;
+ hwpcb->ptbr = idle->thread.ptbr;
hwpcb->pcc = 0;
hwpcb->asn = 0;
- hwpcb->unique = virt_to_phys(&idle->tss);
- hwpcb->flags = idle->tss.pal_flags;
+ hwpcb->unique = virt_to_phys(&idle->thread);
+ hwpcb->flags = idle->thread.pal_flags;
hwpcb->res1 = hwpcb->res2 = 0;
DBGS(("KSP 0x%lx PTBR 0x%lx VPTBR 0x%lx UNIQUE 0x%lx\n",
hwpcb->ksp, hwpcb->ptbr, hwrpb->vptb, hwcpb->unique));
DBGS(("Starting secondary cpu %d: state 0x%lx pal_flags 0x%lx\n",
- cpuid, idle->state, idle->tss.pal_flags));
+ cpuid, idle->state, idle->thread.pal_flags));
/* Setup HWRPB fields that SRM uses to activate secondary CPU */
hwrpb->CPU_restart = __smp_callin;
@@ -403,10 +408,13 @@ smp_boot_one_cpu(int cpuid, int cpunum)
HWRPB.CPU_restart says to start. But this gets all the other
task-y sort of data structures set up like we wish. */
kernel_thread((void *)__smp_callin, NULL, CLONE_PID|CLONE_VM);
- idle = task[cpunum];
- if (!idle)
- panic("No idle process for CPU %d", cpuid);
- idle->processor = cpuid;
+
+ idle = init_task.prev_task;
+ if (!idle)
+ panic("No idle process for CPU %d", cpunum);
+ del_from_runqueue(idle);
+ init_tasks[cpunum] = idle;
+ idle->processor = cpuid;
/* Schedule the first task manually. */
/* ??? Ingo, what is this? */
@@ -516,6 +524,10 @@ smp_boot_cpus(void)
init_idle();
+ /* ??? This should be in init_idle. */
+ atomic_inc(&init_mm.mm_count);
+ current->active_mm = &init_mm;
+
/* Nothing to do on a UP box, or when told not to. */
if (smp_num_probed == 1 || max_cpus == 0) {
printk(KERN_INFO "SMP mode deactivated.\n");
@@ -586,14 +598,12 @@ void
smp_percpu_timer_interrupt(struct pt_regs *regs)
{
int cpu = smp_processor_id();
- int user = user_mode(regs);
+ unsigned long user = user_mode(regs);
struct cpuinfo_alpha *data = &cpu_data[cpu];
-#ifdef NOT_YET_PROFILING
- clear_profile_irq(mid_xlate[cpu]);
+ /* Record kernel PC. */
if (!user)
alpha_do_profile(regs->pc);
-#endif
if (!--data->prof_counter) {
/* We need to make like a normal interrupt -- otherwise
@@ -630,28 +640,7 @@ smp_percpu_timer_interrupt(struct pt_regs *regs)
int __init
setup_profiling_timer(unsigned int multiplier)
{
-#ifdef NOT_YET_PROFILING
- int i;
- unsigned long flags;
-
- /* Prevent level14 ticker IRQ flooding. */
- if((!multiplier) || (lvl14_resolution / multiplier) < 500)
- return -EINVAL;
-
- save_and_cli(flags);
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_present_mask & (1L << i)) {
- load_profile_irq(mid_xlate[i],
- lvl14_resolution / multiplier);
- prof_multiplier[i] = multiplier;
- }
- }
- restore_flags(flags);
-
- return 0;
-#else
return -EINVAL;
-#endif
}
@@ -886,16 +875,18 @@ static void
ipi_flush_tlb_mm(void *x)
{
struct mm_struct *mm = (struct mm_struct *) x;
- if (mm == current->mm)
+ if (mm == current->active_mm)
flush_tlb_current(mm);
}
void
flush_tlb_mm(struct mm_struct *mm)
{
- if (mm == current->mm)
+ if (mm == current->active_mm) {
flush_tlb_current(mm);
- else
+ if (atomic_read(&mm->mm_users) <= 1)
+ return;
+ } else
flush_tlb_other(mm);
if (smp_call_function(ipi_flush_tlb_mm, mm, 1, 1)) {
@@ -913,7 +904,7 @@ static void
ipi_flush_tlb_page(void *x)
{
struct flush_tlb_page_struct *data = (struct flush_tlb_page_struct *)x;
- if (data->mm == current->mm)
+ if (data->mm == current->active_mm)
flush_tlb_current_page(data->mm, data->vma, data->addr);
}
@@ -923,15 +914,17 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
struct flush_tlb_page_struct data;
struct mm_struct *mm = vma->vm_mm;
+ if (mm == current->active_mm) {
+ flush_tlb_current_page(mm, vma, addr);
+ if (atomic_read(&mm->mm_users) <= 1)
+ return;
+ } else
+ flush_tlb_other(mm);
+
data.vma = vma;
data.mm = mm;
data.addr = addr;
- if (mm == current->mm)
- flush_tlb_current_page(mm, vma, addr);
- else
- flush_tlb_other(mm);
-
if (smp_call_function(ipi_flush_tlb_page, &data, 1, 1)) {
printk(KERN_CRIT "flush_tlb_page: timed out\n");
}
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index adcc91f34..fbc1b99ba 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the ALCOR and XLT (XL-300/366/433).
*/
@@ -27,9 +27,9 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
@@ -158,7 +158,7 @@ alcor_init_irq(void)
*/
static int __init
-alcor_map_irq(struct pci_dev *dev, int slot, int pin)
+alcor_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[7][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -175,16 +175,8 @@ alcor_map_irq(struct pci_dev *dev, int slot, int pin)
return COMMON_TABLE_LOOKUP;
}
-static void __init
-alcor_pci_fixup(void)
-{
- layout_all_busses(EISA_DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(alcor_map_irq, common_swizzle);
-}
-
-
static void
-alcor_kill_arch (int mode, char *reboot_cmd)
+alcor_kill_arch(int mode, char *reboot_cmd)
{
/* Who said DEC engineer's have no sense of humor? ;-) */
if (alpha_using_srm) {
@@ -192,7 +184,7 @@ alcor_kill_arch (int mode, char *reboot_cmd)
mb();
}
- generic_kill_arch(mode, reboot_cmd);
+ common_kill_arch(mode, reboot_cmd);
}
@@ -209,6 +201,8 @@ struct alpha_machine_vector alcor_mv __initmv = {
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: EISA_DEFAULT_IO_BASE,
+ min_mem_address: CIA_DEFAULT_MEM_BASE,
nr_irqs: 48,
irq_probe_mask: ALCOR_PROBE_MASK,
@@ -218,9 +212,11 @@ struct alpha_machine_vector alcor_mv __initmv = {
init_arch: cia_init_arch,
init_irq: alcor_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: alcor_pci_fixup,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
kill_arch: alcor_kill_arch,
+ pci_map_irq: alcor_map_irq,
+ pci_swizzle: common_swizzle,
sys: { cia: {
gru_int_req_bits: ALCOR_GRU_INT_REQ_BITS
@@ -238,6 +234,8 @@ struct alpha_machine_vector xlt_mv __initmv = {
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: EISA_DEFAULT_IO_BASE,
+ min_mem_address: CIA_DEFAULT_MEM_BASE,
nr_irqs: 48,
irq_probe_mask: ALCOR_PROBE_MASK,
@@ -247,9 +245,11 @@ struct alpha_machine_vector xlt_mv __initmv = {
init_arch: cia_init_arch,
init_irq: alcor_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: alcor_pci_fixup,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
kill_arch: alcor_kill_arch,
+ pci_map_irq: alcor_map_irq,
+ pci_swizzle: common_swizzle,
sys: { cia: {
gru_int_req_bits: XLT_GRU_INT_REQ_BITS
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
index 37f29e147..244759d1f 100644
--- a/arch/alpha/kernel/sys_cabriolet.c
+++ b/arch/alpha/kernel/sys_cabriolet.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the Cabriolet (AlphaPC64), EB66+, and EB164,
* PC164 and LX164.
@@ -31,9 +31,9 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
@@ -124,7 +124,7 @@ cabriolet_init_irq(void)
*/
static inline int __init
-eb66p_map_irq(struct pci_dev *dev, int slot, int pin)
+eb66p_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[5][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -138,14 +138,6 @@ eb66p_map_irq(struct pci_dev *dev, int slot, int pin)
return COMMON_TABLE_LOOKUP;
}
-static inline void __init
-eb66p_pci_fixup(void)
-{
- layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
- common_pci_fixup(eb66p_map_irq, common_swizzle);
- enable_ide(0x398);
-}
-
/*
* The AlphaPC64 is very similar to the EB66+ except that its slots
@@ -162,7 +154,7 @@ eb66p_pci_fixup(void)
*/
static inline int __init
-cabriolet_map_irq(struct pci_dev *dev, int slot, int pin)
+cabriolet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[5][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -177,19 +169,10 @@ cabriolet_map_irq(struct pci_dev *dev, int slot, int pin)
}
static inline void __init
-cabriolet_pci_fixup(void)
-{
- layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
- common_pci_fixup(cabriolet_map_irq, common_swizzle);
- enable_ide(0x398);
-}
-
-static inline void __init
-eb164_pci_fixup(void)
+cabriolet_init_pci(void)
{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(cabriolet_map_irq, common_swizzle);
- enable_ide(0x398);
+ common_init_pci();
+ ns87312_enable_ide(0x398);
}
@@ -236,7 +219,7 @@ eb164_pci_fixup(void)
*/
static inline int __init
-alphapc164_map_irq(struct pci_dev *dev, int slot, int pin)
+alphapc164_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[7][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -253,13 +236,13 @@ alphapc164_map_irq(struct pci_dev *dev, int slot, int pin)
}
static inline void __init
-alphapc164_pci_fixup(void)
+alphapc164_init_pci(void)
{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(alphapc164_map_irq, common_swizzle);
+ common_init_pci();
SMC93x_Init();
}
+
/*
* The System Vector
*/
@@ -273,18 +256,22 @@ struct alpha_machine_vector cabriolet_mv __initmv = {
DO_APECS_BUS,
machine_check: apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 35,
irq_probe_mask: _PROBE_MASK(35),
update_irq_hw: cabriolet_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: cabriolet_device_interrupt,
init_arch: apecs_init_arch,
init_irq: cabriolet_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: cabriolet_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: cabriolet_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: cabriolet_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(cabriolet)
#endif
@@ -298,18 +285,22 @@ struct alpha_machine_vector eb164_mv __initmv = {
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: CIA_DEFAULT_MEM_BASE,
nr_irqs: 35,
irq_probe_mask: _PROBE_MASK(35),
update_irq_hw: cabriolet_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: cabriolet_device_interrupt,
init_arch: cia_init_arch,
init_irq: cabriolet_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: eb164_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: cabriolet_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: cabriolet_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(eb164)
#endif
@@ -323,18 +314,22 @@ struct alpha_machine_vector eb66p_mv __initmv = {
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 35,
irq_probe_mask: _PROBE_MASK(35),
update_irq_hw: cabriolet_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: cabriolet_device_interrupt,
init_arch: lca_init_arch,
init_irq: cabriolet_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: eb66p_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: cabriolet_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: eb66p_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(eb66p)
#endif
@@ -348,18 +343,22 @@ struct alpha_machine_vector lx164_mv __initmv = {
DO_PYXIS_BUS,
machine_check: pyxis_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 35,
irq_probe_mask: _PROBE_MASK(35),
update_irq_hw: cabriolet_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: cabriolet_device_interrupt,
init_arch: pyxis_init_arch,
init_irq: cabriolet_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: alphapc164_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: alphapc164_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: alphapc164_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(lx164)
#endif
@@ -373,19 +372,22 @@ struct alpha_machine_vector pc164_mv __initmv = {
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: CIA_DEFAULT_MEM_BASE,
nr_irqs: 35,
irq_probe_mask: _PROBE_MASK(35),
update_irq_hw: cabriolet_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: cabriolet_device_interrupt,
init_arch: cia_init_arch,
init_irq: cabriolet_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: alphapc164_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: alphapc164_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: alphapc164_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(pc164)
#endif
-
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index f465b3b4e..a5806275f 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -28,11 +28,10 @@
#include <asm/hwrpb.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
-#define dev2hose(d) (bus2hose[(d)->bus->number]->pci_hose_index)
/*
* HACK ALERT! only the boot cpu is used for interrupts.
@@ -260,7 +259,7 @@ clipper_init_irq(void)
*/
static int __init
-dp264_map_irq(struct pci_dev *dev, int slot, int pin)
+dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[6][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -272,16 +271,18 @@ dp264_map_irq(struct pci_dev *dev, int slot, int pin)
{ 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */
};
const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
+
+ struct pci_controler *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq > 0)
- irq += 16 * dev2hose(dev);
+ irq += 16 * hose->index;
return irq;
}
static int __init
-monet_map_irq(struct pci_dev *dev, int slot, int pin)
+monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[13][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -308,19 +309,23 @@ monet_map_irq(struct pci_dev *dev, int slot, int pin)
return COMMON_TABLE_LOOKUP;
}
-static int __init
-monet_swizzle(struct pci_dev *dev, int *pinp)
+static u8 __init
+monet_swizzle(struct pci_dev *dev, u8 *pinp)
{
+ struct pci_controler *hose = dev->sysdata;
int slot, pin = *pinp;
- /* Check first for the built-in bridge on hose 1. */
- if (dev2hose(dev) == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
+ if (hose->first_busno == dev->bus->number) {
+ slot = PCI_SLOT(dev->devfn);
+ }
+ /* Check for the built-in bridge on hose 1. */
+ else if (hose->index == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
slot = PCI_SLOT(dev->devfn);
} else {
/* Must be a card-based bridge. */
do {
/* Check for built-in bridge on hose 1. */
- if (dev2hose(dev) == 1 &&
+ if (hose->index == 1 &&
PCI_SLOT(dev->bus->self->devfn) == 8) {
slot = PCI_SLOT(dev->devfn);
break;
@@ -338,7 +343,7 @@ monet_swizzle(struct pci_dev *dev, int *pinp)
}
static int __init
-webbrick_map_irq(struct pci_dev *dev, int slot, int pin)
+webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[13][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -359,7 +364,7 @@ webbrick_map_irq(struct pci_dev *dev, int slot, int pin)
}
static int __init
-clipper_map_irq(struct pci_dev *dev, int slot, int pin)
+clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[7][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -372,44 +377,29 @@ clipper_map_irq(struct pci_dev *dev, int slot, int pin)
{ -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */
};
const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
+
+ struct pci_controler *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq > 0)
- irq += 16 * dev2hose(dev);
+ irq += 16 * hose->index;
return irq;
}
static void __init
-dp264_pci_fixup(void)
+dp264_init_pci(void)
{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(dp264_map_irq, common_swizzle);
+ common_init_pci();
SMC669_Init(0);
}
static void __init
-monet_pci_fixup(void)
+monet_init_pci(void)
{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(monet_map_irq, monet_swizzle);
- /* es1888_init(); */ /* later? */
+ common_init_pci();
SMC669_Init(1);
-}
-
-static void __init
-webbrick_pci_fixup(void)
-{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(webbrick_map_irq, common_swizzle);
- SMC669_Init(0);
-}
-
-static void __init
-clipper_pci_fixup(void)
-{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(clipper_map_irq, common_swizzle);
+ es1888_init();
}
@@ -425,18 +415,22 @@ struct alpha_machine_vector dp264_mv __initmv = {
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
irq_probe_mask: _PROBE_MASK(64),
update_irq_hw: dp264_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
init_arch: tsunami_init_arch,
init_irq: dp264_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: dp264_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: dp264_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: dp264_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(dp264)
@@ -448,18 +442,22 @@ struct alpha_machine_vector monet_mv __initmv = {
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
irq_probe_mask: _PROBE_MASK(64),
update_irq_hw: dp264_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
init_arch: tsunami_init_arch,
init_irq: dp264_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: monet_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: monet_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: monet_map_irq,
+ pci_swizzle: monet_swizzle,
};
struct alpha_machine_vector webbrick_mv __initmv = {
@@ -470,18 +468,22 @@ struct alpha_machine_vector webbrick_mv __initmv = {
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
irq_probe_mask: _PROBE_MASK(64),
update_irq_hw: dp264_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
init_arch: tsunami_init_arch,
init_irq: dp264_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: webbrick_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: dp264_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: webbrick_map_irq,
+ pci_swizzle: common_swizzle,
};
struct alpha_machine_vector clipper_mv __initmv = {
@@ -492,18 +494,22 @@ struct alpha_machine_vector clipper_mv __initmv = {
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
irq_probe_mask: _PROBE_MASK(64),
update_irq_hw: clipper_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
init_arch: tsunami_init_arch,
init_irq: clipper_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: clipper_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: clipper_map_irq,
+ pci_swizzle: common_swizzle,
};
/* No alpha_mv alias for webbrick/monet/clipper, since we compile them
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
index 683baa02e..09e0b0def 100644
--- a/arch/alpha/kernel/sys_eb64p.c
+++ b/arch/alpha/kernel/sys_eb64p.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the EB64+ and EB66.
*/
@@ -28,9 +28,9 @@
#include <asm/core_lca.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
@@ -142,7 +142,7 @@ eb64p_init_irq(void)
*/
static int __init
-eb64p_map_irq(struct pci_dev *dev, int slot, int pin)
+eb64p_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[5][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -156,13 +156,6 @@ eb64p_map_irq(struct pci_dev *dev, int slot, int pin)
return COMMON_TABLE_LOOKUP;
}
-static void __init
-eb64p_pci_fixup(void)
-{
- layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
- common_pci_fixup(eb64p_map_irq, common_swizzle);
-}
-
/*
* The System Vector
@@ -177,18 +170,22 @@ struct alpha_machine_vector eb64p_mv __initmv = {
DO_APECS_BUS,
machine_check: apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 32,
irq_probe_mask: _PROBE_MASK(32),
update_irq_hw: eb64p_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: eb64p_device_interrupt,
init_arch: apecs_init_arch,
init_irq: eb64p_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: eb64p_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: eb64p_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(eb64p)
#endif
@@ -202,18 +199,22 @@ struct alpha_machine_vector eb66_mv __initmv = {
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 32,
irq_probe_mask: _PROBE_MASK(32),
update_irq_hw: eb64p_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: eb64p_device_interrupt,
init_arch: lca_init_arch,
init_irq: eb64p_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: eb64p_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: eb64p_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(eb66)
#endif
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index 93a65e76e..0380574a8 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -2,7 +2,7 @@
* linux/arch/alpha/kernel/sys_jensen.c
*
* Copyright (C) 1995 Linus Torvalds
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the Jensen.
*/
@@ -28,8 +28,8 @@
#include <asm/pgtable.h>
#include "proto.h"
-#include "irq.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "machvec_impl.h"
static void
@@ -124,7 +124,7 @@ jensen_machine_check (u64 vector, u64 la, struct pt_regs *regs)
struct alpha_machine_vector jensen_mv __initmv = {
vector_name: "Jensen",
DO_EV4_MMU,
- IO_LITE(JENSEN,jensen,jensen),
+ IO_LITE(JENSEN,jensen),
BUS(jensen),
machine_check: jensen_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
@@ -133,12 +133,13 @@ struct alpha_machine_vector jensen_mv __initmv = {
nr_irqs: 16,
irq_probe_mask: _PROBE_MASK(16),
update_irq_hw: jensen_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: jensen_device_interrupt,
init_arch: NULL,
init_irq: jensen_init_irq,
- init_pit: generic_init_pit,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: NULL,
+ kill_arch: common_kill_arch,
};
ALIAS_MV(jensen)
diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c
index f9c4b64c5..0bea4e3dd 100644
--- a/arch/alpha/kernel/sys_miata.c
+++ b/arch/alpha/kernel/sys_miata.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the MIATA (EV56+PYXIS).
*/
@@ -25,9 +25,9 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
@@ -202,7 +202,7 @@ miata_init_irq(void)
*/
static int __init
-miata_map_irq(struct pci_dev *dev, int slot, int pin)
+miata_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[18][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -224,21 +224,24 @@ miata_map_irq(struct pci_dev *dev, int slot, int pin)
{16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 28, slot 1 */
{16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 29, slot 2 */
{16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 30, slot 3 */
- /* this bridge is on the main bus of the later original MIATA */
+ /* This bridge is on the main bus of the later orig MIATA */
{ -1, -1, -1, -1, -1}, /* IdSel 31, PCI-PCI */
};
const long min_idsel = 3, max_idsel = 20, irqs_per_slot = 5;
return COMMON_TABLE_LOOKUP;
}
-static int __init
-miata_swizzle(struct pci_dev *dev, int *pinp)
+static u8 __init
+miata_swizzle(struct pci_dev *dev, u8 *pinp)
{
int slot, pin = *pinp;
- /* Check first for the built-in bridge. */
- if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
- (PCI_SLOT(dev->bus->self->devfn) == 20)) {
+ if (dev->bus->number == 0) {
+ slot = PCI_SLOT(dev->devfn);
+ }
+ /* Check for the built-in bridge. */
+ else if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
+ (PCI_SLOT(dev->bus->self->devfn) == 20)) {
slot = PCI_SLOT(dev->devfn) + 9;
}
else
@@ -263,14 +266,24 @@ miata_swizzle(struct pci_dev *dev, int *pinp)
}
static void __init
-miata_pci_fixup(void)
+miata_init_pci(void)
{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(miata_map_irq, miata_swizzle);
+ common_init_pci();
SMC669_Init(0); /* it might be a GL (fails harmlessly if not) */
es1888_init();
}
+static void
+miata_kill_arch (int mode, char *reboot_cmd)
+{
+ /* Who said DEC engineers have no sense of humor? ;-) */
+ if (alpha_using_srm) {
+ *(vuip) PYXIS_RESET = 0x0000dead;
+ mb();
+ }
+ common_kill_arch(mode, reboot_cmd);
+}
+
/*
* The System Vector
@@ -284,17 +297,21 @@ struct alpha_machine_vector miata_mv __initmv = {
DO_PYXIS_BUS,
machine_check: pyxis_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 48,
irq_probe_mask: _PROBE_MASK(48),
update_irq_hw: miata_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: miata_device_interrupt,
init_arch: pyxis_init_arch,
init_irq: miata_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: miata_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: miata_init_pci,
+ kill_arch: miata_kill_arch,
+ pci_map_irq: miata_map_irq,
+ pci_swizzle: miata_swizzle,
};
ALIAS_MV(miata)
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index 9952c311f..0c08d9fc0 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the MIKASA (AlphaServer 1000).
*/
@@ -28,9 +28,9 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
mikasa_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
@@ -120,7 +120,7 @@ mikasa_init_irq(void)
*/
static int __init
-mikasa_map_irq(struct pci_dev *dev, int slot, int pin)
+mikasa_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[8][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -137,105 +137,35 @@ mikasa_map_irq(struct pci_dev *dev, int slot, int pin)
return COMMON_TABLE_LOOKUP;
}
-static void __init
-mikasa_pci_fixup(void)
-{
- layout_all_busses(EISA_DEFAULT_IO_BASE,APECS_AND_LCA_DEFAULT_MEM_BASE);
- common_pci_fixup(mikasa_map_irq, common_swizzle);
-}
-
-static void __init
-mikasa_primo_pci_fixup(void)
-{
- layout_all_busses(EISA_DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(mikasa_map_irq, common_swizzle);
-}
+#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
static void
-mikasa_machine_check(unsigned long vector, unsigned long la_ptr,
- struct pt_regs * regs)
+mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs * regs)
{
#define MCHK_NO_DEVSEL 0x205L
#define MCHK_NO_TABT 0x204L
struct el_common *mchk_header;
- struct el_apecs_procdata *mchk_procdata;
- struct el_apecs_mikasa_sysdata_mcheck *mchk_sysdata;
- unsigned long *ptr;
- int i;
+ unsigned int code;
mchk_header = (struct el_common *)la_ptr;
- mchk_procdata = (struct el_apecs_procdata *)
- (la_ptr + mchk_header->proc_offset
- - sizeof(mchk_procdata->paltemp));
-
- mchk_sysdata = (struct el_apecs_mikasa_sysdata_mcheck *)
- (la_ptr + mchk_header->sys_offset);
-
-#ifdef DEBUG
- printk("mikasa_machine_check: vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr);
- printk(" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset);
- printk("mikasa_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
- apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
- mchk_sysdata->epic_pear);
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
- printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
- }
-#endif
-
- /*
- * Check if machine check is due to a badaddr() and if so,
- * ignore the machine check.
- */
-
- if (apecs_mcheck_expected
- && ((unsigned int)mchk_header->code == MCHK_NO_DEVSEL
- || (unsigned int)mchk_header->code == MCHK_NO_TABT)) {
- apecs_mcheck_expected = 0;
- apecs_mcheck_taken = 1;
- mb();
- mb(); /* magic */
- apecs_pci_clr_err();
- wrmces(0x7);
- mb();
- draina();
- }
- else if (vector == 0x620 || vector == 0x630) {
- /* Disable correctable from now on. */
- wrmces(0x1f);
- mb();
- draina();
- printk("mikasa_machine_check: HW correctable (0x%lx)\n",
- vector);
- }
- else {
- printk(KERN_CRIT "APECS machine check:\n");
- printk(KERN_CRIT " vector=0x%lx la_ptr=0x%lx\n",
- vector, la_ptr);
- printk(KERN_CRIT
- " pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
- regs->pc, mchk_header->size, mchk_header->proc_offset,
- mchk_header->sys_offset);
- printk(KERN_CRIT " expected %d DCSR 0x%lx PEAR 0x%lx\n",
- apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
- mchk_sysdata->epic_pear);
-
- ptr = (unsigned long *)la_ptr;
- for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
- printk(KERN_CRIT " +%lx %lx %lx\n",
- i*sizeof(long), ptr[i], ptr[i+1]);
- }
-#if 0
- /* doesn't work with MILO */
- show_regs(regs);
-#endif
- }
+ /* Clear the error before any reporting. */
+ mb();
+ mb(); /* magic */
+ draina();
+ apecs_pci_clr_err();
+ wrmces(0x7);
+ mb();
+
+ code = mchk_header->code;
+ process_mcheck_info(vector, la_ptr, regs, "MIKASA APECS",
+ (mcheck_expected(0)
+ && (code == MCHK_NO_DEVSEL
+ || code == MCHK_NO_TABT)));
}
+#endif
/*
@@ -249,20 +179,24 @@ struct alpha_machine_vector mikasa_mv __initmv = {
DO_DEFAULT_RTC,
DO_APECS_IO,
DO_APECS_BUS,
- machine_check: mikasa_machine_check,
+ machine_check: mikasa_apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 32,
irq_probe_mask: _PROBE_MASK(32),
update_irq_hw: mikasa_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: mikasa_device_interrupt,
init_arch: apecs_init_arch,
init_irq: mikasa_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: mikasa_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: mikasa_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(mikasa)
#endif
@@ -274,20 +208,24 @@ struct alpha_machine_vector mikasa_primo_mv __initmv = {
DO_DEFAULT_RTC,
DO_CIA_IO,
DO_CIA_BUS,
- machine_check: mikasa_machine_check,
+ machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: CIA_DEFAULT_MEM_BASE,
nr_irqs: 32,
irq_probe_mask: _PROBE_MASK(32),
update_irq_hw: mikasa_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: mikasa_device_interrupt,
init_arch: cia_init_arch,
init_irq: mikasa_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: mikasa_primo_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: mikasa_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(mikasa_primo)
#endif
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index 2ade29654..adce91de2 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the NORITAKE (AlphaServer 1000A),
* CORELLE (AlphaServer 800), and ALCOR Primo (AlphaStation 600A).
@@ -29,9 +29,9 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
@@ -168,7 +168,7 @@ noritake_init_irq(void)
*/
static int __init
-noritake_map_irq(struct pci_dev *dev, int slot, int pin)
+noritake_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[15][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -195,13 +195,16 @@ noritake_map_irq(struct pci_dev *dev, int slot, int pin)
return COMMON_TABLE_LOOKUP;
}
-static int __init
-noritake_swizzle(struct pci_dev *dev, int *pinp)
+static u8 __init
+noritake_swizzle(struct pci_dev *dev, u8 *pinp)
{
int slot, pin = *pinp;
- /* Check first for the built-in bridge */
- if (PCI_SLOT(dev->bus->self->devfn) == 8) {
+ if (dev->bus->number == 0) {
+ slot = PCI_SLOT(dev->devfn);
+ }
+ /* Check for the built-in bridge */
+ else if (PCI_SLOT(dev->bus->self->devfn) == 8) {
slot = PCI_SLOT(dev->devfn) + 15; /* WAG! */
}
else
@@ -224,20 +227,6 @@ noritake_swizzle(struct pci_dev *dev, int *pinp)
return slot;
}
-static void __init
-noritake_pci_fixup(void)
-{
- layout_all_busses(EISA_DEFAULT_IO_BASE,APECS_AND_LCA_DEFAULT_MEM_BASE);
- common_pci_fixup(noritake_map_irq, noritake_swizzle);
-}
-
-static void __init
-noritake_primo_pci_fixup(void)
-{
- layout_all_busses(EISA_DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(noritake_map_irq, noritake_swizzle);
-}
-
/*
* The System Vectors
@@ -252,18 +241,22 @@ struct alpha_machine_vector noritake_mv __initmv = {
DO_APECS_BUS,
machine_check: apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: EISA_DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 48,
irq_probe_mask: _PROBE_MASK(48),
update_irq_hw: noritake_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: noritake_device_interrupt,
init_arch: apecs_init_arch,
init_irq: noritake_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: noritake_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: noritake_map_irq,
+ pci_swizzle: noritake_swizzle,
};
ALIAS_MV(noritake)
#endif
@@ -277,18 +270,22 @@ struct alpha_machine_vector noritake_primo_mv __initmv = {
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: EISA_DEFAULT_IO_BASE,
+ min_mem_address: CIA_DEFAULT_MEM_BASE,
nr_irqs: 48,
irq_probe_mask: _PROBE_MASK(48),
update_irq_hw: noritake_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: noritake_device_interrupt,
init_arch: cia_init_arch,
init_irq: noritake_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: noritake_primo_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: noritake_map_irq,
+ pci_swizzle: noritake_swizzle,
};
ALIAS_MV(noritake_primo)
#endif
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index 19d79c060..1b5e1c3cf 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the RAWHIDE.
*/
@@ -26,9 +26,9 @@
#include <asm/core_mcpcia.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
@@ -36,19 +36,19 @@ rawhide_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
{
if (irq >= 40) {
/* PCI bus 1 with builtin NCR810 SCSI */
- *(vuip)MCPCIA_INT_MASK0(1) =
+ *(vuip)MCPCIA_INT_MASK0(5) =
(~((mask) >> 40) & 0x00ffffffU) | 0x00fe0000U;
mb();
/* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(1);
+ *(vuip)MCPCIA_INT_MASK0(5);
}
else if (irq >= 16) {
/* PCI bus 0 with EISA bridge */
- *(vuip)MCPCIA_INT_MASK0(0) =
+ *(vuip)MCPCIA_INT_MASK0(4) =
(~((mask) >> 16) & 0x00ffffffU) | 0x00ff0000U;
mb();
/* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(0);
+ *(vuip)MCPCIA_INT_MASK0(4);
}
else if (irq >= 8)
outb(mask >> 8, 0xA1); /* ISA PIC2 */
@@ -63,6 +63,10 @@ rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
ack = irq = (vector - 0x800) >> 4;
+ /* ??? A 4 bus RAWHIDE has 67 interrupts. Oops. We need
+ something wider than one word for our own internal
+ manipulations. */
+
/*
* The RAWHIDE SRM console reports PCI interrupts with a vector
* 0x80 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
@@ -90,17 +94,17 @@ rawhide_init_irq(void)
STANDARD_INIT_IRQ_PROLOG;
/* HACK ALERT! only PCI busses 0 and 1 are used currently,
- and routing is only to CPU #1*/
+ (MIDs 4 and 5 respectively) and routing is only to CPU #1*/
- *(vuip)MCPCIA_INT_MASK0(0) =
+ *(vuip)MCPCIA_INT_MASK0(4) =
(~((alpha_irq_mask) >> 16) & 0x00ffffffU) | 0x00ff0000U; mb();
/* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(0);
+ *(vuip)MCPCIA_INT_MASK0(4);
- *(vuip)MCPCIA_INT_MASK0(1) =
+ *(vuip)MCPCIA_INT_MASK0(5) =
(~((alpha_irq_mask) >> 40) & 0x00ffffffU) | 0x00fe0000U; mb();
/* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(1);
+ *(vuip)MCPCIA_INT_MASK0(5);
enable_irq(2);
}
@@ -139,7 +143,7 @@ rawhide_init_irq(void)
*/
static int __init
-rawhide_map_irq(struct pci_dev *dev, int slot, int pin)
+rawhide_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[5][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -150,19 +154,14 @@ rawhide_map_irq(struct pci_dev *dev, int slot, int pin)
{ 16+12, 16+12, 16+13, 16+14, 16+15} /* IdSel 5 slot 5 */
};
const long min_idsel = 1, max_idsel = 5, irqs_per_slot = 5;
+
+ struct pci_controler *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq >= 0)
- irq += 24 * bus2hose[dev->bus->number]->pci_hose_index;
+ irq += 24 * hose->index;
return irq;
}
-static void __init
-rawhide_pci_fixup(void)
-{
- layout_all_busses(DEFAULT_IO_BASE, RAWHIDE_DEFAULT_MEM_BASE);
- common_pci_fixup(rawhide_map_irq, common_swizzle);
-}
-
/*
* The System Vector
@@ -176,17 +175,21 @@ struct alpha_machine_vector rawhide_mv __initmv = {
DO_MCPCIA_BUS,
machine_check: mcpcia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: MCPCIA_DEFAULT_MEM_BASE,
nr_irqs: 64,
irq_probe_mask: _PROBE_MASK(64),
update_irq_hw: rawhide_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: rawhide_srm_device_interrupt,
init_arch: mcpcia_init_arch,
init_irq: rawhide_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: rawhide_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: rawhide_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(rawhide)
diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c
index 4d52c256b..f303a8255 100644
--- a/arch/alpha/kernel/sys_ruffian.c
+++ b/arch/alpha/kernel/sys_ruffian.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the RUFFIAN.
*/
@@ -26,9 +26,9 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
ruffian_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
@@ -164,18 +164,6 @@ ruffian_init_irq(void)
}
-/*
- * For RUFFIAN, we do not want to make any modifications to the PCI
- * setup. But we may need to do some kind of init.
- */
-
-static void __init
-ruffian_pci_fixup(void)
-{
- /* layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); */
-}
-
-
#ifdef BUILDING_FOR_MILO
/*
* The DeskStation Ruffian motherboard firmware does not place
@@ -215,25 +203,9 @@ ruffian_get_bank_size(unsigned long offset)
}
#endif /* BUILDING_FOR_MILO */
-static void __init
-ruffian_init_arch(unsigned long *mem_start, unsigned long *mem_end)
-{
- /* FIXME: What do we do with ruffian_get_bank_size above? */
-
- pyxis_enable_errors();
- if (!pyxis_srm_window_setup()) {
- printk("ruffian_init_arch: Skipping window register rewrites."
- "\n... Trust DeskStation firmware!\n");
- }
- pyxis_finish_init_arch();
-}
-
static void
ruffian_init_pit (void)
{
- /* Ruffian depends on the system timer established in MILO! */
- request_region(0x70, 0x10, "timer");
-
outb(0xb6, 0x43); /* pit counter 2: speaker */
outb(0x31, 0x42);
outb(0x13, 0x42);
@@ -248,7 +220,15 @@ ruffian_kill_arch (int mode, char *reboot_cmd)
*(vuip) PYXIS_RESET = 0x0000dead;
mb();
#endif
- generic_kill_arch(mode, reboot_cmd);
+ common_kill_arch(mode, reboot_cmd);
+}
+
+static int __init
+ruffian_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ /* We don't know anything about the PCI routing, so leave
+ the IRQ unchanged. */
+ return dev->irq;
}
@@ -260,11 +240,12 @@ struct alpha_machine_vector ruffian_mv __initmv = {
vector_name: "Ruffian",
DO_EV5_MMU,
DO_DEFAULT_RTC,
- /* For the moment, do not use BWIO on RUFFIAN. */
- IO(PYXIS,pyxis,pyxis),
+ DO_PYXIS_IO,
DO_PYXIS_BUS,
machine_check: pyxis_machine_check,
max_dma_address: ALPHA_RUFFIAN_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 48,
irq_probe_mask: RUFFIAN_PROBE_MASK,
@@ -272,10 +253,12 @@ struct alpha_machine_vector ruffian_mv __initmv = {
ack_irq: ruffian_ack_irq,
device_interrupt: ruffian_device_interrupt,
- init_arch: ruffian_init_arch,
+ init_arch: pyxis_init_arch,
init_irq: ruffian_init_irq,
init_pit: ruffian_init_pit,
- pci_fixup: ruffian_pci_fixup,
+ init_pci: common_init_pci,
kill_arch: ruffian_kill_arch,
+ pci_map_irq: ruffian_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(ruffian)
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
index 5d2cf5288..c6a4ac5b3 100644
--- a/arch/alpha/kernel/sys_rx164.c
+++ b/arch/alpha/kernel/sys_rx164.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the RX164 (PCA56+POLARIS).
*/
@@ -26,9 +26,9 @@
#include <asm/core_polaris.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
@@ -45,10 +45,10 @@ rx164_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
outb(mask, 0x21); /* ISA PIC1 */
}
+#if 0
static void
rx164_srm_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
{
-#if 0
if (irq >= 16) {
if (unmask_p)
cserve_ena(irq - 16);
@@ -59,8 +59,8 @@ rx164_srm_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
outb(mask >> 8, 0xA1); /* ISA PIC2 */
else
outb(mask, 0x21); /* ISA PIC1 */
-#endif
}
+#endif
static void
rx164_isa_device_interrupt(unsigned long vector, struct pt_regs * regs)
@@ -107,7 +107,8 @@ rx164_device_interrupt(unsigned long vector, struct pt_regs *regs)
printk("PLD 0x%lx\n", pld);
#endif
- if (pld & 0xffffffff00000000UL) pld &= 0x00000000ffffffffUL;
+ if (pld & 0xffffffff00000000UL)
+ pld &= 0x00000000ffffffffUL;
/*
* Now for every possible bit set, work through them and call
@@ -137,6 +138,8 @@ rx164_init_irq(void)
enable_irq(16 + 20); /* enable ISA interrupts */
enable_irq(2); /* enable cascade */
}
+
+
/* The RX164 changed its interrupt routing between pass1 and pass2...
*
* PASS1:
@@ -170,7 +173,7 @@ rx164_init_irq(void)
*/
static int __init
-rx164_map_irq(struct pci_dev *dev, int slot, int pin)
+rx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
#if 0
char irq_tab_pass1[6][5] = {
@@ -182,7 +185,7 @@ rx164_map_irq(struct pci_dev *dev, int slot, int pin)
{ 16+2, 16+2, 16+7, 16+12, 16+17}, /* IdSel 9, slot 3 */
{ 16+1, 16+1, 16+6, 16+11, 16+16}, /* IdSel 10, slot 4 */
};
-#endif
+#else
char irq_tab[6][5] = {
/*INT INTA INTB INTC INTD */
{ 16+0, 16+0, 16+6, 16+11, 16+16}, /* IdSel 5, slot 0 */
@@ -192,20 +195,14 @@ rx164_map_irq(struct pci_dev *dev, int slot, int pin)
{ 16+3, 16+3, 16+9, 16+14, 16+19}, /* IdSel 9, slot 3 */
{ 16+4, 16+4, 16+10, 16+15, 16+5}, /* IdSel 10, PCI-PCI */
};
+#endif
const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
+
/* JRP - Need to figure out how to distinguish pass1 from pass2,
- * and use the correct table...
- */
+ and use the correct table. */
return COMMON_TABLE_LOOKUP;
}
-void __init
-rx164_pci_fixup(void)
-{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(rx164_map_irq, common_swizzle);
-}
-
/*
* The System Vector
@@ -219,17 +216,21 @@ struct alpha_machine_vector rx164_mv __initmv = {
DO_POLARIS_BUS,
machine_check: polaris_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 40,
irq_probe_mask: _PROBE_MASK(40),
update_irq_hw: rx164_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: rx164_device_interrupt,
init_arch: polaris_init_arch,
init_irq: rx164_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: rx164_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: rx164_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(rx164)
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index b045f37f6..86b1d8371 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the Sable and Sable-Gamma systems.
*/
@@ -26,9 +26,9 @@
#include <asm/core_t2.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
/*
@@ -198,7 +198,7 @@ sable_init_irq(void)
*/
static int __init
-sable_map_irq(struct pci_dev *dev, int slot, int pin)
+sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[9][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -216,13 +216,6 @@ sable_map_irq(struct pci_dev *dev, int slot, int pin)
return COMMON_TABLE_LOOKUP;
}
-void __init
-sable_pci_fixup(void)
-{
- layout_all_busses(EISA_DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(sable_map_irq, common_swizzle);
-}
-
/*
* The System Vectors
@@ -242,6 +235,8 @@ struct alpha_machine_vector sable_mv __initmv = {
DO_T2_BUS,
machine_check: t2_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: EISA_DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 40,
irq_probe_mask: _PROBE_MASK(40),
@@ -251,9 +246,11 @@ struct alpha_machine_vector sable_mv __initmv = {
init_arch: t2_init_arch,
init_irq: sable_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: sable_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: sable_map_irq,
+ pci_swizzle: common_swizzle,
sys: { t2: {
gamma_bias: 0
@@ -273,6 +270,8 @@ struct alpha_machine_vector sable_gamma_mv __initmv = {
DO_T2_BUS,
machine_check: t2_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: EISA_DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 40,
irq_probe_mask: _PROBE_MASK(40),
@@ -282,9 +281,11 @@ struct alpha_machine_vector sable_gamma_mv __initmv = {
init_arch: t2_init_arch,
init_irq: sable_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: sable_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: sable_map_irq,
+ pci_swizzle: common_swizzle,
sys: { t2: {
gamma_bias: _GAMMA_BIAS
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
index 70d8720e9..8e7fdb85f 100644
--- a/arch/alpha/kernel/sys_sio.c
+++ b/arch/alpha/kernel/sys_sio.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code for all boards that route the PCI interrupts through the SIO
* PCI/ISA bridge. This includes Noname (AXPpci33), Multia (UDB),
@@ -28,11 +28,12 @@
#include <asm/pgtable.h>
#include <asm/core_apecs.h>
#include <asm/core_lca.h>
+#include <asm/pci.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
sio_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
@@ -57,6 +58,8 @@ sio_init_irq(void)
static inline void __init
xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
{
+ struct pci_controler *hose;
+
/*
* Set up the PCI->physical memory translation windows. For
* the XL we *must* use both windows, in order to maximize the
@@ -86,6 +89,16 @@ xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
*/
*(vuip)APECS_IOC_HAXR2 = 0; mb();
+
+ /*
+ * Create our single hose.
+ */
+
+ hose = alloc_pci_controler(mem_start);
+ hose->io_space = &ioport_resource;
+ hose->mem_space = &iomem_resource;
+ hose->config_space = LCA_CONF;
+ hose->index = 0;
}
static inline void __init
@@ -114,26 +127,12 @@ alphabook1_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* This is NOT how we should do it. PIRQ0-X should have
* their own IRQ's, the way intel uses the IO-APIC irq's.
*/
-static unsigned long sio_route_tab __initdata = 0;
static void __init
-sio_pci_fixup(int (*map_irq)(struct pci_dev *dev, int sel, int pin),
- unsigned long new_route_tab)
+sio_pci_route(void)
{
- unsigned int route_tab;
-
- /* Examine or update the PCI routing table. */
- pcibios_read_config_dword(0, PCI_DEVFN(7, 0), 0x60, &route_tab);
-
- sio_route_tab = route_tab;
- if (PCI_MODIFY) {
- sio_route_tab = new_route_tab;
- pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60,
- new_route_tab);
- }
-
- /* Update all the IRQs. */
- common_pci_fixup(map_irq, common_swizzle);
+ pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60,
+ alpha_mv.sys.sio.route_tab);
}
static unsigned int __init
@@ -180,7 +179,7 @@ sio_fixup_irq_levels(unsigned int level_bits)
}
static inline int __init
-noname_map_irq(struct pci_dev *dev, int slot, int pin)
+noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
/*
* The Noname board has 5 PCI slots with each of the 4
@@ -214,49 +213,12 @@ noname_map_irq(struct pci_dev *dev, int slot, int pin)
};
const long min_idsel = 6, max_idsel = 14, irqs_per_slot = 5;
int irq = COMMON_TABLE_LOOKUP, tmp;
- tmp = __kernel_extbl(sio_route_tab, irq);
+ tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
return irq >= 0 ? tmp : -1;
}
-static inline void __init
-noname_pci_fixup(void)
-{
- /*
- * For UDB, the only available PCI slot must not map to IRQ 9,
- * since that's the builtin MSS sound chip. That PCI slot
- * will map to PIRQ1 (for INTA at least), so we give it IRQ 15
- * instead.
- *
- * Unfortunately we have to do this for NONAME as well, since
- * they are co-indicated when the platform type "Noname" is
- * selected... :-(
- */
- layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
- sio_pci_fixup(noname_map_irq, 0x0b0a0f0d);
- sio_fixup_irq_levels(sio_collect_irq_levels());
- enable_ide(0x26e);
-}
-
-static inline void __init
-avanti_pci_fixup(void)
-{
- layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
- sio_pci_fixup(noname_map_irq, 0x0b0a0e0f);
- sio_fixup_irq_levels(sio_collect_irq_levels());
- enable_ide(0x26e);
-}
-
-static inline void __init
-xl_pci_fixup(void)
-{
- layout_all_busses(DEFAULT_IO_BASE, XL_DEFAULT_MEM_BASE);
- sio_pci_fixup(noname_map_irq, 0x0b0a090f);
- sio_fixup_irq_levels(sio_collect_irq_levels());
- enable_ide(0x26e);
-}
-
static inline int __init
-p2k_map_irq(struct pci_dev *dev, int slot, int pin)
+p2k_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[][5] __initlocaldata = {
/*INT A B C D */
@@ -270,29 +232,27 @@ p2k_map_irq(struct pci_dev *dev, int slot, int pin)
};
const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
int irq = COMMON_TABLE_LOOKUP, tmp;
- tmp = __kernel_extbl(sio_route_tab, irq);
+ tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
return irq >= 0 ? tmp : -1;
}
static inline void __init
-p2k_pci_fixup(void)
+noname_init_pci(void)
{
- layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
- sio_pci_fixup(p2k_map_irq, 0x0b0a090f);
+ sio_pci_route();
+ common_init_pci();
sio_fixup_irq_levels(sio_collect_irq_levels());
- enable_ide(0x26e);
+ ns87312_enable_ide(0x26e);
}
static inline void __init
-alphabook1_pci_fixup(void)
+alphabook1_init_pci(void)
{
struct pci_dev *dev;
unsigned char orig, config;
- layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
-
- /* For the AlphaBook1, NCR810 SCSI is 14, PCMCIA controller is 15. */
- sio_pci_fixup(noname_map_irq, 0x0e0f0a0a);
+ sio_pci_route();
+ common_init_pci();
/*
* On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
@@ -304,20 +264,17 @@ alphabook1_pci_fixup(void)
* moment (2.0.29), ncr53c8xx.c does NOT do this, but
* 53c7,8xx.c DOES.
*/
- for (dev = pci_devices; dev; dev = dev->next) {
- if (dev->vendor == PCI_VENDOR_ID_NCR &&
- (dev->device == PCI_DEVICE_ID_NCR_53C810 ||
- dev->device == PCI_DEVICE_ID_NCR_53C815 ||
- dev->device == PCI_DEVICE_ID_NCR_53C820 ||
- dev->device == PCI_DEVICE_ID_NCR_53C825)) {
- unsigned int io_port;
+
+ dev = NULL;
+ while ((dev = pci_find_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {
+ if (dev->device == PCI_DEVICE_ID_NCR_53C810
+ || dev->device == PCI_DEVICE_ID_NCR_53C815
+ || dev->device == PCI_DEVICE_ID_NCR_53C820
+ || dev->device == PCI_DEVICE_ID_NCR_53C825) {
+ unsigned long io_port;
unsigned char ctest4;
- pcibios_read_config_dword(dev->bus->number,
- dev->devfn,
- PCI_BASE_ADDRESS_0,
- &io_port);
- io_port &= PCI_BASE_ADDRESS_IO_MASK;
+ io_port = dev->resource[0].start;
ctest4 = inb(io_port+0x21);
if (!(ctest4 & 0x80)) {
printk("AlphaBook1 NCR init: setting"
@@ -356,18 +313,27 @@ struct alpha_machine_vector alphabook1_mv __initmv = {
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 16,
irq_probe_mask: _PROBE_MASK(16),
update_irq_hw: sio_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: isa_device_interrupt,
init_arch: alphabook1_init_arch,
init_irq: sio_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: alphabook1_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: alphabook1_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: noname_map_irq,
+ pci_swizzle: common_swizzle,
+
+ sys: { sio: {
+ /* NCR810 SCSI is 14, PCMCIA controller is 15. */
+ route_tab: 0x0e0f0a0a,
+ }}
};
ALIAS_MV(alphabook1)
#endif
@@ -381,18 +347,26 @@ struct alpha_machine_vector avanti_mv __initmv = {
DO_APECS_BUS,
machine_check: apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 16,
irq_probe_mask: _PROBE_MASK(16),
update_irq_hw: sio_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: isa_device_interrupt,
init_arch: apecs_init_arch,
init_irq: sio_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: avanti_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: noname_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: noname_map_irq,
+ pci_swizzle: common_swizzle,
+
+ sys: { sio: {
+ route_tab: 0x0b0a0e0f,
+ }}
};
ALIAS_MV(avanti)
#endif
@@ -406,18 +380,35 @@ struct alpha_machine_vector noname_mv __initmv = {
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 16,
irq_probe_mask: _PROBE_MASK(16),
update_irq_hw: sio_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: srm_device_interrupt,
init_arch: lca_init_arch,
init_irq: sio_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: noname_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: noname_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: noname_map_irq,
+ pci_swizzle: common_swizzle,
+
+ sys: { sio: {
+ /* For UDB, the only available PCI slot must not map to IRQ 9,
+ since that's the builtin MSS sound chip. That PCI slot
+ will map to PIRQ1 (for INTA at least), so we give it IRQ 15
+ instead.
+
+ Unfortunately we have to do this for NONAME as well, since
+ they are co-indicated when the platform type "Noname" is
+ selected... :-( */
+
+ route_tab: 0x0b0a0f0d,
+ }}
};
ALIAS_MV(noname)
#endif
@@ -431,18 +422,26 @@ struct alpha_machine_vector p2k_mv __initmv = {
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
nr_irqs: 16,
irq_probe_mask: P2K_PROBE_MASK,
update_irq_hw: sio_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: srm_device_interrupt,
init_arch: lca_init_arch,
init_irq: sio_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: p2k_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: noname_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: p2k_map_irq,
+ pci_swizzle: common_swizzle,
+
+ sys: { sio: {
+ route_tab: 0x0b0a090f,
+ }}
};
ALIAS_MV(p2k)
#endif
@@ -456,18 +455,26 @@ struct alpha_machine_vector xl_mv __initmv = {
BUS(apecs_xl),
machine_check: apecs_machine_check,
max_dma_address: ALPHA_XL_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: XL_DEFAULT_MEM_BASE,
nr_irqs: 16,
irq_probe_mask: _PROBE_MASK(16),
update_irq_hw: sio_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: isa_device_interrupt,
init_arch: xl_init_arch,
init_irq: sio_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: xl_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: noname_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: noname_map_irq,
+ pci_swizzle: common_swizzle,
+
+ sys: { sio: {
+ route_tab: 0x0b0a090f,
+ }}
};
ALIAS_MV(xl)
#endif
diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c
index a35fdd219..a8c7698fb 100644
--- a/arch/alpha/kernel/sys_sx164.c
+++ b/arch/alpha/kernel/sys_sx164.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1995 David A Rusling
* Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the SX164 (PCA56+PYXIS).
*/
@@ -26,9 +26,9 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
@@ -164,7 +164,7 @@ sx164_init_irq(void)
*/
static int __init
-sx164_map_irq(struct pci_dev *dev, int slot, int pin)
+sx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[5][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
@@ -179,10 +179,9 @@ sx164_map_irq(struct pci_dev *dev, int slot, int pin)
}
void __init
-sx164_pci_fixup(void)
+sx164_init_pci(void)
{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(sx164_map_irq, common_swizzle);
+ common_init_pci();
SMC669_Init(0);
}
@@ -199,17 +198,21 @@ struct alpha_machine_vector sx164_mv __initmv = {
DO_PYXIS_BUS,
machine_check: pyxis_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 40,
irq_probe_mask: _PROBE_MASK(40),
update_irq_hw: sx164_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: sx164_device_interrupt,
init_arch: pyxis_init_arch,
init_irq: sx164_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: sx164_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: sx164_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: sx164_map_irq,
+ pci_swizzle: common_swizzle,
};
ALIAS_MV(sx164)
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
index c554a9fa1..c592ee65e 100644
--- a/arch/alpha/kernel/sys_takara.c
+++ b/arch/alpha/kernel/sys_takara.c
@@ -25,9 +25,9 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq.h"
-#include "bios32.h"
-#include "machvec.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
static void
@@ -127,7 +127,7 @@ takara_init_irq(void)
*/
static int __init
-takara_map_irq(struct pci_dev *dev, int slot, int pin)
+takara_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[15][5] __initlocaldata = {
{ 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */
@@ -150,16 +150,18 @@ takara_map_irq(struct pci_dev *dev, int slot, int pin)
return COMMON_TABLE_LOOKUP;
}
-static int __init
-takara_swizzle(struct pci_dev *dev, int *pinp)
+static u8 __init
+takara_swizzle(struct pci_dev *dev, u8 *pinp)
{
int slot = PCI_SLOT(dev->devfn);
int pin = *pinp;
unsigned int ctlreg = inl(0x500);
unsigned int busslot = PCI_SLOT(dev->bus->self->devfn);
- /* Check first for built-in bridges. */
- if (busslot > 16 && ((1<<(36-busslot)) & ctlreg)) {
+ /* Check for built-in bridges. */
+ if (dev->bus->number != 0
+ && busslot > 16
+ && ((1<<(36-busslot)) & ctlreg)) {
if (pin == 1)
pin += (20 - busslot);
else {
@@ -174,11 +176,10 @@ takara_swizzle(struct pci_dev *dev, int *pinp)
}
static void __init
-takara_pci_fixup(void)
+takara_init_pci(void)
{
- layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
- common_pci_fixup(takara_map_irq, takara_swizzle);
- /* enable_ide(0x26e); */
+ common_init_pci();
+ /* ns87312_enable_ide(0x26e); */
}
@@ -194,17 +195,21 @@ struct alpha_machine_vector takara_mv __initmv = {
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: CIA_DEFAULT_MEM_BASE,
nr_irqs: 20,
irq_probe_mask: _PROBE_MASK(20),
update_irq_hw: takara_update_irq_hw,
- ack_irq: generic_ack_irq,
+ ack_irq: common_ack_irq,
device_interrupt: takara_device_interrupt,
init_arch: cia_init_arch,
init_irq: takara_init_irq,
- init_pit: generic_init_pit,
- pci_fixup: takara_pci_fixup,
- kill_arch: generic_kill_arch,
+ init_pit: common_init_pit,
+ init_pci: takara_init_pci,
+ kill_arch: common_kill_arch,
+ pci_map_irq: takara_map_irq,
+ pci_swizzle: takara_swizzle,
};
ALIAS_MV(takara)
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index e7f32dc9a..a86c79cc1 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -40,7 +40,7 @@
#include <linux/timex.h>
#include "proto.h"
-#include "irq.h"
+#include "irq_impl.h"
extern rwlock_t xtime_lock;
extern volatile unsigned long lost_ticks; /* kernel/sched.c */
@@ -94,6 +94,10 @@ void timer_interrupt(int irq, void *dev, struct pt_regs * regs)
smp_percpu_timer_interrupt(regs);
if (smp_processor_id() != smp_boot_cpuid)
return;
+#else
+ /* Not SMP, do kernel PC profiling here. */
+ if (!user_mode(regs))
+ alpha_do_profile(regs->pc);
#endif
write_lock(&xtime_lock);
@@ -180,8 +184,6 @@ rtc_init_pit (void)
CMOS_WRITE(control, RTC_CONTROL);
(void) CMOS_READ(RTC_INTR_FLAGS);
- request_region(0x40, 0x20, "timer"); /* reserve pit */
-
/* Setup interval timer. */
outb(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */
outb(LATCH & 0xff, 0x40); /* LSB */
@@ -194,7 +196,7 @@ rtc_init_pit (void)
#endif
void
-generic_init_pit (void)
+common_init_pit (void)
{
unsigned char x;
@@ -215,8 +217,6 @@ generic_init_pit (void)
}
(void) CMOS_READ(RTC_INTR_FLAGS);
- request_region(RTC_PORT(0), 0x10, "timer"); /* reserve rtc */
-
outb(0x36, 0x43); /* pit counter 0: system timer */
outb(0x00, 0x40);
outb(0x00, 0x40);
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 1b490b9c1..59f021a77 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -22,7 +22,7 @@
#include "proto.h"
-static void
+void
dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
{
printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx\n",
@@ -103,12 +103,12 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
dik_show_code((unsigned int *)regs->pc);
dik_show_trace((unsigned long *)(regs+1));
- if (current->tss.flags & (1UL << 63)) {
+ if (current->thread.flags & (1UL << 63)) {
printk("die_if_kernel recursion detected.\n");
sti();
while (1);
}
- current->tss.flags |= (1UL << 63);
+ current->thread.flags |= (1UL << 63);
do_exit(SIGSEGV);
}
@@ -154,7 +154,9 @@ do_entIF(unsigned long type, unsigned long a1,
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, struct pt_regs regs)
{
- die_if_kernel("Instruction fault", &regs, type, 0);
+ die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"),
+ &regs, type, 0);
+
switch (type) {
case 0: /* breakpoint */
if (ptrace_cancel_bpt(current)) {
@@ -494,12 +496,12 @@ got_exception:
dik_show_code((unsigned int *)pc);
dik_show_trace((unsigned long *)(&regs+1));
- if (current->tss.flags & (1UL << 63)) {
+ if (current->thread.flags & (1UL << 63)) {
printk("die_if_kernel recursion detected.\n");
sti();
while (1);
}
- current->tss.flags |= (1UL << 63);
+ current->thread.flags |= (1UL << 63);
do_exit(SIGSEGV);
}
@@ -601,7 +603,7 @@ do_entUnaUser(void * va, unsigned long opcode,
/* Check the UAC bits to decide what the user wants us to do
with the unaliged access. */
- uac_bits = (current->tss.flags >> UAC_SHIFT) & UAC_BITMASK;
+ uac_bits = (current->thread.flags >> UAC_SHIFT) & UAC_BITMASK;
if (!(uac_bits & UAC_NOPRINT)) {
if (cnt >= 5 && jiffies - last_time > 5*HZ) {
cnt = 0;
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
index 400adf0e1..f550ba7cb 100644
--- a/arch/alpha/lib/Makefile
+++ b/arch/alpha/lib/Makefile
@@ -5,7 +5,7 @@
OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
checksum.o csum_partial_copy.o strlen.o \
strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
- strchr.o strrchr.o \
+ strchr.o strrchr.o memchr.o \
copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
csum_ipv6_magic.o strcasecmp.o semaphore.o \
srm_dispatch.o srm_fixup.o srm_puts.o srm_printk.o
diff --git a/arch/alpha/lib/io.c b/arch/alpha/lib/io.c
index 71ba9d4bf..25de0f871 100644
--- a/arch/alpha/lib/io.c
+++ b/arch/alpha/lib/io.c
@@ -37,45 +37,96 @@ void _outl(unsigned int b, unsigned long addr)
__outl(b, addr);
}
+unsigned long ___raw_readb(unsigned long addr)
+{
+ return __readb(addr);
+}
+
+unsigned long ___raw_readw(unsigned long addr)
+{
+ return __readw(addr);
+}
+
+unsigned long ___raw_readl(unsigned long addr)
+{
+ return __readl(addr);
+}
+
+unsigned long ___raw_readq(unsigned long addr)
+{
+ return __readq(addr);
+}
unsigned long _readb(unsigned long addr)
{
- return __readb(addr);
+ unsigned long r = __readb(addr);
+ mb();
+ return r;
}
unsigned long _readw(unsigned long addr)
{
- return __readw(addr);
+ unsigned long r = __readw(addr);
+ mb();
+ return r;
}
unsigned long _readl(unsigned long addr)
{
- return __readl(addr);
+ unsigned long r = __readl(addr);
+ mb();
+ return r;
}
unsigned long _readq(unsigned long addr)
{
- return __readq(addr);
+ unsigned long r = __readq(addr);
+ mb();
+ return r;
+}
+
+void ___raw_writeb(unsigned char b, unsigned long addr)
+{
+ __writeb(b, addr);
+}
+
+void ___raw_writew(unsigned short b, unsigned long addr)
+{
+ __writew(b, addr);
+}
+
+void ___raw_writel(unsigned int b, unsigned long addr)
+{
+ __writel(b, addr);
+}
+
+void ___raw_writeq(unsigned long b, unsigned long addr)
+{
+ __writeq(b, addr);
}
void _writeb(unsigned char b, unsigned long addr)
{
__writeb(b, addr);
+ mb();
}
void _writew(unsigned short b, unsigned long addr)
{
__writew(b, addr);
+ mb();
}
void _writel(unsigned int b, unsigned long addr)
{
__writel(b, addr);
+ mb();
}
void _writeq(unsigned long b, unsigned long addr)
{
__writeq(b, addr);
+ mb();
}
/*
@@ -363,7 +414,7 @@ void _memcpy_fromio(void * to, unsigned long from, long count)
if (count >= 8 && ((long)to & 7) == (from & 7)) {
count -= 8;
do {
- *(u64 *)to = readq(from);
+ *(u64 *)to = __raw_readq(from);
count -= 8;
to += 8;
from += 8;
@@ -374,7 +425,7 @@ void _memcpy_fromio(void * to, unsigned long from, long count)
if (count >= 4 && ((long)to & 3) == (from & 3)) {
count -= 4;
do {
- *(u32 *)to = readl(from);
+ *(u32 *)to = __raw_readl(from);
count -= 4;
to += 4;
from += 4;
@@ -385,7 +436,7 @@ void _memcpy_fromio(void * to, unsigned long from, long count)
if (count >= 2 && ((long)to & 1) == (from & 1)) {
count -= 2;
do {
- *(u16 *)to = readw(from);
+ *(u16 *)to = __raw_readw(from);
count -= 2;
to += 2;
from += 2;
@@ -394,7 +445,7 @@ void _memcpy_fromio(void * to, unsigned long from, long count)
}
while (count > 0) {
- *(u8 *) to = readb(from);
+ *(u8 *) to = __raw_readb(from);
count--;
to++;
from++;
@@ -414,7 +465,7 @@ void _memcpy_toio(unsigned long to, const void * from, long count)
if (count >= 8 && (to & 7) == ((long)from & 7)) {
count -= 8;
do {
- writeq(*(const u64 *)from, to);
+ __raw_writeq(*(const u64 *)from, to);
count -= 8;
to += 8;
from += 8;
@@ -425,7 +476,7 @@ void _memcpy_toio(unsigned long to, const void * from, long count)
if (count >= 4 && (to & 3) == ((long)from & 3)) {
count -= 4;
do {
- writel(*(const u32 *)from, to);
+ __raw_writel(*(const u32 *)from, to);
count -= 4;
to += 4;
from += 4;
@@ -436,7 +487,7 @@ void _memcpy_toio(unsigned long to, const void * from, long count)
if (count >= 2 && (to & 1) == ((long)from & 1)) {
count -= 2;
do {
- writew(*(const u16 *)from, to);
+ __raw_writew(*(const u16 *)from, to);
count -= 2;
to += 2;
from += 2;
@@ -445,11 +496,12 @@ void _memcpy_toio(unsigned long to, const void * from, long count)
}
while (count > 0) {
- writeb(*(const u8 *) from, to);
+ __raw_writeb(*(const u8 *) from, to);
count--;
to++;
from++;
}
+ mb();
}
/*
@@ -459,21 +511,21 @@ void _memset_c_io(unsigned long to, unsigned long c, long count)
{
/* Handle any initial odd byte */
if (count > 0 && (to & 1)) {
- writeb(c, to);
+ __raw_writeb(c, to);
to++;
count--;
}
/* Handle any initial odd halfword */
if (count >= 2 && (to & 2)) {
- writew(c, to);
+ __raw_writew(c, to);
to += 2;
count -= 2;
}
/* Handle any initial odd word */
if (count >= 4 && (to & 4)) {
- writel(c, to);
+ __raw_writel(c, to);
to += 4;
count -= 4;
}
@@ -483,7 +535,7 @@ void _memset_c_io(unsigned long to, unsigned long c, long count)
count -= 8;
if (count >= 0) {
do {
- writeq(c, to);
+ __raw_writeq(c, to);
to += 8;
count -= 8;
} while (count >= 0);
@@ -492,20 +544,21 @@ void _memset_c_io(unsigned long to, unsigned long c, long count)
/* The tail is word-aligned if we still have count >= 4 */
if (count >= 4) {
- writel(c, to);
+ __raw_writel(c, to);
to += 4;
count -= 4;
}
/* The tail is half-word aligned if we have count >= 2 */
if (count >= 2) {
- writew(c, to);
+ __raw_writew(c, to);
to += 2;
count -= 2;
}
/* And finally, one last byte.. */
if (count) {
- writeb(c, to);
+ __raw_writeb(c, to);
}
+ mb();
}
diff --git a/arch/alpha/lib/memchr.S b/arch/alpha/lib/memchr.S
new file mode 100644
index 000000000..14427eeb5
--- /dev/null
+++ b/arch/alpha/lib/memchr.S
@@ -0,0 +1,164 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Finds characters in a memory area. Optimized for the Alpha:
+
+ - memory accessed as aligned quadwords only
+ - uses cmpbge to compare 8 bytes in parallel
+ - does binary search to find 0 byte in last
+ quadword (HAKMEM needed 12 instructions to
+ do this instead of the 9 instructions that
+ binary search needs).
+
+For correctness consider that:
+
+ - only minimum number of quadwords may be accessed
+ - the third argument is an unsigned long
+*/
+
+ .set noreorder
+ .set noat
+
+ .globl memchr
+ .ent memchr
+memchr:
+ .frame $30,0,$26,0
+ .prologue 0
+
+ # Hack -- if someone passes in (size_t)-1, hoping to just
+ # search til the end of the address space, we will overflow
+ # below when we find the address of the last byte. Given
+ # that we will never have a 56-bit address space, cropping
+ # the length is the easiest way to avoid trouble.
+ zap $18, 0x80, $5 #-e0 :
+
+ beq $18, $not_found # .. e1 :
+ ldq_u $1, 0($16) # e1 : load first quadword
+ insbl $17, 1, $2 # .. e0 : $2 = 000000000000ch00
+ and $17, 0xff, $17 #-e0 : $17 = 00000000000000ch
+ cmpult $18, 9, $4 # .. e1 :
+ or $2, $17, $17 # e0 : $17 = 000000000000chch
+ lda $3, -1($31) # .. e1 :
+ sll $17, 16, $2 #-e0 : $2 = 00000000chch0000
+ addq $16, $5, $5 # .. e1 :
+ or $2, $17, $17 # e1 : $17 = 00000000chchchch
+ unop # :
+ sll $17, 32, $2 #-e0 : $2 = chchchch00000000
+ or $2, $17, $17 # e1 : $17 = chchchchchchchch
+ extql $1, $16, $7 # e0 :
+ beq $4, $first_quad # .. e1 :
+
+ ldq_u $6, -1($5) #-e1 : eight or less bytes to search
+ extqh $6, $16, $6 # .. e0 :
+ mov $16, $0 # e0 :
+ or $7, $6, $1 # .. e1 : $1 = quadword starting at $16
+
+ # Deal with the case where at most 8 bytes remain to be searched
+ # in $1. E.g.:
+ # $18 = 6
+ # $1 = ????c6c5c4c3c2c1
+$last_quad:
+ negq $18, $6 #-e0 :
+ xor $17, $1, $1 # .. e1 :
+ srl $3, $6, $6 # e0 : $6 = mask of $18 bits set
+ cmpbge $31, $1, $2 # .. e1 :
+ and $2, $6, $2 #-e0 :
+ beq $2, $not_found # .. e1 :
+
+$found_it:
+ # Now, determine which byte matched:
+ negq $2, $3 # e0 :
+ and $2, $3, $2 # e1 :
+
+ and $2, 0x0f, $1 #-e0 :
+ addq $0, 4, $3 # .. e1 :
+ cmoveq $1, $3, $0 # e0 :
+
+ addq $0, 2, $3 # .. e1 :
+ and $2, 0x33, $1 #-e0 :
+ cmoveq $1, $3, $0 # .. e1 :
+
+ and $2, 0x55, $1 # e0 :
+ addq $0, 1, $3 # .. e1 :
+ cmoveq $1, $3, $0 #-e0 :
+
+$done: ret # .. e1 :
+
+ # Deal with the case where $18 > 8 bytes remain to be
+ # searched. $16 may not be aligned.
+ .align 4
+$first_quad:
+ andnot $16, 0x7, $0 #-e1 :
+ insqh $3, $16, $2 # .. e0 : $2 = 0000ffffffffffff ($16<0:2> ff)
+ xor $1, $17, $1 # e0 :
+ or $1, $2, $1 # e1 : $1 = ====ffffffffffff
+ cmpbge $31, $1, $2 #-e0 :
+ bne $2, $found_it # .. e1 :
+
+ # At least one byte left to process.
+
+ ldq $1, 8($0) # e0 :
+ subq $5, 1, $18 # .. e1 :
+ addq $0, 8, $0 #-e0 :
+
+ # Make $18 point to last quad to be accessed (the
+ # last quad may or may not be partial).
+
+ andnot $18, 0x7, $18 # .. e1 :
+ cmpult $0, $18, $2 # e0 :
+ beq $2, $final # .. e1 :
+
+ # At least two quads remain to be accessed.
+
+ subq $18, $0, $4 #-e0 : $4 <- nr quads to be processed
+ and $4, 8, $4 # e1 : odd number of quads?
+ bne $4, $odd_quad_count # e1 :
+
+ # At least three quads remain to be accessed
+
+ mov $1, $4 # e0 : move prefetched value to correct reg
+
+ .align 4
+$unrolled_loop:
+ ldq $1, 8($0) #-e0 : prefetch $1
+ xor $17, $4, $2 # .. e1 :
+ cmpbge $31, $2, $2 # e0 :
+ bne $2, $found_it # .. e1 :
+
+ addq $0, 8, $0 #-e0 :
+$odd_quad_count:
+ xor $17, $1, $2 # .. e1 :
+ ldq $4, 8($0) # e0 : prefetch $4
+ cmpbge $31, $2, $2 # .. e1 :
+ addq $0, 8, $6 #-e0 :
+ bne $2, $found_it # .. e1 :
+
+ cmpult $6, $18, $6 # e0 :
+ addq $0, 8, $0 # .. e1 :
+ bne $6, $unrolled_loop #-e1 :
+
+ mov $4, $1 # e0 : move prefetched value into $1
+$final: subq $5, $0, $18 # .. e1 : $18 <- number of bytes left to do
+ bne $18, $last_quad # e1 :
+
+$not_found:
+ mov $31, $0 #-e0 :
+ ret # .. e1 :
+
+ .end memchr
diff --git a/arch/alpha/math-emu/fp-emul.c b/arch/alpha/math-emu/fp-emul.c
index 122ec85ac..c2ebbbb60 100644
--- a/arch/alpha/math-emu/fp-emul.c
+++ b/arch/alpha/math-emu/fp-emul.c
@@ -107,7 +107,7 @@ long
alpha_fp_emul (unsigned long pc)
{
unsigned long op_fun, fa, fb, fc, func, mode;
- unsigned long fpcw = current->tss.flags;
+ unsigned long fpcw = current->thread.flags;
unsigned long va, vb, vc, res, fpcr;
__u32 insn;
@@ -255,7 +255,7 @@ alpha_fp_emul (unsigned long pc)
*/
if (res) {
/* Record exceptions in software control word. */
- current->tss.flags = fpcw |= res >> 35;
+ current->thread.flags = fpcw |= res >> 35;
/* Update hardware control register */
fpcr &= (~FPCR_MASK | FPCR_DYN_MASK);
diff --git a/arch/alpha/math-emu/ieee-math.c b/arch/alpha/math-emu/ieee-math.c
index 224fdd2b7..9a86b1048 100644
--- a/arch/alpha/math-emu/ieee-math.c
+++ b/arch/alpha/math-emu/ieee-math.c
@@ -704,20 +704,21 @@ ieee_CVTQS (int f, unsigned long a, unsigned long *b)
* FPCR_INV if invalid operation occurred, etc.
*/
unsigned long
-ieee_CVTQT (int f, unsigned long a, unsigned long *b)
+ieee_CVTQT (int f, long a, unsigned long *b)
{
EXTENDED op_b;
- op_b.s = 0;
- op_b.f[0] = a;
- op_b.f[1] = 0;
- if (sign(a) < 0) {
- op_b.s = 1;
- op_b.f[0] = -a;
+ if (a != 0) {
+ op_b.s = (a < 0 ? 1 : 0);
+ op_b.f[0] = (a < 0 ? -a : a);
+ op_b.f[1] = 0;
+ op_b.e = 55;
+ normalize(&op_b);
+ return round_t_ieee(f, &op_b, b);
+ } else {
+ *b = 0;
+ return 0;
}
- op_b.e = 55;
- normalize(&op_b);
- return round_t_ieee(f, &op_b, b);
}
diff --git a/arch/alpha/math-emu/ieee-math.h b/arch/alpha/math-emu/ieee-math.h
index 1b3cf2694..076a6d1c8 100644
--- a/arch/alpha/math-emu/ieee-math.h
+++ b/arch/alpha/math-emu/ieee-math.h
@@ -20,7 +20,7 @@
extern unsigned long ieee_CVTST (int rm, unsigned long a, unsigned long *b);
extern unsigned long ieee_CVTTS (int rm, unsigned long a, unsigned long *b);
extern unsigned long ieee_CVTQS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTQT (int rm, unsigned long a, unsigned long *b);
+extern unsigned long ieee_CVTQT (int rm, long a, unsigned long *b);
extern unsigned long ieee_CVTTQ (int rm, unsigned long a, unsigned long *b);
extern unsigned long ieee_CMPTEQ (unsigned long a, unsigned long b,
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 5cf6e4ab0..dc15db08b 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -22,6 +22,7 @@
#include <linux/mman.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -37,12 +38,9 @@ extern void die_if_kernel(char *,struct pt_regs *,long, unsigned long *);
unsigned long last_asn = ASN_FIRST_VERSION;
#endif
-void
-get_new_mmu_context(struct task_struct *p, struct mm_struct *mm)
+void ev5_flush_tlb_current(struct mm_struct *mm)
{
- unsigned long new = __get_new_mmu_context(p, mm);
- p->tss.mm_context = new;
- p->tss.asn = new & HARDWARE_ASN_MASK;
+ ev5_activate_mm(NULL, mm, smp_processor_id());
}
@@ -78,7 +76,8 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
{
struct vm_area_struct * vma;
struct mm_struct *mm = current->mm;
- unsigned fixup;
+ unsigned int fixup;
+ int fault;
/* As of EV6, a load into $31/$f31 is a prefetch, and never faults
(or is suppressed by the PALcode). Support that for older CPUs
@@ -94,8 +93,12 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
}
}
+ /* If we're in an interrupt context, or have no user context,
+ we must not take the fault. */
+ if (!mm || in_interrupt())
+ goto no_context;
+
down(&mm->mmap_sem);
- lock_kernel();
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
@@ -121,9 +124,21 @@ good_area:
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
}
- handle_mm_fault(current, vma, address, cause > 0);
+
+ /*
+ * If for any reason at all we couldn't handle the fault,
+ * make sure we exit gracefully rather than endlessly redo
+ * the fault.
+ */
+ fault = handle_mm_fault(current, vma, address, cause > 0);
up(&mm->mmap_sem);
- goto out;
+
+ if (fault < 0)
+ goto out_of_memory;
+ if (fault == 0)
+ goto do_sigbus;
+
+ return;
/*
* Something tried to access memory that isn't in our memory map..
@@ -134,9 +149,10 @@ bad_area:
if (user_mode(regs)) {
force_sig(SIGSEGV, current);
- goto out;
+ return;
}
+no_context:
/* Are we prepared to handle this fault as an exception? */
if ((fixup = search_exception_table(regs->pc)) != 0) {
unsigned long newpc;
@@ -144,7 +160,7 @@ bad_area:
printk("%s: Exception at [<%lx>] (%lx)\n",
current->comm, regs->pc, newpc);
regs->pc = newpc;
- goto out;
+ return;
}
/*
@@ -155,7 +171,25 @@ bad_area:
"virtual address %016lx\n", address);
die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
do_exit(SIGKILL);
- out:
- unlock_kernel();
-}
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+ printk(KERN_ALERT "VM: killing process %s(%d)\n",
+ current->comm, current->pid);
+ if (!user_mode(regs))
+ goto no_context;
+ do_exit(SIGKILL);
+
+do_sigbus:
+ /*
+ * Send a sigbus, regardless of whether we were in kernel
+ * or user mode.
+ */
+ force_sig(SIGBUS, current);
+ if (!user_mode(regs))
+ goto no_context;
+ return;
+}
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 69f4e038c..86cf4c925 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -173,12 +173,12 @@ show_mem(void)
extern unsigned long free_area_init(unsigned long, unsigned long);
-static inline struct thread_struct *
+static inline unsigned long
load_PCB(struct thread_struct * pcb)
{
register unsigned long sp __asm__("$30");
pcb->ksp = sp;
- return __reload_tss(pcb);
+ return __reload_thread(pcb);
}
/*
@@ -192,7 +192,7 @@ paging_init(unsigned long start_mem, unsigned long end_mem)
unsigned long newptbr;
struct memclust_struct * cluster;
struct memdesc_struct * memdesc;
- struct thread_struct *original_pcb_ptr;
+ unsigned long original_pcb_ptr;
/* initialize mem_map[] */
start_mem = free_area_init(start_mem, end_mem);
@@ -233,10 +233,10 @@ paging_init(unsigned long start_mem, unsigned long end_mem)
}
/* Also set up the real kernel PCB while we're at it. */
- init_task.tss.ptbr = newptbr;
- init_task.tss.pal_flags = 1; /* set FEN, clear everything else */
- init_task.tss.flags = 0;
- original_pcb_ptr = load_PCB(&init_task.tss);
+ init_task.thread.ptbr = newptbr;
+ init_task.thread.pal_flags = 1; /* set FEN, clear everything else */
+ init_task.thread.flags = 0;
+ original_pcb_ptr = load_PCB(&init_task.thread);
tbia();
/* Save off the contents of the original PCB so that we can
@@ -246,11 +246,11 @@ paging_init(unsigned long start_mem, unsigned long end_mem)
since KSEG values also happen to work, folks get confused.
Check this here. */
- if ((unsigned long)original_pcb_ptr < PAGE_OFFSET) {
- original_pcb_ptr = (struct thread_struct *)
- phys_to_virt((unsigned long) original_pcb_ptr);
+ if (original_pcb_ptr < PAGE_OFFSET) {
+ original_pcb_ptr = (unsigned long)
+ phys_to_virt(original_pcb_ptr);
}
- original_pcb = *original_pcb_ptr;
+ original_pcb = *(struct thread_struct *) original_pcb_ptr;
return start_mem;
}
diff --git a/arch/alpha/vmlinux.lds b/arch/alpha/vmlinux.lds
index 0fb2276ea..94270b390 100644
--- a/arch/alpha/vmlinux.lds
+++ b/arch/alpha/vmlinux.lds
@@ -2,11 +2,11 @@ OUTPUT_FORMAT("elf64-alpha")
ENTRY(__start)
SECTIONS
{
- . = 0xfffffc0000310000;
- _text = .;
- .text : { *(.text) }
- .text2 : { *(.text2) }
- _etext = .;
+ . = 0xfffffc0000310000;
+ _text = .;
+ .text : { *(.text) }
+ .text2 : { *(.text2) }
+ _etext = .;
/* Exception table */
. = ALIGN(16);
@@ -26,6 +26,17 @@ SECTIONS
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
+
+ . = ALIGN(16);
+ __setup_start = .;
+ .setup.init : { *(.setup.init) }
+ __setup_end = .;
+
+ . = ALIGN(8);
+ __initcall_start = .;
+ .initcall.init : { *(.initcall.init) }
+ __initcall_end = .;
+
. = ALIGN(2*8192); /* Align double page for init_task_union */
__init_end = .;
@@ -34,6 +45,7 @@ SECTIONS
/* Global data */
_data = .;
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
.rodata : { *(.rodata) }
.data : { *(.data) CONSTRUCTORS }
.got : { *(.got) }
@@ -47,4 +59,27 @@ SECTIONS
.mdebug 0 : { *(.mdebug) }
.note 0 : { *(.note) }
.comment 0 : { *(.comment) }
+
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
}