treewide: Move device_tree to commonlib
[coreboot2.git] / payloads / coreinfo / coreboot_module.c
blobc038d624872432498528563da16a7497c351d184
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include "coreinfo.h"
4 #include <coreboot_tables.h>
6 #if CONFIG(MODULE_COREBOOT)
8 #define MAX_MEMORY_COUNT 5
10 static struct {
11 int mem_count;
12 int mem_actual;
14 struct cb_memory_range range[MAX_MEMORY_COUNT];
16 char vendor[32];
17 char part[32];
19 char strings[10][64];
21 struct cb_serial serial;
22 struct cb_console console;
23 } cb_info;
25 static int tables_good = 0;
27 static int coreboot_module_redraw(WINDOW *win)
29 int row = 2;
30 int i;
32 print_module_title(win, "coreboot Tables");
34 if (tables_good) {
35 mvwprintw(win, row++, 1, "No coreboot tables were found");
36 return 0;
39 mvwprintw(win, row++, 1, "Vendor: %s", cb_info.vendor);
40 mvwprintw(win, row++, 1, "Part: %s", cb_info.part);
42 mvwprintw(win, row++, 1, "Version: %s%s",
43 cb_info.strings[CB_TAG_VERSION - 0x4],
44 cb_info.strings[CB_TAG_EXTRA_VERSION - 0x4]);
46 mvwprintw(win, row++, 1, "Built: %s (%s@%s.%s)",
47 cb_info.strings[CB_TAG_BUILD - 0x4],
48 cb_info.strings[CB_TAG_COMPILE_BY - 0x04],
49 cb_info.strings[CB_TAG_COMPILE_HOST - 0x04],
50 cb_info.strings[CB_TAG_COMPILE_DOMAIN - 0x04]);
52 if (cb_info.serial.tag != 0x0) {
53 mvwprintw(win, row++, 1, "Serial Port I/O base: 0x%x",
54 cb_info.serial.baseaddr);
57 if (cb_info.console.tag != 0x0) {
58 mvwprintw(win, row++, 1, "Default Output Console: ");
60 switch (cb_info.console.type) {
61 case CB_TAG_CONSOLE_SERIAL8250:
62 wprintw(win, "Serial Port");
63 break;
64 case CB_TAG_CONSOLE_VGA:
65 wprintw(win, "VGA");
66 break;
67 case CB_TAG_CONSOLE_BTEXT:
68 wprintw(win, "BTEXT");
69 break;
70 case CB_TAG_CONSOLE_LOGBUF:
71 wprintw(win, "Log Buffer");
72 break;
73 case CB_TAG_CONSOLE_SROM:
74 wprintw(win, "Serial ROM");
75 break;
76 case CB_TAG_CONSOLE_EHCI:
77 wprintw(win, "USB Debug");
78 break;
82 row++;
83 mvwprintw(win, row++, 1, "-- Memory Map --");
85 for (i = 0; i < cb_info.mem_count; i++) {
86 switch (cb_info.range[i].type) {
87 case CB_MEM_RAM:
88 mvwprintw(win, row++, 3, " RAM: ");
89 break;
90 case CB_MEM_RESERVED:
91 mvwprintw(win, row++, 3, "Reserved: ");
92 break;
93 case CB_MEM_TABLE:
94 mvwprintw(win, row++, 3, " Table: ");
97 wprintw(win, "%16.16llx - %16.16llx", cb_info.range[i].start,
98 cb_info.range[i].start + cb_info.range[i].size - 1);
101 return 0;
104 static void parse_memory(unsigned char *ptr)
106 struct cb_memory *mem = (struct cb_memory *)ptr;
107 int max = (MEM_RANGE_COUNT(mem) > MAX_MEMORY_COUNT)
108 ? MAX_MEMORY_COUNT : MEM_RANGE_COUNT(mem);
109 int i;
111 for (i = 0; i < max; i++) {
112 struct cb_memory_range *range =
113 (struct cb_memory_range *)MEM_RANGE_PTR(mem, i);
115 memcpy(&cb_info.range[i], range, sizeof(*range));
118 cb_info.mem_count = max;
119 cb_info.mem_actual = MEM_RANGE_COUNT(mem);
122 static void parse_mainboard(unsigned char *ptr)
124 struct cb_mainboard *mb = (struct cb_mainboard *)ptr;
126 strncpy(cb_info.vendor, cb_mb_vendor_string(mb), sizeof(cb_info.vendor) - 1);
127 strncpy(cb_info.part, cb_mb_part_string(mb), sizeof(cb_info.part) - 1);
130 static void parse_strings(unsigned char *ptr)
132 struct cb_string *string = (struct cb_string *)ptr;
133 int index = string->tag - CB_TAG_VERSION;
135 strncpy(cb_info.strings[index], (const char *)string->string, 63);
136 cb_info.strings[index][63] = 0;
139 static void parse_serial(unsigned char *ptr)
141 memcpy(&cb_info.serial, (struct cb_serial *)ptr,
142 sizeof(struct cb_serial));
145 static void parse_console(unsigned char *ptr)
147 memcpy(&cb_info.console, (struct cb_console *)ptr,
148 sizeof(struct cb_console));
151 static int parse_header(void *addr, int len)
153 struct cb_header *header;
154 unsigned char *ptr = (unsigned char *)addr;
155 int i;
157 for (i = 0; i < len; i += 16, ptr += 16) {
158 header = (struct cb_header *)ptr;
160 if (!strncmp((const char *)header->signature, "LBIO", 4))
161 break;
164 /* We walked the entire space and didn't find anything. */
165 if (i >= len)
166 return -1;
168 if (!header->table_bytes)
169 return 0;
171 /* FIXME: Check the checksum. */
173 if (cb_checksum(header, sizeof(*header)))
174 return -1;
176 if (cb_checksum((ptr + sizeof(*header)), header->table_bytes)
177 != header->table_checksum)
178 return -1;
180 /* Now, walk the tables. */
181 ptr += header->header_bytes;
183 for (u32 j = 0; j < header->table_entries; j++) {
184 struct cb_record *rec = (struct cb_record *)ptr;
186 switch (rec->tag) {
187 case CB_TAG_FORWARD:
188 return parse_header((void *)(unsigned long)((struct cb_forward *)rec)->forward, 1);
189 case CB_TAG_MEMORY:
190 parse_memory(ptr);
191 break;
192 case CB_TAG_MAINBOARD:
193 parse_mainboard(ptr);
194 break;
195 case CB_TAG_VERSION:
196 case CB_TAG_EXTRA_VERSION:
197 case CB_TAG_BUILD:
198 case CB_TAG_COMPILE_TIME:
199 case CB_TAG_COMPILE_BY:
200 case CB_TAG_COMPILE_HOST:
201 case CB_TAG_COMPILE_DOMAIN:
202 case CB_TAG_COMPILER:
203 case CB_TAG_LINKER:
204 case CB_TAG_ASSEMBLER:
205 parse_strings(ptr);
206 break;
207 case CB_TAG_SERIAL:
208 parse_serial(ptr);
209 break;
210 case CB_TAG_CONSOLE:
211 parse_console(ptr);
212 break;
213 default:
214 break;
217 ptr += rec->size;
220 return 1;
223 static int coreboot_module_init(void)
225 int ret = parse_header((void *)0x00000, 0x1000);
227 if (ret != 1)
228 ret = parse_header((void *)0xf0000, 0x1000);
230 /* Return error if we couldn't find it at either address. */
231 tables_good = (ret == 1) ? 0 : -1;
232 return tables_good;
235 struct coreinfo_module coreboot_module = {
236 .name = "coreboot",
237 .init = coreboot_module_init,
238 .redraw = coreboot_module_redraw,
241 #else
243 struct coreinfo_module coreboot_module = {
246 #endif