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/usr/util | |
parent | 4f504a2eebeab64fa4bab9ca2bfddf2359a5522b (diff) | |
download | talos-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/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 |
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 |