Skip to content

Commit

Permalink
errldisplay: use table-driven display for HWPF error strings
Browse files Browse the repository at this point in the history
Gcc generates space-inefficient code for giant switch statements and
the existing display formatted encoded strings have much redundant data.

Refactor the perl script to generate a static table output containg the
string data plus lookup function and move the actual format strings to
the display code itself.

This saves ~300K for the hostboot extended image and allows the
HWPF error string data to be used outside of just the console display
object.

Resolves #118

Signed-off-by: Robert Lippert <rlippert@google.com>
Change-Id: Ifddc1cdb1789b4943a68590c169fcdf8206d2ffa
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48595
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matt Derksen <mderkse1@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
rlippert authored and dcrowell77 committed Oct 28, 2017
1 parent 7535501 commit fb8c267
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 102 deletions.
111 changes: 99 additions & 12 deletions src/usr/errldisplay/errldisplay.C
Expand Up @@ -60,6 +60,7 @@
#include <errl/errlreasoncodes.H>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <initservice/taskargs.H>
#include <algorithm>
#include <console/consoleif.H>
Expand Down Expand Up @@ -529,6 +530,19 @@ void ErrLogDisplay::displayTarget(void *data, size_t size)
}
}

#ifdef CONFIG_CONSOLE_OUTPUT_FFDCDISPLAY
static void printHex(char *i_buf, const size_t i_size)
{
char byte_str[256] = { 0, };
size_t pos = 0;
// Limit dump to first 32 bytes.
for ( size_t i = 0; i < std::min( i_size, 32ul ); ++i )
pos += sprintf( byte_str + pos, "%s%02X", (i % 4) == 0 ? " " : "",
i_buf[i] );
CONSOLE::displayf( NULL, " %s", byte_str );
}
#endif

