Exemplo n.º 1
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);
}
Exemplo n.º 2
0
int
pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
	pci_intr_pin_t pin = pa->pa_intrpin;
	pci_intr_line_t line = pa->pa_intrline;
	pci_chipset_tag_t ipc, pc = pa->pa_pc;
#if NIOAPIC > 0 || NACPICA > 0
	pci_intr_pin_t rawpin = pa->pa_rawintrpin;
	int bus, dev, func;
#endif

	for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
		if ((ipc->pc_present & PCI_OVERRIDE_INTR_MAP) == 0)
			continue;
		return (*ipc->pc_ov->ov_intr_map)(ipc->pc_ctx, pa, ihp);
	}

	if (pin == 0) {
		/* No IRQ used. */
		goto bad;
	}

	*ihp = 0;

	if (pin > PCI_INTERRUPT_PIN_MAX) {
		aprint_normal("pci_intr_map: bad interrupt pin %d\n", pin);
		goto bad;
	}

#if NIOAPIC > 0 || NACPICA > 0
	KASSERT(rawpin >= PCI_INTERRUPT_PIN_A);
	KASSERT(rawpin <= PCI_INTERRUPT_PIN_D);
	pci_decompose_tag(pc, pa->pa_tag, &bus, &dev, &func);
	if (mp_busses != NULL) {
		/*
		 * Note: PCI_INTERRUPT_PIN_A == 1 where intr_find_mpmapping
		 * wants pci bus_pin encoding which uses INT_A == 0.
		 */
		if (intr_find_mpmapping(bus,
		    (dev << 2) | (rawpin - PCI_INTERRUPT_PIN_A), ihp) == 0) {
			if (APIC_IRQ_LEGACY_IRQ(*ihp) == 0)
				*ihp |= line;
			return 0;
		}
		/*
		 * No explicit PCI mapping found. This is not fatal,
		 * we'll try the ISA (or possibly EISA) mappings next.
		 */
	}
#endif

	/*
	 * Section 6.2.4, `Miscellaneous Functions', says that 255 means
	 * `unknown' or `no connection' on a PC.  We assume that a device with
	 * `no connection' either doesn't have an interrupt (in which case the
	 * pin number should be 0, and would have been noticed above), or
	 * wasn't configured by the BIOS (in which case we punt, since there's
	 * no real way we can know how the interrupt lines are mapped in the
	 * hardware).
	 *
	 * XXX
	 * Since IRQ 0 is only used by the clock, and we can't actually be sure
	 * that the BIOS did its job, we also recognize that as meaning that
	 * the BIOS has not configured the device.
	 */
	if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) {
		aprint_normal("pci_intr_map: no mapping for pin %c (line=%02x)\n",
		       '@' + pin, line);
		goto bad;
	} else {
		if (line >= NUM_LEGACY_IRQS) {
			aprint_normal("pci_intr_map: bad interrupt line %d\n", line);
			goto bad;
		}
		if (line == 2) {
			aprint_normal("pci_intr_map: changed line 2 to line 9\n");
			line = 9;
		}
	}
#if NIOAPIC > 0 || NACPICA > 0
	if (mp_busses != NULL) {
		if (intr_find_mpmapping(mp_isa_bus, line, ihp) == 0) {
			if ((*ihp & 0xff) == 0)
				*ihp |= line;
			return 0;
		}
#if NEISA > 0
		if (intr_find_mpmapping(mp_eisa_bus, line, ihp) == 0) {
			if ((*ihp & 0xff) == 0)
				*ihp |= line;
			return 0;
		}
#endif
		aprint_normal("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n",
		    bus, dev, func, pin, line);
		aprint_normal("pci_intr_map: no MP mapping found\n");
	}
#endif

	*ihp = line;
	return 0;

bad:
	*ihp = -1;
	return 1;
}
Exemplo n.º 3
0
int
pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
	int pin;
	int line;

#if NIOAPIC > 0
	int rawpin = pa->pa_rawintrpin;
	pci_chipset_tag_t pc = pa->pa_pc;
	int bus, dev, func;
#endif

	pin = pa->pa_intrpin;
	line = pa->pa_intrline;
#if 0 /* XXXX why is it always 0 ? */
	if (pin == 0) {
		/* No IRQ used */
		goto bad;
	}
#endif
	if (pin > PCI_INTERRUPT_PIN_MAX) {
		printf("pci_intr_map: bad interrupt pin %d\n", pin);
		goto bad;
	}
	ihp->pirq = 0;

#if NIOAPIC > 0
	pci_decompose_tag(pc, pa->pa_tag, &bus, &dev, &func);
	if (mp_busses != NULL) {
		if (intr_find_mpmapping(bus, (dev<<2)|(rawpin-1), ihp) == 0) {
			if (ihp->pirq & APIC_INT_VIA_APIC) {
				/* make sure a new IRQ will be allocated */
				ihp->pirq &= ~0xff;
			} else {
				ihp->pirq |= line;
			}
			goto end;
		}
		/*
		 * No explicit PCI mapping found. This is not fatal,
		 * we'll try the ISA (or possibly EISA) mappings next.
		 */
	}
