Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/macppc/macppc do what freebsd does:
details: https://anonhg.NetBSD.org/src/rev/3711b74bfcac
branches: trunk
changeset: 356872:3711b74bfcac
user: macallan <macallan%NetBSD.org@localhost>
date: Wed Oct 18 12:55:14 2017 +0000
description:
do what freebsd does:
- when disabling an interrupt, disable it on the HT PIC as well
- when establishing an interrupt, don't enable it right away
- program IRQs 0-3 as level, like freebsd does
Now svwsata is almost usable. We still get an interrupt storm but it doesn't
eat up all CPU cycles anymore.
diffstat:
sys/arch/macppc/macppc/pic_u3_ht.c | 48 ++++++++++++++++++++++++++++++++++---
1 files changed, 44 insertions(+), 4 deletions(-)
diffs (124 lines):
diff -r 55771e14491e -r 3711b74bfcac sys/arch/macppc/macppc/pic_u3_ht.c
--- a/sys/arch/macppc/macppc/pic_u3_ht.c Wed Oct 18 10:43:32 2017 +0000
+++ b/sys/arch/macppc/macppc/pic_u3_ht.c Wed Oct 18 12:55:14 2017 +0000
@@ -43,6 +43,12 @@
#include <machine/autoconf.h>
#include <arch/powerpc/pic/picvar.h>
+#ifdef U3_HT_PIC_DEPUG
+#define DPRINTF aprint_error
+#else
+#define DPRINTF if (0) printf
+#endif
+
struct u3_ht_irqmap {
int im_index;
int im_level;
@@ -78,6 +84,7 @@
static int u3_ht_is_ht_irq(struct u3_ht_ops *, int);
static void u3_ht_establish_ht_irq(struct u3_ht_ops *, int, int);
static void u3_ht_enable_ht_irq(struct u3_ht_ops *, int);
+static void u3_ht_disable_ht_irq(struct u3_ht_ops *, int);
static void u3_ht_ack_ht_irq(struct u3_ht_ops *, int);
static void u3_ht_set_priority(struct u3_ht_ops *, int, int);
@@ -206,7 +213,7 @@
u3_ht_set_priority(u3_ht, 0, 15);
- for (irq = 0; irq < pic->pic_numintrs; irq++) {
+ for (irq = 0; irq < 4; irq++) {
x = irq;
x |= OPENPIC_IMASK;
x |= OPENPIC_POLARITY_NEGATIVE;
@@ -215,6 +222,15 @@
u3_ht_write(u3_ht, OPENPIC_SRC_VECTOR(irq), x);
u3_ht_write(u3_ht, OPENPIC_IDEST(irq), 1 << 0);
}
+ for (irq = 4; irq < pic->pic_numintrs; irq++) {
+ x = irq;
+ x |= OPENPIC_IMASK;
+ x |= OPENPIC_POLARITY_NEGATIVE;
+ x |= OPENPIC_SENSE_EDGE;
+ x |= 8 << OPENPIC_PRIORITY_SHIFT;
+ u3_ht_write(u3_ht, OPENPIC_SRC_VECTOR(irq), x);
+ u3_ht_write(u3_ht, OPENPIC_IDEST(irq), 1 << 0);
+ }
x = u3_ht_read(u3_ht, OPENPIC_CONFIG);
x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
@@ -253,6 +269,8 @@
ht_reg = mapiodev(reg[1], reg[2], false);
KASSERT(ht_reg != NULL);
+ memset(irqmap, 0, sizeof(u3_ht->ht_irqmap));
+
for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
if (OF_getprop(child, "reg", reg, 4) != 4)
continue;
@@ -284,6 +302,8 @@
nirq = in32rb(base + 0x04);
nirq = (nirq >> 16) & 0xff;
+ DPRINTF("dev %08x nirq %d pos %08x\n", (uint32_t)base, nirq, (uint32_t)pos);
+ DPRINTF("devreg %08x\n", in32rb(dev_reg + PCI_ID_REG));
for (i = 0; i <= nirq; i++) {
out8rb(base + 0x02, 0x10 + (i << 1));
tmp = in32rb(base + 0x04);
@@ -333,6 +353,9 @@
x = u3_ht_read(u3_ht, OPENPIC_SRC_VECTOR(irq));
x |= OPENPIC_IMASK;
u3_ht_write(u3_ht, OPENPIC_SRC_VECTOR(irq), x);
+
+ if (u3_ht_is_ht_irq(u3_ht, irq))
+ u3_ht_disable_ht_irq(u3_ht, irq);
}
static int
@@ -385,8 +408,8 @@
if (u3_ht_is_ht_irq(u3_ht, irq))
u3_ht_establish_ht_irq(u3_ht, irq, type);
- aprint_debug("%s: setting IRQ %d to priority %d\n", __func__, irq,
- realpri);
+ aprint_error("%s: setting IRQ %d %d to priority %d %x\n", __func__, irq,
+ type, realpri, x);
}
static void
@@ -422,10 +445,15 @@
out8rb(irqmap->im_base + 0x02, 0x10 + (irqmap->im_index << 1));
x = in32rb(irqmap->im_base + 0x04);
- x &= ~0x23;
+ /* mask interrupt */
+ out32rb(irqmap->im_base + 0x04, x | 1);
+
+ /* mask out EOI and LEVEL bits */
+ x &= ~0x22;
if (type == IST_LEVEL_HIGH || type == IST_LEVEL_LOW) {
irqmap->im_level = 1;
+ DPRINTF("level\n");
x |= 0x22;
} else {
irqmap->im_level = 0;
@@ -449,6 +477,18 @@
}
static void
+u3_ht_disable_ht_irq(struct u3_ht_ops *u3_ht, int irq)
+{
+ struct u3_ht_irqmap *irqmap = &u3_ht->ht_irqmap[irq];
+ u_int x;
+
+ out8rb(irqmap->im_base + 0x02, 0x10 + (irqmap->im_index << 1));
+ x = in32rb(irqmap->im_base + 0x04);
+ x |= 0x01;
+ out32rb(irqmap->im_base + 0x04, x);
+}
+
+static void
u3_ht_ack_ht_irq(struct u3_ht_ops *u3_ht, int irq)
{
struct u3_ht_irqmap *irqmap = &u3_ht->ht_irqmap[irq];
Home |
Main Index |
Thread Index |
Old Index