summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYue Du <daviddu@us.ibm.com>2016-09-08 23:03:12 -0500
committerJoshua Hunsberger <jahunsbe@us.ibm.com>2017-10-23 16:32:42 -0500
commit0ffb4be6910704306f79087aa7726e88800e71dc (patch)
treeb026f9b9e222028b9f921552485c13abcae2c4c0
parent8be9737550fa7e6a20031e236b4f5cadd69faf51 (diff)
downloadtalos-hcode-0ffb4be6910704306f79087aa7726e88800e71dc.tar.gz
talos-hcode-0ffb4be6910704306f79087aa7726e88800e71dc.zip
CME/SGPE: STOP image updates and fixes
patchset 1: fix quad spwu(initial) patchset 2: fix quad spwu patchset 3: set scan0 and arrayinit code as default patchset 4: fix for stop3 being nop patchset 5: fix unitified interrupt handler hole of ee bit patchset 6: workaround for pbie read ptr hw bug(initial) patchset 7: optional debug trap based on occ flag[12]/[13] fix stop8 history update typo update fix in patchset 6(still more to come) patchset 8: default disable HW386311_PBIE_RW_PTR_STOP11_FIX patchset 9: workaround for pbie read ptr hw bug(complete) patchset 10:update workaround debug trace and RTC comment patchset 11:add more pk traces to workaround and fix addr patchset 12:fix region bits for the workaround patchset 13:fix region bits ver2 patchset 14:rebase for merge conflict patchset 15:reset scan0/arrayinit to on after rebase patchset 16:fix workaround ring length for rotate back patchset 17:fix pk trace on printing 64bit variables patchset 18:fix l3 purge abort add more traces in partial good config patchset 19:fix history reporting in scominit patchset 20:fix spin bug on 6bits change thread stack size on cme to 512 fix sgpe default pk_app_cfg on istep15_hack patchset 21:fix a typo in patchset 20 patchset 22:fix quad stop history bit0 patchset 23:fix typo in previous 22 patchset 24:add more debug thrace for workaround have parameter for each thread stack size patchset 25:fix typo in 24 patchset 26:fix quad spwu done and possible for pfet error patchset 27:fix stupid kernel bug to cause 0x03abcdef patchset 28:1) add dls+stop1 workaround for pls+srr1 issue 2) some code for bce irritator 3) add block wakeup support and db1+db2 change 4) Note: one marker change for doorbell patchset 29:add broadside support for scan0 module patchset 30:add fused core mode workaround fix workaround compiler define patchset 31:fix qspwu parital good case fix compiler error with broadside mode fix conflict of enum between two headers patchset 32:fix stop handler anormaly introduced by unified interrupt handler returns group id patchset 33:fix a bug introduced by patchset 32 patchset 34:clean scan0 region after workaround patchset 35:Rebased Change-Id: I315d8ccc425a0d420a77d82814962ff6eaa38152 RTC: 161155 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29405 Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Dev-Ready: Gregory S. Still <stillgs@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: YUE DU <daviddu@us.ibm.com> Reviewed-by: AMIT KUMAR <akumar3@us.ibm.com> Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
-rw-r--r--import/chips/p9/common/pmlib/include/cmehw_common.h7
-rw-r--r--import/chips/p9/common/pmlib/include/p9_stop_common.h12
-rw-r--r--import/chips/p9/common/pmlib/include/ppehw_common.h6
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/p9_cme_main.c92
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/pk_app_cfg.h11
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h70
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h9
-rwxr-xr-ximport/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c65
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c180
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c67
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scan0.c21
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scominit.c3
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scan0.c21
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_main.C25
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h10
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c100
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c173
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c44
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h11
19 files changed, 777 insertions, 150 deletions
diff --git a/import/chips/p9/common/pmlib/include/cmehw_common.h b/import/chips/p9/common/pmlib/include/cmehw_common.h
index 059e0518..69598baa 100644
--- a/import/chips/p9/common/pmlib/include/cmehw_common.h
+++ b/import/chips/p9/common/pmlib/include/cmehw_common.h
@@ -31,6 +31,13 @@
#define in32_sh(addr) in32(addr+4)
#define out32_sh(addr, data) out32(addr+4, data)
+/// CME Core Related Configuration
+
+enum CME_CORE_CONFIGS
+{
+ MAX_THREADS_PER_CORE = 4,
+ MAX_CORES_PER_CME = 2
+};
/// Core Masks
diff --git a/import/chips/p9/common/pmlib/include/p9_stop_common.h b/import/chips/p9/common/pmlib/include/p9_stop_common.h
index a7d6b2c0..876ca7fa 100644
--- a/import/chips/p9/common/pmlib/include/p9_stop_common.h
+++ b/import/chips/p9/common/pmlib/include/p9_stop_common.h
@@ -79,7 +79,9 @@ enum P9_STOP_LEVELS
enum P9_STOP_HISTORY_CTRL_STATUS
{
STOP_CORE_READY_RUN = 0,
+ STOP_CACHE_READY_RUN = 0,
STOP_CORE_IS_GATED = 1,
+ STOP_CACHE_IS_GATED = 1,
STOP_TRANS_COMPLETE = 0,
STOP_TRANS_CORE_PORTION = 1,
STOP_TRANS_ENTRY = 2,
@@ -94,14 +96,16 @@ enum P9_STOP_HISTORY_CTRL_STATUS
enum P9_HOMER_REGION_CONSTANTS
{
CME_SRAM_BASE = 0xFFFF8000,
- // CPMR_BASE = HOMER_BASE + 2MB
+ // CPMR_BASE (HOMER_BASE + 2MB)
CPMR_BASE_HOMER_OFFSET = 0x200000,
- // CME_IMAGE_BASE = CPMR_BASE + 6KB + 256KB(8KB + 256B(~56KB) + 192KB)
+ // CME_IMAGE_BASE (CPMR_BASE + 6KB + 256KB(8KB + 256B(~56KB) + 192KB))
CME_IMAGE_CPMR_OFFSET = 0x41800,
- // CME_HEADER_BASE = CME_IMAGE_BASE + 384B
+ // CME_HEADER_BASE (CME_IMAGE_BASE + 384B)
CME_HEADER_IMAGE_OFFSET = 0x180,
// CPMR_ADDRESS is restored at 0x38 location of CME_IMAGE_HEADER
CPMR_ADDR_HEADER_OFFSET = 0x38,
// CME_SRAM_BASE + CME_HEADER_IMAGE_OFFSET + CPMR_ADDR_HEADER_OFFSET
- SELF_RESTORE_ADDR_FETCH = 0xFFFF81B8
+ SELF_RESTORE_ADDR_FETCH = 0xFFFF81B8,
+ // CME_BCE_IRR_HOMER_BASE (HOMER_BASE + 3MB - 128B)
+ CME_BCE_IRR_HOMER_OFFSET = 0x2FFF80
};
diff --git a/import/chips/p9/common/pmlib/include/ppehw_common.h b/import/chips/p9/common/pmlib/include/ppehw_common.h
index 1b19330e..df802bde 100644
--- a/import/chips/p9/common/pmlib/include/ppehw_common.h
+++ b/import/chips/p9/common/pmlib/include/ppehw_common.h
@@ -25,6 +25,12 @@
#ifndef __PPEHW_COMMON_H__
#define __PPEHW_COMMON_H__
+
+/// 64bit variable breaking into two 32bits macro
+#define UPPER32(variable) (uint32_t)((variable >> 32) & 0xFFFFFFFF)
+#define LOWER32(variable) (uint32_t)(variable & 0xFFFFFFFF)
+
+
/// \defgroup be64_bits Bit manipulation for 64-bit Big-Endian values
///
/// \note These macros only work in the assembler context because we build our
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 89e29279..4b7559c7 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
@@ -35,6 +35,11 @@ CmePstateRecord G_cme_pstate_record;
#include "p9_cme_stop.h"
CmeStopRecord G_cme_stop_record = {0};
+#if TEST_ONLY_BCE_IRR
+#include "p9_cme_copy_scan_ring.h"
+BceIrritator G_bce_irr = {0};
+#endif
+
// CME Interrupt Handler Table
EXTERNAL_IRQ_TABLE_START
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_DEBUGGER
@@ -44,7 +49,8 @@ IRQ_HANDLER_DEFAULT //CMEHW_IRQ_PVREF_FAIL
IRQ_HANDLER_DEFAULT //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_handler, (void*)NULL) //CMEHW_IRQ_INTERCME_DIRECT_IN0
+IRQ_HANDLER(p9_cme_pstate_intercme_in0_handler, (void*)NULL)
+//CMEHW_IRQ_INTERCME_DIRECT_IN0
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_BCE_BUSY_HIGH
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_BCE_TIMEOUT
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_DOORBELL3_C0
@@ -61,8 +67,8 @@ IRQ_HANDLER(p9_cme_stop_event_handler, (void*) & (G_cme_stop_record.sem[1]))
//CMEHW_IRQ_SPECIAL_WAKEUP_C0
IRQ_HANDLER(p9_cme_stop_event_handler, (void*) & (G_cme_stop_record.sem[1]))
//CMEHW_IRQ_SPECIAL_WAKEUP_C1
-IRQ_HANDLER_DEFAULT //CMEHW_IRQ_DOORBELL2_C0
-IRQ_HANDLER_DEFAULT //CMEHW_IRQ_DOORBELL2_C1
+IRQ_HANDLER(p9_cme_stop_db2_handler, 0) //CMEHW_IRQ_DOORBELL2_C0
+IRQ_HANDLER(p9_cme_stop_db2_handler, 0) //CMEHW_IRQ_DOORBELL2_C1
IRQ_HANDLER(p9_cme_stop_event_handler, (void*) & (G_cme_stop_record.sem[0]))
//CMEHW_IRQ_PC_PM_STATE_ACTIVE_C0
IRQ_HANDLER(p9_cme_stop_event_handler, (void*) & (G_cme_stop_record.sem[0]))
@@ -89,8 +95,8 @@ IRQ_HANDLER(p9_cme_pstate_db_handler, (void*) & (G_cme_pstate_record.sem[1]))
//CMEHW_IRQ_DOORBELL0_C1
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_INTERCME_IN1
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_INTERCME_IN2
-IRQ_HANDLER(p9_cme_stop_doorbell_handler, 0) //CMEHW_IRQ_DOORBELL1_C0
-IRQ_HANDLER(p9_cme_stop_doorbell_handler, 0) //CMEHW_IRQ_DOORBELL1_C1
+IRQ_HANDLER(p9_cme_stop_db1_handler, 0) //CMEHW_IRQ_DOORBELL1_C0
+IRQ_HANDLER(p9_cme_stop_db1_handler, 0) //CMEHW_IRQ_DOORBELL1_C1
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_PECE_INTR_DISABLED_C0
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_PECE_INTR_DISABLED_C1
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_RESERVED_44
@@ -115,26 +121,41 @@ IRQ_HANDLER_DEFAULT //CMEHW_IRQ_RESERVED_62
IRQ_HANDLER_DEFAULT //CMEHW_IRQ_RESERVED_63
EXTERNAL_IRQ_TABLE_END
-#define KERNEL_STACK_SIZE 256
-#define THREAD_STACK_SIZE 512
-#define STOP_THREAD_STACK_SIZE 512
+#define KERNEL_STACK_SIZE 256
+
+#define CME_THREAD_STACK_SIZE_STOP_EXIT 512
+#define CME_THREAD_STACK_SIZE_STOP_ENTRY 256
+#define CME_THREAD_STACK_SIZE_PSTATE_DB 256
+#define CME_THREAD_STACK_SIZE_PSTATE_PMCR 256
+#if TEST_ONLY_BCE_IRR
+ #define CME_THREAD_STACK_SIZE_BCE_IRR 256
+#endif
-#define CME_THREAD_PRIORITY_STOP_EXIT 1
-#define CME_THREAD_PRIORITY_STOP_ENTRY 2
-#define CME_THREAD_PRIORITY_PSTATE_DB 3
-#define CME_THREAD_PRIORITY_PSTATE_PMCR 4
+#define CME_THREAD_PRIORITY_STOP_EXIT 1
+#define CME_THREAD_PRIORITY_STOP_ENTRY 2
+#define CME_THREAD_PRIORITY_PSTATE_DB 3
+#define CME_THREAD_PRIORITY_PSTATE_PMCR 4
+#if TEST_ONLY_BCE_IRR
+ #define CME_THREAD_PRIORITY_BCE_IRR 30
+#endif
uint8_t G_kernel_stack[KERNEL_STACK_SIZE];
-uint8_t G_p9_cme_stop_enter_thread_stack[THREAD_STACK_SIZE];
-uint8_t G_p9_cme_stop_exit_thread_stack[STOP_THREAD_STACK_SIZE];
-uint8_t G_p9_cme_db_thread_stack[THREAD_STACK_SIZE];
-uint8_t G_p9_cme_pmcr_thread_stack[THREAD_STACK_SIZE];
+uint8_t G_p9_cme_stop_exit_thread_stack[CME_THREAD_STACK_SIZE_STOP_EXIT];
+uint8_t G_p9_cme_stop_enter_thread_stack[CME_THREAD_STACK_SIZE_STOP_ENTRY];
+uint8_t G_p9_cme_db_thread_stack[CME_THREAD_STACK_SIZE_PSTATE_DB];
+uint8_t G_p9_cme_pmcr_thread_stack[CME_THREAD_STACK_SIZE_PSTATE_PMCR];
+#if TEST_ONLY_BCE_IRR
+ uint8_t G_p9_cme_bce_irr_thread_stack[CME_THREAD_STACK_SIZE_BCE_IRR];
+#endif
-PkThread G_p9_cme_stop_enter_thread;
PkThread G_p9_cme_stop_exit_thread;
+PkThread G_p9_cme_stop_enter_thread;
PkThread G_p9_cme_db_thread;
PkThread G_p9_cme_pmcr_thread;
+#if TEST_ONLY_BCE_IRR
+ PkThread G_p9_cme_bce_irr_thread;
+#endif
int
main(int argc, char** argv)
@@ -219,7 +240,7 @@ main(int argc, char** argv)
(PkThreadRoutine)p9_cme_stop_exit_thread,
(void*)NULL,
(PkAddress)G_p9_cme_stop_exit_thread_stack,
- (size_t)THREAD_STACK_SIZE,
+ (size_t)CME_THREAD_STACK_SIZE_STOP_EXIT,
(PkThreadPriority)CME_THREAD_PRIORITY_STOP_EXIT);
PK_TRACE_BIN("G_p9_cme_stop_exit_thread",
@@ -231,7 +252,7 @@ main(int argc, char** argv)
(PkThreadRoutine)p9_cme_stop_enter_thread,
(void*)NULL,
(PkAddress)G_p9_cme_stop_enter_thread_stack,
- (size_t)THREAD_STACK_SIZE,
+ (size_t)CME_THREAD_STACK_SIZE_STOP_ENTRY,
(PkThreadPriority)CME_THREAD_PRIORITY_STOP_ENTRY);
PK_TRACE_BIN("G_p9_cme_stop_enter_thread",
@@ -243,7 +264,7 @@ main(int argc, char** argv)
(PkThreadRoutine)p9_cme_pstate_db_thread,
(void*)NULL,
(PkAddress)G_p9_cme_db_thread_stack,
- (size_t)THREAD_STACK_SIZE,
+ (size_t)CME_THREAD_STACK_SIZE_PSTATE_DB,
(PkThreadPriority)CME_THREAD_PRIORITY_PSTATE_DB);
PK_TRACE_BIN("G_p9_cme_db_thread",
@@ -255,13 +276,32 @@ main(int argc, char** argv)
(PkThreadRoutine)p9_cme_pstate_pmcr_thread,
(void*)NULL,
(PkAddress)G_p9_cme_pmcr_thread_stack,
- (size_t)THREAD_STACK_SIZE,
+ (size_t)CME_THREAD_STACK_SIZE_PSTATE_PMCR,
(PkThreadPriority)CME_THREAD_PRIORITY_PSTATE_PMCR);
PK_TRACE_BIN("G_p9_cme_pmcr_thread",
&G_p9_cme_pmcr_thread,
sizeof(G_p9_cme_pmcr_thread));
+#if TEST_ONLY_BCE_IRR
+
+ if ((G_bce_irr.enable = in32(CME_LCL_FLAGS) & FLAG_BCE_IRR_ENABLE))
+ {
+ // Initialize thread control blocks for the threads
+ pk_thread_create( &G_p9_cme_bce_irr_thread,
+ (PkThreadRoutine)bce_irr_run,
+ (void*)NULL,
+ (PkAddress)G_p9_cme_bce_irr_thread_stack,
+ (size_t)CME_THREAD_STACK_SIZE_BCE_IRR,
+ (PkThreadPriority)CME_THREAD_PRIORITY_BCE_IRR);
+
+ PK_TRACE_BIN("G_p9_cme_bce_irr_thread",
+ &G_p9_cme_bce_irr_thread,
+ sizeof(G_p9_cme_bce_irr_thread));
+ }
+
+#endif
+
// Make G_p9_cme_stop_exit_thread runnable
pk_thread_resume(&G_p9_cme_stop_exit_thread);
@@ -274,6 +314,16 @@ main(int argc, char** argv)
// Make G_p9_cme_pstate_thread runnable
pk_thread_resume(&G_p9_cme_pmcr_thread);
+#if TEST_ONLY_BCE_IRR
+
+ if (G_bce_irr.enable)
+ {
+ // Make G_p9_cme_bce_irr_thread runnable
+ pk_thread_resume(&G_p9_cme_bce_irr_thread);
+ }
+
+#endif
+
PK_TRACE("Launching threads");
ppe42_app_ctx_set(0);
diff --git a/import/chips/p9/procedures/ppe_closed/cme/pk_app_cfg.h b/import/chips/p9/procedures/ppe_closed/cme/pk_app_cfg.h
index 382c312b..a39c0137 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/pk_app_cfg.h
+++ b/import/chips/p9/procedures/ppe_closed/cme/pk_app_cfg.h
@@ -34,25 +34,27 @@
/// \brief Application specific overrides go here.
///
-#define TEST_ONLY_BCE_IRR 0
+#define HW386841_PLS_SRR1_DSL_STOP1_FIX 0
+#define BROADSIDE_SCAN0 0
+#define TEST_ONLY_BCE_IRR 0
#define STOP_PRIME 0
#define SKIP_ABORT 0
#define SKIP_L2_PURGE_ABORT 0
#define SKIP_ENTRY_CATCHUP 0
-#define ISTEP15_HACK 1
+#define ISTEP15_HACK 0
#if !ISTEP15_HACK
#define SKIP_EXIT_CATCHUP 0
#define EPM_P9_TUNING 1
- #define SKIP_SCAN0 1
+ #define SKIP_SCAN0 0
#define SKIP_INITF 0
#define SKIP_SELF_RESTORE 0
#define SKIP_RAM_HRMOR 0
#define SKIP_BCE_SCAN_RING 1
#define SKIP_BCE_SCOM_RESTORE 1
#define SPWU_AUTO 1
- #define SKIP_ARRAYINIT 1
+ #define SKIP_ARRAYINIT 0
#else
#define SKIP_EXIT_CATCHUP 1
#define EPM_P9_TUNING 0
@@ -66,6 +68,7 @@
#define SKIP_ARRAYINIT 0
#endif
+
// --------------------
#define SIMICS_TUNING 0
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 7360d7a7..32ee95fd 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
@@ -114,6 +114,9 @@
#define PERV_SCAN_REGION_TYPE 0x20030005
#define PERV_CLK_REGION 0x20030006
#define PERV_BIST 0x2003000B
+#define PERV_OPCG_CAPT0 0x20030010
+#define PERV_OPCG_CAPT1 0x20030011
+#define PERV_OPCG_CAPT2 0x20030012
#define PERV_CPLT_STAT0 0x20000100
/// Macro to update STOP History
@@ -135,6 +138,15 @@
(((uint64_t)pls) << SHIFT64(60)) | ((uint64_t)srr1_t3) | \
(BIT64(32) | BIT64(40) | BIT64(48) | BIT64(56)))
+#if HW386841_PLS_SRR1_DLS_STOP1_FIX
+#define CME_STOP_UPDATE_DLS(dls, srr1) \
+ ((((uint64_t)dls.threads.t0) << SHIFT64(36)) | (((uint64_t)srr1[0]) << SHIFT64(39)) | \
+ (((uint64_t)dls.threads.t1) << SHIFT64(44)) | (((uint64_t)srr1[1]) << SHIFT64(47)) | \
+ (((uint64_t)dls.threads.t2) << SHIFT64(52)) | (((uint64_t)srr1[2]) << SHIFT64(55)) | \
+ (((uint64_t)dls.threads.t3) << SHIFT64(60)) | ((uint64_t)srr1[3]) | \
+ (BIT64(32) | BIT64(40) | BIT64(48) | BIT64(56)))
+#endif
+
/// CME STOP Return Codes
enum CME_STOP_RETURN_CODE
{
@@ -146,6 +158,8 @@ enum CME_STOP_IRQ_SHORT_NAME
{
IRQ_DB1_C0 = CMEHW_IRQ_DOORBELL1_C0,
IRQ_DB1_C1 = CMEHW_IRQ_DOORBELL1_C1,
+ IRQ_DB2_C0 = CMEHW_IRQ_DOORBELL2_C0,
+ IRQ_DB2_C1 = CMEHW_IRQ_DOORBELL2_C1,
IRQ_STOP_C0 = CMEHW_IRQ_PC_PM_STATE_ACTIVE_C0,
IRQ_STOP_C1 = CMEHW_IRQ_PC_PM_STATE_ACTIVE_C1,
IRQ_PC_C0 = CMEHW_IRQ_PC_INTR_PENDING_C0,
@@ -162,6 +176,8 @@ enum CME_IRQ_VECTORS
IRQ_VEC_WAKE_C1 = BIT64(13) | BIT64(15) | BIT64(17),
IRQ_VEC_SGPE_C0 = BIT64(12) | BIT64(20),
IRQ_VEC_SGPE_C1 = BIT64(13) | BIT64(21),
+ IRQ_VEC_PCWU_C0 = BIT64(12),
+ IRQ_VEC_PCWU_C1 = BIT64(13),
IRQ_VEC_STOP_C0 = BIT64(20),
IRQ_VEC_STOP_C1 = BIT64(21)
};
@@ -169,6 +185,10 @@ enum CME_IRQ_VECTORS
enum CME_STOP_FLAGS
{
FLAG_STOP_READY = BIT32(0),
+ FLAG_BLOCK_WKUP_C0 = BIT32(8),
+ FLAG_BLOCK_WKUP_C1 = BIT32(9),
+ FLAG_BCE_IRR_ENABLE = BIT32(25),
+ FLAG_EX1_INDICATOR = BIT32(26),
FLAG_ENTRY_FIRST_C0 = BIT32(28),
FLAG_ENTRY_FIRST_C1 = BIT32(29),
FLAG_PARTIAL_GOOD_C0 = BIT32(30),
@@ -181,6 +201,13 @@ enum CME_STOP_PIG_TYPES
PIG_TYPE3 = 3
};
+enum CME_DOORBELL_MESSAGE_ID
+{
+ DB1_WKUP_GRANTED = 0x01,
+ DB2_BLOCK_WKUP_ENTRY = 0x01,
+ DB2_BLOCK_WKUP_EXIT = 0x02
+};
+
enum CME_STOP_SRR1
{
MOST_STATE_LOSS = 3,
@@ -188,6 +215,36 @@ enum CME_STOP_SRR1
NO_STATE_LOSS = 1
};
+#if HW386841_PLS_SRR1_DLS_STOP1_FIX
+typedef union
+{
+ uint16_t vector;
+ struct
+ {
+ uint8_t t0 : 4;
+ uint8_t t1 : 4;
+ uint8_t t2 : 4;
+ uint8_t t3 : 4;
+ } threads;
+} CoreThreadsInfo;
+#endif
+
+#if TEST_ONLY_BCE_IRR
+typedef struct
+{
+ uint32_t cmeid;
+ uint32_t sbase;
+ uint32_t mbase;
+ union
+ {
+ uint32_t word;
+ uint8_t byte[4];
+ } data;
+ uint8_t enable;
+} BceIrritator;
+#endif
+
+/// Scom restore block
typedef struct
{
uint32_t pad;
@@ -206,15 +263,17 @@ typedef struct
// need to be a global state for aborting entry
uint8_t act_level_c0;
uint8_t act_level_c1;
+ // partial good configuration,
+ // todo: consider partial good changed during stop,
+ uint32_t core_enabled;
// whether core is in running state,
// need to be a global state for aborted entry detection and wakeup masking
uint32_t core_running;
// core stop handoff to sgpe from cme
// need to be a global state for wakeup and pm_active masking
uint32_t core_stopgpe;
- // partial good configuration,
- // todo: consider partial good changed during stop,
- uint32_t core_enabled;
+ // core in block wakeup mode
+ uint32_t core_blockwu;
PkSemaphore sem[2];
} CmeStopRecord;
@@ -225,10 +284,9 @@ void p9_cme_stop_exit_thread(void*);
int p9_cme_stop_entry();
int p9_cme_stop_exit();
-void p9_cme_stop_enter_semaphore_callback(void*);
-void p9_cme_stop_exit_semaphore_callback(void*);
void p9_cme_stop_event_handler(void*, PkIrqId);
-void p9_cme_stop_doorbell_handler(void*, PkIrqId);
+void p9_cme_stop_db1_handler(void*, PkIrqId);
+void p9_cme_stop_db2_handler(void*, PkIrqId);
int p9_hcd_core_scan0(uint32_t, uint64_t, uint64_t);
int p9_hcd_core_pcb_arb(uint32_t, uint8_t);
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h
index 1ca3c330..5ee4326a 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h
@@ -39,7 +39,8 @@ enum CME_SE_MARKS
BEGINSCOPE_STOP_ENTRY = 0x0,
ENDSCOPE_STOP_ENTRY = 0x8,
STOP_EVENT_HANDLER = 0x10,
- STOP_DOORBELL_HANDLER = 0x18,
+ STOP_DB1_HANDLER = 0x18,
+ STOP_DB2_HANDLER = 0x20,
SE_QUIESCE_CORE_INTF = 0x68,
SE_STOP_CORE_CLKS = 0xe0,
SE_STOP_CORE_GRID = 0xe8,
@@ -67,7 +68,8 @@ const std::vector<CME_SE_MARKS> MARKS =
BEGINSCOPE_STOP_ENTRY,
ENDSCOPE_STOP_ENTRY,
STOP_EVENT_HANDLER,
- STOP_DOORBELL_HANDLER,
+ STOP_DB1_HANDLER,
+ STOP_DB2_HANDLER,
SE_QUIESCE_CORE_INTF,
SE_STOP_CORE_CLKS,
SE_STOP_CORE_GRID,
@@ -91,7 +93,8 @@ const std::map<CME_SE_MARKS, std::string> mMARKS = boost::assign::map_list_of
(BEGINSCOPE_STOP_ENTRY, "BEGINSCOPE_STOP_ENTRY")
(ENDSCOPE_STOP_ENTRY, "ENDSCOPE_STOP_ENTRY")
(STOP_EVENT_HANDLER, "STOP_EVENT_HANDLER")
- (STOP_DOORBELL_HANDLER, "STOP_DOORBELL_HANDLER")
+ (STOP_DB1_HANDLER, "STOP_DB1_HANDLER")
+ (STOP_DB2_HANDLER, "STOP_DB2_HANDLER")
(SE_QUIESCE_CORE_INTF, "SE_QUIESCE_CORE_INTF")
(SE_STOP_CORE_CLKS, "SE_STOP_CORE_CLKS")
(SE_STOP_CORE_GRID, "SE_STOP_CORE_GRID")
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 d29d4fee..43e3f4fb 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
@@ -60,6 +60,7 @@ p9_cme_stop_entry()
uint32_t deeper_core = 0;
uint32_t core_aborted = 0;
uint32_t core_catchup = 0;
+ uint32_t core_stop1 = 0;
uint32_t core;
uint32_t loop;
uint32_t pm_states;
@@ -129,12 +130,24 @@ p9_cme_stop_entry()
{
G_cme_stop_record.req_level_c0 =
(pm_states & BITS32(4, 4)) >> SHIFT32(7);
+
+ if (G_cme_stop_record.req_level_c0 == STOP_LEVEL_1)
+ {
+ G_cme_stop_record.act_level_c0 = STOP_LEVEL_1;
+ core_stop1 |= CME_MASK_C0;
+ }
}
if (core & CME_MASK_C1)
{
G_cme_stop_record.req_level_c1 =
(pm_states & BITS32(8, 4)) >> SHIFT32(11);
+
+ if (G_cme_stop_record.req_level_c1 == STOP_LEVEL_1)
+ {
+ G_cme_stop_record.act_level_c1 = STOP_LEVEL_1;
+ core_stop1 |= CME_MASK_C1;
+ }
}
G_cme_stop_record.core_running &= ~core;
@@ -146,16 +159,32 @@ p9_cme_stop_entry()
G_cme_stop_record.act_level_c1);
// Return error if target STOP level == 1(Nap)
- if((core == CME_MASK_C0 &&
- G_cme_stop_record.req_level_c0 <= STOP_LEVEL_1) ||
- (core == CME_MASK_C1 &&
- G_cme_stop_record.req_level_c1 <= STOP_LEVEL_1) ||
- (core == CME_MASK_BC &&
- (G_cme_stop_record.req_level_c0 <= STOP_LEVEL_1 ||
- G_cme_stop_record.req_level_c1 <= STOP_LEVEL_1)))
+ if(core_stop1)
{
+#if HW386841_PLS_SRR1_DLS_STOP1_FIX
+ // Acknowledge the STOP Entry to PC with a pulse
+ out32(CME_LCL_SICR_OR, core_stop1 << SHIFT32(1));
+ out32(CME_LCL_SICR_CLR, core_stop1 << SHIFT32(1));
+
+ CME_STOP_UPDATE_HISTORY(core_stop1,
+ STOP_CORE_IS_GATED,
+ STOP_TRANS_COMPLETE,
+ STOP_LEVEL_1,
+ STOP_LEVEL_1,
+ STOP_REQ_ENABLE,
+ STOP_ACT_ENABLE);
+
+ core = core & ~core_stop1;
+
+ if (!core)
+ {
+ break;
+ }
+
+#else
PK_TRACE("Error: stop 1 requested to hcode");
pk_halt();
+#endif
}
//----------------------------------------------------------------------
@@ -233,10 +262,11 @@ p9_cme_stop_entry()
//=============================
/// Set LMCR bits 12/13, 14/15 (override disables)
+ out32(CME_LCL_LMCR_OR, (core << SHIFT32(15)));
#if SPWU_AUTO
out32(CME_LCL_LMCR_OR, (core << SHIFT32(13)));
#endif
- out32(CME_LCL_LMCR_OR, (core << SHIFT32(15)));
+
PK_TRACE("SE2.h");
// Raise Core-L2 + Core-CC Quiesces
out32(CME_LCL_SICR_OR, (core << SHIFT32(7)) | (core << SHIFT32(9)));
@@ -508,18 +538,17 @@ p9_cme_stop_entry()
if (target_level == 3)
{
+ /*
+ //==========================
+ MARK_TAG(SE_CORE_VMIN, core)
+ //==========================
- //==========================
- MARK_TAG(SE_CORE_VMIN, core)
- //==========================
-
- PK_TRACE("SE3.a");
- // Enable IVRM if not already
+ PK_TRACE("SE3.a");
+ // Enable IVRM if not already
- PK_TRACE("SE3.b");
+ PK_TRACE("SE3.b");
- // Drop to Vmin
- /*
+ // Drop to Vmin
if(core & CME_MASK_C0)
{
G_cme_stop_record.act_level_c0 = STOP_LEVEL_3;
@@ -868,7 +897,7 @@ p9_cme_stop_entry()
//--------------------------------------------------------------------------
// Release PPM Write Protection
- CME_PUTSCOM(CPPM_CPMMR_CLR, core, BIT64(0));
+ CME_PUTSCOM(CPPM_CPMMR_CLR, CME_MASK_BC, BIT64(0));
//============================
MARK_TRAP(ENDSCOPE_STOP_ENTRY)
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 cbbb2446..a0115c85 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
@@ -28,6 +28,9 @@
#include "p9_cme_copy_scan_ring.h"
extern CmeStopRecord G_cme_stop_record;
+#if HW386841_PLS_SRR1_DLS_STOP1_FIX
+CoreThreadsInfo G_dsl[MAX_CORES_PER_CME] = {0, 0};
+#endif
int
p9_cme_stop_exit()
@@ -48,6 +51,13 @@ p9_cme_stop_exit()
uint8_t catchup_level;
uint32_t core_catchup;
#endif
+#if HW386841_PLS_SRR1_DLS_STOP1_FIX
+ uint32_t core_stop1 = 0;
+ uint8_t dsl;
+ uint8_t thread;
+ uint8_t G_srr1[MAX_CORES_PER_CME][MAX_THREADS_PER_CORE] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
+ cme_scom_pscrs00_t pscrs;
+#endif
ppm_sshsrc_t hist;
uint64_t data64;
@@ -96,14 +106,12 @@ p9_cme_stop_exit()
if (spwu_wake)
{
+ PK_TRACE("X0: setting spwu done");
out32(CME_LCL_SICR_OR, spwu_wake << SHIFT32(17));
}
#endif
- PK_TRACE("X0: Actual Stop Levels[%d %d]",
- G_cme_stop_record.act_level_c0, G_cme_stop_record.act_level_c1);
-
// Code Error: function should never be entered without wakeup source active
if (!core)
{
@@ -128,11 +136,28 @@ p9_cme_stop_exit()
MARK_TAG(BEGINSCOPE_STOP_EXIT, core)
//==================================
- // set target_level to STOP level for c0
- // unless c1(also or only) wants to wakeup
- target_level = deeper_level =
- (core == CME_MASK_C0) ? G_cme_stop_record.act_level_c0 :
- G_cme_stop_record.act_level_c1;
+#if HW386841_PLS_SRR1_DLS_STOP1_FIX
+
+ if ((core & CME_MASK_C0) && G_cme_stop_record.act_level_c0 == STOP_LEVEL_1)
+ {
+ core_stop1 |= CME_MASK_C0;
+ }
+
+ if ((core & CME_MASK_C1) && G_cme_stop_record.act_level_c1 == STOP_LEVEL_1)
+ {
+ core_stop1 |= CME_MASK_C1;
+ }
+
+ core = core & ~core_stop1;
+
+if (!core) goto STOP1_EXIT:
+#endif
+
+ // set target_level to STOP level for c0
+ // unless c1(also or only) wants to wakeup
+ target_level = deeper_level =
+ (core == CME_MASK_C0) ? G_cme_stop_record.act_level_c0 :
+ G_cme_stop_record.act_level_c1;
// If both cores want to wakeup but are in different STOP levels,
// set deeper_level to the deeper level targeted by deeper core
@@ -176,6 +201,33 @@ p9_cme_stop_exit()
while((core & (in32(CME_LCL_SISR) >> SHIFT32(11))) != core);
//--------------------------------------------------------------------------
+ // STOP LEVEL 2 - single core express
+ //--------------------------------------------------------------------------
+
+ if (deeper_core)
+ {
+ core = CME_MASK_BC - deeper_core;
+
+ //============================
+ MARK_TAG(SX_STARTCLOCKS, core)
+ //============================
+
+ // do this again here for stop2 in addition to chiplet_reset
+ // Note IPL doesnt need to do this twice
+ PK_TRACE("4S2: Set Core Glitchless Mux to DPLL");
+ CME_PUTSCOM(C_PPM_CGCR, core, BIT64(3));
+
+ PK_TRACE("X9: Start Core Clock");
+ p9_hcd_core_startclocks(core);
+
+ // Clear CPPM PECE Shadow
+ CME_PUTSCOM(CPPM_PECES, core, 0);
+
+ core = deeper_core;
+ deeper_core = 0;
+ }
+
+ //--------------------------------------------------------------------------
// STOP LEVEL 4
//--------------------------------------------------------------------------
@@ -611,8 +663,94 @@ p9_cme_stop_exit()
// END OF STOP EXIT
//--------------------------------------------------------------------------
+#if HW386841_PLS_SRR1_CME_DLS_FIX
+STOP1_EXIT:
+ core = core | core_stop1;
+#endif
+
PK_TRACE("Restore PSSCR.PLS+SRR1 back to actual level");
+#if HW386841_PLS_SRR1_CME_DLS_FIX
+ core = core | core_stop1;
+
+ if (core & CME_MASK_C0)
+ {
+ CME_GETSCOM(PPM_SSHSRC, CME_MASK_C0, CME_SCOM_AND, hist.value);
+
+ for (thread = 0; thread < MAX_THREADS_PER_CORE; thread++)
+ {
+ pscrs.value = in32((CME_LCL_PSCRS00 + (thread << 2)));
+ dsl = (G_dsl[0].vector & BITS16((thread << 2), 4)) >>
+ SHIFT16((thread << 2) + 3);
+ PK_TRACE("PSCRS1%d %x, old dsl %d", thread, pscrs.value, dsl);
+
+ dsl = MIN(pscrs.field.esl_a_n ? pscrs.fields.rl_a_n : 0,
+ MAX(hist.fields.act_stop_level, dsl));
+ G_dsl[0].vector = ((G_dsl[0].vector & ~BITS16((thread << 2), 4)) |
+ (dsl << SHIFT16((thread << 2) + 3)));
+ PK_TRACE("new dsl %d", dsl);
+
+ if (dsl >= STOP_LEVEL_8)
+ {
+ G_srr1[0][thread] = MOST_STATE_LOSS;
+ }
+ else if (dsl >= STOP_LEVEL_4)
+ {
+ G_srr1[0][thread] = SOME_STATE_LOSS_BUT_NOT_TIMEBASE;
+ }
+ else
+ G_srr1[0][thread] =
+ pscrs.field.esl_a_n ? SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS;
+ }
+
+ CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C0, CME_STOP_UPDATE_DLS(G_dsl[0], G_srr1[0]));
+ PK_TRACE("DLS C0: %x %x %x %x",
+ G_dsl[0].threads.t0, G_dsl[0].threads.t1,
+ G_dsl[0].threads.t2, G_dsl[0].threads.t3);
+ PK_TRACE("SRR1 C0: %x %x %x %x",
+ G_srr1[0][0], G_srr1[0][1], G_srr1[0][2], G_srr1[0][3]);
+ }
+
+ if (core & CME_MASK_C1)
+ {
+ CME_GETSCOM(PPM_SSHSRC, CME_MASK_C1, CME_SCOM_AND, hist.value);
+
+ for (thread = 0; thread < MAX_THREADS_PER_CORE; thread++)
+ {
+ pscrs.value = in32((CME_LCL_PSCRS10 + (thread << 2)));
+ dsl = (G_dsl[1].vector & BITS16((thread << 2), 4)) >>
+ SHIFT16((thread << 2) + 3);
+ PK_TRACE("PSCRS1%d %x, old dsl %d", thread, pscrs.value, dsl);
+
+ dsl = MIN(pscrs.field.esl_a_n ? pscrs.fields.rl_a_n : 0,
+ MAX(hist.fields.act_stop_level, dsl));
+ G_dsl[1].vector = ((G_dsl[1].vector & ~BITS16((thread << 2), 4)) |
+ (dsl << SHIFT16((thread << 2) + 3)));
+ PK_TRACE("new dsl %d", dsl);
+
+ if (G_dsl[1][thread] >= STOP_LEVEL_8)
+ {
+ G_srr1[1][thread] = MOST_STATE_LOSS;
+ }
+ else if (G_dsl[1][thread] >= STOP_LEVEL_4)
+ {
+ G_srr1[1][thread] = SOME_STATE_LOSS_BUT_NOT_TIMEBASE;
+ }
+ else
+ G_srr1[1][thread] =
+ pscrs.field.esl_a_n ? SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS;
+ }
+
+ CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C1, CME_STOP_UPDATE_DLS(G_dsl[1], G_srr1[1]));
+ PK_TRACE("DLS C1: %x %x %x %x",
+ G_dsl[1].threads.t0, G_dsl[1].threads.t1,
+ G_dsl[1].threads.t2, G_dsl[1].threads.t3);
+ PK_TRACE("SRR1 C0: %x %x %x %x",
+ G_srr1[1][0], G_srr1[1][1], G_srr1[1][2], G_srr1[1][3]);
+ }
+
+#else
+
if (core & CME_MASK_C0)
{
CME_GETSCOM(PPM_SSHSRC, CME_MASK_C0, CME_SCOM_AND, hist.value);
@@ -683,6 +821,8 @@ p9_cme_stop_exit()
}
}
+#endif
+
PK_TRACE("XF: Now Wakeup the Core(pm_exit=1)");
out32(CME_LCL_SICR_OR, core << SHIFT32(5));
@@ -704,13 +844,6 @@ p9_cme_stop_exit()
STOP_REQ_DISABLE,
STOP_ACT_DISABLE)
- G_cme_stop_record.core_running |= core;
- G_cme_stop_record.core_stopgpe &= ~core;
-#if SPWU_AUTO
- out32(CME_LCL_LMCR_CLR, (core << SHIFT32(13)));
-#endif
- out32(CME_LCL_LMCR_CLR, (core << SHIFT32(15)));
-
if (core & CME_MASK_C0)
{
G_cme_stop_record.req_level_c0 = 0;
@@ -723,21 +856,34 @@ p9_cme_stop_exit()
G_cme_stop_record.act_level_c1 = 0;
}
- PK_TRACE("XF: Drop pm_exit to allow core to run if spwu is not present");
+ G_cme_stop_record.core_running |= core;
+ G_cme_stop_record.core_stopgpe &= ~core;
+
+ // HALTED_STOP_OVERRIDE_DISABLE = 0
+ out32(CME_LCL_LMCR_CLR, (core << SHIFT32(15)));
+ PK_TRACE("XF: Drop pm_exit to allow core to run if spwu is not present");
#if SPWU_AUTO
+
+ // clear auto spwu disable, enable auto spwu
+ out32(CME_LCL_LMCR_CLR, core << SHIFT32(13));
+
+ //clear pm_exit
out32(CME_LCL_SICR_CLR, core << SHIFT32(5));
+
#else
if (spwu_stop)
{
+ // done = spwu + !pm_active + !core_chiplet_fence + !pcbmux_req + !pcbmux_grant
+ // chiplet fence forces pm_active to zero
PK_TRACE("XF: setting spwu done");
out32(CME_LCL_SICR_OR, spwu_stop << SHIFT32(17));
}
if ((core = (core & (~spwu_stop))))
{
- PK_TRACE("XF: spwu is not done");
+ PK_TRACE("XF: drop pm_exit for not spwu core");
out32(CME_LCL_SICR_CLR, core << SHIFT32(5));
}
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 89b9d4f8..624e1513 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
@@ -53,14 +53,71 @@ p9_cme_stop_event_handler(void* arg, PkIrqId irq)
{
MARK_TRAP(STOP_EVENT_HANDLER)
PK_TRACE("STOP-IRQ: %d", irq);
- pk_semaphore_post((PkSemaphore*)arg);
+
+ if (in32(CME_LCL_EISR) & BITS32(12, 6))
+ {
+ PK_TRACE("lanuch exit");
+ pk_semaphore_post((PkSemaphore*)(&(G_cme_stop_record.sem[1])));
+ }
+ else if (in32(CME_LCL_EISR) & BITS32(20, 2))
+ {
+ PK_TRACE("lanuch entry");
+ pk_semaphore_post((PkSemaphore*)(&(G_cme_stop_record.sem[0])));
+ }
}
void
-p9_cme_stop_doorbell_handler(void* arg, PkIrqId irq)
+p9_cme_stop_db1_handler(void* arg, PkIrqId irq)
{
- PkMachineContext ctx;
- MARK_TRAP(STOP_DOORBELL_HANDLER)
- PK_TRACE("DB-IRQ: %d", irq);
+ PkMachineContext ctx;
+ MARK_TRAP(STOP_DB1_HANDLER)
+ PK_TRACE("DB1-IRQ: %d", irq);
+ pk_irq_vec_restore(&ctx);
+}
+
+void
+p9_cme_stop_db2_handler(void* arg, PkIrqId irq)
+{
+ PkMachineContext ctx;
+ cppm_cmedb2_t db2c0, db2c1;
+
+ MARK_TRAP(STOP_DB2_HANDLER)
+ PK_TRACE("DB2-IRQ: %d", irq);
+
+ CME_GETSCOM(CPPM_CMEDB2, CME_MASK_C0, CME_SCOM_AND, db2c0.value);
+ CME_GETSCOM(CPPM_CMEDB2, CME_MASK_C1, CME_SCOM_AND, db2c1.value);
+ CME_PUTSCOM(CPPM_CMEDB2, CME_MASK_BC, 0);
+ out32(CME_LCL_EISR_CLR, BITS32(18, 2));
+
+ if (db2c0.fields.cme_message_numbern == DB2_BLOCK_WKUP_ENTRY)
+ {
+ G_cme_stop_record.core_blockwu |= CME_MASK_C0;
+ g_eimr_override |= IRQ_VEC_PCWU_C0;
+ }
+ else if (db2c0.fields.cme_message_numbern == DB2_BLOCK_WKUP_EXIT)
+ {
+ G_cme_stop_record.core_blockwu &= ~CME_MASK_C0;
+ g_eimr_override &= ~IRQ_VEC_PCWU_C0;
+ }
+
+ if (db2c1.fields.cme_message_numbern == DB2_BLOCK_WKUP_ENTRY)
+ {
+ G_cme_stop_record.core_blockwu |= CME_MASK_C1;
+ g_eimr_override |= IRQ_VEC_PCWU_C1;
+ }
+ else if (db2c1.fields.cme_message_numbern == DB2_BLOCK_WKUP_EXIT)
+ {
+ G_cme_stop_record.core_blockwu &= ~CME_MASK_C1;
+ g_eimr_override &= ~IRQ_VEC_PCWU_C1;
+ }
+
+ out32(CME_LCL_SICR_OR, G_cme_stop_record.core_blockwu << SHIFT32(3));
+ out32(CME_LCL_SICR_CLR,
+ (~G_cme_stop_record.core_blockwu & CME_MASK_BC) << SHIFT32(3));
+
+ out32(CME_LCL_FLAGS_OR, G_cme_stop_record.core_blockwu << SHIFT32(9));
+ out32(CME_LCL_FLAGS_CLR,
+ (~G_cme_stop_record.core_blockwu & CME_MASK_BC) << SHIFT32(9));
+
pk_irq_vec_restore(&ctx);
}
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scan0.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scan0.c
index 31c41faf..fc6a81a5 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scan0.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scan0.c
@@ -30,8 +30,25 @@ int
p9_hcd_core_scan0(uint32_t core, uint64_t regions, uint64_t scan_type)
{
int rc = CME_STOP_SUCCESS;
- uint64_t scom_data;
+#if BROADSIDE_SCAN0
+ // clean up the scan region
+ CME_PUTSCOM(PERV_SCAN_REGION_TYPE, core, 0);
+
+ // clean up OPCG capture reg0
+ CME_PUTSCOM(PERV_OPCG_CAPT0, core, 0);
+ // clean up OPCG capture reg1
+ CME_PUTSCOM(PERV_OPCG_CAPT1, core, 0);
+ // clean up OPCG capture reg2
+ CME_PUTSCOM(PERV_OPCG_CAPT2, core, 0);
+ // all regions + ARY/NSL
+ CME_PUTSCOM(PERV_CLK_REGION, core, (BITS64(4, 11) | BITS64(49, 2)));
+ // NSL fill for 16 cycles, scan_count=0
+ CME_PUTSCOM(PERV_OPCG_REG1, core, BIT64(59));
+ // OPCG GO, LBIST mode
+ CME_PUTSCOM(PERV_OPCG_REG0, core, BIT64(1));
+#else
+ uint64_t scom_data;
PK_TRACE("raise Vital clock region fence");
CME_PUTSCOM(PERV_CPLT_CTRL1_OR, core, BIT64(3));
@@ -70,6 +87,6 @@ p9_hcd_core_scan0(uint32_t core, uint64_t regions, uint64_t scan_type)
PK_TRACE("Clear Scan Select Register");
CME_PUTSCOM(PERV_SCAN_REGION_TYPE, core, 0);
-
+#endif
return rc;
}
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scominit.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scominit.c
index c47370db..e9315df8 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scominit.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scominit.c
@@ -46,8 +46,5 @@ p9_hcd_core_scominit(uint32_t core)
scom_data = scom_data | BIT64(5);
CME_PUTSCOM(C_THERM_MODE_REG, core, scom_data);
- PK_TRACE("Set core as ready to run in STOP history register");
- CME_PUTSCOM(PPM_SSHSRC, core, 0);
-
return rc;
}
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scan0.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scan0.c
index b57a6cfc..972ca3c2 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scan0.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scan0.c
@@ -30,8 +30,25 @@ int
p9_hcd_cache_scan0(uint32_t quad, uint64_t regions, uint64_t scan_type)
{
int rc = SGPE_STOP_SUCCESS;
- uint64_t scom_data;
+#if BROADSIDE_SCAN0
+ // clean up the scan region
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_SCAN_REGION_TYPE, quad), 0);
+
+ // clean up OPCG capture reg0
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_CAPT0, quad), 0);
+ // clean up OPCG capture reg1
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_CAPT1, quad), 0);
+ // clean up OPCG capture reg2
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_CAPT2, quad), 0);
+ // all regions + ARY/NSL
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CLK_REGION, quad), (BITS64(4, 11) | BITS64(49, 2)));
+ // NSL fill for 16 cycles, scan_count=0
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG1, quad), BIT64(59));
+ // OPCG GO, LBIST mode
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), BIT64(1));
+#else
+ uint64_t scom_data;
PK_TRACE("raise Vital clock region fence");
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CPLT_CTRL1_OR, quad), BIT64(3));
@@ -70,6 +87,6 @@ p9_hcd_cache_scan0(uint32_t quad, uint64_t regions, uint64_t scan_type)
PK_TRACE("Clear Scan Select Register");
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_SCAN_REGION_TYPE, quad), 0);
-
+#endif
return rc;
}
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 99c41db5..873793d9 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
@@ -96,19 +96,21 @@ IRQ_HANDLER_DEFAULT //OCCHW_IRQ_IPI4_LO_PRIORITY
IRQ_HANDLER_DEFAULT //OCCHW_IRQ_RESERVED_63
EXTERNAL_IRQ_TABLE_END
-#define KERNEL_STACK_SIZE 512
-#define THREAD_STACK_SIZE 512
+#define KERNEL_STACK_SIZE 512
-#define SGPE_THREAD_PRIORITY_STOP_EXIT 1
-#define SGPE_THREAD_PRIORITY_STOP_ENTRY 2
+#define SGPE_THREAD_STACK_SIZE_STOP_EXIT 512
+#define SGPE_THREAD_STACK_SIZE_STOP_ENTRY 256
+
+#define SGPE_THREAD_PRIORITY_STOP_EXIT 1
+#define SGPE_THREAD_PRIORITY_STOP_ENTRY 2
uint8_t G_kernel_stack[KERNEL_STACK_SIZE];
-uint8_t G_p9_sgpe_stop_enter_thread_stack[THREAD_STACK_SIZE];
-uint8_t G_p9_sgpe_stop_exit_thread_stack[THREAD_STACK_SIZE];
+uint8_t G_p9_sgpe_stop_exit_thread_stack[SGPE_THREAD_STACK_SIZE_STOP_EXIT];
+uint8_t G_p9_sgpe_stop_enter_thread_stack[SGPE_THREAD_STACK_SIZE_STOP_ENTRY];
-PkThread G_p9_sgpe_stop_enter_thread;
PkThread G_p9_sgpe_stop_exit_thread;
+PkThread G_p9_sgpe_stop_enter_thread;
extern void (*ctor_start_address)() __attribute__ ((section (".rodata")));
extern void (*ctor_end_address)() __attribute__ ((section (".rodata")));
@@ -134,6 +136,11 @@ extern "C" {
int
main(int argc, char** argv)
{
+ if (in32(OCB_OCCFLG) & BIT32(12))
+ {
+ asm volatile ("trap");
+ }
+
// Initializes kernel data (stack, threads, timebase, timers, etc.)
pk_initialize((PkAddress)G_kernel_stack,
KERNEL_STACK_SIZE,
@@ -152,7 +159,7 @@ main(int argc, char** argv)
(PkThreadRoutine)p9_sgpe_stop_enter_thread,
(void*)NULL,
(PkAddress)G_p9_sgpe_stop_enter_thread_stack,
- (size_t)THREAD_STACK_SIZE,
+ (size_t)SGPE_THREAD_STACK_SIZE_STOP_ENTRY,
(PkThreadPriority)SGPE_THREAD_PRIORITY_STOP_ENTRY);
PK_TRACE_BIN("G_p9_sgpe_stop_enter_thread",
@@ -164,7 +171,7 @@ main(int argc, char** argv)
(PkThreadRoutine)p9_sgpe_stop_exit_thread,
(void*)NULL,
(PkAddress)G_p9_sgpe_stop_exit_thread_stack,
- (size_t)THREAD_STACK_SIZE,
+ (size_t)SGPE_THREAD_STACK_SIZE_STOP_EXIT,
(PkThreadPriority)SGPE_THREAD_PRIORITY_STOP_EXIT);
PK_TRACE_BIN("G_p9_sgpe_stop_exit_thread",
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 820f5de8..818765df 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
@@ -107,6 +107,9 @@ extern "C" {
#define PERV_SCAN_REGION_TYPE 0x10030005
#define PERV_CLK_REGION 0x10030006
#define PERV_BIST 0x1003000B
+#define PERV_OPCG_CAPT0 0x10030010
+#define PERV_OPCG_CAPT1 0x10030011
+#define PERV_OPCG_CAPT2 0x10030012
#define PERV_CPLT_STAT0 0x10000100
/// Macro to update STOP History
@@ -172,6 +175,11 @@ enum SGPE_STOP_VECTOR_INDEX
VECTOR_CONFIG = 2
};
+#if HW386311_PBIE_RW_PTR_STOP11_FIX
+#define EXTRACT_RING_BITS(mask, ring, save) save = (ring) & (mask);
+#define RESTORE_RING_BITS(mask, ring, save) ring = (((ring) & (~mask)) | (save));
+#endif
+
typedef struct
{
// requested stop state calculated from core stop levels
@@ -193,7 +201,7 @@ typedef struct
uint32_t ex_r[3];
uint32_t ex_b[3];
uint32_t quad[3];
- uint32_t qswu[2];
+ uint32_t qswu[3];
} sgpe_group_t;
/// SGPE Stop Score Board Structure
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 ef1466fb..d924d196 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
@@ -27,6 +27,30 @@
#include "p9_sgpe_stop_enter_marks.h"
extern SgpeStopRecord G_sgpe_stop_record;
+#if HW386311_PBIE_RW_PTR_STOP11_FIX
+uint64_t G_ring_save[MAX_QUADS][8] =
+{
+ {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}
+};
+uint64_t G_ring_spin[10][2] =
+{
+ {0, 0},
+ {5039, 0xE000000000000000}, //3
+ {5100, 0xC1E061FFED5F0000}, //29
+ {5664, 0xE000000000000000}, //3
+ {5725, 0xC1E061FFED5F0000}, //29
+ {5973, 0xE000000000000000}, //3
+ {6034, 0xC1E061FFED5F0000}, //29
+ {6282, 0xE000000000000000}, //3
+ {6343, 0xC1E061FFED5F0000}, //29
+ {17871, 0} //128
+};
+#endif
int
p9_sgpe_stop_entry()
@@ -43,6 +67,9 @@ p9_sgpe_stop_entry()
uint64_t scom_data;
uint64_t temp_data;
ppm_sshsrc_t hist;
+#if HW386311_PBIE_RW_PTR_STOP11_FIX
+ int spin;
+#endif
//================================
MARK_TAG(BEGINSCOPE_STOP_ENTRY, 0)
@@ -56,7 +83,7 @@ p9_sgpe_stop_entry()
for(qloop = 0; qloop < MAX_QUADS; qloop++)
{
- if (G_sgpe_stop_record.group.qswu[VECTOR_EXIT] & BIT32(qloop))
+ if (G_sgpe_stop_record.group.qswu[VECTOR_CONFIG] & BIT32(qloop))
{
continue;
}
@@ -127,6 +154,8 @@ p9_sgpe_stop_entry()
G_sgpe_stop_record.group.ex_l[VECTOR_CONFIG];
G_sgpe_stop_record.group.ex_r[VECTOR_ENTRY] &=
G_sgpe_stop_record.group.ex_r[VECTOR_CONFIG];
+ G_sgpe_stop_record.group.quad[VECTOR_ENTRY] &=
+ G_sgpe_stop_record.group.quad[VECTOR_CONFIG];
PK_TRACE("Core Entry Vectors: X[%x] X0[%x] X1[%x] Q[%x]",
G_sgpe_stop_record.group.ex_b[VECTOR_ENTRY],
@@ -301,7 +330,7 @@ p9_sgpe_stop_entry()
climit = CORES_PER_QUAD;
G_sgpe_stop_record.state[qloop].act_state_x1 = STOP_LEVEL_8;
entry_ongoing[1] =
- G_sgpe_stop_record.state[qloop].req_state_x0 == STOP_LEVEL_8 ?
+ G_sgpe_stop_record.state[qloop].req_state_x1 == STOP_LEVEL_8 ?
STOP_TRANS_COMPLETE : STOP_TRANS_ENTRY;
}
else
@@ -365,7 +394,7 @@ p9_sgpe_stop_entry()
// Update Quad STOP History
SGPE_STOP_UPDATE_HISTORY(qloop,
QUAD_ADDR_BASE,
- STOP_CORE_IS_GATED,
+ STOP_CACHE_IS_GATED,
STOP_TRANS_ENTRY,
G_sgpe_stop_record.state[qloop].req_state_q,
STOP_LEVEL_11,
@@ -414,11 +443,15 @@ p9_sgpe_stop_entry()
{
#if !SKIP_L3_PURGE_ABORT
- if (in32(OCB_OISR1) & (BITS32(15, 2) & BIT32(19)))
+ if (in32(OCB_OISR1) & (BITS32(15, 2) | BIT32(19)))
{
+ PK_TRACE("SE: interrupt detected");
+
if ((in32(OCB_OPITNPRA(2)) & BITS32((qloop << 2), 4)) ||
(in32(OCB_OPITNPRA(3)) & BITS32((qloop << 2), 4)))
{
+ PK_TRACE("SE: core interrupt detected");
+
for(cloop = 0; cloop < CORES_PER_QUAD; cloop++)
{
if ((in32(OCB_OPIT2CN(((qloop << 2) + cloop))) &
@@ -426,6 +459,7 @@ p9_sgpe_stop_entry()
(in32(OCB_OPIT3CN(((qloop << 2) + cloop))) &
TYPE3_PAYLOAD_EXIT_EVENT))
{
+ PK_TRACE("SE: core wakeup detected");
l3_purge_aborted = 1;
break;
}
@@ -435,6 +469,7 @@ p9_sgpe_stop_entry()
if ((in32(OCB_OPIT6PRB) & BIT32(qloop)) &&
(in32(OCB_OPIT6QN(qloop)) & TYPE6_PAYLOAD_EXIT_EVENT))
{
+ PK_TRACE("SE: quad wakeup detected");
l3_purge_aborted = 1;
}
@@ -654,6 +689,60 @@ p9_sgpe_stop_entry()
MARK_TAG(SE_POWER_OFF_CACHE, (32 >> qloop))
//=========================================
+#if HW386311_PBIE_RW_PTR_STOP11_FIX
+ // bit4,5,11 = perv/eqpb/pbieq, bit59 = inex
+ PK_TRACE("SE: Setup scan register to select the ring");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10030005, qloop), BITS64(4, 2) | BIT64(11) | BIT64(59));
+
+ PK_TRACE("SE: checkword set");
+ scom_data = 0xa5a5a5a5a5a5a5a5;
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+
+ for(spin = 1;; spin++)
+ {
+ PK_TRACE("SE: spin ring loop%d", spin);
+ scom_data = (G_ring_spin[spin][0] - G_ring_spin[spin - 1][0]) << 32;
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10039000, qloop), scom_data);
+
+ PK_TRACE("SE: Poll OPCG done for ring spin");
+
+ do
+ {
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x10000100, qloop), scom_data);
+ }
+ while(~scom_data & BIT64(8));
+
+ if (spin == 9)
+ {
+ PK_TRACE("SE: checkword check");
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+
+ if (scom_data != 0xa5a5a5a5a5a5a5a5)
+ {
+ PK_TRACE("checkword[%x%x] failed", UPPER32(scom_data), LOWER32(scom_data));
+ pk_halt();
+ }
+
+ break;
+ }
+
+ PK_TRACE("SE: save pbie read ptr");
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+ EXTRACT_RING_BITS(G_ring_spin[spin][1], scom_data, G_ring_save[qloop][spin - 1]);
+ PK_TRACE("SE: mask: %8x %8x",
+ UPPER32(G_ring_spin[spin][1]),
+ LOWER32(G_ring_spin[spin][1]));
+ PK_TRACE("SE: ring: %8x %8x",
+ UPPER32(scom_data),
+ LOWER32(scom_data));
+ PK_TRACE("SE: save: %8x %8x",
+ UPPER32(G_ring_save[qloop][spin - 1]),
+ LOWER32(G_ring_save[qloop][spin - 1]));
+ }
+
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10030005, qloop), 0);
+#endif
+
// DD: Assert Cache Vital Thold/PCB Fence/Electrical Fence
PK_TRACE("SE11.q");
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, qloop), BIT64(25));
@@ -755,7 +844,7 @@ p9_sgpe_stop_entry()
SGPE_STOP_UPDATE_HISTORY(qloop,
QUAD_ADDR_BASE,
- STOP_CORE_IS_GATED,
+ STOP_CACHE_IS_GATED,
STOP_TRANS_COMPLETE,
STOP_LEVEL_11,
STOP_LEVEL_11,
@@ -778,7 +867,6 @@ p9_sgpe_stop_entry()
{
if (G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] & BIT32(qloop))
{
- GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_GPMMR_CLR, qloop), BIT64(0));
G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] &= ~BIT32(qloop);
}
}
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 70937d76..2b9c3b25 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
@@ -29,6 +29,14 @@
#include "p9_hcd_cache_initf.h"
extern SgpeStopRecord G_sgpe_stop_record;
+#if HW386311_PBIE_RW_PTR_STOP11_FIX
+ extern uint64_t G_ring_save[MAX_QUADS][8];
+ extern uint64_t G_ring_spin[10][2];
+#endif
+
+#if FUSED_CORE_MODE_SCAN_FIX
+uint32_t G_fcm_spin[4] = {0, 435, 1402, 2411};
+#endif
int
p9_sgpe_stop_exit()
@@ -45,7 +53,9 @@ p9_sgpe_stop_exit()
uint64_t cme_flags;
ppm_sshsrc_t hist;
ocb_ccsr_t ccsr;
-
+#if HW386311_PBIE_RW_PTR_STOP11_FIX
+ int spin;
+#endif
//===============================
MARK_TAG(BEGINSCOPE_STOP_EXIT, 0)
//===============================
@@ -68,50 +78,30 @@ p9_sgpe_stop_exit()
continue;
}
- if (((cexit & BITS32(0, 2)) &&
- (G_sgpe_stop_record.state[qloop].act_state_x0 >= STOP_LEVEL_8)))
- {
- m_l2 |= FST_EX_IN_QUAD;
- }
-
- if (((cexit & BITS32(2, 2)) &&
- (G_sgpe_stop_record.state[qloop].act_state_x1 >= STOP_LEVEL_8)))
- {
- m_l2 |= SND_EX_IN_QUAD;
- }
-
if (G_sgpe_stop_record.group.ex_l[VECTOR_CONFIG] & BIT32(qloop))
{
m_pg |= FST_EX_IN_QUAD;
-
- if (qspwu & BIT32(0))
- {
- m_l2 |= FST_EX_IN_QUAD;
- }
}
if (G_sgpe_stop_record.group.ex_r[VECTOR_CONFIG] & BIT32(qloop))
{
m_pg |= SND_EX_IN_QUAD;
-
- if (qspwu & BIT32(0))
- {
- m_l2 |= SND_EX_IN_QUAD;
- }
}
- PK_TRACE("quad[%d]m_l2[%d]m_pg[%d]", qloop, m_l2, m_pg);
-
- if (G_sgpe_stop_record.group.ex_l[VECTOR_CONFIG] & BIT32(qloop))
+ if ((((cexit & BITS32(0, 2)) || (qspwu & BIT32(0))) &&
+ (G_sgpe_stop_record.state[qloop].act_state_x0 >= STOP_LEVEL_8)))
{
- m_pg |= FST_EX_IN_QUAD;
+ m_l2 |= FST_EX_IN_QUAD;
}
- if (G_sgpe_stop_record.group.ex_r[VECTOR_CONFIG] & BIT32(qloop))
+ if ((((cexit & BITS32(2, 2)) || (qspwu & BIT32(0))) &&
+ (G_sgpe_stop_record.state[qloop].act_state_x1 >= STOP_LEVEL_8)))
{
- m_pg |= SND_EX_IN_QUAD;
+ m_l2 |= SND_EX_IN_QUAD;
}
+ m_l2 = m_l2 & m_pg;
+
PK_TRACE("quad[%d]m_l2[%d]m_pg[%d]", qloop, m_l2, m_pg);
// Update QSSR: stop_exit_ongoing
@@ -138,7 +128,7 @@ p9_sgpe_stop_exit()
{
SGPE_STOP_UPDATE_HISTORY(qloop,
QUAD_ADDR_BASE,
- STOP_CORE_IS_GATED,
+ STOP_CACHE_IS_GATED,
STOP_TRANS_EXIT,
STOP_LEVEL_0,
STOP_LEVEL_0,
@@ -192,6 +182,118 @@ p9_sgpe_stop_exit()
p9_hcd_cache_arrayinit(qloop, m_pg);
#endif
+
+#if FUSED_CORE_MODE_SCAN_FIX
+ // bit8/9 = l2-0/1, bit49 = cfg
+ PK_TRACE("FC: Setup scan register to select the ring");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10030005, qloop), BITS64(8, 2) | BIT64(49));
+
+ PK_TRACE("FC: checkword set");
+ scom_data = 0xa5a5a5a5a5a5a5a5;
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+
+ for(spin = 1;; spin++)
+ {
+ PK_TRACE("FC: spin ring loop%d", spin);
+ scom_data = (G_fcm_spin[spin] - G_fcm_spin[spin - 1]) << 32;
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10039000, qloop), scom_data);
+
+ PK_TRACE("FC: Poll OPCG done for ring spin");
+
+ do
+ {
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x10000100, qloop), scom_data);
+ }
+ while(~scom_data & BIT64(8));
+
+ if (spin == 3)
+ {
+ PK_TRACE("FC: checkword check");
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+
+ if (scom_data != 0xa5a5a5a5a5a5a5a5)
+ {
+ PK_TRACE("FC: checkword[%x%x] failed", UPPER32(scom_data), LOWER32(scom_data));
+ pk_halt();
+ }
+
+ break;
+ }
+
+ PK_TRACE("FC: restore fused core mode bit");
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+ RESTORE_RING_BITS(BIT64(0), scom_data, BIT64(0));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+ }
+
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10030005, qloop), 0);
+#endif
+
+#if HW386311_PBIE_RW_PTR_STOP11_FIX
+ // bit4,5,11 = perv/eqpb/pbieq, bit59 = inex
+ PK_TRACE("SX: Setup scan register to select the ring");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10030005, qloop), BITS64(4, 2) | BIT64(11) | BIT64(59));
+
+ PK_TRACE("SX: checkword set");
+ scom_data = 0xa5a5a5a5a5a5a5a5;
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+
+ for(spin = 1;; spin++)
+ {
+ PK_TRACE("SX: spin ring loop%d", spin);
+ scom_data = (G_ring_spin[spin][0] - G_ring_spin[spin - 1][0]) << 32;
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10039000, qloop), scom_data);
+
+ PK_TRACE("SX: Poll OPCG done for ring spin");
+
+ do
+ {
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x10000100, qloop), scom_data);
+ }
+ while(~scom_data & BIT64(8));
+
+ if (spin == 9)
+ {
+ PK_TRACE("SX: checkword check");
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+
+ if (scom_data != 0xa5a5a5a5a5a5a5a5)
+ {
+ PK_TRACE("checkword[%x%x] failed", UPPER32(scom_data), LOWER32(scom_data));
+ pk_halt();
+ }
+
+ break;
+ }
+
+ PK_TRACE("SX: restore pbie read ptr");
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+ PK_TRACE("SE: mask: %8x %8x",
+ UPPER32(G_ring_spin[spin][1]),
+ LOWER32(G_ring_spin[spin][1]));
+ PK_TRACE("SE: ring: %8x %8x",
+ UPPER32(scom_data),
+ LOWER32(scom_data));
+ PK_TRACE("SE: save: %8x %8x",
+ UPPER32(G_ring_save[qloop][spin - 1]),
+ LOWER32(G_ring_save[qloop][spin - 1]));
+ RESTORE_RING_BITS(G_ring_spin[spin][1], scom_data, G_ring_save[qloop][spin - 1]);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data);
+ PK_TRACE("SE: mask: %8x %8x",
+ UPPER32(G_ring_spin[spin][1]),
+ LOWER32(G_ring_spin[spin][1]));
+ PK_TRACE("SE: ring: %8x %8x",
+ UPPER32(scom_data),
+ LOWER32(scom_data));
+ PK_TRACE("SE: save: %8x %8x",
+ UPPER32(G_ring_save[qloop][spin - 1]),
+ LOWER32(G_ring_save[qloop][spin - 1]));
+
+ }
+
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10030005, qloop), 0);
+#endif
+
//=====================
MARK_TRAP(SX_FUNC_INIT)
//=====================
@@ -301,7 +403,7 @@ p9_sgpe_stop_exit()
PK_TRACE("Doorbell1 the CME %d", ((qloop << 2) + cloop));
GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEMSG,
- ((qloop << 2) + cloop)), (BIT64(0)));
+ ((qloop << 2) + cloop)), BIT64(0));
GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1_OR,
((qloop << 2) + cloop)), BIT64(7));
}
@@ -377,6 +479,11 @@ p9_sgpe_stop_exit()
cme_flags);
}
+ if (in32(OCB_OCCFLG) & BIT32(13))
+ {
+ asm volatile ("trap");
+ }
+
#if !SKIP_CME_BOOT_STOP11
uint16_t cmeBootList = (m_pg << SHIFT16(((qloop << 1) + 1)));
PK_TRACE("Boot CME [%x]", cmeBootList);
@@ -401,7 +508,7 @@ p9_sgpe_stop_exit()
SGPE_STOP_UPDATE_HISTORY(qloop,
QUAD_ADDR_BASE,
- STOP_CORE_IS_GATED,
+ STOP_CACHE_READY_RUN,
STOP_TRANS_COMPLETE,
STOP_LEVEL_0,
STOP_LEVEL_0,
@@ -416,6 +523,8 @@ p9_sgpe_stop_exit()
if (qspwu & BIT32(0))
{
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_GPMMR_OR, qloop), BIT64(0));
+ G_sgpe_stop_record.group.qswu[VECTOR_CONFIG] |= BIT32(qloop);
+ G_sgpe_stop_record.group.qswu[VECTOR_EXIT] &= ~BIT32(qloop);
}
// process core portion of core request
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 a1472174..721c7544 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
@@ -101,7 +101,9 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq)
}
// clear group before analyzing input
+ G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] = 0;
G_sgpe_stop_record.group.core[VECTOR_ENTRY] = 0;
+ G_sgpe_stop_record.group.qswu[VECTOR_EXIT] = 0;
G_sgpe_stop_record.group.core[VECTOR_EXIT] = 0;
G_sgpe_stop_record.group.ex_l[VECTOR_EXIT] = 0;
G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] = 0;
@@ -124,18 +126,27 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq)
if (payload & TYPE6_PAYLOAD_EXIT_EVENT)
{
PK_TRACE("q[%d] request special wakeup", qloop);
- G_sgpe_stop_record.group.qswu[VECTOR_EXIT] |= BIT32(qloop);
- G_sgpe_stop_record.group.quad[VECTOR_EXIT] |= BIT32(qloop);
- G_sgpe_stop_record.group.ex_l[VECTOR_EXIT] |= BIT32(qloop);
- G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] |= BIT32(qloop);
- G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] |=
- BITS32((qloop << 1), 2);
+
+ if (G_sgpe_stop_record.group.qswu[VECTOR_CONFIG] & BIT32(qloop))
+ {
+ PK_TRACE("q[%d] already in special wakeup", qloop);
+ }
+ else
+ {
+ G_sgpe_stop_record.group.qswu[VECTOR_EXIT] |= BIT32(qloop);
+ G_sgpe_stop_record.group.quad[VECTOR_EXIT] |= BIT32(qloop);
+ G_sgpe_stop_record.group.ex_l[VECTOR_EXIT] |= BIT32(qloop);
+ G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] |= BIT32(qloop);
+ G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] |=
+ BITS32((qloop << 1), 2);
+ }
}
else
{
- PK_TRACE("q[%d] drop special wakeup", qloop);
- G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] |= BIT32(qloop);
- G_sgpe_stop_record.group.qswu[VECTOR_EXIT] &= ~BIT32(qloop);
+ PK_TRACE("q[%d] drop special wakeup, clearing done", qloop);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_GPMMR_CLR, qloop), BIT64(0));
+ G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] |= BIT32(qloop);
+ G_sgpe_stop_record.group.qswu[VECTOR_CONFIG] &= ~BIT32(qloop);
}
}
@@ -246,23 +257,30 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq)
G_sgpe_stop_record.group.core[VECTOR_ENTRY],
G_sgpe_stop_record.group.core[VECTOR_EXIT]);
- if ((!G_sgpe_stop_record.group.core[VECTOR_EXIT]) &&
- (!G_sgpe_stop_record.group.core[VECTOR_ENTRY]))
+ if ((!G_sgpe_stop_record.group.core[VECTOR_EXIT]) &&
+ (!G_sgpe_stop_record.group.core[VECTOR_ENTRY]) &&
+ (!G_sgpe_stop_record.group.qswu[VECTOR_EXIT]) &&
+ (!G_sgpe_stop_record.group.qswu[VECTOR_ENTRY]))
{
+ PK_TRACE("Nothing to do, clear masks");
out32(OCB_OIMR1_CLR, (BITS32(15, 2) | BIT32(19)));
}
else
{
- if (G_sgpe_stop_record.group.core[VECTOR_EXIT])
+ if (G_sgpe_stop_record.group.core[VECTOR_EXIT] ||
+ G_sgpe_stop_record.group.qswu[VECTOR_EXIT])
{
PK_TRACE("unblock exit");
pk_semaphore_post(&(G_sgpe_stop_record.sem[1]));
}
- if (G_sgpe_stop_record.group.core[VECTOR_ENTRY])
+ if (G_sgpe_stop_record.group.core[VECTOR_ENTRY] ||
+ G_sgpe_stop_record.group.qswu[VECTOR_ENTRY])
{
PK_TRACE("unblock entry");
pk_semaphore_post(&(G_sgpe_stop_record.sem[0]));
}
+
+ PK_TRACE("RFI");
}
}
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 17a2a82e..4064e663 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
@@ -34,6 +34,11 @@
/// \brief Application specific overrides go here.
///
+// @todo RTC 161182
+#define HW386311_PBIE_RW_PTR_STOP11_FIX 1
+#define BROADSIDE_SCAN0 0
+#define FUSED_CORE_MODE_SCAN_FIX 0
+
#define SIMICS_TUNING 0
#define USE_SIMICS_IO 0
#define DEV_DEBUG 1
@@ -47,12 +52,11 @@
#define SKIP_L3_PURGE_ABORT 0
#define ISTEP15_HACK 0
-
#if EPM_P9_TUNING
#define SKIP_CME_BOOT_STOP11 1
#define SKIP_CME_BOOT_IPL_HB 1
- #define SKIP_ARRAYINIT 1
- #define SKIP_SCAN0 1
+ #define SKIP_ARRAYINIT 0
+ #define SKIP_SCAN0 0
#else
#define SKIP_CME_BOOT_STOP11 0
#define SKIP_CME_BOOT_IPL_HB 1
@@ -63,7 +67,6 @@
// --------------------
-
#if EPM_P9_TUNING
#define PK_TRACE_BUFFER_WRAP_MARKER 1
#endif
OpenPOWER on IntegriCloud