/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <bootstate.h>
#include <cbfs.h>
#include <commonlib/region.h>
#include <console/console.h>
#include <cpu/cpu.h>
#include <crc_byte.h>
#include <elog.h>
#include <fmap.h>
#include <intelbasecode/debug_feature.h>
#include <intelblocks/cse.h>
#include <intelblocks/cse_layout.h>
#include <intelblocks/spi.h>
#include <security/vboot/misc.h>
#include <security/vboot/vboot_common.h>
#include <soc/intel/common/reset.h>
#include <timestamp.h>

#include "cse_lite_cmos.h"

#define BPDT_HEADER_SZ		sizeof(struct bpdt_header)
#define BPDT_ENTRY_SZ		sizeof(struct bpdt_entry)
#define SUBPART_HEADER_SZ	sizeof(struct subpart_hdr)
#define SUBPART_ENTRY_SZ	sizeof(struct subpart_entry)
#define SUBPART_MANIFEST_HDR_SZ	sizeof(struct subpart_entry_manifest_header)

/* Converts bp index to boot partition string */
#define GET_BP_STR(bp_index) (bp_index ? "RW" : "RO")

/* CSE RW boot partition signature */
#define CSE_RW_SIGNATURE	0x000055aa

/* CSE RW boot partition signature size */
#define CSE_RW_SIGN_SIZE	sizeof(uint32_t)

/*
 * CSE Firmware supports 3 boot partitions. For CSE Lite SKU, only 2 boot partitions are
 * used and 3rd boot partition is set to BP_STATUS_PARTITION_NOT_PRESENT.
 * CSE Lite SKU Image Layout:
 * +------------+    +----+------+----+    +-----+------+-----+
 * | CSE REGION | => | RO | DATA | RW | => | BP1 | DATA | BP2 |
 * +------------+    +----+------+----+    +-----+------+-----+
 */
#define CSE_MAX_BOOT_PARTITIONS 3

/* CSE Lite SKU's valid bootable partition identifiers */
enum boot_partition_id {
	/* RO(BP1) contains recovery/minimal boot firmware */
	RO = 0,

	/* RW(BP2) contains fully functional CSE firmware */
	RW = 1
};

/*
 * Boot partition status.
 * The status is returned in response to MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO cmd.
 */
enum bp_status {
	/* This value is returned when a partition has no errors */
	BP_STATUS_SUCCESS = 0,

	/*
	 * This value is returned when a partition should be present based on layout, but it is
	 * not valid.
	 */
	BP_STATUS_GENERAL_FAILURE = 1,

	/* This value is returned when a partition is not present per initial image layout */
	BP_STATUS_PARTITION_NOT_PRESENT = 2,

	/*
	 * This value is returned when unexpected issues are detected in CSE Data area
	 * and CSE TCB-SVN downgrade scenario.
	 */
	BP_STATUS_DATA_FAILURE = 3,
};

/*
 * Boot Partition Info Flags
 * The flags are returned in response to MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO cmd.
 */
enum bp_info_flags {

	/* Redundancy Enabled: It indicates CSE supports RO(BP1) and RW(BP2) regions */
	BP_INFO_REDUNDANCY_EN = 1 << 0,

	/* It indicates RO(BP1) supports Minimal Recovery Mode */
	BP_INFO_MIN_RECOV_MODE_EN = 1 << 1,

	/*
	 * Read-only Config Enabled: It indicates HW protection to CSE RO region is enabled.
	 * The option is relevant only if the BP_INFO_MIN_RECOV_MODE_EN flag is enabled.
	 */
	BP_INFO_READ_ONLY_CFG = 1 << 2,
};

/* CSE boot partition entry info */
struct cse_bp_entry {
	/* Boot partition version */
	struct fw_version fw_ver;

	/* Boot partition status */
	uint32_t status;

	/* Starting offset of the partition within CSE region */
	uint32_t start_offset;

	/* Ending offset of the partition within CSE region */
	uint32_t end_offset;
	uint8_t reserved[12];
} __packed;

/* CSE boot partition info */
struct cse_bp_info {
	/* Number of boot partitions */
	uint8_t total_number_of_bp;

	/* Current boot partition */
	uint8_t current_bp;

	/* Next boot partition */
	uint8_t next_bp;

	/* Boot Partition Info Flags */
	uint8_t flags;

	/* Boot Partition Entry Info */
	struct cse_bp_entry bp_entries[CSE_MAX_BOOT_PARTITIONS];
} __packed;

struct get_bp_info_rsp {
	struct mkhi_hdr hdr;
	struct cse_bp_info bp_info;
} __packed;

static struct get_bp_info_rsp cse_bp_info_rsp;

enum cse_fw_state {
	/* The CMOS and CBMEM have the current fw version. */
	CSE_FW_WARM_BOOT,

	/* The CMOS has the current fw version, and the CBMEM is wiped out. */
	CSE_FW_COLD_BOOT,

	/* The CMOS and CBMEM are not initialized or not same as running firmware version.*/
	CSE_FW_INVALID,
};

static const char * const cse_regions[] = {"RO", "RW"};

static struct cse_specific_info cse_info;

void cse_log_ro_write_protection_info(bool mfg_mode)
{
	bool cse_ro_wp_en = is_spi_wp_cse_ro_en();

	printk(BIOS_DEBUG, "ME: WP for RO is enabled        : %s\n",
			cse_ro_wp_en ? "YES" : "NO");

	if (cse_ro_wp_en) {
		uint32_t base, limit;
		spi_get_wp_cse_ro_range(&base, &limit);
		printk(BIOS_DEBUG, "ME: RO write protection scope - Start=0x%X, End=0x%X\n",
				base, limit);
	}

	/*
	 * If manufacturing mode is disabled, but CSE RO is not write protected,
	 * log error.
	 */
	if (!mfg_mode && !cse_ro_wp_en)
		printk(BIOS_ERR, "ME: Write protection for CSE RO is not enabled\n");
}

enum cb_err cse_get_boot_performance_data(struct cse_boot_perf_rsp *boot_perf_rsp)
{
	struct cse_boot_perf_req {
		struct mkhi_hdr hdr;
		uint32_t reserved;
	} __packed;

	struct cse_boot_perf_req req = {
		.hdr.group_id = MKHI_GROUP_ID_BUP_COMMON,
		.hdr.command = MKHI_BUP_COMMON_GET_BOOT_PERF_DATA,
		.reserved = 0,
	};

	size_t resp_size = sizeof(struct cse_boot_perf_rsp);

	if (heci_send_receive(&req, sizeof(req), boot_perf_rsp, &resp_size,
									HECI_MKHI_ADDR)) {
		printk(BIOS_ERR, "cse_lite: Could not get boot performance data\n");
		return CB_ERR;
	}

	if (boot_perf_rsp->hdr.result) {
		printk(BIOS_ERR, "cse_lite: Get boot performance data resp failed: %d\n",
				boot_perf_rsp->hdr.result);
		return CB_ERR;
	}

	return CB_SUCCESS;
}

static const struct cse_bp_info *cse_get_bp_info_from_rsp(void)
{
	return &cse_bp_info_rsp.bp_info;
}

static uint8_t cse_get_current_bp(void)
{
	const struct cse_bp_info *cse_bp_info = cse_get_bp_info_from_rsp();
	return cse_bp_info->current_bp;
}

static const struct cse_bp_entry *cse_get_bp_entry(enum boot_partition_id bp)
{
	const struct cse_bp_info *cse_bp_info = cse_get_bp_info_from_rsp();
	return &cse_bp_info->bp_entries[bp];
}

static bool is_cse_fpt_info_valid(const struct cse_specific_info *info)
{
	uint32_t crc = ~CRC(info, offsetof(struct cse_specific_info, crc), crc32_byte);

	/*
	 * Authenticate the CBMEM persistent data.
	 *
	 * The underlying assumption is that an event (i.e., CSE upgrade/downgrade) which
	 * could change the values stored in this region has to also trigger the global
	 * reset. Hence, CBMEM persistent data won't be available any time after such
	 * event (global reset or cold reset) being initiated.
	 *
	 * During warm boot scenarios CBMEM contents remain persistent hence, we don't
	 * want to override the existing data in CBMEM to avoid any additional boot latency.
	 */
	if (info->crc != crc)
		return false;

	return true;
}

