From ae077907670f4c5442a12f20ee2f694500b4b757 Mon Sep 17 00:00:00 2001 From: crgeddes Date: Tue, 21 Feb 2017 20:58:21 -0600 Subject: [PATCH] Update quad power off so HB can call it on Slave Quads Previously this HWP was only being called by the SBE down the MPIPL but we also need to call it during HB to power down the slave quads. There is a tricky workaround in this HWP where we need to save off some ring data EQ pointers for the PB. On the SBE we just saved the rings in global variables but we cannot do that in HB because the Hcode would not have access to the global varibles. Instead we will write the ring data to the OCC SRAM to do this I will just pass the data out of the hwp via an out param The same ring data is fetch during cache_initf procedure to init Change-Id: I4f20cd8dd9ca1b53604db1bc3020c0d57bbd1172 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/36828 Tested-by: Jenkins Server Tested-by: PPE CI Tested-by: Hostboot CI Reviewed-by: Matt K. Light Reviewed-by: RAJA DAS Reviewed-by: YUE DU Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/37978 Reviewed-by: Hostboot Team Tested-by: FSP CI Jenkins Tested-by: Jenkins OP Build CI Reviewed-by: Christian R. Geddes --- .../p9/procedures/hwp/pm/p9_quad_power_off.C | 34 ++-- .../p9/procedures/hwp/pm/p9_quad_power_off.H | 15 +- .../isteps/istep06/host_discover_targets.C | 161 ++++++------------ 3 files changed, 77 insertions(+), 133 deletions(-) diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.C b/src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.C index 73246bbb070..b59ad86d8a6 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.C +++ b/src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.C @@ -49,14 +49,11 @@ #include #include + // ---------------------------------------------------------------------- // Function definitions // ---------------------------------------------------------------------- - -#ifdef __PPE__ -uint64_t G_ring_save[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - // {0, 0}, // {5039, 0xE000000000000000}, //3 // {5100, 0xC1E061FFED5F0000}, //29 @@ -67,40 +64,38 @@ uint64_t G_ring_save[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // {6282, 0xE000000000000000}, //3 // {6343, 0xC1E061FFED5F0000}, //29 // {17871, 0} //128 -const uint64_t G_ring_index[10] = + +static const uint64_t RING_INDEX[10] = { 0, 5039, 5100, 5664, 5725, 5973, 6034, 6282, 6343, 17871, }; -#endif - // Procedure p9_quad_power_off entry point, comments in header fapi2::ReturnCode p9_quad_power_off( - const fapi2::Target& i_target) + const fapi2::Target& i_target, + uint64_t* o_ring_save_data) { fapi2::buffer l_data64; constexpr uint64_t l_rawData = 0x1100000000000000ULL; // Bit 3 & 7 are set to be manipulated constexpr uint32_t MAX_CORE_PER_QUAD = 4; fapi2::ReturnCode rc = fapi2::FAPI2_RC_SUCCESS; uint32_t l_cnt = 0; -#ifdef __PPE__ - uint8_t l_isMpipl = 0; - uint8_t l_isRingSaveMpipl = 0; - const fapi2::Target FAPI_SYSTEM; fapi2::Target l_chip = i_target.getParent(); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_MPIPL, FAPI_SYSTEM, l_isMpipl), "fapiGetAttribute of ATTR_IS_MPIPL failed!"); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_RING_SAVE_MPIPL, l_chip, l_isRingSaveMpipl), - "fapiGetAttribute of ATTR_CHIP_EC_FEATURE_RING_SAVE_MPIPL failed"); -#endif + uint8_t l_isMpipl = 0; + uint8_t l_isRingSaveMpipl = 0; + const fapi2::Target FAPI_SYSTEM; FAPI_INF("p9_quad_power_off: Entering..."); // Print chiplet position FAPI_INF("Quad power off chiplet no.%d", i_target.getChipletNumber()); -#ifdef __PPE__ + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_MPIPL, FAPI_SYSTEM, l_isMpipl), "fapiGetAttribute of ATTR_IS_MPIPL failed!"); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_RING_SAVE_MPIPL, l_chip, l_isRingSaveMpipl), + "fapiGetAttribute of ATTR_CHIP_EC_FEATURE_RING_SAVE_MPIPL failed"); + if (l_isMpipl && l_isRingSaveMpipl) { @@ -123,7 +118,7 @@ fapi2::ReturnCode p9_quad_power_off( { uint64_t l_scandata = ((l_spin == 0) || (l_spin == 9)) ? 0x0 : (l_spin & 0x1) ? 0xE000000000000000 : 0xC1E061FFED5F0000; - l_data64.flush<0>().set((G_ring_index[l_spin] - G_ring_index[l_spin - 1]) << 32); + l_data64.flush<0>().set((RING_INDEX[l_spin] - RING_INDEX[l_spin - 1]) << 32); FAPI_TRY(fapi2::putScom(i_target, EQ_SCAN_LONG_ROTATE, @@ -160,7 +155,7 @@ fapi2::ReturnCode p9_quad_power_off( FAPI_TRY(fapi2::getScom(i_target, EQ_SCAN64, l_data64)); - G_ring_save[l_spin - 1] = l_scandata & l_data64; + o_ring_save_data[l_spin - 1] = l_scandata & l_data64; } } @@ -170,7 +165,6 @@ fapi2::ReturnCode p9_quad_power_off( l_data64)); } -#endif FAPI_DBG("Disabling bits 20/22/24/26 in EQ_QPPM_QPMMR_CLEAR, to gain access" " to PFET controller, otherwise Quad Power off scom will fail"); diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.H b/src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.H index f7f9f6d89fb..10aca640f36 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.H +++ b/src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.H @@ -48,14 +48,10 @@ // Constant definitions //------------------------------------------------------------------------------ -#ifdef __PPE__ - extern uint64_t G_ring_save[8]; - extern const uint64_t G_ring_index[10]; -#endif - // function pointer typedef definition for HWP call support typedef fapi2::ReturnCode (*p9_quad_power_off_FP_t) ( - const fapi2::Target& i_target); + const fapi2::Target& i_target, + uint64_t* o_ring_save_data); extern "C" { @@ -66,12 +62,15 @@ extern "C" /** ** @brief Power off the EQ including the functional cores associatated with it. ** - ** @param[in] i_target Targe type EQ + ** @param[in] i_target Targe type EQ + ** @param[out] o_ring_save_data The ring data that tells the PB how to find the + ** EQ will need to be saved away for when we p-on ** ** @return FAPI2_RC_SUCCESS if success, error otherwise **/ fapi2::ReturnCode p9_quad_power_off ( - const fapi2::Target& i_target); + const fapi2::Target& i_target, + uint64_t* o_ring_save_data); } // extern "C" diff --git a/src/usr/isteps/istep06/host_discover_targets.C b/src/usr/isteps/istep06/host_discover_targets.C index 090d6429008..01ba05a08e3 100644 --- a/src/usr/isteps/istep06/host_discover_targets.C +++ b/src/usr/isteps/istep06/host_discover_targets.C @@ -28,10 +28,8 @@ #include #include #include -#include #include #include -#include #include #include #include @@ -54,11 +52,13 @@ #include #include -#include #include #include #include #include +#include +#include +#include #include #include @@ -72,22 +72,17 @@ namespace ISTEP_06 #ifdef CONFIG_PRINT_SYSTEM_INFO -//Loop through list of targets and print out HUID and other key attributes if -//the target has it +//Loop through list of targets and print out HUID and other key attributes if the target has it void print_target_list(TARGETING::TargetHandleList i_targetList) { - for(auto & l_targ : i_targetList) - { - char * l_targetString = - l_targ->getAttr().toString(); - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "%s", l_targetString); - free(l_targetString); + for(auto & l_targ : i_targetList) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "%s", l_targ->getAttr().toString()); - //Every target has a HUID so it is safe to assume this will return okay - //from getAttr + //Every target has a HUID so it is safe to assume this will return okay from getAttr uint32_t l_huid = get_huid(l_targ ); //if output says DEAD then the attribute is not defined @@ -97,8 +92,8 @@ void print_target_list(TARGETING::TargetHandleList i_targetList) uint32_t l_fapi_pos = 0xDEAD; uint32_t l_chip_unit = 0xDEAD; - //The rest of these attributes may or may not exist on the target, so - //only add them to the string if the attribute exists + //The rest of these attributes may or may not exist on the target, so only add them to the + //string if the attribute exists TARGETING::AttributeTraits::Type hwasState; if(l_targ->tryGetAttr(hwasState)) { @@ -169,76 +164,23 @@ void print_system_info(void) } #endif -/** -* @brief Walk through the cores and ensure special wakeup is disabled -* from all srcs. -* -* @param[in/out] ISTEP_ERROR::IStepError -* Pass in the istep error so we can add errors to it -* -* @return bool -* True if no errors were found -* False if at least 1 error was found -*/ -bool deassertSpecialWakeupOnCores(ISTEP_ERROR::IStepError & io_istepError) -{ - errlHndl_t l_err = nullptr; - bool l_success = true; - // First disable special wakeup of all types for all cores - TARGETING::TargetHandleList l_coreTargetList; - TARGETING::getAllChiplets(l_coreTargetList, TARGETING::TYPE_CORE, true); - - for(const auto & l_core : l_coreTargetList) - { - for(uint8_t l_src = 0; l_src < p9specialWakeup::SPW_ALL; l_src++) - { - FAPI_INVOKE_HWP(l_err, p9_cpu_special_wakeup_core, l_core, - p9specialWakeup::SPCWKUP_DISABLE, - p9specialWakeup::PROC_SPCWKUP_ENTITY(l_src)); - if ( l_err ) - { - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "ERROR : returned from p9_cpu_special_wakeup_core for core 0x%x for src 0x%x", TARGETING::get_huid(l_core), l_src ); - l_success = false; - break; - } - else - { - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "disabled special wakeup for core 0x%x for src 0x%x", TARGETING::get_huid(l_core), l_src ); - } - } - if(l_err) - { - // capture the target data in the elog - ERRORLOG::ErrlUserDetailsTarget(l_core).addToLog( l_err ); - // add the err to the istep error - io_istepError.addErrorDetails(l_err); - //commit the error log (this will delete the err) - errlCommit(l_err, ISTEP_COMP_ID); - } - } - - return l_success; -} - -/** -* @brief loop through slave quads, make sure clocks are stopped -* (core and cache) and power them down -* -* @return errlHndl_t -*/ +//loop through slave quads, make sure clocks are stopped (core and cache) and power them down errlHndl_t powerDownSlaveQuads() { TARGETING::Target* l_sys_target = nullptr; TARGETING::targetService().getTopLevelTarget(l_sys_target); - errlHndl_t l_err = nullptr; + errlHndl_t l_err = NULL; + const uint8_t SIZE_OF_RING_DATA_PER_EQ = 0x40; + const uint8_t NUM_ENTRIES_IN_RING_DATA = 0x8; + const uint32_t OCC_SRAM_RING_STASH_BAR = 0xFFF3FC00; bool l_isMasterEq = false; + uint64_t l_ringData[8] = {0,0,0,0,0,0,0,0}; + uint32_t l_ocb_buff_length_act = 0; + uint8_t l_quad_pos; + uint32_t l_ringStashAddr; TARGETING::TargetHandleList l_eqTargetList; getAllChiplets(l_eqTargetList, TARGETING::TYPE_EQ, true); - uint64_t EX_0_CME_SCOM_SICR_SCOM1 = 0x1001203E; - uint64_t CME_SCOM_SICR_PM_EXIT_C0_MASK = 0x0800000000000000; - size_t MASK_SIZE = sizeof(CME_SCOM_SICR_PM_EXIT_C0_MASK); + //Need to know who master is so we can skip them uint8_t l_masterCoreId = TARGETING::getMasterCore()->getAttr(); @@ -248,6 +190,8 @@ errlHndl_t powerDownSlaveQuads() { l_isMasterEq = false; fapi2::Target l_fapi_eq_target (l_eq_target); + fapi2::Target l_chip = + l_fapi_eq_target.getParent(); TARGETING::TargetHandleList l_coreTargetList; TARGETING::getChildChiplets( l_coreTargetList, l_eq_target, @@ -266,23 +210,6 @@ errlHndl_t powerDownSlaveQuads() //If this is the master quad, we have already power cycled so we dont need this if(l_isMasterEq) { - //TODO RTC:171340 Need to clear PM_EXIT bit in EX_0_CME_SCOM_SICR_SCOM1 reg for MPIPL - //deassert pm exit flag on master core (both ex targs to be safe) - TARGETING::TargetHandleList l_exChildren; - TARGETING::getChildChiplets( l_exChildren, - l_eq_target, - TARGETING::TYPE_EX, - true); - - for(const auto & l_ex_child : l_exChildren) - { - // Clear bit 4 of CME_SCOM_SICR which sets PM_EXIT - l_err = deviceWrite(l_ex_child, - &CME_SCOM_SICR_PM_EXIT_C0_MASK, - MASK_SIZE, - DEVICE_SCOM_ADDRESS(EX_0_CME_SCOM_SICR_SCOM1)); //0x1001203E - } - //continue to next EQ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Found master, jumping to next EQ"); continue; @@ -389,7 +316,8 @@ errlHndl_t powerDownSlaveQuads() //Power down slave quad FAPI_INVOKE_HWP(l_err, p9_quad_power_off, - l_fapi_eq_target); + l_fapi_eq_target, + l_ringData); if(l_err) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, @@ -397,6 +325,32 @@ errlHndl_t powerDownSlaveQuads() //Break from do-while break; } + + FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_fapi_eq_target, l_quad_pos); + + l_ringStashAddr = OCC_SRAM_RING_STASH_BAR + (SIZE_OF_RING_DATA_PER_EQ * l_quad_pos); + + // Setup use OCB channel 0 for placing ring data in SRAM + FAPI_INVOKE_HWP(l_err, p9_pm_ocb_indir_setup_linear, l_chip, + p9ocb::OCB_CHAN0, + p9ocb::OCB_TYPE_LINSTR, + l_ringStashAddr); // Bar + + FAPI_INVOKE_HWP(l_err, p9_pm_ocb_indir_access, + l_chip, + p9ocb::OCB_CHAN0, + p9ocb::OCB_PUT, + NUM_ENTRIES_IN_RING_DATA, + true, + l_ringStashAddr, + l_ocb_buff_length_act, + l_ringData); + + for(int x = 0; x < NUM_ENTRIES_IN_RING_DATA; x++) + { + FAPI_DBG("Wrote %lx to OCC SRAM addr: 0x%lx", l_ringData[x], l_ringStashAddr + (x * 8)); + } + }while(0); if(l_err) @@ -416,11 +370,11 @@ void* host_discover_targets( void *io_pArgs ) TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_discover_targets entry" ); - errlHndl_t l_err = nullptr; + errlHndl_t l_err = NULL; ISTEP_ERROR::IStepError l_stepError; // Check whether we're in MPIPL mode - TARGETING::Target* l_pTopLevel = nullptr; + TARGETING::Target* l_pTopLevel = NULL; TARGETING::targetService().getTopLevelTarget( l_pTopLevel ); assert(l_pTopLevel, "host_discover_targets: no TopLevelTarget"); @@ -431,12 +385,9 @@ void* host_discover_targets( void *io_pArgs ) "information has already been loaded from memory" "when the targeting service started"); - //Make sure that all special wakeups are disabled - if(deassertSpecialWakeupOnCores(l_stepError)) - { - //Need to power down the slave quads - l_err = powerDownSlaveQuads(); - } + //Need to power down the slave quads + l_err = powerDownSlaveQuads(); + } else { @@ -450,7 +401,7 @@ void* host_discover_targets( void *io_pArgs ) // Now that all targets have completed presence detect and vpd access, // invalidate PNOR::CENTAUR_VPD sections where all the targets sharing a // VPD_REC_NUM are invalid. - if (nullptr == l_err) //discoverTargets worked + if (NULL == l_err) //discoverTargets worked { l_err = VPD::validateSharedPnorCache(); }