void ErrLogDisplay::displayHwpf(void *data, size_t size, uint8_t i_type)
{
#ifdef CONFIG_CONSOLE_OUTPUT_FFDCDISPLAY
Expand All @@ -539,23 +553,96 @@ void ErrLogDisplay::displayHwpf(void *data, size_t size, uint8_t i_type)
{
case ERRORLOG::ERRL_UDT_STRING:
//this is error code str -- single word of data is HWPF RC
CONSOLE::displayf(NULL,
"------------------------------------------------");
fapi2::hbfwErrDisplayHwpRc(*word_buf);
CONSOLE::displayf( NULL,
"------------------------------------------------" );
const char *rc;
const char *desc;
fapi2::hbfwErrLookupHwpRc( *word_buf, rc, desc );
CONSOLE::displayf( NULL, " HwpReturnCode : %s",
rc ? rc : "Unknown" );
CONSOLE::displayf( NULL, " HWP Error description : %s",
desc ? desc : "Unknown" );
break;

case ERRORLOG::ERRL_UDT_TARGET:
{
//this is HWPF FFDC. First word is hash, rest of data is hex
//reserve space for 16 words of data with spaces between

CONSOLE::displayf(NULL,
"------------------------------------------------");
void * buf = reinterpret_cast<void*>(
reinterpret_cast<char*>( data )+4);
fapi2::hbfwErrDisplayHwpRcFFDC(*word_buf,buf, size-4);
break;
//this is HWPF FFDC. First word is hash, rest of data is hex
//reserve space for 16 words of data with spaces between
CONSOLE::displayf( NULL,
"------------------------------------------------" );
fapi2::hbfwFfdcType type;
uint64_t value;
const char *str;
int index = 0;
char *buf = reinterpret_cast<char*>( data ) + sizeof( *word_buf );
size -= sizeof( *word_buf );
while ( fapi2::hbfwErrLookupHwpRcFFDC( *word_buf, index, type, value,
str ) )
{
if( type == fapi2::HBFW_FFDC_TYPE_HWP_RC_FFDC )
{
const char *rc;
const char *desc;
fapi2::hbfwErrLookupHwpRc( value, rc, desc );
CONSOLE::displayf( NULL, " HwpReturnCode : %s",
rc ? rc : "Unknown" );
CONSOLE::displayf( NULL, " FFDC : %s",
str ? str : "Unknown" );
printHex(buf, size);
size = 0;
}
else if( type == fapi2::HBFW_FFDC_TYPE_SCOM_FAIL )
{
uint64_t val64 = be64toh( *reinterpret_cast<uint64_t*>( buf ) );
CONSOLE::displayf( NULL, " Failed SCOM address : %#016lX",
val64 );
}
else if( type == fapi2::HBFW_FFDC_TYPE_PIB_RC )
{
uint64_t val32 = be64toh( *reinterpret_cast<uint32_t*>( buf ) );
CONSOLE::displayf( NULL, " PIB RC : %#08lX",
val32 );
}
else if( type == fapi2::HBFW_FFDC_TYPE_REGISTER_SET )
{
CONSOLE::displayf( NULL, " Register FFDC : %s",
str ? str : "Unknown" );
}
else if( type == fapi2::HBFW_FFDC_TYPE_CHIP_POSITION
&& (size >= sizeof(uint32_t)) )
{
uint32_t val32 = be32toh( *reinterpret_cast<uint32_t*>( buf ) );
CONSOLE::displayf( NULL, " Chip Position : %X",
val32 );
buf += sizeof(uint32_t);
size -= sizeof(uint32_t);
}
else if( type == fapi2::HBFW_FFDC_TYPE_CFAM_REG
&& (size >= sizeof(uint32_t)) )
{
uint32_t val32 = be32toh( *reinterpret_cast<uint32_t*>( buf ) );
CONSOLE::displayf( NULL, " CFAM Register : %s",
str ? str : "Unknown" );
CONSOLE::displayf( NULL, " %08X", val32 );
buf += sizeof(uint32_t);
size -= sizeof(uint32_t);
}
else if( type == fapi2::HBFW_FFDC_TYPE_SCOM_REG
&& (size >= sizeof(uint64_t)) )
{
uint64_t val64 = be64toh( *reinterpret_cast<uint64_t*>( buf ) );
CONSOLE::displayf( NULL, " SCOM Register : %s",
str ? str : "Unknown" );
CONSOLE::displayf( NULL, " %08llX %08llX",
(val64 >> 32) & 0xffffffff,
(val64 & 0xffffffff) );
buf += sizeof(uint64_t);
size -= sizeof(uint64_t);
}
index++;
}
break;
}
}
#endif
}
Expand Down
2 changes: 2 additions & 0 deletions src/usr/errldisplay/makefile
Expand Up @@ -46,3 +46,5 @@ vpath %.C ${GENDIR} ${GENDIR}/plugins/prdf/rule
EXTRAINCDIR += ${GENDIR}/plugins
EXTRAINCDIR += ${GENDIR}/plugins/prdf/
EXTRAINCDIR += ${ROOTPATH}/src/usr/diag/prdf/plugins/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/centaur/common/include/
158 changes: 68 additions & 90 deletions src/usr/fapi2/platCreateHwpErrParser.pl
Expand Up @@ -7,6 +7,7 @@
# OpenPOWER HostBoot Project
#
# Contributors Listed Below - COPYRIGHT 2015,2017
# [+] Google Inc.
# [+] International Business Machines Corp.
#
#
Expand Down Expand Up @@ -93,10 +94,13 @@
print EDISFILE "#define HBFWERRDISPLAYPLATHWPERR_H_\n\n";
print EDISFILE "namespace fapi2\n";
print EDISFILE "{\n\n";
print EDISFILE "void hbfwErrDisplayHwpRc(const uint32_t i_hwpRc)\n";
print EDISFILE "void hbfwErrLookupHwpRc(const uint32_t i_hwpRc, const char *& o_rcStr, const char *& o_descStr)\n";
print EDISFILE "{\n";
print EDISFILE " switch(i_hwpRc)\n";
print EDISFILE " {\n";
print EDISFILE " static const struct {\n";
print EDISFILE " const uint32_t hwp_rc;\n";
print EDISFILE " const char * const rc_str;\n";
print EDISFILE " const char * const desc;\n";
print EDISFILE " } hwpDescMap[] = {\n";

#------------------------------------------------------------------------------
# For each XML file
Expand Down Expand Up @@ -141,10 +145,7 @@
print TGFILE " i_parser.PrintString(\"HWP Error description\", \"$desc\");\n";
print TGFILE " break;\n";

print EDISFILE " case 0x$errHash24Bit:\n";
print EDISFILE " CONSOLE::displayf(NULL,\" HwpReturnCode : $err->{rc}\");\n";
print EDISFILE " CONSOLE::displayf(NULL,\" HWP Error description : $desc\");\n";
print EDISFILE " break;\n";
print EDISFILE " { 0x$errHash24Bit, \"$err->{rc}\", \"$desc\" },\n";
}
}

