summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/errno.h46
-rw-r--r--src/include/usr/runtime/runtime.H37
-rw-r--r--src/include/usr/runtime/runtime_reasoncodes.H23
-rw-r--r--src/include/usr/vmmconst.h15
-rw-r--r--src/kernel/basesegment.C6
-rw-r--r--src/usr/runtime/hdatservice.C787
-rw-r--r--src/usr/runtime/hdatstructs.H244
-rw-r--r--src/usr/runtime/makefile2
-rw-r--r--src/usr/runtime/populate_attributes.C90
-rw-r--r--src/usr/runtime/test/hdatservicetest.H308
-rw-r--r--src/usr/runtime/test/runtimeattrstest.H31
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml39
-rw-r--r--src/usr/targeting/common/xmltohb/simics_MURANO.system.xml4
-rw-r--r--src/usr/targeting/common/xmltohb/simics_VENICE.system.xml4
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml1
-rw-r--r--src/usr/targeting/common/xmltohb/vbu.system.xml4
-rwxr-xr-xsrc/usr/targeting/xmltohb/genHwsvMrwXml.pl33
17 files changed, 1618 insertions, 56 deletions
diff --git a/src/include/errno.h b/src/include/errno.h
index 020366357..5e7833985 100644
--- a/src/include/errno.h
+++ b/src/include/errno.h
@@ -1,26 +1,25 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/include/errno.h $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2011-2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/errno.h $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2011,2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
#ifndef _ERRNO_H
#define _ERRNO_H
@@ -34,6 +33,7 @@
#define EINVAL 22 // Invalid argument
#define ENFILE 23 // Too many open files in system
#define EDEADLK 35 // Operation would cause deadlock.
+#define EALREADY 114 // Operation already in progress
#define EWOULDBLOCK EAGAIN // operation would block
diff --git a/src/include/usr/runtime/runtime.H b/src/include/usr/runtime/runtime.H
index f638d9762..0681ad3a8 100644
--- a/src/include/usr/runtime/runtime.H
+++ b/src/include/usr/runtime/runtime.H
@@ -38,6 +38,43 @@ namespace RUNTIME
*/
errlHndl_t populate_attributes( void );
+/**
+ * @brief Add the host data mainstore location to VMM
+ */
+errlHndl_t load_host_data( void );
+
+/**
+ * HDAT Sections
+ */
+enum SectionId
+{
+ HSVC_NODE_DATA, //< HostServices Node Attributes
+ HSVC_SYSTEM_DATA, //< HostServices System Attributes
+ IPLPARMS_SYSTEM, //< IPL Parms
+ MS_DUMP_SRC_TBL, //< MDST: Memory Dump Source Table
+ MS_DUMP_DST_TBL, //< MDDT: Memory Dump Destination Table
+ MS_DUMP_RESULTS_TBL, //< MDRT: Memory Dump Results Table
+};
+
+/**
+ * @brief Get a pointer to the beginning of a particular section of
+ * the host data memory.
+ *
+ * @description The returned pointer will not include any header hdat header
+ * information.
+ *
+ * @param[in] i_section Chunk of data to find
+ * @param[in] i_instance Instance of section when there are multiple entries
+ * @param[out] o_dataAddr Physical memory address of data
+ * @param[out] o_dataSize Size of data in bytes, 0 on error, DATA_SIZE_UNKNOWN if unknown
+ *
+ * @return errlHndl_t NULL on success
+ */
+errlHndl_t get_host_data_section( SectionId i_section,
+ uint64_t i_instance,
+ uint64_t& o_dataAddr,
+ size_t& o_dataSize );
+const size_t DATA_SIZE_UNKNOWN = 0xFFFFFFFFFFFFFFFF;
}
diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H
index 3c81ac54b..0986d585b 100644
--- a/src/include/usr/runtime/runtime_reasoncodes.H
+++ b/src/include/usr/runtime/runtime_reasoncodes.H
@@ -29,14 +29,31 @@ namespace RUNTIME
{
enum RuntimeModuleId
{
- MOD_RUNTIME_INVALID = 0x00, /**< Zero is an invalid module id */
- MOD_RUNTIME_POP_SYS_ATTR = 0x01,
- MOD_RUNTIME_POP_NODE_ATTR = 0x02,
+ MOD_RUNTIME_INVALID = 0x00, /**< Invalid module id */
+ MOD_RUNTIME_POP_SYS_ATTR = 0x01, /**< populate_attributes.C */
+ MOD_RUNTIME_POP_NODE_ATTR = 0x02, /**< populate_attributes.C */
+ MOD_HDATSERVICE_CHECK_HEADER = 0x03, /**< hdatservice.C */
+ MOD_HDATSERVICE_CHECK_TUPLE = 0x04, /**< hdatservice.C */
+ MOD_HDATSERVICE_LOAD_HOST_DATA = 0x05, /**< hdatservice.C */
+ MOD_HDATSERVICE_GET_STANDALONE_SECTION = 0x06, /**< hdatservice.C */
+ MOD_HDATSERVICE_GET_HOST_DATA_SECTION = 0x07, /**< hdatservice.C */
+ MOD_HDATSERVICE_VERIFY_HDAT_ADDRESS = 0x08, /**< hdatservice.C */
};
enum RuntimeReasonCode
{
RC_ATTR_GET_FAIL = RUNTIME_COMP_ID | 0x01,
+ RC_BAD_HDAT_HEADER = RUNTIME_COMP_ID | 0x02,
+ RC_BAD_HDAT_TUPLE = RUNTIME_COMP_ID | 0x03,
+ RC_INVALID_STANDALONE = RUNTIME_COMP_ID | 0x04,
+ RC_CANNOT_MAP_MEMORY = RUNTIME_COMP_ID | 0x05,
+ RC_WRONG_PAYLOAD_ATTRS = RUNTIME_COMP_ID | 0x06,
+ RC_CANNOT_MAP_MEMORY2 = RUNTIME_COMP_ID | 0x07,
+ RC_INVALID_PAYLOAD_KIND = RUNTIME_COMP_ID | 0x08,
+ RC_NO_HSVC_NODE_DATA_FOUND = RUNTIME_COMP_ID | 0x09,
+ RC_BAD_NACA = RUNTIME_COMP_ID | 0x0A,
+ RC_INVALID_ADDRESS = RUNTIME_COMP_ID | 0x0B,
+ RC_INVALID_SECTION = RUNTIME_COMP_ID | 0x0C,
};
};
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index 7a5250cce..d858ebbdb 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -58,13 +58,17 @@
#define VMM_ADDR_BASE_BLOCK 0
/** Base Segment Base Block size */
-#define VMM_BASE_BLOCK_SIZE 8*MEGABYTE
+#define VMM_BASE_BLOCK_SIZE (8*MEGABYTE)
/** Base Segment Extended Memory Block Base Address */
-#define VMM_ADDR_EXTEND_BLOCK VMM_ADDR_BASE_BLOCK + VMM_BASE_BLOCK_SIZE
+#define VMM_ADDR_EXTEND_BLOCK (VMM_ADDR_BASE_BLOCK + VMM_BASE_BLOCK_SIZE)
+
+/** Maximize size of Base Segment Memory after expansion */
+#define VMM_MEMORY_SIZE (32*MEGABYTE)
/** Base Segment Extended Memory Block Size */
-#define VMM_EXTEND_BLOCK_SIZE (32*MEGABYTE)-VMM_BASE_BLOCK_SIZE
+#define VMM_EXTEND_BLOCK_SIZE (VMM_MEMORY_SIZE-VMM_BASE_BLOCK_SIZE)
+
/**
* Resource Providers
*/
@@ -113,11 +117,16 @@ enum BlockPriority
/**
* Test Constants
*/
+
/** Base virtual address used in remove pages test */
#define VMM_VADDR_RMVPAGE_TEST (700 * GIGABYTE)
/** Block size used in remove pages test */
#define VMM_SIZE_RMVPAGE_TEST (8 * PAGESIZE)
+/** Chunk of physical memory to use for HostServices Attributes */
+#define HSVC_TEST_MEMORY_ADDR (VMM_MEMORY_SIZE + 32*MEGABYTE)
+#define HSVC_TEST_MEMORY_SIZE (2*MEGABYTE)
+
#endif /* _VMMCONST_H */
diff --git a/src/kernel/basesegment.C b/src/kernel/basesegment.C
index 79cf7ada8..0b4ad5969 100644
--- a/src/kernel/basesegment.C
+++ b/src/kernel/basesegment.C
@@ -117,12 +117,14 @@ int BaseSegment::_mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size,
uint64_t l_vaddr = reinterpret_cast<uint64_t>(i_va);
uint64_t l_blockSizeTotal = 0;
iv_block->totalBlocksAlloc(l_blockSizeTotal);
+
//Verify input address and size falls within this segment's address range
if (l_vaddr < this->getBaseAddress() ||
l_vaddr >= (this->getBaseAddress() + (1ull << SLBE_s)) ||
(l_blockSizeTotal + ALIGN_PAGE(i_size)) >= (1ull << SLBE_s) ||
(l_vaddr != ALIGN_PAGE_DOWN(l_vaddr)))
{
+ printkd("_mmAllocBlock: Address %lX is not part of BaseSegment : baseaddr=%lX, totalblocks=%ld\n", l_vaddr, this->getBaseAddress(), l_blockSizeTotal);
return -EINVAL;
}
@@ -135,8 +137,8 @@ int BaseSegment::_mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size,
// block.. if so return error
if (temp_block->isContained(l_vaddr))
{
- printk("mmAllocBlock Address = %lx is already in a block\n",l_vaddr);
- return -EINVAL;
+ printkd("_mmAllocBlock Address = %lx is already in a block\n",l_vaddr);
+ return -EALREADY;
}
temp_block = temp_block->iv_nextBlock;
diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C
new file mode 100644
index 000000000..63096e6e5
--- /dev/null
+++ b/src/usr/runtime/hdatservice.C
@@ -0,0 +1,787 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/hdatservice.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <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 <attributeenums.H>
+#include <vmmconst.h>
+#include <util/align.H>
+#include "hdatstructs.H"
+
+extern trace_desc_t* g_trac_runtime;
+
+#define TRACUCOMP TRACDCOMP
+
+
+/********************
+ Local Constants used for sanity checks
+ ********************/
+const hdatHeaderExp_t HSVC_NODE_DATA_HEADER = {
+ 0xD1F0, // id
+ "HS KID", // name
+ 0x0010 //version
+};
+
+const hdatHeaderExp_t HSVC_DATA_HEADER = {
+ 0xD1F0, //id
+ "HOSTSR", //name
+ 0x0010 //version
+};
+
+const hdatHeaderExp_t IPLPARMS_SYSTEM_HEADER = {
+ 0xD1F0, //id
+ "IPLPMS", //name
+ 0x0058 //version
+};
+
+//big enough to hold all of PHYP
+const uint64_t HDAT_MEM_SIZE = 128*MEGABYTE;
+
+/********************
+ Utility Functions
+ ********************/
+
+/**
+ * @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 errhdl = NULL;
+
+ // 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)) )
+ {
+ 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 );
+ /*@
+ * @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
+ * @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) );
+ 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 )
+{
+ 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;
+
+ do
+ {
+ // Make sure the Tuple is pointing somewhere valid
+ errhdl = verify_hdat_address( i_base,
+ i_header,
+ sizeof(hdatHDIF_t) );
+ if( errhdl ) { break; }
+
+ // Check the ID, Version and Name
+ if( (i_header->hdatStructId != i_exp.id)
+ && (i_header->hdatVersion != i_exp.version)
+ && !memcmp(i_header->hdatStructName,i_exp.name,6) )
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK "RUNTIME::check_header> HDAT Header data not as expected (id:version:name). Act=%.4X:%.4X:%s, Exp=%.4X:%.4X :%s", i_header->hdatStructId, i_header->hdatVersion, i_header->hdatStructName, i_exp.id, i_exp.version, i_exp.name );
+ hdatHeaderExp_t actual;
+ actual.id = i_header->hdatStructId;
+ actual.version = i_header->hdatVersion;
+ actual.name = i_header->hdatStructName;
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_CHECK_HEADER
+ * @reasoncode RUNTIME::RC_BAD_HDAT_HEADER
+ * @userdata1[0:15] Actual Header: id
+ * @userdata1[16:31] Actual Header: version
+ * @userdata1[32:63] Actual Header: name
+ * @userdata2[0:15] Expected Header: id
+ * @userdata2[16:31] Expected Header: version
+ * @userdata2[32:63] Expected Header: name
+ * @devdesc HDAT Header data not as expected
+ */
+ errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_CHECK_HEADER,
+ RUNTIME::RC_BAD_HDAT_HEADER,
+ actual.flatten(),
+ i_exp.flatten());
+ errhdl->collectTrace("RUNTIME",1024);
+ break;
+ }
+ } while(0);
+
+ 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 errhdl = NULL;
+
+ do
+ {
+ // Make sure the Tuple is in valid memory
+ errhdl = verify_hdat_address( i_base,
+ i_tuple,
+ sizeof(hdat5Tuple_t) );
+ if( errhdl ) { break; }
+
+ // Look for unallocated data
+ if( (i_tuple->hdatAbsAddr == 0)
+ || (i_tuple->hdatAllocCnt == 0)
+ || (i_tuple->hdatAllocSize == 0) )
+ {
+ TRACFCOMP( g_trac_runtime, "check_tuple> Tuple for section %d is unallocated", i_section );
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_CHECK_TUPLE
+ * @reasoncode RUNTIME::RC_BAD_HDAT_TUPLE
+ * @userdata1 Absolute address
+ * @userdata2[0:31] Allocated Count
+ * @userdata2[32:63] Allocated Size
+ * @devdesc Tuple is unallocated
+ */
+ errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_CHECK_TUPLE,
+ RUNTIME::RC_BAD_HDAT_TUPLE,
+ i_tuple->hdatAbsAddr,
+ TWO_UINT32_TO_UINT64(
+ i_tuple->hdatAllocCnt,
+ i_tuple->hdatAllocSize));
+ errhdl->collectTrace("RUNTIME",1024);
+ break;
+ }
+ } while(0);
+
+ return errhdl;
+}
+
+
+/**
+ * @brief Retrieve hardcoded section addresses for standalone mode
+ *
+ * This is here to allow us to manually generate attribute data for
+ * the HostServices code without requiring a full FipS/PHYP boot.
+ *
+ * @param[in] i_section Chunk of data to find
+ * @param[in] i_instance Instance of section when there are multiple entries
+ * @param[out] o_dataAddr Physical memory address of data
+ * @param[out] o_dataSize Size of data in bytes, 0 on error, DATA_SIZE_UNKNOWN if unknown
+ *
+ * @return errlHndl_t NULL on success
+ */
+errlHndl_t get_standalone_section( RUNTIME::SectionId i_section,
+ uint64_t i_instance,
+ uint64_t& o_dataAddr,
+ size_t& o_dataSize )
+{
+ errlHndl_t errhdl = NULL;
+
+ if( RUNTIME::HSVC_SYSTEM_DATA == i_section )
+ {
+ o_dataAddr = HSVC_TEST_MEMORY_ADDR;
+ o_dataSize = 512*KILOBYTE;
+ }
+ else if( RUNTIME::HSVC_NODE_DATA == i_section )
+ {
+ o_dataAddr = HSVC_TEST_MEMORY_ADDR + 512*KILOBYTE;
+ o_dataSize = HSVC_TEST_MEMORY_SIZE - 512*KILOBYTE;
+ }
+ else
+ {
+ TRACFCOMP( g_trac_runtime, "get_standalone_section> Section %d not valid in standalone mode", i_section );
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_GET_STANDALONE_SECTION
+ * @reasoncode RUNTIME::RC_INVALID_STANDALONE
+ * @userdata1 Section ID
+ * @userdata2 Section Instance Number
+ * @devdesc Section is not valid in standalone mode
+ */
+ errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_GET_STANDALONE_SECTION,
+ RUNTIME::RC_INVALID_STANDALONE,
+ i_section,
+ i_instance);
+ errhdl->collectTrace("RUNTIME",1024);
+ }
+
+ return errhdl;
+}
+
+
+/********************
+ Public Methods
+ ********************/
+
+/**
+ * @brief Add the host data mainstore location to VMM
+ */
+errlHndl_t RUNTIME::load_host_data( void )
+{
+ errlHndl_t errhdl = NULL;
+
+ do
+ {
+ 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( TARGETING::PAYLOAD_KIND_PHYP == payload_kind )
+ {
+ // PHYP
+ TARGETING::ATTR_PAYLOAD_BASE_type payload_base
+ = sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>();
+
+ uint64_t hdat_start = payload_base*MEGABYTE;
+ uint64_t hdat_size = HDAT_MEM_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 );
+ int rc = mm_linear_map( reinterpret_cast<void*>(hdat_start),
+ hdat_size );
+ if (rc != 0)
+ {
+ TRACFCOMP( g_trac_runtime, "Failure calling mm_linear_map : rc=%d", rc );
+ /*@
+ * @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;
+ }
+ }
+ else if( TARGETING::PAYLOAD_KIND_NONE == payload_kind )
+ {
+ // Standalone Test Image with no payload
+
+ // Ensure that there really is no payload being loaded
+ TARGETING::ATTR_PAYLOAD_BASE_type payload_base
+ = sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>();
+ if( payload_base != 0 )
+ {
+ TRACFCOMP( g_trac_runtime, "load_host_data> Non-zero PAYLOAD_BASE (0x%X) for PAYLOAD_KIND==NONE", payload_base );
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA
+ * @reasoncode RUNTIME::RC_WRONG_PAYLOAD_ATTRS
+ * @userdata1 PAYLOAD_BASE
+ * @userdata2 PAYLOAD_KIND
+ * @devdesc Nonzero PAYLOAD_BASE for standalone
+ * PAYLOAD_KIND
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA,
+ RUNTIME::RC_WRONG_PAYLOAD_ATTRS,
+ payload_base,
+ payload_kind );
+ errhdl->collectTrace("RUNTIME",1024);
+ break;
+ }
+
+ // 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, HSVC_TEST_MEMORY_SIZE );
+ int rc = mm_linear_map(
+ reinterpret_cast<void*>(HSVC_TEST_MEMORY_ADDR),
+ HSVC_TEST_MEMORY_SIZE );
+ if (rc != 0)
+ {
+ TRACFCOMP( g_trac_runtime, "Failure calling mm_linear_map : rc=%d", rc );
+ /*@
+ * @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;
+ }
+ }
+ else
+ {
+ TRACFCOMP( g_trac_runtime, "load_host_data> No host data to load for payload %d", payload_kind );
+ break;
+ }
+
+
+ } while(0);
+
+ return errhdl;
+}
+
+/**
+ * @brief Get a pointer to the beginning of a particular section of
+ * the host data memory.
+ */
+errlHndl_t RUNTIME::get_host_data_section( SectionId i_section,
+ uint64_t i_instance,
+ uint64_t& o_dataAddr,
+ size_t& o_dataSize )
+{
+ errlHndl_t errhdl = NULL;
+ TRACFCOMP( g_trac_runtime, "RUNTIME::get_host_data_section( i_section=%d, i_instance=%d )", i_section, i_instance );
+
+ do
+ {
+ // Force the answer to zero in case of failure
+ o_dataAddr = 0;
+
+ TARGETING::Target * sys = NULL;
+ TARGETING::targetService().getTopLevelTarget( sys );
+ assert(sys != NULL);
+
+ // Figure out what kind of payload we have
+ TARGETING::ATTR_PAYLOAD_KIND_type payload_kind
+ = sys->getAttr<TARGETING::ATTR_PAYLOAD_KIND>();
+
+ if( TARGETING::PAYLOAD_KIND_NONE == payload_kind )
+ {
+ errhdl = get_standalone_section( i_section,
+ i_instance,
+ o_dataAddr,
+ o_dataSize );
+ // we're all done
+ break;
+ }
+ else if( TARGETING::PAYLOAD_KIND_PHYP != payload_kind )
+ {
+ TRACFCOMP( g_trac_runtime, "get_host_data_section> There is no host data for PAYLOAD_KIND=%d", payload_kind );
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION
+ * @reasoncode RUNTIME::RC_INVALID_PAYLOAD_KIND
+ * @userdata1 ATTR_PAYLOAD_KIND
+ * @userdata2 Requested Section
+ * @devdesc There is no host data for specified kind of payload
+ */
+ errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION,
+ RUNTIME::RC_INVALID_PAYLOAD_KIND,
+ payload_kind,
+ i_section);
+ errhdl->collectTrace("RUNTIME",1024);
+ break;
+ }
+
+ // Go fetch the relative zero address that PHYP uses
+ TARGETING::ATTR_PAYLOAD_BASE_type payload_base
+ = sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>();
+ payload_base = payload_base*MEGABYTE;
+
+ // Everything starts at the NACA
+ // The NACA is part of the platform dependent LID which
+ // is loaded at relative memory address 0x0
+ hdatNaca_t* naca = reinterpret_cast<hdatNaca_t*>
+ (HDAT_NACA_OFFSET + payload_base);
+ TRACFCOMP( g_trac_runtime, "NACA=%p", naca );
+
+ // Do some sanity checks on the NACA
+ if( naca->nacaPhypPciaSupport != 1 )
+ {
+ TRACFCOMP( g_trac_runtime, "get_host_data_section> nacaPhypPciaSupport=%.8X", naca->nacaPhypPciaSupport );
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION
+ * @reasoncode RUNTIME::RC_BAD_NACA
+ * @userdata1 Mainstore address of NACA
+ * @userdata2[0:31] Payload Base Address
+ * @userdata2[32:63] Payload Kind
+ * @devdesc NACA data doesn't seem right
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION,
+ RUNTIME::RC_BAD_NACA,
+ reinterpret_cast<uint64_t>(naca),
+ TWO_UINT32_TO_UINT64(payload_base,
+ payload_kind));
+ errhdl->collectTrace("RUNTIME",1024);
+ //@todo-log NACA data
+ break;
+ }
+
+
+ // The SPIRA pointer is also relative to PHYP's zero
+ hdatSpira_t* spira = reinterpret_cast<hdatSpira_t*>
+ (naca->spira + payload_base);
+ TRACFCOMP( g_trac_runtime, "SPIRA=%p", spira );
+ // Make sure the SPIRA is valid
+ errhdl = verify_hdat_address( payload_base,
+ spira,
+ sizeof(hdatSpira_t) );
+ if( errhdl )
+ {
+ TRACFCOMP( g_trac_runtime, "Spira is at a wacky offset!!! %.16X", naca->spira );
+ //@todo-log NACA data RTC:53139
+ break;
+ }
+
+ // Host Services System Data
+ if( RUNTIME::HSVC_SYSTEM_DATA == i_section )
+ {
+ // Find the right tuple and verify it makes sense
+ hdat5Tuple_t* tuple = &(spira->hdatDataArea[HSVC_DATA]);
+ TRACUCOMP( g_trac_runtime, "HSVC_SYSTEM_DATA tuple=%p", tuple );
+ errhdl = check_tuple( payload_base,
+ i_section,
+ tuple );
+ if( errhdl ) { break; }
+
+ uint64_t base_addr = tuple->hdatAbsAddr + payload_base;
+ 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,
+ HSVC_DATA_HEADER );
+ if( errhdl ) { break; }
+
+ hdatHDIFDataHdr_t* sys_header =
+ reinterpret_cast<hdatHDIFDataHdr_t*>
+ (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,
+ sizeof(hdatHDIFDataHdr_t) );
+ if( errhdl ) { break; }
+
+ o_dataAddr = sys_header->hdatOffset + base_addr;
+ o_dataSize = sys_header->hdatSize;
+ }
+ // Host Services Node Data
+ else if( RUNTIME::HSVC_NODE_DATA == i_section )
+ {
+ // Find the right tuple and verify it makes sense
+ hdat5Tuple_t* tuple = &(spira->hdatDataArea[HSVC_DATA]);
+ TRACUCOMP( g_trac_runtime, "HSVC_NODE_DATA tuple=%p", tuple );
+ errhdl = check_tuple( payload_base,
+ i_section,
+ tuple );
+ if( errhdl ) { break; }
+
+ uint64_t base_addr = tuple->hdatAbsAddr + payload_base;
+ 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,
+ HSVC_DATA_HEADER );
+ if( errhdl ) { break; }
+
+ hdatHDIFChildHdr_t* node_header =
+ reinterpret_cast<hdatHDIFChildHdr_t*>
+ (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,
+ sizeof(hdatHDIFChildHdr_t) );
+ if( errhdl ) { break; }
+
+ hdatHDIF_t* node_data_headers =
+ 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,
+ sizeof(hdatHDIF_t)*(node_header->hdatCnt) );
+ if( errhdl ) { break; }
+
+ // Loop around all instances because the data could be sparsely populated
+ TRACUCOMP( g_trac_runtime, "nodecount=%d", node_header->hdatCnt );
+ bool foundit = false;
+ uint32_t found_instances = 0;
+ for( uint8_t index = 0; index < node_header->hdatCnt; index++ )
+ {
+ TRACUCOMP( g_trac_runtime, "index=%d", index );
+ // Check the headers and version info
+ errhdl = check_header( payload_base,
+ &(node_data_headers[index]),
+ HSVC_NODE_DATA_HEADER );
+ if( errhdl ) { break; }
+
+ uint64_t node_base_addr =
+ reinterpret_cast<uint64_t>(&(node_data_headers[index]));
+
+ TRACUCOMP( g_trac_runtime, "%d> hdatInstance=%d", index, node_data_headers[index].hdatInstance );
+ if( node_data_headers[index].hdatInstance != i_instance )
+ {
+ found_instances |=
+ (0x80000000 >> node_data_headers[index].hdatInstance);
+ continue;
+ }
+ foundit = true;
+
+ hdatHDIFDataHdr_t* local_node_header =
+ reinterpret_cast<hdatHDIFDataHdr_t*>
+ (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,
+ sizeof(hdatHDIFDataHdr_t) );
+ if( errhdl ) { break; }
+
+ o_dataAddr = local_node_header->hdatOffset + node_base_addr;
+ o_dataSize = local_node_header->hdatSize;
+
+ break; // found it, stop the loop
+ }
+ if( errhdl ) { break; }
+
+ // Make sure we found something
+ if( !foundit )
+ {
+ TRACFCOMP( g_trac_runtime, "get_host_data_section> HSVC_NODE_DATA instance %d of section %d is unallocated", i_instance, i_section );
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION
+ * @reasoncode RUNTIME::RC_NO_HSVC_NODE_DATA_FOUND
+ * @userdata1 Mainstore address of node_data_headers
+ * @userdata2[0:31] Requested Instance
+ * @userdata2[32:63] Bitmask of discovered instances
+ * @devdesc Requested instance of HSVC_NODE_DATA is
+ * unallocated
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION,
+ RUNTIME::RC_NO_HSVC_NODE_DATA_FOUND,
+ reinterpret_cast<uint64_t>(node_data_headers),
+ TWO_UINT32_TO_UINT64(i_instance,
+ found_instances));
+ errhdl->collectTrace("RUNTIME",1024);
+ break;
+ }
+
+ }
+ // IPL Parameters : System Parameters
+ else if( RUNTIME::IPLPARMS_SYSTEM == i_section )
+ {
+ // Find the right tuple and verify it makes sense
+ hdat5Tuple_t* tuple = &(spira->hdatDataArea[HDAT_IPL_PARMS]);
+ TRACUCOMP( g_trac_runtime, "IPLPARMS_SYSTEM tuple=%p", tuple );
+ errhdl = check_tuple( payload_base,
+ i_section,
+ tuple );
+ if( errhdl ) { break; }
+
+ uint64_t base_addr = tuple->hdatAbsAddr + payload_base;
+ 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,
+ IPLPARMS_SYSTEM_HEADER );
+ if( errhdl ) { break; }
+
+ hdatHDIFDataHdr_t* internal_data_ptrs =
+ reinterpret_cast<hdatHDIFDataHdr_t*>
+ (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,
+ sizeof(hdatHDIFDataHdr_t) );
+ if( errhdl ) { break; }
+
+ //System Parms are index 0
+ o_dataAddr = internal_data_ptrs[0].hdatOffset + base_addr;
+ o_dataSize = internal_data_ptrs[0].hdatSize;
+ }
+ // MS DUMP Source Table - MDST
+ else if( RUNTIME::MS_DUMP_SRC_TBL == i_section )
+ {
+ //For security we can't trust the FSP's payload attribute
+ // on MPIPLs for the dump tables.
+ //@todo: RTC:59171
+
+ // Find the right tuple and verify it makes sense
+ hdat5Tuple_t* tuple = &(spira->hdatDataArea[HDAT_MS_DUMP_SRC_TBL]);
+ TRACUCOMP( g_trac_runtime, "MS_DUMP_SRC_TBL tuple=%p", tuple );
+ errhdl = check_tuple( payload_base,
+ 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;
+ }
+ // MS DUMP Destination Table - MDDT
+ else if( RUNTIME::MS_DUMP_DST_TBL == i_section )
+ {
+ //For security we can't trust the FSP's payload attribute
+ // on MPIPLs for the dump tables.
+ //@todo: RTC:59171
+
+ // Find the right tuple and verify it makes sense
+ hdat5Tuple_t* tuple = &(spira->hdatDataArea[HDAT_MS_DUMP_DST_TBL]);
+ TRACUCOMP( g_trac_runtime, "MS_DUMP_DST_TBL tuple=%p", tuple );
+ errhdl = check_tuple( payload_base,
+ 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;
+ }
+ // MS DUMP Results Table - MDRT
+ else if( RUNTIME::MS_DUMP_RESULTS_TBL == i_section )
+ {
+ //For security we can't trust the FSP's payload attribute
+ // on MPIPLs for the dump tables.
+ //@todo: RTC:59171
+
+ // Find the right tuple and verify it makes sense
+ hdat5Tuple_t* tuple = &(spira->hdatDataArea[HDAT_MS_DUMP_RSLT_TBL]);
+ TRACUCOMP( g_trac_runtime, "MS_DUMP_RESULTS_TBL tuple=%p", tuple );
+ errhdl = check_tuple( payload_base,
+ 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;
+ }
+ // Not sure how we could get here...
+ else
+ {
+ TRACFCOMP( g_trac_runtime, "get_host_data_section> Unknown section %d", i_section );
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION
+ * @reasoncode RUNTIME::RC_INVALID_SECTION
+ * @userdata1 Section Id
+ * @userdata2 <unused>
+ * @devdesc Unknown section requested
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION,
+ RUNTIME::RC_INVALID_SECTION,
+ i_section,
+ 0);
+ errhdl->collectTrace("RUNTIME",1024);
+ break;
+ }
+
+ // Make sure the range we return is pointing somewhere valid
+ errhdl = verify_hdat_address( payload_base,
+ o_dataAddr,
+ o_dataSize );
+ if( errhdl ) { break; }
+
+ } while(0);
+
+ TRACFCOMP( g_trac_runtime, "get_host_data_section> o_dataAddr=0x%X, o_dataSize=%d", o_dataAddr, o_dataSize );
+
+ return errhdl;
+}
+
+
+/********************
+ Private/Protected Methods
+ ********************/
+
diff --git a/src/usr/runtime/hdatstructs.H b/src/usr/runtime/hdatstructs.H
new file mode 100644
index 000000000..d96a51883
--- /dev/null
+++ b/src/usr/runtime/hdatstructs.H
@@ -0,0 +1,244 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/hdatstructs.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <stdint.h>
+#include <vmmconst.h>
+#include <string.h>
+
+// Copied from FipS:src/hdat/fsp/hdatnaca.H
+// offset in mainstore where NACA starts
+const uint64_t HDAT_NACA_OFFSET = 0x00004000;
+
+
+/* NOTE: Most of these structures were copied and adapted from the HDAT
+ component in FipS. They do not need to be kept exactly in sync so long
+ as this code follows the HDAT specification. */
+
+// Copied from FipS:src/hdat/fsp/hdatnaca.H
+/** @brief
+ * This type definition defines the Node Address Communication Area (NACA).
+ * The NACA is a data structure used primarily by the host operating
+ * system. The NACA is prebuilt as part of the primary host LID. FipS
+ * uses several fields in the NACA to determine where the LID table
+ * and the Service Processor Interace Root Array reside.
+ * Fields which are not used by FipS are just defined as reserved so
+ * that we don't have to chase uninteresting changes the host OS may
+ * make to things FipS does not care about.
+ */
+struct hdatNaca_t
+{
+ uint8_t reserved1[48]; // 0x0000 Reserved space
+ uint64_t spira; // 0x0030 SPIRA offset
+ uint8_t reserved2[104]; // 0x0038 Reserved space
+ uint32_t spiraSize; // 0x00A0 Actual SPIRA size in bytes
+ uint8_t nacaReserved4[28]; // 0x00A4 reserved space
+ uint64_t nacaHypLoadMap; // 0x00C0 Hyp resident module load map
+ uint8_t nacaReserved5[228]; // 0x00C8 reserved space
+ uint8_t nacaFlags[4]; // 0x01AC Flags to control FSP function.
+ uint8_t nacaReserved6[5]; // 0x01B0 reserved space
+ uint8_t nacaSftAttn; // 0x01B5 Software attentions enabled
+ uint8_t nacaReserved7[1]; // 0x01B6 Reserved area not for FSP usage
+ uint8_t nacaPhypPciaSupport; // 0x01B7 PHYP supports PCIA format
+
+} __attribute__ ((packed));
+
+
+// Copied from FipS:src/hdat/fsp/hdatspira.H
+/** @enum hdatSpiraDataAreas
+ * This enumeration defines the various data areas that must be built
+ * and DMA'd to main memory or DMA'd from memory to the service
+ * processor.
+ * This list must be kept in the same order as the 5-tuple entries in
+ * the SPIRA.
+ *
+ * If the order is changed, entries are added, or entries are deleted,
+ * update the HDAT_STR_NAME array in hdatPrtSpira().
+ */
+enum hdatSpiraDataAreas
+{
+ HDAT_SPIRA_DA_FIRST = 0,
+ HDAT_SP_SUBSYS = 0, // service processor subsystem
+ HDAT_IPL_PARMS = 1, // IPL parameters
+ HDAT_ENCLOSURE_VPD = 2, // enclosure vital product data
+ HDAT_SLCA = 3, // slot location code array
+ HDAT_BACKPLANE_VPD = 4, // backplane vital product data
+ HDAT_SYS_VPD = 5, // system vital product data
+ HDAT_CHIP_TOD = 6, // chip time-of-day
+ HDAT_PROC_INIT = 7, // phyp-supplied processor init data
+ HDAT_CLOCK_VPD = 8, // clock vital product data
+ HDAT_ANCHOR_VPD = 9, // anchor card vital product data
+ HDAT_OP_PNL_VPD = 10, // operator panel vital product data
+ HDAT_L3_VPD = 11, // level 3 cache vital product data
+ HDAT_MISC_CEC_VPD = 12, // miscellaneous FRU vital product data
+ RSV_1 = 13, // (old PACA)
+ HDAT_MDT = 14, // memory description tree
+ HDAT_IO_HUB = 15, // I/O hub FRU array
+ HDAT_CPU_CTRL = 16, // CPU controls
+ HDAT_MS_DUMP_SRC_TBL = 17, // mainstore dump source table
+ HDAT_MS_DUMP_DST_TBL = 18, // mainstore dump destination table
+ HDAT_MS_DUMP_RSLT_TBL = 19, // mainstore dump results table
+ HDAT_SPIRA_DA_GA1LAST = 20, // End of list for 1st eclipz release
+ HDAT_HEAP = 20, // Phyp allocated storage location
+ HDAT_PCIA = 21, // PCIA (Core information area)
+ HDAT_PCRD = 22, // PCRD (Chip related data area)
+ HSVC_DATA = 23, // Host Services Data
+ HDAT_SPIRA_DA_LAST = 24
+};
+
+
+// Copied from FipS:src/hdat/fsp/hdatspira.H
+/** @brief Type definition for the 5-tuples that the SPIRA uses to address other
+ * data structures.
+ */
+struct hdat5Tuple_t
+{
+ uint64_t hdatAbsAddr; // 0x0000 Absolute address to a structure
+ uint16_t hdatAllocCnt; // 0x0008 Allocated count
+ uint16_t hdatActualCnt; // 0x000A Actual count
+ uint32_t hdatAllocSize; // 0x000C Allocated size in bytes
+ uint32_t hdatActualSize; // 0x0010 Actual size in bytes
+ uint32_t hdatTceOffset; // 0x0014 Offset to add to TCE at runtime
+ uint8_t hdatReserved1[8]; // 0x0018 Reserved for future use
+} __attribute__ ((packed));
+
+
+// Copied from FipS:src/hdat/fsp/hdat.H
+/** @brief Type definition for the common hypervisor Data Interface
+ * Format (HDIF) header.
+ */
+struct hdatHDIF_t
+{
+ uint16_t hdatStructId; // 0x0000 Structure format ID
+ char hdatStructName[6]; // 0x0002 Structure eye catcher
+ uint16_t hdatInstance; // 0x0008 Instance number
+ uint16_t hdatVersion; // 0x000A Structure version
+ uint32_t hdatSize; // 0x000C Total structure size in bytes
+ uint32_t hdatHdrSize; // 0x0010 Header size in bytes
+ uint32_t hdatDataPtrOffset; // 0x0014 Offset to hdatHDIFDataHdr_t
+ uint16_t hdatDataPtrCnt; // 0x0018 Count of hdatHDIFDataHdr_t structures
+ uint16_t hdatChildStrCnt; // 0x001A Count of hdatHDIFChildPtr_t structs
+ uint32_t hdatChildStrOffset; // 0x001C Offset to child structures array
+} __attribute__ ((packed));
+
+
+// Copied from FipS:src/hdat/fsp/hdat.H
+/** @brief Type definition for the "pointer" header to a child data structure.
+ */
+struct hdatHDIFChildHdr_t
+{
+ uint32_t hdatOffset; // 0x0000 Offset from top of structure
+ uint32_t hdatSize; // 0x0004 Child data structure size in bytes
+ uint32_t hdatCnt; // 0x0008 Count of child data structures
+} __attribute__ ((packed));
+
+
+// Copied from FipS:src/hdat/fsp/hdat.H
+/** @brief Type definition for the "pointer" header to the internal data.
+ */
+struct hdatHDIFDataHdr_t
+{
+ uint32_t hdatOffset; // 0x0000 Offset from top of structure
+ uint32_t hdatSize; // 0x0004 Data structure size in bytes
+} __attribute__ ((packed));
+
+
+// Copied from FipS:src/hdat/fsp/hdat.H
+/** @brief Type definition for the data array header. Used when internal
+ * data is an array.
+ */
+struct hdatHDIFDataArray_t
+{
+ uint32_t hdatOffset; // 0x0000 Offset to array from this structure
+ uint32_t hdatArrayCnt; // 0x0004 Number of array entries
+ uint32_t hdatAllocSize; // 0x0008 Size of allocated space for array entry
+ uint32_t hdatActSize; // 0x000C Actual size of an array entry
+} __attribute__ ((packed));
+
+
+// Copied from FipS:src/hdat/fsp/hdatspira.H
+/** @brief The SPIRA is composed of an HDIF header and an array. Each array
+ * entry is an n-tuple. That is, it is a structure with a particular
+ * number of fields
+ */
+struct hdatSpira_t
+{
+ hdatHDIF_t hdatHDIF; // 0x0000 Common HDIF header
+ hdatHDIFDataHdr_t hdatDataHdr; // 0x0020 Data "pointers"
+ uint8_t hdatReserved1[8]; // 0x0028 Padding/future growth
+ hdatHDIFDataArray_t hdatArrayInfo; // 0x0030 Info on 5-tuple array
+ hdat5Tuple_t hdatDataArea[HDAT_SPIRA_DA_LAST]; //0x0040 5-tuple array
+ // At this point, the host OS may have reserved extra space for future growth
+ // but FipS does not need to be concerned with the reserved space nor DMA it
+ // back from main memory.
+} __attribute__ ((packed));
+
+
+// Copied from FipS:src/hdat/fsp/hdatiplparms.H
+/** @brief Structure definition for system model and feature code
+ */
+struct hdatSysParms_t
+{
+ uint32_t hdatSysModel;
+ uint32_t hdatProcFeatCode;
+ uint32_t hdatEffectivePvr;
+ uint32_t hdatSysType;
+ uint8_t hdatNumLPARsPerOctant[8];
+ uint32_t hdatABCBusSpeed;
+ uint32_t hdatWXYZBusSpeed;
+ uint32_t hdatSystemECOMode;
+ uint32_t hdatSystemAttributes;
+ uint32_t hdatMemoryScrubbing;
+ uint16_t hdatCurrentSPPLValue;
+ uint8_t hdatPumpMode;
+ uint8_t usePoreSleep;
+ uint32_t poreImageSize;
+ uint8_t vTpmEnabled;
+ uint8_t hdatReserved;
+ uint16_t hdatDispWheel;
+} __attribute__ ((packed));
+
+
+/**
+ * @brief Structure used to verify header data
+ */
+struct hdatHeaderExp_t
+{
+ uint16_t id; //<* compare to hdatStructId
+ const char* name; //<* compare to hdatStructName
+ uint16_t version; //<* compare to hdatVersion
+
+ /**
+ * @brief Flatten data into a uint64_t
+ * @return [id:16][version:16][name:32]
+ */
+ const uint64_t flatten( void ) const
+ {
+ uint64_t retval = id;
+ retval <<= 16;
+ retval |= version;
+ retval <<= 32;
+ char* tmp = reinterpret_cast<char*>(&retval);
+ memcpy( tmp+4, name, 6 );
+ return retval;
+ };
+};
+
diff --git a/src/usr/runtime/makefile b/src/usr/runtime/makefile
index 54342e751..e5ef5bf81 100644
--- a/src/usr/runtime/makefile
+++ b/src/usr/runtime/makefile
@@ -30,7 +30,7 @@
ROOTPATH = ../../..
MODULE = runtime
-OBJS = populate_attributes.o
+OBJS = populate_attributes.o hdatservice.o
SUBDIRS = test.d
diff --git a/src/usr/runtime/populate_attributes.C b/src/usr/runtime/populate_attributes.C
index 7562b2d26..873e22df9 100644
--- a/src/usr/runtime/populate_attributes.C
+++ b/src/usr/runtime/populate_attributes.C
@@ -36,7 +36,7 @@
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
#include <runtime/runtime_reasoncodes.H>
-#include <sys/mm.h> //@fixme RTC:49509 - remove if no longer needed.
+#include <runtime/runtime.H>
#include "common/hsvc_attribute_structs.H"
//#include <arch/ppc.H> //for MAGIC_INSTRUCTION
@@ -183,12 +183,6 @@ struct node_data_t
};
-//@fixme RTC:49509
-// Steal the unused fake pnor space until we have mainstore
-#define SYSTEM_DATA_POINTER (64*MEGABYTE)
-#define NODE_DATA_POINTER (SYSTEM_DATA_POINTER+512*KILOBYTE)
-
-
/**
* @brief Populate system attributes for HostServices
*/
@@ -203,12 +197,40 @@ errlHndl_t populate_system_attributes( void )
do {
TRACDCOMP( g_trac_runtime, "-SYSTEM-" );
- // allocate memory and fill it with some junk data
- // @fixme RTC:49509 - remove mm_linear_map and put in real HDAT.
- mm_linear_map(reinterpret_cast<void*>(SYSTEM_DATA_POINTER), 4*MEGABYTE);
- system_data_t* sys_data =
- reinterpret_cast<system_data_t*>(SYSTEM_DATA_POINTER);
+ // find our memory range and fill it with some junk data
+ uint64_t sys_data_addr = 0;
+ uint64_t sys_data_size = 0;
+ errhdl = RUNTIME::get_host_data_section(RUNTIME::HSVC_SYSTEM_DATA,
+ 0,
+ sys_data_addr,
+ sys_data_size );
+ if( errhdl )
+ {
+ TRACFCOMP( g_trac_runtime, "Could not find a space for the system data" );
+ break;
+ }
+ if( (sys_data_addr == 0) || (sys_data_size == 0) )
+ {
+ TRACFCOMP( g_trac_runtime, "Invalid memory values for HSVC_SYSTEM_DATA" );
+ /*@
+ * @errortype
+ * @reasoncode RUNTIME::RC_INVALID_SECTION
+ * @moduleid RUNTIME::MOD_RUNTIME_POP_SYS_ATTR
+ * @userdata1 Returned address: sys_data_addr
+ * @userdata2 Returned size: sys_data_size
+ * @devdesc Invalid memory values for HSVC_SYSTEM_DATA
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_RUNTIME_POP_SYS_ATTR,
+ RUNTIME::RC_INVALID_SECTION,
+ sys_data_addr,
+ sys_data_size );
+ break;
+ }
+ system_data_t* sys_data = reinterpret_cast<system_data_t*>(sys_data_addr);
memset( sys_data, 'A', sizeof(system_data_t) );
+ //@fixme - Should test that we aren't going out of bounds
// These variables are used by the HSVC_LOAD_ATTR macros directly
uint64_t* _num_attr = NULL; //pointer to numAttr in struct
@@ -293,9 +315,40 @@ errlHndl_t populate_node_attributes( uint64_t i_nodeNum )
TRACDCOMP( g_trac_runtime, "-NODE-" );
// allocate memory and fill it with some junk data
- node_data_t* node_data =
- reinterpret_cast<node_data_t*>(NODE_DATA_POINTER);
+ uint64_t node_data_addr = 0;
+ size_t node_data_size = 0;
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::HSVC_NODE_DATA,
+ 0,
+ node_data_addr,
+ node_data_size );
+ if( errhdl )
+ {
+ TRACFCOMP( g_trac_runtime, "Could not find a space for the node data" );
+ break;
+ }
+ if( (node_data_addr == 0) || (node_data_size == 0) )
+ {
+ TRACFCOMP( g_trac_runtime, "Invalid memory values for HSVC_NODE_DATA" );
+ /*@
+ * @errortype
+ * @reasoncode RUNTIME::RC_INVALID_SECTION
+ * @moduleid RUNTIME::MOD_RUNTIME_POP_NODE_ATTR
+ * @userdata1 Returned address: node_data_addr
+ * @userdata2 Returned size: node_data_size
+ * @devdesc Invalid memory values for HSVC_NODE_DATA
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_RUNTIME_POP_NODE_ATTR,
+ RUNTIME::RC_INVALID_SECTION,
+ node_data_addr,
+ node_data_size );
+ break;
+ }
+ node_data_t* node_data = reinterpret_cast<node_data_t*>(node_data_addr);
memset( node_data, 'A', sizeof(node_data) );
+ //@fixme - Should test that we aren't going out of bounds
// These variables are used by the HSVC_LOAD_ATTR macros directly
uint64_t* _num_attr = NULL; //pointer to numAttr in struct
@@ -314,7 +367,7 @@ errlHndl_t populate_node_attributes( uint64_t i_nodeNum )
size_t next_proc = 0;
size_t next_ex = 0;
- // Fill in the metadat
+ // Fill in the metadata
node_data->hsvc.numTargets = 0;
node_data->hsvc.procOffset =
reinterpret_cast<uint64_t>(node_data->procs)
@@ -471,6 +524,13 @@ errlHndl_t populate_attributes( void )
do {
TRACFCOMP( g_trac_runtime, "Running populate_attributes" );
+ // Map the Host Data into the VMM
+ errhdl = RUNTIME::load_host_data();
+ if( errhdl )
+ {
+ break;
+ }
+
//@todo : Remove this before RTC:49137 is merged, fix with RTC:49509
// Skip this in VPO
if( TARGETING::is_vpo() )
diff --git a/src/usr/runtime/test/hdatservicetest.H b/src/usr/runtime/test/hdatservicetest.H
new file mode 100644
index 000000000..8d5dd72de
--- /dev/null
+++ b/src/usr/runtime/test/hdatservicetest.H
@@ -0,0 +1,308 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/test/hdatservicetest.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __TEST_HDATSERVICETEST_H
+#define __TEST_HDATSERVICETEST_H
+
+/**
+ * @file runtimetest.H
+ *
+ */
+
+#include <cxxtest/TestSuite.H>
+
+#include <arch/ppc.H> //for MAGIC
+#include <errl/errlmanager.H>
+#include <runtime/runtime.H>
+#include <targeting/common/commontargeting.H>
+#include <attributeenums.H>
+#include "../hdatstructs.H"
+
+extern trace_desc_t* g_trac_runtime;
+
+class HdatServiceTest: public CxxTest::TestSuite
+{
+ public:
+ void testHdat(void)
+ {
+ TRACFCOMP( g_trac_runtime, "testHdat> start" );
+ errlHndl_t errhdl = NULL;
+
+ // Figure out if we expect to have this data or not
+ TARGETING::Target * sys = NULL;
+ TARGETING::targetService().getTopLevelTarget( sys );
+ assert(sys != NULL);
+ TARGETING::ATTR_PAYLOAD_KIND_type payload_kind =
+ sys->getAttr<TARGETING::ATTR_PAYLOAD_KIND>();
+
+ // Verify something in the system parms
+ uint64_t sys_parms_addr = 0;
+ size_t sys_parms_size = 0;
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::IPLPARMS_SYSTEM,
+ 0,
+ sys_parms_addr,
+ sys_parms_size );
+ if( payload_kind == TARGETING::PAYLOAD_KIND_PHYP )
+ {
+ if( errhdl )
+ {
+ TS_FAIL("testHdat> Error trying to locate IPLPARMS_SYSTEM");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( sys_parms_addr == 0 )
+ {
+ TS_FAIL("testHdat> NULL returned for get_host_data_section(IPLPARMS_SYSTEM)");
+ }
+ else if( (sys_parms_size < sizeof(hdatSysParms_t))
+ || (sys_parms_size == RUNTIME::DATA_SIZE_UNKNOWN) )
+ {
+ TS_FAIL("testHdat> Size of IPLPARMS_SYSTEM data too small");
+ }
+ else
+ {
+ hdatSysParms_t* sys_parms = reinterpret_cast<hdatSysParms_t*>(sys_parms_addr);
+
+ uint32_t pvr = sys_parms->hdatEffectivePvr;
+ TRACFCOMP( g_trac_runtime, "PVR=%.8X", pvr );
+
+ TARGETING::Target* procmaster = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle( procmaster );
+ assert( procmaster != NULL );
+ TARGETING::ATTR_MODEL_type model =
+ procmaster->getAttr<TARGETING::ATTR_MODEL>();
+
+ if( (model == TARGETING::MODEL_MURANO)
+ && !((pvr & 0x00FF0000) == 0x004B0000) )
+ {
+ TS_FAIL("testHdat> PVR model != 4B for Murano");
+ }
+ else if( (model == TARGETING::MODEL_VENICE)
+ && !((pvr & 0x00FF0000) == 0x004D0000) )
+ {
+ TS_FAIL("testHdat> PVR model != 4D for Venice");
+ }
+ }
+ }
+ else
+ {
+ if( !errhdl )
+ {
+ TS_FAIL("testHdat> Did not get expected error trying to locate IPLPARMS_SYSTEM for non-PHYP Payload");
+ }
+ else
+ {
+ delete errhdl;
+ }
+ }
+
+
+
+ // Verify the HostServices Node Data
+ uint64_t node_data_addr = 0;
+ size_t node_data_size = 0;
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::HSVC_NODE_DATA,
+ 0,
+ node_data_addr,
+ node_data_size );
+ if( errhdl
+ && ((payload_kind == TARGETING::PAYLOAD_KIND_PHYP)
+ || (payload_kind == TARGETING::PAYLOAD_KIND_NONE)) )
+ {
+ TS_FAIL("testHdat> Error trying to locate HSVC_NODE_DATA");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( !errhdl
+ && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP)
+ && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) )
+ {
+ TS_FAIL("testHdat> Did not get expected error trying to locate HSVC_NODE_DATA for non-PHYP/Standalone Payload");
+ }
+ else if( (node_data_addr == 0)
+ && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP)
+ && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) )
+ {
+ TS_FAIL("testHdat> NULL or zero size returned for get_host_data_section(HSVC_NODE_DATA)");
+ }
+ else if( (node_data_size == 0)
+ || (node_data_size == RUNTIME::DATA_SIZE_UNKNOWN) )
+ {
+ TS_FAIL("testHdat> Size of HSVC_NODE_DATA is unexpected");
+ }
+ if( errhdl )
+ {
+ delete errhdl;
+ }
+
+
+ // Verify the HostServices System Data
+ uint64_t sys_data_addr = 0;
+ size_t sys_data_size = 0;
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::HSVC_SYSTEM_DATA,
+ 0,
+ sys_data_addr,
+ sys_data_size );
+ if( errhdl
+ && ((payload_kind == TARGETING::PAYLOAD_KIND_PHYP)
+ || (payload_kind == TARGETING::PAYLOAD_KIND_NONE)) )
+ {
+ TS_FAIL("testHdat> Error trying to locate HSVC_SYSTEM_DATA");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( !errhdl
+ && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP)
+ && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) )
+ {
+ TS_FAIL("testHdat> Did not get expected error trying to locate HSVC_SYSTEM_DATA for non-PHYP/Standalone Payload");
+ }
+ else if( ((sys_data_addr == 0) || (sys_data_size == 0))
+ && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP)
+ && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) )
+ {
+ TS_FAIL("testHdat> NULL or zero size returned for get_host_data_section(HSVC_SYSTEM_DATA)");
+ }
+ else if( (sys_data_size == 0)
+ || (sys_data_size == RUNTIME::DATA_SIZE_UNKNOWN) )
+ {
+ TS_FAIL("testHdat> Size of HSVC_SYSTEM_DATA is unexpected");
+ }
+ if( errhdl )
+ {
+ delete errhdl;
+ }
+
+ // Verify the Dump Tables
+ uint64_t dump_addr = 0;
+ size_t dump_size = 0;
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::MS_DUMP_SRC_TBL,
+ 0,
+ dump_addr,
+ dump_size );
+ if( errhdl && (payload_kind == TARGETING::PAYLOAD_KIND_PHYP) )
+ {
+ if( errhdl )
+ {
+ TS_FAIL("testHdat> Error trying to locate MS_DUMP_SRC_TBL");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( dump_addr == 0 )
+ {
+ TS_FAIL("testHdat> NULL returned for get_host_data_section(MS_DUMP_SRC_TBL)");
+ }
+ else if( dump_size < 16 ) //1 entry is 16 bytes
+ {
+ TRACFCOMP( g_trac_runtime, "testHdat> dump_size=%d", dump_size );
+ TS_FAIL("testHdat> Size of MS_DUMP_SRC_TBL data too small");
+ }
+ }
+ else
+ {
+ if( !errhdl )
+ {
+ TS_FAIL("testHdat> Did not get expected error trying to locate MS_DUMP_SRC_TBL for non-PHYP Payload");
+ }
+ else
+ {
+ delete errhdl;
+ }
+ }
+
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::MS_DUMP_DST_TBL,
+ 0,
+ dump_addr,
+ dump_size );
+ if( errhdl && (payload_kind == TARGETING::PAYLOAD_KIND_PHYP) )
+ {
+ if( errhdl )
+ {
+ TS_FAIL("testHdat> Error trying to locate MS_DUMP_DST_TBL");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( dump_addr == 0 )
+ {
+ TS_FAIL("testHdat> NULL returned for get_host_data_section(MS_DUMP_DST_TBL)");
+ }
+ else if( dump_size < 16 ) //1 entry is 16 bytes
+ {
+ TRACFCOMP( g_trac_runtime, "testHdat> dump_size=%d", dump_size );
+ TS_FAIL("testHdat> Size of MS_DUMP_DST_TBL data too small");
+ }
+ }
+ else
+ {
+ if( !errhdl )
+ {
+ TS_FAIL("testHdat> Did not get expected error trying to locate MS_DUMP_DST_TBL for non-PHYP Payload");
+ }
+ else
+ {
+ delete errhdl;
+ }
+ }
+
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::MS_DUMP_RESULTS_TBL,
+ 0,
+ dump_addr,
+ dump_size );
+ if( errhdl && (payload_kind == TARGETING::PAYLOAD_KIND_PHYP) )
+ {
+ if( errhdl )
+ {
+ TS_FAIL("testHdat> Error trying to locate MS_DUMP_RESULTS_TBL");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( dump_addr == 0 )
+ {
+ TS_FAIL("testHdat> NULL returned for get_host_data_section(MS_DUMP_RESULTS_TBL)");
+ }
+ else if( dump_size < 16 ) //1 entry is 16 bytes
+ {
+ TRACFCOMP( g_trac_runtime, "testHdat> dump_size=%d", dump_size );
+ TS_FAIL("testHdat> Size of MS_DUMP_RESULTS_TBL data too small");
+ }
+ }
+ else
+ {
+ if( !errhdl )
+ {
+ TS_FAIL("testHdat> Did not get expected error trying to locate MS_DUMP_RESULTS_TBL for non-PHYP Payload");
+ }
+ else
+ {
+ delete errhdl;
+ }
+ }
+
+
+ TRACFCOMP( g_trac_runtime, "testHdat> finish" );
+ }
+
+};
+
+
+#endif
+
diff --git a/src/usr/runtime/test/runtimeattrstest.H b/src/usr/runtime/test/runtimeattrstest.H
index 435c6bee6..76ccbac01 100644
--- a/src/usr/runtime/test/runtimeattrstest.H
+++ b/src/usr/runtime/test/runtimeattrstest.H
@@ -20,11 +20,11 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-#ifndef __TEST_RUNTIMETEST_H
-#define __TEST_RUNTIMETEST_H
+#ifndef __TEST_RUNTIMEATTRSTEST_H
+#define __TEST_RUNTIMEATTRSTEST_H
/**
- * @file runtimetest.H
+ * @file runtimeattrstest.H
*
*/
@@ -45,7 +45,7 @@ extern trace_desc_t* g_trac_runtime;
using namespace fapi;
-class RuntimeTest: public CxxTest::TestSuite
+class RuntimeAttrsTest: public CxxTest::TestSuite
{
public:
void testVerifySystemAttributes(void)
@@ -302,7 +302,7 @@ class RuntimeTest: public CxxTest::TestSuite
{
TS_FAIL("Error getting fapi::ATTR_CHIP_UNIT_POS");
errlHndl_t errhdl = fapiRcToErrl(l_rc);
- errlCommit(errhdl,CXXTEST_COMP_ID);
+ errlCommit(errhdl,RUNTIME_COMP_ID);
}
fapi::ATTR_FUNCTIONAL_Type tmp2 = 0;
@@ -311,7 +311,7 @@ class RuntimeTest: public CxxTest::TestSuite
{
TS_FAIL("Error getting fapi::ATTR_FUNCTIONAL");
errlHndl_t errhdl = fapiRcToErrl(l_rc);
- errlCommit(errhdl,CXXTEST_COMP_ID);
+ errlCommit(errhdl,RUNTIME_COMP_ID);
}
uint64_t attr = 0;
@@ -373,14 +373,27 @@ class RuntimeTest: public CxxTest::TestSuite
}
private:
- //@fixme RTC:49509
hsvc_system_data_t* getSysPtr(void)
{
- return( (hsvc_system_data_t*)(64*MEGABYTE) );
+ errlHndl_t errhdl = NULL;
+ uint64_t sys_data_addr = 0;
+ size_t sys_data_size = 0;
+ errhdl = RUNTIME::get_host_data_section(RUNTIME::HSVC_SYSTEM_DATA,
+ 0,
+ sys_data_addr,
+ sys_data_size );
+ return( (hsvc_system_data_t*)(sys_data_addr) );
};
hsvc_node_data_t* getNodePtr(void)
{
- return( (hsvc_node_data_t*)(64*MEGABYTE+512*KILOBYTE) );
+ errlHndl_t errhdl = NULL;
+ uint64_t node_data_addr = 0;
+ size_t node_data_size = 0;
+ errhdl = RUNTIME::get_host_data_section(RUNTIME::HSVC_NODE_DATA,
+ 0,
+ node_data_addr,
+ node_data_size );
+ return( (hsvc_node_data_t*)(node_data_addr) );
};
//utility to fetch a proc target based on a procid
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 4c7a9becf..6b52c81cf 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -3310,6 +3310,45 @@
<writeable/>
</attribute>
+<enumerationType>
+ <id>PAYLOAD_KIND</id>
+ <description>
+ Enumeration indicating what kind of payload is to be started
+ </description>
+ <enumerator>
+ <name>UNKNOWN</name>
+ <value>0</value>
+ </enumerator>
+ <enumerator>
+ <name>PHYP</name>
+ <value>1</value>
+ </enumerator>
+ <enumerator>
+ <name>AVP</name>
+ <value>2</value>
+ </enumerator>
+ <enumerator>
+ <name>NONE</name>
+ <value>3</value>
+ </enumerator>
+ <default>UNKNOWN</default>
+</enumerationType>
+
+<attribute>
+ <id>PAYLOAD_KIND</id>
+ <description>
+ Attribute indicating what kind of payload is to be started.
+ </description>
+ <simpleType>
+ <enumeration>
+ <id>PAYLOAD_KIND</id>
+ </enumeration>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <hasStringConversion/>
+</attribute>
+
<attribute>
<id>EFF_DRAM_BANKS</id>
<description>Number of DRAM banks. Initialized and used by HWPs.</description>
diff --git a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
index e0ab6dea5..2695b6ddc 100644
--- a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
@@ -133,6 +133,10 @@
<default>0x0</default>
</attribute>
<attribute>
+ <id>PAYLOAD_KIND</id>
+ <default>NONE</default>
+ </attribute>
+ <attribute>
<id>MSS_MCA_HASH_MODE</id>
<default>0</default>
</attribute>
diff --git a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
index 498eed08b..284c2c1f2 100644
--- a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
@@ -109,6 +109,10 @@
<default>0x0</default>
</attribute>
<attribute>
+ <id>PAYLOAD_KIND</id>
+ <default>NONE</default>
+ </attribute>
+ <attribute>
<id>MSS_MCA_HASH_MODE</id>
<default>0</default>
</attribute>
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index b15e230b6..9754b5713 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -98,6 +98,7 @@
<attribute><id>FREQ_A</id></attribute>
<attribute><id>FREQ_X</id></attribute>
<attribute><id>SP_FUNCTIONS</id></attribute>
+ <attribute><id>PAYLOAD_KIND</id></attribute>
<attribute><id>PAYLOAD_BASE</id></attribute>
<attribute><id>PAYLOAD_ENTRY</id></attribute>
<attribute><id>MSS_MCA_HASH_MODE</id></attribute>
diff --git a/src/usr/targeting/common/xmltohb/vbu.system.xml b/src/usr/targeting/common/xmltohb/vbu.system.xml
index e5d9be752..6c5623166 100644
--- a/src/usr/targeting/common/xmltohb/vbu.system.xml
+++ b/src/usr/targeting/common/xmltohb/vbu.system.xml
@@ -125,6 +125,10 @@
<default>0x100</default>
</attribute>
<attribute>
+ <id>PAYLOAD_KIND</id>
+ <default>AVP</default>
+ </attribute>
+ <attribute>
<id>MSS_MCA_HASH_MODE</id>
<default>0</default>
</attribute>
diff --git a/src/usr/targeting/xmltohb/genHwsvMrwXml.pl b/src/usr/targeting/xmltohb/genHwsvMrwXml.pl
index 8d34e27a0..0f93ae081 100755
--- a/src/usr/targeting/xmltohb/genHwsvMrwXml.pl
+++ b/src/usr/targeting/xmltohb/genHwsvMrwXml.pl
@@ -1275,6 +1275,39 @@ sub generate_sys
<field><id>fsiMasterInit</id><value>1</value></field>
<field><id>reserved</id><value>0</value></field>
</default>
+ </attribute>
+ <attribute>
+ <id>PAYLOAD_KIND</id>
+ <default>PHYP</default>
+ </attribute>
+ <!-- TODO. These must be from MRW. Hardcoded for now -->
+ <attribute>
+ <id>PAYLOAD_BASE</id>
+ <default>256</default>
+ </attribute>
+ <attribute>
+ <id>PAYLOAD_ENTRY</id>
+ <default>0x180</default>
+ </attribute>
+ <attribute>
+ <id>MSS_MCA_HASH_MODE</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>MSS_MBA_ADDR_INTERLEAVE_BIT</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>MSS_MBA_CACHELINE_INTERLEAVE_MODE</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>MSS_PREFETCH_ENABLE</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>MSS_CLEANER_ENABLE</id>
+ <default>1</default>
</attribute>";
if($build eq "fsp")
OpenPOWER on IntegriCloud