From e80ea271b55ef1748fad64c1d75dfbbf9042b1dd Mon Sep 17 00:00:00 2001 From: Greg Still Date: Tue, 5 Apr 2016 15:16:22 -0500 Subject: p9_sbe_select_ex Level 2 update - add PFET Delay settings for booting Quads/Cores for istep 4 - Delays controled the -DPRODUCT_DEFAULT_PFET_DELAY compile switch - if not defined (aka simulation), delays only 1 cycle between steps (on or off) - if defined, fixed delays based on the fastest nest times to meet minimum times for hardware (turn on); turn off is fast - Backed out the vector use reduction as this presented SBE platform problems. Those will be addressed in RTC 151413 - Per discussion to have ALL good core/cache and EX Multicast groups setup in p9_sbe_chiplet_reset, redid this procedure to only REMOVE chiplets from groups 3, 4, 5, and 6 in single mode (the default) so as to leave only one core n group 3 with the associated EQ in group 4 and the assoicated EX in either group 5 or 6 depending on even or odd EX number. If ALL mode (controlled by an attribute), no MC groups are modified. - Vector removal was addressed by removing some error checking for the sake of SBE code space. - Added default setting of QSSR that all L2s and Quads are stopped Change-Id: I650ab91b72cce86d9b7f319e988cccc72a691abd RTC: 151360 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23138 Tested-by: Jenkins Server Tested-by: PPE CI Reviewed-by: Prem Shanker Jha Reviewed-by: YUE DU Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23139 Reviewed-by: Sachin Gupta --- .../p9/procedures/hwp/lib/p9_common_poweronoff.H | 66 ++- .../p9/procedures/hwp/perv/p9_sbe_select_ex.C | 507 ++++++++++++--------- 2 files changed, 353 insertions(+), 220 deletions(-) diff --git a/import/chips/p9/procedures/hwp/lib/p9_common_poweronoff.H b/import/chips/p9/procedures/hwp/lib/p9_common_poweronoff.H index 7adf1cf4..33a5bcc8 100644 --- a/import/chips/p9/procedures/hwp/lib/p9_common_poweronoff.H +++ b/import/chips/p9/procedures/hwp/lib/p9_common_poweronoff.H @@ -42,7 +42,71 @@ enum powerOperation_t POWER_ON_VDD = 0x1, POWER_OFF_VDD = 0xFE }; -} + + + +// For SBE, the initial power-on times are not overly time critical so they are +// hardcoded for the delay necessary when running with the fastest nest (2.4GHz). +// When these same values are used with slower nest frequencies, the delays will +// get longer (more conservative). +// +// For istep 15, the delay settings are computed based on the setting of +// ATTR_FREQ_PB +// +// pfet_delay = (1/nest_frequency_mhz)*1000*4 (PPM clock period in ns) * +// 2^(15-pfet_delay_value). +// +// or +// +// pfet_delay +// 2^(15-pfet_delay_value) = ------------------------------ +// (1/nest_frequency_mhz)*1000*4 +// +// pfet_delay * nest_frequency_mhz +// 2^(15-pfet_delay_value = ------------------------------ +// 1000*4 +// +// ( pfet_delay * nest_frequency_mhz) +// 15-pfet_delay_value = log2( ------------------------------) +// ( 1000*4 ) +// +// ( pfet_delay * nest_frequency_mhz) +// pfet_delay_value = 15 - log2( ------------------------------) +// ( 1000*4 ) +// +// ( pfet_delay * nest_frequency_mhz) +// logexp = ( ------------------------------) +// ( 1000*4 ) +// +// = pfet_delay * nest_frequency_mhz / (1000 * 4) +// = pfet_delay * (nest_frequency_mhz / (1000 * 4)) +// = pfet_delay * (2400 / (1000 * 4)) +// = pfet_delay * (.6) +// +// For core delay of 250ns per step, logexp = 250 * .6 = 150 +// --> log2(150) = 8 (rounded up to next integer) +// -- > pfet_delay_value = 15 - 8 = 7 +// +// For EQ delay of 500ns per step, logexp = 500 * .6 = 300 +// --> log2(150) = 9 (rounded up to next integer) +// -- > pfet_delay_value = 15 - 9 = 6 + + +enum pfetDelays +{ + PFET_DELAY_POWERDOWN_EQ = 0x1, + PFET_DELAY_POWERDOWN_CORE = 0x1, +#ifndef PRODUCT_DEFAULT_PFET_DELAYS + PFET_DELAY_POWERUP_EQ = 0x1, + PFET_DELAY_POWERUP_CORE = 0x1 +#else + PFET_DELAY_POWERUP_EQ = 0x6, + PFET_DELAY_POWERUP_CORE = 0x7 +#endif +}; + + +} // namespace /// @typedef p9_common_poweronoff_FP_t /// function pointer typedef definition for HWP call support diff --git a/import/chips/p9/procedures/hwp/perv/p9_sbe_select_ex.C b/import/chips/p9/procedures/hwp/perv/p9_sbe_select_ex.C index 1dcfd9ae..d3b3670a 100644 --- a/import/chips/p9/procedures/hwp/perv/p9_sbe_select_ex.C +++ b/import/chips/p9/procedures/hwp/perv/p9_sbe_select_ex.C @@ -30,18 +30,50 @@ /// /// High-level procedure flow: /// @verbatim -/// Setup the following MC groups for istep 4 use: -/// - MC group 2: Core(s) (eg ECs); use EC MC group register 2 +/// Following MC groups are needed to be setup for istep 4 use: +/// - MC group 3: Core(s) (eg ECs); use EC MC group register 3 /// - MC group 4: EQ(s); use EQ MC group register 2 /// - MC group 5: Even EXs; use EQ MC group register 3 /// - MC group 6: Odd Exs; use EQ MC group register 4 +/// +/// Prerequisite: istep 2 will setup the above groups with ALL the good +/// elements represented. +/// +/// This procedure will REMOVE entities from these groups in SINGLE mode; +/// in ALL mode, the groups are not changed. In either case, the OCC +/// registers are written with the valid configuration. Additionally, +/// default PFET controller delays are written into all configured +/// EC and EQ chiplets so that istep 4 power-on operations will +/// succeed. +/// /// Parameter indicates single core or all (controlled by Cronus/SBE) -/// - For all, all functional EC/EQ are added to respective MC groups 2, 4, -/// 5, and 6 -/// - For single, the first functional EC/EQ is added to respective MC -/// groups 2, 4, 5 and 6. Note: for single, only 1 EX will be active; -/// Thus, either MC group 5 or 6 will have no chiplets included. -/// Write selected (single/all) EQ/Core mask into OCC complex +/// +/// loop over functional cores { +/// if mode == SINGLE { +/// if first one { +/// Record the master core, EX and EQ number +/// } +/// else { +/// Remove from MC Group 3 +/// } +/// } +/// Set bits in core and EX scoreboard for later updating the OCC +/// Set default PFET controller delay values into Core +/// } +/// +/// loop over functional EQs { +/// if mode == SINGLE { +/// if not master EQ { +/// Remove from MC Groups 4 +/// for the EXs in the EQ { +/// if not master EX && bit is set in EX scoreboard +/// Remove from MC Group 5 if Even (EX0) +/// Remove from MC Group 6 if Odd (EX1) +/// } +/// Set default PFET controller delay values into EQ +/// } +/// +/// Write resultant scoreboard EQ/Core mask into OCC complex /// - This is the "master record " of the enabled cores/quad in the system /// - This is only for during the IPL (will be updated later in step 15) /// @endverbatim @@ -50,13 +82,14 @@ // Includes // ----------------------------------------------------------------------------- #include "p9_sbe_select_ex.H" +#include "p9_common_poweronoff.H" // ----------------------------------------------------------------------------- // Definitions // ----------------------------------------------------------------------------- -namespace p9_selex -{ +static const uint32_t NUM_EX_PER_EQ = 2; + static const uint8_t CORE_CHIPLET_START = 0x20; static const uint8_t CORE_CHIPLET_COUNT = 24; @@ -64,9 +97,10 @@ static const uint8_t CORE_STOP_MC_GROUP = 3; static const uint8_t EQ_STOP_MC_GROUP = 4; static const uint8_t EX_EVEN_STOP_MC_GROUP = 5; static const uint8_t EX_ODD_STOP_MC_GROUP = 6; +static const uint8_t BROADCAST_GROUP = 7; // Use PERV addressses as the accesses to the cores and EQ use PERV targets -static const uint64_t CORE_MC_REG = PERV_MULTICAST_GROUP_2; +static const uint64_t CORE_MC_REG = PERV_MULTICAST_GROUP_3; static const uint64_t EQ_MC_REG = PERV_MULTICAST_GROUP_2; static const uint64_t EX_EVEN_MC_REG = PERV_MULTICAST_GROUP_3; static const uint64_t EX_ODD_MC_REG = PERV_MULTICAST_GROUP_4; @@ -78,18 +112,20 @@ static const uint8_t PERV_EQ_START = 0x10; static const uint8_t PERV_EQ_COUNT = 6; static const uint8_t PERV_CORE_START = 0x20; static const uint8_t PERV_CORE_COUNT = 24; -}; // namespace p9_selex // ----------------------------------------------------------------------------- // Function prototypes // ----------------------------------------------------------------------------- -static fapi2::ReturnCode set_core_mc_group( +fapi2::ReturnCode select_ex_remove_core_from_mc_group( const fapi2::Target& i_target_cplt); -static fapi2::ReturnCode set_eq_mc_groups( - const std::vector >& i_eq_functional_vector, - const uint8_t i_ex_num); +fapi2::ReturnCode select_ex_remove_ex_from_mc_group( + const fapi2::Target& i_target_cplt, + const uint32_t i_ex_num); + +fapi2::ReturnCode select_ex_remove_eq_from_mc_group( + const fapi2::Target& i_target_cplt); // ----------------------------------------------------------------------------- // Function definitions @@ -104,70 +140,23 @@ fapi2::ReturnCode p9_sbe_select_ex( fapi2::buffer l_core_config = 0; fapi2::buffer l_quad_config = 0; + fapi2::buffer l_data64 = 0; uint8_t attr_force_all = 0; bool b_single = true; - bool b_first = true; - const fapi2::Target FAPI_SYSTEM; - - auto l_perv_functional_vector = - i_target.getChildren - (fapi2::TARGET_STATE_FUNCTIONAL); - - std::vector> l_core_functional_vector; - std::vector> l_eq_functional_vector; + bool b_host_core_found = false; + bool b_processing_host_core = false; - // Find the good cores - for (auto it : l_perv_functional_vector) - { - uint8_t l_attr_chip_unit_pos = 0; //actual value is read in FAPI_ATTR_GET below - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, - it, - l_attr_chip_unit_pos)); - - // If not a core, continue to next vector entry - if (!(l_attr_chip_unit_pos >= p9_selex::PERV_CORE_START && - l_attr_chip_unit_pos <= p9_selex::PERV_CORE_START + p9_selex::PERV_CORE_COUNT)) - { - continue; - } - - l_core_functional_vector.push_back(it); - - } - - // Find the good EQs - for (auto it : l_perv_functional_vector) - { - uint8_t l_attr_chip_unit_pos = 0; //actual value is read in FAPI_ATTR_GET below - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, - it, - l_attr_chip_unit_pos)); - - // If not a EQ, continue to next vector entry - if (!(l_attr_chip_unit_pos >= p9_selex::PERV_EQ_START && - l_attr_chip_unit_pos <= p9_selex::PERV_EQ_START + p9_selex::PERV_EQ_COUNT)) - { - continue; - } - - l_eq_functional_vector.push_back(it); - - } - - // Check that configuration allows success - FAPI_ASSERT(l_core_functional_vector.size(), - fapi2::SBE_SELECT_EX_NO_CORES(), - "No functional cores found"); - - FAPI_ASSERT(l_eq_functional_vector.size(), - fapi2::SBE_SELECT_EX_NO_EQS(), - "No functional cache chiplets (EQ) found"); + uint32_t l_master_ex_num = 0xFF; // invalid EX number initialized + uint32_t l_master_eq_num = 0xFF; // invalid EQ number initialized + const fapi2::Target FAPI_SYSTEM; - FAPI_DBG(" Number of candidate cores = %d", - l_core_functional_vector.size()); - FAPI_DBG(" Number of candidate caches = %d", - l_eq_functional_vector.size()); + auto l_core_functional_vector = i_target.getChildren + (fapi2::TARGET_FILTER_ALL_CORES, + fapi2::TARGET_STATE_FUNCTIONAL ); + auto l_eq_functional_vector = i_target.getChildren + (fapi2::TARGET_FILTER_ALL_CACHES, + fapi2::TARGET_STATE_FUNCTIONAL ); // Read the "FORCE_ALL" attribute FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYS_FORCE_ALL_CORES, @@ -178,24 +167,33 @@ fapi2::ReturnCode p9_sbe_select_ex( if (attr_force_all || i_mode == p9selectex::ALL) { b_single = false; + FAPI_DBG("All cores mode"); + } + else + { + FAPI_DBG("Single core mode: Number of candidate cores = %d, Number of candidate caches = %d", + l_core_functional_vector.size(), + l_eq_functional_vector.size()); } - // Loop through the core functional vector looking for the lowest numbered - // core. This fills out the two buffers tracking the core and EX - // configuration as though "ALL" is the mode chosen. This is done to - // reduce conditional processing within the vector loop to allow for - // better prefetch utilization. Also, the FAPI platform code is - // expected to return the vector elements in acsending order; thus, the - // first vector entry is the lowest numbered, valid core. + // Loop through the core functional vector. The first core in the vector + // is going to be the hostboot core as the FAPI platform code is expected + // to return the vector elements in acsending order; thus, the first vector + // entry is the lowest numbered, valid core. + // + // Two buffers track the core and EX configuration as though "ALL" is the + // mode chosen. This is done to reduce conditional processing within the + // vector loop to allow for better prefetch utilization. - for (auto it : l_core_functional_vector) + for (auto core : l_core_functional_vector) { uint8_t l_attr_chip_unit_pos = 0; //actual value is read in FAPI_ATTR_GET below FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, - it, + core, l_attr_chip_unit_pos)); - uint32_t l_core_num = static_cast(l_attr_chip_unit_pos - p9_selex::PERV_CORE_START); + // Needed as core is a PERV target + uint32_t l_core_num = static_cast(l_attr_chip_unit_pos - PERV_CORE_START); FAPI_DBG("Functional core l_attr_chip_unit_pos 0x%02X, l_core_num = 0x%02X", l_attr_chip_unit_pos, l_core_num); @@ -203,90 +201,126 @@ fapi2::ReturnCode p9_sbe_select_ex( uint32_t l_ex_num = l_core_num / 2; uint32_t l_eq_num = l_core_num / 4; - // Determine that the cache associated with the core is also - // in the list - bool b_eq_found = false; - - for (auto it : l_eq_functional_vector) + if (b_single) { - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, - it, - l_attr_chip_unit_pos)); + b_processing_host_core = false; - if ((l_attr_chip_unit_pos - p9_selex::PERV_EQ_START) == static_cast(l_eq_num)) + if (!b_host_core_found) { - b_eq_found = true; - break; - } - } - FAPI_ASSERT(b_eq_found, - fapi2::SBE_SELECT_EX_CORE_EQ_CONFIG_ERROR() - .set_CORE_NUM(l_core_num) - .set_EQ_NUM(l_eq_num), - "Did not find matching EQ for the core"); + l_master_ex_num = l_ex_num; + l_master_eq_num = l_eq_num; - // At this point, all the checks have passed so add the core and the EQ/EX - // to the apppropriate multicast groups and set the bits in the buffers for - // the OCC configuration registers. + uint8_t l_short_core_num = static_cast(l_core_num); + FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MASTER_CORE, + i_target, + l_short_core_num)); - // Core - FAPI_TRY(set_core_mc_group(it)); - l_core_config.setBit(l_core_num); + uint8_t l_short_ex_num = static_cast(l_ex_num); + FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MASTER_EX, + i_target, + l_short_ex_num)); + + FAPI_DBG("MASTER core chiplet %d 0x%02X; EX %d 0x%02X", + l_core_num, l_core_num, + l_master_ex_num, l_master_ex_num); + + b_host_core_found = true; + b_processing_host_core = true; + + } // host_core_found + + // Remove the core from the apppropriate multicast group if not + // the host core + if (!b_processing_host_core) + { + FAPI_TRY(select_ex_remove_core_from_mc_group(core)); + } - // EQ/EX - FAPI_TRY(set_eq_mc_groups(l_eq_functional_vector, l_ex_num)); + } // Single + + // To save code space in the SBE, the assumption is made that if the core + // is good (eg in the core functional vector), then the EX associated with + // it is also good. No checking is performed on the associated the EX + // targets to check this. + // + // Thus, set the bits in the buffers for the OCC configuration register + // update + FAPI_DBG("core num = %d, ex num = %d", + l_core_num, l_ex_num); + l_core_config.setBit(l_core_num); l_quad_config.setBit(l_ex_num); - if (b_first) - { - uint8_t l_core_num_short = static_cast(l_core_num); - FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MASTER_CORE, - i_target, - l_core_num_short)); + FAPI_DBG("Scoreboard values for OCC: Core 0x%016llX EX 0x%016llX", + l_core_config, l_quad_config); + + // Write the default PFET Controller Delay values for the Core + // as it will be used for istep 4 + FAPI_DBG("Setting PFET Delays in core %d", l_core_num); + + l_data64.flush<0>() + .insertFromRight<0, 4>(p9power::PFET_DELAY_POWERDOWN_CORE) + .insertFromRight<4, 4>(p9power::PFET_DELAY_POWERUP_CORE); - uint8_t l_ex_num_short = static_cast(l_ex_num); - FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MASTER_EX, - i_target, - l_ex_num_short)); + FAPI_TRY(fapi2::putScom(core, + C_PPM_PFDLY - 0x20000000, // Create chip address base + l_data64), + "Error: Core PFET Delay register"); - FAPI_DBG("MASTER core chiplet %d 0x%02X; EX %d 0x%02X", - l_core_num, l_core_num, - l_ex_num, l_ex_num); + } // Core loop - b_first = false; - } + // Process the good EQs + for (auto eq : l_eq_functional_vector) + { + uint8_t l_attr_chip_unit_pos = 0; //actual value is read in FAPI_ATTR_GET below + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, + eq, + l_attr_chip_unit_pos)); + + // Needed as eq is a PERV target + uint32_t l_eq_num = static_cast(l_attr_chip_unit_pos - PERV_EQ_START); + + FAPI_DBG("Functional EQ l_attr_chip_unit_pos 0x%02X, l_eq_num = 0x%02X", + l_attr_chip_unit_pos, l_eq_num); if (b_single) { - FAPI_DBG("SINGLE mode: chosen core chiplet %d 0x%02X; EX %d 0x%02X", - l_core_num, l_core_num, - l_ex_num, l_ex_num); - FAPI_DBG("SINGLE mode: core config: %016llX", l_core_config); + if (l_eq_num != l_master_eq_num) + { + FAPI_TRY(select_ex_remove_eq_from_mc_group(eq)); + } + + for (auto i = l_eq_num * NUM_EX_PER_EQ; i < (l_eq_num + 1)*NUM_EX_PER_EQ; ++i) + { + FAPI_DBG("ex = %d, master ex = %d, quad bit[%d] = %d", + i, l_master_ex_num, i, l_quad_config.getBit(i)); + + // Remove from MC group if not master EX and configured + if ((i != l_master_ex_num) && l_quad_config.getBit(i)) + { + FAPI_TRY(select_ex_remove_ex_from_mc_group(eq, i)); + } + } - FAPI_DBG("SINGLE mode: chiplet id 0x%02X; selected element %d Target Type %X", - l_core_num + 0x20, 0, l_core_functional_vector.at(0).getType()); + } // Single - // We found the core and cache so exit in SINGLE mode - break; + FAPI_DBG("Setting PFET Delays in EQ %d", l_eq_num); - } - else - { - FAPI_DBG("ALL mode: core chiplet %d 0x%02X with is chiplet id 0x%02X", - l_core_num, l_core_num, l_core_num + 0x20); + // Write the default PFET Controller Delay values for the EQs + // that will be used for istep 4 + l_data64.flush<0>() + .insertFromRight<0, 4>(p9power::PFET_DELAY_POWERDOWN_EQ) + .insertFromRight<4, 4>(p9power::PFET_DELAY_POWERUP_EQ); - FAPI_DBG("ALL mode: core chiplet %d %02X; EX %d %02X", - l_core_num, l_core_num, - l_ex_num, l_ex_num); - FAPI_DBG("ALL mode: core config: %016llX", l_core_config); + FAPI_TRY(fapi2::putScom(eq, + EQ_PPM_PFDLY - 0x10000000, // Create chip address base + l_data64), + "Error: EQ PFET Delay register, rc 0x%.8X", + (uint32_t)fapi2::current_err); - } - } - FAPI_ASSERT(l_core_config(), - fapi2::SBE_SELECT_EX_NO_CORE_AVAIL_ERROR(), - "No cores are configurable"); + } // EQ loop + // Write to the OCC Core Configuration Status Register FAPI_TRY(fapi2::putScom(i_target, PU_OCB_OCI_CCSR_SCOM2, l_core_config)); @@ -294,6 +328,12 @@ fapi2::ReturnCode p9_sbe_select_ex( // Write to the OCC Quad Configuration Status Register FAPI_TRY(fapi2::putScom(i_target, PU_OCB_OCI_QCSR_SCOM2, l_quad_config)); + // Write default value the OCC Quad Status Status Register + l_data64.flush<0>() + .setBit<0, 12>() // L2 Stopped + .setBit<14, 6>(); // Quad Stopped + FAPI_TRY(fapi2::putScom(i_target, PU_OCB_OCI_QSSR_SCOM2, l_data64)); + fapi_try_exit: FAPI_INF("< p9_sbe_select_ex"); @@ -301,52 +341,58 @@ fapi_try_exit: } // END p9_sbe_select_ex ///----------------------------------------------------------------------------- -/// @brief Set multicast group to core chiplet +/// @brief Remve core chiplet from Dynamic cores multicast group /// -/// @param[in] i_core_target_cplt Reference to TARGET_TYPE_PERV target +/// @param[in] i_target_cplt Reference to TARGET_TYPE_PERV target /// that is a core /// @return FAPI2_RC_SUCCESS if success, else error code. -static fapi2::ReturnCode set_core_mc_group( - const fapi2::Target& i_core_target_cplt) +fapi2::ReturnCode select_ex_remove_core_from_mc_group( + const fapi2::Target& i_target_cplt) { - FAPI_INF("> set_core_mc_group..."); + FAPI_INF("> remove_from_core_mc_group..."); - fapi2::buffer l_data64; + fapi2::buffer l_data64 = 0; - FAPI_DBG("Setting Core MC group %d", p9_selex::CORE_STOP_MC_GROUP ); - l_data64.insertFromRight<3, 3>(p9_selex::CORE_STOP_MC_GROUP); + // Entering group + l_data64.insertFromRight<0, 3>(0x7); + l_data64.insertFromRight<3, 3>(BROADCAST_GROUP); + // Removed group + l_data64.insertFromRight<19, 3>(CORE_STOP_MC_GROUP); +#ifndef __PPE__ uint8_t l_attr_chip_unit_pos = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, - i_core_target_cplt, + i_target_cplt, l_attr_chip_unit_pos)); - FAPI_DBG("Setting MC group in core %d", - (l_attr_chip_unit_pos - p9_selex::PERV_CORE_START)); + FAPI_DBG("Removing Core %d from MC group %d", + l_attr_chip_unit_pos - PERV_CORE_START, + CORE_STOP_MC_GROUP ); +#endif - FAPI_TRY(fapi2::putScom(i_core_target_cplt, - p9_selex::CORE_MC_REG, + FAPI_TRY(fapi2::putScom(i_target_cplt, + CORE_MC_REG, l_data64), - "Error: Core MC group register"); + "Error: Core MC group register, rc 0x%.8X", + (uint32_t)fapi2::current_err); fapi_try_exit: - FAPI_INF("< set_core_mc_group..."); + FAPI_INF("< remove_from_core_mc_group..."); return fapi2::current_err; } ///----------------------------------------------------------------------------- -/// @brief Set multicast groups for the EQ chiplet(s) +/// @brief Remove EX from multicast group /// -/// @param[in] i_eq_functional_vector Vector of functional EQs -/// @param[in] i_ex_num EX number for which the EQ needs to be in MC group +/// @param[in] i_ex_num EX number that needs to be removed from an MC group /// /// @return FAPI2_RC_SUCCESS if success, else error code. -static fapi2::ReturnCode set_eq_mc_groups( - const std::vector >& i_eq_functional_vector, - const uint8_t i_ex_num) +fapi2::ReturnCode select_ex_remove_ex_from_mc_group( + const fapi2::Target& i_target_cplt, + const uint32_t i_ex_num) { - FAPI_INF("> set_eq_mc_groups..."); + FAPI_INF("> select_ex_remove_ex_from_mc_group..."); // If the Core is in a even EX, then put the EQ chiplet in the EQ MC group // and the EX Even MC group. @@ -354,66 +400,89 @@ static fapi2::ReturnCode set_eq_mc_groups( // If the Core is in a odd EX, then put the EQ chiplet in the EQ MC group // and the EX Odd MC group. - fapi2::buffer l_data64; + fapi2::buffer l_data64 = 0; - uint8_t l_eq_num = i_ex_num / 2; // Two EX per EQ + // Entering group + l_data64.insertFromRight<0, 3>(0x7); + l_data64.insertFromRight<3, 3>(BROADCAST_GROUP); - // Search the EQ functional vector for one that corresponds to the input EX number. - // If the correct EQ is not found, flag an error - for (auto it : i_eq_functional_vector) + if (i_ex_num % 2) // Odd EX { - uint8_t l_attr_chip_unit_pos = 0; //actual value is read in FAPI_ATTR_GET below + FAPI_DBG("Removing EX %d (Odd) from MC group %d", + i_ex_num, + EX_ODD_STOP_MC_GROUP); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, - it, - l_attr_chip_unit_pos)); + // Removed group + l_data64.insertFromRight<19, 3>(EX_ODD_STOP_MC_GROUP); - // See if the input EX is in the current EQ - if (l_eq_num == l_attr_chip_unit_pos - p9_selex::PERV_EQ_START) - { - if (l_eq_num % 2) // Odd EX - { - FAPI_DBG("EQ %d associated with EX %d (Odd) put into MC group %d", - l_eq_num, - i_ex_num, - p9_selex::EX_ODD_STOP_MC_GROUP); - l_data64.insertFromRight<3, 3>(p9_selex::EX_ODD_STOP_MC_GROUP); + FAPI_TRY(fapi2::putScom(i_target_cplt, + EX_ODD_MC_REG, + l_data64), + "Error: EX Odd MC group register, rc 0x%.8X", + (uint32_t)fapi2::current_err); - FAPI_TRY(fapi2::putScom(it, - p9_selex::EX_ODD_MC_REG, - l_data64), - "Error: EX Odd MC group register"); + } + else // Even EX + { + FAPI_DBG("Removing EX %d (Even) from MC group %d", + i_ex_num, + EX_EVEN_STOP_MC_GROUP); - } - else // Even EX - { - FAPI_DBG("EQ %d associated with EX %d (Even) put into MC group %d", - l_eq_num, - i_ex_num, - p9_selex::EX_EVEN_STOP_MC_GROUP); - l_data64.insertFromRight<3, 3>(p9_selex::EX_EVEN_STOP_MC_GROUP); - - FAPI_TRY(fapi2::putScom(it, - p9_selex::EX_EVEN_MC_REG, - l_data64), - "Error: EX Even MC group register z"); - } - // EQ - FAPI_DBG("EQ %d put into MC group %d", - l_eq_num, - p9_selex::EQ_STOP_MC_GROUP); - l_data64.insertFromRight<3, 3>(p9_selex::EQ_STOP_MC_GROUP); - - FAPI_TRY(fapi2::putScom(it, - p9_selex::EQ_MC_REG, - l_data64), - "Error: EQ MC group register"); - } + // Removed group + l_data64.insertFromRight<19, 3>(EX_EVEN_STOP_MC_GROUP); + + FAPI_TRY(fapi2::putScom(i_target_cplt, + EX_EVEN_MC_REG, + l_data64), + "Error: EX Even MC group register, rc 0x%.16X", + (uint32_t)fapi2::current_err); } fapi_try_exit: - FAPI_INF("< set_eq_mc_groups..."); + FAPI_INF("< select_ex_remove_ex_from_mc_group..."); + return fapi2::current_err; + +} + +///----------------------------------------------------------------------------- +/// @brief Remove EX from multicast group +/// +/// @param[in] i_ex_num EX number for which the EQ needs to be in MC group +/// +/// @return FAPI2_RC_SUCCESS if success, else error code. +fapi2::ReturnCode select_ex_remove_eq_from_mc_group( + const fapi2::Target& i_target_cplt) +{ + FAPI_INF("> select_ex_remove_eq_from_mc_group..."); + + fapi2::buffer l_data64; + + // Entering group + l_data64.insertFromRight<0, 3>(0x7); + l_data64.insertFromRight<3, 3>(BROADCAST_GROUP); + // Removed group + l_data64.insertFromRight<19, 3>(EQ_STOP_MC_GROUP); + +#ifndef __PPE__ + uint8_t l_attr_chip_unit_pos = 0; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, + i_target_cplt, + l_attr_chip_unit_pos)); + + FAPI_DBG("Removing EQ %d from MC group %d", + l_attr_chip_unit_pos - PERV_EQ_START, + EQ_STOP_MC_GROUP ); +#endif + + FAPI_TRY(fapi2::putScom(i_target_cplt, + EQ_MC_REG, + l_data64), + "Error: EQ MC group register, rc 0x%.8X", + (uint32_t)fapi2::current_err); + +fapi_try_exit: + FAPI_INF("< select_ex_remove_eq_from_mc_group..."); return fapi2::current_err; } -- cgit v1.2.1