summaryrefslogtreecommitdiffstats
path: root/src/usr/runtime
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2013-07-16 11:13:11 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-07-30 16:43:06 -0500
commit12ff45d42b4fa04bdbf36ed36147b5c07e36939f (patch)
tree2d675ac72aa7f74745c2653bad7a2e26ecbc791d /src/usr/runtime
parentb24fe45bee8160d77f130161267ba5a575098a77 (diff)
downloadtalos-hostboot-12ff45d42b4fa04bdbf36ed36147b5c07e36939f.tar.gz
talos-hostboot-12ff45d42b4fa04bdbf36ed36147b5c07e36939f.zip
Support SPIRA-H HDAT Format
Change-Id: If87eedf15c1ef96ea00c1a5574ad1f6b72e697b5 RTC: 71881 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5498 Reviewed-by: Michael Baiocchi <baiocchi@us.ibm.com> Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/runtime')
-rw-r--r--src/usr/runtime/errlud_hdat.C119
-rw-r--r--src/usr/runtime/errlud_hdat.H127
-rw-r--r--src/usr/runtime/hdatservice.C408
-rw-r--r--src/usr/runtime/hdatservice.H25
-rw-r--r--src/usr/runtime/hdatstructs.H118
-rw-r--r--src/usr/runtime/makefile3
-rw-r--r--src/usr/runtime/plugins/RUNTIME_COMP_ID_Parse.C27
-rw-r--r--src/usr/runtime/plugins/errludP_hdat.H294
-rw-r--r--src/usr/runtime/plugins/runtimeUdParserFactory.H55
-rw-r--r--src/usr/runtime/test/hdatservicetest.H119
-rw-r--r--src/usr/runtime/test/makefile3
11 files changed, 1188 insertions, 110 deletions
diff --git a/src/usr/runtime/errlud_hdat.C b/src/usr/runtime/errlud_hdat.C
new file mode 100644
index 000000000..72d024f0e
--- /dev/null
+++ b/src/usr/runtime/errlud_hdat.C
@@ -0,0 +1,119 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/errlud_hdat.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* 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 */
+/**
+ * @file errlud_hdat.C
+ *
+ * @brief Implementation of classes to log and parse various HDAT structures
+ */
+#include "errlud_hdat.H"
+#include <runtime/runtime_reasoncodes.H>
+#include <string.h>
+#include "hdatstructs.H"
+#include <sys/mm.h>
+
+namespace RUNTIME
+{
+
+//------------------------------------------------------------------------------
+// NACA
+//------------------------------------------------------------------------------
+UdNaca::UdNaca(hdatNaca_t* i_naca)
+{
+ if( 0 == mm_virt_to_phys(reinterpret_cast<void*>(i_naca)) )
+ {
+ return;
+ }
+
+ char * l_pBuf = reinterpret_cast<char *>(
+ reallocUsrBuf(sizeof(hdatNaca_t)));
+ memcpy(l_pBuf, i_naca, sizeof(hdatNaca_t));
+
+ // Set up Ud instance variables
+ iv_CompId = RUNTIME_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = RUNTIME_UDT_NACA;
+}
+
+//------------------------------------------------------------------------------
+UdNaca::~UdNaca()
+{
+
+}
+
+
+//------------------------------------------------------------------------------
+// SPIRA
+//------------------------------------------------------------------------------
+UdSpira::UdSpira(hdatSpira_t* i_spira)
+{
+ if( 0 == mm_virt_to_phys(reinterpret_cast<void*>(i_spira)) )
+ {
+ return;
+ }
+
+ char * l_pBuf = reinterpret_cast<char *>(
+ reallocUsrBuf(sizeof(hdatSpira_t)));
+ memcpy(l_pBuf, i_spira, sizeof(hdatSpira_t));
+
+ // Set up Ud instance variables
+ iv_CompId = RUNTIME_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = RUNTIME_UDT_SPIRA;
+}
+
+//------------------------------------------------------------------------------
+UdSpira::~UdSpira()
+{
+
+}
+
+
+//------------------------------------------------------------------------------
+// Tuple
+//------------------------------------------------------------------------------
+UdTuple::UdTuple(hdat5Tuple_t* i_tuple)
+{
+ if( 0 == mm_virt_to_phys(reinterpret_cast<void*>(i_tuple)) )
+ {
+ return;
+ }
+
+ char * l_pBuf = reinterpret_cast<char *>(
+ reallocUsrBuf(sizeof(hdat5Tuple_t)));
+ memcpy(l_pBuf, i_tuple, sizeof(hdat5Tuple_t));
+
+ // Set up Ud instance variables
+ iv_CompId = RUNTIME_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = RUNTIME_UDT_TUPLE;
+}
+
+//------------------------------------------------------------------------------
+UdTuple::~UdTuple()
+{
+
+}
+
+
+}
+
diff --git a/src/usr/runtime/errlud_hdat.H b/src/usr/runtime/errlud_hdat.H
new file mode 100644
index 000000000..bba024294
--- /dev/null
+++ b/src/usr/runtime/errlud_hdat.H
@@ -0,0 +1,127 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/errlud_hdat.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* 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 ERRL_UD_HDAT_H
+#define ERRL_UD_HDAT_H
+
+/**
+ * @file errlud_naca.H
+ *
+ * Defines the classes that logs and parses various HDAT structures
+ */
+
+#include <errl/errluserdetails.H>
+#include "hdatstructs.H"
+
+namespace RUNTIME
+{
+
+/**
+ * @class UdNaca
+ *
+ * Adds NACA FFDC to an error log as user detail data
+ */
+class UdNaca : public ERRORLOG::ErrlUserDetails
+{
+public:
+ /**
+ * @brief Constructor
+ *
+ * Copies the NACA data into the FFDC data
+ *
+ * @param i_naca Pointer to NACA data to capture
+ */
+ UdNaca(hdatNaca_t* i_naca);
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdNaca();
+
+private:
+ // Disabled
+ UdNaca(UdNaca &);
+ UdNaca & operator=(UdNaca &);
+};
+
+
+/**
+ * @class UdSpira
+ *
+ * Adds SPIRA FFDC to an error log as user detail data
+ */
+class UdSpira : public ERRORLOG::ErrlUserDetails
+{
+public:
+ /**
+ * @brief Constructor
+ *
+ * Copies the SPIRA data into the FFDC data
+ *
+ * @param i_spira Pointer to Spira data to capture
+ */
+ UdSpira(hdatSpira_t* i_spira);
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdSpira();
+
+private:
+ // Disabled
+ UdSpira(UdSpira &);
+ UdSpira & operator=(UdSpira &);
+};
+
+
+/**
+ * @class UdSpira
+ *
+ * Adds a Tuple FFDC to an error log as user detail data
+ */
+class UdTuple : public ERRORLOG::ErrlUserDetails
+{
+public:
+ /**
+ * @brief Constructor
+ *
+ * Copies the SPIRA data into the FFDC data
+ *
+ * @param i_spira Pointer to Spira data to capture
+ */
+ UdTuple(hdat5Tuple_t* i_spira);
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdTuple();
+
+private:
+ // Disabled
+ UdTuple(UdSpira &);
+ UdTuple & operator=(UdSpira &);
+};
+
+}
+
+#endif
+
diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C
index e60927b37..3c40d91eb 100644
--- a/src/usr/runtime/hdatservice.C
+++ b/src/usr/runtime/hdatservice.C
@@ -33,6 +33,8 @@
#include "fakepayload.H"
#include <dump/dumpif.H>
#include "hdatservice.H"
+#include "errlud_hdat.H"
+#include <errl/errlmanager.H>
extern trace_desc_t* g_trac_runtime;
@@ -62,6 +64,18 @@ const hdatHeaderExp_t IPLPARMS_SYSTEM_HEADER = {
0x0058 //version
};
+const hdatHeaderExp_t SPIRAH_HEADER = {
+ 0xD1F0, //id
+ "SPIRAH", //name
+ 0x0050 //version
+};
+
+const hdatHeaderExp_t SPIRAS_HEADER = {
+ 0xD1F0, //id
+ "SPIRAS", //name
+ 0x0040 //version
+};
+
//big enough to hold all of PHYP
const uint64_t HDAT_MEM_SIZE = 128*MEGABYTE;
@@ -220,6 +234,7 @@ errlHndl_t check_tuple( uint64_t i_base,
i_tuple->hdatAllocCnt,
i_tuple->hdatAllocSize));
errhdl->collectTrace("RUNTIME",1024);
+ RUNTIME::UdTuple(i_tuple).addToLog(errhdl);
break;
}
} while(0);
@@ -287,7 +302,11 @@ errlHndl_t hdatService::get_standalone_section(
}
hdatService::hdatService(void)
-:iv_payload_addr(NULL), iv_dumptest_addr(NULL)
+:iv_payload_addr(NULL)
+,iv_dumptest_addr(NULL)
+,iv_spiraL(NULL)
+,iv_spiraH(NULL)
+,iv_spiraS(NULL)
{
}
@@ -344,6 +363,13 @@ errlHndl_t hdatService::loadHostData(void)
}
}
+#ifdef REAL_HDAT_TEST
+ // Manually load HDAT memory now
+ TRACFCOMP( g_trac_runtime, "Forcing PHYP mode for testing" );
+ MAGIC_INSTRUCTION(MAGIC_BREAK);
+ payload_kind = TARGETING::PAYLOAD_KIND_PHYP;
+#endif
+
if( TARGETING::PAYLOAD_KIND_PHYP == payload_kind )
{
// PHYP
@@ -353,13 +379,17 @@ errlHndl_t hdatService::loadHostData(void)
uint64_t hdat_start = payload_base*MEGABYTE;
uint64_t hdat_size = HDAT_MEM_SIZE;
+#ifdef REAL_HDAT_TEST
+ hdat_start = 256*MEGABYTE;
+#endif
+
// 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 );
+ hdat_size );
if (NULL == iv_payload_addr)
{
TRACFCOMP( g_trac_runtime, "Failure calling mm_block_map : iv_payload_addr=%p",
@@ -462,7 +492,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
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 );
+ TRACFCOMP( g_trac_runtime, "RUNTIME::getHostDataSection( i_section=%d, i_instance=%d )", i_section, i_instance );
do
{
@@ -484,6 +514,11 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
TARGETING::ATTR_PAYLOAD_KIND_type payload_kind
= sys->getAttr<TARGETING::ATTR_PAYLOAD_KIND>();
+#ifdef REAL_HDAT_TEST
+ TRACFCOMP( g_trac_runtime, "Forcing PHYP mode for testing" );
+ payload_kind = TARGETING::PAYLOAD_KIND_PHYP;
+#endif
+
if( TARGETING::PAYLOAD_KIND_NONE == payload_kind )
{
errhdl = get_standalone_section( i_section,
@@ -495,17 +530,17 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
}
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 );
+ TRACFCOMP( g_trac_runtime, "getHostDataSection> There is no host data for PAYLOAD_KIND=%d", payload_kind );
/*@
* @errortype
- * @moduleid RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION
+ * @moduleid RUNTIME::MOD_HDATSERVICE_GETHOSTDATASECTION
* @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::MOD_HDATSERVICE_GETHOSTDATASECTION,
RUNTIME::RC_INVALID_PAYLOAD_KIND,
payload_kind,
i_section);
@@ -516,59 +551,70 @@ 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);
- // 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 );
+ // Setup the SPIRA pointers
+ errhdl = findSpira();
+ if( errhdl ) { break; }
- // Do some sanity checks on the NACA
- if( naca->nacaPhypPciaSupport != 1 )
+
+ // NACA
+ if( RUNTIME::NACA == i_section )
{
- 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;
+ o_dataAddr = reinterpret_cast<uint64_t>(iv_payload_addr);
+ o_dataAddr += HDAT_NACA_OFFSET;
+ o_dataSize = sizeof(hdatNaca_t);
}
-
-
- // 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 )
+ // SPIRA-H
+ else if( (RUNTIME::SPIRA_H == i_section) && iv_spiraH )
{
- TRACFCOMP( g_trac_runtime, "Spira is at a wacky offset!!! %.16X", naca->spira );
- //@todo-log NACA data RTC:53139
- break;
+ o_dataAddr = reinterpret_cast<uint64_t>(iv_spiraH);
+ if( iv_spiraH )
+ {
+ o_dataSize = iv_spiraH->hdatHDIF.hdatSize;
+ }
+ else
+ {
+ o_dataSize = 0;
+ }
+ }
+ // SPIRA-S
+ else if( (RUNTIME::SPIRA_S == i_section) && iv_spiraS )
+ {
+ o_dataAddr = reinterpret_cast<uint64_t>(iv_spiraS);
+ if( iv_spiraS )
+ {
+ o_dataSize = iv_spiraS->hdatHDIF.hdatSize;
+ }
+ else
+ {
+ o_dataSize = 0;
+ }
+ }
+ // Legacy SPIRA
+ else if( (RUNTIME::SPIRA_L == i_section) && iv_spiraL )
+ {
+ o_dataAddr = reinterpret_cast<uint64_t>(iv_spiraL);
+ if( iv_spiraL )
+ {
+ o_dataSize = iv_spiraL->hdatHDIF.hdatSize;
+ }
+ else
+ {
+ o_dataSize = 0;
+ }
}
-
// Host Services System Data
- if( RUNTIME::HSVC_SYSTEM_DATA == i_section )
+ else if( RUNTIME::HSVC_SYSTEM_DATA == i_section )
{
// Find the right tuple and verify it makes sense
- hdat5Tuple_t* tuple = &(spira->hdatDataArea[HSVC_DATA]);
+ hdat5Tuple_t* tuple = NULL;
+ if( iv_spiraS )
+ {
+ tuple = &(iv_spiraS->hdatDataArea[SPIRAS_HSVC_DATA]);
+ }
+ else if( unlikely(iv_spiraL != NULL) )
+ {
+ tuple = &(iv_spiraL->hdatDataArea[SPIRAL_HSVC_DATA]);
+ }
TRACUCOMP( g_trac_runtime, "HSVC_SYSTEM_DATA tuple=%p", tuple );
errhdl = check_tuple( payload_base,
i_section,
@@ -603,7 +649,15 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
else if( RUNTIME::HSVC_NODE_DATA == i_section )
{
// Find the right tuple and verify it makes sense
- hdat5Tuple_t* tuple = &(spira->hdatDataArea[HSVC_DATA]);
+ hdat5Tuple_t* tuple = NULL;
+ if( iv_spiraS )
+ {
+ tuple = &(iv_spiraS->hdatDataArea[SPIRAS_HSVC_DATA]);
+ }
+ else if( unlikely(iv_spiraL != NULL) )
+ {
+ tuple = &(iv_spiraL->hdatDataArea[SPIRAL_HSVC_DATA]);
+ }
TRACUCOMP( g_trac_runtime, "HSVC_NODE_DATA tuple=%p", tuple );
errhdl = check_tuple( payload_base,
i_section,
@@ -640,7 +694,8 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
sizeof(hdatHDIF_t)*(node_header->hdatCnt) );
if( errhdl ) { break; }
- // Loop around all instances because the data could be sparsely populated
+ // 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;
@@ -685,10 +740,10 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
// 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 );
+ TRACFCOMP( g_trac_runtime, "getHostDataSection> HSVC_NODE_DATA instance %d of section %d is unallocated", i_instance, i_section );
/*@
* @errortype
- * @moduleid RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION
+ * @moduleid RUNTIME::MOD_HDATSERVICE_GETHOSTDATASECTION
* @reasoncode RUNTIME::RC_NO_HSVC_NODE_DATA_FOUND
* @userdata1 Mainstore address of node_data_headers
* @userdata2[0:31] Requested Instance
@@ -698,7 +753,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
*/
errhdl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION,
+ RUNTIME::MOD_HDATSERVICE_GETHOSTDATASECTION,
RUNTIME::RC_NO_HSVC_NODE_DATA_FOUND,
reinterpret_cast<uint64_t>(node_data_headers),
TWO_UINT32_TO_UINT64(i_instance,
@@ -712,7 +767,15 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
else if( RUNTIME::IPLPARMS_SYSTEM == i_section )
{
// Find the right tuple and verify it makes sense
- hdat5Tuple_t* tuple = &(spira->hdatDataArea[HDAT_IPL_PARMS]);
+ hdat5Tuple_t* tuple = NULL;
+ if( iv_spiraS )
+ {
+ tuple = &(iv_spiraS->hdatDataArea[SPIRAS_IPL_PARMS]);
+ }
+ else if( unlikely(iv_spiraL != NULL) )
+ {
+ tuple = &(iv_spiraL->hdatDataArea[SPIRAL_IPL_PARMS]);
+ }
TRACUCOMP( g_trac_runtime, "IPLPARMS_SYSTEM tuple=%p", tuple );
errhdl = check_tuple( payload_base,
i_section,
@@ -752,7 +815,15 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
//@todo: RTC:59171
// Find the right tuple and verify it makes sense
- hdat5Tuple_t* tuple = &(spira->hdatDataArea[HDAT_MS_DUMP_SRC_TBL]);
+ hdat5Tuple_t* tuple = NULL;
+ if( iv_spiraS )
+ {
+ tuple = &(iv_spiraS->hdatDataArea[SPIRAH_MS_DUMP_SRC_TBL]);
+ }
+ else if( unlikely(iv_spiraL != NULL) )
+ {
+ 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,
@@ -771,7 +842,15 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
//@todo: RTC:59171
// Find the right tuple and verify it makes sense
- hdat5Tuple_t* tuple = &(spira->hdatDataArea[HDAT_MS_DUMP_DST_TBL]);
+ hdat5Tuple_t* tuple = NULL;
+ if( iv_spiraS )
+ {
+ tuple = &(iv_spiraS->hdatDataArea[SPIRAH_MS_DUMP_DST_TBL]);
+ }
+ else if( unlikely(iv_spiraL != NULL) )
+ {
+ 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,
@@ -790,7 +869,15 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
//@todo: RTC:59171
// Find the right tuple and verify it makes sense
- hdat5Tuple_t* tuple = &(spira->hdatDataArea[HDAT_MS_DUMP_RSLT_TBL]);
+ hdat5Tuple_t* tuple = NULL;
+ if( iv_spiraS )
+ {
+ tuple = &(iv_spiraS->hdatDataArea[SPIRAH_MS_DUMP_RSLT_TBL]);
+ }
+ else if( unlikely(iv_spiraL != NULL) )
+ {
+ 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,
@@ -805,10 +892,10 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
// Not sure how we could get here...
else
{
- TRACFCOMP( g_trac_runtime, "get_host_data_section> Unknown section %d", i_section );
+ TRACFCOMP( g_trac_runtime, "getHostDataSection> Unknown section %d", i_section );
/*@
* @errortype
- * @moduleid RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION
+ * @moduleid RUNTIME::MOD_HDATSERVICE_GETHOSTDATASECTION
* @reasoncode RUNTIME::RC_INVALID_SECTION
* @userdata1 Section Id
* @userdata2 <unused>
@@ -816,7 +903,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
*/
errhdl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_HDATSERVICE_GET_HOST_DATA_SECTION,
+ RUNTIME::MOD_HDATSERVICE_GETHOSTDATASECTION,
RUNTIME::RC_INVALID_SECTION,
i_section,
0);
@@ -832,7 +919,198 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
} while(0);
- TRACFCOMP( g_trac_runtime, "get_host_data_section> o_dataAddr=0x%X, o_dataSize=%d", o_dataAddr, o_dataSize );
+ TRACFCOMP( g_trac_runtime, "getHostDataSection> o_dataAddr=0x%X, o_dataSize=%d", o_dataAddr, o_dataSize );
+
+ return errhdl;
+}
+
+/**
+ * @brief Locates the proper SPIRA structure and sets instance vars
+ */
+errlHndl_t hdatService::findSpira( void )
+{
+ errlHndl_t errhdl = NULL;
+ errlHndl_t errhdl_s = NULL; //SPIRA-S error
+ errlHndl_t errhdl_l = NULL; //Legacy SPIRA error
+
+ do {
+ // Only do this once
+ if( iv_spiraL || iv_spiraH || iv_spiraS )
+ {
+ break;
+ }
+
+ // Go fetch the relative zero address that PHYP uses
+ uint64_t payload_base = reinterpret_cast<uint64_t>(iv_payload_addr);
+
+ // 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, "findSpira> nacaPhypPciaSupport=%.8X", naca->nacaPhypPciaSupport );
+
+ // Figure out what kind of payload we have
+ TARGETING::Target * sys = NULL;
+ TARGETING::targetService().getTopLevelTarget( sys );
+ TARGETING::ATTR_PAYLOAD_KIND_type payload_kind
+ = sys->getAttr<TARGETING::ATTR_PAYLOAD_KIND>();
+
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_FINDSPIRA
+ * @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_FINDSPIRA,
+ RUNTIME::RC_BAD_NACA,
+ reinterpret_cast<uint64_t>(naca),
+ TWO_UINT32_TO_UINT64(payload_base,
+ payload_kind));
+ errhdl->collectTrace("RUNTIME",1024);
+ RUNTIME::UdNaca(naca).addToLog(errhdl);
+ break;
+ }
+
+
+ // Are we using the SPIRA-H/S or Legacy format
+ if( naca->spiraH != 0 )
+ {
+ // pointer is also relative to PHYP's zero
+ iv_spiraH = reinterpret_cast<hdatSpira_t*>
+ (naca->spiraH + payload_base);
+ TRACFCOMP( g_trac_runtime, "SPIRA-H=%p", iv_spiraH );
+
+ // Check the headers and version info
+ errhdl = check_header( payload_base,
+ &(iv_spiraH->hdatHDIF),
+ SPIRAH_HEADER );
+ if( errhdl )
+ {
+ RUNTIME::UdNaca(naca).addToLog(errhdl);
+ break;
+ }
+
+ // SPIRA-S is at the beginning of the Host Data Area Tuple
+ uint64_t tuple_addr = reinterpret_cast<uint64_t>
+ (&(iv_spiraH->hdatDataArea[SPIRAH_HOST_DATA_AREAS]));
+ TRACUCOMP( g_trac_runtime, "SPIRA-S tuple offset=%.8X", tuple_addr );
+ // need to offset from virtual zero
+ 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,
+ tuple );
+ if( errhdl_s )
+ {
+ TRACFCOMP( g_trac_runtime, "SPIRA-S is invalid, will try legacy SPIRA" );
+ RUNTIME::UdNaca(naca).addToLog(errhdl_s);
+ iv_spiraS = NULL;
+ }
+ else
+ {
+ iv_spiraS = reinterpret_cast<hdatSpira_t*>
+ (tuple->hdatAbsAddr + payload_base);
+ TRACFCOMP( g_trac_runtime, "SPIRA-S=%p", iv_spiraS );
+
+ // Check the headers and version info
+ errhdl_s = check_header( payload_base,
+ &(iv_spiraH->hdatHDIF),
+ SPIRAS_HEADER );
+ if( errhdl_s )
+ {
+ TRACFCOMP( g_trac_runtime, "SPIRA-S is invalid, will try legacy SPIRA" );
+ RUNTIME::UdNaca(naca).addToLog(errhdl_s);
+ RUNTIME::UdSpira(iv_spiraS).addToLog(errhdl_s);
+ iv_spiraS = NULL;
+ }
+ }
+ }
+
+ //Legacy SPIRA
+ // pointer is also relative to PHYP's zero
+ iv_spiraL = reinterpret_cast<hdatSpira_t*>
+ (naca->spiraOld + payload_base);
+ TRACFCOMP( g_trac_runtime, "Legacy SPIRA=%p", iv_spiraL );
+
+ // Make sure the SPIRA is valid
+ errhdl_l = verify_hdat_address( payload_base,
+ iv_spiraL,
+ sizeof(hdatSpira_t) );
+ if( errhdl_l )
+ {
+ TRACFCOMP( g_trac_runtime, "Legacy Spira is at a wacky offset!!! %.16X", naca->spiraOld );
+ iv_spiraL = NULL;
+ RUNTIME::UdNaca(naca).addToLog(errhdl_l);
+ }
+ else
+ {
+ // Look for a filled in HEAP section to see if FSP is using the
+ // new or old format
+ // (Note: this is the logic PHYP is using)
+ hdat5Tuple_t* heap_tuple = &(iv_spiraL->hdatDataArea[SPIRAL_HEAP]);
+ TRACUCOMP( g_trac_runtime, "HEAP tuple=%p", heap_tuple );
+ if( heap_tuple->hdatActualSize == 0 )
+ {
+ TRACFCOMP( g_trac_runtime, "Legacy SPIRA is not filled in, using SPIRA-H/S" );
+ iv_spiraL = NULL;
+ }
+ }
+
+ // Make sure we have a good SPIRA somewhere
+ if( (iv_spiraL == NULL) && (iv_spiraS == NULL) )
+ {
+ TRACFCOMP( g_trac_runtime, "Could not find a valid SPIRA of any type" );
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_FINDSPIRA
+ * @reasoncode RUNTIME::RC_NO_SPIRA
+ * @userdata1[0:31] RC for Legacy SPIRA fail
+ * @userdata1[32:64] EID for Legacy SPIRA fail
+ * @userdata2[0:31] RC for SPIRA-S fail
+ * @userdata2[32:64] EID for SPIRA-S fail
+ * @devdesc Could not find a valid SPIRA of any type
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_FINDSPIRA,
+ RUNTIME::RC_BAD_NACA,
+ TWO_UINT32_TO_UINT64(ERRL_GETRC_SAFE(errhdl_l),
+ ERRL_GETEID_SAFE(errhdl_l)),
+ TWO_UINT32_TO_UINT64(ERRL_GETRC_SAFE(errhdl_s),
+ ERRL_GETEID_SAFE(errhdl_s)));
+ errhdl->collectTrace("RUNTIME",1024);
+
+ // commit the errors related to each SPIRA
+ if( errhdl_s )
+ {
+ errhdl_s->plid(errhdl->plid());
+ errlCommit(errhdl_s,RUNTIME_COMP_ID);
+ }
+ if( errhdl_l )
+ {
+ errhdl_l->plid(errhdl->plid());
+ errlCommit(errhdl_l,RUNTIME_COMP_ID);
+ }
+
+ // return the summary log
+ break;
+ }
+ } while(0);
+
+ if( errhdl_s ) { delete errhdl_s; }
+ if( errhdl_l ) { delete errhdl_l; }
return errhdl;
}
@@ -842,7 +1120,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
********************/
/**
- * @brief Add the host data mainstore location to VMM
+ * @brief Add the host data mainstore locations to VMM
*/
errlHndl_t load_host_data( void )
{
diff --git a/src/usr/runtime/hdatservice.H b/src/usr/runtime/hdatservice.H
index f5e3bf8ae..049bd881e 100644
--- a/src/usr/runtime/hdatservice.H
+++ b/src/usr/runtime/hdatservice.H
@@ -114,6 +114,16 @@ namespace RUNTIME
uint64_t& o_dataAddr,
size_t& o_dataSize );
+ /**
+ * @brief Locates the proper SPIRA structure and sets instance vars
+ *
+ * Walks the NACA and interrogates structures to determine which
+ * kind of SPIRA is available (if any).
+ *
+ * @return errlHndl_t NULL on success
+ */
+ errlHndl_t findSpira( void );
+
private:
/********************************************
@@ -126,7 +136,22 @@ namespace RUNTIME
*/
void * iv_payload_addr;
void * iv_dumptest_addr;
+ void* iv_hdat_addr;
+
+ /**
+ * Legacy SPIRA
+ */
+ hdatSpira_t* iv_spiraL;
+ /**
+ * SPIRA-H
+ */
+ hdatSpira_t* iv_spiraH;
+
+ /**
+ * SPIRA-S
+ */
+ hdatSpira_t* iv_spiraS;
};
};
diff --git a/src/usr/runtime/hdatstructs.H b/src/usr/runtime/hdatstructs.H
index e1e9be925..db4f27588 100644
--- a/src/usr/runtime/hdatstructs.H
+++ b/src/usr/runtime/hdatstructs.H
@@ -49,10 +49,11 @@ const uint64_t HDAT_NACA_OFFSET = 0x00004000;
*/
struct hdatNaca_t
{
- uint8_t reserved1[48]; // 0x0000 Reserved space
- uint64_t spira; // 0x0030 SPIRA offset
+ uint64_t spiraH; // 0x0000 Spira-H offset (if non-zero)
+ uint8_t reserved1[40]; // 0x0008 Reserved space
+ uint64_t spiraOld; // 0x0030 Legacy SPIRA offset
uint8_t reserved2[104]; // 0x0038 Reserved space
- uint32_t spiraSize; // 0x00A0 Actual SPIRA size in bytes
+ uint32_t spiraSizeOld; // 0x00A0 Actual Legacy 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
@@ -65,46 +66,79 @@ struct hdatNaca_t
} __attribute__ ((packed));
-// Copied from FipS:src/hdat/fsp/hdatspira.H
+// Initially 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().
+ * This enumeration defines the list of N-Tuples within
+ * the LegacySPIRA structure
+ */
+enum hdatSpiraLegacyDataAreas
+{
+ SPIRAL_FIRST = 0,
+ SPIRAL_SP_SUBSYS = 0, // service processor subsystem
+ SPIRAL_IPL_PARMS = 1, // IPL parameters
+ SPIRAL_ENCLOSURE_VPD = 2, // enclosure vital product data
+ SPIRAL_SLCA = 3, // slot location code array
+ SPIRAL_BACKPLANE_VPD = 4, // backplane vital product data
+ SPIRAL_SYS_VPD = 5, // system vital product data
+ SPIRAL_CHIP_TOD = 6, // chip time-of-day
+ SPIRAL_PROC_INIT = 7, // phyp-supplied processor init data
+ SPIRAL_CLOCK_VPD = 8, // clock vital product data
+ SPIRAL_ANCHOR_VPD = 9, // anchor card vital product data
+ SPIRAL_OP_PNL_VPD = 10, // operator panel vital product data
+ SPIRAL_L3_VPD = 11, // level 3 cache vital product data
+ SPIRAL_MISC_CEC_VPD = 12, // miscellaneous FRU vital product data
+ SPIRAL_RSV_1 = 13, // (old PACA)
+ SPIRAL_MDT = 14, // memory description tree
+ SPIRAL_IO_HUB = 15, // I/O hub FRU array
+ SPIRAL_CPU_CTRL = 16, // CPU controls
+ SPIRAL_MS_DUMP_SRC_TBL = 17, // mainstore dump source table
+ SPIRAL_MS_DUMP_DST_TBL = 18, // mainstore dump destination table
+ SPIRAL_MS_DUMP_RSLT_TBL = 19, // mainstore dump results table
+ SPIRAL_HEAP = 20, // Phyp allocated storage location
+ SPIRAL_PCIA = 21, // PCIA (Core information area)
+ SPIRAL_PCRD = 22, // PCRD (Chip related data area)
+ SPIRAL_HSVC_DATA = 23, // Host Services Data
+ SPIRAL_LAST = 24
+};
+
+/** @enum hdatSpiraHDataAreas
+ * This enumeration defines the list of N-Tuples within
+ * the SPIRA-H structure
*/
-enum hdatSpiraDataAreas
+enum hdatSpiraHDataAreas
{
- 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
+ SPIRAH_FIRST = 0,
+ SPIRAH_HOST_DATA_AREAS = 0, // Reserved memory for FSP-filled data
+ SPIRAH_PROC_INIT = 1, // phyp-supplied processor init data
+ SPIRAH_CPU_CTRL = 2, // CPU controls
+ SPIRAH_MS_DUMP_SRC_TBL = 3, // mainstore dump source table
+ SPIRAH_MS_DUMP_DST_TBL = 4, // mainstore dump destination table
+ SPIRAH_MS_DUMP_RSLT_TBL = 5, // mainstore dump results table
+ SPIRAH_LAST = 5
+};
+
+/** @enum hdatSpiraSDataAreas
+ * This enumeration defines the list of N-Tuples within
+ * the SPIRA-S structure
+ */
+enum hdatSpiraSDataAreas
+{
+ SPIRAS_FIRST = 0,
+ SPIRAS_SP_SUBSYS = 0, // service processor subsystem
+ SPIRAS_IPL_PARMS = 1, // IPL parameters
+ SPIRAS_SLCA = 2, // slot location code array
+ SPIRAS_BACKPLANE_VPD = 3, // backplane vital product data
+ SPIRAS_SYS_VPD = 4, // system vital product data
+ SPIRAS_CLOCK_VPD = 5, // clock vital product data
+ SPIRAS_ANCHOR_VPD = 6, // anchor card vital product data
+ SPIRAS_OP_PNL_VPD = 7, // operator panel vital product data
+ SPIRAS_MISC_CEC_VPD = 9, // miscellaneous FRU vital product data
+ SPIRAS_MDT = 10, // memory description tree
+ SPIRAS_IO_HUB = 11, // I/O hub FRU array
+ SPIRAS_PCIA = 12, // PCIA (Core information area)
+ SPIRAS_PCRD = 13, // PCRD (Chip related data area)
+ SPIRAS_HSVC_DATA = 14, // Host Services Data
+ SPIRAS_LAST = 14
};
@@ -177,7 +211,7 @@ struct hdatHDIFDataArray_t
} __attribute__ ((packed));
-// Copied from FipS:src/hdat/fsp/hdatspira.H
+// Originally 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
@@ -188,7 +222,7 @@ struct hdatSpira_t
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
+ hdat5Tuple_t hdatDataArea[SPIRAL_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.
diff --git a/src/usr/runtime/makefile b/src/usr/runtime/makefile
index 7f3e5d495..f8d69af3c 100644
--- a/src/usr/runtime/makefile
+++ b/src/usr/runtime/makefile
@@ -31,7 +31,8 @@ ROOTPATH = ../../..
MODULE = runtime
-OBJS = populate_attributes.o hdatservice.o fakepayload.o tce.o
+OBJS = populate_attributes.o hdatservice.o fakepayload.o tce.o \
+ errlud_hdat.o
SUBDIRS = test.d
diff --git a/src/usr/runtime/plugins/RUNTIME_COMP_ID_Parse.C b/src/usr/runtime/plugins/RUNTIME_COMP_ID_Parse.C
new file mode 100644
index 000000000..bc4735aec
--- /dev/null
+++ b/src/usr/runtime/plugins/RUNTIME_COMP_ID_Parse.C
@@ -0,0 +1,27 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/plugins/RUNTIME_COMP_ID_Parse.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* 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 "errludparser.H"
+#include "runtimeUdParserFactory.H"
+
+ERRL_MAKE_UD_PARSER(RUNTIME::UserDetailsParserFactory, hbfw::RUNTIME_COMP_ID)
+
diff --git a/src/usr/runtime/plugins/errludP_hdat.H b/src/usr/runtime/plugins/errludP_hdat.H
new file mode 100644
index 000000000..0bae7a70a
--- /dev/null
+++ b/src/usr/runtime/plugins/errludP_hdat.H
@@ -0,0 +1,294 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/plugins/errludP_hdat.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* 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 ERRL_UDP_NACA_H
+#define ERRL_UDP_NACA_H
+
+/**
+ * @file errludstring.H
+ *
+ * Defines the ErrlUserDetailsParserString class that parser string FFDC
+ * user detail in an error log
+ */
+
+#include "errluserdetails.H"
+#include <string.h>
+
+/**
+ * Some macros to manipulate data types cleanly
+ */
+#define TO_UINT8(ptr) (*(reinterpret_cast<uint8_t*>(ptr)))
+#define TO_UINT16(ptr) (ntohs(*(reinterpret_cast<uint16_t*>(ptr))))
+#define TO_UINT32(ptr) (ntohl(*(reinterpret_cast<uint32_t*>(ptr))))
+#define TO_UINT64(ptr) (ntohll(*(reinterpret_cast<uint64_t*>(ptr))))
+
+namespace RUNTIME
+{
+
+/**
+ * @class UdParserNaca
+ *
+ * Parses NACA user detail in an error log
+ */
+class UdParserNaca : public ERRORLOG::ErrlUserDetailsParser
+{
+public:
+ /**
+ * @brief Constructor
+ */
+ UdParserNaca() {}
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdParserNaca() {}
+
+ /**
+ * @brief Parses string user detail data from an error log
+ *
+ * @param i_version Version of the data
+ * @param i_parse ErrlUsrParser object for outputting information
+ * @param i_pBuffer Pointer to buffer containing detail data
+ * @param i_buflen Length of the buffer
+ */
+ virtual void parse(errlver_t i_version,
+ ErrlUsrParser & i_parser,
+ void * i_pBuffer,
+ const uint32_t i_buflen) const
+ {
+ i_parser.PrintHeading("NACA");
+ i_parser.PrintBlank();
+
+ // Dump the whole thing first
+ i_parser.PrintHexDump(i_pBuffer,i_buflen);
+ i_parser.PrintBlank();
+
+ char* tmp = NULL;
+ // 0x0000 Spira-H offset (if non-zero)
+ if( i_buflen >= 8 )
+ {
+ tmp = static_cast<char *>(i_pBuffer) + 0x0000;
+ i_parser.PrintNumber("SPIRA-H","%.16llX",TO_UINT64(tmp));
+ }
+ // 0x0030 Legacy SPIRA offset
+ if( i_buflen >= 0x0038 )
+ {
+ tmp = static_cast<char *>(i_pBuffer) + 0x0030;
+ i_parser.PrintNumber("Legacy Spira","%.16llX",TO_UINT64(tmp));
+ }
+ // 0x00A0 Actual Legacy SPIRA size in bytes
+ if( i_buflen >= 0x00A4 )
+ {
+ tmp = static_cast<char *>(i_pBuffer) + 0x00A0;
+ i_parser.PrintNumber("Legacy SPIRA size","%.8X",TO_UINT32(tmp));
+ }
+ // 0x01B7 PHYP supports PCIA format
+ if( i_buflen >= 0x01B8 )
+ {
+ tmp = static_cast<char *>(i_pBuffer) + 0x01B7;
+ i_parser.PrintNumber("Legacy Spira","%.16llX",TO_UINT8(tmp));
+ }
+ }
+
+private:
+ // Disabled
+ UdParserNaca(const UdParserNaca&);
+ UdParserNaca & operator=(const UdParserNaca&);
+};
+
+/**
+ * @class UdParserTuple
+ *
+ * Parses Tuple user detail in an error log
+ */
+class UdParserTuple : public ERRORLOG::ErrlUserDetailsParser
+{
+public:
+ /**
+ * @brief Constructor
+ */
+ UdParserTuple() {}
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdParserTuple() {}
+
+ /**
+ * @brief Helper function to do parsing
+ *
+ * @param i_parser ErrlUsrParser object for outputting information
+ * @param i_pBuffer Pointer to buffer containing detail data
+ */
+ static void parse( ErrlUsrParser & i_parser,
+ void * i_pBuffer )
+ {
+ char* tmp = NULL;
+
+ // 0x0000 Absolute address to a structure
+ tmp = static_cast<char *>(i_pBuffer) + 0x0000;
+ i_parser.PrintNumber("Address","%.16llX",TO_UINT64(tmp));
+
+ // 0x0008 Allocated count
+ tmp = static_cast<char *>(i_pBuffer) + 0x0008;
+ i_parser.PrintNumber("Allocated Count","%.4X",TO_UINT16(tmp));
+
+ // 0x000A Actual count
+ tmp = static_cast<char *>(i_pBuffer) + 0x000A;
+ i_parser.PrintNumber("Actual Count","%.4X",TO_UINT16(tmp));
+
+ // 0x000C Allocated size in bytes
+ tmp = static_cast<char *>(i_pBuffer) + 0x000C;
+ i_parser.PrintNumber("Allocated Size","%.8X",TO_UINT32(tmp));
+
+ // 0x0010 Actual size in bytes
+ tmp = static_cast<char *>(i_pBuffer) + 0x0010;
+ i_parser.PrintNumber("Actual Size","%.8X",TO_UINT32(tmp));
+
+ }
+
+ /**
+ * @brief Parses string user detail data from an error log
+ *
+ * @param i_version Version of the data
+ * @param i_parser ErrlUsrParser object for outputting information
+ * @param i_pBuffer Pointer to buffer containing detail data
+ * @param i_buflen Length of the buffer
+ */
+ virtual void parse(errlver_t i_version,
+ ErrlUsrParser & i_parser,
+ void * i_pBuffer,
+ const uint32_t i_buflen) const
+ {
+ i_parser.PrintHeading("Tuple");
+ i_parser.PrintBlank();
+
+ // Dump the whole thing first
+ i_parser.PrintHexDump(i_pBuffer,i_buflen);
+ i_parser.PrintBlank();
+
+ if( i_buflen >= 0x0020 )
+ {
+ UdParserTuple::parse( i_parser, i_pBuffer );
+ }
+ }
+
+private:
+ // Disabled
+ UdParserTuple(const UdParserTuple&);
+ UdParserTuple & operator=(const UdParserTuple &);
+};
+
+/**
+ * @class UdParserSpira
+ *
+ * Parses SPIRA user detail in an error log
+ */
+class UdParserSpira : public ERRORLOG::ErrlUserDetailsParser
+{
+public:
+ /**
+ * @brief Constructor
+ */
+ UdParserSpira() {}
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdParserSpira() {}
+
+ /**
+ * @brief Parses string user detail data from an error log
+ *
+ * @param i_version Version of the data
+ * @param i_parse ErrlUsrParser object for outputting information
+ * @param i_pBuffer Pointer to buffer containing detail data
+ * @param i_buflen Length of the buffer
+ */
+ virtual void parse(errlver_t i_version,
+ ErrlUsrParser & i_parser,
+ void * i_pBuffer,
+ const uint32_t i_buflen) const
+ {
+ i_parser.PrintHeading("SPIRA");
+ i_parser.PrintBlank();
+
+ // Dump the whole thing first
+ i_parser.PrintHexDump(i_pBuffer,i_buflen);
+ i_parser.PrintBlank();
+
+ char* tmp = NULL;
+ //** 0x0000 Common HDIF header
+ // 0x0002 Structure eye catcher
+ if( i_buflen >= 0x0008 )
+ {
+ tmp = static_cast<char *>(i_pBuffer) + 0x0002;
+ char tmp1[7];
+ tmp1[6] = '\0';
+ memcpy( tmp1, tmp, 6 );
+ i_parser.PrintString("Eyecatcher",tmp1);
+ }
+ // 0x000A Structure version
+ if( i_buflen >= 0x000C )
+ {
+ tmp = static_cast<char *>(i_pBuffer) + 0x000A;
+ i_parser.PrintNumber("Version","%.8X",TO_UINT32(tmp));
+ }
+
+ //** 0x0030 Info on 5-tuple array
+ // 0x0004 Number of array entries
+ uint32_t num_tuples = 0;
+ if( i_buflen >= 0x0038 )
+ {
+ tmp = static_cast<char *>(i_pBuffer) + 0x0034;
+ num_tuples = TO_UINT32(tmp);
+ i_parser.PrintNumber("Num Tuples","%.8X",num_tuples);
+ }
+
+ //** 0x0040 5-tuple arrays
+ for( uint32_t tuple = 0;
+ tuple < num_tuples;
+ tuple++ )
+ {
+ i_parser.PrintNumber(" Tuple#","%d",tuple);
+ void* tuple_ptr = static_cast<char *>(i_pBuffer)
+ + 0x0040 + (tuple * 0x20);
+ if( i_buflen < (0x0040 + (tuple * 0x20)) )
+ {
+ break;
+ }
+
+ UdParserTuple::parse( i_parser, tuple_ptr );
+ }
+ }
+
+private:
+ // Disabled
+ UdParserSpira(const UdParserSpira&);
+ UdParserSpira & operator=(const UdParserSpira&);
+};
+
+
+}
+
+#endif
+
diff --git a/src/usr/runtime/plugins/runtimeUdParserFactory.H b/src/usr/runtime/plugins/runtimeUdParserFactory.H
new file mode 100644
index 000000000..0ee0283f1
--- /dev/null
+++ b/src/usr/runtime/plugins/runtimeUdParserFactory.H
@@ -0,0 +1,55 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/plugins/runtimeUdParserFactory.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* 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 */
+#if !defined(_RUNTIMEUDPARSERFACTORY_H)
+#define _RUNTIMEUDPARSERFACTORY_H
+
+#include "errludparserfactory.H"
+#include "errludP_hdat.H"
+
+namespace RUNTIME
+{
+ class UserDetailsParserFactory
+ : public ERRORLOG::ErrlUserDetailsParserFactory
+ {
+ public:
+ UserDetailsParserFactory()
+ {
+ registerParser<RUNTIME::UdParserNaca>
+ (RUNTIME_UDT_NACA);
+ registerParser<RUNTIME::UdParserSpira>
+ (RUNTIME_UDT_SPIRA);
+ registerParser<RUNTIME::UdParserTuple>
+ (RUNTIME_UDT_TUPLE);
+ }
+
+ private:
+
+ UserDetailsParserFactory(const UserDetailsParserFactory &);
+ UserDetailsParserFactory & operator=
+ (const UserDetailsParserFactory &);
+ };
+};
+
+#endif
+
+
diff --git a/src/usr/runtime/test/hdatservicetest.H b/src/usr/runtime/test/hdatservicetest.H
index 3b59651f0..5d860f69a 100644
--- a/src/usr/runtime/test/hdatservicetest.H
+++ b/src/usr/runtime/test/hdatservicetest.H
@@ -36,6 +36,19 @@
#include <targeting/common/commontargeting.H>
#include <attributeenums.H>
#include "../hdatstructs.H"
+#include "../errlud_hdat.H"
+#include <runtime/runtime_reasoncodes.H>
+
+/*
+ * To test with a custom HDAT do the following:
+ * #define REAL_HDAT_TEST in hdatservicetest.H
+ * #define REAL_HDAT_TEST in hdatservice.C
+ * When MAGIC_BREAK hits run this in simics:
+ * system_cmp0.phys_mem.load-file hdat.bin 0x10000000
+ *
+ * Note that there will be DumpTest failures.
+ */
+//#define REAL_HDAT_TEST
extern trace_desc_t* g_trac_runtime;
@@ -54,6 +67,10 @@ class HdatServiceTest: public CxxTest::TestSuite
TARGETING::ATTR_PAYLOAD_KIND_type payload_kind =
sys->getAttr<TARGETING::ATTR_PAYLOAD_KIND>();
+#ifdef REAL_HDAT_TEST
+ payload_kind = TARGETING::PAYLOAD_KIND_PHYP;
+#endif
+
// Verify something in the system parms
uint64_t sys_parms_addr = 0;
size_t sys_parms_size = 0;
@@ -304,6 +321,108 @@ class HdatServiceTest: public CxxTest::TestSuite
TRACFCOMP( g_trac_runtime, "testHdat> finish" );
}
+ void testSpira( void )
+ {
+#ifdef REAL_HDAT_TEST
+ TRACFCOMP( g_trac_runtime, "testSpira> start" );
+ errlHndl_t errhdl = NULL;
+
+ uint64_t naca_addr = 0;
+ size_t naca_size = 0;
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::NACA,
+ 0,
+ naca_addr,
+ naca_size );
+ if( errhdl )
+ {
+ TS_FAIL("testSpira> Error trying to locate NACA");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( naca_addr == 0 )
+ {
+ TS_FAIL("testSpira> NULL returned for get_host_data_section(NACA)");
+ }
+ else if( (naca_size == 0)
+ || (naca_size == RUNTIME::DATA_SIZE_UNKNOWN) )
+ {
+ TS_FAIL("testSpira> Size of NACA data too small");
+ }
+
+
+ uint64_t spiral_addr = 0;
+ size_t spiral_size = 0;
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::SPIRA_L,
+ 0,
+ spiral_addr,
+ spiral_size );
+ if( errhdl )
+ {
+ TS_FAIL("testSpira> Error trying to locate SPIRA_L");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( spiral_addr == 0 )
+ {
+ TS_FAIL("testSpira> NULL returned for get_host_data_section(SPIRA_L)");
+ }
+ else if( (spiral_size == 0)
+ || (spiral_size == RUNTIME::DATA_SIZE_UNKNOWN) )
+ {
+ TS_FAIL("testSpira> Size of SPIRA_L data too small");
+ }
+
+
+ uint64_t spiras_addr = 0;
+ size_t spiras_size = 0;
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::SPIRA_S,
+ 0,
+ spiras_addr,
+ spiras_size );
+ if( errhdl )
+ {
+ TS_FAIL("testSpira> Error trying to locate SPIRA_S");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( spiras_addr == 0 )
+ {
+ TS_FAIL("testSpira> NULL returned for get_host_data_section(SPIRA_S)");
+ }
+ else if( (spiras_size == 0)
+ || (spiras_size == RUNTIME::DATA_SIZE_UNKNOWN) )
+ {
+ TS_FAIL("testSpira> Size of SPIRA-S data too small");
+ }
+
+
+ uint64_t spirah_addr = 0;
+ size_t spirah_size = 0;
+ errhdl = RUNTIME::get_host_data_section(
+ RUNTIME::SPIRA_H,
+ 0,
+ spirah_addr,
+ spirah_size );
+ if( errhdl )
+ {
+ TS_FAIL("testSpira> Error trying to locate SPIRA_H");
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+ }
+ else if( spirah_addr == 0 )
+ {
+ TS_FAIL("testSpira> NULL returned for get_host_data_section(SPIRA_H)");
+ }
+ else if( (spirah_size == 0)
+ || (spirah_size == RUNTIME::DATA_SIZE_UNKNOWN) )
+ {
+ TS_FAIL("testSpira> Size of SPIRA_H data too small");
+ }
+
+
+ TRACFCOMP( g_trac_runtime, "testSpira> finish" );
+#endif
+ }
+
};
diff --git a/src/usr/runtime/test/makefile b/src/usr/runtime/test/makefile
index 2f5472dc4..4ec29e5ca 100644
--- a/src/usr/runtime/test/makefile
+++ b/src/usr/runtime/test/makefile
@@ -25,8 +25,7 @@ ROOTPATH = ../../../..
MODULE = testruntime
TESTS = *.H
-#@fixme - remove this after testing
-## support for fapi
+# support for fapi
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat
OpenPOWER on IntegriCloud