diff options
author | Jack Rosenthal <jrosenth@chromium.org> | 2019-06-17 15:37:55 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-06-19 00:51:23 +0000 |
commit | 7e80ddc5177af46cc8defc2741f4e9590b97cbbb (patch) | |
tree | 811bd2fb95e3190c956bae2e8ff7dd0a2181fa8e | |
parent | 247b6099f910c3e1685b9185371177ac61a32617 (diff) | |
download | chrome-ec-7e80ddc5177af46cc8defc2741f4e9590b97cbbb.tar.gz |
minute-ia: load eip value from top of stack
For interrupt vectors (as opposed to exception handlers), the eip
value is on top of the stack (referentially the return address by C
calling convention). Use separate code for WDT vector.
BUG=b:129983997
BRANCH=none
TEST='crash watchdog' showing correct EIP, CS values
Change-Id: I7efb2c71aba63eefd89fc71af089bc14034b7d08
Signed-off-by: Jack Rosenthal <jrosenth@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1663188
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Reviewed-by: Yuval Peress <peress@chromium.org>
-rw-r--r-- | chip/ish/config_chip.h | 4 | ||||
-rw-r--r-- | core/minute-ia/interrupts.c | 28 | ||||
-rw-r--r-- | core/minute-ia/mia_panic_internal.h | 17 | ||||
-rw-r--r-- | core/minute-ia/panic.c | 10 | ||||
-rw-r--r-- | include/config.h | 3 |
5 files changed, 51 insertions, 11 deletions
diff --git a/chip/ish/config_chip.h b/chip/ish/config_chip.h index d27effdd72..e6b1b52050 100644 --- a/chip/ish/config_chip.h +++ b/chip/ish/config_chip.h @@ -100,6 +100,10 @@ #error "CHIP_FAMILY_ISH(3|4|5) must be defined" #endif +/* Provide WDT vec number to Minute-IA core implementation */ +#undef CONFIG_MIA_WDT_VEC +#define CONFIG_MIA_WDT_VEC ISH_WDT_VEC + /****************************************************************************/ /* Customize the build */ /* Optional features present on this chip */ diff --git a/core/minute-ia/interrupts.c b/core/minute-ia/interrupts.c index 275dba1e9d..1d87dba77a 100644 --- a/core/minute-ia/interrupts.c +++ b/core/minute-ia/interrupts.c @@ -12,6 +12,7 @@ #include "interrupts.h" #include "irq_handler.h" #include "link_defs.h" +#include "mia_panic_internal.h" #include "registers.h" #include "task.h" #include "task_defs.h" @@ -176,11 +177,9 @@ static const irq_desc_t system_irqs[] = { */ #define DEFINE_EXN_HANDLER(vector) \ _DEFINE_EXN_HANDLER(vector, exception_panic_##vector) -#define _DEFINE_EXN_HANDLER(vector, name) \ - __DEFINE_EXN_HANDLER(vector, name) -#define __DEFINE_EXN_HANDLER(vector, name) \ +#define _DEFINE_EXN_HANDLER(vector, name) \ void __keep name(void); \ - __attribute__ ((noreturn)) void name(void) \ + __attribute__((noreturn)) void name(void) \ { \ __asm__ ( \ "push $" #vector "\n" \ @@ -209,7 +208,22 @@ DEFINE_EXN_HANDLER(17); DEFINE_EXN_HANDLER(18); DEFINE_EXN_HANDLER(19); DEFINE_EXN_HANDLER(20); -_DEFINE_EXN_HANDLER(ISH_WDT_VEC, exception_panic_wdt); + +/** + * Use a similar approach for defining an optional handler for + * watchdog timer expiration. However, this time, hardware does not + * push errorcode, and we must account for that by pushing zero. + */ +__attribute__((noreturn)) __keep +void exception_panic_wdt(uint32_t cs) +{ + exception_panic( + CONFIG_MIA_WDT_VEC, + 0, + (uint32_t)__builtin_return_address(0), + cs, + 0); +} void set_interrupt_gate(uint8_t num, isr_handler_t func, uint8_t flags) { @@ -475,8 +489,8 @@ void init_interrupts(void) * retrieve EIP. */ if (IS_ENABLED(CONFIG_WATCHDOG)) - set_interrupt_gate(ISH_WDT_VEC, - exception_panic_wdt, + set_interrupt_gate(CONFIG_MIA_WDT_VEC, + (isr_handler_t)exception_panic_wdt, IDT_DESC_FLAGS); /* Note: At reset, ID field is already set to 0 in APIC ID register */ diff --git a/core/minute-ia/mia_panic_internal.h b/core/minute-ia/mia_panic_internal.h new file mode 100644 index 0000000000..e4d3aa0cdd --- /dev/null +++ b/core/minute-ia/mia_panic_internal.h @@ -0,0 +1,17 @@ +/* Copyright 2019 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * Handle an exception and reboot. The parameters after 'vector' are + * convenientely in the same order as pushed by hardwared during a + * processor exception. + */ +__attribute__((noreturn)) +void exception_panic( + uint32_t vector, + uint32_t errorcode, + uint32_t eip, + uint32_t cs, + uint32_t eflags); diff --git a/core/minute-ia/panic.c b/core/minute-ia/panic.c index 464d25ec52..cbdabc3eec 100644 --- a/core/minute-ia/panic.c +++ b/core/minute-ia/panic.c @@ -7,6 +7,7 @@ #include "console.h" #include "cpu.h" #include "host_command.h" +#include "mia_panic_internal.h" #include "panic.h" #include "printf.h" #include "software_panic.h" @@ -90,7 +91,7 @@ void panic_data_print(const struct panic_data *pdata) * order pushed to the stack by hardware: see "Intel 64 and IA-32 * Architectures Software Developer's Manual", Volume 3A, Figure 6-4. */ -__attribute__((noreturn)) void __keep exception_panic( +void exception_panic( uint32_t vector, uint32_t error_code, uint32_t eip, @@ -121,10 +122,11 @@ __attribute__((noreturn)) void __keep exception_panic( PANIC_DATA_PTR->x86.edi = edi; /* - * Convert ISH_WDT_VEC to be a SW Watchdog. This is for - * code that is in system_common_pre_init + * Convert watchdog timer vector number to be a SW + * Watchdog. This is for code that is in + * system_common_pre_init */ - if (vector == ISH_WDT_VEC) + if (IS_ENABLED(CONFIG_WATCHDOG) && vector == CONFIG_MIA_WDT_VEC) vector = PANIC_SW_WATCHDOG; /* Save stack data to global panic structure */ diff --git a/include/config.h b/include/config.h index a8ff3ea27b..9351502ed3 100644 --- a/include/config.h +++ b/include/config.h @@ -2632,6 +2632,9 @@ /* Define clock input to MFT module. */ #undef CONFIG_MFT_INPUT_LFCLK +/* Minute-IA watchdog timer vector number. */ +#define CONFIG_MIA_WDT_VEC 0xFF + /* Support MKBP event */ #undef CONFIG_MKBP_EVENT |