blob: ea4d89616f62b1457baff71b1a4d47e01a4c2a82 [file] [log] [blame]
Simon Glasse1efad22021-03-15 18:00:24 +13001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2021 Google LLC
4 * Written by Simon Glass <sjg@chromium.org>
5 */
6
Simon Glasse1efad22021-03-15 18:00:24 +13007#include <asm/cb_sysinfo.h>
8#include <command.h>
9#include <console.h>
10#include <asm/global_data.h>
11
12DECLARE_GLOBAL_DATA_PTR;
13
14static void cbprompt(const char *name)
15{
16 for (; *name == '>'; name++)
17 puts(" ");
18 printf("%-12s: ", name);
19}
20
21static void print_dec(const char *name, int value)
22{
23 cbprompt(name);
24 printf(value > 9 ? "0d%d\n" : "%d\n", value);
25}
26
27static void print_hex(const char *name, int value)
28{
29 cbprompt(name);
30 printf("%x\n", value);
31}
32
33static void print_addr(const char *name, ulong value)
34{
35 cbprompt(name);
36 printf("%08lx\n", value);
37}
38
39static void print_addr64(const char *name, u64 value)
40{
41 cbprompt(name);
42 printf("%16llx\n", value);
43}
44
45static void print_ptr(const char *name, const void *value)
46{
47 cbprompt(name);
48 printf("%p\n", value);
49}
50
51static void print_str(const char *name, const char *value)
52{
53 if (value) {
54 cbprompt(name);
55 printf("%s\n", value);
56 }
57}
58
59static void print_idx(const char *name, uint idx, const u8 *strings)
60{
61 const char *ptr;
62
63 cbprompt(name);
64 ptr = (char *)strings + idx;
65 printf("%d: %s\n", idx, ptr ? ptr : "(unknown)");
66}
67
68static const char *const cb_mem_name[] = {
69 NULL,
70 "ram",
71 "reserved",
72 "acpi",
73 "nvs",
74 "unusable",
75 "vendor",
76};
77
78static const char *get_mem_name(int tag)
79{
80 if (tag >= CB_MEM_RAM && tag <= CB_MEM_VENDOR_RSVD)
81 return cb_mem_name[tag];
82
83 if (tag == CB_MEM_TABLE)
84 return "table";
85
86 return "(unknown)";
87}
88
89static const struct timestamp_id_to_name {
90 uint id;
91 const char *name;
92} timestamp_ids[] = {
93 /* Marker to report base_time */
94 { 0, "1st timestamp" },
95 { TS_START_ROMSTAGE, "start of romstage" },
96 { TS_BEFORE_INITRAM, "before ram initialization" },
97 { TS_AFTER_INITRAM, "after ram initialization" },
98 { TS_END_ROMSTAGE, "end of romstage" },
99 { TS_START_VBOOT, "start of verified boot" },
100 { TS_END_VBOOT, "end of verified boot" },
101 { TS_START_COPYRAM, "starting to load ramstage" },
102 { TS_END_COPYRAM, "finished loading ramstage" },
103 { TS_START_RAMSTAGE, "start of ramstage" },
104 { TS_START_BOOTBLOCK, "start of bootblock" },
105 { TS_END_BOOTBLOCK, "end of bootblock" },
106 { TS_START_COPYROM, "starting to load romstage" },
107 { TS_END_COPYROM, "finished loading romstage" },
108 { TS_START_ULZMA, "starting LZMA decompress (ignore for x86)" },
109 { TS_END_ULZMA, "finished LZMA decompress (ignore for x86)" },
110 { TS_START_ULZ4F, "starting LZ4 decompress (ignore for x86)" },
111 { TS_END_ULZ4F, "finished LZ4 decompress (ignore for x86)" },
112 { TS_DEVICE_ENUMERATE, "device enumeration" },
113 { TS_DEVICE_CONFIGURE, "device configuration" },
114 { TS_DEVICE_ENABLE, "device enable" },
115 { TS_DEVICE_INITIALIZE, "device initialization" },
116 { TS_DEVICE_DONE, "device setup done" },
117 { TS_CBMEM_POST, "cbmem post" },
118 { TS_WRITE_TABLES, "write tables" },
119 { TS_FINALIZE_CHIPS, "finalize chips" },
120 { TS_LOAD_PAYLOAD, "load payload" },
121 { TS_ACPI_WAKE_JUMP, "ACPI wake jump" },
122 { TS_SELFBOOT_JUMP, "selfboot jump" },
123
124 { TS_START_COPYVER, "starting to load verstage" },
125 { TS_END_COPYVER, "finished loading verstage" },
126 { TS_START_TPMINIT, "starting to initialize TPM" },
127 { TS_END_TPMINIT, "finished TPM initialization" },
128 { TS_START_VERIFY_SLOT, "starting to verify keyblock/preamble (RSA)" },
129 { TS_END_VERIFY_SLOT, "finished verifying keyblock/preamble (RSA)" },
130 { TS_START_HASH_BODY, "starting to verify body (load+SHA2+RSA) " },
131 { TS_DONE_LOADING, "finished loading body (ignore for x86)" },
132 { TS_DONE_HASHING, "finished calculating body hash (SHA2)" },
133 { TS_END_HASH_BODY, "finished verifying body signature (RSA)" },
134
135 { TS_START_COPYVPD, "starting to load Chrome OS VPD" },
136 { TS_END_COPYVPD_RO, "finished loading Chrome OS VPD (RO)" },
137 { TS_END_COPYVPD_RW, "finished loading Chrome OS VPD (RW)" },
138
139 { TS_U_BOOT_INITTED, "U-Boot start" },
140 { TS_RO_PARAMS_INIT, "RO parameter init" },
141 { TS_RO_VB_INIT, "RO vboot init" },
142 { TS_RO_VB_SELECT_FIRMWARE, "RO vboot select firmware" },
143 { TS_RO_VB_SELECT_AND_LOAD_KERNEL, "RO vboot select&load kernel" },
144 { TS_RW_VB_SELECT_AND_LOAD_KERNEL, "RW vboot select&load kernel" },
145 { TS_VB_SELECT_AND_LOAD_KERNEL, "vboot select&load kernel" },
146 { TS_VB_EC_VBOOT_DONE, "finished EC verification" },
147 { TS_VB_STORAGE_INIT_DONE, "finished storage device initialization" },
148 { TS_VB_READ_KERNEL_DONE, "finished reading kernel from disk" },
149 { TS_VB_VBOOT_DONE, "finished vboot kernel verification" },
150 { TS_KERNEL_DECOMPRESSION, "starting kernel decompression/relocation" },
151 { TS_START_KERNEL, "jumping to kernel" },
152 { TS_U_BOOT_START_KERNEL, "just before jump to kernel" },
153
154 /* Intel ME-related timestamps */
155 { TS_ME_INFORM_DRAM_WAIT, "waiting for ME acknowledgment of raminit"},
156 { TS_ME_INFORM_DRAM_DONE, "finished waiting for ME response"},
157
158 /* FSP-related timestamps */
159 { TS_FSP_MEMORY_INIT_START, "calling FspMemoryInit" },
160 { TS_FSP_MEMORY_INIT_END, "returning from FspMemoryInit" },
161 { TS_FSP_TEMP_RAM_EXIT_START, "calling FspTempRamExit" },
162 { TS_FSP_TEMP_RAM_EXIT_END, "returning from FspTempRamExit" },
163 { TS_FSP_SILICON_INIT_START, "calling FspSiliconInit" },
164 { TS_FSP_SILICON_INIT_END, "returning from FspSiliconInit" },
165 { TS_FSP_BEFORE_ENUMERATE, "calling FspNotify(AfterPciEnumeration)" },
166 { TS_FSP_AFTER_ENUMERATE,
167 "returning from FspNotify(AfterPciEnumeration)" },
168 { TS_FSP_BEFORE_FINALIZE, "calling FspNotify(ReadyToBoot)" },
169 { TS_FSP_AFTER_FINALIZE, "returning from FspNotify(ReadyToBoot)" },
170 { TS_FSP_BEFORE_END_OF_FIRMWARE, "calling FspNotify(EndOfFirmware)" },
171 { TS_FSP_AFTER_END_OF_FIRMWARE,
172 "returning from FspNotify(EndOfFirmware)" },
173};
174
175static const char *timestamp_name(uint32_t id)
176{
177 int i;
178
179 for (i = 0; i < ARRAY_SIZE(timestamp_ids); i++) {
180 if (timestamp_ids[i].id == id)
181 return timestamp_ids[i].name;
182 }
183
184 return "<unknown>";
185}
186
Simon Glassb57a23b2024-10-14 16:32:08 -0600187static void show_option_vals(const struct cb_cmos_option_table *tab,
188 uint id)
189{
190 const void *ptr, *end;
191 bool found = false;
192
193 end = (void *)tab + tab->size;
194 for (ptr = (void *)tab + tab->header_length; ptr < end;) {
195 const struct cb_record *rec = ptr;
196
197 switch (rec->tag) {
198 case CB_TAG_OPTION_ENUM: {
199 const struct cb_cmos_enums *enums = ptr;
200
201 if (enums->config_id == id) {
202 if (!found)
203 printf(" ");
204 printf(" %d:%s", enums->value, enums->text);
205 found = true;
206 }
207 break;
208 }
209 break;
210 case CB_TAG_OPTION_DEFAULTS:
211 case CB_TAG_OPTION_CHECKSUM:
212 case CB_TAG_OPTION:
213 break;
214 default:
215 printf("tag %x\n", rec->tag);
216 break;
217 }
218 ptr += rec->size;
219 }
220}
221
222static void show_option_table(const struct cb_cmos_option_table *tab)
223{
224 const void *ptr, *end;
225
226 print_ptr("option_table", tab);
227 if (!tab->size)
228 return;
229
230 printf(" Bit Len Cfg ID Name\n");
231 end = (void *)tab + tab->size;
232 for (ptr = (void *)tab + tab->header_length; ptr < end;) {
233 const struct cb_record *rec = ptr;
234
235 switch (rec->tag) {
236 case CB_TAG_OPTION: {
237 const struct cb_cmos_entries *entry = ptr;
238
239 printf("%4x %4x %3c %3x %-20s", entry->bit,
240 entry->length, entry->config, entry->config_id,
241 entry->name);
242 show_option_vals(tab, entry->config_id);
243 printf("\n");
244 break;
245 }
246 case CB_TAG_OPTION_ENUM:
247 case CB_TAG_OPTION_DEFAULTS:
248 case CB_TAG_OPTION_CHECKSUM:
249 break;
250 default:
251 printf("tag %x\n", rec->tag);
252 break;
253 }
254 ptr += rec->size;
255 }
256}
257
Simon Glasse1efad22021-03-15 18:00:24 +1300258static void show_table(struct sysinfo_t *info, bool verbose)
259{
260 struct cb_serial *ser = info->serial;
261 int i;
262
Simon Glass4a75a122023-07-25 15:37:06 -0600263 printf("Coreboot table at %lx, size %x, records %x (dec %d), decoded to %p",
264 gd->arch.coreboot_table, info->table_size, info->rec_count,
265 info->rec_count, info);
Simon Glasse1efad22021-03-15 18:00:24 +1300266 if (info->header)
267 printf(", forwarded to %p\n", info->header);
268 printf("\n");
269
270 print_dec("CPU KHz", info->cpu_khz);
271
272 print_addr("Serial I/O port", info->ser_ioport);
273 print_addr(">base", info->ser_base);
274 print_ptr(">pointer", ser);
275 if (ser) {
276 print_hex(">type", ser->type);
277 print_addr(">base", ser->baseaddr);
278 print_dec(">baud", ser->baud);
Simon Glass021f4442021-04-24 10:04:57 +1200279 print_hex(">regwidth", ser->regwidth);
Simon Glasse1efad22021-03-15 18:00:24 +1300280 print_dec(">input_hz", ser->input_hertz);
281 print_addr(">PCI addr", ser->uart_pci_addr);
282 }
283
284 print_dec("Mem ranges", info->n_memranges);
285 printf("%12s: %-11s || base || size\n", "id", "type");
286 for (i = 0; i < info->n_memranges; i++) {
287 const struct memrange *mr = &info->memrange[i];
288
289 printf("%12d: %02x:%-8s %016llx %016llx\n", i, mr->type,
290 get_mem_name(mr->type), mr->base, mr->size);
291 }
Simon Glassb57a23b2024-10-14 16:32:08 -0600292 show_option_table(info->option_table);
Simon Glasse1efad22021-03-15 18:00:24 +1300293
294 print_hex("CMOS start", info->cmos_range_start);
295 if (info->cmos_range_start) {
296 print_hex(">CMOS end", info->cmos_range_end);
297 print_hex(">CMOS csum loc", info->cmos_checksum_location);
298 }
299
300 print_hex("VBNV start", info->vbnv_start);
301 print_hex("VBNV size", info->vbnv_size);
302
303 print_str("CB version", info->cb_version);
304 print_str(">Extra", info->extra_version);
305 print_str(">Build", info->build);
306 print_str(">Time", info->compile_time);
307 print_str(">By", info->compile_by);
308 print_str(">Host", info->compile_host);
309 print_str(">Domain", info->compile_domain);
310 print_str(">Compiler", info->compiler);
311 print_str(">Linker", info->linker);
312 print_str(">Assembler", info->assembler);
313
314 print_ptr("Framebuffer", info->framebuffer);
315 if (info->framebuffer) {
316 struct cb_framebuffer *fb = info->framebuffer;
317
318 print_addr64(">Phys addr", fb->physical_address);
319 print_dec(">X res", fb->x_resolution);
320 print_dec(">X res", fb->y_resolution);
321 print_hex(">Bytes / line", fb->bytes_per_line);
322 print_dec(">Bpp", fb->bits_per_pixel);
323 printf(" %-12s red %d/%d, green %d/%d, blue %d/%d, reserved %d/%d\n",
324 "pos/size", fb->red_mask_pos, fb->red_mask_size,
325 fb->green_mask_pos, fb->green_mask_size,
326 fb->blue_mask_pos, fb->blue_mask_size,
327 fb->reserved_mask_pos, fb->reserved_mask_size);
328 }
329
330 print_dec("GPIOs", info->num_gpios);
331 printf("%12s: %4s %12s %3s %s\n", "id", "port", "polarity", "val",
332 "name");
333 for (i = 0; i < info->num_gpios; i++) {
334 const struct cb_gpio *gpio = &info->gpios[i];
335 char portstr[4];
336
337 if (gpio->port == 0xffffffff)
338 strcpy(portstr, "-");
339 else
340 sprintf(portstr, "%x", gpio->port);
341 printf("%12d: %4s %12s %3d %s\n", i, portstr,
342 gpio->polarity == CB_GPIO_ACTIVE_LOW ? "active-low" :
343 "active-high", gpio->value, gpio->name);
344 }
345 print_dec("MACs", info->num_macs);
346 for (i = 0; i < info->num_macs; i++) {
347 const struct mac_address *mac = &info->macs[i];
348 int j;
349
350 printf("%12d: ", i);
351 for (j = 0; j < sizeof(mac->mac_addr); j++)
352 printf("%s%02x", j ? ":" : "", mac->mac_addr[j]);
353 printf("\n");
354 }
355 print_str(">Serial #", info->serialno);
356 print_ptr("Multiboot tab", info->mbtable);
357 print_ptr("CB header", info->header);
358 print_ptr("CB mainboard", info->mainboard);
359 if (info->mainboard) {
360 struct cb_mainboard *mb = info->mainboard;
361
362 print_idx(">vendor", mb->vendor_idx, mb->strings);
363 print_idx(">part_number", mb->part_number_idx, mb->strings);
364 }
365 print_ptr("vboot handoff", info->vboot_handoff);
366 print_hex(">size", info->vboot_handoff_size);
367 print_ptr(">vdat addr", info->vdat_addr);
368 print_hex(">size", info->vdat_size);
369
370 print_addr64("SMBIOS", info->smbios_start);
371 print_hex(">size", info->smbios_size);
372 print_hex("ROM MTRR", info->x86_rom_var_mtrr_index);
373
374 print_ptr("Tstamp table", info->tstamp_table);
375 if (verbose && info->tstamp_table) {
376 struct timestamp_table *ts = info->tstamp_table;
377
378 printf("%-12s", "Base_time");
379 print_grouped_ull(ts->base_time, 12);
380 printf("\n");
381 print_dec("Tick MHz", ts->tick_freq_mhz);
382 for (i = 0; i < ts->num_entries; i++) {
383 const struct timestamp_entry *tse;
384
385 tse = &ts->entries[i];
386 printf(" ");
387 print_grouped_ull(tse->entry_stamp, 12);
388 printf(" %s\n", timestamp_name(tse->entry_id));
389 }
390 }
391
392 print_ptr("CBmem cons", info->cbmem_cons);
393 if (info->cbmem_cons) {
394 struct cbmem_console *cons = info->cbmem_cons;
395 int i;
396
397 print_hex("Size", cons->size);
398 print_hex("Cursor", cons->cursor);
399 if (verbose) {
400 for (i = 0; i < cons->cursor; i++) {
401 int ch = cons->body[i];
402
403 putc(ch);
404
405 if (ch == '\n') {
406 /* check for ctrl-c to abort... */
407 if (ctrlc()) {
408 puts("Abort\n");
409 return;
410 }
411 printf(" ");
412 }
413 }
414 printf("\n");
415 }
416 }
417
418 print_ptr("MRC cache", info->mrc_cache);
419 print_ptr("ACPI GNVS", info->acpi_gnvs);
420 print_hex("Board ID", info->board_id);
421 print_hex("RAM code", info->ram_code);
422 print_ptr("WiFi calib", info->wifi_calibration);
423 print_addr64("Ramoops buff", info->ramoops_buffer);
424 print_hex(">size", info->ramoops_buffer_size);
425 print_hex("SF size", info->spi_flash.size);
426 print_hex("SF sector", info->spi_flash.sector_size);
427 print_hex("SF erase cmd", info->spi_flash.erase_cmd);
428
429 print_addr64("FMAP offset", info->fmap_offset);
430 print_addr64("CBFS offset", info->cbfs_offset);
431 print_addr64("CBFS size", info->cbfs_size);
432 print_addr64("Boot media size", info->boot_media_size);
433 print_addr64("MTC start", info->mtc_start);
434 print_hex("MTC size", info->mtc_size);
435
436 print_ptr("Chrome OS VPD", info->chromeos_vpd);
Simon Glasscf1f4bb2023-05-04 16:54:59 -0600437 print_ptr("RSDP", info->rsdp);
Simon Glassf35f7fa2023-05-04 16:55:06 -0600438 printf("%-12s: ", "Unimpl.");
439 if (info->unimpl_count) {
440 for (i = 0; i < info->unimpl_count; i++)
441 printf("%02x ", info->unimpl[i]);
442 printf("\n");
443 } else {
444 printf("(none)\n");
445 }
Simon Glasse1efad22021-03-15 18:00:24 +1300446}
447
448static int do_cbsysinfo(struct cmd_tbl *cmdtp, int flag, int argc,
449 char *const argv[])
450{
451 bool verbose = false;
452
453 if (argc > 1) {
454 if (!strcmp("-v", argv[1]))
455 verbose = true;
456 else
457 return CMD_RET_USAGE;
458 }
459
460 if (!gd->arch.coreboot_table) {
461 printf("No coreboot sysinfo table found\n");
462 return CMD_RET_FAILURE;
463 }
464 show_table(&lib_sysinfo, verbose);
465
466 return 0;
467}
468
469U_BOOT_CMD(
470 cbsysinfo, 2, 1, do_cbsysinfo,
471 "Show coreboot sysinfo table",
472 "[-v] Dumps out the contents of the sysinfo table. This only\n"
473 "works if U-Boot is booted from coreboot"
474);