diff options
author | Adam Muhle <armuhle@us.ibm.com> | 2013-01-23 08:53:04 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-02-04 13:24:10 -0600 |
commit | 6ba9a7790919fc430ddf1539579fdb4e9e7bba0d (patch) | |
tree | 488d0567844c4904110873531d833a0c5398fb33 | |
parent | 68286500750647b14ec5cbbe0253bafef2fdf341 (diff) | |
download | blackbird-hostboot-6ba9a7790919fc430ddf1539579fdb4e9e7bba0d.tar.gz blackbird-hostboot-6ba9a7790919fc430ddf1539579fdb4e9e7bba0d.zip |
Triggering Hostboot Shutdown when PNOR is bad
Updating the doShutdown path to support receiving a reason
code as input. Then changing PNOR RP to issue a shutdown
when problems are detected with the PNOR Partition table.
RTC: 44146
Change-Id: Ib4111d0a91f53d90fa100422a1463539897598e6
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/3024
Tested-by: Jenkins Server
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rwxr-xr-x | src/build/simics/hb-simdebug.py | 2 | ||||
-rw-r--r-- | src/include/kernel/kernel_reasoncodes.H | 5 | ||||
-rw-r--r-- | src/include/usr/errl/errlmanager.H | 18 | ||||
-rw-r--r-- | src/include/usr/pnor/pnor_reasoncodes.H | 3 | ||||
-rw-r--r-- | src/kernel/cpumgr.C | 16 | ||||
-rw-r--r-- | src/kernel/terminate.C | 4 | ||||
-rw-r--r-- | src/usr/errl/errlmanager.C | 5 | ||||
-rw-r--r-- | src/usr/errl/parser/errlparser.C | 12 | ||||
-rw-r--r-- | src/usr/hwpf/test/hwpisteperrortest.H | 42 | ||||
-rw-r--r-- | src/usr/pnor/pnorrp.C | 69 |
10 files changed, 113 insertions, 63 deletions
diff --git a/src/build/simics/hb-simdebug.py b/src/build/simics/hb-simdebug.py index 12f4a2c17..048546b46 100755 --- a/src/build/simics/hb-simdebug.py +++ b/src/build/simics/hb-simdebug.py @@ -171,7 +171,7 @@ Examples: \n new_command("hb-errl", (lambda logid, logidStr, flg_l, flg_d: run_hb_debug_framework("Errl", - ("display="+(str(logid) if logid else logidStr) if flg_d else "" + ("display="+(("0x%x" % logid) if logid else logidStr) if flg_d else "" ), outputFile = "hb-errl.output")), [ arg(int_t, "logid", "?", None), diff --git a/src/include/kernel/kernel_reasoncodes.H b/src/include/kernel/kernel_reasoncodes.H index fe4748a19..f76d0993b 100644 --- a/src/include/kernel/kernel_reasoncodes.H +++ b/src/include/kernel/kernel_reasoncodes.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -36,6 +36,9 @@ enum KernelReasonCode { + //NOTE: RC_ASSERT and RC_SHUTDOWN must be used in one unique + // locationto maintain uniqueness as they will be used + // without a MODULE ID. RC_ASSERT = KERNEL_COMP_ID | 0x01, /**< Assert */ RC_SHUTDOWN = KERNEL_COMP_ID | 0x02, /**< Shutdown */ }; diff --git a/src/include/usr/errl/errlmanager.H b/src/include/usr/errl/errlmanager.H index 3b9ad6572..75a5ae25e 100644 --- a/src/include/usr/errl/errlmanager.H +++ b/src/include/usr/errl/errlmanager.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ /* */ /* p1 */ /* */ @@ -176,6 +176,22 @@ private: }; /** + * @enum ERRORLOG_PLID_OFFSET + * + * Base ID of Hostboot PLIDs. The hostboot plid range is 0x90 to 0x93 + * (For each instance running on a multinode system. Eventually the + * offset will need to be offset for the proper node and possibly some + * other initializer sent from FSP to keep PLIDs unique across IPLs. + * + * NOTE: Changes to this define may require changes to + * CpuManager::requestShutdown + */ + enum ERRORLOG_PLID_OFFSET + { + ERRLOG_PLID_BASE = 0x90000000, /**< Hostboot Base PLID Offset */ + }; + + /** * @brief Disabled copy constructor and assignment operator */ ErrlManager(const ErrlManager& i_right); diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H index e8ad6341d..e580e2242 100644 --- a/src/include/usr/pnor/pnor_reasoncodes.H +++ b/src/include/usr/pnor/pnor_reasoncodes.H @@ -66,6 +66,9 @@ namespace PNOR RC_BAD_STARTUP_RC = PNOR_COMP_ID | 0x09, RC_UNSUPORTED_HARDWARE = PNOR_COMP_ID | 0x0A, RC_MICRON_INCOMPLETE = PNOR_COMP_ID | 0x0B, + //RC_PARTITION_TABLE_INVALID Must be Unique by itself + // for Shutdown path + RC_PARTITION_TABLE_INVALID = PNOR_COMP_ID | 0x0C, }; }; diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C index 6e6b59860..954232b2d 100644 --- a/src/kernel/cpumgr.C +++ b/src/kernel/cpumgr.C @@ -111,11 +111,21 @@ void CpuManager::requestShutdown(uint64_t i_status) cv_shutdown_requested = true; // If the shutdown was not called with a Good shutdown status - // then we know we are shutting down due to error and the - // status passed back is instead a PLID + // then we know we are shutting down due to error. We need to + // figure out if the error provided is a PLID or reasoncode + // and write it appropriately. + // Hostboot PLIDs always start with 0x9 (32-bit) + static const uint64_t PLID_MASK = 0x0000000090000000; if (i_status != SHUTDOWN_STATUS_GOOD) { - termWritePlid(TI_SHUTDOWN, i_status); + if ((i_status & 0x00000000F0000000) == PLID_MASK) + { + termWritePlid(TI_SHUTDOWN, i_status); + } + else + { + termWriteSRC(TI_SHUTDOWN,i_status, 0); + } printk("TI initiated on all threads (shutdown)\n"); } diff --git a/src/kernel/terminate.C b/src/kernel/terminate.C index 10daec717..2c103c5af 100644 --- a/src/kernel/terminate.C +++ b/src/kernel/terminate.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -64,7 +64,7 @@ void termWriteSRC(uint16_t i_source, uint16_t i_reasoncode,uint64_t i_failAddr) kernel_TIDataArea.src.ID = 0xBC; kernel_TIDataArea.src.subsystem = 0x11; kernel_TIDataArea.src.reasoncode = i_reasoncode; - kernel_TIDataArea.src.moduleID = MOD_KERNEL_TERMINATE; + kernel_TIDataArea.src.moduleID = 0; kernel_TIDataArea.src.iType = TI_WITH_SRC; // Update User Data with address of fail location diff --git a/src/usr/errl/errlmanager.C b/src/usr/errl/errlmanager.C index e95b6d2fa..4cce80016 100644 --- a/src/usr/errl/errlmanager.C +++ b/src/usr/errl/errlmanager.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ /* */ /* p1 */ /* */ @@ -74,13 +74,12 @@ char* g_ErrlStorage = new char[ ERRL_STORAGE_SIZE ]; #define POINTER2OFFSET(p) ((reinterpret_cast<char*>(p))-(g_ErrlStorage)) - /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// ErrlManager::ErrlManager() { // PNOR will be reinitialized every time hostboot runs - iv_currLogId = 0; + iv_currLogId = ERRLOG_PLID_BASE; iv_hwasProcessCalloutFn = NULL; diff --git a/src/usr/errl/parser/errlparser.C b/src/usr/errl/parser/errlparser.C index 801da1635..71d71aab5 100644 --- a/src/usr/errl/parser/errlparser.C +++ b/src/usr/errl/parser/errlparser.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ /* */ /* p1 */ /* */ @@ -622,10 +622,10 @@ int main( int argc, char *argv[] ) } else { - int c = sscanf( argv[i], "%d", &ulLogId ); + int c = sscanf( argv[i], "%x", &ulLogId ); if( c != 1 ) { - fprintf( stdout, "Provide -d <decimal log ID>\n" ); + fprintf( stdout, "Provide -d <hex log ID>\n" ); exit( 2 ); } } @@ -893,7 +893,7 @@ int main( int argc, char *argv[] ) printf( "%s\n", szDivider ); fListHead = 1; } - printf( "%-16s %8d\n", + printf( "%-16s 0X%8X\n", FindComp(pPrivateHdr->sectionheader.compId), pPrivateHdr->eid ); } @@ -901,7 +901,7 @@ int main( int argc, char *argv[] ) { // Write the native PEL to a temporary file // for x86 errl tool to display. - sprintf( szTmpFilename, "/tmp/pel%d.bin", pPrivateHdr->eid ); + sprintf( szTmpFilename, "/tmp/pel%X.bin", pPrivateHdr->eid ); int fd = open( szTmpFilename, O_RDWR | O_CREAT , 0664 ); if( -1 == fd ) @@ -974,7 +974,7 @@ int main( int argc, char *argv[] ) if( fExtractPEL ) { // Write the native PEL to a temporary file for debug later. - sprintf( szTmpFilename, "%s/pel%d.bin", pszOutputDir, pPrivateHdr->eid ); + sprintf( szTmpFilename, "%s/pel%X.bin", pszOutputDir, pPrivateHdr->eid ); int fd = open( szTmpFilename, O_RDWR | O_CREAT , 0664 ); if( -1 == fd ) diff --git a/src/usr/hwpf/test/hwpisteperrortest.H b/src/usr/hwpf/test/hwpisteperrortest.H index ba75d18ea..0af67a776 100644 --- a/src/usr/hwpf/test/hwpisteperrortest.H +++ b/src/usr/hwpf/test/hwpisteperrortest.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -72,30 +72,34 @@ public: uint64_t l_data0 = new_errl->getUserData1(); - uint32_t eid = ( l_data0 & 0xFFFFFFF00000000) >> 32; + uint32_t eid = ( l_data0 & 0xFFFFFFFF00000000) >> 32; uint32_t reason = (uint32_t)(l_data0 & 0x00000000FFFFFFFF); if( eid != l_errl->eid() ) { - TS_FAIL("expected eid == l_errl->eid() " - "eid rebuilt from user data of " - "IStepError did not match original error eid"); + TS_FAIL("testIstepError1: expected" + "eid[0x%.8x] == l_errl->eid()[0x%.8x] " + "eid rebuilt from user data of " + "IStepError did not match original error eid", + eid, l_errl->eid()); } else { - TS_TRACE("passed: eid == l_errl->eid()"); + TS_TRACE("testIstepError1: passed: eid == l_errl->eid()"); } if( reason != l_errl->reasonCode() ) { - TS_FAIL("expected reasonCode == l_errl->reasonCode() \ + TS_FAIL("testIstepError1: " + "expected reasonCode == l_errl->reasonCode() \ reasonCode rebuilt from user data of \ IStepError did not match original reasoncode"); } else { - TS_TRACE("passed: reason == l_errl->reasonCode()"); + TS_TRACE("testIstepError1: passed: " + "reason == l_errl->reasonCode()"); } @@ -179,30 +183,34 @@ public: uint64_t l_data0 = new_errl->getUserData1(); - uint32_t eid = ( l_data0 & 0xFFFFFFF00000000) >> 32; + uint32_t eid = ( l_data0 & 0xFFFFFFFF00000000) >> 32; uint32_t reason = (uint32_t)(l_data0 & 0x00000000FFFFFFFF); if( eid != l_errl->eid() ) { - TS_FAIL("expected eid == l_errl->eid() " - "eid rebuilt from user data of " - "IStepError did not match original error eid"); + TS_FAIL("testIStepError2: expected " + "eid[0x%.8x] == l_errl->eid()[0x%.8x] " + "eid rebuilt from user data of " + "IStepError did not match original error eid", + eid, l_errl->eid()); } else { - TS_TRACE("passed: eid == l_errl->eid()"); + TS_TRACE("testIStepError2: passed: eid == l_errl->eid()"); } if( reason != l_errl->reasonCode() ) { - TS_FAIL("expected reasonCode == l_errl->reasonCode()" - "reasonCode rebuilt from user data of" - "IStepError did not match original reasoncode"); + TS_FAIL("testIStepError2: " + "expected reasonCode == l_errl->reasonCode()" + "reasonCode rebuilt from user data of" + "IStepError did not match original reasoncode"); } else { - TS_TRACE("passed: reason == l_errl->reasonCode()"); + TS_TRACE("testIStepError2: passed: " + "reason == l_errl->reasonCode()"); } // verify that we counted the error we added diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index 94e98ba99..03159fb15 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ /* */ /* p1 */ /* */ @@ -371,54 +371,63 @@ errlHndl_t PnorRP::readTOC() //TODO: verify checksum of header RTC: 44147 - TRACFCOMP(g_trac_pnor, "PnorRp::readTOC: FFS Block size = 0x%.8X, Partition Table Size = 0x%.8x, entry_count=%d", l_ffs_hdr->block_size, l_ffs_hdr->size, l_ffs_hdr->entry_count); + TRACFCOMP(g_trac_pnor, "PnorRp::readTOC: FFS Block size = 0x%.8X, Partition Table Size = 0x%.8x, entry_count=%d", + l_ffs_hdr->block_size, l_ffs_hdr->size, l_ffs_hdr->entry_count); + + uint64_t spaceUsed = (sizeof(ffs_entry))*l_ffs_hdr->entry_count; /* Checking FFS Header to make sure it looks valid */ - //TODO: Leave FFDC Breadcrumbs before issuing critical assert in the checks below.. RTC: 44146. + bool header_good = true; if(l_ffs_hdr->magic != FFS_MAGIC) { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Invalid magic number in FFS header: 0x%.4X", l_ffs_hdr->magic); - crit_assert(0); + TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Invalid magic number in FFS header: 0x%.4X", + l_ffs_hdr->magic); + header_good = false; } - - if(l_ffs_hdr->version != SUPPORTED_FFS_VERSION) + else if(l_ffs_hdr->version != SUPPORTED_FFS_VERSION) { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported FFS Header version: 0x%.4X", l_ffs_hdr->version); - crit_assert(0); + TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported FFS Header version: 0x%.4X", + l_ffs_hdr->version); + header_good = false; } - - if(l_ffs_hdr->entry_size != sizeof(ffs_entry)) + else if(l_ffs_hdr->entry_size != sizeof(ffs_entry)) { TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unexpected entry_size(0x%.8x) in FFS header: 0x%.4X", l_ffs_hdr->entry_size); - crit_assert(0); + header_good = false; } - - if(l_ffs_hdr->entries == NULL) + else if(l_ffs_hdr->entries == NULL) { TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: FFS Header pointer to entries is NULL."); - crit_assert(0); + header_good = false; } - - if(l_ffs_hdr->block_size != PAGESIZE) + else if(l_ffs_hdr->block_size != PAGESIZE) { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported Block Size(0x%.4X). PNOR Blocks must be 4k", l_ffs_hdr->block_size); - crit_assert(0); + TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported Block Size(0x%.4X). PNOR Blocks must be 4k", + l_ffs_hdr->block_size); + header_good = false; } - - if(l_ffs_hdr->block_count == 0) + else if(l_ffs_hdr->block_count == 0) { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported BLock COunt(0x%.4X). Device cannot be zero blocks in length.", l_ffs_hdr->block_count); - crit_assert(0); + TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported BLock COunt(0x%.4X). Device cannot be zero blocks in length.", + l_ffs_hdr->block_count); + header_good = false; } - //Make sure all the entries fit in specified partition table size. - uint64_t spaceUsed = (sizeof(ffs_entry))*l_ffs_hdr->entry_count; - if(spaceUsed > ((l_ffs_hdr->block_size * l_ffs_hdr->size) - sizeof(ffs_hdr))) + else if(spaceUsed > + ((l_ffs_hdr->block_size * l_ffs_hdr->size) - sizeof(ffs_hdr))) { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: FFS Entries (0x%.16X) go past end of FFS Table.", spaceUsed); + TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: FFS Entries (0x%.16X) go past end of FFS Table.", + spaceUsed); crit_assert(0); } + if(!header_good) + { + //Shutdown if we detected a partition table issue for any reason + INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); + while(1) { task_yield(); } + } + ffs_hb_user_t* ffsUserData = NULL; //Walk through all the entries in the table and parse the data. @@ -480,8 +489,10 @@ errlHndl_t PnorRP::readTOC() if((iv_TOC[cur_side][secId].flashAddr + iv_TOC[cur_side][secId].size) > (l_ffs_hdr->block_count*PAGESIZE)) { - TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Partition(%s) at base address (0x%.8x) extends past end of flash device", cur_entry->name, iv_TOC[cur_side][secId].flashAddr); - crit_assert(0); + TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Partition(%s) at base address (0x%.8x) extends past end of flash device", + cur_entry->name, iv_TOC[cur_side][secId].flashAddr); + INITSERVICE::doShutdown( PNOR::RC_PARTITION_TABLE_INVALID); + while(1) { task_yield(); } } cur_entry++; |