patch-2.3.8 linux/arch/alpha/kernel/sys_dp264.c
Next file: linux/arch/alpha/kernel/sys_takara.c
Previous file: linux/arch/alpha/kernel/smp.c
Back to the patch index
Back to the overall index
- Lines: 356
- Date:
Tue Jun 22 10:46:52 1999
- Orig file:
v2.3.7/linux/arch/alpha/kernel/sys_dp264.c
- Orig date:
Sun Feb 21 19:06:36 1999
diff -u --recursive --new-file v2.3.7/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c
@@ -2,8 +2,8 @@
* linux/arch/alpha/kernel/sys_dp264.c
*
* Copyright (C) 1995 David A Rusling
- * Copyright (C) 1996 Jay A Estabrook
- * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1996, 1999 Jay A Estabrook
+ * Copyright (C) 1998, 1999 Richard Henderson
*
* Code supporting the DP264 (EV6+TSUNAMI).
*/
@@ -35,7 +35,7 @@
#define dev2hose(d) (bus2hose[(d)->bus->number]->pci_hose_index)
/*
- * HACK ALERT! only CPU#0 is used currently
+ * HACK ALERT! only the boot cpu is used for interrupts.
*/
static void
@@ -66,34 +66,60 @@
}
static void
+clipper_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+ if (irq >= 16) {
+ volatile unsigned long *csr;
+
+ if (TSUNAMI_bootcpu < 2)
+ if (!TSUNAMI_bootcpu)
+ csr = &TSUNAMI_cchip->dim0.csr;
+ else
+ csr = &TSUNAMI_cchip->dim1.csr;
+ else
+ if (TSUNAMI_bootcpu == 2)
+ csr = &TSUNAMI_cchip->dim2.csr;
+ else
+ csr = &TSUNAMI_cchip->dim3.csr;
+
+ *csr = (~mask >> 16) | (1UL << 55); /* master ISA enable */
+ mb();
+ *csr;
+ }
+ else if (irq >= 8)
+ outb(mask >> 8, 0xA1); /* ISA PIC2 */
+ else
+ outb(mask, 0x21); /* ISA PIC1 */
+}
+
+static void
dp264_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
#if 1
printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
#else
- unsigned long pld;
- unsigned int i;
+ unsigned long pld;
+ unsigned int i;
- /* Read the interrupt summary register of TSUNAMI */
- pld = TSUNAMI_cchip->dir0.csr;
+ /* Read the interrupt summary register of TSUNAMI */
+ pld = TSUNAMI_cchip->dir0.csr;
- /*
- * Now for every possible bit set, work through them and call
- * the appropriate interrupt handler.
- */
- while (pld) {
- i = ffz(~pld);
- pld &= pld - 1; /* clear least bit set */
- if (i == 55) {
- isa_device_interrupt(vector, regs);
- } else { /* if not timer int */
- handle_irq(16 + i, 16 + i, regs);
- }
+ /*
+ * Now for every possible bit set, work through them and call
+ * the appropriate interrupt handler.
+ */
+ while (pld) {
+ i = ffz(~pld);
+ pld &= pld - 1; /* clear least bit set */
+ if (i == 55)
+ isa_device_interrupt(vector, regs);
+ else
+ handle_irq(16 + i, 16 + i, regs);
#if 0
TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
tmp = TSUNAMI_cchip->dir0.csr;
#endif
- }
+ }
#endif
}
@@ -104,24 +130,48 @@
ack = irq = (vector - 0x800) >> 4;
- /*
- * The DP264 SRM console reports PCI interrupts with a vector
- * 0x100 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
- * shows up as IRQ 16, etc, etc. We adjust it down by 16 to have
- * it line up with the actual bit numbers from the DIM registers,
- * which is how we manage the interrupts/mask. Sigh...
- */
- if (irq >= 32)
- ack = irq = irq - 16;
+ /*
+ * The SRM console reports PCI interrupts with a vector calculated by:
+ *
+ * 0x900 + (0x10 * DRIR-bit)
+ *
+ * So bit 16 shows up as IRQ 32, etc.
+ *
+ * On DP264/BRICK/MONET, we adjust it down by 16 because at least
+ * that many of the low order bits of the DRIR are not used, and
+ * so we don't count them.
+ */
+ if (irq >= 32)
+ ack = irq = irq - 16;
+
+ handle_irq(irq, ack, regs);
+}
+
+static void
+clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ int irq, ack;
+
+ ack = irq = (vector - 0x800) >> 4;
+ /*
+ * The SRM console reports PCI interrupts with a vector calculated by:
+ *
+ * 0x900 + (0x10 * DRIR-bit)
+ *
+ * So bit 16 shows up as IRQ 32, etc.
+ *
+ * CLIPPER uses bits 8-47 for PCI interrupts, so we do not need
+ * to scale down the vector reported, we just use it.
+ *
+ * Eg IRQ 24 is DRIR bit 8, etc, etc
+ */
handle_irq(irq, ack, regs);
}
static void __init
dp264_init_irq(void)
{
- volatile unsigned long *csr;
-
outb(0, DMA1_RESET_REG);
outb(0, DMA2_RESET_REG);
outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
@@ -130,23 +180,26 @@
if (alpha_using_srm)
alpha_mv.device_interrupt = dp264_srm_device_interrupt;
- if (TSUNAMI_bootcpu < 2)
- if (!TSUNAMI_bootcpu)
- csr = &TSUNAMI_cchip->dim0.csr;
- else
- csr = &TSUNAMI_cchip->dim1.csr;
- else
- if (TSUNAMI_bootcpu == 2)
- csr = &TSUNAMI_cchip->dim2.csr;
- else
- csr = &TSUNAMI_cchip->dim3.csr;
-
- /* Note invert on MASK bits. */
- *csr = ~(alpha_irq_mask);
- mb();
- *csr;
+ dp264_update_irq_hw(16, alpha_irq_mask, 0);
- enable_irq(55); /* Enable CYPRESS interrupt controller (ISA). */
+ enable_irq(55); /* Enable ISA interrupt controller. */
+ enable_irq(2);
+}
+
+static void __init
+clipper_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 = clipper_srm_device_interrupt;
+
+ clipper_update_irq_hw(16, alpha_irq_mask, 0);
+
+ enable_irq(55); /* Enable ISA interrupt controller. */
enable_irq(2);
}
@@ -221,7 +274,7 @@
const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
int irq = COMMON_TABLE_LOOKUP;
- if (irq >= 0)
+ if (irq > 0)
irq += 16 * dev2hose(dev);
return irq;
@@ -250,42 +303,38 @@
{ 32, 32, 33, 34, 35}, /* IdSel 13 slot 3 PCI0*/
{ 28, 28, 29, 30, 31}, /* IdSel 14 slot 4 PCI2*/
{ 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/
-};
+ };
const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
- int irq = COMMON_TABLE_LOOKUP;
-
- return irq;
+ return COMMON_TABLE_LOOKUP;
}
static int __init
monet_swizzle(struct pci_dev *dev, int *pinp)
{
- int slot, pin = *pinp;
+ int slot, pin = *pinp;
- /* Check first for the built-in bridge on hose 1. */
- if (dev2hose(dev) == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
- slot = PCI_SLOT(dev->devfn);
- }
- else
- {
- /* Must be a card-based bridge. */
- do {
+ /* Check first for the built-in bridge on hose 1. */
+ if (dev2hose(dev) == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
+ slot = PCI_SLOT(dev->devfn);
+ } else {
+ /* Must be a card-based bridge. */
+ do {
/* Check for built-in bridge on hose 1. */
- if (dev2hose(dev) == 1 &&
+ if (dev2hose(dev) == 1 &&
PCI_SLOT(dev->bus->self->devfn) == 8) {
slot = PCI_SLOT(dev->devfn);
break;
- }
- pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ;
+ }
+ 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;
+ /* 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;
}
static int __init
@@ -300,14 +349,34 @@
{ 30, 30, 30, 30, 30}, /* IdSel 11 21143 #2 */
{ -1, -1, -1, -1, -1}, /* IdSel 12 unused */
{ -1, -1, -1, -1, -1}, /* IdSel 13 unused */
- { 47, 47, 46, 45, 44}, /* IdSel 14 slot 0 */
+ { 35, 35, 34, 33, 32}, /* IdSel 14 slot 0 */
{ 39, 39, 38, 37, 36}, /* IdSel 15 slot 1 */
{ 43, 43, 42, 41, 40}, /* IdSel 16 slot 2 */
- { 35, 35, 34, 33, 32}, /* IdSel 17 slot 3 */
-};
+ { 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */
+ };
const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
+ return COMMON_TABLE_LOOKUP;
+}
+
+static int __init
+clipper_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+ static char irq_tab[7][5] __initlocaldata = {
+ /*INT INTA INTB INTC INTD */
+ { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */
+ { 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */
+ { 16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 3 slot 3 */
+ { 16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 4 slot 4 */
+ { 16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 5 slot 5 */
+ { 16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 6 slot 6 */
+ { -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */
+ };
+ const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
int irq = COMMON_TABLE_LOOKUP;
+ if (irq > 0)
+ irq += 16 * dev2hose(dev);
+
return irq;
}
@@ -336,6 +405,13 @@
SMC669_Init(0);
}
+static void __init
+clipper_pci_fixup(void)
+{
+ layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+ common_pci_fixup(clipper_map_irq, common_swizzle);
+}
+
/*
* The System Vectors
@@ -407,5 +483,28 @@
pci_fixup: webbrick_pci_fixup,
kill_arch: generic_kill_arch,
};
-/* No alpha_mv alias for webbrick, since we compile it in unconditionally
- with DP264; setup_arch knows how to cope. */
+
+struct alpha_machine_vector clipper_mv __initmv = {
+ vector_name: "Clipper",
+ DO_EV6_MMU,
+ DO_DEFAULT_RTC,
+ DO_TSUNAMI_IO,
+ DO_TSUNAMI_BUS,
+ machine_check: tsunami_machine_check,
+ max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+
+ nr_irqs: 64,
+ irq_probe_mask: _PROBE_MASK(64),
+ update_irq_hw: clipper_update_irq_hw,
+ ack_irq: generic_ack_irq,
+ device_interrupt: dp264_device_interrupt,
+
+ init_arch: tsunami_init_arch,
+ init_irq: clipper_init_irq,
+ init_pit: generic_init_pit,
+ pci_fixup: clipper_pci_fixup,
+ kill_arch: generic_kill_arch,
+};
+
+/* No alpha_mv alias for webbrick/monet/clipper, since we compile them
+ in unconditionally with DP264; setup_arch knows how to cope. */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)