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 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 <subratabanik@google.com> Change-Id: Ia1b7f6b98bafeec0afe843f0f78c99c2f34f50b3 Reviewed-on: https://review.coreboot.org/c/coreboot/+/62942 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Kangheui Won <khwon@chromium.org> Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com> Reviewed-by: Michael Niewöhner <foss@mniewoehner.de>
This commit is contained in:
parent
9842bef525
commit
6de1d9ff4e
|
@ -359,4 +359,14 @@ config FSP_USES_CB_DEBUG_EVENT_HANDLER
|
||||||
This option allows to create `Debug Event Handler` to print FSP debug messages
|
This option allows to create `Debug Event Handler` to print FSP debug messages
|
||||||
to output device using coreboot native implementation.
|
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
|
endif
|
||||||
|
|
|
@ -19,6 +19,7 @@ romstage-y += cbmem.c
|
||||||
ramstage-y += debug.c
|
ramstage-y += debug.c
|
||||||
ramstage-$(CONFIG_FSP_USES_CB_DEBUG_EVENT_HANDLER) += fsp_debug_event.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_USE_INTEL_FSP_MP_INIT) += fsp_mpinit.c
|
||||||
|
ramstage-$(CONFIG_DISPLAY_FSP_TIMESTAMPS) += fsp_timestamp.c
|
||||||
ramstage-$(CONFIG_RUN_FSP_GOP) += graphics.c
|
ramstage-$(CONFIG_RUN_FSP_GOP) += graphics.c
|
||||||
ramstage-y += hand_off_block.c
|
ramstage-y += hand_off_block.c
|
||||||
ramstage-$(CONFIG_DISPLAY_FSP_HEADER) += header_display.c
|
ramstage-$(CONFIG_DISPLAY_FSP_HEADER) += header_display.c
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/* 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_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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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_nv_storage_guid[16];
|
||||||
extern const uint8_t fsp_reserved_memory_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);
|
const void *fsp_get_hob_list(void);
|
||||||
void *fsp_get_hob_list_ptr(void);
|
void *fsp_get_hob_list_ptr(void);
|
||||||
const void *fsp_find_extension_hob_by_guid(const uint8_t *guid, size_t *size);
|
const void *fsp_find_extension_hob_by_guid(const uint8_t *guid, size_t *size);
|
||||||
|
|
|
@ -244,6 +244,9 @@ void fsp_silicon_init(void)
|
||||||
timestamp_add_now(TS_FSP_SILICON_INIT_LOAD);
|
timestamp_add_now(TS_FSP_SILICON_INIT_LOAD);
|
||||||
fsps_load();
|
fsps_load();
|
||||||
do_silicon_init(&fsps_hdr);
|
do_silicon_init(&fsps_hdr);
|
||||||
|
|
||||||
|
if (CONFIG(DISPLAY_FSP_TIMESTAMPS))
|
||||||
|
fsp_display_timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
__weak void soc_load_logo(FSPS_UPD *supd) { }
|
__weak void soc_load_logo(FSPS_UPD *supd) { }
|
||||||
|
|
Loading…
Reference in New Issue