From 6de1d9ff4ecfd1b550a99270e7431ab9e0cf5406 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sun, 20 Mar 2022 19:50:38 +0530 Subject: [PATCH] drivers/intel/fsp2_0: Add provision to extract FSP Performance Data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch enriches coreboot FSP2.0 driver to extract the FSP timestamp from FPDT (Firmware Performance Data Table) and display right after FSP-S exits (from `fsp_silicon_init()` function), based on SoC user selects the required `DISPLAY_FSP_TIMESTAMPS` config. The prerequisite to this implementation is to have FSP binary built with `PcdFspPerformanceEnable` PCD set to `TRUE` to allow FSP to populate the FPDT HOB. BUG=b:216635831 TEST=Able to dump FSP performance data with DISPLAY_FSP_TIMESTAMPS Kconfig selected and met the FSP prerequisites. +--------------------------------------------------+ |------ FSP Performance Timestamp Table Dump ------| +--------------------------------------------------+ | Perf-ID Timestamp(ms) String/GUID | +--------------------------------------------------+ 0 460253 SEC/52c05b14-0b98-496c-bc3b04b50211d680 50 460263 PEI/52c05b14-0b98-496c-bc3b04b50211d680 40 460274 PreMem/52c05b14-0b98-496c-bc3b04b50211d680 1 495803 9b3ada4f-ae56-4c24-8deaf03b7558ae50 2 508959 9b3ada4f-ae56-4c24-8deaf03b7558ae50 1 515253 6141e486-7543-4f1a-a579ff532ed78e75 2 525453 6141e486-7543-4f1a-a579ff532ed78e75 1 532059 baeb5bee-5b33-480a-8ab7b29c85e7ceab 2 546806 baeb5bee-5b33-480a-8ab7b29c85e7ceab 1 553302 1b04374d-fa9c-420f-ac62fee6d45e8443 2 563859 1b04374d-fa9c-420f-ac62fee6d45e8443 1 569955 88c17e54-ebfe-4531-a992581029f58126 2 575753 88c17e54-ebfe-4531-a992581029f58126 1 582099 a8499e65-a6f6-48b0-96db45c266030d83 50f0 599599 unknown name/3112356f-cc77-4e82-86d53e25ee8192a4 50f1 716649 unknown name/3112356f-cc77-4e82-86d53e25ee8192a4 2 728507 a8499e65-a6f6-48b0-96db45c266030d83 1 734755 9e1cc850-6731-4848-87526673c7005eee .... Signed-off-by: Subrata Banik Change-Id: Ia1b7f6b98bafeec0afe843f0f78c99c2f34f50b3 Reviewed-on: https://review.coreboot.org/c/coreboot/+/62942 Tested-by: build bot (Jenkins) Reviewed-by: Kangheui Won Reviewed-by: Eric Lai Reviewed-by: Michael Niewöhner --- src/drivers/intel/fsp2_0/Kconfig | 10 ++ src/drivers/intel/fsp2_0/Makefile.inc | 1 + src/drivers/intel/fsp2_0/fsp_timestamp.c | 109 ++++++++++++++++++++ src/drivers/intel/fsp2_0/include/fsp/util.h | 2 + src/drivers/intel/fsp2_0/silicon_init.c | 3 + 5 files changed, 125 insertions(+) create mode 100644 src/drivers/intel/fsp2_0/fsp_timestamp.c diff --git a/src/drivers/intel/fsp2_0/Kconfig b/src/drivers/intel/fsp2_0/Kconfig index 0823aa3020..1eccd61400 100644 --- a/src/drivers/intel/fsp2_0/Kconfig +++ b/src/drivers/intel/fsp2_0/Kconfig @@ -359,4 +359,14 @@ config FSP_USES_CB_DEBUG_EVENT_HANDLER This option allows to create `Debug Event Handler` to print FSP debug messages to output device using coreboot native implementation. +config DISPLAY_FSP_TIMESTAMPS + bool "Display FSP Timestamps" + default n + help + Select this config to retrieve FSP timestamps from Firmware Performance Data Table + (FPDT) and display from ramstage after FSP-S is executed. + + To be able to use this, FSP has to be compiled with `PcdFspPerformanceEnable` set to + `TRUE`. + endif diff --git a/src/drivers/intel/fsp2_0/Makefile.inc b/src/drivers/intel/fsp2_0/Makefile.inc index 076ab2d84b..f5641ac182 100644 --- a/src/drivers/intel/fsp2_0/Makefile.inc +++ b/src/drivers/intel/fsp2_0/Makefile.inc @@ -19,6 +19,7 @@ romstage-y += cbmem.c ramstage-y += debug.c ramstage-$(CONFIG_FSP_USES_CB_DEBUG_EVENT_HANDLER) += fsp_debug_event.c ramstage-$(CONFIG_USE_INTEL_FSP_MP_INIT) += fsp_mpinit.c +ramstage-$(CONFIG_DISPLAY_FSP_TIMESTAMPS) += fsp_timestamp.c ramstage-$(CONFIG_RUN_FSP_GOP) += graphics.c ramstage-y += hand_off_block.c ramstage-$(CONFIG_DISPLAY_FSP_HEADER) += header_display.c diff --git a/src/drivers/intel/fsp2_0/fsp_timestamp.c b/src/drivers/intel/fsp2_0/fsp_timestamp.c new file mode 100644 index 0000000000..da14db91c0 --- /dev/null +++ b/src/drivers/intel/fsp2_0/fsp_timestamp.c @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +#define TIMESTAMP_MS(x) ((x) / 1000ull) + +static const uint8_t fpdt_guid[16] = { + 0xfd, 0x7b, 0x38, 0x3b, 0xbc, 0x7a, 0xf2, 0x4c, + 0xa0, 0xca, 0xb6, 0xa1, 0x6c, 0x1b, 0x1b, 0x25, +}; + +enum fpdt_record_type { + FPDT_GUID_EVENT = 0x1010, + FPDT_STRING_EVENT = 0x1011, +}; + +struct perf_record_hdr { + uint16_t type; + uint8_t length; + uint8_t revision; +} __packed; + +struct generic_event_record { + struct perf_record_hdr header; + uint16_t progress_id; + uint32_t apic_id; + uint64_t timestamp; + uint8_t guid[16]; + uint8_t string[0]; +} __packed; + +/* + * Performance Hob: + * GUID - fpdt_guid; + * Data - FPDT_PEI_EXT_PERF_HEADER one or more FPDT records +*/ +struct fpdt_pei_ext_perf_header { + uint32_t table_size; + uint32_t load_image_count; + uint32_t hob_is_full; +} __packed; + +static void print_guid_record(const struct generic_event_record *rec) +{ + printk(BIOS_INFO, "%5x\t%16llu\t\t", rec->progress_id, TIMESTAMP_MS(rec->timestamp)); + fsp_print_guid(rec->guid); + printk(BIOS_INFO, "\n"); +} + +static void print_string_record(const struct generic_event_record *rec) +{ + size_t str_len = rec->header.length - offsetof(struct generic_event_record, string); + printk(BIOS_INFO, "%5x\t%16llu\t\t%*s/", + rec->progress_id, TIMESTAMP_MS(rec->timestamp), (int)str_len, rec->string); + fsp_print_guid(rec->guid); + printk(BIOS_INFO, "\n"); +} + +static void print_fsp_perf_timestamp(const struct generic_event_record *rec) +{ + switch (rec->header.type) { + case FPDT_GUID_EVENT: + print_guid_record(rec); + break; + case FPDT_STRING_EVENT: + print_string_record(rec); + break; + default: + printk(BIOS_INFO, "Unhandled Event Type 0x%x\n", rec->header.type); + break; + } +} + +static void print_fsp_timestamp_header(void) +{ + printk(BIOS_INFO, "+---------------------------------------------------+\n"); + printk(BIOS_INFO, "|------ FSP Performance Timestamp Table Dump -------|\n"); + printk(BIOS_INFO, "+---------------------------------------------------+\n"); + printk(BIOS_INFO, "| Perf-ID\tTimestamp(ms)\t\tString/GUID |\n"); + printk(BIOS_INFO, "+---------------------------------------------------+\n"); +} + +void fsp_display_timestamp(void) +{ + size_t size; + const struct fpdt_pei_ext_perf_header *hdr = fsp_find_extension_hob_by_guid(fpdt_guid, + &size); + + if (!hdr || !size) { + printk(BIOS_INFO, "FPDT Extended Firmware Performance HOB Not Found!\n" + "Check if PcdFspPerformanceEnable is set to `TRUE` inside FSP package\n"); + return; + } + + const struct generic_event_record *rec = (const struct generic_event_record *)( + (uint8_t *)hdr + sizeof(struct fpdt_pei_ext_perf_header)); + + print_fsp_timestamp_header(); + for (size_t i = 0; i < hdr->table_size;) { + print_fsp_perf_timestamp(rec); + + i += rec->header.length; + rec = (const struct generic_event_record *)((uint8_t *)rec + + rec->header.length); + } +} diff --git a/src/drivers/intel/fsp2_0/include/fsp/util.h b/src/drivers/intel/fsp2_0/include/fsp/util.h index 2687d0dc98..96dc472361 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/util.h +++ b/src/drivers/intel/fsp2_0/include/fsp/util.h @@ -106,6 +106,8 @@ extern const uint8_t fsp_bootloader_tolum_guid[16]; extern const uint8_t fsp_nv_storage_guid[16]; extern const uint8_t fsp_reserved_memory_guid[16]; +/* Function to extract the FSP timestamp from FPDT Hob and display */ +void fsp_display_timestamp(void); const void *fsp_get_hob_list(void); void *fsp_get_hob_list_ptr(void); const void *fsp_find_extension_hob_by_guid(const uint8_t *guid, size_t *size); diff --git a/src/drivers/intel/fsp2_0/silicon_init.c b/src/drivers/intel/fsp2_0/silicon_init.c index 05cea11d55..263ea3b46d 100644 --- a/src/drivers/intel/fsp2_0/silicon_init.c +++ b/src/drivers/intel/fsp2_0/silicon_init.c @@ -244,6 +244,9 @@ void fsp_silicon_init(void) timestamp_add_now(TS_FSP_SILICON_INIT_LOAD); fsps_load(); do_silicon_init(&fsps_hdr); + + if (CONFIG(DISPLAY_FSP_TIMESTAMPS)) + fsp_display_timestamp(); } __weak void soc_load_logo(FSPS_UPD *supd) { }