soc/intel/p2sb: Refactor `p2sb_execute_sideband_access` function

This patch refactors p2sb_execute_sideband_access() to be able to
handle SBI operations in both SMM and non-SMM scenarios.

Prior to FSP-S operation being done, the IOE P2SB device will be
visible on the PCI bus hence, performing the SBI operation using IOE
P2SB doesn't involve unhide/hide operation.

Post FSP-S, the IOE P2SB device is hidden.

Additionally, SBI operations can't be performed as is. The only
possible way to send SBI is inside SMM mode and to do that, coreboot
needs to unhide the P2SB device prior to sending the SBI and hide
it post sending SBI.

As a result, the p2sb_execute_sideband_access() function has been
refactored to manage these cases seamlessly without users of the
p2sb_execute_sideband_access() actually being bothered about the
calling mode.

BUG=b:239806774
TEST=Able to perform p2sb_execute_sideband_access() function call in
both SMM and non-SMM mode without any hang/die.

Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: Iafebd5190deb50fd95382f17bf0248fcbfb23cb8
Reviewed-on: https://review.coreboot.org/c/coreboot/+/66950
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
diff --git a/src/soc/intel/common/block/p2sb/p2sblib.c b/src/soc/intel/common/block/p2sb/p2sblib.c
index e1a5bc2..537f388 100644
--- a/src/soc/intel/common/block/p2sb/p2sblib.c
+++ b/src/soc/intel/common/block/p2sb/p2sblib.c
@@ -63,7 +63,7 @@
 				"Unable to hide the P2SB device!\n");
 }
 
-static void p2sb_execute_sideband_access(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
+static void p2sb_send_sideband_msg(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
 						uint16_t reg, uint32_t *data)
 {
 	struct pcr_sbi_msg msg = {
@@ -78,17 +78,40 @@
 	uint8_t response;
 	int status;
 
-	/* Unhide the P2SB device */
-	p2sb_dev_unhide(dev);
-
 	status = pcr_execute_sideband_msg(dev, &msg, data, &response);
 	if (status || response)
 		printk(BIOS_ERR, "Fail to execute p2sb sideband access\n");
+}
+
+static void p2sb_execute_sbi_in_smm(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
+						uint16_t reg, uint32_t *data)
+{
+	/* Unhide the P2SB device */
+	p2sb_dev_unhide(dev);
+
+	p2sb_send_sideband_msg(dev, cmd, pid, reg, data);
 
 	/* Hide the P2SB device */
 	p2sb_dev_hide(dev);
 }
 
+static void p2sb_execute_sideband_access(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
+						uint16_t reg, uint32_t *data)
+{
+	if (ENV_SMM)
+		/*
+		 * FSP-S will hide the P2SB device. With the device hidden, we will not be
+		 * able to send the sideband interface message. Therefore, we need to unhide
+		 * the P2SB device which can only be done in SMM requiring that this
+		 * function is called from SMM.
+		 */
+		p2sb_execute_sbi_in_smm(dev, cmd, pid, reg, data);
+	else if (!p2sb_dev_is_hidden(dev))
+		p2sb_send_sideband_msg(dev, cmd, pid, reg, data);
+	else
+		printk(BIOS_WARNING, "Error: P2SB must be hidden, try calling from SMM!\n");
+}
+
 uint32_t p2sb_dev_sbi_read(pci_devfn_t dev, uint8_t pid, uint16_t reg)
 {
 	uint32_t val = 0;