Expand All @@ -157,8 +158,15 @@
print TGFILE " }\n";
print TGFILE "}\n\n";

print EDISFILE " default:\n";
print EDISFILE " CONSOLE::displayf(NULL,\" Unrecognized Error ID : 0x%x\", i_hwpRc);\n";
print EDISFILE " };\n\n";
print EDISFILE " o_rcStr = NULL;\n";
print EDISFILE " o_descStr = NULL;\n";
print EDISFILE " for (size_t i = 0; i < sizeof(hwpDescMap)/sizeof(hwpDescMap[0]); ++i) {\n";
print EDISFILE " if (hwpDescMap[i].hwp_rc == i_hwpRc) {\n";
print EDISFILE " o_rcStr = hwpDescMap[i].rc_str;\n";
print EDISFILE " o_descStr = hwpDescMap[i].desc;\n";
print EDISFILE " break;\n";
print EDISFILE " }\n";
print EDISFILE " }\n";
print EDISFILE "}\n\n";

Expand Down Expand Up @@ -209,6 +217,14 @@
print EDISFILE "#ifndef HBFWERRDISPLAYPLATHWPFFDC_H_\n";
print EDISFILE "#define HBFWERRDISPLAYPLATHWPFFDC_H_\n\n";
print EDISFILE "#include <stdio.h>\n\n";
print EDISFILE "#include <p9_mc_scom_addresses.H>\n";
print EDISFILE "#include <p9_misc_scom_addresses.H>\n";
print EDISFILE "#include <p9_obus_scom_addresses.H>\n";
print EDISFILE "#include <p9_perv_scom_addresses.H>\n";
print EDISFILE "#include <p9_quad_scom_addresses.H>\n";
print EDISFILE "#include <p9_xbus_scom_addresses.H>\n";
print EDISFILE "#include <cen_gen_scom_addresses.H>\n";
print EDISFILE "#include <centaur_misc_constants.H>\n";
print EDISFILE "namespace fapi2\n";
print EDISFILE "{\n\n";

Expand All @@ -232,38 +248,28 @@
print TGFILE " switch(l_ffdcId)\n";
print TGFILE " {\n";

print EDISFILE "void printHex(uint8_t * i_buf,\n";
print EDISFILE " const size_t i_size)\n";
print EDISFILE "{\n";
print EDISFILE " char hexStr[256] = {0,};\n";
print EDISFILE " char * pHex = hexStr;\n";
print EDISFILE " size_t strSize = (i_size < 32) ? (i_size) : 32 ;\n";
print EDISFILE " size_t pos = 0;\n";
print EDISFILE "\n";
print EDISFILE " for(size_t i=0; i < strSize; i++)\n";
print EDISFILE " {\n";
print EDISFILE " pos += sprintf(pHex+pos,\"%02X\", i_buf[i]);\n";
print EDISFILE "enum hbfwFfdcType : uint8_t {\n";
print EDISFILE " HBFW_FFDC_TYPE_HWP_RC_FFDC,\n";
print EDISFILE " HBFW_FFDC_TYPE_SCOM_FAIL,\n";
print EDISFILE " HBFW_FFDC_TYPE_PIB_RC,\n";
print EDISFILE " HBFW_FFDC_TYPE_REGISTER_SET,\n";
print EDISFILE " HBFW_FFDC_TYPE_CHIP_POSITION,\n";
print EDISFILE " HBFW_FFDC_TYPE_CFAM_REG,\n";
print EDISFILE " HBFW_FFDC_TYPE_SCOM_REG,\n";
print EDISFILE "};\n";
print EDISFILE "\n";
print EDISFILE " if(((i+1) % 4) == 0)\n";
print EDISFILE " {\n";
print EDISFILE " pos += sprintf(pHex+pos,\" \");\n";
print EDISFILE " }\n";
print EDISFILE " }\n";
print EDISFILE " CONSOLE::displayf(NULL,\" %s\",pHex);\n";
print EDISFILE "}\n\n\n";

