diff options
Diffstat (limited to 'src/usr/diag/prdf/common/rule/prdfRuleMetaData.C')
-rw-r--r-- | src/usr/diag/prdf/common/rule/prdfRuleMetaData.C | 1182 |
1 files changed, 1182 insertions, 0 deletions
diff --git a/src/usr/diag/prdf/common/rule/prdfRuleMetaData.C b/src/usr/diag/prdf/common/rule/prdfRuleMetaData.C new file mode 100644 index 000000000..3e20d2c9d --- /dev/null +++ b/src/usr/diag/prdf/common/rule/prdfRuleMetaData.C @@ -0,0 +1,1182 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/common/rule/prdfRuleMetaData.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 */ + +#include <prdfMfgThresholdMgr.H> + +#ifndef __HOSTBOOT_MODULE + #include <utilreg.H> // for UtilReg + #include <prdfSdcFileControl.H> //for SyncAnalysis +#endif +#include <prdfRuleMetaData.H> +#include <iipEregResolution.h> // for EregResolution +#include <iipServiceDataCollector.h> // for ServiceDataCollector +#include <prdfGroup.H> +#include <prdfRasServices.H> +#include <prdrLoadChip.H> +#include <prdrLoadChipCache.H> +#include <prdfScanFacility.H> // for ScanFacility +#include <iipResolutionFactory.h> // for ResolutionFactory +#include <prdfErrorSignature.H> // for ErrorSignature +#include <utilfile.H> // for UtilFile +#include <UtilHash.H> // for Util::hashString +#include <prdfPfa5Data.h> +#include <prdrCommon.H> + +namespace PRDF +{ + +template <bool Type> +struct ResetAndMaskTransformer + : public std::unary_function<Prdr::Register::ResetOrMaskStruct, + ResetAndMaskErrorRegister::ResetRegisterStruct> +{ + ResetAndMaskTransformer( ScanFacility & i_scanFactory,size_t i_scomlen , + TARGETING::TYPE i_type ) + :cv_scanFactory( i_scanFactory ), + cv_scomlen( i_scomlen ), + iv_chipType( i_type ) + { }; + + virtual ~ResetAndMaskTransformer() {}; + + virtual ResetAndMaskErrorRegister::ResetRegisterStruct + operator()( const Prdr::Register::ResetOrMaskStruct & i ) + { + /* + These reset and mask registers, which are associated with a FIR, are + created along with the FIR. They are needed to clear/mask FIR bits at + the end of analysis. Let us call it scenario X. + + There are situations where we need a separate instance of an AND + register. These are used in plugins to do some special analysis which + is not possible through framework code. Let us call it scenario Y. + + Since, factory actually doesn't use operations (e.g. READ or WRITE) + supported to determine whether a register instance is new or already + available it shall return us the AND register instance created in + scenario X. + + AND registers are write only. If we don't specify WRITE here, even in + scenario Y, we shall get object created during scenario X, which may + not be write-only. + */ + ResetAndMaskErrorRegister::ResetRegisterStruct o; + SCAN_COMM_REGISTER_CLASS::AccessLevel l_readRegAccess = + SCAN_COMM_REGISTER_CLASS::ACCESS_WO; + + + switch ( i.op ) + { + case Prdr::OR: + o.op = getStaticResetOperator<OrOperator<Type> >(); + break; + + case Prdr::AND: + o.op = getStaticResetOperator<AndOperator<Type> >(); + break; + + case Prdr::XOR: + o.op = getStaticResetOperator<XorOperator<Type> >(); + l_readRegAccess = SCAN_COMM_REGISTER_CLASS::ACCESS_RW; + break; + + case Prdr::NOT: + o.op = getStaticResetOperator<NotOperator<Type> >(); + break; + + default: + o.op = NULL; + break; + } + + o.read = & cv_scanFactory.GetScanCommRegister( i.addr_r, cv_scomlen, + iv_chipType, + l_readRegAccess ); + + o.write = & cv_scanFactory.GetScanCommRegister( i.addr_w, cv_scomlen, + iv_chipType, + SCAN_COMM_REGISTER_CLASS::ACCESS_WO ); + + return o; + }; + + private: + ScanFacility & cv_scanFactory; + size_t cv_scomlen; + TARGETING::TYPE iv_chipType; +}; + + +//------------------------------------------------------------------------------ + + RuleMetaData::RuleMetaData( const char * i_fileName, + ScanFacility & i_scanFactory, + ResolutionFactory & i_reslFactory, + TARGETING::TYPE i_type, + errlHndl_t & o_errl ) + : cv_fileName( i_fileName ),cv_dumpType( 0 ),iv_sigOff(0) +{ + o_errl = this->loadRuleFile( i_scanFactory, i_reslFactory,i_type ) ; +} + + +//------------------------------------------------------------------------------ +RuleMetaData::~RuleMetaData() +{ + uint32_t l_size = iv_groupList.size(); + for( uint32_t i = 0; i < l_size; i++ ) + { + delete iv_groupList[i]; + } + iv_groupList.clear(); + cv_hwCaptureGroups.clear(); + cv_hwCaptureReq.clear(); + cv_hwCaptureType.clear(); +} +//------------------------------------------------------------------------------ + + +errlHndl_t RuleMetaData::loadRuleFile( ScanFacility & i_scanFactory , + ResolutionFactory &i_reslFactory , + TARGETING::TYPE i_type ) +{ + RegMap_t l_regMap; + Reset_t l_resetMap; + ResetAndMaskPair l_currentResets; + uint32_t l_vregMax = 0; + ActionMap_t l_actionMap; + GroupMap_t l_groupMap; + uint32_t l_id = 1; + errlHndl_t l_errl = NULL ; + SharedThreshold_t l_sharedThresholds; + + Prdr::Chip * l_chip; + + /* Initialize local data struct to pass to sub-functions */ + RuleFileData l_localData = { l_regMap, l_groupMap, l_actionMap, + i_scanFactory, i_reslFactory, + l_chip, + l_resetMap, l_currentResets, + l_sharedThresholds + }; + // Parse chip file. + l_errl = Prdr::LoadChipCache::loadChip(cv_fileName, &l_chip); + if( NULL == l_errl ) + { + + // Get default dump type. + cv_dumpType = l_chip->cv_dumpType; + + // Set signature offset for capture data output. + iv_sigOff = l_chip->cv_signatureOffset; + + // create hardware regs. + for (int i = 0; i < l_chip->cv_regCount; i++) + { + uint16_t hashId = l_chip->cv_registers[i].cv_name; + SCAN_COMM_REGISTER_CLASS::AccessLevel l_regAccess; + + uint32_t l_accessLvls = + Prdr::PRDR_REGISTER_READ | + Prdr::PRDR_REGISTER_WRITE | + Prdr::PRDR_REGISTER_ACCESS_NIL; + + uint32_t l_accessType = + l_chip->cv_registers[i].cv_flags & l_accessLvls; + + switch( l_accessType ) + { + case Prdr::PRDR_REGISTER_ACCESS_NIL: + l_regAccess = SCAN_COMM_REGISTER_CLASS::ACCESS_NONE; + break; + case Prdr::PRDR_REGISTER_WRITE: + l_regAccess = SCAN_COMM_REGISTER_CLASS::ACCESS_WO; + break; + case Prdr::PRDR_REGISTER_READ: + l_regAccess = SCAN_COMM_REGISTER_CLASS::ACCESS_RO; + break; + default: + l_regAccess = SCAN_COMM_REGISTER_CLASS::ACCESS_RW; + } + //If more operations are incorporated in register, it can be + //specified in same way as above. + l_regMap[l_id] = cv_hwRegs[hashId] + = &i_scanFactory.GetScanCommRegister( + l_chip->cv_registers[i].cv_scomAddr, + l_chip->cv_registers[i].cv_scomLen, + i_type, l_regAccess ); + l_regMap[l_id]->SetId(hashId); + + // Copy reset registers. + std::transform( l_chip->cv_registers[i].cv_resets.begin(), + l_chip->cv_registers[i].cv_resets.end(), + std::back_inserter(l_resetMap[l_id].first), + ResetAndMaskTransformer<RESETOPERATOR_RESET>( + i_scanFactory, + l_chip->cv_registers[i].cv_scomLen, + i_type ) + ); + + // Copy mask registers. + std::transform( l_chip->cv_registers[i].cv_masks.begin(), + l_chip->cv_registers[i].cv_masks.end(), + std::back_inserter(l_resetMap[l_id].second), + ResetAndMaskTransformer<RESETOPERATOR_MASK>( + i_scanFactory, + l_chip->cv_registers[i].cv_scomLen, + i_type ) ); + l_id++; + + } + + // create capture struct for registers. + for (int i = 0; i < l_chip->cv_regCount; i++) + { + uint16_t hashId = l_chip->cv_registers[i].cv_name; + + //This flag signifies that a mapping IS or ISN'T created between a + //uint32_t mapping and a vector of SCAN_COMM_REGISTER_CLASS pointers + //. If there is no mapping outside of the for loop then it is + //because there is a capture type or requirement without a group + //in the rule file. + bool l_group_is_created = false; + // Copy into capture groups. + std::vector<Prdr::Register::CaptureInfoStruct>::const_iterator + l_capturesEnd = l_chip->cv_registers[i].cv_captures.end(); + //For each capture in this register save a Group Type or + //Requirement. + for(std::vector<Prdr::Register::CaptureInfoStruct>::const_iterator + j = l_chip->cv_registers[i].cv_captures.begin(); + j != l_capturesEnd; + ++j) + { + if ('G' == (*j).op) + { + cv_hwCaptureGroups[(*j).data[0]].push_back( + cv_hwRegs[hashId]); + //Added statement below this to indicate group was created. + l_group_is_created = true; + } + // This else if was added for a new capture "type" for registers + // primary/secondary. + // Cannot put the "type" in with the G group otherwise it will + // show up as a i_group of 2 which is not called. + else if('T' == (*j).op) + { + cv_hwCaptureType[cv_hwRegs[hashId]] = + CaptureType((RegType)(*j).data[0]); + } + else if ('f' == (*j).op) + { + CaptureRequirement req; + req.cv_func = this->getExtensibleFunction(j->func); + + cv_hwCaptureReq[cv_hwRegs[hashId]] = req; + } + else if ('P' == (*j).op) + { + cv_hwCaptureNonzero[ cv_hwRegs[hashId] ] = + cv_hwRegs[(*j).data[0]]; + } + else // 'C' + { + CaptureRequirement req; + req.cv_TargetType = (*j).data[0]; + req.cv_TargetIndex = (*j).data[1]; + req.cv_func = NULL; + + cv_hwCaptureReq[cv_hwRegs[hashId]] = req; + } + } + if (!l_group_is_created) // Add to default group if none there. + { + // Add to default if no group specified. + cv_hwCaptureGroups[1].push_back(cv_hwRegs[hashId]); + } + } + + for (int i = 0; i < l_chip->cv_ruleCount; i++) + { + if (l_regMap[l_id]) // check if it already exists. + { + l_vregMax = l_id++; + continue; + } + + l_currentResets = ResetAndMaskPair(); + + SCAN_COMM_REGISTER_CLASS * l_tmp = + this->createVirtualRegister(&l_chip->cv_rules[i], l_localData); + + l_regMap[l_id] = l_tmp; + l_resetMap[l_id] = l_currentResets; + l_vregMax = l_id++; + }; + + // initialize all the pointers for the groups, but don't construct their + // data yet. + Resolution & l_defaultResolution = + i_reslFactory.getCalloutGardResol( NULL, + MRU_LOW, NO_GARD ); + for (int i = 0; i < l_chip->cv_groupCount; i++) + { + iv_groupList.push_back( new Group( l_defaultResolution ) ); + l_groupMap[l_id] = iv_groupList.back(); + l_id++; + }; + + for (int i = 0; i < l_chip->cv_actionCount; i++) + { + if (l_actionMap[i]) + { + l_id++; + continue; + } + + // createActionClass will add to the actionMap. + this->createActionClass(i, l_localData); + //l_actionMap[l_id] = l_tmp; + l_id++; + } + + for (int i = 0; i < l_chip->cv_groupCount; i++) + { + this->createGroup( (Group *) l_groupMap[i+l_vregMax+1], + i,l_localData ); + } + for ( int i = 0; i < Prdr::NUM_GROUP_ATTN; i++ ) + cv_groupAttn[i] = l_groupMap[l_chip->cv_groupAttn[i]]; + + } + else + { + PRDF_ERR(" LoadChipCache::loadChip( ) failed "); + } + + return l_errl; + +} + +//------------------------------------------------------------------------------ + +int32_t RuleMetaData::Analyze( STEP_CODE_DATA_STRUCT & i_serviceData, + ATTENTION_TYPE i_attnType ) +{ + int32_t l_rc = SUCCESS; + ExtensibleChip * l_chipAnalyzed = ServiceDataCollector::getChipAnalyzed( ); + ServiceDataCollector & i_sdc = *(i_serviceData.service_data); + // Set default dump flags. + i_sdc.SetDump( (hwTableContent)cv_dumpType, + l_chipAnalyzed->GetChipHandle() ); + // Add statement below for Drop call. + CaptureData & capture = i_serviceData.service_data->GetCaptureData(); + // Get capture data for this chip. Allow override. + ExtensibleChipFunction * l_ignoreCapture = + getExtensibleFunction("PreventDefaultCapture", true); + bool l_shouldPreventDefaultCapture = false; + + (*l_ignoreCapture) + ( l_chipAnalyzed, PluginDef::bindParm<STEP_CODE_DATA_STRUCT&, bool&> + (i_serviceData, l_shouldPreventDefaultCapture)); + + if (!l_shouldPreventDefaultCapture) + { + // Drop secondary capture from earlier chips. + capture.Drop(SECONDARY); + + // Read capture data. + this->CaptureErrorData( i_sdc.GetCaptureData() ); + } + + // Analyze group. + ErrorRegisterType * l_errReg = NULL; + switch (i_attnType) + { + case CHECK_STOP: + l_errReg = cv_groupAttn[0]; + break; + + case RECOVERABLE: + l_errReg = cv_groupAttn[1]; + break; + + case SPECIAL: + l_errReg = cv_groupAttn[2]; + break; + + // @jl02 JL Added this code to support the new Unit Check Stop. + case UNIT_CS: + // @jl02 JL I don't know if this is the correct cv_groupAttn to add + // here or if it's needed. + l_errReg = cv_groupAttn[3]; + break; + + } + if (NULL != l_errReg) + { //mp02 a Start + //Call any pre analysis functions + ExtensibleChipFunction * l_preAnalysis = + getExtensibleFunction("PreAnalysis", true); + bool analyzed = false; + (*l_preAnalysis)( l_chipAnalyzed , + PluginDef::bindParm<STEP_CODE_DATA_STRUCT&,bool&> + (i_serviceData,analyzed)); + if ( !analyzed) + l_rc = l_errReg->Analyze(i_serviceData); + } //mp02 a Stop + // mp02d l_rc = l_errReg->Analyze(i_serviceData); + else //@jl07 + l_rc = PRD_SCAN_COMM_REGISTER_ZERO; //@jl07 + + // Don't do reset or mask on CS. @pw03 + if (CHECK_STOP != i_serviceData.service_data->getPrimaryAttnType()) //@pw04 + { + #ifndef __HOSTBOOT_MODULE + SyncAnalysis (i_sdc); //mp01 Add call to Sync SDC + #endif + // Call mask plugin. + if (i_serviceData.service_data->IsAtThreshold()) + { + ExtensibleChipFunction * l_mask = + getExtensibleFunction("MaskError", true); + (*l_mask)( l_chipAnalyzed , + PluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_serviceData) + ); //@pw01 + } + + // Call reset plugin. + ExtensibleChipFunction * l_reset = + getExtensibleFunction("ResetError", true); + (*l_reset)( l_chipAnalyzed, + PluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_serviceData) + ); //@pw01 + } + + // Call postanalysis plugin. + // @jl02 JL Adding PostAnalysis plugin call. + ExtensibleChipFunction * l_postanalysis = + getExtensibleFunction("PostAnalysis", true); + // @jl02 the true above means that a plugin may not exist for this call. + // @jl02 JL Adding call for post analysis. + (*l_postanalysis)( l_chipAnalyzed, + PluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_serviceData)); + + + return l_rc; +}; + + +//------------------------------------------------------------------------------ + +int32_t RuleMetaData::CaptureErrorData( CaptureData & io_cap, + int i_group ) +{ + using namespace TARGETING; + ExtensibleChip * l_pChipAnalyzed = ServiceDataCollector::getChipAnalyzed( ); + TargetHandle_t l_pTargetAnalyzed = l_pChipAnalyzed->GetChipHandle( ); + + std::vector<SCAN_COMM_REGISTER_CLASS *>::const_iterator l_hwCaptureEnd = + cv_hwCaptureGroups[i_group].end(); + + for ( std::vector<SCAN_COMM_REGISTER_CLASS *>::const_iterator i = + cv_hwCaptureGroups[i_group].begin(); + i != l_hwCaptureEnd; + ++i ) + { + // Check that requirements are satisfied. + if ( CaptureRequirement() != cv_hwCaptureReq[*i]) + { + CaptureRequirement req = cv_hwCaptureReq[*i]; + if (NULL != req.cv_func) + { + bool l_cap = true; + (*req.cv_func) + ( l_pChipAnalyzed , PluginDef::bindParm<bool &>(l_cap)); + + if (!l_cap) + continue; + } + else + { + bool l_indexValid =false; + TargetHandleList l_ptargetHandleList = + PlatServices::getConnected( + l_pTargetAnalyzed, + (TARGETING::TYPE) req.cv_TargetType ); + + TargetHandleList::iterator itrTarget = + l_ptargetHandleList.begin(); + + for( ; itrTarget != l_ptargetHandleList.end();itrTarget++ ) + { + if ( req.cv_TargetIndex == + PlatServices::getTargetPosition( *itrTarget) ) + { + l_indexValid = true; + break; + } + } + if( false == l_indexValid ) + { + continue; + } + } + } + + HwCaptureNonzero_t::const_iterator l_primRegIter = + cv_hwCaptureNonzero.find(*i); + if(l_primRegIter != cv_hwCaptureNonzero.end()) + { + SCAN_COMM_REGISTER_CLASS * l_primReg = + (l_primRegIter)->second; + + if( l_primReg ) + { + const BIT_STRING_CLASS *l_bitStringPtr = + l_primReg->GetBitString(); + if(l_bitStringPtr->IsZero()) + { + //skip capture data if corresponding primary FIR is + //zero. + continue; + } + } + } + + io_cap.Add( l_pTargetAnalyzed, + (*i)->GetId() ^ this->getSignatureOffset(), + *(*i), + CaptureData::BACK, + cv_hwCaptureType[*i].cv_regType ); + } + + // Call "PostCapture" plugin + ExtensibleChipFunction * l_postCapture = + getExtensibleFunction("PostCapture", true); + + (*l_postCapture) + ( l_pChipAnalyzed, + PluginDef::bindParm<CaptureData &, int>(io_cap, i_group) + ); + + return SUCCESS; +} + + +//------------------------------------------------------------------------------ + +SCAN_COMM_REGISTER_CLASS * RuleMetaData::createVirtualRegister( + Prdr::Expr * i_vReg, + RuleFileData & i_data ) +{ + SCAN_COMM_REGISTER_CLASS * l_arg[4] = { NULL }; + uint32_t l_tmp32 = 0; + SCAN_COMM_REGISTER_CLASS * l_rc = NULL; + + switch(i_vReg->cv_op) + { + case Prdr::NOT: + + l_arg[0] = createVirtualRegister(i_vReg->cv_value[0].p, i_data); + l_rc = &i_data.cv_scanFactory.GetNotRegister(*l_arg[0]); + + break; + + case Prdr::LSHIFT: + case Prdr::RSHIFT: + + l_arg[0] = createVirtualRegister(i_vReg->cv_value[0].p, i_data); + l_tmp32 = i_vReg->cv_value[1].p->cv_value[0].i; + l_rc = (Prdr::LSHIFT == i_vReg->cv_op + ? + &i_data.cv_scanFactory.GetLeftShiftRegister(*l_arg[0], + l_tmp32) + : + &i_data.cv_scanFactory.GetRightShiftRegister(*l_arg[0], + l_tmp32) + ); + break; + + case Prdr::OR: + case Prdr::AND: + + l_arg[0] = createVirtualRegister(i_vReg->cv_value[0].p, i_data); + l_arg[1] = createVirtualRegister(i_vReg->cv_value[1].p, i_data); + l_rc = (Prdr::OR == i_vReg->cv_op + ? + &i_data.cv_scanFactory.GetOrRegister(*l_arg[0], + *l_arg[1]) + : + &i_data.cv_scanFactory.GetAndRegister(*l_arg[0], + *l_arg[1]) + ); + break; + + + case Prdr::REF_REG: + + std::copy( i_data.cv_resets[i_vReg->cv_value[0].i].first.begin(), + i_data.cv_resets[i_vReg->cv_value[0].i].first.end(), + std::back_inserter(i_data.cv_currentResets.first) ); + + std::copy( i_data.cv_resets[i_vReg->cv_value[0].i].second.begin(), + i_data.cv_resets[i_vReg->cv_value[0].i].second.end(), + std::back_inserter(i_data.cv_currentResets.second) ); + + l_rc = i_data.cv_regMap[i_vReg->cv_value[0].i]; + + break; + + case Prdr::REF_RULE: + + if (NULL == i_data.cv_regMap[i_vReg->cv_value[0].i]) + { + i_data.cv_regMap[i_vReg->cv_value[0].i] = + createVirtualRegister( + &i_data.cv_loadChip->cv_rules[i_vReg->cv_value[0].i], + i_data ); + } + l_rc = i_data.cv_regMap[i_vReg->cv_value[0].i]; + + break; + + case Prdr::ATTNLINK: + + if ( NULL != i_vReg->cv_value[0].p ) + { + l_arg[0] = createVirtualRegister(i_vReg->cv_value[0].p, i_data); + } + + if ( NULL != i_vReg->cv_value[1].p ) + { + l_arg[1] = createVirtualRegister(i_vReg->cv_value[1].p, i_data); + + } + if ( NULL != i_vReg->cv_value[2].p ) + { + l_arg[2] = createVirtualRegister(i_vReg->cv_value[2].p, i_data); + } + + if ( NULL != i_vReg->cv_value[3].p ) + { + l_arg[3] = createVirtualRegister(i_vReg->cv_value[3].p, i_data); + } + + // passing NULL objects in *l_arg[x] + l_rc = &i_data.cv_scanFactory.GetAttnTypeRegister(l_arg[0], + l_arg[1], + l_arg[2], + l_arg[3]); + break; + + case Prdr::BIT_STR: + { + uint32_t l_size = i_vReg->cv_bitStrVect.size(); + BIT_STRING_BUFFER_CLASS l_bs(l_size * 64); + + for (uint32_t i = 0; i < l_size; i++) + { + l_bs.SetFieldJustify(32*(2*i) , 32, + (i_vReg->cv_bitStrVect[i] >> 32) & 0xFFFFFFFF); + l_bs.SetFieldJustify(32*((2*i)+1), 32, + (i_vReg->cv_bitStrVect[i] & 0xFFFFFFFF)); + } + + l_rc = &i_data.cv_scanFactory.GetConstantRegister(l_bs); + } + break; + + } + + return l_rc; +}; + +//------------------------------------------------------------------------------ + +Resolution * RuleMetaData::createActionClass( uint32_t i_action, + RuleMetaData::RuleFileData & i_data ) +{ + if ( NULL != i_data.cv_actionMap[i_action] ) + return i_data.cv_actionMap[i_action]; + + Resolution * l_tmpRes = NULL, * l_retRes = NULL; + + for (int i = 0; i < i_data.cv_loadChip->cv_actionSize[i_action]; i++) + { + l_tmpRes = this->createResolution( + &(i_data.cv_loadChip->cv_actions[i_action][i]), + i_data); + if (0 == i) + { + l_retRes = l_tmpRes; + } + else + { + l_retRes = &i_data.cv_reslFactory. + LinkResolutions(*l_retRes, *l_tmpRes); + } + } + + if (NULL == l_retRes) // @pw05 + { + class NullResolution : public Resolution + { + public: + int32_t Resolve( STEP_CODE_DATA_STRUCT & io_data ) + { return SUCCESS; }; + }; + + static NullResolution l_nullRes; + l_retRes = &l_nullRes; + } + + i_data.cv_actionMap[i_action] = l_retRes; + return l_retRes; +}; + +//------------------------------------------------------------------------------ + +Resolution * RuleMetaData::createResolution( Prdr::Expr * i_action, + RuleMetaData::RuleFileData & i_data ) +{ + Resolution * l_rc = NULL; + + switch (i_action->cv_op) + { + case Prdr::REF_ACT: + l_rc = this->createActionClass(i_action->cv_value[0].i - + (i_data.cv_loadChip->cv_regCount + + i_data.cv_loadChip->cv_ruleCount + + i_data.cv_loadChip->cv_groupCount + + 1), + i_data); + break; + + case Prdr::REF_GRP: + l_rc = &i_data.cv_reslFactory.GetEregResolution( + *i_data.cv_groupMap[i_action->cv_value[0].i]); + break; + + case Prdr::ACT_TRY: // TRY + l_rc = &i_data.cv_reslFactory.GetTryResolution( + *(this->createResolution(i_action->cv_value[0].p, + i_data)), + *(this->createResolution(i_action->cv_value[1].p, + i_data)) + ); + break; + + case Prdr::ACT_FUNC: // FUNCCALL + l_rc = &i_data.cv_reslFactory.GetPluginCallResolution( + this->getExtensibleFunction(i_action->cv_actFunc) + ); + break; + + case Prdr::ACT_FLAG: // FLAG + l_rc = &i_data.cv_reslFactory.GetFlagResolution( + (ServiceDataCollector::Flag) i_action->cv_value[0].i); + break; + + case Prdr::ACT_THRES: // Threshold + // The values which different parameter will have + // cv_value[0,1] error frequency and time in sec for field + // threshold + // cv_value[4] true if mnfg threshols needs to be picked up + // from mnfg file, false otherwise + // cv_value [2,3]: error frequency and time in sec for mnfg + // threshold if cv_value[4] is false otheriwse + // cv_value[3] tells which threshold needs to pick + // up from mnfg file + // cv_value[5] maskid id if shared threshold + if (0 == i_action->cv_value[5].i) + { + if ( !PlatServices::mfgMode() ) + { + l_rc = &i_data.cv_reslFactory.GetThresholdSigResolution( + ThresholdResolution::ThresholdPolicy( + (uint16_t)i_action->cv_value[0].i, + i_action->cv_value[1].i ) ); + } + else if(i_action->cv_value[4].i) + { + l_rc = &i_data.cv_reslFactory.GetThresholdSigResolution( + *(MfgThresholdMgr::getInstance()-> + getThresholdP(i_action->cv_value[3].i) ) ); + } + else + { + l_rc = &i_data.cv_reslFactory.GetThresholdSigResolution( + ThresholdResolution::ThresholdPolicy( + (uint16_t)i_action->cv_value[2].i, + i_action->cv_value[3].i ) ); + } + } + else + { + if (NULL == i_data.cv_sharedThresholds[i_action->cv_value[5].i]) + { + if ( !PlatServices::mfgMode() ) + { + l_rc = &i_data.cv_reslFactory.GetThresholdResolution( + i_action->cv_value[5].i, + ThresholdResolution::ThresholdPolicy( + (uint16_t)i_action->cv_value[0].i, + i_action->cv_value[1].i ) ); + } + else if(i_action->cv_value[4].i) + { + l_rc = &i_data.cv_reslFactory. + GetThresholdResolution(i_action->cv_value[5].i, + *(MfgThresholdMgr::getInstance()-> + getThresholdP(i_action->cv_value[3].i))); + } + else + { + l_rc = &i_data.cv_reslFactory. + GetThresholdResolution( i_action->cv_value[5].i, + ThresholdResolution::ThresholdPolicy( + (uint16_t)i_action->cv_value[2].i, + i_action->cv_value[3].i ) ); + } + i_data.cv_sharedThresholds[i_action->cv_value[5].i] = l_rc; + } + else + { + l_rc = i_data.cv_sharedThresholds[i_action->cv_value[5].i]; + } + } + break; + + + case Prdr::ACT_DUMP: + l_rc = &i_data.cv_reslFactory.GetDumpResolution( + (hwTableContent) i_action->cv_value[0].i ); + break; + + case Prdr::ACT_ANALY: // ANALYZE + l_rc = &i_data.cv_reslFactory.GetAnalyzeConnectedResolution( + (TARGETING::TYPE) i_action->cv_value[0].i, + i_action->cv_value[1].i); + break; + + case Prdr::ACT_CALL: // CALLOUT + + switch (i_action->cv_value[0].i) + { + case Prdr::CALLOUT_GARD_CHIP: // connected callout with gard + l_rc = &i_data.cv_reslFactory.getConnCalloutGardResol( + (TARGETING::TYPE) i_action->cv_value[2].i, + i_action->cv_value[3].i, + (CalloutPriorityEnum) i_action->cv_value[1].i, + ( NULL == i_action->cv_value[4].p ? NULL : + ( this->createResolution( + i_action->cv_value[4].p, i_data ) ) ), + TARGETING::TYPE_NA, + (GARD_POLICY) i_action->cv_value[6].i ); + break; + + // connected callout and gard with connection type + case Prdr::CALLOUT_GARD_PEER: + l_rc = &i_data.cv_reslFactory.getConnCalloutGardResol( + (TARGETING::TYPE) i_action->cv_value[2].i, + i_action->cv_value[3].i, + (CalloutPriorityEnum) i_action->cv_value[1].i, + ( NULL == i_action->cv_value[4].p ? NULL : + ( this->createResolution( + i_action->cv_value[4].p, i_data ) ) ), + (TARGETING::TYPE) i_action->cv_value[5].i, + (GARD_POLICY) i_action->cv_value[6].i ); + + break; + + case Prdr::CALLOUT_PROC: // Procedure callout + l_rc = &i_data.cv_reslFactory.getCalloutGardResol( + (SymbolicFru) i_action->cv_value[2].i, + (CalloutPriorityEnum) i_action->cv_value[1].i, + (GARD_POLICY) i_action->cv_value[6].i ); + break; + + case Prdr::CALLOUT_GARD_SELF: // self callout with gard option + default: + l_rc = &i_data.cv_reslFactory.getCalloutGardResol( + NULL , + (CalloutPriorityEnum) i_action->cv_value[1].i, + (GARD_POLICY) i_action->cv_value[6].i ); + break; + + }; + + break; + + case Prdr::ACT_CAPT: // Capture resolution. + l_rc = &i_data.cv_reslFactory.GetCaptureResolution( + i_action->cv_value[0].i); + break; + }; + + return l_rc; +}; + +//------------------------------------------------------------------------------ + +void RuleMetaData::createGroup(Group * i_group, + uint32_t i_groupId, + RuleMetaData::RuleFileData & i_data) +{ + // Internal class to collapse the bit string. + class CreateBitString + { + public: + static void execute(std::vector<uint8_t> & i_bits, + Prdr::Expr * i_expr) + { + if (NULL == i_expr) + return; + if (i_expr->cv_op == Prdr::INT_SHORT) + { + i_bits.push_back(i_expr->cv_value[0].i); + } + else // must be an | or & operator. + { + // Expand bit string from left side. + CreateBitString::execute(i_bits, i_expr->cv_value[0].p); + // Expand bit string from right side. + CreateBitString::execute(i_bits, i_expr->cv_value[1].p); + } + }; + }; + + for (int i = 0; i < i_data.cv_loadChip->cv_groupSize[i_groupId]; i++) + { + std::vector<uint8_t> l_bits; // Vector to hold bit string. + + // Get expression for group's line. + Prdr::Expr * l_expr = &i_data.cv_loadChip->cv_groups[i_groupId][i]; + + // Execute internal (recursive) class to generate bit string. + CreateBitString::execute(l_bits, l_expr->cv_value[1].p); + + // Add expression to group. + i_group->Add(i_data.cv_regMap[l_expr->cv_value[0].i], + &(*l_bits.begin()), + l_bits.size(), + *(this->createResolution(l_expr->cv_value[2].p, i_data)), + i_data.cv_resets[l_expr->cv_value[0].i], + (i_data.cv_regMap[l_expr->cv_value[0].i]->GetId() + + i_data.cv_loadChip->cv_signatureOffset) & 0xffff, + Prdr::AND == l_expr->cv_value[1].p->cv_op + ); + + } // end for. + + // Do flags. --- + + // For idea of secondary bit filter to work, it must be the first filter + // applicable on register data. To manage this, first of all, we must push + // secondary filter to group. + // We are supporting the concept of cascaded filter where one filter works + // after other in harmony. When secondary filter acts, it shall make + // all the secondary bits( which are ON ) as "DON'T CARE" during primary + // pass. So, the intent is to filter out secondary bits or in other words + // analyze only primary bits in primary pass. + + if ( i_data.cv_loadChip->cv_groupFlags[i_groupId] & + Prdr::PRDR_GROUP_FILTER_SECONDARY ) + { + // Add secondary filter to find out if any secondary bit + // is on. + std::vector<uint8_t> l_bits; + CreateBitString::execute(l_bits, + i_data.cv_loadChip->cv_groupSecondaryBits[i_groupId]); + + FilterClass * l_filter = new SecondaryBitsFilter( l_bits ); + i_group->AddFilter( l_filter, true ); + + } + + // Do Priority filter flag. + if (i_data.cv_loadChip->cv_groupFlags[i_groupId] & + Prdr::PRDR_GROUP_FILTER_PRIORITY) + { + std::vector<uint8_t> l_bits; + CreateBitString::execute(l_bits, + i_data.cv_loadChip->cv_groupPriorityBits[i_groupId]); + + FilterClass * l_filter = new PrioritySingleBitFilter(l_bits); + i_group->AddFilter(l_filter); + } + + // Do single bit filter flag. + if (i_data.cv_loadChip->cv_groupFlags[i_groupId] & + Prdr::PRDR_GROUP_FILTER_SINGLE_BIT) + { + FilterClass * l_filter = new SingleBitFilter(); + i_group->AddFilter(l_filter); + } +} + +//------------------------------------------------------------------------------ + +ExtensibleChipFunction *RuleMetaData::getExtensibleFunction( + const char * i_func, + bool i_expectNull ) +{ + #define PRDF_FUNC "[RuleMetaData::getExtensibleFunction] " + ExtensibleFunctionType * plugin = + getPluginGlobalMap().getPlugins(cv_fileName)[i_func]; + + if (NULL == plugin) + { + if (!i_expectNull) + { + errlHndl_t l_errl = NULL; + + PRDF_CREATE_ERRL(l_errl, + ERRL_SEV_UNRECOVERABLE, + ERRL_ETYPE_NOT_APPLICABLE, + SRCI_ERR_INFO, + SRCI_NO_ATTR, + PRDF_RULECHIP, + LIC_REFCODE, + PRDF_CODE_FAIL, + __LINE__, + 0, 0, 0); + + PRDF_ADD_FFDC(l_errl, + cv_fileName, + strlen(cv_fileName), + ErrlVer1, + ErrlString); + + PRDF_ADD_FFDC(l_errl, + i_func, + strlen(i_func), + ErrlVer1, + ErrlString ); + + PRDF_COMMIT_ERRL( l_errl, ERRL_ACTION_REPORT ); + + // We can only reach here in two cases + // 1. PRD patch is not properly applied ( prf files are changed + // but PRDF library is not updated ) + // 2. Obvious miss by developer. + // In both these cases, we should catch these issues at very early + // stage during system Initialize and this scenario should fail + // basic validation. + // So aborting system at this point. + PRDF_ERR( PRDF_FUNC "NULL Function for plugin:%s chip %s", + i_func, cv_fileName ); + + PRDF_ASSERT( NULL != plugin ); + } + + static Plugin<ExtensibleChip> l_nullPlugin(NULL); + plugin = &l_nullPlugin; + + } + return ( ExtensibleChipFunction * ) plugin; + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +SCAN_COMM_REGISTER_CLASS * RuleMetaData::getRegister( const char * i_reg, + bool i_expectNull, + ExtensibleChip* i_chip ) +{ + uint16_t hashId = Util::hashString( i_reg ); + SCAN_COMM_REGISTER_CLASS * l_pRegister = cv_hwRegs[hashId]; + if ( NULL == l_pRegister ) + { + l_pRegister = getNullRegister( i_reg,i_expectNull ); + } + else + { + /* l_register obtained from cv_hwRegs is a ScomRegister which does not + have rule chip info built in.Analyze leg of code uses this register. + Inorder to use this register for scom, target info is obtained from + service data collector.This register does not suit us for read and + write operation in plugin function.It is because in plugin function + register read should not be concerned with finding the associated + rule chip or target.Inorder to address this situation,we create a + wrapper register.This register has rule chip info in addition to all + the data of scomRegister.This object is created through factory and + and destroyed at the end of analysis. + */ + + SCAN_COMM_REGISTER_CLASS * l_pReg = l_pRegister; + ScanFacility & l_scanFac = ScanFacility::Access(); + l_pRegister = & l_scanFac.GetPluginRegister( *l_pReg,*i_chip ); + + } + + return l_pRegister; +} + +//------------------------------------------------------------------------------ + +SCAN_COMM_REGISTER_CLASS * RuleMetaData::getNullRegister( const char * i_reg, + bool i_expectNull ) +{ + static NullRegister l_nullRegister(1024); + SCAN_COMM_REGISTER_CLASS * l_register = &l_nullRegister; + + if (!i_expectNull) + { + errlHndl_t l_errl = NULL; + PRDF_CREATE_ERRL(l_errl, + ERRL_SEV_UNRECOVERABLE, + ERRL_ETYPE_NOT_APPLICABLE, + SRCI_ERR_INFO, + SRCI_NO_ATTR, + PRDF_RULECHIP, + LIC_REFCODE, + PRDF_CODE_FAIL, + __LINE__, + 1, 0, 0); + + PRDF_ADD_FFDC(l_errl, + cv_fileName, + strlen(cv_fileName), + ErrlVer1, + ErrlString); + + + PRDF_ADD_FFDC(l_errl, + i_reg, + strlen(i_reg), + ErrlVer1, + ErrlString); + + PRDF_COMMIT_ERRL(l_errl, ERRL_ACTION_REPORT); + } + return l_register; + +} + +//------------------------------------------------------------------------------ + + +}//namespace PRDF ends |