arch/arm64: Support FEAT_CCIDX
[coreboot2.git] / util / nvramtool / lbtable.c
blob6993cc0ce5d2c6a7c0dfb2577958aa51c2177beb
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <stdint.h>
4 #include <inttypes.h>
5 #include <string.h>
6 #ifndef __MINGW32__
7 #include <sys/mman.h>
8 #endif
9 #include "common.h"
10 #include "coreboot_tables.h"
11 #include "ip_checksum.h"
12 #include "lbtable.h"
13 #include "layout.h"
14 #include "cmos_lowlevel.h"
15 #include "hexdump.h"
16 #include "cbfs.h"
18 typedef void (*lbtable_print_fn_t) (const struct lb_record * rec);
20 /* This structure represents an item in the coreboot table that may be
21 * displayed using the -l option.
23 typedef struct {
24 uint32_t tag;
25 const char *name;
26 const char *description;
27 const char *nofound_msg;
28 lbtable_print_fn_t print_fn;
29 } lbtable_choice_t;
31 typedef struct {
32 unsigned long start; /* address of first byte of memory range */
33 unsigned long end; /* address of last byte of memory range */
34 } mem_range_t;
36 static const struct lb_header *lbtable_scan(unsigned long start,
37 unsigned long end,
38 int *bad_header_count,
39 int *bad_table_count);
40 static const char *lbrec_tag_to_str(uint32_t tag);
41 static void memory_print_fn(const struct lb_record *rec);
42 static void mainboard_print_fn(const struct lb_record *rec);
43 static void cmos_opt_table_print_fn(const struct lb_record *rec);
44 static void print_option_record(const struct cmos_entries *cmos_entry);
45 static void print_enum_record(const struct cmos_enums *cmos_enum);
46 static void print_defaults_record(const struct cmos_defaults *cmos_defaults);
47 static void print_unknown_record(const struct lb_record *cmos_item);
48 static void option_checksum_print_fn(const struct lb_record *rec);
49 static void string_print_fn(const struct lb_record *rec);
51 static const char memory_desc[] =
52 " This shows information about system memory.\n";
54 static const char mainboard_desc[] =
55 " This shows information about your mainboard.\n";
57 static const char version_desc[] =
58 " This shows coreboot version information.\n";
60 static const char extra_version_desc[] =
61 " This shows extra coreboot version information.\n";
63 static const char build_desc[] = " This shows coreboot build information.\n";
65 static const char compile_time_desc[] =
66 " This shows when coreboot was compiled.\n";
68 static const char compile_by_desc[] = " This shows who compiled coreboot.\n";
70 static const char compile_host_desc[] =
71 " This shows the name of the machine that compiled coreboot.\n";
73 static const char compile_domain_desc[] =
74 " This shows the domain name of the machine that compiled coreboot.\n";
76 static const char compiler_desc[] =
77 " This shows the name of the compiler used to build coreboot.\n";
79 static const char linker_desc[] =
80 " This shows the name of the linker used to build coreboot.\n";
82 static const char assembler_desc[] =
83 " This shows the name of the assembler used to build coreboot.\n";
85 static const char cmos_opt_table_desc[] =
86 " This does a low-level dump of the CMOS option table. The table "
87 "contains\n"
88 " information about the layout of the values that coreboot stores in\n"
89 " nonvolatile RAM.\n";
91 static const char option_checksum_desc[] =
92 " This shows the location of the CMOS checksum and the area over which it "
93 "is\n" " calculated.\n";
95 static const char generic_nofound_msg[] =
96 "%s: Item %s not found in coreboot table.\n";
98 static const char nofound_msg_cmos_opt_table[] =
99 "%s: Item %s not found in coreboot table. Apparently, the "
100 "coreboot installed on this system was built without specifying "
101 "CONFIG_HAVE_OPTION_TABLE.\n";
103 static const char nofound_msg_option_checksum[] =
104 "%s: Item %s not found in coreboot table. Apparently, you are "
105 "using coreboot v1.\n";
107 int fd;
109 /* This is the number of items from the coreboot table that may be displayed
110 * using the -l option.
112 #define NUM_LBTABLE_CHOICES 14
114 /* These represent the various items from the coreboot table that may be
115 * displayed using the -l option.
117 static const lbtable_choice_t lbtable_choices[NUM_LBTABLE_CHOICES] =
118 { {LB_TAG_MEMORY, "memory",
119 memory_desc, generic_nofound_msg,
120 memory_print_fn},
121 {LB_TAG_MAINBOARD, "mainboard",
122 mainboard_desc, generic_nofound_msg,
123 mainboard_print_fn},
124 {LB_TAG_VERSION, "version",
125 version_desc, generic_nofound_msg,
126 string_print_fn},
127 {LB_TAG_EXTRA_VERSION, "extra_version",
128 extra_version_desc, generic_nofound_msg,
129 string_print_fn},
130 {LB_TAG_BUILD, "build",
131 build_desc, generic_nofound_msg,
132 string_print_fn},
133 {LB_TAG_COMPILE_TIME, "compile_time",
134 compile_time_desc, generic_nofound_msg,
135 string_print_fn},
136 {LB_TAG_COMPILE_BY, "compile_by",
137 compile_by_desc, generic_nofound_msg,
138 string_print_fn},
139 {LB_TAG_COMPILE_HOST, "compile_host",
140 compile_host_desc, generic_nofound_msg,
141 string_print_fn},
142 {LB_TAG_COMPILE_DOMAIN, "compile_domain",
143 compile_domain_desc, generic_nofound_msg,
144 string_print_fn},
145 {LB_TAG_COMPILER, "compiler",
146 compiler_desc, generic_nofound_msg,
147 string_print_fn},
148 {LB_TAG_LINKER, "linker",
149 linker_desc, generic_nofound_msg,
150 string_print_fn},
151 {LB_TAG_ASSEMBLER, "assembler",
152 assembler_desc, generic_nofound_msg,
153 string_print_fn},
154 {LB_TAG_CMOS_OPTION_TABLE, "cmos_opt_table",
155 cmos_opt_table_desc, nofound_msg_cmos_opt_table,
156 cmos_opt_table_print_fn},
157 {LB_TAG_OPTION_CHECKSUM, "option_checksum",
158 option_checksum_desc, nofound_msg_option_checksum,
159 option_checksum_print_fn}
162 /* The coreboot table resides in low physical memory, which we access using
163 * /dev/mem. These are ranges of physical memory that should be scanned for a
164 * coreboot table.
167 #define NUM_MEM_RANGES 2
169 static const mem_range_t mem_ranges[NUM_MEM_RANGES] =
170 { {0x00000000, 0x00000fff},
171 {0x000f0000, 0x000fffff}
174 /* Pointer to low physical memory that we access by calling mmap() on
175 * /dev/mem.
177 static const void *low_phys_mem;
178 /* impossible value since not page aligned: first map request will happen */
179 static unsigned long low_phys_base = 0x1;
181 /* count of mapped pages */
182 static unsigned long mapped_pages = 0;
184 /* Pointer to coreboot table. */
185 static const struct lb_header *lbtable = NULL;
187 static const hexdump_format_t format =
188 { 12, 4, " ", " | ", " ", " | ", '.' };
190 /****************************************************************************
191 * vtophys
193 * Convert a virtual address to a physical address. 'vaddr' is a virtual
194 * address in the address space of the current process. It points to
195 * somewhere in the chunk of memory that we mapped by calling mmap() on
196 * /dev/mem. This macro converts 'vaddr' to a physical address.
197 ****************************************************************************/
198 #define vtophys(vaddr) (((unsigned long) vaddr) - \
199 ((unsigned long) low_phys_mem) + low_phys_base)
201 /****************************************************************************
202 * phystov
204 * Convert a physical address to a virtual address. 'paddr' is a physical
205 * address. This macro converts 'paddr' to a virtual address in the address
206 * space of the current process. The virtual to physical mapping was set up
207 * by calling mmap() on /dev/mem.
208 ****************************************************************************/
209 #define phystov(paddr) (((unsigned long) low_phys_mem) + \
210 ((unsigned long) paddr) - low_phys_base)
212 /****************************************************************************
213 * map_pages
215 * Maps just enough pages to cover base_address + length
216 * and updates affected variables
217 ****************************************************************************/
218 static void map_pages(unsigned long base_address, unsigned long length)
220 unsigned long num_pages = (length +
221 (base_address & (getpagesize() - 1)) +
222 getpagesize() - 1) >> 12;
223 base_address &= ~(getpagesize() - 1);
225 /* no need to do anything */
226 if ((low_phys_base == base_address) && (mapped_pages == num_pages)) {
227 return;
230 if (low_phys_mem) {
231 munmap((void *)low_phys_mem, mapped_pages << 12);
233 if ((low_phys_mem = mmap(NULL, num_pages << 12, PROT_READ, MAP_SHARED, fd,
234 (off_t) base_address)) == MAP_FAILED) {
235 fprintf(stderr,
236 "%s: Failed to mmap /dev/mem at %lx: %s\n",
237 prog_name, base_address, strerror(errno));
238 exit(1);
240 low_phys_base = base_address;
243 /****************************************************************************
244 * get_lbtable
246 * Find the coreboot table and set global variable lbtable to point to it.
247 ****************************************************************************/
248 void get_lbtable(void)
250 int i, bad_header_count, bad_table_count, bad_headers, bad_tables;
252 if (lbtable != NULL)
253 return;
255 /* The coreboot table is located in low physical memory, which may be
256 * conveniently accessed by calling mmap() on /dev/mem.
259 if ((fd = open("/dev/mem", O_RDONLY, 0)) < 0) {
260 fprintf(stderr, "%s: Can not open /dev/mem for reading: %s\n",
261 prog_name, strerror(errno));
262 exit(1);
265 bad_header_count = 0;
266 bad_table_count = 0;
268 for (i = 0; i < NUM_MEM_RANGES; i++) {
269 lbtable = lbtable_scan(mem_ranges[i].start, mem_ranges[i].end,
270 &bad_headers, &bad_tables);
272 if (lbtable != NULL)
273 return; /* success: we found it! */
275 bad_header_count += bad_headers;
276 bad_table_count += bad_tables;
279 fprintf(stderr,
280 "%s: coreboot table not found. coreboot does not appear to\n"
281 " be installed on this system. Scanning for the table "
282 "produced the\n"
283 " following results:\n\n"
284 " %d valid signatures were found with bad header "
285 "checksums.\n"
286 " %d valid headers were found with bad table "
287 "checksums.\n", prog_name, bad_header_count, bad_table_count);
288 exit(1);
291 /****************************************************************************
292 * dump_lbtable
294 * Do a low-level dump of the coreboot table.
295 ****************************************************************************/
296 void dump_lbtable(void)
298 const char *p, *data;
299 uint32_t bytes_processed;
300 const struct lb_record *lbrec;
302 p = ((const char *)lbtable) + lbtable->header_bytes;
303 printf("coreboot table at physical address 0x%lx:\n"
304 " signature: 0x%x (ASCII: %c%c%c%c)\n"
305 " header_bytes: 0x%x (decimal: %d)\n"
306 " header_checksum: 0x%x (decimal: %d)\n"
307 " table_bytes: 0x%x (decimal: %d)\n"
308 " table_checksum: 0x%x (decimal: %d)\n"
309 " table_entries: 0x%x (decimal: %d)\n\n",
310 vtophys(lbtable), lbtable->signature32,
311 lbtable->signature[0], lbtable->signature[1],
312 lbtable->signature[2], lbtable->signature[3],
313 lbtable->header_bytes, lbtable->header_bytes,
314 lbtable->header_checksum, lbtable->header_checksum,
315 lbtable->table_bytes, lbtable->table_bytes,
316 lbtable->table_checksum, lbtable->table_checksum,
317 lbtable->table_entries, lbtable->table_entries);
319 if ((lbtable->table_bytes == 0) != (lbtable->table_entries == 0)) {
320 printf
321 ("Inconsistent values for table_bytes and table_entries!!!\n"
322 "They should be either both 0 or both nonzero.\n");
323 return;
326 if (lbtable->table_bytes == 0) {
327 printf("The coreboot table is empty!!!\n");
328 return;
331 for (bytes_processed = 0;;) {
332 lbrec = (const struct lb_record *)&p[bytes_processed];
333 printf(" %s record at physical address 0x%lx:\n"
334 " tag: 0x%x (decimal: %d)\n"
335 " size: 0x%x (decimal: %d)\n"
336 " data:\n",
337 lbrec_tag_to_str(lbrec->tag), vtophys(lbrec), lbrec->tag,
338 lbrec->tag, lbrec->size, lbrec->size);
340 data = ((const char *)lbrec) + sizeof(*lbrec);
341 hexdump(data, lbrec->size - sizeof(*lbrec), vtophys(data),
342 stdout, &format);
344 bytes_processed += lbrec->size;
346 if (bytes_processed >= lbtable->table_bytes)
347 break;
349 printf("\n");
353 /****************************************************************************
354 * list_lbtable_choices
356 * List names and informational blurbs for items from the coreboot table
357 * that may be displayed using the -l option.
358 ****************************************************************************/
359 void list_lbtable_choices(void)
361 int i;
363 for (i = 0;;) {
364 printf("%s:\n%s",
365 lbtable_choices[i].name, lbtable_choices[i].description);
367 if (++i >= NUM_LBTABLE_CHOICES)
368 break;
370 printf("\n");
374 /****************************************************************************
375 * list_lbtable_item
377 * Show the coreboot table item specified by 'item'.
378 ****************************************************************************/
379 void list_lbtable_item(const char item[])
381 int i;
382 const struct lb_record *rec;
384 for (i = 0; i < NUM_LBTABLE_CHOICES; i++) {
385 if (strcmp(item, lbtable_choices[i].name) == 0)
386 break;
389 if (i == NUM_LBTABLE_CHOICES) {
390 fprintf(stderr, "%s: Invalid coreboot table item %s.\n",
391 prog_name, item);
392 exit(1);
395 if ((rec = find_lbrec(lbtable_choices[i].tag)) == NULL) {
396 fprintf(stderr, lbtable_choices[i].nofound_msg, prog_name,
397 lbtable_choices[i].name);
398 exit(1);
401 lbtable_choices[i].print_fn(rec);
404 /****************************************************************************
405 * lbtable_scan
407 * Scan the chunk of memory specified by 'start' and 'end' for a coreboot
408 * table. The first 4 bytes of the table are marked by the signature
409 * { 'L', 'B', 'I', 'O' }. 'start' and 'end' indicate the addresses of the
410 * first and last bytes of the chunk of memory to be scanned. For instance,
411 * values of 0x10000000 and 0x1000ffff for 'start' and 'end' specify a 64k
412 * chunk of memory starting at address 0x10000000. 'start' and 'end' are
413 * physical addresses.
415 * If a coreboot table is found, return a pointer to it. Otherwise return
416 * NULL. On return, *bad_header_count and *bad_table_count are set as
417 * follows:
419 * *bad_header_count:
420 * Indicates the number of times in which a valid signature was found
421 * but the header checksum was invalid.
423 * *bad_table_count:
424 * Indicates the number of times in which a header with a valid
425 * checksum was found but the table checksum was invalid.
426 ****************************************************************************/
427 static const struct lb_header *lbtable_scan(unsigned long start,
428 unsigned long end,
429 int *bad_header_count,
430 int *bad_table_count)
432 static const char signature[4] = { 'L', 'B', 'I', 'O' };
433 const struct lb_header *table;
434 const struct lb_forward *forward;
435 unsigned long p;
436 uint32_t sig;
438 assert(end >= start);
439 memcpy(&sig, signature, sizeof(sig));
440 table = NULL;
441 *bad_header_count = 0;
442 *bad_table_count = 0;
444 /* Look for signature. Table is aligned on 16-byte boundary. Therefore
445 * only check every fourth 32-bit memory word. As the loop is coded below,
446 * this function will behave in a reasonable manner for ALL possible values
447 * for 'start' and 'end': even weird boundary cases like 0x00000000 and
448 * 0xffffffff on a 32-bit architecture.
450 map_pages(start, end - start);
451 for (p = start;
452 (p <= end) &&
453 (end - p >= (sizeof(uint32_t) - 1)); p += 4) {
454 if (*(uint32_t*)phystov(p) != sig)
455 continue;
457 /* We found a valid signature. */
458 table = (const struct lb_header *)phystov(p);
460 /* validate header checksum */
461 if (compute_ip_checksum((void *)table, sizeof(*table))) {
462 (*bad_header_count)++;
463 continue;
466 map_pages(p, table->table_bytes + sizeof(*table));
468 table = (const struct lb_header *)phystov(p);
470 /* validate table checksum */
471 if (table->table_checksum !=
472 compute_ip_checksum(((char *)table) + sizeof(*table),
473 table->table_bytes)) {
474 (*bad_table_count)++;
475 continue;
478 /* checksums are ok: we found it! */
479 /* But it may just be a forwarding table, so look if there's a forwarder */
480 lbtable = table;
481 forward = (struct lb_forward *)find_lbrec(LB_TAG_FORWARD);
482 lbtable = NULL;
484 if (forward) {
485 uint64_t new_phys = forward->forward;
486 table = lbtable_scan(new_phys, new_phys + getpagesize(),
487 bad_header_count, bad_table_count);
489 return table;
492 return NULL;
495 /****************************************************************************
496 * find_lbrec
498 * Find the record in the coreboot table that matches 'tag'. Return pointer
499 * to record on success or NULL if record not found.
500 ****************************************************************************/
501 const struct lb_record *find_lbrec(uint32_t tag)
503 const char *p;
504 uint32_t bytes_processed;
505 const struct lb_record *lbrec;
507 p = ((const char *)lbtable) + lbtable->header_bytes;
509 for (bytes_processed = 0;
510 bytes_processed < lbtable->table_bytes;
511 bytes_processed += lbrec->size) {
512 lbrec = (const struct lb_record *)&p[bytes_processed];
514 if (lbrec->tag == tag)
515 return lbrec;
518 return NULL;
521 /****************************************************************************
522 * lbrec_tag_to_str
524 * Return a pointer to the string representation of the given coreboot table
525 * tag.
526 ****************************************************************************/
527 static const char *lbrec_tag_to_str(uint32_t tag)
529 switch (tag) {
530 case LB_TAG_UNUSED:
531 return "UNUSED";
533 case LB_TAG_MEMORY:
534 return "MEMORY";
536 case LB_TAG_HWRPB:
537 return "HWRPB";
539 case LB_TAG_MAINBOARD:
540 return "MAINBOARD";
542 case LB_TAG_VERSION:
543 return "VERSION";
545 case LB_TAG_EXTRA_VERSION:
546 return "EXTRA_VERSION";
548 case LB_TAG_BUILD:
549 return "BUILD";
551 case LB_TAG_COMPILE_TIME:
552 return "COMPILE_TIME";
554 case LB_TAG_COMPILE_BY:
555 return "COMPILE_BY";
557 case LB_TAG_COMPILE_HOST:
558 return "COMPILE_HOST";
560 case LB_TAG_COMPILE_DOMAIN:
561 return "COMPILE_DOMAIN";
563 case LB_TAG_COMPILER:
564 return "COMPILER";
566 case LB_TAG_LINKER:
567 return "LINKER";
569 case LB_TAG_ASSEMBLER:
570 return "ASSEMBLER";
572 case LB_TAG_SERIAL:
573 return "SERIAL";
575 case LB_TAG_CONSOLE:
576 return "CONSOLE";
578 case LB_TAG_FORWARD:
579 return "FORWARD";
581 case LB_TAG_CMOS_OPTION_TABLE:
582 return "CMOS_OPTION_TABLE";
584 case LB_TAG_OPTION_CHECKSUM:
585 return "OPTION_CHECKSUM";
587 default:
588 break;
591 return "UNKNOWN";
594 /****************************************************************************
595 * memory_print_fn
597 * Display function for 'memory' item of coreboot table.
598 ****************************************************************************/
599 static void memory_print_fn(const struct lb_record *rec)
601 const struct lb_memory *p;
602 const char *mem_type;
603 const struct lb_memory_range *ranges;
604 uint64_t size, start, end;
605 int i, entries;
607 p = (const struct lb_memory *)rec;
608 entries = (p->size - sizeof(*p)) / sizeof(p->map[0]);
609 ranges = p->map;
611 if (entries == 0) {
612 printf("No memory ranges were found.\n");
613 return;
616 for (i = 0;;) {
617 switch (ranges[i].type) {
618 case LB_MEM_RAM:
619 mem_type = "AVAILABLE";
620 break;
622 case LB_MEM_RESERVED:
623 mem_type = "RESERVED";
624 break;
626 case LB_MEM_TABLE:
627 mem_type = "CONFIG_TABLE";
628 break;
630 default:
631 mem_type = "UNKNOWN";
632 break;
635 size = ranges[i].size;
636 start = ranges[i].start;
637 end = start + size - 1;
638 printf("%s memory:\n"
639 " from physical addresses 0x%016" PRIx64
640 " to 0x%016" PRIx64 "\n size is 0x%016" PRIx64
641 " bytes (%" PRId64 " in decimal)\n",
642 mem_type, start, end, size, size);
644 if (++i >= entries)
645 break;
647 printf("\n");
651 /****************************************************************************
652 * mainboard_print_fn
654 * Display function for 'mainboard' item of coreboot table.
655 ****************************************************************************/
656 static void mainboard_print_fn(const struct lb_record *rec)
658 const struct lb_mainboard *p;
660 p = (const struct lb_mainboard *)rec;
661 printf("Vendor: %s\n"
662 "Part number: %s\n",
663 &p->strings[p->vendor_idx], &p->strings[p->part_number_idx]);
666 /****************************************************************************
667 * cmos_opt_table_print_fn
669 * Display function for 'cmos_opt_table' item of coreboot table.
670 ****************************************************************************/
671 static void cmos_opt_table_print_fn(const struct lb_record *rec)
673 const struct cmos_option_table *p;
674 const struct lb_record *cmos_item;
675 uint32_t bytes_processed, bytes_for_entries;
676 const char *q;
678 p = (const struct cmos_option_table *)rec;
679 q = ((const char *)p) + p->header_length;
680 bytes_for_entries = p->size - p->header_length;
682 printf("CMOS option table at physical address 0x%lx:\n"
683 " tag: 0x%x (decimal: %d)\n"
684 " size: 0x%x (decimal: %d)\n"
685 " header_length: 0x%x (decimal: %d)\n\n",
686 vtophys(p), p->tag, p->tag, p->size, p->size, p->header_length,
687 p->header_length);
689 if (p->header_length > p->size) {
690 printf
691 ("Header length for CMOS option table is greater than the size "
692 "of the entire table including header!!!\n");
693 return;
696 if (bytes_for_entries == 0) {
697 printf("The CMOS option table is empty!!!\n");
698 return;
701 for (bytes_processed = 0;;) {
702 cmos_item = (const struct lb_record *)&q[bytes_processed];
704 switch (cmos_item->tag) {
705 case LB_TAG_OPTION:
706 print_option_record((const struct cmos_entries *)
707 cmos_item);
708 break;
710 case LB_TAG_OPTION_ENUM:
711 print_enum_record((const struct cmos_enums *)cmos_item);
712 break;
714 case LB_TAG_OPTION_DEFAULTS:
715 print_defaults_record((const struct cmos_defaults *)
716 cmos_item);
717 break;
719 default:
720 print_unknown_record(cmos_item);
721 break;
724 bytes_processed += cmos_item->size;
726 if (bytes_processed >= bytes_for_entries)
727 break;
729 printf("\n");
733 /****************************************************************************
734 * print_option_record
736 * Display "option" record from CMOS option table.
737 ****************************************************************************/
738 static void print_option_record(const struct cmos_entries *cmos_entry)
740 static const size_t S_BUFSIZE = 80;
741 char s[S_BUFSIZE];
743 switch (cmos_entry->config) {
744 case 'e':
745 strcpy(s, "ENUM");
746 break;
748 case 'h':
749 strcpy(s, "HEX");
750 break;
752 case 'r':
753 strcpy(s, "RESERVED");
754 break;
756 default:
757 snprintf(s, S_BUFSIZE, "UNKNOWN: value is 0x%x (decimal: %d)",
758 cmos_entry->config, cmos_entry->config);
759 break;
762 printf(" OPTION record at physical address 0x%lx:\n"
763 " tag: 0x%x (decimal: %d)\n"
764 " size: 0x%x (decimal: %d)\n"
765 " bit: 0x%x (decimal: %d)\n"
766 " length: 0x%x (decimal: %d)\n"
767 " config: %s\n"
768 " config_id: 0x%x (decimal: %d)\n"
769 " name: %s\n",
770 vtophys(cmos_entry), cmos_entry->tag, cmos_entry->tag,
771 cmos_entry->size, cmos_entry->size, cmos_entry->bit,
772 cmos_entry->bit, cmos_entry->length, cmos_entry->length, s,
773 cmos_entry->config_id, cmos_entry->config_id, cmos_entry->name);
776 /****************************************************************************
777 * print_enum_record
779 * Display "enum" record from CMOS option table.
780 ****************************************************************************/
781 static void print_enum_record(const struct cmos_enums *cmos_enum)
783 printf(" ENUM record at physical address 0x%lx:\n"
784 " tag: 0x%x (decimal: %d)\n"
785 " size: 0x%x (decimal: %d)\n"
786 " config_id: 0x%x (decimal: %d)\n"
787 " value: 0x%x (decimal: %d)\n"
788 " text: %s\n",
789 vtophys(cmos_enum), cmos_enum->tag, cmos_enum->tag,
790 cmos_enum->size, cmos_enum->size, cmos_enum->config_id,
791 cmos_enum->config_id, cmos_enum->value, cmos_enum->value,
792 cmos_enum->text);
795 /****************************************************************************
796 * print_defaults_record
798 * Display "defaults" record from CMOS option table.
799 ****************************************************************************/
800 static void print_defaults_record(const struct cmos_defaults *cmos_defaults)
802 printf(" DEFAULTS record at physical address 0x%lx:\n"
803 " tag: 0x%x (decimal: %d)\n"
804 " size: 0x%x (decimal: %d)\n"
805 " name_length: 0x%x (decimal: %d)\n"
806 " name: %s\n"
807 " default_set:\n",
808 vtophys(cmos_defaults), cmos_defaults->tag, cmos_defaults->tag,
809 cmos_defaults->size, cmos_defaults->size,
810 cmos_defaults->name_length, cmos_defaults->name_length,
811 cmos_defaults->name);
812 hexdump(cmos_defaults->default_set, CMOS_IMAGE_BUFFER_SIZE,
813 vtophys(cmos_defaults->default_set), stdout, &format);
816 /****************************************************************************
817 * print_unknown_record
819 * Display record of unknown type from CMOS option table.
820 ****************************************************************************/
821 static void print_unknown_record(const struct lb_record *cmos_item)
823 const char *data;
825 printf(" UNKNOWN record at physical address 0x%lx:\n"
826 " tag: 0x%x (decimal: %d)\n"
827 " size: 0x%x (decimal: %d)\n"
828 " data:\n",
829 vtophys(cmos_item), cmos_item->tag, cmos_item->tag,
830 cmos_item->size, cmos_item->size);
831 data = ((const char *)cmos_item) + sizeof(*cmos_item);
832 hexdump(data, cmos_item->size - sizeof(*cmos_item), vtophys(data),
833 stdout, &format);
836 /****************************************************************************
837 * option_checksum_print_fn
839 * Display function for 'option_checksum' item of coreboot table.
840 ****************************************************************************/
841 static void option_checksum_print_fn(const struct lb_record *rec)
843 struct cmos_checksum *p;
845 p = (struct cmos_checksum *)rec;
846 printf("CMOS checksum from bit %d to bit %d\n"
847 "at position %d is type %s.\n",
848 p->range_start, p->range_end, p->location,
849 (p->type == CHECKSUM_PCBIOS) ? "PC BIOS" : "NONE");
852 /****************************************************************************
853 * string_print_fn
855 * Display function for a generic item of coreboot table that simply
856 * consists of a string.
857 ****************************************************************************/
858 static void string_print_fn(const struct lb_record *rec)
860 const struct lb_string *p;
862 p = (const struct lb_string *)rec;
863 printf("%s\n", p->string);