diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2011-09-08 00:06:56 -0500 |
---|---|---|
committer | Nicholas E. Bofferding <bofferdn@us.ibm.com> | 2011-09-19 13:18:30 -0500 |
commit | b08159eb20f2a0ccfe2d654f56a6fe2079bec98e (patch) | |
tree | 5248e5cea65eff0ba758ed5d50bad1b26884e883 /src/usr/targeting/xmltohb | |
parent | ea37c1fc02819175e8ede86718a3afc904c723bc (diff) | |
download | talos-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/targeting/xmltohb')
-rw-r--r-- | src/usr/targeting/xmltohb/hb.xml | 1032 | ||||
-rw-r--r-- | src/usr/targeting/xmltohb/makefile | 52 | ||||
-rwxr-xr-x | src/usr/targeting/xmltohb/xmltohb.pl | 2385 |
3 files changed, 3469 insertions, 0 deletions
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 + + |