libpayload/x86/exception: Add ability to ignore unknown interrupts

This will make enabling the APIC safer by ignoring unknown interrupts
and not halting the system. Once all interrupt sources have been found
and handled DIE_ON_UNKNOWN_INTERRUPT can be set if desired.

BUG=b:116777191
TEST=Booted grunt, halted the kernel, and pushed the power button while
in S5. Verified that depthcharge logged the unknown exception.

APIC Init Started
APIC Configured
Ignoring interrupt vector 39

Change-Id: If4ed566ec284d69786c369f37e4e331d7f892c74
Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Reviewed-on: https://review.coreboot.org/28882
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Raul E Rangel 2018-10-02 09:45:06 -06:00 committed by Martin Roth
parent 44d89f526d
commit 59e923d757
2 changed files with 32 additions and 3 deletions

View File

@ -37,4 +37,21 @@ config ARCH_SPECIFIC_OPTIONS # dummy
config ENABLE_APIC
bool "Enables the Local APIC"
choice
prompt "Interrupt Handling"
default LOG_UNKNOWN_INTERRUPTS if ENABLE_APIC
default DIE_ON_UNKNOWN_INTERRUPT
config IGNORE_UNKNOWN_INTERRUPTS
bool "Ignore unknown user defined interrupts"
config LOG_UNKNOWN_INTERRUPTS
bool "Logs unknown user defined interrupts to the console"
config DIE_ON_UNKNOWN_INTERRUPT
bool "Die if an unknown user defined interrupt is encountered"
endchoice
endif

View File

@ -171,9 +171,14 @@ void exception_dispatch(void)
if (handlers[vec]) {
handlers[vec](vec);
if (IS_ENABLED(CONFIG_LP_ENABLE_APIC))
apic_eoi(vec);
return;
goto success;
} else if (vec >= EXC_COUNT
&& IS_ENABLED(CONFIG_LP_IGNORE_UNKNOWN_INTERRUPTS)) {
goto success;
} else if (vec >= EXC_COUNT
&& IS_ENABLED(CONFIG_LP_LOG_UNKNOWN_INTERRUPTS)) {
printf("Ignoring interrupt vector %u\n", vec);
goto success;
}
die_if(vec >= EXC_COUNT || !names[vec], "Bad exception vector %u\n",
@ -181,7 +186,14 @@ void exception_dispatch(void)
dump_exception_state();
dump_stack(exception_state->regs.esp, 512);
/* We don't call apic_eoi because we don't want to ack the interrupt and
allow another interrupt to wake the processor. */
halt();
return;
success:
if (IS_ENABLED(CONFIG_LP_ENABLE_APIC))
apic_eoi(vec);
}
void exception_init(void)