summaryrefslogtreecommitdiffstats
path: root/src/usr/runtime/preverifiedlidmgr.C
diff options
context:
space:
mode:
authorStephen Cprek <smcprek@us.ibm.com>2017-10-03 09:36:58 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2017-10-24 13:58:43 -0400
commit0ff075bac5d78384a625de70b34b7ef363a25fd6 (patch)
tree30e1a8e011be3b2bfde6d4e616f8745dde212d28 /src/usr/runtime/preverifiedlidmgr.C
parentda12bd653f7eabbc2d97938a3ac25666187e6abb (diff)
downloadtalos-hostboot-0ff075bac5d78384a625de70b34b7ef363a25fd6.tar.gz
talos-hostboot-0ff075bac5d78384a625de70b34b7ef363a25fd6.zip
Create Pre Verified Lid Manager and refactor exisiting implementation
Change-Id: I5417b8e381bf15a1b696cf006940eedd7a1e235c RTC:125304 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/47110 Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> 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: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/usr/runtime/preverifiedlidmgr.C')
-rw-r--r--src/usr/runtime/preverifiedlidmgr.C332
1 files changed, 332 insertions, 0 deletions
diff --git a/src/usr/runtime/preverifiedlidmgr.C b/src/usr/runtime/preverifiedlidmgr.C
new file mode 100644
index 000000000..0f3398721
--- /dev/null
+++ b/src/usr/runtime/preverifiedlidmgr.C
@@ -0,0 +1,332 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/preverifiedlidmgr.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017 */
+/* [+] 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 <runtime/preverifiedlidmgr.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <utility>
+#include <runtime/populate_hbruntime.H>
+#include <util/align.H>
+#include <util/utillidmgr.H>
+#include <util/utillidpnor.H>
+#include <initservice/initserviceif.H>
+#include <util/singleton.H>
+#include <stdio.h>
+#include <arch/ppc.H>
+
+extern trace_desc_t *g_trac_runtime;
+
+// Set static variables
+TARGETING::PAYLOAD_KIND PreVerifiedLidMgr::cv_payloadKind = TARGETING::PAYLOAD_KIND_NONE;
+std::map<uint64_t,bool> PreVerifiedLidMgr::cv_lidsLoaded {};
+bool PreVerifiedLidMgr::cv_phypLidSeen = false;
+PreVerifiedLidMgr::ResvMemInfo* PreVerifiedLidMgr::cv_pResvMemInfo = nullptr;
+PreVerifiedLidMgr::ResvMemInfo PreVerifiedLidMgr::cv_resvMemInfo {};
+PreVerifiedLidMgr::ResvMemInfo PreVerifiedLidMgr::cv_phypResvMemInfo {};
+mutex_t PreVerifiedLidMgr::cv_mutex = MUTEX_INITIALIZER;
+mutex_t PreVerifiedLidMgr::cv_loadImageMutex = MUTEX_INITIALIZER;
+
+/********************
+ Public Methods
+ ********************/
+
+void PreVerifiedLidMgr::initLock(const uint64_t i_prevAddr,
+ const uint64_t i_prevSize,
+ const size_t i_rangeId)
+{
+ Singleton<PreVerifiedLidMgr>::instance()._initLock(i_prevAddr,
+ i_prevSize,
+ i_rangeId);
+}
+
+void PreVerifiedLidMgr::unlock()
+{
+ Singleton<PreVerifiedLidMgr>::instance()._unlock();
+}
+
+
+errlHndl_t PreVerifiedLidMgr::loadFromPnor(const PNOR::SectionId i_sec,
+ const uint64_t i_addr,
+ const size_t i_size)
+{
+ return Singleton<PreVerifiedLidMgr>::instance()._loadFromPnor(i_sec,
+ i_addr,
+ i_size);
+}
+
+/********************
+ Private Implementations of Static Public Methods
+ ********************/
+
+void PreVerifiedLidMgr::_initLock(const uint64_t i_prevAddr,
+ const uint64_t i_prevSize,
+ const size_t i_rangeId)
+{
+ mutex_lock(&cv_mutex);
+
+ cv_payloadKind = TARGETING::PAYLOAD_KIND_NONE;
+ cv_phypLidSeen = false;
+
+ // Default Reserved Memory Information
+ cv_resvMemInfo.rangeId = i_rangeId;
+ cv_resvMemInfo.curAddr = i_prevAddr;
+ cv_resvMemInfo.prevSize = i_prevSize;
+
+ // PHYP Reserved Memory Information
+ cv_phypResvMemInfo.rangeId = i_rangeId;
+ // PHYP lids loaded at HRMOR - 4K (Header)
+ // Get Target Service, and the system target.
+ TARGETING::Target* l_sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget(l_sys);
+ assert(l_sys!=nullptr,"Top Level Target is nullptr");
+ cv_phypResvMemInfo.curAddr = (l_sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>()
+ * MEGABYTE) - PAGE_SIZE;
+
+ // PHYP should be placed starting exactly at HRMOR - 4K, so make prevSize 0
+ cv_phypResvMemInfo.prevSize = 0;
+
+ // Refer to default reserved memory
+ cv_pResvMemInfo = &cv_resvMemInfo;
+
+ // Set variables based on payload Kind
+ // Note: For PHYP we build up starting at the end of the
+ // previously allocated HOMER/OCC areas, for OPAL we build
+ // downwards from the top of memory where the HOMER/OCC
+ // areas were placed
+
+ // Set default next physical address to simply increment in order
+ getNextAddress = getNextPhypAddress;
+
+ if(TARGETING::is_phyp_load())
+ {
+ cv_payloadKind = TARGETING::PAYLOAD_KIND_PHYP;
+ }
+ else if(TARGETING::is_sapphire_load())
+ {
+ cv_payloadKind = TARGETING::PAYLOAD_KIND_SAPPHIRE;
+ getNextAddress = getNextOpalAddress;
+ }
+}
+
+void PreVerifiedLidMgr::_unlock()
+{
+ TRACFCOMP(g_trac_runtime, "PreVerifiedLidMgr::_unlock");
+ mutex_unlock(&cv_mutex);
+}
+
+errlHndl_t PreVerifiedLidMgr::_loadFromPnor(const PNOR::SectionId i_sec,
+ const uint64_t i_addr,
+ const size_t i_size)
+{
+ mutex_lock(&cv_loadImageMutex);
+
+ TRACFCOMP(g_trac_runtime, ENTER_MRK"PreVerifiedLidMgr::_loadFromPnor - sec %s",
+ PNOR::SectionIdToString(i_sec));
+
+ errlHndl_t l_errl = nullptr;
+
+ do {
+
+ // Translate Pnor Section Id to Lid
+ auto l_lids = Util::getPnorSecLidIds(i_sec);
+ TRACFCOMP( g_trac_runtime, "PreVerifiedLidMgr::loadFromPnor - getPnorSecLidIds lid = 0x%X, containerLid = 0x%X",
+ l_lids.lid, l_lids.containerLid);
+ assert(l_lids.lid != Util::INVALID_LIDID,"Pnor Section = %s not associated with any Lids", PNOR::SectionIdToString(i_sec));
+
+ // Only load if not previously done.
+ if( isLidLoaded(l_lids.containerLid) && isLidLoaded(l_lids.lid) )
+ {
+ TRACFCOMP( g_trac_runtime, "PreVerifiedLidMgr::loadFromPnor - sec %s already loaded",
+ PNOR::SectionIdToString(i_sec));
+ break;
+ }
+
+ // Get next available HB resverved memory address
+ cv_pResvMemInfo->curAddr = getNextAddress(i_size);
+
+ // @TODO RTC:178163 remove need for l_loadImage
+ bool l_loadImage = false;
+ if(cv_payloadKind == TARGETING::PAYLOAD_KIND_PHYP)
+ {
+ // @TODO RTC:178163 enable when we can Load ALL pre-verfied lids
+ // There are checks in phyp for ANY hdat entry marked "RHB_TYPE_VERIFIED_LIDS"
+ // If there are any missing phyp will fail to boot.
+/*
+ l_loadImage = true;
+ // Verified Lid - Header Only
+ if ( (l_lids.containerLid != INVALID_LIDID) &&
+ !isLidLoaded(l_lids.containerLid))
+ {
+ char l_containerLidStr [Util::lidIdStrLength] {};
+ snprintf (l_containerLidStr, Util::lidIdStrLength, "%08X",
+ l_lids.containerLid);
+ l_errl = RUNTIME::setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_LIDS,
+ cv_pResvMemInfo->rangeId,
+ cv_pResvMemInfo->curAddr,
+ getAlignedSize(PAGE_SIZE),
+ l_containerLidStr);
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK"PreVerifiedLidMgr::loadFromPnor - setNextHbRsvMemEntry Lid header failed");
+ break;
+ }
+ }
+
+ // Verified Lid - Content Only
+ if ( (l_lids.lid != INVALID_LIDID) &&
+ !isLidLoaded(l_lids.lid))
+ {
+ char l_lidStr[Util::lidIdStrLength] {};
+ snprintf (l_lidStr, Util::lidIdStrLength, "%08X",l_lids.lid);
+ l_errl = RUNTIME::setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_LIDS,
+ cv_pResvMemInfo->rangeId,
+ cv_pResvMemInfo->curAddr+PAGE_SIZE,
+ getAlignedSize(i_size),
+ l_lidStr);
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK"PreVerifiedLidMgr::loadFromPnor - setNextHbRsvMemEntry Lid content failed");
+ break;
+ }
+ }
+*/
+ }
+ else if(cv_payloadKind == TARGETING::PAYLOAD_KIND_SAPPHIRE)
+ {
+ l_loadImage = true;
+ // Verified PNOR - Header + Content
+ l_errl = RUNTIME::setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_PNOR,
+ cv_pResvMemInfo->rangeId,
+ cv_pResvMemInfo->curAddr,
+ getAlignedSize(i_size),
+ PNOR::SectionIdToString(i_sec),
+ HDAT::RHB_READ_ONLY);
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK"PreVerifiedLidMgr::loadFromPnor - setNextHbRsvMemEntry PNOR content failed");
+ break;
+ }
+ }
+
+ if (l_loadImage)
+ {
+ // Load image into HB reserved memory
+ l_errl = loadImage(i_addr, i_size);
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK"PreVerifiedLidMgr::loadFromPnor - setNextHbRsvMemEntry PNOR content failed");
+ break;
+ }
+ }
+
+ // Indicate the full PNOR section has been loaded.
+ // Include both the header and content lids
+ cv_lidsLoaded.insert(std::make_pair(l_lids.containerLid, true));
+ cv_lidsLoaded.insert(std::make_pair(l_lids.lid, true));
+
+ } while(0);
+
+ TRACFCOMP( g_trac_runtime, EXIT_MRK"PreVerifiedLidMgr::_loadFromPnor");
+
+ mutex_unlock(&cv_loadImageMutex);
+
+ return l_errl;
+}
+
+/********************
+ Private/Protected Methods
+ ********************/
+
+PreVerifiedLidMgr& PreVerifiedLidMgr::getInstance()
+{
+ return Singleton<PreVerifiedLidMgr>::instance();
+}
+
+uint64_t PreVerifiedLidMgr::getAlignedSize(const size_t i_imgSize)
+{
+ return ALIGN_X(i_imgSize, HBRT_RSVD_MEM_OPAL_ALIGN);
+}
+
+uint64_t PreVerifiedLidMgr::getNextPhypAddress(const size_t i_prevSize)
+{
+ return cv_pResvMemInfo->curAddr + cv_pResvMemInfo->prevSize;
+}
+
+uint64_t PreVerifiedLidMgr::getNextOpalAddress(const size_t i_curSize)
+{
+ return cv_pResvMemInfo->curAddr - getAlignedSize(i_curSize);
+}
+
+bool PreVerifiedLidMgr::isLidLoaded(uint32_t i_lidId)
+{
+ bool l_loaded = false;
+
+ if (cv_lidsLoaded.count(i_lidId) > 0)
+ {
+ l_loaded = true;
+ }
+
+ return l_loaded;
+}
+
+errlHndl_t PreVerifiedLidMgr::loadImage(const uint64_t i_imgAddr,
+ const size_t i_imgSize)
+{
+ TRACFCOMP( g_trac_runtime, ENTER_MRK"PreVerifiedLidMgr::loadImage");
+
+ errlHndl_t l_errl = nullptr;
+
+ do {
+
+ uint64_t l_tmpVaddr = 0;
+ // Load the Verified image into HB resv memory
+ l_errl = RUNTIME::mapPhysAddr(cv_pResvMemInfo->curAddr, i_imgSize, l_tmpVaddr);
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK"PreVerifiedLidMgr::loadImage - mapPhysAddr failed");
+ break;
+ }
+
+ // Include Header page from pnor image.
+ memcpy(reinterpret_cast<void*>(l_tmpVaddr),
+ reinterpret_cast<void*>(i_imgAddr),
+ i_imgSize);
+
+ l_errl = RUNTIME::unmapVirtAddr(l_tmpVaddr);
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK"PreVerifiedLidMgr::loadImage - unmapVirtAddr failed");
+ break;
+ }
+
+ // Update previous size using aligned size for OPAL alignment even if that
+ // means there is some wasted space.
+ cv_pResvMemInfo->prevSize = getAlignedSize(i_imgSize);
+
+ } while(0);
+
+ TRACFCOMP( g_trac_runtime, EXIT_MRK"PreVerifiedLidMgr::loadImage");
+
+ return l_errl;
+} \ No newline at end of file
OpenPOWER on IntegriCloud