summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYue Du <daviddu@us.ibm.com>2018-08-29 22:24:08 -0500
committerhostboot <hostboot@us.ibm.com>2019-04-09 10:37:45 -0500
commitf3d82eaa4d8c8181bb2f13b47f6ae67c1e553c1d (patch)
treeb443c04d55c4efe50b0f2249d208ebd1cdae60d3
parent0068bf4a881f3732a01851f96ce764af0b9b404c (diff)
downloadtalos-hcode-f3d82eaa4d8c8181bb2f13b47f6ae67c1e553c1d.zip
talos-hcode-f3d82eaa4d8c8181bb2f13b47f6ae67c1e553c1d.tar.gz
Self Save: Added support for SPR self save in CME hcode(func ver)
Key_Cronus_Test=PM_REGRESS Change-Id: I890e2f8ee2fc50214ad84a37ff8098807fe6cd60 CQ: SW454956 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/65480 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com> Dev-Ready: Gregory S. Still <stillgs@us.ibm.com> Reviewed-by: Gregory S. Still <stillgs@us.ibm.com> Reviewed-by: YUE DU <daviddu@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h11
-rwxr-xr-ximport/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c90
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c395
-rw-r--r--import/chips/p9/procedures/utils/stopreg/selfRest.list2
4 files changed, 306 insertions, 192 deletions
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h
index b7efe2f..c42ebef 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HCODE Project */
/* */
-/* COPYRIGHT 2015,2018 */
+/* COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -235,6 +235,12 @@ enum CME_STOP_SUSPEND_BLOCK
STOP_SUSPEND_SELECT = 0x1 //0bZxx1 for SUSPEND, 0bZxx0 for BLOCK
};
+enum SPR_ACTN
+{
+ SPR_SELF_SAVE = 0x00,
+ SPR_SELF_RESTORE = 0x01,
+};
+
enum CME_SCOM_RESTORE_CONST
{
@@ -320,6 +326,9 @@ void p9_cme_core_livelock_buster();
void p9_cme_stop_entry();
void p9_cme_stop_exit();
+void p9_cme_stop_self_execute(uint32_t, uint32_t);
+void p9_cme_stop_self_cleanup(uint32_t);
+
// CME STOP Interrupt Handlers
void p9_cme_stop_enter_handler(void);
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 15d45bd..70ed76c 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
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HCODE Project */
/* */
-/* COPYRIGHT 2015,2018 */
+/* COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -50,6 +50,7 @@
extern CmeStopRecord G_cme_stop_record;
extern CmeRecord G_cme_record;
+extern uint64_t G_spattn_mask;
#if NIMBUS_DD_LEVEL != 10
@@ -242,6 +243,10 @@ p9_cme_stop_entry()
uint32_t core_mask = 0;
uint32_t core_raw = 0;
uint32_t core = 0;
+#if SMF_SUPPORT_ENABLE
+ uint32_t core_spattn = 0;
+ uint32_t self_save_core = 0;
+#endif
uint32_t thread = 0;
uint32_t pscrs = 0;
uint32_t no_state_loss = 0;
@@ -580,6 +585,67 @@ p9_cme_stop_entry()
#endif
+#if SMF_SUPPORT_ENABLE
+
+ if (G_cme_stop_record.req_level[0] >= STOP_LEVEL_4)
+ {
+ self_save_core |= CME_MASK_C0;
+ }
+
+ if (G_cme_stop_record.req_level[1] >= STOP_LEVEL_4)
+ {
+ self_save_core |= CME_MASK_C1;
+ }
+
+ self_save_core = self_save_core & core;
+
+ if ( self_save_core )
+ {
+
+ p9_cme_stop_self_execute(self_save_core, SPR_SELF_SAVE);
+
+ PK_TRACE("Poll for core stop again(pm_active=1)");
+
+ while((~(in32(G_CME_LCL_EINR))) & (self_save_core << SHIFT32(21)))
+ {
+ core_spattn = (in32_sh(CME_LCL_SISR) >> SHIFT64SH(33)) & self_save_core;
+
+ if (core_spattn)
+ {
+ PK_TRACE_ERR("ERROR: Core[%d] Special Attention Detected. Gard Core!", core_spattn);
+ CME_STOP_CORE_ERROR_HANDLER(self_save_core, core_spattn, CME_STOP_EXIT_SELF_RES_SPATTN);
+
+ PK_TRACE("Release PCB Mux back on Core via SICR[10/11]");
+ out32(G_CME_LCL_SICR_CLR, core_spattn << SHIFT32(11));
+
+ while((core_spattn & ~(in32(G_CME_LCL_SISR) >> SHIFT32(11))) != core_spattn);
+
+ PK_TRACE("PCB Mux Released on Core[%d]", core_spattn);
+ }
+
+ if (!self_save_core)
+ {
+
+#if NIMBUS_DD_LEVEL == 20 || DISABLE_CME_DUAL_CAST == 1
+
+ continue;
+
+#else
+
+ return;
+
+#endif
+
+ }
+ }
+
+ PK_TRACE("SF.RS: Self Save Completed, Core Stopped Again(pm_exit=0/pm_active=1)");
+
+ p9_cme_stop_self_cleanup(self_save_core);
+
+ }// if self_save_core
+
+#endif
// ---------------------------------
// Permanent workaround for HW407385
@@ -1259,18 +1325,20 @@ p9_cme_stop_entry()
MARK_TRAP(SE_IS0_BEGIN)
//===========================
-#if !SKIP_ABORT
+ /*** DISABLE STOP4 to STOP2 abort due to UV mode incorrectly reached on such case ***
+ #if !SKIP_ABORT
- core_wakeup = core & (~G_cme_stop_record.core_blockwu);
- out32(G_CME_LCL_EIMR_CLR, (core_wakeup << SHIFT32(13)) |
- (core_wakeup << SHIFT32(15)) |
- (core_wakeup << SHIFT32(17)));
- sync();
- wrteei(0);
- out32(G_CME_LCL_EIMR_OR, BITS32(10, 12));
- wrteei(1);
+ core_wakeup = core & (~G_cme_stop_record.core_blockwu);
+ out32(G_CME_LCL_EIMR_CLR, (core_wakeup << SHIFT32(13)) |
+ (core_wakeup << SHIFT32(15)) |
+ (core_wakeup << SHIFT32(17)));
+ sync();
+ wrteei(0);
+ out32(G_CME_LCL_EIMR_OR, BITS32(10, 12));
+ wrteei(1);
-#endif
+ #endif
+ */
//===================
MARK_TRAP(SE_IS0_END)
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c
index 9fbac71..b83624e 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HCODE Project */
/* */
-/* COPYRIGHT 2015,2018 */
+/* COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,6 +46,7 @@
extern CmeStopRecord G_cme_stop_record;
extern CmeRecord G_cme_record;
+uint64_t G_spattn_mask = 0;
#if HW386841_NDD1_DSL_STOP1_FIX
@@ -511,7 +512,6 @@ p9_cme_stop_exit()
uint32_t core = 0;
uint32_t core_mask = 0;
uint32_t core_spattn = 0;
- uint64_t spattn_mask = 0;
data64_t scom_data = {0};
#if !SPWU_AUTO
uint32_t spwu_stop = 0;
@@ -1052,271 +1052,308 @@ p9_cme_stop_exit()
#if !SKIP_SELF_RESTORE
- PK_TRACE("Assert block interrupt to PC via SICR[2/3]");
- out32(G_CME_LCL_SICR_OR, core << SHIFT32(3));
+ p9_cme_stop_self_execute(core, SPR_SELF_RESTORE);
- PK_TRACE_PERF("SF.RS: Self Restore Prepare, Core Waking up(pm_exit=1) via SICR[4/5]");
- out32(G_CME_LCL_SICR_OR, core << SHIFT32(5));
-
- CME_PM_EXIT_DELAY
-
- PK_TRACE("Polling for core wakeup(pm_active=0) via EINR[20/21]");
+ //==========================
+ MARK_TRAP(SX_SRESET_THREADS)
+ //==========================
- while((in32(G_CME_LCL_EINR)) & (core << SHIFT32(21)));
+ PK_TRACE("Poll for core stop again(pm_active=1)");
- scom_data.value = pCmeImgHdr->g_cme_cpmr_PhyAddr & BITS64(13, 30); //HRMOR[13:42]
+ while((~(in32(G_CME_LCL_EINR))) & (core << SHIFT32(21)))
+ {
+ core_spattn = (in32_sh(CME_LCL_SISR) >> SHIFT64SH(33)) & core;
-#if NIMBUS_DD_LEVEL == 10
-#if !SKIP_RAM_HRMOR
+ if (core_spattn)
+ {
+ PK_TRACE_ERR("ERROR: Core[%d] Special Attention Detected. Gard Core!", core_spattn);
+ CME_STOP_CORE_ERROR_HANDLER(core, core_spattn, CME_STOP_EXIT_SELF_RES_SPATTN);
- PK_TRACE("Activate thread0 for RAM via THREAD_INFO[18]");
- CME_PUTSCOM(THREAD_INFO, core, BIT64(18));
+ PK_TRACE("Release PCB Mux back on Core via SICR[10/11]");
+ out32(G_CME_LCL_SICR_CLR, core_spattn << SHIFT32(11));
- PK_TRACE("Enable RAM mode via RAM_MODEREG[0]");
- CME_PUTSCOM(RAM_MODEREG, core, BIT64(0));
+ while((core_spattn & ~(in32(G_CME_LCL_SISR) >> SHIFT32(11))) != core_spattn);
- PK_TRACE("Set SPR mode to LT0-7 via SPR_MODE[20-27]");
- CME_PUTSCOM(SPR_MODE, core, BITS64(20, 8));
+ PK_TRACE("PCB Mux Released on Core[%d]", core_spattn);
+ }
- for (core_mask = 2; core_mask; core_mask--)
- {
- if (core & core_mask)
+ if (!core)
{
- PK_TRACE_DBG("Set SPRC to scratch for core[%d] via SCOM_SPRC", core_mask);
- CME_PUTSCOM(SCOM_SPRC, core_mask, ((core_mask & 1) ? BIT64(60) : 0));
- PK_TRACE_DBG("Load SCRATCH0 with HOMER+2MB address %x", scom_data.value);
-
-#if EPM_P9_TUNING
+#if NIMBUS_DD_LEVEL == 20 || DISABLE_CME_DUAL_CAST == 1
- CME_PUTSCOM((SCRATCH0 + (core_mask & 1)), core_mask, 0xA200000);
+ continue;
#else
- CME_PUTSCOM((SCRATCH0 + (core_mask & 1)), core_mask, scom_data.value);
+ if (d2u4_flag)
+ {
+ p9_cme_stop_exit_end((CME_MASK_BC - deeper_core), spwu_stop);
+ }
+
+ return;
#endif
+
}
}
- PK_TRACE("RAM: mfspr sprd , gpr0 via RAM_CTRL");
- CME_PUTSCOM(RAM_CTRL, core, RAM_MFSPR_SPRD_GPR0);
-
- PK_TRACE("RAM: mtspr hrmor, gpr0 via RAM_CTRL");
- CME_PUTSCOM(RAM_CTRL, core, RAM_MTSPR_HRMOR_GPR0);
-
- PK_TRACE("Disable thread0 for RAM via THREAD_INFO");
- CME_PUTSCOM(THREAD_INFO, core, 0);
+ PK_TRACE_PERF("SF.RS: Self Restore Completed, Core Stopped Again(pm_exit=0/pm_active=1)");
- PK_TRACE("Disable RAM mode via RAM_MODEREG");
- CME_PUTSCOM(RAM_MODEREG, core, 0);
+ p9_cme_stop_self_cleanup(core);
- PK_TRACE("Clear scratch/spr used in RAM");
- CME_PUTSCOM(SPR_MODE, core, 0);
- CME_PUTSCOM(SCOM_SPRC, core, 0);
+#endif
- if (core & CME_MASK_C0)
+ if (d2u4_flag)
{
- CME_PUTSCOM(SCRATCH0, CME_MASK_C0, 0);
+ core = CME_MASK_BC;
}
+ }
- if (core & CME_MASK_C1)
- {
- CME_PUTSCOM(SCRATCH1, CME_MASK_C1, 0);
- }
+ p9_cme_stop_exit_end(core, spwu_stop);
+
+#if NIMBUS_DD_LEVEL == 20 || DISABLE_CME_DUAL_CAST == 1
+
+ // NDD2: dual cast workaround loop end
+ }
#endif
-// Nimbus DD2+
-#else
-#if SMF_SUPPORT_ENABLE
+ //===========================
+ MARK_TRAP(ENDSCOPE_STOP_EXIT)
+ //===========================
-#if EPM_P9_TUNING
+ return;
+}
- CME_PUTSCOM(URMOR, core, 0xA200000);
+void
+p9_cme_stop_self_cleanup(uint32_t core)
+{
+ data64_t scom_data;
-#else
+ //Cleaning up thread scratch register after self restore.
+ if( CME_MASK_C0 & core )
+ {
+ CME_PUTSCOM(SCRATCH0, CME_MASK_C0, 0);
+ }
- PK_TRACE_INF("Core Wakes Up, Write URMOR with HOMER address");
- CME_PUTSCOM(URMOR, core, scom_data.value);
+ if( CME_MASK_C1 & core )
+ {
+ CME_PUTSCOM(SCRATCH1, CME_MASK_C1, 0);
+ }
-#endif
+ PK_TRACE("Restore SPATTN after self-restore");
+ CME_PUTSCOM(SPATTN_MASK, core, G_spattn_mask);
-#endif
+ PK_TRACE("Always Unfreeze IMA (by clearing bit 34) in case the CHTM is enabled to sample it");
+ CME_GETSCOM(IMA_EVENT_MASK, core, scom_data.value);
+ CME_PUTSCOM(IMA_EVENT_MASK, core, scom_data.value & ~BIT64(34));
-#if EPM_P9_TUNING
+ PK_TRACE("Drop block interrupt to PC via SICR[2/3]");
+ out32(G_CME_LCL_SICR_CLR, core << SHIFT32(3));
- CME_PUTSCOM(HRMOR, core, 0xA200000);
+ PK_TRACE("Clear pm_active status via EISR[20/21]");
+ out32(G_CME_LCL_EISR_CLR, core << SHIFT32(21));
-#else
+}
- PK_TRACE_PERF("Core Wakes Up, Write HRMOR with HOMER address");
- // Must not set bit 15 in HRMOR
- scom_data.words.upper = scom_data.words.upper & ~BIT32(15);
- CME_PUTSCOM(HRMOR, core, scom_data.value);
+void
+p9_cme_stop_self_execute(uint32_t core, uint32_t i_saveRestore )
+{
+ uint32_t core_mask;
+ data64_t scom_data;
+ cmeHeader_t* pCmeImgHdr = (cmeHeader_t*)(CME_SRAM_HEADER_ADDR);
+ scom_data.value = pCmeImgHdr->g_cme_cpmr_PhyAddr & BITS64(13, 30); //HRMOR[13:42]
-#endif
+ PK_TRACE("Assert block interrupt to PC via SICR[2/3]");
-#endif
+ out32(G_CME_LCL_SICR_OR, core << SHIFT32(3));
- PK_TRACE("Save off and mask SPATTN before self-restore");
- CME_GETSCOM(SPATTN_MASK, core, spattn_mask);
- CME_PUTSCOM(SPATTN_MASK, core, BITS64(0, 64));
+ PK_TRACE_PERF("SF.RS: Self Restore Prepare, Core Waking up(pm_exit=1) via SICR[4/5]");
+ out32(G_CME_LCL_SICR_OR, core << SHIFT32(5));
-#if !DISABLE_CORE_XSTOP_INJECTION
+ CME_PM_EXIT_DELAY
- PK_TRACE("Read WKUP_ERR_INJECT_MODE via CPMMR[8]");
+ PK_TRACE("Polling for core wakeup(pm_active=0) via EINR[20/21]");
- for (core_mask = 2; core_mask; core_mask--)
- {
- if (core & core_mask)
- {
- CME_GETSCOM(CPPM_CPMMR, core_mask, scom_data.value);
+ while((in32(G_CME_LCL_EINR)) & (core << SHIFT32(21)));
- if (scom_data.words.upper & BIT32(8))
- {
- PK_TRACE_INF("WARNING: Injecting a core[%d] xstop via C_LFIR[11]", core);
- CME_PUTSCOM(C_LFIR_OR, core_mask, BIT64(11));
- }
- }
- }
+#if NIMBUS_DD_LEVEL == 10
+#if !SKIP_RAM_HRMOR
-#endif
+ PK_TRACE("Activate thread0 for RAM via THREAD_INFO[18]");
+ CME_PUTSCOM(THREAD_INFO, core, BIT64(18));
- for (core_mask = 2; core_mask; core_mask--)
- {
- if (core & core_mask)
- {
- CME_GETSCOM(CPPM_CPMMR, core_mask, scom_data.value);
+ PK_TRACE("Enable RAM mode via RAM_MODEREG[0]");
+ CME_PUTSCOM(RAM_MODEREG, core, BIT64(0));
- if (scom_data.words.upper & BIT32(3))
- {
- scom_data.value = BIT64(59);
- }
- else
- {
- scom_data.value = 0;
- }
+ PK_TRACE("Set SPR mode to LT0-7 via SPR_MODE[20-27]");
+ CME_PUTSCOM(SPR_MODE, core, BITS64(20, 8));
- //Writing thread scratch register to
- // 1. Init Runtime wakeup mode for core.
- // 2. Signal Self Save Restore code for restore operation.
- CME_PUTSCOM(SCRATCH0, core_mask, scom_data.value);
- CME_PUTSCOM(SCRATCH1, core_mask, scom_data.value);
- CME_PUTSCOM(SCRATCH2, core_mask, scom_data.value);
- CME_PUTSCOM(SCRATCH3, core_mask, scom_data.value);
- }
- }
+ for (core_mask = 2; core_mask; core_mask--)
+ {
+ if (core & core_mask)
+ {
+ PK_TRACE_DBG("Set SPRC to scratch for core[%d] via SCOM_SPRC", core_mask);
+ CME_PUTSCOM(SCOM_SPRC, core_mask, ((core_mask & 1) ? BIT64(60) : 0));
- PK_TRACE_PERF("SF.RS: Self Restore Kickoff, S-Reset All Core Threads");
+ PK_TRACE_DBG("Load SCRATCH0 with HOMER+2MB address %x", scom_data.value);
- // Disable interrupts around the sreset to polling check to not miss the self-restore
- wrteei(0);
- CME_PUTSCOM(DIRECT_CONTROLS, core,
- BIT64(4) | BIT64(12) | BIT64(20) | BIT64(28));
- sync();
+#if EPM_P9_TUNING
- PK_TRACE("Poll for instruction running before drop pm_exit");
+ CME_PUTSCOM((SCRATCH0 + (core_mask & 1)), core_mask, 0xA200000);
- while((~(in32_sh(CME_LCL_SISR))) & (core << SHIFT64SH(47)));
+#else
+ CME_PUTSCOM((SCRATCH0 + (core_mask & 1)), core_mask, scom_data.value);
- wrteei(1);
+#endif
- //==========================
- MARK_TRAP(SX_SRESET_THREADS)
- //==========================
+ }
+ }
- PK_TRACE("Allow threads to run(pm_exit=0)");
- out32(G_CME_LCL_SICR_CLR, core << SHIFT32(5));
+ PK_TRACE("RAM: mfspr sprd , gpr0 via RAM_CTRL");
+ CME_PUTSCOM(RAM_CTRL, core, RAM_MFSPR_SPRD_GPR0);
- PK_TRACE("Poll for core stop again(pm_active=1)");
+ PK_TRACE("RAM: mtspr hrmor, gpr0 via RAM_CTRL");
+ CME_PUTSCOM(RAM_CTRL, core, RAM_MTSPR_HRMOR_GPR0);
- while((~(in32(G_CME_LCL_EINR))) & (core << SHIFT32(21)))
- {
- core_spattn = (in32_sh(CME_LCL_SISR) >> SHIFT64SH(33)) & core;
+ PK_TRACE("Disable thread0 for RAM via THREAD_INFO");
+ CME_PUTSCOM(THREAD_INFO, core, 0);
- if (core_spattn)
- {
- PK_TRACE_ERR("ERROR: Core[%d] Special Attention Detected. Gard Core!", core_spattn);
- CME_STOP_CORE_ERROR_HANDLER(core, core_spattn, CME_STOP_EXIT_SELF_RES_SPATTN);
+ PK_TRACE("Disable RAM mode via RAM_MODEREG");
+ CME_PUTSCOM(RAM_MODEREG, core, 0);
- PK_TRACE("Release PCB Mux back on Core via SICR[10/11]");
- out32(G_CME_LCL_SICR_CLR, core_spattn << SHIFT32(11));
+ PK_TRACE("Clear scratch/spr used in RAM");
+ CME_PUTSCOM(SPR_MODE, core, 0);
+ CME_PUTSCOM(SCOM_SPRC, core, 0);
- while((core_spattn & ~(in32(G_CME_LCL_SISR) >> SHIFT32(11))) != core_spattn);
+ if (core & CME_MASK_C0)
+ {
+ CME_PUTSCOM(SCRATCH0, CME_MASK_C0, 0);
+ }
- PK_TRACE("PCB Mux Released on Core[%d]", core_spattn);
- }
+ if (core & CME_MASK_C1)
+ {
+ CME_PUTSCOM(SCRATCH1, CME_MASK_C1, 0);
+ }
- if (!core)
- {
+#endif
+// Nimbus DD2+
+#else
-#if NIMBUS_DD_LEVEL == 20 || DISABLE_CME_DUAL_CAST == 1
+#if SMF_SUPPORT_ENABLE
- continue;
+#if EPM_P9_TUNING
+ CME_PUTSCOM(URMOR, core, 0xA200000);
+ CME_PUTSCOM(HRMOR, core, 0xA200000);
#else
- if (d2u4_flag)
- {
- p9_cme_stop_exit_end((CME_MASK_BC - deeper_core), spwu_stop);
- }
+ CME_PUTSCOM(URMOR, core, scom_data.value);
+ PK_TRACE_INF("SMF core wakes up, write URMOR with HOMER address" );
+ scom_data.words.upper = scom_data.words.upper & ~BIT32(15);
- return;
+ if( SPR_SELF_SAVE == i_saveRestore )
+ {
+ scom_data.value = pCmeImgHdr->g_cme_unsec_cpmr_PhyAddr & BITS64(13, 30); //Unsecure HOMER
+ PKTRACE("SMF core self save, write un-secure HOMER address");
+ }
-#endif
+ CME_PUTSCOM(HRMOR, core, scom_data.value);
- }
- }
+#endif //EPM_P9_TUNING
- for (core_mask = 2; core_mask; core_mask--)
- {
- if (core & core_mask)
- {
- //Cleaning up thread scratch register after self restore.
- CME_PUTSCOM(SCRATCH0, core_mask, 0);
- CME_PUTSCOM(SCRATCH1, core_mask, 0);
- CME_PUTSCOM(SCRATCH2, core_mask, 0);
- CME_PUTSCOM(SCRATCH3, core_mask, 0);
- }
- }
+#else //SMF Not supported
- PK_TRACE_PERF("SF.RS: Self Restore Completed, Core Stopped Again(pm_exit=0/pm_active=1)");
+#if EPM_P9_TUNING
- PK_TRACE("Restore SPATTN after self-restore");
- CME_PUTSCOM(SPATTN_MASK, core, spattn_mask);
+ CME_PUTSCOM(HRMOR, core, 0xA200000);
+#else
- PK_TRACE("Always Unfreeze IMA (by clearing bit 34) in case the CHTM is enabled to sample it");
- CME_GETSCOM(IMA_EVENT_MASK, core, scom_data.value);
- CME_PUTSCOM(IMA_EVENT_MASK, core, scom_data.value & ~BIT64(34));
+ PK_TRACE_INF("Non SMF core wakes up, write HRMOR with HOMER address");
+ scom_data.words.upper = scom_data.words.upper & ~BIT32(15);
+ CME_PUTSCOM(HRMOR, core, scom_data.value);
- PK_TRACE("Drop block interrupt to PC via SICR[2/3]");
- out32(G_CME_LCL_SICR_CLR, core << SHIFT32(3));
+#endif //EPM_P9_TUNING
- PK_TRACE("Clear pm_active status via EISR[20/21]");
- out32(G_CME_LCL_EISR_CLR, core << SHIFT32(21));
+#endif //SMF_SUPPORT_ENABLE
-#endif
+#endif //Nimbus DD2+
- if (d2u4_flag)
+ PK_TRACE("Save off and mask SPATTN before self-restore");
+ CME_GETSCOM(SPATTN_MASK, core, G_spattn_mask);
+ CME_PUTSCOM(SPATTN_MASK, core, BITS64(0, 64));
+
+#if !DISABLE_CORE_XSTOP_INJECTION
+
+ PK_TRACE("Read WKUP_ERR_INJECT_MODE via CPMMR[8]");
+
+ for (core_mask = 2; core_mask; core_mask--)
+ {
+ if (core & core_mask)
+ {
+ CME_GETSCOM(CPPM_CPMMR, core_mask, scom_data.value);
+
+ if (scom_data.words.upper & BIT32(8))
{
- core = CME_MASK_BC;
+ PK_TRACE_INF("WARNING: Injecting a core[%d] xstop via C_LFIR[11]", core);
+ CME_PUTSCOM(C_LFIR_OR, core_mask, BIT64(11));
}
- }
- p9_cme_stop_exit_end(core, spwu_stop);
+ if( SPR_SELF_SAVE == i_saveRestore )
+ {
+ //Writing thread scratch register to
+ //Signal Self Save Restore code for save operation.
+ scom_data.words.upper = 0;
+ scom_data.words.lower = 1;
+ }
+ else
+ {
+ //Writing thread scratch register to
+ // 1. Init Runtime wakeup mode for core.
+ // 2. Signal Self Save Restore code for restore operation.
-#if NIMBUS_DD_LEVEL == 20 || DISABLE_CME_DUAL_CAST == 1
+ if (scom_data.words.upper & BIT32(3))
+ {
+ scom_data.value = BIT64(59);
+ }
+ else
+ {
+ scom_data.value = 0;
+ }
+ }
- // NDD2: dual cast workaround loop end
+ if( CME_MASK_C0 & core_mask )
+ {
+ CME_PUTSCOM(SCRATCH0, CME_MASK_C0, scom_data.value);
+ }
+
+ if( CME_MASK_C1 & core_mask )
+ {
+ CME_PUTSCOM(SCRATCH1, CME_MASK_C1, scom_data.value);
+ }
+ }
}
#endif
- //===========================
- MARK_TRAP(ENDSCOPE_STOP_EXIT)
- //===========================
+ PK_TRACE_PERF("SF.RS: Self Restore Kickoff, S-Reset All Core Threads");
+
+ // Disable interrupts around the sreset to polling check to not miss the self-restore
+ wrteei(0);
+
+ CME_PUTSCOM(DIRECT_CONTROLS, core,
+ BIT64(4) | BIT64(12) | BIT64(20) | BIT64(28));
+ sync();
+
+ //**DISABLE CHECK FOR instruction running to avoid race condition**
+ //PK_TRACE_INF("Poll for instruction running before drop pm_exit");
+ //while((~(in32_sh(CME_LCL_SISR))) & (core << SHIFT64SH(47)));
+
+ wrteei(1);
+
+ PK_TRACE_INF("Allow threads to run(pm_exit=0)");
+ out32(G_CME_LCL_SICR_CLR, core << SHIFT32(5));
- return;
}
diff --git a/import/chips/p9/procedures/utils/stopreg/selfRest.list b/import/chips/p9/procedures/utils/stopreg/selfRest.list
index c9ce9ea..78e3d1f 100644
--- a/import/chips/p9/procedures/utils/stopreg/selfRest.list
+++ b/import/chips/p9/procedures/utils/stopreg/selfRest.list
@@ -67,7 +67,7 @@ Disassembly of section .selfRestore:
...
b00: 00 00 02 00 attn
...
- c00: 00 00 02 00 attn
+ c00: 4b ff f5 00 b 100 <_sreset_hndlr>
...
d00: 00 00 02 00 attn
...
OpenPOWER on IntegriCloud