From 5f054b32cffe00f2f0bb472c728128fad1c93779 Mon Sep 17 00:00:00 2001 From: Yue Du Date: Fri, 23 Feb 2018 09:57:34 -0600 Subject: STOP: Support Suspend Entry/Exit and Fix Pig Collision 1) also cleanup todos in Stop Hcode 2) make STOP3 complete trans in SSH Key_Cronus_Test=PM_REGRESS Change-Id: I91f89d647f8285f1ac153a8ea389f3c314f18f86 Original-Change-Id: I28a146e15e455f09f8d8ff588e122d5ecf34110a CQ: SW416550 CQ: HW437955 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/54660 Tested-by: PPE CI Tested-by: HWSV CI Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Tested-by: Cronus HW CI Tested-by: Hostboot CI Reviewed-by: RAHUL BATRA Reviewed-by: Michael S. Floyd Reviewed-by: Gregory S. Still --- .../p9/common/pmlib/include/stop_sgpe_cme_api.h | 38 +- .../p9/common/pmlib/include/wof_sgpe_pgpe_api.h | 32 +- .../p9/procedures/ppe_closed/cme/pk_app_cfg.h | 19 +- .../ppe_closed/cme/stop_cme/p9_cme_stop_init.c | 8 + .../pstate_gpe/p9_pgpe_thread_actuate_pstates.c | 2 +- .../sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c | 3 +- .../sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c | 61 ++- .../sgpe/stop_gpe/p9_hcd_sgpe_boot_cme.c | 3 +- .../sgpe/stop_gpe/p9_sgpe_ipc_handlers.c | 67 ++- .../ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h | 60 +-- .../ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c | 26 +- .../sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c | 522 +++++++++++++-------- .../sgpe/stop_gpe/p9_sgpe_stop_threads.c | 62 +-- .../ppe_closed/sgpe/stop_gpe/pk_app_cfg.h | 4 +- .../ppe_closed/sgpe/stop_gpe/sgpe_panic_codes.h | 4 +- 15 files changed, 541 insertions(+), 370 deletions(-) diff --git a/import/chips/p9/common/pmlib/include/stop_sgpe_cme_api.h b/import/chips/p9/common/pmlib/include/stop_sgpe_cme_api.h index 6924b5fb..40a44ad8 100644 --- a/import/chips/p9/common/pmlib/include/stop_sgpe_cme_api.h +++ b/import/chips/p9/common/pmlib/include/stop_sgpe_cme_api.h @@ -41,11 +41,12 @@ enum SGPE_STOP_IRQ_PAYLOAD_MASKS // 0110 reserved TYPE2_PAYLOAD_DECREMENTER_WAKEUP = 0x700, // 0111 - TYPE2_PAYLOAD_SUSPEND_OP_MASK = 0x400, + // These bit1-4 is aligned with the bit0-3 of DB1 below + TYPE2_PAYLOAD_SUSPEND_ACTION_MASK = 0x400, TYPE2_PAYLOAD_SUSPEND_EXIT_MASK = 0x200, TYPE2_PAYLOAD_SUSPEND_ENTRY_MASK = 0x100, - TYPE2_PAYLOAD_SUSPEND_BOTH_MASK = 0x300, - TYPE2_PAYLOAD_SUSPEND_ACK_MASK = 0x080, + TYPE2_PAYLOAD_SUSPEND_SELECT_MASK = 0x080, + TYPE2_PAYLOAD_SUSPEND_ACK_MASK = 0x040, TYPE5_PAYLOAD_CME_ERROR = 0x3FF, TYPE6_PAYLOAD_EXIT_EVENT = 0x00F @@ -63,14 +64,29 @@ enum CME_STOP_PIG_TYPES /// Numberical Doorbell Message IDs(used by CME check) enum CME_DOORBELL_MESSAGE_IDS { - MSGID_DB1_UNSUSPEND_STOP_ENTRIES = 0x01, - MSGID_DB1_UNSUSPEND_STOP_EXITS = 0x02, - MSGID_DB1_UNSUSPEND_STOP_ENTRIES_EXITS = 0x03, - // 0x04 Illegal - MSGID_DB1_SUSPEND_STOP_ENTRIES = 0x05, - MSGID_DB1_SUSPEND_STOP_EXITS = 0x06, - MSGID_DB1_SUSPEND_STOP_ENTRIES_EXITS = 0x07, - MSGID_DB1_WAKEUP_GRANTED = 0x08, + // Bit0:Suspend(1)/Unsuspend(0) | Bit1:Exit | Bit2:Entry | Bit3:Suspend(1)/Block(0) + + // Illegal as Unblock without Entry/Exit 00, // 0000 + MSGID_DB1_UNBLOCK_STOP_ENTRIES = 0x02, // 0010 + MSGID_DB1_UNBLOCK_STOP_EXITS = 0x04, // 0100 + MSGID_DB1_UNBLOCK_STOP_ENTRIES_EXITS = 0x06, // 0110 + + // Illegal as Block without Entry/Exit 08, // 1000 + MSGID_DB1_BLOCK_STOP_ENTRIES = 0x0A, // 1010 + MSGID_DB1_BLOCK_STOP_EXITS = 0x0C, // 1100 + MSGID_DB1_BLOCK_STOP_ENTRIES_EXITS = 0x0E, // 1110 + + // Illegal as Unsuspend without Entry/Exit 01, // 0001 + MSGID_DB1_UNSUSPEND_STOP_ENTRIES = 0x03, // 0011 + MSGID_DB1_UNSUSPEND_STOP_EXITS = 0x05, // 0101 + MSGID_DB1_UNSUSPEND_STOP_ENTRIES_EXITS = 0x07, // 0111 + + // Illegal as Suspend without Entry/Exit 09, // 1001 + MSGID_DB1_SUSPEND_STOP_ENTRIES = 0x0B, // 1011 + MSGID_DB1_SUSPEND_STOP_EXITS = 0x0D, // 1101 + MSGID_DB1_SUSPEND_STOP_ENTRIES_EXITS = 0x0F, // 1111 + + MSGID_DB1_WAKEUP_GRANTED = 0x10, MSGID_DB2_DECREMENTER_WAKEUP = 0x01, MSGID_DB2_RESONANT_CLOCK_DISABLE = 0x02, diff --git a/import/chips/p9/common/pmlib/include/wof_sgpe_pgpe_api.h b/import/chips/p9/common/pmlib/include/wof_sgpe_pgpe_api.h index f51db666..f018bd98 100644 --- a/import/chips/p9/common/pmlib/include/wof_sgpe_pgpe_api.h +++ b/import/chips/p9/common/pmlib/include/wof_sgpe_pgpe_api.h @@ -99,12 +99,12 @@ typedef union uint64_t value; struct { - uint32_t msg_num : 4; - uint32_t update_type : 1; - uint32_t reserved : 3; - uint32_t return_code : 8; - uint32_t active_cores : 24; - uint32_t return_active_cores : 24; + uint64_t msg_num : 4; + uint64_t update_type : 1; + uint64_t reserved : 3; + uint64_t return_code : 8; + uint64_t active_cores : 24; + uint64_t return_active_cores : 24; } fields; } ipcmsg_s2p_update_active_cores_t; @@ -113,16 +113,16 @@ typedef union uint64_t value; struct { - uint32_t msg_num : 4; - uint32_t update_type : 1; - uint32_t entry_type : 1; - uint32_t reserved : 2; - uint32_t return_code : 8; - uint32_t requested_quads : 6; - uint32_t reserved0 : 2; - uint32_t return_active_quads : 6; - uint32_t reserved1 : 2; - uint32_t pad : 32; + uint64_t msg_num : 4; + uint64_t update_type : 1; + uint64_t entry_type : 1; + uint64_t reserved : 2; + uint64_t return_code : 8; + uint64_t requested_quads : 6; + uint64_t reserved0 : 2; + uint64_t return_active_quads : 6; + uint64_t reserved1 : 2; + uint64_t pad : 32; } fields; } ipcmsg_s2p_update_active_quads_t; diff --git a/import/chips/p9/procedures/ppe_closed/cme/pk_app_cfg.h b/import/chips/p9/procedures/ppe_closed/cme/pk_app_cfg.h index 3a63a6da..74dcb72d 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pk_app_cfg.h +++ b/import/chips/p9/procedures/ppe_closed/cme/pk_app_cfg.h @@ -36,15 +36,18 @@ // Debug Switches -//@todo RTC 161182 this is currently broken: -//(need iota/fit resolution to restore function) +//NOTE this is currently broken: +//need iota/fit resolution to restore function //#define TEST_ONLY_BCE_IRR 0 // -------------------- -//override switch to disable stop8 -//(with backup resonant clock support), -//@todo DD level condition is yet to be defined +// Hyp debug support, +#define DISABLE_CORE_XSTOP_INJECTION 0 + +// -------------------- + +//override switch to disable stop8 with backup resonant clock support #define DISABLE_STOP8 1 // -------------------- @@ -76,12 +79,6 @@ #define ENABLE_CME_DEC_TIMER 0 // -------------------- -// Hyp debug support, -// @todo need to disable this for GA -#define DISABLE_CORE_XSTOP_INJECTION 0 - -// -------------------- - // the following functions are always enabled once working // (unless earlier DD level condition undef them below) diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_init.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_init.c index c9bca6b7..6dc58b74 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_init.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_init.c @@ -67,6 +67,14 @@ p9_cme_stop_init() G_cme_stop_record.core_blockpc = ((in32(CME_LCL_SISR) & BITS32(2, 2)) >> SHIFT32(3)); G_cme_stop_record.core_blockwu = G_cme_stop_record.core_blockpc; G_cme_stop_record.core_blockey = 0; + G_cme_stop_record.core_suspendwu = G_cme_stop_record.core_blockpc; + G_cme_stop_record.core_suspendey = 0; + + if (in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_BLOCK_ENTRY_STOP11)) + { + G_cme_stop_record.core_blockey = CME_MASK_BC; + G_cme_stop_record.core_suspendey = CME_MASK_BC; + } // use SISR[16:17] SPECIAL_WKUP_DONE to init special wakeup status G_cme_stop_record.core_in_spwu = ((in32(CME_LCL_SISR) & BITS32(16, 2)) >> SHIFT32(17)); diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_actuate_pstates.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_actuate_pstates.c index 7840600f..4fc90f53 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_actuate_pstates.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_actuate_pstates.c @@ -273,9 +273,9 @@ void p9_pgpe_thread_actuate_pstates(void* arg) ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_CORES_UPDT].cmd; ipcmsg_s2p_update_active_cores_t* args = (ipcmsg_s2p_update_active_cores_t*)async_cmd->cmd_data; args->fields.return_active_cores = G_pgpe_pstate_record.activeCores >> 8; - args->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_CORES_UPDT].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_CORES_UPDT].cmd, IPC_RC_SUCCESS); + args->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; p9_pgpe_optrace(ACK_CORES_ACTV); restore_irq = 1; } diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c index 203430ca..ea58db35 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -66,7 +66,6 @@ p9_hcd_cache_chiplet_reset(uint32_t quad) } } - /// @todo needs to revisit this sim workaround PK_TRACE("Init heartbeat hang counter via HANG_PULSE_6[2]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_HANG_PULSE_6_REG, quad), BIT64(2)); diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c index ddaafd31..0779cc8b 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -31,7 +31,7 @@ inline __attribute__((always_inline)) void p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) { - uint64_t scom_data = 0; + data64_t scom_data = {0}; PK_TRACE("Drop L2 Regional Fences via CPLT_CTRL1[8/9]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_CLEAR, quad), @@ -45,9 +45,9 @@ p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) do { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QACSR, quad), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QACSR, quad), scom_data.value); } - while((~scom_data) & ((uint64_t)ex << SHIFT64(37))); + while((~scom_data.words.lower) & (ex << SHIFT64SH(37))); MARK_TRAP(SX_L2_STARTCLOCKS_ALIGN) @@ -60,11 +60,11 @@ p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_OR, quad), BIT64(3)); PK_TRACE("Set then unset clear_chiplet_is_aligned via SYNC_CONFIG[7]"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data); - scom_data = scom_data | BIT64(7); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data); - scom_data = scom_data & ~BIT64(7); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data.value); + scom_data.words.upper |= BIT32(7); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data.value); + scom_data.words.upper &= ~BIT32(7); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data.value); // 255 cache cycles PPE_WAIT_CORE_CYCLES(510); @@ -73,9 +73,9 @@ p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) do { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, quad), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, quad), scom_data.value); } - while((~scom_data) & BIT64(9)); + while((~scom_data.words.upper) & BIT32(9)); MARK_TRAP(SX_L2_STARTCLOCKS_REGION) @@ -90,21 +90,21 @@ p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, quad), 0); PK_TRACE("Start clock via CLK_REGION"); - scom_data = (CLK_START_CMD | CLK_THOLD_ALL | ((uint64_t)ex << SHIFT64(9))); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data); + scom_data.value = (CLK_START_CMD | CLK_THOLD_ALL | ((uint64_t)ex << SHIFT64(9))); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data.value); PK_TRACE("Polling for clocks starting via CPLT_STAT0[8]"); do { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, quad), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, quad), scom_data.value); } - while((~scom_data) & BIT64(8)); + while((~scom_data.words.upper) & BIT32(8)); PK_TRACE("Check L2 clock running via CLOCK_STAT_SL[8:9]"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), scom_data.value); - if (scom_data & ((uint64_t)ex << SHIFT64(9))) + if (scom_data.words.upper & (ex << SHIFT32(9))) { PK_TRACE_ERR("ERROR: L2 Clock Start Failed. HALT SGPE!"); SGPE_STOP_QUAD_ERROR_HANDLER(quad, SGPE_STOP_EXIT_L2_STARTCLK_FAILED); @@ -117,7 +117,20 @@ p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) // Cleaning up // ------------------------------- - /// @todo RTC166917 Check the Global Checkstop FIR +#if !EPM_P9_TUNING + + PK_TRACE("Check Global Xstop FIR of Cache Chiplet After Start L2 Clock"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_XFIR, quad), scom_data.value); + + if (scom_data.words.upper & BITS32(0, 27)) + { + PK_TRACE_ERR("Cache[%d] Chiplet Global Xstop FIR[%x] Detected After Start L2 Clock. HALT SGPE!", + quad, scom_data.words.upper); + SGPE_STOP_QUAD_ERROR_HANDLER(quad, SGPE_STOP_EXIT_START_L2_XSTOP_ERROR); + return; + } + +#endif #if NIMBUS_DD_LEVEL != 10 @@ -127,27 +140,27 @@ p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) #endif PK_TRACE("Set parital bad l2/l3 and stopped l2 pscom mask"); - scom_data = 0; + scom_data.value = 0; if ((~G_sgpe_stop_record.group.expg[quad]) & FST_EX_IN_QUAD) { - scom_data |= (PSCOM_MASK_EX0_L2 | PSCOM_MASK_EX0_L3); + scom_data.value |= (PSCOM_MASK_EX0_L2 | PSCOM_MASK_EX0_L3); } else if (((~ex) & FST_EX_IN_QUAD) && (G_sgpe_stop_record.state[quad].act_state_x0 >= LEVEL_EX_BASE)) { - scom_data |= PSCOM_MASK_EX0_L2; + scom_data.value |= PSCOM_MASK_EX0_L2; } if ((~G_sgpe_stop_record.group.expg[quad]) & SND_EX_IN_QUAD) { - scom_data |= (PSCOM_MASK_EX1_L2 | PSCOM_MASK_EX1_L3); + scom_data.value |= (PSCOM_MASK_EX1_L2 | PSCOM_MASK_EX1_L3); } else if (((~ex) & SND_EX_IN_QUAD) && (G_sgpe_stop_record.state[quad].act_state_x1 >= LEVEL_EX_BASE)) { - scom_data |= PSCOM_MASK_EX1_L2; + scom_data.value |= PSCOM_MASK_EX1_L2; } - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_RING_FENCE_MASK_LATCH, quad), scom_data); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_RING_FENCE_MASK_LATCH, quad), scom_data.value); } diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_sgpe_boot_cme.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_sgpe_boot_cme.c index da118509..65e8533e 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_sgpe_boot_cme.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_sgpe_boot_cme.c @@ -376,7 +376,6 @@ BootErrorCode_t boot_cme( uint16_t i_bootCme ) // the CME -- waiting until it is "ready" allows for every // thread to complete its initialization prior to the SGPE // routing interrupts (wakeup+PMCR) back to the CME. - // @todo RTC173279 GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS, (l_cmeIndex >> 1), (l_cmeIndex % 2)), l_dataReg); @@ -402,7 +401,7 @@ BootErrorCode_t boot_cme( uint16_t i_bootCme ) GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_EXCGCR, (l_cmeIndex / 2)), excgcr); } - // TODO #else + // #else RE-ENABLE STOP8 on DD22 #endif l_cmeRdyCnt++; 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 7ce6fdd2..30b4631a 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 @@ -65,13 +65,13 @@ p9_sgpe_ipc_pgpe_ctrl_stop_updates(ipc_msg_t* cmd, void* arg) G_sgpe_stop_record.wof.updates_cmd = cmd; // stop in process - if (G_sgpe_stop_record.wof.status_stop == STATUS_PROCESSING) + if (G_sgpe_stop_record.wof.status_stop & STATUS_STOP_PROCESSING) { // Note: response will be sent by stop threads when ongoing stop is completed G_sgpe_stop_record.wof.update_pgpe |= IPC_SGPE_PGPE_UPDATE_CTRL_ONGOING; } // sgpe idle - else if (G_sgpe_stop_record.wof.status_stop == STATUS_IDLE) + else { p9_sgpe_ack_pgpe_ctrl_stop_updates(); } @@ -181,7 +181,8 @@ p9_sgpe_ipc_pgpe_update_active_cores_poll_ack(const uint32_t type) if (G_sgpe_ipcmsg_update_cores.fields.return_active_cores != vector_active_cores) { - PK_TRACE_ERR("ERROR: SGPE Updates PGPE with Active Cores Bad Return List. HALT SGPE!"); + PK_TRACE_ERR("ERROR: SGPE Updates PGPE with Active Cores. ActiveCores ret=0x%x, exp.=0x%x. HALT SGPE!", + G_sgpe_ipcmsg_update_cores.fields.return_active_cores, vector_active_cores); PK_PANIC(SGPE_IPC_UPDATE_ACTIVE_CORE_BAD_LIST); } } @@ -269,19 +270,25 @@ p9_sgpe_ipc_pgpe_update_active_quads_poll_ack(const uint32_t type) void p9_sgpe_ipc_pgpe_suspend_stop(ipc_msg_t* cmd, void* arg) { - PK_TRACE_INF("IPC.PS: Get Suspend Stop IPC from PGPE"); - G_sgpe_stop_record.wof.suspend_cmd = cmd; g_oimr_override |= (BITS64(47, 2) | BITS64(50, 2)); + 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; + G_sgpe_stop_record.wof.suspend_act = msg->fields.command; + + PK_TRACE_INF("IPC.PS: Get Suspend Stop IPC with Action[%x] from PGPE", G_sgpe_stop_record.wof.suspend_act); + // stop in process - if (G_sgpe_stop_record.wof.status_stop == STATUS_PROCESSING) + if (G_sgpe_stop_record.wof.status_stop & STATUS_STOP_PROCESSING) { // Note: response will be sent by stop threads when suspension is completed - G_sgpe_stop_record.wof.status_stop = STATUS_SUSPENDING; + G_sgpe_stop_record.wof.status_stop |= STATUS_SUSPEND_PENDING; } // sgpe idle - else if (G_sgpe_stop_record.wof.status_stop == STATUS_IDLE) + else { p9_sgpe_stop_suspend_all_cmes(); } @@ -293,27 +300,33 @@ void p9_sgpe_stop_suspend_all_cmes() { uint32_t qloop = 0; - uint32_t xloop = 0; uint32_t cloop = 0; uint32_t cpayload_t3 = 0; - uint32_t cme_list = 0; + uint32_t req_list = 0; + uint32_t ack_list = 0; + uint32_t action = G_sgpe_stop_record.wof.suspend_act; + uint32_t ack_msg = (action << 8) | TYPE2_PAYLOAD_SUSPEND_SELECT_MASK | TYPE2_PAYLOAD_SUSPEND_ACK_MASK; for(qloop = 0; qloop < MAX_QUADS; qloop++) { - p9_sgpe_stop_suspend_db1_cme(qloop, BITS32(5, 3)); + req_list |= p9_sgpe_stop_suspend_db1_cme(qloop, ((action << SHIFT32(6)) | BIT32(7))); } - while (cme_list != 0xFFF00000) + PK_TRACE_INF("Requested Suspend on cores[%x] with action[%x]", req_list, action); + + while (ack_list != req_list) { - for(xloop = 0; xloop < MAX_EXES; xloop++) + for(cloop = 0; cloop < MAX_CORES; cloop++) { - for(cloop = 0; cloop < CORES_PER_EX; cloop++) + if ((~ack_list) & req_list & BIT32(cloop)) { - cpayload_t3 = in32(OCB_OPIT3CN(((xloop << 1) + cloop))); + cpayload_t3 = in32(OCB_OPIT3CN(cloop)); + PK_TRACE_INF("Read PIG from Core[%d] with payload[%x]", cloop, cpayload_t3); - if (cpayload_t3 == 0x780) + if (cpayload_t3 == ack_msg) { - cme_list |= BIT32(xloop); + ack_list |= BIT32(cloop); + PK_TRACE_INF("Acked Suspend from cores[%x] with message[%x]", ack_list, ack_msg); // set STOP OVERRIDE MODE/STOP ACTIVE MASK // to convert everything to stop1 @@ -322,17 +335,19 @@ p9_sgpe_stop_suspend_all_cmes() // shares processing code at CME, // and only want this done under suspend_stop // Note: avoid partial bad cme as sgpe sent pig - if (G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(((xloop << 1) + cloop))) + // only doing this when suspend all stop + if ((action == 0x7) && + (G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cloop))) { GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LMCR_OR, - (xloop >> 1), (xloop % 2)), BITS64(16, 2)); + (cloop >> 2), ((cloop & 2) >> 1)), BITS64(16, 2)); } } } } } - PK_TRACE_INF("IPC.PS: Ack Suspend Stop IPC to PGPE as STOP is now SUSPENDED"); + PK_TRACE_INF("IPC.PS: Ack Suspend Stop IPC to PGPE"); ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)(G_sgpe_stop_record.wof.suspend_cmd); @@ -340,5 +355,15 @@ p9_sgpe_stop_suspend_all_cmes() (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; + + G_sgpe_stop_record.wof.status_stop &= ~STATUS_SUSPEND_PENDING; + + if (action < 4) + { + G_sgpe_stop_record.wof.status_stop &= ~action; + } + else + { + G_sgpe_stop_record.wof.status_stop |= (action & 0x3); + } } 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 0a6cf2fb..b55abfd2 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 @@ -230,36 +230,38 @@ enum SGPE_WOF_ACTIVE_UPDATE_STATUS enum SGPE_SUSPEND_FUNCTION_STATUS { - STATUS_IDLE = 0, - STATUS_PROCESSING = 1, - STATUS_SUSPENDING = 2, - STATUS_SUSPENDED = 3 + STATUS_ENTRY_SUSPENDED = 1, + STATUS_EXIT_SUSPENDED = 2, + STATUS_SUSPEND_PENDING = 4, + STATUS_STOP_PROCESSING = 8 }; enum SGPE_STOP_VECTOR_INDEX { - VECTOR_BLOCKE = 0, //(core_save, quad_req, qswu_save, qex01) - VECTOR_BLOCKX = 1, //(core_save, quad_req, qswu_save, qex01) - VECTOR_ENTRY = 2, //(core_ipc, quad, qswu) - VECTOR_EXIT = 3, //(core, quad_ipc qswu) - VECTOR_ACTIVE = 4, //(core_ipc, quad_ipc, qswu_active) - VECTOR_CONFIG = 5, //(core, quad) - VECTOR_ERROR = 6, //( quad) + VECTOR_BLOCKE = 0, //(core_save, quad_req, qswu_save, req, ack) + VECTOR_BLOCKX = 1, //(core_save, quad_req, qswu_save, req, ack) + VECTOR_SUSPENDE = 2, //(core_save, qswu_save) + VECTOR_SUSPENDX = 3, //(core_save, qswu_save) + VECTOR_ENTRY = 4, //(core_ipc, quad, qswu) + VECTOR_EXIT = 5, //(core, quad_ipc qswu) + VECTOR_ACTIVE = 6, //(core_ipc, quad_ipc, qswu_active) + VECTOR_CONFIG = 7, //(core, quad) + VECTOR_ERROR = 8, //( quad) #if !DISABLE_STOP8 - VECTOR_PIGE = 7, //(core) - VECTOR_PIGX = 8, //(core) - VECTOR_PCWU = 9 //(core) - -#else - - VECTOR_RCLKE = 7, //(core_blocke, quad) - VECTOR_RCLKX = 8, //(core_blockx, quad) VECTOR_PIGE = 9, //(core) VECTOR_PIGX = 10,//(core) VECTOR_PCWU = 11 //(core) +#else + + VECTOR_RCLKE = 9, //(core_blocke, quad) + VECTOR_RCLKX = 10,//(core_blockx, quad) + VECTOR_PIGE = 11,//(core) + VECTOR_PIGX = 12,//(core) + VECTOR_PCWU = 13 //(core) + #endif }; @@ -295,21 +297,21 @@ typedef struct typedef struct { + uint32_t creq[2]; // 24 bits + uint32_t cack[2]; // 24 bits uint32_t expg[6]; // 2 bits uint32_t ex01[6]; // 2 bits - uint32_t qex0[2]; // 6 bits - uint32_t qex1[2]; // 6 bits - uint32_t qswu[5]; // 6 bits + uint32_t qswu[7]; // 6 bits #if !DISABLE_STOP8 - uint32_t quad[7]; // 6 bits - uint32_t core[10];// 24 bits + uint32_t quad[9]; // 6 bits + uint32_t core[12];// 24 bits #else - uint32_t quad[9]; // 6 bits - uint32_t core[12];// 24 bits + uint32_t quad[11]; // 6 bits + uint32_t core[14];// 24 bits #endif @@ -321,6 +323,8 @@ typedef struct uint8_t status_stop; // sgpe-pgpe interlock status(quad/core updates enable/disable) uint8_t update_pgpe; + // current/latest actions in suspend stop ipc + uint8_t suspend_act; ipc_msg_t* updates_cmd; ipc_msg_t* suspend_cmd; } sgpe_wof_t; @@ -399,7 +403,9 @@ void p9_sgpe_pig_type3_handler(void*, PkIrqId); void p9_sgpe_pig_type5_handler(void*, PkIrqId); void p9_sgpe_pig_type6_handler(void*, PkIrqId); void p9_sgpe_ipi3_low_handler(void*, PkIrqId); -void p9_sgpe_stop_suspend_db1_cme(uint32_t, uint32_t); + +/// Support Functions shared between suspend and block protocol +uint32_t p9_sgpe_stop_suspend_db1_cme(uint32_t, uint32_t); /// SGPE STOP Entry and Exit Prototypes void p9_sgpe_stop_init(); diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c index 0e6b68c9..078bd132 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c @@ -54,9 +54,6 @@ p9_sgpe_stop_entry() data64_t scom_data = {0}; data64_t temp_data = {0}; uint32_t flg2_data = 0; -#if DISABLE_STOP8 - ppm_pig_t pig = {0}; -#endif #if HW386311_NDD1_PBIE_RW_PTR_STOP11_FIX uint32_t spin = 0; #endif @@ -156,22 +153,7 @@ p9_sgpe_stop_entry() { G_sgpe_stop_record.group.quad[VECTOR_RCLKE] &= ~BIT32((qloop + RCLK_DIS_DONE_OFFSET)); G_sgpe_stop_record.group.quad[VECTOR_RCLKE] |= BIT32((qloop + QUAD_IN_STOP11_OFFSET)); - - // if during resonant clock disable, any exit occured, re-assert them, - // but we are going to complete the stop11 entry prior to process it - for(cloop = 0; cloop < CORES_PER_QUAD; cloop++) - { - cindex = (qloop << 2) + cloop; - - if (G_sgpe_stop_record.group.core[VECTOR_RCLKE] & BIT32(cindex)) - { - G_sgpe_stop_record.group.core[VECTOR_RCLKE] &= ~BIT32(cindex); - pig.fields.req_intr_payload = TYPE2_PAYLOAD_SOFTWARE_WAKEUP; - pig.fields.req_intr_type = PIG_TYPE3; - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(PPM_PIG, cindex), pig.value); - } - } - + G_sgpe_stop_record.group.core[VECTOR_RCLKE] &= ~BITS32((qloop << 2), 4); G_sgpe_stop_record.group.quad[VECTOR_ENTRY] |= BIT32(qloop); ocb_qssr_t qssr = {0}; @@ -189,6 +171,8 @@ p9_sgpe_stop_entry() { // from this point on, only process wakeup when stop11 is entered G_sgpe_stop_record.group.quad[VECTOR_RCLKE] |= BIT32((qloop + RCLK_DIS_REQ_OFFSET)); + // establish mask to ignore the wakeup while in rclk disable + G_sgpe_stop_record.group.core[VECTOR_RCLKE] |= BITS32((qloop << 2), 4); // assume ex0 core0 is good cindex = (qloop << 2); @@ -1147,7 +1131,6 @@ p9_sgpe_stop_entry() // Note: Stop11 will lose all the fences so here needs to assert them GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_OR, qloop), CLK_REGION_ALL); - PK_TRACE_INF("SE.11D: Cache Clock Stopped"); PK_TRACE("Gate the PCBMux request so scanning doesn't cause random requests"); @@ -1363,14 +1346,11 @@ p9_sgpe_stop_entry() #if !SKIP_IPC - /// @todo RTC166577 - /// this block can be done as early as after stop cache clocks if ((in32(OCB_OCCS2) & BIT32(PGPE_ACTIVE)) && G_sgpe_stop_record.wof.update_pgpe != IPC_SGPE_PGPE_UPDATE_PGPE_HALTED && G_sgpe_stop_record.group.quad[VECTOR_ENTRY]) { // Note: if all quads aborted on l3 purge, the quad list will be 0s; - p9_sgpe_ipc_pgpe_update_active_quads(UPDATE_ACTIVE_QUADS_TYPE_ENTRY, UPDATE_ACTIVE_QUADS_ENTRY_TYPE_DONE); 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); diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_threads.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_threads.c index b13c35cb..fc2f72b9 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_threads.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_threads.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -38,7 +38,7 @@ p9_sgpe_stop_exit_thread(void* arg) // Thread goes to sleep pk_semaphore_pend(&(G_sgpe_stop_record.sem[1]), PK_WAIT_FOREVER); - G_sgpe_stop_record.wof.status_stop = STATUS_PROCESSING; + G_sgpe_stop_record.wof.status_stop |= STATUS_STOP_PROCESSING; wrteei(1); // The actual exit sequence @@ -46,34 +46,25 @@ p9_sgpe_stop_exit_thread(void* arg) if (!G_sgpe_stop_record.fit.entry_pending) { + G_sgpe_stop_record.wof.status_stop &= ~STATUS_STOP_PROCESSING; #if !SKIP_IPC - if (G_sgpe_stop_record.wof.status_stop == STATUS_SUSPENDING) + if (G_sgpe_stop_record.wof.status_stop & STATUS_SUSPEND_PENDING) { p9_sgpe_stop_suspend_all_cmes(); } - else if (G_sgpe_stop_record.wof.status_stop != STATUS_SUSPENDED) - { - G_sgpe_stop_record.wof.status_stop = STATUS_IDLE; -#endif - - if (G_sgpe_stop_record.wof.update_pgpe & - IPC_SGPE_PGPE_UPDATE_CTRL_ONGOING) - { - p9_sgpe_ack_pgpe_ctrl_stop_updates(); - } - - PK_TRACE_INF("Setup: Exit Done,no Entry Request.Enable Type2/3/5/6 Interrupt"); - g_oimr_override &= ~(BITS64(47, 2) | BITS64(50, 2)); - pk_irq_vec_restore(&ctx); -#if !SKIP_IPC +#endif + if (G_sgpe_stop_record.wof.update_pgpe & IPC_SGPE_PGPE_UPDATE_CTRL_ONGOING) + { + p9_sgpe_ack_pgpe_ctrl_stop_updates(); } -#endif - + PK_TRACE_INF("Setup: Exit Done,no Entry Request.Enable Type2/3/5/6 Interrupt"); + g_oimr_override &= ~(BITS64(47, 2) | BITS64(50, 2)); + pk_irq_vec_restore(&ctx); } } } @@ -90,40 +81,31 @@ p9_sgpe_stop_enter_thread(void* arg) // Thread goes to sleep pk_semaphore_pend(&(G_sgpe_stop_record.sem[0]), PK_WAIT_FOREVER); - G_sgpe_stop_record.wof.status_stop = STATUS_PROCESSING; + G_sgpe_stop_record.wof.status_stop |= STATUS_STOP_PROCESSING; wrteei(1); // The actual entry sequence p9_sgpe_stop_entry(); + G_sgpe_stop_record.fit.entry_pending = 0; + G_sgpe_stop_record.wof.status_stop &= ~STATUS_STOP_PROCESSING; + #if !SKIP_IPC - if (G_sgpe_stop_record.wof.status_stop == STATUS_SUSPENDING) + if (G_sgpe_stop_record.wof.status_stop & STATUS_SUSPEND_PENDING) { p9_sgpe_stop_suspend_all_cmes(); } - else if (G_sgpe_stop_record.wof.status_stop != STATUS_SUSPENDED) - { - G_sgpe_stop_record.wof.status_stop = STATUS_IDLE; #endif - if (G_sgpe_stop_record.wof.update_pgpe & - IPC_SGPE_PGPE_UPDATE_CTRL_ONGOING) - { - p9_sgpe_ack_pgpe_ctrl_stop_updates(); - } - - G_sgpe_stop_record.fit.entry_pending = 0; - PK_TRACE_INF("Setup: Entry done. Enable Type2/3/5/6 Interrupt"); - g_oimr_override &= ~(BITS64(47, 2) | BITS64(50, 2)); - pk_irq_vec_restore(&ctx); - -#if !SKIP_IPC - + if (G_sgpe_stop_record.wof.update_pgpe & IPC_SGPE_PGPE_UPDATE_CTRL_ONGOING) + { + p9_sgpe_ack_pgpe_ctrl_stop_updates(); } -#endif - + PK_TRACE_INF("Setup: Entry done. Enable Type2/3/5/6 Interrupt"); + g_oimr_override &= ~(BITS64(47, 2) | BITS64(50, 2)); + pk_irq_vec_restore(&ctx); } } diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h index f544d168..c4206505 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -44,8 +44,6 @@ // -------------------- -// @todo RTC 161182 - #if NIMBUS_DD_LEVEL == 10 #define HW386311_NDD1_PBIE_RW_PTR_STOP11_FIX 1 #define HW388878_NDD1_VCS_POWER_ON_IN_CHIPLET_RESET_FIX 1 diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/sgpe_panic_codes.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/sgpe_panic_codes.h index a6f46875..d4dd1320 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/sgpe_panic_codes.h +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/sgpe_panic_codes.h @@ -70,7 +70,7 @@ SGPE_STOP_EXIT_L2_STARTCLK_FAILED = 0x1d07, SGPE_STOP_EXIT_EQ_STARTCLK_FAILED = 0x1d08, SGPE_STOP_EXIT_STARTCLK_XSTOP_ERROR = 0x1d09, SGPE_STOP_EXIT_SCOM_RES_XSTOP_ERROR = 0x1d0a, -//_UNUSED_1d0d = 0x1d0d, +SGPE_STOP_EXIT_START_L2_XSTOP_ERROR = 0x1d0d, //_UNUSED_1d1c = 0x1d1c, //_UNUSED_1d1d = 0x1d1d, //_UNUSED_1d1e = 0x1d1e, @@ -98,7 +98,7 @@ SGPE_STOP_EXIT_VCS_STARTCLK_FAILED = 0x1f01, // NDD1 SGPE_STOP_EXIT_FUSE_SCAN_HEADER_ERR = 0x1f02, // NDD1 SGPE_STOP_EXIT_PBRW_SCAN_HEADER_ERR = 0x1f03, // NDD1 SGPE_STOP_ENTRY_PBRW_SCAN_HEADER_ERR = 0x1f04, // NDD1 -SGPE_PIG_RESCLK_CME_HANDSHAKE_BROKEN = 0x1f05, // NDD2 +//_UNUSED_1f05 = 0x1f05, //_UNUSED_1f06 = 0x1f06, //_UNUSED_1f07 = 0x1f07, //_UNUSED_1f08 = 0x1f08, -- cgit v1.2.1