diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2019-02-13 20:06:06 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2019-02-18 21:19:21 -0600 |
commit | b61b4966edc3812a3c1a5f89dd571de832e06e2d (patch) | |
tree | 66c143f8d7f9869d85ca34bbc22e40d04d74e9cf /src | |
parent | 02f33294dea55eb2f022336f2b4871ea87ef7720 (diff) | |
download | talos-hostboot-b61b4966edc3812a3c1a5f89dd571de832e06e2d.tar.gz talos-hostboot-b61b4966edc3812a3c1a5f89dd571de832e06e2d.zip |
Support reading UCD flash update LIDs
- Added support to read a single LID container and securely verify it
- Added new compile flag CONFIG_UCD_FLASH_UPDATES to enable/disable
future TI UCD9090/UCD90120A flash updates
- Created shell function to hold the UCD flash update logic
Change-Id: I94f3e43558af5d7951febdf6ff0685c120d2db0e
RTC: 201992
CMVC-Prereq: 1076388
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/71945
Reviewed-by: Marshall J. Wilks <mjwilks@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/build/configs/fsprelease.config | 1 | ||||
-rw-r--r-- | src/include/usr/util/util_reasoncodes.H | 4 | ||||
-rw-r--r-- | src/include/usr/util/utilmclmgr.H | 79 | ||||
-rw-r--r-- | src/usr/isteps/istep21/call_host_runtime_setup.C | 11 | ||||
-rw-r--r-- | src/usr/isteps/istep21/call_update_ucd_flash.C | 101 | ||||
-rw-r--r-- | src/usr/isteps/istep21/call_update_ucd_flash.H | 49 | ||||
-rw-r--r-- | src/usr/isteps/istep21/makefile | 3 | ||||
-rw-r--r-- | src/usr/isteps/ucd/HBconfig | 4 | ||||
-rw-r--r-- | src/usr/util/utilmclmgr.C | 99 |
9 files changed, 327 insertions, 24 deletions
diff --git a/src/build/configs/fsprelease.config b/src/build/configs/fsprelease.config index ebebfdf50..43e779520 100644 --- a/src/build/configs/fsprelease.config +++ b/src/build/configs/fsprelease.config @@ -15,6 +15,7 @@ set FSP_BUILD set NVDIMM set CONFIG_NVDIMM +set UCD_FLASH_UPDATES # OpenPower checkstop analysis unset ENABLE_CHECKSTOP_ANALYSIS diff --git a/src/include/usr/util/util_reasoncodes.H b/src/include/usr/util/util_reasoncodes.H index 587943bdd..17ea0edfc 100644 --- a/src/include/usr/util/util_reasoncodes.H +++ b/src/include/usr/util/util_reasoncodes.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* Contributors Listed Below - COPYRIGHT 2012,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -52,6 +52,7 @@ namespace Util UTIL_MCL_PROCESS_COMP = 0x12, // MasterContainerLidMgr::processComponent UTIL_MOD_GET_OBUS_PLL_BUCKET = 0x14, // UtilCommonAttr::getObusPllBucket UTIL_LIDMGR_CSTOR = 0x15, // UtilLidMgr::UtilLidMgr + UTIL_MCL_PROCESS_SINGLE_COMP = 0x16, // UtilLidMgr::processSingleComponent }; enum ReasonCode @@ -83,6 +84,7 @@ namespace Util UTIL_ERC_NO_FREQ_LIST = UTIL_COMP_ID | 0x1A, UTIL_ERC_NO_MATCHING_FREQ = UTIL_COMP_ID | 0x1B, UTIL_LIDMGR_INVAL_LID_REQUEST = UTIL_COMP_ID | 0x1C, + UTIL_LIDMGR_INVAL_COMP = UTIL_COMP_ID | 0x1D, }; }; diff --git a/src/include/usr/util/utilmclmgr.H b/src/include/usr/util/utilmclmgr.H index 5ce5e089f..4f799a59b 100644 --- a/src/include/usr/util/utilmclmgr.H +++ b/src/include/usr/util/utilmclmgr.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2017,2018 */ +/* Contributors Listed Below - COPYRIGHT 2017,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -39,6 +39,27 @@ class MasterContainerLidMgrTest; namespace MCL { +/** + * @brief Structure used to hold information about a container loaded into + * memory using the MCL manager + */ +struct LoadedContainerInfo_t +{ + void* pSecureHeader; ///< Virtual address of secure header; nullptr if N/A + void* pContent; ///< Virtual address of container logical content + size_t size; ///< Size of container logical content in bytes + + /** + * @brief Builds a default LoadedContainerInfo_t + */ + LoadedContainerInfo_t() + : pSecureHeader(nullptr), + pContent(nullptr), + size(0) + { + } +}; + // Component ID(name) within MCL typedef std::array<uint8_t,16> ComponentID; @@ -46,10 +67,11 @@ typedef std::array<uint8_t,16> ComponentID; // NOTE: ComponentID in the MCL does not include NULL terminator so include room typedef char CompIdString[17]; -// Constants to simplify checking for the MCL and POWERVM comp ids +// Constants to simplify checking for the MCL and POWERVM/UCD9090 comp ids extern const ComponentID g_MclCompId; extern const ComponentID g_PowervmCompId; extern const ComponentID g_OpalCompId; +extern const ComponentID g_UcdCompId; // @enum Permission Types for MCL Component enum class CompFlags : uint16_t @@ -118,12 +140,14 @@ 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) {} + LidInfo(): id(0), size(0), vAddr(nullptr) {} + LidInfo(uint32_t i_id): id(i_id), size(0), vAddr(nullptr) {} + LidInfo(uint32_t i_id, size_t i_size): id(i_id), size(i_size), + vAddr(nullptr) {} - uint32_t id; - size_t size; + uint32_t id; // LID ID + size_t size; // Size of LID + void* vAddr; // Virtual address where LID was loaded /** * @brief Lid Info equality comparison @@ -133,7 +157,9 @@ struct LidInfo */ bool operator==(const LidInfo& rhs) const { - return (id == rhs.id && size == rhs.size); + return ( (id == rhs.id) + && (size == rhs.size) + && (vAddr == rhs.vAddr)); } /** @@ -242,9 +268,13 @@ class MasterContainerLidMgr /** * @brief Default Constructor - * Initializes memory spaces, loads, and parses the MCL. + * Initializes memory spaces, loads, and parses the MCL. + * + * @param[in] i_loadOnly Only load content into memory on subsequent + * requests to process components. Do not not move the content to + * Hostboot reserved memory. */ - MasterContainerLidMgr(); + MasterContainerLidMgr(bool i_loadOnly = false); /** * @brief Destructor. Cleans up memory allocated for class @@ -258,6 +288,31 @@ class MasterContainerLidMgr errlHndl_t processComponents(); /** + * @brief Process a single, named component from the MCL. + * Loads the specified component into the managed mainstore memory + * region. If component is marked pre-verified, cryptographically + * verifies the component and extends its measurement to the TPM. + * If MCL manager is in non-load-only mode, copies the content into + * Hostboot reserved memory region as well. + * + * @param[in] i_compId Component ID to load + * @param[out] o_info Information (LID ID, size, virtual address, etc.) + * for the LIDs that were loaded. + * + * @note: The container will go out of scope if another container is loaded + * or the MCL manager goes out of scope. + * + * @note: Component info will be reset on each call + * + * @return errlHndl_t Error log handle + * @retval nullptr Success + * @retval !nullptr Error; Error log handle points to valid error log + */ + errlHndl_t processSingleComponent( + const ComponentID& i_compId, + CompInfo& o_info); + + /** * @brief TPM extend information for secure components * * @param[in] i_compId - Component Id @@ -428,6 +483,10 @@ class MasterContainerLidMgr // Cache current comp id string for easy tracing CompIdString iv_curCompIdStr; + // When processing a component, only load the component and verify / measure + // it (do not copy it to reserved memory). + bool iv_loadOnly; + // Cached PHyp header static uint8_t cv_pPhypHeader[PAGE_SIZE]; diff --git a/src/usr/isteps/istep21/call_host_runtime_setup.C b/src/usr/isteps/istep21/call_host_runtime_setup.C index bde7a34d8..d4a46bbc7 100644 --- a/src/usr/isteps/istep21/call_host_runtime_setup.C +++ b/src/usr/isteps/istep21/call_host_runtime_setup.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -23,6 +23,7 @@ /* */ /* IBM_PROLOG_END_TAG */ +#include <config.h> #include <errl/errlentry.H> #include <errl/errlmanager.H> #include <initservice/isteps_trace.H> @@ -61,6 +62,10 @@ #include <isteps/pm/occCheckstop.H> #endif +#ifdef CONFIG_UCD_FLASH_UPDATES +#include "call_update_ucd_flash.H" +#endif + using namespace ERRORLOG; using namespace ISTEP; using namespace ISTEP_ERROR; @@ -666,6 +671,10 @@ void* call_host_runtime_setup (void *io_pArgs) break; } +#ifdef CONFIG_UCD_FLASH_UPDATES + POWER_SEQUENCER::TI::UCD::call_update_ucd_flash(); +#endif + // Fill in Hostboot runtime data if there is a PAYLOAD if( !(TARGETING::is_no_load()) ) { diff --git a/src/usr/isteps/istep21/call_update_ucd_flash.C b/src/usr/isteps/istep21/call_update_ucd_flash.C new file mode 100644 index 000000000..fa2d36896 --- /dev/null +++ b/src/usr/isteps/istep21/call_update_ucd_flash.C @@ -0,0 +1,101 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/istep21/call_update_ucd_flash.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] 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 <errl/errlentry.H> +#include <trace/interface.H> +#include <initservice/initserviceif.H> +#include <util/utilmclmgr.H> +#include <errl/errlmanager.H> +#include <hbotcompid.H> +#include <config.h> +#include <initservice/isteps_trace.H> + +#include "call_update_ucd_flash.H" + +namespace POWER_SEQUENCER +{ + +namespace TI +{ + +namespace UCD +{ + +void call_update_ucd_flash(void) +{ + errlHndl_t pError = nullptr; + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ENTER_MRK + "call_update_ucd_flash"); + + do { + + // Update UCD flash images, if needed + if (INITSERVICE::spBaseServicesEnabled()) + { + // @TODO RTC 201991 + // break early if no UCD devices + + // Load the UCD flash binary via the MCL in load only mode + MCL::MasterContainerLidMgr mclManager(true); + MCL::CompInfo info; + pError = mclManager.processSingleComponent(MCL::g_UcdCompId,info); + if(pError) + { + break; + } + + // @TODO RTC 201990 add flash update algorithm and make trace TRACDBIN + for(const auto& lid : info.lidIds) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"LID ID=0x%08X, " + "size=%d, vAddr=%p", + lid.id, lid.size, lid.vAddr); + TRACFBIN(ISTEPS_TRACE::g_trac_isteps_trace,"LID",lid.vAddr,64); + } + + // Destructor automatically unloads the UCD flash binary + } + + } while(0); + + if(pError) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK + "call_update_ucd_flash failed"); + errlCommit(pError, ISTEP_COMP_ID); + } + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, EXIT_MRK + "call_update_ucd_flash" ); +} + +} // End UCD namespace + +} // End TI namespace + +} // End POWER_SEQUENCER namespace + + diff --git a/src/usr/isteps/istep21/call_update_ucd_flash.H b/src/usr/isteps/istep21/call_update_ucd_flash.H new file mode 100644 index 000000000..fee1b685c --- /dev/null +++ b/src/usr/isteps/istep21/call_update_ucd_flash.H @@ -0,0 +1,49 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/istep21/call_update_ucd_flash.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2019 */ +/* [+] 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 __CALL_UPDATE_UCD_FLASH_H +#define __CALL_UPDATE_UCD_FLASH_H + +namespace POWER_SEQUENCER +{ + +namespace TI // Texas Instruments devices +{ + +namespace UCD // UCD* series +{ + /** + * @brief Updates the data flash of applicable Texas Instruments UCD + * power sequencer ASICs. + */ + void call_update_ucd_flash(); + +} // End UCD namespace + +} // End TI namespace + +} // End POWER_SEQUENCER namespace + +#endif diff --git a/src/usr/isteps/istep21/makefile b/src/usr/isteps/istep21/makefile index eedcb8cf5..1ba8edd32 100644 --- a/src/usr/isteps/istep21/makefile +++ b/src/usr/isteps/istep21/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2015,2018 +# Contributors Listed Below - COPYRIGHT 2015,2019 # [+] International Business Machines Corp. # # @@ -42,5 +42,6 @@ OBJS += call_host_runtime_setup.o OBJS += freqAttrData.o OBJS += call_host_verify_hdat.o OBJS += call_host_start_payload.o +OBJS += $(if $(CONFIG_UCD_FLASH_UPDATES),call_update_ucd_flash.o,) include ${ROOTPATH}/config.mk diff --git a/src/usr/isteps/ucd/HBconfig b/src/usr/isteps/ucd/HBconfig new file mode 100644 index 000000000..bd8d4fd6a --- /dev/null +++ b/src/usr/isteps/ucd/HBconfig @@ -0,0 +1,4 @@ +config UCD_FLASH_UPDATES + default n + help + Enable UCD power sequencer flash updates diff --git a/src/usr/util/utilmclmgr.C b/src/usr/util/utilmclmgr.C index a201e6905..472bb65ae 100644 --- a/src/usr/util/utilmclmgr.C +++ b/src/usr/util/utilmclmgr.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2017,2018 */ +/* Contributors Listed Below - COPYRIGHT 2017,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -46,6 +46,7 @@ const size_t MclCompSectionPadSize = 16; const ComponentID g_MclCompId {"MSTCONT"}; const ComponentID g_PowervmCompId {"POWERVM"}; const ComponentID g_OpalCompId {"OPAL"}; +const ComponentID g_UcdCompId {"UCD9090"}; void compIdToString(const ComponentID i_compId, CompIdString o_compIdStr) { @@ -96,10 +97,10 @@ void CompInfo::print() const // MasterContainerLidMgr //////////////////////////////////////////////////////////////////////////////// -MasterContainerLidMgr::MasterContainerLidMgr() +MasterContainerLidMgr::MasterContainerLidMgr(const bool i_loadOnly) : iv_mclSize(MCL_SIZE), iv_tmpSize(MCL_TMP_SIZE), iv_maxSize(0), iv_pMclVaddr(nullptr), iv_pTempVaddr(nullptr), iv_pVaddr(nullptr), - iv_compInfoCache{}, iv_hasHeader(true) + iv_compInfoCache{}, iv_hasHeader(true), iv_loadOnly(i_loadOnly) { // Need to make Memory spaces HRMOR-relative uint64_t hrmorVal = cpu_spr_value(CPU_SPR_HRMOR); @@ -352,6 +353,70 @@ void MasterContainerLidMgr::printCompInfoCache() #endif } +errlHndl_t MasterContainerLidMgr::processSingleComponent( + const ComponentID& i_compId, + CompInfo& o_info) +{ + errlHndl_t pError = nullptr; + const CompInfo empty; + o_info = empty; + + do { + + auto compInfoPairItr = iv_compInfoCache.find(i_compId); + if(compInfoPairItr != iv_compInfoCache.end()) + { + // Cache component ID string + compIdToString(compInfoPairItr->first, iv_curCompIdStr); + + pError = processComponent(compInfoPairItr->first, + compInfoPairItr->second); + if (pError) + { + UTIL_FT(ERR_MRK "MasterContainerLidMgr::processSingleComponent: " + "processComponent failed for component ID %s", + iv_curCompIdStr); + break; + } + + // Print component Info after loading component and verifying + UTIL_FT("MasterContainerLidMgr::processSingleComponent %s Info", + iv_curCompIdStr); + iv_compInfoCache.at(compInfoPairItr->first).print(); + + // Tell caller what was loaded + o_info = compInfoPairItr->second; + } + else + { + UTIL_FT(ERR_MRK "MasterContainerLidMgr::processSingleComponent: " + "Could not find component 0x%016llX (1st 8 bytes) in MCL", + compIdToInt(i_compId)); + /*@ + * @errortype + * @moduleid Util::UTIL_MCL_PROCESS_SINGLE_COMP + * @reasoncode Util::UTIL_LIDMGR_INVAL_COMP + * @userdata1 Component ID [truncated to 8 bytes] + * @devdesc Could not find requested component ID in master + * container LID + * @custdesc Firmware load error + */ + pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + Util::UTIL_MCL_PROCESS_SINGLE_COMP, + Util::UTIL_LIDMGR_INVAL_COMP, + compIdToInt(i_compId), + 0, + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + pError->collectTrace(UTIL_COMP_NAME); + break; + } + + } while(0); + + return pError; +} + errlHndl_t MasterContainerLidMgr::processComponents() { errlHndl_t l_errl = nullptr; @@ -382,8 +447,9 @@ errlHndl_t MasterContainerLidMgr::processComponents() return l_errl; } -errlHndl_t MasterContainerLidMgr::processComponent(const ComponentID& i_compId, - CompInfo& io_compInfo) +errlHndl_t MasterContainerLidMgr::processComponent( + const ComponentID& i_compId, + CompInfo& io_compInfo) { UTIL_FT(ENTER_MRK"MasterContainerLidMgr::processComponent %s", iv_curCompIdStr); @@ -394,15 +460,16 @@ errlHndl_t MasterContainerLidMgr::processComponent(const ComponentID& i_compId, // Check if Component is POWERVM (aka PHYP) bool isPhypComp = (i_compId == g_PowervmCompId) ? true : false; - // Only process components if they are marked PRE_VERIFY - if( (io_compInfo.flags & CompFlags::PRE_VERIFY) != - CompFlags::PRE_VERIFY) + // Only process components if they are marked PRE_VERIFY or we're in load only mode + if( ( (io_compInfo.flags & CompFlags::PRE_VERIFY) + != CompFlags::PRE_VERIFY) + && (!iv_loadOnly)) { UTIL_FT("MasterContainerLidMgr::processComponent not a pre-verify section skipping..."); break; } - // Total size of all Lids in component reoprted by the FSP + // Total size of all LIDs in component reported by the FSP size_t l_reportedSize = 0; // Load lids into temp mainstore memory l_errl = loadLids(io_compInfo, l_reportedSize, isPhypComp); @@ -495,8 +562,10 @@ errlHndl_t MasterContainerLidMgr::processComponent(const ComponentID& i_compId, } // Only load lids into HB reserved memory if component is preverified - if( (io_compInfo.flags & CompFlags::PRE_VERIFY) == - CompFlags::PRE_VERIFY) + // and MCL manager is not in load-only mode + if( ( (io_compInfo.flags & CompFlags::PRE_VERIFY) + == CompFlags::PRE_VERIFY) + && (!iv_loadOnly)) { auto l_curAddr = reinterpret_cast<uint64_t>(iv_pVaddr); bool l_firstLid = true; @@ -584,6 +653,9 @@ errlHndl_t MasterContainerLidMgr::loadLids(CompInfo& io_compInfo, break; } + // Store current LID load virtual address + lidInfo.vAddr = l_pLidVaddr; + // Increment vaddr pointer l_pLidVaddr += l_lidSize; @@ -637,6 +709,9 @@ errlHndl_t MasterContainerLidMgr::verifyExtend(const ComponentID& i_compId, // Only verify the lids if in secure mode if (SECUREBOOT::enabled()) { + UTIL_FT(ENTER_MRK"MasterContainerLidMgr::verifyExtend: " + "Secure enabled, calling verifyContainer"); + // Verify Container - some combination of Lids l_errl = SECUREBOOT::verifyContainer(iv_pVaddr, extractLidIds(io_compInfo.lidIds)); @@ -646,6 +721,8 @@ errlHndl_t MasterContainerLidMgr::verifyExtend(const ComponentID& i_compId, SECUREBOOT::handleSecurebootFailure(l_errl); assert(false,"Bug! handleSecurebootFailure shouldn't return!"); } + UTIL_FT(ENTER_MRK"MasterContainerLidMgr::verifyExtend: " + "Secure enabled, calling verifyComponent"); // Verify the component in the Secure Header matches the MCL l_errl = SECUREBOOT::verifyComponentId(l_conHdr, iv_curCompIdStr); |