static void store_cse_info_crc(struct cse_specific_info *info)
{
	info->crc = ~CRC(info, offsetof(struct cse_specific_info, crc), crc32_byte);
}

static enum cse_fw_state get_cse_state(const struct fw_version *cur_cse_fw_ver,
	struct fw_version *cmos_cse_fw_ver, const struct fw_version *cbmem_cse_fw_ver)
{
	enum cse_fw_state state = CSE_FW_WARM_BOOT;
	size_t size = sizeof(struct fw_version);
	/*
	 * Compare if stored CSE version (from the previous boot) is same as current
	 * running CSE version.
	 */
	if (memcmp(cmos_cse_fw_ver, cur_cse_fw_ver, size)) {
		/*
		 * CMOS CSE versioin is invalid, possibly two scenarios
		 * 1.  CSE FW update
		 * 2.  First boot
		 */
		state = CSE_FW_INVALID;
	} else {
		/*
		 * Check if current running CSE version is same as previous stored CSE
		 * version aka CBMEM region is still valid.
		 */
		if (memcmp(cbmem_cse_fw_ver, cur_cse_fw_ver, size))
			state = CSE_FW_COLD_BOOT;
	}
	return state;
}

/*
 * Helper function that stores current CSE firmware version to CBMEM memory,
 * except during recovery mode.
 */
static void cse_store_rw_fw_version(void)
{
	const struct cse_bp_entry *cse_bp;
	cse_bp = cse_get_bp_entry(RW);

	if (vboot_recovery_mode_enabled())
		return;

	if (CONFIG(SOC_INTEL_CSE_LITE_SYNC_IN_ROMSTAGE)) {
		/* update current CSE version and return */
		memcpy(&(cse_info.cse_fwp_version.cur_cse_fw_version),
		 &(cse_bp->fw_ver), sizeof(struct fw_version));
		return;
	}

	struct cse_specific_info *cse_info_in_cbmem = cbmem_add(CBMEM_ID_CSE_INFO,
		 sizeof(*cse_info_in_cbmem));
	if (!cse_info_in_cbmem)
		return;

	/* Avoid CBMEM update if CBMEM already has persistent data */
	if (is_cse_fpt_info_valid(cse_info_in_cbmem))
		return;

	struct cse_specific_info cse_info_in_cmos;
	cmos_read_fw_partition_info(&cse_info_in_cmos);

	/* Get current cse firmware state */
	enum cse_fw_state fw_state = get_cse_state(&(cse_bp->fw_ver),
		 &(cse_info_in_cmos.cse_fwp_version.cur_cse_fw_version),
		 &(cse_info_in_cbmem->cse_fwp_version.cur_cse_fw_version));

	/* Reset CBMEM data and update current CSE version */
	memset(cse_info_in_cbmem, 0, sizeof(*cse_info_in_cbmem));
	memcpy(&(cse_info_in_cbmem->cse_fwp_version.cur_cse_fw_version),
		 &(cse_bp->fw_ver), sizeof(struct fw_version));

	/* Update the CRC */
	store_cse_info_crc(cse_info_in_cbmem);

	if (fw_state == CSE_FW_INVALID) {
		/*
		 * Current CMOS data is outdated, which could be due to CSE update or
		 * rollback, hence, need to update CMOS with current CSE FPT versions.
		 */
		cmos_write_fw_partition_info(cse_info_in_cbmem);
	}
}

#if CONFIG(SOC_INTEL_CSE_LITE_SYNC_IN_ROMSTAGE)
/* Function to copy PRERAM CSE specific info to pertinent CBMEM. */
static void preram_cse_info_sync_to_cbmem(int is_recovery)
{
	if (vboot_recovery_mode_enabled() || !CONFIG(SOC_INTEL_STORE_CSE_FW_VERSION))
		return;

	struct cse_specific_info *cse_info_in_cbmem = cbmem_add(CBMEM_ID_CSE_INFO,
		 sizeof(*cse_info_in_cbmem));
	if (!cse_info_in_cbmem)
		return;

	/* Warm Reboot: Avoid sync into CBMEM if CBMEM already has persistent data */
	if (is_cse_fpt_info_valid(cse_info_in_cbmem))
		return;

	/* Update CBMEM with PRERAM CSE specific info and update the CRC */
	memcpy(cse_info_in_cbmem, &cse_info, sizeof(struct cse_specific_info));
	store_cse_info_crc(cse_info_in_cbmem);

	struct cse_specific_info cse_info_in_cmos;
	cmos_read_fw_partition_info(&cse_info_in_cmos);

	if (!memcmp(&(cse_info_in_cmos.cse_fwp_version.cur_cse_fw_version),
		 &(cse_info_in_cbmem->cse_fwp_version.cur_cse_fw_version),
		 sizeof(struct fw_version))) {
		/* Cold Reboot: Avoid sync into CMOS if CMOS already has persistent data */
		if (is_cse_fpt_info_valid(&cse_info_in_cmos))
			return;
	}

	/*
	 * Current CMOS data is outdated, which could be due to CSE update or
	 * rollback, hence, need to update CMOS with current CSE FPT versions.
	 */
	cmos_write_fw_partition_info(cse_info_in_cbmem);
}

CBMEM_CREATION_HOOK(preram_cse_info_sync_to_cbmem);
#endif

static void cse_print_boot_partition_info(void)
{
	const struct cse_bp_entry *cse_bp;
	const struct cse_bp_info *cse_bp_info = cse_get_bp_info_from_rsp();

	printk(BIOS_DEBUG, "cse_lite: Number of partitions = %d\n",
			cse_bp_info->total_number_of_bp);
	printk(BIOS_DEBUG, "cse_lite: Current partition = %s\n",
			GET_BP_STR(cse_bp_info->current_bp));
	printk(BIOS_DEBUG, "cse_lite: Next partition = %s\n", GET_BP_STR(cse_bp_info->next_bp));
	printk(BIOS_DEBUG, "cse_lite: Flags = 0x%x\n", cse_bp_info->flags);

	/* Log version info of RO & RW partitions */
	cse_bp = cse_get_bp_entry(RO);
	printk(BIOS_DEBUG, "cse_lite: %s version = %d.%d.%d.%d (Status=0x%x, Start=0x%x, End=0x%x)\n",
			GET_BP_STR(RO), cse_bp->fw_ver.major, cse_bp->fw_ver.minor,
			cse_bp->fw_ver.hotfix, cse_bp->fw_ver.build,
			cse_bp->status, cse_bp->start_offset,
			cse_bp->end_offset);

	cse_bp = cse_get_bp_entry(RW);
	printk(BIOS_DEBUG, "cse_lite: %s version = %d.%d.%d.%d (Status=0x%x, Start=0x%x, End=0x%x)\n",
			GET_BP_STR(RW), cse_bp->fw_ver.major, cse_bp->fw_ver.minor,
			cse_bp->fw_ver.hotfix, cse_bp->fw_ver.build,
			cse_bp->status, cse_bp->start_offset,
			cse_bp->end_offset);
}

/*
 * Checks prerequisites for MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO and
 * MKHI_BUP_COMMON_SET_BOOT_PARTITION_INFO HECI commands.
 * It allows execution of the Boot Partition commands in below scenarios:
 *	- When CSE boots from RW partition (COM: Normal and CWS: Normal)
 *	- When CSE boots from RO partition (COM: Soft Temp Disable and CWS: Normal)
 *	- After HMRFPO_ENABLE command is issued to CSE (COM: SECOVER_MEI_MSG and CWS: Normal)
 * The prerequisite check should be handled in cse_get_bp_info() and
 * cse_set_next_boot_partition() since the CSE's current operation mode is changed between these
 * cmd handler calls.
 */
static bool cse_is_bp_cmd_info_possible(void)
{
	if (cse_is_hfs1_cws_normal()) {
		if (cse_is_hfs1_com_normal())
			return true;
		if (cse_is_hfs1_com_secover_mei_msg())
			return true;
		if (cse_is_hfs1_com_soft_temp_disable())
			return true;
	}
	return false;
}

