blob: 872cf9149eeeb30063fb978b3eca59cf66cdbaf9 [file] [log] [blame]
Subrata Banik6de1d9f2022-03-20 19:50:38 +05301/* SPDX-License-Identifier: GPL-2.0-or-later */
2
Subrata Banik6de1d9f2022-03-20 19:50:38 +05303#include <console/console.h>
4#include <fsp/util.h>
Subrata Banik6de1d9f2022-03-20 19:50:38 +05305
Ronak Kanabar7bb93192023-06-14 09:28:16 +05306#define TIMESTAMP_TO_MICRO(x) ((x) / 1000ull)
Subrata Banik6de1d9f2022-03-20 19:50:38 +05307
8static const uint8_t fpdt_guid[16] = {
9 0xfd, 0x7b, 0x38, 0x3b, 0xbc, 0x7a, 0xf2, 0x4c,
10 0xa0, 0xca, 0xb6, 0xa1, 0x6c, 0x1b, 0x1b, 0x25,
11};
12
13enum fpdt_record_type {
14 FPDT_GUID_EVENT = 0x1010,
15 FPDT_STRING_EVENT = 0x1011,
16};
17
18struct perf_record_hdr {
19 uint16_t type;
20 uint8_t length;
21 uint8_t revision;
22} __packed;
23
24struct generic_event_record {
25 struct perf_record_hdr header;
26 uint16_t progress_id;
27 uint32_t apic_id;
28 uint64_t timestamp;
29 uint8_t guid[16];
Elyes Haouasf7926462023-07-28 06:07:35 +020030 uint8_t string[];
Subrata Banik6de1d9f2022-03-20 19:50:38 +053031} __packed;
32
33/*
Martin Roth74f18772023-09-03 21:38:29 -060034 * Performance HOB:
Subrata Banik6de1d9f2022-03-20 19:50:38 +053035 * GUID - fpdt_guid;
36 * Data - FPDT_PEI_EXT_PERF_HEADER one or more FPDT records
37*/
38struct fpdt_pei_ext_perf_header {
39 uint32_t table_size;
40 uint32_t load_image_count;
41 uint32_t hob_is_full;
42} __packed;
43
44static void print_guid_record(const struct generic_event_record *rec)
45{
Ronak Kanabar7bb93192023-06-14 09:28:16 +053046 printk(BIOS_INFO, "%5x\t%16llu\t\t", rec->progress_id, TIMESTAMP_TO_MICRO(rec->timestamp));
Felix Held50c0a6d2022-11-14 22:11:56 +010047 fsp_print_guid(BIOS_INFO, rec->guid);
Subrata Banik6de1d9f2022-03-20 19:50:38 +053048 printk(BIOS_INFO, "\n");
49}
50
51static void print_string_record(const struct generic_event_record *rec)
52{
53 size_t str_len = rec->header.length - offsetof(struct generic_event_record, string);
54 printk(BIOS_INFO, "%5x\t%16llu\t\t%*s/",
Ronak Kanabar7bb93192023-06-14 09:28:16 +053055 rec->progress_id, TIMESTAMP_TO_MICRO(rec->timestamp), (int)str_len, rec->string);
Felix Held50c0a6d2022-11-14 22:11:56 +010056 fsp_print_guid(BIOS_INFO, rec->guid);
Subrata Banik6de1d9f2022-03-20 19:50:38 +053057 printk(BIOS_INFO, "\n");
58}
59
60static void print_fsp_perf_timestamp(const struct generic_event_record *rec)
61{
62 switch (rec->header.type) {
63 case FPDT_GUID_EVENT:
64 print_guid_record(rec);
65 break;
66 case FPDT_STRING_EVENT:
67 print_string_record(rec);
68 break;
69 default:
70 printk(BIOS_INFO, "Unhandled Event Type 0x%x\n", rec->header.type);
71 break;
72 }
73}
74
75static void print_fsp_timestamp_header(void)
76{
77 printk(BIOS_INFO, "+---------------------------------------------------+\n");
78 printk(BIOS_INFO, "|------ FSP Performance Timestamp Table Dump -------|\n");
79 printk(BIOS_INFO, "+---------------------------------------------------+\n");
Ronak Kanabar7bb93192023-06-14 09:28:16 +053080 printk(BIOS_INFO, "| Perf-ID\tTimestamp(us)\t\tString/GUID |\n");
Subrata Banik6de1d9f2022-03-20 19:50:38 +053081 printk(BIOS_INFO, "+---------------------------------------------------+\n");
82}
83
84void fsp_display_timestamp(void)
85{
86 size_t size;
87 const struct fpdt_pei_ext_perf_header *hdr = fsp_find_extension_hob_by_guid(fpdt_guid,
88 &size);
89
90 if (!hdr || !size) {
91 printk(BIOS_INFO, "FPDT Extended Firmware Performance HOB Not Found!\n"
92 "Check if PcdFspPerformanceEnable is set to `TRUE` inside FSP package\n");
93 return;
94 }
95
96 const struct generic_event_record *rec = (const struct generic_event_record *)(
97 (uint8_t *)hdr + sizeof(struct fpdt_pei_ext_perf_header));
98
99 print_fsp_timestamp_header();
100 for (size_t i = 0; i < hdr->table_size;) {
101 print_fsp_perf_timestamp(rec);
102
103 i += rec->header.length;
104 rec = (const struct generic_event_record *)((uint8_t *)rec +
105 rec->header.length);
106 }
107}