diff options
author | Marty Gloff <mgloff@us.ibm.com> | 2016-08-15 16:42:48 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-09-14 11:57:48 -0400 |
commit | 6fb94b1d7cd67d0d8f7ad0b066d36a826bccebb7 (patch) | |
tree | 9701a0c1535093b533a09e1876c1bd1ca32ff270 /src/usr/sbe | |
parent | ce16a4cdde7e39aad38446c13ea31a018c720c04 (diff) | |
download | talos-hostboot-6fb94b1d7cd67d0d8f7ad0b066d36a826bccebb7.tar.gz talos-hostboot-6fb94b1d7cd67d0d8f7ad0b066d36a826bccebb7.zip |
Insert bootloader image into SBE SEEPROM
4) Bootloader-related changes associated with Story 138226: Changes
for P9 SBE.
Change-Id: If9788c3bb2b56fbbaf4f668a1e153da79ad1757f
RTC: 139757
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28276
Reviewed-by: Matt Derksen <v2cibmd@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/sbe')
-rw-r--r-- | src/usr/sbe/makefile | 1 | ||||
-rw-r--r-- | src/usr/sbe/sbe_update.C | 258 | ||||
-rw-r--r-- | src/usr/sbe/sbe_update.H | 52 |
3 files changed, 301 insertions, 10 deletions
diff --git a/src/usr/sbe/makefile b/src/usr/sbe/makefile index 618e066b8..7bf61ffc4 100644 --- a/src/usr/sbe/makefile +++ b/src/usr/sbe/makefile @@ -56,6 +56,7 @@ VPATH += ${UTILS_PATH} include ${ROOTPATH}/procedure.rules.mk include ${HWP_CUSTOMIZE_PATH}/p9_xip_customize.mk +include ${HWP_CUSTOMIZE_PATH}/p9_xip_section_append.mk include ${HWP_ACCESSORS_PATH}/p9_get_mvpd_ring.mk include ${HWP_ACCESSORS_PATH}/p9_mvpd_ring_funcs.mk include ${HWP_XIP_PATH}/p9_xip_image.mk diff --git a/src/usr/sbe/sbe_update.C b/src/usr/sbe/sbe_update.C index c1bc352d8..86e30e2a0 100644 --- a/src/usr/sbe/sbe_update.C +++ b/src/usr/sbe/sbe_update.C @@ -60,6 +60,8 @@ //Procedures #include <p9_xip_customize.H> +#include <p9_xip_section_append.H> +#include <p9_xip_image.h> // ---------------------------------------------- // Trace definitions @@ -734,6 +736,146 @@ namespace SBE ///////////////////////////////////////////////////////////////////// + errlHndl_t findHBBLInPnor(void*& o_imgPtr, + size_t& o_imgSize) + { + errlHndl_t err = NULL; + PNOR::SectionInfo_t pnorInfo; + hbblEndData_t* hbblEndData = NULL; + PNOR::SectionId pnorSectionId = PNOR::HB_BOOTLOADER; + + o_imgPtr = NULL; + o_imgSize = 0; + + TRACDCOMP( g_trac_sbe, + ENTER_MRK"findHBBLInPnor()" ); + + do{ + // Get SBE PNOR section info from PNOR RP + err = getSectionInfo( pnorSectionId, + pnorInfo ); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"findHBBLInPnor: Error calling " + "getSectionInfo() rc=0x%.4X", + err->reasonCode() ); + break; + } + + TRACUCOMP( g_trac_sbe, + INFO_MRK"findHBBLInPnor: sectionId=0x%X. " + "pnor vaddr = 0x%.16X", + pnorSectionId, pnorInfo.vaddr); + + // Look for HBBL end data on 16-byte boundary start at offset 0x2C00 + uint64_t hbblAbsoluteEnd = pnorInfo.vaddr + pnorInfo.size; + uint64_t hbblAddr = pnorInfo.vaddr + 0x2C00; + while( hbblAddr < hbblAbsoluteEnd ) + { + hbblEndData = reinterpret_cast<hbblEndData_t*>(hbblAddr); + + if( HBBL_END_EYECATCHER == hbblEndData->eyecatcher ) + { + TRACUCOMP( g_trac_sbe, + INFO_MRK"findHBBLInPnor: hbblEndData = %p, " + "hbblEndData.address = 0x%.16X", + hbblEndData, hbblEndData->address); + break; + } + + hbblAddr += sizeof(hbblEndData_t); + } + + if( hbblAddr >= hbblAbsoluteEnd ) + { + //The HBBL partition does not have the HBBL end data + TRACFCOMP( g_trac_sbe, ERR_MRK"findHBBLInPnor: HBBL partition " + "does not have the HBBL end data" ); + + /*@ + * @errortype + * @moduleid HBBL_FIND_IN_PNOR + * @reasoncode HBBL_END_DATA_NOT_FOUND + * @userdata1 HBBL PNOR Section Address + * @userdata2 HBBL PNOR Section Size + * @devdesc HBBL partition did not have end data + * @custdesc A problem occurred while updating processor + * boot code. + */ + err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + HBBL_FIND_IN_PNOR, + HBBL_END_DATA_NOT_FOUND, + pnorInfo.vaddr, + pnorInfo.size); + err->collectTrace(SBE_COMP_NAME); + err->addProcedureCallout( HWAS::EPUB_PRC_SP_CODE, + HWAS::SRCI_PRIORITY_HIGH ); + + break; + } + + o_imgPtr = reinterpret_cast<void*>( pnorInfo.vaddr ); + o_imgSize = hbblEndData->address - HBBL_START_ADDRESS; + + }while(0); + + TRACDCOMP( g_trac_sbe, + EXIT_MRK"findHBBLInPnor(): o_imgPtr=%p, o_imgSize=0x%X", + o_imgPtr, o_imgSize ); + + return err; + } + + +///////////////////////////////////////////////////////////////////// + errlHndl_t appendHbblToSbe(void* i_section, + uint32_t i_section_size, + void* i_image, + uint32_t& io_image_size) + { + errlHndl_t err = NULL; + + TRACUCOMP( g_trac_sbe, + ENTER_MRK"appendHbblToSbe(): i_section=%p, " + "i_section_size=0x%X, i_image=%p, " + "io_image_size=0x%X", + i_section, i_section_size, + i_image, io_image_size); + + do{ + // Invoke p9_xip_section_append to append HBBL image to SBE image + FAPI_INVOKE_HWP( err, + p9_xip_section_append, + i_section, + i_section_size, + P9_XIP_SECTION_SBE_HBBL, + i_image, + io_image_size ); + + // Check the return code + if(err) + { + TRACUCOMP( g_trac_sbe, "appendHbblToSbe(): " + "p9_xip_section_append failed, rc=0x%X", + err->reasonCode() ); + + // exit loop + break; + } + + }while(0); + + TRACUCOMP( g_trac_sbe, + EXIT_MRK"appendHbblToSbe(): i_image=%p, " + "io_image_size=0x%X, RC=0x%X", + i_image, io_image_size, ERRL_GETRC_SAFE(err) ); + + return err; + } + + +///////////////////////////////////////////////////////////////////// errlHndl_t procCustomizeSbeImg(TARGETING::Target* i_target, void* i_sbePnorPtr, size_t i_maxImgSize, @@ -788,7 +930,7 @@ namespace SBE coreCount = __builtin_popcount(coreMask); procIOMask = coreMask; - while( coreCount >= 0 ) + while( coreCount >= 0 ) // @TODO RTC:138226 Is 0 right check value? { if( !INITSERVICE::spBaseServicesEnabled() ) // FSP not present ==> ok to call @TODO RTC:160466 { @@ -827,11 +969,13 @@ namespace SBE // exit loop break; } - /* @TODO RTC:138226 RC does not exist in P9 yet, - need to check if it will exist */ + /* @TODO RTC:138226 Both RCs exist in P9, + need to check what to use */ // Look for a specific return code else if ( rc_fapi.isRC( - fapi2::RC_XIPC_IMAGE_WOULD_OVERFLOW) ) + fapi2::RC_XIPC_IMAGE_WOULD_OVERFLOW) || + rc_fapi.isRC( + fapi2::RC_XIPC_IMAGE_WOULD_OVERFLOW_BEFORE_REACHING_MIN_ECS) ) { // This is a specific return code from p9_xip_customize // where the cores sent in couldn't fit, but possibly @@ -1355,6 +1499,8 @@ namespace SBE errlHndl_t err = NULL; bool skip_customization = false; + void *tmp_pnorImage = NULL; + uint32_t tmp_pnorImageSz = 0; do{ @@ -1475,18 +1621,83 @@ namespace SBE /*******************************************/ - /* Customize SBE Image from PNOR and */ + /* Get PNOR HBBL Information */ + /*******************************************/ + void* hbblPnorPtr = NULL; + size_t hbblPnorImageSize = 0; + size_t hbblCachelineSize = 0; + + err = findHBBLInPnor(hbblPnorPtr, + hbblPnorImageSize); + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - " + "Error getting HBBL Version from PNOR, " + "RC=0x%X, PLID=0x%lX", + ERRL_GETRC_SAFE(err), + ERRL_GETPLID_SAFE(err)); + break; + } + else + { + TRACFCOMP( g_trac_sbe, "getSbeInfoState() - " + "hbblPnorPtr=%p, hbblPnorImageSize=0x%08X (%d)", + hbblPnorPtr, hbblPnorImageSize, hbblPnorImageSize); + } + + hbblCachelineSize = setCachelineSize(hbblPnorImageSize); + + TRACUCOMP( g_trac_sbe, "getSbeInfoState() - HBBL: " + "maxSize=0x%X, actSize=0x%X, cachelineSize=0x%X", + HBBL_MAX_SIZE, hbblPnorImageSize, + hbblCachelineSize); + + + /*******************************************/ + /* Append HBBL Image from PNOR to SBE */ + /* Image from PNOR */ + /*******************************************/ + if ( skip_customization == false ) + { + // copy SBE image from PNOR to memory + tmp_pnorImageSz = static_cast<uint32_t>( + sbePnorImageSize + hbblCachelineSize); + tmp_pnorImage = malloc(tmp_pnorImageSz); + memcpy ( tmp_pnorImage, + sbePnorPtr, + sbePnorImageSize); + + err = appendHbblToSbe(hbblPnorPtr, // HBBL Image to append + hbblCachelineSize, // Size of HBBL Image + tmp_pnorImage, // SBE Image + tmp_pnorImageSz); // Available/used + } + + if(err) + { + TRACFCOMP( g_trac_sbe, ERR_MRK"getSbeInfoState() - " + "Error from procAppendHbblToSbe(), " + "RC=0x%X, PLID=0x%lX", + ERRL_GETRC_SAFE(err), + ERRL_GETPLID_SAFE(err)); + break; + } + + + /*******************************************/ + /* Customize SBE/HBBL Image and */ /* Calculate CRC of the image */ /*******************************************/ size_t sbeImgSize = 0; if ( skip_customization == false ) { err = procCustomizeSbeImg(io_sbeState.target, - sbePnorPtr, //SBE vaddr in PNOR - FIXED_SEEPROM_WORK_SPACE, //max size - reinterpret_cast<void*> - (SBE_IMG_VADDR), //destination - sbeImgSize); + tmp_pnorImage, //SBE in memory + FIXED_SEEPROM_WORK_SPACE, //max size + reinterpret_cast<void*> + (SBE_IMG_VADDR), //destination + sbeImgSize); } if(err) @@ -1510,6 +1721,7 @@ namespace SBE FIXED_SEEPROM_WORK_SPACE, sbeImgSize, io_sbeState.customizedImage_crc); + /*******************************************/ /* Get MVPD SBE Version Information */ /*******************************************/ @@ -1597,6 +1809,8 @@ namespace SBE }while(0); + free(tmp_pnorImage); + return err; } @@ -2199,6 +2413,18 @@ namespace SBE io_sbeState.seeprom_0_ver_Nest_Freq_Mismatch, isSimics_check); } + else + { + TRACUCOMP( g_trac_sbe, INFO_MRK"SBE Update tgt=0x%X: Seeprom0 " + "flagged as clean: pnor=%d, crc=%d " + "(custom=0x%X/s0=0x%X), nest_freq=%d, isSimics=%d", + TARGETING::get_huid(io_sbeState.target), + pnor_check_dirty, crc_check_dirty, + io_sbeState.customizedImage_crc, + io_sbeState.seeprom_0_ver.data_crc, + io_sbeState.seeprom_0_ver_Nest_Freq_Mismatch, + isSimics_check); + } /**************************************************************/ /* Compare SEEPROM 1 with PNOR and Customized Image CRC -- */ @@ -2249,6 +2475,18 @@ namespace SBE io_sbeState.seeprom_1_ver_Nest_Freq_Mismatch, isSimics_check); } + else + { + TRACUCOMP( g_trac_sbe, INFO_MRK"SBE Update tgt=0x%X: Seeprom1 " + "flagged as clean: pnor=%d, crc=%d " + "(custom=0x%X/s1=0x%X), nest_freq=%d, isSimics=%d", + TARGETING::get_huid(io_sbeState.target), + pnor_check_dirty, crc_check_dirty, + io_sbeState.customizedImage_crc, + io_sbeState.seeprom_1_ver.data_crc, + io_sbeState.seeprom_1_ver_Nest_Freq_Mismatch, + isSimics_check); + } // Extra information for unit testing diff --git a/src/usr/sbe/sbe_update.H b/src/usr/sbe/sbe_update.H index bbeb105ba..79d3cae2a 100644 --- a/src/usr/sbe/sbe_update.H +++ b/src/usr/sbe/sbe_update.H @@ -95,6 +95,15 @@ namespace SBE const uint64_t NONSECURE_VER_EYECATCH = 0x56455253494F4E00; //'VERSION\0' const uint32_t SUPPORTED_TOC_VER = 0x00000001; + // PNOR HBBL Partition constants + const uint64_t HBBL_START_ADDRESS = 0x0000000000003000; + const size_t HBBL_MAX_SIZE = 20*KILOBYTE; // 20KB + const uint64_t HBBL_END_EYECATCHER = 0x4842424C656E6400; // 'HBBLend\0' + + // Cacheline Size and Mask + const uint64_t CACHELINE_SIZE = 128; + const uint64_t CACHELINE_MASK = CACHELINE_SIZE - 1; + // MVPD SB Keyword contants const size_t MVPD_SB_RECORD_SIZE = 129; @@ -229,6 +238,15 @@ namespace SBE } PACKED; /** + * @brief Layout of Hostboot Bootloader (HBBL) end of load data + */ + struct hbblEndData_t + { + uint64_t eyecatcher; // Expected to contain 'HBBLend\0' + uint64_t address; // bootloader.ld end_load_address + } PACKED; + + /** * @brief Layout of SB keyword in MVPD */ struct mvpdSbKeyword_t @@ -378,6 +396,26 @@ namespace SBE /** + * @brief Append HBBL Immage to SBE Image + * + * @param[in] i_section Pointer to HBBL Image to append + * + * @param[in] i_section_size Cacheline size of HBBL Image + * + * @param[in] i_image Pointer to SBE image in memory (non-ecc) + * + * @param[in/out] io_image_size in: space available for enlarged XIP image + * out: size of enlarged XIP image + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t appendHbblToSbe(void* i_section, + uint32_t i_section_size, + void* i_image, + uint32_t& io_image_size); + + + /** * @brief Customize SBE Image for current Processor * * @param[in] i_target Target processor to customize @@ -594,6 +632,20 @@ namespace SBE /** + * @brief Calculates size for a block of code or data such that the block + * can be aligned on cachelines. + * + * @param[in] i_size Size of block code or data + * + * @return Size of block adjusted to cacheline boundary + */ + inline size_t setCachelineSize(size_t i_size) + { + return (i_size + CACHELINE_MASK) & ~(CACHELINE_MASK); + } + + + /** * @brief Calculates ECC size for a block of code or data allowing for * padding at chip boundaries so 9-byte segment (8 bytes of code * or data and 1 byte of ECC) does not straddle the boundary. |