static void ioapic_abi_rman_setup(struct rman *rm) { int start, end, i; KASSERT(rm->rm_cpuid >= 0 && rm->rm_cpuid < MAXCPU, ("invalid rman cpuid %d", rm->rm_cpuid)); start = end = -1; for (i = 0; i < IOAPIC_HWI_VECTORS; ++i) { const struct ioapic_irqmap *map = &ioapic_irqmaps[rm->rm_cpuid][i]; if (start < 0) { if (IOAPIC_IMT_ISHWI(map)) start = end = i; } else { if (IOAPIC_IMT_ISHWI(map)) { end = i; } else { KKASSERT(end >= 0); if (bootverbose) { kprintf("IOAPIC: rman cpu%d %d - %d\n", rm->rm_cpuid, start, end); } if (rman_manage_region(rm, start, end)) { panic("rman_manage_region" "(cpu%d %d - %d)", rm->rm_cpuid, start, end); } start = end = -1; } } } if (start >= 0) { KKASSERT(end >= 0); if (bootverbose) { kprintf("IOAPIC: rman cpu%d %d - %d\n", rm->rm_cpuid, start, end); } if (rman_manage_region(rm, start, end)) { panic("rman_manage_region(cpu%d %d - %d)", rm->rm_cpuid, start, end); } } }
static void ioapic_abi_intr_teardown(int intr) { const struct ioapic_irqmap *map; int vector, select; uint32_t value; register_t ef; KASSERT(intr >= 0 && intr < IOAPIC_HWI_VECTORS, ("ioapic teardown, invalid irq %d\n", intr)); map = &ioapic_irqmaps[mycpuid][intr]; KASSERT(IOAPIC_IMT_ISHWI(map), ("ioapic teardown, not hwi irq %d, type %d, cpu%d", intr, map->im_type, mycpuid)); if (map->im_type != IOAPIC_IMT_LEGACY) return; KASSERT(ioapic_irqs[intr].io_addr != NULL, ("ioapic teardown, no GSI information, irq %d\n", intr)); ef = read_rflags(); cpu_disable_intr(); /* * Teardown an interrupt vector. The vector should already be * installed in the cpu's IDT, but make sure. */ IOAPIC_INTRDIS(intr); vector = IDT_OFFSET + intr; /* * In order to avoid losing an EOI for a level interrupt, which * is vector based, make sure that the IO APIC is programmed for * edge-triggering first, then reprogrammed with the new vector. * This should clear the IRR bit. */ imen_lock(); select = ioapic_irqs[intr].io_idx; value = ioapic_read(ioapic_irqs[intr].io_addr, select); ioapic_write(ioapic_irqs[intr].io_addr, select, (value & ~APIC_TRIGMOD_MASK)); ioapic_write(ioapic_irqs[intr].io_addr, select, (value & ~IOART_INTVEC) | vector); imen_unlock(); write_rflags(ef); }
static void ioapic_abi_intr_setup(int intr, int flags) { const struct ioapic_irqmap *map; int vector, select; uint32_t value; register_t ef; KASSERT(intr >= 0 && intr < IOAPIC_HWI_VECTORS, ("ioapic setup, invalid irq %d", intr)); map = &ioapic_irqmaps[mycpuid][intr]; KASSERT(IOAPIC_IMT_ISHWI(map), ("ioapic setup, not hwi irq %d, type %d, cpu%d", intr, map->im_type, mycpuid)); if (map->im_type != IOAPIC_IMT_LEGACY) return; KASSERT(ioapic_irqs[intr].io_addr != NULL, ("ioapic setup, no GSI information, irq %d", intr)); ef = read_rflags(); cpu_disable_intr(); vector = IDT_OFFSET + intr; /* * Now reprogram the vector in the IO APIC. In order to avoid * losing an EOI for a level interrupt, which is vector based, * make sure that the IO APIC is programmed for edge-triggering * first, then reprogrammed with the new vector. This should * clear the IRR bit. */ imen_lock(); select = ioapic_irqs[intr].io_idx; value = ioapic_read(ioapic_irqs[intr].io_addr, select); value |= IOART_INTMSET; ioapic_write(ioapic_irqs[intr].io_addr, select, (value & ~APIC_TRIGMOD_MASK)); ioapic_write(ioapic_irqs[intr].io_addr, select, (value & ~IOART_INTVEC) | vector); imen_unlock(); IOAPIC_INTREN(intr); write_rflags(ef); }
static void ioapic_abi_intr_disable(int irq) { const struct ioapic_irqmap *map; KASSERT(irq >= 0 && irq < IOAPIC_HWI_VECTORS, ("ioapic disable, invalid irq %d\n", irq)); map = &ioapic_irqmaps[mycpuid][irq]; KASSERT(IOAPIC_IMT_ISHWI(map), ("ioapic disable, not hwi irq %d, type %d, cpu%d\n", irq, map->im_type, mycpuid)); if (map->im_type != IOAPIC_IMT_LEGACY) return; IOAPIC_INTRDIS(irq); }