summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/attn
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@us.ibm.com>2012-08-17 23:02:51 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-11-13 20:20:25 -0600
commit6a6c4e1385a56e0545144f87a0f4735dbc714f56 (patch)
treeed758bc33d97d8d339d532f6eab677921bc3dd03 /src/usr/diag/attn
parent05144d673fb8ec3c6d9d6af358ce3ab5081ebe17 (diff)
downloadtalos-hostboot-6a6c4e1385a56e0545144f87a0f4735dbc714f56.tar.gz
talos-hostboot-6a6c4e1385a56e0545144f87a0f4735dbc714f56.zip
Attention handler configuration of local err interrupts.
Set priority. Register with INTR using correct xisr number. Parse xisr number in INTR correctly. Change-Id: If6f7afc28d12a2f939f26738471d5d0304179271 RTC: 46448 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1561 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/diag/attn')
-rw-r--r--src/usr/diag/attn/attn.C12
-rw-r--r--src/usr/diag/attn/attnbits.H88
-rw-r--r--src/usr/diag/attn/attnlist.H7
-rw-r--r--src/usr/diag/attn/attnscom.C16
-rw-r--r--src/usr/diag/attn/attnscom.H7
-rw-r--r--src/usr/diag/attn/attnsvc.C222
-rw-r--r--src/usr/diag/attn/attnsvc.H61
-rw-r--r--src/usr/diag/attn/attntarget.C91
-rw-r--r--src/usr/diag/attn/attntarget.H81
-rw-r--r--src/usr/diag/attn/test/attnfakepresenter.C19
-rw-r--r--src/usr/diag/attn/test/attnfaketarget.C37
-rw-r--r--src/usr/diag/attn/test/attnfaketarget.H5
12 files changed, 614 insertions, 32 deletions
diff --git a/src/usr/diag/attn/attn.C b/src/usr/diag/attn/attn.C
index 58006bc0d..5fd628564 100644
--- a/src/usr/diag/attn/attn.C
+++ b/src/usr/diag/attn/attn.C
@@ -90,7 +90,17 @@ errlHndl_t PrdImpl::callPrd(const AttentionList & i_attentions)
if(!attnList.empty())
{
- err = PRDF::main(INVALID_ATTENTION_TYPE, attnList);
+ // AttentionLists keep themselves sorted by attention type
+ // with higher priority attentions
+ // appearing before those with lower priority, where the
+ // priority is defined by the ATTENTION_VALUE_TYPE enum.
+ //
+ // When an AttentionList is converted to an AttnList
+ // the order is preserved. In this way, the PRD
+ // requirement that the highest priority attention
+ // appear first in the argument list is satisfied.
+
+ err = PRDF::main(attnList.front().attnType, attnList);
}
return err;
diff --git a/src/usr/diag/attn/attnbits.H b/src/usr/diag/attn/attnbits.H
index 0a81ca7b3..a17198aec 100644
--- a/src/usr/diag/attn/attnbits.H
+++ b/src/usr/diag/attn/attnbits.H
@@ -169,5 +169,93 @@ bool getCheckbits(
uint64_t i_pos,
uint64_t & o_bits);
}
+
+/**
+ * @brief PsiHbXivr Layout for XIVR registers.
+ */
+struct PsiHbXivr
+{
+ union
+ {
+ uint64_t u64;
+
+ struct
+ {
+ uint64_t res1:8; // zeros
+ uint64_t pir:14; // interrupt destination (server)
+ uint64_t linkptr:2; // which link reg in intr presenter
+ uint64_t priority:8; // intr priority level
+ uint64_t source:3; // source number
+ uint64_t res2:4; // zeros
+ uint64_t intr_pend:25; // interrupt is pending
+ } PACKED;
+ };
+
+ PsiHbXivr() : u64(0) {}
+};
+
+/**
+ * @brief IcpXisr The XISR fields of the XIRR register.
+ */
+struct IcpXisr
+{
+ union
+ {
+ uint64_t u64;
+
+ struct
+ {
+ uint64_t res1:44; // zeros
+ uint64_t node:4; // isn - node
+ uint64_t chip:3; // isn - chip
+ uint64_t unit:2; // isn - unit
+ uint64_t source:11; // isn - source
+ } PACKED;
+ };
+
+ IcpXisr() : u64(0) {}
+};
+
+/**
+ * @brief PsiHbIrqSrcCmp Layout for the IRQ source compare register.
+ *
+ * FIXME: This can go away when RTC 47105 in place.
+ */
+struct PsiHbIrqSrcCmp
+{
+ union
+ {
+ uint64_t u64;
+
+ struct
+ {
+ uint64_t irsn:19;
+ uint64_t res1:10;
+ uint64_t reset:1;
+ uint64_t die:1;
+ uint64_t uie:1;
+ uint64_t mask:19;
+ uint64_t res2:13;
+ } PACKED;
+ };
+
+ PsiHbIrqSrcCmp() : u64(0) {}
+};
+
+/**
+ * @brief PSI host bridge interrupt
+ * config related constants
+ */
+enum
+{
+ PSI_HB_IC_ENABLE = 1,
+ LCL_ERR_ISN = 2,
+ LCL_ERR_XIVR_ADDR = 0x02010919,
+ LCL_ERR_PRIO_DISABLED = 0xff,
+ LCL_ERR_PRIO = 0x20,
+ PSI_HB_IRQ_SRC_CMP_ADDR = 0x0201091b,
+ PSI_HB_IRSN = 0x18,
+ PSI_HB_IRSN_MASK = 0x7FFF8,
+};
}
#endif
diff --git a/src/usr/diag/attn/attnlist.H b/src/usr/diag/attn/attnlist.H
index e6701b6ef..3c1ce4ec8 100644
--- a/src/usr/diag/attn/attnlist.H
+++ b/src/usr/diag/attn/attnlist.H
@@ -39,7 +39,8 @@ namespace ATTN
/**
* @brief AttentionList Class definition.
*
- * Container for Attentions.
+ * Container for Attentions. Attentions
+ * kept sorted by attention type priority.
*/
class AttentionList : public std::vector<Attention>
{
@@ -64,6 +65,10 @@ class AttentionList : public std::vector<Attention>
/**
* @brief getAttnList Convert to PRDF::AttnList.
*
+ * Elements are placed such that attentions with
+ * higher priority appear before those with
+ * lower priority.
+ *
* @param[out] o_dest Where PRDF::AttnData elements are placed.
*/
void getAttnList(PRDF::AttnList & o_dest) const;
diff --git a/src/usr/diag/attn/attnscom.C b/src/usr/diag/attn/attnscom.C
index 32d992c5b..a0c6b48f8 100644
--- a/src/usr/diag/attn/attnscom.C
+++ b/src/usr/diag/attn/attnscom.C
@@ -141,6 +141,22 @@ void ScomImpl::installScomImpl()
getScomWrapper().setImpl(*this);
}
+ScomImpl::~ScomImpl()
+{
+ // restore the default
+
+ ScomWrapper & wrapper = getScomWrapper();
+ ScomImpl * defaultImpl = &Singleton<ScomImpl>::instance();
+
+ if(wrapper.iv_impl == this)
+ {
+ if(this != defaultImpl)
+ {
+ wrapper.setImpl(*defaultImpl);
+ }
+ }
+}
+
errlHndl_t ScomWrapper::putScom(TargetHandle_t i_target, uint64_t i_address,
uint64_t i_data)
{
diff --git a/src/usr/diag/attn/attnscom.H b/src/usr/diag/attn/attnscom.H
index 0905b340d..5525fed41 100644
--- a/src/usr/diag/attn/attnscom.H
+++ b/src/usr/diag/attn/attnscom.H
@@ -103,7 +103,7 @@ class ScomImpl
/**
* @brief dtor
*/
- virtual ~ScomImpl() {}
+ virtual ~ScomImpl();
/**
* @brief ctor
@@ -215,6 +215,11 @@ class ScomWrapper
* @brief assignment Disabled.
*/
ScomWrapper & operator=(const ScomWrapper &);
+
+ /**
+ * @brief Give access to the default implementation.
+ */
+ friend class ScomImpl;
};
}
#endif
diff --git a/src/usr/diag/attn/attnsvc.C b/src/usr/diag/attn/attnsvc.C
index 52386362f..c777eb79d 100644
--- a/src/usr/diag/attn/attnsvc.C
+++ b/src/usr/diag/attn/attnsvc.C
@@ -35,6 +35,7 @@
#include "attnprd.H"
#include "attnproc.H"
#include "attnmem.H"
+#include "attntarget.H"
using namespace std;
using namespace PRDF;
@@ -44,13 +45,165 @@ using namespace ERRORLOG;
namespace ATTN
{
-void* Service::intrTask(void * i_svc)
+errlHndl_t Service::configureInterrupt(
+ ConfigureMode i_mode,
+ TargetHandle_t i_proc,
+ msg_q_t i_q,
+ uint64_t i_xisr,
+ uint64_t i_xivrData,
+ uint64_t i_xivrAddr)
+{
+ errlHndl_t err = NULL;
+
+ do {
+
+ if(i_mode == UP)
+ {
+ err = INTR::registerMsgQ(
+ i_q,
+ ATTENTION,
+ static_cast<INTR::ext_intr_t>(i_xisr));
+ }
+ else
+ {
+ if(NULL == INTR::unRegisterMsgQ(
+ static_cast<INTR::ext_intr_t>(i_xisr)))
+ {
+ ATTN_ERR("INTR did not find xisr: 0x%07x, tgt: %p",
+ i_xisr, i_proc);
+ }
+ }
+
+ if(err)
+ {
+ break;
+ }
+
+
+ // TODO: validate this order of operations doesn't
+ // cause any checkstops (RTC: 52894)
+
+ err = putScom(i_proc, i_xivrAddr, i_xivrData);
+
+ if(err)
+ {
+ break;
+ }
+
+ } while(0);
+
+ return err;
+}
+
+void getMask(uint64_t i_type, void * i_data)
+{
+ uint64_t & mask = *static_cast<uint64_t *>(i_data);
+ uint64_t tmp = 0;
+
+ IPOLL::getCheckbits(i_type, tmp);
+
+ mask |= tmp;
+}
+
+errlHndl_t Service::configureInterrupts(
+ msg_q_t i_q,
+ ConfigureMode i_mode)
+{
+ uint64_t prio = i_mode == UP
+ ? LCL_ERR_PRIO
+ : LCL_ERR_PRIO_DISABLED;
+
+ errlHndl_t err = NULL;
+
+ TargetHandleList procs;
+
+ getTargetService().getAllChips(procs, TYPE_PROC);
+
+ TargetHandleList::iterator it = procs.begin();
+
+ while(it != procs.end())
+ {
+ PsiHbIrqSrcCmp psiHbIrqSrcCmpData;
+
+ psiHbIrqSrcCmpData.irsn = PSI_HB_IRSN;
+ psiHbIrqSrcCmpData.mask = PSI_HB_IRSN_MASK;
+ psiHbIrqSrcCmpData.die = PSI_HB_IC_ENABLE;
+ psiHbIrqSrcCmpData.uie = PSI_HB_IC_ENABLE;
+
+ if(i_mode == UP)
+ {
+ // setup psihb interrupts
+
+ // FIXME: This scom can go away when RTC 47105 in place.
+
+ err = putScom(
+ *it,
+ PSI_HB_IRQ_SRC_CMP_ADDR,
+ psiHbIrqSrcCmpData.u64);
+ }
+
+ if(err)
+ {
+ break;
+ }
+
+ // setup local error interrupts
+
+ IcpXisr xisr;
+
+ uint64_t node = 0, chip = 0;
+
+ getTargetService().getAttribute(ATTR_FABRIC_NODE_ID, *it, node);
+ getTargetService().getAttribute(ATTR_FABRIC_CHIP_ID, *it, chip);
+
+ xisr.node = node;
+ xisr.chip = chip;
+ xisr.source = PSI_HB_IRSN | LCL_ERR_ISN;
+
+ PsiHbXivr psiHbXivrData;
+
+ psiHbXivrData.source = LCL_ERR_ISN;
+ psiHbXivrData.priority = prio;
+ psiHbXivrData.pir = INTR::intrDestCpuId(xisr.u64);
+
+ err = configureInterrupt(
+ i_mode,
+ *it,
+ i_q,
+ xisr.u64,
+ psiHbXivrData.u64,
+ LCL_ERR_XIVR_ADDR);
+
+ if(err)
+ {
+ break;
+ }
+
+ // unmask interrupts in ipoll mask
+
+ uint64_t mask = 0;
+ IPOLL::forEach(~0, &mask, &getMask);
+
+ err = modifyScom(*it, IPOLL::address, ~mask, SCOM_AND);
+
+ if(err)
+ {
+ break;
+ }
+
+ ++it;
+ }
+
+ return err;
+}
+
+void * Service::intrTask(void * i_svc)
{
// interrupt task loop
Service & svc = *static_cast<Service *>(i_svc);
bool shutdown = false;
- msg_t * msg = 0;
+ msg_t * msg = NULL;
while(true)
{
@@ -108,11 +261,37 @@ errlHndl_t Service::processIntrQMsgPreAck(const msg_t & i_msg,
// since the hw can't generate additional interrupts
// until the msg is acknowledged
- errlHndl_t err = 0;
+ errlHndl_t err = NULL;
+
+ TargetHandle_t proc = NULL;
+
+ IcpXisr xisr;
+
+ xisr.u64 = i_msg.data[0];
- // FIXME replace with a real msg -> target conversion
+ TargetHandleList procs;
+ getTargetService().getAllChips(procs, TYPE_PROC);
+
+ TargetHandleList::iterator it = procs.begin();
+
+ while(it != procs.end())
+ {
+ uint64_t node = 0, chip = 0;
- TargetHandle_t proc = reinterpret_cast<TargetHandle_t>(i_msg.data[0]);
+ getTargetService().getAttribute(ATTR_FABRIC_NODE_ID, *it, node);
+ getTargetService().getAttribute(ATTR_FABRIC_CHIP_ID, *it, chip);
+
+ if(node == xisr.node
+ && chip == xisr.chip)
+ {
+ proc = *it;
+ break;
+ }
+
+ ++it;
+ }
+
+ ATTN_DBG("preack: xisr: 0x%07x, tgt: %p", xisr.u64, proc);
do {
@@ -136,6 +315,8 @@ errlHndl_t Service::processIntrQMsgPreAck(const msg_t & i_msg,
break;
}
+ ATTN_DBG("resolving 0x%016x...", ipollMaskScomData);
+
// query the proc resolver for active attentions
err = procOps.resolve(proc, ipollMaskScomData, o_attentions);
@@ -163,7 +344,7 @@ errlHndl_t Service::processIntrQMsgPreAck(const msg_t & i_msg,
break;
}
- ATTN_DBG("resolved %d", o_attentions.size());
+ ATTN_DBG("...resolved %d", o_attentions.size());
} while(0);
@@ -172,7 +353,7 @@ errlHndl_t Service::processIntrQMsgPreAck(const msg_t & i_msg,
void Service::processIntrQMsg(msg_t & i_msg)
{
- errlHndl_t err = 0;
+ errlHndl_t err = NULL;
AttentionList newAttentions;
@@ -271,7 +452,7 @@ bool Service::prdTaskWait(AttentionList & o_attentions)
void Service::processAttentions(const AttentionList & i_attentions)
{
- errlHndl_t err = 0;
+ errlHndl_t err = NULL;
err = getPrdWrapper().callPrd(i_attentions);
@@ -336,7 +517,12 @@ errlHndl_t Service::stop()
if(intrTask)
{
- unRegisterMsgQ(INTR::ATTENTION);
+ errlHndl_t err = configureInterrupts(q, DOWN);
+
+ if(err)
+ {
+ errlCommit(err, HBATTN_COMP_ID);
+ }
msg_t * shutdownMsg = msg_allocate();
shutdownMsg->type = SHUTDOWN;
@@ -382,7 +568,7 @@ bool Service::startPrdTask()
errlHndl_t Service::start()
{
- errlHndl_t err = 0;
+ errlHndl_t err = NULL;
bool cleanStartup = false;
ATTN_SLOW("starting...");
@@ -398,7 +584,7 @@ errlHndl_t Service::start()
msg_q_t q = msg_q_create();
- err = registerMsgQ(q, INTR::ATTENTION, INTR::ATTENTION);
+ err = configureInterrupts(q, UP);
if(err)
{
@@ -423,16 +609,24 @@ errlHndl_t Service::start()
} while(0);
+ tid_t prd = iv_prdTask, intr = iv_intrTask;
+
mutex_unlock(&iv_mutex);
if(!cleanStartup)
{
- // TODO
+ errlHndl_t err2 = stop();
+
+ if(err2)
+ {
+ errlCommit(err2, HBATTN_COMP_ID);
+ }
}
else
{
- ATTN_SLOW("..startup complete");
+ ATTN_SLOW("..startup complete, intr: %d, prd: %d", intr, prd);
}
+
return err;
}
@@ -452,7 +646,7 @@ Service::~Service()
if(err)
{
- // TODO
+ errlCommit(err, HBATTN_COMP_ID);
}
sync_cond_destroy(&iv_cond);
diff --git a/src/usr/diag/attn/attnsvc.H b/src/usr/diag/attn/attnsvc.H
index ebfa414fe..aac628567 100644
--- a/src/usr/diag/attn/attnsvc.H
+++ b/src/usr/diag/attn/attnsvc.H
@@ -86,6 +86,67 @@ class Service
private:
/**
+ * @brief ConfigureMode
+ *
+ * Up or down for parameter for configure methods.
+ */
+ enum ConfigureMode
+ {
+ UP, DOWN,
+ };
+
+ /**
+ * @brief configureInterrupts enable or
+ * disable interrupts used by the service, on all
+ * functioning processors.
+ *
+ * @post Service (un)hooked to/from interrupt service
+ * for local error and host interrupts.
+ * @post Local error and host priority set(cleared).
+ * @post Local error and host interrupts (un)masked at GFIR macro.
+ *
+ * @param[in] i_mode Up or down
+ * @param[in] i_q The msg q to be registered with the
+ * interrupt service.
+ *
+ * @retval[0] No error
+ * @retval[!0] Unexpected error
+ */
+ errlHndl_t configureInterrupts(
+ msg_q_t i_q,
+ ConfigureMode i_mode);
+
+ /**
+ * @brief configureInterrupt enable or disable
+ * a specific interrupt type on a single processor.
+ *
+ * @post Service (un)hooked to/from interrupt service
+ * for local error and host interrupts.
+ * @post local error and host priority set(cleared).
+ * @post local error and host interrupts (un)masked at GFIR macro.
+ *
+ * @param[in] i_mode Up or down
+ * @param[in] i_proc The proc to be configured.
+ * @param[in] i_q The msg q to be registered with the
+ * interrupt service.
+ * @param[in] i_xisr The XISR value for the type being configured.
+ * @param[in] i_xivrData The XIVR register content for
+ * the type being configured.
+ * @param[in] i_xivrAddr The XIVR register address for the type
+ * being configured.
+ *
+ * @retval[0] No error
+ * @retval[!0] Unexpected error
+ */
+ errlHndl_t configureInterrupt(
+ ConfigureMode i_mode,
+ TARGETING::TargetHandle_t i_proc,
+ msg_q_t i_q,
+ uint64_t i_xisr,
+ uint64_t i_xivrData,
+ uint64_t i_xivrAddr);
+
+ /**
* @brief intrTask infinite wait-for-interrupt loop
*
* repeatedly call intrTaskWait and processIntrQMsg
diff --git a/src/usr/diag/attn/attntarget.C b/src/usr/diag/attn/attntarget.C
index 6b2e17c92..b3a509904 100644
--- a/src/usr/diag/attn/attntarget.C
+++ b/src/usr/diag/attn/attntarget.C
@@ -37,6 +37,14 @@ using namespace TARGETING;
namespace ATTN
{
+void TargetServiceImpl::getAllChips(
+ TARGETING::TargetHandleList & o_list,
+ TARGETING::TYPE i_type,
+ bool i_functional)
+{
+ TARGETING::getAllChips(o_list, i_type, i_functional);
+}
+
void TargetServiceImpl::getMcsList(
TargetHandle_t i_proc,
TargetHandleList & o_list)
@@ -94,29 +102,40 @@ TargetHandle_t TargetServiceImpl::getMcs(
TargetHandle_t i_proc,
uint64_t i_pos)
{
+ PredicateCTM classTypeMatch(CLASS_UNIT, TYPE_MCS);
+ PredicateIsFunctional functionalMatch;
+ PredicatePostfixExpr pred;
+
class ChipUnitMatch : public PredicateBase
{
- uint64_t iv_pos;
+ uint8_t iv_pos;
public:
bool operator()(const Target * i_target) const
{
- return i_target->getAttr<ATTR_CHIP_UNIT>() == iv_pos;
- }
+ uint8_t pos;
- explicit ChipUnitMatch(uint64_t i_pos) : iv_pos(i_pos) {}
+ bool match = false;
- } chipUnitMatch(i_pos);
+ if(i_target->tryGetAttr<ATTR_CHIP_UNIT>(pos))
+ {
+ match = iv_pos == pos;
+ }
- PredicateCTM classTypeMatch(CLASS_UNIT, TYPE_MCS);
- PredicateIsFunctional functionalMatch;
+ return match;
+ }
- PredicatePostfixExpr pred;
+ explicit ChipUnitMatch(uint8_t i_pos)
+ : iv_pos(i_pos) {}
+
+ } chipUnitMatch(i_pos);
- pred.push(&chipUnitMatch).push(&classTypeMatch).And().push(
+ pred.push(&classTypeMatch).push(
&functionalMatch).And();
+ pred.push(&chipUnitMatch).And();
+
TargetHandleList list;
TargetHandle_t mcs = NULL;
@@ -124,8 +143,8 @@ TargetHandle_t TargetServiceImpl::getMcs(
list,
i_proc,
TARGETING::TargetService::CHILD_BY_AFFINITY,
- TARGETING::TargetService::IMMEDIATE,
- &pred);
+ TARGETING::TargetService::ALL,
+ &chipUnitMatch);
if(list.size() == 1)
{
@@ -158,11 +177,61 @@ TargetHandle_t TargetServiceImpl::getMembuf(
return membuf;
}
+bool TargetServiceImpl::getAttribute(
+ ATTRIBUTE_ID i_attribute,
+ TargetHandle_t i_target,
+ uint64_t & o_val)
+{
+ bool found = false;
+ uint8_t u8;
+
+ switch (i_attribute)
+ {
+ case ATTR_FABRIC_NODE_ID:
+
+ found = i_target->tryGetAttr<ATTR_FABRIC_NODE_ID>(u8);
+ o_val = u8;
+
+ break;
+
+ case ATTR_FABRIC_CHIP_ID:
+
+ found = i_target->tryGetAttr<ATTR_FABRIC_CHIP_ID>(u8);
+ o_val = u8;
+
+ break;
+
+ default:
+
+ break;
+ }
+
+ return found;
+}
+
TYPE TargetServiceImpl::getType(TargetHandle_t i_target)
{
return i_target->getAttr<ATTR_TYPE>();
}
+TargetServiceImpl::~TargetServiceImpl()
+{
+ // restore the default
+
+ getTargetService().setImpl(Singleton<TargetServiceImpl>::instance());
+
+ TargetService & wrapper = getTargetService();
+ TargetServiceImpl * defaultImpl = &Singleton<TargetServiceImpl>::instance();
+
+ if(wrapper.iv_impl == this)
+ {
+ if(this != defaultImpl)
+ {
+ wrapper.setImpl(*defaultImpl);
+ }
+ }
+}
+
TargetService & getTargetService()
{
return Singleton<TargetService>::instance();
diff --git a/src/usr/diag/attn/attntarget.H b/src/usr/diag/attn/attntarget.H
index 344f02bb4..b37fb3719 100644
--- a/src/usr/diag/attn/attntarget.H
+++ b/src/usr/diag/attn/attntarget.H
@@ -70,6 +70,19 @@ class TargetService
TARGETING::TargetHandle_t i_membuf);
/**
+ * @brief getAllChips Get a list of chips.
+ *
+ * @param[out] o_list The populated list of chips.
+ * @param[in] i_type The type of chip for which a list
+ * should be obtained.
+ * @param[in] i_functional functional chip filter.
+ */
+ void getAllChips(
+ TARGETING::TargetHandleList & o_list,
+ TARGETING::TYPE i_type,
+ bool i_functional = true);
+
+ /**
* @brief getMcs Find the requested membuf chip
* target parent MCS unit target.
*
@@ -137,6 +150,22 @@ class TargetService
TARGETING::TargetHandle_t i_target);
/**
+ * @brief getAttribute Obtain the attribute for the requested target.
+ *
+ * @param[in] i_attribute The attribute to be obtained.
+ * @param[in] i_target The target for which the attribute
+ * should be obtained.
+ * @param[out] o_val The value of the attribute.
+ *
+ * @retval[true] The attribute was found.
+ * @retval[false] The attribute was not found.
+ */
+ bool getAttribute(
+ TARGETING::ATTRIBUTE_ID i_attribute,
+ TARGETING::TargetHandle_t i_target,
+ uint64_t & o_val);
+
+ /**
* @brief setImpl Set the active target service implementation.
*
* @param[in] i_impl The target service implementation to make active.
@@ -164,6 +193,11 @@ class TargetService
* @brief assignment Disabled.
*/
TargetService & operator=(const TargetService &);
+
+ /**
+ * @brief Give access to the default implementation.
+ */
+ friend class TargetServiceImpl;
};
/**
@@ -218,6 +252,19 @@ class TargetServiceImpl
TARGETING::TargetHandle_t i_membuf);
/**
+ * @brief getAllChips Get a list of chips.
+ *
+ * @param[out] o_list The populated list of chips.
+ * @param[in] i_type The type of chip for which a list
+ * should be obtained.
+ * @param[in] i_functional functional chip filter.
+ */
+ virtual void getAllChips(
+ TARGETING::TargetHandleList & o_list,
+ TARGETING::TYPE i_type,
+ bool i_functional = true);
+
+ /**
* @brief getMcs Find the MCS unit target given
* the proc chip parent target and MCS position.
*
@@ -271,6 +318,22 @@ class TargetServiceImpl
TARGETING::TargetHandle_t i_target);
/**
+ * @brief getAttribute Obtain the attribute for the requested target.
+ *
+ * @param[in] i_attribute The attribute to be obtained.
+ * @param[in] i_target The target for which the attribute
+ * should be obtained.
+ * @param[out] o_val The value of the attribute.
+ *
+ * @retval[true] The attribute was found.
+ * @retval[false] The attribute was not found.
+ */
+ virtual bool getAttribute(
+ TARGETING::ATTRIBUTE_ID i_attribute,
+ TARGETING::TargetHandle_t i_target,
+ uint64_t & o_val);
+
+ /**
* @brief installTargetService
*
* Make this the active target service implementation.
@@ -280,7 +343,7 @@ class TargetServiceImpl
/**
* @brief dtor
*/
- virtual ~TargetServiceImpl() {}
+ virtual ~TargetServiceImpl();
/**
* @brief ctor
@@ -314,6 +377,14 @@ inline TARGETING::TargetHandle_t TargetService::getMcs(
return iv_impl->getMcs(i_proc, i_pos);
}
+inline void TargetService::getAllChips(
+ TARGETING::TargetHandleList & o_list,
+ TARGETING::TYPE i_type,
+ bool i_functional)
+{
+ iv_impl->getAllChips(o_list, i_type, i_functional);
+}
+
inline void TargetService::getMcsPos(
TARGETING::TargetHandle_t i_mcs,
uint64_t & o_pos)
@@ -333,6 +404,14 @@ inline TARGETING::TYPE TargetService::getType(
return iv_impl->getType(i_target);
}
+inline bool TargetService::getAttribute(
+ TARGETING::ATTRIBUTE_ID i_attribute,
+ TARGETING::TargetHandle_t i_target,
+ uint64_t & o_val)
+{
+ return iv_impl->getAttribute(i_attribute, i_target, o_val);
+}
+
inline void TargetService::setImpl(TargetServiceImpl & i_impl)
{
iv_impl = &i_impl;
diff --git a/src/usr/diag/attn/test/attnfakepresenter.C b/src/usr/diag/attn/test/attnfakepresenter.C
index 81a7ea2f8..bc137a26b 100644
--- a/src/usr/diag/attn/test/attnfakepresenter.C
+++ b/src/usr/diag/attn/test/attnfakepresenter.C
@@ -29,6 +29,7 @@
#include "attnfakepresenter.H"
#include "../attntrace.H"
+#include "../attntarget.H"
using namespace TARGETING;
using namespace PRDF;
@@ -42,6 +43,7 @@ struct InterruptProperties
MessageType type;
void * data;
void (*callback)(TargetHandle_t, MessageType, void *);
+ uint64_t xisr;
};
struct PresenterProperties
@@ -127,12 +129,23 @@ void FakePresenter::interrupt(
if(iv_tid)
{
+ IcpXisr xisr;
+
+ uint64_t node = 0, chip = 0;
+
+ getTargetService().getAttribute(ATTR_FABRIC_NODE_ID, i_source, node);
+ getTargetService().getAttribute(ATTR_FABRIC_CHIP_ID, i_source, chip);
+
+ xisr.node = node;
+ xisr.chip = chip;
+
InterruptProperties * p = new InterruptProperties;
p->source = i_source;
p->type = i_type;
p->data = i_data;
p->callback = i_callback;
+ p->xisr = xisr.u64;
msg_t * m = msg_allocate();
@@ -170,10 +183,10 @@ bool FakePresenter::wait(msg_q_t i_q)
recvMsg->data[0]);
sendMsg->type = p->type;
- sendMsg->data[0] = reinterpret_cast<uint64_t>(p->source);
+ sendMsg->data[0] = p->xisr;
- ATTN_DBG("FakePresenter: raising interrupt: src: %p, type: %d",
- p->source, p->type);
+ ATTN_DBG("FakePresenter: raising interrupt: src: %p, type: %d, xisr: 0x%07x",
+ p->source, p->type, p->xisr);
msg_sendrecv(i_q, sendMsg);
diff --git a/src/usr/diag/attn/test/attnfaketarget.C b/src/usr/diag/attn/test/attnfaketarget.C
index 0e34b52d7..e4b1020be 100644
--- a/src/usr/diag/attn/test/attnfaketarget.C
+++ b/src/usr/diag/attn/test/attnfaketarget.C
@@ -73,6 +73,43 @@ void FakeProcTargetService::getAllChips(
}
}
+bool FakeProcTargetService::getAttribute(
+ TARGETING::ATTRIBUTE_ID i_attribute,
+ TARGETING::TargetHandle_t i_target,
+ uint64_t & o_val)
+{
+ bool found = false;
+
+ if(find(iv_procs.begin(), iv_procs.end(), i_target) != iv_procs.end())
+ {
+ found = true;
+
+ switch (i_attribute)
+ {
+ case ATTR_FABRIC_NODE_ID:
+
+ o_val = 0;
+ break;
+
+ case ATTR_FABRIC_CHIP_ID:
+
+ o_val = distance(
+ iv_procs.begin(),
+ find(
+ iv_procs.begin(),
+ iv_procs.end(),
+ i_target));
+ break;
+
+ default:
+ found = false;
+ break;
+ }
+ }
+
+ return found;
+}
+
void FakeMemTargetService::getAllChips(
TargetHandleList & o_list,
TYPE i_type,
diff --git a/src/usr/diag/attn/test/attnfaketarget.H b/src/usr/diag/attn/test/attnfaketarget.H
index 4f893a643..48a21cb94 100644
--- a/src/usr/diag/attn/test/attnfaketarget.H
+++ b/src/usr/diag/attn/test/attnfaketarget.H
@@ -203,6 +203,11 @@ class FakeProcTargetService : public TargetServiceImpl
return TARGETING::TYPE_PROC;
}
+ virtual bool getAttribute(
+ TARGETING::ATTRIBUTE_ID i_attribute,
+ TARGETING::TargetHandle_t i_target,
+ uint64_t & o_val);
+
/**
* @brief dtor
*/
OpenPOWER on IntegriCloud