summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRahul Batra <rbatra@us.ibm.com>2018-01-04 21:43:15 -0600
committerhostboot <hostboot@us.ibm.com>2018-04-06 12:39:11 -0500
commit5e7a5085043cfc42787069489663c9ba600038d3 (patch)
tree8c56fed0686802472f0ed202f68a037c585d1f25
parent4a102688afb2cb3b815334145d4f7c8b84ab4017 (diff)
downloadtalos-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>
-rw-r--r--import/chips/p9/common/pmlib/include/gpehw_common.h7
-rw-r--r--import/chips/p9/common/pmlib/include/occhw_irq_config.h8
-rw-r--r--import/chips/p9/common/pmlib/include/pstate_pgpe_cme_api.h17
-rw-r--r--import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h2
-rw-r--r--import/chips/p9/common/pmlib/include/stop_sgpe_cme_api.h9
-rw-r--r--import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h67
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/iota_lnk_cfg.h4
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/p9_cme.h5
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/p9_cme_iota_main.c24
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h89
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq_priority_table.c61
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/p9_cme_main.c4
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_intercme.c57
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.c87
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h37
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c549
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_pmcr.c5
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h5
-rwxr-xr-ximport/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c6
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c1
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c21
-rw-r--r--import/chips/p9/procedures/ppe_closed/lib/p9_stop_recovery_trigger.c37
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.c12
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe.h23
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c55
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_ipc_handlers.c11
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.c9
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq.h10
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_irq_handlers.c408
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_main.c55
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_optrace.h21
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.h134
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_actuate_pstates.c16
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_thread_process_requests.c358
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pgpe_panic_codes.h132
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pk_app_cfg.h16
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_common.mk4
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pstate_gpe.mk4
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/topfiles.mk3
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_ipc_handlers.c2
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.c4
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_irq.h8
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C4
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h2
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h7
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c5
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c15
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_init.c29
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c528
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_threads.c8
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h2
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/sgpe_panic_codes.h6
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
OpenPOWER on IntegriCloud