summaryrefslogtreecommitdiffstats
path: root/src/usr/hwas
diff options
context:
space:
mode:
authorMike Jones <mjjones@us.ibm.com>2011-10-26 14:59:19 -0500
committerMIKE J. JONES <mjjones@us.ibm.com>2011-11-01 12:14:11 -0500
commit5554e9d53859a91b39b01c8f789fe536e4688ecb (patch)
tree8f24ea04634c7aed7e34d7ce6a26326c0e954e8d /src/usr/hwas
parent14cd4e689a68a7440309090d0a6f82d25f8b6984 (diff)
downloadtalos-hostboot-5554e9d53859a91b39b01c8f789fe536e4688ecb.tar.gz
talos-hostboot-5554e9d53859a91b39b01c8f789fe536e4688ecb.zip
Initial Deconfigure and GARD support
Change-Id: I8448480627ad478e8e16377027137e6df410053f Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/460 Tested-by: Jenkins Server Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Diffstat (limited to 'src/usr/hwas')
-rw-r--r--src/usr/hwas/deconfigGard.C692
-rw-r--r--src/usr/hwas/makefile2
-rw-r--r--src/usr/hwas/test/hwasGardTest.H920
3 files changed, 1613 insertions, 1 deletions
diff --git a/src/usr/hwas/deconfigGard.C b/src/usr/hwas/deconfigGard.C
new file mode 100644
index 000000000..e1f42c2c7
--- /dev/null
+++ b/src/usr/hwas/deconfigGard.C
@@ -0,0 +1,692 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/hwas/deconfigGard.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+/**
+ * @file deconfigGard.C
+ *
+ * @brief Implements the DeconfigGard class
+ */
+
+#include <string.h>
+#include <targeting/targetservice.H>
+#include <errl/errlmanager.H>
+#include <hwas/deconfigGard.H>
+#include <hwas/hwas_reasoncodes.H>
+#include <pnor/pnorif.H>
+
+// Trace definition
+trace_desc_t* g_trac_deconf = NULL;
+#define __COMP_TD__ g_trac_deconf
+
+// The DeconfigGard code needs to trace a target. The current recommended way is
+// to get the Target's PHYS_PATH attribute and do a binary trace. However, the
+// size of a TARGETING::EntityPath is 17 bytes. This code will trace only the
+// first 16 bytes to avoid a multi-line binary trace. This all seems a little
+// convoluted. Is there a better way to trace a Target
+#define DG_TRAC_TARGET(string, pPath) \
+ TRACFBIN(g_trac_deconf, string, pPath, sizeof(TARGETING::EntityPath) - 1)
+
+namespace HWAS
+{
+
+//******************************************************************************
+DeconfigGard & theDeconfigGard()
+{
+ return Singleton<DeconfigGard>::instance();
+}
+
+//******************************************************************************
+DeconfigGard::DeconfigGard()
+: iv_nextGardRecordId(0),
+ iv_maxGardRecords(0),
+ iv_pGardRecords(NULL)
+{
+ TRAC_INIT_BUFFER(&g_trac_deconf, "DECONF", 4096);
+ TRAC_INF("DeconfigGard Constructor");
+ mutex_init(&iv_mutex);
+}
+
+//******************************************************************************
+DeconfigGard::~DeconfigGard()
+{
+ TRAC_INF("DeconfigGard Destructor");
+ mutex_destroy(&iv_mutex);
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::clearGardRecordsForReplacedTargets()
+{
+ TRAC_INF("****TBD****Usr Request: Clear GARD Records for replaced Targets");
+ mutex_lock(&iv_mutex);
+ errlHndl_t l_pErr = NULL;
+
+ // TODO
+
+ mutex_unlock(&iv_mutex);
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::deconfigureTargetsFromGardRecordsForIpl()
+{
+ TRAC_INF("****TBD****Usr Request: Deconfigure Targets from GARD Records for IPL");
+ mutex_lock(&iv_mutex);
+ errlHndl_t l_pErr = NULL;
+
+ // TODO
+
+ mutex_unlock(&iv_mutex);
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::deconfigureTarget(TARGETING::Target & i_target,
+ errlHndl_t i_pErr)
+{
+ TRAC_ERR("Usr Request: Deconfigure Target");
+ mutex_lock(&iv_mutex);
+
+ // Caller must pass a valid errlHndl_t
+ assert(i_pErr != NULL);
+
+ // Deconfigure the Target
+ _deconfigureTarget(i_target, i_pErr, DECONFIG_CAUSE_FIRMWARE_REQ);
+
+ // Deconfigure other Targets by association
+ _deconfigureByAssoc(i_target, i_pErr);
+
+ mutex_unlock(&iv_mutex);
+ return NULL;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::createGardRecord(const TARGETING::Target & i_target,
+ errlHndl_t i_pErr,
+ const GardSeverity i_severity)
+{
+ TRAC_ERR("Usr Request: Create GARD Record");
+ mutex_lock(&iv_mutex);
+ errlHndl_t l_pErr = _createGardRecord(i_target, i_pErr, i_severity);
+ mutex_unlock(&iv_mutex);
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::getDeconfigureRecords(
+ const TARGETING::EntityPath * i_pTargetId,
+ DeconfigureRecords_t & o_records) const
+{
+ TRAC_INF("Usr Request: Get Deconfigure Record(s)");
+ mutex_lock(&iv_mutex);
+ _getDeconfigureRecords(i_pTargetId, o_records);
+ mutex_unlock(&iv_mutex);
+ return NULL;
+}
+
+
+//******************************************************************************
+errlHndl_t DeconfigGard::clearGardRecords(const uint32_t i_recordId)
+{
+ TRAC_INF("Usr Request: Clear GARD Record(s) by Record ID");
+ mutex_lock(&iv_mutex);
+ errlHndl_t l_pErr = _clearGardRecords(i_recordId);
+ mutex_unlock(&iv_mutex);
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::clearGardRecords(
+ const TARGETING::EntityPath & i_targetId)
+{
+ TRAC_INF("Usr Request: Clear GARD Record(s) by Target ID");
+ mutex_lock(&iv_mutex);
+ errlHndl_t l_pErr = _clearGardRecords(i_targetId);
+ mutex_unlock(&iv_mutex);
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::getGardRecords(
+ const uint32_t i_recordId,
+ GardRecords_t & o_records)
+{
+ TRAC_INF("Usr Request: Get GARD Record(s) by Record ID");
+ mutex_lock(&iv_mutex);
+ errlHndl_t l_pErr = _getGardRecords(i_recordId, o_records);
+ mutex_unlock(&iv_mutex);
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::getGardRecords(
+ const TARGETING::EntityPath & i_targetId,
+ GardRecords_t & o_records)
+{
+ TRAC_INF("Usr Request: Get GARD Record(s) by Target ID");
+ mutex_lock(&iv_mutex);
+ errlHndl_t l_pErr = _getGardRecords(i_targetId, o_records);
+ mutex_unlock(&iv_mutex);
+ return l_pErr;
+}
+
+//******************************************************************************
+void DeconfigGard::_deconfigureByAssoc(TARGETING::Target & i_target,
+ errlHndl_t i_pErr)
+{
+ TARGETING::EntityPath l_id = i_target.getAttr<TARGETING::ATTR_PHYS_PATH>();
+ DG_TRAC_TARGET(ERR_MRK "****TBD****: Deconfiguring by Association for: ",
+ &l_id);
+
+ // TODO
+}
+
+//******************************************************************************
+void DeconfigGard::_deconfigureTarget(TARGETING::Target & i_target,
+ errlHndl_t i_pErr,
+ const DeconfigCause i_cause)
+{
+ TARGETING::EntityPath l_id = i_target.getAttr<TARGETING::ATTR_PHYS_PATH>();
+ DG_TRAC_TARGET(ERR_MRK "Deconfiguring Target: ", &l_id);
+
+ errlHndl_t l_pErr = NULL;
+
+ if (!i_target.getAttr<TARGETING::ATTR_DECONFIG_GARDABLE>())
+ {
+ // Target is not Deconfigurable. Commit an error
+ TRAC_ERR("Target not Deconfigurable");
+ /*@
+ * @errortype
+ * @moduleid MOD_DECONFIG_GARD
+ * @reasoncode RC_TARGET_NOT_DECONFIGURABLE
+ * @devdesc Attempt to deconfigure a target that is not
+ * deconfigurable
+ */
+ l_pErr = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ MOD_DECONFIG_GARD,
+ RC_TARGET_NOT_DECONFIGURABLE);
+ errlCommit(l_pErr);
+ }
+ else
+ {
+ // Set the Target state to non-functional. The assumption is that it is
+ // not possible for another thread (other than deconfigGard) to be
+ // updating HWAS_STATE concurrently.
+ TARGETING::HwasState l_state =
+ i_target.getAttr<TARGETING::ATTR_HWAS_STATE>();
+
+ if (!l_state.functional)
+ {
+ TRAC_ERR("Target HWAS_STATE already non-functional");
+ }
+ else
+ {
+ TRAC_ERR("Setting Target HWAS_STATE to non-functional");
+ l_state.functional = 0;
+ i_target.setAttr<TARGETING::ATTR_HWAS_STATE>(l_state);
+ }
+
+ // Do any necessary Deconfigure Actions
+ _doDeconfigureActions(i_target);
+
+ // Create a Deconfigure Record
+ _createDeconfigureRecord(i_target, i_pErr, i_cause);
+ }
+}
+
+//******************************************************************************
+void DeconfigGard::_doDeconfigureActions(TARGETING::Target & i_target)
+{
+ // TODO
+}
+
+//******************************************************************************
+void DeconfigGard::_createDeconfigureRecord(
+ const TARGETING::Target & i_target,
+ errlHndl_t i_pErr,
+ const DeconfigCause i_cause)
+{
+ // Get the Target's ID
+ TARGETING::EntityPath l_id = i_target.getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+ // Look for an existing Deconfigure Record for the Target
+ DeconfigureRecordsCItr_t l_itr = iv_deconfigureRecords.begin();
+
+ for (; l_itr != iv_deconfigureRecords.end(); ++l_itr)
+ {
+ if ((*l_itr).iv_targetId == l_id)
+ {
+ break;
+ }
+ }
+
+ if (l_itr != iv_deconfigureRecords.end())
+ {
+ TRAC_ERR("Not creating a Deconfigure Record, one already exists");
+ }
+ else
+ {
+ // Create a DeconfigureRecord
+ TRAC_ERR("Creating a Deconfigure Record");
+
+ DeconfigureRecord l_record;
+ l_record.iv_targetId = l_id;
+ l_record.iv_errlogPlid = 0; // TODO Get PLID from ErrorLog
+ l_record.iv_cause = i_cause;
+ l_record.iv_padding[0] = 0;
+ l_record.iv_padding[1] = 0;
+ l_record.iv_padding[2] = 0;
+ l_record.iv_deconfigureTime = 0; // TODO Get epoch time
+
+ iv_deconfigureRecords.push_back(l_record);
+ }
+}
+
+//******************************************************************************
+void DeconfigGard::_clearDeconfigureRecords(
+ const TARGETING::EntityPath * i_pTargetId)
+{
+ if (i_pTargetId == NULL)
+ {
+ TRAC_INF("Clearing all %d Deconfigure Records",
+ iv_deconfigureRecords.size());
+ iv_deconfigureRecords.clear();
+ }
+ else
+ {
+ // Look for a Deconfigure Record for the specified Target (there can
+ // only be one record)
+ bool l_foundRecord = false;
+
+ for (DeconfigureRecordsItr_t l_itr = iv_deconfigureRecords.begin();
+ l_itr != iv_deconfigureRecords.end(); ++l_itr)
+ {
+ if ((*l_itr).iv_targetId == *i_pTargetId)
+ {
+ DG_TRAC_TARGET(INFO_MRK "Clearing Deconfigure Record for: ",
+ i_pTargetId);
+ iv_deconfigureRecords.erase(l_itr);
+ l_foundRecord = true;
+ break;
+ }
+ }
+
+ if (!l_foundRecord)
+ {
+ DG_TRAC_TARGET(INFO_MRK "Did not find a Deconfigure Record to clear for: ",
+ i_pTargetId);
+ }
+ }
+}
+
+//******************************************************************************
+void DeconfigGard::_getDeconfigureRecords(
+ const TARGETING::EntityPath * i_pTargetId,
+ DeconfigureRecords_t & o_records) const
+{
+ DeconfigureRecordsCItr_t l_itr = iv_deconfigureRecords.begin();
+ o_records.clear();
+
+ if (i_pTargetId == NULL)
+ {
+ TRAC_INF("Getting all %d Deconfigure Records",
+ iv_deconfigureRecords.size());
+
+ for (; l_itr != iv_deconfigureRecords.end(); ++l_itr)
+ {
+ o_records.push_back(*l_itr);
+ }
+ }
+ else
+ {
+ // Look for a Deconfigure Record for the specified Target (there can
+ // only be one record)
+ for (; l_itr != iv_deconfigureRecords.end(); ++l_itr)
+ {
+ if ((*l_itr).iv_targetId == *i_pTargetId)
+ {
+ DG_TRAC_TARGET(INFO_MRK "Getting Deconfigure Record for: ",
+ i_pTargetId);
+ o_records.push_back(*l_itr);
+ break;
+ }
+ }
+
+ if (l_itr == iv_deconfigureRecords.end())
+ {
+ DG_TRAC_TARGET(INFO_MRK "Did not find a Deconfigure Record to get for: ",
+ i_pTargetId);
+ }
+ }
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::_createGardRecord(const TARGETING::Target & i_target,
+ errlHndl_t i_pErr,
+ const GardSeverity i_severity)
+{
+ errlHndl_t l_pErr = NULL;
+
+ TARGETING::EntityPath l_id = i_target.getAttr<TARGETING::ATTR_PHYS_PATH>();
+ DG_TRAC_TARGET(ERR_MRK "Creating GARD Record for: ", &l_id);
+
+ if (!i_target.getAttr<TARGETING::ATTR_DECONFIG_GARDABLE>())
+ {
+ // Target is not GARDable. Commit an error
+ TRAC_ERR("Target not GARDable");
+ /*@
+ * @errortype
+ * @moduleid MOD_DECONFIG_GARD
+ * @reasoncode RC_TARGET_NOT_GARDABLE
+ * @devdesc Attempt to create a GARD Record for a target that is
+ * not GARDable
+ */
+ l_pErr = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_DECONFIG_GARD,
+ RC_TARGET_NOT_GARDABLE);
+ errlCommit(l_pErr);
+ }
+ else
+ {
+ l_pErr = _ensureGardRecordDataSetup();
+
+ if (l_pErr)
+ {
+ TRAC_ERR("Error from _ensureGardRecordDataSetup");
+ }
+ else
+ {
+ GardRecord * l_pRecord = NULL;
+
+ // Find an empty GARD Record slot
+ for (uint32_t i = 0; i < iv_maxGardRecords; i++)
+ {
+ if (iv_pGardRecords[i].iv_recordId == 0)
+ {
+ l_pRecord = &(iv_pGardRecords[i]);
+ break;
+ }
+ }
+
+ if (!l_pRecord)
+ {
+ TRAC_ERR("GARD Record Repository full");
+ /*@
+ * @errortype
+ * @moduleid MOD_DECONFIG_GARD
+ * @reasoncode RC_GARD_REPOSITORY_FULL
+ * @devdesc Attempt to create a GARD Record and the GARD
+ * Repository is full
+ * @userdata1 Number of GARD Records in repository
+ */
+ l_pErr = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_DECONFIG_GARD,
+ RC_GARD_REPOSITORY_FULL,
+ iv_maxGardRecords);
+ }
+ else
+ {
+ l_pRecord->iv_recordId = iv_nextGardRecordId++;
+ l_pRecord->iv_targetId = l_id;
+ // TODO Setup iv_cardMruSn or iv_chipMruEcid
+ l_pRecord->iv_errlogPlid = 0; // TODO Get PLID from ErrorLog
+ l_pRecord->iv_severity = i_severity;
+ l_pRecord->iv_padding[0] = 0;
+ l_pRecord->iv_padding[1] = 0;
+ l_pRecord->iv_padding[2] = 0;
+ l_pRecord->iv_gardTime = 0; // TODO Get epoch time
+ }
+ }
+ }
+
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::_clearGardRecords(const uint32_t i_recordId)
+{
+ errlHndl_t l_pErr = NULL;
+
+ l_pErr = _ensureGardRecordDataSetup();
+
+ if (l_pErr)
+ {
+ TRAC_ERR("Error from _ensureGardRecordDataSetup");
+ }
+ else
+ {
+ if (i_recordId == 0)
+ {
+ TRAC_INF("Clearing all GARD Records");
+
+ // Only clear valid GARD Records to avoid excessive PNOR access
+ for (uint32_t i = 0; i < iv_maxGardRecords; i++)
+ {
+ if (iv_pGardRecords[i].iv_recordId != 0)
+ {
+ memset(&(iv_pGardRecords[i]), 0, sizeof(GardRecord));
+ }
+ }
+ }
+ else
+ {
+ uint32_t i = 0;
+ for (; i < iv_maxGardRecords; i++)
+ {
+ if (iv_pGardRecords[i].iv_recordId == i_recordId)
+ {
+ TRAC_INF("Clearing GARD Record ID 0x%x", i_recordId);
+ memset(&(iv_pGardRecords[i]), 0, sizeof(GardRecord));
+ break;
+ }
+ }
+
+ if (i == iv_maxGardRecords)
+ {
+ TRAC_INF("No GARD Record ID 0x%x to clear", i_recordId);
+ }
+ }
+ }
+
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::_clearGardRecords(
+ const TARGETING::EntityPath & i_targetId)
+{
+ errlHndl_t l_pErr = NULL;
+
+ l_pErr = _ensureGardRecordDataSetup();
+
+ if (l_pErr)
+ {
+ TRAC_ERR("Error from _ensureGardRecordDataSetup");
+ }
+ else
+ {
+ bool l_gardRecordsCleared = false;
+
+ for (uint32_t i = 0; i < iv_maxGardRecords; i++)
+ {
+ if (iv_pGardRecords[i].iv_targetId == i_targetId)
+ {
+ DG_TRAC_TARGET(INFO_MRK "Clearing GARD Record for: ",
+ &i_targetId);
+ memset(&(iv_pGardRecords[i]), 0, sizeof(GardRecord));
+ l_gardRecordsCleared = true;
+ }
+ }
+
+ if (!l_gardRecordsCleared)
+ {
+ DG_TRAC_TARGET(INFO_MRK "No GARD Records to clear for: ",
+ &i_targetId);
+ }
+ }
+
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::_getGardRecords(const uint32_t i_recordId,
+ GardRecords_t & o_records)
+{
+ errlHndl_t l_pErr = NULL;
+ o_records.clear();
+
+ l_pErr = _ensureGardRecordDataSetup();
+
+ if (l_pErr)
+ {
+ TRAC_ERR("Error from _ensureGardRecordDataSetup");
+ }
+ else
+ {
+ if (i_recordId == 0)
+ {
+ TRAC_INF("Getting all GARD Records");
+ for (uint32_t i = 0; i < iv_maxGardRecords; i++)
+ {
+ if (iv_pGardRecords[i].iv_recordId != 0)
+ {
+ TRAC_INF("Getting GARD Record ID 0x%x",
+ iv_pGardRecords[i].iv_recordId);
+ o_records.push_back(iv_pGardRecords[i]);
+ }
+ }
+ }
+ else
+ {
+ uint32_t i = 0;
+ for (; i < iv_maxGardRecords; i++)
+ {
+ if (iv_pGardRecords[i].iv_recordId == i_recordId)
+ {
+ TRAC_INF("Getting GARD Record ID 0x%x", i_recordId);
+ o_records.push_back(iv_pGardRecords[i]);
+ break;
+ }
+ }
+
+ if (i == iv_maxGardRecords)
+ {
+ TRAC_INF("No GARD Record ID 0x%x to get", i_recordId);
+ }
+ }
+ }
+
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::_getGardRecords(
+ const TARGETING::EntityPath & i_targetId,
+ GardRecords_t & o_records)
+{
+ errlHndl_t l_pErr = NULL;
+ o_records.clear();
+
+ l_pErr = _ensureGardRecordDataSetup();
+
+ if (l_pErr)
+ {
+ TRAC_ERR("Error from _ensureGardRecordDataSetup");
+ }
+ else
+ {
+ bool l_gardRecordsGot = false;
+
+ for (uint32_t i = 0; i < iv_maxGardRecords; i++)
+ {
+ if (iv_pGardRecords[i].iv_targetId == i_targetId)
+ {
+ DG_TRAC_TARGET(INFO_MRK "Getting GARD Record for: ",
+ &i_targetId);
+ o_records.push_back(iv_pGardRecords[i]);
+ l_gardRecordsGot = true;
+ }
+ }
+
+ if (!l_gardRecordsGot)
+ {
+ DG_TRAC_TARGET(INFO_MRK "No GARD Records to get for: ",
+ &i_targetId);
+ }
+ }
+
+ return l_pErr;
+}
+
+//******************************************************************************
+errlHndl_t DeconfigGard::_ensureGardRecordDataSetup()
+{
+ errlHndl_t l_pErr = NULL;
+
+ if (iv_pGardRecords == NULL)
+ {
+ PNOR::SectionInfo_t l_section;
+
+ // TODO Update when PNOR for GARD Records available (change HB_DATA)
+ l_pErr = PNOR::getSectionInfo(PNOR::HB_DATA, PNOR::SIDE_A, l_section);
+
+ if(l_pErr)
+ {
+ TRAC_ERR("Error getting GARD Record PNOR section info");
+ }
+ else
+ {
+ uint32_t l_numGardRecords = 0;
+ iv_pGardRecords = reinterpret_cast<GardRecord *>(l_section.vaddr);
+ iv_maxGardRecords = l_section.size / sizeof(GardRecord);
+
+ // TODO Remove this section when PNOR for GARD Records available
+ // For now, just use a buffer
+ iv_pGardRecords = new GardRecord[20];
+ memset(iv_pGardRecords, 0, sizeof(GardRecord) * 20);
+ iv_maxGardRecords = 20;
+ // TODO Remove this section when PNOR for GARD Records available
+
+ // Figure out the next GARD Record ID to use
+ for (uint32_t i = 0; i < iv_maxGardRecords; i++)
+ {
+ if (iv_pGardRecords[i].iv_recordId > iv_nextGardRecordId)
+ {
+ iv_nextGardRecordId = iv_pGardRecords[i].iv_recordId;
+ }
+
+ if (iv_pGardRecords[i].iv_recordId != 0)
+ {
+ l_numGardRecords++;
+ }
+ }
+
+ iv_nextGardRecordId++;
+
+ TRAC_INF("GARD Record data setup. MaxRecords: %d. NextID: %d. NumRecords: %d",
+ iv_maxGardRecords, iv_nextGardRecordId, l_numGardRecords);
+ }
+ }
+
+ return l_pErr;
+}
+
+}
diff --git a/src/usr/hwas/makefile b/src/usr/hwas/makefile
index 2542f0c39..f752aa88c 100644
--- a/src/usr/hwas/makefile
+++ b/src/usr/hwas/makefile
@@ -29,7 +29,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp
MODULE = hwas
-OBJS = hwas.o testHWP.o
+OBJS = hwas.o deconfigGard.o testHWP.o
SUBDIRS=test.d
diff --git a/src/usr/hwas/test/hwasGardTest.H b/src/usr/hwas/test/hwasGardTest.H
new file mode 100644
index 000000000..dda0de693
--- /dev/null
+++ b/src/usr/hwas/test/hwasGardTest.H
@@ -0,0 +1,920 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/hwas/test/hwasGardTest.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#ifndef _HWASGARDTEST_H
+#define _HWASGARDTEST_H
+
+/**
+ * @file hwasGardTest.H
+ *
+ * @brief Unit tests for HWAS Deconfigure and GARD functionality
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// CXXTEST
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <targeting/targetservice.H>
+#include <hwas/deconfigGard.H>
+#include <hwas/hwas_reasoncodes.H>
+
+class HwasGardTest: public CxxTest::TestSuite
+{
+public:
+
+ /**
+ * @brief Test getting all Deconfigure Records
+ */
+ void testDeconfigure1()
+ {
+ TS_TRACE(INFO_MRK "testDeconfigure1: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::DeconfigureRecords_t l_records;
+
+ // Get all Deconfigure Records
+ l_pErr = HWAS::theDeconfigGard().getDeconfigureRecords(NULL, l_records);
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ TS_FAIL("testDeconfigure1: Error from getDeconfigureRecords");
+ }
+ else
+ {
+ TS_TRACE(INFO_MRK "testDeconfigure1: Success. %d records",
+ l_records.size());
+ }
+ }
+
+ /**
+ * @brief Test getting a Deconfigure Record for a specific Target
+ */
+ void testDeconfigure2()
+ {
+ TS_TRACE(INFO_MRK "testDeconfigure2: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::DeconfigureRecords_t l_records;
+
+ // Get the master processor chip
+ TARGETING::Target* l_pTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(l_pTarget);
+ TARGETING::EntityPath l_id =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+ // Get any Deconfigure Record for the chip
+ l_pErr = HWAS::theDeconfigGard().getDeconfigureRecords(&l_id,
+ l_records);
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ TS_FAIL("testDeconfigure2: Error from getDeconfigureRecords");
+ }
+ else
+ {
+ if (l_records.size() > 1)
+ {
+ TS_FAIL("testDeconfigure2: More than 1 record (%d) for chip",
+ l_records.size());
+ }
+ else
+ {
+ TS_TRACE(INFO_MRK "testDeconfigure2: Success. %d records",
+ l_records.size());
+ }
+ }
+ }
+
+ /**
+ * @brief Test Deconfiguring a Target, getting the Deconfigure Record and
+ * clearing the Deconfigure Record
+ */
+ void testDeconfigure3()
+ {
+ TS_TRACE(INFO_MRK "testDeconfigure3: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::DeconfigureRecords_t l_records;
+
+ // Get the master processor chip
+ TARGETING::Target* l_pTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(l_pTarget);
+ TARGETING::EntityPath l_id =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+ // Create an error log to pass to the deconfigureTarget function, this
+ // will never be committed.
+ errlHndl_t l_pNewErr = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ HWAS::MOD_DECONFIG_GARD,
+ HWAS::RC_TARGET_NOT_DECONFIGURABLE);
+
+ do
+ {
+ // Get any existing Deconfigure Record for the chip
+ l_pErr = HWAS::theDeconfigGard().getDeconfigureRecords(&l_id,
+ l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testDeconfigure3: Error from getDeconfigureRecords");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_TRACE(INFO_MRK "testDeconfigure3: Chip has existing Deconfigure Record, skipping test");
+ break;
+ }
+
+ // Get the original HWAS_STATE of the chip
+ TARGETING::HwasState l_origState =
+ l_pTarget->getAttr<TARGETING::ATTR_HWAS_STATE>();
+
+ // Deconfigure the chip
+ l_pErr = HWAS::theDeconfigGard().deconfigureTarget(*l_pTarget,
+ l_pNewErr);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testDeconfigure3: Error from deconfigureTarget");
+ break;
+ }
+
+ // Get the new HWAS_STATE of the chip
+ TARGETING::HwasState l_state =
+ l_pTarget->getAttr<TARGETING::ATTR_HWAS_STATE>();
+
+ if (l_state.functional)
+ {
+ TS_FAIL("testDeconfigure3: Chip functional after deconfigure");
+ // intentionally continue
+ }
+
+ // Get the Deconfigure Record for the chip
+ l_pErr = HWAS::theDeconfigGard().getDeconfigureRecords(&l_id,
+ l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testDeconfigure3: Error from getDeconfigureRecords (2)");
+ break;
+ }
+
+ if (l_records.size() != 1)
+ {
+ TS_FAIL("testDeconfigure3: %d records for chip, expected 1",
+ l_records.size());
+ break;
+ }
+
+ // Reset the HWAS_STATE of the chip
+ l_pTarget->setAttr<TARGETING::ATTR_HWAS_STATE>(l_origState);
+
+ // Clear the Deconfigure Record
+ HWAS::theDeconfigGard()._clearDeconfigureRecords(&l_id);
+
+ // Get the Deconfigure Record for the chip
+ l_records.clear();
+
+ l_pErr = HWAS::theDeconfigGard().getDeconfigureRecords(&l_id,
+ l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testDeconfigure3: Error from getDeconfigureRecords (3)");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_FAIL("testDeconfigure3: %d records for chip, expected 0",
+ l_records.size());
+ break;
+ }
+
+ TS_TRACE(INFO_MRK "testDeconfigure3: Success");
+ }
+ while (0);
+
+ delete l_pNewErr;
+ l_pNewErr = NULL;
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ }
+ }
+
+ /**
+ * @brief Test Deconfiguring a Target multiple times
+ */
+ void testDeconfigure4()
+ {
+ TS_TRACE(INFO_MRK "testDeconfigure4: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::DeconfigureRecords_t l_records;
+
+ // Get the master processor chip
+ TARGETING::Target* l_pTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(l_pTarget);
+ TARGETING::EntityPath l_id =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+ // Create an error log to pass to the deconfigureTarget function, this
+ // will never be committed.
+ errlHndl_t l_pNewErr = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ HWAS::MOD_DECONFIG_GARD,
+ HWAS::RC_TARGET_NOT_DECONFIGURABLE);
+
+ do
+ {
+ // Get any existing Deconfigure Record for the chip
+ l_pErr = HWAS::theDeconfigGard().getDeconfigureRecords(&l_id,
+ l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testDeconfigure4: Error from getDeconfigureRecords");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_TRACE(INFO_MRK "testDeconfigure4: Chip has existing Deconfigure Record, skipping test");
+ break;
+ }
+
+ // Get the current HWAS_STATE of the chip
+ TARGETING::HwasState l_origState =
+ l_pTarget->getAttr<TARGETING::ATTR_HWAS_STATE>();
+
+ // Deconfigure the chip
+ l_pErr = HWAS::theDeconfigGard().deconfigureTarget(*l_pTarget,
+ l_pNewErr);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testDeconfigure4: Error from deconfigureTarget");
+ break;
+ }
+
+ // Deconfigure the chip again
+ l_pErr = HWAS::theDeconfigGard().deconfigureTarget(*l_pTarget,
+ l_pNewErr);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testDeconfigure4: Error from deconfigureTarget (2)");
+ break;
+ }
+
+ // Get the new HWAS_STATE of the chip
+ TARGETING::HwasState l_state =
+ l_pTarget->getAttr<TARGETING::ATTR_HWAS_STATE>();
+
+ if (l_state.functional)
+ {
+ TS_FAIL("testDeconfigure4: Chip functional after deconfigure");
+ // intentionally continue
+ }
+
+ // Get the Deconfigure Record for the chip
+ l_pErr = HWAS::theDeconfigGard().getDeconfigureRecords(&l_id,
+ l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testDeconfigure4: Error from getDeconfigureRecords (2)");
+ break;
+ }
+
+ // The second Deconfigure should not have created a new record
+ if (l_records.size() != 1)
+ {
+ TS_FAIL("testDeconfigure4: %d records for chip, expected 1",
+ l_records.size());
+ break;
+ }
+
+ // Reset the HWAS_STATE of the chip
+ l_pTarget->setAttr<TARGETING::ATTR_HWAS_STATE>(l_origState);
+
+ // Clear the Deconfigure Record
+ HWAS::theDeconfigGard()._clearDeconfigureRecords(&l_id);
+
+ TS_TRACE(INFO_MRK "testDeconfigure4: Success");
+ }
+ while (0);
+
+ delete l_pNewErr;
+ l_pNewErr = NULL;
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ }
+ }
+
+ /**
+ * @brief Test getting all GARD Records
+ */
+ void testGard1()
+ {
+ TS_TRACE(INFO_MRK "testGard1: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::GardRecords_t l_records;
+
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(0, l_records);
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ TS_FAIL("testGard1: Error from getGardRecords");
+ }
+ else
+ {
+ TS_TRACE(INFO_MRK "testGard1: Success. %d records",
+ l_records.size());
+ }
+ }
+
+ /**
+ * @brief Test getting GARD Records with a bad record ID).
+ */
+ void testGard2()
+ {
+ TS_TRACE(INFO_MRK "testGard2: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::GardRecords_t l_records;
+
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(0x12345678, l_records);
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ TS_FAIL("testGard2: Error from getGardRecords");
+ }
+ else
+ {
+ if (l_records.size())
+ {
+ TS_FAIL("testGard2: %d records found for bad ID",
+ l_records.size());
+ }
+ else
+ {
+ TS_TRACE(INFO_MRK "testGard2: Success");
+ }
+ }
+ }
+
+ /**
+ * @brief Test getting GARD Records for a specific target
+ */
+ void testGard3()
+ {
+ TS_TRACE(INFO_MRK "testGard3: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::GardRecords_t l_records;
+
+ // Get the master processor chip
+ TARGETING::Target* l_pTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(l_pTarget);
+ TARGETING::EntityPath l_id =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+
+ // Get all GARD Records for the Target
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ TS_FAIL("testGard3: Error from getGardRecords");
+ }
+ else
+ {
+ TS_TRACE(INFO_MRK "testGard3: Success. %d records",
+ l_records.size());
+ }
+ }
+
+ /**
+ * @brief Test creating a GARD Record, getting the GARD Record and
+ * clearing the GARD Record
+ */
+ void testGard4()
+ {
+ TS_TRACE(INFO_MRK "testGard4: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::GardRecords_t l_records;
+
+ // Get the master processor chip
+ TARGETING::Target* l_pTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(l_pTarget);
+ TARGETING::EntityPath l_id =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+ // Create an error log to pass to the createGardRecord function, this
+ // will never be committed.
+ errlHndl_t l_pNewErr = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ HWAS::MOD_DECONFIG_GARD,
+ HWAS::RC_TARGET_NOT_DECONFIGURABLE);
+
+ do
+ {
+ // Get any existing GARD Records for the chip
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard4: Error from getGardRecords");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_TRACE(INFO_MRK "testGard4: Chip has %d existing Gard Records, skipping test",
+ l_records.size());
+ break;
+ }
+
+ // Create a GARD Record for the chip
+ l_pErr = HWAS::theDeconfigGard().
+ createGardRecord(*l_pTarget, l_pNewErr,
+ HWAS::DeconfigGard::GARD_SEVERITY_PREDICTIVE);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard4: Error from createGardRecord");
+ break;
+ }
+
+ // Get the GARD Records for the chip
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard4: Error from getGardRecords (2)");
+ break;
+ }
+
+ if (l_records.size() != 1)
+ {
+ TS_FAIL("testGard4: %d records for chip, expected 1",
+ l_records.size());
+ break;
+ }
+
+ if (l_records[0].iv_severity !=
+ HWAS::DeconfigGard::GARD_SEVERITY_PREDICTIVE)
+ {
+ TS_FAIL("testGard4: Record severity %d, expected predictive",
+ l_records[0].iv_severity);
+ break;
+ }
+
+ // Clear the GARD Records for the chip
+ l_pErr = HWAS::theDeconfigGard().clearGardRecords(l_id);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard4: Error from clearGardRecords");
+ break;
+ }
+
+ // Get the GARD Records for the chip
+ l_records.clear();
+
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard4: Error from getGardRecords (3)");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_FAIL("testGard4: %d records for chip, expected 0",
+ l_records.size());
+ break;
+ }
+
+ TS_TRACE(INFO_MRK "testGard4: Success");
+ }
+ while (0);
+
+ delete l_pNewErr;
+ l_pNewErr = NULL;
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ }
+ }
+
+ /**
+ * @brief Test creating a GARD Record for a Target multiple times
+ */
+ void testGard5()
+ {
+ TS_TRACE(INFO_MRK "testGard5: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::GardRecords_t l_records;
+
+ // Get the master processor chip
+ TARGETING::Target* l_pTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(l_pTarget);
+ TARGETING::EntityPath l_id =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+ // Create an error log to pass to the createGardRecord function, this
+ // will never be committed.
+ errlHndl_t l_pNewErr = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ HWAS::MOD_DECONFIG_GARD,
+ HWAS::RC_TARGET_NOT_DECONFIGURABLE);
+
+ do
+ {
+ // Get any existing GARD Records for the chip
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard5: Error from getGardRecords");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_TRACE(INFO_MRK "testGard5: Chip has %d existing Gard Records, skipping test",
+ l_records.size());
+ break;
+ }
+
+ // Create a GARD Record for the chip
+ l_pErr = HWAS::theDeconfigGard().
+ createGardRecord(*l_pTarget, l_pNewErr,
+ HWAS::DeconfigGard::GARD_SEVERITY_PREDICTIVE);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard5: Error from createGardRecord");
+ break;
+ }
+
+ // Create another GARD Record for the chip
+ l_pErr = HWAS::theDeconfigGard().
+ createGardRecord(*l_pTarget, l_pNewErr,
+ HWAS::DeconfigGard::GARD_SEVERITY_FATAL);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard5: Error from createGardRecord (2)");
+ break;
+ }
+
+ // Get the GARD Records for the chip
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard5: Error from getGardRecords (2)");
+ break;
+ }
+
+ if (l_records.size() != 2)
+ {
+ TS_FAIL("testGard5: %d records for chip, expected 2",
+ l_records.size());
+ break;
+ }
+
+ // Clear the GARD Records for the chip
+ l_pErr = HWAS::theDeconfigGard().clearGardRecords(l_id);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard5: Error from clearGardRecords");
+ break;
+ }
+
+ // Get the GARD Records for the chip
+ l_records.clear();
+
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard5: Error from getGardRecords (3)");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_FAIL("testGard5: %d records for chip, expected 0",
+ l_records.size());
+ break;
+ }
+
+ TS_TRACE(INFO_MRK "testGard5: Success");
+ }
+ while (0);
+
+ delete l_pNewErr;
+ l_pNewErr = NULL;
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ }
+ }
+
+ /**
+ * @brief Test getting and clearing GARD Records by recordID
+ */
+ void testGard6()
+ {
+ TS_TRACE(INFO_MRK "testGard6: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::GardRecords_t l_records;
+
+ // Get the master processor chip
+ TARGETING::Target* l_pTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(l_pTarget);
+ TARGETING::EntityPath l_id =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+ // Create an error log to pass to the createGardRecord function, this
+ // will never be committed.
+ errlHndl_t l_pNewErr = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ HWAS::MOD_DECONFIG_GARD,
+ HWAS::RC_TARGET_NOT_DECONFIGURABLE);
+
+ do
+ {
+ // Get any existing GARD Records for the chip
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard6: Error from getGardRecords");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_TRACE(INFO_MRK "testGard6: Chip has %d existing Gard Records, skipping test",
+ l_records.size());
+ break;
+ }
+
+ // Create a GARD Record for the chip
+ l_pErr = HWAS::theDeconfigGard().
+ createGardRecord(*l_pTarget, l_pNewErr,
+ HWAS::DeconfigGard::GARD_SEVERITY_PREDICTIVE);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard6: Error from createGardRecord");
+ break;
+ }
+
+ // Create another GARD Record for the chip
+ l_pErr = HWAS::theDeconfigGard().
+ createGardRecord(*l_pTarget, l_pNewErr,
+ HWAS::DeconfigGard::GARD_SEVERITY_FATAL);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard6: Error from createGardRecord (2)");
+ break;
+ }
+
+ // Get the GARD Records for the chip
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard6: Error from getGardRecords (2)");
+ break;
+ }
+
+ if (l_records.size() != 2)
+ {
+ TS_FAIL("testGard6: %d records for chip, expected 2",
+ l_records.size());
+ break;
+ }
+
+ // Get the first GARD Record for the chip by Record ID
+ uint32_t l_recordID = l_records[0].iv_recordId;
+ l_records.clear();
+
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_recordID,
+ l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard6: Error from getGardRecords (3)");
+ break;
+ }
+
+ if (l_records.size() != 1)
+ {
+ TS_FAIL("testGard6: %d records for chip, expected 1",
+ l_records.size());
+ break;
+ }
+
+ // Clear the first GARD Record for the chip by Record ID
+ l_pErr = HWAS::theDeconfigGard().clearGardRecords(l_recordID);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard6: Error from clearGardRecords");
+ break;
+ }
+
+ // Get the GARD Records for the chip
+ l_records.clear();
+
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(l_id, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard6: Error from getGardRecords (4)");
+ break;
+ }
+
+ if (l_records.size() != 1)
+ {
+ TS_FAIL("testGard6: %d records for chip, expected 1 (2)",
+ l_records.size());
+ break;
+ }
+
+ // Clear the GARD Records for the chip
+ l_pErr = HWAS::theDeconfigGard().clearGardRecords(l_id);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard6: Error from clearGardRecords");
+ break;
+ }
+
+ TS_TRACE(INFO_MRK "testGard6: Success");
+ }
+ while (0);
+
+ delete l_pNewErr;
+ l_pNewErr = NULL;
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ }
+ }
+
+ /**
+ * @brief Test getting and clearing all GARD Records
+ */
+ void testGard7()
+ {
+ TS_TRACE(INFO_MRK "testGard7: Started");
+
+ errlHndl_t l_pErr = NULL;
+ HWAS::DeconfigGard::GardRecords_t l_records;
+
+ // Get the master processor chip
+ TARGETING::Target* l_pTarget = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(l_pTarget);
+ TARGETING::EntityPath l_id =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+ // Create an error log to pass to the createGardRecord function, this
+ // will never be committed.
+ errlHndl_t l_pNewErr = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ HWAS::MOD_DECONFIG_GARD,
+ HWAS::RC_TARGET_NOT_DECONFIGURABLE);
+
+ do
+ {
+ // Get all existing GARD Records
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(0, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard7: Error from getGardRecords");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_TRACE(INFO_MRK "testGard7: %d existing Gard Records, skipping test",
+ l_records.size());
+ break;
+ }
+
+ // Create a GARD Record for the chip
+ l_pErr = HWAS::theDeconfigGard().
+ createGardRecord(*l_pTarget, l_pNewErr,
+ HWAS::DeconfigGard::GARD_SEVERITY_PREDICTIVE);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard7: Error from createGardRecord");
+ break;
+ }
+
+ // Create another GARD Record for the chip
+ l_pErr = HWAS::theDeconfigGard().
+ createGardRecord(*l_pTarget, l_pNewErr,
+ HWAS::DeconfigGard::GARD_SEVERITY_FATAL);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard7: Error from createGardRecord (2)");
+ break;
+ }
+
+ // Clear all GARD Records
+ l_pErr = HWAS::theDeconfigGard().clearGardRecords(0);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard7: Error from clearGardRecords");
+ break;
+ }
+
+ // Get the GARD Records
+ l_records.clear();
+
+ l_pErr = HWAS::theDeconfigGard().getGardRecords(0, l_records);
+
+ if (l_pErr)
+ {
+ TS_FAIL("testGard7: Error from getGardRecords (2)");
+ break;
+ }
+
+ if (l_records.size() != 0)
+ {
+ TS_FAIL("testGard7: %d records for chip, expected 0",
+ l_records.size());
+ break;
+ }
+
+ TS_TRACE(INFO_MRK "testGard7: Success");
+ }
+ while (0);
+
+ delete l_pNewErr;
+ l_pNewErr = NULL;
+
+ if (l_pErr)
+ {
+ errlCommit(l_pErr);
+ }
+ }
+};
+
+#endif
OpenPOWER on IntegriCloud