Subject: re: E250 support?
To: None <eeh@netbsd.org>
From: matthew green <mrg@eterna.com.au>
List: port-sparc64
Date: 02/07/2001 12:36:14
I have a possible fix. Can you build kernels?
actually, eeh and i discussed this and i have a change that should work.
i've tested it on my U5 and i'll upload a GENERIC kernel shortly. once
it is verified to work on the 250, i'll commit to -current.
.mrg.
patch for pci_machdep.c for those interested. it also fixes a bug
where io/mem space weren't (force) enabled for devices without an
"interrupts" property.
Index: pci_machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/dev/pci_machdep.c,v
retrieving revision 1.18
diff -p -r1.18 pci_machdep.c
*** pci_machdep.c 2001/01/19 21:25:19 1.18
--- pci_machdep.c 2001/02/07 01:33:23
*************** pci_attach_hook(parent, self, pba)
*** 85,91 ****
char *name, *devtype;
u_int32_t hi, mid, lo, intr;
u_int32_t dev, fn, bus;
! int node, i, n, *ip, *ap;
DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\npci_attach_hook:"));
--- 85,91 ----
char *name, *devtype;
u_int32_t hi, mid, lo, intr;
u_int32_t dev, fn, bus;
! int node, i, n, real_intr, *ip, *ap;
DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\npci_attach_hook:"));
*************** pci_attach_hook(parent, self, pba)
*** 144,152 ****
/* if there isn't any "interrupts" then we don't care to fix it */
ip = NULL;
if (getprop(node, "interrupts", sizeof(int), &n, (void **)&ip))
! continue;
DPRINTF(SPDB_INTFIX, (" got interrupts"));
!
/* and if there isn't an "assigned-addresses" we can't find b/d/f */
if (getprop(node, "assigned-addresses", sizeof(int), &n,
(void **)&ap))
--- 144,152 ----
/* if there isn't any "interrupts" then we don't care to fix it */
ip = NULL;
if (getprop(node, "interrupts", sizeof(int), &n, (void **)&ip))
! goto enable_iomem;
DPRINTF(SPDB_INTFIX, (" got interrupts"));
!
/* and if there isn't an "assigned-addresses" we can't find b/d/f */
if (getprop(node, "assigned-addresses", sizeof(int), &n,
(void **)&ap))
*************** pci_attach_hook(parent, self, pba)
*** 167,172 ****
--- 167,179 ----
tag = pci_make_tag(pc, bus, dev, fn);
+ /* if "interrupts" <= 4, we must do the fixup, otherwise, it's done */
+ if (*ip > 5) {
+ real_intr = *ip;
+ i = -1;
+ goto found_intr;
+ }
+
DPRINTF(SPDB_INTFIX, ("; tag %08x\n\t; reg: hi %x mid %x lo %x intr %x", tag, pr->phys_hi, pr->phys_mid, pr->phys_lo, *ip));
DPRINTF(SPDB_INTFIX, ("\n\t; intmapmask: hi %x mid %x lo %x intr %x", pp->pp_intmapmask.phys_hi, pp->pp_intmapmask.phys_mid,
pp->pp_intmapmask.phys_lo, pp->pp_intmapmask.intr));
*************** pci_attach_hook(parent, self, pba)
*** 179,229 ****
DPRINTF(SPDB_INTFIX, ("\n\t; after: hi %x mid %x lo %x intr %x", hi, mid, lo, intr));
for (i = 0; i < pp->pp_nintmap; i++) {
! DPRINTF(SPDB_INTFIX, ("\n\t\tmatching for: hi %x mid %x lo %x intr %x", pp->pp_intmap[i].phys_hi, pp->pp_intmap[i].phys_mid,
! pp->pp_intmap[i].phys_lo, pp->pp_intmap[i].intr));
if (pp->pp_intmap[i].phys_hi != hi ||
pp->pp_intmap[i].phys_mid != mid ||
pp->pp_intmap[i].phys_lo != lo ||
! pp->pp_intmap[i].intr != intr)
continue;
! DPRINTF(SPDB_INTFIX, ("... BINGO! ..."));
!
! bingo:
/*
* OK! we found match. pull out the old interrupt
* register, patch in the new value, and put it back.
*/
intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
! DPRINTF(SPDB_INTFIX, ("\n\t ; read %x from intreg", intr));
!
! intr = (intr & ~PCI_INTERRUPT_LINE_MASK) |
! (pp->pp_intmap[i].child_intr & PCI_INTERRUPT_LINE_MASK);
! DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\n\t ; gonna write %x to intreg", intr));
pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
! DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\n\t ; reread %x from intreg", intr));
break;
- }
- if (i == pp->pp_nintmap) {
- /*
- * Not matched by parent interrupt map. If the
- * interrupt property has the INTMAP_OBIO bit
- * set, assume the PROM has (wrongly) supplied it
- * in the parent's bus format, rather than as a
- * PCI interrupt line number.
- *
- * This seems to be an issue only with the
- * psycho host-to-pci bridge.
- */
- if (pp->pp_sc->sc_mode == PSYCHO_MODE_PSYCHO &&
- (*ip & INTMAP_OBIO) != 0) {
- DPRINTF((SPDB_INTFIX|SPDB_INTMAP),
- ("\n\t; PSYCHO: no match but obio interrupt in parent format"));
-
- i = -1; goto bingo; /* XXX - hackish.. */
- }
}
/* enable mem & dma if not already */
pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE|PCI_COMMAND_IO_ENABLE);
--- 186,223 ----
DPRINTF(SPDB_INTFIX, ("\n\t; after: hi %x mid %x lo %x intr %x", hi, mid, lo, intr));
for (i = 0; i < pp->pp_nintmap; i++) {
! DPRINTF(SPDB_INTFIX, ("\n\t\tmatching for: hi %x mid %x lo %x intr %x child_intr %x", pp->pp_intmap[i].phys_hi, pp->pp_intmap[i].phys_mid,
! pp->pp_intmap[i].phys_lo, pp->pp_intmap[i].intr, pp->pp_intmap[i].child_intr));
if (pp->pp_intmap[i].phys_hi != hi ||
pp->pp_intmap[i].phys_mid != mid ||
pp->pp_intmap[i].phys_lo != lo ||
! (pp->pp_intmap[i].intr != intr && pp->pp_intmap[i].child_intr != intr))
continue;
!
! if (pp->pp_intmap[i].child_intr == intr)
! DPRINTF(SPDB_INTFIX, ("... BINGO! found it in child_intr ..."));
! else
! DPRINTF(SPDB_INTFIX, ("... BINGO! found it in intr ..."));
! real_intr = pp->pp_intmap[i].child_intr;
!
! found_intr:
/*
* OK! we found match. pull out the old interrupt
* register, patch in the new value, and put it back.
*/
intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
! DPRINTF(SPDB_INTFIX, ("\t ; read %x from intreg\n", intr));
! intr = (intr & ~PCI_INTERRUPT_LINE_MASK) | (real_intr & PCI_INTERRUPT_LINE_MASK);
! DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\t ; gonna write %x to intreg\n", intr));
pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
! DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\t ; reread %x from intreg\n", intr));
break;
}
+ if (i == pp->pp_nintmap)
+ printf("%s: could not find interrupts vector!", self->dv_xname);
+ enable_iomem:
/* enable mem & dma if not already */
pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE|PCI_COMMAND_IO_ENABLE);