summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/soc/intel/alderlake/romstage/romstage.c4
-rw-r--r--src/soc/intel/common/block/cse/Kconfig7
-rw-r--r--src/soc/intel/common/block/cse/Makefile.inc1
-rw-r--r--src/soc/intel/common/block/cse/telemetry.c74
-rw-r--r--src/soc/intel/common/block/include/intelblocks/cse.h6
5 files changed, 92 insertions, 0 deletions
diff --git a/src/soc/intel/alderlake/romstage/romstage.c b/src/soc/intel/alderlake/romstage/romstage.c
index 9720d9e549..45421c810b 100644
--- a/src/soc/intel/alderlake/romstage/romstage.c
+++ b/src/soc/intel/alderlake/romstage/romstage.c
@@ -142,6 +142,10 @@ void mainboard_romstage_entry(void)
timestamp_add_now(TS_CSE_FW_SYNC_END);
}
+ /* Update coreboot timestamp table with CSE timestamps */
+ if (CONFIG(SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY))
+ cse_get_telemetry_data();
+
/*
* Set low maximum temp threshold value used for dynamic thermal sensor
* shutdown consideration.
diff --git a/src/soc/intel/common/block/cse/Kconfig b/src/soc/intel/common/block/cse/Kconfig
index e30244799e..9621e9ad5f 100644
--- a/src/soc/intel/common/block/cse/Kconfig
+++ b/src/soc/intel/common/block/cse/Kconfig
@@ -166,6 +166,13 @@ config SOC_INTEL_CSE_LITE_COMPRESS_ME_RW
help
Enable compression on Intel CSE CBFS RW blob
+config SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY
+ def_bool n
+ depends on SOC_INTEL_CSE_LITE_SKU
+ help
+ Mainboard user to select this Kconfig in order to capture pre-cpu
+ reset boot performance telemetry data.
+
if STITCH_ME_BIN
config CSE_COMPONENTS_PATH
diff --git a/src/soc/intel/common/block/cse/Makefile.inc b/src/soc/intel/common/block/cse/Makefile.inc
index 472ae9550c..0c307cab7b 100644
--- a/src/soc/intel/common/block/cse/Makefile.inc
+++ b/src/soc/intel/common/block/cse/Makefile.inc
@@ -6,6 +6,7 @@ ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CSE) += disable_heci.c
smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CSE) += disable_heci.c
ramstage-$(CONFIG_SOC_INTEL_CSE_SET_EOP) += cse_eop.c
+romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += telemetry.c
ifeq ($(CONFIG_STITCH_ME_BIN),y)
diff --git a/src/soc/intel/common/block/cse/telemetry.c b/src/soc/intel/common/block/cse/telemetry.c
new file mode 100644
index 0000000000..544de802d1
--- /dev/null
+++ b/src/soc/intel/common/block/cse/telemetry.c
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <console/console.h>
+#include <intelblocks/cse.h>
+#include <timestamp.h>
+
+#define MSEC_TO_USEC(x) (x * 1000)
+
+void cse_get_telemetry_data(void)
+{
+ struct cse_boot_perf_rsp cse_perf_data;
+ s64 ts[NUM_CSE_BOOT_PERF_DATA] = {0};
+ s64 current_time, start_stamp;
+ int zero_point_idx = 0;
+
+ /*
+ * 1. Each TS holds the time elapsed between the "Zero-Point" till the TS itself
+ * happened.
+ * 2. In case CSME did not hit some of the TS in the latest boot flow that value of
+ * these TS will be 0x00000000.
+ * 3. In case of error, TS value will be set to 0xFFFFFFFF.
+ * 4. All other TS values will be relative to the zero point. The API caller should
+ * normalize the TS values to the zero-point value.
+ */
+ if (!cse_get_boot_performance_data(&cse_perf_data))
+ return;
+
+ current_time = timestamp_get();
+
+ for (unsigned int i = 0; i < NUM_CSE_BOOT_PERF_DATA; i++) {
+
+ if (cse_perf_data.timestamp[i] == 0xffffffff) {
+ printk(BIOS_ERR, "%s: CSME timestamps invalid\n", __func__);
+ return;
+ }
+
+ ts[i] = (s64)MSEC_TO_USEC(cse_perf_data.timestamp[i]) *
+ timestamp_tick_freq_mhz();
+ }
+
+ /* Find zero-point */
+ for (unsigned int i = 0; i < NUM_CSE_BOOT_PERF_DATA; i++) {
+ if (cse_perf_data.timestamp[i] != 0) {
+ zero_point_idx = i;
+ break;
+ }
+ }
+
+ /* Normalize TS values to zero-point */
+ for (unsigned int i = zero_point_idx + 1; i < NUM_CSE_BOOT_PERF_DATA; i++) {
+
+ if (ts[i] && ts[i] < ts[zero_point_idx]) {
+ printk(BIOS_ERR, "%s: CSME timestamps invalid,"
+ " wraparound detected\n", __func__);
+ return;
+ }
+
+ if (ts[i])
+ ts[i] -= ts[zero_point_idx];
+ }
+
+ /* Inject CSME timestamps into the coreboot timestamp table */
+ start_stamp = current_time - ts[PERF_DATA_CSME_GET_PERF_RESPONSE];
+
+ timestamp_add(TS_ME_ROM_START, start_stamp);
+ timestamp_add(TS_ME_BOOT_STALL_END,
+ start_stamp + ts[PERF_DATA_CSME_RBE_BOOT_STALL_DONE_TO_PMC]);
+ timestamp_add(TS_ME_ICC_CONFIG_START,
+ start_stamp + ts[PERF_DATA_CSME_POLL_FOR_PMC_PPS_START]);
+ timestamp_add(TS_ME_HOST_BOOT_PREP_END,
+ start_stamp + ts[PERF_DATA_CSME_HOST_BOOT_PREP_DONE]);
+ timestamp_add(TS_ME_RECEIVED_CRDA_FROM_PMC,
+ start_stamp + ts[PERF_DATA_PMC_SENT_CRDA]);
+}
diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h
index f031ad5105..f94fc73ae3 100644
--- a/src/soc/intel/common/block/include/intelblocks/cse.h
+++ b/src/soc/intel/common/block/include/intelblocks/cse.h
@@ -509,4 +509,10 @@ void cse_send_end_of_post(void);
*/
void soc_disable_heci1_using_pcr(void);
+/*
+ * Get all the timestamps CSE collected using cse_get_boot_performance_data() and
+ * insert them into the CBMEM timestamp table.
+ */
+void cse_get_telemetry_data(void);
+
#endif // SOC_INTEL_COMMON_CSE_H