Ejemplo n.º 1
0
void *
pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
    int (*func)(void *), void *arg, char *what)
{
	int pin, irq;
	struct pic *pic;

	pic = &i8259_pic;
	pin = irq = ih;

#if NIOAPIC > 0
	if (ih & APIC_INT_VIA_APIC) {
		pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih));
		if (pic == NULL) {
			printf("pci_intr_establish: bad ioapic %d\n",
			    APIC_IRQ_APIC(ih));
			return NULL;
		}
		pin = APIC_IRQ_PIN(ih);
		irq = APIC_IRQ_LEGACY_IRQ(ih);
		if (irq < 0 || irq >= NUM_LEGACY_IRQS)
			irq = -1;
	}
#endif

	return intr_establish(irq, pic, pin, IST_LEVEL, level, func, arg, what);
}
Ejemplo n.º 2
0
void *
pci_intr_establish_xname(pci_chipset_tag_t pc, pci_intr_handle_t ih,
    int level, int (*func)(void *), void *arg, const char *xname)
{
	int pin, irq;
	struct pic *pic;
#if NIOAPIC > 0
	struct ioapic_softc *ioapic;
#endif
	bool mpsafe;
	pci_chipset_tag_t ipc;

	for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
		if ((ipc->pc_present & PCI_OVERRIDE_INTR_ESTABLISH) == 0)
			continue;
		return (*ipc->pc_ov->ov_intr_establish)(ipc->pc_ctx,
		    pc, ih, level, func, arg);
	}

	if (INT_VIA_MSI(ih)) {
		if (MSI_INT_IS_MSIX(ih))
			return x86_pci_msix_establish(pc, ih, level, func, arg,
			    xname);
		else
			return x86_pci_msi_establish(pc, ih, level, func, arg,
			    xname);
	}

	pic = &i8259_pic;
	pin = irq = APIC_IRQ_LEGACY_IRQ(ih);
	mpsafe = ((ih & MPSAFE_MASK) != 0);

#if NIOAPIC > 0
	if (ih & APIC_INT_VIA_APIC) {
		ioapic = ioapic_find(APIC_IRQ_APIC(ih));
		if (ioapic == NULL) {
			aprint_normal("pci_intr_establish: bad ioapic %d\n",
			    APIC_IRQ_APIC(ih));
			return NULL;
		}
		pic = &ioapic->sc_pic;
		pin = APIC_IRQ_PIN(ih);
		irq = APIC_IRQ_LEGACY_IRQ(ih);
		if (irq < 0 || irq >= NUM_LEGACY_IRQS)
			irq = -1;
	}
#endif

	return intr_establish_xname(irq, pic, pin, IST_LEVEL, level, func, arg,
	    mpsafe, xname);
}
Ejemplo n.º 3
0
void *
pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
    int (*func)(void *), void *arg, const char *what)
{
	int pin, irq;
	int bus, dev;
	pcitag_t tag = ih.tag;
	struct pic *pic;

	if (ih.line & APIC_INT_VIA_MSG) {
		return intr_establish(-1, &msi_pic, tag, IST_PULSE, level,
		    func, arg, what);
	}

	pci_decompose_tag(pc, ih.tag, &bus, &dev, NULL);
#if NACPIPRT > 0
	acpiprt_route_interrupt(bus, dev, ih.pin);
#endif

	pic = &i8259_pic;
	pin = irq = ih.line;

#if NIOAPIC > 0
	if (ih.line & APIC_INT_VIA_APIC) {
		pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih.line));
		if (pic == NULL) {
			printf("pci_intr_establish: bad ioapic %d\n",
			    APIC_IRQ_APIC(ih.line));
			return NULL;
		}
		pin = APIC_IRQ_PIN(ih.line);
		irq = APIC_IRQ_LEGACY_IRQ(ih.line);
		if (irq < 0 || irq >= NUM_LEGACY_IRQS)
			irq = -1;
	}
#endif

	return intr_establish(irq, pic, pin, IST_LEVEL, level, func, arg, what);
}
Ejemplo n.º 4
0
void *
pci_intr_establish(pci_chipset_tag_t pcitag, pci_intr_handle_t intrh,
    int level, int (*func)(void *), void *arg)
{
	char evname[16];
#if NIOAPIC > 0
	struct ioapic_softc *pic;
	if (intrh.pirq & APIC_INT_VIA_APIC) {
		pic = ioapic_find(APIC_IRQ_APIC(intrh.pirq));
		if (pic == NULL) {
			printf("pci_intr_establish: bad ioapic %d\n",
			    APIC_IRQ_APIC(intrh.pirq));
			return NULL;
		}
		snprintf(evname, sizeof(evname), "%s pin %d",
		    device_xname(pic->sc_dev), APIC_IRQ_PIN(intrh.pirq));
	} else
#endif
		snprintf(evname, sizeof(evname), "irq%d", intrh.pirq);

	return (void *)pirq_establish(intrh.pirq & 0xff,
	    intrh.evtch, func, arg, level, evname);
}
Ejemplo n.º 5
0
const char
*pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
{
	static char buf[64];
#if NIOAPIC > 0
	struct ioapic_softc *pic;
	if (ih.pirq & APIC_INT_VIA_APIC) {
		pic = ioapic_find(APIC_IRQ_APIC(ih.pirq));
		if (pic == NULL) {
			printf("pci_intr_string: bad ioapic %d\n",
			    APIC_IRQ_APIC(ih.pirq));
			return NULL;
		}
		snprintf(buf, 64, "%s pin %d, event channel %d",
		    device_xname(pic->sc_dev), APIC_IRQ_PIN(ih.pirq),
		    ih.evtch);
		return buf;
	}
#endif
	snprintf(buf, 64, "irq %d, event channel %d",
	    ih.pirq, ih.evtch);
	return buf;
}
Ejemplo n.º 6
0
void *
isa_intr_establish(isa_chipset_tag_t ic, int irq, int type, int level,
    int (*ih_fun)(void *), void *ih_arg)
{
	struct pic *pic;
	int pin;
#if NIOAPIC > 0
	int mpih;
	struct ioapic_softc *ioapic;
#endif

	pin = irq;
	pic = &i8259_pic;

#if NIOAPIC > 0
	if (mp_busses != NULL) {
		if (intr_find_mpmapping(mp_isa_bus, irq, &mpih) == 0 ||
		    intr_find_mpmapping(mp_eisa_bus, irq, &mpih) == 0) {
			if (!APIC_IRQ_ISLEGACY(mpih)) {
				pin = APIC_IRQ_PIN(mpih);
				ioapic = ioapic_find(APIC_IRQ_APIC(mpih));
				if (ioapic == NULL) {
					printf("isa_intr_establish: "
					       "unknown apic %d\n",
					    APIC_IRQ_APIC(mpih));
					return NULL;
				}
				pic = &ioapic->sc_pic;
			}
		} else
			printf("isa_intr_establish: no MP mapping found\n");
	}
#endif
	return intr_establish(irq, pic, pin, type, level, ih_fun, ih_arg,
	    false);
}
Ejemplo n.º 7
0
/*
 * can't use bus_space_xxx as we don't have a bus handle ...
 */
