diff --git a/src/drivers/intel/fsp2_0/Kconfig.debug_blob b/src/drivers/intel/fsp2_0/Kconfig.debug_blob index 14f502c4d6..e9e6053c64 100644 --- a/src/drivers/intel/fsp2_0/Kconfig.debug_blob +++ b/src/drivers/intel/fsp2_0/Kconfig.debug_blob @@ -45,4 +45,21 @@ config DISPLAY_FSP_VERSION_INFO_2 Select this option to display Firmware version information using new header 'FirmwareVersionInfo.h'. +config HAVE_GPIO_SNAPSHOT_VERIFY_SUPPORT + bool + default n + help + Select this option if platform provides support for GPIO + config snapshot and verify callbacks: `gpio_snapshot()` + and `gpio_verify_snapshot()` + +config CHECK_GPIO_CONFIG_CHANGES + bool "Check GPIO config changes across calls to FSP-S" + depends on HAVE_GPIO_SNAPSHOT_VERIFY_SUPPORT + help + Select this option to identify if any GPIOs are re-configured + by FSP-S differently than the mainboard configuration. This + requires platform support to snapshot and verify that config + matches snapshot. + endif # PLATFORM_USES_FSP2_0 diff --git a/src/drivers/intel/fsp2_0/debug.c b/src/drivers/intel/fsp2_0/debug.c index 3d66587eb9..323c799987 100644 --- a/src/drivers/intel/fsp2_0/debug.c +++ b/src/drivers/intel/fsp2_0/debug.c @@ -11,6 +11,27 @@ asmlinkage size_t fsp_write_line(uint8_t *buffer, size_t number_of_bytes) return number_of_bytes; } +enum fsp_call_phase { + BEFORE_FSP_CALL, + AFTER_FSP_CALL, +}; + +static void fsp_gpio_config_check(enum fsp_call_phase phase, const char *call_str) +{ + switch (phase) { + case BEFORE_FSP_CALL: + printk(BIOS_SPEW, "Snapshot all GPIOs before %s.\n", call_str); + gpio_snapshot(); + break; + case AFTER_FSP_CALL: + printk(BIOS_SPEW, "Verify GPIO snapshot after %s...", call_str); + printk(BIOS_SPEW, "%zd changes detected!\n", gpio_verify_snapshot()); + break; + default: + break; + } +} + /*----------- * MemoryInit *----------- @@ -62,6 +83,9 @@ void fsp_debug_before_silicon_init(fsp_silicon_init_fn silicon_init, const FSPS_UPD *fsps_old_upd, const FSPS_UPD *fsps_new_upd) { + if (CONFIG(CHECK_GPIO_CONFIG_CHANGES)) + fsp_gpio_config_check(BEFORE_FSP_CALL, "FSP Silicon Init"); + display_mtrrs(); /* Display the UPD values */ @@ -77,6 +101,9 @@ void fsp_debug_before_silicon_init(fsp_silicon_init_fn silicon_init, void fsp_debug_after_silicon_init(uint32_t status) { + if (CONFIG(CHECK_GPIO_CONFIG_CHANGES)) + fsp_gpio_config_check(AFTER_FSP_CALL, "FSP Silicon Init"); + if (CONFIG(DISPLAY_FSP_CALLS_AND_STATUS)) printk(BIOS_SPEW, "FspSiliconInit returned 0x%08x\n", status); @@ -94,6 +121,9 @@ void fsp_debug_after_silicon_init(uint32_t status) void fsp_before_debug_notify(fsp_notify_fn notify, const struct fsp_notify_params *notify_params) { + if (CONFIG(CHECK_GPIO_CONFIG_CHANGES)) + fsp_gpio_config_check(BEFORE_FSP_CALL, "FSP Notify"); + /* Display the call to FspNotify */ if (!CONFIG(DISPLAY_FSP_CALLS_AND_STATUS)) return; @@ -105,6 +135,9 @@ void fsp_before_debug_notify(fsp_notify_fn notify, void fsp_debug_after_notify(uint32_t status) { + if (CONFIG(CHECK_GPIO_CONFIG_CHANGES)) + fsp_gpio_config_check(AFTER_FSP_CALL, "FSP Notify"); + if (CONFIG(DISPLAY_FSP_CALLS_AND_STATUS)) printk(BIOS_SPEW, "FspNotify returned 0x%08x\n", status); diff --git a/src/drivers/intel/fsp2_0/include/fsp/debug.h b/src/drivers/intel/fsp2_0/include/fsp/debug.h index e3d19180f0..be7dd3a1a8 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/debug.h +++ b/src/drivers/intel/fsp2_0/include/fsp/debug.h @@ -57,4 +57,9 @@ void fsp_print_guid_extension_hob(const struct hob_header *hob); */ asmlinkage size_t fsp_write_line(uint8_t *buffer, size_t number_of_bytes); +/* Callback to snapshot all GPIO configurations. */ +void gpio_snapshot(void); +/* Callback to verify that current GPIO configuration matches the saved snapshot */ +size_t gpio_verify_snapshot(void); + #endif /* _FSP2_0_DEBUG_H_ */