15 #define BPDT_HEADER_SZ sizeof(struct bpdt_header)
16 #define BPDT_ENTRY_SZ sizeof(struct bpdt_entry)
17 #define SUBPART_HEADER_SZ sizeof(struct subpart_hdr)
18 #define SUBPART_ENTRY_SZ sizeof(struct subpart_entry)
19 #define SUBPART_MANIFEST_HDR_SZ sizeof(struct subpart_entry_manifest_header)
22 #define GET_BP_STR(bp_index) (bp_index ? "RW" : "RO")
25 #define CSE_RW_SIGNATURE 0x000055aa
28 #define CSE_RW_SIGN_SIZE sizeof(uint32_t)
38 #define CSE_MAX_BOOT_PARTITIONS 3
135 struct cse_boot_perf_req {
140 struct cse_boot_perf_req req = {
150 printk(
BIOS_ERR,
"cse_lite: Could not get boot performance data\n");
155 printk(
BIOS_ERR,
"cse_lite: Get boot performance data resp failed: %d\n",
188 printk(
BIOS_DEBUG,
"cse_lite: %s version = %d.%d.%d.%d (Status=0x%x, Start=0x%x, End=0x%x)\n",
195 printk(
BIOS_DEBUG,
"cse_lite: %s version = %d.%d.%d.%d (Status=0x%x, Start=0x%x, End=0x%x)\n",
228 struct get_bp_info_req {
233 struct get_bp_info_req info_req = {
253 printk(
BIOS_ERR,
"cse_lite: Get partition info resp failed: %d\n",
271 struct set_boot_partition_info_req {
277 struct set_boot_partition_info_req switch_req = {
284 if (bp !=
RO && bp !=
RW) {
285 printk(
BIOS_ERR,
"cse_lite: Incorrect partition id(%d) is provided", bp);
297 size_t sw_resp_sz =
sizeof(
struct mkhi_hdr);
299 if (
heci_send_receive(&switch_req,
sizeof(switch_req), &switch_resp, &sw_resp_sz,
304 printk(
BIOS_ERR,
"cse_lite: Set Boot Partition Info Response Failed: %d\n",
314 struct data_clr_request {
319 struct data_clr_request data_clr_rq = {
327 printk(
BIOS_ERR,
"cse_lite: CSE doesn't meet DATA CLEAR cmd prerequisites\n");
334 size_t data_clr_rsp_sz =
sizeof(data_clr_rsp);
341 if (data_clr_rsp.
result) {
342 printk(
BIOS_ERR,
"cse_lite: CSE DATA CLEAR command response failed: %d\n",
367 die(
"cse_lite: Failed to reset the system\n");
466 CONFIG_SOC_INTEL_CSE_FMAP_NAME);
478 printk(
BIOS_ERR,
"cse_lite: Failed to read RW boot partition signature\n");
497 size = end_offset + 1 - start_offset;
499 if (
rdev_chain(target_rdev, &cse_region_rdev, start_offset, size))
502 printk(
BIOS_DEBUG,
"cse_lite: CSE RW partition: offset = 0x%x, size = 0x%x\n",
515 return CONFIG_SOC_INTEL_CSE_RW_A_FMAP_NAME;
517 return CONFIG_SOC_INTEL_CSE_RW_B_FMAP_NAME;
541 const void *rw_blob,
const size_t rw_blob_sz)
544 uint8_t rw_comp_sha[VB2_SHA256_DIGEST_SIZE];
546 if (vb2_digest_buffer(rw_blob, rw_blob_sz, VB2_HASH_SHA256, rw_comp_sha,
547 VB2_SHA256_DIGEST_SIZE)) {
548 printk(
BIOS_ERR,
"cse_lite: CSE CBFS RW's SHA-256 calculation has failed\n");
552 if (
memcmp(expected_rw_blob_sha, rw_comp_sha, VB2_SHA256_DIGEST_SIZE)) {
553 printk(
BIOS_ERR,
"cse_lite: Computed CBFS RW's SHA-256 does not match with"
554 "the provided SHA in the metadata\n");
557 printk(
BIOS_SPEW,
"cse_lite: Computed SHA of CSE CBFS RW Image matches the"
558 " provided hash in the metadata\n");
565 printk(
BIOS_ERR,
"cse_lite: CSE RW partition could not be erased\n");
572 size_t offset,
size_t size)
592 if ((*curr - start) >= size) {
607 char *version_str, *ptr;
613 ptr = version_str =
cbfs_map(CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME, &size);
616 CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME);
620 if (!
read_ver_field(version_str, &ptr, size, &cbfs_rw_version.major) ||
621 !
read_ver_field(version_str, &ptr, size, &cbfs_rw_version.minor) ||
622 !
read_ver_field(version_str, &ptr, size, &cbfs_rw_version.hotfix) ||
623 !
read_ver_field(version_str, &ptr, size, &cbfs_rw_version.build)) {
629 cbfs_rw_version.major,
630 cbfs_rw_version.minor,
631 cbfs_rw_version.hotfix,
632 cbfs_rw_version.build);
646 const void *cse_cbfs_rw,
const size_t cse_cbfs_rw_sz)
656 cse_cbfs_rw_wo_sign_sz))
669 if (!
CONFIG(SOC_INTEL_CSE_RW_UPDATE))
672 if (
CONFIG(SOC_INTEL_COMMON_BASECODE_DEBUG_FEATURE))
679 const void *cse_cbfs_rw,
const size_t cse_blob_sz,
683 printk(
BIOS_ERR,
"RW update does not fit. CSE RW flash region size: %zx,"
731 CONFIG_SOC_INTEL_CSE_RW_CBFS_NAME, &size);
733 printk(
BIOS_ERR,
"cse_lite: CSE CBFS RW blob could not be mapped\n");
737 cbfs_rw_hash =
cbfs_map(CONFIG_SOC_INTEL_CSE_RW_HASH_CBFS_NAME,
NULL);
740 CONFIG_SOC_INTEL_CSE_RW_HASH_CBFS_NAME);
811 size = end_offset + 1 - start_offset;
813 if (
rdev_chain(cse_rdev, &cse_region_rdev, start_offset, size))
816 printk(
BIOS_DEBUG,
"cse_lite: CSE %s partition: offset = 0x%x, size = 0x%x\n",
830 printk(
BIOS_ERR,
"cse_lite: Failed to locate %s in the CSE Region\n",
836 printk(
BIOS_ERR,
"cse_lite: Failed to read BPDT header from CSE region\n");
843 printk(
BIOS_ERR,
"cse_lite: Failed to read BPDT entries from CSE region\n");
852 bpdt_entries[i].
size);
855 bpdt_entries[i].
size))
875 printk(
BIOS_ERR,
"cse_lite: Failed to read %s sub partition entry\n",
882 printk(
BIOS_ERR,
"cse_lite: Failed to read %s Sub part entry #0 manifest\n",
924 const void *subpart_cbfs_rw,
const size_t blob_sz,
929 "smaller than blob size:%zx, abort update\n",
939 if (!
cse_copy_rw(target_rdev, (
void *)subpart_cbfs_rw, 0, blob_sz))
965 struct fw_version target_fw_ver, source_fw_ver;
970 if (!subpart_cbfs_rw) {
978 source_fw_ver.major, source_fw_ver.minor, source_fw_ver.hotfix,
979 source_fw_ver.build);
995 target_fw_ver.minor, target_fw_ver.hotfix, target_fw_ver.build);
1013 size, &target_rdev);
1032 CONFIG_SOC_INTEL_CSE_IOM_CBFS_NAME);
1037 CONFIG_SOC_INTEL_CSE_NPHY_CBFS_NAME);
1051 printk(
BIOS_DEBUG,
"cse_lite: Skip switching to RW in the recovery path\n");
1062 printk(
BIOS_ERR,
"cse_lite: Failed to get CSE boot partition info\n");
1068 printk(
BIOS_ERR,
"cse_lite: System is already in Recovery Mode, "
1084 die(
"ERROR: GLOBAL RESET Failed to reset the system\n");
1105 if (
CONFIG(SOC_INTEL_CSE_SUB_PART_UPDATE))
void cbfs_unmap(void *mapping)
static void * cbfs_map(const char *name, size_t *size_out)
static void * cbfs_unverified_area_map(const char *area, const char *name, size_t *size_out)
bool cse_is_hfs1_com_soft_temp_disable(void)
bool cse_is_hfs1_cws_normal(void)
bool cse_is_hfs1_com_normal(void)
enum cse_tx_rx_status heci_send_receive(const void *snd_msg, size_t snd_sz, void *rcv_msg, size_t *rcv_sz, uint8_t cse_addr)
bool cse_is_hfs1_com_secover_mei_msg(void)
bool cse_is_hfs3_fw_sku_lite(void)
void cse_trigger_vboot_recovery(enum csme_failure_reason reason)
int cse_hmrfpo_enable(void)
#define printk(level,...)
void __noreturn die(const char *fmt,...)
#define MKHI_BUP_COMMON_GET_BOOT_PERF_DATA
@ CSE_COMMUNICATION_ERROR
@ CSE_LITE_SKU_SUB_PART_LAYOUT_MISMATCH_ERROR
@ CSE_LITE_SKU_SUB_PART_BLOB_ACCESS_ERR
@ CSE_LITE_SKU_RW_ACCESS_ERROR
@ CSE_LITE_SKU_LAYOUT_MISMATCH_ERROR
@ CSE_LITE_SKU_SUB_PART_UPDATE_NOT_REQ
@ CSE_LITE_SKU_FW_UPDATE_ERROR
@ CSE_LITE_SKU_SUB_PART_ACCESS_ERR
@ CSE_LITE_SKU_RW_SWITCH_ERROR
@ CSE_LITE_SKU_RW_JUMP_ERROR
@ CSE_LITE_SKU_RW_BLOB_SHA256_MISMATCH
@ CSE_LITE_SKU_PART_UPDATE_SUCCESS
@ CSE_LITE_SKU_RW_BLOB_NOT_FOUND
@ CSE_LITE_SKU_DATA_WIPE_ERROR
@ CSE_LITE_SKU_RW_METADATA_NOT_FOUND
@ CSE_LITE_SKU_SUB_PART_UPDATE_FAIL
#define MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO
#define MKHI_BUP_COMMON_SET_BOOT_PARTITION_INFO
#define MKHI_GROUP_ID_BUP_COMMON
#define MKHI_BUP_COMMON_DATA_CLEAR
static int cse_compare_sub_part_version(const struct fw_version *a, const struct fw_version *b)
static const char * cse_sub_part_str(enum bpdt_entry_type type)
@ BP_INFO_MIN_RECOV_MODE_EN
static bool cse_fix_data_failure_err(const struct cse_bp_info *cse_bp_info)
#define SUBPART_MANIFEST_HDR_SZ
static const char *const cse_regions[]
#define CSE_MAX_BOOT_PARTITIONS
static bool cse_boot_to_rw(const struct cse_bp_info *cse_bp_info)
__weak void cse_board_reset(void)
static bool cse_is_rw_dp_valid(const struct cse_bp_info *cse_bp_info)
static bool cse_copy_rw(const struct region_device *target_rdev, const void *buf, size_t offset, size_t size)
struct cse_bp_entry __packed
static uint8_t cse_fw_update(const struct cse_bp_info *cse_bp_info)
static bool cse_locate_area_as_rdev_rw(const struct cse_bp_info *cse_bp_info, size_t bp, struct region_device *cse_rdev)
static enum csme_failure_reason cse_trigger_fw_update(const struct cse_bp_info *cse_bp_info, enum cse_update_status status, struct region_device *target_rdev)
static const char * cse_get_source_rdev_fmap(void)
static bool cse_get_bp_info(struct get_bp_info_rsp *bp_info_rsp)
static bool cse_set_and_boot_from_next_bp(enum boot_partition_id bp)
static bool is_cse_fw_update_enabled(void)
static uint8_t cse_sub_part_trigger_update(enum bpdt_entry_type type, uint8_t bp, const void *subpart_cbfs_rw, const size_t blob_sz, struct region_device *target_rdev)
static const struct fw_version * cse_get_rw_version(const struct cse_bp_info *cse_bp_info)
@ BP_STATUS_GENERAL_FAILURE
@ BP_STATUS_PARTITION_NOT_PRESENT
static enum csme_failure_reason cse_sub_part_fw_component_update(enum bpdt_entry_type type, const struct cse_bp_info *cse_bp_info, const char *name)
static bool cse_is_rw_bp_sign_valid(const struct region_device *target_rdev)
static void cse_sub_part_get_source_fw_version(void *subpart_cbfs_rw, struct fw_version *fw_ver)
static bool cse_erase_rw_region(const struct region_device *target_rdev)
static bool cse_boot_to_ro(const struct cse_bp_info *cse_bp_info)
static const struct fw_version * cse_get_bp_entry_version(enum boot_partition_id bp, const struct cse_bp_info *bp_info)
static uint8_t cse_sub_part_fw_update(const struct cse_bp_info *cse_bp_info)
static bool cse_verify_cbfs_rw_sha256(const uint8_t *expected_rw_blob_sha, const void *rw_blob, const size_t rw_blob_sz)
static bool cse_is_rw_bp_status_valid(const struct cse_bp_info *cse_bp_info)
bool cse_get_boot_performance_data(struct cse_boot_perf_rsp *boot_perf_rsp)
static bool cse_sub_part_get_target_rdev(const struct cse_bp_info *cse_bp_info, struct region_device *target_rdev, size_t bp, enum bpdt_entry_type type)
#define SUBPART_HEADER_SZ
static uint8_t cse_get_current_bp(const struct cse_bp_info *cse_bp_info)
static enum cse_update_status cse_check_update_status(const struct cse_bp_info *cse_bp_info, struct region_device *target_rdev)
static bool cse_is_bp_cmd_info_possible(void)
static bool cse_set_next_boot_partition(enum boot_partition_id bp)
static bool cse_prep_for_rw_update(const struct cse_bp_info *cse_bp_info, enum cse_update_status status)
static bool cse_get_target_rdev(const struct cse_bp_info *cse_bp_info, struct region_device *target_rdev)
static bool cse_get_rw_rdev(struct region_device *rdev)
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, struct region_device *target_rdev)
#define GET_BP_STR(bp_index)
static void cse_print_boot_partition_info(const struct cse_bp_info *cse_bp_info)
static bool cse_prep_for_component_update(const struct cse_bp_info *cse_bp_info)
@ CSE_UPDATE_NOT_REQUIRED
@ CSE_UPDATE_METADATA_ERROR
static void cse_get_bp_entry_range(const struct cse_bp_info *cse_bp_info, enum boot_partition_id bp, uint32_t *start_offset, uint32_t *end_offset)
static bool cse_data_clear_request(const struct cse_bp_info *cse_bp_info)
static bool read_ver_field(const char *start, char **curr, size_t size, uint16_t *ver_field)
static uint8_t handle_cse_sub_part_fw_update_rv(uint8_t rv)
static bool cse_get_sub_part_fw_version(enum bpdt_entry_type type, const struct region_device *rdev, struct fw_version *fw_ver)
static bool cse_write_rw_region(const struct region_device *target_rdev, const void *cse_cbfs_rw, const size_t cse_cbfs_rw_sz)
static const struct cse_bp_entry * cse_get_bp_entry(enum boot_partition_id bp, const struct cse_bp_info *cse_bp_info)
bool is_debug_cse_fw_update_disable(void)
static struct region_device rdev
int fmap_locate_area_as_rdev_rw(const char *name, struct region_device *area)
#define BIOS_INFO
BIOS_INFO - Expected events.
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
static int vboot_is_firmware_slot_a(struct vb2_context *ctx)
ssize_t rdev_eraseat(const struct region_device *rd, size_t offset, size_t size)
static size_t region_device_sz(const struct region_device *rdev)
ssize_t rdev_writeat(const struct region_device *rd, const void *b, size_t offset, size_t size)
int rdev_chain(struct region_device *child, const struct region_device *parent, size_t offset, size_t size)
ssize_t rdev_readat(const struct region_device *rd, void *b, size_t offset, size_t size)
const struct smm_save_state_ops *legacy_ops __weak
int vboot_recovery_mode_enabled(void)
struct vb2_context * vboot_get_context(void)
void do_global_reset(void)
bool skip_cse_sub_part_update(void)
int strcmp(const char *s1, const char *s2)
unsigned int skip_atoi(char **s)
int memcmp(const void *s1, const void *s2, size_t n)
uint8_t total_number_of_bp
struct cse_bp_entry bp_entries[CSE_MAX_BOOT_PARTITIONS]
struct cse_bp_info bp_info