static struct get_bp_info_rsp *sync_cse_bp_info_to_cbmem(void)
{
	struct get_bp_info_rsp *cse_bp_info_in_cbmem = cbmem_find(CBMEM_ID_CSE_BP_INFO);

	if (cse_bp_info_in_cbmem != NULL)
		return cse_bp_info_in_cbmem;

	cse_bp_info_in_cbmem = cbmem_add(CBMEM_ID_CSE_BP_INFO,
		sizeof(struct get_bp_info_rsp));

	if (!cse_bp_info_in_cbmem) {
		printk(BIOS_ERR, "Unable to store Boot Parition Info in cbmem\n");
		return NULL;
	}

	/* Copy the CSE Boot Partition Info command response to cbmem */
	memcpy(cse_bp_info_in_cbmem, &cse_bp_info_rsp, sizeof(struct get_bp_info_rsp));

	return cse_bp_info_in_cbmem;
}

static bool is_cse_bp_info_valid(struct get_bp_info_rsp *bp_info_rsp)
{
	/*
	 * In case the cse_bp_info_rsp header group ID, command is incorrect or is_resp is 0,
	 * then return false to indicate cse_bp_info is not valid.
	 */
	return (bp_info_rsp->hdr.group_id != MKHI_GROUP_ID_BUP_COMMON ||
		bp_info_rsp->hdr.command != MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO ||
		!bp_info_rsp->hdr.is_resp) ? false : true;
}

static enum cb_err cse_get_bp_info(void)
{
	struct get_bp_info_req {
		struct mkhi_hdr hdr;
		uint8_t reserved[4];
	} __packed;

	struct get_bp_info_req info_req = {
		.hdr.group_id = MKHI_GROUP_ID_BUP_COMMON,
		.hdr.command = MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO,
		.reserved = {0},
	};

	/*
	 * If SOC_INTEL_CSE_LITE_SYNC_IN_RAMSTAGE config is selected and memory has been
	 * initialized, check if there is cse bp info response stored in cbmem. Once the data
	 * is validated, copy it to the global cse_bp_info_rsp so that it can be used by other
	 * functions. In case, data is not available in cbmem or invalid, continue to send the
	 * GET_BOOT_PARTITION_INFO command, else return.
	 */
	if (CONFIG(SOC_INTEL_CSE_LITE_SYNC_IN_RAMSTAGE) && cbmem_online()) {
		struct get_bp_info_rsp *cse_bp_info_in_cbmem = sync_cse_bp_info_to_cbmem();
		if (cse_bp_info_in_cbmem) {
			if (is_cse_bp_info_valid(cse_bp_info_in_cbmem)) {
				memcpy(&cse_bp_info_rsp, cse_bp_info_in_cbmem,
					sizeof(struct get_bp_info_rsp));
				return CB_SUCCESS;
			}
		}
	} else {
		/*
		 * If SOC_INTEL_CSE_LITE_SYNC_IN_ROMSTAGE config is selected, check if the
		 * global cse bp info response stored in global cse_bp_info_rsp is valid.
		 * In case, it is not valid, continue to send the GET_BOOT_PARTITION_INFO
		 * command, else return.
		 */
		if (is_cse_bp_info_valid(&cse_bp_info_rsp))
			return CB_SUCCESS;
	}

	if (!cse_is_bp_cmd_info_possible()) {
		printk(BIOS_ERR, "cse_lite: CSE does not meet prerequisites\n");
		return CB_ERR;
	}

	size_t resp_size = sizeof(struct get_bp_info_rsp);

	if (heci_send_receive(&info_req, sizeof(info_req), &cse_bp_info_rsp, &resp_size,
									HECI_MKHI_ADDR)) {
		printk(BIOS_ERR, "cse_lite: Could not get partition info\n");
		return CB_ERR;
	}

	if (cse_bp_info_rsp.hdr.result) {
		printk(BIOS_ERR, "cse_lite: Get partition info resp failed: %d\n",
				cse_bp_info_rsp.hdr.result);
		return CB_ERR;
	}

	cse_print_boot_partition_info();
	return CB_SUCCESS;
}

void cse_fill_bp_info(void)
{
	if (vboot_recovery_mode_enabled())
		return;

	if (cse_get_bp_info() != CB_SUCCESS)
		cse_trigger_vboot_recovery(CSE_COMMUNICATION_ERROR);
}

/* Function to copy PRERAM CSE BP info to pertinent CBMEM. */
static void preram_cse_bp_info_sync_to_cbmem(int is_recovery)
{
	if (vboot_recovery_mode_enabled())
		return;

	sync_cse_bp_info_to_cbmem();
}

CBMEM_CREATION_HOOK(preram_cse_bp_info_sync_to_cbmem);

/*
 * It sends HECI command to notify CSE about its next boot partition. When coreboot wants
 * CSE to boot from certain partition (BP1 <RO> or BP2 <RW>), then this command can be used.
 * The CSE's valid bootable partitions are BP1(RO) and BP2(RW).
 * This function must be used before EOP.
 * Returns false on failure and true on success.
 */
static enum cb_err cse_set_next_boot_partition(enum boot_partition_id bp)
{
	struct set_boot_partition_info_req {
		struct mkhi_hdr hdr;
		uint8_t next_bp;
		uint8_t reserved[3];
	} __packed;

	struct set_boot_partition_info_req switch_req = {
		.hdr.group_id = MKHI_GROUP_ID_BUP_COMMON,
		.hdr.command = MKHI_BUP_COMMON_SET_BOOT_PARTITION_INFO,
		.next_bp = bp,
		.reserved = {0},
	};

	if (bp != RO && bp != RW) {
		printk(BIOS_ERR, "cse_lite: Incorrect partition id(%d) is provided", bp);
		return CB_ERR_ARG;
	}

	printk(BIOS_INFO, "cse_lite: Set Boot Partition Info Command (%s)\n", GET_BP_STR(bp));

	if (!cse_is_bp_cmd_info_possible()) {
		printk(BIOS_ERR, "cse_lite: CSE does not meet prerequisites\n");
		return CB_ERR;
	}

	struct mkhi_hdr switch_resp;
	size_t sw_resp_sz = sizeof(struct mkhi_hdr);

	if (heci_send_receive(&switch_req, sizeof(switch_req), &switch_resp, &sw_resp_sz,
									HECI_MKHI_ADDR))
		return CB_ERR;

	if (switch_resp.result) {
		printk(BIOS_ERR, "cse_lite: Set Boot Partition Info Response Failed: %d\n",
				switch_resp.result);
		return CB_ERR;
	}

	return CB_SUCCESS;
}

static enum cb_err cse_data_clear_request(void)
{
	struct data_clr_request {
		struct mkhi_hdr hdr;
		uint8_t reserved[4];
	} __packed;

	struct data_clr_request data_clr_rq = {
		.hdr.group_id = MKHI_GROUP_ID_BUP_COMMON,
		.hdr.command = MKHI_BUP_COMMON_DATA_CLEAR,
		.reserved = {0},
	};

	if (!cse_is_hfs1_cws_normal() || !cse_is_hfs1_com_soft_temp_disable() ||
			cse_get_current_bp() != RO) {
		printk(BIOS_ERR, "cse_lite: CSE doesn't meet DATA CLEAR cmd prerequisites\n");
		return CB_ERR;
	}

	printk(BIOS_DEBUG, "cse_lite: Sending DATA CLEAR HECI command\n");

	struct mkhi_hdr data_clr_rsp;
	size_t data_clr_rsp_sz = sizeof(data_clr_rsp);

	if (heci_send_receive(&data_clr_rq, sizeof(data_clr_rq), &data_clr_rsp,
				&data_clr_rsp_sz, HECI_MKHI_ADDR)) {
		return CB_ERR;
	}

	if (data_clr_rsp.result) {
		printk(BIOS_ERR, "cse_lite: CSE DATA CLEAR command response failed: %d\n",
				data_clr_rsp.result);
		return CB_ERR;
	}

