diff options
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.c | 522 |
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); |