#endif

	if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) {
		printf("pci_intr_map: no mapping for pin %c (line=%02x)\n",
		    '@' + pin, line);
		goto bad;
	}
#ifdef DOM0OPS
	if (line >= NUM_LEGACY_IRQS) {
		printf("pci_intr_map: bad interrupt line %d\n", line);
		goto bad;
	}
#endif
	if (line == 2) {
		printf("pci_intr_map: changed line 2 to line 9\n");
		line = 9;
	}
#if NIOAPIC > 0
	if (mp_busses != NULL) {
		if (intr_find_mpmapping(mp_isa_bus, line, ihp) == 0) {
			if ((ihp->pirq & 0xff) == 0)
				ihp->pirq |= line;
			goto end;
		}
		printf("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n",
		    bus, dev, func, pin, line);
		printf("pci_intr_map: no MP mapping found\n");
	}
#endif /* NIOAPIC */

	ihp->pirq = line;

#if NIOAPIC > 0
end:
#endif
	ihp->evtch = xen_intr_map(&ihp->pirq, IST_LEVEL);
	if (ihp->evtch == -1)
		goto bad;

	return 0;

bad:
	ihp->pirq = -1;
	ihp->evtch = -1;
	return 1;
}
Exemplo n.º 4
0
int
pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
	int pin = pa->pa_intrpin;
	int line = pa->pa_intrline;
#if NIOAPIC > 0
	int rawpin = pa->pa_rawintrpin;
	pci_chipset_tag_t pc = pa->pa_pc;
	int bus, dev, func;
	int mppin;
#endif

	if (pin == 0) {
		/* No IRQ used. */
		goto bad;
	}

	if (pin > PCI_INTERRUPT_PIN_MAX) {
		printf("pci_intr_map: bad interrupt pin %d\n", pin);
		goto bad;
	}

#if NIOAPIC > 0
	pci_decompose_tag(pc, pa->pa_tag, &bus, &dev, &func);
	if (mp_busses != NULL) {
		mppin = (dev << 2)|(rawpin - 1);
		if (intr_find_mpmapping(bus, mppin, ihp) == 0) {
			*ihp |= line;
			return 0;
		}
		if (pa->pa_bridgetag) {
			int bridgebus, bridgedev;

			pci_decompose_tag(pc, *pa->pa_bridgetag,
			    &bridgebus, &bridgedev, NULL);
			mppin = (bridgedev << 2)|((rawpin + dev - 1) & 0x3);
			if (intr_find_mpmapping(bridgebus, mppin, ihp) == 0) {
				*ihp |= line;
				return 0;
			}
		}
		/*
		 * No explicit PCI mapping found. This is not fatal,
		 * we'll try the ISA (or possibly EISA) mappings next.
		 */
	}
#endif

	/*
	 * Section 6.2.4, `Miscellaneous Functions', says that 255 means
	 * `unknown' or `no connection' on a PC.  We assume that a device with
	 * `no connection' either doesn't have an interrupt (in which case the
	 * pin number should be 0, and would have been noticed above), or
	 * wasn't configured by the BIOS (in which case we punt, since there's
	 * no real way we can know how the interrupt lines are mapped in the
	 * hardware).
	 *
	 * XXX
	 * Since IRQ 0 is only used by the clock, and we can't actually be sure
	 * that the BIOS did its job, we also recognize that as meaning that
	 * the BIOS has not configured the device.
	 */
	if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) {
		printf("pci_intr_map: no mapping for pin %c (line=%02x)\n",
		       '@' + pin, line);
		goto bad;
	} else {
		if (line >= NUM_LEGACY_IRQS) {
			printf("pci_intr_map: bad interrupt line %d\n", line);
			goto bad;
		}
		if (line == 2) {
			printf("pci_intr_map: changed line 2 to line 9\n");
			line = 9;
		}
	}
#if NIOAPIC > 0
	if (mp_busses != NULL) {
		if (mp_isa_bus != NULL &&
		    intr_find_mpmapping(mp_isa_bus->mb_idx, line, ihp) == 0) {
			*ihp |= line;
			return 0;
		}
#if NEISA > 0
		if (mp_eisa_bus != NULL &&
		    intr_find_mpmapping(mp_eisa_bus->mb_idx, line, ihp) == 0) {
			*ihp |= line;
			return 0;
		}
#endif
		printf("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n",
		    bus, dev, func, pin, line);
		printf("pci_intr_map: no MP mapping found\n");
	}
#endif

	*ihp = line;
	return 0;

bad:
	*ihp = -1;
	return 1;
}