blob: 0b6cca8c31962b523ed5f240d4f866cbe4afdf2d [file] [log] [blame]
Jordan Crouse7249f792008-03-20 00:11:05 +00001/*
2 * This file is part of the coreinfo project.
3 *
4 * Copyright (C) 2008 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Jordan Crouse7249f792008-03-20 00:11:05 +000014 */
15
Jordan Crouse7249f792008-03-20 00:11:05 +000016#include "coreinfo.h"
Philip Prindevillefe2f6b02011-12-23 17:22:05 -070017#include <coreboot_tables.h>
Jordan Crouse7249f792008-03-20 00:11:05 +000018
Stefan Reinauer04fb7a82015-06-29 16:08:39 -070019#if IS_ENABLED(CONFIG_MODULE_COREBOOT)
Uwe Hermannab5b3e02008-03-31 20:30:18 +000020
Jordan Crouse7249f792008-03-20 00:11:05 +000021#define MAX_MEMORY_COUNT 5
22
23static struct {
24 int mem_count;
25 int mem_actual;
26
27 struct cb_memory_range range[MAX_MEMORY_COUNT];
28
29 char vendor[32];
30 char part[32];
31
32 char strings[10][64];
Uwe Hermann3a406fe2008-03-20 01:11:28 +000033
Jordan Crouse7249f792008-03-20 00:11:05 +000034 struct cb_serial serial;
35 struct cb_console console;
36} cb_info;
37
38static int tables_good = 0;
39
Uwe Hermann3a406fe2008-03-20 01:11:28 +000040int coreboot_module_redraw(WINDOW *win)
Jordan Crouse7249f792008-03-20 00:11:05 +000041{
42 int row = 2;
43 int i;
44
45 print_module_title(win, "Coreboot Tables");
46
47 if (tables_good) {
Uwe Hermanna0c00932008-03-27 20:46:49 +000048 mvwprintw(win, row++, 1, "No Coreboot tables were found");
Jordan Crouse7249f792008-03-20 00:11:05 +000049 return 0;
50 }
Uwe Hermann3a406fe2008-03-20 01:11:28 +000051
Uwe Hermanna0c00932008-03-27 20:46:49 +000052 mvwprintw(win, row++, 1, "Vendor: %s", cb_info.vendor);
53 mvwprintw(win, row++, 1, "Part: %s", cb_info.part);
Jordan Crouse7249f792008-03-20 00:11:05 +000054
Uwe Hermanna0c00932008-03-27 20:46:49 +000055 mvwprintw(win, row++, 1, "Version: %s%s",
Uwe Hermann3a406fe2008-03-20 01:11:28 +000056 cb_info.strings[CB_TAG_VERSION - 0x4],
57 cb_info.strings[CB_TAG_EXTRA_VERSION - 0x4]);
Jordan Crouse7249f792008-03-20 00:11:05 +000058
Uwe Hermanna0c00932008-03-27 20:46:49 +000059 mvwprintw(win, row++, 1, "Built: %s (%s@%s.%s)",
Jordan Crouse7249f792008-03-20 00:11:05 +000060 cb_info.strings[CB_TAG_BUILD - 0x4],
61 cb_info.strings[CB_TAG_COMPILE_BY - 0x04],
62 cb_info.strings[CB_TAG_COMPILE_HOST - 0x04],
63 cb_info.strings[CB_TAG_COMPILE_DOMAIN - 0x04]);
64
65 if (cb_info.serial.tag != 0x0) {
Uwe Hermanna0c00932008-03-27 20:46:49 +000066 mvwprintw(win, row++, 1, "Serial Port I/O base: 0x%x",
QingPei Wang45945cf2011-11-22 15:24:12 +080067 cb_info.serial.baseaddr);
Jordan Crouse7249f792008-03-20 00:11:05 +000068 }
69
70 if (cb_info.console.tag != 0x0) {
Uwe Hermanna0c00932008-03-27 20:46:49 +000071 mvwprintw(win, row++, 1, "Default Output Console: ");
Uwe Hermann3a406fe2008-03-20 01:11:28 +000072
73 switch (cb_info.console.type) {
Jordan Crouse7249f792008-03-20 00:11:05 +000074 case CB_TAG_CONSOLE_SERIAL8250:
75 wprintw(win, "Serial Port");
76 break;
77 case CB_TAG_CONSOLE_VGA:
78 wprintw(win, "VGA");
79 break;
80 case CB_TAG_CONSOLE_BTEXT:
81 wprintw(win, "BTEXT");
82 break;
83 case CB_TAG_CONSOLE_LOGBUF:
84 wprintw(win, "Log Buffer");
85 break;
86 case CB_TAG_CONSOLE_SROM:
87 wprintw(win, "Serial ROM");
88 break;
89 case CB_TAG_CONSOLE_EHCI:
90 wprintw(win, "USB Debug");
91 break;
92 }
93 }
94
95 row++;
Uwe Hermanna0c00932008-03-27 20:46:49 +000096 mvwprintw(win, row++, 1, "-- Memory Map --");
Jordan Crouse7249f792008-03-20 00:11:05 +000097
Uwe Hermann3a406fe2008-03-20 01:11:28 +000098 for (i = 0; i < cb_info.mem_count; i++) {
99 switch (cb_info.range[i].type) {
Jordan Crouse7249f792008-03-20 00:11:05 +0000100 case CB_MEM_RAM:
Uwe Hermanna0c00932008-03-27 20:46:49 +0000101 mvwprintw(win, row++, 3, " RAM: ");
Jordan Crouse7249f792008-03-20 00:11:05 +0000102 break;
Jordan Crouse7249f792008-03-20 00:11:05 +0000103 case CB_MEM_RESERVED:
Uwe Hermanna0c00932008-03-27 20:46:49 +0000104 mvwprintw(win, row++, 3, "Reserved: ");
Jordan Crouse7249f792008-03-20 00:11:05 +0000105 break;
Jordan Crouse7249f792008-03-20 00:11:05 +0000106 case CB_MEM_TABLE:
Uwe Hermanna0c00932008-03-27 20:46:49 +0000107 mvwprintw(win, row++, 3, " Table: ");
Jordan Crouse7249f792008-03-20 00:11:05 +0000108 }
109
110 wprintw(win, "%16.16llx - %16.16llx",
Philip Prindeville46404d72011-12-23 17:09:02 -0700111 cb_unpack64(cb_info.range[i].start),
112 cb_unpack64(cb_info.range[i].start) +
113 cb_unpack64(cb_info.range[i].size) - 1);
Jordan Crouse7249f792008-03-20 00:11:05 +0000114 }
Uwe Hermann35845a22008-03-20 20:05:22 +0000115
116 return 0;
Jordan Crouse7249f792008-03-20 00:11:05 +0000117}
118
119static void parse_memory(unsigned char *ptr)
120{
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000121 struct cb_memory *mem = (struct cb_memory *)ptr;
Jordan Crouse7249f792008-03-20 00:11:05 +0000122 int max = (MEM_RANGE_COUNT(mem) > MAX_MEMORY_COUNT)
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000123 ? MAX_MEMORY_COUNT : MEM_RANGE_COUNT(mem);
Jordan Crouse7249f792008-03-20 00:11:05 +0000124 int i;
125
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000126 for (i = 0; i < max; i++) {
127 struct cb_memory_range *range =
128 (struct cb_memory_range *)MEM_RANGE_PTR(mem, i);
Jordan Crouse7249f792008-03-20 00:11:05 +0000129
130 memcpy(&cb_info.range[i], range, sizeof(*range));
131 }
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000132
Jordan Crouse7249f792008-03-20 00:11:05 +0000133 cb_info.mem_count = max;
134 cb_info.mem_actual = MEM_RANGE_COUNT(mem);
135}
136
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000137static void parse_mainboard(unsigned char *ptr)
Jordan Crouse7249f792008-03-20 00:11:05 +0000138{
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000139 struct cb_mainboard *mb = (struct cb_mainboard *)ptr;
Jordan Crouse7249f792008-03-20 00:11:05 +0000140
Alexandru Gagniuc811d6612012-08-15 06:36:00 -0500141 strncpy(cb_info.vendor, cb_mb_vendor_string(mb), sizeof(cb_info.vendor) - 1);
Philip Prindeville68299ee2011-12-23 18:45:33 -0700142 strncpy(cb_info.part, cb_mb_part_string(mb), sizeof(cb_info.part) - 1);
Jordan Crouse7249f792008-03-20 00:11:05 +0000143}
144
145static void parse_strings(unsigned char *ptr)
146{
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000147 struct cb_string *string = (struct cb_string *)ptr;
Jordan Crouse7249f792008-03-20 00:11:05 +0000148 int index = string->tag - CB_TAG_VERSION;
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000149
Uwe Hermann35845a22008-03-20 20:05:22 +0000150 strncpy(cb_info.strings[index], (const char *)string->string, 63);
Jordan Crouse7249f792008-03-20 00:11:05 +0000151 cb_info.strings[index][63] = 0;
152}
153
154static void parse_serial(unsigned char *ptr)
155{
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000156 memcpy(&cb_info.serial, (struct cb_serial *)ptr,
Jordan Crouse7249f792008-03-20 00:11:05 +0000157 sizeof(struct cb_serial));
158}
159
160static void parse_console(unsigned char *ptr)
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000161{
162 memcpy(&cb_info.console, (struct cb_console *)ptr,
Jordan Crouse7249f792008-03-20 00:11:05 +0000163 sizeof(struct cb_console));
164}
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000165
Jordan Crouse7249f792008-03-20 00:11:05 +0000166static int parse_header(void *addr, int len)
167{
168 struct cb_header *header;
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000169 unsigned char *ptr = (unsigned char *)addr;
Jordan Crouse7249f792008-03-20 00:11:05 +0000170 int i;
171
172 for (i = 0; i < len; i += 16, ptr += 16) {
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000173 header = (struct cb_header *)ptr;
Jordan Crouse7249f792008-03-20 00:11:05 +0000174
Uwe Hermann35845a22008-03-20 20:05:22 +0000175 if (!strncmp((const char *)header->signature, "LBIO", 4))
Jordan Crouse7249f792008-03-20 00:11:05 +0000176 break;
177 }
178
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000179 /* We walked the entire space and didn't find anything. */
Jordan Crouse7249f792008-03-20 00:11:05 +0000180 if (i >= len)
181 return -1;
182
183 if (!header->table_bytes)
184 return 0;
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000185
186 /* FIXME: Check the checksum. */
Jordan Crouse7249f792008-03-20 00:11:05 +0000187
Philip Prindevillefe2f6b02011-12-23 17:22:05 -0700188 if (cb_checksum(header, sizeof(*header)))
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000189 return -1;
Jordan Crouse7249f792008-03-20 00:11:05 +0000190
Philip Prindevillefe2f6b02011-12-23 17:22:05 -0700191 if (cb_checksum((ptr + sizeof(*header)), header->table_bytes)
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000192 != header->table_checksum)
193 return -1;
Jordan Crouse7249f792008-03-20 00:11:05 +0000194
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000195 /* Now, walk the tables. */
Jordan Crouse7249f792008-03-20 00:11:05 +0000196 ptr += header->header_bytes;
197
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000198 for (i = 0; i < header->table_entries; i++) {
199 struct cb_record *rec = (struct cb_record *)ptr;
200
201 switch (rec->tag) {
Myles Watson44163f72009-08-24 15:25:11 +0000202 case CB_TAG_FORWARD:
203 return parse_header((void *)(unsigned long)((struct cb_forward *)rec)->forward, 1);
204 break;
Jordan Crouse7249f792008-03-20 00:11:05 +0000205 case CB_TAG_MEMORY:
206 parse_memory(ptr);
207 break;
Jordan Crouse7249f792008-03-20 00:11:05 +0000208 case CB_TAG_MAINBOARD:
209 parse_mainboard(ptr);
210 break;
Jordan Crouse7249f792008-03-20 00:11:05 +0000211 case CB_TAG_VERSION:
212 case CB_TAG_EXTRA_VERSION:
213 case CB_TAG_BUILD:
214 case CB_TAG_COMPILE_TIME:
215 case CB_TAG_COMPILE_BY:
216 case CB_TAG_COMPILE_HOST:
217 case CB_TAG_COMPILE_DOMAIN:
218 case CB_TAG_COMPILER:
219 case CB_TAG_LINKER:
220 case CB_TAG_ASSEMBLER:
221 parse_strings(ptr);
222 break;
Jordan Crouse7249f792008-03-20 00:11:05 +0000223 case CB_TAG_SERIAL:
224 parse_serial(ptr);
225 break;
Jordan Crouse7249f792008-03-20 00:11:05 +0000226 case CB_TAG_CONSOLE:
227 parse_console(ptr);
228 break;
Jordan Crouse7249f792008-03-20 00:11:05 +0000229 default:
230 break;
231 }
232
233 ptr += rec->size;
234 }
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000235
Jordan Crouse7249f792008-03-20 00:11:05 +0000236 return 1;
237}
238
Uwe Hermann0bfb5c42008-03-23 15:34:04 +0000239static int coreboot_module_init(void)
Jordan Crouse7249f792008-03-20 00:11:05 +0000240{
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000241 int ret = parse_header((void *)0x00000, 0x1000);
Jordan Crouse7249f792008-03-20 00:11:05 +0000242
243 if (ret != 1)
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000244 ret = parse_header((void *)0xf0000, 0x1000);
Jordan Crouse7249f792008-03-20 00:11:05 +0000245
Uwe Hermann3a406fe2008-03-20 01:11:28 +0000246 /* Return error if we couldn't find it at either address. */
247 tables_good = (ret == 1) ? 0 : -1;
Jordan Crouse7249f792008-03-20 00:11:05 +0000248 return tables_good;
249}
250
Jordan Crouse7249f792008-03-20 00:11:05 +0000251struct coreinfo_module coreboot_module = {
252 .name = "Coreboot",
253 .init = coreboot_module_init,
254 .redraw = coreboot_module_redraw,
255};
Uwe Hermannab5b3e02008-03-31 20:30:18 +0000256
257#else
258
259struct coreinfo_module coreboot_module = {
260};
261
262#endif