From 12ff45d42b4fa04bdbf36ed36147b5c07e36939f Mon Sep 17 00:00:00 2001 From: Dan Crowell Date: Tue, 16 Jul 2013 11:13:11 -0500 Subject: Support SPIRA-H HDAT Format Change-Id: If87eedf15c1ef96ea00c1a5574ad1f6b72e697b5 RTC: 71881 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5498 Reviewed-by: Michael Baiocchi Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert Reviewed-by: A. Patrick Williams III --- src/usr/runtime/errlud_hdat.C | 119 +++++++ src/usr/runtime/errlud_hdat.H | 127 +++++++ src/usr/runtime/hdatservice.C | 408 +++++++++++++++++++---- src/usr/runtime/hdatservice.H | 25 ++ src/usr/runtime/hdatstructs.H | 118 ++++--- src/usr/runtime/makefile | 3 +- src/usr/runtime/plugins/RUNTIME_COMP_ID_Parse.C | 27 ++ src/usr/runtime/plugins/errludP_hdat.H | 294 ++++++++++++++++ src/usr/runtime/plugins/runtimeUdParserFactory.H | 55 +++ src/usr/runtime/test/hdatservicetest.H | 119 +++++++ src/usr/runtime/test/makefile | 3 +- 11 files changed, 1188 insertions(+), 110 deletions(-) create mode 100644 src/usr/runtime/errlud_hdat.C create mode 100644 src/usr/runtime/errlud_hdat.H create mode 100644 src/usr/runtime/plugins/RUNTIME_COMP_ID_Parse.C create mode 100644 src/usr/runtime/plugins/errludP_hdat.H create mode 100644 src/usr/runtime/plugins/runtimeUdParserFactory.H (limited to 'src/usr/runtime') 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 +#include +#include "hdatstructs.H" +#include + +namespace RUNTIME +{ + +//------------------------------------------------------------------------------ +// NACA +//------------------------------------------------------------------------------ +UdNaca::UdNaca(hdatNaca_t* i_naca) +{ + if( 0 == mm_virt_to_phys(reinterpret_cast(i_naca)) ) + { + return; + } + + char * l_pBuf = reinterpret_cast( + 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(i_spira)) ) + { + return; + } + + char * l_pBuf = reinterpret_cast( + 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(i_tuple)) ) + { + return; + } + + char * l_pBuf = reinterpret_cast( + 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 +#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 #include "hdatservice.H" +#include "errlud_hdat.H" +#include 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(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(); +#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(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 - (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(naca), - TWO_UINT32_TO_UINT64(payload_base, - payload_kind)); - errhdl->collectTrace("RUNTIME",1024); - //@todo-log NACA data - break; + o_dataAddr = reinterpret_cast(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 - (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(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(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(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(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 @@ -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(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 + (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(); + + /*@ + * @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(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 + (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 + (&(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(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 + (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 + (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 + +/** + * Some macros to manipulate data types cleanly + */ +#define TO_UINT8(ptr) (*(reinterpret_cast(ptr))) +#define TO_UINT16(ptr) (ntohs(*(reinterpret_cast(ptr)))) +#define TO_UINT32(ptr) (ntohl(*(reinterpret_cast(ptr)))) +#define TO_UINT64(ptr) (ntohll(*(reinterpret_cast(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(i_pBuffer) + 0x0000; + i_parser.PrintNumber("SPIRA-H","%.16llX",TO_UINT64(tmp)); + } + // 0x0030 Legacy SPIRA offset + if( i_buflen >= 0x0038 ) + { + tmp = static_cast(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(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(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(i_pBuffer) + 0x0000; + i_parser.PrintNumber("Address","%.16llX",TO_UINT64(tmp)); + + // 0x0008 Allocated count + tmp = static_cast(i_pBuffer) + 0x0008; + i_parser.PrintNumber("Allocated Count","%.4X",TO_UINT16(tmp)); + + // 0x000A Actual count + tmp = static_cast(i_pBuffer) + 0x000A; + i_parser.PrintNumber("Actual Count","%.4X",TO_UINT16(tmp)); + + // 0x000C Allocated size in bytes + tmp = static_cast(i_pBuffer) + 0x000C; + i_parser.PrintNumber("Allocated Size","%.8X",TO_UINT32(tmp)); + + // 0x0010 Actual size in bytes + tmp = static_cast(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(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(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(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(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_UDT_NACA); + registerParser + (RUNTIME_UDT_SPIRA); + registerParser + (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 #include #include "../hdatstructs.H" +#include "../errlud_hdat.H" +#include + +/* + * 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(); +#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 -- cgit v1.2.1