summaryrefslogtreecommitdiffstats
path: root/src/usr/diag
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@us.ibm.com>2012-07-12 15:35:56 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-08-15 12:48:21 -0500
commitd268066a67809fa018b840f53163805f583aadcd (patch)
treed30c1fb836ae07b8f5770ff9ec13f3a80c6d543f /src/usr/diag
parent122f4ba48151f29cfb8be1d411509a219bd1df12 (diff)
downloadtalos-hostboot-d268066a67809fa018b840f53163805f583aadcd.tar.gz
talos-hostboot-d268066a67809fa018b840f53163805f583aadcd.zip
Attention handler fake system.
A fake hardware implementation framework for unit testing. Change-Id: I596c26d4c10a0f707c9eab29419b36e8ed11ac6b RTC: 41428 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1356 Tested-by: Jenkins Server Reviewed-by: LARINA M. DSOUZA <larsouza@in.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/diag')
-rw-r--r--src/usr/diag/attn/test/attncomp.H105
-rw-r--r--src/usr/diag/attn/test/attnfakeelement.H110
-rw-r--r--src/usr/diag/attn/test/attnfakesys.C370
-rw-r--r--src/usr/diag/attn/test/attnfakesys.H282
-rw-r--r--src/usr/diag/attn/test/attntest.H18
5 files changed, 840 insertions, 45 deletions
diff --git a/src/usr/diag/attn/test/attncomp.H b/src/usr/diag/attn/test/attncomp.H
new file mode 100644
index 000000000..5d0538905
--- /dev/null
+++ b/src/usr/diag/attn/test/attncomp.H
@@ -0,0 +1,105 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/test/attncomp.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_ATTNCOMP_H
+#define __TEST_ATTNCOMP_H
+
+/**
+ * @file attncomp.H
+ *
+ * @brief HBATTN test lib comparison functors.
+ */
+
+#include "attntest.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief AttnDataSwo Less than comparison functor for PRDF::AttnData structs.
+ */
+class AttnDataSwo
+{
+ public:
+
+ /**
+ * @brief operator() Less than comparison for 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 AttnDataEq Equality comparison predicate for PRDF::AttnData structs.
+ */
+class AttnDataEq
+{
+ public:
+
+ /**
+ * @brief operator() Equality comparison for PRDF::AttnData structs.
+ *
+ * @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_l != i_r;
+ */
+ bool operator()(
+ const PRDF::AttnData & i_r) const
+ {
+ return compare(iv_d, i_r) == 0;
+ }
+
+ /**
+ * @brief ctor
+ *
+ * @param[in] i_l One of two PRDF::AttnData structs to be compared.
+ */
+ explicit AttnDataEq(const PRDF::AttnData & i_l) :
+ iv_d(i_l) {}
+
+ private:
+
+ /**
+ * @brief iv_d
+ *
+ * One of two PRDF::AttnData structs to be compared.
+ */
+ const PRDF::AttnData & iv_d;
+};
+}
+#endif
diff --git a/src/usr/diag/attn/test/attnfakeelement.H b/src/usr/diag/attn/test/attnfakeelement.H
new file mode 100644
index 000000000..1d13406fa
--- /dev/null
+++ b/src/usr/diag/attn/test/attnfakeelement.H
@@ -0,0 +1,110 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/diag/attn/test/attnfakeelement.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_ATTNFAKEELEMENT_H
+#define __TEST_ATTNFAKEELEMENT_H
+
+/**
+ * @file attnfakeelement.H
+ *
+ * @brief HBATTN fake system element class definitions.
+ */
+
+#include "attntest.H"
+
+namespace ATTN
+{
+
+/**
+ * @brief FakeSource Attention source interface.
+ *
+ * Interface definition for classes wishing to attach logic
+ * to FakeSystem error injections.
+ */
+class FakeSource
+{
+ public:
+
+ /**
+ * @brief dtor
+ */
+ virtual ~FakeSource() {}
+
+ /**
+ * @brief processPutAttention Process injected attention.
+ *
+ * @param[in] i_sys System on which attention was injected.
+ * @param[in] i_attn Attention that was injected.
+ * @param[in] i_count number of attentions currently present.
+ */
+ virtual errlHndl_t processPutAttention(
+ FakeSystem & i_sys,
+ const PRDF::AttnData & i_attn,
+ uint64_t i_count) = 0;
+
+ /**
+ * @brief processClearAttention Process cleared attention.
+ *
+ * @param[in] i_sys System on which attention was cleared.
+ * @param[in] i_attn Attention that was cleared.
+ * @param[in] i_count number of attentions currently present.
+ */
+ virtual errlHndl_t processClearAttention(
+ FakeSystem & i_sys,
+ const PRDF::AttnData & i_attn,
+ uint64_t i_count) = 0;
+};
+
+/**
+ * @brief FakeReg Register interface.
+ *
+ * Interface definition for classes wishing to attach logic
+ * to FakeSystem register modifications.
+ */
+class FakeReg
+{
+ public:
+
+ /**
+ * @brief dtor
+ */
+ virtual ~FakeReg() {}
+
+ /**
+ * @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.
+ */
+ virtual errlHndl_t processPutReg(
+ FakeSystem & i_sys,
+ TARGETING::TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_new,
+ uint64_t i_old) = 0;
+};
+}
+#endif
diff --git a/src/usr/diag/attn/test/attnfakesys.C b/src/usr/diag/attn/test/attnfakesys.C
index e93e264e3..1958ae39b 100644
--- a/src/usr/diag/attn/test/attnfakesys.C
+++ b/src/usr/diag/attn/test/attnfakesys.C
@@ -29,9 +29,12 @@
#include "../attnlist.H"
#include "../attntrace.H"
+#include "../attntarget.H"
+#include "attnfakeelement.H"
#include "attnfakesys.H"
#include "attntest.H"
#include <sys/msg.h>
+#include <sys/time.h>
using namespace std;
using namespace PRDF;
@@ -45,13 +48,15 @@ errlHndl_t FakeSystem::putScom(
uint64_t i_address,
uint64_t i_data)
{
+ errlHndl_t err = 0;
+
mutex_lock(&iv_mutex);
- iv_regs[i_target][i_address] = i_data;
+ err = putReg(i_target, i_address, i_data);
mutex_unlock(&iv_mutex);
- return 0;
+ return err;
}
errlHndl_t FakeSystem::getScom(
@@ -61,7 +66,7 @@ errlHndl_t FakeSystem::getScom(
{
mutex_lock(&iv_mutex);
- o_data = iv_regs[i_target][i_address];
+ o_data = getReg(i_target, i_address);
mutex_unlock(&iv_mutex);
@@ -75,26 +80,17 @@ errlHndl_t FakeSystem::modifyScom(
uint64_t & o_data,
ScomOp i_op)
{
+ errlHndl_t err = 0;
+
mutex_lock(&iv_mutex);
o_data = iv_regs[i_target][i_address];
- uint64_t data = iv_regs[i_target][i_address];
-
- bool changed = (i_op == SCOM_OR
- ? (data | i_data) != data
- : (data & i_data) != data);
-
- if(changed)
- {
- iv_regs[i_target][i_address] = i_op == SCOM_OR
- ? data | i_data
- : data & i_data;
- }
+ err = modifyReg(i_target, i_address, i_data, i_op);
mutex_unlock(&iv_mutex);
- return 0;
+ return err;
}
errlHndl_t FakeSystem::mask(const PRDF::AttnData & i_data)
@@ -394,14 +390,354 @@ bool FakeSystem::validate()
return valid;
}
+bool FakeSystem::wait(uint64_t i_maxWaitNs)
+{
+ uint64_t count = 0;
+ uint64_t previous = 0;
+ uint64_t elapsedNs = 0;
+
+ do
+ {
+ mutex_lock(&iv_mutex);
+
+ previous = count;
+ count = iv_attentions.size();
+
+ mutex_unlock(&iv_mutex);
+
+ if(!count)
+ {
+ break;
+ }
+
+ nanosleep(0, TEN_CTX_SWITCHES_NS);
+
+ if(count == previous)
+ {
+ elapsedNs += TEN_CTX_SWITCHES_NS;
+ }
+ }
+ while(elapsedNs < i_maxWaitNs);
+
+ return count == 0;
+}
+
+void FakeSystem::wait()
+{
+ mutex_lock(&iv_mutex);
+
+ while(!iv_attentions.empty())
+ {
+ sync_cond_wait(&iv_cond, &iv_mutex);
+ }
+
+ mutex_unlock(&iv_mutex);
+}
+
+void FakeSystem::addReg(uint64_t i_address, FakeReg & i_element)
+{
+ // register a new implemenation element
+
+ mutex_lock(&iv_mutex);
+
+ iv_regImpl.push_back(make_pair(i_address, &i_element));
+
+ mutex_unlock(&iv_mutex);
+}
+
+void FakeSystem::addSource(
+ TYPE i_targetType,
+ ATTENTION_VALUE_TYPE i_type,
+ FakeSource & i_element)
+{
+ // register a new implemenation element
+
+ mutex_lock(&iv_mutex);
+
+ iv_sources.push_back(make_pair(make_pair(i_targetType, i_type), &i_element));
+
+ mutex_unlock(&iv_mutex);
+}
+
+errlHndl_t FakeSystem::putReg(
+ TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_data)
+{
+ uint64_t data = iv_regs[i_target][i_address];
+
+ putRegUnsafe(i_target, i_address, i_data);
+
+ return makeRegCallbacks(
+ i_target, i_address, i_data, data);
+}
+
+void FakeSystem::putRegUnsafe(
+ TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_data)
+{
+ ATTN_DBG("FakeSystem::putReg: tgt: %p, add: %016x, data: %016x",
+ i_target, i_address, i_data);
+
+ iv_regs[i_target][i_address] = i_data;
+}
+
+uint64_t FakeSystem::getReg(
+ TargetHandle_t i_target,
+ uint64_t i_address)
+{
+ uint64_t data = iv_regs[i_target][i_address];
+
+ return data;
+}
+
+errlHndl_t FakeSystem::modifyReg(
+ TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_data,
+ ScomOp i_op)
+{
+ errlHndl_t err = 0;
+
+ uint64_t data = iv_regs[i_target][i_address];
+
+
+ uint64_t changedData = i_op == SCOM_OR
+ ? (data | i_data)
+ : (data & i_data);
+
+ bool changed = changedData != data;
+
+ if(changed)
+ {
+ putRegUnsafe(
+ i_target,
+ i_address,
+ changedData);
+
+ err = makeRegCallbacks(
+ i_target,
+ i_address,
+ changedData,
+ data);
+ }
+
+ return err;
+}
+
+errlHndl_t FakeSystem::makeRegCallbacks(
+ TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_new,
+ uint64_t i_old)
+{
+ // inform each element of the update
+
+ errlHndl_t err = 0;
+
+ vector<pair<uint64_t, FakeReg *> >::iterator it =
+ iv_regImpl.begin();
+
+ while(!err && it != iv_regImpl.end())
+ {
+ if(it->first == i_address
+ || it->first == 0)
+ {
+ err = (*it->second).processPutReg(
+ *this,
+ i_target,
+ i_address,
+ i_new,
+ i_old);
+ }
+
+ ++it;
+ }
+
+ return err;
+}
+
+errlHndl_t FakeSystem::makeAttnCallbacks(
+ const AttnList & i_list,
+ bool i_set)
+{
+ errlHndl_t err = 0;
+
+ AttnList::const_iterator ait = i_list.begin();
+
+ while(ait != i_list.end())
+ {
+ vector<Entry>::iterator it =
+ iv_sources.begin();
+
+ TYPE type = getTargetService().getType(ait->targetHndl);
+
+ AttnDataMap<uint64_t>::iterator tit = iv_attentions.find(*ait);
+
+ uint64_t count = tit == iv_attentions.end() ? 0 : tit->second;
+
+ while(!err && it != iv_sources.end())
+ {
+ Key & k = it->first;
+
+ if(k.first == TYPE_NA
+ || (k.first == type && k.second == ait->attnType))
+ {
+ if(i_set)
+ {
+ err = (*it->second).processPutAttention(
+ *this,
+ *ait,
+ count);
+ }
+ else
+ {
+ err = (*it->second).processClearAttention(
+ *this,
+ *ait,
+ count);
+ }
+ }
+ ++it;
+ }
+
+ ++ait;
+ }
+
+ return err;
+}
+
+errlHndl_t FakeSystem::putAttentions(
+ const AttnList & i_list)
+{
+ errlHndl_t err = 0;
+
+ // inject the attentions and then
+ // inform each element
+
+ mutex_lock(&iv_mutex);
+
+ AttnList::const_iterator ait = i_list.begin();
+
+ while(ait != i_list.end())
+ {
+ ATTN_DBG("FakeSystem::putAttention: tgt: %p, type: %d",
+ ait->targetHndl, ait->attnType);
+
+ iv_attentions[*ait]++;
+ ++ait;
+ }
+
+ err = makeAttnCallbacks(i_list, true);
+
+ mutex_unlock(&iv_mutex);
+
+ return err;
+}
+
+void FakeSystem::clearAttentionUnsafe(
+ const AttnData & i_attn)
+{
+ ATTN_DBG("FakeSystem::clearAttention: tgt: %p, type: %d",
+ i_attn.targetHndl, i_attn.attnType);
+
+ // clear the attention and then
+ // inform each element
+
+ iv_attentions[i_attn]--;
+
+ if(!iv_attentions[i_attn])
+ {
+ iv_attentions.erase(i_attn);
+ }
+}
+
+errlHndl_t FakeSystem::clearAttention(
+ const PRDF::AttnData & i_attn)
+{
+ errlHndl_t err = 0;
+
+ mutex_lock(&iv_mutex);
+
+ clearAttentionUnsafe(i_attn);
+
+ bool done = iv_attentions.empty();
+
+ err = makeAttnCallbacks(AttnList(1, i_attn), false);
+
+ mutex_unlock(&iv_mutex);
+
+ if(done)
+ {
+ sync_cond_signal(&iv_cond);
+ }
+
+ return err;
+}
+
+errlHndl_t FakeSystem::clearAllAttentions(
+ const PRDF::AttnData & i_attn)
+{
+ errlHndl_t err = 0;
+
+ mutex_lock(&iv_mutex);
+
+ AttnDataMap<uint64_t>::iterator it = iv_attentions.find(i_attn);
+
+ uint64_t count = it == iv_attentions.end() ? 0 : it->second,
+ cit = count;
+
+ while(cit--)
+ {
+ clearAttentionUnsafe(i_attn);
+ }
+
+ bool done = iv_attentions.empty();
+
+ err = makeAttnCallbacks(AttnList(count, i_attn), false);
+
+ mutex_unlock(&iv_mutex);
+
+ if(done)
+ {
+ sync_cond_signal(&iv_cond);
+ }
+
+ return err;
+}
+
+uint64_t FakeSystem::count(const AttnData & i_attention)
+{
+ AttnDataMap<uint64_t>::iterator it = iv_attentions.find(i_attention);
+
+ uint64_t count = it == iv_attentions.end() ? 0 : it->second;
+
+ return count;
+}
+
+void FakeSystem::dump()
+{
+ AttnDataMap<uint64_t>::iterator it = iv_attentions.begin();
+
+ while(it != iv_attentions.end())
+ {
+ ATTN_DBG("target: %p, type: %d, count: %d",
+ it->first.targetHndl, it->first.attnType, it->second);
+
+ ++it;
+ }
+}
+
FakeSystem::FakeSystem()
- : iv_map(Comp())
{
mutex_init(&iv_mutex);
+ sync_cond_init(&iv_cond);
}
FakeSystem::~FakeSystem()
{
+ sync_cond_destroy(&iv_cond);
mutex_destroy(&iv_mutex);
}
}
diff --git a/src/usr/diag/attn/test/attnfakesys.H b/src/usr/diag/attn/test/attnfakesys.H
index 34d0d29b2..50b7a57e0 100644
--- a/src/usr/diag/attn/test/attnfakesys.H
+++ b/src/usr/diag/attn/test/attnfakesys.H
@@ -30,11 +30,12 @@
* @brief HBATTN fake system class definition.
*/
-#include "../attnfwd.H"
#include "../attnops.H"
#include "../attnprd.H"
#include "../attnresolv.H"
#include "../attnscom.H"
+#include "attntest.H"
+#include "attncomp.H"
#include <map>
namespace ATTN
@@ -98,33 +99,10 @@ struct FakeSystemProperties
};
/**
- * @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.
+ * Container that presents an interface to fake hardware
+ * implementations.
*/
class FakeSystem :
public AttentionOps,
@@ -135,6 +113,158 @@ class FakeSystem :
public:
/**
+ * @brief putReg
+ *
+ * Simulate register modification originating in hardware.
+ *
+ * @param[in] i_target Target to write register on.
+ * @param[in] i_address Register address to write to.
+ * @param[in] i_data Data to write to register.
+ *
+ * @retval[0] No errors.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t putReg(
+ TARGETING::TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_data);
+
+ /**
+ * @brief modifyReg
+ *
+ * Simulate register modification originating in hardware.
+ *
+ * @param[in] i_target Target to update register on.
+ * @param[in] i_address Register address to update.
+ * @param[in] i_data Data to write to register.
+ * @param[in] i_op and/or behavior.
+ *
+ * @retval[0] No errors.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t modifyReg(
+ TARGETING::TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_data,
+ ScomOp i_op);
+
+ /**
+ * @brief getReg Register read originating in hardware.
+ *
+ * @param[in] i_target Target to read register from.
+ * @param[in] i_address Register address to read from.
+ *
+ * @return Register data.
+ */
+ uint64_t getReg(
+ TARGETING::TargetHandle_t i_target,
+ uint64_t i_address);
+
+ /**
+ * @brief putAttentions
+ *
+ * Instruct the system to inject the specified attention.
+ *
+ * @param[in] i_list The attentions to inject.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t putAttentions(
+ const PRDF::AttnList & i_list);
+
+ /**
+ * @brief clearAttention
+ *
+ * Instruct the system clear the specified attention.
+ *
+ * @param[in] i_attn The attention to clear.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t clearAttention(
+ const PRDF::AttnData & i_attn);
+
+ /**
+ * @brief clearAllAttentions
+ *
+ * Instruct the system clear all instances of the specified attention.
+ *
+ * @param[in] i_attn The attention to clear.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t clearAllAttentions(
+ const PRDF::AttnData & i_attn);
+
+ /**
+ * @brief count
+ *
+ * For the provided attention type, obtain the number
+ * of times it is being reported by the system.
+ *
+ * @param[in] i_attn The attention type for which the count should be
+ * obtained.
+ */
+ uint64_t count(
+ const PRDF::AttnData & i_attn);
+
+ /**
+ * @brief wait
+ *
+ * Block the calling thread until no attentions are
+ * being reported on the system.
+ *
+ * @param[in] i_maxTimeNs Max amount of time to wait
+ * once system has reached stable state
+ * (number of attentions isn't changing)
+ *
+ * @retval[true] No attentions being reported.
+ * @retval[false].Attentions still being reported
+ * after waiting i_maxTimeNs.
+ */
+ bool wait(uint64_t i_maxTimeNs);
+
+ /**
+ * @brief wait
+ *
+ * Block the calling thread until no attentions are
+ * being reported on the system.
+ */
+ void wait();
+
+ /**
+ * @brief addReg
+ *
+ * Register a register implementaion with the system.
+ *
+ * @param[in] i_address The address for which the implementation
+ * wishes to monitor.
+ * @param[in] i_reg The register implementation to add to the system.
+ */
+ void addReg(
+ uint64_t i_address,
+ FakeReg & i_reg);
+
+ /**
+ * @brief addSource
+ *
+ * Register an attention source implementation with the system.
+ *
+ * @param[in] i_targetType The target type for which the implementation
+ * wishes to monitor.
+ * @param[in] i_type The attention type for which the implementation
+ * wishes to monitor.
+ * @param[in] i_source The source to add to the system.
+ */
+ void addSource(
+ TARGETING::TYPE i_targetType,
+ PRDF::ATTENTION_VALUE_TYPE i_type,
+ FakeSource & i_source);
+
+ /**
* @brief putScom Write a register using SCOM.
*
* @param[in] i_target Target to write register on.
@@ -277,6 +407,11 @@ class FakeSystem :
virtual bool validate();
/**
+ * @brief dump Dump active attentions to trace.
+ */
+ void dump();
+
+ /**
* @brief ctor
*/
FakeSystem();
@@ -301,7 +436,7 @@ class FakeSystem :
/**
* @brief iv_map Attention <-> state association.
*/
- std::map<PRDF::AttnData, FakeSystemProperties, Comp> iv_map;
+ AttnDataMap<FakeSystemProperties> iv_map;
/**
* @brief Reg Register/address association alias.
@@ -319,9 +454,100 @@ class FakeSystem :
Regs iv_regs;
/**
- * @brief iv_mutex iv_map protection.
+ * @brief makeAttnCallbacks
+ *
+ * Notify registered sources of attention state changes.
+ *
+ * @param[in] i_list List of attentions changing state.
+ * @param[in] i_set Attentions turning on / off.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t makeAttnCallbacks(
+ const PRDF::AttnList & i_list,
+ bool i_set);
+
+ /**
+ * @brief makeRegCallbacks
+ *
+ * Notify registered registers of content changes.
+ *
+ * @param[in] i_target Target being updated.
+ * @param[in] i_address Address of register being updated.
+ * @param[in] i_new Post update register content.
+ * @param[in] i_new Pre update register content.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ errlHndl_t makeRegCallbacks(
+ TARGETING::TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_new,
+ uint64_t i_old);
+
+ /**
+ * @brief clearAttentionUnsafe
+ *
+ * Thread unsafe wrapper for clearAttention.
+ *
+ * @param[in] i_attn The attention to clear.
+ *
+ * @retval[0] No error occurred.
+ * @retval[!0] Unexpected error occurred.
+ */
+ void clearAttentionUnsafe(
+ const PRDF::AttnData & i_attn);
+
+ /**
+ * @brief putRegUnsafe
+ *
+ * Thread unsafe wrapper for putReg.
+ *
+ * @param[in] i_target Target to write register on.
+ * @param[in] i_address Register address to write to.
+ * @param[in] i_data Data to write to register.
+ */
+ void putRegUnsafe(
+ TARGETING::TargetHandle_t i_target,
+ uint64_t i_address,
+ uint64_t i_data);
+
+ /**
+ * @brief iv_attentions Current active attentions.
+ */
+ AttnDataMap<uint64_t> iv_attentions;
+
+ /**
+ * @brief iv_regImpl registered register implementations.
+ */
+ std::vector<std::pair<uint64_t, FakeReg *> > iv_regImpl;
+
+ /**
+ * @brief Key Registered source key alias.
+ */
+ typedef std::pair<TARGETING::TYPE, PRDF::ATTENTION_VALUE_TYPE> Key;
+
+ /**
+ * @brief Entry Registered source key/value alias.
+ */
+ typedef std::pair<Key, FakeSource *> Entry;
+
+ /**
+ * @brief iv_source Registered sources.
+ */
+ std::vector<Entry> iv_sources;
+
+ /**
+ * @brief iv_mutex Shared data access serialization.
*/
mutex_t iv_mutex;
+
+ /**
+ * @brief iv_cond Zero attentions condition.
+ */
+ sync_cond_t iv_cond;
};
}
#endif
diff --git a/src/usr/diag/attn/test/attntest.H b/src/usr/diag/attn/test/attntest.H
index b8d036d16..52862486e 100644
--- a/src/usr/diag/attn/test/attntest.H
+++ b/src/usr/diag/attn/test/attntest.H
@@ -31,11 +31,17 @@
*/
#include "../attnfwd.H"
+#include <map>
namespace ATTN
{
class FakePresenter;
+struct AttnDataSwo;
+struct AttnDataEq;
+class FakeSystem;
+class FakeReg;
+class FakeSource;
/**
* @brief randint Generate random integer between bounds.
@@ -55,5 +61,17 @@ uint64_t randint(uint64_t i_min, uint64_t i_max);
* @return uint64_t Random integer from simics host.
*/
extern "C" uint64_t generate_random();
+
+/**
+ * @brief AttnDataMap
+ *
+ * AttnData as key map template.
+ */
+template <typename T>
+ class AttnDataMap :
+ public std::map<PRDF::AttnData, T, AttnDataSwo>
+ {
+
+ };
}
#endif
OpenPOWER on IntegriCloud