summaryrefslogtreecommitdiffstats
path: root/src
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
parent4f504a2eebeab64fa4bab9ca2bfddf2359a5522b (diff)
downloadblackbird-hostboot-6caab6132b05f6f97e8543d50633f1e29b3e4d84.tar.gz
blackbird-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')
-rw-r--r--src/include/usr/util/util_reasoncodes.H40
-rw-r--r--src/include/usr/util/utillidmgr.H1
-rw-r--r--src/include/usr/util/utilmclmgr.H310
-rw-r--r--src/include/usr/vmmconst.h15
-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
8 files changed, 866 insertions, 21 deletions
diff --git a/src/include/usr/util/util_reasoncodes.H b/src/include/usr/util/util_reasoncodes.H
index 4b9c5c308..f90784c77 100644
--- a/src/include/usr/util/util_reasoncodes.H
+++ b/src/include/usr/util/util_reasoncodes.H
@@ -47,32 +47,36 @@ namespace Util
UTIL_TCE_DISABLE_TCES = 0x0D, // Util::UTIL_TCE_DISABLE_TCES
UTIL_TCE_MAP_PSIHB = 0x0E, // UtilTceMgr::mapPsiHostBridge
UTIL_TCE_UNMAP_PSIHB = 0x0F, // UtilTceMgr::unmapPsiHostBridge
+ UTIL_MCL_INIT_MEM = 0x10, // MasterContainerLidMgr::initMem
+ UTIL_MCL_REL_MEM = 0x11, // MasterContainerLidMgr::releaseMem
};
enum ReasonCode
{
- UTIL_ERC_NONE = UTIL_COMP_ID | 0x01,
- UTIL_ERC_BAD_PTR = UTIL_COMP_ID | 0x02,
- UTIL_ERC_EOF = UTIL_COMP_ID | 0x03,
- UTIL_LIDMGR_RC_FAIL = UTIL_COMP_ID | 0x04,
- UTIL_LIDMGR_INVAL_DATA = UTIL_COMP_ID | 0x05,
- UTIL_LIDMGR_INVAL_SIZE = UTIL_COMP_ID | 0x06,
- UTIL_LIDMGR_UNSUP_MSG = UTIL_COMP_ID | 0x07,
- UTIL_LIDMGR_INVAL_SIZE_PNOR = UTIL_COMP_ID | 0x08,
- UTIL_LIDMGR_UNLOAD_RC_FAIL = UTIL_COMP_ID | 0x09,
- UTIL_LIDMGR_NOT_FOUND = UTIL_COMP_ID | 0x0A,
- UTIL_LIDMGR_MM_FAIL = UTIL_COMP_ID | 0x0B,
- UTIL_TCE_INVALID_SIZE = UTIL_COMP_ID | 0x0C,
- UTIL_TCE_ADDR_NOT_ALIGNED = UTIL_COMP_ID | 0x0D,
- UTIL_TCE_DEV_MAP_FAIL = UTIL_COMP_ID | 0x0E,
- UTIL_TCE_DEV_UNMAP_FAIL = UTIL_COMP_ID | 0x0F,
+ UTIL_ERC_NONE = UTIL_COMP_ID | 0x01,
+ UTIL_ERC_BAD_PTR = UTIL_COMP_ID | 0x02,
+ UTIL_ERC_EOF = UTIL_COMP_ID | 0x03,
+ UTIL_LIDMGR_RC_FAIL = UTIL_COMP_ID | 0x04,
+ UTIL_LIDMGR_INVAL_DATA = UTIL_COMP_ID | 0x05,
+ UTIL_LIDMGR_INVAL_SIZE = UTIL_COMP_ID | 0x06,
+ UTIL_LIDMGR_UNSUP_MSG = UTIL_COMP_ID | 0x07,
+ UTIL_LIDMGR_INVAL_SIZE_PNOR = UTIL_COMP_ID | 0x08,
+ UTIL_LIDMGR_UNLOAD_RC_FAIL = UTIL_COMP_ID | 0x09,
+ UTIL_LIDMGR_NOT_FOUND = UTIL_COMP_ID | 0x0A,
+ UTIL_LIDMGR_MM_FAIL = UTIL_COMP_ID | 0x0B,
+ UTIL_TCE_INVALID_SIZE = UTIL_COMP_ID | 0x0C,
+ UTIL_TCE_ADDR_NOT_ALIGNED = UTIL_COMP_ID | 0x0D,
+ UTIL_TCE_DEV_MAP_FAIL = UTIL_COMP_ID | 0x0E,
+ UTIL_TCE_DEV_UNMAP_FAIL = UTIL_COMP_ID | 0x0F,
UTIL_TCE_NOT_ENOUGH_FREE_ENTRIES = UTIL_COMP_ID | 0x10,
UTIL_TCE_ENTRY_NOT_CONTIGUOUS = UTIL_COMP_ID | 0x11,
UTIL_TCE_PREVIOUSLY_ALLOCATED = UTIL_COMP_ID | 0x12,
- UTIL_TCE_INVALID_COUNT = UTIL_COMP_ID | 0x13,
- UTIL_TCE_ALLOC_BLOCK_FAIL = UTIL_COMP_ID | 0x14,
- UTIL_TCE_BLOCK_UNMAP_FAIL = UTIL_COMP_ID | 0x15,
+ UTIL_TCE_INVALID_COUNT = UTIL_COMP_ID | 0x13,
+ UTIL_TCE_ALLOC_BLOCK_FAIL = UTIL_COMP_ID | 0x14,
+ UTIL_TCE_BLOCK_UNMAP_FAIL = UTIL_COMP_ID | 0x15,
+ UTIL_MM_BLOCK_MAP_FAILED = UTIL_COMP_ID | 0x16,
+ UTIL_MM_BLOCK_UNMAP_FAILED = UTIL_COMP_ID | 0x17,
};
};
diff --git a/src/include/usr/util/utillidmgr.H b/src/include/usr/util/utillidmgr.H
index cda762f66..725e51671 100644
--- a/src/include/usr/util/utillidmgr.H
+++ b/src/include/usr/util/utillidmgr.H
@@ -50,6 +50,7 @@ enum LidId
TEST_LIDID = 0x00000111,
OCC_LIDID = 0x81e00430,
OCC_CONTAINER_LIDID = 0x80d0000b,
+ MCL_LIDID = 0x80D00020,
// TODO RTC 172767 Make utillidmgr LIDID structure attribute driven
WOF_LIDID = 0x81e00440,
WOF_CONTAINER_LIDID = 0x80d00015,
diff --git a/src/include/usr/util/utilmclmgr.H b/src/include/usr/util/utilmclmgr.H
new file mode 100644
index 000000000..58a73bae4
--- /dev/null
+++ b/src/include/usr/util/utilmclmgr.H
@@ -0,0 +1,310 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/util/utilmclmgr.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 __MASTERCONTAINERLIDMGR_H
+#define __MASTERCONTAINERLIDMGR_H
+
+#include <vector>
+#include <map>
+#include <secureboot/containerheader.H>
+#include <errl/errlentry.H>
+#include <usr/vmmconst.h>
+
+// Forward declarations
+class MasterContainerLidMgrTest;
+
+namespace MCL
+{
+
+// Component ID(name) within MCL
+typedef std::array<uint8_t,16> ComponentID;
+
+// Defines to simplify syntax when checking for the MCL and POWERVM comp ids
+extern const ComponentID g_MclCompId;
+extern const ComponentID g_PowervmCompId;
+
+// @enum Permission Types for MCL Component
+enum class CompFlags : uint16_t
+{
+ UNSIGNED = 0x0000,
+ SIGNED = 0x8000,
+ PRE_VERIFY = 0x4000,
+ SIGNED_PRE_VERIFY = SIGNED|PRE_VERIFY,
+};
+
+/**
+ * @brief Comp Flags logical AND overload
+ *
+ * @param[in] lhs - CompFlags to compare to
+ * @param[in] rhs - CompFlags to compare to
+ *
+ * @return CompFlags - The result of logically AND'ing two CompFlags
+ */
+inline CompFlags operator&(const CompFlags &lhs, const CompFlags &rhs)
+{
+ return static_cast<CompFlags>(
+ static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs)
+ );
+}
+
+/**
+ * @brief Comp Flags logical OR overload
+ *
+ * @param[in] lhs - CompFlags to compare to
+ * @param[in] rhs - CompFlags to compare to
+ *
+ * @return CompFlags - The result of logically OR'ing two CompFlags
+ */
+inline CompFlags operator|(const CompFlags &lhs, const CompFlags &rhs)
+{
+ return static_cast<CompFlags>(
+ static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs)
+ );
+}
+
+// MCL header section
+struct MclHeader
+{
+ uint32_t version;
+ uint32_t offsetToCompSection;
+ uint8_t numComponents;
+ uint8_t reserved[7];
+} __attribute__ ((packed));
+
+// Structure for each component within the MCL
+struct MclCompSection
+{
+ ComponentID compId;
+ uint32_t sizeCompList;
+ uint32_t numLids;
+ CompFlags flags;
+ uint8_t reserved[6];
+ // Array size determined by numLids
+ uint32_t lidArray[];
+ //padding to 16 byte boundary
+} __attribute__ ((packed));
+
+// Padded size for MCL components
+extern const size_t MclCompSectionPadSize;
+
+// @brief Structure that holds lid ids and sizes
+struct LidInfo
+{
+ LidInfo(): id(0), size(0) {}
+ LidInfo(uint32_t i_id): id(i_id), size(0) {}
+ LidInfo(uint32_t i_id, size_t i_size): id(i_id), size(i_size) {}
+
+ uint32_t id;
+ size_t size;
+
+ /**
+ * @brief Lid Info equality comparison
+ *
+ * @param[in] rhs - LidInfo to compare to
+ * @return bool - true if Lid Infos are equal, false otherwise
+ */
+ bool operator==(const LidInfo& rhs) const
+ {
+ return (id == rhs.id && size == rhs.size);
+ }
+
+ /**
+ * @brief Lid Info inequality comparison
+ *
+ * @param[in] rhs - LidInfo to compare to
+ * @return bool - true if Lid Infos are not equal, false otherwise
+ */
+ bool operator!=(const LidInfo& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+};
+
+// @brief Structure that holds information on each component in the MCL
+struct CompInfo
+{
+ CompFlags flags;
+ uint64_t mainstoreAddr;
+ size_t totalSize;
+ size_t protectedSize;
+ size_t unprotectedSize;
+ std::vector<LidInfo> lidIds;
+
+ // Constructors
+ CompInfo()
+ : flags(CompFlags::UNSIGNED), mainstoreAddr(0), totalSize(0),
+ protectedSize(0), unprotectedSize(0), lidIds{} {}
+ CompInfo(CompFlags i_flags)
+ : flags(i_flags), mainstoreAddr(0), totalSize(0), protectedSize(0),
+ unprotectedSize(0), lidIds{} {}
+
+ /**
+ * @brief Comp Info equality comparison
+ *
+ * @param[in] rhs - CompInfo to compare to
+ * @return bool - true if Comp Infos are equal, false otherwise
+ */
+ bool operator==(const CompInfo& rhs) const
+ {
+ return (flags == rhs.flags &&
+ mainstoreAddr == rhs.mainstoreAddr &&
+ totalSize == rhs.totalSize &&
+ protectedSize == rhs.protectedSize &&
+ unprotectedSize == rhs.unprotectedSize &&
+ lidIds == rhs.lidIds);
+ }
+
+ /**
+ * @brief Comp Info inequality comparison
+ *
+ * @param[in] rhs - CompInfo to compare to
+ * @return bool - true if Comp Infos are not equal, false otherwise
+ */
+ bool operator!=(const CompInfo& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ /**
+ * @brief Print Comp Info in human friendly format
+ * @return N/A
+ */
+ void print() const;
+};
+
+// Structure for Comp Info cache
+typedef std::map<ComponentID, CompInfo> CompInfoMap;
+
+// @brief Class to manager the Master Container Lid provided by the FSP
+class MasterContainerLidMgr
+{
+
+ public:
+
+ /**
+ * @brief Default Constructor
+ * Initializes memory spaces, loads, and parses the MCL.
+ */
+ MasterContainerLidMgr();
+
+ /**
+ * @brief Destructor. Cleans up memory allocated for class
+ */
+ ~MasterContainerLidMgr();
+
+ protected:
+
+ /**
+ * @brief Custom Constructor.
+ * Same as default cstor, but passes in a custom MCL
+ * NOTE: protected cstor to be used by test cases only
+ * nullptr indicates to load from UtilLidMgr
+ * @param[in] i_pMcl - pointer to custom MCL
+ * @param[in] i_size - size of custom MCL
+ */
+ MasterContainerLidMgr(const void* i_pMcl,
+ const size_t i_size);
+
+ private:
+
+ /**
+ * @brief Common function for all constructors to call to initialize the MCL
+ *
+ * @param[in] i_pMcl - Pointer to custom MCL if provided
+ * NOTE: nullptr indicates to load from UtilLidMgr
+ * @param[in] i_pMcl - Size of Custom MCL
+ *
+ * @return N/A
+ */
+ void initMcl(const void* i_pMcl = nullptr, const size_t i_mclSize = 0);
+
+ /**
+ * @brief Responsible for allocating space for MCL mgr component parsing
+ * NOTE: Will shutdown if error occurs
+ *
+ * @param[in] i_physAddr - Starting physical address to initialize memory
+ * @param[in] i_size - Size to allocate
+ * @param[in/out] io_pVaddr - Pointer to store virtual address pointer from
+ * block map
+ * NOTE: no-op unless the pointer is a nullptr
+ *
+ * @return N/A
+ */
+ void initMem(const uint64_t i_physAddr, const size_t i_size,
+ void *&io_pVaddr);
+
+ /**
+ * @brief Responsible for deallocating space used by MCL component parsing
+ * NOTE: Will shutdown if error occurs
+ *
+ * @param[in] i_physAddr - Starting physical address to deallocate from
+ * @param[in/out] io_pVaddr - Pointer to virtual memory to release
+ * NOTE: no-op if the pointer is nullptr
+ *
+ * @return N/A
+ */
+ void releaseMem(const uint64_t i_physAddr, void *&io_pVaddr);
+
+ /**
+ * @brief Parse MCL and store important information in Comp Info Cache
+ * Will also print out Comp Info Cache
+ * @return N/A
+ */
+ void parseMcl();
+
+ /**
+ * @brief Print MCL Comp Info Cache in human friendly format
+ * @return N/A
+ */
+ void printCompInfoCache();
+
+ // Physical addresses reserved for the MCL itself
+ uint64_t iv_mclAddr;
+
+ // Maximum size of memory for the MCL itself
+ size_t iv_mclSize;
+
+ // Physical addresses reserved for temp MCL mgr space
+ uint64_t iv_tmpAddr;
+
+ // Maximum size of memory for temp MCL mgr workspace
+ size_t iv_tmpSize;
+
+ // Pointer to MCL virtual address space
+ void* iv_pMclVaddr;
+
+ // Pointer to MCL temp virtual address space
+ void* iv_pTempVaddr;
+
+ // Cache Components and their corresponding lids
+ CompInfoMap iv_compInfoCache;
+
+ // Allow test cases to call custom constructors and have direct access
+ friend class ::MasterContainerLidMgrTest;
+};
+
+} // end namespace MCL
+
+#endif \ No newline at end of file
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index a08ba05c5..ed773da09 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -208,7 +208,6 @@ enum BlockPriority
*/
#define VMM_INTERNODE_PRESERVED_MEMORY_ADDR (96 * MEGABYTE)
-
/**
* Test Constants
*/
@@ -236,8 +235,20 @@ enum BlockPriority
#define UNSECURE_MEM_REGION_SIZE_TEST (1*KILOBYTE)
+/** Two memory locations for MCL processing **/
+// Note: 2 spaces needed so the MCL can be initialized without wiping out PHYP
+// Location for the MCL itself to sit in.
+#define MCL_ADDR (20*MEGABYTE)
+#define MCL_SIZE (16*KILOBYTE)
+// Location for PHYP to be loaded into and reused for all Master Container Lids
+// Verification is done in the temp space and then loaded into mainstore memory
+#define MCL_TMP_ADDR (MCL_ADDR + MCL_SIZE)
+#define MCL_TMP_SIZE ( (64 * MEGABYTE) + PAGESIZE )
+
/** PreVerifiedLidMgr test space */
-#define PREVERLIDMGR_TEST_ADDR (364*MEGABYTE)
+#define PREVERLIDMGR_TEST_ADDR (512*MEGABYTE)
#define PREVERLIDMGR_TEST_SIZE (64*MEGABYTE)
+
+
#endif /* _VMMCONST_H */
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