print EDISFILE "void hbfwErrDisplayHwpRcFFDC(const uint32_t i_ffdcId,\n";
print EDISFILE " void * i_pBuffer,\n";
print EDISFILE " const uint32_t i_buflen)\n";
print EDISFILE "int hbfwErrLookupHwpRcFFDC(const uint32_t i_ffdcId,\n";
print EDISFILE " int i_index,\n";
print EDISFILE " hbfwFfdcType &o_ffdcType,\n";
print EDISFILE " uint64_t &o_value,\n";
print EDISFILE " const char * & o_str)\n";
print EDISFILE "{\n";
print EDISFILE " const uint32_t CFAM_DATA_LEN = 4;\n";
print EDISFILE " const uint32_t SCOM_DATA_LEN = 8;\n";
print EDISFILE " const uint32_t POS_LEN = 4;\n";
print EDISFILE " uint8_t * l_pBuffer = static_cast<uint8_t *>(i_pBuffer);\n";
print EDISFILE " uint32_t l_buflen = i_buflen;\n\n";
print EDISFILE " switch(i_ffdcId)\n";
print EDISFILE " {\n";

print EDISFILE " static const struct {\n";
print EDISFILE " const uint32_t ffdc_id;\n";
print EDISFILE " hbfwFfdcType type;\n";
print EDISFILE " uint64_t value;\n";
print EDISFILE " const char * const str;\n";
print EDISFILE " } __attribute__((packed)) hwpRcFfdcMap[] = {\n";

#------------------------------------------------------------------------------
# For each XML file
Expand Down Expand Up @@ -299,11 +305,7 @@
print TGFILE " i_parser.PrintNumber(\"Failed SCOM address\",\"%#016lX\",l_Address);}\n";
print TGFILE " break;\n";

print EDISFILE " case 0x$ffdcHash32Bit:\n";
print EDISFILE " { uint64_t l_Address =\n";
print EDISFILE " *(reinterpret_cast<uint64_t*>(l_pBuffer));\n";
print EDISFILE " CONSOLE::displayf(NULL,\" Failed SCOM address : %#016lX\",l_Address);}\n";
print EDISFILE " break;\n";
print EDISFILE " { 0x$ffdcHash32Bit, HBFW_FFDC_TYPE_SCOM_FAIL, 0, NULL},\n";

$ffdcName = $err->{rc} . "_pcb_pib_rc";
$ffdcHash128Bit = md5_hex($ffdcName);
Expand All @@ -314,10 +316,7 @@
print TGFILE " i_parser.PrintNumber(\"PIB RC:\",\"%#08lX\",l_PibRc);}\n";
print TGFILE " break;\n";

print EDISFILE " case 0x$ffdcHash32Bit:\n";
print EDISFILE " {uint32_t l_PibRc = *(reinterpret_cast<uint32_t *>(l_pBuffer));\n";
print EDISFILE " CONSOLE::displayf(NULL,\" PIB RC : %#08lX\",l_PibRc);}\n";
print EDISFILE " break;\n";
print EDISFILE " { 0x$ffdcHash32Bit, HBFW_FFDC_TYPE_PIB_RC, 0, NULL},\n";

}
foreach my $ffdc (@{$err->{ffdc}})
Expand All @@ -338,13 +337,9 @@
print TGFILE "{i_parser.PrintHexDump(l_pBuffer, l_buflen);}\n";
print TGFILE " break;\n";

print EDISFILE " case 0x$ffdcHash32Bit:\n";
print EDISFILE " CONSOLE::displayf(NULL,\" HwpReturnCode : $err->{rc}\");\n";
print EDISFILE " CONSOLE::displayf(NULL,\" FFDC : $ffdc\");\n";
print EDISFILE " if (l_buflen) ";
print EDISFILE " {printHex(l_pBuffer, l_buflen);}\n";
print EDISFILE " break;\n";

my $errHash128Bit = md5_hex($err->{rc});
my $errHash24Bit = substr($errHash128Bit, 0, 6);
print EDISFILE " { 0x$ffdcHash32Bit, HBFW_FFDC_TYPE_HWP_RC_FFDC, 0x$errHash24Bit, \"$ffdc\"},\n";
}
}

Expand Down Expand Up @@ -374,19 +369,8 @@
print TGFILE " l_buflen -= POS_LEN;\n";
print TGFILE " }\n";

