diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2017-03-06 16:36:11 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-04-16 21:32:17 -0400 |
commit | 6677ffcbda04c73a7d3ed1e651e3394c8218e503 (patch) | |
tree | 2de578165f3517ecd95dd56548a4e5ebdfa4bb8b /src/usr | |
parent | 6274618ff6a4b0cd8447c1e31940c66b40fa1c42 (diff) | |
download | talos-hostboot-6677ffcbda04c73a7d3ed1e651e3394c8218e503.tar.gz talos-hostboot-6677ffcbda04c73a7d3ed1e651e3394c8218e503.zip |
Propagate attribute overrides up to the HBRT code
Attribute overrides are stored in a separate tank of memory from
the regular attribute values. This tank will be added as an
additional reserved memory section for HBRT to consume (only if
overrides exist).
Also fixed a couple bugs encountered while testing:
- No longer crashes if an error is created inside the targeting
initialization code.
- Added reserved bytes to RHB definition.
Change-Id: I5b10f7ad8dfcb58c550868bb83c4d843f48e1aae
RTC: 169942
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38547
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com>
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/errl/runtime/rt_errlmanager.C | 11 | ||||
-rw-r--r-- | src/usr/runtime/hdatservice.C | 4 | ||||
-rw-r--r-- | src/usr/runtime/hdatstructs.H | 1 | ||||
-rw-r--r-- | src/usr/runtime/populate_hbruntime.C | 209 | ||||
-rw-r--r-- | src/usr/targeting/attrPlatOverride.C | 11 | ||||
-rwxr-xr-x | src/usr/targeting/attrrp.C | 152 | ||||
-rwxr-xr-x | src/usr/targeting/common/xmltohb/target_types.xml | 12 | ||||
-rw-r--r-- | src/usr/targeting/runtime/attrPlatOverride_rt.C | 70 | ||||
-rw-r--r-- | src/usr/targeting/runtime/attrrp_rt.C | 9 | ||||
-rw-r--r-- | src/usr/targeting/runtime/test/testtargeting.H | 43 | ||||
-rw-r--r-- | src/usr/testcore/rtloader/loader.H | 53 |
11 files changed, 522 insertions, 53 deletions
diff --git a/src/usr/errl/runtime/rt_errlmanager.C b/src/usr/errl/runtime/rt_errlmanager.C index 981b4f117..14b61622e 100644 --- a/src/usr/errl/runtime/rt_errlmanager.C +++ b/src/usr/errl/runtime/rt_errlmanager.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* Contributors Listed Below - COPYRIGHT 2013,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -83,7 +83,14 @@ ErrlManager::ErrlManager() : // determine starting PLID value TARGETING::Target * sys = NULL; - TARGETING::targetService().getTopLevelTarget( sys ); + if( TARGETING::targetService().isInitialized() ) + { + TARGETING::targetService().getTopLevelTarget( sys ); + } + else + { + TRACFCOMP( g_trac_errl, "Error log being created before TARGETING is ready..." ); + } if(sys) { iv_currLogId = sys->getAttr<TARGETING::ATTR_HOSTSVC_PLID>(); diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C index 0b6201df9..cc289f5fa 100644 --- a/src/usr/runtime/hdatservice.C +++ b/src/usr/runtime/hdatservice.C @@ -1243,7 +1243,7 @@ errlHndl_t hdatService::updateHostDataSectionActual( SectionId i_section, else if( !((TARGETING::PAYLOAD_KIND_PHYP == payload_kind ) || (TARGETING::PAYLOAD_KIND_SAPPHIRE == payload_kind ))) { - TRACFCOMP( g_trac_runtime, "get_host_data_section> There is no host data for PAYLOAD_KIND=%d", payload_kind ); + TRACFCOMP( g_trac_runtime, "updateHostDataSectionActual> There is no host data for PAYLOAD_KIND=%d", payload_kind ); /*@ * @errortype * @moduleid RUNTIME::MOD_HDATSERVICE_UPDATE_SECTION_ACTUAL @@ -1294,7 +1294,7 @@ errlHndl_t hdatService::updateHostDataSectionActual( SectionId i_section, // Not sure how we could get here... else { - TRACFCOMP( g_trac_runtime, "get_host_data_section> Unknown section %d", i_section ); + TRACFCOMP( g_trac_runtime, "updateHostDataSectionActual> Unknown section %d", i_section ); /*@ * @errortype * @moduleid RUNTIME::MOD_HDATSERVICE_UPDATE_SECTION_ACTUAL diff --git a/src/usr/runtime/hdatstructs.H b/src/usr/runtime/hdatstructs.H index 4cb51ac41..b686d7f8c 100644 --- a/src/usr/runtime/hdatstructs.H +++ b/src/usr/runtime/hdatstructs.H @@ -333,6 +333,7 @@ struct hdatMsVpdRhbAddrRange_t uint64_t hdatRhbAddrRngEndAddr; // 0x000C Range ending uint32_t hdatRhbLabelSize; // 0x0014 Label size uint8_t hdatRhbLabelString[64]; // 0x0018 Label string Ptr + uint8_t reserved[8]; // 0x0058 Reserved } __attribute__ ((packed)); diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index b045a1cd7..5f97d5e90 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -59,6 +59,8 @@ #include "../hdat/hdattpmdata.H" #include "../secureboot/trusted/tpmLogMgr.H" #include "../secureboot/trusted/trustedboot.H" +#include <targeting/common/attributeTank.H> +#include <runtime/interface.h> #include <targeting/attrPlatOverride.H> @@ -181,6 +183,51 @@ errlHndl_t populate_RtDataByNode(uint64_t iNodeId) break; } + //@fixme-RTC:169478-Remove this workaround once HDAT+PHYP is ready + // Add the override data into the back-end of the allocated + // attribute data to handle the case where the RHB pointers + // are not yet being used + { + size_t l_attrOverMaxSize = 64*KILOBYTE; + + // Stick the overrides at Attributes+1MB-64KB + uint8_t* l_overridePtr = + reinterpret_cast<uint8_t*>( l_hbrtDataAddr + + 1*MEGABYTE + - l_attrOverMaxSize ); + + // copy overrides into local buffer + uint8_t* l_overrideData = + reinterpret_cast<uint8_t*>(malloc(l_attrOverMaxSize)); + size_t l_actualSize = l_attrOverMaxSize; + l_elog = TARGETING::AttrRP::saveOverrides( l_overrideData, + l_actualSize ); + if( l_elog ) + { + TRACFCOMP( g_trac_runtime, "workaround is busted!!!" ); + break; + } + else if( l_actualSize > 0 ) + { + memcpy( reinterpret_cast<uint8_t*>(l_hbrtDataAddr + +1*MEGABYTE + -l_attrOverMaxSize), + l_overrideData, + l_actualSize ); + TRACFCOMP( g_trac_runtime, "Copied %d bytes of overrides into HDAT", l_actualSize ); + } + else + { + TRACFCOMP( g_trac_runtime, "No overrides" ); + // add a terminator at the end so that the processing + // code in HBRT is happy + TARGETING::AttrOverrideSection* l_term = + reinterpret_cast<TARGETING::AttrOverrideSection*> + (l_overridePtr); + l_term->iv_layer = TARGETING::AttributeTank::TANK_LAYER_TERM; + } + } + // Load ATTRIBUTE data into HDAT TARGETING::AttrRP::save(l_hbrtDataAddr); @@ -419,6 +466,7 @@ void traceHbRsvMemRange(hdatMsVpdRhbAddrRange_t* & i_rngPtr ) */ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) { + TRACFCOMP( g_trac_runtime, ENTER_MRK"populate_HbRsvMem> i_nodeId=%d", i_nodeId ); errlHndl_t l_elog = nullptr; do { @@ -436,7 +484,7 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) // First phyp entry is for the entire 256M HB space uint64_t l_hbAddr = cpu_spr_value(CPU_SPR_HRMOR) - VMM_HRMOR_OFFSET; - l_label = "ibm,hb-rsv-mem"; + l_label = HBRT_RSVD_MEM__PRIMARY; l_labelSize = strlen(l_label) + 1; // Get a pointer to the next available HDAT HB Rsv Mem entry @@ -514,12 +562,13 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) // -----...-------------- // -----HOMER_0---------- // -----VPD-------------- - // -----ATTR Data-------- - // -----HBRT Image------- + // -----ATTR Data------------ + // -----ATTR Override Data--- + // -----HBRT Image----------- // First opal entries are for the HOMERs uint64_t l_homerAddr = l_topMemAddr; - l_label = "ibm,homer-image"; + l_label = HBRT_RSVD_MEM__HOMER; l_labelSize = strlen(l_label) + 1; // Loop through all functional Procs @@ -565,14 +614,14 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) #ifdef CONFIG_START_OCC_DURING_BOOT + /////////////////////////////////////////////////// // OCC Common entry TARGETING::Target * l_sys = nullptr; TARGETING::targetService().getTopLevelTarget( l_sys ); assert(l_sys != nullptr); uint64_t l_occCommonAddr = l_sys->getAttr <TARGETING::ATTR_OCC_COMMON_AREA_PHYS_ADDR>(); - - l_label = "ibm,occ-common-area"; + l_label = HBRT_RSVD_MEM__OCC_COMMON; l_labelSize = strlen(l_label) + 1; // Get a pointer to the next available HDAT HB Rsv Mem entry @@ -601,10 +650,24 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) #endif } + // Establish a couple variables to keep track of where the + // next section lands as we deal with the less statically + // sized areas. These values must always remain 64KB + // aligned + uint64_t l_prevDataAddr = 0; + uint64_t l_prevDataSize = 0; + + //==================== + // Note that for PHYP we build up starting at the end of the + // previously allocated HOMER/OCC areas, for OPAL we build + // downwards from the top of memory where the HOMER/OCC + // areas were placed + + /////////////////////////////////////////////////// // VPD entry uint64_t l_vpdAddr = 0x0; - l_label = "ibm,hbrt-vpd-image"; + l_label = HBRT_RSVD_MEM__VPD_CACHE; l_labelSize = strlen(l_label) + 1; if(TARGETING::is_phyp_load()) @@ -641,6 +704,8 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) memcpy( l_rngPtr->hdatRhbLabelString, l_label, l_labelSize ); + l_prevDataAddr = l_vpdAddr; + l_prevDataSize = VMM_RT_VPD_SIZE; traceHbRsvMemRange(l_rngPtr); @@ -666,21 +731,23 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) } + /////////////////////////////////////////////////// // ATTR Data entry uint64_t l_attrDataAddr = 0x0; - l_label = "ibm,hbrt-target-image"; + l_label = HBRT_RSVD_MEM__ATTRIBUTES; l_labelSize = strlen(l_label) + 1; uint64_t l_attrSize = TARGETING::AttrRP::maxSize(); + // Minimum 64K size for Opal + size_t l_attrSizeAligned = ALIGN_X( l_attrSize, 64*KILOBYTE ); + if(TARGETING::is_phyp_load()) { - l_attrDataAddr = l_vpdAddr + VMM_RT_VPD_SIZE; - l_attrDataAddr = ALIGN_X(l_attrDataAddr,64*KILOBYTE); + l_attrDataAddr = l_prevDataAddr + l_prevDataSize; } else if(TARGETING::is_sapphire_load()) { - l_attrDataAddr = l_vpdAddr - l_attrSize; - l_attrDataAddr = ALIGN_DOWN_X(l_attrDataAddr,64*KILOBYTE); + l_attrDataAddr = l_prevDataAddr - l_attrSizeAligned; } // Get a pointer to the next available HDAT HB Rsv Mem entry @@ -697,8 +764,6 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) l_rngPtr->hdatRhbRngId = i_nodeId; l_rngPtr->hdatRhbAddrRngStrAddr = l_attrDataAddr | VmmManager::FORCE_PHYS_ADDR; - // Minimum 64K size for Opal - size_t l_attrSizeAligned = ALIGN_X( l_attrSize, 64*KILOBYTE ); l_rngPtr->hdatRhbAddrRngEndAddr = (l_attrDataAddr | VmmManager::FORCE_PHYS_ADDR) + l_attrSizeAligned - 1 ; @@ -706,6 +771,8 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) memcpy( l_rngPtr->hdatRhbLabelString, l_label, l_labelSize ); + l_prevDataAddr = l_attrDataAddr; + l_prevDataSize = l_attrSizeAligned; traceHbRsvMemRange(l_rngPtr); @@ -725,12 +792,118 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) } + /////////////////////////////////////////////////// + // ATTR Overrides entry + uint64_t l_attrOverDataAddr = 0x0; + l_label = HBRT_RSVD_MEM__OVERRIDES; + l_labelSize = strlen(l_label) + 1; + + // default to the minimum space we have to allocate anyway + size_t l_attrOverMaxSize = 64*KILOBYTE; + //@fixme-RTC:171863-fill in real size + + // copy overrides into local buffer + uint8_t* l_overrideData = + reinterpret_cast<uint8_t*>(malloc(l_attrOverMaxSize)); + size_t l_actualSize = l_attrOverMaxSize; + l_elog = TARGETING::AttrRP::saveOverrides( l_overrideData, + l_actualSize ); + if( l_elog ) + { + // check if the issue was a lack of space (unlikely) + if( unlikely( l_actualSize > 0 ) ) + { + TRACFCOMP( g_trac_runtime, "Expanding override section to %d", l_actualSize ); + free(l_overrideData); + l_overrideData = + reinterpret_cast<uint8_t*>(malloc(l_actualSize)); + l_elog = TARGETING::AttrRP::saveOverrides( l_overrideData, + l_actualSize ); + } + + // overrides are not critical so just commit this + // and keep going without any + if( l_elog ) + { + TRACFCOMP( g_trac_runtime, "Errors applying overrides, just skipping" ); + errlCommit( l_elog, RUNTIME_COMP_ID ); + l_elog = NULL; + l_actualSize = 0; + } + } + + // only add a section if there are actually overrides + if( l_actualSize > 0 ) + { + // Minimum 64K size for Opal + size_t l_actualSizeAligned = ALIGN_X( l_actualSize, 64*KILOBYTE ); + + // phyp/opal build in reverse... + if(TARGETING::is_phyp_load()) + { + l_attrOverDataAddr = l_prevDataAddr + l_prevDataSize; + } + else if(TARGETING::is_sapphire_load()) + { + l_attrOverDataAddr = l_prevDataAddr - l_actualSizeAligned; + } + + // Get a pointer to the next available HDAT HB Rsv Mem entry + l_rngPtr = nullptr; + l_elog = getNextRhbAddrRange(l_rngPtr); + if(l_elog) + { + break; + } + + // Fill in the entry + l_rngPtr->hdatRhbRngType = + static_cast<uint8_t>(HDAT::RHB_TYPE_HBRT); + l_rngPtr->hdatRhbRngId = i_nodeId; + l_rngPtr->hdatRhbAddrRngStrAddr = + l_attrOverDataAddr | VmmManager::FORCE_PHYS_ADDR; + l_rngPtr->hdatRhbAddrRngEndAddr = + (l_attrOverDataAddr | VmmManager::FORCE_PHYS_ADDR) + + l_actualSizeAligned - 1 ; + l_rngPtr->hdatRhbLabelSize = l_labelSize; + memcpy( l_rngPtr->hdatRhbLabelString, + l_label, + l_labelSize ); + l_prevDataAddr = l_attrOverDataAddr; + l_prevDataSize = l_actualSizeAligned; + + traceHbRsvMemRange(l_rngPtr); + + // Load the attribute data into memory + l_elog = mapPhysAddr(l_attrOverDataAddr, + ALIGN_PAGE(l_actualSize), + l_vAddr); + if(l_elog) + { + break; + } + + memcpy( reinterpret_cast<void*>(l_vAddr), + l_overrideData, + l_actualSize ); + free(l_overrideData); + + l_elog = unmapVirtAddr(l_vAddr); + if(l_elog) + { + break; + } + } + + + /////////////////////////////////////////////////// // HBRT image entry + // Only needed for OPAL on OP, data comes from a LID in other cases if(TARGETING::is_sapphire_load() && (!INITSERVICE::spBaseServicesEnabled())) { uint64_t l_hbrtImageAddr = 0x0; - l_label = "ibm,hbrt-code-image"; + l_label = HBRT_RSVD_MEM__CODE; l_labelSize = strlen(l_label) + 1; PNOR::SectionInfo_t l_pnorInfo; @@ -759,7 +932,8 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) (l_relocateCount+1)*sizeof(uint64_t); // Set the image address, align down 64K for Opal - l_hbrtImageAddr = ALIGN_PAGE_DOWN(l_attrDataAddr - l_imageSize); + l_hbrtImageAddr = ALIGN_PAGE_DOWN(l_prevDataAddr); + l_hbrtImageAddr = ALIGN_PAGE_DOWN(l_hbrtImageAddr - l_imageSize); l_hbrtImageAddr = ALIGN_DOWN_X(l_hbrtImageAddr,64*KILOBYTE); // Get a pointer to the next available HDAT HB Rsv Mem entry @@ -808,7 +982,8 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId) } while(0); - return(l_elog); + TRACFCOMP( g_trac_runtime, EXIT_MRK"populate_HbRsvMem> l_elog=%.8X", ERRL_GETRC_SAFE(l_elog) ); + return(l_elog); } // end populate_HbRsvMem diff --git a/src/usr/targeting/attrPlatOverride.C b/src/usr/targeting/attrPlatOverride.C index b9af17f92..2848c920b 100644 --- a/src/usr/targeting/attrPlatOverride.C +++ b/src/usr/targeting/attrPlatOverride.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2016 */ +/* Contributors Listed Below - COPYRIGHT 2014,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -31,6 +31,14 @@ namespace TARGETING { +const std::pair<AttributeTank::TankLayer, PNOR::SectionId> + tankLayerToPnor[AttributeTank::TANK_LAYER_LAST] = + { + std::make_pair(AttributeTank::TANK_LAYER_FAPI, PNOR::ATTR_TMP), + std::make_pair(AttributeTank::TANK_LAYER_TARG, PNOR::ATTR_TMP), + std::make_pair(AttributeTank::TANK_LAYER_PERM, PNOR::ATTR_PERM) + }; + errlHndl_t getAttrOverrides(PNOR::SectionInfo_t &i_sectionInfo, AttributeTank* io_tanks[AttributeTank::TANK_LAYER_LAST]) { @@ -63,6 +71,7 @@ errlHndl_t getAttrOverrides(PNOR::SectionInfo_t &i_sectionInfo, do { + TRACFCOMP( g_trac_targeting, "Section id=%d, size=%d", i_sectionInfo.id, i_sectionInfo.size ); uint32_t l_index = 0; // Deserialize each section diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C index cc0cc57c1..f67ac831f 100755 --- a/src/usr/targeting/attrrp.C +++ b/src/usr/targeting/attrrp.C @@ -43,9 +43,12 @@ #include <targeting/common/targreasoncodes.H> #include <targeting/attrrp.H> #include <targeting/common/trace.H> +#include <targeting/common/attributeTank.H> #include <initservice/initserviceif.H> #include <util/align.H> #include <sys/misc.h> +#include <fapi2/plat_attr_override_sync.H> +#include <targeting/attrPlatOverride.H> using namespace INITSERVICE; using namespace ERRORLOG; @@ -651,6 +654,13 @@ namespace TARGETING } // end maxSize + errlHndl_t AttrRP::saveOverrides( uint8_t* i_dest, size_t& io_size ) + { + // Call save on singleton instance. + return Singleton<AttrRP>::instance()._saveOverrides(i_dest,io_size); + } + + void* AttrRP::_save(uint64_t& io_addr) { TRACDCOMP(g_trac_targeting, "AttrRP::save: top @ 0x%lx", io_addr); @@ -687,4 +697,146 @@ namespace TARGETING return region; } + + errlHndl_t AttrRP::_saveOverrides( uint8_t* i_dest, size_t& io_size ) + { + TRACFCOMP( g_trac_targeting, ENTER_MRK"AttrRP::_saveOverrides: i_dest=%p, io_size=%d", i_dest, io_size ); + errlHndl_t l_err = nullptr; + + do + { + size_t l_maxSize = io_size; + io_size = 0; + + // Save the fapi and temp overrides + // Note: no need to look at PERM because those were added to + // the base targeting model + + size_t l_tankSize = l_maxSize; + uint8_t* l_dest = i_dest; + + // FAPI + l_err = saveOverrideTank( l_dest, + l_tankSize, + &fapi2::theAttrOverrideSync().iv_overrideTank, + AttributeTank::TANK_LAYER_FAPI ); + if( l_err ) + { + break; + } + l_maxSize -= l_tankSize; + io_size += l_tankSize; + + // TARGETING + l_tankSize = l_maxSize; + l_dest = i_dest + io_size; + l_err = saveOverrideTank( l_dest, + l_tankSize, + &Target::theTargOverrideAttrTank(), + AttributeTank::TANK_LAYER_TARG ); + if( l_err ) + { + break; + } + l_maxSize -= l_tankSize; + io_size += l_tankSize; + } while(0); + + TRACFCOMP( g_trac_targeting, EXIT_MRK"AttrRP::_saveOverrides: io_size=%d, l_err=%.8X", io_size, ERRL_GETRC_SAFE(l_err) ); + return l_err; + } + + errlHndl_t AttrRP::saveOverrideTank( uint8_t* i_dest, + size_t& io_size, + AttributeTank* i_tank, + AttributeTank::TankLayer i_layer ) + { + TRACFCOMP( g_trac_targeting, ENTER_MRK"AttrRP::saveOverrideTank: i_dest=%p, io_size=%d, i_layer=%d", i_dest, io_size, i_layer ); + errlHndl_t l_err = nullptr; + size_t l_maxSize = io_size; + io_size = 0; + + // List of chunks we're going to save away + std::vector<AttributeTank::AttributeSerializedChunk> l_chunks; + i_tank->serializeAttributes( + TARGETING::AttributeTank::ALLOC_TYPE_MALLOC, + PAGESIZE, l_chunks ); + + // Copy each chunk until we run out of space + for( auto l_chunk : l_chunks ) + { + // total size of data plus header for this chunk + uint32_t l_chunkSize = l_chunk.iv_size; + l_chunkSize += sizeof(AttrOverrideSection); + // don't want to double-count the data payload... + l_chunkSize -= sizeof(AttrOverrideSection::iv_chunk); + + // look for overflow, but only create 1 error + if( (l_err == nullptr) + && (io_size + l_chunkSize > l_maxSize) ) + { + TRACFCOMP( g_trac_targeting, ERR_MRK"Size of chunk is too big" ); + /*@ + * @errortype + * @moduleid TARG_MOD_SAVE_OVERRIDE_TANK + * @reasoncode TARG_SPACE_OVERRUN + * @userdata1[00:31] Maximum Available size + * @userdata1[32:63] Required size + * @userdata2[00:31] Chunk Size + * @userdata2[32:63] Previous Size + * + * @devdesc Size of override data exceeds available + * buffer space + * + * @custdesc Internal firmware error applying + * custom configuration settings + */ + l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + TARG_CREATE_VMM_SECTIONS, + TARG_RC_MM_PERM_FAIL, + TWO_UINT32_TO_UINT64(l_maxSize, + io_size + l_chunkSize), + TWO_UINT32_TO_UINT64(l_chunkSize, + io_size), + true /*SW Error */); + //deliberately not breaking out here so that we can + // compute the required size and free the memory in + // one place + } + + if( l_err == nullptr ) + { + // fill in the header + AttrOverrideSection* l_header = + reinterpret_cast<AttrOverrideSection*>(i_dest+io_size); + l_header->iv_layer = i_layer; + l_header->iv_size = l_chunk.iv_size; + + // add the data + memcpy( l_header->iv_chunk, + l_chunk.iv_pAttributes, + l_chunk.iv_size ); + } + + io_size += l_chunkSize; + + // freeing data that was allocated by serializeAttributes() + free( l_chunk.iv_pAttributes ); + l_chunk.iv_pAttributes = NULL; + } + + // add a terminator at the end since the size might get lost + // but only if we found some overrides + if( (io_size > 0) + && (io_size + sizeof(AttributeTank::TankLayer) < l_maxSize) ) + { + AttrOverrideSection* l_term = + reinterpret_cast<AttrOverrideSection*>(i_dest+io_size); + l_term->iv_layer = AttributeTank::TANK_LAYER_TERM; + io_size += sizeof(AttributeTank::TankLayer); + } + + TRACFCOMP( g_trac_targeting, ENTER_MRK"AttrRP::saveOverrideTank: io_size=%d", io_size ); + return l_err; + } }; diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml index eb56559c2..d0a0e529d 100755 --- a/src/usr/targeting/common/xmltohb/target_types.xml +++ b/src/usr/targeting/common/xmltohb/target_types.xml @@ -577,6 +577,18 @@ <attribute><id>SCRATCH_UINT32_ARRAY_2</id></attribute> <attribute><id>SCRATCH_UINT64_ARRAY_1</id></attribute> <attribute><id>SCRATCH_UINT64_ARRAY_2</id></attribute> + <attribute><id>SCRATCH_INT8_1</id></attribute> + <attribute><id>SCRATCH_INT8_2</id></attribute> + <attribute><id>SCRATCH_INT32_1</id></attribute> + <attribute><id>SCRATCH_INT32_2</id></attribute> + <attribute><id>SCRATCH_INT64_1</id></attribute> + <attribute><id>SCRATCH_INT64_2</id></attribute> + <attribute><id>SCRATCH_INT8_ARRAY_1</id></attribute> + <attribute><id>SCRATCH_INT8_ARRAY_2</id></attribute> + <attribute><id>SCRATCH_INT32_ARRAY_1</id></attribute> + <attribute><id>SCRATCH_INT32_ARRAY_2</id></attribute> + <attribute><id>SCRATCH_INT64_ARRAY_1</id></attribute> + <attribute><id>SCRATCH_INT64_ARRAY_2</id></attribute> <attribute> <id>AFFINITY_PATH</id> <default>affinity:sys-0</default> diff --git a/src/usr/targeting/runtime/attrPlatOverride_rt.C b/src/usr/targeting/runtime/attrPlatOverride_rt.C index 2c28edec8..92a937f03 100644 --- a/src/usr/targeting/runtime/attrPlatOverride_rt.C +++ b/src/usr/targeting/runtime/attrPlatOverride_rt.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2016 */ +/* Contributors Listed Below - COPYRIGHT 2014,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -89,37 +89,59 @@ int apply_attr_override(uint8_t* i_data, void applyTempOverrides() { - // With FSP, we can not access PNOR, just return - if(INITSERVICE::spBaseServicesEnabled()) + TRACFCOMP(g_trac_targeting, ENTER_MRK"applyTempOverrides"); + errlHndl_t l_err = NULL; + + // Get a pointer to the reserved memory where HB + // saved the overrides during boot + uint64_t l_overAddr = 0; + uint8_t* l_overPtr = nullptr; + if( g_hostInterfaces != NULL && + g_hostInterfaces->get_reserved_mem ) { + l_overAddr = g_hostInterfaces + ->get_reserved_mem("ibm,hbrt-targetoverride-image",0); + if( l_overAddr != 0 ) + { + TRACFCOMP(g_trac_targeting, "Overrides found at %.16X", l_overAddr ); + l_overPtr = reinterpret_cast<uint8_t*>(l_overAddr); + } + else + { + // grab the data we stashed at the end of the targeting data + l_overAddr = g_hostInterfaces + ->get_reserved_mem("ibm,hbrt-target-image",0); + if( l_overAddr != 0 ) + { + l_overAddr += (1*MEGABYTE - 64*KILOBYTE); + TRACFCOMP(g_trac_targeting, "NULL from get_reserved_mem, using stashed value at %.llX instead", l_overAddr ); + l_overPtr = reinterpret_cast<uint8_t*>(l_overAddr); + } + } + } + + // Having no overrides is a normal thing + if( l_overPtr == nullptr ) + { + TRACFCOMP(g_trac_targeting, "No Overrides found" ); + TRACFCOMP(g_trac_targeting, EXIT_MRK"applyTempOverrides"); return; } - TRACFCOMP(g_trac_targeting, ENTER_MRK"applyTempOverrides"); - errlHndl_t l_err = NULL; + // Use a faux PNOR Section that is associated + // with the data in mainstore PNOR::SectionInfo_t l_info; - // Get temporary attribute overrides from pnor - l_err = PNOR::getSectionInfo(PNOR::ATTR_TMP, l_info); + l_info.vaddr = l_overAddr; + l_info.size = 64*KILOBYTE; //@fixme-RTC:171863-use real size + l_info.id = PNOR::ATTR_TMP; + l_info.name = "HBRT Overrides"; - // Attr override sections are optional so just delete error + TRACFCOMP(g_trac_targeting," HBRT: processing overrides from boot"); + l_err = TARGETING::getAttrOverrides(l_info); if (l_err) { - TRACFCOMP(g_trac_targeting," HBRT: error getting ATTR_TMP pnor " - "section. Not applying temp attributes."); - delete l_err; - l_err = NULL; - } - else - { - TRACFCOMP(g_trac_targeting," HBRT: processing temporary " - "overrides"); - l_err = TARGETING::getAttrOverrides(l_info); - if (l_err) - { - TRACFCOMP(g_trac_targeting," HBRT: Failed applyTempOverrides:" - " getting temporary overrides"); - errlCommit( l_err, TARG_COMP_ID ); - } + TRACFCOMP(g_trac_targeting," HBRT: Failed applying overrides"); + errlCommit( l_err, TARG_COMP_ID ); } TRACFCOMP(g_trac_targeting, EXIT_MRK"applyTempOverrides"); diff --git a/src/usr/targeting/runtime/attrrp_rt.C b/src/usr/targeting/runtime/attrrp_rt.C index cf4370f05..4f323e699 100644 --- a/src/usr/targeting/runtime/attrrp_rt.C +++ b/src/usr/targeting/runtime/attrrp_rt.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2016 */ +/* Contributors Listed Below - COPYRIGHT 2013,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -38,12 +38,15 @@ namespace TARGETING { void AttrRP::startup(errlHndl_t& io_taskRetErrl, bool isMpipl) { + TRACFCOMP(g_trac_targeting, "AttrRP::startup"); errlHndl_t l_errl = NULL; do { - TargetingHeader* l_header = reinterpret_cast<TargetingHeader*>( - g_hostInterfaces->get_reserved_mem("ibm,hbrt-target-image",0)); + TargetingHeader* l_header = + reinterpret_cast<TargetingHeader*>( + g_hostInterfaces-> + get_reserved_mem(HBRT_RSVD_MEM__ATTRIBUTES,0)); if ((NULL == l_header) || (l_header->eyeCatcher != PNOR_TARG_EYE_CATCHER)) diff --git a/src/usr/targeting/runtime/test/testtargeting.H b/src/usr/targeting/runtime/test/testtargeting.H index 68ef93603..99c0fbbb4 100644 --- a/src/usr/targeting/runtime/test/testtargeting.H +++ b/src/usr/targeting/runtime/test/testtargeting.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2016 */ +/* Contributors Listed Below - COPYRIGHT 2013,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -119,6 +119,35 @@ class TargetingTestSuite : public CxxTest::TestSuite } } + // Verify HBRT is picking up the overrides from the IPL + // Note: must be before testApplyAttrOverrides, because that + // test clears out all of the overrides + void testIplOverrides() + { + using namespace TARGETING; + TRACFCOMP(g_trac_targeting,"testIplOverrides"); + + //See rt_get_targ_override() for setup details about setting + // SYSTEM:ATTR_SCRATCH_INT32_1 = -99 + + TargetService& l_targetService = targetService(); + TARGETING::Target* l_pTarget = NULL; + (void) l_targetService.getTopLevelTarget(l_pTarget); + if (l_pTarget == NULL) + { + TS_FAIL("Top level target handle is NULL"); + } + else + { + ATTR_SCRATCH_INT32_1_type l_val = + l_pTarget->getAttr<TARGETING::ATTR_SCRATCH_INT32_1>(); + if( l_val != -99 ) + { + TS_FAIL("testIplOverrides> SCRATCH_INT32_1=%d, expected %d", l_val, -99 ); + } + } + } + void testApplyAttrOverrides() { using namespace TARGETING; @@ -218,8 +247,18 @@ class TargetingTestSuite : public CxxTest::TestSuite l_attrNewVal,l_attrOverrideVal); break; } - TRACFCOMP(g_trac_targeting,"testApplyAttrOverrides SUCCESS"); + // verify that any previous overrides are not still there + ATTR_SCRATCH_INT32_1_type l_val = + l_pTarget->getAttr<TARGETING::ATTR_SCRATCH_INT32_1>(); + if( l_val == -99 ) + { + TS_FAIL("testApplyAttrOverrides> SCRATCH_INT32_1=%d, expected %d", -99, 0 ); + break; + } + + TRACFCOMP(g_trac_targeting,"testApplyAttrOverrides SUCCESS"); } while (0); } + }; diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H index 8e07cf021..8914c709b 100644 --- a/src/usr/testcore/rtloader/loader.H +++ b/src/usr/testcore/rtloader/loader.H @@ -42,6 +42,8 @@ #include <devicefw/userif.H> #include <pnor/ecc.H> #include <ipmi/ipmiif.H> +#include <targeting/common/attributeTank.H> + trace_desc_t* g_trac_hbrt = NULL; TRAC_INIT(&g_trac_hbrt, "HBRT_TEST", 2*KILOBYTE); @@ -331,10 +333,12 @@ class RuntimeLoaderTest : public CxxTest::TestSuite static uint64_t rt_get_reserved_mem(const char* i_region, uint32_t i_instance) { - if (0 == strcmp(i_region, "ibm,hbrt-vpd-image")) + if (0 == strcmp(i_region, HBRT_RSVD_MEM__VPD_CACHE)) return rt_get_vpd(); - else if (0 == strcmp(i_region, "ibm,hbrt-target-image")) + else if (0 == strcmp(i_region, HBRT_RSVD_MEM__ATTRIBUTES)) return rt_get_targ(); + else if (0 == strcmp(i_region, HBRT_RSVD_MEM__OVERRIDES)) + return rt_get_targ_override(); else return 0; } @@ -543,6 +547,49 @@ class RuntimeLoaderTest : public CxxTest::TestSuite return cv_targ_addr; } + static uint64_t rt_get_targ_override() + { + using namespace TARGETING; + if (cv_targ_over_addr != 0) + { + return cv_targ_over_addr; + } + + // add an override to use in a later test + AttributeTank* l_tank = + &Target::theTargOverrideAttrTank(); + ATTR_SCRATCH_INT32_1_type l_val = -99; + l_tank->setAttribute(ATTR_SCRATCH_INT32_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + AttributeTank::ATTR_NODE_NA, + 0, sizeof(l_val), &l_val); + + // copy overrides into local buffer + size_t l_actualSize = 64*KILOBYTE; + uint8_t* l_overrideData = + reinterpret_cast<uint8_t*>(malloc(l_actualSize)); + errlHndl_t l_elog = TARGETING::AttrRP::saveOverrides( + l_overrideData, + l_actualSize ); + if(l_elog) + { + TRACFCOMP( g_trac_hbrt, ERR_MRK" Attribute Overrides exceed allocated space" ); + errlCommit( l_elog, CXXTEST_COMP_ID ); + } + else if( l_actualSize == 0 ) + { + TRACFCOMP( g_trac_hbrt, INFO_MRK" No Attribute Overrides Present" ); + } + else + { + cv_targ_over_addr = reinterpret_cast<uint64_t>(l_overrideData); + } + + return cv_targ_over_addr; + } + static int rt_ipmi_msg(uint8_t netfn, uint8_t cmd, void *tx_buf, size_t tx_size, void *rx_buf, size_t *rx_size) @@ -574,6 +621,7 @@ class RuntimeLoaderTest : public CxxTest::TestSuite static uint64_t cv_vpd_phys_addr; static uint64_t cv_targ_addr; static uint64_t cv_targ_phys_addr; + static uint64_t cv_targ_over_addr; }; @@ -583,6 +631,7 @@ uint64_t RuntimeLoaderTest::cv_vpd_addr = 0; uint64_t RuntimeLoaderTest::cv_vpd_phys_addr = 0; uint64_t RuntimeLoaderTest::cv_targ_addr = 0; uint64_t RuntimeLoaderTest::cv_targ_phys_addr = 0; +uint64_t RuntimeLoaderTest::cv_targ_over_addr = 0; |