summaryrefslogtreecommitdiffstats
path: root/src/usr/vpd/ipvpd.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/vpd/ipvpd.C')
-rw-r--r--src/usr/vpd/ipvpd.C202
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
OpenPOWER on IntegriCloud