print EDISFILE " case 0x$ffdcHash32Bit:\n";
print EDISFILE " CONSOLE::displayf(NULL,\" Register FFDC : $ffdcName\");\n";
print EDISFILE " while (l_buflen > 0)\n";
print EDISFILE " {\n";
print EDISFILE " if (l_buflen >= POS_LEN)\n";
print EDISFILE " {\n";
print EDISFILE " uint32_t * l_pBufferTemp = reinterpret_cast<uint32_t *>(l_pBuffer);\n";
print EDISFILE " CONSOLE::displayf(NULL,\" Chip Position : %X\", *l_pBufferTemp);\n";
print EDISFILE " l_pBufferTemp = NULL;\n";
print EDISFILE " l_pBuffer+= POS_LEN;\n";
print EDISFILE " l_buflen -= POS_LEN;\n";
print EDISFILE " }\n";

print EDISFILE " { 0x$ffdcHash32Bit, HBFW_FFDC_TYPE_REGISTER_SET, 0, \"$ffdcName\"},\n";
print EDISFILE " { 0x$ffdcHash32Bit, HBFW_FFDC_TYPE_CHIP_POSITION, 0, NULL},\n";

foreach my $cfamRegister (@{$registerFfdc->{cfamRegister}})
{
Expand All @@ -398,13 +382,7 @@
print TGFILE " l_buflen -= CFAM_DATA_LEN;\n";
print TGFILE " }\n";

print EDISFILE " if (l_buflen >= CFAM_DATA_LEN)\n";
print EDISFILE " {\n";
print EDISFILE " CONSOLE::displayf(NULL,\" CFAM Register : $cfamRegister\");\n";
print EDISFILE " printHex(l_pBuffer, CFAM_DATA_LEN);\n";
print EDISFILE " l_pBuffer+= CFAM_DATA_LEN;\n";
print EDISFILE " l_buflen -= CFAM_DATA_LEN;\n";
print EDISFILE " }\n";
print EDISFILE " { 0x$ffdcHash32Bit, HBFW_FFDC_TYPE_CFAM_REG, $cfamRegister, \"$cfamRegister\"},\n";
}
foreach my $scomRegister (@{$registerFfdc->{scomRegister}})
{
Expand All @@ -417,19 +395,10 @@
print TGFILE " l_buflen -= SCOM_DATA_LEN;\n";
print TGFILE " }\n";

print EDISFILE " if (l_buflen >= SCOM_DATA_LEN)\n";
print EDISFILE " {\n";
print EDISFILE " CONSOLE::displayf(NULL,\" SCOM Register : $scomRegister\");\n";
print EDISFILE " printHex(l_pBuffer, SCOM_DATA_LEN);\n";
print EDISFILE " l_pBuffer+= SCOM_DATA_LEN;\n";
print EDISFILE " l_buflen -= SCOM_DATA_LEN;\n";
print EDISFILE " }\n";
print EDISFILE " { 0x$ffdcHash32Bit, HBFW_FFDC_TYPE_SCOM_REG, $scomRegister, \"$scomRegister\"},\n";
}
print TGFILE " }\n";
print TGFILE " break;\n";

print EDISFILE " }\n";
print EDISFILE " break;\n";
}
}

Expand All @@ -443,11 +412,20 @@
print TGFILE " }\n\n";
print TGFILE "}\n\n";

print EDISFILE " default:\n";
print EDISFILE " CONSOLE::displayf(NULL,\" Unrecognized FFDC : 0x%x\", i_ffdcId);\n";
print EDISFILE " if (l_buflen) ";
print EDISFILE " {printHex(l_pBuffer, l_buflen);}\n";
print EDISFILE " }\n\n";
print EDISFILE " };\n\n";
print EDISFILE " for (size_t i = 0; i < sizeof(hwpRcFfdcMap)/sizeof(hwpRcFfdcMap[0]); ++i) {\n";
print EDISFILE " if (hwpRcFfdcMap[i].ffdc_id == i_ffdcId) {\n";
print EDISFILE " if (i_index == 0) {\n";
print EDISFILE " o_ffdcType = hwpRcFfdcMap[i].type;\n";
print EDISFILE " o_value = hwpRcFfdcMap[i].value;\n";
print EDISFILE " o_str = hwpRcFfdcMap[i].str;\n";
print EDISFILE " return 1;\n";
print EDISFILE " } else {\n";
print EDISFILE " i_index--;\n";
print EDISFILE " }\n";
print EDISFILE " }\n";
print EDISFILE " }\n";
print EDISFILE " return 0;\n";
print EDISFILE "}\n\n";


Expand Down

0 comments on commit fb8c267

Please sign in to comment.