int32_t ErrorRegister::SetErrorSignature( STEP_CODE_DATA_STRUCT & error, BitKey & bl ) { int32_t rc = SUCCESS; ErrorSignature * esig = error.service_data->GetErrorSignature(); uint32_t blen = bl.size(); switch( blen ) { case 0: esig->setErrCode( PRD_SCAN_COMM_REGISTER_ZERO ); if( error.service_data->isPrimaryPass() ) { rc = PRD_SCAN_COMM_REGISTER_ZERO; } else if( !xNoErrorOnZeroScr ) { rc = PRD_SCAN_COMM_REGISTER_ZERO; } break; case 1: esig->setErrCode(bl.getListValue(0)); break; default: for( uint32_t index = 0; index < blen; ++index ) { esig->setErrCode(bl.getListValue(index)); } esig->setErrCode(PRD_MULTIPLE_ERRORS); }; return rc; }
int32_t ErrorRegister::Analyze( STEP_CODE_DATA_STRUCT & io_sdc ) { int32_t rc = SUCCESS; uint32_t l_savedErrSig = 0; ErrorSignature * esig = io_sdc.service_data->GetErrorSignature(); if(xScrId == 0x0fff) { esig->setRegId(scr.GetAddress()); } else { esig->setRegId( xScrId ); } // Get Data from hardware const BIT_STRING_CLASS &bs = Read( io_sdc.service_data->getSecondaryAttnType() ); BitKey bl; // null bit list has length 0 if ( scr_rc == SUCCESS ) { bl = Filter( bs ); rc = SetErrorSignature( io_sdc, bl ); // Save signature to determine if it changes during resolution // execution. l_savedErrSig = esig->getSigId(); } // This loop will iterate through all bits in the bit list until an active // attention is found. This is useful in the cases where a global or chiplet // level FIR has multiple bits set, but the associated local FIRs may not // have an active attention because of a filter or hardware bug. uint32_t res_rc = SUCCESS; BitKey analyzed_bl; // Keep track of bits that have been analyzed. BitKey remaining_bl = bl; // Keep track of bits that need to be analyzed. do { BitKey res_bl = remaining_bl; BitKey tmp_bl = remaining_bl; // lookup and execute the resolutions res_rc = Lookup( io_sdc, res_bl ); // Add the resolved bits to the analyzed list. // TODO: RTC 126267 Should modify BitKey to have a more efficient way of // adding bits to a list. for ( uint32_t i = 0; i < res_bl.size(); i++ ) analyzed_bl.setBit(res_bl.getListValue(i)); // Remove the resolved bits from the remaining list. remaining_bl.removeBits(res_bl); // Make sure forward progress is made. if ( tmp_bl == remaining_bl ) break; } while ( (PRD_SCAN_COMM_REGISTER_ZERO == res_rc) && (0 != remaining_bl.size()) ); if ( SUCCESS == rc ) rc = res_rc; // previous rc has prioity over res_rc // If we had a DD02 and the signature changes, ignore DD02. if ( rc == PRD_SCAN_COMM_REGISTER_ZERO ) { uint32_t l_currentSig = esig->getSigId(); if( l_currentSig != l_savedErrSig ) { // Found a better answer during the DD02 analysis. rc = res_rc; } } if( scr_rc == SUCCESS ) { FilterUndo( analyzed_bl ); // NOTE: This is an unusual work-a-round for NOT clearing // particular FIR bits in a register because they are cleared // in another part of the plugin code. if( rc == PRD_NO_CLEAR_FIR_BITS ) { //Return success to indicate that we understand the DDFF rc = SUCCESS; } else { int32_t reset_rc; reset_rc = Reset( analyzed_bl, io_sdc ); if( rc == SUCCESS ) rc = reset_rc; } } else // scr read failed { esig->setErrCode( PRD_SCANCOM_FAILURE ); rc = scr_rc; } return(rc); }