diff options
author | Corey Swenson <cswenson@us.ibm.com> | 2015-05-15 10:30:04 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-07-17 09:50:29 -0500 |
commit | a34452451070830c8f9149100a8a8523220527a9 (patch) | |
tree | ceeef38401d1c3eed596b1c3e1bb705570b75892 /src/usr/vpd | |
parent | 5d1ff7656b2b1b8e50d9f30b180ff3e10b3adf3e (diff) | |
download | talos-hostboot-a34452451070830c8f9149100a8a8523220527a9.tar.gz talos-hostboot-a34452451070830c8f9149100a8a8523220527a9.zip |
Fix for VPD issues in golden and mfg boot
Change-Id: I86bed87da21ec9037c7b828874052066e4ec5f4a
RTC: 128100
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/17821
Tested-by: Jenkins Server
Tested-by: Jenkins OP Build CI
Tested-by: Jenkins OP HW
Reviewed-by: William H. Schwartz <whs@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/vpd')
-rw-r--r-- | src/usr/vpd/HBconfig | 4 | ||||
-rw-r--r-- | src/usr/vpd/mvpd.C | 2 | ||||
-rw-r--r-- | src/usr/vpd/rtvpd_load.C | 53 | ||||
-rw-r--r-- | src/usr/vpd/runtime/rt_vpd.C | 136 | ||||
-rwxr-xr-x | src/usr/vpd/vpd.C | 118 | ||||
-rw-r--r-- | src/usr/vpd/vpd.H | 15 | ||||
-rw-r--r-- | src/usr/vpd/vpd.mk | 1 | ||||
-rw-r--r-- | src/usr/vpd/vpd_common.C | 139 |
8 files changed, 251 insertions, 217 deletions
diff --git a/src/usr/vpd/HBconfig b/src/usr/vpd/HBconfig index 1d6e6f1b8..615a548e8 100644 --- a/src/usr/vpd/HBconfig +++ b/src/usr/vpd/HBconfig @@ -45,7 +45,7 @@ config PVPD_READ_FROM_HW config PVPD_WRITE_TO_PNOR default y if PVPD_READ_FROM_PNOR - depends on PVPD_READ_FROM_PNOR + depends on PVPD_READ_FROM_PNOR && CVPD_WRITE_TO_PNOR help Write Planar VPD data to PNOR cache @@ -92,7 +92,7 @@ config DJVPD_READ_FROM_PNOR default y help Read Dimm JEDEC VPD/SPD data from PNOR cache - + config DJVPD_READ_FROM_HW default n help diff --git a/src/usr/vpd/mvpd.C b/src/usr/vpd/mvpd.C index a1c41be5b..6a8cd2777 100644 --- a/src/usr/vpd/mvpd.C +++ b/src/usr/vpd/mvpd.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ diff --git a/src/usr/vpd/rtvpd_load.C b/src/usr/vpd/rtvpd_load.C index d7b46436f..b9fbf2fef 100644 --- a/src/usr/vpd/rtvpd_load.C +++ b/src/usr/vpd/rtvpd_load.C @@ -82,7 +82,7 @@ errlHndl_t bld_vpd_image(PNOR::SectionId vpd_type, * @moduleid VPD::VPD_BLD_RT_IMAGE * @userdata1 Size provided * @userdata2 vpd_type | Size required - * @devdesc Reserved size in memory insufficient + * @devdesc Reserved size in memory insufficient * for runtime VPD */ err = new ERRORLOG::ErrlEntry @@ -152,6 +152,57 @@ errlHndl_t VPD::vpd_load_rt_image(uint64_t & o_vpd_addr) mm_block_unmap(vptr); + } while( 0 ); + + return err; +} + +// External function see vpd_if.H +errlHndl_t VPD::goldenSwitchUpdate(void) +{ + errlHndl_t err = NULL; + + do + { +#ifdef CONFIG_PNOR_TWO_SIDE_SUPPORT + // Do not write to the PNOR at runtime after booting from the + // golden side of pnor + PNOR::SideInfo_t l_pnorInfo; + err = PNOR::getSideInfo( PNOR::WORKING, l_pnorInfo ); + if( err ) + { + break; + } + else if( l_pnorInfo.isGolden ) + { + TARGETING::ATTR_VPD_SWITCHES_type l_switch; + + // Find all the targets with VPD switches + for (TARGETING::TargetIterator target = + TARGETING::targetService().begin(); + target != TARGETING::targetService().end(); + ++target) + { + if(target->tryGetAttr<TARGETING::ATTR_VPD_SWITCHES>(l_switch)) + { + l_switch.disableWriteToPnorRT = 1; + target->setAttr<TARGETING::ATTR_VPD_SWITCHES>( l_switch ); + } + } + } +#endif + } while( 0 ); + + return err; +} + +// External function see vpd_if.H +errlHndl_t VPD::goldenCacheInvalidate(void) +{ + errlHndl_t err = NULL; + + do + { bool l_invalidateCaches = false; // In manufacturing mode the VPD PNOR cache needs to be cleared diff --git a/src/usr/vpd/runtime/rt_vpd.C b/src/usr/vpd/runtime/rt_vpd.C index d73b0dc1a..f6bc47139 100644 --- a/src/usr/vpd/runtime/rt_vpd.C +++ b/src/usr/vpd/runtime/rt_vpd.C @@ -37,11 +37,7 @@ #include "cvpd.H" #include "spd.H" -// ---------------------------------------------- -// Trace definitions -// ---------------------------------------------- -trace_desc_t* g_trac_vpd = NULL; -TRAC_INIT( & g_trac_vpd, "VPD", KILOBYTE ); +extern trace_desc_t* g_trac_vpd; // ------------------------ // Macros for unit testing @@ -50,30 +46,39 @@ TRAC_INIT( & g_trac_vpd, "VPD", KILOBYTE ); //#define TRACSSCOMP(args...) TRACFCOMP(args) #define TRACSSCOMP(args...) + namespace VPD { // ------------------------------------------------------------------ -// getVpdLocation +// rtVpdInit // ------------------------------------------------------------------ -errlHndl_t getVpdLocation ( int64_t & o_vpdLocation, - TARGETING::Target * i_target ) +struct rtVpdInit { - errlHndl_t err = NULL; - - TRACSSCOMP( g_trac_vpd, - ENTER_MRK"getVpdLocation()" ); - - o_vpdLocation = i_target->getAttr<TARGETING::ATTR_VPD_REC_NUM>(); - TRACUCOMP( g_trac_vpd, - INFO_MRK"Using VPD location: %d", - o_vpdLocation ); - - TRACSSCOMP( g_trac_vpd, - EXIT_MRK"getVpdLocation()" ); - - return err; -} + rtVpdInit() + { + // The VPD code that is common to IPL and runtime uses the + // pnorCacheValid switch. During a golden-side boot this switch + // gets cleared when the VPD cache is invalidated. At runtime + // we may need to use the VPD cache (really the devtree data in + // memory) so we copy the RT switch to the common switch. + + // Find all the targets with VPD switches + for (TARGETING::TargetIterator target = + TARGETING::targetService().begin(); + target != TARGETING::targetService().end(); + ++target) + { + TARGETING::ATTR_VPD_SWITCHES_type l_switch; + if(target->tryGetAttr<TARGETING::ATTR_VPD_SWITCHES>(l_switch)) + { + l_switch.pnorCacheValid = l_switch.pnorCacheValidRT; + target->setAttr<TARGETING::ATTR_VPD_SWITCHES>( l_switch ); + } + } + } +}; +rtVpdInit g_rtVpdInit; // ------------------------------------------------------------------ // Fake getPnorAddr - VPD image is in memory @@ -347,7 +352,7 @@ errlHndl_t writePNOR ( uint64_t i_byteAddr, // Check if the VPD PNOR cache is loaded for this target TARGETING::ATTR_VPD_SWITCHES_type vpdSwitches = i_target->getAttr<TARGETING::ATTR_VPD_SWITCHES>(); - if( vpdSwitches.pnorCacheValid ) + if( vpdSwitches.pnorCacheValid && !(vpdSwitches.disableWriteToPnorRT) ) { PNOR::SectionInfo_t info; writeAddr = NULL; @@ -386,21 +391,6 @@ errlHndl_t writePNOR ( uint64_t i_byteAddr, } } - //------------------------ - // Write HW version of VPD - //------------------------ - err = DeviceFW::deviceOp( DeviceFW::WRITE, - i_target, - i_data, - i_numBytes, - DEVICE_EEPROM_ADDRESS( - EEPROM::VPD_PRIMARY, - i_byteAddr ) ); - if( err ) - { - break; - } - } while(0); TRACSSCOMP( g_trac_vpd, @@ -454,73 +444,5 @@ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes, return err; } -// ------------------------------------------------------------------ -// resolveVpdSource -// ------------------------------------------------------------------ -bool resolveVpdSource( TARGETING::Target * i_target, - bool i_readFromPnorEnabled, - bool i_readFromHwEnabled, - vpdCmdTarget i_vpdCmdTarget, - vpdCmdTarget& o_vpdSource ) -{ - bool badConfig = false; - o_vpdSource = VPD::INVALID_LOCATION; - - if( i_vpdCmdTarget == VPD::PNOR ) - { - if( i_readFromPnorEnabled ) - { - o_vpdSource = VPD::PNOR; - } - else - { - badConfig = true; - } - } - else if( i_vpdCmdTarget == VPD::SEEPROM ) - { - if( i_readFromHwEnabled ) - { - o_vpdSource = VPD::SEEPROM; - } - else - { - badConfig = true; - } - } - else - { - if( i_readFromPnorEnabled && - i_readFromHwEnabled ) - { - // PNOR needs to be loaded before we can use it - TARGETING::ATTR_VPD_SWITCHES_type vpdSwitches = - i_target->getAttr<TARGETING::ATTR_VPD_SWITCHES>(); - if( vpdSwitches.pnorCacheValid ) - { - o_vpdSource = VPD::PNOR; - } - else - { - o_vpdSource = VPD::SEEPROM; - } - } - else if( i_readFromPnorEnabled ) - { - o_vpdSource = VPD::PNOR; - } - else if( i_readFromHwEnabled ) - { - o_vpdSource = VPD::SEEPROM; - } - else - { - badConfig = true; - } - } - - return badConfig; -} - }; // end namepsace VPD diff --git a/src/usr/vpd/vpd.C b/src/usr/vpd/vpd.C index e3773bff3..4a8ccf408 100755 --- a/src/usr/vpd/vpd.C +++ b/src/usr/vpd/vpd.C @@ -39,10 +39,9 @@ #include "ipvpd.H" // ---------------------------------------------- -// Trace definitions +// Trace - defined in vpd_common // ---------------------------------------------- -trace_desc_t* g_trac_vpd = NULL; -TRAC_INIT( & g_trac_vpd, "VPD", KILOBYTE ); +extern trace_desc_t* g_trac_vpd; // ------------------------ // Macros for unit testing @@ -55,29 +54,6 @@ namespace VPD { // ------------------------------------------------------------------ -// getVpdLocation -// ------------------------------------------------------------------ -errlHndl_t getVpdLocation ( int64_t & o_vpdLocation, - TARGETING::Target * i_target ) -{ - errlHndl_t err = NULL; - - TRACSSCOMP( g_trac_vpd, - ENTER_MRK"getVpdLocation()" ); - - o_vpdLocation = i_target->getAttr<TARGETING::ATTR_VPD_REC_NUM>(); - TRACUCOMP( g_trac_vpd, - INFO_MRK"Using VPD location: %d", - o_vpdLocation ); - - TRACSSCOMP( g_trac_vpd, - EXIT_MRK"getVpdLocation()" ); - - return err; -} - - -// ------------------------------------------------------------------ // getPnorAddr // ------------------------------------------------------------------ errlHndl_t getPnorAddr ( pnorInformation & i_pnorInfo, @@ -355,78 +331,6 @@ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes, // ------------------------------------------------------------------ -// resolveVpdSource -// ------------------------------------------------------------------ -bool resolveVpdSource( TARGETING::Target * i_target, - bool i_rwPnorEnabled, - bool i_rwHwEnabled, - vpdCmdTarget i_vpdCmdTarget, - vpdCmdTarget& o_vpdSource ) -{ - bool badConfig = false; - o_vpdSource = VPD::INVALID_LOCATION; - - if( i_vpdCmdTarget == VPD::PNOR ) - { - if( i_rwPnorEnabled ) - { - o_vpdSource = VPD::PNOR; - } - else - { - badConfig = true; - TRACFCOMP(g_trac_vpd,"resolveVpdSource: VpdCmdTarget=PNOR but READ/WRITE PNOR CONFIG is disabled"); - } - } - else if( i_vpdCmdTarget == VPD::SEEPROM ) - { - if( i_rwHwEnabled ) - { - o_vpdSource = VPD::SEEPROM; - } - else - { - badConfig = true; - TRACFCOMP(g_trac_vpd,"resolveVpdSource: VpdCmdTarget=SEEPROM but READ/WRITE HW CONFIG is disabled"); - } - } - else // i_vpdCmdTarget == VPD::AUTOSELECT - { - if( i_rwPnorEnabled && - i_rwHwEnabled ) - { - // PNOR needs to be loaded before we can use it - TARGETING::ATTR_VPD_SWITCHES_type vpdSwitches = - i_target->getAttr<TARGETING::ATTR_VPD_SWITCHES>(); - if( vpdSwitches.pnorCacheValid ) - { - o_vpdSource = VPD::PNOR; - } - else - { - o_vpdSource = VPD::SEEPROM; - } - } - else if( i_rwPnorEnabled ) - { - o_vpdSource = VPD::PNOR; - } - else if( i_rwHwEnabled ) - { - o_vpdSource = VPD::SEEPROM; - } - else - { - badConfig = true; - TRACFCOMP(g_trac_vpd,"resolveVpdSource: READ/WRITE PNOR CONFIG and READ/WRITE HW CONFIG disabled"); - } - } - - return badConfig; -} - - -// ------------------------------------------------------------------ // setPartAndSerialNumberAttributes // ------------------------------------------------------------------ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target ) @@ -815,10 +719,11 @@ errlHndl_t ensureCacheIsInSync ( TARGETING::Target * i_target ) } } - // Set target attribute switch that says VPD is loaded into PNOR + // Set target attribute switches that say VPD is loaded into PNOR TARGETING::ATTR_VPD_SWITCHES_type vpdSwitches = i_target->getAttr<TARGETING::ATTR_VPD_SWITCHES>(); vpdSwitches.pnorCacheValid = 1; + vpdSwitches.pnorCacheValidRT = 1; i_target->setAttr<TARGETING::ATTR_VPD_SWITCHES>( vpdSwitches ); } while(0); @@ -876,6 +781,7 @@ void setVpdConfigFlagsHW ( ) { Singleton<MvpdFacade>::instance().setConfigFlagsHW(); Singleton<CvpdFacade>::instance().setConfigFlagsHW(); + Singleton<PvpdFacade>::instance().setConfigFlagsHW(); SPD::setConfigFlagsHW(); } @@ -889,13 +795,6 @@ errlHndl_t invalidateAllPnorCaches ( bool i_setHwOnly ) errlHndl_t l_err = NULL; do { - // Reset the PNOR config flags to HW - MVPD/CVPD/SPD - // Checks for PNOR caching mode before reset - if( i_setHwOnly ) - { - VPD::setVpdConfigFlagsHW(); - } - // Find all the targets with VPD switches for (TARGETING::TargetIterator target = TARGETING::targetService().begin(); @@ -922,6 +821,13 @@ errlHndl_t invalidateAllPnorCaches ( bool i_setHwOnly ) break; } + // Reset the PNOR config flags to HW - MVPD/CVPD/SPD + // Checks for PNOR caching mode before reset + if( i_setHwOnly ) + { + VPD::setVpdConfigFlagsHW(); + } + } while(0); return l_err; diff --git a/src/usr/vpd/vpd.H b/src/usr/vpd/vpd.H index 3d7b22a6e..1451feae8 100644 --- a/src/usr/vpd/vpd.H +++ b/src/usr/vpd/vpd.H @@ -83,6 +83,21 @@ union VpdWriteMsg_t /** + * @brief This function is used to query the attribute code to get the VPD + * Location value for the target provided. + * + * @param[out] o_vpdLocation - The value of the VPD Location attribute. + * + * @param[in] i_target - The target to query. + * + * @return errlHndl_t - NULL if successful, otherwise a pointer to the + * Error log. + */ +errlHndl_t getVpdLocation ( int64_t & o_vpdLocation, + TARGETING::Target * i_target ); + + +/** * @brief This function will query the PNOR RP to get the offset of the * section requested. It will then set global variables to save this * value away for later use. This function only needs to be called once. diff --git a/src/usr/vpd/vpd.mk b/src/usr/vpd/vpd.mk index 65d22e344..a541ccc7e 100644 --- a/src/usr/vpd/vpd.mk +++ b/src/usr/vpd/vpd.mk @@ -23,6 +23,7 @@ # # IBM_PROLOG_END_TAG # common objects with runtime +OBJS += vpd_common.o OBJS += ipvpd.o OBJS += mvpd.o OBJS += cvpd.o diff --git a/src/usr/vpd/vpd_common.C b/src/usr/vpd/vpd_common.C new file mode 100644 index 000000000..d11dc8743 --- /dev/null +++ b/src/usr/vpd/vpd_common.C @@ -0,0 +1,139 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/vpd/vpd.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* [+] 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 "vpd.H" + +// ---------------------------------------------- +// Trace definitions +// ---------------------------------------------- +trace_desc_t* g_trac_vpd = NULL; +TRAC_INIT( & g_trac_vpd, "VPD", KILOBYTE ); + +// ------------------------ +// Macros for unit testing +//#define TRACUCOMP(args...) TRACFCOMP(args) +#define TRACUCOMP(args...) +//#define TRACSSCOMP(args...) TRACFCOMP(args) +#define TRACSSCOMP(args...) + + +namespace VPD +{ + +// ------------------------------------------------------------------ +// getVpdLocation +// ------------------------------------------------------------------ +errlHndl_t getVpdLocation ( int64_t & o_vpdLocation, + TARGETING::Target * i_target ) +{ + errlHndl_t err = NULL; + + TRACSSCOMP( g_trac_vpd, + ENTER_MRK"getVpdLocation()" ); + + o_vpdLocation = i_target->getAttr<TARGETING::ATTR_VPD_REC_NUM>(); + TRACUCOMP( g_trac_vpd, + INFO_MRK"Using VPD location: %d", + o_vpdLocation ); + + TRACSSCOMP( g_trac_vpd, + EXIT_MRK"getVpdLocation()" ); + + return err; +} + + +// ------------------------------------------------------------------ +// resolveVpdSource +// ------------------------------------------------------------------ +bool resolveVpdSource( TARGETING::Target * i_target, + bool i_rwPnorEnabled, + bool i_rwHwEnabled, + vpdCmdTarget i_vpdCmdTarget, + vpdCmdTarget& o_vpdSource ) +{ + bool badConfig = false; + o_vpdSource = VPD::INVALID_LOCATION; + + if( i_vpdCmdTarget == VPD::PNOR ) + { + if( i_rwPnorEnabled ) + { + o_vpdSource = VPD::PNOR; + } + else + { + badConfig = true; + TRACFCOMP(g_trac_vpd,"resolveVpdSource: VpdCmdTarget=PNOR but READ/WRITE PNOR CONFIG is disabled"); + } + } + else if( i_vpdCmdTarget == VPD::SEEPROM ) + { + if( i_rwHwEnabled ) + { + o_vpdSource = VPD::SEEPROM; + } + else + { + badConfig = true; + TRACFCOMP(g_trac_vpd,"resolveVpdSource: VpdCmdTarget=SEEPROM but READ/WRITE HW CONFIG is disabled"); + } + } + else // i_vpdCmdTarget == VPD::AUTOSELECT + { + if( i_rwPnorEnabled && + i_rwHwEnabled ) + { + // PNOR needs to be loaded before we can use it + TARGETING::ATTR_VPD_SWITCHES_type vpdSwitches = + i_target->getAttr<TARGETING::ATTR_VPD_SWITCHES>(); + if( vpdSwitches.pnorCacheValid ) + { + o_vpdSource = VPD::PNOR; + } + else + { + o_vpdSource = VPD::SEEPROM; + } + } + else if( i_rwPnorEnabled ) + { + o_vpdSource = VPD::PNOR; + } + else if( i_rwHwEnabled ) + { + o_vpdSource = VPD::SEEPROM; + } + else + { + badConfig = true; + TRACFCOMP(g_trac_vpd,"resolveVpdSource: READ/WRITE PNOR CONFIG and READ/WRITE HW CONFIG disabled"); + } + } + + return badConfig; +} + +}; //end VPD namespace |