summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2013-08-19 08:56:23 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-09-13 17:38:38 -0500
commit5d8dd9af9d7a4df742ebbd8cdf20c58a8e95b05f (patch)
tree6c8e663be551562a7835d4f554a13e5afe7e317a /src
parent45f3421a82460ed2ce5dd86d3bb62209ac9d948e (diff)
downloadtalos-hostboot-5d8dd9af9d7a4df742ebbd8cdf20c58a8e95b05f.tar.gz
talos-hostboot-5d8dd9af9d7a4df742ebbd8cdf20c58a8e95b05f.zip
Catch overrun of HSVC attributes in HDAT
Ran into a problem integrating a new HB release that would have been a lot easier to debug if this code had been there. Change-Id: I3c420172bcff25a7042d3ee603f179273ba88761 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5827 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/runtime/runtime.H11
-rw-r--r--src/include/usr/runtime/runtime_reasoncodes.H4
-rw-r--r--src/include/usr/vmmconst.h7
-rw-r--r--src/usr/runtime/errlud_hdat.C87
-rw-r--r--src/usr/runtime/hdatservice.C128
-rw-r--r--src/usr/runtime/hdatservice.H12
-rw-r--r--src/usr/runtime/plugins/errludP_hdat.H107
-rw-r--r--src/usr/runtime/populate_attributes.C67
-rw-r--r--src/usr/runtime/test/hdatservicetest.H13
9 files changed, 378 insertions, 58 deletions
diff --git a/src/include/usr/runtime/runtime.H b/src/include/usr/runtime/runtime.H
index 0536d2c63..d98e1451e 100644
--- a/src/include/usr/runtime/runtime.H
+++ b/src/include/usr/runtime/runtime.H
@@ -124,6 +124,17 @@ void update_MDRT_Count(uint16_t i_count);
*/
errlHndl_t write_MDRT_Count(void);
+/*
+ * @brief Retrieve and log FFDC data relevant to a given section of
+ * host data memory
+ *
+ * @param[in] i_section Relevant section
+ * @param[inout] io_errlog Log to append FFDC to
+ *
+ * @return errlHndl_t NULL on success
+ */
+void add_host_data_ffdc( SectionId i_section,
+ errlHndl_t& io_errlog );
}
diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H
index 3c888abf1..4f3a37af2 100644
--- a/src/include/usr/runtime/runtime_reasoncodes.H
+++ b/src/include/usr/runtime/runtime_reasoncodes.H
@@ -46,6 +46,7 @@ namespace RUNTIME
MOD_TCE_MAP = 0x0E, /**< tce.C */
MOD_HDATSERVICE_FINDSPIRA = 0x0F, /** hdatservice.C */
MOD_HDATSERVICE_UPDATE_SECTION_ACTUAL = 0x10, /**< hdatservice.C */
+ MOD_HDATSERVICE_MAPREGION = 0x11, /**< hdatservice.C */
};
enum RuntimeReasonCode
@@ -56,7 +57,7 @@ namespace RUNTIME
RC_BAD_HDAT_TUPLE = RUNTIME_COMP_ID | 0x03,
RC_INVALID_STANDALONE = RUNTIME_COMP_ID | 0x04,
RC_CANNOT_MAP_MEMORY = RUNTIME_COMP_ID | 0x05,
- RC_WRONG_PAYLOAD_ATTRS = RUNTIME_COMP_ID | 0x06,
+ //RC_XXX = RUNTIME_COMP_ID | 0x06,
RC_CANNOT_MAP_MEMORY2 = RUNTIME_COMP_ID | 0x07,
RC_INVALID_PAYLOAD_KIND = RUNTIME_COMP_ID | 0x08,
RC_NO_HSVC_NODE_DATA_FOUND = RUNTIME_COMP_ID | 0x09,
@@ -74,6 +75,7 @@ namespace RUNTIME
RC_TCE_ENTRY_NOT_CONTIGUOUS = RUNTIME_COMP_ID | 0x15,
RC_NO_SPIRA = RUNTIME_COMP_ID | 0x16,
RC_CANNOT_MAP_HDAT = RUNTIME_COMP_ID | 0x17,
+ RC_NOT_ENOUGH_SPACE = RUNTIME_COMP_ID | 0x18,
};
enum UserDetailsTypes
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index 6190e719e..fbb787ea1 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -146,8 +146,11 @@ enum BlockPriority
#define VMM_SIZE_RMVPAGE_TEST (8 * PAGESIZE)
/** Chunk of physical memory to use for HostServices Attributes */
-#define HSVC_TEST_MEMORY_ADDR (VMM_MEMORY_SIZE + 32*MEGABYTE)
-#define HSVC_TEST_MEMORY_SIZE (2*MEGABYTE)
+#define HSVC_TEST_MEMORY_ADDR (VMM_MEMORY_SIZE + 32*MEGABYTE)
+#define HSVC_TEST_SYSDATA_SIZE (4*KILOBYTE) /* match FSP HDAT code */
+#define HSVC_TEST_NODEDATA_SIZE (256000) /* match FSP HDAT code */
+#define HSVC_TEST_MEMORY_SIZE \
+ ALIGN_PAGE((HSVC_TEST_SYSDATA_SIZE+HSVC_TEST_NODEDATA_SIZE))
/* Chunk of physical memory used for Dump Source Table */
#define DUMP_TEST_MEMORY_ADDR (HSVC_TEST_MEMORY_ADDR + HSVC_TEST_MEMORY_SIZE)
diff --git a/src/usr/runtime/errlud_hdat.C b/src/usr/runtime/errlud_hdat.C
index 72d024f0e..3fe926c48 100644
--- a/src/usr/runtime/errlud_hdat.C
+++ b/src/usr/runtime/errlud_hdat.C
@@ -39,19 +39,34 @@ namespace RUNTIME
//------------------------------------------------------------------------------
UdNaca::UdNaca(hdatNaca_t* i_naca)
{
- if( 0 == mm_virt_to_phys(reinterpret_cast<void*>(i_naca)) )
+ // Set up Ud instance variables
+ iv_CompId = RUNTIME_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = RUNTIME_UDT_NACA;
+
+ //***** Memory Layout *****
+ // 8 bytes : Physical Address
+ // 8 bytes : Virtual Address
+ // XX bytes : NACA data
+
+ uint64_t phys_addr = mm_virt_to_phys(reinterpret_cast<void*>(i_naca));
+ if( 0 == phys_addr )
{
+ uint64_t* l_pBuf64 = reinterpret_cast<uint64_t *>(
+ reallocUsrBuf(sizeof(uint64_t)*2));
+ l_pBuf64[0] = phys_addr;
+ l_pBuf64[1] = 0;
return;
}
char * l_pBuf = reinterpret_cast<char *>(
- reallocUsrBuf(sizeof(hdatNaca_t)));
+ reallocUsrBuf(sizeof(hdatNaca_t)
+ +sizeof(uint64_t)*2));
+ memcpy(l_pBuf, &phys_addr, sizeof(uint64_t));
+ l_pBuf += sizeof(uint64_t);
+ memcpy(l_pBuf, &i_naca, sizeof(uint64_t));
+ l_pBuf += sizeof(uint64_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;
}
//------------------------------------------------------------------------------
@@ -66,19 +81,34 @@ UdNaca::~UdNaca()
//------------------------------------------------------------------------------
UdSpira::UdSpira(hdatSpira_t* i_spira)
{
- if( 0 == mm_virt_to_phys(reinterpret_cast<void*>(i_spira)) )
+ // Set up Ud instance variables
+ iv_CompId = RUNTIME_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = RUNTIME_UDT_SPIRA;
+
+ //***** Memory Layout *****
+ // 8 bytes : Physical Address
+ // 8 bytes : Virtual Address
+ // XX bytes : SPIRA data
+
+ uint64_t phys_addr = mm_virt_to_phys(reinterpret_cast<void*>(i_spira));
+ if( 0 == phys_addr )
{
+ uint64_t* l_pBuf64 = reinterpret_cast<uint64_t *>(
+ reallocUsrBuf(sizeof(uint64_t)*2));
+ l_pBuf64[0] = phys_addr;
+ l_pBuf64[1] = 0;
return;
}
char * l_pBuf = reinterpret_cast<char *>(
- reallocUsrBuf(sizeof(hdatSpira_t)));
+ reallocUsrBuf(sizeof(hdatSpira_t)
+ +sizeof(uint64_t)*2));
+ memcpy(l_pBuf, &phys_addr, sizeof(uint64_t));
+ l_pBuf += sizeof(uint64_t);
+ memcpy(l_pBuf, &i_spira, sizeof(uint64_t));
+ l_pBuf += sizeof(uint64_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;
}
//------------------------------------------------------------------------------
@@ -93,19 +123,34 @@ UdSpira::~UdSpira()
//------------------------------------------------------------------------------
UdTuple::UdTuple(hdat5Tuple_t* i_tuple)
{
- if( 0 == mm_virt_to_phys(reinterpret_cast<void*>(i_tuple)) )
+ // Set up Ud instance variables
+ iv_CompId = RUNTIME_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = RUNTIME_UDT_TUPLE;
+
+ //***** Memory Layout *****
+ // 8 bytes : Physical Address
+ // 8 bytes : Virtual Address
+ // XX bytes : Tuple data
+
+ uint64_t phys_addr = mm_virt_to_phys(reinterpret_cast<void*>(i_tuple));
+ if( 0 == phys_addr )
{
+ uint64_t* l_pBuf64 = reinterpret_cast<uint64_t *>(
+ reallocUsrBuf(sizeof(uint64_t)*2));
+ l_pBuf64[0] = phys_addr;
+ l_pBuf64[1] = 0;
return;
}
char * l_pBuf = reinterpret_cast<char *>(
- reallocUsrBuf(sizeof(hdat5Tuple_t)));
+ reallocUsrBuf(sizeof(hdat5Tuple_t)
+ +sizeof(uint64_t)*2));
+ memcpy(l_pBuf, &phys_addr, sizeof(uint64_t));
+ l_pBuf += sizeof(uint64_t);
+ memcpy(l_pBuf, &i_tuple, sizeof(uint64_t));
+ l_pBuf += sizeof(uint64_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;
}
//------------------------------------------------------------------------------
diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C
index f6d70d19b..be8b912fd 100644
--- a/src/usr/runtime/hdatservice.C
+++ b/src/usr/runtime/hdatservice.C
@@ -37,6 +37,8 @@
#include "errlud_hdat.H"
#include <errl/errlmanager.H>
+//#define REAL_HDAT_TEST
+
extern trace_desc_t* g_trac_runtime;
#define TRACUCOMP TRACDCOMP
@@ -99,7 +101,7 @@ errlHndl_t hdatService::verify_hdat_address( void* i_addr,
+ i_size;
// Make sure that the entire range is within the memory
- // space that we mapped
+ // space that we allocated
for(memRegionItr region = iv_mem_regions.begin();
(region != iv_mem_regions.end()) && !found; ++region)
{
@@ -140,6 +142,13 @@ errlHndl_t hdatService::verify_hdat_address( void* i_addr,
reinterpret_cast<uint64_t>(i_addr),
reinterpret_cast<uint64_t>(i_size));
errhdl->collectTrace("RUNTIME",1024);
+
+ // most likely this is a HB code bug
+ errhdl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ // but it could also be a FSP bug in setting up the HDAT data
+ errhdl->addProcedureCallout(HWAS::EPUB_PRC_SP_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
}
return errhdl;
@@ -248,13 +257,13 @@ errlHndl_t hdatService::get_standalone_section(
if( RUNTIME::HSVC_SYSTEM_DATA == i_section )
{
o_dataAddr = reinterpret_cast<uint64_t>(iv_mem_regions[0].virt_addr);
- o_dataSize = 512*KILOBYTE;
+ o_dataSize = HSVC_TEST_SYSDATA_SIZE;
}
else if( RUNTIME::HSVC_NODE_DATA == i_section )
{
o_dataAddr = reinterpret_cast<uint64_t>(iv_mem_regions[0].virt_addr)
- + 512*KILOBYTE;
- o_dataSize = HSVC_TEST_MEMORY_SIZE - 512*KILOBYTE;
+ + HSVC_TEST_SYSDATA_SIZE;
+ o_dataSize = HSVC_TEST_NODEDATA_SIZE;
}
else if( RUNTIME::MS_DUMP_SRC_TBL == i_section )
{
@@ -341,7 +350,7 @@ errlHndl_t hdatService::mapRegion(uint64_t i_addr, size_t i_bytes,
l_mem.virt_addr );
/*@
* @errortype
- * @moduleid RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA
+ * @moduleid RUNTIME::MOD_HDATSERVICE_MAPREGION
* @reasoncode RUNTIME::RC_CANNOT_MAP_MEMORY
* @userdata1 Starting Address
* @userdata2 Size
@@ -349,7 +358,7 @@ errlHndl_t hdatService::mapRegion(uint64_t i_addr, size_t i_bytes,
*/
errhdl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA,
+ RUNTIME::MOD_HDATSERVICE_MAPREGION,
RUNTIME::RC_CANNOT_MAP_MEMORY,
l_mem.phys_addr,
l_mem.size );
@@ -785,6 +794,10 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
if( !foundit )
{
TRACFCOMP( g_trac_runtime, "getHostDataSection> HSVC_NODE_DATA instance %d of section %d is unallocated", i_instance, i_section );
+ // Go get the physical address we mapped in
+ uint64_t phys_addr =
+ mm_virt_to_phys(reinterpret_cast<void*>(node_data_headers));
+
/*@
* @errortype
* @moduleid RUNTIME::MOD_HDATSERVICE_GETHOSTDATASECTION
@@ -799,7 +812,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
RUNTIME::MOD_HDATSERVICE_GETHOSTDATASECTION,
RUNTIME::RC_NO_HSVC_NODE_DATA_FOUND,
- reinterpret_cast<uint64_t>(node_data_headers),
+ phys_addr,
TWO_UINT32_TO_UINT64(i_instance,
found_instances));
errhdl->collectTrace("RUNTIME",1024);
@@ -1007,6 +1020,10 @@ errlHndl_t hdatService::findSpira( void )
TARGETING::ATTR_PAYLOAD_KIND_type payload_kind
= sys->getAttr<TARGETING::ATTR_PAYLOAD_KIND>();
+ // Go get the physical address we mapped in
+ uint64_t phys_addr =
+ mm_virt_to_phys(reinterpret_cast<void*>(naca));
+
/*@
* @errortype
* @moduleid RUNTIME::MOD_HDATSERVICE_FINDSPIRA
@@ -1020,7 +1037,7 @@ errlHndl_t hdatService::findSpira( void )
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
RUNTIME::MOD_HDATSERVICE_FINDSPIRA,
RUNTIME::RC_BAD_NACA,
- reinterpret_cast<uint64_t>(naca),
+ reinterpret_cast<uint64_t>(phys_addr),
TWO_UINT32_TO_UINT64(payload_base,
payload_kind));
errhdl->collectTrace("RUNTIME",1024);
@@ -1266,6 +1283,90 @@ errlHndl_t hdatService::updateHostDataSectionActual( SectionId i_section,
return errhdl;
}
+/**
+ * @brief Retrieve and log FFDC data relevant to a given section of
+ * host data memory
+ */
+void hdatService::addFFDC( SectionId i_section,
+ errlHndl_t& io_errlog )
+{
+ uint64_t addr = 0;
+ uint64_t size = 0;
+ errlHndl_t errlog = NULL;
+
+ if( RUNTIME::NACA == i_section )
+ {
+ errlog = getHostDataSection( NACA, 0, addr, size );
+ if( errlog )
+ {
+ delete errlog;
+ }
+ else if( (addr != 0) && (size != 0) )
+ {
+ hdatNaca_t* naca = reinterpret_cast<hdatNaca_t*>(addr);
+ RUNTIME::UdNaca(naca).addToLog(io_errlog);
+ }
+ return;
+ }
+ else if( (RUNTIME::SPIRA_L == i_section)
+ || (RUNTIME::SPIRA_S == i_section)
+ || (RUNTIME::SPIRA_H == i_section) )
+ {
+ // grab the NACA first
+ addFFDC( NACA, io_errlog );
+
+ errlog = getHostDataSection( i_section, 0, addr, size );
+ if( errlog )
+ {
+ delete errlog;
+ }
+ else if( (addr != 0) && (size != 0) )
+ {
+ hdatSpira_t* spira = reinterpret_cast<hdatSpira_t*>(addr);
+ RUNTIME::UdSpira(spira).addToLog(io_errlog);
+ }
+ return;
+ }
+ else if( RUNTIME::HSVC_SYSTEM_DATA == i_section )
+ {
+ // grab the SPIRA data
+ if( iv_spiraL) { addFFDC( SPIRA_L, io_errlog ); }
+ if( iv_spiraH) { addFFDC( SPIRA_H, io_errlog ); }
+ if( iv_spiraS) { addFFDC( SPIRA_S, io_errlog ); }
+
+ // grab the Tuple it is part of
+ 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]);
+ }
+ if( tuple ) { RUNTIME::UdTuple(tuple).addToLog(io_errlog); }
+ }
+ else if( RUNTIME::HSVC_NODE_DATA == i_section )
+ {
+ // grab the SPIRA data
+ if( iv_spiraL) { addFFDC( SPIRA_L, io_errlog ); }
+ if( iv_spiraH) { addFFDC( SPIRA_H, io_errlog ); }
+ if( iv_spiraS) { addFFDC( SPIRA_S, io_errlog ); }
+
+ // grab the Tuple it is part of
+ 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]);
+ }
+ if( tuple ) { RUNTIME::UdTuple(tuple).addToLog(io_errlog); }
+ }
+}
+
/********************
Public Methods
********************/
@@ -1308,6 +1409,17 @@ errlHndl_t write_MDRT_Count( void )
{
return Singleton<hdatService>::instance().writeMdrtCount();
}
+
+/**
+ * @brief Retrieve and log FFDC data relevant to a given section of
+ * host data memory
+ */
+void add_host_data_ffdc( SectionId i_section,
+ errlHndl_t& io_errlog )
+{
+ return Singleton<hdatService>::instance().addFFDC(i_section,io_errlog);
+}
+
};
/********************
diff --git a/src/usr/runtime/hdatservice.H b/src/usr/runtime/hdatservice.H
index 0b670273a..4743f0da1 100644
--- a/src/usr/runtime/hdatservice.H
+++ b/src/usr/runtime/hdatservice.H
@@ -107,6 +107,18 @@ namespace RUNTIME
errlHndl_t updateHostDataSectionActual( SectionId i_section,
uint16_t i_count );
+ /**
+ * @brief Retrieve and log FFDC data relevant to a given section of
+ * host data memory
+ *
+ * @param[in] i_section Relevant section
+ * @param[inout] io_errlog Log to append FFDC to
+ *
+ * @return errlHndl_t NULL on success
+ */
+ void addFFDC( SectionId i_section,
+ errlHndl_t& io_errlog );
+
protected:
/**
* @brief Constructor
diff --git a/src/usr/runtime/plugins/errludP_hdat.H b/src/usr/runtime/plugins/errludP_hdat.H
index 0bae7a70a..a7e899c4f 100644
--- a/src/usr/runtime/plugins/errludP_hdat.H
+++ b/src/usr/runtime/plugins/errludP_hdat.H
@@ -24,10 +24,9 @@
#define ERRL_UDP_NACA_H
/**
- * @file errludstring.H
+ * @file errludP_hdat.H
*
- * Defines the ErrlUserDetailsParserString class that parser string FFDC
- * user detail in an error log
+ * Defines the ErrlUserDetailsParser classes that parse HDAT structures
*/
#include "errluserdetails.H"
@@ -41,6 +40,9 @@
#define TO_UINT32(ptr) (ntohl(*(reinterpret_cast<uint32_t*>(ptr))))
#define TO_UINT64(ptr) (ntohll(*(reinterpret_cast<uint64_t*>(ptr))))
+//@todo: RTC:81826 - Support 64-bit numbers
+// Combine Hi/Lo entries into a single 64-bit number
+
namespace RUNTIME
{
@@ -75,36 +77,55 @@ public:
void * i_pBuffer,
const uint32_t i_buflen) const
{
+ char* l_databuf = static_cast<char*>(i_pBuffer);
i_parser.PrintHeading("NACA");
i_parser.PrintBlank();
+ // Print out the memory addresses
+ i_parser.PrintNumber("Phys Addr Hi","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Phys Addr Lo","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Virt Addr Hi","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Virt Addr Lo","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Byte Size","%.8lX",i_buflen);
+
+ // Skip the rest if we don't have the data
+ uint32_t l_buflen = i_buflen - sizeof(uint64_t)*2;
+ if( l_buflen == 0 )
+ {
+ return;
+ }
+
// Dump the whole thing first
- i_parser.PrintHexDump(i_pBuffer,i_buflen);
+ i_parser.PrintHexDump(l_databuf,l_buflen);
i_parser.PrintBlank();
char* tmp = NULL;
// 0x0000 Spira-H offset (if non-zero)
- if( i_buflen >= 8 )
+ if( l_buflen >= 0x0008 )
{
- tmp = static_cast<char *>(i_pBuffer) + 0x0000;
+ tmp = static_cast<char *>(l_databuf) + 0x0000;
i_parser.PrintNumber("SPIRA-H","%.16llX",TO_UINT64(tmp));
}
// 0x0030 Legacy SPIRA offset
- if( i_buflen >= 0x0038 )
+ if( l_buflen >= 0x0038 )
{
- tmp = static_cast<char *>(i_pBuffer) + 0x0030;
+ tmp = static_cast<char *>(l_databuf) + 0x0030;
i_parser.PrintNumber("Legacy Spira","%.16llX",TO_UINT64(tmp));
}
// 0x00A0 Actual Legacy SPIRA size in bytes
- if( i_buflen >= 0x00A4 )
+ if( l_buflen >= 0x00A4 )
{
- tmp = static_cast<char *>(i_pBuffer) + 0x00A0;
+ tmp = static_cast<char *>(l_databuf) + 0x00A0;
i_parser.PrintNumber("Legacy SPIRA size","%.8X",TO_UINT32(tmp));
}
// 0x01B7 PHYP supports PCIA format
- if( i_buflen >= 0x01B8 )
+ if( l_buflen >= 0x01B8 )
{
- tmp = static_cast<char *>(i_pBuffer) + 0x01B7;
+ tmp = static_cast<char *>(l_databuf) + 0x01B7;
i_parser.PrintNumber("Legacy Spira","%.16llX",TO_UINT8(tmp));
}
}
@@ -179,16 +200,35 @@ public:
void * i_pBuffer,
const uint32_t i_buflen) const
{
+ char* l_databuf = static_cast<char*>(i_pBuffer);
i_parser.PrintHeading("Tuple");
i_parser.PrintBlank();
+ // Print out the memory addresses
+ i_parser.PrintNumber("Phys Addr Hi","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Phys Addr Lo","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Virt Addr Hi","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Virt Addr Lo","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Byte Size","%.8lX",i_buflen);
+
+ // Skip the rest if we don't have the data
+ uint32_t l_buflen = i_buflen - sizeof(uint64_t)*2;
+ if( l_buflen < 0x0018 )
+ {
+ return;
+ }
+
// Dump the whole thing first
- i_parser.PrintHexDump(i_pBuffer,i_buflen);
+ i_parser.PrintHexDump(l_databuf,l_buflen);
i_parser.PrintBlank();
- if( i_buflen >= 0x0020 )
+ if( l_buflen >= 0x0020 )
{
- UdParserTuple::parse( i_parser, i_pBuffer );
+ UdParserTuple::parse( i_parser, l_databuf );
}
}
@@ -229,37 +269,56 @@ public:
void * i_pBuffer,
const uint32_t i_buflen) const
{
+ char* l_databuf = static_cast<char*>(i_pBuffer);
i_parser.PrintHeading("SPIRA");
i_parser.PrintBlank();
+ // Print out the memory addresses
+ i_parser.PrintNumber("Phys Addr Hi","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Phys Addr Lo","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Virt Addr Hi","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Virt Addr Lo","%.8lX",TO_UINT32(l_databuf));
+ l_databuf += sizeof(uint32_t);
+ i_parser.PrintNumber("Byte Size","%.8lX",i_buflen);
+
+ // Skip the rest if we don't have the data
+ uint32_t l_buflen = i_buflen - sizeof(uint64_t)*2;
+ if( l_buflen == 0 )
+ {
+ return;
+ }
+
// Dump the whole thing first
- i_parser.PrintHexDump(i_pBuffer,i_buflen);
+ i_parser.PrintHexDump(l_databuf,l_buflen);
i_parser.PrintBlank();
char* tmp = NULL;
//** 0x0000 Common HDIF header
// 0x0002 Structure eye catcher
- if( i_buflen >= 0x0008 )
+ if( l_buflen >= 0x0008 )
{
- tmp = static_cast<char *>(i_pBuffer) + 0x0002;
+ tmp = static_cast<char *>(l_databuf) + 0x0002;
char tmp1[7];
tmp1[6] = '\0';
memcpy( tmp1, tmp, 6 );
i_parser.PrintString("Eyecatcher",tmp1);
}
// 0x000A Structure version
- if( i_buflen >= 0x000C )
+ if( l_buflen >= 0x000C )
{
- tmp = static_cast<char *>(i_pBuffer) + 0x000A;
+ tmp = static_cast<char *>(l_databuf) + 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 )
+ if( l_buflen >= 0x0038 )
{
- tmp = static_cast<char *>(i_pBuffer) + 0x0034;
+ tmp = static_cast<char *>(l_databuf) + 0x0034;
num_tuples = TO_UINT32(tmp);
i_parser.PrintNumber("Num Tuples","%.8X",num_tuples);
}
@@ -270,9 +329,9 @@ public:
tuple++ )
{
i_parser.PrintNumber(" Tuple#","%d",tuple);
- void* tuple_ptr = static_cast<char *>(i_pBuffer)
+ void* tuple_ptr = static_cast<char *>(l_databuf)
+ 0x0040 + (tuple * 0x20);
- if( i_buflen < (0x0040 + (tuple * 0x20)) )
+ if( l_buflen < (0x0040 + (tuple * 0x20)) )
{
break;
}
diff --git a/src/usr/runtime/populate_attributes.C b/src/usr/runtime/populate_attributes.C
index 061283faf..1370a51a2 100644
--- a/src/usr/runtime/populate_attributes.C
+++ b/src/usr/runtime/populate_attributes.C
@@ -241,11 +241,47 @@ errlHndl_t populate_system_attributes( void )
RUNTIME::RC_INVALID_SECTION,
sys_data_addr,
sys_data_size );
+ // most likely this is a HB code bug
+ errhdl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ // but it could also be a FSP bug in setting up the HDAT data
+ errhdl->addProcedureCallout(HWAS::EPUB_PRC_SP_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ // save some of the HDAT data for FFDC
+ RUNTIME::add_host_data_ffdc( RUNTIME::HSVC_SYSTEM_DATA, errhdl );
+
break;
}
+ else if( sizeof(system_data_t) > sys_data_size )
+ {
+ TRACFCOMP( g_trac_runtime, "Not enough space allocated by HDAT for HostServices System Data" );
+ /*@
+ * @errortype
+ * @reasoncode RUNTIME::RC_NOT_ENOUGH_SPACE
+ * @moduleid RUNTIME::MOD_RUNTIME_POP_SYS_ATTR
+ * @userdata1 Required size
+ * @userdata2 Available size
+ * @devdesc Not enough space allocated by HDAT for
+ * HostServices System Data
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_RUNTIME_POP_SYS_ATTR,
+ RUNTIME::RC_NOT_ENOUGH_SPACE,
+ sizeof(system_data_t),
+ sys_data_size );
+ // need to update the FSP code
+ errhdl->addProcedureCallout(HWAS::EPUB_PRC_SP_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // save some of the HDAT data for FFDC
+ RUNTIME::add_host_data_ffdc( RUNTIME::HSVC_SYSTEM_DATA, errhdl );
+
+ break;
+ }
+
system_data_t* sys_data = reinterpret_cast<system_data_t*>(sys_data_addr);
memset( sys_data, 'A', sizeof(system_data_t) );
- //@fixme - Should test that we aren't going out of bounds
// These variables are used by the HSVC_LOAD_ATTR macros directly
uint64_t* _num_attr = NULL; //pointer to numAttr in struct
@@ -361,9 +397,36 @@ errlHndl_t populate_node_attributes( uint64_t i_nodeNum )
node_data_size );
break;
}
+ else if( sizeof(node_data_t) > node_data_size )
+ {
+ TRACFCOMP( g_trac_runtime, "Not enough space allocated by HDAT for HostServices Node Data" );
+ /*@
+ * @errortype
+ * @reasoncode RUNTIME::RC_NOT_ENOUGH_SPACE
+ * @moduleid RUNTIME::MOD_RUNTIME_POP_NODE_ATTR
+ * @userdata1 Required size
+ * @userdata2 Available size
+ * @devdesc Not enough space allocated by HDAT for
+ * HostServices Node Data
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_RUNTIME_POP_NODE_ATTR,
+ RUNTIME::RC_NOT_ENOUGH_SPACE,
+ sizeof(node_data_t),
+ node_data_size );
+ // need to update the FSP code
+ errhdl->addProcedureCallout(HWAS::EPUB_PRC_SP_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // save some of the HDAT data for FFDC
+ RUNTIME::add_host_data_ffdc( RUNTIME::HSVC_NODE_DATA, errhdl );
+
+ break;
+ }
+
node_data_t* node_data = reinterpret_cast<node_data_t*>(node_data_addr);
memset( node_data, 'A', sizeof(node_data) );
- //@fixme - Should test that we aren't going out of bounds
// These variables are used by the HSVC_LOAD_ATTR macros directly
uint64_t* _num_attr = NULL; //pointer to numAttr in struct
diff --git a/src/usr/runtime/test/hdatservicetest.H b/src/usr/runtime/test/hdatservicetest.H
index 4ddc089ea..3094e80aa 100644
--- a/src/usr/runtime/test/hdatservicetest.H
+++ b/src/usr/runtime/test/hdatservicetest.H
@@ -418,6 +418,19 @@ class HdatServiceTest: public CxxTest::TestSuite
TS_FAIL("testSpira> Size of SPIRA_H data too small");
}
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_VERIFY_HDAT_ADDRESS,
+ RUNTIME::RC_BAD_HDAT_HEADER,
+ 0,0 );
+ add_host_data_ffdc(RUNTIME::HSVC_NODE_DATA,errhdl);
+ add_host_data_ffdc(RUNTIME::HSVC_SYSTEM_DATA,errhdl);
+ add_host_data_ffdc(RUNTIME::NACA,errhdl);
+ add_host_data_ffdc(RUNTIME::SPIRA_L,errhdl);
+ add_host_data_ffdc(RUNTIME::SPIRA_S,errhdl);
+ add_host_data_ffdc(RUNTIME::SPIRA_H,errhdl);
+ errlCommit(errhdl,RUNTIME_COMP_ID);
+
TRACFCOMP( g_trac_runtime, "testSpira> finish" );
#endif
OpenPOWER on IntegriCloud