diff options
| author | Yue Du <daviddu@us.ibm.com> | 2017-01-22 00:02:26 -0600 |
|---|---|---|
| committer | Joshua Hunsberger <jahunsbe@us.ibm.com> | 2017-10-23 18:00:49 -0500 |
| commit | bed4c8cd7e1a9338f631426aeb3e19451b0bc641 (patch) | |
| tree | 3959e6e1e4b11bc0e9d146c2fb1f95e3463d71aa | |
| parent | ffa811767e629eb9a53f85d6c498ab1505fa8861 (diff) | |
| download | talos-hcode-bed4c8cd7e1a9338f631426aeb3e19451b0bc641.tar.gz talos-hcode-bed4c8cd7e1a9338f631426aeb3e19451b0bc641.zip | |
STOP: block wakeup (+ block entry since patch 15)
Change-Id: I6636b7f77842e9a5e07fffa0f908fb4d46e7d763
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35205
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: BRIAN D. VICTOR <brian.d.victor1@ibm.com>
Reviewed-by: Brian T. Vanderpool <vanderp@us.ibm.com>
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
18 files changed, 737 insertions, 280 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 new file mode 100644 index 00000000..fb7fb201 --- /dev/null +++ b/import/chips/p9/common/pmlib/include/stop_sgpe_cme_api.h @@ -0,0 +1,65 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/common/pmlib/include/stop_sgpe_cme_api.h $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2015,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __STOP_SGPE_CME_API_H__ +#define __STOP_SGPE_CME_API_H__ + + +enum SGPE_STOP_IRQ_PAYLOAD_MASKS +{ + + TYPE2_PAYLOAD_SUSPEND_OP_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_HARDWARE_WAKEUP = 0x800, + TYPE2_PAYLOAD_EXIT_EVENT = 0xC00, + TYPE2_PAYLOAD_STOP_LEVEL = 0x00F, + TYPE3_PAYLOAD_EXIT_EVENT = 0xC00, + TYPE6_PAYLOAD_EXIT_EVENT = 0x00F +}; + + +/// PIG TYPEs used by CME +enum CME_STOP_PIG_TYPES +{ + PIG_TYPE2 = 2, + PIG_TYPE3 = 3 +}; + +/// 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, + MSGID_DB1_WAKEUP_GRANTED = 0x04, + MSGID_DB1_SUSPEND_STOP_ENTRIES = 0x05, + MSGID_DB1_SUSPEND_STOP_EXITS = 0x06, + MSGID_DB1_SUSPEND_STOP_ENTRIES_EXITS = 0x07 +}; + +#endif /* __STOP_SGPE_CME_API_H__ */ 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 new file mode 100644 index 00000000..9bd951fc --- /dev/null +++ b/import/chips/p9/common/pmlib/include/wof_sgpe_pgpe_api.h @@ -0,0 +1,157 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/common/pmlib/include/wof_sgpe_pgpe_api.h $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2016,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __IPC_MESSAGES_H__ +#define __IPC_MESSAGES_H__ + +//--------------- +// IPC from SGPE to PGPE +//--------------- +enum MESSAGE_ID_IPI2HI_SGPE_PGPE +{ + MSGID_SGPE_PGPE_UPDATE_ACTIVE_CORES = 0x8, + MSGID_SGPE_PGPE_UPDATE_ACTIVE_QUADS = 0x9, + MSGID_SGPE_PGPE_SUSPEND_PSTATES = 0x10 +}; + +//--------------- +// IPC from PGPE to SGPE +//--------------- +enum MESSAGE_ID_IPI3HI_PGPE_SGPE +{ + MSGID_PGPE_SGPE_INVALID = 0, + MSGID_PGPE_SGPE_CONTROL_STOP_UPDATES = 1, + MSGID_PGPE_SGPE_SUSPEND_STOP = 2 +}; + +enum CTRL_STOP_UPDATES_ACTION +{ + CTRL_STOP_UPDT_RESERVED0 = 0x0, + CTRL_STOP_UPDT_ENABLE_CORE = 0x1, + CTRL_STOP_UPDT_ENABLE_QUAD = 0x2, + CTRL_STOP_UPDT_ENABLE_CORE_QUAD = 0x3, + CTRL_STOP_UPDT_RESERVED1 = 0x4, + CTRL_STOP_UPDT_DISABLE_CORE = 0x5, + CTRL_STOP_UPDT_DISABLE_QUAD = 0x6, + CTRL_STOP_UPDT_DISABLE_CORE_QUAD = 0x7 +}; + +enum UPDATE_ACTIVE_TYPES +{ + UPDATE_ACTIVE_TYPE_ENTRY = 0, + UPDATE_ACTIVE_TYPE_EXIT = 1 +}; + +enum IPC_SGPE_PGPE_RETURN_CODES +{ + IPC_SGPE_PGPE_RC_NULL = 0x00, + IPC_SGPE_PGPE_RC_SUCCESS = 0x01, + IPC_SGPE_PGPE_RC_REQ_WHILE_PENDING_ACK = 0x10, + IPC_SGPE_PGPE_RC_PM_COMPLEX_SUSPEND = 0x11 +}; + + +// Sgpe to Pgpe IPC message format + +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; + } fields; +} ipcmsg_s2p_update_active_cores_t; + +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 requested_quads : 6; + uint32_t reserved0 : 2; + uint32_t return_active_quads : 6; + uint32_t reserved1 : 2; + uint32_t pad : 32; + } fields; +} ipcmsg_s2p_update_active_quads_t; + +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 requested_quads : 6; + uint32_t reserved0 : 2; + uint32_t return_active_quads : 6; + uint32_t reserved1 : 2; + uint32_t pad : 32; + } fields; +} ipcmsg_s2p_suspend_pstate_t; + + +// Pgpe to Sgpe IPC message format + +typedef union +{ + uint64_t value; + struct + { + uint32_t msg_num : 8; + uint32_t return_code : 8; + uint32_t action : 8; + uint32_t pad : 8; + uint32_t active_quads : 6; + uint32_t reserved : 2; + uint32_t active_cores : 24; + } fields; +} ipcmsg_p2s_ctrl_stop_updates_t; + +typedef union +{ + uint64_t value; + struct + { + uint32_t msg_num : 8; + uint32_t return_code : 8; + uint32_t reserved0 : 16; + uint32_t reserved1 : 32; + } fields; +} ipcmsg_p2s_suspend_stop_t; + + +#endif // __IPC_MESSAGES_H__ diff --git a/import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h b/import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h index 79e1f2ee..e84be9fe 100644 --- a/import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h +++ b/import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h @@ -143,6 +143,31 @@ namespace p9hcd { #endif +//Enum form of CME FLAGs. +enum PM_CME_CMEFLG_DEFS +{ + CME_STOP_READY = 0, + CME_PMCR_READY = 1, + CME_QMGR_READY = 2, + CME_QMGR_MASTER = 3, + CME_RCLK_OPERABLE = 4, + CME_IVRM_OPERABLE = 5, + CME_VDM_OPERABLE = 6, + CME_OCC_HB_SAFE_MODE = 7, + CME_BLOCK_STOP_EXIT_ENABLED_C0 = 8, + CME_BLOCK_STOP_EXIT_ENABLED_C1 = 9, + CME_BLOCK_STOP_ENTRY_ENABLED_C0 = 10, + CME_BLOCK_STOP_ENTRY_ENABLED_C1 = 11, + // Reserve 12:24 + CME_FREQ_UPDATE_DISABLE = 25, + CME_EX_ID = 26, + CME_SIBLING_FUNCTIONAL = 27, + CME_STOP_ENTRY_FIRST_C0 = 28, + CME_STOP_ENTRY_FIRST_C1 = 29, + CME_CORE0_GOOD = 30, + CME_CORE1_GOOD = 31 +}; + //Enum form of OCC FLAGs. enum PM_GPE_OCCFLG_DEFS { @@ -152,10 +177,10 @@ enum PM_GPE_OCCFLG_DEFS PGPE_SAFE_MODE = 2, PM_COMPLEX_SUSPEND = 3, SGPE_ACTIVE = 8, - SGPE_IGNORE_STOP_EXITS = 9, - SGPE_IGNORE_STOP_ENTRY = 10, - SGPE_STOP_EXITS_IGNORED = 11, - SGPE_STOP_ENTRIES_IGNORED = 12, + SGPE_IGNORE_STOP_CONTROL = 9, + SGPE_IGNORE_STOP_ACTION = 10, + SGPE_IGNORE_STOP_EXITS = 11, + SGPE_IGNORE_STOP_ENTRIES = 12, SGPE_24_7_ACTIVATE = 14, SGPE_24_7_ACTIVE = 15, PIB_I2C_MASTER_ENGINE_1_LOCK_BIT0 = 16, //BIT0 ored BIT1 gives the field diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h index 63da774d..4f7165c2 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h @@ -34,6 +34,7 @@ #include "ppehw_common.h" #include "cmehw_common.h" #include "cmehw_interrupts.h" +#include "stop_sgpe_cme_api.h" #include "cme_register_addresses.h" #include "ppm_register_addresses.h" @@ -44,6 +45,7 @@ #include "cppm_firmware_registers.h" #include "p9_hcode_image_defines.H" +#include "p9_pm_hcd_flags.h" #include "p9_stop_common.h" #include "p9_cme.h" @@ -142,43 +144,26 @@ -/// CME STOP IRQs with shorter names -enum CME_STOP_IRQ_SHORT_NAME -{ - IRQ_DB1_C0 = CMEHW_IRQ_DOORBELL1_C0, - IRQ_DB1_C1 = CMEHW_IRQ_DOORBELL1_C1, - IRQ_DB2_C0 = CMEHW_IRQ_DOORBELL2_C0, - IRQ_DB2_C1 = CMEHW_IRQ_DOORBELL2_C1, - IRQ_STOP_C0 = CMEHW_IRQ_PC_PM_STATE_ACTIVE_C0, - IRQ_STOP_C1 = CMEHW_IRQ_PC_PM_STATE_ACTIVE_C1, - IRQ_PC_C0 = CMEHW_IRQ_PC_INTR_PENDING_C0, - IRQ_PC_C1 = CMEHW_IRQ_PC_INTR_PENDING_C1, - IRQ_RWU_C0 = CMEHW_IRQ_REG_WAKEUP_C0, - IRQ_RWU_C1 = CMEHW_IRQ_REG_WAKEUP_C1, - IRQ_SWU_C0 = CMEHW_IRQ_SPECIAL_WAKEUP_C0, - IRQ_SWU_C1 = CMEHW_IRQ_SPECIAL_WAKEUP_C1 -}; - enum CME_IRQ_VECTORS { // if auto mask eimr.spwu else never mask eimr.spwu #if SPWU_AUTO - IRQ_VEC_WAKE_C0 = BIT64(12) | BIT64(14) | BIT64(16), - IRQ_VEC_WAKE_C1 = BIT64(13) | BIT64(15) | BIT64(17), + IRQ_VEC_WAKE_C0 = BIT64(12) | BIT64(14) | BIT64(16), + IRQ_VEC_WAKE_C1 = BIT64(13) | BIT64(15) | BIT64(17), #else - IRQ_VEC_WAKE_C0 = BIT64(12) | BIT64(16), - IRQ_VEC_WAKE_C1 = BIT64(13) | BIT64(17), + IRQ_VEC_WAKE_C0 = BIT64(12) | BIT64(16), + IRQ_VEC_WAKE_C1 = BIT64(13) | BIT64(17), #endif - IRQ_VEC_SGPE_C0 = BIT64(12) | BIT64(20), - IRQ_VEC_SGPE_C1 = BIT64(13) | BIT64(21), - IRQ_VEC_PCWU_C0 = BIT64(12), - IRQ_VEC_PCWU_C1 = BIT64(13), - IRQ_VEC_SPWU_C0 = BIT64(14), - IRQ_VEC_SPWU_C1 = BIT64(15), - IRQ_VEC_RGWU_C0 = BIT64(16), - IRQ_VEC_RGWU_C1 = BIT64(17), - IRQ_VEC_STOP_C0 = BIT64(20), - IRQ_VEC_STOP_C1 = BIT64(21) + IRQ_VEC_SGPE_C0 = BIT64(12) | BIT64(20), + IRQ_VEC_SGPE_C1 = BIT64(13) | BIT64(21), + IRQ_VEC_PCWU_C0 = BIT64(12), + IRQ_VEC_PCWU_C1 = BIT64(13), + IRQ_VEC_SPWU_C0 = BIT64(14), + IRQ_VEC_SPWU_C1 = BIT64(15), + IRQ_VEC_RGWU_C0 = BIT64(16), + IRQ_VEC_RGWU_C1 = BIT64(17), + IRQ_VEC_STOP_C0 = BIT64(20), + IRQ_VEC_STOP_C1 = BIT64(21) }; enum CME_STOP_STATE_HISTORY_VECTORS @@ -197,41 +182,6 @@ enum CME_STOP_STATE_HISTORY_VECTORS SSH_ACT_LV5_COMPLETE = (SSH_ACT_LEVEL_UPDATE | BIT32(9) | BIT32(11) | SSH_TRANS_SGPE) }; -enum CME_STOP_FLAGS -{ - FLAG_STOP_READY = BIT32(0), - FLAG_BLOCK_WKUP_C0 = BIT32(8), - FLAG_BLOCK_WKUP_C1 = BIT32(9), - FLAG_EX1_INDICATOR = BIT32(26), - FLAG_ENTRY_FIRST_C0 = BIT32(28), - FLAG_ENTRY_FIRST_C1 = BIT32(29), - FLAG_PARTIAL_GOOD_C0 = BIT32(30), - FLAG_PARTIAL_GOOD_C1 = BIT32(31) -}; - -enum ATTR_CME_MODE_FLAGS -{ - MAP_3_TO_2 = BIT32(0), - MAP_4_TO_2 = BIT32(1), - MAP_5_TO_4 = BIT32(2), - MAP_8_TO_5 = BIT32(3), - MAP_11_TO_8 = BIT32(4), - SKIP_CORE_POWEROFF = BIT32(31) -}; - -enum CME_STOP_PIG_TYPES -{ - PIG_TYPE2 = 2, - PIG_TYPE3 = 3 -}; - -enum CME_DOORBELL_MESSAGE_ID -{ - DB1_WKUP_GRANTED = 0x01, - DB2_BLOCK_WKUP_ENTRY = 0x01, - DB2_BLOCK_WKUP_EXIT = 0x02 -}; - enum CME_STOP_SRR1 { MOST_STATE_LOSS = 3, @@ -240,6 +190,8 @@ enum CME_STOP_SRR1 }; #if TEST_ONLY_BCE_IRR +#define FLAG_BCE_IRR_ENABLE BIT32(18) + typedef struct { uint32_t cmeid; @@ -280,6 +232,8 @@ typedef struct uint32_t core_blockpc; // core in block wakeup mode, can be used as core select in scom address or data uint32_t core_blockwu; + // core in block entry mode, can be used as core select in scom address or data + uint32_t core_blockey; // core in special wakeup, can be used as core select in scom address or data uint32_t core_in_spwu; PkSemaphore sem[2]; 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 da444382..6d360416 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 @@ -28,6 +28,8 @@ #include "p9_cme_irq.h" extern CmeStopRecord G_cme_stop_record; +extern CmeRecord G_cme_record; + void @@ -142,7 +144,12 @@ p9_cme_stop_spwu_handler(void* arg, PkIrqId irq) // Core is now out of spwu, allow pm_active G_cme_stop_record.core_in_spwu &= ~core_mask; - g_eimr_override &= ~(IRQ_VEC_STOP_C0 >> core_index); + + // if in block entry mode, do not release the mask + if (!(G_cme_stop_record.core_blockey & core_mask)) + { + g_eimr_override &= ~(IRQ_VEC_STOP_C0 >> core_index); + } } } } @@ -190,24 +197,17 @@ p9_cme_stop_enter_handler(void* arg, PkIrqId irq) } void -p9_cme_stop_db1_handler(void* arg, PkIrqId irq) -{ - PkMachineContext ctx; - MARK_TRAP(STOP_DB1_HANDLER) - PK_TRACE_DBG("DB1 Handler Trigger %d", irq); - pk_irq_vec_restore(&ctx); -} - -void p9_cme_stop_db2_handler(void* arg, PkIrqId irq) { PkMachineContext ctx; + MARK_TRAP(STOP_DB2_HANDLER) PK_TRACE_DBG("DB2 Handler Trigger %d", irq); // read and clear doorbell uint32_t core = (in32(CME_LCL_EISR) & BITS32(18, 2)) >> SHIFT32(19); CME_PUTSCOM_NOP(CPPM_CMEDB2, core, 0); + out32(CME_LCL_EISR_CLR, BITS32(18, 2)); // unmask pc interrupt pending to wakeup that is still pending core &= (~(G_cme_stop_record.core_running)); @@ -216,3 +216,90 @@ p9_cme_stop_db2_handler(void* arg, PkIrqId irq) pk_irq_vec_restore(&ctx); } + +void +p9_cme_stop_db1_handler(void* arg, PkIrqId irq) +{ + PkMachineContext ctx; + cppm_cmedb1_t db1 = {0}; + ppm_pig_t pig = {0}; + uint32_t core = 0; + uint32_t suspend_ack = 0; + + MARK_TRAP(STOP_DB1_HANDLER) + PK_TRACE_DBG("DB1 Handler Trigger %d", irq); + + // Suspend DB should only come from the first good core + if (G_cme_record.core_enabled & CME_MASK_C0) + { + CME_GETSCOM(CPPM_CMEDB1, CME_MASK_C0, db1.value); + CME_PUTSCOM_NOP(CPPM_CMEDB1, CME_MASK_C0, 0); + out32_sh(CME_LCL_EISR_CLR, BIT64SH(40)); + core = CME_MASK_C0; + } + else if (G_cme_record.core_enabled & CME_MASK_C1) + { + CME_GETSCOM(CPPM_CMEDB1, CME_MASK_C1, db1.value); + CME_PUTSCOM_NOP(CPPM_CMEDB1, CME_MASK_C1, 0); + out32_sh(CME_LCL_EISR_CLR, BIT64SH(41)); + core = CME_MASK_C1; + } + + // block msgs + if ((db1.fields.cme_message_numbern > 0x4) && + (db1.fields.cme_message_numbern < 0x8)) + { + suspend_ack = 1; + + // exit + if (db1.fields.cme_message_numbern & 0x2) + { + G_cme_stop_record.core_blockwu |= CME_MASK_BC; + g_eimr_override |= IRQ_VEC_WAKE_C0 | IRQ_VEC_WAKE_C1; + out32(CME_LCL_SICR_OR, BITS32(2, 2)); + out32(CME_LCL_FLAGS_OR, BITS32(8, 2)); + } + + // entry + if (db1.fields.cme_message_numbern & 0x1) + { + G_cme_stop_record.core_blockey |= CME_MASK_BC; + g_eimr_override |= IRQ_VEC_STOP_C0 | IRQ_VEC_STOP_C1; + out32(CME_LCL_FLAGS_OR, BITS32(10, 2)); + } + } + // unblock msgs + else if ((db1.fields.cme_message_numbern < 0x4) && + (db1.fields.cme_message_numbern > 0)) + { + suspend_ack = 1; + + // exit + if (db1.fields.cme_message_numbern & 0x2) + { + G_cme_stop_record.core_blockwu &= ~CME_MASK_BC; + g_eimr_override &= ~(IRQ_VEC_WAKE_C0 | IRQ_VEC_WAKE_C1); + out32(CME_LCL_SICR_CLR, BITS32(2, 2)); + out32(CME_LCL_FLAGS_CLR, BITS32(8, 2)); + } + + // entry + if (db1.fields.cme_message_numbern & 0x1) + { + G_cme_stop_record.core_blockey &= ~CME_MASK_BC; + g_eimr_override &= ~(IRQ_VEC_STOP_C0 | IRQ_VEC_STOP_C1); + out32(CME_LCL_FLAGS_CLR, BITS32(10, 2)); + } + } + + if (suspend_ack) + { + pig.fields.req_intr_payload = db1.fields.cme_message_numbern; + pig.fields.req_intr_payload = pig.fields.req_intr_payload << 8; + pig.fields.req_intr_payload |= 0x080; // set bit 4 for ack package + pig.fields.req_intr_type = PIG_TYPE2; + CME_PUTSCOM_NOP(PPM_PIG, core, pig.value); + } + + pk_irq_vec_restore(&ctx); +} diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_ipc_handlers.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_ipc_handlers.c index 0f0048c7..3f78819f 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_ipc_handlers.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_ipc_handlers.c @@ -29,7 +29,7 @@ #include "ipc_async_cmd.h" #include "p9_pgpe_header.h" #include "pstate_pgpe_occ_api.h" -#include "ipc_messages.h" +#include "wof_sgpe_pgpe_api.h" #include "occhw_shared_data.h" #include "p9_pgpe_ipc_handlers.h" #include "p9_pgpe_pstate.h" @@ -354,7 +354,7 @@ void p9_pgpe_ipc_sgpe_suspend_pstates(ipc_msg_t* cmd, void* arg) ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)cmd; ipcmsg_s2p_suspend_pstate_t* args = (ipcmsg_s2p_suspend_pstate_t*)async_cmd->cmd_data; - args->fields.return_code = SGPE_PGPE_RC_REQ_WHILE_PENDING_ACK; + args->fields.return_code = IPC_SGPE_PGPE_RC_REQ_WHILE_PENDING_ACK; ipc_send_rsp(cmd, IPC_RC_SUCCESS); } @@ -388,7 +388,7 @@ void p9_pgpe_ipc_sgpe_updt_active_cores(ipc_msg_t* cmd, void* arg) ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)cmd; ipcmsg_s2p_update_active_cores_t* args = (ipcmsg_s2p_update_active_cores_t*)async_cmd->cmd_data; - args->fields.return_code = SGPE_PGPE_RC_REQ_WHILE_PENDING_ACK; + args->fields.return_code = IPC_SGPE_PGPE_RC_REQ_WHILE_PENDING_ACK; ipc_send_rsp(cmd, IPC_RC_SUCCESS); } @@ -425,7 +425,7 @@ void p9_pgpe_ipc_sgpe_updt_active_quads(ipc_msg_t* cmd, void* arg) ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)cmd; ipcmsg_s2p_update_active_quads_t* args = (ipcmsg_s2p_update_active_quads_t*)async_cmd->cmd_data; - args->fields.return_code = SGPE_PGPE_RC_REQ_WHILE_PENDING_ACK; + args->fields.return_code = IPC_SGPE_PGPE_RC_REQ_WHILE_PENDING_ACK; ipc_send_rsp(cmd, IPC_RC_SUCCESS); PK_TRACE_INF("SGPE_UPDT_QUADS: %d %d\n", G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_QUADS_UPDT].pending_processing, diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c index 2af3d892..e195d594 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c @@ -31,7 +31,7 @@ #include "p9_dd1_doorbell_wr.h" #include "p9_pgpe_pstate.h" #include "pstate_pgpe_occ_api.h" -#include "ipc_messages.h" +#include "wof_sgpe_pgpe_api.h" #include "p9_pgpe_header.h" // @@ -401,7 +401,7 @@ void p9_pgpe_pstate_process_quad_exit(uint32_t quadsAffected) //ACK back to SGPE ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_QUADS_UPDT].cmd; ipcmsg_s2p_update_active_quads_t* args = (ipcmsg_s2p_update_active_quads_t*)async_cmd->cmd_data; - args->fields.return_code = SGPE_PGPE_IPC_RC_SUCCESS; + args->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_QUADS_UPDT].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_QUADS_UPDT].cmd, IPC_RC_SUCCESS); diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.h index 04294c16..34412e71 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.h @@ -29,7 +29,7 @@ #include "ipc_api.h" #include "ipc_async_cmd.h" #include "pstate_pgpe_occ_api.h" -#include "ipc_messages.h" +#include "wof_sgpe_pgpe_api.h" #include "p9_pgpe_header.h" 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 44b82a09..3baf0502 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 @@ -30,7 +30,7 @@ #include "ipc_async_cmd.h" #include "p9_pgpe_gppb.h" #include "pstate_pgpe_occ_api.h" -#include "ipc_messages.h" +#include "wof_sgpe_pgpe_api.h" #include "p9_dd1_doorbell_wr.h" #include "avs_driver.h" diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_process_requests.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_process_requests.c index 98868a9a..cae06ac5 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_process_requests.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_process_requests.c @@ -26,7 +26,7 @@ #include "gpehw_common.h" #include "p9_pgpe_pstate.h" #include "pstate_pgpe_occ_api.h" -#include "ipc_messages.h" +#include "wof_sgpe_pgpe_api.h" #include "ipc_api.h" #include "ipc_async_cmd.h" #include "p9_pgpe_header.h" @@ -198,7 +198,7 @@ void p9_pgpe_process_sgpe_updt_active_cores() if (G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPENDED) { PK_TRACE_DBG("PROCTH: PM Suspended\n"); - args->fields.return_code = SGPE_PGPE_RC_PM_COMPLEX_SUSPEND; + args->fields.return_code = IPC_SGPE_PGPE_RC_PM_COMPLEX_SUSPEND; 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); } @@ -228,7 +228,7 @@ void p9_pgpe_process_sgpe_updt_active_cores() if (args->fields.update_type == UPDATE_ACTIVE_TYPE_ENTRY) { PK_TRACE_DBG("PROCTH: Core Entry ACK back to SGPE\n"); - args->fields.return_code = SGPE_PGPE_IPC_RC_SUCCESS; + 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); } @@ -254,7 +254,7 @@ void p9_pgpe_process_sgpe_updt_active_quads() G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPEND_PENDING || G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) { - args->fields.return_code = SGPE_PGPE_RC_PM_COMPLEX_SUSPEND; + args->fields.return_code = IPC_SGPE_PGPE_RC_PM_COMPLEX_SUSPEND; G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_QUADS_UPDT].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_QUADS_UPDT].cmd, IPC_RC_SUCCESS); } @@ -269,7 +269,7 @@ void p9_pgpe_process_sgpe_updt_active_quads() G_pgpe_pstate_record.pReqActQuads->fields.requested_active_quads &= (~(args->fields.requested_quads << 2)); //For Entry ACK back to SGPE right away - args->fields.return_code = SGPE_PGPE_IPC_RC_SUCCESS; + args->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_QUADS_UPDT].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_QUADS_UPDT].cmd, IPC_RC_SUCCESS); PK_TRACE_DBG("PROCTH: Q Updt Entry, ACK sent to SGPE\n"); @@ -396,7 +396,7 @@ void p9_pgpe_process_sgpe_suspend_pstates() G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE ) { PK_TRACE_DBG("PROCTH: Susp Pst while SUSPEND/SAFE\n"); - args->fields.return_code = SGPE_PGPE_RC_PM_COMPLEX_SUSPEND; + args->fields.return_code = IPC_SGPE_PGPE_RC_PM_COMPLEX_SUSPEND; G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_SUSPEND_PSTATES].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_SUSPEND_PSTATES].cmd, IPC_RC_SUCCESS); } @@ -404,7 +404,7 @@ void p9_pgpe_process_sgpe_suspend_pstates() G_pgpe_pstate_record.pstatesStatus == PSTATE_STOPPED || G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE) { - args->fields.return_code = SGPE_PGPE_IPC_RC_SUCCESS; + args->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_SUSPEND_PSTATES].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_SUSPEND_PSTATES].cmd, IPC_RC_SUCCESS); @@ -544,7 +544,7 @@ void p9_pgpe_process_wof_ctrl() pk_irq_vec_restore(&ctx); pk_semaphore_pend(&(G_pgpe_pstate_record.sem_actuate), PK_WAIT_FOREVER); - if (G_sgpe_control_updt.fields.return_code == SGPE_PGPE_IPC_RC_SUCCESS) + if (G_sgpe_control_updt.fields.return_code == IPC_SGPE_PGPE_RC_SUCCESS) { //Update Shared Memory Region G_pgpe_pstate_record.pQuadState0->fields.active_cores = G_sgpe_control_updt.fields.active_cores >> 8; 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 307612be..98a2d8ec 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 @@ -52,8 +52,6 @@ enum SCOM_ADDR_CCSR = 0x0006C090, CHECK_BIT_DWORD = 0x8000000000000000ll, SET_ADDR_MSB = 0x80000000, - CME_STOP_READY = 0x8000000000000000ll, - CME_PMCR_READY = 0x4000000000000000ll, WKUP_NOTIFY_SELECT = 0x0004000000000000, CME_BOOT_TIMEOUT = 0x32, CME_BCE_TIMEOUT = 0xB0, @@ -382,7 +380,7 @@ BootErrorCode_t boot_cme( uint16_t i_bootCme ) GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS, (l_cmeIndex >> 1), (l_cmeIndex % 2)), l_dataReg); - if (!(l_dataReg & CME_PMCR_READY)) + if (!(l_dataReg & BIT64(CME_PMCR_READY))) { continue; } 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 a8ee7627..aa3a1d29 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 @@ -37,7 +37,7 @@ void p9_sgpe_ipc_pgpe_ctrl_stop_updates(ipc_msg_t* cmd, void* arg) ipcmsg_p2s_ctrl_stop_updates_t* msg = (ipcmsg_p2s_ctrl_stop_updates_t*)async_cmd->cmd_data; - msg->fields.return_code = SGPE_IPC_RETURN_CODE_ACK; + msg->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; msg->fields.active_quads = G_sgpe_stop_record.group.quad[VECTOR_ACTIVE] >> SHIFT32(5); msg->fields.active_cores = G_sgpe_stop_record.group.core[VECTOR_ACTIVE] >> SHIFT32(23); @@ -74,7 +74,7 @@ void p9_sgpe_ipc_pgpe_suspend_stop(ipc_msg_t* cmd, void* arg) 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 = SGPE_IPC_RETURN_CODE_ACK; + msg->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; ipc_send_rsp(cmd, IPC_RC_SUCCESS); diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.h index 9a0795ac..c9f7a8bd 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.h +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.h @@ -49,8 +49,8 @@ // Priority Levels #define IDX_PRTY_LVL_HIPRTY 0 #define IDX_PRTY_LVL_IPI3_HIGH 1 -#define IDX_PRTY_LVL_PIG_TYPE 2 -#define IDX_PRTY_LVL_IPI3_LOW 3 +#define IDX_PRTY_LVL_IPI3_LOW 2 +#define IDX_PRTY_LVL_PIG_TYPE 3 #define IDX_PRTY_LVL_DISABLED 4 #define IDX_PRTY_VEC 0 #define IDX_MASK_VEC 1 @@ -62,10 +62,10 @@ extern const uint64_t ext_irq_vectors_sgpe[NUM_EXT_IRQ_PRTY_LEVELS][2]; #define IRQ_VEC_PRTY0_SGPE (uint64_t)(0x0000000000000000) // Group1: ipi3_high #define IRQ_VEC_PRTY1_SGPE (uint64_t)(0x0000000800000000) -// Group2: pig_type -#define IRQ_VEC_PRTY2_SGPE (uint64_t)(0x0000000000019000) // Group3: ipi3_low -#define IRQ_VEC_PRTY3_SGPE (uint64_t)(0x0000000000000004) +#define IRQ_VEC_PRTY2_SGPE (uint64_t)(0x0000000000000004) +// Group2: pig_type +#define IRQ_VEC_PRTY3_SGPE (uint64_t)(0x0000000000019000) // Group4: We should never detect these #define IRQ_VEC_PRTY4_SGPE (uint64_t)(0x0100800000000000) //#define IRQ_VEC_PRTY4_SGPE (uint64_t)(0xFEFF7FF7FFFE6FFB) diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C index 0f17949a..d813c0aa 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C @@ -74,14 +74,11 @@ IRQ_HANDLER_DEFAULT //OCCHW_IRQ_STRM3_PULL IRQ_HANDLER_DEFAULT //OCCHW_IRQ_STRM3_PUSH IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE0_PENDING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE1_PENDING -IRQ_HANDLER(p9_sgpe_stop_pig_handler, 0) -//IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE2_PENDING -IRQ_HANDLER(p9_sgpe_stop_pig_handler, 0) -//IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE3_PENDING +IRQ_HANDLER(p9_sgpe_stop_pig_handler, 0) //OCCHW_IRQ_PMC_PCB_INTR_TYPE2_PENDING +IRQ_HANDLER(p9_sgpe_stop_pig_handler, 0) //OCCHW_IRQ_PMC_PCB_INTR_TYPE3_PENDING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE4_PENDING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE5_PENDING -IRQ_HANDLER(p9_sgpe_stop_pig_handler, 0) -//IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE6_PENDING +IRQ_HANDLER(p9_sgpe_stop_pig_handler, 0) //OCCHW_IRQ_PMC_PCB_INTR_TYPE6_PENDING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE7_PENDING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_O2S_0A_ONGOING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_O2S_0B_ONGOING @@ -91,7 +88,7 @@ IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PSSBRIDGE_ONGOING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_IPI0_LO_PRIORITY IRQ_HANDLER_DEFAULT //OCCHW_IRQ_IPI1_LO_PRIORITY IRQ_HANDLER_DEFAULT //OCCHW_IRQ_IPI2_LO_PRIORITY -IRQ_HANDLER_DEFAULT //OCCHW_IRQ_IPI3_LO_PRIORITY +IRQ_HANDLER(p9_sgpe_stop_ipi_handler, 0) //OCCHW_IRQ_IPI3_LO_PRIORITY IRQ_HANDLER_DEFAULT //OCCHW_IRQ_IPI4_LO_PRIORITY IRQ_HANDLER_DEFAULT //OCCHW_IRQ_RESERVED_63 EXTERNAL_IRQ_TABLE_END 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 a287b440..f62484ee 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 @@ -39,6 +39,9 @@ extern "C" { #include "gpehw_common.h" #include "occhw_interrupts.h" +#include "stop_sgpe_cme_api.h" +#include "wof_sgpe_pgpe_api.h" + #include "ocb_register_addresses.h" #include "cme_register_addresses.h" #include "ppm_register_addresses.h" @@ -53,15 +56,17 @@ extern "C" { #include "ipc_api.h" #include "ipc_async_cmd.h" -#include "ipc_messages.h" #include "p9_hcode_image_defines.H" #include "p9_pm_hcd_flags.h" #include "p9_stop_common.h" +#include "p9_dd1_doorbell_wr.h" #if HW386311_NDD1_PBIE_RW_PTR_STOP11_FIX || NDD1_FUSED_CORE_MODE_SCAN_FIX + #define EXTRACT_RING_BITS(mask, ring, save) save = (ring) & (mask); #define RESTORE_RING_BITS(mask, ring, save) ring = (((ring) & (~mask)) | (save)); + #endif @@ -169,36 +174,7 @@ extern "C" { #define PERV_CPLT_STAT0 0x10000100 #define PERV_NET_CTRL1_WAND 0x000F0045 -enum SGPE_IPC_CONSTANTS -{ - ENABLE_CORE_STOP_UPDATES = 1, - ENABLE_QUAD_STOP_UPDATES = 2, - ENABLE_BOTH_STOP_UPDATES = 3, - DISABLE_CORE_STOP_UPDATES = 5, - DISABLE_QUAD_STOP_UPDATES = 6, - DISABLE_BOTH_STOP_UPDATES = 7, - SGPE_IPC_UPDATE_CORE_ENABLED = 1, - SGPE_IPC_UPDATE_QUAD_ENABLED = 2, - SGPE_IPC_UPDATE_TYPE_ENTRY = 0, - SGPE_IPC_UPDATE_TYPE_EXIT = 1, - SGPE_IPC_RETURN_CODE_NULL = 0, - SGPE_IPC_RETURN_CODE_ACK = 1 -}; - -enum SGPE_STOP_IRQ_SHORT_NAMES -{ - IRQ_STOP_TYPE2 = OCCHW_IRQ_PMC_PCB_INTR_TYPE2_PENDING, - IRQ_STOP_TYPE3 = OCCHW_IRQ_PMC_PCB_INTR_TYPE3_PENDING, - IRQ_STOP_TYPE6 = OCCHW_IRQ_PMC_PCB_INTR_TYPE6_PENDING -}; -enum SGPE_STOP_IRQ_PAYLOAD_MASKS -{ - TYPE2_PAYLOAD_EXIT_EVENT = 0xC00, - TYPE2_PAYLOAD_STOP_LEVEL = 0xF, - TYPE3_PAYLOAD_EXIT_EVENT = 0xC00, - TYPE6_PAYLOAD_EXIT_EVENT = 0xF -}; enum SGPE_STOP_STATE_HISTORY_VECTORS { @@ -217,17 +193,6 @@ enum SGPE_STOP_EVENT_LEVELS LEVEL_EQ_BASE = 11 }; -enum SGPE_STOP_CME_FLAGS -{ - CME_QUAD_MGR_INDICATOR = BIT32(3), - CME_EX1_INDICATOR = BIT32(26), - CME_SIBLING_FUNCTIONAL = BIT32(27), - CME_CORE0_ENTRY_FIRST = BIT32(28), - CME_CORE1_ENTRY_FIRST = BIT32(29), - CME_CORE0_ENABLE = BIT32(30), - CME_CORE1_ENABLE = BIT32(31) -}; - enum SGPE_STOP_PSCOM_MASK { PSCOM_MASK_ALL_L2 = BITS32(2, 2) | BITS32(10, 2), @@ -237,7 +202,13 @@ enum SGPE_STOP_PSCOM_MASK PSCOM_MASK_EX1_L3 = BIT32(5) | BIT32(7) | BIT32(9) }; -enum SGPE_FUNCTION_STATUS +enum SGPE_WOF_ACTIVE_UPDATE_STATUS +{ + IPC_SGPE_PGPE_UPDATE_CORE_ENABLED = 1, + IPC_SGPE_PGPE_UPDATE_QUAD_ENABLED = 2 +}; + +enum SGPE_SUSPEND_FUNCTION_STATUS { STATUS_IDLE = 0, STATUS_PROCESSING = 1, @@ -247,11 +218,13 @@ enum SGPE_FUNCTION_STATUS enum SGPE_STOP_VECTOR_INDEX { - VECTOR_EXIT = 0, - VECTOR_ENTRY = 1, - VECTOR_CONFIG = 2, - VECTOR_ACTIVE = 3, - VECTOR_PCWU = 4 + VECTOR_CONFIG = 0, //(core, quad, qswu_ongoing, exlr) + VECTOR_BLOCKE = 1, //(core_save, quad_req, qswu_save, exlr_ack) + VECTOR_BLOCKX = 2, //(core_save, quad_req, qswu_save, exlr_ack) + VECTOR_ENTRY = 3, //(core_ipc, quad, qswu, exlr) + VECTOR_EXIT = 4, //(core, quad_ipc qswu) + VECTOR_ACTIVE = 5, //(core_ipc, quad_ipc) + VECTOR_PCWU = 6 //(core) }; typedef struct @@ -270,22 +243,21 @@ typedef struct typedef struct { - uint32_t core[5]; // 24 bits - uint32_t quad[4]; // 6 bits - uint32_t ex_l[3]; // 6 bits - uint32_t ex_r[3]; // 6 bits - uint32_t ex_b[3]; // 12 bits - uint32_t qswu[3]; // 6 bits + uint32_t ex_l[4]; // 6 bits + uint32_t ex_r[4]; // 6 bits + uint32_t qswu[5]; // 6 bits + uint32_t quad[6]; // 6 bits + uint32_t core[7]; // 24 bits } sgpe_group_t; typedef struct { // function status(functional, suspending, suspended, resuming) - uint8_t status_pstate; - uint8_t status_stop; + uint8_t status_pstate; + uint8_t status_stop; // sgpe-pgpe interlock status(quad/core updates enable/disable) - uint8_t update_pgpe; - ipc_msg_t* suspend_cmd; + uint8_t update_pgpe; + ipc_msg_t* suspend_cmd; } sgpe_wof_t; /// SGPE Stop Score Board Structure @@ -299,7 +271,7 @@ typedef struct // group of ex and quad entering or exiting the stop sgpe_group_t group; sgpe_wof_t wof; - PkSemaphore sem[3]; + PkSemaphore sem[4]; } SgpeStopRecord; typedef struct @@ -327,6 +299,8 @@ 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); void p9_sgpe_stop_pig_handler(void*, PkIrqId); void p9_sgpe_stop_enter_thread(void*); void p9_sgpe_stop_exit_thread(void*); 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 a945af2d..bc57a656 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 @@ -56,8 +56,6 @@ p9_sgpe_stop_entry() uint32_t qloop = 0; uint32_t cloop = 0; uint32_t climit = 0; - uint32_t xentry = 0; - uint32_t qentry = 0; uint64_t host_attn = 0; uint64_t local_xstop = 0; data64_t scom_data = {0}; @@ -79,7 +77,6 @@ p9_sgpe_stop_entry() G_sgpe_stop_record.group.ex_l[VECTOR_ENTRY] = 0; G_sgpe_stop_record.group.ex_r[VECTOR_ENTRY] = 0; - G_sgpe_stop_record.group.ex_b[VECTOR_ENTRY] = 0; G_sgpe_stop_record.group.quad[VECTOR_ENTRY] = 0; for(qloop = 0; qloop < MAX_QUADS; qloop++) @@ -112,15 +109,12 @@ p9_sgpe_stop_entry() G_sgpe_stop_record.state[qloop].req_state_x0 >= LEVEL_EX_BASE) { G_sgpe_stop_record.group.ex_l[VECTOR_ENTRY] |= BIT32(qloop); - G_sgpe_stop_record.group.ex_b[VECTOR_ENTRY] |= BIT32(qloop << 1); } if (G_sgpe_stop_record.state[qloop].act_state_x1 < LEVEL_EX_BASE && G_sgpe_stop_record.state[qloop].req_state_x1 >= LEVEL_EX_BASE) { G_sgpe_stop_record.group.ex_r[VECTOR_ENTRY] |= BIT32(qloop); - G_sgpe_stop_record.group.ex_b[VECTOR_ENTRY] |= - BIT32((qloop << 1) + 1); } if (G_sgpe_stop_record.state[qloop].act_state_q < LEVEL_EQ_BASE && @@ -129,7 +123,8 @@ p9_sgpe_stop_entry() G_sgpe_stop_record.group.quad[VECTOR_ENTRY] |= BIT32(qloop); } - if (G_sgpe_stop_record.group.ex_b[VECTOR_ENTRY] || + if (G_sgpe_stop_record.group.ex_l[VECTOR_ENTRY] || + G_sgpe_stop_record.group.ex_r[VECTOR_ENTRY] || G_sgpe_stop_record.group.quad[VECTOR_ENTRY]) { PK_TRACE_DBG("Actual: clv[%d][%d][%d][%d]", @@ -150,8 +145,6 @@ p9_sgpe_stop_entry() } } - G_sgpe_stop_record.group.ex_b[VECTOR_ENTRY] &= - G_sgpe_stop_record.group.ex_b[VECTOR_CONFIG]; G_sgpe_stop_record.group.ex_l[VECTOR_ENTRY] &= G_sgpe_stop_record.group.ex_l[VECTOR_CONFIG]; G_sgpe_stop_record.group.ex_r[VECTOR_ENTRY] &= @@ -159,8 +152,7 @@ p9_sgpe_stop_entry() G_sgpe_stop_record.group.quad[VECTOR_ENTRY] &= G_sgpe_stop_record.group.quad[VECTOR_CONFIG]; - PK_TRACE_DBG("Core Entry Vectors: X[%x] X0[%x] X1[%x] Q[%x]", - G_sgpe_stop_record.group.ex_b[VECTOR_ENTRY], + PK_TRACE_DBG("Core Entry Vectors: X0[%x] X1[%x] Q[%x]", G_sgpe_stop_record.group.ex_l[VECTOR_ENTRY], G_sgpe_stop_record.group.ex_r[VECTOR_ENTRY], G_sgpe_stop_record.group.quad[VECTOR_ENTRY]); @@ -181,12 +173,12 @@ p9_sgpe_stop_entry() // the SGPE will halt as the SGPE and PGPE are now out of synchronization. // [This is not a likely error.] - if((G_sgpe_stop_record.wof.update_pgpe & SGPE_IPC_UPDATE_CORE_ENABLED) && + if((G_sgpe_stop_record.wof.update_pgpe & IPC_SGPE_PGPE_UPDATE_CORE_ENABLED) && G_sgpe_stop_record.group.core[VECTOR_ENTRY]) { PK_TRACE_INF("SEIPC: Update PGPE with Active Cores"); - G_sgpe_ipcmsg_update_cores.fields.update_type = SGPE_IPC_UPDATE_TYPE_ENTRY; - G_sgpe_ipcmsg_update_cores.fields.return_code = SGPE_IPC_RETURN_CODE_NULL; + G_sgpe_ipcmsg_update_cores.fields.update_type = UPDATE_ACTIVE_TYPE_ENTRY; + G_sgpe_ipcmsg_update_cores.fields.return_code = IPC_SGPE_PGPE_RC_NULL; G_sgpe_ipcmsg_update_cores.fields.active_cores = (G_sgpe_stop_record.group.core[VECTOR_ENTRY] >> SHIFT32(5)); @@ -206,9 +198,9 @@ p9_sgpe_stop_entry() // can poll right away since pgpe should ack right back PK_TRACE_INF("SEIPC: Poll PGPE Update Active Cores Ack"); - while (G_sgpe_ipcmsg_update_cores.fields.return_code == SGPE_IPC_RETURN_CODE_NULL); + while (G_sgpe_ipcmsg_update_cores.fields.return_code == IPC_SGPE_PGPE_RC_NULL); - if (G_sgpe_ipcmsg_update_cores.fields.return_code != SGPE_IPC_RETURN_CODE_ACK) + if (G_sgpe_ipcmsg_update_cores.fields.return_code != IPC_SGPE_PGPE_RC_SUCCESS) { PK_TRACE_ERR("ERROR: Entry Updates PGPE with Active Cores Bad RC. HALT SGPE!"); PK_PANIC(SGPE_STOP_ENTRY_IPC_CORE_BAD_RC); @@ -238,8 +230,8 @@ p9_sgpe_stop_entry() //=============================== PK_TRACE_INF("SEIPC: Message PGPE to Suspend Pstate(stop11 and pstate enabled)"); - G_sgpe_ipcmsg_suspend_pstate.fields.update_type = SGPE_IPC_UPDATE_TYPE_ENTRY; - G_sgpe_ipcmsg_suspend_pstate.fields.return_code = SGPE_IPC_RETURN_CODE_NULL; + G_sgpe_ipcmsg_suspend_pstate.fields.update_type = UPDATE_ACTIVE_TYPE_ENTRY; + G_sgpe_ipcmsg_suspend_pstate.fields.return_code = IPC_SGPE_PGPE_RC_NULL; G_sgpe_ipcmsg_suspend_pstate.fields.requested_quads = (G_sgpe_stop_record.group.quad[VECTOR_ENTRY] >> SHIFT32(5)); @@ -261,13 +253,14 @@ p9_sgpe_stop_entry() PK_TRACE_INF("SEIPC: Pend PGPE Suspend Pstate Ack"); pk_semaphore_pend(&(G_sgpe_stop_record.sem[2]), PK_WAIT_FOREVER); - if (G_sgpe_ipcmsg_suspend_pstate.fields.return_code != SGPE_IPC_RETURN_CODE_ACK) + if (G_sgpe_ipcmsg_suspend_pstate.fields.return_code != IPC_SGPE_PGPE_RC_SUCCESS) { PK_TRACE_ERR("ERROR: Entry Suspend PGPE Pstate Function Bad RC. HALT SGPE!"); PK_PANIC(SGPE_STOP_ENTRY_IPC_PSTATE_BAD_RC); } } - else if (!G_sgpe_stop_record.group.ex_b[VECTOR_ENTRY]) + else if ((!G_sgpe_stop_record.group.ex_l[VECTOR_ENTRY]) && + (!G_sgpe_stop_record.group.ex_r[VECTOR_ENTRY])) { //============================ MARK_TAG(SE_LESSTHAN8_DONE, 0) @@ -279,12 +272,22 @@ p9_sgpe_stop_entry() // only stop 8 sets x_in - for(xentry = G_sgpe_stop_record.group.ex_b[VECTOR_ENTRY], qloop = 0; - xentry > 0; - xentry = xentry << 2, qloop++) + for(qloop = 0; qloop < MAX_QUADS; qloop++) { // if this ex is not up to entry, skip - if (!(ex = ((xentry & BITS32(0, 2)) >> SHIFT32(1)))) + ex = 0; + + if (G_sgpe_stop_record.group.ex_l[VECTOR_ENTRY] & BIT32(qloop)) + { + ex |= FST_EX_IN_QUAD; + } + + if (G_sgpe_stop_record.group.ex_r[VECTOR_ENTRY] & BIT32(qloop)) + { + ex |= SND_EX_IN_QUAD; + } + + if (!ex) { continue; } @@ -556,12 +559,10 @@ p9_sgpe_stop_entry() - for(qentry = G_sgpe_stop_record.group.quad[VECTOR_ENTRY], qloop = 0, ex = 0; - qentry > 0; - qentry = qentry << 1, qloop++, ex = 0) + for(qloop = 0; qloop < MAX_QUADS; qloop++) { // if this quad is not up to entry, skip - if (!(qentry & BIT32(0))) + if (!(G_sgpe_stop_record.group.quad[VECTOR_ENTRY] & BIT32(qloop))) { continue; } @@ -570,6 +571,8 @@ p9_sgpe_stop_entry() PK_TRACE("+++++ +++++ QUAD STOP ENTRY [LEVEL 11-15] +++++ +++++"); // ------------------------------------------------------------------------ + ex = 0; + if (G_sgpe_stop_record.group.ex_l[VECTOR_CONFIG] & BIT32(qloop)) { ex |= FST_EX_IN_QUAD; @@ -1186,8 +1189,8 @@ p9_sgpe_stop_entry() G_sgpe_ipcmsg_update_quads.fields.requested_quads = G_sgpe_stop_record.group.quad[VECTOR_ENTRY] >> SHIFT32(5); - G_sgpe_ipcmsg_update_quads.fields.update_type = SGPE_IPC_UPDATE_TYPE_ENTRY; - G_sgpe_ipcmsg_update_quads.fields.return_code = SGPE_IPC_RETURN_CODE_NULL; + G_sgpe_ipcmsg_update_quads.fields.update_type = UPDATE_ACTIVE_TYPE_ENTRY; + G_sgpe_ipcmsg_update_quads.fields.return_code = IPC_SGPE_PGPE_RC_NULL; G_sgpe_ipccmd_to_pgpe.cmd_data = &G_sgpe_ipcmsg_update_quads; ipc_init_msg(&G_sgpe_ipccmd_to_pgpe.cmd, @@ -1205,7 +1208,7 @@ p9_sgpe_stop_entry() PK_TRACE_INF("SEIPC: Pend PGPE Update Active Quads Ack"); pk_semaphore_pend(&(G_sgpe_stop_record.sem[2]), PK_WAIT_FOREVER); - if (G_sgpe_ipcmsg_update_quads.fields.return_code != SGPE_IPC_RETURN_CODE_ACK) + if (G_sgpe_ipcmsg_update_quads.fields.return_code != IPC_SGPE_PGPE_RC_SUCCESS) { PK_TRACE_INF("ERROR: Entry Updates PGPE with Active Quads Bad RC. HALT SGPE!"); PK_PANIC(SGPE_STOP_ENTRY_IPC_QUAD_BAD_RC); diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c index c89718d0..a353f591 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c @@ -26,7 +26,6 @@ #include "p9_sgpe_stop.h" #include "p9_sgpe_stop_exit_marks.h" #include "p9_hcd_sgpe_boot_cme.h" -#include "p9_dd1_doorbell_wr.h" extern SgpeStopRecord G_sgpe_stop_record; @@ -330,11 +329,10 @@ p9_sgpe_stop_exit() MARK_TAG(BEGINSCOPE_STOP_EXIT, 0) //=============================== - PK_TRACE_DBG("Core Exit Vectors: X[%x] X0[%x] X1[%x] Q[%x]", - G_sgpe_stop_record.group.ex_b[VECTOR_EXIT], - G_sgpe_stop_record.group.ex_l[VECTOR_EXIT], - G_sgpe_stop_record.group.ex_r[VECTOR_EXIT], - G_sgpe_stop_record.group.quad[VECTOR_EXIT]); + PK_TRACE_DBG("Core Exit Vectors: C[%x] Q[%x] S[%x]", + G_sgpe_stop_record.group.core[VECTOR_EXIT], + G_sgpe_stop_record.group.quad[VECTOR_EXIT], + G_sgpe_stop_record.group.qswu[VECTOR_EXIT]); #if !SKIP_IPC @@ -354,12 +352,12 @@ p9_sgpe_stop_exit() // combination that could violate the current or thermal parameters // which could lead to system checkstop] - if((G_sgpe_stop_record.wof.update_pgpe & SGPE_IPC_UPDATE_CORE_ENABLED) && + if((G_sgpe_stop_record.wof.update_pgpe & IPC_SGPE_PGPE_UPDATE_CORE_ENABLED) && G_sgpe_stop_record.group.core[VECTOR_EXIT]) { PK_TRACE_INF("SXIPC: Update PGPE with Active Cores"); - G_sgpe_ipcmsg_update_cores.fields.update_type = SGPE_IPC_UPDATE_TYPE_EXIT; - G_sgpe_ipcmsg_update_cores.fields.return_code = SGPE_IPC_RETURN_CODE_NULL; + G_sgpe_ipcmsg_update_cores.fields.update_type = UPDATE_ACTIVE_TYPE_EXIT; + G_sgpe_ipcmsg_update_cores.fields.return_code = IPC_SGPE_PGPE_RC_NULL; G_sgpe_ipcmsg_update_cores.fields.active_cores = (G_sgpe_stop_record.group.core[VECTOR_EXIT] >> SHIFT32(5)); @@ -380,9 +378,9 @@ p9_sgpe_stop_exit() /// move the poll below to before switch exit to cme when sgpe supports multicast PK_TRACE_INF("SXIPC: Poll PGPE Update Active Cores Ack"); - while (G_sgpe_ipcmsg_update_cores.fields.return_code == SGPE_IPC_RETURN_CODE_NULL); + while (G_sgpe_ipcmsg_update_cores.fields.return_code == IPC_SGPE_PGPE_RC_NULL); - if (G_sgpe_ipcmsg_update_cores.fields.return_code != SGPE_IPC_RETURN_CODE_ACK) + if (G_sgpe_ipcmsg_update_cores.fields.return_code != IPC_SGPE_PGPE_RC_SUCCESS) { PK_TRACE_ERR("ERROR: Exit Updates PGPE with Active Cores Bad RC. HALT SGPE!"); PK_PANIC(SGPE_STOP_EXIT_IPC_CORE_BAD_RC); @@ -401,7 +399,6 @@ p9_sgpe_stop_exit() // PGPE, as part of its processing this IPC, // will write the QPPM_DPLL_FREQ register before responding. - if ((in32(OCB_OCCS2) & BIT32(PGPE_ACTIVE)) && G_sgpe_stop_record.group.quad[VECTOR_EXIT]) // exit from STOP11 { @@ -429,8 +426,8 @@ p9_sgpe_stop_exit() if (G_sgpe_ipcmsg_update_quads.fields.requested_quads) { PK_TRACE_INF("SXIPC: Update PGPE with Active Quads(stop11 and pstate enabled)"); - G_sgpe_ipcmsg_update_quads.fields.update_type = SGPE_IPC_UPDATE_TYPE_EXIT; - G_sgpe_ipcmsg_update_quads.fields.return_code = SGPE_IPC_RETURN_CODE_NULL; + G_sgpe_ipcmsg_update_quads.fields.update_type = UPDATE_ACTIVE_TYPE_EXIT; + G_sgpe_ipcmsg_update_quads.fields.return_code = IPC_SGPE_PGPE_RC_NULL; G_sgpe_ipccmd_to_pgpe.cmd_data = &G_sgpe_ipcmsg_update_quads; ipc_init_msg(&G_sgpe_ipccmd_to_pgpe.cmd, @@ -450,7 +447,7 @@ p9_sgpe_stop_exit() PK_TRACE_INF("SXIPC: Pend PGPE Update Active Quads Ack"); pk_semaphore_pend(&(G_sgpe_stop_record.sem[3]), PK_WAIT_FOREVER); - if (G_sgpe_ipcmsg_update_quads.fields.return_code != SGPE_IPC_RETURN_CODE_ACK) + if (G_sgpe_ipcmsg_update_quads.fields.return_code != IPC_SGPE_PGPE_RC_SUCCESS) { PK_TRACE_ERR("ERROR: Exit Updates PGPE with Active Quads Bad RC. HALT SGPE!"); PK_PANIC(SGPE_STOP_EXIT_IPC_QUAD_BAD_RC); @@ -828,8 +825,6 @@ p9_sgpe_stop_exit() } PK_TRACE_DBG("Check: Core[%d] will send Doorbell1", ((qloop << 2) + cloop)); - p9_dd1_db_unicast_wr(GPE_SCOM_ADDR_CORE(CPPM_CMEMSG, - ((qloop << 2) + cloop)), BIT64(0)); // workaround has to use base address as read on OR/CLR leads to error p9_dd1_db_unicast_wr(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1, ((qloop << 2) + cloop)), BIT64(7)); @@ -852,21 +847,21 @@ p9_sgpe_stop_exit() if (m_pg & (~ex_mask)) { - cme_flags |= CME_SIBLING_FUNCTIONAL; + cme_flags |= BIT32(CME_SIBLING_FUNCTIONAL); } if (ex_index == 1) { - cme_flags |= CME_EX1_INDICATOR; + cme_flags |= BIT32(CME_EX_ID); - if (!(cme_flags & CME_SIBLING_FUNCTIONAL)) + if (!(cme_flags & BIT32(CME_SIBLING_FUNCTIONAL))) { - cme_flags |= CME_QUAD_MGR_INDICATOR; + cme_flags |= BIT32(CME_QMGR_MASTER); } } else { - cme_flags |= CME_QUAD_MGR_INDICATOR; + cme_flags |= BIT32(CME_QMGR_MASTER); } @@ -888,13 +883,13 @@ p9_sgpe_stop_exit() { if (ccsr.value & BIT32((ec_index + cloop))) { - cme_flags |= (CME_CORE0_ENABLE >> cloop); + cme_flags |= (BIT32(CME_CORE0_GOOD) >> cloop); GPE_GETSCOM(GPE_SCOM_ADDR_CORE(C_NET_CTRL0, (ec_index + cloop)), scom_data.value); if (!(scom_data.words.upper & BIT32(18))) { - cme_flags |= (CME_CORE0_ENTRY_FIRST >> cloop); + cme_flags |= (BIT32(CME_STOP_ENTRY_FIRST_C0) >> cloop); } #if NIMBUS_DD_LEVEL != 1 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 15a4954f..56b703a1 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 @@ -46,12 +46,12 @@ SgpeStopRecord G_sgpe_stop_record __attribute__((section (".dump_ptrs"))) = {0, 0, 0, 0, 0, 0, 0} }, // 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, 0, 0, 0} }, // wof status {0, 0, 0, 0}, @@ -59,6 +59,144 @@ SgpeStopRecord G_sgpe_stop_record __attribute__((section (".dump_ptrs"))) = {{0, 0, 0}} }; + + +void +p9_sgpe_stop_suspend_msg_db1(uint32_t qloop, uint32_t msgid) +{ + uint32_t cstart = 0; + uint32_t cloop = 0; + uint32_t cmask = 0; + data64_t scom_data = {0}; + ppm_pig_t pig = {0}; + + for(cstart = 0; cstart < CORES_PER_QUAD; cstart += 2) + { + for(cloop = cstart, cmask = BIT32(((qloop << 2) + cstart)); + cloop < (cstart + CORES_PER_EX); + cloop++, cmask = cmask >> 1) + { + // find the first good core served by each active CME + if (G_sgpe_stop_record.group.core[VECTOR_CONFIG] & cmask) + { + break; + } + } + + // 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 + { + scom_data.words.upper = msgid; + scom_data.words.lower = 0; + p9_dd1_db_unicast_wr(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1, + ((qloop << 2) + cloop)), scom_data.value); + } + // 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)) + { + cloop = cstart; + } + + pig.fields.req_intr_payload = msgid >> 16; + pig.fields.req_intr_payload |= 0x080; // set bit 4 for ack package + pig.fields.req_intr_type = PIG_TYPE2; + GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(PPM_PIG, ((qloop << 2) + cloop)), pig.value); + } + } +} + +void +p9_sgpe_stop_ipi_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}; + + PK_TRACE_DBG("IPI-IRQ: %d", irq); + // Clear ipi3_lo interrupt + out32(OCB_OISR1_CLR, BIT32(29)); + + // occflg[9]control + [11]exit/[12]entry(filter bit[10] here) + // bit[9] must be on to perform any operations below + // also verify we are doing at least one operation from entry/exit + // otherwise, even bit[9] is on, the requested operation is undefined + // 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); + + for (qloop = 0; qloop < MAX_QUADS; qloop++) + { + if (!(G_sgpe_stop_record.group.quad[VECTOR_CONFIG] & BIT32(qloop))) + { + continue; + } + + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QCCR, qloop), scom_data.value); + + // target quad is to participate block/unblock exit + if (scom_data.words.upper & BIT32(10)) + { + action = action | BIT32(6); + + if (action & BIT32(5)) + { + G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] |= BIT32(qloop); + } + else + { + G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] &= ~BIT32(qloop); + } + } + // not participate exit, taking exit encoding bit out + else + { + action = action & (~BIT32(6)); + } + + // target quad is to participate block/unblock entry + if (scom_data.words.upper & BIT32(11)) + { + action = action | BIT32(7); + + if (action & BIT32(5)) + { + G_sgpe_stop_record.group.quad[VECTOR_BLOCKE] |= BIT32(qloop); + } + else + { + G_sgpe_stop_record.group.quad[VECTOR_BLOCKE] &= ~BIT32(qloop); + } + } + // not participate entry, taking entry encoding bit out + else + { + action = action & (~BIT32(7)); + } + + // if this quad participates either entry/exit for block/unlock + // send msg; otherwise skip the quad + if (action & BITS32(6, 2)) + { + p9_sgpe_stop_suspend_msg_db1(qloop, action); + } + } + } + + pk_irq_vec_restore(&ctx); +} + + + // PCB Interrupt Type2 // Payload // 0 - set = Hardware Exit | unset = Firmware Stop @@ -86,17 +224,20 @@ void p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) { PkMachineContext ctx; - uint32_t cirq = 0; - uint32_t qirq = 0; - uint32_t cloop = 0; - uint32_t qloop = 0; - uint32_t cpending_t2 = 0; - uint32_t cpending_t3 = 0; - uint32_t qpending_t6 = 0; - uint32_t cpayload_t2 = 0; - uint32_t cpayload_t3 = 0; - uint32_t qpayload_t6 = 0; - uint64_t scom_data = 0; + uint32_t cirq = 0; + uint32_t qirq = 0; + uint32_t cloop = 0; + uint32_t qloop = 0; + uint32_t cpending_t2 = 0; + uint32_t cpending_t3 = 0; + uint32_t qpending_t6 = 0; + uint32_t cpayload_t2 = 0; + uint32_t cpayload_t3 = 0; + uint32_t qpayload_t6 = 0; + uint32_t suspend_mask = 0; + uint32_t suspend_index = 0; + uint32_t vector_index = 0; + data64_t scom_data = {0}; //========================= MARK_TRAP(STOP_PIG_HANDLER) @@ -136,19 +277,15 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) } // clear group before analyzing input - G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] = 0; G_sgpe_stop_record.group.core[VECTOR_ENTRY] = 0; - G_sgpe_stop_record.group.qswu[VECTOR_EXIT] = 0; + G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] = 0; G_sgpe_stop_record.group.core[VECTOR_EXIT] = 0; - G_sgpe_stop_record.group.ex_l[VECTOR_EXIT] = 0; - G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] = 0; - G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] = 0; + G_sgpe_stop_record.group.qswu[VECTOR_EXIT] = 0; G_sgpe_stop_record.group.quad[VECTOR_EXIT] = 0; // loop all quads for(qloop = 0; qloop < MAX_QUADS; qloop++) { - // if no quad special wakeup, skip to core request if (qirq && (BIT32(qloop) & qpending_t6 & G_sgpe_stop_record.group.quad[VECTOR_CONFIG])) @@ -166,14 +303,15 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) { PK_TRACE_DBG("Quad Already in Special Wakeup"); } + 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); G_sgpe_stop_record.group.quad[VECTOR_EXIT] |= BIT32(qloop); - G_sgpe_stop_record.group.ex_l[VECTOR_EXIT] |= BIT32(qloop); - G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] |= BIT32(qloop); - G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] |= - BITS32((qloop << 1), 2); } } else @@ -181,8 +319,16 @@ p9_sgpe_stop_pig_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)); - G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] |= BIT32(qloop); - G_sgpe_stop_record.group.qswu[VECTOR_CONFIG] &= ~BIT32(qloop); + 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); + } + else + { + G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] |= BIT32(qloop); + G_sgpe_stop_record.group.qswu[VECTOR_CONFIG] &= ~BIT32(qloop); + } } } @@ -194,7 +340,7 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) } PK_TRACE_DBG("Quad[%d] Has Core Request:", qloop); - PK_TRACE_DBG("Now clv[%d][%d][%d][%d]", + PK_TRACE_DBG("Now Core Levels[%d][%d][%d][%d]", G_sgpe_stop_record.level[qloop][0], G_sgpe_stop_record.level[qloop][1], G_sgpe_stop_record.level[qloop][2], @@ -209,10 +355,10 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) continue; } - // read payload on core has interrupt2 cpending cpayload_t2 = 0; cpayload_t3 = 0; + // read payload on core has interrupt2 cpending if (cpending_t2 & BIT32((qloop << 2) + cloop)) { cpayload_t2 = in32(OCB_OPIT2CN(((qloop << 2) + cloop))); @@ -227,8 +373,73 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) PK_TRACE_INF("Core[%d] Type2 Payload [%x] Type3 Payload [%x]", ((qloop << 2) + cloop), cpayload_t2, cpayload_t3); + // if not hardware pig and is an suspend ack pig + if (((~cpayload_t2) & TYPE2_PAYLOAD_HARDWARE_WAKEUP) && + (cpayload_t2 & TYPE2_PAYLOAD_SUSPEND_ACK_MASK)) + { + for(suspend_mask = TYPE2_PAYLOAD_SUSPEND_EXIT_MASK, + vector_index = VECTOR_EXIT, + suspend_index = VECTOR_BLOCKX; + suspend_index > 0; + suspend_index--, + vector_index--, + suspend_mask = suspend_mask >> 1) + { + // if entry/exit is selected for performing suspend/unsuspend operation + if (cpayload_t2 & suspend_mask) + { + // suspend entry/exit/both + if (cpayload_t2 & TYPE2_PAYLOAD_SUSPEND_OP_MASK) + { + if ((cloop >> 1) % 2) + { + G_sgpe_stop_record.group.ex_r[suspend_index] |= BIT32(qloop); + } + else + { + G_sgpe_stop_record.group.ex_l[suspend_index] |= BIT32(qloop); + } + + if((G_sgpe_stop_record.group.ex_r[suspend_index] & + G_sgpe_stop_record.group.ex_l[suspend_index] & + G_sgpe_stop_record.group.quad[suspend_index]) == + G_sgpe_stop_record.group.quad[suspend_index]) + { + out32(OCB_OCCFLG_CLR, BIT32(SGPE_IGNORE_STOP_CONTROL)); + } + } + // unsuspend entry/exit/both + else + { + if ((cloop >> 1) % 2) + { + G_sgpe_stop_record.group.ex_r[suspend_index] &= ~BIT32(qloop); + } + else + { + G_sgpe_stop_record.group.ex_l[suspend_index] &= ~BIT32(qloop); + } + + if ((G_sgpe_stop_record.group.ex_r[suspend_index] | + G_sgpe_stop_record.group.ex_l[suspend_index]) == 0) + { + G_sgpe_stop_record.group.core[vector_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; + out32(OCB_OCCFLG_CLR, BIT32(SGPE_IGNORE_STOP_CONTROL)); + } + } + } + } + + continue; + } + GPE_GETSCOM(GPE_SCOM_ADDR_CORE(CPPM_CPMMR, - ((qloop << 2) + cloop)), scom_data); + ((qloop << 2) + cloop)), scom_data.value); // T2 T3 NS given point to SGPE // exit exit SGPE ---- proceed with exit @@ -270,7 +481,7 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) // if t2 entry (t3 exit or empty) else if (cpayload_t2 && (!(cpayload_t2 & TYPE2_PAYLOAD_EXIT_EVENT))) { - if (!(scom_data & BIT64(13))) + if (!(scom_data.words.upper & BIT32(13))) { // wakeup=normal + notify=cme -> error if (cpayload_t2 != 0x400) @@ -300,7 +511,7 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) // if t3 entry (t2 exit or empty) else if (cpayload_t3 && (!(cpayload_t3 & TYPE2_PAYLOAD_EXIT_EVENT))) { - if (!(scom_data & BIT64(13))) + if (!(scom_data.words.upper & BIT32(13))) { PK_TRACE_ERR("ERROR: Received Type3 Entry PIG When Wakeup_notify_select = 0. HALT SGPE!"); PK_PANIC(SGPE_PIG_TYPE3_ENTRY_WNS_CME); @@ -315,7 +526,7 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) // both exit or one exit + one empty else { - if (!(scom_data & BIT64(13))) + if (!(scom_data.words.upper & BIT32(13))) { if ((cpayload_t2 & TYPE2_PAYLOAD_EXIT_EVENT) && (cpayload_t3 & TYPE2_PAYLOAD_EXIT_EVENT)) @@ -332,25 +543,20 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) { PK_TRACE_INF("Core Request Exit"); - if (cloop < CORES_PER_EX) + if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] & BIT32(qloop)) { - G_sgpe_stop_record.group.ex_l[VECTOR_EXIT] |= - BIT32(qloop); - G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] |= - BIT32((qloop << 1)); + PK_TRACE_DBG("Core is in Block Wakeup Mode, Ignore Now", cloop); + G_sgpe_stop_record.group.core[VECTOR_BLOCKX] |= + BIT32(((qloop << 2) + cloop)); } else { - G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] |= + PK_TRACE_DBG("Core Considered Stopped, Will Wakeup", cloop); + G_sgpe_stop_record.group.quad[VECTOR_EXIT] |= BIT32(qloop); - G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] |= - BIT32(((qloop << 1) + 1)); + G_sgpe_stop_record.group.core[VECTOR_EXIT] |= + BIT32(((qloop << 2) + cloop)); } - - G_sgpe_stop_record.group.quad[VECTOR_EXIT] |= - BIT32(qloop); - G_sgpe_stop_record.group.core[VECTOR_EXIT] |= - BIT32(((qloop << 2) + cloop)); } } } @@ -362,13 +568,6 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) G_sgpe_stop_record.level[qloop][3]); } - G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] &= - G_sgpe_stop_record.group.ex_b[VECTOR_CONFIG]; - G_sgpe_stop_record.group.ex_l[VECTOR_EXIT] &= - G_sgpe_stop_record.group.ex_l[VECTOR_CONFIG]; - G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] &= - G_sgpe_stop_record.group.ex_r[VECTOR_CONFIG]; - PK_TRACE_DBG("Quad Special Wakeup: Raise[%x], Drop[%x]", G_sgpe_stop_record.group.qswu[VECTOR_EXIT], G_sgpe_stop_record.group.qswu[VECTOR_ENTRY]); @@ -402,5 +601,8 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) G_sgpe_stop_record.wof.status_stop = STATUS_PROCESSING; pk_semaphore_post(&(G_sgpe_stop_record.sem[0])); } + + PK_TRACE("Disable ipi3_lo interrupt"); + out32(OCB_OIMR1_OR, BIT32(29)); } } |

