[Skiboot] [PATCH] core: hostservices: Remove redundant special wakeup code

Shilpasri G Bhat shilpa.bhat at linux.vnet.ibm.com
Wed Jan 17 15:20:24 AEDT 2018


Use the generic dctl_{set/clear}_special_wakeup() in hostservices to
assert and de-assert core special wakeup for P8 and remove the
duplicated code.

Signed-off-by: Shilpasri G Bhat <shilpa.bhat at linux.vnet.ibm.com>
---
 core/hostservices.c | 164 +---------------------------------------------------
 1 file changed, 3 insertions(+), 161 deletions(-)

diff --git a/core/hostservices.c b/core/hostservices.c
index 20334b2..c37bf2f 100644
--- a/core/hostservices.c
+++ b/core/hostservices.c
@@ -545,162 +545,8 @@ static void hservice_nanosleep(uint64_t i_seconds, uint64_t i_nano_seconds)
 	nanosleep_nopoll(&ts, NULL);
 }
 
-static int hservice_set_special_wakeup(struct cpu_thread *cpu)
-{
-	uint64_t val, core_id, poll_target, stamp;
-	int rc;
-
-	/*
-	 * Note: HWP checks for checkstops, but I assume we don't need to
-	 * as we wouldn't be running if one was present
-	 */
-
-	/* Grab core ID once */
-	core_id = pir_to_core_id(cpu->pir);
-
-	/*
-	 * The original HWp reads the XSCOM first but ignores the result
-	 * and error, let's do the same until I know for sure that is
-	 * not necessary
-	 */
-	xscom_read(cpu->chip_id,
-		   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
-		   &val);
-
-	/* Then we write special wakeup */
-	rc = xscom_write(cpu->chip_id,
-			 XSCOM_ADDR_P8_EX_SLAVE(core_id,
-						EX_PM_SPECIAL_WAKEUP_PHYP),
-			 PPC_BIT(0));
-	if (rc) {
-		prerror("HBRT: XSCOM error %d asserting special"
-			" wakeup on 0x%x\n", rc, cpu->pir);
-		return rc;
-	}
-
-	/*
-	 * HWP uses the history for Perf register here, dunno why it uses
-	 * that one instead of the pHyp one, maybe to avoid clobbering it...
-	 *
-	 * In any case, it does that to check for run/nap vs.sleep/winkle/other
-	 * to decide whether to poll on checkstop or not. Since we don't deal
-	 * with checkstop conditions here, we ignore that part.
-	 */
-
-	/*
-	 * Now poll for completion of special wakeup. The HWP is nasty here,
-	 * it will poll at 5ms intervals for up to 200ms. This is not quite
-	 * acceptable for us at runtime, at least not until we have the
-	 * ability to "context switch" HBRT. In practice, because we don't
-	 * winkle, it will never take that long, so we increase the polling
-	 * frequency to 1us per poll. However we do have to keep the same
-	 * timeout.
-	 *
-	 * We don't use time_wait_ms() either for now as we don't want to
-	 * poll the FSP here.
-	 */
-	stamp = mftb();
-	poll_target = stamp + msecs_to_tb(200);
-	val = 0;
-	while (!(val & EX_PM_GP0_SPECIAL_WAKEUP_DONE)) {
-		/* Wait 1 us */
-		hservice_nanosleep(0, 1000);
-
-		/* Read PM state */
-		rc = xscom_read(cpu->chip_id,
-				XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_GP0),
-				&val);
-		if (rc) {
-			prerror("HBRT: XSCOM error %d reading PM state on"
-				" 0x%x\n", rc, cpu->pir);
-			return rc;
-		}
-		/* Check timeout */
-		if (mftb() > poll_target)
-			break;
-	}
-
-	/* Success ? */
-	if (val & EX_PM_GP0_SPECIAL_WAKEUP_DONE) {
-		uint64_t now = mftb();
-		prlog(PR_TRACE, "HBRT: Special wakeup complete after %ld us\n",
-		      tb_to_usecs(now - stamp));
-		return 0;
-	}
-
-	/*
-	 * We timed out ...
-	 *
-	 * HWP has a complex workaround for HW255321 which affects
-	 * Murano DD1 and Venice DD1. Ignore that for now
-	 *
-	 * Instead we just dump some XSCOMs for error logging
-	 */
-	prerror("HBRT: Timeout on special wakeup of 0x%0x\n", cpu->pir);
-	prerror("HBRT:      PM0 = 0x%016llx\n", val);
-	val = -1;
-	xscom_read(cpu->chip_id,
-		   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
-		   &val);
-	prerror("HBRT: SPC_WKUP = 0x%016llx\n", val);
-	val = -1;
-	xscom_read(cpu->chip_id,
-		   XSCOM_ADDR_P8_EX_SLAVE(core_id,
-					  EX_PM_IDLE_STATE_HISTORY_PHYP),
-		   &val);
-	prerror("HBRT:  HISTORY = 0x%016llx\n", val);
-
-	return OPAL_HARDWARE;
-}
-
-static int hservice_clr_special_wakeup(struct cpu_thread *cpu)
-{
-	uint64_t val, core_id;
-	int rc;
-
-	/*
-	 * Note: HWP checks for checkstops, but I assume we don't need to
-	 * as we wouldn't be running if one was present
-	 */
-
-	/* Grab core ID once */
-	core_id = pir_to_core_id(cpu->pir);
-
-	/*
-	 * The original HWp reads the XSCOM first but ignores the result
-	 * and error, let's do the same until I know for sure that is
-	 * not necessary
-	 */
-	xscom_read(cpu->chip_id,
-		   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
-		   &val);
-
-	/* Then we write special wakeup */
-	rc = xscom_write(cpu->chip_id,
-			 XSCOM_ADDR_P8_EX_SLAVE(core_id,
-						EX_PM_SPECIAL_WAKEUP_PHYP), 0);
-	if (rc) {
-		prerror("HBRT: XSCOM error %d deasserting"
-			" special wakeup on 0x%x\n", rc, cpu->pir);
-		return rc;
-	}
-
-	/*
-	 * The original HWp reads the XSCOM again with the comment
-	 * "This puts an inherent delay in the propagation of the reset
-	 * transition"
-	 */
-	xscom_read(cpu->chip_id,
-		   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
-		   &val);
-
-	return 0;
-}
-
 int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
 {
-	int (*set_wakeup)(struct cpu_thread *cpu);
-	int (*clear_wakeup)(struct cpu_thread *cpu);
 	struct cpu_thread *cpu;
 	int rc = OPAL_SUCCESS;
 
@@ -712,14 +558,10 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
 		 */
 		i_core &= 0x0fffffff;
 		i_core <<= 3;
-		set_wakeup = hservice_set_special_wakeup;
-		clear_wakeup = hservice_clr_special_wakeup;
 		break;
 	case proc_gen_p9:
 		i_core &= SPR_PIR_P9_MASK;
 		i_core <<= 2;
-		set_wakeup = dctl_set_special_wakeup;
-		clear_wakeup = dctl_clear_special_wakeup;
 		break;
 	default:
 		return OPAL_UNSUPPORTED;
@@ -734,7 +576,7 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
 		prlog(PR_DEBUG, "HBRT: Special wakeup assert for core 0x%x,"
 		      " count=%d\n", i_core, cpu->hbrt_spec_wakeup);
 		if (cpu->hbrt_spec_wakeup == 0)
-			rc = set_wakeup(cpu);
+			rc = dctl_set_special_wakeup(cpu);
 		if (rc == 0)
 			cpu->hbrt_spec_wakeup++;
 		return rc;
@@ -753,7 +595,7 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
 		/* What to do with count on errors ? */
 		cpu->hbrt_spec_wakeup--;
 		if (cpu->hbrt_spec_wakeup == 0)
-			rc = clear_wakeup(cpu);
+			rc = dctl_clear_special_wakeup(cpu);
 		return rc;
 	case 2: /* Clear all special wakeups */
 		prlog(PR_DEBUG, "HBRT: Special wakeup release for all cores\n");
@@ -761,7 +603,7 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
 			if (cpu->hbrt_spec_wakeup) {
 				cpu->hbrt_spec_wakeup = 0;
 				/* What to do on errors ? */
-				clear_wakeup(cpu);
+				dctl_clear_special_wakeup(cpu);
 			}
 		}
 		return OPAL_SUCCESS;
-- 
1.8.3.1



More information about the Skiboot mailing list