diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2013-08-19 08:56:23 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-09-13 17:38:38 -0500 |
commit | 5d8dd9af9d7a4df742ebbd8cdf20c58a8e95b05f (patch) | |
tree | 6c8e663be551562a7835d4f554a13e5afe7e317a /src | |
parent | 45f3421a82460ed2ce5dd86d3bb62209ac9d948e (diff) | |
download | talos-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.H | 11 | ||||
-rw-r--r-- | src/include/usr/runtime/runtime_reasoncodes.H | 4 | ||||
-rw-r--r-- | src/include/usr/vmmconst.h | 7 | ||||
-rw-r--r-- | src/usr/runtime/errlud_hdat.C | 87 | ||||
-rw-r--r-- | src/usr/runtime/hdatservice.C | 128 | ||||
-rw-r--r-- | src/usr/runtime/hdatservice.H | 12 | ||||
-rw-r--r-- | src/usr/runtime/plugins/errludP_hdat.H | 107 | ||||
-rw-r--r-- | src/usr/runtime/populate_attributes.C | 67 | ||||
-rw-r--r-- | src/usr/runtime/test/hdatservicetest.H | 13 |
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 |