Skip to content

Commit bcf27a5

Browse files
committed
Haswell NRI: add Measure per-task execution time when CONFIG_DEBUG_RAM_SETUP=y
This is merged https://review.coreboot.org/c/coreboot/+/87830 to help troubleshoot #1923 (comment) As of now, unknowns are: - if NRI can work with Heads neutered ME per https://github.com/linuxboot/heads/blob/master/blobs/t440p/download-clean-me and https://github.com/linuxboot/heads/blob/master/blobs/w541/download-clean-me - What is causing '[ERROR] SF size 0x2800000 does not correspond to CONFIG_ROM_SIZE 0xc00000!!' - NRI per-task spent time; this is what this commit should shed some light for both w541 and t440p Signed-off-by: Thierry Laurion <insurgo@riseup.net>
1 parent ce63b85 commit bcf27a5

1 file changed

Lines changed: 140 additions & 0 deletions

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
From ab29f52ee2c816c62edc0eff2df576370abe3a09 Mon Sep 17 00:00:00 2001
2+
From: Angel Pons <th3fanbus@gmail.com>
3+
Date: Sun, 25 May 2025 13:03:04 +0200
4+
Subject: [PATCH] Haswell NRI: Measure per-task execution time
5+
6+
Add some simple execution time measurement code. It only logs execution
7+
times if `DEBUG_RAM_SETUP` is selected. Note that this will fill things
8+
like pre-RAM CBMEM console, but NRI's debug output is already extremely
9+
verbose, and will become even more verbose as additional training steps
10+
get added.
11+
12+
Future plans include measuring the time spent waiting for REUT hardware
13+
to finish testing, as that is what takes most time for complex training
14+
algorithms (which are yet to be published).
15+
16+
Tested on Asrock B85M Pro4, still boots to Arch Linux. Output example:
17+
18+
+------------------+------------+
19+
| Task | msecs |
20+
+------------------+------------+
21+
| PROCSPD | 503 |
22+
| INITMPLL | 33 |
23+
| CONVTIM | 43 |
24+
| CONFMC | 1 |
25+
| MEMMAP | 39 |
26+
| JEDECINIT | 1 |
27+
| PRETRAIN | 23 |
28+
| SOT | 394 |
29+
| RCVET | 1448 |
30+
| RDMPRT | 1088 |
31+
| JWRL | 1975 |
32+
| OPTCOMP | 0 |
33+
| POSTTRAIN | 0 |
34+
| ACTIVATE | 0 |
35+
| SAVE_TRAIN | 0 |
36+
| SAVE_NONT | 0 |
37+
| RAMINITEND | 4 |
38+
+------------------+------------+
39+
| Total | 5558 |
40+
+------------------+------------+
41+
42+
Note: the board had 4x dual-rank DIMMs installed, which gives the worst
43+
possible boot time (more ranks to train, and that means more log output
44+
to push through 115200 baud serial). Without debug logging, training is
45+
substantially faster.
46+
47+
Change-Id: Ie4b6f6246e54f23d03babdb6fa0271538f69984e
48+
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
49+
Reviewed-on: https://review.coreboot.org/c/coreboot/+/87830
50+
Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
51+
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
52+
---
53+
.../haswell/native_raminit/raminit_main.c | 35 ++++++++++++++++++-
54+
1 file changed, 34 insertions(+), 1 deletion(-)
55+
56+
diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c
57+
index 21c953b332..d211bfb20a 100644
58+
--- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c
59+
+++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c
60+
@@ -10,6 +10,7 @@
61+
#include <northbridge/intel/haswell/raminit.h>
62+
#include <static.h>
63+
#include <string.h>
64+
+#include <timer.h>
65+
#include <types.h>
66+
67+
#include "raminit_native.h"
68+
@@ -85,6 +86,9 @@ static const struct task_entry fast_boot[] = {
69+
{ raminit_done, true, "RAMINITEND", },
70+
};
71+
72+
+_Static_assert(ARRAY_SIZE(cold_boot) >= ARRAY_SIZE(fast_boot),
73+
+ "Code assumes cold boot task list is the longest one");
74+
+
75+
/* Return a generic stepping value to make stepping checks simpler */
76+
static enum generic_stepping get_stepping(const uint32_t cpuid)
77+
{
78+
@@ -120,6 +124,9 @@ static void initialize_ctrl(struct sysinfo *ctrl)
79+
ctrl->bootmode = bootmode;
80+
}
81+
82+
+/** TODO: Adjust unit scale dynamically? **/
83+
+#define T_SCALE 1000 /* 1 = usecs, 1000 = msecs */
84+
+
85+
static enum raminit_status try_raminit(
86+
struct sysinfo *ctrl,
87+
const struct task_entry *const schedule,
88+
@@ -127,7 +134,11 @@ static enum raminit_status try_raminit(
89+
{
90+
enum raminit_status status = RAMINIT_STATUS_UNSPECIFIED_ERROR;
91+
92+
- for (size_t i = 0; i < length; i++) {
93+
+ long spent_time[ARRAY_SIZE(cold_boot)] = { 0 };
94+
+ long total = 0;
95+
+
96+
+ size_t i;
97+
+ for (i = 0; i < length; i++) {
98+
const struct task_entry *const entry = &schedule[i];
99+
assert(entry);
100+
assert(entry->name);
101+
@@ -136,14 +147,36 @@ static enum raminit_status try_raminit(
102+
103+
assert(entry->task);
104+
printk(RAM_DEBUG, "\nExecuting raminit task %s\n", entry->name);
105+
+ struct mono_time prev, curr;
106+
+ timer_monotonic_get(&prev);
107+
status = entry->task(ctrl);
108+
+ timer_monotonic_get(&curr);
109+
+ spent_time[i] = mono_time_diff_microseconds(&prev, &curr);
110+
printk(RAM_DEBUG, "\n");
111+
if (status) {
112+
+ i++;
113+
printk(BIOS_ERR, "raminit failed on step %s\n", entry->name);
114+
break;
115+
}
116+
}
117+
118+
+ if (CONFIG(DEBUG_RAM_SETUP)) {
119+
+ const char unit_multiplier = T_SCALE == 1 ? 'u' : 'm';
120+
+ printk(RAM_DEBUG, "+------------------+------------+\n");
121+
+ printk(RAM_DEBUG, "| Task | %csecs |\n", unit_multiplier);
122+
+ printk(RAM_DEBUG, "+------------------+------------+\n");
123+
+ assert(i <= length);
124+
+ for (size_t j = 0; j < i; j++) {
125+
+ char buf[] = " ";
126+
+ strncpy(buf, schedule[j].name, strlen(schedule[j].name));
127+
+ printk(RAM_DEBUG, "| %s | % 10ld |\n", buf, spent_time[j] / T_SCALE);
128+
+ total += spent_time[j];
129+
+ }
130+
+ printk(RAM_DEBUG, "+------------------+------------+\n");
131+
+ printk(RAM_DEBUG, "| Total | % 10ld |\n", total / T_SCALE);
132+
+ printk(RAM_DEBUG, "+------------------+------------+\n");
133+
+ }
134+
+
135+
return status;
136+
}
137+
138+
--
139+
2.39.5
140+

0 commit comments

Comments
 (0)