	return CB_SUCCESS;
}

__weak void cse_board_reset(void)
{
	/* Default weak implementation, does nothing. */
}

__weak void cse_fw_update_misc_oper(void)
{
	/* Default weak implementation, does nothing. */
}

/* Set the CSE's next boot partition and issues system reset */
static enum cb_err cse_set_and_boot_from_next_bp(enum boot_partition_id bp)
{
	if (cse_set_next_boot_partition(bp) != CB_SUCCESS)
		return CB_ERR;

	/* Allow the board to perform a reset for CSE RO<->RW jump */
	cse_board_reset();

	/* If board does not perform the reset, then perform global_reset */
	do_global_reset();

	die("cse_lite: Failed to reset the system\n");

	/* Control never reaches here */
	return CB_ERR;
}

static enum cb_err cse_boot_to_rw(void)
{
	if (cse_get_current_bp() == RW)
		return CB_SUCCESS;

	return cse_set_and_boot_from_next_bp(RW);
}

/* Check if CSE RW data partition is valid or not */
static bool cse_is_rw_dp_valid(void)
{
	const struct cse_bp_entry *rw_bp;

	rw_bp = cse_get_bp_entry(RW);
	return rw_bp->status != BP_STATUS_DATA_FAILURE;
}

/*
 * It returns true if RW partition doesn't indicate BP_STATUS_DATA_FAILURE
 * otherwise false if any operation fails.
 */
static enum cb_err cse_fix_data_failure_err(void)
{
	/*
	 * If RW partition status indicates BP_STATUS_DATA_FAILURE,
	 *  - Send DATA CLEAR HECI command to CSE
	 *  - Send SET BOOT PARTITION INFO(RW) command to set CSE's next partition
	 *  - Issue GLOBAL RESET HECI command.
	 */
	if (cse_is_rw_dp_valid())
		return CB_SUCCESS;

	if (cse_data_clear_request() != CB_SUCCESS)
		return CB_ERR;

	return cse_boot_to_rw();
}

static const struct fw_version *cse_get_bp_entry_version(enum boot_partition_id bp)
{
	const struct cse_bp_entry *cse_bp;

	cse_bp = cse_get_bp_entry(bp);
	return &cse_bp->fw_ver;
}

static const struct fw_version *cse_get_rw_version(void)
{
	return cse_get_bp_entry_version(RW);
}

static void cse_get_bp_entry_range(enum boot_partition_id bp, uint32_t *start_offset,
		uint32_t *end_offset)
{
	const struct cse_bp_entry *cse_bp;

	cse_bp = cse_get_bp_entry(bp);

	if (start_offset)
		*start_offset = cse_bp->start_offset;

	if (end_offset)
		*end_offset = cse_bp->end_offset;

}

static bool cse_is_rw_bp_status_valid(void)
{
	const struct cse_bp_entry *rw_bp;

	rw_bp = cse_get_bp_entry(RW);

	if (rw_bp->status == BP_STATUS_PARTITION_NOT_PRESENT ||
			rw_bp->status == BP_STATUS_GENERAL_FAILURE) {
		printk(BIOS_ERR, "cse_lite: RW BP (status:%u) is not valid\n", rw_bp->status);
		return false;
	}
	return true;
}

static enum cb_err cse_boot_to_ro(void)
{
	if (cse_get_current_bp() == RO)
		return CB_SUCCESS;

	return cse_set_and_boot_from_next_bp(RO);
}

static enum cb_err cse_get_rw_rdev(struct region_device *rdev)
{
	if (fmap_locate_area_as_rdev_rw(CONFIG_SOC_INTEL_CSE_FMAP_NAME, rdev) < 0) {
		printk(BIOS_ERR, "cse_lite: Failed to locate %s in FMAP\n",
				CONFIG_SOC_INTEL_CSE_FMAP_NAME);
		return CB_ERR;
	}

	return CB_SUCCESS;
}

static bool cse_is_rw_bp_sign_valid(const struct region_device *target_rdev)
{
	uint32_t cse_bp_sign;

	if (rdev_readat(target_rdev, &cse_bp_sign, 0, CSE_RW_SIGN_SIZE) != CSE_RW_SIGN_SIZE) {
		printk(BIOS_ERR, "cse_lite: Failed to read RW boot partition signature\n");
		return false;
	}

	return cse_bp_sign == CSE_RW_SIGNATURE;
}

static enum cb_err cse_get_target_rdev(struct region_device *target_rdev)
{
	struct region_device cse_region_rdev;
	size_t size;
	uint32_t start_offset;
	uint32_t end_offset;

	if (cse_get_rw_rdev(&cse_region_rdev) != CB_SUCCESS)
		return CB_ERR;

	cse_get_bp_entry_range(RW, &start_offset, &end_offset);
	size = end_offset + 1 - start_offset;

	if (rdev_chain(target_rdev, &cse_region_rdev, start_offset, size))
		return CB_ERR;

	printk(BIOS_DEBUG, "cse_lite: CSE RW partition: offset = 0x%x, size = 0x%x\n",
			(uint32_t)start_offset, (uint32_t)size);

	return CB_SUCCESS;
}

static const char *cse_get_source_rdev_fmap(void)
{
	struct vb2_context *ctx = vboot_get_context();
	if (ctx == NULL)
		return NULL;

	if (vboot_is_firmware_slot_a(ctx))
		return CONFIG_SOC_INTEL_CSE_RW_A_FMAP_NAME;

	return CONFIG_SOC_INTEL_CSE_RW_B_FMAP_NAME;
}

/*
 * Compare versions of CSE CBFS sub-component and CSE sub-component partition
 * In case of CSE component comparison:
 * If ver_cmp_status = 0, no update is required
 * If ver_cmp_status < 0, coreboot downgrades CSE RW region
 * If ver_cmp_status > 0, coreboot upgrades CSE RW region
 */
static int cse_compare_sub_part_version(const struct fw_version *a, const struct fw_version *b)
{
	if (a->major != b->major)
		return a->major - b->major;
	else if (a->minor != b->minor)
		return a->minor - b->minor;
	else if (a->hotfix != b->hotfix)
		return a->hotfix - b->hotfix;
	else
		return a->build - b->build;
}

/* The function calculates SHA-256 of CSE RW blob and compares it with the provided SHA value */
static bool cse_verify_cbfs_rw_sha256(const uint8_t *expected_rw_blob_sha,
		const void *rw_blob, const size_t rw_blob_sz)

{
	struct vb2_hash calculated;

	if (vb2_hash_calculate(vboot_hwcrypto_allowed(), rw_blob, rw_blob_sz,
			       VB2_HASH_SHA256, &calculated)) {
		printk(BIOS_ERR, "cse_lite: CSE CBFS RW's SHA-256 calculation has failed\n");
		return false;
	}

	if (memcmp(expected_rw_blob_sha, calculated.sha256, sizeof(calculated.sha256))) {
		printk(BIOS_ERR, "cse_lite: Computed CBFS RW's SHA-256 does not match with"
				"the provided SHA in the metadata\n");
		return false;
	}
	printk(BIOS_SPEW, "cse_lite: Computed SHA of CSE CBFS RW Image matches the"
			" provided hash in the metadata\n");
	return true;
}

static enum cb_err cse_erase_rw_region(const struct region_device *target_rdev)
{
	if (rdev_eraseat(target_rdev, 0, region_device_sz(target_rdev)) < 0) {
		printk(BIOS_ERR, "cse_lite: CSE RW partition could not be erased\n");
		return CB_ERR;
	}
	return CB_SUCCESS;
}

static enum cb_err cse_copy_rw(const struct region_device *target_rdev, const void *buf,
		size_t offset, size_t size)
{
	if (rdev_writeat(target_rdev, buf, offset, size) < 0) {
		printk(BIOS_ERR, "cse_lite: Failed to update CSE firmware\n");
		return CB_ERR;
	}

	return CB_SUCCESS;
}

