summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/hwas/common/deconfigGard.H22
-rw-r--r--src/include/usr/hwas/common/hwasCallout.H1
-rw-r--r--src/include/usr/pnor/pnor_const.H1
-rw-r--r--src/include/usr/util/utilsemipersist.H83
-rw-r--r--src/usr/errl/plugins/errludcallout.H5
-rw-r--r--src/usr/errldisplay/errldisplay.C1
-rw-r--r--src/usr/hwas/HBconfig6
-rw-r--r--src/usr/hwas/common/deconfigGard.C59
-rw-r--r--src/usr/hwas/hwasPlatCallout.C22
-rw-r--r--src/usr/hwas/hwasPlatDeconfigGard.C8
-rw-r--r--src/usr/isteps/istep06/host_set_ipl_parms.C44
-rw-r--r--src/usr/isteps/istep16/call_host_ipl_complete.C23
-rw-r--r--src/usr/pnor/pnor_utils.C1
-rw-r--r--src/usr/util/makefile1
-rw-r--r--src/usr/util/utilsemipersist.C136
15 files changed, 401 insertions, 12 deletions
diff --git a/src/include/usr/hwas/common/deconfigGard.H b/src/include/usr/hwas/common/deconfigGard.H
index 0c133f427..2cdc5fd26 100644
--- a/src/include/usr/hwas/common/deconfigGard.H
+++ b/src/include/usr/hwas/common/deconfigGard.H
@@ -60,6 +60,19 @@ namespace HWAS
errlHndl_t collectGard(const TARGETING::PredicateBase *i_pPredicate = NULL);
/**
+ * @brief clearGardByType Common HWAS function to clear all GARD records of
+ * given type
+ *
+ * It will call into hwas platform-specific functions.
+ *
+ * @param i_type Type of records to be cleared
+ *
+ * @return errlHndl_t valid errlHndl_t handle if there was an error
+ * NULL if no errors;
+ */
+errlHndl_t clearGardByType(const GARD_ErrorType i_type);
+
+/**
* @brief Returns a reference to the DeconfigGard singleton.
*/
class DeconfigGard;
@@ -239,6 +252,15 @@ public:
errlHndl_t clearGardRecordsForReplacedTargets();
/**
+ * @brief Clears GARD Records that match requested error type
+ *
+ * @param i_type error type to clear
+ *
+ * @return errlHndl_t. Error log handle.
+ */
+ errlHndl_t clearGardRecordsByType(GARD_ErrorType i_type);
+
+ /**
* @brief Deconfigures Targets that have GARD Records in preparation to IPL.
*
* @param i_pPredicate restrict processing - only look at GARD records
diff --git a/src/include/usr/hwas/common/hwasCallout.H b/src/include/usr/hwas/common/hwasCallout.H
index 5b8ffff33..9a729a5ed 100644
--- a/src/include/usr/hwas/common/hwasCallout.H
+++ b/src/include/usr/hwas/common/hwasCallout.H
@@ -57,6 +57,7 @@ typedef enum {
GARD_Predictive = 0xE6, //Policy flag to disable.
GARD_Power = 0xE9, //Needed since EID is NOT passed in.
GARD_PHYP = 0xEA, //Needed since EID is NOT passed in.
+ GARD_Reconfig = 0xEB, //Force deconfig on reconfig loop
GARD_Void = 0xFF
} GARD_ErrorType;
diff --git a/src/include/usr/pnor/pnor_const.H b/src/include/usr/pnor/pnor_const.H
index ae02a2fd2..9f435681d 100644
--- a/src/include/usr/pnor/pnor_const.H
+++ b/src/include/usr/pnor/pnor_const.H
@@ -71,6 +71,7 @@ enum SectionId
RINGOVD, /**< Ring override data */
WOFDATA, /**< VFRT data tables for WOF */
SBKT, /**< SecureBoot Key Transition */
+ HB_VOLATILE, /**< Semi volatile partition for reconfig */
#endif
NUM_SECTIONS, /**< Number of defined sections */
diff --git a/src/include/usr/util/utilsemipersist.H b/src/include/usr/util/utilsemipersist.H
new file mode 100644
index 000000000..82943825e
--- /dev/null
+++ b/src/include/usr/util/utilsemipersist.H
@@ -0,0 +1,83 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/util/utilsemipersist.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,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 */
+#ifndef UTILSEMIPERSIST_H
+#define UTILSEMIPERSIST_H
+
+/**
+ * @file utilsemipersist.H
+ *
+ * @brief Utilies to access the semi persistent memory
+ *
+ *
+ */
+
+/*****************************************************************************/
+// I n c l u d e s
+/*****************************************************************************/
+
+// Utility Includes
+
+/*****************************************************************************/
+// Forwards
+/*****************************************************************************/
+
+//*****************************************************************************/
+// C o n s t a n t s
+/*****************************************************************************/
+namespace Util
+{
+ enum
+ {
+ PERSIST_MAGIC = 0x48425f56, // HB_V
+ };
+
+ struct semiPersistData_t
+ {
+ uint32_t magic; //HB_V
+ uint32_t reboot_cnt; // Number of reboots with valid data
+ semiPersistData_t(): magic(0), reboot_cnt(0) {};
+ } PACKED;
+
+ /**
+ * @brief This function writes data structure to the HB semi persistent
+ * region. Data is flushed to storage once this call returns
+ * @param[in] i_data Structure to write
+ *
+ * @return none
+ */
+ void writeSemiPersistData(const semiPersistData_t i_data);
+
+ /**
+ * @brief This function reads data structure from the HB semi persistent
+ * region. If the region cannot be found it will return 0s for all data.
+ * User must check magic header to know if data is valid
+ * @param[in] o_data Structure to read
+ *
+ * @return none
+ */
+ void readSemiPersistData(semiPersistData_t & o_data);
+};
+
+#endif //UTILMEM_H
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);
+ }
+};
OpenPOWER on IntegriCloud