summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/common/block/cse/Kconfig14
-rw-r--r--src/soc/intel/common/block/cse/Makefile.inc59
-rw-r--r--src/soc/intel/common/block/cse/cse_lite.c56
-rw-r--r--src/soc/intel/common/block/include/intelblocks/cse.h10
4 files changed, 86 insertions, 53 deletions
diff --git a/src/soc/intel/common/block/cse/Kconfig b/src/soc/intel/common/block/cse/Kconfig
index 94f8cd5ebc..e06895080e 100644
--- a/src/soc/intel/common/block/cse/Kconfig
+++ b/src/soc/intel/common/block/cse/Kconfig
@@ -51,11 +51,17 @@ config SOC_INTEL_CSE_RW_CBFS_NAME
help
CBFS entry name for Intel CSE CBFS RW blob
-config SOC_INTEL_CSE_RW_METADATA_CBFS_NAME
- string "CBFS name for CSE RW metadata file" if SOC_INTEL_CSE_RW_UPDATE
- default "me_rw.metadata"
+config SOC_INTEL_CSE_RW_HASH_CBFS_NAME
+ string "CBFS name for CSE RW hash file" if SOC_INTEL_CSE_RW_UPDATE
+ default "me_rw.hash"
help
- CBFS name for Intel CSE CBFS RW metadata file
+ CBFS name for Intel CSE CBFS RW hash file
+
+config SOC_INTEL_CSE_RW_VERSION_CBFS_NAME
+ string "CBFS name for CSE RW version file" if SOC_INTEL_CSE_RW_UPDATE
+ default "me_rw.version"
+ help
+ CBFS name for Intel CSE CBFS RW version file
config SOC_INTEL_CSE_RW_FILE
string "Intel CSE CBFS RW path and filename" if SOC_INTEL_CSE_RW_UPDATE
diff --git a/src/soc/intel/common/block/cse/Makefile.inc b/src/soc/intel/common/block/cse/Makefile.inc
index e21efc6144..9b50704a57 100644
--- a/src/soc/intel/common/block/cse/Makefile.inc
+++ b/src/soc/intel/common/block/cse/Makefile.inc
@@ -7,40 +7,43 @@ smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_HECI_DISABLE_IN_SMM) += disable_heci.c
ramstage-$(CONFIG_SOC_INTEL_CSE_SET_EOP) += cse_eop.c
ifeq ($(CONFIG_SOC_INTEL_CSE_RW_UPDATE),y)
-ifneq ($(CONFIG_SOC_INTEL_CSE_RW_FILE),"")
+
+ifeq ($(CONFIG_SOC_INTEL_CSE_RW_FILE),"")
+$(error "CSE RW file path is missing and need to be set by mainboard config")
+endif
+
+ifeq ($(CONFIG_SOC_INTEL_CSE_RW_VERSION),"")
+$(error "CSE RW version is missing and need to be set by mainboard config")
+endif
+
+CSE_RW_FILE=$(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_FILE))
+
CSE_LITE_ME_RW = $(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_CBFS_NAME))
regions-for-file-$(CSE_LITE_ME_RW) = $(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_A_FMAP_NAME)), \
$(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_B_FMAP_NAME))
cbfs-files-y += $(CSE_LITE_ME_RW)
-$(CSE_LITE_ME_RW)-file := $(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_FILE))
+$(CSE_LITE_ME_RW)-file := $(CSE_RW_FILE)
$(CSE_LITE_ME_RW)-name := $(CSE_LITE_ME_RW)
$(CSE_LITE_ME_RW)-type := raw
-else
-$(error "CSE RW file path is missing and need to be set by mainboard config")
-endif
-# Extract the CSE RW firmware version and update the cse_rw_metadata structure
-ifneq ($(CONFIG_SOC_INTEL_CSE_RW_VERSION),"")
-CSE_RW_VERSION:=$(subst ., ,$(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_VERSION)))
-MAJOR := $(word 1, $(CSE_RW_VERSION))
-MINOR := $(word 2, $(CSE_RW_VERSION))
-HOTFIX := $(word 3, $(CSE_RW_VERSION))
-BUILD := $(word 4, $(CSE_RW_VERSION))
-CPPFLAGS_common += -DCSE_RW_MAJOR=$(MAJOR) -DCSE_RW_MINOR=$(MINOR) -DCSE_RW_HOTFIX=$(HOTFIX) -DCSE_RW_BUILD=$(BUILD)
-else
-$(error "CSE RW version is missing and need to be set by mainboard config")
-endif
+$(obj)/cse_rw.version:
+ @echo '$(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_VERSION))' > $@
+
+CSE_RW_VERSION = $(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME))
+regions-for-file-$(CSE_RW_VERSION) = FW_MAIN_A,FW_MAIN_B
+cbfs-files-y += $(CSE_RW_VERSION)
+$(CSE_RW_VERSION)-file := $(obj)/cse_rw.version
+$(CSE_RW_VERSION)-name := $(CSE_RW_VERSION)
+$(CSE_RW_VERSION)-type := raw
+
+$(obj)/cse_rw.hash: $(CSE_RW_FILE)
+ openssl dgst -sha256 -binary $< > $@
+
+CSE_RW_HASH = $(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_HASH_CBFS_NAME))
+regions-for-file-$(CSE_RW_HASH) = FW_MAIN_A,FW_MAIN_B
+cbfs-files-y += $(CSE_RW_HASH)
+$(CSE_RW_HASH)-file := $(obj)/cse_rw.hash
+$(CSE_RW_HASH)-name := $(CSE_RW_HASH)
+$(CSE_RW_HASH)-type := raw
-# Compute the hash of the CSE RW binary and update the cse_rw_metadata structure
-CSE_RW_PATH := $(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_FILE))
-HASH := $(shell openssl dgst -sha256 -hex $(CSE_RW_PATH) | cut -d " " -f2 | fold -w2 | paste -sd',' -)
-CPPFLAGS_common += -DCSE_RW_SHA256=$(HASH)
-
-# Add the CSE RW metadata file to FW_MAIN_A/B
-CSE_RW_METADATA = $(call strip_quotes,$(CONFIG_SOC_INTEL_CSE_RW_METADATA_CBFS_NAME))
-regions-for-file-$(CSE_RW_METADATA) = FW_MAIN_A,FW_MAIN_B
-cbfs-files-y += $(CSE_RW_METADATA)
-$(CSE_RW_METADATA)-file := cse_rw_metadata.c:struct
-$(CSE_RW_METADATA)-name := $(CSE_RW_METADATA)
-$(CSE_RW_METADATA)-type := raw
endif
diff --git a/src/soc/intel/common/block/cse/cse_lite.c b/src/soc/intel/common/block/cse/cse_lite.c
index b381c48103..281d381736 100644
--- a/src/soc/intel/common/block/cse/cse_lite.c
+++ b/src/soc/intel/common/block/cse/cse_lite.c
@@ -565,29 +565,53 @@ enum cse_update_status {
CSE_UPDATE_METADATA_ERROR,
};
-static struct cse_rw_metadata source_metadata;
+static bool read_ver_field(const char *start, char **curr, size_t size, uint16_t *ver_field)
+{
+ if ((*curr - start) >= size) {
+ printk(BIOS_ERR, "cse_lite: Version string read overflow!\n");
+ return false;
+ }
+
+ *ver_field = skip_atoi(curr);
+ (*curr)++;
+ return true;
+}
static enum cse_update_status cse_check_update_status(const struct cse_bp_info *cse_bp_info,
struct region_device *target_rdev)
{
int ret;
+ struct fw_version cbfs_rw_version;
+ char *version_str, *ptr;
+ size_t size;
if (!cse_is_rw_bp_sign_valid(target_rdev))
return CSE_UPDATE_CORRUPTED;
- if (cbfs_load(CONFIG_SOC_INTEL_CSE_RW_METADATA_CBFS_NAME, &source_metadata,
- sizeof(source_metadata)) != sizeof(source_metadata)) {
- printk(BIOS_ERR, "cse_lite: Failed to get CSE CBFS RW metadata\n");
+ ptr = version_str = cbfs_map(CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME, &size);
+ if (!version_str) {
+ printk(BIOS_ERR, "cse_lite: Failed to get %s\n",
+ CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME);
+ return CSE_UPDATE_METADATA_ERROR;
+ }
+
+ if (!read_ver_field(version_str, &ptr, size, &cbfs_rw_version.major) ||
+ !read_ver_field(version_str, &ptr, size, &cbfs_rw_version.minor) ||
+ !read_ver_field(version_str, &ptr, size, &cbfs_rw_version.hotfix) ||
+ !read_ver_field(version_str, &ptr, size, &cbfs_rw_version.build)) {
+ cbfs_unmap(version_str);
return CSE_UPDATE_METADATA_ERROR;
}
printk(BIOS_DEBUG, "cse_lite: CSE CBFS RW version : %d.%d.%d.%d\n",
- source_metadata.version.major,
- source_metadata.version.minor,
- source_metadata.version.hotfix,
- source_metadata.version.build);
+ cbfs_rw_version.major,
+ cbfs_rw_version.minor,
+ cbfs_rw_version.hotfix,
+ cbfs_rw_version.build);
+
+ cbfs_unmap(version_str);
- ret = compare_cse_version(&source_metadata.version, cse_get_rw_version(cse_bp_info));
+ ret = compare_cse_version(&cbfs_rw_version, cse_get_rw_version(cse_bp_info));
if (ret == 0)
return CSE_UPDATE_NOT_REQUIRED;
else if (ret < 0)
@@ -664,6 +688,7 @@ static enum csme_failure_reason cse_trigger_fw_update(const struct cse_bp_info *
{
struct region_device source_rdev;
enum csme_failure_reason rv;
+ uint8_t *cbfs_rw_hash;
if (!cse_get_source_rdev(&source_rdev))
return CSE_LITE_SKU_RW_BLOB_NOT_FOUND;
@@ -675,8 +700,16 @@ static enum csme_failure_reason cse_trigger_fw_update(const struct cse_bp_info *
return CSE_LITE_SKU_RW_BLOB_NOT_FOUND;
}
- if (!cse_verify_cbfs_rw_sha256(source_metadata.sha256, cse_cbfs_rw,
- region_device_sz(&source_rdev))) {
+ cbfs_rw_hash = cbfs_map(CONFIG_SOC_INTEL_CSE_RW_HASH_CBFS_NAME, NULL);
+ if (!cbfs_rw_hash) {
+ printk(BIOS_ERR, "cse_lite: Failed to get %s\n",
+ CONFIG_SOC_INTEL_CSE_RW_HASH_CBFS_NAME);
+ rv = CSE_LITE_SKU_RW_METADATA_NOT_FOUND;
+ goto error_exit;
+ }
+
+ if (!cse_verify_cbfs_rw_sha256(cbfs_rw_hash, cse_cbfs_rw,
+ region_device_sz(&source_rdev))) {
rv = CSE_LITE_SKU_RW_BLOB_SHA256_MISMATCH;
goto error_exit;
}
@@ -690,6 +723,7 @@ static enum csme_failure_reason cse_trigger_fw_update(const struct cse_bp_info *
target_rdev);
error_exit:
+ cbfs_unmap(cbfs_rw_hash);
rdev_munmap(&source_rdev, cse_cbfs_rw);
return rv;
}
diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h
index f162d485fd..80e28d5e75 100644
--- a/src/soc/intel/common/block/include/intelblocks/cse.h
+++ b/src/soc/intel/common/block/include/intelblocks/cse.h
@@ -76,16 +76,6 @@ struct fw_version {
uint16_t build;
} __packed;
-/*
- * CSE RW metadata structure
- * fw_version - CSE RW firmware version
- * sha256 - Hash of the CSE RW binary.
- */
-struct cse_rw_metadata {
- struct fw_version version;
- uint8_t sha256[VB2_SHA256_DIGEST_SIZE];
-};
-
/* CSE recovery sub-error codes */
enum csme_failure_reason {
/* No error */