cbsysinfo.c 12 KB

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