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
|
* 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);
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
@ -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_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user