arch/x86: Implement the IRQ allocation and usage interfaces for intel 64

This is the only architecture user for this at the moment.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2021-01-06 15:01:03 +01:00 committed by Carles Cufí
parent b99eaca729
commit 88bac5d0b5

View file

@ -156,3 +156,67 @@ void arch_sched_ipi(void)
z_loapic_ipi(0, LOAPIC_ICR_IPI_OTHERS, CONFIG_SCHED_IPI_VECTOR);
}
#endif
/* The first bit is used to indicate whether the list of reserved interrupts
* have been initialized based on content stored in the irq_alloc linker
* section in ROM.
*/
#define IRQ_LIST_INITIALIZED 0
static ATOMIC_DEFINE(irq_reserved, CONFIG_MAX_IRQ_LINES);
static void irq_init(void)
{
extern uint8_t __irq_alloc_start[];
extern uint8_t __irq_alloc_end[];
const uint8_t *irq;
for (irq = __irq_alloc_start; irq < __irq_alloc_end; irq++) {
__ASSERT_NO_MSG(*irq < CONFIG_MAX_IRQ_LINES);
atomic_set_bit(irq_reserved, *irq);
}
}
unsigned int arch_irq_allocate(void)
{
unsigned int key = irq_lock();
int i;
if (!atomic_test_and_set_bit(irq_reserved, IRQ_LIST_INITIALIZED)) {
irq_init();
}
for (i = 0; i < ARRAY_SIZE(irq_reserved); i++) {
unsigned int fz, irq;
while ((fz = find_lsb_set(~atomic_get(&irq_reserved[i])))) {
irq = (fz - 1) + (i * sizeof(atomic_val_t) * 8);
if (irq >= CONFIG_MAX_IRQ_LINES) {
break;
}
if (!atomic_test_and_set_bit(irq_reserved, irq)) {
irq_unlock(key);
return irq;
}
}
}
irq_unlock(key);
return UINT_MAX;
}
void arch_irq_set_used(unsigned int irq)
{
unsigned int key = irq_lock();
atomic_set_bit(irq_reserved, irq);
irq_unlock(key);
}
bool arch_irq_is_used(unsigned int irq)
{
return atomic_test_bit(irq_reserved, irq);
}