summaryrefslogtreecommitdiff
path: root/payloads/libpayload/arch
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2018-10-02 09:45:06 -0600
committerMartin Roth <martinroth@google.com>2018-10-04 15:25:17 +0000
commit59e923d75791bad6980a634f4762d295405c6a07 (patch)
treef7431b16d6dd10076b75b5ea207158c21494c2f4 /payloads/libpayload/arch
parent44d89f526de96322e9dac7b1212f20be10806384 (diff)
downloadcoreboot-59e923d75791bad6980a634f4762d295405c6a07.tar.xz
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>
Diffstat (limited to 'payloads/libpayload/arch')
-rw-r--r--payloads/libpayload/arch/x86/Kconfig17
-rw-r--r--payloads/libpayload/arch/x86/exception.c18
2 files changed, 32 insertions, 3 deletions
diff --git a/payloads/libpayload/arch/x86/Kconfig b/payloads/libpayload/arch/x86/Kconfig
index cbb21cbc14..129ff5f682 100644
--- a/payloads/libpayload/arch/x86/Kconfig
+++ b/payloads/libpayload/arch/x86/Kconfig
@@ -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
diff --git a/payloads/libpayload/arch/x86/exception.c b/payloads/libpayload/arch/x86/exception.c
index 1fa1304f62..983a9f3bd2 100644
--- a/payloads/libpayload/arch/x86/exception.c
+++ b/payloads/libpayload/arch/x86/exception.c
@@ -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)