summaryrefslogtreecommitdiffstats
path: root/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c')
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c228
1 files changed, 166 insertions, 62 deletions
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 5490507d..49d34942 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
@@ -38,6 +38,10 @@ p9_cme_stop_exit()
uint32_t deeper_core = 0;
uint32_t wakeup;
uint32_t core;
+#if !SKIP_CATCHUP
+ uint8_t core_catchup;
+#endif
+ uint8_t catchup_ongoing = 0;
uint8_t pcwu, spwu, rgwu;
//uint8_t grant;
ppm_sshsrc_t hist;
@@ -48,7 +52,7 @@ p9_cme_stop_exit()
// extract wakeup signals, clear status, and mask wakeup interrupts
wakeup = (in32(CME_LCL_EISR) >> SHIFT32(17)) & 0x3F;
- out32(CME_LCL_EISR_CLR, wakeup << SHIFT32(17));
+ out32(CME_LCL_EISR_CLR, (wakeup << SHIFT32(17)) | BITS32(24, 2));
// build the core select for wakeup
pcwu = (wakeup >> 4) & CME_MASK_BC;
@@ -57,9 +61,7 @@ p9_cme_stop_exit()
core = pcwu | spwu | rgwu;
// mask wake up interrupts
- out32(CME_LCL_EIMR_OR, (core << SHIFT32(13)) |
- (core << SHIFT32(15)) |
- (core << SHIFT32(17)));
+ out32(CME_LCL_EIMR_OR, BITS32(12, 6));
PK_TRACE("X0: Core Select[%d], pcwu[%d], spwu[%d], rgwu[%d]",
core, pcwu, spwu, rgwu);
@@ -74,14 +76,14 @@ p9_cme_stop_exit()
MARK_TAG(BEGINSCOPE_STOP_EXIT, core)
//==================================
- PK_TRACE("X0: Stop Levels[%d %d]",
- G_cme_stop_record.pm_state_c0, G_cme_stop_record.pm_state_c1);
+ PK_TRACE("X0: Actual Stop Levels[%d %d]",
+ G_cme_stop_record.act_stop_c0, G_cme_stop_record.act_stop_c1);
// Code Error: by default stop 1 auto wakeup should be enabled
- if ((core == CME_MASK_C0 && G_cme_stop_record.pm_state_c0 < 2) ||
- (core == CME_MASK_C1 && G_cme_stop_record.pm_state_c1 < 2) ||
- (core == CME_MASK_BC && (G_cme_stop_record.pm_state_c0 < 2 ||
- G_cme_stop_record.pm_state_c1 < 2)))
+ if ((core == CME_MASK_C0 && G_cme_stop_record.act_stop_c0 < 2) ||
+ (core == CME_MASK_C1 && G_cme_stop_record.act_stop_c1 < 2) ||
+ (core == CME_MASK_BC && (G_cme_stop_record.act_stop_c0 < 2 ||
+ G_cme_stop_record.act_stop_c1 < 2)))
{
return CME_STOP_EXIT_WAKEUP_FROM_STOP1;
}
@@ -89,23 +91,23 @@ p9_cme_stop_exit()
// set target_level to STOP level for c0
// unless c1(also or only) wants to wakeup
target_level = deeper_level =
- (core == CME_MASK_C0) ? G_cme_stop_record.pm_state_c0 :
- G_cme_stop_record.pm_state_c1;
+ (core == CME_MASK_C0) ? G_cme_stop_record.act_stop_c0 :
+ G_cme_stop_record.act_stop_c1;
// If both cores want to wakeup but are in different STOP levels,
// set deeper_level to the deeper level targeted by deeper core
if ((core == CME_MASK_BC) &&
- (G_cme_stop_record.pm_state_c0 != G_cme_stop_record.pm_state_c1))
+ (G_cme_stop_record.act_stop_c0 != G_cme_stop_record.act_stop_c1))
{
// Assume C0 is deeper, target_level is already set to C1
- deeper_level = G_cme_stop_record.pm_state_c0;
+ deeper_level = G_cme_stop_record.act_stop_c0;
deeper_core = CME_MASK_C0;
// Otherwise correct assumption on which one is in lighter level
- if (G_cme_stop_record.pm_state_c0 < G_cme_stop_record.pm_state_c1)
+ if (G_cme_stop_record.act_stop_c0 < G_cme_stop_record.act_stop_c1)
{
- target_level = G_cme_stop_record.pm_state_c0;
- deeper_level = G_cme_stop_record.pm_state_c1;
+ target_level = G_cme_stop_record.act_stop_c0;
+ deeper_level = G_cme_stop_record.act_stop_c1;
deeper_core = CME_MASK_C1;
}
}
@@ -154,71 +156,159 @@ p9_cme_stop_exit()
core = deeper_core;
}
-#if !STOP_PRIME
- // todo PK_TRACE("BCE Runtime Kickoff");
-
- // todo for catch up case
- //PK_TRACE("X1: Request PCB Arbiter");
- //p9_hcd_core_pcb_arb(core, 1);
-
- PK_TRACE("X1: Core Poweron");
- MARK_TRAP(SX_POWERON)
-
- if(p9_hcd_core_poweron(core))
+ do //catchup loop
{
- pk_halt();
- }
- MARK_TRAP(SX_POWERON_END)
+#if !STOP_PRIME
+ // todo PK_TRACE("BCE Runtime Kickoff");
+
+ // todo for catch up case
+ //PK_TRACE("X1: Request PCB Arbiter");
+ //p9_hcd_core_pcb_arb(core, 1);
+
+ PK_TRACE("X1: Core Poweron");
+ MARK_TRAP(SX_POWERON)
+ p9_hcd_core_poweron(core);
+ MARK_TRAP(SX_POWERON_END)
+
+ PK_TRACE("X2: Core Chiplet Reset");
+ MARK_TRAP(SX_CHIPLET_RESET)
+ p9_hcd_core_chiplet_reset(core);
+ MARK_TRAP(SX_CHIPLET_RESET_END)
+
+#if !SKIP_CATCHUP
+
+ //catchup
+ if (catchup_ongoing)
+ {
+ core = CME_MASK_BC;
+ catchup_ongoing = 0;
+ }
+ else
+ {
+ wakeup = (in32(CME_LCL_EISR) >> SHIFT32(17)) & 0x3F;
+ out32(CME_LCL_EISR_CLR, wakeup << SHIFT32(17));
+ core_catchup = ((wakeup >> 4) | (wakeup >> 2) | (wakeup >> 0)) &
+ CME_MASK_BC;
+
+ if (core_catchup && (core_catchup + core) == CME_MASK_BC)
+ {
+ out32(CME_LCL_SICR_OR, core_catchup << SHIFT32(11));
+
+ if(((core_catchup & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_2) ||
+ ((core_catchup & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_2))
+ {
+ deeper_core = core;
+ d2u4_flag = 1;
+ }
+ else if(((core_catchup & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_4) ||
+ ((core_catchup & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_4))
+ {
+ core = core_catchup;
+ catchup_ongoing = 1;
+ continue;
+ }
+
+ while((core_catchup & (in32(CME_LCL_SISR) >> SHIFT32(11))) !=
+ core_catchup);
+ }
+ }
- PK_TRACE("X2: Core Chiplet Reset");
- MARK_TRAP(SX_CHIPLET_RESET)
- p9_hcd_core_chiplet_reset(core);
- MARK_TRAP(SX_CHIPLET_RESET_END)
+#endif
#if !SKIP_INITF
- PK_TRACE("X3: Core GPTR Time Initf");
- MARK_TRAP(SX_GPTR_TIME_INITF)
- p9_hcd_core_gptr_time_initf(core);
- MARK_TRAP(SX_GPTR_TIME_INITF_END)
+ PK_TRACE("X3: Core GPTR Time Initf");
+ MARK_TRAP(SX_GPTR_TIME_INITF)
+ p9_hcd_core_gptr_time_initf(core);
+ MARK_TRAP(SX_GPTR_TIME_INITF_END)
#endif
- PK_TRACE("X4: Switch glsmux to DPLL output");
- CME_PUTSCOM(PPM_CGCR_OR, core, BIT64(3));
-
- PK_TRACE("X5: Core Chiplet Init");
- MARK_TRAP(SX_CHIPLET_INIT)
- p9_hcd_core_chiplet_init(core);
- MARK_TRAP(SX_CHIPLET_INIT_END)
+ PK_TRACE("X5: Core Chiplet Init");
+ MARK_TRAP(SX_CHIPLET_INIT)
+ p9_hcd_core_chiplet_init(core);
+ MARK_TRAP(SX_CHIPLET_INIT_END)
#if !SKIP_INITF
- PK_TRACE("X6: Core Repair Initf");
- MARK_TRAP(SX_REPAIR_INITF)
- p9_hcd_core_repair_initf(core);
- MARK_TRAP(SX_REPAIR_INITF_END)
+ PK_TRACE("X6: Core Repair Initf");
+ MARK_TRAP(SX_REPAIR_INITF)
+ p9_hcd_core_repair_initf(core);
+ MARK_TRAP(SX_REPAIR_INITF_END)
+#endif
+
+#if !SKIP_CATCHUP
+
+ //catchup
+ if (catchup_ongoing)
+ {
+ core = CME_MASK_BC;
+ catchup_ongoing = 0;
+ }
+ else
+ {
+ wakeup = (in32(CME_LCL_EISR) >> SHIFT32(17)) & 0x3F;
+ out32(CME_LCL_EISR_CLR, wakeup << SHIFT32(17));
+ core_catchup = ((wakeup >> 4) | (wakeup >> 2) | (wakeup >> 0)) &
+ CME_MASK_BC;
+
+ if (core_catchup && (core_catchup + core) == CME_MASK_BC)
+ {
+ out32(CME_LCL_SICR_OR, core_catchup << SHIFT32(11));
+
+ if(((core_catchup & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_2) ||
+ ((core_catchup & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_2))
+ {
+ deeper_core = core;
+ d2u4_flag = 1;
+ }
+ else if(((core_catchup & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_4) ||
+ ((core_catchup & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_4))
+ {
+ core = core_catchup;
+ catchup_ongoing = 1;
+ continue;
+ }
+
+ while((core_catchup & (in32(CME_LCL_SISR) >> SHIFT32(11))) !=
+ core_catchup);
+ }
+ }
+
#endif
#if !SKIP_ARY_INIT
- PK_TRACE("X7: Core Array Init");
- MARK_TRAP(SX_ARRAY_INIT)
- p9_hcd_core_arrayinit(core);
- MARK_TRAP(SX_ARRAY_INIT_END)
+ PK_TRACE("X7: Core Array Init");
+ MARK_TRAP(SX_ARRAY_INIT)
+ p9_hcd_core_arrayinit(core);
+ MARK_TRAP(SX_ARRAY_INIT_END)
#endif
#if !SKIP_INITF
- PK_TRACE("X8: Core Func Scan");
- MARK_TRAP(SX_INITF)
- p9_hcd_core_initf(core);
- MARK_TRAP(SX_INITF_END)
+ PK_TRACE("X8: Core Func Scan");
+ MARK_TRAP(SX_INITF)
+ p9_hcd_core_initf(core);
+ MARK_TRAP(SX_INITF_END)
#endif
#endif
+ }
+ while(catchup_ongoing);
+
if (d2u4_flag)
{
core = CME_MASK_BC;
}
}
+ // todo STOP LEVEL 3
+
//--------------------------------------------------------------------------
// STOP LEVEL 2
//--------------------------------------------------------------------------
@@ -298,7 +388,7 @@ p9_cme_stop_exit()
PK_TRACE("Poll for Core stop again(pm_active=1)");
- while(~(in32(CME_LCL_EINR)) & (core << SHIFT32(21)));
+ while((~(in32(CME_LCL_EINR))) & (core << SHIFT32(21)));
MARK_TRAP(SX_STOP15_THREADS)
@@ -341,9 +431,17 @@ p9_cme_stop_exit()
STOP_REQ_DISABLE,
STOP_ACT_DISABLE)
- // unmask stop interrupts
- G_cme_stop_record.cme_wakenup |= core;
- out32(CME_LCL_EIMR_CLR, (core << SHIFT32(21)));
+ G_cme_stop_record.active_core |= core;
+
+ if (core & CME_MASK_C0)
+ {
+ G_cme_stop_record.act_stop_c0 = 0;
+ }
+
+ if (core & CME_MASK_C1)
+ {
+ G_cme_stop_record.act_stop_c1 = 0;
+ }
// If not special wakeup, allow core to go back into STOP in the future
if (!spwu)
@@ -352,6 +450,12 @@ p9_cme_stop_exit()
out32(CME_LCL_SICR_CLR, core << SHIFT32(5));
}
+ // unmask stop interrupts
+ out32(CME_LCL_EIMR_CLR, ((core << SHIFT32(21)) |
+ /* ((~core & ~G_cme_stop_record.active_core & CME_MASK_BC)<<SHIFT32(13))| */
+ ((~core & ~G_cme_stop_record.active_core & CME_MASK_BC) << SHIFT32(15)) |
+ ((~core & ~G_cme_stop_record.active_core & CME_MASK_BC) << SHIFT32(17))));
+
//===========================
MARK_TRAP(ENDSCOPE_STOP_EXIT)
//===========================
OpenPOWER on IntegriCloud