soc/intel/common/block/cse: Modify handling of HMRFPO_ENABLE command

Below changes are done:
1. Allow execution of HMRFPO_ENABLE command if CSE meets below
   prerequisites:
    - Current operation mode(COM) is Normal and Curret working state(CWS)
      is Normal.
    -(or) COM is Soft Temp Disable and CWS is Normal if ME's
      Firmware SKU is Custom.
2. Check response status.
3. Add documentation for send_hmrfpo_enable_msg().
4. Rename padding field of hmrfpo_enable_resp to reserved.

The HMRFPO (Host ME Region Flash Protection Override) mode prevents CSE to
execute SPI I/O cycles to CSE region, and unlocks the CSE region to perform
updates to it. This command is only valid before EOP(End of Post).

For Custom SKU, follow below procedure to place CSE in HMRFPO mode:
  1. Ensure CSE boots from BP1. When CSE boots from BP1, it will have
     opmode Temp Disable Mode.
  2. Send HMRFPO_ENABLE command to CSE. Then, CSE enters HMRFPO mode.

CSE Firmware Custom SKU Image Layout:
         = [RO] + [RW + DATA PART] = [BP1] + [BP2 + DATA PART]

Here, BP1 will have reduced functionality of BP2, and the BP1 will be
CSE's RO partition and [BP2 + DATA PART] together will represent
CSE's RW partition. CSE can boot from either BP1(RO) or BP2(RW).

CSE Image Layout in Consumer SKU: BP2 + BP3 + DATA PART

TEST=Verfied on hatch board.

Change-Id: I7c87998fa105947e5ba4638a8e68625e46703448
Signed-off-by: Sridhar Siricilla <sridhar.siricilla@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/37283
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c
index c9712dbb..041656a 100644
--- a/src/soc/intel/common/block/cse/cse.c
+++ b/src/soc/intel/common/block/cse/cse.c
@@ -650,6 +650,26 @@
 	return status;
 }
 
+static bool cse_is_hmrfpo_enable_allowed(void)
+{
+	/*
+	 * Allow sending HMRFPO ENABLE command only if:
+	 *  - CSE's current working state is Normal and current operation mode is Normal
+	 *  - (or) cse's current working state is normal and current operation mode is
+	 *    Soft Temp Disable if CSE's Firmware SKU is Custom
+	 */
+	if (!cse_is_hfs1_cws_normal())
+		return false;
+
+	if (cse_is_hfs1_com_normal())
+		return true;
+
+	if (cse_is_hfs3_fw_sku_custom() && cse_is_hfs1_com_soft_temp_disable())
+		return true;
+
+	return false;
+}
+
 /* Sends HMRFPO Enable command to CSE */
 int cse_hmrfpo_enable(void)
 {
@@ -675,36 +695,34 @@
 		/* Length of factory data area, not relevant for client SKUs */
 		uint32_t fct_limit;
 		uint8_t status;
-		uint8_t padding[3];
+		uint8_t reserved[3];
 	} __packed;
 
 	struct hmrfpo_enable_resp resp;
 	size_t resp_size = sizeof(struct hmrfpo_enable_resp);
 
 	printk(BIOS_DEBUG, "HECI: Send HMRFPO Enable Command\n");
-	/*
-	 * This command can be run only if:
-	 * - Working state is normal and
-	 * - Operation mode is normal or temporary disable mode.
-	 */
-	if (!cse_is_hfs1_cws_normal() ||
-		(!cse_is_hfs1_com_normal() && !cse_is_hfs1_com_soft_temp_disable())) {
-		printk(BIOS_ERR, "HECI: ME not in required Mode\n");
-		goto failed;
+
+	if (!cse_is_hmrfpo_enable_allowed()) {
+		printk(BIOS_ERR, "HECI: CSE does not meet required prerequisites\n");
+		return 0;
 	}
 
 	if (!heci_send_receive(&msg, sizeof(struct hmrfpo_enable_msg),
 				&resp, &resp_size))
-		goto failed;
+		return 0;
 
 	if (resp.hdr.result) {
 		printk(BIOS_ERR, "HECI: Resp Failed:%d\n", resp.hdr.result);
-		goto failed;
+		return 0;
 	}
-	return 1;
 
-failed:
-	return 0;
+	if (resp.status) {
+		printk(BIOS_ERR, "HECI: HMRFPO_Enable Failed (resp status: %d)\n", resp.status);
+		return 0;
+	}
+
+	return 1;
 }
 
 /*