summaryrefslogtreecommitdiffstats
path: root/src/usr/vpd/dvpd.C
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2018-06-18 23:05:31 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2018-07-03 09:18:52 -0400
commite5dfc3ab0ec51ee63205c7064b7b4a4c4b8ba46f (patch)
tree76ccf82718d46c0bb7bbb5cbcf451d2bbd03aaf6 /src/usr/vpd/dvpd.C
parent691894a135de3e81f4318a5498c4a964fdebb8ae (diff)
downloadtalos-hostboot-e5dfc3ab0ec51ee63205c7064b7b4a4c4b8ba46f.tar.gz
talos-hostboot-e5dfc3ab0ec51ee63205c7064b7b4a4c4b8ba46f.zip
Allow SPDX override as part of FW load
Memory VPD contents have changed since the cards have been built so we need to provide a method to override the data as part of a FW build. We have done the same thing previously for the MEMD record on the Nimbus machines so will use the same design here for SPDX. As part of this change, the previous MEMD support was refactored to be completely generic so a single code path can be used for any arbitrary record. Change-Id: I5af5e965429c881be3de0d18c82b1d7918ac9c22 CQ: SW430659 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/61190 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60980
Diffstat (limited to 'src/usr/vpd/dvpd.C')
-rw-r--r--src/usr/vpd/dvpd.C164
1 files changed, 154 insertions, 10 deletions
diff --git a/src/usr/vpd/dvpd.C b/src/usr/vpd/dvpd.C
index 8adf670f7..9e5e7fbf4 100644
--- a/src/usr/vpd/dvpd.C
+++ b/src/usr/vpd/dvpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -113,12 +113,44 @@ namespace DVPD
args.location = ((VPD::vpdCmdTarget)va_arg( i_args, uint64_t ));
TRACSSCOMP( g_trac_vpd,
- ENTER_MRK"dvpdRead()" );
+ ENTER_MRK"dvpdRead(0x%.8X):rec=%d,kw=%d,loc=%d",
+ TARGETING::get_huid(i_target),
+ args.record,
+ args.keyword,
+ args.location);
+
+#ifdef CONFIG_SECUREBOOT
+ // Load the secure section just in case if we're using it
+ bool l_didload = false;
+ err = Singleton<DvpdFacade>::instance().
+ loadUnloadSecureSection( args, i_target, true, l_didload );
+#endif
- err = Singleton<DvpdFacade>::instance().read(i_target,
- io_buffer,
- io_buflen,
- args);
+ if( !err )
+ {
+ err = Singleton<DvpdFacade>::instance().read(i_target,
+ io_buffer,
+ io_buflen,
+ args);
+ }
+
+#ifdef CONFIG_SECUREBOOT
+ if( l_didload )
+ {
+ errlHndl_t err2 = Singleton<DvpdFacade>::instance().
+ loadUnloadSecureSection( args, i_target, false, l_didload );
+ if( err2 && !err )
+ {
+ err = err2;
+ err2 = nullptr;
+ }
+ else if( err2 )
+ {
+ err2->plid(err->plid());
+ errlCommit( err2, VPD_COMP_ID );
+ }
+ }
+#endif
return err;
}
@@ -166,7 +198,11 @@ namespace DVPD
args.location = ((VPD::vpdCmdTarget)va_arg( i_args, uint64_t ));
TRACSSCOMP( g_trac_vpd,
- ENTER_MRK"dvpdWrite()" );
+ ENTER_MRK"dvpdWrite(0x%.8X):rec=%d,kw=%d,loc=%d",
+ TARGETING::get_huid(i_target),
+ args.record,
+ args.keyword,
+ args.location);
err = Singleton<DvpdFacade>::instance().write(i_target,
@@ -337,9 +373,8 @@ IpVpdFacade(DVPD::dvpdRecords,
iv_configInfo.vpdWriteHW = false;
#endif
-iv_vpdSectionSize = DVPD::SECTION_SIZE;
-iv_vpdMaxSections = DVPD::MAX_SECTIONS;
-
+ iv_vpdSectionSize = DVPD::SECTION_SIZE;
+ iv_vpdMaxSections = DVPD::MAX_SECTIONS;
}
// Retrun lists of records that should be copied to pnor.
void DvpdFacade::getRecordLists(
@@ -367,3 +402,112 @@ void DvpdFacade::getRecordLists(
#endif
}
+/**
+ * @brief Callback function to check for a record override
+ */
+errlHndl_t DvpdFacade::checkForRecordOverride( const char* i_record,
+ TARGETING::Target* i_target,
+ uint8_t*& o_ptr )
+{
+ TRACFCOMP(g_trac_vpd,ENTER_MRK"DvpdFacade::checkForRecordOverride( %s, 0x%.8X )",
+ i_record, get_huid(i_target));
+ errlHndl_t l_errl = nullptr;
+ o_ptr = nullptr;
+
+ assert( i_record != nullptr, "DvpdFacade::checkForRecordOverride() i_record is null" );
+ assert( i_target != nullptr, "DvpdFacade::checkForRecordOverride() i_target is null" );
+
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(i_record,i_target);
+
+ do
+ {
+ // We only support overriding MEMD
+ if( strcmp( i_record, "MEMD" ) )
+ {
+ TRACFCOMP(g_trac_vpd,"Record %s has no override", i_record);
+ iv_overridePtr[l_recTarg] = nullptr;
+ break;
+ }
+
+ // Compare the last nibble
+ constexpr uint32_t l_vmMask = 0x0000000F;
+ input_args_t l_args = { DVPD::MEMD, DVPD::VM, VPD::AUTOSELECT };
+ l_errl = getMEMDFromPNOR( l_args,
+ i_target,
+ l_vmMask );
+ if( l_errl )
+ {
+ TRACFCOMP(g_trac_vpd,ERR_MRK"ERROR from getMEMDFromPNOR.");
+ break;
+ }
+
+ } while(0);
+
+ // For any error, we should reset the override map so that we'll
+ // attempt everything again the next time we want VPD
+ if( l_errl )
+ {
+ iv_overridePtr.erase(l_recTarg);
+ }
+ else
+ {
+ o_ptr = iv_overridePtr[l_recTarg];
+ }
+
+ return l_errl;
+}
+
+#ifdef CONFIG_SECUREBOOT
+/**
+ * @brief Load/unload the appropriate secure section for
+ * an overriden PNOR section
+ */
+errlHndl_t DvpdFacade::loadUnloadSecureSection( input_args_t i_args,
+ TARGETING::Target* i_target,
+ bool i_load,
+ bool& o_loaded )
+{
+ errlHndl_t l_err = nullptr;
+ o_loaded = false;
+
+#ifndef __HOSTBOOT_RUNTIME
+ // Only relevant for MEMD
+ if( i_args.record != DVPD::MEMD )
+ {
+ return nullptr;
+ }
+
+ const char* l_record = nullptr;
+ l_err = translateRecord( i_args.record, l_record );
+ if( l_err )
+ {
+ return l_err;
+ }
+
+ // Jump out if we don't have an override
+ VPD::RecordTargetPair_t l_recTarg =
+ VPD::makeRecordTargetPair(l_record,i_target);
+ VPD::OverrideMap_t::iterator l_overItr = iv_overridePtr.find(l_recTarg);
+ if( l_overItr == iv_overridePtr.end() )
+ {
+ return nullptr;
+ }
+
+ if( i_load )
+ {
+ l_err = loadSecureSection(PNOR::MEMD);
+ if( !l_err )
+ {
+ o_loaded = true;
+ }
+ }
+ else
+ {
+ l_err = unloadSecureSection(PNOR::MEMD);
+ }
+#endif
+
+ return l_err;
+}
+#endif
OpenPOWER on IntegriCloud