summaryrefslogtreecommitdiffstats
path: root/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
diff options
context:
space:
mode:
Diffstat (limited to 'import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c')
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c522
1 files changed, 335 insertions, 187 deletions
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
index 59ecefbf..39bf2efc 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
@@ -50,17 +50,17 @@ SgpeStopRecord G_sgpe_stop_record __attribute__((section (".dump_ptrs"))) =
},
// group vectors
{
- {0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0},
{0, 0},
{0, 0},
- {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0},
#if DISABLE_STOP8
- {0, 0, 0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#else
- {0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0, 0, 0, 0}
+ {0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#endif
},
// wof status
@@ -82,8 +82,13 @@ p9_sgpe_fit_handler()
in32(OCB_OPITNPRA(PIG_TYPE5)) |
in32(OCB_OPIT6PRB);
+ // reset counter if current processing stop8+
+ if (G_sgpe_stop_record.wof.status_stop & STATUS_STOP_PROCESSING)
+ {
+ G_sgpe_stop_record.fit.starve_counter = 0;
+ }
// count to 10 times that stop8+ is not serviced, then block stop5
- if (G_sgpe_stop_record.wof.status_stop == STATUS_IDLE && tpending)
+ else if (tpending)
{
PK_TRACE("FIT: Stravation Counter: %d", G_sgpe_stop_record.fit.starve_counter);
@@ -99,11 +104,6 @@ p9_sgpe_fit_handler()
g_oimr_override |= BIT64(47);
}
}
- // reset counter if current processing stop8+
- else if (G_sgpe_stop_record.wof.status_stop == STATUS_PROCESSING)
- {
- G_sgpe_stop_record.fit.starve_counter = 0;
- }
}
@@ -141,15 +141,23 @@ p9_sgpe_checkstop_handler(void* arg, PkIrqId irq)
-void
+uint32_t
p9_sgpe_stop_suspend_db1_cme(uint32_t qloop, uint32_t msgid)
{
uint32_t cstart = 0;
uint32_t cindex = 0;
uint32_t cloop = 0;
uint32_t cmask = 0;
+ uint32_t req_list = 0;
data64_t scom_data = {0};
- ppm_pig_t pig = {0};
+
+ // For each quad that is not in STOP 11, send doorbeel
+ // Note: Stop11 wakeup will write CME_FLAGS to inform CME about BLOCK Entry
+ // No need for BLOCK Exit with STOP11 tells CME as the wakeup itself is blocked
+ if (!(G_sgpe_stop_record.group.quad[VECTOR_ACTIVE] & BIT32(qloop)))
+ {
+ return 0;
+ }
for(cstart = 0; cstart < CORES_PER_QUAD; cstart += 2)
{
@@ -166,10 +174,9 @@ p9_sgpe_stop_suspend_db1_cme(uint32_t qloop, uint32_t msgid)
cindex = (qloop << 2) + cloop;
- // For each quad that is not in STOP 11, send doorbeel
- if ((G_sgpe_stop_record.group.quad[VECTOR_ACTIVE] & BIT32(qloop)) &&
- (cloop != (cstart + CORES_PER_EX))) // if ex is partial good
+ if (cloop != (cstart + CORES_PER_EX)) // if ex is partial good
{
+ req_list |= BIT32(cindex);
scom_data.words.upper = msgid;
scom_data.words.lower = 0;
@@ -184,30 +191,22 @@ p9_sgpe_stop_suspend_db1_cme(uint32_t qloop, uint32_t msgid)
#endif
}
- // otherwise send an ack pig on behalf of that quad(stop11 or partial bad) or ex (ex is partial bad)
- else
- {
- if (cloop == (cstart + CORES_PER_EX))
- {
- cindex = (qloop << 2) + cstart;
- }
-
- pig.fields.req_intr_payload = msgid >> 16;
- pig.fields.req_intr_payload |= TYPE2_PAYLOAD_SUSPEND_ACK_MASK;
- pig.fields.req_intr_type = PIG_TYPE3;
- GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(PPM_PIG, cindex), pig.value);
- }
}
+
+ return req_list;
}
+
+
void
p9_sgpe_ipi3_low_handler(void* arg, PkIrqId irq)
{
- PkMachineContext ctx;
- uint32_t qloop = 0;
- uint32_t action = 0;
- uint32_t occflg = in32(OCB_OCCFLG) & BITS32(9, 4);
- data64_t scom_data = {0};
+ PkMachineContext ctx;
+ uint32_t req_list = 0;
+ uint32_t qloop = 0;
+ uint32_t action = 0;
+ uint32_t occflg = in32(OCB_OCCFLG) & BITS32(9, 4);
+ data64_t scom_data = {0};
PK_TRACE_INF("IPI-IRQ: %d", irq);
// Clear ipi3_lo interrupt
@@ -220,11 +219,24 @@ p9_sgpe_ipi3_low_handler(void* arg, PkIrqId irq)
// thus cannot be performed(no error taking out when this happens)
if ((occflg & (~BIT32(10))) > BIT32(9))
{
- // msg[5-7] << occflg[10]enable + [11]exit/[12]entry (filter bit[9] here)
- // msg[5] : perform block/unblock operation (enable/disable ignore stop func)
- // msg[6] : perform exit block/unblock operation
- // msg[7] : perform entry block/unblock operation
- action = ((occflg & (~BIT32(9))) << 5);
+ // msg[4-6] << occflg[10]enable + [11]exit/[12]entry (filter bit[9] here)
+ // msg[4] : perform block/unblock operation (enable/disable ignore stop func)
+ // msg[5] : perform exit block/unblock operation
+ // msg[6] : perform entry block/unblock operation
+ // msg[7] : reserved for suspend function
+ action = ((occflg & (~BIT32(9))) << 6);
+
+ if (action & BIT32(6))
+ {
+ G_sgpe_stop_record.group.creq[VECTOR_BLOCKX] = 0;
+ G_sgpe_stop_record.group.cack[VECTOR_BLOCKX] = 0;
+ }
+
+ if (action & BIT32(7))
+ {
+ G_sgpe_stop_record.group.creq[VECTOR_BLOCKE] = 0;
+ G_sgpe_stop_record.group.cack[VECTOR_BLOCKE] = 0;
+ }
for (qloop = 0; qloop < MAX_QUADS; qloop++)
{
@@ -238,9 +250,9 @@ p9_sgpe_ipi3_low_handler(void* arg, PkIrqId irq)
// target quad is to participate block/unblock exit
if (scom_data.words.upper & BIT32(10))
{
- action = action | BIT32(6);
+ action = action | BIT32(5);
- if (action & BIT32(5))
+ if (action & BIT32(4))
{
G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] |= BIT32(qloop);
}
@@ -252,15 +264,15 @@ p9_sgpe_ipi3_low_handler(void* arg, PkIrqId irq)
// not participate exit, taking exit encoding bit out
else
{
- action = action & (~BIT32(6));
+ action = action & (~BIT32(5));
}
// target quad is to participate block/unblock entry
if (scom_data.words.upper & BIT32(11))
{
- action = action | BIT32(7);
+ action = action | BIT32(6);
- if (action & BIT32(5))
+ if (action & BIT32(4))
{
G_sgpe_stop_record.group.quad[VECTOR_BLOCKE] |= BIT32(qloop);
}
@@ -272,14 +284,24 @@ p9_sgpe_ipi3_low_handler(void* arg, PkIrqId irq)
// not participate entry, taking entry encoding bit out
else
{
- action = action & (~BIT32(7));
+ action = action & (~BIT32(6));
}
// if this quad participates either entry/exit for block/unlock
// send msg; otherwise skip the quad
- if (action & BITS32(6, 2))
+ if (action & BITS32(5, 2))
{
- p9_sgpe_stop_suspend_db1_cme(qloop, action);
+ req_list = p9_sgpe_stop_suspend_db1_cme(qloop, action);
+
+ if (action & BIT32(6))
+ {
+ G_sgpe_stop_record.group.creq[VECTOR_BLOCKX] |= req_list;
+ }
+
+ if (action & BIT32(7))
+ {
+ G_sgpe_stop_record.group.creq[VECTOR_BLOCKE] |= req_list;
+ }
}
}
}
@@ -352,14 +374,34 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type)
uint32_t tpayload = 0;
uint32_t vector_index = 0;
uint32_t request_index = 0;
+ uint32_t block_index = 0;
+ uint32_t block_mask = 0;
uint32_t suspend_index = 0;
uint32_t suspend_mask = 0;
+ uint32_t entry_ignored = 0;
+ uint32_t exit_ignored = 0;
+#if DISABLE_STOP8
+ uint32_t s11x_rclk_enabled = 0;
+ uint32_t s11e_rclk_disabled = 0;
+#endif
data64_t scom_data = {0};
sgpeHeader_t* pSgpeImgHdr = (sgpeHeader_t*)(OCC_SRAM_SGPE_HEADER_ADDR);
// read typeX interrupt pending status
// then clear interrupt pending status
cpending = in32(OCB_OPITNPRA(type));
+
+#if DISABLE_STOP8
+
+ if (type == PIG_TYPE3)
+ {
+ // if having ongoing stop11 in resclk disable phase, hold on to all exits
+ // Note: no clearing interrupt pending bits in this case
+ cpending &= ~G_sgpe_stop_record.group.core[VECTOR_RCLKE];
+ }
+
+#endif
+
out32(OCB_OPITNPRA_CLR(type), cpending);
PK_TRACE("Cores Pending: %x", cpending);
@@ -452,62 +494,89 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type)
// if not hardware pig and is an suspend ack pig
if ((type == PIG_TYPE3) &&
((~cpayload) & TYPE2_PAYLOAD_HARDWARE_WAKEUP) &&
- (cpayload & TYPE2_PAYLOAD_SUSPEND_ACK_MASK))
+ (cpayload & TYPE2_PAYLOAD_SUSPEND_ACK_MASK))
{
- for(suspend_mask = TYPE2_PAYLOAD_SUSPEND_ENTRY_MASK,
+ if (cpayload & TYPE2_PAYLOAD_SUSPEND_SELECT_MASK)
+ {
+ if ((~cpayload) & TYPE2_PAYLOAD_SUSPEND_ACTION_MASK)
+ {
+ if (cpayload & TYPE2_PAYLOAD_SUSPEND_EXIT_MASK)
+ {
+ G_sgpe_stop_record.group.core[VECTOR_PIGX] |=
+ G_sgpe_stop_record.group.core[VECTOR_SUSPENDX] & BITS32((qloop << 2), 4);
+ G_sgpe_stop_record.group.qswu[VECTOR_EXIT] |=
+ G_sgpe_stop_record.group.qswu[VECTOR_SUSPENDX] & BITS32((qloop << 2), 4);
+ G_sgpe_stop_record.group.core[VECTOR_SUSPENDX] &= ~BITS32((qloop << 2), 4);
+ G_sgpe_stop_record.group.qswu[VECTOR_SUSPENDX] &= ~BITS32((qloop << 2), 4);
+ }
+
+ if (cpayload & TYPE2_PAYLOAD_SUSPEND_ENTRY_MASK)
+ {
+ G_sgpe_stop_record.group.core[VECTOR_PIGE] |=
+ G_sgpe_stop_record.group.core[VECTOR_SUSPENDE] & BITS32((qloop << 2), 4);
+ G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] |=
+ G_sgpe_stop_record.group.qswu[VECTOR_SUSPENDE] & BITS32((qloop << 2), 4);
+ G_sgpe_stop_record.group.core[VECTOR_SUSPENDE] &= ~BITS32((qloop << 2), 4);
+ G_sgpe_stop_record.group.qswu[VECTOR_SUSPENDE] &= ~BITS32((qloop << 2), 4);
+ }
+ }
+
+ continue;
+ }
+
+ for(block_mask = TYPE2_PAYLOAD_SUSPEND_ENTRY_MASK,
+ suspend_mask = STATUS_ENTRY_SUSPENDED,
+ suspend_index = VECTOR_SUSPENDE,
vector_index = VECTOR_ENTRY,
request_index = VECTOR_PIGE,
- suspend_index = VECTOR_BLOCKE;
- suspend_index <= VECTOR_BLOCKX;
- suspend_index++,
- request_index++,
+ block_index = VECTOR_BLOCKE;
+ block_index <= VECTOR_BLOCKX;
+ block_index++,
vector_index++,
- suspend_mask = suspend_mask << 1)
+ request_index++,
+ suspend_index++,
+ suspend_mask++,
+ block_mask = block_mask << 1)
{
- // if entry/exit is selected for performing suspend/unsuspend operation
- if (cpayload & suspend_mask)
+ // if entry/exit is selected for performing block/unblock operation
+ if (cpayload & block_mask)
{
- // suspend entry/exit/both
- if (cpayload & TYPE2_PAYLOAD_SUSPEND_OP_MASK)
+ // block entry/exit/both
+ if (cpayload & TYPE2_PAYLOAD_SUSPEND_ACTION_MASK)
{
- if ((cloop >> 1) % 2)
- {
- G_sgpe_stop_record.group.qex1[suspend_index] |= BIT32(qloop);
- }
- else
- {
- G_sgpe_stop_record.group.qex0[suspend_index] |= BIT32(qloop);
- }
+ G_sgpe_stop_record.group.cack[block_index] |= BIT32(cloop);
- if((G_sgpe_stop_record.group.qex0[suspend_index] &
- G_sgpe_stop_record.group.qex1[suspend_index] &
- G_sgpe_stop_record.group.quad[suspend_index]) ==
- G_sgpe_stop_record.group.quad[suspend_index])
+ if (G_sgpe_stop_record.group.cack[block_index] ==
+ G_sgpe_stop_record.group.creq[block_index])
{
out32(OCB_OCCFLG_CLR, BIT32(SGPE_IGNORE_STOP_CONTROL));
}
}
- // unsuspend entry/exit/both
+ // unblock entry/exit/both
else
{
- if ((cloop >> 1) % 2)
- {
- G_sgpe_stop_record.group.qex1[suspend_index] &= ~BIT32(qloop);
- }
- else
- {
- G_sgpe_stop_record.group.qex0[suspend_index] &= ~BIT32(qloop);
- }
+ G_sgpe_stop_record.group.cack[block_index] |= BIT32(cloop);
- if ((G_sgpe_stop_record.group.qex0[suspend_index] |
- G_sgpe_stop_record.group.qex1[suspend_index]) == 0)
+ if (G_sgpe_stop_record.group.cack[block_index] ==
+ G_sgpe_stop_record.group.creq[block_index])
{
- G_sgpe_stop_record.group.core[request_index] |=
- G_sgpe_stop_record.group.core[suspend_index];
- G_sgpe_stop_record.group.core[suspend_index] = 0;
- G_sgpe_stop_record.group.qswu[vector_index] |=
- G_sgpe_stop_record.group.qswu[suspend_index];
- G_sgpe_stop_record.group.qswu[suspend_index] = 0;
+ if (G_sgpe_stop_record.wof.status_stop & suspend_mask)
+ {
+ G_sgpe_stop_record.group.core[suspend_index] |=
+ G_sgpe_stop_record.group.core[block_index];
+ G_sgpe_stop_record.group.qswu[suspend_index] |=
+ G_sgpe_stop_record.group.qswu[block_index];
+ }
+ else
+ {
+ G_sgpe_stop_record.group.core[request_index] |=
+ G_sgpe_stop_record.group.core[block_index];
+ G_sgpe_stop_record.group.qswu[vector_index] |=
+ G_sgpe_stop_record.group.qswu[block_index];
+ }
+
+ G_sgpe_stop_record.group.core[block_index] = 0;
+ G_sgpe_stop_record.group.qswu[block_index] = 0;
out32(OCB_OCCFLG_CLR, BIT32(SGPE_IGNORE_STOP_CONTROL));
}
}
@@ -591,80 +660,117 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type)
#if DISABLE_STOP8
- // if having ongoing stop11 in resclk disable phase, hold on to all exits
- if (G_sgpe_stop_record.group.quad[VECTOR_RCLKE] & BIT32((qloop + RCLK_DIS_REQ_OFFSET)))
+ // Priority of Processing Exit Requests
+ // 1) Receive PIG Type5 with Rclk Exit encoding, aka
+ // Stop11 Entry aborted and Resonant Clock Enable completed
+ // --> allow wakeup from Stop5, previously saved off to RCLKX vector
+ // +++ set sibling RCLK_OPERATABLE
+ // AND/OR
+ // 2) Receive PIG Type3/2 with Core Exit encoding, but
+ // Stop Exit is Suspended, on all quads
+ // --> save off exit requests to suspend list
+ // if it was Type5 above, move RCLKX to SUSPEND list
+ // AND/OR
+ // Stop Exit is Blocked, on this quad
+ // --> save off exit requests to block list
+ // if it was Type5 above, move RCLKX to BLOCK list
+
+ s11x_rclk_enabled = 0;
+ exit_ignored = 0;
+
+ // Quad-Manager completed the resonant clock enable, proceed stop5 exit is now allowed
+ if ((type == PIG_TYPE5) && (cpayload == TYPE5_PAYLOAD_EXIT_RCLK))
{
- if ((type == PIG_TYPE5) && (cpayload == TYPE5_PAYLOAD_EXIT_RCLK))
+ PK_TRACE_INF("Core Request Exit Allowed as Resonant Clock Enable is Completed");
+ G_sgpe_stop_record.group.quad[VECTOR_RCLKX] &= ~BIT32(qloop);
+ s11x_rclk_enabled = 1;
+
+ // restore Sibling's ability to change rclk as QM just did to itself
+ ex = (cindex % 4) >> 1;
+
+ if (G_sgpe_stop_record.group.expg[qloop] & (ex + 1))
{
- PK_TRACE_ERR("ERROR: IMPOSSIBLE! RESCLK CME HANDSHAKE BROKEN! HALT SGPE!");
- PK_PANIC(SGPE_PIG_RESCLK_CME_HANDSHAKE_BROKEN);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS_OR, qloop, (ex ^ 1)),
+ BIT64(CME_FLAGS_RCLK_OPERABLE));
}
+ }
- PK_TRACE_INF("Core Request Exit But Resonent Clock Disable Ongoing so ignore");
- G_sgpe_stop_record.group.core[VECTOR_RCLKE] |= BIT32(cindex);
+ if (G_sgpe_stop_record.wof.status_stop & STATUS_EXIT_SUSPENDED)
+ {
+ PK_TRACE_DBG("Core Request Exit But in Suspend Wakeup Mode so Ignore");
+ exit_ignored = 1;
+
+ if (s11x_rclk_enabled)
+ {
+ G_sgpe_stop_record.group.core[VECTOR_SUSPENDX] |=
+ G_sgpe_stop_record.group.core[VECTOR_RCLKX] & BITS32((qloop << 2), 4);
+ }
+ else
+ {
+ G_sgpe_stop_record.group.core[VECTOR_SUSPENDX] |= BIT32(cindex);
+ }
}
- else if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] & BIT32(qloop))
+
+ if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] & BIT32(qloop))
{
PK_TRACE_DBG("Core Request Exit But in Block Wakeup Mode so Ignore");
+ exit_ignored = 1;
- if ((type == PIG_TYPE5) && (cpayload == TYPE5_PAYLOAD_EXIT_RCLK))
+ if (s11x_rclk_enabled)
{
- G_sgpe_stop_record.group.quad[VECTOR_RCLKX] &= ~BIT32(qloop);
G_sgpe_stop_record.group.core[VECTOR_BLOCKX] |=
G_sgpe_stop_record.group.core[VECTOR_RCLKX] & BITS32((qloop << 2), 4);
-
- // restore Sibling's ability to change rclk as QM just did to itself
- ex = (cindex % 4) >> 1;
-
- if (G_sgpe_stop_record.group.expg[qloop] & (ex + 1))
- {
- GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS_OR, qloop, (ex ^ 1)),
- BIT64(CME_FLAGS_RCLK_OPERABLE));
- }
}
else
{
G_sgpe_stop_record.group.core[VECTOR_BLOCKX] |= BIT32(cindex);
}
}
- // Quad-Manager completed the resonant clock enable, proceed stop5 exit is now allowed
- else if ((type == PIG_TYPE5) && (cpayload == TYPE5_PAYLOAD_EXIT_RCLK))
+
+ if (exit_ignored)
+ {
+ continue;
+ }
+
+ if (s11x_rclk_enabled)
{
- PK_TRACE_INF("Core Request Exit Allowed as Resonant Clock Enable is Completed");
- G_sgpe_stop_record.group.quad[VECTOR_RCLKX] &= ~BIT32(qloop);
G_sgpe_stop_record.group.core[VECTOR_PIGX] |=
G_sgpe_stop_record.group.core[VECTOR_RCLKX] & BITS32((qloop << 2), 4);
-
- // restore Sibling's ability to change rclk as QM just did to itself
- ex = (cindex % 4) >> 1;
-
- if (G_sgpe_stop_record.group.expg[qloop] & (ex + 1))
- {
- GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS_OR, qloop, (ex ^ 1)),
- BIT64(CME_FLAGS_RCLK_OPERABLE));
- }
+ continue;
}
#else
+ exit_ignored = 0;
+
+ if (G_sgpe_stop_record.wof.status_stop & STATUS_EXIT_SUSPENDED)
+ {
+ PK_TRACE_DBG("Core Request Exit But in Suspend Wakeup Mode so Ignore");
+ G_sgpe_stop_record.group.core[VECTOR_SUSPENDX] |= BIT32(cindex);
+ exit_ignored = 1;
+ }
+
if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] & BIT32(qloop))
{
PK_TRACE_DBG("Core Request Exit But in Block Wakeup Mode so Ignore");
G_sgpe_stop_record.group.core[VECTOR_BLOCKX] |= BIT32(cindex);
+ exit_ignored = 1;
+ }
+
+ if (exit_ignored)
+ {
+ continue;
}
#endif
- else
- {
- PK_TRACE_INF("Core Request Exit Confirmed");
- G_sgpe_stop_record.group.core[VECTOR_PIGX] |= BIT32(cindex);
+ PK_TRACE_INF("Core Request Exit Confirmed");
+ G_sgpe_stop_record.group.core[VECTOR_PIGX] |= BIT32(cindex);
- PK_TRACE("Update STOP history on core: in transition of exit");
- scom_data.words.upper = SSH_EXIT_IN_SESSION;
- scom_data.words.lower = 0;
- GPE_PUTSCOM_VAR(PPM_SSHSRC, CORE_ADDR_BASE, cindex, 0, scom_data.value);
- }
+ PK_TRACE("Update STOP history on core: in transition of exit");
+ scom_data.words.upper = SSH_EXIT_IN_SESSION;
+ scom_data.words.lower = 0;
+ GPE_PUTSCOM_VAR(PPM_SSHSRC, CORE_ADDR_BASE, cindex, 0, scom_data.value);
}
}
// request entry
@@ -692,47 +798,77 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type)
#if DISABLE_STOP8
- if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKE] & BIT32(qloop))
- {
- PK_TRACE_DBG("Core Request Entry But in Block Entry Mode so Ignore");
+ // Priority of Processing Entry Requests
+ // 1) Receive PIG Type5 with Rclk Entry encoding, aka Resonant Clock Disable completed
+ // --> allow stop11 entry to proceed
+ // ELSE
+ // 2) Receive PIG Type3/2 with Core Entry encoding, but
+ // Stop Entry is Suspended, on all quads
+ // --> save off entry requests to suspend list
+ // AND/OR
+ // Stop Entry is Blocked, on this quad
+ // --> save off entry requests to block list
- if ((type == PIG_TYPE5) &&
- (cpayload == (TYPE5_PAYLOAD_ENTRY_RCLK | STOP_LEVEL_11)))
- {
- G_sgpe_stop_record.group.quad[VECTOR_RCLKE] &= ~BIT32((qloop + RCLK_DIS_REQ_OFFSET));
- G_sgpe_stop_record.group.quad[VECTOR_RCLKE] |= BIT32((qloop + RCLK_DIS_DONE_OFFSET));
- }
- else
- {
- G_sgpe_stop_record.group.core[VECTOR_BLOCKE] |= BIT32(cindex);
- }
- }
+ entry_ignored = 0;
+ s11e_rclk_disabled = 0;
// Quad-Manager completed the resonant clock disable, proceed stop11 entry
// block entry protocol is checked in the entry code instead of here below
- else if ((type == PIG_TYPE5) &&
- (cpayload == (TYPE5_PAYLOAD_ENTRY_RCLK | STOP_LEVEL_11)))
+ if ((type == PIG_TYPE5) &&
+ (cpayload == (TYPE5_PAYLOAD_ENTRY_RCLK | STOP_LEVEL_11)))
{
PK_TRACE_INF("Core Request Entry Allowed as Resonant Clock Disable is Completed");
G_sgpe_stop_record.group.quad[VECTOR_RCLKE] &= ~BIT32((qloop + RCLK_DIS_REQ_OFFSET));
G_sgpe_stop_record.group.quad[VECTOR_RCLKE] |= BIT32((qloop + RCLK_DIS_DONE_OFFSET));
+ s11e_rclk_disabled = 1;
+ }
+
+ if (G_sgpe_stop_record.wof.status_stop & STATUS_ENTRY_SUSPENDED && !s11e_rclk_disabled)
+ {
+ PK_TRACE_DBG("Core Request Entry But in Suspend Entry Mode so Ignore");
+ G_sgpe_stop_record.group.core[VECTOR_SUSPENDE] |= BIT32(cindex);
+ entry_ignored = 1;
+ }
+
+ if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKE] & BIT32(qloop) && !s11e_rclk_disabled)
+ {
+ PK_TRACE_DBG("Core Request Entry But in Block Entry Mode so Ignore");
+ G_sgpe_stop_record.group.core[VECTOR_BLOCKE] |= BIT32(cindex);
+ entry_ignored = 1;
+ }
+
+ if (entry_ignored || s11e_rclk_disabled)
+ {
+ continue;
}
#else
+ entry_ignored = 0;
+
+ if (G_sgpe_stop_record.wof.status_stop & STATUS_ENTRY_SUSPENDED)
+ {
+ PK_TRACE_DBG("Core Request Entry But in Suspend Entry Mode so Ignore");
+ G_sgpe_stop_record.group.core[VECTOR_SUSPENDE] |= BIT32(cindex);
+ entry_ignored = 1;
+ }
+
if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKE] & BIT32(qloop))
{
PK_TRACE_DBG("Core Request Entry But in Block Entry Mode so Ignore");
G_sgpe_stop_record.group.core[VECTOR_BLOCKE] |= BIT32(cindex);
+ entry_ignored = 1;
}
-#endif
-
- else
+ if (entry_ignored)
{
- PK_TRACE_INF("Core Request Entry Confirmed");
- G_sgpe_stop_record.group.core[VECTOR_PIGE] |= BIT32(cindex);
+ continue;
}
+
+#endif
+
+ PK_TRACE_INF("Core Request Entry Confirmed");
+ G_sgpe_stop_record.group.core[VECTOR_PIGE] |= BIT32(cindex);
}
// payload invalid
else
@@ -806,31 +942,29 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type)
#endif
- if ((cexit = G_sgpe_stop_record.group.core[VECTOR_PIGX]) ||
- (center = G_sgpe_stop_record.group.core[VECTOR_PIGE]))
- {
- // Taking Stop5 Actions, Can only do these steps after ipc done above
- scom_data.words.lower = 0;
+ // Taking Stop5 Actions, Can only do these steps after ipc done above
+ scom_data.words.lower = 0;
+ cexit = G_sgpe_stop_record.group.core[VECTOR_PIGX];
+ center = G_sgpe_stop_record.group.core[VECTOR_PIGE];
- for(cindex = 0; cexit || center; cexit <<= 1, center <<= 1, cindex++)
+ for(cindex = 0; cexit || center; cexit <<= 1, center <<= 1, cindex++)
+ {
+ if ((cexit & BIT32(0)) && (type == 2))
{
- if ((cexit & BIT32(0)) && (type == 2))
- {
- p9_sgpe_stop_exit_handoff_cme(cindex);
- }
+ p9_sgpe_stop_exit_handoff_cme(cindex);
+ }
- if (center & BIT32(0))
- {
- PK_TRACE("Update STOP history: in core[%d] stop level 5", cindex);
- scom_data.words.upper = SSH_ACT_LV5_COMPLETE;
- GPE_PUTSCOM_VAR(PPM_SSHSRC, CORE_ADDR_BASE, cindex, 0, scom_data.value);
+ if (center & BIT32(0))
+ {
+ PK_TRACE("Update STOP history: in core[%d] stop level 5", cindex);
+ scom_data.words.upper = SSH_ACT_LV5_COMPLETE;
+ GPE_PUTSCOM_VAR(PPM_SSHSRC, CORE_ADDR_BASE, cindex, 0, scom_data.value);
- G_sgpe_stop_record.group.core[VECTOR_ACTIVE] &= ~BIT32(cindex);
+ G_sgpe_stop_record.group.core[VECTOR_ACTIVE] &= ~BIT32(cindex);
- //================================================
- MARK_TAG(SE_LESSTHAN8_DONE, (32 >> (cindex >> 2)))
- //================================================
- }
+ //================================================
+ MARK_TAG(SE_LESSTHAN8_DONE, (32 >> (cindex >> 2)))
+ //================================================
}
}
}
@@ -895,9 +1029,6 @@ p9_sgpe_pig_type2_handler(void* arg, PkIrqId irq)
//===============================
PK_TRACE_DBG("PIG-TYPE2: %d", irq);
- // Clear Type2 Interrupt
- out32(OCB_OISR1_CLR, BIT32(15));
-
// Parse Type2 Requests
p9_sgpe_pig_cpayload_parser(PIG_TYPE2);
@@ -915,9 +1046,6 @@ p9_sgpe_pig_type3_handler(void* arg, PkIrqId irq)
//===============================
PK_TRACE_DBG("PIG-TYPE3: %d", irq);
- // Clear Type3 Interrupt
- out32(OCB_OISR1_CLR, BIT32(16));
-
// Parse Type3 Requests
p9_sgpe_pig_cpayload_parser(PIG_TYPE3);
@@ -934,9 +1062,6 @@ p9_sgpe_pig_type5_handler(void* arg, PkIrqId irq)
//===============================
PK_TRACE_DBG("PIG-TYPE5: %d", irq);
- // Clear Type5 Interrupt
- out32(OCB_OISR1_CLR, BIT32(18));
-
#if DISABLE_STOP8
// Parse Type5 Requests
@@ -958,6 +1083,8 @@ p9_sgpe_pig_type6_handler(void* arg, PkIrqId irq)
uint32_t qloop = 0;
uint32_t qpending = 0;
uint32_t qpayload = 0;
+ uint32_t exit_ignored = 0;
+ uint32_t entry_ignored = 0;
//===============================
MARK_TRAP(STOP_PIG_TYPE6_HANDLER)
@@ -1005,14 +1132,26 @@ p9_sgpe_pig_type6_handler(void* arg, PkIrqId irq)
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_GPMMR_OR, qloop), BIT64(0));
G_sgpe_stop_record.group.qswu[VECTOR_ACTIVE] |= BIT32(qloop);
}
- else if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] & BIT32(qloop))
- {
- PK_TRACE_DBG("Quad is in Block Wakeup Mode, Ignore Now");
- G_sgpe_stop_record.group.qswu[VECTOR_BLOCKX] |= BIT32(qloop);
- }
else
{
- G_sgpe_stop_record.group.qswu[VECTOR_EXIT] |= BIT32(qloop);
+ if (G_sgpe_stop_record.wof.status_stop & STATUS_EXIT_SUSPENDED)
+ {
+ PK_TRACE_DBG("Quad is in Suspend Wakeup Mode, Ignore Now");
+ G_sgpe_stop_record.group.qswu[VECTOR_SUSPENDX] |= BIT32(qloop);
+ exit_ignored = 1;
+ }
+
+ if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] & BIT32(qloop))
+ {
+ PK_TRACE_DBG("Quad is in Block Wakeup Mode, Ignore Now");
+ G_sgpe_stop_record.group.qswu[VECTOR_BLOCKX] |= BIT32(qloop);
+ exit_ignored = 1;
+ }
+
+ if (!exit_ignored)
+ {
+ G_sgpe_stop_record.group.qswu[VECTOR_EXIT] |= BIT32(qloop);
+ }
}
}
else
@@ -1020,12 +1159,21 @@ p9_sgpe_pig_type6_handler(void* arg, PkIrqId irq)
PK_TRACE_DBG("Quad Drop Special Wakeup, Clearing Done");
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_GPMMR_CLR, qloop), BIT64(0));
+ if (G_sgpe_stop_record.wof.status_stop & STATUS_ENTRY_SUSPENDED)
+ {
+ PK_TRACE_DBG("Quad is in Suspend Entry Mode, Ignore Re-entry Now");
+ G_sgpe_stop_record.group.qswu[VECTOR_SUSPENDE] |= BIT32(qloop);
+ entry_ignored = 1;
+ }
+
if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKE] & BIT32(qloop))
{
PK_TRACE_DBG("Quad is in Block Entry Mode, Ignore Re-entry Now");
G_sgpe_stop_record.group.qswu[VECTOR_BLOCKE] |= BIT32(qloop);
+ entry_ignored = 1;
}
- else
+
+ if (!entry_ignored)
{
G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] |= BIT32(qloop);
G_sgpe_stop_record.group.qswu[VECTOR_ACTIVE] &= ~BIT32(qloop);
OpenPOWER on IntegriCloud