summaryrefslogtreecommitdiffstats
path: root/import
diff options
context:
space:
mode:
Diffstat (limited to 'import')
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c24
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_ipc_handlers.c57
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h2
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c10
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);
OpenPOWER on IntegriCloud