arch/x86: Add a spurious interrupt handler to x86_64

Right now x86_64 doesn't install handlers for vectors that aren't
populated by Zephyr code.  Add a tiny spurious interrupt handler that
logs the error and triggers a fatal error, like other platforms do.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2020-06-16 12:49:54 -07:00 committed by Carles Cufí
commit c7d76cbe58
2 changed files with 23 additions and 5 deletions

View file

@ -10,6 +10,9 @@
#include <drivers/interrupt_controller/sysapic.h>
#include <drivers/interrupt_controller/loapic.h>
#include <irq.h>
#include <logging/log.h>
LOG_MODULE_DECLARE(os);
unsigned char _irq_to_interrupt_vector[CONFIG_MAX_IRQ_LINES];
@ -17,10 +20,6 @@ unsigned char _irq_to_interrupt_vector[CONFIG_MAX_IRQ_LINES];
* The low-level interrupt code consults these arrays to dispatch IRQs, so
* so be sure to keep locore.S up to date with any changes. Note the indices:
* use (vector - IV_IRQS), since exception vectors do not appear here.
*
* Entries which are NULL in x86_irq_funcs[] correspond to unassigned vectors.
* The locore IRQ handler should (read: doesn't currently) raise an exception
* rather than attempt to dispatch to a NULL x86_irq_func[]. FIXME.
*/
#define NR_IRQ_VECTORS (IV_NR_VECTORS - IV_IRQS) /* # vectors free for IRQs */
@ -28,6 +27,20 @@ unsigned char _irq_to_interrupt_vector[CONFIG_MAX_IRQ_LINES];
void (*x86_irq_funcs[NR_IRQ_VECTORS])(void *);
void *x86_irq_args[NR_IRQ_VECTORS];
static void irq_spurious(void *arg)
{
LOG_ERR("Spurious interrupt, vector %d\n", (uint32_t)(uint64_t)arg);
z_fatal_error(K_ERR_SPURIOUS_IRQ, NULL);
}
void x86_64_irq_init(void)
{
for (int i = 0; i < NR_IRQ_VECTORS; i++) {
x86_irq_funcs[i] = irq_spurious;
x86_irq_args[i] = (void *)(long)(i + IV_IRQS);
}
}
/*
* Find a free IRQ vector at the specified priority, or return -1 if none left.
*/
@ -55,7 +68,7 @@ static int allocate_vector(unsigned int priority)
if (vector == Z_X86_OOPS_VECTOR) {
continue;
}
if (x86_irq_funcs[vector - IV_IRQS] == NULL) {
if (x86_irq_funcs[vector - IV_IRQS] == irq_spurious) {
return vector;
}
}

View file

@ -10,6 +10,7 @@
#include <arch/x86/multiboot.h>
extern FUNC_NORETURN void z_cstart(void);
extern void x86_64_irq_init(void);
/* Early global initialization functions, C domain. This runs only on the first
* CPU for SMP systems.
@ -24,6 +25,10 @@ FUNC_NORETURN void z_x86_prep_c(void *arg)
z_x86_early_serial_init();
#endif
#ifdef CONFIG_X86_64
x86_64_irq_init();
#endif
#ifdef CONFIG_MULTIBOOT_INFO
z_multiboot_init(info);
#else