int apic_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) { pci_chipset_tag_t pc = pa->pa_pc; struct elroy_softc *sc = pc->_cookie; pcitag_t tag = pa->pa_tag; hppa_hpa_t hpa = cpu_gethpa(0); pcireg_t reg; reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); printf(" pin=%d line=%d ", PCI_INTERRUPT_PIN(reg), PCI_INTERRUPT_LINE(reg)); apic_write(sc->sc_regs, APIC_ENT0(PCI_INTERRUPT_PIN(reg)), PCI_INTERRUPT_LINE(reg)); apic_write(sc->sc_regs, APIC_ENT1(PCI_INTERRUPT_PIN(reg)), ((hpa & 0x0ff00000) >> 4) | ((hpa & 0x000ff000) << 12)); *ihp = PCI_INTERRUPT_LINE(reg) + 1; return (*ihp == 0); }
void * apic_intr_establish(void *v, pci_intr_handle_t ih, int pri, int (*handler)(void *), void *arg, const char *name) { struct elroy_softc *sc = v; volatile struct elroy_regs *r = sc->sc_regs; hppa_hpa_t hpa = cpu_gethpa(0); struct evcount *cnt; struct apic_iv *aiv, *biv; void *iv; int irq = APIC_INT_IRQ(ih); int line = APIC_INT_LINE(ih); u_int32_t ent0; /* no mapping or bogus */ if (irq <= 0 || irq > 63) return (NULL); aiv = malloc(sizeof(struct apic_iv), M_DEVBUF, M_NOWAIT); if (aiv == NULL) { free(cnt, M_DEVBUF, 0); return NULL; } aiv->sc = sc; aiv->ih = ih; aiv->handler = handler; aiv->arg = arg; aiv->next = NULL; aiv->cnt = NULL; if (apic_intr_list[irq]) { cnt = malloc(sizeof(struct evcount), M_DEVBUF, M_NOWAIT); if (!cnt) { free(aiv, M_DEVBUF, 0); return (NULL); } evcount_attach(cnt, name, NULL); biv = apic_intr_list[irq]; while (biv->next) biv = biv->next; biv->next = aiv; aiv->cnt = cnt; return (arg); } if ((iv = cpu_intr_establish(pri, irq, apic_intr, aiv, name))) { ent0 = (63 - irq) & APIC_ENT0_VEC; ent0 |= apic_get_int_ent0(sc, line); #if 0 if (cold) { sc->sc_imr |= (1 << irq); ent0 |= APIC_ENT0_MASK; } #endif apic_write(sc->sc_regs, APIC_ENT0(line), APIC_ENT0_MASK); apic_write(sc->sc_regs, APIC_ENT1(line), ((hpa & 0x0ff00000) >> 4) | ((hpa & 0x000ff000) << 12)); apic_write(sc->sc_regs, APIC_ENT0(line), ent0); /* Signal EOI. */ elroy_write32(&r->apic_eoi, htole32((63 - irq) & APIC_ENT0_VEC)); apic_intr_list[irq] = aiv; }