diff options
| author | crgeddes <crgeddes@us.ibm.com> | 2015-12-10 15:55:51 -0600 |
|---|---|---|
| committer | WILLIAM G. HOFFA <wghoffa@us.ibm.com> | 2016-02-26 08:49:33 -0600 |
| commit | 581462957e6df9ea663914fabf65f9f77b4e4bfa (patch) | |
| tree | 26602a2bccd1a3bfdc95d8c935ae74cecd155aed /src/usr/fapi2/plat_utils.C | |
| parent | a9e3b39d8520ff5c0356e85d4ce27ebf8f9a5fef (diff) | |
| download | blackbird-hostboot-581462957e6df9ea663914fabf65f9f77b4e4bfa.tar.gz blackbird-hostboot-581462957e6df9ea663914fabf65f9f77b4e4bfa.zip | |
Basic Hostboot platform support for FAPI2
Allows clean compile and link of FAPI2 procedures and a subset of the
platform functional support
RTC:123290
Change-Id: I9faa3bea86d1b43bca0a7eaca3869b45cc0b0d54
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/23046
Tested-by: Jenkins Server
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: Richard J. Knight <rjknight@us.ibm.com>
Reviewed-by: WILLIAM G. HOFFA <wghoffa@us.ibm.com>
Diffstat (limited to 'src/usr/fapi2/plat_utils.C')
| -rw-r--r-- | src/usr/fapi2/plat_utils.C | 978 |
1 files changed, 978 insertions, 0 deletions
diff --git a/src/usr/fapi2/plat_utils.C b/src/usr/fapi2/plat_utils.C new file mode 100644 index 000000000..aa146e45b --- /dev/null +++ b/src/usr/fapi2/plat_utils.C @@ -0,0 +1,978 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/plat_utils.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] 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 plat_utils.C +/// +/// @brief Implements the plat_utils.H utility functions. +/// +/// Note that platform code must provide the implementation. +/// + +#include <sys/time.h> +#include <utils.H> +#include <plat_trace.H> +#include <return_code.H> +#include <error_info.H> +#include <assert.h> +#include <plat_utils.H> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <hwpf_fapi2_reasoncodes.H> + +//****************************************************************************** +// Trace descriptors +//****************************************************************************** +trace_desc_t* g_fapiTd; +trace_desc_t* g_fapiImpTd; +trace_desc_t* g_fapiScanTd; +trace_desc_t* g_fapiMfgTd; + + +//****************************************************************************** +// Global TracInit objects. Construction will initialize the trace buffer +//****************************************************************************** +TRAC_INIT(&g_fapiTd, FAPI_TRACE_NAME, 2*KILOBYTE); +TRAC_INIT(&g_fapiImpTd, FAPI_IMP_TRACE_NAME, 2*KILOBYTE); +TRAC_INIT(&g_fapiScanTd, FAPI_SCAN_TRACE_NAME, 4*KILOBYTE); +TRAC_INIT(&g_fapiMfgTd, FAPI_MFG_TRACE_NAME, 4*KILOBYTE); +namespace fapi2 +{ + +// Define global current_err +//thread_local ReturnCode current_err; +ReturnCode current_err; +/// +/// @brief Translates a FAPI callout priority to an HWAS callout priority +/// +/// @param[i] i_fapiPri FAPI callout priority +/// +/// @return HWAS callout priority +/// +HWAS::callOutPriority xlateCalloutPriority( + const fapi2::CalloutPriorities::CalloutPriority i_fapiPri) +{ + // Use the CalloutPriority enum value as an index + HWAS::callOutPriority l_priority = HWAS::SRCI_PRIORITY_HIGH; + size_t l_index = i_fapiPri; + + const HWAS::callOutPriority HWAS_PRI[] = {HWAS::SRCI_PRIORITY_LOW, + HWAS::SRCI_PRIORITY_MED, + HWAS::SRCI_PRIORITY_HIGH}; + + if (l_index < (sizeof(HWAS_PRI)/sizeof(HWAS::callOutPriority))) + { + l_priority = HWAS_PRI[l_index]; + } + else + { + FAPI_ERR("fapi2::xlateCalloutPriority: Unknown priority 0x%x, assuming HIGH", + i_fapiPri); + } + + return l_priority; +} + +/// +/// * @brief Translates a FAPI Clock HW callout to an HWAS clock callout +/// +/// * @param[i] i_fapiClock FAPI Clock HW callout +/// +/// * @return HWAS Clock HW callout +/// +HWAS::clockTypeEnum xlateClockHwCallout( + const fapi2::HwCallouts::HwCallout i_fapiClock) +{ + // Use the HwCallout enum value as an index + HWAS::clockTypeEnum l_clock = HWAS::TODCLK_TYPE; + size_t l_index = i_fapiClock; + + const HWAS::clockTypeEnum HWAS_CLOCK[] = { + HWAS::TODCLK_TYPE, + HWAS::MEMCLK_TYPE, + HWAS::OSCREFCLK_TYPE, + HWAS::OSCPCICLK_TYPE}; + + if (l_index < (sizeof(HWAS_CLOCK)/sizeof(HWAS::clockTypeEnum))) + { + l_clock = HWAS_CLOCK[l_index]; + } + else + { + FAPI_ERR("fapi::xlateClockHwCallout: Unknown clock 0x%x, assuming TOD", + i_fapiClock); + } + + return l_clock; +} + +/// +/// * @brief Translates a FAPI Part HW callout to an HWAS part callout +/// +/// * @param[i] i_fapiPart FAPI part HW callout +/// +/// * @return HWAS part HW callout +/// +HWAS::partTypeEnum xlatePartHwCallout( + const fapi2::HwCallouts::HwCallout i_fapiPart) +{ + // Use the HwCallout enum value as an index + HWAS::partTypeEnum l_part = HWAS::NO_PART_TYPE; + + // clock xlate function above assumes indexes match + // between 2 enums. seems better to do it explicitly + + switch (i_fapiPart) + { + case HwCallouts::FLASH_CONTROLLER_PART: + l_part = HWAS::FLASH_CONTROLLER_PART_TYPE; + break; + case HwCallouts::PNOR_PART: + l_part = HWAS::PNOR_PART_TYPE; + break; + case HwCallouts::SBE_SEEPROM_PART: + l_part = HWAS::SBE_SEEPROM_PART_TYPE; + break; + case HwCallouts::VPD_PART: + l_part = HWAS::VPD_PART_TYPE; + break; + case HwCallouts::LPC_SLAVE_PART: + l_part = HWAS::LPC_SLAVE_PART_TYPE; + break; + case HwCallouts::GPIO_EXPANDER_PART: + l_part = HWAS::GPIO_EXPANDER_PART_TYPE; + break; + case HwCallouts::SPIVID_SLAVE_PART: + l_part = HWAS::SPIVID_SLAVE_PART_TYPE; + break; + case HwCallouts::TOD_CLOCK: + l_part = HWAS::TOD_CLOCK; + break; + case HwCallouts::MEM_REF_CLOCK: + l_part = HWAS::MEM_REF_CLOCK; + break; + case HwCallouts::PROC_REF_CLOCK: + l_part = HWAS::PROC_REF_CLOCK; + break; + case HwCallouts::PCI_REF_CLOCK: + l_part = HWAS::PCI_REF_CLOCK; + break; + + } + + return l_part; +} + +/// +/// * @brief Translates a FAPI procedure callout to an HWAS procedure callout +/// +/// * @param[i] i_fapiProc FAPI procedure callout +/// +/// * @return HWAS procedure callout +/// +HWAS::epubProcedureID xlateProcedureCallout( + const fapi2::ProcedureCallouts::ProcedureCallout i_fapiProc) +{ + // Use the ProcedureCallout enum value as an index + HWAS::epubProcedureID l_proc = HWAS::EPUB_PRC_HB_CODE; + size_t l_index = i_fapiProc; + + //@TODO RTC:124673 - need to verify the order still matches + const HWAS::epubProcedureID HWAS_PROC[] = { + HWAS::EPUB_PRC_HB_CODE, + HWAS::EPUB_PRC_LVL_SUPP, + HWAS::EPUB_PRC_MEMORY_PLUGGING_ERROR, + HWAS::EPUB_PRC_EIBUS_ERROR}; + + if (l_index < (sizeof(HWAS_PROC)/sizeof(HWAS::epubProcedureID))) + { + l_proc = HWAS_PROC[l_index]; + } + else + { + FAPI_ERR("fapi2::xlateProcedureCallout: Unknown proc 0x%x, assuming CODE", + i_fapiProc); + } + + return l_proc; +} + +/// +/// * @brief Translates a FAPI2 target type to a Targeting target type +/// +/// * @param[i] i_targetType FAPI2 target type +/// * @param[o] o_class Targeting class +/// * @param[o] o_type Targeting type +/// +void xlateTargetType(const fapi2::TargetType i_targetType, + TARGETING::CLASS & o_class, + TARGETING::TYPE & o_type) +{ + switch (i_targetType) + { + case fapi2::TARGET_TYPE_SYSTEM: + o_class = TARGETING::CLASS_SYS; + o_type = TARGETING::TYPE_SYS; + break; + case fapi2::TARGET_TYPE_DIMM: + o_class = TARGETING::CLASS_LOGICAL_CARD; + o_type = TARGETING::TYPE_DIMM; + break; + case fapi2::TARGET_TYPE_PROC_CHIP: + o_class = TARGETING::CLASS_CHIP; + o_type = TARGETING::TYPE_PROC; + break; + case fapi2::TARGET_TYPE_MEMBUF_CHIP: + o_class = TARGETING::CLASS_CHIP; + o_type = TARGETING::TYPE_MEMBUF; + break; + case fapi2::TARGET_TYPE_EX: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_EX; + break; + case fapi2::TARGET_TYPE_MBA: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_MBA; + break; + case fapi2::TARGET_TYPE_MCS: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_MCS; + break; + case fapi2::TARGET_TYPE_XBUS: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_XBUS; + break; + case fapi2::TARGET_TYPE_L4: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_L4; + break; + case fapi2::TARGET_TYPE_CORE: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_CORE; + break; + case fapi2::TARGET_TYPE_EQ: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_EQ; + break; + case fapi2::TARGET_TYPE_MCA: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_MCA; + break; + case fapi2::TARGET_TYPE_MCBIST: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_MCBIST; + break; + case fapi2::TARGET_TYPE_MI: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_MI; + break; + case fapi2::TARGET_TYPE_CAPP: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_CAPP; + break; + case fapi2::TARGET_TYPE_DMI: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_DMI; + break; + case fapi2::TARGET_TYPE_OBUS: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_OBUS; + break; + case fapi2::TARGET_TYPE_NV: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_NVBUS; + break; + case fapi2::TARGET_TYPE_SBE: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_SBE; + break; + case fapi2::TARGET_TYPE_PPE: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_PPE; + break; + case fapi2::TARGET_TYPE_PERV: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_PERV; + break; + case fapi2::TARGET_TYPE_PEC: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_PEC; + break; + case fapi2::TARGET_TYPE_PHB: + o_class = TARGETING::CLASS_UNIT; + o_type = TARGETING::TYPE_PHB; + break; + default: + o_class = TARGETING::CLASS_NA; + o_type = TARGETING::TYPE_NA; + } +} + +/// +/// @brief Is this target type pair a physical parent <-> child? +/// @return Return true if the types have physically parent <-> child +/// relationship; false otherwise. +/// +bool isPhysParentChild(const TargetType i_parentType, + const TargetType i_childType) +{ + bool l_result = false; + if (i_parentType == TARGET_TYPE_PROC_CHIP) + { + if ( (i_childType & (TARGET_TYPE_EX | + TARGET_TYPE_MCS | + TARGET_TYPE_XBUS | + TARGET_TYPE_ABUS | + TARGET_TYPE_CORE | + TARGET_TYPE_EQ | + TARGET_TYPE_MCA | + TARGET_TYPE_MCBIST | + TARGET_TYPE_MI | + TARGET_TYPE_CAPP | + TARGET_TYPE_DMI | + TARGET_TYPE_OBUS | + TARGET_TYPE_NV | + TARGET_TYPE_SBE | + TARGET_TYPE_PPE | + TARGET_TYPE_PERV | + TARGET_TYPE_PEC)) != 0 ) + { + l_result = true; + } + } + else if (i_parentType == TARGET_TYPE_MEMBUF_CHIP) + { + if ( (i_childType & (TARGET_TYPE_MBA | TARGET_TYPE_L4)) != 0 ) + { + l_result = true; + } + } + return l_result; +} + +/// +/// @brief Processes any FFDC in the ReturnCode Error Information and adds them +/// to the error log +/// +/// @param[i] i_errInfo Reference to ReturnCode Error Information +/// @param[io] io_pError Errorlog Handle +/// +void processEIFfdcs(const ErrorInfo & i_errInfo, + errlHndl_t io_pError) +{ + // Iterate through the FFDC sections, adding each to the error log + uint32_t l_size = 0; + + for (auto itr = i_errInfo.iv_ffdcs.begin(); + itr != i_errInfo.iv_ffdcs.end(); ++itr) + { + const void * l_pFfdc = (*itr)->getData(l_size); + uint32_t l_ffdcId = (*itr)->getFfdcId(); + + // Add the FFDC ID as the first word, then the FFDC data + FAPI_DBG("processEIFfdcs: Adding %d bytes of FFDC (id:0x%08x)", l_size, + l_ffdcId); + ERRORLOG::ErrlUD * l_pUD = io_pError->addFFDC( + HWPF_COMP_ID, &l_ffdcId, sizeof(l_ffdcId), 1, + HWPF_FAPI2_UDT_HWP_FFDC); + + if (l_pUD) + { + io_pError->appendToFFDC(l_pUD, l_pFfdc, l_size); + } + } +} + +/// +/// @brief Processes any HW callouts requests in the ReturnCode Error +/// Information and adds them to the error log +/// +/// @param[i] i_errInfo Reference to ReturnCode Error Information +/// @param[io] io_pError Errorlog Handle +/// +void processEIHwCallouts(const ErrorInfo & i_errInfo, + errlHndl_t io_pError) +{ + // Iterate through the HW callout requests, adding each to the error log + for (auto itr = i_errInfo.iv_hwCallouts.begin(); + itr != i_errInfo.iv_hwCallouts.end(); ++itr) + { + HWAS::callOutPriority l_priority = + xlateCalloutPriority((*itr)->iv_calloutPriority); + + HwCallouts::HwCallout l_hw = ((*itr)->iv_hw); + + TARGETING::Target * l_pRefTarget = + reinterpret_cast<TARGETING::Target*>((*itr)->iv_refTarget.get()); + + if ( ((l_hw == HwCallouts::TOD_CLOCK) || + (l_hw == HwCallouts::MEM_REF_CLOCK) || + (l_hw == HwCallouts::PROC_REF_CLOCK) || + (l_hw == HwCallouts::PCI_REF_CLOCK)) && + l_pRefTarget != NULL) + { + HWAS::clockTypeEnum l_clock = + xlateClockHwCallout((*itr)->iv_hw); + + FAPI_ERR("processEIHwCallouts: Adding clock-callout" + " (clock:%d, pri:%d)", + l_clock, l_priority); + + // Force PCI clocks to be deconfigured and garded + if( l_hw == HwCallouts::PCI_REF_CLOCK ) + { + io_pError->addClockCallout(l_pRefTarget, + l_clock, + l_priority, + HWAS::DECONFIG, + HWAS::GARD_Predictive); + } + else + { + io_pError->addClockCallout(l_pRefTarget, l_clock, l_priority); + } + } + else if ( (l_hw == HwCallouts::FLASH_CONTROLLER_PART) || + (l_hw == HwCallouts::PNOR_PART) || + (l_hw == HwCallouts::SBE_SEEPROM_PART) || + (l_hw == HwCallouts::VPD_PART) || + (l_hw == HwCallouts::LPC_SLAVE_PART) || + (l_hw == HwCallouts::GPIO_EXPANDER_PART) || + (l_hw == HwCallouts::SPIVID_SLAVE_PART) ) + { + HWAS::partTypeEnum l_part = + xlatePartHwCallout((*itr)->iv_hw); + + FAPI_ERR("processEIHwCallouts: Adding part-callout" + " (part:%d, pri:%d)", + l_part, l_priority); + io_pError->addPartCallout(l_pRefTarget, l_part, l_priority); + } + else + { + FAPI_ERR("processEIHwCallouts: Unsupported HW callout (%d)", l_hw); + io_pError->addPartCallout(l_pRefTarget, HWAS::NO_PART_TYPE, + l_priority); + io_pError->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, l_priority); + } + } +} + +/// +/// @brief Processes any Procedure callouts requests in the ReturnCode Error +/// Information and adds them to the error log +/// +/// @param[i] i_errInfo Reference to ReturnCode Error Information +/// @param[io] io_pError Errorlog Handle +/// +void processEIProcCallouts(const ErrorInfo & i_errInfo, + errlHndl_t io_pError) +{ + // Iterate through the procedure callout requests, adding each to the error + // log + for (auto itr = i_errInfo.iv_procedureCallouts.begin(); + itr != i_errInfo.iv_procedureCallouts.end(); ++itr) + { + HWAS::epubProcedureID l_procedure = + xlateProcedureCallout((*itr)->iv_procedure); + + HWAS::callOutPriority l_priority = + xlateCalloutPriority((*itr)->iv_calloutPriority); + + FAPI_DBG("processEIProcCallouts: Adding proc-callout" + " (proc:0x%02x, pri:%d)", + l_procedure, l_priority); + io_pError->addProcedureCallout(l_procedure, l_priority); + } +} + +/// +/// @brief Processes any Bus callouts requests in the ReturnCode Error +/// Information and adds them to the error log +/// +/// @param[i] i_errInfo Reference to ReturnCode Error Information +/// @param[io] io_pError Errorlog Handle +/// +void processEIBusCallouts(const ErrorInfo & i_errInfo, + errlHndl_t io_pError) +{ + // Iterate through the bus callout requests, adding each to the error log + for (auto itr = i_errInfo.iv_busCallouts.begin(); + itr != i_errInfo.iv_busCallouts.end(); ++itr) + { + TARGETING::Target * l_pTarget1 = + reinterpret_cast<TARGETING::Target*>((*itr)->iv_target1.get()); + + TARGETING::Target * l_pTarget2 = + reinterpret_cast<TARGETING::Target*>((*itr)->iv_target2.get()); + + HWAS::callOutPriority l_priority = + xlateCalloutPriority((*itr)->iv_calloutPriority); + + bool l_busTypeValid = true; + HWAS::busTypeEnum l_busType = HWAS::FSI_BUS_TYPE; + TARGETING::TYPE l_type1 = l_pTarget1->getAttr<TARGETING::ATTR_TYPE>(); + TARGETING::TYPE l_type2 = l_pTarget2->getAttr<TARGETING::ATTR_TYPE>(); + + if ( ((l_type1 == TARGETING::TYPE_MCS) && + (l_type2 == TARGETING::TYPE_MEMBUF)) || + ((l_type1 == TARGETING::TYPE_MEMBUF) && + (l_type2 == TARGETING::TYPE_MCS)) ) + { + l_busType = HWAS::DMI_BUS_TYPE; + } + else if ((l_type1 == TARGETING::TYPE_ABUS) && + (l_type2 == TARGETING::TYPE_ABUS)) + { + l_busType = HWAS::A_BUS_TYPE; + } + else if ((l_type1 == TARGETING::TYPE_XBUS) && + (l_type2 == TARGETING::TYPE_XBUS)) + { + l_busType = HWAS::X_BUS_TYPE; + } + else + { + FAPI_ERR("processEIBusCallouts: Bus between target types not known (0x%08x:0x%08x)", + l_type1, l_type2); + l_busTypeValid = false; + } + + if (l_busTypeValid) + { + FAPI_DBG("processEIBusCallouts: Adding bus-callout" + " (bus:%d, pri:%d)", + l_busType, l_priority); + io_pError->addBusCallout(l_pTarget1, l_pTarget2, l_busType, + l_priority); + } + } +} + +/// +/// @brief Processes any Callout/Deconfigure/GARD requests in the +/// ReturnCode Error Information and adds them to the error log +/// +/// @param[i] i_errInfo Reference to ReturnCode Error Information +/// @param[io] io_pError Errorlog Handle +/// +void processEICDGs(const ErrorInfo & i_errInfo, + errlHndl_t io_pError) +{ + // Iterate through the CGD requests, adding each to the error log + for (auto itr = i_errInfo.iv_CDGs.begin(); + itr != i_errInfo.iv_CDGs.end(); ++itr) + { + TARGETING::Target * l_pTarget = + reinterpret_cast<TARGETING::Target*>((*itr)->iv_target.get()); + + HWAS::callOutPriority l_priority = + xlateCalloutPriority((*itr)->iv_calloutPriority); + + HWAS::DeconfigEnum l_deconfig = HWAS::NO_DECONFIG; + if ((*itr)->iv_deconfigure) + { + l_deconfig = HWAS::DELAYED_DECONFIG; + } + + HWAS::GARD_ErrorType l_gard = HWAS::GARD_NULL; + if ((*itr)->iv_gard) + { + l_gard = HWAS::GARD_Unrecoverable; + } + + FAPI_DBG("processEICDGs: Calling out target" + " (huid:%.8x, pri:%d, deconf:%d, gard:%d)", + TARGETING::get_huid(l_pTarget), l_priority, l_deconfig, + l_gard); + io_pError->addHwCallout(l_pTarget, l_priority, l_deconfig, l_gard); + } + +} + +/// +/// @brief Returns child targets to Callout/Deconfigure/GARD +/// +/// @param[i] i_parentTarget FAPI2 Parent Target +/// @param[i] i_childType FAPI2 Child Type +/// @param[i] i_childPort Child Port Number +/// For DIMMs: MBA Port Number +/// Else unused +/// @param[i] i_childNum Child Number +/// For DIMMs: DIMM Socket Number +/// For Chips: Chip Position +/// For Chiplets: Chiplet Position +/// +void getChildTargetsForCDG( + const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_parentTarget, + const fapi2::TargetType i_childType, + const uint8_t i_childPort, + const uint8_t i_childNum, + TARGETING::TargetHandleList & o_childTargets) +{ + o_childTargets.clear(); + + do + { + // Get the parent TARGETING::Target + TARGETING::Target * l_pTargParent = + reinterpret_cast<TARGETING::Target *>(i_parentTarget.get()); + + if (l_pTargParent == NULL) + { + FAPI_ERR("getChildTargetsForCDG: NULL Target pointer"); + break; + } + + // Find if the child target type is a dimm, chip or chiplet + bool l_childIsDimm = false; + bool l_childIsChip = false; + bool l_childIsChiplet = false; + + if (i_childType == fapi2::TARGET_TYPE_DIMM) + { + l_childIsDimm = true; + } + else + { + l_childIsChip = fapi2::Target<TARGET_TYPE_ALL>::isChip(i_childType); + if (!l_childIsChip) + { + l_childIsChiplet = fapi2::Target<TARGET_TYPE_ALL>:: + isChiplet(i_childType); + } + } + + // Translate the FAPI child target type into TARGETING Class/Type + TARGETING::CLASS l_targChildClass = TARGETING::CLASS_NA; + TARGETING::TYPE l_targChildType = TARGETING::TYPE_NA; + xlateTargetType(i_childType, l_targChildClass, l_targChildType); + + if (l_targChildType == TARGETING::TYPE_NA) + { + FAPI_ERR("getChildTargetsForCDG: Could not xlate child type (0x%08x)", + i_childType); + break; + } + + // Get the child targets + TARGETING::TargetHandleList l_targChildList; + + if ( isPhysParentChild(i_parentTarget.getType(), i_childType) ) + { + // Child by containment + TARGETING::getChildChiplets(l_targChildList, l_pTargParent, + l_targChildType); + FAPI_ERR("getChildTargetsForCDG: Got %d candidate children by containment", + l_targChildList.size()); + } + else + { + // Assumption is child by affinity + TARGETING::getChildAffinityTargets(l_targChildList, l_pTargParent, + l_targChildClass, + l_targChildType); + FAPI_ERR("getChildTargetsForCDG: Got %d candidate children by affinity", + l_targChildList.size()); + } + + // Filter out child targets based on type and input port/number + for (TARGETING::TargetHandleList::const_iterator + l_itr = l_targChildList.begin(); + l_itr != l_targChildList.end(); ++l_itr) + { + if (l_childIsDimm) + { + // Match i_childPort and i_childNum + if ( ((i_childPort == ErrorInfoChildrenCDG::ALL_CHILD_PORTS) || + (i_childPort == + (*l_itr)->getAttr<TARGETING::ATTR_MBA_PORT>())) + && + ((i_childNum == ErrorInfoChildrenCDG::ALL_CHILD_NUMBERS) || + (i_childNum == + (*l_itr)->getAttr<TARGETING::ATTR_MBA_DIMM>())) ) + { + o_childTargets.push_back(*l_itr); + } + } + else if (l_childIsChip) + { + // Match i_childNum + if ((i_childNum == ErrorInfoChildrenCDG::ALL_CHILD_NUMBERS) || + (i_childNum == + (*l_itr)->getAttr<TARGETING::ATTR_POSITION>())) + { + o_childTargets.push_back(*l_itr); + } + } + else if (l_childIsChiplet) + { + // Match i_childNum + if ((i_childNum == ErrorInfoChildrenCDG::ALL_CHILD_NUMBERS) || + (i_childNum == + (*l_itr)->getAttr<TARGETING::ATTR_CHIP_UNIT>())) + { + o_childTargets.push_back(*l_itr); + } + } + else + { + // Do not match on anything + o_childTargets.push_back(*l_itr); + } + } + } while(0); +} + +/// +/// @brief Processes any Children Callout/Deconfigure/GARD requests in the +/// ReturnCode Error Information and adds them to the error log +/// +/// @param[i] i_errInfo Reference to ReturnCode Error Information +/// @param[io] io_pError Errorlog Handle +/// +void processEIChildrenCDGs(const ErrorInfo & i_errInfo, + errlHndl_t io_pError) +{ + // Iterate through the Child CGD requests, adding each to the error log + for (auto itr = i_errInfo.iv_childrenCDGs.begin(); + itr != i_errInfo.iv_childrenCDGs.end(); ++itr) + { + HWAS::callOutPriority l_priority = + xlateCalloutPriority((*itr)->iv_calloutPriority); + + HWAS::DeconfigEnum l_deconfig = HWAS::NO_DECONFIG; + if ((*itr)->iv_deconfigure) + { + l_deconfig = HWAS::DELAYED_DECONFIG; + } + + HWAS::GARD_ErrorType l_gard = HWAS::GARD_NULL; + if ((*itr)->iv_gard) + { + l_gard = HWAS::GARD_Unrecoverable; + } + + // Get a list of children to callout + TARGETING::TargetHandleList l_children; + getChildTargetsForCDG((*itr)->iv_parent, + (*itr)->iv_childType, + (*itr)->iv_childPort, + (*itr)->iv_childNumber, + l_children); + + // Callout/Deconfigure/GARD each child as appropriate + for (TARGETING::TargetHandleList::const_iterator + itr = l_children.begin(); + itr != l_children.end(); ++itr) + { + FAPI_DBG("processEIChildrenCDGs: Calling out target" + " (huid:%.8x, pri:%d, deconf:%d, gard:%d)", + TARGETING::get_huid(*itr), l_priority, l_deconfig, + l_gard); + io_pError->addHwCallout(*itr, l_priority, l_deconfig, l_gard); + } + } +} + +/// +/// @brief Converts a fapi2::ReturnCode to a HostBoot PLAT error log +/// See doxygen in plat_utils.H +/// +errlHndl_t rcToErrl(ReturnCode & io_rc, + ERRORLOG::errlSeverity_t i_sev) +{ + errlHndl_t l_pError = NULL; + + FAPI_DBG("Entering rcToErrl"); + + if (io_rc) + { + uint64_t l_rcValue = io_rc; + + // ReturnCode contains an error. Find out which component of the HWPF + // created the error + ReturnCode::returnCodeCreator l_creator = io_rc.getCreator(); + if (l_creator == ReturnCode::CREATOR_PLAT) + { + // PLAT error. Release the errlHndl_t + FAPI_ERR("rcToErrl: PLAT error: 0x%08x", l_rcValue); + //@TODO RTC:143127 + //l_pError = reinterpret_cast<errlHndl_t> (io_rc.releaseData()); + } + else if (l_creator == ReturnCode::CREATOR_HWP) + { + // HWP Error. Create an error log + FAPI_ERR("rcToErrl: HWP error: 0x%08x", l_rcValue); + + /*@ + * @errortype + * @moduleid MOD_FAPI2_RC_TO_ERRL + * @reasoncode RC_HWP_GENERATED_ERROR + * @userdata1 RC value from HWP + * @userdata2 <unused> + * @devdesc HW Procedure generated error. See User Data. + * @custdesc Error initializing processor/memory subsystem + * during boot. See FRU list for repair actions + */ + l_pError = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_FAPI2_RC_TO_ERRL, + RC_HWP_GENERATED_ERROR, + l_rcValue); + + // Add the rcValue as FFDC. This will explain what the error was + l_pError->addFFDC(HWPF_COMP_ID, &l_rcValue, sizeof(l_rcValue), 1, + HWPF_FAPI2_UDT_HWP_RCVALUE); + + // Get the Error Information Pointer + const ErrorInfo* l_pErrorInfo = io_rc.getErrorInfo(); + if (l_pErrorInfo) + { + // There is error information associated with the ReturnCode + processEIFfdcs(*l_pErrorInfo, l_pError); + processEIProcCallouts(*l_pErrorInfo, l_pError); + processEIBusCallouts(*l_pErrorInfo, l_pError); + processEICDGs(*l_pErrorInfo, l_pError); + processEIChildrenCDGs(*l_pErrorInfo, l_pError); + processEIHwCallouts(*l_pErrorInfo, l_pError); + } + else + { + FAPI_ERR("rcToErrl: No Error Information"); + } + } + else + { + // FAPI error. Create an error log + FAPI_ERR("rcToErrl: FAPI error: 0x%08x", l_rcValue); + + // The errlog reason code is the HWPF compID and the rcValue LSB + uint16_t l_reasonCode = l_rcValue; + l_reasonCode &= 0xff; + l_reasonCode |= HWPF_COMP_ID; + + // HostBoot errlog tags for FAPI errors are in hwpfReasonCodes.H + l_pError = new ERRORLOG::ErrlEntry(i_sev, + MOD_FAPI2_RC_TO_ERRL, + l_reasonCode); + + // FAPI may have added Error Information. + // Get the Error Information Pointer + const ErrorInfo* l_pErrorInfo = io_rc.getErrorInfo(); + if (l_pErrorInfo) + { + processEIFfdcs(*l_pErrorInfo, l_pError); + processEIProcCallouts(*l_pErrorInfo, l_pError); + processEIBusCallouts(*l_pErrorInfo, l_pError); + processEICDGs(*l_pErrorInfo, l_pError); + processEIChildrenCDGs(*l_pErrorInfo, l_pError); + processEIHwCallouts(*l_pErrorInfo, l_pError); + } + } + + // add the fapi traces to the elog + l_pError->collectTrace(FAPI_TRACE_NAME, 256 ); + l_pError->collectTrace(FAPI_IMP_TRACE_NAME, 384 ); + l_pError->collectTrace(FAPI_SCAN_TRACE_NAME, 256 ); + } + + FAPI_DBG("Exiting rcToErrl"); + return l_pError; +} + +/// +/// @brief Log an error. +/// +void logError( + fapi2::ReturnCode & io_rc, + fapi2::errlSeverity_t i_sev, + bool i_unitTestError ) +{ + FAPI_DBG("Entering logError"); + + // ENUM CONVERSION FAPI to PLATFORM + errlHndl_t l_pError = NULL; + + FAPI_INF("logError"); + + // Convert a FAPI severity to a ERRORLOG severity + ERRORLOG::errlSeverity_t l_sev = ERRORLOG::ERRL_SEV_UNRECOVERABLE; + switch (i_sev) + { + case fapi2::FAPI2_ERRL_SEV_RECOVERED: + l_sev = ERRORLOG::ERRL_SEV_RECOVERED; + break; + case fapi2::FAPI2_ERRL_SEV_PREDICTIVE: + l_sev = ERRORLOG::ERRL_SEV_PREDICTIVE; + break; + case fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE: + // l_sev set above + break; + default: + FAPI_ERR("severity (i_sev) of %d is unknown",i_sev); + break; + } + + // Convert the return code to an error log. + // This will set the return code to FAPI2_RC_SUCCESS and clear any + // PLAT Data, HWP FFDC data, and Error Target associated with it. + l_pError = rcToErrl(io_rc, l_sev); + + // Commit the error log. This will delete the error log and set the handle + // to NULL. + if (i_unitTestError) + { + errlCommit(l_pError, CXXTEST_COMP_ID); + } + else + { + errlCommit(l_pError, HWPF_COMP_ID); + } + + return; +} + +ReturnCode delay(uint64_t i_nanoSeconds, uint64_t i_simCycles) +{ + nanosleep( 0, i_nanoSeconds ); + return FAPI2_RC_SUCCESS; +} + +/// +/// @brief Assert a condition, and halt +/// +/// @param[in] a boolean representing the assertion +/// +void Assert(bool i_expression) +{ + assert(i_expression); +} + +bool platIsScanTraceEnabled() +{ + // SCAN trace can be dynamically turned on/off, always return true here + return 1; +} + +} //end namespace |

