diff options
Diffstat (limited to 'import/chips')
39 files changed, 1728 insertions, 743 deletions
diff --git a/import/chips/p9/common/pmlib/include/cmehw_common.h b/import/chips/p9/common/pmlib/include/cmehw_common.h index 0aba0f73..083ca2c3 100644 --- a/import/chips/p9/common/pmlib/include/cmehw_common.h +++ b/import/chips/p9/common/pmlib/include/cmehw_common.h @@ -49,26 +49,21 @@ enum CME_SCOM_CONTROLS CME_SCOM_EQ = 0, CME_SCOM_OR = 1, CME_SCOM_AND = 2, - CME_SCOM_QUEUE = 3 + CME_SCOM_QUEUED = 3 }; #define CME_SCOM_ADDR(addr, core, op) (addr | (core << 22) | (op << 20)) -#define CME_GETSCOM(addr, core, scom_op, data) \ - rc = getscom(0, CME_SCOM_ADDR(addr, core, scom_op), &data); \ - if (rc) { \ - PK_TRACE("getscom@%d failed w/rc=0x%08x", \ - CME_SCOM_ADDR(addr, core, scom_op), rc); \ - pk_halt(); \ - } - -#define CME_PUTSCOM(addr, core, data) \ - rc = putscom(0, CME_SCOM_ADDR(addr, core, CME_SCOM_NOP), data); \ - if (rc) { \ - PK_TRACE("putscom@%d failed w/rc=0x%08x", \ - CME_SCOM_ADDR(addr, core, CME_SCOM_NOP), rc); \ - pk_halt(); \ - } - +#ifdef USE_PPE_IMPRECISE_MODE +#define CME_GETSCOM(addr, core, scom_op, data) \ + getscom(0, CME_SCOM_ADDR(addr, core, CME_SCOM_QUEUED), &data); +#define CME_PUTSCOM(addr, core, data) \ + putscom(0, CME_SCOM_ADDR(addr, core, CME_SCOM_QUEUED), data); +#else +#define CME_GETSCOM(addr, core, scom_op, data) \ + getscom(0, CME_SCOM_ADDR(addr, core, scom_op), &data); +#define CME_PUTSCOM(addr, core, data) \ + putscom(0, CME_SCOM_ADDR(addr, core, CME_SCOM_NOP), data); +#endif #endif /* __CMEHW_COMMON_H__ */ diff --git a/import/chips/p9/common/pmlib/include/cmehw_interrupts.h b/import/chips/p9/common/pmlib/include/cmehw_interrupts.h index 44a8990e..53107013 100644 --- a/import/chips/p9/common/pmlib/include/cmehw_interrupts.h +++ b/import/chips/p9/common/pmlib/include/cmehw_interrupts.h @@ -194,7 +194,7 @@ CMEHW_IRQ_DEBUGGER STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \ CMEHW_IRQ_DEBUG_TRIGGER STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \ CMEHW_IRQ_QUAD_CHECKSTOP STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \ - CMEHW_IRQ_PVREF_FAIL STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_ENABLED \ + CMEHW_IRQ_PVREF_FAIL STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \ CMEHW_IRQ_OCC_HEARTBEAT_LOST STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \ CMEHW_IRQ_CORE_CHECKSTOP STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \ CMEHW_IRQ_DROPOUT_DETECT STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \ diff --git a/import/chips/p9/common/pmlib/include/gpehw_common.h b/import/chips/p9/common/pmlib/include/gpehw_common.h index d0d01d76..0349bad9 100644 --- a/import/chips/p9/common/pmlib/include/gpehw_common.h +++ b/import/chips/p9/common/pmlib/include/gpehw_common.h @@ -50,18 +50,10 @@ enum GPE_CHIPLET_CONFIGS enum GPE_CHIPLET_MASKS { - ONE_QUAD_IN_CHIP = 0x20, - ALL_QUADS_IN_CHIP = 0x3F, - ONE_CORE_IN_QUAD = 0x8, - ALL_CORES_IN_QUAD = 0xF, FST_CORE_IN_EX = 0x2, SND_CORE_IN_EX = 0x1, - BOTH_CORES_IN_EX = 0x3, FST_EX_IN_QUAD = 0x2, - SND_EX_IN_QUAD = 0x1, - BOTH_EX_IN_QUAD = 0x3, - FST_2CORES_IN_QUAD = 0xC, - SND_2CORES_IN_QUAD = 0x3 + SND_EX_IN_QUAD = 0x1 }; @@ -96,35 +88,14 @@ enum GPE_SCOM_ADDRESS_PARAMETERS #define GPE_SCOM_ADDR_CME(addr, quad, cme) \ GPE_SCOM_ADDR(addr, QUAD_ADDR_BASE|CME_ADDR_BASE, quad, cme) -#define GPE_GETSCOM(addr, data) \ - rc = getscom(0, addr, &data); \ - if (rc) { \ - PK_TRACE("getscom@%d failed w/rc=0x%08x", addr, rc); \ - pk_halt(); \ - } - -#define GPE_PUTSCOM(addr, data) \ - rc = putscom(0, addr, data); \ - if (rc) { \ - PK_TRACE("putscom@%d failed w/rc=0x%08x", addr, rc); \ - pk_halt(); \ - } - -#define GPE_GETSCOM_VAR(addr, cplt_base, cq_offset, ex_select, data) \ - rc = getscom(0,GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select),&data);\ - if (rc) { \ - PK_TRACE("getscom@%d failed w/rc=0x%08x", \ - GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select), rc); \ - pk_halt(); \ - } - -#define GPE_PUTSCOM_VAR(addr, cplt_base, cq_offset, ex_select, data) \ - rc = putscom(0,GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select), data);\ - if (rc) { \ - PK_TRACE("putscom@%d failed w/rc=0x%08x", \ - GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select), rc); \ - pk_halt(); \ - } +#define GPE_GETSCOM(addr, data) getscom(0, addr, &data); + +#define GPE_PUTSCOM(addr, data) putscom(0, addr, data); +#define GPE_GETSCOM_VAR(addr, cplt_base, cq_offset, ex_select, data) \ + getscom(0,GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select),&data); + +#define GPE_PUTSCOM_VAR(addr, cplt_base, cq_offset, ex_select, data) \ + putscom(0,GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select), data); #endif /* __GPEHW_COMMON_H__ */ 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 f0a1a09d..6f14eba5 100644 --- a/import/chips/p9/common/pmlib/include/p9_stop_common.h +++ b/import/chips/p9/common/pmlib/include/p9_stop_common.h @@ -23,24 +23,34 @@ /* */ /* IBM_PROLOG_END_TAG */ -/// Init Vectors for Register Setup -enum P9_HCD_COMMON_INIT_VECTORS +// Clock Control Constants +enum P9_HCD_COMMON_CLK_CTRL_CONSTANTS { - // (1)PCB_EP_RESET - // (2)CLK_ASYNC_RESET - // (3)PLL_TEST_EN - // (4)PLLRST - // (5)PLLBYP - // (11)EDIS - // (12)VITL_MPW1 - // (13)VITL_MPW2 - // (14)VITL_MPW3 - // (18)FENCE_EN - // (22)FUNC_CLKSEL - // (26)LVLTRANS_FENCE - C_NET_CTRL0_INIT_VECTOR = (BIT64(1) | BITS64(3, 3) | BITS64(11, 4) | BIT64(18) | BIT64(22) | BIT64(26)), - Q_NET_CTRL0_INIT_VECTOR = (BITS64(1, 5) | BITS64(11, 4) | BIT64(18) | BIT64(22) | BIT64(26)), - HANG_PULSE1_INIT_VECTOR = BIT64(5) + CLK_STOP_CMD = BIT64(0), + CLK_START_CMD = BIT64(1), + CLK_REGION_DPLL = BIT64(14), + CLK_REGION_ALL_BUT_EX = BITS64(4, 2) | BITS64(10, 2) | BIT64(14), + CLK_REGION_ALL_BUT_EX_DPLL = BITS64(4, 2) | BITS64(10, 2), + CLK_REGION_ALL_BUT_EX_ANEP_DPLL = BITS64(4, 2) | BIT64(11), + CLK_REGION_EX0_L2_L3_REFR = BIT64(6) | BIT64(8) | BIT64(12), + CLK_REGION_EX1_L2_L3_REFR = BIT64(7) | BIT64(9) | BIT64(13), + CLK_REGION_ALL_BUT_PLL = BITS64(4, 10), + CLK_REGION_ALL = BITS64(4, 11), + CLK_THOLD_ALL = BITS64(48, 3) +}; + +// SCAN0 Constants +enum P9_HCD_COMMON_SCAN0_CONSTANTS +{ + SCAN0_REGION_ALL = 0x7FF, + SCAN0_REGION_ALL_BUT_PLL = 0x7FE, + SCAN0_REGION_ALL_BUT_EX = 0x619, + SCAN0_REGION_ALL_BUT_EX_DPLL = 0x618, + SCAN0_REGION_ALL_BUT_EX_ANEP_DPLL = 0x608, + SCAN0_REGION_EX0_L2_L3_REFR = 0x144, + SCAN0_REGION_EX1_L2_L3_REFR = 0x0A2, + SCAN0_TYPE_GPTR_REPR_TIME = 0x230, + SCAN0_TYPE_ALL_BUT_GPTR_REPR_TIME = 0xDCF }; /// STOP Level constants @@ -78,3 +88,19 @@ enum P9_STOP_HISTORY_CTRL_STATUS STOP_REQ_DISABLE = 0, STOP_ACT_DISABLE = 0 }; + +/// Homer Layout +enum P9_HOMER_REGION_CONSTANTS +{ + CME_SRAM_BASE = 0xFFFF8000, + // CPMR_BASE = HOMER_BASE + 2MB + CPMR_BASE_HOMER_OFFSET = 0x200000, + // 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_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 +}; diff --git a/import/chips/p9/common/pmlib/include/ppehw_common.h b/import/chips/p9/common/pmlib/include/ppehw_common.h index 382f3eee..1b19330e 100644 --- a/import/chips/p9/common/pmlib/include/ppehw_common.h +++ b/import/chips/p9/common/pmlib/include/ppehw_common.h @@ -45,10 +45,10 @@ #define BIT8(b) BITS8((b), 1) /// Create a amount of shift to bit location \a b -#define SHIFT64(b) (63-b) -#define SHIFT32(b) (31-b) -#define SHIFT16(b) (15-b) -#define SHIFT8(b) (7-b) +#define SHIFT64(b) (63-(b)) +#define SHIFT32(b) (31-(b)) +#define SHIFT16(b) (15-(b)) +#define SHIFT8(b) (7-(b)) /// Mark and Tag @@ -77,7 +77,13 @@ #define PPE_CORE_CYCLE_RATIO 8 // core is 8 times faster than cme #define PPE_FOR_LOOP_CYCLES 4 // fused compare branch(3), addition(1) #define PPE_CORE_CYCLE_DIVIDER (PPE_CORE_CYCLE_RATIO*PPE_FOR_LOOP_CYCLES) -#define PPE_WAIT_CORE_CYCLES(l,cc) for(l=0;l<cc/PPE_CORE_CYCLE_DIVIDER;l++); +#ifdef USE_PPE_IMPRECISE_MODE +#define PPE_WAIT_CORE_CYCLES(l,cc) \ + for(l=0;l<cc/PPE_CORE_CYCLE_DIVIDER;l++);asm volatile ("sync"); +#else +#define PPE_WAIT_CORE_CYCLES(l,cc) \ + for(l=0;l<cc/PPE_CORE_CYCLE_DIVIDER;l++); +#endif /// IRQ Setup diff --git a/import/chips/p9/common/pmlib/include/registers/cme_register_addresses.h b/import/chips/p9/common/pmlib/include/registers/cme_register_addresses.h index 93b50634..36c50fca 100644 --- a/import/chips/p9/common/pmlib/include/registers/cme_register_addresses.h +++ b/import/chips/p9/common/pmlib/include/registers/cme_register_addresses.h @@ -81,8 +81,8 @@ #define CME_SCOM_EITR 0x10012028 #define CME_SCOM_EISTR 0x10012029 #define CME_SCOM_EINR 0x1001202a -#define CME_SCOM_SISR 0x1001202b -#define CME_SCOM_ICRR 0x1001202c +#define CME_SCOM_SISR 0x1001204c +#define CME_SCOM_ICRR 0x1001204d #define CME_SCOM_XIXCR 0x10012010 #define CME_SCOM_XIRAMRA 0x10012011 #define CME_SCOM_XIRAMGA 0x10012012 @@ -136,7 +136,7 @@ #define CME_LCL_LMCR 0xc00001a0 #define CME_LCL_LMCR_OR 0xc00001b0 #define CME_LCL_LMCR_CLR 0xc00001b8 -#define CME_LCL_BCECSR 0xc00001f0 +#define CME_LCL_BCECSR 0xc00001e0 #define CME_LCL_PMSRS0 0xc0000200 #define CME_LCL_PMSRS1 0xc0000220 #define CME_LCL_PMCRS0 0xc0000240 diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.c b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.c index 92cfea67..b670ea59 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.c +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.c @@ -54,7 +54,7 @@ const uint64_t ext_irq_vectors_cme[NUM_EXT_IRQ_PRTY_LEVELS][2] = IRQ_VEC_PRTY0_CME, IRQ_VEC_PRTY6_CME | /* 0: IDX_PRTY_LVL_HIPRTY */ IRQ_VEC_PRTY5_CME | - //IRQ_VEC_PRTY4_CME | + IRQ_VEC_PRTY4_CME | IRQ_VEC_PRTY3_CME | IRQ_VEC_PRTY2_CME | IRQ_VEC_PRTY1_CME | @@ -64,7 +64,7 @@ const uint64_t ext_irq_vectors_cme[NUM_EXT_IRQ_PRTY_LEVELS][2] = IRQ_VEC_PRTY1_CME, IRQ_VEC_PRTY6_CME | /* 1: IDX_PRTY_LVL_BCE_DB3 */ IRQ_VEC_PRTY5_CME | - //IRQ_VEC_PRTY4_CME | + IRQ_VEC_PRTY4_CME | IRQ_VEC_PRTY3_CME | IRQ_VEC_PRTY2_CME | IRQ_VEC_PRTY1_CME @@ -73,7 +73,7 @@ const uint64_t ext_irq_vectors_cme[NUM_EXT_IRQ_PRTY_LEVELS][2] = IRQ_VEC_PRTY2_CME, IRQ_VEC_PRTY6_CME | /* 2: IDX_PRTY_LVL_WAKE_DB2 */ IRQ_VEC_PRTY5_CME | - //IRQ_VEC_PRTY4_CME | + IRQ_VEC_PRTY4_CME | IRQ_VEC_PRTY3_CME | IRQ_VEC_PRTY2_CME }, @@ -81,14 +81,14 @@ const uint64_t ext_irq_vectors_cme[NUM_EXT_IRQ_PRTY_LEVELS][2] = IRQ_VEC_PRTY3_CME, IRQ_VEC_PRTY6_CME | /* 3: IDX_PRTY_LVL_STOP */ IRQ_VEC_PRTY5_CME | - //IRQ_VEC_PRTY4_CME | + IRQ_VEC_PRTY4_CME | IRQ_VEC_PRTY3_CME }, { IRQ_VEC_PRTY4_CME, IRQ_VEC_PRTY6_CME | /* 4: IDX_PRTY_LVL_DB1 */ - IRQ_VEC_PRTY5_CME //| - //IRQ_VEC_PRTY4_CME + IRQ_VEC_PRTY5_CME | + IRQ_VEC_PRTY4_CME }, { IRQ_VEC_PRTY5_CME, diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h index e811e1d6..c7bc1c0a 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h @@ -78,18 +78,18 @@ extern const uint64_t ext_irq_vectors_cme[NUM_EXT_IRQ_PRTY_LEVELS][2]; // Group0: Non-task hi-prty IRQs #define IRQ_VEC_PRTY0_CME (uint64_t)(0xFE00000000000000) -// Group1: DB3 + BCE -#define IRQ_VEC_PRTY1_CME (uint64_t)(0x00F0000000000000) -// Group2: DB2 + WAKEUP -#define IRQ_VEC_PRTY2_CME (uint64_t)(0x000FF00000000000) -// Group3: STOP -#define IRQ_VEC_PRTY3_CME (uint64_t)(0x00000C0000000000) +// Group1: DB3 +#define IRQ_VEC_PRTY1_CME (uint64_t)(0x0030000000000000) +// Group2: DB2 +#define IRQ_VEC_PRTY2_CME (uint64_t)(0x0000300000000000) +// Group3: WAKEUP + STOP +#define IRQ_VEC_PRTY3_CME (uint64_t)(0x000FCC0000000000) // Group4: DB1 #define IRQ_VEC_PRTY4_CME (uint64_t)(0x0000000000C00000) // Group5: BD0 + PMCR #define IRQ_VEC_PRTY5_CME (uint64_t)(0x000000003C000000) // Group6: We should never detect these -#define IRQ_VEC_PRTY6_CME (uint64_t)(0x010003FFC33FFFFF) +#define IRQ_VEC_PRTY6_CME (uint64_t)(0x01C003FFC33FFFFF) // This should be 0xFFFFFFFFFFFFFFFF #define IRQ_VEC_PRTY_CHECK ( IRQ_VEC_PRTY0_CME | \ 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 0f478706..16d3bb02 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,16 +34,19 @@ /// \brief Application specific overrides go here. /// -#define STOP_PRIME 0 -#define SKIP_ABORT 0 -#define SKIP_L2_PURGE_ABORT 0 -#define SKIP_ENTRY_CATCHUP 0 -#define SKIP_EXIT_CATCHUP 1 -#define SKIP_SCAN0 0 -#define SKIP_INITF 0 -#define SKIP_ARY_INIT 0 -#define SKIP_SELF_RESTORE 0 -#define SKIP_BCE 1 +#define STOP_PRIME 0 +#define SKIP_ABORT 0 +#define SKIP_L2_PURGE_ABORT 0 +#define SKIP_ENTRY_CATCHUP 0 +#define SKIP_EXIT_CATCHUP 1 +#define SKIP_ARRAYINIT 1 +#define SKIP_SCAN0 1 +#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 // -------------------- @@ -56,6 +59,7 @@ #define PK_TRACE_BUFFER_WRAP_MARKER 1 #endif #define PK_TRACE_TIMER_OUTPUT 0 +#define PK_TRACE_ENABLE 1 // -------------------- 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 e2f1bdb4..046b0601 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 @@ -45,14 +45,42 @@ #include "p9_stop_common.h" +// ram_vtid [0:1] 00 +// pre_decode [2:5] 0000 +// spare [6:7] 00 +// instruction [8:39] 0111 11,00 000,1 0101 0100 0,010 1010 011,0 +// 31 | GPR0(0) | SPRD(10101 01000) | MFSPR(339) +// constant [40:63] 0000 0000 0000 0000 0000 0000 +#define RAM_MFSPR_SPRD_GPR0 0x7C1542A6000000 + +// ram_vtid [0:1] 00 +// pre_decode [2:5] 0000 +// spare [6:7] 00 +// instruction [8:39] 0111 11,00 000,1 1001 0100 1,011 1010 011,0 +// 31 | GPR0(0) | HRMOR(11001 01001) | MTSPR(467) +// constant [40:63] 0000 0000 0000 0000 0000 0000 +#define RAM_MTSPR_HRMOR_GPR0 0x7C194BA6000000 + +// ram_vtid [0:1] 00 +// pre_decode [2:5] 0000 +// spare [6:7] 00 +// instruction [8:39] 0111 11,00 000,1 0111 1101 0,011 1010 011,0 +// 31 | GPR0(0) | PSSCR(10111 11010) | MTSPR(467) +// constant [40:63] 0000 0000 0000 0000 0000 0000 +#define RAM_MTSPR_PSSCR_GPR0 0x7C17D3A6000000 + /// handcoded addresses TO BE REMOVED +#define RAS_STATUS 0x20010A02 +#define RAM_MODEREG 0x20010A4E +#define RAM_CTRL 0x20010A4F +#define RAM_STATUS 0x20010A50 +#define SCOM_SPRC 0x20010A80 +#define SPR_MODE 0x20010A84 +#define SCRACTH0 0x20010A86 +#define SCRACTH1 0x20010A87 #define THREAD_INFO 0x20010A9B #define DIRECT_CONTROLS 0x20010A9C -#define RAS_STATUS 0x20010A02 -#define RAM_MODEREG 0x20010A51 -#define RAM_CTRL 0x20010A52 -#define RAM_STATUS 0x20010A53 #define C_SYNC_CONFIG 0x20030000 #define C_OPCG_ALIGN 0x20030001 @@ -62,6 +90,7 @@ #define C_CLOCK_STAT_NSL 0x20030009 #define C_CLOCK_STAT_ARY 0x2003000a #define C_BIST 0x2003000B +#define C_THERM_MODE_REG 0x2005000F #define C_SLAVE_CONFIG_REG 0x200F001E #define C_ERROR_REG 0x200F001F @@ -72,15 +101,20 @@ #define C_CPLT_CTRL0_CLEAR 0x20000020 #define C_CPLT_CTRL1_OR 0x20000011 #define C_CPLT_CTRL1_CLEAR 0x20000021 +#define C_CPLT_CONF0_OR 0x20000018 +#define C_CPLT_CONF0_CLEAR 0x20000028 #define C_CPLT_STAT0 0x20000100 -#define PERV_CPLT_CTRL0_OR 0x00000010 -#define PERV_CPLT_CTRL0_CLEAR 0x00000020 -#define PERV_OPCG_REG0 0x00030002 -#define PERV_OPCG_REG1 0x00030003 -#define PERV_CLK_REGION 0x00030006 -#define PERV_BIST 0x0003000B -#define PERV_CPLT_STAT0 0x00000100 +#define PERV_CPLT_CTRL0_OR 0x20000010 +#define PERV_CPLT_CTRL0_CLEAR 0x20000020 +#define PERV_CPLT_CTRL1_OR 0x20000011 +#define PERV_CPLT_CTRL1_CLEAR 0x20000021 +#define PERV_OPCG_REG0 0x20030002 +#define PERV_OPCG_REG1 0x20030003 +#define PERV_SCAN_REGION_TYPE 0x20030005 +#define PERV_CLK_REGION 0x20030006 +#define PERV_BIST 0x2003000B +#define PERV_CPLT_STAT0 0x20000100 /// Macro to update STOP History #define CME_STOP_UPDATE_HISTORY(core,gated,trans,req_l,act_l,req_e,act_e) \ @@ -92,10 +126,13 @@ hist.fields.act_write_enable = act_e; \ CME_PUTSCOM(PPM_SSHSRC, core, hist.value); -#define IRQ_VEC_WAKE_C0 (uint64_t)(0x000A800000000000) -#define IRQ_VEC_WAKE_C1 (uint64_t)(0x0005400000000000) -#define IRQ_VEC_STOP_C0 (uint64_t)(0x0000080000000000) -#define IRQ_VEC_STOP_C1 (uint64_t)(0x0000040000000000) +/// Macro to update PSSCR.PLS +#define CME_STOP_UPDATE_PLS_SRR1(pls, srr1_t0, srr1_t1, srr1_t2, srr1_t3) \ + ((((uint64_t)pls) << SHIFT64(36)) | (((uint64_t)srr1_t0) << SHIFT64(39)) | \ + (((uint64_t)pls) << SHIFT64(44)) | (((uint64_t)srr1_t1) << SHIFT64(47)) | \ + (((uint64_t)pls) << SHIFT64(52)) | (((uint64_t)srr1_t2) << SHIFT64(55)) | \ + (((uint64_t)pls) << SHIFT64(60)) | ((uint64_t)srr1_t3) | \ + (BIT64(32) | BIT64(40) | BIT64(48) | BIT64(56))) /// CME STOP Return Codes enum CME_STOP_RETURN_CODE @@ -118,6 +155,16 @@ enum CME_STOP_IRQ_SHORT_NAME IRQ_SWU_C1 = CMEHW_IRQ_SPECIAL_WAKEUP_C1 }; +enum CME_IRQ_VECTORS +{ + IRQ_VEC_WAKE_C0 = BIT64(12) | BIT64(14) | BIT64(16), + 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_STOP_C0 = BIT64(20), + IRQ_VEC_STOP_C1 = BIT64(21) +}; + enum CME_STOP_FLAGS { FLAG_STOP_READY = BIT32(0), @@ -127,13 +174,25 @@ enum CME_STOP_FLAGS FLAG_PARTIAL_GOOD_C1 = BIT32(31) }; - enum CME_STOP_PIG_TYPES { PIG_TYPE2 = 2, PIG_TYPE3 = 3 }; +enum CME_STOP_SRR1 +{ + MOST_STATE_LOSS = 3, + SOME_STATE_LOSS_BUT_NOT_TIMEBASE = 2, + NO_STATE_LOSS = 1 +}; + +typedef struct +{ + uint32_t pad; + uint32_t addr; + uint64_t data; +} CmeScomRestore; /// Stop Score Board Structure typedef struct @@ -170,6 +229,7 @@ void p9_cme_stop_exit_semaphore_callback(void*); void p9_cme_stop_event_handler(void*, PkIrqId); void p9_cme_stop_doorbell_handler(void*, PkIrqId); +int p9_hcd_core_scan0(uint32_t, uint64_t, uint64_t); int p9_hcd_core_pcb_arb(uint32_t, uint8_t); int p9_hcd_core_poweron(uint32_t); int p9_hcd_core_chiplet_reset(uint32_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 ec8a950c..1ca3c330 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 @@ -87,6 +87,29 @@ const std::vector<CME_SE_MARKS> MARKS = SE_SGPE_HANDOFF }; +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") + (SE_QUIESCE_CORE_INTF, "SE_QUIESCE_CORE_INTF") + (SE_STOP_CORE_CLKS, "SE_STOP_CORE_CLKS") + (SE_STOP_CORE_GRID, "SE_STOP_CORE_GRID") + (SE_STOP2_DONE, "SE_STOP2_DONE") + (SE_IS0_BEGIN, "SE_IS0_BEGIN") + (SE_IS0_END, "SE_IS0_END") + (SE_CATCHUP, "SE_CATCHUP") + (SE_CORE_VMIN, "SE_CORE_VMIN") + (SE_STOP3_DONE, "SE_STOP3_DONE") + (SE_POWER_OFF_CORE, "SE_POWER_OFF_CORE") + (SE_STOP4_DONE, "SE_STOP4_DONE") + (SE_IS1_BEGIN, "SE_IS1_BEGIN") + (SE_IS1_END, "SE_IS1_END") + (SE_PURGE_L2, "SE_PURGE_L2") + (SE_PURGE_L2_ABORT, "SE_PURGE_L2_ABORT") + (SE_PURGE_L2_DONE, "SE_PURGE_L2_DONE") + (SE_SGPE_HANDOFF, "SE_SGPE_HANDOFF"); + } #endif 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 3bc44a6d..d6c86889 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 @@ -51,8 +51,6 @@ extern CmeStopRecord G_cme_stop_record; int p9_cme_stop_entry() { - - int rc = 0; int catchup_ongoing = 0; int entry_ongoing = 1; uint8_t target_level; @@ -141,9 +139,11 @@ p9_cme_stop_entry() G_cme_stop_record.core_running &= ~core; - PK_TRACE("SE1: Request Stop Levels[%d %d]", + PK_TRACE("SE1: Stop Levels Request[%d %d] Actual[%d, %d]", G_cme_stop_record.req_level_c0, - G_cme_stop_record.req_level_c1); + G_cme_stop_record.req_level_c1, + G_cme_stop_record.act_level_c0, + G_cme_stop_record.act_level_c1); // Return error if target STOP level == 1(Nap) if((core == CME_MASK_C0 && @@ -170,6 +170,11 @@ p9_cme_stop_entry() // Protect PPM Register Write CME_PUTSCOM(CPPM_CPMMR_OR, core, BIT64(0)); + PK_TRACE("SE2.g"); + // Acknowledge the STOP Entry to PC with a pulse + out32(CME_LCL_SICR_OR, core << SHIFT32(1)); + out32(CME_LCL_SICR_CLR, core << SHIFT32(1)); + // set target_level from pm_state for both cores or just one core target_level = (core == CME_MASK_C0) ? G_cme_stop_record.req_level_c0 : G_cme_stop_record.req_level_c1; @@ -214,8 +219,8 @@ p9_cme_stop_entry() STOP_ACT_DISABLE); } - PK_TRACE("SE2: target_lv[%d], deeper_lv[%d], deeper_core[%d]", - target_level, deeper_level, deeper_core); + PK_TRACE("SE2: core[%d], target_lv[%d], deeper_lv[%d], deeper_core[%d]", + core, target_level, deeper_level, deeper_core); // Poll Infinitely for PCB Mux Grant // MF: change watchdog timer in pk to ensure forward progress @@ -227,14 +232,11 @@ p9_cme_stop_entry() MARK_TRAP(SE_QUIESCE_CORE_INTF) //============================= - PK_TRACE("SE2.g"); - // Acknowledge the STOP Entry to PC with a pulse - out32(CME_LCL_SICR_OR, core << SHIFT32(1)); - out32(CME_LCL_SICR_CLR, core << SHIFT32(1)); - /// Set LMCR bits 12/13, 14/15 (override disables) - out32(CME_LCL_LMCR_OR, ((core << SHIFT32(13)) | (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))); @@ -265,16 +267,25 @@ p9_cme_stop_entry() PK_TRACE("SE2.l"); // Stop Core Clocks - CME_PUTSCOM(C_CLK_REGION, core, 0x8FFC00000000E000); + CME_PUTSCOM(C_CLK_REGION, core, (CLK_STOP_CMD | CLK_REGION_ALL_BUT_PLL | CLK_THOLD_ALL)); PK_TRACE("SE2.m"); // Poll for core clocks stopped do { - CME_GETSCOM(C_CLOCK_STAT_SL, core, CME_SCOM_AND, scom_data); + CME_GETSCOM(C_CPLT_STAT0, core, CME_SCOM_AND, scom_data); + } + while((~scom_data) & BIT64(8)); + + PK_TRACE("Check core clock is stopped via CLOCK_STAT_SL[4-13]"); + CME_GETSCOM(C_CLOCK_STAT_SL, core, CME_SCOM_AND, scom_data); + + if (((~scom_data) & CLK_REGION_ALL_BUT_PLL) != 0) + { + PK_TRACE("Core clock stop failed"); + pk_halt(); } - while((scom_data & BITS64(4, 10)) != BITS64(4, 10)); // MF: verify compiler generate single rlwmni // MF: delay may be needed for stage latch to propagate thold @@ -305,9 +316,15 @@ p9_cme_stop_entry() // Assert skew sense to skewadjust Fence CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(22)); // Assert Vital Fence - CME_PUTSCOM(C_CPLT_CTRL1_OR, core, BIT64(3)); + CME_PUTSCOM(C_CPLT_CTRL1_OR, core, BIT64(3)); // Assert Regional Fences - CME_PUTSCOM(C_CPLT_CTRL1_OR, core, 0xFFFF700000000000); + CME_PUTSCOM(C_CPLT_CTRL1_OR, core, BITS64(4, 11)); + /// @todo add DD1 attribute control + PK_TRACE("DD1 only: reset sdis_n(flushing LCBES condition workaround"); + CME_PUTSCOM(C_CPLT_CONF0_CLEAR, core, BIT64(34)); + /// @todo add VDM_ENABLE attribute control + PK_TRACE("Drop vdm enable via CPPM_VDMCR[0]"); + CME_PUTSCOM(PPM_VDMCR_CLR, core, BIT64(0)); PK_TRACE("SE2: Clock Sync Dropped"); @@ -365,43 +382,6 @@ p9_cme_stop_entry() entry_ongoing = 1; } - //=========================== - MARK_TRAP(SE_IS0_BEGIN) - //=========================== -#if !SKIP_ABORT - out32(CME_LCL_EIMR_CLR, (core << SHIFT32(13)) | - (core << SHIFT32(15)) | - (core << SHIFT32(17))); - sync(); - out32(CME_LCL_EIMR_OR, (core << SHIFT32(13)) | - (core << SHIFT32(15)) | - (core << SHIFT32(17))); -#endif - //=================== - MARK_TRAP(SE_IS0_END) - //=================== - - core_aborted = core & G_cme_stop_record.core_running; - - if (core_aborted && deeper_core) - { - if (core_aborted != deeper_core) - { - target_level = deeper_level; - } - - deeper_core = 0; - } - - core = core & ~G_cme_stop_record.core_running; - - if (!core) - { - core |= core_aborted; - entry_ongoing = 0; - break; - } - #if !SKIP_ENTRY_CATCHUP if (catchup_ongoing) @@ -462,6 +442,9 @@ p9_cme_stop_entry() //======================== } + PK_TRACE("core[%d] running[%d] core_catchup[%d] origin_core[%d]", + core, G_cme_stop_record.core_running, core_catchup, origin_core); + #endif } @@ -470,12 +453,51 @@ p9_cme_stop_entry() do { - // If we are done at STOP level 2 or aborted + // If we are done at STOP level 2 if (!entry_ongoing) { break; } + //=========================== + MARK_TRAP(SE_IS0_BEGIN) + //=========================== +#if !SKIP_ABORT + out32(CME_LCL_EIMR_CLR, (core << SHIFT32(13)) | + (core << SHIFT32(15)) | + (core << SHIFT32(17))); + sync(); + out32(CME_LCL_EIMR_OR, (core << SHIFT32(13)) | + (core << SHIFT32(15)) | + (core << SHIFT32(17))); +#endif + //=================== + MARK_TRAP(SE_IS0_END) + //=================== + + core_aborted = core & G_cme_stop_record.core_running; + core = core & ~G_cme_stop_record.core_running; + + PK_TRACE("core[%d] running[%d] core_aborted[%d]", + core, G_cme_stop_record.core_running, core_aborted); + + if (!core) + { + core |= core_aborted; + entry_ongoing = 0; + break; + } + + if (core_aborted && deeper_core) + { + if (core_aborted != deeper_core) + { + target_level = deeper_level; + } + + deeper_core = 0; + } + PK_TRACE("SE2+:core[%d],deeper_core[%d],\ target_level[%d],deeper_level[%d]", core, deeper_core, target_level, deeper_level); @@ -483,75 +505,75 @@ p9_cme_stop_entry() //---------------------------------------------------------------------- // STOP LEVEL 3 //---------------------------------------------------------------------- + /* + if (target_level == 3) + { - if (target_level == 3) - { - - //========================== - MARK_TAG(SE_CORE_VMIN, core) - //========================== - - PK_TRACE("SE3.a"); - // Enable IVRM if not already - - PK_TRACE("SE3.b"); - // Drop to Vmin - - if(core & CME_MASK_C0) - { - G_cme_stop_record.act_level_c0 = STOP_LEVEL_3; - } + //========================== + MARK_TAG(SE_CORE_VMIN, core) + //========================== - if(core & CME_MASK_C1) - { - G_cme_stop_record.act_level_c1 = STOP_LEVEL_3; - } + PK_TRACE("SE3.a"); + // Enable IVRM if not already - //=========================== - MARK_TAG(SE_STOP3_DONE, core) - //=========================== + PK_TRACE("SE3.b"); + // Drop to Vmin - PK_TRACE("SE3.c"); - // Update Stop History: In Core Stop Level 3 - CME_STOP_UPDATE_HISTORY(core, - STOP_CORE_IS_GATED, - STOP_TRANS_COMPLETE, - target_level, - STOP_LEVEL_3, - STOP_REQ_DISABLE, - STOP_ACT_ENABLE); + if(core & CME_MASK_C0) + { + G_cme_stop_record.act_level_c0 = STOP_LEVEL_3; + } - // If both cores targeting different levels - // deeper core should have at least deeper stop level than 3 - // only need to modify deeper core history if another one was done - if (deeper_core) - { - CME_STOP_UPDATE_HISTORY(deeper_core, - STOP_CORE_IS_GATED, - STOP_TRANS_ENTRY, - deeper_level, - STOP_LEVEL_2, - STOP_REQ_DISABLE, - STOP_ACT_ENABLE); - // from now on, proceed with only deeper core - core = deeper_core; - target_level = deeper_level; - deeper_level = 0; - deeper_core = 0; - entry_ongoing = 1; - } - else - { - entry_ongoing = 0; - } + if(core & CME_MASK_C1) + { + G_cme_stop_record.act_level_c1 = STOP_LEVEL_3; + } - // If we are done at STOP level 3 - if (!entry_ongoing) - { - break; - } - } + //=========================== + MARK_TAG(SE_STOP3_DONE, core) + //=========================== + + PK_TRACE("SE3.c"); + // Update Stop History: In Core Stop Level 3 + CME_STOP_UPDATE_HISTORY(core, + STOP_CORE_IS_GATED, + STOP_TRANS_COMPLETE, + target_level, + STOP_LEVEL_3, + STOP_REQ_DISABLE, + STOP_ACT_ENABLE); + + // If both cores targeting different levels + // deeper core should have at least deeper stop level than 3 + // only need to modify deeper core history if another one was done + if (deeper_core) + { + CME_STOP_UPDATE_HISTORY(deeper_core, + STOP_CORE_IS_GATED, + STOP_TRANS_ENTRY, + deeper_level, + STOP_LEVEL_2, + STOP_REQ_DISABLE, + STOP_ACT_ENABLE); + // from now on, proceed with only deeper core + core = deeper_core; + target_level = deeper_level; + deeper_level = 0; + deeper_core = 0; + entry_ongoing = 1; + } + else + { + entry_ongoing = 0; + } + // If we are done at STOP level 3 + if (!entry_ongoing) + { + break; + } + } + */ //---------------------------------------------------------------------- // STOP LEVEL 4 //---------------------------------------------------------------------- @@ -626,7 +648,7 @@ p9_cme_stop_entry() STOP_ACT_ENABLE); // If both cores targeting different levels - // deeper core should have at least deeper stop level than 2 + // deeper core should have at least deeper stop level than 4 // only need to modify deeper core history if another one was done if (deeper_core && !entry_ongoing) { @@ -645,6 +667,12 @@ p9_cme_stop_entry() entry_ongoing = 1; } + // If we are done at STOP level 4 + if (!entry_ongoing) + { + break; + } + //=========================== MARK_TRAP(SE_IS1_BEGIN) //=========================== @@ -661,19 +689,11 @@ p9_cme_stop_entry() MARK_TRAP(SE_IS1_END) //=================== - core_aborted = core & G_cme_stop_record.core_running; - - if (core_aborted && deeper_core) - { - if (core_aborted != deeper_core) - { - target_level = deeper_level; - } - - deeper_core = 0; - } + core_aborted = core & G_cme_stop_record.core_running; + core = core & ~G_cme_stop_record.core_running; - core = core & ~G_cme_stop_record.core_running; + PK_TRACE("core[%d] running[%d] core_aborted[%d]", + core, G_cme_stop_record.core_running, core_aborted); if (!core) { @@ -682,10 +702,14 @@ p9_cme_stop_entry() break; } - // If we are done at STOP level 4 or aborted - if (!entry_ongoing) + if (core_aborted && deeper_core) { - break; + if (core_aborted != deeper_core) + { + target_level = deeper_level; + } + + deeper_core = 0; } PK_TRACE("SE4+:core[%d],deeper_core[%d],\ @@ -696,22 +720,21 @@ p9_cme_stop_entry() // STOP LEVEL 5 (preparsion of STOP LEVEL 8 and above) //---------------------------------------------------------------------- - // block all wake up before purge L2, - // this is last chance either core can exit - //out32(CME_LCL_EIMR_OR, BITS32(12, 6)); - if ((G_cme_stop_record.req_level_c0 >= STOP_LEVEL_8) && (G_cme_stop_record.req_level_c1 >= STOP_LEVEL_8)) { - //========================= - MARK_TAG(SE_PURGE_L2, core) - //========================= + //================================ + MARK_TAG(SE_PURGE_L2, CME_MASK_BC) + //================================ - // Assert L2+NCU Purges(chtm purge will be done in SGPE), - // and NCU tlbie quiesce + // Assert L2+NCU Purge and NCU tlbie quiesce + // (chtm purge will be done in SGPE), + // insert tlbie quiesce before ncu purge to avoid window condition + // of ncu traffic still happening when purging starts PK_TRACE("SE5.1a"); - out32(CME_LCL_SICR_OR, BIT32(18) | BIT32(21) | BIT32(22)); + out32(CME_LCL_SICR_OR, BIT32(18) | BIT32(21)); + out32(CME_LCL_SICR_OR, BIT32(22)); // todo: poll for tlbie quiesce done? @@ -722,12 +745,23 @@ p9_cme_stop_entry() { #if !SKIP_L2_PURGE_ABORT - if(in32(CME_LCL_EINR) & BITS32(12, 6)) + if (!core_aborted && + (in32(CME_LCL_EINR) & BITS32(12, 6))) { + if (in32(CME_LCL_EINR) & IRQ_VEC_WAKE_C0) + { + core_aborted |= CME_MASK_C0; + } - //=============================== - MARK_TAG(SE_PURGE_L2_ABORT, core) - //=============================== + if (in32(CME_LCL_EINR) & IRQ_VEC_WAKE_C1) + { + core_aborted |= CME_MASK_C1; + } + + PK_TRACE("L2 Purge aborted by core[%d]", core_aborted); + //======================================= + MARK_TAG(SE_PURGE_L2_ABORT, core_aborted) + //======================================= // abort L2+NCU purges out32(CME_LCL_SICR_OR, BIT32(19) | BIT32(23)); } @@ -736,15 +770,24 @@ p9_cme_stop_entry() } while((in32(CME_LCL_EISR) & BITS32(22, 2)) != BITS32(22, 2)); - // Deassert L2+NCU Purges, their possible aborts, NCU tlbie quiesce + // Deassert L2+NCU Purges, their possible aborts PK_TRACE("SE5.1c"); - out32(CME_LCL_SICR_CLR, BITS32(18, 6)); + out32(CME_LCL_SICR_CLR, (BITS32(18, 2) | BITS32(22, 2))); PK_TRACE("SE5.1: L2/NCU/CHTM Purged"); - //============================== - MARK_TAG(SE_PURGE_L2_DONE, core) - //============================== + //=============================================================== + MARK_TAG(SE_PURGE_L2_DONE, core_aborted ? core_aborted : CME_MASK_BC) + //=============================================================== + + if (core != core_aborted) + { + core &= ~core_aborted; + } + else + { + break; + } } //============================= 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 c38399a7..83cee38d 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 @@ -32,21 +32,21 @@ extern CmeStopRecord G_cme_stop_record; int p9_cme_stop_exit() { - int rc = 0; int d2u4_flag = 0; int catchup_ongoing = 0; uint8_t target_level; uint8_t deeper_level = 0; uint32_t deeper_core = 0; uint32_t wakeup; - uint32_t pcwu; - uint32_t spwu; - uint32_t rgwu; uint32_t core; +#if !SPWU_AUTO + uint32_t spwu_stop; + uint32_t spwu_wake; +#endif #if !SKIP_EXIT_CATCHUP + uint8_t catchup_level; uint32_t core_catchup; #endif - //uint32_t grant; ppm_sshsrc_t hist; //-------------------------------------------------------------------------- @@ -55,44 +55,54 @@ p9_cme_stop_exit() // extract wakeup signals, clear status, and mask wakeup interrupts wakeup = (in32(CME_LCL_EISR) >> SHIFT32(17)) & 0x3F; - out32(CME_LCL_EISR_CLR, (wakeup << SHIFT32(17)) | BITS32(24, 2)); - out32_sh(CME_LCL_EISR_CLR, (in32_sh(CME_LCL_EISR) & BITS32(8, 2))); - - // build the core select for wakeup - pcwu = (wakeup >> 4) & CME_MASK_BC; - spwu = (wakeup >> 2) & CME_MASK_BC; - rgwu = (wakeup >> 0) & CME_MASK_BC; - core = pcwu | spwu | rgwu; + core = ((wakeup >> 4) | (wakeup >> 2) | wakeup) & CME_MASK_BC; // override with partial good core mask - core = core & G_cme_stop_record.core_enabled; + // also ignore wakeup to running cores + core = core & G_cme_stop_record.core_enabled & + (~G_cme_stop_record.core_running); + + PK_TRACE("X0: Core Select[%d] Wakeup[%x] Actual Stop Levels[%d %d]", + core, wakeup, + G_cme_stop_record.act_level_c0, + G_cme_stop_record.act_level_c1); + +#if !SPWU_AUTO + spwu_stop = (wakeup >> 2) & G_cme_stop_record.core_enabled; + spwu_wake = spwu_stop & G_cme_stop_record.core_running; + spwu_stop = spwu_stop & (~G_cme_stop_record.core_running); - PK_TRACE("X0: Core Select[%d], pcwu[%d], spwu[%d], rgwu[%d]", - core, pcwu, spwu, rgwu); + if (spwu_wake) + { + out32(CME_LCL_SICR_OR, spwu << SHIFT32(17)); + } + +#endif // Code Error: function should never be entered without wakeup source active if (!core) { - PK_TRACE("Error: no wakeup fired"); - pk_halt(); +#if !SPWU_AUTO + + if (!spwu_wake) + { +#endif + PK_TRACE("Error: no wakeup fired"); + pk_halt(); +#if !SPWU_AUTO + } + else + { + return CME_STOP_SUCCESS; + } + +#endif } //================================== MARK_TAG(BEGINSCOPE_STOP_EXIT, core) //================================== - PK_TRACE("X0: Actual Stop Levels[%d %d]", - G_cme_stop_record.act_level_c0, G_cme_stop_record.act_level_c1); - - // Code Error: by default stop 1 auto wakeup should be enabled - if ((core == CME_MASK_C0 && G_cme_stop_record.act_level_c0 < 2) || - (core == CME_MASK_C1 && G_cme_stop_record.act_level_c1 < 2) || - (core == CME_MASK_BC && (G_cme_stop_record.act_level_c0 < 2 || - G_cme_stop_record.act_level_c1 < 2))) - { - pk_halt(); - } - // set target_level to STOP level for c0 // unless c1(also or only) wants to wakeup target_level = deeper_level = @@ -120,6 +130,13 @@ p9_cme_stop_exit() PK_TRACE("X0: target_lv[%d], deeper_lv[%d], deeper_c[%d]", target_level, deeper_level, deeper_core); + // ensure PCB Mux grant is present for all cores that wants to wakeup + // only stop 11 needs to request for new grant + out32(CME_LCL_SICR_OR, (core << SHIFT32(11))); + + // chtm purge done + out32(CME_LCL_EISR_CLR, (core << SHIFT32(25))); + PK_TRACE("X0: Update STOP History: In Transition of Exit"); CME_STOP_UPDATE_HISTORY(core, STOP_CORE_IS_GATED, @@ -129,21 +146,10 @@ p9_cme_stop_exit() STOP_REQ_DISABLE, STOP_ACT_DISABLE); - // ensure PCB Mux grant is present for all cores that wants to wakeup - // only stop 11 needs to request for new grant - //if (!(grant=(core & (in32(CME_LCL_SISR) >> SHIFT32(11))))) { PK_TRACE("X0: Check and Request PCB Mux"); - // if (((~grant & CME_MASK_C0 & core) && - // (G_cme_stop_record.pm_state_c0 < 11)) || - // ((~grant & CME_MASK_C1 & core) && - // (G_cme_stop_record.pm_state_c1 < 11))) - // pk_halt(); - out32(CME_LCL_SICR_OR, core << SHIFT32(11)); while((core & (in32(CME_LCL_SISR) >> SHIFT32(11))) != core); - //} - //-------------------------------------------------------------------------- // STOP LEVEL 4 //-------------------------------------------------------------------------- @@ -162,16 +168,12 @@ p9_cme_stop_exit() do //catchup loop { -#if !SKIP_BCE - PK_TRACE("BCE Runtime Kickoff"); +#if !SKIP_BCE_SCOM_RESTORE + PK_TRACE("BCE Runtime Kickoff: copy scom restore"); //right now a blocking call. Need to confirm this. - instance_scan_init(); + instance_scom_restore(); #endif - // todo for catch up case - //PK_TRACE("X1: Request PCB Arbiter"); - //p9_hcd_core_pcb_arb(core, 1); - //======================== MARK_TAG(SX_POWERON, core) //======================== @@ -189,7 +191,6 @@ p9_cme_stop_exit() #if !STOP_PRIME #if !SKIP_EXIT_CATCHUP - //catchup if (catchup_ongoing) { core = CME_MASK_BC; @@ -198,49 +199,61 @@ p9_cme_stop_exit() else { wakeup = (in32(CME_LCL_EISR) >> SHIFT32(17)) & 0x3F; - out32(CME_LCL_EISR_CLR, wakeup << SHIFT32(17)); - core_catchup = - ((wakeup >> 4) | (wakeup >> 2) | (wakeup >> 0)) & - CME_MASK_BC; + core_catchup = (~core) & + ((wakeup >> 4) | (wakeup >> 2) | wakeup); + core_catchup = core_catchup & G_cme_stop_record.core_enabled & + (~G_cme_stop_record.core_running); - if (core_catchup && (core_catchup + core) == CME_MASK_BC) + if (core_catchup) { - out32(CME_LCL_SICR_OR, core_catchup << SHIFT32(11)); + //================================== + MARK_TAG(SX_CATCHUP_B, core_catchup) + //================================== + + // pcbmux grant + out32(CME_LCL_SICR_OR, (core_catchup << SHIFT32(11))); + // chtm purge done + out32(CME_LCL_EISR_CLR, (core_catchup << SHIFT32(25))); + + CME_STOP_UPDATE_HISTORY(core_catchup, + STOP_CORE_IS_GATED, + STOP_TRANS_EXIT, + STOP_LEVEL_0, + STOP_LEVEL_0, + STOP_REQ_DISABLE, + STOP_ACT_DISABLE); + + catchup_level = (core_catchup & CME_MASK_C0) ? + G_cme_stop_record.act_level_c0 : + G_cme_stop_record.act_level_c1 ; + + PK_TRACE("core[%d] running[%d] core_catchup[%d] catchup_level[%d]", + core, G_cme_stop_record.core_running, + core_catchup, catchup_level); - if(((core_catchup & CME_MASK_C0) && - G_cme_stop_record.act_level_c0 == STOP_LEVEL_2) || - ((core_catchup & CME_MASK_C1) && - G_cme_stop_record.act_level_c1 == STOP_LEVEL_2)) + while((core_catchup & (in32(CME_LCL_SISR) >> + SHIFT32(11))) != core_catchup); + + if (catchup_level < STOP_LEVEL_4) { - deeper_core = core; - d2u4_flag = 1; + deeper_core = core; + d2u4_flag = 1; } - else if(((core_catchup & CME_MASK_C0) && - G_cme_stop_record.act_level_c0 == STOP_LEVEL_4) || - ((core_catchup & CME_MASK_C1) && - G_cme_stop_record.act_level_c1 == STOP_LEVEL_4)) + else { core = core_catchup; catchup_ongoing = 1; continue; } - - while((core_catchup & (in32(CME_LCL_SISR) >> - SHIFT32(11))) != core_catchup); } - - //========================== - MARK_TAG(SX_CATCHUP_A, core) - //========================== } #endif -#if !SKIP_INITF //============================== MARK_TAG(SX_CHIPLET_INITS, core) //============================== - +#if !SKIP_INITF PK_TRACE("X3: Core GPTR Time Initf"); p9_hcd_core_gptr_time_initf(core); #endif @@ -255,7 +268,6 @@ p9_cme_stop_exit() #if !SKIP_EXIT_CATCHUP - //catchup if (catchup_ongoing) { core = CME_MASK_BC; @@ -264,58 +276,69 @@ p9_cme_stop_exit() else { wakeup = (in32(CME_LCL_EISR) >> SHIFT32(17)) & 0x3F; - out32(CME_LCL_EISR_CLR, wakeup << SHIFT32(17)); - core_catchup = - ((wakeup >> 4) | (wakeup >> 2) | (wakeup >> 0)) & - CME_MASK_BC; + core_catchup = (~core) & + ((wakeup >> 4) | (wakeup >> 2) | wakeup); + core_catchup = core_catchup & G_cme_stop_record.core_enabled & + (~G_cme_stop_record.core_running); - if (core_catchup && (core_catchup + core) == CME_MASK_BC) + if (core_catchup) { - out32(CME_LCL_SICR_OR, core_catchup << SHIFT32(11)); + //================================== + MARK_TAG(SX_CATCHUP_B, core_catchup) + //================================== + + // pcbmux grant + out32(CME_LCL_SICR_OR, (core_catchup << SHIFT32(11))); + // chtm purge done + out32(CME_LCL_EISR_CLR, (core_catchup << SHIFT32(25))); + + CME_STOP_UPDATE_HISTORY(core_catchup, + STOP_CORE_IS_GATED, + STOP_TRANS_EXIT, + STOP_LEVEL_0, + STOP_LEVEL_0, + STOP_REQ_DISABLE, + STOP_ACT_DISABLE); + + catchup_level = (core_catchup & CME_MASK_C0) ? + G_cme_stop_record.act_level_c0 : + G_cme_stop_record.act_level_c1 ; + + PK_TRACE("core[%d] running[%d] core_catchup[%d] catchup_level[%d]", + core, G_cme_stop_record.core_running, + core_catchup, catchup_level); - if(((core_catchup & CME_MASK_C0) && - G_cme_stop_record.act_level_c0 == STOP_LEVEL_2) || - ((core_catchup & CME_MASK_C1) && - G_cme_stop_record.act_level_c1 == STOP_LEVEL_2)) + while((core_catchup & (in32(CME_LCL_SISR) >> + SHIFT32(11))) != core_catchup); + + if (catchup_level < STOP_LEVEL_4) { - deeper_core = core; - d2u4_flag = 1; + deeper_core = core; + d2u4_flag = 1; } - else if(((core_catchup & CME_MASK_C0) && - G_cme_stop_record.act_level_c0 == STOP_LEVEL_4) || - ((core_catchup & CME_MASK_C1) && - G_cme_stop_record.act_level_c1 == STOP_LEVEL_4)) + else { core = core_catchup; catchup_ongoing = 1; continue; } - - while((core_catchup & (in32(CME_LCL_SISR) >> - SHIFT32(11))) != core_catchup); } - - //========================== - MARK_TAG(SX_CATCHUP_B, core) - //========================== } #endif -#if !SKIP_ARY_INIT //=========================== MARK_TAG(SX_ARRAY_INIT, core) //=========================== - +#if !SKIP_ARRAYINIT PK_TRACE("X7: Core Array Init"); p9_hcd_core_arrayinit(core); #endif -#if !SKIP_INITF //===================== MARK_TRAP(SX_FUNC_INIT) //===================== - +#if !SKIP_INITF PK_TRACE("X8: Core Func Scan"); p9_hcd_core_initf(core); #endif @@ -333,17 +356,18 @@ p9_cme_stop_exit() //-------------------------------------------------------------------------- // STOP LEVEL 3 //-------------------------------------------------------------------------- - if (deeper_level == STOP_LEVEL_3 || target_level == STOP_LEVEL_3) - { - //====================== - MARK_TAG(SX_STOP3, core) - //====================== - - PK_TRACE("STOP Level 3 Sequence"); - //Return to full voltage - //disable ivrm? - } + /* + if (deeper_level == STOP_LEVEL_3 || target_level == STOP_LEVEL_3) + { + //====================== + MARK_TAG(SX_STOP3, core) + //====================== + PK_TRACE("STOP Level 3 Sequence"); + //Return to full voltage + //disable ivrm? + } + */ //-------------------------------------------------------------------------- // STOP LEVEL 2 //-------------------------------------------------------------------------- @@ -352,6 +376,11 @@ p9_cme_stop_exit() 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); @@ -383,22 +412,19 @@ p9_cme_stop_exit() MARK_TAG(SX_BCE_CHECK, core) //========================== -#if !SKIP_BCE +#if !SKIP_BCE_SCOM_RESTORE PK_TRACE("BCE Runtime Check"); if( BLOCK_COPY_SUCCESS != isScanRingCopyDone() ) { - PK_TRACE("BC2: Copy of Instance Specific Scan ring failed"); - // TODO should return an error code. + PK_TRACE("BCE: Copy of scom restore failed"); + pk_halt(); } + PK_TRACE("X11: XIP Customized Scoms"); + p9_hcd_core_scomcust(core); #endif - // todo - //PK_TRACE("X11: XIP Customized Scoms"); - //MARK_TRAP(SX_SCOMCUST) - //p9_hcd_core_scomcust(core); - //============================== MARK_TAG(SX_RUNTIME_INITS, core) //============================== @@ -422,8 +448,6 @@ p9_cme_stop_exit() PK_TRACE("Raise block interrupt to PC"); out32(CME_LCL_SICR_OR, core << SHIFT32(3)); - PK_TRACE("RAM HRMOR"); - PK_TRACE("Now Wakeup the Core(pm_exit=1)"); out32(CME_LCL_SICR_OR, core << SHIFT32(5)); @@ -431,6 +455,55 @@ p9_cme_stop_exit() while((in32(CME_LCL_EINR)) & (core << SHIFT32(21))); +#if !SKIP_RAM_HRMOR + PK_TRACE("Activate Thread0 for RAM"); + CME_PUTSCOM(THREAD_INFO, core, BIT64(18)); + + PK_TRACE("Enable RAM mode"); + CME_PUTSCOM(RAM_MODEREG, core, BIT64(0)); + + PK_TRACE("Set SPR mode to LT0-7"); + CME_PUTSCOM(SPR_MODE, core, BITS64(20, 8)); + + if (core & CME_MASK_C0) + { + PK_TRACE("Set SPRC to Scratch0 for core0"); + CME_PUTSCOM(SCOM_SPRC, CME_MASK_C0, 0); + + PK_TRACE("Load Scratch0 with HOMER+2MB"); +#if EPM_P9_TUNING + CME_PUTSCOM(SCRACTH0, CME_MASK_C0, 0x200000); +#else + CME_PUTSCOM(SCRACTH0, CME_MASK_C0, int64(SELF_RESTORE_ADDR_FETCH)); +#endif + } + + if (core & CME_MASK_C1) + { + PK_TRACE("Set SPRC to Scratch1 for core1"); + CME_PUTSCOM(SCOM_SPRC, CME_MASK_C1, BIT64(60)); + + PK_TRACE("Load Scratch1 with HOMER+2MB"); +#if EPM_P9_TUNING + CME_PUTSCOM(SCRACTH1, CME_MASK_C1, 0x200000); +#else + CME_PUTSCOM(SCRACTH1, CME_MASK_C1, int64(SELF_RESTORE_ADDR_FETCH)); +#endif + } + + PK_TRACE("RAM: mfspr sprd , gpr0"); + CME_PUTSCOM(RAM_CTRL, core, RAM_MFSPR_SPRD_GPR0); + + PK_TRACE("RAM: mtspr hrmor, gpr0"); + CME_PUTSCOM(RAM_CTRL, core, RAM_MTSPR_HRMOR_GPR0); + + PK_TRACE("Disable Thread0 for RAM"); + CME_PUTSCOM(THREAD_INFO, core, 0); + + PK_TRACE("Disable RAM mode"); + CME_PUTSCOM(RAM_MODEREG, core, 0); +#endif + PK_TRACE("S-Reset all threads"); CME_PUTSCOM(DIRECT_CONTROLS, core, BIT64(4) | BIT64(12) | BIT64(20) | BIT64(28)); @@ -444,19 +517,14 @@ p9_cme_stop_exit() PK_TRACE("Poll for Core stop again(pm_active=1)"); - while((~(in32(CME_LCL_EINR))) & (core << SHIFT32(21))); - - //PK_TRACE("Restore PSSCR back to actual level"); - //PLS here: - if (core & CME_MASK_C0) - CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C0, - (((uint64_t)G_cme_stop_record.act_level_c0 << - SHIFT64(36)) | BIT64(32))); - - if (core & CME_MASK_C1) - CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C1, - (((uint64_t)G_cme_stop_record.act_level_c1 << - SHIFT64(36)) | BIT64(32))); + while((~(in32(CME_LCL_EINR))) & (core << SHIFT32(21))) + { + if (in32_sh(CME_LCL_SISR) & (core << SHIFT32(1))) + { + PK_TRACE("Error: Core Special Attention Detected"); + pk_halt(); + } + } PK_TRACE("Drop block interrupt to PC"); out32(CME_LCL_SICR_CLR, core << SHIFT32(3)); @@ -476,6 +544,78 @@ p9_cme_stop_exit() // END OF STOP EXIT //-------------------------------------------------------------------------- + PK_TRACE("Restore PSSCR.PLS+SRR1 back to actual level"); + + if (core & CME_MASK_C0) + { + CME_GETSCOM(PPM_SSHSRC, CME_MASK_C0, CME_SCOM_AND, hist.value); + + if (hist.fields.act_stop_level >= STOP_LEVEL_8) + { + CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C0, CME_STOP_UPDATE_PLS_SRR1( + hist.fields.act_stop_level, + MOST_STATE_LOSS, MOST_STATE_LOSS, + MOST_STATE_LOSS, MOST_STATE_LOSS)); + } + else if (hist.fields.act_stop_level >= STOP_LEVEL_4) + { + CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C0, CME_STOP_UPDATE_PLS_SRR1( + hist.fields.act_stop_level, + SOME_STATE_LOSS_BUT_NOT_TIMEBASE, + SOME_STATE_LOSS_BUT_NOT_TIMEBASE, + SOME_STATE_LOSS_BUT_NOT_TIMEBASE, + SOME_STATE_LOSS_BUT_NOT_TIMEBASE)); + } + else + { + CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C0, CME_STOP_UPDATE_PLS_SRR1( + hist.fields.act_stop_level, + ((in32(CME_LCL_PSCRS00) & BIT32(2)) ? + SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS), + ((in32(CME_LCL_PSCRS10) & BIT32(2)) ? + SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS), + ((in32(CME_LCL_PSCRS20) & BIT32(2)) ? + SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS), + ((in32(CME_LCL_PSCRS30) & BIT32(2)) ? + SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS))); + } + } + + if (core & CME_MASK_C1) + { + CME_GETSCOM(PPM_SSHSRC, CME_MASK_C1, CME_SCOM_AND, hist.value); + + if (hist.fields.act_stop_level >= STOP_LEVEL_8) + { + CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C1, CME_STOP_UPDATE_PLS_SRR1( + hist.fields.act_stop_level, + MOST_STATE_LOSS, MOST_STATE_LOSS, + MOST_STATE_LOSS, MOST_STATE_LOSS)); + } + else if(hist.fields.act_stop_level >= STOP_LEVEL_4) + { + CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C1, CME_STOP_UPDATE_PLS_SRR1( + hist.fields.act_stop_level, + SOME_STATE_LOSS_BUT_NOT_TIMEBASE, + SOME_STATE_LOSS_BUT_NOT_TIMEBASE, + SOME_STATE_LOSS_BUT_NOT_TIMEBASE, + SOME_STATE_LOSS_BUT_NOT_TIMEBASE)); + } + else + { + CME_PUTSCOM(DIRECT_CONTROLS, CME_MASK_C1, CME_STOP_UPDATE_PLS_SRR1( + hist.fields.act_stop_level, + ((in32(CME_LCL_PSCRS01) & BIT32(2)) ? + SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS), + ((in32(CME_LCL_PSCRS11) & BIT32(2)) ? + SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS), + ((in32(CME_LCL_PSCRS21) & BIT32(2)) ? + SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS), + ((in32(CME_LCL_PSCRS31) & BIT32(2)) ? + SOME_STATE_LOSS_BUT_NOT_TIMEBASE : NO_STATE_LOSS))); + } + } + PK_TRACE("XF: Now Wakeup the Core(pm_exit=1)"); out32(CME_LCL_SICR_OR, core << SHIFT32(5)); @@ -499,7 +639,10 @@ p9_cme_stop_exit() G_cme_stop_record.core_running |= core; G_cme_stop_record.core_stopgpe &= ~core; - out32(CME_LCL_LMCR_CLR, ((core << SHIFT32(13)) | (core << SHIFT32(15)))); +#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) { @@ -514,7 +657,22 @@ p9_cme_stop_exit() } PK_TRACE("XF: Drop pm_exit to allow core to run if spwu is not present"); + +#if SPWU_AUTO out32(CME_LCL_SICR_CLR, core << SHIFT32(5)); +#else + + if (spwu_stop) + { + out32(CME_LCL_SICR_OR, spwu << SHIFT32(17)); + } + + if ((core = (core & (~spwu_stop)))) + { + out32(CME_LCL_SICR_CLR, core << SHIFT32(5)); + } + +#endif //=========================== MARK_TRAP(ENDSCOPE_STOP_EXIT) diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit_marks.h b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit_marks.h index 19ebdb92..ef1a3700 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit_marks.h +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit_marks.h @@ -50,12 +50,13 @@ enum CME_SX_MARKS SX_STARTCLOCKS = 0x120, SX_STARTCLOCKS_ALIGN = 0x128, SX_STARTCLOCKS_REGION = 0x130, - SX_SCOM_INITS = 0x138, - SX_BCE_CHECK = 0x140, - SX_RUNTIME_INITS = 0x148, - SX_SELF_RESTORE = 0x150, - SX_SRESET_THREADS = 0x168, - SX_ENABLE_ANALOG = 0x1e0 + SX_STARTCLOCKS_DONE = 0x138, + SX_SCOM_INITS = 0x140, + SX_BCE_CHECK = 0x148, + SX_RUNTIME_INITS = 0x150, + SX_SELF_RESTORE = 0x168, + SX_SRESET_THREADS = 0x1e0, + SX_ENABLE_ANALOG = 0x1e8 }; @@ -77,6 +78,7 @@ const std::vector<CME_SX_MARKS> MARKS = SX_STARTCLOCKS, SX_STARTCLOCKS_ALIGN, SX_STARTCLOCKS_REGION, + SX_STARTCLOCKS_DONE, SX_SCOM_INITS, SX_BCE_CHECK, SX_RUNTIME_INITS, @@ -85,6 +87,29 @@ const std::vector<CME_SX_MARKS> MARKS = SX_ENABLE_ANALOG }; +const std::map<CME_SX_MARKS, std::string> mMARKS = boost::assign::map_list_of + (BEGINSCOPE_STOP_EXIT, "BEGINSCOPE_STOP_EXIT") + (ENDSCOPE_STOP_EXIT, "ENDSCOPE_STOP_EXIT") + (SX_STOP3, "SX_STOP3") + (SX_POWERON, "SX_POWERON") + (SX_CHIPLET_RESET, "SX_CHIPLET_RESET") + (SX_CHIPLET_RESET_SCAN0, "SX_CHIPLET_RESET_SCAN0") + (SX_CATCHUP_A, "SX_CATCHUP_A") + (SX_CHIPLET_INITS, "SX_CHIPLET_INITS") + (SX_CATCHUP_B, "SX_CATCHUP_B") + (SX_ARRAY_INIT, "SX_ARRAY_INIT") + (SX_FUNC_INIT, "SX_FUNC_INIT") + (SX_STARTCLOCKS, "SX_STARTCLOCKS") + (SX_STARTCLOCKS_ALIGN, "SX_STARTCLOCKS_ALIGN") + (SX_STARTCLOCKS_REGION, "SX_STARTCLOCKS_REGION") + (SX_STARTCLOCKS_DONE, "SX_STARTCLOCKS_DONE") + (SX_SCOM_INITS, "SX_SCOM_INITS") + (SX_BCE_CHECK, "SX_BCE_CHECK") + (SX_RUNTIME_INITS, "SX_RUNTIME_INITS") + (SX_SELF_RESTORE, "SX_SELF_RESTORE") + (SX_SRESET_THREADS, "SX_SRESET_THREADS") + (SX_ENABLE_ANALOG, "SX_ENABLE_ANALOG"); + } #endif 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 64bd14cd..89b9d4f8 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 @@ -59,24 +59,8 @@ p9_cme_stop_event_handler(void* arg, PkIrqId irq) void p9_cme_stop_doorbell_handler(void* arg, PkIrqId irq) { - uint32_t db1; PkMachineContext ctx; - MARK_TRAP(STOP_DOORBELL_HANDLER) PK_TRACE("DB-IRQ: %d", irq); - - db1 = in32_sh(CME_LCL_EISR); - g_eimr_override |= BITS64(40, 2); - - if (db1 & BIT32(8)) - { - g_eimr_override &= ~IRQ_VEC_WAKE_C0; - } - - if (db1 & BIT32(9)) - { - g_eimr_override &= ~IRQ_VEC_WAKE_C1; - } - pk_irq_vec_restore(&ctx); } diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_arrayinit.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_arrayinit.c index b64f30b9..81a9e462 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_arrayinit.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_arrayinit.c @@ -30,63 +30,78 @@ int p9_hcd_core_arrayinit(uint32_t core) { int rc = CME_STOP_SUCCESS; - /* @todo minic arrayinit module - uint64_t scom_data; - - PK_TRACE("Setup ABISTMUX_SEL"); - CME_PUTSCOM(PERV_CPLT_CTRL0_OR, core, BIT64(0)); - - PK_TRACE("setup ABIST modes"); - CME_GETSCOM(PERV_BIST, core, CME_SCOM_OR, scom_data); - scom_data &= ~BIT64(0) ; - scom_data |= BITS64(1, 2); - scom_data |= BITS64(6, 2); - CME_PUTSCOM(PERV_BIST, core, scom_data); - - PK_TRACE("Setup all Clock Domains and Clock Types"); - CME_GETSCOM(PERV_CLK_REGION, core, CME_SCOM_OR, scom_data); - scom_data |= BITS64(6, 2); - scom_data |= BITS64(48, 3); - CME_PUTSCOM(PERV_CLK_REGION, core, scom_data); - - PK_TRACE("Setup: loopcount , OPCG engine start ABIST, run-N mode"); - CME_GETSCOM(PERV_OPCG_REG0, core, CME_SCOM_OR, scom_data); - scom_data = 0x8002000000042FFF; - CME_PUTSCOM(PERV_OPCG_REG0, core, scom_data); - - PK_TRACE("Setup IDLE count"); - CME_GETSCOM(PERV_OPCG_REG1, core, CME_SCOM_OR, scom_data); - scom_data &= 0x000000000FFFFFFF; - scom_data |= 0x0000000F00000000; - CME_PUTSCOM(PERV_OPCG_REG1, core, scom_data); - - PK_TRACE("opcg go"); - CME_GETSCOM(PERV_OPCG_REG0, core, CME_SCOM_OR, scom_data); - scom_data |= BIT64(1); - CME_PUTSCOM(PERV_OPCG_REG0, core, scom_data); - - PK_TRACE("Poll OPCG done bit to check for run-N completeness"); - - do - { - CME_GETSCOM(PERV_CPLT_STAT0, core, CME_SCOM_AND, scom_data); - } - while(!(scom_data & BIT64(8))); - - PK_TRACE("OPCG done, clear Run-N mode"); - CME_GETSCOM(PERV_OPCG_REG0, core, CME_SCOM_OR, scom_data); - scom_data &= ~(BIT64(0) | BIT64(14) | BITS64(21, 43)); - CME_PUTSCOM(PERV_OPCG_REG0, core, scom_data); - - PK_TRACE("clear all clock REGIONS and type"); - CME_PUTSCOM(PERV_CLK_REGION, core, 0); - - PK_TRACE("clear ABISTCLK_MUXSEL"); - CME_PUTSCOM(PERV_CPLT_CTRL0_CLEAR, core, BIT64(0)); - - PK_TRACE("clear BIST REGISTER"); - CME_PUTSCOM(PERV_BIST, core, 0); - */ + uint64_t scom_data; + + /// @todo add DD1 attribute control + PK_TRACE("DD1 only: set sdis_n(flushing LCBES condition workaround"); + CME_PUTSCOM(C_CPLT_CONF0_OR, core, BIT64(34)); + + PK_TRACE("Drop vital fence (moved to arrayinit from sacn0 module)"); + CME_PUTSCOM(PERV_CPLT_CTRL1_CLEAR, core, BIT64(3)); + + PK_TRACE("Setup ABISTMUX_SEL"); + CME_PUTSCOM(PERV_CPLT_CTRL0_OR, core, BIT64(0)); + + PK_TRACE("setup ABIST modes"); + CME_GETSCOM(PERV_BIST, core, CME_SCOM_AND, scom_data); + scom_data &= ~BIT64(0); + scom_data |= BIT64(1); // select_sram = 1 + scom_data &= ~BIT64(2); // select_edram = 0 + scom_data |= BITS64(4, 11); // regions = 0x7FF + CME_PUTSCOM(PERV_BIST, core, scom_data); + + PK_TRACE("Setup all Clock Domains and Clock Types"); + CME_GETSCOM(PERV_CLK_REGION, core, CME_SCOM_AND, scom_data); + scom_data |= (BITS64(4, 11) | BITS64(48, 3));// regions = 0x7FF + CME_PUTSCOM(PERV_CLK_REGION, core, scom_data); + + PK_TRACE("Drop Region fences"); + CME_PUTSCOM(PERV_CPLT_CTRL1_CLEAR, core, BITS64(4, 11)); + + PK_TRACE("Setup: loopcount , OPCG engine start ABIST, run-N mode"); + CME_GETSCOM(PERV_OPCG_REG0, core, CME_SCOM_AND, scom_data); + scom_data |= 0x8002000000042FFF; // b0 = 1 b14 = 1 loop_counter = 0x42FFF + CME_PUTSCOM(PERV_OPCG_REG0, core, scom_data); + + PK_TRACE("Setup IDLE count"); + CME_GETSCOM(PERV_OPCG_REG1, core, CME_SCOM_AND, scom_data); + scom_data |= 0x0000000F00000000; //scan_count|misr_a_valur|misr_b_value + CME_PUTSCOM(PERV_OPCG_REG1, core, scom_data); + + PK_TRACE("opcg go"); + CME_GETSCOM(PERV_OPCG_REG0, core, CME_SCOM_AND, scom_data); + scom_data |= BIT64(1); + CME_PUTSCOM(PERV_OPCG_REG0, core, scom_data); + + PK_TRACE("Poll OPCG done bit to check for run-N completeness"); + + do + { + CME_GETSCOM(PERV_CPLT_STAT0, core, CME_SCOM_AND, scom_data); + } + while(!(scom_data & BIT64(8))); + + PK_TRACE("OPCG done, clear Run-N mode"); + CME_GETSCOM(PERV_OPCG_REG0, core, CME_SCOM_AND, scom_data); + scom_data &= ~(BIT64(0) | BIT64(14) | BITS64(21, 43)); + CME_PUTSCOM(PERV_OPCG_REG0, core, scom_data); + + PK_TRACE("clear all clock REGIONS and type"); + CME_PUTSCOM(PERV_CLK_REGION, core, 0); + + PK_TRACE("clear ABISTCLK_MUXSEL"); + CME_PUTSCOM(PERV_CPLT_CTRL0_CLEAR, core, BIT64(0)); + + PK_TRACE("clear BIST REGISTER"); + CME_PUTSCOM(PERV_BIST, core, 0); + +#if !SKIP_SCAN0 + p9_hcd_core_scan0(core, SCAN0_REGION_ALL_BUT_PLL, SCAN0_TYPE_ALL_BUT_GPTR_REPR_TIME); +#endif + + /// @todo add DD1 attribute control + PK_TRACE("DD1 only: reset sdis_n(flushing LCBES condition workaround"); + CME_PUTSCOM(C_CPLT_CONF0_CLEAR, core, BIT64(34)); return rc; } diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_chiplet_reset.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_chiplet_reset.c index a97ac8da..1e118429 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_chiplet_reset.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_chiplet_reset.c @@ -26,6 +26,26 @@ #include "p9_cme_stop.h" #include "p9_cme_stop_exit_marks.h" +enum P9_HCD_CORE_CHIPLET_RESET_CONSTANTS +{ + // (1)PCB_EP_RESET + // (2)CLK_ASYNC_RESET + // (3)PLL_TEST_EN + // (4)PLLRST + // (5)PLLBYP + // (11)EDIS + // (12)VITL_MPW1 + // (13)VITL_MPW2 + // (14)VITL_MPW3 + // (16)VITL_THOLD + // (18)FENCE_EN + // (22)FUNC_CLKSEL + // (25)PCB_FENCE + // (26)LVLTRANS_FENCE + C_NET_CTRL0_INIT_VECTOR = (BIT64(1) | BITS64(3, 3) | BITS64(11, 4) | + BIT64(16) | BIT64(18) | BIT64(22) | BITS64(25, 2)) +}; + int p9_hcd_core_chiplet_reset(uint32_t core) { @@ -33,7 +53,7 @@ p9_hcd_core_chiplet_reset(uint32_t core) //uint64_t scom_data, uint32_t loop; - PK_TRACE("Init NET_CTRL0[1,3-5,11-14,18,22,26],step needed for hotplug"); + PK_TRACE("Init NET_CTRL0[1,3-5,11-14,16,18,22,25,26],step needed for hotplug"); CME_PUTSCOM(CPPM_NC0INDIR_OR, core, C_NET_CTRL0_INIT_VECTOR); CME_PUTSCOM(CPPM_NC0INDIR_CLR, core, ~(C_NET_CTRL0_INIT_VECTOR | BIT64(2))); @@ -48,10 +68,11 @@ p9_hcd_core_chiplet_reset(uint32_t core) PK_TRACE("Drop core glsmux reset via PPM_CGCR[0]"); CME_PUTSCOM(C_PPM_CGCR, core, 0); - PPE_WAIT_CORE_CYCLES(loop, 400); PK_TRACE("Flip core glsmux to DPLL via PPM_CGCR[3]"); CME_PUTSCOM(C_PPM_CGCR, core, BIT64(3)); + // 200 core clocks + PPE_WAIT_CORE_CYCLES(loop, 200); PK_TRACE("Assert chiplet enable via NET_CTRL0[0]"); CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(0)); @@ -65,10 +86,16 @@ p9_hcd_core_chiplet_reset(uint32_t core) PK_TRACE("Drop PCB fence via NET_CTRL0[25]"); CME_PUTSCOM(CPPM_NC0INDIR_CLR, core, BIT64(25)); -#if !SKIP_SCAN0 // Marker for scan0 MARK_TRAP(SX_CHIPLET_RESET_SCAN0) +#if !SKIP_SCAN0 + p9_hcd_core_scan0(core, SCAN0_REGION_ALL, SCAN0_TYPE_GPTR_REPR_TIME); + p9_hcd_core_scan0(core, SCAN0_REGION_ALL, SCAN0_TYPE_ALL_BUT_GPTR_REPR_TIME); #endif + /// @todo add VDM_ENABLE attribute control + PK_TRACE("Assert vdm enable via CPPM_VDMCR[0]"); + CME_PUTSCOM(PPM_VDMCR_OR, core, BIT64(0)); + return rc; } diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_poweron.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_poweron.c index b2a1acb2..4a091106 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_poweron.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_poweron.c @@ -54,17 +54,36 @@ p9_hcd_core_poweron(uint32_t core) PK_TRACE("Prepare PFET Controls"); CME_PUTSCOM(PPM_PFCS_CLR, core, BIT64(4) | BIT64(5) | BIT64(8)); - // vdd_pfet_force_state = 11 (Force Von) - PK_TRACE("Power Off Core VDD"); - CME_PUTSCOM(PPM_PFCS_OR, core, BITS64(0, 2)); + // Serialize only the PFET power-on for the Core Pair + if (core & CME_MASK_C0) + { + // vdd_pfet_force_state = 11 (Force Von) + PK_TRACE("Power Off Core VDD"); + CME_PUTSCOM(PPM_PFCS_OR, CME_MASK_C0, BITS64(0, 2)); + + PK_TRACE("Poll for power gate sequencer state: 0x8 (FSM Idle)"); - PK_TRACE("Poll for power gate sequencer state: 0x8 (FSM Idle)"); + do + { + CME_GETSCOM(PPM_PFCS, CME_MASK_C0, CME_SCOM_AND, scom_data); + } + while(!(scom_data & BIT64(42))); + } - do + if (core & CME_MASK_C1) { - CME_GETSCOM(PPM_PFCS, core, CME_SCOM_AND, scom_data); + // vdd_pfet_force_state = 11 (Force Von) + PK_TRACE("Power Off Core VDD"); + CME_PUTSCOM(PPM_PFCS_OR, CME_MASK_C1, BITS64(0, 2)); + + PK_TRACE("Poll for power gate sequencer state: 0x8 (FSM Idle)"); + + do + { + CME_GETSCOM(PPM_PFCS, CME_MASK_C1, CME_SCOM_AND, scom_data); + } + while(!(scom_data & BIT64(42))); } - while(!(scom_data & BIT64(42))); // vdd_pfet_force_state = 00 (Nop) PK_TRACE("Turn Off Force Von"); 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 new file mode 100644 index 00000000..31c41faf --- /dev/null +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scan0.c @@ -0,0 +1,75 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scan0.c $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2015,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include "p9_cme_stop.h" +#include "p9_cme_stop_exit_marks.h" + +int +p9_hcd_core_scan0(uint32_t core, uint64_t regions, uint64_t scan_type) +{ + int rc = CME_STOP_SUCCESS; + uint64_t scom_data; + + PK_TRACE("raise Vital clock region fence"); + CME_PUTSCOM(PERV_CPLT_CTRL1_OR, core, BIT64(3)); + + PK_TRACE("Raise region fences for scanned regions"); + CME_PUTSCOM(PERV_CPLT_CTRL1_OR, core, BITS64(4, 11)); + + PK_TRACE("Setup all Clock Domains and Clock Types"); + CME_GETSCOM(PERV_CLK_REGION, core, CME_SCOM_AND, scom_data); + scom_data |= ((regions << SHIFT64(14)) | BITS64(48, 3)); + CME_PUTSCOM(PERV_CLK_REGION, core, scom_data); + + PK_TRACE("Write scan select register"); + scom_data = (scan_type << SHIFT64(59)) | (regions << SHIFT64(14)); + CME_PUTSCOM(PERV_SCAN_REGION_TYPE, core, scom_data); + + PK_TRACE("set OPCG_REG0 register bit 0='0'"); + CME_GETSCOM(PERV_OPCG_REG0, core, CME_SCOM_AND, scom_data); + scom_data &= ~BIT64(0); + CME_PUTSCOM(PERV_OPCG_REG0, core, scom_data); + + PK_TRACE("trigger Scan0"); + CME_GETSCOM(PERV_OPCG_REG0, core, CME_SCOM_AND, scom_data); + scom_data |= BIT64(2); + CME_PUTSCOM(PERV_OPCG_REG0, core, scom_data); + + PK_TRACE("Poll OPCG done bit to check for run-N completeness"); + + do + { + CME_GETSCOM(PERV_CPLT_STAT0, core, CME_SCOM_AND, scom_data); + } + while(!(scom_data & BIT64(8))); + + PK_TRACE("clear all clock REGIONS and type"); + CME_PUTSCOM(PERV_CLK_REGION, core, 0); + + PK_TRACE("Clear Scan Select Register"); + CME_PUTSCOM(PERV_SCAN_REGION_TYPE, core, 0); + + return rc; +} diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scomcust.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scomcust.c index bac50bd1..1bbf98fe 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scomcust.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scomcust.c @@ -25,9 +25,22 @@ #include "p9_cme_stop.h" #include "p9_cme_stop_exit_marks.h" +#include "p9_hcode_image_defines.H" int p9_hcd_core_scomcust(uint32_t core) { + /* + CmeImageHeader_t* pCmeImgHdr = (CmeImageHeader_t*)(CME_HEADER_IMAGE_OFFSET); + CmeScomRestore* pCmeScomRes = (CmeScomRestore*)(pCmeImgHdr->coreScomRestoreOffset); + int i; + + for(i=0; pCmeScomRes->pad; i++, pCmeScomRes += sizeof(CmeScomRestore)) + { + PK_TRACE("scom[%d] addr[%x] data[%016llx]", + i, pCmeScomRes->addr, pCmeScomRes->data); + CME_PUTSCOM(pCmeScomRes->addr, core, pCmeScomRes->data); + } + */ return 0; } 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 213c792c..c47370db 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 @@ -30,9 +30,24 @@ int p9_hcd_core_scominit(uint32_t core) { int rc = CME_STOP_SUCCESS; - PK_TRACE("TP.TCEC00.CORE.EPS.FIR.LOCAL_FIR_MASK = 0xBEEF"); - CME_PUTSCOM(0x2004000D, core, 0xbeef); - PK_TRACE("EX00.EC.C0.PC.FIR.CORE_FIRMASK = 0xDEAD"); - CME_PUTSCOM(0x20010A43, core, 0xdead); + uint64_t scom_data; + + // how about bit 6? + PK_TRACE("Restore SYNC_CONFIG[8] for stop1"); + CME_GETSCOM(C_SYNC_CONFIG, core, CME_SCOM_AND, scom_data); + scom_data = scom_data | BIT64(8); + CME_PUTSCOM(C_SYNC_CONFIG, core, scom_data); + + /// @todo set the sample pulse count (bit 6:9) + /// enable the appropriate loops + /// (needs investigation with the Perv team on the EC wiring). + PK_TRACE("Enable DTS sampling via THERM_MODE_REG[5]"); + CME_GETSCOM(C_THERM_MODE_REG, core, CME_SCOM_AND, scom_data); + 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/cme/stop_cme/p9_hcd_core_startclocks.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_startclocks.c index 06aeea19..f949a3d2 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_startclocks.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_startclocks.c @@ -32,9 +32,9 @@ p9_hcd_core_startclocks(uint32_t core) int rc = CME_STOP_SUCCESS; uint64_t scom_data, loop; - // do this again here for stop2 in addition to chiplet_reset - PK_TRACE("4S2: Set Core Glitchless Mux to DPLL"); - CME_PUTSCOM(C_PPM_CGCR, core, BIT64(3)); + /// @todo add DD1 attribute control + PK_TRACE("DD1 only: set sdis_n(flushing LCBES condition workaround"); + CME_PUTSCOM(C_CPLT_CONF0_OR, core, BIT64(34)); PK_TRACE("Set inop_align/wait/wait_cycles via OPCG_ALIGN[0-3,12-19,52-63]"); CME_GETSCOM(C_OPCG_ALIGN, core, CME_SCOM_AND, scom_data); @@ -42,8 +42,8 @@ p9_hcd_core_startclocks(uint32_t core) scom_data = scom_data | (BIT64(1) | BIT64(3) | BIT64(59)); CME_PUTSCOM(C_OPCG_ALIGN, core, scom_data); - PK_TRACE("Drop partial good fences via CPLT_CTRL1[3-14]"); - CME_PUTSCOM(C_CPLT_CTRL1_CLEAR, core, 0xFFFF700000000000); + PK_TRACE("Drop partial good fences via CPLT_CTRL1[4-14]"); + CME_PUTSCOM(C_CPLT_CTRL1_CLEAR, core, BITS64(4, 11)); PK_TRACE("Drop vital fences via CPLT_CTRL1[3]"); CME_PUTSCOM(C_CPLT_CTRL1_CLEAR, core, BIT64(3)); @@ -81,6 +81,8 @@ p9_hcd_core_startclocks(uint32_t core) CME_PUTSCOM(C_SYNC_CONFIG, core, scom_data); scom_data = scom_data & ~BIT64(7); CME_PUTSCOM(C_SYNC_CONFIG, core, scom_data); + // 255 cache cycles + PPE_WAIT_CORE_CYCLES(loop, 510); PK_TRACE("Check chiplet_is_aligned"); @@ -88,49 +90,53 @@ p9_hcd_core_startclocks(uint32_t core) { CME_GETSCOM(C_CPLT_STAT0, core, CME_SCOM_AND, scom_data); } - while(~scom_data & BIT64(9)); + while((~scom_data) & BIT64(9)); MARK_TRAP(SX_STARTCLOCKS_REGION) PK_TRACE("Drop force_align via CPLT_CTRL0[3]"); CME_PUTSCOM(C_CPLT_CTRL0_CLEAR, core, BIT64(3)); - PPE_WAIT_CORE_CYCLES(loop, 450); // clock_start() PK_TRACE("Clear all bits prior start core clocks via SCAN_REGION_TYPE"); CME_PUTSCOM(C_SCAN_REGION_TYPE, core, 0); - PK_TRACE("Start core clocks(arrays+nsl clock region) via CLK_REGION"); - scom_data = 0x4FFC000000006000; + PK_TRACE("Start core clocks(all but pll) via CLK_REGION"); + scom_data = (CLK_START_CMD | CLK_REGION_ALL_BUT_PLL | CLK_THOLD_ALL); CME_PUTSCOM(C_CLK_REGION, core, scom_data); - PK_TRACE("Start core clocks(sl+refresh clock region) via CLK_REGION"); - scom_data = 0x4FFC00000000E000; - CME_PUTSCOM(C_CLK_REGION, core, scom_data); - - PK_TRACE("Polling for core clocks running via CLOCK_STAT_SL"); + PK_TRACE("Polling for core clocks running via CPLT_STAT0[8]"); do { - CME_GETSCOM(C_CLOCK_STAT_SL, core, CME_SCOM_AND, scom_data); + CME_GETSCOM(C_CPLT_STAT0, core, CME_SCOM_AND, scom_data); + } + while((~scom_data) & BIT64(8)); + + PK_TRACE("Check core clock is running via CLOCK_STAT_SL[4-13]"); + CME_GETSCOM(C_CLOCK_STAT_SL, core, CME_SCOM_AND, scom_data); + + if(scom_data & CLK_REGION_ALL_BUT_PLL) + { + PK_TRACE("Core clock start failed"); + pk_halt(); } - while((scom_data & BITS64(4, 10)) != 0); PK_TRACE("Core clock is now running"); + MARK_TRAP(SX_STARTCLOCKS_DONE) + /// @todo add attr_pg control PK_TRACE("Drop chiplet fence via NC0INDIR[18]"); CME_PUTSCOM(CPPM_NC0INDIR_CLR, core, BIT64(18)); - // checkstop + /// @todo xstop check PK_TRACE("Drop flushmode_inhibit via CPLT_CTRL0[2]"); CME_PUTSCOM(C_CPLT_CTRL0_CLEAR, core, BIT64(2)); - // check align - - // needed by cme - PK_TRACE("Drop Core-L2 + Core-CC Quiesces"); + /// @todo add ipl mode attr control + PK_TRACE("Drop Core-L2 + Core-CC Quiesces via CME_LCL_SICR[6,8]/[7,9]"); out32(CME_LCL_SICR_CLR, (core << SHIFT32(7)) | (core << SHIFT32(9))); return rc; diff --git a/import/chips/p9/procedures/ppe_closed/cme/topfiles.mk b/import/chips/p9/procedures/ppe_closed/cme/topfiles.mk index 5de4bc57..94e2096b 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/topfiles.mk +++ b/import/chips/p9/procedures/ppe_closed/cme/topfiles.mk @@ -32,6 +32,7 @@ STOP-C-SOURCES = stop_cme/p9_cme_stop_irq_handlers.c \ stop_cme/p9_cme_stop_exit_thread.c \ stop_cme/p9_cme_stop_entry.c \ stop_cme/p9_cme_stop_exit.c \ + stop_cme/p9_hcd_core_scan0.c \ stop_cme/p9_hcd_core_poweron.c \ stop_cme/p9_hcd_core_chiplet_reset.c \ stop_cme/p9_hcd_core_gptr_time_initf.c \ diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_arrayinit.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_arrayinit.c index 6b1803de..4ab1f196 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_arrayinit.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_arrayinit.c @@ -27,9 +27,96 @@ #include "p9_sgpe_stop_exit_marks.h" int -p9_hcd_cache_arrayinit(uint32_t quad) +p9_hcd_cache_arrayinit(uint32_t quad, uint32_t ex) { int rc = SGPE_STOP_SUCCESS; + uint64_t scom_data; + + /// @todo add DD1 attribute control + PK_TRACE("DD1 only: set sdis_n(flushing LCBES condition workaround"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CONF0_OR, quad), BIT64(34)); + + PK_TRACE("Drop vital fence (moved to arrayinit from sacn0 module)"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CPLT_CTRL1_CLEAR, quad), BIT64(3)); + + PK_TRACE("Setup ABISTMUX_SEL"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CPLT_CTRL0_OR, quad), BIT64(0)); + + PK_TRACE("setup ABIST modes"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_BIST, quad), scom_data); + scom_data &= ~BIT64(0); + scom_data |= BIT64(1); // select_sram = 1 + scom_data &= ~BIT64(2); // select_edram = 0 + scom_data |= BITS64(4, 10);// regions = 0x7FE all but dpll + scom_data &= ~BIT64(14); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_BIST, quad), scom_data); + + PK_TRACE("Setup all Clock Domains and Clock Types"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_CLK_REGION, quad), scom_data); + scom_data |= (BITS64(4, 10) | BITS64(48, 3));// regions = 0x7FE + scom_data &= ~BIT64(14); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CLK_REGION, quad), scom_data); + + PK_TRACE("Drop Region fences"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CPLT_CTRL1_CLEAR, quad), BITS64(4, 11)); + + PK_TRACE("Setup: loopcount , OPCG engine start ABIST, run-N mode"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + scom_data |= 0x8002000000042FFF; // b0 = 1 b14 = 1 loop_counter = 0x42FFF + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + + PK_TRACE("Setup IDLE count"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG1, quad), scom_data); + scom_data |= 0x0000000F00000000; //scan_count|misr_a_valur|misr_b_value + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG1, quad), scom_data); + + PK_TRACE("opcg go"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + scom_data |= BIT64(1); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + + PK_TRACE("Poll OPCG done bit to check for run-N completeness"); + + do + { + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_CPLT_STAT0, quad), scom_data); + } + while(!(scom_data & BIT64(8))); + + PK_TRACE("OPCG done, clear Run-N mode"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + scom_data &= ~(BIT64(0) | BIT64(14) | BITS64(21, 43)); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + + PK_TRACE("clear all clock REGIONS and type"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CLK_REGION, quad), 0); + + PK_TRACE("clear ABISTCLK_MUXSEL"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CPLT_CTRL0_CLEAR, quad), BIT64(0)); + + PK_TRACE("clear BIST REGISTER"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_BIST, quad), 0); + +#if !SKIP_SCAN0 + uint64_t regions = SCAN0_REGION_ALL_BUT_EX_ANEP_DPLL; + + if (ex & FST_EX_IN_QUAD) + { + regions |= SCAN0_REGION_EX0_L2_L3_REFR; + } + + if (ex & SND_EX_IN_QUAD) + { + regions |= SCAN0_REGION_EX1_L2_L3_REFR; + } + + p9_hcd_cache_scan0(quad, regions, SCAN0_TYPE_ALL_BUT_GPTR_REPR_TIME); + // all but anep dpll all but gptr repr time +#endif + + /// @todo add DD1 attribute control + PK_TRACE("DD1 only: reset sdis_n(flushing LCBES condition workaround"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CONF0_CLEAR, quad), BIT64(34)); return rc; } diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c index 8e1e4a08..a8224000 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c @@ -28,12 +28,33 @@ extern SgpeStopRecord G_sgpe_stop_record; +enum P9_HCD_CACHE_CHIPLET_RESET_CONSTANTS +{ + // (1)PCB_EP_RESET + // (2)CLK_ASYNC_RESET + // (3)PLL_TEST_EN + // (4)PLLRST + // (5)PLLBYP + // (11)EDIS + // (12)VITL_MPW1 + // (13)VITL_MPW2 + // (14)VITL_MPW3 + // (16)VITL_THOLD + // (18)FENCE_EN + // (22)FUNC_CLKSEL + // (25)PCB_FENCE + // (26)LVLTRANS_FENCE + Q_NET_CTRL0_INIT_VECTOR = (BITS64(1, 5) | BITS64(11, 4) | BIT64(16) | + BIT64(18) | BIT64(22) | BITS64(25, 2)) +}; + int -p9_hcd_cache_chiplet_reset(uint32_t quad) +p9_hcd_cache_chiplet_reset(uint32_t quad, uint32_t ex) { int rc = SGPE_STOP_SUCCESS; uint64_t scom_data; uint32_t core, cbit; + uint32_t loop; for(core = 0, cbit = BIT32((quad << 2)); core < CORES_PER_QUAD; @@ -46,7 +67,11 @@ p9_hcd_cache_chiplet_reset(uint32_t quad) } } - PK_TRACE("Init NET_CTRL0[1-5,11-14,18,22,26],step needed for hotplug"); + /// @todo needs to revisit this sim workaround + PK_TRACE("Init heartbeat hang counter via HANG_PULSE_6[2]"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_HANG_PULSE_6_REG, quad), BIT64(2)); + + PK_TRACE("Init NET_CTRL0[1-5,11-14,16,18,22,25,26],step needed for hotplug"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, quad), Q_NET_CTRL0_INIT_VECTOR); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WAND, quad), Q_NET_CTRL0_INIT_VECTOR); @@ -71,6 +96,9 @@ p9_hcd_cache_chiplet_reset(uint32_t quad) PK_TRACE("Drop L2 glsmux reset via QPPM_EXCGCR[32:33]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_CLR, quad), BITS64(32, 2)); + // 40 ref cycles + PPE_WAIT_CORE_CYCLES(loop, 1600); + PK_TRACE("Assert chiplet enable via NET_CTRL0[0]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, quad), BIT64(0)); @@ -88,14 +116,32 @@ p9_hcd_cache_chiplet_reset(uint32_t quad) scom_data &= ~BITS64(47, 5); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_OPCG_ALIGN, quad), scom_data); -#if !SKIP_SCAN0 // Marker for scan0 MARK_TRAP(SX_CHIPLET_RESET_SCAN0) +#if !SKIP_SCAN0 + uint64_t regions = SCAN0_REGION_ALL_BUT_EX; + + if (ex & FST_EX_IN_QUAD) + { + regions |= SCAN0_REGION_EX0_L2_L3_REFR; + } + + if (ex & SND_EX_IN_QUAD) + { + regions |= SCAN0_REGION_EX1_L2_L3_REFR; + } + + p9_hcd_cache_scan0(quad, regions, SCAN0_TYPE_GPTR_REPR_TIME); + p9_hcd_cache_scan0(quad, regions, SCAN0_TYPE_ALL_BUT_GPTR_REPR_TIME); #endif + /// content below from p9_hcd_cache_chiplet_l3_dcc_setup /// @todo scan_with_setpulse_module(l3 dcc) - //PK_TRACE("Drop L3 DCC bypass via NET_CTRL1[1]"); - //GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL1_WAND, quad), ~BIT64(1)); + PK_TRACE("Drop L3 DCC bypass via NET_CTRL1[1]"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL1_WAND, quad), ~BIT64(1)); + /// @todo add VDM_ENABLE attribute control + PK_TRACE("Assert vdm enable via CPPM_VDMCR[0]"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_VDMCR_OR, quad), BIT64(0)); return rc; } diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_dpll_setup.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_dpll_setup.c index 88a5acc9..540e4dfc 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_dpll_setup.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_dpll_setup.c @@ -43,27 +43,33 @@ p9_hcd_cache_dpll_setup(uint32_t quad) PK_TRACE("Drop DPLL clock region fence via NET_CTRL1[14]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_CLEAR, quad), BIT64(14)); + // start_clock() + PK_TRACE("Clear all bits prior start DPLL clock via SCAN_REGION_TYPE"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, quad), 0); - PK_TRACE("Start DPLL clock(arrays+nsl clock region) via CLK_REGION"); - scom_data = 0x4002000000006000; - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data); - - PK_TRACE("Start DPLL clock(sl+refresh clock region) via CLK_REGION"); - scom_data = 0x400200000000E000; + PK_TRACE("Start DPLL clock via CLK_REGION"); + scom_data = (CLK_START_CMD | CLK_REGION_DPLL | CLK_THOLD_ALL); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data); - PK_TRACE("Polling for DPLL clock running via CLOCK_STAT_SL"); + PK_TRACE("Polling for DPLL clock running via CPLT_STAT0[8]"); do { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, quad), scom_data); } - while((~scom_data & BIT64(14)) != BIT64(14)); + while(!(scom_data & BIT64(8))); - PK_TRACE("DPLL clock is now running"); + PK_TRACE("Check DPLL clock running via CLOCK_STAT_SL[14]"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), scom_data); + if (scom_data & BIT64(14)) + { + PK_TRACE("Start DPLL clock failed"); + pk_halt(); + } + + PK_TRACE("DPLL clock is now running"); MARK_TRAP(SX_DPLL_START_DONE) PK_TRACE("Poll for DPLL lock"); diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c index 22835d3c..a7c485f7 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c @@ -26,28 +26,22 @@ #include "p9_sgpe_stop.h" #include "p9_sgpe_stop_exit_marks.h" +extern SgpeStopRecord G_sgpe_stop_record; + int -p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) +p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex, uint32_t pg) { int rc = SGPE_STOP_SUCCESS; + uint32_t loop; uint64_t scom_data; - // do this again here for stop8 in addition to dpll_setup - PK_TRACE("4S8: Switch L2 glsmux select to DPLL output"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_OR, quad), BITS64(34, 2)); - - PK_TRACE("Setup OPCG_ALIGN Register"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_OPCG_ALIGN, quad), scom_data); - scom_data = scom_data & (BITS64(0, 4) & BITS64(12, 8) & BITS64(52, 12)); - scom_data = scom_data | (BIT64(1) | BIT64(3) | BIT64(59)); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_OPCG_ALIGN, quad), scom_data); - - PK_TRACE("Drop L2 Regional Fences"); + PK_TRACE("Drop L2 Regional Fences via CPLT_CTRL1[8/9]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_CLEAR, quad), ((uint64_t)ex << SHIFT64(9))); PK_TRACE("Raise clock sync enable before switch to dpll"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_OR, quad), (ex << SHIFT64(37))); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_OR, quad), + ((uint64_t)ex << SHIFT64(37))); PK_TRACE("Poll for clock sync done to raise"); @@ -55,63 +49,105 @@ p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) { GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QACSR, quad), scom_data); } - while(!(scom_data & (ex << SHIFT64(37)))); + while((~scom_data) & ((uint64_t)ex << SHIFT64(37))); MARK_TRAP(SX_L2_STARTCLOCKS_ALIGN) // align_chiplets() - PK_TRACE("Set flushmode_inhibit via CPLT_CTRL0[2]"); + PK_TRACE("Assert flushmode_inhibit via CPLT_CTRL0[2]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_OR, quad), BIT64(2)); - PK_TRACE("Set force_align via CPLT_CTRL0[3]"); + PK_TRACE("Assert force_align via CPLT_CTRL0[3]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_OR, quad), BIT64(3)); - PK_TRACE("Set/Unset clear_chiplet_is_aligned via SYNC_CONFIG[7]"); + PK_TRACE("Set then unset clear_chiplet_is_aligned via SYNC_CONFIG[7]"); GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data); scom_data = scom_data | BIT64(7); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data); scom_data = scom_data & ~BIT64(7); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data); + // 255 cache cycles + PPE_WAIT_CORE_CYCLES(loop, 510); + PK_TRACE("Check chiplet_is_aligned"); do { GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, quad), scom_data); } - while(~scom_data & BIT64(9)); - - PK_TRACE("Clear force_align via CPLT_CTRL0[3]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(3)); + while((~scom_data) & BIT64(9)); MARK_TRAP(SX_L2_STARTCLOCKS_REGION) + PK_TRACE("Drop force_align via CPLT_CTRL0[3]"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(3)); + // ------------------------------- // Start L2 Clock // ------------------------------- - PK_TRACE("Set all bits to zero prior clock start via SCAN_REGION_TYPE"); + PK_TRACE("Clear all bits prior clock start via SCAN_REGION_TYPE"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, quad), 0); - PK_TRACE("Start clock(arrays+nsl clock region) via CLK_REGION"); - scom_data = 0x4000000000006000 | ((uint64_t)ex << SHIFT64(9)); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data); - - PK_TRACE("Start clock(sl+refresh clock region) via CLK_REGION"); - scom_data = 0x400000000000E000 | ((uint64_t)ex << SHIFT64(9)); + PK_TRACE("Start clock via CLK_REGION"); + scom_data = (CLK_START_CMD | CLK_THOLD_ALL | ((uint64_t)ex << SHIFT64(9))); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data); - PK_TRACE("Polling for clocks starting via CLOCK_STAT_SL"); + PK_TRACE("Polling for clocks starting via CPLT_STAT0[8]"); do { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, quad), scom_data); + } + while((~scom_data) & BIT64(8)); + + PK_TRACE("Check L2 clock running via CLOCK_STAT_SL[8:9]"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), scom_data); + + if (scom_data & ((uint64_t)ex << SHIFT64(9))) + { + PK_TRACE("L2 clock start failed"); + pk_halt(); } - while(((~scom_data >> SHIFT64(9)) & ex) != ex); PK_TRACE("L2 clock is now running"); + // ------------------------------- + // Cleaning up + // ------------------------------- + + /// @todo Check the Global Checkstop FIR of dedicated EX chiplet + + PK_TRACE("Clear flushmode_inhibit via CPLT_CTRL0[2]"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(2)); + + PK_TRACE("Set parital bad l2/l3 and stopped l2 pscom mask"); + scom_data = 0; + + if ((~pg) & FST_EX_IN_QUAD) + { + scom_data |= (PSCOM_MASK_EX0_L2 | PSCOM_MASK_EX0_L3); + } + else if (((~ex) & FST_EX_IN_QUAD) && + (G_sgpe_stop_record.state[quad].act_state_x0 >= LEVEL_EX_BASE)) + { + scom_data |= PSCOM_MASK_EX0_L2; + } + + if ((~pg) & SND_EX_IN_QUAD) + { + scom_data |= (PSCOM_MASK_EX1_L2 | PSCOM_MASK_EX1_L3); + } + else if (((~ex) & SND_EX_IN_QUAD) && + (G_sgpe_stop_record.state[quad].act_state_x1 >= LEVEL_EX_BASE)) + { + scom_data |= PSCOM_MASK_EX1_L2; + } + + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_RING_FENCE_MASK_LATCH, quad), scom_data); + PK_TRACE("Drop TLBIE Quiesce"); if (ex & FST_EX_IN_QUAD) @@ -124,9 +160,6 @@ p9_hcd_cache_l2_startclocks(uint32_t quad, uint32_t ex) GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_CLR, quad, 1), BIT64(21)); } - PK_TRACE("Clear flushmode_inhibit via CPLT_CTRL0[2]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(2)); - PK_TRACE("Drop L2 Snoop Disable"); if (ex & FST_EX_IN_QUAD) diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_poweron.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_poweron.c index f5732e13..8322fbf0 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_poweron.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_poweron.c @@ -43,12 +43,12 @@ p9_hcd_cache_poweron(uint32_t quad) PK_TRACE("Assert vital thold via NET_CTRL0[16]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, quad), BIT64(16)); - PK_TRACE("Assert L3 glsmux reset via PPM_CGCR[0]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_PPM_CGCR, quad), BIT64(0)); - PK_TRACE("Assert L2 glsmux reset via QPPM_EXCGCR[32:33]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_OR, quad), BITS64(32, 2)); + PK_TRACE("Assert cache glsmux reset via PPM_CGCR[0]"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_PPM_CGCR, quad), BIT64(0)); + #if !STOP_PRIME uint64_t scom_data; 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 new file mode 100644 index 00000000..b57a6cfc --- /dev/null +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scan0.c @@ -0,0 +1,75 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scan0.c $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2015,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include "p9_sgpe_stop.h" +#include "p9_sgpe_stop_exit_marks.h" + +int +p9_hcd_cache_scan0(uint32_t quad, uint64_t regions, uint64_t scan_type) +{ + int rc = SGPE_STOP_SUCCESS; + uint64_t scom_data; + + PK_TRACE("raise Vital clock region fence"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CPLT_CTRL1_OR, quad), BIT64(3)); + + PK_TRACE("Raise region fences for scanned regions"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CPLT_CTRL1_OR, quad), BITS64(4, 11)); + + PK_TRACE("Setup all Clock Domains and Clock Types"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_CLK_REGION, quad), scom_data); + scom_data |= ((regions << SHIFT64(14)) | BITS64(48, 3)); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CLK_REGION, quad), scom_data); + + PK_TRACE("Write scan select register"); + scom_data = (scan_type << SHIFT64(59)) | (regions << SHIFT64(14)); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_SCAN_REGION_TYPE, quad), scom_data); + + PK_TRACE("set OPCG_REG0 register bit 0='0'"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + scom_data &= ~BIT64(0); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + + PK_TRACE("trigger Scan0"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + scom_data |= BIT64(2); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_OPCG_REG0, quad), scom_data); + + PK_TRACE("Poll OPCG done bit to check for run-N completeness"); + + do + { + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PERV_CPLT_STAT0, quad), scom_data); + } + while(!(scom_data & BIT64(8))); + + PK_TRACE("clear all clock REGIONS and type"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_CLK_REGION, quad), 0); + + PK_TRACE("Clear Scan Select Register"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PERV_SCAN_REGION_TYPE, quad), 0); + + return rc; +} diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scominit.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scominit.c index ac43bda5..77c37459 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scominit.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_scominit.c @@ -30,6 +30,14 @@ int p9_hcd_cache_scominit(uint32_t quad) { int rc = SGPE_STOP_SUCCESS; + uint64_t scom_data; + + PK_TRACE("Enable DTS sampling via THERM_MODE_REG[5]"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_THERM_MODE_REG, quad), scom_data); + scom_data |= BIT64(5); + /// @todo set the sample pulse count (bit 6:9) + /// enable the appropriate loops (needs investigation with the Perv team on the EC wiring). + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_THERM_MODE_REG, quad), scom_data); return rc; } diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_startclocks.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_startclocks.c index e43ca92e..a3810ffb 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_startclocks.c +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_startclocks.c @@ -38,41 +38,66 @@ p9_hcd_cache_startclocks(uint32_t quad, uint32_t ex) PK_TRACE("Sequence EX-L3 EDRAM enables via QPPM_QCCR[0-7]"); + // QCCR[0/4] EDRAM_ENABLE_DC + // QCCR[1/5] EDRAM_VWL_ENABLE_DC + // QCCR[2/6] L3_EX0/1_EDRAM_VROW_VBLH_ENABLE_DC + // QCCR[3/7] EDRAM_VPP_ENABLE_DC // 0x0 -> 0x8 -> 0xC -> 0xE -> 0xF to turn on edram // stagger EDRAM turn-on per EX (not both at same time) if (ex & FST_EX_IN_QUAD) { GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(0)); - //PPE_WAIT_CORE_CYCLES(loop, 48000); +#if !EPM_P9_TUNING + PPE_WAIT_CORE_CYCLES(loop, 48000); +#endif GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(1)); - //PPE_WAIT_CORE_CYCLES(loop, 4000); +#if !EPM_P9_TUNING + PPE_WAIT_CORE_CYCLES(loop, 4000); +#endif GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(2)); - //PPE_WAIT_CORE_CYCLES(loop, 16000); +#if !EPM_P9_TUNING + PPE_WAIT_CORE_CYCLES(loop, 16000); +#endif GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(3)); - //PPE_WAIT_CORE_CYCLES(loop, 4000); +#if !EPM_P9_TUNING + PPE_WAIT_CORE_CYCLES(loop, 4000); +#endif } if (ex & SND_EX_IN_QUAD) { GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(4)); - //PPE_WAIT_CORE_CYCLES(loop, 100); +#if !EPM_P9_TUNING + PPE_WAIT_CORE_CYCLES(loop, 48000); +#endif GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(5)); - //PPE_WAIT_CORE_CYCLES(loop, 100); +#if !EPM_P9_TUNING + PPE_WAIT_CORE_CYCLES(loop, 4000); +#endif GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(6)); - //PPE_WAIT_CORE_CYCLES(loop, 100); +#if !EPM_P9_TUNING + PPE_WAIT_CORE_CYCLES(loop, 16000); +#endif GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(7)); - //PPE_WAIT_CORE_CYCLES(loop, 100); +#if !EPM_P9_TUNING + PPE_WAIT_CORE_CYCLES(loop, 4000); +#endif } + PK_TRACE("Assert cache EX1 ID bit2"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_OR, quad), BIT64(6)); + PK_TRACE("Set inop_align/wait/wait_cycles via OPCG_ALIGN[0-3,12-19,52-63]"); GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_OPCG_ALIGN, quad), scom_data); - scom_data = scom_data & ~(BITS64(0, 4) & BITS64(12, 8) & BITS64(52, 12)); + scom_data = scom_data & ~(BITS64(0, 4) | BITS64(12, 8) | BITS64(52, 12)); scom_data = scom_data | (BIT64(1) | BIT64(3) | BIT64(59)); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_OPCG_ALIGN, quad), scom_data); - PK_TRACE("Drop partial good fences via CPLT_CTRL1[3-14]"); + PK_TRACE("Drop partial good fences via CPLT_CTRL1[4,5,6/7,11,12/13]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_CLEAR, quad), - 0xFFFF700000000000); + (CLK_REGION_ALL_BUT_EX_DPLL | + ((uint64_t)ex << SHIFT64(7)) | + ((uint64_t)ex << SHIFT64(13)))); PK_TRACE("Drop vital fence via CPLT_CTRL1[3]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_CLEAR, quad), BIT64(3)); @@ -80,7 +105,7 @@ p9_hcd_cache_startclocks(uint32_t quad, uint32_t ex) PK_TRACE("Reset abstclk & syncclk muxsel(io_clk_sel) via CPLT_CTRL0[0:1]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(0) | BIT64(1)); - /// @todo set fabric node/chip ID values(read from nest chiplet) still need? + /// @todo set fabric node/chip ID values(read from nest chiplet) // align_chiplets() @@ -97,19 +122,21 @@ p9_hcd_cache_startclocks(uint32_t quad, uint32_t ex) scom_data = scom_data & ~BIT64(7); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SYNC_CONFIG, quad), scom_data); + // 255 cache cycles + PPE_WAIT_CORE_CYCLES(loop, 510); + PK_TRACE("Check chiplet_is_aligned"); do { GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, quad), scom_data); } - while(~scom_data & BIT64(9)); + while((~scom_data) & BIT64(9)); MARK_TRAP(SX_CACHE_STARTCLOCKS_REGION) PK_TRACE("Drop force_align via CPLT_CTRL0[3]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(3)); - PPE_WAIT_CORE_CYCLES(loop, 450); // ------------------------------- // Start L3 Clock @@ -118,34 +145,43 @@ p9_hcd_cache_startclocks(uint32_t quad, uint32_t ex) PK_TRACE("Clear all bits prior start cache clocks via SCAN_REGION_TYPE"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, quad), 0); - PK_TRACE("Start cache clocks(arrays+nsl clock region) via CLK_REGION"); - scom_data = 0x4C3C000000006000 | ((uint64_t)ex << SHIFT64(7)); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data); - - PK_TRACE("Start cache clocks(sl+refresh clock region) via CLK_REGION"); - scom_data = 0x4C3C00000000E000 | ((uint64_t)ex << SHIFT64(7)); + PK_TRACE("Start cache clocks via CLK_REGION"); + scom_data = (CLK_START_CMD | CLK_THOLD_ALL | + CLK_REGION_ALL_BUT_EX_ANEP_DPLL | + ((uint64_t)ex << SHIFT64(7)) | + ((uint64_t)ex << SHIFT64(13))); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data); // Read Clock Status Register (Cache chiplet) // check for bits 4:14 eq. zero, no tholds on - PK_TRACE("Poll for cache clocks running"); + PK_TRACE("Poll for cache clocks running via CPLT_STAT0[8]"); do { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, quad), scom_data); + } + while((~scom_data) & BIT64(8)); + + PK_TRACE("Check cache clock running via CLOCK_STAT_SL[4-14]"); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), scom_data); + + if (scom_data & (CLK_REGION_ALL_BUT_EX_ANEP_DPLL | + ((uint64_t)ex << SHIFT64(7)) | + ((uint64_t)ex << SHIFT64(13)))) + { + PK_TRACE("Cache clock start failed"); + pk_halt(); } - while((scom_data & - (BITS64(4, 2) | ((uint64_t)ex << SHIFT64(7)) | BITS64(10, 4))) != 0); PK_TRACE("Cache clocks running now"); - // @todo - // deskew_init() + /// @todo deskew_init() // ------------------------------- // Cleaning up // ------------------------------- + /// @todo add ipl mode attr control PK_TRACE("Drop chiplet fence via NET_CTRL0[18]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WAND, quad), ~BIT64(18)); @@ -154,6 +190,20 @@ p9_hcd_cache_startclocks(uint32_t quad, uint32_t ex) PK_TRACE("Drop flushmode_inhibit via CPLT_CTRL0[2]"); GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(2)); + PK_TRACE("Set all l2s and partial bad l3 pscom mask"); + scom_data = PSCOM_MASK_ALL_L2; + + if ((~ex) & FST_EX_IN_QUAD) + { + scom_data |= PSCOM_MASK_EX0_L3; + } + + if ((~ex) & SND_EX_IN_QUAD) + { + scom_data |= PSCOM_MASK_EX1_L3; + } + + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_RING_FENCE_MASK_LATCH, quad), scom_data); PK_TRACE("Drop refresh quiesce"); 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 40690ac3..805fc212 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 @@ -49,15 +49,19 @@ #include "p9_stop_common.h" +#define EQ_RING_FENCE_MASK_LATCH 0x10010008 #define EQ_SYNC_CONFIG 0x10030000 #define EQ_OPCG_ALIGN 0x10030001 #define EQ_SCAN_REGION_TYPE 0x10030005 #define EQ_CLK_REGION 0x10030006 #define EQ_CLOCK_STAT_SL 0x10030008 +#define EQ_THERM_MODE_REG 0x1005000F #define EQ_BIST 0x100F000B +#define EQ_HANG_PULSE_6_REG 0x100F0026 #define EQ_NET_CTRL0_WAND 0x100F0041 #define EQ_NET_CTRL0_WOR 0x100F0042 +#define C_NET_CTRL0 0x200F0040 #define C_NET_CTRL0_WOR 0x200F0042 #define EQ_NET_CTRL1_WAND 0x100F0045 #define EQ_NET_CTRL1_WOR 0x100F0046 @@ -66,6 +70,8 @@ #define EQ_CPLT_CTRL0_CLEAR 0x10000020 #define EQ_CPLT_CTRL1_OR 0x10000011 #define EQ_CPLT_CTRL1_CLEAR 0x10000021 +#define EQ_CPLT_CONF0_OR 0x10000018 +#define EQ_CPLT_CONF0_CLEAR 0x10000028 #define EQ_CPLT_STAT0 0x10000100 #define EQ_QPPM_DPLL_CTRL_CLEAR 0x100F0153 @@ -88,8 +94,16 @@ #define EX_PM_LCO_DIS_REG 0x10011816 #define EX_PM_L2_RCMD_DIS_REG 0x10011818 -#define SGPE_STOP_L2_CLOCK_REGION(ex) (ex << SHIFT64(9)) -#define SGPE_STOP_L3_CLOCK_REGION(ex) (ex << SHIFT64(7)) +#define PERV_CPLT_CTRL0_OR 0x10000010 +#define PERV_CPLT_CTRL0_CLEAR 0x10000020 +#define PERV_CPLT_CTRL1_OR 0x10000011 +#define PERV_CPLT_CTRL1_CLEAR 0x10000021 +#define PERV_OPCG_REG0 0x10030002 +#define PERV_OPCG_REG1 0x10030003 +#define PERV_SCAN_REGION_TYPE 0x10030005 +#define PERV_CLK_REGION 0x10030006 +#define PERV_BIST 0x1003000B +#define PERV_CPLT_STAT0 0x10000100 /// Macro to update STOP History #define SGPE_STOP_UPDATE_HISTORY(id,base,gated,trans,req_l,act_l,req_e,act_e) \ @@ -127,6 +141,16 @@ enum SGPE_STOP_EVENT_LEVELS LEVEL_EQ_BASE = 11 }; +enum SGPE_STOP_PSCOM_MASK +{ + PSCOM_MASK_ALL_L2 = BITS64(2, 2) | BITS64(10, 2), + PSCOM_MASK_EX0_L2 = BIT64(2) | BIT64(10), + PSCOM_MASK_EX1_L2 = BIT64(3) | BIT64(11), + PSCOM_MASK_EX0_L3 = BIT64(4) | BIT64(6) | BIT64(8), + PSCOM_MASK_EX1_L3 = BIT64(5) | BIT64(7) | BIT64(9) +}; + + enum SGPE_STOP_VECTOR_INDEX { VECTOR_EXIT = 0, @@ -144,6 +168,8 @@ typedef struct uint8_t act_state_x0; uint8_t act_state_x1; uint8_t act_state_q; + // both cme_flags: first(0:3) | enable(4:7) + uint8_t cme_flags; } sgpe_state_t; typedef struct @@ -176,16 +202,17 @@ void p9_sgpe_stop_exit_thread(void*); int p9_sgpe_stop_entry(); int p9_sgpe_stop_exit(); +int p9_hcd_cache_scan0(uint32_t, uint64_t, uint64_t); int p9_hcd_cache_poweron(uint32_t); -int p9_hcd_cache_chiplet_reset(uint32_t); +int p9_hcd_cache_chiplet_reset(uint32_t, uint32_t); int p9_hcd_cache_gptr_time_initf(uint32_t); int p9_hcd_cache_dpll_setup(uint32_t); int p9_hcd_cache_chiplet_init(uint32_t); int p9_hcd_cache_repair_initf(uint32_t); -int p9_hcd_cache_arrayinit(uint32_t); +int p9_hcd_cache_arrayinit(uint32_t, uint32_t ex); int p9_hcd_cache_initf(uint32_t); int p9_hcd_cache_startclocks(uint32_t, uint32_t); -int p9_hcd_cache_l2_startclocks(uint32_t, uint32_t); +int p9_hcd_cache_l2_startclocks(uint32_t, uint32_t, uint32_t); int p9_hcd_cache_scominit(uint32_t); int p9_hcd_cache_scomcust(uint32_t); int p9_hcd_cache_ras_runtime_scom(uint32_t); diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h index 3700f57f..5b29e347 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h @@ -79,6 +79,25 @@ const std::vector<SGPE_SE_MARKS> MARKS = SE_STOP11_DONE }; +const std::map<SGPE_SE_MARKS, std::string> mMARKS = boost::assign::map_list_of + (BEGINSCOPE_STOP_ENTRY, "BEGINSCOPE_STOP_ENTRY") + (ENDSCOPE_STOP_ENTRY, "ENDSCOPE_STOP_ENTRY") + (STOP_PIG_HANDLER, "STOP_PIG_HANDLER") + (SE_LESSTHAN8_WAIT, "SE_LESSTHAN8_WAIT") + (SE_STOP_SUSPEND_PSTATE, "SE_STOP_SUSPEND_PSTATE") + (SE_STOP_L2_CLKS, "SE_STOP_L2_CLKS") + (SE_STOP_L2_GRID, "SE_STOP_L2_GRID") + (SE_STOP8_DONE, "SE_STOP8_DONE") + (SE_PURGE_L3, "SE_PURGE_L3") + (SE_PURGE_L3_ABORT, "SE_PURGE_L3_ABORT") + (SE_PURGE_L3_ABORT_DONE, "SE_PURGE_L3_ABORT_DONE") + (SE_PURGE_PB, "SE_PURGE_PB") + (SE_WAIT_PGPE_SUSPEND, "SE_WAIT_PGPE_SUSPEND") + (SE_QUIESCE_QUAD, "SE_QUIESCE_QUAD") + (SE_STOP_CACHE_CLKS, "SE_STOP_CACHE_CLKS") + (SE_POWER_OFF_CACHE, "SE_POWER_OFF_CACHE") + (SE_STOP11_DONE, "SE_STOP11_DONE"); + } #endif 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 31605cca..ef1466fb 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 @@ -33,7 +33,6 @@ p9_sgpe_stop_entry() { int entry_ongoing[2] = {0, 0}; int l3_purge_aborted = 0; - int rc = 0; uint32_t ex = 0; uint32_t qloop; uint32_t cloop; @@ -42,6 +41,7 @@ p9_sgpe_stop_entry() uint32_t qentry; uint32_t loop; uint64_t scom_data; + uint64_t temp_data; ppm_sshsrc_t hist; //================================ @@ -94,8 +94,7 @@ p9_sgpe_stop_entry() BIT32((qloop << 1) + 1); } - if (G_sgpe_stop_record.state[qloop].act_state_q < - G_sgpe_stop_record.state[qloop].req_state_q && + if (G_sgpe_stop_record.state[qloop].act_state_q < LEVEL_EQ_BASE && G_sgpe_stop_record.state[qloop].req_state_q >= LEVEL_EQ_BASE) { G_sgpe_stop_record.group.quad[VECTOR_ENTRY] |= BIT32(qloop); @@ -115,10 +114,10 @@ p9_sgpe_stop_entry() G_sgpe_stop_record.state[qloop].act_state_x0, G_sgpe_stop_record.state[qloop].act_state_x1); - PK_TRACE("req: x0lv[%d]x1lv[%d]qlv[%d]", + PK_TRACE("req: qlv[%d]x0lv[%d]x1lv[%d]", + G_sgpe_stop_record.state[qloop].req_state_q, G_sgpe_stop_record.state[qloop].req_state_x0, - G_sgpe_stop_record.state[qloop].req_state_x1, - G_sgpe_stop_record.state[qloop].req_state_q); + G_sgpe_stop_record.state[qloop].req_state_x1); } } @@ -202,6 +201,31 @@ p9_sgpe_stop_entry() PPE_WAIT_CORE_CYCLES(loop, 256) + PK_TRACE("set partial bad l2/l3 and stopping/stoped l2 pscom masks"); + scom_data = 0; + + if (!(G_sgpe_stop_record.group.ex_l[VECTOR_CONFIG] & BIT32(qloop))) + { + scom_data |= (PSCOM_MASK_EX0_L2 | PSCOM_MASK_EX0_L3); + } + else if ((ex & FST_EX_IN_QUAD) || + (G_sgpe_stop_record.state[qloop].act_state_x0 >= LEVEL_EX_BASE)) + { + scom_data |= PSCOM_MASK_EX0_L2; + } + + if (!(G_sgpe_stop_record.group.ex_r[VECTOR_CONFIG] & BIT32(qloop))) + { + scom_data |= (PSCOM_MASK_EX1_L2 | PSCOM_MASK_EX1_L3); + } + else if ((ex & SND_EX_IN_QUAD) || + (G_sgpe_stop_record.state[qloop].act_state_x1 >= LEVEL_EX_BASE)) + { + scom_data |= PSCOM_MASK_EX1_L2; + } + + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_RING_FENCE_MASK_LATCH, qloop), scom_data); + PK_TRACE("SE8.b"); // Set all bits to zero prior stop cache clocks GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, qloop), 0); @@ -209,16 +233,25 @@ p9_sgpe_stop_entry() PK_TRACE("SE8.c"); // Stop L2 Clocks GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, qloop), - (0x800000000000E000 | ((uint64_t)ex << SHIFT64(9)))); + (CLK_STOP_CMD | CLK_THOLD_ALL | + ((uint64_t)ex << SHIFT64(9)))); PK_TRACE("SE8.d"); - // Poll for L2 clocks stopped + do { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, qloop), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, qloop), scom_data); + } + while((~scom_data) & BIT64(8)); + + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, qloop), scom_data); + + if (((~scom_data) & ((uint64_t)ex << SHIFT64(9))) != 0) + { + PK_TRACE("L2 clock stop failed"); + pk_halt(); } - while(((scom_data >> SHIFT64(9)) & ex) != ex); // MF: verify compiler generate single rlwmni // MF: delay may be needed for stage latch to propagate thold @@ -460,16 +493,22 @@ p9_sgpe_stop_entry() } #endif + scom_data = 0; + temp_data = 0; if (ex & FST_EX_IN_QUAD) + { GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, qloop, 0), scom_data); + } if (ex & SND_EX_IN_QUAD) + { GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, qloop, 1), - scom_data); + temp_data); + } } - while(scom_data & BIT64(0)); + while((scom_data | temp_data) & BIT64(0)); if (l3_purge_aborted) { @@ -565,18 +604,29 @@ p9_sgpe_stop_entry() PK_TRACE("SE11.m"); // Stop Cache Clocks GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, qloop), - 0x8C3E00000000E000 | ((uint64_t)ex << SHIFT64(7))); + (CLK_STOP_CMD | CLK_THOLD_ALL | + CLK_REGION_ALL_BUT_EX | + ((uint64_t)ex << SHIFT64(7)) | + ((uint64_t)ex << SHIFT64(13)))); PK_TRACE("SE11.n"); - // Poll for Cache clocks stopped + do { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, qloop), scom_data); + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, qloop), scom_data); + } + while((~scom_data) & BIT64(8)); + + GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, qloop), scom_data); + + if (((~scom_data) & (CLK_REGION_ALL_BUT_EX | + ((uint64_t)ex << SHIFT64(7)) | + ((uint64_t)ex << SHIFT64(13)))) != 0) + { + PK_TRACE("Cache clock stop failed"); + pk_halt(); } - while((scom_data & - (BITS64(4, 2) | ((uint64_t)ex << SHIFT64(7)) | BITS64(10, 5))) != - (BITS64(4, 2) | ((uint64_t)ex << SHIFT64(7)) | BITS64(10, 5))); // MF: verify compiler generate single rlwmni // MF: delay may be needed for stage latch to propagate thold @@ -589,8 +639,16 @@ p9_sgpe_stop_entry() // Assert Vital Fence GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_OR, qloop), BIT64(3)); // Raise Partial Good Fences + // Must cover partial bad fences as well or powerbus error will raise + // Note: Stop11 will lose all the fences so here needs to assert them GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_OR, qloop), - 0xFFFF700000000000); + (CLK_REGION_ALL_BUT_EX | + ((uint64_t)ex << SHIFT64(7)) | + ((uint64_t)ex << SHIFT64(9)) | + ((uint64_t)ex << SHIFT64(13)))); + /// @todo add VDM_ENABLE attribute control + PK_TRACE("Assert vdm enable via CPPM_VDMCR[0]"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_VDMCR_CLR, qloop), BIT64(0)); //========================================= MARK_TAG(SE_POWER_OFF_CACHE, (32 >> qloop)) @@ -603,7 +661,10 @@ p9_sgpe_stop_entry() GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, qloop), BIT64(16)); // L3 edram shutdown - // todo: not EPM flag for delay + // QCCR[0/4] EDRAM_ENABLE_DC + // QCCR[1/5] EDRAM_VWL_ENABLE_DC + // QCCR[2/6] L3_EX0/1_EDRAM_VROW_VBLH_ENABLE_DC + // QCCR[3/7] EDRAM_VPP_ENABLE_DC PK_TRACE("SE11.r"); if (ex & SND_EX_IN_QUAD) @@ -722,8 +783,6 @@ p9_sgpe_stop_entry() } } - // Enable Type2/3/6 Interrupt - out32(OCB_OIMR1_CLR, (BITS32(15, 2) | BIT32(19))); //============================ MARK_TRAP(ENDSCOPE_STOP_ENTRY) //============================ 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 2a69c844..13fcd08f 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 @@ -32,9 +32,8 @@ extern SgpeStopRecord G_sgpe_stop_record; int p9_sgpe_stop_exit() { - int rc = 0; uint32_t m_l2; - uint32_t m_l3; + uint32_t m_pg; uint32_t cloop; uint32_t qloop; uint32_t cexit; @@ -42,7 +41,9 @@ p9_sgpe_stop_exit() int cme; uint32_t core; uint64_t scom_data = 0; + uint64_t cme_flags; ppm_sshsrc_t hist; + ocb_ccsr_t ccsr; //=============================== MARK_TAG(BEGINSCOPE_STOP_EXIT, 0) @@ -56,35 +57,70 @@ p9_sgpe_stop_exit() for(cexit = G_sgpe_stop_record.group.core[VECTOR_EXIT], qspwu = G_sgpe_stop_record.group.qswu[VECTOR_EXIT], - qloop = 0, m_l2 = 0, m_l3 = 0; + qloop = 0, m_l2 = 0, m_pg = 0; cexit > 0 || qspwu > 0; - cexit = cexit << 4, qspwu = qspwu << 1, qloop++, m_l2 = 0, m_l3 = 0) + cexit = cexit << 4, qspwu = qspwu << 1, qloop++, m_l2 = 0, m_pg = 0) { - m_l2 |= ((cexit & BITS32(0, 2)) ? FST_EX_IN_QUAD : 0); - m_l2 |= ((cexit & BITS32(2, 2)) ? SND_EX_IN_QUAD : 0); + if (!((cexit & BITS32(0, 4)) || (qspwu & BIT32(0)))) + { + continue; + } - if (qspwu & BIT32(0)) + 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)) { - 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)) + 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; } } - if(!m_l2) - { - continue; - } + PK_TRACE("quad[%d]m_l2[%d]m_pg[%d]", qloop, m_l2, m_pg); // Update QSSR: stop_exit_ongoing out32(OCB_QSSR_OR, BIT32(qloop + 26)); - if(G_sgpe_stop_record.state[qloop].act_state_q >= STOP_LEVEL_11) + for(cloop = 0; cloop < CORES_PER_QUAD; cloop++) + { + if(!(cexit & BIT32(cloop))) + { + continue; + } + + SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop), + CORE_ADDR_BASE, + STOP_CORE_IS_GATED, + STOP_TRANS_EXIT, + STOP_LEVEL_0, + STOP_LEVEL_0, + STOP_REQ_DISABLE, + STOP_ACT_DISABLE); + } + + if(m_l2 && G_sgpe_stop_record.state[qloop].act_state_q >= STOP_LEVEL_11) { SGPE_STOP_UPDATE_HISTORY(qloop, QUAD_ADDR_BASE, @@ -95,23 +131,6 @@ p9_sgpe_stop_exit() STOP_REQ_DISABLE, STOP_ACT_DISABLE); - for(cloop = 0; cloop < CORES_PER_QUAD; cloop++) - { - if(!(cexit & BIT32(cloop))) - { - continue; - } - - SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop), - CORE_ADDR_BASE, - STOP_CORE_IS_GATED, - STOP_TRANS_EXIT, - STOP_LEVEL_0, - STOP_LEVEL_0, - STOP_REQ_DISABLE, - STOP_ACT_DISABLE); - } - //================================= MARK_TAG(SX_POWERON, (32 >> qloop)) //================================= @@ -123,8 +142,8 @@ p9_sgpe_stop_exit() MARK_TRAP(SX_CHIPLET_RESET) //========================= - PK_TRACE("Cache Chiplet Reset"); - p9_hcd_cache_chiplet_reset(qloop); + PK_TRACE("Cache Chiplet Reset m_pg[%d]", m_pg); + p9_hcd_cache_chiplet_reset(qloop, m_pg); #if !STOP_PRIME PK_TRACE("Cache Gptr Time Initf"); @@ -154,10 +173,10 @@ p9_sgpe_stop_exit() //==================================== MARK_TAG(SX_ARRAY_INIT, (32 >> qloop)) //==================================== - +#if !SKIP_ARRAYINIT PK_TRACE("Cache Arrayinit"); - p9_hcd_cache_arrayinit(qloop); - + p9_hcd_cache_arrayinit(qloop, m_pg); +#endif //===================== MARK_TRAP(SX_FUNC_INIT) //===================== @@ -166,53 +185,27 @@ p9_sgpe_stop_exit() p9_hcd_cache_initf(qloop); #endif - if (G_sgpe_stop_record.group.ex_l[VECTOR_CONFIG] & BIT32(qloop)) - { - m_l3 |= FST_EX_IN_QUAD; - } - - if (G_sgpe_stop_record.group.ex_r[VECTOR_CONFIG] & BIT32(qloop)) - { - m_l3 |= SND_EX_IN_QUAD; - } - //=========================================== MARK_TAG(SX_CACHE_STARTCLOCKS, (32 >> qloop)) //=========================================== - PK_TRACE("Cache Startclocks"); - p9_hcd_cache_startclocks(qloop, m_l3); + PK_TRACE("Cache Startclocks m_pg[%d]", m_pg); + p9_hcd_cache_startclocks(qloop, m_pg); } - if((G_sgpe_stop_record.state[qloop].act_state_x0 >= STOP_LEVEL_8 && - m_l2 == FST_EX_IN_QUAD) || - (G_sgpe_stop_record.state[qloop].act_state_x1 >= STOP_LEVEL_8 && - m_l2 == SND_EX_IN_QUAD) ) + if (m_l2) { - for(cloop = 0; cloop < CORES_PER_QUAD; cloop++) - { - if(!(cexit & BIT32(cloop))) - { - continue; - } - - SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop), - CORE_ADDR_BASE, - STOP_CORE_IS_GATED, - STOP_TRANS_EXIT, - STOP_LEVEL_0, - STOP_LEVEL_0, - STOP_REQ_DISABLE, - STOP_ACT_DISABLE); - } - //======================================================== MARK_TAG(SX_L2_STARTCLOCKS, ((m_l2 << 6) | (32 >> qloop))) //======================================================== + // do this again here for stop8 in addition to dpll_setup + PK_TRACE("4S8: Switch L2 glsmux select to DPLL output"); + GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_OR, qloop), BITS64(34, 2)); + PK_TRACE("Cache L2 Startclocks"); - p9_hcd_cache_l2_startclocks(qloop, m_l2); + p9_hcd_cache_l2_startclocks(qloop, m_l2, m_pg); // reset ex actual state if ex is exited. if (m_l2 & FST_EX_IN_QUAD) @@ -229,11 +222,12 @@ p9_sgpe_stop_exit() out32(OCB_QSSR_CLR, (m_l2 << SHIFT32((qloop << 1) + 1))); } - if(G_sgpe_stop_record.state[qloop].act_state_q >= STOP_LEVEL_11) + if(m_l2 && G_sgpe_stop_record.state[qloop].act_state_q >= STOP_LEVEL_11) { for(cme = 0; cme < EXES_PER_QUAD; cme += 2) { - core = ((cexit & BITS32(cme, 2)) >> SHIFT32(cme + 1)); + + core = ((cexit & BITS32(cme, 2)) >> SHIFT32((cme + 1))); if(!core) { @@ -243,14 +237,15 @@ p9_sgpe_stop_exit() // Raise Core-L2 + Core-CC Quiesces GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_OR, qloop, (cme >> 1)), - ((core << SHIFT32(7)) | (core << SHIFT32(9)))); + ((uint64_t)core << SHIFT64(7) | + (uint64_t)core << SHIFT64(9))); do { - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SISR, + GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SISR, qloop, (cme >> 1)), scom_data); } - while((scom_data & core) != core); + while(((scom_data >> 32) & core) != core); } #if !STOP_PRIME @@ -268,8 +263,94 @@ p9_sgpe_stop_exit() MARK_TAG(SX_CME_BOOT, (32 >> qloop)) //================================== -#if !SKIP_CME_BOOT - uint16_t cmeBootList = (m_l3 << SHIFT16(((qloop << 1) + 1))); + // doorbell cme to let rebooted cme knows about ongoing stop11 + for(cloop = 0; cloop < CORES_PER_QUAD; cloop++) + { + if(!(cexit & BIT32(cloop))) + { + continue; + } + + PK_TRACE("Doorbell1 the CME %d", ((qloop << 2) + cloop)); + GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEMSG, + ((qloop << 2) + cloop)), (BIT64(0))); + GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1_OR, + ((qloop << 2) + cloop)), BIT64(7)); + } + + // Setting up cme_flags + do + { + ccsr.value = in32(OCB_CCSR); + } + while (ccsr.fields.change_in_progress); + + if (m_pg & FST_EX_IN_QUAD) + { + cme_flags = 0; + + if (ccsr.value & BIT32((qloop << 2))) + { + cme_flags |= 0x2; + GPE_GETSCOM(GPE_SCOM_ADDR_CORE(C_NET_CTRL0, + ((qloop << 2))), scom_data); + + if (!(scom_data & BIT64(18))) + { + cme_flags |= 0x8; + } + } + + if (ccsr.value & BIT32((qloop << 2) + 1)) + { + cme_flags |= 0x1; + GPE_GETSCOM(GPE_SCOM_ADDR_CORE(C_NET_CTRL0, + ((qloop << 2) + 1)), scom_data); + + if (!(scom_data & BIT64(18))) + { + cme_flags |= 0x4; + } + } + + GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS_OR, qloop, 0), + cme_flags); + } + + if (m_pg & SND_EX_IN_QUAD) + { + cme_flags = 0; + + if (ccsr.value & BIT32(((qloop << 2) + 2))) + { + cme_flags |= 0x2; + GPE_GETSCOM(GPE_SCOM_ADDR_CORE(C_NET_CTRL0, + ((qloop << 2) + 2)), scom_data); + + if (!(scom_data & BIT64(18))) + { + cme_flags |= 0x8; + } + } + + if (ccsr.value & BIT32(((qloop << 2) + 3))) + { + cme_flags |= 0x1; + GPE_GETSCOM(GPE_SCOM_ADDR_CORE(C_NET_CTRL0, + ((qloop << 2) + 3)), scom_data); + + if (!(scom_data & BIT64(18))) + { + cme_flags |= 0x4; + } + } + + GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS_OR, qloop, 1), + cme_flags); + } + +#if !SKIP_CME_BOOT_STOP11 + uint16_t cmeBootList = (m_pg << SHIFT16(((qloop << 1) + 1))); PK_TRACE("Boot CME [%x]", cmeBootList); boot_cme( cmeBootList ); #endif @@ -319,31 +400,15 @@ p9_sgpe_stop_exit() // reset clevel to 0 if core is going to wake up G_sgpe_stop_record.level[qloop][cloop] = 0; - /*do { - GPE_GETSCOM(CME_SCOM_FLAGS, QUAD_ADDR_BASE|CME_ADDR_OFFSET_EX0, - ((qloop<<2)+cloop), scom_data); - } while(!(scom_data & BIT64(0)));*/ - // TODO PUT THE FOLLOWING TWO BEFORE CME_BOOT() // Change PPM Wakeup to CME GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CPMMR_CLR, ((qloop << 2) + cloop)), BIT64(13)); - PK_TRACE("Doorbell1 the CME %d", ((qloop << 2) + cloop)); - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEMSG, ((qloop << 2) + cloop)), - (BIT64(0))); - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1_OR, - ((qloop << 2) + cloop)), BIT64(7)); } // Update QSSR: drop stop_exit_ongoing out32(OCB_QSSR_CLR, BIT32(qloop + 26)); } - // Enable Type2/3/6 Interrupt - if (!G_sgpe_stop_record.group.core[VECTOR_ENTRY]) - { - out32(OCB_OIMR1_CLR, (BITS32(15, 2) | BIT32(19))); - } - //=========================== MARK_TRAP(ENDSCOPE_STOP_EXIT) //=========================== diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit_marks.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit_marks.h index 7efdc085..b7816ff8 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit_marks.h +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit_marks.h @@ -85,6 +85,28 @@ const std::vector<SGPE_SX_MARKS> MARKS = SX_LESSTHAN8_WAIT }; +const std::map<SGPE_SX_MARKS, std::string> mMARKS = boost::assign::map_list_of + (BEGINSCOPE_STOP_EXIT, "BEGINSCOPE_STOP_EXIT") + (ENDSCOPE_STOP_EXIT, "ENDSCOPE_STOP_EXIT") + (SX_POWERON, "SX_POWERON") + (SX_CHIPLET_RESET, "SX_CHIPLET_RESET") + (SX_CHIPLET_RESET_SCAN0, "SX_CHIPLET_RESET_SCAN0") + (SX_DPLL_SETUP, "SX_DPLL_SETUP") + (SX_DPLL_START_DONE, "SX_DPLL_START_DONE") + (SX_CHIPLET_INITS, "SX_CHIPLET_INITS") + (SX_ARRAY_INIT, "SX_ARRAY_INIT") + (SX_FUNC_INIT, "SX_FUNC_INIT") + (SX_CACHE_STARTCLOCKS, "SX_CACHE_STARTCLOCKS") + (SX_CACHE_STARTCLOCKS_REGION, "SX_CACHE_STARTCLOCKS_REGION") + (SX_L2_STARTCLOCKS, "SX_L2_STARTCLOCKS") + (SX_L2_STARTCLOCKS_ALIGN, "SX_L2_STARTCLOCKS_ALIGN") + (SX_L2_STARTCLOCKS_REGION, "SX_L2_STARTCLOCKS_REGION") + (SX_SCOM_INITS, "SX_SCOM_INITS") + (SX_CME_BOOT, "SX_CME_BOOT") + (SX_RUNTIME_INITS, "SX_RUNTIME_INITS") + (SX_ENABLE_ANALOG, "SX_ENABLE_ANALOG") + (SX_LESSTHAN8_WAIT, "SX_LESSTHAN8_WAIT"); + } #endif 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 88cbf890..85ddd82b 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 @@ -62,6 +62,7 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) uint32_t cpending_t3 = 0; uint32_t qpending_t6 = 0; uint32_t payload = 0; + uint64_t scom_data; //========================= MARK_TRAP(STOP_PIG_HANDLER) @@ -159,8 +160,8 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) if (!((cpending_t2 | cpending_t3) & BIT32((qloop << 2) + cloop))) { continue; - // read payload on core has interrupt cpending } + // read payload on core has interrupt cpending else if (cpending_t2 & BIT32((qloop << 2) + cloop)) { payload = in32(OCB_OPIT2CN(((qloop << 2) + cloop))); @@ -177,22 +178,38 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) { PK_TRACE("c[%d] request exit", cloop); - if (cloop < CORES_PER_EX) - { - G_sgpe_stop_record.group.ex_l[VECTOR_EXIT] |= BIT32(qloop); - G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] |= - BIT32(qloop << 1); - } - else + // Due to some wakeup signal sources can be "fake" + // as they are triggered regardless of the state of the core, + // check if the core is running, skip exit if so as fail safe. + // Using chiplet fence in NET_CTRL0[18] for this purpose; + // if chiplet fenced, core is stopped; otherwise running. + GPE_GETSCOM(GPE_SCOM_ADDR_CORE(C_NET_CTRL0, + ((qloop << 2) + cloop)), scom_data); + + if (scom_data & BIT64(18)) { - G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] |= BIT32(qloop); - G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] |= - BIT32((qloop << 1) + 1); - } + PK_TRACE("c[%d] confirmed stopped", cloop); - G_sgpe_stop_record.group.quad[VECTOR_EXIT] |= BIT32(qloop); - G_sgpe_stop_record.group.core[VECTOR_EXIT] |= - BIT32(((qloop << 2) + cloop)); + if (cloop < CORES_PER_EX) + { + G_sgpe_stop_record.group.ex_l[VECTOR_EXIT] |= + BIT32(qloop); + G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] |= + BIT32(qloop << 1); + } + else + { + G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] |= + BIT32(qloop); + G_sgpe_stop_record.group.ex_b[VECTOR_EXIT] |= + BIT32((qloop << 1) + 1); + } + + G_sgpe_stop_record.group.quad[VECTOR_EXIT] |= + BIT32(qloop); + G_sgpe_stop_record.group.core[VECTOR_EXIT] |= + BIT32(((qloop << 2) + cloop)); + } } // otherwise it is entry request with stop level in payload else @@ -222,7 +239,7 @@ p9_sgpe_stop_pig_handler(void* arg, PkIrqId irq) G_sgpe_stop_record.group.ex_r[VECTOR_EXIT] &= G_sgpe_stop_record.group.ex_r[VECTOR_CONFIG]; - PK_TRACE("Quad Speciali Wakeup: Raise[%x], Drop[%x]", + PK_TRACE("Quad Special Wakeup: Raise[%x], Drop[%x]", G_sgpe_stop_record.group.qswu[VECTOR_EXIT], G_sgpe_stop_record.group.qswu[VECTOR_ENTRY]); PK_TRACE("Core Request Stop: Entry[%x], Exit[%x]", 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 8e775ca7..aa68586c 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,11 +34,14 @@ /// \brief Application specific overrides go here. /// -#define STOP_PRIME 0 -#define SKIP_L3_PURGE 0 -#define SKIP_L3_PURGE_ABORT 0 -#define SKIP_CME_BOOT 1 -#define SKIP_IPL_SETUP 1 +#define STOP_PRIME 0 +#define SKIP_L3_PURGE 0 +#define SKIP_L3_PURGE_ABORT 0 +#define SKIP_CME_BOOT_STOP11 1 +#define SKIP_CME_BOOT_IPL_HB 1 +#define SKIP_ARRAYINIT 1 +#define SKIP_SCAN0 1 +#define SKIP_INITF 0 // -------------------- @@ -51,6 +54,7 @@ #define PK_TRACE_BUFFER_WRAP_MARKER 1 #endif #define PK_TRACE_TIMER_OUTPUT 0 +#define PK_TRACE_ENABLE 1 // -------------------- diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/topfiles.mk b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/topfiles.mk index 9863f2eb..14735849 100644 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/topfiles.mk +++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/topfiles.mk @@ -28,6 +28,7 @@ TOP-C-SOURCES = p9_sgpe_main.c \ p9_sgpe_stop_irq_handlers.c \ p9_sgpe_stop_enter_thread.c \ p9_sgpe_stop_exit_thread.c \ + p9_hcd_cache_scan0.c \ p9_hcd_cache_poweron.c \ p9_hcd_cache_chiplet_reset.c \ p9_hcd_cache_gptr_time_initf.c \ |