diff options
Diffstat (limited to 'import')
4 files changed, 79 insertions, 14 deletions
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 6d360416..1c7fa20e 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 @@ -256,7 +256,17 @@ p9_cme_stop_db1_handler(void* arg, PkIrqId irq) { G_cme_stop_record.core_blockwu |= CME_MASK_BC; g_eimr_override |= IRQ_VEC_WAKE_C0 | IRQ_VEC_WAKE_C1; + + // Set AUTO_STOP1_DISABLE + out32(CME_LCL_LMCR_OR, BIT32(18)); + + // Set PM_BLOCK_INTERRUPTS out32(CME_LCL_SICR_OR, BITS32(2, 2)); + + // Clear PM_EXIT + out32(CME_LCL_SICR_CLR, BITS32(4, 2)); + + // Block Exit Enabled out32(CME_LCL_FLAGS_OR, BITS32(8, 2)); } @@ -265,6 +275,11 @@ p9_cme_stop_db1_handler(void* arg, PkIrqId irq) { G_cme_stop_record.core_blockey |= CME_MASK_BC; g_eimr_override |= IRQ_VEC_STOP_C0 | IRQ_VEC_STOP_C1; + + // Clear PM_ENTRY_ACK + out32(CME_LCL_SICR_CLR, BITS32(0, 2)); + + // Block Entry Enabled out32(CME_LCL_FLAGS_OR, BITS32(10, 2)); } } @@ -279,7 +294,14 @@ p9_cme_stop_db1_handler(void* arg, PkIrqId irq) { G_cme_stop_record.core_blockwu &= ~CME_MASK_BC; g_eimr_override &= ~(IRQ_VEC_WAKE_C0 | IRQ_VEC_WAKE_C1); + + // Clear AUTO_STOP1_DISABLE + out32(CME_LCL_LMCR_CLR, BIT32(18)); + + // Clear PM_BLOCK_INTERRUPTS out32(CME_LCL_SICR_CLR, BITS32(2, 2)); + + // Block Exit Disabled out32(CME_LCL_FLAGS_CLR, BITS32(8, 2)); } @@ -288,6 +310,8 @@ p9_cme_stop_db1_handler(void* arg, PkIrqId irq) { G_cme_stop_record.core_blockey &= ~CME_MASK_BC; g_eimr_override &= ~(IRQ_VEC_STOP_C0 | IRQ_VEC_STOP_C1); + + // Block Entry Disabled out32(CME_LCL_FLAGS_CLR, BITS32(10, 2)); } } diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_ipc_handlers.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_ipc_handlers.c index aa3a1d29..7a42d1ca 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_ipc_handlers.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_ipc_handlers.c @@ -29,7 +29,8 @@ extern SgpeStopRecord G_sgpe_stop_record; -void p9_sgpe_ipc_pgpe_ctrl_stop_updates(ipc_msg_t* cmd, void* arg) +void +p9_sgpe_ipc_pgpe_ctrl_stop_updates(ipc_msg_t* cmd, void* arg) { PkMachineContext ctx; @@ -57,30 +58,64 @@ void p9_sgpe_ipc_pgpe_ctrl_stop_updates(ipc_msg_t* cmd, void* arg) pk_irq_vec_restore(&ctx); } -void p9_sgpe_ipc_pgpe_suspend_stop(ipc_msg_t* cmd, void* arg) +void +p9_sgpe_ipc_pgpe_suspend_stop(ipc_msg_t* cmd, void* arg) { PkMachineContext ctx; + G_sgpe_stop_record.wof.suspend_cmd = cmd; + g_oimr_override |= (BITS64(47, 2) | BIT64(51)); + // stop in process if (G_sgpe_stop_record.wof.status_stop == STATUS_PROCESSING) { // Note: response will be sent by stop threads when suspension is completed - G_sgpe_stop_record.wof.suspend_cmd = cmd; G_sgpe_stop_record.wof.status_stop = STATUS_SUSPENDING; } // sgpe idle else if (G_sgpe_stop_record.wof.status_stop == STATUS_IDLE) { - ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)cmd; - ipcmsg_p2s_suspend_stop_t* msg = - (ipcmsg_p2s_suspend_stop_t*)async_cmd->cmd_data; - msg->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; + p9_sgpe_stop_suspend_all_cmes(); + } + + pk_irq_vec_restore(&ctx); +} + +void +p9_sgpe_stop_suspend_all_cmes() +{ + uint32_t qloop = 0; + uint32_t xloop = 0; + uint32_t cloop = 0; + uint32_t cpayload_t2 = 0; + uint32_t cme_list = 0; + + for(qloop = 0; qloop < MAX_QUADS; qloop++) + { + p9_sgpe_stop_suspend_msg_db1(qloop, BITS32(5, 3)); + } - ipc_send_rsp(cmd, IPC_RC_SUCCESS); + while (cme_list != 0xFFF00000) + { + for(xloop = 0; xloop < MAX_EXES; xloop++) + { + for(cloop = 0; cloop < CORES_PER_EX; cloop++) + { + cpayload_t2 = in32(OCB_OPIT2CN(((xloop << 1) + cloop))); - G_sgpe_stop_record.wof.status_stop = STATUS_SUSPENDED; - g_oimr_override |= (BITS64(47, 2) | BIT64(51)); + if (cpayload_t2 == 0x780) + { + cme_list |= BIT32(xloop); + } + } + } } - pk_irq_vec_restore(&ctx); + ipc_async_cmd_t* async_cmd = + (ipc_async_cmd_t*)(G_sgpe_stop_record.wof.suspend_cmd); + ipcmsg_p2s_suspend_stop_t* msg = + (ipcmsg_p2s_suspend_stop_t*)async_cmd->cmd_data; + msg->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; + ipc_send_rsp(G_sgpe_stop_record.wof.suspend_cmd, IPC_RC_SUCCESS); + G_sgpe_stop_record.wof.status_stop = STATUS_SUSPENDED; } diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h index f62484ee..d5d07e0c 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h @@ -297,7 +297,6 @@ void p9_sgpe_ipc_pgpe_ctrl_stop_updates(ipc_msg_t* cmd, void* arg); void p9_sgpe_ipc_pgpe_suspend_stop(ipc_msg_t* cmd, void* arg); void p9_sgpe_ipc_pgpe_rsp_callback(ipc_msg_t* cmd, void* arg); - /// SGPE STOP Entry and Exit Prototypes void p9_sgpe_stop_suspend_msg_db1(uint32_t, uint32_t); void p9_sgpe_stop_ipi_handler(void*, PkIrqId); @@ -307,6 +306,7 @@ void p9_sgpe_stop_exit_thread(void*); void p9_sgpe_stop_entry(); void p9_sgpe_stop_exit(); void p9_sgpe_stop_cme_scominit(uint32_t, uint32_t, uint32_t); +void p9_sgpe_stop_suspend_all_cmes(); /// Procedures shared between Istep4 and SGPE Stop void p9_hcd_cache_scan0(uint32_t, uint64_t, uint64_t); 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 56b703a1..828b2ae2 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 @@ -333,8 +333,7 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) } // if no core request, skip to next quad - if(!cirq || (!(BITS32((qloop << 2), 4) & (cpending_t2 | cpending_t3) & - G_sgpe_stop_record.group.core[VECTOR_CONFIG]))) + if(!cirq || (!(BITS32((qloop << 2), 4) & (cpending_t2 | cpending_t3)))) { continue; } @@ -438,6 +437,13 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) continue; } + // check core partial good here as suspend protocol may send pig on bad core + // on behalf of bad ex, which is processed by code above + if (!(G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32((qloop << 2) + cloop))) + { + continue; + } + GPE_GETSCOM(GPE_SCOM_ADDR_CORE(CPPM_CPMMR, ((qloop << 2) + cloop)), scom_data.value); |