summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2011-09-08 00:06:56 -0500
committerNicholas E. Bofferding <bofferdn@us.ibm.com>2011-09-19 13:18:30 -0500
commitb08159eb20f2a0ccfe2d654f56a6fe2079bec98e (patch)
tree5248e5cea65eff0ba758ed5d50bad1b26884e883 /src/usr
parentea37c1fc02819175e8ede86718a3afc904c723bc (diff)
downloadtalos-hostboot-b08159eb20f2a0ccfe2d654f56a6fe2079bec98e.tar.gz
talos-hostboot-b08159eb20f2a0ccfe2d654f56a6fe2079bec98e.zip
Implement support for generating the PNOR targeting image
- Generate PNOR targeting image as part of the build process - Load it into SIMICS physical memory - Access image from targeting service at correct virtual address - Bridge fapi attributes to host boot attributes using direct macro - Support multidimensional arrays for simple attributes - Removed support for fake PNOR image Change-Id: I45d986d69397940a165c850d0db0fdeccd137d4d Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/341 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Reviewed-by: CAMVAN T. NGUYEN <ctnguyen@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/hwpf/hwp/fapiHwpAttributeInfo.xml10
-rw-r--r--src/usr/hwpf/plat/fapiPlatAttributeService.C100
-rw-r--r--src/usr/hwpf/plat/makefile3
-rw-r--r--src/usr/pnor/pnorrp.C2
-rw-r--r--src/usr/pnor/test/pnorrptest.H2
-rw-r--r--src/usr/targeting/fakepnordata.C545
-rw-r--r--src/usr/targeting/fakepnordata.H693
-rw-r--r--src/usr/targeting/makefile5
-rw-r--r--src/usr/targeting/predicates/predicatectm.C2
-rw-r--r--src/usr/targeting/targetservice.C38
-rw-r--r--src/usr/targeting/test/attributestrings.C106
-rw-r--r--src/usr/targeting/test/makefile8
-rw-r--r--src/usr/targeting/test/targetingtest.H174
-rw-r--r--src/usr/targeting/xmltohb/hb.xml1032
-rw-r--r--src/usr/targeting/xmltohb/makefile52
-rwxr-xr-xsrc/usr/targeting/xmltohb/xmltohb.pl2385
16 files changed, 3787 insertions, 1370 deletions
diff --git a/src/usr/hwpf/hwp/fapiHwpAttributeInfo.xml b/src/usr/hwpf/hwp/fapiHwpAttributeInfo.xml
index 16b98f1ed..6951ca1e5 100644
--- a/src/usr/hwpf/hwp/fapiHwpAttributeInfo.xml
+++ b/src/usr/hwpf/hwp/fapiHwpAttributeInfo.xml
@@ -126,4 +126,14 @@
<array>2 2</array>
<writeable/>
</attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
+ <id>ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>Dummy plat init uint8 attribute used for testing</description>
+ <valueType>uint8</valueType>
+ <platInit/>
+ <writeable/>
+ <array>1 3 5</array>
+ </attribute>
</attributes>
diff --git a/src/usr/hwpf/plat/fapiPlatAttributeService.C b/src/usr/hwpf/plat/fapiPlatAttributeService.C
new file mode 100644
index 000000000..e72e637f5
--- /dev/null
+++ b/src/usr/hwpf/plat/fapiPlatAttributeService.C
@@ -0,0 +1,100 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/hwpf/plat/fapiPlatAttributeService.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+
+/**
+ * @file fapiPlatAttributeService.C
+ *
+ * @brief Implements HWP attribute -> HB attribute bridging functions
+ *
+ * Note that platform code must provide the implementation.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+#include <targeting/targetservice.H>
+#include <errl/errlentry.H>
+#include <errl/errltypes.H>
+#include <hwpf/plat/fapiPlatAttributeService.H>
+#include <hwpf/plat/fapiPlatReasonCodes.H>
+
+//******************************************************************************
+// Implementation
+//******************************************************************************
+
+namespace fapi
+{
+
+namespace platAttrSvc
+{
+
+//******************************************************************************
+// fapi::platAttrSvc::getSystemTarget
+//******************************************************************************
+
+TARGETING::Target* getSystemTarget()
+{
+ TARGETING::Target* l_pTarget = NULL;
+ TARGETING::targetService().getTopLevelTarget(l_pTarget);
+ assert(l_pTarget);
+ return l_pTarget;
+}
+
+//******************************************************************************
+// fapi::platAttrSvc::createAttrAccessError
+//******************************************************************************
+
+fapi::ReturnCode createAttrAccessError(
+ const TARGETING::ATTRIBUTE_ID i_targAttrId,
+ const fapi::AttributeId i_fapiAttrId,
+ const fapi::Target* const i_pFapiTarget)
+{
+ /*
+ * @errortype
+ * @moduleid fapi::MOD_PLAT_ATTR_SVC_CREATE_ATTR_ACCESS_ERROR
+ * @reasoncode fapi::RC_FAILED_TO_ACCESS_ATTRIBUTE
+ * @userdata1 Top 32 bits = platform attribute ID, lower 32 bits =
+ * FAPI attribute ID
+ * @userdata2 FAPI target type, or NULL if system target
+ * @devdesc Failed to get requested attribute.
+ * Possible causes: Invalid target, attribute not implemented,
+ * attribute not present on given target, target service not
+ * initialized
+ */
+ errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ fapi::MOD_PLAT_ATTR_SVC_CREATE_ATTR_ACCESS_ERROR,
+ fapi::RC_FAILED_TO_ACCESS_ATTRIBUTE,
+ (static_cast<uint64_t>(i_targAttrId) << 32)
+ | (static_cast<uint64_t>(i_fapiAttrId)),
+ i_pFapiTarget ? i_pFapiTarget->getType(): NULL);
+
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA;
+ l_rc.setPlatData(reinterpret_cast<void *>(l_pError));
+ return l_rc;
+}
+
+} // End platAttrSvc namespace
+
+} // End fapi namespace
diff --git a/src/usr/hwpf/plat/makefile b/src/usr/hwpf/plat/makefile
index b66185740..e14cf76a1 100644
--- a/src/usr/hwpf/plat/makefile
+++ b/src/usr/hwpf/plat/makefile
@@ -33,6 +33,7 @@ OBJS = fapiPlatHwAccess.o \
fapiPlatReturnCodeDataRef.o \
fapiPlatSystemConfig.o \
fapiPlatTarget.o \
- fapiPlatUtil.o
+ fapiPlatUtil.o \
+ fapiPlatAttributeService.o
include ${ROOTPATH}/config.mk
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index 3d1dc3889..005ff8525 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -321,7 +321,7 @@ errlHndl_t PnorRP::readTOC()
iv_TOC[PNOR::SIDE_A][PNOR::TOC].size = 8 + 8 + PNOR::NUM_SECTIONS*sizeof(TOCEntry_t);
iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].size = 500*1024; //500K
iv_TOC[PNOR::SIDE_A][PNOR::GLOBAL_DATA].size = PAGESIZE; //4K
- iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].size = 2*PAGESIZE; //8K
+ iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].size = 4*PAGESIZE; //16K
// fake PNOR will look like this: TOC::HB_EXT_CODE:GLOBAL_DATA:HB_DATA
// virtual addresses
diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H
index 9741b6cb0..f3825edd5 100644
--- a/src/usr/pnor/test/pnorrptest.H
+++ b/src/usr/pnor/test/pnorrptest.H
@@ -67,7 +67,7 @@ class PnorRpTest : public CxxTest::TestSuite
/* GLOBAL_DATA */ { PAGESIZE, 0x8007D690 },
/* SBE_IPL */ { 0, 0 },
/* HB_BASE_CODE */ { 0, 0 },
- /* HB_DATA */ { 2*PAGESIZE, 0x8007E690 },
+ /* HB_DATA */ { 4*PAGESIZE, 0x8007E690 },
/* HB_ERRLOGS */ { 0, 0 },
/* HB_EXT_CODE */ { 0x7D000, 0x80000690 },
/* HB_RUNTIME */ { 0, 0 },
diff --git a/src/usr/targeting/fakepnordata.C b/src/usr/targeting/fakepnordata.C
deleted file mode 100644
index 4d5e78306..000000000
--- a/src/usr/targeting/fakepnordata.C
+++ /dev/null
@@ -1,545 +0,0 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/targeting/fakepnordata.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
-
-/**
- * @file 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
deleted file mode 100644
index 4389cc105..000000000
--- a/src/usr/targeting/fakepnordata.H
+++ /dev/null
@@ -1,693 +0,0 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/targeting/fakepnordata.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
-
-#ifndef 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
index d335c2d93..1c26396f6 100644
--- a/src/usr/targeting/makefile
+++ b/src/usr/targeting/makefile
@@ -39,11 +39,10 @@ ITERATORS_OBJS = \
TARGET_OBJS = \
target.o \
targetservice.o \
- entitypath.o \
- fakepnordata.o
+ entitypath.o
OBJS = ${TARGET_OBJS} ${PREDICATES_OBJS} ${ITERATORS_OBJS}
-SUBDIRS = test.d
+SUBDIRS = test.d xmltohb.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/targeting/predicates/predicatectm.C b/src/usr/targeting/predicates/predicatectm.C
index 79de118ea..cb3275c19 100644
--- a/src/usr/targeting/predicates/predicatectm.C
+++ b/src/usr/targeting/predicates/predicatectm.C
@@ -38,7 +38,7 @@
// Targeting Component
#include <targeting/target.H>
-#include <targeting/attributeenums.H>
+#include <attributeenums.H>
#include <targeting/predicates/predicatectm.H>
//******************************************************************************
diff --git a/src/usr/targeting/targetservice.C b/src/usr/targeting/targetservice.C
index 701ea646c..497807348 100644
--- a/src/usr/targeting/targetservice.C
+++ b/src/usr/targeting/targetservice.C
@@ -40,12 +40,13 @@
#include <sys/task.h>
#include <trace/interface.H>
#include <initservice/taskargs.H>
+#include <pnor/pnorif.H>
// This component
#include <targeting/targetservice.H>
#include "trace.H"
-#include "fakepnordata.H"
#include <targeting/predicates/predicatebase.H>
+#include <pnortargeting.H>
//******************************************************************************
// targetService
@@ -171,9 +172,24 @@ void TargetService::init()
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);
+ // PNOR.
+ //@TODO Fully account for the attribute resource provider
+ PNOR::SectionInfo_t l_sectionInfo;
+ errlHndl_t l_pElog = PNOR::getSectionInfo(
+ PNOR::HB_DATA, PNOR::SIDE_A, l_sectionInfo );
+ if(l_pElog)
+ {
+ l_pElog->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE);
+ errlCommit(l_pElog);
+ assert("Failed to get handle to targeting data");
+ }
+
+ TargetingHeader* l_pHdr = reinterpret_cast<TargetingHeader*>(
+ l_sectionInfo.vaddr);
+ assert(l_pHdr->eyeCatcher == PNOR_TARG_EYE_CATCHER);
+
+ iv_pPnor = reinterpret_cast<uint32_t*>(
+ (reinterpret_cast<char*>(l_pHdr) + l_pHdr->headerSize));
(void)_configureTargetPool();
@@ -495,11 +511,12 @@ void TargetService::dump() const
l_entityPath.dump();
}
- uint8_t l_dummyRw = 0;
+ DUMMY_RW_ATTR l_dummyRw;
+ memset(l_dummyRw,0x00,sizeof(l_dummyRw));
if ((*iv_targets)[i].tryGetAttr<ATTR_DUMMY_RW> (l_dummyRw))
{
TARG_INF("Dummy = 0x%X",
- l_dummyRw);
+ l_dummyRw[0][0][0]);
}
TARG_INF("Supports FSI SCOM = %d",
@@ -570,8 +587,8 @@ void TargetService::_configureTargetPool()
// (uint32_t*)+1 --> points to ------------> targets[]
iv_targets =
- reinterpret_cast< Target(*)[] > (
- *(reinterpret_cast<uint32_t**>(
+ reinterpret_cast< Target(*)[] > (
+ *(static_cast<uint32_t**>(
const_cast<void*>(iv_pPnor))) + 1);
TARG_EXIT();
@@ -588,7 +605,10 @@ uint32_t TargetService::_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)));
+ iv_maxTargets = *(*(static_cast<const uint32_t * const *>(iv_pPnor)));
+
+ TARG_INF("Max targets = %d",iv_maxTargets);
+
return iv_maxTargets;
#undef TARG_FN
diff --git a/src/usr/targeting/test/attributestrings.C b/src/usr/targeting/test/attributestrings.C
deleted file mode 100644
index 9cfa61d53..000000000
--- a/src/usr/targeting/test/attributestrings.C
+++ /dev/null
@@ -1,106 +0,0 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/targeting/test/attributestrings.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
-/**
- * @file 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
index 1e3d79623..e4398bf7c 100644
--- a/src/usr/targeting/test/makefile
+++ b/src/usr/targeting/test/makefile
@@ -22,9 +22,17 @@
# IBM_PROLOG_END
ROOTPATH = ../../../..
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
+
MODULE = testtargeting
TESTS = *.H
OBJS = attributestrings.o
include ${ROOTPATH}/config.mk
+
+vpath %.C ${GENDIR}
+
diff --git a/src/usr/targeting/test/targetingtest.H b/src/usr/targeting/test/targetingtest.H
index 9f6c13db4..8dd2ad56a 100644
--- a/src/usr/targeting/test/targetingtest.H
+++ b/src/usr/targeting/test/targetingtest.H
@@ -39,6 +39,11 @@
// CXXTEST
#include <cxxtest/TestSuite.H>
+#include <hwpf/plat/fapiPlatAttributeService.H>
+#include <fapiReturnCode.H>
+#include <fapiAttributeIds.H>
+#include <fapiAttributeService.H>
+#include <errl/errlmanager.H>
// This component
#include <targeting/attributes.H>
@@ -88,6 +93,20 @@ class TargetingTestSuite: public CxxTest::TestSuite
"be the NULL value");
}
+ ScomSwitches l_switches = {0};
+ l_switches =
+ l_pMasterProcChipTargetHandle->getAttr<ATTR_SCOM_SWITCHES>();
+ if( l_switches.useFsiScom != 0
+ || l_switches.useXscom != 1
+ || l_switches.useInbandScom != 0
+ || l_switches.reserved != 0)
+ {
+ TS_FAIL("SCOM Switches stuct was not correct (%d, %d, %d, %d)",
+ l_switches.useFsiScom, l_switches.useXscom,
+ l_switches.useInbandScom ,
+ l_switches.reserved);
+ }
+
if ( l_pMasterProcChipTargetHandle->getAttr<ATTR_CLASS> ()
!= CLASS_CHIP)
{
@@ -447,41 +466,50 @@ class TargetingTestSuite: public CxxTest::TestSuite
if(l_scom != 5)
{
- TS_FAIL("SCOM attribute should not have been altered in the failed "
- "write");
+ TS_FAIL("SCOM attribute should not have been altered in the "
+ "failed write");
}
- uint8_t l_wo = 6;
+ DUMMY_RW_ATTR l_wo;
+ memset(l_wo,0x00,sizeof(l_wo));
+ l_wo[0][1][2] = 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)
+ if(l_wo[0][1][2] != 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)
+ DUMMY_RW_ATTR l_read;
+ l_pTarget->tryGetAttr<ATTR_DUMMY_RW>(l_read);
+ if(memcmp(l_read,l_wo,sizeof(l_read)))
{
TS_FAIL("Failed to read back the correct ATTR_DUMMY_RW");
}
- uint8_t l_setWo = 9;
+ DUMMY_RW_ATTR l_setWo;
+ memset(l_setWo,0x00,sizeof(l_setWo));
+ l_setWo[0][2][4] = 9;
l_pTarget->setAttr<ATTR_DUMMY_RW>(l_setWo);
- if(l_setWo != 9)
+ if(l_setWo[0][2][4] != 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)
+ DUMMY_RW_ATTR l_setWoVerify;
+ l_pTarget->tryGetAttr<ATTR_DUMMY_RW>(l_setWoVerify);
+ if(memcmp(l_setWoVerify,l_setWo,sizeof(l_setWoVerify)))
{
TS_FAIL("ATTR_DUMMY_RW read should have matched prior write");
}
+
+ memset(l_setWo,0x05,sizeof(l_setWo));
+ l_pTarget->setAttr<ATTR_DUMMY_RW>(l_setWo);
TS_TRACE(EXIT_MRK "testTargetClass" );
}
@@ -991,6 +1019,132 @@ class TargetingTestSuite: public CxxTest::TestSuite
TS_TRACE(EXIT_MRK "testComplexFilter" );
}
+
+ void testFapiToHbMacros ()
+ {
+ TS_TRACE(ENTER_MRK "testFapiToHbMacros" );
+
+ TS_TRACE(INF_MRK "Now using direct access macros");
+
+ using namespace TARGETING;
+ using namespace fapi;
+
+ TargetService& l_targetService = targetService();
+
+ TARGETING::Target* l_pTarget = NULL;
+ (void) l_targetService.getTopLevelTarget(l_pTarget);
+ if (l_pTarget == NULL)
+ {
+ TS_FAIL("Top level handle was NULL when initialization "
+ "complete");
+ }
+
+ DUMMY_RW_ATTR l_dummyRw;
+ memset(l_dummyRw,0x00,sizeof(l_dummyRw));
+ l_pTarget->tryGetAttr<TARGETING::ATTR_DUMMY_RW>(l_dummyRw);
+ if(l_dummyRw[0][1][2] != 5)
+ {
+ TS_FAIL("l_dummyRw value is %d, not 5 as expected in direct "
+ "attribute access",l_dummyRw[0][1][2]);
+ }
+
+ TARGETING::CLASS l_class =
+ l_pTarget->getAttr<TARGETING::ATTR_CLASS>();
+ if(l_class != TARGETING::CLASS_SYS)
+ {
+ TS_FAIL("l_class value is %d, not %d as expected in direct "
+ "attribute access",l_class,TARGETING::CLASS_SYS);
+ }
+
+ TARGETING::TYPE l_type = l_pTarget->getAttr<TARGETING::ATTR_TYPE>();
+ if(l_type != TARGETING::TYPE_SYS)
+ {
+ TS_FAIL("l_type value is %d, not %d as expected in direct "
+ "attribute access",l_type,TARGETING::TYPE_SYS);
+ }
+
+ uint64_t l_xscom =
+ l_pTarget->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>();
+ if(l_xscom != 0x300000000000)
+ {
+ TS_FAIL("l_xscom value is %x, not %x as expected in direct "
+ "attribute access",l_xscom,0x300000000000);
+ }
+
+ TS_TRACE(INF_MRK "Now using FAPI get macros");
+
+ memset(l_dummyRw,0x00,sizeof(l_dummyRw));
+ fapi::ReturnCode l_rc = FAPI_ATTR_GET(
+ ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8, NULL, l_dummyRw);
+ if(l_rc != 0)
+ {
+ TS_FAIL("Failed to get dummy RW attribute on system target");
+ }
+
+ if(l_dummyRw[0][2][4] != 5)
+ {
+ TS_FAIL("l_dummyRw value is %d, not 5 as expected",
+ l_dummyRw[0][2][4]);
+ }
+
+ TS_TRACE(INF_MRK "Now using FAPI set macros");
+
+ l_dummyRw[0][2][3] = 6;
+ l_rc = FAPI_ATTR_SET(ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8, NULL,
+ l_dummyRw);
+ if(l_rc != 0)
+ {
+ TS_FAIL("Failed to write dummy RW attribute on system target");
+ }
+
+ memset(l_dummyRw,0x00,sizeof(l_dummyRw));
+ l_rc = FAPI_ATTR_GET(ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8, NULL,
+ l_dummyRw);
+ if(l_rc != 0)
+ {
+ TS_FAIL("Failed to get dummy RW attribute on system target");
+ }
+
+ if(l_dummyRw[0][2][3] != 6)
+ {
+ TS_FAIL("l_dummyRw value is %d, not 6 as expected due to a "
+ "prior write",l_dummyRw[0][2][3]);
+ }
+
+ TS_TRACE(INF_MRK "Now using targets without the attribute");
+
+ memset(l_dummyRw,0x00,sizeof(l_dummyRw));
+ EntityPath l_realPath(EntityPath::PATH_PHYSICAL);
+ l_realPath.addLast(TYPE_SYS,0).addLast(TYPE_NODE,0);
+ l_pTarget = l_realPath.operator->();
+ if (l_pTarget == NULL)
+ {
+ TS_FAIL("Node 0 target handle should not be NULL");
+ }
+
+ fapi::Target* l_pFapiTarget = new fapi::Target(
+ fapi::TARGET_TYPE_PROC_CHIP, l_pTarget);
+ l_rc = FAPI_ATTR_GET(ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8,
+ l_pFapiTarget , l_dummyRw);
+ if(l_rc == 0)
+ {
+ TS_FAIL("Should have failed getting the attribute on "
+ "non-supporting target");
+ }
+ else if(l_rc != FAPI_RC_PLAT_ERR_SEE_DATA)
+ {
+ TS_FAIL("Should have been a platform handled error");
+ }
+ else
+ {
+ errlHndl_t l_pErrLog = static_cast<ERRORLOG::ErrlEntry*>(
+ l_rc.releasePlatData());
+ ERRORLOG::errlCommit(l_pErrLog);
+ }
+
+ TS_TRACE(EXIT_MRK "testFapiToHbMacros" );
+ }
+
};
#endif // End __TESTTARGETING_H
diff --git a/src/usr/targeting/xmltohb/hb.xml b/src/usr/targeting/xmltohb/hb.xml
new file mode 100644
index 000000000..490afd8d2
--- /dev/null
+++ b/src/usr/targeting/xmltohb/hb.xml
@@ -0,0 +1,1032 @@
+<!-- IBM_PROLOG_BEGIN_TAG
+ This is an automatically generated prolog.
+
+ $Source: src/usr/targeting/xmltohb/hb.xml $
+
+ IBM CONFIDENTIAL
+
+ COPYRIGHT International Business Machines Corp. 2011
+
+ 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 -->
+<attributes>
+
+<!-- HOST BOOT ATTRIBUTE TYPES -->
+
+<attribute>
+ <id>CLASS</id>
+ <description>Attribute indicating the target's class</description>
+ <simpleType>
+ <enumeration>
+ <description>Enumeration indicating the target's class</description>
+ <enumerator>
+ <name>NA</name>
+ <value>0</value>
+ </enumerator>
+ <enumerator>
+ <name>CARD</name>
+ <value>1</value>
+ </enumerator>
+ <enumerator>
+ <name>ENC</name>
+ <value>2</value>
+ </enumerator>
+ <enumerator>
+ <name>CHIP</name>
+ <value>3</value>
+ </enumerator>
+ <enumerator>
+ <name>UNIT</name>
+ <value>4</value>
+ </enumerator>
+ <enumerator>
+ <name>DEV</name>
+ <value>5</value>
+ </enumerator>
+ <enumerator>
+ <name>SYS</name>
+ <value>6</value>
+ </enumerator>
+ <enumerator>
+ <name>MAX</name>
+ <value>7</value>
+ </enumerator>
+ <default>NA</default>
+ </enumeration>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <hasStringConversion/>
+</attribute>
+
+<attribute>
+ <id>TYPE</id>
+ <description>Attribute indicating the target's type</description>
+ <simpleType>
+ <enumeration>
+ <description>Attribute indicating the target's type</description>
+ <enumerator>
+ <name>NA</name>
+ <value>0</value>
+ </enumerator>
+ <enumerator>
+ <name>SYS</name>
+ </enumerator>
+ <enumerator>
+ <name>NODE</name>
+ </enumerator>
+ <enumerator>
+ <name>DIMM</name>
+ </enumerator>
+ <enumerator>
+ <name>SCM</name>
+ </enumerator>
+ <enumerator>
+ <name>DCM</name>
+ </enumerator>
+ <enumerator>
+ <name>MEMBUF</name>
+ </enumerator>
+ <enumerator>
+ <name>PROC</name>
+ </enumerator>
+ <enumerator>
+ <name>MEMVRM</name>
+ </enumerator>
+ <enumerator>
+ <name>PROCVRM</name>
+ </enumerator>
+ <enumerator>
+ <name>EX</name>
+ </enumerator>
+ <enumerator>
+ <name>CORE</name>
+ </enumerator>
+ <enumerator>
+ <name>L2</name>
+ </enumerator>
+ <enumerator>
+ <name>L3</name>
+ </enumerator>
+ <enumerator>
+ <name>L4</name>
+ </enumerator>
+ <enumerator>
+ <name>MCS</name>
+ </enumerator>
+ <enumerator>
+ <name>MBS</name>
+ </enumerator>
+ <enumerator>
+ <name>MBA</name>
+ </enumerator>
+ <enumerator>
+ <name>MEM_PORT</name>
+ </enumerator>
+ <enumerator>
+ <name>PERVASIVE</name>
+ </enumerator>
+ <enumerator>
+ <name>POWERBUS</name>
+ </enumerator>
+ <enumerator>
+ <name>XBUS</name>
+ </enumerator>
+ <enumerator>
+ <name>ABUS</name>
+ </enumerator>
+ <enumerator>
+ <name>PCI</name>
+ </enumerator>
+ <enumerator>
+ <name>LAST_IN_RANGE</name>
+ </enumerator>
+ <default>NA</default>
+ </enumeration>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <hasStringConversion/>
+</attribute>
+
+<attribute>
+ <id>MODEL</id>
+ <description>Attribute indicating the target's model</description>
+ <simpleType>
+ <enumeration>
+ <description>Enumeration indicating the target's model</description>
+ <enumerator>
+ <name>NA</name>
+ <value>0</value>
+ </enumerator>
+ <enumerator>
+ <name>SALERNO</name>
+ <value>16</value>
+ </enumerator>
+ <enumerator>
+ <name>VENICE</name>
+ </enumerator>
+ <enumerator>
+ <name>CENTAUR</name>
+ <value>48</value>
+ </enumerator>
+ <enumerator>
+ <name>JEDEC</name>
+ <value>80</value>
+ </enumerator>
+ <enumerator>
+ <name>CDIMM</name>
+ </enumerator>
+ <enumerator>
+ <name>POWER8</name>
+ <value>112</value>
+ </enumerator>
+ <default>NA</default>
+ </enumeration>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <hasStringConversion/>
+</attribute>
+
+<attribute>
+ <id>ENGINE_TYPE</id>
+ <description>Attribute indicating the target's engine type</description>
+ <simpleType>
+ <enumeration>
+ <description>Enumeration indicating the target's engine type</description>
+ <enumerator>
+ <name>NA</name>
+ <value>0</value>
+ </enumerator>
+ <enumerator>
+ <name>ENGINE_IIC</name>
+ <value>1</value>
+ </enumerator>
+ <enumerator>
+ <name>ENIGNE_SCOM</name>
+ <value>2</value>
+ </enumerator>
+ <default>NA</default>
+ </enumeration>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <hasStringConversion/>
+</attribute>
+
+<attribute>
+ <id>DUMMY_RW</id>
+ <description>Dummy attribute with read/write permissions</description>
+ <simpleType>
+ <uint8_t>
+ <default>5</default>
+ </uint8_t>
+ <array>1,3,5</array>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+ <hwpfToHbAttrMap>
+ <id>ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8</id>
+ <macro>DIRECT</macro>
+ </hwpfToHbAttrMap>
+</attribute>
+
+<attribute>
+ <id>DUMMY_WO</id>
+ <description>Dummy attribute with write-only permissions</description>
+ <simpleType>
+ <uint8_t>
+ <default>0</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <writeable/>
+</attribute>
+
+<attribute>
+ <id>DUMMY_RO</id>
+ <description>Dummy attribute with read-only permissions</description>
+ <simpleType>
+ <uint8_t>
+ <default>0</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
+ <id>DUMMY_HEAP_ZERO_DEFAULT</id>
+ <description>Dummy attribute on the heap with zero initialization</description>
+ <simpleType>
+ <uint8_t>
+ <default>5</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
+ <id>PHYS_PATH</id>
+ <description>Physical hierarchical path to the target</description>
+ <nativeType>
+ <name>EntityPath</name>
+ </nativeType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
+ <id>AFFINITY_PATH</id>
+ <description>Hierarchical path to the target with respect to logical affinity</description>
+ <nativeType>
+ <name>EntityPath</name>
+ </nativeType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
+ <id>POWER_PATH</id>
+ <description>Hierarchical path to the target with respect to power</description>
+ <nativeType>
+ <name>EntityPath</name>
+ </nativeType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <description>Attribute which describes capabilities of a target</description>
+ <complexType>
+ <description>Structure which defines a target's primary capabilities.
+ A target can only support at most FSI SCOM and one of the other two SCOM
+ types. Applicable for all targets. Structure is read-only.
+ </description>
+ <field>
+ <name>supportsFsiScom</name>
+ <description>0b0: Target does not support FSI SCOM;
+ 0b1: Target supports FSI SCOM
+ </description>
+ <type>uint8_t</type>
+ <bits>1</bits>
+ <default>0</default>
+ </field>
+ <field>
+ <name>supportsXscom</name>
+ <description>0b0: Target does not support XSCOM;
+ 0b1: Target supports FSI XSCOM</description>
+ <type>uint8_t</type>
+ <bits>1</bits>
+ <default>0</default>
+ </field>
+ <field>
+ <name>supportsInbandScom</name>
+ <description>0b0: Target does not support inband SCOM</description>
+ <type>uint8_t</type>
+ <bits>1</bits>
+ <default>0</default>
+ </field>
+ <field>
+ <name>reserved</name>
+ <description>Reserved for future use</description>
+ <type>uint8_t</type>
+ <bits>5</bits>
+ <default>0</default>
+ </field>
+ </complexType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
+ <id>SCOM_SWITCHES</id>
+ <description>Attribute storing information about which SCOM path to use</description>
+ <complexType>
+ <description>Structure which defines which SCOM to use at a point in
+ time. Only applicable if target supports one or more SCOM types. Only
+ one bit (of the first three) can ever be set at any one time.
+ </description>
+ <field>
+ <name>useFsiScom</name>
+ <description>0b0: Do not use FSI SCOM at this time. 0b1: Use FSI
+ SCOM at this time</description>
+ <type>uint8_t</type>
+ <bits>1</bits>
+ <default>0</default>
+ </field>
+ <field>
+ <name>useXscom</name>
+ <description>0b0: Do not use XSCOM at this time. 0b1: Use XSCOM at
+ this time</description>
+ <type>uint8_t</type>
+ <bits>1</bits>
+ <default>0</default>
+ </field>
+ <field>
+ <name>useInbandScom</name>
+ <description>0b0: Do not use inband SCOM at this time. 0b1: Use
+ inband SCOM at this time</description>
+ <type>uint8_t</type>
+ <bits>1</bits>
+ <default>0</default>
+ </field>
+ <field>
+ <name>reserved</name>
+ <description>Reserved for future expansion</description>
+ <type>uint8_t</type>
+ <bits>5</bits>
+ <default>0</default>
+ </field>
+ </complexType>
+ <persistency>volatile</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
+ <id>XSCOM_BASE_ADDRESS</id>
+ <description>System XSCOM base address</description>
+ <simpleType>
+ <uint64_t>
+ <default>0x300000000000</default>
+ </uint64_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
+ <id>XSCOM_CHIP_INFO</id>
+ <description>Attribute which describes XSCOM chip info</description>
+ <complexType>
+ <description>Structure which defines chip info necessary for XSCOM.
+ Only applicable for chip targets which support XSCOM. Structure is
+ read-only</description>
+ <field>
+ <name>nodeId</name>
+ <description>Unique ID of node containing the chip</description>
+ <type>uint8_t</type>
+ <default>0</default>
+ </field>
+ <field>
+ <name>chipId</name>
+ <description>Unique ID of chip, relative to node</description>
+ <type>uint8_t</type>
+ <default>0</default>
+ </field>
+ </complexType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
+ <id>I2C_CHIP_INFO</id>
+ <description>Attribute which describes I2C chip info</description>
+ <complexType>
+ <description>Structure which defines info necessary for I2C. Only
+ applicable for chip targets which support I2C. Structure is
+ read-only.</description>
+ <field>
+ <name>busSpeed</name>
+ <description>Slave device bus speed</description>
+ <type>uint32_t</type>
+ <default>0</default>
+ </field>
+ <field>
+ <name>deviceAddr</name>
+ <description>Slave device address</description>
+ <type>uint32_t</type>
+ <default>0</default>
+ </field>
+ <field>
+ <name>devicePort</name>
+ <description>Slave device port location</description>
+ <type>uint32_t</type>
+ <default>0</default>
+ </field>
+ <field>
+ <name>deviceMasterEng</name>
+ <description>Master I2C engine slave is hung off of</description>
+ <type>uint32_t</type>
+ <default>0</default>
+ </field>
+ </complexType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+<!-- HOST BOOT TARGETS -->
+
+<targetType>
+ <id>base</id>
+ <attribute><id>CLASS</id></attribute>
+ <attribute><id>TYPE</id></attribute>
+ <attribute><id>MODEL</id></attribute>
+ <attribute><id>PHYS_PATH</id></attribute>
+ <attribute><id>AFFINITY_PATH</id></attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>sys-sys-power8</id>
+ <parent>base</parent>
+ <attribute><id>CLASS</id><default>SYS</default></attribute>
+ <attribute><id>TYPE</id><default>SYS</default></attribute>
+ <attribute><id>MODEL</id><default>POWER8</default></attribute>
+ <attribute><id>DUMMY_RW</id></attribute>
+ <attribute>
+ <id>XSCOM_BASE_ADDRESS</id>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>chip</id>
+ <parent>base</parent>
+ <attribute>
+ <id>CLASS</id>
+ <default>CHIP</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>chip-processor</id>
+ <parent>chip</parent>
+ <attribute>
+ <id>TYPE</id>
+ <default>PROC</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>reserved</id><value>0</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>SCOM_SWITCHES</id>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>chip-processor-salerno</id>
+ <parent>chip-processor</parent>
+ <attribute>
+ <id>MODEL</id>
+ <default>SALERNO</default>
+ </attribute>
+ <attribute>
+ <id>XSCOM_CHIP_INFO</id>
+ </attribute>
+ <attribute><id>DUMMY_RW</id></attribute>
+ <attribute><id>DUMMY_HEAP_ZERO_DEFAULT</id></attribute>
+</targetType>
+
+<targetType>
+ <id>unit</id>
+ <parent>base</parent>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>reserved</id><value>0</value></field>
+ </default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>unit-ex-salerno</id>
+ <parent>unit</parent>
+ <attribute>
+ <id>TYPE</id>
+ <default>EX</default>
+ </attribute>
+ <attribute>
+ <id>MODEL</id>
+ <default>SALERNO</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>unit-core-salerno</id>
+ <parent>unit</parent>
+ <attribute>
+ <id>TYPE</id>
+ <default>CORE</default>
+ </attribute>
+ <attribute>
+ <id>MODEL</id>
+ <default>SALERNO</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>unit-mba-salerno</id>
+ <parent>unit</parent>
+ <attribute>
+ <id>TYPE</id>
+ <default>MBA</default>
+ </attribute>
+ <attribute>
+ <id>MODEL</id>
+ <default>SALERNO</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>unit-pervasive-salerno</id>
+ <parent>unit</parent>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERVASIVE</default>
+ </attribute>
+ <attribute>
+ <id>MODEL</id>
+ <default>SALERNO</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>unit-pci-salerno</id>
+ <parent>unit</parent>
+ <attribute>
+ <id>TYPE</id>
+ <default>PCI</default>
+ </attribute>
+ <attribute>
+ <id>MODEL</id>
+ <default>SALERNO</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>unit-powerbus-salerno</id>
+ <parent>unit</parent>
+ <attribute>
+ <id>TYPE</id>
+ <default>POWERBUS</default>
+ </attribute>
+ <attribute>
+ <id>MODEL</id>
+ <default>SALERNO</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>unit-memport-salerno</id>
+ <parent>unit</parent>
+ <attribute>
+ <id>TYPE</id>
+ <default>MEM_PORT</default>
+ </attribute>
+ <attribute>
+ <id>MODEL</id>
+ <default>SALERNO</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>unit-mcs-salerno</id>
+ <parent>unit</parent>
+ <attribute>
+ <id>TYPE</id>
+ <default>MCS</default>
+ </attribute>
+ <attribute>
+ <id>MODEL</id>
+ <default>SALERNO</default>
+ </attribute>
+</targetType>
+
+<targetType>
+ <id>enc-node-power8</id>
+ <parent>base</parent>
+ <attribute>
+ <id>CLASS</id>
+ <default>ENC</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>NODE</default>
+ </attribute>
+ <attribute>
+ <id>MODEL</id>
+ <default>POWER8</default>
+ </attribute>
+</targetType>
+
+<!-- HOST BOOT TARGET INSTANCES -->
+
+<targetInstance>
+ <id>sys0</id>
+ <type>sys-sys-power8</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0</id>
+ <type>enc-node-power8</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0</id>
+ <type>chip-processor-salerno</type>
+ <attribute><id>SCOM_SWITCHES</id>
+ <default>
+ <field><id>useFsiScom</id><value>0</value></field>
+ <field><id>useXscom</id><value>1</value></field>
+ <field><id>useInbandScom</id><value>0</value></field>
+ <field><id>reserved</id><value>0</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>XSCOM_CHIP_INFO</id>
+ <default>
+ <field><id>nodeId</id><value>0</value></field>
+ <field><id>chipId</id><value>0</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0</default>
+ </attribute>
+ </targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex0</id>
+ <type>unit-ex-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex1</id>
+ <type>unit-ex-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex2</id>
+ <type>unit-ex-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-2</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-2</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex3</id>
+ <type>unit-ex-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-3</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-3</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex4</id>
+ <type>unit-ex-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-4</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-4</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex5</id>
+ <type>unit-ex-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-5</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-5</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex0core0</id>
+ <type>unit-core-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-0/core-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex1core0</id>
+ <type>unit-core-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-1/core-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex2core0</id>
+ <type>unit-core-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-2/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-2/core-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex3core0</id>
+ <type>unit-core-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-3/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-3/core-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex4core0</id>
+ <type>unit-core-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-4/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-4/core-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0ex5core0</id>
+ <type>unit-core-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/ex-5/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/ex-5/core-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0mcs0</id>
+ <type>unit-mcs-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/mcs-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/mcs-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0mcs0mba0</id>
+ <type>unit-mba-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/mcs-0/mba-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/mcs-0/mba-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0mcs0mba1</id>
+ <type>unit-mba-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/mcs-0/mba-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/mcs-0/mba-1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0mcs0mba0port0</id>
+ <type>unit-memport-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/mcs-0/mba-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/mcs-0/mba-0/mem_port-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0mcs0mba1port0</id>
+ <type>unit-memport-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/mcs-0/mba-1/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/mcs-0/mba-1/mem_port-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0pervasive0</id>
+ <type>unit-pervasive-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/pervasive-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/pervasive-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0powerbus0</id>
+ <type>unit-powerbus-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/powerbus-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/powerbus-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0pci0</id>
+ <type>unit-pci-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/pci-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/pci-0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0pci1</id>
+ <type>unit-pci-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/pci-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/pci-1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0pci2</id>
+ <type>unit-pci-salerno</type>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/pci-2</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/pci-2</default>
+ </attribute>
+</targetInstance>
+
+</attributes>
diff --git a/src/usr/targeting/xmltohb/makefile b/src/usr/targeting/xmltohb/makefile
new file mode 100644
index 000000000..f67de5f9f
--- /dev/null
+++ b/src/usr/targeting/xmltohb/makefile
@@ -0,0 +1,52 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/targeting/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2011
+#
+# p1
+#
+# Object Code Only (OCO) source materials
+# Licensed Internal Code Source Materials
+# IBM HostBoot Licensed Internal Code
+#
+# The source code for this program is not published or other-
+# wise divested of its trade secrets, irrespective of what has
+# been deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END
+
+ROOTPATH = ../../../..
+
+XMLTOHB_HEADER_TARGETS = \
+ attributeenums.H \
+ attributestrings.H \
+ attributetraits.H \
+ attributestructs.H \
+ pnortargeting.H \
+ fapiplatattrmacros.H
+
+XMLTOHB_SOURCE_TARGETS = \
+ attributestrings.C
+
+XMLTOHB_BINARY_TARGETS = \
+ targeting.bin
+
+GENFILES = \
+ ${XMLTOHB_HEADER_TARGETS} \
+ ${XMLTOHB_SOURCE_TARGETS} \
+ ${XMLTOHB_BINARY_TARGETS}
+
+# Delete any generated file on error
+.DELETE_ON_ERROR:
+
+$(addprefix %/,$(GENFILES)) : xmltohb.pl hb.xml
+ ./$< --hb-xml-file ./hb.xml --fapi-attributes-xml-file=../../hwpf/hwp/fapiHwpAttributeInfo.xml --src-output-dir=$(dir $@) --img-output-dir=$(dir $@) $(filter-out $<,$^)
+ cp -f $(dir $@)/targeting.bin $(IMGDIR)
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/targeting/xmltohb/xmltohb.pl b/src/usr/targeting/xmltohb/xmltohb.pl
new file mode 100755
index 000000000..c971aa832
--- /dev/null
+++ b/src/usr/targeting/xmltohb/xmltohb.pl
@@ -0,0 +1,2385 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/targeting/xmltohb/xmltohb.pl $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2011
+#
+# 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
+
+#
+# Purpose:
+# Author: Nick Bofferding
+# Last Updated: 09/09/2011
+#
+# Version: 1.0
+#
+# Change Log **********************************************************
+#
+# End Change Log ******************************************************
+
+use strict;
+
+################################################################################
+# Use of the following packages
+################################################################################
+
+use Getopt::Long;
+use Pod::Usage;
+use XML::Simple;
+use Text::Wrap;
+use Data::Dumper;
+use POSIX;
+
+################################################################################
+# Process command line parameters, issue help text if needed
+################################################################################
+
+sub main{ }
+my $cfgSrcOutputDir = ".";
+my $cfgImgOutputDir = ".";
+my $cfgHbXmlFile = "./hb.xml";
+my $cfgFapiAttributesXmlFile = "../../hwpf/hwp/fapiHwpAttributeInfo.xml";
+my $cfgHelp = 0;
+my $cfgMan = 0;
+my $cfgVerbose = 0;
+
+GetOptions("hb-xml-file:s" => \$cfgHbXmlFile,
+ "src-output-dir:s" => \$cfgSrcOutputDir,
+ "img-output-dir:s" => \$cfgImgOutputDir,
+ "fapi-attributes-xml-file:s" => \$cfgFapiAttributesXmlFile,
+ "help" => \$cfgHelp,
+ "man" => \$cfgMan,
+ "verbose" => \$cfgVerbose ) || pod2usage(-verbose => 0);
+
+pod2usage(-verbose => 1) if $cfgHelp;
+pod2usage(-verbose => 2) if $cfgMan;
+
+# Remove extraneous '/' from end of path names; use temporary version of $/ for
+# the chomp
+{
+ local $/ = '/';
+ chomp($cfgSrcOutputDir);
+ $cfgSrcOutputDir .= "/";
+
+ chomp($cfgImgOutputDir);
+ $cfgImgOutputDir .= "/";
+}
+
+if($cfgVerbose)
+{
+ print STDOUT "Host boot intemediate XML model = $cfgHbXmlFile\n";
+ print STDOUT "Fapi attributes XML file = $cfgFapiAttributesXmlFile\n";
+ print STDOUT "Source output dir = $cfgSrcOutputDir\n";
+ print STDOUT "Image output dir = $cfgImgOutputDir\n";
+}
+
+################################################################################
+# Initialize some globals
+################################################################################
+
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Until full machine parseable workbook parsing splits out all the input files,
+# use the intermediate representation containing the full host boot model.
+# Aborts application if file name not found.
+my $attributes = $xml->XMLin($cfgHbXmlFile, forcearray => ['attribute','hwpfToHbAttrMap']);
+my $fapiAttributes = $xml->XMLin($cfgFapiAttributesXmlFile, forcearray => ['attribute']);
+
+# Perform some sanity validation of the model (so we don't have to later)
+validateAttributes($attributes);
+validateTargetInstances($attributes);
+validateTargetTypes($attributes);
+
+# Open the output files and write them
+open(TRAIT_FILE,">$cfgSrcOutputDir"."attributetraits.H")
+ or fatal ("Trait file: \"$cfgSrcOutputDir"
+ . "attributetraits.H\" could not be opened.");
+my $traitFile = *TRAIT_FILE;
+writeTraitFileHeader($traitFile);
+writeTraitFileTraits($attributes,$traitFile);
+writeTraitFileFooter($traitFile);
+close $traitFile;
+
+open(ATTR_FILE,">$cfgSrcOutputDir"."attributeenums.H")
+ or fatal ("Attribute enum file: \"$cfgSrcOutputDir"
+ . "attributeenums.H\" could not be opened.");
+my $enumFile = *ATTR_FILE;
+writeEnumFileHeader($enumFile);
+writeEnumFileAttrIdEnum($attributes,$enumFile);
+writeEnumFileAttrEnums($attributes,$enumFile);
+writeEnumFileFooter($enumFile);
+close $enumFile;
+
+open(STRING_HEADER_FILE,">$cfgSrcOutputDir"."attributestrings.H")
+ or fatal ("Attribute string header file: \"$cfgSrcOutputDir"
+ . "attributestrings.H\" could not be opened.");
+my $stringHeaderFile = *STRING_HEADER_FILE;
+writeStringHeaderFileHeader($stringHeaderFile);
+writeStringHeaderFileStrings($attributes,$stringHeaderFile);
+writeStringHeaderFileFooter($stringHeaderFile);
+close $stringHeaderFile;
+
+open(STRING_IMPLEMENTATION_FILE,">$cfgSrcOutputDir"."attributestrings.C")
+ or fatal ("Attribute string source file: \"$cfgSrcOutputDir"
+ . "attributestrings.C\" could not be opened.");
+my $stringImplementationFile = *STRING_IMPLEMENTATION_FILE;
+writeStringImplementationFileHeader($stringImplementationFile);
+writeStringImplementationFileStrings($attributes,$stringImplementationFile);
+writeStringImplementationFileFooter($stringImplementationFile);
+close $stringImplementationFile;
+
+open(STRUCTS_HEADER_FILE,">$cfgSrcOutputDir"."attributestructs.H")
+ or fatal ("Attribute struct file: \"$cfgSrcOutputDir"
+ . "attributestructs.H\" could not be opened.");
+my $structFile = *STRUCTS_HEADER_FILE;
+writeStructFileHeader($structFile);
+writeStructFileStructs($attributes,$structFile);
+writeStructFileFooter($structFile);
+close $structFile;
+
+open(PNOR_HEADER_DEF_FILE,">$cfgSrcOutputDir"."pnortargeting.H")
+ or fatal ("Targeting header definition header file: \"$cfgSrcOutputDir"
+ . "pnortargeting.H\" could not be opened.");
+my $pnorHeaderDefFile = *PNOR_HEADER_DEF_FILE;
+writeHeaderFormatHeaderFile($pnorHeaderDefFile);
+close $pnorHeaderDefFile;
+
+open(FAPI_PLAT_ATTR_MACROS_FILE,">$cfgSrcOutputDir"."fapiplatattrmacros.H")
+ or fatal ("FAPI platform attribute macro header file: \"$cfgSrcOutputDir"
+ . "fapiplatattrmacros.H\" could not be opened.");
+my $fapiPlatAttrMacrosHeaderFile = *FAPI_PLAT_ATTR_MACROS_FILE;
+writeFapiPlatAttrMacrosHeaderFileHeader ($fapiPlatAttrMacrosHeaderFile);
+writeFapiPlatAttrMacrosHeaderFileContent($attributes,$fapiAttributes,$fapiPlatAttrMacrosHeaderFile);
+writeFapiPlatAttrMacrosHeaderFileFooter ($fapiPlatAttrMacrosHeaderFile);
+close $fapiPlatAttrMacrosHeaderFile;
+
+open(PNOR_TARGETING_FILE,">$cfgImgOutputDir"."targeting.bin")
+ or fatal ("Targeting image file: \"$cfgSrcOutputDir"
+ . "targeting.bin\" could not be opened.");
+my $pnorFile = *PNOR_TARGETING_FILE;
+writeTargetingImage($pnorFile,$attributes);
+close $pnorFile;
+
+exit(0);
+
+################################################################################
+# Report a fatal error and quit
+################################################################################
+
+sub DEBUG_FUNCTIONS { }
+sub fatal {
+ my($msg) = @_;
+
+ print STDERR "[FATAL!] $msg\n";
+
+ for(my $caller = 1; ; $caller++)
+ {
+ my ($package, $filename, $callerLine,
+ $subr, $has_args, $wantarray )= caller($caller);
+ my $line = (caller($caller-1))[2];
+ if(!$line) { last; }
+
+ print STDERR " $caller: $subr" . "(". $line . ")\n";
+ }
+
+ exit(1);
+}
+
+sub VALIDATION_FUNCTIONS { }
+
+################################################################################
+# Validates sub-elements of an element against criteria
+################################################################################
+
+sub validateSubElements {
+ my($name,$mustBeHash,$element,$criteria) = @_;
+
+ if($mustBeHash && (ref($element) ne "HASH"))
+ {
+ fatal("$name must be in the form of a hash.");
+ }
+
+ # print keys %{$element} . "\n";
+
+ for my $subElementName (keys %{$element})
+ {
+ if(!exists $criteria->{$subElementName})
+ {
+ fatal("$name element cannot have child element of type "
+ . "\"$subElementName\".");
+ }
+ }
+
+ for my $subElementName (keys %{$criteria})
+ {
+ if( ($criteria->{$subElementName}{required} == 1)
+ && (!exists $element->{$subElementName}))
+ {
+ fatal("$name element missing required child element "
+ . "\"$subElementName\".");
+ }
+
+ if(exists $element->{$subElementName}
+ && ($criteria->{$subElementName}{isscalar} == 1)
+ && (ref ($element->{$subElementName}) eq "HASH"))
+ {
+ fatal("$name element child element \"$subElementName\" should be "
+ . "scalar, but is a hash.");
+ }
+ }
+}
+
+################################################################################
+# Validates attribute element for correctness
+################################################################################
+
+sub validateAttributes {
+ my($attributes) = @_;
+
+ my %elements = ( );
+ $elements{"id"} = { required => 1, isscalar => 1};
+ $elements{"description"} = { required => 1, isscalar => 1};
+ $elements{"persistency"} = { required => 1, isscalar => 1};
+ $elements{"readable"} = { required => 0, isscalar => 0};
+ $elements{"simpleType"} = { required => 0, isscalar => 0};
+ $elements{"complexType"} = { required => 0, isscalar => 0};
+ $elements{"nativeType"} = { required => 0, isscalar => 0};
+ $elements{"writeable"} = { required => 0, isscalar => 0};
+ $elements{"hasStringConversion"}
+ = { required => 0, isscalar => 0};
+ $elements{"hwpfToHbAttrMap"}
+ = { required => 0, isscalar => 0};
+
+ foreach my $attribute (@{$attributes->{attribute}})
+ {
+ validateSubElements("attribute",1,$attribute,\%elements);
+ }
+}
+
+################################################################################
+# Validates field element for correctness
+################################################################################
+
+sub validateFieldElement {
+ my($field) = @_;
+
+ my %elements = ( );
+ $elements{"type"} = { required => 1, isscalar => 1};
+ $elements{"name"} = { required => 1, isscalar => 1};
+ $elements{"description"} = { required => 1, isscalar => 1};
+ $elements{"default"} = { required => 1, isscalar => 1};
+ $elements{"bits"} = { required => 0, isscalar => 1};
+
+ validateSubElements("field",1,$field,\%elements);
+}
+
+################################################################################
+# Validates target type elements for correctness
+################################################################################
+
+sub validateTargetTypes {
+ my($attributes) = @_;
+
+ my %elements = ( );
+ $elements{"id"} = { required => 1, isscalar => 1};
+ $elements{"parent"} = { required => 0, isscalar => 1};
+ $elements{"attribute"} = { required => 0, isscalar => 0};
+
+ foreach my $targetType (@{$attributes->{targetType}})
+ {
+ validateSubElements("targetType",1,$targetType,\%elements);
+ }
+}
+
+################################################################################
+# Validates target instance elements for correctness
+################################################################################
+
+sub validateTargetInstances{
+ my($attributes) = @_;
+
+ my %elements = ( );
+ $elements{"id"} = { required => 1, isscalar => 1};
+ $elements{"type"} = { required => 1, isscalar => 1};
+ $elements{"attribute"} = { required => 0, isscalar => 0};
+
+ foreach my $targetInstance (@{$attributes->{targetInstance}})
+ {
+ validateSubElements("targetInstance",1,$targetInstance,\%elements);
+ }
+}
+
+sub SOURCE_FILE_GENERATION_FUNCTIONS { }
+
+################################################################################
+# Writes the plat attribute macros header file header
+################################################################################
+
+sub writeFapiPlatAttrMacrosHeaderFileHeader {
+ my($outFile) = @_;
+
+ print $outFile <<VERBATIM;
+
+#ifndef FAPI_FAPIPLATATTRMACROS_H
+#define FAPI_FAPIPLATATTRMACROS_H
+
+/**
+ * \@file fapiplatattrmacros.H
+ *
+ * \@brief FAPI -> HB attribute mappings. This file is autogenerated and
+ * should not be altered.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+#include <stdint.h>
+
+//******************************************************************************
+// Macros
+//******************************************************************************
+
+namespace fapi
+{
+
+namespace platAttrSvc
+{
+VERBATIM
+}
+
+################################################################################
+# Writes the plat attribute macros
+################################################################################
+
+sub writeFapiPlatAttrMacrosHeaderFileContent {
+ my($attributes,$fapiAttributes,$outFile) = @_;
+
+ my $macroSection = "";
+ my $attrSection = "";
+
+ foreach my $attribute (@{$attributes->{attribute}})
+ {
+ foreach my $hwpfToHbAttrMap (@{$attribute->{hwpfToHbAttrMap}})
+ {
+ if( !exists $hwpfToHbAttrMap->{id}
+ || !exists $hwpfToHbAttrMap->{macro})
+ {
+ fatal("id,macro fields required\n");
+ }
+
+ my $fapiReadable = 0;
+ my $fapiWriteable = 0;
+ my $instantiated = 0;
+
+ foreach my $fapiAttr (@{$fapiAttributes->{attribute}})
+ {
+ if( (exists $fapiAttr->{id})
+ && ($fapiAttr->{id} eq $hwpfToHbAttrMap->{id})
+ && (exists $fapiAttr->{platInit}) )
+ {
+ # FAPI doesn't have a 'readable' element, so assume FAPI
+ # attribute is always readable
+ $fapiReadable = 1;
+
+ if(exists $fapiAttr->{writeable})
+ {
+ $fapiWriteable = 1;
+ }
+
+ last;
+ }
+ }
+
+ if($fapiReadable)
+ {
+ if(exists $attribute->{readable})
+ {
+ $macroSection .= ' #define ' . $hwpfToHbAttrMap->{id} .
+ "_GETMACRO(ID,PTARGET,VAL) \\\n" .
+ " FAPI_PLAT_ATTR_SVC_GETMACRO_" .
+ $hwpfToHbAttrMap->{macro} . "(ID,PTARGET,VAL)\n";
+ $instantiated = 1;
+ }
+ else
+ {
+ fatal("FAPI attribute $hwpfToHbAttrMap->{id} requires " .
+ "platform supply readable attribute.");
+ }
+ }
+
+ if($fapiWriteable)
+ {
+ if(exists $attribute->{writeable})
+ {
+ $macroSection .= ' #define ' . $hwpfToHbAttrMap->{id} .
+ "_SETMACRO(ID,PTARGET,VAL) \\\n" .
+ " FAPI_PLAT_ATTR_SVC_SETMACRO_" .
+ $hwpfToHbAttrMap->{macro} . "(ID,PTARGET,VAL)\n";
+ $instantiated = 1;
+ }
+ else
+ {
+ fatal("FAPI attribute $hwpfToHbAttrMap->{id} requires "
+ . "platform supply writeable attribute.");
+ }
+ }
+
+ if($instantiated)
+ {
+ $attrSection .= ' #define FAPI_PLAT_ATTR_SVC_MACRO_' .
+ $hwpfToHbAttrMap->{macro} . "_FAPI_" .
+ $hwpfToHbAttrMap->{id} . " \\\n" .
+ " TARGETING::ATTR_" .
+ $attribute->{id} . "\n";
+ }
+ }
+ }
+
+ print $outFile $attrSection;
+ print $outFile "\n";
+ print $outFile $macroSection;
+ print $outFile "\n";
+}
+
+################################################################################
+# Writes the plat attribute macros header file footer
+################################################################################
+
+sub writeFapiPlatAttrMacrosHeaderFileFooter {
+ my($outFile) = @_;
+
+print $outFile <<VERBATIM;
+} // End namespace platAttrSvc
+
+} // End namespace fapi
+
+#endif // FAPI_FAPIPLATATTRMACROS_H
+
+VERBATIM
+
+}
+
+################################################################################
+# Writes the pnor targeting header format file
+################################################################################
+
+sub writeHeaderFormatHeaderFile {
+ my($outFile) = @_;
+
+ print $outFile <<VERBATIM;
+
+#ifndef TARG_PNORHEADER_H
+#define TARG_PNORHEADER_H
+
+/**
+ * \@file pnorheader.H
+ *
+ * \@brief Definition for structure of targeting's PNOR image header. This
+ * file is autogenerated and should not be altered.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+#include <stdint.h>
+
+// Targeting component
+
+//******************************************************************************
+// Complex Types
+//******************************************************************************
+
+namespace TARGETING
+{
+ const uint32_t PNOR_TARG_EYE_CATCHER = 0x54415247;
+
+ enum SECTION_TYPE
+ {
+ // Targeting read-only section backed to PNOR. Always the 0th section.
+ SECTION_TYPE_PNOR_RO = 0x00,
+
+ // Targeting read-write section backed to PNOR
+ SECTION_TYPE_PNOR_RW = 0x01,
+
+ // Targeting heap section initialized out of PNOR
+ SECTION_TYPE_HEAP_PNOR_INIT = 0x02,
+
+ // Targeting heap section intialized to zero
+ SECTION_TYPE_HEAP_ZERO_INIT = 0x03,
+ };
+
+ struct TargetingSection
+ {
+ // Type of targeting section
+ const SECTION_TYPE sectionType;
+
+ // Offset of the section within the PNOR targeting image from byte zero
+ // of the targeting header
+ const uint32_t sectionOffset;
+
+ // Size of the section within the PNOR targeting image
+ const uint32_t sectionSize;
+
+ } PACKED;
+
+ struct TargetingHeader
+ {
+ // Eyecatcher to quickly verify correct population of targeting PNOR
+ // data
+ const uint32_t eyeCatcher;
+
+ // Major version of the PNOR targeting image
+ const uint16_t majorVersion;
+
+ // Minor version of the PNOR targeting image
+ const uint16_t minorVersion;
+
+ // Total size of the targeting header (from beginning of header). The
+ // PNOR RO targeting data is located immediately following the header
+ const uint32_t headerSize;
+
+ // Virtual memory offset from the virtual memory address of the previous
+ // section where the attribute resource provider must load the next
+ // section. If there is no previous section, it will represent the
+ // offset from the virtual memory base address (typically 0)
+ const uint32_t vmmSectionOffset;
+
+ // Virtual memory base address where the attribute resource provider
+ // must load the 0th (PNOR RO) section
+ void* const vmmBaseAddress;
+
+ // Size of each TargetingSection record
+ const uint32_t sizeOfSection;
+
+ // Number of TargetingSection records
+ const uint32_t numSections;
+
+ // Offset to the first TargetingSection record, from the end of this
+ // field
+ const uint32_t offsetToSections;
+
+ // Pad, in bytes, given by "offsetToSections"
+
+ // const TargetingSection sections[numSections];
+
+ } PACKED;
+
+} // End namespace TARGETING
+
+#endif // TARG_PNORHEADER_H
+
+VERBATIM
+
+}
+
+################################################################################
+# Writes the string implementation file header
+################################################################################
+
+sub writeStringImplementationFileHeader {
+ my($outFile) = @_;
+
+ print $outFile <<VERBATIM;
+
+/**
+ * \@file attributestrings.C
+ *
+ * \@brief Attribute string implementation. This file is autogenerated and
+ * should not be altered.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+#include <stdint.h>
+#include <stdlib.h>
+
+// Targeting component
+#include <targeting/attributes.H>
+
+namespace TARGETING {
+
+VERBATIM
+
+}
+
+################################################################################
+# Writes string implementation
+################################################################################
+
+sub writeStringImplementationFileStrings {
+ my($attributes,$outFile) = @_;
+
+ foreach my $attribute (@{$attributes->{attribute}})
+ {
+ if(exists $attribute->{simpleType})
+ {
+ my $simpleType = $attribute->{simpleType};
+ if(exists $simpleType->{enumeration})
+ {
+ my $enumeration = $simpleType->{enumeration};
+
+ print $outFile "//*********************************************"
+ . "*********************************\n";
+ print $outFile "// attrToString<ATTR_", $attribute->{id}, ">\n";
+ print $outFile "//*********************************************"
+ . "*********************************\n\n";
+ print $outFile "template<>\n";
+ print $outFile "const char* attrToString<ATTR_",
+ $attribute->{id},"> (\n";
+ print $outFile " AttributeTraits<ATTR_",$attribute->{id},
+ ">::Type const& i_attrValue)\n";
+ print $outFile "{\n";
+ print $outFile " switch(i_attrValue)\n";
+ print $outFile " {\n";
+
+ foreach my $enumerator (@{$enumeration->{enumerator}})
+ {
+ print $outFile " case ", $attribute->{id}, "_",
+ $enumerator->{name},":\n";
+ print $outFile " return \"",
+ $enumerator->{name},"\";\n";
+ }
+
+ print $outFile " default:\n";
+ print $outFile " return \"Cannot decode ",
+ $attribute->{id}, "\";\n";
+ print $outFile " }\n";
+ print $outFile "}\n\n";
+ }
+ }
+ }
+}
+
+################################################################################
+# Writes the string implementation file footer
+################################################################################
+
+sub writeStringImplementationFileFooter {
+ my($outFile) = @_;
+
+print $outFile <<VERBATIM;
+} // End namespace TARGETING
+
+VERBATIM
+}
+
+################################################################################
+# Writes the struct file header
+################################################################################
+
+sub writeStructFileHeader {
+ my($outFile) = @_;
+
+print $outFile <<VERBATIM;
+
+#ifndef TARG_ATTRIBUTESTRUCTS_H
+#define TARG_ATTRIBUTESTRUCTS_H
+
+/**
+ * \@file attributestructs.H
+ *
+ * \@brief Complex structures for host boot attributes. This file is
+ * autogenerated and should not be altered.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+#include <stdint.h>
+#include <stdlib.h>
+
+// Targeting component
+#include <targeting/entitypath.H>
+
+//******************************************************************************
+// Complex Types
+//******************************************************************************
+
+namespace TARGETING
+{
+
+VERBATIM
+
+}
+
+################################################################################
+# Writes struct header file structs
+################################################################################
+
+sub writeStructFileStructs {
+ my($attributes,$outFile) = @_;
+
+ foreach my $attribute (@{$attributes->{attribute}})
+ {
+ if(exists $attribute->{complexType})
+ {
+ my $complexType = $attribute->{complexType};
+ if(!exists $complexType->{description})
+ {
+ fatal("ERROR: Complex type requires a 'description'.");
+ }
+
+ print $outFile "/**\n";
+ print $outFile wrapBrief($complexType->{description});
+ print $outFile " */\n";
+
+ print $outFile "struct ",
+ calculateStructName($attribute->{id}), "\n";
+ print $outFile "{\n";
+
+ my $complex = $attribute->{complexType};
+ foreach my $field (@{$complex->{field}})
+ {
+ validateFieldElement($field);
+
+ my $bits = "";
+ if($field->{bits})
+ {
+ $bits = " : " . $field->{bits};
+ }
+
+ print $outFile wrapComment($field->{description});
+ print $outFile " ", $field->{type}, " ", $field->{name},
+ $bits, "; \n\n";
+ }
+
+ print $outFile "} PACKED;\n\n";
+ }
+ }
+}
+
+################################################################################
+# Writes the struct file footer
+################################################################################
+
+sub writeStructFileFooter {
+ my($outFile) = @_;
+
+print $outFile <<VERBATIM;
+} // End namespace TARGETING
+
+#endif // TARG_ATTRIBUTESTRUCTS_H
+
+VERBATIM
+
+}
+
+################################################################################
+# Writes the string header file header
+################################################################################
+
+sub writeStringHeaderFileHeader {
+ my($outFile) = @_;
+
+print $outFile <<VERBATIM;
+
+#ifndef TARG_ATTRIBUTESTRINGS_H
+#define TARG_ATTRIBUTESTRINGS_H
+
+/**
+ * \@file attributestrings.H
+ *
+ * \@brief Attribute string conversion routines. This file is autogenerated
+ * and should not be altered.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+#include <stdint.h>
+#include <stdlib.h>
+
+namespace TARGETING
+{
+
+/**
+ * \@brief Class used to clarify compiler error when caller attempts to
+ * stringify an unsupported attribute
+ */
+class InvalidAttributeForStringification;
+
+/**
+ * \@brief Return attribute as a string
+ *
+ * \@param[in] i_attrValue Value of the attribute
+ *
+ * \@return String which decodes the attribute value
+ */
+template<const ATTRIBUTE_ID A>
+const char* attrToString(
+ typename AttributeTraits<A>::Type const& i_attrValue)
+{
+ // Default behavior is to fail the compile if caller attempt to print an
+ // unsupported string
+ return InvalidAttributeForStringification();
+}
+
+VERBATIM
+
+}
+
+################################################################################
+# Writes string interfaces
+################################################################################
+
+sub writeStringHeaderFileStrings {
+ my($attributes,$outFile) = @_;
+
+ foreach my $attribute (@{$attributes->{attribute}})
+ {
+ if(exists $attribute->{simpleType})
+ {
+ my $simpleType = $attribute->{simpleType};
+ if(exists $simpleType->{enumeration})
+ {
+ my $enumeration = $simpleType->{enumeration};
+ print $outFile "/**\n";
+ print $outFile " * \@brief See "
+ . "attrToString<const ATTRIBUTE_ID A>\n";
+ print $outFile " */\n";
+ print $outFile "template<>\n";
+ print $outFile "const char* attrToString<ATTR_",
+ $attribute->{id},">(\n";
+ print $outFile " AttributeTraits<ATTR_",$attribute->{id},
+ ">::Type const& i_attrValue);\n";
+ print $outFile "\n";
+ }
+ }
+ }
+}
+
+################################################################################
+# Writes the string header file footer
+################################################################################
+
+sub writeStringHeaderFileFooter {
+ my($outFile) = @_;
+
+print $outFile <<VERBATIM;
+
+} // End namespace TARGETING
+
+#endif // TARG_ATTRIBUTESTRINGS_H
+
+VERBATIM
+}
+
+################################################################################
+# Writes the enum file header
+################################################################################
+
+sub writeEnumFileHeader {
+ my($outFile) = @_;
+
+print $outFile <<VERBATIM;
+
+#ifndef TARG_ATTRIBUTEENUMS_H
+#define TARG_ATTRIBUTEENUMS_H
+
+/**
+ * \@file attributeenums.H
+ *
+ * \@brief Defined enums for platform attributes
+ *
+ * This header file contains enumerations for supported platform attributes
+ * (as opposed to HWPF attributes). This file is automatically
+ * generated and should not be altered.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+#include <stdint.h>
+#include <stdlib.h>
+
+//******************************************************************************
+// Enumerations
+//******************************************************************************
+
+namespace TARGETING
+{
+
+VERBATIM
+
+}
+
+################################################################################
+# Writes the enum file attribute enumeration
+################################################################################
+
+sub writeEnumFileAttrIdEnum {
+ my($attributes,$outFile) = @_;
+
+ print $outFile <<VERBATIM;
+/**
+ * \@brief Platform attribute IDs
+ *
+ * Enumeration defining every possible platform attribute that can be
+ * associated with a target. This file is autogenerated and should not be
+ * altered.
+ */
+enum ATTRIBUTE_ID
+{
+VERBATIM
+
+ my $attrId;
+ my $hexVal;
+
+ format ATTRENUMFORMAT =
+ ATTR_@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< = @<<<<<<<<<<
+ $attrId $hexVal .","
+.
+ select($outFile);
+ $~ = 'ATTRENUMFORMAT';
+
+ my $attributeIdEnumeration = getAttributeIdEnumeration($attributes);
+ foreach my $enumerator (@{$attributeIdEnumeration->{enumerator}})
+ {
+ $hexVal = sprintf "0x%08X", $enumerator->{value};
+ $attrId = $enumerator->{name};
+ write;
+ }
+
+ print $outFile "};\n\n";
+}
+
+################################################################################
+# Writes other enumerations to enumeration file
+################################################################################
+
+sub writeEnumFileAttrEnums {
+ my($attributes,$outFile) = @_;
+
+ my $enumName = "";
+ my $enumHex = "";
+
+ format ENUMFORMAT =
+ @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< = @<<<<<<<<<<
+ $enumName $enumHex .","
+.
+ select($outFile);
+ $~ = 'ENUMFORMAT';
+
+ foreach my $attribute (@{$attributes->{attribute}})
+ {
+ if(exists $attribute->{simpleType})
+ {
+ my $simpleType = $attribute->{simpleType};
+ if(exists $simpleType->{enumeration})
+ {
+ my $enumeration = $simpleType->{enumeration};
+ print $outFile "/**\n";
+ print $outFile wrapBrief( $enumeration->{description} );
+ print $outFile " */\n";
+ print $outFile "enum ", $attribute->{id}, "\n";
+ print $outFile "{\n";
+
+ foreach my $enumerator (@{$enumeration->{enumerator}})
+ {
+ $enumHex = sprintf "0x%08X",
+ enumNameToValue($enumeration,$enumerator->{name});
+ $enumName = $attribute->{id} . "_" . $enumerator->{name};
+ write;
+ }
+
+ print $outFile "};\n\n";
+ }
+ }
+ }
+}
+
+################################################################################
+# Writes the enum file footer
+################################################################################
+
+sub writeEnumFileFooter {
+ my($outFile) = @_;
+
+print $outFile <<VERBATIM;
+} // End namespace TARGETING
+
+#endif // TARG_ATTRIBUTEENUMS_H
+
+VERBATIM
+}
+
+################################################################################
+# Writes the trait file header
+################################################################################
+
+sub writeTraitFileHeader {
+ my($outFile) = @_;
+
+print $outFile <<VERBATIM;
+
+#ifndef TARG_ATTRIBUTETRAITS_H
+#define TARG_ATTRIBUTETRAITS_H
+
+/**
+ * \@file attributetraits.H
+ *
+ * \@brief Templates which map attributes to their type/properties
+ *
+ * This header file contains templates which map attributes to their
+ * type/properties. This file is autogenerated and should not be altered.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// STD
+#include <stdint.h>
+#include <stdlib.h>
+
+namespace TARGETING
+{
+
+//******************************************************************************
+// Attribute Property Mappings
+//******************************************************************************
+
+/**
+ * \@brief Template associating a specific attribute with a type and other
+ * properties, such as whether it is readable/writable
+ *
+ * This is automatically generated
+ *
+ * enum {
+ * disabled = Special value for the basic, unused wildcard attribute
+ * readable = Attribute is readable
+ * writable = Attribute is writable
+ * hasStringConversion = Attribute has debug string conversion
+ * }
+ *
+ * typedef <type> TYPE // <type> is the Attribute's valid type
+ */
+template<const ATTRIBUTE_ID A>
+class AttributeTraits
+{
+ private:
+ enum { disabled };
+ typedef void* Type;
+};
+
+VERBATIM
+
+}
+
+################################################################################
+# Writes computed traits to trait file
+################################################################################
+
+sub writeTraitFileTraits {
+ my($attributes,$outFile) = @_;
+
+ my $typedefs = "";
+
+ foreach my $attribute (@{$attributes->{attribute}})
+ {
+ # Build boolean traits
+
+ my $traits = "";
+ foreach my $trait ("writeable","readable","hasStringConversion")
+ {
+ if(exists $attribute->{$trait})
+ {
+ $traits .= " $trait,";
+ }
+ }
+ chop($traits);
+
+ # Build value type
+
+ my $type = "";
+ my $dimensions = "";
+ if(exists $attribute->{simpleType})
+ {
+ my $simpleType = $attribute->{simpleType};
+ my $simpleTypeProperties = simpleTypeProperties();
+ for my $typeName (keys %{$simpleType})
+ {
+ if(exists $simpleTypeProperties->{$typeName})
+ {
+ if( $simpleTypeProperties->{$typeName}{typeName}
+ eq "XMLTOHB_USE_PARENT_ATTR_ID")
+ {
+ $type = $attribute->{id};
+ }
+ else
+ {
+ $type = $simpleTypeProperties->{$typeName}{typeName};
+ }
+
+ if( (exists $simpleType->{array})
+ && ($simpleTypeProperties->{$typeName}{supportsArray}) )
+ {
+ my @bounds = split(/,/,$simpleType->{array});
+ foreach my $bound (@bounds)
+ {
+ $dimensions .= "[$bound]";
+ }
+ }
+ last;
+ }
+ }
+
+ if($type eq "")
+ {
+ fatal("Unsupported simpleType child element for "
+ . "attribute $attribute->{id}. Keys are ("
+ . join(',',keys %{$simpleType}) . ")");
+ }
+ }
+ elsif(exists $attribute->{nativeType})
+ {
+ $type = $attribute->{nativeType}->{name};
+ }
+ elsif(exists $attribute->{complexType})
+ {
+ $type = calculateStructName($attribute->{id});
+ }
+ else
+ {
+ fatal("Could not determine attribute data type for attribute "
+ . "$attribute->{id}.");
+ }
+
+ # Add traits definition to output
+
+ print $outFile "template<>\n";
+ print $outFile "class AttributeTraits<ATTR_",$attribute->{id},">\n";
+ print $outFile "{\n";
+ print $outFile " public:\n";
+ print $outFile " enum {",$traits," };\n";
+ print $outFile " typedef ", $type, " Type$dimensions;\n";
+ print $outFile "};\n\n";
+
+ $typedefs .= "typedef " . $type .
+ " $attribute->{id}" . "_ATTR" . $dimensions . ";\n";
+ };
+
+ print $outFile "/**\n";
+ print $outFile wrapBrief("Mapping of alias type name to underlying type");
+ print $outFile " */\n";
+ print $outFile $typedefs ."\n";
+}
+
+################################################################################
+# Writes the trait file footer
+################################################################################
+
+sub writeTraitFileFooter {
+ my($outFile) = @_;
+
+ print $outFile <<VERBATIM;
+} // End namespace TARGETING
+
+#endif // TARG_ATTRIBUTETRAITS_H
+
+VERBATIM
+}
+
+sub UTILITY_FUNCTIONS { }
+
+################################################################################
+# Get generated enumeration describing attribute IDs
+################################################################################
+
+sub getAttributeIdEnumeration {
+ my($attributes) = @_;
+
+ my $attributeValue = 0;
+ my $enumeration = { } ;
+ $enumeration->{description} = "Internal enum for attribute IDs\n";
+ $enumeration->{default} = "NA";
+ $enumeration->{enumerator}->[0]->{name} = "NA";
+ $enumeration->{enumerator}->[0]->{value} = 0;
+
+ foreach my $attribute (@{$attributes->{attribute}})
+ {
+ $attributeValue++;
+ $enumeration->{enumerator}->[$attributeValue]->{name}
+ = $attribute->{id};
+ $enumeration->{enumerator}->[$attributeValue]->{value}
+ = sprintf "%u",$attributeValue;
+ }
+
+ return $enumeration;
+}
+
+################################################################################
+# If value is hex, convert to regular number
+###############################################################################
+
+sub unhexify {
+ my($val) = @_;
+ if($val =~ m/^0[xX][0123456790A-Fa-f]+$/)
+ {
+ $val = hex($val);
+ }
+ return $val;
+}
+
+################################################################################
+# Pack uint64_t into a buffer in big-endian format
+################################################################################
+
+sub packQuad{
+ my($quad) = @_;
+
+ unhexify($quad);
+
+ return pack("NN" , $quad >> 32, $quad);
+}
+
+################################################################################
+# Get space required to store an enum, based on the max value
+################################################################################
+
+sub enumSpace {
+ my($maxEnumVal) = @_;
+ if($maxEnumVal == 0)
+ {
+ # Enum needs at least one byte
+ $maxEnumVal++;
+ }
+ my $space = ceil(log($maxEnumVal+1) / (8 * log(2)));
+ return $space;
+}
+
+################################################################################
+# Get mininum # of bytes, in block size chunks, able to contain the input data
+################################################################################
+
+sub sizeBlockAligned {
+ my ($size,$blockSize,$oneBlockMinimum) = @_;
+
+ if( (!defined $size)
+ || (!defined $blockSize)
+ || (!defined $oneBlockMinimum) )
+ {
+ fatal("Caller must specify 'size', 'blockSize', 'oneBlockMinimum' "
+ . "args.");
+ }
+
+ if(!$blockSize)
+ {
+ fatal("'blockSize' arg must be > 0.");
+ }
+
+ if(($size % $blockSize) || (($size==0) && $oneBlockMinimum) )
+ {
+ $size += ($blockSize - ($size % $blockSize));
+ }
+
+ return $size;
+}
+
+################################################################################
+# Optimize white space for C++/doxygen documentation
+################################################################################
+
+sub optWhiteSpace {
+ my($text) = @_;
+
+ # Remove leading, trailing white space, then collapse excess internal
+ # whitespace
+ $text =~ s/^\s+|\s+$//g;
+ $text =~ s/\s+/ /g;
+
+ return $text;
+}
+
+################################################################################
+# Wrap text into a C++/doxygen brief description
+################################################################################
+
+sub wrapBrief {
+ my($text) = @_;
+
+ my $brief_start = " * \@brief ";
+ my $brief_continue = " * ";
+
+ return wrap($brief_start,$brief_continue, optWhiteSpace($text))."\n";
+}
+
+################################################################################
+# Wrap text into a C++ style comment
+################################################################################
+
+sub wrapComment {
+ my($text) = @_;
+
+ my $comment_start = " // ";
+ my $comment_continue = " // ";
+
+ return wrap($comment_start,$comment_continue,optWhiteSpace($text))."\n";
+}
+
+################################################################################
+# Calculate struct type name for a header file, based on its ID
+################################################################################
+
+sub calculateStructName {
+ my($id) = @_;
+
+ my $type = "";
+
+ # Struct name is original ID with underscores removed and first letter of
+ # each word capitalized
+ my @words = split(/_/,$id);
+ foreach my $word (@words)
+ {
+ $type .= ucfirst( lc($word) );
+ }
+
+ return $type;
+}
+
+################################################################################
+# Return array containing only distinct target types that are actally in use
+################################################################################
+
+sub getInstantiatedTargetTypes {
+ my($attributes) = @_;
+
+ my %seen = ();
+ my @uniqueTargetTypes = ();
+
+ foreach my $targetInstance (@{$attributes->{targetInstance}})
+ {
+ push (@uniqueTargetTypes, $targetInstance->{type})
+ unless $seen{$targetInstance->{type}}++;
+ }
+
+ return @uniqueTargetTypes;
+}
+
+################################################################################
+# Get hash ref to supported simple types and their properties
+################################################################################
+
+sub simpleTypeProperties {
+
+ my %typesHoH = ();
+
+ # Intentionally didn't wrap these to 80 columns to keep them lined up and
+ # more readable/editable
+ $typesHoH{"uint8_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint8_t" , bytes => 1, bits => 8 , packfmt => "C" };
+ $typesHoH{"uint16_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint16t" , bytes => 2, bits => 16, packfmt => "S" };
+ $typesHoH{"uint32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint32_t" , bytes => 4, bits => 32, packfmt => "L" };
+ $typesHoH{"uint64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint64_t" , bytes => 8, bits => 64, packfmt =>\&packQuad };
+ $typesHoH{"enumeration"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "XMLTOHB_USE_PARENT_ATTR_ID" , bytes => 0, bits => 0 , packfmt => "packEnumeration" };
+
+ return \%typesHoH;
+}
+
+################################################################################
+# Get attribute default
+################################################################################
+
+sub getAttributeDefault {
+ my($attributeId,$attributes) = @_;
+
+ my $default = "";
+ my $simpleTypeProperties = simpleTypeProperties();
+
+ foreach my $attribute (@{$attributes->{attribute}})
+ {
+ if ($attribute->{id} eq $attributeId)
+ {
+ if(exists $attribute->{simpleType})
+ {
+ for my $type (keys %{$simpleTypeProperties})
+ {
+ # Note: must check for 'type' before 'default', otherwise
+ # might add value to the hash
+ if( exists $attribute->{simpleType}->{$type}
+ && exists $attribute->{simpleType}->{$type}->{default})
+ {
+ $default = $attribute->{simpleType}->{$type}->{default};
+ last;
+ }
+ }
+ }
+ elsif(exists $attribute->{complexType})
+ {
+ my $cplxDefault = { } ;
+ my $i = 0;
+ foreach my $field (@{$attribute->{complexType}->{field}})
+ {
+ $cplxDefault->{field}->[$i]->{id} = $field->{name};
+ $cplxDefault->{field}->[$i]->{value} = $field->{default};
+ $i++;
+ }
+ return $cplxDefault;
+ }
+ elsif(exists $attribute->{nativeType})
+ {
+ if( exists $attribute->{nativeType}->{name}
+ && ($attribute->{nativeType}->{name} eq "EntityPath"))
+ {
+ $default = "MustBeOverriddenByTargetInstance";
+ }
+ else
+ {
+ fatal("Cannot provide default for unsupported nativeType.");
+ }
+ }
+ else
+ {
+ fatal("Unrecognized value type.");
+ }
+
+ last;
+ }
+ }
+
+ return $default;
+}
+
+################################################################################
+# Get target attributes
+################################################################################
+
+sub getTargetAttributes {
+ my($type,$attributes,$attrhasha) = @_;
+
+ foreach my $targetType (@{$attributes->{targetType}})
+ {
+ if($targetType->{id} eq $type)
+ {
+ if(exists $targetType->{parent})
+ {
+ getTargetAttributes($targetType->{parent},
+ $attributes,$attrhasha);
+ }
+
+ foreach my $attr (@{$targetType->{attribute}})
+ {
+ $attrhasha->{ $attr->{id} } = $attr;
+
+ if(!exists $attrhasha->{ $attr->{id}}->{default})
+ {
+ my $default = getAttributeDefault($attr->{id},$attributes);
+ $attrhasha->{ $attr->{id}}->{default} = $default;
+ }
+ }
+
+ last;
+ }
+ }
+}
+
+################################################################################
+# Compute maximum enumerator value for a given enumeration
+################################################################################
+
+sub maxEnumValue {
+ my($enumeration) = @_;
+
+ my $max = 0;
+ my $candidateMax = 0;
+ foreach my $enumerator (@{$enumeration->{enumerator}})
+ {
+ my $candidateMax = unhexify(enumNameToValue(
+ $enumeration,$enumerator->{name}));
+ if($candidateMax > $max)
+ {
+ $max = $candidateMax;
+ }
+ }
+
+ return $max;
+}
+
+################################################################################
+# Serialize an enumeration to data buffer
+################################################################################
+
+sub packEnumeration {
+ my($enumeration,$value) = @_;
+
+ my $binaryData;
+
+ # Determine space required for max enum
+ my $bytes = enumSpace( maxEnumValue($enumeration) );
+
+ $value = unhexify($value);
+
+ # Encode the value
+ for (my $count=$bytes-1; $count >= 0; $count--)
+ {
+ $binaryData .= pack("C", (0xFF & ($value >> (8*$count))) );
+ }
+
+ if( (length $binaryData) < 1)
+ {
+ fatal("Failed to write binary data for enumeration.");
+ }
+
+ #print " Enum description: ", $enumeration->{description}, "\n";
+ #print "Enum storage space required: ", $bytes, "\n";
+ #print " Value encoded: ", $value, "\n";
+ #print " Final length of encode: ", (length $binaryData), "\n";
+
+ return $binaryData;
+}
+
+################################################################################
+# Convert enumerator name into equivalent enumerator value for given enumeration
+################################################################################
+
+sub enumNameToValue {
+ my ($enumeration,$enumeratorName) = @_;
+
+ my $nextEnumeratorValue = 0;
+ my $found = 0;
+ my $enumeratorValue;
+
+ foreach my $enumerator (@{$enumeration->{enumerator}})
+ {
+ my $currentEnumeratorValue;
+ if(exists $enumerator->{value} )
+ {
+ $nextEnumeratorValue = unhexify($enumerator->{value}) + 1;
+ $currentEnumeratorValue = unhexify($enumerator->{value});
+ }
+ else
+ {
+ $currentEnumeratorValue = $nextEnumeratorValue;
+ $nextEnumeratorValue += 1;
+ }
+
+ if($enumerator->{name} eq $enumeratorName)
+ {
+ $found = 1;
+ $enumeratorValue = $currentEnumeratorValue;
+ last;
+ }
+ }
+
+ if(!$found)
+ {
+ fatal("Could not convert enumerator name \"$enumeratorName\"into "
+ . "enumerator value.");
+ }
+
+ return $enumeratorValue;
+}
+
+################################################################################
+# Object which accumulates/flushes bit field data
+################################################################################
+
+{
+
+package Accumulator;
+
+################################################################################
+# Constructor; create a new Accumulator object
+################################################################################
+
+sub new {
+ my ($class) = @_;
+ my $self = { _currentType => "", _accumulator => "", _bits => 0 };
+
+ bless $self, $class;
+ return $self;
+}
+
+################################################################################
+# Accumulate a new bit field
+################################################################################
+
+sub accumulate {
+ my($self,$type,$bits,$value) = @_;
+
+ my $binaryData;
+ my $simpleTypeProperties = main::simpleTypeProperties();
+
+ if($bits > $simpleTypeProperties->{$type}{bits})
+ {
+ main::fatal("Too many bits ($bits) for type ($type).");
+ }
+
+ if($self->{_currentType} eq "")
+ {
+ $self->{_currentType} = $type;
+ $self->{_bits} = $bits;
+ }
+ elsif($self->{_currentType} eq $type)
+ {
+ if($self->{_bits} + $bits >
+ $simpleTypeProperties->{$self->{_currentType}}{bits})
+ {
+ $binaryData = $self->releaseAndClear();
+ $self->{_currentType} = $type;
+ $self->{_bits} = $bits;
+ }
+ else
+ {
+ $self->{_bits} += $bits;
+ }
+ }
+ else
+ {
+ $binaryData = $self->releaseAndClear();
+ $self->{_currentType} = $type;
+ $self->{_bits} = $bits;
+ }
+
+ for(my $count = 0; $count < $bits; $count++)
+ {
+ if( 1 & ($value >> $bits - $count - 1))
+ {
+ $self->{_accumulator} .= "1";
+ }
+ else
+ {
+ $self->{_accumulator} .= "0";
+ }
+ }
+
+ return $binaryData;
+}
+
+################################################################################
+# Release the accumulator (if non-empty) to the caller and clear
+################################################################################
+
+sub releaseAndClear {
+ my($self) = @_;
+
+ my $binaryData;
+
+ if($self->{_currentType} ne "")
+ {
+ my $simpleTypeProperties = main::simpleTypeProperties();
+
+ $binaryData = pack
+ ("B$simpleTypeProperties->{$self->{_currentType}}{bits}",
+ $self->{_accumulator});
+
+ $self->{_accumulator} = "";
+ $self->{_currentType} = "";
+ $self->{_bits} = 0;
+ }
+
+ return $binaryData;
+}
+
+1;
+
+}
+
+################################################################################
+# Pack a complex type into a binary data stream
+################################################################################
+
+sub packComplexType {
+ my ($complexType,$attributeDefault) = @_;
+
+ my $binaryData;
+ my $simpleTypeProperties = simpleTypeProperties();
+
+ my $accumulator = new Accumulator();
+
+ # Build using each field
+ foreach my $field (@{$complexType->{field}})
+ {
+ # print STDERR "Field = ", $field->{name}, "\n";
+ # print STDERR "Default = ", $field->{default}, "\n";
+ # print STDERR "Bits = ", $field->{bits}, "\n";
+ # print STDERR "Type = ", $field->{type}, "\n";
+
+ my $found = 0;
+ foreach my $default (@{$attributeDefault->{field}})
+ {
+ if($default->{id} eq $field->{name})
+ {
+ $found = 1;
+ if(exists $field->{bits})
+ {
+ $binaryData .= $accumulator->accumulate(
+ $field->{type},unhexify($field->{bits}),
+ unhexify($default->{value}));
+ }
+ # If non-bitfield
+ else
+ {
+ $binaryData .= $accumulator->releaseAndClear();
+
+ # Pack easy types using 'pack', otherwise invoke appropriate
+ # (possibly workaround) callback function
+ if(exists $simpleTypeProperties->{$field->{type}}
+ && $simpleTypeProperties->{$field->{type}}
+ {complexTypeSupport})
+ {
+ my $defaultValue = $default->{value};
+ if($simpleTypeProperties->{$field->{type}}{canBeHex})
+ {
+ $defaultValue = unhexify($defaultValue);
+ }
+
+ if(ref ($simpleTypeProperties->{$field->{type}}
+ {packfmt}) eq "CODE")
+ {
+ $binaryData .=
+ $simpleTypeProperties->{$field->{type}}
+ {packfmt}->($defaultValue);
+ }
+ else
+ {
+ $binaryData .= pack(
+ $simpleTypeProperties->{$field->{type}}
+ {packfmt},$defaultValue);
+ }
+ }
+ else
+ {
+ fatal("Field type $field->{type} not supported in "
+ . "complex type.");
+ }
+ }
+
+ last;
+ }
+ }
+
+ if(!$found)
+ {
+ fatal("Could not find value for field.");
+ }
+ }
+
+ $binaryData .= $accumulator->releaseAndClear();
+
+ return $binaryData;
+}
+
+################################################################################
+# Pack an attribute into a binary data stream
+################################################################################
+
+sub packAttribute {
+ my($attributes,$attribute,$value) = @_;
+
+ my $binaryData;
+
+ if(exists $attribute->{simpleType})
+ {
+ my $simpleType = $attribute->{simpleType};
+ my $simpleTypeProperties = simpleTypeProperties();
+
+ for my $typeName (keys %{$simpleType})
+ {
+ if(exists $simpleTypeProperties->{$typeName})
+ {
+ if($typeName eq "enumeration")
+ {
+ my $enumeration = $simpleType->{enumeration};
+
+ # Here $value is the enumerator name
+ my $enumeratorValue = enumNameToValue($enumeration,$value);
+ $binaryData = packEnumeration($enumeration,$enumeratorValue);
+ }
+ else
+ {
+ if($simpleTypeProperties->{$typeName}{canBeHex})
+ {
+ $value = unhexify($value);
+ }
+
+ if(ref ($simpleTypeProperties->{$typeName}{packfmt}) eq "CODE")
+ {
+ $binaryData .=
+ $simpleTypeProperties->{$typeName}{packfmt}->($value);
+ }
+ else
+ {
+ $binaryData .=
+ pack($simpleTypeProperties->{$typeName}{packfmt},
+ $value);
+ }
+ }
+
+ my $arrayMultiplier = 1;
+ if( ($simpleTypeProperties->{$typeName}{supportsArray})
+ && (exists $simpleType->{array}) )
+ {
+ my @bounds = split(/,/,$simpleType->{array});
+ foreach my $bound (@bounds)
+ {
+ $arrayMultiplier *= $bound;
+ }
+
+ my $tmpBinaryData = $binaryData;
+ for( my $i = 1; $i < $arrayMultiplier; ++$i)
+ {
+ $binaryData .= $tmpBinaryData;
+ }
+ }
+
+ last;
+ }
+ }
+
+ if( (length $binaryData) < 1)
+ {
+ fatal("Error requested simple type not supported. Keys are ("
+ . join(',',keys %{$simpleType}) . ")");
+ }
+ }
+ elsif(exists $attribute->{complexType})
+ {
+ if(ref ($value) eq "HASH" )
+ {
+ $binaryData = packComplexType($attribute->{complexType},$value);
+ }
+ else
+ {
+ fatal("Warning cannot serialize non-hash complex type.");
+ }
+ }
+ elsif(exists $attribute->{nativeType})
+ {
+ if($attribute->{nativeType}->{name} eq "EntityPath")
+ {
+ my $maxPathElements = 8;
+ my ($typeStr,$path) = split(/:/,$value);
+ my (@paths) = split(/\//,$path);
+
+ my $type = 0;
+ if($typeStr eq "physical")
+ {
+ $type = 2;
+ }
+ elsif($typeStr eq "affinity")
+ {
+ $type = 1;
+ }
+ else
+ {
+ fatal("Unsupported enity path type.");
+ }
+
+ if( (scalar @paths) > $maxPathElements)
+ {
+ fatal("Path elements cannot be greater than $maxPathElements.");
+ }
+
+ $binaryData .= pack("C", (0xF0 & ($type << 4)) +
+ (0x0F & (scalar @paths)));
+
+ foreach my $pathElement (@paths)
+ {
+ my ($pathType,$pathInstance) = split(/-/,$pathElement);
+ $pathType = uc($pathType);
+
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+ if($attr->{id} eq "TYPE")
+ {
+ $pathType =
+ enumNameToValue(
+ $attr->{simpleType}->{enumeration},$pathType);
+ $binaryData .= pack ("CC", $pathType, $pathInstance);
+ last;
+ }
+ }
+ }
+
+ if($maxPathElements > (scalar @paths))
+ {
+ $binaryData .= pack("C".(($maxPathElements - scalar @paths)*2));
+ }
+ }
+ else
+ {
+ fatal("Error nativeType not supported on attribute ID = "
+ . "$attribute->{id}.");
+ }
+ }
+ else
+ {
+ fatal("Unsupported attribute type on attribute ID = $attribute->{id}.");
+ }
+
+ if( (length $binaryData) < 1)
+ {
+ fatal("Serialization failed for attribute ID = $attribute->{id}.");
+ }
+
+ return $binaryData;
+}
+
+################################################################################
+# Write the PNOR targeting image
+################################################################################
+
+sub writeTargetingImage {
+ my($outFile, $attributes) = @_;
+
+ # 128 MB virtual memory offset between sections
+ #@TODO Need the final value after full host boot support is implemented.
+ # For now assume 4k since we're mapping directly to physical targeting image
+ my $vmmSectionOffset = 4 * 1024;
+
+ # Virtual memory addresses corresponding to the start of the targeting image
+ # PNOR/heap sections
+ #@TODO Need the final value of the base address after full host boot support
+ # is implemented.
+ my $pnorRoBaseAddress = 0x8007E690;
+ my $pnorRwBaseAddress = $pnorRoBaseAddress + $vmmSectionOffset;
+ my $heapPnorInitBaseAddr = $pnorRwBaseAddress + $vmmSectionOffset;
+ my $heapZeroInitBaseAddr = $heapPnorInitBaseAddr + $vmmSectionOffset;
+
+ # Reserve 256 bytes for the header, then keep track of PNOR RO offset
+ my $headerSize = 256;
+ my $offset = $headerSize;
+
+ # Reserve space for the pointer to the # of targets, update later;
+ my $numTargetsPointer = 0;
+ my $numTargetsPointerBinData = packQuad($numTargetsPointer);
+ $offset += (length $numTargetsPointerBinData);
+
+ ############################################################################
+ # Build the attribute list for each unique CTM
+ ############################################################################
+
+ # Get an array of only the unique types of targets actually used by the
+ # aggregation of target instances.
+ my @targetTypes = getInstantiatedTargetTypes($attributes);
+
+ my $attributeIdEnumeration = getAttributeIdEnumeration($attributes);
+
+ my %attributeListTypeHoH = ();
+ my $attributeListBinData;
+
+ # For each unique type of target modeled, create the attribute list
+ foreach my $targetType (@targetTypes)
+ {
+ # Create the attribute list associated with each target type
+ #@TODO Eventually we'll need criteria to order the attributes
+ # for code update
+ my %attrhash = ();
+ getTargetAttributes($targetType, $attributes,\%attrhash);
+
+ # Serialize per target type attribute list
+ my $perTargetTypeAttrBinData;
+ for my $attributeId (keys %attrhash)
+ {
+ $perTargetTypeAttrBinData .= packEnumeration(
+ $attributeIdEnumeration,
+ enumNameToValue($attributeIdEnumeration,$attributeId));
+ }
+
+ # Save offset of the attribute list, tied to the type
+ $attributeListTypeHoH{$targetType}{offset} = $offset;
+ $attributeListTypeHoH{$targetType}{elements} = scalar keys %attrhash;
+ $attributeListTypeHoH{$targetType}{size} =
+ (length $perTargetTypeAttrBinData);
+
+ #print "Target type: $targetType\n";
+ #print " elements: $attributeListTypeHoH{$targetType}{elements}\n";
+ #print " offset: $attributeListTypeHoH{$targetType}{offset}\n";
+ #print " size: $attributeListTypeHoH{$targetType}{size}\n";
+
+ # Append attribute data for this part to the attribute list subsection
+ $attributeListBinData .= $perTargetTypeAttrBinData;
+
+ # Increment the offset
+ $offset += (length $perTargetTypeAttrBinData);
+ }
+
+ # For each target instance ...
+
+ #@TODO Eventually we'll need criteria to order the attributes
+ # for code update. At minimum, ensure that we always process at this level
+ # in the given order
+ my @targetsAoH = ();
+ my $numTargets = 0;
+ foreach my $targetInstance (@{$attributes->{targetInstance}})
+ {
+ push(@targetsAoH, $targetInstance);
+ $numTargets++;
+ }
+
+ my $numAttributes = 0;
+ foreach my $targetInstance (@targetsAoH)
+ {
+ my %attrhash = ();
+ getTargetAttributes($targetInstance->{type}, $attributes,\%attrhash);
+ $numAttributes += keys %attrhash;
+ }
+
+ # Reserve # pointers * sizeof(pointer)
+ my $startOfAttributePointers = $offset;
+ print "Total attributes = $numAttributes\n";
+ $offset += ($numAttributes * (length packQuad(0) ));
+
+ # Now we can determine the pointer to the number of targets
+ # Don't increment the offset; already accounted for
+ $numTargetsPointer = $pnorRoBaseAddress + $offset;
+ $numTargetsPointerBinData = packQuad($numTargetsPointer);
+
+ my $numTargetsBinData = pack("N",$numTargets);
+ $offset += (length $numTargetsBinData);
+
+ my $roAttrBinData;
+ my $heapZeroInitOffset = 0;
+ my $heapZeroInitBinData;
+ my $heapPnorInitOffset = 0;
+ my $heapPnorInitBinData;
+ my $rwAttrBinData;
+ my $rwOffset = 0;
+ my $attributePointerBinData;
+ my $targetsBinData;
+
+ # Ensure consistent ordering of target instances
+ my $attrAddr = $pnorRoBaseAddress + $startOfAttributePointers;
+
+ foreach my $targetInstance (@targetsAoH)
+ {
+ my $data;
+
+ # print "TargetInstance: $targetInstance->{id}\n";
+ # print " Attributes: ",
+ # $attributeListTypeHoH{$targetInstance->{type}}{elements}, "\n" ;
+ # print " offset: ",
+ # $attributeListTypeHoH{$targetInstance->{type}}{offset}, "\n" ;
+
+ # Create target record
+ $data .= pack('N',
+ $attributeListTypeHoH{$targetInstance->{type}}{elements});
+ $data .= packQuad(
+ $attributeListTypeHoH{$targetInstance->{type}}{offset}
+ + $pnorRoBaseAddress);
+ $data .= packQuad($attrAddr);
+ $attrAddr += $attributeListTypeHoH{$targetInstance->{type}}{elements}
+ * (length packQuad(0));
+
+ # Increment the offset
+ $offset += (length $data);
+
+ # Add it to the target sub-section
+ $targetsBinData .= $data;
+ }
+
+ my $pnorRoOffset = $offset;
+ my $attributesWritten = 0;
+
+ foreach my $targetInstance (@targetsAoH)
+ {
+ my $data;
+ my %attrhash = ();
+ my @AoH = ();
+
+ # Ensure consistent ordering of attributes for each target type
+ # Get the attribute list associated with each target type
+ #@TODO Attributes must eventually be ordered correctly for code update
+ getTargetAttributes($targetInstance->{type}, $attributes,\%attrhash);
+
+ # Update hash with any per-instance overrides, but only if that
+ # attribute has already been defined
+ foreach my $attr (@{$targetInstance->{attribute}})
+ {
+ if(exists $attrhash{$attr->{id}})
+ {
+ $attrhash{ $attr->{id} } = $attr;
+ }
+ else
+ {
+ fatal("Target instance \"$targetInstance->{id}\" cannot "
+ . "override attribute \"$attr->{id}\" unless "
+ . "the attribute has already been defined in the target "
+ . "type inheritance chain.");
+ }
+ }
+
+ for my $attributeId (keys %attrhash)
+ {
+ foreach my $attributeDef (@{$attributes->{attribute}})
+ {
+ my $section;
+ if( $attributeDef->{id} eq $attributeId )
+ {
+ if( exists $attributeDef->{writeable}
+ && $attributeDef->{persistency} eq "non-volatile" )
+ {
+ $section = "pnor-rw";
+ }
+ elsif ( !exists $attributeDef->{writeable}
+ && $attributeDef->{persistency} eq "non-volatile")
+ {
+ $section = "pnor-ro";
+ }
+ elsif ($attributeDef->{persistency} eq "volatile" )
+ {
+ $section = "heap-pnor-initialized";
+ }
+ elsif($attributeDef->{persistency} eq "volatile-zeroed")
+ {
+ $section = "heap-zero-initialized";
+ }
+ else
+ {
+ fatal("Persistency not supported.");
+ }
+
+ if($section eq "pnor-ro")
+ {
+ my $rodata = packAttribute($attributes,$attributeDef,
+ $attrhash{$attributeId}->{default});
+
+ $attributePointerBinData .= packQuad(
+ $offset + $pnorRoBaseAddress);
+
+ $offset += (length $rodata);
+
+ $roAttrBinData .= $rodata;
+ }
+ elsif($section eq "pnor-rw")
+ {
+ my $rwdata = packAttribute($attributes,$attributeDef,
+ $attrhash{$attributeId}->{default});
+
+ print "Wrote to pnor-rw value ",$attributeDef->{id}, ",
+ ", $attrhash{$attributeId}->{default}," \n";
+ $attributePointerBinData .= packQuad(
+ $rwOffset + $pnorRwBaseAddress);
+
+ $rwOffset += (length $rwdata);
+
+ $rwAttrBinData .= $rwdata;
+
+ }
+ elsif($section eq "heap-zero-initialized")
+ {
+ my $heapZeroInitData = packAttribute($attributes,
+ $attributeDef,$attrhash{$attributeId}->{default});
+
+ $attributePointerBinData .= packQuad(
+ $heapZeroInitOffset + $heapZeroInitBaseAddr);
+
+ $heapZeroInitOffset += (length $heapZeroInitData);
+
+ $heapZeroInitBinData .= $heapZeroInitData;
+
+ }
+ elsif($section eq "heap-pnor-initialized")
+ {
+ my $heapPnorInitData = packAttribute($attributes,
+ $attributeDef,$attrhash{$attributeId}->{default});
+
+ $attributePointerBinData .= packQuad(
+ $heapPnorInitOffset + $heapPnorInitBaseAddr);
+
+ $heapPnorInitOffset += (length $heapPnorInitData);
+
+ $heapPnorInitBinData .= $heapPnorInitData;
+ }
+ else
+ {
+ fatal("Could not find a suitable section.");
+ }
+
+ $attributesWritten++;
+
+ last;
+ }
+ }
+
+
+ } # End attribute loop
+
+ } # End target instance loop
+
+ if($numAttributes != $attributesWritten)
+ {
+ fatal("Number of attributes expected, $numAttributes, does not match "
+ . "what was written to PNOR, $attributesWritten.");
+ }
+
+ # Build header data
+ #@TODO Need header file for host boot which lays out the header
+
+ my $headerBinData;
+ my $blockSize = 4*1024;
+
+ my %sectionHoH = ();
+ $sectionHoH{ pnorRo }{ offset } = 0;
+ $sectionHoH{ pnorRo }{ type } = 0;
+ $sectionHoH{ pnorRo }{ size } = sizeBlockAligned($offset,$blockSize,1);
+
+ $sectionHoH{ pnorRw }{ offset } =
+ $sectionHoH{pnorRo}{offset} + $sectionHoH{pnorRo}{size};
+ $sectionHoH{ pnorRw }{ type } = 1;
+ $sectionHoH{ pnorRw }{ size } = sizeBlockAligned($rwOffset,$blockSize,1);
+
+ $sectionHoH{ heapPnorInit }{ offset } =
+ $sectionHoH{pnorRw}{offset} + $sectionHoH{pnorRw}{size};
+ $sectionHoH{ heapPnorInit }{ type } = 2;
+ $sectionHoH{ heapPnorInit }{ size } =
+ sizeBlockAligned($heapPnorInitOffset,$blockSize,1);
+
+ $sectionHoH{ heapZeroInit }{ offset } =
+ $sectionHoH{heapPnorInit}{offset} + $sectionHoH{heapPnorInit}{size};
+ $sectionHoH{ heapZeroInit }{ type } = 3;
+ $sectionHoH{ heapZeroInit }{ size } =
+ sizeBlockAligned($heapZeroInitOffset,$blockSize,1);
+
+ my $numSections = keys %sectionHoH;
+
+ # Version 1.0 to start with
+ my $headerMajorMinorVersion = 0x00010000;
+ my $eyeCatcher = 0x54415247; # TARG
+ my $sizeOfSection = 9;
+ my $offsetToSections = 0;
+
+ $headerBinData .= pack("N",$eyeCatcher);
+ $headerBinData .= pack("N",$headerMajorMinorVersion);
+ $headerBinData .= pack("N",$headerSize);
+ $headerBinData .= pack("N",$vmmSectionOffset);
+ $headerBinData .= packQuad($pnorRoBaseAddress);
+ $headerBinData .= pack("N",$sizeOfSection);
+ $headerBinData .= pack("N",$numSections);
+ $headerBinData .= pack("N",$offsetToSections);
+
+ foreach my $section ("pnorRo","pnorRw","heapPnorInit","heapZeroInit")
+ {
+ $headerBinData .= pack("C" , $sectionHoH{$section}{type});
+ $headerBinData .= pack("N" , $sectionHoH{$section}{offset});
+ $headerBinData .= pack("N" , $sectionHoH{$section}{size});
+ }
+
+ # Serialize PNOR RO section to multiple of 4k page size (pad if necessary)
+
+ # First 256 bytes is RO header (pad if necessary)
+ if((length $headerBinData) > $headerSize)
+ {
+ fatal("Header data of length " . (length $headerBinData) . " is larger "
+ . "than allocated amount of $headerSize.");
+ }
+ print $outFile $headerBinData;
+ my $padSize = sizeBlockAligned((length $headerBinData),$headerSize,1)
+ - (length $headerBinData);
+ print $outFile pack ("@".$padSize);
+
+ # Remaining data belongs to targeting
+ print $outFile $numTargetsPointerBinData;
+ print $outFile $attributeListBinData;
+ print $outFile $attributePointerBinData;
+ print $outFile $numTargetsBinData;
+ print $outFile $targetsBinData;
+ print $outFile $roAttrBinData;
+ print $outFile pack ("@".($sectionHoH{pnorRo}{size} - $offset));
+
+ # Serialize PNOR RW section to multiple of 4k page size (pad if necessary)
+ print $outFile $rwAttrBinData;
+ print $outFile pack("@".($sectionHoH{pnorRw}{size} - $rwOffset));
+
+ # Serialize PNOR initiated heap section to multiple of 4k page size (pad if
+ # necessary)
+ print $outFile $heapPnorInitBinData;
+ print $outFile pack("@".($sectionHoH{heapPnorInit}{size}
+ - $heapPnorInitOffset));
+
+ # Serialize 0 initiated heap section to multiple of 4k page size (pad if
+ # necessary)
+ #@TODO: Once host boot support 0 initialization of heap pages for targeting,
+ # remove the contents of this section, since it will be a "virtual" section.
+ # Until then, zero out the section and map it into memory
+ print $outFile pack("@".(length $heapZeroInitBinData));
+ print $outFile pack("@".($sectionHoH{heapZeroInit}{size}
+ - $heapZeroInitOffset));
+}
+
+__END__
+
+=head1 NAME
+
+xmltohb.pl
+
+=head1 SYNOPSIS
+
+xmltohb.pl [options] [file ...]
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<--help>
+
+Print a brief help message and exits.
+
+=item B<--man>
+
+Prints the manual page and exits.
+
+=item B<--hb-xml-file>
+
+File containing the intermediate representation of the host boot XML just prior
+to compilation down to images and source files (Default is ./hb.xml)
+
+=item B<--fapi-attributes-xml-file>
+
+File containing the FAPI HWP attributes, for purposes of configuring the
+attribute mappings between FAPI and targeting code (Default is
+../../hwpf/hwp/fapiHwpAttributeInfo.xml)
+
+=item B<--src-output-dir>=DIRECTORY
+
+Sets the output directory for generated source files (default is the current
+directory)
+
+=item B<--img-output-dir>=DIRECTORY
+
+Sets the output directory for generated binary files
+(default is the current directory)
+
+=item B<--verbose>
+
+Prints out some internal workings
+
+=back
+
+=head1 DESCRIPTION
+
+B<xmltohb.pl> will process a set of input .xml files and emit source files and
+a PNOR targeting image binary to facilitate compiling and configuring host boot
+respectively.
+
+=cut
+
+
OpenPOWER on IntegriCloud