diff options
Diffstat (limited to 'src/usr/targeting')
-rw-r--r-- | src/usr/targeting/entitypath.C | 400 | ||||
-rw-r--r-- | src/usr/targeting/fakepnordata.C | 523 | ||||
-rw-r--r-- | src/usr/targeting/fakepnordata.H | 671 | ||||
-rw-r--r-- | src/usr/targeting/makefile | 8 | ||||
-rw-r--r-- | src/usr/targeting/target.C | 123 | ||||
-rw-r--r-- | src/usr/targeting/targetservice.C | 567 | ||||
-rw-r--r-- | src/usr/targeting/test/attributestrings.C | 84 | ||||
-rw-r--r-- | src/usr/targeting/test/makefile | 8 | ||||
-rw-r--r-- | src/usr/targeting/test/targetingtest.H | 457 | ||||
-rw-r--r-- | src/usr/targeting/trace.H | 43 |
10 files changed, 2884 insertions, 0 deletions
diff --git a/src/usr/targeting/entitypath.C b/src/usr/targeting/entitypath.C new file mode 100644 index 000000000..024c563ee --- /dev/null +++ b/src/usr/targeting/entitypath.C @@ -0,0 +1,400 @@ + +/** + * @file entitypath.C + * + * @brief Implementation of the EntityPath class + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <trace/interface.H> + +// This component +#include <targeting/target.H> +#include <targeting/targetservice.H> +#include "trace.H" + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "EntityPath::" + +extern trace_desc_t* g_trac_targeting; + +//****************************************************************************** +// EntityPath::EntityPath (Path Type Constructor) +//****************************************************************************** + +EntityPath::EntityPath( + const PATH_TYPE i_pathType) + : iv_type(i_pathType), iv_size(0) +{ + #define TARG_FN "EntityPath(...)" + + memset(&iv_pathElement[0], 0x00, sizeof(iv_pathElement)); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::EntityPath (Full Constructor) +//****************************************************************************** + +EntityPath::EntityPath() + : iv_type(PATH_NA), iv_size(0) +{ + #define TARG_FN "EntityPath()" + + memset(&iv_pathElement[0], 0x00, sizeof(iv_pathElement)); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::~EntityPath +//****************************************************************************** + +EntityPath::~EntityPath() +{ + #define TARG_FN "~EntityPath()" + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::removeLast +//****************************************************************************** + +EntityPath& EntityPath::removeLast() +{ + #define TARG_FN "removeLast()" + + if(size() < 1) + { + TARG_ERR("Entity path empty (%d); cannot remove any path elements", + size()); + assert(0); + } + + iv_pathElement[size() - 1].type = TYPE_NA; + iv_pathElement[size() - 1].instance = 0; + --iv_size; + return *this; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::copyRemoveLast +//****************************************************************************** + +EntityPath EntityPath::copyRemoveLast() const +{ + #define TARG_FN "copyRemoveLast()" + + EntityPath l_newPath = *this; + l_newPath.removeLast(); + return l_newPath; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::addLast +//****************************************************************************** + +EntityPath& EntityPath::addLast( + const TYPE i_type, + const uint8_t i_instance) +{ + #define TARG_FN "addLast(...)" + + if(size() >= MAX_PATH_ELEMENTS) + { + TARG_ERR("Entity path cannot store any more path elements with size %d", + size()); + assert(size() < MAX_PATH_ELEMENTS); + } + + iv_pathElement[size()].type = i_type; + iv_pathElement[size()].instance = i_instance; + ++iv_size; + return *this; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::copyAddLast +//****************************************************************************** + +EntityPath EntityPath::copyAddLast( + const TYPE i_type, + const uint8_t i_instance) const +{ + #define TARG_FN "copyAddLast(...)" + + EntityPath l_newPath = *this; + l_newPath.addLast(i_type,i_instance); + return l_newPath; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::operator-> +//****************************************************************************** + +Target* EntityPath::operator->(void) +{ + #define TARG_FN "operator->()" + + return theTargetService::instance().toTarget(*this); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::operator== +//****************************************************************************** + +bool EntityPath::operator==( + const EntityPath &i_rhs) const +{ + #define TARG_FN "operator==(...)" + + return ( (i_rhs.iv_type == iv_type) + && (i_rhs.iv_size == iv_size) + && (memcmp(&iv_pathElement[0], + &i_rhs.iv_pathElement[0], + (sizeof(iv_pathElement[0])*iv_size)) == 0)); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::equals +//****************************************************************************** + +bool EntityPath::equals( + const EntityPath& i_rhs, + const uint32_t i_size) const +{ + #define TARG_FN "equals(...)" + + if(i_size > MAX_PATH_ELEMENTS) + { + TARG_ERR("Caller specified invalid entity path size of %d which " + "is greater than MAX_PATH_ELEMENTS",i_size,size()); + assert(i_size <= MAX_PATH_ELEMENTS); + } + + return ( (i_rhs.iv_type == iv_type) + && (i_size <= i_rhs.size()) + && (i_size <= size()) + && (memcmp(&iv_pathElement[0], + &i_rhs.iv_pathElement[0], + (sizeof(iv_pathElement[0])*i_size)) == 0)); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::operator[] +//****************************************************************************** + +const EntityPath::PathElement& EntityPath::operator[]( + const uint32_t i_index) const +{ + #define TARG_FN "operator[](...)" + + if(i_index >= size()) + { + TARG_ERR("Caller specified invalid entity path subscript of %d when " + "size is only %d",i_index,size()); + assert(0); + } + return iv_pathElement[i_index]; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::size +//****************************************************************************** + +uint32_t EntityPath::size() const +{ + #define TARG_FN "size()" + + return iv_size; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::setType +//****************************************************************************** + +void EntityPath::setType( + const PATH_TYPE i_pathType) +{ + #define TARG_FN "setType(...)" + + iv_type = i_pathType; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::type +//****************************************************************************** + +EntityPath::PATH_TYPE EntityPath::type() const +{ + #define TARG_FN "type()" + + return iv_type; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::pathTypeAsString (DEBUG) +//****************************************************************************** + +const char* EntityPath::pathTypeAsString() const +{ + #define TARG_FN "pathTypeAsString()" + + switch (iv_type) + { + case PATH_DEVICE: + return "Device"; + case PATH_AFFINITY: + return "Logical"; + case PATH_PHYSICAL: + return "Physical"; + case PATH_POWER: + return "Power"; + default: + return "Unknown entity path type"; + } + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::pathElementTypeAsString (DEBUG) +//****************************************************************************** + +const char* EntityPath::pathElementTypeAsString( + const TYPE i_type) const +{ + #define TARG_FN "pathElementTypeAsString(...)" + + switch (i_type) + { + case TYPE_PROC: + return "Proc"; + case TYPE_NODE: + return "Node"; + case TYPE_CORE: + return "Core"; + case TYPE_L2: + return "L2"; + case TYPE_MCS: + return "MCS"; + case TYPE_MBA: + return "MBA"; + case TYPE_MEM_PORT: + return "MemPort"; + case TYPE_L3: + return "L3"; + case TYPE_PERVASIVE: + return "Pervasive"; + case TYPE_POWERBUS: + return "Powerbus"; + case TYPE_SCM: + return "SCM"; + case TYPE_SYS: + return "Sys"; + case TYPE_DCM: + return "DCM"; + case TYPE_EX: + return "EX"; + case TYPE_PCI: + return "PCI"; +// case TYPE_FSI_LINK: +// return "FSI-link"; +// case TYPE_CFAM: +// return "CFAM"; +// case TYPE_ENGINE: +// return "Engine"; + default: + return "Unknown path type"; + } + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::pathEngineInstanceAsString (DEBUG) +//****************************************************************************** + +const char* EntityPath::pathEngineInstanceAsString( + const ENGINE_TYPE i_engine) const +{ + #define TARG_FN "pathEngineInstanceAsString(...)" + + switch (i_engine) + { +// case ENGINE_IIC: +// return "IIC"; +// case ENGINE_SCOM: +// return "SCOM"; + default: + return "Unknown engine type"; + } + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::dump (DEBUG) +//****************************************************************************** + +void EntityPath::dump() const +{ + #define TARG_FN "dump()" + + char l_pBuf[200]; + char* l_pCursor = l_pBuf; + l_pCursor+=sprintf(l_pCursor,"%s:",pathTypeAsString()); + for(uint32_t i=0; i<size(); ++i) + { + l_pCursor+=sprintf(l_pCursor,"/%s%d", + pathElementTypeAsString(operator[](i).type), + operator[](i).instance); + } + + TRACFBIN(g_trac_targeting, + "EntityPath", + l_pBuf, + l_pCursor-l_pBuf); + + #undef TARG_FN +} + +#undef TARG_CLASS + +#undef TARG_NAMESPACE + +} // End namespace TARGETING diff --git a/src/usr/targeting/fakepnordata.C b/src/usr/targeting/fakepnordata.C new file mode 100644 index 000000000..ea7295ee1 --- /dev/null +++ b/src/usr/targeting/fakepnordata.C @@ -0,0 +1,523 @@ + +/** + * @file fakepnordata.C + * + * @brief Generates a fake PNOR image for supporting host boot while PNOR + * is not available (i.e. bringup) +*/ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <string.h> +#include <assert.h> +#include <stdio.h> +#include <vector> + +// Other components +#include <util/singleton.H> +#include <trace/interface.H> + +// This component +#include <targeting/attributes.H> +#include <targeting/target.H> +#include "fakepnordata.H" +#include "trace.H" + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "PnorBuilderService::" + + + +//****************************************************************************** +// PnorBuilderService::~PnorBuilderService +//****************************************************************************** + +PnorBuilderService::~PnorBuilderService() +{ + free(iv_pPnor); + free(iv_pHeap); +} + +//****************************************************************************** +// PnorBuilderService::heapBase +//****************************************************************************** + +uint8_t* PnorBuilderService::heapBase() const +{ + return reinterpret_cast<uint8_t*>(iv_pHeap); +} + +//****************************************************************************** +// PnorBuilderService::pnorBase +//****************************************************************************** + +uint8_t* PnorBuilderService::pnorBase() const +{ + return reinterpret_cast<uint8_t*>(iv_pPnor); +} + +//****************************************************************************** +// PnorBuilderService::clearPnorSection +//****************************************************************************** + +void PnorBuilderService::clearPnorSection() +{ + memset(pnorBase(),0x00,PNOR_SIZE); +} + +//****************************************************************************** +// PnorBuilderService::clearHeapSection +//****************************************************************************** + +void PnorBuilderService::clearHeapSection() +{ + memset(heapBase(),0x00,HEAP_SIZE); +} + +//****************************************************************************** +// PnorBuilderService::populateValidAttrIds +//****************************************************************************** + +void PnorBuilderService::populateValidAttrIds( + uint8_t*& i_pPnor, + const std::vector<AttrInfo>& i_attrInfo, + ATTRIBUTE_ID*& o_pAttrNames) +{ + uint32_t l_numAttr = i_attrInfo.size(); + *(reinterpret_cast<uint32_t*>(i_pPnor)) = l_numAttr; + i_pPnor+=sizeof(l_numAttr); + ATTRIBUTE_ID (*l_pAttr)[] = (ATTRIBUTE_ID (*)[])i_pPnor; + for(uint32_t i=0; i<l_numAttr; ++i) + { + memcpy(i_pPnor,&i_attrInfo[i].attrId,sizeof(i_attrInfo[i].attrId)); + i_pPnor+=sizeof(i_attrInfo[i].attrId); + } + o_pAttrNames = (ATTRIBUTE_ID*)l_pAttr; +} + +//****************************************************************************** +// PnorBuilderService::populateAttrs +//****************************************************************************** + +void PnorBuilderService::populateAttrs( + const ATTRIBUTE_ID* i_pAttrNames, + uint8_t*& i_pPnor, + uint8_t*& i_pHeap, + std::vector< Target* >& o_targets, + const std::vector<AttrInfo>& i_attrInfo) +{ + void* (*l_pAttrValues)[] = (void* (*)[])i_pPnor; + + // Reserve space for number of pointers + i_pPnor += sizeof(void*) * i_attrInfo.size(); + + // Iterate through the data + for(uint32_t i=0; i<i_attrInfo.size(); ++i) + { + void* l_pData = (i_attrInfo[i].location == PNOR) + ? (void*)i_pPnor : (void*)i_pHeap; + memcpy(l_pData,i_attrInfo[i].pData,i_attrInfo[i].size); + if(i_attrInfo[i].location == PNOR) + { + i_pPnor+=i_attrInfo[i].size; + } + else + { + i_pHeap+=i_attrInfo[i].size; + } + (*l_pAttrValues)[i] = l_pData; + } + + Target* l_pTarget = new Target(); + l_pTarget->iv_attrs = i_attrInfo.size(); + l_pTarget->iv_pAttrNames = (ATTRIBUTE_ID (*)[])i_pAttrNames; + l_pTarget->iv_pAttrValues = l_pAttrValues; + o_targets.push_back(l_pTarget); +} + +//****************************************************************************** +// PnorBuilderService::buildTargetingImage +//****************************************************************************** + +void PnorBuilderService::buildTargetingImage() +{ + #define TARG_FN "buildTargetingImage()" + + TARG_INF(">>Build targeting image"); + + clearPnorSection(); + clearHeapSection(); + + std::vector<Target*> l_targets; + + uint8_t* l_pPnor = pnorBase(); + uint8_t* l_pHeap = heapBase(); + ATTRIBUTE_ID* l_pAttrNames = NULL; + + uint32_t** l_numTargets = (uint32_t**)l_pPnor; + l_pPnor+=sizeof(uint32_t*); + std::vector<AttrInfo> l_attrs; + + TARG_INF("Populate sys 0"); + + // Populate the system target + SysSysPower8 l_sysSysPower8_0; + EntityPath l_sysContainment(EntityPath::PATH_PHYSICAL); + EntityPath l_sysAffinity(EntityPath::PATH_AFFINITY); + l_sysContainment.addLast(TYPE_SYS,0); + l_sysAffinity.addLast(TYPE_SYS,0); + l_sysSysPower8_0.iv_physicalPath.set(l_sysContainment); + l_sysSysPower8_0.iv_affinityPath.set(l_sysAffinity); + l_sysSysPower8_0.iv_xscomBaseAddr.set(0x300000000000); + l_sysSysPower8_0.getAttrInfo(l_attrs); + populateValidAttrIds(l_pPnor,l_attrs,l_pAttrNames); + populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs); + l_attrs.clear(); + + // Populate the sys0/node0 target + EncNodePower8 l_encNodePower8_0; + EntityPath l_nodeContainment = l_sysContainment; + l_nodeContainment.addLast(TYPE_NODE,0); + EntityPath l_nodeAffinity = l_sysAffinity; + l_nodeAffinity.addLast(TYPE_NODE,0); + l_encNodePower8_0.iv_physicalPath.set(l_nodeContainment); + l_encNodePower8_0.iv_affinityPath.set(l_nodeAffinity); + l_encNodePower8_0.getAttrInfo(l_attrs); + populateValidAttrIds(l_pPnor,l_attrs,l_pAttrNames); + populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs); + l_attrs.clear(); + +// // Populate the sys0/node0/SCM0 target +// CardScmPower8 l_cardScmPower8_0; +// EntityPath l_scmContainment = l_nodeContainment; +// l_scmContainment.addLast(TYPE_SCM,0); +// EntityPath l_scmAffinity = l_nodeAffinity; +// l_scmAffinity.addLast(TYPE_SCM,0); +// l_cardScmPower8_0.iv_physicalPath.set(l_scmContainment); +// l_cardScmPower8_0.iv_affinityPath.set(l_scmAffinity); +// l_cardScmPower8_0.getAttrInfo(l_attrs); +// populateValidAttrIds(l_pPnor,l_attrs,l_pAttrNames); +// populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs); +// l_attrs.clear(); + + TARG_INF("Populate proc 0"); + + // Populate the sys0/node0/proc0 Salerno processor chip targets + ProcChipSalerno l_procChipSalerno_0; + EntityPath l_procContainment = l_nodeContainment; + l_procContainment.addLast(TYPE_PROC,0); + EntityPath l_procAffinity = l_nodeAffinity; + l_procAffinity.addLast(TYPE_PROC,0); + l_procChipSalerno_0.iv_physicalPath.set(l_procContainment); + l_procChipSalerno_0.iv_affinityPath.set(l_procAffinity); + XscomChipInfo l_xscomChipInfo = {0,0}; + l_procChipSalerno_0.iv_xscomChipInfo.set(l_xscomChipInfo); + l_procChipSalerno_0.getAttrInfo(l_attrs); + populateValidAttrIds(l_pPnor,l_attrs,l_pAttrNames); + populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs); + + + +#define EX_PER_SALERNO 6 + + ATTRIBUTE_ID* l_pExAttrNames = NULL; + ATTRIBUTE_ID* l_pCoreAttrNames = NULL; + ATTRIBUTE_ID* l_pL2AttrNames = NULL; + ATTRIBUTE_ID* l_pL3AttrNames = NULL; + TARG_INF("Populate EXs and sub-units"); + + for(int i=0; i<EX_PER_SALERNO; ++i) + { + TARG_INF("Populate EX"); + std::vector<AttrInfo> l_exInstAttrs; + UnitExSalerno l_unitExSalerno; + + // Customize + EntityPath l_exContainment = l_procContainment; + l_exContainment.addLast(TYPE_EX,i); + EntityPath l_exAffinity = l_procAffinity; + l_exAffinity.addLast(TYPE_EX,i); + l_unitExSalerno.iv_physicalPath.set(l_exContainment); + l_unitExSalerno.iv_affinityPath.set(l_exAffinity); + l_unitExSalerno.getAttrInfo(l_exInstAttrs); + + // If valid attributes are empty for this class + if(l_pExAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_exInstAttrs,l_pExAttrNames); + } + + populateAttrs(l_pExAttrNames,l_pPnor,l_pHeap,l_targets,l_exInstAttrs); + + TARG_INF("Populate Core"); + + // Populate core + std::vector<AttrInfo> l_coreInstAttrs; + UnitCoreSalerno l_unitCoreSalerno; + EntityPath l_coreContainment = l_procContainment; + l_coreContainment.addLast(TYPE_CORE,i); + EntityPath l_coreAffinity = l_exAffinity; + l_coreAffinity.addLast(TYPE_CORE,0); + l_unitCoreSalerno.iv_physicalPath.set(l_coreContainment); + l_unitCoreSalerno.iv_affinityPath.set(l_coreAffinity); + l_unitCoreSalerno.getAttrInfo(l_coreInstAttrs); + if(l_pCoreAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_coreInstAttrs,l_pCoreAttrNames); + } + populateAttrs(l_pCoreAttrNames,l_pPnor,l_pHeap,l_targets,l_coreInstAttrs); + + TARG_INF("Populate L2"); + + // Populate L2 + std::vector<AttrInfo> l_l2InstAttrs; + UnitL2Salerno l_unitL2Salerno; + EntityPath l_l2Containment = l_procContainment; + l_l2Containment.addLast(TYPE_L2,i); + EntityPath l_l2Affinity = l_exAffinity; + l_l2Affinity.addLast(TYPE_L2,0); + l_unitL2Salerno.iv_physicalPath.set(l_l2Containment); + l_unitL2Salerno.iv_affinityPath.set(l_l2Affinity); + l_unitL2Salerno.getAttrInfo(l_l2InstAttrs); + if(l_pL2AttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_l2InstAttrs,l_pL2AttrNames); + } + populateAttrs(l_pL2AttrNames,l_pPnor,l_pHeap,l_targets,l_l2InstAttrs); + + TARG_INF("Populate L3"); + + // Populate L3 + std::vector<AttrInfo> l_l3InstAttrs; + UnitL3Salerno l_unitL3Salerno; + EntityPath l_l3Containment = l_procContainment; + l_l3Containment.addLast(TYPE_L3,i); + EntityPath l_l3Affinity = l_exAffinity; + l_l3Affinity.addLast(TYPE_L3,0); + l_unitL3Salerno.iv_physicalPath.set(l_l3Containment); + l_unitL3Salerno.iv_affinityPath.set(l_l3Affinity); + l_unitL3Salerno.getAttrInfo(l_l3InstAttrs); + if(l_pL3AttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_l3InstAttrs,l_pL3AttrNames); + } + populateAttrs(l_pL3AttrNames,l_pPnor,l_pHeap,l_targets,l_l3InstAttrs); + } + + + // Populate Mcs + ATTRIBUTE_ID* l_pMcsAttrNames = NULL; + + std::vector<AttrInfo> l_McsInstAttrs; + UnitMcsSalerno l_unitMcsSalerno; + EntityPath l_McsContainment = l_procContainment; + l_McsContainment.addLast(TYPE_MCS,0); + EntityPath l_McsAffinity = l_procAffinity; + l_McsAffinity.addLast(TYPE_MCS,0); + l_unitMcsSalerno.iv_physicalPath.set(l_McsContainment); + l_unitMcsSalerno.iv_affinityPath.set(l_McsAffinity); + l_unitMcsSalerno.getAttrInfo(l_McsInstAttrs); + if(l_pMcsAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_McsInstAttrs,l_pMcsAttrNames); + } + populateAttrs(l_pMcsAttrNames,l_pPnor,l_pHeap,l_targets,l_McsInstAttrs); + + ATTRIBUTE_ID* l_pMbaAttrNames = NULL; + ATTRIBUTE_ID* l_pMemPortAttrNames = NULL; + + for(int i=0; i<2; ++i) + { + // Populate MBAs + std::vector<AttrInfo> l_MbaInstAttrs; + UnitMbaSalerno l_unitMbaSalerno; + EntityPath l_mbaContainment = l_procContainment; + l_mbaContainment.addLast(TYPE_MBA,i); + EntityPath l_mbaAffinity = l_McsAffinity; + l_mbaAffinity.addLast(TYPE_MBA,i); + l_unitMbaSalerno.iv_physicalPath.set(l_mbaContainment); + l_unitMbaSalerno.iv_affinityPath.set(l_mbaAffinity); + l_unitMbaSalerno.getAttrInfo(l_MbaInstAttrs); + if(l_pMbaAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_MbaInstAttrs,l_pMbaAttrNames); + } + populateAttrs(l_pMbaAttrNames,l_pPnor,l_pHeap,l_targets,l_MbaInstAttrs); + + for(uint32_t l_ports=0; l_ports<1; ++l_ports) + { + // Populate Memory Ports + std::vector<AttrInfo> l_MemPortInstAttrs; + UnitMemPortSalerno l_unitMemPortSalerno; + EntityPath l_MemPortContainment = l_procContainment; + l_MemPortContainment.addLast(TYPE_MEM_PORT,i); + EntityPath l_MemPortAffinity = l_mbaAffinity; + l_MemPortAffinity.addLast(TYPE_MEM_PORT,l_ports); + l_unitMemPortSalerno.iv_physicalPath.set(l_MemPortContainment); + l_unitMemPortSalerno.iv_affinityPath.set(l_MemPortAffinity); + l_unitMemPortSalerno.getAttrInfo(l_MemPortInstAttrs); + if(l_pMemPortAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_MemPortInstAttrs,l_pMemPortAttrNames); + } + populateAttrs(l_pMemPortAttrNames,l_pPnor,l_pHeap,l_targets,l_MemPortInstAttrs); + + // DIMMs will get linked up later + } + } + + // Populate Pervasive Unit + ATTRIBUTE_ID* l_pPervasiveAttrNames = NULL; + std::vector<AttrInfo> l_PervasiveInstAttrs; + UnitPervasiveSalerno l_unitPervasiveSalerno; + EntityPath l_PervasiveContainment = l_procContainment; + l_PervasiveContainment.addLast(TYPE_PERVASIVE,0); + EntityPath l_PervasiveAffinity = l_procAffinity; + l_PervasiveAffinity.addLast(TYPE_PERVASIVE,0); + l_unitPervasiveSalerno.iv_physicalPath.set(l_PervasiveContainment); + l_unitPervasiveSalerno.iv_affinityPath.set(l_PervasiveAffinity); + l_unitPervasiveSalerno.getAttrInfo(l_PervasiveInstAttrs); + if(l_pPervasiveAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_PervasiveInstAttrs,l_pPervasiveAttrNames); + } + populateAttrs(l_pPervasiveAttrNames,l_pPnor,l_pHeap,l_targets,l_PervasiveInstAttrs); + + // Populate Powerbus Unit + ATTRIBUTE_ID* l_pPowerbusAttrNames = NULL; + std::vector<AttrInfo> l_PowerbusInstAttrs; + UnitPowerbusSalerno l_unitPowerbusSalerno; + EntityPath l_PowerbusContainment = l_procContainment; + l_PowerbusContainment.addLast(TYPE_POWERBUS,0); + EntityPath l_PowerbusAffinity = l_procAffinity; + l_PowerbusAffinity.addLast(TYPE_POWERBUS,0); + l_unitPowerbusSalerno.iv_physicalPath.set(l_PowerbusContainment); + l_unitPowerbusSalerno.iv_affinityPath.set(l_PowerbusAffinity); + l_unitPowerbusSalerno.getAttrInfo(l_PowerbusInstAttrs); + if(l_pPowerbusAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_PowerbusInstAttrs,l_pPowerbusAttrNames); + } + populateAttrs(l_pPowerbusAttrNames,l_pPnor,l_pHeap,l_targets,l_PowerbusInstAttrs); + + // Populate PCI Units + ATTRIBUTE_ID* l_pPciAttrNames = NULL; + + for(int i=0; i<3; ++i) + { + std::vector<AttrInfo> l_PciInstAttrs; + UnitPciSalerno l_unitPciSalerno; + EntityPath l_pciContainment = l_procContainment; + l_pciContainment.addLast(TYPE_PCI,i); + EntityPath l_pciAffinity = l_procAffinity; + l_pciAffinity.addLast(TYPE_PCI,i); + l_unitPciSalerno.iv_physicalPath.set(l_pciContainment); + l_unitPciSalerno.iv_affinityPath.set(l_pciAffinity); + l_unitPciSalerno.getAttrInfo(l_PciInstAttrs); + if(l_pPciAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_PciInstAttrs,l_pPciAttrNames); + } + populateAttrs(l_pPciAttrNames,l_pPnor,l_pHeap,l_targets,l_PciInstAttrs); + } + + + /* + TARG_INF("Populate proc 1"); + + + // Populate the sys0/node0/DCM0/proc1 Salerno processor chip targets + ProcChipSalerno l_procChipSalerno_1; + l_containment.removeLast(); + l_affinity.removeLast(); + l_containment.addLast(TYPE_PROC,1); + l_affinity.addLast(TYPE_PROC,1); + l_procChipSalerno_1.iv_physicalPath.set(l_containment); + l_procChipSalerno_1.iv_affinityPath.set(l_affinity); + std::vector<AttrInfo> l_attrs1; + l_procChipSalerno_1.getAttrInfo(l_attrs1); + populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs1); + l_attrs.clear(); + l_attrs1.clear(); + */ + + TARG_INF("Finalize PNOR"); + + // Populate pointer to total # of targets at beginning of + // targeting section + *l_numTargets = (uint32_t*)l_pPnor; + + // Add number of targets + uint32_t l_instance = l_targets.size(); + memcpy(l_pPnor,&l_instance,sizeof(l_instance)); + l_pPnor+= sizeof(l_instance); + + // Add actual targets + for(uint32_t i=0; i<l_targets.size(); ++i) + { + memcpy(l_pPnor,l_targets[i],sizeof(Target)); + l_pPnor+=sizeof(Target); + } + + // Compute the actual PNOR and heap sizes and reallocate the memory + uint32_t l_pnorSize = (l_pPnor - pnorBase()); + uint32_t l_heapSize = (l_pHeap - heapBase()); + // realloc(iv_pPnor,l_pnorSize); + // realloc(iv_pHeap,l_heapSize); + + TARG_INF( + "Targeting PNOR size = %d bytes, " + "heap size = %d bytes, " + "est stack size = %d bytes",l_pnorSize,l_heapSize, + (uint32_t)((uint64_t)&l_targets-(uint64_t)&l_heapSize)); + + + // PNOR/HEAP image now ready for bringup use + + #undef TARG_FN +} + +//****************************************************************************** +// PnorBuilderService::getTargetingImageBaseAddress +//****************************************************************************** + +void PnorBuilderService::getTargetingImageBaseAddress( + const void*& o_pTargetsArea) +{ + o_pTargetsArea = reinterpret_cast<void*>(iv_pPnor); +} + +//****************************************************************************** +// PnorBuilderService::PnorBuilderService +//****************************************************************************** + +PnorBuilderService::PnorBuilderService() +{ + TARG_INF(">>PnorBuilderService"); + + + iv_pPnor = reinterpret_cast<uint8_t*>(malloc(PNOR_SIZE)); + + TARG_INF(">>malloc(HEAP_SIZE)"); + + iv_pHeap = reinterpret_cast<uint8_t*>(malloc(HEAP_SIZE)); + + TARG_INF("Calling buildTargetingImage"); + + (void)buildTargetingImage(); + + TARG_INF("<<PnorBuilderService"); + +} + +#undef TARG_NAMESPACE +#undef TARG_CLASS + +} // End namespace TARGETING + diff --git a/src/usr/targeting/fakepnordata.H b/src/usr/targeting/fakepnordata.H new file mode 100644 index 000000000..bd6f0494a --- /dev/null +++ b/src/usr/targeting/fakepnordata.H @@ -0,0 +1,671 @@ + +#ifndef TARG_FAKEPNORDATA_H +#define TARG_FAKEPNORDATA_H + +/** + * @file fakepnordata.H + * + * @brief Interface to generate targets/attributes and fake out PNOR + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> +#include <vector> + +namespace TARGETING +{ + +/** + * @brief Enum which describes where an attribute resides + */ +enum LOCATION +{ + PNOR, ///< Attribute resides in PNOR + HEAP, ///< Attribute resides in heap memory, not backed to PNOR +}; + +/** + * @brief Structure which holds attribute information for the PNOR targeting + * image generator + */ +struct AttrInfo +{ + uint32_t size; ///< Size of attribute + ATTRIBUTE_ID attrId; ///< Attribute ID + LOCATION location; ///< Location where attribute resides + const void* pData; ///< Address of attribute +}; + +/** + * @brief Property class which maintains info about a property to serialize + */ +template<ATTRIBUTE_ID A,LOCATION L> +class Property +{ + public: + + /** + * @brief Map the attribute's type to something more intuitive + */ + typedef typename AttributeTraits<A>::Type _Type; + + /** + * @brief Build a property + */ + Property() + { + info.size = sizeof(_Type); + info.attrId = A; + info.location = L; + info.pData = &iv_data; + iv_initialized = false; + memset(&iv_data,0x00,sizeof(iv_data)); + } + + /** + * @brief Push attribute info to the attribute array + * + * @param[out] o_info Array of attribute structures + */ + void addAttrInfo( + std::vector<AttrInfo>& o_info) const + { + if(info.location == PNOR) + { + assert(iv_initialized); + } + o_info.push_back(info); + } + + /** + * @brief Sets the attribute value + * + * @param[in] i_value Value of the attribute to set + */ + void set( + _Type const& i_value) + { + iv_data = i_value; + iv_initialized = true; + } + + /** + * @brief Return size of the attribute + * + * @return uint32_t giving the size of the attribute in bytes + */ + uint32_t size() const + { + return sizeof(iv_data); + } + + /** + * @brief Return attribute's corresponding attribute ID + * + * @return Attribute ID of the attribute + */ + ATTRIBUTE_ID id() const + { + return info.attrId; + } + + /** + * @brief Return address of the attribute data + * + * @return Address of the attribute data + */ + const _Type* data() const + { + return &iv_data; + } + + /** + * @brief Return location where attribute resides + * + * @return Location specifier + */ + LOCATION location() const + { + return info.location; + } + + public: + + AttrInfo info; ///< Attribute information + _Type iv_data; ///< Attribute data + bool iv_initialized; ///< Whether attribute was set or not +}; + +/** + * @brief Base class describing attributes that all targets have. + * + * Note: will not repeat documentation for subclasses, since they act the same + */ +class Base +{ + public: + + /** + * @brief Build the base object for attributes + */ + Base() + { + } + + /** + * @brief Populate the list with information on all the attributes + * + * @param[out] o_info List containing all the attribute information + */ + void getAttrInfo( + std::vector<AttrInfo>& o_info) const + { + iv_class.addAttrInfo(o_info); + iv_type.addAttrInfo(o_info); + iv_model.addAttrInfo(o_info); + iv_physicalPath.addAttrInfo(o_info); + iv_affinityPath.addAttrInfo(o_info); + iv_interfaces.addAttrInfo(o_info); + } + + public: + + Property<ATTR_CLASS,PNOR> iv_class; + Property<ATTR_TYPE,PNOR> iv_type; + Property<ATTR_MODEL,PNOR> iv_model; + Property<ATTR_PHYS_PATH,PNOR> iv_physicalPath; + Property<ATTR_AFFINITY_PATH,PNOR> iv_affinityPath; + Property<ATTR_PRIMARY_CAPABILITIES,PNOR> iv_interfaces; +}; + +/** + * @brief Class describing the data for all cards + */ +class Card : public Base +{ + public: + + Card() + { + iv_class.set(CLASS_CARD); + + PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo( + std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for all DCM cards + */ +class CardScmPower8 : public Card +{ + public: + + CardScmPower8() + { + iv_type.set(TYPE_SCM); + iv_model.set(MODEL_POWER8); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Card::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for the top level system + */ +class SysSysPower8 : public Base +{ + public: + + SysSysPower8() + { + iv_class.set(CLASS_SYS); + iv_type.set(TYPE_SYS); + iv_model.set(MODEL_POWER8); + + PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + + iv_xscomBaseAddr.addAttrInfo(o_info); + } + + Property<ATTR_XSCOM_BASE_ADDRESS,PNOR> iv_xscomBaseAddr; +}; + +/** + * @brief Class describing the data for a chip + */ +class Chip : public Base +{ + public: + + Chip() + { + iv_class.set(CLASS_CHIP); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for a node + */ +class EncNodePower8 : public Base +{ + public: + + EncNodePower8() + { + iv_class.set(CLASS_ENC); + iv_type.set(TYPE_NODE); + iv_model.set(MODEL_POWER8); + + PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for the Salerno chip + */ +class ProcChipSalerno : public Chip +{ + public: + + ProcChipSalerno() + { + iv_type.set(TYPE_PROC); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + l_capabilities.supportsFsiScom = true; + l_capabilities.supportsXscom = true; + iv_interfaces.set(l_capabilities); + + ScomSwitches l_switches = {0}; + l_switches.useXscom = 1; + iv_scomSwitches.set(l_switches); + + iv_dummyRw.set(0); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Chip::getAttrInfo(o_info); + + iv_dummyRw.addAttrInfo(o_info); + iv_scomSwitches.addAttrInfo(o_info); + iv_xscomChipInfo.addAttrInfo(o_info); + } + + Property<ATTR_DUMMY_RW,PNOR> iv_dummyRw; + Property<ATTR_SCOM_SWITCHES,HEAP> iv_scomSwitches; + Property<ATTR_XSCOM_CHIP_INFO,PNOR> iv_xscomChipInfo; + +}; + +/** + * @brief Class describing the data for a logical entity + */ +class Logical : public Base +{ + public: + + Logical() + { + iv_class.set(CLASS_UNIT); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for an EX unit + */ +class UnitExSalerno : public Logical +{ + public: + + UnitExSalerno() + { + iv_type.set(TYPE_EX); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for a core unit + */ +class UnitCoreSalerno : public Logical +{ + public: + + UnitCoreSalerno() + { + iv_type.set(TYPE_CORE); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for an L3 unit + */ +class UnitL3Salerno : public Logical +{ + public: + + UnitL3Salerno() + { + iv_type.set(TYPE_L3); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } + +}; + +/** + * @brief Class describing the data for an L2 unit + */ +class UnitL2Salerno : public Logical +{ + public: + + UnitL2Salerno() + { + iv_type.set(TYPE_L2); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for an MCA unit + */ +class UnitMcsSalerno : public Logical +{ + public: + + UnitMcsSalerno() + { + iv_type.set(TYPE_MCS); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } + + Property<ATTR_SCOM_SWITCHES,HEAP> iv_scomSwitches; +}; + +/** + * @brief Class describing the data for an MCA unit + */ +class UnitMbaSalerno : public Logical +{ + public: + + UnitMbaSalerno() + { + iv_type.set(TYPE_MBA); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for the pervasive unit + */ +class UnitPervasiveSalerno : public Logical +{ + public: + + UnitPervasiveSalerno() + { + iv_type.set(TYPE_PERVASIVE); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } + +}; + +class UnitPciSalerno : public Logical +{ + public: + + UnitPciSalerno() + { + iv_type.set(TYPE_PCI); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +class UnitPowerbusSalerno : public Logical +{ + public: + + UnitPowerbusSalerno() + { + iv_type.set(TYPE_POWERBUS); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +class UnitMemPortSalerno : public Logical +{ + public: + + UnitMemPortSalerno() + { + iv_type.set(TYPE_MEM_PORT); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +//****************************************************************************** +// PNOR Builder Service +//****************************************************************************** + +/** + * @brief Class which builds fake PNOR image for bringup + */ +class PnorBuilderService +{ + public: + + /** + * @brief Initial PNOR sizes + */ + static const uint32_t PNOR_SIZE = 8000; + static const uint32_t HEAP_SIZE = 8000; + + /** + * @brief Constructs the PnorBuilderService + */ + PnorBuilderService(); + + /** + * @brief Destructs the PnorBuilderService + */ + ~PnorBuilderService(); + + /** + * @brief Returns pointer to the start of the heap section + */ + uint8_t* heapBase() const; + + /** + * @brief Returns pointer to the start of the PNOR section + */ + uint8_t* pnorBase() const; + + /** + * @brief Clears the PNOR section + */ + void clearPnorSection(); + + /** + * @brief Clears the PNOR section + */ + void clearHeapSection(); + + /** + * @brief Populates attributes valid attributes for a class/type/model + * into the targeting image + * + * @param[in] i_pPnor On input and output, pointer to next valid + * location to write to in PNOR + * @param[in] i_attrInfo List of attributes to process + * @param[in] o_pAttrNames Pointer to where the list was stored + */ + void populateValidAttrIds( + uint8_t*& io_pPnor, + const std::vector<AttrInfo>& i_attrInfo, + ATTRIBUTE_ID*& o_pAttrNames); + + /** + * @brief Populates attributes into the targeting image + * + * @param[in] i_pAttrNames Pointer to array of valid attributes for + * the class/type/model in question + * @param[in/out] io_pPnor On both input and output, a pointer to the + * next free position in PNOR to populate. + * @param[in/out] io_pHeap On both input and output, a pointer to the + * next free position on the heap to populate. + * @param[out] o_targets List of targets to serialize + * @param[in] i_attrInfo List of attribute infor structures + */ + void populateAttrs( + const ATTRIBUTE_ID* i_pAttrNames, + uint8_t*& io_pPnor, + uint8_t*& io_pHeap, + std::vector< Target* >& o_targets, + const std::vector<AttrInfo>& i_attrInfo); + + /** + * @brief Builds the targeting image + */ + void buildTargetingImage(); + + /** + * @brief Updates caller's pointer with the address of the targeting + * layout + * + * @param[out] o_pTargetsArea Pointer to the address of the targeting + * layout + */ + void getTargetingImageBaseAddress( + const void*& o_pTargetsArea); + + uint8_t* iv_pPnor; + uint8_t* iv_pHeap; + +} PACKED; + +typedef Singleton<PnorBuilderService> thePnorBuilderService; + +} // End namespace TARGETING + +#endif // TARG_FAKEPNORDATA_H diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile new file mode 100644 index 000000000..09b9d3be3 --- /dev/null +++ b/src/usr/targeting/makefile @@ -0,0 +1,8 @@ +ROOTPATH = ../../.. +MODULE = targeting + +OBJS = target.o targetservice.o entitypath.o fakepnordata.o + +SUBDIRS = test.d + +include ${ROOTPATH}/config.mk diff --git a/src/usr/targeting/target.C b/src/usr/targeting/target.C new file mode 100644 index 000000000..590fc66bc --- /dev/null +++ b/src/usr/targeting/target.C @@ -0,0 +1,123 @@ + +/** + * @file target.C + * + * @brief Implementation of the Target class + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// This component +#include <targeting/target.H> +#include "trace.H" + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "Target::" + +//****************************************************************************** +// Target::~Target +//****************************************************************************** + +Target::~Target() +{ + #define TARG_FN "~Target()" + + #undef TARG_FN +} + +//****************************************************************************** +// Target::_tryGetAttr +//****************************************************************************** + +bool Target::_tryGetAttr( + const ATTRIBUTE_ID i_attr, + const uint32_t i_size, + void* const io_pAttrData) const +{ + #define TARG_FN "_tryGetAttr()" + + void* l_pAttrData = NULL; + (void) _getAttrPtr(i_attr, l_pAttrData); + if (l_pAttrData) + { + memcpy(io_pAttrData, l_pAttrData, i_size); + } + return (l_pAttrData != NULL); + + #undef TARG_FN +} + +//****************************************************************************** +// Target::_trySetAttr +//****************************************************************************** + +bool Target::_trySetAttr( + const ATTRIBUTE_ID i_attr, + const uint32_t i_size, + const void* const i_pAttrData) const +{ + #define TARG_FN "_trySetAttr()" + + void* l_pAttrData = NULL; + (void) _getAttrPtr(i_attr, l_pAttrData); + if (l_pAttrData) + { + memcpy(l_pAttrData, i_pAttrData, i_size); + } + return (l_pAttrData != NULL); + + #undef TARG_FN +} + +//****************************************************************************** +// Target::_getAttrPtr +//****************************************************************************** + +void Target::_getAttrPtr( + const ATTRIBUTE_ID i_attr, + void*& o_pAttr) const +{ + #define TARG_FN "_getAttrPtr()" + + void* l_pAttr = NULL; + for (uint32_t i = 0; i < iv_attrs; ++i) + { + if ((*iv_pAttrNames)[i] == i_attr) + { + l_pAttr = (*iv_pAttrValues)[i]; + } + } + o_pAttr = l_pAttr; + + #undef TARG_FN +} + +//****************************************************************************** +// Target::Target +//****************************************************************************** + +Target::Target() +{ + #define TARG_FN "Target()" + + // Note there is no intialization of a target, since it's mapped to memory + // directly. + + #undef TARG_FN +} + +#undef TARG_CLASS + +#undef TARG_NAMESPACE + +} // End namespace TARGETING diff --git a/src/usr/targeting/targetservice.C b/src/usr/targeting/targetservice.C new file mode 100644 index 000000000..e90449d23 --- /dev/null +++ b/src/usr/targeting/targetservice.C @@ -0,0 +1,567 @@ + +/** + * @file targetservice.C + * + * @brief Implementation of the TargetService class + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// Other components +#include <trace/interface.H> + +// This component +#include <targeting/targetservice.H> +#include "trace.H" +#include "fakepnordata.H" + +//****************************************************************************** +// targetService +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" + +//****************************************************************************** +// targetService +//****************************************************************************** + +TARGETING::TargetService& targetService() +{ + #define TARG_FN "targetService()" + + return TARGETING::theTargetService::instance(); + + #undef TARG_FN +} + +//****************************************************************************** +// Component trace buffer +//****************************************************************************** + +trace_desc_t* g_trac_targeting = NULL; +TRAC_INIT(&g_trac_targeting, "TARG", 4096); + +#define TARG_CLASS "TargetService::" + +//****************************************************************************** +// TargetService::TargetService +//****************************************************************************** + +TargetService::TargetService() : + iv_initialized(false), iv_maxTargets(0), iv_pPnor(NULL) +{ + #define TARG_FN "TargetService()" + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::~TargetService +//****************************************************************************** + +TargetService::~TargetService() +{ + #define TARG_FN "~TargetService()" + + // Nothing to do; Target[] memory not owned by this object + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::init +//****************************************************************************** + +void TargetService::init() +{ + #define TARG_FN "init()" + + TARG_ENTER(); + + // Build the association mappings + AssociationAttrMap a1 = {PARENT, INWARDS, ATTR_PHYS_PATH}; + AssociationAttrMap a2 = {CHILD, OUTWARDS, ATTR_PHYS_PATH}; + AssociationAttrMap a3 = {PARENT_BY_AFFINITY, INWARDS, ATTR_AFFINITY_PATH}; + AssociationAttrMap a4 = {CHILD_BY_AFFINITY, OUTWARDS, ATTR_AFFINITY_PATH}; + AssociationAttrMap a5 = {VOLTAGE_SUPPLIER, INWARDS, ATTR_POWER_PATH}; + AssociationAttrMap a6 = {VOLTAGE_CONSUMER, OUTWARDS, ATTR_POWER_PATH}; + iv_associationMappings.push_back(a1); + iv_associationMappings.push_back(a2); + iv_associationMappings.push_back(a3); + iv_associationMappings.push_back(a4); + iv_associationMappings.push_back(a5); + iv_associationMappings.push_back(a6); + + // Get+save pointer to beginning of targeting's swappable config in + // PNOR. Note that this will change once PNOR is accessible + (void)thePnorBuilderService::instance() + .getTargetingImageBaseAddress(iv_pPnor); + + (void)_configureTargetPool(); + + iv_initialized = true; + + TARG_EXIT(); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getTopLevelTarget +//****************************************************************************** + +void TargetService::getTopLevelTarget( + Target*& o_targetHandle) const +{ + #define TARG_FN "getTopLevelTarget(...)" + + if (iv_initialized) + { + EntityPath l_topLevelPhysicalPath(EntityPath::PATH_PHYSICAL); + l_topLevelPhysicalPath.addLast(TYPE_SYS, 0); + o_targetHandle = toTarget(l_topLevelPhysicalPath); + } + else + { + o_targetHandle = NULL; + assert(iv_initialized); + } + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::exists +//****************************************************************************** + +void TargetService::exists( + const EntityPath& i_entityPath, + bool& o_exists) const +{ + #define TARG_FN "exists(...)" + + bool l_found = false; + if (iv_initialized) + { + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + if (i_entityPath == (*iv_targets)[i].getAttr<ATTR_PHYS_PATH> ()) + { + l_found = true; + } + } + } + else + { + assert(iv_initialized); + } + + o_exists = l_found; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::toTarget +//****************************************************************************** + +Target* TargetService::toTarget( + const EntityPath& i_entityPath) const +{ + #define TARG_FN "toTarget(...)" + + // Used by -> operator on EntityPath for convenience (can be dangerous + // though!) + Target* l_pTarget = NULL; + if (iv_initialized) + { + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + if (i_entityPath == (*iv_targets)[i].getAttr<ATTR_PHYS_PATH> ()) + { + l_pTarget = &(*iv_targets)[i]; + break; + } + } + } + else + { + assert(iv_initialized); + } + + return l_pTarget; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::masterProcChipTarget +//****************************************************************************** + +void TargetService::masterProcChipTargetHandle( + Target*& o_masterProcChipTargetHandle) const +{ + #define TARG_FN "masterProcChipTargetHandle(...)" + + Target* l_pTarget = NULL; + if (iv_initialized) + { + //@TODO Need to query the actual hardware and cross check it with + // PNOR to determine the master chip + // target; for now, just always report sys0.n0.proc0 + EntityPath l_masterProcChipEntityPath(EntityPath::PATH_PHYSICAL); + l_masterProcChipEntityPath.addLast(TYPE_SYS, 0).addLast(TYPE_NODE, 0) + .addLast(TYPE_PROC, 0); + + l_pTarget = l_masterProcChipEntityPath.operator->(); + } + else + { + assert(iv_initialized); + } + + o_masterProcChipTargetHandle = l_pTarget; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::tryGetPath +//****************************************************************************** + +bool TargetService::tryGetPath( + const ATTRIBUTE_ID i_attr, + const Target* const i_pTarget, + EntityPath& o_entityPath) const +{ + #define TARG_FN "tryGetPath(...)" + + bool l_exist = false; + if (iv_initialized) + { + switch (i_attr) + { + case ATTR_PHYS_PATH: + l_exist = i_pTarget->tryGetAttr<ATTR_PHYS_PATH> (o_entityPath); + break; + case ATTR_AFFINITY_PATH: + l_exist = i_pTarget->tryGetAttr<ATTR_AFFINITY_PATH> ( + o_entityPath); + break; + case ATTR_POWER_PATH: + l_exist = i_pTarget->tryGetAttr<ATTR_POWER_PATH> (o_entityPath); + break; + default: + TARG_ERR("BUG; i_attr = 0x%08X does not map to an entity " + "path"); + assert(0); + break; + } + } + else + { + assert(iv_initialized); + } + + return l_exist; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getAssociated +//****************************************************************************** + +void TargetService::getAssociated( + const Target* const i_pTarget, + const ASSOCIATION_TYPE i_type, + const RECURSION_LEVEL i_recursionLevel, + TargetHandleList& o_list) const +{ + #define TARG_FN "getAssociated(...)" + + do { + + assert(iv_initialized); + + if( (i_pTarget == NULL) + || (i_pTarget == MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) ) + { + TARG_ERR("BUG; caller tried to get association using a NULL target " + "handle or the master processor chip target handle sentinel. " + "i_pTarget = %p",i_pTarget); + assert(0); + } + + // Start with no elements + o_list.clear(); + + // Figure out which attribute to look up + for (uint32_t i = 0; i < iv_associationMappings.size(); ++i) + { + if (i_type == iv_associationMappings[i].associationType) + { + EntityPath l_entityPath; + + bool l_exist = tryGetPath(iv_associationMappings[i].attr, + i_pTarget, l_entityPath); + + if (l_exist) + { + if (iv_associationMappings[i].associationDir == INWARDS) + { + (void) _getInwards(iv_associationMappings[i].attr, + i_recursionLevel, l_entityPath, o_list); + } + else if (iv_associationMappings[i].associationDir + == OUTWARDS) + { + (void) _getOutwards(iv_associationMappings[i].attr, + i_recursionLevel, l_entityPath, o_list); + } + else + { + TARG_ERR("BUG; iv_associationMappings[i].associationDir " + "= 0x%X not supported", + iv_associationMappings[i].associationDir); + assert(0); + } + } + break; + } + } + + } while (0); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::dump() +//****************************************************************************** + +void TargetService::dump() const +{ + #define TARG_FN "dump(...)" + + if (iv_initialized) + { + TARG_INF("Targets (size=%d):", + sizeof(Target)*iv_maxTargets); + + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + TARG_INF( + "[Target %d] " + "Class = 0x%X, " + "Type = 0x%X, " + "Model = 0x%X", + i, + (*iv_targets)[i].getAttr<ATTR_CLASS>(), + (*iv_targets)[i].getAttr<ATTR_TYPE>(), + (*iv_targets)[i].getAttr<ATTR_MODEL>()); + TARG_INF("Physical"); + (*iv_targets)[i].getAttr<ATTR_PHYS_PATH>().dump(); + + EntityPath l_entityPath; + if( (*iv_targets)[i].tryGetAttr<ATTR_AFFINITY_PATH>(l_entityPath) ) + { + TARG_INF("Affinity"); + l_entityPath.dump(); + } + + if( (*iv_targets)[i].tryGetAttr<ATTR_POWER_PATH>(l_entityPath) ) + { + TARG_INF("Power"); + l_entityPath.dump(); + } + + uint8_t l_dummyRw = 0; + if ((*iv_targets)[i].tryGetAttr<ATTR_DUMMY_RW> (l_dummyRw)) + { + TARG_INF("Dummy = 0x%X", + l_dummyRw); + } + + TARG_INF("Supports FSI SCOM = %d", + (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() + .supportsFsiScom); + TARG_INF("Supports XSCOM SCOM = %d", + (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() + .supportsXscom); + TARG_INF("Supports Inband SCOM = %d", + (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() + .supportsInbandScom); + + ScomSwitches l_switches = {0}; + if ( (*iv_targets)[i].tryGetAttr<ATTR_SCOM_SWITCHES>(l_switches) ) + { + TARG_INF("Use FSI SCOM = %d",l_switches.useFsiScom); + TARG_INF("Use XSCOM = %d",l_switches.useXscom); + TARG_INF("Use inband SCOM = %d",l_switches.useInbandScom); + } + + uint64_t l_xscomBaseAddr = 0; + if ( (*iv_targets)[i].tryGetAttr<ATTR_XSCOM_BASE_ADDRESS>( + l_xscomBaseAddr) ) + { + TARG_INF("XSCOM Base Address = 0x%X",l_xscomBaseAddr); + } + + XscomChipInfo l_xscomChipInfo = {0}; + if ( (*iv_targets)[i].tryGetAttr<ATTR_XSCOM_CHIP_INFO>( + l_xscomChipInfo) ) + { + TARG_INF("XSCOM Node ID = 0x%X",l_xscomChipInfo.nodeId); + TARG_INF("XSCOM Chip ID = 0x%X",l_xscomChipInfo.chipId); + } + + } + } + else + { + assert(iv_initialized); + } + + return; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::_configureTargetPool +//****************************************************************************** + +void TargetService::_configureTargetPool() +{ + #define TARG_FN "_configureTargetPool(...)" + + TARG_ENTER(); + + _maxTargets(); + + // iv_pPnor--> points to uint32_t* --> points to --> uint32_t, targets[] + // (uint32_t*)+1 --> points to ------------> targets[] + + iv_targets = + reinterpret_cast< Target(*)[] > ( + *(reinterpret_cast<uint32_t**>( + const_cast<void*>(iv_pPnor))) + 1); + TARG_EXIT(); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::_maxTargets +//****************************************************************************** + +uint32_t TargetService::_maxTargets() +{ + #define TARG_FN "_maxTargets(...)" + + // Target count found by following the pointer pointed to by the iv_pPnor + // pointer. + iv_maxTargets = *(*(reinterpret_cast<const uint32_t * const *>(iv_pPnor))); + return iv_maxTargets; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::_getInwards +//****************************************************************************** + +void TargetService::_getInwards( + const ATTRIBUTE_ID i_attr, + const RECURSION_LEVEL i_recursionLevel, + EntityPath i_entityPath, + TargetHandleList& o_list) const +{ + #define TARG_FN "_getInwards(...)" + + while (i_entityPath.size() > 1) + { + i_entityPath.removeLast(); + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + EntityPath l_candidatePath; + bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i], + l_candidatePath); + if (l_candidateFound && (l_candidatePath == i_entityPath)) + { + o_list.push_back(&(*iv_targets)[i]); + break; + } + } + + if (i_recursionLevel == IMMEDIATE) + { + break; + } + } + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::_getOutwards +//****************************************************************************** + +void TargetService::_getOutwards( + const ATTRIBUTE_ID i_attr, + const RECURSION_LEVEL i_recursionLevel, + EntityPath i_entityPath, + TargetHandleList& o_list) const +{ + #define TARG_FN "_getOutwards()...)" + + do { + + // If at max depth (a leaf path element), no children possible + if (i_entityPath.size() >= EntityPath::MAX_PATH_ELEMENTS) + { + break; + } + + // Find the children (immediate, or all), depending on recursion level + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + EntityPath l_candidatePath; + bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i], + l_candidatePath); + if (l_candidateFound) + { + if ( ( (i_recursionLevel == IMMEDIATE) + && (l_candidatePath.size() == i_entityPath.size() + 1)) + || ( (i_recursionLevel == ALL) + && (l_candidatePath.size() > i_entityPath.size()))) + { + if (i_entityPath.equals(l_candidatePath,i_entityPath.size())) + { + o_list.push_back(&(*iv_targets)[i]); + } + } + } + } + + } while (0); + + #undef TARG_FN +} + +#undef TARG_CLASS + +#undef TARG_NAMESPACE + +} // End namespace TARGETING diff --git a/src/usr/targeting/test/attributestrings.C b/src/usr/targeting/test/attributestrings.C new file mode 100644 index 000000000..0cc2eda9c --- /dev/null +++ b/src/usr/targeting/test/attributestrings.C @@ -0,0 +1,84 @@ +/** + * @file attributestrings.C + * + * @brief Attribute string implementation. This file will be autogenerated in + * the future + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> + +// This component +#include <targeting/attributes.H> +#include <targeting/attributetraits.H> +#include <targeting/attributestrings.H> + +namespace TARGETING { + +//****************************************************************************** +// attrToString<ATTR_CLASS> +//****************************************************************************** + +template<> +const char* attrToString<ATTR_CLASS> ( + AttributeTraits<ATTR_CLASS>::Type const& i_attrValue) +{ + switch (i_attrValue) + { + case CLASS_CARD: + return "Card"; + case CLASS_ENC: + return "Enclosure"; + case CLASS_CHIP: + return "Chip"; + case CLASS_UNIT: + return "Unit"; + case CLASS_DEV: + return "Device"; + default: + return "Cannot decode class"; + } +} + +//****************************************************************************** +// attrToString<ATTR_TYPE> +//****************************************************************************** + +template<> +const char* attrToString<ATTR_TYPE> ( + AttributeTraits<ATTR_TYPE>::Type const& i_attrValue) +{ + switch (i_attrValue) + { + case TYPE_PROC: + return "Processor"; + case TYPE_EX: + return "EX chiplet"; + default: + return "Cannot decode type"; + } +} + +//****************************************************************************** +// attrToString<ATTR_MODEL> +//****************************************************************************** + +template<> +const char* attrToString<ATTR_MODEL> ( + AttributeTraits<ATTR_MODEL>::Type const& i_attrValue) +{ + switch (i_attrValue) + { + case MODEL_SALERNO: + return "Salerno"; + default: + return "Cannot decode model"; + } +} + +} // End namespace TARGETING diff --git a/src/usr/targeting/test/makefile b/src/usr/targeting/test/makefile new file mode 100644 index 000000000..4f0ff8b66 --- /dev/null +++ b/src/usr/targeting/test/makefile @@ -0,0 +1,8 @@ +ROOTPATH = ../../../.. + +MODULE = testtargeting +TESTS = *.H + +OBJS = attributestrings.o + +include ${ROOTPATH}/config.mk diff --git a/src/usr/targeting/test/targetingtest.H b/src/usr/targeting/test/targetingtest.H new file mode 100644 index 000000000..bd8ffdb0e --- /dev/null +++ b/src/usr/targeting/test/targetingtest.H @@ -0,0 +1,457 @@ +#ifndef __TESTTARGETING_H +#define __TESTTARGETING_H + +/** + * @file testtargeting.H + * + * @brief All unit tests for the targeting infrastructure + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdio.h> +#include <sys/time.h> + +// CXXTEST +#include <cxxtest/TestSuite.H> + +// This component +#include <targeting/attributes.H> +#include <targeting/entitypath.H> +#include <targeting/target.H> +#include <targeting/targetservice.H> + +class TargetingTestSuite: public CxxTest::TestSuite +{ + public: + + /** + * @brief Test the TargetService class (except debug cases) + */ + void testTargetServiceClass() + { + nanosleep(1,0); + TS_TRACE(ENTER_MRK "testTargetServiceClass" ); + + using namespace TARGETING; + + TargetService& l_targetService = targetService(); + + l_targetService.init(); + + // Post init + // Test: void masterProcChipTarget( + // TargetHandleList& o_masterProcChipTarget) const; + + Target* l_pMasterProcChipTargetHandle = NULL; + (void) l_targetService.masterProcChipTargetHandle( + l_pMasterProcChipTargetHandle); + + if ( l_pMasterProcChipTargetHandle + == MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) + { + TS_FAIL("Post init; master proc chip target handle should not " + "be the sentinel value"); + } + + if (l_pMasterProcChipTargetHandle == NULL) + { + TS_FAIL("Post init; master proc chip target handle should not " + "be the NULL value"); + } + + if ( l_pMasterProcChipTargetHandle->getAttr<ATTR_CLASS> () + != CLASS_CHIP) + { + TS_FAIL("Post init; master proc chip target handle was not of " + "chip class"); + } + + if ( l_pMasterProcChipTargetHandle->getAttr<ATTR_TYPE> () + != TYPE_PROC) + { + TS_FAIL("Post init; master proc chip target handle was not of " + "proc type"); + } + + // Post init + // Test: void getTopLevelTarget(Target*& o_targetHandle) const; + + Target* l_pTopLevel = NULL; + (void) l_targetService.getTopLevelTarget(l_pTopLevel); + if (l_pTopLevel == NULL) + { + TS_FAIL("Top level handle was NULL when initialization " + "complete"); + } + + if (l_pTopLevel->getAttr<ATTR_CLASS> () != CLASS_SYS) + { + TS_FAIL("Post init; top level target class != CLASS_SYS"); + } + + // Post init + // Test: void exists( + // const EntityPath& i_entityPath, + // bool& o_exists) const; + + bool l_exists = false; + (void) l_targetService.exists( + l_pTopLevel->getAttr<ATTR_PHYS_PATH> (), l_exists); + + if (l_exists != true) + { + TS_FAIL("Expected top level target to exist"); + } + + // Post init + // Test: Target* toTarget( + // const EntityPath& i_entityPath) const; + + Target* l_pInverseTarget = NULL; + l_pInverseTarget = l_targetService.toTarget( + l_pTopLevel->getAttr<ATTR_PHYS_PATH> ()); + + if (l_pInverseTarget != l_pTopLevel) + { + TS_FAIL("Expected to get the original target"); + } + + // Post init + // Test: void getAssociated( + // const Target* i_pTarget, + // ASSOCIATION_TYPE i_type, + // RECURSION_LEVEL i_recursionLevel, + // TargetHandleList& o_list) const; + + TargetHandleList l_list; + (void) l_targetService.getAssociated(l_pTopLevel, + TARGETING::TargetService::CHILD, + TARGETING::TargetService::IMMEDIATE, l_list); + if (!l_list.size()) + { + TS_FAIL("Should have found some child elements" ); + } + + // Verify child of given target has a parent that is the original + // target + + TargetHandleList l_parentList; + (void) l_targetService.getAssociated(l_list[0], + TARGETING::TargetService::PARENT, + TARGETING::TargetService::IMMEDIATE, l_parentList); + + if (l_parentList.size() != 1) + { + TS_FAIL("Should have found a parent element" ); + } + + if (l_parentList[0] != l_pTopLevel) + { + TS_FAIL("Parent handle should have matched original target " + "handle" ); + } + + (void) l_targetService.getAssociated(l_pTopLevel, + TARGETING::TargetService::CHILD_BY_AFFINITY, + TARGETING::TargetService::IMMEDIATE, l_list); + + if (!l_list.size()) + { + TS_FAIL("Should have found some child elements" ); + } + + (void) l_targetService.getAssociated(l_pTopLevel, + TARGETING::TargetService::CHILD_BY_AFFINITY, + TARGETING::TargetService::ALL, l_list); + + if (!l_list.size()) + { + TS_FAIL("Should have found more child elements" ); + } + + l_targetService.dump(); + + TS_TRACE(EXIT_MRK "testTargetServiceClass" ); + } + + /** + * @test Tests the EntityPath class (except debug cases) + */ + void testEntityPathClass(void) + { + TS_TRACE(ENTER_MRK "testEntityPathClass" ); + + using namespace TARGETING; + + EntityPath l_defaultPath; + if(l_defaultPath.size() != 0) + { + TS_FAIL("Default entity path's size was not 0"); + } + + if(l_defaultPath.type() != EntityPath::PATH_NA) + { + TS_FAIL("Default entity path's type was not PATH_NA"); + } + + EntityPath l_nonDefaultPath(EntityPath::PATH_PHYSICAL); + if(l_nonDefaultPath.size() != 0) + { + TS_FAIL("Non-default entity path's size was not 0"); + } + + if(l_nonDefaultPath.type() != EntityPath::PATH_PHYSICAL) + { + TS_FAIL("Non-default entity path's type was not " + "EntityPath::PATH_PHYSICAL"); + } + + l_defaultPath.setType(EntityPath::PATH_AFFINITY); + if(l_defaultPath.type() != EntityPath::PATH_AFFINITY) + { + TS_FAIL("Default entity path's type was not " + "EntityPath::PATH_AFFINITY after setting"); + } + + l_defaultPath.setType(EntityPath::PATH_PHYSICAL); + if(!(l_defaultPath == l_nonDefaultPath)) + { + TS_FAIL("Default entity path should have been equal to " + "the non-default entity path"); + } + + if(!l_defaultPath.equals(l_nonDefaultPath,0)) + { + TS_FAIL("Default entity path should have been equal to " + "the non-default entity path (equals API)"); + } + + l_defaultPath.addLast(TYPE_PROC,0); + if(l_defaultPath == l_nonDefaultPath) + { + TS_FAIL("Default entity path should NOT have been equal to " + "the non-default entity path"); + } + + if(l_defaultPath.equals(l_nonDefaultPath,1)) + { + TS_FAIL("Default entity path should NOT have been equal to " + "the non-default entity path (equals API, comparing 1 " + "element)"); + } + + if(l_defaultPath.size() != 1) + { + TS_FAIL("Default entity path should have had one path element" + "after adding PROC0"); + } + + l_nonDefaultPath.addLast(TYPE_PROC,0); + if(! (l_defaultPath == l_nonDefaultPath) ) + { + TS_FAIL("Default entity path should have been equal to " + "the non-default entity path since they now" + "both have the same 1 path element"); + } + + l_defaultPath.addLast(TYPE_MBA,1).addLast(TYPE_MBS,2); + if(l_defaultPath.size() != 3) + { + TS_FAIL("Default entity path should have had two path elements" + "after adding MBA1 and MBS2"); + } + + if( (l_defaultPath[0].type != TYPE_PROC) + || (l_defaultPath[0].instance != 0) + || (l_defaultPath[1].type != TYPE_MBA) + || (l_defaultPath[1].instance != 1) + || (l_defaultPath[2].type != TYPE_MBS) + || (l_defaultPath[2].instance != 2)) + { + TS_FAIL("Default entity path should have had correct 3 path " + "elements"); + } + + l_defaultPath.removeLast(); + if(l_defaultPath.size() != 2) + { + TS_FAIL("Default entity path should have had two path elements" + "after removing MBS2"); + } + + if( (l_defaultPath[0].type != TYPE_PROC) + || (l_defaultPath[0].instance != 0) + || (l_defaultPath[1].type != TYPE_MBA) + || (l_defaultPath[1].instance != 1)) + { + TS_FAIL("Default entity path should have had correct 2 path " + "elements"); + } + + l_nonDefaultPath.addLast(TYPE_MBA,1).addLast(TYPE_MBS,2); + + // Default now has proc/mba/ + // Non-default now has proc/mba/mbs + if(l_defaultPath == l_nonDefaultPath) + { + TS_FAIL("Default entity path should NOT have been equal to " + "the non-default entity path since they now" + "have different number of path elements"); + } + + if( !l_defaultPath.equals(l_nonDefaultPath,2) ) + { + TS_FAIL("Default entity path should have been equal to " + "the non-default entity path since they have the same" + "first two path elements"); + } + + l_defaultPath.removeLast().removeLast(); + if(l_defaultPath.size() != 0) + { + TS_FAIL("Default entity path should have had no path element" + "after removing MBA1 and PROC0"); + } + + TargetService& l_targetService = targetService(); + l_targetService.init(); + + EntityPath l_realPath(EntityPath::PATH_PHYSICAL); + l_realPath.addLast(TYPE_SYS,0).addLast(TYPE_NODE,0) + .addLast(TYPE_PROC,0); + + Target* l_pTarget = l_realPath.operator->(); + if(l_pTarget == NULL) + { + TS_FAIL("Real entity path should have mapped to an existing " + "target"); + } + + EntityPath l_path(EntityPath::PATH_PHYSICAL); + l_path.addLast(TYPE_SYS,0); + EntityPath l_changedPath = l_path.copyRemoveLast(); + if( (l_changedPath.size() != 0) + || (l_path.size() != 1)) + { + TS_FAIL("Const entity path should not have been altered in " + "const add test"); + } + + l_changedPath = l_path.copyAddLast(TYPE_NODE,0); + if( (l_changedPath.size() != 2) + || (l_path.size() != 1)) + { + TS_FAIL("Const entity path should not have been altered " + "in const add test"); + } + + TS_TRACE(EXIT_MRK "testEntityPathClass" ); + } + + /** + * @test Tests the EntityPath class (except debug cases) + */ + void testTargetClass(void) + { + TS_TRACE(ENTER_MRK "testTargetClass" ); + + using namespace TARGETING; + TargetService& l_targetService = targetService(); + l_targetService.init(); + + EntityPath l_realPath(EntityPath::PATH_PHYSICAL); + l_realPath.addLast(TYPE_SYS,0).addLast(TYPE_NODE,0) + .addLast(TYPE_PROC,0); + l_realPath.dump(); + + Target* l_pTarget = l_realPath.operator->(); + if(l_pTarget == NULL) + { + TS_FAIL("Failed to convert entity path to initial target"); + } + + CLASS l_class = l_pTarget->getAttr<ATTR_CLASS>(); + if(l_class != CLASS_CHIP) + { + TS_FAIL("Failed to get the class attribute"); + } + + l_class = CLASS_NA; + if( !l_pTarget->tryGetAttr<ATTR_CLASS>(l_class) ) + { + TS_FAIL("Failed to get the class attribute"); + } + + if(l_class != CLASS_CHIP) + { + TS_FAIL("Failed to try/get the class attribute"); + } + + attrToString<ATTR_CLASS>(l_class); + + uint8_t l_scom = 0; + if( l_pTarget->tryGetAttr<ATTR_DUMMY_RO>(l_scom) ) + { + TS_FAIL("ATTR_DUMMY_RO attribute should not have been available " + "to read"); + } + + if(l_scom != 0) + { + TS_FAIL("Failed ! try/get should not have set the SCOM attribute"); + } + + l_scom = 5; + if( l_pTarget->trySetAttr<ATTR_DUMMY_WO>(l_scom) ) + { + TS_FAIL("ATTR_DUMMY_WO attribute should not have been available " + "to write"); + } + + if(l_scom != 5) + { + TS_FAIL("SCOM attribute should not have been altered in the failed " + "write"); + } + + uint8_t l_wo = 6; + if( !l_pTarget->trySetAttr<ATTR_DUMMY_RW>(l_wo) ) + { + TS_FAIL("ATTR_DUMMY_RW should have been available for write"); + } + + if(l_wo != 6) + { + TS_FAIL("ATTR_DUMMY_RW local attribute should not have been " + "altered in the successful write"); + } + + uint8_t l_read = l_pTarget->getAttr<ATTR_DUMMY_RW>(); + if(l_read != l_wo) + { + TS_FAIL("Failed to read back the correct ATTR_DUMMY_RW"); + } + + uint8_t l_setWo = 9; + l_pTarget->setAttr<ATTR_DUMMY_RW>(l_setWo); + if(l_setWo != 9) + { + TS_FAIL("ATTR_DUMMY_RW local attribute should not have been " + "altered in the successful setAttr"); + } + + uint8_t l_setWoVerify = l_pTarget->getAttr<ATTR_DUMMY_RW>(); + if(l_setWoVerify != l_setWo) + { + TS_FAIL("ATTR_DUMMY_RW read should have matched prior write"); + } + + TS_TRACE(EXIT_MRK "testTargetClass" ); + } +}; + +#endif // End __TESTTARGETING_H diff --git a/src/usr/targeting/trace.H b/src/usr/targeting/trace.H new file mode 100644 index 000000000..d16ef8ece --- /dev/null +++ b/src/usr/targeting/trace.H @@ -0,0 +1,43 @@ + +#ifndef TARG_TRACE_H +#define TARG_TRACE_H + +/** + * @file trace.H + * + * @brief Targeting related trace macros. Callers of these macros must + * define TARG_NAMESPACE, TARG_CLASS, and TARG_FN as appropriate + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// Other Components +#include <trace/interface.H> + +// Give callers access to the trace buffer +namespace TARGETING +{ + extern trace_desc_t* g_trac_targeting; +} + +#define TARG_TAG "[TARG]" +#define TARG_ENTER(args...) \ + TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " ENTER_MRK " " TARG_NAMESPACE \ + TARG_CLASS TARG_FN " " args) + +#define TARG_EXIT(args...) \ + TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " EXIT_MRK " " TARG_NAMESPACE \ + TARG_CLASS TARG_FN " " args) + +#define TARG_ERR(args...) \ + TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " ERR_MRK " " args) + +#define TARG_INF(args...) \ + TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " INFO_MRK " " args) + +#define TARG_BIN(args...) \ + TRACFBIN(TARGETING::g_trac_targeting,TARG_TAG " " args) + +#endif // TARG_TRACE_H |