summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@us.ibm.com>2012-05-17 09:12:42 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-07-16 18:38:10 -0500
commit19b2fa16137b10e1c34b71bec450a36eee1a0545 (patch)
tree54f947b39816072ecd314036f3afc6bf7865a67c /src
parent43c18103e9bdbbf1fd17bfcccf885c64d07f305c (diff)
downloadtalos-hostboot-19b2fa16137b10e1c34b71bec450a36eee1a0545.tar.gz
talos-hostboot-19b2fa16137b10e1c34b71bec450a36eee1a0545.zip
Initial attention handler support.
RTC: 40764 Change-Id: Ic5b5b3e80915cb4f0ee543baa6fe4abc51e07ad2 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1079 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/build/debug/simics-debug-framework.py4
-rw-r--r--src/include/arch/ppc.H3
-rw-r--r--src/include/usr/diag/attn/attn.H36
-rw-r--r--src/include/usr/hbotcompid.H7
-rw-r--r--src/makefile5
-rw-r--r--src/usr/diag/attn/attn.C157
-rw-r--r--src/usr/diag/attn/attnfwd.H100
-rw-r--r--src/usr/diag/attn/attnlist.C79
-rw-r--r--src/usr/diag/attn/attnlist.H118
-rw-r--r--src/usr/diag/attn/attnlistutil.H101
-rw-r--r--src/usr/diag/attn/attnops.H206
-rw-r--r--src/usr/diag/attn/attnprd.H122
-rw-r--r--src/usr/diag/attn/attnresolv.H130
-rw-r--r--src/usr/diag/attn/attnsvc.C427
-rw-r--r--src/usr/diag/attn/attnsvc.H258
-rw-r--r--src/usr/diag/attn/attntrace.C39
-rw-r--r--src/usr/diag/attn/attntrace.H47
-rw-r--r--src/usr/diag/attn/makefile33
-rw-r--r--src/usr/diag/attn/test/attnfakesys.C349
-rw-r--r--src/usr/diag/attn/test/attnfakesys.H261
-rw-r--r--src/usr/diag/attn/test/attnrand.S32
-rw-r--r--src/usr/diag/attn/test/attntest.C78
-rw-r--r--src/usr/diag/attn/test/attntest.H56
-rw-r--r--src/usr/diag/attn/test/attntestlist.H401
-rw-r--r--src/usr/diag/attn/test/attntestops.H110
-rw-r--r--src/usr/diag/attn/test/attntestsvc.H237
-rw-r--r--src/usr/diag/attn/test/attntesttest.H80
-rw-r--r--src/usr/diag/attn/test/attntesttrace.H72
-rw-r--r--src/usr/diag/attn/test/makefile33
-rw-r--r--src/usr/diag/makefile2
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvctasks.H13
31 files changed, 3592 insertions, 4 deletions
diff --git a/src/build/debug/simics-debug-framework.py b/src/build/debug/simics-debug-framework.py
index e7694e03c..3ddbcd388 100755
--- a/src/build/debug/simics-debug-framework.py
+++ b/src/build/debug/simics-debug-framework.py
@@ -42,6 +42,7 @@
import os
import subprocess
import re
+import random
# @class DebugFrameworkIPCMessage
# @brief Wrapper class for constructing a properly formed IPC message for the
@@ -377,6 +378,9 @@ def writeLongLong(address,n):
# See src/include/arch/ppc.H for the definitions of the magic args.
# Hostboot magic args should range 7000..7999.
def magic_instruction_callback(user_arg, cpu, arg):
+ if arg == 7008:
+ cpu.r3 = random.randint(1, 0xffffffffffffffffL)
+
if arg == 7006: # MAGIC_SHUTDOWN
# KernelMisc::shutdown()
print "KernelMisc::shutdown() called."
diff --git a/src/include/arch/ppc.H b/src/include/arch/ppc.H
index 77122be0d..5d2e51a7b 100644
--- a/src/include/arch/ppc.H
+++ b/src/include/arch/ppc.H
@@ -326,7 +326,8 @@ enum
{
MAGIC_SHUTDOWN = 7006, // KernelMisc::shutdown() called.
MAGIC_BREAK = 7007, // hard-code a breakpoint
- MAGIC_CONTINUOUS_TRACE = 7055 // extract mixed trace buffer
+ MAGIC_CONTINUOUS_TRACE = 7055, // extract mixed trace buffer
+ MAGIC_RANDOM = 7008, // generate random number
};
diff --git a/src/include/usr/diag/attn/attn.H b/src/include/usr/diag/attn/attn.H
new file mode 100644
index 000000000..6b553e35b
--- /dev/null
+++ b/src/include/usr/diag/attn/attn.H
@@ -0,0 +1,36 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/diag/attn/attn.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
+#ifndef __ATTN_ATTN_H
+#define __ATTN_ATTN_H
+
+/**
+ * @file attn.H
+ *
+ * @brief HBATTN declarations.
+ */
+
+namespace ATTN
+{
+
+}
+#endif
diff --git a/src/include/usr/hbotcompid.H b/src/include/usr/hbotcompid.H
index 8f9f8daff..667a2a811 100644
--- a/src/include/usr/hbotcompid.H
+++ b/src/include/usr/hbotcompid.H
@@ -232,6 +232,13 @@ const char UTIL_COMP_NAME[] = "util";
//@{
const compId_t ISTEP_COMP_ID = 0x1700;
const char ISTEP_COMP_NAME[] = "istep";
+
+/** @name HBATTN
+ * HBATTN attention service component
+ */
+//@{
+const compId_t HBATTN_COMP_ID = 0x1800;
+const char HBATTN_COMP_NAME[] = "attn";
//@}
/** @name RESERVED
diff --git a/src/makefile b/src/makefile
index 5ea9cb97d..4a59af354 100644
--- a/src/makefile
+++ b/src/makefile
@@ -60,7 +60,8 @@ EXTENDED_MODULES = targeting ecmddatabuffer fapi hwp plat \
activate_powerbus build_winkle_images \
core_activate dram_initialization edi_ei_initialization \
establish_system_smp load_payload \
- nest_chiplets start_payload thread_activate slave_sbe
+ nest_chiplets start_payload thread_activate slave_sbe \
+ attn
DIRECT_BOOT_MODULES = example
RUNTIME_MODULES =
@@ -69,7 +70,7 @@ TESTCASE_MODULES = cxxtest testerrl testdevicefw testsyslib \
testscom testxscom testtargeting testinitservice testkernel \
testhwpf testecmddatabuffer initsvctesttask testcxxtest \
testpnor testi2c testfsi testvfs testhwas testintr testspd \
- testpore testutil testmbox testmdia testmvpd testprdf
+ testpore testutil testmbox testmdia testmvpd testprdf testattn
RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic
diff --git a/src/usr/diag/attn/attn.C b/src/usr/diag/attn/attn.C
new file mode 100644
index 000000000..688dd9f13
--- /dev/null
+++ b/src/usr/diag/attn/attn.C
@@ -0,0 +1,157 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/attn.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
+/**
+ * @file attn.C
+ *
+ * @brief HBATTN utility function definitions.
+ */
+
+#include "attnprd.H"
+#include "attnresolv.H"
+#include "attnops.H"
+#include "attnlist.H"
+#include "attntrace.H"
+
+using namespace std;
+using namespace PRDF;
+using namespace TARGETING;
+
+namespace ATTN
+{
+
+errlHndl_t PrdImpl::callPrd(const AttentionList & i_attentions)
+{
+ // forward call to the real PRD
+
+ errlHndl_t err = 0;
+
+ // convert attention list to PRD type
+
+ AttnList attnList;
+
+ i_attentions.getAttnList(attnList);
+
+ if(!attnList.empty())
+ {
+ err = PrdMain(INVALID_ATTENTION_TYPE, attnList);
+ }
+
+ return err;
+}
+
+PrdWrapper & getPrdWrapper()
+{
+ // prd wrapper singleton access
+
+ static PrdWrapper w;
+
+ return w;
+}
+
+PrdWrapper::PrdWrapper()
+ : iv_impl(&Singleton<PrdImpl>::instance())
+{
+ // default call the real PRD
+}
+
+errlHndl_t PrdWrapper::callPrd(const AttentionList & i_attentions)
+{
+ // forward call to the installed PRD implementation.
+
+ ATTN_DBG("call PRD with %d using: %p", i_attentions.size(), iv_impl);
+
+ return iv_impl->callPrd(i_attentions);
+}
+
+errlHndl_t Resolver::resolve(
+ TARGETING::TargetHandle_t i_proc,
+ AttentionList & o_attentions)
+{
+ // default resolver. determine what attentions are unmasked
+ // in the ipoll mask register and query the proc & mem
+ // resolvers for active attentions
+
+ return 0;
+}
+
+ResolverWrapper & getResolverWrapper()
+{
+ // resolver wrapper singleton access
+
+ static ResolverWrapper w;
+
+ return w;
+}
+
+ResolverWrapper::ResolverWrapper()
+ : iv_impl(&Singleton<Resolver>::instance())
+{
+ // default call the real resolver
+}
+
+errlHndl_t ResolverWrapper::resolve(
+ TARGETING::TargetHandle_t i_proc,
+ AttentionList & o_attentions)
+{
+ // forward call to the installed resolver implementation
+
+ errlHndl_t err = iv_impl->resolve(i_proc, o_attentions);
+
+ if(!err)
+ {
+ ATTN_DBG("resolved %d using: %p", o_attentions.size(), iv_impl);
+ }
+
+ return err;
+}
+
+int64_t Attention::compare(const Attention & i_rhs) const
+{
+ return ATTN::compare(iv_data, i_rhs.iv_data);
+}
+
+int64_t compare(const AttnData & i_l, const AttnData & i_r)
+{
+ if(i_l.attnType < i_r.attnType)
+ {
+ return -1;
+ }
+
+ if(i_r.attnType < i_l.attnType)
+ {
+ return 1;
+ }
+
+ if(i_l.targetHndl < i_r.targetHndl)
+ {
+ return -1;
+ }
+
+ if(i_r.targetHndl < i_l.targetHndl)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+}
diff --git a/src/usr/diag/attn/attnfwd.H b/src/usr/diag/attn/attnfwd.H
new file mode 100644
index 000000000..b8ef812ef
--- /dev/null
+++ b/src/usr/diag/attn/attnfwd.H
@@ -0,0 +1,100 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/attnfwd.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
+#ifndef __ATTN_ATTNFWD_H
+#define __ATTN_ATTNFWD_H
+
+/**
+ * @file attnfwd.H
+ *
+ * @brief HBATTN forward declarations.
+ */
+
+#include <intr/interrupt.H>
+#include <errl/errlentry.H>
+#include <diag/prdf/prdf_proto.H>
+#include <targeting/common/target.H>
+#include <vector>
+#include <builtins.h>
+
+class AttnTraceTest;
+class AttnSvcTest;
+class AttnListTest;
+class AttnOpsTest;
+
+namespace ATTN
+{
+
+class Attention;
+class AttentionList;
+class AttentionOps;
+class PrdWrapper;
+class PrdImpl;
+class ResolverWrapper;
+class Resolver;
+
+/**
+ * @brief MessageType Attention service message types.
+ */
+enum MessageType
+{
+ /**
+ * @brief ATTENTION Attention message.
+ */
+ ATTENTION = INTR::ATTENTION,
+
+ /**
+ * @brief SHUTDOWN Shutdown message.
+ */
+ SHUTDOWN,
+};
+
+/**
+ * @brief getPrdWrapper PrdWrapper singleton access.
+ *
+ * @return PrdWrapper Singleton instance.
+ */
+PrdWrapper & getPrdWrapper();
+
+/**
+ * @brief getResolverWrapper ResolverWrapper singleton access.
+ *
+ * @return ResolverWrapper Singleton instance.
+ */
+ResolverWrapper & getResolverWrapper();
+
+/**
+ * @brief compare compare two PRDF::AttnData structures.
+ *
+ * @param[in] i_l one of two AttnData structures.
+ * @param[in] i_r one of two AttnData structures.
+ *
+ * @raturn int64_t The result of the comparison.
+ *
+ * @retval[-1] i_l < i_r
+ * @retval[1] i_r < i_l
+ * @retval[0] equivalent
+ */
+int64_t compare(const PRDF::AttnData & i_l, const PRDF::AttnData & i_r);
+
+}
+#endif
diff --git a/src/usr/diag/attn/attnlist.C b/src/usr/diag/attn/attnlist.C
new file mode 100644
index 000000000..d9075c105
--- /dev/null
+++ b/src/usr/diag/attn/attnlist.C
@@ -0,0 +1,79 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attnlist.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 attnlist.C
+ *
+ * @brief HBATTN AttentionList function definitions.
+ */
+
+#include "attnfwd.H"
+#include "attnlist.H"
+#include "attnops.H"
+#include <algorithm>
+
+using namespace std;
+using namespace PRDF;
+
+namespace ATTN
+{
+
+AttentionList & AttentionList::merge(const AttentionList & i_src)
+{
+ // union of two attention lists
+
+ const_iterator sit = i_src.begin();
+ iterator dit = begin();
+
+ while(sit != i_src.end())
+ {
+ dit = insert(lower_bound(dit, end(), *sit), *sit);
+ ++sit;
+ }
+
+ return *this;
+}
+
+void AttentionList::getAttnList(PRDF::AttnList & o_dest) const
+{
+ // convert AttentionList to PRDF::AttnList
+
+ const_iterator sit = begin();
+
+ AttnData d;
+
+ while(sit != end())
+ {
+ sit->getData(d);
+
+ o_dest.push_back(d);
+
+ ++sit;
+ }
+}
+
+void AttentionList::add(const Attention & i_attn)
+{
+ insert(lower_bound(begin(), end(), i_attn), i_attn);
+}
+}
diff --git a/src/usr/diag/attn/attnlist.H b/src/usr/diag/attn/attnlist.H
new file mode 100644
index 000000000..e6701b6ef
--- /dev/null
+++ b/src/usr/diag/attn/attnlist.H
@@ -0,0 +1,118 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attnlist.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_ATTNLIST_H
+#define __ATTN_ATTNLIST_H
+
+/**
+ * @file attnlist.H
+ *
+ * @brief HBATTN AttentionList definition.
+ */
+
+#include "attnops.H"
+#include "attnfwd.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief AttentionList Class definition.
+ *
+ * Container for Attentions.
+ */
+class AttentionList : public std::vector<Attention>
+{
+ public:
+
+ /**
+ * @brief merge Merge two containers.
+ *
+ * @param[in] i_src Container from which elements are merged.
+ *
+ * @return AttentionList Merged attention list.
+ */
+ AttentionList & merge(const AttentionList & i_src);
+
+ /**
+ * @brief add Insert a new Attention element.
+ *
+ * @param[in] i_attn The attention element to add.
+ */
+ void add(const Attention & i_attn);
+
+ /**
+ * @brief getAttnList Convert to PRDF::AttnList.
+ *
+ * @param[out] o_dest Where PRDF::AttnData elements are placed.
+ */
+ void getAttnList(PRDF::AttnList & o_dest) const;
+
+ /**
+ * @brief forEach Invoke a functor on each element.
+ *
+ * @param[in] i_functor The functor to invoke.
+ *
+ * @return Functor The functor.
+ */
+ template<typename Functor>
+ Functor forEach(Functor i_functor) const
+ {
+ return std::for_each(begin(), end(), i_functor);
+ }
+
+ /**
+ * @brief split Create two lists by evaluating a predicate.
+ *
+ * @param[in/out] io_true Insert elements that evaluate true.
+ * @param[in/out] ioi_false Insert elements that evaluate false.
+ * @param[in] i_predicate The predicate to evaluate.
+ *
+ * @return Predicate The predicate functor.
+ */
+ template<typename Predicate>
+ Predicate split(AttentionList & io_true,
+ AttentionList & io_false,
+ Predicate i_predicate) const
+ {
+ const_iterator dit = begin();
+
+ while(dit != end())
+ {
+ i_predicate(*dit)
+ ? io_true.add(*dit)
+ : io_false.add(*dit);
+
+ ++dit;
+ }
+
+ return i_predicate;
+ }
+
+ /**
+ * @brief AttnListTest Provide access to unit test.
+ */
+ friend class ::AttnListTest;
+};
+}
+#endif
diff --git a/src/usr/diag/attn/attnlistutil.H b/src/usr/diag/attn/attnlistutil.H
new file mode 100644
index 000000000..79f909da0
--- /dev/null
+++ b/src/usr/diag/attn/attnlistutil.H
@@ -0,0 +1,101 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/attnlistutil.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
+#ifndef __ATTN_ATTNLISTUTIL_H
+#define __ATTN_ATTNLISTUTIL_H
+
+/**
+ * @file attnlistutil.H
+ *
+ * @brief HBATTN AttentionList utility type definitions.
+ */
+
+#include "attnfwd.H"
+#include "attnops.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief MaskFunct Mask attentions functor.
+ */
+struct MaskFunct
+{
+ errlHndl_t err;
+
+ MaskFunct() : err(0) {}
+
+ void operator()(const Attention & i_attn)
+ {
+ if(!err)
+ {
+ err = i_attn.mask();
+ }
+ }
+};
+
+/**
+ * @brief UnmaskFunct Unmask attentions functor.
+ */
+struct UnmaskFunct
+{
+ errlHndl_t err;
+
+ UnmaskFunct() : err(0) {}
+
+ void operator()(const Attention & i_attn)
+ {
+ if(!err)
+ {
+ err = i_attn.unmask();
+ }
+ }
+};
+
+/**
+ * @brief ClearedPredicate Attention query predicate.
+ */
+struct ClearedPredicate
+{
+ errlHndl_t err;
+
+ ClearedPredicate() : err(0) {}
+
+ bool operator()(const Attention & i_attn)
+ {
+ bool attnIsOn = false, condition = false;
+
+ if(!err)
+ {
+ err = i_attn.query(attnIsOn);
+
+ if(!err && !attnIsOn)
+ {
+ condition = true;
+ }
+ }
+
+ return condition;
+ }
+};
+}
+#endif
diff --git a/src/usr/diag/attn/attnops.H b/src/usr/diag/attn/attnops.H
new file mode 100644
index 000000000..2001522e5
--- /dev/null
+++ b/src/usr/diag/attn/attnops.H
@@ -0,0 +1,206 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attnops.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_ATTNOPS_H
+#define __ATTN_ATTNOPS_H
+
+/**
+ * @file attnops.H
+ *
+ * @brief HBATTN Attention and AttentionOps definitions.
+ */
+
+#include "attnfwd.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief AttentionOps Interface specification.
+ *
+ * For types that implement mask, unmask and query operations.
+ */
+class AttentionOps
+{
+ public:
+
+ /**
+ * @brief mask Mask this attention.
+ *
+ * @param[in] i_data the attention to be masked.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual errlHndl_t mask(const PRDF::AttnData & i_data) = 0;
+
+ /**
+ * @brief unmask Unmask this attention.
+ *
+ * @param[in] i_data the attention to be unmasked.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual errlHndl_t unmask(const PRDF::AttnData & i_data) = 0;
+
+ /**
+ * @brief query Test to see if this attention is active.
+ *
+ * @param[in] i_data the attention to be queried.
+ * @param[out] o_active true if attention is active.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual errlHndl_t query(const PRDF::AttnData & i_data,
+ bool & o_active) = 0;
+
+ /**
+ * @brief dtor
+ */
+ virtual ~AttentionOps() {}
+
+ /**
+ * @brief AttnOpsTest Provide access to unit test.
+ */
+ friend class AttnOpsTest;
+};
+
+/**
+ * @brief Attention Operation router.
+ *
+ * Routes Attention mask, unmask and query operations
+ * to the correct handler.
+ */
+class Attention
+{
+ public:
+
+ /**
+ * @brief mask Mask this attention.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t mask() const
+ {
+ return iv_ops->mask(iv_data);
+ }
+
+ /**
+ * @brief unmask Unmask this attention.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t unmask() const
+ {
+ return iv_ops->unmask(iv_data);
+ }
+
+ /**
+ * @brief query Test to see if this attention is active.
+ *
+ * @param[out] o_active true if attention is active.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t query(bool & o_active) const
+ {
+ return iv_ops->query(iv_data, o_active);
+ }
+
+ /**
+ * @brief getData Convert this attention to PRDF::AttnData.
+ *
+ * @param[out] o_data Converted attention.
+ */
+ void getData(PRDF::AttnData & o_data) const
+ {
+ o_data = iv_data;
+ }
+
+ /**
+ * @brief compare Compare two attentions.
+ *
+ * @param[in] i_rhs The other attention.
+ *
+ * @retval[-1] This attention is less than the other attention.
+ * @retval[1] This attention is greather than the other attention.
+ * @retval[0] This attention is equivalent to the other attention.
+ */
+ int64_t compare(const Attention & i_rhs) const;
+
+ /**
+ * @brief ctor
+ *
+ * @param[in] i_data The PRDF::AttnData representation of the attention.
+ * @param[in] i_ops The AttentionOps instance to which operations
+ * should be routed.
+ */
+ Attention(const PRDF::AttnData & i_data,
+ AttentionOps * i_ops)
+ : iv_data(i_data), iv_ops(i_ops) {}
+
+ private:
+
+ /**
+ * @brief iv_data The PRDF::AttnData representation of the attention.
+ */
+ PRDF::AttnData iv_data;
+
+ /**
+ * @brief iv_ops The AttentionOps instance to which operations
+ * should be routed.
+ */
+ AttentionOps * iv_ops;
+
+ /**
+ * @brief AttnOpsTest Provide access to unit test.
+ */
+ friend class ::AttnOpsTest;
+};
+
+/**
+ * @brief operator< Test two attentions for less than.
+ *
+ * @param[in] i_lhs The left hand side of the comparison.
+ * @param[in] i_rhs The right hand side of the comparison.
+ *
+ * @retval[true] i_lhs is less than i_rhs.
+ * @retval[false] i_lhs is not less than i_rhs.
+ */
+inline bool operator<(const Attention & i_lhs, const Attention & i_rhs)
+{
+ return i_lhs.compare(i_rhs) < 0;
+}
+}
+#endif
diff --git a/src/usr/diag/attn/attnprd.H b/src/usr/diag/attn/attnprd.H
new file mode 100644
index 000000000..5569c0ab9
--- /dev/null
+++ b/src/usr/diag/attn/attnprd.H
@@ -0,0 +1,122 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attnprd.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_ATTNPRD_H
+#define __ATTN_ATTNPRD_H
+
+/**
+ * @file attnprd.H
+ *
+ * @brief HBATTN PRD wrapper class definitions.
+ */
+
+#include "attnfwd.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief PrdImpl PRD implementation interface requirement.
+ *
+ * Default implementation forwards call to real PRD.
+ */
+class PrdImpl
+{
+ public:
+
+ /**
+ * @brief callPrd Forward PRD call to real PRD.
+ *
+ * @param[in] i_attentions List of attentions for PRD to analyze.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual errlHndl_t callPrd(const AttentionList & i_attentions);
+
+ /**
+ * @brief dtor
+ */
+ virtual ~PrdImpl() {}
+
+ /**
+ * @brief ctor
+ */
+ PrdImpl() {}
+};
+
+/**
+ * @brief PrdWrapper Hold the installed prd implementation.
+ */
+class PrdWrapper
+{
+ public:
+
+ /**
+ * @brief callPrd Route PRD call to the active PRD implementation.
+ *
+ * @param[in] i_attentions List of attentions for PRD to analyze.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t callPrd(const AttentionList & i_attentions);
+
+ /**
+ * @brief setImpl Set the active PRD implementation.
+ *
+ * @param[in] i_prd The PRD implementation to make active.
+ */
+ void setImpl(PrdImpl & i_prd)
+ {
+ iv_impl = &i_prd;
+ }
+
+ /**
+ * @brief ctor
+ */
+ PrdWrapper();
+
+ private:
+
+ /**
+ * @brief iv_impl The active PRD implementation.
+ */
+ PrdImpl * iv_impl;
+
+ /**
+ * @brief copy Disabled.
+ */
+ PrdWrapper(const PrdWrapper &);
+
+ /**
+ * @brief assignment Disabled.
+ */
+ PrdWrapper & operator=(const PrdWrapper &);
+};
+}
+#endif
diff --git a/src/usr/diag/attn/attnresolv.H b/src/usr/diag/attn/attnresolv.H
new file mode 100644
index 000000000..c8c756710
--- /dev/null
+++ b/src/usr/diag/attn/attnresolv.H
@@ -0,0 +1,130 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attnresolv.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_ATTNRESOLV_H
+#define __ATTN_ATTNRESOLV_H
+
+/**
+ * @file attnresolv.H
+ *
+ * @brief HBATTN Resolver wrapper class definitions.
+ */
+
+#include "attnfwd.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief Resolver Resolver implementation interface requirement.
+ *
+ * Default implementation forwards call to Proc & Mem resolvers.
+ */
+class Resolver
+{
+ public:
+
+ /**
+ * @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[out] o_attentions Where to put attentions when found.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual errlHndl_t resolve(
+ TARGETING::TargetHandle_t i_proc,
+ AttentionList & o_attentions);
+
+ /**
+ * @brief dtor
+ */
+ virtual ~Resolver() {}
+
+ /**
+ * @brief ctor
+ */
+ Resolver() {}
+};
+
+/**
+ * @brief ResolverWrapper Hold the installed resolver implementation.
+ */
+class ResolverWrapper
+{
+ public:
+
+ /**
+ * @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[out] o_attentions Where to put attentions when found.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t resolve(
+ TARGETING::TargetHandle_t i_proc,
+ AttentionList & o_attentions);
+
+ /**
+ * @brief setImpl Set the active PRD implementation.
+ *
+ * @param[in] i_prd The PRD implementation to make active.
+ */
+ void setImpl(Resolver & i_resolver)
+ {
+ iv_impl = &i_resolver;
+ }
+
+ /**
+ * @brief ctor
+ */
+ ResolverWrapper();
+
+ private:
+
+ /**
+ * @brief iv_impl The active resolver implementation.
+ */
+ Resolver * iv_impl;
+
+ /**
+ * @brief copy Disabled.
+ */
+ ResolverWrapper(const ResolverWrapper &);
+
+ /**
+ * @brief assignment Disabled.
+ */
+ ResolverWrapper & operator=(const ResolverWrapper &);
+};
+}
+#endif
diff --git a/src/usr/diag/attn/attnsvc.C b/src/usr/diag/attn/attnsvc.C
new file mode 100644
index 000000000..85d399819
--- /dev/null
+++ b/src/usr/diag/attn/attnsvc.C
@@ -0,0 +1,427 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attnsvc.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 attnsvc.C
+ *
+ * @brief HBATTN background service class function definitions.
+ */
+
+#include <sys/msg.h>
+#include <errl/errlmanager.H>
+#include "attnsvc.H"
+#include "attntrace.H"
+#include "attnlistutil.H"
+#include "attnresolv.H"
+#include "attnprd.H"
+
+using namespace std;
+using namespace PRDF;
+using namespace TARGETING;
+using namespace ERRORLOG;
+
+namespace ATTN
+{
+
+void Service::intrTask(void * i_svc)
+{
+ // interrupt task loop
+
+ Service & svc = *static_cast<Service *>(i_svc);
+ bool shutdown = false;
+ msg_t * msg = 0;
+
+ while(true)
+ {
+ // wait for a shutdown message or interrupt
+
+ shutdown = svc.intrTaskWait(msg);
+
+ if(shutdown)
+ {
+ break;
+ }
+
+ // got an interrupt. process it
+
+ svc.processIntrQMsg(*msg);
+ }
+}
+
+bool Service::intrTaskWait(msg_t * & o_msg)
+{
+ // wait for a shutdown message
+ // or an interrupt
+
+ bool shutdown = false;
+ msg_q_t q = iv_intrTaskQ;
+
+ o_msg = msg_wait(q);
+
+ ATTN_FAST("...intr task woke up");
+
+ shutdown = o_msg->type == SHUTDOWN;
+
+ if(shutdown)
+ {
+ // this was a shutdown message.
+ // ack the message and tell the
+ // task loop to exit
+
+ iv_intrTaskQ = 0;
+ iv_shutdownPrdTask = true;
+
+ msg_respond(q, o_msg);
+
+ ATTN_FAST("interrupt task shutting down");
+ }
+
+ return shutdown;
+}
+
+errlHndl_t Service::processIntrQMsgPreAck(const msg_t & i_msg,
+ AttentionList & o_attentions)
+{
+ // this function should do as little as possible
+ // since the hw can't generate additional interrupts
+ // until the msg is acknowledged
+
+ errlHndl_t err = 0;
+
+ // FIXME replace with a real msg -> target conversion
+
+ TargetHandle_t proc = reinterpret_cast<TargetHandle_t>(i_msg.data[0]);
+
+ do {
+
+ // determine what has an attention
+
+ err = getResolverWrapper().resolve(proc, o_attentions);
+
+ if(err)
+ {
+ break;
+ }
+
+ // mask them
+
+ err = o_attentions.forEach(MaskFunct()).err;
+
+ if(err)
+ {
+ break;
+ }
+
+ } while(0);
+
+ return err;
+}
+
+void Service::processIntrQMsg(msg_t & i_msg)
+{
+ errlHndl_t err = 0;
+
+ AttentionList newAttentions;
+
+ // processIntrQMsgPreAck function should do as little as possible
+ // since the hw can't generate additional interrupts until the
+ // msg is acknowledged
+
+ err = processIntrQMsgPreAck(i_msg, newAttentions);
+
+ // respond to the interrupt service so hw
+ // can generate additional interrupts
+
+ msg_respond(iv_intrTaskQ, &i_msg);
+
+ if(err)
+ {
+ errlCommit(err, HBATTN_COMP_ID);
+ }
+ else if(!newAttentions.empty())
+ {
+ // put the new attentions in the list
+
+ mutex_lock(&iv_mutex);
+
+ iv_attentions.merge(newAttentions);
+
+ mutex_unlock(&iv_mutex);
+
+ // wake up the prd task
+
+ sync_cond_signal(&iv_cond);
+ }
+}
+
+void Service::prdTask(void * i_svc)
+{
+ // prd task loop
+
+ Service & svc = *static_cast<Service *>(i_svc);
+ bool shutdown = false;
+ AttentionList attentions;
+
+ // wait for a wakeup
+
+ while(true)
+ {
+ shutdown = svc.prdTaskWait(attentions);
+
+ if(shutdown)
+ {
+ // this was a shutdown wakeup.
+ // tell the prd task loop to exit
+
+ break;
+ }
+
+ // new attentions for prd to handle
+
+ svc.processAttentions(attentions);
+ }
+}
+
+bool Service::prdTaskWait(AttentionList & o_attentions)
+{
+ // wait for a wakeup
+
+ bool shutdown = false;
+
+ mutex_lock(&iv_mutex);
+
+ while(iv_attentions.empty() && !iv_shutdownPrdTask)
+ {
+ sync_cond_wait(&iv_cond, &iv_mutex);
+
+ ATTN_FAST("...prd task woke up");
+ }
+
+ o_attentions = iv_attentions;
+ iv_attentions.clear();
+
+ if(o_attentions.empty() && iv_shutdownPrdTask)
+ {
+ swap(shutdown, iv_shutdownPrdTask);
+ }
+
+ mutex_unlock(&iv_mutex);
+
+ if(shutdown)
+ {
+ ATTN_FAST("prd task shutting down");
+ }
+
+ return shutdown;
+}
+
+void Service::processAttentions(const AttentionList & i_attentions)
+{
+ errlHndl_t err = 0;
+
+ err = getPrdWrapper().callPrd(i_attentions);
+
+ if(err)
+ {
+ errlCommit(err, HBATTN_COMP_ID);
+ }
+
+ do {
+
+ // figure out which attentions PRD did not clear.
+
+ AttentionList cleared, uncleared;
+
+ err = i_attentions.split(cleared, uncleared, ClearedPredicate()).err;
+
+ if(err)
+ {
+ break;
+ }
+
+ mutex_lock(&iv_mutex);
+
+ // reinsert attentions PRD did not clear.
+
+ iv_attentions.merge(uncleared);
+
+ mutex_unlock(&iv_mutex);
+
+ // unmask cleared attentions
+
+ err = cleared.forEach(UnmaskFunct()).err;
+
+ if(err)
+ {
+ break;
+ }
+
+ } while(0);
+
+ if(err)
+ {
+ errlCommit(err, HBATTN_COMP_ID);
+ }
+}
+
+errlHndl_t Service::stop()
+{
+ ATTN_SLOW("shutting down...");
+
+ mutex_lock(&iv_mutex);
+
+ tid_t intrTask = iv_intrTask;
+ tid_t prdTask = iv_prdTask;
+
+ msg_q_t q = iv_intrTaskQ;
+
+ iv_intrTask = 0;
+ iv_prdTask = 0;
+
+ mutex_unlock(&iv_mutex);
+
+ if(intrTask)
+ {
+ unRegisterMsgQ(INTR::ATTENTION);
+
+ msg_t * shutdownMsg = msg_allocate();
+ shutdownMsg->type = SHUTDOWN;
+
+ msg_sendrecv(q, shutdownMsg);
+ msg_free(shutdownMsg);
+
+ task_wait_tid(intrTask, 0, 0);
+
+ msg_q_destroy(q);
+ }
+
+ if(prdTask)
+ {
+ sync_cond_signal(&iv_cond);
+ task_wait_tid(prdTask, 0, 0);
+ }
+
+ ATTN_SLOW("..shutdown complete");
+
+ return 0;
+}
+
+bool Service::startIntrTask()
+{
+ if(!iv_intrTask)
+ {
+ iv_intrTask = task_create(&intrTask, this);
+ }
+
+ return iv_intrTask != 0;
+}
+
+bool Service::startPrdTask()
+{
+ if(!iv_prdTask)
+ {
+ iv_prdTask = task_create(&prdTask, this);
+ }
+
+ return iv_prdTask != 0;
+}
+
+errlHndl_t Service::start()
+{
+ errlHndl_t err = 0;
+ bool cleanStartup = false;
+
+ ATTN_SLOW("starting...");
+
+ mutex_lock(&iv_mutex);
+
+ do {
+
+ if(!iv_intrTaskQ) {
+
+ // register msg q with interrupt
+ // service for attention type interrupts
+
+ msg_q_t q = msg_q_create();
+
+ err = registerMsgQ(q, INTR::ATTENTION, INTR::ATTENTION);
+
+ if(err)
+ {
+ msg_q_destroy(q);
+ break;
+ }
+
+ iv_intrTaskQ = q;
+ }
+
+ if(!startIntrTask())
+ {
+ break;
+ }
+
+ if(!startPrdTask())
+ {
+ break;
+ }
+
+ cleanStartup = true;
+
+ } while(0);
+
+ mutex_unlock(&iv_mutex);
+
+ if(!cleanStartup)
+ {
+ // TODO
+ }
+ else
+ {
+ ATTN_SLOW("..startup complete");
+ }
+ return err;
+}
+
+Service::Service() :
+ iv_intrTaskQ(0),
+ iv_shutdownPrdTask(false),
+ iv_prdTask(0),
+ iv_intrTask(0)
+{
+ mutex_init(&iv_mutex);
+ sync_cond_init(&iv_cond);
+}
+
+Service::~Service()
+{
+ errlHndl_t err = stop();
+
+ if(err)
+ {
+ // TODO
+ }
+
+ sync_cond_destroy(&iv_cond);
+ mutex_destroy(&iv_mutex);
+}
+}
diff --git a/src/usr/diag/attn/attnsvc.H b/src/usr/diag/attn/attnsvc.H
new file mode 100644
index 000000000..19cd9a9e7
--- /dev/null
+++ b/src/usr/diag/attn/attnsvc.H
@@ -0,0 +1,258 @@
+// 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
+#ifndef __ATTN_ATTNSVC_H
+#define __ATTN_ATTNSVC_H
+
+/**
+ * @file attnsvc.H
+ *
+ * @brief HBATTN background service class definition.
+ */
+
+#include <sys/task.h>
+#include <sys/sync.h>
+#include "attnfwd.H"
+#include "attnlist.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief Service Host attention handler background service class definition.
+ */
+class Service
+{
+ public:
+
+ /**
+ * @brief stop Stop the background attention handler service.
+ *
+ * Noop if service already stopped.
+ *
+ * @post Service stopped. All resources reclaimed.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error.
+ */
+ errlHndl_t stop();
+
+ /**
+ * @brief start start the background attention handler service
+ *
+ * noop if service already started
+ *
+ * @post service started.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] no error
+ * @retval[!0] unexpected error
+ */
+ errlHndl_t start();
+
+ /**
+ * @brief ctor
+ */
+ Service();
+
+ /**
+ * @brief dtor
+ */
+ ~Service();
+
+ private:
+
+ /**
+ * @brief intrTask infinite wait-for-interrupt loop
+ *
+ * repeatedly call intrTaskWait and processIntrQMsg
+ *
+ * @param[in] i_svc service object associated with task
+ */
+ static void intrTask(void * i_svc);
+
+ /**
+ * @brief prdTask infinite wait-for-attention loop
+ *
+ * repeatedly call prdTaskWait and processAttentions
+ *
+ * @param[in] i_svc service object associated with task
+ */
+ static void prdTask(void * i_svc);
+
+ /**
+ * @brief startIntrTask start task helper function
+ *
+ * check to see if task already started
+ *
+ * @return bool Operation status.
+ *
+ * @retval[true] task started
+ * @retval[false] task not started
+ */
+ bool startIntrTask();
+
+ /**
+ * @brief intrTaskWait wait for message on msg Q
+ *
+ * Messages are either shutdown messages or messages from
+ * the interrupt service. Handle shutdown messages directly or
+ * defer interrupt service messages to processIntrQMsg
+ *
+ * @post new message available.
+ *
+ * @param[out] o_msg interrupt svc intr message
+ *
+ * @return bool Shutdown instruction.
+ *
+ * @retval[true] shutdown requested
+ * @retval[false] shutdown not requested
+ */
+ bool intrTaskWait(msg_t * & o_msg);
+
+ /**
+ * @brief processIntrQMsg process interrupt service message
+ *
+ * resolve interrupt service message into attentions and
+ * route to prd for analysis
+ *
+ * @post attentions routed to prd for analysis
+ *
+ * @param[in] i_msg interrupt svc intr message to be processed
+ */
+ void processIntrQMsg(msg_t & i_msg);
+
+ /**
+ * @brief processIntrQMsgPreAck pre EOI interrupt service message
+ * processing
+ *
+ * perform the interrupt service message processing steps that must
+ * be done before EOI can be sent by the interrupt service. Namely
+ * resolve and mask the interrupt causing attentions.
+ *
+ * @post interrupt service message ready to be acknowledged
+ *
+ * @param[in] i_msg interrupt svc intr message to be processed
+ * @param[out] o_attentions attentions associated with interrupt msg
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] no error
+ * @retval[!0] unexpected error
+ */
+ errlHndl_t processIntrQMsgPreAck(const msg_t & i_msg,
+ AttentionList & o_attentions);
+
+ /**
+ * @brief startPrdTask start task helper function
+ *
+ * check to see if task already started
+ *
+ * @return bool Operation status.
+ *
+ * @retval[true] task started
+ * @retval[false] task not started
+ */
+ bool startPrdTask();
+
+ /**
+ * @brief prdTaskWait wait for wakeup
+ *
+ * Wakeups are either shutdown wakeups or wakeups from
+ * the interrupt task. Handle shutdown wakeups directly or
+ * defer interrupt task wakeups to processAttentions
+ *
+ * @post new attentions available
+ *
+ * @return bool Shutdown instruction.
+ *
+ * @retval[true] shutdown requested
+ * @retval[false] shutdown not requested
+ */
+ bool prdTaskWait(AttentionList & o_attentions);
+
+ /**
+ * @brief processAttentions process interrupt task wakeup
+ *
+ * call prd to analyze attentions
+ *
+ * @post attentions analyzed by prd. attentions cleard by prd unmasked
+ *
+ * @param[in] i_attentions attentions to be processed by prd
+ */
+ void processAttentions(const AttentionList & i_attentions);
+
+ /**
+ * @brief iv_attentions all active attentions in the node
+ */
+ AttentionList iv_attentions;
+
+ /**
+ * @brief iv_intrTaskQ intr task message q
+ */
+ msg_q_t iv_intrTaskQ;
+
+ /**
+ * @brief iv_shutdownPrdTask prd task shutdown flag
+ */
+ bool iv_shutdownPrdTask;
+
+ /**
+ * @brief iv_prdTask prd task tid
+ */
+ tid_t iv_prdTask;
+
+ /**
+ * @brief iv_intrTask intr task tid
+ */
+ tid_t iv_intrTask;
+
+ /**
+ * @brief iv_mutex pendingAttentions protection
+ */
+ mutex_t iv_mutex;
+
+ /**
+ * @brief iv_cond pendingAttentions and shutdown flag condition
+ */
+ sync_cond_t iv_cond;
+
+ /**
+ * @brief copy disabled
+ */
+ Service(const Service &);
+
+ /**
+ * @brief assignment disabled
+ */
+ Service &operator=(const Service &);
+
+ /**
+ * @brief AttnSvcTest Provide access to unit test.
+ */
+ friend class ::AttnSvcTest;
+};
+}
+#endif
diff --git a/src/usr/diag/attn/attntrace.C b/src/usr/diag/attn/attntrace.C
new file mode 100644
index 000000000..c21c8d61c
--- /dev/null
+++ b/src/usr/diag/attn/attntrace.C
@@ -0,0 +1,39 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/attntrace.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 attntrace.C
+ *
+ * @brief HBATTN trace descriptors.
+ */
+
+#include "attntrace.H"
+
+namespace ATTN
+{
+
+trace_desc_t * fastTd = 0, * slowTd = 0;
+
+TRAC_INIT(&fastTd, "ATTN_FAST", 4096);
+TRAC_INIT(&slowTd, "ATTN_SLOW", 4096);
+}
diff --git a/src/usr/diag/attn/attntrace.H b/src/usr/diag/attn/attntrace.H
new file mode 100644
index 000000000..bc74cf919
--- /dev/null
+++ b/src/usr/diag/attn/attntrace.H
@@ -0,0 +1,47 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/attntrace.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
+#ifndef __ATTN_ATTNTRACE_H
+#define __ATTN_ATTNTRACE_H
+
+/**
+ * @file attntrace.H
+ *
+ * @brief HBATTN trace macros.
+ */
+
+#include <trace/interface.H>
+
+namespace ATTN
+{
+
+extern trace_desc_t * fastTd;
+extern trace_desc_t * slowTd;
+
+}
+
+#define ATTN_DBG( _fmt_, _args_...) TRACDCOMP( ATTN::fastTd, INFO_MRK""_fmt_, ##_args_)
+#define ATTN_FAST( _fmt_, _args_...) TRACFCOMP( ATTN::fastTd, INFO_MRK""_fmt_, ##_args_)
+#define ATTN_SLOW( _fmt_, _args_...) TRACFCOMP( ATTN::slowTd, INFO_MRK""_fmt_, ##_args_)
+#define ATTN_ERR( _fmt_, _args_...) TRACFCOMP( ATTN::slowTd, ERR_MRK""_fmt_, ##_args_)
+
+#endif
diff --git a/src/usr/diag/attn/makefile b/src/usr/diag/attn/makefile
new file mode 100644
index 000000000..d63fc623b
--- /dev/null
+++ b/src/usr/diag/attn/makefile
@@ -0,0 +1,33 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/diag/attn/makefile $
+#
+# 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
+ROOTPATH = ../../../..
+
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/diag
+
+MODULE = attn
+
+OBJS = attntrace.o attn.o attnsvc.o attnlist.o
+
+SUBDIRS = test.d
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/diag/attn/test/attnfakesys.C b/src/usr/diag/attn/test/attnfakesys.C
new file mode 100644
index 000000000..a91f5f395
--- /dev/null
+++ b/src/usr/diag/attn/test/attnfakesys.C
@@ -0,0 +1,349 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/test/attnfakesys.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
+/**
+ * @file attnfakesys.C
+ *
+ * @brief HBATTN fake system class method definitions.
+ */
+
+#include "../attnlist.H"
+#include "../attntrace.H"
+#include "attnfakesys.H"
+#include "attntest.H"
+#include <sys/msg.h>
+
+using namespace std;
+using namespace PRDF;
+using namespace TARGETING;
+
+namespace ATTN
+{
+
+errlHndl_t FakeSystem::mask(const PRDF::AttnData & i_data)
+{
+ mutex_lock(&iv_mutex);
+
+ // mark the attention as masked and
+ // indicate that mask was called in the
+ // event history
+
+ iv_map[i_data].mask = true;
+ iv_map[i_data].history.push_back(MASK_EVENT);
+
+ mutex_unlock(&iv_mutex);
+
+ return 0;
+}
+
+errlHndl_t FakeSystem::unmask(const PRDF::AttnData & i_data)
+{
+ mutex_lock(&iv_mutex);
+
+ // mark the attention as unmasked and
+ // indicate that unmask was called in the
+ // event history
+
+ iv_map[i_data].mask = false;
+ iv_map[i_data].history.push_back(UNMASK_EVENT);
+
+ mutex_unlock(&iv_mutex);
+
+ return 0;
+}
+
+errlHndl_t FakeSystem::query(const PRDF::AttnData & i_data, bool & o_active)
+{
+ mutex_lock(&iv_mutex);
+
+ // provide the status of the attention and
+ // indicate that query was called in the
+ // event history
+
+ o_active = iv_map[i_data].active;
+ iv_map[i_data].history.push_back(QUERY_EVENT);
+
+ mutex_unlock(&iv_mutex);
+
+ return 0;
+}
+
+errlHndl_t FakeSystem::resolve(
+ TargetHandle_t i_proc,
+ AttentionList & o_attentions)
+{
+ mutex_lock(&iv_mutex);
+
+ // check each attention in the map
+ // and add any marked active
+ // to the output list
+
+ map<AttnData, FakeSystemProperties>::iterator it = iv_map.begin();
+
+ while(it != iv_map.end())
+ {
+ if(it->first.targetHndl == i_proc
+ && it->second.active && !it->second.mask)
+ {
+ o_attentions.add(Attention(it->first, this));
+ }
+
+ ++it;
+ }
+
+ mutex_unlock(&iv_mutex);
+
+ return 0;
+}
+
+errlHndl_t FakeSystem::callPrd(const AttentionList & i_attentions)
+{
+ AttnList l;
+
+ i_attentions.getAttnList(l);
+
+ AttnList::iterator it = l.begin();
+
+ mutex_lock(&iv_mutex);
+
+ // simulate prd by clearing any attentions passed in and
+ // indicate that prd was called in the
+ // event history
+
+ while(it != l.end())
+ {
+ iv_map[*it].active = false;
+ iv_map[*it].history.push_back(CALLPRD_EVENT);
+
+ ++it;
+ }
+
+ mutex_unlock(&iv_mutex);
+
+ return 0;
+}
+
+uint64_t FakeSystem::raiseAttentions(msg_q_t i_q, uint64_t i_count)
+{
+ AttnList list;
+
+ mutex_lock(&iv_mutex);
+
+ uint64_t count = generateAttentions(i_count, list);
+
+ AttnList::iterator it = list.begin();
+
+ while(it != list.end())
+ {
+ iv_map[*it].active = true;
+ iv_map[*it].count++;
+
+ ++it;
+ }
+
+ mutex_unlock(&iv_mutex);
+
+ it = list.begin();
+
+ while(it != list.end())
+ {
+ msg_t * m = msg_allocate();
+
+ m->type = ATTENTION;
+ m->data[0] = reinterpret_cast<uint64_t>(it->targetHndl);
+
+ msg_sendrecv(i_q, m);
+ ++it;
+ }
+
+ return count;
+}
+
+void FakeSystem::install()
+{
+ // register this objects
+ // functions as the
+ // resolver and prd implementations
+
+ getResolverWrapper().setImpl(*this);
+ getPrdWrapper().setImpl(*this);
+}
+
+ATTENTION_VALUE_TYPE getRandomAttentionType()
+{
+ ATTENTION_VALUE_TYPE a;
+
+ switch (randint(1, 3))
+ {
+ case 1:
+ a = CHECK_STOP;
+ break;
+ case 2:
+ a = RECOVERABLE;
+ break;
+ case 3:
+ default:
+ a = SPECIAL;
+ break;
+ };
+
+ return a;
+}
+
+uint64_t FakeSystem::generateAttentions(uint64_t i_count, AttnList & io_list)
+{
+ static const TargetHandle_t nullTarget = 0;
+ static const uint64_t numTypes = 3;
+ static const uint64_t maxTargets = 64;
+
+ uint64_t count = 0;
+
+ uint64_t remaining = maxTargets * numTypes;
+
+ while(i_count != 0 && remaining > 0)
+ {
+ AttnData d;
+
+ // generate a "random" attention on one of maxTargets possible targets
+
+ d.targetHndl = nullTarget + randint(1, maxTargets);
+ d.attnType = getRandomAttentionType();
+
+ map<AttnData, FakeSystemProperties>::iterator it
+ = iv_map.lower_bound(d);
+
+ if(it != iv_map.end() && !compare(it->first, d)
+ && (it->second.active || it->second.mask))
+ {
+ // the random attention algorithm might
+ // generate an attention
+ // that is already active or masked...
+ // since this class simulates
+ // behaving hardware, don't use those
+
+ --remaining;
+ }
+ else
+ {
+ // check for a duplicate attention
+ // already in the list
+
+ AttnList::iterator lit = io_list.begin();
+
+ while(lit != io_list.end())
+ {
+ if(!compare(*lit, d))
+ {
+ break;
+ }
+
+ ++lit;
+ }
+
+ if(lit == io_list.end())
+ {
+ io_list.push_back(d);
+
+ ++count;
+ --remaining;
+ }
+ }
+
+ --i_count;
+ }
+
+ return count;
+}
+
+bool FakeSystem::validate()
+{
+ static const uint64_t seq[] = {
+ MASK_EVENT,
+ CALLPRD_EVENT,
+ QUERY_EVENT,
+ UNMASK_EVENT,
+ };
+ static const uint64_t * seqEnd = seq
+ +sizeof(seq)/sizeof(*seq);
+
+ // this class simulates behaving hardware,
+ // and PRD code that will clear every error.
+ // using those assumptions, validate
+ // the correct sequence occurred for each attention
+
+ bool valid = true;
+
+ mutex_lock(&iv_mutex);
+
+ map<AttnData, FakeSystemProperties>::const_iterator it = iv_map.begin();
+
+ while(it != iv_map.end())
+ {
+ vector<uint64_t> & history = it->second.history;
+
+ vector<uint64_t>::const_iterator hit = history.begin();
+ const uint64_t * sit = seq;
+
+ uint64_t count = it->second.count;
+
+ while(count > 0 && hit != history.end())
+ {
+ if(*sit != *hit)
+ {
+ break;
+ }
+
+ ++sit;
+ ++hit;
+
+ if(sit == seqEnd)
+ {
+ sit = seq;
+ --count;
+ }
+ }
+
+ if(count)
+ {
+ valid = false;
+ break;
+ }
+
+ ++it;
+ }
+
+ mutex_unlock(&iv_mutex);
+
+ return valid;
+}
+
+FakeSystem::FakeSystem()
+ : iv_map(Comp())
+{
+ mutex_init(&iv_mutex);
+}
+
+FakeSystem::~FakeSystem()
+{
+ mutex_destroy(&iv_mutex);
+}
+}
diff --git a/src/usr/diag/attn/test/attnfakesys.H b/src/usr/diag/attn/test/attnfakesys.H
new file mode 100644
index 000000000..2ab0c4ec7
--- /dev/null
+++ b/src/usr/diag/attn/test/attnfakesys.H
@@ -0,0 +1,261 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/test/attnfakesys.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_ATTNFAKESYS_H
+#define __TEST_ATTNFAKESYS_H
+
+/**
+ * @file attnfakesys.H
+ *
+ * @brief HBATTN fake system class definition.
+ */
+
+#include "../attnfwd.H"
+#include "../attnops.H"
+#include "../attnprd.H"
+#include "../attnresolv.H"
+#include <map>
+
+namespace ATTN
+{
+
+/**
+ * @brief Event fake system event trace types.
+ */
+enum Event
+{
+ /**
+ * @brief MASK_EVENT A simulated attention was masked.
+ */
+ MASK_EVENT,
+
+ /**
+ * @brief UNMASK_EVENT A simulated attention was unmasked.
+ */
+ UNMASK_EVENT,
+
+ /**
+ * @brief QUERY_EVENT A simulated attention was queried.
+ */
+ QUERY_EVENT,
+
+ /**
+ * @brief CALLPRD_EVENT A simulated attention was forwarded to PRD.
+ */
+ CALLPRD_EVENT,
+};
+
+/**
+ * @brief FakeSystemProperties data associated with a simulated attention.
+ */
+struct FakeSystemProperties
+{
+ /**
+ * @brief mask The mask state of the simulated attention.
+ */
+ bool mask;
+
+ /**
+ * @brief active The state of the simulated attention.
+ */
+ bool active;
+
+ /**
+ * @brief count The number of times the simulated attention has occurred.
+ */
+ uint64_t count;
+
+ /**
+ * @brief history Simlated aattention trace.
+ */
+ std::vector<uint64_t> history;
+
+ /**
+ * @brief ctor
+ */
+ FakeSystemProperties() : mask(false), active(false), count(0) {}
+};
+
+/**
+ * @brief Comp Comparison functor for two PRDF::AttnData structs.
+ */
+struct Comp
+{
+ /**
+ * @brief operator() Comparison functor for two PRDF::AttnData structs.
+ *
+ * @param[in] i_l One of two PRDF::AttnData structs to be compared.
+ * @param[in] i_r One of two PRDF::AttnData structs to be compared.
+ *
+ * @return bool Comparison result.
+ *
+ * @retval[true] i_l < i_r;
+ * @retval[false ] i_r < i_l;
+ */
+ bool operator()(const PRDF::AttnData & i_l,
+ const PRDF::AttnData & i_r) const
+ {
+ return compare(i_l, i_r) < 0;
+ }
+};
+
+/**
+ * @brief FakeSystem
+ *
+ * AttentionOps, Resolver and PRD implementations that simulate
+ * normal system behavior.
+ */
+class FakeSystem :
+ public AttentionOps,
+ public Resolver,
+ public PrdImpl
+{
+ public:
+
+ /**
+ * @brief mask Mask this attention.
+ *
+ * @param[in] i_data the attention to be masked.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual errlHndl_t mask(const PRDF::AttnData & i_data);
+
+ /**
+ * @brief unmask Unmask this attention.
+ *
+ * @param[in] i_data the attention to be unmasked.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual 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 be queried.
+ * @param[out] o_active true if attention is active.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual 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[out] o_attentions Where to put attentions when found.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual errlHndl_t resolve(
+ TARGETING::TargetHandle_t i_proc,
+ AttentionList & o_attentions);
+
+ /**
+ * @brief callPrd Simulate a call to PRD.
+ *
+ * @param[in] i_attentions List of attentions for PRD to analyze.
+ *
+ * @return errlHndl_t Error log.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ virtual errlHndl_t callPrd(const AttentionList & i_attentions);
+
+ /**
+ * @brief install install this class as the prd and resolver
+ * implementation.
+ */
+ void install();
+
+ /**
+ * @brief raiseAttentions Attempt to raise random attentions.
+ *
+ * @param[in] i_q The message Q where simulated attention
+ * messages should be sent.
+ * @param[i_count] The number of attentions to generate.
+ *
+ * @return The actual number of attentions raised.
+ */
+ uint64_t raiseAttentions(msg_q_t i_q, uint64_t i_count);
+
+ /**
+ * @brief validate Perform validation of the simulated system.
+ *
+ * @return The result of the validation.
+ *
+ * @retval[true] Result is valid.
+ * @retval[false] Result is invalid.
+ */
+ virtual bool validate();
+
+ /**
+ * @brief ctor
+ */
+ FakeSystem();
+
+ /**
+ * @brief dtor
+ */
+ virtual ~FakeSystem();
+
+ private:
+
+ /**
+ * @brief generateAttentions Generate random attentions.
+ *
+ * @param[in] i_count The number of attentions to generate.
+ * @param[in/out] io_list Where generated attentions are placed.
+ *
+ * @return uint64_t The actual number of attentions generated.
+ */
+ uint64_t generateAttentions(uint64_t i_count, PRDF::AttnList & io_list);
+
+ /**
+ * @brief iv_map Attention <-> state association.
+ */
+ std::map<PRDF::AttnData, FakeSystemProperties, Comp> iv_map;
+
+ /**
+ * @brief iv_mutex iv_map protection.
+ */
+ mutex_t iv_mutex;
+};
+}
+#endif
diff --git a/src/usr/diag/attn/test/attnrand.S b/src/usr/diag/attn/test/attnrand.S
new file mode 100644
index 000000000..6bc887f22
--- /dev/null
+++ b/src/usr/diag/attn/test/attnrand.S
@@ -0,0 +1,32 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/diag/attn/test/attnrand.S $
+#
+# 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
+.include "kernel/ppcconsts.S"
+
+.section .text
+
+.global generate_random
+
+generate_random:
+ li r3, 0
+ rlwimi 0x1b,0x1b,0x0,0x6,0x10
+ blr
diff --git a/src/usr/diag/attn/test/attntest.C b/src/usr/diag/attn/test/attntest.C
new file mode 100644
index 000000000..136c7027f
--- /dev/null
+++ b/src/usr/diag/attn/test/attntest.C
@@ -0,0 +1,78 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/test/attntest.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 attntest.C
+ *
+ * @brief HBATTN test utility function definitions.
+ */
+
+#include <arch/ppc.H>
+#include <algorithm>
+#include "attntest.H"
+#include "../attntrace.H"
+
+using namespace std;
+
+namespace ATTN
+{
+
+uint64_t randint(uint64_t i_min, uint64_t i_max)
+{
+ static bool setup = false;
+ static uint64_t hapSeed = generate_random();
+
+ if(!setup)
+ {
+ if(!hapSeed)
+ {
+ ATTN_DBG("falling back to timebase seed for PRNG");
+ }
+ else
+ {
+ ATTN_DBG("hapseed: %d", hapSeed);
+ }
+
+ setup = true;
+ }
+
+ static uint64_t seed = hapSeed ? hapSeed : getTB() + 1;
+
+ uint64_t lo, hi;
+
+ seed = seed * seed;
+ lo = (seed & 0x0000ffffffff0000ull) >> 16;
+ hi = (seed & 0x000000000000ffffull) << 32;
+ hi |= (seed & 0xffff000000000000ull);
+ seed = lo;
+
+ uint64_t min = i_min, max = i_max;
+
+ if(i_min > i_max)
+ {
+ swap(min, max);
+ }
+
+ return ((lo | hi) % (i_max +1 - i_min)) + i_min;
+}
+}
diff --git a/src/usr/diag/attn/test/attntest.H b/src/usr/diag/attn/test/attntest.H
new file mode 100644
index 000000000..96b0f3749
--- /dev/null
+++ b/src/usr/diag/attn/test/attntest.H
@@ -0,0 +1,56 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/test/attntest.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
+#ifndef __TEST_ATTNTEST_H
+#define __TEST_ATTNTEST_H
+
+/**
+ * @file attntest.H
+ *
+ * @brief HBATTN test utility function declarations.
+ */
+
+#include "../attnfwd.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief randint Generate random integer between bounds.
+ *
+ * @param[in] i_min The minimum bound.
+ * @param[in] i_max The maximum bound.
+ *
+ * @return uint64_t Generated random integer.
+ */
+uint64_t randint(uint64_t i_min, uint64_t i_max);
+
+/**
+ * @brief generate_random Issue a magic instruction
+ * with a hap callback that fetches a random
+ * number from the simics host.
+ *
+ * @return uint64_t Random integer from simics host.
+ */
+extern "C" uint64_t generate_random();
+}
+#endif
diff --git a/src/usr/diag/attn/test/attntestlist.H b/src/usr/diag/attn/test/attntestlist.H
new file mode 100644
index 000000000..c8c23f48b
--- /dev/null
+++ b/src/usr/diag/attn/test/attntestlist.H
@@ -0,0 +1,401 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/test/attntestlist.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_ATTNTESTLIST_H
+#define __TEST_ATTNTESTLIST_H
+
+/**
+ * @file attntestlist.H
+ *
+ * @brief Unit test for the attnlist module.
+ */
+
+#include "../attnfwd.H"
+#include "../attnlist.H"
+#include <cxxtest/TestSuite.H>
+
+using namespace ATTN;
+using namespace TARGETING;
+using namespace PRDF;
+
+/**
+ * @brief CounterFunct Functor for testing the forEach method.
+ */
+struct CounterFunct
+{
+ uint64_t counter;
+
+ CounterFunct() : counter(0) {}
+
+ void operator()(const Attention &)
+ {
+ counter++;
+ }
+};
+
+/**
+ * @brief CheckstopPredicate Predicate for testing split method.
+ */
+struct CheckstopPredicate
+{
+ bool operator()(const Attention & i_attn)
+ {
+ AttnData d;
+
+ i_attn.getData(d);
+
+ return d.attnType == CHECK_STOP;
+ }
+};
+
+/**
+ * @brief AttnListTest Unit test for the attnlist module.
+ */
+class AttnListTest : public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief testEmpty Unit test for the
+ * empty method.
+ */
+ void testEmpty(void)
+ {
+ static AttentionOps * nullOps = 0;
+
+ TS_TRACE(ENTER_MRK "testEmpty");
+
+ do {
+
+ AttentionList l;
+
+ if(!l.empty())
+ {
+ TS_FAIL("Defalt constructed attention list not empty");
+ break;
+ }
+
+ l.add(Attention(AttnData(), nullOps));
+
+ if(l.empty())
+ {
+ TS_FAIL("Attention list empty after insert");
+ break;
+ }
+
+ } while(0);
+
+ TS_TRACE(EXIT_MRK "testEmpty");
+ }
+
+ /**
+ * @brief testInsert Unit test for the
+ * insert method.
+ */
+ void testInsert(void)
+ {
+ static AttentionOps * nullOps = 0;
+ static const uint64_t size = 10;
+
+ TS_TRACE(ENTER_MRK "testInsert");
+
+ AttentionList l;
+
+ for(uint64_t count = 0; count < size; ++count)
+ {
+ l.add(Attention(AttnData(), nullOps));
+ }
+
+ // verify correct number of elements inserted
+
+ if(l.size() != size)
+ {
+ TS_FAIL("Unexpected number of elements inserted: %d", l.size());
+ }
+
+ AttentionList::iterator it2 = l.begin();
+ AttentionList::iterator it1 = it2;
+ it2++;
+
+ while(it2 != l.end())
+ {
+ if((*it2) < (*it1))
+ {
+ TS_FAIL("Attention list not sorted");
+ break;
+ }
+
+ ++it1;
+ ++it2;
+ }
+
+ l.clear();
+
+ if(!l.empty())
+ {
+ TS_FAIL("Attention list not cleared");
+ }
+
+ TS_TRACE(EXIT_MRK "testInsert");
+ }
+
+ /**
+ * @brief testGetAttnList Unit test for the
+ * getAttnList method.
+ */
+ void testGetAttnList(void)
+ {
+ static AttentionOps * nullOps = 0;
+ static const TargetHandle_t nullTarget = 0;
+
+ static const AttnData tests[] =
+ {
+ {nullTarget, CHECK_STOP},
+ {nullTarget +1, CHECK_STOP},
+ {nullTarget +2, CHECK_STOP},
+ {nullTarget, RECOVERABLE},
+ {nullTarget +1, RECOVERABLE},
+ {nullTarget +2, RECOVERABLE},
+ };
+ static const AttnData * testsEnd = tests
+ + sizeof(tests)/sizeof(*tests);
+
+ TS_TRACE(ENTER_MRK "testGetAttnList");
+
+ const AttnData * testIt = tests;
+
+ AttentionList attentionList;
+
+ while(testIt != testsEnd)
+ {
+ AttentionList l;
+ l.add(Attention(*testIt, nullOps));
+ attentionList.add(Attention(*testIt, nullOps));
+
+ AttnList attnList;
+ l.getAttnList(attnList);
+
+ if(attnList.size() != 1
+ || attnList[0].targetHndl != testIt->targetHndl
+ || attnList[0].attnType != testIt->attnType)
+ {
+ TS_FAIL("Unexpected error calling getAttnList");
+ break;
+ }
+
+ ++testIt;
+ }
+
+ AttnList l;
+ attentionList.getAttnList(l);
+
+ testIt = tests;
+
+ while(testIt != testsEnd)
+ {
+ if(static_cast<uint64_t>(testIt - tests) >= l.size())
+ {
+ TS_FAIL("Unexpected number of elements");
+ break;
+ }
+
+ AttnData & d = l[testIt - tests];
+
+ if(d.targetHndl != testIt->targetHndl
+ || d.attnType != testIt->attnType)
+ {
+ TS_FAIL("Unexpected error calling getAttnList");
+ break;
+ }
+
+ ++testIt;
+ }
+
+ TS_TRACE(EXIT_MRK "testGetAttnData");
+ }
+
+ /**
+ * @brief testForEach Unit test for the
+ * forEach method.
+ */
+ void testForEach(void)
+ {
+ static AttentionOps * nullOps = 0;
+ static const uint64_t size = 10;
+
+ TS_TRACE(ENTER_MRK "testForEach");
+
+ AttentionList l;
+
+ for(uint64_t count = 0; count < size; ++count)
+ {
+ l.add(Attention(AttnData(), nullOps));
+ }
+
+ if(l.forEach(CounterFunct()).counter != size)
+ {
+ TS_FAIL("Unexpected result calling forEach");
+ }
+
+ TS_TRACE(EXIT_MRK "testForEach");
+ }
+
+ /**
+ * @brief testSplit Unit test for the
+ * split method.
+ */
+ void testSplit(void)
+ {
+ static AttentionOps * nullOps = 0;
+ static const TargetHandle_t nullTarget = 0;
+
+ static const AttnData tests[] =
+ {
+ {nullTarget, CHECK_STOP},
+ {nullTarget +2, CHECK_STOP},
+ {nullTarget, RECOVERABLE},
+ {nullTarget +1, RECOVERABLE},
+ {nullTarget +2, RECOVERABLE},
+ {nullTarget +1, CHECK_STOP},
+ };
+ static const AttnData * testsEnd = tests
+ + sizeof(tests)/sizeof(*tests);
+
+ TS_TRACE(ENTER_MRK "testSplit");
+
+ const AttnData * testIt = tests;
+
+ uint64_t xstpCount = 0;
+
+ AttentionList l;
+
+ while(testIt != testsEnd)
+ {
+ l.add(Attention(*testIt, nullOps));
+
+ if(testIt->attnType == CHECK_STOP)
+ {
+ ++xstpCount;
+ }
+ ++testIt;
+ }
+
+ AttentionList t, f;
+ l.split(t, f, CheckstopPredicate());
+
+ if(t.size() != xstpCount
+ || f.size() != static_cast<uint64_t>((
+ testsEnd - tests)) - xstpCount)
+ {
+ TS_FAIL("Unexpected result calling split");
+ }
+
+ AttentionList::iterator tit = t.begin();
+ AttentionList::iterator fit = f.begin();
+
+ while(tit != t.end() && fit != f.end())
+ {
+ AttnData td, fd;
+ tit->getData(td);
+ fit->getData(fd);
+
+ if(td.attnType != CHECK_STOP
+ || fd.attnType != RECOVERABLE)
+ {
+ TS_FAIL("Unexpected result calling split");
+ break;
+ }
+
+ ++tit;
+ ++fit;
+ }
+
+ TS_TRACE(EXIT_MRK "testSplit");
+ }
+
+ /**
+ * @brief testMerge Unit test for the
+ * merge method.
+ */
+ void testMerge(void)
+ {
+ static AttentionOps * nullOps = 0;
+ static const TargetHandle_t nullTarget = 0;
+
+ static const struct Tests
+ {
+ AttnData a;
+ AttnData b;
+
+ } tests[] =
+ {
+ {{nullTarget +1, CHECK_STOP}, {nullTarget +2, RECOVERABLE}},
+ {{nullTarget +3, SPECIAL}, {nullTarget +4, RECOVERABLE}},
+ {{nullTarget +5, CHECK_STOP}, {nullTarget +6, RECOVERABLE}},
+ {{nullTarget +7, SPECIAL}, {nullTarget +8, RECOVERABLE}},
+ {{nullTarget +9, CHECK_STOP}, {nullTarget +10, SPECIAL}},
+ };
+ static const Tests * testsEnd = tests
+ + sizeof(tests)/sizeof(*tests);
+
+ TS_TRACE(EXIT_MRK "testMerge");
+
+ const Tests * testIt = tests;
+
+ AttentionList l1, l2;
+
+ while(testIt != testsEnd)
+ {
+ l1.add(Attention(testIt->a, nullOps));
+ l2.add(Attention(testIt->b, nullOps));
+
+ ++testIt;
+ }
+
+ l1.merge(l2);
+
+ if(l1.size() != static_cast<uint64_t>((testsEnd - tests) * 2))
+ {
+ TS_FAIL("Attention list not merged");
+ }
+
+ AttentionList::iterator it2 = l1.begin();
+ AttentionList::iterator it1 = it2;
+ it2++;
+
+ while(it2 != l1.end())
+ {
+ if((*it2) < (*it1))
+ {
+ TS_FAIL("Attention list not sorted");
+ break;
+ }
+
+ ++it1;
+ ++it2;
+ }
+
+ TS_TRACE(EXIT_MRK "testMerge");
+ }
+};
+#endif
diff --git a/src/usr/diag/attn/test/attntestops.H b/src/usr/diag/attn/test/attntestops.H
new file mode 100644
index 000000000..5bf55a788
--- /dev/null
+++ b/src/usr/diag/attn/test/attntestops.H
@@ -0,0 +1,110 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/test/attntestops.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
+#ifndef __TEST_ATTNTESTOPS_H
+#define __TEST_ATTNTESTOPS_H
+
+/**
+ * @file attntestops.H
+ *
+ * @brief Unit test for the attnops module.
+ */
+
+#include "../attnfwd.H"
+#include "../attnops.H"
+#include <cxxtest/TestSuite.H>
+
+using namespace ATTN;
+using namespace TARGETING;
+using namespace PRDF;
+
+/**
+ * @brief AttnOpsTest Unit test for the attnops module.
+ */
+class AttnOpsTest : public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief testCompare Unit test for the
+ * compare method.
+ */
+ void testCompare(void)
+ {
+ static const TargetHandle_t nullTarget = 0;
+
+ static const struct Test
+ {
+ TargetHandle_t targetA;
+ TargetHandle_t targetB;
+ ATTENTION_VALUE_TYPE typeA;
+ ATTENTION_VALUE_TYPE typeB;
+ int64_t expected;
+
+ } tests[] = {
+
+ {nullTarget, nullTarget, CHECK_STOP, SPECIAL, -1},
+ {nullTarget, nullTarget, SPECIAL, CHECK_STOP, 1},
+ {nullTarget, nullTarget, CHECK_STOP, CHECK_STOP, 0},
+ {nullTarget, nullTarget, SPECIAL, SPECIAL, 0},
+ {nullTarget, nullTarget +1, SPECIAL, SPECIAL, -1},
+ {nullTarget +1, nullTarget +1, SPECIAL, SPECIAL, 0},
+ {nullTarget +1, nullTarget, SPECIAL, SPECIAL, 1},
+ {nullTarget, nullTarget +1, CHECK_STOP, SPECIAL, -1},
+ {nullTarget, nullTarget +1, SPECIAL, CHECK_STOP, 1},
+ {nullTarget +1, nullTarget, CHECK_STOP, SPECIAL, -1},
+ {nullTarget +1, nullTarget, SPECIAL, CHECK_STOP, 1},
+ };
+
+ static const Test * testsEnd = tests
+ + sizeof(tests)/sizeof(*tests);
+
+ TS_TRACE(ENTER_MRK "testCompare");
+
+ const Test * testIt = tests;
+
+ AttnData a, b;
+
+ while(testIt != testsEnd)
+ {
+ a.targetHndl = testIt->targetA;
+ b.targetHndl = testIt->targetB;
+ a.attnType = testIt->typeA;
+ b.attnType = testIt->typeB;
+
+ AttentionOps * nullOps = 0;
+
+ Attention lhs(a, nullOps), rhs(b, nullOps);
+
+ if(lhs.compare(rhs) != testIt->expected)
+ {
+ TS_FAIL("Unexpected result comparing attentions");
+ break;
+ }
+
+ ++testIt;
+ }
+
+ TS_TRACE(EXIT_MRK "testCompare");
+ }
+};
+#endif
diff --git a/src/usr/diag/attn/test/attntestsvc.H b/src/usr/diag/attn/test/attntestsvc.H
new file mode 100644
index 000000000..baac17321
--- /dev/null
+++ b/src/usr/diag/attn/test/attntestsvc.H
@@ -0,0 +1,237 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/test/attntestsvc.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
+#ifndef __TEST_ATTNTESTSVC_H
+#define __TEST_ATTNTESTSVC_H
+
+/**
+ * @file attntestsvc.H
+ *
+ * @brief Unit test for the attnsvc module.
+ */
+
+#include "../attnfwd.H"
+#include "../attnsvc.H"
+#include "attnfakesys.H"
+#include "attntest.H"
+#include <cxxtest/TestSuite.H>
+
+using namespace ATTN;
+using namespace std;
+
+/**
+ * @brief AttnSvcTest Unit test for the attnsvc module.
+ */
+class AttnSvcTest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief testStartStop Unit test for the
+ * start and stop methods.
+ */
+ void testStartStop(void)
+ {
+ TS_TRACE(ENTER_MRK "testStartStop");
+
+ errlHndl_t err = 0;
+
+ Service svc;
+
+ do {
+
+ err = svc.start();
+
+ if(err)
+ {
+ TS_FAIL("unexpected error starting service");
+ break;
+ }
+
+ if(!svc.iv_intrTask)
+ {
+ TS_FAIL("interrupt task not started");
+ }
+
+ if(!svc.iv_prdTask)
+ {
+ TS_FAIL("prd task not started");
+ }
+
+ if(svc.iv_shutdownPrdTask)
+ {
+ TS_FAIL("shutdown variable set");
+ }
+
+ if(!svc.iv_intrTaskQ)
+ {
+ TS_FAIL("no message q created");
+ }
+
+ // should be able to call start again
+
+ err = svc.start();
+
+ if(err)
+ {
+ TS_FAIL("unexpected error starting service");
+ break;
+ }
+
+ if(!svc.iv_intrTask)
+ {
+ TS_FAIL("interrupt task not started");
+ }
+
+ if(!svc.iv_prdTask)
+ {
+ TS_FAIL("prd task not started");
+ }
+
+ if(svc.iv_shutdownPrdTask)
+ {
+ TS_FAIL("shutdown variable set");
+ }
+
+ if(!svc.iv_intrTaskQ)
+ {
+ TS_FAIL("no message q created");
+ }
+
+ err = svc.stop();
+
+ if(err)
+ {
+ TS_FAIL("unexpected error stopping service");
+ break;
+ }
+
+ if(svc.iv_intrTask)
+ {
+ TS_FAIL("interrupt task not stopped");
+ }
+
+ if(svc.iv_prdTask)
+ {
+ TS_FAIL("prd task not stopped");
+ }
+
+ if(svc.iv_shutdownPrdTask)
+ {
+ TS_FAIL("shutdown variable set");
+ }
+
+ if(svc.iv_intrTaskQ)
+ {
+ TS_FAIL("message q not reclaimed");
+ }
+
+ // should be able to call stop again
+
+ err = svc.stop();
+
+ if(err)
+ {
+ TS_FAIL("unexpected error stopping service");
+ break;
+ }
+
+ if(svc.iv_intrTask)
+ {
+ TS_FAIL("interrupt task not stopped");
+ }
+
+ if(svc.iv_prdTask)
+ {
+ TS_FAIL("prd task not stopped");
+ }
+
+ if(svc.iv_shutdownPrdTask)
+ {
+ TS_FAIL("shutdown variable set");
+ }
+
+ if(svc.iv_intrTaskQ)
+ {
+ TS_FAIL("message q not reclaimed");
+ }
+
+ } while(0);
+
+ TS_TRACE(EXIT_MRK "testStartStop");
+ }
+
+ /**
+ * @brief testAttentions Unit test for the attnsvc module.
+ */
+ void testAttentions()
+ {
+ TS_TRACE(ENTER_MRK "testAttentions");
+
+ errlHndl_t err = 0;
+
+ FakeSystem hooks;
+ Service svc;
+
+ hooks.install();
+
+ do
+ {
+ err = svc.start();
+
+ if(err)
+ {
+ TS_FAIL("unexpected error starting service");
+ break;
+ }
+
+ static const int64_t iterations = 20;
+
+ for(int64_t it = 0; it < iterations; ++it)
+ {
+ int64_t count = randint(1, 10);
+
+ TS_TRACE("raising %d attentions", count);
+
+ hooks.raiseAttentions(svc.iv_intrTaskQ, count);
+ }
+
+ err = svc.stop();
+
+ if(err)
+ {
+ TS_FAIL("unexpected error stopping service");
+ break;
+ }
+
+ if(!hooks.validate())
+ {
+ TS_FAIL("unexpected result after injecting attentions");
+ break;
+ }
+
+ } while(0);
+
+ TS_TRACE(EXIT_MRK "testAttentions");
+ }
+};
+#endif
diff --git a/src/usr/diag/attn/test/attntesttest.H b/src/usr/diag/attn/test/attntesttest.H
new file mode 100644
index 000000000..d33b49470
--- /dev/null
+++ b/src/usr/diag/attn/test/attntesttest.H
@@ -0,0 +1,80 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/test/attntesttest.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
+#ifndef __TEST_ATTNTESTTEST_H
+#define __TEST_ATTNTESTTEST_H
+
+/**
+ * @file attntesttest.H
+ *
+ * @brief Unit test for the attntest module.
+ */
+
+#include "../attnfwd.H"
+#include "attntest.H"
+#include <cxxtest/TestSuite.H>
+
+using namespace ATTN;
+
+/**
+ * @brief AttnTest Unit test for the attntest module.
+ */
+class AttnTestTest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief Unit test for the randint function.
+ */
+ void testRand(void)
+ {
+ TS_TRACE(ENTER_MRK "testRand");
+
+ int64_t lower, upper;
+
+ for(int64_t iteration = 1; iteration < 100; ++iteration)
+ {
+ lower = iteration;
+ upper = iteration * iteration;
+
+ int64_t val = randint(lower, upper);
+
+ if(val < lower || upper < val)
+ {
+ TS_FAIL("rand %d not between bounds %d and %d");
+ }
+
+ lower = iteration;
+ upper = iteration + iteration;
+
+ val = randint(lower, upper);
+
+ if(val < lower || upper < val)
+ {
+ TS_FAIL("rand %d not between bounds %d and %d");
+ }
+ }
+
+ TS_TRACE(EXIT_MRK "testRand");
+ }
+};
+#endif
diff --git a/src/usr/diag/attn/test/attntesttrace.H b/src/usr/diag/attn/test/attntesttrace.H
new file mode 100644
index 000000000..b72982ed8
--- /dev/null
+++ b/src/usr/diag/attn/test/attntesttrace.H
@@ -0,0 +1,72 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/diag/attn/test/attntesttrace.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
+#ifndef __TEST_ATTNTESTTRACE_H
+#define __TEST_ATTNTESTTRACE_H
+
+/**
+ * @file attntesttrace.H
+ *
+ * @brief Unit test for the attntrace module.
+ */
+
+#include "../attnfwd.H"
+#include "../attntrace.H"
+#include <cxxtest/TestSuite.H>
+
+/**
+ * @brief AttnTraceTest Unit test for the attntrace module.
+ */
+class AttnTraceTest : public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief testTrace Unit test for ATTN trace
+ * macros.
+ */
+ void testTrace(void)
+ {
+ using namespace ATTN;
+
+ TS_TRACE(ENTER_MRK "testTrace");
+
+ ATTN_FAST("attn trace unit test");
+ ATTN_FAST("attn trace unit test: %p", 0);
+ ATTN_FAST("attn trace unit test: %d", 1234);
+
+ ATTN_DBG("attn trace unit test");
+ ATTN_DBG("attn trace unit test: %p", 0);
+ ATTN_DBG("attn trace unit test: %d", 1234);
+
+ ATTN_ERR("attn trace unit test");
+ ATTN_ERR("attn trace unit test: %p", 0);
+ ATTN_ERR("attn trace unit test: %d", 1234);
+
+ ATTN_SLOW("attn trace unit test");
+ ATTN_SLOW("attn trace unit test: %p", 0);
+ ATTN_SLOW("attn trace unit test: %d", 1234);
+
+ TS_TRACE(EXIT_MRK "testTrace");
+ }
+};
+#endif
diff --git a/src/usr/diag/attn/test/makefile b/src/usr/diag/attn/test/makefile
new file mode 100644
index 000000000..e3838f065
--- /dev/null
+++ b/src/usr/diag/attn/test/makefile
@@ -0,0 +1,33 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/diag/attn/test/makefile $
+#
+# 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
+ROOTPATH = ../../../../..
+
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/diag
+
+OBJS = attnfakesys.o attntest.o attnrand.o
+
+MODULE = testattn
+
+TESTS = *.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/diag/makefile b/src/usr/diag/makefile
index d55ba0d84..3518d118c 100644
--- a/src/usr/diag/makefile
+++ b/src/usr/diag/makefile
@@ -22,6 +22,6 @@
# IBM_PROLOG_END
ROOTPATH = ../../..
-SUBDIRS = mdia.d prdf.d
+SUBDIRS = mdia.d prdf.d attn.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H
index a15e5fd73..37a2cd07c 100644
--- a/src/usr/initservice/extinitsvc/extinitsvctasks.H
+++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H
@@ -291,6 +291,19 @@ const TaskInfo g_exttaskinfolist[] = {
}
},
+ /**
+ * @brief ATTN code library
+ */
+ {
+ "libattn.so" , // taskname
+ NULL, // no pointer to fn
+ {
+ INIT_TASK, // task type
+ EXT_IMAGE, // Extended Module
+ }
+ },
+
+
// end TODO.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
OpenPOWER on IntegriCloud