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:
parent
b7cd0eeaac
commit
f1d2503dc5
@ -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
|
||||
@ -86,7 +86,7 @@ pci_attach_hook(parent, self, pba)
|
||||
struct psycho_registers *pr;
|
||||
pcitag_t tag;
|
||||
char *name, *devtype;
|
||||
u_int32_t hi, mid, lo, intr;
|
||||
u_int32_t hi, mid, lo, intr, line;
|
||||
u_int32_t dev, fn, bus;
|
||||
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].intr != intr)
|
||||
continue;
|
||||
intr = pp->pp_intmap[i].child_intr;
|
||||
DPRINTF(SPDB_INTFIX, ("... BINGO! ..."));
|
||||
|
||||
bingo:
|
||||
@ -197,14 +198,16 @@ pci_attach_hook(parent, self, pba)
|
||||
* 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));
|
||||
line = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
|
||||
DPRINTF(SPDB_INTFIX, ("\n\t ; read %x from intreg", line));
|
||||
|
||||
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));
|
||||
line = PCI_INTERRUPT_CODE(PCI_INTERRUPT_LATENCY(line),
|
||||
PCI_INTERRUPT_GRANT(line),
|
||||
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);
|
||||
DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\n\t ; reread %x from intreg", intr));
|
||||
break;
|
||||
}
|
||||
if (i == pp->pp_nintmap) {
|
||||
@ -223,7 +226,9 @@ pci_attach_hook(parent, self, pba)
|
||||
DPRINTF((SPDB_INTFIX|SPDB_INTMAP),
|
||||
("\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.
|
||||
* XXX: how does this deal with multiple interrupts for a device?
|
||||
*/
|
||||
int
|
||||
pci_intr_map(pa, ihp)
|
||||
struct pci_attach_args *pa;
|
||||
pci_intr_handle_t *ihp;
|
||||
{
|
||||
#if 0
|
||||
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;
|
||||
int rv, pin, line;
|
||||
|
||||
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
|
||||
* 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...
|
||||
*/
|
||||
DPRINTF(SPDB_INTR, ("pci_intr_map: tag %lx; pin %d; line %d",
|
||||
(long)tag, pin, line));
|
||||
#if 1
|
||||
if (line == 255) {
|
||||
DPRINTF(SPDB_INTR, ("pci_intr_map: tag %lx; line %d",
|
||||
(long)pa->pa_intrtag, line));
|
||||
|
||||
if (line >= 0x40) {
|
||||
*ihp = -1;
|
||||
rv = 1;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
if (pin > 4)
|
||||
panic("pci_intr_map: pin > 4");
|
||||
|
||||
rv = psycho_intr_map(tag, pin, line, ihp);
|
||||
|
||||
(*ihp) = line & 0x3f;
|
||||
rv = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -479,11 +483,11 @@ pci_intr_string(pc, ih)
|
||||
static char str[16];
|
||||
|
||||
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 */
|
||||
panic("pci_intr_string: bogus handle\n");
|
||||
}
|
||||
sprintf(str, "vector %u", ih);
|
||||
sprintf(str, "ipl %u", ih);
|
||||
DPRINTF(SPDB_INTR, ("; returning %s\n", str));
|
||||
|
||||
return (str);
|
||||
|
@ -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
|
||||
@ -196,10 +196,8 @@ psycho_attach(parent, self, aux)
|
||||
sabre_init(sc, ma, &pba);
|
||||
else if (strcmp(model, ROM_PSYCHO_MODEL) == 0)
|
||||
psycho_init(sc, ma, &pba);
|
||||
#ifdef DIAGNOSTIC
|
||||
else
|
||||
panic("psycho_attach: unknown model %s?", model);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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_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 */
|
||||
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 */
|
||||
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 |
|
||||
PCICTL_ARB_PARK |
|
||||
PCICTL_ERRINTEN |
|
||||
@ -454,12 +454,10 @@ psycho_init(sc, ma, pba)
|
||||
pci_ctl = (struct pci_ctl *)(u_long)ma->ma_address[0];
|
||||
|
||||
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_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
|
||||
@ -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 2, INTA#/B#/C#/D# */
|
||||
0, 0, 0, 0, /* PCI B, Slot 3, INTA#/B#/C#/D# */
|
||||
|
||||
PIL_SCSI, /* SCSI */
|
||||
PIL_NET, /* Ethernet */
|
||||
3, /* Parallel */
|
||||
PIL_AUD, /* Audio Record */
|
||||
|
||||
PIL_AUD, /* Audio Playback */
|
||||
14, /* Power Fail */
|
||||
4, /* Keyboard/Mouse/Serial */
|
||||
PIL_FD, /* Floppy */
|
||||
|
||||
14, /* Thermal Warning */
|
||||
PIL_SER, /* Keyboard */
|
||||
PIL_SER, /* Mouse */
|
||||
PIL_SER, /* Serial */
|
||||
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
14, /* Uncorrectable ECC error */
|
||||
14, /* Correctable ECC error */
|
||||
|
||||
14, /* PCI A bus error */
|
||||
14, /* PCI B bus error */
|
||||
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
|
||||
*/
|
||||
@ -953,7 +940,7 @@ psycho_intr_establish(t, ihandle, level, flags, handler, arg)
|
||||
if (ih == 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);
|
||||
DPRINTF(PDB_INTR, (" ino %x", ino));
|
||||
if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) == 0) {
|
||||
@ -1027,6 +1014,8 @@ psycho_intr_establish(t, ihandle, level, flags, handler, arg)
|
||||
*/
|
||||
if (level != IPL_NONE)
|
||||
ih->ih_pil = level;
|
||||
else if (ino > (sizeof(pci_ino_to_ipl_table) / sizeof(int)))
|
||||
ih->ih_pil = 0;
|
||||
else
|
||||
ih->ih_pil = pci_ino_to_ipl_table[ino];
|
||||
|
||||
|
@ -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
|
||||
@ -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_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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user