1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
12 static void write_invalid_str(char *dest
, size_t length
)
14 snprintf(dest
, length
, "%s", "INVALID");
17 const struct emi_eeprom_vpd
*get_emi_eeprom_vpd(void)
20 struct emi_eeprom_vpd layout
;
21 uint8_t raw
[sizeof(struct emi_eeprom_vpd
)];
24 /* Check if cached VPD is valid */
25 if (vpd
.layout
.header
.revision
== VPD_LATEST_REVISION
)
28 ec_emi_read(vpd
.raw
, EMI_0_IO_BASE_ADDR
, 0, 0, sizeof(vpd
.raw
));
30 /* If the magic value doesn't match, consider EEPROM VPD unreliable */
31 if (vpd
.layout
.header
.magic
!= VPD_MAGIC
) {
32 printk(BIOS_WARNING
, "Atlas VPD: Bad magic value, using fallback defaults\n");
33 vpd
.layout
.header
.revision
= 0;
35 printk(BIOS_DEBUG
, "Atlas VPD: Got revision %u from EC\n",
36 vpd
.layout
.header
.revision
);
40 * For backwards compatibility, if the VPD from the EC is an older
41 * version, uprev it to the latest version coreboot knows about by
42 * filling in the remaining fields with default values. Should the
43 * EC provide a newer VPD revision, coreboot would downgrade it to
44 * the latest version it knows about as the VPD layout is designed
45 * to be backwards compatible.
47 * Whenever the value of `VPD_LATEST_REVISION` is incremented, add
48 * a new `case` label just before the `default` label that matches
49 * the second latest revision to initialise the newly-added fields
50 * of the VPD structure with a reasonable fallback value. Note the
51 * intentional falling through.
53 switch (vpd
.layout
.header
.revision
) {
55 memset(vpd
.raw
, 0, sizeof(vpd
.raw
));
56 vpd
.layout
.header
.magic
= VPD_MAGIC
;
57 write_invalid_str(vpd
.layout
.serial_number
, sizeof(vpd
.layout
.serial_number
));
58 write_invalid_str(vpd
.layout
.part_number
, sizeof(vpd
.layout
.part_number
));
59 vpd
.layout
.profile
= ATLAS_PROF_UNPROGRAMMED
;
62 /* Ensure serial numbers are NULL-terminated, update revision last */
63 vpd
.layout
.serial_number
[ATLAS_SN_PN_LENGTH
- 1] = '\0';
64 vpd
.layout
.part_number
[ATLAS_SN_PN_LENGTH
- 1] = '\0';
65 vpd
.layout
.header
.revision
= VPD_LATEST_REVISION
;