diff options
| author | Yue Du <daviddu@us.ibm.com> | 2016-09-08 23:03:12 -0500 |
|---|---|---|
| committer | Joshua Hunsberger <jahunsbe@us.ibm.com> | 2017-10-23 16:32:42 -0500 |
| commit | 0ffb4be6910704306f79087aa7726e88800e71dc (patch) | |
| tree | b026f9b9e222028b9f921552485c13abcae2c4c0 | |
| parent | 8be9737550fa7e6a20031e236b4f5cadd69faf51 (diff) | |
| download | talos-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>
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 |

