1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <arch/cbconfig.h>
5 #include <commonlib/bsd/ipchksum.h>
6 #include <console/console.h>
7 #include <console/uart.h>
9 #include <boot/coreboot_tables.h>
10 #include <boot/tables.h>
11 #include <boot_device.h>
14 #include <device/device.h>
15 #include <drivers/tpm/tpm_ppi.h>
17 #include <fw_config.h>
21 #include <bootsplash.h>
23 #include <spi_flash.h>
28 #if CONFIG(USE_OPTION_TABLE)
29 #include <option_table.h>
31 #if CONFIG(PLATFORM_USES_FSP2_0)
34 void lb_string_platform_blob_version(struct lb_header
*header
);
37 __weak
enum cb_err
fill_lb_pcie(struct lb_pcie
*pcie
)
39 return CB_ERR_NOT_IMPLEMENTED
;
42 static struct lb_header
*lb_table_init(unsigned long addr
)
44 struct lb_header
*header
;
46 addr
= ALIGN_UP(addr
, 16);
48 header
= (void *)addr
;
49 header
->signature
[0] = 'L';
50 header
->signature
[1] = 'B';
51 header
->signature
[2] = 'I';
52 header
->signature
[3] = 'O';
53 header
->header_bytes
= sizeof(*header
);
54 header
->header_checksum
= 0;
55 header
->table_bytes
= 0;
56 header
->table_checksum
= 0;
57 header
->table_entries
= 0;
61 static struct lb_record
*lb_first_record(struct lb_header
*header
)
63 struct lb_record
*rec
;
64 rec
= (void *)(((char *)header
) + sizeof(*header
));
68 static struct lb_record
*lb_last_record(struct lb_header
*header
)
70 struct lb_record
*rec
;
71 rec
= (void *)(((char *)header
) + sizeof(*header
)
72 + header
->table_bytes
);
76 struct lb_record
*lb_new_record(struct lb_header
*header
)
78 struct lb_record
*rec
;
79 rec
= lb_last_record(header
);
80 if (header
->table_entries
) {
81 assert(IS_ALIGNED(rec
->size
, LB_ENTRY_ALIGN
));
82 header
->table_bytes
+= rec
->size
;
83 rec
= lb_last_record(header
);
85 header
->table_entries
++;
86 rec
->tag
= LB_TAG_UNUSED
;
87 rec
->size
= sizeof(*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
);
102 static void lb_add_serial(struct lb_header
*header
)
104 struct lb_serial new_serial
= { .tag
= LB_TAG_SERIAL
,
105 .size
= sizeof(struct lb_serial
),
107 if (fill_lb_serial(&new_serial
) != CB_SUCCESS
)
110 struct lb_serial
*serial
= (struct lb_serial
*)lb_new_record(header
);
111 memcpy(serial
, &new_serial
, sizeof(*serial
));
112 assert(serial
->type
== LB_SERIAL_TYPE_IO_MAPPED
113 || serial
->type
== LB_SERIAL_TYPE_MEMORY_MAPPED
)
114 if (serial
->type
== LB_SERIAL_TYPE_IO_MAPPED
)
115 lb_add_console(LB_TAG_CONSOLE_SERIAL8250
, header
);
117 lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM
, header
);
120 void lb_add_console(uint16_t consoletype
, void *data
)
122 struct lb_header
*header
= (struct lb_header
*)data
;
123 struct lb_console
*console
;
125 console
= (struct lb_console
*)lb_new_record(header
);
126 console
->tag
= LB_TAG_CONSOLE
;
127 console
->size
= sizeof(*console
);
128 console
->type
= consoletype
;
131 static void lb_pcie(struct lb_header
*header
)
133 struct lb_pcie pcie
= { .tag
= LB_TAG_PCIE
, .size
= sizeof(pcie
) };
135 if (fill_lb_pcie(&pcie
) != CB_SUCCESS
)
138 memcpy(lb_new_record(header
), &pcie
, sizeof(pcie
));
141 static void lb_framebuffer(struct lb_header
*header
)
143 struct lb_framebuffer
*framebuffer
;
144 struct lb_framebuffer fb
= {0};
146 if (!CONFIG(LINEAR_FRAMEBUFFER
) || fill_lb_framebuffer(&fb
))
149 framebuffer
= (struct lb_framebuffer
*)lb_new_record(header
);
150 memcpy(framebuffer
, &fb
, sizeof(*framebuffer
));
151 framebuffer
->tag
= LB_TAG_FRAMEBUFFER
;
152 framebuffer
->size
= sizeof(*framebuffer
);
154 if (CONFIG(BOOTSPLASH
)) {
155 uint8_t *fb_ptr
= (uint8_t *)(uintptr_t)framebuffer
->physical_address
;
156 unsigned int width
= framebuffer
->x_resolution
;
157 unsigned int height
= framebuffer
->y_resolution
;
158 unsigned int bytes_per_line
= framebuffer
->bytes_per_line
;
159 unsigned int depth
= framebuffer
->bits_per_pixel
;
160 set_bootsplash(fb_ptr
, width
, height
, bytes_per_line
, depth
);
164 void lb_add_gpios(struct lb_gpios
*gpios
, const struct lb_gpio
*gpio_table
,
167 size_t table_size
= count
* sizeof(struct lb_gpio
);
169 memcpy(&gpios
->gpios
[gpios
->count
], gpio_table
, table_size
);
170 gpios
->count
+= count
;
171 gpios
->size
+= table_size
;
174 static void lb_gpios(struct lb_header
*header
)
176 struct lb_gpios
*gpios
;
179 gpios
= (struct lb_gpios
*)lb_new_record(header
);
180 gpios
->tag
= LB_TAG_GPIO
;
181 gpios
->size
= sizeof(*gpios
);
183 fill_lb_gpios(gpios
);
185 printk(BIOS_INFO
, "Passing %u GPIOs to payload:\n"
186 " NAME | PORT | POLARITY | VALUE\n",
188 for (g
= &gpios
->gpios
[0]; g
< &gpios
->gpios
[gpios
->count
]; g
++) {
189 printk(BIOS_INFO
, "%16.16s | ", g
->name
);
191 printk(BIOS_INFO
, " undefined | ");
193 printk(BIOS_INFO
, "%#.8x | ", g
->port
);
194 if (g
->polarity
== ACTIVE_HIGH
)
195 printk(BIOS_INFO
, " high | ");
197 printk(BIOS_INFO
, " low | ");
200 printk(BIOS_INFO
, " low\n");
203 printk(BIOS_INFO
, " high\n");
206 printk(BIOS_INFO
, "undefined\n");
212 __weak
uint32_t board_id(void) { return UNDEFINED_STRAPPING_ID
; }
213 __weak
uint32_t ram_code(void) { return UNDEFINED_STRAPPING_ID
; }
214 __weak
uint32_t sku_id(void) { return UNDEFINED_STRAPPING_ID
; }
215 __weak
uint64_t fw_config_get(void) { return UNDEFINED_FW_CONFIG
; }
217 static void lb_boot_media_params(struct lb_header
*header
)
219 struct lb_boot_media_params
*bmp
;
220 const struct region_device
*boot_dev
;
221 const struct cbfs_boot_device
*cbd
= cbfs_get_boot_device(false);
225 boot_dev
= boot_device_ro();
226 if (boot_dev
== NULL
)
229 bmp
= (struct lb_boot_media_params
*)lb_new_record(header
);
230 bmp
->tag
= LB_TAG_BOOT_MEDIA_PARAMS
;
231 bmp
->size
= sizeof(*bmp
);
233 bmp
->cbfs_offset
= region_device_offset(&cbd
->rdev
);
234 bmp
->cbfs_size
= region_device_sz(&cbd
->rdev
);
235 bmp
->boot_media_size
= region_device_sz(boot_dev
);
237 bmp
->fmap_offset
= get_fmap_flash_offset();
240 static void lb_mmc_info(struct lb_header
*header
)
242 struct lb_mmc_info
*rec
;
245 ms_cbmem
= cbmem_find(CBMEM_ID_MMC_STATUS
);
249 rec
= (struct lb_mmc_info
*)lb_new_record(header
);
251 rec
->tag
= LB_TAG_MMC_INFO
;
252 rec
->size
= sizeof(*rec
);
253 rec
->early_cmd1_status
= *ms_cbmem
;
256 static void add_cbmem_pointers(struct lb_header
*header
)
259 * These CBMEM sections' addresses are included in the coreboot table
260 * with the appropriate tags.
262 const struct section_id
{
266 {CBMEM_ID_TIMESTAMP
, LB_TAG_TIMESTAMPS
},
267 {CBMEM_ID_CONSOLE
, LB_TAG_CBMEM_CONSOLE
},
268 {CBMEM_ID_ACPI_GNVS
, LB_TAG_ACPI_GNVS
},
269 {CBMEM_ID_ACPI_CNVS
, LB_TAG_ACPI_CNVS
},
270 {CBMEM_ID_VPD
, LB_TAG_VPD
},
271 {CBMEM_ID_WIFI_CALIBRATION
, LB_TAG_WIFI_CALIBRATION
},
272 {CBMEM_ID_TPM_CB_LOG
, LB_TAG_TPM_CB_LOG
},
273 {CBMEM_ID_FMAP
, LB_TAG_FMAP
},
274 {CBMEM_ID_VBOOT_WORKBUF
, LB_TAG_VBOOT_WORKBUF
},
275 {CBMEM_ID_TYPE_C_INFO
, LB_TAG_TYPE_C_INFO
},
279 for (i
= 0; i
< ARRAY_SIZE(section_ids
); i
++) {
280 const struct section_id
*sid
= section_ids
+ i
;
281 struct lb_cbmem_ref
*cbmem_ref
;
282 void *cbmem_addr
= cbmem_find(sid
->cbmem_id
);
285 continue; /* This section is not present */
287 cbmem_ref
= (struct lb_cbmem_ref
*)lb_new_record(header
);
289 printk(BIOS_ERR
, "No more room in coreboot table!\n");
292 cbmem_ref
->tag
= sid
->table_tag
;
293 cbmem_ref
->size
= sizeof(*cbmem_ref
);
294 cbmem_ref
->cbmem_addr
= (unsigned long)cbmem_addr
;
298 static struct lb_mainboard
*lb_mainboard(struct lb_header
*header
)
300 struct lb_record
*rec
;
301 struct lb_mainboard
*mainboard
;
302 rec
= lb_new_record(header
);
303 mainboard
= (struct lb_mainboard
*)rec
;
304 mainboard
->tag
= LB_TAG_MAINBOARD
;
306 mainboard
->size
= ALIGN_UP(sizeof(*mainboard
) +
307 strlen(mainboard_vendor
) + 1 +
308 strlen(mainboard_part_number
) + 1, LB_ENTRY_ALIGN
);
310 mainboard
->vendor_idx
= 0;
311 mainboard
->part_number_idx
= strlen(mainboard_vendor
) + 1;
313 memcpy(mainboard
->strings
+ mainboard
->vendor_idx
,
314 mainboard_vendor
, strlen(mainboard_vendor
) + 1);
315 memcpy(mainboard
->strings
+ mainboard
->part_number_idx
,
316 mainboard_part_number
, strlen(mainboard_part_number
) + 1);
321 static struct lb_board_config
*lb_board_config(struct lb_header
*header
)
323 struct lb_record
*rec
;
324 struct lb_board_config
*config
;
325 rec
= lb_new_record(header
);
326 config
= (struct lb_board_config
*)rec
;
328 config
->tag
= LB_TAG_BOARD_CONFIG
;
329 config
->size
= sizeof(*config
);
331 const uint64_t fw_config
= fw_config_get();
332 config
->board_id
= board_id();
333 config
->ram_code
= ram_code();
334 config
->sku_id
= sku_id();
335 config
->fw_config
= fw_config
;
337 if (config
->board_id
!= UNDEFINED_STRAPPING_ID
)
338 printk(BIOS_INFO
, "Board ID: %d\n", config
->board_id
);
339 if (config
->ram_code
!= UNDEFINED_STRAPPING_ID
)
340 printk(BIOS_INFO
, "RAM code: %d\n", config
->ram_code
);
341 if (config
->sku_id
!= UNDEFINED_STRAPPING_ID
)
342 printk(BIOS_INFO
, "SKU ID: %d\n", config
->sku_id
);
343 if (fw_config
!= UNDEFINED_FW_CONFIG
)
344 printk(BIOS_INFO
, "FW config: %#" PRIx64
"\n", fw_config
);
349 #if CONFIG(USE_OPTION_TABLE)
350 static struct cmos_checksum
*lb_cmos_checksum(struct lb_header
*header
)
352 struct lb_record
*rec
;
353 struct cmos_checksum
*cmos_checksum
;
354 rec
= lb_new_record(header
);
355 cmos_checksum
= (struct cmos_checksum
*)rec
;
356 cmos_checksum
->tag
= LB_TAG_OPTION_CHECKSUM
;
358 cmos_checksum
->size
= (sizeof(*cmos_checksum
));
360 cmos_checksum
->range_start
= LB_CKS_RANGE_START
* 8;
361 cmos_checksum
->range_end
= (LB_CKS_RANGE_END
* 8) + 7;
362 cmos_checksum
->location
= LB_CKS_LOC
* 8;
363 cmos_checksum
->type
= CHECKSUM_PCBIOS
;
365 return cmos_checksum
;
369 static void lb_strings(struct lb_header
*header
)
371 static const struct {
375 { LB_TAG_VERSION
, coreboot_version
, },
376 { LB_TAG_EXTRA_VERSION
, coreboot_extra_version
, },
377 { LB_TAG_BUILD
, coreboot_build
, },
378 { LB_TAG_COMPILE_TIME
, coreboot_compile_time
, },
381 for (i
= 0; i
< ARRAY_SIZE(strings
); i
++) {
382 struct lb_string
*rec
;
384 rec
= (struct lb_string
*)lb_new_record(header
);
385 len
= strlen(strings
[i
].string
);
386 rec
->tag
= strings
[i
].tag
;
387 rec
->size
= ALIGN_UP(sizeof(*rec
) + len
+ 1, LB_ENTRY_ALIGN
);
388 memcpy(rec
->string
, strings
[i
].string
, len
+1);
393 static void lb_record_version_timestamp(struct lb_header
*header
)
395 struct lb_timestamp
*rec
;
396 rec
= (struct lb_timestamp
*)lb_new_record(header
);
397 rec
->tag
= LB_TAG_VERSION_TIMESTAMP
;
398 rec
->size
= sizeof(*rec
);
399 rec
->timestamp
= coreboot_version_timestamp
;
402 void __weak
lb_board(struct lb_header
*header
) { /* NOOP */ }
405 * It's possible that the system is using a SPI flash as the boot device,
406 * however it is not probing for devices to fill in specifics. In that
407 * case don't provide any information as the correct information is
410 void __weak
lb_spi_flash(struct lb_header
*header
) { /* NOOP */ }
412 static struct lb_forward
*lb_forward(struct lb_header
*header
,
413 struct lb_header
*next_header
)
415 struct lb_record
*rec
;
416 struct lb_forward
*forward
;
417 rec
= lb_new_record(header
);
418 forward
= (struct lb_forward
*)rec
;
419 forward
->tag
= LB_TAG_FORWARD
;
420 forward
->size
= sizeof(*forward
);
421 forward
->forward
= (uint64_t)(unsigned long)next_header
;
425 static unsigned long lb_table_fini(struct lb_header
*head
)
427 struct lb_record
*rec
, *first_rec
;
428 rec
= lb_last_record(head
);
429 if (head
->table_entries
) {
430 assert(IS_ALIGNED(rec
->size
, LB_ENTRY_ALIGN
));
431 head
->table_bytes
+= rec
->size
;
434 first_rec
= lb_first_record(head
);
435 head
->table_checksum
= ipchksum(first_rec
, head
->table_bytes
);
436 head
->header_checksum
= 0;
437 head
->header_checksum
= ipchksum(head
, sizeof(*head
));
439 "Wrote coreboot table at: %p, 0x%x bytes, checksum %x\n",
440 head
, head
->table_bytes
, head
->table_checksum
);
441 return (unsigned long)rec
+ rec
->size
;
444 static void lb_add_acpi_rsdp(struct lb_header
*head
)
446 struct lb_acpi_rsdp
*acpi_rsdp
;
447 struct lb_record
*rec
= lb_new_record(head
);
448 acpi_rsdp
= (struct lb_acpi_rsdp
*)rec
;
449 acpi_rsdp
->tag
= LB_TAG_ACPI_RSDP
;
450 acpi_rsdp
->size
= sizeof(*acpi_rsdp
);
451 acpi_rsdp
->rsdp_pointer
= get_coreboot_rsdp();
454 size_t write_coreboot_forwarding_table(uintptr_t entry
, uintptr_t target
)
456 struct lb_header
*head
;
458 printk(BIOS_DEBUG
, "Writing table forward entry at %p\n",
461 head
= lb_table_init(entry
);
462 lb_forward(head
, (struct lb_header
*)target
);
464 return (uintptr_t)lb_table_fini(head
) - entry
;
467 static uintptr_t write_coreboot_table(uintptr_t rom_table_end
)
469 struct lb_header
*head
;
471 printk(BIOS_DEBUG
, "Writing coreboot table at 0x%08lx\n",
472 (long)rom_table_end
);
474 head
= lb_table_init(rom_table_end
);
476 #if CONFIG(USE_OPTION_TABLE)
478 struct cmos_option_table
*option_table
=
479 cbfs_map("cmos_layout.bin", NULL
);
481 struct lb_record
*rec_dest
= lb_new_record(head
);
482 /* Copy the option config table, it's already a
485 memcpy(rec_dest
, option_table
, option_table
->size
);
486 /* Create CMOS checksum entry in coreboot table */
487 lb_cmos_checksum(head
);
490 "cmos_layout.bin could not be found!\n");
495 /* Serialize resource map into mem table types (LB_MEM_*) */
496 bootmem_write_memory_table(lb_memory(head
));
498 /* Record our motherboard */
501 /* Record the serial ports and consoles */
502 if (CONFIG(CONSOLE_SERIAL
))
505 if (CONFIG(CONSOLE_USB
))
506 lb_add_console(LB_TAG_CONSOLE_EHCI
, head
);
511 /* Record our various random string information */
513 if (CONFIG(PLATFORM_USES_FSP2_0
))
514 lb_string_platform_blob_version(head
);
515 lb_record_version_timestamp(head
);
516 /* Record our framebuffer */
517 lb_framebuffer(head
);
519 /* Record our GPIO settings (ChromeOS specific) */
520 if (CONFIG(CHROMEOS
))
523 /* pass along VBNV offsets in CMOS */
524 if (CONFIG(VBOOT_VBNV_CMOS
))
525 lb_table_add_vbnv_cmos(head
);
527 /* Pass mmc early init status */
530 /* Add SPI flash description if available */
531 if (CONFIG(BOOT_DEVICE_SPI_FLASH
))
534 add_cbmem_pointers(head
);
537 if (CONFIG(SMMSTORE_V2
))
540 /* Add board-specific table entries, if any. */
543 if (CONFIG(CHROMEOS_RAMOOPS
))
546 lb_boot_media_params(head
);
548 /* Board configuration information (including straps) */
549 lb_board_config(head
);
554 /* Add architecture records. */
555 lb_arch_add_records(head
);
557 /* Add all cbmem entries into the coreboot tables. */
558 cbmem_add_records_to_cbtable(head
);
560 if (CONFIG(HAVE_ACPI_TABLES
))
561 lb_add_acpi_rsdp(head
);
563 /* Remember where my valid memory ranges are */
564 return lb_table_fini(head
);
567 void *write_tables(void)
569 uintptr_t cbtable_start
;
570 uintptr_t cbtable_end
;
572 const size_t max_table_size
= COREBOOT_TABLE_SIZE
;
574 cbtable_start
= (uintptr_t)cbmem_add(CBMEM_ID_CBTABLE
, max_table_size
);
576 if (!cbtable_start
) {
577 printk(BIOS_ERR
, "Could not add CBMEM for coreboot table.\n");
581 /* Add architecture specific tables. */
582 arch_write_tables(cbtable_start
);
584 /* Write the coreboot table. */
585 cbtable_end
= write_coreboot_table(cbtable_start
);
586 cbtable_size
= cbtable_end
- cbtable_start
;
588 if (cbtable_size
> max_table_size
) {
589 printk(BIOS_ERR
, "%s: coreboot table didn't fit (%zx/%zx)\n",
590 __func__
, cbtable_size
, max_table_size
);
593 printk(BIOS_DEBUG
, "coreboot table: %zd bytes.\n", cbtable_size
);
595 /* Print CBMEM sections */
597 return (void *)cbtable_start
;