diff options
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/hwpf/hwp/activate_powerbus/activate_powerbus.C | 5 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/sbe_centaur_init/sbe_centaur_init.C | 9 | ||||
-rw-r--r-- | src/usr/hwpf/plat/fapiPlatAttributeService.C | 1 | ||||
-rwxr-xr-x | src/usr/i2c/test/i2ctest.H | 8 | ||||
-rw-r--r-- | src/usr/makefile | 2 | ||||
-rw-r--r-- | src/usr/pnor/pnorrp.C | 4 | ||||
-rw-r--r-- | src/usr/sbe/makefile | 42 | ||||
-rw-r--r-- | src/usr/sbe/sbe_update.C | 2311 | ||||
-rw-r--r-- | src/usr/sbe/sbe_update.H | 439 | ||||
-rw-r--r-- | src/usr/sbe/test/makefile | 28 | ||||
-rw-r--r-- | src/usr/sbe/test/sbeupdatetest.H | 777 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/attribute_types.xml | 26 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/simics_MURANO.system.xml | 6 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/target_types.xml | 3 |
14 files changed, 3646 insertions, 15 deletions
diff --git a/src/usr/hwpf/hwp/activate_powerbus/activate_powerbus.C b/src/usr/hwpf/hwp/activate_powerbus/activate_powerbus.C index 2cbfc4409..a1d1da4ab 100644 --- a/src/usr/hwpf/hwp/activate_powerbus/activate_powerbus.C +++ b/src/usr/hwpf/hwp/activate_powerbus/activate_powerbus.C @@ -44,6 +44,8 @@ #include <initservice/isteps_trace.H> #include <hwpisteperror.H> +#include <sbe/sbeif.H> + // targeting support #include <targeting/common/commontargeting.H> #include <targeting/common/utilFilter.H> @@ -301,7 +303,8 @@ void * call_host_slave_sbe_update( void * io_pArgs ) TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_slave_sbe_update entry" ); - // call p8_customize_image.C + // @todo RTC 47033 - enable this call + // l_errl = SBE::updateProcessorSbeSeeproms(); TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_slave_sbe_update exit" ); diff --git a/src/usr/hwpf/hwp/sbe_centaur_init/sbe_centaur_init.C b/src/usr/hwpf/hwp/sbe_centaur_init/sbe_centaur_init.C index 097fe78ea..1bf3e339c 100644 --- a/src/usr/hwpf/hwp/sbe_centaur_init/sbe_centaur_init.C +++ b/src/usr/hwpf/hwp/sbe_centaur_init/sbe_centaur_init.C @@ -53,6 +53,7 @@ #include "sbe_centaur_init.H" #include <hwpisteperror.H> #include <errl/errludtarget.H> +#include <sbe/sbeif.H> #include "cen_xip_customize.H" extern fapi::ReturnCode fapiPoreVe(const fapi::Target i_target, @@ -143,6 +144,14 @@ void* call_sbe_centaur_init( void *io_pArgs ) l_membuf_iter != l_membufTargetList.end(); ++l_membuf_iter) { +/* + //find SBE image in PNOR + // @todo RTC 77647 + // Will use SBE::findSBEInPnor() function rather than + // VFS::module_load/address() function calls above + +*/ + // Make sure we have successfully retrieved the reference image if (l_errl) { diff --git a/src/usr/hwpf/plat/fapiPlatAttributeService.C b/src/usr/hwpf/plat/fapiPlatAttributeService.C index af9aacc68..a4c68d653 100644 --- a/src/usr/hwpf/plat/fapiPlatAttributeService.C +++ b/src/usr/hwpf/plat/fapiPlatAttributeService.C @@ -1576,6 +1576,7 @@ fapi::ReturnCode fapiPlatGetSpdAttrAccessor( return l_rc; } + } // End platAttrSvc namespace } // End fapi namespace diff --git a/src/usr/i2c/test/i2ctest.H b/src/usr/i2c/test/i2ctest.H index 15fe1f226..0224d8dd8 100755 --- a/src/usr/i2c/test/i2ctest.H +++ b/src/usr/i2c/test/i2ctest.H @@ -113,7 +113,7 @@ class I2CTest: public CxxTest::TestSuite // Read/Write SBE Primary: Murano-0, port-0 - // Safe to write to first 1K: 0x-0x400 + // Safe to write to first 0x300: 0x0-0x2FF { 0x00, 0x00, 0xAC, 0x0000ababcdcdefef, 8, false, TARGETING::TYPE_PROC }, // Write data to 0x0000 @@ -142,7 +142,7 @@ class I2CTest: public CxxTest::TestSuite // Read/Write SBE Backup: Murano-0, port-0 - // Safe to write to first 1K: 0x-0x400 + // Safe to write to first 0x300: 0x0-0x2FF { 0x00, 0x00, 0xAE, 0x0000ababcdcdefef, 8, false, TARGETING::TYPE_PROC }, // Write data to 0x0000 @@ -371,12 +371,12 @@ class I2CTest: public CxxTest::TestSuite // PROCESSOR TESTS // Read/Write SBE Backup: Murano-0, port-0 - // Safe to write to first 1K: 0x-0x400 + // Safe to write to first 0x300: 0x0-0x2FF { 0x00, 0x00, 0xAE, 0x0123, 0xFEFEDADA57579191, 8, TARGETING::TYPE_PROC }, // Read/Write SBE Primary: Murano-0, port-0 - // Safe to write to first 1K: 0x-0x400 + // Safe to write to first 0x300: 0x0-0x2FF { 0x00, 0x00, 0xAC, 0x02FC, 0x5ABC310000000000, 3, TARGETING::TYPE_PROC }, }; diff --git a/src/usr/makefile b/src/usr/makefile index 890756706..6433dba12 100644 --- a/src/usr/makefile +++ b/src/usr/makefile @@ -30,6 +30,6 @@ SUBDIRS = trace.d cxxtest.d testcore.d errl.d devicefw.d \ scom.d xscom.d targeting.d initservice.d hwpf.d \ ecmddatabuffer.d pnor.d i2c.d vfs.d fsi.d hwas.d fsiscom.d \ intr.d pore.d util.d mbox.d diag.d vpd.d scan.d \ - runtime.d ibscom.d dump.d secureboot.d devtree.d + runtime.d ibscom.d dump.d secureboot.d devtree.d sbe.d include ${ROOTPATH}/config.mk diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index 3d859c48b..cfb7fbd07 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -218,8 +218,8 @@ void PnorRP::initDaemon() * @devdesc PnorRP::initDaemon> Error from mm_alloc_block */ l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - PNOR::MOD_PNORRP_GETSECTIONINFO, - PNOR::RC_INVALID_SECTION, + PNOR::MOD_PNORRP_INITDAEMON, + PNOR::RC_EXTERNAL_ERROR, TO_UINT64(BASE_VADDR), TO_UINT64(rc)); l_errhdl->collectTrace(PNOR_COMP_NAME); diff --git a/src/usr/sbe/makefile b/src/usr/sbe/makefile new file mode 100644 index 000000000..50de91c2d --- /dev/null +++ b/src/usr/sbe/makefile @@ -0,0 +1,42 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/sbe/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2013 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG +ROOTPATH = ../../.. +MODULE = sbe + +## support for Targeting and fapi +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp + +## pointer to common HWP files +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include + +## pointer to already consumed procedures. +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build + +OBJS = sbe_update.o + +SUBDIRS = test.d + +include ${ROOTPATH}/config.mk diff --git a/src/usr/sbe/sbe_update.C b/src/usr/sbe/sbe_update.C new file mode 100644 index 000000000..8001c9954 --- /dev/null +++ b/src/usr/sbe/sbe_update.C @@ -0,0 +1,2311 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/sbe/sbe_update.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <vector> +#include <trace/interface.H> +#include <vpd/mvpdenums.H> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <errl/errludtarget.H> +#include <targeting/common/predicates/predicatectm.H> +#include <targeting/common/utilFilter.H> +#include <util/align.H> +#include <util/crc32.H> +#include <errno.h> +#include <pnor/pnorif.H> +#include <pnor/ecc.H> +#include <devicefw/driverif.H> +#include <sys/mm.h> +#include <sys/misc.h> +#include <hwas/common/deconfigGard.H> +#include <sbe/sbeif.H> +#include <sbe/sbereasoncodes.H> +#include "sbe_update.H" + +// fapi support +#include <fapi.H> +#include <fapiPlatHwpInvoker.H> +#include <hwpf/plat/fapiPlatTrace.H> + +//Procedures +#include <p8_xip_customize.H> +#include <sbe_xip_image.h> +#include <p8_image_help_base.H> + +// ---------------------------------------------- +// Trace definitions +// ---------------------------------------------- +trace_desc_t* g_trac_sbe = NULL; +TRAC_INIT( & g_trac_sbe, SBE_COMP_NAME, KILOBYTE ); + +// ------------------------ +// Macros for unit testing +//#define TRACUCOMP(args...) TRACFCOMP(args) +#define TRACUCOMP(args...) + +using namespace ERRORLOG; +using namespace TARGETING; + +namespace SBE +{ + + enum { + SBE_IMG_VADDR = VMM_VADDR_SBE_UPDATE, + RING_BUF1_VADDR = FIXED_SEEPROM_WORK_SPACE + SBE_IMG_VADDR, + RING_BUF2_VADDR = RING_BUF1_VADDR + FIXED_RING_BUF_SIZE, + //NOTE: recycling the same memory space for different + //steps in the process. + SBE_ECC_IMG_VADDR = RING_BUF1_VADDR, + SBE_ECC_IMG_MAX_SIZE = VMM_VADDR_SBE_UPDATE_END - SBE_ECC_IMG_VADDR, + }; + +///////////////////////////////////////////////////////////////////// + errlHndl_t updateProcessorSbeSeeproms() + { + errlHndl_t err = NULL; + errlHndl_t err_cleanup = NULL; + sbeTargetState_t sbeState; + std::vector<sbeTargetState_t> sbeStates_vector; + + bool l_cleanupVmmSpace = false; + bool l_restartNeeded = false; + + TRACUCOMP( g_trac_sbe, + ENTER_MRK"updateProcessorSbeSeeproms()" ); + + do{ + + //Make sure procedure constants keep within expected range. + assert((FIXED_SEEPROM_WORK_SPACE <= VMM_SBE_UPDATE_SIZE/2), + "updateProcessorSbeSeeproms() FIXED_SEEPROM_WORK_SPACE " + "too large"); + assert((FIXED_RING_BUF_SIZE <= VMM_SBE_UPDATE_SIZE/4), + "updateProcessorSbeSeeproms() FIXED_RING_BUF_SIZE too " + "large"); + + err = createSbeImageVmmSpace(); + if (err) + { + TRACFCOMP( g_trac_sbe, + INFO_MRK"updateProcessorSbeSeeproms(): " + "createSbeImageVmmSpace() Failed. ", + "rc=0x%.4X", err->reasonCode() ); + + break; + } + else + { + // Make sure cleanup gets called + l_cleanupVmmSpace = true; + } + + /*****************************************************************/ + /* Iterate over all the functional processors and do for each: */ + /* 1) Check their SBE State (PNOR, MVPD, SEEPROMs, etc), */ + /* 2) Determine the Necessary Update */ + /* 3) Perform Update Action */ + /*****************************************************************/ + TARGETING::TargetHandleList procList; + TARGETING::getAllChips(procList, + TARGETING::TYPE_PROC, + true); // true: return functional targets + + if( ( 0 == procList.size() ) || + ( NULL == procList[0] ) ) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"updateProcessorSbeSeeproms() - " + "No functional processors Found!" ); + break; + } + + + for(uint32_t i=0; i<procList.size(); i++) + { + + /*********************************************/ + /* Collect SBE Information for this Target */ + /*********************************************/ + memset(&sbeState, 0, sizeof(sbeState)); + sbeState.target = procList[i]; + + // @todo RTC 47033 check attribute on target to see if it's + // the master processor and set sbeState.target_is_master + + err = getSbeInfoState(sbeState); + + if (err) + { + TRACFCOMP( g_trac_sbe, + INFO_MRK"updateProcessorSbeSeeproms(): " + "getSbeInfoState() Failed " + "rc=0x%.4X, Target UID=0x%X", + err->reasonCode(), + TARGETING::get_huid(sbeState.target)); + + // Don't break - handle error at the end of the loop + + } + + + /**********************************************/ + /* Determine update actions for this target */ + /**********************************************/ + // Skip if we got an error collecting SBE Info State + if ( err == NULL ) + { + err = getTargetUpdateActions(sbeState); + if (err) + { + TRACFCOMP( g_trac_sbe, + INFO_MRK"updateProcessorSbeSeeproms(): " + "getTargetUpdateActions() Failed ", + "rc=0x%.4X, Target UID=0x%X", + err->reasonCode(), + TARGETING::get_huid(sbeState.target)); + + // Don't break - handle error at the end of the loop, + } + } + + /**********************************************/ + /* Perform Update Actions For This Target */ + /**********************************************/ + if ((err == NULL) && (sbeState.update_actions & DO_UPDATE)) + { + + err = performUpdateActions(sbeState); + if (err) + { + TRACFCOMP( g_trac_sbe, + INFO_MRK"updateProcessorSbeSeeproms(): " + "performUpdateActions() Failed ", + "rc=0x%.4X, Target UID=0x%X", + err->reasonCode(), + TARGETING::get_huid(sbeState.target)); + + break; + } + else + { + // Target updated without failure, so set IPL_RESTART + // flag, if necessary + if (sbeState.update_actions & IPL_RESTART) + { + l_restartNeeded = true; + } + } + + } + + + // Push this sbeState onto the vector + sbeStates_vector.push_back(sbeState); + + if ( err ) + { + // Something failed for this target. + // Commit the error here and move on to the next target, + // or if no targets left, will just continue the IPL + TRACFCOMP( g_trac_sbe, + INFO_MRK"updateProcessorSbeSeeproms(): " + "Committing Error Log rc=0x%.4X for " + "Target UID=0x%X, but continuing procedure", + err->reasonCode(), + TARGETING::get_huid(sbeState.target)); + errlCommit( err, SBE_COMP_ID ); + } + + + + } //end of Target for loop collecting each target's SBE State + + + /**************************************************************/ + /* Perform System Operation */ + /**************************************************************/ + //TODO RTC: 47033 - Restart IPL if SBE Update requires it + // For Now just trace that a restart is needed + if (l_restartNeeded == true) + { + TRACFCOMP( g_trac_sbe, + INFO_MRK"updateProcessorSbeSeeproms(): Restart " + "Needed, but not currently supported (%d). " + "Continuing IPL", + l_restartNeeded ); + } + + + }while(0); + + + + // Cleanup VMM Workspace + if ( l_cleanupVmmSpace == true ) + { + err_cleanup = cleanupSbeImageVmmSpace(); + if ( err_cleanup != NULL ) + { + + if ( err != NULL ) + { + // 2 error logs, so commit the cleanup log here + TRACFCOMP( g_trac_sbe, + ERR_MRK"updateProcessorSbeSeeproms(): Previous " + "error (rc=0x%X) before cleanupSbeImageVmmSpace" + "() failed. Committing cleanup error (rc=0x%X) " + "and returning original error", + err->reasonCode(), err_cleanup->reasonCode() ); + + errlCommit( err_cleanup, SBE_COMP_ID ); + } + else + { + // no previous error, so returning cleanup error + TRACFCOMP( g_trac_sbe, + ERR_MRK"updateProcessorSbeSeeproms(): " + "cleanupSbeImageVmmSpace() failed.", + "rc=0x%.4X", err_cleanup->reasonCode() ); + err = err_cleanup; + } + } + } + + + TRACUCOMP( g_trac_sbe, + EXIT_MRK"updateProcessorSbeSeeproms()" ); + + return err; + } + +///////////////////////////////////////////////////////////////////// + errlHndl_t findSBEInPnor(TARGETING::Target* i_target, + void*& o_imgPtr, + size_t& o_imgSize, + sbe_image_version_t* o_version) + { + errlHndl_t err = NULL; + PNOR::SectionInfo_t pnorInfo; + sbeToc_t* sbeToc = NULL; + uint8_t ec = 0; + PNOR::SectionId pnorSectionId = PNOR::INVALID_SECTION; + + void* hdr_Ptr = NULL; + o_imgPtr = NULL; + o_imgSize = 0; + + TRACDCOMP( g_trac_sbe, + ENTER_MRK"findSBEInPnor()" ); + + do{ + + // Get the correct PNOR Section Id + if ( i_target->getAttr<ATTR_TYPE>() == TYPE_PROC ) + { + pnorSectionId = PNOR::SBE_IPL; + } + else if ( i_target->getAttr<ATTR_TYPE>() == TYPE_MEMBUF ) + { + pnorSectionId = PNOR::CENTAUR_SBE; + } + else + { + // Unsopported target type was passed in + TRACFCOMP( g_trac_sbe, ERR_MRK"findSBEInPnor: Unsupported " + "target type was passed in: uid=0x%X, type=0x%X", + TARGETING::get_huid(i_target), + i_target->getAttr<ATTR_TYPE>()); + + /*@ + * @errortype + * @moduleid SBE_FIND_IN_PNOR + * @reasoncode SBE_INVALID_INPUT + * @userdata1 Target Unit Id + * @userdata2 Target Type + * @devdesc Unsupported Target Type passed in + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_FIND_IN_PNOR, + SBE_INVALID_INPUT, + TARGETING::get_huid(i_target), + i_target->getAttr<ATTR_TYPE>()); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + break; + } + + + // Get SBE PNOR section info from PNOR RP + err = PNOR::getSectionInfo( pnorSectionId, + PNOR::CURRENT_SIDE, + pnorInfo ); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"findSBEInPnor: Error calling " + "PNOR::getSectionInfo() rc=0x%.4X", + err->reasonCode() ); + break; + } + + TRACUCOMP( g_trac_sbe, + INFO_MRK"findSBEInPnor: UID=0x%X, sectionId=0x%X. " + "pnor vaddr = 0x%.16X", + TARGETING::get_huid(i_target), + pnorSectionId, pnorInfo.vaddr); + + sbeToc = reinterpret_cast<sbeToc_t*>( pnorInfo.vaddr ); + + if (sbeToc->eyeCatch != SBETOC_EYECATCH) + { + //The SBE partition does not have the proper eyecatcher + TRACFCOMP( g_trac_sbe, ERR_MRK"findSBEInPnor: SBE partition " + "does not have the proper eyecatcher: was: 0x%X, " + "should be: 0x%X", + sbeToc->eyeCatch, SBETOC_EYECATCH ); + + /*@ + * @errortype + * @moduleid SBE_FIND_IN_PNOR + * @reasoncode SBE_INVALID_EYECATCHER + * @userdata1 SBE TOC EYE-CATCHER + * @userdata2 Expected EYE-CATCHER + * @devdesc Unsupported EYE-CATCHER found in TOC + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_FIND_IN_PNOR, + SBE_INVALID_EYECATCHER, + sbeToc->eyeCatch, + SBETOC_EYECATCH); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + break; + } + else + { + + //Check the TOC Version + if( SUPPORTED_TOC_VER != sbeToc->tocVersion) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"findSBEInPnor: Unsupported " + "SBE TOC Version in SBE Partition" ); + /*@ + * @errortype + * @moduleid SBE_FIND_IN_PNOR + * @reasoncode SBE_UNSUPPORTED_TOC + * @userdata1[0:31] CHIP EC + * @userdata1[32:63] Expected TOC Version + * @userdata2[0:31] SBE TOC Version + * @userdata2[32:63] SBE TOC EyeCatch + * @devdesc SBE partition contains unsupported version + * of Table of Contents + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_FIND_IN_PNOR, + SBE_UNSUPPORTED_TOC, + TWO_UINT32_TO_UINT64(ec, + SUPPORTED_TOC_VER), + TWO_UINT32_TO_UINT64(sbeToc->tocVersion, + sbeToc->eyeCatch)); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + + // @todo RTC 47033 capture SBE TOC for analysis + + break; + } + + //Walk the TOC and find our current EC + ec = i_target->getAttr<TARGETING::ATTR_EC>(); + for(uint32_t i=0; i<MAX_SBE_ENTRIES; i++) + { + if(static_cast<uint32_t>(ec) == sbeToc->entries[i].ec) + { + + // EC found in TOC + uint64_t offset = pnorInfo.vaddr + + static_cast<uint64_t>(sbeToc->entries[i].offset); + hdr_Ptr = reinterpret_cast<void*>( offset ); + + o_imgSize = sbeToc->entries[i].size; + + TRACUCOMP( g_trac_sbe, INFO_MRK"findSBEInPnor: Found " + "EC Image: ec=0x%.2X offset=0x%.16X, i=%d " + "size=0x%X", + ec, offset, i, o_imgSize ); + break; + } + } + } + + if(NULL == hdr_Ptr) + { + //if we get here, it's an error + TRACFCOMP( g_trac_sbe,ERR_MRK"findSBEInPnor:SBE Image not " + "located, ec=0x%.2X",ec ); + + /*@ + * @errortype + * @moduleid SBE_FIND_IN_PNOR + * @reasoncode SBE_EC_NOT_FOUND + * @userdata1[0:31] CHIP EC + * @userdata1[32:63] PNOR Section ID + * @userdata2[0:31] SBE TOC Version + * @userdata2[32:63] SBE TOC EyeCatch + * @devdesc SBE image for current chip EC was not found + * in PNOR + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_FIND_IN_PNOR, + SBE_EC_NOT_FOUND, + TWO_UINT32_TO_UINT64(ec, + pnorSectionId), + TWO_UINT32_TO_UINT64(sbeToc->tocVersion, + sbeToc->eyeCatch)); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + // @todo RTC 47033 capture SBE TOC for analysis + + break; + } + + // The SBE Image for the corresponding EC was found and includes a + // SBE Header, so advance PNOR pointer 4k to move it past header + // page to the start of the non-customized SBE image + o_imgPtr = reinterpret_cast<void*> + (reinterpret_cast<char*>(hdr_Ptr)+0x1000); + + + if(NULL != o_version) + { + err = readPNORVersion(hdr_Ptr, + *o_version); + if(err) + { + break; + } + } + + }while(0); + + + TRACDCOMP( g_trac_sbe, + EXIT_MRK"findSBEInPnor(): o_imgPtr=%p, o_imgSize=0x%X", + o_imgPtr, o_imgSize ); + + + return err; + } + + + +///////////////////////////////////////////////////////////////////// + errlHndl_t procCustomizeSbeImg(TARGETING::Target* i_target, + void* i_sbePnorPtr, + size_t i_maxImgSize, + void* io_imgPtr, + size_t& o_actImgSize) + { + errlHndl_t err = NULL; + uint32_t coreMask = 0x0000FFFF; + size_t maxCores = P8_MAX_EX_PER_PROC; + uint32_t procIOMask = 0; + + TRACUCOMP( g_trac_sbe, + ENTER_MRK"procCustomizeSbeImg(): uid=0x%X, i_sbePnorPtr= " + "%p, maxS=0x%X, io_imgPtr=%p", + TARGETING::get_huid(i_target), i_sbePnorPtr, + i_maxImgSize, io_imgPtr); + + do{ + + // cast OUR type of target to a FAPI type of target. + const fapi::Target + l_fapiTarg(fapi::TARGET_TYPE_PROC_CHIP, + (const_cast<TARGETING::Target*>(i_target))); + + + // The p8_xip_customize() procedure tries to include as much core + // information as possible, but is limited by SBE Image size + // constraints. + // This loop is designed to remove the number of cores passed into + // p8_xip_customize() until an image can be created successfully. + + while( __builtin_popcount(procIOMask) < + __builtin_popcount(coreMask)) + { + + err = selectBestCores(i_target, + maxCores, + coreMask); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"procCustomizeSbeImg() - " + "selectBestCores() failed rc=0x%X. " + "MaxCores=0x%.8X. HUID=0x%.8X. Aborting Update", + err->reasonCode(), maxCores, + TARGETING::get_huid(i_target)); + break; + } + + procIOMask = coreMask; + + uint32_t tmpImgSize = static_cast<uint32_t>(i_maxImgSize); + + FAPI_INVOKE_HWP( err, + p8_xip_customize, + l_fapiTarg, + i_sbePnorPtr, //image in + io_imgPtr, //image out + tmpImgSize, + 0, //IPL + 0, //HB/IPL + (void*)RING_BUF1_VADDR, + (uint32_t)FIXED_RING_BUF_SIZE, + (void*)RING_BUF2_VADDR, + (uint32_t)FIXED_RING_BUF_SIZE, + procIOMask); + + o_actImgSize = static_cast<size_t>(tmpImgSize); + + maxCores = __builtin_popcount(procIOMask); + + if ( err ) + { + TRACFCOMP( g_trac_sbe, + ERR_MRK"procCustomizeSbeImg(): FAPI_INVOKE_HWP(" + "p8_xip_customize) failed with rc=0x%x04X, " + "MaxCores=0x%.8X. HUID=0x%.8X. coreMask=0x%.8X, " + "procIOMask=0x%.8X.", + err->reasonCode(), maxCores, + TARGETING::get_huid(i_target), + coreMask, procIOMask); + + ERRORLOG::ErrlUserDetailsTarget(i_target, + "Proc Target") + .addToLog(err); + + // @todo RTC 47033 look for specific return code for + // the case where he couldn't fix the cores we asked for + // but could possibly fit a lesser amount + + break; + } + + } + + + if(err) + { + break; + } + }while(0); + + TRACUCOMP( g_trac_sbe, + EXIT_MRK"procCustomizeSbeImg(): io_imgPtr=%p, " + "o_actImgSize=0x%X", io_imgPtr, o_actImgSize ); + + return err; + } + +///////////////////////////////////////////////////////////////////// + errlHndl_t selectBestCores(TARGETING::Target* i_target, + size_t i_maxExs, + uint32_t& o_exMask) + { + TRACUCOMP( g_trac_sbe, + ENTER_MRK"selectBestCores(i_maxCores=0x%.8X)", + i_maxExs); + + errlHndl_t err = NULL; + uint32_t manGuardExs = 0x00000000; + uint32_t exCount = 0; + uint32_t deconfigByEid = 0; + + o_exMask = 0x00000000; + + do{ + // find all EX chiplets of the proc + TARGETING::TargetHandleList l_exTargetList; + TARGETING::getChildChiplets( l_exTargetList, + i_target, + TARGETING::TYPE_EX, + false); // return all + + //Sort through cores + for ( TargetHandleList::const_iterator + l_iterEX = l_exTargetList.begin(); + l_iterEX != l_exTargetList.end(); + ++l_iterEX ) + { + // make a local copy of the EX target + const TARGETING::Target* l_ex_target = *l_iterEX; + + + if( !(l_ex_target-> + getAttr<TARGETING::ATTR_HWAS_STATE>().present) ) + { + // not present, so skip and continue + continue; + } + + + uint8_t chipUnit = l_ex_target-> + getAttr<TARGETING::ATTR_CHIP_UNIT>(); + + if(l_ex_target-> + getAttr<TARGETING::ATTR_HWAS_STATE>().functional) + { + o_exMask |= (0x00008000 >> chipUnit); + exCount++; + + if(exCount >= i_maxExs) + { + break; + } + } + else + { + //If non-functional due to FCO or Manual gard, + //add it to list of exs to include if + //more are needed + + deconfigByEid = l_ex_target-> + getAttr<TARGETING::ATTR_HWAS_STATE>(). + deconfiguredByEid; + if( + // FCO + (deconfigByEid == + HWAS::DeconfigGard::DECONFIGURED_BY_FIELD_CORE_OVERRIDE) + || // Manual GARD + (deconfigByEid == + HWAS::DeconfigGard::DECONFIGURED_BY_MANUAL_GARD) + ) + { + manGuardExs |= (0x00008000 >> chipUnit); + } + } + } // end ex target loop + + if(exCount >= i_maxExs) + { + //We've found enough, break out of function + break; + } + + //Look for more 'good' exs. + manGuardExs = trimBitMask(manGuardExs, + i_maxExs-exCount); + o_exMask |= manGuardExs; + TRACUCOMP( g_trac_sbe,INFO_MRK"selectBestCores: trimBitMask manGuardExs=0x%.8X", + manGuardExs); + + }while(0); + + TRACUCOMP( g_trac_sbe, + EXIT_MRK"selectBestCores(o_exMask=0x%.8X)", + o_exMask); + + return err; + } + + +///////////////////////////////////////////////////////////////////// + errlHndl_t getSetMVPDVersion(TARGETING::Target* i_target, + opType_t i_op, + mvpdSbKeyword_t& io_sb_keyword) + { + errlHndl_t err = NULL; + size_t vpdSize = 0; + + TRACUCOMP( g_trac_sbe, + ENTER_MRK"getSetMVPDVersion(i_op=%d)", i_op ); + + do{ + // Read SB Keyword which contains SBE version and dirty bit + // information + // Note: First read with NULL for o_buffer sets vpdSize to the + // correct length + err = deviceRead( i_target, + NULL, + vpdSize, + DEVICE_MVPD_ADDRESS( MVPD::CP00, + MVPD::SB ) ); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSetMVPDVersion() - MVPD " + "failure getting SB keywordw size HUID=0x%.8X", + TARGETING::get_huid(i_target)); + break; + } + + if(vpdSize != MVPD_SB_RECORD_SIZE) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSetMVPDVersion() - MVPD SB " + "keyword wrong length HUID=0x%.8X, length=0x.2X, " + "expected=0x.2x", + TARGETING::get_huid(i_target), vpdSize, + MVPD_SB_RECORD_SIZE); + /*@ + * @errortype + * @moduleid SBE_GETSET_MVPD_VERSION + * @reasoncode SBE_MVPD_LEN_INVALID + * @userdata1 Discovered VPD Size + * @userdata2 Expected VPD Size + * @devdesc SB Keyword in MVPD has invalid size + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_GETSET_MVPD_VERSION, + SBE_MVPD_LEN_INVALID, + TO_UINT64(vpdSize), + TO_UINT64(MVPD_SB_RECORD_SIZE)); + ErrlUserDetailsTarget(i_target + ).addToLog(err); + err->collectTrace(SBE_COMP_NAME, 256); + err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_MED ); + + break; + } + + if(i_op == MVPDOP_READ) + { + err = deviceRead( i_target, + reinterpret_cast<void*>( &io_sb_keyword ), + vpdSize, + DEVICE_MVPD_ADDRESS( MVPD::CP00, + MVPD::SB ) ); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSetMVPDVersion() - MVPD " + "failure reading SB keyword data HUID=0x%.8X", + TARGETING::get_huid(i_target)); + break; + } + + TRACDBIN(g_trac_sbe, "MVPD:SB", &io_sb_keyword, vpdSize); + + } + else //write + { + err = deviceWrite( i_target, + reinterpret_cast<void*>( &io_sb_keyword ), + vpdSize, + DEVICE_MVPD_ADDRESS( MVPD::CP00, + MVPD::SB ) ); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSetMVPDVersion() - MVPD " + "failure writing SB keyword data HUID=0x%.8X", + TARGETING::get_huid(i_target)); + break; + } + } + + }while(0); + + TRACUCOMP( g_trac_sbe, + EXIT_MRK"getSetMVPDVersion()" ); + + return err; + } + +///////////////////////////////////////////////////////////////////// + errlHndl_t readPNORVersion(void*& i_pnorImgHdrPtr, + sbe_image_version_t& o_version) + { + errlHndl_t err = NULL; + TRACDCOMP( g_trac_sbe, + ENTER_MRK"readPNORVersion()" ); + + do{ + // @todo RTC 34080 - support Secure Boot Header + + //For Non-secure systems, version is prefixed with + //'VERSION\0' in ASCII in the 4k header. The official + //protocol is to scan for VERSION, then grab the value + //that follows. + + char* tmpPtr = static_cast<char*>(i_pnorImgHdrPtr); + + + //Last reasonable offset is (Version size + + //size of eyecatcher) bytes from end of Page. + char* endPtr = tmpPtr +(4*KILOBYTE) - + sizeof(sbe_image_version_t&) - + sizeof(NONSECURE_VER_EYECATCH); + + // Increment pointer sizeof(uint64_t) because eyecatcher + // must be 8-byte alligned + for(; tmpPtr<endPtr; tmpPtr+=sizeof(uint64_t)) + { + if(*(reinterpret_cast<uint64_t*>(tmpPtr)) == + NONSECURE_VER_EYECATCH) + { + //increment 8 more bytes and break out + tmpPtr+=sizeof(uint64_t); + break; + } + } + + if(tmpPtr < endPtr) + { + memcpy(reinterpret_cast<void*>( &o_version ), + tmpPtr, + sizeof(o_version)); + } + else + { + + TRACFCOMP( g_trac_sbe, ERR_MRK"readPNORVersion() - VERSION not found in SBE image in PNOR"); + /*@ + * @errortype + * @moduleid SBE_READ_PNOR_VERSION + * @reasoncode SBE_VERSION_NOT_FOUND + * @userdata1 Not Used + * @userdata2 Not Used + * @devdesc Image Version not found in PNOR + * SBE image. + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_READ_PNOR_VERSION, + SBE_VERSION_NOT_FOUND, + 0, 0); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + } + + }while(0); + + TRACDCOMP( g_trac_sbe, + EXIT_MRK"readPNORVersion()" ); + + return err; + } + +///////////////////////////////////////////////////////////////////// + errlHndl_t getSbeBootSeeprom(TARGETING::Target* i_target, + sbeSeepromSide_t& o_bootSide) + { + TRACUCOMP( g_trac_sbe, + ENTER_MRK"getSbeBootSeeprom()" ); + + errlHndl_t err = NULL; + uint64_t scomData = 0x0; + + o_bootSide = SBE_SEEPROM0; + + do{ + + size_t op_size = sizeof(scomData); + err = deviceRead( i_target, + &scomData, + op_size, + DEVICE_SCOM_ADDRESS(SBE_VITAL_REG_0x0005001C) ); + if( err ) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeBootSeeprom() -Error " + "reading SBE VITAL REG (0x%.8X) from Target :" + "HUID=0x%.8X", + SBE_VITAL_REG_0x0005001C, + TARGETING::get_huid(i_target)); + break; + } + if(scomData & SBE_BOOT_SELECT_MASK) + { + o_bootSide = SBE_SEEPROM1; + } + + }while(0); + + TRACUCOMP( g_trac_sbe, + EXIT_MRK"getSbeBootSeeprom(): o_bootSide=0x%X", o_bootSide ); + + return err; + } + + +///////////////////////////////////////////////////////////////////// + errlHndl_t getSbeInfoState(sbeTargetState_t& io_sbeState) + { + + TRACDCOMP( g_trac_sbe, + ENTER_MRK"getSbeInfoState(): HUID=0x%.8X", + TARGETING::get_huid(io_sbeState.target)); + + + errlHndl_t err = NULL; + + do{ + + /************************************************************/ + /* Set Target Properties (target_is_master previously set) */ + /************************************************************/ + io_sbeState.ec = io_sbeState.target->getAttr<TARGETING::ATTR_EC>(); + + + /*******************************************/ + /* Get PNOR SBE Version Information */ + /*******************************************/ + void* sbePnorPtr = NULL; + size_t sbePnorImageSize = 0; + sbe_image_version_t tmp_pnorVersion; + + err = findSBEInPnor(io_sbeState.target, + sbePnorPtr, + sbePnorImageSize, + &tmp_pnorVersion); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - " + "Error getting SBE Version from PNOR"); + break; + } + + // copy tmp_pnorVersion to the main structure + memcpy ( &io_sbeState.pnorVersion, + &tmp_pnorVersion, + sizeof(tmp_pnorVersion)); + + + /*******************************************/ + /* Customize SBE Image from PNOR and */ + /* Calculate CRC of the image */ + /*******************************************/ + size_t sbeImgSize = 0; + err = procCustomizeSbeImg(io_sbeState.target, + sbePnorPtr, //SBE vaddr in PNOR + FIXED_SEEPROM_WORK_SPACE, //max size + reinterpret_cast<void*> + (SBE_IMG_VADDR), //destination + sbeImgSize); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - " + "Error from procCustomizeSbeImg()"); + break; + } + + io_sbeState.customizedImage_size = sbeImgSize; + io_sbeState.customizedImage_crc = + Util::crc32_calc(reinterpret_cast<void*> + (SBE_IMG_VADDR), + sbeImgSize) ; + + TRACUCOMP( g_trac_sbe, "getSbeInfoState() - procCustomizeSbeImg(): " + "maxSize=0x%X, actSize=0x%X, crc=0x%X", + FIXED_SEEPROM_WORK_SPACE, sbeImgSize, + io_sbeState.customizedImage_crc); + + + + /*******************************************/ + /* Get MVPD SBE Version Information */ + /*******************************************/ + err = getSetMVPDVersion(io_sbeState.target, + MVPDOP_READ, + io_sbeState.mvpdSbKeyword); + if(err) + { + //If MVPD is bad, commit the error and move to the next proc + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - " + "Error reading version from MVPD"); + break; + } + + + // Determine Permanent Side from flag in MVPD + if(SEEPROM_0_PERMANENT_VALUE == + (io_sbeState.mvpdSbKeyword.flags & PERMANENT_FLAG_MASK)) + { + io_sbeState.permanent_seeprom_side = SBE_SEEPROM0; + } + else // Side 1 must be permanent + { + io_sbeState.permanent_seeprom_side = SBE_SEEPROM1; + } + + + /*******************************************/ + /* Get SEEPROM A SBE Version Information */ + /*******************************************/ + err = getSeepromSideVersion(io_sbeState.target, + EEPROM::SBE_PRIMARY, + io_sbeState.seeprom_0_ver, + io_sbeState.seeprom_0_ver_ECC_fail); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error " + "getting SBE Information from SEEPROM A (0x%X)", + EEPROM::SBE_PRIMARY); + break; + } + + TRACDBIN(g_trac_sbe, "getSbeInfoState-spA", + &(io_sbeState.seeprom_0_ver), + sizeof(sbeVersion_t)); + + /*******************************************/ + /* Get SEEPROM B SBE Version Information */ + /*******************************************/ + err = getSeepromSideVersion(io_sbeState.target, + EEPROM::SBE_BACKUP, + io_sbeState.seeprom_1_ver, + io_sbeState.seeprom_1_ver_ECC_fail); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error " + "getting SBE Information from SEEPROM B (0x%X)", + EEPROM::SBE_BACKUP); + break; + } + + + TRACDBIN(g_trac_sbe, "getSbeInfoState-spB", + &(io_sbeState.seeprom_1_ver), + sizeof(sbeVersion_t)); + + /***********************************************/ + /* Determine which SEEPROM System Booted On */ + /***********************************************/ + //Get Current (boot) Side + sbeSeepromSide_t tmp_cur_side = SBE_SEEPROM_INVALID; + err = getSbeBootSeeprom(io_sbeState.target, tmp_cur_side); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error returned from getSbeBootSeeprom()"); + break; + } + io_sbeState.cur_seeprom_side = tmp_cur_side; + if (io_sbeState.cur_seeprom_side == SBE_SEEPROM0) + { + io_sbeState.alt_seeprom_side = SBE_SEEPROM1; + } + else if ( io_sbeState.cur_seeprom_side == SBE_SEEPROM1) + { + io_sbeState.alt_seeprom_side = SBE_SEEPROM0; + } + else + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - Error: " + "Unexpected cur_seeprom_side value = 0x%X, ", + io_sbeState.cur_seeprom_side); + + /*@ + * @errortype + * @moduleid SBE_GET_TARGET_INFO_STATE + * @reasoncode SBE_INVALID_SEEPROM_SIDE + * @userdata1 Temporary Current Side + * @userdata2 SBE State Current Side + * @devdesc Invalid Boot SEEPROM Side Found + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_GET_TARGET_INFO_STATE, + SBE_INVALID_SEEPROM_SIDE, + tmp_cur_side, + io_sbeState.cur_seeprom_side); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + + break; + } + + TRACUCOMP( g_trac_sbe,"getSbeInfoState() - cur=0x%X, alt=0x%X", + io_sbeState.cur_seeprom_side, + io_sbeState.alt_seeprom_side); + + }while(0); + + return err; + + } + + +///////////////////////////////////////////////////////////////////// + errlHndl_t getSeepromSideVersion(TARGETING::Target* i_target, + EEPROM::eeprom_chip_types_t i_seepromSide, + sbeSeepromVersionInfo_t& o_info, + bool& o_seeprom_ver_ECC_fail) + { + + TRACUCOMP( g_trac_sbe, + ENTER_MRK"getSeepromSideVersion(): HUID=0x%.8X, side:%d", + TARGETING::get_huid(i_target), i_seepromSide); + + errlHndl_t err = NULL; + PNOR::ECC::eccStatus eccStatus = PNOR::ECC::CLEAN; + o_seeprom_ver_ECC_fail = false; + + size_t sbeInfoSize_ECC = (sizeof(sbeSeepromVersionInfo_t)*9)/8; + size_t sbeInfoSize_ECC_aligned = ALIGN_8(sbeInfoSize_ECC); + + // Create data buffer of larger size + // NOTE: EEPROM read will fill in smaller, unaligned size + uint8_t * tmp_data_ECC = static_cast<uint8_t*>( + malloc(sbeInfoSize_ECC_aligned)); + + do{ + + /*******************************************/ + /* Read SBE Version SBE Version Information */ + /*******************************************/ + + // Clear Buffer + memset( tmp_data_ECC, 0, sbeInfoSize_ECC_aligned ); + + //Read SBE Versions + err = deviceRead( i_target, + tmp_data_ECC, + sbeInfoSize_ECC, + DEVICE_EEPROM_ADDRESS( + i_seepromSide, + SBE_VERSION_SEEPROM_ADDRESS)); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSeepromSideVersion() - Error " + "reading SBE Version from Seeprom 0x%X, HUID=0x%.8X", + i_seepromSide, TARGETING::get_huid(i_target)); + break; + } + + TRACDBIN(g_trac_sbe, + "getSeepromSideVersion()- tmp_data_ECC (not-aligned)", + tmp_data_ECC, + sbeInfoSize_ECC); + + TRACDBIN(g_trac_sbe, + "getSeepromSideVersion()- tmp_data_ECC (aligned)", + tmp_data_ECC, + sbeInfoSize_ECC_aligned); + + + // Clear destination + memset( &o_info, 0, sizeof(o_info) ); + + + // Remove ECC + eccStatus = PNOR::ECC::removeECC( + tmp_data_ECC, + reinterpret_cast<uint8_t*>(&o_info), + sizeof(o_info)); + + TRACUCOMP( g_trac_sbe, "getSeepromSideVersion(): eccStatus=%d, " + "sizeof o_info=%d, sI_ECC=%d, sI_ECC_aligned=%d", + eccStatus, sizeof(o_info), sbeInfoSize_ECC, + sbeInfoSize_ECC_aligned); + + // Handle Uncorrectable ECC - no error log: + // clear data and set o_seeprom_ver_ECC_fail=true + if ( eccStatus == PNOR::ECC::UNCORRECTABLE ) + { + + TRACFCOMP( g_trac_sbe,ERR_MRK"getSeepromSideVersion() - ECC " + "ERROR: eccStatus=%d, side=%d, sizeof o_info=%d, " + "sI_ECC=%d, sI_ECC_aligned=%d", + eccStatus, i_seepromSide, sizeof(o_info), + sbeInfoSize_ECC, sbeInfoSize_ECC_aligned); + + memset( &o_info, 0, sizeof(o_info)); + o_seeprom_ver_ECC_fail = true; + + TRACFCOMP( g_trac_sbe, "getSeepromSideVersion(): clearing out " + "version data (o_info) for side %d and returning " + "o_seeprom_ver_ECC_fail as true (%d)", + i_seepromSide, o_seeprom_ver_ECC_fail); + } + + TRACDBIN(g_trac_sbe, + "getSeepromSideVersion: data (no ECC)", + &o_info, + sizeof(o_info)); + + }while(0); + + // Free allocated memory + free(tmp_data_ECC); + + + TRACUCOMP( g_trac_sbe, + EXIT_MRK"getSeepromSideVersion: o_seeprom_ver_ECC_fail=%d", + o_seeprom_ver_ECC_fail ); + + return err; + } + + +///////////////////////////////////////////////////////////////////// + errlHndl_t updateSeepromSide(sbeTargetState_t i_sbeState) + { + TRACDCOMP( g_trac_sbe, + ENTER_MRK"updateSeepromSide(): HUID=0x%.8X", + TARGETING::get_huid(i_sbeState.target)); + errlHndl_t err = NULL; + int64_t rc = 0; + + int64_t rc_readBack_ECC_memcmp = 0; + PNOR::ECC::eccStatus eccStatus = PNOR::ECC::CLEAN; + + // This struct is always 8-byte aligned + size_t sbeInfoSize = sizeof(sbeSeepromVersionInfo_t); + size_t sbeInfoSize_ECC = (sbeInfoSize*9)/8; + + + // Buffers for reading/writing SBE Version Information + uint8_t * sbeInfo_data = static_cast<uint8_t*>( + malloc(sbeInfoSize)); + + uint8_t * sbeInfo_data_ECC = static_cast<uint8_t*>( + malloc(sbeInfoSize_ECC)); + + uint8_t * sbeInfo_data_readBack = static_cast<uint8_t*>( + malloc(sbeInfoSize)); + + uint8_t * sbeInfo_data_ECC_readBack = static_cast<uint8_t*>( + malloc(sbeInfoSize_ECC)); + + + do{ + + + /*******************************************/ + /* Update SBE Version Information */ + /*******************************************/ + + // The new version has already been created + memcpy(sbeInfo_data, &i_sbeState.new_seeprom_ver, sbeInfoSize); + + // Inject ECC to Data + memset( sbeInfo_data_ECC, 0, sbeInfoSize_ECC); + PNOR::ECC::injectECC(sbeInfo_data, sbeInfoSize, sbeInfo_data_ECC); + + TRACDBIN( g_trac_sbe, "updateSeepromSide: Info", + sbeInfo_data, sbeInfoSize); + TRACDBIN( g_trac_sbe, "updateSeepromSide: Info ECC", + sbeInfo_data_ECC, sbeInfoSize_ECC); + + err = deviceWrite( i_sbeState.target, + sbeInfo_data_ECC, + sbeInfoSize_ECC, + DEVICE_EEPROM_ADDRESS( + i_sbeState.seeprom_side_to_update, + SBE_VERSION_SEEPROM_ADDRESS)); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"updateSeepromSide() - Error " + "Writing SBE Version Info: HUID=0x%.8X, side=%d", + TARGETING::get_huid(i_sbeState.target), + i_sbeState.seeprom_side_to_update); + break; + } + + + // In an effort to avoid an infinite loop of updates, if there + // was an ECC error when reading this SBE Version Information + // while collecting data, read back this data to ensure there + // isn't a permanent ECC error on the SEEPROM + if ( i_sbeState.new_readBack_check == true ) + { + + // Read Back Version Information + err = deviceRead( i_sbeState.target, + sbeInfo_data_ECC_readBack, + sbeInfoSize_ECC, + DEVICE_EEPROM_ADDRESS( + i_sbeState.seeprom_side_to_update, + SBE_VERSION_SEEPROM_ADDRESS)); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"updateSeepromSide() - Error " + "Reading Back SBE Version Info: HUID=0x%.8X, " + "size=%d", + TARGETING::get_huid(i_sbeState.target), + i_sbeState.seeprom_side_to_update); + break; + } + + // Compare ECC data + rc_readBack_ECC_memcmp = memcmp( sbeInfo_data_ECC, + sbeInfo_data_ECC_readBack, + sbeInfoSize_ECC); + + + // Remove ECC + eccStatus = PNOR::ECC::removeECC( sbeInfo_data_ECC_readBack, + sbeInfo_data_readBack, + sbeInfoSize); + + + TRACUCOMP( g_trac_sbe, "updateSeepromSide(): eccStatus=%d, " + "sizeof sI=%d, sI_ECC=%d, rc_ECC=%d", + eccStatus, sbeInfoSize, sbeInfoSize_ECC, + rc_readBack_ECC_memcmp); + + // Fail if uncorrectable ECC or any data miscompare + if ( ( eccStatus == PNOR::ECC::UNCORRECTABLE ) || + ( rc_readBack_ECC_memcmp != 0 ) + ) + { + + // There is an ECC issue with this SEEPROM + + TRACFCOMP( g_trac_sbe,ERR_MRK"updateSeepromSide() - ECC " + "ERROR or Data Miscimpare On SBE Version Read " + "Back: eccStatus=%d, rc_ECC=%d, " + "sI=%d, sI_ECC=%d, HUID=0x%.8X, side=%d", + eccStatus, rc_readBack_ECC_memcmp, + sbeInfoSize, sbeInfoSize_ECC, + TARGETING::get_huid(i_sbeState.target), + i_sbeState.seeprom_side_to_update); + + + /*@ + * @errortype + * @moduleid SBE_GET_SEEPROM_INFO + * @reasoncode SBE_ECC_FAIL + * @userdata1[0:15] ECC Status + * @userdata1[16:31] SEEPROM Side + * @userdata1[32:47] RC on Data Compare with ECC + * @userdata1[48:63] <unused> + * @userdata2[0:31] Size - No Ecc + * @userdata2[32:63] Size - ECC + * @devdesc ECC or Data Miscompare Fail Reading Back + * SBE Verion Information + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_UPDATE_SEEPROMS, + SBE_ECC_FAIL, + FOUR_UINT16_TO_UINT64( + eccStatus, + i_sbeState.seeprom_side_to_update, + rc_readBack_ECC_memcmp, + 0x0), + TWO_UINT32_TO_UINT64(sbeInfoSize, + sbeInfoSize_ECC)); + + err->collectTrace(SBE_COMP_NAME); + err->addHwCallout( i_sbeState.target, + HWAS::SRCI_PRIORITY_HIGH, + HWAS::DELAYED_DECONFIG, + HWAS::GARD_Predictive ); + + + ErrlUserDetailsTarget(i_sbeState.target).addToLog(err); + + break; + } + + } + + /*******************************************/ + /* Update SBE with Customized Image */ + /*******************************************/ + // The Customized Image For This Target Still Resides In + // The SBE Update VMM Space: SBE_IMG_VADDR = VMM_VADDR_SBE_UPDATE + + + // Inject ECC + // clear out back half of page block to use as temp space + // for ECC injected SBE Image. + rc = mm_remove_pages(RELEASE, + reinterpret_cast<void*> + (SBE_ECC_IMG_VADDR), + SBE_ECC_IMG_MAX_SIZE); + if( rc ) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"updateSeepromSide() - Error " + "from mm_remove_pages : rc=%d, HUID=0x%.8X.", + rc, TARGETING::get_huid(i_sbeState.target) ); + /*@ + * @errortype + * @moduleid SBE_UPDATE_SEEPROMS + * @reasoncode SBE_REMOVE_PAGES_FOR_EC + * @userdata1 Requested Address + * @userdata2 rc from mm_remove_pages + * @devdesc updateProcessorSbeSeeproms> mm_remove_pages + * RELEASE failed + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_UPDATE_SEEPROMS, + SBE_REMOVE_PAGES_FOR_EC, + TO_UINT64(SBE_ECC_IMG_VADDR), + TO_UINT64(rc)); + //Target isn't directly related to fail, but could be useful + // to see how far we got before failing. + ErrlUserDetailsTarget(i_sbeState.target + ).addToLog(err); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + break; + } + + + //align size, calculate ECC size + size_t sbeImgSize = ALIGN_8(i_sbeState.customizedImage_size); + size_t sbeEccImgSize = static_cast<size_t>(sbeImgSize*9/8); + + + assert(sbeEccImgSize <= SBE_ECC_IMG_MAX_SIZE, + "updateSeepromSide() SBE Image with ECC too large"); + + TRACUCOMP( g_trac_sbe, INFO_MRK"updateSeepromSide(): " + "SBE_VADDR=0x%.16X, ECC_VADDR=0x%.16X, size=0x%.8X, " + "eccSize=0x%.8X", + SBE_IMG_VADDR, + SBE_ECC_IMG_VADDR, + sbeImgSize, + sbeEccImgSize ); + + PNOR::ECC::injectECC(reinterpret_cast<uint8_t*>(SBE_IMG_VADDR), + sbeImgSize, + reinterpret_cast<uint8_t*> + (SBE_ECC_IMG_VADDR)); + + TRACDBIN(g_trac_sbe,"updateSeepromSide()-start of IMG - no ECC", + reinterpret_cast<void*>(SBE_IMG_VADDR), 0x80); + TRACDBIN(g_trac_sbe,"updateSeepromSide()-start of IMG - ECC", + reinterpret_cast<void*>(SBE_ECC_IMG_VADDR), 0x80); + + + //Write new data to seeprom + TRACFCOMP( g_trac_sbe, INFO_MRK"updateSeepromSide(): Write New " + "SBE Image for Target 0x%X to Seeprom %d", + TARGETING::get_huid(i_sbeState.target), + i_sbeState.seeprom_side_to_update ); + + //Write image to indicated side + err = deviceWrite(i_sbeState.target, + reinterpret_cast<void*> + (SBE_ECC_IMG_VADDR), + sbeEccImgSize, + DEVICE_EEPROM_ADDRESS( + i_sbeState.seeprom_side_to_update, + SBE_IMAGE_SEEPROM_ADDRESS)); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"updateSeepromSide() - Error " + "writing new SBE image to size=%d. HUID=0x%.8X." + "SBE_VADDR=0x%.16X, ECC_VADDR=0x%.16X, size=0x%.8X, " + "eccSize=0x%.8X, EEPROM offset=0x%X", + i_sbeState.seeprom_side_to_update, + TARGETING::get_huid(i_sbeState.target), + SBE_IMG_VADDR, SBE_ECC_IMG_VADDR, sbeImgSize, + sbeEccImgSize, SBE_IMAGE_SEEPROM_ADDRESS); + break; + } + + }while(0); + + // Free allocated memory + free( sbeInfo_data ); + free( sbeInfo_data_ECC); + free( sbeInfo_data_readBack ); + free( sbeInfo_data_ECC_readBack ); + + return err; + + + } + + + +///////////////////////////////////////////////////////////////////// + errlHndl_t getTargetUpdateActions(sbeTargetState_t& io_sbeState) + { + TRACDCOMP( g_trac_sbe, + ENTER_MRK"getTargetUpdateActions()"); + errlHndl_t err = NULL; + + bool seeprom_0_isDirty = false; + bool seeprom_1_isDirty = false; + bool current_side_isDirty = false; + bool alt_side_isDirty = false; + + + do{ + + + + /**************************************************************/ + /* Compare SEEPROM 0 with PNOR and Customized Image CRC -- */ + /* -- dirty or clean? */ + /**************************************************************/ + if ( + // Check PNOR and SEEPROM 0 Version + (0 != memcmp(&(io_sbeState.pnorVersion), + &(io_sbeState.seeprom_0_ver.image_version), + SBE_IMAGE_VERSION_SIZE)) + || + // Check CRC and SEEPROM 0 CRC + (0 != memcmp(&(io_sbeState.customizedImage_crc), + &(io_sbeState.seeprom_0_ver.data_crc), + SBE_DATA_CRC_SIZE)) + ) + { + seeprom_0_isDirty = true; + } + + + + /**************************************************************/ + /* Compare SEEPROM 1 with PNOR and Customized Image CRC -- */ + /* -- dirty or clean? */ + /**************************************************************/ + if ( + // Check PNOR and SEEPROM 1 Version + (0 != memcmp(&(io_sbeState.pnorVersion), + &(io_sbeState.seeprom_1_ver.image_version), + SBE_IMAGE_VERSION_SIZE)) + || + // Check CRC and SEEPROM 1 CRC + (0 != memcmp(&(io_sbeState.customizedImage_crc), + &(io_sbeState.seeprom_1_ver.data_crc), + SBE_DATA_CRC_SIZE)) + ) + { + seeprom_1_isDirty = true; + } + + + + /**************************************************************/ + /* Determine what side to update */ + /**************************************************************/ + + //If all clean, we are done: + if((!seeprom_0_isDirty) && + (!seeprom_1_isDirty)) + { + break; + } + + //Need to update something + if( io_sbeState.cur_seeprom_side == SBE_SEEPROM0 ) + { + current_side_isDirty = seeprom_0_isDirty; + alt_side_isDirty = seeprom_1_isDirty; + } + else + { + current_side_isDirty = seeprom_1_isDirty; + alt_side_isDirty = seeprom_0_isDirty; + } + + + // Set system_situation - bits defined in sbe_update.H + uint8_t system_situation = 0x00; + + // Bit 0: current_side is permanent (0) or temp (1) + // -- defaulted to 0 (cur=perm) above + if ( io_sbeState.cur_seeprom_side != + io_sbeState.permanent_seeprom_side ) + { + system_situation |= SITUATION_CUR_IS_TEMP; + } + + // Bit 1: current_side clean (0) or dirty (1) + // -- defaulted to 0 (clean) above + if ( current_side_isDirty ) + { + system_situation |= SITUATION_CUR_IS_DIRTY; + } + + // Bit 2: alt_side is clean (0) or dirty (1) + if ( alt_side_isDirty ) + { + system_situation |= SITUATION_ALT_IS_DIRTY; + } + + + // Call function to update actions + decisionTreeForUpdates(io_sbeState, system_situation); + + TRACUCOMP( g_trac_sbe, "getTargetUpdateActions() - system_situation" + "= 0x%.2X, actions=0x%.8X, Update EEPROM=0x%X", + system_situation, + io_sbeState.update_actions, + io_sbeState.seeprom_side_to_update); + + + /**************************************************************/ + /* Setup new SBE Image Version Info */ + /**************************************************************/ + // Setup new SBE Image Version Info + memset(&(io_sbeState.new_seeprom_ver), + 0x0, + sizeof(sbeSeepromVersionInfo_t)); + + + io_sbeState.new_seeprom_ver.struct_version = + SBE_SEEPROM_STRUCT_VERSION; + + memcpy( &(io_sbeState.new_seeprom_ver.image_version), + &(io_sbeState.pnorVersion), + SBE_IMAGE_VERSION_SIZE); + + memcpy( &(io_sbeState.new_seeprom_ver.data_crc), + &(io_sbeState.customizedImage_crc), + SBE_DATA_CRC_SIZE); + + // If there was an ECC fail on either SEEPROM, do a read-back + // Check when writing this information to the SEEPROM + io_sbeState.new_readBack_check = ( + io_sbeState.seeprom_0_ver_ECC_fail || + io_sbeState.seeprom_1_ver_ECC_fail); + + + TRACDBIN( g_trac_sbe, + "getTargetUpdateActions() - New SBE Version Info", + &(io_sbeState.new_seeprom_ver), + sizeof(sbeSeepromVersionInfo_t)); + + /**************************************************************/ + /* Update MVPD Struct to write back */ + /**************************************************************/ + + // Note: mvpdSbKeyword.flags updated above + memset(&(io_sbeState.mvpdSbKeyword), + 0, + sizeof(sbeSeepromVersionInfo_t)); + + if ( io_sbeState.seeprom_side_to_update == EEPROM::SBE_PRIMARY ) + { + memcpy( &(io_sbeState.mvpdSbKeyword.seeprom_0_data_crc), + &(io_sbeState.customizedImage_crc), + SBE_DATA_CRC_SIZE); + + memcpy( &(io_sbeState.mvpdSbKeyword.seeprom_0_short_version), + &(io_sbeState.pnorVersion), + SBE_MVPD_SHORT_IMAGE_VERSION_SIZE); + } + else // EEPROM::SBE_Backup + { + memcpy( &(io_sbeState.mvpdSbKeyword.seeprom_1_data_crc), + &(io_sbeState.customizedImage_crc), + SBE_DATA_CRC_SIZE); + + memcpy( &(io_sbeState.mvpdSbKeyword.seeprom_1_short_version), + &(io_sbeState.pnorVersion), + SBE_MVPD_SHORT_IMAGE_VERSION_SIZE); + } + + + + + + + }while(0); + + return err; + + + } + +///////////////////////////////////////////////////////////////////// + void decisionTreeForUpdates(sbeTargetState_t& io_sbeState, + uint8_t i_system_situation) + { + + + uint32_t l_actions = CLEAR_ACTIONS; + io_sbeState.update_actions = CLEAR_ACTIONS; + io_sbeState.seeprom_side_to_update = EEPROM::LAST_CHIP_TYPE; + + + do{ + + // To be safe, we're only look at the bits defined in sbe_update.H + i_system_situation &= SITUATION_ALL_BITS_MASK; + + // @todo RTC 47033 set bit 1 in MVPD SB flag byte to + // represent the which SEEPROM the FSP should reboot from + + + switch ( i_system_situation ) + { + case ( SITUATION_CUR_IS_TEMP | + SITUATION_CUR_IS_DIRTY | + SITUATION_ALT_IS_DIRTY ) : + + // 0xE0: cur=temp, cur=dirty, alt=dirty + // Treat like 0xC0 + // not sure why we booted off of temp + + case ( SITUATION_CUR_IS_TEMP | + SITUATION_CUR_IS_DIRTY | + SITUATION_ALT_IS_CLEAN ) : + + + // 0xC0: cur=temp, cur=dirty, alt=clean + // Bad path: we shouldn't be booting to dirty side + // Update Alt and re-IPL to it + // Update MVPD flag: make cur=perm (because we know it + // works a bit) + + l_actions |= IPL_RESTART; + l_actions |= DO_UPDATE; + + // Set Update side to alt + io_sbeState.seeprom_side_to_update = + ( io_sbeState.alt_seeprom_side == SBE_SEEPROM0 ) + ? EEPROM::SBE_PRIMARY : EEPROM::SBE_BACKUP ; + + // Update MVPD flag make cur=perm + ( io_sbeState.cur_seeprom_side == SBE_SEEPROM0 ) ? + // clear bit 0 + io_sbeState.mvpdSbKeyword.flags &= ~PERMANENT_FLAG_MASK + : //set bit 0 + io_sbeState.mvpdSbKeyword.flags |= PERMANENT_FLAG_MASK; + + + TRACFCOMP( g_trac_sbe, INFO_MRK"decisionTreeForUpdates() - " + "cur=temp/dirty. Update alt. Re-IPL. " + "Update MVPD flag. " + "(d_t=0x%.2X, act=0x%.8X)", + i_system_situation, l_actions); + + + break; + + case ( SITUATION_CUR_IS_TEMP | + SITUATION_CUR_IS_CLEAN | + SITUATION_ALT_IS_DIRTY ) : + + // 0xA0: cur=temp, cur=clean, alt=dirty + // Common 2nd step of Code Update path + // Update Alt and Continue IPL + // Update MVPD flag: make cur=perm + + l_actions |= DO_UPDATE; + + // Set Update side to alt + io_sbeState.seeprom_side_to_update = + ( io_sbeState.alt_seeprom_side == SBE_SEEPROM0 ) + ? EEPROM::SBE_PRIMARY : EEPROM::SBE_BACKUP ; + + + // MVPD flag Update + // Update MVPD flag make cur=perm + ( io_sbeState.cur_seeprom_side == SBE_SEEPROM0 ) ? + // clear bit 0 + io_sbeState.mvpdSbKeyword.flags &= ~PERMANENT_FLAG_MASK + : //set bit 0 + io_sbeState.mvpdSbKeyword.flags |= PERMANENT_FLAG_MASK; + + + TRACFCOMP( g_trac_sbe, INFO_MRK"decisionTreeForUpdates() - " + "cur=temp/clean, alt=dirty. " + "Update alt. Continue IPL. Update MVPD flag." + "(d_t=0x%.2X, act=0x%.8X)", + i_system_situation, l_actions); + + break; + + + case ( SITUATION_CUR_IS_TEMP | + SITUATION_CUR_IS_CLEAN | + SITUATION_ALT_IS_CLEAN ) : + + // 0x80: cur=temp, cur=clean, alt=clean + // Should've broke earlier -- both sides are clean, + // but handle just in case + // Not sure why cur=temp, but do nothing + + l_actions = CLEAR_ACTIONS; + + TRACFCOMP( g_trac_sbe, INFO_MRK"decisionTreeForUpdates() - " + "Both sides clean-no updates. cur was temp. " + "Continue IPL. (d_t=0x%.2X, act=0x%.8X)", + i_system_situation, l_actions); + + break; + + + case ( SITUATION_CUR_IS_PERM | + SITUATION_CUR_IS_DIRTY | + SITUATION_ALT_IS_DIRTY ) : + + // 0x60: cur=perm, cur=dirty, alt=dirty + // Common situation: likely first step of code update + // Update alt and re-ipl + l_actions |= IPL_RESTART; + l_actions |= DO_UPDATE; + + // Set Update side to alt + io_sbeState.seeprom_side_to_update = + ( io_sbeState.alt_seeprom_side == SBE_SEEPROM0 ) + ? EEPROM::SBE_PRIMARY : EEPROM::SBE_BACKUP ; + + TRACFCOMP( g_trac_sbe, INFO_MRK"decisionTreeForUpdates() - " + "cur=perm/dirty, alt=dirty. Update alt. re-IPL. " + "(d_t=0x%.2X, act=0x%.8X)", + i_system_situation, l_actions); + + break; + + + case ( SITUATION_CUR_IS_PERM | + SITUATION_CUR_IS_DIRTY | + SITUATION_ALT_IS_CLEAN ) : + + // 0x40: cur=perm, cur=dirty, alt=clean + // @todo RTC 40733 - Ask FSP if we just asked for re-IPL + // for now just continue IPL + TRACFCOMP( g_trac_sbe, INFO_MRK"decisionTreeForUpdates() - " + "cur=perm/dirty, alt=clean. Continue IPL. " + "(d_t=0x%.2X, act=0x%.8X)", + i_system_situation, l_actions); + break; + + + case ( SITUATION_CUR_IS_PERM | + SITUATION_CUR_IS_CLEAN | + SITUATION_ALT_IS_DIRTY ) : + + // 0x20: cur=perm, cur=clean, alt=dirty + // Not sure why alt is dirty, but update alt and + // continue IPL + + l_actions |= DO_UPDATE; + + // Set Update side to alt + io_sbeState.seeprom_side_to_update = + ( io_sbeState.alt_seeprom_side == SBE_SEEPROM0 ) + ? EEPROM::SBE_PRIMARY : EEPROM::SBE_BACKUP ; + + TRACFCOMP( g_trac_sbe, INFO_MRK"decisionTreeForUpdates() - " + "cur=perm/clean, alt=dirty. " + "Update alt. Continue IPL. " + "(d_t=0x%.2X, act=0x%.8X)", + i_system_situation, l_actions); + + break; + + + case ( SITUATION_CUR_IS_PERM | + SITUATION_CUR_IS_CLEAN | + SITUATION_ALT_IS_CLEAN ) : + + // 0x0: cur=perm, cur=clean, alt=clean + // Should've broke earlier -- both sides are clean, + // but handle just in case + l_actions = CLEAR_ACTIONS; + + TRACFCOMP( g_trac_sbe, INFO_MRK"decisionTreeForUpdates() - " + "Both sides clean-no updates. cur was temp. " + "Continue IPL. (d_t=0x%.2X, act=0x%.8X)", + i_system_situation, l_actions); + + break; + + default: + + TRACFCOMP( g_trac_sbe, INFO_MRK"decisionTreeForUpdates() - " + "Unsupported Scenario. Just Continue IPL. " + "(d_t=0x%.2X, act=0x%.8X)", + i_system_situation, l_actions); + + break; + } + + + // Set actions + io_sbeState.update_actions = static_cast<sbeUpdateActions_t> + (l_actions); + + TRACUCOMP( g_trac_sbe, "decisionTreeForUpdates() - i_system_situation= " + "0x%.2X, actions=0x%.8X, Update EEPROM=0x%X, doU=%d, " + "reIpl=%d", + i_system_situation, + io_sbeState.update_actions, + io_sbeState.seeprom_side_to_update, + io_sbeState.update_actions && DO_UPDATE, + io_sbeState.update_actions && IPL_RESTART); + + }while(0); + + return; + + + } + + +///////////////////////////////////////////////////////////////////// + errlHndl_t performUpdateActions(sbeTargetState_t& io_sbeState) + { + TRACDCOMP( g_trac_sbe, + ENTER_MRK"performUpdateActions()"); + errlHndl_t err = NULL; + + do{ + + + /**************************************************************/ + /* Update Actions: */ + /* 1) Update SEEPROM */ + /* 2) Update MVPD */ + /**************************************************************/ + + /**************************************************************/ + /* 1) Update SEEPROM */ + /**************************************************************/ + err = updateSeepromSide(io_sbeState); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"performUpdateActions() - " + "updateProcessorSbeSeeproms() failed. HUID=0x%.8X.", + TARGETING::get_huid(io_sbeState.target)); + continue; + } + + /**************************************************************/ + /* 2) Update MVPD */ + /**************************************************************/ + //Update MVPD anytime we do any sort of SBE Update. + err = getSetMVPDVersion(io_sbeState.target, + MVPDOP_WRITE, + io_sbeState.mvpdSbKeyword); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"performUpdateActions() - " + "Error Updating MVPD with new SBE Image Info " + "HUID=0x%.8X, rc=0x%.4x", + TARGETING::get_huid(io_sbeState.target), + err->reasonCode()); + break; + } + + + + }while(0); + + return err; + + + } + +///////////////////////////////////////////////////////////////////// + // @todo RTC 47033 - Likely to remove this function because creating a + // CRC from the customized image seems more efficient. + errlHndl_t getDataCrc(TARGETING::Target* i_target, + uint32_t& o_data_crc) + { + TRACDCOMP( g_trac_sbe, + ENTER_MRK"getDataCrc"); + + errlHndl_t err = NULL; + size_t data_size = 0; + uint8_t* data_ptr = NULL; + uint8_t index = 0; + + size_t mvpd_pdG_size = 0; + uint8_t* mvpd_pdG_data_ptr = NULL; + size_t mvpd_pdR_size = 0; + uint8_t* mvpd_pdR_data_ptr = NULL; + + o_data_crc = 0x0; + + do{ + + + /*******************************************/ + /* Get #G Ring Data from MVPD */ + /*******************************************/ + // Note: First read with NULL for o_buffer sets vpdSize to the + // correct length + err = deviceRead( i_target, + NULL, + mvpd_pdG_size, + DEVICE_MVPD_ADDRESS( MVPD::CP00, + MVPD::pdG ) ); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getDataCrc() - MVPD failure getting pdG keyword size HUID=0x%.8X", + TARGETING::get_huid(i_target)); + break; + } + + // Create buffer to capture the data + mvpd_pdG_data_ptr = static_cast<uint8_t*>(malloc(mvpd_pdG_size)); + + err = deviceRead( i_target, + mvpd_pdG_data_ptr, + mvpd_pdG_size, + DEVICE_MVPD_ADDRESS( MVPD::CP00, + MVPD::pdG ) ); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getDataCrc() - MVPD failure read pdG data HUID=0x%.8X", + TARGETING::get_huid(i_target)); + break; + } + + + /*******************************************/ + /* Get #R Ring Data from MVPD */ + /*******************************************/ + // Note: First read with NULL for o_buffer sets vpdSize to the + // correct length + err = deviceRead( i_target, + NULL, + mvpd_pdR_size, + DEVICE_MVPD_ADDRESS( MVPD::CP00, + MVPD::pdR ) ); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getDataCrc() - MVPD failure getting pdR keyword size HUID=0x%.8X", + TARGETING::get_huid(i_target)); + break; + } + + // Create buffer to capture the data + mvpd_pdR_data_ptr = static_cast<uint8_t*>(malloc(mvpd_pdR_size)); + + err = deviceRead( i_target, + mvpd_pdR_data_ptr, + mvpd_pdR_size, + DEVICE_MVPD_ADDRESS( MVPD::CP00, + MVPD::pdR ) ); + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getDataCrc() - MVPD failure read pdG data HUID=0x%.8X", + TARGETING::get_huid(i_target)); + break; + } + + + /**********************************************/ + /* Concatenate the Data and compute the CRC */ + /**********************************************/ + // Add up all the sizes and create a buffer + data_size = mvpd_pdG_size + mvpd_pdR_size; + data_ptr = static_cast<uint8_t*>(malloc(data_size)); + + + memcpy( data_ptr, mvpd_pdG_data_ptr, mvpd_pdG_size); + index = mvpd_pdG_size; + + memcpy( &(data_ptr[index]), mvpd_pdR_data_ptr, mvpd_pdR_size); + + o_data_crc = Util::crc32_calc(data_ptr, data_size); + + + }while(0); + + // Free allocated memory + free(mvpd_pdG_data_ptr); + free(mvpd_pdR_data_ptr); + + + TRACUCOMP( g_trac_sbe, EXIT_MRK"getDataCrc: o_data_crc= 0x%.4x, " + "pdG_size=%d, pdR_size=%d", + o_data_crc, mvpd_pdG_size, mvpd_pdR_size); + + return err; + + } + + + +///////////////////////////////////////////////////////////////////// + uint32_t trimBitMask(uint32_t i_mask, + size_t i_maxBits) + { + TRACDCOMP( g_trac_sbe, + ENTER_MRK"trimBitMask(i_mask=0x%.8X, i_maxBits=0x%.8X)", + i_mask, i_maxBits); + uint32_t retMask = i_mask; + + + while(__builtin_popcount(retMask) > static_cast<int32_t>(i_maxBits)) + { + retMask ^= 0x1 << static_cast<uint32_t>(__builtin_ctz(retMask)); + } + + TRACDCOMP( g_trac_sbe, + EXIT_MRK"trimBitMask(): retMask=0x%.8X", + retMask); + + return retMask; + } + + +///////////////////////////////////////////////////////////////////// + errlHndl_t createSbeImageVmmSpace(void) + { + + TRACDCOMP( g_trac_sbe, + ENTER_MRK"createSbeImageVmmSpace"); + + int64_t rc = 0; + errlHndl_t err = NULL; + + do{ + + //Make sure procedure constants keep within expected range. + assert((FIXED_SEEPROM_WORK_SPACE <= VMM_SBE_UPDATE_SIZE/2), + "createSbeImageVmmSpace() FIXED_SEEPROM_WORK_SPACE too large"); + assert((FIXED_RING_BUF_SIZE <= VMM_SBE_UPDATE_SIZE/4), + "createSbeImageVmmSpace() FIXED_RING_BUF_SIZE too large"); + + + // Create a memory block to serve as XIP Customize scratch space + // NOTE: using mm_alloc_block since this code is running before we + // have mainstore and we must have contiguous blocks of memory for + // the customize procedure to use. + rc = mm_alloc_block( NULL, + reinterpret_cast<void*> + (VMM_VADDR_SBE_UPDATE), + VMM_SBE_UPDATE_SIZE); + + if( rc ) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"createSbeImageVmmSpace() - " + "Error from mm_alloc_block : rc=%d", rc ); + /*@ + * @errortype + * @moduleid SBE_CREATE_TEST_SPACE + * @reasoncode SBE_ALLOC_BLOCK_FAIL + * @userdata1 Requested Address + * @userdata2 rc from mm_alloc_block + * @devdesc updateProcessorSbeSeeproms> Error + * from mm_alloc_block + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_CREATE_TEST_SPACE, + SBE_ALLOC_BLOCK_FAIL, + TO_UINT64(VMM_VADDR_SBE_UPDATE), + TO_UINT64(rc)); + + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + + break; + } + + rc = mm_set_permission(reinterpret_cast<void*> + (VMM_VADDR_SBE_UPDATE), + VMM_SBE_UPDATE_SIZE, + WRITABLE | ALLOCATE_FROM_ZERO ); + if( rc ) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"createSbeImageVmmSpace() - Error from mm_set_permission : rc=%d", rc ); + /*@ + * @errortype + * @moduleid SBE_CREATE_TEST_SPACE + * @reasoncode SBE_SET_PERMISSION_FAIL + * @userdata1 Requested Address + * @userdata2 rc from mm_set_permission + * @devdesc updateProcessorSbeSeeproms> Error from + * mm_set_permission + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_CREATE_TEST_SPACE, + SBE_SET_PERMISSION_FAIL, + TO_UINT64(VMM_VADDR_SBE_UPDATE), + TO_UINT64(rc)); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + break; + } + + }while(0); + + TRACDCOMP( g_trac_sbe, + EXIT_MRK"createSbeImageVmmSpace() - rc =0x%X", rc); + + return err; + + } + + +///////////////////////////////////////////////////////////////////// + errlHndl_t cleanupSbeImageVmmSpace(void) + { + TRACDCOMP( g_trac_sbe, + ENTER_MRK"cleanupSbeImageVmmSpace"); + + errlHndl_t err = NULL; + int64_t rc = 0; + + do{ + + //release all pages in page block to ensure we + //start with clean state + rc = mm_remove_pages(RELEASE, + reinterpret_cast<void*> + (VMM_VADDR_SBE_UPDATE), + VMM_SBE_UPDATE_SIZE); + if( rc ) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"cleanupSbeImageVmmSpace() - " + "Error from mm_remove_pages : rc=%d", rc ); + /*@ + * @errortype + * @moduleid SBE_CLEANUP_TEST_SPACE + * @reasoncode SBE_REMOVE_PAGES_FAIL + * @userdata1 Requested Address + * @userdata2 rc from mm_remove_pages + * @devdesc updateProcessorSbeSeeproms> mm_remove_pages + * RELEASE failed + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBE_CLEANUP_TEST_SPACE, + SBE_REMOVE_PAGES_FAIL, + TO_UINT64(VMM_VADDR_SBE_UPDATE), + TO_UINT64(rc)); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + } + + }while(0); + + + TRACDCOMP( g_trac_sbe, + EXIT_MRK"cleanupSbeImageVmmSpace() - rc =0x%X", rc); + + return err; + + } + + +} //end SBE Namespace diff --git a/src/usr/sbe/sbe_update.H b/src/usr/sbe/sbe_update.H new file mode 100644 index 000000000..bb161dfd0 --- /dev/null +++ b/src/usr/sbe/sbe_update.H @@ -0,0 +1,439 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/sbe/sbe_update.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __SBE_SBE_UPDATE_H +#define __SBE_SBE_UPDATE_H + + +#include <stdint.h> +#include <builtins.h> +#include <errl/errlentry.H> +#include <pnor/pnorif.H> +#include <vmmconst.h> +#include <targeting/common/targetservice.H> +#include <i2c/eepromif.H> + +namespace SBE +{ + /******************************************/ + /* Constants */ + /******************************************/ + // Size of CRC used for version checking + const size_t SBE_DATA_CRC_SIZE = 4; // 4 bytes (32 bits) + + // Using only first 20 bytes of 64-byte sbe_image_version + const size_t SBE_MVPD_SHORT_IMAGE_VERSION_SIZE = 20; + + // Version of Struct stored in SEEPROM + const uint32_t SBE_SEEPROM_STRUCT_VERSION = 0x00000001; + + // Used for locations of SBE_Version and SBE Image on a SEEPROM + const uint64_t SBE_IMAGE_SEEPROM_ADDRESS = 0x400; // 1KB + const uint64_t SBE_VERSION_SEEPROM_ADDRESS = 0x300; // 1KB - 256B + + //Used to read SBE Boot Side from processor + const uint64_t SBE_VITAL_REG_0x0005001C = 0x005001C; + const uint64_t SBE_BOOT_SELECT_MASK = 0x0080000000000000; + + // PNOR SBE and SBEC Partition constants + const uint32_t MAX_SBE_ENTRIES = 9; + const uint32_t SBETOC_EYECATCH = 0x53424500; //'SBE\0' + const uint64_t NONSECURE_VER_EYECATCH = 0x56455253494F4E00; //'VERSION\0' + const uint32_t SUPPORTED_TOC_VER = 0x00000001; + + // MVPD SB Keyword contants + const size_t MVPD_SB_RECORD_SIZE = 49; + const uint8_t PERMANENT_FLAG_MASK = 0x80; + // PERMANENT FLAG = 0 -> indicates 0 is permanent. + const uint8_t SEEPROM_0_PERMANENT_VALUE = 0x00; + const uint8_t SEEPROM_1_PERMANENT_VALUE = 0x80; + // @todo RTC 47033 - add support for bit 1 (0x40): temp boot side + + + // Situation constants -- bits numbered from left to right + const uint8_t SITUATION_ALL_BITS_MASK = 0xE0; + // Bit 0: current side is permanent (=0) or temp (=1) + const uint8_t SITUATION_CUR_IS_PERM = 0x00; + const uint8_t SITUATION_CUR_IS_TEMP = 0x80; + + // Bit 1: current_side clean (=0) or dirty (=1) + const uint8_t SITUATION_CUR_IS_CLEAN = 0x00; + const uint8_t SITUATION_CUR_IS_DIRTY = 0x40; + + // Bit 2: alt side clean (=0) or dirty (=1) + const uint8_t SITUATION_ALT_IS_CLEAN = 0x00; + const uint8_t SITUATION_ALT_IS_DIRTY = 0x20; + + + /******************************************/ + /* Enums */ + /******************************************/ + // Used for MVPD function + enum opType_t + { + MVPDOP_UNKNOWN, // Invalid + MVPDOP_READ, // Read version data from MVPD + MVPDOP_WRITE, // Write version data to MVPD + }; + + // Used to keep track of perm/temp, and cur/alt + enum sbeSeepromSide_t + { + SBE_SEEPROM0, // corresponds to EEPROM::SBE_PRIMARY + SBE_SEEPROM1, // corresponts to EEPROM::SBE_BACKUP + SBE_SEEPROM_INVALID, + }; + + // Actions can be combined + enum sbeUpdateActions_t + { + CLEAR_ACTIONS = 0x00000000, + DO_UPDATE = 0x00000001, + IPL_RESTART = 0x00000002, + CALLOUT_SBE_CODE = 0x00000004, + UNSUPPORTED_SITUATION = 0x00000008, + }; + + + /******************************************/ + /* Structs */ + /******************************************/ + + /** + * @brief Struct containing version information stored on SBE SEEPROMs + * + * NOTE: For ECC purposes, this must be 8-byte aligned, + * so pad data if necessary + * struct_version 1: size = 4+64+4 = 72 (aligned) + */ + struct sbeSeepromVersionInfo_t + { + uint32_t struct_version; + uint8_t image_version[SBE_IMAGE_VERSION_SIZE]; + uint8_t data_crc[SBE_DATA_CRC_SIZE]; + } PACKED; + + + /** + * @brief Struct of individual SBE entry in SBE and SBEC + * Table of Contents in PNOR partitions + */ + struct sbeTocEntry_t + { + uint32_t ec; // Chip EC, right aligned + uint32_t offset; // Offset within partition, in bytes + uint32_t size; // Size of image, in bytes + } PACKED; + + /** + * @brief Layout of Table of Contents at beginning of SBE and + * SBEC Partitions in PNOR + */ + struct sbeToc_t + { + uint32_t eyeCatch; // Expected to contain 'SBE\0' + uint32_t tocVersion; // Version of SBE TOC + sbeTocEntry_t entries[MAX_SBE_ENTRIES]; // Image entries + } PACKED; + + /** + * @brief Layout of SB keyword in MVPD + */ + struct mvpdSbKeyword_t + { + uint8_t flags; // 1 byte for various flags + + uint8_t seeprom_0_data_crc[SBE_DATA_CRC_SIZE]; + uint8_t seeprom_0_short_version[SBE_MVPD_SHORT_IMAGE_VERSION_SIZE]; + + uint8_t seeprom_1_data_crc[SBE_DATA_CRC_SIZE]; + uint8_t seeprom_1_short_version[SBE_MVPD_SHORT_IMAGE_VERSION_SIZE]; + } PACKED; + + + /** + * @brief Contains the SBE state for a given target + */ + struct sbeTargetState_t + { + + // Target Information + TARGETING::Target* target; + bool target_is_master; + uint8_t ec; + + // Current Target SBE State Information + sbe_image_version_t pnorVersion; + mvpdSbKeyword_t mvpdSbKeyword; + + sbeSeepromVersionInfo_t seeprom_0_ver; + sbeSeepromVersionInfo_t seeprom_1_ver; + + bool seeprom_0_ver_ECC_fail; + bool seeprom_1_ver_ECC_fail; + + sbeSeepromSide_t cur_seeprom_side; // aka 'booted' side + sbeSeepromSide_t alt_seeprom_side; + sbeSeepromSide_t permanent_seeprom_side; + + // Customized Image Information for this Target + size_t customizedImage_size; + uint32_t customizedImage_crc; + + // Update Fields and New Fields to be Written to the Target + sbeUpdateActions_t update_actions; + EEPROM::eeprom_chip_types_t seeprom_side_to_update; + + sbeSeepromVersionInfo_t new_seeprom_ver; + bool new_readBack_check; + + }; + + + + /******************************************/ + /* Functions -- High Level Functions */ + /******************************************/ + + /** + * @brief Collects SBE Information for a specifc target + * + * @param[io/out] io_sbeState Struct containing SBE State of the target + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t getSbeInfoState(sbeTargetState_t& io_sbeState); + + /** + * @brief Analyze and Determine Update Actions for a specific target + * + * @param[io/out] io_sbeState Struct containing SBE State of the target + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t getTargetUpdateActions(sbeTargetState_t& io_sbeState); + + /** + * @brief Performs the Update Actions for a specific target + * + * @param[io/out] io_sbeState Struct containing SBE State of the target + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t performUpdateActions(sbeTargetState_t& io_sbeState); + + + /******************************************/ + /* Functions -- System Access */ + /******************************************/ + + /** + * @brief Read or Write SB Keyword in MVPD + * + * @param[in] i_target Target processor + * + * @param[in] i_op Indicates read or write + * + * @param[io/out] io_sb_keyword Pointer to MVPD SBE Keyword struct + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t getSetMVPDVersion(TARGETING::Target* i_target, + opType_t i_op, + mvpdSbKeyword_t& io_sb_keyword); + + + /** + * @brief Read SBE Version from PNOR + * + * @param[in] i_pnorImgHdrPtr Pointer to Image Header in PNOR + * + * @param[out] o_version Pointer to SBE Version struct + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t readPNORVersion(void*& i_pnorImgHdrPtr, + sbe_image_version_t& o_version); + + + /** + * @brief Customize SBE Image for current Processor + * + * @param[in] i_target Target processor to customize + * + * @param[in] i_sbePnorPtr Pointer to SBE Image in PNOR + * Expected that this pointer was found with + * findSBEInPnor() function and is past any + * image header + * + * @param[in] i_maxImgSize Maximum size of customized image + * + * @param[out] io_imgPtr Pointer to SBE image in memory + * Memory from this pointer through + * i_maxImgSize is expected to be pre-alloacted + * + * @param[out] o_actImgSize Actual size of the customized image + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t procCustomizeSbeImg(TARGETING::Target* i_target, + void* i_sbePnorPtr, + size_t i_maxImgSize, + void* io_imgPtr, + size_t& o_actImgSize); + + /** + @brief Collect data for CRC, Concatenate the data, then compute the CRC + * + * @param[in] i_target Target processor + * + * @param[out] o_data_crc CRC computed from concatenated collected data + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t getDataCrc(TARGETING::Target* i_target, + uint32_t& o_data_crc); + + + /** + * @brief Determines which Seeprom was used to boot the SBE + * + * @param[in] i_target Target processor to customize + * + * @param[out] o_bootSide The Seeprom the SBE booted from + * + * @return errlHndl_t Error log handle on failure. + */ + + errlHndl_t getSbeBootSeeprom(TARGETING::Target* i_target, + sbeSeepromSide_t& o_bootSide); + + + /** + * @brief Collects Version information from a specific SEEPROM + * + * @param[in] i_target Target processor to customize + * + * @param[in] i_seepromSide The SEEPROM on the target that to collect + * the information from + * + * @param[out] o_info Struct containing the SBE Version Information + * + * @param[out] o_seeprom_ver_ECC_fail Reports if there was an ECC erorr on + * the collected information + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t getSeepromSideVersion(TARGETING::Target* i_target, + EEPROM::eeprom_chip_types_t i_seepromSide, + sbeSeepromVersionInfo_t& o_info, + bool& o_seeprom_ver_ECC_fail); + + /** + * @brief Updates a specific SEEPROM + * + * @param[io/out] io_sbeState Struct containing SBE State of the target + * and the information to be used for updating + * the SBE State of the target + */ + errlHndl_t updateSeepromSide(sbeTargetState_t i_sbeState); + + + + /******************************************/ + /* Functions -- Helper Functions */ + /******************************************/ + + /** + * @brief Determines the Update Actions for a specific target situation + * + * @param[io/out] io_sbeState Struct containing SBE State of the target + * and is updated based on the situation + * + * @param[in] i_system_situation SBE Situation of the target that requires + * analysis to determine Update Actions + * + * @return void + */ + void decisionTreeForUpdates(sbeTargetState_t& io_sbeState, + uint8_t i_system_situation); + + /** + * @brief Creates the memory space needed for SBE Image Customization + * by allocating and setting permissions on VMM_VADDR_SBE_UPDATE + * area defined in vmmconst.H + * + * @param[in] void + * + * @return void + */ + errlHndl_t createSbeImageVmmSpace(void); + + /** + * @brief Cleans up memory space needed for SBE Image Customization + * + * @param[in] void + * + * @return void + */ + errlHndl_t cleanupSbeImageVmmSpace(void); + + /** + * @brief Select best cores to include in SBE Image. + * The output is used to indicate to p8_xip_customize which cores + * should be included in the SBE image. + * + * @param[in] i_target Target processor to use for core selection + * + * @param[in] i_maxCores Maximum number of cores to select for inclusion + * in the SBE Image + * + * @param[out] o_coreMask Core Mask for the target that does not exceed + * the maximum number of cores + * NOTE: bits 16:31 = EX0:EX15 + * This value is used as input into + * p8_xip_customize.C + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t selectBestCores(TARGETING::Target* i_target, + size_t i_maxCores, + uint32_t& o_coreMask); + + + /** + * @brief Reduces bits set in a bit mask until there is a + * a maximum number of bits set + * + * @param[in] i_mask Starting mask to be reduced + * + * @param[in] i_maxBits Maximum number of bits that the + * returned Bit Mask can contain + * + * @return uint32_t Bit Mask + */ + uint32_t trimBitMask(uint32_t i_mask, + size_t i_maxBits); + + +} //end namespace SBE +#endif diff --git a/src/usr/sbe/test/makefile b/src/usr/sbe/test/makefile new file mode 100644 index 000000000..4190b0625 --- /dev/null +++ b/src/usr/sbe/test/makefile @@ -0,0 +1,28 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/sbe/test/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2013 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG +ROOTPATH = ../../../.. + +MODULE = testsbe +TESTS = *.H + +include ${ROOTPATH}/config.mk diff --git a/src/usr/sbe/test/sbeupdatetest.H b/src/usr/sbe/test/sbeupdatetest.H new file mode 100644 index 000000000..e92dc6d4c --- /dev/null +++ b/src/usr/sbe/test/sbeupdatetest.H @@ -0,0 +1,777 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/sbe/test/sbeupdatetest.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __SBEUPDATETEST_H +#define __SBEUPDATETEST_H +/** + * @file sbeupdatetest.H + * + * @brief Test cases for SBE Update code + */ +#include <sys/time.h> + +#include <cxxtest/TestSuite.H> +#include <errl/errlmanager.H> +#include <errl/errlentry.H> +#include <devicefw/driverif.H> +#include <vfs/vfs.H> +#include <targeting/common/utilFilter.H> +#include <sbe/sbeif.H> +#include "../sbe_update.H" + + +extern trace_desc_t* g_trac_sbe; + +// Macros for unit testing +//#define TRACUCOMP(args...) TRACFCOMP(args) +#define TRACUCOMP(args...) + +const char SBE_BUILD_WINK_NAME[30] = "libbuild_winkle_images.so"; +const char SBE_LIBRARY_NAME[16] = "libsbe.so"; + + +using namespace SBE; + + +void getTargetList( TARGETING::TYPE i_targetType, + TARGETING::TargetHandleList & o_targetList, + bool i_functional ) // if true: return functional targets +{ + + + TARGETING::getAllChips(o_targetList, + i_targetType, + i_functional); + + if ( o_targetList.size() == 0 ) + { + TRACFCOMP( g_trac_sbe, + INFO_MRK"getTargetList() - Found Zero (%d) Targets of " + "type 0x%X", + o_targetList.size(), i_targetType ); + } + + TRACDCOMP( g_trac_sbe, + "getTargetList() - found %d Targets of type 0x%X", + o_targetList.size(), i_targetType ); + + return; +} + +TARGETING::Target* getFunctionalTarget(TARGETING::TYPE i_targetType) +{ + TARGETING::Target * theTarget = NULL; + TRACDCOMP( g_trac_sbe, + "getFunctionalTarget() - Finding Target of Type 0x%0x", + i_targetType ); + + do { + // Get the Processor targets + TARGETING::TargetHandleList targetList; + getTargetList( i_targetType, targetList, true ); + + if( ( 0 == targetList.size() ) || + ( NULL == targetList[0] ) ) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getFunctionalTarget() - Couldn't " + "find functional Target of Type 0x%0x (list.size=%d)", + i_targetType, targetList.size()); + continue; // continue because have no valid targets + } + + // List is of functional targets, so just return the first one + theTarget = targetList[0]; + + }while(0); + + TRACDCOMP( g_trac_sbe, + "getFunctionalTarget() - Returning Target 0x%0x of Type 0x%0x", + TARGETING::get_huid(theTarget), i_targetType ); + + return theTarget; + +} + + +errlHndl_t loadSbeModule(bool& o_loaded) +{ + errlHndl_t err = NULL; + o_loaded = false; + + if(!VFS::module_is_loaded(SBE_LIBRARY_NAME)) + { + err = VFS::module_load(SBE_LIBRARY_NAME); + if(err) + { + // Don't use g_trac_sbe - libsbe might not be loaded + TS_FAIL("loadSbeModule() - %s load failed", SBE_LIBRARY_NAME ); + + } + else + { + o_loaded = true; + } + } + + // This module is needed for certain HW procedure (like p8_xip_customize()) + if(!VFS::module_is_loaded(SBE_BUILD_WINK_NAME)) + { + err = VFS::module_load(SBE_BUILD_WINK_NAME); + if(err) + { + // Don't use g_trac_sbe - libsbe might not be loaded + TS_FAIL("loadSbeModule() - %s load failed", SBE_BUILD_WINK_NAME); + } + else + { + o_loaded = true; + } + } + + return err; +} + +errlHndl_t unloadSbeModule() +{ + errlHndl_t err = NULL; + + err = VFS::module_unload(SBE_LIBRARY_NAME); + if(err) + { + // Don't use g_trac_sbe - libsbe might be unloaded + TS_FAIL("unloadSbeModule() - %s unload failed", SBE_LIBRARY_NAME ); + + // No break or return - still try and unload other module + } + + err = VFS::module_unload(SBE_BUILD_WINK_NAME); + if(err) + { + // Don't use g_trac_sbe - libsbe might be unloaded + TS_FAIL("unloadSbeModule() - %s unload failed", SBE_BUILD_WINK_NAME); + } + + return err; +} + + +class SBEUpdateTest: public CxxTest::TestSuite +{ + public: + + /** + * @brief This function will test __trimCoreMask + */ + void testTrimBitMask( void ) + { + + uint64_t fails = 0x0; + uint64_t total = 0x0; + + do{ + + TRACFCOMP( g_trac_sbe, + ENTER_MRK"testTrimBitMask()" ); + + struct + { + uint32_t inMask; + uint32_t maxBits; + uint32_t outMask; + } testData[] = + { + {0xFFFFFFFF, 10, 0xFFC00000}, + {0xFFFFFFFF, 32, 0xFFFFFFFF}, + {0x0000FF00, 4, 0x0000F000}, + {0x0000FF00, 8, 0x0000FF00}, + {0x0000FF50, 16, 0x0000FF50}, + {0x000000FF, 5, 0x000000F8}, + {0x000000FF, 8, 0x000000FF}, + }; + const uint32_t NUM_TESTS = sizeof(testData)/sizeof(testData[0]); + + uint32_t retMask = 0; + + for(uint32_t i=0; i < NUM_TESTS; i++) + { + retMask = trimBitMask(testData[i].inMask, + testData[i].maxBits); + total++; + if(retMask != testData[i].outMask) + { + fails++; + TRACFCOMP( g_trac_sbe, ERR_MRK"testTrimBitMask() - i=%d, " + "retMask=0x%.8X, expMask=0x%.8X", + i, retMask, testData[i].outMask); + TS_FAIL("testTrimBitMask() - Return data did not match " + "expected data."); + } + } + + }while(0); + + TRACFCOMP( g_trac_sbe, + EXIT_MRK"testTrimBitMask - %d/%d fails", + fails, total ); + } + + /** + * @brief This function will test SBE Update's ability + * to find SBE images in PNOR + */ + + void testFindSbeInPnor ( void ) + { + errlHndl_t err = NULL; + uint64_t fails = 0x0; + uint64_t total = 0x0; + + TARGETING::Target* theTarget = NULL; + void* sbeImgPtr = NULL; + size_t sbeImgSize = 0; + sbe_image_version_t version; + + do{ + + TRACFCOMP( g_trac_sbe, + ENTER_MRK"testFindSbeInPnor()" ); + + /****************************************************/ + /* Find a valid Processor */ + /****************************************************/ + theTarget = getFunctionalTarget(TARGETING::TYPE_PROC); + if(theTarget == NULL) + { + total++; + fails++; + TS_FAIL("testReadSbeFromPnor() - No Functional Proc Targets found!"); + break; + } + + total++; + err = findSBEInPnor(theTarget, + sbeImgPtr, + sbeImgSize, + &version); + + if(err || (sbeImgPtr == NULL) || (sbeImgSize == 0) ) + { + fails++; + TRACFCOMP( g_trac_sbe, ERR_MRK"testFindSbeInPnor() - failure " + "finding Proc SBE image for uid=0x%X, ec=0x%.2X" + "sbeImgPtr=%p, sbeImgSize=0x%x", + TARGETING::get_huid(theTarget), + theTarget->getAttr<TARGETING::ATTR_EC>(), + sbeImgPtr, sbeImgSize ); + TS_FAIL("testFindSbeInPnor() -failure finding SBE image!"); + errlCommit( err, + SBE_COMP_ID ); + + } + TRACDBIN(g_trac_sbe, "testFindSbeInPnor()-Proc PNOR Version", &version, sizeof(version)); + TRACDBIN(g_trac_sbe, "testFindSbeInPnor()-Proc PNOR Image", sbeImgPtr, 0x80); + + + /****************************************************/ + /* Find a valid MemBuf */ + /****************************************************/ + theTarget = getFunctionalTarget(TARGETING::TYPE_MEMBUF); + if(theTarget == NULL) + { + total++; + fails++; + TS_FAIL("testReadSbeFromPnor() - No Functional MemBuf Targets found!"); + break; + } + + total++; + err = findSBEInPnor(theTarget, + sbeImgPtr, + sbeImgSize, + &version); + + if(err || (sbeImgPtr == NULL) || (sbeImgSize == 0) ) + { + fails++; + TRACFCOMP( g_trac_sbe, ERR_MRK"testFindSbeInPnor() - failure " + "finding MemBuf SBE image for uid=0x%X, ec=0x%.2X, " + "sbeImgPtr=%p, sbeImgSize=0x%x", + TARGETING::get_huid(theTarget), + theTarget->getAttr<TARGETING::ATTR_EC>(), + sbeImgPtr, sbeImgSize ); + TS_FAIL("testFindSbeInPnor() -failure finding SBE image!"); + errlCommit( err, + SBE_COMP_ID ); + + } + TRACDBIN(g_trac_sbe, "testFindSbeInPnor()-MEMBUF PNOR Version", &version, sizeof(version)); + TRACDBIN(g_trac_sbe, "testFindSbeInPnor()-MEMBUF PNOR Image", sbeImgPtr, 0x80); + + + /****************************************************/ + /* Verify invalid target Type is not found */ + /****************************************************/ + // test with system target -- safe that this target is configured + TARGETING::TargetService & tS = TARGETING::targetService(); + tS.getTopLevelTarget( theTarget ); + if(theTarget == NULL) + { + total++; + fails++; + TS_FAIL("testFindSbeInPnor() - System target Not Found!"); + break; + } + + total++; + err = findSBEInPnor(theTarget, + sbeImgPtr, + sbeImgSize); + + if(err) + { + TRACFCOMP( g_trac_sbe, "testFindSbeInPnor() - Did not " + "find system-target SBE image as expected: " + "uid=0x%X, err=0x%X", + TARGETING::get_huid(theTarget), + err->reasonCode() ); + delete err; + err = NULL; + } + else + { + fails++; + TRACFCOMP( g_trac_sbe, ERR_MRK"testFindSbeInPnor() - Fail " + " expected when searching for invalid target " + "(Xbus): uid=0x%X, ec=0x%.2X", + TARGETING::get_huid(theTarget), + theTarget->getAttr<TARGETING::ATTR_EC>() ); + + TS_FAIL("testFindSbeInPnor() - Fail expected when searching for invalid EC level!"); + errlCommit( err, + SBE_COMP_ID ); + } + + TRACFCOMP( g_trac_sbe, + EXIT_MRK"testFindSbeInPnor - %d/%d fails", + fails, total ); + + }while(0); + + } + + + /** + * @brief This function will run through the functions used to collect + * SBE information on a single target, determine if that target + * needs to be updated, and perform the update. + */ + void testSbeUpdateTarget ( void ) + { + + errlHndl_t err = NULL; + errlHndl_t err_cleanup = NULL; + + uint64_t fails = 0x0; + uint64_t total = 0x0; + sbeTargetState_t sbeState; + + do{ + + /****************************************************/ + /* Get Functional Target and Load SBE Module */ + /****************************************************/ + TARGETING::Target * theTarget = + getFunctionalTarget(TARGETING::TYPE_PROC); + if(theTarget == NULL) + { + total++; + fails++; + TS_FAIL("testSbeUpdateTarget() - No Functional Targets found!"); + break; + } + + TRACFCOMP( g_trac_sbe, + ENTER_MRK"testSbeUpdateTarget()" ); + + uint8_t local_ec = theTarget->getAttr<TARGETING::ATTR_EC>(); + + err = createSbeImageVmmSpace(); + if(theTarget == NULL) + { + total++; + fails++; + TS_FAIL("testSbeUpdateTarget() - Call to createSbeImageVmmSpace() failed"); + break; + } + + + /****************************************************/ + /* Get SBE Info State */ + /****************************************************/ + // Clear struct + memset(&sbeState, 0, sizeof(sbeState)); + + // Must set struct's target field + sbeState.target = theTarget; + + // set bad ec just for comparison to local_ec later + sbeState.ec = 0xFF; + + + total++; + err = getSbeInfoState(sbeState); + if(err) + { + fails++; + TS_FAIL("testSbeUpdateTarget() - call getSbeInfoState() failed."); + break; + } + + + /****************************************************/ + /* Compare/Display SBE Version Information */ + /****************************************************/ + + // Quick EC check + if (local_ec != sbeState.ec) + { + fails++; + TS_FAIL("testSbeUpdateTarget() - Bad ec check: local=0x%X, other=0x%X", local_ec, sbeState); + break; + } + + // Display sbeState + TRACUCOMP( g_trac_sbe, + "testSbeUpdateTarget() Info For Target 0x%X ec=0x%X " + "cur=0x%X alt=0x%X, ECC_fail 0/1=%d/%d, isMaster=%d " + "Custom Image Size=0x%X, CRC=0x%X", + TARGETING::get_huid(sbeState.target), sbeState.ec, + sbeState.cur_seeprom_side, sbeState.alt_seeprom_side, + sbeState.seeprom_0_ver_ECC_fail, + sbeState.seeprom_1_ver_ECC_fail, + sbeState.target_is_master, + sbeState.customizedImage_size, + sbeState.customizedImage_crc); + + TRACDBIN( g_trac_sbe, "testSbeUpdateTarget()-pnorVersion", + &sbeState.pnorVersion, sizeof(sbe_image_version_t)); + TRACDBIN( g_trac_sbe, "testSbeUpdateTarget()-mvpdSbKeyword", + &sbeState.mvpdSbKeyword, sizeof(mvpdSbeVersion_t)); + TRACDBIN( g_trac_sbe, "testSbeUpdateTarget()-seeprom_0_ver", + &sbeState.seeprom_0_ver, + sizeof(sbeSeepromVersionInfo_t)); + TRACDBIN( g_trac_sbe, "testSbeUpdateTarget()-seeprom_1_ver", + &sbeState.seeprom_1_ver, + sizeof(sbeSeepromVersionInfo_t)); + + + /****************************************************/ + /* CRC Calculation */ + /****************************************************/ + uint32_t new_data_crc = 0; + total++; + + err = getDataCrc(theTarget, new_data_crc); + if(err) + { + fails++; + TS_FAIL("testSbeUpdateTarget() - getDataCrc() failed"); + break; + } + + TRACUCOMP( g_trac_sbe, "testSbeUpdateTarget(): getDataCrc(): data_crc=0x%.4x", + new_data_crc); + + /****************************************************/ + /* Get Target Update Actions */ + /****************************************************/ + + total++; + err = getTargetUpdateActions(sbeState); + if(err) + { + fails++; + TS_FAIL("testSbeUpdateTarget() - getTargetUpdateActions() failed"); + break; + } + + + /****************************************************/ + /* Update SBE Backup */ + /****************************************************/ + // force backup to SEEPROM 1 just in case + if ( !(sbeState.update_actions & DO_UPDATE ) ) + { + sbeState.seeprom_side_to_update = EEPROM::SBE_BACKUP; + } + total++; + + err = performUpdateActions(sbeState); + if(err) + { + fails++; + TS_FAIL("testSbeUpdateTarget() - performUpdateActions() failed."); + break; + } + + + }while(0); + + err_cleanup = cleanupSbeImageVmmSpace(); + if(err_cleanup) + { + total++; + fails++; + TS_FAIL("testSbeUpdateTarget() -Call to cleanupSbeImageVmmSpace() failed."); + errlCommit( err_cleanup, SBE_COMP_ID ); + + } + + TRACFCOMP( g_trac_sbe, + EXIT_MRK"testSbeUpdateTarget() - %d/%d fails", + fails, total ); + } + + + + /** + * @brief This function will call decisionTreeForUpdates() and make + sure the correct update action is returned for a specific + situation. + */ + void testSbeDecisionTree ( void ) + { + + uint64_t fails = 0x0; + uint64_t total = 0x0; + + sbeTargetState_t sbeState; + + struct + { + // Inputs + uint8_t i_situation; + sbeSeepromSide_t i_cur; // current_seeprom_side + uint8_t i_flags; // mvpdSbKeyword.flags + + // Expected Output + sbeUpdateActions_t o_update_actions; + EEPROM::eeprom_chip_types_t o_seeprom; + uint8_t o_flags; // mvpdSbKeyword.flags + + } testData[] = + { + + // case 0xE0: cur=temp, cur=dirty, alt=dirty + // Arbitrarily set cur side to 0 (therefore perm set to 1) + // - update alt=1 + // - make cur=perm + // - re-IPL + { 0xE0, SBE_SEEPROM0, 0x80, + static_cast<sbeUpdateActions_t>(DO_UPDATE|IPL_RESTART), + EEPROM::SBE_BACKUP, 0x00 }, + + + // case 0xC0: cur=temp, cur=dirty, alt=dirty + // Arbitrarily set cur side to 1 (therefore perm set to 0) + // - update alt=0 + // - make cur=perm + // - re-IPL + { 0xC0, SBE_SEEPROM1, 0x00, + static_cast<sbeUpdateActions_t>(DO_UPDATE|IPL_RESTART), + EEPROM::SBE_PRIMARY, 0x80 }, + + // case 0xA0: cur=temp, cur=clean, alt=dirty + // Arbitarily Set cur side to 1 (therefore perm set to 0) + // - update alt=0 + // - make cur=perm + // - Continue IPL + { 0xA0, SBE_SEEPROM1, 0x00, + static_cast<sbeUpdateActions_t>(DO_UPDATE), + EEPROM::SBE_PRIMARY, 0x80 }, + + // case 0x80: cur=temp, cur=clean, alt=clean + // Arbitrarily set cur side to 1 (therefore perm set to 0) + // - No updates + // - Continue IPL + { 0x80, SBE_SEEPROM1, 0x00, + static_cast<sbeUpdateActions_t>(CLEAR_ACTIONS), + EEPROM::LAST_CHIP_TYPE, 0x00 }, + + // case 0x60: cur=perm, cur=dirty, alt=dirty + // Arbitrarily set cur side to 0 (therefore perm set to 0) + // - update alt=1 + // - re-IPL + { 0x60, SBE_SEEPROM0, 0x00, + static_cast<sbeUpdateActions_t>(DO_UPDATE|IPL_RESTART), + EEPROM::SBE_BACKUP, 0x00 }, + + // case 0x40: cur=temp, cur=dirty, alt=clean + // @todo RTC 47033 - Ask FSP if we just re-IPLed, but just + // continue IPL now + // Arbitrarily set cur side to 1 (therefore perm set to 1) + // No Updates + // Continue IPL + { 0x40, SBE_SEEPROM1, 0x80, + static_cast<sbeUpdateActions_t>(CLEAR_ACTIONS), + EEPROM::LAST_CHIP_TYPE, 0x80 }, + + // case 0x20: cur=perm, cur=clean, alt=dirty + // Arbitrarily set cur side to 0 (therefore perm set to 0) + // - update alt=1 + // - Continue IPL + { 0x20, SBE_SEEPROM0, 0x00, + static_cast<sbeUpdateActions_t>(DO_UPDATE), + EEPROM::SBE_BACKUP, 0x00 }, + + // case 0x00: cur=perm, cur=clean, alt=clean + // Arbitrarily set cur side to 0 (therefore perm set to 0) + // - No Updates + // - Continue IPL + // NOTE: this will test that right-most-bit is ignored: + // so techincally case 0x01, which should be = case 0x00 + { 0x01, SBE_SEEPROM0, 0x00, + static_cast<sbeUpdateActions_t>(CLEAR_ACTIONS), + EEPROM::LAST_CHIP_TYPE, 0x00 }, + + }; + + const uint32_t NUM_CMDS = sizeof(testData)/sizeof(testData[0]); + + + do{ + + TRACFCOMP( g_trac_sbe, + ENTER_MRK"testSbeDecisionTree()" ); + + + // Loop through each situation + for( uint32_t i = 0; i < NUM_CMDS; i++ ) + { + + sbeState.update_actions = CLEAR_ACTIONS; + + /****************************************************/ + /* Set Input Values */ + /****************************************************/ + sbeState.cur_seeprom_side = testData[i].i_cur; + + sbeState.alt_seeprom_side = + ( ( testData[i].i_cur == SBE_SEEPROM0 ) + ? SBE_SEEPROM1 : SBE_SEEPROM0 ); + + sbeState.mvpdSbKeyword.flags = testData[i].i_flags; + + + /****************************************************/ + /* Get Target Update Actions */ + /****************************************************/ + total++; + SBE::decisionTreeForUpdates(sbeState, + testData[i].i_situation); + + + /****************************************************/ + /* Check Output Values */ + /****************************************************/ + if (( testData[i].o_update_actions != sbeState.update_actions ) + || + ( testData[i].o_seeprom != sbeState.seeprom_side_to_update ) + || + ( testData[i].o_flags != sbeState.mvpdSbKeyword.flags ) + ) + { + fails++; + + TRACFCOMP( g_trac_sbe, ERR_MRK"testSbeDecisionTree() - " + "Fail! Unexpected results for situation=0x%.2X (i=%d): " + "Inputs: cur=%d, flags=0x%.2X", + testData[i].i_situation, i, + testData[i].i_cur, testData[i].i_flags); + + TRACFCOMP( g_trac_sbe, ERR_MRK"testSbeDecisionTree() - " + "Expected/Returned: update_actions=0x%.4X/0x%.4x, " + "update seeprom=%d/%d, flags=0x%.2X/0x%.2X", + testData[i].o_update_actions, sbeState.update_actions, + testData[i].o_seeprom, sbeState.seeprom_side_to_update, + testData[i].o_flags, sbeState.mvpdSbKeyword.flags); + + TS_FAIL("testSbeDecisionTree() - Fail! Unexpected results for pass %d, situation=0x%.2X", i, testData[i].i_situation); + + // Don't break - complete the remaining tests + } + + } // end of for-loop + + }while(0); + + TRACFCOMP( g_trac_sbe, EXIT_MRK + EXIT_MRK"testSbeDecisionTree() - %d/%d fails", + fails, total ); + } + + + /** + * @brief Constructor + */ + SBEUpdateTest() : CxxTest::TestSuite() + { + errlHndl_t err = NULL; + uint64_t fails = 0x0; + uint64_t total = 0x0; + bool sbe_loaded = false; + + err = loadSbeModule(sbe_loaded); + if(err) + { + total++; + fails++; + TS_FAIL("SBEUpdateTest() - Constuctor: failed to load modules"); + errlCommit( err, SBE_COMP_ID ); + } + + }; + + + /** + * @brief Destructor + */ + ~SBEUpdateTest() + { + errlHndl_t err = NULL; + uint64_t fails = 0x0; + uint64_t total = 0x0; + + err = unloadSbeModule(); + if(err) + { + total++; + fails++; + TS_FAIL("~SBEUpdateTest() - Destuctor: failed to load modules"); + errlCommit( err, SBE_COMP_ID ); + } + + }; + +}; + +#endif diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml index 2b06b940b..14d8cb757 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types.xml @@ -5811,6 +5811,26 @@ firmware notes: Used as override attribute for pstate procedure </attribute> <attribute> + <id>SBE_IMAGE_MINIMUM_VALID_EXS</id> + <description> + The minimum number of valid EXs that is required to be used when + customizing a SBE image. The customization will fail if it cannot + create an image with at least this many EXs. + </description> + <simpleType> + <uint8_t> + <default>3</default> + </uint8_t> + </simpleType> + <persistency>non-volatile</persistency> + <readable/> + <hwpfToHbAttrMap> + <id>ATTR_SBE_IMAGE_MINIMUM_VALID_EXS</id> + <macro>DIRECT</macro> + </hwpfToHbAttrMap> +</attribute> + +<attribute> <id>PROC_PSI_UNTRUSTED_BAR0_BASE_ADDR</id> <description> PSI Untrusted BAR0 base address (secure mode) @@ -5932,10 +5952,10 @@ firmware notes: Used as override attribute for pstate procedure <id>PROC_SECURITY_SETUP_VECTOR</id> <description> Secureboot 64-bit proc_sbe_security_setup_vector used - by proc_sbe_security_setup.S. 0s are an unsecure SBE image + by proc_sbe_security_setup.S. 0s are an unsecure SBE image creator: platform firmware notes: - 64-bit proc_sbe_security_setup_vector + 64-bit proc_sbe_security_setup_vector </description> <simpleType> <uint64_t> @@ -9498,7 +9518,7 @@ Measured in GB</description> </description> <simpleType> <uint8_t> - <default>4</default> + <default>2</default> </uint8_t> </simpleType> <persistency>non-volatile</persistency> diff --git a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml index 84ca82f95..b8bb37d6b 100644 --- a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml +++ b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml @@ -75,7 +75,7 @@ </attribute> <attribute> <id>FREQ_PROC_REFCLOCK</id> - <default>200</default> + <default>133</default> </attribute> <attribute> <id>FREQ_MEM_REFCLOCK</id> @@ -87,11 +87,11 @@ </attribute> <attribute> <id>FREQ_PB</id> - <default>0x960</default> + <default>0x7D0</default> </attribute> <attribute> <id>FREQ_X</id> - <default>0x12C0</default> + <default>0xFA0</default> </attribute> <attribute> <id>FREQ_A</id> diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml index 9fdfa1f37..9120f4ae9 100644 --- a/src/usr/targeting/common/xmltohb/target_types.xml +++ b/src/usr/targeting/common/xmltohb/target_types.xml @@ -149,6 +149,7 @@ <attribute><id>SBE_IMAGE_OFFSET</id></attribute> <attribute><id>BOOT_VOLTAGE</id></attribute> <attribute><id>SYNC_BETWEEN_STEPS</id></attribute> + <attribute><id>SBE_IMAGE_MINIMUM_VALID_EXS</id></attribute> <!-- End sbe_config_update attributes --> <!-- proc_select_boot_master attributes --> <attribute><id>PROC_SELECT_BOOT_MASTER</id></attribute> @@ -398,7 +399,7 @@ <attribute><id>SBE_SEEPROM_I2C_PORT</id></attribute> <attribute><id>PNOR_I2C_ADDRESS_BYTES</id></attribute> <!-- End Supporting poreve_memory_attributes.xml --> -<!-- TODO RTC 62291. This next attribute moves to hostboot only +<!-- TODO RTC 82688. This next attribute moves to hostboot only with this story --> <attribute><id>PROC_SECURITY_SETUP_VECTOR</id></attribute> |