1 /* 2 * Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 /* 8 * coreboot(4) driver for FreeBSD 9 * 10 * Structures and constants derived from the coreboot table specification. 11 */ 12 13 #ifndef _DEV_COREBOOT_COREBOOT_H_ 14 #define _DEV_COREBOOT_COREBOOT_H_ 15 16 #include <sys/types.h> 17 #include <sys/conf.h> 18 #include <sys/sysctl.h> 19 #include <sys/bus.h> 20 21 #include <dev/coreboot/corebootio.h> 22 23 #define CB_HEADER_SIGNATURE "LBIO" 24 #define CB_HEADER_SIG_LEN 4 25 26 /* 27 * Memory scan range for coreboot table discovery. 28 * Low memory (0x0–0x1000) contains a forward pointer to the real table. 29 */ 30 #define CB_SCAN_LOW_START 0x00000000 31 #define CB_SCAN_LOW_END 0x00001000 32 #define CB_SCAN_LOW_STEP 16 33 34 /* 35 * Defensive limits for parsing untrusted firmware-provided lengths. 36 */ 37 #define CB_TABLE_ALIGN 4 38 #define CB_MAX_HEADER_BYTES 4096 39 #define CB_MAX_TABLE_BYTES (1024 * 1024) 40 #define CB_MAX_TABLE_MAP_BYTES (CB_MAX_HEADER_BYTES + CB_MAX_TABLE_BYTES) 41 #define CB_MAX_CONSOLE_BYTES (1024 * 1024) 42 43 /* 44 * Coreboot table record tags - only tags we actually parse. 45 * Full enum preserved for forward compatibility (unknown tags are skipped). 46 */ 47 enum cb_tag { 48 CB_TAG_UNUSED = 0x0000, 49 CB_TAG_MAINBOARD = 0x0003, 50 CB_TAG_VERSION = 0x0004, 51 CB_TAG_EXTRA_VERSION = 0x0005, 52 CB_TAG_BUILD = 0x0006, 53 CB_TAG_COMPILE_TIME = 0x0007, 54 CB_TAG_COMPILER = 0x000b, 55 CB_TAG_SERIAL = 0x000f, 56 CB_TAG_CONSOLE = 0x0010, 57 CB_TAG_FORWARD = 0x0011, 58 CB_TAG_FRAMEBUFFER = 0x0012, 59 CB_TAG_GPIO = 0x0013, 60 CB_TAG_TIMESTAMPS = 0x0016, 61 CB_TAG_CBMEM_CONSOLE = 0x0017, 62 CB_TAG_ACPI_GNVS = 0x0024, 63 CB_TAG_VERSION_TIMESTAMP = 0x0026, 64 CB_TAG_WIFI_CALIBRATION = 0x0027, 65 CB_TAG_SPI_FLASH = 0x0029, 66 CB_TAG_SERIALNO = 0x002a, 67 CB_TAG_VPD = 0x002c, 68 CB_TAG_BOOT_MEDIA_PARAMS = 0x0030, 69 CB_TAG_CBMEM_ENTRY = 0x0031, 70 CB_TAG_TSC_INFO = 0x0032, 71 CB_TAG_MAC_ADDRS = 0x0033, 72 CB_TAG_VBOOT_WORKBUF = 0x0034, 73 CB_TAG_MMC_INFO = 0x0035, 74 CB_TAG_TPM_CB_LOG = 0x0036, 75 CB_TAG_FMAP = 0x0037, 76 CB_TAG_PLATFORM_BLOB_VERSION = 0x0038, 77 CB_TAG_SMMSTOREV2 = 0x0039, 78 CB_TAG_TPM_PPI_HANDOFF = 0x003a, 79 CB_TAG_BOARD_CONFIG = 0x0040, 80 CB_TAG_ACPI_CNVS = 0x0041, 81 CB_TAG_TYPE_C_INFO = 0x0042, 82 CB_TAG_ACPI_RSDP = 0x0043, 83 CB_TAG_PCIE = 0x0044, 84 CB_TAG_ROOT_BRIDGE_INFO = 0x0048, 85 }; 86 87 /* 88 * Coreboot table header - located at a physical address found by scanning 89 * low memory for the "LBIO" signature. 90 */ 91 struct cb_header { 92 uint8_t signature[CB_HEADER_SIG_LEN]; 93 uint32_t header_bytes; 94 uint32_t header_checksum; 95 uint32_t table_bytes; 96 uint32_t table_checksum; 97 uint32_t table_entries; 98 } __packed; 99 100 /* 101 * Generic record header - every table entry starts with this. 102 */ 103 struct cb_record { 104 uint32_t tag; 105 uint32_t size; 106 } __packed; 107 108 /* 109 * CB_TAG_FORWARD - pointer to the real table in high memory. 110 */ 111 struct cb_forward { 112 uint32_t tag; 113 uint32_t size; 114 uint64_t forward; 115 } __packed; 116 117 /* 118 * CB_TAG_MAINBOARD - board vendor and part number. 119 * Strings are packed after the struct, indexed by vendor_idx and part_idx. 120 */ 121 struct cb_mainboard { 122 uint32_t tag; 123 uint32_t size; 124 uint8_t vendor_idx; 125 uint8_t part_idx; 126 uint8_t strings[]; 127 } __packed; 128 129 /* 130 * Variable-length string record - used by VERSION, BUILD, COMPILE_*, etc. 131 */ 132 struct cb_string { 133 uint32_t tag; 134 uint32_t size; 135 uint8_t string[]; 136 } __packed; 137 138 /* 139 * CB_TAG_SERIAL - serial port configuration. 140 */ 141 struct cb_serial { 142 uint32_t tag; 143 uint32_t size; 144 uint32_t type; 145 uint32_t baseaddr; 146 uint32_t baud; 147 uint32_t regwidth; 148 uint32_t input_hertz; 149 } __packed; 150 151 /* 152 * CB_TAG_CBMEM_CONSOLE - pointer to firmware console ring buffer. 153 */ 154 struct cb_cbmem_ref { 155 uint32_t tag; 156 uint32_t size; 157 uint64_t cbmem_addr; 158 } __packed; 159 160 /* 161 * CB_TAG_CBMEM_ENTRY - one per CBMEM region. 162 */ 163 struct cb_cbmem_entry { 164 uint32_t tag; 165 uint32_t size; 166 uint64_t address; 167 uint32_t entry_size; 168 uint32_t id; 169 } __packed; 170 171 /* 172 * CB_TAG_TSC_INFO - TSC frequency. 173 */ 174 struct cb_tsc_info { 175 uint32_t tag; 176 uint32_t size; 177 uint32_t freq_khz; 178 } __packed; 179 180 /* 181 * CB_TAG_VERSION_TIMESTAMP - build version timestamp. 182 * timestamp is Unix time in seconds (seconds since 1970-01-01 UTC). 183 */ 184 struct cb_version_timestamp { 185 uint32_t tag; 186 uint32_t size; 187 uint32_t timestamp; 188 } __packed; 189 190 /* 191 * CB_TAG_BOARD_CONFIG - board identification and firmware config. 192 */ 193 struct cb_board_config { 194 uint32_t tag; 195 uint32_t size; 196 uint64_t fw_config; 197 uint32_t board_id; 198 uint32_t ram_code; 199 uint32_t sku_id; 200 } __packed; 201 202 /* 203 * CB_TAG_BOOT_MEDIA_PARAMS - offsets and sizes on boot media. 204 */ 205 struct cb_boot_media_params { 206 uint32_t tag; 207 uint32_t size; 208 uint64_t fmap_offset; 209 uint64_t cbfs_offset; 210 uint64_t cbfs_size; 211 uint64_t boot_media_size; 212 } __packed; 213 214 /* 215 * CB_TAG_MMC_INFO - early eMMC/MMC status. 216 */ 217 struct cb_mmc_info { 218 uint32_t tag; 219 uint32_t size; 220 int32_t early_cmd1_status; 221 } __packed; 222 223 /* 224 * CB_TAG_PCIE - PCIe controller base address. 225 */ 226 struct cb_pcie { 227 uint32_t tag; 228 uint32_t size; 229 uint64_t ctrl_base; 230 } __packed; 231 232 /* 233 * CB_TAG_MAC_ADDRS - factory-provisioned MAC addresses. 234 */ 235 struct cb_mac_address { 236 uint8_t mac_addr[6]; 237 uint8_t pad[2]; 238 } __packed; 239 240 struct cb_macs { 241 uint32_t tag; 242 uint32_t size; 243 uint32_t count; 244 struct cb_mac_address entries[]; 245 } __packed; 246 247 /* 248 * CB_TAG_SPI_FLASH - SPI flash chip parameters. 249 */ 250 struct cb_flash_mmap_window { 251 uint32_t flash_base; 252 uint32_t host_base; 253 uint32_t size; 254 } __packed; 255 256 struct cb_spi_flash { 257 uint32_t tag; 258 uint32_t size; 259 uint32_t flash_size; 260 uint32_t sector_size; 261 uint8_t erase_cmd; 262 uint8_t flags; 263 uint16_t reserved; 264 uint32_t mmap_count; 265 struct cb_flash_mmap_window mmap_table[]; 266 } __packed; 267 268 /* 269 * CB_TAG_CONSOLE - firmware console type. 270 */ 271 struct cb_console { 272 uint32_t tag; 273 uint32_t size; 274 uint16_t type; 275 uint8_t pad[2]; 276 } __packed; 277 278 #define CB_CONSOLE_SERIAL8250 0 279 #define CB_CONSOLE_VGA 1 /* obsolete */ 280 #define CB_CONSOLE_EHCI 5 281 #define CB_CONSOLE_SERIAL8250MEM 6 282 283 /* 284 * CB_TAG_FRAMEBUFFER - linear framebuffer info. 285 * The orientation, flags, and pad fields were added later. 286 * Minimum record size is up to reserved_mask_size (29 bytes). 287 */ 288 #define CB_FRAMEBUFFER_MIN_SIZE 29 289 struct cb_framebuffer { 290 uint32_t tag; 291 uint32_t size; 292 uint64_t physical_address; 293 uint32_t x_resolution; 294 uint32_t y_resolution; 295 uint32_t bytes_per_line; 296 uint8_t bits_per_pixel; 297 uint8_t red_mask_pos; 298 uint8_t red_mask_size; 299 uint8_t green_mask_pos; 300 uint8_t green_mask_size; 301 uint8_t blue_mask_pos; 302 uint8_t blue_mask_size; 303 uint8_t reserved_mask_pos; 304 uint8_t reserved_mask_size; 305 uint8_t orientation; 306 uint8_t flags; 307 uint8_t pad; 308 } __packed; 309 310 /* 311 * CB_TAG_GPIO - GPIO pin states. 312 */ 313 struct cb_gpio { 314 uint32_t port; 315 uint32_t polarity; 316 uint32_t value; 317 uint8_t name[16]; 318 } __packed; 319 320 struct cb_gpios { 321 uint32_t tag; 322 uint32_t size; 323 uint32_t count; 324 struct cb_gpio entries[]; 325 } __packed; 326 327 /* 328 * CB_TAG_TPM_PPI_HANDOFF - TPM Physical Presence Interface handoff. 329 */ 330 struct cb_tpm_ppi { 331 uint32_t tag; 332 uint32_t size; 333 uint32_t ppi_address; 334 uint8_t tpm_version; /* 1=TPM1.2, 2=TPM2.0 */ 335 uint8_t ppi_version; /* BCD encoded */ 336 uint8_t pad[2]; 337 } __packed; 338 339 /* 340 * CB_TAG_SMMSTOREV2 - SMM-based variable store configuration. 341 * 342 * The mmap_addr field was added after the initial implementation. 343 * Older coreboot emits a shorter record (32 bytes) without it. 344 * Consumers must check rec->size to detect whether mmap_addr is present. 345 */ 346 #define CB_SMMSTOREV2_BASE_SIZE 32 /* size without mmap_addr */ 347 struct cb_smmstorev2 { 348 uint32_t tag; 349 uint32_t size; 350 uint32_t num_blocks; 351 uint32_t block_size; 352 uint32_t mmap_addr_lo; /* deprecated 32-bit address */ 353 uint32_t com_buffer; 354 uint32_t com_buffer_size; 355 uint8_t apm_cmd; 356 uint8_t unused[3]; 357 /* Fields below only present if size > CB_SMMSTOREV2_BASE_SIZE */ 358 uint64_t mmap_addr; /* 64-bit address (preferred) */ 359 } __packed; 360 361 /* 362 * CB_TAG_ACPI_RSDP - ACPI Root System Description Pointer address. 363 */ 364 struct cb_acpi_rsdp { 365 uint32_t tag; 366 uint32_t size; 367 uint64_t rsdp_pointer; 368 } __packed; 369 370 /* 371 * CBMEM console ring buffer (in-memory structure at cbmem_addr). 372 * Bit 31 of cursor indicates overflow (ring has wrapped). 373 */ 374 struct cbmem_console { 375 uint32_t size; 376 uint32_t cursor; 377 uint8_t body[]; 378 } __packed; 379 380 #define CBMEM_CONSOLE_CURSOR_MASK ((1 << 28) - 1) 381 #define CBMEM_CONSOLE_OVERFLOW (1 << 31) 382 383 #define CB_MAX_MAC_ADDRS 8 384 #define CB_MAX_GPIOS 32 385 386 /* 387 * Driver softc 388 */ 389 struct coreboot_softc { 390 device_t dev; 391 392 vm_paddr_t table_paddr; 393 vm_size_t table_size; 394 void *table_vaddr; 395 396 char version[64]; 397 char build[64]; 398 char compile_time[64]; 399 char compiler[128]; 400 char extra_version[64]; 401 char platform_blob_version[64]; 402 char serialno[64]; 403 uint32_t version_timestamp; 404 int has_version_timestamp; 405 406 char mb_vendor[64]; 407 char mb_part[64]; 408 409 uint32_t serial_baseaddr; 410 uint32_t serial_baud; 411 uint32_t serial_regwidth; 412 int has_serial; 413 414 uint32_t tsc_freq_khz; 415 int has_tsc_info; 416 417 uint64_t pcie_ctrl_base; 418 int has_pcie; 419 420 uint64_t fmap_offset; 421 uint64_t cbfs_offset; 422 uint64_t cbfs_size; 423 uint64_t boot_media_size; 424 int has_boot_media; 425 426 int32_t mmc_early_cmd1_status; 427 int has_mmc_info; 428 429 vm_paddr_t console_paddr; 430 vm_size_t console_size; 431 uint32_t console_data_size; 432 struct cbmem_console *console_vaddr; 433 int has_console; 434 struct cdev *console_cdev; 435 436 uint32_t cbmem_count; 437 struct cbmem_entry_info cbmem_entries[CB_MAX_CBMEM_ENTRIES]; 438 struct cdev *cbmem_cdev; 439 440 uint64_t fw_config; 441 uint32_t board_id; 442 uint32_t ram_code; 443 uint32_t sku_id; 444 int has_board_config; 445 446 uint32_t mac_count; 447 struct cb_mac_address macs[CB_MAX_MAC_ADDRS]; 448 char mac_strs[CB_MAX_MAC_ADDRS][18]; 449 450 uint64_t acpi_rsdp; 451 int has_acpi_rsdp; 452 453 uint32_t spi_flash_size; 454 uint32_t spi_sector_size; 455 uint8_t spi_erase_cmd; 456 uint8_t spi_flags; 457 int has_spi_flash; 458 459 uint16_t console_type; 460 int has_console_type; 461 462 uint64_t fb_addr; 463 uint32_t fb_x_res; 464 uint32_t fb_y_res; 465 uint32_t fb_stride; 466 uint8_t fb_bpp; 467 int has_framebuffer; 468 469 uint32_t gpio_count; 470 struct cb_gpio gpios[CB_MAX_GPIOS]; 471 472 uint32_t tpm_ppi_addr; 473 uint8_t tpm_version; 474 int has_tpm; 475 476 vm_paddr_t tpm_log_paddr; 477 int has_tpm_log; 478 479 vm_paddr_t acpi_gnvs_paddr; 480 int has_acpi_gnvs; 481 vm_paddr_t acpi_cnvs_paddr; 482 int has_acpi_cnvs; 483 vm_paddr_t vpd_paddr; 484 int has_vpd; 485 vm_paddr_t wifi_cal_paddr; 486 int has_wifi_cal; 487 vm_paddr_t fmap_paddr; 488 int has_fmap; 489 vm_paddr_t vboot_workbuf_paddr; 490 int has_vboot_workbuf; 491 vm_paddr_t type_c_info_paddr; 492 int has_type_c_info; 493 vm_paddr_t root_bridge_info_paddr; 494 int has_root_bridge_info; 495 496 uint32_t smmstore_num_blocks; 497 uint32_t smmstore_block_size; 498 uint64_t smmstore_mmap_addr; 499 uint32_t smmstore_com_buffer; 500 uint8_t smmstore_apm_cmd; 501 int has_smmstore; 502 503 vm_paddr_t timestamps_paddr; 504 int has_timestamps; 505 506 struct sysctl_ctx_list sysctl_ctx; 507 struct sysctl_oid *sysctl_tree; 508 }; 509 510 /* 511 * Generic ID-to-name linear search. 512 * The table must be terminated by an entry with name == NULL. 513 * Returns fallback if no match is found. 514 */ 515 struct cb_id_name { 516 uint32_t id; 517 const char *name; 518 }; 519 520 static __inline const char * 521 cb_id_lookup(const struct cb_id_name *tbl, uint32_t id, const char *fallback) 522 { 523 int i; 524 525 for (i = 0; tbl[i].name != NULL; i++) { 526 if (tbl[i].id == id) 527 return (tbl[i].name); 528 } 529 return (fallback); 530 } 531 532 /* 533 * CBMEM ID to human-readable name lookup. 534 */ 535 static __inline const char * 536 cbmem_id_to_name(uint32_t id) 537 { 538 static const struct cb_id_name names[] = { 539 { CBMEM_ID_ACPI, "ACPI" }, 540 { CBMEM_ID_ACPI_GNVS, "ACPI GNVS" }, 541 { CBMEM_ID_AFTER_CAR, "AFTER CAR" }, 542 { CBMEM_ID_CBTABLE, "COREBOOT" }, 543 { CBMEM_ID_CBTABLE_FWD, "COREBOOT FWD" }, 544 { CBMEM_ID_CBFS_RO_MCACHE, "RO MCACHE" }, 545 { CBMEM_ID_CBFS_RW_MCACHE, "RW MCACHE" }, 546 { CBMEM_ID_CONSOLE, "CONSOLE" }, 547 { CBMEM_ID_ELOG, "ELOG" }, 548 { CBMEM_ID_FMAP, "FMAP" }, 549 { CBMEM_ID_FREESPACE, "FREE SPACE" }, 550 { CBMEM_ID_FSP_RESERVED_MEMORY, "FSP MEMORY" }, 551 { CBMEM_ID_FSP_RUNTIME, "FSP RUNTIME" }, 552 { CBMEM_ID_FSPM_VERSION, "FSPM VERSION" }, 553 { CBMEM_ID_IGD_OPREGION, "IGD OPREGION" }, 554 { CBMEM_ID_IMD_ROOT, "IMD ROOT" }, 555 { CBMEM_ID_IMD_SMALL, "IMD SMALL" }, 556 { CBMEM_ID_MEMINFO, "MEM INFO" }, 557 { CBMEM_ID_MPTABLE, "SMP TABLE" }, 558 { CBMEM_ID_MRCDATA, "MRC DATA" }, 559 { CBMEM_ID_PIRQ, "IRQ TABLE" }, 560 { CBMEM_ID_POWER_STATE, "POWER STATE" }, 561 { CBMEM_ID_RAM_OOPS, "RAMOOPS" }, 562 { CBMEM_ID_RAMSTAGE, "RAMSTAGE" }, 563 { CBMEM_ID_REFCODE, "REFCODE" }, 564 { CBMEM_ID_RESUME, "ACPI RESUME" }, 565 { CBMEM_ID_ROMSTAGE_INFO, "ROMSTAGE" }, 566 { CBMEM_ID_ROMSTAGE_RAM_STACK, "ROMSTG STACK" }, 567 { CBMEM_ID_ROOT, "CBMEM ROOT" }, 568 { CBMEM_ID_SMBIOS, "SMBIOS" }, 569 { CBMEM_ID_SMM_COMBUFFER, "SMM COMBUF" }, 570 { CBMEM_ID_SMM_SAVE_SPACE, "SMM BACKUP" }, 571 { CBMEM_ID_TIMESTAMP, "TIMESTAMP" }, 572 { CBMEM_ID_VBOOT_WORKBUF, "VBOOT WORK" }, 573 { CBMEM_ID_VPD, "VPD" }, 574 { 0, NULL } 575 }; 576 577 return (cb_id_lookup(names, id, "UNKNOWN")); 578 } 579 580 /* 581 * IP-style 16-bit checksum (RFC 1071) over 16-bit words. 582 * When computed over data including its checksum field, result is 0. 583 */ 584 static __inline uint16_t 585 cb_checksum(const void *ptr, size_t len) 586 { 587 const uint8_t *p = (const uint8_t *)ptr; 588 uint32_t sum = 0; 589 size_t i; 590 591 for (i = 0; i + 1 < len; i += 2) 592 sum += (uint32_t)p[i] | ((uint32_t)p[i + 1] << 8); 593 594 if (i < len) 595 sum += p[i]; 596 597 while (sum >> 16) 598 sum = (sum & 0xffff) + (sum >> 16); 599 600 return ((uint16_t)~sum); 601 } 602 603 /* 604 * Destroy a character device and clear the pointer. 605 * Safe to call with a NULL cdev pointer. 606 */ 607 static __inline void 608 coreboot_cdev_destroy(struct cdev **cdevp) 609 { 610 611 if (*cdevp != NULL) { 612 destroy_dev(*cdevp); 613 *cdevp = NULL; 614 } 615 } 616 617 /* Functions exported from coreboot.c */ 618 struct coreboot_softc *coreboot_get_softc(void); 619 620 /* Functions exported from coreboot_console.c */ 621 int coreboot_console_create(struct coreboot_softc *sc); 622 void coreboot_console_destroy(struct coreboot_softc *sc); 623 624 /* Functions exported from coreboot_cbmem.c */ 625 int coreboot_cbmem_create(struct coreboot_softc *sc); 626 void coreboot_cbmem_destroy(struct coreboot_softc *sc); 627 628 /* Functions exported from coreboot_timestamps.c */ 629 int coreboot_timestamps_register(struct coreboot_softc *sc, 630 struct sysctl_oid *parent); 631 632 #endif /* _DEV_COREBOOT_COREBOOT_H_ */ 633