lib/libpayload: Replace strapping_ids with new board configuration entry
[coreboot.git] / src / lib / coreboot_table.c
blob69ded3c70091e1850becbe3a00e4632d64dc42a0
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/cbconfig.h>
4 #include <console/console.h>
5 #include <console/uart.h>
6 #include <ip_checksum.h>
7 #include <boot/coreboot_tables.h>
8 #include <boot/tables.h>
9 #include <boot_device.h>
10 #include <string.h>
11 #include <version.h>
12 #include <boardid.h>
13 #include <device/device.h>
14 #include <fmap.h>
15 #include <fw_config.h>
16 #include <stdlib.h>
17 #include <cbfs.h>
18 #include <cbmem.h>
19 #include <bootmem.h>
20 #include <bootsplash.h>
21 #include <spi_flash.h>
22 #include <security/vboot/misc.h>
23 #include <security/vboot/vbnv_layout.h>
24 #include <smmstore.h>
26 #if CONFIG(USE_OPTION_TABLE)
27 #include <option_table.h>
28 #endif
29 #if CONFIG(CHROMEOS)
30 #if CONFIG(HAVE_ACPI_TABLES)
31 #include <acpi/acpi.h>
32 #endif
33 #include <vendorcode/google/chromeos/chromeos.h>
34 #include <vendorcode/google/chromeos/gnvs.h>
35 #endif
36 #if CONFIG(PLATFORM_USES_FSP2_0)
37 #include <fsp/util.h>
38 #else
39 void lb_string_platform_blob_version(struct lb_header *header);
40 #endif
42 static struct lb_header *lb_table_init(unsigned long addr)
44 struct lb_header *header;
46 /* 16 byte align the address */
47 addr += 15;
48 addr &= ~15;
50 header = (void *)addr;
51 header->signature[0] = 'L';
52 header->signature[1] = 'B';
53 header->signature[2] = 'I';
54 header->signature[3] = 'O';
55 header->header_bytes = sizeof(*header);
56 header->header_checksum = 0;
57 header->table_bytes = 0;
58 header->table_checksum = 0;
59 header->table_entries = 0;
60 return header;
63 static struct lb_record *lb_first_record(struct lb_header *header)
65 struct lb_record *rec;
66 rec = (void *)(((char *)header) + sizeof(*header));
67 return rec;
70 static struct lb_record *lb_last_record(struct lb_header *header)
72 struct lb_record *rec;
73 rec = (void *)(((char *)header) + sizeof(*header)
74 + header->table_bytes);
75 return rec;
78 struct lb_record *lb_new_record(struct lb_header *header)
80 struct lb_record *rec;
81 rec = lb_last_record(header);
82 if (header->table_entries)
83 header->table_bytes += rec->size;
84 rec = lb_last_record(header);
85 header->table_entries++;
86 rec->tag = LB_TAG_UNUSED;
87 rec->size = sizeof(*rec);
88 return rec;
91 static struct lb_memory *lb_memory(struct lb_header *header)
93 struct lb_record *rec;
94 struct lb_memory *mem;
95 rec = lb_new_record(header);
96 mem = (struct lb_memory *)rec;
97 mem->tag = LB_TAG_MEMORY;
98 mem->size = sizeof(*mem);
99 return mem;
102 void lb_add_serial(struct lb_serial *new_serial, void *data)
104 struct lb_header *header = (struct lb_header *)data;
105 struct lb_serial *serial;
107 serial = (struct lb_serial *)lb_new_record(header);
108 serial->tag = LB_TAG_SERIAL;
109 serial->size = sizeof(*serial);
110 serial->type = new_serial->type;
111 serial->baseaddr = new_serial->baseaddr;
112 serial->baud = new_serial->baud;
113 serial->regwidth = new_serial->regwidth;
114 serial->input_hertz = new_serial->input_hertz;
115 serial->uart_pci_addr = new_serial->uart_pci_addr;
118 void lb_add_console(uint16_t consoletype, void *data)
120 struct lb_header *header = (struct lb_header *)data;
121 struct lb_console *console;
123 console = (struct lb_console *)lb_new_record(header);
124 console->tag = LB_TAG_CONSOLE;
125 console->size = sizeof(*console);
126 console->type = consoletype;
129 static void lb_framebuffer(struct lb_header *header)
131 struct lb_framebuffer *framebuffer;
132 struct lb_framebuffer fb = {0};
134 if (!CONFIG(LINEAR_FRAMEBUFFER) || fill_lb_framebuffer(&fb))
135 return;
137 framebuffer = (struct lb_framebuffer *)lb_new_record(header);
138 memcpy(framebuffer, &fb, sizeof(*framebuffer));
139 framebuffer->tag = LB_TAG_FRAMEBUFFER;
140 framebuffer->size = sizeof(*framebuffer);
142 if (CONFIG(BOOTSPLASH)) {
143 uint8_t *fb_ptr = (uint8_t *)(uintptr_t)framebuffer->physical_address;
144 unsigned int width = framebuffer->x_resolution;
145 unsigned int height = framebuffer->y_resolution;
146 unsigned int depth = framebuffer->bits_per_pixel;
147 set_bootsplash(fb_ptr, width, height, depth);
151 void lb_add_gpios(struct lb_gpios *gpios, const struct lb_gpio *gpio_table,
152 size_t count)
154 size_t table_size = count * sizeof(struct lb_gpio);
156 memcpy(&gpios->gpios[gpios->count], gpio_table, table_size);
157 gpios->count += count;
158 gpios->size += table_size;
161 #if CONFIG(CHROMEOS)
162 static void lb_gpios(struct lb_header *header)
164 struct lb_gpios *gpios;
165 struct lb_gpio *g;
167 gpios = (struct lb_gpios *)lb_new_record(header);
168 gpios->tag = LB_TAG_GPIO;
169 gpios->size = sizeof(*gpios);
170 gpios->count = 0;
171 fill_lb_gpios(gpios);
173 printk(BIOS_INFO, "Passing %u GPIOs to payload:\n"
174 " NAME | PORT | POLARITY | VALUE\n",
175 gpios->count);
176 for (g = &gpios->gpios[0]; g < &gpios->gpios[gpios->count]; g++) {
177 printk(BIOS_INFO, "%16s | ", g->name);
178 if (g->port == -1)
179 printk(BIOS_INFO, " undefined | ");
180 else
181 printk(BIOS_INFO, "%#.8x | ", g->port);
182 if (g->polarity == ACTIVE_HIGH)
183 printk(BIOS_INFO, " high | ");
184 else
185 printk(BIOS_INFO, " low | ");
186 switch (g->value) {
187 case 0:
188 printk(BIOS_INFO, " low\n");
189 break;
190 case 1:
191 printk(BIOS_INFO, " high\n");
192 break;
193 default:
194 printk(BIOS_INFO, "undefined\n");
195 break;
200 static void lb_vbnv(struct lb_header *header)
202 #if CONFIG(PC80_SYSTEM)
203 struct lb_range *vbnv;
205 vbnv = (struct lb_range *)lb_new_record(header);
206 vbnv->tag = LB_TAG_VBNV;
207 vbnv->size = sizeof(*vbnv);
208 vbnv->range_start = CONFIG_VBOOT_VBNV_OFFSET + 14;
209 vbnv->range_size = VBOOT_VBNV_BLOCK_SIZE;
210 #endif
212 #endif /* CONFIG_CHROMEOS */
214 __weak uint32_t board_id(void) { return UNDEFINED_STRAPPING_ID; }
215 __weak uint32_t ram_code(void) { return UNDEFINED_STRAPPING_ID; }
216 __weak uint32_t sku_id(void) { return UNDEFINED_STRAPPING_ID; }
217 __weak uint64_t fw_config_get(void) { return UNDEFINED_FW_CONFIG; }
219 static void lb_boot_media_params(struct lb_header *header)
221 struct lb_boot_media_params *bmp;
222 const struct region_device *boot_dev;
223 struct region_device cbfs_dev;
225 boot_device_init();
227 if (cbfs_boot_region_device(&cbfs_dev))
228 return;
230 boot_dev = boot_device_ro();
231 if (boot_dev == NULL)
232 return;
234 bmp = (struct lb_boot_media_params *)lb_new_record(header);
235 bmp->tag = LB_TAG_BOOT_MEDIA_PARAMS;
236 bmp->size = sizeof(*bmp);
238 bmp->cbfs_offset = region_device_offset(&cbfs_dev);
239 bmp->cbfs_size = region_device_sz(&cbfs_dev);
240 bmp->boot_media_size = region_device_sz(boot_dev);
242 bmp->fmap_offset = get_fmap_flash_offset();
245 static void lb_mmc_info(struct lb_header *header)
247 struct lb_mmc_info *rec;
248 int32_t *ms_cbmem;
250 ms_cbmem = cbmem_find(CBMEM_ID_MMC_STATUS);
251 if (!ms_cbmem)
252 return;
254 rec = (struct lb_mmc_info *)lb_new_record(header);
256 rec->tag = LB_TAG_MMC_INFO;
257 rec->size = sizeof(*rec);
258 rec->early_cmd1_status = *ms_cbmem;
261 static void add_cbmem_pointers(struct lb_header *header)
264 * These CBMEM sections' addresses are included in the coreboot table
265 * with the appropriate tags.
267 const struct section_id {
268 int cbmem_id;
269 int table_tag;
270 } section_ids[] = {
271 {CBMEM_ID_TIMESTAMP, LB_TAG_TIMESTAMPS},
272 {CBMEM_ID_CONSOLE, LB_TAG_CBMEM_CONSOLE},
273 {CBMEM_ID_ACPI_GNVS, LB_TAG_ACPI_GNVS},
274 {CBMEM_ID_VPD, LB_TAG_VPD},
275 {CBMEM_ID_WIFI_CALIBRATION, LB_TAG_WIFI_CALIBRATION},
276 {CBMEM_ID_TCPA_LOG, LB_TAG_TCPA_LOG},
277 {CBMEM_ID_FMAP, LB_TAG_FMAP},
278 {CBMEM_ID_VBOOT_WORKBUF, LB_TAG_VBOOT_WORKBUF},
280 int i;
282 for (i = 0; i < ARRAY_SIZE(section_ids); i++) {
283 const struct section_id *sid = section_ids + i;
284 struct lb_cbmem_ref *cbmem_ref;
285 void *cbmem_addr = cbmem_find(sid->cbmem_id);
287 if (!cbmem_addr)
288 continue; /* This section is not present */
290 cbmem_ref = (struct lb_cbmem_ref *)lb_new_record(header);
291 if (!cbmem_ref) {
292 printk(BIOS_ERR, "No more room in coreboot table!\n");
293 break;
295 cbmem_ref->tag = sid->table_tag;
296 cbmem_ref->size = sizeof(*cbmem_ref);
297 cbmem_ref->cbmem_addr = (unsigned long)cbmem_addr;
301 static struct lb_mainboard *lb_mainboard(struct lb_header *header)
303 struct lb_record *rec;
304 struct lb_mainboard *mainboard;
305 rec = lb_new_record(header);
306 mainboard = (struct lb_mainboard *)rec;
307 mainboard->tag = LB_TAG_MAINBOARD;
309 mainboard->size = ALIGN_UP(sizeof(*mainboard) +
310 strlen(mainboard_vendor) + 1 +
311 strlen(mainboard_part_number) + 1, 8);
313 mainboard->vendor_idx = 0;
314 mainboard->part_number_idx = strlen(mainboard_vendor) + 1;
316 memcpy(mainboard->strings + mainboard->vendor_idx,
317 mainboard_vendor, strlen(mainboard_vendor) + 1);
318 memcpy(mainboard->strings + mainboard->part_number_idx,
319 mainboard_part_number, strlen(mainboard_part_number) + 1);
321 return mainboard;
324 static struct lb_board_config *lb_board_config(struct lb_header *header)
326 struct lb_record *rec;
327 struct lb_board_config *config;
328 rec = lb_new_record(header);
329 config = (struct lb_board_config *)rec;
331 config->tag = LB_TAG_BOARD_CONFIG;
332 config->size = sizeof(*config);
334 config->board_id = board_id();
335 config->ram_code = ram_code();
336 config->sku_id = sku_id();
337 config->fw_config = pack_lb64(fw_config_get());
339 return config;
342 #if CONFIG(USE_OPTION_TABLE)
343 static struct cmos_checksum *lb_cmos_checksum(struct lb_header *header)
345 struct lb_record *rec;
346 struct cmos_checksum *cmos_checksum;
347 rec = lb_new_record(header);
348 cmos_checksum = (struct cmos_checksum *)rec;
349 cmos_checksum->tag = LB_TAG_OPTION_CHECKSUM;
351 cmos_checksum->size = (sizeof(*cmos_checksum));
353 cmos_checksum->range_start = LB_CKS_RANGE_START * 8;
354 cmos_checksum->range_end = (LB_CKS_RANGE_END * 8) + 7;
355 cmos_checksum->location = LB_CKS_LOC * 8;
356 cmos_checksum->type = CHECKSUM_PCBIOS;
358 return cmos_checksum;
360 #endif
362 static void lb_strings(struct lb_header *header)
364 static const struct {
365 uint32_t tag;
366 const char *string;
367 } strings[] = {
368 { LB_TAG_VERSION, coreboot_version, },
369 { LB_TAG_EXTRA_VERSION, coreboot_extra_version, },
370 { LB_TAG_BUILD, coreboot_build, },
371 { LB_TAG_COMPILE_TIME, coreboot_compile_time, },
373 unsigned int i;
374 for (i = 0; i < ARRAY_SIZE(strings); i++) {
375 struct lb_string *rec;
376 size_t len;
377 rec = (struct lb_string *)lb_new_record(header);
378 len = strlen(strings[i].string);
379 rec->tag = strings[i].tag;
380 rec->size = ALIGN_UP(sizeof(*rec) + len + 1, 8);
381 memcpy(rec->string, strings[i].string, len+1);
386 static void lb_record_version_timestamp(struct lb_header *header)
388 struct lb_timestamp *rec;
389 rec = (struct lb_timestamp *)lb_new_record(header);
390 rec->tag = LB_TAG_VERSION_TIMESTAMP;
391 rec->size = sizeof(*rec);
392 rec->timestamp = coreboot_version_timestamp;
395 void __weak lb_board(struct lb_header *header) { /* NOOP */ }
398 * It's possible that the system is using a SPI flash as the boot device,
399 * however it is not probing for devices to fill in specifics. In that
400 * case don't provide any information as the correct information is
401 * not known.
403 void __weak lb_spi_flash(struct lb_header *header) { /* NOOP */ }
405 static struct lb_forward *lb_forward(struct lb_header *header,
406 struct lb_header *next_header)
408 struct lb_record *rec;
409 struct lb_forward *forward;
410 rec = lb_new_record(header);
411 forward = (struct lb_forward *)rec;
412 forward->tag = LB_TAG_FORWARD;
413 forward->size = sizeof(*forward);
414 forward->forward = (uint64_t)(unsigned long)next_header;
415 return forward;
418 static unsigned long lb_table_fini(struct lb_header *head)
420 struct lb_record *rec, *first_rec;
421 rec = lb_last_record(head);
422 if (head->table_entries)
423 head->table_bytes += rec->size;
425 first_rec = lb_first_record(head);
426 head->table_checksum = compute_ip_checksum(first_rec,
427 head->table_bytes);
428 head->header_checksum = 0;
429 head->header_checksum = compute_ip_checksum(head, sizeof(*head));
430 printk(BIOS_DEBUG,
431 "Wrote coreboot table at: %p, 0x%x bytes, checksum %x\n",
432 head, head->table_bytes, head->table_checksum);
433 return (unsigned long)rec + rec->size;
436 size_t write_coreboot_forwarding_table(uintptr_t entry, uintptr_t target)
438 struct lb_header *head;
440 printk(BIOS_DEBUG, "Writing table forward entry at %p\n",
441 (void *)entry);
443 head = lb_table_init(entry);
444 lb_forward(head, (struct lb_header *)target);
446 return (uintptr_t)lb_table_fini(head) - entry;
449 static uintptr_t write_coreboot_table(uintptr_t rom_table_end)
451 struct lb_header *head;
453 printk(BIOS_DEBUG, "Writing coreboot table at 0x%08lx\n",
454 (long)rom_table_end);
456 head = lb_table_init(rom_table_end);
458 #if CONFIG(USE_OPTION_TABLE)
460 struct cmos_option_table *option_table =
461 cbfs_boot_map_with_leak("cmos_layout.bin",
462 CBFS_COMPONENT_CMOS_LAYOUT, NULL);
463 if (option_table) {
464 struct lb_record *rec_dest = lb_new_record(head);
465 /* Copy the option config table, it's already a
466 * lb_record...
468 memcpy(rec_dest, option_table, option_table->size);
469 /* Create CMOS checksum entry in coreboot table */
470 lb_cmos_checksum(head);
471 } else {
472 printk(BIOS_ERR,
473 "cmos_layout.bin could not be found!\n");
476 #endif
478 /* Serialize resource map into mem table types (LB_MEM_*) */
479 bootmem_write_memory_table(lb_memory(head));
481 /* Record our motherboard */
482 lb_mainboard(head);
484 /* Record the serial ports and consoles */
485 #if CONFIG(CONSOLE_SERIAL)
486 uart_fill_lb(head);
487 #endif
488 #if CONFIG(CONSOLE_USB)
489 lb_add_console(LB_TAG_CONSOLE_EHCI, head);
490 #endif
492 /* Record our various random string information */
493 lb_strings(head);
494 if (CONFIG(PLATFORM_USES_FSP2_0))
495 lb_string_platform_blob_version(head);
496 lb_record_version_timestamp(head);
497 /* Record our framebuffer */
498 lb_framebuffer(head);
500 #if CONFIG(CHROMEOS)
501 /* Record our GPIO settings (ChromeOS specific) */
502 lb_gpios(head);
504 /* pass along VBNV offsets in CMOS */
505 lb_vbnv(head);
506 #endif
508 /* Pass mmc early init status */
509 lb_mmc_info(head);
511 /* Add SPI flash description if available */
512 if (CONFIG(BOOT_DEVICE_SPI_FLASH))
513 lb_spi_flash(head);
515 add_cbmem_pointers(head);
517 /* SMMSTORE v2 */
518 if (CONFIG(SMMSTORE_V2))
519 lb_smmstorev2(head);
521 /* Add board-specific table entries, if any. */
522 lb_board(head);
524 #if CONFIG(CHROMEOS_RAMOOPS)
525 lb_ramoops(head);
526 #endif
528 lb_boot_media_params(head);
530 /* Board configuration information (including straps) */
531 lb_board_config(head);
533 /* Add architecture records. */
534 lb_arch_add_records(head);
536 /* Add all cbmem entries into the coreboot tables. */
537 cbmem_add_records_to_cbtable(head);
539 /* Remember where my valid memory ranges are */
540 return lb_table_fini(head);
543 void *write_tables(void)
545 uintptr_t cbtable_start;
546 uintptr_t cbtable_end;
547 size_t cbtable_size;
548 const size_t max_table_size = COREBOOT_TABLE_SIZE;
550 cbtable_start = (uintptr_t)cbmem_add(CBMEM_ID_CBTABLE, max_table_size);
552 if (!cbtable_start) {
553 printk(BIOS_ERR, "Could not add CBMEM for coreboot table.\n");
554 return NULL;
557 /* Add architecture specific tables. */
558 arch_write_tables(cbtable_start);
560 /* Write the coreboot table. */
561 cbtable_end = write_coreboot_table(cbtable_start);
562 cbtable_size = cbtable_end - cbtable_start;
564 if (cbtable_size > max_table_size) {
565 printk(BIOS_ERR, "%s: coreboot table didn't fit (%zx/%zx)\n",
566 __func__, cbtable_size, max_table_size);
569 printk(BIOS_DEBUG, "coreboot table: %zd bytes.\n", cbtable_size);
571 /* Print CBMEM sections */
572 cbmem_list();
573 return (void *)cbtable_start;