diff options
Diffstat (limited to 'src/usr/vpd/ipvpd.C')
-rw-r--r-- | src/usr/vpd/ipvpd.C | 202 |
1 files changed, 184 insertions, 18 deletions
diff --git a/src/usr/vpd/ipvpd.C b/src/usr/vpd/ipvpd.C index 168bc5d36..b38bd77a3 100644 --- a/src/usr/vpd/ipvpd.C +++ b/src/usr/vpd/ipvpd.C @@ -39,7 +39,6 @@ #include <vfs/vfs.H> #include <vpd/vpdreasoncodes.H> #include <vpd/vpd_if.H> -#include <config.h> #include <vpd/ipvpdenums.H> #include <util/utilrsvdmem.H> #include <util/runtime/util_rt.H> @@ -319,6 +318,117 @@ errlHndl_t IpVpdFacade::write ( TARGETING::Target * i_target, } // ------------------------------------------------------------------ +// IpVpdFacade::cmpEecacheToEeprom +// ------------------------------------------------------------------ +errlHndl_t IpVpdFacade::cmpEecacheToEeprom(TARGETING::Target * i_target, + VPD::vpdRecord i_record, + VPD::vpdKeyword i_keyword, + bool & o_match) +{ + errlHndl_t l_err = nullptr; + + TRACSSCOMP(g_trac_vpd, ENTER_MRK"cmpEecacheToEeprom() "); + + o_match = false; + + input_args_t l_cacheArgs; + l_cacheArgs.record = i_record; + l_cacheArgs.keyword = i_keyword; + l_cacheArgs.location = VPD::SEEPROM; + l_cacheArgs.eepromSource = EEPROM::CACHE; + + input_args_t l_hardwareArgs; + l_hardwareArgs.record = i_record; + l_hardwareArgs.keyword = i_keyword; + l_hardwareArgs.location = VPD::SEEPROM; + l_hardwareArgs.eepromSource = EEPROM::HARDWARE; + + do + { + // Get the CACHE size + size_t l_sizeCache = 0; + + l_err = read(i_target, + nullptr, + l_sizeCache, + l_cacheArgs); + + if( l_err || (l_sizeCache == 0) ) + { + TRACFCOMP(g_trac_vpd, + "cmpEecacheToEeprom() an error occurred reading the keyword size in cache"); + break; + } + + // Get the CACHE data + uint8_t l_dataCache[l_sizeCache]; + l_err = read( i_target, + l_dataCache, + l_sizeCache, + l_cacheArgs ); + + if( l_err ) + { + TRACFCOMP(g_trac_vpd, + "cmpEecacheToEeprom() an error occurred reading the keyword in cache"); + break; + } + + // Get the HARDWARE size + size_t l_sizeHardware = 0; + l_err = read( i_target, + nullptr, + l_sizeHardware, + l_hardwareArgs ); + + if( l_err || (l_sizeHardware == 0) ) + { + TRACFCOMP(g_trac_vpd, + "cmpEecacheToEeprom() an error occurred reading the keyword size in hardware"); + break; + } + + // Get the HARDWARE data + uint8_t l_dataHardware[l_sizeHardware]; + l_err = read( i_target, + l_dataHardware, + l_sizeHardware, + l_hardwareArgs ); + + if( l_err ) + { + TRACFCOMP(g_trac_vpd, + "cmpEecacheToEeprom() an error occurred reading the keyword in hardware"); + break; + } + + // Compare the CACHE/HARDWARE keyword size/data + if( l_sizeCache != l_sizeHardware ) + { + // Leave o_match == false since there isn't a match. + break; + } + + if( memcmp( l_dataCache, + l_dataHardware, + l_sizeCache ) != 0 ) + { + TRACFCOMP( g_trac_vpd, "cmpEecacheToEeprom found mismatch for HUID %.8X 0x%X:0x%X", TARGETING::get_huid(i_target), i_record, i_keyword ); + TRACFBIN( g_trac_vpd, "HARDWARE", l_dataHardware, l_sizeHardware ); + TRACFBIN( g_trac_vpd, "CACHE", l_dataCache, l_sizeCache ); + break; + } + + o_match = true; + + } while(0); + + TRACSSCOMP( g_trac_vpd, EXIT_MRK"cmpEecacheToEeprom()" ); + + return l_err; +} + +// ------------------------------------------------------------------ // IpVpdFacade::cmpPnorToSeeprom // ------------------------------------------------------------------ errlHndl_t IpVpdFacade::cmpPnorToSeeprom ( TARGETING::Target * i_target, @@ -885,8 +995,12 @@ errlHndl_t IpVpdFacade::findRecordOffset ( const char * i_record, return err; } - TRACFCOMP( g_trac_vpd, INFO_MRK" Record %s for target 0x%.8X exists at %p in PNOR", + // Don't trace that record exists in PNOR if it does not + if (l_overridePtr != nullptr) + { + TRACFCOMP( g_trac_vpd, INFO_MRK" Record %s for target 0x%.8X exists at %p in PNOR", i_record, get_huid(i_target), l_overridePtr ); + } } // If we have an override, the record is already pointed at directly @@ -1180,7 +1294,7 @@ errlHndl_t IpVpdFacade::findRecordOffsetSeeprom ( const char * i_record, TARGETING::Target * i_target, input_args_t i_args ) { - errlHndl_t err = NULL; + errlHndl_t err = nullptr; char l_buffer[256] = { 0 }; uint16_t offset = 0x0; @@ -1248,6 +1362,12 @@ errlHndl_t IpVpdFacade::findRecordOffsetSeeprom ( const char * i_record, err = retrieveKeyword( "PT", "VTOC", offset, index, i_target, l_buffer, pt_len, i_args ); if ( err ) { + // There may be only one PT record + if (index != 0) + { + delete err; + err = nullptr; + } break; } @@ -1271,7 +1391,7 @@ errlHndl_t IpVpdFacade::findRecordOffsetSeeprom ( const char * i_record, } } - if ( !found && err == NULL ) { + if ( !found && err == nullptr ) { TRACFCOMP( g_trac_vpd, ERR_MRK"IpVpdFacade::findRecordOffsetSeeprom: " "No matching Record (%s) found in VTOC!", i_record ); @@ -1618,6 +1738,36 @@ errlHndl_t IpVpdFacade::retrieveRecord( const char * i_recordName, return err; } + +// ------------------------------------------------------------------ +// IpVpdFacade::fetchData +// ------------------------------------------------------------------ +errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr, + size_t i_numBytes, + void * o_data, + TARGETING::Target * i_target, + VPD::vpdCmdTarget i_location, + const char* i_record ) +{ + errlHndl_t err = nullptr; + + // Create an input_args struct which will default EEPROM_SOURCE + // to EEPROM::AUTOSELECT. + input_args_t inputArgs; + + // Set the VPD location to the given location (PNOR/SEEPROM). + inputArgs.location = i_location; + + err = fetchData(i_byteAddr, + i_numBytes, + o_data, + i_target, + inputArgs, + i_record); + + return err; +} + // ------------------------------------------------------------------ // IpVpdFacade::fetchData // ------------------------------------------------------------------ @@ -1625,7 +1775,7 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr, size_t i_numBytes, void * o_data, TARGETING::Target * i_target, - VPD::vpdCmdTarget i_location, + input_args_t i_args, const char* i_record ) { errlHndl_t err = NULL; @@ -1636,12 +1786,12 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr, configError = VPD::resolveVpdSource( i_target, iv_configInfo.vpdReadPNOR, iv_configInfo.vpdReadHW, - i_location, + i_args.location, vpdSource ); // Look for a record override in our image unless explicitly told not to bool l_foundOverride = false; - if( (i_location & VPD::OVERRIDE_MASK) != VPD::USEVPD ) + if( (i_args.location & VPD::OVERRIDE_MASK) != VPD::USEVPD ) { uint8_t* l_overridePtr = nullptr; VPD::RecordTargetPair_t l_recTarg = @@ -1694,7 +1844,11 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr, } else if ( (vpdSource == VPD::SEEPROM) && !l_foundOverride ) { - err = fetchDataFromEeprom( i_byteAddr, i_numBytes, o_data, i_target ); + err = fetchDataFromEeprom(i_byteAddr, + i_numBytes, + o_data, + i_target, + i_args.eepromSource); } else { @@ -1723,7 +1877,7 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr, VPD::VPD_READ_SOURCE_UNRESOLVED, TWO_UINT32_TO_UINT64( TARGETING::get_huid(i_target), - i_location ), + i_args.location ), TWO_UINT32_TO_UINT64( iv_configInfo.vpdReadPNOR, iv_configInfo.vpdReadHW ), @@ -1777,10 +1931,11 @@ errlHndl_t IpVpdFacade::fetchDataFromPnor ( uint64_t i_byteAddr, // ------------------------------------------------------------------ // IpVpdFacade::fetchDataFromEeprom // ------------------------------------------------------------------ -errlHndl_t IpVpdFacade::fetchDataFromEeprom ( uint64_t i_byteAddr, - size_t i_numBytes, - void * o_data, - TARGETING::Target * i_target ) +errlHndl_t IpVpdFacade::fetchDataFromEeprom(uint64_t i_byteAddr, + size_t i_numBytes, + void * o_data, + TARGETING::Target * i_target, + EEPROM::EEPROM_SOURCE i_eepromSource) { errlHndl_t err = NULL; TRACSSCOMP( g_trac_vpd, @@ -1797,7 +1952,8 @@ errlHndl_t IpVpdFacade::fetchDataFromEeprom ( uint64_t i_byteAddr, i_numBytes, DEVICE_EEPROM_ADDRESS( EEPROM::VPD_PRIMARY, - i_byteAddr, EEPROM::AUTOSELECT ) ); + i_byteAddr, + i_eepromSource ) ); if( err ) { break; @@ -1896,21 +2052,31 @@ errlHndl_t IpVpdFacade::findKeywordAddr ( const char * i_keywordName, offset, i_recordName ); + // convert data for SRC display + uint32_t exp_rec; + memcpy( &exp_rec, i_recordName, RECORD_BYTE_SIZE ); + uint32_t act_rec; + memcpy( &act_rec, record, RECORD_BYTE_SIZE ); + /*@ * @errortype * @reasoncode VPD::VPD_RECORD_MISMATCH * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid VPD::VPD_IPVPD_FIND_KEYWORD_ADDR - * @userdata1 Current offset into VPD - * @userdata2 Start of Record offset + * @userdata1[00:31] Current offset into VPD + * @userdata1[32:63] Start of Record offset + * @userdata2[00:31] Expected record name + * @userdata2[32:63] Found record name * @devdesc Record name does not match value expected for * offset read. */ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, VPD::VPD_IPVPD_FIND_KEYWORD_ADDR, VPD::VPD_RECORD_MISMATCH, - offset, - i_offset ); + TWO_UINT32_TO_UINT64(offset, + i_offset ), + TWO_UINT32_TO_UINT64(exp_rec, + act_rec) ); // Could be the VPD of the target wasn't set up properly // -- DECONFIG so that we can possibly keep booting |