diff options
| author | Rahul Batra <rbatra@us.ibm.com> | 2018-01-04 21:43:15 -0600 |
|---|---|---|
| committer | hostboot <hostboot@us.ibm.com> | 2018-04-06 12:39:11 -0500 |
| commit | 5e7a5085043cfc42787069489663c9ba600038d3 (patch) | |
| tree | 8c56fed0686802472f0ed202f68a037c585d1f25 | |
| parent | 4a102688afb2cb3b815334145d4f7c8b84ab4017 (diff) | |
| download | talos-hcode-5e7a5085043cfc42787069489663c9ba600038d3.tar.gz talos-hcode-5e7a5085043cfc42787069489663c9ba600038d3.zip | |
PGPE: Error Handling Support
Key_Cronus_Test=PM_REGRESS
Change-Id: Ib6fb30d6b8c0cdc21002b34b708e724f54eac62b
Original-Change-Id: I00aca629108aeaca88db34eec8e408f3cd48ff7f
CQ: SW414842
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48635
Reviewed-by: RANGANATHPRASAD G. BRAHMASAMUDRA <prasadbgr@in.ibm.com>
Reviewed-by: YUE DU <daviddu@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com>
Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
52 files changed, 1868 insertions, 1125 deletions
diff --git a/import/chips/p9/common/pmlib/include/gpehw_common.h b/import/chips/p9/common/pmlib/include/gpehw_common.h index 4ddd764e..06a549d6 100644 --- a/import/chips/p9/common/pmlib/include/gpehw_common.h +++ b/import/chips/p9/common/pmlib/include/gpehw_common.h @@ -77,13 +77,6 @@ enum GPE_SCOM_ADDRESS_PARAMETERS CME1_ADDR_OFFSET = 0x00000400 }; -enum GPE_ERR_INJ_BIT_POS -{ - SGPE_HCODE_ERR_INJ_BIT = 0x00000002, - PGPE_HCODE_ERR_INJ_BIT = 0x00000001, -}; - - /// GPE SCOM #define GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select) \ (addr | cplt_base | (cq_offset << 24) | (ex_select << 10)) diff --git a/import/chips/p9/common/pmlib/include/occhw_irq_config.h b/import/chips/p9/common/pmlib/include/occhw_irq_config.h index 07d55103..66a1e5d3 100644 --- a/import/chips/p9/common/pmlib/include/occhw_irq_config.h +++ b/import/chips/p9/common/pmlib/include/occhw_irq_config.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -87,7 +87,7 @@ OCCHW_IRQ_OCC_MALF_ALERT OCCHW_IRQ_TARGET_ID_NONE \ OCCHW_IRQ_ADU_MALF_ALERT OCCHW_IRQ_TARGET_ID_NONE \ OCCHW_IRQ_EXTERNAL_TRAP OCCHW_IRQ_TARGET_ID_405_NONCRIT \ - OCCHW_IRQ_IVRM_PVREF_ERROR OCCHW_IRQ_TARGET_ID_NONE \ + OCCHW_IRQ_IVRM_PVREF_ERROR OCCHW_IRQ_TARGET_ID_GPE2 \ OCCHW_IRQ_OCC_TIMER0 OCCHW_IRQ_TARGET_ID_405_NONCRIT \ OCCHW_IRQ_OCC_TIMER1 OCCHW_IRQ_TARGET_ID_405_NONCRIT \ OCCHW_IRQ_HALT_PSTATES OCCHW_IRQ_TARGET_ID_NONE \ @@ -112,12 +112,12 @@ OCCHW_IRQ_STRM2_PUSH OCCHW_IRQ_TARGET_ID_405_NONCRIT \ OCCHW_IRQ_STRM3_PULL OCCHW_IRQ_TARGET_ID_405_NONCRIT \ OCCHW_IRQ_STRM3_PUSH OCCHW_IRQ_TARGET_ID_405_NONCRIT \ - OCCHW_IRQ_PMC_PCB_INTR_TYPE0_PENDING OCCHW_IRQ_TARGET_ID_NONE \ + OCCHW_IRQ_PMC_PCB_INTR_TYPE0_PENDING OCCHW_IRQ_TARGET_ID_GPE3 \ OCCHW_IRQ_PMC_PCB_INTR_TYPE1_PENDING OCCHW_IRQ_TARGET_ID_GPE2 \ OCCHW_IRQ_PMC_PCB_INTR_TYPE2_PENDING OCCHW_IRQ_TARGET_ID_GPE3 \ OCCHW_IRQ_PMC_PCB_INTR_TYPE3_PENDING OCCHW_IRQ_TARGET_ID_GPE3 \ OCCHW_IRQ_PMC_PCB_INTR_TYPE4_PENDING OCCHW_IRQ_TARGET_ID_GPE2 \ - OCCHW_IRQ_PMC_PCB_INTR_TYPE5_PENDING OCCHW_IRQ_TARGET_ID_GPE3 \ + OCCHW_IRQ_PMC_PCB_INTR_TYPE5_PENDING OCCHW_IRQ_TARGET_ID_GPE2 \ OCCHW_IRQ_PMC_PCB_INTR_TYPE6_PENDING OCCHW_IRQ_TARGET_ID_GPE3 \ OCCHW_IRQ_PMC_PCB_INTR_TYPE7_PENDING OCCHW_IRQ_TARGET_ID_NONE \ OCCHW_IRQ_PMC_O2S_0A_ONGOING OCCHW_IRQ_TARGET_ID_NONE \ diff --git a/import/chips/p9/common/pmlib/include/pstate_pgpe_cme_api.h b/import/chips/p9/common/pmlib/include/pstate_pgpe_cme_api.h index 7a51f0a5..570fb411 100644 --- a/import/chips/p9/common/pmlib/include/pstate_pgpe_cme_api.h +++ b/import/chips/p9/common/pmlib/include/pstate_pgpe_cme_api.h @@ -91,7 +91,9 @@ enum PMSR_DEFS enum MESSAGE_ID_DB0 { MSGID_DB0_VALID_START = 0, //This is for error checking - MSGID_DB0_DB3_GLOBAL_ACTUAL_BROADCAST = 0, + //This is used when sending DB3 with payloads in DB0. + //The reason is DB3 register has less bits than DB0. + MSGID_DB0_DB3_PAYLOAD = 0, MSGID_DB0_RESERVED = 1, MSGID_DB0_GLOBAL_ACTUAL_BROADCAST = 2, MSGID_DB0_START_PSTATE_BROADCAST = 3, @@ -105,12 +107,12 @@ enum MESSAGE_ID_DB0 enum MESSAGE_ID_DB3 { MSGID_DB3_INVALID = 0, - MSGID_DB3_VALID_START = 1, //This is for error checking - MSGID_DB3_HIGH_PRIORITY_PSTATE = 1, + MSGID_DB3_HIGH_PRIORITY_PSTATE = 0x01, + MSGID_DB3_ENTER_SAFE_MODE = 0x02, + MSGID_DB3_REPLAY_DB0 = 0x03, + MSGID_DB3_DISABLE_SGPE_HANDOFF = 0x04, MSGID_DB3_IMMEDIATE_HALT = 0xF1, MSGID_DB3_RESTORE_STATE_AND_HALT = 0xF2, - MSGID_DB3_REPLAY_DB0 = 0xF3, - MSGID_DB3_VALID_END = 0xF3 //This is for error checking }; enum MESSAGEID_PCB_TYPE4_ACK_TYPES @@ -130,7 +132,6 @@ enum DB0_CLIP_BCAST_FIELDS enum DB0_PMSR_UPDT_COMMANDS { - DB0_PMSR_UPDT_SET_SAFE_MODE = 0x0, DB0_PMSR_UPDT_SET_PSTATES_SUSPENDED = 0x1, DB0_PMSR_UPDT_CLEAR_PSTATES_SUSPENDED = 0x2 }; @@ -266,7 +267,7 @@ typedef union pgpe_db0_pmsr_updt // //PGPE-CME Doorbell0(Pstate Abort) // -typedef union pgpe_db0_pstate_start_abort +typedef union pgpe_db0_pstate_register_done { uint64_t value; struct @@ -279,7 +280,7 @@ typedef union pgpe_db0_pstate_start_abort uint64_t msg_id : 8; #endif } fields; -} pgpe_db0_pstate_start_abort_t; +} pgpe_db0_pstate_register_done_t; #endif //__PSTATE_PGPE_CME_API_H__ diff --git a/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h b/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h index 22b64597..75cd011a 100644 --- a/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h +++ b/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h @@ -68,6 +68,8 @@ enum MESSAGE_ID_IPI2HI // to using the new VFRT. The original VFRT is still being used. #define PGPE_WOF_RC_VFRT_QUAD_MISMATCH 0x20 #define PGPE_RC_REQ_WHILE_PENDING_ACK 0x21 +#define PGPE_RC_NULL_VFRT_POINTER 0x22 +#define PGPE_RC_INVALID_PMCR_OWNER 0x23 // // PMCR Owner 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 40a44ad8..81b6ba9e 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 @@ -30,14 +30,14 @@ enum SGPE_STOP_IRQ_PAYLOAD_MASKS { TYPE2_PAYLOAD_STOP_LEVEL = 0x00F, TYPE2_PAYLOAD_ENTRY_EVENT = 0x000, // 0000 - TYPE5_PAYLOAD_ENTRY_RCLK = 0x100, // 0001 + TYPE0_PAYLOAD_ENTRY_RCLK = 0x100, // 0001 // 0010 reserved // 0011 reserved TYPE2_PAYLOAD_EXIT_EVENT = 0xC00, // 1100 TYPE2_PAYLOAD_HARDWARE_WAKEUP = 0x800, // 1000 TYPE2_PAYLOAD_SOFTWARE_WAKEUP = 0x400, // 0100 - TYPE5_PAYLOAD_EXIT_RCLK = 0x500, // 0101 + TYPE0_PAYLOAD_EXIT_RCLK = 0x500, // 0101 // 0110 reserved TYPE2_PAYLOAD_DECREMENTER_WAKEUP = 0x700, // 0111 @@ -48,7 +48,6 @@ enum SGPE_STOP_IRQ_PAYLOAD_MASKS TYPE2_PAYLOAD_SUSPEND_SELECT_MASK = 0x080, TYPE2_PAYLOAD_SUSPEND_ACK_MASK = 0x040, - TYPE5_PAYLOAD_CME_ERROR = 0x3FF, TYPE6_PAYLOAD_EXIT_EVENT = 0x00F }; @@ -56,9 +55,9 @@ enum SGPE_STOP_IRQ_PAYLOAD_MASKS /// PIG TYPEs used by CME enum CME_STOP_PIG_TYPES { + PIG_TYPE0 = 0, PIG_TYPE2 = 2, - PIG_TYPE3 = 3, - PIG_TYPE5 = 5 + PIG_TYPE3 = 3 }; /// Numberical Doorbell Message IDs(used by CME check) 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 1deb386d..40812374 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 @@ -57,8 +57,8 @@ enum PM_GPE_OCCFLG_DEFS 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, + AUX_THREAD_ACTIVATE = 14, + AUX_THREAD_ACTIVE = 15, PIB_I2C_MASTER_ENGINE_1_LOCK_BIT0 = 16, //BIT0 ored BIT1 gives the field PIB_I2C_MASTER_ENGINE_1_LOCK_BIT1 = 17, //BIT0 ored BIT1 gives the field PIB_I2C_MASTER_ENGINE_2_LOCK_BIT0 = 18, //BIT0 ored BIT1 gives the field @@ -75,8 +75,13 @@ enum PM_GPE_OCCFLG_DEFS //Enum form of OCC FLAG2. enum PM_GPE_OCCFLG2_DEFS { + OCCFLG2_DEAD_CORES_START = 0, + OCCFLG2_DEAD_CORES_LENGTH = 24, + OCCFLG2_PGPE_HCODE_FIT_ERR_INJ = 27, PM_CALLOUT_ACTIVE = 28, - STOP_RECOVERY_TRIGGER_ENABLE = 29 + STOP_RECOVERY_TRIGGER_ENABLE = 29, + OCCFLG2_SGPE_HCODE_STOP_REQ_ERR_INJ = 30, + OCCFLG2_PGPE_HCODE_PSTATE_REQ_ERR_INJ = 31 }; // @@ -92,11 +97,12 @@ enum PM_GPE_OCC_SCRATCH2_DEFS CME_DEBUG_TRAP_ENABLE = 9, PGPE_DEBUG_TRAP_ENABLE = 10, L3_CONTAINED_MODE = 11, - PGPE_SAFE_MODE_ERROR = 12, + PGPE_SAFE_MODE_ERROR = 14, PM_DEBUG_HALT_ENABLE = 15, CORE_THROTTLE_CONTINUOUS_CHANGE_ENABLE = 16, PGPE_OP_TRACE_DISABLE = 24, PGPE_OP_TRACE_MEM_MODE = 25 + }; // @@ -104,31 +110,32 @@ enum PM_GPE_OCC_SCRATCH2_DEFS // enum PM_CME_FLAGS_DEFS { - CME_FLAGS_STOP_READY = 0, - CME_FLAGS_PMCR_READY = 1, - CME_FLAGS_QMGR_READY = 2, - CME_FLAGS_QMGR_MASTER = 3, - CME_FLAGS_RCLK_OPERABLE = 4, - CME_FLAGS_IVRM_OPERABLE = 5, - CME_FLAGS_VDM_OPERABLE = 6, - CME_FLAGS_OCC_HB_SAFE_MODE = 7, - CME_FLAGS_STOP_BLOCK_EXIT_C0 = 8, - CME_FLAGS_STOP_BLOCK_EXIT_C1 = 9, - CME_FLAGS_STOP_BLOCK_ENTRY_C0 = 10, - CME_FLAGS_STOP_BLOCK_ENTRY_C1 = 11, - CME_FLAGS_CORE_QUIESCE_ACTIVE = 12, - CME_FLAGS_PM_DEBUG_HALT_ENABLE = 13, - CME_FLAGS_WAIT_ON_PSTATE_START = 14, - CME_FLAGS_SPWU_CHECK_ENABLE = 22, - CME_FLAGS_BLOCK_ENTRY_STOP11 = 23, - CME_FLAGS_PSTATES_ENABLED = 24, - CME_FLAGS_FREQ_UPDT_DISABLE = 25, - CME_FLAGS_EX_ID = 26, - CME_FLAGS_SIBLING_FUNCTIONAL = 27, - CME_FLAGS_STOP_ENTRY_FIRST_C0 = 28, - CME_FLAGS_STOP_ENTRY_FIRST_C1 = 29, - CME_FLAGS_CORE0_GOOD = 30, - CME_FLAGS_CORE1_GOOD = 31 + CME_FLAGS_STOP_READY = 0, + CME_FLAGS_PMCR_READY = 1, + CME_FLAGS_QMGR_READY = 2, + CME_FLAGS_QMGR_MASTER = 3, + CME_FLAGS_RCLK_OPERABLE = 4, + CME_FLAGS_IVRM_OPERABLE = 5, + CME_FLAGS_VDM_OPERABLE = 6, + CME_FLAGS_PGPE_HB_LOSS_SAFE_MODE = 7, + CME_FLAGS_STOP_BLOCK_EXIT_C0 = 8, + CME_FLAGS_STOP_BLOCK_EXIT_C1 = 9, + CME_FLAGS_STOP_BLOCK_ENTRY_C0 = 10, + CME_FLAGS_STOP_BLOCK_ENTRY_C1 = 11, + CME_FLAGS_CORE_QUIESCE_ACTIVE = 12, + CME_FLAGS_PM_DEBUG_HALT_ENABLE = 13, + CME_FLAGS_SAFE_MODE = 16, + CME_FLAGS_PSTATES_SUSPENDED = 17, + CME_FLAGS_SPWU_CHECK_ENABLE = 22, + CME_FLAGS_BLOCK_ENTRY_STOP11 = 23, + CME_FLAGS_PSTATES_ENABLED = 24, + CME_FLAGS_FREQ_UPDT_DISABLE = 25, + CME_FLAGS_EX_ID = 26, + CME_FLAGS_SIBLING_FUNCTIONAL = 27, + CME_FLAGS_STOP_ENTRY_FIRST_C0 = 28, + CME_FLAGS_STOP_ENTRY_FIRST_C1 = 29, + CME_FLAGS_CORE0_GOOD = 30, + CME_FLAGS_CORE1_GOOD = 31 }; // @@ -147,6 +154,8 @@ enum PM_CME_SCRATCH_DEFS // enum PM_CPPM_CSAR_DEFS { + CPPM_CSAR_FIT_HCODE_ERROR_INJECT = 27, + CPPM_CSAR_ENABLE_PSTATE_REGISTRATION_INTERLOCK = 28, CPPM_CSAR_DISABLE_CME_NACK_ON_PROLONGED_DROOP = 29, CPPM_CSAR_PSTATE_HCODE_ERROR_INJECT = 30, CPPM_CSAR_STOP_HCODE_ERROR_INJECT = 31 diff --git a/import/chips/p9/procedures/ppe_closed/cme/iota_lnk_cfg.h b/import/chips/p9/procedures/ppe_closed/cme/iota_lnk_cfg.h index 2bbf930c..521a85fb 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/iota_lnk_cfg.h +++ b/import/chips/p9/procedures/ppe_closed/cme/iota_lnk_cfg.h @@ -37,8 +37,8 @@ #define PPE_DEBUG_PTRS_OFFSET CME_DEBUG_PTRS_OFFSET #define PPE_DEBUG_PTRS_SIZE CME_DEBUG_PTRS_SIZE -#define PPE_DUMP_PTR_PSTATE_SIZE 0x4C +#define PPE_DUMP_PTR_PSTATE_SIZE 0x50 #define PPE_DUMP_PTR_STOP_SIZE 0x34 -#define PPE_DUMP_PTR_COMMON_SIZE 0x8 +#define PPE_DUMP_PTR_COMMON_SIZE 0xC #endif diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme.h b/import/chips/p9/procedures/ppe_closed/cme/p9_cme.h index 54f93b28..f3ad4f98 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme.h +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme.h @@ -47,8 +47,9 @@ typedef struct typedef struct { // target mask of enabled cores, used to filter 2bit core select in scom address - uint32_t core_enabled; - uint32_t spurr_freq_ref_upper; + uint32_t core_enabled; + uint32_t spurr_freq_ref_upper; + uint32_t disableSGPEHandoff; } CmeRecord; diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_iota_main.c b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_iota_main.c index 00cc3753..0aa0651d 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_iota_main.c +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_iota_main.c @@ -31,7 +31,7 @@ // CME Pstate Header and Structure #include "p9_cme.h" -CmeRecord G_cme_record = {0, 0}; +CmeRecord G_cme_record = {0, 0, 0}; // CME Pstate Header and Structure #include "p9_cme_pstate.h" @@ -49,6 +49,17 @@ CmeFitRecord G_cme_fit_record = {0, 0, 0, 0, 0xFFFFFFFF, 0}; void fit_handler() { + data64_t scom_data; + scom_data.value = 0; + + CME_GETSCOM_OR(CPPM_CSAR, CME_MASK_BC, scom_data.value); + + if(BIT32(CPPM_CSAR_FIT_HCODE_ERROR_INJECT) & scom_data.words.upper) + { + PKTRACE("CME FIT ERROR INJECT TRAP"); + PK_PANIC(CME_STOP_ENTRY_TRAP_INJECT); + } + mtspr(SPRN_TSR, TSR_FIS); PK_TRACE("FIT Timer Handler"); @@ -78,12 +89,10 @@ void p9_cme_hipri_ext_handler(uint32_t task_idx) PK_TRACE_ERR("CME HIGHEST PRIORITY EXCEPTION DETECTED. EISR(0:7) = %02x", eisr_subset >> 24 ); - - // report and clear only the first one found - // multiples of this priority will cause repeated interrupts until they are all cleared uint32_t bitnum = cntlz32(eisr_subset); if(in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_PM_DEBUG_HALT_ENABLE)) + { switch (bitnum) { case 0: @@ -104,14 +113,17 @@ void p9_cme_hipri_ext_handler(uint32_t task_idx) default: break; } + } - uint32_t eisr_mask = (1 << (31 - bitnum)); - out32(CME_LCL_EISR_CLR, eisr_mask); + //if debug halt is NOT enabled, clear the ones reported in the trace + //above and return + out32(CME_LCL_EISR_CLR, eisr_subset); } IOTA_BEGIN_TASK_TABLE IOTA_TASK(p9_cme_hipri_ext_handler), // bits 0-3,5 IOTA_TASK(p9_cme_pstate_db3_handler), // bits 10,11 + IOTA_TASK(p9_cme_pgpe_hb_loss_handler), //bit 4 IOTA_TASK(p9_cme_stop_db2_handler), // bits 18,19 IOTA_TASK(p9_cme_stop_spwu_handler), // bits 14,15 IOTA_TASK(p9_cme_stop_rgwu_handler), // bits 16,17 diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h index 3fe0e411..c5a29801 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h @@ -51,52 +51,55 @@ // Priority Levels #define IDX_PRTY_LVL_HIPRTY 0 #define IDX_PRTY_LVL_DB3 1 -#define IDX_PRTY_LVL_DB2 2 -#define IDX_PRTY_LVL_SPWU 3 -#define IDX_PRTY_LVL_RGWU 4 -#define IDX_PRTY_LVL_PCWU 5 -#define IDX_PRTY_LVL_PM_ACTIVE 6 -#define IDX_PRTY_LVL_DB1 7 -#define IDX_PRTY_LVL_DB0 8 -#define IDX_PRTY_LVL_INTERCME_IN0 9 -#define IDX_PRTY_LVL_PMCR 10 -#define IDX_PRTY_LVL_COMM_RECVD 11 -#define IDX_PRTY_LVL_DISABLED 12 +#define IDX_PRTY_LVL_HB_LOSS 2 +#define IDX_PRTY_LVL_DB2 3 +#define IDX_PRTY_LVL_SPWU 4 +#define IDX_PRTY_LVL_RGWU 5 +#define IDX_PRTY_LVL_PCWU 6 +#define IDX_PRTY_LVL_PM_ACTIVE 7 +#define IDX_PRTY_LVL_DB1 8 +#define IDX_PRTY_LVL_DB0 9 +#define IDX_PRTY_LVL_INTERCME_IN0 10 +#define IDX_PRTY_LVL_PMCR 11 +#define IDX_PRTY_LVL_COMM_RECVD 12 +#define IDX_PRTY_LVL_DISABLED 13 #define IDX_PRTY_VEC 0 #define IDX_MASK_VEC 1 -#define NUM_EXT_IRQ_PRTY_LEVELS 13 +#define NUM_EXT_IRQ_PRTY_LEVELS 14 // Group0: Non-task hi-prty IRQs -#define IRQ_VEC_PRTY0_CME (uint64_t)(0xFE00000000000000) +#define IRQ_VEC_PRTY0_CME (uint64_t)(0xF600000000000000) // Group1: DB3 #define IRQ_VEC_PRTY1_CME (uint64_t)(0x0030000000000000) -// Group2: DB2 -#define IRQ_VEC_PRTY2_CME (uint64_t)(0x0000300000000000) -// Group3: SPWU -#define IRQ_VEC_PRTY3_CME (uint64_t)(0x0003000000000000) -#define IRQ_SPWU IRQ_VEC_PRTY3_CME -// Group4: RGWU -#define IRQ_VEC_PRTY4_CME (uint64_t)(0x0000C00000000000) -#define IRQ_RGWU IRQ_VEC_PRTY4_CME -// Group5: PCWU -#define IRQ_VEC_PRTY5_CME (uint64_t)(0x000C000000000000) -#define IRQ_PCWU IRQ_VEC_PRTY5_CME -// Group6: PM_ACTIVE -#define IRQ_VEC_PRTY6_CME (uint64_t)(0x00000C0000000000) -#define IRQ_PMACT IRQ_VEC_PRTY6_CME -// Group7: DB1 -#define IRQ_VEC_PRTY7_CME (uint64_t)(0x0000000000C00000) -#define IRQ_DB1 IRQ_VEC_PRTY7_CME -// Group8: DB0 -#define IRQ_VEC_PRTY8_CME (uint64_t)(0x000000000C000000) -// Group9: INTERCME_IN0 -#define IRQ_VEC_PRTY9_CME (uint64_t)(0x0100000000000000) -// Group10: PMCR -#define IRQ_VEC_PRTY10_CME (uint64_t)(0x0000000030000000) -// Group11: COMM_RECVD -#define IRQ_VEC_PRTY11_CME (uint64_t)(0x0000000400000000) -// Group12: We should never detect these -#define IRQ_VEC_PRTY12_CME (uint64_t)(0x00C003FBC33FFFFF) +// Group2: HB LOSS +#define IRQ_VEC_PRTY2_CME (uint64_t)(0x0800000000000000) +// Group3: DB2 +#define IRQ_VEC_PRTY3_CME (uint64_t)(0x0000300000000000) +// Group4: SPWU +#define IRQ_VEC_PRTY4_CME (uint64_t)(0x0003000000000000) +#define IRQ_SPWU IRQ_VEC_PRTY4_CME +// Group5: RGWU +#define IRQ_VEC_PRTY5_CME (uint64_t)(0x0000C00000000000) +#define IRQ_RGWU IRQ_VEC_PRTY5_CME +// Group6: PCWU +#define IRQ_VEC_PRTY6_CME (uint64_t)(0x000C000000000000) +#define IRQ_PCWU IRQ_VEC_PRTY6_CME +// Group7: PM_ACTIVE +#define IRQ_VEC_PRTY7_CME (uint64_t)(0x00000C0000000000) +#define IRQ_PMACT IRQ_VEC_PRTY7_CME +// Group8: DB1 +#define IRQ_VEC_PRTY8_CME (uint64_t)(0x0000000000C00000) +#define IRQ_DB1 IRQ_VEC_PRTY8_CME +// Group9: DB0 +#define IRQ_VEC_PRTY9_CME (uint64_t)(0x000000000C000000) +// Group10: INTERCME_IN0 +#define IRQ_VEC_PRTY10_CME (uint64_t)(0x0100000000000000) +// Group11: PMCR +#define IRQ_VEC_PRTY11_CME (uint64_t)(0x0000000030000000) +// Group12: COMM_RECVD +#define IRQ_VEC_PRTY12_CME (uint64_t)(0x0000000400000000) +// Group13: We should never detect these +#define IRQ_VEC_PRTY13_CME (uint64_t)(0x00C003FBC33FFFFF) // Combined vector for all Stop IRQs that need to be manually // masked during STOP state processing Do not include DB2 (always unmasked) @@ -121,7 +124,8 @@ IRQ_VEC_PRTY9_CME | \ IRQ_VEC_PRTY10_CME | \ IRQ_VEC_PRTY11_CME | \ - IRQ_VEC_PRTY12_CME ) + IRQ_VEC_PRTY12_CME | \ + IRQ_VEC_PRTY13_CME ) #define IRQ_VEC_PRTY_XOR_CHECK (IRQ_VEC_PRTY0_CME ^ \ IRQ_VEC_PRTY1_CME ^ \ @@ -135,4 +139,5 @@ IRQ_VEC_PRTY9_CME ^ \ IRQ_VEC_PRTY10_CME ^ \ IRQ_VEC_PRTY11_CME ^ \ - IRQ_VEC_PRTY12_CME ) + IRQ_VEC_PRTY12_CME ^ \ + IRQ_VEC_PRTY13_CME ) diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq_priority_table.c b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq_priority_table.c index bf5a39b2..73d53125 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq_priority_table.c +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq_priority_table.c @@ -49,7 +49,8 @@ const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = IRQ_VEC_PRTY9_CME | IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | - IRQ_VEC_PRTY12_CME + IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME }, { IRQ_VEC_PRTY1_CME, /* 1: IDX_PRTY_LVL_DB3 */ @@ -64,10 +65,11 @@ const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = IRQ_VEC_PRTY9_CME | IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | - IRQ_VEC_PRTY12_CME + IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME }, { - IRQ_VEC_PRTY2_CME, /* 2: IDX_PRTY_LVL_DB2 */ + IRQ_VEC_PRTY2_CME, /* 2: IDX_PRTY_LVL_HB_LOSS */ IRQ_VEC_PRTY2_CME | IRQ_VEC_PRTY3_CME | IRQ_VEC_PRTY4_CME | @@ -78,10 +80,11 @@ const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = IRQ_VEC_PRTY9_CME | IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | - IRQ_VEC_PRTY12_CME + IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME }, { - IRQ_VEC_PRTY3_CME, /* 3: IDX_PRTY_LVL_SPWU */ + IRQ_VEC_PRTY3_CME, /* 3: IDX_PRTY_LVL_DB2 */ IRQ_VEC_PRTY3_CME | IRQ_VEC_PRTY4_CME | IRQ_VEC_PRTY5_CME | @@ -91,10 +94,11 @@ const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = IRQ_VEC_PRTY9_CME | IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | - IRQ_VEC_PRTY12_CME + IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME }, { - IRQ_VEC_PRTY4_CME, /* 4: IDX_PRTY_LVL_RGWU */ + IRQ_VEC_PRTY4_CME, /* 4: IDX_PRTY_LVL_SPWU */ IRQ_VEC_PRTY4_CME | IRQ_VEC_PRTY5_CME | IRQ_VEC_PRTY6_CME | @@ -104,13 +108,14 @@ const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME | // For Stop Entry/Exit related priority groups, mask every other SE/SX // related priority group, even higher ones, since the actual procedures // will open up EIMR at specific points in the SE/SX sequence. IRQ_VEC_STOP_CME }, { - IRQ_VEC_PRTY5_CME, /* 5: IDX_PRTY_LVL_PCWU */ + IRQ_VEC_PRTY5_CME, /* 5: IDX_PRTY_LVL_RGWU */ IRQ_VEC_PRTY5_CME | IRQ_VEC_PRTY6_CME | IRQ_VEC_PRTY7_CME | @@ -119,13 +124,14 @@ const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME | // For Stop Entry/Exit related priority groups, mask every other SE/SX // related priority group, even higher ones, since the actual procedures // will open up EIMR at specific points in the SE/SX sequence. IRQ_VEC_STOP_CME }, { - IRQ_VEC_PRTY6_CME, /* 6: IDX_PRTY_LVL_PM_ACTIVE */ + IRQ_VEC_PRTY6_CME, /* 6: IDX_PRTY_LVL_PCWU */ IRQ_VEC_PRTY6_CME | IRQ_VEC_PRTY7_CME | IRQ_VEC_PRTY8_CME | @@ -133,37 +139,49 @@ const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME | // For Stop Entry/Exit related priority groups, mask every other SE/SX // related priority group, even higher ones, since the actual procedures // will open up EIMR at specific points in the SE/SX sequence. IRQ_VEC_STOP_CME }, { - IRQ_VEC_PRTY7_CME, /* 7: IDX_PRTY_LVL_DB1 */ + IRQ_VEC_PRTY7_CME, /* 7: IDX_PRTY_LVL_PM_ACTIVE */ IRQ_VEC_PRTY7_CME | IRQ_VEC_PRTY8_CME | IRQ_VEC_PRTY9_CME | IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | - IRQ_VEC_PRTY12_CME + IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME }, { - IRQ_VEC_PRTY8_CME, /* 8: IDX_PRTY_LVL_DB0 */ + IRQ_VEC_PRTY8_CME, /* 8: IDX_PRTY_LVL_DB1 */ IRQ_VEC_PRTY8_CME | IRQ_VEC_PRTY9_CME | IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | - IRQ_VEC_PRTY12_CME + IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME }, { - IRQ_VEC_PRTY9_CME, /* 9: IDX_PRTY_LVL_INTERCME_IN0 */ + IRQ_VEC_PRTY9_CME, /* 9: IDX_PRTY_LVL_DB0 */ IRQ_VEC_PRTY9_CME | IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY11_CME | IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME + }, + { + IRQ_VEC_PRTY10_CME, /* 10: IDX_PRTY_LVL_INTERCME_IN0 */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY11_CME | + IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME | // The entirety of this handler is executed in EE=0 mode on PK, for IOTA // this behavior can ony be emulated by masking all higher priority // interrupts in the UIH + IRQ_VEC_PRTY9_CME | IRQ_VEC_PRTY8_CME | IRQ_VEC_PRTY7_CME | IRQ_VEC_PRTY6_CME | @@ -174,18 +192,19 @@ const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = IRQ_VEC_PRTY1_CME }, { - IRQ_VEC_PRTY10_CME, /* 10: IDX_PRTY_LVL_PMCR */ - IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY11_CME, /* 11: IDX_PRTY_LVL_PMCR */ IRQ_VEC_PRTY11_CME | - IRQ_VEC_PRTY12_CME + IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME }, { - IRQ_VEC_PRTY11_CME, /* 11: IDX_PRTY_LVL_COMM_RECVD */ - IRQ_VEC_PRTY11_CME | + IRQ_VEC_PRTY12_CME, /* 12: IDX_PRTY_LVL_COMM_RECVD */ IRQ_VEC_PRTY12_CME | + IRQ_VEC_PRTY13_CME | // The entirety of this handler is executed in EE=0 mode on PK, for IOTA // this behavior can ony be emulated by masking all higher priority // interrupts in the UIH + IRQ_VEC_PRTY11_CME | IRQ_VEC_PRTY10_CME | IRQ_VEC_PRTY9_CME | IRQ_VEC_PRTY8_CME | @@ -199,8 +218,8 @@ const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = }, { - IRQ_VEC_PRTY12_CME, /* 12: IDX_PRTY_LVL_DISABLED */ - IRQ_VEC_PRTY12_CME + IRQ_VEC_PRTY13_CME, /* 13: IDX_PRTY_LVL_DISABLED */ + IRQ_VEC_PRTY13_CME } }; diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_main.c b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_main.c index 48beb30a..be6e5eda 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_main.c +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_main.c @@ -51,7 +51,7 @@ IRQ_HANDLER_DEFAULT //CMEHW_IRQ_DEBUGGER IRQ_HANDLER_DEFAULT //CMEHW_IRQ_DEBUG_TRIGGER IRQ_HANDLER_DEFAULT //CMEHW_IRQ_QUAD_CHECKSTOP IRQ_HANDLER_DEFAULT //CMEHW_IRQ_PVREF_FAIL -IRQ_HANDLER_DEFAULT //CMEHW_IRQ_OCC_HEARTBEAT_LOST +IRQ_HANDLER(p9_cme_pgpe_hb_loss_handler, 0) //CMEHW_IRQ_OCC_HEARTBEAT_LOST IRQ_HANDLER_DEFAULT //CMEHW_IRQ_CORE_CHECKSTOP IRQ_HANDLER_DEFAULT //CMEHW_IRQ_DROPOUT_FAIL IRQ_HANDLER(p9_cme_pstate_intercme_in0_irq_handler, (void*)NULL) @@ -85,7 +85,7 @@ IRQ_HANDLER_DEFAULT //CMEHW_IRQ_CHTM_PURGE_DONE_C1 IRQ_HANDLER_DEFAULT //CMEHW_IRQ_BCE_BUSY_LOW IRQ_HANDLER_DEFAULT //CMEHW_IRQ_FINAL_VDM_DATA0 IRQ_HANDLER_DEFAULT //CMEHW_IRQ_FINAL_VDM_DATA1 -IRQ_HANDLER(p9_cme_pstate_intercme_msg_handler, (void*)NULL) //CMEHW_IRQ_COMM_RECVD +IRQ_HANDLER(p9_cme_pstate_intercme_msg_handler, 0) //CMEHW_IRQ_COMM_RECVD IRQ_HANDLER_DEFAULT //CMEHW_IRQ_COMM_SEND_ACK IRQ_HANDLER_DEFAULT //CMEHW_IRQ_COMM_SEND_NACK IRQ_HANDLER_DEFAULT //CMEHW_IRQ_SPARE_32 diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c index d84b6896..bd7645c3 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c @@ -49,43 +49,45 @@ extern CmeRecord G_cme_record; // void p9_cme_pstate_intercme_in0_irq_handler(void) { - p9_cme_pstate_process_db0_sibling(); - } void p9_cme_pstate_intercme_msg_handler(void) { - - p9_cme_pstate_sibling_lock_and_intercme_protocol(0); - + p9_cme_pstate_sibling_lock_and_intercme_protocol(INTERCME_MSG_LOCK_WAIT_ON_RECV , + INTERCME_IN0_PROCESS_SKIP); } -void p9_cme_pstate_sibling_lock_and_intercme_protocol(uint32_t process_intercme_in0) +void p9_cme_pstate_sibling_lock_and_intercme_protocol(INTERCME_MSG_LOCK_ACTION intercme_msg_lock_action, + INTERCME_IN0_PROCESS_ACTION intercme_in0_process_action) { - PK_TRACE("SIBL: Enter"); + PK_TRACE_INF("SIBL: Enter"); uint32_t msg; - intercme_msg_recv(&msg, IMT_LOCK_SIBLING); - // Block on the intercme0/intercme1 interrupt + if (intercme_msg_lock_action == INTERCME_MSG_LOCK_WAIT_ON_RECV) + { + intercme_msg_recv(&msg, IMT_LOCK_SIBLING); + } + + // Block on the intercme0/intercme1/intercme2 interrupt while((!(in32(CME_LCL_EISR) & BIT32(7))) && (!(in32_sh(CME_LCL_EISR) & BIT64SH(38)))) {} //If INTERCME_DIRECT_IN1, then error. if(in32_sh(CME_LCL_EISR) & BIT64SH(38)) { - G_cme_pstate_record.pstatesSuspended = 1; + out32(CME_LCL_FLAGS_OR, BIT32(CME_FLAGS_PSTATES_SUSPENDED)); p9_cme_pstate_pmsr_updt(); intercme_direct(INTERCME_DIRECT_IN1, INTERCME_DIRECT_ACK, 0); } //If INTERCME_DIRECT_IN0, then process DB0 data - if((in32(CME_LCL_EISR) & BIT32(7)) && (process_intercme_in0 == 1)) + if((in32(CME_LCL_EISR) & BIT32(7)) && (intercme_in0_process_action == INTERCME_IN0_PROCESS)) { p9_cme_pstate_process_db0_sibling(); } - PK_TRACE("SIBL: Enter"); + PK_TRACE_INF("SIBL: Exit"); } void p9_cme_pstate_process_db0_sibling() @@ -97,7 +99,7 @@ void p9_cme_pstate_process_db0_sibling() //writes same value for both cores CME_GETSCOM(CPPM_CMEDB0, G_cme_pstate_record.firstGoodCoreMask, dbData.value); - PK_TRACE("INTER0: Enter"); + PK_TRACE_INF("INTER0: Enter"); dbQuadInfo = (dbData.value >> (in32(CME_LCL_SRTCH0) & (BITS32(CME_SCRATCH_LOCAL_PSTATE_IDX_START, CME_SCRATCH_LOCAL_PSTATE_IDX_LENGTH) @@ -106,30 +108,33 @@ void p9_cme_pstate_process_db0_sibling() if(dbData.fields.cme_message_number0 == MSGID_DB0_START_PSTATE_BROADCAST) { - PK_TRACE("INTER0: DB0 Start"); + PK_TRACE_INF("INTER0: DB0 Start"); G_cme_pstate_record.quadPstate = dbQuadInfo; G_cme_pstate_record.globalPstate = dbBit8_15; p9_cme_pstate_pmsr_updt(); - // Enable PMCR updates for good cores + //Enable PMCR updates for good cores g_eimr_override &= ~(uint64_t)(G_cme_record.core_enabled << SHIFT64(35)); + //Unmask EIMR[OCC_HEARTBEAT_LOST/4] + g_eimr_override &= ~BIT64(4); + //Clear Core GPMMR RESET_STATE_INDICATOR bit to show pstates have started CME_PUTSCOM(PPM_GPMMR_CLR, G_cme_record.core_enabled, BIT64(15)); } else if((dbData.fields.cme_message_number0 == MSGID_DB0_GLOBAL_ACTUAL_BROADCAST) || - (dbData.fields.cme_message_number0 == MSGID_DB0_DB3_GLOBAL_ACTUAL_BROADCAST)) + (dbData.fields.cme_message_number0 == MSGID_DB0_DB3_PAYLOAD)) { - PK_TRACE("INTER0: DB0 GlbBcast"); + PK_TRACE_INF("INTER0: DB0 GlbBcast"); G_cme_pstate_record.quadPstate = dbQuadInfo; G_cme_pstate_record.globalPstate = dbBit8_15; p9_cme_pstate_pmsr_updt(); } else if(dbData.fields.cme_message_number0 == MSGID_DB0_CLIP_BROADCAST) { - PK_TRACE("INTER0: DB0 Clip"); + PK_TRACE_INF("INTER0: DB0 Clip"); if (dbBit8_15 == DB0_CLIP_BCAST_TYPE_PMIN) { @@ -144,10 +149,12 @@ void p9_cme_pstate_process_db0_sibling() } else if(dbData.fields.cme_message_number0 == MSGID_DB0_STOP_PSTATE_BROADCAST) { - PK_TRACE("INTER0: DB0 Stop"); + PK_TRACE_INF("INTER0: DB0 Stop"); out32_sh(CME_LCL_EIMR_OR, (BITS64SH(34, 2)));//Disable PMCR0/1 g_eimr_override |= BITS64(34, 2); + g_eimr_override |= BIT64(4); + //PGPE will update the LMCR[0] before sending the STOP PSTATE Doorbell. //Here we update the PMSR to indicate that Pstates are no longer honored accordingly. p9_cme_pstate_pmsr_updt(); @@ -157,20 +164,16 @@ void p9_cme_pstate_process_db0_sibling() } else if(dbData.fields.cme_message_number0 == MSGID_DB0_PMSR_UPDT) { - PK_TRACE("INTER0: DB0 PMSR Updt"); + PK_TRACE_INF("INTER0: DB0 PMSR Updt"); switch(dbBit8_15) { - case DB0_PMSR_UPDT_SET_SAFE_MODE: - G_cme_pstate_record.safeMode = 1; - break; - case DB0_PMSR_UPDT_SET_PSTATES_SUSPENDED: - G_cme_pstate_record.pstatesSuspended = 1; + out32(CME_LCL_FLAGS_OR, BIT32(CME_FLAGS_PSTATES_SUSPENDED)); break; case DB0_PMSR_UPDT_CLEAR_PSTATES_SUSPENDED: - G_cme_pstate_record.pstatesSuspended = 0; + out32(CME_LCL_FLAGS_CLR, BIT32(CME_FLAGS_PSTATES_SUSPENDED)); break; } @@ -185,5 +188,5 @@ void p9_cme_pstate_process_db0_sibling() intercme_direct(INTERCME_DIRECT_IN0, INTERCME_DIRECT_ACK, 0); - PK_TRACE("INTER0: Exit"); + PK_TRACE_INF("INTER0: Exit"); } diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c index 6f1a9b1a..d0b00ca3 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c @@ -75,8 +75,8 @@ int send_pig_packet(uint64_t data, uint32_t coreMask) { int rc = 0; uint64_t data_tmp; - PkMachineContext ctx __attribute__((unused)); + pk_critical_section_enter(&ctx); // First make sure no interrupt request is currently granted @@ -87,6 +87,8 @@ int send_pig_packet(uint64_t data, uint32_t coreMask) } while ((((ppm_pig_t)data_tmp).fields.pending_source & 0x1)); + PK_TRACE_INF("send pig core=0x%x, data=0x%08x%08x", coreMask, data >> 32, data); + // Send PIG packet CME_PUTSCOM(PPM_PIG, coreMask, data); PK_TRACE_DBG("CME: Sending PIG[%x] at core[%x]", @@ -97,11 +99,34 @@ int send_pig_packet(uint64_t data, uint32_t coreMask) return rc; } +void send_ack_to_pgpe(uint32_t ack) +{ + ppm_pig_t ppmPigData; + ppmPigData.value = 0; + ppmPigData.fields.req_intr_type = 4; + ppmPigData.fields.req_intr_payload = ack; + send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); +} + uint32_t poll_dpll_stat() { data64_t data; uint32_t rc = 0; + // DPLL Modes + // enable_fmin enable_fmax enable_jump + // DPLL Mode 2 0 0 0 + // DPLL Mode 3 0 0 1 + // DPLL Mode 4 X 1 0 + // DPLL Mode 4 1 X 0 + // DPLL Mode 3.5 0 1 1 + // DPLL Mode 5 1 X 1 + // TODO Future Attributes + // DROOP_PROTECT -> DPLL Mode 3 + // DROOP_PROTECT_OVERVOLT -> DPLL Mode 3.5 + // DYNAMIC -> DPLL Mode 4 + // DYNAMIC_PROTECT -> DPLL Mode 5 + // DPLL Mode 2 if(!(in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_VDM_OPERABLE))) { @@ -572,29 +597,34 @@ inline uint32_t update_vdm_jump_values_in_dpll(uint32_t pstate, uint32_t region) PkMachineContext ctx __attribute__((unused)); pk_critical_section_enter(&ctx); - qppm_dpll_freq_t saved_dpll_val; - qppm_dpll_freq_t reduced_dpll_val; - // The frequency needs to be reduced by the N_L amount, this depends on - // if the frequency has already been changed (if raising ps, then the - // freq has already been dropped and the N_L value is based on that, ie. "new") - uint32_t adj_n_l = (pstate >= G_cme_pstate_record.quadPstate) - ? (new_jump_values & BITS32(0, 4)) >> 28 - : (scom_data.words.lower & BITS32(0, 4)) >> 28; - data64_t poll_data; - // Read the current freq controls - nonatomic_ippm_read(QPPM_DPLL_FREQ, &saved_dpll_val.value); - // Reduce freq by N_L (in 32nds) - reduced_dpll_val.value = 0; - reduced_dpll_val.fields.fmult = mulu16(saved_dpll_val.fields.fmult - , (32 - adj_n_l)) >> 5; - reduced_dpll_val.fields.fmax = reduced_dpll_val.fields.fmult; - reduced_dpll_val.fields.fmin = reduced_dpll_val.fields.fmult; - // Write the reduced frequency - nonatomic_ippm_write(QPPM_DPLL_FREQ, reduced_dpll_val.value); - rc = poll_dpll_stat(); - - if (!rc) + do { + qppm_dpll_freq_t saved_dpll_val; + qppm_dpll_freq_t reduced_dpll_val; + // The frequency needs to be reduced by the N_L amount, this depends on + // if the frequency has already been changed (if raising ps, then the + // freq has already been dropped and the N_L value is based on that, ie. "new") + uint32_t adj_n_l = (pstate >= G_cme_pstate_record.quadPstate) + ? (new_jump_values & BITS32(0, 4)) >> 28 + : (scom_data.words.lower & BITS32(0, 4)) >> 28; + data64_t poll_data; + // Read the current freq controls + nonatomic_ippm_read(QPPM_DPLL_FREQ, &saved_dpll_val.value); + // Reduce freq by N_L (in 32nds) + reduced_dpll_val.value = 0; + reduced_dpll_val.fields.fmult = (saved_dpll_val.fields.fmult + * (32 - adj_n_l)) >> 5; + reduced_dpll_val.fields.fmax = reduced_dpll_val.fields.fmult; + reduced_dpll_val.fields.fmin = reduced_dpll_val.fields.fmult; + // Write the reduced frequency + nonatomic_ippm_write(QPPM_DPLL_FREQ, reduced_dpll_val.value); + rc = poll_dpll_stat(); + + if (rc) + { + break; //If rc, then skip to the bottom of the function + } + // Clear jump enable (drop to Mode 2) nonatomic_ippm_write(QPPM_DPLL_CTRL_CLR, BIT64(1)); // Poll for lock @@ -622,8 +652,14 @@ inline uint32_t update_vdm_jump_values_in_dpll(uint32_t pstate, uint32_t region) // Restore frequency nonatomic_ippm_write(QPPM_DPLL_FREQ, saved_dpll_val.value); rc = poll_dpll_stat(); + + if (rc) + { + break; //If rc, then skip to the bottom of the function + } } } + while(0); pk_critical_section_exit(&ctx); } @@ -836,6 +872,7 @@ void p9_cme_resclk_update(ANALOG_TARGET target, uint32_t next_idx, uint32_t curr void p9_cme_pstate_pmsr_updt() { uint64_t pmsrData; + uint32_t cme_flags = in32(CME_LCL_FLAGS); //Note: PMSR[58/UPDATE_IN_PROGRESS] is always cleared here pmsrData = ((uint64_t)G_cme_pstate_record.globalPstate) << 56; @@ -852,13 +889,13 @@ void p9_cme_pstate_pmsr_updt() } //PMSR[33] is SAFE_MODE bit - if(G_cme_pstate_record.safeMode) + if(cme_flags & BIT32(CME_FLAGS_SAFE_MODE)) { pmsrData |= BIT64(33); } //PMSR[35] is PSTATES_SUSPENDED bit - if(G_cme_pstate_record.pstatesSuspended) + if(cme_flags & BIT32(CME_FLAGS_PSTATES_SUSPENDED)) { pmsrData |= BIT64(35); } diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h index 74f162bf..68bd1c87 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h @@ -167,6 +167,19 @@ enum DB0_TRIGGER PROCESS_DB0_TRIGGER_DB3_IRQ = 2, }; +typedef enum +{ + INTERCME_MSG_LOCK_WAIT_ON_RECV = 0, + INTERCME_MSG_LOCK_SKIP = 1, +} INTERCME_MSG_LOCK_ACTION; + +typedef enum +{ + INTERCME_IN0_PROCESS = 0, + INTERCME_IN0_PROCESS_SKIP = 1, +} INTERCME_IN0_PROCESS_ACTION; + + typedef struct { uint32_t qmFlag; //4 @@ -174,13 +187,18 @@ typedef struct uint32_t quadPstate; //12 uint32_t firstGoodCoreMask; //16 uint32_t globalPstate; //20 - cme_resclk_data_t resclkData; //40 - cme_vdm_data_t vdmData; //56 - uint32_t pmin; //60 - uint32_t safeMode; //64 - uint32_t pmax; //68 - uint32_t pstatesSuspended; //72 - uint32_t nextPstate; //76 + uint32_t pmin; //24 + uint32_t pmax; //28 + uint32_t nextPstate; //32 + uint32_t updateAnalogError; //36 + //This is set and cleared during CME boot(registration, so no need + //to protect it in critical section. It only serves to make sure + //that p9_cme_update_analog is called if pstates are started during + //registration even + uint32_t registerInProgress; //40 + cme_resclk_data_t resclkData; //60 + cme_vdm_data_t vdmData; //76 + uint32_t skipSiblingLock; //80(0x50 bytes) } CmePstateRecord; typedef struct @@ -200,6 +218,7 @@ void p9_cme_pstate_intercme_in0_irq_handler(void); void p9_cme_pstate_intercme_msg_handler(void); void p9_cme_pstate_db0_safe_mode(); int send_pig_packet(uint64_t data, uint32_t coreMask); +void send_ack_to_pgpe(uint32_t ack); uint32_t poll_dpll_stat(); void ippm_read(uint32_t addr, uint64_t* data); void ippm_write(uint32_t addr, uint64_t data); @@ -209,9 +228,11 @@ void intercme_direct(INTERCME_DIRECT_INTF intf, INTERCME_DIRECT_TYPE type, uint3 void p9_cme_core_stop_analog_control(uint32_t core_mask, ANALOG_CONTROL enable); void p9_cme_pstate_pmsr_updt(); void p9_cme_pstate_pmsr_updt_in_progress(); -void p9_cme_pstate_sibling_lock_and_intercme_protocol(uint32_t process_intercme_in0); +void p9_cme_pstate_sibling_lock_and_intercme_protocol(INTERCME_MSG_LOCK_ACTION intercme_msg_lock_action, + INTERCME_IN0_PROCESS_ACTION intercme_in0_process_action); void p9_cme_pstate_process_db0_sibling(); + #ifdef USE_CME_RESCLK_FEATURE uint32_t p9_cme_resclk_get_index(uint32_t pstate); void p9_cme_resclk_update(ANALOG_TARGET target, uint32_t next_idx, uint32_t curr_idx); diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c index caa9e666..97323138 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c @@ -57,12 +57,6 @@ extern LocalPstateParmBlock* G_lppb; extern uint8_t G_vdm_threshold_table[]; cppm_cmedb0_t G_dbData; -//This is set and cleared during registration, so no need -//to protect it in critical section. It only serves to make sure -//that p9_cme_update_analog is called if pstates are started during -//registration even -uint32_t G_register_in_progress; -uint32_t G_update_analog_error; // //Function Prototypes @@ -75,12 +69,87 @@ inline void p9_cme_pstate_update_analog() __attribute__((always_inline)); void p9_cme_pstate_init(); void p9_cme_pstate_process_db0(); -void p9_cme_pstate_notify_sib(); +void p9_cme_pstate_notify_sib(INTERCME_DIRECT_INTF intf); void p9_cme_pstate_db0_start(); void p9_cme_pstate_db0_glb_bcast(); void p9_cme_pstate_db0_clip_bcast(); void p9_cme_pstate_update(); -void p9_cme_pstate_pig_send(); + +// +//Doorbell0 interrupt handler +// +void +p9_cme_pgpe_hb_loss_handler(void* arg, PkIrqId irq) +{ + PK_TRACE_ERR("HB LOSS OCCURED"); + + //Clear Interrupt + out32(CME_LCL_EISR_CLR, BIT32(4)); + + //Quad Manager + if(G_cme_pstate_record.qmFlag) + { + //Notify and Receive ack from sibling CME. This syncs up both CMEs before + //Quad Manager touches any analog controls. Otherwise, it's possible that + //sibling due to STOP ends up touching resclks + p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN2); + +#ifdef USE_CME_RESCLK_FEATURE + + if (in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_RCLK_OPERABLE)) + { + p9_cme_resclk_update(ANALOG_COMMON, p9_cme_resclk_get_index(ANALOG_PSTATE_RESCLK_OFF), + G_cme_pstate_record.resclkData.common_resclk_idx); + out32(CME_LCL_FLAGS_CLR, BIT32(CME_FLAGS_RCLK_OPERABLE)); + } + +#endif + //move DPLL directly to value in QPPMR[Fsafe] if that value is nonzero + data64_t scom_data = {0}; + ippm_read(QPPM_QPMMR, &scom_data.value); + uint32_t FSafe = (scom_data.words.upper >> 20) & 0x7FF; + + out32(CME_LCL_FLAGS_CLR, BIT32(CME_FLAGS_PSTATES_ENABLED)); + out32(CME_LCL_FLAGS_OR, BIT32(CME_FLAGS_SAFE_MODE) | + BIT32(CME_FLAGS_PGPE_HB_LOSS_SAFE_MODE)); + + if(FSafe) + { + PK_TRACE_INF("Fsafe=0x%x", FSafe); + G_cme_pstate_record.nextPstate = G_lppb->dpll_pstate0_value - FSafe; + G_cme_pstate_record.globalPstate = G_lppb->dpll_pstate0_value - FSafe; + p9_cme_pstate_update_analog(); + } + + //Notify and Receive ack from sibling CME. This is to tell sibling that + //Quad Manager is done touching analong controls + p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN2); + //Sibling CME + } + else + { + //Wait to receive a notify from Quad Manager + //and then ACK back to quad manager + while(!(in32_sh(CME_LCL_EISR) & BIT64SH(39))); + + intercme_direct(INTERCME_DIRECT_IN2, INTERCME_DIRECT_ACK, 0); + + PK_TRACE_INF("RCVed Notify and ACKed"); + + out32(CME_LCL_FLAGS_CLR, BIT32(CME_FLAGS_PSTATES_ENABLED)); + out32(CME_LCL_FLAGS_OR, BIT32(CME_FLAGS_SAFE_MODE) | + BIT32(CME_FLAGS_PGPE_HB_LOSS_SAFE_MODE)); + + //Wait to receive a notify from Quad Manager + //and then ACK back to quad manager + while(!(in32_sh(CME_LCL_EISR) & BIT64SH(39))); + + intercme_direct(INTERCME_DIRECT_IN2, INTERCME_DIRECT_ACK, 0); + PK_TRACE_INF("RCVed Notify and ACKed"); + } + + PK_TRACE_ERR("HB LOSS OCCURED Processed!"); +} // //Doorbell0 interrupt handler @@ -88,8 +157,14 @@ void p9_cme_pstate_pig_send(); //Only enabled on QuadManager-CME void p9_cme_pstate_db0_handler(void) { - wrteei(1); + //Mask EIMR[PGPE_HB_LOSS/4]; +// out32(CME_LCL_EIMR_OR, BIT32(4)); + g_eimr_override |= BIT64(4); + p9_cme_pstate_process_db0(); + +// out32(CME_LCL_EIMR_CLR, BIT32(4)); + g_eimr_override &= ~BIT64(4); } // @@ -99,65 +174,95 @@ void p9_cme_pstate_db0_handler(void) void p9_cme_pstate_db3_handler(void) { cppm_cmedb3_t db3; - - PK_TRACE_INF("DB3 Handler"); + ppm_sshsrc_t sshsrc; + uint32_t cm; //Clear EISR and read DB3 register out32(CME_LCL_EISR_CLR, BITS32(10, 2)); CME_GETSCOM(CPPM_CMEDB3, G_cme_pstate_record.firstGoodCoreMask, db3.value); + PK_TRACE_INF("DB3 Handler DB3=0x%08x%08x", db3.value >> 32, db3.value); - if(db3.fields.cme_message_numbern >= MSGID_DB3_HIGH_PRIORITY_PSTATE) - { - p9_cme_pstate_db3_handler_high_priority_pstate(); - } - else if (db3.fields.cme_message_numbern == MSGID_DB3_REPLAY_DB0) - { - p9_cme_pstate_db3_handler_replay_db0(); - } - else + if((db3.fields.cme_message_numbern == MSGID_DB3_HIGH_PRIORITY_PSTATE) || + (db3.fields.cme_message_numbern == MSGID_DB3_REPLAY_DB0) || + (db3.fields.cme_message_numbern == MSGID_DB3_ENTER_SAFE_MODE)) { - //\todo Will be done in the Error Handling commit - //48635 - } -} -// -//Doorbell3 Handler Replay DB0 -// -void p9_cme_pstate_db3_handler_replay_db0() -{ - G_update_analog_error = 0; - PK_TRACE_INF("PSTATE: Process DB0 Replay"); + G_cme_pstate_record.updateAnalogError = 0; + G_cme_pstate_record.skipSiblingLock = 1; - //QuadManager - if(G_cme_pstate_record.qmFlag) - { - p9_cme_pstate_process_db0(); + //On quadManage, we process the data in DB0. The data is written + //by PGPE before writing the DB3 register + if(G_cme_pstate_record.qmFlag) + { + p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN2); + p9_cme_pstate_process_db0(); + } + //On Sibling, poll on intercme_msg "LOCK_SIBLING", then + //poll on intercme_in0/1 direct msg. + else + { + //Wait to receive a notify from Quad Manager + //and then ACK back to quad manager + while(!(in32_sh(CME_LCL_EISR) & BIT64SH(39))); + + intercme_direct(INTERCME_DIRECT_IN2, INTERCME_DIRECT_ACK, 0); + + p9_cme_pstate_sibling_lock_and_intercme_protocol(INTERCME_MSG_LOCK_SKIP, INTERCME_IN0_PROCESS); + } + + if (db3.fields.cme_message_numbern == MSGID_DB3_ENTER_SAFE_MODE) + { + out32(CME_LCL_FLAGS_OR, BIT32(CME_FLAGS_SAFE_MODE)); + } + + G_cme_pstate_record.skipSiblingLock = 0; } - //On Sibling, poll on intercme_msg "LOCK_SIBLING", then - //poll on intercme_in0/1 direct msg. - else + else if (db3.fields.cme_message_numbern == MSGID_DB3_DISABLE_SGPE_HANDOFF) { - p9_cme_pstate_sibling_lock_and_intercme_protocol(1); - } -} -// -//Doorbell3 Handler High Priority Pstate -// -void p9_cme_pstate_db3_handler_high_priority_pstate() -{ - //Quad Manager - if(G_cme_pstate_record.qmFlag) - { - p9_cme_pstate_process_db0(); + G_cme_record.disableSGPEHandoff = 1; + + for(cm = 2; cm > 0; cm--) + { + if (in32(CME_LCL_FLAGS) & cm) + { + CME_GETSCOM(PPM_SSHSRC, cm, sshsrc); + + //then clear the EIMR[PC_INTERRUPT_PENDING_C1)] + if ((sshsrc.fields.stop_gated == 1) && ( + (sshsrc.fields.act_stop_level < 5) || + (sshsrc.fields.act_stop_level == 5 && sshsrc.fields.stop_transition != 0x2))) + { + CME_PUTSCOM(CPPM_CPMMR_CLR, cm, BIT64(13)); + out32(CME_LCL_EIMR_CLR, cm << SHIFT32(13)); + } + } + } + + //Notify and Receive ack from sibling CME. This syncs up + //Quad Manager and Sibling before Quad Manager acks back to + //PGPE + if (G_cme_pstate_record.qmFlag) + { + p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN2); + send_ack_to_pgpe(MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK); + } + else + { + //Wait to receive a notify from Quad Manager + //and then ACK back to quad manager + while(!(in32_sh(CME_LCL_EISR) & BIT64SH(39))); + + intercme_direct(INTERCME_DIRECT_IN2, INTERCME_DIRECT_ACK, 0); + } } - //On Sibling poll, on intercme_msg "LOCK_SIBLING", then - //poll on intercme_in0/1 direct msg. else { - p9_cme_pstate_sibling_lock_and_intercme_protocol(1); + //\todo Will be done as part of 41947 + //41947 } + + PK_TRACE_INF("DB3 Handler Done "); } // @@ -176,8 +281,6 @@ void p9_cme_pstate_init() PK_TRACE_INF("PSTATE: Hdr=0x%x, LPPB=0x%x, Nominal_Freq_Mhz=%d ", (uint32_t)G_cmeHeader, (uint32_t)G_lppb, G_lppb->operating_points[NOMINAL].frequency_mhz); - G_register_in_progress = 0; - // Pre-compute the value to be used as the SPURR reference during CME Boot and // save in a variable to be used later during Stop exit. // The value is the 2's complement of ROUND((Core Nominal Frequency in Mhz)/64) @@ -195,6 +298,8 @@ void p9_cme_pstate_init() // Mask PMCR interrupts, these will be unmasked when starting Pstates eimr_or |= BITS64(34, 2); + + //Read CME_LCL_FLAGS uint32_t cme_flags = in32(CME_LCL_FLAGS); @@ -212,6 +317,10 @@ void p9_cme_pstate_init() cores |= CME_MASK_C1; } + //Disable PGPE heart beat loss + g_eimr_override |= BIT64(4); + out32(CME_LCL_EIMR_OR, BIT32(4)); + //Enable Interrupts depending on whether this CME is //a quadManager or siblingCME. DB0 is enabled only //on quadManager. Whereas, InterCME_IN0 only on @@ -228,13 +337,13 @@ void p9_cme_pstate_init() if (cme_flags & BIT32(CME_FLAGS_CORE0_GOOD)) { - eimr_clr |= BIT64(10) | BIT64(36); //Enable DB3_0 and DB0_0 - eimr_or |= BIT64(11) | BIT64(37); //Disable DB3_1 and DB0_1 + eimr_clr |= BIT64(36); //Enable DB0_0 + eimr_or |= BIT64(37); //Disable DB0_1 } else { - eimr_clr |= BIT64(11) | BIT64(37); //Enable DB3_1 and DB0_1 - eimr_or |= BIT64(10) | BIT64(36); //Disable DB3_0 and DB0_0 + eimr_clr |= BIT64(37); //Enable DB0_1 + eimr_or |= BIT64(36); //Disable DB0_0 } // Disable the intercme messages used by the Sibling @@ -319,9 +428,21 @@ void p9_cme_pstate_init() PK_TRACE_INF("sib | initial pstate=%d", G_cme_pstate_record.quadPstate); //Enable InterCME_IN0 but do not clear the override mask - out32(CME_LCL_EIMR_CLR, BIT32(7)); + eimr_clr |= BIT64(7); } + if (cme_flags & BIT32(CME_FLAGS_CORE0_GOOD)) + { + eimr_clr |= BIT64(11); //Enable DB3_0 + eimr_or |= BIT64(10); //Disable DB3_1 + } + else + { + eimr_clr |= BIT64(11); //Enable DB3_1 + eimr_or |= BIT64(10); //Disable DB3_0 + } + + g_eimr_override |= eimr_or; g_eimr_override &= ~eimr_clr; out64(CME_LCL_EIMR_OR, eimr_or); @@ -416,8 +537,7 @@ void p9_cme_pstate_init() // void p9_cme_pstate_process_db0() { - ppm_pig_t ppmPigData; - G_update_analog_error = 0; + G_cme_pstate_record.updateAnalogError = 0; uint64_t scom_data; PK_TRACE_INF("PSTATE: Process DB0 Enter"); @@ -436,71 +556,81 @@ void p9_cme_pstate_process_db0() uint32_t cme_flags = in32(CME_LCL_FLAGS); - //Process DB0 - //Start Pstates and Pstates NOT enabled - if((G_dbData.fields.cme_message_number0 == MSGID_DB0_START_PSTATE_BROADCAST) && - (!(cme_flags & BIT32(CME_FLAGS_PSTATES_ENABLED)))) - { - //This will Clear EISR[DB0_C0/1] to prevent another DB0 interrupt - //PGPE multicast Global Bcast/Clip Bcast DB0, and it's possible that - //the DB0 interrupt was taken as a result of multicast operation, but - //the value of DB0 read corresponds to Pstate Start. In such a case, - //another DB0 interrupt can happen, and it appears as PGPE has sent - //a second Pstate Start causing CME to ACK back with error and Halt - p9_cme_pstate_db0_start(); - } - //Global Actual Broadcast and Pstates enabled - else if((G_dbData.fields.cme_message_number0 == MSGID_DB0_GLOBAL_ACTUAL_BROADCAST) || - (G_dbData.fields.cme_message_number0 == MSGID_DB0_DB3_GLOBAL_ACTUAL_BROADCAST)) + PK_TRACE_INF("PSTATE: DB0=0x%08x%08x", G_dbData.value >> 32, G_dbData.value); + + //Ignore if Doorbell0 if DB0_PROCESSING_ENABLE=0. This bit is zero + //upon CME boot. PGPE will set it right before sending Pstate Starts. + //PGPE clears it before ACKing Stop Entry Notify(this CME is about to powered off) + //back to SGPE + if (!(cme_flags & BIT32(CME_FLAGS_SAFE_MODE))) { - //Process Global Bcast only if Pstates are enabled. - //Otherwise, ignore. The reason is PGPE multicasts Global Bcast, and doorbell0 - //can be written while this CME is powered-off or or about to be powered-off. - //For Pstate Start and Stop PGPE only unicasts. - if (cme_flags & BIT32(CME_FLAGS_PSTATES_ENABLED)) + //Process DB0 + //Start Pstates and Pstates NOT enabled + if((G_dbData.fields.cme_message_number0 == MSGID_DB0_START_PSTATE_BROADCAST) && + (!(cme_flags & BIT32(CME_FLAGS_PSTATES_ENABLED)))) { - p9_cme_pstate_db0_glb_bcast(); + //This will Clear EISR[DB0_C0/1] to prevent another DB0 interrupt + //PGPE multicast Global Bcast/Clip Bcast DB0, and it's possible that + //the DB0 interrupt was taken as a result of multicast operation, but + //the value of DB0 read corresponds to Pstate Start. In such a case, + //another DB0 interrupt can happen, and it appears as PGPE has sent + //a second Pstate Start causing CME to ACK back with error and Halt + p9_cme_pstate_db0_start(); } - } - //Stop Pstates and Pstates enabled - else if((G_dbData.fields.cme_message_number0 == MSGID_DB0_STOP_PSTATE_BROADCAST) && - (cme_flags & BIT32(CME_FLAGS_PSTATES_ENABLED))) - { - p9_cme_pstate_db0_stop(); - } - //Pmin or Pmax Update - else if(G_dbData.fields.cme_message_number0 == MSGID_DB0_CLIP_BROADCAST) - { - p9_cme_pstate_db0_clip_bcast(); - } - else if(G_dbData.fields.cme_message_number0 == MSGID_DB0_PMSR_UPDT) - { - p9_cme_pstate_db0_pmsr_updt(); - } - else if(G_dbData.fields.cme_message_number0 == MSGID_DB0_REGISTER_DONE) - { - ppmPigData.value = 0; - ppmPigData.fields.req_intr_type = 4; - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; - send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); - } - //Otherwise, send an ERR ACK to PGPE and Halt - else - { - ppmPigData.value = 0; - ppmPigData.fields.req_intr_type = 4; - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_ACK_ERROR; - send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); - PK_TRACE_INF("PSTATE: Bad DB0=0x%x", (uint8_t)G_dbData.fields.cme_message_number0); - - if(G_dbData.fields.cme_message_number0 < MSGID_DB0_VALID_START || - G_dbData.fields.cme_message_number0 > MSGID_DB0_VALID_END) + //Global Actual Broadcast and Pstates enabled + else if((G_dbData.fields.cme_message_number0 == MSGID_DB0_GLOBAL_ACTUAL_BROADCAST) || + (G_dbData.fields.cme_message_number0 == MSGID_DB0_DB3_PAYLOAD)) + { + //Process Global Bcast only if Pstates are enabled. + //Otherwise, ignore. The reason is PGPE multicasts Global Bcast, and doorbell0 + //can be written while this CME is powered-off or or about to be powered-off. + //For Pstate Start and Stop PGPE only unicasts. + if (cme_flags & BIT32(CME_FLAGS_PSTATES_ENABLED)) + { + p9_cme_pstate_db0_glb_bcast(); + } + } + //Stop Pstates only if Pstates are enabled + else if((G_dbData.fields.cme_message_number0 == MSGID_DB0_STOP_PSTATE_BROADCAST) && + (cme_flags & BIT32(CME_FLAGS_PSTATES_ENABLED))) { - PK_PANIC(CME_PSTATE_UNEXPECTED_DB0_MSGID); + p9_cme_pstate_db0_stop(); } + //Pmin or Pmax Update + else if(G_dbData.fields.cme_message_number0 == MSGID_DB0_CLIP_BROADCAST) + { + //Process only if Pstates are enabled. Otherwise, ignore. + if (cme_flags & BIT32(CME_FLAGS_PSTATES_ENABLED)) + { + p9_cme_pstate_db0_clip_bcast(); + } + } + else if(G_dbData.fields.cme_message_number0 == MSGID_DB0_PMSR_UPDT) + { + p9_cme_pstate_db0_pmsr_updt(); + } + else if(G_dbData.fields.cme_message_number0 == MSGID_DB0_REGISTER_DONE) + { + send_ack_to_pgpe(MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK); + } + //Otherwise, send an ERR ACK to PGPE and Halt else { - PK_PANIC(CME_PSTATE_INVALID_DB0_MSGID); + PK_TRACE_INF("PSTATE: Bad DB0=0x%x", (uint8_t)G_dbData.fields.cme_message_number0); + send_ack_to_pgpe(MSGID_PCB_TYPE4_ACK_ERROR); + + if(in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_PM_DEBUG_HALT_ENABLE)) + { + if(G_dbData.fields.cme_message_number0 < MSGID_DB0_VALID_START || + G_dbData.fields.cme_message_number0 > MSGID_DB0_VALID_END) + { + PK_PANIC(CME_PSTATE_UNEXPECTED_DB0_MSGID); + } + else + { + PK_PANIC(CME_PSTATE_INVALID_DB0_MSGID); + } + } } } @@ -510,9 +640,12 @@ void p9_cme_pstate_process_db0() inline void p9_cme_pstate_register() { + G_cme_pstate_record.registerInProgress = 1; + uint64_t scom_data; + CME_GETSCOM_OR( CPPM_CSAR, CME_MASK_BC, scom_data ); + uint32_t register_enable = scom_data & BIT64(CPPM_CSAR_ENABLE_PSTATE_REGISTRATION_INTERLOCK); + uint32_t msgCnt = 0; uint32_t done = 0; - uint32_t cme_flags = in32(CME_LCL_FLAGS); - G_register_in_progress = 1; //Quad Manager sends register message to PGPE if (G_cme_pstate_record.qmFlag) @@ -520,16 +653,10 @@ inline void p9_cme_pstate_register() //Clear EISR[DB0_C0/1] out32_sh(CME_LCL_EISR_CLR, BITS64SH(36, 2)); - //Send type4(ack doorbell) - ppm_pig_t ppmPigData; - ppmPigData.value = 0; - ppmPigData.fields.req_intr_type = 4; - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_QUAD_MGR_AVAILABLE; - send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); - + send_ack_to_pgpe(MSGID_PCB_TYPE4_QUAD_MGR_AVAILABLE); PK_TRACE_INF("PSTATE: Register Msg Sent"); - if (cme_flags & BIT32(CME_FLAGS_WAIT_ON_PSTATE_START)) //Poll on DB0 + if(register_enable) { PK_TRACE_INF("PSTATE: Wait on Pstate Start"); @@ -537,15 +664,15 @@ inline void p9_cme_pstate_register() //PGPE might send DB0 to other quads as part of processing registration //msg from this quad, but we don't want this quad to process them until //PGPE has set DB0_PROCESSING_ENABLE - while(!(in32(CME_LCL_SRTCH0) & BIT32(CME_SCRATCH_DB0_PROCESSING_ENABLE))); + //while(!(in32(CME_LCL_SRTCH0) & BIT32(CME_SCRATCH_DB0_PROCESSING_ENABLE))); PK_TRACE_INF("PSTATE: DB0 Processing is Enabled"); //PGPE sends MSGID_DB0_REGISTER_DONE, if Pstates aren't active anymore. //Otherwise, PGPE sends DB0 in the following order - //1. MSGID_DB0_CLIP_BROADCAST + //1. MSGID_DB0_START_PSTATE_BROADCAST //2. MSGID_DB0_CLIP_BROADCAST - //3. MSGID_DB0_START_PSTATE_BROADCAST + //3. MSGID_DB0_CLIP_BROADCAST while(!done) { uint32_t db0_check = G_cme_pstate_record.firstGoodCoreMask << SHIFT64SH(37); @@ -562,39 +689,41 @@ inline void p9_cme_pstate_register() if((G_dbData.fields.cme_message_number0 == MSGID_DB0_START_PSTATE_BROADCAST)) { p9_cme_pstate_db0_start(); - done = 1; + msgCnt++; } - else if ((G_dbData.fields.cme_message_number0 == MSGID_DB0_CLIP_BROADCAST)) + else if ((G_dbData.fields.cme_message_number0 == MSGID_DB0_CLIP_BROADCAST) && + ((in32(CME_LCL_FLAGS) & BIT32(CME_FLAGS_PSTATES_ENABLED)))) { p9_cme_pstate_db0_clip_bcast(); + msgCnt++; } //PGPE sends this if Pstates aren't active anymore else if ((G_dbData.fields.cme_message_number0 == MSGID_DB0_REGISTER_DONE)) { + send_ack_to_pgpe(MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK); + done = 1; + } + + if (msgCnt == 3) + { done = 1; - ppmPigData.value = 0; - ppmPigData.fields.req_intr_type = 4; - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; - send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); } } } - //Sibling CME } + //Sibling CME else { - uint32_t msgCnt = 0; - - if (cme_flags & BIT32(CME_FLAGS_WAIT_ON_PSTATE_START)) + if (register_enable) { PK_TRACE_INF("PSTATE: Wait on Pstate Start"); //PGPE sends MSGID_DB0_REGISTER_DONE, if Pstates aren't active anymore. //Otherwise, PGPE sends DB0 in the following order - //1. MSGID_DB0_CLIP_BROADCAST + //1. MSGID_DB0_START_PSTATE_BROADCAST //2. MSGID_DB0_CLIP_BROADCAST - //3. MSGID_DB0_START_PSTATE_BROADCAST + //3. MSGID_DB0_CLIP_BROADCAST while(!done) { if ((G_dbData.fields.cme_message_number0 == MSGID_DB0_REGISTER_DONE)) @@ -604,22 +733,22 @@ inline void p9_cme_pstate_register() } else { - p9_cme_pstate_sibling_lock_and_intercme_protocol(1); + p9_cme_pstate_sibling_lock_and_intercme_protocol(INTERCME_MSG_LOCK_WAIT_ON_RECV, INTERCME_IN0_PROCESS); msgCnt++; if (msgCnt == 3) { done = 1; } - - PK_TRACE_INF("PSTATE: Sib Register MsgCnt=%d", msgCnt); } + + PK_TRACE_INF("PSTATE: Sib Register MsgCnt=%d", msgCnt); } } } - G_register_in_progress = 0; - PK_TRACE_INF("PSTATE: Register Done"); + G_cme_pstate_record.registerInProgress = 0; + PK_TRACE_INF("PSTATE: Register Done\n"); } // @@ -628,25 +757,27 @@ inline void p9_cme_pstate_register() void p9_cme_pstate_db0_start() { PK_TRACE_INF("PSTATE: DB0 Start Enter"); - ppm_pig_t ppmPigData; p9_cme_pstate_update(); + uint32_t ack; + + //Enable PGPE_HEARTBEAT_LOSS in EIMR upon Pstate Start + //will be applied on return from DB0 interrupt + g_eimr_override &= ~BIT64(4); //Clear EISR[DB0_C0/1] to prevent another interrupt out32_sh(CME_LCL_EISR_CLR, BITS64SH(36, 2)); //Prepare PPM type4 payload for ACK/NACK for PGPE //Send NACK, if any errors. Otherwise, send ACK - ppmPigData.value = 0; - ppmPigData.fields.req_intr_type = 4; - if(G_update_analog_error) + if(G_cme_pstate_record.updateAnalogError) { - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_NACK_DROOP_PRESENT; + ack = MSGID_PCB_TYPE4_NACK_DROOP_PRESENT; } else { - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; + ack = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; out32(CME_LCL_FLAGS_OR, BIT32(24));//Set Pstates Enabled @@ -658,10 +789,10 @@ void p9_cme_pstate_db0_start() } //Send type4(ack doorbell) - send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); + send_ack_to_pgpe(ack); - //Reset G_update_analog_error - G_update_analog_error = 0; + //Reset G_cme_pstate_record.updateAnalogError + G_cme_pstate_record.updateAnalogError = 0; PK_TRACE_INF("PSTATE: DB0 Start Exit"); } @@ -672,28 +803,25 @@ void p9_cme_pstate_db0_start() void p9_cme_pstate_db0_glb_bcast() { PK_TRACE_INF("PSTATE: DB0 GlbBcast Enter"); - ppm_pig_t ppmPigData; p9_cme_pstate_update(); + uint32_t ack; //Prepare PPM type4 payload for ACK/NACK for PGPE //Send NACK, if any errors. Otherwise, send ACK - ppmPigData.value = 0; - ppmPigData.fields.req_intr_type = 4; - - if(G_update_analog_error) + if(G_cme_pstate_record.updateAnalogError) { - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_NACK_DROOP_PRESENT; + ack = MSGID_PCB_TYPE4_NACK_DROOP_PRESENT; } else { - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; + ack = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; } //Send type4(ack doorbell) - send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); - G_update_analog_error = 0; - PK_TRACE_INF("PSTATE: DB0 GlbBcast Exit"); + send_ack_to_pgpe(ack); + G_cme_pstate_record.updateAnalogError = 0; + PK_TRACE_INF("PSTATE: DB0 GlbBcast Exit\n"); } // @@ -702,10 +830,14 @@ void p9_cme_pstate_db0_glb_bcast() inline void p9_cme_pstate_db0_stop() { PK_TRACE_INF("PSTATE: DB0 Stop Enter"); - ppm_pig_t ppmPigData; out32(CME_LCL_FLAGS_CLR, BIT32(24));//Set Pstates Disabled + //Disable PGPE_HEARTBEAT_LOSS in EIMR + //will be applied on return from DB0 interrupt + g_eimr_override |= BIT64(4); + out32(CME_LCL_EIMR_OR, BIT32(4)); + // Disable both PMCR regs ignoring partial-goodness out32_sh(CME_LCL_EIMR_OR, BITS64SH(34, 2)); g_eimr_override |= BITS64(34, 2); @@ -713,13 +845,10 @@ inline void p9_cme_pstate_db0_stop() //PGPE will update the LMCR[0] before sending the STOP PSTATE Doorbell. //Here we update the PMSR to indicate that Pstates are no longer honored accordingly. p9_cme_pstate_pmsr_updt(); - p9_cme_pstate_notify_sib(); //Notify sibling + p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN0); //Notify sibling //Send type4(ack doorbell) - ppmPigData.value = 0; - ppmPigData.fields.req_intr_type = 4; - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_ACK_PSTATE_SUSPENDED; - send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); + send_ack_to_pgpe(MSGID_PCB_TYPE4_ACK_PSTATE_SUSPENDED); //Set Core GPMMR RESET_STATE_INDICATOR bit to show pstates have stopped CME_PUTSCOM(PPM_GPMMR_OR, G_cme_record.core_enabled, BIT64(15)); @@ -732,7 +861,6 @@ void p9_cme_pstate_db0_clip_bcast() PK_TRACE_INF("PSTATE: DB0 Clip Enter"); - ppm_pig_t ppmPigData; uint32_t dbBit8_15 = (G_dbData.value & BITS64(8, 8)) >> SHIFT64(15); @@ -758,13 +886,10 @@ void p9_cme_pstate_db0_clip_bcast() } p9_cme_pstate_pmsr_updt(); - p9_cme_pstate_notify_sib(); //Notify sibling + p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN0); //Notify sibling //Send type4(ack doorbell) - ppmPigData.value = 0; - ppmPigData.fields.req_intr_type = 4; - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; - send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); + send_ack_to_pgpe(MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK); PK_TRACE_INF("PSTATE: DB0 Clip Exit"); } @@ -772,34 +897,26 @@ void p9_cme_pstate_db0_clip_bcast() inline void p9_cme_pstate_db0_pmsr_updt() { PK_TRACE_INF("PSTATE: DB0 Pmsr Updt Enter"); - ppm_pig_t ppmPigData; uint32_t dbBit8_15 = (G_dbData.value & BITS64(8, 8)) >> SHIFT64(15); switch(dbBit8_15) { - case DB0_PMSR_UPDT_SET_SAFE_MODE: - G_cme_pstate_record.safeMode = 1; - break; - case DB0_PMSR_UPDT_SET_PSTATES_SUSPENDED: - G_cme_pstate_record.pstatesSuspended = 1; + out32(CME_LCL_FLAGS_OR, BIT32(17)); break; case DB0_PMSR_UPDT_CLEAR_PSTATES_SUSPENDED: - G_cme_pstate_record.pstatesSuspended = 0; + out32(CME_LCL_FLAGS_CLR, BIT32(17)); break; } p9_cme_pstate_pmsr_updt(); - p9_cme_pstate_notify_sib(); //Notify sibling + p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN0); //Notify sibling //Send type4(ack doorbell) - ppmPigData.value = 0; - ppmPigData.fields.req_intr_type = 4; - ppmPigData.fields.req_intr_payload = MSGID_PCB_TYPE4_ACK_PSTATE_SUSPENDED; - send_pig_packet(ppmPigData.value, G_cme_pstate_record.firstGoodCoreMask); + send_ack_to_pgpe(MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK); //Set Core GPMMR RESET_STATE_INDICATOR bit to show pstates have stopped CME_PUTSCOM(PPM_GPMMR_OR, G_cme_record.core_enabled, BIT64(15)); @@ -807,23 +924,15 @@ inline void p9_cme_pstate_db0_pmsr_updt() PK_TRACE_INF("PSTATE: DB0 Safe Mode Exit"); } -void p9_cme_pstate_notify_sib() +void p9_cme_pstate_notify_sib(INTERCME_DIRECT_INTF intf) { PK_TRACE_INF("PSTATE: Notify Enter"); //Notify sibling CME(if any) if(G_cme_pstate_record.siblingCMEFlag) { - if(G_update_analog_error) - { - intercme_direct(INTERCME_DIRECT_IN1, INTERCME_DIRECT_NOTIFY, 0); - } - else - { - intercme_direct(INTERCME_DIRECT_IN0, INTERCME_DIRECT_NOTIFY, 0); - } + intercme_direct(intf, INTERCME_DIRECT_NOTIFY, 0); } - } inline void p9_cme_pstate_freq_update(uint32_t cme_flags) @@ -836,7 +945,6 @@ inline void p9_cme_pstate_freq_update(uint32_t cme_flags) { PK_TRACE_INF("PSTATE: Freq Updt Enter"); PK_TRACE_INF("PSTATE: Dpll0=0x%x", G_lppb->dpll_pstate0_value); - PK_TRACE_INF("PSTATE: Hdr=0x%x, LPPB=0x%x", (uint32_t)G_cmeHeader, (uint32_t)G_lppb); //Adjust DPLL qppm_dpll_freq_t dpllFreq; @@ -856,7 +964,7 @@ inline void p9_cme_pstate_freq_update(uint32_t cme_flags) ippm_write(QPPM_DPLL_FREQ, dpllFreq.value); - G_update_analog_error = poll_dpll_stat(); + G_cme_pstate_record.updateAnalogError = poll_dpll_stat(); PK_TRACE_INF("PSTATE: Freq Updt Exit"); } @@ -875,10 +983,10 @@ inline void p9_cme_pstate_update_analog() if((cme_flags & BIT32(CME_FLAGS_VDM_OPERABLE)) && G_cme_pstate_record.nextPstate < G_cme_pstate_record.quadPstate) { - G_update_analog_error = p9_cme_vdm_update(G_cme_pstate_record.nextPstate); + G_cme_pstate_record.updateAnalogError = p9_cme_vdm_update(G_cme_pstate_record.nextPstate); } - if (G_update_analog_error) + if (G_cme_pstate_record.updateAnalogError) { break; } //If error skip the code below @@ -905,7 +1013,7 @@ inline void p9_cme_pstate_update_analog() p9_cme_pstate_freq_update(cme_flags); //If error changing DPLL freq, skip the code below - if (G_update_analog_error) + if (G_cme_pstate_record.updateAnalogError) { break; } @@ -925,9 +1033,9 @@ inline void p9_cme_pstate_update_analog() if((cme_flags & BIT32(CME_FLAGS_VDM_OPERABLE)) && G_cme_pstate_record.nextPstate >= G_cme_pstate_record.quadPstate) { - G_update_analog_error = p9_cme_vdm_update(G_cme_pstate_record.nextPstate); + G_cme_pstate_record.updateAnalogError = p9_cme_vdm_update(G_cme_pstate_record.nextPstate); - if (G_update_analog_error) + if (G_cme_pstate_record.updateAnalogError) { break; } @@ -953,9 +1061,9 @@ void p9_cme_pstate_update() >> SHIFT64(15); if((G_cme_pstate_record.nextPstate != G_cme_pstate_record.quadPstate) || - G_register_in_progress) + G_cme_pstate_record.registerInProgress) { - if(G_cme_pstate_record.siblingCMEFlag) + if(G_cme_pstate_record.siblingCMEFlag && (!G_cme_pstate_record.skipSiblingLock)) { // "Lock" the sibling until the pstate transition is complete intercme_msg_send(0, IMT_LOCK_SIBLING); @@ -966,21 +1074,21 @@ void p9_cme_pstate_update() PK_TRACE_INF("PSTATE: DBData=0x%08x%08x", G_dbData.value >> 32, G_dbData.value); - p9_cme_pstate_pmsr_updt_in_progress(); - pk_critical_section_enter(&ctx); + p9_cme_pstate_pmsr_updt_in_progress(); + p9_cme_pstate_update_analog(); //Update quadPstate only if no error - if(!G_update_analog_error) + if(!G_cme_pstate_record.updateAnalogError) { // Must update quadPstate before calling PMSR update G_cme_pstate_record.quadPstate = G_cme_pstate_record.nextPstate; } else { - G_cme_pstate_record.pstatesSuspended = 1; + out32(CME_LCL_FLAGS_OR, BIT32(CME_FLAGS_PSTATES_SUSPENDED)); } pk_critical_section_exit(&ctx); @@ -988,7 +1096,14 @@ void p9_cme_pstate_update() p9_cme_pstate_pmsr_updt(); - p9_cme_pstate_notify_sib(); + if(G_cme_pstate_record.updateAnalogError) + { + p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN1); + } + else + { + p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN0); + } PK_TRACE_INF("PSTATE: Pstate Updt Exit"); } diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_pmcr.c b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_pmcr.c index d414ef46..4c3a2ac7 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_pmcr.c +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_pmcr.c @@ -69,8 +69,9 @@ void cme_pstate_pmcr_action() request = in64(CME_LCL_PMCRS0 + ((cm & 1) << 5)) & PMCR_LOWERPS_MASK; PK_TRACE_INF("PMCR: Fwd Core[%d] Pstate Request = 0x%02x", cm, (uint32_t)(request >> PMCR_PSTATE_SHIFT_AMOUNT)); - // Note that LowerPS coincidentally is in the correct place for the PIG payload - + //NOTE: that LowerPS coincidentally is in the correct place for the PIG payload + //Send Type1(previously Phase 2) only. + //Phase 1 is deprecated(Previously used Type0 which is now re-defined) ppmPigData.value = 0; ppmPigData.fields.req_intr_type = 1; ppmPigData.value |= request; 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 4179877a..48f922ab 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 @@ -296,7 +296,7 @@ typedef struct // store panic code indicating where and what that certain core encountered error // mostly from various xstop detection or failed clock operation through stages of code uint32_t error_code[2]; -} CmeStopRecord; +} CmeStopRecord __attribute__ ((aligned (8)));; #if HW405292_NDD1_PCBMUX_SAVIOR @@ -327,3 +327,6 @@ void p9_cme_stop_db2_handler(void); // CME STOP Utility Functions void p9_hcd_core_scan0(uint32_t, uint64_t, uint64_t); void p9_hcd_core_pcb_arb(uint32_t, uint8_t); // not used + +// CME Error Handler +void p9_cme_pgpe_hb_loss_handler(void*, PkIrqId); diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c index 795944e1..42b5e8ec 100755 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c @@ -1548,6 +1548,12 @@ p9_cme_stop_entry() #endif + if (G_cme_record.disableSGPEHandoff) + { + PK_TRACE_INF("SE.4+: Disable SGPE Handoff due to SGPE Halt"); + break; + } + //============================= MARK_TAG(SE_SGPE_HANDOFF, core) //============================= diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c index 5e5cb1f3..bd9e74e7 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c @@ -334,6 +334,7 @@ p9_cme_stop_exit_end(uint32_t core, uint32_t spwu_stop) // done = spwu + !pm_active + !core_chiplet_fence + !pcbmux_req + !pcbmux_grant // chiplet fence forces pm_active to zero // Note: pm_exit is asserted above for every core waking up including spwu + PK_TRACE_DBG("SX.0B: Core[%d] Assert SPWU_DONE via SICR[16/17]", spwu_stop); // Note: clear pm_active so that potential stop1 wont use leftover pm_active upon drop spwu later out32(CME_LCL_EISR_CLR, ((spwu_stop << SHIFT32(15)) | (spwu_stop << SHIFT32(21)))); // clear spwu in EISR 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 e64e6950..cf8bd2f4 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 @@ -25,6 +25,8 @@ #include "p9_cme_stop.h" #include "p9_cme_stop_enter_marks.h" +#include "qppm_register_addresses.h" +#include "qppm_firmware_registers.h" #include "p9_cme_irq.h" #include "p9_cme_pstate.h" @@ -171,6 +173,13 @@ p9_cme_stop_spwu_handler(void) // Core is now out of spwu, allow pm_active // block entry mode is handled via eimr override G_cme_stop_record.core_in_spwu &= ~core_mask; + + // if in block entry mode, do not release the mask + if (!(G_cme_stop_record.core_blockey & core_mask)) + { + // use 32 bit UPPER mask to prevent compiler from doing 64-bit shifting + g_eimr_override &= ((uint64_t)~((IRQ_VEC_STOP_C0_UPPER) >> core_index)) << 32 | 0xFFFFFFFF; + } } } } @@ -307,8 +316,9 @@ p9_cme_stop_db2_handler(void) #endif #endif // Finish handshake with SGPE for Stop11 via PIG - pig.fields.req_intr_type = PIG_TYPE5; - pig.fields.req_intr_payload = TYPE5_PAYLOAD_ENTRY_RCLK | STOP_LEVEL_11; + pig.fields.req_intr_type = PIG_TYPE0; + pig.fields.req_intr_payload = TYPE0_PAYLOAD_ENTRY_RCLK | STOP_LEVEL_11; + //CME_PUTSCOM_NOP(PPM_PIG, core_mask, pig.value); send_pig_packet(pig.value, core_mask); break; @@ -335,8 +345,9 @@ p9_cme_stop_db2_handler(void) #endif #endif // Finish handshake with SGPE for Stop11 via PIG - pig.fields.req_intr_type = PIG_TYPE5; - pig.fields.req_intr_payload = TYPE5_PAYLOAD_EXIT_RCLK; + pig.fields.req_intr_type = PIG_TYPE0; + pig.fields.req_intr_payload = TYPE0_PAYLOAD_EXIT_RCLK; + //CME_PUTSCOM_NOP(PPM_PIG, core_mask, pig.value); send_pig_packet(pig.value, core_mask); break; @@ -350,8 +361,6 @@ p9_cme_stop_db2_handler(void) p9_cme_stop_eval_eimr_override(); } - - void p9_cme_stop_db1_handler(void) { diff --git a/import/chips/p9/procedures/ppe_closed/lib/p9_stop_recovery_trigger.c b/import/chips/p9/procedures/ppe_closed/lib/p9_stop_recovery_trigger.c index c554e373..93df097e 100644 --- a/import/chips/p9/procedures/ppe_closed/lib/p9_stop_recovery_trigger.c +++ b/import/chips/p9/procedures/ppe_closed/lib/p9_stop_recovery_trigger.c @@ -39,29 +39,32 @@ void p9_stop_recovery_trigger() { - uint64_t scom_data = 0; - PK_TRACE_INF("WARNING: STOP RECOVERY TRIGGER!"); + if (in32(OCB_OCCFLG2) & BIT32(STOP_RECOVERY_TRIGGER_ENABLE)) + { + uint64_t scom_data = 0; + PK_TRACE_INF("WARNING: STOP RECOVERY TRIGGER!"); - PK_TRACE("1. Set ADU lock for exclusive use for a timeout of 500ms."); + PK_TRACE("1. Set ADU lock for exclusive use for a timeout of 500ms."); - do - { + do + { - GPE_PUTSCOM(0x90001, 0x0010000000000000ull); - GPE_GETSCOM(0x90001, scom_data); + GPE_PUTSCOM(0x90001, 0x0010000000000000ull); + GPE_GETSCOM(0x90001, scom_data); - } - while (!(scom_data & 0x0010000000000000ull)); + } + while (!(scom_data & 0x0010000000000000ull)); - PK_TRACE("2. Cleanup/reset ADU"); - GPE_PUTSCOM(0x90001, 0x1810000000000000ull); + PK_TRACE("2. Cleanup/reset ADU"); + GPE_PUTSCOM(0x90001, 0x1810000000000000ull); - PK_TRACE("3. Setup PowerBus 'address' field for malf alert"); - GPE_PUTSCOM(0x90000, 0x0000100000000000ull); + PK_TRACE("3. Setup PowerBus 'address' field for malf alert"); + GPE_PUTSCOM(0x90000, 0x0000100000000000ull); - PK_TRACE("4. Setup PowerBus command type and launch malfunction"); - GPE_PUTSCOM(0x90001, 0x2210A03104000000ull); + PK_TRACE("4. Setup PowerBus command type and launch malfunction"); + GPE_PUTSCOM(0x90001, 0x2210A03104000000ull); - PK_TRACE("5. Set OCCFLG2[28] PM Callout Active"); - out32(OCB_OCCFLG2_OR, BIT32(PM_CALLOUT_ACTIVE)); + PK_TRACE("5. Set OCCFLG2[28] PM Callout Active"); + out32(OCB_OCCFLG2_OR, BIT32(PM_CALLOUT_ACTIVE)); + } } diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.c index 13e94827..c779c19a 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -364,7 +364,7 @@ void external_voltage_control_init(uint32_t* vext_read_mv) if (rc) { PK_TRACE_ERR("AVS_INIT: DriveIdleFrame FAIL"); - PGPE_PANIC_AND_TRACE(PGPE_AVS_INIT_DRIVE_IDLE_FRAME); + PGPE_TRACE_AND_PANIC(PGPE_AVS_INIT_DRIVE_IDLE_FRAME); } // Drive read transaction to return initial setting of rail voltage and wait on o2s_ongoing=0 @@ -373,7 +373,7 @@ void external_voltage_control_init(uint32_t* vext_read_mv) if (rc) { PK_TRACE_ERR("AVS_INIT: DriveRead FAIL"); - PGPE_PANIC_AND_TRACE(PGPE_AVS_INIT_DRIVE_READ); + PGPE_TRACE_AND_PANIC(PGPE_AVS_INIT_DRIVE_READ); } *vext_read_mv = CmdDataRead; @@ -392,7 +392,7 @@ void external_voltage_control_write(uint32_t vext_write_mv) if (vext_write_mv > AVS_DRIVER_MAX_EXTERNAL_VOLTAGE || vext_write_mv < AVS_DRIVER_MIN_EXTERNAL_VOLTAGE) { - PGPE_PANIC_AND_TRACE(PGPE_VOLTAGE_OUT_OF_BOUNDS); + PGPE_TRACE_AND_PANIC(PGPE_VOLTAGE_OUT_OF_BOUNDS); } // Drive write transaction with a target voltage on a particular rail and wait on o2s_ongoing=0 @@ -406,13 +406,13 @@ void external_voltage_control_write(uint32_t vext_write_mv) case AVS_RC_ONGOING_TIMEOUT: PK_TRACE_ERR("AVS_WRITE: OnGoing Flag Timeout"); - PGPE_PANIC_AND_TRACE(PGPE_AVS_WRITE_ONGOING_FLAG_TIMEOUT); + PGPE_TRACE_AND_PANIC(PGPE_AVS_WRITE_ONGOING_FLAG_TIMEOUT); break; case AVS_RC_RESYNC_ERROR: PK_TRACE_ERR("AVS_WRITE: Resync Error"); GPE_PUTSCOM(OCB_OCCLFIR_OR, BIT64(59)); //OCCLFIR[59]=AVS Resync Error - PGPE_PANIC_AND_TRACE(PGPE_AVS_RESYNC_ERROR); + PGPE_TRACE_AND_PANIC(PGPE_AVS_RESYNC_ERROR); break; default: diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe.h index 2a28c074..09952f19 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe.h @@ -103,20 +103,25 @@ enum PGPE_WOF_CTRL #define QUAD_EX1_MASK(quad) \ (QUAD0_EX1_MASK >> (q*2)) -#define PGPE_PANIC_AND_TRACE(val)\ - G_pgpe_optrace_data.word[0] = val; \ +#define PGPE_OPTIONAL_TRACE_AND_PANIC(panic_code) \ + if (in32(OCB_OCCS2) & BIT32(PM_DEBUG_HALT_ENABLE)) { \ + G_pgpe_optrace_data.word[0] = panic_code; \ + p9_pgpe_optrace(HALT_CONDITION ); \ + PK_PANIC(panic_code); } + +#define PGPE_TRACE_AND_PANIC(panic_code)\ + G_pgpe_optrace_data.word[0] = panic_code; \ p9_pgpe_optrace(HALT_CONDITION ); \ - PK_PANIC(val); + PK_PANIC(panic_code); + /// PGPE PState -void p9_pgpe_irq_handler_occ_error(void* arg, PkIrqId irq); -void p9_pgpe_irq_handler_sgpe_halt(void* arg, PkIrqId irq); -void p9_pgpe_irq_handler_xstop_gpe2(void* arg, PkIrqId irq); +void p9_pgpe_irq_handler_occ_sgpe_cme_pvref_error(void* arg, PkIrqId irq); +void p9_pgpe_irq_handler_system_xstop(void* arg, PkIrqId irq); void p9_pgpe_irq_handler_pcb_type1(void* arg, PkIrqId irq); void p9_pgpe_irq_handler_pcb_type4(void* arg, PkIrqId irq); void p9_pgpe_thread_process_requests(void* arg); void p9_pgpe_thread_actuate_pstates(void* arg); -void p9_pgpe_thread_safe_mode_and_pm_suspend(void* arg); ///PGPE PState Info void p9_pgpe_gen_pstate_info(); @@ -127,7 +132,7 @@ void p9_pgpe_fit_init(); ///PGPE IPC void p9_pgpe_ipc_init(); -//OCB Heartbeat Error -void p9_pgpe_ocb_hb_error_init(); +//IRQ initialization and setup +void p9_pgpe_irq_init(); #endif //_P9_PGPE_H_ diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c index e6229062..5d2062bc 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c @@ -32,6 +32,7 @@ #define AUX_TASK 14 #define GPE2TSEL 0xC0020000 +#define OCB_OCI_OCCHBR_OCC_HEARTBEAT_EN 16 uint32_t G_orig_throttle = 0; //original value of throttle SCOM before manipulation uint32_t G_throttleOn; //is throttling currently enabled @@ -46,6 +47,8 @@ uint32_t G_aux_task_count; uint32_t G_tb_sync_count_threshold; uint32_t G_tb_sync_count; +uint32_t G_quad_hb_value; + extern GlobalPstateParmBlock* G_gppb; extern PgpeHeader_t* G_pgpe_header_data; extern PgpePstateRecord G_pgpe_pstate_record; @@ -54,6 +57,7 @@ extern uint32_t G_last_sync_op; void (*p9_pgpe_auxiliary_task)() = (void*)OCC_SRAM_AUX_TASK_ADDR; + // //Local function declarations // @@ -94,6 +98,11 @@ void p9_pgpe_fit_init() uint32_t tsel = 0xA; #endif G_tb_sync_count_threshold = ((0x2 << tsel) - 1); + //Calculated to be twice the interval between FIT interrupts in Quad HBR + //ticks + uint32_t sub = (((1 << (29 - tsel)) / G_gppb->nest_frequency_mhz) << + 4) * (G_beacon_count_threshold + 1); + G_quad_hb_value = ((0x10000 - sub) << 16) | BIT32(OCB_OCI_OCCHBR_OCC_HEARTBEAT_EN); PK_TRACE_DBG("Fit TimebaseSyncThr=0x%d", G_tb_sync_count_threshold); G_throttleOn = 0; G_throttleCount = 0; @@ -155,6 +164,22 @@ __attribute__((always_inline)) inline void handle_core_throttle() p9_pgpe_pstate_write_core_throttle(G_orig_throttle, NO_RETRY); } } +//Quads must get HB value +__attribute__((always_inline)) inline void handle_quad_hb_update() +{ + uint32_t q; + ocb_qcsr_t qcsr; + qcsr.value = in32(OCB_QCSR); + + for (q = 0; q < MAX_QUADS; q++) + { + //Update for configured quads + if (qcsr.fields.ex_config & (0xC00 >> (q << 1))) + { + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_OCCHB, q), (uint64_t) G_quad_hb_value << 32); + } + } +} //PGPE beacon needs to be written every 2ms. However, we //set the FIT interrupt period smaller than that, and @@ -164,9 +189,15 @@ __attribute__((always_inline)) inline void handle_occ_beacon() { if (G_beacon_count == G_beacon_count_threshold) { - //write to SRAM - *(G_pgpe_header_data->g_pgpe_beacon_addr) = *(G_pgpe_header_data->g_pgpe_beacon_addr) + 1; - G_beacon_count = 0; + //Update OCC heart beat register + handle_quad_hb_update(); + + if (G_pgpe_pstate_record.updatePGPEBeacon == 1) + { + //write to SRAM + *(G_pgpe_header_data->g_pgpe_beacon_addr) = *(G_pgpe_header_data->g_pgpe_beacon_addr) + 1; + G_beacon_count = 0; + } } else { @@ -180,10 +211,13 @@ __attribute__((always_inline)) inline void handle_occflg_requests() //Read OCC_FLAGS occFlag.value = in32(OCB_OCCFLG); - if((G_pgpe_pstate_record.pstatesStatus != PSTATE_PM_SUSPENDED) - && (G_pgpe_pstate_record.pstatesStatus != PSTATE_PM_SUSPEND_PENDING) - && (G_pgpe_pstate_record.pstatesStatus != PSTATE_SAFE_MODE_PENDING) - && (G_pgpe_pstate_record.pstatesStatus != PSTATE_STOP_PENDING)) + if(in32(OCB_OCCFLG2) & BIT32(OCCFLG2_PGPE_HCODE_FIT_ERR_INJ)) + { + PK_TRACE_ERR("FIT_IPC_ERROR_INJECT TRAP"); + PK_PANIC(PGPE_SET_PMCR_TRAP_INJECT); + } + + if (G_pgpe_pstate_record.pstatesStatus & (PSTATE_INIT | PSTATE_ACTIVE | PSTATE_SAFE_MODE | PSTATE_STOPPED)) { if(occFlag.value & BIT32(PM_COMPLEX_SUSPEND)) { @@ -235,9 +269,9 @@ __attribute__((always_inline)) inline void handle_occflg_requests() //number of FIT interrupts __attribute__((always_inline)) inline void handle_aux_task() { - if(in32(OCB_OCCFLG) & BIT32(SGPE_24_7_ACTIVATE)) + if(in32(OCB_OCCFLG) & BIT32(AUX_THREAD_ACTIVATE)) { - out32(OCB_OCCFLG_OR, BIT32(SGPE_24_7_ACTIVE)); + out32(OCB_OCCFLG_OR, BIT32(AUX_THREAD_ACTIVE)); if(G_aux_task_count == G_aux_task_count_threshold) { @@ -251,7 +285,7 @@ __attribute__((always_inline)) inline void handle_aux_task() } else { - out32(OCB_OCCFLG_CLR, BIT32(SGPE_24_7_ACTIVE)); + out32(OCB_OCCFLG_CLR, BIT32(AUX_THREAD_ACTIVE)); } } @@ -295,6 +329,7 @@ __attribute__((always_inline)) inline void handle_fit_timebase_sync() //by GPE_TIMER_SELECT register void p9_pgpe_fit_handler(void* arg, PkIrqId irq) { + mtmsr(PPE42_MSR_INITIAL); handle_occ_beacon(); handle_core_throttle(); 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 b4a650d5..c717b09a 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 @@ -113,6 +113,7 @@ void p9_pgpe_ipc_405_start_stop(ipc_msg_t* cmd, void* arg) ipc_send_rsp(cmd, IPC_RC_SUCCESS); G_pgpe_optrace_data.word[0] = PGPE_OP_PSTATE_START_STOP_WHILE_PENDING; p9_pgpe_optrace(UNEXPECTED_ERROR); + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); } } @@ -139,6 +140,7 @@ void p9_pgpe_ipc_405_clips(ipc_msg_t* cmd, void* arg) ipc_send_rsp(cmd, IPC_RC_SUCCESS); G_pgpe_optrace_data.word[0] = PGPE_OP_CLIP_UPDT_IN_WHILE_PENDING; p9_pgpe_optrace(UNEXPECTED_ERROR); + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); } } @@ -150,9 +152,8 @@ void p9_pgpe_ipc_405_clips(ipc_msg_t* cmd, void* arg) void p9_pgpe_ipc_405_set_pmcr(ipc_msg_t* cmd, void* arg) { PK_TRACE_INF("IPC: Set PMCR"); - uint32_t flg2_data = in32(OCB_OCCFLG2); - if( flg2_data & PGPE_HCODE_ERR_INJ_BIT ) + if(in32(OCB_OCCFLG2) & BIT32(OCCFLG2_PGPE_HCODE_PSTATE_REQ_ERR_INJ)) { PK_TRACE_ERR("SET PMCR IPC ERROR INJECT TRAP"); PK_PANIC(PGPE_SET_PMCR_TRAP_INJECT); @@ -174,6 +175,7 @@ void p9_pgpe_ipc_405_set_pmcr(ipc_msg_t* cmd, void* arg) ipc_send_rsp(cmd, IPC_RC_SUCCESS); G_pgpe_optrace_data.word[0] = PGPE_OP_SET_PMCR_WHILE_PENDING; p9_pgpe_optrace(UNEXPECTED_ERROR); + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); } } @@ -200,6 +202,7 @@ void p9_pgpe_ipc_405_wof_control(ipc_msg_t* cmd, void* arg) ipc_send_rsp(cmd, IPC_RC_SUCCESS); G_pgpe_optrace_data.word[0] = PGPE_OP_WOF_CTRL_WHILE_PENDING; p9_pgpe_optrace(UNEXPECTED_ERROR); + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); } } @@ -226,6 +229,7 @@ void p9_pgpe_ipc_405_wof_vfrt(ipc_msg_t* cmd, void* arg) ipc_send_rsp(cmd, IPC_RC_SUCCESS); G_pgpe_optrace_data.word[0] = PGPE_OP_WOF_VFRT_WHILE_PENDING; p9_pgpe_optrace(UNEXPECTED_ERROR); + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); } } @@ -254,6 +258,7 @@ void p9_pgpe_ipc_sgpe_updt_active_cores(ipc_msg_t* cmd, void* arg) ipc_send_rsp(cmd, IPC_RC_SUCCESS); G_pgpe_optrace_data.word[0] = PGPE_OP_CORES_ACTIVE_WHILE_PENDING; p9_pgpe_optrace(UNEXPECTED_ERROR); + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); } } @@ -285,7 +290,7 @@ void p9_pgpe_ipc_sgpe_updt_active_quads(ipc_msg_t* cmd, void* arg) ipc_send_rsp(cmd, IPC_RC_SUCCESS); G_pgpe_optrace_data.word[0] = PGPE_OP_QUADS_ACTIVE_WHILE_PENDING; p9_pgpe_optrace(UNEXPECTED_ERROR); - PK_TRACE_INF("IPC: Updt Quads while pending"); + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); } } diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.c index 811b998a..e7fcbfab 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -143,10 +143,10 @@ void pk_unified_irq_prty_mask_handler(void) { PK_TRACE_ERR("A Phantom IRQ fired, ext_irq_vector_pk=0x%08x%08x", UPPER32(ext_irq_vector_pk), LOWER32(ext_irq_vector_pk)); - PGPE_PANIC_AND_TRACE(PGPE_UIH_EIMR_STACK_OVERFLOW); + PGPE_TRACE_AND_PANIC(PGPE_UIH_EIMR_STACK_OVERFLOW); } - PK_TRACE_DBG("IRQ SET: prty_lvl=%d, g_oimr_stack_ctr=0x%x", g_current_prty_level, g_oimr_stack_ctr); + PK_TRACE_INF("IRQ SET: prty_lvl=%d, g_oimr_stack_ctr=0x%x", g_current_prty_level, g_oimr_stack_ctr); // 3. Return the priority vector in d5 and let hwmacro_get_ext_irq do the // rest, i.e. route first found IRQ in the returned priority vector @@ -179,13 +179,12 @@ void pk_irq_save_and_set_mask(uint32_t iPrtyLvl) g_oimr_stack[g_oimr_stack_ctr] = g_current_prty_level; g_current_prty_level = iPrtyLvl; // Update prty level tracker. g_oimr_override_stack[g_oimr_stack_ctr] = g_oimr_override; - PK_TRACE_DBG("IRQ SET: prty_lvl=%d, g_oimr_stack_ctr=0x%x", g_current_prty_level, g_oimr_stack_ctr); } else { PK_TRACE_ERR("Code bug: OIMR S/R stack counter=%d >= max=%d.", g_oimr_stack_ctr, NUM_EXT_IRQ_PRTY_LEVELS); - PGPE_PANIC_AND_TRACE(PGPE_UIH_EIMR_STACK_OVERFLOW); + PGPE_TRACE_AND_PANIC(PGPE_UIH_EIMR_STACK_OVERFLOW); } // Write the new mask for this priority level. diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.h index 9865d105..f74619ab 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.h @@ -75,7 +75,7 @@ extern const uint64_t ext_irq_vectors_gpe[NUM_EXT_IRQ_PRTY_LEVELS][2]; #define IRQ_VEC_PRTY0_GPE2 (uint64_t)(0x0000000000000000) // Non-task hi-prty IRQs // Shared between all instances -#define IRQ_VEC_PRTY1_GPE2 (uint64_t)(0x2080000000000000) // Task1-OCB_ERROR(HeartBeat Loss)/GPE3_HALT +#define IRQ_VEC_PRTY1_GPE2 (uint64_t)(0x2080080000002000) // Task1-OCB_ERROR(HeartBeat Loss)/GPE3_ERROR/PCB_TYPE5/PVREF #define IRQ_VEC_PRTY2_GPE2 (uint64_t)(0x0001000000000000) // Task2-CHECK_STOP_GPE2 #define IRQ_VEC_PRTY3_GPE2 (uint64_t)(0x0000001000000000) // Task3-IPI2-HI(IPC from OCC/SGPE) #define IRQ_VEC_PRTY4_GPE2 (uint64_t)(0x0000000000004000) // Task4-PCB_INTR_TYPE4(PCB Type4 from CME) @@ -127,7 +127,7 @@ pk_irq_vec_restore( PkMachineContext* context) // Restore the prty level tracker to the task that was interrupted, if any. g_current_prty_level = g_oimr_stack[g_oimr_stack_ctr]; g_oimr_stack_ctr--; - PK_TRACE_DBG("IRQ RS: prty_lvl=%d, g_oimr_stack_ctr=0x%x", g_current_prty_level, g_oimr_stack_ctr); + PK_TRACE_INF("IRQ RS: prty_lvl=%d, g_oimr_stack_ctr=0x%x", g_current_prty_level, g_oimr_stack_ctr); } else { @@ -139,7 +139,9 @@ pk_irq_vec_restore( PkMachineContext* context) pk_critical_section_exit(context); } -//This masks all UIH external interrupts, but leaves timer interrupts enableda +//This masks all UIH external interrupts(EXCEPT for Severe Errors in the Power +//Management Engines, Chip Voltage Reference, or System Checkstop), but leaves +//timer interrupts enableda // //Note: Care must be taken to call equal number of pk_irq_sub_critical_enter and //pk_irq_sub_critical_exit calls @@ -152,7 +154,7 @@ inline void pk_irq_sub_critical_enter(PkMachineContext* ctx) { pk_critical_section_enter(ctx); - pk_irq_save_and_set_mask(0); + pk_irq_save_and_set_mask(3); pk_critical_section_exit(ctx); } diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq_handlers.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq_handlers.c index f699772e..4c806450 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq_handlers.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq_handlers.c @@ -30,7 +30,6 @@ #include "ppe42_cache.h" #include "p9_pgpe_gppb.h" #include "p9_pgpe_optrace.h" -#include "p9_stop_recovery_trigger.h" extern TraceData_t G_pgpe_optrace_data; // @@ -39,9 +38,34 @@ extern TraceData_t G_pgpe_optrace_data; extern PgpePstateRecord G_pgpe_pstate_record; extern GlobalPstateParmBlock* G_gppb; +//Local Function Prototypes +void p9_pgpe_ocb_hb_error_init(); +void p9_pgpe_irq_handler_ocb_err(); +void p9_pgpe_irq_handler_sgpe_err(); +void p9_pgpe_irq_handler_cme_err(); +void p9_pgpe_irq_handler_pvref_err(); + +// +//p9_pgpe_irq_init() +// +//This function is callded during PGPE boot, and does +//needed initialization and setup of PGPE owned IRQs +void p9_pgpe_irq_init() +{ + //Set up OCB Heartbeat Loss(OISR[2]) + p9_pgpe_ocb_hb_error_init(); + + //Setup SGPE_ERR(OISR[8]) and PVREF_ERR(OISR[20]) + out32(OCB_OISR0_CLR, BIT32(8) | BIT32(20));//Clear any pending interrupts + out32(OCB_OIMR0_CLR, BIT32(8) | BIT32(20));//Unmask interrupts +} + // -//OCB Error Interrupt Handler +//p9_pgpe_ocb_hb_error_init // +//This is called during PGPE boot, and sets up OCB_HW loss fir bit +//to generate OCB interrupt. Also, clears the FIR bit +//and any pending OCB_HB interrupt #define OCC_HB_ERROR_FIR 4 void p9_pgpe_ocb_hb_error_init() { @@ -66,79 +90,199 @@ void p9_pgpe_ocb_hb_error_init() out32(OCB_OIMR0_CLR, BIT32(2));//Unmask interrupt } -void p9_pgpe_irq_handler_occ_error(void* arg, PkIrqId irq) +// +//p9_pgpe_irq_handler_occ_sgpe_cme_pvref_error +// +//This is the common handler for OISR[2/OCC_ERROR], OISR[8/GPE3_ERROR], OISR[20/PVREF_ERROR] +//or OISR[50/PCB_TYPE5] +//They are same priority in UIH, but OCB_ERROR is higher priority from HW perspective +//so UIH will always call its handler. Therefore, we have one handler, +//and then check to see which interrupt(s) fired +void p9_pgpe_irq_handler_occ_sgpe_cme_pvref_error(void* arg, PkIrqId irq) { - PK_TRACE_DBG("OCCHB: Enter"); PkMachineContext ctx; + PK_TRACE_INF("Error IRQ Detected"); + uint64_t oisr = ((uint64_t)(in32(OCB_OISR0)) << 32) | in32(OCB_OISR1); + + //OCC Error + if(oisr & BIT64(2)) + { + p9_pgpe_irq_handler_ocb_err(); + } + + //SGPE Error + if(oisr & BIT64(8)) + { + p9_pgpe_irq_handler_sgpe_err(); + } + + //PVREF Error + if(oisr & BIT64(20)) + { + p9_pgpe_irq_handler_pvref_err(); + } + + //CME Error(PCB Type5) + if (oisr & BIT64(50)) + { + p9_pgpe_irq_handler_cme_err(); + } + + pk_irq_vec_restore(&ctx); +} + +// +//p9_pgpe_irq_handler_ocb_error +// +//Handler for OCB_ERROR interrupt which is trigerred by a loss of OCC +//heartbeat +// +void p9_pgpe_irq_handler_ocb_err() +{ ocb_occlfir_t fir; fir.value = 0; + PK_TRACE_INF("OCB FIR Detected"); + out32(OCB_OISR0_CLR, BIT32(2)); + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_FIR_IRQ); + //Read OCB_LFIR GPE_GETSCOM(OCB_OCCLFIR, fir.value); //If OCB_LFIR[occ_hb_error] if (fir.fields.occ_hb_error == 1) { - GPE_PUTSCOM(OCB_OCCLFIR_AND, ~BIT64(OCC_HB_ERROR_FIR)); + + G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.activeQuads << 24) | + (G_pgpe_pstate_record.activeCores << 8); + G_pgpe_optrace_data.word[1] = (G_pgpe_pstate_record.psCurr.fields.glb << 24) | + (G_pgpe_pstate_record.eVidCurr << 8) | + PGPE_OP_TRACE_OCC_HB_FAULT; + p9_pgpe_optrace(SEVERE_FAULT_DETECTED); if((G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE)) { G_pgpe_pstate_record.pstatesStatus = PSTATE_SAFE_MODE_PENDING; } + + G_pgpe_pstate_record.severeFault[SAFE_MODE_FAULT_OCC] = 1; } else { - PK_TRACE_ERR("OCCHB: Unexpected OCC_FIR[0x%08x%08x] ", UPPER32(fir.value), LOWER32(fir.value)); + PK_TRACE_ERR("OCCERR: Unexpected OCC_FIR[0x%08x%08x] ", UPPER32(fir.value), LOWER32(fir.value)); + G_pgpe_optrace_data.word[0] = PGPE_OP_UNEXPECTED_OCC_FIR; + p9_pgpe_optrace(UNEXPECTED_ERROR); } +} - pk_irq_vec_restore(&ctx); +// +//p9_pgpe_irq_handler_sgpe_err +// +//Handles SGPE Fault +// +void p9_pgpe_irq_handler_sgpe_err() +{ + PK_TRACE_INF("SGPE Error"); + + out32(OCB_OISR0_CLR, BIT32(8)); + + //Optrace + G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.activeQuads << 24) | + (G_pgpe_pstate_record.activeCores << 8); + G_pgpe_optrace_data.word[1] = (G_pgpe_pstate_record.psCurr.fields.glb << 24) | + (G_pgpe_pstate_record.eVidCurr << 8) | + PGPE_OP_TRACE_SGPE_FAULT; + p9_pgpe_optrace(SEVERE_FAULT_DETECTED); + + //HALT if DEBUG_HALT is set + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_GPE3_ERROR); + + //Update pstatesStatus, so that actuate thread breaks out of pstatesStatus = ACTIVE_LOOP + //And, then actuate to Psafe. + if ((G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE)) + { + G_pgpe_pstate_record.pstatesStatus = PSTATE_SAFE_MODE_PENDING; + } + else + { + p9_pgpe_pstate_sgpe_fault(); + } + + G_pgpe_pstate_record.severeFault[SAFE_MODE_FAULT_SGPE] = 1; - PK_TRACE_DBG("OCC Error: Exit"); } // -//SGPE Halt Interrupt Handler +//p9_pgpe_irq_handler_pvref_err // -void p9_pgpe_irq_handler_sgpe_halt(void* arg, PkIrqId irq) +//Handles pvref error interrupt +// +void p9_pgpe_irq_handler_pvref_err() { - PK_TRACE_DBG("SGPE Halt: Enter"); - PkMachineContext ctx; + PK_TRACE_INF("PVREF Error"); - out32(OCB_OISR0_CLR, BIT32(8)); - //\TODO: RTC 164107 - //Implement Safe Mode - //p9_pgpe_pstate_safe_mode(); + out32(OCB_OISR0_CLR, BIT32(20)); + + //Optrace + G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.activeQuads << 24) | + (G_pgpe_pstate_record.activeCores << 8); + G_pgpe_optrace_data.word[1] = (G_pgpe_pstate_record.psCurr.fields.glb << 24) | + (G_pgpe_pstate_record.eVidCurr << 8) | + PGPE_OP_TRACE_PVREF_FAULT; + p9_pgpe_optrace(SEVERE_FAULT_DETECTED); - if (in32(OCB_OCCFLG2) & BIT32(STOP_RECOVERY_TRIGGER_ENABLE)) + //HALT if DEBUG_HALT is set + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_PVREF_ERROR); + + //Update pstatesStatus, so that actuate thread breaks out of pstatesStatus = ACTIVE_LOOP + //And, then actuate to Psafe. + if ((G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE)) { - p9_stop_recovery_trigger(); + G_pgpe_pstate_record.pstatesStatus = PSTATE_SAFE_MODE_PENDING; + } + else + { + p9_pgpe_pstate_pvref_fault(); } - pk_irq_vec_restore(&ctx);//Restore interrupts - PK_TRACE_DBG("SGPE Halt: Exit"); + G_pgpe_pstate_record.severeFault[SAFE_MODE_FAULT_PVREF] = 1; + } // -//Checkstop GPE2 Interrupt Handler +//System Checkstop Interrupt Handler // -void p9_pgpe_irq_handler_xstop_gpe2(void* arg, PkIrqId irq) +//Handles system xstop. PGPE does NOT do anything in response +//except logs in the trace +void p9_pgpe_irq_handler_system_xstop(void* arg, PkIrqId irq) { - PK_TRACE_DBG("XSTOP GPE2: Enter"); + PK_TRACE_INF("SYSTEM XSTOP"); PkMachineContext ctx; - PGPE_PANIC_AND_TRACE(PGPE_XSTOP_SGPE_IRQ); + out32(OCB_OISR0_CLR, BIT32(15)); + + //Optrace + G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.activeQuads << 24) | + (G_pgpe_pstate_record.activeCores << 8); + G_pgpe_optrace_data.word[1] = (G_pgpe_pstate_record.psCurr.fields.glb << 24) | + (G_pgpe_pstate_record.eVidCurr << 8) | + PGPE_OP_TRACE_SYS_XSTOP; + p9_pgpe_optrace(SEVERE_FAULT_DETECTED); + + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_XSTOP_GPE2); //Halt if DEBUG_HALT is set + + pk_irq_vec_restore(&ctx);//Restore interrupt - pk_irq_vec_restore(&ctx);//Restore interrupts - PK_TRACE_DBG("XSTOP GPE2: Exit"); } // //PCB Type 1 Interrupt Handler // -//\\tbd RTC:177526 GA1 only Phase1 data is used since only LowerPS fields is supported in PMCR +//Handler PCB Type 1 interrupt which is forwarding of Pstates +//Requests by CME // void p9_pgpe_irq_handler_pcb_type1(void* arg, PkIrqId irq) { @@ -147,9 +291,8 @@ void p9_pgpe_irq_handler_pcb_type1(void* arg, PkIrqId irq) ocb_opit1cn_t opit1cn; uint32_t c; uint32_t opit1pra; - uint32_t flg2_data = in32(OCB_OCCFLG2); - if( flg2_data & PGPE_HCODE_ERR_INJ_BIT ) + if(in32(OCB_OCCFLG2) & BIT32(OCCFLG2_PGPE_HCODE_PSTATE_REQ_ERR_INJ)) { PK_TRACE_ERR("PCB TYPE1 ERROR INJECT TRAP"); PK_PANIC(PGPE_SET_PMCR_TRAP_INJECT); @@ -174,10 +317,9 @@ void p9_pgpe_irq_handler_pcb_type1(void* arg, PkIrqId irq) opit1cn.value = in32(OCB_OPIT1CN(c)); //Extract the LowerPState field and store the Pstate request - //RTC:177526 GA1 only Phase1 data is used since only LowerPS fields is supported in PMCR G_pgpe_pstate_record.coresPSRequest[c] = opit1cn.value & 0xff; - PK_TRACE_DBG("PCB1: c[%d]=0%x", c, G_pgpe_pstate_record.coresPSRequest[c]); - G_pgpe_optrace_data.word[0] = (c << 24) | (G_pgpe_pstate_record.globalPSCurr << 16) | + PK_TRACE_INF("PCB1: c[%d]=0%x", c, G_pgpe_pstate_record.coresPSRequest[c]); + G_pgpe_optrace_data.word[0] = (c << 24) | (G_pgpe_pstate_record.psCurr.fields.glb << 16) | G_pgpe_pstate_record.coresPSRequest[c]; p9_pgpe_optrace(PRC_PCB_T1); } @@ -189,6 +331,8 @@ void p9_pgpe_irq_handler_pcb_type1(void* arg, PkIrqId irq) } else { + opit1pra = in32(OCB_OPIT1PRA); + out32(OCB_OPIT1PRA_CLR, opit1pra); G_pgpe_optrace_data.word[0] = PGPE_OP_PCB_TYPE1_IN_PSTATE_STOPPED; p9_pgpe_optrace(UNEXPECTED_ERROR); } @@ -204,11 +348,11 @@ void p9_pgpe_irq_handler_pcb_type1(void* arg, PkIrqId irq) // //PCB Type 4 Interrupt Handler // -//This interrupt is enabled at PGPE Init and stays enabled always -//However, behaviour depends on pstates status. -//If pstates are enabled, then activeQuads variable is updated, quad manager -//CME(s) is/are sent a Pstate Start Doorbell, and then ACKs are collected. If pstates are disabled, -//then only activeQuads variable is updated +//Handles PCB Type4 interrupts from CME which are CME registration +//messages. In this handler, PGPE simply takes note of which CMEs +//sent registration message. The actual processing is handled in the +//process thread. +// void p9_pgpe_irq_handler_pcb_type4(void* arg, PkIrqId irq) { PkMachineContext ctx; @@ -220,7 +364,7 @@ void p9_pgpe_irq_handler_pcb_type4(void* arg, PkIrqId irq) //Check which CMEs sent Registration Type4 opit4pr = in32(OCB_OPIT4PRA); out32(OCB_OPIT4PRA_CLR, opit4pr); - PK_TRACE_DBG("PCB4: opit4pr 0x%x", opit4pr); + PK_TRACE_INF("PCB4: opit4pr 0x%x", opit4pr); for (q = 0; q < MAX_QUADS; q++) { @@ -231,15 +375,16 @@ void p9_pgpe_irq_handler_pcb_type4(void* arg, PkIrqId irq) //Already registered if (G_pgpe_pstate_record.activeQuads & QUAD_MASK(q)) { - PK_TRACE_DBG("PCB4: Quad %d Already Registered. opit4pra=0x%x", q, opit4pr); - PGPE_PANIC_AND_TRACE(PGPE_CME_UNEXPECTED_REGISTRATION); + PK_TRACE_ERR("PCB4: Quad %d Already Registered. opit4pra=0x%x", q, opit4pr); + PGPE_TRACE_AND_PANIC(PGPE_CME_UNEXPECTED_REGISTRATION); } G_pgpe_pstate_record.pendQuadsRegisterProcess |= QUAD_MASK(q); } } - if ((G_pgpe_pstate_record.semProcessPosted == 0) && G_pgpe_pstate_record.pendQuadsRegisterProcess != 0) + if ((G_pgpe_pstate_record.semProcessPosted == 0) && + G_pgpe_pstate_record.pendQuadsRegisterProcess != 0) { PK_TRACE_DBG("PCB4: posted"); G_pgpe_pstate_record.semProcessPosted = 1; @@ -248,8 +393,6 @@ void p9_pgpe_irq_handler_pcb_type4(void* arg, PkIrqId irq) G_pgpe_pstate_record.semProcessSrc |= SEM_PROCESS_SRC_TYPE4_IRQ; - out32(OCB_OISR1_CLR, BIT32(17)); //Clear out TYPE4 in OISR - //Restore the interrupt here. However, it will be processed inside the process thread //This doesn't cause an issue because back to back type4 interrupts will just //set a bit in pendQuadsRegisterProcess bit field. However, semaphore to the process @@ -258,3 +401,182 @@ void p9_pgpe_irq_handler_pcb_type4(void* arg, PkIrqId irq) pk_irq_vec_restore(&ctx); PK_TRACE_DBG("PCB4: Exit"); } + +// +//CME Error(PCB Type5) Interrupt Handler +// +//Handles CME error +// +// +// Take immediate action here since Pstates cannot be moved using the faulted +// CMEs per normal protocols. The remainder of the actions in response to this error +// occur after going into safe mode +// +void p9_pgpe_irq_handler_cme_err() +{ + + uint32_t q, idx, idx_off, freq_done; + uint32_t opit5pr; + uint32_t opit5prQuad; + uint64_t value, baseVal; + qppm_dpll_freq_t dpllFreq; + ocb_qcsr_t qcsr; + qcsr.value = in32(OCB_QCSR); + uint64_t cme_flags = 0; + + //Optrace + G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.activeQuads << 24) | + (G_pgpe_pstate_record.activeCores << 8); + G_pgpe_optrace_data.word[1] = (G_pgpe_pstate_record.psCurr.fields.glb << 24) | + (G_pgpe_pstate_record.eVidCurr << 8) | + PGPE_OP_TRACE_CME_FAULT; + p9_pgpe_optrace(SEVERE_FAULT_DETECTED); + + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_CME_FAULT); //Halt if DEBUG_HALT is set + + //Check which CMEs sent Type5 + opit5pr = in32(OCB_OPIT5PRA); + out32(OCB_OPIT5PRA_CLR, opit5pr); + PK_TRACE_INF("CER:CME ERR opit5pr 0x%x", opit5pr); + + //If prolonged droop recovery is not active + if (!(in32(OCB_OCCFLG) & BIT32(PGPE_PROLONGED_DROOP_WORKAROUND_ACTIVE))) + { + p9_pgpe_pstate_write_core_throttle(CORE_IFU_THROTTLE, RETRY); + } + + wrteei(1); + + for (q = 0; q < MAX_QUADS; q++) + { + opit5prQuad = (opit5pr >> ((MAX_QUADS - q + 1) << 2)) & 0xf; + + + if (opit5prQuad) + { + PK_TRACE_DBG("CER:Quad[%d]", q); + + G_pgpe_pstate_record.errorQuads |= QUAD_MASK(q); + + //1.1 Halt both CMEs in the quad containing faulted CME, + if (qcsr.fields.ex_config & QUAD_EX0_MASK(q)) + { + GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_XIXCR, q, 0), BIT64(3)); //XCR[1:3] = 001(Halt the CME) + GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS, q, 0), cme_flags); + } + + if (qcsr.fields.ex_config & QUAD_EX1_MASK(q)) + { + GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_XIXCR, q, 1), BIT64(3)); //XCR[1:3] = 001(Halt the CME) + + //Read CME1 CME_FLAGS, if CME0 not configured + if (!(qcsr.fields.ex_config & QUAD_EX0_MASK(q))) + { + GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS, q, 1), cme_flags); + } + } + + PK_TRACE_DBG("CER:Quad[%d] CMEs Halted", q); + + //1.2 The quad in error is stepped out of resonance by the PGPE. This keeps the cores that may be + // running in the quad operating. There is a momentary rise in power as resonance is disabled. + // (~100us). + + //Open Analog Controls for SCOM access in this quad + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QPMMR_CLR, q), BIT64(22) | BIT64(24) | BIT64(26)); + + if(cme_flags & BIT64(CME_FLAGS_RCLK_OPERABLE)) + { + //. Read the QACCR + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QACCR, q), value); + baseVal = value & BITS64(13, 51); + value &= BITS64(0, 15); + value = value >> 48; + + //Search from the lowest index of the resclk table until a match to the QACCR value + idx_off = G_gppb->resclk.resclk_index[0]; + idx = idx_off; + + while(idx < RESCLK_STEPS) + { + if (G_gppb->resclk.steparray[idx].value == value) + { + break; + } + else + { + idx++; + } + } + + if (idx == RESCLK_STEPS) + { + PK_TRACE_DBG("CER:Resclk Idx Search Failed"); + PGPE_TRACE_AND_PANIC(PGPE_RESCLK_IDX_SEARCH_FAIL); + } + + //PGPE steps down from that index to the off index value + while (idx > idx_off) + { + value = (((uint64_t)G_gppb->resclk.steparray[--idx].value) << 48) | baseVal; + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QACCR, q), value); + } + + PK_TRACE_DBG("CER:Quad[%d] ResClk Disabled", q); + } + + //1.3 Move DPLL to Fsafe (~100us) + dpllFreq.value = 0; + dpllFreq.fields.fmax = G_gppb->dpll_pstate0_value - G_pgpe_pstate_record.safePstate; + dpllFreq.fields.fmult = dpllFreq.fields.fmax; + dpllFreq.fields.fmin = dpllFreq.fields.fmax; + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_DPLL_FREQ, q), dpllFreq.value); + + // poll DPLL Status frequency change done before proceeding + // + freq_done = 0; + + do + { + //Read DPLL_STAT + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_DPLL_STAT, q), value); + + if(cme_flags & BIT64(CME_FLAGS_VDM_OPERABLE)) + { + freq_done = value & BIT64(60); //[UPDATE_COMPLETE]=1 means done + } + else + { + freq_done = !(value & BIT64(61)); //[FREQ_CHANGE]=0 means done + } + } + while (!freq_done); + + PK_TRACE_DBG("CER:Quad[%d] DPLL Moved to Fsafe", q); + + //2. The quad in error is removed from the expected Ack vector. + G_pgpe_pstate_record.activeQuads &= (~QUAD_MASK(q)); + G_pgpe_pstate_record.activeDB &= ~(QUAD_ALL_CORES_MASK(q)); + PK_TRACE_DBG("CER: Quad[%d] Removed from activeQuads", q); + } + } + + //If prolonged droop recovery is not active + if (!(in32(OCB_OCCFLG) & BIT32(PGPE_PROLONGED_DROOP_WORKAROUND_ACTIVE))) + { + p9_pgpe_pstate_write_core_throttle(CORE_THROTTLE_OFF, RETRY); + } + + //It is safe for PGPE to leave VDMs enabled and not change the vid compare + //or thresholds later when the external voltage is dropped to Psafe worst + //case, VDMs on the failing Quad will indicate a permanent droop which + //causes the DPLL to drop 12.5% even if not needed + + if((G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE)) + { + G_pgpe_pstate_record.pstatesStatus = PSTATE_SAFE_MODE_PENDING; + } + + G_pgpe_pstate_record.severeFault[SAFE_MODE_FAULT_CME] = 1; + +} diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c index 3add869c..39e1da64 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c @@ -43,18 +43,10 @@ PgpePstateRecord G_pgpe_pstate_record __attribute__((section (".dump_ptrs"))) = {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, - {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}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, @@ -66,32 +58,42 @@ PgpePstateRecord G_pgpe_pstate_record __attribute__((section (".dump_ptrs"))) = 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} }; EXTERNAL_IRQ_TABLE_START IRQ_HANDLER_DEFAULT //OCCHW_IRQ_DEBUGGER IRQ_HANDLER_DEFAULT //OCCHW_IRQ_TRACE_TRIGGER -IRQ_HANDLER(p9_pgpe_irq_handler_occ_error, NULL) //OCCHW_IRQ_OCC_ERROR +IRQ_HANDLER(p9_pgpe_irq_handler_occ_sgpe_cme_pvref_error, NULL) //OCCHW_IRQ_OCC_ERROR IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PBA_ERROR IRQ_HANDLER_DEFAULT //OCCHW_IRQ_SRT_ERROR IRQ_HANDLER_DEFAULT //OCCHW_IRQ_GPE0_HALT IRQ_HANDLER_DEFAULT //OCCHW_IRQ_GPE1_HALT IRQ_HANDLER_DEFAULT //OCCHW_IRQ_GPE2_HALT -IRQ_HANDLER(p9_pgpe_irq_handler_sgpe_halt, NULL) //OCCHW_IRQ_GPE3_HALT +IRQ_HANDLER(p9_pgpe_irq_handler_occ_sgpe_cme_pvref_error, NULL) //OCCHW_IRQ_GPE3_HALT IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PPC405_HALT IRQ_HANDLER_DEFAULT //OCCHW_IRQ_OCB_ERROR IRQ_HANDLER_DEFAULT //OCCHW_IRQ_SPIPSS_ERROR IRQ_HANDLER_DEFAULT //OCCHW_IRQ_CHECK_STOP_PPC405 IRQ_HANDLER_DEFAULT //OCCHW_IRQ_CHECK_STOP_GPE0 IRQ_HANDLER_DEFAULT //OCCHW_IRQ_CHECK_STOP_GPE1 -IRQ_HANDLER(p9_pgpe_irq_handler_xstop_gpe2, NULL) //OCCHW_IRQ_CHECK_STOP_GPE2 +IRQ_HANDLER(p9_pgpe_irq_handler_system_xstop, NULL) //OCCHW_IRQ_CHECK_STOP_GPE2 IRQ_HANDLER_DEFAULT //OCCHW_IRQ_CHECK_STOP_GPE3 IRQ_HANDLER_DEFAULT //OCCHW_IRQ_OCC_MALF_ALERT IRQ_HANDLER_DEFAULT //OCCHW_IRQ_ADU_MALF_ALERT IRQ_HANDLER_DEFAULT //OCCHW_IRQ_EXTERNAL_TRAP -IRQ_HANDLER_DEFAULT //OCCHW_IRQ_IVRM_PVREF_ERROR +IRQ_HANDLER(p9_pgpe_irq_handler_occ_sgpe_cme_pvref_error, NULL)//OCCHW_IRQ_IVRM_PVREF_ERROR IRQ_HANDLER_DEFAULT //OCCHW_IRQ_OCC_TIMER0 IRQ_HANDLER_DEFAULT //OCCHW_IRQ_OCC_TIMER1 IRQ_HANDLER_DEFAULT //OCCHW_IRQ_AVS_SLAVE0 @@ -121,7 +123,7 @@ IRQ_HANDLER(p9_pgpe_irq_handler_pcb_type1, NULL) //OCCHW_IRQ_PMC_PCB_INTR_TYPE1_ IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE2_PENDING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE3_PENDING IRQ_HANDLER(p9_pgpe_irq_handler_pcb_type4, NULL) //OCCHW_IRQ_PMC_PCB_INTR_TYPE4_PENDING -IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE5_PENDING +IRQ_HANDLER(p9_pgpe_irq_handler_occ_sgpe_cme_pvref_error, NULL) //OCCHW_IRQ_PMC_PCB_INTR_TYPE5_PENDING IRQ_HANDLER_DEFAULT //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 @@ -138,7 +140,8 @@ IRQ_HANDLER_DEFAULT //OCCHW_IRQ_RESERVED_63 EXTERNAL_IRQ_TABLE_END #define KERNEL_STACK_SIZE 512 -#define THREAD_STACK_SIZE 512 +#define THREAD_PROCESS_STACK_SIZE 512 +#define THREAD_ACTUATE_STACK_SIZE 768 #define PGPE_THREAD_PRIORITY_PROCESS_REQUESTS 1 #define PGPE_THREAD_PRIORITY_ACTUATE_PSTATES 2 @@ -147,8 +150,8 @@ uint8_t G_kernel_stack[KERNEL_STACK_SIZE]; extern uint32_t g_pgpe_timebase_hz __attribute__ ((section (".pgpe_image_header"))); //Thread Stacks -uint8_t G_p9_pgpe_thread_process_requests_stack[THREAD_STACK_SIZE]; -uint8_t G_p9_pgpe_thread_actuate_pstates_stack[THREAD_STACK_SIZE]; +uint8_t G_p9_pgpe_thread_process_requests_stack[THREAD_PROCESS_STACK_SIZE]; +uint8_t G_p9_pgpe_thread_actuate_pstates_stack[THREAD_ACTUATE_STACK_SIZE]; //Thread Control Block PkThread G_p9_pgpe_thread_process_requests; @@ -173,7 +176,7 @@ main(int argc, char** argv) if(mfspr(287) != PVR_CONST) { - PGPE_PANIC_AND_TRACE(PGPE_BAD_DD_LEVEL); + PGPE_TRACE_AND_PANIC(PGPE_BAD_DD_LEVEL); } uint32_t timebase = g_pgpe_timebase_hz; @@ -208,7 +211,7 @@ main(int argc, char** argv) (PkThreadRoutine)p9_pgpe_thread_process_requests, (void*)NULL, (PkAddress)G_p9_pgpe_thread_process_requests_stack, - (size_t)THREAD_STACK_SIZE, + (size_t)THREAD_PROCESS_STACK_SIZE, (PkThreadPriority)PGPE_THREAD_PRIORITY_PROCESS_REQUESTS); PK_TRACE_BIN("G_p9_pgpe_thread_process_requests", @@ -220,7 +223,7 @@ main(int argc, char** argv) (PkThreadRoutine)p9_pgpe_thread_actuate_pstates, (void*)NULL, (PkAddress)G_p9_pgpe_thread_actuate_pstates_stack, - (size_t)THREAD_STACK_SIZE, + (size_t)THREAD_ACTUATE_STACK_SIZE, (PkThreadPriority)PGPE_THREAD_PRIORITY_ACTUATE_PSTATES); PK_TRACE_BIN("G_p9_pgpe_thread_actuate_pstates", @@ -258,8 +261,8 @@ main(int argc, char** argv) PK_TRACE_DBG("Init all pstate data to default values"); p9_pgpe_pstate_init(); - PK_TRACE_DBG("Setup OCCFIR[OCC_HB Error]"); - p9_pgpe_ocb_hb_error_init(); + PK_TRACE_DBG("Setup IRQs"); + p9_pgpe_irq_init(); g_oimr_override |= BIT64(49); out32(OCB_OIMR1_OR, BIT32(17)); //Disable PCB_INTR_TYPE4 diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_optrace.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_optrace.h index 4483c184..dea34083 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_optrace.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_optrace.h @@ -68,15 +68,31 @@ enum PGPE_OP_TRACE_ENCODES PRC_CORES_ACTV = 0x5A, PRC_QUAD_ACTV = 0x5B, FIT_TB_SYNC = 0x5C, + SEVERE_FAULT_DETECTED = 0x5D, SYSTEM_XSTOP = 0x4D, PRC_PM_SUSP = 0x4E, - PRC_SAFE_MODE = 0x5F, + PRC_SAFE_MODE = 0x4F, //Debug Markers PROLONGED_DROOP_EVENT = 0x9E, PROLONGED_DROOP_RESOLVED = 0xAF }; +enum PGPE_OP_TRACE_SEVERE_FAULTS +{ + PGPE_OP_TRACE_PVREF_FAULT = 0x10, + PGPE_OP_TRACE_SGPE_FAULT = 0x8, + PGPE_OP_TRACE_CME_FAULT = 0x4, + PGPE_OP_TRACE_OCC_HB_FAULT = 0x2, + PGPE_OP_TRACE_SYS_XSTOP = 0x1 +}; + +enum PGPE_OP_TRACE_SAFE_MODE_REASON +{ + PGPE_OP_TRACE_OCCFLG_SUSP = 0x2, + PGPE_OP_TRACE_OCCFLG_SAFE = 0x1 +}; + //Unexpected Errors enum PGPE_OP_TRACE_UNEXPECTED_ERRORS { @@ -113,7 +129,8 @@ enum PGPE_OP_TRACE_UNEXPECTED_ERRORS PGPE_OP_QUADS_ACTIVE_IN_PM_SUSP = 0x51, PGPE_OP_QUADS_ACTIVE_WHILE_PENDING = 0x52, PGPE_OP_PCB_TYPE1_IN_PSTATE_STOPPED = 0x60, - PGPE_OP_PCB_TYPE1_IN_PMCR_OWNER_OCC = 0x61 + PGPE_OP_PCB_TYPE1_IN_PMCR_OWNER_OCC = 0x61, + PGPE_OP_UNEXPECTED_OCC_FIR = 0x80 }; // 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 7eb92289..70bcd967 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 @@ -31,9 +31,13 @@ #include "pstate_pgpe_occ_api.h" #include "wof_sgpe_pgpe_api.h" #include "p9_pgpe_header.h" +#include "p9_stop_recovery_trigger.h" -#define VRATIO_ROUNDING_ADJUST 24 //VFRT tables are built assuming we truncate +//VFRT tables are built assuming we truncate, and 24 is needed to adjust for the +//intermediate value truncation in converting Vratio to an Vindex, which involves +//a *24(multiply by 24) conversion for a max error of -24(negative 24) +#define VRATIO_ROUNDING_ADJUST 24 #define MAX_VRATIO 65535 // (2^16) - 1 enum IPC_PEND_TBL @@ -62,14 +66,14 @@ enum QUAD_BIT_MASK enum PSTATE_STATUS { - PSTATE_INIT = 0, //PGPE Booted - PSTATE_ACTIVE = 1, //Pstates are active - PSTATE_STOP_PENDING = 2, //Pstate Stop Pending - PSTATE_SAFE_MODE_PENDING = 3, //Safe Mode Pending - PSTATE_SAFE_MODE = 4, //Safe Mode - PSTATE_STOPPED = 5, //Pstates are stopped - PSTATE_PM_SUSPEND_PENDING = 6, //PM Complex Suspend Pending - PSTATE_PM_SUSPENDED = 7 //PM Complex Suspend + PSTATE_INIT = 0x00000001, //PGPE Booted + PSTATE_ACTIVE = 0x00000002, //Pstates are active + PSTATE_STOP_PENDING = 0x00000004, //Pstate Stop Pending + PSTATE_SAFE_MODE_PENDING = 0x00000008, //Safe Mode Pending + PSTATE_SAFE_MODE = 0x00000010, //Safe Mode + PSTATE_STOPPED = 0x00000020, //Pstates are stopped + PSTATE_PM_SUSPEND_PENDING = 0x00000040, //PM Complex Suspend Pending + PSTATE_PM_SUSPENDED = 0x00000080, //PM Complex Suspend }; enum WOF_STATUS @@ -79,12 +83,22 @@ enum WOF_STATUS WOF_ENABLED = 2 //Pstates are active }; -enum PSTATE_DB0 +enum SAFE_MODE_FAULT_INDEX { - PGPE_DB0_UNICAST = 0, - PGPE_DB0_MULTICAST = 1, - PGPE_DB0_ACK_WAIT_CME = 0, - PGPE_DB0_ACK_SKIP = 1 + SAFE_MODE_FAULT_OCC = 0, + SAFE_MODE_FAULT_SGPE = 1, + SAFE_MODE_FAULT_CME = 2, + SAFE_MODE_FAULT_PVREF = 3 +}; + +enum PSTATE_DB +{ + PGPE_DB_ACK_WAIT_CME = 0, + PGPE_DB_ACK_SKIP = 1, + PGPE_DB0_TYPE_UNICAST = 0, + PGPE_DB0_TYPE_MULTICAST = 1, + PGPE_DB3_SKIP_CHECK_NACKS = 0, + PGPE_DB3_CHECK_NACKS = 1 }; enum SEMAPHORE_PROCESS_POST_SRC @@ -122,7 +136,22 @@ typedef struct ipc_req uint8_t pad[2]; } ipc_req_t; -/// PGPE PState + +typedef union sys_ps +{ + uint64_t value; + struct + { + uint8_t pad; + uint8_t glb; + uint8_t quads[6]; + } fields; +} sys_ps_t; + +// +// PGPE PState +// +// Structure for storing internal PGPE state typedef struct { uint8_t pstatesStatus; //1 @@ -134,18 +163,10 @@ typedef struct uint8_t psClipMax[MAX_QUADS], //12 higher numbered(min freq and volt) psClipMin[MAX_QUADS]; //18 lower numbered(max freq and volt) uint8_t coresPSRequest[MAX_CORES]; //42 per core requested pstate - uint8_t quadPSComputed[MAX_QUADS]; //48 computed Pstate per quad - uint8_t globalPSComputed; //49 computed global Pstate - uint8_t pad1; //50 - uint8_t quadPSTarget[MAX_QUADS]; //56 target Pstate per quad - uint8_t globalPSTarget; //57 target global Pstate - uint8_t pad2; //58 - uint8_t quadPSCurr[MAX_QUADS]; //64 target Pstate per quad - uint8_t globalPSCurr; //65 target global Pstate - uint8_t pad3; //66 - uint8_t quadPSNext[MAX_QUADS]; //72 target Pstate per quad - uint8_t globalPSNext; //73 - uint8_t pad4[3]; //76 + sys_ps_t psComputed; //48 + sys_ps_t psTarget; //56 + sys_ps_t psCurr; //64 + sys_ps_t psNext; //72 uint32_t eVidCurr, eVidNext; //84 ipc_req_t ipcPendTbl[MAX_IPC_PEND_TBL_ENTRIES]; //156(9entries*8bytes) HomerVFRTLayout_t* pVFRT; //160 @@ -162,42 +183,79 @@ typedef struct uint32_t pendingPminClipBcast, pendingPmaxClipBcast;//252,256 uint32_t semProcessPosted, semProcessSrc;//260,264 uint32_t quadsNACKed, cntNACKs, quadsCntNACKs[MAX_QUADS];//268,272,296 + uint32_t errorQuads; + uint32_t updatePGPEBeacon; + uint8_t severeFault[4]; } PgpePstateRecord __attribute__ ((aligned (8))); +typedef struct db0_parms +{ + uint64_t db0val; + uint32_t type; + uint32_t targetCores; + uint32_t waitForAcks; + uint32_t expectedAckFrom; + uint32_t expectedAckValue; +} db0_parms_t; + +typedef struct db3_parms +{ + uint64_t db3val; + uint64_t db0val; + uint32_t targetCores; + uint32_t waitForAcks; + uint32_t expectedAckFrom; + uint32_t expectedAckValue; + uint32_t checkNACKs; +} db3_parms_t; + // //Functions called by threads // +//PGPE Boot/Iniitilization/Common void p9_pgpe_pstate_init(); void p9_pgpe_pstate_setup_process_pcb_type4(); +void p9_pgpe_pstate_ipc_rsp_cb_sem_post(ipc_msg_t* msg, void* arg); + +//Pstate Calculation and Status Updates void p9_pgpe_pstate_do_auction(); void p9_pgpe_pstate_apply_clips(); void p9_pgpe_pstate_calc_wof(); -void p9_pgpe_pstate_updt_actual_quad(uint32_t q); +void p9_pgpe_pstate_updt_actual_quad(); void p9_pgpe_pstate_update_wof_state(); -void p9_pgpe_pstate_freq_updt(); -void p9_pgpe_send_db0(uint64_t db0, uint32_t coresVector, uint32_t type, uint32_t process_ack, uint32_t ackVector); -void p9_pgpe_send_db3_high_priority_pstate(uint32_t coresVector, uint32_t ackVector); -void p9_pgpe_wait_cme_db_ack(uint32_t coresVector); -void p9_pgpe_pstate_start(uint32_t pstate_start_origin); -void p9_pgpe_wait_cme_db_ack(uint32_t coresVector); + +//CME Communication +void p9_pgpe_send_db0(db0_parms_t p); +void p9_pgpe_send_db3(db3_parms_t p); +void p9_pgpe_wait_cme_db_ack(uint32_t quadAckExpect, uint32_t expectedAck); +void p9_pgpe_pstate_send_pmsr_updt(uint32_t command, uint32_t targetCoresVector, uint32_t quadsAckVector); + +//OCC IPC Processing void p9_pgpe_pstate_start(uint32_t pstate_start_origin); void p9_pgpe_pstate_set_pmcr_owner(uint32_t owner); void p9_pgpe_pstate_stop(); void p9_pgpe_pstate_clip_bcast(uint32_t clip_type); +void p9_pgpe_pstate_wof_ctrl(uint32_t action); + +//SGPE Comminucation/Processing void p9_pgpe_pstate_process_quad_entry_notify(uint32_t quadsAffected); void p9_pgpe_pstate_process_quad_entry_done(uint32_t quadsAffected); void p9_pgpe_pstate_process_quad_exit(uint32_t quadsAffected); -void p9_pgpe_pstate_wof_ctrl(uint32_t action); +void p9_pgpe_pstate_send_suspend_stop(); void p9_pgpe_pstate_send_ctrl_stop_updt(uint32_t ctrl); + +//Error Handling void p9_pgpe_pstate_apply_safe_clips(); void p9_pgpe_pstate_safe_mode(); -void p9_pgpe_pstate_send_suspend_stop(); void p9_pgpe_pstate_pm_complex_suspend(); -void p9_pgpe_pstate_pmsr_updt(uint32_t command, uint32_t targetCoresVector, uint32_t quadsAckVector); +void p9_pgpe_pstate_sgpe_fault(); +void p9_pgpe_pstate_cme_fault(); +void p9_pgpe_pstate_pvref_fault(); + +//Actuation int32_t p9_pgpe_pstate_at_target(); void p9_pgpe_pstate_do_step(); void p9_pgpe_pstate_updt_ext_volt(uint32_t tgtEVid); -void p9_pgpe_pstate_ipc_rsp_cb_sem_post(ipc_msg_t* msg, void* arg); void p9_pgpe_pstate_write_core_throttle(uint32_t throttleData, uint32_t enable_retry); #endif // 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 4fc90f53..aa8fe255 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 @@ -76,12 +76,16 @@ void p9_pgpe_thread_actuate_pstates(void* arg) //Mask all external interrupts. Timers are still enabled pk_irq_sub_critical_enter(&ctx); p9_pgpe_pstate_start(PSTATE_START_OCC_FLAG); - G_pgpe_optrace_data.word[0] = (START_STOP_FLAG << 24) | (G_pgpe_pstate_record.globalPSComputed << 16) | (in32( + G_pgpe_optrace_data.word[0] = (START_STOP_FLAG << 24) | (G_pgpe_pstate_record.psComputed.fields.glb << 16) | (in32( OCB_QCSR) >> 16); p9_pgpe_optrace(PRC_START_STOP); pk_irq_sub_critical_exit(&ctx); } + + // Set OCC Scratch2[PGPE_ACTIVE] and start updating beacon, + // so that external world knows that PGPE is UP + G_pgpe_pstate_record.updatePGPEBeacon = 1; occScr2 = in32(OCB_OCCS2); occScr2 |= BIT32(PGPE_ACTIVE); out32(OCB_OCCS2, occScr2); @@ -131,8 +135,6 @@ void p9_pgpe_thread_actuate_pstates(void* arg) pk_irq_sub_critical_enter(&ctx); //We check that pstates are active after entering critical section - //It's possible that some IPC or even FIT before we set actuating=1 - //has updated the PstatesState to a !PSTATE_ACTIVE state if (G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE) { p9_pgpe_pstate_do_step(); @@ -183,10 +185,10 @@ void p9_pgpe_thread_actuate_pstates(void* arg) //Make sure that minPS is not below(higher value/low freq-volt) than safePstate minPS = (minPS > G_pgpe_pstate_record.safePstate) ? G_pgpe_pstate_record.safePstate : minPS; - if (G_pgpe_pstate_record.quadPSCurr[q] > G_pgpe_pstate_record.psClipMax[q] || - G_pgpe_pstate_record.quadPSCurr[q] < minPS || - G_pgpe_pstate_record.globalPSCurr > G_pgpe_pstate_record.psClipMax[q] || - G_pgpe_pstate_record.globalPSCurr < minPS) + if (G_pgpe_pstate_record.psCurr.fields.quads[q] > G_pgpe_pstate_record.psClipMax[q] || + G_pgpe_pstate_record.psCurr.fields.quads[q] < minPS || + G_pgpe_pstate_record.psCurr.fields.glb > G_pgpe_pstate_record.psClipMax[q] || + G_pgpe_pstate_record.psCurr.fields.glb < minPS) { inRange = 0; 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 2a13c6de..2d9246a3 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 @@ -85,7 +85,7 @@ void p9_pgpe_thread_process_requests(void* arg) out32(OCB_OCCFLG_OR, BIT32(29)); } - PK_TRACE_INF("PTH:Inited"); + PK_TRACE_DBG("PTH:Inited"); while(1) { @@ -104,13 +104,9 @@ void p9_pgpe_thread_process_requests(void* arg) //Go through IPC Pending Table - //We must process this before CORES and QUADS active updt. Once, OCC has sent - //the WOF_DISABLE, PGPE must stop interlocking quads active updt with it. Also, PGPE - //must properly ensure that any pending CORE active update are processed properly - //once WOF_DISABLE has been received. SGPE should get all ACKS, but no more WOF - //calculation be performed if (G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_WOF_CTRL].pending_processing) { + //During processo_wof_ctrl, it's pending_ack bit is cleared p9_pgpe_process_wof_ctrl(); } @@ -118,6 +114,8 @@ void p9_pgpe_thread_process_requests(void* arg) { p9_pgpe_process_sgpe_updt_active_cores(); + //If we have pending_ack for active cores, then don't open up IPC yet. It will be opened + //up after actuation if(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_CORES_UPDT].pending_ack == 1) { restore_irq = 0; @@ -126,11 +124,13 @@ void p9_pgpe_thread_process_requests(void* arg) if (G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SGPE_ACTIVE_QUADS_UPDT].pending_processing == 1) { + //During process_spge_updt_active_quads, it's pending_ack bit may be cleared p9_pgpe_process_sgpe_updt_active_quads(); } if(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_PSTATE_START_STOP].pending_processing == 1) { + //During process_start_stop, it's pending_ack bit is cleared p9_pgpe_process_start_stop(); } @@ -138,6 +138,8 @@ void p9_pgpe_thread_process_requests(void* arg) { p9_pgpe_process_clip_updt(); + //If we have pending_ack for clip_updt cores, then don't open up IPC yet. It will be opened + //up after actuation if(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_CLIP_UPDT].pending_ack == 1) { restore_irq = 0; @@ -148,6 +150,8 @@ void p9_pgpe_thread_process_requests(void* arg) { p9_pgpe_process_wof_vfrt(); + //If we have pending_ack for wof_vfrt, then don't open up IPC yet. It will be opened + //up after actuation if(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_WOF_VFRT].pending_ack == 1) { restore_irq = 0; @@ -156,13 +160,8 @@ void p9_pgpe_thread_process_requests(void* arg) if (G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SET_PMCR_REQ].pending_processing == 1) { + //During process_start_stop, it's pending_ack bit is cleared p9_pgpe_process_set_pmcr_req(); - - if(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SET_PMCR_REQ].pending_ack == 1) - { - restore_irq = 0; - } - } if (G_pgpe_pstate_record.ipcPendTbl[IPC_ACK_CTRL_STOP_UPDT].pending_processing) @@ -207,7 +206,7 @@ void p9_pgpe_thread_process_requests(void* arg) void p9_pgpe_process_sgpe_updt_active_cores() { PK_TRACE_DBG("PTH: Core Updt Entry"); - uint32_t c, ack_now = 0; + uint32_t c, ack_now = 0, bad_rc = 0; 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; @@ -221,6 +220,7 @@ void p9_pgpe_process_sgpe_updt_active_cores() G_pgpe_optrace_data.word[0] = PGPE_OP_CORES_ACTIVE_IN_WOF_DISABLED; p9_pgpe_optrace(UNEXPECTED_ERROR); ack_now = 1; + bad_rc = 1; } else { @@ -230,7 +230,7 @@ void p9_pgpe_process_sgpe_updt_active_cores() if(G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE) { //Store separately as shared SRAM location is split - PK_TRACE_DBG("PTH: Core Updt type=%u(0/1=EN/EX) reqCores=0x%x", args->fields.update_type, args->fields.active_cores); + PK_TRACE_INF("PTH: Core Updt type=%u(0/1=EN/EX) reqCores=0x%x", args->fields.update_type, args->fields.active_cores); //If ENTRY type then send ACK to SGPE immediately //Otherwise, wait to ACK until WOF Clip has been applied(from actuate_pstate thread) @@ -249,8 +249,6 @@ void p9_pgpe_process_sgpe_updt_active_cores() G_pgpe_pstate_record.pQuadState0->fields.active_cores = (G_pgpe_pstate_record.activeCores >> 16); G_pgpe_pstate_record.pQuadState1->fields.active_cores = (G_pgpe_pstate_record.activeCores & 0x0000FF00); - PK_TRACE_DBG("PTH: numActiveCores=0x%x,activeCores=0x%x", G_pgpe_pstate_record.numActiveCores, - G_pgpe_pstate_record.activeCores); PK_TRACE_DBG("PTH: quadPS2=0x%08x%08x,activeCores=0x%x", G_pgpe_pstate_record.pQuadState0->value >> 32, G_pgpe_pstate_record.pQuadState0->value, G_pgpe_pstate_record.pQuadState0->fields.active_cores ); PK_TRACE_DBG("PTH: quadPS1=0x%08x%08x,activeCores=0x%x", G_pgpe_pstate_record.pQuadState1->value >> 32, @@ -267,7 +265,8 @@ void p9_pgpe_process_sgpe_updt_active_cores() } } - PK_TRACE_DBG("PTH: numActiveCores=0x%x", G_pgpe_pstate_record.numActiveCores); + PK_TRACE_INF("PTH: numActiveCores=0x%x,activeCores=0x%x", G_pgpe_pstate_record.numActiveCores, + G_pgpe_pstate_record.activeCores); //OP_TRACE(Do before auction and wof calculation) G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.activeQuads << 24) | @@ -288,6 +287,11 @@ void p9_pgpe_process_sgpe_updt_active_cores() args->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; PK_TRACE_DBG("PTH: Core Entry ACK back to SGPE"); p9_pgpe_optrace(ACK_CORES_ACTV); + + if (bad_rc == 1) + { + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_SGPE_IPC_ACK_BAD_RC); + } } PK_TRACE_DBG("PTH: Core Updt Exit"); @@ -327,7 +331,7 @@ void p9_pgpe_process_sgpe_updt_active_quads() p9_pgpe_pstate_process_quad_entry_done(args->fields.requested_quads << 2); } - args->fields.return_active_quads = G_pgpe_pstate_record.activeQuads >> 2; + args->fields.return_active_quads = (G_pgpe_pstate_record.activeQuads >> 2); args->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; } //EXIT @@ -341,19 +345,21 @@ void p9_pgpe_process_sgpe_updt_active_quads() //Otherwise, we don't as SAFE_MODE or PM_COMPLEX_SUSPEND or STOP is pending if(G_pgpe_pstate_record.wofStatus == WOF_ENABLED && G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE) { - PK_TRACE_DBG("PTH: OCCLFG[30] set"); + PK_TRACE_INF("PTH: OCCLFG[30] set"); out32(OCB_OCCFLG_OR, BIT32(REQUESTED_ACTIVE_QUAD_UPDATE));//Set OCCFLG[REQUESTED_ACTIVE_QUAD_UPDATE] ack_now = 0; } else { p9_pgpe_pstate_process_quad_exit(args->fields.requested_quads << 2); - args->fields.return_active_quads = (G_pgpe_pstate_record.activeQuads >> 2) | - args->fields.requested_quads; //activeQuads isn't updated until registration, so we OR with requested quads. + args->fields.return_active_quads = G_pgpe_pstate_record.pReqActQuads->fields.requested_active_quads >> + 2; //activeQuads isn't updated until registration, so we OR with requested quads. args->fields.return_code = IPC_SGPE_PGPE_RC_SUCCESS; } } + PK_TRACE_INF("PTH: type=0x%x(EN=0,EX=1), req=0x%x,active=0x%x,ret=0x%x", args->fields.update_type, + args->fields.requested_quads, G_pgpe_pstate_record.activeQuads, args->fields.return_active_quads); G_pgpe_optrace_data.word[0] = (args->fields.requested_quads << 26) | (SS << 24) | (G_pgpe_pstate_record.activeCores >> 8); @@ -372,7 +378,7 @@ void p9_pgpe_process_sgpe_updt_active_quads() void p9_pgpe_process_start_stop() { PK_TRACE_DBG("PTH: Start/Stop Entry"); - uint32_t ack_now = 1; + uint32_t ack_now = 1, bad_rc = 0; ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_PSTATE_START_STOP].cmd; ipcmsg_start_stop_t* args = (ipcmsg_start_stop_t*)async_cmd->cmd_data; @@ -381,21 +387,18 @@ void p9_pgpe_process_start_stop() PK_TRACE_DBG("START_STOP: Imm"); args->msg_cb.rc = PGPE_RC_SUCCESS; G_pgpe_optrace_data.word[0] = (START_STOP_IPC << 24) | - (G_pgpe_pstate_record.globalPSComputed << 16) | + (G_pgpe_pstate_record.psComputed.fields.glb << 16) | (in32(OCB_QCSR) >> 16); p9_pgpe_optrace(PRC_START_STOP); } - else if(G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPEND_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPENDED || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + else if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_PM_SUSPEND_PENDING | PSTATE_PM_SUSPENDED | + PSTATE_SAFE_MODE_PENDING | PSTATE_SAFE_MODE)) { PK_TRACE_DBG("START_STOP: PM_SUSP/Safe"); args->msg_cb.rc = PGPE_RC_PM_COMPLEX_SUSPEND_SAFE_MODE; - if(G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_SAFE_MODE_PENDING | PSTATE_SAFE_MODE)) { if (args->action == PGPE_ACTION_PSTATE_START) @@ -420,46 +423,58 @@ void p9_pgpe_process_start_stop() } p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; + } else { //If Start if (args->action == PGPE_ACTION_PSTATE_START) { - if(G_pgpe_pstate_record.pstatesStatus == PSTATE_INIT || G_pgpe_pstate_record.pstatesStatus == PSTATE_STOPPED) + if ((args->pmcr_owner == PMCR_OWNER_HOST) || + (args->pmcr_owner == PMCR_OWNER_OCC) || + (args->pmcr_owner == PMCR_OWNER_CHAR)) { - p9_pgpe_pstate_start(PSTATE_START_OCC_IPC); - args->msg_cb.rc = PGPE_RC_SUCCESS; - pk_semaphore_post(&G_pgpe_pstate_record.sem_actuate); + if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_INIT | PSTATE_STOPPED)) + { + p9_pgpe_pstate_start(PSTATE_START_OCC_IPC); + args->msg_cb.rc = PGPE_RC_SUCCESS; + pk_semaphore_post(&G_pgpe_pstate_record.sem_actuate); + } + else if (G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE) + { + p9_pgpe_pstate_set_pmcr_owner(args->pmcr_owner); + args->msg_cb.rc = PGPE_RC_SUCCESS; + } + + G_pgpe_optrace_data.word[0] = (args->pmcr_owner << 25 ) | + (1 << 24) | + (G_pgpe_pstate_record.psCurr.fields.glb << 16) | + (in32(OCB_QCSR) >> 16); + p9_pgpe_optrace(PRC_START_STOP); } - else if (G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE) + else { - PK_TRACE_DBG("START_STOP: PMCR OWNER Change to %d ", args->pmcr_owner); - p9_pgpe_pstate_set_pmcr_owner(args->pmcr_owner); - args->msg_cb.rc = PGPE_RC_SUCCESS; + args->msg_cb.rc = PGPE_RC_INVALID_PMCR_OWNER; + p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } - - G_pgpe_optrace_data.word[0] = (args->pmcr_owner << 25 ) | - (1 << 24) | - (G_pgpe_pstate_record.globalPSCurr << 16) | - (in32(OCB_QCSR) >> 16); - p9_pgpe_optrace(PRC_START_STOP); } else { - if(G_pgpe_pstate_record.pstatesStatus == PSTATE_INIT - || G_pgpe_pstate_record.pstatesStatus == PSTATE_STOPPED) + if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_INIT | PSTATE_STOPPED)) { PK_TRACE_DBG("START_STOP: Already Stopped"); args->msg_cb.rc = PGPE_RC_SUCCESS; G_pgpe_optrace_data.word[0] = PGPE_OP_PSTATE_STOP_IN_PSTATE_STOPPED; p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } else if (G_pgpe_pstate_record.pstatesStatus == PSTATE_ACTIVE) { p9_pgpe_pstate_stop(); args->msg_cb.rc = PGPE_RC_SUCCESS; - G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.globalPSCurr << 16) | + G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.psCurr.fields.glb << 16) | (in32(OCB_QCSR) >> 16); p9_pgpe_optrace(PRC_START_STOP); } @@ -472,6 +487,11 @@ void p9_pgpe_process_start_stop() G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_PSTATE_START_STOP].pending_ack = 0; G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_PSTATE_START_STOP].pending_processing = 0; p9_pgpe_optrace(ACK_START_STOP); + + if (bad_rc == 1) + { + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); + } } PK_TRACE_DBG("PTH: Start/Stop End"); @@ -485,7 +505,7 @@ void p9_pgpe_process_clip_updt() { PK_TRACE_DBG("PTH: Clip Updt Entry"); - uint32_t q, ack_now = 1; + uint32_t q, ack_now = 1, bad_rc = 0; ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_CLIP_UPDT].cmd; ipcmsg_clip_update_t* args = (ipcmsg_clip_update_t*)async_cmd->cmd_data; @@ -509,16 +529,16 @@ void p9_pgpe_process_clip_updt() (G_pgpe_pstate_record.psClipMin[5]); p9_pgpe_optrace(PRC_CLIP_UPDT); } - else if (G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPENDED || - G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPEND_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + else if (G_pgpe_pstate_record.pstatesStatus & (PSTATE_PM_SUSPENDED | + PSTATE_PM_SUSPEND_PENDING | + PSTATE_SAFE_MODE_PENDING | + PSTATE_SAFE_MODE)) { PK_TRACE_DBG("PTH: Clip Updt PMSUSP/Safe"); args->msg_cb.rc = PGPE_RC_PM_COMPLEX_SUSPEND_SAFE_MODE; - if(G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_SAFE_MODE_PENDING | + PSTATE_SAFE_MODE)) { G_pgpe_optrace_data.word[0] = PGPE_OP_CLIP_UPDT_IN_SAFE_MODE; } @@ -528,6 +548,7 @@ void p9_pgpe_process_clip_updt() } p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } else { @@ -545,7 +566,7 @@ void p9_pgpe_process_clip_updt() //We can't have max freq/voltage to be below safePstate, so just halt PGPE if(args->ps_val_clip_max[q] > G_pgpe_pstate_record.safePstate) { - PGPE_PANIC_AND_TRACE(PGPE_PMAX_RCV_GREATER_THAN_PSAFE); + PGPE_TRACE_AND_PANIC(PGPE_PMAX_RCV_GREATER_THAN_PSAFE); } if (G_pgpe_pstate_record.psClipMin[q] != args->ps_val_clip_max[q]) @@ -574,7 +595,7 @@ void p9_pgpe_process_clip_updt() //If CLIP_UPDT before Pstate Start, then ack now. Otherwise, ACK //after actuation - if (G_pgpe_pstate_record.pstatesStatus == PSTATE_INIT || G_pgpe_pstate_record.pstatesStatus == PSTATE_STOPPED) + if (G_pgpe_pstate_record.pstatesStatus & (PSTATE_INIT | PSTATE_STOPPED)) { args->msg_cb.rc = PGPE_RC_SUCCESS; } @@ -591,6 +612,11 @@ void p9_pgpe_process_clip_updt() G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_CLIP_UPDT].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_CLIP_UPDT].cmd, IPC_RC_SUCCESS); p9_pgpe_optrace(ACK_CLIP_UPDT); + + if (bad_rc == 1) + { + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); + } } PK_TRACE_DBG("PTH: Clip Upd Exit"); @@ -603,7 +629,7 @@ void p9_pgpe_process_wof_ctrl() { PK_TRACE_DBG("PTH: WOF Ctrl Enter"); - uint32_t ack_now = 1; + uint32_t ack_now = 1, bad_rc = 0; ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_WOF_CTRL].cmd; ipcmsg_wof_control_t* args = (ipcmsg_wof_control_t*)async_cmd->cmd_data; @@ -620,16 +646,13 @@ void p9_pgpe_process_wof_ctrl() (in32(OCB_QCSR) >> 16); p9_pgpe_optrace(PRC_WOF_CTRL); } - else if (G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPENDED || - G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPEND_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + else if (G_pgpe_pstate_record.pstatesStatus & ( PSTATE_PM_SUSPENDED | PSTATE_PM_SUSPEND_PENDING | + PSTATE_SAFE_MODE_PENDING | PSTATE_SAFE_MODE)) { PK_TRACE_DBG("PTH: WOF Ctrl PMSUSP/Safe"); args->msg_cb.rc = PGPE_RC_PM_COMPLEX_SUSPEND_SAFE_MODE; - if(G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_SAFE_MODE_PENDING | PSTATE_SAFE_MODE)) { G_pgpe_optrace_data.word[0] = PGPE_OP_WOF_CTRL_IN_SAFE_MODE; } @@ -639,13 +662,15 @@ void p9_pgpe_process_wof_ctrl() } p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } - else if(G_pgpe_pstate_record.pstatesStatus == PSTATE_INIT || G_pgpe_pstate_record.pstatesStatus == PSTATE_STOPPED) + else if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_INIT | PSTATE_STOPPED)) { PK_TRACE_DBG("PTH: WOF Ctrl PSStop/Init"); args->msg_cb.rc = PGPE_RC_PSTATES_NOT_STARTED; G_pgpe_optrace_data.word[0] = PGPE_OP_WOF_CTRL_IN_PSTATE_STOPPED; p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } else { @@ -655,7 +680,7 @@ void p9_pgpe_process_wof_ctrl() { if(G_pgpe_pstate_record.wofStatus == WOF_DISABLED) { - PK_TRACE_DBG("PTH: WOF Ctrl=ON,WOF_Enabled=0"); + PK_TRACE_INF("PTH: WOF Ctrl=ON,WOF_Enabled=0"); p9_pgpe_pstate_wof_ctrl(PGPE_ACTION_WOF_ON); ack_now = 0; //For WOF_ENABLE, we ACK after WOF_CLIP has been honored(actuate thread) @@ -668,16 +693,17 @@ void p9_pgpe_process_wof_ctrl() else { args->msg_cb.rc = PGPE_RC_SUCCESS; - PK_TRACE_DBG("PTH: WOF Ctrl=ON,WOF_Enabled=1"); + PK_TRACE_INF("PTH: WOF Ctrl=ON,WOF_Enabled=1"); G_pgpe_optrace_data.word[0] = PGPE_OP_WOF_CTRL_ENABLE_WHEN_ENABLED; p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } } else if (args->action == PGPE_ACTION_WOF_OFF) { if(G_pgpe_pstate_record.wofStatus == WOF_ENABLED) { - PK_TRACE_DBG("PTH: WOF Ctrl=OFF,WOF_Enabled=1"); + PK_TRACE_INF("PTH: WOF Ctrl=OFF,WOF_Enabled=1"); //Disable WOF, and we ACK to OCC below p9_pgpe_pstate_wof_ctrl(PGPE_ACTION_WOF_OFF); @@ -690,9 +716,10 @@ void p9_pgpe_process_wof_ctrl() else { args->msg_cb.rc = PGPE_RC_SUCCESS; - PK_TRACE_DBG("PTH: WOF Ctrl=OFF,WOF_Enabled=0"); + PK_TRACE_INF("PTH: WOF Ctrl=OFF,WOF_Enabled=0"); G_pgpe_optrace_data.word[0] = PGPE_OP_WOF_CTRL_DISABLE_WHEN_DISABLED; p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } } } @@ -702,6 +729,11 @@ void p9_pgpe_process_wof_ctrl() G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_WOF_CTRL].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_WOF_CTRL].cmd, IPC_RC_SUCCESS); p9_pgpe_optrace(ACK_WOF_CTRL); + + if (bad_rc == 1) + { + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); + } } PK_TRACE_DBG("PTH: WOF Ctrl Exit"); @@ -713,7 +745,7 @@ void p9_pgpe_process_wof_ctrl() void p9_pgpe_process_wof_vfrt() { PK_TRACE_DBG("PTH: WOF VFRT Enter"); - uint32_t ack_now = 1; + uint32_t ack_now = 1, bad_rc = 0; ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_WOF_VFRT].cmd; ipcmsg_wof_vfrt_t* args = (ipcmsg_wof_vfrt_t*)async_cmd->cmd_data; @@ -729,16 +761,13 @@ void p9_pgpe_process_wof_vfrt() G_pgpe_optrace_data.word[1] = 0; p9_pgpe_optrace(PRC_WOF_VFRT); } - else if (G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPENDED || - G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPEND_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + else if (G_pgpe_pstate_record.pstatesStatus & (PSTATE_PM_SUSPENDED | PSTATE_PM_SUSPEND_PENDING | + PSTATE_SAFE_MODE_PENDING | PSTATE_SAFE_MODE)) { PK_TRACE_DBG("PTH: WOF VFRT PMSUSP/Safe"); args->msg_cb.rc = PGPE_RC_PM_COMPLEX_SUSPEND_SAFE_MODE; - if(G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_SAFE_MODE_PENDING | PSTATE_SAFE_MODE)) { G_pgpe_optrace_data.word[0] = PGPE_OP_WOF_VFRT_IN_SAFE_MODE; } @@ -748,20 +777,23 @@ void p9_pgpe_process_wof_vfrt() } p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } - else if(G_pgpe_pstate_record.pstatesStatus == PSTATE_STOPPED || G_pgpe_pstate_record.pstatesStatus == PSTATE_INIT) + else if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_STOPPED | PSTATE_INIT)) { PK_TRACE_DBG("PTH: WOF VFRT PSStop/Init"); args->msg_cb.rc = PGPE_RC_PSTATES_NOT_STARTED; G_pgpe_optrace_data.word[0] = PGPE_OP_WOF_VFRT_IN_PSTATE_STOPPED; p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } else { if(args->homer_vfrt_ptr == NULL) { PK_TRACE_ERR("PTH: NULL VFRT Ptr"); - PGPE_PANIC_AND_TRACE(PGPE_NULL_VFRT_POINTER); + bad_rc = 1; + args->msg_cb.rc = PGPE_RC_NULL_VFRT_POINTER; } //Update VFRT pointer @@ -795,6 +827,11 @@ void p9_pgpe_process_wof_vfrt() G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_WOF_VFRT].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_WOF_VFRT].cmd, IPC_RC_SUCCESS); p9_pgpe_optrace(ACK_WOF_VFRT); + + if (bad_rc == 1) + { + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); + } } PK_TRACE_DBG("PTH: WOF VFRT Exit"); @@ -807,7 +844,7 @@ void p9_pgpe_process_set_pmcr_req() { PK_TRACE_DBG("PTH: Set PMCR Enter"); - uint32_t q, c; + uint32_t q, c, bad_rc = 0; ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SET_PMCR_REQ].cmd; ipcmsg_set_pmcr_t* args = (ipcmsg_set_pmcr_t*)async_cmd->cmd_data; @@ -818,13 +855,13 @@ void p9_pgpe_process_set_pmcr_req() PK_TRACE_DBG("PTH: Set PMCR Imme"); p9_pgpe_optrace(PRC_SET_PMCR); args->msg_cb.rc = PGPE_RC_SUCCESS; - G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.quadPSTarget[0] << 24) | - (G_pgpe_pstate_record.quadPSTarget[1] << 16) | - (G_pgpe_pstate_record.quadPSTarget[2] << 8) | - G_pgpe_pstate_record.quadPSTarget[3]; - G_pgpe_optrace_data.word[1] = (G_pgpe_pstate_record.quadPSTarget[4] << 24) | - (G_pgpe_pstate_record.quadPSTarget[5] << 16) | - G_pgpe_pstate_record.globalPSTarget << 8; + G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.psTarget.fields.quads[0] << 24) | + (G_pgpe_pstate_record.psTarget.fields.quads[1] << 16) | + (G_pgpe_pstate_record.psTarget.fields.quads[2] << 8) | + G_pgpe_pstate_record.psTarget.fields.quads[3]; + G_pgpe_optrace_data.word[1] = (G_pgpe_pstate_record.psTarget.fields.quads[4] << 24) | + (G_pgpe_pstate_record.psTarget.fields.quads[5] << 16) | + G_pgpe_pstate_record.psTarget.fields.glb << 8; p9_pgpe_optrace(PRC_SET_PMCR); } else if(G_pgpe_pstate_record.pmcrOwner != PMCR_OWNER_OCC) @@ -833,24 +870,23 @@ void p9_pgpe_process_set_pmcr_req() args->msg_cb.rc = PGPE_RC_OCC_NOT_PMCR_OWNER; G_pgpe_optrace_data.word[0] = PGPE_OP_SET_PMCR_AND_PMCR_OWNER_NOT_OCC; p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } - else if (G_pgpe_pstate_record.pstatesStatus == PSTATE_INIT || G_pgpe_pstate_record.pstatesStatus == PSTATE_STOPPED) + else if (G_pgpe_pstate_record.pstatesStatus & (PSTATE_INIT | PSTATE_STOPPED)) { PK_TRACE_DBG("PTH: Pstates !Started"); args->msg_cb.rc = PGPE_RC_PSTATES_NOT_STARTED; G_pgpe_optrace_data.word[0] = PGPE_OP_SET_PMCR_IN_PSTATE_STOPPED; p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } - else if (G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPENDED || - G_pgpe_pstate_record.pstatesStatus == PSTATE_PM_SUSPEND_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + else if (G_pgpe_pstate_record.pstatesStatus & (PSTATE_PM_SUSPENDED | PSTATE_PM_SUSPEND_PENDING | + PSTATE_SAFE_MODE_PENDING | PSTATE_SAFE_MODE)) { PK_TRACE_DBG("PTH: Set PMCR in PM_Susp/Safe"); args->msg_cb.rc = PGPE_RC_PM_COMPLEX_SUSPEND_SAFE_MODE; - if(G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE_PENDING || - G_pgpe_pstate_record.pstatesStatus == PSTATE_SAFE_MODE) + if(G_pgpe_pstate_record.pstatesStatus & (PSTATE_SAFE_MODE_PENDING | PSTATE_SAFE_MODE)) { G_pgpe_optrace_data.word[0] = PGPE_OP_SET_PMCR_IN_SAFE_MODE; } @@ -860,6 +896,7 @@ void p9_pgpe_process_set_pmcr_req() } p9_pgpe_optrace(UNEXPECTED_ERROR); + bad_rc = 1; } else { @@ -872,7 +909,7 @@ void p9_pgpe_process_set_pmcr_req() G_pgpe_pstate_record.coresPSRequest[c] = (args->pmcr[q] >> 48) & 0x00FF; } - PK_TRACE_DBG("PTH: coresPSReq: 0x%x", G_pgpe_pstate_record.coresPSRequest[q * CORES_PER_QUAD]); + PK_TRACE_INF("PTH: coresPSReq: 0x%x", G_pgpe_pstate_record.coresPSRequest[q * CORES_PER_QUAD]); } //PGPE Trace(PRC_SET_PMCR) @@ -882,7 +919,7 @@ void p9_pgpe_process_set_pmcr_req() G_pgpe_pstate_record.coresPSRequest[12]; G_pgpe_optrace_data.word[1] = (G_pgpe_pstate_record.coresPSRequest[16] << 24) | (G_pgpe_pstate_record.coresPSRequest[20] << 16) | - G_pgpe_pstate_record.globalPSCurr << 8; + G_pgpe_pstate_record.psCurr.fields.glb << 8; p9_pgpe_optrace(PRC_SET_PMCR); p9_pgpe_pstate_do_auction(); @@ -895,6 +932,11 @@ void p9_pgpe_process_set_pmcr_req() G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SET_PMCR_REQ].pending_ack = 0; ipc_send_rsp(G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_SET_PMCR_REQ].cmd, IPC_RC_SUCCESS); + if (bad_rc == 1) + { + PGPE_OPTIONAL_TRACE_AND_PANIC(PGPE_OCC_IPC_ACK_BAD_RC); + } + PK_TRACE_DBG("PTH: Set PMCR Exit"); } @@ -911,7 +953,8 @@ void p9_pgpe_process_registration() uint64_t value; pgpe_db0_start_ps_bcast_t db0_glb_bcast; pgpe_db0_clip_bcast_t db0_clip_bcast; - pgpe_db0_pstate_start_abort_t db0_pstate_start_abort; + db0_parms_t db0p; + pgpe_db0_pstate_register_done_t db0_pstate_register_done; //Save it for global bcast sync in case GlobalPSTarget is higher in //after doing auctions with just registered quads @@ -942,10 +985,10 @@ void p9_pgpe_process_registration() G_pgpe_pstate_record.pendQuadsRegisterReceive &= ~QUAD_MASK(q); G_pgpe_pstate_record.pendQuadsRegisterProcess &= ~QUAD_MASK(q); - PK_TRACE_DBG("PTH: Quad %d Registered. qActive=0x%x cActive=0x%x", q, G_pgpe_pstate_record.activeQuads, + PK_TRACE_INF("PTH: Quad %d Registration Processing. qActive=0x%x cActive=0x%x", q, G_pgpe_pstate_record.activeQuads, G_pgpe_pstate_record.activeDB); - G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.activeQuads << 24) | (G_pgpe_pstate_record.globalPSCurr << 16) + G_pgpe_optrace_data.word[0] = (G_pgpe_pstate_record.activeQuads << 24) | (G_pgpe_pstate_record.psCurr.fields.glb << 16) | (in32(OCB_QCSR) >> 16); p9_pgpe_optrace(PRC_PCB_T4); } @@ -963,15 +1006,16 @@ void p9_pgpe_process_registration() //to quads that were previously active. This will ensure that before frequency is moved //on just registered quad as a result of processing Pstate Start(below), the voltage is //correct. Also, quads that were already active will learn the new global pstate value. - if (G_pgpe_pstate_record.globalPSTarget < G_pgpe_pstate_record.globalPSCurr) + if (G_pgpe_pstate_record.psTarget.fields.glb < G_pgpe_pstate_record.psCurr.fields.glb) { //Interpolate TargetVoltage from GlobalPSTarget - uint32_t targetEVid = p9_pgpe_gppb_intp_vdd_from_ps(G_pgpe_pstate_record.globalPSTarget, VPD_PT_SET_BIASED_SYSP); + uint32_t targetEVid = p9_pgpe_gppb_intp_vdd_from_ps((uint8_t)(G_pgpe_pstate_record.psTarget.fields.glb), + VPD_PT_SET_BIASED_SYSP); //Move voltage by voltage step-size while(G_pgpe_pstate_record.eVidCurr != targetEVid) { - if ((G_pgpe_pstate_record.eVidCurr - targetEVid ) <= G_gppb->ext_vrm_step_size_mv) + if ((targetEVid - G_pgpe_pstate_record.eVidCurr) <= G_gppb->ext_vrm_step_size_mv) { G_pgpe_pstate_record.eVidNext = targetEVid; } @@ -984,37 +1028,21 @@ void p9_pgpe_process_registration() } //Set GlobalPSCurr and Next - G_pgpe_pstate_record.globalPSCurr = G_pgpe_pstate_record.globalPSTarget; - G_pgpe_pstate_record.globalPSNext = G_pgpe_pstate_record.globalPSTarget; + G_pgpe_pstate_record.psCurr.fields.glb = G_pgpe_pstate_record.psTarget.fields.glb; + G_pgpe_pstate_record.psNext.fields.glb = G_pgpe_pstate_record.psTarget.fields.glb; //Do globalbcast to sync up globalPS - db0_glb_bcast.value = 0; + db0_glb_bcast.value = G_pgpe_pstate_record.psNext.value; db0_glb_bcast.fields.msg_id = MSGID_DB0_GLOBAL_ACTUAL_BROADCAST; - db0_glb_bcast.fields.global_actual = G_pgpe_pstate_record.globalPSNext; - db0_glb_bcast.fields.quad0_ps = G_pgpe_pstate_record.quadPSNext[0]; - db0_glb_bcast.fields.quad1_ps = G_pgpe_pstate_record.quadPSNext[1]; - db0_glb_bcast.fields.quad2_ps = G_pgpe_pstate_record.quadPSNext[2]; - db0_glb_bcast.fields.quad3_ps = G_pgpe_pstate_record.quadPSNext[3]; - db0_glb_bcast.fields.quad4_ps = G_pgpe_pstate_record.quadPSNext[4]; - db0_glb_bcast.fields.quad5_ps = G_pgpe_pstate_record.quadPSNext[5]; - - p9_pgpe_send_db0(db0_glb_bcast.value, - oldActiveDB, - PGPE_DB0_MULTICAST, - PGPE_DB0_ACK_WAIT_CME, - oldActiveQuads); + db0p.db0val = db0_glb_bcast.value; + db0p.type = PGPE_DB0_TYPE_MULTICAST; + db0p.targetCores = oldActiveDB; + db0p.waitForAcks = PGPE_DB_ACK_WAIT_CME; + db0p.expectedAckFrom = oldActiveQuads; + db0p.expectedAckValue = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; + p9_pgpe_send_db0(db0p); } - //Send clip updates to all quads that are already registered - db0_clip_bcast.value = 0; - db0_clip_bcast.fields.msg_id = MSGID_DB0_CLIP_BROADCAST; - db0_clip_bcast.fields.clip_type = DB0_CLIP_BCAST_TYPE_PMIN; - db0_clip_bcast.fields.quad0_clip = G_pgpe_pstate_record.psClipMax[0]; - db0_clip_bcast.fields.quad1_clip = G_pgpe_pstate_record.psClipMax[1]; - db0_clip_bcast.fields.quad2_clip = G_pgpe_pstate_record.psClipMax[2]; - db0_clip_bcast.fields.quad3_clip = G_pgpe_pstate_record.psClipMax[3]; - db0_clip_bcast.fields.quad4_clip = G_pgpe_pstate_record.psClipMax[4]; - db0_clip_bcast.fields.quad5_clip = G_pgpe_pstate_record.psClipMax[5]; //Do setup for every quad that registered for (q = 0; q < MAX_QUADS; q++) @@ -1023,28 +1051,24 @@ void p9_pgpe_process_registration() { //Give Quad Manager CME control of DPLL through inter-ppm //SGPE sets up the DPLL_SEL bits before booting CME + //uint64_t safeDpll = G_gppb->dpll_pstate0_value - G_pgpe_pstate_record.safePstate; + //safeDpll = safeDpll << 52; GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QPMMR_OR, q), BIT64(26)); - uint32_t quadCoresVector = 0; - for (c = FIRST_CORE_FROM_QUAD(q); c < LAST_CORE_FROM_QUAD(q); c++) { if (G_pgpe_pstate_record.activeDB & CORE_MASK(c)) { unicastCoresVector |= CORE_MASK(c); - quadCoresVector |= CORE_MASK(c); } } - p9_pgpe_send_db0(db0_clip_bcast.value, quadCoresVector, PGPE_DB0_UNICAST, PGPE_DB0_ACK_SKIP, 0); - //Write CME_SCRATCH and PMSR0/1 registers if (qcsr.fields.ex_config & QUAD_EX0_MASK(q)) { //CME_Scratch GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SRTCH0, q, 0), value); value |= ((uint64_t)(MAX_QUADS - 1 - q) << 3) << 32; - value |= BIT64(CME_SCRATCH_DB0_PROCESSING_ENABLE); GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SRTCH0, q, 0), value); } @@ -1053,7 +1077,6 @@ void p9_pgpe_process_registration() //CME_Scratch GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SRTCH0, q, 1), value); value |= ((uint64_t)(MAX_QUADS - 1 - q) << 3) << 32; - value |= BIT64(CME_SCRATCH_DB0_PROCESSING_ENABLE); GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SRTCH0, q, 1), value); } @@ -1061,7 +1084,29 @@ void p9_pgpe_process_registration() } } - p9_pgpe_wait_cme_db_ack(quadAckExpect); + //Send Pstate Start DB0 to all quads that registered + db0_glb_bcast.value = G_pgpe_pstate_record.psTarget.value; + db0_glb_bcast.fields.msg_id = MSGID_DB0_START_PSTATE_BROADCAST; + db0p.db0val = db0_glb_bcast.value; + db0p.type = PGPE_DB0_TYPE_UNICAST; + db0p.targetCores = unicastCoresVector; + db0p.waitForAcks = PGPE_DB_ACK_WAIT_CME; + db0p.expectedAckFrom = quadAckExpect; + db0p.expectedAckValue = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; + p9_pgpe_send_db0(db0p); + + //Send clip updates to all quads that are already registered + db0_clip_bcast.value = 0; + db0_clip_bcast.fields.msg_id = MSGID_DB0_CLIP_BROADCAST; + db0_clip_bcast.fields.clip_type = DB0_CLIP_BCAST_TYPE_PMIN; + db0_clip_bcast.fields.quad0_clip = G_pgpe_pstate_record.psClipMax[0]; + db0_clip_bcast.fields.quad1_clip = G_pgpe_pstate_record.psClipMax[1]; + db0_clip_bcast.fields.quad2_clip = G_pgpe_pstate_record.psClipMax[2]; + db0_clip_bcast.fields.quad3_clip = G_pgpe_pstate_record.psClipMax[3]; + db0_clip_bcast.fields.quad4_clip = G_pgpe_pstate_record.psClipMax[4]; + db0_clip_bcast.fields.quad5_clip = G_pgpe_pstate_record.psClipMax[5]; + db0p.db0val = db0_clip_bcast.value; + p9_pgpe_send_db0(db0p); db0_clip_bcast.value = 0; db0_clip_bcast.fields.msg_id = MSGID_DB0_CLIP_BROADCAST; @@ -1072,32 +1117,24 @@ void p9_pgpe_process_registration() db0_clip_bcast.fields.quad3_clip = G_pgpe_pstate_record.psClipMin[3]; db0_clip_bcast.fields.quad4_clip = G_pgpe_pstate_record.psClipMin[4]; db0_clip_bcast.fields.quad5_clip = G_pgpe_pstate_record.psClipMin[5]; - p9_pgpe_send_db0(db0_clip_bcast.value, unicastCoresVector, PGPE_DB0_UNICAST, PGPE_DB0_ACK_WAIT_CME, quadAckExpect); - //Send Pstate Start DB0 to all quads that registered - db0_glb_bcast.value = 0; - db0_glb_bcast.fields.msg_id = MSGID_DB0_START_PSTATE_BROADCAST; - db0_glb_bcast.fields.global_actual = G_pgpe_pstate_record.globalPSTarget; - db0_glb_bcast.fields.quad0_ps = G_pgpe_pstate_record.quadPSTarget[0]; - db0_glb_bcast.fields.quad1_ps = G_pgpe_pstate_record.quadPSTarget[1]; - db0_glb_bcast.fields.quad2_ps = G_pgpe_pstate_record.quadPSTarget[2]; - db0_glb_bcast.fields.quad3_ps = G_pgpe_pstate_record.quadPSTarget[3]; - db0_glb_bcast.fields.quad4_ps = G_pgpe_pstate_record.quadPSTarget[4]; - db0_glb_bcast.fields.quad5_ps = G_pgpe_pstate_record.quadPSTarget[5]; - p9_pgpe_send_db0(db0_glb_bcast.value, unicastCoresVector, PGPE_DB0_UNICAST, PGPE_DB0_ACK_WAIT_CME, quadAckExpect); + db0p.db0val = db0_clip_bcast.value; + p9_pgpe_send_db0(db0p); + //Quads for (q = 0; q < MAX_QUADS; q++) { if (quadAckExpect & QUAD_MASK(q)) { - G_pgpe_pstate_record.quadPSCurr[q] = G_pgpe_pstate_record.quadPSTarget[q]; - G_pgpe_pstate_record.quadPSNext[q] = G_pgpe_pstate_record.quadPSTarget[q]; - p9_pgpe_pstate_updt_actual_quad(QUAD_MASK(q)); + G_pgpe_pstate_record.psCurr.fields.quads[q] = G_pgpe_pstate_record.psTarget.fields.quads[q]; + G_pgpe_pstate_record.psNext.fields.quads[q] = G_pgpe_pstate_record.psTarget.fields.quads[q]; } } + + p9_pgpe_pstate_updt_actual_quad(); } - //Send REGISTER_DONE if Pstates aren't active anymore + //Send if Pstates aren't active anymore, REGISTER_DONE else { for (q = 0; q < MAX_QUADS; q++) @@ -1120,21 +1157,36 @@ void p9_pgpe_process_registration() } } - db0_pstate_start_abort.value = 0; - db0_pstate_start_abort.fields.msg_id = MSGID_DB0_REGISTER_DONE; - p9_pgpe_send_db0(db0_pstate_start_abort.value, unicastCoresVector, PGPE_DB0_UNICAST, PGPE_DB0_ACK_WAIT_CME, - quadAckExpect); + db0_pstate_register_done.value = 0; + db0_pstate_register_done.fields.msg_id = MSGID_DB0_REGISTER_DONE; + db0p.db0val = db0_pstate_register_done.value; + db0p.type = PGPE_DB0_TYPE_UNICAST; + db0p.targetCores = unicastCoresVector; + db0p.waitForAcks = PGPE_DB_ACK_WAIT_CME; + db0p.expectedAckFrom = quadAckExpect; + db0p.expectedAckValue = MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK; + p9_pgpe_send_db0(db0p); } PK_TRACE_DBG("PTH: Register Exit"); } +// +//This is called when an ACK is received for CTRL_STOP_UPDT ipc +//sent by PGPE to SGPE. This handler is effectively a NOP and is there +//just to keep the IPC mechanism happy +// void p9_pgpe_process_ack_sgpe_ctrl_stop_updt() { G_pgpe_pstate_record.ipcPendTbl[IPC_ACK_CTRL_STOP_UPDT].pending_processing = 0; G_pgpe_pstate_record.ipcPendTbl[IPC_ACK_CTRL_STOP_UPDT].pending_ack = 0; } +// +//This is called when an ACK is received for SUSPEND_STOP ipc +//sent by PGPE to SGPE. This handler is effectively a NOP and is there +//just to keep the IPC mechanism happy +// void p9_pgpe_process_ack_sgpe_suspend_stop() { G_pgpe_pstate_record.ipcPendTbl[IPC_ACK_SUSPEND_STOP].pending_processing = 0; diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pgpe_panic_codes.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pgpe_panic_codes.h index 32573404..6955845a 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pgpe_panic_codes.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pgpe_panic_codes.h @@ -43,75 +43,75 @@ // The following are reserved for instance specific use. // Setup, Common Error or AVS BUS -PGPE_UIH_EIMR_STACK_UNDERFLOW = 0x1c00, -PGPE_UIH_EIMR_STACK_OVERFLOW = 0x1c01, -PGPE_UIH_PHANTOM_INTERRUPT = 0x1c02, -PGPE_AVS_READ_ONGOING_FLAG_TIMEOUT = 0x1c03, -PGPE_AVS_WRITE_ONGOING_FLAG_TIMEOUT = 0x1c04, -PGPE_AVS_INIT_DRIVE_IDLE_FRAME = 0x1c05, -PGPE_AVS_INIT_DRIVE_READ = 0x1c06, -PGPE_AVS_RESYNC_ERROR = 0x1c07, -//_UNUSED_1c08 = 0x1c08, -//_UNUSED_1c19 = 0x1c19, -//_UNUSED_1c0c = 0x1c0a, -PGPE_UNEXPECTED_OCC_FIR_IRQ = 0x1c0d, -PGPE_XSTOP_SGPE_IRQ = 0x1c1c, -//_UNUSED_1c1d = 0x1c1d, -PGPE_BAD_DD_LEVEL = 0x1c1e, -//_UNUSED_1c1f = 0x1c1f, +PGPE_UIH_EIMR_STACK_UNDERFLOW = 0x1c00, +PGPE_UIH_EIMR_STACK_OVERFLOW = 0x1c01, +PGPE_UIH_PHANTOM_INTERRUPT = 0x1c02, +PGPE_AVS_READ_ONGOING_FLAG_TIMEOUT = 0x1c03, +PGPE_AVS_WRITE_ONGOING_FLAG_TIMEOUT = 0x1c04, +PGPE_AVS_INIT_DRIVE_IDLE_FRAME = 0x1c05, +PGPE_AVS_INIT_DRIVE_READ = 0x1c06, +PGPE_AVS_RESYNC_ERROR = 0x1c07, +//_UNUSED_1c08 = 0x1c08, +PGPE_CME_FAULT = 0x1c09, +PGPE_PVREF_ERROR = 0x1c0a, +PGPE_OCC_FIR_IRQ = 0x1c0d, +PGPE_XSTOP_GPE2 = 0x1c1c, +PGPE_GPE3_ERROR = 0x1c1d, +PGPE_BAD_DD_LEVEL = 0x1c1e, +PGPE_OCC_HB_LOSS = 0x1c1f, -PGPE_CME_UNEXPECTED_REGISTRATION = 0x1d00, //Communication -PGPE_CME_UNEXPECTED_DB0_ACK = 0x1d01, -PGPE_OCC_IPC_RSP_BAD_RC = 0x1d02, -PGPE_SGPE_IPC_SEND_BAD_RC = 0x1d03, -PGPE_SGPE_SUSPEND_STOP_BAD_ACK = 0x1d04, -PGPE_SGPE_CTRL_STOP_UPDT_BAD_ACK = 0x1d05, -PGPE_CME_DB0_ERROR_ACK = 0x1d06, -//_UNUSED_1d07 = 0x1d07, -//_UNUSED_1d08 = 0x1d08, -//_UNUSED_1d09 = 0x1d09, -//_UNUSED_1d0a = 0x1d0a, -//_UNUSED_1d0d = 0x1d0d, -//_UNUSED_1d1c = 0x1d1c, -//_UNUSED_1d1d = 0x1d1d, -//_UNUSED_1d1e = 0x1d1e, -//_UNUSED_1d1f = 0x1d1f, +PGPE_CME_UNEXPECTED_REGISTRATION = 0x1d00, //Communication +PGPE_CME_UNEXPECTED_DB_ACK = 0x1d01, +PGPE_OCC_IPC_ACK_BAD_RC = 0x1d02, +PGPE_SGPE_IPC_ACK_BAD_RC = 0x1d03, +PGPE_SGPE_SUSPEND_STOP_BAD_ACK = 0x1d04, +PGPE_SGPE_CTRL_STOP_UPDT_BAD_ACK = 0x1d05, +PGPE_CME_DB_ERROR_ACK = 0x1d06, +PGPE_RESCLK_IDX_SEARCH_FAIL = 0x1d07, +PGPE_SGPE_IPC_SEND_FAIL = 0x1d08, +//_UNUSED_1d09 = 0x1d09, +//_UNUSED_1d0a = 0x1d0a, +//_UNUSED_1d0d = 0x1d0d, +//_UNUSED_1d1c = 0x1d1c, +//_UNUSED_1d1d = 0x1d1d, +//_UNUSED_1d1e = 0x1d1e, +//_UNUSED_1d1f = 0x1d1f, -PGPE_PM_SUSPEND_REQ_WHILE_STOPPED = 0x1e00, -PGPE_SAFE_MODE_REQ_WHILE_STOPPED = 0x1e01, -PGPE_NULL_VFRT_POINTER = 0x1e02, -PGPE_INVALID_PMCR_OWNER = 0x1e03, -PGPE_VOLTAGE_OUT_OF_BOUNDS = 0x1e04, -PGPE_SET_PMCR_TRAP_INJECT = 0x1e05, -PGPE_DROOP_AND_CORE_THRTLE_ENABLED = 0x1e06, -PGPE_INVALID_FREQ_UPDT = 0x1e07, -PGPE_PMAX_RCV_GREATER_THAN_PSAFE = 0x1e08, -//_UNUSED_1e07 = 0x1e07, -//_UNUSED_1e08 = 0x1e08, -//_UNUSED_1e09 = 0x1e09, -//_UNUSED_1e0a = 0x1e0a, -//_UNUSED_1e0d = 0x1e0d, -//_UNUSED_1e1c = 0x1e1c, -//_UNUSED_1e1d = 0x1e1d, -//_UNUSED_1e1e = 0x1e1e, -//_UNUSED_1e1f = 0x1e1f, +PGPE_PM_SUSPEND_REQ_WHILE_STOPPED = 0x1e00, +PGPE_SAFE_MODE_REQ_WHILE_STOPPED = 0x1e01, +PGPE_NULL_VFRT_POINTER = 0x1e02, +PGPE_INVALID_PMCR_OWNER = 0x1e03, +PGPE_VOLTAGE_OUT_OF_BOUNDS = 0x1e04, +PGPE_SET_PMCR_TRAP_INJECT = 0x1e05, +PGPE_DROOP_AND_CORE_THROTTLE_ENABLED = 0x1e06, +PGPE_INVALID_FREQ_UPDT = 0x1e07, +PGPE_PMAX_RCV_GREATER_THAN_PSAFE = 0x1e08, +//_UNUSED_1e07 = 0x1e07, +//_UNUSED_1e08 = 0x1e08, +//_UNUSED_1e09 = 0x1e09, +//_UNUSED_1e0a = 0x1e0a, +//_UNUSED_1e0d = 0x1e0d, +//_UNUSED_1e1c = 0x1e1c, +//_UNUSED_1e1d = 0x1e1d, +//_UNUSED_1e1e = 0x1e1e, +//_UNUSED_1e1f = 0x1e1f, -//_UNUSED_1f00 = 0x1f00, -//_UNUSED_1f01 = 0x1f01, -//_UNUSED_1f02 = 0x1f02, -//_UNUSED_1f03 = 0x1f03, -//_UNUSED_1f04 = 0x1f04, -//_UNUSED_1f05 = 0x1f05, -//_UNUSED_1f06 = 0x1f06, -//_UNUSED_1f07 = 0x1f07, -//_UNUSED_1f08 = 0x1f08, -//_UNUSED_1f09 = 0x1f09, -//_UNUSED_1f0a = 0x1f0a, -//_UNUSED_1f0d = 0x1f0d, -//_UNUSED_1f1c = 0x1f1c, -//_UNUSED_1f1d = 0x1f1d, -//_UNUSED_1f1e = 0x1f1e, -//_UNUSED_1f1f = 0x1f1f +//_UNUSED_1f00 = 0x1f00, +//_UNUSED_1f01 = 0x1f01, +//_UNUSED_1f02 = 0x1f02, +//_UNUSED_1f03 = 0x1f03, +//_UNUSED_1f04 = 0x1f04, +//_UNUSED_1f05 = 0x1f05, +//_UNUSED_1f06 = 0x1f06, +//_UNUSED_1f07 = 0x1f07, +//_UNUSED_1f08 = 0x1f08, +//_UNUSED_1f09 = 0x1f09, +//_UNUSED_1f0a = 0x1f0a, +//_UNUSED_1f0d = 0x1f0d, +//_UNUSED_1f1c = 0x1f1c, +//_UNUSED_1f1d = 0x1f1d, +//_UNUSED_1f1e = 0x1f1e, +//_UNUSED_1f1f = 0x1f1f #endif diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pk_app_cfg.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pk_app_cfg.h index bd250b47..c677b2e7 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pk_app_cfg.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pk_app_cfg.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -108,15 +108,7 @@ #define STATIC_IRQ_TABLE -/// About OCCHW_IRQ_PMC_PCB_INTR_TYPE1_PENDING : -/// This interrupt is used by the PGPE (GPE2) exclusively. Thus, rather than -/// defining the entire OCCHW_IRQ_ROUTES table here, and thus over-riding -/// the default routing table, I've updated the default table in -/// p9_code/include/occhw_irq_config.h . - /// Static configuration data for external interrupts: -/// Note, that these interrupts only have relevance for 405 IPC messaging and -/// xstop. The PCB type 1 interrupt is configured manually in the code.) /// /// IRQ#, TYPE, POLARITY, ENABLE /// @@ -124,8 +116,10 @@ OCCHW_IRQ_OCC_ERROR OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED \ OCCHW_IRQ_GPE3_HALT OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED \ OCCHW_IRQ_CHECK_STOP_GPE2 OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED \ + OCCHW_IRQ_IVRM_PVREF_ERROR OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED \ OCCHW_IRQ_IPI2_HI_PRIORITY OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED \ OCCHW_IRQ_IPI2_LO_PRIORITY OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED \ - OCCHW_IRQ_PMC_PCB_INTR_TYPE1_PENDING OCCHW_IRQ_TYPE_LEVEL OCCHW_IRQ_POLARITY_HI OCCHW_IRQ_MASKED \ - OCCHW_IRQ_PMC_PCB_INTR_TYPE4_PENDING OCCHW_IRQ_TYPE_LEVEL OCCHW_IRQ_POLARITY_HI OCCHW_IRQ_MASKED + OCCHW_IRQ_PMC_PCB_INTR_TYPE1_PENDING OCCHW_IRQ_TYPE_LEVEL OCCHW_IRQ_POLARITY_HI OCCHW_IRQ_MASKED \ + OCCHW_IRQ_PMC_PCB_INTR_TYPE4_PENDING OCCHW_IRQ_TYPE_LEVEL OCCHW_IRQ_POLARITY_HI OCCHW_IRQ_MASKED \ + OCCHW_IRQ_PMC_PCB_INTR_TYPE5_PENDING OCCHW_IRQ_TYPE_LEVEL OCCHW_IRQ_POLARITY_HI OCCHW_IRQ_MASKED #endif /*__PK_APP_CFG_H__*/ diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk index 8e3d002f..6e8376bf 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk @@ -5,7 +5,7 @@ # # OpenPOWER HCODE Project # -# COPYRIGHT 2017 +# COPYRIGHT 2017,2018 # [+] International Business Machines Corp. # # @@ -79,7 +79,7 @@ $(IMAGE)_TRACE_HASH_PREFIX := $(shell echo $(IMAGE) | md5sum | cut -c1-4 \ # Options for PK_TRACE -PSTATE_COMMONFLAGS+= -DPK_TRACE_LEVEL=2 +PSTATE_COMMONFLAGS+= -DPK_TRACE_LEVEL=1 PSTATE_COMMONFLAGS+= -DPK_TRACE_TIMER_OUTPUT=0 diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk index daa7cf5a..f7965d8f 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk @@ -5,7 +5,7 @@ # # OpenPOWER HCODE Project # -# COPYRIGHT 2016,2017 +# COPYRIGHT 2016,2018 # [+] International Business Machines Corp. # # @@ -81,7 +81,7 @@ $(IMAGE)_TRACE_HASH_PREFIX := $(shell echo $(IMAGE) | md5sum | cut -c1-4 \ | xargs -i printf "%d" 0x{}) # Options for PK_TRACE -$(IMAGE)_COMMONFLAGS+= -DPK_TRACE_LEVEL=2 +$(IMAGE)_COMMONFLAGS+= -DPK_TRACE_LEVEL=1 $(IMAGE)_COMMONFLAGS+= -DPK_TRACE_TIMER_OUTPUT=0 diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/topfiles.mk b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/topfiles.mk index b1c64228..e8923209 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/topfiles.mk +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/topfiles.mk @@ -5,7 +5,7 @@ # # OpenPOWER HCODE Project # -# COPYRIGHT 2015,2017 +# COPYRIGHT 2015,2018 # [+] International Business Machines Corp. # # @@ -28,7 +28,6 @@ TOP-C-SOURCES = p9_pgpe_pstate.c \ p9_pgpe_irq.c \ p9_pgpe_fit.c \ avs_driver.c \ - p9_pgpe_boot_temp.c \ p9_pgpe_gppb.c \ p9_pgpe_gen_pstate_info.c \ p9_pgpe_header.c \ 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 30b4631a..97010f62 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 @@ -271,7 +271,7 @@ void p9_sgpe_ipc_pgpe_suspend_stop(ipc_msg_t* cmd, void* arg) { G_sgpe_stop_record.wof.suspend_cmd = cmd; - g_oimr_override |= (BITS64(47, 2) | BITS64(50, 2)); + g_oimr_override |= (BIT64(45) | BITS64(47, 2) | BIT64(51)); ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)(G_sgpe_stop_record.wof.suspend_cmd); diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.c index f61cccb8..06b3464a 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -90,7 +90,7 @@ const uint64_t ext_irq_vectors_sgpe[NUM_EXT_IRQ_PRTY_LEVELS][2] = IRQ_VEC_PRTY7_SGPE }, { - IRQ_VEC_PRTY4_SGPE, /* 4: IDX_PRTY_LVL_PIG_TYPE5 */ + IRQ_VEC_PRTY4_SGPE, /* 4: IDX_PRTY_LVL_PIG_TYPE0 */ IRQ_VEC_PRTY4_SGPE | IRQ_VEC_PRTY5_SGPE | IRQ_VEC_PRTY6_SGPE | 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 a417c7bc..8dd4771d 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 @@ -51,7 +51,7 @@ #define IDX_PRTY_LVL_IPI3_HIGH 1 #define IDX_PRTY_LVL_PIG_TYPE2 2 #define IDX_PRTY_LVL_PIG_TYPE6 3 -#define IDX_PRTY_LVL_PIG_TYPE5 4 +#define IDX_PRTY_LVL_PIG_TYPE0 4 #define IDX_PRTY_LVL_PIG_TYPE3 5 #define IDX_PRTY_LVL_IPI3_LOW 6 #define IDX_PRTY_LVL_DISABLED 7 @@ -68,8 +68,8 @@ extern const uint64_t ext_irq_vectors_sgpe[NUM_EXT_IRQ_PRTY_LEVELS][2]; #define IRQ_VEC_PRTY2_SGPE (uint64_t)(0x0000000000010000) // Group3: pig_type6 #define IRQ_VEC_PRTY3_SGPE (uint64_t)(0x0000000000001000) -// Group4: pig_type5 -#define IRQ_VEC_PRTY4_SGPE (uint64_t)(0x0000000000002000) +// Group4: pig_type0 +#define IRQ_VEC_PRTY4_SGPE (uint64_t)(0x0000000000040000) // Group5: pig_type3 #define IRQ_VEC_PRTY5_SGPE (uint64_t)(0x0000000000008000) // Group6: ipi3_low @@ -77,7 +77,7 @@ extern const uint64_t ext_irq_vectors_sgpe[NUM_EXT_IRQ_PRTY_LEVELS][2]; // Group7: We should never detect these #define OVERRIDE_OTHER_ENGINES_IRQS 0 #if OVERRIDE_OTHER_ENGINES_IRQS == 1 - #define IRQ_VEC_PRTY7_SGPE (uint64_t)(0xFEFF7FF7FFFE4FFB) // Other instances' IRQs + #define IRQ_VEC_PRTY7_SGPE (uint64_t)(0xFEFF7FF7FFFA6FFB) // Other instances' IRQs #else #define IRQ_VEC_PRTY7_SGPE (uint64_t)(0x0000000000000000) // Other instances' IRQs #endif 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 da0edbfc..873cf238 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,12 +74,12 @@ IRQ_HANDLER_DEFAULT //OCCHW_IRQ_STRM2_PULL IRQ_HANDLER_DEFAULT //OCCHW_IRQ_STRM2_PUSH 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(p9_sgpe_pig_type0_handler, 0) //OCCHW_IRQ_PMC_PCB_INTR_TYPE0_PENDING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE1_PENDING IRQ_HANDLER(p9_sgpe_pig_type2_handler, 0) //OCCHW_IRQ_PMC_PCB_INTR_TYPE2_PENDING IRQ_HANDLER(p9_sgpe_pig_type3_handler, 0) //OCCHW_IRQ_PMC_PCB_INTR_TYPE3_PENDING IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE4_PENDING -IRQ_HANDLER(p9_sgpe_pig_type5_handler, 0) //OCCHW_IRQ_PMC_PCB_INTR_TYPE5_PENDING +IRQ_HANDLER_DEFAULT //OCCHW_IRQ_PMC_PCB_INTR_TYPE5_PENDING IRQ_HANDLER(p9_sgpe_pig_type6_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 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 b55abfd2..23f008c3 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 @@ -398,9 +398,9 @@ void p9_sgpe_stop_suspend_all_cmes(); void p9_sgpe_fit_handler(); void p9_sgpe_pgpe_halt_handler(void*, PkIrqId); void p9_sgpe_checkstop_handler(void*, PkIrqId); +void p9_sgpe_pig_type0_handler(void*, PkIrqId); void p9_sgpe_pig_type2_handler(void*, PkIrqId); 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); diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h index 3e083da2..2840e85c 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -40,7 +40,7 @@ enum SGPE_SE_MARKS ENDSCOPE_STOP_ENTRY = 0x18, STOP_PIG_TYPE2_HANDLER = 0x20, STOP_PIG_TYPE3_HANDLER = 0x28, - STOP_PIG_TYPE5_HANDLER = 0x30, + STOP_PIG_TYPE0_HANDLER = 0x30, STOP_PIG_TYPE6_HANDLER = 0x38, SE_LESSTHAN8_DONE = 0x68, SE_STOP_L2_CLKS = 0xe0, @@ -67,7 +67,7 @@ const std::vector<SGPE_SE_MARKS> MARKS = ENDSCOPE_STOP_ENTRY, STOP_PIG_TYPE2_HANDLER, STOP_PIG_TYPE3_HANDLER, - STOP_PIG_TYPE5_HANDLER, + STOP_PIG_TYPE0_HANDLER, STOP_PIG_TYPE6_HANDLER, SE_LESSTHAN8_DONE, SE_STOP_L2_CLKS, @@ -90,6 +90,7 @@ const std::map<SGPE_SE_MARKS, std::string> mMARKS = boost::assign::map_list_of (ENDSCOPE_STOP_ENTRY, "ENDSCOPE_STOP_ENTRY") (STOP_PIG_TYPE2_HANDLER, "STOP_PIG_TYPE2_HANDLER") (STOP_PIG_TYPE3_HANDLER, "STOP_PIG_TYPE3_HANDLER") + (STOP_PIG_TYPE0_HANDLER, "STOP_PIG_TYPE0_HANDLER") (STOP_PIG_TYPE6_HANDLER, "STOP_PIG_TYPE6_HANDLER") (SE_LESSTHAN8_DONE, "SE_LESSTHAN8_DONE") (SE_STOP_L2_CLKS, "SE_STOP_L2_CLKS") 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 078bd132..5c702d54 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 @@ -53,7 +53,6 @@ p9_sgpe_stop_entry() uint64_t local_xstop = 0; data64_t scom_data = {0}; data64_t temp_data = {0}; - uint32_t flg2_data = 0; #if HW386311_NDD1_PBIE_RW_PTR_STOP11_FIX uint32_t spin = 0; #endif @@ -70,9 +69,7 @@ p9_sgpe_stop_entry() MARK_TAG(BEGINSCOPE_STOP_ENTRY, 0) //================================ - flg2_data = in32(OCB_OCCFLG2); - - if( flg2_data & SGPE_HCODE_ERR_INJ_BIT ) + if( in32(OCB_OCCFLG2) & BIT32(OCCFLG2_SGPE_HCODE_STOP_REQ_ERR_INJ)) { PK_TRACE_ERR("SGPE STOP ENTRY ERROR INJECT TRAP"); PK_PANIC(SGPE_STOP_ENTRY_TRAP_INJECT); 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 c0ca7e34..7c9ff02c 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 @@ -333,7 +333,6 @@ p9_sgpe_stop_exit() uint32_t ex_index = 0; uint32_t ec_index = 0; data64_t scom_data = {0}; - uint32_t flg2_data = 0; #if !STOP_PRIME ocb_ccsr_t ccsr = {0}; uint32_t cme_flags = 0; @@ -365,9 +364,7 @@ p9_sgpe_stop_exit() G_sgpe_stop_record.group.ex01[4] = 0; G_sgpe_stop_record.group.ex01[5] = 0; - flg2_data = in32(OCB_OCCFLG2); - - if( flg2_data & SGPE_HCODE_ERR_INJ_BIT ) + if(in32(OCB_OCCFLG2) & BIT32(OCCFLG2_SGPE_HCODE_STOP_REQ_ERR_INJ)) { PK_TRACE_ERR("SGPE STOP EXIT ERROR INJECT TRAP"); PK_PANIC(SGPE_STOP_EXIT_TRAP_INJECT); @@ -924,10 +921,7 @@ p9_sgpe_stop_exit() cme_flags |= BIT32(CME_FLAGS_QMGR_MASTER); } - if ((in32(OCB_OCCS2) & BIT32(PGPE_ACTIVE)) && (in32(OCB_OCCS2) & BIT32(PGPE_PSTATE_PROTOCOL_ACTIVE))) - { - cme_flags |= BIT32(CME_FLAGS_WAIT_ON_PSTATE_START); - } + #if NIMBUS_DD_LEVEL != 10 @@ -966,6 +960,11 @@ p9_sgpe_stop_exit() #endif + if ((in32(OCB_OCCS2) & BIT32(PGPE_ACTIVE)) && (in32(OCB_OCCS2) & BIT32(PGPE_PSTATE_PROTOCOL_ACTIVE))) + { + GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CSAR_OR, (ec_index + cloop)), + BIT64(CPPM_CSAR_ENABLE_PSTATE_REGISTRATION_INTERLOCK)); + } } } diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_init.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_init.c index b44be78d..a90e0eb3 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_init.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_init.c @@ -79,6 +79,17 @@ void p9_sgpe_stop_cme_scominit(uint32_t quad, uint32_t cme, uint32_t cme_flags) GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_CSCR_CLR, quad, cme), BITS64(47, 13)); GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_CSCR_OR, quad, cme), BIT64(1)); + //CME_LFIR[0,1,2,3,4] should generate CME PCB Error Packet(type5 owned by PGPE) + //(1,0,0)(Act0,Act1,Mask) = CME PCB Error Packet + PK_TRACE("Setup CME FIR Act0/Act1/Mask for CME_LFIR[0,1,2,3,4]") + GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LFIRACT0, quad, cme), scom_data.value); + scom_data.value |= BITS64(0, 5); + GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LFIRACT0, quad, cme), scom_data.value); + GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LFIRACT1, quad, cme), scom_data.value); + scom_data.value &= ~BITS64(0, 5); + GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LFIRACT1, quad, cme), scom_data.value); + GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LFIRMASK_AND, quad, cme), ~BITS64(0, 5)); + PK_TRACE("Allow the CME to access the PCB Slave NET_CTRL registers"); // check core partial good @@ -501,10 +512,7 @@ p9_sgpe_stop_init() cme_flags |= BIT32(CME_FLAGS_QMGR_MASTER); } - if ((in32(OCB_OCCS2) & BIT32(PGPE_ACTIVE)) && (in32(OCB_OCCS2) & BIT32(PGPE_PSTATE_PROTOCOL_ACTIVE))) - { - cme_flags |= BIT32(CME_FLAGS_WAIT_ON_PSTATE_START); - } + PK_TRACE_DBG("CME%d%d_FLAGS :%x", qloop, xloop, cme_flags); p9_sgpe_stop_cme_scominit(qloop, xloop, cme_flags); @@ -552,6 +560,11 @@ p9_sgpe_stop_init() GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB2, cindex), 0); GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB3, cindex), 0); + if ((in32(OCB_OCCS2) & BIT32(PGPE_ACTIVE)) && (in32(OCB_OCCS2) & BIT32(PGPE_PSTATE_PROTOCOL_ACTIVE))) + { + GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CSAR_OR, cindex), BIT64(CPPM_CSAR_ENABLE_PSTATE_REGISTRATION_INTERLOCK)); + } + if ((G_sgpe_stop_record.state[qloop].cme_flags & cmask) && (G_sgpe_stop_record.state[qloop].cme_flags & (cmask << 4))) { @@ -622,13 +635,13 @@ p9_sgpe_stop_init() out32(OCB_OISR0_CLR, (BIT32(8) | BIT32(16))); out32(OCB_OIMR0_CLR, (BIT32(8) | BIT32(16))); - PK_TRACE_INF("Setup: Clear and Unmask Type 2,3,5,6 and ipi_lo_3 interrupts"); - out32(OCB_OISR1_CLR, (BITS32(15, 2) | BITS32(18, 2) | BIT32(29))); + PK_TRACE_INF("Setup: Clear and Unmask Type 0, 2,3,6 and ipi_lo_3 interrupts"); + out32(OCB_OISR1_CLR, (BIT32(13) | BITS32(15, 2) | BIT32(19) | BIT32(29))); + out32(OCB_OPITNPRA_CLR(0), BITS32(0, 24)); out32(OCB_OPITNPRA_CLR(2), BITS32(0, 24)); out32(OCB_OPITNPRA_CLR(3), BITS32(0, 24)); - out32(OCB_OPITNPRA_CLR(5), BITS32(0, 24)); out32(OCB_OPIT6PRB_CLR, BITS32(0, 6)); - out32(OCB_OIMR1_CLR, (BITS32(15, 2) | BITS32(18, 2) | BIT32(29))); + out32(OCB_OIMR1_CLR, BIT32(13) | (BITS32(15, 2) | BIT32(19) | BIT32(29))); //-------------------------------------------------------------------------- // SGPE Init Completed 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 39bf2efc..18fa12ac 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 @@ -79,7 +79,7 @@ p9_sgpe_fit_handler() PK_TRACE("FIT: Handler Fired"); uint32_t tpending = in32(OCB_OPITNPRA(PIG_TYPE3)) | - in32(OCB_OPITNPRA(PIG_TYPE5)) | + in32(OCB_OPITNPRA(PIG_TYPE0)) | in32(OCB_OPIT6PRB); // reset counter if current processing stop8+ @@ -113,16 +113,13 @@ p9_sgpe_pgpe_halt_handler(void* arg, PkIrqId irq) { PkMachineContext ctx; - PK_TRACE_INF("WARNING: PGPE Has Halted"); - PK_OPTIONAL_DEBUG_HALT(SGPE_PGPE_HALT_DETECTED); + PK_TRACE_INF("WARNING: PGPE Halted Due to Error"); + PK_OPTIONAL_DEBUG_HALT(SGPE_PGPE_ERROR_DETECTED); out32(OCB_OISR0_CLR, BIT32(7)); G_sgpe_stop_record.wof.update_pgpe = IPC_SGPE_PGPE_UPDATE_PGPE_HALTED; - if (in32(OCB_OCCFLG2) & BIT32(STOP_RECOVERY_TRIGGER_ENABLE)) - { - p9_stop_recovery_trigger(); - } + p9_stop_recovery_trigger(); pk_irq_vec_restore(&ctx); } @@ -141,176 +138,6 @@ p9_sgpe_checkstop_handler(void* arg, PkIrqId irq) -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}; - - // 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) - { - 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; - } - } - - cindex = (qloop << 2) + cloop; - - 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; - -#if NIMBUS_DD_LEVEL != 10 - - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1, cindex), scom_data.value); - -#else - - p9_dd1_db_unicast_wr(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1, cindex), scom_data.value); - -#endif - - } - } - - return req_list; -} - - - -void -p9_sgpe_ipi3_low_handler(void* arg, PkIrqId irq) -{ - 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 - 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[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++) - { - 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(5); - - if (action & BIT32(4)) - { - 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(5)); - } - - // target quad is to participate block/unblock entry - if (scom_data.words.upper & BIT32(11)) - { - action = action | BIT32(6); - - if (action & BIT32(4)) - { - 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(6)); - } - - // if this quad participates either entry/exit for block/unlock - // send msg; otherwise skip the quad - if (action & BITS32(5, 2)) - { - 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; - } - } - } - } - - pk_irq_vec_restore(&ctx); -} - - - // PCB Interrupt Type2 // Payload // 0 - set = Hardware Exit | unset = Firmware Stop @@ -449,48 +276,11 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type) } else { - cpayload = in32(OCB_OPIT5CN(cindex)); + cpayload = in32(OCB_OPIT0CN(cindex)); } - PK_TRACE_INF("Core[%d] sent PIG Type[%d] with Payload [%x]", cindex, type, cpayload); - if (type == PIG_TYPE5) - { - -#if DISABLE_STOP8 - - if ((cpayload != TYPE5_PAYLOAD_EXIT_RCLK) && - (cpayload != (TYPE5_PAYLOAD_ENTRY_RCLK | STOP_LEVEL_11))) - { - -#endif - - // Errors detected by the CME for any reason (STOP or Pstate) - // will cause the CME to halt. The CME halt is communicated via - // a PCB Interrupt Type 5 to SGPE. SGPE will, in turn, set OCC - // LFIR[cme_error_notify] (2) as an FFDC marker for this type of error. - GPE_PUTSCOM(OCB_OCCLFIR_OR, BIT64(2)); - - if (cpayload == TYPE5_PAYLOAD_CME_ERROR) - { - PK_TRACE_ERR("ERROR: CME Halt Due to Error"); - PK_PANIC(SGPE_PIG_TYPE5_CME_ERROR); - } - else - { - PK_TRACE_ERR("ERROR: Undefined Type5 Payload"); - PK_PANIC(SGPE_PIG_TYPE5_PAYLOAD_INVALID); - } - -#if DISABLE_STOP8 - - } - -#endif - - } - // if not hardware pig and is an suspend ack pig if ((type == PIG_TYPE3) && ((~cpayload) & TYPE2_PAYLOAD_HARDWARE_WAKEUP) && @@ -544,7 +334,7 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type) // block entry/exit/both if (cpayload & TYPE2_PAYLOAD_SUSPEND_ACTION_MASK) { - G_sgpe_stop_record.group.cack[block_index] |= BIT32(cloop); + G_sgpe_stop_record.group.cack[block_index] |= BIT32(cindex); if (G_sgpe_stop_record.group.cack[block_index] == G_sgpe_stop_record.group.creq[block_index]) @@ -555,7 +345,7 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type) // unblock entry/exit/both else { - G_sgpe_stop_record.group.cack[block_index] |= BIT32(cloop); + G_sgpe_stop_record.group.cack[block_index] |= BIT32(cindex); if (G_sgpe_stop_record.group.cack[block_index] == G_sgpe_stop_record.group.creq[block_index]) @@ -636,7 +426,7 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type) (already handoff cme by other wakeup"); } // otherwise PPM shouldnt send duplicate pig if wakeup is present - // also not suppose to handoff to cme if resclk is not enabled before(type5) + // also not suppose to handoff to cme if resclk is not enabled before(type0) else { PK_TRACE_INF("ERROR: Received Phantom Hardware Type%d Wakeup PIG \ @@ -661,7 +451,7 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type) #if DISABLE_STOP8 // Priority of Processing Exit Requests - // 1) Receive PIG Type5 with Rclk Exit encoding, aka + // 1) Receive PIG Type0 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 @@ -669,17 +459,17 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type) // 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 + // if it was Type0 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 + // if it was Type0 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_TYPE0) && (cpayload == TYPE0_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); @@ -799,7 +589,7 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type) #if DISABLE_STOP8 // Priority of Processing Entry Requests - // 1) Receive PIG Type5 with Rclk Entry encoding, aka Resonant Clock Disable completed + // 1) Receive PIG Type0 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 @@ -814,8 +604,8 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type) // Quad-Manager completed the resonant clock disable, proceed stop11 entry // block entry protocol is checked in the entry code instead of here below - if ((type == PIG_TYPE5) && - (cpayload == (TYPE5_PAYLOAD_ENTRY_RCLK | STOP_LEVEL_11))) + if ((type == PIG_TYPE0) && + (cpayload == (TYPE0_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)); @@ -967,6 +757,12 @@ p9_sgpe_pig_cpayload_parser(const uint32_t type) //================================================ } } + + if (type == PIG_TYPE2) + { + G_sgpe_stop_record.group.core[VECTOR_PIGX] = 0; + G_sgpe_stop_record.group.core[VECTOR_PIGE] = 0; + } } @@ -981,24 +777,29 @@ p9_sgpe_pig_thread_lanucher() G_sgpe_stop_record.group.core[VECTOR_EXIT] = 0; // Taking Stop8/11 Actions if any - if (G_sgpe_stop_record.group.core[VECTOR_PIGX] || + if (G_sgpe_stop_record.group.qswu[VECTOR_EXIT] || + G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] || + G_sgpe_stop_record.group.core[VECTOR_PIGX] || G_sgpe_stop_record.group.core[VECTOR_PIGE] || (G_sgpe_stop_record.group.quad[VECTOR_RCLKE] & BITS32(RCLK_DIS_DONE_OFFSET, 6))) { - // block both type3 and type5, 6 + // block both type3, type0, type6 // so another doesnt interrupt until next round - out32(OCB_OIMR1_OR, (BIT32(16) | BITS32(18, 2))); - g_oimr_override |= (BIT64(48) | BITS64(50, 2)); + out32(OCB_OIMR1_OR, (BIT32(13) | BIT32(16) | BIT32(19))); + g_oimr_override |= (BIT64(45) | BIT64(48) | BIT64(51)); - if (G_sgpe_stop_record.group.core[VECTOR_PIGX]) + if ((G_sgpe_stop_record.group.core[VECTOR_PIGX]) || + (G_sgpe_stop_record.group.qswu[VECTOR_EXIT])) { PK_TRACE_INF("Unblock Exit Thread"); G_sgpe_stop_record.group.core[VECTOR_EXIT] = G_sgpe_stop_record.group.core[VECTOR_PIGX]; + G_sgpe_stop_record.group.core[VECTOR_PIGX] = 0; pk_semaphore_post(&(G_sgpe_stop_record.sem[1])); } - if ((G_sgpe_stop_record.group.core[VECTOR_PIGE]) || + if ((G_sgpe_stop_record.group.qswu[VECTOR_ENTRY]) || + (G_sgpe_stop_record.group.core[VECTOR_PIGE]) || (G_sgpe_stop_record.group.quad[VECTOR_RCLKE] & BITS32(RCLK_DIS_DONE_OFFSET, 6) & (~(G_sgpe_stop_record.group.quad[VECTOR_BLOCKE] >> 16)))) { @@ -1006,6 +807,7 @@ p9_sgpe_pig_thread_lanucher() G_sgpe_stop_record.fit.entry_pending = 1; G_sgpe_stop_record.group.core[VECTOR_ENTRY] = G_sgpe_stop_record.group.core[VECTOR_PIGE]; + G_sgpe_stop_record.group.core[VECTOR_PIGE] = 0; pk_semaphore_post(&(G_sgpe_stop_record.sem[0])); } } @@ -1019,6 +821,230 @@ p9_sgpe_pig_thread_lanucher() +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}; + + // 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) + { + 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; + } + } + + cindex = (qloop << 2) + cloop; + + 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; + +#if NIMBUS_DD_LEVEL != 10 + + GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1, cindex), scom_data.value); + +#else + + p9_dd1_db_unicast_wr(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1, cindex), scom_data.value); + +#endif + + } + } + + return req_list; +} + + + +void +p9_sgpe_ipi3_low_handler(void* arg, PkIrqId irq) +{ + uint32_t req_list = 0; + uint32_t qloop = 0; + uint32_t action = 0; + uint32_t occflg = in32(OCB_OCCFLG) & BITS32(SGPE_IGNORE_STOP_CONTROL, 4); + data64_t scom_data = {0}; + + PK_TRACE_INF("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(SGPE_IGNORE_STOP_ACTION))) > BIT32(SGPE_IGNORE_STOP_CONTROL)) + { + // 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(SGPE_IGNORE_STOP_CONTROL))) << 6); + + if (occflg & BIT32(SGPE_IGNORE_STOP_EXITS)) + { + G_sgpe_stop_record.group.creq[VECTOR_BLOCKX] = 0; + G_sgpe_stop_record.group.cack[VECTOR_BLOCKX] = 0; + } + + if (occflg & BIT32(SGPE_IGNORE_STOP_ENTRIES)) + { + 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++) + { + 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(QPPM_QCCR_IGNORE_QUAD_STOP_EXITS)) + { + action = action | BIT32(5); + + if (action & BIT32(4)) + { + 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(5)); + } + + // target quad is to participate block/unblock entry + if (scom_data.words.upper & BIT32(QPPM_QCCR_IGNORE_QUAD_STOP_ENTRIES)) + { + action = action | BIT32(6); + + if (action & BIT32(4)) + { + 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(6)); + } + + // if this quad participates either entry/exit for block/unlock + // send msg; otherwise skip the quad + if (action & BITS32(5, 2)) + { + req_list = p9_sgpe_stop_suspend_db1_cme(qloop, action); + + if (action & BIT32(5)) + { + G_sgpe_stop_record.group.creq[VECTOR_BLOCKX] |= req_list; + } + + if (action & BIT32(6)) + { + G_sgpe_stop_record.group.creq[VECTOR_BLOCKE] |= req_list; + } + } + } + + if ((occflg & BIT32(SGPE_IGNORE_STOP_EXITS)) && + (G_sgpe_stop_record.group.creq[VECTOR_BLOCKX] == 0)) + { + if (!(occflg & BIT32(SGPE_IGNORE_STOP_ACTION))) + { + if (G_sgpe_stop_record.wof.status_stop & STATUS_EXIT_SUSPENDED) + { + G_sgpe_stop_record.group.core[VECTOR_SUSPENDX] |= + G_sgpe_stop_record.group.core[VECTOR_BLOCKX]; + G_sgpe_stop_record.group.qswu[VECTOR_SUSPENDX] |= + G_sgpe_stop_record.group.qswu[VECTOR_BLOCKX]; + } + else + { + G_sgpe_stop_record.group.core[VECTOR_PIGX] |= + G_sgpe_stop_record.group.core[VECTOR_BLOCKX]; + G_sgpe_stop_record.group.qswu[VECTOR_EXIT] |= + G_sgpe_stop_record.group.qswu[VECTOR_BLOCKX]; + } + + G_sgpe_stop_record.group.core[VECTOR_BLOCKX] = 0; + G_sgpe_stop_record.group.qswu[VECTOR_BLOCKX] = 0; + } + + out32(OCB_OCCFLG_CLR, BIT32(SGPE_IGNORE_STOP_CONTROL)); + } + + if ((occflg & BIT32(SGPE_IGNORE_STOP_ENTRIES)) && + (G_sgpe_stop_record.group.creq[VECTOR_BLOCKE] == 0)) + { + if (!(occflg & BIT32(SGPE_IGNORE_STOP_ACTION))) + { + if (G_sgpe_stop_record.wof.status_stop & STATUS_ENTRY_SUSPENDED) + { + G_sgpe_stop_record.group.core[VECTOR_SUSPENDE] |= + G_sgpe_stop_record.group.core[VECTOR_BLOCKE]; + G_sgpe_stop_record.group.qswu[VECTOR_SUSPENDE] |= + G_sgpe_stop_record.group.qswu[VECTOR_BLOCKE]; + } + else + { + G_sgpe_stop_record.group.core[VECTOR_PIGE] |= + G_sgpe_stop_record.group.core[VECTOR_BLOCKE]; + G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] |= + G_sgpe_stop_record.group.qswu[VECTOR_BLOCKE]; + } + + G_sgpe_stop_record.group.core[VECTOR_BLOCKE] = 0; + G_sgpe_stop_record.group.qswu[VECTOR_BLOCKE] = 0; + } + + out32(OCB_OCCFLG_CLR, BIT32(SGPE_IGNORE_STOP_CONTROL)); + } + } + + // decide if launch the thread + p9_sgpe_pig_thread_lanucher(); +} + + + void p9_sgpe_pig_type2_handler(void* arg, PkIrqId irq) { @@ -1055,17 +1081,17 @@ p9_sgpe_pig_type3_handler(void* arg, PkIrqId irq) void -p9_sgpe_pig_type5_handler(void* arg, PkIrqId irq) +p9_sgpe_pig_type0_handler(void* arg, PkIrqId irq) { //=============================== - MARK_TRAP(STOP_PIG_TYPE5_HANDLER) + MARK_TRAP(STOP_PIG_TYPE0_HANDLER) //=============================== - PK_TRACE_DBG("PIG-TYPE5: %d", irq); + PK_TRACE_DBG("PIG-TYPE0: %d", irq); #if DISABLE_STOP8 - // Parse Type5 Requests - p9_sgpe_pig_cpayload_parser(PIG_TYPE5); + // Parse Type0 Requests + p9_sgpe_pig_cpayload_parser(PIG_TYPE0); // decide if launch the thread p9_sgpe_pig_thread_lanucher(); @@ -1079,7 +1105,6 @@ p9_sgpe_pig_type5_handler(void* arg, PkIrqId irq) void p9_sgpe_pig_type6_handler(void* arg, PkIrqId irq) { - PkMachineContext ctx; uint32_t qloop = 0; uint32_t qpending = 0; uint32_t qpayload = 0; @@ -1185,31 +1210,6 @@ p9_sgpe_pig_type6_handler(void* arg, PkIrqId irq) G_sgpe_stop_record.group.qswu[VECTOR_EXIT], G_sgpe_stop_record.group.qswu[VECTOR_ENTRY]); - if (G_sgpe_stop_record.group.qswu[VECTOR_EXIT] || - G_sgpe_stop_record.group.qswu[VECTOR_ENTRY]) - { - // block both type3 and type5, 6 - // so another doesnt interrupt until next round - out32(OCB_OIMR1_OR, (BIT32(16) | BITS32(18, 2))); - g_oimr_override |= (BIT64(48) | BITS64(50, 2)); - - if (G_sgpe_stop_record.group.qswu[VECTOR_EXIT]) - { - PK_TRACE_INF("Unblock Exit"); - pk_semaphore_post(&(G_sgpe_stop_record.sem[1])); - } - - if (G_sgpe_stop_record.group.qswu[VECTOR_ENTRY]) - { - PK_TRACE_INF("Unblock Entry"); - G_sgpe_stop_record.fit.entry_pending = 1; - pk_semaphore_post(&(G_sgpe_stop_record.sem[0])); - } - } - else - { - PK_TRACE_INF("Nothing to do, Enable Interrupts"); - g_oimr_override &= ~BIT64(47); - pk_irq_vec_restore(&ctx); - } + // decide if launch the thread + p9_sgpe_pig_thread_lanucher(); } 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 fc2f72b9..e5e1c095 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 @@ -62,8 +62,8 @@ p9_sgpe_stop_exit_thread(void* arg) 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_TRACE_INF("Setup: Exit Done,no Entry Request.Enable Type0/2/3/6 Interrupt"); + g_oimr_override &= ~(BIT64(45) | BITS64(47, 2) | BIT64(51)); pk_irq_vec_restore(&ctx); } } @@ -104,8 +104,8 @@ p9_sgpe_stop_enter_thread(void* arg) p9_sgpe_ack_pgpe_ctrl_stop_updates(); } - PK_TRACE_INF("Setup: Entry done. Enable Type2/3/5/6 Interrupt"); - g_oimr_override &= ~(BITS64(47, 2) | BITS64(50, 2)); + PK_TRACE_INF("Setup: Entry done. Enable Type0/2/3/6 Interrupt"); + g_oimr_override &= ~(BIT64(45) | BITS64(47, 2) | BIT64(51)); 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 c4206505..702a2c1e 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 @@ -145,9 +145,9 @@ OCCHW_IRQ_CHECK_STOP_GPE3 OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED \ OCCHW_IRQ_IPI3_HI_PRIORITY OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED \ OCCHW_IRQ_IPI3_LO_PRIORITY OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED \ + OCCHW_IRQ_PMC_PCB_INTR_TYPE0_PENDING OCCHW_IRQ_TYPE_LEVEL OCCHW_IRQ_POLARITY_HI OCCHW_IRQ_MASKED \ OCCHW_IRQ_PMC_PCB_INTR_TYPE2_PENDING OCCHW_IRQ_TYPE_LEVEL OCCHW_IRQ_POLARITY_HI OCCHW_IRQ_MASKED \ OCCHW_IRQ_PMC_PCB_INTR_TYPE3_PENDING OCCHW_IRQ_TYPE_LEVEL OCCHW_IRQ_POLARITY_HI OCCHW_IRQ_MASKED \ - OCCHW_IRQ_PMC_PCB_INTR_TYPE5_PENDING OCCHW_IRQ_TYPE_LEVEL OCCHW_IRQ_POLARITY_HI OCCHW_IRQ_MASKED \ OCCHW_IRQ_PMC_PCB_INTR_TYPE6_PENDING OCCHW_IRQ_TYPE_EDGE OCCHW_IRQ_POLARITY_RISING OCCHW_IRQ_MASKED // -------------------- 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 d4dd1320..a53cd63d 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 @@ -87,10 +87,10 @@ SGPE_STOP_ENTRY_STOP11_RESCLK_ON = 0x1e06, //_UNUSED_1e08 = 0x1e08, //_UNUSED_1e09 = 0x1e09, SGPE_IPC_UPDATE_ACTIVE_QUAD_BAD_LIST = 0x1e0a, -SGPE_PGPE_HALT_DETECTED = 0x1e0d, +SGPE_PGPE_ERROR_DETECTED = 0x1e0d, SGPE_SYSTEM_CHECKSTOP_DETECTED = 0x1e1c, -SGPE_PIG_TYPE5_PAYLOAD_INVALID = 0x1e1d, -SGPE_PIG_TYPE5_CME_ERROR = 0x1e1e, +//_UNUSED_1e1d = 0x1e1d, +//_UNUSED_1e1e = 0x1e1e, SGPE_STOP_ENTRY_TRAP_INJECT = 0x1e1f, SGPE_STOP_EXIT_VCS_STOPCLK_FAILED = 0x1f00, // NDD1 |

