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