diff options
| author | William Bryan <wilbryan@us.ibm.com> | 2015-09-23 11:30:56 -0500 |
|---|---|---|
| committer | William A. Bryan <wilbryan@us.ibm.com> | 2015-09-24 10:32:03 -0500 |
| commit | 447b47d1dfbfafa54363beabb381122d780b783b (patch) | |
| tree | e7b3ea09544addf729be985743a1667a66b3a9e9 /src/ppe/tools | |
| parent | 9513285de33024843868b9cf4baa57d462ad63dd (diff) | |
| download | talos-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/Makefile | 148 | ||||
| -rw-r--r-- | src/ppe/tools/image/bin/.empty | 0 | ||||
| -rw-r--r-- | src/ppe/tools/image/p9_image_help_base.H | 119 | ||||
| -rw-r--r-- | src/ppe/tools/image/p9_ring_identification.H | 65 | ||||
| -rw-r--r-- | src/ppe/tools/image/p9_ring_identification.c | 146 | ||||
| -rw-r--r-- | src/ppe/tools/image/p9_scan_compression.H | 369 | ||||
| -rwxr-xr-x | src/ppe/tools/image/ppeSetFixed.pl | 234 | ||||
| -rw-r--r-- | src/ppe/tools/image/sbe_default_tool.c | 310 | ||||
| -rw-r--r-- | src/ppe/tools/image/sbe_xip_tool.c | 2135 | ||||
| -rwxr-xr-x | src/ppe/tools/scripts/parseErrorInfo.pl | 1511 | ||||
| -rwxr-xr-x | src/ppe/tools/scripts/ppeCreateAttrGetSetMacros.pl | 557 | ||||
| -rwxr-xr-x | src/ppe/tools/scripts/ppeCreateIfAttrService.pl | 241 | ||||
| -rw-r--r-- | src/ppe/tools/scripts/ppeParseAttrGetSetMacros.pl | 284 | ||||
| -rwxr-xr-x | src/ppe/tools/scripts/ppeParseAttributeInfo.pl | 1090 | ||||
| -rwxr-xr-x | src/ppe/tools/scripts/ppeParseProcSbeFixed.pl | 277 | ||||
| -rw-r--r-- | src/ppe/tools/scripts/src/fapi2PlatAttributeService.H | 1085 |
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, §ionOffset); + 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, §ion); + 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_ |

