diff options
author | crgeddes <crgeddes@us.ibm.com> | 2016-08-24 09:52:10 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-08-29 11:13:41 -0400 |
commit | a24586804c3bdf9506c8af79e1adc69d0b478366 (patch) | |
tree | b95191fa2b9e9cba82894473007b81e353f850e7 /src/usr/pnor/pnorrp.C | |
parent | c18640be25f0fe65971fe6f95d482d0c8264b98f (diff) | |
download | talos-hostboot-a24586804c3bdf9506c8af79e1adc69d0b478366.tar.gz talos-hostboot-a24586804c3bdf9506c8af79e1adc69d0b478366.zip |
Update pnorrp to only attempt to parse TOC if its at a valid offset
In the gensis case for pnor generation they were not creating a backup
toc in pnor. This caused pnorrp to fail because it was attempting to
parse garbage. Our error logs should have caught this but it exposed
a bug in the errlmanager code that tried to call targeting code before
the extended image had been loaded
Change-Id: Iedbb03a9d5a3c842c9497121268d170ab623d075
RTC: 159832
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28729
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Reviewed-by: Matt Derksen <v2cibmd@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/pnor/pnorrp.C')
-rw-r--r-- | src/usr/pnor/pnorrp.C | 79 |
1 files changed, 42 insertions, 37 deletions
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index c6a4880c1..0c1feea77 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -738,10 +738,13 @@ errlHndl_t PnorRP::findTOC() errlHndl_t PnorRP::readTOC() { TRACUCOMP(g_trac_pnor, "PnorRP::readTOC>" ); - errlHndl_t l_errhdl = NULL; - errlHndl_t l_secondary_errhdl = NULL; + errlHndl_t l_errhdl = nullptr; + errlHndl_t l_primary_errhdl = nullptr; + errlHndl_t l_secondary_errhdl = nullptr; + uint8_t* toc0Buffer = new uint8_t[PAGESIZE]; uint8_t* toc1Buffer = new uint8_t[PAGESIZE]; + PNOR::SectionData_t l_secondary_TOC[PNOR::NUM_SECTIONS+1]; uint64_t fatal_error = 0; do { //Initialize toc bufferes to invalid value @@ -749,7 +752,7 @@ errlHndl_t PnorRP::readTOC() //then parseTOC will see invalid data memset(toc0Buffer, 0xFF, PAGESIZE); memset(toc1Buffer, 0xFF, PAGESIZE); - + //If the first toc is at a valid offset try to read and parse it if (iv_TocOffset[WORKING].first != INVALID_OFFSET) { l_errhdl = readFromDevice(iv_TocOffset[WORKING].first, 0, false, @@ -759,8 +762,12 @@ errlHndl_t PnorRP::readTOC() TRACFCOMP(g_trac_pnor,"readTOC:readFromDevice failed for TOC0"); break; } - } + l_primary_errhdl = PNOR::parseTOC(toc0Buffer, iv_TOC); + //For now assume TOC_0 worked and we are using it + iv_TOC_used = TOC_0; + } + //If the second toc is at a valid offset try to read and parse it if (iv_TocOffset[WORKING].second != INVALID_OFFSET) { l_errhdl = readFromDevice(iv_TocOffset[WORKING].second, 0, false, @@ -770,45 +777,40 @@ errlHndl_t PnorRP::readTOC() TRACFCOMP(g_trac_pnor,"readTOC:readFromDevice failed for TOC1"); break; } - } - //In order to track errors we will always parse both TOCs - l_errhdl = PNOR::parseTOC(toc0Buffer, iv_TOC); - PNOR::SectionData_t l_secondary_TOC[PNOR::NUM_SECTIONS+1]; - l_secondary_errhdl = PNOR::parseTOC(toc1Buffer, l_secondary_TOC); + l_secondary_errhdl = PNOR::parseTOC(toc1Buffer, l_secondary_TOC); + } - //If there is no error in the primary TOC - if(!l_errhdl) + //if at least one of them is good, only report errors as informational + if((l_primary_errhdl != nullptr) && (l_secondary_errhdl == nullptr)) { - //Then we use the primary TOC - iv_TOC_used = TOC_0; - //If we found an error in the secondary TOC - if(l_secondary_errhdl) - { + //Found an error in primary TOC, report it + //@TODO RTC:144079 Try to fix PNOR for detected TOC failures - //Set the error severity to INFORMATIONAL and commit it - l_secondary_errhdl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL); - errlCommit(l_secondary_errhdl, PNOR_COMP_ID); - } + //Set the error severity to INFORMATIONAL + l_primary_errhdl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL); + //commit error logs for corrupted TOC + errlCommit(l_primary_errhdl, PNOR_COMP_ID); + + //use the secondary TOC if first is bad + iv_TOC_used = TOC_1; + memcpy(iv_TOC, l_secondary_TOC, (sizeof(l_secondary_TOC))); } - //Otherwise if the secondary TOC has no error - else if(!l_secondary_errhdl) + //If we found an error in the secondary TOC + else if((l_secondary_errhdl != nullptr) && (l_primary_errhdl == nullptr)) { - //then we will use the secondary TOC instead - iv_TOC_used = TOC_1; - memcpy(iv_TOC, l_secondary_TOC, (sizeof(l_secondary_TOC))); - //Set the error severity to INFORMATIONAL for the primaryTOC error - // and commit it - //@TODO RTC:144079: Try to fix PNOR for detected TOC failures - l_errhdl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL); - errlCommit(l_errhdl, PNOR_COMP_ID); + //@TODO RTC:144079 Try to fix PNOR for detected TOC failures + //Set the error severity to INFORMATIONAL + l_secondary_errhdl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL); + //commit error logs for corrupted TOC + errlCommit(l_secondary_errhdl, PNOR_COMP_ID); } - //In the case that both TOCs, have errors shut down the system - else + //In the case that both TOCs failing, have errors shut down the system + else if(l_primary_errhdl != nullptr && l_secondary_errhdl != nullptr) { //commit both error logs for each corrupted TOC - l_errhdl->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE); - errlCommit(l_errhdl, PNOR_COMP_ID); + l_primary_errhdl->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE); + errlCommit(l_primary_errhdl, PNOR_COMP_ID); l_secondary_errhdl->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE); errlCommit(l_secondary_errhdl, PNOR_COMP_ID); TRACFCOMP(g_trac_pnor, "readTOC: parseTOC failed"); @@ -816,20 +818,23 @@ errlHndl_t PnorRP::readTOC() INITSERVICE::doShutdown(PNOR::RC_PARTITION_TABLE_INVALID); } + //Set the virtual addresses for the different sections of pnor + //so the resource provider has it ready for later use l_errhdl = setVirtAddrs(); + if (l_errhdl) { - TRACFCOMP(g_trac_pnor, "readTOC: Failed to set vaddr in TOC"); + TRACFCOMP(g_trac_pnor, "readTOC: Failed to set virtual addresses in TOC"); INITSERVICE::doShutdown(PNOR::RC_PNOR_SET_VADDR_FAILED); } } while (0); - if(toc0Buffer != NULL) + if(toc0Buffer != nullptr) { delete[] toc0Buffer; } - if(toc1Buffer != NULL) + if(toc1Buffer != nullptr) { delete[] toc1Buffer; } |