]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
x86: coreboot: Update parsing of the latest sysinfo
authorSimon Glass <sjg@chromium.org>
Mon, 15 Mar 2021 05:00:22 +0000 (18:00 +1300)
committerSimon Glass <sjg@chromium.org>
Sat, 27 Mar 2021 00:59:59 +0000 (13:59 +1300)
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 <sjg@chromium.org>
arch/x86/include/asm/cb_sysinfo.h
arch/x86/include/asm/coreboot_tables.h
arch/x86/lib/coreboot/cb_sysinfo.c

index 419ec5293350421ce835fc498ab4641ef800972d..675eef6f2c9490e2f9a87255850a66c295fffbad 100644 (file)
 #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;
index 3172814d09aa9956d9fcea50071703a9f4c8f5ef..a74654bbe3a8970ac1a243b3680258e4e24f9bf7 100644 (file)
@@ -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;
index 816a0efd135db5411ee24b8ce17087613d363b13..e2c65bfb1eed73177c9eb41147ce5d09ba03dae9 100644 (file)
@@ -7,8 +7,10 @@
  */
 
 #include <common.h>
-#include <net.h>
 #include <asm/cb_sysinfo.h>
+#include <init.h>
+#include <mapmem.h>
+#include <net.h>
 #include <asm/global_data.h>
 
 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;
+}