| /* SPDX-License-Identifier: GPL-2.0-only */ |
| |
| #ifndef COMMONLIB_COREBOOT_TABLES_H |
| #define COMMONLIB_COREBOOT_TABLES_H |
| |
| #include <stdint.h> |
| |
| /* The coreboot table information is for conveying information |
| * from the firmware to the loaded OS image. Primarily this |
| * is expected to be information that cannot be discovered by |
| * other means, such as querying the hardware directly. |
| * |
| * All of the information should be Position Independent Data. |
| * That is it should be safe to relocated any of the information |
| * without it's meaning/correctness changing. For table that |
| * can reasonably be used on multiple architectures the data |
| * size should be fixed. This should ease the transition between |
| * 32 bit and 64 bit architectures etc. |
| * |
| * The completeness test for the information in this table is: |
| * - Can all of the hardware be detected? |
| * - Are the per motherboard constants available? |
| * - Is there enough to allow a kernel to run that was written before |
| * a particular motherboard is constructed? (Assuming the kernel |
| * has drivers for all of the hardware but it does not have |
| * assumptions on how the hardware is connected together). |
| * |
| * With this test it should be straight forward to determine if a |
| * table entry is required or not. This should remove much of the |
| * long term compatibility burden as table entries which are |
| * irrelevant or have been replaced by better alternatives may be |
| * dropped. Of course it is polite and expedite to include extra |
| * table entries and be backwards compatible, but it is not required. |
| */ |
| |
| enum { |
| LB_TAG_UNUSED = 0x0000, |
| LB_TAG_MEMORY = 0x0001, |
| LB_TAG_HWRPB = 0x0002, |
| LB_TAG_MAINBOARD = 0x0003, |
| LB_TAG_VERSION = 0x0004, |
| LB_TAG_EXTRA_VERSION = 0x0005, |
| LB_TAG_BUILD = 0x0006, |
| LB_TAG_COMPILE_TIME = 0x0007, |
| LB_TAG_COMPILE_BY = 0x0008, |
| LB_TAG_COMPILE_HOST = 0x0009, |
| LB_TAG_COMPILE_DOMAIN = 0x000a, |
| LB_TAG_COMPILER = 0x000b, |
| LB_TAG_LINKER = 0x000c, |
| LB_TAG_ASSEMBLER = 0x000d, |
| LB_TAG_SERIAL = 0x000f, |
| LB_TAG_CONSOLE = 0x0010, |
| LB_TAG_FORWARD = 0x0011, |
| LB_TAG_FRAMEBUFFER = 0x0012, |
| LB_TAG_GPIO = 0x0013, |
| LB_TAG_TIMESTAMPS = 0x0016, |
| LB_TAG_CBMEM_CONSOLE = 0x0017, |
| LB_TAG_MRC_CACHE = 0x0018, |
| LB_TAG_VBNV = 0x0019, |
| LB_TAG_VBOOT_HANDOFF = 0x0020, /* deprecated */ |
| LB_TAG_X86_ROM_MTRR = 0x0021, |
| LB_TAG_DMA = 0x0022, |
| LB_TAG_RAM_OOPS = 0x0023, |
| LB_TAG_ACPI_GNVS = 0x0024, |
| LB_TAG_BOARD_ID = 0x0025, /* deprecated */ |
| LB_TAG_VERSION_TIMESTAMP = 0x0026, |
| LB_TAG_WIFI_CALIBRATION = 0x0027, |
| LB_TAG_RAM_CODE = 0x0028, /* deprecated */ |
| LB_TAG_SPI_FLASH = 0x0029, |
| LB_TAG_SERIALNO = 0x002a, |
| LB_TAG_MTC = 0x002b, |
| LB_TAG_VPD = 0x002c, |
| LB_TAG_SKU_ID = 0x002d, /* deprecated */ |
| LB_TAG_BOOT_MEDIA_PARAMS = 0x0030, |
| LB_TAG_CBMEM_ENTRY = 0x0031, |
| LB_TAG_TSC_INFO = 0x0032, |
| LB_TAG_MAC_ADDRS = 0x0033, |
| LB_TAG_VBOOT_WORKBUF = 0x0034, |
| LB_TAG_MMC_INFO = 0x0035, |
| LB_TAG_TPM_CB_LOG = 0x0036, |
| LB_TAG_FMAP = 0x0037, |
| LB_TAG_PLATFORM_BLOB_VERSION = 0x0038, |
| LB_TAG_SMMSTOREV2 = 0x0039, |
| LB_TAG_TPM_PPI_HANDOFF = 0x003a, |
| LB_TAG_BOARD_CONFIG = 0x0040, |
| LB_TAG_ACPI_CNVS = 0x0041, |
| LB_TAG_TYPE_C_INFO = 0x0042, |
| LB_TAG_ACPI_RSDP = 0x0043, |
| LB_TAG_PCIE = 0x0044, |
| /* The following options are CMOS-related */ |
| LB_TAG_CMOS_OPTION_TABLE = 0x00c8, |
| LB_TAG_OPTION = 0x00c9, |
| LB_TAG_OPTION_ENUM = 0x00ca, |
| LB_TAG_OPTION_DEFAULTS = 0x00cb, |
| LB_TAG_OPTION_CHECKSUM = 0x00cc, |
| }; |
| |
| /* All table entry base addresses and sizes must be 4-byte aligned. */ |
| #define LB_ENTRY_ALIGN 4 |
| |
| /* Since coreboot is usually compiled 32bit, gcc will align 64bit |
| * types to 32bit boundaries. If the coreboot table is dumped on a |
| * 64bit system, a uint64_t would be aligned to 64bit boundaries, |
| * breaking the table format. |
| * |
| * lb_uint64_t will keep 64bit coreboot table values aligned to 32bit |
| * to ensure compatibility. |
| */ |
| |
| typedef __aligned(LB_ENTRY_ALIGN) uint64_t lb_uint64_t; |
| |
| struct lb_header { |
| uint8_t signature[4]; /* LBIO */ |
| uint32_t header_bytes; |
| uint32_t header_checksum; |
| uint32_t table_bytes; |
| uint32_t table_checksum; |
| uint32_t table_entries; |
| }; |
| |
| /* Every entry in the boot environment list will correspond to a boot |
| * info record. Encoding both type and size. The type is obviously |
| * so you can tell what it is. The size allows you to skip that |
| * boot environment record if you don't know what it is. This allows |
| * forward compatibility with records not yet defined. |
| */ |
| struct lb_record { |
| uint32_t tag; /* tag ID */ |
| uint32_t size; /* size of record (in bytes) */ |
| }; |
| |
| struct lb_memory_range { |
| lb_uint64_t start; |
| lb_uint64_t size; |
| uint32_t type; |
| #define LB_MEM_RAM 1 /* Memory anyone can use */ |
| #define LB_MEM_RESERVED 2 /* Don't use this memory region */ |
| #define LB_MEM_ACPI 3 /* ACPI Tables */ |
| #define LB_MEM_NVS 4 /* ACPI NVS Memory */ |
| #define LB_MEM_UNUSABLE 5 /* Unusable address space */ |
| #define LB_MEM_VENDOR_RSVD 6 /* Vendor Reserved */ |
| #define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */ |
| #define LB_MEM_SOFT_RESERVED 0xefffffff /* Specific purpose memory */ |
| }; |
| |
| struct lb_memory { |
| uint32_t tag; |
| uint32_t size; |
| struct lb_memory_range map[]; |
| }; |
| |
| struct lb_pcie { |
| uint32_t tag; |
| uint32_t size; |
| lb_uint64_t ctrl_base; /* Base address of PCIe controller */ |
| }; |
| _Static_assert(_Alignof(struct lb_pcie) == 4, |
| "lb_uint64_t alignment doesn't work as expected for struct lb_pcie!"); |
| |
| struct lb_hwrpb { |
| uint32_t tag; |
| uint32_t size; |
| lb_uint64_t hwrpb; |
| }; |
| |
| struct lb_mainboard { |
| uint32_t tag; |
| uint32_t size; |
| uint8_t vendor_idx; |
| uint8_t part_number_idx; |
| uint8_t strings[]; |
| }; |
| |
| struct lb_string { |
| uint32_t tag; |
| uint32_t size; |
| uint8_t string[]; |
| }; |
| |
| struct lb_timestamp { |
| uint32_t tag; |
| uint32_t size; |
| uint32_t timestamp; |
| }; |
| |
| /* 0xe is taken by v3 */ |
| |
| struct lb_serial { |
| uint32_t tag; |
| uint32_t size; |
| #define LB_SERIAL_TYPE_IO_MAPPED 1 |
| #define LB_SERIAL_TYPE_MEMORY_MAPPED 2 |
| uint32_t type; |
| uint32_t baseaddr; |
| uint32_t baud; |
| uint32_t regwidth; |
| |
| /* Crystal or input frequency to the chip containing the UART. |
| * Provide the board specific details to allow the payload to |
| * initialize the chip containing the UART and make independent |
| * decisions as to which dividers to select and their values |
| * to eventually arrive at the desired console baud-rate. */ |
| uint32_t input_hertz; |
| }; |
| |
| struct lb_console { |
| uint32_t tag; |
| uint32_t size; |
| uint16_t type; |
| uint8_t pad[2]; |
| }; |
| |
| #define LB_TAG_CONSOLE_SERIAL8250 0 |
| #define LB_TAG_CONSOLE_VGA 1 // OBSOLETE |
| #define LB_TAG_CONSOLE_BTEXT 2 // OBSOLETE |
| #define LB_TAG_CONSOLE_LOGBUF 3 // OBSOLETE |
| #define LB_TAG_CONSOLE_SROM 4 // OBSOLETE |
| #define LB_TAG_CONSOLE_EHCI 5 |
| #define LB_TAG_CONSOLE_SERIAL8250MEM 6 |
| |
| struct lb_forward { |
| uint32_t tag; |
| uint32_t size; |
| lb_uint64_t forward; |
| }; |
| |
| /** |
| * coreboot framebuffer |
| * |
| * The coreboot framebuffer uses a very common format usually referred |
| * to as "linear framebuffer": |
| * |
| * The first pixel of the framebuffer is the upper left corner, its |
| * address is given by `physical_address`. |
| * |
| * Each pixel is represented by exactly `bits_per_pixel` bits. If a |
| * pixel (or a color component therein) doesn't fill a whole byte or |
| * doesn't start on a byte boundary, it starts at the least signifi- |
| * cant bit not occupied by the previous pixel (or color component). |
| * Pixels (or color components) that span multiple bytes always start |
| * in the byte with the lowest address. |
| * |
| * The framebuffer provides a visible rectangle of `x_resolution` * |
| * `y_resolution` pixels. However, the lines always start at a byte |
| * boundary given by `bytes_per_line`, which may leave a gap after |
| * each line of pixels. Thus, the data for a pixel with the coordi- |
| * nates (x, y) from the upper left corner always starts at |
| * |
| * physical_address + y * bytes_per_line + x * bits_per_pixel / 8 |
| * |
| * `bytes_per_line` is always big enough to hold `x_resolution` |
| * pixels. It can, however, be arbitrarily higher (e.g. to fulfill |
| * hardware constraints or for optimization purposes). The size of |
| * the framebuffer is always `y_resolution * bytes_per_line`. |
| * |
| * The coreboot framebuffer only supports RGB color formats. The |
| * position and size of each color component are specified indivi- |
| * dually by <color>_mask_pos and <color>_mask_size. To allow byte |
| * or word aligned pixels, a fourth (padding) component may be |
| * specified by `reserved_mask_pos` and `reserved_mask_size`. |
| * |
| * Software utilizing the coreboot framebuffer shall consider all |
| * fields described above. It may, however, only implement a subset |
| * of the possible color formats. |
| */ |
| |
| /* |
| * Framebuffer orientation, matches drm_connector.h drm_panel_orientation in the |
| * Linux kernel. |
| */ |
| enum lb_fb_orientation { |
| LB_FB_ORIENTATION_NORMAL = 0, |
| LB_FB_ORIENTATION_BOTTOM_UP = 1, |
| LB_FB_ORIENTATION_LEFT_UP = 2, |
| LB_FB_ORIENTATION_RIGHT_UP = 3, |
| }; |
| |
| struct lb_framebuffer_flags { |
| uint8_t has_external_display : 1; |
| uint8_t reserved : 7; |
| }; |
| |
| struct lb_framebuffer { |
| uint32_t tag; |
| uint32_t size; |
| |
| lb_uint64_t physical_address; |
| uint32_t x_resolution; |
| uint32_t y_resolution; |
| uint32_t bytes_per_line; |
| uint8_t bits_per_pixel; |
| uint8_t red_mask_pos; |
| uint8_t red_mask_size; |
| uint8_t green_mask_pos; |
| uint8_t green_mask_size; |
| uint8_t blue_mask_pos; |
| uint8_t blue_mask_size; |
| uint8_t reserved_mask_pos; |
| uint8_t reserved_mask_size; |
| uint8_t orientation; |
| struct lb_framebuffer_flags flags; |
| uint8_t pad; |
| }; |
| |
| struct lb_gpio { |
| uint32_t port; |
| uint32_t polarity; |
| #define ACTIVE_LOW 0 |
| #define ACTIVE_HIGH 1 |
| uint32_t value; |
| #define GPIO_MAX_NAME_LENGTH 16 |
| uint8_t name[GPIO_MAX_NAME_LENGTH]; |
| }; |
| |
| struct lb_gpios { |
| uint32_t tag; |
| uint32_t size; |
| |
| uint32_t count; |
| struct lb_gpio gpios[]; |
| }; |
| |
| struct lb_range { |
| uint32_t tag; |
| uint32_t size; |
| |
| lb_uint64_t range_start; |
| uint32_t range_size; |
| }; |
| |
| void lb_ramoops(struct lb_header *header); |
| |
| struct lb_cbmem_ref { |
| uint32_t tag; |
| uint32_t size; |
| |
| lb_uint64_t cbmem_addr; |
| }; |
| |
| struct lb_x86_rom_mtrr { |
| uint32_t tag; |
| uint32_t size; |
| /* The variable range MTRR index covering the ROM. */ |
| uint32_t index; |
| }; |
| |
| /* Memory map windows to translate addresses between SPI flash space and host address space. */ |
| struct flash_mmap_window { |
| uint32_t flash_base; |
| uint32_t host_base; |
| uint32_t size; |
| }; |
| |
| struct lb_spi_flash { |
| uint32_t tag; |
| uint32_t size; |
| uint32_t flash_size; |
| uint32_t sector_size; |
| uint32_t erase_cmd; |
| /* |
| * Number of mmap windows used by the platform to decode addresses between SPI flash |
| * space and host address space. This determines the number of entries in mmap_table. |
| */ |
| |
| uint32_t mmap_count; |
| struct flash_mmap_window mmap_table[]; |
| }; |
| |
| struct lb_boot_media_params { |
| uint32_t tag; |
| uint32_t size; |
| /* offsets are relative to start of boot media */ |
| lb_uint64_t fmap_offset; |
| lb_uint64_t cbfs_offset; |
| lb_uint64_t cbfs_size; |
| lb_uint64_t boot_media_size; |
| }; |
| |
| /* |
| * There can be more than one of these records as there is one per cbmem entry. |
| */ |
| struct lb_cbmem_entry { |
| uint32_t tag; |
| uint32_t size; |
| |
| lb_uint64_t address; |
| uint32_t entry_size; |
| uint32_t id; |
| }; |
| |
| struct lb_tsc_info { |
| uint32_t tag; |
| uint32_t size; |
| |
| uint32_t freq_khz; |
| }; |
| |
| struct mac_address { |
| uint8_t mac_addr[6]; |
| uint8_t pad[2]; /* Pad it to 8 bytes to keep it simple. */ |
| }; |
| |
| struct lb_mmc_info { |
| uint32_t tag; |
| uint32_t size; |
| /* |
| * Passes the early mmc status to payload to indicate if firmware |
| * successfully sent CMD0, CMD1 to the card or not. In case of |
| * success, the payload can skip the first step of the initialization |
| * sequence which is to send CMD0, and instead start by sending CMD1 |
| * as described in Jedec Standard JESD83-B1 section 6.4.3. |
| * passes 1 on success |
| */ |
| int32_t early_cmd1_status; |
| }; |
| |
| /* |
| * USB Type-C Port Information |
| * This record contains board-specific type-c port information. |
| * There will be one record per type-C port. |
| * Orientation fields should be of type enum type_c_orientation. |
| */ |
| enum type_c_orientation { |
| /* The orientation of the signal follows the orientation of the CC lines. */ |
| TYPEC_ORIENTATION_NONE, |
| /* The orientation of the signal is fixed to follow CC1 */ |
| TYPEC_ORIENTATION_NORMAL, |
| /* The orientation of the signal is fixed to follow CC2 */ |
| TYPEC_ORIENTATION_REVERSE, |
| }; |
| |
| struct type_c_port_info { |
| uint8_t usb2_port_number; |
| uint8_t usb3_port_number; |
| uint8_t sbu_orientation; |
| uint8_t data_orientation; |
| }; |
| |
| struct type_c_info { |
| uint32_t port_count; |
| struct type_c_port_info port_info[]; |
| }; |
| |
| struct lb_macs { |
| uint32_t tag; |
| uint32_t size; |
| uint32_t count; |
| struct mac_address mac_addrs[]; |
| }; |
| |
| struct lb_board_config { |
| uint32_t tag; |
| uint32_t size; |
| |
| lb_uint64_t fw_config; |
| uint32_t board_id; |
| uint32_t ram_code; |
| uint32_t sku_id; |
| }; |
| |
| #define MAX_SERIALNO_LENGTH 32 |
| |
| /* The following structures are for the CMOS definitions table */ |
| /* CMOS header record */ |
| struct cmos_option_table { |
| uint32_t tag; /* CMOS definitions table type */ |
| uint32_t size; /* size of the entire table */ |
| uint32_t header_length; /* length of header */ |
| }; |
| |
| /* CMOS entry record |
| * This record is variable length. The name field may be |
| * shorter than CMOS_MAX_NAME_LENGTH. The entry may start |
| * anywhere in the byte, but can not span bytes unless it |
| * starts at the beginning of the byte and the length is |
| * fills complete bytes. |
| */ |
| struct cmos_entries { |
| uint32_t tag; /* entry type */ |
| uint32_t size; /* length of this record */ |
| uint32_t bit; /* starting bit from start of image */ |
| uint32_t length; /* length of field in bits */ |
| uint32_t config; /* e=enumeration, h=hex, r=reserved */ |
| uint32_t config_id; /* a number linking to an enumeration record */ |
| #define CMOS_MAX_NAME_LENGTH 32 |
| uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name of entry in ascii, |
| variable length int aligned */ |
| }; |
| |
| /* CMOS enumerations record |
| * This record is variable length. The text field may be |
| * shorter than CMOS_MAX_TEXT_LENGTH. |
| */ |
| struct cmos_enums { |
| uint32_t tag; /* enumeration type */ |
| uint32_t size; /* length of this record */ |
| uint32_t config_id; /* a number identifying the config id */ |
| uint32_t value; /* the value associated with the text */ |
| #define CMOS_MAX_TEXT_LENGTH 32 |
| uint8_t text[CMOS_MAX_TEXT_LENGTH]; /* enum description in ascii, |
| variable length int aligned */ |
| }; |
| |
| /* CMOS defaults record |
| * This record contains default settings for the CMOS ram. |
| */ |
| struct cmos_defaults { |
| uint32_t tag; /* default type */ |
| uint32_t size; /* length of this record */ |
| uint32_t name_length; /* length of the following name field */ |
| uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name identifying the default */ |
| #define CMOS_IMAGE_BUFFER_SIZE 256 |
| uint8_t default_set[CMOS_IMAGE_BUFFER_SIZE]; /* default settings */ |
| }; |
| |
| struct cmos_checksum { |
| uint32_t tag; |
| uint32_t size; |
| /* In practice everything is byte aligned, but things are measured |
| * in bits to be consistent. |
| */ |
| uint32_t range_start; /* First bit that is checksummed (byte aligned) */ |
| uint32_t range_end; /* Last bit that is checksummed (byte aligned) */ |
| uint32_t location; /* First bit of the checksum (byte aligned) */ |
| uint32_t type; /* Checksum algorithm that is used */ |
| #define CHECKSUM_NONE 0 |
| #define CHECKSUM_PCBIOS 1 |
| }; |
| |
| /* SMMSTOREv2 record |
| * This record contains information to use SMMSTOREv2. |
| */ |
| |
| struct lb_smmstorev2 { |
| uint32_t tag; |
| uint32_t size; |
| uint32_t num_blocks; /* Number of writable blocks in SMM */ |
| uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ |
| uint32_t mmap_addr; /* MMIO address of the store for read only access */ |
| uint32_t com_buffer; /* Physical address of the communication buffer */ |
| uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ |
| uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ |
| uint8_t unused[3]; /* Set to zero */ |
| }; |
| |
| enum lb_tpm_ppi_tpm_version { |
| LB_TPM_VERSION_UNSPEC = 0, |
| LB_TPM_VERSION_TPM_VERSION_1_2, |
| LB_TPM_VERSION_TPM_VERSION_2, |
| }; |
| |
| /* |
| * Handoff buffer for TPM Physical Presence Interface. |
| * * ppi_address Pointer to PPI buffer shared with ACPI |
| * The layout of the buffer matches the QEMU virtual memory device |
| * that is generated by QEMU. |
| * See files 'hw/i386/acpi-build.c' and 'include/hw/acpi/tpm.h' |
| * for details. |
| * * tpm_version TPM version: 1 for TPM1.2, 2 for TPM2.0 |
| * * ppi_version BCD encoded version of TPM PPI interface |
| */ |
| struct lb_tpm_physical_presence { |
| uint32_t tag; |
| uint32_t size; |
| uint32_t ppi_address; /* Address of ACPI PPI communication buffer */ |
| uint8_t tpm_version; /* 1: TPM1.2, 2: TPM2.0 */ |
| uint8_t ppi_version; /* BCD encoded */ |
| uint8_t pad[2]; |
| }; |
| |
| |
| /* |
| * Handoff the ACPI RSDP |
| */ |
| struct lb_acpi_rsdp { |
| uint32_t tag; |
| uint32_t size; |
| lb_uint64_t rsdp_pointer; /* Address of the ACPI RSDP */ |
| }; |
| |
| #endif |