enum cse_update_status {
	CSE_UPDATE_NOT_REQUIRED,
	CSE_UPDATE_UPGRADE,
	CSE_UPDATE_DOWNGRADE,
	CSE_UPDATE_CORRUPTED,
	CSE_UPDATE_METADATA_ERROR,
};

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 cb_err get_cse_ver_from_cbfs(struct fw_version *cbfs_rw_version)
{
	char *version_str, *cbfs_ptr;
	size_t size;

	if (cbfs_rw_version == NULL)
		return CB_ERR;

	cbfs_ptr = cbfs_map(CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME, &size);
	version_str = cbfs_ptr;
	if (!version_str) {
		printk(BIOS_ERR, "cse_lite: Failed to get %s\n",
			  CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME);
		return CB_ERR;
	}

	if (!read_ver_field(version_str, &cbfs_ptr, size, &cbfs_rw_version->major) ||
	    !read_ver_field(version_str, &cbfs_ptr, size, &cbfs_rw_version->minor) ||
		!read_ver_field(version_str, &cbfs_ptr, size, &cbfs_rw_version->hotfix) ||
		!read_ver_field(version_str, &cbfs_ptr, size, &cbfs_rw_version->build)) {
		cbfs_unmap(version_str);
		return CB_ERR;
	}

	cbfs_unmap(version_str);
	return CB_SUCCESS;
}

static enum cse_update_status cse_check_update_status(struct region_device *target_rdev)
{
	int ret;
	struct fw_version cbfs_rw_version;

	if (!cse_is_rw_bp_sign_valid(target_rdev))
		return CSE_UPDATE_CORRUPTED;

	if (get_cse_ver_from_cbfs(&cbfs_rw_version) == CB_ERR)
		return CSE_UPDATE_METADATA_ERROR;

	printk(BIOS_DEBUG, "cse_lite: CSE CBFS RW version : %d.%d.%d.%d\n",
			cbfs_rw_version.major,
			cbfs_rw_version.minor,
			cbfs_rw_version.hotfix,
			cbfs_rw_version.build);

	ret = cse_compare_sub_part_version(&cbfs_rw_version, cse_get_rw_version());
	if (ret == 0)
		return CSE_UPDATE_NOT_REQUIRED;
	else if (ret < 0)
		return CSE_UPDATE_DOWNGRADE;
	else
		return CSE_UPDATE_UPGRADE;
}

static enum cb_err cse_write_rw_region(const struct region_device *target_rdev,
		const void *cse_cbfs_rw, const size_t cse_cbfs_rw_sz)
{
	/* Points to CSE CBFS RW image after boot partition signature */
	uint8_t *cse_cbfs_rw_wo_sign = (uint8_t *)cse_cbfs_rw + CSE_RW_SIGN_SIZE;

	/* Size of CSE CBFS RW image without boot partition signature */
	uint32_t cse_cbfs_rw_wo_sign_sz = cse_cbfs_rw_sz - CSE_RW_SIGN_SIZE;

	/* Update except CSE RW signature */
	if (cse_copy_rw(target_rdev, cse_cbfs_rw_wo_sign, CSE_RW_SIGN_SIZE,
				cse_cbfs_rw_wo_sign_sz) != CB_SUCCESS)
		return CB_ERR;

	/* Update CSE RW signature to indicate update is complete */
	if (cse_copy_rw(target_rdev, (void *)cse_cbfs_rw, 0, CSE_RW_SIGN_SIZE) != CB_SUCCESS)
		return CB_ERR;

	printk(BIOS_INFO, "cse_lite: CSE RW Update Successful\n");
	return CB_SUCCESS;
}

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 void *cse_cbfs_rw, const size_t cse_blob_sz,
		struct region_device *target_rdev)
{
	if (region_device_sz(target_rdev) < cse_blob_sz) {
		printk(BIOS_ERR, "RW update does not fit. CSE RW flash region size: %zx,"
			"Update blob size:%zx\n", region_device_sz(target_rdev), cse_blob_sz);
		return CSE_LITE_SKU_LAYOUT_MISMATCH_ERROR;
	}

	if (cse_erase_rw_region(target_rdev) != CB_SUCCESS)
		return CSE_LITE_SKU_FW_UPDATE_ERROR;

	if (cse_write_rw_region(target_rdev, cse_cbfs_rw, cse_blob_sz) != CB_SUCCESS)
		return CSE_LITE_SKU_FW_UPDATE_ERROR;

	return CSE_NO_ERROR;
}

static enum cb_err cse_prep_for_rw_update(enum cse_update_status status)
{
	if (status == CSE_UPDATE_CORRUPTED)
		elog_add_event(ELOG_TYPE_PSR_DATA_LOST);
	/*
	 * To set CSE's operation mode to HMRFPO mode:
	 * 1. Ensure CSE to boot from RO(BP1)
	 * 2. Send HMRFPO_ENABLE command to CSE
	 */
	if (cse_boot_to_ro() != CB_SUCCESS)
		return CB_ERR;

	if ((status == CSE_UPDATE_DOWNGRADE) || (status == CSE_UPDATE_CORRUPTED)) {
		/* Reset the PSR backup command status in CMOS */
		if (CONFIG(SOC_INTEL_CSE_LITE_PSR))
			update_psr_backup_status(PSR_BACKUP_PENDING);

		if (cse_data_clear_request() != CB_SUCCESS) {
			printk(BIOS_ERR, "cse_lite: CSE data clear failed!\n");
			return CB_ERR;
		}
	}

	return cse_hmrfpo_enable();
}

static enum csme_failure_reason cse_trigger_fw_update(enum cse_update_status status,
		struct region_device *target_rdev)
{
	enum csme_failure_reason rv;
	uint8_t *cbfs_rw_hash;
	void *cse_cbfs_rw = NULL;
	size_t size;

	const char *area_name = cse_get_source_rdev_fmap();
	if (!area_name)
		return CSE_LITE_SKU_RW_BLOB_NOT_FOUND;

	if (CONFIG(SOC_INTEL_CSE_LITE_COMPRESS_ME_RW)) {
		cse_cbfs_rw = cbfs_unverified_area_cbmem_alloc(area_name,
			CONFIG_SOC_INTEL_CSE_RW_CBFS_NAME, CBMEM_ID_CSE_UPDATE, &size);
	} else {
		cse_cbfs_rw = cbfs_unverified_area_map(area_name,
			CONFIG_SOC_INTEL_CSE_RW_CBFS_NAME, &size);
	}
	if (!cse_cbfs_rw) {
		printk(BIOS_ERR, "cse_lite: CSE CBFS RW blob could not be mapped\n");
		return CSE_LITE_SKU_RW_BLOB_NOT_FOUND;
	}

	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, size)) {
		rv = CSE_LITE_SKU_RW_BLOB_SHA256_MISMATCH;
		goto error_exit;
	}

	if (cse_prep_for_rw_update(status) != CB_SUCCESS) {
		rv = CSE_COMMUNICATION_ERROR;
		goto error_exit;
	}

	cse_fw_update_misc_oper();
	rv = cse_update_rw(cse_cbfs_rw, size, target_rdev);

error_exit:
	cbfs_unmap(cbfs_rw_hash);
	cbfs_unmap(cse_cbfs_rw);
	return rv;
}

static bool is_psr_data_backed_up(void)
{
	/* Track PSR backup status in CMOS */
	return (get_psr_backup_status() == PSR_BACKUP_DONE);
}

static bool is_psr_supported(void)
{
	uint32_t feature_status;

	/*
	 * Check if SoC has support for PSR feature typically PSR feature
	 * is only supported by vpro SKU
	 *
	 */
	if (cse_get_fw_feature_state(&feature_status) != CB_SUCCESS) {
		printk(BIOS_ERR, "cse_get_fw_feature_state command failed !\n");
		return false;
	}

	if (!(feature_status & ME_FW_FEATURE_PSR)) {
		printk(BIOS_DEBUG, "PSR is not supported in this SKU !\n");
		return false;
	}

	return true;
}

/*
 * PSR data needs to be backed up prior to downgrade. So switch the CSE boot mode to RW, send
 * PSR back-up command to CSE and update the PSR back-up state in CMOS.
 */
