summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@us.ibm.com>2012-07-11 20:46:39 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-08-30 13:37:46 -0500
commitf2bc28f73b48e96f776a66fbec7d3f071ea9bc62 (patch)
tree8becd5fd69b4738c261d5a84d82a94ec762268a4
parent4a2f7b1d5010d9ac8c179ec34f038264ae393a5a (diff)
downloadtalos-hostboot-f2bc28f73b48e96f776a66fbec7d3f071ea9bc62.tar.gz
talos-hostboot-f2bc28f73b48e96f776a66fbec7d3f071ea9bc62.zip
Attention handler support for processor attentions.
RTC: 41446 Change-Id: Ia02c87b5daa10ad758751dcbd6981aa1ce3f5c48 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1361 Tested-by: Jenkins Server Reviewed-by: Zane Shelley <zshelle@us.ibm.com> Reviewed-by: LARINA M. DSOUZA <larsouza@in.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/usr/diag/attn/attn.C32
-rw-r--r--src/usr/diag/attn/attnfwd.H1
-rw-r--r--src/usr/diag/attn/attnproc.C151
-rw-r--r--src/usr/diag/attn/attnproc.H98
-rw-r--r--src/usr/diag/attn/attnsvc.H46
-rw-r--r--src/usr/diag/attn/makefile2
-rw-r--r--src/usr/diag/attn/test/attntestproc.H465
-rw-r--r--src/usr/diag/attn/test/attnvalidate.C329
-rw-r--r--src/usr/diag/attn/test/attnvalidate.H191
-rw-r--r--src/usr/diag/attn/test/makefile3
10 files changed, 1293 insertions, 25 deletions
diff --git a/src/usr/diag/attn/attn.C b/src/usr/diag/attn/attn.C
index fed47c991..496b659e5 100644
--- a/src/usr/diag/attn/attn.C
+++ b/src/usr/diag/attn/attn.C
@@ -33,6 +33,7 @@
#include "attnlist.H"
#include "attntrace.H"
#include "attnsvc.H"
+#include "attnproc.H"
using namespace std;
using namespace PRDF;
@@ -108,7 +109,36 @@ errlHndl_t Resolver::resolve(
// in the ipoll mask register and query the proc & mem
// resolvers for active attentions
- return 0;
+ static ProcOps procOps;
+
+ errlHndl_t err = 0;
+
+ uint64_t ipollMaskScomData = 0;
+
+ do {
+
+ // get ipoll mask register content and decode
+ // unmasked attention types
+
+ err = getScom(i_proc, IPOLL::address, ipollMaskScomData);
+
+ if(err)
+ {
+ break;
+ }
+
+ // query the proc resolver for active attentions
+
+ err = procOps.resolve(i_proc, ipollMaskScomData, o_attentions);
+
+ if(err)
+ {
+ break;
+ }
+
+ } while(0);
+
+ return err;
}
ResolverWrapper & getResolverWrapper()
diff --git a/src/usr/diag/attn/attnfwd.H b/src/usr/diag/attn/attnfwd.H
index 3a6aaf780..65aede329 100644
--- a/src/usr/diag/attn/attnfwd.H
+++ b/src/usr/diag/attn/attnfwd.H
@@ -43,6 +43,7 @@ class AttnSvcTest;
class AttnListTest;
class AttnOpsTest;
class AttScomTest;
+class AttnProcTest;
namespace ATTN
{
diff --git a/src/usr/diag/attn/attnproc.C b/src/usr/diag/attn/attnproc.C
new file mode 100644
index 000000000..28676b2e3
--- /dev/null
+++ b/src/usr/diag/attn/attnproc.C
@@ -0,0 +1,151 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attnproc.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * 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_TAG
+ */
+/**
+ * @file attnproc.C
+ *
+ * @brief HBATTN Processor attention operations function definitions.
+ */
+
+#include <errl/errlmanager.H>
+#include "attnproc.H"
+#include "attnlist.H"
+#include "attntrace.H"
+
+using namespace std;
+using namespace PRDF;
+using namespace TARGETING;
+using namespace ERRORLOG;
+
+namespace ATTN
+{
+
+errlHndl_t ProcOps::mask(const AttnData & i_data)
+{
+ errlHndl_t err = 0;
+
+ uint64_t ipollMaskWriteBits = 0;
+
+ IPOLL::getCheckbits(i_data.attnType, ipollMaskWriteBits);
+
+ err = modifyScom(i_data.targetHndl, IPOLL::address,
+ ipollMaskWriteBits, SCOM_OR);
+
+ return err;
+}
+
+errlHndl_t ProcOps::unmask(const AttnData & i_data)
+{
+ errlHndl_t err = 0;
+
+ uint64_t ipollMaskWriteBits = 0;
+
+ IPOLL::getCheckbits(i_data.attnType, ipollMaskWriteBits);
+
+ err = modifyScom(i_data.targetHndl, IPOLL::address,
+ ~ipollMaskWriteBits, SCOM_AND);
+ return err;
+}
+
+errlHndl_t ProcOps::query(const AttnData & i_attnToCheck, bool & o_active)
+{
+ errlHndl_t err = 0;
+
+ uint64_t address = 0, checkbits = 0, scomData = 0;
+
+ GFIR::getAddress(i_attnToCheck.attnType, address);
+
+ GFIR::getCheckbits(i_attnToCheck.attnType, checkbits);
+
+ err = getScom(i_attnToCheck.targetHndl, address, scomData);
+
+ if(!err)
+ {
+ if(scomData & checkbits)
+ {
+ o_active = true;
+ }
+ else
+ {
+ o_active = false;
+ }
+ }
+
+ return err;
+}
+
+errlHndl_t ProcOps::resolve(
+ TargetHandle_t i_proc,
+ uint64_t i_typeMask,
+ AttentionList & o_attentions)
+{
+ errlHndl_t err = 0;
+
+ bool active = false;
+ AttnData d;
+ d.targetHndl = i_proc;
+
+ uint64_t ignored;
+
+ for(uint64_t type = INVALID_ATTENTION_TYPE;
+ type != END_ATTENTION_TYPE;
+ ++type)
+ {
+ if(!GFIR::getCheckbits(type, ignored))
+ {
+ // this object doesn't support
+ // this attention type
+
+ continue;
+ }
+
+ uint64_t mask = 0;
+
+ IPOLL::getCheckbits(type, mask);
+
+ if(!(mask & ~i_typeMask))
+ {
+ // this attention type is masked
+
+ continue;
+ }
+
+ d.attnType = static_cast<ATTENTION_VALUE_TYPE>(type);
+
+ err = query(d, active);
+
+ if(err)
+ {
+ errlCommit(err, HBATTN_COMP_ID);
+ }
+
+ else if(active)
+ {
+ o_attentions.add(Attention(d, this));
+ break;
+ }
+ }
+
+ return err;
+}
+}
diff --git a/src/usr/diag/attn/attnproc.H b/src/usr/diag/attn/attnproc.H
new file mode 100644
index 000000000..bc170154e
--- /dev/null
+++ b/src/usr/diag/attn/attnproc.H
@@ -0,0 +1,98 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attnproc.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * 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_TAG
+ */
+#ifndef __ATTN_ATTNPROC_H
+#define __ATTN_ATTNPROC_H
+
+/**
+ * @file attnproc.H
+ *
+ * @brief HBATTN Processor attention operations definition.
+ */
+
+#include "attnops.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief ProcOps ATTN Processor attention operations definition.
+ */
+class ProcOps : public AttentionOps
+{
+ public:
+
+ /**
+ * @brief mask Mask this attention.
+ *
+ * @param[in] i_data The attention to mask.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t mask(const PRDF::AttnData & i_data);
+
+ /**
+ * @brief unmask Unmask this attention.
+ *
+ * @param[in] i_data The attention to unmask.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t unmask(const PRDF::AttnData & i_data);
+
+ /**
+ * @brief query Test to see if this attention is active.
+ *
+ * @param[in] i_data The attention to query.
+ * @param[out] o_active true if attention is active.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t query(const PRDF::AttnData & i_data, bool & o_active);
+
+ /**
+ * @brief resolve Find attentions of the supplied type on the
+ * supplied target.
+ *
+ * @param[in] i_proc The proc on which to look for attentions.
+ * @param[in] i_typeMask The types of attentions to look for.
+ * @param[out] o_attentions Where to put attentions when found.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t resolve(
+ TARGETING::TargetHandle_t i_proc,
+ uint64_t i_typeMask,
+ AttentionList & o_attentions);
+
+ /**
+ * @brief dtor
+ */
+ ~ProcOps() {}
+};
+}
+#endif
diff --git a/src/usr/diag/attn/attnsvc.H b/src/usr/diag/attn/attnsvc.H
index 19cd9a9e7..b0574cbeb 100644
--- a/src/usr/diag/attn/attnsvc.H
+++ b/src/usr/diag/attn/attnsvc.H
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/diag/attn/attnsvc.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2012
-//
-// 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
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attnsvc.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * 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_TAG
+ */
#ifndef __ATTN_ATTNSVC_H
#define __ATTN_ATTNSVC_H
@@ -253,6 +254,7 @@ class Service
* @brief AttnSvcTest Provide access to unit test.
*/
friend class ::AttnSvcTest;
+ friend class ::AttnProcTest;
};
}
#endif
diff --git a/src/usr/diag/attn/makefile b/src/usr/diag/attn/makefile
index 93234a8b3..1b7fcdb3f 100644
--- a/src/usr/diag/attn/makefile
+++ b/src/usr/diag/attn/makefile
@@ -27,7 +27,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/diag
MODULE = attn
OBJS = attntrace.o attn.o attnsvc.o attnlist.o attnbits.o attntarget.o \
- attnscom.o
+ attnscom.o attnproc.o
SUBDIRS = test.d
diff --git a/src/usr/diag/attn/test/attntestproc.H b/src/usr/diag/attn/test/attntestproc.H
new file mode 100644
index 000000000..0a870b646
--- /dev/null
+++ b/src/usr/diag/attn/test/attntestproc.H
@@ -0,0 +1,465 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/test/attntestproc.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * 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_TAG
+ */
+#ifndef __TEST_ATTNTESTPROC_H
+#define __TEST_ATTNTESTPROC_H
+
+/**
+ * @file attntestproc.H
+ *
+ * @brief Unit test for the attnproc module.
+ */
+
+#include "../attnproc.H"
+#include "../attnsvc.H"
+#include "attnfakesys.H"
+#include "attnfakeprd.H"
+#include "attnfakegfir.H"
+#include "attnfakeipoll.H"
+#include "attnrandsource.H"
+#include "attnfaketarget.H"
+#include "attnfakepresenter.H"
+#include "attntest.H"
+#include "attnvalidate.H"
+#include <cxxtest/TestSuite.H>
+#include <sys/time.h>
+
+using namespace ATTN;
+using namespace PRDF;
+using namespace std;
+
+/**
+ * @brief AttnProcTest Unit test for the attnproc module.
+ */
+class AttnProcTest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief testMask Unit test for the
+ * mask method.
+ */
+ void testMask(void)
+ {
+ TS_TRACE(ENTER_MRK "testMask");
+
+ static const uint64_t iterations = 100;
+ static const uint64_t targetPoolSize = 8;
+
+ errlHndl_t err = 0;
+
+ ProcOps ops;
+ AttnData d;
+
+ FakeProcTargetService targetSvc(targetPoolSize);
+ FakeSystem system;
+
+ TargetHandleList procs;
+
+ targetSvc.getAllChips(procs, TYPE_PROC);
+
+ system.installScomImpl();
+
+ for(uint64_t it = 0; it < iterations; ++it)
+ {
+ d.targetHndl = *(&procs[0] + randint(0, targetPoolSize -1));
+ d.attnType = getRandomAttentionType();
+
+ // put some random data in the mask register
+
+ uint64_t randomData = randint(0, 0xffffffff);
+ uint64_t maskbits = 0;
+
+ if(!IPOLL::getCheckbits(d.attnType, maskbits))
+ {
+ TS_FAIL("unexpected error calling getCheckbits");
+ break;
+ }
+
+ randomData = randomData & ~maskbits;
+
+ err = putScom(
+ d.targetHndl,
+ IPOLL::address,
+ randomData);
+ if(err)
+ {
+ TS_FAIL("unexpected error calling putscom");
+ break;
+ }
+
+ err = ops.mask(d);
+
+ if(err)
+ {
+ TS_FAIL("unexpected error masking attention");
+ break;
+ }
+
+ uint64_t data = 0;
+ err = getScom(d.targetHndl, IPOLL::address, data);
+ if(err)
+ {
+ TS_FAIL("unexpected error calling getscom");
+ break;
+ }
+
+ // verify that the attn was masked, and that
+ // other bits weren't touched
+
+ if(!(data & maskbits))
+ {
+ TS_FAIL("attention not masked");
+ break;
+ }
+
+ if((data & ~maskbits) != randomData)
+ {
+ TS_FAIL("unexpected data in mask register");
+ break;
+ }
+
+ // clean up by unmasking
+
+ err = ops.unmask(d);
+
+ if(err)
+ {
+ TS_FAIL("unexpected error unmasking attention");
+ break;
+ }
+ }
+
+ TS_TRACE(EXIT_MRK "testMask");
+ }
+
+ /**
+ * @brief testUnmask Unit test for the
+ * unmask method.
+ */
+ void testUnmask(void)
+ {
+ TS_TRACE(ENTER_MRK "testUnmask");
+
+ static const uint64_t iterations = 100;
+ static const uint64_t targetPoolSize = 8;
+
+ errlHndl_t err = 0;
+
+ ProcOps ops;
+ AttnData d;
+
+ FakeProcTargetService targetSvc(targetPoolSize);
+ FakeSystem system;
+
+ TargetHandleList procs;
+
+ targetSvc.getAllChips(procs, TYPE_PROC);
+
+ system.installScomImpl();
+
+ for(uint64_t it = 0; it < iterations; ++it)
+ {
+ d.targetHndl = *(&procs[0] + randint(0, targetPoolSize -1));
+ d.attnType = getRandomAttentionType();
+
+ // mask first
+
+ err = ops.mask(d);
+
+ if(err)
+ {
+ TS_FAIL("unexpected error masking attention");
+ break;
+ }
+
+ // put some random data in the mask register
+
+ uint64_t randomData = randint(0, 0xffffffff);
+ uint64_t maskbits = 0;
+
+ if(!IPOLL::getCheckbits(d.attnType, maskbits))
+ {
+ TS_FAIL("unexpected error calling getCheckbits");
+ break;
+ }
+
+ randomData = randomData | maskbits;
+
+ err = putScom(d.targetHndl, IPOLL::address, randomData);
+ if(err)
+ {
+ TS_FAIL("unexpected error calling putscom");
+ break;
+ }
+
+ err = ops.unmask(d);
+
+ if(err)
+ {
+ TS_FAIL("unexpected error masking attention");
+ break;
+ }
+
+ uint64_t data = 0;
+ err = getScom(d.targetHndl, IPOLL::address, data);
+ if(err)
+ {
+ TS_FAIL("unexpected error calling getscom");
+ break;
+ }
+
+ // verify that the attn was masked, and that
+ // other bits weren't touched
+
+ if(!(data & ~maskbits))
+ {
+ TS_FAIL("attention not unmasked");
+ break;
+ }
+
+ if((data | maskbits) != randomData)
+ {
+ TS_FAIL("unexpected data in mask register");
+ break;
+ }
+ }
+
+ TS_TRACE(EXIT_MRK "testUnmask");
+ }
+
+ /**
+ * @brief testQuery Unit test for the
+ * query method.
+ */
+ void testQuery(void)
+ {
+ static const uint64_t iterations = 100;
+ static const uint64_t targetPoolSize = 8;
+
+ TS_TRACE(ENTER_MRK "testQuery");
+
+ errlHndl_t err = 0;
+
+ ProcOps ops;
+ AttnData d;
+
+ FakeSystem system;
+ FakeProcTargetService targetSvc(targetPoolSize);
+
+ TargetHandleList procs;
+
+ targetSvc.getAllChips(procs, TYPE_PROC);
+
+ FakeGfir xstpGfir(CHECK_STOP),
+ spclGfir(SPECIAL),
+ recGfir(RECOVERABLE);
+
+ xstpGfir.install(system);
+ spclGfir.install(system);
+ recGfir.install(system);
+
+ system.installScomImpl();
+ targetSvc.installTargetService();
+
+ for(uint64_t it = 0; it < iterations; ++it)
+ {
+ bool result;
+
+ d.targetHndl = *(&procs[0] + randint(0, targetPoolSize -1));
+ d.attnType = getRandomAttentionType();
+
+ // set the error in hardware
+
+ err = system.putAttentions(AttnList(1, d));
+ if(err)
+ {
+ TS_FAIL("unexpected error calling putAttentions");
+ break;
+ }
+
+ err = ops.query(d, result);
+
+ if(err)
+ {
+ TS_FAIL("unexpected error calling query");
+ break;
+ }
+
+ if(!result)
+ {
+ TS_FAIL("expected attention");
+ break;
+ }
+
+ // clear the error in hardware
+
+ err = system.clearAttention(d);
+ if(err)
+ {
+ TS_FAIL("unexpected error calling clearAttention");
+ break;
+ }
+
+ err = ops.query(d, result);
+
+ if(err)
+ {
+ TS_FAIL("unexpected error calling query");
+ break;
+ }
+
+ if(result)
+ {
+ TS_FAIL("did not expect attention");
+ break;
+ }
+ }
+
+ TS_TRACE(EXIT_MRK "testQuery");
+ }
+
+ /**
+ * @brief testAttentions Unit test for the
+ * attnproc module.
+ */
+ void testAttentions()
+ {
+ static const uint64_t targetPoolSize = 8;
+ static const uint64_t iterations = 5;
+ static const uint64_t maxAttnsPerIteration = 5;
+
+ TS_TRACE(ENTER_MRK "testAttentions");
+
+ errlHndl_t err = 0;
+
+ Service svc;
+
+ FakePresenter presenter;
+ FakeSystem system;
+
+ FakeGfir xstpGfir(CHECK_STOP),
+ spclGfir(SPECIAL),
+ recGfir(RECOVERABLE);
+
+ xstpGfir.install(system);
+ spclGfir.install(system);
+ recGfir.install(system);
+
+ FakeIpoll xstpIpoll(CHECK_STOP, presenter),
+ spclIpoll(SPECIAL, presenter),
+ recIpoll(RECOVERABLE, presenter);
+
+ xstpIpoll.install(system);
+ spclIpoll.install(system);
+ recIpoll.install(system);
+
+ Validator v;
+
+ v.install(system);
+
+ system.installScomImpl();
+
+ FakeProcTargetService targetSvc(targetPoolSize);
+
+ TargetHandleList procs;
+
+ targetSvc.getAllChips(procs, TYPE_PROC);
+
+ RandSource source(
+ iterations,
+ maxAttnsPerIteration,
+ system,
+ &procs[0],
+ &procs[0] + procs.size());
+
+ targetSvc.installTargetService();
+
+ FakePrd prd(system);
+
+ prd.installPrd();
+
+ do
+ {
+ err = svc.start();
+
+ if(err)
+ {
+ TS_FAIL("unexpected error starting service");
+ break;
+ }
+
+ if(!presenter.start(svc.iv_intrTaskQ))
+ {
+ TS_FAIL("unexpected error starting fake presenter");
+ break;
+ }
+
+ if(!source.start())
+ {
+ TS_FAIL("unexpected error starting source");
+ break;
+ }
+
+ // wait for the testcase to finish injecting attentions
+
+ if(!source.wait())
+ {
+ TS_FAIL("unexpected error waiting for source");
+ break;
+ }
+
+ // wait for the the service to handle all the attentions
+ TS_TRACE("Waiting for attentions to be cleared.");
+
+ if(!system.wait(TEN_CTX_SWITCHES_NS * iterations * 50))
+ {
+ TS_FAIL("Attentions still present on system.");
+
+ system.dump();
+ break;
+ }
+
+ } while(0);
+
+ err = svc.stop();
+
+ if(err)
+ {
+ TS_FAIL("unexpected error stopping service");
+ delete err;
+ }
+
+ presenter.stop();
+
+ if(!v.empty())
+ {
+ TS_FAIL("unexpected result after injecting attentions");
+
+ v.dump();
+ }
+
+ TS_TRACE(EXIT_MRK "testAttentions");
+ }
+};
+#endif
diff --git a/src/usr/diag/attn/test/attnvalidate.C b/src/usr/diag/attn/test/attnvalidate.C
new file mode 100644
index 000000000..dec7766a9
--- /dev/null
+++ b/src/usr/diag/attn/test/attnvalidate.C
@@ -0,0 +1,329 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/test/attnvalidate.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * 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_TAG
+ */
+/**
+ * @file attnvalidate.C
+ *
+ * @brief HBATTN fake system validation class method definitions.
+ */
+
+#include "attncomp.H"
+#include "attnvalidate.H"
+#include "attnfakesys.H"
+#include "../attntarget.H"
+#include "../attntrace.H"
+
+using namespace PRDF;
+using namespace TARGETING;
+using namespace std;
+
+namespace ATTN
+{
+
+errlHndl_t Validator::processPutAttention(
+ FakeSystem & i_sys,
+ const AttnData & i_attention,
+ uint64_t i_count)
+{
+ // add this new attention to the list
+
+ Properties p;
+
+ p.targetHndl = i_attention.targetHndl;
+ p.attnType = i_attention.attnType;
+
+ TargetHandle_t target = 0;
+
+ uint64_t ipollCheckbits;
+
+ if(getTargetService().getType(i_attention.targetHndl) == TYPE_PROC)
+ {
+ IPOLL::getCheckbits(i_attention.attnType, ipollCheckbits);
+ target = i_attention.targetHndl;
+ }
+ else
+ {
+ IPOLL::getCheckbits(HOST, ipollCheckbits);
+
+ target = getTargetService().getProc(i_attention.targetHndl);
+ }
+
+ bool masked = i_sys.getReg(target, IPOLL::address) & ipollCheckbits;
+
+ if(!masked)
+ {
+ p.next = MASK;
+ }
+ else
+ {
+ p.next = CLEAR;
+ }
+
+ iv_properties.push_back(p);
+
+ return 0;
+}
+
+errlHndl_t Validator::processClearAttention(
+ FakeSystem & i_sys,
+ const AttnData & i_attention,
+ uint64_t i_count)
+{
+ do {
+
+ AttnDataEq comp(i_attention);
+
+ // there should be at least one matching
+ // attention ready to be cleared
+
+ vector<Properties>::iterator it = find_if(
+ iv_properties.begin(),
+ iv_properties.end(),
+ comp);
+
+ while(it != iv_properties.end())
+ {
+ if(it->next == CLEAR)
+ {
+ // this attention now ready to be unmasked
+
+ it->next = UNMASK;
+ break;
+ }
+
+ it = find_if(++it, iv_properties.end(), comp);
+ }
+
+ if(it == iv_properties.end())
+ {
+ ATTN_ERR("Validator: tgt: %p, type %d not ready to be cleared",
+ i_attention.targetHndl, i_attention.attnType);
+ }
+ }
+ while(0);
+
+ return 0;
+}
+
+struct AppendInnerLoopArgs
+{
+ AttnList * list;
+ TargetHandleList mcsList;
+};
+
+void appendInnerLoop(
+ uint64_t i_type,
+ void * i_args)
+{
+ AppendInnerLoopArgs * args = static_cast<AppendInnerLoopArgs *>(i_args);
+
+ AttnList & list = *args->list;
+ TargetHandleList & mcsList = args->mcsList;
+
+ AttnData d;
+
+ TargetHandleList::iterator it = mcsList.begin();
+
+ while(it != mcsList.end())
+ {
+ d.attnType = static_cast<ATTENTION_VALUE_TYPE>(i_type);
+ d.targetHndl = getTargetService().getMembuf(*it);
+
+ list.push_back(d);
+
+ ++it;
+ }
+}
+
+struct AppendOuterLoopArgs
+{
+ TargetHandle_t target;
+ AttnList list;
+};
+
+
+void appendOuterLoop(
+ uint64_t i_type,
+ void * i_args)
+{
+ AppendOuterLoopArgs * args = static_cast<AppendOuterLoopArgs *>(i_args);
+
+ AttnList & list = args->list;
+
+ AttnData d;
+ uint64_t hostmask;
+
+ IPOLL::getCheckbits(HOST, hostmask);
+
+ // assemble a list of all attentions to check
+
+ if(i_type == HOST)
+ {
+ // for host attn bit changed, check any attention
+ // type on any membufs behind this proc
+
+ AppendInnerLoopArgs innerLoopArgs;
+
+ innerLoopArgs.list = &args->list;
+
+ getTargetService().getMcsList(args->target, innerLoopArgs.mcsList);
+
+ IPOLL::forEach(
+ 0xffffffffffffffffull & ~hostmask,
+ &innerLoopArgs,
+ &appendInnerLoop);
+ }
+ else
+ {
+ // for other attn types, just check the proc
+
+ d.attnType = static_cast<ATTENTION_VALUE_TYPE>(i_type);
+ d.targetHndl = args->target;
+
+ list.push_back(d);
+ }
+}
+
+errlHndl_t Validator::processPutReg(
+ FakeSystem & i_sys,
+ TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_new,
+ uint64_t i_old)
+{
+ AppendOuterLoopArgs args;
+
+ args.target = i_target;
+
+ // these bits turned off
+
+ IPOLL::forEach(i_old & ~i_new, &args, &appendOuterLoop);
+
+ AttnList::iterator it = args.list.begin();
+
+ while(it != args.list.end())
+ {
+ processUnmask(*it);
+ ++it;
+ }
+
+ args.list.clear();
+
+ // these bits turned on
+
+ IPOLL::forEach(i_new & ~i_old, &args, &appendOuterLoop);
+
+ it = args.list.begin();
+
+ while(it != args.list.end())
+ {
+ processMask(*it);
+ ++it;
+ }
+
+ return 0;
+}
+
+
+void Validator::processUnmask(const AttnData & i_data)
+{
+ AttnDataEq comp(i_data);
+
+ vector<Properties>::iterator pit = find_if(
+ iv_properties.begin(),
+ iv_properties.end(),
+ comp);
+
+ while(pit != iv_properties.end())
+ {
+ if(pit->next == UNMASK)
+ {
+ // finished with this attention
+
+ ATTN_DBG("Validator: tgt: %p, type: %d done.",
+ pit->targetHndl, pit->attnType);
+
+ pit = iv_properties.erase(pit);
+ }
+ else
+ {
+ ++pit;
+ }
+
+ pit = find_if(pit,
+ iv_properties.end(),
+ comp);
+ }
+}
+
+void Validator::processMask(const AttnData & i_data)
+{
+ AttnDataEq comp(i_data);
+
+ vector<Properties>::iterator pit = find_if(
+ iv_properties.begin(),
+ iv_properties.end(),
+ comp);
+
+ while(pit != iv_properties.end())
+ {
+ if(pit->next == MASK)
+ {
+ // this attention now ready to be cleared
+
+ pit->next = CLEAR;
+ }
+
+ pit = find_if(++pit,
+ iv_properties.end(),
+ comp);
+ }
+}
+
+void Validator::install(FakeSystem & i_sys)
+{
+ i_sys.addSource(TYPE_NA, INVALID_ATTENTION_TYPE, *this);
+
+ // monitor changes to ipoll
+ i_sys.addReg(IPOLL::address, *this);
+}
+
+bool Validator::empty() const
+{
+ return iv_properties.empty();
+}
+
+void Validator::dump() const
+{
+ vector<Properties>::const_iterator it =
+ iv_properties.begin();
+
+ while(it != iv_properties.end())
+ {
+ ATTN_DBG("target: %p, type: %d, next: %d",
+ it->targetHndl, it->attnType, it->next);
+
+ ++it;
+ }
+}
+}
diff --git a/src/usr/diag/attn/test/attnvalidate.H b/src/usr/diag/attn/test/attnvalidate.H
new file mode 100644
index 000000000..f962297ea
--- /dev/null
+++ b/src/usr/diag/attn/test/attnvalidate.H
@@ -0,0 +1,191 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/test/attnvalidate.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * 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_TAG
+ */
+#ifndef __TEST_ATTNVALIDATE_H
+#define __TEST_ATTNVALIDATE_H
+
+/**
+ * @file attnvalidate.H
+ *
+ * @brief HBATTN fake system validation class definitions.
+ */
+
+#include "attnfakeelement.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief Validator
+ *
+ * Fake system validation class definition.
+ *
+ * Monitors attention state changes and ipoll mask
+ * changes.
+ *
+ * Accumulates attentions injected on the system and
+ * tracks attention mask -> clear -> unmask lifeccyle.
+ */
+class Validator : public FakeReg, public FakeSource
+{
+ public:
+
+ /**
+ * @brief ctor
+ */
+ Validator() {};
+
+ /**
+ * @brief dtor
+ */
+ ~Validator() {}
+
+ /**
+ * @brief install
+ *
+ * Register this object with the provided system for
+ * the appropriate callbacks.
+ *
+ * @param[in] i_system The system in which to register callbacks.
+ */
+ void install(FakeSystem & i_sys);
+
+ /**
+ * @brief processPutReg Process modified register content.
+ *
+ * @param[in] i_sys System that modified register content.
+ * @param[in] i_target Target whose registers were modified.
+ * @param[in] i_address Address of register that was modified.
+ * @param[in] i_new Register content after modification.
+ * @param[in] i_old Register content before modification.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t processPutReg(
+ FakeSystem & i_sys,
+ TARGETING::TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_new,
+ uint64_t i_old);
+
+ /**
+ * @brief processPutAttention Process injected attention.
+ *
+ * @param[in] i_sys System that modified register content.
+ * @param[in] i_attn Attention that was injected.
+ * @param[in] i_count number of attentions currently present.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t processPutAttention(
+ FakeSystem & i_sys,
+ const PRDF::AttnData & i_attn,
+ uint64_t i_count);
+
+ /**
+ * @brief processClearAttention Process cleared attention.
+ *
+ * @param[in] i_sys System that modified register content.
+ * @param[in] i_attn Attention that was cleared.
+ * @param[in] i_count number of attentions currently present.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t processClearAttention(
+ FakeSystem & i_sys,
+ const PRDF::AttnData & i_attn,
+ uint64_t i_count);
+
+ /**
+ * @brief empty
+ *
+ * Indicates whether or not all attentions successfully
+ * completed the mask -> clear -> unmask lifecycle.
+ *
+ * @return[true] All lifecycles completed.
+ * @return[false] One or more lifecycles incomplete.
+ */
+ bool empty() const;
+
+ /**
+ * @brief dump
+ *
+ * Dump the list of attentions with incomplete lifecycles.
+ */
+ void dump() const;
+
+ private:
+
+ /**
+ * @brief processUnmask
+ *
+ * Unmask specific handling for ipoll mask register changes.
+ *
+ * @param[in] i_data The attention type that was unmasked.
+ */
+ void processUnmask(const PRDF::AttnData & i_data);
+
+ /**
+ * @brief processMask
+ *
+ * Mask specific handling for ipoll mask register changes.
+ *
+ * @param[in] i_data The attention type that was masked.
+ */
+ void processMask(const PRDF::AttnData & i_data);
+
+ /**
+ * @brief Attention lifecycle enumeration.
+ */
+ enum
+ {
+ MASK = 1,
+ UNMASK,
+ CLEAR,
+ DONE,
+ };
+
+ /**
+ * @brief Properties
+ *
+ * Adds an additional attribute to an AttnData struct.
+ */
+ struct Properties : public PRDF::AttnData
+ {
+ /**
+ * @brief next The expected next state for this attention
+ * in the mask -> clear -> unmask lifecycle.
+ */
+ uint64_t next;
+ };
+
+ /**
+ * @brief Attnetion type status association list.
+ */
+ std::vector<Properties> iv_properties;
+};
+}
+#endif
diff --git a/src/usr/diag/attn/test/makefile b/src/usr/diag/attn/test/makefile
index bb47c41db..905760162 100644
--- a/src/usr/diag/attn/test/makefile
+++ b/src/usr/diag/attn/test/makefile
@@ -25,7 +25,8 @@ ROOTPATH = ../../../../..
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/diag
OBJS = attnfakesys.o attntest.o attnrand.o attnfakepresenter.o attnfakeprd.o \
- attnfaketarget.o attnrandsource.o attnfakegfir.o attnfakeipoll.o
+ attnfaketarget.o attnrandsource.o attnfakegfir.o attnfakeipoll.o \
+ attnvalidate.o
MODULE = testattn
OpenPOWER on IntegriCloud