patch-2.1.92 linux/arch/alpha/kernel/bios32.c
Next file: linux/arch/alpha/kernel/cia.c
Previous file: linux/arch/alpha/kernel/apecs.c
Back to the patch index
Back to the overall index
- Lines: 1334
- Date:
Mon Mar 30 00:21:39 1998
- Orig file:
v2.1.91/linux/arch/alpha/kernel/bios32.c
- Orig date:
Thu Mar 26 15:57:02 1998
diff -u --recursive --new-file v2.1.91/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
@@ -25,6 +25,7 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
+#include <linux/tasks.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
@@ -63,6 +64,8 @@
#include <asm/hwrpb.h>
#include <asm/io.h>
#include <asm/uaccess.h>
+#include <asm/segment.h>
+#include <asm/system.h>
#define KB 1024
@@ -70,7 +73,9 @@
#define GB (1024*MB)
#define MAJOR_REV 0
-#define MINOR_REV 3
+
+/* minor revision 4, add multi-PCI handling */
+#define MINOR_REV 4
/*
* Align VAL to ALIGN, which must be a power of two.
@@ -78,7 +83,20 @@
#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
+#if defined(CONFIG_ALPHA_MCPCIA) || defined(CONFIG_ALPHA_TSUNAMI)
+/* multiple PCI bus machines */
+/* make handle from bus number */
+extern struct linux_hose_info *bus2hose[256];
+#define HANDLE(b) (((unsigned long)(bus2hose[(b)]->pci_hose_index)&3)<<32)
+#define DEV_IS_ON_PRIMARY(dev) \
+ (bus2hose[(dev)->bus->number]->pci_first_busno == (dev)->bus->number)
+#else /* MCPCIA || TSUNAMI */
+#define HANDLE(b) (0)
+#define DEV_IS_ON_PRIMARY(dev) ((dev)->bus->number == 0)
+#endif /* MCPCIA || TSUNAMI */
/*
+ * PCI_MODIFY
+ *
* Temporary internal macro. If this 0, then do not write to any of
* the PCI registers, merely read them (i.e., use configuration as
* determined by SRM). The SRM seem do be doing a less than perfect
@@ -95,7 +113,18 @@
* the graphics card---there have been some rumor that the #9 BIOS
* incorrectly resets that address to 0...).
*/
+#ifdef CONFIG_ALPHA_SRM_SETUP
+#define PCI_MODIFY 0
+static struct pci_dev *irq_dev_to_reset[16];
+static unsigned char irq_to_reset[16];
+static int irq_reset_count = 0;
+static struct pci_dev *io_dev_to_reset[16];
+static unsigned char io_reg_to_reset[16];
+static unsigned int io_to_reset[16];
+static int io_reset_count = 0;
+#else /* SRM_SETUP */
#define PCI_MODIFY 1
+#endif /* SRM_SETUP */
extern struct hwrpb_struct *hwrpb;
@@ -103,9 +132,7 @@
#if defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164)
extern int SMC93x_Init(void);
#endif
-#ifdef CONFIG_ALPHA_SX164
extern int SMC669_Init(void);
-#endif
#ifdef CONFIG_ALPHA_MIATA
static int es1888_init(void);
#endif
@@ -115,7 +142,7 @@
/*
* NOTE: we can't just blindly use 64K for machines with EISA busses; they
* may also have PCI-PCI bridges present, and then we'd configure the bridge
- * incorrectly
+ * incorrectly.
*
* Also, we start at 0x8000 or 0x9000, in hopes to get all devices'
* IO space areas allocated *before* 0xC000; this is because certain
@@ -123,12 +150,17 @@
* accesses to probe the bus. If a device's registers appear at 0xC000,
* it may see an INx/OUTx at that address during BIOS emulation of the
* VGA BIOS, and some cards, notably Adaptec 2940UW, take mortal offense.
+ *
+ * Note that we may need this stuff for SRM_SETUP also, since certain
+ * SRM consoles screw up and allocate I/O space addresses > 64K behind
+ * PCI-to_PCI bridges, which can't pass I/O addresses larger than 64K, AFAIK.
*/
#if defined(CONFIG_ALPHA_EISA)
-static unsigned int io_base = 0x9000; /* start above 8th slot */
+#define DEFAULT_IO_BASE 0x9000 /* start above 8th slot */
#else
-static unsigned int io_base = 0x8000;
+#define DEFAULT_IO_BASE 0x8000 /* start at 8th slot */
#endif
+static unsigned int io_base;
#if defined(CONFIG_ALPHA_XL)
/*
@@ -142,7 +174,7 @@
* We accept the risk that a broken Myrinet card will be put into a true XL
* and thus can more easily run into the problem described below.
*/
-static unsigned int mem_base = 16*MB + 2*MB; /* 16M to 64M-1 is avail */
+#define DEFAULT_MEM_BASE (16*MB + 2*MB) /* 16M to 64M-1 is avail */
#elif defined(CONFIG_ALPHA_LCA) || defined(CONFIG_ALPHA_APECS)
/*
@@ -154,7 +186,7 @@
* However, APECS and LCA have only 34 bits for physical addresses, thus
* limiting PCI bus memory addresses for SPARSE access to be less than 128Mb.
*/
-static unsigned int mem_base = 64*MB + 2*MB;
+#define DEFAULT_MEM_BASE (64*MB + 2*MB)
#else
/*
@@ -166,9 +198,10 @@
* Because CIA and PYXIS and T2 have more bits for physical addresses,
* they support an expanded range of SPARSE memory addresses.
*/
-static unsigned int mem_base = 128*MB + 16*MB;
+#define DEFAULT_MEM_BASE (128*MB + 16*MB)
#endif
+static unsigned int mem_base;
/*
* Disable PCI device DEV so that it does not respond to I/O or memory
@@ -179,7 +212,6 @@
struct pci_bus *bus;
unsigned short cmd;
-#ifdef CONFIG_ALPHA_EISA
/*
* HACK: the PCI-to-EISA bridge does not seem to identify
* itself as a bridge... :-(
@@ -189,15 +221,17 @@
DBG_DEVS(("disable_dev: ignoring PCEB...\n"));
return;
}
-#endif
-#ifdef CONFIG_ALPHA_SX164
+
+ /*
+ * we don't have code that will init the CYPRESS bridge correctly
+ * so we do the next best thing, and depend on the previous
+ * console code to do the right thing, and ignore it here... :-\
+ */
if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
- /* FIXME: We want a symbolic device name here. */
- dev->device == 0xc693) {
+ dev->device == PCI_DEVICE_ID_CONTAQ_82C693) {
DBG_DEVS(("disable_dev: ignoring CYPRESS bridge...\n"));
return;
}
-#endif
bus = dev->bus;
pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
@@ -211,16 +245,16 @@
/*
* Layout memory and I/O for a device:
*/
-#define MAX(val1, val2) ((val1) > (val2) ? val1 : val2)
+#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))
static void layout_dev(struct pci_dev *dev)
{
struct pci_bus *bus;
unsigned short cmd;
- unsigned int base, mask, size, reg;
+ unsigned int base, mask, size, off;
unsigned int alignto;
+ unsigned long handle;
-#ifdef CONFIG_ALPHA_EISA
/*
* HACK: the PCI-to-EISA bridge does not seem to identify
* itself as a bridge... :-(
@@ -230,32 +264,39 @@
DBG_DEVS(("layout_dev: ignoring PCEB...\n"));
return;
}
-#endif
-#ifdef CONFIG_ALPHA_SX164
+
+ /*
+ * we don't have code that will init the CYPRESS bridge correctly
+ * so we do the next best thing, and depend on the previous
+ * console code to do the right thing, and ignore it here... :-\
+ */
if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
- dev->device == 0xc693) {
+ dev->device == PCI_DEVICE_ID_CONTAQ_82C693) {
DBG_DEVS(("layout_dev: ignoring CYPRESS bridge...\n"));
return;
}
-#endif
bus = dev->bus;
pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
- for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
+ for (off = PCI_BASE_ADDRESS_0; off <= PCI_BASE_ADDRESS_5; off += 4) {
/*
* Figure out how much space and of what type this
* device wants.
*/
- pcibios_write_config_dword(bus->number, dev->devfn, reg,
+ pcibios_write_config_dword(bus->number, dev->devfn, off,
0xffffffff);
- pcibios_read_config_dword(bus->number, dev->devfn, reg, &base);
+ pcibios_read_config_dword(bus->number, dev->devfn, off, &base);
if (!base) {
/* this base-address register is unused */
- dev->base_address[(reg - PCI_BASE_ADDRESS_0)>>2] = 0;
+ dev->base_address[PCI_BASE_INDEX(off)] = 0;
continue;
}
+ DBG_DEVS(("layout_dev: slot %d fn %d off 0x%x base 0x%x\n",
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
+ off, base));
+
/*
* We've read the base address register back after
* writing all ones and so now we must decode it.
@@ -281,11 +322,13 @@
base = ALIGN(io_base, alignto);
io_base = base + size;
pcibios_write_config_dword(bus->number, dev->devfn,
- reg, base | 0x1);
- dev->base_address[(reg - PCI_BASE_ADDRESS_0)>>2]
- = base | 0x1;
- DBG_DEVS(("layout_dev: dev 0x%x IO @ 0x%x (0x%x)\n",
- dev->device, base, size));
+ off, base | 0x1);
+
+ handle = HANDLE(bus->number) | base | 1;
+ dev->base_address[PCI_BASE_INDEX(off)] = handle;
+
+ DBG_DEVS(("layout_dev: dev 0x%x IO @ 0x%lx (0x%x)\n",
+ dev->device, handle, size));
} else {
unsigned int type;
/*
@@ -306,7 +349,7 @@
"slot %d, function %d: \n",
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
- reg += 4; /* skip extra 4 bytes */
+ off += 4; /* skip extra 4 bytes */
continue;
case PCI_BASE_ADDRESS_MEM_TYPE_1M:
@@ -365,10 +408,11 @@
}
mem_base = base + size;
pcibios_write_config_dword(bus->number, dev->devfn,
- reg, base);
- dev->base_address[(reg-PCI_BASE_ADDRESS_0)>>2] = base;
- DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%x (0x%x)\n",
- dev->device, base, size));
+ off, base);
+ handle = HANDLE(bus->number) | base;
+ dev->base_address[PCI_BASE_INDEX(off)] = handle;
+ DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%lx (0x%x)\n",
+ dev->device, handle, size));
}
}
@@ -397,16 +441,17 @@
}
-static void layout_bus(struct pci_bus *bus)
+static int layout_bus(struct pci_bus *bus)
{
unsigned int l, tio, bio, tmem, bmem;
struct pci_bus *child;
struct pci_dev *dev;
+ int found_vga = 0;
DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
if (!bus->devices && !bus->children)
- return;
+ return 0;
/*
* Align the current bases on appropriate boundaries (4K for
@@ -424,6 +469,8 @@
* devices. They'll be re-enabled only once all address
* decoders are programmed consistently.
*/
+ DBG_DEVS(("layout_bus: disable_dev for bus %d\n", bus->number));
+
for (dev = bus->devices; dev; dev = dev->sibling) {
if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
(dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) {
@@ -441,6 +488,8 @@
(dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) {
layout_dev(dev);
}
+ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
+ found_vga = 1;
}
/*
* Recursively allocate space for all of the sub-buses:
@@ -448,7 +497,7 @@
DBG_DEVS(("layout_bus: starting bus %d children\n", bus->number));
for (child = bus->children; child; child = child->next) {
- layout_bus(child);
+ found_vga += layout_bus(child);
}
/*
* Align the current bases on 4K and 1MB boundaries:
@@ -458,6 +507,8 @@
if (bus->self) {
struct pci_dev *bridge = bus->self;
+
+ DBG_DEVS(("layout_bus: config bus %d bridge\n", bus->number));
/*
* Set up the top and bottom of the PCI I/O segment
* for this bus.
@@ -481,10 +532,13 @@
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x24, 0x0000ffff);
/*
- * Tell bridge that there is an ISA bus in the system:
+ * Tell bridge that there is an ISA bus in the system,
+ * and (possibly) a VGA as well.
*/
+ l = 0x00040000; /* ISA present */
+ if (found_vga) l |= 0x00080000; /* VGA present */
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
- 0x3c, 0x00040000);
+ 0x3c, l);
/*
* Clear status bits, enable I/O (for downstream I/O),
* turn on master enable (for upstream I/O), turn on
@@ -494,6 +548,8 @@
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x4, 0xffff0007);
}
+ DBG_DEVS(("layout_bus: bus %d finished\n", bus->number));
+ return found_vga;
}
#endif /* !PCI_MODIFY */
@@ -633,6 +689,76 @@
return (((pin-1) + slot) % 4) + 1;
}
+#ifdef CONFIG_ALPHA_SRM_SETUP
+/* look for mis-configured devices' I/O space addresses behind bridges */
+static void check_behind_io(struct pci_dev *dev)
+{
+ struct pci_bus *bus = dev->bus;
+ unsigned int reg, orig_base, new_base, found_one = 0;
+
+ for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
+ /* read the current setting, check for I/O space and >= 64K */
+ pcibios_read_config_dword(bus->number, dev->devfn, reg, &orig_base);
+ if (!orig_base || !(orig_base & PCI_BASE_ADDRESS_SPACE_IO))
+ continue; /* unused or non-IO */
+ if (orig_base < 64*1024) {
+#if 1
+printk("check_behind_io: ALREADY OK! bus %d slot %d base 0x%x\n",
+ bus->number, PCI_SLOT(dev->devfn), orig_base);
+#endif
+ if (orig_base & ~1)
+ continue; /* OK! */
+ orig_base = 0x12001; /* HACK! FIXME!! */
+ }
+
+ /* HACK ALERT! for now, just subtract 32K from the
+ original address, which should give us addresses
+ in the range 0x8000 and up */
+ new_base = orig_base - 0x8000;
+#if 1
+printk("check_behind_io: ALERT! bus %d slot %d old 0x%x new 0x%x\n",
+ bus->number, PCI_SLOT(dev->devfn), orig_base, new_base);
+#endif
+ pcibios_write_config_dword(bus->number, dev->devfn,
+ reg, new_base);
+
+ io_dev_to_reset[io_reset_count] = dev;
+ io_reg_to_reset[io_reset_count] = reg;
+ io_to_reset[io_reset_count] = orig_base;
+ io_reset_count++;
+ found_one++;
+ } /* end for-loop */
+
+ /* if any were modified, gotta hack the bridge IO limits too... */
+ if (found_one) {
+ if (bus->self) {
+ struct pci_dev *bridge = bus->self;
+ unsigned int l;
+ /*
+ * Set up the top and bottom of the PCI I/O segment
+ * for this bus.
+ */
+ pcibios_read_config_dword(bridge->bus->number,
+ bridge->devfn, 0x1c, &l);
+#if 1
+printk("check_behind_io: ALERT! bus %d slot %d oldLIM 0x%x\n",
+ bus->number, PCI_SLOT(bridge->devfn), l);
+#endif
+ l = (l & 0xffff0000U) | 0xf080U; /* give it ALL */
+ pcibios_write_config_dword(bridge->bus->number,
+ bridge->devfn, 0x1c, l);
+ pcibios_write_config_dword(bridge->bus->number,
+ bridge->devfn,
+ 0x3c, 0x00040000);
+ pcibios_write_config_dword(bridge->bus->number,
+ bridge->devfn,
+ 0x4, 0xffff0007);
+ } else
+ printk("check_behind_io: WARNING! bus->self NULL\n");
+ }
+}
+#endif /* CONFIG_ALPHA_SRM_SETUP */
+
/*
* Most evaluation boards share most of the fixup code, which is isolated
* here. This function is declared "inline" as only one platform will ever
@@ -644,7 +770,7 @@
char irq_tab[max_idsel - min_idsel + 1][irqs_per_slot],
long ide_base)
{
- struct pci_dev *dev;
+ struct pci_dev *dev, *curr;
unsigned char pin;
unsigned char slot;
@@ -652,12 +778,18 @@
* Go through all devices, fixing up irqs as we see fit:
*/
for (dev = pci_devices; dev; dev = dev->next) {
- if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE
- /* PCEB (PCI to EISA bridge) does not identify
- itself as a bridge... :-P */
- && !(dev->vendor == PCI_VENDOR_ID_INTEL &&
- dev->device == PCI_DEVICE_ID_INTEL_82375))
- || dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA) {
+ if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE ||
+ dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA) {
+ /*
+ * HACK: the PCI-to-EISA bridge appears not to identify
+ * itself as a bridge... :-(
+ */
+ if (dev->vendor == PCI_VENDOR_ID_INTEL &&
+ dev->device == PCI_DEVICE_ID_INTEL_82375) {
+ DBG_DEVS(("common_fixup: ignoring PCEB...\n"));
+ continue;
+ }
+
/*
* This device is not on the primary bus, we need
* to figure out which interrupt pin it will come
@@ -668,45 +800,100 @@
* the inline static routine above).
*/
dev->irq = 0;
- if (dev->bus->number != 0) {
- struct pci_dev *curr = dev;
+ if (!DEV_IS_ON_PRIMARY(dev)) {
/* read the pin and do the PCI-PCI bridge
interrupt pin swizzle */
pcibios_read_config_byte(dev->bus->number,
dev->devfn,
PCI_INTERRUPT_PIN,
&pin);
- /* cope with 0 */
- if (pin == 0)
+ /* cope with 0 and illegal */
+ if (pin == 0 || pin > 4)
pin = 1;
/* follow the chain of bridges, swizzling
as we go */
+ curr = dev;
#if defined(CONFIG_ALPHA_MIATA)
+ /* check first for the built-in bridge */
+ if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
+ (PCI_SLOT(dev->bus->self->devfn) == 20)) {
slot = PCI_SLOT(dev->devfn) + 5;
DBG_DEVS(("MIATA: bus 1 slot %d pin %d"
" irq %d min_idsel %d\n",
PCI_SLOT(dev->devfn), pin,
irq_tab[slot - min_idsel][pin],
min_idsel));
+ }
+ else /* must be a card-based bridge */
+ {
+ do {
+ if ((PCI_SLOT(curr->bus->self->devfn) == 8) ||
+ (PCI_SLOT(curr->bus->self->devfn) == 20))
+ {
+ slot = PCI_SLOT(curr->devfn) + 5;
+ break;
+ }
+ /* swizzle */
+ pin = bridge_swizzle(
+ pin, PCI_SLOT(curr->devfn)) ;
+ /* move up the chain of bridges */
+ curr = curr->bus->self ;
+ /* slot of the next bridge. */
+ slot = PCI_SLOT(curr->devfn);
+ } while (curr->bus->self) ;
+ }
#elif defined(CONFIG_ALPHA_NORITAKE)
- /* WAG Alert! */
- slot = PCI_SLOT(dev->devfn) + 14;
+ /* check first for the built-in bridge */
+ if (PCI_SLOT(dev->bus->self->devfn) == 8) {
+ slot = PCI_SLOT(dev->devfn) + 15; /* WAG! */
DBG_DEVS(("NORITAKE: bus 1 slot %d pin %d"
- " irq %d min_idsel %d\n",
+ "irq %d min_idsel %ld\n",
PCI_SLOT(dev->devfn), pin,
irq_tab[slot - min_idsel][pin],
min_idsel));
-#else
+ }
+ else /* must be a card-based bridge */
+ {
do {
+ if (PCI_SLOT(curr->bus->self->devfn) == 8) {
+ slot = PCI_SLOT(curr->devfn) + 15;
+ break;
+ }
/* swizzle */
- pin = bridge_swizzle(pin, PCI_SLOT(curr->devfn));
+ pin = bridge_swizzle(
+ pin, PCI_SLOT(curr->devfn)) ;
+ /* move up the chain of bridges */
+ curr = curr->bus->self ;
+ /* slot of the next bridge. */
+ slot = PCI_SLOT(curr->devfn);
+ } while (curr->bus->self) ;
+ }
+#else /* everyone but MIATA and NORITAKE */
+ DBG_DEVS(("common_fixup: bus %d slot %d pin %d "
+ "irq %d min_idsel %ld\n",
+ curr->bus->number,
+ PCI_SLOT(dev->devfn), pin,
+ irq_tab[slot - min_idsel][pin],
+ min_idsel));
+ do {
+ /* swizzle */
+ pin =
+ bridge_swizzle(pin, PCI_SLOT(curr->devfn));
/* move up the chain of bridges */
curr = curr->bus->self;
} while (curr->bus->self);
/* The slot is the slot of the last bridge. */
slot = PCI_SLOT(curr->devfn);
-#endif /* MIATA */
- } else {
+#endif
+#ifdef CONFIG_ALPHA_SRM_SETUP
+ /*
+ * must make sure that SRM didn't screw up
+ * and allocate an address > 64K for I/O
+ * space behind a PCI-PCI bridge
+ */
+ check_behind_io(dev);
+#endif /* CONFIG_ALPHA_SRM_SETUP */
+ } else { /* just a device on a primary bus */
/* work out the slot */
slot = PCI_SLOT(dev->devfn);
/* read the pin */
@@ -714,16 +901,48 @@
dev->devfn,
PCI_INTERRUPT_PIN,
&pin);
+ DBG_DEVS(("common_fixup: bus %d slot %d"
+ " pin %d irq %d min_idsel %ld\n",
+ dev->bus->number, slot, pin,
+ irq_tab[slot - min_idsel][pin],
+ min_idsel));
+ /* cope with 0 and illegal */
+ if (pin == 0 || pin > 4)
+ pin = 1;
}
if (irq_tab[slot - min_idsel][pin] != -1)
dev->irq = irq_tab[slot - min_idsel][pin];
-#if PCI_MODIFY
- /* tell the device: */
- pcibios_write_config_byte(dev->bus->number,
+#ifdef CONFIG_ALPHA_RAWHIDE
+ dev->irq +=
+ 24 * bus2hose[dev->bus->number]->pci_hose_index;
+#endif /* RAWHIDE */
+#ifdef CONFIG_ALPHA_SRM
+ {
+ unsigned char irq_orig;
+ /* read the original SRM-set IRQ and tell */
+ pcibios_read_config_byte(dev->bus->number,
dev->devfn,
PCI_INTERRUPT_LINE,
- dev->irq);
-#endif
+ &irq_orig);
+ if (irq_orig != dev->irq) {
+ DBG_DEVS(("common_fixup: bus %d slot 0x%x "
+ "SRM IRQ 0x%x changed to 0x%x\n",
+ dev->bus->number,PCI_SLOT(dev->devfn),
+ irq_orig, dev->irq));
+#ifdef CONFIG_ALPHA_SRM_SETUP
+ irq_dev_to_reset[irq_reset_count] = dev;
+ irq_to_reset[irq_reset_count] = irq_orig;
+ irq_reset_count++;
+#endif /* CONFIG_ALPHA_SRM_SETUP */
+ }
+ }
+#endif /* SRM */
+
+ /* always tell the device, so the driver knows what is
+ * the real IRQ to use; the device does not use it.
+ */
+ pcibios_write_config_byte(dev->bus->number, dev->devfn,
+ PCI_INTERRUPT_LINE, dev->irq);
DBG_DEVS(("common_fixup: bus %d slot 0x%x"
" VID 0x%x DID 0x%x\n"
@@ -737,11 +956,24 @@
* if it's a VGA, enable its BIOS ROM at C0000
*/
if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
- pcibios_write_config_dword(dev->bus->number,
+ /* but if its a Cirrus 543x/544x DISABLE it, */
+ /* since enabling ROM disables the memory... */
+ if ((dev->vendor == PCI_VENDOR_ID_CIRRUS) &&
+ (dev->device >= 0x00a0) &&
+ (dev->device <= 0x00ac)) {
+ pcibios_write_config_dword(
+ dev->bus->number,
+ dev->devfn,
+ PCI_ROM_ADDRESS,
+ 0x00000000);
+ } else {
+ pcibios_write_config_dword(
+ dev->bus->number,
dev->devfn,
PCI_ROM_ADDRESS,
0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
}
+ }
/*
* if it's a SCSI, disable its BIOS ROM
*/
@@ -752,46 +984,6 @@
0x0000000);
}
}
-#ifdef CONFIG_ALPHA_SX164
- /* If it the CYPRESS PCI-ISA bridge, disable IDE
- interrupt routing through PCI (ie do through PIC). */
- else if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
- dev->device == 0xc693 &&
- PCI_FUNC(dev->devfn) == 0) {
- pcibios_write_config_word(dev->bus->number,
- dev->devfn, 0x04, 0x0007);
-
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x40, 0x80);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x41, 0x80);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x42, 0x80);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x43, 0x80);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x44, 0x27);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x45, 0xe0);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x48, 0xf0);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x49, 0x40);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x4a, 0x00);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x4b, 0x80);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x4c, 0x80);
- pcibios_write_config_byte(dev->bus->number,
- dev->devfn, 0x4d, 0x70);
-
- outb(0, DMA1_RESET_REG);
- outb(0, DMA2_RESET_REG);
- outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
- outb(0, DMA2_MASK_REG);
- }
-#endif /* SX164 */
}
if (ide_base) {
enable_ide(ide_base);
@@ -814,6 +1006,7 @@
static inline void eb66p_fixup(void)
{
static char irq_tab[5][5] __initlocaldata = {
+ /*INT INTA INTB INTC INTD */
{16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J25 */
{16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J26 */
{ -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
@@ -825,8 +1018,8 @@
/*
- * The PC164/LX164 has 19 PCI interrupts, four from each of the four PCI
- * slots, the SIO, PCI/IDE, and USB.
+ * The PC164 and LX164 have 19 PCI interrupts, four from each of the four
+ * PCI slots, the SIO, PCI/IDE, and USB.
*
* Each of the interrupts can be individually masked. This is
* accomplished by setting the appropriate bit in the mask register.
@@ -901,6 +1094,7 @@
static inline void cabriolet_fixup(void)
{
static char irq_tab[5][5] __initlocaldata = {
+ /*INT INTA INTB INTC INTD */
{ 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5, slot 2, J21 */
{ 16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J19 */
{ 16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J20 */
@@ -957,6 +1151,7 @@
static inline void eb66_and_eb64p_fixup(void)
{
static char irq_tab[5][5] __initlocaldata = {
+ /*INT INTA INTB INTC INTD */
{16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */
{16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */
{16+1, 16+1, 16+3, 16+8, 16+10}, /* IdSel 7, slot ?, ?? */
@@ -968,7 +1163,7 @@
/*
- * Fixup configuration for MIKASA (NORITAKE is different)
+ * Fixup configuration for MIKASA (AlphaServer 1000)
*
* Summary @ 0x536:
* Bit Meaning
@@ -1020,7 +1215,10 @@
}
/*
- * Fixup configuration for NORITAKE (MIKASA is different)
+ * Fixup configuration for NORITAKE (AlphaServer 1000A)
+ *
+ * This is also used for CORELLE (AlphaServer 800)
+ * and ALCOR Primo (AlphaStation 600A).
*
* Summary @ 0x542, summary register #1:
* Bit Meaning
@@ -1076,8 +1274,11 @@
*/
static inline void noritake_fixup(void)
{
- static char irq_tab[13][5] __initlocaldata = {
+ static char irq_tab[15][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
+ /* note: IDSELs 16, 17, and 25 are CORELLE only */
+ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */
+ { -1, -1, -1, -1, -1}, /* IdSel 17, S3 Trio64 */
{ -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */
{ -1, -1, -1, -1, -1}, /* IdSel 19, PPB */
{ -1, -1, -1, -1, -1}, /* IdSel 20, ???? */
@@ -1085,18 +1286,20 @@
{ 16+2, 16+2, 16+3, 32+2, 32+3}, /* IdSel 22, slot 0 */
{ 16+4, 16+4, 16+5, 32+4, 32+5}, /* IdSel 23, slot 1 */
{ 16+6, 16+6, 16+7, 32+6, 32+7}, /* IdSel 24, slot 2 */
- /* The following are actually on bus 1, across the bridge */
+ { 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 25, slot 3 */
+ /* the following 5 are actually on PCI bus 1, which is */
+ /* across the built-in bridge of the NORITAKE only */
{ 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */
{ 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 17, slot 3 */
{16+10, 16+10, 16+11, 32+10, 32+11}, /* IdSel 18, slot 4 */
{16+12, 16+12, 16+13, 32+12, 32+13}, /* IdSel 19, slot 5 */
{16+14, 16+14, 16+15, 32+14, 32+15}, /* IdSel 20, slot 6 */
};
- common_fixup(7, 18, 5, irq_tab, 0);
+ common_fixup(5, 19, 5, irq_tab, 0);
}
/*
- * Fixup configuration for ALCOR
+ * Fixup configuration for ALCOR and XLT (XL-300/366/433)
*
* Summary @ GRU_INT_REQ:
* Bit Meaning
@@ -1126,6 +1329,7 @@
* The device to slot mapping looks like:
*
* Slot Device
+ * 6 built-in TULIP (XLT only)
* 7 PCI on board slot 0
* 8 PCI on board slot 3
* 9 PCI on board slot 4
@@ -1140,8 +1344,10 @@
*/
static inline void alcor_fixup(void)
{
- static char irq_tab[6][5] __initlocaldata = {
+ static char irq_tab[7][5] __initlocaldata = {
/*INT INTA INTB INTC INTD */
+ /* note: IDSEL 17 is XLT only */
+ {16+13, 16+13, 16+13, 16+13, 16+13}, /* IdSel 17, TULIP */
{ 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 18, slot 0 */
{16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 19, slot 3 */
{16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 20, slot 4 */
@@ -1149,62 +1355,6 @@
{ 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 2 */
{ 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
};
- common_fixup(7, 12, 5, irq_tab, 0);
-}
-
-/*
- * Fixup configuration for ALPHA XLT (EV5/EV56)
- *
- * Summary @ GRU_INT_REQ:
- * Bit Meaning
- * 0 Interrupt Line A from slot 2
- * 1 Interrupt Line B from slot 2
- * 2 Interrupt Line C from slot 2
- * 3 Interrupt Line D from slot 2
- * 4 Interrupt Line A from slot 1
- * 5 Interrupt line B from slot 1
- * 6 Interrupt Line C from slot 1
- * 7 Interrupt Line D from slot 1
- * 8 Interrupt Line A from slot 0
- * 9 Interrupt Line B from slot 0
- *10 Interrupt Line C from slot 0
- *11 Interrupt Line D from slot 0
- *12 NCR810 SCSI in slot 9
- *13 DC-21040 (TULIP) in slot 6
- *14-19 Reserved
- *20-23 Jumpers (interrupt)
- *24-27 Module revision
- *28-30 Reserved
- *31 EISA interrupt
- *
- * The device to slot mapping looks like:
- *
- * Slot Device
- * 6 TULIP
- * 7 PCI on board slot 0
- * 8 none
- * 9 SCSI
- * 10 PCI-ISA bridge
- * 11 PCI on board slot 2
- * 12 PCI on board slot 1
- *
- *
- * This two layered interrupt approach means that we allocate IRQ 16 and
- * above for PCI interrupts. The IRQ relates to which bit the interrupt
- * comes in on. This makes interrupt processing much easier.
- */
-static inline void xlt_fixup(void)
-{
- static char irq_tab[7][5] __initlocaldata = {
- /*INT INTA INTB INTC INTD */
- {16+13, 16+13, 16+13, 16+13, 16+13}, /* IdSel 17, TULIP */
- { 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 18, slot 0 */
- { -1, -1, -1, -1, -1}, /* IdSel 19, none */
- {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 20, SCSI */
- { -1, -1, -1, -1, -1}, /* IdSel 21, SIO */
- { 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 2 */
- { 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
- };
common_fixup(6, 12, 5, irq_tab, 0);
}
@@ -1262,8 +1412,6 @@
* with the values in the sable_irq_to_mask[] and sable_mask_to_irq[] tables
* in irq.c
*/
-
-#ifdef CONFIG_ALPHA_SABLE
static inline void sable_fixup(void)
{
static char irq_tab[9][5] __initlocaldata = {
@@ -1280,7 +1428,6 @@
};
common_fixup(0, 8, 5, irq_tab, 0);
}
-#endif
/*
* Fixup configuration for MIATA (EV56+PYXIS)
@@ -1362,7 +1509,8 @@
{ -1, -1, -1, -1, -1}, /* IdSel 21, none */
{16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 22, slot 4 */
{16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 23, slot 5 */
- /* The following are actually on bus 1, across the bridge */
+ /* The following are actually on bus 1, which is */
+ /* across the builtin PCI-PCI bridge */
{16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 24, slot 1 */
{16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 25, slot 2 */
{16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 26, slot 3 */
@@ -1373,6 +1521,7 @@
{ -1, -1, -1, -1, -1}, /* IdSel 31, PCI-PCI */
};
common_fixup(3, 20, 5, irq_tab, 0);
+ SMC669_Init(); /* it might be a GL (fails harmlessly if not) */
es1888_init();
}
#endif
@@ -1399,7 +1548,6 @@
*14 Interrupt Line B from slot 1
*15 Interrupt line B from slot 0
*16 Interrupt Line C from slot 3
-
*17 Interrupt Line C from slot 2
*18 Interrupt Line C from slot 1
*19 Interrupt Line C from slot 0
@@ -1417,7 +1565,6 @@
*
*/
-#ifdef CONFIG_ALPHA_SX164
static inline void sx164_fixup(void)
{
static char irq_tab[5][5] __initlocaldata = {
@@ -1428,12 +1575,154 @@
{ -1, -1, -1, -1, -1}, /* IdSel 8 SIO */
{ 16+ 8, 16+ 8, 16+12, 16+16, 16+20} /* IdSel 9 slot 3 J15 */
};
-
common_fixup(5, 9, 5, irq_tab, 0);
+ SMC669_Init();
+}
+/*
+ * Fixup configuration for DP264 (EV6+TSUNAMI)
+ *
+ * Summary @ TSUNAMI_CSR_DIM0:
+ * Bit Meaning
+ * 0-17 Unused
+ *18 Interrupt SCSI B (Adaptec 7895 builtin)
+ *19 Interrupt SCSI A (Adaptec 7895 builtin)
+ *20 Interrupt Line D from slot 2 PCI0
+ *21 Interrupt Line C from slot 2 PCI0
+ *22 Interrupt Line B from slot 2 PCI0
+ *23 Interrupt Line A from slot 2 PCI0
+ *24 Interrupt Line D from slot 1 PCI0
+ *25 Interrupt Line C from slot 1 PCI0
+ *26 Interrupt Line B from slot 1 PCI0
+ *27 Interrupt Line A from slot 1 PCI0
+ *28 Interrupt Line D from slot 0 PCI0
+ *29 Interrupt Line C from slot 0 PCI0
+ *30 Interrupt Line B from slot 0 PCI0
+ *31 Interrupt Line A from slot 0 PCI0
+ *
+ *32 Interrupt Line D from slot 3 PCI1
+ *33 Interrupt Line C from slot 3 PCI1
+ *34 Interrupt Line B from slot 3 PCI1
+ *35 Interrupt Line A from slot 3 PCI1
+ *36 Interrupt Line D from slot 2 PCI1
+ *37 Interrupt Line C from slot 2 PCI1
+ *38 Interrupt Line B from slot 2 PCI1
+ *39 Interrupt Line A from slot 2 PCI1
+ *40 Interrupt Line D from slot 1 PCI1
+ *41 Interrupt Line C from slot 1 PCI1
+ *42 Interrupt Line B from slot 1 PCI1
+ *43 Interrupt Line A from slot 1 PCI1
+ *44 Interrupt Line D from slot 0 PCI1
+ *45 Interrupt Line C from slot 0 PCI1
+ *46 Interrupt Line B from slot 0 PCI1
+ *47 Interrupt Line A from slot 0 PCI1
+ *48-52 Unused
+ *53 PCI0 NMI (from Cypress)
+ *54 PCI0 SMI INT (from Cypress)
+ *55 PCI0 ISA Interrupt (from Cypress)
+ *56-60 Unused
+ *61 PCI1 Bus Error
+ *62 PCI0 Bus Error
+ *63 Reserved
+ *
+ * IdSel
+ * 5 Cypress Bridge I/O
+ * 6 SCSI Adaptec builtin
+ * 7 64 bit PCI option slot 0
+ * 8 64 bit PCI option slot 1
+ * 9 64 bit PCI option slot 2
+ *
+ */
+
+static inline void dp264_fixup(void)
+{
+ static char irq_tab[5][5] __initlocaldata = {
+ /*INT INTA INTB INTC INTD */
+ { -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */
+ { 16+ 2, 16+ 2, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin */
+ { 16+15, 16+15, 16+14, 16+13, 16+12}, /* IdSel 7 slot 0 */
+ { 16+11, 16+11, 16+10, 16+ 9, 16+ 8}, /* IdSel 8 slot 1 */
+ { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4} /* IdSel 9 slot 2 */
+ };
+ common_fixup(5, 9, 5, irq_tab, 0);
SMC669_Init();
}
-#endif
+
+/*
+ * Fixup configuration for RAWHIDE
+ *
+ * Summary @ MCPCIA_PCI0_INT_REQ:
+ * Bit Meaning
+ *0 Interrupt Line A from slot 2 PCI0
+ *1 Interrupt Line B from slot 2 PCI0
+ *2 Interrupt Line C from slot 2 PCI0
+ *3 Interrupt Line D from slot 2 PCI0
+ *4 Interrupt Line A from slot 3 PCI0
+ *5 Interrupt Line B from slot 3 PCI0
+ *6 Interrupt Line C from slot 3 PCI0
+ *7 Interrupt Line D from slot 3 PCI0
+ *8 Interrupt Line A from slot 4 PCI0
+ *9 Interrupt Line B from slot 4 PCI0
+ *10 Interrupt Line C from slot 4 PCI0
+ *11 Interrupt Line D from slot 4 PCI0
+ *12 Interrupt Line A from slot 5 PCI0
+ *13 Interrupt Line B from slot 5 PCI0
+ *14 Interrupt Line C from slot 5 PCI0
+ *15 Interrupt Line D from slot 5 PCI0
+ *16 EISA interrupt (PCI 0) or SCSI interrupt (PCI 1)
+ *17-23 NA
+ *
+ * IdSel
+ * 1 EISA bridge (PCI bus 0 only)
+ * 2 PCI option slot 2
+ * 3 PCI option slot 3
+ * 4 PCI option slot 4
+ * 5 PCI option slot 5
+ *
+ */
+
+static inline void rawhide_fixup(void)
+{
+ static char irq_tab[5][5] __initlocaldata = {
+ /*INT INTA INTB INTC INTD */
+ { 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 only */
+ { 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */
+ { 16+ 4, 16+ 4, 16+ 5, 16+ 6, 16+ 7}, /* IdSel 3 slot 3 */
+ { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 4 slot 4 */
+ { 16+12, 16+12, 16+13, 16+14, 16+15} /* IdSel 5 slot 5 */
+ };
+ common_fixup(1, 5, 5, irq_tab, 0);
+}
+
+/*
+ * The Takara has PCI devices 1, 2, and 3 configured to slots 20,
+ * 19, and 18 respectively, in the default configuration. They can
+ * also be jumpered to slots 8, 7, and 6 respectively, which is fun
+ * because the SIO ISA bridge can also be slot 7. However, the SIO
+ * doesn't explicitly generate PCI-type interrupts, so we can
+ * assign it whatever the hell IRQ we like and it doesn't matter.
+ */
+static inline void takara_fixup(void)
+{
+ 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 */
+ { -1, -1, -1, -1, -1}, /* slot 12 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 13 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 14 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 15 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 16 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 17 == nothing */
+ { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 18 == device 3 */
+ { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 19 == device 2 */
+ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 20 == device 1 */
+ };
+ common_fixup(6, 20, 5, irq_tab, 0x26e);
+}
/*
* Fixup configuration for all boards that route the PCI interrupts
@@ -1462,6 +1751,7 @@
* driven at all).
*/
static const char pirq_tab[][5] __initlocaldata = {
+ /*INT A B C D */
#ifdef CONFIG_ALPHA_P2K
{ 0, 0, -1, -1, -1}, /* idsel 6 (53c810) */
{-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */
@@ -1497,7 +1787,7 @@
#if defined(CONFIG_ALPHA_BOOK1)
/* for the AlphaBook1, NCR810 SCSI is 14, PCMCIA controller is 15 */
- const unsigned int route_tab = 0x0e0f0a0a;
+ const unsigned int new_route_tab = 0x0e0f0a0a;
#elif defined(CONFIG_ALPHA_NONAME)
/*
@@ -1510,16 +1800,24 @@
* they are co-indicated when the platform type "Noname" is
* selected... :-(
*/
- const unsigned int route_tab = 0x0b0a0f09;
+ const unsigned int new_route_tab = 0x0b0a0f09;
#else
- const unsigned int route_tab = 0x0b0a090f;
+ const unsigned int new_route_tab = 0x0b0a090f;
#endif
-
- unsigned int level_bits;
+ unsigned int route_tab, old_route_tab;
+ unsigned int level_bits, old_level_bits;
unsigned char pin, slot;
int pirq;
+ pcibios_read_config_dword(0, PCI_DEVFN(7, 0), 0x60, &old_route_tab);
+ DBG_DEVS(("sio_fixup: old pirq route table: 0x%08x\n",
+ old_route_tab));
+#if PCI_MODIFY
+ route_tab = new_route_tab;
pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60, route_tab);
+#else
+ route_tab = old_route_tab;
+#endif
/*
* Go through all devices, fixing up irqs as we see fit:
@@ -1576,20 +1874,33 @@
* if it's a VGA, enable its BIOS ROM at C0000
*/
if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
- pcibios_write_config_dword(dev->bus->number,
+ /* but if its a Cirrus 543x/544x DISABLE it, */
+ /* since enabling ROM disables the memory... */
+ if ((dev->vendor == PCI_VENDOR_ID_CIRRUS) &&
+ (dev->device >= 0x00a0) &&
+ (dev->device <= 0x00ac)) {
+ pcibios_write_config_dword(
+ dev->bus->number,
+ dev->devfn,
+ PCI_ROM_ADDRESS,
+ 0x00000000);
+ } else {
+ pcibios_write_config_dword(
+ dev->bus->number,
dev->devfn,
PCI_ROM_ADDRESS,
0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
}
+ }
if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
continue; /* for now, displays get no IRQ */
}
if (pirq < 0) {
- printk("bios32.sio_fixup: "
+ DBG_DEVS(("bios32.sio_fixup: "
"weird, device %04x:%04x coming in on"
" slot %d has no irq line!!\n",
- dev->vendor, dev->device, slot);
+ dev->vendor, dev->device, slot));
continue;
}
@@ -1653,7 +1964,12 @@
*
* Note: we at least preserve any level-set bits on AlphaBook1
*/
- level_bits |= ((inb(0x4d0) | (inb(0x4d1) << 8)) & 0x71ff);
+ old_level_bits = inb(0x4d0) | (inb(0x4d1) << 8);
+ DBG_DEVS(("sio_fixup: old irq level bits: 0x%04x\n",
+ old_level_bits));
+ level_bits |= (old_level_bits & 0x71ff);
+ DBG_DEVS(("sio_fixup: new irq level bits: 0x%04x\n",
+ level_bits));
outb((level_bits >> 0) & 0xff, 0x4d0);
outb((level_bits >> 8) & 0xff, 0x4d1);
@@ -1688,11 +2004,35 @@
unsigned long __init
pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
{
+ struct pci_bus *cur;
+
+#ifdef CONFIG_ALPHA_MCPCIA
+ /* must do massive setup for multiple PCI busses here... */
+ DBG_DEVS(("pcibios_fixup: calling mcpcia_fixup()...\n"));
+ mem_start = mcpcia_fixup(mem_start, mem_end);
+#endif /* MCPCIA */
+
+#ifdef CONFIG_ALPHA_TSUNAMI
+ /* must do massive setup for multiple PCI busses here... */
+ /* mem_start = tsunami_fixup(mem_start, mem_end); */
+#endif /* TSUNAMI */
+
#if PCI_MODIFY && !defined(CONFIG_ALPHA_RUFFIAN)
/*
* Scan the tree, allocating PCI memory and I/O space.
*/
- layout_bus(&pci_root);
+ /*
+ * Sigh; check_region() will need changing to accept a HANDLE,
+ * if we allocate I/O space addresses on a per-bus basis.
+ * For now, make the I/O bases unique across all busses, so
+ * that check_region() will not get confused... ;-}
+ */
+ io_base = DEFAULT_IO_BASE;
+ for (cur = &pci_root; cur; cur = cur->next) {
+ mem_base = DEFAULT_MEM_BASE;
+ DBG_DEVS(("pcibios_fixup: calling layout_bus()\n"));
+ layout_bus(cur);
+ }
#endif
/*
@@ -1713,10 +2053,8 @@
eb66_and_eb64p_fixup();
#elif defined(CONFIG_ALPHA_MIKASA)
mikasa_fixup();
-#elif defined(CONFIG_ALPHA_ALCOR)
+#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
alcor_fixup();
-#elif defined(CONFIG_ALPHA_XLT)
- xlt_fixup();
#elif defined(CONFIG_ALPHA_SABLE)
sable_fixup();
#elif defined(CONFIG_ALPHA_MIATA)
@@ -1725,6 +2063,12 @@
noritake_fixup();
#elif defined(CONFIG_ALPHA_SX164)
sx164_fixup();
+#elif defined(CONFIG_ALPHA_DP264)
+ dp264_fixup();
+#elif defined(CONFIG_ALPHA_RAWHIDE)
+ rawhide_fixup();
+#elif defined(CONFIG_ALPHA_TAKARA)
+ takara_fixup();
#elif defined(CONFIG_ALPHA_RUFFIAN)
/* no fixup needed */
#else
@@ -1831,6 +2175,33 @@
return err;
}
+#if (defined(CONFIG_ALPHA_PC164) || \
+ defined(CONFIG_ALPHA_LX164) || \
+ defined(CONFIG_ALPHA_SX164) || \
+ defined(CONFIG_ALPHA_EB164) || \
+ defined(CONFIG_ALPHA_EB66P) || \
+ defined(CONFIG_ALPHA_CABRIOLET)) && defined(CONFIG_ALPHA_SRM)
+
+/*
+ on the above machines, under SRM console, we must use the CSERVE PALcode
+ routine to manage the interrupt mask for us, otherwise, the kernel/HW get
+ out of sync with what the PALcode thinks it needs to deliver/ignore
+ */
+void
+cserve_update_hw(unsigned long irq, unsigned long mask)
+{
+ extern void cserve_ena(unsigned long);
+ extern void cserve_dis(unsigned long);
+
+ if (mask & (1UL << irq))
+ /* disable */
+ cserve_dis(irq - 16);
+ else
+ /* enable */
+ cserve_ena(irq - 16);
+ return;
+}
+#endif /* (PC164 || LX164 || SX164 || EB164 || CABRIO) && SRM */
#ifdef CONFIG_ALPHA_MIATA
/*
@@ -1876,5 +2247,45 @@
return 0;
}
#endif /* CONFIG_ALPHA_MIATA */
+
+#ifdef CONFIG_ALPHA_SRM_SETUP
+void reset_for_srm(void)
+{
+ extern void scrreset(void);
+ struct pci_dev *dev;
+ int i;
+
+ /* reset any IRQs that we changed */
+ for (i = 0; i < irq_reset_count; i++) {
+ dev = irq_dev_to_reset[i];
+
+ pcibios_write_config_byte(dev->bus->number, dev->devfn,
+ PCI_INTERRUPT_LINE, irq_to_reset[i]);
+#if 1
+ printk("reset_for_srm: bus %d slot 0x%x "
+ "SRM IRQ 0x%x changed back from 0x%x\n",
+ dev->bus->number, PCI_SLOT(dev->devfn),
+ irq_to_reset[i], dev->irq);
+#endif
+ }
+
+ /* reset any IO addresses that we changed */
+ for (i = 0; i < io_reset_count; i++) {
+ dev = io_dev_to_reset[i];
+
+ pcibios_write_config_byte(dev->bus->number, dev->devfn,
+ io_reg_to_reset[i], io_to_reset[i]);
+#if 1
+ printk("reset_for_srm: bus %d slot 0x%x "
+ "SRM IO restored to 0x%x\n",
+ dev->bus->number, PCI_SLOT(dev->devfn),
+ io_to_reset[i]);
+#endif
+}
+
+ /* reset the visible screen to the top of display memory */
+ scrreset();
+}
+#endif /* CONFIG_ALPHA_SRM_SETUP */
#endif /* CONFIG_PCI */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov