rework pci_attach_hook() to just deal with the INO, not the full

interrupt number.  properly find interrupts for the E250.  modify
pci_intr_map() accordingly.  retire psycho_intr_map().  deal with
INO values upto 0x3f, not upto 0x32.  restructure sabre_init() and
psycho_init() to be more similar, and display each psycho's IGN.
psycho_intr_establish() deals with INO upto 0x3f, values from 0x32
and higher get 0 for IPL.

tested on E250 & U5.
This commit is contained in:
mrg 2001-03-06 08:09:16 +00:00
parent b7cd0eeaac
commit f1d2503dc5
3 changed files with 48 additions and 57 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pci_machdep.c,v 1.19 2001/03/02 06:34:06 mrg Exp $ */ /* $NetBSD: pci_machdep.c,v 1.20 2001/03/06 08:09:16 mrg Exp $ */
/* /*
* Copyright (c) 1999, 2000 Matthew R. Green * Copyright (c) 1999, 2000 Matthew R. Green
@ -86,7 +86,7 @@ pci_attach_hook(parent, self, pba)
struct psycho_registers *pr; struct psycho_registers *pr;
pcitag_t tag; pcitag_t tag;
char *name, *devtype; char *name, *devtype;
u_int32_t hi, mid, lo, intr; u_int32_t hi, mid, lo, intr, line;
u_int32_t dev, fn, bus; u_int32_t dev, fn, bus;
int node, i, n, *ip, *ap; int node, i, n, *ip, *ap;
@ -190,6 +190,7 @@ pci_attach_hook(parent, self, pba)
pp->pp_intmap[i].phys_lo != lo || pp->pp_intmap[i].phys_lo != lo ||
pp->pp_intmap[i].intr != intr) pp->pp_intmap[i].intr != intr)
continue; continue;
intr = pp->pp_intmap[i].child_intr;
DPRINTF(SPDB_INTFIX, ("... BINGO! ...")); DPRINTF(SPDB_INTFIX, ("... BINGO! ..."));
bingo: bingo:
@ -197,14 +198,16 @@ pci_attach_hook(parent, self, pba)
* OK! we found match. pull out the old interrupt * OK! we found match. pull out the old interrupt
* register, patch in the new value, and put it back. * register, patch in the new value, and put it back.
*/ */
intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); line = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
DPRINTF(SPDB_INTFIX, ("\n\t ; read %x from intreg", intr)); DPRINTF(SPDB_INTFIX, ("\n\t ; read %x from intreg", line));
intr = (intr & ~PCI_INTERRUPT_LINE_MASK) | line = PCI_INTERRUPT_CODE(PCI_INTERRUPT_LATENCY(line),
(pp->pp_intmap[i].child_intr & PCI_INTERRUPT_LINE_MASK); PCI_INTERRUPT_GRANT(line),
DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\n\t ; gonna write %x to intreg", intr)); PCI_INTERRUPT_PIN(line),
PCI_INTERRUPT_LINE(intr));
DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\n\t ; gonna write %x to intreg", line));
pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr); pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\n\t ; reread %x from intreg", intr));
break; break;
} }
if (i == pp->pp_nintmap) { if (i == pp->pp_nintmap) {
@ -223,7 +226,9 @@ pci_attach_hook(parent, self, pba)
DPRINTF((SPDB_INTFIX|SPDB_INTMAP), DPRINTF((SPDB_INTFIX|SPDB_INTMAP),
("\n\t; PSYCHO: no match but obio interrupt in parent format")); ("\n\t; PSYCHO: no match but obio interrupt in parent format"));
i = -1; goto bingo; /* XXX - hackish.. */ intr = *ip;
i = -1;
goto bingo; /* hackish */
} }
} }
@ -433,41 +438,40 @@ pci_conf_write(pc, tag, reg, data)
/* /*
* interrupt mapping foo. * interrupt mapping foo.
* XXX: how does this deal with multiple interrupts for a device?
*/ */
int int
pci_intr_map(pa, ihp) pci_intr_map(pa, ihp)
struct pci_attach_args *pa; struct pci_attach_args *pa;
pci_intr_handle_t *ihp; pci_intr_handle_t *ihp;
{ {
#if 0 int rv, pin, line;
pci_chipset_tag_t pc = pa->pa_pc;
#endif
pcitag_t tag = pa->pa_intrtag;
int pin = pa->pa_intrpin;
int line = pa->pa_intrline;
int rv;
pin = pa->pa_intrpin;
line = pa->pa_intrline;
DPRINTF(SPDB_INTMAP, ("pci_intr_map: dev %u fn %u: ", pa->pa_device,
pa->pa_function));
/* /*
* XXX * XXX
* UltraSPARC IIi PCI does not use PCI_INTERRUPT_REG, but we have * UltraSPARC PCI does not use PCI_INTERRUPT_REG, but we have
* used this space for our own purposes... * used this space for our own purposes...
*/ */
DPRINTF(SPDB_INTR, ("pci_intr_map: tag %lx; pin %d; line %d", DPRINTF(SPDB_INTR, ("pci_intr_map: tag %lx; line %d",
(long)tag, pin, line)); (long)pa->pa_intrtag, line));
#if 1
if (line == 255) { if (line >= 0x40) {
*ihp = -1; *ihp = -1;
rv = 1; rv = 1;
goto out; goto out;
} }
#endif
if (pin > 4) if (pin > 4)
panic("pci_intr_map: pin > 4"); panic("pci_intr_map: pin > 4");
rv = psycho_intr_map(tag, pin, line, ihp); (*ihp) = line & 0x3f;
rv = 0;
out: out:
DPRINTF(SPDB_INTR, ("; handle = %d; returning %d\n", (int)*ihp, rv)); DPRINTF(SPDB_INTR, ("; handle = %x; returning %d\n", (u_int)*ihp, rv));
return (rv); return (rv);
} }
@ -479,11 +483,11 @@ pci_intr_string(pc, ih)
static char str[16]; static char str[16];
DPRINTF(SPDB_INTR, ("pci_intr_string: ih %u", ih)); DPRINTF(SPDB_INTR, ("pci_intr_string: ih %u", ih));
if (ih < 0 || ih > 0x32) { if (ih < 0 || ih >= 0x40) {
printf("\n"); /* i'm *so* beautiful */ printf("\n"); /* i'm *so* beautiful */
panic("pci_intr_string: bogus handle\n"); panic("pci_intr_string: bogus handle\n");
} }
sprintf(str, "vector %u", ih); sprintf(str, "ipl %u", ih);
DPRINTF(SPDB_INTR, ("; returning %s\n", str)); DPRINTF(SPDB_INTR, ("; returning %s\n", str));
return (str); return (str);

