summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2020-06-24 00:40:54 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2020-06-24 00:40:54 +0000
commit22013c7690c45d0c592fa9612211bd4d1264d394 (patch)
treea2c120793520a17682c49d07a1091ecf22b21acf
parent9150d9795e6d2707bfa8afa8f84852af0e13b73e (diff)
remove ifdeffed out code for redistributing pyro eq interrupts over cpus.
when sparc64 attaches cpus early during boot, it really just allocates the software state for them (ie, the devices and the cpu_info structs) and fills them in with information from openfirmware, but it doesnt actually spin them up in a physical sense until just before root is mounted. in between that, we now set up pyro with an msi event queue per cpu, and target the interrupts for those event queues at the different cpus. if a device generates an msi interrupt before the cpus are spun up, pyro will fire an interrupt at those cpus, but cos they're not running yet, they don't handle the interrupt, and the event queue never gets processed. because the msi interrupt state is never cleared by the pyro interrupt handler because the cpu didn't run it, any further msi interrupts from that pci device don't cause the eq interrupt to fire again, so it gets stuck. one approach to dealing with this is to target all the event queues that pyro sets up at the boot cpu, and once the other cpus are running we go through and retarget the event queue interrupts at the different cpus. this means the boot cpu works on the other cpus behalf until they're running, and it avoids the eq interrupts being ignored before the other cpus are running. another approach is to spin the cpus up when they're attached, so they'll be set up to process early pyro interrupts, even if they sit at splhigh until after autoconf has run. i had a quick go at this and it didn't go well. the approach we went with was to avoid having the device in question generate interrupts early. i left the redistributing code in the tree so people might discover it if needed, or at least see this description of what's happening. kettenis@ seemed ok with leaving the code in jmatthew@s pci_intr_establish_cpu commit, but removing it after. this is that removal.
-rw-r--r--sys/arch/sparc64/dev/pyro.c76
1 files changed, 1 insertions, 75 deletions
diff --git a/sys/arch/sparc64/dev/pyro.c b/sys/arch/sparc64/dev/pyro.c
index 4881f8d5514..96e66b029e4 100644
--- a/sys/arch/sparc64/dev/pyro.c
+++ b/sys/arch/sparc64/dev/pyro.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pyro.c,v 1.34 2020/06/23 01:21:29 jmatthew Exp $ */
+/* $OpenBSD: pyro.c,v 1.35 2020/06/24 00:40:53 dlg Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -105,9 +105,6 @@ void pyro_attach(struct device *, struct device *, void *);
void pyro_init(struct pyro_softc *, int);
void pyro_init_iommu(struct pyro_softc *, struct pyro_pbm *);
void pyro_init_msi(struct pyro_softc *, struct pyro_pbm *);
-#if 0
-void pyro_redistribute_msi(struct device *);
-#endif
int pyro_print(void *, const char *);
pci_chipset_tag_t pyro_alloc_chipset(struct pyro_pbm *, int,
@@ -258,9 +255,6 @@ pyro_init(struct pyro_softc *sc, int busa)
pbm->pp_cfgt = pyro_alloc_config_tag(pbm);
pbm->pp_dmat = pyro_alloc_dma_tag(pbm);
-#if 0
- sc->sc_pbm = pbm;
-#endif
pyro_init_msi(sc, pbm);
if (bus_space_map(pbm->pp_cfgt, 0, 0x10000000, 0, &pbm->pp_cfgh))
@@ -432,80 +426,12 @@ pyro_init_msi(struct pyro_softc *sc, struct pyro_pbm *pbm)
pbm->pp_flags |= PCI_FLAGS_MSI_ENABLED;
-#if 0
- /*
- * XXX some devices may interrupt before a cpu has hatched,
- * so rather than have their interrupts get dropped because
- * the other cpu isn't running, point the interrupts at the
- * boot cpu and redistribute them later on. this assumes that
- * only msi and msix interrupts get targetted to other CPUs,
- * so only the msi eqs need to be redistributed.
- */
- config_mountroot(&sc->sc_dv, pyro_redistribute_msi);
-#endif
-
return;
free_table:
free(pbm->pp_msi, M_DEVBUF, 0);
}
-#if 0
-void
-pyro_redistribute_msi(struct device *dev)
-{
- struct pyro_softc *sc = (struct pyro_softc *)dev;
- struct pyro_pbm *pbm = sc->sc_pbm;
- struct pyro_eq *eq;
- struct cpu_info *ci;
- CPU_INFO_ITERATOR cii;
- uint64_t map, clr;
- int i;
-
- CPU_INFO_FOREACH(cii, ci) {
- unsigned int unit = CPU_INFO_UNIT(ci);
- struct intrhand *ih;
-
- eq = &pbm->pp_eq[unit];
- ih = eq->eq_ih;
-
- map = bus_space_read_8(sc->sc_bust, sc->sc_csrh,
- FIRE_INTR_MAP(eq->eq_intr));
- CLR(map, INTMAP_V);
- bus_space_write_8(sc->sc_bust, sc->sc_csrh,
- FIRE_INTR_MAP(eq->eq_intr), map);
-
- /* wait for pending to clear */
- for (i = 0; i < 10000; i++) {
- clr = bus_space_read_8(sc->sc_bust, sc->sc_csrh,
- FIRE_INTR_CLR(eq->eq_intr));
- clr &= 0x3;
- if (clr != 0x3)
- break;
-
- delay(10000);
- }
-
- if (clr == 0x3) {
- panic("%s: unable to clear pending state on eq %u",
- sc->sc_dv.dv_xname, eq->eq_id);
- }
-
- if (sc->sc_oberon) {
- CLR(map, OBERON_INTRMAP_T_DESTID_MASK);
- SET(map, ci->ci_upaid << OBERON_INTRMAP_T_DESTID_SHIFT);
- } else {
- CLR(map, FIRE_INTRMAP_T_JPID_MASK);
- SET(map, ci->ci_upaid << FIRE_INTRMAP_T_JPID_SHIFT);
- }
- SET(map, INTMAP_V);
-
- bus_space_write_8(sc->sc_bust, sc->sc_csrh,
- FIRE_INTR_MAP(eq->eq_intr), map);
- }
-}
-#endif
-
int
pyro_print(void *aux, const char *p)
{