[coreboot-gerrit] Patch set updated for coreboot: WIP: soc/intel/common: Add store/restore for variable MRC data

Andrey Petrov (andrey.petrov@intel.com) gerrit at coreboot.org
Tue Nov 8 20:57:51 CET 2016


Andrey Petrov (andrey.petrov at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17320

-gerrit

commit a106d525a42019cba6b298aac45c61edd926ee80
Author: Andrey Petrov <andrey.petrov at intel.com>
Date:   Tue Nov 8 08:30:06 2016 -0800

    WIP: soc/intel/common: Add store/restore for variable MRC data
    
    Piggy-back on existing MRC cache infrastructure to store variable MRC data.
    
    Only one set of data can be valid at given point of time. Currently this
    magically happens because region alignment is forced to 0x1000 and region
    itself is of the same size. This needs to be somehow programatically
    enforced.
    
    Change-Id: I8a660d356ca760b8ff9907396fb9b34cb16cf1db
    Signed-off-by: Andrey Petrov <andrey.petrov at intel.com>
---
 src/commonlib/include/commonlib/cbmem_id.h |   1 +
 src/soc/intel/common/Kconfig               |   4 +
 src/soc/intel/common/mrc_cache.c           | 116 ++++++++++++++++++++++-------
 src/soc/intel/common/mrc_cache.h           |   2 +
 4 files changed, 96 insertions(+), 27 deletions(-)

diff --git a/src/commonlib/include/commonlib/cbmem_id.h b/src/commonlib/include/commonlib/cbmem_id.h
index 7d97bff..701f7e3 100644
--- a/src/commonlib/include/commonlib/cbmem_id.h
+++ b/src/commonlib/include/commonlib/cbmem_id.h
@@ -41,6 +41,7 @@
 #define CBMEM_ID_MMA_DATA	0x4D4D4144
 #define CBMEM_ID_MPTABLE	0x534d5054
 #define CBMEM_ID_MRCDATA	0x4d524344
+#define CBMEM_ID_VAR_MRCDATA	0x4d524345
 #define CBMEM_ID_MTC		0xcb31d31c
 #define CBMEM_ID_NONE		0x00000000
 #define CBMEM_ID_PIRQ		0x49525154
diff --git a/src/soc/intel/common/Kconfig b/src/soc/intel/common/Kconfig
index affec55..9fec201 100644
--- a/src/soc/intel/common/Kconfig
+++ b/src/soc/intel/common/Kconfig
@@ -27,6 +27,10 @@ config MRC_SETTINGS_PROTECT
 	bool "Enable protection on MRC settings"
 	default n
 
+config MRC_SETTINGS_VARIABLE_DATA
+	bool
+	default n
+
 endif # CACHE_MRC_SETTINGS
 
 config DISPLAY_MTRRS
diff --git a/src/soc/intel/common/mrc_cache.c b/src/soc/intel/common/mrc_cache.c
index bef3ba2..f6b52ff 100644
--- a/src/soc/intel/common/mrc_cache.c
+++ b/src/soc/intel/common/mrc_cache.c
@@ -35,13 +35,35 @@ struct mrc_data_region {
 	uint32_t size;
 };
 
+/* Table to match cbmem id to FMAP region */
+static const struct cbmem_to_region {
+	const char *reg_name;
+	const uint32_t cbmem_id;
+} regions[] = {
+	{"RW_MRC_CACHE", CBMEM_ID_MRCDATA},
+	{"RW_VAR_MRC_CACHE", CBMEM_ID_VAR_MRCDATA},
+	{NULL, 0}
+};
+
 /* common code */
-static int mrc_cache_get_region(struct mrc_data_region *region)
+
+static const char *mrc_region_for_cbmem(uint32_t cbmem_id)
+{
+	const struct cbmem_to_region *s;
+
+	for (s = regions; s->cbmem_id != 0; s++)
+		if (cbmem_id == s->cbmem_id)
+			return s->reg_name;
+
+	return "<unspecified>";
+}
+
+static int mrc_cache_get_region(struct mrc_data_region *region, uint32_t cbmem_id)
 {
 	bool located_by_fmap = true;
 	struct region_device rdev;
 
-	if (fmap_locate_area_as_rdev("RW_MRC_CACHE", &rdev))
+	if (fmap_locate_area_as_rdev(mrc_region_for_cbmem(cbmem_id), &rdev))
 		located_by_fmap =  false;
 
 	/* CHROMEOS builds must get their MRC cache from FMAP. */
@@ -55,8 +77,11 @@ static int mrc_cache_get_region(struct mrc_data_region *region)
 		if (region->base == NULL)
 			return -1;
 	} else {
-		region->base = (void *)CONFIG_MRC_SETTINGS_CACHE_BASE;
-		region->size = CONFIG_MRC_SETTINGS_CACHE_SIZE;
+		/* Only regular constant MRC data is memory mapped */
+		if (cbmem_id == CBMEM_ID_MRCDATA) {
+			region->base = (void *)CONFIG_MRC_SETTINGS_CACHE_BASE;
+			region->size = CONFIG_MRC_SETTINGS_CACHE_SIZE;
+		}
 	}
 
 	return 0;
@@ -164,19 +189,30 @@ int mrc_cache_get_current_with_version(const struct mrc_saved_data **cache,
 {
 	struct mrc_data_region region;
 
-	if (mrc_cache_get_region(&region) < 0)
+	if (mrc_cache_get_region(&region, CBMEM_ID_MRCDATA) < 0)
 		return -1;
 
 	return __mrc_cache_get_current(&region, cache, version);
 }
 
+int mrc_cache_get_vardata(const struct mrc_saved_data **cache)
+{
+	struct mrc_data_region region;
+
+	if (mrc_cache_get_region(&region, CBMEM_ID_VAR_MRCDATA) < 0)
+		return -1;
+
+	return __mrc_cache_get_current(&region, cache, 0);
+}
+
+
 int mrc_cache_get_current(const struct mrc_saved_data **cache)
 {
 	return mrc_cache_get_current_with_version(cache, 0);
 }
 /* Fill in mrc_saved_data structure with payload. */
 static void mrc_cache_fill(struct mrc_saved_data *cache, const void *data,
-                           size_t size, uint32_t version)
+                           size_t size, uint32_t version, uint32_t cbmem_id)
 {
 	cache->signature = MRC_DATA_SIGNATURE;
 	cache->size = size;
@@ -186,15 +222,15 @@ static void mrc_cache_fill(struct mrc_saved_data *cache, const void *data,
 	                                      cache->size);
 }
 
-int mrc_cache_stash_data_with_version(const void *data, size_t size,
-					uint32_t version)
+static int _mrc_stash_data(const void *data, size_t size, uint32_t version,
+			    uint32_t cbmem_id)
 {
 	int cbmem_size;
 	struct mrc_saved_data *cache;
 
 	cbmem_size = sizeof(*cache) + ALIGN(size, 16);
 
-	cache = cbmem_add(CBMEM_ID_MRCDATA, cbmem_size);
+	cache = cbmem_add(cbmem_id, cbmem_size);
 
 	if (cache == NULL) {
 		printk(BIOS_ERR, "No space in cbmem for MRC data.\n");
@@ -207,11 +243,23 @@ int mrc_cache_stash_data_with_version(const void *data, size_t size,
 	printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%zu bytes)\n",
 	       data, cache, size);
 
-	mrc_cache_fill(cache, data, size, version);
+	mrc_cache_fill(cache, data, size, version, cbmem_id);
 
 	return 0;
 }
 
+int mrc_cache_stash_data_with_version(const void *data, size_t size,
+					uint32_t version)
+{
+	return _mrc_stash_data(data, size, version, CBMEM_ID_MRCDATA);
+}
+
+int mrc_cache_stash_vardata(const void *data, size_t size)
+{
+	return _mrc_stash_data(data, size, 0, CBMEM_ID_VAR_MRCDATA);
+}
+
+
 int mrc_cache_stash_data(const void *data, size_t size)
 {
 	return mrc_cache_stash_data_with_version(data, size, 0);
@@ -263,21 +311,23 @@ mrc_cache_next_slot(const struct mrc_data_region *region,
 	return next_slot;
 }
 
-/* Protect RW_MRC_CACHE region with a Protected Range Register */
-static int protect_mrc_cache(const struct mrc_data_region *region)
+/* Protect specified region with a Protected Range Register */
+static int protect_mrc_cache(const struct mrc_data_region *region,
+				const char *name)
 {
 #if IS_ENABLED(CONFIG_MRC_SETTINGS_PROTECT)
+
 	if (nvm_is_write_protected() <= 0) {
-		printk(BIOS_INFO, "NOT enabling PRR for RW_MRC_CACHE region\n");
+		printk(BIOS_INFO, "NOT enabling PRR for %s region\n", name);
 		return 1;
 	}
 
 	if (nvm_protect(region->base, region->size) < 0) {
-		printk(BIOS_ERR, "ERROR setting PRR for RW_MRC_CACHE region\n");
+		printk(BIOS_ERR, "ERROR setting PRR for %s region\n", name);
 		return -1;
 	}
 
-	printk(BIOS_INFO, "Enabled Protected Range on RW_MRC_CACHE region\n");
+	printk(BIOS_INFO, "Enabled Protected Range on %s region\n", name);
 #endif
 	return 0;
 }
@@ -294,28 +344,33 @@ static void log_event_cache_update(uint8_t slot, uint8_t status)
 		printk(BIOS_ERR, "Failed to log mem cache update event.\n");
 }
 
-static void update_mrc_cache(void *unused)
+static void update_mrc_cache_type(uint32_t cbmem_id, const char *type)
 {
 	const struct mrc_saved_data *current_boot;
 	const struct mrc_saved_data *current_saved;
 	const struct mrc_saved_data *next_slot;
 	struct mrc_data_region region;
+	const char* reg_name;
+
+	printk(BIOS_DEBUG, "Updating %s MRC cache data.\n", type);
+
+	current_boot = cbmem_find(cbmem_id);
 
-	printk(BIOS_DEBUG, "Updating MRC cache data.\n");
+	reg_name = mrc_region_for_cbmem(cbmem_id);
 
-	current_boot = cbmem_find(CBMEM_ID_MRCDATA);
 	if (!current_boot) {
-		printk(BIOS_ERR, "No MRC cache in cbmem.\n");
+		printk(BIOS_ERR, "No %s MRC cache in cbmem.\n", type);
 		return;
 	}
 
-	if (mrc_cache_get_region(&region)) {
-		printk(BIOS_ERR, "Could not obtain MRC cache region.\n");
+	if (mrc_cache_get_region(&region, cbmem_id)) {
+		printk(BIOS_ERR, "Could not obtain %s MRC cache region.\n",
+		    type);
 		return;
 	}
 
 	if (!mrc_cache_valid(&region, current_boot)) {
-		printk(BIOS_ERR, "MRC cache data in cbmem invalid.\n");
+		printk(BIOS_ERR, "MRC %s cache data in cbmem invalid.\n", type);
 		return;
 	}
 
@@ -326,8 +381,8 @@ static void update_mrc_cache(void *unused)
 		if (current_saved->size == current_boot->size &&
 		    !memcmp(&current_saved->data[0], &current_boot->data[0],
 		            current_saved->size)) {
-			printk(BIOS_DEBUG, "MRC cache up to date.\n");
-			protect_mrc_cache(&region);
+			printk(BIOS_DEBUG, "MRC %s cache up to date.\n", type);
+			protect_mrc_cache(&region, reg_name);
 			return;
 		}
 	}
@@ -347,8 +402,8 @@ static void update_mrc_cache(void *unused)
 
 	if (nvm_write((void *)next_slot, current_boot,
 	               current_boot->size + sizeof(*current_boot))) {
-		printk(BIOS_DEBUG, "Failure writing MRC cache to %p.\n",
-		       next_slot);
+		printk(BIOS_DEBUG, "Failure writing %s MRC cache to %p.\n",
+		       reg_name, next_slot);
 		log_event_cache_update(ELOG_MEM_CACHE_UPDATE_SLOT_NORMAL,
 			ELOG_MEM_CACHE_UPDATE_STATUS_FAIL);
 	} else {
@@ -356,7 +411,14 @@ static void update_mrc_cache(void *unused)
 			ELOG_MEM_CACHE_UPDATE_STATUS_SUCCESS);
 	}
 
-	protect_mrc_cache(&region);
+	protect_mrc_cache(&region, reg_name);
+}
+
+static void update_mrc_cache(void *unused)
+{
+	update_mrc_cache_type(CBMEM_ID_MRCDATA, "constant");
+	if (IS_ENABLED(CONFIG_MRC_SETTINGS_VARIABLE_DATA))
+		update_mrc_cache_type(CBMEM_ID_VAR_MRCDATA, "variable");
 }
 
 BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY, update_mrc_cache, NULL);
diff --git a/src/soc/intel/common/mrc_cache.h b/src/soc/intel/common/mrc_cache.h
index 9b14c1e..58d4a78 100644
--- a/src/soc/intel/common/mrc_cache.h
+++ b/src/soc/intel/common/mrc_cache.h
@@ -32,10 +32,12 @@ struct mrc_saved_data {
 int mrc_cache_get_current(const struct mrc_saved_data **cache);
 int mrc_cache_get_current_with_version(const struct mrc_saved_data **cache,
 					uint32_t version);
+int mrc_cache_get_vardata(const struct mrc_saved_data **cache);
 
 /* Stash the resulting MRC data to be saved in non-volatile storage later. */
 int mrc_cache_stash_data(const void *data, size_t size);
 int mrc_cache_stash_data_with_version(const void *data, size_t size,
 					uint32_t version);
+int mrc_cache_stash_vardata(const void *data, size_t size);
 
 #endif /* _COMMON_MRC_CACHE_H_ */



More information about the coreboot-gerrit mailing list