diff options
| author | Brad Bishop <bradleyb@us.ibm.com> | 2012-05-17 09:12:42 -0500 |
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-07-16 18:38:10 -0500 |
| commit | 19b2fa16137b10e1c34b71bec450a36eee1a0545 (patch) | |
| tree | 54f947b39816072ecd314036f3afc6bf7865a67c /src | |
| parent | 43c18103e9bdbbf1fd17bfcccf885c64d07f305c (diff) | |
| download | talos-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')
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. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |

