summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorDean Sanner <dsanner@us.ibm.com>2013-07-10 09:28:50 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-08-21 15:37:33 -0500
commita6f46d0a9461b96781bc85c9fd82c24d14b5ce42 (patch)
treedfa696458e593a61d2c73b6de54a0e05d9a7a5cb /src/usr
parent486fc31f3be1c268b1bf6012c9d0910dc2012c5a (diff)
downloadtalos-hostboot-a6f46d0a9461b96781bc85c9fd82c24d14b5ce42.tar.gz
talos-hostboot-a6f46d0a9461b96781bc85c9fd82c24d14b5ce42.zip
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 <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/dump/dumpCollect.C1
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C59
-rw-r--r--src/usr/hwpf/hwp/core_activate/core_activate.C86
-rw-r--r--src/usr/hwpf/hwp/start_payload/makefile29
-rw-r--r--src/usr/hwpf/hwp/start_payload/start_payload.C100
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C20
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.H6
-rw-r--r--src/usr/runtime/hdatservice.C440
-rw-r--r--src/usr/runtime/hdatservice.H81
-rw-r--r--src/usr/runtime/test/hdatservicetest.H2
-rw-r--r--src/usr/targeting/common/util.C18
11 files changed, 515 insertions, 327 deletions
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 <trace/interface.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
+#include <targeting/common/commontargeting.H>
#include <runtime/runtime.H>
#include <util/align.H>
#include <sys/mm.h>
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 <runtime/runtime.H>
namespace BUILD_WINKLE_IMAGES
@@ -311,6 +312,44 @@ errlHndl_t applyPoreGenCpuRegs( TARGETING::Target *i_cpuTarget,
}
//
+// 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<TARGETING::ATTR_PROC_MEM_BASES>(l_mem_bases);
+ l_pProc->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>(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
//
void* call_host_build_winkle( void *io_pArgs )
@@ -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
- <void * const>(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<void * const>(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 <targeting/common/utilFilter.H>
#include <targeting/namedtarget.H>
#include <targeting/attrsync.H>
+#include <runtime/runtime.H>
// fapi support
#include <fapi.H>
@@ -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<TARGETING::Target*>(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<ATTR_PAYLOAD_BASE>(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/<HWP_dir>
+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 <initservice/istepdispatcherif.H>
#include <usr/cxxtest/TestSuite.H>
#include <hwpf/istepreasoncodes.H>
+#include <errl/errludtarget.H>
#include <sys/time.h>
#include <sys/mmio.h>
#include <mbox/mbox_queues.H>
@@ -62,6 +63,8 @@
// fapi support
#include <fapi.H>
#include <fapiPlatHwpInvoker.H>
+#include "p8_set_pore_bar.H"
+
#include "start_payload.H"
#include <runtime/runtime.H>
@@ -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<TARGETING::Target*>(
+ 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<TARGETING::ATTR_PAYLOAD_KIND>();
+ //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<TARGETING::ATTR_PAYLOAD_KIND>();
- 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
@@ -984,26 +984,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<TARGETING::ATTR_SP_FUNCTIONS>(spfuncs) &&
- spfuncs.mailboxEnabled )
- {
- spless = false;
- }
-
- return spless;
-}
-
-
-// ----------------------------------------------------------------------------
// IStepDispatcher::checkMpiplMode()
// ----------------------------------------------------------------------------
bool IStepDispatcher::checkMpiplMode( ) const
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 <trace/interface.H>
#include <errl/errlentry.H>
#include <runtime/runtime_reasoncodes.H>
-#include <runtime/runtime.H>
#include <sys/mm.h>
#include <targeting/common/commontargeting.H>
+#include <initservice/initserviceif.H>
+#include <runtime/runtime.H>
#include <attributeenums.H>
#include <vmmconst.h>
#include <util/align.H>
@@ -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<uint64_t>(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<uint64_t>(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<uint64_t>(i_addr),
+ reinterpret_cast<uint64_t>(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<uint64_t>(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<uint64_t>(iv_payload_addr);
- uint64_t v_dumpAddr = reinterpret_cast<uint64_t>(iv_dumptest_addr);
if( RUNTIME::HSVC_SYSTEM_DATA == i_section )
{
- o_dataAddr = v_baseAddr;
+ o_dataAddr = reinterpret_cast<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<void*>(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<uint64_t>(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<uint64_t>(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<void*>(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<void*>(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<void*>(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<uint64_t>(iv_payload_addr);
+ // This is always the first entry in the vector
+ uint64_t payload_base =
+ reinterpret_cast<uint64_t>(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<uint64_t>(iv_payload_addr);
+ o_dataAddr = reinterpret_cast<uint64_t>(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<hdatHDIF_t*>(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<hdatHDIF_t*>(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<hdatHDIF_t*>
(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<hdatHDIF_t*>
+ uint64_t base_addr;
+ errhdl = getSpiraTupleVA(tuple, base_addr);
+ if( errhdl ) { break; }
+
+ hdatHDIF_t* ipl_parms = reinterpret_cast<hdatHDIF_t*>
(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<void*>(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<uint64_t>(iv_payload_addr);
+ // This is always the first entry in the vector
+ uint64_t payload_base =
+ reinterpret_cast<uint64_t>(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<hdat5Tuple_t*>(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 <util/locked/list.H>
#include <list>
#include <errl/errlentry.H>
-#include <usr/devicefw/driverif.H>
#include <attributestructs.H>
#include <sys/task.h>
-#include <usr/fsi/fsiif.H>
+#include <vector>
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<hdatMemRegion_t>::iterator memRegionItr;
+
public:
/**
@@ -95,6 +109,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
*
* This is here to allow us to manually generate attribute data for
@@ -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<hdatMemRegion_t> 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 <arch/ppc.H> //for MAGIC
#include <errl/errlmanager.H>
-#include <runtime/runtime.H>
#include <targeting/common/commontargeting.H>
+#include <runtime/runtime.H>
#include <attributeenums.H>
#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<TARGETING::ATTR_PAYLOAD_KIND>());
}
OpenPOWER on IntegriCloud