[coreboot-gerrit] New patch to review for coreboot: soc/intel/apollolake: Cache FPF status value in flash

Andrey Petrov (andrey.petrov@intel.com) gerrit at coreboot.org
Sun Mar 12 19:59:44 CET 2017


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

-gerrit

commit 7ece543634bdd77e4e23933d09c5646ad96874b4
Author: Andrey Petrov <andrey.petrov at intel.com>
Date:   Sun Mar 12 00:51:34 2017 -0800

    soc/intel/apollolake: Cache FPF status value in flash
    
    Since asking CSE to read FPF status turned out to be slow in some
    cases, cache and save returned value on first boot only. Value is
    read from flash on consequent boots.
    
    BUG=b:35586975
    BRANCH=reef
    TEST=boot twice, make sure cached FPF status is loaded from
    flash the second time.
    
    Change-Id: I6e56a35407c9097616ccb05a557fded7b639c88a
    Signed-off-by: Andrey Petrov <andrey.petrov at intel.com>
---
 src/soc/intel/apollolake/cse.c | 63 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 53 insertions(+), 10 deletions(-)

diff --git a/src/soc/intel/apollolake/cse.c b/src/soc/intel/apollolake/cse.c
index a8e3b5b..45c3b66 100644
--- a/src/soc/intel/apollolake/cse.c
+++ b/src/soc/intel/apollolake/cse.c
@@ -15,7 +15,9 @@
 
 #include <arch/io.h>
 #include <bootstate.h>
+#include <commonlib/region.h>
 #include <console/console.h>
+#include <fmap.h>
 #include <intelblocks/cse.h>
 #include <soc/pci_devs.h>
 #include <stdint.h>
@@ -38,7 +40,14 @@
 
 #define FUSE_LOCK_FILE				"/fpf/intel/SocCfgLock"
 
-static int8_t g_fuse_status;
+/* Status values are made in such a way erase is not needed */
+static enum fuse_flash_state {
+	FUSE_FLASH_FUSED = 0xfffffffc,
+	FUSE_FLASH_UNFUSED = 0xfffffffe,
+	FUSE_FLASH_UNKNOWN = 0xffffffff,
+} g_fuse_state;
+
+#define FPF_STATUS_FMAP				"FPF_STATUS"
 
 /*
  * Read file from CSE internal filesystem.
@@ -115,16 +124,50 @@ static int read_cse_file(const char *path, void *buff, size_t *size,
 	return 1;
 }
 
+static enum fuse_flash_state load_cached_fpf(void)
+{
+	struct region_device rdev;
+	enum fuse_flash_state state;
+
+	state = FUSE_FLASH_UNKNOWN;
+
+	if (fmap_locate_area_as_rdev(FPF_STATUS_FMAP, &rdev) == 0) {
+		if (rdev_readat(&rdev, &state, 0, sizeof(state)) >= 0)
+			return state;
+	}
+
+	printk(BIOS_WARNING, "failed to load cached FPF value\n");
+
+	return state;
+}
+
+static int save_fpf_state(enum fuse_flash_state state)
+{
+	struct region_device rdev;
+
+	if (fmap_locate_area_as_rdev_rw(FPF_STATUS_FMAP, &rdev) < 0)
+		return -1;
+
+	return rdev_writeat(&rdev, &state, 0, sizeof(state));
+}
+
 static void fpf_blown(void *unused)
 {
-	int8_t fuse;
+	uint8_t fuse;
 	size_t sz = sizeof(fuse);
 
-	if (read_cse_file(FUSE_LOCK_FILE, &fuse, &sz, 0, READ_FILE_FLAG_HW)) {
-		g_fuse_status = fuse;
+	g_fuse_state = load_cached_fpf();
+
+	if (g_fuse_state != FUSE_FLASH_UNKNOWN)
 		return;
-	}
-	g_fuse_status = -1;
+
+	if (!read_cse_file(FUSE_LOCK_FILE, &fuse, &sz, 0, READ_FILE_FLAG_HW))
+		return;
+
+	g_fuse_state = fuse == 1 ? FUSE_FLASH_FUSED : FUSE_FLASH_UNFUSED;
+
+	if (save_fpf_state(g_fuse_state) < 0)
+		printk(BIOS_CRIT, "failed to save FPF state\n");
 }
 
 static uint32_t dump_status(int index, int reg_addr)
@@ -154,15 +197,15 @@ static void dump_cse_state(void *unused)
 		(fwsts1 & (1 << 0x4)) ? "YES" : "NO");
 
 	printk(BIOS_DEBUG, "ME: FPF status              : ");
-	switch (g_fuse_status) {
-	case 0:
+	switch (g_fuse_state) {
+	case FUSE_FLASH_UNFUSED:
 		printk(BIOS_DEBUG, "unfused");
 		break;
-	case 1:
+	case FUSE_FLASH_FUSED:
 		printk(BIOS_DEBUG, "fused");
 		break;
 	default:
-	case -1:
+	case FUSE_FLASH_UNKNOWN:
 		printk(BIOS_DEBUG, "unknown");
 	}
 	printk(BIOS_DEBUG, "\n");



More information about the coreboot-gerrit mailing list