1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <console/console.h>
4 #include <intelblocks/cse.h>
7 #define MSEC_TO_USEC(x) (x * 1000)
9 static void process_cse_telemetry_data(void)
11 struct cse_boot_perf_rsp cse_perf_data
;
12 s64 ts
[NUM_CSE_BOOT_PERF_DATA
] = {0};
14 int zero_point_idx
= 0;
17 * 1. Each TS holds the time elapsed between the "Zero-Point" till the TS itself
19 * 2. In case CSME did not hit some of the TS in the latest boot flow that value of
20 * these TS will be 0x00000000.
21 * 3. In case of error, TS value will be set to 0xFFFFFFFF.
22 * 4. All other TS values will be relative to the zero point. The API caller should
23 * normalize the TS values to the zero-point value.
25 if (cse_get_boot_performance_data(&cse_perf_data
) != CB_SUCCESS
)
28 current_time
= timestamp_get();
30 for (unsigned int i
= 0; i
< NUM_CSE_BOOT_PERF_DATA
; i
++) {
31 if (cse_perf_data
.timestamp
[i
] == 0xffffffff) {
32 printk(BIOS_ERR
, "%s: CSME timestamps invalid\n", __func__
);
36 ts
[i
] = (s64
)MSEC_TO_USEC(cse_perf_data
.timestamp
[i
]) *
37 timestamp_tick_freq_mhz();
41 for (unsigned int i
= 0; i
< NUM_CSE_BOOT_PERF_DATA
; i
++) {
42 if (cse_perf_data
.timestamp
[i
] != 0) {
48 /* Normalize TS values to zero-point */
49 for (unsigned int i
= zero_point_idx
+ 1; i
< NUM_CSE_BOOT_PERF_DATA
; i
++) {
50 if (ts
[i
] && ts
[i
] < ts
[zero_point_idx
]) {
51 printk(BIOS_ERR
, "%s: CSME timestamps invalid,"
52 " wraparound detected\n", __func__
);
57 ts
[i
] -= ts
[zero_point_idx
];
60 /* Inject CSME timestamps into the coreboot timestamp table */
61 soc_cbmem_inject_telemetry_data(ts
, current_time
);
64 void cse_get_telemetry_data(void)
66 /* If CSE is already hidden then accessing CSE registers should be avoided */
67 if (!is_cse_enabled()) {
68 printk(BIOS_DEBUG
, "CSE is disabled, not sending `Get Boot Perf` message\n");
72 process_cse_telemetry_data();