[coreboot-gerrit] Patch set updated for coreboot: soc/intel/apollolake: Add check if FPFs are blown

Andrey Petrov (andrey.petrov@intel.com) gerrit at coreboot.org
Tue Mar 7 18:56:51 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/18604

-gerrit

commit 5855c2fa401d07114a8a0e2e93d1eac5e60b5491
Author: Andrey Petrov <andrey.petrov at intel.com>
Date:   Fri Mar 3 08:12:36 2017 -0800

    soc/intel/apollolake: Add check if FPFs are blown
    
    Apollolake platform comes with FPF (field-programmable-fuses). FPF can
    be blown only once, typically at the end of the manufacturing process.
    This patch adds code that sends a request to CSE to figure out if FPFs
    have already been blown.
    
    Change-Id: I9e768a8b95a3cb48adf66e1f17803c720908802d
    Signed-off-by: Andrey Petrov <andrey.petrov at intel.com>
---
 src/soc/intel/apollolake/cse.c | 111 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 110 insertions(+), 1 deletion(-)

diff --git a/src/soc/intel/apollolake/cse.c b/src/soc/intel/apollolake/cse.c
index ba3898da..0b37b97 100644
--- a/src/soc/intel/apollolake/cse.c
+++ b/src/soc/intel/apollolake/cse.c
@@ -16,6 +16,7 @@
 #include <arch/io.h>
 #include <bootstate.h>
 #include <console/console.h>
+#include <intelblocks/cse.h>
 #include <soc/pci_devs.h>
 #include <stdint.h>
 
@@ -26,6 +27,100 @@
 #define PCI_ME_HFSTS5	0x68
 #define PCI_ME_HFSTS6	0x6c
 
+#define MKHI_GROUP_ID_MCA			0x0a
+#define READ_FILE				0x02
+#define   READ_FILE_FLAG_DEFAULT		(1 << 0)
+#define   READ_FILE_FLAG_HASH			(1 << 1)
+#define   READ_FILE_FLAG_EMULATED		(1 << 2)
+#define   READ_FILE_FLAG_HW			(1 << 3)
+
+#define MCA_MAX_FILE_PATH_SIZE			64
+#define MCA_MAX_FILE_NAME			12
+
+#define FUSE_LOCK_FILE				"/fpf/intel/SocCfgLock"
+
+int8_t g_fuse_status;
+
+static int read_cse_file(const char *path, void *buff, uint32_t bsize,
+				uint32_t offset, uint32_t len, uint32_t flags)
+{
+	int res;
+	uint32_t reply_size;
+
+	union mkhi_header {
+		uint32_t data;
+		struct {
+			uint32_t group_id: 8;
+			uint32_t command: 7;
+			uint32_t is_response: 1;
+			uint32_t reserved: 8;
+			uint32_t result: 8;
+		} __attribute__ ((packed)) fields;
+	};
+
+	struct mca_command {
+		union mkhi_header mkhi_hdr;
+		char file_name[MCA_MAX_FILE_PATH_SIZE];
+		uint32_t offset;
+		uint32_t data_size;
+		uint8_t flags;
+	} __attribute__ ((packed)) msg;
+
+	struct mca_response {
+		union mkhi_header mkhi_hdr;
+		uint32_t data_size;
+		uint8_t buffer[128];
+	} __attribute__ ((packed)) rmsg;
+
+	if (bsize < len) {
+		printk(BIOS_ERR, "provided buffer is too small\n");
+		return 0;
+	}
+
+	if (sizeof(rmsg.buffer) < len) {
+		printk(BIOS_ERR, "internal buffer is too small\n");
+		return 0;
+	}
+
+	strncpy(msg.file_name, path, sizeof(msg.file_name));
+	msg.mkhi_hdr.fields.group_id = MKHI_GROUP_ID_MCA;
+	msg.mkhi_hdr.fields.command = READ_FILE;
+	msg.flags = flags;
+	msg.data_size = len;
+	msg.offset = offset;
+
+	res = heci_send(&msg, sizeof(msg), BIOS_HOST_ADDR, HECI_MKHI_ADDR);
+
+	if (!res)
+		return 0;
+
+	reply_size = sizeof(rmsg);
+	res = heci_receive(&rmsg, &reply_size);
+
+	if (!res)
+		return 0;
+
+	if (rmsg.data_size <= bsize)
+		memcpy(buff, rmsg.buffer, rmsg.data_size);
+	else
+		return 0;
+
+	return 1;
+}
+
+static void fpf_blown(void *unused)
+{
+	int8_t fuse;
+
+	if (read_cse_file(FUSE_LOCK_FILE, &fuse, sizeof(fuse), 0, 1,
+						READ_FILE_FLAG_HW)) {
+		g_fuse_status = fuse;
+		return;
+	}
+
+	g_fuse_status = -1;
+}
+
 static uint32_t dump_status(int index, int reg_addr)
 {
 	uint32_t reg = pci_read_config32(HECI1_DEV, reg_addr);
@@ -51,7 +146,21 @@ static void dump_cse_state(void *unused)
 	   the product so it's called out explicitly. */
 	printk(BIOS_DEBUG, "ME: Manufacturing Mode      : %s\n",
 		(fwsts1 & (1 << 0x4)) ? "YES" : "NO");
-}
 
+	printk(BIOS_DEBUG, "ME: FPF status              : ");
+	switch (g_fuse_status) {
+	case 0:
+		printk(BIOS_DEBUG, "unfused");
+		break;
+	case 1:
+		printk(BIOS_DEBUG, "fused");
+		break;
+	default:
+	case -1:
+		printk(BIOS_DEBUG, "unknown");
+	}
+	printk(BIOS_DEBUG, "\n");
+}
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, fpf_blown, NULL);
 BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, dump_cse_state, NULL);
 BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, dump_cse_state, NULL);



More information about the coreboot-gerrit mailing list