From a6f46d0a9461b96781bc85c9fd82c24d14b5ce42 Mon Sep 17 00:00:00 2001 From: Dean Sanner Date: Wed, 10 Jul 2013 09:28:50 -0500 Subject: Hostboot support for running Sapphire on FSP Key Changes: --Distinguish between Sapphire SPless/FSP --Place HOMER image at top of memory --Allow SPIRA to be outside of 128MB "HDAT" window --Don't clear the PORE BARs in Sapphire mode --Force payload address to 0 if in sapphire mode Change-Id: I1e4d5bb68dad51e4408a568217b08a6aadef2494 RTC: 73481 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5361 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III --- src/include/usr/initservice/initserviceif.H | 26 ++ src/include/usr/isteps/istep21list.H | 1 + src/include/usr/targeting/common/util.H | 10 + src/usr/dump/dumpCollect.C | 1 + .../hwp/build_winkle_images/build_winkle_images.C | 59 ++- src/usr/hwpf/hwp/core_activate/core_activate.C | 86 +--- src/usr/hwpf/hwp/start_payload/makefile | 29 +- src/usr/hwpf/hwp/start_payload/start_payload.C | 100 ++++- .../initservice/istepdispatcher/istepdispatcher.C | 20 - .../initservice/istepdispatcher/istepdispatcher.H | 6 - src/usr/runtime/hdatservice.C | 440 ++++++++++++--------- src/usr/runtime/hdatservice.H | 81 +++- src/usr/runtime/test/hdatservicetest.H | 2 +- src/usr/targeting/common/util.C | 18 + 14 files changed, 552 insertions(+), 327 deletions(-) diff --git a/src/include/usr/initservice/initserviceif.H b/src/include/usr/initservice/initserviceif.H index 77db81ea4..e32e57640 100644 --- a/src/include/usr/initservice/initserviceif.H +++ b/src/include/usr/initservice/initserviceif.H @@ -25,6 +25,10 @@ #include #include +#include +#include +#include +#include namespace INITSERVICE { @@ -94,6 +98,28 @@ void doShutdown ( uint64_t i_status, uint64_t i_payload_base = 0, uint64_t i_payload_entry = 0, uint64_t i_payload_data = 0) NO_RETURN; + +/** + * @brief This function will return whether or not we are SPless + * + * @return bool - whether we are SPLESS. + */ +inline bool spLess ( void ) +{ + bool spless = false; + TARGETING::Target * sys = NULL; + TARGETING::targetService().getTopLevelTarget( sys ); + TARGETING::SpFunctions spfuncs; + if( sys && + sys->tryGetAttr(spfuncs) && + !spfuncs.mailboxEnabled ) + { + spless = true; + } + + return spless; } +} + #endif diff --git a/src/include/usr/isteps/istep21list.H b/src/include/usr/isteps/istep21list.H index 7b4bfb8e1..00a882483 100644 --- a/src/include/usr/isteps/istep21list.H +++ b/src/include/usr/isteps/istep21list.H @@ -105,6 +105,7 @@ namespace INITSERVICE const DepModInfo g_istep21Dependancies = { { + DEP_LIB(libbuild_winkle_images.so), DEP_LIB(libstart_payload.so), DEP_LIB(libruntime.so), DEP_LIB(libdevtree.so), diff --git a/src/include/usr/targeting/common/util.H b/src/include/usr/targeting/common/util.H index 4ea2ab8de..cea0e1690 100644 --- a/src/include/usr/targeting/common/util.H +++ b/src/include/usr/targeting/common/util.H @@ -91,6 +91,16 @@ void clear_hwas_changed_bit(Target * i_target, const HWAS_CHANGED_BIT i_bit); */ bool is_phyp_load( ATTR_PAYLOAD_KIND_type* o_type = NULL ); +/** + * @brief Utility function to determine if Sapphire is the payload + * + * @description If the payload kind is Sapphire returns true. Does + * not matter if it is Sapphire with FSP or standalone + * + * @return bool True when loadding sapphire + */ +bool is_sapphire_load(void); + } #endif // __TARGETING_COMMON_UTIL_H diff --git a/src/usr/dump/dumpCollect.C b/src/usr/dump/dumpCollect.C index daa699859..8f85f44a9 100644 --- a/src/usr/dump/dumpCollect.C +++ b/src/usr/dump/dumpCollect.C @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C b/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C index 51c90a001..ff6e936f7 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C +++ b/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C @@ -75,6 +75,7 @@ #include "p8_pm.H" // PM_INIT #include "p8_set_pore_bar/p8_poreslw_init.H" #include "p8_slw_build/sbe_xip_image.h" +#include namespace BUILD_WINKLE_IMAGES @@ -310,6 +311,44 @@ errlHndl_t applyPoreGenCpuRegs( TARGETING::Target *i_cpuTarget, return l_errl; } +// +// Utility function to obtain the highest known address in the system +// +uint64_t get_top_mem_addr(void) +{ + uint64_t top_addr = 0; + + do + { + // Get all functional proc chip targets + TARGETING::TargetHandleList l_cpuTargetList; + getAllChips(l_cpuTargetList, TYPE_PROC); + + for ( size_t proc = 0; proc < l_cpuTargetList.size(); proc++ ) + { + TARGETING::Target * l_pProc = l_cpuTargetList[proc]; + + //Not checking success here as fail results in no change to + // top_addr + uint64_t l_mem_bases[8] = {0,}; + uint64_t l_mem_sizes[8] = {0,}; + l_pProc->tryGetAttr(l_mem_bases); + l_pProc->tryGetAttr(l_mem_sizes); + + for (size_t i=0; i< 8; i++) + { + if(l_mem_sizes[i]) //non zero means that there is memory present + { + top_addr = std::max(top_addr, + l_mem_bases[i] + l_mem_sizes[i]); + } + } + } + }while(0); + + return top_addr; +} + // // Wrapper function to call host_build_winkle // @@ -319,10 +358,9 @@ void* call_host_build_winkle( void *io_pArgs ) const char *l_pPoreImage = NULL; uint32_t l_poreSize = 0; - void *l_pRealMemBase = - reinterpret_cast - (VMM_HOMER_REGION_START_ADDR ); - void* l_pVirtMemBase = NULL; + void *l_pRealMemBase = NULL; + void* l_pVirtMemBase = NULL; + uint64_t l_memBase = VMM_HOMER_REGION_START_ADDR; ISTEP_ERROR::IStepError l_StepError; @@ -338,6 +376,19 @@ void* call_host_build_winkle( void *io_pArgs ) assert(VMM_HOMER_REGION_SIZE <= THIRTYTWO_GB, "host_build_winkle: Unsupported HOMER Region size"); + //If running Sapphire need to place this at the top of memory + if(is_sapphire_load()) + { + l_memBase = get_top_mem_addr(); + assert (l_memBase != 0, + "host_build_winkle: Top of memory was 0!"); + l_memBase -= VMM_HOMER_REGION_SIZE; + } + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "HOMER base = %x", l_memBase); + + l_pRealMemBase = reinterpret_cast(l_memBase ); + l_pVirtMemBase = mm_block_map(l_pRealMemBase, VMM_HOMER_REGION_SIZE); diff --git a/src/usr/hwpf/hwp/core_activate/core_activate.C b/src/usr/hwpf/hwp/core_activate/core_activate.C index 9524e0069..d3433f3f4 100644 --- a/src/usr/hwpf/hwp/core_activate/core_activate.C +++ b/src/usr/hwpf/hwp/core_activate/core_activate.C @@ -50,6 +50,7 @@ #include #include #include +#include // fapi support #include @@ -331,84 +332,10 @@ void* call_host_activate_slave_cores( void *io_pArgs ) } else { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "set PORE bars back to 0" ); - - // @todo see RTC 51264 - - // This has to be modified if we are loading other AVP's instead - // of PHYP + // Call proc_post_winkle TARGETING::TargetHandleList l_procTargetList; getAllChips(l_procTargetList, TYPE_PROC); - // loop thru all the cpus and reset the pore bars. - for (TargetHandleList::const_iterator - l_proc_iter = l_procTargetList.begin(); - l_proc_iter != l_procTargetList.end(); - ++l_proc_iter) - { - // make a local copy of the CPU target - const TARGETING::Target* l_proc_target = *l_proc_iter; - - // trace HUID - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "target HUID %.8X", TARGETING::get_huid(l_proc_target)); - - // cast OUR type of target to a FAPI type of target. - fapi::Target l_fapi_proc_target( TARGET_TYPE_PROC_CHIP, - (const_cast(l_proc_target)) ); - - // reset pore bar notes: - // A mem_size of 0 means to ignore the image address - // This image should have been moved to memory after winkle - - // call the HWP with each fapi::Target - FAPI_INVOKE_HWP( l_errl, - p8_set_pore_bar, - l_fapi_proc_target, - 0, - 0, - 0, - SLW_MEMORY - ); - if ( l_errl ) - { - // capture the target data in the elog - ErrlUserDetailsTarget(l_proc_target).addToLog( l_errl ); - - /*@ - * @errortype - * @reasoncode ISTEP_RESET_PORE_BARS_FAILED - * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE - * @moduleid ISTEP_HOST_ACTIVATE_SLAVE_CORES - * @userdata1 bytes 0-1: plid identifying first error - * bytes 2-3: reason code of first error - * @userdata2 bytes 0-1: total number of elogs included - * bytes 2-3: N/A - * @devdesc call to set_pore_bars failed. - * see error identified by the plid in - * user data field. - */ - l_stepError.addErrorDetails(ISTEP_RESET_PORE_BARS_FAILED, - ISTEP_HOST_ACTIVATE_SLAVE_CORES, - l_errl ); - - errlCommit( l_errl, HWPF_COMP_ID ); - - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "ERROR : p8_set_pore_bar, PLID=0x%x", - l_errl->plid() ); - } - else - { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "SUCCESS : p8_set_pore_bar" ); - } - - } // end for - - - // Call proc_post_winkle - // Done activate all master/slave cores. // Run post winkle check on all EX targets, one proc at a time. for (TargetHandleList::const_iterator l_procIter = @@ -710,6 +637,15 @@ void* call_host_ipl_complete( void *io_pArgs ) break; } + //If Sapphire Payload need to set payload base to zero + if (is_sapphire_load()) + { + TARGETING::Target* sys = NULL; + TARGETING::targetService().getTopLevelTarget(sys); + assert( sys != NULL ); + sys->setAttr(0x0); + } + // Sync attributes to Fsp l_err = syncAllAttributesToFsp(); diff --git a/src/usr/hwpf/hwp/start_payload/makefile b/src/usr/hwpf/hwp/start_payload/makefile index 5f66a867c..fe3458284 100644 --- a/src/usr/hwpf/hwp/start_payload/makefile +++ b/src/usr/hwpf/hwp/start_payload/makefile @@ -1,25 +1,25 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. # -# $Source: src/usr/hwpf/hwp/start_payload/makefile $ +# $Source: src/usr/hwpf/hwp/start_payload/makefile $ # -# IBM CONFIDENTIAL +# IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2012 +# COPYRIGHT International Business Machines Corp. 2012,2013 # -# p1 +# p1 # -# Object Code Only (OCO) source materials -# Licensed Internal Code Source Materials -# IBM HostBoot Licensed Internal Code +# 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 other- -# wise divested of its trade secrets, irrespective of what has -# been deposited with the U.S. Copyright Office. +# 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 +# Origin: 30 # -# IBM_PROLOG_END +# IBM_PROLOG_END_TAG ROOTPATH = ../../../../.. @@ -41,6 +41,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/start_payload ## NOTE: add a new EXTRAINCDIR when you add a new HWP ## EXAMPLE: ## EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/start_payload/ +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar ## NOTE: add new object files when you add a new HWP diff --git a/src/usr/hwpf/hwp/start_payload/start_payload.C b/src/usr/hwpf/hwp/start_payload/start_payload.C index 3c06db171..36c076026 100644 --- a/src/usr/hwpf/hwp/start_payload/start_payload.C +++ b/src/usr/hwpf/hwp/start_payload/start_payload.C @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,8 @@ // fapi support #include #include +#include "p8_set_pore_bar.H" + #include "start_payload.H" #include @@ -102,6 +105,76 @@ errlHndl_t callShutdown ( void ); errlHndl_t notifyFsp ( bool i_istepModeFlag, TARGETING::SpFunctions i_spFuncs ); +/** + * @brief This function will clear the PORE BARs. Needs to be done + * depending on payload type + * + * @return errlHndl_t - NULL if successful, otherwise a pointer to the error + * log. + */ +errlHndl_t clearPoreBars ( void ) +{ + errlHndl_t l_errl = NULL; + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "set PORE bars back to 0" ); + + TARGETING::TargetHandleList l_procTargetList; + getAllChips(l_procTargetList, TYPE_PROC); + + // loop thru all the cpus and reset the pore bars. + for (TargetHandleList::const_iterator + l_proc_iter = l_procTargetList.begin(); + l_proc_iter != l_procTargetList.end(); + ++l_proc_iter) + { + // make a local copy of the CPU target + const TARGETING::Target* l_proc_target = *l_proc_iter; + + // trace HUID + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "target HUID %.8X", TARGETING::get_huid(l_proc_target)); + + // cast OUR type of target to a FAPI type of target. + fapi::Target l_fapi_proc_target( TARGET_TYPE_PROC_CHIP, + (const_cast( + l_proc_target)) ); + + // reset pore bar notes: + // A mem_size of 0 means to ignore the image address + // This image should have been moved to memory after winkle + + // call the HWP with each fapi::Target + FAPI_INVOKE_HWP( l_errl, + p8_set_pore_bar, + l_fapi_proc_target, + 0, + 0, + 0, + SLW_MEMORY + ); + if ( l_errl ) + { + // capture the target data in the elog + ERRORLOG::ErrlUserDetailsTarget(l_proc_target).addToLog( l_errl ); + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR : p8_set_pore_bar, PLID=0x%x", + l_errl->plid() ); + break; + } + else + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "SUCCESS : p8_set_pore_bar" ); + } + + } // end for + + return l_errl; +} + + // // Wrapper function to call host_runtime_setup // @@ -144,14 +217,24 @@ void* call_host_runtime_setup( void *io_pArgs ) break; } - // Only run OCC in AVP mode. Run the rest in !AVP mode + // Get the Payload kind -- various tasks rely on payload TARGETING::Target * sys = NULL; TARGETING::targetService().getTopLevelTarget( sys ); assert(sys != NULL); - TARGETING::ATTR_PAYLOAD_KIND_type payload_kind = sys->getAttr(); + //If PHYP then clean the PORE BARs + if( TARGETING::PAYLOAD_KIND_PHYP == payload_kind ) + { + l_err = clearPoreBars(); + if( l_err ) + { + break; + } + } + + //Only run OCC in AVP mode. Run the rest in !AVP mode if( TARGETING::PAYLOAD_KIND_AVP == payload_kind ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Skipping host_runtime_setup in AVP mode. Starting OCC" ); @@ -201,9 +284,11 @@ void* call_host_runtime_setup( void *io_pArgs ) } break; } - else if( TARGETING::PAYLOAD_KIND_SAPPHIRE == payload_kind) + else if( is_sapphire_load() && + INITSERVICE::spLess()) { - // Write the devtree out + // Write the devtree out when in SPLess + // Sapphire mode l_err = DEVTREE::build_flatdevtree(); if ( l_err ) { @@ -434,10 +519,9 @@ errlHndl_t callShutdown ( void ) break; } - // Load payload data if in SAPPHIRE mode - TARGETING::ATTR_PAYLOAD_KIND_type payload_kind - = sys->getAttr(); - if( TARGETING::PAYLOAD_KIND_SAPPHIRE == payload_kind ) + // Load payload data if in SPLess SAPPHIRE mode + if( is_sapphire_load() && + INITSERVICE::spLess()) { payloadData = DEVTREE::get_flatdevtree_phys_addr(); } diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C index 104f204ef..2b5c86bc9 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.C +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C @@ -983,26 +983,6 @@ bool IStepDispatcher::getIStepMode( ) const } -// ---------------------------------------------------------------------------- -// IStepDispatcher::spLess() -// ---------------------------------------------------------------------------- -bool IStepDispatcher::spLess ( void ) -{ - bool spless = true; - TARGETING::Target * sys = NULL; - TARGETING::targetService().getTopLevelTarget( sys ); - TARGETING::SpFunctions spfuncs; - if( sys && - sys->tryGetAttr(spfuncs) && - spfuncs.mailboxEnabled ) - { - spless = false; - } - - return spless; -} - - // ---------------------------------------------------------------------------- // IStepDispatcher::checkMpiplMode() // ---------------------------------------------------------------------------- diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H index 3bfdf5eff..2ad5eb8b5 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.H +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H @@ -293,12 +293,6 @@ private: */ void setIstepInfo ( uint16_t i_type ); - /** - * @brief This function will return whether or not we are SPless - * - * @return bool - whether we are SPLESS. - */ - bool spLess ( void ); /** * @brief This function will check whether or not we are in MPIPL mode diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C index a2b273e48..4de60449b 100644 --- a/src/usr/runtime/hdatservice.C +++ b/src/usr/runtime/hdatservice.C @@ -23,9 +23,10 @@ #include #include #include -#include #include #include +#include +#include #include #include #include @@ -85,64 +86,67 @@ const uint64_t HDAT_MEM_SIZE = 128*MEGABYTE; /** * @brief Verify that a block of memory falls inside a safe range - * @param i_base Payload base address * @param i_addr Address to check * @param i_size Number of bytes to check * @return Error if address seems wrong */ -errlHndl_t verify_hdat_address( uint64_t i_base, - uint64_t i_addr, - size_t i_size ) +errlHndl_t hdatService::verify_hdat_address( void* i_addr, + size_t i_size ) { errlHndl_t errhdl = NULL; + bool found = false; + uint64_t l_end = reinterpret_cast(i_addr) + + i_size; // Make sure that the entire range is within the memory - // space that we allocated - if( (i_addr < i_base) - || ((i_addr+i_size) > (i_base+HDAT_MEM_SIZE)) ) + // space that we mapped + for(memRegionItr region = iv_mem_regions.begin(); + (region != iv_mem_regions.end()) && !found; ++region) { - TRACFCOMP( g_trac_runtime, "Invalid HDAT Address : i_base=0x%X, i_addr=0x%X, i_size=0x%X", i_base, i_addr, i_size ); + hdatMemRegion_t memR = *region; + + uint64_t l_range_end = reinterpret_cast(memR.virt_addr) + + memR.size; + if ((i_addr >= memR.virt_addr) && + (l_end <= l_range_end)) + { + found = true; + break; + } + } + + if(!found) + { + TRACFCOMP( g_trac_runtime, "Invalid HDAT Address : i_addr=%p, i_size=0x%X", i_addr, i_size ); + for(memRegionItr region = iv_mem_regions.begin(); + (region != iv_mem_regions.end()) && !found; ++region) + { + hdatMemRegion_t memR = *region; + TRACFCOMP( g_trac_runtime, " Region : virt_addr=0x%X, size=0x%X", + memR.virt_addr, memR.size ); + } /*@ * @errortype * @moduleid RUNTIME::MOD_HDATSERVICE_VERIFY_HDAT_ADDRESS * @reasoncode RUNTIME::RC_INVALID_ADDRESS - * @userdata1[0:31] Start of address range under test - * @userdata1[32:63] Size of address range under test - * @userdata2[0:31] Payload base address - * @userdata2[32:63] Size of mapped HDAT section + * @userdata1 Start of address range under test + * @userdata2 Size of address range under test * @devdesc HDAT data block falls outside valid range */ errhdl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, RUNTIME::MOD_HDATSERVICE_VERIFY_HDAT_ADDRESS, RUNTIME::RC_INVALID_ADDRESS, - TWO_UINT32_TO_UINT64(i_addr,i_size), - TWO_UINT32_TO_UINT64(i_base,HDAT_MEM_SIZE) ); + reinterpret_cast(i_addr), + reinterpret_cast(i_size)); errhdl->collectTrace("RUNTIME",1024); } return errhdl; } -// Handy overloading to avoid messy casts by the caller -errlHndl_t verify_hdat_address( uint64_t i_base, - void* i_addr, - size_t i_size ) -{ - return verify_hdat_address( i_base, - reinterpret_cast(i_addr), - i_size ); -} -/** - * @brief Verify the header portion of an HDAT section - * @param i_base Payload base address - * @param i_header Actual header data - * @param i_exp Expected header data - * @return Error on mismatch - */ -errlHndl_t check_header( uint64_t i_base, - hdatHDIF_t* i_header, - const hdatHeaderExp_t& i_exp ) +errlHndl_t hdatService::check_header( hdatHDIF_t* i_header, + const hdatHeaderExp_t& i_exp ) { TRACUCOMP( g_trac_runtime, "check_header(%s)> %.4X : %.4X : %s", i_exp.name, i_header->hdatStructId, i_header->hdatVersion, i_header->hdatStructName ); errlHndl_t errhdl = NULL; @@ -150,8 +154,7 @@ errlHndl_t check_header( uint64_t i_base, do { // Make sure the Tuple is pointing somewhere valid - errhdl = verify_hdat_address( i_base, - i_header, + errhdl = verify_hdat_address( i_header, sizeof(hdatHDIF_t) ); if( errhdl ) { break; } @@ -190,24 +193,15 @@ errlHndl_t check_header( uint64_t i_base, return errhdl; } -/** - * @brief Verify basic characteristics of a HDAT Tuple structure - * @param i_base Payload base address - * @param i_section Section name being verified - * @param i_tuple Tuple to check - * @return Error if Tuple is unallocated - */ -errlHndl_t check_tuple( uint64_t i_base, - const RUNTIME::SectionId i_section, - hdat5Tuple_t* i_tuple ) +errlHndl_t hdatService::check_tuple( const RUNTIME::SectionId i_section, + hdat5Tuple_t* i_tuple ) { errlHndl_t errhdl = NULL; do { // Make sure the Tuple is in valid memory - errhdl = verify_hdat_address( i_base, - i_tuple, + errhdl = verify_hdat_address( i_tuple, sizeof(hdat5Tuple_t) ); if( errhdl ) { break; } @@ -250,33 +244,33 @@ errlHndl_t hdatService::get_standalone_section( size_t& o_dataSize ) { errlHndl_t errhdl = NULL; - uint64_t v_baseAddr = reinterpret_cast(iv_payload_addr); - uint64_t v_dumpAddr = reinterpret_cast(iv_dumptest_addr); if( RUNTIME::HSVC_SYSTEM_DATA == i_section ) { - o_dataAddr = v_baseAddr; + o_dataAddr = reinterpret_cast(iv_mem_regions[0].virt_addr); o_dataSize = 512*KILOBYTE; } else if( RUNTIME::HSVC_NODE_DATA == i_section ) { - o_dataAddr = v_baseAddr + 512*KILOBYTE; + o_dataAddr = reinterpret_cast(iv_mem_regions[0].virt_addr) + + 512*KILOBYTE; o_dataSize = HSVC_TEST_MEMORY_SIZE - 512*KILOBYTE; } else if( RUNTIME::MS_DUMP_SRC_TBL == i_section ) { - o_dataAddr = v_dumpAddr; + o_dataAddr = reinterpret_cast(iv_mem_regions[1].virt_addr); o_dataSize = DUMP_TEST_SRC_MEM_SIZE; } else if( RUNTIME::MS_DUMP_DST_TBL == i_section ) { - o_dataAddr = v_dumpAddr + DUMP_TEST_SRC_MEM_SIZE; + o_dataAddr = reinterpret_cast(iv_mem_regions[1].virt_addr) + + DUMP_TEST_SRC_MEM_SIZE; o_dataSize = DUMP_TEST_DST_MEM_SIZE; } else if( RUNTIME::MS_DUMP_RESULTS_TBL == i_section ) { - o_dataAddr = v_dumpAddr + DUMP_TEST_SRC_MEM_SIZE + - DUMP_TEST_DST_MEM_SIZE; + o_dataAddr = reinterpret_cast(iv_mem_regions[1].virt_addr) + + DUMP_TEST_SRC_MEM_SIZE + DUMP_TEST_DST_MEM_SIZE; o_dataSize = DUMP_TEST_RESULTS_MEM_SIZE; } else @@ -302,9 +296,7 @@ errlHndl_t hdatService::get_standalone_section( } hdatService::hdatService(void) -:iv_payload_addr(NULL) -,iv_dumptest_addr(NULL) -,iv_spiraL(NULL) +:iv_spiraL(NULL) ,iv_spiraH(NULL) ,iv_spiraS(NULL) { @@ -312,27 +304,142 @@ hdatService::hdatService(void) hdatService::~hdatService(void) { - if(iv_payload_addr) + for(memRegionItr region = iv_mem_regions.begin(); + (region != iv_mem_regions.end()); ++region) { - mm_block_unmap(iv_payload_addr); - iv_payload_addr = NULL; + mm_block_unmap((*region).virt_addr); } - if(iv_dumptest_addr) + iv_mem_regions.clear(); +} + +errlHndl_t hdatService::mapRegion(uint64_t i_addr, size_t i_bytes, + uint64_t &o_vaddr) +{ + errlHndl_t errhdl = NULL; + + do { - mm_block_unmap(iv_dumptest_addr); - iv_dumptest_addr = NULL; - } + hdatMemRegion_t l_mem; + + l_mem.phys_addr = i_addr; + l_mem.size = i_bytes; + + // make sure that our numbers are page-aligned, required by mm call + l_mem.phys_addr = ALIGN_PAGE_DOWN(l_mem.phys_addr); //round down + l_mem.size = ALIGN_PAGE(l_mem.size) + (4*KILOBYTE); //round up + + l_mem.virt_addr = mm_block_map(reinterpret_cast(l_mem.phys_addr), + l_mem.size ); + TRACFCOMP( g_trac_runtime, "mapRegion> Mapped in 0x%X-0x%X (%X ) @ %p", l_mem.phys_addr, + l_mem.phys_addr+l_mem.size, l_mem.size, l_mem.virt_addr); + + if (NULL == l_mem.virt_addr) + { + TRACFCOMP( g_trac_runtime, "Failure calling mm_block_map : virt_addr=%p", + l_mem.virt_addr ); + /*@ + * @errortype + * @moduleid RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA + * @reasoncode RUNTIME::RC_CANNOT_MAP_MEMORY + * @userdata1 Starting Address + * @userdata2 Size + * @devdesc Error mapping in memory + */ + errhdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA, + RUNTIME::RC_CANNOT_MAP_MEMORY, + l_mem.phys_addr, + l_mem.size ); + errhdl->collectTrace("RUNTIME",1024); + break; + } + + iv_mem_regions.push_back(l_mem); + o_vaddr = reinterpret_cast(l_mem.virt_addr); + o_vaddr = o_vaddr + (i_addr-l_mem.phys_addr); + }while(0); + + return errhdl; +} + +errlHndl_t hdatService::getSpiraTupleVA(hdat5Tuple_t* i_tuple, + uint64_t & o_vaddr) +{ + errlHndl_t errhdl = NULL; + bool found = false; + o_vaddr = 0x0; + uint64_t l_phys_addr, l_size; + + //PHYP and Sapphire have different philsophies about how they + //lay the HDAT memory out. PHYP puts it all within a 128MB + //area. Sapphire puts the NACA in one area and then all of the + //SPIRA data sections in another (way up in memory). This + //function checks to see if the requested region is already + //mapped, and if not it will map it. + // + //It then returns the "base" virtual pointer for the requested + //tuple + + //Note that if Sapphire/PHYP change how they do things this + //code will break (and the various address checking is expected + //to catch it) + + do + { + // Get the absolute address = tuple addr + HRMOR (payload base) + l_phys_addr = i_tuple->hdatAbsAddr + iv_mem_regions[0].phys_addr; + l_size = i_tuple->hdatActualCnt * i_tuple->hdatActualSize; + + TRACUCOMP( g_trac_runtime, "SPIRA Data ptr 0x%X, size 0x%X", + l_phys_addr, l_size); + + //Check to see if the requested data fully falls within + //an existing mapping if so do nothing + for(memRegionItr region = iv_mem_regions.begin(); + (region != iv_mem_regions.end()) && !found; ++region) + { + hdatMemRegion_t memR = *region; + + if ((l_phys_addr >= memR.phys_addr) && + ((l_phys_addr + l_size) < (memR.phys_addr + memR.size))) + { + found = true; + o_vaddr = reinterpret_cast(memR.virt_addr); + o_vaddr = o_vaddr + (l_phys_addr-memR.phys_addr); + break; + } + } + + //if not found, then map it in + if(!found) + { + TRACFCOMP( g_trac_runtime, "SPIRA Data @ 0x%X not mapped, mapping", + l_phys_addr); + errhdl = mapRegion(l_phys_addr, l_size, o_vaddr); + if(errhdl) + { + break; + } + } + }while(0); + + TRACUCOMP( g_trac_runtime, "SPIRA Data Base Data ptr 0x%X", o_vaddr); + + + return errhdl; } errlHndl_t hdatService::loadHostData(void) { errlHndl_t errhdl = NULL; + uint64_t l_dummy = 0x0; do { - //Check to see if already mapped, if so just return - if (iv_payload_addr != NULL) + //if already loaded (mapping present) just exit + if(0 != iv_mem_regions.size()) { break; } @@ -356,7 +463,10 @@ errlHndl_t hdatService::loadHostData(void) payload_kind = TARGETING::PAYLOAD_KIND_PHYP; #endif - if( TARGETING::PAYLOAD_KIND_PHYP == payload_kind ) + //If PHYP or Sapphire w/FSP + if( (TARGETING::PAYLOAD_KIND_PHYP == payload_kind ) || + ((TARGETING::PAYLOAD_KIND_SAPPHIRE == payload_kind ) && + !INITSERVICE::spLess())) { // PHYP TARGETING::ATTR_PAYLOAD_BASE_type payload_base @@ -368,35 +478,12 @@ errlHndl_t hdatService::loadHostData(void) #ifdef REAL_HDAT_TEST hdat_start = 256*MEGABYTE; #endif + // make sure that our numbers are page-aligned, expected by + // rest of hdatservice code + assert(hdat_start == ALIGN_PAGE(hdat_start)); + assert (hdat_size == ALIGN_PAGE(hdat_size)); - // make sure that our numbers are page-aligned, required by mm call - hdat_start = ALIGN_PAGE_DOWN(hdat_start); //round down - hdat_size = ALIGN_PAGE(hdat_size); //round up - - TRACFCOMP( g_trac_runtime, "load_host_data> PHYP: Mapping in 0x%X-0x%X (%d MB)", hdat_start, hdat_start+hdat_size, hdat_size ); - iv_payload_addr = mm_block_map( reinterpret_cast(hdat_start), - hdat_size ); - if (NULL == iv_payload_addr) - { - TRACFCOMP( g_trac_runtime, "Failure calling mm_block_map : iv_payload_addr=%p", - iv_payload_addr ); - /*@ - * @errortype - * @moduleid RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA - * @reasoncode RUNTIME::RC_CANNOT_MAP_MEMORY - * @userdata1 Starting Address - * @userdata2 Size - * @devdesc Error mapping in memory - */ - errhdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA, - RUNTIME::RC_CANNOT_MAP_MEMORY, - hdat_start, - hdat_size ); - errhdl->collectTrace("RUNTIME",1024); - break; - } + errhdl = mapRegion(hdat_start, hdat_size, l_dummy); } else if( TARGETING::PAYLOAD_KIND_NONE == payload_kind ) { @@ -404,30 +491,14 @@ errlHndl_t hdatService::loadHostData(void) FakePayload::load(); // Map in some arbitrary memory for the HostServices code to use - TRACFCOMP( g_trac_runtime, "load_host_data> STANDALONE: Mapping in 0x%X-0x%X (%d MB)", HSVC_TEST_MEMORY_ADDR, HSVC_TEST_MEMORY_ADDR+HSVC_TEST_MEMORY_SIZE, + TRACFCOMP( g_trac_runtime, "load_host_data> STANDALONE: Mapping in 0x%X-0x%X (%d MB)", HSVC_TEST_MEMORY_ADDR, + HSVC_TEST_MEMORY_ADDR+HSVC_TEST_MEMORY_SIZE, HSVC_TEST_MEMORY_SIZE); - iv_payload_addr = mm_block_map( - reinterpret_cast(HSVC_TEST_MEMORY_ADDR), - HSVC_TEST_MEMORY_SIZE); - if (NULL == iv_payload_addr) + + errhdl = mapRegion(HSVC_TEST_MEMORY_ADDR, + HSVC_TEST_MEMORY_SIZE, l_dummy); + if(errhdl) { - TRACFCOMP( g_trac_runtime, "Failure calling mm_block_map : iv_payload_addr=%p", - iv_payload_addr ); - /*@ - * @errortype - * @moduleid RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA - * @reasoncode RUNTIME::RC_CANNOT_MAP_MEMORY2 - * @userdata1 Starting Address - * @userdata2 Size - * @devdesc Error mapping in standalone memory - */ - errhdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA, - RUNTIME::RC_CANNOT_MAP_MEMORY2, - HSVC_TEST_MEMORY_ADDR, - HSVC_TEST_MEMORY_SIZE ); - errhdl->collectTrace("RUNTIME",1024); break; } @@ -435,28 +506,11 @@ errlHndl_t hdatService::loadHostData(void) TRACFCOMP( g_trac_runtime, "load_host_data> STANDALONE: Mapping in 0x%X-0x%X (%d MB)", DUMP_TEST_MEMORY_ADDR, DUMP_TEST_MEMORY_ADDR+DUMP_TEST_MEMORY_SIZE, DUMP_TEST_MEMORY_SIZE); - iv_dumptest_addr = mm_block_map( - reinterpret_cast(DUMP_TEST_MEMORY_ADDR), - DUMP_TEST_MEMORY_SIZE ); - if (NULL == iv_dumptest_addr) + + errhdl = mapRegion(DUMP_TEST_MEMORY_ADDR, + DUMP_TEST_MEMORY_SIZE, l_dummy); + if(errhdl) { - TRACFCOMP( g_trac_runtime, "Failure calling mm_block_map : iv_dumptest_addr=%p", - iv_dumptest_addr ); - /*@ - * @errortype - * @moduleid RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA - * @reasoncode RUNTIME::RC_CANNOT_MAP_MEMORY3 - * @userdata1 Starting Address - * @userdata2 Size - * @devdesc Error mapping in standalone memory - */ - errhdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA, - RUNTIME::RC_CANNOT_MAP_MEMORY3, - DUMP_TEST_MEMORY_ADDR, - DUMP_TEST_MEMORY_SIZE ); - errhdl->collectTrace("RUNTIME",1024); break; } } @@ -514,7 +568,10 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, // we're all done break; } - else if( TARGETING::PAYLOAD_KIND_PHYP != payload_kind ) + //If payload is not (PHYP or Sapphire w/fsp) + else if( !((TARGETING::PAYLOAD_KIND_PHYP == payload_kind ) || + ((TARGETING::PAYLOAD_KIND_SAPPHIRE == payload_kind ) && + !INITSERVICE::spLess()))) { TRACFCOMP( g_trac_runtime, "getHostDataSection> There is no host data for PAYLOAD_KIND=%d", payload_kind ); /*@ @@ -535,7 +592,9 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, } // Go fetch the relative zero address that PHYP uses - uint64_t payload_base = reinterpret_cast(iv_payload_addr); + // This is always the first entry in the vector + uint64_t payload_base = + reinterpret_cast(iv_mem_regions[0].virt_addr); // Setup the SPIRA pointers errhdl = findSpira(); @@ -545,7 +604,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, // NACA if( RUNTIME::NACA == i_section ) { - o_dataAddr = reinterpret_cast(iv_payload_addr); + o_dataAddr = reinterpret_cast(payload_base); o_dataAddr += HDAT_NACA_OFFSET; o_dataSize = sizeof(hdatNaca_t); } @@ -591,6 +650,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, // Host Services System Data else if( RUNTIME::HSVC_SYSTEM_DATA == i_section ) { + // Find the right tuple and verify it makes sense hdat5Tuple_t* tuple = NULL; if( iv_spiraS ) @@ -602,19 +662,20 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, tuple = &(iv_spiraL->hdatDataArea[SPIRAL_HSVC_DATA]); } TRACUCOMP( g_trac_runtime, "HSVC_SYSTEM_DATA tuple=%p", tuple ); - errhdl = check_tuple( payload_base, - i_section, + errhdl = check_tuple( i_section, tuple ); if( errhdl ) { break; } - uint64_t base_addr = tuple->hdatAbsAddr + payload_base; + uint64_t base_addr; + errhdl = getSpiraTupleVA(tuple, base_addr); + if( errhdl ) { break; } + hdatHDIF_t* hsvc_header = reinterpret_cast(base_addr); TRACUCOMP( g_trac_runtime, "hsvc_header=%p", hsvc_header ); // Check the headers and version info - errhdl = check_header( payload_base, - hsvc_header, + errhdl = check_header( hsvc_header, HSVC_DATA_HEADER ); if( errhdl ) { break; } @@ -623,8 +684,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, (hsvc_header->hdatDataPtrOffset + base_addr); TRACUCOMP( g_trac_runtime, "sys_header=%p", sys_header ); // Make sure the Data Header is pointing somewhere valid - errhdl = verify_hdat_address( payload_base, - sys_header, + errhdl = verify_hdat_address( sys_header, sizeof(hdatHDIFDataHdr_t) ); if( errhdl ) { break; } @@ -645,19 +705,21 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, tuple = &(iv_spiraL->hdatDataArea[SPIRAL_HSVC_DATA]); } TRACUCOMP( g_trac_runtime, "HSVC_NODE_DATA tuple=%p", tuple ); - errhdl = check_tuple( payload_base, - i_section, + errhdl = check_tuple( i_section, tuple ); if( errhdl ) { break; } - uint64_t base_addr = tuple->hdatAbsAddr + payload_base; + + uint64_t base_addr; + errhdl = getSpiraTupleVA(tuple, base_addr); + if( errhdl ) { break; } + hdatHDIF_t* hsvc_header = reinterpret_cast(base_addr); TRACUCOMP( g_trac_runtime, "hsvc_header=%p", hsvc_header ); // Check the headers and version info - errhdl = check_header( payload_base, - hsvc_header, + errhdl = check_header( hsvc_header, HSVC_DATA_HEADER ); if( errhdl ) { break; } @@ -666,8 +728,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, (hsvc_header->hdatChildStrOffset + base_addr); TRACUCOMP( g_trac_runtime, "node_headers=%p", node_header ); // Make sure the Child Header is pointing somewhere valid - errhdl = verify_hdat_address( payload_base, - node_header, + errhdl = verify_hdat_address( node_header, sizeof(hdatHDIFChildHdr_t) ); if( errhdl ) { break; } @@ -675,8 +736,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, reinterpret_cast (node_header->hdatOffset + base_addr); // Make sure the headers are all in a valid range - errhdl = verify_hdat_address( payload_base, - node_data_headers, + errhdl = verify_hdat_address( node_data_headers, sizeof(hdatHDIF_t)*(node_header->hdatCnt) ); if( errhdl ) { break; } @@ -689,8 +749,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, { TRACUCOMP( g_trac_runtime, "index=%d", index ); // Check the headers and version info - errhdl = check_header( payload_base, - &(node_data_headers[index]), + errhdl = check_header( &(node_data_headers[index]), HSVC_NODE_DATA_HEADER ); if( errhdl ) { break; } @@ -711,8 +770,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, (node_data_headers[index].hdatDataPtrOffset + node_base_addr); TRACUCOMP( g_trac_runtime, "local_node_header=%p", local_node_header ); // Make sure the header is pointing somewhere valid - errhdl = verify_hdat_address( payload_base, - local_node_header, + errhdl = verify_hdat_address( local_node_header, sizeof(hdatHDIFDataHdr_t) ); if( errhdl ) { break; } @@ -763,19 +821,20 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, tuple = &(iv_spiraL->hdatDataArea[SPIRAL_IPL_PARMS]); } TRACUCOMP( g_trac_runtime, "IPLPARMS_SYSTEM tuple=%p", tuple ); - errhdl = check_tuple( payload_base, - i_section, + errhdl = check_tuple( i_section, tuple ); if( errhdl ) { break; } - uint64_t base_addr = tuple->hdatAbsAddr + payload_base; - hdatHDIF_t* ipl_parms = reinterpret_cast + uint64_t base_addr; + errhdl = getSpiraTupleVA(tuple, base_addr); + if( errhdl ) { break; } + + hdatHDIF_t* ipl_parms = reinterpret_cast (base_addr); TRACUCOMP( g_trac_runtime, "ipl_parms=%p", ipl_parms ); // Check the headers and version info - errhdl = check_header( payload_base, - ipl_parms, + errhdl = check_header( ipl_parms, IPLPARMS_SYSTEM_HEADER ); if( errhdl ) { break; } @@ -784,8 +843,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, (ipl_parms->hdatDataPtrOffset + base_addr); TRACUCOMP( g_trac_runtime, "internal_data_ptrs=%p", internal_data_ptrs ); // Make sure the Header is pointing somewhere valid - errhdl = verify_hdat_address( payload_base, - internal_data_ptrs, + errhdl = verify_hdat_address( internal_data_ptrs, sizeof(hdatHDIFDataHdr_t) ); if( errhdl ) { break; } @@ -811,15 +869,15 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, tuple = &(iv_spiraL->hdatDataArea[SPIRAL_MS_DUMP_SRC_TBL]); } TRACUCOMP( g_trac_runtime, "MS_DUMP_SRC_TBL tuple=%p", tuple ); - errhdl = check_tuple( payload_base, - i_section, + errhdl = check_tuple( i_section, tuple ); if( errhdl ) { break; } //Note - there is no header for the MDST - o_dataAddr = tuple->hdatAbsAddr + payload_base; o_dataSize = tuple->hdatActualCnt * tuple->hdatActualSize; - } + errhdl = getSpiraTupleVA(tuple, o_dataAddr); + if( errhdl ) { break; } + } // MS DUMP Destination Table - MDDT else if( RUNTIME::MS_DUMP_DST_TBL == i_section ) { @@ -838,14 +896,14 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, tuple = &(iv_spiraL->hdatDataArea[SPIRAL_MS_DUMP_DST_TBL]); } TRACUCOMP( g_trac_runtime, "MS_DUMP_DST_TBL tuple=%p", tuple ); - errhdl = check_tuple( payload_base, - i_section, + errhdl = check_tuple( i_section, tuple ); if( errhdl ) { break; } //Note - there is no header for the MDDT - o_dataAddr = tuple->hdatAbsAddr + payload_base; o_dataSize = tuple->hdatActualCnt * tuple->hdatActualSize; + errhdl = getSpiraTupleVA(tuple, o_dataAddr); + if( errhdl ) { break; } } // MS DUMP Results Table - MDRT else if( RUNTIME::MS_DUMP_RESULTS_TBL == i_section ) @@ -865,15 +923,16 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, tuple = &(iv_spiraL->hdatDataArea[SPIRAL_MS_DUMP_RSLT_TBL]); } TRACUCOMP( g_trac_runtime, "MS_DUMP_RESULTS_TBL tuple=%p", tuple ); - errhdl = check_tuple( payload_base, - i_section, + errhdl = check_tuple( i_section, tuple ); if( errhdl ) { break; } //Note - there is no header for the MDRT - o_dataAddr = tuple->hdatAbsAddr + payload_base; //return the total allocated size since it is empty at first o_dataSize = tuple->hdatAllocSize * tuple->hdatAllocSize; + errhdl = getSpiraTupleVA(tuple, o_dataAddr); + if( errhdl ) { break; } + } // Not sure how we could get here... else @@ -898,8 +957,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, } // Make sure the range we return is pointing somewhere valid - errhdl = verify_hdat_address( payload_base, - o_dataAddr, + errhdl = verify_hdat_address( reinterpret_cast(o_dataAddr), o_dataSize ); if( errhdl ) { break; } @@ -927,7 +985,9 @@ errlHndl_t hdatService::findSpira( void ) } // Go fetch the relative zero address that PHYP uses - uint64_t payload_base = reinterpret_cast(iv_payload_addr); + // This is always the first entry in the vector + uint64_t payload_base = + reinterpret_cast(iv_mem_regions[0].virt_addr); // Everything starts at the NACA // The NACA is part of the platform dependent LID which @@ -978,8 +1038,7 @@ errlHndl_t hdatService::findSpira( void ) TRACFCOMP( g_trac_runtime, "SPIRA-H=%p", iv_spiraH ); // Check the headers and version info - errhdl = check_header( payload_base, - &(iv_spiraH->hdatHDIF), + errhdl = check_header( &(iv_spiraH->hdatHDIF), SPIRAH_HEADER ); if( errhdl ) { @@ -995,8 +1054,7 @@ errlHndl_t hdatService::findSpira( void ) tuple_addr += payload_base; hdat5Tuple_t* tuple = reinterpret_cast(tuple_addr); TRACUCOMP( g_trac_runtime, "SPIRA-S tuple=%p", tuple ); - errlHndl_t errhdl_s = check_tuple( payload_base, - SPIRA_S, + errlHndl_t errhdl_s = check_tuple( SPIRA_S, tuple ); if( errhdl_s ) { @@ -1011,8 +1069,7 @@ errlHndl_t hdatService::findSpira( void ) TRACFCOMP( g_trac_runtime, "SPIRA-S=%p", iv_spiraS ); // Check the headers and version info - errhdl_s = check_header( payload_base, - &(iv_spiraH->hdatHDIF), + errhdl_s = check_header( &(iv_spiraH->hdatHDIF), SPIRAS_HEADER ); if( errhdl_s ) { @@ -1031,8 +1088,7 @@ errlHndl_t hdatService::findSpira( void ) TRACFCOMP( g_trac_runtime, "Legacy SPIRA=%p", iv_spiraL ); // Make sure the SPIRA is valid - errhdl_l = verify_hdat_address( payload_base, - iv_spiraL, + errhdl_l = verify_hdat_address( iv_spiraL, sizeof(hdatSpira_t) ); if( errhdl_l ) { diff --git a/src/usr/runtime/hdatservice.H b/src/usr/runtime/hdatservice.H index 049bd881e..542c7be32 100644 --- a/src/usr/runtime/hdatservice.H +++ b/src/usr/runtime/hdatservice.H @@ -27,10 +27,9 @@ #include #include #include -#include #include #include -#include +#include namespace RUNTIME { @@ -44,6 +43,21 @@ namespace RUNTIME */ class hdatService { + struct hdatMemRegion_t + { + uint64_t phys_addr; + void * virt_addr; + size_t size; + + /** + * Default Contructor + */ + hdatMemRegion_t() : + phys_addr(0), virt_addr(NULL), size(0) {} + }; + + typedef std::vector::iterator memRegionItr; + public: /** @@ -94,6 +108,62 @@ namespace RUNTIME */ ~hdatService(); + /** + * @brief Map a region of memory + * + * Utility to map a region of memory so it can be accessed. + * Map information is stored as a class variable + * + * @param[in] i_addr Physical address to map + * @param[in] i_bytes Number of bytes to map + * @param[out] o_vaddr Virtual address mapped to + * + * @return errlHndl_t NULL on success + */ + errlHndl_t mapRegion( uint64_t i_addr, size_t i_bytes, + uint64_t &o_vaddr); + + /** + * @brief Retrieve (and map if necessary) a SPIRA data area + * + * PHYP SPIRA is within the base mapping, Sapphire is not + * + * @param[in] i_tuple Valid tuple pointer to area to be mapped + * @param[out] o_vaddr Virtual address to access data area + * + * @return errlHndl_t NULL on success + */ + errlHndl_t getSpiraTupleVA(hdat5Tuple_t* i_tuple, + uint64_t & o_vaddr); + + /** + * @brief Verify that a block of memory falls inside a safe range + * @param i_addr Address to check + * @param i_size Number of bytes to check + * @return Error if address seems wrong + */ + errlHndl_t verify_hdat_address( void* i_addr, + size_t i_size ); + + /** + * @brief Verify the header portion of an HDAT section + * @param i_header Actual header data + * @param i_exp Expected header data + * @return Error on mismatch + */ + errlHndl_t check_header( hdatHDIF_t* i_header, + const hdatHeaderExp_t& i_exp ); + + /** + * @brief Verify basic characteristics of a HDAT Tuple structure + * @param i_section Section name being verified + * @param i_tuple Tuple to check + * @return Error if Tuple is unallocated + */ + errlHndl_t check_tuple( const RUNTIME::SectionId i_section, + hdat5Tuple_t* i_tuple ); + + /** * @brief Retrieve hardcoded section addresses for standalone mode * @@ -131,12 +201,9 @@ namespace RUNTIME ********************************************/ /** - * Virtual address to payload base addr - (HDAT area is offset from there) + * Vector of virtual address mapped in */ - void * iv_payload_addr; - void * iv_dumptest_addr; - void* iv_hdat_addr; + std::vector iv_mem_regions; /** * Legacy SPIRA diff --git a/src/usr/runtime/test/hdatservicetest.H b/src/usr/runtime/test/hdatservicetest.H index 5d860f69a..4ddc089ea 100644 --- a/src/usr/runtime/test/hdatservicetest.H +++ b/src/usr/runtime/test/hdatservicetest.H @@ -32,8 +32,8 @@ #include //for MAGIC #include -#include #include +#include #include #include "../hdatstructs.H" #include "../errlud_hdat.H" diff --git a/src/usr/targeting/common/util.C b/src/usr/targeting/common/util.C index 5f2bcd919..c622e4b5d 100644 --- a/src/usr/targeting/common/util.C +++ b/src/usr/targeting/common/util.C @@ -156,6 +156,24 @@ bool is_phyp_load( ATTR_PAYLOAD_KIND_type* o_type ) } return( PAYLOAD_KIND_PHYP == payload_kind ); + } + +/** + * @brief Utility function to determine if Sapphire is the payload + * + * @description If the payload kind is Sapphire returns true. Does + * not matter if it is Sapphire with FSP or standalone + * + * @return bool True when loadding sapphire + */ +bool is_sapphire_load(void) +{ + TARGETING::Target * sys = NULL; + TARGETING::targetService().getTopLevelTarget( sys ); + assert(sys != NULL); + + return (TARGETING::PAYLOAD_KIND_SAPPHIRE == + sys->getAttr()); } -- cgit v1.2.1