soc/intel/common: Add support to control CSE firmware update

The patch adds support to control CSE Lite firmware update dynamically.
In order to disable the CSE firmware update functionality, offset 0xf00
in the coreboot binary be updated with 0x1.

Run below command on the binary to disable CSE firmwar update

printf '\x01' | dd of=image-brya4es.serial.bin bs=1 seek=3840 count=1
conv=notrunc

BUG=b:153410586
TEST=Verified CSE firmware update functionality is not getting
triggered after updating the offset:0xF00 in the coreboot binary.

........................ CB Logs ......................................
[DEBUG]  prev_sleep_state 5
[DEBUG]  cse_lite: Number of partitions = 3
[DEBUG]  cse_lite: Current partition = RW
[DEBUG]  cse_lite: Next partition = RW
[DEBUG]  cse_lite: Flags = 0x3
[DEBUG]  cse_lite: RO version = 16.0.15.1752 (Status=0x0, Start=0x2000,
End=0x19bfff)
[DEBUG]  cse_lite: RW version = 16.0.15.1752 (Status=0x0,
Start=0x205000, End=0x439fff)
rt_debug: pre_mem_debug.cse_fw_update_disable=1
[DEBUG]  Boot Count incremented to 956
.......................................................................

Signed-off-by: Sridhar Siricilla <sridhar.siricilla@intel.com>
Change-Id: I9f234b142191eb83137d5d83f21e890e1cb828ba
Reviewed-on: https://review.coreboot.org/c/coreboot/+/62715
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Rizwan Qureshi <rizwan.qureshi@intel.com>
This commit is contained in:
Sridhar Siricilla
2022-03-09 20:35:32 +05:30
committed by Felix Held
parent 574f3c8fe4
commit 0aa1ac41c3
3 changed files with 30 additions and 5 deletions

View File

@ -10,7 +10,8 @@
#define SI_DESC_REGION_SZ 4096 #define SI_DESC_REGION_SZ 4096
struct pre_mem_ft { struct pre_mem_ft {
uint8_t reserved[64]; uint8_t cse_fw_update_disable; /* Byte location: 0xF00 */
uint8_t reserved[63];
}; };
static struct pre_mem_ft pre_mem_debug; static struct pre_mem_ft pre_mem_debug;
@ -18,6 +19,14 @@ static struct pre_mem_ft pre_mem_debug;
_Static_assert(sizeof(struct pre_mem_ft) % 64 == 0 && sizeof(struct pre_mem_ft) <= 256, _Static_assert(sizeof(struct pre_mem_ft) % 64 == 0 && sizeof(struct pre_mem_ft) <= 256,
"sizeof(struct pre_mem_ft) must be a multiple of 64 bytes and up to 256 bytes"); "sizeof(struct pre_mem_ft) must be a multiple of 64 bytes and up to 256 bytes");
bool is_debug_cse_fw_update_disable(void)
{
printk(BIOS_DEBUG, "rt_debug: pre_mem_debug.cse_fw_update_disable=%d\n",
pre_mem_debug.cse_fw_update_disable);
return pre_mem_debug.cse_fw_update_disable == 1;
}
uint8_t pre_mem_debug_init(void) uint8_t pre_mem_debug_init(void)
{ {
if (spi_flash_read(boot_device_spi_flash(), PRE_MEM_FEATURE_CTRL_OFFSET, if (spi_flash_read(boot_device_spi_flash(), PRE_MEM_FEATURE_CTRL_OFFSET,

View File

@ -5,6 +5,9 @@
#include <types.h> #include <types.h>
/* Check if CSE firmware update is enabled or not */
bool is_debug_cse_fw_update_disable(void);
/* /*
* Reads OEM Section area in the Descriptor Region and * Reads OEM Section area in the Descriptor Region and
* populates pre_mem_debug structure. * populates pre_mem_debug structure.

View File

@ -1,15 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
#include <arch/cpu.h>
#include <console/console.h> #include <console/console.h>
#include <cbfs.h> #include <cbfs.h>
#include <commonlib/region.h> #include <commonlib/region.h>
#include <fmap.h> #include <fmap.h>
#include <intelblocks/cse.h> #include <intelblocks/cse.h>
#include <intelblocks/cse_layout.h> #include <intelblocks/cse_layout.h>
#include <intelbasecode/debug_feature.h>
#include <security/vboot/vboot_common.h> #include <security/vboot/vboot_common.h>
#include <security/vboot/misc.h> #include <security/vboot/misc.h>
#include <soc/intel/common/reset.h> #include <soc/intel/common/reset.h>
#include <arch/cpu.h>
#define BPDT_HEADER_SZ sizeof(struct bpdt_header) #define BPDT_HEADER_SZ sizeof(struct bpdt_header)
#define BPDT_ENTRY_SZ sizeof(struct bpdt_entry) #define BPDT_ENTRY_SZ sizeof(struct bpdt_entry)
@ -663,6 +664,17 @@ static bool cse_write_rw_region(const struct region_device *target_rdev,
return true; return true;
} }
static bool is_cse_fw_update_enabled(void)
{
if (!CONFIG(SOC_INTEL_CSE_RW_UPDATE))
return false;
if (CONFIG(SOC_INTEL_COMMON_BASECODE_DEBUG_FEATURE))
return !is_debug_cse_fw_update_disable();
return true;
}
static enum csme_failure_reason cse_update_rw(const struct cse_bp_info *cse_bp_info, static enum csme_failure_reason cse_update_rw(const struct cse_bp_info *cse_bp_info,
const void *cse_cbfs_rw, const size_t cse_blob_sz, const void *cse_cbfs_rw, const size_t cse_blob_sz,
struct region_device *target_rdev) struct region_device *target_rdev)
@ -1079,10 +1091,11 @@ void cse_fw_sync(void)
cse_trigger_vboot_recovery(CSE_LITE_SKU_DATA_WIPE_ERROR); cse_trigger_vboot_recovery(CSE_LITE_SKU_DATA_WIPE_ERROR);
/* /*
* If SOC_INTEL_CSE_RW_UPDATE is defined , then trigger CSE firmware update. The driver * cse firmware update is skipped if SOC_INTEL_CSE_RW_UPDATE is not defined and
* triggers recovery if CSE CBFS RW metadata or CSE CBFS RW blob is not available. * runtime debug control flag is not enabled. The driver triggers recovery if CSE CBFS
* RW metadata or CSE CBFS RW blob is not available.
*/ */
if (CONFIG(SOC_INTEL_CSE_RW_UPDATE)) { if (is_cse_fw_update_enabled()) {
uint8_t rv; uint8_t rv;
rv = cse_fw_update(&cse_bp_info.bp_info); rv = cse_fw_update(&cse_bp_info.bp_info);
if (rv) if (rv)