vendorcode/google/chromeos: Save VPD region into GNVS

Store the memory address of VPD region start and length for the memory
mapped RO_VPD and RW_VPD into GNVS so they can be used by ACPI code.

BUG=b:123925776
TEST=boot on sarien and verify VPD start/length in GNVS

Change-Id: I39073a9d78f5ff60bfe088860c087a5167f05fdf
Signed-off-by: Duncan Laurie <dlaurie@google.com>
Reviewed-on: https://review.coreboot.org/c/31667
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Lijian Zhao <lijian.zhao@intel.com>
diff --git a/src/vendorcode/google/chromeos/acpi/gnvs.asl b/src/vendorcode/google/chromeos/acpi/gnvs.asl
index 52d3a0d..69e848a 100644
--- a/src/vendorcode/google/chromeos/acpi/gnvs.asl
+++ b/src/vendorcode/google/chromeos/acpi/gnvs.asl
@@ -32,4 +32,8 @@
 MEHH,  256,	// 0xd9e - Management Engine Hash
 RMOB,   32,	// 0xdbe - RAM oops base address
 RMOL,   32,	// 0xdc2 - RAM oops length
-		// 0xdc6
+ROVP,	32,	// 0xdc6 - pointer to RO_VPD
+ROVL,	32,	// 0xdca - size of RO_VPD
+RWVP,	32,	// 0xdce - pointer to RW_VPD
+RWVL,	32,	// 0xdd2 - size of RW_VPD
+		// 0xdd6
diff --git a/src/vendorcode/google/chromeos/gnvs.c b/src/vendorcode/google/chromeos/gnvs.c
index 86ba4f3..44162c8 100644
--- a/src/vendorcode/google/chromeos/gnvs.c
+++ b/src/vendorcode/google/chromeos/gnvs.c
@@ -20,6 +20,7 @@
 #include <cbmem.h>
 #include <console/console.h>
 #include <elog.h>
+#include <fmap.h>
 #include <security/vboot/vbnv.h>
 #include <security/vboot/vboot_common.h>
 #include <vboot_struct.h>
@@ -30,14 +31,41 @@
 static chromeos_acpi_t *chromeos_acpi;
 static u32 me_hash_saved[8];
 
+static size_t chromeos_vpd_region(const char *region, uintptr_t *base)
+{
+	struct region_device vpd;
+
+	if (fmap_locate_area_as_rdev(region, &vpd))
+		return 0;
+
+	*base = (uintptr_t)rdev_mmap_full(&vpd);
+
+	return region_device_sz(&vpd);
+}
+
 void chromeos_init_chromeos_acpi(chromeos_acpi_t *init)
 {
+	size_t vpd_size;
+	uintptr_t vpd_base = 0;
+
 	chromeos_acpi = init;
 
 	/* Copy saved ME hash into NVS */
 	memcpy(chromeos_acpi->mehh, me_hash_saved, sizeof(chromeos_acpi->mehh));
 
 	chromeos_ram_oops_init(chromeos_acpi);
+
+	vpd_size = chromeos_vpd_region("RO_VPD", &vpd_base);
+	if (vpd_size && vpd_base) {
+		chromeos_acpi->vpd_ro_base = vpd_base;
+		chromeos_acpi->vpd_ro_size = vpd_size;
+	}
+
+	vpd_size = chromeos_vpd_region("RW_VPD", &vpd_base);
+	if (vpd_size && vpd_base) {
+		chromeos_acpi->vpd_rw_base = vpd_base;
+		chromeos_acpi->vpd_rw_size = vpd_size;
+	}
 }
 
 void chromeos_set_me_hash(u32 *hash, int len)
diff --git a/src/vendorcode/google/chromeos/gnvs.h b/src/vendorcode/google/chromeos/gnvs.h
index 76ca20c..b114dd0 100644
--- a/src/vendorcode/google/chromeos/gnvs.h
+++ b/src/vendorcode/google/chromeos/gnvs.h
@@ -70,7 +70,11 @@
 	u32	mehh[8];	// d9e management engine hash
 	u32	ramoops_base;	// dbe ramoops base address
 	u32	ramoops_len;	// dc2 ramoops length
-	u8	pad[314];	// dc6-eff
+	u32	vpd_ro_base;	// dc6 pointer to RO_VPD
+	u32	vpd_ro_size;	// dca size of RO_VPD
+	u32	vpd_rw_base;	// dce pointer to RW_VPD
+	u32	vpd_rw_size;	// dd2 size of RW_VPD
+	u8	pad[298];	// dd6-eff
 } __packed chromeos_acpi_t;
 
 void chromeos_init_chromeos_acpi(chromeos_acpi_t *init);