[Skiboot] [PATCH V4 2/4] core/direct-controls: wait for core special wkup bit cleared

Shilpasri G Bhat shilpa.bhat at linux.vnet.ibm.com
Mon Nov 20 17:10:36 AEDT 2017


From: Robert Lippert <rlippert at google.com>

When clearing special wakeup bit on a core, wait until the
bit is actually cleared by the hardware in the status register
until returning success.

This may help avoid issues with back-to-back reads where the
special wakeup request is cleared but the firmware is still
processing the request and the next attempt to set the bit
reads an immediate success from the previous operation.

Change-Id: I86ec8cbbbddd1a5724f451244907693bc09e01ea
Signed-off-by: Robert Lippert <rlippert at google.com>
---
 core/direct-controls.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/core/direct-controls.c b/core/direct-controls.c
index fcb9350..0ed00c1 100644
--- a/core/direct-controls.c
+++ b/core/direct-controls.c
@@ -95,8 +95,12 @@ static int p9_core_clear_special_wakeup(struct cpu_thread *cpu)
 	uint32_t chip_id = pir_to_chip_id(cpu->pir);
 	uint32_t core_id = pir_to_core_id(cpu->pir);
 	uint32_t swake_addr;
+	uint32_t sshhyp_addr;
+	uint64_t val;
+	int i;
 
 	swake_addr = XSCOM_ADDR_P9_EC_SLAVE(core_id, EC_PPM_SPECIAL_WKUP_HYP);
+	sshhyp_addr = XSCOM_ADDR_P9_EC_SLAVE(core_id, P9_EC_PPM_SSHHYP);
 
 	/*
 	 * De-assert special wakeup after a small delay.
@@ -110,8 +114,25 @@ static int p9_core_clear_special_wakeup(struct cpu_thread *cpu)
 				chip_id, core_id);
 		return OPAL_HARDWARE;
 	}
+	time_wait_us(1);
 
-	return OPAL_SUCCESS;
+	for (i = 0; i < P9_SPWKUP_TIMEOUT/P9_SPWKUP_POLL_INTERVAL; i++) {
+		if (xscom_read(chip_id, sshhyp_addr, &val)) {
+			prlog(PR_ERR, "Could not clear special wakeup on %u:%u:"
+					" Unable to read PPM_SSHHYP.\n",
+					chip_id, core_id);
+			return OPAL_HARDWARE;
+		}
+		if (!(val & P9_SPECIAL_WKUP_DONE))
+			return 0;
+
+		time_wait_us(P9_SPWKUP_POLL_INTERVAL);
+	}
+
+	prlog(PR_ERR, "Could not clear special wakeup on %u:%u:"
+			" timeout waiting for clear of SPECIAL_WKUP_DONE.\n",
+			chip_id, core_id);
+	return OPAL_HARDWARE;
 }
 
 static int p9_thread_quiesced(struct cpu_thread *cpu)
-- 
1.8.3.1



More information about the Skiboot mailing list