summaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/alpha/kernel')
-rw-r--r--arch/alpha/kernel/Makefile25
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c5
-rw-r--r--arch/alpha/kernel/core_apecs.c4
-rw-r--r--arch/alpha/kernel/core_cia.c10
-rw-r--r--arch/alpha/kernel/core_irongate.c353
-rw-r--r--arch/alpha/kernel/core_lca.c4
-rw-r--r--arch/alpha/kernel/core_mcpcia.c146
-rw-r--r--arch/alpha/kernel/core_polaris.c6
-rw-r--r--arch/alpha/kernel/core_pyxis.c10
-rw-r--r--arch/alpha/kernel/core_t2.c4
-rw-r--r--arch/alpha/kernel/core_tsunami.c89
-rw-r--r--arch/alpha/kernel/fpreg.c98
-rw-r--r--arch/alpha/kernel/irq.c128
-rw-r--r--arch/alpha/kernel/irq_impl.h49
-rw-r--r--arch/alpha/kernel/machvec_impl.h10
-rw-r--r--arch/alpha/kernel/pci.c209
-rw-r--r--arch/alpha/kernel/pci_impl.h5
-rw-r--r--arch/alpha/kernel/process.c73
-rw-r--r--arch/alpha/kernel/proto.h26
-rw-r--r--arch/alpha/kernel/ptrace.c6
-rw-r--r--arch/alpha/kernel/setup.c257
-rw-r--r--arch/alpha/kernel/signal.c1
-rw-r--r--arch/alpha/kernel/smp.c62
-rw-r--r--arch/alpha/kernel/sys_alcor.c6
-rw-r--r--arch/alpha/kernel/sys_cabriolet.c8
-rw-r--r--arch/alpha/kernel/sys_dp264.c73
-rw-r--r--arch/alpha/kernel/sys_eb64p.c5
-rw-r--r--arch/alpha/kernel/sys_eiger.c215
-rw-r--r--arch/alpha/kernel/sys_jensen.c4
-rw-r--r--arch/alpha/kernel/sys_miata.c5
-rw-r--r--arch/alpha/kernel/sys_mikasa.c5
-rw-r--r--arch/alpha/kernel/sys_nautilus.c535
-rw-r--r--arch/alpha/kernel/sys_noritake.c5
-rw-r--r--arch/alpha/kernel/sys_rawhide.c109
-rw-r--r--arch/alpha/kernel/sys_ruffian.c7
-rw-r--r--arch/alpha/kernel/sys_rx164.c4
-rw-r--r--arch/alpha/kernel/sys_sable.c5
-rw-r--r--arch/alpha/kernel/sys_sio.c20
-rw-r--r--arch/alpha/kernel/sys_sx164.c4
-rw-r--r--arch/alpha/kernel/sys_takara.c72
-rw-r--r--arch/alpha/kernel/time.c23
-rw-r--r--arch/alpha/kernel/traps.c2
42 files changed, 2013 insertions, 674 deletions
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index 282147e72..9210ae57c 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -12,22 +12,20 @@
.S.o:
$(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $<
-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 \
- ptrace.o time.o fpreg.o semaphore.o
+ ptrace.o time.o semaphore.o
OX_OBJS := alpha_ksyms.o
ifdef CONFIG_ALPHA_GENERIC
-O_OBJS += core_apecs.o core_cia.o core_lca.o core_mcpcia.o core_pyxis.o \
- core_t2.o core_tsunami.o core_polaris.o \
- sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.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 \
+O_OBJS += core_apecs.o core_cia.o core_irongate.o core_lca.o core_mcpcia.o \
+ core_polaris.o core_pyxis.o core_t2.o core_tsunami.o \
+ sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \
+ sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \
+ sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \
+ sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o \
es1888.o smc37c669.o smc37c93x.o ns87312.o pci.o
else
@@ -42,6 +40,9 @@ endif
ifdef CONFIG_ALPHA_CIA
O_OBJS += core_cia.o
endif
+ifdef CONFIG_ALPHA_IRONGATE
+O_OBJS += core_irongate.o
+endif
ifdef CONFIG_ALPHA_LCA
O_OBJS += core_lca.o
endif
@@ -74,6 +75,9 @@ endif
ifneq ($(CONFIG_ALPHA_EB64P)$(CONFIG_ALPHA_EB66),)
O_OBJS += sys_eb64p.o
endif
+ifdef CONFIG_ALPHA_EIGER
+O_OBJS += sys_eiger.o
+endif
ifdef CONFIG_ALPHA_JENSEN
O_OBJS += sys_jensen.o
endif
@@ -83,6 +87,9 @@ endif
ifdef CONFIG_ALPHA_MIKASA
O_OBJS += sys_mikasa.o
endif
+ifdef CONFIG_ALPHA_NAUTILUS
+O_OBJS += sys_nautilus.o
+endif
ifdef CONFIG_ALPHA_NORITAKE
O_OBJS += sys_noritake.o
endif
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index ffd93ca9d..ef8be067c 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -27,7 +27,7 @@
#include <asm/fpu.h>
#include <asm/irq.h>
#include <asm/machvec.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/semaphore.h>
#define __KERNEL_SYSCALLS__
@@ -103,7 +103,9 @@ EXPORT_SYMBOL(hwrpb);
EXPORT_SYMBOL(wrusp);
EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(alpha_read_fp_reg);
+EXPORT_SYMBOL(alpha_read_fp_reg_s);
EXPORT_SYMBOL(alpha_write_fp_reg);
+EXPORT_SYMBOL(alpha_write_fp_reg_s);
/* In-kernel system calls. */
EXPORT_SYMBOL(kernel_thread);
@@ -123,6 +125,7 @@ EXPORT_SYMBOL(csum_tcpudp_magic);
EXPORT_SYMBOL(ip_compute_csum);
EXPORT_SYMBOL(ip_fast_csum);
EXPORT_SYMBOL(csum_partial_copy);
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
EXPORT_SYMBOL(csum_partial_copy_from_user);
EXPORT_SYMBOL(csum_ipv6_magic);
diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c
index 6a402a3e1..04e556f2e 100644
--- a/arch/alpha/kernel/core_apecs.c
+++ b/arch/alpha/kernel/core_apecs.c
@@ -357,7 +357,7 @@ struct pci_ops apecs_pci_ops =
};
void __init
-apecs_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+apecs_init_arch(void)
{
struct pci_controler *hose;
@@ -386,7 +386,7 @@ apecs_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = APECS_CONF;
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
index 4e773862b..9f628bff6 100644
--- a/arch/alpha/kernel/core_cia.c
+++ b/arch/alpha/kernel/core_cia.c
@@ -315,7 +315,7 @@ struct pci_ops cia_pci_ops =
};
void __init
-cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+cia_init_arch(void)
{
struct pci_controler *hose;
struct resource *hae_mem;
@@ -424,8 +424,8 @@ cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
- hae_mem = alloc_resource(mem_start);
+ hose = alloc_pci_controler();
+ hae_mem = alloc_resource();
hose->io_space = &ioport_resource;
hose->mem_space = hae_mem;
@@ -435,8 +435,10 @@ cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
hae_mem->start = 0;
hae_mem->end = CIA_MEM_R1_MASK;
hae_mem->name = pci_hae0_name;
+ hae_mem->flags = IORESOURCE_MEM;
- request_resource(&iomem_resource, hae_mem);
+ if (request_resource(&iomem_resource, hae_mem) < 0)
+ printk(KERN_ERR "Failed to request HAE_MEM\n");
}
static inline void
diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
new file mode 100644
index 000000000..ef686277c
--- /dev/null
+++ b/arch/alpha/kernel/core_irongate.c
@@ -0,0 +1,353 @@
+/*
+ * linux/arch/alpha/kernel/core_irongate.c
+ *
+ * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
+ *
+ * Copyright (C) 1999 Alpha Processor, Inc.,
+ * (David Daniel, Stig Telfer, Soohoon Lee)
+ *
+ * Code common to all IRONGATE core logic chips.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/pci.h>
+#include <asm/hwrpb.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_irongate.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+#include "pci_impl.h"
+
+
+/*
+ * NOTE: Herein lie back-to-back mb instructions. They are magic.
+ * One plausible explanation is that the I/O controller does not properly
+ * handle the system transaction. Another involves timing. Ho hum.
+ */
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
+# define DBG_CFG(args) printk args
+#else
+# define DBG_CFG(args)
+#endif
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address accordingly. It is therefore not safe
+ * to have concurrent invocations to configuration space access
+ * routines, but there really shouldn't be any need for this.
+ *
+ * addr[31:24] reserved
+ * addr[23:16] bus number (8 bits = 128 possible buses)
+ * addr[15:11] Device number (5 bits)
+ * addr[10: 8] function number
+ * addr[ 7: 2] register number
+ *
+ * For IRONGATE:
+ * if (bus = addr[23:16]) == 0
+ * then
+ * type 0 config cycle:
+ * addr_on_pci[31:11] = id selection for device = addr[15:11]
+ * addr_on_pci[10: 2] = addr[10: 2] ???
+ * addr_on_pci[ 1: 0] = 00
+ * else
+ * type 1 config cycle (pass on with no decoding):
+ * addr_on_pci[31:24] = 0
+ * addr_on_pci[23: 2] = addr[23: 2]
+ * addr_on_pci[ 1: 0] = 01
+ * fi
+ *
+ * Notes:
+ * The function number selects which function of a multi-function device
+ * (e.g., SCSI and Ethernet).
+ *
+ * The register selects a DWORD (32 bit) register offset. Hence it
+ * doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ * bits.
+ */
+
+static int
+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_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);
+
+ addr = (bus << 16) | (device_fn << 8) | where;
+ addr |= IRONGATE_CONF;
+
+ *pci_addr = addr;
+ DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+ return 0;
+}
+
+static int
+irongate_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = __kernel_ldbu(*(vucp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = __kernel_ldwu(*(vusp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = *(vuip)addr;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ __kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ __kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *(vuip)addr = value;
+ mb();
+ *(vuip)addr;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+struct pci_ops irongate_pci_ops =
+{
+ read_byte: irongate_read_config_byte,
+ read_word: irongate_read_config_word,
+ read_dword: irongate_read_config_dword,
+ write_byte: irongate_write_config_byte,
+ write_word: irongate_write_config_word,
+ write_dword: irongate_write_config_dword
+};
+
+#if 0
+static void
+irongate_register_dump(const char *function_name)
+{
+ printk("%s: Irongate registers:\n"
+ "\tdev_vendor\t0x%08x\n"
+ "\tstat_cmd\t0x%08x\n"
+ "\tclass\t\t0x%08x\n"
+ "\tlatency\t\t0x%08x\n"
+ "\tbar0\t\t0x%08x\n"
+ "\tbar1\t\t0x%08x\n"
+ "\tbar2\t\t0x%08x\n"
+ "\trsrvd0[0]\t0x%08x\n"
+ "\trsrvd0[1]\t0x%08x\n"
+ "\trsrvd0[2]\t0x%08x\n"
+ "\trsrvd0[3]\t0x%08x\n"
+ "\trsrvd0[4]\t0x%08x\n"
+ "\trsrvd0[5]\t0x%08x\n"
+ "\tcapptr\t\t0x%08x\n"
+ "\trsrvd1[0]\t0x%08x\n"
+ "\trsrvd1[1]\t0x%08x\n"
+ "\tbacsr10\t\t0x%08x\n"
+ "\tbacsr32\t\t0x%08x\n"
+ "\tbacsr54\t\t0x%08x\n"
+ "\trsrvd2[0]\t0x%08x\n"
+ "\tdrammap\t\t0x%08x\n"
+ "\tdramtm\t\t0x%08x\n"
+ "\tdramms\t\t0x%08x\n"
+ "\trsrvd3[0]\t0x%08x\n"
+ "\tbiu0\t\t0x%08x\n"
+ "\tbiusip\t\t0x%08x\n"
+ "\trsrvd4[0]\t0x%08x\n"
+ "\trsrvd4[1]\t0x%08x\n"
+ "\tmro\t\t0x%08x\n"
+ "\trsrvd5[0]\t0x%08x\n"
+ "\trsrvd5[1]\t0x%08x\n"
+ "\trsrvd5[2]\t0x%08x\n"
+ "\twhami\t\t0x%08x\n"
+ "\tpciarb\t\t0x%08x\n"
+ "\tpcicfg\t\t0x%08x\n"
+ "\trsrvd6[0]\t0x%08x\n"
+ "\trsrvd6[1]\t0x%08x\n"
+ "\trsrvd6[2]\t0x%08x\n"
+ "\trsrvd6[3]\t0x%08x\n"
+ "\trsrvd6[4]\t0x%08x\n"
+ "\tagpcap\t\t0x%08x\n"
+ "\tagpstat\t\t0x%08x\n"
+ "\tagpcmd\t\t0x%08x\n"
+ "\tagpva\t\t0x%08x\n"
+ "\tagpmode\t\t0x%08x\n",
+ function_name,
+ IRONGATE0->dev_vendor,
+ IRONGATE0->stat_cmd,
+ IRONGATE0->class,
+ IRONGATE0->latency,
+ IRONGATE0->bar0,
+ IRONGATE0->bar1,
+ IRONGATE0->bar2,
+ IRONGATE0->rsrvd0[0],
+ IRONGATE0->rsrvd0[1],
+ IRONGATE0->rsrvd0[2],
+ IRONGATE0->rsrvd0[3],
+ IRONGATE0->rsrvd0[4],
+ IRONGATE0->rsrvd0[5],
+ IRONGATE0->capptr,
+ IRONGATE0->rsrvd1[0],
+ IRONGATE0->rsrvd1[1],
+ IRONGATE0->bacsr10,
+ IRONGATE0->bacsr32,
+ IRONGATE0->bacsr54,
+ IRONGATE0->rsrvd2[0],
+ IRONGATE0->drammap,
+ IRONGATE0->dramtm,
+ IRONGATE0->dramms,
+ IRONGATE0->rsrvd3[0],
+ IRONGATE0->biu0,
+ IRONGATE0->biusip,
+ IRONGATE0->rsrvd4[0],
+ IRONGATE0->rsrvd4[1],
+ IRONGATE0->mro,
+ IRONGATE0->rsrvd5[0],
+ IRONGATE0->rsrvd5[1],
+ IRONGATE0->rsrvd5[2],
+ IRONGATE0->whami,
+ IRONGATE0->pciarb,
+ IRONGATE0->pcicfg,
+ IRONGATE0->rsrvd6[0],
+ IRONGATE0->rsrvd6[1],
+ IRONGATE0->rsrvd6[2],
+ IRONGATE0->rsrvd6[3],
+ IRONGATE0->rsrvd6[4],
+ IRONGATE0->agpcap,
+ IRONGATE0->agpstat,
+ IRONGATE0->agpcmd,
+ IRONGATE0->agpva,
+ IRONGATE0->agpmode);
+}
+#else
+#define irongate_register_dump(x)
+#endif
+
+int
+irongate_pci_clr_err(void)
+{
+ unsigned int nmi_ctl=0;
+ unsigned int IRONGATE_jd;
+
+again:
+ IRONGATE_jd = IRONGATE0->stat_cmd;
+ printk("Iron stat_cmd %x\n", IRONGATE_jd);
+ IRONGATE0->stat_cmd = IRONGATE_jd; /* write again clears error bits */
+ mb();
+ IRONGATE_jd = IRONGATE0->stat_cmd; /* re-read to force write */
+
+ IRONGATE_jd = IRONGATE0->dramms;
+ printk("Iron dramms %x\n", IRONGATE_jd);
+ IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */
+ mb();
+ IRONGATE_jd = IRONGATE0->dramms; /* re-read to force write */
+
+ /* Clear ALI NMI */
+ nmi_ctl = inb(0x61);
+ nmi_ctl |= 0x0c;
+ outb(nmi_ctl, 0x61);
+ nmi_ctl &= ~0x0c;
+ outb(nmi_ctl, 0x61);
+
+ IRONGATE_jd = IRONGATE0->dramms;
+ if (IRONGATE_jd & 0x300) goto again;
+
+ return 0;
+}
+
+void __init
+irongate_init_arch(void)
+{
+ struct pci_controler *hose;
+
+ irongate_pci_clr_err();
+ irongate_register_dump(__FUNCTION__);
+
+ /*
+ * Create our single hose.
+ */
+
+ hose = alloc_pci_controler();
+ hose->io_space = &ioport_resource;
+ hose->mem_space = &iomem_resource;
+ hose->config_space = IRONGATE_CONF;
+ hose->index = 0;
+}
diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c
index 8b87f8afa..266023f77 100644
--- a/arch/alpha/kernel/core_lca.c
+++ b/arch/alpha/kernel/core_lca.c
@@ -279,7 +279,7 @@ struct pci_ops lca_pci_ops =
};
void __init
-lca_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+lca_init_arch(void)
{
struct pci_controler *hose;
@@ -307,7 +307,7 @@ lca_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = LCA_CONF;
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
index 1222556d3..b4fe28849 100644
--- a/arch/alpha/kernel/core_mcpcia.c
+++ b/arch/alpha/kernel/core_mcpcia.c
@@ -43,7 +43,7 @@
# define DBG_CFG(args)
#endif
-#define MCPCIA_MAX_HOSES 2
+#define MCPCIA_MAX_HOSES 4
/* Dodge has PCI0 and PCI1 at MID 4 and 5 respectively. Durango adds
PCI2 and PCI3 at MID 6 and 7 respectively. */
@@ -205,7 +205,7 @@ mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose,
static int
mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr, w;
unsigned char type1;
@@ -221,7 +221,7 @@ mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
static int
mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr, w;
unsigned char type1;
@@ -237,7 +237,7 @@ mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
static int
mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr;
unsigned char type1;
@@ -252,7 +252,7 @@ mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
static int
mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr;
unsigned char type1;
@@ -305,6 +305,7 @@ mcpcia_probe_hose(int h)
mb();
mb();
draina();
+ wrmces(7);
mcheck_expected(cpu) = 1;
mcheck_taken(cpu) = 0;
mcheck_extra(cpu) = mid;
@@ -327,16 +328,16 @@ mcpcia_probe_hose(int h)
}
static void __init
-mcpcia_new_hose(unsigned long *mem_start, int h)
+mcpcia_new_hose(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 = alloc_pci_controler();
+ io = alloc_resource();
+ mem = alloc_resource();
+ hae_mem = alloc_resource();
hose->io_space = io;
hose->mem_space = hae_mem;
@@ -346,18 +347,33 @@ mcpcia_new_hose(unsigned long *mem_start, int h)
io->start = MCPCIA_IO(mid) - MCPCIA_IO_BIAS;
io->end = io->start + 0xffff;
io->name = pci_io_names[h];
+ io->flags = IORESOURCE_IO;
mem->start = MCPCIA_DENSE(mid) - MCPCIA_MEM_BIAS;
mem->end = mem->start + 0xffffffff;
mem->name = pci_mem_names[h];
+ mem->flags = IORESOURCE_MEM;
hae_mem->start = mem->start;
hae_mem->end = mem->start + MCPCIA_MEM_MASK;
hae_mem->name = pci_hae0_name;
+ hae_mem->flags = IORESOURCE_MEM;
+
+ if (request_resource(&ioport_resource, io) < 0)
+ printk(KERN_ERR "Failed to request IO on hose %d\n", h);
+ if (request_resource(&iomem_resource, mem) < 0)
+ printk(KERN_ERR "Failed to request MEM on hose %d\n", h);
+ if (request_resource(mem, hae_mem) < 0)
+ printk(KERN_ERR "Failed to request HAE_MEM on hose %d\n", h);
+}
- request_resource(&ioport_resource, io);
- request_resource(&iomem_resource, mem);
- request_resource(mem, hae_mem);
+static void
+mcpcia_pci_clr_err(int mid)
+{
+ *(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 __init
@@ -366,19 +382,13 @@ mcpcia_startup_hose(struct pci_controler *hose)
int mid = hose2mid(hose->index);
unsigned int tmp;
+ mcpcia_pci_clr_err(mid);
+
/*
- * Set up error reporting. Make sure CPU_PE is OFF in the mask.
+ * Set up error reporting.
*/
-#if 0
- tmp = *(vuip)MCPCIA_ERR_MASK(mid);
- tmp &= ~4;
- *(vuip)MCPCIA_ERR_MASK(mid) = tmp;
- mb();
- tmp = *(vuip)MCPCIA_ERR_MASK(mid);
-#endif
-
tmp = *(vuip)MCPCIA_CAP_ERR(mid);
- tmp |= 0x0006; /* master/target abort */
+ tmp |= 0x0006; /* master/target abort */
*(vuip)MCPCIA_CAP_ERR(mid) = tmp;
mb();
tmp = *(vuip)MCPCIA_CAP_ERR(mid);
@@ -420,29 +430,39 @@ mcpcia_startup_hose(struct pci_controler *hose)
}
void __init
-mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+mcpcia_init_arch(void)
{
- extern asmlinkage void entInt(void);
- struct pci_controler *hose;
- int h, hose_count = 0;
-
- /* 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;
+ /* Allocate hose 0. That's the one that all the ISA junk hangs
+ off of, from which we'll be registering stuff here in a bit.
+ Other hose detection is done in mcpcia_init_hoses, which is
+ called from init_IRQ. */
+
+ mcpcia_new_hose(0);
+}
+
+/* This is called from init_IRQ, since we cannot take interrupts
+ before then. Which means we cannot do this in init_arch. */
+
+void __init
+mcpcia_init_hoses(void)
+{
+ struct pci_controler *hose;
+ int h, hose_count = 0;
+
/* 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);
+ if (h != 0)
+ mcpcia_new_hose(h);
hose_count++;
}
}
- printk("mcpcia_init_arch: found %d hoses\n", hose_count);
+ printk("mcpcia_init_hoses: found %d hoses\n", hose_count);
/* Now do init for each hose. */
for (hose = hose_head; hose; hose = hose->next)
@@ -450,15 +470,6 @@ mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
}
static void
-mcpcia_pci_clr_err(int mid)
-{
- *(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
mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
{
struct el_common_EV5_uncorrectable_mcheck *frame;
@@ -468,65 +479,65 @@ mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
/* Print PAL fields */
for (i = 0; i < 24; i += 2) {
- printk("\tpal temp[%d-%d]\t\t= %16lx %16lx\n\r",
+ printk(" paltmp[%d-%d] = %16lx %16lx\n",
i, i+1, frame->paltemp[i], frame->paltemp[i+1]);
}
for (i = 0; i < 8; i += 2) {
- printk("\tshadow[%d-%d]\t\t= %16lx %16lx\n\r",
+ printk(" shadow[%d-%d] = %16lx %16lx\n",
i, i+1, frame->shadow[i],
frame->shadow[i+1]);
}
- printk("\tAddr of excepting instruction\t= %16lx\n\r",
+ printk(" Addr of excepting instruction = %16lx\n",
frame->exc_addr);
- printk("\tSummary of arithmetic traps\t= %16lx\n\r",
+ printk(" Summary of arithmetic traps = %16lx\n",
frame->exc_sum);
- printk("\tException mask\t\t\t= %16lx\n\r",
+ printk(" Exception mask = %16lx\n",
frame->exc_mask);
- printk("\tBase address for PALcode\t= %16lx\n\r",
+ printk(" Base address for PALcode = %16lx\n",
frame->pal_base);
- printk("\tInterrupt Status Reg\t\t= %16lx\n\r",
+ printk(" Interrupt Status Reg = %16lx\n",
frame->isr);
- printk("\tCURRENT SETUP OF EV5 IBOX\t= %16lx\n\r",
+ printk(" CURRENT SETUP OF EV5 IBOX = %16lx\n",
frame->icsr);
- printk("\tI-CACHE Reg %s parity error\t= %16lx\n\r",
+ printk(" I-CACHE Reg %s parity error = %16lx\n",
(frame->ic_perr_stat & 0x800L) ?
"Data" : "Tag",
frame->ic_perr_stat);
- printk("\tD-CACHE error Reg\t\t= %16lx\n\r",
+ printk(" D-CACHE error Reg = %16lx\n",
frame->dc_perr_stat);
if (frame->dc_perr_stat & 0x2) {
switch (frame->dc_perr_stat & 0x03c) {
case 8:
- printk("\t\tData error in bank 1\n\r");
+ printk(" Data error in bank 1\n");
break;
case 4:
- printk("\t\tData error in bank 0\n\r");
+ printk(" Data error in bank 0\n");
break;
case 20:
- printk("\t\tTag error in bank 1\n\r");
+ printk(" Tag error in bank 1\n");
break;
case 10:
- printk("\t\tTag error in bank 0\n\r");
+ printk(" Tag error in bank 0\n");
break;
}
}
- printk("\tEffective VA\t\t\t= %16lx\n\r",
+ printk(" Effective VA = %16lx\n",
frame->va);
- printk("\tReason for D-stream\t\t= %16lx\n\r",
+ printk(" Reason for D-stream = %16lx\n",
frame->mm_stat);
- printk("\tEV5 SCache address\t\t= %16lx\n\r",
+ printk(" EV5 SCache address = %16lx\n",
frame->sc_addr);
- printk("\tEV5 SCache TAG/Data parity\t= %16lx\n\r",
+ printk(" EV5 SCache TAG/Data parity = %16lx\n",
frame->sc_stat);
- printk("\tEV5 BC_TAG_ADDR\t\t\t= %16lx\n\r",
+ printk(" EV5 BC_TAG_ADDR = %16lx\n",
frame->bc_tag_addr);
- printk("\tEV5 EI_ADDR: Phys addr of Xfer\t= %16lx\n\r",
+ printk(" EV5 EI_ADDR: Phys addr of Xfer = %16lx\n",
frame->ei_addr);
- printk("\tFill Syndrome\t\t\t= %16lx\n\r",
+ printk(" Fill Syndrome = %16lx\n",
frame->fill_syndrome);
- printk("\tEI_STAT reg\t\t\t= %16lx\n\r",
+ printk(" EI_STAT reg = %16lx\n",
frame->ei_stat);
- printk("\tLD_LOCK\t\t\t\t= %16lx\n\r",
+ printk(" LD_LOCK = %16lx\n",
frame->ld_lock);
}
@@ -547,7 +558,8 @@ mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
if (mcheck_expected(cpu)) {
mcpcia_pci_clr_err(mcheck_extra(cpu));
} else {
- /* FIXME: how do we figure out which hose the error was on? */
+ /* 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));
diff --git a/arch/alpha/kernel/core_polaris.c b/arch/alpha/kernel/core_polaris.c
index a6b1a70c7..972e707cb 100644
--- a/arch/alpha/kernel/core_polaris.c
+++ b/arch/alpha/kernel/core_polaris.c
@@ -146,7 +146,7 @@ polaris_write_config_word(struct pci_dev *dev, int where, u16 value)
__kernel_stw(value, *(vusp)pci_addr);
mb();
- __kernel_ldbu(*(vusp)pci_addr);
+ __kernel_ldwu(*(vusp)pci_addr);
return PCIBIOS_SUCCESSFUL;
}
@@ -176,7 +176,7 @@ struct pci_ops polaris_pci_ops =
};
void __init
-polaris_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+polaris_init_arch(void)
{
struct pci_controler *hose;
@@ -192,7 +192,7 @@ polaris_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = POLARIS_DENSE_CONFIG_BASE;
diff --git a/arch/alpha/kernel/core_pyxis.c b/arch/alpha/kernel/core_pyxis.c
index 4f9dd9a81..ee18e1472 100644
--- a/arch/alpha/kernel/core_pyxis.c
+++ b/arch/alpha/kernel/core_pyxis.c
@@ -285,7 +285,7 @@ struct pci_ops pyxis_pci_ops =
};
void __init
-pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+pyxis_init_arch(void)
{
struct pci_controler *hose;
unsigned int temp;
@@ -379,7 +379,7 @@ pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = PYXIS_CONF;
@@ -389,8 +389,10 @@ pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
static inline void
pyxis_pci_clr_err(void)
{
- *(vuip)PYXIS_ERR;
- *(vuip)PYXIS_ERR = 0x0180;
+ unsigned int tmp;
+
+ tmp = *(vuip)PYXIS_ERR;
+ *(vuip)PYXIS_ERR = tmp;
mb();
*(vuip)PYXIS_ERR; /* re-read to force write */
}
diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c
index 6028e4e58..079ad445c 100644
--- a/arch/alpha/kernel/core_t2.c
+++ b/arch/alpha/kernel/core_t2.c
@@ -322,7 +322,7 @@ struct pci_ops t2_pci_ops =
};
void __init
-t2_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+t2_init_arch(void)
{
struct pci_controler *hose;
unsigned int i;
@@ -384,7 +384,7 @@ t2_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = T2_CONF;
diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c
index b27298bd5..dab4e1733 100644
--- a/arch/alpha/kernel/core_tsunami.c
+++ b/arch/alpha/kernel/core_tsunami.c
@@ -26,6 +26,13 @@
int TSUNAMI_bootcpu;
+static struct
+{
+ unsigned long wsba[4];
+ unsigned long wsm[4];
+ unsigned long tba[4];
+} saved_pchip[2];
+
/*
* NOTE: Herein lie back-to-back mb instructions. They are magic.
* One plausible explanation is that the I/O controller does not properly
@@ -84,7 +91,7 @@ static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
@@ -154,6 +161,8 @@ tsunami_write_config_byte(struct pci_dev *dev, int where, u8 value)
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
return PCIBIOS_SUCCESSFUL;
}
@@ -167,6 +176,8 @@ tsunami_write_config_word(struct pci_dev *dev, int where, u16 value)
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
return PCIBIOS_SUCCESSFUL;
}
@@ -180,6 +191,8 @@ tsunami_write_config_dword(struct pci_dev *dev, int where, u32 value)
return PCIBIOS_DEVICE_NOT_FOUND;
*(vuip)addr = value;
+ mb();
+ *(vuip)addr;
return PCIBIOS_SUCCESSFUL;
}
@@ -243,31 +256,55 @@ tsunami_probe_write(volatile unsigned long *vaddr)
#define FN __FUNCTION__
static void __init
-tsunami_init_one_pchip(tsunami_pchip *pchip, int index,
- unsigned long *mem_start)
+tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
{
struct pci_controler *hose;
if (tsunami_probe_read(&pchip->pctl.csr) == 0)
return;
- hose = alloc_pci_controler(mem_start);
- hose->io_space = alloc_resource(mem_start);
- hose->mem_space = alloc_resource(mem_start);
+ hose = alloc_pci_controler();
+ hose->io_space = alloc_resource();
+ hose->mem_space = alloc_resource();
hose->config_space = TSUNAMI_CONF(index);
hose->index = index;
hose->io_space->start = TSUNAMI_IO(index) - TSUNAMI_IO_BIAS;
- hose->io_space->end = hose->io_space->start + 0xffff;
+ hose->io_space->end = hose->io_space->start + TSUNAMI_IO_SPACE - 1;
hose->io_space->name = pci_io_names[index];
+ hose->io_space->flags = IORESOURCE_IO;
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];
+ hose->mem_space->flags = IORESOURCE_MEM;
+
+ if (request_resource(&ioport_resource, hose->io_space) < 0)
+ printk(KERN_ERR "Failed to request IO on hose %d\n", index);
+ if (request_resource(&iomem_resource, hose->mem_space) < 0)
+ printk(KERN_ERR "Failed to request MEM on hose %d\n", index);
+
+ /*
+ * Save the existing PCI window translations. SRM will
+ * need them when we go to reboot.
+ */
+
+ saved_pchip[index].wsba[0] = pchip->wsba[0].csr;
+ saved_pchip[index].wsm[0] = pchip->wsm[0].csr;
+ saved_pchip[index].tba[0] = pchip->tba[0].csr;
+
+ saved_pchip[index].wsba[1] = pchip->wsba[1].csr;
+ saved_pchip[index].wsm[1] = pchip->wsm[1].csr;
+ saved_pchip[index].tba[1] = pchip->tba[1].csr;
+
+ saved_pchip[index].wsba[2] = pchip->wsba[2].csr;
+ saved_pchip[index].wsm[2] = pchip->wsm[2].csr;
+ saved_pchip[index].tba[2] = pchip->tba[2].csr;
- request_resource(&ioport_resource, hose->io_space);
- request_resource(&iomem_resource, hose->mem_space);
+ saved_pchip[index].wsba[3] = pchip->wsba[3].csr;
+ saved_pchip[index].wsm[3] = pchip->wsm[3].csr;
+ saved_pchip[index].tba[3] = pchip->tba[3].csr;
/*
* Set up the PCI->physical memory translation windows.
@@ -294,7 +331,7 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index,
}
void __init
-tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+tsunami_init_arch(void)
{
#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
extern asmlinkage void entInt(void);
@@ -338,9 +375,37 @@ tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
/* Find how many hoses we have, and initialize them. TSUNAMI
and TYPHOON can have 2, but might only have 1 (DS10). */
- tsunami_init_one_pchip(TSUNAMI_pchip0, 0, mem_start);
+ tsunami_init_one_pchip(TSUNAMI_pchip0, 0);
+ if (TSUNAMI_cchip->csc.csr & 1L<<14)
+ tsunami_init_one_pchip(TSUNAMI_pchip1, 1);
+}
+
+static void
+tsunami_kill_one_pchip(tsunami_pchip *pchip, int index)
+{
+ pchip->wsba[0].csr = saved_pchip[index].wsba[0];
+ pchip->wsm[0].csr = saved_pchip[index].wsm[0];
+ pchip->tba[0].csr = saved_pchip[index].tba[0];
+
+ pchip->wsba[1].csr = saved_pchip[index].wsba[1];
+ pchip->wsm[1].csr = saved_pchip[index].wsm[1];
+ pchip->tba[1].csr = saved_pchip[index].tba[1];
+
+ pchip->wsba[2].csr = saved_pchip[index].wsba[2];
+ pchip->wsm[2].csr = saved_pchip[index].wsm[2];
+ pchip->tba[2].csr = saved_pchip[index].tba[2];
+
+ pchip->wsba[3].csr = saved_pchip[index].wsba[3];
+ pchip->wsm[3].csr = saved_pchip[index].wsm[3];
+ pchip->tba[3].csr = saved_pchip[index].tba[3];
+}
+
+void
+tsunami_kill_arch(int mode)
+{
+ tsunami_kill_one_pchip(TSUNAMI_pchip0, 0);
if (TSUNAMI_cchip->csc.csr & 1L<<14)
- tsunami_init_one_pchip(TSUNAMI_pchip1, 1, mem_start);
+ tsunami_kill_one_pchip(TSUNAMI_pchip1, 1);
}
static inline void
diff --git a/arch/alpha/kernel/fpreg.c b/arch/alpha/kernel/fpreg.c
deleted file mode 100644
index 0bd8b9f67..000000000
--- a/arch/alpha/kernel/fpreg.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * arch/alpha/kernel/fpreg.c
- *
- * (C) Copyright 1998 Linus Torvalds
- */
-
-#if defined(__alpha_cix__) || defined(__alpha_fix__)
-#define STT(reg,val) asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
-#else
-#define STT(reg,val) asm volatile ("stt $f"#reg",%0" : "=m"(val));
-#endif
-
-unsigned long
-alpha_read_fp_reg (unsigned long reg)
-{
- unsigned long val;
-
- switch (reg) {
- case 0: STT( 0, val); break;
- case 1: STT( 1, val); break;
- case 2: STT( 2, val); break;
- case 3: STT( 3, val); break;
- case 4: STT( 4, val); break;
- case 5: STT( 5, val); break;
- case 6: STT( 6, val); break;
- case 7: STT( 7, val); break;
- case 8: STT( 8, val); break;
- case 9: STT( 9, val); break;
- case 10: STT(10, val); break;
- case 11: STT(11, val); break;
- case 12: STT(12, val); break;
- case 13: STT(13, val); break;
- case 14: STT(14, val); break;
- case 15: STT(15, val); break;
- case 16: STT(16, val); break;
- case 17: STT(17, val); break;
- case 18: STT(18, val); break;
- case 19: STT(19, val); break;
- case 20: STT(20, val); break;
- case 21: STT(21, val); break;
- case 22: STT(22, val); break;
- case 23: STT(23, val); break;
- case 24: STT(24, val); break;
- case 25: STT(25, val); break;
- case 26: STT(26, val); break;
- case 27: STT(27, val); break;
- case 28: STT(28, val); break;
- case 29: STT(29, val); break;
- case 30: STT(30, val); break;
- case 31: STT(31, val); break;
- }
- return val;
-}
-
-#if defined(__alpha_cix__) || defined(__alpha_fix__)
-#define LDT(reg,val) asm volatile ("itoft %0,$f"#reg : : "r"(val));
-#else
-#define LDT(reg,val) asm volatile ("ldt $f"#reg",%0" : : "m"(val));
-#endif
-
-void
-alpha_write_fp_reg (unsigned long reg, unsigned long val)
-{
- switch (reg) {
- case 0: LDT( 0, val); break;
- case 1: LDT( 1, val); break;
- case 2: LDT( 2, val); break;
- case 3: LDT( 3, val); break;
- case 4: LDT( 4, val); break;
- case 5: LDT( 5, val); break;
- case 6: LDT( 6, val); break;
- case 7: LDT( 7, val); break;
- case 8: LDT( 8, val); break;
- case 9: LDT( 9, val); break;
- case 10: LDT(10, val); break;
- case 11: LDT(11, val); break;
- case 12: LDT(12, val); break;
- case 13: LDT(13, val); break;
- case 14: LDT(14, val); break;
- case 15: LDT(15, val); break;
- case 16: LDT(16, val); break;
- case 17: LDT(17, val); break;
- case 18: LDT(18, val); break;
- case 19: LDT(19, val); break;
- case 20: LDT(20, val); break;
- case 21: LDT(21, val); break;
- case 22: LDT(22, val); break;
- case 23: LDT(23, val); break;
- case 24: LDT(24, val); break;
- case 25: LDT(25, val); break;
- case 26: LDT(26, val); break;
- case 27: LDT(27, val); break;
- case 28: LDT(28, val); break;
- case 29: LDT(29, val); break;
- case 30: LDT(30, val); break;
- case 31: LDT(31, val); break;
- }
-}
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 43da6affd..d6d6e0611 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -22,15 +22,14 @@
#include <linux/random.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/irq.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/bitops.h>
#include <asm/machvec.h>
#include "proto.h"
-#include "irq_impl.h"
#define vulp volatile unsigned long *
#define vuip volatile unsigned int *
@@ -42,8 +41,8 @@ int __local_irq_count;
int __local_bh_count;
#endif
-#if NR_IRQS > 64
-# error Unable to handle more than 64 irq levels.
+#if NR_IRQS > 128
+# error Unable to handle more than 128 irq levels.
#endif
#ifdef CONFIG_ALPHA_GENERIC
@@ -60,7 +59,8 @@ int __local_bh_count;
/*
* Shadow-copy of masked interrupts.
*/
-unsigned long alpha_irq_mask = ~0UL;
+
+unsigned long _alpha_irq_masks[2] = { ~0UL, ~0UL };
/*
* The ack_irq routine used by 80% of the systems.
@@ -110,6 +110,8 @@ void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf;
# define IACK_SC TSUNAMI_IACK_SC
#elif defined(CONFIG_ALPHA_POLARIS)
# define IACK_SC POLARIS_IACK_SC
+#elif defined(CONFIG_ALPHA_IRONGATE)
+# define IACK_SC IRONGATE_IACK_SC
#else
/* This is bogus but necessary to get it to compile on all platforms. */
# define IACK_SC 1L
@@ -179,19 +181,22 @@ srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
*/
static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
-static struct irqaction *irq_action[NR_IRQS];
+spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = {0,} };
static inline void
mask_irq(unsigned long irq)
{
- alpha_mv.update_irq_hw(irq, alpha_irq_mask |= 1UL << irq, 0);
+ set_bit(irq, _alpha_irq_masks);
+ alpha_mv.update_irq_hw(irq, alpha_irq_mask, 0);
}
static inline void
unmask_irq(unsigned long irq)
{
- alpha_mv.update_irq_hw(irq, alpha_irq_mask &= ~(1UL << irq), 1);
+ clear_bit(irq, _alpha_irq_masks);
+ alpha_mv.update_irq_hw(irq, alpha_irq_mask, 1);
}
void
@@ -225,12 +230,7 @@ enable_irq(unsigned int irq_nr)
int
check_irq(unsigned int irq)
{
- struct irqaction **p;
-
- p = irq_action + irq;
- if (*p == NULL)
- return 0;
- return -EBUSY;
+ return irq_desc[irq].action ? -EBUSY : 0;
}
int
@@ -248,7 +248,7 @@ request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
if (!handler)
return -EINVAL;
- p = irq_action + irq;
+ p = &irq_desc[irq].action;
action = *p;
if (action) {
/* Can't share interrupts unless both agree to */
@@ -309,14 +309,14 @@ free_irq(unsigned int irq, void *dev_id)
printk("Trying to free reserved IRQ %d\n", irq);
return;
}
- for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
+ for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
if (action->dev_id != dev_id)
continue;
/* Found it - now free it */
save_and_cli(flags);
*p = action->next;
- if (!irq[irq_action])
+ if (!irq_desc[irq].action)
mask_irq(irq);
restore_flags(flags);
kfree(action);
@@ -339,7 +339,7 @@ int get_irq_list(char *buf)
#endif
for (i = 0; i < NR_IRQS; i++) {
- action = irq_action[i];
+ action = irq_desc[i].action;
if (!action)
continue;
p += sprintf(p, "%3d: ",i);
@@ -387,8 +387,6 @@ 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)
{
@@ -409,7 +407,6 @@ wait_on_irq(int cpu, void *where)
/* Duh, we have to loop. Release the lock to avoid deadlocks */
spin_unlock(&global_irq_lock);
- mb();
for (;;) {
if (!--count) {
@@ -417,7 +414,7 @@ wait_on_irq(int cpu, void *where)
count = MAXCOUNT;
}
__sti();
- SYNC_OTHER_CPUS(cpu);
+ udelay(1); /* make sure to run pending irqs */
__cli();
if (atomic_read(&global_irq_count))
@@ -437,17 +434,13 @@ static inline void
get_irqlock(int cpu, void* where)
{
if (!spin_trylock(&global_irq_lock)) {
- /* do we already hold the lock? */
- if (cpu == global_irq_holder) {
-#if 0
- printk("get_irqlock: already held at %08lx\n",
- previous_irqholder);
-#endif
+ /* Do we already hold the lock? */
+ if (cpu == global_irq_holder)
return;
- }
- /* Uhhuh.. Somebody else got it. Wait.. */
+ /* Uhhuh.. Somebody else got it. Wait. */
spin_lock(&global_irq_lock);
}
+
/*
* Ok, we got the lock bit.
* But that's actually just the easy part.. Now
@@ -543,63 +536,6 @@ __global_restore_flags(unsigned long flags)
}
}
-#undef INIT_STUCK
-#define INIT_STUCK (1<<26)
-
-#undef STUCK
-#define STUCK \
- if (!--stuck) { \
- printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n", \
- irq, cpu, global_irq_holder); \
- stuck = INIT_STUCK; \
- }
-
-#undef VERBOSE_IRQLOCK_DEBUGGING
-
-void
-irq_enter(int cpu, int irq)
-{
-#ifdef VERBOSE_IRQLOCK_DEBUGGING
- extern void smp_show_backtrace_all_cpus(void);
-#endif
- int stuck = INIT_STUCK;
-
- hardirq_enter(cpu, irq);
- barrier();
- while (spin_is_locked(&global_irq_lock)) {
- if (cpu == global_irq_holder) {
- int globl_locked = spin_is_locked(&global_irq_lock);
- int globl_icount = atomic_read(&global_irq_count);
- int local_count = local_irq_count(cpu);
-
- /* It is very important that we load the state
- variables before we do the first call to
- printk() as printk() could end up changing
- them... */
-
- printk("CPU[%d]: where [%p] glocked[%d] gicnt[%d]"
- " licnt[%d]\n",
- cpu, previous_irqholder, globl_locked,
- globl_icount, local_count);
-#ifdef VERBOSE_IRQLOCK_DEBUGGING
- printk("Performing backtrace on all CPUs,"
- " write this down!\n");
- smp_show_backtrace_all_cpus();
-#endif
- break;
- }
- STUCK;
- barrier();
- }
-}
-
-void
-irq_exit(int cpu, int irq)
-{
- hardirq_exit(cpu, irq);
- release_irqlock(cpu);
-}
-
static void
show(char * str, void *where)
{
@@ -700,12 +636,6 @@ synchronize_irq(void)
}
#endif
}
-
-#else /* !__SMP__ */
-
-#define irq_enter(cpu, irq) (++local_irq_count(cpu))
-#define irq_exit(cpu, irq) (--local_irq_count(cpu))
-
#endif /* __SMP__ */
static void
@@ -722,7 +652,7 @@ unexpected_irq(int irq, struct pt_regs * regs)
printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
printk("Expecting: ");
for (i = 0; i < ACTUAL_NR_IRQS; i++)
- if ((action = irq_action[i]))
+ if ((action = irq_desc[i].action))
while (action->handler) {
printk("[%s:%d] ", action->name, i);
action = action->next;
@@ -776,7 +706,7 @@ handle_irq(int irq, int ack, struct pt_regs * regs)
irq_enter(cpu, irq);
kstat.irqs[cpu][irq] += 1;
- action = irq_action[irq];
+ action = irq_desc[irq].action;
/*
* For normal interrupts, we mask it out, and then ACK it.
@@ -819,11 +749,13 @@ probe_irq_on(void)
unsigned long delay;
unsigned int i;
- for (i = ACTUAL_NR_IRQS - 1; i > 0; i--) {
+ /* Handle only the first 64 IRQs here. This is enough for
+ [E]ISA, which is the only thing that needs probing anyway. */
+ for (i = (ACTUAL_NR_IRQS - 1) & 63; i > 0; i--) {
if (!(PROBE_MASK & (1UL << i))) {
continue;
}
- action = irq_action[i];
+ action = irq_desc[i].action;
if (!action) {
enable_irq(i);
irqs |= (1UL << i);
@@ -852,6 +784,8 @@ probe_irq_off(unsigned long irqs)
{
int i;
+ /* Handle only the first 64 IRQs here. This is enough for
+ [E]ISA, which is the only thing that needs probing anyway. */
irqs &= alpha_irq_mask;
if (!irqs)
return 0;
diff --git a/arch/alpha/kernel/irq_impl.h b/arch/alpha/kernel/irq_impl.h
deleted file mode 100644
index bc8854212..000000000
--- a/arch/alpha/kernel/irq_impl.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * linux/arch/alpha/kernel/irq.h
- *
- * Copyright (C) 1995 Linus Torvalds
- * Copyright (C) 1998 Richard Henderson
- *
- * This file contains declarations and inline functions for interfacing
- * with the IRQ handling routines in irq.c.
- */
-
-#include <linux/config.h>
-
-#define STANDARD_INIT_IRQ_PROLOG \
- outb(0, DMA1_RESET_REG); \
- outb(0, DMA2_RESET_REG); \
- outb(0, DMA1_CLR_MASK_REG); \
- outb(0, DMA2_CLR_MASK_REG)
-
-extern unsigned long alpha_irq_mask;
-
-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);
-
-extern void handle_irq(int irq, int ack, struct pt_regs * regs);
-
-#define RTC_IRQ 8
-#ifdef CONFIG_RTC
-#define TIMER_IRQ 0 /* timer is the pit */
-#else
-#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_impl.h b/arch/alpha/kernel/machvec_impl.h
index a0ff70dcc..fc0d0cc0c 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -7,12 +7,14 @@
*/
#include <linux/config.h>
+#include <asm/pgalloc.h>
-/* Whee. Both TSUNAMI and POLARIS don't have an HAE. Fix things up for
+/* Whee. IRONGATE, POLARIS and TSUNAMI 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)
+#define IRONGATE_HAE_ADDRESS (&alpha_mv.hae_cache)
#define POLARIS_HAE_ADDRESS (&alpha_mv.hae_cache)
+#define TSUNAMI_HAE_ADDRESS (&alpha_mv.hae_cache)
#if CIA_ONE_HAE_WINDOW
#define CIA_HAE_ADDRESS (&alpha_mv.hae_cache)
@@ -90,10 +92,11 @@
#define DO_APECS_IO IO(APECS,apecs)
#define DO_CIA_IO IO(CIA,cia)
+#define DO_IRONGATE_IO IO(IRONGATE,irongate)
#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_PYXIS_IO IO(PYXIS,pyxis)
#define DO_T2_IO IO(T2,t2)
#define DO_TSUNAMI_IO IO(TSUNAMI,tsunami)
@@ -103,6 +106,7 @@
#define DO_APECS_BUS BUS(apecs)
#define DO_CIA_BUS BUS(cia)
+#define DO_IRONGATE_BUS BUS(irongate)
#define DO_LCA_BUS BUS(lca)
#define DO_MCPCIA_BUS BUS(mcpcia)
#define DO_PYXIS_BUS BUS(pyxis)
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 39d6b759f..9a61a4e99 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -6,10 +6,14 @@
* David Mosberger (davidm@cs.arizona.edu)
*/
+/* 2.3.x PCI/resources, 1999 Andrea Arcangeli <andrea@suse.de> */
+
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/bootmem.h>
#include <asm/machvec.h>
#include "proto.h"
@@ -36,7 +40,6 @@ const char pci_hae0_name[] = "HAE0";
*/
struct pci_controler *hose_head, **hose_tail = &hose_head;
-struct pci_controler *probing_hose;
/*
* Quirks.
@@ -54,32 +57,122 @@ quirk_isa_bridge(struct pci_dev *dev)
dev->class = PCI_CLASS_BRIDGE_ISA;
}
+static void __init
+quirk_vga_enable_rom(struct pci_dev *dev)
+{
+ /* If it's a VGA, enable its BIOS ROM at C0000.
+ But if its a Cirrus 543x/544x DISABLE it, since
+ enabling ROM disables the memory... */
+ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA &&
+ /* But if its a Cirrus 543x/544x DISABLE it */
+ (dev->vendor != PCI_VENDOR_ID_CIRRUS ||
+ (dev->device < 0x00a0) || (dev->device > 0x00ac)))
+ {
+ u32 reg;
+
+ pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+ reg |= PCI_ROM_ADDRESS_ENABLE;
+ pci_write_config_dword(dev, dev->rom_base_reg, reg);
+ dev->resource[PCI_ROM_RESOURCE].flags |= PCI_ROM_ADDRESS_ENABLE;
+ }
+}
+
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 },
+ { PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, quirk_vga_enable_rom },
{ 0 }
};
+#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))
+#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
+#define KB 1024
+#define MB (1024*KB)
+#define GB (1024*MB)
+
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+ struct pci_dev * dev = data;
+ unsigned long alignto;
+ unsigned long start = res->start;
+
+ if (res->flags & IORESOURCE_IO) {
+ /*
+ * 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);
+ start = ALIGN(start, alignto);
+ }
+ else if (res->flags & IORESOURCE_MEM) {
+ /*
+ * 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);
+ start = ALIGN(start, alignto);
+ if (size > 7 * 16*MB) {
+ printk(KERN_WARNING "PCI: dev %s "
+ "requests %ld bytes of contiguous "
+ "address space---don't use sparse "
+ "memory accesses on this device!\n",
+ dev->name, size);
+ } else {
+ if (((start / (16*MB)) & 0x7) == 0) {
+ start &= ~(128*MB - 1);
+ start += 16*MB;
+ start = ALIGN(start, alignto);
+ }
+ if (start/(128*MB) != (start + size)/(128*MB)) {
+ start &= ~(128*MB - 1);
+ start += (128 + 16)*MB;
+ start = ALIGN(start, alignto);
+ }
+ }
+ }
+
+ res->start = start;
+}
+#undef MAX
+#undef ALIGN
+#undef KB
+#undef MB
+#undef GB
/*
* Pre-layout host-independant device initialization.
*/
static void __init
-pcibios_assign_special(void)
+pcibios_assign_special(struct pci_dev * dev)
{
- 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;
+ if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) {
/* Resource 1 of IDE controller is the address of HD_CMD
register which actually occupies a single byte (0x3f6
for ide0) in reported 0x3f4-3f7 range. We have to fix
@@ -87,11 +180,20 @@ pcibios_assign_special(void)
controller. */
dev->resource[1].start += 2;
dev->resource[1].end = dev->resource[1].start;
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- if (dev->resource[i].flags)
+ for (i = 0; i < PCI_NUM_RESOURCES; i++)
+ if (dev->resource[i].flags && dev->resource[i].start)
pci_claim_resource(dev, i);
- }
}
+ /*
+ * 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... :-\
+ */
+ else if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
+ dev->device == PCI_DEVICE_ID_CONTAQ_82C693)
+ for (i = 0; i < PCI_NUM_RESOURCES; i++)
+ if (dev->resource[i].flags && dev->resource[i].start)
+ pci_claim_resource(dev, i);
}
@@ -110,31 +212,65 @@ pcibios_setup(char *str)
}
void __init
+pcibios_fixup_resource(struct resource *res, struct resource *root)
+{
+ res->start += root->start;
+ res->end += root->start;
+}
+
+void __init
+pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
+{
+ /* Update device resources. */
+
+ int i;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ if (!dev->resource[i].start)
+ continue;
+ if (dev->resource[i].flags & IORESOURCE_IO)
+ pcibios_fixup_resource(&dev->resource[i],
+ bus->resource[0]);
+ else if (dev->resource[i].flags & IORESOURCE_MEM)
+ pcibios_fixup_resource(&dev->resource[i],
+ bus->resource[1]);
+ }
+ pcibios_assign_special(dev);
+}
+
+void __init
pcibios_fixup_bus(struct pci_bus *bus)
{
/* Propogate hose info into the subordinate devices. */
- struct pci_controler *hose = probing_hose;
+ struct pci_controler *hose = (struct pci_controler *) bus->sysdata;
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;
+ for (dev = bus->devices; dev; dev = dev->sibling) {
+ if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+ pcibios_fixup_device_resources(dev, bus);
+ }
}
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);
+ int where;
+ u32 reg;
+
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
+ reg = (res->start - root->start) | (res->flags & 0xf);
+ pci_write_config_dword(dev, where, reg);
+ if ((res->flags & (PCI_BASE_ADDRESS_SPACE
+ | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
+ == (PCI_BASE_ADDRESS_SPACE_MEMORY
+ | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
+ pci_write_config_dword(dev, where+4, 0);
+ printk(KERN_WARNING "PCI: dev %s type 64-bit\n", dev->name);
+ }
/* ??? FIXME -- record old value for shutdown. */
}
@@ -170,6 +306,16 @@ common_swizzle(struct pci_dev *dev, u8 *pinp)
}
void __init
+pcibios_fixup_pbus_ranges(struct pci_bus * bus,
+ struct pbus_set_ranges_data * ranges)
+{
+ ranges->io_start -= bus->resource[0]->start;
+ ranges->io_end -= bus->resource[0]->start;
+ ranges->mem_start -= bus->resource[1]->start;
+ ranges->mem_end -= bus->resource[1]->start;
+}
+
+void __init
common_init_pci(void)
{
struct pci_controler *hose;
@@ -180,15 +326,12 @@ common_init_pci(void)
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);
@@ -197,17 +340,11 @@ common_init_pci(void)
struct pci_controler * __init
-alloc_pci_controler(unsigned long *mem_start)
+alloc_pci_controler(void)
{
- 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 = alloc_bootmem(sizeof(*hose));
*hose_tail = hose;
hose_tail = &hose->next;
@@ -216,17 +353,11 @@ alloc_pci_controler(unsigned long *mem_start)
}
struct resource * __init
-alloc_resource(unsigned long *mem_start)
+alloc_resource(void)
{
- 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));
+ res = alloc_bootmem(sizeof(*res));
return res;
}
diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
index c7c97f096..b46fb9980 100644
--- a/arch/alpha/kernel/pci_impl.h
+++ b/arch/alpha/kernel/pci_impl.h
@@ -125,12 +125,11 @@ static inline u8 bridge_swizzle(u8 pin, u8 slot)
/* The hose list. */
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 struct pci_controler *alloc_pci_controler(void);
+extern struct resource *alloc_resource(void);
extern const char *const pci_io_names[];
extern const char *const pci_mem_names[];
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 0390e3138..e80282155 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -94,8 +94,8 @@ cpu_idle(void)
}
}
-void
-common_kill_arch (int mode, char *restart_cmd)
+static void
+common_shutdown(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
@@ -141,24 +141,12 @@ common_kill_arch (int mode, char *restart_cmd)
#ifdef CONFIG_RTC
/* Reset rtc to defaults. */
- {
- unsigned char control;
-
- cli();
-
- /* Reset periodic interrupt frequency. */
- CMOS_WRITE(0x26, RTC_FREQ_SELECT);
-
- /* Turn on periodic interrupts. */
- control = CMOS_READ(RTC_CONTROL);
- control |= RTC_PIE;
- CMOS_WRITE(control, RTC_CONTROL);
- CMOS_READ(RTC_INTR_FLAGS);
-
- sti();
- }
+ rtc_kill_pit();
#endif
+ if (alpha_mv.kill_arch)
+ alpha_mv.kill_arch(mode);
+
if (!alpha_using_srm && mode != LINUX_REBOOT_CMD_RESTART) {
/* Unfortunately, since MILO doesn't currently understand
the hwrpb bits above, we can't reliably halt the
@@ -175,21 +163,23 @@ common_kill_arch (int mode, char *restart_cmd)
void
machine_restart(char *restart_cmd)
{
- alpha_mv.kill_arch(LINUX_REBOOT_CMD_RESTART, restart_cmd);
+ common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd);
}
void
machine_halt(void)
{
- alpha_mv.kill_arch(LINUX_REBOOT_CMD_HALT, NULL);
+ common_shutdown(LINUX_REBOOT_CMD_HALT, NULL);
}
-void machine_power_off(void)
+void
+machine_power_off(void)
{
- alpha_mv.kill_arch(LINUX_REBOOT_CMD_POWER_OFF, NULL);
+ common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
}
-void show_regs(struct pt_regs * regs)
+void
+show_regs(struct pt_regs * regs)
{
printk("\nps: %04lx pc: [<%016lx>]\n", regs->ps, regs->pc);
printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
@@ -210,7 +200,8 @@ void show_regs(struct pt_regs * regs)
/*
* Re-start a thread when doing execve()
*/
-void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+void
+start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
{
set_fs(USER_DS);
regs->pc = pc;
@@ -221,11 +212,13 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
/*
* Free current thread data structures etc..
*/
-void exit_thread(void)
+void
+exit_thread(void)
{
}
-void flush_thread(void)
+void
+flush_thread(void)
{
/* Arrange for each exec'ed process to start off with a clean slate
with respect to the FPU. This is all exceptions disabled. Note
@@ -236,7 +229,8 @@ void flush_thread(void)
wrfpcr(FPCR_DYN_NORMAL | FPCR_INVD | FPCR_DZED | FPCR_OVFD | FPCR_INED);
}
-void release_thread(struct task_struct *dead_task)
+void
+release_thread(struct task_struct *dead_task)
{
}
@@ -249,15 +243,17 @@ void release_thread(struct task_struct *dead_task)
* Notice that "fork()" is implemented in terms of clone,
* with parameters (SIGCHLD, 0).
*/
-int alpha_clone(unsigned long clone_flags, unsigned long usp,
- struct switch_stack * swstack)
+int
+alpha_clone(unsigned long clone_flags, unsigned long usp,
+ struct switch_stack * swstack)
{
if (!usp)
usp = rdusp();
return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1));
}
-int alpha_vfork(struct switch_stack * swstack)
+int
+alpha_vfork(struct switch_stack * swstack)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
(struct pt_regs *) (swstack+1));
@@ -274,8 +270,9 @@ int alpha_vfork(struct switch_stack * swstack)
* for a kernel fork().
*/
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
- struct task_struct * p, struct pt_regs * regs)
+int
+copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ struct task_struct * p, struct pt_regs * regs)
{
extern void ret_from_sys_call(void);
extern void ret_from_smp_fork(void);
@@ -313,7 +310,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
/*
* fill in the user structure for a core dump..
*/
-void dump_thread(struct pt_regs * pt, struct user * dump)
+void
+dump_thread(struct pt_regs * pt, struct user * dump)
{
/* switch stack follows right below pt_regs: */
struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
@@ -370,7 +368,8 @@ void dump_thread(struct pt_regs * pt, struct user * dump)
memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
}
-int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
+int
+dump_fpu(struct pt_regs * regs, elf_fpregset_t *r)
{
/* switch stack follows right below pt_regs: */
struct switch_stack * sw = ((struct switch_stack *) regs) - 1;
@@ -388,7 +387,8 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
*
* Don't do this at home.
*/
-asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+asmlinkage int
+sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
@@ -415,7 +415,8 @@ extern void scheduling_functions_end_here(void);
#define first_sched ((unsigned long) scheduling_functions_start_here)
#define last_sched ((unsigned long) scheduling_functions_end_here)
-unsigned long get_wchan(struct task_struct *p)
+unsigned long
+get_wchan(struct task_struct *p)
{
unsigned long schedule_frame;
unsigned long pc;
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 2a196efa1..3efbdda08 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -12,43 +12,51 @@ struct pci_dev;
/* core_apecs.c */
extern struct pci_ops apecs_pci_ops;
-extern void apecs_init_arch(unsigned long *, unsigned long *);
+extern void apecs_init_arch(void);
extern void apecs_pci_clr_err(void);
extern void apecs_machine_check(u64, u64, struct pt_regs *);
/* core_cia.c */
extern struct pci_ops cia_pci_ops;
-extern void cia_init_arch(unsigned long *, unsigned long *);
+extern void cia_init_arch(void);
extern void cia_machine_check(u64, u64, struct pt_regs *);
+/* core_irongate.c */
+extern struct pci_ops irongate_pci_ops;
+extern int irongate_pci_clr_err(void);
+extern void irongate_init_arch(void);
+extern void irongate_machine_check(u64, u64, struct pt_regs *);
+
/* core_lca.c */
extern struct pci_ops lca_pci_ops;
-extern void lca_init_arch(unsigned long *, unsigned long *);
+extern void lca_init_arch(void);
extern void lca_machine_check(u64, u64, struct pt_regs *);
/* core_mcpcia.c */
extern struct pci_ops mcpcia_pci_ops;
-extern void mcpcia_init_arch(unsigned long *, unsigned long *);
+extern void mcpcia_init_arch(void);
+extern void mcpcia_init_hoses(void);
extern void mcpcia_machine_check(u64, u64, struct pt_regs *);
/* core_polaris.c */
extern struct pci_ops polaris_pci_ops;
-extern void polaris_init_arch(unsigned long *, unsigned long *);
+extern void polaris_init_arch(void);
extern void polaris_machine_check(u64, u64, struct pt_regs *);
/* core_pyxis.c */
extern struct pci_ops pyxis_pci_ops;
-extern void pyxis_init_arch(unsigned long *, unsigned long *);
+extern void pyxis_init_arch(void);
extern void pyxis_machine_check(u64, u64, struct pt_regs *);
/* core_t2.c */
extern struct pci_ops t2_pci_ops;
-extern void t2_init_arch(unsigned long *, unsigned long *);
+extern void t2_init_arch(void);
extern void t2_machine_check(u64, u64, struct pt_regs *);
/* core_tsunami.c */
extern struct pci_ops tsunami_pci_ops;
-extern void tsunami_init_arch(unsigned long *, unsigned long *);
+extern void tsunami_init_arch(void);
+extern void tsunami_kill_arch(int);
extern void tsunami_machine_check(u64, u64, struct pt_regs *);
/* setup.c */
@@ -67,6 +75,7 @@ extern int smp_boot_cpuid;
/* time.c */
extern void timer_interrupt(int irq, void *dev, struct pt_regs * regs);
extern void rtc_init_pit(void);
+extern void rtc_kill_pit(void);
extern void common_init_pit(void);
extern unsigned long est_cycle_freq;
@@ -102,7 +111,6 @@ extern void entUna(void);
extern void entDbg(void);
/* process.c */
-extern void common_kill_arch (int mode, char *reboot_cmd);
extern void cpu_idle(void) __attribute__((noreturn));
/* ptrace.c */
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 333bb63ec..b650de6b1 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -57,12 +57,6 @@ enum {
* | | v
* +================================+
*/
-#define PT_REG(reg) (PAGE_SIZE*2 - sizeof(struct pt_regs) \
- + (long)&((struct pt_regs *)0)->reg)
-
-#define SW_REG(reg) (PAGE_SIZE*2 - sizeof(struct pt_regs) \
- - sizeof(struct switch_stack) \
- + (long)&((struct switch_stack *)0)->reg)
/*
* The following table maps a register index into the stack offset at
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 9bb21671c..3a1fb94a3 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -4,6 +4,8 @@
* Copyright (C) 1995 Linus Torvalds
*/
+/* 2.3.x bootmem, 1999 Andrea Arcangeli <andrea@suse.de> */
+
/*
* Bootup setup stuff.
*/
@@ -26,6 +28,7 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/ioport.h>
+#include <linux/bootmem.h>
#ifdef CONFIG_RTC
#include <linux/timex.h>
@@ -40,6 +43,8 @@
#include <asm/hwrpb.h>
#include <asm/dma.h>
#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/mmu_context.h>
#include "proto.h"
#include "pci_impl.h"
@@ -57,7 +62,6 @@ unsigned char aux_device_present = 0xaa;
#define N(a) (sizeof(a)/sizeof(a[0]))
-static unsigned long find_end_memory(void);
static struct alpha_machine_vector *get_sysvec(long, long, long);
static struct alpha_machine_vector *get_sysvec_byname(const char *);
static void get_sysnames(long, long, char **, char **);
@@ -68,7 +72,7 @@ static void get_sysnames(long, long, char **, char **);
* initialized, we need to copy things out into a more permanent
* place.
*/
-#define PARAM ZERO_PAGE(0)
+#define PARAM ZERO_PGE
#define COMMAND_LINE ((char*)(PARAM + 0x0000))
#define COMMAND_LINE_SIZE 256
#define INITRD_START (*(unsigned long *) (PARAM+0x100))
@@ -115,12 +119,14 @@ WEAK(eb164_mv);
WEAK(eb64p_mv);
WEAK(eb66_mv);
WEAK(eb66p_mv);
+WEAK(eiger_mv);
WEAK(jensen_mv);
WEAK(lx164_mv);
WEAK(miata_mv);
WEAK(mikasa_mv);
WEAK(mikasa_primo_mv);
WEAK(monet_mv);
+WEAK(nautilus_mv);
WEAK(noname_mv);
WEAK(noritake_mv);
WEAK(noritake_primo_mv);
@@ -181,17 +187,181 @@ reserve_std_resources(void)
request_resource(io, standard_io_resources+i);
}
-void __init
-setup_arch(char **cmdline_p, unsigned long * memory_start_p,
- unsigned long * memory_end_p)
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
+#define PFN_MAX PFN_DOWN(0x80000000)
+#define for_each_mem_cluster(memdesc, cluster, i) \
+ for ((cluster) = (memdesc)->cluster, (i) = 0; \
+ (i) < (memdesc)->numclusters; (i)++, (cluster)++)
+
+static void __init
+setup_memory(void)
{
+ struct memclust_struct * cluster;
+ struct memdesc_struct * memdesc;
+ unsigned long start_pfn, bootmap_size, bootmap_pages, bootmap_start;
+ unsigned long start, end;
extern char _end[];
+ int i;
+
+ /* Find free clusters, and init and free the bootmem accordingly. */
+ memdesc = (struct memdesc_struct *)
+ (hwrpb->mddt_offset + (unsigned long) hwrpb);
+
+ for_each_mem_cluster(memdesc, cluster, i) {
+ printk("memcluster %d, usage %01lx, start %8lu, end %8lu\n",
+ i, cluster->usage, cluster->start_pfn,
+ cluster->start_pfn + cluster->numpages);
+
+ /* Bit 0 is console/PALcode reserved. Bit 1 is
+ non-volatile memory -- we might want to mark
+ this for later. */
+ if (cluster->usage & 3)
+ continue;
+
+ end = cluster->start_pfn + cluster->numpages;
+ if (end > max_low_pfn)
+ max_low_pfn = end;
+ }
+
+ /* Enforce maximum of 2GB even if there is more. Blah. */
+ if (max_low_pfn > PFN_MAX)
+ max_low_pfn = PFN_MAX;
+ printk("max_low_pfn %ld\n", max_low_pfn);
+
+ /* Find the end of the kernel memory. */
+ start_pfn = PFN_UP(virt_to_phys(_end));
+ printk("_end %p, start_pfn %ld\n", _end, start_pfn);
+
+ bootmap_start = -1;
+
+ try_again:
+ if (max_low_pfn <= start_pfn)
+ panic("not enough memory to boot");
+
+ /* We need to know how many physically contigous pages
+ we'll need for the bootmap. */
+ bootmap_pages = bootmem_bootmap_pages(max_low_pfn);
+ printk("bootmap size: %ld pages\n", bootmap_pages);
+
+ /* Now find a good region where to allocate the bootmap. */
+ for_each_mem_cluster(memdesc, cluster, i) {
+ if (cluster->usage & 3)
+ continue;
+
+ start = cluster->start_pfn;
+ end = start + cluster->numpages;
+ if (end <= start_pfn)
+ continue;
+ if (start >= max_low_pfn)
+ continue;
+ if (start < start_pfn)
+ start = start_pfn;
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+ if (end - start >= bootmap_pages) {
+ printk("allocating bootmap in area %ld:%ld\n",
+ start, start+bootmap_pages);
+ bootmap_start = start;
+ break;
+ }
+ }
+
+ if (bootmap_start == -1) {
+ max_low_pfn >>= 1;
+ printk("bootmap area not found now trying with %ld pages\n",
+ max_low_pfn);
+ goto try_again;
+ }
+
+ /* Allocate the bootmap and mark the whole MM as reserved. */
+ bootmap_size = init_bootmem(bootmap_start, max_low_pfn);
+
+ /* Mark the free regions. */
+ for_each_mem_cluster(memdesc, cluster, i) {
+ if (cluster->usage & 3)
+ continue;
+
+ start = cluster->start_pfn;
+ if (start < start_pfn)
+ start = start_pfn;
+
+ end = cluster->start_pfn + cluster->numpages;
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+
+ if (start >= end)
+ continue;
+
+ start = PFN_PHYS(start);
+ end = PFN_PHYS(end);
+
+ free_bootmem(start, end - start);
+ printk("freeing pages %ld:%ld\n",
+ PFN_UP(start), PFN_DOWN(end));
+ }
+
+ /* Reserve the bootmap memory. */
+ reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size);
+ printk("reserving bootmap %ld:%ld\n", bootmap_start,
+ bootmap_start + PFN_UP(bootmap_size));
+#ifdef CONFIG_BLK_DEV_INITRD
+ initrd_start = INITRD_START;
+ if (initrd_start) {
+ initrd_end = initrd_start+INITRD_SIZE;
+ printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
+ (void *) initrd_start, INITRD_SIZE);
+
+ if (initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
+ printk("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ initrd_end,
+ phys_to_virt(PFN_PHYS(max_low_pfn)));
+ initrd_start = initrd_end = 0;
+ } else {
+ reserve_bootmem(virt_to_phys(initrd_start),
+ INITRD_SIZE);
+ }
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+}
+
+int __init page_is_ram(unsigned long pfn)
+{
+ struct memclust_struct * cluster;
+ struct memdesc_struct * memdesc;
+ int i;
+
+ memdesc = (struct memdesc_struct *) (hwrpb->mddt_offset + (unsigned long) hwrpb);
+ for_each_mem_cluster(memdesc, cluster, i)
+ {
+ if (pfn >= cluster->start_pfn &&
+ pfn < cluster->start_pfn + cluster->numpages)
+ {
+ if (cluster->usage & 3)
+ return 0;
+ else
+ return 1;
+ }
+ }
+
+ return 0;
+}
+#undef PFN_UP
+#undef PFN_DOWN
+#undef PFN_PHYS
+#undef PFN_MAX
+
+void __init
+setup_arch(char **cmdline_p)
+{
struct alpha_machine_vector *vec = NULL;
struct percpu_struct *cpu;
char *type_name, *var_name, *p;
- hwrpb = (struct hwrpb_struct*)(IDENT_ADDR + INIT_HWRPB->phys_addr);
+ hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
/*
* Locate the command line.
@@ -249,9 +419,10 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
type_name, (*var_name ? " variation " : ""), var_name,
hwrpb->sys_type, hwrpb->sys_variation);
}
- if (vec != &alpha_mv)
+ if (vec != &alpha_mv) {
alpha_mv = *vec;
-
+ }
+
#ifdef CONFIG_ALPHA_GENERIC
/* Assume that we've booted from SRM if we havn't booted from MILO.
Detect the later by looking for "MILO" in the system serial nr. */
@@ -281,29 +452,12 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
wrmces(0x7);
/* Find our memory. */
- *memory_end_p = find_end_memory();
- *memory_start_p = (unsigned long) _end;
-
-#ifdef CONFIG_BLK_DEV_INITRD
- initrd_start = INITRD_START;
- if (initrd_start) {
- initrd_end = initrd_start+INITRD_SIZE;
- printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
- (void *) initrd_start, INITRD_SIZE);
-
- if (initrd_end > *memory_end_p) {
- printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- initrd_end, (unsigned long) memory_end_p);
- initrd_start = initrd_end = 0;
- }
- }
-#endif
+ setup_memory();
/* Initialize the machine. Usually has to do with setting up
DMA windows and the like. */
if (alpha_mv.init_arch)
- alpha_mv.init_arch(memory_start_p, memory_end_p);
+ alpha_mv.init_arch();
/* Reserve standard resources. */
reserve_std_resources();
@@ -353,35 +507,6 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
#endif
}
-static unsigned long __init
-find_end_memory(void)
-{
- int i;
- unsigned long high = 0;
- struct memclust_struct * cluster;
- struct memdesc_struct * memdesc;
-
- memdesc = (struct memdesc_struct *)
- (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
- cluster = memdesc->cluster;
-
- for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
- unsigned long tmp;
- tmp = (cluster->start_pfn + cluster->numpages) << PAGE_SHIFT;
- if (tmp > high)
- high = tmp;
- }
-
- /* Round it up to an even number of pages. */
- high = (high + PAGE_SIZE) & (PAGE_MASK*2);
-
- /* Enforce maximum of 2GB even if there is more. Blah. */
- if (high > 0x80000000UL)
- high = 0x80000000UL;
- return PAGE_OFFSET + high;
-}
-
-
static char sys_unknown[] = "Unknown";
static char systype_names[][16] = {
"0",
@@ -391,11 +516,13 @@ static char systype_names[][16] = {
"Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
"Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
"Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
- "Tsunami", "Wildfire", "CUSCO"
+ "Tsunami", "Wildfire", "CUSCO", "Eiger"
};
static char unofficial_names[][8] = {"100", "Ruffian"};
+static char api_names[][16] = {"200", "Nautilus"};
+
static char eb164_names[][8] = {"EB164", "PC164", "LX164", "SX164", "RX164"};
static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,4};
@@ -419,7 +546,6 @@ static char tsunami_names[][16] = {
};
static int tsunami_indices[] = {0,1,2,3,4,5,6,7,8};
-
static struct alpha_machine_vector * __init
get_sysvec(long type, long variation, long cpu)
{
@@ -462,6 +588,7 @@ get_sysvec(long type, long variation, long cpu)
NULL, /* Tsunami -- see variation. */
NULL, /* Wildfire */
NULL, /* CUSCO */
+ &eiger_mv, /* Eiger */
};
static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata =
@@ -470,6 +597,12 @@ get_sysvec(long type, long variation, long cpu)
&ruffian_mv,
};
+ static struct alpha_machine_vector *api_vecs[] __initlocaldata =
+ {
+ NULL, /* 200 */
+ &nautilus_mv,
+ };
+
static struct alpha_machine_vector *alcor_vecs[] __initlocaldata =
{
&alcor_mv, &xlt_mv, &xlt_mv
@@ -518,6 +651,9 @@ get_sysvec(long type, long variation, long cpu)
vec = NULL;
if (type < N(systype_vecs)) {
vec = systype_vecs[type];
+ } else if ((type > ST_API_BIAS) &&
+ (type - ST_API_BIAS) < N(api_vecs)) {
+ vec = api_vecs[type - ST_API_BIAS];
} else if ((type > ST_UNOFFICIAL_BIAS) &&
(type - ST_UNOFFICIAL_BIAS) < N(unofficial_vecs)) {
vec = unofficial_vecs[type - ST_UNOFFICIAL_BIAS];
@@ -591,12 +727,14 @@ get_sysvec_byname(const char *name)
&eb64p_mv,
&eb66_mv,
&eb66p_mv,
+ &eiger_mv,
&jensen_mv,
&lx164_mv,
&miata_mv,
&mikasa_mv,
&mikasa_primo_mv,
&monet_mv,
+ &nautilus_mv,
&noname_mv,
&noritake_mv,
&noritake_primo_mv,
@@ -637,6 +775,9 @@ get_sysnames(long type, long variation,
else set type name to family */
if (type < N(systype_names)) {
*type_name = systype_names[type];
+ } else if ((type > ST_API_BIAS) &&
+ (type - ST_API_BIAS) < N(api_names)) {
+ *type_name = api_names[type - ST_API_BIAS];
} else if ((type > ST_UNOFFICIAL_BIAS) &&
(type - ST_UNOFFICIAL_BIAS) < N(unofficial_names)) {
*type_name = unofficial_names[type - ST_UNOFFICIAL_BIAS];
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index cd8f6e0ad..cc5d8b16b 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -688,6 +688,7 @@ 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:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index e35dd7c7e..3fbf11495 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
+#include <linux/irq.h>
#include <asm/hwrpb.h>
#include <asm/ptrace.h>
@@ -23,14 +24,15 @@
#include <asm/irq.h>
#include <asm/bitops.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/hardirq.h>
#include <asm/softirq.h>
+#include <asm/mmu_context.h>
#define __KERNEL_SYSCALLS__
#include <asm/unistd.h>
#include "proto.h"
-#include "irq_impl.h"
#define DEBUG_SMP 0
@@ -45,8 +47,8 @@ struct cpuinfo_alpha cpu_data[NR_CPUS];
/* A collection of single bit ipi messages. */
static struct {
- unsigned long bits __cacheline_aligned;
-} ipi_data[NR_CPUS];
+ unsigned long bits ____cacheline_aligned;
+} ipi_data[NR_CPUS] __cacheline_aligned;
enum ipi_message_type {
IPI_RESCHEDULE,
@@ -54,7 +56,7 @@ enum ipi_message_type {
IPI_CPU_STOP,
};
-spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
/* Set to a secondary's cpuid when it comes online. */
static unsigned long smp_secondary_alive;
@@ -394,6 +396,16 @@ started:
return 0;
}
+static int __init fork_by_hand(void)
+{
+ struct pt_regs regs;
+ /*
+ * don't care about the regs settings since
+ * we'll never reschedule the forked task.
+ */
+ return do_fork(CLONE_VM|CLONE_PID, 0, &regs);
+}
+
/*
* Bring one cpu online.
*/
@@ -407,18 +419,25 @@ smp_boot_one_cpu(int cpuid, int cpunum)
to kernel_thread is irrelevant -- it's going to start where
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);
+ /*
+ * We can't use kernel_thread since we must avoid to
+ * reschedule the child.
+ */
+ if (fork_by_hand() < 0)
+ panic("failed fork for CPU %d", 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;
+ panic("No idle process for CPU %d", cpuid);
- /* Schedule the first task manually. */
- /* ??? Ingo, what is this? */
- idle->has_cpu = 1;
+ idle->processor = cpuid;
+ __cpu_logical_map[cpunum] = cpuid;
+ cpu_number_map[cpuid] = cpunum;
+ idle->has_cpu = 1; /* we schedule the first task manually */
+
+ del_from_runqueue(idle);
+ unhash_process(idle);
+ init_tasks[cpunum] = idle;
DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n",
cpuid, idle->state, idle->flags));
@@ -440,13 +459,18 @@ smp_boot_one_cpu(int cpuid, int cpunum)
barrier();
}
+ /* we must invalidate our stuff as we failed to boot the CPU */
+ __cpu_logical_map[cpunum] = -1;
+ cpu_number_map[cpuid] = -1;
+
+ /* the idle task is local to us so free it as we don't use it */
+ free_task_struct(idle);
+
printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid);
return -1;
alive:
/* Another "Red Snapper". */
- cpu_number_map[cpuid] = cpunum;
- __cpu_logical_map[cpunum] = cpuid;
return 0;
}
@@ -579,16 +603,6 @@ smp_commence(void)
mb();
}
-/*
- * Only broken Intel needs this, thus it should not even be
- * referenced globally.
- */
-
-void __init
-initialize_secondary(void)
-{
-}
-
extern void update_one_process(struct task_struct *p, unsigned long ticks,
unsigned long user, unsigned long system,
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index fbc1b99ba..2a27bac5b 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -27,7 +27,7 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -176,15 +176,13 @@ alcor_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
}
static void
-alcor_kill_arch(int mode, char *reboot_cmd)
+alcor_kill_arch(int mode)
{
/* Who said DEC engineer's have no sense of humor? ;-) */
if (alpha_using_srm) {
*(vuip) GRU_RESET = 0x0000dead;
mb();
}
-
- common_kill_arch(mode, reboot_cmd);
}
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
index 244759d1f..bc4d2c2ba 100644
--- a/arch/alpha/kernel/sys_cabriolet.c
+++ b/arch/alpha/kernel/sys_cabriolet.c
@@ -31,7 +31,7 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -269,7 +269,7 @@ struct alpha_machine_vector cabriolet_mv __initmv = {
init_irq: cabriolet_init_irq,
init_pit: common_init_pit,
init_pci: cabriolet_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: cabriolet_map_irq,
pci_swizzle: common_swizzle,
};
@@ -298,7 +298,6 @@ struct alpha_machine_vector eb164_mv __initmv = {
init_irq: cabriolet_init_irq,
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,
};
@@ -327,7 +326,6 @@ struct alpha_machine_vector eb66p_mv __initmv = {
init_irq: cabriolet_init_irq,
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,
};
@@ -356,7 +354,6 @@ struct alpha_machine_vector lx164_mv __initmv = {
init_irq: cabriolet_init_irq,
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,
};
@@ -385,7 +382,6 @@ struct alpha_machine_vector pc164_mv __initmv = {
init_irq: cabriolet_init_irq,
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,
};
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 9959aad33..f0ef47183 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -27,7 +27,7 @@
#include <asm/hwrpb.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -39,28 +39,30 @@
static void
dp264_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
{
- if (irq >= 16) {
- volatile unsigned long *csr;
+ volatile unsigned long *csr;
- if (TSUNAMI_bootcpu < 2)
- if (!TSUNAMI_bootcpu)
- csr = &TSUNAMI_cchip->dim0.csr;
- else
- csr = &TSUNAMI_cchip->dim1.csr;
+ if (TSUNAMI_bootcpu < 2) {
+ if (!TSUNAMI_bootcpu)
+ csr = &TSUNAMI_cchip->dim0.csr;
else
- if (TSUNAMI_bootcpu == 2)
- csr = &TSUNAMI_cchip->dim2.csr;
- else
- csr = &TSUNAMI_cchip->dim3.csr;
-
- *csr = ~mask;
- mb();
- *csr;
+ csr = &TSUNAMI_cchip->dim1.csr;
+ } else {
+ if (TSUNAMI_bootcpu == 2)
+ csr = &TSUNAMI_cchip->dim2.csr;
+ else
+ csr = &TSUNAMI_cchip->dim3.csr;
+ }
+
+ *csr = ~mask;
+ mb();
+ *csr;
+
+ if (irq < 16) {
+ if (irq >= 8)
+ outb(mask >> 8, 0xA1); /* ISA PIC2 */
+ else
+ outb(mask, 0x21); /* ISA PIC1 */
}
- else if (irq >= 8)
- outb(mask >> 8, 0xA1); /* ISA PIC2 */
- else
- outb(mask, 0x21); /* ISA PIC1 */
}
static void
@@ -274,8 +276,19 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
struct pci_controler *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
- if (irq > 0)
+ if (irq > 0) {
irq += 16 * hose->index;
+ } else {
+ /* ??? The Contaq IDE controler on the ISA bridge uses
+ "legacy" interrupts 14 and 15. I don't know if anything
+ can wind up at the same slot+pin on hose1, so we'll
+ just have to trust whatever value the console might
+ have assigned. */
+
+ u8 irq8;
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
+ irq = irq8;
+ }
return irq;
}
@@ -418,7 +431,7 @@ struct alpha_machine_vector dp264_mv __initmv = {
min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
update_irq_hw: dp264_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
@@ -427,7 +440,7 @@ struct alpha_machine_vector dp264_mv __initmv = {
init_irq: dp264_init_irq,
init_pit: common_init_pit,
init_pci: dp264_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: tsunami_kill_arch,
pci_map_irq: dp264_map_irq,
pci_swizzle: common_swizzle,
};
@@ -445,7 +458,7 @@ struct alpha_machine_vector monet_mv __initmv = {
min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
update_irq_hw: dp264_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
@@ -454,7 +467,7 @@ struct alpha_machine_vector monet_mv __initmv = {
init_irq: dp264_init_irq,
init_pit: common_init_pit,
init_pci: monet_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: tsunami_kill_arch,
pci_map_irq: monet_map_irq,
pci_swizzle: monet_swizzle,
};
@@ -471,7 +484,7 @@ struct alpha_machine_vector webbrick_mv __initmv = {
min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
update_irq_hw: dp264_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
@@ -479,8 +492,8 @@ struct alpha_machine_vector webbrick_mv __initmv = {
init_arch: tsunami_init_arch,
init_irq: dp264_init_irq,
init_pit: common_init_pit,
- init_pci: dp264_init_pci,
- kill_arch: common_kill_arch,
+ init_pci: common_init_pci,
+ kill_arch: tsunami_kill_arch,
pci_map_irq: webbrick_map_irq,
pci_swizzle: common_swizzle,
};
@@ -497,7 +510,7 @@ struct alpha_machine_vector clipper_mv __initmv = {
min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
update_irq_hw: clipper_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
@@ -506,7 +519,7 @@ struct alpha_machine_vector clipper_mv __initmv = {
init_irq: clipper_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: tsunami_kill_arch,
pci_map_irq: clipper_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
index 09e0b0def..e8e224715 100644
--- a/arch/alpha/kernel/sys_eb64p.c
+++ b/arch/alpha/kernel/sys_eb64p.c
@@ -28,7 +28,7 @@
#include <asm/core_lca.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -183,7 +183,7 @@ struct alpha_machine_vector eb64p_mv __initmv = {
init_irq: eb64p_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: eb64p_map_irq,
pci_swizzle: common_swizzle,
};
@@ -212,7 +212,6 @@ struct alpha_machine_vector eb66_mv __initmv = {
init_irq: eb64p_init_irq,
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,
};
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
new file mode 100644
index 000000000..433abddfb
--- /dev/null
+++ b/arch/alpha/kernel/sys_eiger.c
@@ -0,0 +1,215 @@
+/*
+ * linux/arch/alpha/kernel/sys_eiger.c
+ *
+ * Copyright (C) 1995 David A Rusling
+ * Copyright (C) 1996, 1999 Jay A Estabrook
+ * Copyright (C) 1998, 1999 Richard Henderson
+ * Copyright (C) 1999 Iain Grant
+ *
+ * Code supporting the EIGER (EV6+TSUNAMI).
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/pgtable.h>
+#include <asm/core_tsunami.h>
+#include <asm/hwrpb.h>
+
+#include "proto.h"
+#include <asm/hw_irq.h>
+#include "pci_impl.h"
+#include "machvec_impl.h"
+
+
+/*
+ * HACK ALERT! only the boot cpu is used for interrupts.
+ */
+
+static void
+eiger_update_irq_hw(unsigned long irq, unsigned long unused, int unmask_p)
+{
+ unsigned int regaddr;
+ unsigned long mask;
+
+ if (irq <= 15) {
+ if (irq <= 7)
+ outb(alpha_irq_mask, 0x21); /* ISA PIC1 */
+ else
+ outb(alpha_irq_mask >> 8, 0xA1); /* ISA PIC2 */
+ } else {
+ if (irq > 63)
+ mask = _alpha_irq_masks[1] << 16;
+ else
+ mask = _alpha_irq_masks[0] >> ((irq - 16) & 0x30);
+
+ regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
+
+ outl(mask & 0xffff0000UL, regaddr);
+ }
+}
+
+static void
+eiger_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ unsigned intstatus;
+
+ /*
+ * The PALcode will have passed us vectors 0x800 or 0x810,
+ * which are fairly arbitrary values and serve only to tell
+ * us whether an interrupt has come in on IRQ0 or IRQ1. If
+ * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
+ * probably ISA, but PCI interrupts can come through IRQ0
+ * as well if the interrupt controller isn't in accelerated
+ * mode.
+ *
+ * OTOH, the accelerator thing doesn't seem to be working
+ * overly well, so what we'll do instead is try directly
+ * examining the Master Interrupt Register to see if it's a
+ * PCI interrupt, and if _not_ then we'll pass it on to the
+ * ISA handler.
+ */
+
+ intstatus = inw(0x500) & 15;
+ if (intstatus) {
+ /*
+ * This is a PCI interrupt. Check each bit and
+ * despatch an interrupt if it's set.
+ */
+
+ if (intstatus & 8) handle_irq(16+3, 16+3, regs);
+ if (intstatus & 4) handle_irq(16+2, 16+2, regs);
+ if (intstatus & 2) handle_irq(16+1, 16+1, regs);
+ if (intstatus & 1) handle_irq(16+0, 16+0, regs);
+ } else {
+ isa_device_interrupt (vector, regs);
+ }
+}
+
+static void
+eiger_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ int irq = (vector - 0x800) >> 4;
+ handle_irq(irq, irq, regs);
+}
+
+static void __init
+eiger_init_irq(void)
+{
+ outb(0, DMA1_RESET_REG);
+ outb(0, DMA2_RESET_REG);
+ outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
+ outb(0, DMA2_MASK_REG);
+
+ if (alpha_using_srm)
+ alpha_mv.device_interrupt = eiger_srm_device_interrupt;
+
+ eiger_update_irq_hw(16, alpha_irq_mask, 0);
+
+ enable_irq(2);
+}
+
+static int __init
+eiger_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ u8 irq_orig;
+
+ /* The SRM console has already calculated out the IRQ value's for
+ option cards. As this works lets just read in the value already
+ set and change it to a useable value by Linux.
+
+ All the IRQ values generated by the console are greater than 90,
+ so we subtract 80 because it is (90 - allocated ISA IRQ's). */
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_orig);
+
+ return irq_orig - 0x80;
+}
+
+static u8 __init
+eiger_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+ struct pci_controler *hose = dev->sysdata;
+ int slot, pin = *pinp;
+ int bridge_count = 0;
+
+ /* Find the number of backplane bridges. */
+ int backplane = inw(0x502) & 0x0f;
+
+ switch (backplane)
+ {
+ case 0x00: bridge_count = 0; break; /* No bridges */
+ case 0x01: bridge_count = 1; break; /* 1 */
+ case 0x03: bridge_count = 2; break; /* 2 */
+ case 0x07: bridge_count = 3; break; /* 3 */
+ case 0x0f: bridge_count = 4; break; /* 4 */
+ };
+
+ /* Check first for the built-in bridges on hose 0. */
+ if (hose->index == 0
+ && PCI_SLOT(dev->bus->self->devfn) > 20-bridge_count) {
+ slot = PCI_SLOT(dev->devfn);
+ } else {
+ /* Must be a card-based bridge. */
+ do {
+ /* Check for built-in bridges on hose 0. */
+ if (hose->index == 0
+ && (PCI_SLOT(dev->bus->self->devfn)
+ > 20 - bridge_count)) {
+ slot = PCI_SLOT(dev->devfn);
+ break;
+ }
+ pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+
+ /* Move up the chain of bridges. */
+ dev = dev->bus->self;
+ /* Slot of the next bridge. */
+ slot = PCI_SLOT(dev->devfn);
+ } while (dev->bus->self);
+ }
+ *pinp = pin;
+ return slot;
+}
+
+/*
+ * The System Vectors
+ */
+
+struct alpha_machine_vector eiger_mv __initmv = {
+ vector_name: "Eiger",
+ DO_EV6_MMU,
+ DO_DEFAULT_RTC,
+ DO_TSUNAMI_IO,
+ 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: 128,
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
+ update_irq_hw: eiger_update_irq_hw,
+ ack_irq: common_ack_irq,
+ device_interrupt: eiger_device_interrupt,
+
+ init_arch: tsunami_init_arch,
+ init_irq: eiger_init_irq,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: tsunami_kill_arch,
+ pci_map_irq: eiger_map_irq,
+ pci_swizzle: eiger_swizzle,
+};
+ALIAS_MV(eiger)
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index 0380574a8..ad156c9f2 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -28,7 +28,7 @@
#include <asm/pgtable.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "machvec_impl.h"
@@ -140,6 +140,6 @@ struct alpha_machine_vector jensen_mv __initmv = {
init_irq: jensen_init_irq,
init_pit: common_init_pit,
init_pci: NULL,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
};
ALIAS_MV(jensen)
diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c
index 0bea4e3dd..b2da23528 100644
--- a/arch/alpha/kernel/sys_miata.c
+++ b/arch/alpha/kernel/sys_miata.c
@@ -25,7 +25,7 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -274,14 +274,13 @@ miata_init_pci(void)
}
static void
-miata_kill_arch (int mode, char *reboot_cmd)
+miata_kill_arch(int mode)
{
/* Who said DEC engineers have no sense of humor? ;-) */
if (alpha_using_srm) {
*(vuip) PYXIS_RESET = 0x0000dead;
mb();
}
- common_kill_arch(mode, reboot_cmd);
}
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index 0c08d9fc0..ac55371a6 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -28,7 +28,7 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -194,7 +194,7 @@ struct alpha_machine_vector mikasa_mv __initmv = {
init_irq: mikasa_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: mikasa_map_irq,
pci_swizzle: common_swizzle,
};
@@ -223,7 +223,6 @@ struct alpha_machine_vector mikasa_primo_mv __initmv = {
init_irq: mikasa_init_irq,
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,
};
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
new file mode 100644
index 000000000..b51eee671
--- /dev/null
+++ b/arch/alpha/kernel/sys_nautilus.c
@@ -0,0 +1,535 @@
+/*
+ * linux/arch/alpha/kernel/sys_nautilus.c
+ *
+ * Copyright (C) 1995 David A Rusling
+ * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1999 Alpha Processor, Inc.,
+ * (David Daniel, Stig Telfer, Soohoon Lee)
+ *
+ * Code supporting NAUTILUS systems.
+ *
+ *
+ * NAUTILUS has the following I/O features:
+ *
+ * a) Driven by AMD 751 aka IRONGATE (northbridge):
+ * 4 PCI slots
+ * 1 AGP slot
+ *
+ * b) Driven by ALI M1543C (southbridge)
+ * 2 ISA slots
+ * 2 IDE connectors
+ * 1 dual drive capable FDD controller
+ * 2 serial ports
+ * 1 ECP/EPP/SP parallel port
+ * 2 USB ports
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/pgtable.h>
+#include <asm/core_irongate.h>
+#include <asm/hwrpb.h>
+
+#include "proto.h"
+#include <asm/hw_irq.h>
+#include "pci_impl.h"
+#include "machvec_impl.h"
+
+#define dev2hose(d) (bus2hose[(d)->bus->number]->pci_hose_index)
+
+static void
+nautilus_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+ /* The timer is connected to PIC interrupt line also on Nautilus.
+ The timer interrupt handler enables the PIC line, so in order
+ not to get multiple timer interrupt sources, we mask it out
+ at all times. */
+
+ mask |= 0x100;
+ if (irq >= 8)
+ outb(mask >> 8, 0xA1);
+ else
+ outb(mask, 0x21);
+}
+
+static void __init
+nautilus_init_irq(void)
+{
+ STANDARD_INIT_IRQ_PROLOG;
+
+ enable_irq(2); /* enable cascade */
+ disable_irq(8);
+}
+
+static int __init
+nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ /* Preserve the IRQ set up by the console. */
+
+ u8 irq;
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+ return irq;
+}
+
+void
+nautilus_kill_arch(int mode)
+{
+ u8 tmp;
+
+ if (mode == LINUX_REBOOT_CMD_RESTART) {
+ pcibios_read_config_byte(0, 0x38, 0x43, &tmp);
+ pcibios_write_config_byte(0, 0x38, 0x43, tmp | 0x80);
+ outb(1, 0x92);
+ outb(0, 0x92);
+ }
+}
+
+/* Machine check handler code
+ *
+ * Perform analysis of a machine check that was triggered by the EV6
+ * CPU's fault-detection mechanism.
+ */
+
+/* IPR structures for EV6, containing the necessary data for the
+ * machine check handler to unpick the logout frame
+ */
+
+/* I_STAT */
+
+#define EV6__I_STAT__PAR ( 1 << 29 )
+
+/* MM_STAT */
+
+#define EV6__MM_STAT__DC_TAG_PERR ( 1 << 10 )
+
+/* DC_STAT */
+
+#define EV6__DC_STAT__SEO ( 1 << 4 )
+#define EV6__DC_STAT__ECC_ERR_LD ( 1 << 3 )
+#define EV6__DC_STAT__ECC_ERR_ST ( 1 << 2 )
+#define EV6__DC_STAT__TPERR_P1 ( 1 << 1 )
+#define EV6__DC_STAT__TPERR_P0 ( 1 )
+
+/* C_STAT */
+
+#define EV6__C_STAT__BC_PERR ( 0x01 )
+#define EV6__C_STAT__DC_PERR ( 0x02 )
+#define EV6__C_STAT__DSTREAM_MEM_ERR ( 0x03 )
+#define EV6__C_STAT__DSTREAM_BC_ERR ( 0x04 )
+#define EV6__C_STAT__DSTREAM_DC_ERR ( 0x05 )
+#define EV6__C_STAT__PROBE_BC_ERR0 ( 0x06 )
+#define EV6__C_STAT__PROBE_BC_ERR1 ( 0x07 )
+#define EV6__C_STAT__ISTREAM_MEM_ERR ( 0x0B )
+#define EV6__C_STAT__ISTREAM_BC_ERR ( 0x0C )
+#define EV6__C_STAT__DSTREAM_MEM_DBL ( 0x13 )
+#define EV6__C_STAT__DSTREAM_BC_DBL ( 0x14 )
+#define EV6__C_STAT__ISTREAM_MEM_DBL ( 0x1B )
+#define EV6__C_STAT__ISTREAM_BC_DBL ( 0x1C )
+
+
+/* Take the two syndromes from the CBOX error chain and convert them
+ * into a bit number. */
+
+/* NOTE - since I don't know of any difference between C0 and C1 I
+ just ignore C1, since in all cases I've seen so far they are
+ identical. */
+
+static const unsigned char ev6_bit_to_syndrome[72] =
+{
+ 0xce, 0xcb, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc, /* 0 */
+ 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34, /* 8 */
+ 0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, /* 16 */
+ 0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xf1, 0xf4, /* 24 */
+ 0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, /* 32 */
+ 0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xb0, 0xb5, /* 40 */
+ 0x8f, 0x8a, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d, /* 48 */
+ 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75, /* 56 */
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 /* 64 */
+};
+
+
+static int ev6_syn2bit(unsigned long c0, unsigned long c1)
+{
+ int bit;
+
+ for (bit = 0; bit < 72; bit++)
+ if (ev6_bit_to_syndrome[bit] == c0) return bit;
+ for (bit = 0; bit < 72; bit++)
+ if (ev6_bit_to_syndrome[bit] == c1) return bit + 64;
+
+ return -1; /* not found */
+}
+
+
+/* Single bit ECC errors are categorized here. */
+
+#if 0
+static const char *interr = "CPU internal error";
+static const char *slotb= "Slot-B error";
+static const char *membus= "Memory/EV6-bus error";
+#else
+static const char *interr = "";
+static const char *slotb = "";
+static const char *membus = "";
+#endif
+
+static void
+ev6_crd_interp(char *interp, struct el_common_EV6_mcheck * L)
+{
+ /* Icache data or tag parity error. */
+ if (L->I_STAT & EV6__I_STAT__PAR) {
+ sprintf(interp, "%s: I_STAT[PAR]\n "
+ "Icache data or tag parity error", interr);
+ return;
+ }
+
+ /* Dcache tag parity error (on issue) (DFAULT). */
+ if (L->MM_STAT & EV6__MM_STAT__DC_TAG_PERR) {
+ sprintf(interp, "%s: MM_STAT[DC_TAG_PERR]\n "
+ "Dcache tag parity error(on issue)", interr);
+ return;
+ }
+
+ /* Errors relating to D-stream set non-zero DC_STAT.
+ Mask CRD bits. */
+ switch (L->DC_STAT & (EV6__DC_STAT__ECC_ERR_ST
+ | EV6__DC_STAT__ECC_ERR_LD)) {
+ case EV6__DC_STAT__ECC_ERR_ST:
+ /* Dcache single-bit ECC error on small store */
+ sprintf(interp, "%s: DC_STAT[ECC_ERR_ST]\n "
+ "Dcache single-bit ECC error on small store", interr);
+ return;
+
+ case EV6__DC_STAT__ECC_ERR_LD:
+ switch (L->C_STAT) {
+ case 0:
+ /* Dcache single-bit error on speculative load */
+ /* Bcache victim read on Dcache/Bcache miss */
+ sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT=0\n "
+ "Dcache single-bit ECC error on speculative load",
+ slotb);
+ return;
+
+ case EV6__C_STAT__DSTREAM_DC_ERR:
+ /* Dcache single bit error on load */
+ sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_DC_ERR]\n"
+ " Dcache single-bit ECC error on speculative load, bit %d",
+ interr, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+ case EV6__C_STAT__DSTREAM_BC_ERR:
+ /* Bcache single-bit error on Dcache fill */
+ sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_BC_ERR]\n"
+ " Bcache single-bit error on Dcache fill, bit %d",
+ slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+ case EV6__C_STAT__DSTREAM_MEM_ERR:
+ /* Memory single-bit error on Dcache fill */
+ sprintf(interp, "%s (to Dcache): DC_STAT[ECC_ERR_LD] "
+ "C_STAT[DSTREAM_MEM_ERR]\n "
+ "Memory single-bit error on Dcache fill, "
+ "Address 0x%lX, bit %d",
+ membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
+ L->DC1_SYNDROME));
+ return;
+ }
+ }
+
+ /* I-stream, other misc errors go on C_STAT alone */
+ switch (L->C_STAT) {
+ case EV6__C_STAT__ISTREAM_BC_ERR:
+ /* Bcache single-bit error on Icache fill (also MCHK) */
+ sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
+ "Bcache single-bit error on Icache fill, bit %d",
+ slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+ case EV6__C_STAT__ISTREAM_MEM_ERR:
+ /* Memory single-bit error on Icache fill (also MCHK) */
+ sprintf(interp, "%s : C_STATISTREAM_MEM_ERR]\n "
+ "Memory single-bit error on Icache fill "
+ "addr 0x%lX, bit %d",
+ membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
+ L->DC1_SYNDROME));
+ return;
+
+ case EV6__C_STAT__PROBE_BC_ERR0:
+ case EV6__C_STAT__PROBE_BC_ERR1:
+ /* Bcache single-bit error on a probe hit */
+ sprintf(interp, "%s: C_STAT[PROBE_BC_ERR]\n "
+ "Bcache single-bit error on a probe hit, "
+ "addr 0x%lx, bit %d",
+ slotb, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
+ L->DC1_SYNDROME));
+ return;
+ }
+}
+
+static void
+ev6_mchk_interp(char *interp, struct el_common_EV6_mcheck * L)
+{
+ /* Machine check errors described by DC_STAT */
+ switch (L->DC_STAT) {
+ case EV6__DC_STAT__TPERR_P0:
+ case EV6__DC_STAT__TPERR_P1:
+ /* Dcache tag parity error (on retry) */
+ sprintf(interp, "%s: DC_STAT[TPERR_P0|TPERR_P1]\n "
+ "Dcache tag parity error(on retry)", interr);
+ return;
+
+ case EV6__DC_STAT__SEO:
+ /* Dcache second error on store */
+ sprintf(interp, "%s: DC_STAT[SEO]\n "
+ "Dcache second error during mcheck", interr);
+ return;
+ }
+
+ /* Machine check errors described by C_STAT */
+ switch (L->C_STAT) {
+ case EV6__C_STAT__DC_PERR:
+ /* Dcache duplicate tag parity error */
+ sprintf(interp, "%s: C_STAT[DC_PERR]\n "
+ "Dcache duplicate tag parity error at 0x%lX",
+ interr, L->C_ADDR);
+ return;
+
+ case EV6__C_STAT__BC_PERR:
+ /* Bcache tag parity error */
+ sprintf(interp, "%s: C_STAT[BC_PERR]\n "
+ "Bcache tag parity error at 0x%lX",
+ slotb, L->C_ADDR);
+ return;
+
+ case EV6__C_STAT__ISTREAM_BC_ERR:
+ /* Bcache single-bit error on Icache fill (also CRD) */
+ sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
+ "Bcache single-bit error on Icache fill 0x%lX bit %d",
+ slotb, L->C_ADDR,
+ ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+
+ case EV6__C_STAT__ISTREAM_MEM_ERR:
+ /* Memory single-bit error on Icache fill (also CRD) */
+ sprintf(interp, "%s: C_STAT[ISTREAM_MEM_ERR]\n "
+ "Memory single-bit error on Icache fill 0x%lX, bit %d",
+ membus, L->C_ADDR,
+ ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+
+ case EV6__C_STAT__ISTREAM_BC_DBL:
+ /* Bcache double-bit error on Icache fill */
+ sprintf(interp, "%s: C_STAT[ISTREAM_BC_DBL]\n "
+ "Bcache double-bit error on Icache fill at 0x%lX",
+ slotb, L->C_ADDR);
+ return;
+ case EV6__C_STAT__DSTREAM_BC_DBL:
+ /* Bcache double-bit error on Dcache fill */
+ sprintf(interp, "%s: C_STAT[DSTREAM_BC_DBL]\n "
+ "Bcache double-bit error on Dcache fill at 0x%lX",
+ slotb, L->C_ADDR);
+ return;
+
+ case EV6__C_STAT__ISTREAM_MEM_DBL:
+ /* Memory double-bit error on Icache fill */
+ sprintf(interp, "%s: C_STAT[ISTREAM_MEM_DBL]\n "
+ "Memory double-bit error on Icache fill at 0x%lX",
+ membus, L->C_ADDR);
+ return;
+
+ case EV6__C_STAT__DSTREAM_MEM_DBL:
+ /* Memory double-bit error on Dcache fill */
+ sprintf(interp, "%s: C_STAT[DSTREAM_MEM_DBL]\n "
+ "Memory double-bit error on Dcache fill at 0x%lX",
+ membus, L->C_ADDR);
+ return;
+ }
+}
+
+static void
+ev6_cpu_machine_check(unsigned long vector, struct el_common_EV6_mcheck *L,
+ struct pt_regs *regs)
+{
+ char interp[80];
+
+ /* This is verbose and looks intimidating. Should it be printed for
+ corrected (CRD) machine checks? */
+
+ printk(KERN_CRIT "PALcode logout frame: "
+ "MCHK_Code %d "
+ "MCHK_Frame_Rev %d\n"
+ "I_STAT %016lx "
+ "DC_STAT %016lx "
+ "C_ADDR %016lx\n"
+ "SYND1 %016lx "
+ "SYND0 %016lx "
+ "C_STAT %016lx\n"
+ "C_STS %016lx "
+ "RES %016lx "
+ "EXC_ADDR%016lx\n"
+ "IER_CM %016lx "
+ "ISUM %016lx "
+ "MM_STAT %016lx\n"
+ "PALBASE %016lx "
+ "I_CTL %016lx "
+ "PCTX %016lx\n"
+ "CPU registers: "
+ "PC %016lx "
+ "Return %016lx\n",
+ L->MCHK_Code, L->MCHK_Frame_Rev, L->I_STAT, L->DC_STAT,
+ L->C_ADDR, L->DC1_SYNDROME, L->DC0_SYNDROME, L->C_STAT,
+ L->C_STS, L->RESERVED0, L->EXC_ADDR, L->IER_CM, L->ISUM,
+ L->MM_STAT, L->PAL_BASE, L->I_CTL, L->PCTX,
+ regs->pc, regs->r26);
+
+ /* Attempt an interpretation on the meanings of the fields above. */
+ sprintf(interp, "No interpretation available!" );
+ if (vector == SCB_Q_PROCERR)
+ ev6_crd_interp(interp, L);
+ else if (vector == SCB_Q_PROCMCHK)
+ ev6_mchk_interp(interp, L);
+
+ printk(KERN_CRIT "interpretation: %s\n\n", interp);
+}
+
+
+/* Perform analysis of a machine check that arrived from the system (NMI) */
+
+static void
+naut_sys_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs *regs)
+{
+ printk("xtime %lx\n", CURRENT_TIME);
+ printk("PC %lx RA %lx\n", regs->pc, regs->r26);
+ irongate_pci_clr_err();
+}
+
+/* Machine checks can come from two sources - those on the CPU and those
+ in the system. They are analysed separately but all starts here. */
+
+void
+nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs *regs)
+{
+ char *mchk_class;
+ unsigned cpu_analysis=0, sys_analysis=0;
+
+ /* Now for some analysis. Machine checks fall into two classes --
+ those picked up by the system, and those picked up by the CPU.
+ Add to that the two levels of severity - correctable or not. */
+
+ if (vector == SCB_Q_SYSMCHK
+ && ((IRONGATE0->dramms & 0x3FF) == 0x300)) {
+ unsigned long nmi_ctl, temp;
+
+ /* Clear ALI NMI */
+ nmi_ctl = inb(0x61);
+ nmi_ctl |= 0x0c;
+ outb(nmi_ctl, 0x61);
+ nmi_ctl &= ~0x0c;
+ outb(nmi_ctl, 0x61);
+
+ temp = IRONGATE0->stat_cmd;
+ IRONGATE0->stat_cmd = temp; /* write again clears error bits */
+ mb();
+ temp = IRONGATE0->stat_cmd; /* re-read to force write */
+
+ temp = IRONGATE0->dramms;
+ IRONGATE0->dramms = temp; /* write again clears error bits */
+ mb();
+ temp = IRONGATE0->dramms; /* re-read to force write */
+
+ draina();
+ wrmces(0x7);
+ mb();
+ return;
+ }
+
+ switch (vector) {
+ case SCB_Q_SYSERR:
+ mchk_class = "Correctable System Machine Check (NMI)";
+ sys_analysis = 1;
+ break;
+ case SCB_Q_SYSMCHK:
+ mchk_class = "Fatal System Machine Check (NMI)";
+ sys_analysis = 1;
+ break;
+
+ case SCB_Q_PROCERR:
+ mchk_class = "Correctable Processor Machine Check";
+ cpu_analysis = 1;
+ break;
+ case SCB_Q_PROCMCHK:
+ mchk_class = "Fatal Processor Machine Check";
+ cpu_analysis = 1;
+ break;
+
+ default:
+ mchk_class = "Unknown vector!";
+ break;
+ }
+
+ printk(KERN_CRIT "NAUTILUS Machine check 0x%lx [%s]\n",
+ vector, mchk_class);
+
+ if (cpu_analysis)
+ ev6_cpu_machine_check(vector,
+ (struct el_common_EV6_mcheck *)la_ptr,
+ regs);
+ if (sys_analysis)
+ naut_sys_machine_check(vector, la_ptr, regs);
+
+ /* Tell the PALcode to clear the machine check */
+ draina();
+ wrmces(0x7);
+ mb();
+}
+
+
+
+/*
+ * The System Vectors
+ */
+
+struct alpha_machine_vector nautilus_mv __initmv = {
+ vector_name: "Nautilus",
+ DO_EV6_MMU,
+ DO_DEFAULT_RTC,
+ DO_IRONGATE_IO,
+ DO_IRONGATE_BUS,
+ machine_check: nautilus_machine_check,
+ max_dma_address: ALPHA_NAUTILUS_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
+
+ nr_irqs: 16,
+ irq_probe_mask: (_PROBE_MASK(16) & ~0x101UL),
+ update_irq_hw: nautilus_update_irq_hw,
+ ack_irq: common_ack_irq,
+ device_interrupt: isa_device_interrupt,
+
+ init_arch: irongate_init_arch,
+ init_irq: nautilus_init_irq,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: nautilus_kill_arch,
+ pci_map_irq: nautilus_map_irq,
+ pci_swizzle: common_swizzle,
+};
+ALIAS_MV(nautilus)
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index adce91de2..c1a793393 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -29,7 +29,7 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -254,7 +254,7 @@ struct alpha_machine_vector noritake_mv __initmv = {
init_irq: noritake_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: noritake_map_irq,
pci_swizzle: noritake_swizzle,
};
@@ -283,7 +283,6 @@ struct alpha_machine_vector noritake_primo_mv __initmv = {
init_irq: noritake_init_irq,
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,
};
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index 4561c4046..0a0ce2267 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -25,46 +25,59 @@
#include <asm/core_mcpcia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
+static unsigned int hose_irq_masks[4] = {
+ 0xff0000, 0xfe0000, 0xff0000, 0xff0000
+};
+
+
+/* Note that `mask' initially contains only the low 64 bits. */
static void
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(5) =
- (~((mask) >> 40) & 0x00ffffffU) | 0x00fe0000U;
- mb();
- /* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(5);
+ unsigned int saddle, hose, new_irq;
+
+ if (irq < 16) {
+ if (irq < 8)
+ outb(mask, 0x21); /* ISA PIC1 */
+ else
+ outb(mask >> 8, 0xA1); /* ISA PIC2 */
+ return;
}
- else if (irq >= 16) {
- /* PCI bus 0 with EISA bridge */
- *(vuip)MCPCIA_INT_MASK0(4) =
- (~((mask) >> 16) & 0x00ffffffU) | 0x00ff0000U;
- mb();
- /* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(4);
+
+ saddle = (irq > 63);
+ mask = _alpha_irq_masks[saddle];
+
+ if (saddle == 0) {
+ /* Saddle 0 includes EISA interrupts. */
+ mask >>= 16;
+ new_irq = irq - 16;
+ } else {
+ new_irq = irq - 64;
+ }
+
+ hose = saddle << 1;
+ if (new_irq >= 24) {
+ mask >>= 24;
+ hose += 1;
}
- else if (irq >= 8)
- outb(mask >> 8, 0xA1); /* ISA PIC2 */
- else
- outb(mask, 0x21); /* ISA PIC1 */
+
+ *(vuip)MCPCIA_INT_MASK0(hose) =
+ (~mask & 0x00ffffff) | hose_irq_masks[hose];
+ mb();
+ *(vuip)MCPCIA_INT_MASK0(hose);
}
static void
rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
- int irq, ack;
-
- ack = irq = (vector - 0x800) >> 4;
+ int irq;
- /* ??? A 4 bus RAWHIDE has 67 interrupts. Oops. We need
- something wider than one word for our own internal
- manipulations. */
+ irq = (vector - 0x800) >> 4;
/*
* The RAWHIDE SRM console reports PCI interrupts with a vector
@@ -73,37 +86,37 @@ rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
* it line up with the actual bit numbers from the REQ registers,
* which is how we manage the interrupts/mask. Sigh...
*
- * also, PCI #1 interrupts are offset some more... :-(
+ * Also, PCI #1 interrupts are offset some more... :-(
*/
- if (irq == 52)
- ack = irq = 56; /* SCSI on PCI 1 is special */
- else {
- if (irq >= 24) /* adjust all PCI interrupts down 8 */
- ack = irq = irq - 8;
- if (irq >= 48) /* adjust PCI bus 1 interrupts down another 8 */
- ack = irq = irq - 8;
+
+ if (irq == 52) {
+ /* SCSI on PCI1 is special. */
+ irq = 72;
}
- handle_irq(irq, ack, regs);
+ /* Adjust by which hose it is from. */
+ irq -= ((irq + 16) >> 2) & 0x38;
+
+ handle_irq(irq, irq, regs);
}
static void __init
rawhide_init_irq(void)
{
- STANDARD_INIT_IRQ_PROLOG;
+ struct pci_controler *hose;
- /* HACK ALERT! only PCI busses 0 and 1 are used currently,
- (MIDs 4 and 5 respectively) and routing is only to CPU #1*/
+ mcpcia_init_hoses();
- *(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(4);
+ STANDARD_INIT_IRQ_PROLOG;
+
+ /* HACK ALERT! Routing is only to CPU #0. */
+ for (hose = hose_head; hose; hose = hose->next) {
+ int h = hose->index;
- *(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(5);
+ *(vuip)MCPCIA_INT_MASK0(h) = hose_irq_masks[h];
+ mb();
+ *(vuip)MCPCIA_INT_MASK0(h);
+ }
enable_irq(2);
}
@@ -177,8 +190,8 @@ struct alpha_machine_vector rawhide_mv __initmv = {
min_io_address: DEFAULT_IO_BASE,
min_mem_address: MCPCIA_DEFAULT_MEM_BASE,
- nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ nr_irqs: 128,
+ irq_probe_mask: _PROBE_MASK(128),
update_irq_hw: rawhide_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: rawhide_srm_device_interrupt,
@@ -187,7 +200,7 @@ struct alpha_machine_vector rawhide_mv __initmv = {
init_irq: rawhide_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: rawhide_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c
index f303a8255..c03a91296 100644
--- a/arch/alpha/kernel/sys_ruffian.c
+++ b/arch/alpha/kernel/sys_ruffian.c
@@ -26,7 +26,7 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -212,15 +212,14 @@ ruffian_init_pit (void)
}
static void
-ruffian_kill_arch (int mode, char *reboot_cmd)
+ruffian_kill_arch (int mode)
{
#if 0
- /* this only causes re-entry to ARCSBIOS */
+ /* This only causes re-entry to ARCSBIOS */
/* Perhaps this works for other PYXIS as well? */
*(vuip) PYXIS_RESET = 0x0000dead;
mb();
#endif
- common_kill_arch(mode, reboot_cmd);
}
static int __init
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
index c6a4ac5b3..969d3561f 100644
--- a/arch/alpha/kernel/sys_rx164.c
+++ b/arch/alpha/kernel/sys_rx164.c
@@ -26,7 +26,7 @@
#include <asm/core_polaris.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -229,7 +229,7 @@ struct alpha_machine_vector rx164_mv __initmv = {
init_irq: rx164_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: rx164_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index 86b1d8371..53afe259b 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -26,7 +26,7 @@
#include <asm/core_t2.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -248,7 +248,7 @@ struct alpha_machine_vector sable_mv __initmv = {
init_irq: sable_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: sable_map_irq,
pci_swizzle: common_swizzle,
@@ -283,7 +283,6 @@ struct alpha_machine_vector sable_gamma_mv __initmv = {
init_irq: sable_init_irq,
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,
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
index a6575de9c..f26991f55 100644
--- a/arch/alpha/kernel/sys_sio.c
+++ b/arch/alpha/kernel/sys_sio.c
@@ -30,7 +30,7 @@
#include <asm/core_lca.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -55,7 +55,7 @@ sio_init_irq(void)
}
static inline void __init
-xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+xl_init_arch(void)
{
struct pci_controler *hose;
@@ -93,7 +93,7 @@ xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = LCA_CONF;
@@ -101,7 +101,7 @@ xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
}
static inline void __init
-alphabook1_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+alphabook1_init_arch(void)
{
/* The AlphaBook1 has LCD video fixed at 800x600,
37 rows and 100 cols. */
@@ -109,7 +109,7 @@ alphabook1_init_arch(unsigned long *mem_start, unsigned long *mem_end)
screen_info.orig_video_cols = 100;
screen_info.orig_video_lines = 37;
- lca_init_arch(mem_start, mem_end);
+ lca_init_arch();
}
@@ -238,8 +238,8 @@ p2k_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
static inline void __init
noname_init_pci(void)
{
- sio_pci_route();
common_init_pci();
+ sio_pci_route();
sio_fixup_irq_levels(sio_collect_irq_levels());
ns87312_enable_ide(0x26e);
}
@@ -250,8 +250,8 @@ alphabook1_init_pci(void)
struct pci_dev *dev;
unsigned char orig, config;
- sio_pci_route();
common_init_pci();
+ sio_pci_route();
/*
* On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
@@ -325,7 +325,7 @@ struct alpha_machine_vector alphabook1_mv __initmv = {
init_irq: sio_init_irq,
init_pit: common_init_pit,
init_pci: alphabook1_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: noname_map_irq,
pci_swizzle: common_swizzle,
@@ -359,7 +359,6 @@ struct alpha_machine_vector avanti_mv __initmv = {
init_irq: sio_init_irq,
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,
@@ -392,7 +391,6 @@ struct alpha_machine_vector noname_mv __initmv = {
init_irq: sio_init_irq,
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,
@@ -434,7 +432,6 @@ struct alpha_machine_vector p2k_mv __initmv = {
init_irq: sio_init_irq,
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,
@@ -467,7 +464,6 @@ struct alpha_machine_vector xl_mv __initmv = {
init_irq: sio_init_irq,
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,
diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c
index a8c7698fb..6ad08e442 100644
--- a/arch/alpha/kernel/sys_sx164.c
+++ b/arch/alpha/kernel/sys_sx164.c
@@ -26,7 +26,7 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -211,7 +211,7 @@ struct alpha_machine_vector sx164_mv __initmv = {
init_irq: sx164_init_irq,
init_pit: common_init_pit,
init_pci: sx164_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: sx164_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
index c592ee65e..a17cd4de6 100644
--- a/arch/alpha/kernel/sys_takara.c
+++ b/arch/alpha/kernel/sys_takara.c
@@ -25,7 +25,7 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -40,9 +40,13 @@ takara_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
outb(mask, 0x21); /* ISA PIC1 */
else
outb(mask >> 8, 0xA1); /* ISA PIC2 */
- } else if (irq <= 31) {
- regaddr = 0x510 + ((irq - 16) & 0x0c);
- outl((mask >> ((irq - 16) & 0x0c)) & 0xf0000Ul, regaddr);
+ } else {
+ if (irq > 63)
+ mask = _alpha_irq_masks[1] << 16;
+ else
+ mask = mask >> ((irq - 16) & 0x30);
+ regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
+ outl(mask & 0xffff0000UL, regaddr);
}
}
@@ -87,10 +91,6 @@ static void
takara_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
int irq = (vector - 0x800) >> 4;
-
- if (irq > 15)
- irq = ((vector - 0x800) >> 6) + 12;
-
handle_irq(irq, irq, regs);
}
@@ -99,10 +99,9 @@ takara_init_irq(void)
{
STANDARD_INIT_IRQ_PROLOG;
- if (alpha_using_srm)
+ if (alpha_using_srm) {
alpha_mv.device_interrupt = takara_srm_device_interrupt;
-
- if (!alpha_using_srm) {
+ } else {
unsigned int ctlreg = inl(0x500);
/* Return to non-accelerated mode. */
@@ -127,6 +126,37 @@ takara_init_irq(void)
*/
static int __init
+takara_map_irq_srm(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 */
+ { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */
+ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */
+ { -1, -1, -1, -1, -1}, /* slot 9 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 10 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 11 == nothing */
+ /* These are behind the bridges. */
+ { 12, 12, 13, 14, 15}, /* slot 12 == nothing */
+ { 8, 8, 9, 19, 11}, /* slot 13 == nothing */
+ { 4, 4, 5, 6, 7}, /* slot 14 == nothing */
+ { 0, 0, 1, 2, 3}, /* slot 15 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 16 == nothing */
+ {64+ 0, 64+0, 64+1, 64+2, 64+3}, /* slot 17= device 4 */
+ {48+ 0, 48+0, 48+1, 48+2, 48+3}, /* slot 18= device 3 */
+ {32+ 0, 32+0, 32+1, 32+2, 32+3}, /* slot 19= device 2 */
+ {16+ 0, 16+0, 16+1, 16+2, 16+3}, /* slot 20= device 1 */
+ };
+ const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
+ int irq = COMMON_TABLE_LOOKUP;
+ if (irq >= 0 && irq < 16) {
+ /* Guess that we are behind a bridge. */
+ unsigned int busslot = PCI_SLOT(dev->bus->self->devfn);
+ irq += irq_tab[busslot-min_idsel][0];
+ }
+ return irq;
+}
+
+static int __init
takara_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[15][5] __initlocaldata = {
@@ -165,10 +195,13 @@ takara_swizzle(struct pci_dev *dev, u8 *pinp)
if (pin == 1)
pin += (20 - busslot);
else {
- /* Must be a card-based bridge. */
- printk(KERN_WARNING "takara_swizzle: cannot handle "
- "card-bridge behind builtin bridge yet.\n");
+ printk(KERN_WARNING "takara_swizzle: can only "
+ "handle cards with INTA IRQ pin.\n");
}
+ } else {
+ /* Must be a card-based bridge. */
+ printk(KERN_WARNING "takara_swizzle: cannot handle "
+ "card-bridge behind builtin bridge yet.\n");
}
*pinp = pin;
@@ -178,8 +211,11 @@ takara_swizzle(struct pci_dev *dev, u8 *pinp)
static void __init
takara_init_pci(void)
{
+ if (alpha_using_srm)
+ alpha_mv.pci_map_irq = takara_map_irq_srm;
+
common_init_pci();
- /* ns87312_enable_ide(0x26e); */
+ ns87312_enable_ide(0x26e);
}
@@ -198,8 +234,8 @@ struct alpha_machine_vector takara_mv __initmv = {
min_io_address: DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
- nr_irqs: 20,
- irq_probe_mask: _PROBE_MASK(20),
+ nr_irqs: 128,
+ irq_probe_mask: _PROBE_MASK(48),
update_irq_hw: takara_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: takara_device_interrupt,
@@ -208,7 +244,7 @@ struct alpha_machine_vector takara_mv __initmv = {
init_irq: takara_init_irq,
init_pit: common_init_pit,
init_pci: takara_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: takara_map_irq,
pci_swizzle: takara_swizzle,
};
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index a86c79cc1..6e528e08f 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_impl.h"
+#include <asm/hw_irq.h>
extern rwlock_t xtime_lock;
extern volatile unsigned long lost_ticks; /* kernel/sched.c */
@@ -174,7 +174,7 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon,
#ifdef CONFIG_RTC
void
-rtc_init_pit (void)
+rtc_init_pit(void)
{
unsigned char control;
@@ -193,6 +193,25 @@ rtc_init_pit (void)
outb(0x31, 0x42);
outb(0x13, 0x42);
}
+
+void
+rtc_kill_pit(void)
+{
+ unsigned char control;
+
+ cli();
+
+ /* Reset periodic interrupt frequency. */
+ CMOS_WRITE(0x26, RTC_FREQ_SELECT);
+
+ /* Turn on periodic interrupts. */
+ control = CMOS_READ(RTC_CONTROL);
+ control |= RTC_PIE;
+ CMOS_WRITE(control, RTC_CONTROL);
+ CMOS_READ(RTC_INTR_FLAGS);
+
+ sti();
+}
#endif
void
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 59f021a77..36b0cc43a 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -113,7 +113,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
}
#ifndef CONFIG_MATHEMU
-static long dummy_emul() { return 0; }
+static long dummy_emul(void) { return 0; }
long (*alpha_fp_emul_imprecise)(struct pt_regs *regs, unsigned long writemask)
= (void *)dummy_emul;
long (*alpha_fp_emul) (unsigned long pc)