diff options
| author | hostboot <hostboot@us.ibm.com> | 2018-08-22 13:03:19 -0500 |
|---|---|---|
| committer | hostboot <hostboot@us.ibm.com> | 2018-08-22 17:53:59 -0500 |
| commit | f241353a3ec6fe9d0d485d39ba2d3b40e43efc8d (patch) | |
| tree | 3e5b67c5ab85b68abb74cdeab545ab2472f53f7d | |
| parent | 94491cf743ec0c11f3ba6c6dd4985d8b42c1ad7c (diff) | |
| download | talos-hcode-f241353a3ec6fe9d0d485d39ba2d3b40e43efc8d.tar.gz talos-hcode-f241353a3ec6fe9d0d485d39ba2d3b40e43efc8d.zip | |
Remove files to restore git history
Change-Id: Iebd10abef2c2fa9888e35761287d73b339e228ea
3 files changed, 0 insertions, 3654 deletions
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 deleted file mode 100755 index 6af16da3..00000000 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c +++ /dev/null @@ -1,1698 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c $ */ -/* */ -/* OpenPOWER HCODE Project */ -/* */ -/* COPYRIGHT 2015,2018 */ -/* [+] 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 */ -/// \file p9_cme_stop_enter_thread.c -/// \brief CME Stop Entey Thread -/// -/// Features of this code file: -/// - main() registers an IRQ handler which gets interrupted on a STOP update -/// by a core. -/// - main creates a thread which pends on semaphore to be posted by the IRQ -/// handler. -/// - p9_cme_stop_enter_thread() pends on semaphore from IRQ handler. -/// - On interrupt, stop_handler() does as follows: -/// - masks the IRQ -/// - posts a semaphore -/// - exits. -/// - On semaphore post, p9_cme_stop_enter_thread() does as follows: -/// - clears the IRQ -/// - reads STOP -/// - call p9_cme_stop_entry() sequence -/// - unmasks the IRQ -/// - pends on next semaphore post. -/// - -#include "p9_cme_stop.h" -#include "p9_cme_stop_enter_marks.h" -#include "p9_cme_pstate.h" -#include "p9_hcode_image_defines.H" - -extern CmeStopRecord G_cme_stop_record; -extern CmeRecord G_cme_record; - -#if NIMBUS_DD_LEVEL != 10 - -extern uint8_t G_pls[MAX_CORES_PER_CME][MAX_THREADS_PER_CORE]; -uint64_t G_scratch[2] = {0}; - -#endif - - - -#if HW402407_NDD1_TLBIE_STOP_WORKAROUND - - -void prepare_for_ramming (uint32_t core) -{ - uint64_t scom_data; - - // Now core thinks its awake and ramming is allowed - PK_TRACE("RAMMING Put in core maintenance mode via direct controls"); - CME_PUTSCOM(DIRECT_CONTROLS, core, (BIT64(7) | BIT64(15) | BIT64(23) | BIT64(31))); - - PK_TRACE("RAMMING Activate thread0-3 for RAM via THREAD_INFO 18-21"); - CME_PUTSCOM(THREAD_INFO, core, BITS64(18, 4)); - - CME_GETSCOM(THREAD_INFO, core, scom_data); - PK_TRACE("THREAD_INFO core 0x%X 0x%X", core, (uint32_t) (scom_data & 0xFFFFFFFF)); - - - PK_TRACE("LPID Enable RAM mode via RAM_MODEREG[0]"); - CME_PUTSCOM(RAM_MODEREG, core, BIT64(0)); - - PK_TRACE("LPID Set SPR mode to LT0-7 via SPR_MODE[20-27]"); - CME_PUTSCOM(SPR_MODE, core, BITS64(20, 8)); - - if (core & CME_MASK_C0) - { - PK_TRACE("LPID Set SPRC to scratch0 for core0 via SCOM_SPRC"); - CME_PUTSCOM(SCOM_SPRC, CME_MASK_C0, 0); - } - - if (core & CME_MASK_C1) - { - PK_TRACE("LPID Set SPRC to scratch1 for core1 via SCOM_SPRC"); - CME_PUTSCOM(SCOM_SPRC, CME_MASK_C1, BIT64(60)); - } -} - -uint16_t ram_read_lpid( uint32_t core, uint32_t thread ) -{ - uint64_t scom_data = 0; - - PK_TRACE("RAM: mfspr lpidr, gpr0 via RAM_CTRL"); - CME_PUTSCOM(RAM_CTRL, core, RAM_MFSPR_LPIDR_GPR0 | (((uint64_t) thread) << 62)); - - PK_TRACE("LPID RAM: mtspr sprd , gpr0 via RAM_CTRL"); - CME_PUTSCOM(RAM_CTRL, core, RAM_MTSPR_SPRD_GPR0 | (((uint64_t) thread) << 62)); - - if (core & CME_MASK_C0) - { - CME_GETSCOM(SCRATCH0, CME_MASK_C0, scom_data); - } - - if (core & CME_MASK_C1) - { - CME_GETSCOM(SCRATCH1, CME_MASK_C1, scom_data); - } - - PK_TRACE("RAMMING LPID read for core 0x%X 0x%X", core, (uint32_t) (scom_data & 0xFFFFFFFF)); - - if (scom_data > 0xFFF ) - { - PK_TRACE_ERR("ERROR: Unexpected LPID core %d : 0x%lX 0xFFF. HALT CME!", core, scom_data); - PK_PANIC(CME_STOP_ENTRY_BAD_LPID_ERROR); - } - - return ((uint16_t) scom_data); -} - -void ram_write_lpid( uint32_t core, uint32_t thread, uint16_t lpid ) -{ - - PK_TRACE("LPID2 Writing LPID to 0x%X for core 0x%X thread %d", lpid, core, thread); - - if (core & CME_MASK_C0) - { - PK_TRACE("LPID Set SPRC to scratch0 for core0 via SCOM_SPRC"); - CME_PUTSCOM(SCOM_SPRC, CME_MASK_C0, 0); - CME_PUTSCOM(SCRATCH0, CME_MASK_C0, (uint64_t) lpid); - } - - if (core & CME_MASK_C1) - { - PK_TRACE("LPID Set SPRC to scratch1 for core1 via SCOM_SPRC"); - CME_PUTSCOM(SCOM_SPRC, CME_MASK_C1, BIT64(60)); - CME_PUTSCOM(SCRATCH1, CME_MASK_C1, (uint64_t) lpid); - } - - PK_TRACE("LPID RAM: mfspr sprd , gpr0 via RAM_CTRL"); - CME_PUTSCOM(RAM_CTRL, core, RAM_MFSPR_SPRD_GPR0 | (((uint64_t) thread) << 62)); - - PK_TRACE("RAM: mtspr lpidr, gpr0 via RAM_CTRL"); - CME_PUTSCOM(RAM_CTRL, core, RAM_MTSPR_LPIDR_GPR0 | (((uint64_t) thread) << 62)); -} - - -void turn_off_ram_mode (uint32_t core) -{ - PK_TRACE("LPID Disable thread0-3 for RAM via THREAD_INFO"); - CME_PUTSCOM(THREAD_INFO, core, 0); - - PK_TRACE("LPID Disable RAM mode via RAM_MODEREG"); - CME_PUTSCOM(RAM_MODEREG, core, 0); - - PK_TRACE("LPID Clear scratch/spr used in RAM"); - CME_PUTSCOM(SPR_MODE, core, 0); - CME_PUTSCOM(SCOM_SPRC, core, 0); - - if (core & CME_MASK_C0) - { - CME_PUTSCOM(SCRATCH0, CME_MASK_C0, 0); - } - - if (core & CME_MASK_C1) - { - CME_PUTSCOM(SCRATCH1, CME_MASK_C1, 0); - } - - PK_TRACE("LPID Clear core maintenance mode via direct controls"); - CME_PUTSCOM(DIRECT_CONTROLS, core, (BIT64(3) | BIT64(11) | BIT64(19) | BIT64(27))); - -} - -#endif - - - -#if HW405292_NDD1_PCBMUX_SAVIOR - -void p9_cme_pcbmux_savior_prologue(uint32_t core) -{ - uint32_t old_msr = 0; - uint32_t new_msr = 0; - uint64_t scom_data = 0; - - old_msr = mfmsr(); - new_msr = old_msr | 0x7F000000; - mtmsr(new_msr); - CME_GETSCOM(0x8F0002, core, scom_data); - mtmsr(old_msr); -} - -void p9_cme_pcbmux_savior_epilogue(uint32_t core) -{ - uint64_t scom_data = 0; - uint32_t old_msr = 0; - uint32_t new_msr = 0; - - // Read the value from core CPLT_STAT0. Ignore the data - old_msr = mfmsr(); - new_msr = old_msr | 0x7F000000; - mtmsr(new_msr); - CME_GETSCOM(0x00000100, core, scom_data); - mtmsr(old_msr); - -} - -#endif - - - -void -p9_cme_stop_entry() -{ - int catchup_ongoing = 0; - int entry_ongoing = 1; - uint8_t target_level = 0; - uint8_t deeper_level = 0; - uint32_t deeper_core = 0; -#if !SKIP_ENTRY_CATCHUP - uint8_t origin_level = 0; - uint32_t origin_core = 0; - uint32_t core_catchup = 0; -#endif -#if !SKIP_ABORT - uint32_t core_wakeup = 0; -#endif - uint32_t core_aborted = 0; - uint32_t core_stop1 = 0; - uint32_t core_index = 0; - uint32_t core_mask = 0; - uint32_t core_raw = 0; - uint32_t core = 0; - uint32_t thread = 0; - uint32_t pscrs = 0; - uint32_t no_state_loss = 0; - uint32_t pm_states = 0; - uint32_t lclr_data = 0; - data64_t scom_data = {0}; - ppm_pig_t pig = {0}; - cmeHeader_t* pCmeImgHdr = (cmeHeader_t*)(CME_SRAM_HEADER_ADDR); - -#if HW402407_NDD1_TLBIE_STOP_WORKAROUND - - uint16_t lpid_c0[4] = {0, 0, 0, 0}; - uint16_t lpid_c1[4] = {0, 0, 0, 0}; - -#endif // tlbie stop workaround - - //-------------------------------------------------------------------------- - PK_TRACE("+++++ +++++ BEGIN OF STOP ENTRY +++++ +++++"); - //-------------------------------------------------------------------------- - - // First we need to determine which of the two STOP interrupts fired. - // Iow, which of the two cores, "left-0" or "right-1", updated their - // STOP PM_STATE. If both have fired by the time we get to this point, - // CME will do Daul-cast to both cores at the same time in entry flow. - - // pm_active is edge trigger because its level can be phantom - // due to common-core constantly gives pm_active when core is stopped, - // reading from EINR for raw signal, ignore EISR if EINR signal is gone - core = (in32(G_CME_LCL_EISR) & BITS32(20, 2)); - core_raw = (in32(G_CME_LCL_EINR) & BITS32(20, 2)); - out32(G_CME_LCL_EISR_CLR, core); - core = (core & core_raw) >> SHIFT32(21); - - // filter with partial good and running core mask - // core cannot enter stop if core is already stopped - core = core & G_cme_record.core_enabled & - G_cme_stop_record.core_running; - - PK_TRACE_DBG("Check: Core Select[%d] Enabled[%d] Running[%d]", - core, G_cme_record.core_enabled, - G_cme_stop_record.core_running); - - if (!core) - { - // PM_ACTIVE can be phantom, only gives warning - PK_TRACE_INF("WARNING: Only Phantom PM_ACTIVE to be Ignored. Return"); - return; - } - - // NDD2: OOB bits wired to SISR - // not implemented in DD1 - // bit1 is Recoverable Error - // bit2 is Special Attention - if (((core & CME_MASK_C0) && (in32(G_CME_LCL_SISR) & BITS32(13, 2))) || - ((core & CME_MASK_C1) && (in32_sh(CME_LCL_SISR) & BITS64SH(61, 2)))) - { - PK_TRACE_INF("WARNING: Attn/Recov Present, Abort Entry and Return"); - return; - } - -#if NIMBUS_DD_LEVEL == 20 || DISABLE_CME_DUAL_CAST == 1 - - uint32_t dual_core = core; - uint32_t single_core = CME_MASK_C0; - - // NDD2: dual cast workaround loop start - for(; single_core; single_core = single_core >> 1) - { - if (single_core & dual_core) - { - core = single_core; - } - else - { - continue; - } - -#endif - - //=================================== - MARK_TAG(BEGINSCOPE_STOP_ENTRY, core) - //=================================== - - do // while(0) loop for stop flow control - { - - // Read SISR for pm_state_cX - pm_states = in32_sh(CME_LCL_SISR); - - // entry: req_level = target stop level - // act_level = current stop level - // running = FALSE, TRUE if aborted - // stopped: req_level = act_level = target and current stop level - // (if<=5) - // running = FALSE - // exit/abort: req_level = requested stop level - // act_level = latest stop level - // running = FALSE - // running: req_level = act_level = 0 - // running = TRUE - // pm_active AND running : req_level = New requested stop level - // pm_active AND !running : req_level = Not possible, - // ignore false re-entry - // !pm_active AND running : req_level = 0 by exit, - // not changing req_level - // !pm_active AND !running : req_level = Current req_level - - for (core_mask = 2; core_mask; core_mask--) - { - if (core & core_mask) - { - core_index = core_mask & 1; - no_state_loss = 0; - - for (thread = 0; thread < MAX_THREADS_PER_CORE; thread++) - { - // address are 0x20 apart between threads and 0x80 apart between cores - pscrs = in32((CME_LCL_PSCRS00 + (core_index << 7) + (thread << 5))); - - // if either esl or ec bit is off with at least one thread - if ((~pscrs) & BITS32(2, 2)) - { - no_state_loss = 1; - break; - } - } - - G_cme_stop_record.req_level[core_index] = - (pm_states & BITS64SH((36 + (core_index << 2)), 4)) >> - SHIFT64SH((39 + (core_index << 2))); - - if (G_cme_stop_record.req_level[core_index] == STOP_LEVEL_1) - { - G_cme_stop_record.act_level[core_index] = STOP_LEVEL_1; - core &= ~core_mask; - } - - if ((pCmeImgHdr->g_cme_mode_flags & CME_STOP_11_TO_8_BIT_POS) && - (G_cme_stop_record.req_level[core_index] >= STOP_LEVEL_11)) - { - G_cme_stop_record.req_level[core_index] = STOP_LEVEL_8; - } - - if ((pCmeImgHdr->g_cme_mode_flags & CME_STOP_8_TO_5_BIT_POS) && - (G_cme_stop_record.req_level[core_index] >= STOP_LEVEL_8 && - G_cme_stop_record.req_level[core_index] < STOP_LEVEL_11)) - { - G_cme_stop_record.req_level[core_index] = STOP_LEVEL_5; - } - - if ((pCmeImgHdr->g_cme_mode_flags & CME_STOP_5_TO_4_BIT_POS) && - (G_cme_stop_record.req_level[core_index] >= STOP_LEVEL_5 && - G_cme_stop_record.req_level[core_index] < STOP_LEVEL_8)) - { - G_cme_stop_record.req_level[core_index] = STOP_LEVEL_4; - } - - // Convert everything to stop2 if no state loss - // stop1 doesnt use req_level variable so doesnt matter - if (no_state_loss || - ((pCmeImgHdr->g_cme_mode_flags & CME_STOP_4_TO_2_BIT_POS) && - (G_cme_stop_record.req_level[core_index] == STOP_LEVEL_4))) - { - G_cme_stop_record.req_level[core_index] = STOP_LEVEL_2; - } - } - } - - PK_TRACE_DBG("Check: Stop Levels Request[%d %d] Actual[%d, %d]", - G_cme_stop_record.req_level[0], - G_cme_stop_record.req_level[1], - G_cme_stop_record.act_level[0], - G_cme_stop_record.act_level[1]); - - if (!core) - { - PK_TRACE_INF("WARNING: STOP1 PM_ACTIVE to be Ignored. Return"); - return; - } - - // Mark core as to be stopped - G_cme_stop_record.core_running &= ~core; - - -#if !DISABLE_PERIODIC_CORE_QUIESCE && (NIMBUS_DD_LEVEL == 20 || NIMBUS_DD_LEVEL == 21 || CUMULUS_DD_LEVEL == 10) - - G_cme_record.fit_record.core_quiesce_fit_trigger = 0; - -#endif - - // Request PCB Mux - -#if HW405292_NDD1_PCBMUX_SAVIOR - - p9_cme_pcbmux_savior_prologue(core); - -#endif - - PK_TRACE("Request PCB mux via SICR[10/11]"); - out32(G_CME_LCL_SICR_OR, core << SHIFT32(11)); - - // Poll Infinitely for PCB Mux Grant - while((core & (in32(G_CME_LCL_SISR) >> SHIFT32(11))) != core); - - PK_TRACE("PCB Mux Granted on Core[%d]", core); - -#if HW405292_NDD1_PCBMUX_SAVIOR - - p9_cme_pcbmux_savior_epilogue(core); - -#endif - - // Stop 1 - - if(core_stop1) - { - PK_TRACE_DBG("Check: core[%d] core_stop1[%d]", core, core_stop1); - - -#if HW386841_NDD1_DSL_STOP1_FIX - - //---------------------------------------------------------------------- - PK_TRACE("+++++ +++++ STOP LEVEL 1 ENTRY +++++ +++++"); - //---------------------------------------------------------------------- - - // Note: Only Stop1 requires pulsing entry ack to pc, - // thus this is NDD1 only as well. - PK_TRACE("Pulse STOP entry acknowledgement to PC via SICR[0/1]"); - out32(G_CME_LCL_SICR_OR, core_stop1 << SHIFT32(1)); - out32(G_CME_LCL_SICR_CLR, core_stop1 << SHIFT32(1)); - - if (core & CME_MASK_C0) - { - scom_data.value = in64(CME_LCL_PECESR0); - CME_PUTSCOM(CPPM_PECES, CME_MASK_C0, scom_data.value); - } - - if (core & CME_MASK_C1) - { - scom_data.value = in64(CME_LCL_PECESR1); - CME_PUTSCOM(CPPM_PECES, CME_MASK_C1, scom_data.value); - } - - // Removed: Do not want users to become accustomed to - // seeing Stop1 reflected in Stop History on DD1 - /* - PK_TRACE("Update STOP history: in core stop level 1"); - scom_data.words.lower = 0; - scom_data.words.upper = SSH_ACT_LV1_COMPLETE; - CME_PUTSCOM(PPM_SSHSRC, core_stop1, scom_data.value); - */ - - core = core & ~core_stop1; - - if (!core) - { - // not catchup or catchup with stop2, terminates - entry_ongoing = 0; - -#if !SKIP_ENTRY_CATCHUP - - // otherwise, go back to origin core and continue - if (origin_core && (origin_level > STOP_LEVEL_2)) - { - core = origin_core; - target_level = origin_level; - entry_ongoing = 1; - } - -#endif - - break; - } - -#else - - // Nap should be done by hardware when auto_stop1 is enabled - // Halt on error if target STOP level == 1(Nap) - PK_TRACE_ERR("ERROR: Stop 1 Requested to CME When AUTO_STOP1 Enabled, HALT CME!"); - PK_PANIC(CME_STOP_ENTRY_WITH_AUTO_NAP); - -#endif - - } - - //---------------------------------------------------------------------- - PK_TRACE("+++++ +++++ STOP LEVEL 2 ENTRY +++++ +++++"); - //---------------------------------------------------------------------- - - // 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[0] : - G_cme_stop_record.req_level[1]; - - // If both cores are going into STOP but targeting different levels, - if ((core == CME_MASK_BC) && - (G_cme_stop_record.req_level[0] != G_cme_stop_record.req_level[1])) - { - // set target_level to the lighter level targeted by one core - // set deeper_level to the deeper level targeted by deeper core - deeper_level = G_cme_stop_record.req_level[0]; - deeper_core = CME_MASK_C0; - - if (G_cme_stop_record.req_level[0] < G_cme_stop_record.req_level[1]) - { - target_level = G_cme_stop_record.req_level[0]; - deeper_level = G_cme_stop_record.req_level[1]; - deeper_core = CME_MASK_C1; - } - } - - PK_TRACE("Update STOP history: in transition of entry"); - // Set req_level_level to target_level of either both or just one core - scom_data.words.lower = 0; - scom_data.words.upper = (SSH_REQ_LEVEL_UPDATE | - (((uint32_t)target_level) << SHIFT32(7))); - CME_PUTSCOM(PPM_SSHSRC, core, scom_data.value); - - // Set req_level_level to deeper_level for deeper core - if (deeper_core) - { - scom_data.words.lower = 0; - scom_data.words.upper = (SSH_REQ_LEVEL_UPDATE | - (((uint32_t)deeper_level) << SHIFT32(7))); - CME_PUTSCOM(PPM_SSHSRC, deeper_core, scom_data.value); - } - - PK_TRACE_DBG("Check: core[%d] target_lv[%d] deeper_lv[%d] deeper_core[%d]", - core, target_level, deeper_level, deeper_core); - - - // --------------------------------- - // Permanent workaround for HW407385 - - wrteei(0); - - PK_TRACE("HW407385: Assert block interrupt to PC via SICR[2/3]"); - out32(G_CME_LCL_SICR_OR, core << SHIFT32(3)); - - PK_TRACE("HW407385: Waking up the core(pm_exit=1) via SICR[4/5]"); - out32(G_CME_LCL_SICR_OR, core << SHIFT32(5)); - - CME_PM_EXIT_DELAY - - PK_TRACE("HW407385: Polling for core wakeup(pm_active=0) via EINR[20/21]"); - - while((in32(G_CME_LCL_EINR)) & (core << SHIFT32(21))); - - wrteei(1); - - // end of HW407385 - // --------------------------------- - - -#if NIMBUS_DD_LEVEL != 10 - - if (target_level > STOP_LEVEL_3 || deeper_level > STOP_LEVEL_3) - { - if (target_level < STOP_LEVEL_4) - { - core = deeper_core; - } - -#ifdef PLS_DEBUG - - PK_TRACE("RAMMING Read RAS_STATUS[(0 + 8*T)] CORE_MAINT_MODE to find out which threads are in maintenance mode"); - - if (core & CME_MASK_C0) - { - CME_GETSCOM(RAS_STATUS, CME_MASK_C0, scom_data.value); - PKTRACE("CheckA RAS_STATUS_UPPER Core0 %X", scom_data.words.upper); - } - - if (core & CME_MASK_C1) - { - CME_GETSCOM(RAS_STATUS, CME_MASK_C1, scom_data.value); - PKTRACE("CheckA RAS_STATUS_UPPER Core1 %X", scom_data.words.upper); - } - -#endif - - // This will quiesce the active threads, put all threads into core maintenance mode, - // and eventually quiesce the entire core. Now core thinks its awake and ramming is allowed - PK_TRACE("RAMMING Assert DC_CORE_STOP for ALL threads via DIRECT_CONTROL"); - CME_PUTSCOM(DIRECT_CONTROLS, core, (BIT64(7) | BIT64(15) | BIT64(23) | BIT64(31))); - - PK_TRACE("RAMMING Loop on RAS_STATUS [(3 + 8*T)]LSU_QUIESCED and [(1 + 8*T)]THREAD_QUIESCE are active"); - - do - { - - CME_GETSCOM_AND(RAS_STATUS, core, scom_data.value); -#ifdef PLS_DEBUG - PKTRACE("CheckB RAS_STATUS_AND_UPPER %X", scom_data.words.upper); -#endif - } - while((scom_data.words.upper & (BIT32(1) | BIT32(3) | BIT32(9) | BIT32(11) | BIT32(17) | BIT32(19) | BIT32(25) | BIT32( - 27))) - != (BIT32(1) | BIT32(3) | BIT32(9) | BIT32(11) | BIT32(17) | BIT32(19) | BIT32(25) | BIT32(27))); - - PK_TRACE("RAMMING Loop on RAS_STATUS[32] NEST_ACTIVE is 0"); - - do - { - - CME_GETSCOM_OR(RAS_STATUS, core, scom_data.value); -#ifdef PLS_DEBUG - PKTRACE("CheckC RAS_STATUS_OR_LOWER[0] %X", scom_data.words.lower); -#endif - } - while(scom_data.words.lower & BIT32(0)); - - PK_TRACE("RAMMING Loop on THREAD_INFO[23] THREAD_ACTION_IN_PROGRESS is 0"); - - do - { - - CME_GETSCOM_OR(THREAD_INFO, core, scom_data.value); -#ifdef PLS_DEBUG - PKTRACE("CheckD THREAD_INFO_OR_UPPER[23] %X", scom_data.words.upper); -#endif - } - while(scom_data.words.upper & BIT32(23)); - -#ifdef PLS_DEBUG - - PK_TRACE("RAMMING Read THREAD_INFO[0:3] to find out which threads are active"); - - if (core & CME_MASK_C0) - { - CME_GETSCOM(THREAD_INFO, CME_MASK_C0, scom_data.value); - PKTRACE("CheckE THREAD_INFO_UPPER[0:3] Core0 %X", scom_data.words.upper); - } - - if (core & CME_MASK_C1) - { - CME_GETSCOM(THREAD_INFO, CME_MASK_C1, scom_data.value); - PKTRACE("CheckE THREAD_INFO_UPPER[0:3] Core1 %X", scom_data.words.upper); - } - - PK_TRACE("RAMMING Read CORE_THREAD_STATE[56:59] to find out which threads are stopped"); - - if (core & CME_MASK_C0) - { - CME_GETSCOM(CORE_THREAD_STATE, CME_MASK_C0, scom_data.value); - PKTRACE("CheckF CORE_THREAD_STATE[56:59] Core0 %X %X", scom_data.words.upper, scom_data.words.lower); - } - - if (core & CME_MASK_C1) - { - CME_GETSCOM(CORE_THREAD_STATE, CME_MASK_C1, scom_data.value); - PKTRACE("CheckF CORE_THREAD_STATE[56:59] Core1 %X %X", scom_data.words.upper, scom_data.words.lower); - } - -#endif - - PK_TRACE("RAMMING Activate thread[0:3] for RAM via THREAD_INFO[18:21]"); - CME_PUTSCOM(THREAD_INFO, core, BITS64(18, 4)); - - do - { - - CME_GETSCOM_AND(THREAD_INFO, core, scom_data.value); -#ifdef PLS_DEBUG - PKTRACE("CheckG THREAD_INFO_AND_UPPER[0:3] %X", scom_data.words.upper); -#endif - } - while((scom_data.words.upper & BITS32(0, 4)) != BITS32(0, 4)); - - PK_TRACE("RAMMING Enable RAM mode via RAM_MODEREG[0]"); - CME_PUTSCOM(RAM_MODEREG, core, BIT64(0)); - - PK_TRACE("RAMMING Set SPR mode to LT0-7 via SPR_MODE[20-27]"); - CME_PUTSCOM(SPR_MODE, core, BITS64(20, 8)); - - PK_TRACE("RAMMING Set SPRC to scratch1 for cores via SCOM_SPRC"); - CME_PUTSCOM(SCOM_SPRC, core, BIT64(60)); - - PK_TRACE("Save off Scratch1 Register from cores"); - - if (core & CME_MASK_C0) - { - CME_GETSCOM(SCRATCH1, CME_MASK_C0, G_scratch[0]); - } - - if (core & CME_MASK_C1) - { - CME_GETSCOM(SCRATCH1, CME_MASK_C1, G_scratch[1]); - } - - PK_TRACE("Write default Data into Scratch1 Register"); - CME_PUTSCOM(SCRATCH1, core, 0xDEADBEEFDEADBEEF); - - uint32_t pls_core = ((G_cme_stop_record.req_level[0] > STOP_LEVEL_3) ? (core & CME_MASK_C0) : 0) - | ((G_cme_stop_record.req_level[1] > STOP_LEVEL_3) ? (core & CME_MASK_C1) : 0); - - for(core_mask = CME_MASK_C0; core_mask > 0; core_mask --) - { - if (core_mask & pls_core) - { - for(thread = 0; thread < 4; thread++) - { - PK_TRACE("PSSCR RAM: mfspr psscr, gpr0 via RAM_CTRL"); - CME_PUTSCOM(RAM_CTRL, core_mask, RAM_MFSPR_PSSCR_GPR0 | (((uint64_t) thread) << 62)); - - do - { - CME_GETSCOM(RAM_STATUS, core_mask, scom_data.value); - } - while(!(scom_data.words.upper & BIT32(1))); - - PK_TRACE("PSSCR RAM: mtspr sprd , gpr0 via RAM_CTRL"); - CME_PUTSCOM(RAM_CTRL, core_mask, RAM_MTSPR_SPRD_GPR0 | (((uint64_t) thread) << 62)); - - do - { - CME_GETSCOM(RAM_STATUS, core_mask, scom_data.value); - } - while(!(scom_data.words.upper & BIT32(1))); - - do - { - CME_GETSCOM(SCRATCH1, core_mask, scom_data.value); - } - while ((scom_data.words.upper == 0xDEADBEEF) || (scom_data.words.lower == 0xDEADBEEF)); - - if (scom_data.words.lower & BIT64SH(41)) - { - G_pls[core_mask & 1][thread] = 11; - } - else - { - G_pls[core_mask & 1][thread] = (scom_data.words.upper & BITS32(0, 4)) >> SHIFT32(3); - } - -#ifdef PLS_DEBUG - PKTRACE("cXtX PSSCR %X %X G_pls %x pls_core %d", - scom_data.words.upper, scom_data.words.lower, G_pls[core_mask & 1][thread], pls_core); -#endif - - } - } - } - - PK_TRACE("RAMMING Disable thread0-3 for RAM via THREAD_INFO"); - CME_PUTSCOM(THREAD_INFO, core, 0); - - PK_TRACE("RAMMING Disable RAM mode via RAM_MODEREG"); - CME_PUTSCOM(RAM_MODEREG, core, 0); - - PK_TRACE("RAMMING Clear scratch/spr used in RAM"); - CME_PUTSCOM(SPR_MODE, core, 0); - CME_PUTSCOM(SCOM_SPRC, core, 0); - - if (core & CME_MASK_C0) - { -#ifdef PLS_DEBUG - PKTRACE("SCRATCH1 %x %x", (G_scratch[0] >> 32), (G_scratch[0] & 0xffffffff)); -#endif - CME_PUTSCOM(SCRATCH1, CME_MASK_C0, G_scratch[0]); - } - - if (core & CME_MASK_C1) - { -#ifdef PLS_DEBUG - PKTRACE("SCRATCH1 %x %x", (G_scratch[1] >> 32), (G_scratch[1] & 0xffffffff)); -#endif - CME_PUTSCOM(SCRATCH1, CME_MASK_C1, G_scratch[1]); - } - - PK_TRACE("RAMMING Clear core maintenance mode via direct controls"); - CME_PUTSCOM(DIRECT_CONTROLS, core, (BIT64(3) | BIT64(11) | BIT64(19) | BIT64(27))); - - sync(); - - if (target_level < STOP_LEVEL_4) - { - core = CME_MASK_BC; - } - } - -#endif - - - -// ==================================== -#if HW402407_NDD1_TLBIE_STOP_WORKAROUND - - // Save thread's LPIDs and overwrite with POWMAN_RESERVED_LPID - prepare_for_ramming(core); - - for (thread = 0; thread < 4; thread++ ) - { - if (core & CME_MASK_C0) - { - lpid_c0[thread] = ram_read_lpid(CME_MASK_C0, thread); - PK_TRACE("c0lpid %X thread %X", (uint32_t) lpid_c0[thread], thread); - } - - if (core & CME_MASK_C1) - { - lpid_c1[thread] = ram_read_lpid(CME_MASK_C1, thread); - PK_TRACE("c1lpid %X thread %X", (uint32_t) lpid_c1[thread], thread); - } - } - - for (thread = 0; thread < 4; thread++ ) - { - if (core & CME_MASK_C0) - { - ram_write_lpid(CME_MASK_C0, thread, POWMAN_RESERVED_LPID); - -#if HW402407_PARANOID_LPID_MODE - - if (ram_read_lpid(CME_MASK_C0, thread) != POWMAN_RESERVED_LPID) - { - PK_TRACE_ERR("ERROR: C0 READ LPID not equal to expected value. HALT CME!"); - PK_PANIC(CME_STOP_ENTRY_BAD_LPID_ERROR); - } - -#endif - } - - if (core & CME_MASK_C1) - { - ram_write_lpid(CME_MASK_C1, thread, POWMAN_RESERVED_LPID); - -#if HW402407_PARANOID_LPID_MODE - - if (ram_read_lpid(CME_MASK_C1, thread) != POWMAN_RESERVED_LPID) - { - PK_TRACE_ERR("ERROR: C1 READ LPID not equal to expected value. HALT CME!"); - PK_PANIC(CME_STOP_ENTRY_BAD_LPID_ERROR); - } - -#endif - } - } - - sync(); - -#endif // tlbie stop workaround -// ==================================== - - - - PK_TRACE_INF("SE.2A: Core[%d] PCB Mux Granted", core); - - //============================= - MARK_TRAP(SE_QUIESCE_CORE_INTF) - //============================= - - PK_TRACE("Assert halt STOP override disable via LMCR[14/15]"); - out32(G_CME_LCL_LMCR_OR, (core << SHIFT32(15))); - -#if SPWU_AUTO - PK_TRACE("Assert auto special wakeup disable via LMCR[12/13]"); - out32(G_CME_LCL_LMCR_OR, (core << SHIFT32(13))); -#endif - - -#if HW402407_NDD1_TLBIE_STOP_WORKAROUND - // Need to wait for any pending TLBIEs to complete - PPE_WAIT_CORE_CYCLES(2000) -#endif - - PK_TRACE("Assert core-L2 + core-CC quiesces via SICR[6/7,8/9]"); - out32(G_CME_LCL_SICR_OR, (core << SHIFT32(7)) | (core << SHIFT32(9))); - - PK_TRACE("Poll for L2 interface quiesced via SISR[30/31]"); - - do - { - lclr_data = in32(G_CME_LCL_SISR); - } - while((lclr_data & core) != core); - - // Waits quiesce done for at least 512 core cycles - PPE_WAIT_CORE_CYCLES(512) - - PK_TRACE_DBG("SE.2B: Interfaces Quiesced"); - - -// ==================================== -#if HW402407_NDD1_TLBIE_STOP_WORKAROUND - - // Restore thread's LPIDs - - for (thread = 0; thread < 4; thread++ ) - { - if (core & CME_MASK_C0) - { - ram_write_lpid(CME_MASK_C0, thread, lpid_c0[thread]); - } - - if (core & CME_MASK_C1) - { - ram_write_lpid(CME_MASK_C1, thread, lpid_c1[thread]); - } - } - -#if HW402407_PARANOID_LPID_MODE - - // Read back and check - for (thread = 0; thread < 4; thread++ ) - { - if (core & CME_MASK_C0) - { - if (ram_read_lpid(CME_MASK_C0, thread) != lpid_c0[thread]) - { - PK_TRACE_ERR("ERROR: Core0 READ LPID not equal to expected value. HALT CME!"); - PK_PANIC(CME_STOP_ENTRY_BAD_LPID_ERROR); - } - } - - if (core & CME_MASK_C1) - { - if (ram_read_lpid(CME_MASK_C1, thread) != lpid_c1[thread]) - { - PK_TRACE_ERR("ERROR: Core1 READ LPID not equal to expected value. HALT CME!"); - PK_PANIC(CME_STOP_ENTRY_BAD_LPID_ERROR); - } - } - } - -#endif - turn_off_ram_mode (core); - - sync(); - -#endif // tlbie stop workaround -// ==================================== - - - // --------------------------------- - // Permanent workaround for HW407385 - - wrteei(0); - - PK_TRACE("HW407385: Drop pm_exit via SICR[4/5]"); - out32(G_CME_LCL_SICR_CLR, core << SHIFT32(5)); - - PK_TRACE("HW407385: Polling for core to stop(pm_active=1) via EINR[20/21]"); - - while((~(in32(G_CME_LCL_EINR))) & (core << SHIFT32(21))); - - PK_TRACE("HW407385: Clear pm_active status via EISR[20/21]"); - out32(G_CME_LCL_EISR_CLR, core << SHIFT32(21)); - - PK_TRACE("HW407385: Drop block interrupt to PC via SICR[2/3]"); - out32(G_CME_LCL_SICR_CLR, core << SHIFT32(3)); - - wrteei(1); - - // end of HW407385 - // --------------------------------- - - //========================== - MARK_TRAP(SE_STOP_CORE_CLKS) - //========================== - - sync(); - - PK_TRACE("Assert core chiplet fence via NET_CTRL0[18]"); - CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(18)); - - sync(); - - PK_TRACE("Clear SCAN_REGION_TYPE prior to stop core clocks"); - CME_PUTSCOM(C_SCAN_REGION_TYPE, core, 0); - -#if NIMBUS_DD_LEVEL == 10 - - // NDD1: Core Global Xstop FIR - for (core_mask = 2; core_mask > 0; core_mask--) - { - if (core & core_mask) - { - CME_GETSCOM(0x20040000, core_mask, scom_data.value); - - if (scom_data.value) - { - PK_TRACE_ERR("ERROR: Core[%d] GLOBAL XSTOP[%x] DETECTED. Gard Core!", - core_mask, scom_data.words.upper); - CME_STOP_CORE_ERROR_HANDLER(core, core_mask, CME_STOP_ENTRY_XSTOP_ERROR) - } - - if (!core) - { - return; - } - } - - } - -#endif - - PK_TRACE("Stop Core Clocks via CLK_REGION"); - CME_PUTSCOM(C_CLK_REGION, core, - (CLK_STOP_CMD | CLK_REGION_ALL_BUT_PLL | CLK_THOLD_ALL)); - - PK_TRACE("Poll for core clocks stopped via CPLT_STAT0[8]"); - - do - { - CME_GETSCOM_AND(C_CPLT_STAT0, core, scom_data.value); - } - while(!(scom_data.words.upper & BIT32(8))); - - PK_TRACE("Check core clock is stopped via CLOCK_STAT_SL[4-13]"); - - for (core_mask = 2; core_mask > 0; core_mask--) - { - if (core & core_mask) - { - CME_GETSCOM(C_CLOCK_STAT_SL, core_mask, scom_data.value); - - if (((~scom_data.value) & CLK_REGION_ALL_BUT_PLL) != 0) - { - PK_TRACE_ERR("ERROR: Core[%d] Clock Stop Failed. Gard Core!", core_mask); - CME_STOP_CORE_ERROR_HANDLER(core, core_mask, CME_STOP_ENTRY_STOPCLK_FAILED); - - if (!core) - { - return; - } - } - } - } - - PK_TRACE_DBG("SE.2C: Core Clock Stopped"); - - //============================== - MARK_TRAP(SE_STOP_CORE_GRID) - //============================== - - sync(); - - PK_TRACE("Drop clock sync enable before switch to refclk via CACCR[15]"); - CME_PUTSCOM(CPPM_CACCR_CLR, core, BIT64(15)); - - PK_TRACE("Poll for clock sync done to drop via CACSR[13]"); - - do - { - CME_GETSCOM_OR(CPPM_CACSR, core, scom_data.value); - } - while(scom_data.words.upper & BIT32(13)); - - wrteei(0); - p9_cme_core_stop_analog_control(core, ANALOG_DISABLE); - wrteei(1); - - PK_TRACE("Switch glsmux to refclk to save clock grid power via CGCR[3]"); - CME_PUTSCOM(C_PPM_CGCR, core, 0); - - PK_TRACE("Assert skew sense to skewadjust fence via NET_CTRL0[22]"); - CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(22)); - - sync(); - - PK_TRACE("Drop ABIST_SRAM_MODE_DC to support ABIST Recovery via BIST[1]"); - CME_GETSCOM(C_BIST, core, scom_data.value); - scom_data.words.upper &= ~BIT32(1); - CME_PUTSCOM(C_BIST, core, scom_data.value); - - PK_TRACE("Assert vital fence via CPLT_CTRL1[3]"); - CME_PUTSCOM(C_CPLT_CTRL1_OR, core, BIT64(3)); - - PK_TRACE("Assert regional fences via CPLT_CTRL1[4-13]"); - CME_PUTSCOM(C_CPLT_CTRL1_OR, core, BITS64(4, 11)); - -#if NIMBUS_DD_LEVEL == 10 - - PK_TRACE("Drop sdis_n(flushing LCBES condition) via CPLT_CONF0[34]"); - CME_PUTSCOM(C_CPLT_CONF0_CLEAR, core, BIT64(34)); - -#endif - - // Allow queued scoms to complete to Core EPS before switching to Core PPM - sync(); - - PK_TRACE("Copy PECE CME sample to PPM Shadow via PECES"); - - if (core & CME_MASK_C0) - { - scom_data.value = in64(CME_LCL_PECESR0); - CME_PUTSCOM(CPPM_PECES, CME_MASK_C0, scom_data.value); - G_cme_stop_record.act_level[0] = STOP_LEVEL_2; - } - - if (core & CME_MASK_C1) - { - scom_data.value = in64(CME_LCL_PECESR1); - CME_PUTSCOM(CPPM_PECES, CME_MASK_C1, scom_data.value); - G_cme_stop_record.act_level[1] = STOP_LEVEL_2; - } - - PK_TRACE_DBG("SE.2D: Clock Sync Dropped"); - - //=========================== - MARK_TAG(SE_STOP2_DONE, core) - //=========================== - - // Round Stop3 to Stop2 - if (target_level == STOP_LEVEL_3) - { - target_level = STOP_LEVEL_2; - } - - if (deeper_level == STOP_LEVEL_3) - { - deeper_core = 0; - deeper_level = 0; - } - - PK_TRACE("Update STOP history: in core stop level 2"); - // Check if STOP level 2 reaches the target for both or one core - entry_ongoing = - target_level == STOP_LEVEL_2 ? - STOP_TRANS_COMPLETE : STOP_TRANS_ENTRY; - - scom_data.words.lower = 0; - scom_data.words.upper = (SSH_ACT_LV2_COMPLETE | - (((uint32_t)entry_ongoing) << SHIFT32(3))); - CME_PUTSCOM(PPM_SSHSRC, core, scom_data.value); - - // If both cores targeting different levels - // deeper core should have at least deeper stop level than 2 - // but only need to modify deeper core history if another one was done - if (deeper_core && !entry_ongoing) - { - scom_data.words.lower = 0; - scom_data.words.upper = SSH_ACT_LV2_CONTINUE; - CME_PUTSCOM(PPM_SSHSRC, deeper_core, scom_data.value); - - // from now on, proceed with only deeper core - core = deeper_core; - target_level = deeper_level; - deeper_level = 0; - deeper_core = 0; - entry_ongoing = 1; - } - -#if !SKIP_ENTRY_CATCHUP - - if (catchup_ongoing) - { - // Y = 2 eo = 0 same if X = 2 - // Y > 2 eo = 1 c=c t=t same if X = 2 - // if X > 2 eo = 1 - // if Y = 2 c=o t=o - // else (Y > 2) c=2 - // if X != Y (X = Y: dl=0 dc=0 t=t) - // dl=o dc=o (X > Y) - // if X < Y - // dl=t dc=c t=o - if (origin_level > STOP_LEVEL_2) - { - if (target_level == STOP_LEVEL_2) - { - core = origin_core; - target_level = origin_level; - } - else - { - if (origin_level != target_level) - { - deeper_core = origin_core; - deeper_level = origin_level; - - if (origin_level < target_level) - { - deeper_core = core; - deeper_level = target_level; - target_level = origin_level; - } - } - - core = CME_MASK_BC; - } - - entry_ongoing = 1; - } - - break; - } - - core_catchup = (in32(G_CME_LCL_EISR) & BITS32(20, 2)) >> SHIFT32(21); - core_catchup = core_catchup & G_cme_record.core_enabled & - G_cme_stop_record.core_running; - - if (core_catchup) - { - out32(G_CME_LCL_EISR_CLR, core_catchup << SHIFT32(21)); - origin_core = core; - origin_level = target_level; - core = core_catchup; - catchup_ongoing = 1; - - //======================== - MARK_TAG(SE_CATCHUP, core) - //======================== - } - - PK_TRACE_DBG("Catch: core[%d] running[%d] core_catchup[%d] origin_core[%d]", - core, G_cme_stop_record.core_running, core_catchup, origin_core); - -#endif - - } - while(catchup_ongoing); - - do - { - - // If we are done at STOP level 2 - if (!entry_ongoing) - { - break; - } - - //=========================== - MARK_TRAP(SE_IS0_BEGIN) - //=========================== - -#if !SKIP_ABORT - - core_wakeup = core & (~G_cme_stop_record.core_blockwu); - out32(G_CME_LCL_EIMR_CLR, (core_wakeup << SHIFT32(13)) | - (core_wakeup << SHIFT32(15)) | - (core_wakeup << SHIFT32(17))); - sync(); - wrteei(0); - out32(G_CME_LCL_EIMR_OR, BITS32(10, 12)); - wrteei(1); - -#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_DBG("Abort: 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_DBG("Check: core[%d] deeper_core[%d] target_level[%d] deeper_level[%d]", - core, deeper_core, target_level, deeper_level); - - //---------------------------------------------------------------------- - PK_TRACE("+++++ +++++ STOP LEVEL 4 ENTRY +++++ +++++"); - //---------------------------------------------------------------------- - - // NDD2: OOB bits wired to SISR - // not implemented in DD1 - // bit0 is System checkstop - // bit1 is Recoverable Error - // bit2 is Special Attention - // bit3 is Core Checkstop - - if ((core & CME_MASK_C0) && (in32(G_CME_LCL_SISR) & BITS32(12, 4))) - { - PK_TRACE_INF("WARNING: Core0 Xstop/Attn/Recov Present, Abort Entry"); - core -= CME_MASK_C0; - } - - if ((core & CME_MASK_C1) && (in32_sh(CME_LCL_SISR) & BITS64SH(60, 4))) - { - PK_TRACE_INF("WARNING: Core1 Xstop/Attn/Recov Present, Abort Entry"); - core -= CME_MASK_C1; - } - - if (!core) - { - break; - } - - //=============================== - MARK_TAG(SE_POWER_OFF_CORE, core) - //=============================== - - PK_TRACE("Assert PCB fence via NET_CTRL0[25]"); - CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(25)); - - PK_TRACE("Assert electrical fence via NET_CTRL0[26]"); - CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(26)); - - PK_TRACE("Assert vital thold via NET_CTRL0[16]"); - CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(16)); - -#if !STOP_PRIME - - if(in32(G_CME_LCL_FLAGS) & BIT32(CME_FLAGS_VDM_OPERABLE)) - { - PK_TRACE_DBG("Clear Poweron bit in VDMCR"); - CME_PUTSCOM(PPM_VDMCR_CLR, core, BIT64(0)); - } - - PK_TRACE("Drop vdd_pfet_val/sel_override/regulation_finger_en via PFCS[4,5,8]"); - // vdd_pfet_val/sel_override = 0 (disbaled) - // vdd_pfet_regulation_finger_en = 0 (controled by FSM) - CME_PUTSCOM(PPM_PFCS_CLR, core, BIT64(4) | BIT64(5) | BIT64(8)); - - PK_TRACE("Power off core VDD via PFCS[0-1]"); - // vdd_pfet_force_state = 01 (Force Voff) - CME_PUTSCOM(PPM_PFCS_OR, core, BIT64(1)); - - PK_TRACE("Poll for vdd_pfets_disabled_sense via PFSNS[1]"); - - CME_GETSCOM_OR( CPPM_CSAR, core, scom_data.value ); - - if( BIT64(CPPM_CSAR_STOP_HCODE_ERROR_INJECT) & scom_data.value ) - { - // Clear the injection so things are not permenently stuck - CME_PUTSCOM(CPPM_CSAR_CLR, core, BIT64(CPPM_CSAR_STOP_HCODE_ERROR_INJECT)); - PK_TRACE_DBG("CME STOP ENTRY ERROR INJECT TRAP"); - PK_PANIC(CME_STOP_ENTRY_TRAP_INJECT); - } - - do - { - CME_GETSCOM_AND(PPM_PFSNS, core, scom_data.value); - } - while(!(scom_data.words.upper & BIT32(1))); - - PK_TRACE("Turn off force voff via PFCS[0-1]"); - // vdd_pfet_force_state = 00 (Nop) - CME_PUTSCOM(PPM_PFCS_CLR, core, BITS64(0, 2)); - - PK_TRACE_INF("SE.4A: Core[%d] Powered Off", core); - -#endif - - if (core & CME_MASK_C0) - { - G_cme_stop_record.act_level[0] = STOP_LEVEL_4; - } - - if (core & CME_MASK_C1) - { - G_cme_stop_record.act_level[1] = STOP_LEVEL_4; - } - - //=========================== - MARK_TAG(SE_STOP4_DONE, core) - //=========================== - - PK_TRACE("Update STOP history: in core stop level 4"); - // Check if STOP level 4 reaches the target for both or one core - entry_ongoing = - target_level == STOP_LEVEL_4 ? STOP_TRANS_COMPLETE : - STOP_TRANS_ENTRY; - - scom_data.words.lower = 0; - scom_data.words.upper = (SSH_ACT_LV4_COMPLETE | - (((uint32_t)entry_ongoing) << SHIFT32(3))); - CME_PUTSCOM(PPM_SSHSRC, core, scom_data.value); - - // If both cores targeting different levels - // 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) - { - scom_data.words.lower = 0; - scom_data.words.upper = SSH_ACT_LV4_CONTINUE; - CME_PUTSCOM(PPM_SSHSRC, deeper_core, scom_data.value); - - // from now on, proceed with only deeper core - core = deeper_core; - target_level = deeper_level; - deeper_level = 0; - deeper_core = 0; - entry_ongoing = 1; - } - - // If we are done at STOP level 4 - if (!entry_ongoing) - { - break; - } - - //=========================== - MARK_TRAP(SE_IS1_BEGIN) - //=========================== - -#if !SKIP_ABORT - - core_wakeup = core & (~G_cme_stop_record.core_blockwu); - out32(G_CME_LCL_EIMR_CLR, (core_wakeup << SHIFT32(13)) | - (core_wakeup << SHIFT32(15)) | - (core_wakeup << SHIFT32(17))); - sync(); - wrteei(0); - out32(G_CME_LCL_EIMR_OR, BITS32(10, 12)); - wrteei(1); - -#endif - - //=================== - MARK_TRAP(SE_IS1_END) - //=================== - - core_aborted = core & G_cme_stop_record.core_running; - core = core & ~G_cme_stop_record.core_running; - - PK_TRACE_DBG("Abort: 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_DBG("Check: core[%d] deeper_core[%d] target_level[%d] deeper_level[%d]", - core, deeper_core, target_level, deeper_level); - - //---------------------------------------------------------------------- - PK_TRACE("+++++ +++++ STOP LEVEL 5-7 ENTRY +++++ +++++"); - //---------------------------------------------------------------------- - -// NDD1 workaround to save cme image size -#if NIMBUS_DD_LEVEL != 10 && DISABLE_STOP8 != 1 - - if ((G_cme_stop_record.req_level[0] >= STOP_LEVEL_8) && - (G_cme_stop_record.req_level[1] >= STOP_LEVEL_8)) - { - - //================================ - MARK_TAG(SE_PURGE_L2, CME_MASK_BC) - //================================ - - PK_TRACE("Assert L2+NCU purge and NCU tlbie quiesce via SICR[18,21,22]"); - // insert tlbie quiesce before ncu purge to avoid window condition - // of ncu traffic still happening when purging starts - // Note: chtm purge and drop tlbie quiesce will be done in SGPE - out32(G_CME_LCL_SICR_OR, BIT32(18) | BIT32(21)); - out32(G_CME_LCL_SICR_OR, BIT32(22)); - - PK_TRACE("Poll for purged done via EISR[22,23]"); - - do - { - -#if !SKIP_L2_PURGE_ABORT - - if (!core_aborted && - (in32(G_CME_LCL_EINR) & BITS32(12, 6))) - { - if (in32(G_CME_LCL_EINR) & - (((core & CME_MASK_C0) ? BIT32(12) : 0) | BIT32(14) | BIT32(16))) - { - core_aborted |= CME_MASK_C0; - } - - if (in32(G_CME_LCL_EINR) & - (((core & CME_MASK_C1) ? BIT32(13) : 0) | BIT32(15) | BIT32(17))) - { - core_aborted |= CME_MASK_C1; - } - - if (core_aborted) - { - //======================================= - MARK_TAG(SE_PURGE_L2_ABORT, core_aborted) - //======================================= - - PK_TRACE_INF("Abort: L2+NCU purge aborted by core[%d]", core_aborted); - out32(G_CME_LCL_SICR_OR, BIT32(19) | BIT32(23)); - } - } - -#endif - - } - while((in32(G_CME_LCL_EISR) & BITS32(22, 2)) != BITS32(22, 2)); - - PK_TRACE("Drop L2+NCU purges and their possible aborts via SICR[18,19,22,23]"); - out32(G_CME_LCL_SICR_CLR, (BITS32(18, 2) | BITS32(22, 2))); - - PK_TRACE_DBG("SE.5A: L2 and NCU Purged"); - - //=================================================================== - MARK_TAG(SE_PURGE_L2_DONE, core_aborted ? core_aborted : CME_MASK_BC) - //=================================================================== - - - - // 1) if core = 3 aborted = 1, core = 2(sgpe handoff) aborted (cme wakeup) - // 2) if core = 1 aborted = 1, core = 0(break) aborted (cme wakeup) - // 3) if core = 2 aborted = 3, core = 0(break) aborted (cme/sgpe wakeup) - // 4) if core = 1 aborted = 2, core = 1(sgpe handoff) aborted (sgpe wakeup) - // for case 3) and 4) on the other core already handoff to sgpe - // if rgwu or spwu, fine because it will be sgpe wakeup - // if pc, there wont be sgpe wakeup due to notify bug, - // so ignore this case for abortion. otherwise, - // for case 3) core is waking up by tag along with another core - // but leave stop8 record at sgpe - // for case 4) l2 is not purged and sgpe will do stop8 - if (core != (core_aborted & core)) - { - core &= ~core_aborted; - } - else - { - break; - } - } - -#endif - - if (G_cme_record.disableSGPEHandoff) - { - PK_TRACE_INF("SE.4+: Disable SGPE Handoff due to SGPE Halt"); - break; - } - - //============================= - MARK_TAG(SE_SGPE_HANDOFF, core) - //============================= - - PK_TRACE("Update STOP history: in core stop level 5"); - scom_data.words.lower = 0; - scom_data.words.upper = SSH_ACT_LV5_CONTINUE; - CME_PUTSCOM(PPM_SSHSRC, core, scom_data.value); - -#if NIMBUS_DD_LEVEL != 10 - - PK_TRACE("Drop PPM_WRITE_DISABLE via CPMMR[0]"); - CME_PUTSCOM(CPPM_CPMMR_CLR, core, BIT64(0)); - -#endif - - PK_TRACE("Send PCB interrupt per core via PIG, select irq type via CPMMR[10]"); - - for (core_mask = 2; core_mask; core_mask--) - { - if (core & core_mask) - { - core_index = core_mask & 1; - -#if DISABLE_STOP8 - - if (G_cme_stop_record.req_level[core_index] >= STOP_LEVEL_11) - -#else - - if (G_cme_stop_record.req_level[core_index] >= STOP_LEVEL_8) - -#endif - - { - CME_PUTSCOM(CPPM_CPMMR_OR, core_mask, BIT64(10)); - pig.fields.req_intr_type = PIG_TYPE3; - G_cme_stop_record.core_blockpc |= core_mask; - } - else if (G_cme_stop_record.req_level[core_index] >= STOP_LEVEL_5) - { - CME_PUTSCOM(CPPM_CPMMR_CLR, core_mask, BIT64(10)); - pig.fields.req_intr_type = PIG_TYPE2; - G_cme_stop_record.core_blockpc &= ~core_mask; - } - else - { - PK_TRACE_ERR("ERROR: Core[%d] Handoff to SGPE with Requested Stop Level[%d]", - core_mask, G_cme_stop_record.req_level[core_index]); - PK_PANIC(CME_STOP_ENTRY_HANDOFF_LESSTHAN5); - } - - pig.fields.req_intr_payload = G_cme_stop_record.req_level[core_index]; - - - // If in block wakeup mode, disable all interrupts so the PPM PIG doesn't - // send one that could overwrite the stop entry request - // The SGPE will restore the CPPM PECE Shadow - if (G_cme_stop_record.core_blockwu & core_mask) - { - CME_PUTSCOM(CPPM_PECES, core_mask, BITS64(32, 4)); - } - - // put PIG and Wakeup_Notify_Select back to back as possible - send_pig_packet(pig.value, core_mask); - - do - { - CME_GETSCOM(PPM_PIG, core_mask, scom_data.value); - } - while (scom_data.words.lower & BIT64SH(39)); - - CME_PUTSCOM(CPPM_CPMMR_OR, core_mask, BIT64(13)); - PK_TRACE_DBG("Switch Core[%d] PPM wakeup to STOP-GPE via CPMMR[13]", core_mask); - - G_cme_stop_record.core_stopgpe |= core_mask; - G_cme_stop_record.act_level[core_index] = STOP_LEVEL_5; - } - } - - sync(); - - PK_TRACE("Clear special/regular wakeup after wakeup_notify = 1 since it is edge triggered"); - out32(G_CME_LCL_EISR_CLR, (core << SHIFT32(15)) | (core << SHIFT32(17))); - - PK_TRACE_INF("SE.5B: Core[%d] Handed off to SGPE", core); - - } - while(0); - - //-------------------------------------------------------------------------- - PK_TRACE("+++++ +++++ END OF STOP ENTRY +++++ +++++"); - //-------------------------------------------------------------------------- - - //============================ - MARK_TRAP(ENDSCOPE_STOP_ENTRY) - //============================ - -#if NIMBUS_DD_LEVEL == 20 || DISABLE_CME_DUAL_CAST == 1 - - // NDD2: dual cast workaround loop end - } - -#endif - - return; -} 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 deleted file mode 100644 index 6365b932..00000000 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h +++ /dev/null @@ -1,462 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h $ */ -/* */ -/* OpenPOWER HCODE Project */ -/* */ -/* COPYRIGHT 2015,2018 */ -/* [+] 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 */ -/// -/// \file p9_cme_stop.h -/// \brief header of p9_cme_stop_enter_thread.c and p9_cme_stop_exit.c -/// - -#ifdef __cplusplus -extern "C" { -#endif - -#include "pk.h" -#include "ppe42.h" -#include "ppe42_scom.h" - -#include "ppehw_common.h" -#include "gpehw_common.h" -#include "occhw_interrupts.h" - -#include "stop_sgpe_cme_api.h" -#include "wof_sgpe_pgpe_api.h" - -#include "ocb_register_addresses.h" -#include "cme_register_addresses.h" -#include "ppm_register_addresses.h" -#include "cppm_register_addresses.h" -#include "qppm_register_addresses.h" -#include "gpe_register_addresses.h" - -#include "ocb_firmware_registers.h" -#include "cme_firmware_registers.h" -#include "ppm_firmware_registers.h" -#include "cppm_firmware_registers.h" -#include "qppm_firmware_registers.h" - -#include "ipc_api.h" -#include "ipc_async_cmd.h" - -#include "p9_hcode_image_defines.H" -#include "p9_pm_hcd_flags.h" -#include "p9_stop_common.h" -#include "p9_dd1_doorbell_wr.h" - -#if HW386311_NDD1_PBIE_RW_PTR_STOP11_FIX || NDD1_FUSED_CORE_MODE_SCAN_FIX - -#define EXTRACT_RING_BITS(mask, ring, save) save = (ring) & (mask); -#define RESTORE_RING_BITS(mask, ring, save) ring = (((ring) & (~mask)) | (save)); - -#endif - - -extern uint32_t G_OCB_CCSR; -extern uint32_t G_OCB_QCSR; -extern uint32_t G_OCB_QSSR; -extern uint32_t G_OCB_QSSR_CLR; -extern uint32_t G_OCB_QSSR_OR; -extern uint32_t G_OCB_OCCFLG; -extern uint32_t G_OCB_OCCFLG_CLR; -extern uint32_t G_OCB_OCCFLG_OR; -extern uint32_t G_OCB_OCCFLG2; -extern uint32_t G_OCB_OCCFLG2_CLR; -extern uint32_t G_OCB_OCCS2; -extern uint32_t G_OCB_OISR0_CLR; -extern uint32_t G_OCB_OISR1; -extern uint32_t G_OCB_OISR1_CLR; -extern uint32_t G_OCB_OIMR0_CLR; -extern uint32_t G_OCB_OIMR0_OR; -extern uint32_t G_OCB_OIMR1_CLR; -extern uint32_t G_OCB_OIMR1_OR; -extern uint32_t G_OCB_OPIT0PRA; -extern uint32_t G_OCB_OPIT2PRA; -extern uint32_t G_OCB_OPIT3PRA; -extern uint32_t G_OCB_OPIT6PRB; -extern uint32_t G_OCB_OPIT0PRA_CLR; -extern uint32_t G_OCB_OPIT1PRA_CLR; -extern uint32_t G_OCB_OPIT2PRA_CLR; -extern uint32_t G_OCB_OPIT3PRA_CLR; -extern uint32_t G_OCB_OPIT4PRA_CLR; -extern uint32_t G_OCB_OPIT5PRA_CLR; -extern uint32_t G_OCB_OPIT6PRB_CLR; -extern uint32_t G_OCB_OPIT7PRB_CLR; -extern uint32_t G_OCB_OCCLFIR_AND; -extern uint32_t G_GPE_GPE3TSEL; - - -#define DEBUG_TRACE_CONTROL 0x100107D0 -#define L3TRA_TRACE_TRCTRL_CONFIG 0x10010402 -#define L3TRA_TRACE_TRDATA_CONFIG_0 0x10010403 -#define L3TRA_TRACE_TRDATA_CONFIG_1 0x10010404 -#define L3TRA_TRACE_TRDATA_CONFIG_4 0x10010407 -#define L3TRA_TRACE_TRDATA_CONFIG_5 0x10010408 -#define L3TRA_TRACE_TRDATA_CONFIG_9 0x10010409 - -#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_CLOCK_STAT_ARY 0x1003000A -#define EQ_CC_ATOMIC_LOCK 0x100303FF -#define EQ_XFIR 0x10040000 -#define EQ_FIR_MASK 0x10040002 -#define EQ_HOST_ATTN 0x10040009 -#define EQ_LOCAL_XSTOP_ERR 0x10040018 -#define EQ_THERM_MODE_REG 0x1005000F - -#define EQ_BIST 0x100F000B -#define EQ_SLAVE_CONFIG_REG 0x100F001E -#define EQ_ERROR_REG 0x100F001F -#define EQ_HANG_PULSE_6_REG 0x100F0026 -#define EQ_NET_CTRL0_WAND 0x100F0041 -#define EQ_NET_CTRL0_WOR 0x100F0042 - -#define C_SLAVE_CONFIG 0x200F001E -#define C_NET_CTRL0 0x200F0040 -#define C_NET_CTRL0_WAND 0x200F0041 -#define C_NET_CTRL0_WOR 0x200F0042 -#define EQ_NET_CTRL1_WAND 0x100F0045 -#define EQ_NET_CTRL1_WOR 0x100F0046 - -#define EQ_CPLT_CTRL0_OR 0x10000010 -#define EQ_CPLT_CTRL0_CLEAR 0x10000020 -#define EQ_CPLT_CTRL1_OR 0x10000011 -#define EQ_CPLT_CTRL1_CLEAR 0x10000021 -#define EQ_CPLT_CONF0 0x10000008 -#define EQ_CPLT_CONF0_OR 0x10000018 -#define EQ_CPLT_CONF0_CLEAR 0x10000028 -#define EQ_CPLT_STAT0 0x10000100 - -#define EQ_QPPM_DPLL_CTRL_CLEAR 0x100F0153 -#define EQ_QPPM_DPLL_CTRL_OR 0x100F0154 -#define EQ_QPPM_DPLL_STAT 0x100F0155 -#define EQ_QPPM_QACCR_SCOM1 0x100F0161 -#define EQ_QPPM_QACCR_SCOM2 0x100F0162 -#define EQ_QPPM_QACSR 0x100F0163 -#define EQ_PPM_CGCR 0x100F0164 -#define EQ_QPPM_EXCGCR 0x100F0165 -#define EQ_QPPM_EXCGCR_CLR 0x100F0166 -#define EQ_QPPM_EXCGCR_OR 0x100F0167 -#define EQ_QPPM_QCCR 0x100F01BD -#define EQ_QPPM_QCCR_WCLEAR 0x100F01BE -#define EQ_QPPM_QCCR_WOR 0x100F01BF -#define EQ_QPPM_ATOMIC_LOCK 0x100F03FF - -#define EX_L2_MODE_REG0 0x1001080A -#define EX_L2_MODE_REG1 0x1001080B -#define EX_L2_RD_EPS_REG 0x10010810 -#define EX_L2_WR_EPS_REG 0x10010811 - -#define EX_L3_RD_EPSILON_CFG_REG 0x10011829 -#define EX_L3_WR_EPSILON_CFG_REG 0x1001182A -#define EX_L3_MODE_REG0 0x1001182B -#define EX_L3_MODE_REG1 0x1001180A - -#define EX_NCU_MODE_REG 0x1001100A -#define EX_NCU_MODE_REG2 0x1001100B -#define EX_NCU_MODE_REG3 0x1001100C -#define EX_NCU_STATUS_REG 0x1001100F - -#define EX_DRAM_REF_REG 0x1001180F -#define EX_PM_PURGE_REG 0x10011813 -#define EX_PM_LCO_DIS_REG 0x10011816 -#define EX_PM_L2_RCMD_DIS_REG 0x10011818 - -#define EX_CHTM0_MODE_REG 0x10012200 -#define EX_CHTM1_MODE_REG 0x10012300 -#define EX_CHTM0_MEM_REG 0x10012201 -#define EX_CHTM1_MEM_REG 0x10012301 -#define EX_CHTM0_STAT_REG 0x10012202 -#define EX_CHTM1_STAT_REG 0x10012302 -#define EX_CHTM0_LAST_REG 0x10012203 -#define EX_CHTM1_LAST_REG 0x10012303 -#define EX_CHTM0_TRIG_REG 0x10012204 -#define EX_CHTM1_TRIG_REG 0x10012304 -#define EX_CHTM0_CTRL_REG 0x10012205 -#define EX_CHTM1_CTRL_REG 0x10012305 - -#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_OPCG_CAPT0 0x10030010 -#define PERV_OPCG_CAPT1 0x10030011 -#define PERV_OPCG_CAPT2 0x10030012 -#define PERV_CPLT_STAT0 0x10000100 -#define PERV_NET_CTRL1_WAND 0x000F0045 - - -#define PK_OPTIONAL_DEBUG_HALT(panic_code) \ - if (in32(G_OCB_OCCS2) & BIT32(PM_DEBUG_HALT_ENABLE)) {PK_PANIC(panic_code);} - - -#define SGPE_STOP_QUAD_ERROR_HANDLER(quad_error, panic_code) \ - G_sgpe_stop_record.group.quad[VECTOR_ERROR] |= BIT32(quad_error); \ - G_sgpe_stop_record.group.quad[VECTOR_CONFIG] &= ~BIT32(quad_error); \ - G_sgpe_stop_record.group.quad[VECTOR_ACTIVE] &= ~BIT32(quad_error); \ - G_sgpe_stop_record.state[quad_error].error_code = panic_code; \ - PK_OPTIONAL_DEBUG_HALT(panic_code) - -enum SGPE_STOP_STATE_HISTORY_VECTORS -{ - SSH_EXIT_COMPLETE = 0, - SSH_EXIT_IN_SESSION = (SSH_STOP_GATED | SSH_TRANS_EXIT), - SSH_ENTRY_IN_SESSION = (SSH_STOP_GATED | SSH_TRANS_ENTRY), - SSH_REQ_LEVEL_UPDATE = (SSH_STOP_GATED | SSH_TRANS_ENTRY | SSH_REQ_ENABLE), - SSH_ACT_LEVEL_UPDATE = (SSH_STOP_GATED | SSH_ACT_ENABLE), - SSH_ACT_LV5_COMPLETE = (SSH_ACT_LEVEL_UPDATE | BIT32(9) | BIT32(11)), - SSH_ACT_LV5_CONTINUE = (SSH_ACT_LV5_COMPLETE | SSH_ENTRY_IN_SESSION), - SSH_ACT_LV8_COMPLETE = (SSH_ACT_LEVEL_UPDATE | BIT32(8)), - SSH_ACT_LV11_COMPLETE = (SSH_ACT_LEVEL_UPDATE | BIT32(8) | BITS32(10, 2)) -}; - -enum SGPE_STOP_EVENT_LEVELS -{ - LEVEL_EX_BASE = 8, - LEVEL_EQ_BASE = 11 -}; - -enum SGPE_STOP_PSCOM_MASK -{ - PSCOM_MASK_ALL_L2 = BITS32(2, 2) | BITS32(10, 2), - PSCOM_MASK_EX0_L2 = BIT32(2) | BIT32(10), - PSCOM_MASK_EX1_L2 = BIT32(3) | BIT32(11), - PSCOM_MASK_EX0_L3 = BIT32(4) | BIT32(6) | BIT32(8), - PSCOM_MASK_EX1_L3 = BIT32(5) | BIT32(7) | BIT32(9) -}; - -enum SGPE_WOF_ACTIVE_UPDATE_STATUS -{ - IPC_SGPE_PGPE_UPDATE_CORE_ENABLED = 0x01, - IPC_SGPE_PGPE_UPDATE_PGPE_HALTED = 0xF0 -}; - -enum SGPE_SUSPEND_FUNCTION_STATUS -{ - STATUS_ENTRY_SUSPENDED = 1, - STATUS_EXIT_SUSPENDED = 2, - STATUS_SUSPEND_PENDING = 4, - STATUS_STOP_PROCESSING = 8 -}; - -enum SGPE_STOP_VECTOR_INDEX -{ - VECTOR_BLOCKE = 0, //(core_save, quad_req, qswu_save, req, ack) - VECTOR_BLOCKX = 1, //(core_save, quad_req, qswu_save, req, ack) - VECTOR_SUSPENDE = 2, //(core_save, qswu_save) - VECTOR_SUSPENDX = 3, //(core_save, qswu_save) - VECTOR_ENTRY = 4, //(core_ipc, quad, qswu) - VECTOR_EXIT = 5, //(core, quad_ipc qswu) - VECTOR_ACTIVE = 6, //(core_ipc, quad_ipc, qswu_active) - VECTOR_CONFIG = 7, //(core, quad) - VECTOR_ERROR = 8, //( quad) - -#if !DISABLE_STOP8 - - VECTOR_PIGE = 9, //(core) - VECTOR_PIGX = 10,//(core) - VECTOR_PCWU = 11 //(core) - -#else - - VECTOR_RCLKE = 9, //(core_blocke, quad) - VECTOR_RCLKX = 10,//(core_blockx, quad) - VECTOR_PIGE = 11,//(core) - VECTOR_PIGX = 12,//(core) - VECTOR_PCWU = 13 //(core) - -#endif - -}; - -enum VECTOR_RCLKE_QUAD_OFFSETS -{ - RCLK_DIS_REQ_OFFSET = 0, - RCLK_DIS_DONE_OFFSET = 8, - QUAD_IN_STOP11_OFFSET = 16 -}; - -enum SCOM_RESTORE_CONST -{ - SCOM_ENTRY_MARK = 0xDEADDEAD, - SCOM_REST_SIZE_PER_EQ = 0x300, //default size - SCOM_REST_SKIP_CODE = 0x60000000, -}; - -typedef struct -{ - // requested stop state calculated from core stop levels - uint8_t req_state_x0; - uint8_t req_state_x1; - uint8_t req_state_q; - // actual stop state - 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; - uint32_t error_code; -} sgpe_state_t; - -typedef struct -{ - uint32_t creq[2]; // 24 bits - uint32_t cack[2]; // 24 bits - uint32_t expg[6]; // 2 bits - uint32_t ex01[6]; // 2 bits - uint32_t qswu[7]; // 6 bits - -#if !DISABLE_STOP8 - - uint32_t quad[9]; // 6 bits - uint32_t core[12];// 24 bits - -#else - - uint32_t quad[11]; // 6 bits - uint32_t core[14];// 24 bits - -#endif - -} sgpe_group_t; - -typedef struct -{ - // function status(idle, processing, suspending, suspended) - uint8_t status_stop; - // sgpe-pgpe interlock status(quad/core updates enable/disable) - uint8_t update_pgpe; - // current/latest actions in suspend stop ipc - uint8_t suspend_act; - ipc_msg_t* updates_cmd; - ipc_msg_t* suspend_cmd; -} sgpe_wof_t; - -typedef struct -{ - uint32_t starve_counter; - uint8_t entry_pending; -} sgpe_fit_t; - -/// SGPE Stop Score Board Structure -typedef struct -{ - // requested stop level for all cores in all quads - // needs to be global variable for ex/quad stop evaluation - uint8_t level[MAX_QUADS][CORES_PER_QUAD]; - // requested and actual state of quad stop - sgpe_state_t state[MAX_QUADS]; - // group of ex and quad entering or exiting the stop - sgpe_group_t group; - sgpe_wof_t wof; - sgpe_fit_t fit; - PkSemaphore sem[2]; -} SgpeStopRecord __attribute__ ((aligned (8))); - -/// SCOM restore entry header description -typedef struct __attribute__((__packed__)) ScomRestoreHeader -{ - uint32_t entryType: 1; // 0 - 0xDEADDEAD, 1 - under version control - uint32_t entryVersion: 3; // version number - uint32_t reserved: 20; // reserved - uint32_t entryLimit: 8; // Max scom entries allowed -} ScomRestoreHeader_t; - -typedef union __attribute__((__packed__)) ScomRestValdityMark -{ - ScomRestoreHeader_t scomRestHeader; - uint32_t scomRestHeaderValue; -} ScomRestValdityMark_t; - -/// SCOM restore entry description -typedef struct __attribute__((__packed__)) ScomEntry -{ - ScomRestValdityMark_t scomEntryHeader; - uint32_t scomEntryAddress; - uint64_t scomEntryData; -} ScomEntry_t; - - -#if HW386311_NDD1_PBIE_RW_PTR_STOP11_FIX -// Types for PB EQ asynch work-around -struct ring_save -{ - uint64_t element[MAX_QUADS][8]; -}; -#endif - - -/// SGPE to PGPE IPC handlers -void p9_sgpe_ipc_uih_done_hook(); -void p9_sgpe_ipc_pgpe_ctrl_stop_updates(ipc_msg_t*, void*); -void p9_sgpe_ipc_pgpe_update_active_cores(const uint32_t); -void p9_sgpe_ipc_pgpe_update_active_cores_poll_ack(); -void p9_sgpe_ipc_pgpe_update_active_quads(const uint32_t, const uint32_t); -void p9_sgpe_ipc_pgpe_update_active_quads_poll_ack(); -void p9_sgpe_ipc_pgpe_suspend_stop(ipc_msg_t*, void*); -void p9_sgpe_stop_suspend_all_cmes(); - -/// SGPE STOP Interrupt Handlers -void p9_sgpe_fit_handler(); -void p9_sgpe_pgpe_halt_handler(void*, PkIrqId); -void p9_sgpe_checkstop_handler(void*, PkIrqId); -void p9_sgpe_pig_type0_handler(void*, PkIrqId); -void p9_sgpe_pig_type2_handler(void*, PkIrqId); -void p9_sgpe_pig_type3_handler(void*, PkIrqId); -void p9_sgpe_pig_type6_handler(void*, PkIrqId); -void p9_sgpe_ipi3_low_handler(void*, PkIrqId); - -/// Support Functions shared between suspend and block protocol -uint32_t p9_sgpe_stop_suspend_db1_cme(uint32_t, uint32_t); - -/// SGPE STOP Entry and Exit Prototypes -void p9_sgpe_stop_init(); -void p9_sgpe_stop_cme_scominit(uint32_t, uint32_t, uint32_t); - -void p9_sgpe_stop_enter_thread(void*); -void p9_sgpe_stop_entry(); - -void p9_sgpe_stop_exit_thread(void*); -void p9_sgpe_stop_exit(); -void p9_sgpe_stop_exit_handoff_cme(uint32_t); - -/// Procedures shared between Istep4 and SGPE Stop -void p9_hcd_cache_chiplet_l3_dcc_setup(uint32_t); -void p9_hcd_cache_gptr_time_initf(uint32_t); -void p9_hcd_cache_dpll_initf(uint32_t); -void p9_hcd_cache_dcc_skewadjust_setup(uint32_t); -void p9_hcd_cache_repair_initf(uint32_t); -void p9_hcd_cache_initf(uint32_t); -void p9_hcd_cache_scan0(uint32_t, uint64_t, uint64_t); - -#ifdef __cplusplus -} // extern "C" -#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 deleted file mode 100644 index d402c545..00000000 --- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c +++ /dev/null @@ -1,1494 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c $ */ -/* */ -/* OpenPOWER HCODE Project */ -/* */ -/* COPYRIGHT 2015,2018 */ -/* [+] 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_enter_marks.h" - -extern SgpeStopRecord G_sgpe_stop_record; - - -#if HW386311_NDD1_PBIE_RW_PTR_STOP11_FIX - - extern struct ring_save* G_ring_save; - extern uint64_t G_ring_spin[10][2]; - -#endif - -void -p9_sgpe_stop_entry() -{ - uint32_t l3_purge_aborted = 0; - uint32_t ex = 0; - uint32_t ex_mask = 0; - uint32_t ex_index = 0; - uint32_t bitloc = 0; - uint32_t qloop = 0; - uint32_t cloop = 0; - uint32_t climit = 0; - uint32_t cindex = 0; - uint32_t quad_error = 0; - uint64_t host_attn = 0; - uint64_t local_xstop = 0; - data64_t scom_data = {0}; - data64_t temp_data = {0}; -#if HW386311_NDD1_PBIE_RW_PTR_STOP11_FIX - uint32_t spin = 0; -#endif -#if !SKIP_IPC - uint32_t ipc_quad_entry = 0; -#endif - sgpeHeader_t* pSgpeImgHdr = (sgpeHeader_t*)(OCC_SRAM_SGPE_HEADER_ADDR); - - //-------------------------------------------------------------------------- - PK_TRACE("+++++ +++++ BEGIN OF STOP ENTRY +++++ +++++"); - //-------------------------------------------------------------------------- - - //================================ - MARK_TAG(BEGINSCOPE_STOP_ENTRY, 0) - //================================ - - if( in32(G_OCB_OCCFLG2) & BIT32(OCCFLG2_SGPE_HCODE_STOP_REQ_ERR_INJ)) - { - // Clear the injection so things are not permenently stuck - out32(G_OCB_OCCFLG2_CLR, BIT32(OCCFLG2_SGPE_HCODE_STOP_REQ_ERR_INJ)); - PK_TRACE_ERR("SGPE STOP ENTRY ERROR INJECT TRAP"); - PK_PANIC(SGPE_STOP_ENTRY_TRAP_INJECT); - } - - G_sgpe_stop_record.group.core[VECTOR_ENTRY] = 0; - G_sgpe_stop_record.group.quad[VECTOR_ENTRY] = 0; - G_sgpe_stop_record.group.ex01[0] = 0; - G_sgpe_stop_record.group.ex01[1] = 0; - G_sgpe_stop_record.group.ex01[2] = 0; - G_sgpe_stop_record.group.ex01[3] = 0; - G_sgpe_stop_record.group.ex01[4] = 0; - G_sgpe_stop_record.group.ex01[5] = 0; - - for(qloop = 0; qloop < MAX_QUADS; qloop++) - { - if ((G_sgpe_stop_record.group.qswu[VECTOR_ACTIVE] | - G_sgpe_stop_record.group.quad[VECTOR_BLOCKE] | - -#if DISABLE_STOP8 - - G_sgpe_stop_record.group.quad[VECTOR_RCLKE] | - G_sgpe_stop_record.group.quad[VECTOR_RCLKX] | - -#endif - - (~G_sgpe_stop_record.group.quad[VECTOR_CONFIG])) & BIT32(qloop)) - { - continue; - } - - // Calculate EX and Quad targets based on current core stop levels - G_sgpe_stop_record.state[qloop].req_state_x0 = - G_sgpe_stop_record.level[qloop][0] < - G_sgpe_stop_record.level[qloop][1] ? - G_sgpe_stop_record.level[qloop][0] : - G_sgpe_stop_record.level[qloop][1] ; - G_sgpe_stop_record.state[qloop].req_state_x1 = - G_sgpe_stop_record.level[qloop][2] < - G_sgpe_stop_record.level[qloop][3] ? - G_sgpe_stop_record.level[qloop][2] : - G_sgpe_stop_record.level[qloop][3] ; - 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_x0 : - G_sgpe_stop_record.state[qloop].req_state_x1 ; - -#if !DISABLE_STOP8 - - // Check if EX and/or Quad qualifies to proceed with entry - if(G_sgpe_stop_record.state[qloop].act_state_x0 < LEVEL_EX_BASE && - G_sgpe_stop_record.state[qloop].req_state_x0 >= LEVEL_EX_BASE) - { - G_sgpe_stop_record.group.ex01[qloop] |= FST_EX_IN_QUAD; - } - - if(G_sgpe_stop_record.state[qloop].act_state_x1 < LEVEL_EX_BASE && - G_sgpe_stop_record.state[qloop].req_state_x1 >= LEVEL_EX_BASE) - { - G_sgpe_stop_record.group.ex01[qloop] |= SND_EX_IN_QUAD; - } - -#endif - - 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) - { - -#if !DISABLE_STOP8 - - G_sgpe_stop_record.group.quad[VECTOR_ENTRY] |= BIT32(qloop); - -#else - - // if resonant clock disable is completed, process stop11 entry - if (G_sgpe_stop_record.group.quad[VECTOR_RCLKE] & BIT32((qloop + RCLK_DIS_DONE_OFFSET))) - { - G_sgpe_stop_record.group.quad[VECTOR_RCLKE] &= ~BIT32((qloop + RCLK_DIS_DONE_OFFSET)); - G_sgpe_stop_record.group.quad[VECTOR_RCLKE] |= BIT32((qloop + QUAD_IN_STOP11_OFFSET)); - G_sgpe_stop_record.group.core[VECTOR_RCLKE] &= ~BITS32((qloop << 2), 4); - G_sgpe_stop_record.group.quad[VECTOR_ENTRY] |= BIT32(qloop); - - ocb_qssr_t qssr = {0}; - qssr.value = in32(G_OCB_QSSR); - - // check qssr for already stopped ex - G_sgpe_stop_record.group.ex01[qloop] = - (((~qssr.value) & BITS32((qloop << 1), 2)) >> - SHIFT32(((qloop << 1) + 1))); - - } - // if stop11 entry qualifies, hold on processing it but first - // send DB to Quad-Manager to disable the resonant clock - else if (!(G_sgpe_stop_record.group.quad[VECTOR_RCLKE] & BIT32((qloop + QUAD_IN_STOP11_OFFSET)))) - { - // from this point on, only process wakeup when stop11 is entered - G_sgpe_stop_record.group.quad[VECTOR_RCLKE] |= BIT32((qloop + RCLK_DIS_REQ_OFFSET)); - // establish mask to ignore the wakeup while in rclk disable - G_sgpe_stop_record.group.core[VECTOR_RCLKE] |= BITS32((qloop << 2), 4); - - // assume ex0 core0 is good - cindex = (qloop << 2); - ex = 0; - - // if ex0 is bad, switch to ex1 - if (!(G_sgpe_stop_record.group.expg[qloop] & FST_EX_IN_QUAD)) - { - cindex += 2; - ex = 1; - } - - // if first core in the ex is bad - if (!(G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex))) - { - cindex++; - } - - // send DB2 with msgid 0x2 to the first good core - // to trigger Quad Manager to disable resonant clock - - // QM will also clear the cme_flag[rclk_operatable] to - // temporarily disable pstate code from changing rclk - // but the Sibling CME also needs to do so, here SGPE - // will do it for the Sibling. - - if (G_sgpe_stop_record.group.expg[qloop] & (ex + 1)) - { - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_FLAGS_CLR, qloop, (ex ^ 1)), - BIT64(CME_FLAGS_RCLK_OPERABLE)); - } - - PK_TRACE_INF("DB2 MessageID 2(Rclk Entry) sent to core %d", cindex); - -#if NIMBUS_DD_LEVEL != 10 - - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB2, cindex), BIT64(6)); - -#else - - p9_dd1_db_unicast_wr(GPE_SCOM_ADDR_CORE(CPPM_CMEDB2, cindex), BIT64(6)); - -#endif - - } - -#endif - - } - - G_sgpe_stop_record.group.ex01[qloop] &= - G_sgpe_stop_record.group.expg[qloop]; - - if (G_sgpe_stop_record.group.ex01[qloop] || - G_sgpe_stop_record.group.quad[VECTOR_ENTRY]) - { - PK_TRACE_DBG("Actual: clv[%d][%d][%d][%d]", - G_sgpe_stop_record.level[qloop][0], - G_sgpe_stop_record.level[qloop][1], - G_sgpe_stop_record.level[qloop][2], - G_sgpe_stop_record.level[qloop][3]); - - PK_TRACE_DBG("Actual: qlv:[%d]x0lv[%d]x1lv[%d]", - G_sgpe_stop_record.state[qloop].act_state_q, - G_sgpe_stop_record.state[qloop].act_state_x0, - G_sgpe_stop_record.state[qloop].act_state_x1); - - PK_TRACE_DBG("Request: 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); - } - } - - PK_TRACE_DBG("Entry Vectors: Q0_EX[%x] Q1_EX[%x] Q2_EX[%x] QSPWU[%x]", - G_sgpe_stop_record.group.ex01[0], - G_sgpe_stop_record.group.ex01[1], - G_sgpe_stop_record.group.ex01[2], - G_sgpe_stop_record.group.qswu[VECTOR_ACTIVE]); - - PK_TRACE_DBG("Entry Vectors: Q3_EX[%x] Q4_EX[%x] Q5_EX[%x] QENTRY[%x]", - G_sgpe_stop_record.group.ex01[3], - G_sgpe_stop_record.group.ex01[4], - G_sgpe_stop_record.group.ex01[5], - G_sgpe_stop_record.group.quad[VECTOR_ENTRY]); - - - - for(qloop = 0; qloop < MAX_QUADS; qloop++) - { - // if this ex is not up to entry, skip - if (!(ex = G_sgpe_stop_record.group.ex01[qloop])) - { - continue; - } - - // In order to preserve state for PRD, - // If host attn or local xstop present, - // abort L2 Purge and rest of Entry - // Note: Need to read status before stopclocks - // while these registers are still accessible - PK_TRACE("Checking status of Host Attention"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_HOST_ATTN, qloop), host_attn); - - PK_TRACE("Checking status of Local Checkstop"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_LOCAL_XSTOP_ERR, qloop), local_xstop); - - if ((host_attn | local_xstop) & BIT64(0)) - { - PK_TRACE_INF("WARNING: HostAttn or LocalXstop Present, Abort EX Entry for Quad[%d]", qloop); - quad_error |= BIT32(qloop); - continue; - } - } - - for (qloop = 0; qloop < MAX_QUADS; qloop++) - { - // if this ex is not up to entry, skip - if (!(ex = G_sgpe_stop_record.group.ex01[qloop])) - { - continue; - } - - // If this quad is in block exit, copy the PSCR information back to the CPPM PECE Shadow - // Bit 8:13 correspond to 0:5, 8:13, 16:21, and 24:29. Bit 3 corresponds to 32,33,34,35 - if (G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] & BIT32(qloop)) - { - if (G_sgpe_stop_record.group.ex01[qloop] & FST_EX_IN_QUAD) - { - - cindex = qloop << 2; - - if (G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex)) - { - temp_data.value = 0; - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS00, qloop, 0), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) << 8; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 3; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS01, qloop, 0), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)); - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 2; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS02, qloop, 0), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) >> 8; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 1; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS03, qloop, 0), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) >> 16; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)); - - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_PECES, cindex), temp_data.value); - } - - cindex = (qloop << 2) + 1; - - if (G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex)) - { - temp_data.value = 0; - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS10, qloop, 0), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) << 8; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 3; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS11, qloop, 0), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)); - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 2; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS12, qloop, 0), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) >> 8; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 1; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS13, qloop, 0), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) >> 16; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)); - - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_PECES, cindex), temp_data.value); - } - } - - if (G_sgpe_stop_record.group.ex01[qloop] & SND_EX_IN_QUAD) - { - cindex = (qloop << 2) + 2; - - if (G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex)) - { - temp_data.value = 0; - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS00, qloop, 1), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) << 8; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 3; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS01, qloop, 1), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)); - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 2; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS02, qloop, 1), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) >> 8; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 1; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS03, qloop, 1), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) >> 16; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)); - - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_PECES, cindex), temp_data.value); - } - - cindex = (qloop << 2) + 3; - - if (G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex)) - { - temp_data.value = 0; - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS10, qloop, 1), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) << 8; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 3; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS11, qloop, 1), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)); - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 2; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS12, qloop, 1), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) >> 8; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)) << 1; - - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PSCRS13, qloop, 1), scom_data.value); - temp_data.words.upper = (scom_data.words.upper & BITS32(8, 6)) >> 16; - temp_data.words.lower = (scom_data.words.upper & BIT32(3)); - - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_PECES, cindex), temp_data.value); - } - } - - PK_TRACE("Restored PECES due to block wakeup being active"); - - } - } - - -// Permanent workaround to save cme image size -#if NIMBUS_DD_LEVEL == 10 || DISABLE_STOP8 == 1 - - //----------------------------------------------------------- - PK_TRACE("+++++ +++++ EX STOP ENTRY [L2 PURGE] +++++ +++++"); - //----------------------------------------------------------- - - PK_TRACE("Assert L2+NCU purge and NCU tlbie quiesce via SICR[18,21,22]"); - - for(qloop = 0; qloop < MAX_QUADS; qloop++) - { - if (quad_error & BIT32(qloop)) - { - continue; - } - - // insert tlbie quiesce before ncu purge to avoid window condition - // of ncu traffic still happening when purging starts - // Note: chtm purge and drop tlbie quiesce will be done in SGPE - - if (G_sgpe_stop_record.group.ex01[qloop] & FST_EX_IN_QUAD) - { - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_OR, qloop, 0), BIT64(18) | BIT64(21)); - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_OR, qloop, 0), BIT64(22)); - } - - if (G_sgpe_stop_record.group.ex01[qloop] & SND_EX_IN_QUAD) - { - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_OR, qloop, 1), BIT64(18) | BIT64(21)); - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_OR, qloop, 1), BIT64(22)); - } - } - - PK_TRACE("Poll for purged done via EISR[22,23] then Drop L2+NCU purges via SICR[18,22]"); - - for(qloop = 0; qloop < MAX_QUADS; qloop++) - { - if (quad_error & BIT32(qloop)) - { - continue; - } - - if (G_sgpe_stop_record.group.ex01[qloop] & FST_EX_IN_QUAD) - { - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_EISR, qloop, 0), scom_data.value); - } - while((scom_data.words.upper & BITS32(22, 2)) != BITS32(22, 2)); - - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_CLR, qloop, 0), (BIT64(18) | BIT64(22))); - } - - if (G_sgpe_stop_record.group.ex01[qloop] & SND_EX_IN_QUAD) - { - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_EISR, qloop, 1), scom_data.value); - } - while((scom_data.words.upper & BITS32(22, 2)) != BITS32(22, 2)); - - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_CLR, qloop, 1), (BIT64(18) | BIT64(22))); - } - } - - PK_TRACE_DBG("SE.5+: L2 and NCU Purged by SGPE"); - -#endif - - - - // only stop 8 sets x_in - for(qloop = 0; qloop < MAX_QUADS; qloop++) - { - // if this ex is not up to entry, skip - if ((!(ex = G_sgpe_stop_record.group.ex01[qloop])) || (quad_error & BIT32(qloop))) - { - continue; - } - - // ------------------------------------------------------------------------ - PK_TRACE("+++++ +++++ EX STOP ENTRY [LEVEL 8-10] +++++ +++++"); - // ------------------------------------------------------------------------ - - if (ex & FST_EX_IN_QUAD) - { - cloop = 0; - } - else - { - cloop = CORES_PER_EX; - } - - if (ex & SND_EX_IN_QUAD) - { - climit = CORES_PER_QUAD; - } - else - { - climit = CORES_PER_EX; - } - - for(; cloop < climit; cloop++) - { - cindex = (qloop << 2) + cloop; - - // Check partial good core - if (!(G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex))) - { - continue; - } - - PK_TRACE("Update STOP history on core[%d]: continue on entering", cindex); - scom_data.words.lower = 0; - scom_data.words.upper = SSH_ENTRY_IN_SESSION; - GPE_PUTSCOM_VAR(PPM_SSHSRC, CORE_ADDR_BASE, cindex, 0, scom_data.value); - } - - PK_TRACE_INF("SE.8A: Quad[%d] EX_L2[%d] Stopping L2 Clocks", qloop, ex); - - PK_TRACE("Acquire cache clock controller atomic lock"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CC_ATOMIC_LOCK, qloop), BITS64(0, 5)); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CC_ATOMIC_LOCK, qloop), scom_data.value); - - if ((scom_data.words.upper & BITS32(0, 5)) != 0xC0000000) - { - PK_TRACE_ERR("ERROR: Failed to Obtain Cache %d Clk Ctrl Atomic Lock. Register Content: %x", - qloop, scom_data.words.upper); - SGPE_STOP_QUAD_ERROR_HANDLER(qloop, SGPE_STOP_ENTRY_GET_CLK_LOCK_FAILED); - continue; - } - - PK_TRACE("Update QSSR: stop_entry_ongoing"); - out32(G_OCB_QSSR_OR, BIT32(qloop + 20)); - - //==================================================== - MARK_TAG(SE_STOP_L2_CLKS, ((ex << 6) | (32 >> qloop))) - //==================================================== - - PK_TRACE("Drop L2 Snoop(quiesce L2-L3 interface) via EX_PM_L2_RCMD_DIS_REG[0]"); - - if (ex & FST_EX_IN_QUAD) - { - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_L2_RCMD_DIS_REG, qloop, 0), BIT64(0)); - } - - if (ex & SND_EX_IN_QUAD) - { - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_L2_RCMD_DIS_REG, qloop, 1), BIT64(0)); - } - - PPE_WAIT_CORE_CYCLES(256) - - PK_TRACE("Assert partial bad L2/L3 and stopping/stoped l2 pscom masks via RING_FENCE_MASK_LATCH"); - scom_data.value = 0; - - if (!(G_sgpe_stop_record.group.expg[qloop] & FST_EX_IN_QUAD)) - { - scom_data.words.upper |= (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.words.upper |= PSCOM_MASK_EX0_L2; - } - - if (!(G_sgpe_stop_record.group.expg[qloop] & SND_EX_IN_QUAD)) - { - scom_data.words.upper |= (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.words.upper |= PSCOM_MASK_EX1_L2; - } - - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_RING_FENCE_MASK_LATCH, qloop), scom_data.value); - - - - PK_TRACE("Clear SCAN_REGION_TYPE prior to stop L2 clocks"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, qloop), 0); - - PK_TRACE("Stop L2 clocks via CLK_REGION[8/9]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, qloop), - (CLK_STOP_CMD | CLK_THOLD_ALL | - ((uint64_t)ex << SHIFT64(9)))); - - PK_TRACE("Poll for L2 clocks stopped via CPLT_STAT0[8]"); - - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, qloop), scom_data.value); - } - while(!(scom_data.words.upper & BIT32(8))); - - PK_TRACE("Check L2 clock is stopped via CLOCK_STAT_SL[4-13]"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, qloop), scom_data.value); - - if (((~(scom_data.words.upper)) & (ex << SHIFT32(9))) != 0) - { - PK_TRACE_ERR("ERROR: L2 clock stop failed. HALT SGPE!"); - SGPE_STOP_QUAD_ERROR_HANDLER(qloop, SGPE_STOP_ENTRY_L2_STOPCLK_FAILED); - continue; - } - - // MF: verify compiler generate single rlwmni - // MF: delay may be needed for stage latch to propagate thold - - PK_TRACE_DBG("SE.8B: L2 Clock Stopped"); - - //======================== - MARK_TRAP(SE_STOP_L2_GRID) - //======================== - - PK_TRACE("Drop clock sync enable before switch to refclk via EXCGCR[36/37]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_CLR, qloop), - ((uint64_t)ex << SHIFT64(37))); - - PK_TRACE("Poll for clock sync done to drop via QACSR[36/37]"); - - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QACSR, qloop), scom_data.value); - } - while((((~(scom_data.words.lower)) >> SHIFT64SH(37)) & ex) != ex); - - PK_TRACE("Switch glsmux to refclk to save clock grid power via EXCGCR[34/35]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_CLR, qloop), - ((uint64_t)ex << SHIFT64(35))); - - if (ex & FST_EX_IN_QUAD) - { - cloop = 0; - G_sgpe_stop_record.state[qloop].act_state_x0 = STOP_LEVEL_8; - } - else - { - cloop = CORES_PER_EX; - } - - if (ex & SND_EX_IN_QUAD) - { - climit = CORES_PER_QUAD; - G_sgpe_stop_record.state[qloop].act_state_x1 = STOP_LEVEL_8; - } - else - { - climit = CORES_PER_EX; - } - - for(; cloop < climit; cloop++) - { - cindex = (qloop << 2) + cloop; - - // Check partial good core - if (!(G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex))) - { - continue; - } - - PK_TRACE("Update STOP history on core[%d]: in stop level 8", cindex); - scom_data.words.lower = 0; - scom_data.words.upper = SSH_ACT_LV8_COMPLETE; - GPE_PUTSCOM_VAR(PPM_SSHSRC, CORE_ADDR_BASE, cindex, 0, scom_data.value); - } - - PK_TRACE("Update QSSR: l2_stopped, drop stop_entry_ongoing"); - out32(G_OCB_QSSR_CLR, BIT32(qloop + 20)); - out32(G_OCB_QSSR_OR, (ex << SHIFT32((qloop << 1) + 1))); - - PK_TRACE_DBG("SE.8C: L2 Clock Sync Dropped"); - - PK_TRACE("Release cache clock controller atomic lock"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CC_ATOMIC_LOCK, qloop), 0); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CC_ATOMIC_LOCK, qloop), scom_data.value); - - if (scom_data.words.upper & BIT32(0)) - { - PK_TRACE_ERR("ERROR: Failed to Release Cache %d Clk Ctrl Atomic Lock. Register Content: %x", - qloop, scom_data.words.upper); - SGPE_STOP_QUAD_ERROR_HANDLER(qloop, SGPE_STOP_ENTRY_DROP_CLK_LOCK_FAILED); - continue; - } - - //================================================== - MARK_TAG(SE_STOP8_DONE, ((ex << 6) | (32 >> qloop))) - //================================================== - - } - - - - // L3 Purge loop to parallel all quad purges - for(qloop = 0; qloop < MAX_QUADS; qloop++) - { - // if this quad is not up to entry, skip - if (!(G_sgpe_stop_record.group.quad[VECTOR_ENTRY] & BIT32(qloop))) - { - continue; - } - - // In order to preserve state for PRD, - // If host attn or local xstop present, - // abort L3 Purge and rest of Entry - // Note: Need to read status before stopclocks - // while these registers are still accessible - PK_TRACE("Checking status of Host Attention"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_HOST_ATTN, qloop), host_attn); - - PK_TRACE("Checking status of Local Checkstop"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_LOCAL_XSTOP_ERR, qloop), local_xstop); - - if ((host_attn | local_xstop) & BIT64(0)) - { - PK_TRACE_INF("WARNING: HostAttn or LocalXstop Present, Abort L3 Purge on Quad[%d]", qloop); - quad_error |= BIT32(qloop); - } - - // for L3 Purge check above and L2 Purge check earlier - if (quad_error & BIT32(qloop)) - { - // Take this out for rest of Stop11 entry and IPC code at the end - G_sgpe_stop_record.group.quad[VECTOR_ENTRY] &= ~BIT32(qloop); - continue; - } - - // ------------------------------------------------------------------------ - PK_TRACE("+++++ +++++ QUAD STOP ENTRY [LEVEL 11-15, L3 PURGE] +++++ +++++"); - // ------------------------------------------------------------------------ - - ex = G_sgpe_stop_record.group.expg[qloop]; - - for(cloop = 0; cloop < CORES_PER_QUAD; cloop++) - { - cindex = (qloop << 2) + cloop; - - // Check partial good core - if (!(G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex))) - { - continue; - } - - PK_TRACE("Update STOP history on core[%d]: continue entering", cindex); - scom_data.words.lower = 0; - scom_data.words.upper = SSH_ENTRY_IN_SESSION; - GPE_PUTSCOM_VAR(PPM_SSHSRC, CORE_ADDR_BASE, cindex, 0, scom_data.value); - } - - PK_TRACE("Update STOP history on quad[%d]: update request stop level", qloop); - scom_data.words.lower = 0; - scom_data.words.upper = (SSH_REQ_LEVEL_UPDATE | - ((uint32_t)G_sgpe_stop_record.state[qloop].req_state_q << SHIFT32(7))); - GPE_PUTSCOM_VAR(PPM_SSHSRC, QUAD_ADDR_BASE, qloop, 0, scom_data.value); - - PK_TRACE("Update QSSR: stop_entry_ongoing"); - out32(G_OCB_QSSR_OR, BIT32(qloop + 20)); - - PK_TRACE_INF("SE.11A: Quad[%d] EX_PG[%d] Shutting Cache Down", qloop, ex); - - //================================== - MARK_TAG(SE_PURGE_L3, (32 >> qloop)) - //================================== - - PK_TRACE("Drop LCO prior to purge via EX_PM_LCO_DIS_REG[0]"); - - if(ex & FST_EX_IN_QUAD) - { - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_LCO_DIS_REG, qloop, 0), - BIT64(0)); - } - - if(ex & SND_EX_IN_QUAD) - { - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_LCO_DIS_REG, qloop, 1), - BIT64(0)); - } - -#if !SKIP_L3_PURGE - - for (ex_mask = 2; ex_mask; ex_mask--) - { - if (ex & ex_mask) - { - ex_index = ex_mask & 1; - - PK_TRACE("Assert purge L3 on EX[%d] via EX_PM_PURGE_REG[0]", ex_index); - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, qloop, ex_index), BIT64(0)); - - PK_TRACE("Halt CHTM[0+1] on EX[%d] via HTM_TRIG[1]", ex_index); - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_CHTM0_TRIG_REG, qloop, ex_index), BIT64(1)); - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_CHTM1_TRIG_REG, qloop, ex_index), BIT64(1)); - - // Disable PMISC and IMA - Bits 1,2,4 - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_CHTM0_CTRL_REG, qloop, ex_index), 0); - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_CHTM1_CTRL_REG, qloop, ex_index), 0); - - // Disable Tracing - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_CHTM0_MODE_REG, qloop, ex_index), 0); - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_CHTM1_MODE_REG, qloop, ex_index), 0); - - } - } - - PK_TRACE("Disable cme trace array via DEBUG_TRACE_CONTROL[1]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(DEBUG_TRACE_CONTROL, qloop), BIT64(1)); - - } - - - - // L3 Purge done poll loop to parallel all quad purge done polls - for(qloop = 0; qloop < MAX_QUADS; qloop++) - { - // if this quad is not up to entry, skip - if (!(G_sgpe_stop_record.group.quad[VECTOR_ENTRY] & BIT32(qloop))) - { - continue; - } - - ex = G_sgpe_stop_record.group.expg[qloop]; - - // ------------------------------------------------------------------------------ - PK_TRACE("+++++ +++++ QUAD STOP ENTRY [LEVEL 11-15, L3 PURGE DONE] +++++ +++++"); - // ------------------------------------------------------------------------------ - - PK_TRACE("Poll for L3 purge done via EX_PM_PURGE_REG[0]"); - - // Poll on the same request bit thus no need to deassert - do - { - -#if !SKIP_L3_PURGE_ABORT - - if ((in32(G_OCB_OISR1) & (BITS32(15, 2) | BIT32(19))) && - // Skip L3 Purge Abort check if in Block Wakeup mode - (!(G_sgpe_stop_record.group.quad[VECTOR_BLOCKX] & BIT32(qloop)))) - { - PK_TRACE("Abort: interrupt detected"); - - if ((in32(G_OCB_OPIT2PRA) & BITS32((qloop << 2), 4)) || - (in32(G_OCB_OPIT3PRA) & BITS32((qloop << 2), 4))) - { - PK_TRACE("Abort: core interrupt detected"); - - for(cloop = 0; cloop < CORES_PER_QUAD; cloop++) - { - cindex = (qloop << 2) + cloop; - - if ((in32(OCB_OPIT2CN(cindex)) & TYPE2_PAYLOAD_EXIT_EVENT) || - (in32(OCB_OPIT3CN(cindex)) & TYPE2_PAYLOAD_EXIT_EVENT)) - { - PK_TRACE_DBG("Abort: core wakeup detected"); - l3_purge_aborted = 1; - break; - } - } - } - - if ((in32(G_OCB_OPIT6PRB) & BIT32(qloop)) && - (in32(OCB_OPIT6QN(qloop)) & TYPE6_PAYLOAD_EXIT_EVENT)) - { - PK_TRACE_DBG("Abort: quad wakeup detected"); - l3_purge_aborted = 1; - } - - if (l3_purge_aborted) - { - - //======================================== - MARK_TAG(SE_PURGE_L3_ABORT, (32 >> qloop)) - //======================================== - - PK_TRACE_DBG("Abort: assert purge L3 abort"); - - if (ex & FST_EX_IN_QUAD) - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, qloop, 0), - BIT64(2)); - - if (ex & SND_EX_IN_QUAD) - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, qloop, 1), - BIT64(2)); - - PK_TRACE_DBG("Abort: poll for abort done"); - - if(ex & FST_EX_IN_QUAD) - { - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, - qloop, 0), scom_data.value); - } - while(scom_data.words.upper & (BIT32(0) | BIT32(2))); - } - - if(ex & SND_EX_IN_QUAD) - { - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, - qloop, 1), scom_data.value); - } - while(scom_data.words.upper & (BIT32(0) | BIT32(2))); - } - - //============================================= - MARK_TAG(SE_PURGE_L3_ABORT_DONE, (32 >> qloop)) - //============================================= - - PK_TRACE("Abort: Drop LCO Disable"); - - if (ex & FST_EX_IN_QUAD) - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_LCO_DIS_REG, - qloop, 0), 0); - - if (ex & SND_EX_IN_QUAD) - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_LCO_DIS_REG, - qloop, 1), 0); - } - } - -#endif - scom_data.value = 0; - temp_data.value = 0; - - if (ex & FST_EX_IN_QUAD) - { - GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, qloop, 0), - scom_data.value); - } - - if (ex & SND_EX_IN_QUAD) - { - GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, qloop, 1), - temp_data.value); - } - } - while((scom_data.words.upper | temp_data.words.upper) & BIT32(0)); - - if (l3_purge_aborted) - { - PK_TRACE_INF("Abort: L3 Purge Aborted"); - -#if DISABLE_STOP8 - - // assume ex0 core0 is good - cindex = (qloop << 2); - - // if ex0 is bad, switch to ex1 - if (!(G_sgpe_stop_record.group.expg[qloop] & FST_EX_IN_QUAD)) - { - cindex += 2; - } - - // if first core in the ex is bad, switch to second core - if (!(G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex))) - { - cindex++; - } - - // send DB2 with msgid 0x3 to the first good core - // to trigger Quad Manager to enable resonant clock again - - PK_TRACE_INF("DB2 MessageID 3(Rclk Entry Abort) sent to core %d", cindex); - -#if NIMBUS_DD_LEVEL != 10 - - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB2, cindex), BITS64(6, 2)); - -#else - - p9_dd1_db_unicast_wr(GPE_SCOM_ADDR_CORE(CPPM_CMEDB2, cindex), BITS64(6, 2)); - -#endif - - // block handoff to cme until resonant clock enable is completed. - G_sgpe_stop_record.group.quad[VECTOR_RCLKX] |= BIT32(qloop); - -#endif - - PK_TRACE("Update QSSR afer L3 Purge Abort: drop stop_entry_ongoing"); - out32(OCB_QSSR_CLR, BIT32(qloop + 20)); - - PK_TRACE("Clear stop history on quad[%d]", qloop); - scom_data.words.lower = 0; - scom_data.words.upper = SSH_EXIT_COMPLETE; - GPE_PUTSCOM_VAR(PPM_SSHSRC, QUAD_ADDR_BASE, qloop, 0, scom_data.value); - - // For IPC reporting, taking aborted quad out of the list - G_sgpe_stop_record.group.quad[VECTOR_ENTRY] &= ~BIT32(qloop); - continue; - } - - PK_TRACE_DBG("SE.11B: L3 Purged"); - -#endif - - } - - - - // loop for rest of quad stop - for(qloop = 0; qloop < MAX_QUADS; qloop++) - { - // if this quad is not up to entry, skip - if (!(G_sgpe_stop_record.group.quad[VECTOR_ENTRY] & BIT32(qloop))) - { - continue; - } - - ex = G_sgpe_stop_record.group.expg[qloop]; - - // ------------------------------------------------------------------------------ - PK_TRACE("+++++ +++++ QUAD STOP ENTRY [LEVEL 11-15, CONTINUE] +++++ +++++"); - // ------------------------------------------------------------------------------ - -#if !SKIP_IPC - - // Upon entry into STOP 11, right before stopping the clocks to the cache chiplet - // the SGPE must communicate to the PGPE to - // allow it to know which CME Quad Managers will no longer be active; and - // if WOF is enabled, - // to perform VRFT calculations to take advantage of the core/cache power. - // If Pstates are disabled, SGPE does nothing. - // If Pstates are enabled, the SGPE: - // 1. sends Suspend Pstates IPC to PGPE and waits for the response IPC . - // PGPE completes any current Pstate operations and responses to the Suspend Pstates IPC. - // 2. stops the clocks (and optionally finishes the entry) - // 3. sends Update Active Quads IPC to PGPE and waits for the response IPC. - // PGPE, as a side effect of processing the Update Active Quads IPC, - // will resume Pstate protocol operations. - // 4. optionally finishes the entry (if not done above) - - if ((!ipc_quad_entry) && - (in32(G_OCB_OCCS2) & BIT32(PGPE_ACTIVE)) && - G_sgpe_stop_record.wof.update_pgpe != IPC_SGPE_PGPE_UPDATE_PGPE_HALTED && - G_sgpe_stop_record.group.quad[VECTOR_ENTRY]) // entry into STOP11 - { - //============================ - MARK_TRAP(SE_PGPE_QUAD_NOTIFY) - //============================ - - p9_sgpe_ipc_pgpe_update_active_quads(UPDATE_ACTIVE_QUADS_TYPE_ENTRY, - UPDATE_ACTIVE_QUADS_ENTRY_TYPE_NOTIFY); - - //=============================================== - MARK_TAG(SE_WAIT_PGPE_QUAD_NOTIFY, (32 >> qloop)) - //=============================================== - - p9_sgpe_ipc_pgpe_update_active_quads_poll_ack(UPDATE_ACTIVE_QUADS_TYPE_ENTRY); - ipc_quad_entry = 1; - } - -#endif - - //================================== - MARK_TAG(SE_PURGE_PB, (32 >> qloop)) - //================================== - - PK_TRACE("Acquire cache PCB slave atomic lock"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_ATOMIC_LOCK, qloop), BITS64(0, 5)); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_ATOMIC_LOCK, qloop), scom_data.value); - - if ((scom_data.words.upper & BITS32(0, 5)) != 0xC0000000) - { - PK_TRACE_ERR("ERROR: Failed to Obtain Cache %d PCB Slave Atomic Lock. Register Content: %x", - qloop, scom_data.words.upper); - SGPE_STOP_QUAD_ERROR_HANDLER(qloop, SGPE_STOP_ENTRY_GET_SLV_LOCK_FAILED); - continue; - } - - // Stopping CME first in case CME initiates Powerbus Traffic - - if (ex & FST_EX_IN_QUAD) - { - PK_TRACE("Halting CME0"); - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_XIXCR, qloop, 0), BIT64(3)); - } - - if (ex & SND_EX_IN_QUAD) - { - PK_TRACE("Halting CME1"); - GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_XIXCR, qloop, 1), BIT64(3)); - } - - if (ex & FST_EX_IN_QUAD) - { - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_XIRAMDBG, qloop, 0), - scom_data.value); - } - while(!(scom_data.words.upper & BIT32(0))); - - PK_TRACE("CME0 Halted"); - } - - if (ex & SND_EX_IN_QUAD) - { - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_XIRAMDBG, qloop, 1), - scom_data.value); - } - while(!(scom_data.words.upper & BIT32(0))); - - PK_TRACE("CME1 Halted"); - } - - PK_TRACE_DBG("CME Halted"); - - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QACCR, qloop), scom_data.value); - - if (scom_data.words.upper) - { - // Stop11 needs resclk to be off, otherwise exit will fail - PK_TRACE_ERR("ERROR: Q[%d]ACCR[%x] is not clean after CMEs are halted", - qloop, scom_data.words.upper); - PK_PANIC(SGPE_STOP_ENTRY_STOP11_RESCLK_ON); - } - - //Set Quad GPMMR RESET_STATE_INDICATOR bit to indicate CME is offline - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_GPMMR_OR, qloop), BIT64(15)); - - PK_TRACE("Assert powerbus purge via QCCR[30]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, qloop), BIT64(30)); - - PK_TRACE("Poll PowerBus purge done via QCCR[31]"); - - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR, qloop), scom_data.value); - } - while(!(scom_data.words.upper & BIT32(31))); - - PK_TRACE("Drop powerbus purge via QCCR[30]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(30)); - - PK_TRACE_DBG("SE.11C: PowerBus Purged"); - - //====================================== - MARK_TAG(SE_QUIESCE_QUAD, (32 >> qloop)) - //====================================== - - PK_TRACE("Assert refresh quiesce prior to L3 (refresh domain) stop clk via EX_DRAM_REF_REG[7]"); - - // Assert refresh quiesce prior to L3 (refresh domain) stop clk - // Edram quiesce is asserted by hardware when l3 thold is asserted in cc - if (ex & FST_EX_IN_QUAD) - { - GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_DRAM_REF_REG, qloop, 0), scom_data.value); - scom_data.words.upper |= BIT32(7); - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_DRAM_REF_REG, qloop, 0), scom_data.value); - } - - if (ex & SND_EX_IN_QUAD) - { - GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_DRAM_REF_REG, qloop, 1), scom_data.value); - scom_data.words.upper |= BIT32(7); - GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_DRAM_REF_REG, qloop, 1), scom_data.value); - } - - PK_TRACE("Check NCU_STATUS_REG[0:3] for all zeros"); - // HW407207 - can only check bit 0:2 - - if (ex & FST_EX_IN_QUAD) - { - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_NCU_STATUS_REG, qloop, 0), - scom_data.value); - PK_TRACE("Polling NCU_STATUS_REG 0"); - } - while(((~(scom_data.words.upper)) & BITS32(0, 3)) != BITS32(0, 3)); - } - - if (ex & SND_EX_IN_QUAD) - { - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_NCU_STATUS_REG, qloop, 1), - scom_data.value); - PK_TRACE("Polling NCU_STATUS_REG 1"); - } - while(((~(scom_data.words.upper)) & BITS32(0, 3)) != BITS32(0, 3)); - } - - PK_TRACE_DBG("NCU Status Clean"); - - // PGPE may have already cleared bit26: DPLL_ENABLE if booted, - // but SGPE can always do it in case PGPE isnt booted - PK_TRACE("Drop CME_INTERPPM_IVRM/ACLK/VDATA_ENABLE via QPMMR[20,22,24]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QPMMR_CLR, qloop), (BIT64(20) | BIT64(22) | BIT64(24) | BIT64(26))); - - if(pSgpeImgHdr->g_sgpe_reserve_flags & SGPE_VDM_ENABLE_BIT_POS) - { - PK_TRACE("Clear Jump Protect Enable (no need to poll DPLL_STAT"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_DPLL_CTRL_CLEAR, qloop), BIT64(1)); - - PK_TRACE("Write QPPM VDMCR to set Disable and clear Poweron"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_VDMCR, qloop), BIT64(1)); - - PK_TRACE("Clear QPPM VDMCFGR"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_VDMCFGR, qloop), 0); - } - - //=========================== - MARK_TRAP(SE_STOP_CACHE_CLKS) - //=========================== - - PK_TRACE("Assert cache chiplet fence via NET_CTRL0[18]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, qloop), BIT64(18)); - - PK_TRACE("Switch glsmux to refclk to save clock grid power via CGCR[3]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_PPM_CGCR, qloop), 0); - - PK_TRACE("Clear SCAN_REGION prior to stop cache clocks"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, qloop), 0); - - PK_TRACE("Stop cache clocks via CLK_REGION"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, qloop), - (CLK_STOP_CMD | CLK_THOLD_ALL | CLK_REGION_ALL)); - - PK_TRACE("Poll for cache clocks stopped via CPLT_STAT0[8]"); - - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_STAT0, qloop), scom_data.value); - } - while(!(scom_data.words.upper & BIT32(8))); - - PK_TRACE("Check cache clock is stopped via CLOCK_STAT_SL[4-13]"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, qloop), scom_data.value); - - if (((~scom_data.value) & CLK_REGION_ALL) != 0) - { - PK_TRACE_ERR("ERROR: Cache clock stop failed. HALT SGPE!"); - SGPE_STOP_QUAD_ERROR_HANDLER(qloop, SGPE_STOP_ENTRY_EQ_STOPCLK_FAILED); - continue; - } - - PK_TRACE("Assert vital fence via CPLT_CTRL1[3]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_OR, qloop), BIT64(3)); - - PK_TRACE("Assert partial good regional fences via CPLT_CTRL1[4-14]"); - // 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), CLK_REGION_ALL); - - PK_TRACE_DBG("SE.11D: Cache Clock Stopped"); - - PK_TRACE("Gate the PCBMux request so scanning doesn't cause random requests"); - - for(cloop = 0; cloop < CORES_PER_QUAD; cloop++) - { - cindex = (qloop << 2) + cloop; - - // only loop over configured cores - if (!(G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex))) - { - continue; - } - - GPE_GETSCOM(GPE_SCOM_ADDR_CORE(C_SLAVE_CONFIG, cindex), scom_data.value); - scom_data.words.upper |= BITS32(6, 2); - GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(C_SLAVE_CONFIG, cindex), scom_data.value); - } - - //========================================= - MARK_TAG(SE_POWER_OFF_CACHE, (32 >> qloop)) - //========================================= - -#if HW386311_NDD1_PBIE_RW_PTR_STOP11_FIX - - PK_TRACE_DBG("PBRW: Engage with PBIE Read/Write Pointer Scan Workaround"); - - // bit4,5,11 = perv/eqpb/pbieq, bit59 = inex - PK_TRACE("PBRW: Setup scan register to select the ring"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10030005, qloop), BITS64(4, 2) | BIT64(11) | BIT64(59)); - - PK_TRACE("PBRW: checkword set"); - scom_data.value = 0xa5a5a5a5a5a5a5a5; - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data.value); - - for(spin = 1;; spin++) - { - PK_TRACE("PBRW: spin ring loop%d", spin); - scom_data.words.upper = (G_ring_spin[spin][0] - G_ring_spin[spin - 1][0]); - scom_data.words.lower = 0; - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10039000, qloop), scom_data.value); - - PK_TRACE("PBRW: Poll OPCG done for ring spin"); - - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x10000100, qloop), scom_data.value); - } - while(!(scom_data.words.upper & BIT32(8))); - - if (spin == 9) - { - PK_TRACE("PBRW: checkword check"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data.value); - - if (scom_data.value != 0xa5a5a5a5a5a5a5a5) - { - PK_TRACE_ERR("ERROR: Checkword[%x%x] Failed. HALT SGPE!", - scom_data.words.upper, scom_data.words.lower); - PK_PANIC(SGPE_STOP_ENTRY_PBRW_SCAN_HEADER_ERR); - } - - break; - } - - PK_TRACE("PBRW: save pbie read ptr"); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(0x1003E000, qloop), scom_data.value); - EXTRACT_RING_BITS(G_ring_spin[spin][1], scom_data.value, - G_ring_save->element[qloop][spin - 1]); - PK_TRACE("PBRW: mask: %8x %8x", - UPPER32(G_ring_spin[spin][1]), - LOWER32(G_ring_spin[spin][1])); - PK_TRACE("PBRW: ring: %8x %8x", - scom_data.words.upper, - scom_data.words.lower); - PK_TRACE("PBRW: save: %8x %8x", - UPPER32(G_ring_save->element[qloop][spin - 1]), - LOWER32(G_ring_save->element[qloop][spin - 1])); - } - - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(0x10030005, qloop), 0); - -#endif - - PK_TRACE("Assert PCB fence via NET_CTRL0[25]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, qloop), BIT64(25)); - - PK_TRACE("Assert electrical fence via NET_CTRL0[26]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, qloop), BIT64(26)); - - PK_TRACE("Drop sram_enable via NET_CTRL0[23]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WAND, qloop), ~BIT64(23)); - - PK_TRACE("Assert vital thold via NET_CTRL0[16]"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, qloop), BIT64(16)); - - PK_TRACE("Shutdown L3 EDRAM via QCCR[0-3/4-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 - for (ex_mask = 2; ex_mask; ex_mask--) - { - if (ex & ex_mask) - { - bitloc = (ex_mask & 1) << 2; - - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), - BIT64((bitloc + 3))); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), - BIT64((bitloc + 2))); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), - BIT64((bitloc + 1))); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), - BIT64(bitloc)); - } - } - -#if !STOP_PRIME - - PK_TRACE("Drop vdd/vcs_pfet_val/sel_override/regulation_finger_en via PFCS[4-7,8]"); - // vdd_pfet_val/sel_override = 0 (disbaled) - // vcs_pfet_val/sel_override = 0 (disbaled) - // vdd_pfet_regulation_finger_en = 0 (controled by FSM) - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, qloop), - BITS64(4, 4) | BIT64(8)); - - PK_TRACE("Power off VCS via PFCS[2-3]"); - // vcs_pfet_force_state = 01 (Force Voff) - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_OR, qloop), BIT64(3)); - - PK_TRACE("Poll for vcs_pfets_disabled_sense via PFSNS[3]"); - - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFSNS, qloop), scom_data.value); - } - while(!(scom_data.words.upper & BIT32(3))); - - PK_TRACE("Power off VDD via PFCS[0-1]"); - // vdd_pfet_force_state = 01 (Force Voff) - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_OR, qloop), BIT64(1)); - - PK_TRACE("Poll for vdd_pfets_disabled_sense via PFSNS[1]"); - - do - { - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFSNS, qloop), scom_data.value); - } - while(!(scom_data.words.upper & BIT32(1))); - - PK_TRACE("Turn off force voff via PFCS[0-3]"); - // vdd_pfet_force_state = 00 (Nop) - // vcs_pfet_force_state = 00 (Nop) - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, qloop), BITS64(0, 4)); - - PK_TRACE_DBG("SE.11E: Cache Powered Off"); - -#endif - - PK_TRACE("Release cache PCB slave atomic lock"); - GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_ATOMIC_LOCK, qloop), 0); - GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_ATOMIC_LOCK, qloop), scom_data.value); - - if (scom_data.words.upper & BIT32(0)) - { - PK_TRACE_ERR("ERROR: Failed to Release Cache %d PCB Slave Atomic Lock. Register Content: %x", - qloop, scom_data.words.upper); - SGPE_STOP_QUAD_ERROR_HANDLER(qloop, SGPE_STOP_ENTRY_DROP_SLV_LOCK_FAILED); - continue; - } - - for(cloop = 0; cloop < CORES_PER_QUAD; cloop++) - { - cindex = (qloop << 2) + cloop; - - // Check partial good core - if (!(G_sgpe_stop_record.group.core[VECTOR_CONFIG] & BIT32(cindex))) - { - continue; - } - - PK_TRACE("Update STOP history on core[%d]: in stop level 11", cindex); - scom_data.words.lower = 0; - scom_data.words.upper = SSH_ACT_LV11_COMPLETE ; - GPE_PUTSCOM_VAR(PPM_SSHSRC, CORE_ADDR_BASE, cindex, 0, scom_data.value); - } - - PK_TRACE("Update STOP history on quad[%d]: in stop level 11", qloop); - scom_data.words.lower = 0; - scom_data.words.upper = SSH_ACT_LV11_COMPLETE; - GPE_PUTSCOM_VAR(PPM_SSHSRC, QUAD_ADDR_BASE, qloop, 0, scom_data.value); - - PK_TRACE("Update QSSR: quad_stopped"); - out32(G_OCB_QSSR_OR, BIT32(qloop + 14)); - - PK_TRACE("Update QSSR: drop stop_entry_ongoing"); - out32(G_OCB_QSSR_CLR, BIT32(qloop + 20)); - - G_sgpe_stop_record.state[qloop].act_state_q = STOP_LEVEL_11; - G_sgpe_stop_record.group.quad[VECTOR_ACTIVE] &= ~BIT32(qloop); - G_sgpe_stop_record.group.qswu[VECTOR_ENTRY] &= ~BIT32(qloop); - - //===================================== - MARK_TAG(SE_STOP11_DONE, (32 >> qloop)) - //===================================== - } - - //-------------------------------------------------------------------------- - PK_TRACE("+++++ +++++ END OF STOP ENTRY +++++ +++++"); - //-------------------------------------------------------------------------- - -#if !SKIP_IPC - - if ((in32(G_OCB_OCCS2) & BIT32(PGPE_ACTIVE)) && - G_sgpe_stop_record.wof.update_pgpe != IPC_SGPE_PGPE_UPDATE_PGPE_HALTED && - G_sgpe_stop_record.group.quad[VECTOR_ENTRY]) - { - // Note: if all quads aborted on l3 purge, the quad list will be 0s; - p9_sgpe_ipc_pgpe_update_active_quads(UPDATE_ACTIVE_QUADS_TYPE_ENTRY, - UPDATE_ACTIVE_QUADS_ENTRY_TYPE_DONE); - - // pgpe should ack right away - p9_sgpe_ipc_pgpe_update_active_quads_poll_ack(UPDATE_ACTIVE_QUADS_TYPE_ENTRY); - } - -#endif - - //============================ - MARK_TRAP(ENDSCOPE_STOP_ENTRY) - //============================ - - return; -} |

