summaryrefslogtreecommitdiffstats
path: root/src/ppe/tools
diff options
context:
space:
mode:
authorWilliam Bryan <wilbryan@us.ibm.com>2015-09-23 11:30:56 -0500
committerWilliam A. Bryan <wilbryan@us.ibm.com>2015-09-24 10:32:03 -0500
commit447b47d1dfbfafa54363beabb381122d780b783b (patch)
treee7b3ea09544addf729be985743a1667a66b3a9e9 /src/ppe/tools
parent9513285de33024843868b9cf4baa57d462ad63dd (diff)
downloadtalos-occ-447b47d1dfbfafa54363beabb381122d780b783b.tar.gz
talos-occ-447b47d1dfbfafa54363beabb381122d780b783b.zip
Update new PPE HW code
Change-Id: I8e0f107fc08c857b00102fa67f35516a04ee6c78 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/20731 Reviewed-by: Martha Broyles <mbroyles@us.ibm.com> Reviewed-by: William A. Bryan <wilbryan@us.ibm.com> Tested-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src/ppe/tools')
-rw-r--r--src/ppe/tools/image/Makefile148
-rw-r--r--src/ppe/tools/image/bin/.empty0
-rw-r--r--src/ppe/tools/image/p9_image_help_base.H119
-rw-r--r--src/ppe/tools/image/p9_ring_identification.H65
-rw-r--r--src/ppe/tools/image/p9_ring_identification.c146
-rw-r--r--src/ppe/tools/image/p9_scan_compression.H369
-rwxr-xr-xsrc/ppe/tools/image/ppeSetFixed.pl234
-rw-r--r--src/ppe/tools/image/sbe_default_tool.c310
-rw-r--r--src/ppe/tools/image/sbe_xip_tool.c2135
-rwxr-xr-xsrc/ppe/tools/scripts/parseErrorInfo.pl1511
-rwxr-xr-xsrc/ppe/tools/scripts/ppeCreateAttrGetSetMacros.pl557
-rwxr-xr-xsrc/ppe/tools/scripts/ppeCreateIfAttrService.pl241
-rw-r--r--src/ppe/tools/scripts/ppeParseAttrGetSetMacros.pl284
-rwxr-xr-xsrc/ppe/tools/scripts/ppeParseAttributeInfo.pl1090
-rwxr-xr-xsrc/ppe/tools/scripts/ppeParseProcSbeFixed.pl277
-rw-r--r--src/ppe/tools/scripts/src/fapi2PlatAttributeService.H1085
16 files changed, 8571 insertions, 0 deletions
diff --git a/src/ppe/tools/image/Makefile b/src/ppe/tools/image/Makefile
new file mode 100644
index 0000000..e4d60da
--- /dev/null
+++ b/src/ppe/tools/image/Makefile
@@ -0,0 +1,148 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/image/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+############################################################################
+
+# Makefile for image tools
+# works on X86 Linux hosts.
+
+# Make targets:
+
+# all :
+#
+# utilities : Build utility programs and procedures
+#
+# clean : Removes the bin/ directory and all symbolic links
+#
+
+############################################################################
+
+
+ifeq ($(CTEPATH),)
+$(warning CTEPATH not defined; defaulting to awd)
+CTEPATH = /afs/awd/projects/cte
+endif
+
+
+# Are we setup for eCMD, if so let's get our eCMD Release from there
+ifneq ($(strip $(ECMD_RELEASE)),)
+ ECMD_RELEASE := $(shell ecmdVersion full)
+ # Make sure we got a valid version back
+ ifeq ($(findstring ver,$(ECMD_RELEASE)),)
+ ECMD_RELEASE := rel
+ endif
+else
+ # If not setup for eCMD, default to rel
+ ECMD_RELEASE := rel
+endif
+
+
+# Ok, now set our eCMD Path, if not set already
+ifeq ($(strip $(ECMD_PATH)),)
+ ECMD_PATH := ${CTEPATH}/tools/ecmd/${ECMD_RELEASE}/
+endif
+
+ifeq ($(strip $(ECMD_PLUGIN)),cro)
+# Cronus plugin specific setup
+ CRONUS_PATH := $(shell echo ${ECMD_EXE} | sed -n 's|\([a-zA-Z0-9]*\)\(_*\)\([a-zA-Z0-9]*\)_x86\.exe|prcd_d|p')
+ ifeq ($(strip $(CRONUS_PATH)),)
+ $(error "Error determining CRONUS_PATH from env!")
+ endif
+endif
+
+# We need common up-to-date headers for FAPI - currently using these.
+FAPI = $(ECMD_PATH)ext/fapi
+
+# Locations of required headers.
+INCLUDES += -I. -I../../ -I../../utils
+INCLUDES += -I ../../sbe/image/
+INCLUDES += -I ../../sbe/sbefw/
+INCLUDES += -I ../../sbe/plat/include
+INCLUDES += -I ../../hwpf/plat/include/
+INCLUDES += -I ../../pk/ppe42/
+INCLUDES += -I ../../pk/kernel/
+INCLUDES += -I ../../pk/std/
+INCLUDES += -I ../../pk/trace/
+INCLUDES += -I ../../tools/ppetracepp/
+INCLUDES += -I ../../importtemp/fapi2/include/
+
+INCLUDES += -I$(CRONUS_PATH)
+INCLUDES += -I$(ECMD_PATH)/capi
+INCLUDES += -I$(FAPI)/capi
+
+# Under Linux the scheme is to use a common compiler to create procedures.
+# However, the common compiler can be VERY slow, so if the system compiler is
+# also 4.1.2 we're using that one instead. Also, the Linux FAPI libraries we
+# link with are 32-bit only so we need to force 32-bit mode.
+
+ifeq ($(wildcard /etc/ldap.conf), )
+ GSACELL = ausgsa
+else
+ GSACELL = $(shell cat /etc/ldap.conf | grep "host " | \
+ cut -d" " -f2 | cut -d. -f1)
+endif
+
+GCC-RELEASE = 4.8.2
+GCC-VERSION = $(shell gcc -v 2>&1 | grep "$(GCC-RELEASE)")
+
+ifeq ($(GCC-VERSION),)
+$(error wrong compiler version. Use $(GCC-RELEASE) compiler. Try: "scl enable devtoolset-2 bash")
+else
+CC = gcc
+CXX = g++
+endif
+
+#UTILITIES-SOURCES += ../../sbe/image/sbe_xip_image.c
+UTILITIES-SOURCES = sbe_xip_tool.c sbe_default_tool.c
+
+UTILITIES = sbe_xip_tool sbe_default_tool
+
+# Utility targets
+UTILITIES-OBJc = $(patsubst %.c,bin/%.o,$(UTILITIES-SOURCES))
+UTILITIES-OBJECTS += $(patsubst %.C,bin/%.o,$(UTILITIES-OBJc))
+UTILITIES-DEPENDENCIES = $(patsubst %.o,%.d,$(UTILITIES-OBJECTS))
+UTILITIES-EXECUTABLES = $(patsubst %,bin/%,$(UTILITIES))
+
+
+.PHONY : utilities
+utilities: $(UTILITIES-EXECUTABLES)
+
+bin/%.o: %.c
+ $(CXX) -std=c++11 $(INCLUDES) $(CXXFLAGS) -DDEBUG_SBE_XIP_IMAGE=1 -DFAPI2_NO_FFDC -c -o $@ $<
+
+bin/sbe_xip_image.o: ../../sbe/image/sbe_xip_image.c
+ $(CXX) -std=c++11 $(INCLUDES) $(CXXFLAGS) -DDEBUG_SBE_XIP_IMAGE=1 -DFAPI2_NO_FFDC -c -o $@ $<
+
+bin/sbe_xip_tool: bin/sbe_xip_image.o bin/p9_ring_identification.o bin/sbe_xip_tool.o
+ $(CXX) $(CXXFLAGS) ${INCLUDES} -o $@ $^
+ ln -sf bin/sbe_xip_tool sbe_xip_tool
+
+bin/sbe_default_tool: bin/sbe_xip_image.o bin/sbe_default_tool.o
+ $(CXX) $(CXXFLAGS) ${INCLUDES} -o $@ $^
+ ln -sf bin/sbe_default_tool sbe_default_tool
+
+clean:
+ rm sbe_xip_tool sbe_default_tool
+ rm -rf bin
+ mkdir -p bin \ No newline at end of file
diff --git a/src/ppe/tools/image/bin/.empty b/src/ppe/tools/image/bin/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/tools/image/bin/.empty
diff --git a/src/ppe/tools/image/p9_image_help_base.H b/src/ppe/tools/image/p9_image_help_base.H
new file mode 100644
index 0000000..f9b6369
--- /dev/null
+++ b/src/ppe/tools/image/p9_image_help_base.H
@@ -0,0 +1,119 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/image/p9_image_help_base.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _P9_IMAGE_HELP_BASE_H_
+#define _P9_IMAGE_HELP_BASE_H_
+
+#include <sbe_xip_image.h>
+
+//
+// Various image/ring buffer sizes. Must be used by all users (VBU, FSP, HB, HBI, Cronus)
+//
+const uint32_t MAX_REF_IMAGE_SIZE = 5000000; // Max reference image size.
+const uint32_t FIXED_SEEPROM_WORK_SPACE= 128*1024; // Max work space for Seeprom img.
+const uint32_t MAX_SEEPROM_IMAGE_SIZE = 56*1024; // Max Seeprom image size.
+const uint32_t FIXED_RING_BUF_SIZE = 60000; // Fixed ring buf size for _fixed.
+
+const uint8_t MAX_VPD_TYPES = 2; // #G and #R, so far.
+#define CHIPLET_ID_MIN 0x00
+#define CHIPLET_ID_MAX 0x1F
+#define CHIPLET_ID_EX_MIN 0x10
+#define CHIPLET_ID_EX_MAX 0x1F
+const uint8_t MAX_CHIPLETS = CHIPLET_ID_MAX-CHIPLET_ID_MIN+1;
+const uint32_t ASM_RS4_LAUNCH_BUF_SIZE = 24; // Byte size of RS4 launch buffer.
+const uint32_t WF_ENCAP_SIZE = 400; // Byte size of WF encapsulation.
+ // (Actually, only 304B but may change.)
+const uint32_t WF_WORST_CASE_SIZE_FAC = 4; // WC WF size = 3x ring length.
+ // (Assumes 12B per write.)
+ // (4x w/waits instructions.)
+const uint32_t LISTING_STRING_SIZE = 256;
+const uint64_t MAX_UINT64_T = (uint64_t)0xFFFFFFFF<<32 | (uint64_t)0xFFFFFFFF;
+
+const uint8_t RING_SECTION_ID[] = {
+ SBE_XIP_SECTION_RINGS,
+ SBE_XIP_SECTION_OVERLAYS,
+};
+const uint8_t RING_SECTION_ID_SIZE = sizeof(RING_SECTION_ID) / sizeof(RING_SECTION_ID[0]);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Base (shared) ring layout for both RS4 and Wiggle-flip layouts.
+typedef struct {
+ uint64_t entryOffset;
+ uint64_t backItemPtr;
+ uint32_t sizeOfThis;
+ uint32_t sizeOfMeta; // Exact size of meta data. Arbitrary size. Not null terminated.
+} BaseRingLayout;
+
+// RS4 specific layout.
+typedef struct {
+ uint64_t entryOffset;
+ uint64_t backItemPtr;
+ uint32_t sizeOfThis;
+ uint32_t sizeOfMeta; // Exact size of meta data. Arbitrary size. Not null terminated.
+ uint32_t ddLevel;
+ uint8_t sysPhase;
+ uint8_t override;
+ uint8_t reserved1;
+ uint8_t reserved2;
+} Rs4RingLayout;
+
+// PairingInfo is used for pairing, or matching, a back pointer address of a
+// ring block with its corresponding TOC name.
+typedef struct {
+ uint64_t address; // (in) Holds HOMER backPtr addr of the ring
+ uint8_t vectorpos; // (in) Vector position of fwdPtr [0;31]
+ // max=0 for most VPD rings
+ // max=1 for all non-VPD rings
+ // max=1 for perv_ VPD rings
+ // max=15 for most VPD ex_ rings
+ // max=31 for 16 ex_ chiplets with override
+ char *name; // (out) TOC name
+ uint8_t isvpd; // (out) 0: Non-VPD ring 1: VPD ring
+ uint8_t overridable; // (out) 0: No (most VPD rings) 1: Yes (all non-VPD rings)
+ uint8_t override; // (out) 0: base 1: override
+} PairingInfo;
+
+
+///
+/// ****************************************************************************
+/// Function declares.
+/// ****************************************************************************
+///
+int over_write_ring_data_in_image( void *io_image,
+ const char *i_ringName,
+ const void *i_ringData, // WF or RS4
+ const uint32_t i_sizeRingData, // Byte size
+ const uint8_t i_idxVector,
+ const uint8_t i_override,
+ const uint8_t i_overridable );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_P8_IMAGE_HELP_BASE_H_
diff --git a/src/ppe/tools/image/p9_ring_identification.H b/src/ppe/tools/image/p9_ring_identification.H
new file mode 100644
index 0000000..452fcf2
--- /dev/null
+++ b/src/ppe/tools/image/p9_ring_identification.H
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/image/p9_ring_identification.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _P9_RING_IDENT_H_
+#define _P9_RING_IDENT_H_
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+// Ring ID list structure.
+typedef struct {
+ const char *ringName;
+ uint8_t ringId;
+ uint8_t chipIdMin; // the min chipletId
+ uint8_t chipIdMax; // the max chipletId
+ const char *ringNameImg; // Ring name in image: ringName + "_ring"
+ uint8_t vpdKeyword;
+ uint8_t bWcSpace; // 0: fitted 1: worst-case space (3 x ring length)
+} RingIdList;
+
+extern const RingIdList RING_ID_LIST_PG[], RING_ID_LIST_PR[];
+extern const uint32_t RING_ID_LIST_PG_SIZE, RING_ID_LIST_PR_SIZE;
+extern const RingIdList RING_ID_LIST[];
+extern const uint32_t RING_ID_LIST_SIZE;
+
+// Enumerated VPD keyword values.
+// Note! This is DIFFERENT from the MvpdKeyword list in fapiMvpdAccess.H which
+// can't be used in this file since it's not, per se, a fapi file. So
+// these values need to be translated in xip_customize when passing the
+// mvpdKeyword to getMvpdRing();
+enum VpdKeyword {
+ VPD_KEYWORD_PDG,
+ VPD_KEYWORD_PDR,
+ NUM_OF_VPD_TYPES
+};
+
+int get_vpd_ring_list_entry(const char *i_ringName,
+ const uint8_t i_ringId,
+ RingIdList **i_ringIdList);
+
+
+#endif
diff --git a/src/ppe/tools/image/p9_ring_identification.c b/src/ppe/tools/image/p9_ring_identification.c
new file mode 100644
index 0000000..126293b
--- /dev/null
+++ b/src/ppe/tools/image/p9_ring_identification.c
@@ -0,0 +1,146 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/image/p9_ring_identification.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <p9_ring_identification.H>
+
+const RingIdList RING_ID_LIST_PG[] = {
+ /* ringName ringId chipletId ringNameImg mvpdKeyword wc */
+ /* min max */
+ {"ab_gptr_ab", 0xA0, 0x08, 0x08, "ab_gptr_ab_ring", VPD_KEYWORD_PDG, 0},
+ {"ab_gptr_ioa", 0xA1, 0x08, 0x08, "ab_gptr_ioa_ring", VPD_KEYWORD_PDG, 0},
+ {"ab_gptr_perv", 0xA2, 0x08, 0x08, "ab_gptr_perv_ring", VPD_KEYWORD_PDG, 0},
+ {"ab_gptr_pll", 0xA3, 0x08, 0x08, "ab_gptr_pll_ring", VPD_KEYWORD_PDG, 0},
+ {"ab_time", 0xA4, 0x08, 0x08, "ab_time_ring", VPD_KEYWORD_PDG, 0},
+ {"ex_gptr_core", 0xA5, 0xFF, 0xFF, "ex_gptr_core_ring", VPD_KEYWORD_PDG, 0}, //Chip specific
+ {"ex_gptr_dpll", 0xA6, 0xFF, 0xFF, "ex_gptr_dpll_ring", VPD_KEYWORD_PDG, 0}, //Chip specific
+ {"ex_gptr_l2", 0xA7, 0xFF, 0xFF, "ex_gptr_l2_ring", VPD_KEYWORD_PDG, 0}, //Chip specific
+ {"ex_gptr_l3", 0xA8, 0xFF, 0xFF, "ex_gptr_l3_ring", VPD_KEYWORD_PDG, 0}, //Chip specific
+ {"ex_gptr_l3refr", 0xA9, 0xFF, 0xFF, "ex_gptr_l3refr_ring", VPD_KEYWORD_PDG, 0}, //Chip specific
+ {"ex_gptr_perv", 0xAA, 0xFF, 0xFF, "ex_gptr_perv_ring", VPD_KEYWORD_PDG, 0}, //Chip specific
+ {"ex_time_core", 0xAB, 0x10, 0x1F, "ex_time_core_ring", VPD_KEYWORD_PDG, 0}, //Chiplet specfc
+ {"ex_time_eco", 0xAC, 0x10, 0x1F, "ex_time_eco_ring", VPD_KEYWORD_PDG, 0}, //Chiplet specfc
+ {"pb_gptr_dmipll", 0xAD, 0x02, 0x02, "pb_gptr_dmipll_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_gptr_mcr", 0xAE, 0x02, 0x02, "pb_gptr_mcr_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_gptr_nest", 0xAF, 0x02, 0x02, "pb_gptr_nest_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_gptr_nx", 0xB0, 0x02, 0x02, "pb_gptr_nx_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_gptr_pcis", 0xB1, 0x02, 0x02, "pb_gptr_pcis_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_gptr_perv", 0xB2, 0x02, 0x02, "pb_gptr_perv_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_time", 0xB3, 0x02, 0x02, "pb_time_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_time_mcr", 0xB4, 0x02, 0x02, "pb_time_mcr_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_time_nx", 0xB5, 0x02, 0x02, "pb_time_nx_ring", VPD_KEYWORD_PDG, 0},
+ {"pci_gptr_iopci", 0xB6, 0x09, 0x09, "pci_gptr_iopci_ring", VPD_KEYWORD_PDG, 0},
+ {"pci_gptr_pbf", 0xB7, 0x09, 0x09, "pci_gptr_pbf_ring", VPD_KEYWORD_PDG, 0},
+ {"pci_gptr_pci0", 0xB8, 0x09, 0x09, "pci_gptr_pci0_ring", VPD_KEYWORD_PDG, 0},
+ {"pci_gptr_pci1", 0xB9, 0x09, 0x09, "pci_gptr_pci1_ring", VPD_KEYWORD_PDG, 0},
+ {"pci_gptr_pci2", 0xBA, 0x09, 0x09, "pci_gptr_pci2_ring", VPD_KEYWORD_PDG, 0},
+ {"pci_gptr_perv", 0xBB, 0x09, 0x09, "pci_gptr_perv_ring", VPD_KEYWORD_PDG, 0},
+ {"pci_gptr_pll", 0xBC, 0x09, 0x09, "pci_gptr_pll_ring", VPD_KEYWORD_PDG, 0},
+ {"pci_time", 0xBD, 0x09, 0x09, "pci_time_ring", VPD_KEYWORD_PDG, 0},
+ {"perv_gptr_net", 0xBE, 0x00, 0x00, "perv_gptr_net_ring", VPD_KEYWORD_PDG, 0},
+ {"perv_gptr_occ", 0xBF, 0x00, 0x00, "perv_gptr_occ_ring", VPD_KEYWORD_PDG, 0},
+ {"perv_gptr_perv", 0xC0, 0x00, 0x00, "perv_gptr_perv_ring", VPD_KEYWORD_PDG, 0},
+ {"perv_gptr_pib", 0xC1, 0x00, 0x00, "perv_gptr_pib_ring", VPD_KEYWORD_PDG, 0},
+ {"perv_gptr_pll", 0xC2, 0x00, 0x00, "perv_gptr_pll_ring", VPD_KEYWORD_PDG, 0},
+ {"perv_time", 0xC3, 0x00, 0x00, "perv_time_ring", VPD_KEYWORD_PDG, 0},
+ {"xb_gptr_iopci", 0xC4, 0x04, 0x04, "xb_gptr_iopci_ring", VPD_KEYWORD_PDG, 0},
+ {"xb_gptr_iox", 0xC5, 0x04, 0x04, "xb_gptr_iox_ring", VPD_KEYWORD_PDG, 0},
+ {"xb_gptr_pben", 0xC6, 0x04, 0x04, "xb_gptr_pben_ring", VPD_KEYWORD_PDG, 0},
+ {"xb_gptr_perv", 0xC7, 0x04, 0x04, "xb_gptr_perv_ring", VPD_KEYWORD_PDG, 0},
+ {"xb_time", 0xC8, 0x04, 0x04, "xb_time_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_gptr_mcl", 0xC9, 0x02, 0x02, "pb_gptr_mcl_ring", VPD_KEYWORD_PDG, 0},
+ {"pb_time_mcl", 0xCA, 0x02, 0x02, "pb_time_mcl_ring", VPD_KEYWORD_PDG, 0},
+};
+
+const RingIdList RING_ID_LIST_PR[] = {
+ /* ringName ringId chipIdMin chipIdMax ringNameImg mvpdKeyword */
+ {"ab_repr", 0xE0, 0x08, 0x08, "ab_repr_ring", VPD_KEYWORD_PDR, 0},
+ {"ex_repr_core", 0xE1, 0x10, 0x1F, "ex_repr_core_ring", VPD_KEYWORD_PDR, 1},
+ {"ex_repr_eco", 0xE2, 0x10, 0x1F, "ex_repr_eco_ring", VPD_KEYWORD_PDR, 1},
+ {"pb_repr", 0xE3, 0x02, 0x02, "pb_repr_ring", VPD_KEYWORD_PDR, 0},
+ {"pb_repr_mcr", 0xE4, 0x02, 0x02, "pb_repr_mcr_ring", VPD_KEYWORD_PDR, 0},
+ {"pb_repr_nx", 0xE5, 0x02, 0x02, "pb_repr_nx_ring", VPD_KEYWORD_PDR, 0},
+ {"pci_repr", 0xE6, 0x09, 0x09, "pci_repr_ring", VPD_KEYWORD_PDR, 0},
+ {"perv_repr", 0xE7, 0x00, 0x00, "perv_repr_ring", VPD_KEYWORD_PDR, 0},
+ {"perv_repr_net", 0xE8, 0x00, 0x00, "perv_repr_net_ring", VPD_KEYWORD_PDR, 0},
+ {"perv_repr_pib", 0xE9, 0x00, 0x00, "perv_repr_pib_ring", VPD_KEYWORD_PDR, 0},
+ {"xb_repr", 0xEA, 0x04, 0x04, "xb_repr_ring", VPD_KEYWORD_PDR, 0},
+ {"pb_repr_mcl", 0xEB, 0x02, 0x02, "pb_repr_mcl_ring", VPD_KEYWORD_PDR, 0},
+};
+
+const uint32_t RING_ID_LIST_PG_SIZE = sizeof(RING_ID_LIST_PG)/sizeof(RING_ID_LIST_PG[0]);
+const uint32_t RING_ID_LIST_PR_SIZE = sizeof(RING_ID_LIST_PR)/sizeof(RING_ID_LIST_PR[0]);
+
+// get_vpd_ring_list_entry() retrieves the MVPD list entry based on either a ringName
+// or a ringId. If both are supplied, only the ringName is used. If ringName==NULL,
+// then the ringId is used. A pointer to the RingIdList is returned.
+int get_vpd_ring_list_entry(const char *i_ringName,
+ const uint8_t i_ringId,
+ RingIdList **i_ringIdList)
+{
+ int rc=0, NOT_FOUND=1, FOUND=0;
+ uint8_t iVpdType;
+ uint8_t iRing;
+ RingIdList *ring_id_list=NULL;
+ uint8_t ring_id_list_size;
+
+ rc = NOT_FOUND;
+ for (iVpdType=0; iVpdType<NUM_OF_VPD_TYPES; iVpdType++) {
+ if (iVpdType==0) {
+ ring_id_list = (RingIdList*)RING_ID_LIST_PG;
+ ring_id_list_size = (uint32_t)RING_ID_LIST_PG_SIZE;
+ }
+ else {
+ ring_id_list = (RingIdList*)RING_ID_LIST_PR;
+ ring_id_list_size = (uint32_t)RING_ID_LIST_PR_SIZE;
+ }
+ // Search the MVPD reference lists for either a:
+ // - ringName match with or w/o _image in the name, or
+ // - ringId match.
+ if (i_ringName) {
+ // Search for ringName match.
+ for (iRing=0; iRing<ring_id_list_size; iRing++) {
+ if ( strcmp((ring_id_list+iRing)->ringName, i_ringName)==0 ||
+ strcmp((ring_id_list+iRing)->ringNameImg,i_ringName)==0 ) {
+ *i_ringIdList = ring_id_list+iRing;
+ return FOUND;
+ }
+ }
+ }
+ else {
+ // Search for ringId match (since ringName was not supplied).
+ for (iRing=0; iRing<ring_id_list_size; iRing++) {
+ if ((ring_id_list+iRing)->ringId==i_ringId) {
+ *i_ringIdList = ring_id_list+iRing;
+ return FOUND;
+ }
+ }
+ }
+
+ }
+ return rc;
+}
+
+
+
+
diff --git a/src/ppe/tools/image/p9_scan_compression.H b/src/ppe/tools/image/p9_scan_compression.H
new file mode 100644
index 0000000..c2254ab
--- /dev/null
+++ b/src/ppe/tools/image/p9_scan_compression.H
@@ -0,0 +1,369 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/image/p9_scan_compression.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __P9_SCAN_COMPRESSION_H__
+#define __P9_SCAN_COMPRESSION_H__
+
+/// This header declares and documents the entry points defined in
+/// p9_scan_compression.C. Some constants are also required by the scan
+/// decompression HOMER assembly procedures.
+
+#include "fapi_sbe_common.H"
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/// Compressed Scan Chain Data Structure Format
+///
+/// The compressed scan ring data structure must be 8-byte aligned in
+/// memory. The container data structure consists of this 24-byte header
+/// followed by an arbitrary number of 8 byte doublewords containing the
+/// compressed scan data. Images are always stored and processed in
+/// big-endian byte order. This container format is common across all
+/// decompression algorithms.
+///
+/// Bytes - Content
+///
+/// 0:3 - A 32-bit "magic number" that identifies and validates the
+/// compression algorithm and algorithm version used to compress the data.
+///
+/// 4:7 - The 32-bit size of the entire data structure in \e bytes. This
+/// consists of this 24-byte header plus the compressed scan data. This value
+/// is always a multiple of 8.
+///
+/// 8:11 - This 32-bit value is reserved to the compression
+/// algorithm. Typically this field is used to record the 'size' of the
+/// compressed string in units specific to each algorithm.
+///
+/// 12:15 - The length of the original scan chain in \e bits.
+///
+/// 16:19 - The 32 high-order bits of the value written to the Scan Select
+/// register to set up the scan. The Scan Select register only defines these
+/// bits.
+///
+/// 20 - The Scan Chain Data Structure version number
+///
+/// 21 - Flush-optimize : Is this byte is non-zero, the ring state to be
+/// modified is the flush state of the ring.
+///
+/// 22 - The ring ID uniquely identifying the repair ring name.
+///
+/// 23 - The 7-bit pervasive chiplet Id + Multicast bit of the chiplet to
+/// scan. This value is loaded directly into P0. The decompression
+/// algorithms provide two entry points - one that uses this value as the
+/// chiplet Id, and another that allows the caller to specify the chiplet Id
+/// in the call.
+
+typedef struct {
+
+ /// Magic number - See \ref scan_compression_magic
+ uint32_t iv_magic;
+
+ /// Total size in bytes, including the container header
+ uint32_t iv_size;
+
+ /// Reserved to the algorithm
+ uint32_t iv_algorithmReserved;
+
+ /// Length of the original scan chain in bits
+ uint32_t iv_length;
+
+ /// The high-order 32 bits of the Scan Select Register
+ ///
+ /// Note that the Scan Select register only defines the high order 32
+ /// bits, so we only need store the 32 high-order bits. This field is
+ /// 8-byte aligned so that the doubleword loaded by the HOMER can be
+ /// directly written to the scan select register.
+ uint32_t iv_scanSelect;
+
+ /// Data structure (header) version
+ uint8_t iv_headerVersion;
+
+ /// Flush-state optimization
+ ///
+ /// Normally, modifying the state of the ring requires XOR-ing the
+ /// difference state (the compressed state) with the current ring state as
+ /// it will appear in the Scan Data Register. If the current state of the
+ /// ring is the scan-0 flush state, then by definition the Scan Data
+ /// Register is always 0. Therefore we can simply write the difference to
+ /// the Scan Data Register rather than using a read-XOR-write.
+ uint8_t iv_flushOptimization;
+
+ /// Ring ID uniquely identifying the repair name. (See the list of ring
+ /// name vs ring IDs in p8_ring_identification.c).
+ uint8_t iv_ringId;
+
+ /// 7-bit pervasive chiplet Id + Multicast bit
+ ///
+ /// This field is right-justified in an 8-byte aligned doubleword so that
+ /// the P0 register can be directly updated from the doubelword value in a
+ /// data register.
+ uint8_t iv_chipletId;
+
+} CompressedScanData;
+
+
+/// Endian-translate a CompressedScanData structure
+///
+/// \param o_data A pointer to a CompressedScanData structure to receive the
+/// endian-translated form of \a i_data.
+///
+/// \param i_data A pointer to the original CompressedScanData structure.
+///
+/// This API performs an endian-converting copy of a CompressedScanData
+/// structure. This copy is guaranteed to be done in such a way that \a i_data
+/// and \a o_data may be the same pointer for in-place conversion. Due to the
+/// symmetry of reverse, translating a structure twice is always guaranteed to
+/// return the origial structure to its original byte order.
+void
+compressed_scan_data_translate(CompressedScanData* o_data,
+ CompressedScanData* i_data);
+
+
+/// Compress a scan string using the RS4 compression algorithm
+///
+/// \param[in,out] io_data This is a pointer to a memory area which must be
+/// large enough to hold the worst-case result of compressing \a i_string (see
+/// below). Note that the CompressedScanData is always created in big-endian
+/// format, however the caller can use compresed_scan_data_translate() to
+/// create a copy of the header in host format.
+///
+/// \param[in] i_dataSize The size of \a io_data in bytes.
+///
+/// \param[out] o_imageSize The effective size of the entire compressed scan
+/// data structure (header + compressed data) created in \a io_data, in bytes.
+/// This value will always be a multiple of 8.
+///
+/// \param[in] i_string The string to compress. Scan data to compress is
+/// left-justified in this input string.
+///
+/// \param[in] i_length The length of the input string in \e bits. It is
+/// assumed the \a i_string contains at least (\a i_length + 7) / 8 bytes.
+///
+/// \param[in] i_scanSelect The 64-bit value written to the Scan Select
+/// register to set up for the scan. Only the 32 high-order bits are actually
+/// stored.
+///
+/// \param[in] i_ringId The ring ID that uniquely identifies the ring name of
+/// a repair ring. (See p8_ring_identification.c for more info.)
+///
+/// \param[in] i_chipletId The 7-bit value for the iv_chipletId field of the
+/// CompressedScanData.
+///
+/// \param[in] i_flushOptimization This input parameter should be set to a
+/// non-0 value if it is known that this ring difference will be applied to a
+/// scan-0 flush state. This will improve the performance of the
+/// decompress-scan routine. If the initial state of the ring is unknown, set
+/// this parameter to 0.
+///
+/// This API is required for integration with PHYP which does not support
+/// malloc(). Applications in environments supporting malloc() can use
+/// rs4_compress() instead.
+///
+/// The worst-case compression for RS4 requires 2 nibbles of control overhead
+/// per 15 nibbles of data (17/15), plus a maximum of 2 nibbles of termination.
+/// We always require this worst-case amount of memory including the header and
+/// any rounding required to guarantee that the data size is a multiple of 8
+/// bytes. The final image size is also rounded up to a multiple of 8 bytes.
+/// If the \a i_dataSize is less than this amount (based on \a i_length) the
+/// call will fail.
+///
+/// \returns See \ref scan_compression_codes
+int
+_rs4_compress(CompressedScanData* io_data,
+ uint32_t i_dataSize,
+ uint32_t* o_imageSize,
+ const uint8_t* i_string,
+ const uint32_t i_length,
+ const uint64_t i_scanSelect,
+ const uint8_t i_ringId,
+ const uint8_t i_chipletId,
+ const uint8_t i_flushOptimization);
+
+
+/// Compress a scan string using the RS4 compression algorithm
+///
+/// \param[out] o_data This algorithm uses malloc() to allocate memory for the
+/// compresed data, and returns a pointer to this memory in \a o_data. After
+/// the call this memory is owned by the caller who is responsible for
+/// free()-ing the data area once it is no longer required. Note that the
+/// CompressedScanData is always created in big-endian format, however the
+/// caller can use compresed_scan_data_translate() to create a copy of the
+/// header in host format.
+///
+/// \param[out] o_size The effective size of the entire compressed scan data
+/// structure (header + compressed data) pointed to by \a o_data, in bytes.
+/// This value will always be a multiple of 8.
+///
+/// \param[in] i_string The string to compress. Scan data to compress is
+/// left-justified in this input string.
+///
+/// \param[in] i_length The length of the input string in \e bits. It is
+/// assumed the \a i_string contains at least (\a i_length + 7) / 8 bytes.
+///
+/// \param[in] i_scanSelect The 64-bit value written to the Scan Select
+/// register to set up for the scan. Only the 32 high-order bits are actually
+/// stored.
+///
+/// \param[in] i_ringId The ring ID that uniquely identifies the ring name of
+/// a repair ring. (See p8_ring_identification.c for more info.)
+///
+/// \param[in] i_chipletId The 7-bit value for the iv_chipletId field of the
+/// CompressedScanData.
+///
+/// \param[in] i_flushOptimization This input parameter should be set to a
+/// non-0 value if it is known that this ring difference will be applied to a
+/// scan-0 flush state. This will improve the performance of the
+/// decompress-scan routine. If the initial state of the ring is unknown, set
+/// this parameter to 0.
+///
+/// \returns See \ref scan_compression_codes
+int
+rs4_compress(CompressedScanData** o_data,
+ uint32_t* o_size,
+ const uint8_t* i_string,
+ const uint32_t i_length,
+ const uint64_t i_scanSelect,
+ const uint8_t i_ringId,
+ const uint8_t i_chipletId,
+ const uint8_t i_flushOptimization);
+
+
+/// Decompress a scan string compressed using the RS4 compression algorithm
+///
+/// \param[in,out] io_string A caller-supplied data area to contain the
+/// decompressed string. The \a i_stringSize must be large enough to contain
+/// the decompressed string, which is the size of the original string in bits
+/// rounded up to the nearest byte.
+///
+/// \param[in] i_stringSize The size (in bytes) of \a i_string.
+///
+/// \param[out] o_length The length of the decompressed string in \e bits.
+///
+/// \param[in] i_data A pointer to the CompressedScanData header + data to be
+/// decompressed.
+///
+/// This API is required for integration with PHYP which does not support
+/// malloc(). Applications in environments supporting malloc() can use
+/// rs4_decompress() instead.
+///
+/// \returns See \ref scan_compression_codes
+int
+_rs4_decompress(uint8_t* i_string,
+ uint32_t i_stringSize,
+ uint32_t* o_length,
+ const CompressedScanData* i_data);
+
+
+/// Decompress a scan string compressed using the RS4 compression algorithm
+///
+/// \param[out] o_string The API malloc()-s this data area to contain the
+/// decompressed string. After this call the caller owns \a o_string and is
+/// responsible for free()-ing this data area once it is no longer required.
+///
+/// \param[out] o_length The length of the decompressed string in \e bits.
+/// The caller may assume that \a o_string contains at least (\a o_length + 7)
+/// / 8 \e bytes.
+///
+/// \param[in] i_data A pointer to the CompressedScanData header + data to be
+/// decompressed.
+///
+/// \returns See \ref scan_compression_codes
+int
+rs4_decompress(uint8_t** o_string,
+ uint32_t* o_length,
+ const CompressedScanData* i_data);
+
+
+/// Determine if an RS4 compressed scan string is all 0
+///
+/// \param[in] i_data A pointer to the CompressedScanData header + data to be
+///
+/// \param[out] o_redundant Set to 1 if the RS4 string is the compressed form
+/// of a scan string that is all 0; Otherwise set to 0.
+///
+/// \returns See \ref scan _compression_code
+int
+rs4_redundant(const CompressedScanData* i_data, int* o_redundant);
+
+
+#endif // __ASSEMBLER__
+
+
+/// The current version of the CompressedScanData structure
+///
+/// This constant is required to be a #define to guarantee consistency between
+/// the header format and cmopiled code.
+#define COMPRESSED_SCAN_DATA_VERSION 1
+
+/// The size of the CompressedScanData structure
+CONST_UINT8_T(COMPRESSED_SCAN_DATA_SIZE, 24);
+
+
+/// \defgroup scan_compression_magic Scan Compression Magic Numbers
+///
+/// @ {
+
+/// RS4 Magic
+CONST_UINT32_T(RS4_MAGIC, 0x52533401); /* "RS4" + Version 0x01 */
+
+/// @}
+
+
+/// \defgroup scan_compression_codes Scan Compression Return Codes
+///
+/// @{
+
+/// Normal return code
+CONST_UINT8_T(SCAN_COMPRESSION_OK, 0);
+
+/// The (de)compression algorithm could not allocate enough memory for the
+/// (de)compression.
+CONST_UINT8_T(SCAN_COMPRESSION_NO_MEMORY, 1);
+
+/// Magic number mismatch on scan decompression
+CONST_UINT8_T(SCAN_DECOMPRESSION_MAGIC_ERROR, 2);
+
+/// Decompression size error
+///
+/// Decompression produced a string of a size different than indicated in the
+/// header, indicating either a bug or data corruption. Note that the entire
+/// application should be considered corrupted if this error occurs since it
+/// may not be discovered until after the decompression buffer is
+/// overrun. This error may also be returned by rs4_redundant() in the event
+/// of inconsistencies in the compressed string.
+CONST_UINT8_T(SCAN_DECOMPRESSION_SIZE_ERROR, 3);
+
+/// A buffer would overflow
+///
+/// Either the caller-supplied memory buffer to _rs4_decompress() was too
+/// small to contain the decompressed string, or a caller-supplied buffer to
+/// _rs4_compress() was not large enough to hold the worst-case compressed
+/// string.
+CONST_UINT8_T(SCAN_COMPRESSION_BUFFER_OVERFLOW, 4);
+
+/// @}
+
+#endif // __P8_SCAN_COMPRESSION_H__
diff --git a/src/ppe/tools/image/ppeSetFixed.pl b/src/ppe/tools/image/ppeSetFixed.pl
new file mode 100755
index 0000000..4315a8c
--- /dev/null
+++ b/src/ppe/tools/image/ppeSetFixed.pl
@@ -0,0 +1,234 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/image/ppeSetFixed.pl $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# Purpose: This perl script will parse the attribute and default list and
+# and set the default values into the image.
+
+use strict;
+
+my $attrpath = "../../importtemp/xml";
+my $sbedefaultpath = "../../script/image";
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 3)
+{
+ print ("Usage: ppeSetFixed.pl <image> <attributes and default list> <attribute file> ...\n");
+ print (" This perl script will the attributes and default list to lookup the defaults\n");
+ print (" and parse the attribute file to lookup the types.\n");
+ print (" The default values will be set in the image.\n");
+ print ("example:\n");
+ print ("./ppeSetFixed.pl \\\n" );
+ print (". \\\n" );
+ print (" ../../sbe/obj/seeprom_main.bin \\\n" );
+ print ("$attrpath/p9_ppe_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/perv_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/proc_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/ex_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/eq_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/core_attributes.xml \n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+
+my $xmlFiles = 0;
+my $attCount = 0;
+my $numIfAttrFiles = 0;
+my @attrChipIds;
+my @attrExIds;
+my @attrCoreIds;
+my @attrEqIds;
+my @attrPervIds;
+
+
+
+#------------------------------------------------------------------------------
+# Element names
+#------------------------------------------------------------------------------
+my $attribute = 'attribute';
+
+#------------------------------------------------------------------------------
+# For each argument
+#------------------------------------------------------------------------------
+my $sbedefaultpath = $ARGV[0];
+my $image = $ARGV[1];
+my $argfile = $ARGV[2];
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+
+if ( ! -e $image) {die "ppeSetFixed.pl: $image $!"};
+
+foreach my $entr (@{$entries->{entry}}) {
+
+ my $inname = $entr->{name};
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+ foreach my $argnum (3 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ if ( ! -e $infile) {die "ppeSetFixed.pl: $infile $!"};
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+ if($attr->{id} eq $inname) {
+
+ #------------------------------------------------------------------
+ # Check that the AttributeId exists
+ #------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("ppeSbeFixed.pl ERROR. Att 'id' missing\n");
+ exit(1);
+ }
+
+
+ if($attr->{targetType} eq "TARGET_TYPE_PROC_CHIP") {
+
+ push(@attrChipIds, $entr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_CORE") {
+
+ push(@attrCoreIds, $entr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_EQ") {
+
+ push(@attrEqIds, $entr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_EX") {
+
+ push(@attrExIds, $entr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_PERV") {
+
+ push(@attrPervIds, $entr);
+
+ } else {
+
+ print ("ppeSetFixed.pl ERROR. Wrong attribute type: $attr->{targetType}\n");
+ exit(1);
+
+ }
+
+ }
+ }
+ }
+
+}
+
+
+
+setFixed("TARGET_TYPE_PROC_CHIP", @attrChipIds);
+setFixed("TARGET_TYPE_CORE", @attrCoreIds);
+setFixed("TARGET_TYPE_EQ", @attrEqIds);
+setFixed("TARGET_TYPE_EX", @attrExIds);
+setFixed("TARGET_TYPE_PERV", @attrPervIds);
+
+
+
+sub setFixed {
+
+ my ($string, @entries) = @_;
+
+foreach my $attr (@entries)
+{
+
+ my $inname = $attr->{name};
+
+ my @values = $attr->{value};
+
+
+ if(scalar @values > 0) {
+
+ foreach my $val (@values)
+ {
+
+ if(defined $val && ref($val) eq "") {
+
+ if ($val =~ /(0x)?[0-9a-fA-F]+/) {
+
+ my $systemRc = system("$sbedefaultpath/sbe_default_tool $image $inname $val $string 0");
+
+ if ($systemRc) {
+ print "sbe_default_tool: error in execution\n";
+ exit 1;
+ }
+
+ } else {
+ print ("ppeSetFixed.pl ERROR. not hex\n");
+ exit(1);
+ }
+
+ } elsif(defined $val && ref($val) eq "ARRAY") {
+
+ my $index = 0;
+
+ foreach my $arr (@{$val}) {
+
+ if(defined $arr && ref($arr) eq "") {
+ if ($arr =~ /(0x)?[0-9a-fA-F]+/) {
+
+ my $systemRc = system("$sbedefaultpath/sbe_default_tool $image $inname $arr $string $index");
+
+ if ($systemRc) {
+ print "sbe_default_tool: error in execution\n";
+ exit 1;
+ }
+
+
+ }
+ }
+ $index++;
+ }
+
+
+
+ }
+
+
+ }
+ }
+
+
+}
+
+}
+
+
diff --git a/src/ppe/tools/image/sbe_default_tool.c b/src/ppe/tools/image/sbe_default_tool.c
new file mode 100644
index 0000000..d0e728d
--- /dev/null
+++ b/src/ppe/tools/image/sbe_default_tool.c
@@ -0,0 +1,310 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/image/sbe_default_tool.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// \file sbe_default_tool.c
+/// \brief SBE-XIP image setter tool for attributes in fixed section
+///
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <endian.h>
+
+
+#define __PPE__
+#include "fapi2.H"
+#include "proc_sbe_fixed.H"
+
+const char* g_usage =
+"Usage: sbe_default_tool <image> <attribute> <value> <target type> <index>\n"
+"The 'image' is the binary image with fixed section.\n"
+"\n"
+"The 'attribute' is the attribute to be set.\n"
+"\n"
+"The 'value' is the value of the attribute to be set.\n"
+"\n"
+"The 'target type' is the type of the target. The following targets are defined:\n"
+"TARGET_TYPE_PROC_CHIP: chip target\n"
+"TARGET_TYPE_PERV: pervasive target\n"
+"TARGET_TYPE_CORE: core target\n"
+"TARGET_TYPE_EQ: eq target\n"
+"TARGET_TYPE_EX: ex target\n"
+"\n"
+"The 'index' is the index of the value. Checking is performed.\n"
+"example:\n"
+"./sbe_default_tool ./sbe_main.bin ATTR_PLL_RING 0x33CAFE34 TARGET_TYPE_PERV 0\n"
+"./sbe_default_tool ./sbe_main.bin ATTR_SCRATCH_UINT8_1 12 TARGET_TYPE_PROC_CHIP 0\n"
+ ;
+
+
+void assertTarget(const char* str, unsigned int index)
+{
+
+ if(strcmp(str, "TARGET_TYPE_PROC_CHIP") == 0) {
+ if (index > 0) {
+ fprintf(stderr, "sbe_default_tool: index is larger than 0\n");
+ exit(1);
+ }
+ return;
+ } else if(strcmp(str, "TARGET_TYPE_EX") == 0) {
+ if (index >= EX_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index is larger than EX_TARGET_COUNT\n");
+ exit(1);
+ }
+ return;
+ } else if(strcmp(str, "TARGET_TYPE_EQ") == 0) {
+ if (index >= EQ_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index is larger than EQ_TARGET_COUNT\n");
+ exit(1);
+ }
+ return;
+ } else if(strcmp(str, "TARGET_TYPE_CORE") == 0) {
+ if (index >= CORE_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index is larger than EQ_TARGET_COUNT\n");
+ exit(1);
+ }
+ return;
+ } else if(strcmp(str, "TARGET_TYPE_PERV") == 0) {
+ if (index >= PERV_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index is larger than PERV_TARGET_COUNT\n");
+ exit(1);
+ }
+ return;
+ } else {
+
+ if (index >= PERV_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: target not supported:");
+ fprintf(stderr, " %s\n", str);
+ exit(1);
+ }
+ }
+}
+
+void setAttribute(void* image, const char* attribute, unsigned int index, uint64_t val) {
+
+
+ SbeXipItem item;
+ void *thePointer;
+ int rc;
+
+ rc = sbe_xip_find(image, attribute, &item);
+ if (rc) {
+ fprintf(stderr, "sbe_default_tool: attribute not existing:");
+ fprintf(stderr, " %s", attribute);
+ exit(1);
+ }
+
+ // debug purpose
+ //printf("offset in string section: 0x%x \n", be32toh(item.iv_toc->iv_id));
+ //printf("address: 0x%x \n", item.iv_address);
+
+ sbe_xip_image2host(image, item.iv_address, &thePointer);
+
+ // debug purpose
+ //printf("pointer1: 0x%x \n", thePointer);
+ //printf("val: 0x%llx \n", val);
+
+ if(item.iv_toc->iv_type == SBE_XIP_UINT8) {
+
+ *((uint8_t*)thePointer + index) = (uint8_t)val;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_INT8) {
+
+ *((int8_t*)thePointer + index) = (int8_t)val;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_UINT16) {
+
+ *((uint16_t*)thePointer + index) = (uint16_t)val;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_INT16) {
+
+ *((int16_t*)thePointer + index) = (int16_t)val;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_UINT32) {
+
+ *((uint32_t*)thePointer + index) = (uint32_t)val;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_INT32) {
+
+ *((int32_t*)thePointer + index) = (int32_t)val;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_UINT64) {
+
+ *((uint64_t*)thePointer + index) = (uint64_t)val;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_INT64) {
+
+ *((int64_t*)thePointer + index) = (int64_t)val;
+
+ } else {
+ fprintf(stderr, "sbe_default_tool: type not available");
+ exit(1);
+ }
+
+
+
+
+ SBE_XIP_SECTION_NAMES(section_name);
+ SBE_XIP_TYPE_STRINGS(type_name);
+
+ // debug purpose
+ //printf("pointer2: 0x%x \n", thePointer);
+ //printf("section id: %s \n", section_name[item.iv_toc->iv_section]);
+ //printf("location in section: 0x%x \n", be32toh(item.iv_toc->iv_data));
+ //printf("type name: %s \n", type_name[item.iv_toc->iv_type]);
+
+ return;
+}
+
+
+uint64_t getAttribute(void* image, const char* attribute, unsigned int index) {
+
+ uint64_t val = 0;
+
+ SbeXipItem item;
+ void *thePointer;
+ int rc;
+
+ rc = sbe_xip_find(image, attribute, &item);
+ if (rc) {
+ fprintf(stderr, "sbe_default_tool: attribute not existing:");
+ fprintf(stderr, " %s", attribute);
+ exit(1);
+ }
+
+ sbe_xip_image2host(image, item.iv_address, &thePointer);
+
+ if(item.iv_toc->iv_type == SBE_XIP_UINT8) {
+
+ val = *((uint8_t*)thePointer + index);
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_INT8) {
+
+ val = *((int8_t*)thePointer + index);
+ val &= 0xFF;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_UINT16) {
+
+ val = *((uint16_t*)thePointer + index);
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_INT16) {
+
+ val = *((int16_t*)thePointer + index);
+ val &= 0xFFFF;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_UINT32) {
+
+ val = *((uint32_t*)thePointer + index);
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_INT32) {
+
+ val = *((int32_t*)thePointer + index);
+ val &= 0xFFFFFFFF;
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_UINT64) {
+
+ val = *((uint64_t*)thePointer + index);
+
+ } else if(item.iv_toc->iv_type == SBE_XIP_INT64) {
+
+ val = *((int64_t*)thePointer + index);
+
+ } else {
+ fprintf(stderr, "sbe_default_tool: type not available");
+ exit(1);
+ }
+
+
+
+ return val;
+}
+
+int main(int argc, const char** argv)
+{
+
+ int fileFd, rc;
+ void* image;
+ struct stat buf;
+
+ if(argc != 6) {
+ fprintf(stderr, "sbe_default_tool: argument missing\n");
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+
+ printf("sbe_default_tool %s %s %s %s %s\n", argv[1], argv[2], argv[3], argv[4], argv[5]);
+
+ fileFd = open(argv[1], O_RDWR);
+ if (fileFd < 0) {
+ fprintf(stderr, "sbe_default_tool: open() of the file to be appended failed");
+ exit(1);
+ }
+
+ rc = fstat(fileFd, &buf);
+ if (rc) {
+ fprintf(stderr, "sbe_default_tool: fstat() of the file to be appended failed");
+ exit(1);
+ }
+
+ image = mmap(0, buf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fileFd, 0);
+ if (image == MAP_FAILED) {
+ fprintf(stderr, "sbe_default_tool: mmap() of the file to be appended failed");
+ exit(1);
+ }
+
+
+ uint64_t val=strtoull(argv[3], 0, 0);
+
+ unsigned int index = strtoul(argv[5], 0, 10);
+
+ assertTarget(argv[4], index);
+
+ setAttribute(image, argv[2], index, val);
+
+ uint64_t check = getAttribute(image, argv[2], index);
+
+ if((check & val) != check) {
+
+ fprintf(stderr, "sbe_default_tool: set and get values not equal");
+ fprintf(stderr, "%lx != %lx\n", check, val);
+ exit(1);
+
+ }
+
+ rc = close(fileFd);
+ if (rc) {
+ fprintf(stderr, "sbe_default_tool: close() of modified image failed");
+ exit(1);
+ }
+
+
+ return 0;
+}
diff --git a/src/ppe/tools/image/sbe_xip_tool.c b/src/ppe/tools/image/sbe_xip_tool.c
new file mode 100644
index 0000000..111d9a8
--- /dev/null
+++ b/src/ppe/tools/image/sbe_xip_tool.c
@@ -0,0 +1,2135 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/image/sbe_xip_tool.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: sbe_xip_tool.c,v 1.13 2014/06/27 20:50:16 maploetz Exp $
+
+/// \file sbe_xip_tool.c
+/// \brief SBE-XIP image search/edit tool
+///
+/// Note: This file was originally stored under .../procedures/ipl/sbe. It
+/// was moved here at version 1.19.
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+
+#define __PPE__
+#include "fapi2.H"
+#include "proc_sbe_fixed.H"
+#include "sbe_xip_image.h"
+
+#include "sbe_link.H"
+#include "p9_image_help_base.H"
+#include "p9_ring_identification.H"
+#include "p9_scan_compression.H"
+
+// Usage: sbe_xip_tool <image> [-<flag> ...] normalize
+// sbe_xip_tool <image> [-<flag> ...] get <item>
+// sbe_xip_tool <image> [-<flag> ...] getv <item> <index>
+// sbe_xip_tool <image> [-<flag> ...] set <item> <value> [ <item1> <value1> ... ]
+// sbe_xip_tool <image> [-<flag> ...] setv <item> <index> <value> [ <item1> <index1> <value1> ... ]
+// sbe_xip_tool <image> [-<flag> ...] report [<regex>]
+// sbe_xip_tool <image> [-<flag> ...] append <section> <file>
+// sbe_xip_tool <image> [-<flag> ...] extract <section> <file>
+// sbe_xip_tool <image> [-<flag> ...] delete [ <section0> ... <sectionN> ]
+// sbe_xip_tool <image> [-<flag> ...] dis <section or .rings_summary>\n"//
+//
+// This simple application uses the SBE-XIP image APIs to normalize, search
+// update and edit SBE-XIP images. This program encapsulates several commands
+// in a common command framework which requires an image to operate on, a
+// command name, and command arguments that vary by command. Commands that
+// modify the image always rewrite the image in-place in the filesystem;
+// however the original image is only modified if the command has completed
+// without error.
+//
+// The program operates on an SBE-XIP format binary image, which must be
+// normalized - unless the tool is being called to normalize the image in the
+// first place using the 'normalize' command. The tool also validates the
+// image prior to operating on the image.
+//
+// The 'get' command retrieves a scalar value from the image and prints its
+// representation on stdout (followed by a newline). Scalar integer values
+// and image addresses are printed as hex numbers (0x...). Strings are printed
+// verbatim.
+//
+// The 'getv' command retrieves a vector element from the image and prints its
+// representation on stdout (followed by a newline). Integer values
+// and image addresses are printed as hex numbers (0x...). Vectors of strings
+// are not supported.
+//
+// The 'set' command allows setting integer and string values in the image.
+// New integer values can be specified in decimal or hex (0x...). Strings are
+// taken verbatim from the command line. Note that new string values will be
+// silently truncated to the length of the current string if the new value is
+// longer than the current string. Updating address values is currently not
+// supported. Any number of item/value pairs can be specified with a single
+// 'set' command.
+//
+// The 'setv' command is provided to set individual vector elements of
+// integral arrays.
+//
+// The 'report' command prints a report including a dump of the header and
+// section table, a listing of the types and values of all items that appear
+// in the TOC. The TOC listing includes the
+// sequence number of the entry in the TOC, the item name, the item type and
+// the item value.
+//
+// The 'append' command either creates or extends the section named by the
+// section argument, by appending the contents of the named file verbatim.
+// Currently the section must either be the final (highest address) section of
+// the image, or must be empty, in which case the append command creates the
+// section as the final section of the image. The 'append' command writes the
+// relocatable image address where the input file was loaded to stdout.
+//
+// The 'extract' command extracts a sections from the binary image.
+//
+// The 'delete' command deletes 0 or more sections, starting with <section0>.
+// Each section to be deleted must either be the final (highest address)
+// section of the image at the time it is deleted, or must be empty. The
+// 'delete' command writes the size of the final modified image to stdout.
+//
+// The 'dis' command disassembles the section named by the section argument.
+// Note that the section name .rings_summary, which is not an actual XIP
+// section name, merely indicates to summarize the .rings section.
+//
+// The following -i<flag> are supported:
+// -ifs
+// causes the validation step to ignore image size check against the file
+// size.
+// -iv
+// causes all validation checking to be ignored. (Skips validation step.)
+
+const char* g_usage =
+"Usage: sbe_xip_tool <image> [-i<flag> ...] normalize\n"
+" sbe_xip_tool <image> [-i<flag> ...] get <item>\n"
+" sbe_xip_tool <image> [-i<flag> ...] getv <item> <index>\n"
+" sbe_xip_tool <image> [-i<flag> ...] set <item> <value> [ <item1> <value1> ... ]\n"
+" sbe_xip_tool <image> [-i<flag> ...] setv <item> <index> <value> [ <item1> <index1> <value1> ... ]\n"
+" sbe_xip_tool <image> [-i<flag> ...] report [<regex>]\n"
+" sbe_xip_tool <image> [-i<flag> ...] append <section> <file>\n"
+" sbe_xip_tool <image> [-i<flag> ...] extract <section> <file>\n"
+" sbe_xip_tool <image> [-i<flag> ...] delete [ <section0> ... <sectionN> ]\n"
+" sbe_xip_tool <image> [-i<flag> ...] dis <section or .rings_summary>\n"//\n"
+"\n"
+"This simple application uses the SBE-XIP image APIs to normalize, search\n"
+"update and edit SBE-XIP images. This program encapsulates several commands\n"
+"in a common command framework which requires an image to operate on, a\n"
+"command name, and command arguments that vary by command. Commands that\n"
+"modify the image always rewrite the image in-place in the filesystem;\n"
+"however the original image is only modified if the command has completed\n"
+"without error.\n"
+"\n"
+"The program operates on an SBE-XIP format binary image, which must be\n"
+"normalized - unless the tool is being called to normalize the image in the\n"
+"first place using the 'normalize' command. The tool also validates the\n"
+"image prior to operating on the image.\n"
+"\n"
+"The 'get' command retrieves a scalar value from the image and prints its\n"
+"representation on stdout (followed by a newline). Scalar integer values\n"
+"and image addresses are printed as hex numbers (0x...). Strings are printed\n"
+"verbatim.\n"
+"\n"
+"The 'getv' command retrieves a vector element from the image and prints its\n"
+"representation on stdout (followed by a newline). Integer values\n"
+"and image addresses are printed as hex numbers (0x...). Vectors of strings\n"
+"are not supported.\n"
+"\n"
+"The 'set' command allows setting integer and string values in the image.\n"
+"New integer values can be specified in decimal or hex (0x...). Strings are\n"
+"taken verbatim from the command line. Note that new string values will be\n"
+"silently truncated to the length of the current string if the new value is\n"
+"longer than the current string. Updating address values is currently not\n"
+"supported. Any number of item/value pairs can be specified with a single\n"
+"'set' command.\n"
+"\n"
+"The 'setv' command is provided to set individual vector elements of\n"
+"integral arrays.\n"
+"\n"
+"The 'report' command prints a report including a dump of the header and\n"
+"section table, a listing of the types and values of all items that appear\n"
+"in the TOC. The TOC listing includes the\n"
+"sequence number of the entry in the TOC, the item name, the item type and\n"
+"the item value.\n"
+"\n"
+"The 'append' command either creates or extends the section named by the\n"
+"section argument, by appending the contents of the named file verbatim.\n"
+"Currently the section must either be the final (highest address) section of\n"
+"the image, or must be empty, in which case the append command creates the\n"
+"section as the final section of the image. The 'append' command writes the\n"
+"relocatable image address where the input file was loaded to stdout.\n"
+"\n"
+"The 'extract' command extracs a sections from a binary image.\n"
+"\n"
+"The 'delete' command deletes 0 or more sections, starting with <section0>.\n"
+"Each section to be deleted must either be the final (highest address)\n"
+"section of the image at the time it is deleted, or must be empty. The\n"
+"'delete' command writes the size of the final modified image to stdout.\n"
+"\n"
+"The 'dis' command disassembles the section named by the section argument.\n"
+"Note that the section name .rings_summary, which is not an actual XIP\n"
+"section name, merely indicates to summarize the .rings section.\n"
+"\n"
+"-i<flag>:\n"
+"\t-ifs Causes the validation step to ignore image size check against the\n"
+"\tfile size.\n"
+"\t-iv Causes all validation checking to be ignored.\n"
+ ;
+
+SBE_XIP_ERROR_STRINGS(g_errorStrings);
+SBE_XIP_TYPE_STRINGS(g_typeStrings);
+SBE_XIP_TYPE_ABBREVS(g_typeAbbrevs);
+SBE_XIP_SECTION_NAMES(g_sectionNames);
+// Disassembler error support.
+DIS_ERROR_STRINGS(g_errorStringsDis);
+
+#define ERRBUF_SIZE 60
+
+typedef struct {
+ int index;
+ int regex;
+ regex_t preg;
+} ReportControl;
+
+off_t g_imageSize;
+
+
+// Byte-reverse a 32-bit integer if on an LE machine
+inline uint32_t
+myRev32(const uint32_t i_x)
+{
+ uint32_t rx;
+
+#ifdef _BIG_ENDIAN
+ rx = i_x;
+#else
+ uint8_t *pix = (uint8_t*)(&i_x);
+ uint8_t *prx = (uint8_t*)(&rx);
+
+ prx[0] = pix[3];
+ prx[1] = pix[2];
+ prx[2] = pix[1];
+ prx[3] = pix[0];
+#endif
+
+ return rx;
+}
+
+// Byte-reverse a 64-bit integer if on a little-endian machine
+inline uint64_t
+myRev64(const uint64_t i_x)
+{
+ uint64_t rx;
+
+#ifdef _BIG_ENDIAN
+ rx = i_x;
+#else
+ uint8_t *pix = (uint8_t*)(&i_x);
+ uint8_t *prx = (uint8_t*)(&rx);
+
+ prx[0] = pix[7];
+ prx[1] = pix[6];
+ prx[2] = pix[5];
+ prx[3] = pix[4];
+ prx[4] = pix[3];
+ prx[5] = pix[2];
+ prx[6] = pix[1];
+ prx[7] = pix[0];
+#endif
+
+ return rx;
+}
+
+// Normalize an SBE-XIP image. We normalize a copy of the image first so that
+// the original image will be available for debugging in case the
+// normalization fails, then validate and copy the normalized image back to
+// the mmap()-ed file.
+
+int
+normalize(void* io_image, const int i_argc, const char** i_argv, uint32_t i_maskIgnores)
+{
+ int rc;
+ void *copy;
+
+ do {
+
+ // The 'normalize' command takes no arguments
+
+ if (i_argc != 0) {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+
+ copy = malloc(g_imageSize);
+ if (copy == 0) {
+ perror("malloc() failed : ");
+ exit(1);
+ }
+
+ memcpy(copy, io_image, g_imageSize);
+
+ rc = sbe_xip_normalize(copy);
+ if (rc) break;
+
+ if ( !(i_maskIgnores & SBE_XIP_IGNORE_ALL) ) {
+ rc = sbe_xip_validate2(copy, g_imageSize, i_maskIgnores);
+ }
+ if (rc) break;
+
+ memcpy(io_image, copy, g_imageSize);
+
+ } while (0);
+
+ return rc;
+}
+
+
+// Print a line of a report, listing the index, symbol, type and current
+// value.
+
+int
+tocListing(void* io_image,
+ const SbeXipItem* i_item,
+ void* arg)
+{
+ int rc;
+ ReportControl *control;
+ uint64_t data;
+ char* s;
+
+ control = (ReportControl*)arg;
+
+ do {
+ rc = 0;
+
+ if (control->regex) {
+ if (regexec(&(control->preg), i_item->iv_id, 0, 0, 0)) {
+ break;
+ }
+ }
+
+ printf("0x%04x | %-42s | %s | ",
+ control->index, i_item->iv_id,
+ SBE_XIP_TYPE_STRING(g_typeAbbrevs, i_item->iv_type));
+
+ switch (i_item->iv_type) {
+ case SBE_XIP_UINT8:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("0x%02x", (uint8_t)data);
+ break;
+ case SBE_XIP_INT8:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("%d", (int8_t)data);
+ break;
+ case SBE_XIP_UINT16:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("0x%08x", (uint16_t)data);
+ break;
+ case SBE_XIP_INT16:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("%d", (int16_t)data);
+ break;
+ case SBE_XIP_UINT32:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("0x%08x", (uint32_t)data);
+ break;
+ case SBE_XIP_INT32:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("%d", (int32_t)data);
+ break;
+ case SBE_XIP_UINT64:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("0x%016llx", data);
+ break;
+ case SBE_XIP_INT64:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("%d", (int64_t)data);
+ break;
+ case SBE_XIP_STRING:
+ rc = sbe_xip_get_string(io_image, i_item->iv_id, &s);
+ if (rc) break;
+ printf("%s", s);
+ break;
+ case SBE_XIP_ADDRESS:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("0x%04x:0x%08x",
+ (uint16_t)((data >> 32) & 0xffff),
+ (uint32_t)(data & 0xffffffff));
+ break;
+ default:
+ printf("unknown type\n");
+ rc = SBE_XIP_BUG;
+ break;
+ }
+ printf("\n");
+ } while (0);
+ control->index += 1;
+ return rc;
+}
+
+
+// Dump the image header, including the section table
+
+int
+dumpHeader(void* i_image)
+{
+ int i;
+ SbeXipHeader header;
+ SbeXipSection* section;
+ char magicString[9];
+
+ SBE_XIP_SECTION_NAMES(section_name);
+
+ // Dump header information. Since the TOC may not exist we need to get
+ // the information from the header explicitly.
+
+ sbe_xip_translate_header(&header, (SbeXipHeader*)i_image);
+
+ memcpy(magicString, (char*)(&(((SbeXipHeader*)i_image)->iv_magic)), 8);
+ magicString[8] = 0;
+
+ printf("Magic Number : 0x%016llx \"%s\"\n",
+ header.iv_magic, magicString);
+ printf("Header Version : 0x%02x\n", header.iv_headerVersion);
+ printf("Link Address : 0x%016llx\n", header.iv_linkAddress);
+ printf("Entry Offset : 0x%08x\n", (uint32_t)header.iv_entryOffset);
+ printf("Image Size : 0x%08x (%d)\n",
+ header.iv_imageSize, header.iv_imageSize);
+ printf("Normalized : %s\n", header.iv_normalized ? "Yes" : "No");
+ printf("TOC Sorted : %s\n", header.iv_tocSorted ? "Yes" : "No");
+ printf("Build Date : %02d/%02d/%04d\n",
+ (header.iv_buildDate / 100) % 100,
+ header.iv_buildDate % 100,
+ header.iv_buildDate / 10000);
+ printf("Build Time : %02d:%02d\n",
+ header.iv_buildTime / 100,
+ header.iv_buildTime % 100);
+ printf("Build User : %s\n", header.iv_buildUser);
+ printf("Build Host : %s\n", header.iv_buildHost);
+ printf("\n");
+
+ printf("Section Table : Offset Size\n");
+ printf("\n");
+
+ for (i = 0; i < SBE_XIP_SECTIONS; i++) {
+ section = &(header.iv_section[i]);
+ printf("%-16s 0x%08x 0x%08x (%d)\n",
+ section_name[i],
+ section->iv_offset, section->iv_size, section->iv_size);
+ }
+
+ printf("\n");
+
+ return 0;
+}
+
+
+// Print a report
+
+int
+report(void* io_image, const int i_argc, const char** i_argv)
+{
+ int rc;
+ ReportControl control;
+ char errbuf[ERRBUF_SIZE];
+
+ do {
+
+ // Basic syntax check : [<regexp>]
+
+ if (i_argc > 1) {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+
+ // Compile a regular expression if supplied
+
+ if (i_argc == 1) {
+ rc = regcomp(&(control.preg), i_argv[0], REG_NOSUB);
+ if (rc) {
+ regerror(rc, &(control.preg), errbuf, ERRBUF_SIZE);
+ fprintf(stderr, "Error from regcomp() : %s\n", errbuf);
+ exit(1);
+ }
+ control.regex = 1;
+ } else {
+ control.regex = 0;
+
+ dumpHeader(io_image);
+ printf("TOC Report\n\n");
+ }
+
+ // Map the TOC with the mapReport() function
+
+ control.index = 0;
+ rc = sbe_xip_map_toc(io_image, tocListing, (void*)(&control));
+ if (rc) break;
+
+ } while (0);
+
+ return rc;
+}
+
+
+// Set a scalar or vector element values in the image. The 'i_setv' argument
+// indicates set/setv (0/1).
+
+int
+set(void* io_image, const int i_argc, const char** i_argv, int i_setv)
+{
+ int rc, arg, base, clause_args, index_val;
+ SbeXipItem item;
+ unsigned long long newValue;
+ const char *key, *index, *value;
+ char *endptr;
+
+ do {
+
+ // Basic syntax check: <item> <value> [ <item1> <value1> ... ]
+ // Basic syntax check: <item> <index> <value> [ <item1> <index1> <value1> ... ]
+
+ clause_args = (i_setv ? 3 : 2);
+
+ if ((i_argc % clause_args) != 0) {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+
+ for (arg = 0; arg < i_argc; arg += clause_args) {
+
+ key = i_argv[arg];
+ if (i_setv) {
+ index = i_argv[arg + 1];
+ index_val = strtol(index, 0, 0);
+ value = i_argv[arg + 2];
+ } else {
+ index = "";
+ index_val = 0;
+ value = i_argv[arg + 1];
+ }
+
+ // Search for the item to see what type of data it expects, then
+ // case split on the type.
+
+ rc = sbe_xip_find(io_image, key, &item);
+ if (rc) break;
+
+ if (index_val < 0) {
+ fprintf(stderr,
+ "Illegal negative vector index %s for %s\n",
+ index, key);
+ exit(1);
+ } else if ((item.iv_elements != 0) &&
+ (index_val >= item.iv_elements)) {
+ fprintf(stderr,
+ "Index %s out-of-bounds for %s (%d elements)\n",
+ index, key, item.iv_elements);
+ exit(1);
+ }
+
+ switch (item.iv_type) {
+ case SBE_XIP_UINT8:
+ case SBE_XIP_UINT16:
+ case SBE_XIP_UINT32:
+ case SBE_XIP_UINT64:
+
+ // We need to do a bit of preprocessing on the string to
+ // determine its format and set the base for strtoull(),
+ // otherwise strtoull() will be confused by leading zeros
+ // e.g. in time strings generated by `date +%H%M`, and try to
+ // process the string as octal.
+
+ if ((strlen(value) >= 2) && (value[0] == '0') &&
+ ((value[1] == 'x') || (value[1] == 'X'))) {
+ base = 16;
+ } else {
+ base = 10;
+ }
+
+ errno = 0;
+ newValue = strtoull(value, &endptr, base);
+ if ((errno != 0) || (endptr != (value + strlen(value)))) {
+ fprintf(stderr,
+ "Error parsing putative integer value : %s\n",
+ value);
+ exit(1);
+ }
+
+ switch (item.iv_type) {
+
+ case SBE_XIP_UINT8:
+ if ((uint8_t)newValue != newValue) {
+ fprintf(stderr,
+ "Value 0x%016llx too large for 8-bit type\n",
+ newValue);
+ exit(1);
+ }
+ break;
+
+ case SBE_XIP_UINT16:
+ if ((uint16_t)newValue != newValue) {
+ fprintf(stderr,
+ "Value 0x%016llx too large for 16-bit type\n",
+ newValue);
+ exit(1);
+ }
+ break;
+
+ case SBE_XIP_UINT32:
+ if ((uint32_t)newValue != newValue) {
+ fprintf(stderr,
+ "Value 0x%016llx too large for 32-bit type\n",
+ newValue);
+ exit(1);
+ }
+ break;
+
+ case SBE_XIP_UINT64:
+ break;
+
+ default:
+ break;
+ }
+
+ rc = sbe_xip_set_element(io_image, key, index_val, newValue);
+ if (rc) rc = SBE_XIP_BUG;
+ break;
+
+ case SBE_XIP_STRING:
+
+ if (i_setv) {
+ fprintf(stderr, "Can't use 'setv' for string data %s\n",
+ key);
+ exit(1);
+ }
+ rc = sbe_xip_set_string(io_image, key, (char*)value);
+ if (rc) rc = SBE_XIP_BUG;
+ break;
+ case SBE_XIP_INT8:
+ case SBE_XIP_INT16:
+ case SBE_XIP_INT32:
+ case SBE_XIP_INT64:
+ fprintf(stderr,
+ "Item %s has int type %s, "
+ "which is not supported for '%s'.\n",
+ i_argv[arg],
+ SBE_XIP_TYPE_STRING(g_typeStrings, item.iv_type),
+ (i_setv ? "setv" : "set"));
+ exit(1);
+ break;
+ default:
+ fprintf(stderr,
+ "Item %s has type %s, "
+ "which is not supported for '%s'.\n",
+ i_argv[arg],
+ SBE_XIP_TYPE_STRING(g_typeStrings, item.iv_type),
+ (i_setv ? "setv" : "set"));
+ exit(1);
+ break;
+ }
+
+ if (rc) break;
+
+ }
+ } while (0);
+
+ //if good rc, we need to msync the mmaped file to push contents to
+ //the actual file. Per man page this is required although some
+ //file systems (notably AFS) don't seem to require (GSA does)
+ if(!rc)
+ {
+ uint8_t i = 0;
+ do {
+ rc = msync(io_image, g_imageSize , MS_SYNC);
+ if(rc)
+ {
+ i++;
+ fprintf(stderr,
+ "msync failed with errno %d\n", errno);
+ }
+ } while(rc && i < 5);
+
+ if(rc)
+ {
+ exit(3);
+ }
+ }
+
+ return rc;
+}
+
+
+// Get a value from the image, and return on stdout. The 'i_getv' argument
+// indicates get/getv (0/1)
+
+int
+get(void* i_image, const int i_argc, const char** i_argv, int i_getv)
+{
+ int rc, nargs, index_val;
+ SbeXipItem item;
+ const char *key, *index;
+ uint64_t data;
+ char* s;
+
+ do {
+
+ // Basic syntax check: <item>
+ // Basic syntax check: <item> <index>
+
+ nargs = (i_getv ? 2 : 1);
+
+ if (i_argc != nargs) {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+
+ key = i_argv[0];
+ if (i_getv) {
+ index = i_argv[1];
+ index_val = strtol(index, 0, 0);
+ } else {
+ index = "";
+ index_val = 0;
+ }
+
+ // Search for the item to determine its type, then case split on the
+ // type.
+
+ rc = sbe_xip_find(i_image, key, &item);
+ if (rc) break;
+
+ if (index_val < 0) {
+ fprintf(stderr,
+ "Illegal negative vector index %s for %s\n",
+ index, key);
+ exit(1);
+ } else if ((item.iv_elements != 0) &&
+ (index_val >= item.iv_elements)) {
+ fprintf(stderr, "Index %s out-of-bounds for %s (%d elements)\n",
+ index, key, item.iv_elements);
+ exit(1);
+ }
+
+ switch (item.iv_type) {
+
+ case SBE_XIP_UINT8:
+ case SBE_XIP_UINT16:
+ case SBE_XIP_UINT32:
+ case SBE_XIP_UINT64:
+ rc = sbe_xip_get_element(i_image, key, index_val, &data);
+ if (rc) {
+ rc = SBE_XIP_BUG;
+ break;
+ }
+ switch (item.iv_type) {
+ case SBE_XIP_UINT8:
+ printf("0x%02x\n", (uint8_t)data);
+ break;
+ case SBE_XIP_UINT16:
+ printf("0x%04x\n", (uint16_t)data);
+ break;
+ case SBE_XIP_UINT32:
+ printf("0x%08x\n", (uint32_t)data);
+ break;
+ case SBE_XIP_UINT64:
+ printf("0x%016llx\n", data);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case SBE_XIP_ADDRESS:
+ if (i_getv) {
+ fprintf(stderr, "Can't use 'getv' for address data : %s\n",
+ key);
+ exit(1);
+ }
+ rc = sbe_xip_get_scalar(i_image, key, &data);
+ if (rc) {
+ rc = SBE_XIP_BUG;
+ break;
+ }
+ printf("0x%012llx\n", data);
+ break;
+
+ case SBE_XIP_STRING:
+ if (i_getv) {
+ fprintf(stderr, "Can't use 'getv' for string data : %s\n",
+ key);
+ exit(1);
+ }
+ rc = sbe_xip_get_string(i_image, key, &s);
+ if (rc) {
+ rc = SBE_XIP_BUG;
+ break;
+ }
+ printf("%s\n", s);
+ break;
+ case SBE_XIP_INT8:
+ case SBE_XIP_INT16:
+ case SBE_XIP_INT32:
+ case SBE_XIP_INT64:
+ fprintf(stderr, "%s%d : Bug, int types not implemented %d\n",
+ __FILE__, __LINE__, item.iv_type);
+ exit(1);
+ break;
+ default:
+ fprintf(stderr, "%s%d : Bug, unexpected type %d\n",
+ __FILE__, __LINE__, item.iv_type);
+ exit(1);
+ break;
+ }
+ } while (0);
+
+ return rc;
+}
+
+
+// strtoul() with application-specific error handling
+
+unsigned long
+localStrtoul(const char* s)
+{
+ unsigned long v;
+ char* endptr;
+
+ errno = 0;
+ v = strtoul(s, &endptr, 0);
+ if ((errno != 0) || (endptr != (s + strlen(s)))) {
+ fprintf(stderr,
+ "Error parsing putative integer value : %s\n",
+ s);
+ exit(1);
+ }
+ return v;
+}
+
+
+// Append a file to section
+int
+append(const char* i_imageFile, const int i_imageFd, void* io_image,
+ int i_argc, const char** i_argv)
+{
+ int fileFd, newImageFd, sectionId, rc;
+ struct stat buf;
+ const char* section;
+ const char* file;
+ void* appendImage;
+ void* newImage;
+ uint32_t size, newSize, sectionOffset;
+ uint64_t homerAddress;
+
+ do {
+
+ // Basic syntax check: <section> <file>
+
+ if (i_argc != 2) {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+ section = i_argv[0];
+ file = i_argv[1];
+
+ // Translate the section name to a section Id
+
+ for (sectionId = 0; sectionId < SBE_XIP_SECTIONS; sectionId++) {
+ if (strcmp(section, g_sectionNames[sectionId]) == 0) {
+ break;
+ }
+ }
+ if (sectionId == SBE_XIP_SECTIONS) {
+ fprintf(stderr, "Unrecognized section name : '%s;\n",
+ section);
+ exit(1);
+ }
+
+
+ // Open and mmap the file to be appended
+
+ fileFd = open(file, O_RDONLY);
+ if (fileFd < 0) {
+ perror("open() of the file to be appended failed : ");
+ exit(1);
+ }
+
+ rc = fstat(fileFd, &buf);
+ if (rc) {
+ perror("fstat() of the file to be appended failed : ");
+ exit(1);
+ }
+
+ appendImage = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, fileFd, 0);
+ if (appendImage == MAP_FAILED) {
+ perror("mmap() of the file to be appended failed : ");
+ exit(1);
+ }
+
+
+ // malloc() a buffer for the new image, adding space for alignment
+
+ rc = sbe_xip_image_size(io_image, &size);
+ if (rc) break;
+
+ newSize = size + buf.st_size + SBE_XIP_MAX_SECTION_ALIGNMENT;
+
+ newImage = malloc(newSize);
+
+ if (newImage == 0) {
+ fprintf(stderr, "Can't malloc() a buffer for the new image\n");
+ exit(1);
+ }
+
+
+ // Copy the image. At this point the original image file must be
+ // closed.
+
+ memcpy(newImage, io_image, size);
+
+ rc = close(i_imageFd);
+ if (rc) {
+ perror("close() of the original image file failed : ");
+ exit(1);
+ }
+
+
+ // Do the append and print the image address where the data was loaded.
+ // We will not fail for unaligned addresses, as we have no knowledge
+ // of whether or why the user wants the final image address.
+
+ rc = sbe_xip_append(newImage, sectionId,
+ appendImage, buf.st_size,
+ newSize, &sectionOffset);
+ if (rc) break;
+
+ rc = sbe_xip_section2image(newImage, sectionId, sectionOffset,
+ &homerAddress);
+ if (rc && (rc != SBE_XIP_ALIGNMENT_ERROR)) break;
+
+ printf("0x%016llx\n", homerAddress);
+
+
+ // Now write the new image back to the filesystem
+
+ newImageFd = open(i_imageFile, O_WRONLY | O_TRUNC);
+ if (newImageFd < 0) {
+ perror("re-open() of image file failed : ");
+ exit(1);
+ }
+
+ rc = sbe_xip_image_size(newImage, &size);
+ if (rc) break;
+
+ rc = write(newImageFd, newImage, size);
+ if ((rc < 0) || ((uint32_t)rc != size)) {
+ perror("write() of modified image failed : ");
+ exit(1);
+ }
+
+ rc = close(newImageFd);
+ if (rc) {
+ perror("close() of modified image failed : ");
+ exit(1);
+ }
+ } while (0);
+
+ return rc;
+}
+
+// Extract section from a file
+int
+extract(const char* i_imageFile, const int i_imageFd, void* io_image,
+ int i_argc, const char** i_argv)
+{
+ int fileFd, newImageFd, sectionId, rc;
+ void* newImage;
+ const char* section;
+ const char* file;
+ struct stat buf;
+ SbeXipHeader header;
+ SbeXipSection* xSection;
+ uint32_t size;
+ uint32_t offset;
+ unsigned int i;
+
+ do {
+
+ if (i_argc != 2) {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+ section = i_argv[0];
+ file = i_argv[1];
+
+ printf("%s %s\n", section , file);
+
+ for (sectionId = 0; sectionId < SBE_XIP_SECTIONS; sectionId++) {
+ if (strcmp(section, g_sectionNames[sectionId]) == 0) {
+ break;
+ }
+ }
+ if (sectionId == SBE_XIP_SECTIONS) {
+ fprintf(stderr, "Unrecognized section name : '%s;\n",
+ section);
+ exit(1);
+ }
+
+ sbe_xip_translate_header(&header, (SbeXipHeader*)io_image);
+
+ for (i = 0; i < SBE_XIP_SECTIONS; i++) {
+ xSection = &(header.iv_section[i]);
+
+ if (strcmp(section, g_sectionNames[i]) == 0) {
+
+ size = xSection->iv_size;
+ offset = xSection->iv_offset;
+
+ printf("%-16s 0x%08x 0x%08x (%d)\n",
+ g_sectionNames[i],
+ xSection->iv_offset, xSection->iv_size, xSection->iv_size);
+
+ break;
+ }
+ }
+
+ newImage = malloc(size);
+
+ if (newImage == 0) {
+ fprintf(stderr, "Can't malloc() a buffer for the new image\n");
+ exit(1);
+ }
+
+ memcpy(newImage, (void*)((uint64_t)io_image + offset), size);
+
+ fileFd = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0755);
+ if (fileFd < 0) {
+ perror("open() of the fixed section : ");
+ exit(1);
+ }
+
+ rc = write(fileFd, newImage, size);
+ if ((rc < 0) || ((uint32_t)rc != size)) {
+ perror("write() of fixed section : ");
+ exit(1);
+ }
+
+ rc = close(fileFd);
+ if (rc) {
+ perror("close() of fixed section : ");
+ exit(1);
+ }
+
+ } while (0);
+
+ return rc;
+
+}
+
+
+// Delete 0 or more sections in order.
+
+int
+deleteSection(const char* i_imageFile, const int i_imageFd, void* io_image,
+ int i_argc, const char** i_argv)
+{
+ int newImageFd, sectionId, rc, argc;
+ const char* section;
+ const char** argv;
+ void* newImage;
+ uint32_t size;
+
+ do {
+
+ // malloc() a buffer for the new image
+
+ rc = sbe_xip_image_size(io_image, &size);
+ if (rc) break;
+
+ newImage = malloc(size);
+
+ if (newImage == 0) {
+ fprintf(stderr, "Can't malloc() a buffer for the new image\n");
+ exit(1);
+ }
+
+
+ // Copy the image. At this point the original image file must be
+ // closed.
+
+ memcpy(newImage, io_image, size);
+
+ rc = close(i_imageFd);
+ if (rc) {
+ perror("close() of the original image file failed : ");
+ exit(1);
+ }
+
+ // Delete the sections in argument order
+
+ for (argc = i_argc, argv = i_argv; argc != 0; argc--, argv++) {
+
+ // Translate the section name to a section Id
+
+ section = *argv;
+
+ for (sectionId = 0; sectionId < SBE_XIP_SECTIONS; sectionId++) {
+ if (strcmp(section, g_sectionNames[sectionId]) == 0) {
+ break;
+ }
+ }
+ if (sectionId == SBE_XIP_SECTIONS) {
+ fprintf(stderr, "Unrecognized section name : '%s;\n",
+ section);
+ exit(1);
+ }
+
+ // Delete the section
+
+ rc = sbe_xip_delete_section(newImage, sectionId);
+ if (rc) break;
+ }
+ if (rc) break;
+
+ // Print the final size of the new image
+
+ rc = sbe_xip_image_size(newImage, &size);
+ if (rc) break;
+
+ printf("%u\n", size);
+
+ // Now write the new image back to the filesystem
+
+ newImageFd = open(i_imageFile, O_WRONLY | O_TRUNC);
+ if (newImageFd < 0) {
+ perror("re-open() of image file failed : ");
+ exit(1);
+ }
+
+ rc = write(newImageFd, newImage, size);
+ if ((rc < 0) || ((uint32_t)rc != size)) {
+ perror("write() of modified image failed : ");
+ exit(1);
+ }
+
+ rc = close(newImageFd);
+ if (rc) {
+ perror("close() of modified image failed : ");
+ exit(1);
+ }
+ } while (0);
+
+ return rc;
+}
+
+
+// 'TEST' is an undocumented command provided to test the APIs. It searches
+// and modifies a copy of the image but puts the image back together as it
+// was, then verifies that the the original image and the copy are identical.
+
+#define BOMB_IF(test) \
+ if (test) { \
+ fprintf(stderr, "%s:%d : Error in TEST\n", \
+ __FILE__, __LINE__); \
+ exit(1); \
+ }
+
+#define BOMB_IF_RC \
+ if (rc) { \
+ fprintf(stderr, "%s:%d : Error in TEST, rc = %s\n", \
+ __FILE__, __LINE__, \
+ SBE_XIP_ERROR_STRING(g_errorStrings, rc)); \
+ exit(1); \
+ }
+
+
+int
+TEST(void* io_image, const int i_argc, const char** i_argv)
+{
+ int rc;
+ uint64_t linkAddress, entryPoint, data, data1, magicKey, entry_offset[2];
+ char *key, *revision, *revdup, *longString, *shortString;
+ void *originalImage, *deleteAppendImage;
+ uint32_t imageSize;
+ SbeXipItem item;
+ SbeXipHeader header;
+ SbeXipSection section;
+ //ProcSbeFixed* fixed;
+ uint32_t tocSize;
+
+ do {
+ rc = sbe_xip_image_size(io_image, &imageSize);
+ BOMB_IF_RC;
+ originalImage = malloc(imageSize);
+ BOMB_IF(originalImage == 0);
+ memcpy(originalImage, io_image, imageSize);
+
+ rc = sbe_xip_get_scalar(io_image, "toc_sorted", &data);
+ BOMB_IF_RC;
+ BOMB_IF(data != 1);
+
+ rc = sbe_xip_get_scalar(io_image, "image_size", &data);
+ BOMB_IF_RC;
+ BOMB_IF(data != (uint64_t)g_imageSize);
+
+ rc = sbe_xip_get_scalar(io_image, "magic", &magicKey);
+ BOMB_IF_RC;
+
+ switch (magicKey) {
+ case SBE_BASE_MAGIC:
+ key = (char*)"proc_sbe_fabricinit_revision";
+ rc = sbe_xip_get_string(io_image, key, &revision);
+ BOMB_IF_RC;
+ BOMB_IF(strncmp(revision, "1.", 2) != 0);
+ break;
+ case SBE_SEEPROM_MAGIC:
+ key = (char*)"";
+ // Can't do this test here as the TOC has been stripped
+ break;
+ case SBE_CENTAUR_MAGIC:
+ key = (char*)"cen_sbe_initf_revision";
+ rc = sbe_xip_get_string(io_image, key, &revision);
+ BOMB_IF_RC;
+ BOMB_IF(strncmp(revision, "1.", 2) != 0);
+ break;
+ default:
+ BOMB_IF(1);
+ break;
+ }
+
+ rc = sbe_xip_get_scalar(io_image, "link_address", &linkAddress);
+ BOMB_IF_RC;
+ if (magicKey != SBE_SEEPROM_MAGIC) {
+ rc = sbe_xip_get_scalar(io_image, "entry_point", &entryPoint);
+ BOMB_IF_RC;
+ }
+ rc = sbe_xip_get_scalar(io_image, "entry_offset", &data);
+ BOMB_IF_RC;
+ BOMB_IF((magicKey != SBE_SEEPROM_MAGIC) && (entryPoint != (linkAddress + data)));
+
+ rc =
+ sbe_xip_set_scalar(io_image, "toc_sorted", 0) ||
+ sbe_xip_set_scalar(io_image, "image_size", 0);
+ BOMB_IF_RC;
+
+ data = 0;
+ data += (rc = sbe_xip_get_scalar(io_image, "toc_sorted", &data), data);
+ BOMB_IF_RC;
+ data += (rc = sbe_xip_get_scalar(io_image, "image_size", &data), data);
+ BOMB_IF_RC;
+ BOMB_IF(data != 0);
+
+ // Write back keys found during read check.
+
+ rc =
+ sbe_xip_set_scalar(io_image, "toc_sorted", 1) ||
+ sbe_xip_set_scalar(io_image, "image_size", g_imageSize);
+ BOMB_IF_RC;
+
+ // We'll rewrite the revision keyword with a long string and a short
+ // string, and verify that rewriting is being done correctly. In the
+ // end we copy the original revision string back in, which is safe
+ // because the memory allocation for strings does not change when they
+ // are modified.
+
+ revdup = strdup(revision);
+ longString = (char*)"A very long string";
+ shortString = (char*)"?";
+
+ if (magicKey != SBE_SEEPROM_MAGIC) {
+ rc =
+ sbe_xip_set_string(io_image, key, longString) ||
+ sbe_xip_get_string(io_image, key, &revision);
+ BOMB_IF_RC;
+ BOMB_IF((strlen(revision) != strlen(revdup)) ||
+ (strncmp(revision, longString, strlen(revdup)) != 0));
+
+ rc =
+ sbe_xip_set_string(io_image, key, shortString) ||
+ sbe_xip_get_string(io_image, key, &revision);
+ BOMB_IF_RC;
+ BOMB_IF(strcmp(revision, shortString) != 0);
+
+ memcpy(revision, revdup, strlen(revdup) + 1);
+ }
+
+ // Use sbe_xip_[read,write]_uint64 to modify the image and restore it
+ // to its original form.
+
+ rc = sbe_xip_find(io_image, "entry_offset", &item);
+ BOMB_IF_RC;
+ rc = sbe_xip_get_scalar(io_image, "entry_offset", &(entry_offset[0]));
+ BOMB_IF_RC;
+
+ rc = sbe_xip_read_uint64(io_image, item.iv_address, &(entry_offset[1]));
+ BOMB_IF_RC;
+ BOMB_IF(entry_offset[0] != entry_offset[1]);
+
+ rc = sbe_xip_write_uint64(io_image, item.iv_address,
+ 0xdeadbeefdeadc0deull);
+ BOMB_IF_RC;
+ rc = sbe_xip_read_uint64(io_image, item.iv_address, &(entry_offset[1]));
+ BOMB_IF_RC;
+ BOMB_IF(entry_offset[1] != 0xdeadbeefdeadc0deull);
+
+ rc = sbe_xip_write_uint64(io_image, item.iv_address, entry_offset[0]);
+ BOMB_IF_RC;
+
+ // Try sbe_xip_get_section against the translated header
+
+ sbe_xip_translate_header(&header, (SbeXipHeader*)io_image);
+ rc = sbe_xip_get_section(io_image, SBE_XIP_SECTION_TOC, &section);
+ BOMB_IF_RC;
+ BOMB_IF((section.iv_size !=
+ header.iv_section[SBE_XIP_SECTION_TOC].iv_size));
+
+
+ // Make sure the .fixed section access compiles and seems to
+ // work. Modify an entry via the .fixed and verify it with normal TOC
+ // access.
+
+ if (magicKey == SBE_SEEPROM_MAGIC) {
+
+ BOMB_IF(0 != 0);
+
+ exit(1);
+
+ rc = sbe_xip_get_scalar(io_image, "proc_sbe_ex_dpll_initf_control",
+ &data);
+ BOMB_IF_RC;
+ //fixed =
+ //(ProcSbeFixed*)((unsigned long)io_image + SBE_XIP_FIXED_OFFSET);
+ //fixed->proc_sbe_ex_dpll_initf_control = 0xdeadbeefdeadc0deull;
+ rc = sbe_xip_get_scalar(io_image, "proc_sbe_ex_dpll_initf_control",
+ &data1);
+ BOMB_IF_RC;
+#ifdef _BIG_ENDIAN
+ BOMB_IF(data1 != 0xdeadbeefdeadc0deull);
+#else
+ BOMB_IF(data1 != 0xdec0addeefbeaddeull);
+#endif
+ rc = sbe_xip_set_scalar(io_image, "proc_sbe_ex_dpll_initf_control",
+ data);
+ BOMB_IF_RC;
+ }
+
+ // Temporarily "delete" the .toc section and try to get/set via the
+ // mini-TOC for .fixed, and make sure that we can't get things that
+ // are not in the mini-toc.
+
+ tocSize =
+ ((SbeXipHeader*)io_image)->iv_section[SBE_XIP_SECTION_TOC].iv_size;
+
+ ((SbeXipHeader*)io_image)->iv_section[SBE_XIP_SECTION_TOC].iv_size =
+ 0;
+
+ rc = sbe_xip_get_scalar(io_image, "proc_sbe_ex_dpll_initf_control",
+ &data);
+ rc = sbe_xip_set_scalar(io_image, "proc_sbe_ex_dpll_initf_control",
+ 0xdeadbeef);
+ rc = sbe_xip_get_scalar(io_image, "proc_sbe_ex_dpll_initf_control",
+ &data1);
+ BOMB_IF(data1 != 0xdeadbeef);
+ rc = sbe_xip_set_scalar(io_image, "proc_sbe_ex_dpll_initf_control",
+ data);
+ BOMB_IF_RC;
+
+ BOMB_IF(sbe_xip_find(io_image, "proc_sbe_ex_dpll_initf", 0) !=
+ SBE_XIP_ITEM_NOT_FOUND);
+
+ ((SbeXipHeader*)io_image)->iv_section[SBE_XIP_SECTION_TOC].iv_size =
+ tocSize;
+
+ if (magicKey != SBE_SEEPROM_MAGIC) {
+ BOMB_IF(sbe_xip_find(io_image, "proc_sbe_ex_dpll_initf", 0) != 0);
+ }
+
+
+#ifdef DEBUG_SBE_XIP_IMAGE
+ printf("\nYou will see an expected warning below "
+ "about SBE_XIP_WOULD_OVERFLOW\n"
+ "It means the TEST is working (not failing)\n\n");
+#endif
+
+ // Finally compare against the original
+
+ BOMB_IF(memcmp(io_image, originalImage, imageSize));
+
+ } while (0);
+
+ return rc;
+}
+
+
+/// Function: pairRingNameAndAddr() to be used w/sbe_xip_map_toc()
+///
+/// Brief: Looks for address match for both base and override rings and
+/// for multi-chiplet rings. Returns the ring name and other good
+/// stuff in the PairingInfo structure upon a match.
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_item A pointer to the "next" SbeXipItem in the TOC.
+///
+/// \param[io] io_pairing A pointer to the structure, PairingInfo.
+///
+/// Assumptions:
+/// - On input, io_pairing contains
+/// - address = the backPtr of the next ring block,
+/// - vectorpos = the next vector position, starting from 0,1,2,..,31 and
+/// which includes possible override pos.
+/// - The TOC is then traversed and each TOC entry is put into i_item.
+/// - The backPtr in io_pairing is kept constant until TOC has been exhausted.
+/// - On output, io_pairing contains
+/// - name = TOC name
+/// - isvpd = whether it's a VPD or non-VPD ring
+/// - overridable = whether it's an overridable ring
+/// - override = whether it's a base or an override ring
+/// - In general, we don't know if a ring is a base or an override of if it is a
+/// multi-chiplet type. Thus, we first look for a match to the vector in
+/// in position zero, then we try position one, then position two, ..., and up
+/// to a max of position 31 (which would be an override for ex chiplet 0x1F).
+///
+static int pairRingNameAndAddr( void *i_image, const SbeXipItem *i_item, void *io_pairing)
+{
+ int rc=0,rcLoc=-1;
+ SbeXipItem tocItem;
+ PairingInfo *pairingInfo;
+ RingIdList *ringIdList;
+
+ SBE_XIP_ERROR_STRINGS(g_errorStrings);
+
+ rcLoc = sbe_xip_find( i_image, i_item->iv_id, &tocItem);
+ if (rcLoc) {
+ fprintf( stderr, "sbe_xip_find() failed : %s\n", SBE_XIP_ERROR_STRING(g_errorStrings, rcLoc));
+ rc = DIS_RING_NAME_ADDR_MATCH_FAILURE;
+ }
+ else {
+ pairingInfo = (PairingInfo*)io_pairing;
+ // Do a sanity check.
+ if (pairingInfo->vectorpos>31) {
+ fprintf( stderr, "vectorpos (=%i) must be between [0;31]\n",pairingInfo->vectorpos);
+ rc = DIS_RING_NAME_ADDR_MATCH_FAILURE;
+ }
+ // Check for match.
+ // - vectorpos is passed in such that first we look for base match, then for override
+ // or chiplet range match.
+ if (tocItem.iv_address == pairingInfo->address-8*pairingInfo->vectorpos &&
+ tocItem.iv_id!=NULL ) {
+ pairingInfo->name = tocItem.iv_id;
+ rcLoc = get_vpd_ring_list_entry(pairingInfo->name,0,&ringIdList);
+ if (!rcLoc) {
+ // It is a VPD ring...and they never have overrides.
+ pairingInfo->isvpd = 1;
+ pairingInfo->overridable = 0;
+ }
+ else {
+ // It is a non-VPD ring...and they all have override capability.
+ pairingInfo->isvpd = 0;
+ pairingInfo->overridable = 1;
+ }
+ if (pairingInfo->vectorpos==0)
+ // This can only be a base match.
+ pairingInfo->override = 0;
+ else {
+ // This is not a base match. Investigating further if override. (Note,
+ // this includes a multi-dim vector with multi-dim override.)
+ if (pairingInfo->overridable &&
+ 2*(pairingInfo->vectorpos/2)!=pairingInfo->vectorpos)
+ pairingInfo->override = 1;
+ else
+ pairingInfo->override = 0;
+ }
+ rc = DIS_RING_NAME_ADDR_MATCH_SUCCESS;
+ }
+ }
+ return rc;
+}
+
+// this function is just defined out, because there is a future need.
+#ifdef BLUBBER
+/// Function: disassembleSection
+///
+/// Brief: Disassembles a section and returns a pointer to a buffer that
+/// contains the listing.
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_argc Additional number of arguments beyond "dis" keyword.
+///
+/// \param[in] i_argv Additional arguments beyond "dis" keyword.
+///
+/// Assumptions:
+///
+int disassembleSection(void *i_image,
+ int i_argc,
+ const char **i_argv)
+{
+ int rc=0, rcSet=0;
+ uint32_t rcCount=0;
+ char *disList=NULL;
+ uint32_t sizeSection=0, nextLinkOffsetBlock=0;
+ uint32_t sizeBlock=0, sizeData=0, sizeCode=0, sizeData2=0;
+ uint32_t sizeDisLine=0, sizeList=0, sizeListMax=0;
+ uint32_t offsetCode=0;
+ uint8_t typeRingsSection=0; // 0: RS4 1: Wiggle-Flip
+ uint8_t bSummary=0, bFoundInToc=0;
+ uint32_t sectionId;
+ uint64_t backPtr=0, fwdPtr=0;
+ PairingInfo pairingInfo;
+ const char *sectionName;
+ char *ringName;
+ uint32_t ringSeqNo=0; // Ring sequence location counter.
+ uint8_t vectorPos,overRidable;
+ void *nextBlock, *nextSection;
+ SbeXipHeader hostHeader;
+ SbeXipSection hostSection;
+ ImageInlineContext ctx;
+ ImageInlineDisassembly dis;
+ char lineDis[LISTING_STRING_SIZE];
+ void *hostRs4Container;
+ uint32_t compressedBits=0, ringLength=0;
+ double compressionPct=0;
+
+ if (i_argc != 1) {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+ sectionName = i_argv[0];
+
+ // Determine SBE-XIP section ID from the section name, e.g.
+ // .loader_text => SBE_XIP_SECTION_LOADER_TEXT
+ // .text => SBE_XIP_SECTION_TEXT
+ // .rings => SBE_XIP_SECTION_RINGS
+ if (strcmp(sectionName, ".header")==0)
+ sectionId = SBE_XIP_SECTION_HEADER;
+ else
+ if (strcmp(sectionName, ".fixed")==0)
+ sectionId = SBE_XIP_SECTION_FIXED;
+ else
+ if (strcmp(sectionName, ".fixed_toc")==0)
+ sectionId = SBE_XIP_SECTION_FIXED_TOC;
+ else
+ if (strcmp(sectionName, ".loader_text")==0)
+ sectionId = SBE_XIP_SECTION_LOADER_TEXT;
+ else
+ if (strcmp(sectionName, ".loader_data")==0)
+ sectionId = SBE_XIP_SECTION_LOADER_DATA;
+ else
+ if (strcmp(sectionName, ".text")==0)
+ sectionId = SBE_XIP_SECTION_TEXT;
+ else
+ if (strcmp(sectionName, ".data")==0)
+ sectionId = SBE_XIP_SECTION_DATA;
+ else
+ if (strcmp(sectionName, ".toc")==0)
+ sectionId = SBE_XIP_SECTION_TOC;
+ else
+ if (strcmp(sectionName, ".strings")==0)
+ sectionId = SBE_XIP_SECTION_STRINGS;
+ else
+ if (strcmp(sectionName, ".base")==0)
+ sectionId = SBE_XIP_SECTION_BASE;
+ else
+ if (strcmp(sectionName, ".baseloader")==0)
+ sectionId = SBE_XIP_SECTION_BASELOADER;
+ else
+ if (strcmp(sectionName, ".rings")==0)
+ sectionId = SBE_XIP_SECTION_RINGS;
+ else
+ if (strcmp(sectionName, ".rings_summary")==0) {
+ sectionId = SBE_XIP_SECTION_RINGS;
+ bSummary = 1;
+ }
+ else
+ if (strcmp(sectionName, ".overlays")==0)
+ sectionId = SBE_XIP_SECTION_OVERLAYS;
+ else {
+ fprintf(stderr,"ERROR : %s is an invalid section name.\n",sectionName);
+ fprintf(stderr,"Valid <section> names for the 'dis' function are:\n");
+ fprintf(stderr,"\t.header\n");
+ fprintf(stderr,"\t.fixed\n");
+ fprintf(stderr,"\t.fixed_toc\n");
+ fprintf(stderr,"\t.loader_text\n");
+ fprintf(stderr,"\t.loader_data\n");
+ fprintf(stderr,"\t.text\n");
+ fprintf(stderr,"\t.data\n");
+ fprintf(stderr,"\t.toc\n");
+ fprintf(stderr,"\t.strings\n");
+ fprintf(stderr,"\t.base\n");
+ fprintf(stderr,"\t.baseloader\n");
+ fprintf(stderr,"\t.overlays\n");
+ fprintf(stderr,"\t.rings\n");
+ fprintf(stderr,"\t.rings_summary\n");
+ exit(1);
+ }
+
+ // Get host header and section pointer.
+ //
+ sbe_xip_translate_header( &hostHeader, (SbeXipHeader*)i_image);
+ rc = sbe_xip_get_section( i_image, sectionId, &hostSection);
+ if (rc) {
+ fprintf( stderr, "sbe_xip_get_section() failed : %s\n", SBE_XIP_ERROR_STRING(g_errorStrings, rc));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+ sizeSection = hostSection.iv_size;
+ nextBlock = (void*)(hostSection.iv_offset + (uintptr_t)i_image);
+ nextSection = (void*)((uint64_t)nextBlock + (uint64_t)sizeSection);
+
+ // Relocatable offset of section at hand.
+ nextLinkOffsetBlock = (uint32_t)hostHeader.iv_linkAddress + hostSection.iv_offset;
+
+ // Allocate buffer to hold disassembled listing. (Start out with minimum 10k buffer size.)
+ //
+ if (sizeSection>10000)
+ sizeListMax = sizeSection; // Just to use something as an initial guess.
+ else
+ sizeListMax = 10000;
+ disList = (char*)malloc(sizeListMax);
+ if (disList==NULL) {
+ fprintf( stderr, "ERROR : malloc() failed.\n");
+ fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_MEMORY_ERROR));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+ *disList = '\0'; // Make sure the buffer is NULL terminated (though probably not needed.)
+ sizeList = 0;
+
+ // Create context and point it to image section.
+ //
+ rc = image_inline_context_create( &ctx,
+ nextBlock,
+ sizeSection,
+ nextLinkOffsetBlock,
+ 0);
+ if (rc) {
+ fprintf( stderr, "ERROR : %s (rc=%i)\n",image_inline_error_strings[rc],rc);
+ fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_ERROR));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+
+ while ((uint64_t)nextBlock<(uint64_t)nextSection) {
+
+ // Disassemble sections based on their types and intents.
+ //
+ if (sectionId==SBE_XIP_SECTION_RINGS || sectionId==SBE_XIP_SECTION_OVERLAYS) {
+ // Ring section (with a mix of data and code.)
+ // ...use BaseRingLayout structure to decode each ring block.
+ offsetCode = (uint32_t)myRev64(((BaseRingLayout*)nextBlock)->entryOffset);
+ sizeBlock = myRev32(((BaseRingLayout*)nextBlock)->sizeOfThis);
+ // ...determine ring type, either RS4 or Wiggle-flip.
+ if (offsetCode-(myRev32(((BaseRingLayout*)nextBlock)->sizeOfMeta)+3)/4*4>28) {
+ typeRingsSection = 0; // RS4 w/32-byte header.
+ sizeData2 = sizeBlock - offsetCode - ASM_RS4_LAUNCH_BUF_SIZE;
+ }
+ else
+ typeRingsSection = 1; // Wiggle-flip w/24-byte header.
+ // ...get the backPtr and fwdPtr and put at top of disasm listing.
+ backPtr = myRev64(((BaseRingLayout*)nextBlock)->backItemPtr);
+ sbe_xip_read_uint64(i_image,
+ backPtr,
+ &fwdPtr);
+
+ // Calculate RS4 compression efficiency if RS4 rings.
+ if (typeRingsSection==0) {
+ hostRs4Container = (void*)( (uintptr_t)nextBlock +
+ offsetCode + ASM_RS4_LAUNCH_BUF_SIZE );
+ compressedBits = myRev32(((CompressedScanData*)hostRs4Container)->iv_algorithmReserved) * 4;
+ ringLength = myRev32(((CompressedScanData*)hostRs4Container)->iv_length);
+ compressionPct = (double)compressedBits / (double)ringLength * 100.0;
+ }
+
+ //
+ // Map over TOC or do a targeted search of FIXED_TOC to pair backPtr addr
+ // with ring name and override and/or vector position (i.e. multi-chiplet).
+ //
+ sbe_xip_get_section( i_image, SBE_XIP_SECTION_TOC, &hostSection);
+ if (hostSection.iv_offset) {
+ // TOC exists.
+ pairingInfo.address = backPtr;
+ // Search for pairing. First exhaust base position (pos=0), then next, then next, ...
+ for (pairingInfo.vectorpos=0;pairingInfo.vectorpos<32;pairingInfo.vectorpos++) {
+ rc = sbe_xip_map_toc( i_image, pairRingNameAndAddr, (void*)(&pairingInfo));
+ if (rc)
+ break;
+ }
+ if (rc==DIS_RING_NAME_ADDR_MATCH_FAILURE) {
+ fprintf( stderr,"ERROR : Error associated with sbe_xip_map_toc().\n");
+ fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_RING_NAME_ADDR_MATCH_FAILURE));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+ ringSeqNo++;
+ if (rc==DIS_RING_NAME_ADDR_MATCH_SUCCESS) {
+ bFoundInToc = 1;
+ ringName = pairingInfo.name; // The ring name matched in pairRingNameAndAddr()
+ vectorPos = pairingInfo.vectorpos; // The vector position matched in pairRingNameAndAddr()
+ overRidable = pairingInfo.overridable; // Whether the ring supports on override ring.
+ if (pairingInfo.override) {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = %s (override)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
+ ringSeqNo, ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
+ }
+ else {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = %s (base)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
+ ringSeqNo,ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
+ }
+ }
+ else {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = Not found (but TOC's available)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n",
+ ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr);
+ }
+ }
+ else {
+ // TOC doesn't exist. First try targeted search of MVPD ring names in FIXED_TOC.
+ bFoundInToc = 0; // If we find in fixed_toc, then change to 1.
+ // 2012-11-13: CMO TBD. Try using pairRingNameAndAddr by enabling a sequential
+ // traversing of each of the MVPD lists inside that function. You'll
+ // need to call pairRing manually from right here (or from a
+ // sbe_xip_search_fixed_toc()-like function). Maybe you can add a
+ // 4th arg to pairRing that is zero by default, meaning it is to be
+ // used by xip_map_toc(). But if non-zero, it is to be used in a
+ // traversing manner. Or you could add another member to the
+ // PairingInfo struct to indirectly pass this info to the function.
+ // You'd also need to pass two more arguments to get_vpd_ring_list_
+ // entry() to indicate sequence number and the MVPD keyword.
+ // rc = pairRingNameAndAddr();
+ // if (rc==DIS_RING_NAME_ADDR_MATCH_SUCCESS) {
+ // bFoundInToc = 1;
+ // // Do same as in TOC section above.
+ // break;
+ // }
+ // // OK, so ring name wasn't in TOC nor in FIXED_TOC. That happens if the ring
+ // // is a non-Mvpd ring and the TOC has been removed, such as in an IPL or
+ // // Seeprom image.
+ ringSeqNo++;
+ if (typeRingsSection==0) {
+ // RS4 header, which has override info
+ if (((Rs4RingLayout*)nextBlock)->override==0) {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = Not available (base)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
+ ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
+ }
+ else {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = Not available (override)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
+ ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
+ }
+ }
+ else {
+ // WF header, which doesn't have override info
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName and override = Not available\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n",
+ ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr);
+ }
+ }
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ }
+ else if ( sectionId==SBE_XIP_SECTION_LOADER_TEXT ||
+ sectionId==SBE_XIP_SECTION_TEXT) {
+ // Sections that have only code.
+ offsetCode = 0;
+ sizeBlock = sizeSection;
+ }
+ else {
+ // Sections that have only data.
+ offsetCode = sizeSection;
+ sizeBlock = sizeSection;
+ }
+ sizeData = offsetCode;
+ sizeCode = sizeBlock - offsetCode - sizeData2;
+
+ if (sectionId==SBE_XIP_SECTION_RINGS && bSummary) {
+ //
+ // Summarize rings section.
+
+ if (typeRingsSection==0) { // RS4 header.
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ddLevel = 0x%02x\n# override= %i\n# sysPhase= %i\n# Block size= %i\n",
+ myRev32(((Rs4RingLayout*)nextBlock)->ddLevel),
+ ((Rs4RingLayout*)nextBlock)->override,
+ ((Rs4RingLayout*)nextBlock)->sysPhase,
+ sizeBlock);
+ }
+ else { // WF header.
+ if (bFoundInToc) {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# override= %i\n# Block size= %i\n",
+ pairingInfo.override, sizeBlock);
+ }
+ else {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# override= Not available\n# Block size= %i\n",
+ sizeBlock);
+ }
+ }
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ // Readjust list buffer size, if needed.
+ if (sizeList > sizeListMax-1000) {
+ sizeListMax = 2*sizeListMax;
+ disList = (char*)realloc( (void*)(disList), sizeListMax);
+ }
+
+ }
+ else {
+ //
+ // Do disassembly.
+
+ // ...data disassembly
+ if (sizeData>0) {
+ ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA;
+ do {
+ rc = image_inline_disassemble( &ctx, &dis);
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ if (rc) {
+ rcSet = rcSet | 0x1;
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n",
+ image_inline_error_strings[rc],rc,sectionId);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ }
+ // Readjust list buffer size, if needed.
+ if (sizeList > sizeListMax-1000) {
+ sizeListMax = 2*sizeListMax;
+ disList = (char*)realloc( (void*)(disList), sizeListMax);
+ }
+ } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData);
+ }
+ if (rcSet)
+ rc = 0;
+
+ // ...code disassembly
+ if (sizeCode>0) {
+ ctx.options = IMAGE_INLINE_LISTING_MODE;
+ do {
+ rc = image_inline_disassemble( &ctx, &dis);
+ ctx.options = IMAGE_INLINE_LISTING_MODE;
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ if (rc && rcCount<100) {
+ rcSet = rcSet | 0x2;
+ rcCount++;
+ if (sectionId==SBE_XIP_SECTION_RINGS) {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "WARNING: %s (rc=%i) -> Trying data disasm mode. Check code, xyzRingLayout structures and image section.\n",
+ image_inline_error_strings[rc],rc);
+ }
+ else {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "WARNING: %s (rc=%i) -> Trying data disasm mode.\n",
+ image_inline_error_strings[rc],rc);
+ }
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA;
+ rc = 0;
+ }
+ else {
+ if (rc && rcCount>=1000) {
+ fprintf(stderr, "Too many disasm warnings. Check output listing.\n");
+ fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_TOO_MANY_DISASM_WARNINGS));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+ }
+ // Readjust list buffer size, if needed.
+ if (sizeList > sizeListMax-1000) {
+ sizeListMax = 2*sizeListMax;
+ disList = (char*)realloc( (void*)(disList), sizeListMax);
+ }
+ } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData+sizeCode);
+ }
+ if (rcSet)
+ rc = 0;
+
+ // ...data2 disassembly (only done for rings section if RS4 type.)
+ if (sizeData2>0) {
+ ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA;
+ do {
+ rc = image_inline_disassemble( &ctx, &dis);
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ if (rc) {
+ rcSet = rcSet | 0x4;
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n",
+ image_inline_error_strings[rc],rc,sectionId);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ }
+ // Readjust list buffer size, if needed.
+ if (sizeList > sizeListMax-1000) {
+ sizeListMax = 2*sizeListMax;
+ disList = (char*)realloc( (void*)(disList), sizeListMax);
+ }
+ } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeBlock);
+ }
+ if (rcSet)
+ rc = 0;
+
+ } // End of if (bSummary) condition.
+
+ nextBlock = (void*)((uint64_t)nextBlock + (uint64_t)sizeBlock);
+ nextLinkOffsetBlock = nextLinkOffsetBlock + sizeBlock;
+
+ } // End of while(nextBlock...) loop.
+
+ // Adjust final buffer size, add 1 for NULL char and print it.
+ if (disList) {
+ disList = (char*)realloc( (void*)(disList), sizeList+1);
+ fprintf(stdout,"%s\n",disList);
+ free(disList);
+ }
+
+ if (rcSet)
+ fprintf( stderr, "INFO : There were some hickups: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_TROUBLES));
+
+ return 0;
+
+}
+#endif
+
+// open() and mmap() the file
+
+void
+openAndMap(const char* i_fileName, int i_writable, int* o_fd, void** o_image, const uint32_t i_maskIgnores)
+{
+ int rc, openMode, mmapProt, mmapShared;
+ struct stat buf;
+
+ if (i_writable) {
+ openMode = O_RDWR;
+ mmapProt = PROT_READ | PROT_WRITE;
+ mmapShared = MAP_SHARED;
+ } else {
+ openMode = O_RDONLY;
+ mmapProt = PROT_READ;
+ mmapShared = MAP_PRIVATE;
+ }
+
+ *o_fd = open(i_fileName, openMode);
+ if (*o_fd < 0) {
+ perror("open() of the image failed : ");
+ exit(1);
+ }
+
+ rc = fstat(*o_fd, &buf);
+ if (rc) {
+ perror("fstat() of the image failed : ");
+ exit(1);
+ }
+ g_imageSize = buf.st_size;
+
+ *o_image = mmap(0, g_imageSize, mmapProt, mmapShared, *o_fd, 0);
+ if (*o_image == MAP_FAILED) {
+ perror("mmap() of the image failed : ");
+ exit(1);
+ }
+
+ if ( !(i_maskIgnores & SBE_XIP_IGNORE_ALL) ) {
+ rc = sbe_xip_validate2(*o_image, g_imageSize, i_maskIgnores);
+ if (rc) {
+ fprintf(stderr, "sbe_xip_validate2() failed : %s\n",
+ SBE_XIP_ERROR_STRING(g_errorStrings, rc));
+ exit(1);
+ }
+ }
+
+}
+
+
+static inline void
+openAndMapWritable(const char* i_imageFile, int* o_fd, void** o_image, const uint32_t i_maskIgnores)
+{
+ openAndMap(i_imageFile, 1, o_fd, o_image, i_maskIgnores);
+}
+
+
+static inline void
+openAndMapReadOnly(const char* i_imageFile, int* o_fd, void** o_image, const uint32_t i_maskIgnores)
+{
+ openAndMap(i_imageFile, 0, o_fd, o_image, i_maskIgnores);
+}
+
+
+// Parse and execute a pre-tokenized command
+
+void
+command(const char* i_imageFile, const int i_argc, const char** i_argv, const uint32_t i_maskIgnores)
+{
+ void* image;
+ int fd, rc = 0;
+
+ if (strcmp(i_argv[0], "normalize") == 0) {
+
+ openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = normalize(image, i_argc - 1, &(i_argv[1]), i_maskIgnores);
+
+ } else if (strcmp(i_argv[0], "set") == 0) {
+
+ openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = set(image, i_argc - 1, &(i_argv[1]), 0);
+
+ } else if (strcmp(i_argv[0], "setv") == 0) {
+
+ openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = set(image, i_argc - 1, &(i_argv[1]), 1);
+
+ } else if (strcmp(i_argv[0], "get") == 0) {
+
+ openAndMapReadOnly(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = get(image, i_argc - 1, &(i_argv[1]), 0);
+
+ } else if (strcmp(i_argv[0], "getv") == 0) {
+
+ openAndMapReadOnly(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = get(image, i_argc - 1, &(i_argv[1]), 1);
+
+ } else if (strcmp(i_argv[0], "report") == 0) {
+
+ openAndMapReadOnly(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = report(image, i_argc - 1, &(i_argv[1]));
+
+ } else if (strcmp(i_argv[0], "append") == 0) {
+
+ openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = append(i_imageFile, fd, image, i_argc - 1, &(i_argv[1]));
+
+ } else if (strcmp(i_argv[0], "extract") == 0) {
+
+ openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = extract(i_imageFile, fd, image, i_argc - 1, &(i_argv[1]));
+
+ } else if (strcmp(i_argv[0], "delete") == 0) {
+
+ openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = deleteSection(i_imageFile, fd, image, i_argc - 1,
+ &(i_argv[1]));
+
+ } else if (strcmp(i_argv[0], "dis") == 0) {
+
+ //openAndMapReadOnly(i_imageFile, &fd, &image, i_maskIgnores);
+ //rc = disassembleSection(image, i_argc - 1, &(i_argv[1]));
+ fprintf(stderr, "not supported\n");
+ exit(1);
+
+
+ } else if (strcmp(i_argv[0], "TEST") == 0) {
+
+ openAndMapWritable(i_imageFile, &fd, &image, i_maskIgnores);
+ rc = TEST(image, i_argc - 1, &(i_argv[1]));
+
+ } else {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+ if (rc) {
+ fprintf(stderr, "Command failed : %s\n",
+ SBE_XIP_ERROR_STRING(g_errorStrings, rc));
+ exit(1);
+ }
+}
+
+
+// Open, map and validate the image, then parse and execute the command. The
+// image is memory-mapped read/write, i.e, it may be modified in-place.
+// Commands that modify the size of the image will close and recreate the
+// file.
+
+int
+main(int argc, const char** argv)
+{
+ uint8_t argcMin, idxArgvFlagsStart;
+ uint8_t numFlags=0, idxArgv, bMoreFlags;
+ uint32_t maskIgnores=0;
+
+ argcMin = 3;
+ idxArgvFlagsStart = argcMin - 1; // -i flags must start after image file name.
+
+ numFlags = 0;
+ bMoreFlags = 1;
+ do {
+ idxArgv = idxArgvFlagsStart + numFlags;
+ if (idxArgv <= (argc-1)) {
+ if (strncmp(argv[idxArgv], "-i", 1) == 0) {
+ numFlags++;
+ bMoreFlags = 1;
+ if (strncmp(argv[idxArgv], "-ifs", 4) == 0) {
+ maskIgnores = maskIgnores | SBE_XIP_IGNORE_FILE_SIZE;
+ }
+ else
+ if (strncmp(argv[idxArgv], "-iv", 3) == 0) {
+ maskIgnores = maskIgnores | SBE_XIP_IGNORE_ALL;
+ }
+ else {
+ fprintf(stderr, g_usage);
+ fprintf(stderr, "\n");
+ fprintf(stderr,"argv[%i]=%s is an unsupported flag.",idxArgv,argv[idxArgv]);
+ fprintf(stderr,"See top of above help menu for supported flags.\n");
+ exit(1);
+ }
+ }
+ else
+ bMoreFlags = 0;
+ }
+ else {
+ bMoreFlags = 0;
+ break;
+ }
+ } while (bMoreFlags);
+
+ if ((argc < (argcMin+numFlags)) ||
+ (strncmp(argv[1], "-h", 2) == 0) ||
+ (strncmp(argv[1], "--h", 3) == 0) ) {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+
+ command(argv[1], argc - idxArgv, &(argv[idxArgv]), maskIgnores);
+
+ return 0;
+}
diff --git a/src/ppe/tools/scripts/parseErrorInfo.pl b/src/ppe/tools/scripts/parseErrorInfo.pl
new file mode 100755
index 0000000..1211940
--- /dev/null
+++ b/src/ppe/tools/scripts/parseErrorInfo.pl
@@ -0,0 +1,1511 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/scripts/parseErrorInfo.pl $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2011,2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# $Id: fapiParseErrorInfo.pl,v 1.30 2014/07/25 00:36:41 jmcgill Exp $
+# Purpose: This perl script will parse HWP Error XML files and create required
+# FAPI code.
+#
+# Author: CamVan Nguyen and Mike Jones
+# Reworked for fapi2/P9
+#
+# Usage:
+# fapiParseErrorInfo.pl <output dir> <filename1> <filename2> ...
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains
+# bugs that result in XML parse errors that can be fixed by adjusting white-
+# space (i.e. parse errors that do not make sense).
+#------------------------------------------------------------------------------
+$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use Digest::MD5 qw(md5_hex);
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+use Data::Dumper;
+use Getopt::Long;
+
+my $target_ffdc_type = "fapi2::Target<T>";
+my $buffer_ffdc_type = "fapi2::buffer";
+my $variable_buffer_ffdc_type = "fapi2::variable_buffer";
+my $ffdc_type = "fapi2::ffdc_t";
+
+# We want to keep the signatures for the ffdc gathering hwp so that
+# we can create members of the proper types for the ffdc classes.
+my %signatures = ("proc_extract_pore_halt_ffdc" => ["por_base_state",
+ "por_halt_type_t",
+ "por_ffdc_offset_t"],
+ "hwpTestFfdc1" => [$target_ffdc_type],
+ "proc_extract_pore_base_ffdc" => ["por_base_state", "por_sbe_base_state"],
+ "proc_tp_collect_dbg_data" => [$target_ffdc_type],
+ );
+
+# There are some names used in the XML files which exist in either
+# c++ keywords (case, for example) or macros (DOMAIN). The one's which
+# cause problems and need to be changed are here.
+#
+# DOMAIN is defined to 1 in math.h
+my %mangle_names = ("DOMAIN" => "FAPI2_DOMAIN");
+
+# A list of deprecated elements. These will report messages to the
+# user, and not define anything. They have not been found to be used,
+# but that doesn't mean they're not ...
+my %deprecated = ("RC_PROCPM_PMCINIT_TIMEOUT" => "CHIP_IN_ERROR is defined as a callout procedure");
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $arg_empty_ffdc = undef;
+my $arg_output_dir = undef;
+my $arg_use_variable_buffers = undef;
+
+# Get the options from the command line - the rest of @ARGV will
+# be filenames
+GetOptions("empty-ffdc-classes" => \$arg_empty_ffdc,
+ "output-dir=s" => \$arg_output_dir,
+ "use-variable-buffers" => \$arg_use_variable_buffers);
+
+my $numArgs = $#ARGV + 1;
+if (($numArgs < 1) || ($arg_output_dir eq undef))
+{
+ print ("Usage: parseErrorInfo.pl [--empty-ffdc-classes] [--use-variable-buffers] --output-dir=<output dir> <filename1> <filename2> ...\n");
+ print (" This perl script will parse HWP Error XML files and creates\n");
+ print (" the following files:\n");
+ print (" - hwp_return_codes.H. HwpReturnCode enumeration (HWP generated errors)\n");
+ print (" - hwp_error_info.H. Error information (used by FAPI_SET_HWP_ERROR\n");
+ print (" when a HWP generates an error)\n");
+ print (" - collect_reg_ffdc.C. Function to collect register FFDC\n");
+ print (" - set_sbe_error.H. Macro to create an SBE error\n");
+ print (" The --empty-ffdc-classes option is for platforms which don't collect ffdc.\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Hashes containing error names/enum-values
+#------------------------------------------------------------------------------
+my %errNameToValueHash;
+my %errValuePresentHash;
+
+#------------------------------------------------------------------------------
+# Hashes containing ffdc names/enum-values
+#------------------------------------------------------------------------------
+my %ffdcNameToValueHash;
+my %ffdcValuePresentHash;
+
+#------------------------------------------------------------------------------
+# Subroutine that checks if an entry exists in an array. If it doesn't exist
+# then it is added. The index of the entry within the array is returned
+#------------------------------------------------------------------------------
+sub addEntryToArray
+{
+ my ($arrayref, $entry ) = @_;
+
+ my $match = 0;
+ my $index = 0;
+
+ foreach my $element (@$arrayref)
+ {
+ if ($element eq $entry)
+ {
+ $match = 1;
+ last;
+ }
+ else
+ {
+ $index++;
+ }
+ }
+
+ if (!($match))
+ {
+ push(@$arrayref, $entry);
+ }
+
+ return $index;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine that figures out an error enum value from an error name and stores
+# it in global hashes
+#------------------------------------------------------------------------------
+sub setErrorEnumValue
+{
+ my $name = $_[0];
+
+ #--------------------------------------------------------------------------
+ # Check that the error name is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($errNameToValueHash{$name}))
+ {
+ # Two different errors with the same name!
+ print ("fapiParseErrorInfo.pl ERROR. Duplicate error name ", $name, "\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Figure out the error enum-value. This is a hash value generated from
+ # the error name. A hash is used for Cronus so that if a HWP is not
+ # recompiled against a new eCMD/Cronus version where the errors have
+ # changed then there will not be a mismatch in error values.
+ # This is a 24bit hash value because FAPI has a requirement that the
+ # top byte of the 32 bit error value be zero to store flags indicating
+ # the creator of the error
+ #--------------------------------------------------------------------------
+ my $errHash128Bit = md5_hex($name);
+ my $errHash24Bit = substr($errHash128Bit, 0, 6);
+
+ #--------------------------------------------------------------------------
+ # Check that the error enum-value is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($errValuePresentHash{$errHash24Bit}))
+ {
+ # Two different errors generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate error hash value\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Update the hashes with the error name and ID
+ #--------------------------------------------------------------------------
+ $errValuePresentHash{$errHash24Bit} = 1;
+ $errNameToValueHash{$name} = $errHash24Bit;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine that figures out an FFDC ID value from an FFDC name and stores it
+# in global hashes for use when creating the enumeration of FFDC IDs
+#------------------------------------------------------------------------------
+sub setFfdcIdValue
+{
+ my $name = $_[0];
+
+ #--------------------------------------------------------------------------
+ # Check that the FFDC name is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($ffdcNameToValueHash{$name}))
+ {
+ # Two different FFDCs with the same name!
+ print ("fapiParseErrorInfo.pl ERROR. Duplicate FFDC name ", $name, "\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Figure out the FFDC enum-value. This is a hash value generated from
+ # the FFDC name.
+ #--------------------------------------------------------------------------
+ my $ffdcHash128Bit = md5_hex($name);
+ my $ffdcHash32Bit = substr($ffdcHash128Bit, 0, 8);
+
+ #--------------------------------------------------------------------------
+ # Check that the error enum-value is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($ffdcValuePresentHash{$ffdcHash32Bit}))
+ {
+ # Two different FFDCs generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate FFDC hash value\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Update the hashes with the error name and ID
+ #--------------------------------------------------------------------------
+ $ffdcValuePresentHash{$ffdcHash32Bit} = 1;
+ $ffdcNameToValueHash{$name} = $ffdcHash32Bit;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine to create ffdc methods
+#------------------------------------------------------------------------------
+sub addFfdcMethod
+{
+ my $methods = shift;
+ my $ffdc_uc = shift;
+ my $class_name = shift;
+ my $type = shift;
+
+ # Remove the leading *_
+ $class_name = (split (/_/, $class_name, 2))[1];
+
+ # If we didn't get a type passed in, this element will get an ffdc_t pair.
+ $type = $ffdc_type if ($type eq undef);
+
+ # Mangle the uppercase name if needed
+ $ffdc_uc = $mangle_names{$ffdc_uc} if ($mangle_names{$ffdc_uc} ne undef);
+
+ my $key = $ffdc_uc.$type;
+ my $key_target = $ffdc_uc.$target_ffdc_type;
+ my $key_ffdc = $ffdc_uc.$ffdc_type;
+
+ # Check to see if this element already has been recorded with this
+ # type or a target type. Note the effect we're shooting for here is
+ # to define the member if it's not been defined before *or* it's
+ # changing from an ffdc_t to a target due to other information in the xml
+ return if ($methods->{$key}{type} eq $type);
+ return if ($methods->{$key_target}{type} eq $target_ffdc_type);
+
+ # Just leave if this is a variable_buffer ans we're not supporting that.
+ return if (($type eq $variable_buffer_ffdc_type) && ($arg_use_variable_buffers eq undef));
+
+ # Set the proper type, and clear out any previous members/methods if
+ # we're going from an ffdc_t to a target.
+ $methods->{$key}{type} = $type;
+ delete $methods->{$key_ffdc} if ($type eq $target_ffdc_type);
+
+ my $method = "";
+ my $method_body = "";
+
+ # If we're generating empty classes, not using an argument name will avoid the unused parameter warnings
+ my $param = ($arg_empty_ffdc eq undef) ? "i_value" : "";
+
+ if ($type eq $ffdc_type)
+ {
+ $method = "\n template< typename T >\n";
+ $method .= " inline $class_name& set_$ffdc_uc(const T& $param)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ elsif ($type eq $buffer_ffdc_type)
+ {
+ # Two methods - one for integral buffers and one for variable_buffers
+ $method = "\n template< typename T >\n";
+ $method .= " inline $class_name& set_$ffdc_uc(const fapi2::buffer<T>& $param)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ elsif ($type eq $variable_buffer_ffdc_type)
+ {
+ $method = "\n inline $class_name& set_$ffdc_uc(const fapi2::variable_buffer& $param)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n";
+
+ # No need to add the member here, it was added with fapi2::buffer. And we can't have variable
+ # buffer support with out integral buffer support (can we?)
+ }
+
+ elsif ($type eq $target_ffdc_type)
+ {
+ $method = "\n template< TargetType T >\n";
+ $method .= " inline $class_name& set_$ffdc_uc(const $type& $param)\n";
+ $method_body .= " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ else
+ {
+ print ("ffdc type $type is unknown");
+ exit(1);
+ }
+
+ $method .= ($arg_empty_ffdc eq undef) ? $method_body : " {return *this;}\n\n";
+ $methods->{$key}{method} = $method;
+}
+
+#------------------------------------------------------------------------------
+# Open output files for writing
+#------------------------------------------------------------------------------
+my $rcFile = $arg_output_dir;
+$rcFile .= "/";
+$rcFile .= "hwp_return_codes.H";
+open(RCFILE, ">", $rcFile);
+
+my $eiFile = $arg_output_dir;
+$eiFile .= "/";
+$eiFile .= "hwp_error_info.H";
+open(EIFILE, ">", $eiFile);
+
+my $ecFile = $arg_output_dir;
+$ecFile .= "/";
+$ecFile .= "hwp_ffdc_classes.H";
+open(ECFILE, ">", $ecFile);
+
+my $crFile = $arg_output_dir;
+$crFile .= "/";
+$crFile .= "collect_reg_ffdc.C";
+open(CRFILE, ">", $crFile);
+
+my $sbFile = $arg_output_dir;
+$sbFile .= "/";
+$sbFile .= "set_sbe_error.H";
+open(SBFILE, ">", $sbFile);
+
+#------------------------------------------------------------------------------
+# Print start of file information to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "// hwp_error_info.H\n";
+print EIFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print EIFILE "#ifndef FAPI2_HWPERRORINFO_H_\n";
+print EIFILE "#define FAPI2_HWPERRORINFO_H_\n\n";
+print EIFILE "#include <target.H>\n";
+print EIFILE "#include <plat_trace.H>\n";
+print EIFILE "#include <hwp_return_codes.H>\n";
+print EIFILE "#include <set_sbe_error.H>\n";
+print EIFILE "/**\n";
+print EIFILE " * \@brief Error Information macros and HwpFfdcId enumeration\n";
+print EIFILE " *\/\n";
+
+#------------------------------------------------------------------------------
+# Print start of file information to hwp_ffdc_classes.H
+#------------------------------------------------------------------------------
+print ECFILE "// hwp_ffdc_classes.H\n";
+print ECFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print ECFILE "#ifndef FAPI2_HWP_FFDC_CLASSES_H_\n";
+print ECFILE "#define FAPI2_HWP_FFDC_CLASSES_H_\n\n";
+print ECFILE "#include <ffdc.H>\n";
+print ECFILE "#include <buffer.H>\n";
+print ECFILE "#include <variable_buffer.H>\n" if ($arg_use_variable_buffers ne undef);
+print ECFILE "#include <error_info.H>\n";
+print ECFILE "#include <utils.H>\n";
+print ECFILE "#include <hwp_error_info.H>\n";
+print ECFILE "#include <collect_reg_ffdc.H>\n";
+#print ECFILE "#include <proc_extract_sbe_rc.H>\n\n";
+print ECFILE "/**\n";
+print ECFILE " * \@brief FFDC gathering classes\n";
+print ECFILE " *\/\n";
+print ECFILE "namespace fapi2\n{\n";
+
+#------------------------------------------------------------------------------
+# Print start of file information to collectRegFfdc.C
+#------------------------------------------------------------------------------
+print CRFILE "// collect_reg_ffdc.C\n";
+print CRFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print CRFILE "#include <stdint.h>\n";
+print CRFILE "#include <vector>\n";
+
+print CRFILE "#include <buffer.H>\n";
+print CRFILE "#include <collect_reg_ffdc.H>\n";
+print CRFILE "#include <target.H>\n";
+print CRFILE "#include <return_code.H>\n";
+print CRFILE "#include <hw_access.H>\n";
+print CRFILE "#include <plat_trace.H>\n\n";
+
+print CRFILE "namespace fapi2\n";
+print CRFILE "{\n";
+print CRFILE "void collectRegFfdc(const fapi2::ffdc_t& i_target,\n";
+print CRFILE " const fapi2::HwpFfdcId i_ffdcId,\n";
+print CRFILE " fapi2::ReturnCode & o_rc,\n";
+print CRFILE " const TargetType i_child,\n";
+print CRFILE " const TargetType i_presChild,\n";
+print CRFILE " uint32_t i_childOffsetMult)\n";
+print CRFILE "{\n";
+print CRFILE " FAPI_INF(\"collectRegFfdc. FFDC ID: 0x%x\", i_ffdcId);\n";
+print CRFILE " fapi2::ReturnCode l_rc;\n";
+print CRFILE " fapi2::buffer<uint64_t> l_buf;\n";
+print CRFILE " uint32_t l_cfamData = 0;\n";
+print CRFILE " uint64_t l_scomData = 0;\n";
+print CRFILE " std::vector<uint32_t> l_cfamAddresses;\n";
+print CRFILE " std::vector<uint64_t> l_scomAddresses;\n";
+print CRFILE " uint32_t l_ffdcSize = 0;\n\n";
+print CRFILE " switch (i_ffdcId)\n";
+print CRFILE " {\n";
+print CRFILE " // void statments for the unused variables\n";
+print CRFILE " static_cast<void>(l_cfamData);\n";
+print CRFILE " static_cast<void>(l_scomData);\n";
+print CRFILE " static_cast<void>(l_ffdcSize);\n";
+print CRFILE " static_cast<const void>(i_target);\n";
+print CRFILE " static_cast<void>(o_rc);\n";
+print CRFILE " static_cast<void>(i_child);\n";
+print CRFILE " static_cast<void>(i_presChild);\n";
+print CRFILE " static_cast<void>(i_childOffsetMult);\n";
+#------------------------------------------------------------------------------
+# Print start of file information to setSbeError.H
+#------------------------------------------------------------------------------
+print SBFILE "// setSbeError.H\n";
+print SBFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print SBFILE "// When SBE code creates an error, it produces an error value\n";
+print SBFILE "// that matches a value in the HwpReturnCode enum in\n";
+print SBFILE "// fapiHwpReturnCodes.H. The SBE uses the __ASSEMBLER__\n";
+print SBFILE "// primitives in hwpReturnCodes.H to do this. The function\n";
+print SBFILE "// that extracts the error value from the SBE needs to call\n";
+print SBFILE "// FAPI_SET_HWP_ERROR to create the error and get all the\n";
+print SBFILE "// actions in the error XML file performed, but that macro can\n";
+print SBFILE "// only be called with the enumerator, not the value. This\n";
+print SBFILE "// FAPI_SET_SBE_ERROR macro can be called instead, it calls\n";
+print SBFILE "// FAPI_SET_HWP_ERROR with the correct error enumerator.\n";
+print SBFILE "// Errors containing <sbeError/> in their XML are supported\n";
+print SBFILE "// in this macro.\n\n";
+print SBFILE "// Note that it is expected that this macro will be called\n";
+print SBFILE "// in one place (the function that extracts the error from\n";
+print SBFILE "// the SBE), if this changes and it is called in multiple\n";
+print SBFILE "// places then the macro could be turned into a function to\n";
+print SBFILE "// avoid the code size increase of expanding the macro in\n";
+print SBFILE "// multiple places. The function approach is slightly more\n";
+print SBFILE "// complicated, there is an extra C file and the function\n";
+print SBFILE "// must take a parameter for the generic chip ID in the error\n";
+print SBFILE "// XML.\n\n";
+print SBFILE "#ifndef FAPI2_SETSBEERROR_H_\n";
+print SBFILE "#define FAPI2_SETSBEERROR_H_\n\n";
+print SBFILE "#define FAPI_SET_SBE_ERROR(RC, ERRVAL)\\\n";
+print SBFILE "{\\\n";
+print SBFILE "switch (ERRVAL)\\\n";
+print SBFILE "{\\\n";
+
+#------------------------------------------------------------------------------
+# For each XML file
+#------------------------------------------------------------------------------
+foreach my $argnum (0 .. $#ARGV)
+{
+ my $infile = $ARGV[$argnum];
+ my $count = 0;
+
+ #--------------------------------------------------------------------------
+ # Read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one element
+ #--------------------------------------------------------------------------
+ my $errors = $xml->XMLin($infile, ForceArray =>
+ ['hwpError', 'collectFfdc', 'ffdc', 'callout', 'deconfigure', 'gard',
+ 'registerFfdc', 'collectRegisterFfdc', 'cfamRegister', 'scomRegister',
+ 'id','collectTrace', 'buffer']);
+
+ # Uncomment to get debug output of all errors
+ #print "\nFile: ", $infile, "\n", Dumper($errors), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Error
+ #--------------------------------------------------------------------------
+ foreach my $err (@{$errors->{hwpError}})
+ {
+ # Hash of methods for the ffdc-gathering class
+ my %methods;
+
+ #----------------------------------------------------------------------
+ # Check that expected fields are present
+ #----------------------------------------------------------------------
+ if (! exists $err->{rc})
+ {
+ print ("parseErrorInfo.pl ERROR. rc missing\n");
+ exit(1);
+ }
+
+ if (! exists $err->{description})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. description missing\n");
+ exit(1);
+ }
+
+ #----------------------------------------------------------------------
+ # Check that this rc hasn't been deprecated
+ #----------------------------------------------------------------------
+ if ($deprecated{$err->{rc}} ne undef)
+ {
+ print "WARNING: $err->{rc} has been deprecated because $deprecated{$err->{rc}}\n";
+ next;
+ }
+
+ #----------------------------------------------------------------------
+ # Set the error enum value in a global hash
+ #---------------------------------------------------------------------
+ setErrorEnumValue($err->{rc});
+
+ #----------------------------------------------------------------------
+ # If this is an SBE error, add it to set_sbe_error.H
+ #----------------------------------------------------------------------
+ if (exists $err->{sbeError})
+ {
+ print SBFILE " case fapi2::$err->{rc}:\\\n";
+ print SBFILE " FAPI_SET_HWP_ERROR(RC, $err->{rc});\\\n";
+ print SBFILE " break;\\\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the CALL_FUNCS_TO_COLLECT_FFDC macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_FFDC(RC) ";
+
+ # For now, this code is removed. It appears to work just fine but
+ # will require more of the fapi2 infrastructure to be in place.
+ # Because the ffdc collection classes create members with real types,
+ # the declarations of the types need to be visible - and they're not
+ # right now. When we get further along, we can enable this code.
+=begin NO_FFDC_COLLECT_HWP
+ $count = 0;
+
+ foreach my $collectFfdc (@{$err->{collectFfdc}})
+ {
+ if ($count == 0)
+ {
+ print EIFILE "{ fapi2::ReturnCode l_tempRc; ";
+ }
+ $count++;
+
+ print EIFILE "FAPI_EXEC_HWP(l_tempRc, $collectFfdc, RC); ";
+
+ # collectFfdc is a string we're going to stuff into FAPI_EXEC_HWP
+ # but we need to create the arguments in the ffdc class. The first
+ # element inthe collectFfdc string is the function to call.
+ my @elements = split /,/, $collectFfdc;
+ my @signature = @{$signatures{@elements[0]}};
+ for (my $i = 1; $i <= $#elements; $i++)
+ {
+ @elements[$i] =~ s/^\s+|\s+$//g;
+ addFfdcMethod(\%methods, @elements[$i], $err->{rc}, @signature[$i-1]);
+ }
+ }
+
+ if ($count > 0)
+ {
+ print EIFILE "}";
+ }
+=cut NO_FFDC_COLLECT_HWP
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the CALL_FUNCS_TO_COLLECT_REG_FFDC macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC) ";
+
+ foreach my $collectRegisterFfdc (@{$err->{collectRegisterFfdc}})
+ {
+ #------------------------------------------------------------------
+ # Check that expected fields are present
+ #------------------------------------------------------------------
+ if (! exists $collectRegisterFfdc->{id}[0])
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. id(s) missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ foreach my $id (@{$collectRegisterFfdc->{id}})
+ {
+ #---------------------------------------------------------------------------------
+ # Check FFDC register collection type: target, child, or based on present children
+ #---------------------------------------------------------------------------------
+ if (exists $collectRegisterFfdc->{target})
+ {
+ print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{target}, ";
+ print EIFILE "fapi2::$id, RC, fapi2::TARGET_TYPE_NONE, fapi2::TARGET_TYPE_NONE); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{target},
+ $err->{rc}, $target_ffdc_type);
+ }
+ elsif (exists $collectRegisterFfdc->{childTargets})
+ {
+ if (! exists $collectRegisterFfdc->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR: parent missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{childTargets}->{parent}, fapi2::$id, ";
+ print EIFILE "RC, fapi2::$collectRegisterFfdc->{childTargets}->{childType}, fapi2::TARGET_TYPE_NONE); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{childTargets}->{parent},
+ $err->{rc}, $target_ffdc_type);
+ }
+ elsif (exists $collectRegisterFfdc->{basedOnPresentChildren})
+ {
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{target})
+ {
+ print ("parseErrorInfo.pl ERROR: target missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier})
+ {
+ print ("parseErrorInfo.pl ERROR: childPosOffsetMultiplier missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{basedOnPresentChildren}->{target}, fapi2::$id, RC, ";
+ print EIFILE "fapi2::TARGET_TYPE_NONE, fapi2::$collectRegisterFfdc->{basedOnPresentChildren}->{childType}, ";
+ print EIFILE "$collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier}); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{basedOnPresentChildren}->{target},
+ $err->{rc}, $target_ffdc_type);
+ }
+ else
+ {
+ print ("parseErrorInfo.pl ERROR: Invalid collectRegisterFfdc configuration\n");
+ exit(1);
+ }
+ }
+ }
+
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the ADD_ERROR_INFO macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_ADD_ERROR_INFO(RC) ";
+
+ # Array of EI Objects
+ my @eiObjects;
+
+ my $eiObjectStr = "const void * l_objects[] = {";
+ my $eiEntryStr = "";
+ my $eiEntryCount = 0;
+ my %cdgTargetHash; # Records the callout/deconfigure/gards for Targets
+ my %cdgChildHash; # Records the callout/deconfigure/gards for Children
+
+ # collect firmware trace
+ foreach my $collectTrace (@{$err->{collectTrace}})
+ {
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_COLLECT_TRACE; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].collect_trace.iv_eieTraceId = fapi2::CollectTraces::$collectTrace; \\\n";
+ $eiEntryCount++;
+ }
+
+ # Local FFDC
+ foreach my $ffdc (@{$err->{ffdc}})
+ {
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $ffdcName = $err->{rc} . "_";
+ $ffdcName = $ffdcName . $ffdc;
+ setFfdcIdValue($ffdcName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $ffdc);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $ffdc, $err->{rc});
+
+ $ffdc = $mangle_names{$ffdc} if ($mangle_names{$ffdc} ne undef);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$ffdcName; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = $ffdc.size(); \\\n";
+ $eiEntryCount++;
+ }
+
+ # Buffers, looks a lot like local ffdc
+ foreach my $buffer (@{$err->{buffer}})
+ {
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $bufferName = $err->{rc} . "_";
+ $bufferName = $bufferName . $buffer;
+ setFfdcIdValue($bufferName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $buffer);
+
+ # Add a method to the ffdc-gathering class - one for each buffer type
+ addFfdcMethod(\%methods, $buffer, $err->{rc}, $buffer_ffdc_type);
+ addFfdcMethod(\%methods, $buffer, $err->{rc}, $variable_buffer_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$bufferName; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = fapi2::getErrorInfoFfdcSize($buffer); \\\n";
+ $eiEntryCount++;
+ }
+
+ # Procedure/Target/Bus/Child callouts
+ foreach my $callout (@{$err->{callout}})
+ {
+ if (! exists $callout->{priority})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout priority missing\n");
+ exit(1);
+ }
+
+ my $elementsFound = 0;
+ if (exists $callout->{hw})
+ {
+ # HW Callout
+ if (! exists $callout->{hw}->{hwid})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. HW Callout hwid missing\n");
+ exit(1);
+ }
+
+ # Check that those HW callouts that need reference targets have them
+ if (($callout->{hw}->{hwid} eq "TOD_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "MEM_REF_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "PROC_REF_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "PCI_REF_CLOCK"))
+ {
+ if (! exists $callout->{hw}->{refTarget})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout missing refTarget\n");
+ exit(1);
+ }
+ }
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_HW_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_hw = fapi2::HwCallouts::$callout->{hw}->{hwid}; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ if (exists $callout->{hw}->{refTarget})
+ {
+ # Add the Targets to the objectlist if they don't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $callout->{hw}->{refTarget});
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = $objNum; \\\n";
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $callout->{hw}->{refTarget}, $err->{rc});
+ }
+ else
+ {
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = 0xff; \\\n";
+ }
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{procedure})
+ {
+ # Procedure Callout
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_PROCEDURE_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_procedure = fapi2::ProcedureCallouts::$callout->{procedure}; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{bus})
+ {
+ # A Bus Callout consists of two targets separated by
+ # commas/spaces
+ my @targets = split(/\s*,\s*|\s+/, $callout->{bus});
+
+ if (scalar @targets != 2)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. did not find two targets in bus callout\n");
+ exit(1);
+ }
+
+ # Add the Targets to the objectlist if they don't already exist
+ my $objNum1 = addEntryToArray(\@eiObjects, $targets[0]);
+
+ my $objNum2 = addEntryToArray(\@eiObjects, $targets[1]);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $targets[0], $err->{rc}, $target_ffdc_type);
+ addFfdcMethod(\%methods, $targets[1], $err->{rc}, $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_BUS_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint1ObjIndex = $objNum1; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint2ObjIndex = $objNum2; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # deconfigure and GARD requests
+ $cdgTargetHash{$callout->{target}}{callout} = 1;
+ $cdgTargetHash{$callout->{target}}{priority} =
+ $callout->{priority};
+
+ $elementsFound++;
+ }
+ if (exists $callout->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $callout->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout parent missing\n");
+ exit(1);
+ }
+
+ if (! exists $callout->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any deconfigure and GARD requests
+ my $parent = $callout->{childTargets}->{parent};
+ my $childType = $callout->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{callout} = 1;
+ $cdgChildHash{$parent}{$childType}{priority} =
+ $callout->{priority};
+
+ $elementsFound++;
+
+ if (exists $callout->{childTargets}->{childPort})
+ {
+ my $childPort = $callout->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+ }
+
+ if (exists $callout->{childTargets}->{childNumber})
+ {
+ my $childNum = $callout->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+ }
+
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout has multiple elements\n");
+ exit(1);
+ }
+ } # callout
+
+ # Target/Child deconfigures
+ foreach my $deconfigure (@{$err->{deconfigure}})
+ {
+ my $elementsFound = 0;
+ if (exists $deconfigure->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # callout and GARD requests
+ $cdgTargetHash{$deconfigure->{target}}{deconf} = 1;
+ $elementsFound++;
+ }
+ if (exists $deconfigure->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $deconfigure->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure parent missing\n");
+ exit(1);
+ }
+ if (! exists $deconfigure->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any callout and GARD requests
+ my $parent = $deconfigure->{childTargets}->{parent};
+ my $childType = $deconfigure->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{deconf} = 1;
+
+ $elementsFound++;
+
+ if ( exists $deconfigure->{childTargets}->{childPort})
+ {
+ my $childPort = $deconfigure->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+ }
+
+ if ( exists $deconfigure->{childTargets}->{childNumber})
+ {
+ my $childNum = $deconfigure->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+
+ }
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure has multiple elements\n");
+ exit(1);
+ }
+ } # deconfigure
+
+ # Target/Child Gards
+ foreach my $gard (@{$err->{gard}})
+ {
+ my $elementsFound = 0;
+ if (exists $gard->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # callout and deconfigure requests
+ $cdgTargetHash{$gard->{target}}{gard} = 1;
+ $elementsFound++;
+ }
+ if (exists $gard->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $gard->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD parent missing\n");
+ exit(1);
+ }
+ if (! exists $gard->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any callout and deconfigure requests
+ my $parent = $gard->{childTargets}->{parent};
+ my $childType = $gard->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{gard} = 1;
+
+ $elementsFound++;
+
+ if ( exists $gard->{childTargets}->{childPort})
+ {
+ my $childPort = $gard->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+
+ }
+
+ if ( exists $gard->{childTargets}->{childNumber})
+ {
+ my $childNum = $gard->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+ }
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD has multiple elements\n");
+ exit(1);
+ }
+ } # gard
+
+ # Process the callout, deconfigures and GARDs for each Target
+ foreach my $cdg (keys %cdgTargetHash)
+ {
+ my $callout = 0;
+ my $priority = 'LOW';
+ my $deconf = 0;
+ my $gard = 0;
+
+ if (exists $cdgTargetHash{$cdg}->{callout})
+ {
+ $callout = 1;
+ }
+ if (exists $cdgTargetHash{$cdg}->{priority})
+ {
+ $priority = $cdgTargetHash{$cdg}->{priority};
+ }
+ if (exists $cdgTargetHash{$cdg}->{deconf})
+ {
+ $deconf = 1;
+ }
+ if (exists $cdgTargetHash{$cdg}->{gard})
+ {
+ $gard = 1;
+ }
+
+ # Add the Target to the objectlist if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $cdg);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $cdg, $err->{rc}, $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CDG; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_targetObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_callout = $callout; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_deconfigure = $deconf; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_gard = $gard; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n";
+ $eiEntryCount++;
+ }
+
+ # Process the callout, deconfigures and GARDs for Child Targets
+ foreach my $parent (keys %cdgChildHash)
+ {
+ foreach my $childType (keys %{$cdgChildHash{$parent}})
+ {
+ my $callout = 0;
+ my $priority = 'LOW';
+ my $deconf = 0;
+ my $gard = 0;
+ my $childPort = 0xFF;
+ my $childNumber = 0xFF;
+
+ if (exists $cdgChildHash{$parent}{$childType}->{callout})
+ {
+ $callout = 1;
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{priority})
+ {
+ $priority =
+ $cdgChildHash{$parent}->{$childType}->{priority};
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{deconf})
+ {
+ $deconf = 1;
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{childPort})
+ {
+ $childPort =
+ $cdgChildHash{$parent}->{$childType}->{childPort} ;
+ addFfdcMethod(\%methods, $childPort, $err->{rc});
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{childNumber})
+ {
+ $childNumber =
+ $cdgChildHash{$parent}->{$childType}->{childNumber} ;
+ addFfdcMethod(\%methods, $childNumber, $err->{rc});
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{gard})
+ {
+ $gard = 1;
+ }
+
+
+ # Add the Target to the objectlist if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $parent);
+ addFfdcMethod(\%methods, $parent, $err->{rc}, $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CHILDREN_CDG; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_parentObjIndex = $objNum; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_callout = $callout; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_deconfigure = $deconf; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childType = fapi2::$childType; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childPort = $childPort; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childNumber = $childNumber; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_gard = $gard; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n";
+ $eiEntryCount++;
+ }
+ }
+
+ # Add all objects to $eiObjectStr
+ my $objCount = 0;
+
+ foreach my $eiObject (@eiObjects)
+ {
+ if ($objCount > 0)
+ {
+ $eiObjectStr .= ", ";
+ }
+
+ if ($mangle_names{$eiObject} eq undef)
+ {
+ $eiObjectStr .= "$eiObject"
+ }
+ else
+ {
+ $eiObjectStr .= $mangle_names{$eiObject};
+ }
+
+ $objCount++;
+ }
+ $eiObjectStr .= "};";
+
+ # Print info to file
+ if ($eiEntryCount > 0)
+ {
+ print EIFILE "\\\n{ \\\n $eiObjectStr \\\n";
+ print EIFILE " fapi2::ErrorInfoEntry l_entries[$eiEntryCount]; \\\n";
+ print EIFILE "$eiEntryStr";
+ print EIFILE " RC.addErrorInfo(l_objects, l_entries, $eiEntryCount); \\\n}";
+ }
+
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the return code class to hwp_error_info.H
+ #----------------------------------------------------------------------
+ # Remove the repeated whitespace and newlines other characters from the description
+ $err->{description} =~ s/^\s+|\s+$|"//g;
+ $err->{description} =~ tr{\n}{ };
+ $err->{description} =~ s/\h+/ /g;
+
+ #----------------------------------------------------------------------
+ # Print the return code class to hwp_error_info.H
+ #----------------------------------------------------------------------
+ my $class_name = $err->{rc};
+ # Remove everything upto and including the first _. This makes the ffdc class
+ # names different from the error code value enum names.
+ $class_name = (split (/_/, $class_name, 2))[1];
+
+ # Class declaration
+ print ECFILE "\nclass $class_name\n{\n public:\n";
+
+ # Constructor. This traces the description. If this is too much, we can
+ # remove it.
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err):\n";
+ print ECFILE " iv_rc(i_rc),\n";
+ print ECFILE " iv_sev(i_sev)\n";
+ print ECFILE " { FAPI_ERR(\"$err->{description}\"); }\n";
+ }
+ else
+ {
+ # Void expression keeps the compiler from complaining about the unused arguments.
+ # We want to set the i_rc to the RC if we're empty. This otherwise gets done in _setHwpError()
+ print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err)\n";
+ print ECFILE " {\n";
+ print ECFILE " static_cast<void>(i_sev);\n";
+ print ECFILE " i_rc = $err->{rc};\n";
+ print ECFILE " }\n\n";
+ }
+
+ # Methods
+ foreach my $key (keys %methods)
+ {
+ print ECFILE $methods{$key}{method};
+ }
+
+ # Stick the execute method at the end of the other methods. We allow
+ # passing in of the severity so that macros which call execute() can over-ride
+ # the default severity.
+ print ECFILE " void execute(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNDEFINED)\n";
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " {\n";
+ print ECFILE " FAPI_SET_HWP_ERROR(iv_rc, $err->{rc});\n";
+ print ECFILE " fapi2::logError(iv_rc, (i_sev == fapi2::FAPI2_ERRL_SEV_UNDEFINED) ? iv_sev : i_sev);\n";
+ print ECFILE " }\n\n";
+ }
+ else
+ {
+ print ECFILE " {\n";
+ print ECFILE " static_cast<void>(i_sev);\n";
+ print ECFILE " }\n\n";
+ }
+
+ # Instance variables
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " private:\n ";
+ foreach my $key (keys %methods)
+ {
+ print ECFILE $methods{$key}{member};
+ }
+
+ print ECFILE "fapi2::ReturnCode& iv_rc;\n";
+ print ECFILE " fapi2::errlSeverity_t iv_sev;\n";
+ }
+
+ print ECFILE "};\n\n\n\n";
+ }
+
+ #--------------------------------------------------------------------------
+ # For each registerFfdc.
+ #--------------------------------------------------------------------------
+ foreach my $registerFfdc (@{$errors->{registerFfdc}})
+ {
+ #----------------------------------------------------------------------
+ # Check that expected fields are present
+ #----------------------------------------------------------------------
+ if (! exists $registerFfdc->{id}[0])
+ {
+ print ("parseErrorInfo.pl ERROR. id missing from registerFfdc\n");
+ exit(1);
+ }
+
+ if (scalar @{$registerFfdc->{id}} > 1)
+ {
+ print ("parseErrorInfo.pl ERROR. multiple ids in registerFfdc\n");
+ exit(1);
+ }
+
+ #----------------------------------------------------------------------
+ # Set the FFDC ID value in a global hash
+ #----------------------------------------------------------------------
+ setFfdcIdValue($registerFfdc->{id}[0]);
+
+ #----------------------------------------------------------------------
+ # Generate code to capture the registers in collect_reg_ffdc.C
+ #----------------------------------------------------------------------
+ print CRFILE " case $registerFfdc->{id}[0]:\n";
+
+=begin NEED_P9_REGISTERS
+ # Look for CFAM Register addresses
+ foreach my $cfamRegister (@{$registerFfdc->{cfamRegister}})
+ {
+ print CRFILE " l_cfamAddresses.push_back($cfamRegister);\n";
+ print CRFILE " l_ffdcSize += sizeof(l_cfamData);\n";
+ }
+
+ # Look for SCOM Register addresses
+ foreach my $scomRegister (@{$registerFfdc->{scomRegister}})
+ {
+ print CRFILE " l_scomAddresses.push_back($scomRegister);\n";
+ print CRFILE " l_ffdcSize += sizeof(l_scomData);\n";
+ }
+=cut NEED_P9_REGISTERS
+
+ print CRFILE " break;\n";
+ }
+
+}
+
+#------------------------------------------------------------------------------
+# Print end of file information to collect_reg_ffdc.C
+#------------------------------------------------------------------------------
+print CRFILE " default:\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Invalid FFDC ID 0x%x\", ";
+print CRFILE "i_ffdcId);\n";
+print CRFILE " return;\n";
+print CRFILE " }\n\n";
+
+=begin NEED_P9_REGISTERS
+
+print CRFILE " uint8_t * l_pBuf = NULL;\n";
+print CRFILE " uint8_t * l_pData = NULL;\n";
+print CRFILE " std::vector<fapi::Target> l_targets;\n";
+print CRFILE " uint32_t l_chipletPos32 = 0;\n";
+#---------------------------------------------------------------------------------------------------------
+# Populate chiplet vectors (if required by register collection method) and adjust buffer sizes accordingly
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_child)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_child, l_targets, TARGET_STATE_FUNCTIONAL);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " if (l_targets.empty())\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_ffdcSize *= l_targets.size();\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " }\n";
+print CRFILE " else if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_presChild, l_targets, TARGET_STATE_PRESENT);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " if (l_targets.empty())\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_ffdcSize *= l_targets.size();\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " l_targets.push_back(i_target);\n";
+print CRFILE " }\n\n";
+#---------------------------------------------------------------------------------------------------------
+# Obtain target position and insert as the first word in the buffer
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " bool l_targIsChiplet = i_target.isChiplet();\n\n";
+print CRFILE " for (std::vector<fapi::Target>::const_iterator targetIter = l_targets.begin();\n";
+print CRFILE " targetIter != l_targets.end(); ++targetIter)\n";
+print CRFILE " {\n";
+print CRFILE " if ((fapi2::TARGET_TYPE_NONE != i_child) ||\n";
+print CRFILE " (fapi2::TARGET_TYPE_NONE != i_presChild) ||\n";
+print CRFILE " (true == l_targIsChiplet))\n";
+print CRFILE " {\n";
+print CRFILE " uint8_t l_chipletPos = 0;\n";
+print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &(*targetIter), l_chipletPos);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chiplet position\");\n";
+print CRFILE " l_chipletPos = 0xFF;\n";
+print CRFILE " }\n";
+ #-------------------------------------------------------------------------
+ # We print the target's position in the error log whether the target is a
+ # chip or chiplet, so we need to store the chiplet position in a uint32_t
+ # to have consitency in the buffer as ATTR_POS below returns a uint32_t
+ #-------------------------------------------------------------------------
+print CRFILE " l_chipletPos32 = l_chipletPos;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_POS, &(*targetIter), l_chipletPos32);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chip position\");\n";
+print CRFILE " l_chipletPos32 = 0xFFFFFFFF;\n";
+print CRFILE " }\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_chipletPos32;\n";
+print CRFILE " l_pData += sizeof(l_chipletPos32);\n";
+#---------------------------------------------------------------------------------------------------------
+# Instert cfam data (if any) related to this chip / chiplet into the buffer
+# If collecting FFDC based on present children, adjust the register address by the appropriate offset
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " for (std::vector<uint32_t>::const_iterator cfamIter = l_cfamAddresses.begin();\n";
+print CRFILE " cfamIter != l_cfamAddresses.end(); ++cfamIter)\n";
+print CRFILE " {\n";
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetCfamRegister(i_target, (*cfamIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetCfamRegister(*targetIter, *cfamIter, l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: CFAM error for 0x%x\",";
+print CRFILE "*cfamIter);\n";
+print CRFILE " l_cfamData = 0xbaddbadd;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_cfamData = l_buf.getWord(0);\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_cfamData;\n";
+print CRFILE " l_pData += sizeof(l_cfamData);\n";
+print CRFILE " }\n\n";
+#---------------------------------------------------------------------------------------------------------
+# Instert any scom data (if any) related to this chip / chiplet into the buffer
+# If collecting FFDC based on present children, adjust the register address by the appropriate offset
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " for (std::vector<uint64_t>::const_iterator scomIter = l_scomAddresses.begin();\n";
+print CRFILE " scomIter != l_scomAddresses.end(); ++scomIter)\n";
+print CRFILE " {\n";
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetScom(i_target, (*scomIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetScom(*targetIter, *scomIter, l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: SCOM error for 0x%llx\",";
+print CRFILE "*scomIter);\n";
+print CRFILE " l_scomData = 0xbaddbaddbaddbaddULL;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_scomData = l_buf.getDoubleWord(0);\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint64_t *>(l_pData)) = l_scomData;\n";
+print CRFILE " l_pData += sizeof(l_scomData);\n";
+print CRFILE " }\n";
+print CRFILE " }\n\n";
+print CRFILE " o_rc.addEIFfdc(i_ffdcId, l_pBuf, l_ffdcSize);\n";
+print CRFILE " delete [] l_pBuf;\n";
+=cut NEED_P9_REGISTERS
+
+print CRFILE "}\n";
+print CRFILE "}\n";
+
+
+#------------------------------------------------------------------------------
+# Print the fapiHwpReturnCodes.H file
+#------------------------------------------------------------------------------
+print RCFILE "// fapiHwpReturnCodes.H\n";
+print RCFILE "// This file is generated by perl script parseErrorInfo.pl\n\n";
+print RCFILE "#ifndef FAPI2_HWPRETURNCODES_H_\n";
+print RCFILE "#define FAPI2_HWPRETURNCODES_H_\n\n";
+print RCFILE "#ifndef __ASSEMBLER__\n";
+print RCFILE "namespace fapi2\n";
+print RCFILE "{\n\n";
+print RCFILE "/**\n";
+print RCFILE " * \@brief Enumeration of HWP return codes\n";
+print RCFILE " *\/\n";
+print RCFILE "enum HwpReturnCode\n";
+print RCFILE "{\n";
+foreach my $key (keys %errNameToValueHash)
+{
+ print RCFILE " $key = 0x$errNameToValueHash{$key},\n";
+}
+print RCFILE "};\n\n";
+print RCFILE "}\n\n";
+print RCFILE "#else\n";
+foreach my $key (keys %errNameToValueHash)
+{
+ print RCFILE " .set $key, 0x$errNameToValueHash{$key}\n";
+}
+print RCFILE "#endif\n";
+print RCFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Print the HwpFfdcId enumeration to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "namespace fapi2\n";
+print EIFILE "{\n\n";
+print EIFILE "/**\n";
+print EIFILE " * \@brief Enumeration of FFDC identifiers\n";
+print EIFILE " *\/\n";
+print EIFILE "enum HwpFfdcId\n";
+print EIFILE "{\n";
+foreach my $key (keys %ffdcNameToValueHash)
+{
+ print EIFILE " $key = 0x$ffdcNameToValueHash{$key},\n";
+}
+print EIFILE "};\n\n";
+print EIFILE "}\n\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "\n\n#endif\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to hwp_ffdc_classes.H
+#------------------------------------------------------------------------------
+print ECFILE "\n};\n"; # close the namespace
+print ECFILE "\n\n#endif\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to set_sbe_error.H
+#------------------------------------------------------------------------------
+print SBFILE " default:\\\n";
+print SBFILE " FAPI_SET_HWP_ERROR(RC, RC_SBE_UNKNOWN_ERROR);\\\n";
+print SBFILE " break;\\\n";
+print SBFILE "}\\\n";
+print SBFILE "}\n\n";
+print SBFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Close output files
+#------------------------------------------------------------------------------
+close(RCFILE);
+close(EIFILE);
+close(ECFILE);
+close(CRFILE);
+close(SBFILE);
diff --git a/src/ppe/tools/scripts/ppeCreateAttrGetSetMacros.pl b/src/ppe/tools/scripts/ppeCreateAttrGetSetMacros.pl
new file mode 100755
index 0000000..0948e2d
--- /dev/null
+++ b/src/ppe/tools/scripts/ppeCreateAttrGetSetMacros.pl
@@ -0,0 +1,557 @@
+#!/usr/bin/perl -w
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/scripts/ppeCreateAttrGetSetMacros.pl $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+#find enums in AttributeId
+#for each enum check for ${enum}_Type
+#check for type and array values
+#Check Plat file for ${enum}_GETMACRO and ${enum}_SETMACRO
+#If they do not exist add apporpriate _SETMACRO and _GETMACRO to Plat file
+
+use strict;
+use File::Copy;
+use Getopt::Long;
+
+sub enumParser ($);
+sub help;
+
+my $DEBUG = 0;
+my $VERBOSE = 0;
+
+my $state = 0;
+my $last_value = -1;
+my $current_entry;
+my $current_enum_name;
+
+my %enums;
+
+my %attributeTypes;
+my %attributeArrayTypes;
+
+my %getMacros;
+my %setMacros;
+my %targetMacros;
+
+
+
+my $fapiAttributeIdsFile = "fapi2AttributeIds.H";
+my $fapiPlatAttributeServiceFile= "fapi2PlatAttributeService.H";
+my $fapiPlatAttributeServiceImpl= "fapi2PlatAttributeService.C";
+
+
+my $includePath = "./";
+my $srcPath = "./";
+
+my @newAttributeDefines;
+my @newTargetDefines;
+my @newTargetImplementations;
+
+
+my $servicePath;
+my $help;
+
+GetOptions ("verbose" => \$VERBOSE,
+ "help" => \$help,
+ "debug" => \$DEBUG,
+ "path=s" => \$servicePath,
+ "inc=s" => \$includePath,
+ "src=s" => \$srcPath,
+);
+
+help() if $help;
+
+open (FILE, $includePath . "/" . $fapiAttributeIdsFile) or die "ERROR:: could not open $fapiAttributeIdsFile\n";
+
+while (<FILE>) {
+ # attempt to parse attributes from current line in file
+ enumParser($_);
+
+ # see if the line describes an attribute
+ if (m/\s*typedef\s+(\w+)\s+(\w+)_Type(\S*)\s*;/) {
+ my $type = $1;
+ my $attribute = $2;
+ my $arrayType = $3;
+
+ if ($DEBUG) { print "DEBUG:: type = $type : attribute = $attribute : arrayType = $arrayType\n"; }
+
+ # save attribute type and if it is an array and its size
+ $attributeTypes{$attribute} = $type;
+ if ($arrayType) {
+ $attributeArrayTypes{$attribute} = $arrayType;
+ } else {
+ $attributeArrayTypes{$attribute} = "none";
+ }
+ }
+
+ # look for MACROs
+ # look for: #define ATTR_CHIP_HAS_SBE_GETMACRO ATTRIBUTE_NOT_WRITABLE
+ if (m/\s*#define\s+(\w+)_GETMACRO\s+(\S+)\s*/) {
+ $getMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : GETMACRO = $2\n"; }
+ # look for: #define ATTR_CHIP_EC_FEATURE_TEST1_GETMACRO(ID, PTARGET, VAL) fapi::fapiQueryChipEcFeature(ID, PTARGET, VAL)
+ } elsif (m/\s*#define\s+(\w+)_GETMACRO\(ID\,\sPTARGET\,\sVAL\)\s(.+)/) {
+ $getMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : GETMACRO = $2\n"; }
+ # look for: #define ATTR_CHIP_HAS_SBE_SETMACRO ATTRIBUTE_NOT_WRITABLE
+ } elsif (m/\s*#define\s+(\w+)_SETMACRO\s+(\S+)\s*/) {
+ $setMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : SETMACRO = $2\n"; }
+ # look for: #define ATTR_CHIP_EC_FEATURE_TEST2_SETMACRO(ID, PTARGET, VAL) CHIP_EC_FEATURE_ATTRIBUTE_NOT_WRITABLE
+ } elsif (m/\s*#define\s+(\w+)_SETMACRO\(ID\,\sPTARGET\,\sVAL\)\s(.+)/) {
+ $setMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : SETMACRO = $2\n"; }
+ } elsif (m/\s*const\s*TargetTypes_t\s+(\w+)_TargetTypes\s*=\s*(\S+)\s*;\s*/) {
+ $targetMacros{$1} = $2;
+# print "DEBUG:: attribute = $1 : TARGET = $2\n";
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : TARGET = $2\n"; }
+ }
+}
+
+close (FILE);
+
+#find copy of fapiPlatAttributeService.H
+if (!$servicePath) {
+ #$CTEPATH/tools/ecmd/$ECMD_RELEASE/ext/fapi/capi
+ my $ctepath = $ENV{CTEPATH};
+ my $ecmd_release = $ENV{ECMD_RELEASE};
+ if ($DEBUG) { print "DEBUG:: ctepath = $ctepath\n"; }
+ if ($DEBUG) { print "DEBUG:: ecmd_release = $ecmd_release\n"; }
+ if (!$ctepath) {
+ print "ERROR:: environment variable CTEPATH not defined!\n";
+ exit 1;
+ }
+ if (!$ecmd_release) {
+ print "ERROR:: environment variable ECMD_RELEASE not defined!\n";
+ exit 1;
+ }
+ $servicePath = "$ctepath/tools/ecmd/$ecmd_release/ext/fapi/capi";
+}
+
+if ($DEBUG) { print "DEBUG:: servicePath = $servicePath\n"; }
+
+# test that servicePath exists
+if (!-d $servicePath) {
+ print "ERROR:: path $servicePath does not exist!\n";
+ exit 1;
+}
+
+# test that fapiPlatAttributeService.H is in that directory
+if (!-f "$servicePath/$fapiPlatAttributeServiceFile") {
+ print "ERROR:: $fapiPlatAttributeServiceFile does not exist in $servicePath\n";
+ exit 1;
+}
+
+# copy fapiPlatAttributeService.H to local dir
+#my $systemRc = system("cp $servicePath/$fapiPlatAttributeServiceFile $includePath");
+copy("$servicePath/$fapiPlatAttributeServiceFile","$includePath") or die "Copy failed: $!";
+
+#if ($systemRc) {
+# print "ERROR:: error copying $fapiPlatAttributeServiceFile from $servicePath\n";
+# exit 1;
+#}
+
+
+
+# look in fapiPlatAttributeService.H for MACROs
+open (FILE, $includePath . "/". $fapiPlatAttributeServiceFile) or die "ERROR:: could not open $fapiPlatAttributeServiceFile\n";
+while (<FILE>) {
+ if (m/\s*#define\s+(\w+)_GETMACRO\s+(\S+)\s*/) {
+ $getMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : GETMACRO = $2\n"; }
+ } elsif (m/\s*#define\s+(\w+)_SETMACRO\s+(\S+)\s*/) {
+ $setMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : SETMACRO = $2\n"; }
+ } elsif (m/\s*const\s*TargetTypes_t\s+(\w+)_TargetTypes\s*=\s*(\S+)\s*;\s*/) {
+ $targetMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : TARGET = $2\n"; }
+ }
+}
+close (FILE);
+
+# go through attributes found in file
+for my $attribute (sort keys %{$enums{AttributeId}}) {
+ if ($DEBUG) { print "DEBUG:: attribute = $attribute\n"; }
+ my $type;
+ my $arrayType;
+ my $dimension = 0;
+
+ # check that each attribute has attributeType
+ if ($attributeTypes{$attribute}) {
+ if ($attributeArrayTypes{$attribute}) {
+ $type = $attributeTypes{$attribute};
+ $arrayType = $attributeArrayTypes{$attribute};
+ } else {
+ print "ERROR:: arrayType not found for $attribute\n";
+ next;
+ }
+ } else {
+ print "ERROR:: type not found for $attribute\n";
+ next;
+ }
+
+ # determine if attribute is an array
+ if ($arrayType =~ m/none/) {
+ if ($DEBUG) { print "DEBUG:: $attribute = $type\n"; }
+ } else {
+ # find dimension for array
+ my $tempArrayType = $arrayType;
+ while ($tempArrayType =~ m/\[\d*\].*/) {
+ $dimension++;
+ $tempArrayType =~ s/\[\d*\]//;
+ }
+ if ($DEBUG) { print "DEBUG:: $attribute = $type$arrayType dimension = $dimension\n"; }
+ }
+
+ my $setMacro = $setMacros{$attribute};
+ my $getMacro = $getMacros{$attribute};
+ my $targetMacro = $targetMacros{$attribute};
+
+# print "$attribute $setMacro $getMacro $targetMacro \n";
+
+ # if an attribute is missing the SET or GET MACRO add to list in insert into file later
+ if (!($getMacro && $setMacro)) {
+ my $macroPrefix = "PLAT_ATTR_";
+ my $macroPostfix = "";
+
+ if ($dimension == 0) {
+ $macroPostfix = "_GLOBAL_INT";
+ } else {
+ if ($type =~ m/uint8_t/) {
+ $macroPostfix = "_UINT8_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/uint32_t/) {
+ $macroPostfix = "_UINT32_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/uint64_t/) {
+ $macroPostfix = "_UINT64_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/int8_t/) {
+ $macroPostfix = "_INT8_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/int32_t/) {
+ $macroPostfix = "_INT32_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/int64_t/) {
+ $macroPostfix = "_INT64_" . $dimension . "D_ARRAY";
+ } else {
+ print "ERROR:: unknown type $type for attribute $attribute\n";
+ next;
+ }
+ }
+
+ my $macroTarget = "";
+ if(defined $targetMacro) {
+ if($targetMacro eq "TARGET_TYPE_PROC_CHIP") {
+ $macroTarget = "ProcChipAttributes_t";
+ } elsif ($targetMacro eq "TARGET_TYPE_CORE") {
+ $macroTarget = "CoreAttributes_t";
+ } elsif ($targetMacro eq "TARGET_TYPE_EX") {
+ $macroTarget = "EXAttributes_t";
+ } elsif ($targetMacro eq "TARGET_TYPE_EQ") {
+ $macroTarget = "EQAttributes_t";
+ } elsif ($targetMacro eq "TARGET_TYPE_PERV") {
+ $macroTarget = "PervAttributes_t";
+ } else {
+ print "ERROR:: unknown type $targetMacro for attribute $attribute\n";
+ next;
+ }
+ }
+
+ if (!$getMacro) {
+ if ($VERBOSE) { print "INFO:: did not find ${attribute}_GETMACRO\n"; }
+ my $attributeDefine = "#define ${attribute}_GETMACRO ${macroPrefix}GET${macroPostfix}";
+ push(@newAttributeDefines, $attributeDefine);
+
+ if(defined $targetMacro) {
+
+
+ my $targetFunction = "template<> void __get<fapi2::$targetMacro, fapi2attr::$macroTarget, $type, fapi2::${attribute}> ( const fapi2::Target<fapi2::$targetMacro>* i_ptarget, fapi2attr::$macroTarget* object, const fapi2::AttributeId attrid, $type *value )";
+ push(@newTargetDefines, $targetFunction . ";");
+
+ my $targetImplementation = "";
+ if($targetMacro eq "TARGET_TYPE_PROC_CHIP") {
+
+ $targetImplementation .= "\n" . $targetFunction . "\n{\n *value = object->fapi2attr::${macroTarget}::${attribute};\n}\n";
+
+ } else {
+
+ $targetImplementation .= "\n" . $targetFunction . "\n{\n uint32_t index = (i_ptarget)->getTargetNumber();\n *value = object->fapi2attr::${macroTarget}::${attribute}[index];\n}\n";
+
+ }
+ push(@newTargetImplementations, $targetImplementation);
+ }
+ }
+ if (!$setMacro) {
+ if ($VERBOSE) { print "INFO:: did not find ${attribute}_SETMACRO\n"; }
+ my $attributeDefine = "#define ${attribute}_SETMACRO ${macroPrefix}SET${macroPostfix}";
+ push(@newAttributeDefines, $attributeDefine);
+
+ if(defined $targetMacro) {
+
+ my $targetFunction = "template<> void __set<fapi2::$targetMacro, fapi2attr::$macroTarget, $type, fapi2::${attribute}> ( const fapi2::Target<fapi2::$targetMacro>* i_ptarget, fapi2attr::$macroTarget* object, const fapi2::AttributeId attrid, $type* value )";
+ push(@newTargetDefines, $targetFunction . ";");
+
+ my $targetImplementation = "";
+
+ if($targetMacro eq "TARGET_TYPE_PROC_CHIP") {
+
+ $targetImplementation = "\n" . $targetFunction . "\n{\n object->fapi2attr::${macroTarget}::${attribute} = *value;\n}\n";
+ } else {
+ $targetImplementation = "\n" . $targetFunction . "\n{\n uint32_t index = (i_ptarget)->getTargetNumber();\n object->fapi2attr::${macroTarget}::${attribute}[index] = *value;\n}\n";
+ }
+
+ push(@newTargetImplementations, $targetImplementation);
+ }
+ }
+ }
+}
+
+# if file is missing any GET or SET MACROs
+if (@newAttributeDefines != 0) {
+
+ my $updatedFapiPlatAttributeServiceFile = "$fapiPlatAttributeServiceFile.temp";
+ open (OUTFILE, ">$updatedFapiPlatAttributeServiceFile") or die "ERROR:: could not open $updatedFapiPlatAttributeServiceFile\n";
+ open (FILE, $includePath . "/" . $fapiPlatAttributeServiceFile) or die "ERROR:: could not open $fapiPlatAttributeServiceFile\n";
+
+ my $insertTagFound = 0;
+
+ while (<FILE>) {
+ print OUTFILE $_;
+ # search for tag to insert after
+ if (m/\/\*.*INSERT NEW ATTRIBUTES HERE.*\*\//) {
+ $insertTagFound = 1;
+ # insert missing GET or SET MACROs
+ print OUTFILE "\n";
+ foreach my $attributeDefine (@newAttributeDefines) {
+ print OUTFILE "$attributeDefine\n";
+ if ($VERBOSE) { print "INFO:: adding $attributeDefine\n"; }
+ }
+ }
+
+ if (m/\/\*.*INSERT NEW GETTER AND SETTER FUNCTIONS HERE.*\*\//) {
+
+ $insertTagFound = 1;
+ # insert missing GET or SET MACROs
+ print OUTFILE "\n";
+ foreach my $targetDefine (@newTargetDefines) {
+ print OUTFILE "$targetDefine\n";
+ if ($VERBOSE) { print "INFO:: adding getter setter method\n"; }
+ }
+ }
+
+
+ }
+ close (FILE);
+ close (OUTFILE);
+
+ if ($insertTagFound == 0) {
+ # remove file that we did not update
+ system("rm $updatedFapiPlatAttributeServiceFile");
+ print ("WARNING:: did not find tag \"INSERT NEW ATTRIBUTES HERE\" in $fapiPlatAttributeServiceFile. no updates performed.\n");
+ } else {
+ # copy new file over the old one
+ system("mv $updatedFapiPlatAttributeServiceFile $includePath/$fapiPlatAttributeServiceFile");
+ }
+
+
+ my $updatedFapiPlatAttributeServiceImpl = $srcPath . "/" . $fapiPlatAttributeServiceImpl;
+ open (OUTFILE, ">$updatedFapiPlatAttributeServiceImpl") or die "ERROR:: could not open $updatedFapiPlatAttributeServiceImpl\n";
+
+ print OUTFILE "// $fapiPlatAttributeServiceImpl\n";
+ print OUTFILE "// This file is generated by perl script ppeCreateAttrGetSetMacros.pl\n\n";
+
+ print OUTFILE "#include <fapi2.H>\n";
+ print OUTFILE "#include <fapi2PlatAttributeService.H>\n";
+ print OUTFILE "#include \"proc_sbe_fixed.H\"\n";
+ print OUTFILE "#include \"plat_target_parms.H\"\n\n";
+ print OUTFILE "namespace fapi2 {\n";
+
+
+ foreach my $impl (@newTargetImplementations) {
+
+ print OUTFILE $impl;
+
+ }
+
+ print OUTFILE "\n} // namespace fapi2\n";
+
+
+ close (OUTFILE);
+}
+
+
+
+
+exit;
+
+# enumParser state machine
+# "enum" "enum_name" "{" "entry" "}"
+# [0] ------> [1] -------------> [2] ---> [3] -----------> [4] -------------------------------------> [7]
+# "," "=" "value" "}"
+# [3] <----------- [4] ----> [5] --------> [6] -------------> [7]
+# "}" ";"
+# [3] -----------------------------------------------------> [7] ---> [0]
+# ","
+#
+# [3] <----------------------------------- [6]
+#
+
+sub enumParser ($){
+ my $line = $_[0];
+ chomp($line);
+
+ if ($DEBUG) { print "DEBUG:: state = $state : line = \"$line\"\n"; }
+
+ if ($state == 0) {
+ # find enum as first word
+ if ($line =~ m/\s*enum\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found enum in $line\n"; }
+ $state = 1;
+ # reset last_value
+ $last_value = -1;
+ # reset current_entry
+ $current_entry = "";
+ # reset current_enum_name;
+ $current_enum_name = "";
+ # remove enum from line recheck
+ $line =~ s/\s*enum\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 1) {
+ # find ENUM_NAME as first word
+ if ($line =~ m/\s*(\w+)\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found ENUM_NAME $1 in $line\n"; }
+ $state = 2;
+ my $enum_name = $1;
+ $current_enum_name = $enum_name;
+ # remove ENUM_NAME from line
+ $line =~ s/\s*$enum_name\s*//;
+ #recheck
+ enumParser($line);
+ }
+ } elsif ($state == 2) {
+ # find { as first word
+ if ($line =~ m/\s*{\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found { in $line\n"; }
+ $state = 3;
+ # remove { from line recheck
+ $line =~ s/\s*{\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 3) {
+ # find ENTRY as first word
+ if ($line =~ m/\s*(\w+)\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found ENTRY $1 in $line\n"; }
+ my $entry = $1;
+ $current_entry = $entry;
+ # remove ENTRY from line
+ $line =~ s/\s*$entry\s*//;
+ $state = 4;
+ #recheck
+ enumParser($line);
+ }
+ # find } as first word
+ elsif ($line =~ m/\s*}\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found } in $line\n"; }
+ $state = 7;
+ # remove } from line recheck
+ $line =~ s/\s*}\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 4) {
+ # find = as first word
+ if ($line =~ m/\s*=\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found = in $line\n"; }
+ $state = 5;
+ # remove = from line recheck
+ $line =~ s/\s*=\s*//;
+ enumParser($line);
+ }
+ # find , as first word
+ elsif ($line =~ m/\s*,\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found , in $line\n"; }
+ $state = 3;
+ # assign next last_value to entry
+ $last_value++;
+ my $value = $last_value;
+ if ($DEBUG) { print "DEBUG:: default VALUE $value assigned to $current_entry\n"; }
+ $enums{$current_enum_name}{$current_entry} = $value;
+ # remove , from line recheck
+ $line =~ s/\s*,\s*//;
+ enumParser($line);
+ }
+ # find } as first word
+ elsif ($line =~ m/\s*}\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found } in $line\n"; }
+ $state = 7;
+ # remove } from line recheck
+ $line =~ s/\s*}\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 5) {
+ # find VALUE as first word
+ if ($line =~ m/\s*(\w+)\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found VALUE $1 in $line\n"; }
+ my $value = $1;
+ $last_value = $value;
+ # assign value to entry
+ if ($DEBUG) { print "DEBUG:: VALUE $value assigned to $current_entry\n"; }
+ $enums{$current_enum_name}{$current_entry} = $value;
+ # remove VALUE from line
+ $line =~ s/\s*$value\s*//;
+ $state = 6;
+ #recheck
+ enumParser($line);
+ }
+ } elsif ($state == 6) {
+ # find , as first word
+ if ($line =~ m/\s*,\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found , in $line\n"; }
+ $state = 3;
+ # remove , from line recheck
+ $line =~ s/\s*,\s*//;
+ enumParser($line);
+ }
+ # find } as first word
+ elsif ($line =~ m/\s*}\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found } in $line\n"; }
+ $state = 7;
+ # remove } from line recheck
+ $line =~ s/\s*}\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 7) {
+ # find ; as first word
+ if ($line =~ m/\s*;\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found ; in $line\n"; }
+ $state = 0;
+ # remove ; from line recheck
+ $line =~ s/\s*;\s*//;
+ enumParser($line);
+ }
+ }
+}
+
+sub help {
+ printf("Usage: ppeCreateAttrGetSetMacros.pl [--path <pathToFapiHeaders>] [--verbose] [--help] [--src <pathToFapiTemplate>] [--inc <pathToFapiOutput]\n");
+ printf("-path <pathToFapiHeaders> Option to enable specifying alternate path to fapi headers\n");
+ printf("-v | -verbose Inform user of findings and changes\n");
+ printf("-h | -help print this message\n");
+ exit(0);
+}
diff --git a/src/ppe/tools/scripts/ppeCreateIfAttrService.pl b/src/ppe/tools/scripts/ppeCreateIfAttrService.pl
new file mode 100755
index 0000000..a6abbfe
--- /dev/null
+++ b/src/ppe/tools/scripts/ppeCreateIfAttrService.pl
@@ -0,0 +1,241 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/scripts/ppeCreateIfAttrService.pl $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# Purpose: This perl script will parse HWP Attribute XML files and
+# initfile attr files and create the fapiGetInitFileAttr() function
+# in a file called fapi2AttributeService.C
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 3)
+{
+ print ("Usage: fapi2CreateIfAttrService.pl <output dir>\n");
+ print (" [<if-attr-file1> <if-attr-file2> ...]\n");
+ print (" -a <attr-xml-file1> [<attr-xml-file2> ...]\n");
+ print (" This perl script will parse if-attr files (containing the\n");
+ print (" attributes used by the initfile) and attribute XML files\n");
+ print (" (containing all HWPF attributes) and create the\n");
+ print (" fapiGetInitFileAttr() function in a file called\n");
+ print (" fapiAttributeService.C. Only the attributes specified in\n");
+ print (" the if-attr files are supported. If no if-attr files are\n");
+ print (" specified then all attributes are supported\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+#use Data::Dumper;
+
+#------------------------------------------------------------------------------
+# Open output file for writing
+#------------------------------------------------------------------------------
+my $asFile = $ARGV[0];
+$asFile .= "/";
+$asFile .= "fapi2AttributeService.C";
+open(ASFILE, ">", $asFile);
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributeService.C
+#------------------------------------------------------------------------------
+print ASFILE "// fapi2AttributeService.C\n";
+print ASFILE "// This file is generated by perl script fapi2CreateIfAttrService.pl\n\n";
+print ASFILE "#include <fapi2AttributeService.H>\n";
+print ASFILE "//#include <fapi2ChipEcFeature.H>\n";
+print ASFILE "//#include <fapi2PlatTrace.H>\n\n";
+print ASFILE "namespace fapi2\n";
+print ASFILE "{\n\n";
+print ASFILE "ReturnCode fapiGetInitFileAttr(const AttributeId i_id,\n";
+print ASFILE " const Target * i_pTarget,\n";
+print ASFILE " uint64_t & o_val,\n";
+print ASFILE " const uint32_t i_arrayIndex1,\n";
+print ASFILE " const uint32_t i_arrayIndex2,\n";
+print ASFILE " const uint32_t i_arrayIndex3,\n";
+print ASFILE " const uint32_t i_arrayIndex4)\n";
+print ASFILE "{\n";
+print ASFILE " ReturnCode l_rc;\n\n";
+
+my $xmlFiles = 0;
+my $attCount = 0;
+my $numIfAttrFiles = 0;
+my @attrIds;
+
+#------------------------------------------------------------------------------
+# Element names
+#------------------------------------------------------------------------------
+my $attribute = 'attribute';
+
+#------------------------------------------------------------------------------
+# For each argument
+#------------------------------------------------------------------------------
+my $argfile = $ARGV[1];
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+foreach my $entr (@{$entries->{entry}}) {
+
+ my $inname = $entr->{name};
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+ foreach my $argnum (2 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ # Uncomment to get debug output of all attributes
+ #print "\nFile: ", $infile, "\n", Dumper($attributes), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+
+
+ if($attr->{id} eq $inname) {
+
+ #------------------------------------------------------------------
+ # Check that the AttributeId exists
+ #------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'id' missing\n");
+ exit(1);
+ }
+
+
+ #------------------------------------------------------------------
+ # Figure out the number of attribute array dimensions
+ #------------------------------------------------------------------
+ my $numArrayDimensions = 0;
+ if ($attr->{array})
+ {
+ # Remove leading whitespace
+ my $dimText = $attr->{array};
+ $dimText =~ s/^\s+//;
+
+ # Split on commas or whitespace
+ my @vals = split(/\s*,\s*|\s+/, $dimText);
+
+ $numArrayDimensions=@vals;
+ }
+
+ #------------------------------------------------------------------
+ # Print the attribute get code to fapiAttributeService.C
+ #------------------------------------------------------------------
+ if ($attCount > 0)
+ {
+ print ASFILE " else ";
+ }
+ else
+ {
+ print ASFILE " ";
+ }
+ $attCount++;
+
+ print ASFILE "if (i_id == $attr->{id})\n";
+ print ASFILE " {\n";
+ print ASFILE " $attr->{id}_Type l_attr;\n";
+
+ if (exists $attr->{privileged})
+ {
+ print ASFILE " l_rc = FAPI_ATTR_GET_PRIVILEGED($attr->{id}, i_pTarget, l_attr);\n";
+ }
+ else
+ {
+ print ASFILE " l_rc = FAPI_ATTR_GET($attr->{id}, i_pTarget, l_attr);\n";
+ }
+ print ASFILE " o_val = l_attr";
+
+ if ($numArrayDimensions >= 5)
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. More than 4 array dimensions!!\n");
+ exit(1);
+ }
+ else
+ {
+ for (my $i = 0; $i < $numArrayDimensions; $i++)
+ {
+ print ASFILE "[i_arrayIndex";
+ print ASFILE $i+1;
+ print ASFILE "]";
+ }
+ }
+
+ print ASFILE ";\n";
+ print ASFILE " }\n";
+
+
+
+ }
+ }
+ }
+
+}
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiAttributeService.C
+#--------------------------------------------------------------------------
+if ($attCount > 0)
+{
+ print ASFILE " else\n";
+}
+print ASFILE " {\n";
+print ASFILE " FAPI_ERR(\"fapiGetInitFileAttr: Unrecognized attr ID: 0x%x\", i_id);\n";
+print ASFILE " l_rc.setFapiError(FAPI_RC_INVALID_ATTR_GET);\n";
+print ASFILE " l_rc.addEIFfdc(0, &i_id, sizeof(i_id));\n";
+print ASFILE " }\n\n";
+print ASFILE " if (l_rc)\n";
+print ASFILE " {\n";
+print ASFILE " if (i_pTarget)\n";
+print ASFILE " {\n";
+print ASFILE " FAPI_ERR(\"fapiGetInitFileAttr: Error getting attr ID 0x%x from targType 0x%x\",\n";
+print ASFILE " i_id, i_pTarget->getType());\n";
+print ASFILE " }\n";
+print ASFILE " else\n";
+print ASFILE " {\n";
+print ASFILE " FAPI_ERR(\"fapiGetInitFileAttr: Error getting attr ID 0x%x from system target\",\n";
+print ASFILE " i_id);\n";
+print ASFILE " }\n";
+print ASFILE " }\n\n";
+print ASFILE " return l_rc;\n";
+print ASFILE "}\n\n";
+print ASFILE "}\n";
+
+
+#------------------------------------------------------------------------------
+# Close output file
+#------------------------------------------------------------------------------
+close(ASFILE);
diff --git a/src/ppe/tools/scripts/ppeParseAttrGetSetMacros.pl b/src/ppe/tools/scripts/ppeParseAttrGetSetMacros.pl
new file mode 100644
index 0000000..a1edf32
--- /dev/null
+++ b/src/ppe/tools/scripts/ppeParseAttrGetSetMacros.pl
@@ -0,0 +1,284 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/scripts/ppeParseAttrGetSetMacros.pl $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# Purpose: This perl script will parse HWP Attribute XML files and
+# initfile attr files and create the fapiGetInitFileAttr() function
+# in a file called fapiAttributeService.C
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 3)
+{
+ print ("Usage: ppeParseAttrGetSetMacros.pl <output dir>\n");
+ print (" [<if-attr-file1> <if-attr-file2> ...]\n");
+ print (" -a <attr-xml-file1> [<attr-xml-file2> ...]\n");
+ print (" This perl script will parse if-attr files (containing the\n");
+ print (" attributes used by the initfile) and attribute XML files\n");
+ print (" (containing all HWPF attributes) and create the\n");
+ print (" fapiGetInitFileAttr() function in a file called\n");
+ print (" fapiAttributeService.C. Only the attributes specified in\n");
+ print (" the if-attr files are supported. If no if-attr files are\n");
+ print (" specified then all attributes are supported\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+#use Data::Dumper;
+
+#------------------------------------------------------------------------------
+# Open output file for writing
+#------------------------------------------------------------------------------
+my $chipFile = $ARGV[0];
+$chipFile .= "/";
+$chipFile .= "fapi2_attribute_getsettemplates.h";
+open(CHFILE, ">", $chipFile);
+
+my $exFile = $ARGV[0];
+$exFile .= "/";
+$exFile .= "proc_sbe_fixed_ex.H";
+open(EXFILE, ">", $exFile);
+
+my $coreFile = $ARGV[0];
+$coreFile .= "/";
+$coreFile .= "proc_sbe_fixed_core.H";
+open(COFILE, ">", $coreFile);
+
+my $eqFile = $ARGV[0];
+$eqFile .= "/";
+$eqFile .= "proc_sbe_fixed_eq.H";
+open(EQFILE, ">", $eqFile);
+
+my $pervFile = $ARGV[0];
+$pervFile .= "/";
+$pervFile .= "proc_sbe_fixed_perv.H";
+open(PEFILE, ">", $pervFile);
+
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributeService.C
+#------------------------------------------------------------------------------
+#print ASFILE "// proc_sbe_func.H\n";
+#print ASFILE "// This file is generated by perl script fapi2ParseProcSbeFixed.pl\n\n";
+#print ASFILE "#ifndef __PROC_SBE_FIXED_H__\n";
+#print ASFILE "#define __PROC_SBE_FIXED_H__\n";
+#print ASFILE "#include \"p9_sbe.H\"\n";
+#print ASFILE "#include \"plat_target_parms.H\"\n";
+#print ASFILE "#include \"fapi2AttributeIds.H\"\n\n";
+
+
+my $xmlFiles = 0;
+my $attCount = 0;
+my $numIfAttrFiles = 0;
+my @attrChipIds;
+my @attrExIds;
+my @attrCoreIds;
+my @attrEqIds;
+my @attrPervIds;
+
+
+
+#------------------------------------------------------------------------------
+# Element names
+#------------------------------------------------------------------------------
+my $attribute = 'attribute';
+
+#------------------------------------------------------------------------------
+# For each argument
+#------------------------------------------------------------------------------
+my $argfile = $ARGV[1];
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+foreach my $entr (@{$entries->{entry}}) {
+
+ my $inname = $entr->{name};
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+ foreach my $argnum (2 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ # Uncomment to get debug output of all attributes
+ #print "\nFile: ", $infile, "\n", Dumper($attributes), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+ if($attr->{id} eq $inname) {
+
+ #------------------------------------------------------------------
+ # Check that the AttributeId exists
+ #------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("ppeParseGetSetMacros.pl ERROR. Att 'id' missing\n");
+ exit(1);
+ }
+
+
+ if($attr->{targetType} eq "TARGET_TYPE_PROC_CHIP") {
+
+ push(@attrChipIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_CORE") {
+
+ push(@attrCoreIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_EQ") {
+
+ push(@attrEqIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_EX") {
+
+ push(@attrExIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_PERV") {
+
+# push(@attrPervIds, $attr->{id});
+ push(@attrPervIds, $attr);
+
+ } else {
+
+ print ("ppeParseAttrGetSetMacros.pl ERROR. Wrong attribute type: $attr->{targetType}\n");
+ exit(1);
+
+ }
+
+ }
+ }
+ }
+
+}
+
+
+print CHFILE "// proc_sbe_fixed_proc_chip.H\n";
+print CHFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print CHFILE "#ifndef __PROC_SBE_FIXED_PROC_CHIP_H__\n";
+print CHFILE "#define __PROC_SBE_FIXED_PROC_CHIP_H__\n\n";
+foreach my $attr (@attrChipIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print CHFILE "PROC_SBE_FIXED_$value($attr->{id});\n"
+
+
+}
+print CHFILE "\n#endif // __PROC_SBE_FIXED_PROC_CHIP_H__";
+
+print EXFILE "// proc_sbe_fixed_ex.H\n";
+print EXFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print EXFILE "#ifndef __PROC_SBE_FIXED_EX_H__\n";
+print EXFILE "#define __PROC_SBE_FIXED_EX_H__\n";
+foreach my $attr (@attrExIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print EXFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, EX_TARGET_COUNT);\n"
+
+
+}
+print EXFILE "\n#endif // __PROC_SBE_FIXED_EX_H__";
+
+
+print COFILE "// proc_sbe_fixed_co.H\n";
+print COFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print COFILE "#ifndef __PROC_SBE_FIXED_CO_H__\n";
+print COFILE "#define __PROC_SBE_FIXED_CO_H__\n";
+foreach my $attr (@attrCoreIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print COFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, CORE_TARGET_COUNT);\n"
+
+
+}
+print COFILE "\n#endif // __PROC_SBE_FIXED_CO_H__";
+
+
+
+print EQFILE "// proc_sbe_fixed_eq.H\n";
+print EQFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print EQFILE "#ifndef __PROC_SBE_FIXED_EQ_H__\n";
+print EQFILE "#define __PROC_SBE_FIXED_EQ_H__\n";
+foreach my $attr (@attrEqIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print EQFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, EQ_TARGET_COUNT);\n"
+
+
+}
+print EQFILE "\n#endif // __PROC_SBE_FIXED_EQ_H__";
+
+
+
+print PEFILE "// proc_sbe_fixed_perv.H\n";
+print PEFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print PEFILE "#ifndef __PROC_SBE_FIXED_PERV_H__\n";
+print PEFILE "#define __PROC_SBE_FIXED_PERV_H__\n";
+foreach my $attr (@attrPervIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print PEFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, PERV_TARGET_COUNT);\n"
+
+
+}
+print PEFILE "\n#endif // __PROC_SBE_FIXED_PERV_H__";
+
+
+
+
+
+
+
+
+#print ASFILE "#endif // __PROC_SBE_FIXED_H__";
+
+
+#------------------------------------------------------------------------------
+# Close output file
+#------------------------------------------------------------------------------
+close(CHFILE);
+close(COFILE);
+close(EXFILE);
+close(PEFILE);
+close(EQFILE);
+
diff --git a/src/ppe/tools/scripts/ppeParseAttributeInfo.pl b/src/ppe/tools/scripts/ppeParseAttributeInfo.pl
new file mode 100755
index 0000000..339f5d0
--- /dev/null
+++ b/src/ppe/tools/scripts/ppeParseAttributeInfo.pl
@@ -0,0 +1,1090 @@
+#!/usr/bin/perl -w
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/scripts/ppeParseAttributeInfo.pl $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# Purpose: This perl script will parse HWP Attribute XML files
+# and add attribute information to a file called fapi2AttributeIds.H
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 2)
+{
+ print ("Usage: ppeParseAttributeInfo.pl <output dir> <attr-xml-file1> [<attr-xml-file2> ...]\n");
+ print (" This perl script will parse attribute XML files and create the following files:\n");
+ print (" - fapi2AttributeIds.H. Contains IDs, type, value enums and other information\n");
+ print (" - fapi2ChipEcFeature.C. Contains a function to query chip EC features\n");
+ print (" - fapi2AttributePlatCheck.H. Contains compile time checks that all attributes are\n");
+ print (" handled by the platform\n");
+ print (" - fapi2AttributesSupported.html Contains the HWPF attributes supported\n");
+ print (" - fapi2AttrInfo.csv Used to process Attribute Override Text files\n");
+ print (" - fapi2AttrEnumInfo.csv Used to process Attribute Override Text files\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use Digest::MD5 qw(md5_hex);
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+#use Data::Dumper;
+
+#------------------------------------------------------------------------------
+# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains
+# bugs that result in XML parse errors that can be fixed by adjusting white-
+# space (i.e. parse errors that do not make sense).
+#------------------------------------------------------------------------------
+$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
+
+#------------------------------------------------------------------------------
+# Open output files for writing
+#------------------------------------------------------------------------------
+my $aiFile = $ARGV[0];
+$aiFile .= "/";
+$aiFile .= "fapi2AttributeIds.H";
+open(AIFILE, ">", $aiFile);
+
+my $ecFile = $ARGV[0];
+$ecFile .= "/";
+$ecFile .= "fapi2ChipEcFeature.C";
+open(ECFILE, ">", $ecFile);
+
+my $acFile = $ARGV[0];
+$acFile .= "/";
+$acFile .= "fapi2AttributePlatCheck.H";
+open(ACFILE, ">", $acFile);
+
+my $asFile = $ARGV[0];
+$asFile .= "/";
+$asFile .= "fapi2AttributesSupported.html";
+open(ASFILE, ">", $asFile);
+
+my $itFile = $ARGV[0];
+$itFile .= "/";
+$itFile .= "fapi2AttrInfo.csv";
+open(ITFILE, ">", $itFile);
+
+my $etFile = $ARGV[0];
+$etFile .= "/";
+$etFile .= "fapi2AttrEnumInfo.csv";
+open(ETFILE, ">", $etFile);
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributeIds.H
+#------------------------------------------------------------------------------
+print AIFILE "// fapi2AttributeIds.H\n";
+print AIFILE "// This file is generated by perl script fapiParseAttributeInfo.pl\n\n";
+print AIFILE "#ifndef FAPI2ATTRIBUTEIDS_H_\n";
+print AIFILE "#define FAPI2ATTRIBUTEIDS_H_\n\n";
+print AIFILE "#ifndef __ASSEMBLER__\n\n";
+print AIFILE "#include <target.H>\n";
+print AIFILE "#include <target_types.H>\n\n";
+print AIFILE "namespace fapi2\n";
+print AIFILE "{\n\n";
+print AIFILE "\/**\n";
+print AIFILE " * \@brief Enumeration of attribute IDs\n";
+print AIFILE " *\/\n";
+print AIFILE "enum AttributeId\n{\n";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiChipEcFeature.C
+#------------------------------------------------------------------------------
+print ECFILE "// fapiChipEcFeature.C\n";
+print ECFILE "// This file is generated by perl script fapiParseAttributeInfo.pl\n";
+print ECFILE "// It implements the fapiQueryChipEcFeature function\n\n";
+print ECFILE "#include <fapiChipEcFeature.H>\n";
+print ECFILE "#include <fapiAttributeService.H>\n";
+print ECFILE "#include <fapiSystemConfig.H>\n";
+print ECFILE "#include <fapiPlatTrace.H>\n\n";
+print ECFILE "namespace fapi2\n";
+print ECFILE "{\n\n";
+print ECFILE "fapi::ReturnCode fapiQueryChipEcFeature(fapi::AttributeId i_id,\n";
+print ECFILE " const fapi::Target * i_pTarget,\n";
+print ECFILE " uint8_t & o_hasFeature)\n";
+print ECFILE "{\n";
+print ECFILE " o_hasFeature = false;\n";
+print ECFILE " fapi::ReturnCode l_rc;\n";
+print ECFILE " uint8_t l_chipName = 0;\n";
+print ECFILE " uint8_t l_chipEc = 0;\n";
+print ECFILE " fapi::Target l_target = *i_pTarget;\n\n";
+print ECFILE " if (i_pTarget->isChiplet())\n";
+print ECFILE " {\n";
+print ECFILE " l_rc = fapiGetParentChip(*i_pTarget, l_target);\n\n";
+print ECFILE " if (l_rc)\n";
+print ECFILE " {\n";
+print ECFILE " FAPI_ERR(\"fapiQueryChipEcFeature: error getting parent chip\");\n";
+print ECFILE " }\n";
+print ECFILE " }\n\n";
+print ECFILE " if (!l_rc)\n";
+print ECFILE " {\n";
+print ECFILE " l_rc = FAPI_ATTR_GET_PRIVILEGED(ATTR_NAME, &l_target, l_chipName);\n\n";
+print ECFILE " if (l_rc)\n";
+print ECFILE " {\n";
+print ECFILE " FAPI_ERR(\"fapiQueryChipEcFeature: error getting chip name\");\n";
+print ECFILE " }\n";
+print ECFILE " else\n";
+print ECFILE " {\n";
+print ECFILE " l_rc = FAPI_ATTR_GET_PRIVILEGED(ATTR_EC, &l_target, l_chipEc);\n\n";
+print ECFILE " if (l_rc)\n";
+print ECFILE " {\n";
+print ECFILE " FAPI_ERR(\"fapiQueryChipEcFeature: error getting chip ec\");\n";
+print ECFILE " }\n";
+print ECFILE " else\n";
+print ECFILE " {\n";
+print ECFILE " switch (i_id)\n";
+print ECFILE " {\n";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributePlatCheck.H
+#------------------------------------------------------------------------------
+print ACFILE "// fapiAttributePlatCheck.H\n";
+print ACFILE "// This file is generated by perl script fapiParseAttributeInfo.pl\n";
+print ACFILE "// A platform can include it to ensure that it handles all HWPF\n";
+print ACFILE "// attributes\n\n";
+print ACFILE "#ifndef FAPIATTRIBUTEPLATCHECK_H_\n";
+print ACFILE "#define FAPIATTRIBUTEPLATCHECK_H_\n\n";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributesSupported.html
+#------------------------------------------------------------------------------
+print ASFILE "<html>\n";
+print ASFILE "<body>\n\n";
+print ASFILE "<!-- fapiAttributesSupported.html -->\n";
+print ASFILE "<!-- This file is generated by perl script fapiParseAttributeInfo.pl -->\n";
+print ASFILE "<!-- It lists all HWPF attributes supported -->\n\n";
+print ASFILE "<h4>HWPF Attributes supported by this build.</h4>\n";
+print ASFILE "<table border=\"4\">\n";
+print ASFILE "<tr><th>Attribute ID</th><th>Attribute Description</th></tr>";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttrInfo.csv
+#------------------------------------------------------------------------------
+print ITFILE "# fapiAttrInfo.csv\n";
+print ITFILE "# This file is generated by perl script fapiParseAttributeInfo.pl\n";
+print ITFILE "# It lists information about FAPI attributes and is used to\n";
+print ITFILE "# process FAPI Attribute text files (overrides/syncs)\n";
+print ITFILE "# Format:\n";
+print ITFILE "# <FAPI-ATTR-ID-STR>,<LAYER-ATTR-ID-STR>,<ATTR-ID-VAL>,<ATTR-TYPE>\n";
+print ITFILE "# Note that for the AttributeTanks at the FAPI layer, the\n";
+print ITFILE "# FAPI-ATTR-ID-STR and LAYER-ATTR-ID-STR will be identical\n";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttrEnumInfo.csv
+#------------------------------------------------------------------------------
+print ETFILE "# fapiAttrEnumInfo.csv\n";
+print ETFILE "# This file is generated by perl script fapiParseAttributeInfo.pl\n";
+print ETFILE "# It lists information about FAPI attribute enumeratorss and is\n";
+print ETFILE "# used to process FAPI Attribute text files (overrides/syncs)\n";
+print ETFILE "# Format:\n";
+print ETFILE "# <ENUM-STR>,<ENUM-VAL>\n";
+
+my %attrIdHash; # Records which Attribute IDs have been used
+my %attrValHash; # Records which Attribute values have been used
+
+#------------------------------------------------------------------------------
+# For each XML file
+#------------------------------------------------------------------------------
+#my $argfile = "p9_ppe_attributes.xml";
+my $argfile = $ARGV[1];
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+foreach my $entr (@{$entries->{entry}}) {
+
+# print " $entr->{file}, $entr->{name}\n";
+
+ #my $infile = $entr->{file};
+ my $inname = $entr->{name};
+
+foreach my $argnum (2 .. $#ARGV)
+{
+ my $infile = $ARGV[$argnum];
+
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ # Uncomment to get debug output of all attributes
+ #print "\nFile: ", $infile, "\n", Dumper($attributes), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+ #print "? $attr->{id}, $inname\n";
+
+ if($attr->{id} eq $inname) {
+
+ #print "yes $attr->{id}, $inname\n";
+
+ #----------------------------------------------------------------------
+ # Print the Attribute ID and calculated value to fapiAttributeIds.H and
+ # fapiAttributeIds.txt. The value for an attribute is a hash value
+ # generated from the attribute name, this ties a specific value to a
+ # specific attribute name. This is done for Cronus so that if a HWP is
+ # not recompiled against a new eCMD/Cronus version where the attributes
+ # have changed then there will not be a mismatch in enumerator values.
+ # This is a 28bit hash value because the Initfile compiler has a
+ # requirement that the top nibble of the 32 bit attribute ID be zero to
+ # store flags
+ #----------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Attribute 'id' missing in $infile\n");
+ exit(1);
+ }
+
+ if (exists($attrIdHash{$attr->{id}}))
+ {
+ # Two different attributes with the same id!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate Attribute id $attr->{id} in $infile\\n");
+ exit(1);
+ }
+
+ # Calculate a 28 bit hash value.
+ my $attrHash128Bit = md5_hex($attr->{id});
+ my $attrHash28Bit = substr($attrHash128Bit, 0, 7);
+
+ # Print the attribute ID/value to fapiAttributeIds.H
+ print AIFILE " $attr->{id} = 0x$attrHash28Bit,\n";
+
+ if (exists($attrValHash{$attrHash28Bit}))
+ {
+ # Two different attributes generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate attr id hash value for $attr->{id} in $infile\ \n");
+ exit(1);
+ }
+
+ $attrIdHash{$attr->{id}} = $attrHash28Bit;
+ $attrValHash{$attrHash28Bit} = 1;
+ }
+ };
+}
+}
+
+#------------------------------------------------------------------------------
+# Print AttributeId enumeration end to fapiAttributeIds.H
+#------------------------------------------------------------------------------
+print AIFILE "};\n\n";
+
+#------------------------------------------------------------------------------
+# Print Attribute Information comment to fapiAttributeIds.H
+#------------------------------------------------------------------------------
+print AIFILE "\/**\n";
+print AIFILE " * \@brief Attribute Information\n";
+print AIFILE " *\/\n";
+
+
+foreach my $entr (@{$entries->{entry}}) {
+
+# print " $entr->{file}, $entr->{name}\n";
+
+# my $infile = $entr->{file};
+ my $inname = $entr->{name};
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+foreach my $argnum (2 .. $#ARGV)
+{
+ my $infile = $ARGV[$argnum];
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ # Uncomment to get debug output of all attributes
+ #print "\nFile: ", $infile, "\n", Dumper($attributes), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+
+
+ if($attr->{id} eq $inname) {
+
+ #----------------------------------------------------------------------
+ # Print a comment with the attribute ID fapiAttributeIds.H
+ #----------------------------------------------------------------------
+ print AIFILE "/* $attr->{id} */\n";
+
+ #----------------------------------------------------------------------
+ # Print the AttributeId and description to fapiAttributesSupported.html
+ #----------------------------------------------------------------------
+ if (! exists $attr->{description})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Attribute 'description' missing for $attr->{id} in $infile\n");
+ exit(1);
+ }
+
+
+ #----------------------------------------------------------------------
+ # Figure out the attribute array dimensions (if array)
+ #----------------------------------------------------------------------
+ my $arrayDimensions = "";
+ my $numArrayDimensions = 0;
+ if ($attr->{array})
+ {
+ # Remove leading whitespace
+ my $dimText = $attr->{array};
+ $dimText =~ s/^\s+//;
+
+ # Split on commas or whitespace
+ my @vals = split(/\s*,\s*|\s+/, $dimText);
+
+ foreach my $val (@vals)
+ {
+ $arrayDimensions .= "[${val}]";
+ $numArrayDimensions++;
+ }
+ }
+
+ #----------------------------------------------------------------------
+ # Print the typedef for each attribute's val type to fapiAttributeIds.H
+ # Print the attribute information to fapiAttrInfo.csv
+ #----------------------------------------------------------------------
+ if (exists $attr->{chipEcFeature})
+ {
+ # The value type of chip EC feature attributes is uint8_t
+ print AIFILE "typedef uint8_t $attr->{id}_Type;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u8\n"
+ }
+ else
+ {
+ if (! exists $attr->{valueType})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'valueType' missing for $attr->{id} in $infile\n");
+ exit(1);
+ }
+
+ if ($attr->{valueType} eq 'uint8')
+ {
+ print AIFILE "typedef uint8_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u8" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'uint16')
+ {
+ print AIFILE "typedef uint16_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u8" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'uint32')
+ {
+ print AIFILE "typedef uint32_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u32" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'uint64')
+ {
+ print AIFILE "typedef uint64_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u64" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'int8')
+ {
+ print AIFILE "typedef int8_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},8" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'int16')
+ {
+ print AIFILE "typedef int16_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},32" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'int32')
+ {
+ print AIFILE "typedef int32_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},32" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'int64')
+ {
+ print AIFILE "typedef int64_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},64" .
+ "$arrayDimensions\n";
+ }
+ else
+ {
+ print ("fapi2ParseAttributeInfo.pl ERROR. valueType not recognized: ");
+ print $attr->{valueType}, " for $attr->{id} in $infile\n";
+ exit(1);
+ }
+ }
+
+ #----------------------------------------------------------------------
+ # Print if the attribute is privileged
+ #----------------------------------------------------------------------
+ if (exists $attr->{privileged})
+ {
+ print AIFILE "const bool $attr->{id}_Privileged = true;\n";
+ }
+ else
+ {
+ print AIFILE "const bool $attr->{id}_Privileged = false;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the target type(s) that the attribute is associated with
+ #----------------------------------------------------------------------
+ if (! exists $attr->{targetType})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'targetType' missing for $attr->{id} in $infile\n");
+ exit(1);
+ }
+
+ print AIFILE "const TargetTypes_t $attr->{id}_TargetTypes = ";
+
+ # Split on commas
+ my @targTypes = split(',', $attr->{targetType});
+
+ my $targTypeCount = 0;
+ foreach my $targType (@targTypes)
+ {
+ # Remove newlines and leading/trailing whitespace
+ $targType =~ s/\n//;
+ $targType =~ s/^\s+//;
+ $targType =~ s/\s+$//;
+
+ if ($targTypeCount != 0)
+ {
+ print AIFILE " | ";
+ }
+ print AIFILE "$targType";
+ $targTypeCount++;
+ }
+ print AIFILE ";\n";
+
+ #----------------------------------------------------------------------
+ # Print if the attribute is a platInit attribute
+ #----------------------------------------------------------------------
+ if (exists $attr->{platInit})
+ {
+ print AIFILE "const bool $attr->{id}_PlatInit = true;\n";
+ }
+ else
+ {
+ print AIFILE "const bool $attr->{id}_PlatInit = false;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print if the attribute is a initToZero attribute
+ #----------------------------------------------------------------------
+ if (exists $attr->{initToZero})
+ {
+ print AIFILE "const bool $attr->{id}_InitToZero = true;\n";
+ }
+ else
+ {
+ print AIFILE "const bool $attr->{id}_InitToZero = false;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the value enumeration (if specified) to fapiAttributeIds.H and
+ # fapiAttributeEnums.txt
+ #----------------------------------------------------------------------
+ if (exists $attr->{enum})
+ {
+ print AIFILE "enum $attr->{id}_Enum\n{\n";
+
+ # Values must be separated by commas to allow for values to be
+ # specified: <enum>VAL_A = 3, VAL_B = 5, VAL_C = 0x23</enum>
+ my @vals = split(',', $attr->{enum});
+
+ foreach my $val (@vals)
+ {
+ # Remove newlines and leading/trailing whitespace
+ $val =~ s/\n//;
+ $val =~ s/^\s+//;
+ $val =~ s/\s+$//;
+
+ # Print the attribute enum to fapiAttributeIds.H
+ print AIFILE " ENUM_$attr->{id}_${val}";
+
+ # Print the attribute enum to fapiAttrEnumInfo.csv
+ my $attrEnumTxt = "$attr->{id}_${val}\n";
+ $attrEnumTxt =~ s/ = /,/;
+ print ETFILE $attrEnumTxt;
+
+ if ($attr->{valueType} eq 'uint64')
+ {
+ print AIFILE "ULL";
+ }
+
+ print AIFILE ",\n";
+ }
+
+ print AIFILE "};\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print _GETMACRO and _SETMACRO where appropriate to fapiAttributeIds.H
+ #----------------------------------------------------------------------
+ if (exists $attr->{chipEcFeature})
+ {
+ #------------------------------------------------------------------
+ # The attribute is a Chip EC Feature, define _GETMACRO to call a
+ # fapi function and define _SETMACRO to something that will cause a
+ # compile failure if a set is attempted
+ #------------------------------------------------------------------
+ print AIFILE "#define $attr->{id}_GETMACRO(ID, PTARGET, VAL) \\\n";
+ print AIFILE " PLAT_GET_CHIP_EC_FEATURE_OVERRIDE(ID, PTARGET, VAL) ? fapi::FAPI_RC_SUCCESS : \\\n";
+ print AIFILE " fapi::fapiQueryChipEcFeature(fapi::ID, PTARGET, VAL)\n";
+ print AIFILE "#define $attr->{id}_SETMACRO(ID, PTARGET, VAL) ";
+ print AIFILE "CHIP_EC_FEATURE_ATTRIBUTE_NOT_WRITABLE\n";
+ }
+ elsif (! exists $attr->{writeable})
+ {
+ #------------------------------------------------------------------
+ # The attribute is read-only, define the _SETMACRO to something
+ # that will cause a compile failure if a set is attempted
+ #------------------------------------------------------------------
+ if (! exists $attr->{writeable})
+ {
+ print AIFILE "#define $attr->{id}_SETMACRO ATTRIBUTE_NOT_WRITABLE\n";
+ }
+ }
+
+ #----------------------------------------------------------------------
+ # If the attribute is a Chip EC Feature, print the chip EC feature
+ # query to fapiChipEcFeature.C
+ #----------------------------------------------------------------------
+ if (exists $attr->{chipEcFeature})
+ {
+ my $chipCount = 0;
+ print ECFILE " case $attr->{id}:\n";
+ print ECFILE " if (\n";
+
+ foreach my $chip (@{$attr->{chipEcFeature}->{chip}})
+ {
+ $chipCount++;
+
+ if (! exists $chip->{name})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'name' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'ec' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec}->{value})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'value' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec}->{test})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'test' missing\n");
+ exit(1);
+ }
+
+ my $test;
+ if ($chip->{ec}->{test} eq 'EQUAL')
+ {
+ $test = '==';
+ }
+ elsif ($chip->{ec}->{test} eq 'GREATER_THAN')
+ {
+ $test = '>';
+ }
+ elsif ($chip->{ec}->{test} eq 'GREATER_THAN_OR_EQUAL')
+ {
+ $test = '>=';
+ }
+ elsif ($chip->{ec}->{test} eq 'LESS_THAN')
+ {
+ $test = '<';
+ }
+ elsif ($chip->{ec}->{test} eq 'LESS_THAN_OR_EQUAL')
+ {
+ $test = '<=';
+ }
+ else
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. test '$chip->{ec}->{test}' unrecognized\n");
+ exit(1);
+ }
+
+ if ($chipCount > 1)
+ {
+ print ECFILE " ||\n";
+ }
+ print ECFILE " ((l_chipName == $chip->{name}) &&\n";
+ print ECFILE " (l_chipEc $test $chip->{ec}->{value}))\n";
+ }
+
+ print ECFILE " )\n";
+ print ECFILE " {\n";
+ print ECFILE " o_hasFeature = true;\n";
+ print ECFILE " }\n";
+ print ECFILE " break;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the platform attribute checks to fapiAttributePlatCheck.H
+ #----------------------------------------------------------------------
+ if (exists $attr->{writeable})
+ {
+ print ACFILE "#ifndef $attr->{id}_SETMACRO\n";
+ print ACFILE "#error Platform does not support set of HWPF attr $attr->{id}\n";
+ print ACFILE "#endif\n";
+ }
+
+ print ACFILE "#ifndef $attr->{id}_GETMACRO\n";
+ print ACFILE "#error Platform does not support get of HWPF attr $attr->{id}\n";
+ print ACFILE "#endif\n\n";
+
+ #----------------------------------------------------------------------
+ # Print newline between each attribute's info to fapiAttributeIds.H
+ #----------------------------------------------------------------------
+ print AIFILE "\n";
+
+
+
+
+
+ }
+ };
+}
+}
+
+
+
+=for comment
+
+#------------------------------------------------------------------------------
+# For each XML file
+#------------------------------------------------------------------------------
+foreach my $argnum (1 .. $#ARGV)
+{
+ my $infile = $ARGV[$argnum];
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute', 'chip']);
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+ #----------------------------------------------------------------------
+ # Print a comment with the attribute ID fapiAttributeIds.H
+ #----------------------------------------------------------------------
+ print AIFILE "/* $attr->{id} */\n";
+
+ #----------------------------------------------------------------------
+ # Print the AttributeId and description to fapiAttributesSupported.html
+ #----------------------------------------------------------------------
+ if (! exists $attr->{description})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'description' missing\n");
+ exit(1);
+ }
+
+ print ASFILE "<tr>\n";
+ print ASFILE " <td>$attr->{id}</td>\n";
+ print ASFILE " <td>$attr->{description}</td>\n";
+ print ASFILE "</tr>\n";
+
+ #----------------------------------------------------------------------
+ # Figure out the attribute array dimensions (if array)
+ #----------------------------------------------------------------------
+ my $arrayDimensions = "";
+ my $numArrayDimensions = 0;
+ if ($attr->{array})
+ {
+ # Remove leading whitespace
+ my $dimText = $attr->{array};
+ $dimText =~ s/^\s+//;
+
+ # Split on commas or whitespace
+ my @vals = split(/\s*,\s*|\s+/, $dimText);
+
+ foreach my $val (@vals)
+ {
+ $arrayDimensions .= "[${val}]";
+ $numArrayDimensions++;
+ }
+ }
+
+ #----------------------------------------------------------------------
+ # Print the typedef for each attribute's val type to fapiAttributeIds.H
+ # Print the attribute information to fapiAttrInfo.csv
+ #----------------------------------------------------------------------
+ if (exists $attr->{chipEcFeature})
+ {
+ # The value type of chip EC feature attributes is uint8_t
+ print AIFILE "typedef uint8_t $attr->{id}_Type;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u8\n"
+ }
+ else
+ {
+ if (! exists $attr->{valueType})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'valueType' missing\n");
+ exit(1);
+ }
+
+ if ($attr->{valueType} eq 'uint8')
+ {
+ print AIFILE "typedef uint8_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u8" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'uint32')
+ {
+ print AIFILE "typedef uint32_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u32" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'uint64')
+ {
+ print AIFILE "typedef uint64_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u64" .
+ "$arrayDimensions\n";
+ }
+ else
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. valueType not recognized: ");
+ print $attr->{valueType}, "\n";
+ exit(1);
+ }
+ }
+
+ #----------------------------------------------------------------------
+ # Print if the attribute is privileged
+ #----------------------------------------------------------------------
+ if (exists $attr->{privileged})
+ {
+ print AIFILE "const bool $attr->{id}_Privileged = true;\n";
+ }
+ else
+ {
+ print AIFILE "const bool $attr->{id}_Privileged = false;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the target type(s) that the attribute is associated with
+ #----------------------------------------------------------------------
+ if (! exists $attr->{targetType})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'targetType' missing\n");
+ exit(1);
+ }
+
+ print AIFILE "const TargetTypes_t $attr->{id}_TargetTypes = ";
+
+ # Split on commas
+ my @targTypes = split(',', $attr->{targetType});
+
+ my $targTypeCount = 0;
+ foreach my $targType (@targTypes)
+ {
+ # Remove newlines and leading/trailing whitespace
+ $targType =~ s/\n//;
+ $targType =~ s/^\s+//;
+ $targType =~ s/\s+$//;
+
+ if ($targTypeCount != 0)
+ {
+ print AIFILE " | ";
+ }
+ print AIFILE "$targType";
+ $targTypeCount++;
+ }
+ print AIFILE ";\n";
+
+ #----------------------------------------------------------------------
+ # Print if the attribute is a platInit attribute
+ #----------------------------------------------------------------------
+ if (exists $attr->{platInit})
+ {
+ print AIFILE "const bool $attr->{id}_PlatInit = true;\n";
+ }
+ else
+ {
+ print AIFILE "const bool $attr->{id}_PlatInit = false;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print if the attribute is a initToZero attribute
+ #----------------------------------------------------------------------
+ if (exists $attr->{initToZero})
+ {
+ print AIFILE "const bool $attr->{id}_InitToZero = true;\n";
+ }
+ else
+ {
+ print AIFILE "const bool $attr->{id}_InitToZero = false;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the value enumeration (if specified) to fapiAttributeIds.H and
+ # fapiAttributeEnums.txt
+ #----------------------------------------------------------------------
+ if (exists $attr->{enum})
+ {
+ print AIFILE "enum $attr->{id}_Enum\n{\n";
+
+ # Values must be separated by commas to allow for values to be
+ # specified: <enum>VAL_A = 3, VAL_B = 5, VAL_C = 0x23</enum>
+ my @vals = split(',', $attr->{enum});
+
+ foreach my $val (@vals)
+ {
+ # Remove newlines and leading/trailing whitespace
+ $val =~ s/\n//;
+ $val =~ s/^\s+//;
+ $val =~ s/\s+$//;
+
+ # Print the attribute enum to fapiAttributeIds.H
+ print AIFILE " ENUM_$attr->{id}_${val}";
+
+ # Print the attribute enum to fapiAttrEnumInfo.csv
+ my $attrEnumTxt = "$attr->{id}_${val}\n";
+ $attrEnumTxt =~ s/ = /,/;
+ print ETFILE $attrEnumTxt;
+
+ if ($attr->{valueType} eq 'uint64')
+ {
+ print AIFILE "ULL";
+ }
+
+ print AIFILE ",\n";
+ }
+
+ print AIFILE "};\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print _GETMACRO and _SETMACRO where appropriate to fapiAttributeIds.H
+ #----------------------------------------------------------------------
+ if (exists $attr->{chipEcFeature})
+ {
+ #------------------------------------------------------------------
+ # The attribute is a Chip EC Feature, define _GETMACRO to call a
+ # fapi function and define _SETMACRO to something that will cause a
+ # compile failure if a set is attempted
+ #------------------------------------------------------------------
+ print AIFILE "#define $attr->{id}_GETMACRO(ID, PTARGET, VAL) \\\n";
+ print AIFILE " PLAT_GET_CHIP_EC_FEATURE_OVERRIDE(ID, PTARGET, VAL) ? fapi::FAPI_RC_SUCCESS : \\\n";
+ print AIFILE " fapi::fapiQueryChipEcFeature(fapi::ID, PTARGET, VAL)\n";
+ print AIFILE "#define $attr->{id}_SETMACRO(ID, PTARGET, VAL) ";
+ print AIFILE "CHIP_EC_FEATURE_ATTRIBUTE_NOT_WRITABLE\n";
+ }
+ elsif (! exists $attr->{writeable})
+ {
+ #------------------------------------------------------------------
+ # The attribute is read-only, define the _SETMACRO to something
+ # that will cause a compile failure if a set is attempted
+ #------------------------------------------------------------------
+ if (! exists $attr->{writeable})
+ {
+ print AIFILE "#define $attr->{id}_SETMACRO ATTRIBUTE_NOT_WRITABLE\n";
+ }
+ }
+
+ #----------------------------------------------------------------------
+ # If the attribute is a Chip EC Feature, print the chip EC feature
+ # query to fapiChipEcFeature.C
+ #----------------------------------------------------------------------
+ if (exists $attr->{chipEcFeature})
+ {
+ my $chipCount = 0;
+ print ECFILE " case $attr->{id}:\n";
+ print ECFILE " if (\n";
+
+ foreach my $chip (@{$attr->{chipEcFeature}->{chip}})
+ {
+ $chipCount++;
+
+ if (! exists $chip->{name})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'name' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'ec' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec}->{value})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'value' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec}->{test})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'test' missing\n");
+ exit(1);
+ }
+
+ my $test;
+ if ($chip->{ec}->{test} eq 'EQUAL')
+ {
+ $test = '==';
+ }
+ elsif ($chip->{ec}->{test} eq 'GREATER_THAN')
+ {
+ $test = '>';
+ }
+ elsif ($chip->{ec}->{test} eq 'GREATER_THAN_OR_EQUAL')
+ {
+ $test = '>=';
+ }
+ elsif ($chip->{ec}->{test} eq 'LESS_THAN')
+ {
+ $test = '<';
+ }
+ elsif ($chip->{ec}->{test} eq 'LESS_THAN_OR_EQUAL')
+ {
+ $test = '<=';
+ }
+ else
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. test '$chip->{ec}->{test}' unrecognized\n");
+ exit(1);
+ }
+
+ if ($chipCount > 1)
+ {
+ print ECFILE " ||\n";
+ }
+ print ECFILE " ((l_chipName == $chip->{name}) &&\n";
+ print ECFILE " (l_chipEc $test $chip->{ec}->{value}))\n";
+ }
+
+ print ECFILE " )\n";
+ print ECFILE " {\n";
+ print ECFILE " o_hasFeature = true;\n";
+ print ECFILE " }\n";
+ print ECFILE " break;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the platform attribute checks to fapiAttributePlatCheck.H
+ #----------------------------------------------------------------------
+ if (exists $attr->{writeable})
+ {
+ print ACFILE "#ifndef $attr->{id}_SETMACRO\n";
+ print ACFILE "#error Platform does not support set of HWPF attr $attr->{id}\n";
+ print ACFILE "#endif\n";
+ }
+
+ print ACFILE "#ifndef $attr->{id}_GETMACRO\n";
+ print ACFILE "#error Platform does not support get of HWPF attr $attr->{id}\n";
+ print ACFILE "#endif\n\n";
+
+ #----------------------------------------------------------------------
+ # Print newline between each attribute's info to fapiAttributeIds.H
+ #----------------------------------------------------------------------
+ print AIFILE "\n";
+ };
+}
+
+=cut
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiAttributeIds.H
+#------------------------------------------------------------------------------
+print AIFILE "} //fapi2 \n\n";
+print AIFILE "#endif // __ASSEMBLER__\n\n";
+print AIFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiChipEcFeature.C
+#------------------------------------------------------------------------------
+print ECFILE " default:\n";
+print ECFILE " FAPI_ERR(\"fapiQueryChipEcFeature: Unknown feature 0x%x\",\n";
+print ECFILE " i_id);\n";
+print ECFILE " l_rc.setFapiError(FAPI_RC_INVALID_CHIP_EC_FEATURE_GET);\n";
+print ECFILE " l_rc.addEIFfdc(0, &i_id, sizeof(i_id));\n";
+print ECFILE " break;\n";
+print ECFILE " }\n\n";
+print ECFILE " if (o_hasFeature)\n";
+print ECFILE " {\n";
+print ECFILE " FAPI_INF(\"fapiQueryChipEcFeature: Chip (0x%x:0x%x) has ";
+print ECFILE "feature (0x%x)\", l_chipName, l_chipEc, i_id);\n";
+print ECFILE " }\n";
+print ECFILE " else\n";
+print ECFILE " {\n";
+print ECFILE " FAPI_INF(\"fapiQueryChipEcFeature: Chip (0x%x:0x%x) does not ";
+print ECFILE "have feature (0x%x)\", l_chipName, l_chipEc, i_id);\n";
+print ECFILE " }\n";
+print ECFILE " }\n";
+print ECFILE " }\n";
+print ECFILE " }\n";
+print ECFILE " return l_rc;\n";
+print ECFILE "}\n\n";
+print ECFILE "}\n";
+
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiAttributePlatCheck.H
+#------------------------------------------------------------------------------
+print ACFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiAttributesSupported.html
+#------------------------------------------------------------------------------
+print ASFILE "</table>\n\n";
+print ASFILE "</body>\n";
+print ASFILE "</html>\n";
+
+
+
+
+
+
+
+
+
+#------------------------------------------------------------------------------
+# Close output files
+#------------------------------------------------------------------------------
+close(AIFILE);
+close(ECFILE);
+close(ACFILE);
+close(ASFILE);
+close(ITFILE);
+close(ETFILE);
+
diff --git a/src/ppe/tools/scripts/ppeParseProcSbeFixed.pl b/src/ppe/tools/scripts/ppeParseProcSbeFixed.pl
new file mode 100755
index 0000000..8f25582
--- /dev/null
+++ b/src/ppe/tools/scripts/ppeParseProcSbeFixed.pl
@@ -0,0 +1,277 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/scripts/ppeParseProcSbeFixed.pl $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# Purpose: This perl script will parse HWP Attribute XML files and
+# initfile attr files and create the fapiGetInitFileAttr() function
+# in a file called fapiAttributeService.C
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 3)
+{
+ print ("Usage: ppeParseProcSbeFixed.pl <output dir>\n");
+ print (" [<if-attr-file1> <if-attr-file2> ...]\n");
+ print (" -a <attr-xml-file1> [<attr-xml-file2> ...]\n");
+ print (" This perl script will parse if-attr files (containing the\n");
+ print (" attributes used by the initfile) and attribute XML files\n");
+ print (" (containing all HWPF attributes) and create the\n");
+ print (" fapiGetInitFileAttr() function in a file called\n");
+ print (" fapiAttributeService.C. Only the attributes specified in\n");
+ print (" the if-attr files are supported. If no if-attr files are\n");
+ print (" specified then all attributes are supported\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+#use Data::Dumper;
+
+#------------------------------------------------------------------------------
+# Open output file for writing
+#------------------------------------------------------------------------------
+my $chipFile = $ARGV[0];
+$chipFile .= "/";
+$chipFile .= "proc_sbe_fixed_proc_chip.H";
+open(CHFILE, ">", $chipFile);
+
+my $exFile = $ARGV[0];
+$exFile .= "/";
+$exFile .= "proc_sbe_fixed_ex.H";
+open(EXFILE, ">", $exFile);
+
+my $coreFile = $ARGV[0];
+$coreFile .= "/";
+$coreFile .= "proc_sbe_fixed_core.H";
+open(COFILE, ">", $coreFile);
+
+my $eqFile = $ARGV[0];
+$eqFile .= "/";
+$eqFile .= "proc_sbe_fixed_eq.H";
+open(EQFILE, ">", $eqFile);
+
+my $pervFile = $ARGV[0];
+$pervFile .= "/";
+$pervFile .= "proc_sbe_fixed_perv.H";
+open(PEFILE, ">", $pervFile);
+
+
+
+my $xmlFiles = 0;
+my $attCount = 0;
+my $numIfAttrFiles = 0;
+my @attrChipIds;
+my @attrExIds;
+my @attrCoreIds;
+my @attrEqIds;
+my @attrPervIds;
+
+
+
+#------------------------------------------------------------------------------
+# Element names
+#------------------------------------------------------------------------------
+my $attribute = 'attribute';
+
+#------------------------------------------------------------------------------
+# For each argument
+#------------------------------------------------------------------------------
+my $argfile = $ARGV[1];
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+foreach my $entr (@{$entries->{entry}}) {
+
+ my $inname = $entr->{name};
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+ foreach my $argnum (2 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ # Uncomment to get debug output of all attributes
+ #print "\nFile: ", $infile, "\n", Dumper($attributes), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+ if($attr->{id} eq $inname) {
+
+ #------------------------------------------------------------------
+ # Check that the AttributeId exists
+ #------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'id' missing\n");
+ exit(1);
+ }
+
+
+ if($attr->{targetType} eq "TARGET_TYPE_PROC_CHIP") {
+
+ #push(@attrChipIds, $attr->{id});
+ push(@attrChipIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_CORE") {
+
+ # push(@attrCoreIds, $attr->{id});
+ push(@attrCoreIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_EQ") {
+
+ # push(@attrEqIds, $attr->{id});
+ push(@attrEqIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_EX") {
+
+ # push(@attrExIds, $attr->{id});
+ push(@attrExIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_PERV") {
+
+# push(@attrPervIds, $attr->{id});
+ push(@attrPervIds, $attr);
+
+ } else {
+
+ print ("ppeParseProcSbeFixed.pl ERROR. Wrong attribute type: $attr->{targetType} for attribute $attr->{id} in $infile\n");
+ exit(1);
+
+ }
+
+ }
+ }
+ }
+
+}
+
+
+print CHFILE "// proc_sbe_fixed_proc_chip.H\n";
+print CHFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print CHFILE "#ifndef __PROC_SBE_FIXED_PROC_CHIP_H__\n";
+print CHFILE "#define __PROC_SBE_FIXED_PROC_CHIP_H__\n\n";
+foreach my $attr (@attrChipIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print CHFILE "PROC_SBE_FIXED_$value($attr->{id});\n"
+
+
+}
+print CHFILE "\n#endif // __PROC_SBE_FIXED_PROC_CHIP_H__";
+
+print EXFILE "// proc_sbe_fixed_ex.H\n";
+print EXFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print EXFILE "#ifndef __PROC_SBE_FIXED_EX_H__\n";
+print EXFILE "#define __PROC_SBE_FIXED_EX_H__\n";
+foreach my $attr (@attrExIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print EXFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, EX_TARGET_COUNT);\n"
+
+
+}
+print EXFILE "\n#endif // __PROC_SBE_FIXED_EX_H__";
+
+
+print COFILE "// proc_sbe_fixed_co.H\n";
+print COFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print COFILE "#ifndef __PROC_SBE_FIXED_CO_H__\n";
+print COFILE "#define __PROC_SBE_FIXED_CO_H__\n";
+foreach my $attr (@attrCoreIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print COFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, CORE_TARGET_COUNT);\n"
+
+
+}
+print COFILE "\n#endif // __PROC_SBE_FIXED_CO_H__";
+
+
+
+print EQFILE "// proc_sbe_fixed_eq.H\n";
+print EQFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print EQFILE "#ifndef __PROC_SBE_FIXED_EQ_H__\n";
+print EQFILE "#define __PROC_SBE_FIXED_EQ_H__\n";
+foreach my $attr (@attrEqIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print EQFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, EQ_TARGET_COUNT);\n"
+
+
+}
+print EQFILE "\n#endif // __PROC_SBE_FIXED_EQ_H__";
+
+
+
+print PEFILE "// proc_sbe_fixed_perv.H\n";
+print PEFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print PEFILE "#ifndef __PROC_SBE_FIXED_PERV_H__\n";
+print PEFILE "#define __PROC_SBE_FIXED_PERV_H__\n";
+foreach my $attr (@attrPervIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print PEFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, PERV_TARGET_COUNT);\n"
+
+
+}
+print PEFILE "\n#endif // __PROC_SBE_FIXED_PERV_H__";
+
+
+
+
+
+
+
+
+#print ASFILE "#endif // __PROC_SBE_FIXED_H__";
+
+
+#------------------------------------------------------------------------------
+# Close output file
+#------------------------------------------------------------------------------
+close(CHFILE);
+close(COFILE);
+close(EXFILE);
+close(PEFILE);
+close(EQFILE);
+
diff --git a/src/ppe/tools/scripts/src/fapi2PlatAttributeService.H b/src/ppe/tools/scripts/src/fapi2PlatAttributeService.H
new file mode 100644
index 0000000..fdb65a6
--- /dev/null
+++ b/src/ppe/tools/scripts/src/fapi2PlatAttributeService.H
@@ -0,0 +1,1085 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/scripts/src/fapi2PlatAttributeService.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file fapiPlatAttributeService.H
+ *
+ * @brief Defines the PLAT attribute access macros and defines which macro
+ * handles each attribute.
+ *
+ */
+
+
+#ifndef FAPI2PLATATTRIBUTESERVICE_H_
+#define FAPI2PLATATTRIBUTESERVICE_H_
+
+#include <stdint.h>
+#include <stddef.h>
+#include <fapi2AttributeIds.H>
+#include <plat_includes.H>
+#include "proc_sbe_fixed.H"
+#include "plat_target_parms.H"
+
+#define PLAT_GET_CHIP_EC_FEATURE_OVERRIDE(ID, PTARGET, VAL) \
+ fapi2::_getEcFeatureOverride<fapi2::ID##_Type>(fapi2::ID, PTARGET, VAL)
+
+/* INSERT NEW ATTRIBUTES HERE */
+
+#define ATTR_TARGET_SCOMABLE_GETMACRO PLAT_ATTR_GET_GLOBAL_INT
+#define ATTR_TARGET_SCOMABLE_SETMACRO PLAT_ATTR_SET_GLOBAL_INT
+
+
+
+/******************************************************************************/
+/* * Global macros * */
+/* These macros are called by the macros above to invoke the appropriate API. */
+/* These macros do not need to change when a new attribute is introduced. */
+/******************************************************************************/
+
+/* global get uint8_t 1D array macro */
+#define PLAT_ATTR_GET_UINT8_1D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayShort<fapi2::ID##_Type, static_cast<TargetType>(fapi2::ID##_TargetTypes), fapi2::ID> \
+ (fapi2::ID, PTARGET, VAL)
+
+/* global set uint8_t 1D array macro */
+#define PLAT_ATTR_SET_UINT8_1D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayShort<fapi2::ID##_Type, static_cast<TargetType>(fapi2::ID##_TargetTypes), fapi2::ID> \
+ (fapi2::ID, PTARGET, VAL)
+
+/* global get uint8_t 2D array macro */
+#define PLAT_ATTR_GET_UINT8_2D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayShort(fapi2::ID, PTARGET, VAL[0])
+/* global set uint8_t 2D array macro */
+#define PLAT_ATTR_SET_UINT8_2D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayShort(fapi2::ID, PTARGET, VAL[0])
+
+/* global get uint8_t 3D array macro */
+#define PLAT_ATTR_GET_UINT8_3D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayShort(fapi2::ID, PTARGET, VAL[0][0])
+/* global set uint8_t 3D array macro */
+#define PLAT_ATTR_SET_UINT8_3D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayShort(fapi2::ID, PTARGET, VAL[0][0])
+
+/* global get uint8_t 4D array macro */
+#define PLAT_ATTR_GET_UINT8_4D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayShort(fapi2::ID, PTARGET, VAL[0][0][0])
+/* global set uint8_t 4D array macro */
+#define PLAT_ATTR_SET_UINT8_4D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayShort(fapi2::ID, PTARGET, VAL[0][0][0])
+
+/* global get uint32_t 1D array macro */
+#define PLAT_ATTR_GET_UINT32_1D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayWord(fapi2::ID, PTARGET, VAL)
+/* global set uint32_t 1D array macro */
+#define PLAT_ATTR_SET_UINT32_1D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayWord(fapi2::ID, PTARGET, VAL)
+
+/* global get uint32_t 2D array macro */
+#define PLAT_ATTR_GET_UINT32_2D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayWord(fapi2::ID, PTARGET, VAL[0])
+/* global set uint32_t 2D array macro */
+#define PLAT_ATTR_SET_UINT32_2D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayWord(fapi2::ID, PTARGET, VAL[0])
+
+/* global get uint32_t 3D array macro */
+#define PLAT_ATTR_GET_UINT32_3D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayWord(fapi2::ID, PTARGET, VAL[0][0])
+/* global set uint32_t 3D array macro */
+#define PLAT_ATTR_SET_UINT32_3D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayWord(fapi2::ID, PTARGET, VAL[0][0])
+
+/* global get uint32_t 4D array macro */
+#define PLAT_ATTR_GET_UINT32_4D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayWord(fapi2::ID, PTARGET, VAL[0][0][0])
+/* global set uint32_t 4D array macro */
+#define PLAT_ATTR_SET_UINT32_4D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayWord(fapi2::ID, PTARGET, VAL[0][0][0])
+
+
+/* global get uint64_t 1D array macro */
+#define PLAT_ATTR_GET_UINT64_1D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayDoubleWord(fapi2::ID, PTARGET, VAL)
+/* global set uint64_t 1D array macro */
+#define PLAT_ATTR_SET_UINT64_1D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayDoubleWord(fapi2::ID, PTARGET, VAL)
+
+/* global get uint64_t 2D array macro */
+#define PLAT_ATTR_GET_UINT64_2D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayDoubleWord(fapi2::ID, PTARGET, VAL[0])
+/* global set uint64_t 2D array macro */
+#define PLAT_ATTR_SET_UINT64_2D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayDoubleWord(fapi2::ID, PTARGET, VAL[0])
+
+/* global get uint64_t 3D array macro */
+#define PLAT_ATTR_GET_UINT64_3D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayDoubleWord(fapi2::ID, PTARGET, VAL[0][0])
+/* global set uint64_t 3D array macro */
+#define PLAT_ATTR_SET_UINT64_3D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayDoubleWord(fapi2::ID, PTARGET, VAL[0][0])
+
+/* global get uint64_t 4D array macro */
+#define PLAT_ATTR_GET_UINT64_4D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeArrayDoubleWord(fapi2::ID, PTARGET, VAL[0][0][0])
+/* global set uint64_t 4D array macro */
+#define PLAT_ATTR_SET_UINT64_4D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_setAttributeArrayDoubleWord(fapi2::ID, PTARGET, VAL[0][0][0])
+
+/* global get int macro (uint8_t, 32 and 64) */
+#define PLAT_ATTR_GET_GLOBAL_INT(ID, PTARGET, VAL) \
+ fapi2::_get<fapi2::ID##_Type, static_cast<TargetType>(fapi2::ID##_TargetTypes), fapi2::ID> \
+ (fapi2::ID, PTARGET, VAL)
+
+/* global set int macro (uint8_t, 32 and 64) */
+#define PLAT_ATTR_SET_GLOBAL_INT(ID, PTARGET, VAL) \
+ fapi2::_set<fapi2::ID##_Type, static_cast<TargetType>(fapi2::ID##_TargetTypes), fapi2::ID> \
+ (fapi2::ID, PTARGET, VAL)
+
+
+//here
+
+/******************************************************************************/
+// Get Override Macros
+/******************************************************************************/
+/* global get override uint8_t 1D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_1D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayShort(fapi2::ID, PTARGET, VAL)
+/* global get override uint8_t 2D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_2D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayShort(fapi2::ID, PTARGET, VAL[0])
+/* global get override uint8_t 3D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_3D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayShort(fapi2::ID, PTARGET, VAL[0][0])
+/* global get override uint8_t 4D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_4D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayShort(fapi2::ID, PTARGET, VAL[0][0][0])
+
+
+/* global get override uint32_t 1D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_1D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayWord(fapi2::ID, PTARGET, VAL)
+/* global get override uint32_t 2D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_2D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayWord(fapi2::ID, PTARGET, VAL[0])
+/* global get override uint32_t 3D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_3D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayWord(fapi2::ID, PTARGET, VAL[0][0])
+/* global get override uint32_t 4D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_4D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayWord(fapi2::ID, PTARGET, VAL[0][0][0])
+
+
+/* global get override uint64_t 1D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_1D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayDoubleWord(fapi2::ID, PTARGET, VAL)
+/* global get override uint64_t 2D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_2D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayDoubleWord(fapi2::ID, PTARGET, VAL[0])
+/* global get override uint64_t 3D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_3D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayDoubleWord(fapi2::ID, PTARGET, VAL[0][0])
+/* global get override uint64_t 4D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_4D_ARRAY(ID, PTARGET, VAL) \
+ fapi2::_getAttributeOverrideArrayDoubleWord(fapi2::ID, PTARGET, VAL[0][0][0])
+
+/* global get override int macro (uint8_t, 32 and 64) */
+#define PLAT_ATTR_GET_OVERRIDE_GLOBAL_INT(ID, PTARGET, VAL) \
+ fapi2::_getOverride<fapi2::ID##_Type>(fapi2::ID, PTARGET, VAL)
+
+/******************************************************************************/
+// Get string
+/******************************************************************************/
+
+extern "C"
+{
+ extern fapi2attr::ProcChipAttributes_t* G_proc_chip_attributes asm("G_proc_chip_attributes") __attribute__ ((section (".fixed")));
+ extern fapi2attr::PervAttributes_t* G_perv_attributes asm("G_perv_attributes") __attribute__ ((section (".fixed")));
+ extern fapi2attr::CoreAttributes_t* G_core_attributes asm("G_core_attributes") __attribute__ ((section (".fixed")));
+ extern fapi2attr::EQAttributes_t* G_eq_attributes asm("G_eq_attributes") __attribute__ ((section (".fixed")));
+ extern fapi2attr::EXAttributes_t* G_ex_attributes asm("G_ex_attributes") __attribute__ ((section (".fixed")));
+
+}
+
+namespace fapi2
+{
+
+
+// Parameters are done as pointers (vs references) to allow the attribute
+// storage to be relocated
+template<fapi2::TargetType K, typename TAttrStruct, typename TValue, fapi2::AttributeId AId>
+void __set( const fapi2::Target<K>* i_ptarget, TAttrStruct* object, const fapi2::AttributeId attrid, TValue* value );
+
+template<fapi2::TargetType K, typename TAttrStruct, typename TValue, fapi2::AttributeId AId>
+void __get( const fapi2::Target<K>* i_ptarget, TAttrStruct* object, const fapi2::AttributeId attrid, TValue* value );
+
+
+/* INSERT NEW GETTER AND SETTER FUNCTIONS HERE */
+
+
+
+//******************************************************************************
+// Get base template
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_Id,
+ const Target<K> * const i_pTarget,
+ T& o_value)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const fapi2::AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint8_t& o_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get uint32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint32_t& o_value)
+{
+ static_assert(std::is_same<T, uint32_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get uint64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint64_t& o_value)
+{
+ static_assert(std::is_same<T, uint64_t>::value, "Attribute type mismatch");
+
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override uint8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint8_t& o_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override uint32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint32_t& o_value)
+{
+ static_assert(std::is_same<T, uint32_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override uint64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint64_t& o_value)
+{
+ static_assert(std::is_same<T, uint64_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get override EC Feature (uint8_t)
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getEcFeatureOverride(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint8_t& o_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch");
+
+ // The way this is implemented, we want to return a non-zero return code if we found an override.
+ // Return 0 if there was an error.
+ // This is how it's implemented:
+ // PLAT_GET_CHIP_EC_FEATURE_OVERRIDE(ID, PTARGET, VAL) ? fapi::FAPI_RC_SUCCESS : fapi::fapiQueryChipEcFeature(fapi::ID, PTARGET, VAL)
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get uint8_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeArrayShort(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint8_t * o_pValues)
+{
+// fapi2::Attributeta o_data;
+// fapi2::ReturnCode l_fapi_rc(FAPI2_RC_SUCCESS);
+// uint32_t l_ecmd_rc = ECMD_SUCCESS;
+//
+// ecmdChipTarget l_ecmd_target;
+// fapiTargetPointerToEcmdTarget(i_pTarget, l_ecmd_target);
+//
+// o_data.faValidMask = FAPI_ATTRIBUTE_TYPE_UINT8ARY;
+// o_data.faUint8ary = o_pValues;
+//
+// l_ecmd_rc = fapi2GetAttribute(l_ecmd_target, i_id, o_data);
+// if (l_ecmd_rc)
+// {
+// l_fapi_rc = (ReturnCodes) l_ecmd_rc;
+// }
+// return l_fapi_rc;
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint8_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _setAttributeArrayShort(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint8_t * i_pValues)
+{
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_proc_chip_attributes, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( *i_pTarget, G_perv_attributes, i_pValues );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_core_attributes, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( *i_pTarget, G_eq_attributes, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( *i_pTarget, G_ex_attributes, *i_pValues );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint32_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeArrayWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint32_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint32_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _setAttributeArrayWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint32_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint64_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeArrayDoubleWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint64_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint64_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _setAttributeArrayDoubleWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint64_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override uint8_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeOverrideArrayShort(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint8_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override uint32_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeOverrideArrayWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint32_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override uint64_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeOverrideArrayDoubleWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ uint64_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set base template
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_Id,
+ const Target<K> * const i_pTarget,
+ T& i_value)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+
+//******************************************************************************
+// Set uint8_t
+//******************************************************************************
+template<typename T, TargetType K, typename A>
+ReturnCode _set(const AttributeId i_Id,
+ const Target<K> * const i_pTarget,
+ uint8_t& i_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_proc_chip_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( *i_pTarget, G_perv_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_core_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( *i_pTarget, G_eq_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( *i_pTarget, G_ex_attributes, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set uint32_t
+//******************************************************************************
+template<typename T, TargetType K, typename A>
+ReturnCode _set(
+ const Target<K> * const i_pTarget,
+ uint32_t& i_value)
+{
+ static_assert(std::is_same<T, uint32_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_proc_chip_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( *i_pTarget, G_perv_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_core_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( *i_pTarget, G_eq_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( *i_pTarget, G_ex_attributes, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set uint64_t
+//******************************************************************************
+
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_Id,
+ const Target<K> * const i_pTarget,
+ const uint64_t & i_value)
+{
+ static_assert(std::is_same<T, uint64_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_proc_chip_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( *i_pTarget, G_perv_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_core_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( *i_pTarget, G_eq_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( *i_pTarget, G_ex_attributes, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int8_t& o_value)
+{
+ static_assert(std::is_same<T, int8_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int32_t& o_value)
+{
+ static_assert(std::is_same<T, int32_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int64_t& o_value)
+{
+ static_assert(std::is_same<T, int64_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override int8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int8_t& o_value)
+{
+ static_assert(std::is_same<T, int8_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override int32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int32_t& o_value)
+{
+ static_assert(std::is_same<T, int32_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override int64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int64_t& o_value)
+{
+ static_assert(std::is_same<T, int64_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int8_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeArraySignedShort(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int8_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int8_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _setAttributeArraySignedShort(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int8_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int32_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeArraySignedWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int32_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int32_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _setAttributeArraySignedWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int32_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int64_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeArraySignedDoubleWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int64_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set int64_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _setAttributeArraySignedDoubleWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int64_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int8_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeOverrideArraySignedShort(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int8_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override int32_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeOverrideArraySignedWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int32_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override int64_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeOverrideArraySignedDoubleWord(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int64_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int8_t& i_value)
+{
+ static_assert(std::is_same<T, int8_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_proc_chip_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( *i_pTarget, G_perv_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_core_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( *i_pTarget, G_eq_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( *i_pTarget, G_ex_attributes, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ int32_t& i_value)
+{
+ static_assert(std::is_same<T, int32_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_proc_chip_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( *i_pTarget, G_perv_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_core_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( *i_pTarget, G_eq_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( *i_pTarget, G_ex_attributes, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> * const i_pTarget,
+ const int64_t & i_value)
+{
+ static_assert(std::is_same<T, int64_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_proc_chip_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( *i_pTarget, G_perv_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( *i_pTarget, G_core_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( *i_pTarget, G_eq_attributes, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( *i_pTarget, G_ex_attributes, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+} // namespace fapi2
+#endif // FAPIPLATATTRIBUTESERVICE_H_
OpenPOWER on IntegriCloud