From 1058ab37f7176370e835d53299c2ae44437925e3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 15 Mar 2021 18:00:22 +1300 Subject: [PATCH] x86: coreboot: Update parsing of the latest sysinfo Quite a few new tag types have been added over the years. Bring these into U-Boot so that all required tags can be parsed. Add a proper comment to struct sysinfo_t while we are here, since many of the meanings are not obvious. Signed-off-by: Simon Glass --- arch/x86/include/asm/cb_sysinfo.h | 164 +++++++++++++++- arch/x86/include/asm/coreboot_tables.h | 161 +++++++++++++--- arch/x86/lib/coreboot/cb_sysinfo.c | 257 ++++++++++++++++++++++--- 3 files changed, 525 insertions(+), 57 deletions(-) diff --git a/arch/x86/include/asm/cb_sysinfo.h b/arch/x86/include/asm/cb_sysinfo.h index 419ec52933..675eef6f2c 100644 --- a/arch/x86/include/asm/cb_sysinfo.h +++ b/arch/x86/include/asm/cb_sysinfo.h @@ -14,15 +14,141 @@ #define SYSINFO_MAX_MEM_RANGES 32 /* Allow a maximum of 8 GPIOs */ #define SYSINFO_MAX_GPIOS 8 +/* Up to 10 MAC addresses */ +#define SYSINFO_MAX_MACS 10 +/** + * struct sysinfo_t - Information passed to U-Boot from coreboot + * + * Coreboot passes on a lot of information using a list of individual data + * structures identified by a numeric tag. These are parsed in U-Boot to produce + * this struct. Some of the pointers here point back to the tagged data + * structure, since it is assumed to remain around while U-Boot is running. + * + * The 'cbsysinfo' command can display this information. + * + * @cpu_khz: CPU frequence in KHz (e.g. 1100000) + * @serial: Pointer to the serial information, NULL if none + * @ser_ioport: Not actually provided by a tag and not used on modern hardware, + * which typicaally uses a memory-mapped port + * @ser_base: Not used at all, but present to match up with the coreboot data + * structure + * @n_memranges: Number of memory ranges + * @memrange: List of memory ranges: + * @base: Base address of range + * @size: Size of range in bytes + * @type: Type of range (CB_MEM_RAM, etc.) + * @option_table: Provides a pointer to the CMOS RAM options table, which + * indicates which options are available. The header is followed by a list + * of struct cb_cmos_entries records, so that an option can be found from + * its name. This is not used in U-Boot. NULL if not present + * @cmos_range_start: Start bit of the CMOS checksum range (in fact this must + * be a multiple of 8) + * @cmos_range_end: End bit of the CMOS checksum range (multiple of 8). This is + * the inclusive end. + * @cmos_checksum_location: Location of checksum, multiplied by 8. This is the + * byte offset into the CMOS RAM of the first checksum byte. The second one + * follows immediately. The checksum is a simple 16-bit sum of all the + * bytes from offset cmos_range_start / 8 to cmos_range_end / 8, inclusive, + * in big-endian format (so sum >> 8 is stored in the first byte). + * @vbnv_start: Start offset of CMOS RAM used for Chromium OS verified boot + * (typically 0x34) + * @vbnv_size: Number of bytes used by Chromium OS verified boot (typically + * 0x10) + * @extra_version: Extra version information, typically "" + * @build: Build date, e.g. "Wed Nov 18 02:51:58 UTC 2020" + * @compile_time: Compilation time, e.g. "02:51:58" + * @compile_by: Who compiled coreboot (never set?) + * @compile_host: Name of the machine that compiled coreboot (never set?) + * @compile_domain: Domain name of the machine that compiled coreboot (never + * set?) + * @compiler: Name of the compiler used to build coreboot (never set?) + * @linker: Name of the linker used to build coreboot (never set?) + * @assembler: Name of the assembler used to build coreboot (never set?) + * @cb_version: Coreboot version string, e.g. v1.9308_26_0.0.22-2599-g232f22c75d + * @framebuffer: Address of framebuffer tag, or NULL if none. See + * struct cb_framebuffer for the definition + * @num_gpios: Number of verified-boot GPIOs + * @gpios: List of GPIOs: + * @port: GPIO number, or 0xffffffff if not a GPIO + * @polarity: CB_GPIO_ACTIVE_LOW or CB_GPIO_ACTIVE_HIGH + * @value: Value of GPIO (0 or 1) + * @name: Name of GPIO + * + * A typical list is: + * id: port polarity val name + * 0: - active-high 1 write protect + * 1: - active-high 0 recovery + * 2: - active-high 1 lid + * 3: - active-high 0 power + * 4: - active-high 0 oprom + * 5: 29 active-high 0 EC in RW + * + * @num_macs: Number of MAC addresses + * @macs: List of MAC addresses + * @serialno: Serial number, or NULL (never set?) + * @mbtable: Address of the multiboot table, or NULL. This is a + * struct multiboot_header, not used in U-Boot + * @header: Address of header, if there is a CB_TAG_FORWARD, else NULL + * @mainboard: Pointer to mainboard info or NULL. Typically the vendor is + * "Google" and the part number is "" + * @vboot_handoff: Pointer to Chromium OS verified boot hand-off information. + * This is struct vboot_handoff, providing access to internal information + * generated by coreboot when this is being used + * @vboot_handoff_size: Size of hand-off information (typically 0xc0c) + * @vdat_addr: Pointer to Chromium OS verified boot data, which uses + * struct chromeos_acpi. It sits in the Intel Global NVS struct, after the + * first 0x100 bytes + * @vdat_size: Size of this data, typically 0xf00 + * @smbios_start: Address of SMBIOS tables + * @smbios_size: Size of SMBIOS tables (e.g. 0x800) + * @x86_rom_var_mtrr_index: MTRR number used for ROM caching. Not used in U-Boot + * @tstamp_table: Pointer to timestamp_table, struct timestamp_table + * @cbmem_cons: Pointer to the console dump, struct cbmem_console. This provides + * access to the console output generated by coreboot, typically about 64KB + * and mostly PCI enumeration info + * @mrc_cache: Pointer to memory-reference-code cache, typically NULL + * acpi_gnvs: @Pointer to Intel Global NVS struct, see struct acpi_global_nvs + * @board_id: Board ID indicating the board variant, typically 0xffffffff + * @ram_code: RAM code indicating the SDRAM type, typically 0xffffffff + * @wifi_calibration: WiFi calibration info, NULL if none + * @ramoops_buffer: Address of kernel Ramoops buffer + * @ramoops_buffer_size: Sizeof of Ramoops buffer, typically 1MB + * @spi_flash: Information about SPI flash: + * @size: Size in bytes, e.g. 16MB + * @sector_size; Sector size of flash device, e.g. 4KB + * @erase_cmd: Command used to erase flash, or 0 if not used + * @fmap_offset: SPI-flash offset of the flash map (FMAP) table. This has a + * __FMAP__ header. It provides information about the different top-level + * sections in the SPI flash, e.g. 0x204000 + * @cbfs_offset: SPI-flash offset of the Coreboot Filesystem (CBFS) used for + * read-only data, e.g. 0x205000. This is typically called 'COREBOOT' in + * the flash map. It holds various coreboot binaries as well as + * video-configuration files and graphics data for the Chromium OS + * verified boot user interface. + * @cbfs_size: Size of CBFS, e.g. 0x17b000 + * @boot_media_size; Size of boot media (i.e. SPI flash), e.g. 16MB + * @mtc_start; Start of MTC region (Nvidia private data), 0 if not used. See + * https://chromium.googlesource.com/chromiumos/third_party/coreboot/+/chromeos-2013.04/src/soc/nvidia/tegra210/mtc.c + * @mtc_size: Size of MTC region + * @chromeos_vpd: Chromium OS Vital Product Data region, typically NULL, meaning + * not used + */ struct sysinfo_t { + unsigned int cpu_khz; + struct cb_serial *serial; + unsigned short ser_ioport; + unsigned long ser_base; // for mmapped serial + int n_memranges; + struct memrange { unsigned long long base; unsigned long long size; unsigned int type; } memrange[SYSINFO_MAX_MEM_RANGES]; + struct cb_cmos_option_table *option_table; u32 cmos_range_start; u32 cmos_range_end; u32 cmos_checksum_location; @@ -40,19 +166,51 @@ struct sysinfo_t { char *linker; char *assembler; + char *cb_version; + struct cb_framebuffer *framebuffer; int num_gpios; struct cb_gpio gpios[SYSINFO_MAX_GPIOS]; + int num_macs; + struct mac_address macs[SYSINFO_MAX_MACS]; + char *serialno; + + unsigned long *mbtable; /** Pointer to the multiboot table */ + struct cb_header *header; + struct cb_mainboard *mainboard; + + void *vboot_handoff; + u32 vboot_handoff_size; void *vdat_addr; u32 vdat_size; - void *tstamp_table; - void *cbmem_cons; u64 smbios_start; u32 smbios_size; - struct cb_serial *serial; + int x86_rom_var_mtrr_index; + + void *tstamp_table; + void *cbmem_cons; + void *mrc_cache; + void *acpi_gnvs; + u32 board_id; + u32 ram_code; + void *wifi_calibration; + u64 ramoops_buffer; + u32 ramoops_buffer_size; + struct { + u32 size; + u32 sector_size; + u32 erase_cmd; + } spi_flash; + u64 fmap_offset; + u64 cbfs_offset; + u64 cbfs_size; + u64 boot_media_size; + u64 mtc_start; + u32 mtc_size; + void *chromeos_vpd; }; extern struct sysinfo_t lib_sysinfo; diff --git a/arch/x86/include/asm/coreboot_tables.h b/arch/x86/include/asm/coreboot_tables.h index 3172814d09..a74654bbe3 100644 --- a/arch/x86/include/asm/coreboot_tables.h +++ b/arch/x86/include/asm/coreboot_tables.h @@ -262,13 +262,14 @@ struct cb_framebuffer { }; #define CB_TAG_GPIO 0x0013 -#define GPIO_MAX_NAME_LENGTH 16 - +#define CB_GPIO_ACTIVE_LOW 0 +#define CB_GPIO_ACTIVE_HIGH 1 +#define CB_GPIO_MAX_NAME_LENGTH 16 struct cb_gpio { u32 port; u32 polarity; u32 value; - u8 name[GPIO_MAX_NAME_LENGTH]; + u8 name[CB_GPIO_MAX_NAME_LENGTH]; }; struct cb_gpios { @@ -281,61 +282,158 @@ struct cb_gpios { #define CB_TAG_FDT 0x0014 struct cb_fdt { - uint32_t tag; - uint32_t size; /* size of the entire entry */ + u32 tag; + u32 size; /* size of the entire entry */ /* the actual FDT gets placed here */ }; #define CB_TAG_VDAT 0x0015 struct cb_vdat { - uint32_t tag; - uint32_t size; /* size of the entire entry */ + u32 tag; + u32 size; /* size of the entire entry */ void *vdat_addr; - uint32_t vdat_size; + u32 vdat_size; }; #define CB_TAG_TIMESTAMPS 0x0016 #define CB_TAG_CBMEM_CONSOLE 0x0017 + +struct cbmem_console { + u32 size; + u32 cursor; + char body[0]; +} __packed; + #define CB_TAG_MRC_CACHE 0x0018 struct cb_cbmem_tab { - uint32_t tag; - uint32_t size; - void *cbmem_tab; + u32 tag; + u32 size; + u64 cbmem_tab; }; #define CB_TAG_VBNV 0x0019 struct cb_vbnv { - uint32_t tag; - uint32_t size; - uint32_t vbnv_start; - uint32_t vbnv_size; + u32 tag; + u32 size; + u32 vbnv_start; + u32 vbnv_size; +}; + +#define CB_TAG_VBOOT_HANDOFF 0x0020 + +#define CB_TAG_X86_ROM_MTRR 0x0021 +struct cb_x86_rom_mtrr { + u32 tag; + u32 size; + /* + * The variable range MTRR index covering the ROM. If one wants to + * enable caching the ROM, the variable MTRR needs to be set to + * write-protect. To disable the caching after enabling set the + * type to uncacheable + */ + u32 index; +}; + +#define CB_TAG_DMA 0x0022 +#define CB_TAG_RAM_OOPS 0x0023 +#define CB_TAG_ACPI_GNVS 0x0024 + +#define CB_TAG_BOARD_ID 0x0025 +struct cb_board_id { + u32 tag; + u32 size; + /* Board ID as retrieved from the board revision GPIOs. */ + u32 board_id; +}; + +#define CB_TAG_MAC_ADDRS 0x0026 +struct mac_address { + u8 mac_addr[6]; + u8 pad[2]; /* Pad it to 8 bytes to keep it simple. */ +}; + +struct cb_macs { + u32 tag; + u32 size; + u32 count; + struct mac_address mac_addrs[0]; }; -#define CB_TAG_CBMEM_ENTRY 0x0031 -#define CBMEM_ID_SMBIOS 0x534d4254 +#define CB_TAG_WIFI_CALIBRATION 0x0027 + +#define CB_TAG_RAM_CODE 0x0028 +struct cb_ram_code { + u32 tag; + u32 size; + u32 ram_code; +}; + +#define CB_TAG_SPI_FLASH 0x0029 +struct cb_spi_flash { + u32 tag; + u32 size; + u32 flash_size; + u32 sector_size; + u32 erase_cmd; +}; + +#define CB_TAG_MTC 0x002b +#define CB_TAG_VPD 0x002c +struct lb_range { + u32 tag; + u32 size; + u64 range_start; + u32 range_size; +}; + +#define CB_TAG_BOOT_MEDIA_PARAMS 0x0030 +struct cb_boot_media_params { + u32 tag; + u32 size; + /* offsets are relative to start of boot media */ + u64 fmap_offset; + u64 cbfs_offset; + u64 cbfs_size; + u64 boot_media_size; +}; + +#define CB_TAG_CBMEM_ENTRY 0x0031 +#define CBMEM_ID_SMBIOS 0x534d4254 struct cb_cbmem_entry { - uint32_t tag; - uint32_t size; - uint64_t address; - uint32_t entry_size; - uint32_t id; + u32 tag; + u32 size; + u64 address; + u32 entry_size; + u32 id; }; +#define CB_TAG_TSC_INFO 0x0032 +struct cb_tsc_info { + u32 tag; + u32 size; + + u32 freq_khz; +}; + +#define CB_TAG_SERIALNO 0x002a +#define CB_MAX_SERIALNO_LENGTH 32 + #define CB_TAG_CMOS_OPTION_TABLE 0x00c8 struct cb_cmos_option_table { u32 tag; u32 size; u32 header_length; + /* entries follow after this header */ }; #define CB_TAG_OPTION 0x00c9 -#define CMOS_MAX_NAME_LENGTH 32 +#define CB_CMOS_MAX_NAME_LENGTH 32 struct cb_cmos_entries { u32 tag; @@ -344,34 +442,33 @@ struct cb_cmos_entries { u32 length; u32 config; u32 config_id; - u8 name[CMOS_MAX_NAME_LENGTH]; + u8 name[CB_CMOS_MAX_NAME_LENGTH]; }; #define CB_TAG_OPTION_ENUM 0x00ca -#define CMOS_MAX_TEXT_LENGTH 32 - +#define CB_CMOS_MAX_TEXT_LENGTH 32 struct cb_cmos_enums { u32 tag; u32 size; u32 config_id; u32 value; - u8 text[CMOS_MAX_TEXT_LENGTH]; + u8 text[CB_CMOS_MAX_TEXT_LENGTH]; }; #define CB_TAG_OPTION_DEFAULTS 0x00cb -#define CMOS_IMAGE_BUFFER_SIZE 128 +#define CB_CMOS_IMAGE_BUFFER_SIZE 128 struct cb_cmos_defaults { u32 tag; u32 size; u32 name_length; - u8 name[CMOS_MAX_NAME_LENGTH]; - u8 default_set[CMOS_IMAGE_BUFFER_SIZE]; + u8 name[CB_CMOS_MAX_NAME_LENGTH]; + u8 default_set[CB_CMOS_IMAGE_BUFFER_SIZE]; }; #define CB_TAG_OPTION_CHECKSUM 0x00cc -#define CHECKSUM_NONE 0 -#define CHECKSUM_PCBIOS 1 +#define CB_CHECKSUM_NONE 0 +#define CB_CHECKSUM_PCBIOS 1 struct cb_cmos_checksum { u32 tag; diff --git a/arch/x86/lib/coreboot/cb_sysinfo.c b/arch/x86/lib/coreboot/cb_sysinfo.c index 816a0efd13..e2c65bfb1e 100644 --- a/arch/x86/lib/coreboot/cb_sysinfo.c +++ b/arch/x86/lib/coreboot/cb_sysinfo.c @@ -7,8 +7,10 @@ */ #include -#include #include +#include +#include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -29,7 +31,7 @@ struct sysinfo_t lib_sysinfo __attribute__((section(".data"))); */ /* === Parsing code === */ -/* This is the generic parsing code. */ +/* This is the generic parsing code */ static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info) { @@ -61,15 +63,24 @@ static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info) static void cb_parse_serial(unsigned char *ptr, struct sysinfo_t *info) { struct cb_serial *ser = (struct cb_serial *)ptr; + info->serial = ser; } +static void cb_parse_vboot_handoff(unsigned char *ptr, struct sysinfo_t *info) +{ + struct lb_range *vbho = (struct lb_range *)ptr; + + info->vboot_handoff = (void *)(uintptr_t)vbho->range_start; + info->vboot_handoff_size = vbho->range_size; +} + static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info) { - struct cb_vbnv *vbnv = (struct cb_vbnv *)ptr; + struct lb_range *vbnv = (struct lb_range *)ptr; - info->vbnv_start = vbnv->vbnv_start; - info->vbnv_size = vbnv->vbnv_size; + info->vbnv_start = vbnv->range_start; + info->vbnv_size = vbnv->range_size; } static void cb_parse_cbmem_entry(unsigned char *ptr, struct sysinfo_t *info) @@ -97,25 +108,79 @@ static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info) static void cb_parse_vdat(unsigned char *ptr, struct sysinfo_t *info) { - struct cb_vdat *vdat = (struct cb_vdat *) ptr; + struct lb_range *vdat = (struct lb_range *)ptr; + + info->vdat_addr = map_sysmem(vdat->range_start, vdat->range_size); + info->vdat_size = vdat->range_size; +} + +static void cb_parse_mac_addresses(unsigned char *ptr, + struct sysinfo_t *info) +{ + struct cb_macs *macs = (struct cb_macs *)ptr; + int i; + + info->num_macs = (macs->count < ARRAY_SIZE(info->macs)) ? + macs->count : ARRAY_SIZE(info->macs); + + for (i = 0; i < info->num_macs; i++) + info->macs[i] = macs->mac_addrs[i]; +} + +static void cb_parse_tstamp(void *ptr, struct sysinfo_t *info) +{ + struct cb_cbmem_tab *const cbmem = ptr; + + info->tstamp_table = map_sysmem(cbmem->cbmem_tab, 0); +} + +static void cb_parse_cbmem_cons(void *ptr, struct sysinfo_t *info) +{ + struct cb_cbmem_tab *const cbmem = ptr; + + info->cbmem_cons = map_sysmem(cbmem->cbmem_tab, 0); +} + +static void cb_parse_acpi_gnvs(unsigned char *ptr, struct sysinfo_t *info) +{ + struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr; - info->vdat_addr = vdat->vdat_addr; - info->vdat_size = vdat->vdat_size; + info->acpi_gnvs = map_sysmem(cbmem->cbmem_tab, 0); } -static void cb_parse_tstamp(unsigned char *ptr, struct sysinfo_t *info) +static void cb_parse_board_id(unsigned char *ptr, struct sysinfo_t *info) { - info->tstamp_table = ((struct cb_cbmem_tab *)ptr)->cbmem_tab; + struct cb_board_id *const cbbid = (struct cb_board_id *)ptr; + + info->board_id = cbbid->board_id; } -static void cb_parse_cbmem_cons(unsigned char *ptr, struct sysinfo_t *info) +static void cb_parse_ram_code(unsigned char *ptr, struct sysinfo_t *info) { - info->cbmem_cons = ((struct cb_cbmem_tab *)ptr)->cbmem_tab; + struct cb_ram_code *const ram_code = (struct cb_ram_code *)ptr; + + info->ram_code = ram_code->ram_code; } -static void cb_parse_framebuffer(unsigned char *ptr, struct sysinfo_t *info) +static void cb_parse_optiontable(void *ptr, struct sysinfo_t *info) { - info->framebuffer = (struct cb_framebuffer *)ptr; + /* ptr points to a coreboot table entry and is already virtual */ + info->option_table = ptr; +} + +static void cb_parse_checksum(void *ptr, struct sysinfo_t *info) +{ + struct cb_cmos_checksum *cmos_cksum = ptr; + + info->cmos_range_start = cmos_cksum->range_start; + info->cmos_range_end = cmos_cksum->range_end; + info->cmos_checksum_location = cmos_cksum->location; +} + +static void cb_parse_framebuffer(void *ptr, struct sysinfo_t *info) +{ + /* ptr points to a coreboot table entry and is already virtual */ + info->framebuffer = ptr; } static void cb_parse_string(unsigned char *ptr, char **info) @@ -123,6 +188,82 @@ static void cb_parse_string(unsigned char *ptr, char **info) *info = (char *)((struct cb_string *)ptr)->string; } +static void cb_parse_wifi_calibration(void *ptr, struct sysinfo_t *info) +{ + struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr; + + info->wifi_calibration = map_sysmem(cbmem->cbmem_tab, 0); +} + +static void cb_parse_ramoops(void *ptr, struct sysinfo_t *info) +{ + struct lb_range *ramoops = (struct lb_range *)ptr; + + info->ramoops_buffer = ramoops->range_start; + info->ramoops_buffer_size = ramoops->range_size; +} + +static void cb_parse_mtc(void *ptr, struct sysinfo_t *info) +{ + struct lb_range *mtc = (struct lb_range *)ptr; + + info->mtc_start = mtc->range_start; + info->mtc_size = mtc->range_size; +} + +static void cb_parse_spi_flash(void *ptr, struct sysinfo_t *info) +{ + struct cb_spi_flash *flash = (struct cb_spi_flash *)ptr; + + info->spi_flash.size = flash->flash_size; + info->spi_flash.sector_size = flash->sector_size; + info->spi_flash.erase_cmd = flash->erase_cmd; +} + +static void cb_parse_boot_media_params(unsigned char *ptr, + struct sysinfo_t *info) +{ + struct cb_boot_media_params *const bmp = + (struct cb_boot_media_params *)ptr; + + info->fmap_offset = bmp->fmap_offset; + info->cbfs_offset = bmp->cbfs_offset; + info->cbfs_size = bmp->cbfs_size; + info->boot_media_size = bmp->boot_media_size; +} + +static void cb_parse_vpd(void *ptr, struct sysinfo_t *info) +{ + struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr; + + info->chromeos_vpd = map_sysmem(cbmem->cbmem_tab, 0); +} + +static void cb_parse_tsc_info(void *ptr, struct sysinfo_t *info) +{ + const struct cb_tsc_info *tsc_info = ptr; + + if (tsc_info->freq_khz == 0) + return; + + /* Honor the TSC frequency passed to the payload */ + info->cpu_khz = tsc_info->freq_khz; +} + +static void cb_parse_x86_rom_var_mtrr(void *ptr, struct sysinfo_t *info) +{ + struct cb_x86_rom_mtrr *rom_mtrr = ptr; + + info->x86_rom_var_mtrr_index = rom_mtrr->index; +} + +static void cb_parse_mrc_cache(void *ptr, struct sysinfo_t *info) +{ + struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr; + + info->mrc_cache = map_sysmem(cbmem->cbmem_tab, 0); +} + __weak void cb_parse_unhandled(u32 tag, unsigned char *ptr) { } @@ -137,7 +278,7 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) if (!header->table_bytes) return 0; - /* Make sure the checksums match. */ + /* Make sure the checksums match */ if (!ip_checksum_ok(header, sizeof(*header))) return -1; @@ -145,16 +286,26 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) header->table_checksum) return -1; - /* Now, walk the tables. */ + info->header = header; + + /* + * Board straps represented by numerical values are small numbers. + * Preset them to an invalid value in case the firmware does not + * supply the info. + */ + info->board_id = ~0; + info->ram_code = ~0; + + /* Now, walk the tables */ ptr += header->header_bytes; - /* Inintialize some fields to sentinel values. */ + /* Inintialize some fields to sentinel values */ info->vbnv_start = info->vbnv_size = (uint32_t)(-1); for (i = 0; i < header->table_entries; i++) { struct cb_record *rec = (struct cb_record *)ptr; - /* We only care about a few tags here (maybe more later). */ + /* We only care about a few tags here (maybe more later) */ switch (rec->tag) { case CB_TAG_FORWARD: return cb_parse_header( @@ -169,7 +320,7 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) cb_parse_serial(ptr, info); break; case CB_TAG_VERSION: - cb_parse_string(ptr, &info->version); + cb_parse_string(ptr, &info->cb_version); break; case CB_TAG_EXTRA_VERSION: cb_parse_string(ptr, &info->extra_version); @@ -198,6 +349,12 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) case CB_TAG_ASSEMBLER: cb_parse_string(ptr, &info->assembler); break; + case CB_TAG_CMOS_OPTION_TABLE: + cb_parse_optiontable(ptr, info); + break; + case CB_TAG_OPTION_CHECKSUM: + cb_parse_checksum(ptr, info); + break; /* * FIXME we should warn on serial if coreboot set up a * framebuffer buf the payload does not know about it. @@ -205,24 +362,72 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) case CB_TAG_FRAMEBUFFER: cb_parse_framebuffer(ptr, info); break; + case CB_TAG_MAINBOARD: + info->mainboard = (struct cb_mainboard *)ptr; + break; case CB_TAG_GPIO: cb_parse_gpios(ptr, info); break; case CB_TAG_VDAT: cb_parse_vdat(ptr, info); break; + case CB_TAG_VBNV: + cb_parse_vbnv(ptr, info); + break; + case CB_TAG_VBOOT_HANDOFF: + cb_parse_vboot_handoff(ptr, info); + break; + case CB_TAG_MAC_ADDRS: + cb_parse_mac_addresses(ptr, info); + break; + case CB_TAG_SERIALNO: + cb_parse_string(ptr, &info->serialno); + break; case CB_TAG_TIMESTAMPS: cb_parse_tstamp(ptr, info); break; case CB_TAG_CBMEM_CONSOLE: cb_parse_cbmem_cons(ptr, info); break; - case CB_TAG_VBNV: - cb_parse_vbnv(ptr, info); + case CB_TAG_ACPI_GNVS: + cb_parse_acpi_gnvs(ptr, info); break; case CB_TAG_CBMEM_ENTRY: cb_parse_cbmem_entry(ptr, info); break; + case CB_TAG_BOARD_ID: + cb_parse_board_id(ptr, info); + break; + case CB_TAG_RAM_CODE: + cb_parse_ram_code(ptr, info); + break; + case CB_TAG_WIFI_CALIBRATION: + cb_parse_wifi_calibration(ptr, info); + break; + case CB_TAG_RAM_OOPS: + cb_parse_ramoops(ptr, info); + break; + case CB_TAG_SPI_FLASH: + cb_parse_spi_flash(ptr, info); + break; + case CB_TAG_MTC: + cb_parse_mtc(ptr, info); + break; + case CB_TAG_BOOT_MEDIA_PARAMS: + cb_parse_boot_media_params(ptr, info); + break; + case CB_TAG_TSC_INFO: + cb_parse_tsc_info(ptr, info); + break; + case CB_TAG_VPD: + cb_parse_vpd(ptr, info); + break; + case CB_TAG_X86_ROM_MTRR: + cb_parse_x86_rom_var_mtrr(rec, info); + break; + case CB_TAG_MRC_CACHE: + cb_parse_mrc_cache(rec, info); + break; default: cb_parse_unhandled(rec->tag, ptr); break; @@ -235,7 +440,7 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) } /* == Architecture specific == */ -/* This is the x86 specific stuff. */ +/* This is the x86 specific stuff */ int get_coreboot_info(struct sysinfo_t *info) { @@ -253,3 +458,11 @@ int get_coreboot_info(struct sysinfo_t *info) return 0; } + +const struct sysinfo_t *cb_get_sysinfo(void) +{ + if (!ll_boot_init()) + return &lib_sysinfo; + + return NULL; +} -- 2.39.5