/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/include/usr/hwas/common/hwas.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2012,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 */ #ifndef __HWAS_HWAS_H #define __HWAS_HWAS_H /** * @file hwas.H * * HardWare Availability Service prototypes. * In trying to keep with C++ tradition, doxygen documentation for functions * are here in the .H file. * * All of the following routines are "named isteps" - they are invoked as * tasks by the @ref IStepDispatcher. * */ /******************************************************************************/ // Includes /******************************************************************************/ #include #include #include #include namespace HWAS { /** * @brief initHardware Common HWAS function to setup the hardware * * It will call into the hwas platform-specific platInitHardware() * function to init the FSI hardware. * * @param none * * @return errlHndl_t valid errlHndl_t handle if there was an error * NULL if no errors; */ errlHndl_t initHardware(); /** * @brief discoverTagets Common HWAS function to build targeting * * This routine will walk through all the targets and initialize HWAS STATE * to a known default value (powered off, etc.) * * Then call into the hwas platform-specific platPresenceDetect() function * to read the hardware information, and apply it to the target states, * and call into the hwas platform-specific functions: * platReadIDEC() to get and set the ChipID and EC values. * platReadPartialGood() to get and set the partial good vector. * * @param none * * @return errlHndl_t valid errlHndl_t handle if there was an error * NULL if no errors; */ errlHndl_t discoverTargets(); /** * @brief restrictECunits Internal HWAS function to restrict the ECs * * This routine will walk through the procs in the list, and turn EC * units to not functional if the number of units is larger than the max * given. This is used for PR keyword and Field Core Override (FCO) * processing. * * @param[in] i_procRestrict vector of procRestrict entries * @param[in] i_present boolean for 'present' HWAS value for restricted * EC units * @param[in] i_deconfigReason DECONFIGURED_BY_ enum or 0 * * @return errlHndl_t valid errlHndl_t handle if there was an error * NULL if no errors; */ // Maximum number of EXs per proc #define NUM_EX_PER_EQ 2 #define NUM_EQ_PER_CHIP 6 #define NUM_EX_PER_CHIP (NUM_EX_PER_EQ * NUM_EQ_PER_CHIP) // structure used to store proc information for EC restrict processing typedef struct { TARGETING::TargetHandle_t target; // proc target uint32_t group; // uniq id for this group - ie: FRUID, node uint32_t maxECs; // max EC units for this group uint8_t procs; // number of procs in the group } procRestrict_t; errlHndl_t restrictECunits( std::vector &i_procRestrict, const bool i_present, const uint32_t i_deconfigReason); /** * @brief Verifies that the system has enough hardware to proceed through * the IPL. * This function contains checks that are COMMON between HWSV and HB. * platform-specific checks will be called by platCheckMinimimHardware(), * see hwasCommon.H . * If it cannot find minimum hardware, an error will be created and returned. * Error logs will also be created for each hardware module that is not * running. * * @param[in] i_nodeOrSys Level of HW check node or system * @param[out] o_bootable Indicate whether the system is * is bootable with current configuration. * if o_bootable is not NULL an error for * system unavailability will not be logged * * @return error log handle */ errlHndl_t checkMinimumHardware( const TARGETING::ConstTargetHandle_t i_nodeOrSys = NULL, bool *o_bootable = NULL); /** * @brief Loop through processors, make sure all have the same EC level * create an error log for any slave processor that does not match * the master's EC level * * * @return errlHndl_t Error returned will be a summary of all errors that * occurred during the procedure, all PLIDs should match */ errlHndl_t validateProcessorEcLevels(); /** * @brief Determines if passed in ECs are allowed to be mixed without error * * Called by validateProcessorEcLevels() * * @param[in] i_model: Cumulus or Nimbus * @param[in] i_baseEC: EC level of primary chip * @param[in] i_compareEC: EC level of to check against mixing allowed * * @return bool -- true if mixing allowed, otherwise false * note that same EC is not mixed, thus returns false */ bool mixedECsAllowed(TARGETING::ATTR_MODEL_type i_model, TARGETING::ATTR_EC_type i_baseEC, TARGETING::ATTR_EC_type i_compareEC); /** * @brief Struct representing a particular target. Used by * invokePresentByAssoc to populate a vector of TargetInfo's for subsequent * use by deconfigPresentByAssoc */ struct TargetInfo { TARGETING::ATTR_AFFINITY_PATH_type affinityPath; TARGETING::Target * pThisTarget; TARGETING::ATTR_TYPE_type type; HWAS::DeconfigGard::DeconfiguredByReason reason; }; // Structure populated in invokePresentByAssoc() for use in presentByAssoc() typedef std::vector TargetInfoVector; /** * @brief Invokes presentByAssoc * * Called by discoverTargets(). This function queries the system and populates * a vector of structs representing functional MCS, MEMBUFS, MBAs, MCAs,DIMMS. * This vector is then passed to presentByAssoc() which systematically adds * targets to another vector to be deconfigured based on their related targets * Upon completion of presentByAssoc(), this function iterates * through the returned vector and deconfigures any targets marked * for deconfiguration. */ void invokePresentByAssoc(); /** * @brief Algorithm to validate the memory target structure. * * For non direct memory, check if a MCS has a MEMBUF, a MEMBUF has a MBA, * and the MBA has a DIMM. * * For direct memory, check if a MCS has a MCA, and a MCA has a DIMM. * * The vector o_funcTargets is sorted by affinity path to allow a single pass * with some backtracking to check every scenario more efficiently. * These checks are needed because of scenarios where targets are non-present * and their related targets are not marked as deconfigured * * @param[in/out] io_funcTargets A vector of functional memory targets * @param[out] o_targToDeconfig A vector of targets to deconfigure, done * this way to allow unit tests */ void presentByAssoc(TargetInfoVector& io_funcTargets, TargetInfoVector& o_targToDeconfig); /** * @brief Algorithm to set up the EQ_GARD and EC_GARD attributes on the proc * * @param[in] i_procTarget Proccesor target to set attributes on */ void setChipletGardsOnProc(TARGETING::Target * i_procTarget); /** * @brief Find the ATTR_EC for all processors and calculate the EFFECTIVE_EC * (the lowest EC found) * */ void calculateEffectiveEC(); /** * @brief Mark any MCA units that are present but have a disabled port as * non-functional * * @return error log handle */ errlHndl_t markDisabledMcas(); /* * @brief: This function calls check_for_missing_memory and set * ATTR_PROC_MEM_TO_USE to the processor that we should use * in case of missing memory behind master proc * * @note: Only applicable for PHYP based system * * @param[in]: i_node: Node target to operate on * * @retval: error log handle */ errlHndl_t update_proc_mem_to_use (const TARGETING::Target* i_node); /* * @brief: checks whether we are missing memory behind master proc * * If there is no memory behind the master proc, then we iterate * through all the other procs and figure out a proc that has * memory. We figure out the proc with memory and * return that to the user as io_proc_mem_to_use. User can update * ATTR_PROC_MEM_TO_USE as needed. * * @note: Only applicable for PHYP based system * * @param[in]: i_node: Node target to operate on * @param[in/out]: io_proc_mem_to_use: Value of ATTR_PROC_MEM_TO_USE * the value is changed only if we find missing * memory * @param[out]: o_found_missing_mem: indicated whether we found missing * memory behind master proc or not * @retval error log handle */ errlHndl_t check_for_missing_memory (const TARGETING::Target* i_node, uint8_t & io_proc_mem_to_use, bool & o_found_missing_mem); /* * @brief This function takes in proc target and returns group/chip id * in the following bit format: GGGG CCC * where G = Group Id and C = Chip Id * * @param[in] i_proc: proc target * @retval: chip info including group and chip id */ uint64_t getGroupChipIdInfo (TARGETING::TargetHandle_t i_proc); /* * @brief This function takes in the value of ATTR_PROC_MEM_TO_USE * and extract out group and chip id * in the following bit format: GGGG CCC * where G = Group Id and C = Chip Id * * @param[in] i_proc_mem_to_use: Value of ATTR_PROC_MEM_TO_USE * @param[out] o_grp_id: group id * @param[out] o_chip_id: chip id */ void parseProcMemToUseIntoGrpChipId (uint8_t i_proc_mem_to_use, uint8_t & o_grp_id, uint8_t & o_chip_id); /* * @brief This function computes whether current value of * PROC_MEM_TO_USE matches with the expected value. * The expected value can change through the IPL because * we might end up deconfiguring dimms. * * @param[out] o_valid: true, if current and expected values are the same */ errlHndl_t check_current_proc_mem_to_use_is_still_valid (bool o_valid); }; // end namespace #endif