summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYue Du <daviddu@us.ibm.com>2017-05-30 15:30:48 -0500
committerJoshua Hunsberger <jahunsbe@us.ibm.com>2017-10-23 17:45:19 -0500
commitb03e899df8aa67236c6c54a4295911c9366c74cd (patch)
tree07d18daa2cd9cb5117e49a615b24b7c5cd7ce5a9
parent91f5606901071c52b34b38aa14ce83decf41ae90 (diff)
downloadtalos-hcode-b03e899df8aa67236c6c54a4295911c9366c74cd.tar.gz
talos-hcode-b03e899df8aa67236c6c54a4295911c9366c74cd.zip
STOP: Fix STOP1 with Powermixer
Change-Id: I42a9cbaab372506de09be183448bc3fcb5362c2c Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41139 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Juan R. Medina <jrmedina@us.ibm.com> Reviewed-by: Brian T. Vanderpool <vanderp@us.ibm.com> Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
-rw-r--r--import/chips/p9/common/pmlib/include/cmehw_common.h3
-rwxr-xr-ximport/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c81
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c19
3 files changed, 60 insertions, 43 deletions
diff --git a/import/chips/p9/common/pmlib/include/cmehw_common.h b/import/chips/p9/common/pmlib/include/cmehw_common.h
index e7a002b4..4b692087 100644
--- a/import/chips/p9/common/pmlib/include/cmehw_common.h
+++ b/import/chips/p9/common/pmlib/include/cmehw_common.h
@@ -59,6 +59,9 @@ enum CME_BCEBAR_INDEXES
#define CME_SCOM_ADDR(addr, core, op) (addr | (core << 22) | (op << 20))
+#define CME_PUTSCOM_NOP(addr, core, data) \
+ putscom_norc(CME_SCOM_ADDR(addr, core, CME_SCOM_NOP), data);
+
#if defined(USE_CME_QUEUED_SCOM)
#define CME_GETSCOM(addr, core, scom_op, data) \
PPE_LVD(CME_SCOM_ADDR(addr, core, scom_op), data);
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c
index a113da00..8ad8acf8 100755
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c
@@ -362,6 +362,30 @@ p9_cme_stop_entry()
// Mark core as to be stopped
G_cme_stop_record.core_running &= ~core;
+ // Request PCB Mux
+
+#if HW405292_NDD1_PCBMUX_SAVIOR
+
+ p9_cme_pcbmux_savior_prologue(core);
+
+#endif
+
+ PK_TRACE("Request PCB mux via SICR[10/11]");
+ out32(CME_LCL_SICR_OR, core << SHIFT32(11));
+
+ // Poll Infinitely for PCB Mux Grant
+ while((core & (in32(CME_LCL_SISR) >> SHIFT32(11))) != core);
+
+ PK_TRACE("PCB Mux Granted on Core[%d]", core);
+
+#if HW405292_NDD1_PCBMUX_SAVIOR
+
+ p9_cme_pcbmux_savior_epilogue(core);
+
+#endif
+
+ // Stop 1
+
if(core_stop1)
{
PK_TRACE_DBG("Check: core[%d] core_stop1[%d]", core, core_stop1);
@@ -387,6 +411,24 @@ p9_cme_stop_entry()
CME_PUTSCOM(PPM_SSHSRC, core_stop1, scom_data.value);
*/
+ core = core & ~core_stop1;
+
+ if (!core)
+ {
+ // not catchup or catchup with stop2, terminates
+ entry_ongoing = 0;
+
+ // otherwise, go back to origin core and continue
+ if (origin_core && (origin_level > STOP_LEVEL_2))
+ {
+ core = origin_core;
+ target_level = origin_level;
+ entry_ongoing = 1;
+ }
+
+ break;
+ }
+
#else
// Nap should be done by hardware when auto_stop1 is enabled
@@ -398,42 +440,6 @@ p9_cme_stop_entry()
}
-
-#if HW405292_NDD1_PCBMUX_SAVIOR
-
- p9_cme_pcbmux_savior_prologue(core);
-
-#endif
-
- PK_TRACE("Request PCB mux via SICR[10/11]");
- out32(CME_LCL_SICR_OR, core << SHIFT32(11));
-
- // Poll Infinitely for PCB Mux Grant
- while((core & (in32(CME_LCL_SISR) >> SHIFT32(11))) != core);
-
- PK_TRACE("PCB Mux Granted on Core[%d]", core);
-
-#if HW405292_NDD1_PCBMUX_SAVIOR
-
- p9_cme_pcbmux_savior_epilogue(core);
-
-#endif
-
-#if HW386841_NDD1_DSL_STOP1_FIX
-
- // check target after getting PCBMUX for Stop1 Workaround
- if (core_stop1)
- {
- core = core & ~core_stop1;
-
- if (!core)
- {
- break;
- }
- }
-
-#endif
-
//----------------------------------------------------------------------
PK_TRACE("+++++ +++++ STOP LEVEL 2 ENTRY +++++ +++++");
//----------------------------------------------------------------------
@@ -747,6 +753,9 @@ p9_cme_stop_entry()
PK_TRACE("Drop sdis_n(flushing LCBES condition) via CPLT_CONF0[34]");
CME_PUTSCOM(C_CPLT_CONF0_CLEAR, core, BIT64(34));
+ // Allow queued scoms to complete to Core EPS before switching to Core PPM
+ sync();
+
PK_TRACE("Copy PECE CME sample to PPM Shadow via PECES");
if (core & CME_MASK_C0)
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c
index 5cfe3d16..87692bf2 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c
@@ -34,13 +34,15 @@ void
p9_cme_stop_pcwu_handler(void* arg, PkIrqId irq)
{
MARK_TRAP(STOP_PCWU_HANDLER)
- PK_TRACE_INF("PCWU Handler Trigger %d", irq);
+ PkMachineContext ctx;
uint32_t core_mask = 0;
uint32_t core = (in32(CME_LCL_EISR) & BITS32(12, 2)) >> SHIFT32(13);
data64_t scom_data = {0};
ppm_pig_t pig = {0};
+ PK_TRACE_INF("PCWU Handler Trigger %d Level %d", irq, core);
+
for (core_mask = 2; core_mask; core_mask--)
{
if (core & core_mask)
@@ -55,11 +57,11 @@ p9_cme_stop_pcwu_handler(void* arg, PkIrqId irq)
{
pig.fields.req_intr_type = PIG_TYPE2;
pig.fields.req_intr_payload = 0x400;
- CME_PUTSCOM(PPM_PIG, core_mask, pig.value);
+ CME_PUTSCOM_NOP(PPM_PIG, core_mask, pig.value);
}
// block pc for stop8,11 or stop5 as pig sent
- out32(CME_LCL_EIMR_OR, core_mask << SHIFT32(13));
+ g_eimr_override |= (core_mask << SHIFT32(13));
G_cme_stop_record.core_blockpc |= core_mask;
core = core - core_mask;
}
@@ -72,6 +74,10 @@ p9_cme_stop_pcwu_handler(void* arg, PkIrqId irq)
out32(CME_LCL_EIMR_OR, BITS32(12, 6) | BITS32(20, 2));
pk_semaphore_post((PkSemaphore*)arg);
}
+ else
+ {
+ pk_irq_vec_restore(&ctx);
+ }
}
@@ -87,7 +93,6 @@ void
p9_cme_stop_spwu_handler(void* arg, PkIrqId irq)
{
MARK_TRAP(STOP_SPWU_HANDLER)
- //PK_TRACE_INF("SPWU Handler");
PkMachineContext ctx;
int sem_post = 0;
@@ -200,12 +205,12 @@ p9_cme_stop_db2_handler(void* arg, PkIrqId irq)
// read and clear doorbell
uint32_t core = (in32(CME_LCL_EISR) & BITS32(18, 2)) >> SHIFT32(19);
- CME_PUTSCOM(CPPM_CMEDB2, core, 0);
- G_cme_stop_record.core_blockpc &= ~core;
+ CME_PUTSCOM_NOP(CPPM_CMEDB2, core, 0);
// unmask pc interrupt pending to wakeup that is still pending
core &= (~(G_cme_stop_record.core_running));
- out32(CME_LCL_EIMR_CLR, core << SHIFT32(13));
+ g_eimr_override &= ~(core << SHIFT32(13));
+ G_cme_stop_record.core_blockpc &= ~core;
pk_irq_vec_restore(&ctx);
}
OpenPOWER on IntegriCloud