diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c index c8f60f0..cfb27bf 100644 --- a/sys/amd64/amd64/local_apic.c +++ b/sys/amd64/amd64/local_apic.c @@ -908,6 +908,42 @@ apic_alloc_vector(u_int apic_id, u_int irq) return (0); } +/* Request a free IDT vector to be used by the specified IRQ. */ +u_int +apic_alloc_vector_broadcast(u_int irq) +{ + u_int apic_id; + u_int vector; + + KASSERT(irq < NUM_IO_INTS, ("Invalid IRQ %u", irq)); + + /* + * Search for a free vector. Currently we just use a very simple + * algorithm to find the first free vector. + */ + mtx_lock_spin(&icu_lock); + for (vector = 0; vector < APIC_NUM_IOINTS; vector++) { + for (apic_id = 0; apic_id < LVT_MAX; apic_id++) { + if (!lapics[apic_id].la_present) + continue; + if (lapics[apic_id].la_ioint_irqs[vector] != -1) + break; + } + if (apic_id < LVT_MAX) + continue; + for (apic_id = 0; apic_id < LVT_MAX; apic_id++) { + if (!lapics[apic_id].la_present) + continue; + lapics[apic_id].la_ioint_irqs[vector] = irq; + } + mtx_unlock_spin(&icu_lock); + printf("apic_alloc_vector_broadcast: vector %u for irq %u\n", + vector + APIC_IO_INTS, irq); + return (vector + APIC_IO_INTS); + } + mtx_unlock_spin(&icu_lock); + return (0); +} /* * Request 'count' free contiguous IDT vectors to be used by 'count' * IRQs. 'count' must be a power of two and the vectors will be diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h index 91bba99..7093692 100644 --- a/sys/amd64/include/apicvar.h +++ b/sys/amd64/include/apicvar.h @@ -186,6 +186,7 @@ extern vm_paddr_t lapic_paddr; extern int apic_cpuids[]; u_int apic_alloc_vector(u_int apic_id, u_int irq); +u_int apic_alloc_vector_broadcast(u_int irq); u_int apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align); void apic_disable_vector(u_int apic_id, u_int vector);