/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/hwpf/target.C $ */ /* */ /* OpenPOWER sbe Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ /* You may obtain a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ /* implied. See the License for the specific language governing */ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ #include #include #include #include #include // Global Vector containing ALL targets. This structure is referenced by // fapi2::getChildren to produce the resultant returned vector from that // call. std::vector G_vec_targets; // Global variable for fixed section in pibmem G_sbe_attrs_t G_sbe_attrs; fapi2attr::SystemAttributes_t* G_system_attributes_ptr; fapi2attr::ProcChipAttributes_t* G_proc_chip_attributes_ptr; fapi2attr::PervAttributes_t* G_perv_attributes_ptr; fapi2attr::CoreAttributes_t* G_core_attributes_ptr; fapi2attr::EQAttributes_t* G_eq_attributes_ptr; fapi2attr::EXAttributes_t* G_ex_attributes_ptr; namespace fapi2 { static ReturnCode plat_AttrInit() { union { struct { uint64_t iv_majorEC : 4; uint64_t iv_deviceIdDontCare : 4; uint64_t iv_minorEC : 4; uint64_t iv_chipId : 8; uint64_t iv_deviceIdDontCare2 : 20; uint64_t iv_c4Pin : 1; uint64_t iv_deviceIdDontCare3 :17; uint64_t iv_fusedMode : 1; uint64_t iv_deviceIdDontCare4 :5; }; uint64_t iv_deviceIdReg; } l_deviceId; uint8_t l_chipName = fapi2::ENUM_ATTR_NAME_NONE; uint8_t l_ec = 0; uint8_t fusedMode = 0; fapi2::Target l_chipTarget = plat_getChipTarget(); FAPI_TRY(getscom_abs(PERV_DEVICE_ID_REG, &l_deviceId.iv_deviceIdReg)); l_ec = (l_deviceId.iv_majorEC << 4) | (l_deviceId.iv_minorEC); switch(l_deviceId.iv_chipId) { case 0xD1: l_chipName = fapi2::ENUM_ATTR_NAME_NIMBUS; break; case 0xD4: l_chipName = fapi2::ENUM_ATTR_NAME_CUMULUS; break; default: FAPI_ERR("Unsupported chip ID: 0x%02X", static_cast(l_deviceId.iv_chipId)); assert(false); } fusedMode = (uint8_t)l_deviceId.iv_fusedMode; FAPI_TRY(PLAT_ATTR_INIT(fapi2::ATTR_NAME, l_chipTarget, l_chipName)); FAPI_TRY(PLAT_ATTR_INIT(fapi2::ATTR_EC, l_chipTarget, l_ec)); FAPI_TRY(PLAT_ATTR_INIT(fapi2::ATTR_FUSED_CORE_MODE, fapi2::Target(), fusedMode)); fapi_try_exit: return fapi2::current_err; } // Get the plat target handle by chiplet number - For PERV targets template<> plat_target_handle_t plat_getTargetHandleByChipletNumber( const uint8_t i_chipletNumber) { uint32_t l_idx = 0; if((i_chipletNumber > 0) && (i_chipletNumber < (EQ_CHIPLET_OFFSET + EQ_TARGET_COUNT))) { l_idx = (i_chipletNumber - NEST_GROUP1_CHIPLET_OFFSET) + NEST_GROUP1_TARGET_OFFSET; } else if((i_chipletNumber >= CORE_CHIPLET_OFFSET) && (i_chipletNumber < (CORE_CHIPLET_OFFSET + CORE_TARGET_COUNT))) { l_idx = (i_chipletNumber - CORE_CHIPLET_OFFSET) + CORE_TARGET_OFFSET; } else { assert(false); } return G_vec_targets[l_idx]; } // Get the plat target handle by chiplet number - For EQ targets template<> plat_target_handle_t plat_getTargetHandleByChipletNumber( const uint8_t i_chipletNumber) { assert(((i_chipletNumber >= EQ_CHIPLET_OFFSET) && (i_chipletNumber < (EQ_CHIPLET_OFFSET + EQ_TARGET_COUNT)))) uint32_t l_idx = (i_chipletNumber - EQ_CHIPLET_OFFSET) + EQ_TARGET_OFFSET; return G_vec_targets[l_idx]; } // Get the plat target handle by chiplet number - For CORE targets template<> plat_target_handle_t plat_getTargetHandleByChipletNumber( const uint8_t i_chipletNumber) { assert(((i_chipletNumber >= CORE_CHIPLET_OFFSET) && (i_chipletNumber < (CORE_CHIPLET_OFFSET + CORE_TARGET_COUNT)))); uint32_t l_idx = (i_chipletNumber - CORE_CHIPLET_OFFSET) + CORE_TARGET_OFFSET; return G_vec_targets[l_idx]; } // Get the plat target handle by chiplet number - For EX targets template<> plat_target_handle_t plat_getTargetHandleByChipletNumber( const uint8_t i_chipletNumber) { assert(((i_chipletNumber >= CORE_CHIPLET_OFFSET) && (i_chipletNumber < (CORE_CHIPLET_OFFSET + CORE_TARGET_COUNT)))); uint32_t l_idx = ((i_chipletNumber - CORE_CHIPLET_OFFSET) / 2) + EX_TARGET_OFFSET; return G_vec_targets[l_idx]; } // Get plat target handle by instance number - For EX targets template <> plat_target_handle_t plat_getTargetHandleByInstance( const uint8_t i_targetNum) { assert(i_targetNum < EX_TARGET_COUNT); return G_vec_targets[i_targetNum + EX_TARGET_OFFSET]; } TargetType plat_target_handle_t::getFapiTargetType() const { TargetType l_targetType = TARGET_TYPE_NONE; switch(fields.type) { case PPE_TARGET_TYPE_PROC_CHIP: l_targetType = TARGET_TYPE_PROC_CHIP; break; case PPE_TARGET_TYPE_MCS: l_targetType = TARGET_TYPE_MCS; break; case PPE_TARGET_TYPE_MI: l_targetType = TARGET_TYPE_MI; break; case PPE_TARGET_TYPE_PHB: l_targetType = TARGET_TYPE_PHB; break; case PPE_TARGET_TYPE_CORE | PPE_TARGET_TYPE_PERV: l_targetType = TARGET_TYPE_CORE; break; case PPE_TARGET_TYPE_EQ | PPE_TARGET_TYPE_PERV: l_targetType = TARGET_TYPE_EQ; break; case PPE_TARGET_TYPE_EX: l_targetType = TARGET_TYPE_EX; break; case PPE_TARGET_TYPE_PERV: l_targetType = TARGET_TYPE_PERV; break; case PPE_TARGET_TYPE_SYSTEM: l_targetType = TARGET_TYPE_SYSTEM; break; case PPE_TARGET_TYPE_MCBIST | PPE_TARGET_TYPE_PERV: l_targetType = TARGET_TYPE_MCBIST; break; case PPE_TARGET_TYPE_MC | PPE_TARGET_TYPE_PERV: l_targetType = TARGET_TYPE_MC; break; case PPE_TARGET_TYPE_NONE: case PPE_TARGET_TYPE_ALL: default: assert(false); break; } return l_targetType; } plat_target_handle_t plat_target_handle_t::getParent( const TargetType i_parentType) const { plat_target_handle_t l_handle; switch(i_parentType) { case TARGET_TYPE_PROC_CHIP: l_handle = G_vec_targets[CHIP_TARGET_OFFSET]; break; case TARGET_TYPE_PERV: assert(fields.type & PPE_TARGET_TYPE_PERV); l_handle = *this; break; case TARGET_TYPE_EX: assert(fields.type & PPE_TARGET_TYPE_CORE); l_handle = G_vec_targets [(fields.type_target_num / EX_PER_QUAD) + EX_TARGET_OFFSET]; break; case TARGET_TYPE_EQ: assert(fields.type & (PPE_TARGET_TYPE_EX | PPE_TARGET_TYPE_CORE)); { uint32_t l_perQuad = (fields.type & PPE_TARGET_TYPE_EX) ? EX_PER_QUAD : CORES_PER_QUAD; l_handle = G_vec_targets [(fields.type_target_num / l_perQuad) + EQ_TARGET_OFFSET]; } break; default: assert(false); } return l_handle; } void plat_target_handle_t::getChildren(const TargetType i_parentType, const TargetType i_childType, const plat_target_type_t i_platType, const TargetState i_state, std::vector &o_children) const { uint32_t l_childPerChiplet = 0; uint32_t l_childTargetOffset = 0; uint32_t l_loopCount = G_vec_targets.size(); TargetType l_targetType = i_parentType; if((i_parentType & ~(TARGET_TYPE_PROC_CHIP)) != 0) { // For composite targets, if multicast, treat as PROC_CHIP, else // treat as other target if(this->fields.is_multicast) { l_targetType = TARGET_TYPE_PROC_CHIP; } else { l_targetType = static_cast(l_targetType & ~(TARGET_TYPE_PROC_CHIP)); } } // EQ ==> EX if((l_targetType == TARGET_TYPE_EQ) && (i_childType == TARGET_TYPE_EX)) { l_childPerChiplet = EX_PER_QUAD; l_childTargetOffset = EX_TARGET_OFFSET; l_loopCount = l_childPerChiplet; } // EQ ==> EC if((l_targetType == TARGET_TYPE_EQ) && (i_childType == TARGET_TYPE_CORE)) { l_childPerChiplet = CORES_PER_QUAD; l_childTargetOffset = CORE_TARGET_OFFSET; l_loopCount = l_childPerChiplet; } // EX ==> EC if((l_targetType == TARGET_TYPE_EX) && (i_childType == TARGET_TYPE_CORE)) { l_childPerChiplet = CORES_PER_EX; l_childTargetOffset = CORE_TARGET_OFFSET; l_loopCount = l_childPerChiplet; } // else it is TARGET_TYPE_PROC_CHIP ==> anything, and we iterate over // all the targets for(uint32_t i = 0; i < l_loopCount; ++i) { plat_target_handle_t l_temp = G_vec_targets.at((this->fields.type_target_num * l_childPerChiplet) + l_childTargetOffset + i); if ((l_temp.fields.type & i_platType) == i_platType) { switch (i_state) { case TARGET_STATE_PRESENT: if (l_temp.fields.present) { o_children.push_back(l_temp); } break; case TARGET_STATE_FUNCTIONAL: if (l_temp.fields.functional) { o_children.push_back(l_temp); } break; default: assert(false); } } } } void plat_target_handle_t::getChildren(const TargetFilter i_filter, const TargetState i_state, std::vector &o_children) const { static const uint64_t mask = 1; // Walk the bits in the input target filter. For every bit, at // position x, that is set, x can be used as an index into our global // target vector (indexed by chiplet number) for (uint32_t l_idx = 0; l_idx < sizeof(TargetFilter) * 8; ++l_idx) { if (i_filter & (mask << (((sizeof(TargetFilter)*8)-1) - l_idx))) { plat_target_handle_t l_targetHandle = G_vec_targets.at(l_idx + NEST_GROUP1_CHIPLET_OFFSET); if(l_targetHandle.fields.type & PPE_TARGET_TYPE_PERV) // Can be an assertion? { switch (i_state) { case TARGET_STATE_PRESENT: if(l_targetHandle.fields.present) { o_children.push_back(l_targetHandle); } break; case TARGET_STATE_FUNCTIONAL: if(l_targetHandle.fields.functional) { o_children.push_back(l_targetHandle); } break; default: break; } } } } } #ifndef __noRC__ ReturnCode current_err; #endif fapi2::ReturnCode plat_PervPGTargets(const fapi2::Target & i_target, bool & o_present) { o_present = false; uint16_t attr_value = 0; FAPI_ATTR_GET(fapi2::ATTR_PG, i_target, attr_value); FAPI_DBG("Target: 0x%08X, ATTR_PG value = %x", static_cast(i_target.get().value), attr_value); if (0 == (attr_value & 0x1000)) { o_present = true; } return fapi2::FAPI2_RC_SUCCESS; } /// @brief Function to determine if pervsaive target within a chip is /// present and, thus, considered functional per PG attributes fapi2::ReturnCode plat_TargetPresent( fapi2::Target & i_chiplet_target, bool & b_present) { uint8_t l_chipName = fapi2::ENUM_ATTR_NAME_NONE; FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, plat_getChipTarget(), l_chipName)); // TODO via RTC 164026 // In nimbus all pervasive chiplets (non quad, non core), are present // other than OBUS1 and OBUS2. In cumulus all chiplets are present. // Though on field parts, all chiplets which are present should be // functional. But in lab when we can get partial good parts, its // possible that few chiplets are not functional. So we need to // differentiate between present versus functional chiplets. // We need to see if we need to use same strategy for cores/caches as // well. // Also in current code we are hard coding the chiplets. We need to use // attribute to differentiate between nimbus versus cumulus config. static const size_t OBUS1 = 10; static const size_t OBUS2 = 11; if((OBUS1 == i_chiplet_target.getChipletNumber()) || (OBUS2 == i_chiplet_target.getChipletNumber())) { if(fapi2::ENUM_ATTR_NAME_CUMULUS == l_chipName) { static_cast((i_chiplet_target.operator()())).setPresent(); } } else if( i_chiplet_target.getChipletNumber() < EQ_CHIPLET_OFFSET ) { static_cast((i_chiplet_target.operator()())).setPresent(); } // Find the PERV target number in the partial good initialization // array FAPI_TRY(plat_PervPGTargets(i_chiplet_target, b_present)); if (b_present) { if( i_chiplet_target.getChipletNumber() >= EQ_CHIPLET_OFFSET ) { static_cast((i_chiplet_target.operator()())).setPresent(); } static_cast((i_chiplet_target.operator()())).setFunctional(true); } else { FAPI_DBG("Perv target NOT present (nor functional): chiplet_number = %d", i_chiplet_target.getChipletNumber()); } FAPI_DBG("Target present = %u, Target functional = %u", static_cast(i_chiplet_target.get()).getPresent(), static_cast(i_chiplet_target.get()).getFunctional()); fapi_try_exit: return fapi2::current_err; } /// @brief Function to initialize the G_targets vector based on partial good /// attributes /// this will move to plat_target.H formally fapi2::ReturnCode plat_TargetsInit() { bool b_present = false; uint8_t l_chipName = fapi2::ENUM_ATTR_NAME_NONE; plat_target_handle_t l_platHandle; // Copy fixed section from SEEPROM to PIBMEM G_sbe_attrs.G_system_attrs = G_system_attributes; G_sbe_attrs.G_proc_chip_attrs = G_proc_chip_attributes; G_sbe_attrs.G_perv_attrs = G_perv_attributes; G_sbe_attrs.G_core_attrs = G_core_attributes; G_sbe_attrs.G_eq_attrs = G_eq_attributes; G_sbe_attrs.G_ex_attrs = G_ex_attributes; // Initialise global attribute pointers G_system_attributes_ptr = &(G_sbe_attrs.G_system_attrs); G_proc_chip_attributes_ptr = &(G_sbe_attrs.G_proc_chip_attrs); G_perv_attributes_ptr = &(G_sbe_attrs.G_perv_attrs); G_core_attributes_ptr = &(G_sbe_attrs.G_core_attrs); G_eq_attributes_ptr = &(G_sbe_attrs.G_eq_attrs); G_ex_attributes_ptr = &(G_sbe_attrs.G_ex_attrs); std::vector::iterator tgt_iter; uint32_t l_beginning_offset; FAPI_DBG("Platform target initialization. Target Count = %u", TARGET_COUNT); /* * Initialize all entries to NULL */ for (uint32_t i = 0; i < TARGET_COUNT; ++i) { G_vec_targets.push_back((fapi2::plat_target_handle_t)0x0); } /* * Chip Target is the first one */ l_beginning_offset = CHIP_TARGET_OFFSET; fapi2::Target chip_target((createPlatTargetHandle(0))); G_vec_targets.at(l_beginning_offset) = (fapi2::plat_target_handle_t)(chip_target.get()); // Initialize platform attributes. Needs to be after the chip target is // created. FAPI_TRY(plat_AttrInit()); FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, plat_getChipTarget(), l_chipName)); /* * Nest Targets - group 1 */ l_beginning_offset = NEST_GROUP1_TARGET_OFFSET; for (uint32_t i = 0; i < NEST_GROUP1_TARGET_COUNT; ++i) { fapi2::Target target_name((createPlatTargetHandle(i))); // Determine if the chiplet is present and, thus, functional // via partial good attributes FAPI_TRY(plat_TargetPresent(target_name, b_present)); G_vec_targets.at(l_beginning_offset+i) = (fapi2::plat_target_handle_t)(target_name.get()); } /* * Memory Controller Synchronous (MCBIST/MC) Targets */ // Note: MCBIST/MC have the same offset and counts, so the loop just // uses MCBIST constants l_beginning_offset = MCBIST_TARGET_OFFSET; for (uint32_t i = 0; i < MCBIST_TARGET_COUNT; ++i) { if(fapi2::ENUM_ATTR_NAME_CUMULUS == l_chipName) { l_platHandle = createPlatTargetHandle(i); } else if(fapi2::ENUM_ATTR_NAME_NIMBUS == l_chipName) { l_platHandle = createPlatTargetHandle(i); } fapi2::Target l_perv(l_platHandle); // Determine if the chiplet is present and, thus, functional // via partial good attributes FAPI_TRY(plat_TargetPresent(l_perv, b_present)); G_vec_targets.at(l_beginning_offset+i) = (fapi2::plat_target_handle_t)(l_perv.get()); } /* * Nest Targets - group 2 */ l_beginning_offset = NEST_GROUP2_TARGET_OFFSET; for (uint32_t i = NEST_GROUP2_TARGET_OFFSET; i < (NEST_GROUP2_TARGET_OFFSET + NEST_GROUP2_TARGET_COUNT); ++i) { fapi2::Target target_name((createPlatTargetHandle(i - 1))); // Determine if the chiplet is present and, thus, functional // via partial good attributes FAPI_TRY(plat_TargetPresent(target_name, b_present)); G_vec_targets.at(i) = (fapi2::plat_target_handle_t)(target_name.get()); } /* * Cache (EQ) Targets */ l_beginning_offset = EQ_TARGET_OFFSET; for (uint32_t i = 0; i < EQ_TARGET_COUNT; ++i) { fapi2::Target target_name((createPlatTargetHandle(i))); fapi2::Target l_perv = target_name.getParent(); // Determine if the chiplet is present and, thus, functional // via partial good attributes FAPI_TRY(plat_TargetPresent(l_perv, b_present)); G_vec_targets.at(l_beginning_offset+i) = (fapi2::plat_target_handle_t)(l_perv.get()); } /* * Core (EC) Targets */ l_beginning_offset = CORE_TARGET_OFFSET; for (uint32_t i = 0; i < CORE_TARGET_COUNT; ++i) { fapi2::Target target_name((createPlatTargetHandle(i))); fapi2::Target l_perv = target_name.getParent(); // Determine if the chiplet is present and, thus, functional // via partial good attributes FAPI_TRY(plat_TargetPresent(l_perv, b_present)); G_vec_targets.at(l_beginning_offset+i) = (fapi2::plat_target_handle_t)(l_perv.get()); } /* * EX Targets */ l_beginning_offset = EX_TARGET_OFFSET; for (uint32_t i = 0; i < EX_TARGET_COUNT; ++i) { fapi2::Target target_name((createPlatTargetHandle(i))); fapi2::Target l_parent = target_name.getParent(); // Get the parent EQ's ATTR_PG uint16_t l_eqAttrPg = 0; FAPI_ATTR_GET(fapi2::ATTR_PG, l_parent.getParent(), l_eqAttrPg); // Check if this EX's L2 and L3 regions are marked "good" if(0 == (i % EX_PER_QUAD)) { // Bits 6 and 8 need to be 0 l_eqAttrPg &= 0x0280; } else { // Bits 7 and 9 need to be 0 l_eqAttrPg &= 0x0140; } if(0 == l_eqAttrPg) { static_cast(target_name.operator ()()).setPresent(); static_cast(target_name.operator ()()).setFunctional(true); } G_vec_targets.at(l_beginning_offset+i) = (fapi2::plat_target_handle_t)(target_name.get()); } /* * MCS/MI Targets */ // Note: MCS/MI have the same offset and counts, so the loop just uses // MCS constants l_beginning_offset = MCS_TARGET_OFFSET; for (uint32_t i = 0; i < MCS_TARGET_COUNT; ++i) { if(fapi2::ENUM_ATTR_NAME_CUMULUS == l_chipName) { l_platHandle = createPlatTargetHandle(i); } else if(fapi2::ENUM_ATTR_NAME_NIMBUS == l_chipName) { l_platHandle = createPlatTargetHandle(i); } fapi2::Target l_nestTarget((plat_getTargetHandleByChipletNumber(N3_CHIPLET - (MCS_PER_MCBIST * (i / MCS_PER_MCBIST))))); uint16_t l_attrPg = 0; FAPI_ATTR_GET(fapi2::ATTR_PG, l_nestTarget, l_attrPg); if(0 == (i / MCS_PER_MCBIST)) { // Bit 10 needs to be 0 for MCS 0, 1 l_attrPg &= 0x0020; } else { // Bit 9 needs to be 0 for MCS 2, 3 l_attrPg &= 0x0040; } if(0 == l_attrPg) { l_platHandle.setPresent(); l_platHandle.setFunctional(true); } G_vec_targets.at(l_beginning_offset+i) = l_platHandle; } /* * PHB Targets */ l_beginning_offset = PHB_TARGET_OFFSET; for (uint32_t i = 0; i < PHB_TARGET_COUNT; ++i) { fapi2::Target target_name(createPlatTargetHandle(i)); fapi2::Target l_pciTarget((plat_getTargetHandleByChipletNumber(target_name.getChipletNumber()))); constexpr uint16_t l_pciPgArray[] = {0xE1FD, 0xE0FD, 0xE07D}; uint16_t l_attrPg = 0; FAPI_ATTR_GET(fapi2::ATTR_PG, l_pciTarget, l_attrPg); if(l_pciPgArray[target_name.getChipletNumber() - PCI0_CHIPLET] == l_attrPg) { static_cast(target_name.operator ()()).setPresent(); static_cast(target_name.operator ()()).setFunctional(true); } G_vec_targets.at(l_beginning_offset+i) = (fapi2::plat_target_handle_t)(target_name.get()); } fapi_try_exit: return fapi2::current_err; } /// @brief Function to initialize the G_targets vector based on partial good /// attributes fapi2::Target plat_getChipTarget() { // Get the chip specific target return ((fapi2::Target)G_vec_targets.at(0)); } /// @brief Function to apply any gard records set (via // ATTR_EQ_GARD/ATTR_EC_GARD) to mark corresponding targets non functional ReturnCode plat_ApplyGards() { uint8_t l_eqGards = 0; uint32_t l_ecGards = 0; static const uint32_t l_mask = 0x80000000; bool l_coreGroupNonFunctional = true; fapi2::Target l_chip = plat_getChipTarget(); // Read the EQ and EC gard attributes from the chip target FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EQ_GARD, l_chip, l_eqGards)); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EC_GARD, l_chip, l_ecGards)); FAPI_DBG("ATTR_EQ_GARD:: 0x%08x", l_eqGards); FAPI_DBG("ATTR_EC_GARD:: 0x%08x", l_ecGards); // Iterate over the bits in EQ and EC gards, if set, mark the // corresponding target non-functional for(uint32_t l_idx = 0; l_idx < EQ_TARGET_COUNT; ++l_idx) { if((l_mask >> l_idx) & (((uint32_t)(l_eqGards)) << 24)) { FAPI_DBG("Making %d'th EQ non-functional", l_idx); // EQ chiplet l_idx is to be marked non-functional fapi2::Target l_target = G_vec_targets.at(l_idx + EQ_TARGET_OFFSET); static_cast(l_target.operator ()()).setFunctional(false); G_vec_targets.at(l_idx + EQ_TARGET_OFFSET) = l_target.get(); } } for(uint32_t l_idx = 0; l_idx < CORE_TARGET_COUNT; ++l_idx) { if((l_mask >> l_idx) & (l_ecGards)) { FAPI_DBG("Making %d'th EC non-functional", l_idx); // EC chiplet l_idx is to be marked non-functional fapi2::Target l_target = G_vec_targets.at(l_idx + CORE_TARGET_OFFSET); static_cast(l_target.operator ()()).setFunctional(false); G_vec_targets.at(l_idx + CORE_TARGET_OFFSET) = l_target.get(); } else { l_coreGroupNonFunctional = false; } if(0 == ((l_idx + 1) % CORES_PER_EX)) { if(true == l_coreGroupNonFunctional) { // All cores of this group are non-functional. Mark the EX // non-functional too. G_vec_targets.at((l_idx / CORES_PER_EX) + EX_TARGET_OFFSET).fields.functional = false; } // Reset ex non-functional flag for the next group l_coreGroupNonFunctional = true; } } fapi_try_exit: return fapi2::current_err; } } // fapi2