static void backup_psr_data(void)
{
	printk(BIOS_DEBUG, "cse_lite: Initiate PSR data backup flow\n");
	/* Switch CSE to RW to send PSR_HECI_FW_DOWNGRADE_BACKUP command */
	if (cse_boot_to_rw() != CB_SUCCESS) {
		elog_add_event(ELOG_TYPE_PSR_DATA_LOST);
		goto update_and_exit;
	}
	/*
	 * The function to check for PSR feature support can only be called after
	 * switching to RW partition. The command MKHI_FWCAPS_GET_FW_FEATURE_STATE
	 * that gives feature state is supported by a process that is loaded only
	 * when CSE boots from RW.
	 *
	 */
	if (!is_psr_supported())
		goto update_and_exit;

	/*
	 * Prerequisites:
	 * 1) HFSTS1 Current Working State is Normal
	 * 2) HFSTS1 Current Operation Mode is Normal
	 */
	if (!cse_is_hfs1_cws_normal() || !cse_is_hfs1_com_normal()) {
		printk(BIOS_DEBUG, "cse_lite: PSR_HECI_FW_DOWNGRADE_BACKUP command "
		       "prerequisites not met!\n");
		elog_add_event(ELOG_TYPE_PSR_DATA_LOST);
		goto update_and_exit;
	}

	/* Send PSR_HECI_FW_DOWNGRADE_BACKUP command */
	struct psr_heci_fw_downgrade_backup_req {
		struct psr_heci_header header;
	} __packed;

	struct psr_heci_fw_downgrade_backup_req req = {
		.header.command = PSR_HECI_FW_DOWNGRADE_BACKUP,
	};

	struct psr_heci_fw_downgrade_backup_res {
		struct psr_heci_header header;
		uint32_t status;
	} __packed;

	struct psr_heci_fw_downgrade_backup_res backup_psr_resp;
	size_t resp_size = sizeof(backup_psr_resp);

	printk(BIOS_DEBUG, "cse_lite: Send PSR_HECI_FW_DOWNGRADE_BACKUP command\n");
	if (heci_send_receive(&req, sizeof(req),
		&backup_psr_resp, &resp_size, HECI_PSR_ADDR)) {
		printk(BIOS_ERR, "cse_lite: could not backup PSR data\n");
		elog_add_event_byte(ELOG_TYPE_PSR_DATA_BACKUP, ELOG_PSR_DATA_BACKUP_FAILED);
	} else {
		if (backup_psr_resp.status != PSR_STATUS_SUCCESS) {
			printk(BIOS_ERR, "cse_lite: PSR_HECI_FW_DOWNGRADE_BACKUP command "
			       "returned %u\n", backup_psr_resp.status);
			elog_add_event_byte(ELOG_TYPE_PSR_DATA_BACKUP,
						ELOG_PSR_DATA_BACKUP_FAILED);
		} else {
			elog_add_event_byte(ELOG_TYPE_PSR_DATA_BACKUP,
						ELOG_PSR_DATA_BACKUP_SUCCESS);
		}
	}

update_and_exit:
	/*
	 * An attempt to send PSR back-up command has been made. Update this info in CMOS and
	 * send success once backup_psr_data() has been called. We do not want to put the system
	 * into recovery for PSR data backup command pre-requisites not being met.
	 * We cannot do much if CSE fails to backup the PSR data, except create an event log.
	 */
	update_psr_backup_status(PSR_BACKUP_DONE);
	return;
}

static void initiate_psr_data_backup(void)
{
	if (is_psr_data_backed_up())
		return;

	backup_psr_data();
}

static uint8_t cse_fw_update(void)
{
	struct region_device target_rdev;
	enum cse_update_status status;

	if (cse_get_target_rdev(&target_rdev) != CB_SUCCESS) {
		printk(BIOS_ERR, "cse_lite: Failed to get CSE RW Partition\n");
		return CSE_LITE_SKU_RW_ACCESS_ERROR;
	}

	status = cse_check_update_status(&target_rdev);
	if (status == CSE_UPDATE_NOT_REQUIRED)
		return CSE_NO_ERROR;
	if (status == CSE_UPDATE_METADATA_ERROR)
		return CSE_LITE_SKU_RW_METADATA_NOT_FOUND;
	if (CONFIG(SOC_INTEL_CSE_LITE_PSR) && status == CSE_UPDATE_DOWNGRADE)
		initiate_psr_data_backup();

	printk(BIOS_DEBUG, "cse_lite: CSE RW update is initiated\n");
	return cse_trigger_fw_update(status, &target_rdev);
}

static const char *cse_sub_part_str(enum bpdt_entry_type type)
{
	switch (type) {
	case IOM_FW:
		return "IOM";
	case NPHY_FW:
		return "NPHY";
	default:
		return "Unknown";
	}
}

static enum cb_err cse_locate_area_as_rdev_rw(size_t bp, struct region_device  *cse_rdev)
{
	struct region_device cse_region_rdev;
	uint32_t size;
	uint32_t start_offset;
	uint32_t end_offset;

	if (cse_get_rw_rdev(&cse_region_rdev) != CB_SUCCESS)
		return CB_ERR;

	if (!strcmp(cse_regions[bp], "RO"))
		cse_get_bp_entry_range(RO, &start_offset, &end_offset);
	else
		cse_get_bp_entry_range(RW, &start_offset, &end_offset);

	size = end_offset + 1 - start_offset;

	if (rdev_chain(cse_rdev, &cse_region_rdev, start_offset, size))
		return CB_ERR;

	printk(BIOS_DEBUG, "cse_lite: CSE %s  partition: offset = 0x%x, size = 0x%x\n",
			cse_regions[bp], start_offset, size);
	return CB_SUCCESS;
}

static enum cb_err cse_sub_part_get_target_rdev(struct region_device *target_rdev, size_t bp,
						enum bpdt_entry_type type)
{
	struct bpdt_header bpdt_hdr;
	struct region_device cse_rdev;
	struct bpdt_entry bpdt_entries[MAX_SUBPARTS];
	uint8_t i;

	if (cse_locate_area_as_rdev_rw(bp, &cse_rdev) != CB_SUCCESS) {
		printk(BIOS_ERR, "cse_lite: Failed to locate %s in the CSE Region\n",
				cse_regions[bp]);
		return CB_ERR;
	}

	if ((rdev_readat(&cse_rdev, &bpdt_hdr, 0, BPDT_HEADER_SZ)) != BPDT_HEADER_SZ) {
		printk(BIOS_ERR, "cse_lite: Failed to read BPDT header from CSE region\n");
		return CB_ERR;
	}

	if ((rdev_readat(&cse_rdev, bpdt_entries, BPDT_HEADER_SZ,
		(bpdt_hdr.descriptor_count * BPDT_ENTRY_SZ))) !=
		(bpdt_hdr.descriptor_count * BPDT_ENTRY_SZ)) {
		printk(BIOS_ERR, "cse_lite: Failed to read BPDT entries from CSE region\n");
		return CB_ERR;
	}

	/* walk through BPDT entries to identify sub-partition's payload offset and size */
	for (i = 0; i < bpdt_hdr.descriptor_count; i++) {
		if (bpdt_entries[i].type == type) {
			printk(BIOS_INFO, "cse_lite: Sub-partition %s- offset = 0x%x,"
				"size = 0x%x\n", cse_sub_part_str(type), bpdt_entries[i].offset,
					bpdt_entries[i].size);

			if (rdev_chain(target_rdev, &cse_rdev, bpdt_entries[i].offset,
				bpdt_entries[i].size))
				return CB_ERR;
			else
				return CB_SUCCESS;
		}
	}

	printk(BIOS_ERR, "cse_lite: Sub-partition %s is not found\n", cse_sub_part_str(type));
	return CB_ERR;
}

static enum cb_err cse_get_sub_part_fw_version(enum bpdt_entry_type type,
					const struct region_device *rdev,
					struct fw_version *fw_ver)
{
	struct subpart_entry subpart_entry;
	struct subpart_entry_manifest_header man_hdr;

