diff options
author | Angel Pons <th3fanbus@gmail.com> | 2023-03-22 13:25:09 +0100 |
---|---|---|
committer | Lean Sheng Tan <sheng.tan@9elements.com> | 2023-03-24 16:39:17 +0000 |
commit | 56c1c4dff9c7ccd8968a3e32be800375bf3d5b78 (patch) | |
tree | f8614b97e6f66a63fe48cc1558f7e4dc37b12bea /src/mainboard/prodrive/atlas/vpd.c | |
parent | 964079f77cced3aedc468a888b6b6f32cfbec7c9 (diff) |
mb/prodrive/atlas: Implement initial VPD support
Atlas stores VPD (Vital Product Data) in an I2C EEPROM, which is only
connected to the EC. In order for the host (x86) to be able to access
the VPD, the EC reads the EEPROM contents into a buffer in EC RAM and
provides the host with read-only access to this EC RAM buffer through
EMI (Embedded Memory Interface) 0.
The VPD layout is designed to be extensible yet backwards compatible.
The code in coreboot uses the revision field to know which fields are
valid, and will populate the rest with fallback values.
Use the serial number and part number in VPD to populate SMBIOS tables.
Change-Id: I2d3d70fee22548daa73ef98af56c98e950dc5e9d
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/73937
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
Diffstat (limited to 'src/mainboard/prodrive/atlas/vpd.c')
-rw-r--r-- | src/mainboard/prodrive/atlas/vpd.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/mainboard/prodrive/atlas/vpd.c b/src/mainboard/prodrive/atlas/vpd.c new file mode 100644 index 0000000000..12371f71e6 --- /dev/null +++ b/src/mainboard/prodrive/atlas/vpd.c @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <string.h> +#include <types.h> + +#include "ec.h" +#include "mainboard.h" +#include "vpd.h" + +const union emi_eeprom_vpd *get_emi_eeprom_vpd(void) +{ + static union emi_eeprom_vpd vpd = {0}; + + /* Check if cached VPD is valid */ + if (vpd.header.revision == VPD_LATEST_REVISION) + return &vpd; + + ec_emi_read(vpd.raw, EMI_0_IO_BASE_ADDR, 0, 0, sizeof(vpd.raw)); + + /* If the magic value doesn't match, consider EEPROM VPD unreliable */ + if (vpd.header.magic != VPD_MAGIC) { + printk(BIOS_WARNING, "Atlas VPD: Bad magic value, using fallback defaults\n"); + vpd.header.revision = 0; + } else { + printk(BIOS_DEBUG, "Atlas VPD: Got revision %u from EC\n", vpd.header.revision); + } + + /* + * For backwards compatibility, if the VPD from the EC is an older + * version, uprev it to the latest version coreboot knows about by + * filling in the remaining fields with default values. Should the + * EC provide a newer VPD revision, coreboot would downgrade it to + * the latest version it knows about as the VPD layout is designed + * to be backwards compatible. + * + * Whenever the value of `VPD_LATEST_REVISION` is incremented, add + * a new `case` label just before the `default` label that matches + * the second latest revision to initialise the newly-added fields + * of the VPD structure with a reasonable fallback value. Note the + * intentional falling through. + */ + switch (vpd.header.revision) { + case 0: + memset(vpd.raw, 0, sizeof(vpd.raw)); + vpd.header.magic = VPD_MAGIC; + vpd.serial_number[0] = '\0'; + vpd.part_number[0] = '\0'; + vpd.profile = ATLAS_PROF_UNPROGRAMMED; + __fallthrough; + default: + /* Ensure serial numbers are NULL-terminated, update revision last */ + vpd.serial_number[ATLAS_SN_PN_LENGTH - 1] = '\0'; + vpd.part_number[ATLAS_SN_PN_LENGTH - 1] = '\0'; + vpd.header.revision = VPD_LATEST_REVISION; + break; + } + + return &vpd; +} |