void 
ioapic_attach(struct device *parent, struct device *self, void *aux)
{
	struct ioapic_softc *sc = (struct ioapic_softc *)self;  
	struct apic_attach_args  *aaa = (struct apic_attach_args  *) aux;
	int apic_id;
	bus_space_handle_t bh;
	u_int32_t ver_sz;
	int i;
	
	sc->sc_flags = aaa->flags;
	sc->sc_apicid = aaa->apic_id;

	printf(" apid %d", aaa->apic_id);

	if (ioapic_find(aaa->apic_id) != NULL) {
		printf(", duplicate apic id (ignored)\n");
		return;
	}

	ioapic_add(sc);

	printf(" pa 0x%lx", aaa->apic_address);

	if (x86_mem_add_mapping(aaa->apic_address, PAGE_SIZE, 0, &bh) != 0) {
		printf(", map failed\n");
		return;
	}
	sc->sc_reg = (volatile u_int32_t *)(bh + IOAPIC_REG);
	sc->sc_data = (volatile u_int32_t *)(bh + IOAPIC_DATA);	

	sc->sc_pic.pic_type = PIC_IOAPIC;
	mtx_init(&sc->sc_pic.pic_mutex, IPL_NONE);
	sc->sc_pic.pic_hwmask = ioapic_hwmask;
	sc->sc_pic.pic_hwunmask = ioapic_hwunmask;
	sc->sc_pic.pic_addroute = ioapic_addroute;
	sc->sc_pic.pic_delroute = ioapic_delroute;
	sc->sc_pic.pic_edge_stubs = ioapic_edge_stubs;
	sc->sc_pic.pic_level_stubs = ioapic_level_stubs;

	ver_sz = ioapic_read(sc, IOAPIC_VER);
	sc->sc_apic_vers = (ver_sz & IOAPIC_VER_MASK) >> IOAPIC_VER_SHIFT;
	sc->sc_apic_sz = (ver_sz & IOAPIC_MAX_MASK) >> IOAPIC_MAX_SHIFT;
	sc->sc_apic_sz++;

	if (aaa->apic_vecbase != -1)
		sc->sc_apic_vecbase = aaa->apic_vecbase;
	else {
		/*
		 * XXX this assumes ordering of ioapics in the table.
		 * Only needed for broken BIOS workaround (see mpbios.c)
		 */
		sc->sc_apic_vecbase = ioapic_vecbase;
		ioapic_vecbase += sc->sc_apic_sz;
	}

	if (mp_verbose) {
		printf(", %s mode",
		    aaa->flags & IOAPIC_PICMODE ? "PIC" : "virtual wire");
	}

	printf(", version %x, %d pins\n", sc->sc_apic_vers, sc->sc_apic_sz);

	apic_id = (ioapic_read(sc, IOAPIC_ID) & IOAPIC_ID_MASK) >>
	    IOAPIC_ID_SHIFT;

	sc->sc_pins = malloc(sizeof(struct ioapic_pin) * sc->sc_apic_sz,
	    M_DEVBUF, M_WAITOK);

	for (i=0; i<sc->sc_apic_sz; i++) {
		sc->sc_pins[i].ip_next = NULL;
		sc->sc_pins[i].ip_map = NULL;
		sc->sc_pins[i].ip_vector = 0;
		sc->sc_pins[i].ip_type = IST_NONE;
	}

	/*
	 * In case the APIC is not initialized to the correct ID
	 * do it now.
	 * Maybe we should record the original ID for interrupt
	 * mapping later ...
	 */
	if (apic_id != sc->sc_apicid) {
		printf("%s: misconfigured as apic %d",
		    sc->sc_pic.pic_dev.dv_xname, apic_id);
		ioapic_set_id(sc);
	}
#if 0
	/* output of this was boring. */
	if (mp_verbose)
		for (i=0; i<sc->sc_apic_sz; i++)
			ioapic_print_redir(sc, "boot", i);
#endif
}