	if ((rdev_readat(rdev, &subpart_entry, SUBPART_HEADER_SZ, SUBPART_ENTRY_SZ))
			!= SUBPART_ENTRY_SZ) {
		printk(BIOS_ERR, "cse_lite: Failed to read %s sub partition entry\n",
				cse_sub_part_str(type));
		return CB_ERR;
	}

	if ((rdev_readat(rdev, &man_hdr, subpart_entry.offset_bytes, SUBPART_MANIFEST_HDR_SZ))
			!= SUBPART_MANIFEST_HDR_SZ) {
		printk(BIOS_ERR, "cse_lite: Failed to read %s Sub part entry #0 manifest\n",
				cse_sub_part_str(type));
		return CB_ERR;
	}

	fw_ver->major = man_hdr.binary_version.major;
	fw_ver->minor = man_hdr.binary_version.minor;
	fw_ver->hotfix = man_hdr.binary_version.hotfix;
	fw_ver->build = man_hdr.binary_version.build;

	return CB_SUCCESS;
}

static void cse_sub_part_get_source_fw_version(void *subpart_cbfs_rw, struct fw_version *fw_ver)
{
	uint8_t *ptr = (uint8_t *)subpart_cbfs_rw;
	struct subpart_entry *subpart_entry;
	struct subpart_entry_manifest_header *man_hdr;

	subpart_entry = (struct subpart_entry *)(ptr + SUBPART_HEADER_SZ);
	man_hdr = (struct subpart_entry_manifest_header *)(ptr + subpart_entry->offset_bytes);

	fw_ver->major = man_hdr->binary_version.major;
	fw_ver->minor = man_hdr->binary_version.minor;
	fw_ver->hotfix = man_hdr->binary_version.hotfix;
	fw_ver->build = man_hdr->binary_version.build;
}

static enum cb_err cse_prep_for_component_update(void)
{
	/*
	 * To set CSE's operation mode to HMRFPO mode:
	 * 1. Ensure CSE to boot from RO(BP1)
	 * 2. Send HMRFPO_ENABLE command to CSE
	 */
	if (cse_boot_to_ro() != CB_SUCCESS)
		return CB_ERR;

	return cse_hmrfpo_enable();
}

static enum csme_failure_reason 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)
{
	if (region_device_sz(target_rdev) < blob_sz) {
		printk(BIOS_ERR, "cse_lite: %s Target sub-partition size: %zx, "
				"smaller than blob size:%zx, abort update\n",
				cse_sub_part_str(type), region_device_sz(target_rdev), blob_sz);
		return CSE_LITE_SKU_SUB_PART_LAYOUT_MISMATCH_ERROR;
	}

	/* Erase CSE Lite sub-partition */
	if (cse_erase_rw_region(target_rdev) != CB_SUCCESS)
		return CSE_LITE_SKU_SUB_PART_UPDATE_FAIL;

	/* Update CSE Lite sub-partition */
	if (cse_copy_rw(target_rdev, (void *)subpart_cbfs_rw, 0, blob_sz) != CB_SUCCESS)
		return CSE_LITE_SKU_SUB_PART_UPDATE_FAIL;

	printk(BIOS_INFO, "cse_lite: CSE %s %s Update successful\n", GET_BP_STR(bp),
			cse_sub_part_str(type));

	return CSE_LITE_SKU_PART_UPDATE_SUCCESS;
}

static enum csme_failure_reason handle_cse_sub_part_fw_update_rv(enum csme_failure_reason rv)
{
	switch (rv) {
	case CSE_LITE_SKU_PART_UPDATE_SUCCESS:
	case CSE_LITE_SKU_SUB_PART_UPDATE_NOT_REQ:
		return rv;
	default:
		cse_trigger_vboot_recovery(rv);
	}
	/* Control never reaches here */
	return rv;
}

static enum csme_failure_reason cse_sub_part_fw_component_update(enum bpdt_entry_type type,
		const char *name)
{
	struct region_device target_rdev;
	struct fw_version target_fw_ver, source_fw_ver;
	enum csme_failure_reason rv;
	size_t size;

	void *subpart_cbfs_rw = cbfs_map(name, &size);
	if (!subpart_cbfs_rw) {
		printk(BIOS_ERR, "cse_lite: Not able to map %s CBFS file\n",
				cse_sub_part_str(type));
		return CSE_LITE_SKU_SUB_PART_BLOB_ACCESS_ERR;
	}

	cse_sub_part_get_source_fw_version(subpart_cbfs_rw, &source_fw_ver);
	printk(BIOS_INFO, "cse_lite: CBFS %s FW Version: %x.%x.%x.%x\n", cse_sub_part_str(type),
			source_fw_ver.major, source_fw_ver.minor, source_fw_ver.hotfix,
			source_fw_ver.build);

	/* Trigger sub-partition update in CSE RO and CSE RW */
	for (size_t bp = 0; bp < ARRAY_SIZE(cse_regions); bp++) {
		if (cse_sub_part_get_target_rdev(&target_rdev, bp, type) != CB_SUCCESS) {
			rv = CSE_LITE_SKU_SUB_PART_ACCESS_ERR;
			goto error_exit;
		}

		if (cse_get_sub_part_fw_version(type, &target_rdev, &target_fw_ver) != CB_SUCCESS) {
			rv = CSE_LITE_SKU_SUB_PART_ACCESS_ERR;
			goto error_exit;
		}

		printk(BIOS_INFO, "cse_lite: %s %s FW Version: %x.%x.%x.%x\n", cse_regions[bp],
				cse_sub_part_str(type), target_fw_ver.major,
				target_fw_ver.minor, target_fw_ver.hotfix, target_fw_ver.build);

		if (!cse_compare_sub_part_version(&target_fw_ver, &source_fw_ver)) {
			printk(BIOS_INFO, "cse_lite: %s %s update is not required\n",
					cse_regions[bp], cse_sub_part_str(type));
			rv = CSE_LITE_SKU_SUB_PART_UPDATE_NOT_REQ;
			continue;
		}

		printk(BIOS_INFO, "CSE %s %s Update initiated\n", GET_BP_STR(bp),
				cse_sub_part_str(type));

		if (cse_prep_for_component_update() != CB_SUCCESS) {
			rv = CSE_LITE_SKU_SUB_PART_ACCESS_ERR;
			goto error_exit;
		}

		rv = cse_sub_part_trigger_update(type, bp, subpart_cbfs_rw,
				size, &target_rdev);

		if (rv != CSE_LITE_SKU_PART_UPDATE_SUCCESS)
			goto error_exit;
	}
error_exit:
	cbfs_unmap(subpart_cbfs_rw);
	return rv;
}

static enum csme_failure_reason cse_sub_part_fw_update(void)
{
	if (skip_cse_sub_part_update()) {
		printk(BIOS_INFO, "CSE Sub-partition update not required\n");
		return CSE_LITE_SKU_SUB_PART_UPDATE_NOT_REQ;
	}

	enum csme_failure_reason rv;
	rv = cse_sub_part_fw_component_update(IOM_FW, CONFIG_SOC_INTEL_CSE_IOM_CBFS_NAME);

	handle_cse_sub_part_fw_update_rv(rv);

	rv = cse_sub_part_fw_component_update(NPHY_FW, CONFIG_SOC_INTEL_CSE_NPHY_CBFS_NAME);

	return handle_cse_sub_part_fw_update_rv(rv);
}

