diff options
Diffstat (limited to 'src/usr/diag/attn/attnmem.C')
-rw-r--r-- | src/usr/diag/attn/attnmem.C | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/src/usr/diag/attn/attnmem.C b/src/usr/diag/attn/attnmem.C new file mode 100644 index 000000000..ebf60cd58 --- /dev/null +++ b/src/usr/diag/attn/attnmem.C @@ -0,0 +1,265 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/diag/attn/attnmem.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 attnmem.C + * + * @brief HBATTN Memory attention operations function definitions. + */ + +#include <errl/errlmanager.H> +#include <targeting/common/targetservice.H> +#include "attnmem.H" +#include "attnlist.H" +#include "attntarget.H" + +using namespace std; +using namespace PRDF; +using namespace TARGETING; +using namespace ERRORLOG; + +namespace ATTN +{ + +errlHndl_t MemOps::mask(const AttnData & i_data) +{ + errlHndl_t err = 0; + + do { + + TargetHandle_t proc = getTargetService().getProc(i_data.targetHndl); + + mutex_lock(&iv_mutex); + + bool mask = iv_maskState[proc] == 0; + + iv_maskState[proc]++; + + mutex_unlock(&iv_mutex); + + if(mask) + { + uint64_t ipollMaskWriteBits = 0; + + IPOLL::getCheckbits(HOST, ipollMaskWriteBits); + + err = modifyScom(proc, IPOLL::address, + ipollMaskWriteBits, SCOM_OR); + + if(err) + { + break; + } + } + + + } while(0); + + return err; +} + +errlHndl_t MemOps::unmask(const AttnData & i_data) +{ + errlHndl_t err = 0; + + do { + + TargetHandle_t proc = getTargetService().getProc(i_data.targetHndl); + + mutex_lock(&iv_mutex); + + iv_maskState[proc]--; + + bool unmask = iv_maskState[proc] == 0; + + if(unmask) + { + iv_maskState.erase(proc); + } + + mutex_unlock(&iv_mutex); + + if(unmask) + { + uint64_t ipollMaskWriteBits = 0; + + IPOLL::getCheckbits(HOST, ipollMaskWriteBits); + + err = modifyScom(proc, IPOLL::address, + ~ipollMaskWriteBits, SCOM_AND); + + if(err) + { + break; + } + } + + } while(0); + + return err; +} + +errlHndl_t MemOps::query(const AttnData & i_attnToCheck, bool & o_active) +{ + errlHndl_t err = 0; + + uint64_t checkbits = 0, scomData = 0; + TargetHandle_t mem = i_attnToCheck.targetHndl; + + do + { + TargetHandle_t mcs = getTargetService().getMcs(mem); + + MCI::getCheckbits(i_attnToCheck.attnType, checkbits); + + err = getScom(mcs, MCI::address, scomData); + + if(err) + { + break; + } + + if(scomData & checkbits) + { + o_active = true; + } + else + { + o_active = false; + } + + } while(0); + + return err; +} + +struct ResolveMcsArgs +{ + TargetHandle_t proc; + AttentionList * list; + MemOps * ops; +}; + +void resolveMcs(uint64_t i_mcs, void * i_data) +{ + ResolveMcsArgs * args = static_cast<ResolveMcsArgs *>(i_data); + + uint64_t mciFirScomData; + + TargetHandle_t mcs = getTargetService().getMcs(args->proc, i_mcs); + + // read the MCI fir to determine what type of attention + // centaur reporting + + errlHndl_t err = getScom(mcs, MCI::address, mciFirScomData); + + if(err) + { + errlCommit(err, HBATTN_COMP_ID); + } + else + { + // pick the highest priority attention + + for(uint64_t type = INVALID_ATTENTION_TYPE; + type != END_ATTENTION_TYPE; + ++type) + { + uint64_t mask; + + if(!MCI::getCheckbits(type, mask)) + { + // this object doesn't support + // this attention type + + continue; + } + + if(mask & mciFirScomData) + { + AttnData d; + d.targetHndl = getTargetService().getMembuf(mcs); + + d.attnType = static_cast<ATTENTION_VALUE_TYPE>(type); + + args->list->add(Attention(d, args->ops)); + break; + } + } + } +} + +errlHndl_t MemOps::resolve( + TargetHandle_t i_proc, + uint64_t i_typeMask, + AttentionList & o_attentions) +{ + errlHndl_t err = 0; + + uint64_t gp1ScomData = 0, hostMask = 0; + vector<uint64_t> mcsPositions; + + IPOLL::getCheckbits(HOST, hostMask); + + do { + + if(hostMask & i_typeMask) + { + // host attentions are masked.... + + break; + } + + // get the nest_gp1 register content and decode + // (get a list of membufs reporting attentions) + + err = getScom(i_proc, GP1::address, gp1ScomData); + + if(err) + { + break; + } + + ResolveMcsArgs args; + + args.proc = i_proc; + args.list = &o_attentions; + args.ops = this; + + GP1::forEach(gp1ScomData, &args, &resolveMcs); + + } while(0); + + return err; +} + +MemOps::MemOps() +{ + mutex_init(&iv_mutex); +} + +MemOps::~MemOps() +{ + mutex_destroy(&iv_mutex); +} +} |