Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/62942 )
Change subject: drivers/intel/fsp2_0: Add provision to extract FSP Performance Data ......................................................................
drivers/intel/fsp2_0: Add provision to extract FSP Performance Data
This patch enriches coreboot FSP2.0 driver to extract the FSP timestamp from FPDT (Firmware Performance Data Table) and display as part of ramstage boot stage if the SoC user selects the required `GET_FSP_TIMESTAMP` 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 GET_FSP_TIMESTAMP Kconfig selected and met the FSP prerequisites. +--------------------------------------------------+ |------ FSP Performance Timestamp Table Dump ------| +--------------------------------------------------+ |Perf-ID Timestamp(ms) String/GUID | +--------------------------------------------------+ 0 460253 SEC 50 460263 PEI 40 460274 PreMem 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 50f1 716649 unknown name 2 728507 a8499e65-a6f6-48b0-96db45c266030d83 1 734755 9e1cc850-6731-4848-87526673c7005eee ....
Signed-off-by: Subrata Banik subratabanik@google.com Change-Id: Ia1b7f6b98bafeec0afe843f0f78c99c2f34f50b3 --- M src/drivers/intel/fsp2_0/Kconfig M src/drivers/intel/fsp2_0/Makefile.inc A src/drivers/intel/fsp2_0/fsp_timestamp.c M src/drivers/intel/fsp2_0/include/fsp/util.h 4 files changed, 124 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/42/62942/1
diff --git a/src/drivers/intel/fsp2_0/Kconfig b/src/drivers/intel/fsp2_0/Kconfig index fdea4b8..2db0748 100644 --- a/src/drivers/intel/fsp2_0/Kconfig +++ b/src/drivers/intel/fsp2_0/Kconfig @@ -352,4 +352,11 @@ to perform the required lock down and chipset register configuration prior boot to payload.
+config GET_FSP_TIMESTAMP + bool + help + Select this config to retrieve FSP timestamp from Firmware Performance Data Table + (FPDT). SoC users requires to compile and generate FSP binary 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 eaf99d1..9399dda 100644 --- a/src/drivers/intel/fsp2_0/Makefile.inc +++ b/src/drivers/intel/fsp2_0/Makefile.inc @@ -24,6 +24,7 @@ ramstage-$(CONFIG_VERIFY_HOBS) += hob_verify.c ramstage-y += notify.c ramstage-y += silicon_init.c +ramstage-$(CONFIG_GET_FSP_TIMESTAMP) += fsp_timestamp.c ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c ramstage-y += util.c ramstage-$(CONFIG_MMA) += mma_core.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 0000000..04fd5cf --- /dev/null +++ b/src/drivers/intel/fsp2_0/fsp_timestamp.c @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <commonlib/bsd/compiler.h> +#include <console/console.h> +#include <fsp/util.h> +#include <lib.h> + +#define TIMESTAMP(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(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\n", + rec->progress_id, TIMESTAMP(rec->timestamp), (int)str_len, rec->string); +} + +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_get_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 = malloc(hdr->table_size); + if (!rec) + return; + + memset((void *)rec, 0, sizeof(*rec)); + memcpy((void *)rec, (uint8_t *)hdr + sizeof(struct fpdt_pei_ext_perf_header), + hdr->table_size); + + 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); + } + + free((void *)rec); +} + diff --git a/src/drivers/intel/fsp2_0/include/fsp/util.h b/src/drivers/intel/fsp2_0/include/fsp/util.h index 7347034..c1cc76b 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/util.h +++ b/src/drivers/intel/fsp2_0/include/fsp/util.h @@ -100,6 +100,7 @@ extern const uint8_t fsp_nv_storage_guid[16]; extern const uint8_t fsp_reserved_memory_guid[16];
+void fsp_get_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);