summaryrefslogtreecommitdiffstats
path: root/src/usr/util
diff options
context:
space:
mode:
authorStephen Cprek <smcprek@us.ibm.com>2017-09-22 15:40:05 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2017-11-01 16:17:32 -0400
commit6caab6132b05f6f97e8543d50633f1e29b3e4d84 (patch)
treebea06b53edb3a7d111d771fe825c0f73951b864c /src/usr/util
parent4f504a2eebeab64fa4bab9ca2bfddf2359a5522b (diff)
downloadtalos-hostboot-6caab6132b05f6f97e8543d50633f1e29b3e4d84.tar.gz
talos-hostboot-6caab6132b05f6f97e8543d50633f1e29b3e4d84.zip
Create Master Container Lid Manager and test parsing
Change-Id: I9cecf5bc44382f3aa60d7f86c964c9e01b9bc332 RTC: 125304 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/46713 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: Marshall J. Wilks <mjwilks@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/usr/util')
-rw-r--r--src/usr/util/makefile1
-rw-r--r--src/usr/util/test/testmclmgr.H240
-rw-r--r--src/usr/util/utilbase.H5
-rw-r--r--src/usr/util/utilmclmgr.C275
4 files changed, 520 insertions, 1 deletions
diff --git a/src/usr/util/makefile b/src/usr/util/makefile
index d0e4659cf..4eddf52f1 100644
--- a/src/usr/util/makefile
+++ b/src/usr/util/makefile
@@ -40,6 +40,7 @@ OBJS += utiltcemgr.o
OBJS += utilsemipersist.o
OBJS += utilrsvdmem.o
OBJS += utilxipimage.o
+OBJS += utilmclmgr.o
SUBDIRS += test.d
SUBDIRS += runtime.d
diff --git a/src/usr/util/test/testmclmgr.H b/src/usr/util/test/testmclmgr.H
new file mode 100644
index 000000000..d5ce9eec5
--- /dev/null
+++ b/src/usr/util/test/testmclmgr.H
@@ -0,0 +1,240 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/util/test/testmclmgr.H $ */
+/* */
+/* 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 */
+#ifndef _TESTMASTERCONTAINERLIDMGR_H
+#define _TESTMASTERCONTAINERLIDMGR_H
+
+
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <util/utilmclmgr.H>
+#include "../utilbase.H"
+#include <usr/vmmconst.h>
+
+namespace MCL
+{
+
+// Defines to simplify list initialzer syntax
+#define COMP_TEST1 {0x54,0x45,0x53,0x54,0x31}
+#define COMP_TEST2 {0x54,0x45,0x53,0x54,0x32}
+#define COMP_TEST3 {0x54,0x45,0x53,0x54,0x33}
+#define COMP_TEST4 {0x54,0x45,0x53,0x54,0x34}
+
+// Define deault vectors to simplify syntax
+const std::vector<uint32_t> defaultLids {0xA1234567, 0x89ABCDEF, 0x13579246};
+const std::vector<std::pair<ComponentID,bool> > defaultComps{
+ {COMP_TEST1,1} ,
+ {COMP_TEST2, 0} ,
+ {COMP_TEST3, 1},
+ {COMP_TEST4, 0}
+ };
+}
+
+using namespace MCL;
+
+class MasterContainerLidMgrTest : public CxxTest::TestSuite
+{
+public:
+
+ class TestMcl
+ {
+ public:
+
+ // Actual Size
+ size_t iv_size;
+
+ // Pointers to internal buffer
+ uint8_t* iv_bufferCur;
+ uint8_t* iv_bufferStart;
+
+ // Pointers within internal buffer to useful information
+ MclHeader* iv_pHeader;
+ std::vector<MclCompSection*> iv_compSections;
+
+ // Max Size of buffer
+ static const size_t iv_maxSize = 256;
+
+ // Comp Info Cache
+ CompInfoMap iv_compInfoCache;
+
+ // Vector of test lids
+ std::vector<uint32_t> iv_testLids;
+
+ // Vector of pairs for test components and if they are signed or not
+ std::vector<std::pair<ComponentID,bool> > iv_testComps;
+
+ TestMcl()
+ : iv_size(0),iv_bufferCur(nullptr),iv_bufferStart(nullptr),
+ iv_pHeader(nullptr), iv_compInfoCache{}, iv_testLids{defaultLids},
+ iv_testComps{defaultComps}
+ {
+ initMcl();
+ }
+
+ TestMcl(std::vector<uint32_t>& i_lids)
+ : iv_size(0),iv_bufferCur(nullptr),iv_bufferStart(nullptr),
+ iv_pHeader(nullptr), iv_compInfoCache{}, iv_testLids{i_lids},
+ iv_testComps{defaultComps}
+ {
+ initMcl();
+ }
+
+ TestMcl(std::vector<uint32_t>& i_lids,
+ std::vector<std::pair<ComponentID,bool> >& i_comps)
+ : iv_size(0),iv_bufferCur(nullptr),iv_bufferStart(nullptr),
+ iv_pHeader(nullptr), iv_compInfoCache{}, iv_testLids{i_lids},
+ iv_testComps{i_comps}
+ {
+ initMcl();
+ }
+
+ void initMcl()
+ {
+ // Note: () zero initializes
+ iv_bufferStart = new uint8_t[iv_maxSize]();
+ iv_bufferCur = iv_bufferStart;
+ genMcl();
+ genCompInfoCache();
+ }
+
+
+ ~TestMcl()
+ {
+ delete[] iv_bufferStart;
+ iv_bufferStart = nullptr;
+ }
+
+ void genMcl()
+ {
+ // Handle MCL Header
+ auto l_pMclHdrSec = reinterpret_cast<MclHeader*>(iv_bufferCur);
+ l_pMclHdrSec->version = 0xDEADBEEF;
+ l_pMclHdrSec->offsetToCompSection = sizeof(MclHeader);
+ l_pMclHdrSec->numComponents = iv_testComps.size();
+
+ // Store MCL header pointer for reference
+ iv_pHeader = l_pMclHdrSec;
+
+ // Increment member variables
+ iv_bufferCur += l_pMclHdrSec->offsetToCompSection;
+ iv_size += l_pMclHdrSec->offsetToCompSection;
+ // Assert we have not surpased max buffer size
+ assert(iv_size <= iv_maxSize, "TestMcl internal buffer ran out of space");
+
+ // Get size of of all lid ids
+ auto l_lidsSize = sizeof(uint32_t) * iv_testLids.size();
+
+ // Handle MCL Component Sections
+ for (auto compPair : iv_testComps)
+ {
+ auto comp = compPair.first;
+ auto secure = compPair.second;
+
+ // Assert we have enough room for next component
+ assert( (iv_size + sizeof(MclCompSection) + l_lidsSize) <= iv_maxSize, "TestMcl internal buffer ran out of space");
+
+ auto l_pMclCompSec = reinterpret_cast<MclCompSection*>(iv_bufferCur);
+ memcpy(l_pMclCompSec->compId.data(), &comp, sizeof(ComponentID));
+ l_pMclCompSec->sizeCompList = sizeof(MclCompSection) +
+ l_lidsSize;
+ l_pMclCompSec->numLids = iv_testLids.size();
+ if (secure)
+ {
+ l_pMclCompSec->flags = CompFlags::SIGNED_PRE_VERIFY;
+ }
+ else
+ {
+ l_pMclCompSec->flags = CompFlags::UNSIGNED;
+ }
+ memcpy(&l_pMclCompSec->lidArray, iv_testLids.data(), l_lidsSize);
+
+ // Pad to MclCompSectionPadSize byte boundary
+ auto l_padMod = l_pMclCompSec->sizeCompList %
+ MclCompSectionPadSize;
+ if (l_padMod)
+ {
+ auto l_padSize = MclCompSectionPadSize - l_padMod;
+ auto l_end = reinterpret_cast<uint8_t*>(l_pMclCompSec) +
+ l_pMclCompSec->sizeCompList;
+ memset(l_end, 0, l_padSize);
+ l_pMclCompSec->sizeCompList += l_padSize;
+ }
+
+ // Store comp sections for reference
+ iv_compSections.push_back(l_pMclCompSec);
+
+ // Increment member variables
+ iv_bufferCur += l_pMclCompSec->sizeCompList;
+ iv_size += l_pMclCompSec->sizeCompList;
+ // Assert we have not surpased max buffer size
+ assert(iv_size <= iv_maxSize, "TestMcl internal buffer ran out of space");
+ }
+ }
+
+ void genCompInfoCache()
+ {
+ // Add MCL itself to Cache
+ CompInfo l_compHdrInfo(CompFlags::SIGNED_PRE_VERIFY);
+ l_compHdrInfo.lidIds.push_back(Util::MCL_LIDID);
+ iv_compInfoCache.insert(std::make_pair(g_MclCompId, l_compHdrInfo));
+
+ // Add all components in MCL to cache
+ for ( const auto comp : iv_compSections)
+ {
+ CompInfo l_compInfo(comp->flags);
+ auto * l_pId = comp->lidArray;
+ for (uint8_t i = 0; i < comp->numLids; ++i)
+ {
+ l_compInfo.lidIds.push_back(*l_pId);
+ l_pId++;
+ }
+ iv_compInfoCache.insert(std::make_pair(comp->compId, l_compInfo));
+ }
+ }
+ };
+
+ /**
+ * @brief Test that MCL manager properly parses a MCL
+ */
+ void testMCLparser(void)
+ {
+ UTIL_FT(ENTER_MRK"testMCLparser start" );
+ // Generate test MCL
+ TestMcl l_TestMcl{};
+
+ // Pass test MCL to MCL manager
+ MasterContainerLidMgr l_mcl(l_TestMcl.iv_bufferStart,
+ l_TestMcl.iv_size);
+
+ // Ensure the Comp Info Caches match
+ if (l_TestMcl.iv_compInfoCache != l_mcl.iv_compInfoCache)
+ {
+ TS_FAIL("testMCLparser> Comp Info Caches do not match");
+ }
+
+ UTIL_FT(EXIT_MRK"testMCLparser complete");
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/src/usr/util/utilbase.H b/src/usr/util/utilbase.H
index bef9e88d2..42a30032f 100644
--- a/src/usr/util/utilbase.H
+++ b/src/usr/util/utilbase.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,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. */
@@ -33,6 +35,7 @@ namespace Util
#define UTIL_DT(...) TRACDCOMP( Util::g_util_trace, __VA_ARGS__ )
#define UTIL_FT(...) TRACFCOMP( Util::g_util_trace, __VA_ARGS__ )
+#define UTIL_FBIN(...) TRACFBIN( Util::g_util_trace, __VA_ARGS__ )
#define UTIL_BOOL_ALPHA(x) ((x) ? "TRUE" : "FALSE")
diff --git a/src/usr/util/utilmclmgr.C b/src/usr/util/utilmclmgr.C
new file mode 100644
index 000000000..a3f9077ff
--- /dev/null
+++ b/src/usr/util/utilmclmgr.C
@@ -0,0 +1,275 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/util/utilmclmgr.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 <util/utilmclmgr.H>
+#include <util/utillidmgr.H>
+#include <util/util_reasoncodes.H>
+#include "utilbase.H"
+#include <sys/mm.h>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <initservice/initserviceif.H>
+
+namespace MCL
+{
+
+const size_t MclCompSectionPadSize = 16;
+
+// Defines to simplify list initialzer syntax
+#define COMP_MSTCONT {0x4d,0x53,0x54,0x43,0x4f,0x4e,0x54}
+#define COMP_POWERVM {0x50,0x4f,0x57,0x45,0x52,0x56,0x4d}
+const ComponentID g_MclCompId = COMP_MSTCONT;
+const ComponentID g_PowervmCompId = COMP_POWERVM;
+
+////////////////////////////////////////////////////////////////////////////////
+// CompInfo
+////////////////////////////////////////////////////////////////////////////////
+
+void CompInfo::print() const
+{
+ UTIL_FT(" - Flags: 0x%04X", flags);
+ UTIL_FT(" - Mainstore Addr: 0x%llX", mainstoreAddr);
+ UTIL_FT(" - Total Size: 0x%llX", totalSize);
+ UTIL_FT(" - Protected Size: 0x%llX", protectedSize);
+ UTIL_FT(" - Unprotected Size: 0x%llX", unprotectedSize);
+ UTIL_FT(" - LidIds:");
+ for (auto lidInfo : lidIds)
+ {
+ UTIL_FT(" - 0x%08X, size 0x%X", lidInfo.id, lidInfo.size);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// MasterContainerLidMgr
+////////////////////////////////////////////////////////////////////////////////
+
+MasterContainerLidMgr::MasterContainerLidMgr()
+: iv_mclAddr(MCL_ADDR), iv_mclSize(MCL_SIZE), iv_tmpAddr(MCL_TMP_ADDR),
+ iv_tmpSize(MCL_TMP_SIZE), iv_pMclVaddr(nullptr), iv_pTempVaddr(nullptr),
+ iv_compInfoCache{}
+{
+ initMcl();
+}
+
+MasterContainerLidMgr::MasterContainerLidMgr(const void* i_pMcl,
+ const size_t i_size)
+: iv_mclAddr(MCL_ADDR), iv_mclSize(MCL_SIZE), iv_tmpAddr(MCL_TMP_ADDR),
+ iv_tmpSize(MCL_TMP_SIZE), iv_pMclVaddr(nullptr), iv_pTempVaddr(nullptr),
+ iv_compInfoCache{}
+{
+ initMcl(i_pMcl, i_size);
+}
+
+MasterContainerLidMgr::~MasterContainerLidMgr()
+{
+ // Release all address spaces
+ releaseMem(iv_tmpAddr, iv_pTempVaddr);
+}
+
+void MasterContainerLidMgr::initMcl(const void* i_pMcl, const size_t i_mclSize)
+{
+ UTIL_FT(ENTER_MRK"MasterContainerLidMgr::initMcl");
+
+ // Add MCL itself to Cache but don't add to comp order
+ CompInfo l_compHdrInfo(CompFlags::SIGNED_PRE_VERIFY);
+ LidInfo l_hdrLidInfo(Util::MCL_LIDID);
+ l_compHdrInfo.lidIds.push_back(l_hdrLidInfo);
+ iv_compInfoCache.insert(std::make_pair(g_MclCompId, l_compHdrInfo));
+
+ // Initialize MCL address space
+ initMem(iv_mclAddr, iv_mclSize, iv_pMclVaddr);
+
+ if(i_pMcl != nullptr)
+ {
+ // set cached MCL pointer with custom MCL
+ memcpy(iv_pMclVaddr, i_pMcl, i_mclSize);
+ }
+ else
+ {
+ // Load Lid
+ }
+
+ // Parse all Components in MCL
+ parseMcl();
+
+ // Initialize temporary space for processing lids
+ initMem(iv_tmpAddr, iv_tmpSize, iv_pTempVaddr);
+
+ UTIL_FT(EXIT_MRK"MasterContainerLidMgr::initMcl");
+}
+
+void MasterContainerLidMgr::releaseMem(const uint64_t i_physAddr,
+ void *&io_pVaddr)
+{
+ UTIL_FT(ENTER_MRK"MasterContainerLidMgr::releaseMem");
+
+ errlHndl_t l_errl = nullptr;
+ assert(i_physAddr != 0, "MasterContainerLidMgr physical address to release cannot be 0");
+
+ do {
+ if ( io_pVaddr != nullptr)
+ {
+ int l_mm_rc = mm_block_unmap(io_pVaddr);
+ if(l_mm_rc != 0)
+ {
+ UTIL_FT("Fail from mm_block_unmap for Mcl Mgr, rc=%d Addr 0x%.16llX",
+ l_mm_rc, i_physAddr);
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_MCL_REL_MEM
+ * @reasoncode Util::UTIL_MM_BLOCK_UNMAP_FAILED
+ * @userdata1 Address being removed
+ * @userdata2 rc from mm_block_unmap
+ * @devdesc Error calling mm_block_unmap for Mcl Mgr
+ * @custdesc Firmware Error
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_MCL_REL_MEM,
+ Util::UTIL_MM_BLOCK_UNMAP_FAILED,
+ i_physAddr,
+ l_mm_rc,
+ true); //software callout
+ l_errl->collectTrace(UTIL_COMP_NAME);
+ break;
+ }
+ io_pVaddr = nullptr;
+ }
+ } while(0);
+
+ if (l_errl)
+ {
+ uint64_t l_reasonCode = l_errl->reasonCode();
+ errlCommit(l_errl,UTIL_COMP_ID);
+ INITSERVICE::doShutdown(l_reasonCode);
+ }
+
+ UTIL_FT(EXIT_MRK"MasterContainerLidMgr::releaseMem");
+}
+
+void MasterContainerLidMgr::initMem(const uint64_t i_physAddr,
+ const size_t i_size,
+ void *&io_pVaddr)
+{
+ UTIL_FT(ENTER_MRK"MasterContainerLidMgr::initMem");
+
+ errlHndl_t l_errl = nullptr;
+ assert(i_physAddr != 0, "MasterContainerLidMgr physical address cannot be 0");
+
+ do {
+ //Check if we already initialized vm space
+ if (io_pVaddr == nullptr)
+ {
+ io_pVaddr = mm_block_map(reinterpret_cast<void*>(i_physAddr), i_size);
+ if(io_pVaddr == nullptr)
+ {
+ UTIL_FT("MasterContainerLidMgr::initMem mm_block_map failed for Addr 0x%.16llX and size=0x%X ",
+ i_physAddr, i_size);
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_MCL_INIT_MEM
+ * @reasoncode Util::UTIL_MM_BLOCK_MAP_FAILED
+ * @userdata1 Address being allocated
+ * @userdata2 Size of block allocation
+ * @devdesc Error calling mm_block_map for Mcl Mgr
+ * @custdesc Firmware Error
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_MCL_INIT_MEM,
+ Util::UTIL_MM_BLOCK_MAP_FAILED,
+ i_physAddr,
+ i_size,
+ true); //software callout
+ l_errl->collectTrace(UTIL_COMP_NAME);
+ break;
+ }
+ memset(io_pVaddr, 0, i_size);
+ }
+ } while(0);
+
+ if (l_errl)
+ {
+ uint64_t l_reasonCode = l_errl->reasonCode();
+ errlCommit(l_errl,UTIL_COMP_ID);
+ INITSERVICE::doShutdown(l_reasonCode);
+ }
+
+ UTIL_FT(EXIT_MRK"MasterContainerLidMgr::initMem");
+}
+
+void MasterContainerLidMgr::parseMcl()
+{
+ UTIL_FT(ENTER_MRK"MasterContainerLidMgr::parseMcl");
+
+ assert(iv_pMclVaddr != nullptr);
+
+ auto l_pMcl = reinterpret_cast<const uint8_t*>(iv_pMclVaddr);
+
+ // Parse MCL header
+ auto l_pMclHdr = reinterpret_cast<const MclHeader*>(l_pMcl);
+ uint8_t l_totalComponents = l_pMclHdr->numComponents;
+ uint32_t l_offsetToCompSection = l_pMclHdr->offsetToCompSection;
+ l_pMcl += l_offsetToCompSection;
+
+ // Parse Each Component in MCL header
+ for (uint8_t comp = 0; comp < l_totalComponents; ++comp)
+ {
+ auto l_pMclSec = reinterpret_cast<const MclCompSection*>(l_pMcl);
+
+ // Construct Comp Info with a subset of information
+ CompInfo l_compInfo (l_pMclSec->flags);
+
+ // Parse all lids
+ auto l_pId = l_pMclSec->lidArray;
+ for (uint8_t lid = 0; lid < l_pMclSec->numLids; ++lid)
+ {
+ LidInfo l_lidInfo(*l_pId);
+ l_compInfo.lidIds.push_back(l_lidInfo);
+ l_pId++;
+ }
+
+ // Insert component into Comp Info Cache
+ iv_compInfoCache.insert(std::make_pair(l_pMclSec->compId, l_compInfo));
+
+ // Increment past current component
+ l_pMcl += l_pMclSec->sizeCompList;
+ }
+
+ printCompInfoCache();
+
+ UTIL_FT(EXIT_MRK"MasterContainerLidMgr::parseMcl");
+}
+
+void MasterContainerLidMgr::printCompInfoCache()
+{
+ UTIL_FT("> MCL Comp Info cache:");
+ for (const auto &i : iv_compInfoCache)
+ {
+ UTIL_FBIN("- Comp Id:", &i.first, sizeof(ComponentID));
+ i.second.print();
+ }
+}
+
+} // end namespace MCL
OpenPOWER on IntegriCloud