summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2012-04-15 20:44:53 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2012-04-15 20:44:53 +0000
commit93068738255cbd031018f80458b82b1fd3de9d20 (patch)
treef26369f77231724b2fd98595f4256d234ed5a6ed
parentaff35ecb8eedf9fb6b8ce71c3e1ad582bac54500 (diff)
Define symbolic constants for the interrupt controller pin assignments on
IP20, IP22 and IP24, and provide the necessary macros to compute interrupt vectors numbers (from the int.c point of view) from given sources.
-rw-r--r--sys/arch/sgi/gio/gio.c21
-rw-r--r--sys/arch/sgi/localbus/int.c89
-rw-r--r--sys/arch/sgi/localbus/intreg.h57
-rw-r--r--sys/arch/sgi/sgi/eisa_machdep.c6
4 files changed, 120 insertions, 53 deletions
diff --git a/sys/arch/sgi/gio/gio.c b/sys/arch/sgi/gio/gio.c
index b201adab5b9..b8b31b6be2b 100644
--- a/sys/arch/sgi/gio/gio.c
+++ b/sys/arch/sgi/gio/gio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gio.c,v 1.1 2012/03/28 20:44:23 miod Exp $ */
+/* $OpenBSD: gio.c,v 1.2 2012/04/15 20:44:51 miod Exp $ */
/* $NetBSD: gio.c,v 1.32 2011/07/01 18:53:46 dyoung Exp $ */
/*
@@ -47,6 +47,7 @@
#include <sgi/gio/giodevs_data.h>
#include <sgi/localbus/imcvar.h>
+#include <sgi/localbus/intreg.h>
#include <sgi/localbus/intvar.h>
#include <sgi/sgi/ip22.h>
@@ -468,10 +469,15 @@ gio_arb_config(int slot, uint32_t flags)
}
/*
- * Establish an interrupt handler for the specified slot.
+ * Establish an interrupt handler for expansion boards (not frame buffers!)
+ * in the specified slot.
*
- * Indy and Challenge S have an interrupt per GIO slot. Indigo and Indigo2
- * share a single interrupt, however.
+ * Indy and Challenge S have a single GIO interrupt per GIO slot, but
+ * distinct slot interrups. Indigo and Indigo2 have three GIO interrupts per
+ * slot, but at a given GIO interrupt level, all slots share the same
+ * interrupt on the interrupt controller.
+ *
+ * Expansion boards appear to always use the intermediate level.
*/
void *
gio_intr_establish(int slot, int level, int (*func)(void *), void *arg,
@@ -483,7 +489,7 @@ gio_intr_establish(int slot, int level, int (*func)(void *), void *arg,
case SGI_IP20:
if (slot == GIO_SLOT_GFX)
return NULL;
- intr = 6;
+ intr = INT2_L0_INTR(INT2_L0_GIO_LVL1);
break;
case SGI_IP22:
case SGI_IP26:
@@ -491,11 +497,12 @@ gio_intr_establish(int slot, int level, int (*func)(void *), void *arg,
if (sys_config.system_subtype == IP22_INDIGO2) {
if (slot == GIO_SLOT_EXP1)
return NULL;
- intr = 6;
+ intr = INT2_L0_INTR(INT2_L0_GIO_LVL1);
} else {
if (slot == GIO_SLOT_GFX)
return NULL;
- intr = (slot == GIO_SLOT_EXP0) ? 22 : 23;
+ intr = INT2_MAP1_INTR(slot == GIO_SLOT_EXP0 ?
+ INT2_MAP_GIO_SLOT0 : INT2_MAP_GIO_SLOT1);
}
break;
default:
diff --git a/sys/arch/sgi/localbus/int.c b/sys/arch/sgi/localbus/int.c
index 01e8b2a5dde..e521bce3c69 100644
--- a/sys/arch/sgi/localbus/int.c
+++ b/sys/arch/sgi/localbus/int.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: int.c,v 1.1 2012/03/28 20:44:23 miod Exp $ */
+/* $OpenBSD: int.c,v 1.2 2012/04/15 20:44:52 miod Exp $ */
/* $NetBSD: int.c,v 1.24 2011/07/01 18:53:46 dyoung Exp $ */
/*
@@ -30,7 +30,7 @@
*/
/*
- * INT2 (IP20, IP22) /INT3 (IP24) interrupt controllers
+ * INT2 (IP20, IP22) / INT3 (IP24) interrupt controllers
*/
#include <sys/param.h>
@@ -66,6 +66,7 @@ struct cfdriver int_cd = {
};
paddr_t int2_base;
+paddr_t int2_get_base(void);
#define int2_read(r) *(volatile uint8_t *)(int2_base + (r))
#define int2_write(r, v) *(volatile uint8_t *)(int2_base + (r)) = (v)
@@ -167,6 +168,9 @@ int2_intr_establish(int irq, int level, int (*ih_fun) (void *),
#ifdef DIAGNOSTIC
if (irq < 0 || irq >= INT2_NINTS)
panic("int2_intr_establish: illegal irq %d", irq);
+ /* Mappable interrupts can't be above IPL_TTY */
+ if ((irq >> 3) >= 2 && level > IPL_TTY)
+ return NULL;
#endif
ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
@@ -200,12 +204,12 @@ int2_intr_establish(int irq, int level, int (*ih_fun) (void *),
* masked as a whole, by the level 0 or 1 interrupt they cascade to.
*/
case 2:
- int2_write(INT2_MAP_MASK0,
- int2_read(INT2_MAP_MASK0) | (1 << (irq & 7)));
+ int2_write(INT2_IP22_MAP_MASK0,
+ int2_read(INT2_IP22_MAP_MASK0) | (1 << (irq & 7)));
break;
case 3:
- int2_write(INT2_MAP_MASK1,
- int2_read(INT2_MAP_MASK1) | (1 << (irq & 7)));
+ int2_write(INT2_IP22_MAP_MASK1,
+ int2_read(INT2_IP22_MAP_MASK1) | (1 << (irq & 7)));
break;
}
@@ -241,13 +245,15 @@ int
int2_mappable_intr(void *arg)
{
uint which = (unsigned long)arg;
+ vaddr_t imrreg;
uint64_t imr, isr;
uint i, intnum;
struct intrhand *ih;
int rc, ret;
- isr = int2_read(INT2_MAP_STATUS);
- imr = int2_read(INT2_MAP_MASK0 + (which << 2));
+ imrreg = which == 0 ? INT2_IP22_MAP_MASK0 : INT2_IP22_MAP_MASK1;
+ isr = int2_read(INT2_IP22_MAP_STATUS);
+ imr = int2_read(imrreg);
isr &= imr;
if (isr == 0)
@@ -259,7 +265,6 @@ int2_mappable_intr(void *arg)
* is registered at IPL_TTY, so we can safely assume we are running
* at IPL_TTY now.
*/
-
for (i = 0; i < 8; i++) {
intnum = i + 16 + (which << 3);
if (isr & (1 << i)) {
@@ -305,31 +310,16 @@ int2_match(struct device *parent, void *match, void *aux)
void
int2_attach(struct device *parent, struct device *self, void *aux)
{
- uint32_t address;
-
- switch (sys_config.system_type) {
- case SGI_IP20:
- address = INT2_IP20;
- break;
- default:
- case SGI_IP22:
- case SGI_IP26:
- case SGI_IP28:
- if (sys_config.system_subtype == IP22_INDIGO2)
- address = INT2_IP22;
- else
- address = INT2_IP24;
- break;
- }
+ if (int2_base == 0)
+ int2_base = int2_get_base();
- printf(" addr 0x%x\n", address);
- int2_base = PHYS_TO_XKPHYS((uint64_t)address, CCA_NC);
+ printf(" addr 0x%x\n", XKPHYS_TO_PHYS(int2_base));
/* Clean out interrupt masks */
int2_write(INT2_LOCAL0_MASK, 0);
int2_write(INT2_LOCAL1_MASK, 0);
- int2_write(INT2_MAP_MASK0, 0);
- int2_write(INT2_MAP_MASK1, 0);
+ int2_write(INT2_IP22_MAP_MASK0, 0);
+ int2_write(INT2_IP22_MAP_MASK1, 0);
/* Reset timer interrupts */
int2_write(INT2_TIMER_CONTROL,
@@ -347,12 +337,35 @@ int2_attach(struct device *parent, struct device *self, void *aux)
register_splx_handler(int2_splx);
if (sys_config.system_type != SGI_IP20) {
- /* Wire interrupts 7, 11 to mappable interrupt 0,1 handlers */
- int2_intr_establish(7, IPL_TTY, int2_mappable_intr,
- (void *)0, NULL);
- int2_intr_establish(8 + 3, IPL_TTY, int2_mappable_intr,
- (void *)1, NULL);
+ /* Wire mappable interrupt handlers */
+ int2_intr_establish(INT2_L0_INTR(INT2_L0_IP22_MAP0), IPL_TTY,
+ int2_mappable_intr, (void *)0, NULL);
+ int2_intr_establish(INT2_L1_INTR(INT2_L1_IP22_MAP1), IPL_TTY,
+ int2_mappable_intr, (void *)1, NULL);
+ }
+}
+
+paddr_t
+int2_get_base(void)
+{
+ uint32_t address;
+
+ switch (sys_config.system_type) {
+ case SGI_IP20:
+ address = INT2_IP20;
+ break;
+ default:
+ case SGI_IP22:
+ case SGI_IP26:
+ case SGI_IP28:
+ if (sys_config.system_subtype == IP22_INDIGO2)
+ address = INT2_IP22;
+ else
+ address = INT2_IP24;
+ break;
}
+
+ return PHYS_TO_XKPHYS((uint64_t)address, CCA_NC);
}
/*
@@ -362,8 +375,8 @@ void
int2_wait_fifo(uint32_t flag)
{
if (int2_base == 0)
- delay(5000); /* XXX */
- else
- while (int2_read(INT2_LOCAL0_STATUS) & flag)
- ;
+ int2_base = int2_get_base();
+
+ while (int2_read(INT2_LOCAL0_STATUS) & flag)
+ ;
}
diff --git a/sys/arch/sgi/localbus/intreg.h b/sys/arch/sgi/localbus/intreg.h
index c6deca4e933..c06b4df8c02 100644
--- a/sys/arch/sgi/localbus/intreg.h
+++ b/sys/arch/sgi/localbus/intreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intreg.h,v 1.1 2012/03/28 20:44:23 miod Exp $ */
+/* $OpenBSD: intreg.h,v 1.2 2012/04/15 20:44:52 miod Exp $ */
/* $NetBSD: int2reg.h,v 1.5 2009/02/12 06:33:57 rumble Exp $ */
/*
@@ -39,13 +39,60 @@
#define INT2_LOCAL0_MASK 0x07
#define INT2_LOCAL1_STATUS 0x0b
#define INT2_LOCAL1_MASK 0x0f
-#define INT2_MAP_STATUS 0x13
-#define INT2_MAP_MASK0 0x17
-#define INT2_MAP_MASK1 0x1b
-#define INT2_MAP_POL 0x1f
+#define INT2_IP22_MAP_STATUS 0x13
+#define INT2_IP22_MAP_MASK0 0x17
+#define INT2_IP22_MAP_MASK1 0x1b
+#define INT2_IP22_MAP_POL 0x1f
+#define INT2_IP20_LED 0x1f
#define INT2_TIMER_CLEAR 0x23
#define INT2_ERROR_STATUS 0x27
#define INT2_TIMER_0 0x33
#define INT2_TIMER_1 0x37
#define INT2_TIMER_2 0x3b
#define INT2_TIMER_CONTROL 0x3f
+
+/* LOCAL0 bits */
+#define INT2_L0_FIFO 0
+#define INT2_L0_GIO_SLOT0 0 /* IP24 */
+#define INT2_L0_GIO_LVL0 0 /* IP20/IP22 */
+#define INT2_L0_IP20_PARALLEL 1
+#define INT2_L0_IP22_SCSI0 1
+#define INT2_L0_SCSI1 2
+#define INT2_L0_ENET 3
+#define INT2_L0_GFX_DMA 4
+#define INT2_L0_IP20_SERIAL 5
+#define INT2_L0_IP22_PARALLEL 5
+#define INT2_L0_GIO_LVL1 6 /* IP20/IP22 */
+#define INT2_L0_IP20_VME0 7
+#define INT2_L0_IP22_MAP0 7
+
+/* LOCAL1 bits */
+#define INT2_L1_IP24_ISDN_ISAC 0
+#define INT2_L1_IP20_GR1MODE 1 /* not an interrupt but a status bit */
+#define INT2_L1_IP22_PANEL 1
+#define INT2_L1_IP24_ISDN_HSCX 2
+#define INT2_L1_IP20_VME1 3
+#define INT2_L1_IP22_MAP1 3
+#define INT2_L1_IP20_DSP 4
+#define INT2_L1_IP22_HPC_DMA 4
+#define INT2_L1_ACFAIL 5
+#define INT2_L1_VIDEO 6
+#define INT2_L1_RETRACE 7
+#define INT2_L1_GIO_LVL2 7 /* IP20/IP22 */
+
+/* MAP bits */
+#define INT2_MAP_NEWPORT 0 /* IP24 */
+#define INT2_MAP_PASSWD 1
+#define INT2_MAP_ISDN_POWER 2 /* IP24 */
+#define INT2_MAP_EISA 3 /* IP22 */
+#define INT2_MAP_PCKBC 4
+#define INT2_MAP_SERIAL 5
+#define INT2_MAP_GFX0_DRAIN 6 /* IP22 */
+#define INT2_MAP_GIO_SLOT0 6 /* IP24 */
+#define INT2_MAP_GFX1_DRAIN 7 /* IP22 */
+#define INT2_MAP_GIO_SLOT1 7 /* IP24 */
+
+#define INT2_L0_INTR(x) ((x) + 0)
+#define INT2_L1_INTR(x) ((x) + 8)
+#define INT2_MAP0_INTR(x) ((x) + 16)
+#define INT2_MAP1_INTR(x) ((x) + 24)
diff --git a/sys/arch/sgi/sgi/eisa_machdep.c b/sys/arch/sgi/sgi/eisa_machdep.c
index d7286ee268c..4da23e87680 100644
--- a/sys/arch/sgi/sgi/eisa_machdep.c
+++ b/sys/arch/sgi/sgi/eisa_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: eisa_machdep.c,v 1.1 2012/04/02 20:40:52 miod Exp $ */
+/* $OpenBSD: eisa_machdep.c,v 1.2 2012/04/15 20:44:52 miod Exp $ */
/*
* Copyright (c) 2012 Miodrag Vallat.
@@ -23,6 +23,7 @@
#include <sys/queue.h>
#include <machine/bus.h>
+#include <sgi/localbus/intreg.h>
#include <sgi/localbus/intvar.h>
#include <dev/ic/i8259reg.h>
@@ -57,7 +58,7 @@ int eisa_intr(void *);
#define eisa_io_write(o,v) \
*(volatile uint8_t *)PHYS_TO_XKPHYS(EISA_IO_BASE | (o), CCA_NC) = (v)
-#define EISA_INT2_IRQNO (24 + 3) /* Mapped interrupt #3 */
+#define EISA_INT2_IRQNO INT2_MAP1_INTR(INT2_MAP_EISA)
/*
* EISA interrupt handlers.
@@ -99,7 +100,6 @@ eisa_intr_string(eisa_chipset_tag_t ec, eisa_intr_handle_t ih)
snprintf(irqstr, sizeof irqstr, "eisa irq %d", ih);
return irqstr;
-
}
void *