View File

@ -1,4 +1,4 @@
/* $NetBSD: psycho.c,v 1.30 2001/02/28 15:21:08 mrg Exp $ */ /* $NetBSD: psycho.c,v 1.31 2001/03/06 08:09:16 mrg Exp $ */
/* /*
* Copyright (c) 1999, 2000 Matthew R. Green * Copyright (c) 1999, 2000 Matthew R. Green
@ -196,10 +196,8 @@ psycho_attach(parent, self, aux)
sabre_init(sc, ma, &pba); sabre_init(sc, ma, &pba);
else if (strcmp(model, ROM_PSYCHO_MODEL) == 0) else if (strcmp(model, ROM_PSYCHO_MODEL) == 0)
psycho_init(sc, ma, &pba); psycho_init(sc, ma, &pba);
#ifdef DIAGNOSTIC
else else
panic("psycho_attach: unknown model %s?", model); panic("psycho_attach: unknown model %s?", model);
#endif
/* /*
* attach the pci.. note we pass PCI A tags, etc., for the sabre here. * attach the pci.. note we pass PCI A tags, etc., for the sabre here.
@ -254,13 +252,15 @@ sabre_init(sc, ma, pba)
sc->sc_basepaddr = (paddr_t)ma->ma_reg[0].ur_paddr; sc->sc_basepaddr = (paddr_t)ma->ma_reg[0].ur_paddr;
sc->sc_ign = 0x7c0; /* APB IGN is always 0x7c */ sc->sc_ign = 0x7c0; /* APB IGN is always 0x7c */
csr = sc->sc_regs->psy_csr;
/* csr = bus_space_read_8(sc->sc_bustag, (bus_space_handle_t)(u_long)
&sc->sc_regs->psy_pcictl[0].pci_csr, 0); */
/* who? said a voice, incredulous */ /* who? said a voice, incredulous */
sc->sc_mode = PSYCHO_MODE_SABRE; sc->sc_mode = PSYCHO_MODE_SABRE;
printf("sabre: "); printf("sabre: ign %x ", sc->sc_ign);
/* setup the PCI control register; there is only one for the sabre */ /* setup the PCI control register; there is only one for the sabre */
csr = bus_space_read_8(sc->sc_bustag, (bus_space_handle_t)(u_long)
&sc->sc_regs->psy_pcictl[0].pci_csr, 0);
csr |= PCICTL_MRLM | csr |= PCICTL_MRLM |
PCICTL_ARB_PARK | PCICTL_ARB_PARK |
PCICTL_ERRINTEN | PCICTL_ERRINTEN |
@ -454,12 +454,10 @@ psycho_init(sc, ma, pba)
pci_ctl = (struct pci_ctl *)(u_long)ma->ma_address[0]; pci_ctl = (struct pci_ctl *)(u_long)ma->ma_address[0];
csr = sc->sc_regs->psy_csr; csr = sc->sc_regs->psy_csr;
printf("psycho: impl %d, version %d: ",
PSYCHO_GCSR_IMPL(csr), PSYCHO_GCSR_VERS(csr) );
sc->sc_ign = PSYCHO_GCSR_IGN(csr) << 6; sc->sc_ign = PSYCHO_GCSR_IGN(csr) << 6;
sc->sc_mode = PSYCHO_MODE_PSYCHO; sc->sc_mode = PSYCHO_MODE_PSYCHO;
printf("psycho: impl %d, version %d: ign %x ",
PSYCHO_GCSR_IMPL(csr), PSYCHO_GCSR_VERS(csr), sc->sc_ign);
/* /*
* Match other psycho's that are already configured against * Match other psycho's that are already configured against
@ -893,43 +891,32 @@ static int pci_ino_to_ipl_table[] = {
0, 0, 0, 0, /* PCI B, Slot 1, INTA#/B#/C#/D# */ 0, 0, 0, 0, /* PCI B, Slot 1, INTA#/B#/C#/D# */
0, 0, 0, 0, /* PCI B, Slot 2, INTA#/B#/C#/D# */ 0, 0, 0, 0, /* PCI B, Slot 2, INTA#/B#/C#/D# */
0, 0, 0, 0, /* PCI B, Slot 3, INTA#/B#/C#/D# */ 0, 0, 0, 0, /* PCI B, Slot 3, INTA#/B#/C#/D# */
PIL_SCSI, /* SCSI */ PIL_SCSI, /* SCSI */
PIL_NET, /* Ethernet */ PIL_NET, /* Ethernet */
3, /* Parallel */ 3, /* Parallel */
PIL_AUD, /* Audio Record */ PIL_AUD, /* Audio Record */
PIL_AUD, /* Audio Playback */ PIL_AUD, /* Audio Playback */
14, /* Power Fail */ 14, /* Power Fail */
4, /* Keyboard/Mouse/Serial */ 4, /* Keyboard/Mouse/Serial */
PIL_FD, /* Floppy */ PIL_FD, /* Floppy */
14, /* Thermal Warning */ 14, /* Thermal Warning */
PIL_SER, /* Keyboard */ PIL_SER, /* Keyboard */
PIL_SER, /* Mouse */ PIL_SER, /* Mouse */
PIL_SER, /* Serial */ PIL_SER, /* Serial */
0, /* Reserved */ 0, /* Reserved */
0, /* Reserved */ 0, /* Reserved */
14, /* Uncorrectable ECC error */ 14, /* Uncorrectable ECC error */
14, /* Correctable ECC error */ 14, /* Correctable ECC error */
14, /* PCI A bus error */ 14, /* PCI A bus error */
14, /* PCI B bus error */ 14, /* PCI B bus error */
14, /* power management */ 14, /* power management */
}; };
int
psycho_intr_map(tag, pin, line, ihp)
pcitag_t tag;
int pin;
int line;
pci_intr_handle_t *ihp;
{
if (line < 0 || line > 0x32)
panic("psycho_intr_map: line %d line < 0 || line > 0x32", line);
/* UltraSPARC IIi does not use this register, but we have set it */
(*ihp) = line;
return (0);
}
/* /*
* install an interrupt handler for a PCI device * install an interrupt handler for a PCI device
*/ */
@ -953,7 +940,7 @@ psycho_intr_establish(t, ihandle, level, flags, handler, arg)
if (ih == NULL) if (ih == NULL)
return (NULL); return (NULL);
DPRINTF(PDB_INTR, ("\npsycho_intr_establish: ihandle %x", ihandle)); DPRINTF(PDB_INTR, ("\npsycho_intr_establish: ihandle %x vec %lx", ihandle, vec));
ino = INTINO(vec); ino = INTINO(vec);
DPRINTF(PDB_INTR, (" ino %x", ino)); DPRINTF(PDB_INTR, (" ino %x", ino));
if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) == 0) { if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) == 0) {
@ -1027,6 +1014,8 @@ psycho_intr_establish(t, ihandle, level, flags, handler, arg)
*/ */
if (level != IPL_NONE) if (level != IPL_NONE)
ih->ih_pil = level; ih->ih_pil = level;
else if (ino > (sizeof(pci_ino_to_ipl_table) / sizeof(int)))
ih->ih_pil = 0;
else else
ih->ih_pil = pci_ino_to_ipl_table[ino]; ih->ih_pil = pci_ino_to_ipl_table[ino];

View File

@ -1,4 +1,4 @@
/* $NetBSD: psychovar.h,v 1.4 2000/07/18 11:35:03 pk Exp $ */ /* $NetBSD: psychovar.h,v 1.5 2001/03/06 08:09:17 mrg Exp $ */
/* /*
* Copyright (c) 1999, 2000 Matthew R. Green * Copyright (c) 1999, 2000 Matthew R. Green
@ -121,6 +121,4 @@ bus_space_tag_t psycho_alloc_bus_tag __P((struct psycho_pbm *, int));
#define psycho_alloc_mem_tag(pp) psycho_alloc_bus_tag((pp), PCI_MEMORY_BUS_SPACE) #define psycho_alloc_mem_tag(pp) psycho_alloc_bus_tag((pp), PCI_MEMORY_BUS_SPACE)
#define psycho_alloc_io_tag(pp) psycho_alloc_bus_tag((pp), PCI_IO_BUS_SPACE) #define psycho_alloc_io_tag(pp) psycho_alloc_bus_tag((pp), PCI_IO_BUS_SPACE)
int psycho_intr_map __P((pcitag_t, int, int, pci_intr_handle_t *));
#endif /* _SPARC64_DEV_PSYCHOVAR_H_ */ #endif /* _SPARC64_DEV_PSYCHOVAR_H_ */