static void do_cse_fw_sync(void)
{
	/*
	 * If system is in recovery mode, skip CSE Lite update if CSE sub-partition update
	 * is not enabled and continue to update CSE sub-partitions.
	 */
	if (vboot_recovery_mode_enabled() && !CONFIG(SOC_INTEL_CSE_SUB_PART_UPDATE)) {
		printk(BIOS_DEBUG, "cse_lite: Skip switching to RW in the recovery path\n");
		return;
	}

	/* If CSE SKU type is not Lite, skip enabling CSE Lite SKU */
	if (!cse_is_hfs3_fw_sku_lite()) {
		printk(BIOS_ERR, "cse_lite: Not a CSE Lite SKU\n");
		return;
	}

	if (cse_get_bp_info() != CB_SUCCESS) {
		printk(BIOS_ERR, "cse_lite: Failed to get CSE boot partition info\n");

		 /* If system is in recovery mode, don't trigger recovery again */
		if (!vboot_recovery_mode_enabled()) {
			cse_trigger_vboot_recovery(CSE_COMMUNICATION_ERROR);
		} else {
			printk(BIOS_ERR, "cse_lite: System is already in Recovery Mode, "
					"so no action\n");
			return;
		}
	}

	/* Store the CSE RW Firmware Version into CBMEM */
	if (CONFIG(SOC_INTEL_STORE_CSE_FW_VERSION))
		cse_store_rw_fw_version();

	/*
	 * If system is in recovery mode, CSE Lite update has to be skipped but CSE
	 * sub-partitions like NPHY and IOM have to be updated. If CSE sub-partition update
	 * fails during recovery, just continue to boot.
	 */
	if (CONFIG(SOC_INTEL_CSE_SUB_PART_UPDATE) && vboot_recovery_mode_enabled()) {
		if (cse_sub_part_fw_update() == CSE_LITE_SKU_PART_UPDATE_SUCCESS) {
			cse_board_reset();
			do_global_reset();
			die("ERROR: GLOBAL RESET Failed to reset the system\n");
		}

		return;
	}

	if (cse_fix_data_failure_err() != CB_SUCCESS)
		cse_trigger_vboot_recovery(CSE_LITE_SKU_DATA_WIPE_ERROR);

	/*
	 * CSE firmware update is skipped if SOC_INTEL_CSE_RW_UPDATE is not defined and
	 * 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 (is_cse_fw_update_enabled()) {
		uint8_t rv;
		rv = cse_fw_update();
		if (rv)
			cse_trigger_vboot_recovery(rv);
	}

	if (CONFIG(SOC_INTEL_CSE_SUB_PART_UPDATE))
		cse_sub_part_fw_update();

	if (!cse_is_rw_bp_status_valid())
		cse_trigger_vboot_recovery(CSE_LITE_SKU_RW_JUMP_ERROR);

	if (cse_boot_to_rw() != CB_SUCCESS) {
		printk(BIOS_ERR, "cse_lite: Failed to switch to RW\n");
		cse_trigger_vboot_recovery(CSE_LITE_SKU_RW_SWITCH_ERROR);
	}
}

void cse_fw_sync(void)
{
	timestamp_add_now(TS_CSE_FW_SYNC_START);
	do_cse_fw_sync();
	timestamp_add_now(TS_CSE_FW_SYNC_END);
}

static enum cb_err send_get_fpt_partition_info_cmd(enum fpt_partition_id id,
	struct fw_version_resp *resp)
{
	enum cse_tx_rx_status ret;
	struct fw_version_msg {
		struct mkhi_hdr hdr;
		enum fpt_partition_id partition_id;
	} __packed msg = {
		.hdr = {
			.group_id = MKHI_GROUP_ID_GEN,
			.command = GEN_GET_IMAGE_FW_VERSION,
		},
		.partition_id = id,
	};

	/*
	 * Prerequisites:
	 * 1) HFSTS1 CWS is Normal
	 * 2) HFSTS1 COM is Normal
	 * 3) Only sent after DID (accomplished by compiling this into ramstage)
	 */

	if (cse_is_hfs1_com_soft_temp_disable() || !cse_is_hfs1_cws_normal() ||
		!cse_is_hfs1_com_normal()) {
		printk(BIOS_ERR,
			"HECI: Prerequisites not met for Get Image Firmware Version command\n");
		return CB_ERR;
	}

	size_t resp_size = sizeof(struct fw_version_resp);
	ret = heci_send_receive(&msg, sizeof(msg), resp, &resp_size, HECI_MKHI_ADDR);

	if (ret || resp->hdr.result) {
		printk(BIOS_ERR, "CSE: Failed to get partition information for %d: 0x%x\n",
			id, resp->hdr.result);
		return CB_ERR;
	}

	return CB_SUCCESS;
}

static enum cb_err cse_get_fpt_partition_info(enum fpt_partition_id id,
		 struct fw_version_resp *resp)
{
	if (vboot_recovery_mode_enabled()) {
		printk(BIOS_WARNING,
			"CSE: Skip sending Get Image Info command during recovery mode!\n");
		return CB_ERR;
	}

	if (id == FPT_PARTITION_NAME_ISHC && !CONFIG(DRIVERS_INTEL_ISH)) {
		printk(BIOS_WARNING, "CSE: Info request denied, no ISH partition\n");
		return CB_ERR;
	}

	return send_get_fpt_partition_info_cmd(id, resp);
}

static bool is_ish_version_valid(struct cse_fw_ish_version_info *version)
{
	const struct fw_version invalid_fw = {0, 0, 0, 0};
	if (!memcmp(&version->cur_ish_fw_version, &invalid_fw, sizeof(struct fw_version)))
		return false;
	return true;
}

/*
 * Helper function to read ISH version from CSE FPT using HECI command.
 *
 * The HECI command only be executed after memory has been initialized.
 * This is because the command relies on resources that are not available
 * until DRAM initialization command has been sent.
 */
static void store_ish_version(void)
{
	if (!ENV_RAMSTAGE)
		return;

	if (vboot_recovery_mode_enabled())
		return;

	struct cse_specific_info *cse_info_in_cbmem = cbmem_find(CBMEM_ID_CSE_INFO);
	if (cse_info_in_cbmem == NULL)
		return;

	struct cse_specific_info cse_info_in_cmos;
	cmos_read_fw_partition_info(&cse_info_in_cmos);

	struct cse_fw_partition_info *cbmem_version = &(cse_info_in_cbmem->cse_fwp_version);
	struct cse_fw_partition_info *cmos_version = &(cse_info_in_cmos.cse_fwp_version);

	/* Get current cse firmware state */
	enum cse_fw_state fw_state = get_cse_state(
		 &(cbmem_version->cur_cse_fw_version),
		 &(cmos_version->ish_partition_info.prev_cse_fw_version),
		 &(cbmem_version->ish_partition_info.prev_cse_fw_version));

	if (fw_state == CSE_FW_WARM_BOOT) {
		return;
	} else {
		if (fw_state == CSE_FW_COLD_BOOT &&
			 is_ish_version_valid(&(cmos_version->ish_partition_info))) {
			/* CMOS data is persistent across cold boots */
			memcpy(&(cse_info_in_cbmem->cse_fwp_version.ish_partition_info),
				&(cse_info_in_cmos.cse_fwp_version.ish_partition_info),
				sizeof(struct cse_fw_ish_version_info));
			store_cse_info_crc(cse_info_in_cbmem);
		} else {
			/*
			 * Current running CSE version is different than previous stored CSE version
			 * which could be due to CSE update or rollback, hence, need to send ISHC
			 * partition info cmd to know the currently running ISH version.
			 */
			struct fw_version_resp resp;
			if (cse_get_fpt_partition_info(FPT_PARTITION_NAME_ISHC,
				 &resp) == CB_SUCCESS) {
				/* Update stored CSE version with current cse version */
				memcpy(&(cbmem_version->ish_partition_info.prev_cse_fw_version),
				 &(cbmem_version->cur_cse_fw_version),  sizeof(struct fw_version));

				/* Retrieve and update current ish version */
				memcpy(&(cbmem_version->ish_partition_info.cur_ish_fw_version),
				 &(resp.manifest_data.version), sizeof(struct fw_version));

				/* Update the CRC */
				store_cse_info_crc(cse_info_in_cbmem);

				/* Update CMOS with current CSE FPT versions.*/
				cmos_write_fw_partition_info(cse_info_in_cbmem);
			}
		}
	}
}

static void ramstage_cse_misc_ops(void *unused)
{
	if (acpi_get_sleep_type() == ACPI_S3)
		return;

	if (CONFIG(SOC_INTEL_CSE_LITE_SYNC_IN_RAMSTAGE))
		cse_fw_sync();

	/*
	 * Store the ISH RW Firmware Version into CBMEM if ISH partition
	 * is available
	 */
	if (soc_is_ish_partition_enabled())
		store_ish_version();
}

BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, ramstage_cse_misc_ops, NULL);
