diff options
| author | Stephen Cprek <smcprek@us.ibm.com> | 2017-09-22 15:40:05 -0500 |
|---|---|---|
| committer | William G. Hoffa <wghoffa@us.ibm.com> | 2017-11-01 16:17:32 -0400 |
| commit | 6caab6132b05f6f97e8543d50633f1e29b3e4d84 (patch) | |
| tree | bea06b53edb3a7d111d771fe825c0f73951b864c /src | |
| parent | 4f504a2eebeab64fa4bab9ca2bfddf2359a5522b (diff) | |
| download | blackbird-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.H | 40 | ||||
| -rw-r--r-- | src/include/usr/util/utillidmgr.H | 1 | ||||
| -rw-r--r-- | src/include/usr/util/utilmclmgr.H | 310 | ||||
| -rw-r--r-- | src/include/usr/vmmconst.h | 15 | ||||
| -rw-r--r-- | src/usr/util/makefile | 1 | ||||
| -rw-r--r-- | src/usr/util/test/testmclmgr.H | 240 | ||||
| -rw-r--r-- | src/usr/util/utilbase.H | 5 | ||||
| -rw-r--r-- | src/usr/util/utilmclmgr.C | 275 |
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 |

