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>
13 #include <device/device.h>
19 #include <bootsplash.h>
20 #include <spi_flash.h>
21 #include <security/vboot/misc.h>
22 #include <security/vboot/vbnv_layout.h>
25 #if CONFIG(USE_OPTION_TABLE)
26 #include <option_table.h>
29 #if CONFIG(HAVE_ACPI_TABLES)
30 #include <acpi/acpi.h>
32 #include <vendorcode/google/chromeos/chromeos.h>
33 #include <vendorcode/google/chromeos/gnvs.h>
35 #if CONFIG(PLATFORM_USES_FSP2_0)
38 void lb_string_platform_blob_version(struct lb_header
*header
);
41 static struct lb_header
*lb_table_init(unsigned long addr
)
43 struct lb_header
*header
;
45 /* 16 byte align the address */
49 header
= (void *)addr
;
50 header
->signature
[0] = 'L';
51 header
->signature
[1] = 'B';
52 header
->signature
[2] = 'I';
53 header
->signature
[3] = 'O';
54 header
->header_bytes
= sizeof(*header
);
55 header
->header_checksum
= 0;
56 header
->table_bytes
= 0;
57 header
->table_checksum
= 0;
58 header
->table_entries
= 0;
62 static struct lb_record
*lb_first_record(struct lb_header
*header
)
64 struct lb_record
*rec
;
65 rec
= (void *)(((char *)header
) + sizeof(*header
));
69 static struct lb_record
*lb_last_record(struct lb_header
*header
)
71 struct lb_record
*rec
;
72 rec
= (void *)(((char *)header
) + sizeof(*header
)
73 + header
->table_bytes
);
77 struct lb_record
*lb_new_record(struct lb_header
*header
)
79 struct lb_record
*rec
;
80 rec
= lb_last_record(header
);
81 if (header
->table_entries
)
82 header
->table_bytes
+= rec
->size
;
83 rec
= lb_last_record(header
);
84 header
->table_entries
++;
85 rec
->tag
= LB_TAG_UNUSED
;
86 rec
->size
= sizeof(*rec
);
90 static struct lb_memory
*lb_memory(struct lb_header
*header
)
92 struct lb_record
*rec
;
93 struct lb_memory
*mem
;
94 rec
= lb_new_record(header
);
95 mem
= (struct lb_memory
*)rec
;
96 mem
->tag
= LB_TAG_MEMORY
;
97 mem
->size
= sizeof(*mem
);
101 void lb_add_serial(struct lb_serial
*new_serial
, void *data
)
103 struct lb_header
*header
= (struct lb_header
*)data
;
104 struct lb_serial
*serial
;
106 serial
= (struct lb_serial
*)lb_new_record(header
);
107 serial
->tag
= LB_TAG_SERIAL
;
108 serial
->size
= sizeof(*serial
);
109 serial
->type
= new_serial
->type
;
110 serial
->baseaddr
= new_serial
->baseaddr
;
111 serial
->baud
= new_serial
->baud
;
112 serial
->regwidth
= new_serial
->regwidth
;
113 serial
->input_hertz
= new_serial
->input_hertz
;
114 serial
->uart_pci_addr
= new_serial
->uart_pci_addr
;
117 void lb_add_console(uint16_t consoletype
, void *data
)
119 struct lb_header
*header
= (struct lb_header
*)data
;
120 struct lb_console
*console
;
122 console
= (struct lb_console
*)lb_new_record(header
);
123 console
->tag
= LB_TAG_CONSOLE
;
124 console
->size
= sizeof(*console
);
125 console
->type
= consoletype
;
128 static void lb_framebuffer(struct lb_header
*header
)
130 struct lb_framebuffer
*framebuffer
;
131 struct lb_framebuffer fb
= {0};
133 if (!CONFIG(LINEAR_FRAMEBUFFER
) || fill_lb_framebuffer(&fb
))
136 framebuffer
= (struct lb_framebuffer
*)lb_new_record(header
);
137 memcpy(framebuffer
, &fb
, sizeof(*framebuffer
));
138 framebuffer
->tag
= LB_TAG_FRAMEBUFFER
;
139 framebuffer
->size
= sizeof(*framebuffer
);
141 if (CONFIG(BOOTSPLASH
)) {
142 uint8_t *fb_ptr
= (uint8_t *)(uintptr_t)framebuffer
->physical_address
;
143 unsigned int width
= framebuffer
->x_resolution
;
144 unsigned int height
= framebuffer
->y_resolution
;
145 unsigned int depth
= framebuffer
->bits_per_pixel
;
146 set_bootsplash(fb_ptr
, width
, height
, depth
);
150 void lb_add_gpios(struct lb_gpios
*gpios
, const struct lb_gpio
*gpio_table
,
153 size_t table_size
= count
* sizeof(struct lb_gpio
);
155 memcpy(&gpios
->gpios
[gpios
->count
], gpio_table
, table_size
);
156 gpios
->count
+= count
;
157 gpios
->size
+= table_size
;
161 static void lb_gpios(struct lb_header
*header
)
163 struct lb_gpios
*gpios
;
166 gpios
= (struct lb_gpios
*)lb_new_record(header
);
167 gpios
->tag
= LB_TAG_GPIO
;
168 gpios
->size
= sizeof(*gpios
);
170 fill_lb_gpios(gpios
);
172 printk(BIOS_INFO
, "Passing %u GPIOs to payload:\n"
173 " NAME | PORT | POLARITY | VALUE\n",
175 for (g
= &gpios
->gpios
[0]; g
< &gpios
->gpios
[gpios
->count
]; g
++) {
176 printk(BIOS_INFO
, "%16s | ", g
->name
);
178 printk(BIOS_INFO
, " undefined | ");
180 printk(BIOS_INFO
, "%#.8x | ", g
->port
);
181 if (g
->polarity
== ACTIVE_HIGH
)
182 printk(BIOS_INFO
, " high | ");
184 printk(BIOS_INFO
, " low | ");
187 printk(BIOS_INFO
, " low\n");
190 printk(BIOS_INFO
, " high\n");
193 printk(BIOS_INFO
, "undefined\n");
199 static void lb_vbnv(struct lb_header
*header
)
201 #if CONFIG(PC80_SYSTEM)
202 struct lb_range
*vbnv
;
204 vbnv
= (struct lb_range
*)lb_new_record(header
);
205 vbnv
->tag
= LB_TAG_VBNV
;
206 vbnv
->size
= sizeof(*vbnv
);
207 vbnv
->range_start
= CONFIG_VBOOT_VBNV_OFFSET
+ 14;
208 vbnv
->range_size
= VBOOT_VBNV_BLOCK_SIZE
;
211 #endif /* CONFIG_CHROMEOS */
213 __weak
uint32_t board_id(void) { return UNDEFINED_STRAPPING_ID
; }
214 __weak
uint32_t ram_code(void) { return UNDEFINED_STRAPPING_ID
; }
215 __weak
uint32_t sku_id(void) { return UNDEFINED_STRAPPING_ID
; }
217 static void lb_board_id(struct lb_header
*header
)
219 struct lb_strapping_id
*rec
;
220 uint32_t bid
= board_id();
222 if (bid
== UNDEFINED_STRAPPING_ID
)
225 rec
= (struct lb_strapping_id
*)lb_new_record(header
);
227 rec
->tag
= LB_TAG_BOARD_ID
;
228 rec
->size
= sizeof(*rec
);
231 printk(BIOS_INFO
, "Board ID: %d\n", bid
);
234 static void lb_boot_media_params(struct lb_header
*header
)
236 struct lb_boot_media_params
*bmp
;
237 const struct region_device
*boot_dev
;
238 struct region_device cbfs_dev
;
242 if (cbfs_boot_region_device(&cbfs_dev
))
245 boot_dev
= boot_device_ro();
246 if (boot_dev
== NULL
)
249 bmp
= (struct lb_boot_media_params
*)lb_new_record(header
);
250 bmp
->tag
= LB_TAG_BOOT_MEDIA_PARAMS
;
251 bmp
->size
= sizeof(*bmp
);
253 bmp
->cbfs_offset
= region_device_offset(&cbfs_dev
);
254 bmp
->cbfs_size
= region_device_sz(&cbfs_dev
);
255 bmp
->boot_media_size
= region_device_sz(boot_dev
);
257 bmp
->fmap_offset
= get_fmap_flash_offset();
260 static void lb_ram_code(struct lb_header
*header
)
262 struct lb_strapping_id
*rec
;
263 uint32_t code
= ram_code();
265 if (code
== UNDEFINED_STRAPPING_ID
)
268 rec
= (struct lb_strapping_id
*)lb_new_record(header
);
270 rec
->tag
= LB_TAG_RAM_CODE
;
271 rec
->size
= sizeof(*rec
);
274 printk(BIOS_INFO
, "RAM code: %d\n", code
);
277 static void lb_sku_id(struct lb_header
*header
)
279 struct lb_strapping_id
*rec
;
280 uint32_t sid
= sku_id();
282 if (sid
== UNDEFINED_STRAPPING_ID
)
285 rec
= (struct lb_strapping_id
*)lb_new_record(header
);
287 rec
->tag
= LB_TAG_SKU_ID
;
288 rec
->size
= sizeof(*rec
);
291 printk(BIOS_INFO
, "SKU ID: %d\n", sid
);
294 static void lb_mmc_info(struct lb_header
*header
)
296 struct lb_mmc_info
*rec
;
299 ms_cbmem
= cbmem_find(CBMEM_ID_MMC_STATUS
);
303 rec
= (struct lb_mmc_info
*)lb_new_record(header
);
305 rec
->tag
= LB_TAG_MMC_INFO
;
306 rec
->size
= sizeof(*rec
);
307 rec
->early_cmd1_status
= *ms_cbmem
;
310 static void add_cbmem_pointers(struct lb_header
*header
)
313 * These CBMEM sections' addresses are included in the coreboot table
314 * with the appropriate tags.
316 const struct section_id
{
320 {CBMEM_ID_TIMESTAMP
, LB_TAG_TIMESTAMPS
},
321 {CBMEM_ID_CONSOLE
, LB_TAG_CBMEM_CONSOLE
},
322 {CBMEM_ID_ACPI_GNVS
, LB_TAG_ACPI_GNVS
},
323 {CBMEM_ID_VPD
, LB_TAG_VPD
},
324 {CBMEM_ID_WIFI_CALIBRATION
, LB_TAG_WIFI_CALIBRATION
},
325 {CBMEM_ID_TCPA_LOG
, LB_TAG_TCPA_LOG
},
326 {CBMEM_ID_FMAP
, LB_TAG_FMAP
},
327 {CBMEM_ID_VBOOT_WORKBUF
, LB_TAG_VBOOT_WORKBUF
},
331 for (i
= 0; i
< ARRAY_SIZE(section_ids
); i
++) {
332 const struct section_id
*sid
= section_ids
+ i
;
333 struct lb_cbmem_ref
*cbmem_ref
;
334 void *cbmem_addr
= cbmem_find(sid
->cbmem_id
);
337 continue; /* This section is not present */
339 cbmem_ref
= (struct lb_cbmem_ref
*)lb_new_record(header
);
341 printk(BIOS_ERR
, "No more room in coreboot table!\n");
344 cbmem_ref
->tag
= sid
->table_tag
;
345 cbmem_ref
->size
= sizeof(*cbmem_ref
);
346 cbmem_ref
->cbmem_addr
= (unsigned long)cbmem_addr
;
350 static struct lb_mainboard
*lb_mainboard(struct lb_header
*header
)
352 struct lb_record
*rec
;
353 struct lb_mainboard
*mainboard
;
354 rec
= lb_new_record(header
);
355 mainboard
= (struct lb_mainboard
*)rec
;
356 mainboard
->tag
= LB_TAG_MAINBOARD
;
358 mainboard
->size
= ALIGN_UP(sizeof(*mainboard
) +
359 strlen(mainboard_vendor
) + 1 +
360 strlen(mainboard_part_number
) + 1, 8);
362 mainboard
->vendor_idx
= 0;
363 mainboard
->part_number_idx
= strlen(mainboard_vendor
) + 1;
365 memcpy(mainboard
->strings
+ mainboard
->vendor_idx
,
366 mainboard_vendor
, strlen(mainboard_vendor
) + 1);
367 memcpy(mainboard
->strings
+ mainboard
->part_number_idx
,
368 mainboard_part_number
, strlen(mainboard_part_number
) + 1);
373 #if CONFIG(USE_OPTION_TABLE)
374 static struct cmos_checksum
*lb_cmos_checksum(struct lb_header
*header
)
376 struct lb_record
*rec
;
377 struct cmos_checksum
*cmos_checksum
;
378 rec
= lb_new_record(header
);
379 cmos_checksum
= (struct cmos_checksum
*)rec
;
380 cmos_checksum
->tag
= LB_TAG_OPTION_CHECKSUM
;
382 cmos_checksum
->size
= (sizeof(*cmos_checksum
));
384 cmos_checksum
->range_start
= LB_CKS_RANGE_START
* 8;
385 cmos_checksum
->range_end
= (LB_CKS_RANGE_END
* 8) + 7;
386 cmos_checksum
->location
= LB_CKS_LOC
* 8;
387 cmos_checksum
->type
= CHECKSUM_PCBIOS
;
389 return cmos_checksum
;
393 static void lb_strings(struct lb_header
*header
)
395 static const struct {
399 { LB_TAG_VERSION
, coreboot_version
, },
400 { LB_TAG_EXTRA_VERSION
, coreboot_extra_version
, },
401 { LB_TAG_BUILD
, coreboot_build
, },
402 { LB_TAG_COMPILE_TIME
, coreboot_compile_time
, },
405 for (i
= 0; i
< ARRAY_SIZE(strings
); i
++) {
406 struct lb_string
*rec
;
408 rec
= (struct lb_string
*)lb_new_record(header
);
409 len
= strlen(strings
[i
].string
);
410 rec
->tag
= strings
[i
].tag
;
411 rec
->size
= ALIGN_UP(sizeof(*rec
) + len
+ 1, 8);
412 memcpy(rec
->string
, strings
[i
].string
, len
+1);
417 static void lb_record_version_timestamp(struct lb_header
*header
)
419 struct lb_timestamp
*rec
;
420 rec
= (struct lb_timestamp
*)lb_new_record(header
);
421 rec
->tag
= LB_TAG_VERSION_TIMESTAMP
;
422 rec
->size
= sizeof(*rec
);
423 rec
->timestamp
= coreboot_version_timestamp
;
426 void __weak
lb_board(struct lb_header
*header
) { /* NOOP */ }
429 * It's possible that the system is using a SPI flash as the boot device,
430 * however it is not probing for devices to fill in specifics. In that
431 * case don't provide any information as the correct information is
434 void __weak
lb_spi_flash(struct lb_header
*header
) { /* NOOP */ }
436 static struct lb_forward
*lb_forward(struct lb_header
*header
,
437 struct lb_header
*next_header
)
439 struct lb_record
*rec
;
440 struct lb_forward
*forward
;
441 rec
= lb_new_record(header
);
442 forward
= (struct lb_forward
*)rec
;
443 forward
->tag
= LB_TAG_FORWARD
;
444 forward
->size
= sizeof(*forward
);
445 forward
->forward
= (uint64_t)(unsigned long)next_header
;
449 static unsigned long lb_table_fini(struct lb_header
*head
)
451 struct lb_record
*rec
, *first_rec
;
452 rec
= lb_last_record(head
);
453 if (head
->table_entries
)
454 head
->table_bytes
+= rec
->size
;
456 first_rec
= lb_first_record(head
);
457 head
->table_checksum
= compute_ip_checksum(first_rec
,
459 head
->header_checksum
= 0;
460 head
->header_checksum
= compute_ip_checksum(head
, sizeof(*head
));
462 "Wrote coreboot table at: %p, 0x%x bytes, checksum %x\n",
463 head
, head
->table_bytes
, head
->table_checksum
);
464 return (unsigned long)rec
+ rec
->size
;
467 size_t write_coreboot_forwarding_table(uintptr_t entry
, uintptr_t target
)
469 struct lb_header
*head
;
471 printk(BIOS_DEBUG
, "Writing table forward entry at %p\n",
474 head
= lb_table_init(entry
);
475 lb_forward(head
, (struct lb_header
*)target
);
477 return (uintptr_t)lb_table_fini(head
) - entry
;
480 static uintptr_t write_coreboot_table(uintptr_t rom_table_end
)
482 struct lb_header
*head
;
484 printk(BIOS_DEBUG
, "Writing coreboot table at 0x%08lx\n",
485 (long)rom_table_end
);
487 head
= lb_table_init(rom_table_end
);
489 #if CONFIG(USE_OPTION_TABLE)
491 struct cmos_option_table
*option_table
=
492 cbfs_boot_map_with_leak("cmos_layout.bin",
493 CBFS_COMPONENT_CMOS_LAYOUT
, NULL
);
495 struct lb_record
*rec_dest
= lb_new_record(head
);
496 /* Copy the option config table, it's already a
499 memcpy(rec_dest
, option_table
, option_table
->size
);
500 /* Create CMOS checksum entry in coreboot table */
501 lb_cmos_checksum(head
);
504 "cmos_layout.bin could not be found!\n");
509 /* Serialize resource map into mem table types (LB_MEM_*) */
510 bootmem_write_memory_table(lb_memory(head
));
512 /* Record our motherboard */
515 /* Record the serial ports and consoles */
516 #if CONFIG(CONSOLE_SERIAL)
519 #if CONFIG(CONSOLE_USB)
520 lb_add_console(LB_TAG_CONSOLE_EHCI
, head
);
523 /* Record our various random string information */
525 if (CONFIG(PLATFORM_USES_FSP2_0
))
526 lb_string_platform_blob_version(head
);
527 lb_record_version_timestamp(head
);
528 /* Record our framebuffer */
529 lb_framebuffer(head
);
532 /* Record our GPIO settings (ChromeOS specific) */
535 /* pass along VBNV offsets in CMOS */
539 /* Add strapping IDs if available */
544 /* Pass mmc early init status */
547 /* Add SPI flash description if available */
548 if (CONFIG(BOOT_DEVICE_SPI_FLASH
))
551 add_cbmem_pointers(head
);
554 if (CONFIG(SMMSTORE_V2
))
557 /* Add board-specific table entries, if any. */
560 #if CONFIG(CHROMEOS_RAMOOPS)
564 lb_boot_media_params(head
);
566 /* Add architecture records. */
567 lb_arch_add_records(head
);
569 /* Add all cbmem entries into the coreboot tables. */
570 cbmem_add_records_to_cbtable(head
);
572 /* Remember where my valid memory ranges are */
573 return lb_table_fini(head
);
576 void *write_tables(void)
578 uintptr_t cbtable_start
;
579 uintptr_t cbtable_end
;
581 const size_t max_table_size
= COREBOOT_TABLE_SIZE
;
583 cbtable_start
= (uintptr_t)cbmem_add(CBMEM_ID_CBTABLE
, max_table_size
);
585 if (!cbtable_start
) {
586 printk(BIOS_ERR
, "Could not add CBMEM for coreboot table.\n");
590 /* Add architecture specific tables. */
591 arch_write_tables(cbtable_start
);
593 /* Write the coreboot table. */
594 cbtable_end
= write_coreboot_table(cbtable_start
);
595 cbtable_size
= cbtable_end
- cbtable_start
;
597 if (cbtable_size
> max_table_size
) {
598 printk(BIOS_ERR
, "%s: coreboot table didn't fit (%zx/%zx)\n",
599 __func__
, cbtable_size
, max_table_size
);
602 printk(BIOS_DEBUG
, "coreboot table: %zd bytes.\n", cbtable_size
);
604 /* Print CBMEM sections */
606 return (void *)cbtable_start
;