diff options
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/errl/plugins/errludcallout.H | 5 | ||||
-rw-r--r-- | src/usr/errldisplay/errldisplay.C | 1 | ||||
-rw-r--r-- | src/usr/hwas/HBconfig | 6 | ||||
-rw-r--r-- | src/usr/hwas/common/deconfigGard.C | 59 | ||||
-rw-r--r-- | src/usr/hwas/hwasPlatCallout.C | 22 | ||||
-rw-r--r-- | src/usr/hwas/hwasPlatDeconfigGard.C | 8 | ||||
-rw-r--r-- | src/usr/isteps/istep06/host_set_ipl_parms.C | 44 | ||||
-rw-r--r-- | src/usr/isteps/istep16/call_host_ipl_complete.C | 23 | ||||
-rw-r--r-- | src/usr/pnor/pnor_utils.C | 1 | ||||
-rw-r--r-- | src/usr/util/makefile | 1 | ||||
-rw-r--r-- | src/usr/util/utilsemipersist.C | 136 |
11 files changed, 294 insertions, 12 deletions
diff --git a/src/usr/errl/plugins/errludcallout.H b/src/usr/errl/plugins/errludcallout.H index 10cc3af96..a1cb7dfe6 100644 --- a/src/usr/errl/plugins/errludcallout.H +++ b/src/usr/errl/plugins/errludcallout.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2016 */ +/* Contributors Listed Below - COPYRIGHT 2013,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -114,6 +114,7 @@ case HWAS::_type: i_parser.PrintString( "GARD Error Type", #_type); break; case_GARD_ERROR_TYPE(GARD_Predictive) case_GARD_ERROR_TYPE(GARD_Power) case_GARD_ERROR_TYPE(GARD_PHYP) + case_GARD_ERROR_TYPE(GARD_Reconfig) case_GARD_ERROR_TYPE(GARD_Void) default: i_parser.PrintNumber( "Deconfig State", "UNKNOWN: 0x%X", @@ -171,6 +172,7 @@ case HWAS::_type: i_parser.PrintString( "GARD Error Type", #_type); break; case_GARD_ERROR_TYPE(GARD_Predictive) case_GARD_ERROR_TYPE(GARD_Power) case_GARD_ERROR_TYPE(GARD_PHYP) + case_GARD_ERROR_TYPE(GARD_Reconfig) case_GARD_ERROR_TYPE(GARD_Void) default: i_parser.PrintNumber( "Deconfig State", "UNKNOWN: 0x%X", @@ -246,6 +248,7 @@ case HWAS::_type: i_parser.PrintString( "GARD Error Type", #_type); break; case_GARD_ERROR_TYPE(GARD_Predictive) case_GARD_ERROR_TYPE(GARD_Power) case_GARD_ERROR_TYPE(GARD_PHYP) + case_GARD_ERROR_TYPE(GARD_Reconfig) case_GARD_ERROR_TYPE(GARD_Void) default: i_parser.PrintNumber( "Deconfig State", "UNKNOWN: 0x%X", diff --git a/src/usr/errldisplay/errldisplay.C b/src/usr/errldisplay/errldisplay.C index 3cb40d6f9..305ddfd3d 100644 --- a/src/usr/errldisplay/errldisplay.C +++ b/src/usr/errldisplay/errldisplay.C @@ -432,6 +432,7 @@ case HWAS::_type: CONSOLE::displayf(NULL, " GARD Error Type : %s", #_t case_GARD_ERROR_TYPE(GARD_Predictive) case_GARD_ERROR_TYPE(GARD_Power) case_GARD_ERROR_TYPE(GARD_PHYP) + case_GARD_ERROR_TYPE(GARD_Reconfig) case_GARD_ERROR_TYPE(GARD_Void) default: CONSOLE::displayf(NULL, " GARD Error Type : UNKNOWN: 0x%X", diff --git a/src/usr/hwas/HBconfig b/src/usr/hwas/HBconfig index 8f6791be4..f219e3ec6 100644 --- a/src/usr/hwas/HBconfig +++ b/src/usr/hwas/HBconfig @@ -3,6 +3,12 @@ config NO_GARD_SUPPORT help Skip guarding when set +config RECALL_DECONFIG_ON_RECONFIG + default n + help + Remember both garded and deconfigured parts on a reconfig loop. + Normally only garded parts are remembered. + config HOST_HCDB_SUPPORT default n depends on MEMVPD_READ_FROM_HW || MVPD_READ_FROM_HW || DJVPD_READ_FROM_HW diff --git a/src/usr/hwas/common/deconfigGard.C b/src/usr/hwas/common/deconfigGard.C index 6f1925b9c..82ee77aff 100644 --- a/src/usr/hwas/common/deconfigGard.C +++ b/src/usr/hwas/common/deconfigGard.C @@ -105,6 +105,12 @@ errlHndl_t collectGard(const PredicateBase *i_pPredicate) } return errl; } // collectGard + +errlHndl_t clearGardByType(const GARD_ErrorType i_type) +{ + return theDeconfigGard().clearGardRecordsByType(i_type); +} + #endif //****************************************************************************** @@ -190,7 +196,7 @@ errlHndl_t DeconfigGard::applyGardRecord(Target *i_pTarget, //****************************************************************************** errlHndl_t DeconfigGard::clearGardRecordsForReplacedTargets() { - HWAS_INF("User Request: Clear GARD Records for replaced Targets"); + HWAS_INF("Clear GARD Records for replaced Targets"); errlHndl_t l_pErr = NULL; // Create the predicate with HWAS changed state and our GARD bit @@ -355,6 +361,57 @@ errlHndl_t DeconfigGard::clearGardRecordsForReplacedTargets() } // clearGardRecordsForReplacedTargets //****************************************************************************** +errlHndl_t DeconfigGard::clearGardRecordsByType(const GARD_ErrorType i_type) +{ + HWAS_INF("Clear GARD Records by type %x", i_type); + errlHndl_t l_pErr = nullptr; + + do + { + GardRecords_t l_gardRecords; + l_pErr = platGetGardRecords(nullptr, l_gardRecords); + if (l_pErr) + { + HWAS_ERR("Error from platGetGardRecords"); + break; + } + + // For each GARD Record + for (const auto & l_gardRecord : l_gardRecords) + { + //If this is the type to clear + if(l_gardRecord.iv_errorType == i_type) + { + // Find the associated Target + Target* l_pTarget = targetService(). + toTarget(l_gardRecord.iv_targetId); + + if (l_pTarget == nullptr) + { + // could be a platform specific target for the other + // ie, we are hostboot and this is an FSP target, or + // vice-versa + // we just skip this GARD record + continue; + } + + l_pErr = platClearGardRecords(l_pTarget); + if (l_pErr) + { + HWAS_ERR("Error from platClearGardRecords"); + break; + } + + } + } + } + while (0); + + return l_pErr; +} // clearGardRecordsByType + + +//****************************************************************************** errlHndl_t DeconfigGard::deconfigureTargetsFromGardRecordsForIpl( const PredicateBase *i_pPredicate) { diff --git a/src/usr/hwas/hwasPlatCallout.C b/src/usr/hwas/hwasPlatCallout.C index 2385434cc..5c6f8e687 100644 --- a/src/usr/hwas/hwasPlatCallout.C +++ b/src/usr/hwas/hwasPlatCallout.C @@ -97,9 +97,18 @@ errlHndl_t platHandleHWCallout( } default: { + +#ifndef CONFIG_NO_GARD_SUPPORT errl = HWAS::theDeconfigGard().platCreateGardRecord(i_pTarget, io_errl->eid(), i_gardErrorType); +#elif CONFIG_RECALL_DECONFIG_ON_RECONFIG + //If Gard is turned off, always populate a reconfig type + //in case of a reconfig loop + errl = HWAS::theDeconfigGard() + .platCreateGardRecord(i_pTarget,io_errl->eid(), + GARD_Reconfig); +#endif break; } } // switch i_gardErrorType @@ -115,6 +124,19 @@ errlHndl_t platHandleHWCallout( // call HWAS common function errl = HWAS::theDeconfigGard().deconfigureTarget(*i_pTarget, io_errl->eid()); + +#ifdef CONFIG_RECALL_DECONFIG_ON_RECONFIG + //Always force a gard record on deconfig. If already + //garded, won't update/harm anything + if(!errl) + { + errl = HWAS::theDeconfigGard() + .platCreateGardRecord(i_pTarget, + io_errl->eid(), + GARD_Reconfig); + } +#endif + break; } case (DELAYED_DECONFIG): diff --git a/src/usr/hwas/hwasPlatDeconfigGard.C b/src/usr/hwas/hwasPlatDeconfigGard.C index b98fa28d8..6c8aa27d5 100644 --- a/src/usr/hwas/hwasPlatDeconfigGard.C +++ b/src/usr/hwas/hwasPlatDeconfigGard.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2016 */ +/* Contributors Listed Below - COPYRIGHT 2013,2017 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -91,7 +91,6 @@ errlHndl_t DeconfigGard::platClearGardRecords( { errlHndl_t l_pErr = NULL; -#ifndef CONFIG_NO_GARD_SUPPORT EntityPath l_targetId; if (!i_pTarget) { @@ -144,7 +143,6 @@ errlHndl_t DeconfigGard::platClearGardRecords( } HWAS_MUTEX_UNLOCK(iv_mutex); -#endif // CONFIG_NO_GARD_SUPPORT return l_pErr; } @@ -155,7 +153,6 @@ errlHndl_t DeconfigGard::platGetGardRecords( errlHndl_t l_pErr = NULL; o_records.clear(); -#ifndef CONFIG_NO_GARD_SUPPORT EntityPath l_targetId; if (!i_pTarget) { @@ -201,7 +198,6 @@ errlHndl_t DeconfigGard::platGetGardRecords( HWAS_MUTEX_UNLOCK(iv_mutex); HWAS_INF("Get returning %d GARD Records", o_records.size()); -#endif // CONFIG_NO_GARD_SUPPORT return l_pErr; } @@ -215,7 +211,6 @@ errlHndl_t DeconfigGard::platCreateGardRecord( get_huid(i_pTarget), i_errlEid); errlHndl_t l_pErr = NULL; -#ifndef CONFIG_NO_GARD_SUPPORT HWAS_MUTEX_LOCK(iv_mutex); do @@ -396,7 +391,6 @@ errlHndl_t DeconfigGard::platCreateGardRecord( while (0); HWAS_MUTEX_UNLOCK(iv_mutex); -#endif // CONFIG_NO_GARD_SUPPORT return l_pErr; } diff --git a/src/usr/isteps/istep06/host_set_ipl_parms.C b/src/usr/isteps/istep06/host_set_ipl_parms.C index b7c5aec3b..8fe9f12cc 100644 --- a/src/usr/isteps/istep06/host_set_ipl_parms.C +++ b/src/usr/isteps/istep06/host_set_ipl_parms.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* Contributors Listed Below - COPYRIGHT 2015,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -29,6 +29,9 @@ #include <errl/errlmanager.H> #include <isteps/hwpisteperror.H> #include <initservice/isteps_trace.H> +#include <util/utilsemipersist.H> +#include <hwas/common/deconfigGard.H> + namespace ISTEP_06 { @@ -36,10 +39,45 @@ namespace ISTEP_06 void* host_set_ipl_parms( void *io_pArgs ) { ISTEP_ERROR::IStepError l_stepError; + errlHndl_t l_err; + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_set_ipl_parms entry" ); + + //Read out the semi persistent area. + Util::semiPersistData_t l_semiData; + Util::readSemiPersistData(l_semiData); + + // If magic number set, then this is warm reboot: + // 1) increment boot count + if(l_semiData.magic == Util::PERSIST_MAGIC) + { + l_semiData.reboot_cnt++; + } + // else magic number is not set, then this is first, cold boot: + // 1) set magic num, boot count + // 2) clear all gard records of type GARD_Reconfig + else + { + memset(&l_semiData, 0x0, sizeof(Util::semiPersistData_t)); + l_semiData.magic = Util::PERSIST_MAGIC; + + l_err = HWAS::clearGardByType(HWAS::GARD_Reconfig); + if (l_err) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X: clearGardByType( )", + l_err->reasonCode() ); + // Create IStep error log and cross ref error that occurred + l_stepError.addErrorDetails( l_err ); + errlCommit( l_err, ISTEP_COMP_ID ); + } + } + + //Write update data back out + Util::writeSemiPersistData(l_semiData); - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_set_ipl_parms entry" ); - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_set_ipl_parms exit" ); + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_set_ipl_parms exit" ); return l_stepError.getErrorHandle(); } diff --git a/src/usr/isteps/istep16/call_host_ipl_complete.C b/src/usr/isteps/istep16/call_host_ipl_complete.C index 1242367ef..87eca889b 100644 --- a/src/usr/isteps/istep16/call_host_ipl_complete.C +++ b/src/usr/isteps/istep16/call_host_ipl_complete.C @@ -46,6 +46,9 @@ #include <runtime/runtime.H> #include <util/utiltce.H> +#include <util/utilsemipersist.H> +#include <hwas/common/deconfigGard.H> + using namespace ERRORLOG; using namespace TARGETING; using namespace ISTEP; @@ -64,6 +67,26 @@ void* call_host_ipl_complete (void *io_pArgs) "call_host_ipl_complete entry" ); do { + //No more reconfig loops are supported from this point + //forward. Clean up the semi persistent area + // 1) clear magic number (so next boot thinks it is cold) + // 2) clear any reconfig specific gard records + Util::semiPersistData_t l_semiData; //inits to 0s + Util::writeSemiPersistData(l_semiData); + + l_err = HWAS::clearGardByType(HWAS::GARD_Reconfig); + if (l_err) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X: clearGardByType( )", + l_err->reasonCode() ); + // Create IStep error log and cross ref error that occurred + l_stepError.addErrorDetails( l_err ); + errlCommit( l_err, ISTEP_COMP_ID ); + } + + + // Setup the TCEs needed for the FSP to DMA the PAYLOAD /* @TODO RTC 168745 - make this call when FSP is ready for TCE Support * and add check that we're on a FSP system diff --git a/src/usr/pnor/pnor_utils.C b/src/usr/pnor/pnor_utils.C index 51627de40..b211b375b 100644 --- a/src/usr/pnor/pnor_utils.C +++ b/src/usr/pnor/pnor_utils.C @@ -443,6 +443,7 @@ const char * PNOR::SectionIdToString( uint32_t i_secIdIndex ) "RINGOVD", /**< PNOR::RINGOVD : Ring overrides */ "WOFDATA", /**< PNOR::WOFDATA : VFRT data tables for WOF */ "SBKT", /**< PNOR::SBKT : SecureBoot Key Transition */ + "HB_VOLATILE", /**< PNOR::HB_VOLATILE : Semi volatile partition */ #endif }; diff --git a/src/usr/util/makefile b/src/usr/util/makefile index 0c3e100cb..3c8e04183 100644 --- a/src/usr/util/makefile +++ b/src/usr/util/makefile @@ -34,6 +34,7 @@ OBJS += utillidmgr.o OBJS += utillidpnor.o OBJS += utilmbox_scratch.o OBJS += utiltcemgr.o +OBJS += utilsemipersist.o SUBDIRS += test.d SUBDIRS += runtime.d diff --git a/src/usr/util/utilsemipersist.C b/src/usr/util/utilsemipersist.C new file mode 100644 index 000000000..28ce93936 --- /dev/null +++ b/src/usr/util/utilsemipersist.C @@ -0,0 +1,136 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/util/utilsemipersist.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file utilsemipersist.C + * + * @brief Abstraction of semi volatile pnor partition + * + * Used for creating and manipulating streams + */ + +/*****************************************************************************/ +// I n c l u d e s +/*****************************************************************************/ +#include <trace/interface.H> +#include <limits.h> +#include <util/util_reasoncodes.H> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <pnor/pnorif.H> +#include <sys/mm.h> +#include <util/utilsemipersist.H> +#include "utilbase.H" +trace_desc_t* g_trac_persist = nullptr; +TRAC_INIT(&g_trac_persist, "UTIL_PERSIST", KILOBYTE); + +using namespace ERRORLOG; + +namespace Util +{ + + // ---------------------------------------------- + // Globals + // ---------------------------------------------- + mutex_t g_PersistMutex = MUTEX_INITIALIZER; + + semiPersistData_t * getHbVolatile() + { + errlHndl_t l_err = nullptr; + uint64_t l_vaddr = 0x0; + static uint64_t g_HbVolatileAddr = 0x0; + + do + { + if(g_HbVolatileAddr) + { + l_vaddr = g_HbVolatileAddr; + break; + } + + PNOR::SectionInfo_t l_pnorHbVolatile; + l_err = PNOR::getSectionInfo(PNOR::HB_VOLATILE, l_pnorHbVolatile); + if(l_err) + { + delete l_err; + l_err = nullptr; + TRACFCOMP( g_trac_persist, + INFO_MRK"getHbVolatile(): HB_VOLATILE section not" + " found, it is optional"); + break; + } + if(l_pnorHbVolatile.size == 0) + { + TRACFCOMP( g_trac_persist, + INFO_MRK"getHbVolatile(): HB_VOLATILE section is" + " empty in PNOR"); + break; + } + + g_HbVolatileAddr = l_pnorHbVolatile.vaddr; + l_vaddr = g_HbVolatileAddr; + + }while(0); + + return reinterpret_cast<semiPersistData_t*>(l_vaddr); + } + + void readSemiPersistData(semiPersistData_t & o_data) + { + memset(&o_data, 0x0, sizeof(semiPersistData_t)); + + //Lock to prevent concurrent access + mutex_lock(&g_PersistMutex); + + auto l_data = getHbVolatile(); + if(l_data) + { + o_data = *l_data; + } + + mutex_unlock(&g_PersistMutex); + } + + void writeSemiPersistData(const semiPersistData_t i_data) + { + //Lock to prevent concurrent access + mutex_lock(&g_PersistMutex); + + auto l_data = getHbVolatile(); + if(l_data) + { + *l_data = i_data; + int l_rc = mm_remove_pages(FLUSH, l_data, + sizeof(semiPersistData_t)); + if (l_rc) + { + TRACFCOMP(g_trac_persist, + ERR_MRK"writeSemiPersistData(): mm_remove_pages" + "(FLUSH,%p,%d) returned %d",l_data, + sizeof(semiPersistData_t),l_rc); + } + } + mutex_unlock(&g_PersistMutex); + } +}; |