summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShakeeb <shakeebbk@in.ibm.com>2016-08-27 10:50:49 -0500
committerSachin Gupta <sgupta2m@in.ibm.com>2016-08-30 06:01:06 -0400
commitf2d94b5f809410300fe10dc9d0786790018463a0 (patch)
tree467f90297b0eb7c5c6672653d778ed4734c0d5a3 /src
parent49b557dcae32250e8e06c4de895c0b7ba0e8009e (diff)
downloadtalos-sbe-f2d94b5f809410300fe10dc9d0786790018463a0.tar.gz
talos-sbe-f2d94b5f809410300fe10dc9d0786790018463a0.zip
SBE code restructure: sbe -> src rename
Change-Id: I6e4378d0e71a00ed2b239658d43f180df2a9b748 RTC:159709 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28875 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: RAJA DAS <rajadas2@in.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/.empty0
-rw-r--r--src/boot/Makefile86
-rw-r--r--src/boot/bootfiles.mk34
-rw-r--r--src/boot/loader_l1.S82
-rw-r--r--src/boot/loader_l2.c88
-rw-r--r--src/boot/loader_l2_setup.S57
-rw-r--r--src/boot/otprom_init.S178
-rw-r--r--src/boot/pibmem_repair.S62
-rw-r--r--src/build/models/n10_e9027_tp026_soa_sc_u285_01/base13
-rw-r--r--src/build/models/n10_e9030_tp029_soa_sc_u339_01/base19
-rw-r--r--src/build/models/n10_e9031_tp030_soa_sc_u008_01/base11
-rw-r--r--src/build/models/n10_e9031_tp030_soa_sc_u012_01/base11
-rw-r--r--src/build/models/n10_e9031_tp030_soa_sc_u022_01/base11
-rwxr-xr-xsrc/build/tools/CommitSbeImageToCMVC.py376
-rwxr-xr-xsrc/build/tools/Debug/sbe-debug.py136
-rw-r--r--src/build/tools/README66
-rwxr-xr-xsrc/build/tools/conv_rel_branch.pl339
-rwxr-xr-xsrc/build/tools/gitRelease.pm2102
-rw-r--r--src/build/tools/perl.modules/gitUtil.pm592
-rwxr-xr-xsrc/build/tools/sandbox-create60
-rwxr-xr-xsrc/build/tools/sbeCmvcConstants.py84
-rwxr-xr-xsrc/build/tools/sbeCmvcUtility.py570
-rwxr-xr-xsrc/build/tools/sbeGitTool.pl332
-rw-r--r--src/build/tools/sbePatchUtility.py179
-rwxr-xr-xsrc/build/tools/sbePrime.py296
-rw-r--r--src/hwpf/include/buffer_traits.H241
-rw-r--r--src/hwpf/include/error_info.H685
-rw-r--r--src/hwpf/include/error_info_defs.H331
-rw-r--r--src/hwpf/include/fapi2.H77
-rw-r--r--src/hwpf/include/fapi2AttributeService.H150
-rw-r--r--src/hwpf/include/fapi2Structs.H132
-rw-r--r--src/hwpf/include/fapi2_hw_access.H464
-rw-r--r--src/hwpf/include/fapi2_target.H588
-rw-r--r--src/hwpf/include/ffdc.H35
-rw-r--r--src/hwpf/include/hw_access.H603
-rw-r--r--src/hwpf/include/hwp_ffdc_classes.H23
-rw-r--r--src/hwpf/include/plat/hwp_executor.H64
-rw-r--r--src/hwpf/include/plat/multicast.H54
-rw-r--r--src/hwpf/include/plat/plat_attributes.H36
-rw-r--r--src/hwpf/include/plat/plat_error_scope.H70
-rw-r--r--src/hwpf/include/plat/plat_hw_access.H148
-rw-r--r--src/hwpf/include/plat/plat_includes.H39
-rw-r--r--src/hwpf/include/plat/plat_ring_traverse.H116
-rw-r--r--src/hwpf/include/plat/plat_target.H215
-rw-r--r--src/hwpf/include/plat/plat_target_definitions.H111
-rw-r--r--src/hwpf/include/plat/plat_target_filter.H89
-rw-r--r--src/hwpf/include/plat/plat_target_parms.H92
-rw-r--r--src/hwpf/include/plat/plat_target_utils.H86
-rw-r--r--src/hwpf/include/plat/plat_trace.H113
-rw-r--r--src/hwpf/include/plat/target.H434
-rw-r--r--src/hwpf/include/return_code.H107
-rw-r--r--src/hwpf/include/set_sbe_error.H23
-rw-r--r--src/hwpf/include/utils.H122
-rw-r--r--src/hwpf/include/vector.H850
-rw-r--r--src/hwpf/src/Makefile51
-rw-r--r--src/hwpf/src/fapi2sbefiles.mk49
-rw-r--r--src/hwpf/src/ffdc.C41
-rw-r--r--src/hwpf/src/plat/Makefile41
-rw-r--r--src/hwpf/src/plat/fapi2sbeplatfiles.mk52
-rw-r--r--src/hwpf/src/plat/plat_hw_access.C72
-rw-r--r--src/hwpf/src/plat/plat_utils.C304
-rw-r--r--src/hwpf/src/plat/target.C609
-rw-r--r--src/hwpf/src/plat_ring_traverse.C467
-rw-r--r--src/hwpf/src/return_code.C46
-rw-r--r--src/image/Makefile316
-rw-r--r--src/image/Mirror_WA_attributes.xml34
-rw-r--r--src/image/base_ppe_header.S209
-rw-r--r--src/image/base_sbe_fixed.S67
-rwxr-xr-xsrc/image/buildInfo.py48
-rw-r--r--src/image/img_defs.mk486
-rwxr-xr-xsrc/image/linkloader.cmd96
-rw-r--r--src/image/linkotprom.cmd43
-rw-r--r--src/image/linksbe.cmd108
-rw-r--r--src/image/linkseeprom.cmd200
-rw-r--r--src/image/p9_sbe.H52
-rwxr-xr-xsrc/image/parsAndCutElf.py69
-rw-r--r--src/image/proc_sbe_fixed.H211
-rw-r--r--src/image/sbe_common.H600
-rw-r--r--src/image/sbe_link.H102
-rw-r--r--src/image/topfiles.mk53
-rw-r--r--src/sample/Makefile99
-rw-r--r--src/sample/img_defs.mk264
-rw-r--r--src/sample/link.cmd91
-rw-r--r--src/sample/pk_scom.c235
-rw-r--r--src/sample/pk_scom.h66
-rw-r--r--src/sample/pk_trace_wrap.c32
-rw-r--r--src/sample/pk_trace_wrap.h30
-rw-r--r--src/sample/sample_main.C122
-rw-r--r--src/sample/topfiles.mk29
-rw-r--r--src/sbefw/Makefile56
-rw-r--r--src/sbefw/assert.h49
-rw-r--r--src/sbefw/pk_app_cfg.h144
-rw-r--r--src/sbefw/plugins/sbeUserDataParser.C292
-rw-r--r--src/sbefw/pool.C65
-rw-r--r--src/sbefw/pool.H58
-rw-r--r--src/sbefw/sbeFFDC.C141
-rw-r--r--src/sbefw/sbeFFDC.H125
-rw-r--r--src/sbefw/sbeFFDCType.H100
-rw-r--r--src/sbefw/sbeFifoMsgUtils.C375
-rw-r--r--src/sbefw/sbeFifoMsgUtils.H192
-rw-r--r--src/sbefw/sbeHostMsg.H132
-rw-r--r--src/sbefw/sbeHostUtils.C226
-rw-r--r--src/sbefw/sbeHostUtils.H244
-rw-r--r--src/sbefw/sbeSpMsg.H634
-rw-r--r--src/sbefw/sbeXipUtils.H63
-rw-r--r--src/sbefw/sbe_host_intf.H89
-rw-r--r--src/sbefw/sbe_sp_intf.H408
-rw-r--r--src/sbefw/sbecmdcntlinst.C203
-rw-r--r--src/sbefw/sbecmdcntlinst.H45
-rw-r--r--src/sbefw/sbecmdcntrldmt.C302
-rw-r--r--src/sbefw/sbecmdcntrldmt.H59
-rw-r--r--src/sbefw/sbecmdgeneric.C118
-rw-r--r--src/sbefw/sbecmdgeneric.H46
-rw-r--r--src/sbefw/sbecmdiplcontrol.C830
-rw-r--r--src/sbefw/sbecmdiplcontrol.H117
-rw-r--r--src/sbefw/sbecmdmemaccess.C778
-rw-r--r--src/sbefw/sbecmdmemaccess.H54
-rw-r--r--src/sbefw/sbecmdparser.C483
-rw-r--r--src/sbefw/sbecmdparser.H119
-rw-r--r--src/sbefw/sbecmdprocessor.C376
-rw-r--r--src/sbefw/sbecmdreceiver.C325
-rw-r--r--src/sbefw/sbecmdregaccess.C274
-rw-r--r--src/sbefw/sbecmdregaccess.H56
-rw-r--r--src/sbefw/sbecmdringaccess.C305
-rw-r--r--src/sbefw/sbecmdringaccess.H63
-rw-r--r--src/sbefw/sbecmdscomaccess.C495
-rw-r--r--src/sbefw/sbecmdscomaccess.H93
-rw-r--r--src/sbefw/sbecmdsram.C337
-rw-r--r--src/sbefw/sbecmdsram.H64
-rw-r--r--src/sbefw/sbeerrorcodes.H49
-rw-r--r--src/sbefw/sbeevents.H96
-rw-r--r--src/sbefw/sbeexeintf.H256
-rw-r--r--src/sbefw/sbefifo.H227
-rw-r--r--src/sbefw/sbefwfiles.mk48
-rw-r--r--src/sbefw/sbeirq.C195
-rw-r--r--src/sbefw/sbeirq.H109
-rw-r--r--src/sbefw/sbemain.C352
-rw-r--r--src/sbefw/sberegaccess.C331
-rw-r--r--src/sbefw/sberegaccess.H266
-rw-r--r--src/sbefw/sbescom.C198
-rw-r--r--src/sbefw/sbescom.H38
-rw-r--r--src/sbefw/sbestates.H67
-rw-r--r--src/sbefw/sbetrace.H75
-rw-r--r--src/sbefw/sbeutil.H81
-rw-r--r--src/sbefw/vector397
-rwxr-xr-xsrc/test/citest/autocitest96
-rwxr-xr-xsrc/test/citest/build-script72
-rwxr-xr-xsrc/test/citest/check-copyright30
-rwxr-xr-xsrc/test/citest/copyright-check.sh56
-rwxr-xr-xsrc/test/citest/create-sandbox73
-rw-r--r--src/test/citest/etc/patches/chip.act.patch146
-rw-r--r--src/test/citest/etc/patches/patchlist.txt14
-rw-r--r--src/test/citest/etc/patches/pervasive.act.patch28
-rw-r--r--src/test/citest/etc/patches/powermgmt.act.patch1057
-rw-r--r--src/test/citest/etc/patches/standalone.simics.patch4
-rwxr-xr-xsrc/test/citest/etc/workarounds.postsimsetup43
-rwxr-xr-xsrc/test/citest/etc/workarounds.presimsetup31
-rwxr-xr-xsrc/test/citest/populate-sandbox60
-rwxr-xr-xsrc/test/citest/sbetest-start.sh38
-rwxr-xr-xsrc/test/citest/setup-env84
-rwxr-xr-xsrc/test/ffdc.xml41
-rwxr-xr-xsrc/test/test.xml49
-rwxr-xr-xsrc/test/testAbort.py57
-rw-r--r--src/test/testAduMem.xml42
-rw-r--r--src/test/testAduMem_ecc.py68
-rw-r--r--src/test/testAduMem_itag.py66
-rw-r--r--src/test/testAduMem_noEccNoItag.py99
-rw-r--r--src/test/testAduMem_withEccItag.py66
-rw-r--r--src/test/testAduMem_withEccWithItagReadWrite.py96
-rw-r--r--src/test/testCntlInstruction.py473
-rwxr-xr-xsrc/test/testCntlInstruction.xml30
-rwxr-xr-xsrc/test/testContinueMpipl.py57
-rwxr-xr-xsrc/test/testContinueSbeBoot.py57
-rwxr-xr-xsrc/test/testEnterMpipl.py57
-rw-r--r--src/test/testExecutorMemory.py80
-rw-r--r--src/test/testExecutorPSU.py140
-rw-r--r--src/test/testExecutorPutRing.py225
-rwxr-xr-xsrc/test/testExecutorPutRing.xml30
-rw-r--r--src/test/testFifoReset.py80
-rw-r--r--src/test/testFifoReset.xml35
-rwxr-xr-xsrc/test/testGeneric.xml30
-rwxr-xr-xsrc/test/testGetCapabilities.py82
-rw-r--r--src/test/testGetMem.py74
-rw-r--r--src/test/testGetMem_expdata.py83
-rw-r--r--src/test/testGetRing.py95
-rwxr-xr-xsrc/test/testGetRing.xml29
-rw-r--r--src/test/testIstep.xml332
-rwxr-xr-xsrc/test/testIstepAuto.py54
-rwxr-xr-xsrc/test/testIstepInvalid.py57
-rwxr-xr-xsrc/test/testIstepInvalidFenced.py57
-rwxr-xr-xsrc/test/testIstepSuccess.py57
-rwxr-xr-xsrc/test/testModifyScom.py97
-rw-r--r--src/test/testPSUUserUtil.py58
-rw-r--r--src/test/testPSUUtil.py376
-rwxr-xr-xsrc/test/testPutGetInScom.py82
-rw-r--r--src/test/testPutGetMem.xml34
-rwxr-xr-xsrc/test/testPutGetRegFpr.py81
-rwxr-xr-xsrc/test/testPutGetRegGpr.py81
-rwxr-xr-xsrc/test/testPutGetRegSpr.py81
-rwxr-xr-xsrc/test/testPutGetScom.py118
-rw-r--r--src/test/testPutMem.py83
-rw-r--r--src/test/testPutMem_fail.py84
-rwxr-xr-xsrc/test/testPutScomUnderMask.py98
-rwxr-xr-xsrc/test/testRegAccess.xml46
-rw-r--r--src/test/testRegistry.py79
-rw-r--r--src/test/testSbeDump.py110
-rwxr-xr-xsrc/test/testScom.xml42
-rw-r--r--src/test/testSram.py129
-rwxr-xr-xsrc/test/testSram.xml31
-rw-r--r--src/test/testStartInstruction.py64
-rw-r--r--src/test/testStopInstruction.py64
-rw-r--r--src/test/testUtil.py170
-rwxr-xr-xsrc/tools/debug/simics/makefile53
-rwxr-xr-xsrc/tools/debug/simics/sbe_standalone.simics2
-rwxr-xr-xsrc/tools/debug/simics/sbe_startup.simics14
-rwxr-xr-xsrc/tools/debug/simics/simics-debug-framework.py88
-rwxr-xr-xsrc/tools/hooks/addCopyright1167
-rwxr-xr-xsrc/tools/hooks/gerrit-hostname78
-rwxr-xr-xsrc/tools/hooks/post-commit32
-rwxr-xr-xsrc/tools/hooks/pre-commit38
-rwxr-xr-xsrc/tools/hooks/pre-commit-actions48
-rwxr-xr-xsrc/tools/hooks/pre-commit-prologs46
-rwxr-xr-xsrc/tools/hooks/setupgithooks.sh63
-rwxr-xr-xsrc/tools/hooks/verify-commit358
-rw-r--r--src/tools/image/Makefile86
-rw-r--r--src/tools/image/sbe_default_tool.c310
-rw-r--r--src/tools/ppetracepp/Makefile37
-rw-r--r--src/tools/ppetracepp/cmvc/makefile28
-rwxr-xr-xsrc/tools/ppetracepp/jhash.h166
-rwxr-xr-xsrc/tools/ppetracepp/ppe2fsp.c532
-rw-r--r--src/tools/ppetracepp/ppe2fsp.h33
-rw-r--r--src/tools/ppetracepp/ppe2fsp_cmd.c138
-rwxr-xr-xsrc/tools/ppetracepp/ppetracepp.C949
-rwxr-xr-xsrc/tools/ppetracepp/trac_interface.h369
-rwxr-xr-xsrc/tools/ppetracepp/tracehash.pl896
-rwxr-xr-xsrc/tools/scripts/parseErrorInfo.pl1663
-rwxr-xr-xsrc/tools/scripts/ppeCreateAttrGetSetMacros.pl571
-rwxr-xr-xsrc/tools/scripts/ppeCreateIfAttrService.pl240
-rw-r--r--src/tools/scripts/ppeParseAttrGetSetMacros.pl286
-rwxr-xr-xsrc/tools/scripts/ppeParseAttributeInfo.pl746
-rwxr-xr-xsrc/tools/scripts/ppeParseProcSbeFixed.pl318
-rwxr-xr-xsrc/tools/scripts/ppeSetFixed.pl259
-rw-r--r--src/tools/scripts/src/fapi2PlatAttributeService.H1416
243 files changed, 46664 insertions, 0 deletions
diff --git a/src/.empty b/src/.empty
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/.empty
diff --git a/src/boot/Makefile b/src/boot/Makefile
new file mode 100644
index 00000000..95e29143
--- /dev/null
+++ b/src/boot/Makefile
@@ -0,0 +1,86 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/boot/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+export SUB_OBJDIR = /boot
+
+include img_defs.mk
+include bootfiles.mk
+
+INCLUDES += -I$(IMAGE_SRCDIR)
+
+OBJS := $(addprefix $(OBJDIR)/, $(BOOT_OBJECTS))
+BOOTOBJS += $(OBJS)
+LINK_SCRIPT_LOADER = $(addprefix $(OBJDIR)/, linkscriptloader)
+LINK_SCRIPT_OTPROM = $(addprefix $(OBJDIR)/, linkscriptotprom)
+
+all: $(OBJS) \
+ $(OBJDIR)/$(IMAGE_LOADER_NAME).bin $(OBJDIR)/$(IMAGE_OTPROM_NAME).bin
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+# Loader Objects
+LOADER_OBJS := $(addprefix $(OBJDIR)/, $(BASE_LOADER_OBJECTS))
+#Otprom Loader Objects
+OTPROM_LOADER_OBJS := $(addprefix $(OBJDIR)/, $(OTPROM_LOADER_OBJECTS))
+# ---- Otprom Image ------
+$(OBJDIR)/$(IMAGE_OTPROM_NAME).bin $(OBJDIR)/$(IMAGE_OTPROM_NAME).dis: $(OBJDIR)/$(IMAGE_OTPROM_NAME).out
+ $(OBJCOPY) -O binary $< $(OBJDIR)/$(IMAGE_OTPROM_NAME).bin `/usr/bin/nm $(OBJDIR)/$(IMAGE_OTPROM_NAME).out | grep "A _loader_end" | cut -d " " -f 1`
+ $(OBJDUMP) -S $< > $(OBJDIR)/$(IMAGE_OTPROM_NAME).dis
+
+#create a linked ELF executable
+$(OBJDIR)/$(IMAGE_OTPROM_NAME).out: $(OTPROM_LOADER_OBJS) $(LINK_SCRIPT_OTPROM)
+ $(LD) -e base_loader -T$(LINK_SCRIPT_OTPROM) -Map $(OBJDIR)/$(IMAGE_OTPROM_NAME).map -Bstatic -o $(OBJDIR)/$(IMAGE_OTPROM_NAME).out $(OTPROM_LOADER_OBJS)
+
+# pass the link command file through the C preprocessor to evaluate macros
+# and remove comments
+$(LINK_SCRIPT_OTPROM): $(IMAGE_SRCDIR)/linkotprom.cmd
+ $(CPP) -I. -E -x c++ -P $(DEFS) $(IMAGE_SRCDIR)/linkotprom.cmd -o $(LINK_SCRIPT_OTPROM)
+
+# ---- Loader Image ------
+$(OBJDIR)/$(IMAGE_LOADER_NAME).bin $(OBJDIR)/$(IMAGE_LOADER_NAME).dis: $(OBJDIR)/$(IMAGE_LOADER_NAME).out
+ $(OBJCOPY) -O binary $< $(OBJDIR)/$(IMAGE_LOADER_NAME).bin --pad-to 0x`/usr/bin/nm $(OBJDIR)/$(IMAGE_LOADER_NAME).out | grep "A _loader_end" | cut -d " " -f 1`
+ $(OBJDUMP) -S $< > $(OBJDIR)/$(IMAGE_LOADER_NAME).dis
+
+#create a linked ELF executable
+$(OBJDIR)/$(IMAGE_LOADER_NAME).out: $(LOADER_OBJS) $(LINK_SCRIPT_LOADER)
+ $(LD) -e base_loader -T$(LINK_SCRIPT_LOADER) -Map $(OBJDIR)/$(IMAGE_LOADER_NAME).map -Bstatic -o $(OBJDIR)/$(IMAGE_LOADER_NAME).out $(LOADER_OBJS)
+
+# pass the link command file through the C preprocessor to evaluate macros
+# and remove comments
+$(LINK_SCRIPT_LOADER): $(IMAGE_SRCDIR)/linkloader.cmd
+ $(CPP) -I. -E -x c++ -P $(DEFS) $(IMAGE_SRCDIR)/linkloader.cmd -o $(LINK_SCRIPT_LOADER)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+.PHONY: clean all
+
+#clean the kernel directory first, then the application level clean
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
+
+
diff --git a/src/boot/bootfiles.mk b/src/boot/bootfiles.mk
new file mode 100644
index 00000000..0836e59f
--- /dev/null
+++ b/src/boot/bootfiles.mk
@@ -0,0 +1,34 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/boot/bootfiles.mk $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+BOOTTOP-S-SOURCES = loader_l1.S
+
+BOOT_OBJECTS += $(BOOTTOP-S-SOURCES:.S=.o)
+
+BASE-LOADER-C-SOURCES = loader_l2.c
+BASE-LOADER-S-SOURCES = loader_l2_setup.S
+
+BASE_LOADER_OBJECTS = $(BASE-LOADER-C-SOURCES:.c=.o) $(BASE-LOADER-S-SOURCES:.S=.o)
+
+OTPROM-LOADER-S-SOURCES = otprom_init.S
+OTPROM_LOADER_OBJECTS = $(OTPROM-LOADER-S-SOURCES:.S=.o)
diff --git a/src/boot/loader_l1.S b/src/boot/loader_l1.S
new file mode 100644
index 00000000..1699b239
--- /dev/null
+++ b/src/boot/loader_l1.S
@@ -0,0 +1,82 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/boot/loader_l1.S $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+
+ .nolist
+#include "pk.h"
+#include "sbe_link.H"
+ .list
+
+### ****************************************************************************
+### .loader_text - This section contains pm loader code
+### @TODO via RTC 136315
+### It also contains vector code. We can remove vector code
+### once OTPROM support for simics is in.
+### ****************************************************************************
+
+ .section .loader_text, "ax", @progbits
+
+ .global _pibmemRepair
+
+__vectors:
+
+ ############################################################
+ # 0x0040 : System Reset
+ ############################################################
+ .org __vectors + 0x0040
+
+__system_reset:
+ b __pmLoader
+
+
+__pmLoader:
+ bl _pibmemRepair
+ _liw %r3, SBE_LOADER_BASE_SECTION # Base Loader Section Location
+ _liw %r4, SBE_LOADER_BASE_ORIGIN # dest
+ _liw %r9, SBE_SEEPROM_BASE_ORIGIN
+ lwz r5, 4(r3) #size of image in bytes
+ li r6, 3
+ srw r5, r5, r6 # Number of double word transfers
+ mtctr r5 # set the counter for loop
+ lwz r8, 0(r3) # offset of baseloader section
+ adde r8, r8, r9 # add base address to offset to get absolute address
+
+copy_loop:
+ lvd d28, 0(r8)
+ stvd d28, 0(r4)
+ addi r8, r8, 8
+ addi r4, r4, 8
+ bdnz copy_loop
+
+ ############################################################
+ # SBE entry function is 4 byte number in image header
+ ############################################################
+
+ _liw %r3, SBE_SEEPROM_BASE_ORIGIN + SBE_LOADER_ENTRY_HEADER_OFFSET
+ lwz r6, 0(r3)
+ mtlr r6
+ blr
+
+ .epilogue __pmLoader
+
+#include "pibmem_repair.S"
diff --git a/src/boot/loader_l2.c b/src/boot/loader_l2.c
new file mode 100644
index 00000000..4f575bea
--- /dev/null
+++ b/src/boot/loader_l2.c
@@ -0,0 +1,88 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/boot/loader_l2.c $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 "sbeXipUtils.H"
+
+// Load section to destination address
+int32_t loadSection( P9XipSection * i_section, uint64_t *i_destAddr )
+{
+ uint32_t idx = 0;
+ uint64_t *seepromAddr = (uint64_t *)( g_headerAddr + i_section->iv_offset);
+ uint32_t sectionSize = i_section->iv_size;
+ for( idx = 0; idx < sectionSize; idx += 8 )
+ {
+ *i_destAddr = *seepromAddr;
+ i_destAddr++; seepromAddr++;
+
+ }
+ return 0;
+}
+
+// Function to load base image into PIBMEM
+int32_t base_loader()
+{
+ int32_t rc = 0;
+ P9XipHeader *hdr = getXipHdr();
+
+ uint64_t *pibMemAddr = (uint64_t *)g_pibMemAddr;
+ uint64_t *tempPibMemAddr = (uint64_t *)g_pibMemAddr;
+ uint64_t *pibEndAddr = (uint64_t *)(SBE_LOADER_BASE_ORIGIN);
+
+ // Initialise complete PIBMEM with 0
+ // Though this is inefficient, this is quick fix to solve the
+ // HW write of data which is not 8 byte alligned. All write which
+ // are not 8 byte alligned, translates to read-modify-write. So
+ // if code does a write for 4 byte, first HW will read 8 bytes. If
+ // there is no data written there earlier and random data is present
+ // it can cause ecc errors.
+ // TODO via RTC 158797
+ // Though we may be able to optimise it, but than we have to put the
+ // logic in loadSection function which is not desired. So currently
+ // initialising all PIBMEM. If performance become concern during initial
+ // SBE load, we can optimise this.
+ // We have three options here in optimisation
+ // 1. Put this logic in SEEPROM loader ( pmloader ). This was we can
+ // reclaim space taken by base loader as stack/bss can grow in base
+ // loader section after image load.
+ // 2. Keep this code in PIBMEM. But do not initialise the memory taken
+ // by base image.
+ // 3. Do what is done in option 1 but only initialise memoty after base
+ // section to end of PIBMEM. This will involve some more hardcoding
+ // in seeprom loader.
+ // My preference will be option 1 but depends upon performance goals.
+ for( ; tempPibMemAddr < pibEndAddr; tempPibMemAddr++ )
+ {
+ *tempPibMemAddr = 0;
+ }
+
+ loadSection(&(hdr->iv_section[P9_XIP_SECTION_SBE_BASE]), pibMemAddr);
+ // Set the IVPR register. This is required so that interrupt vector table
+ // points to pk interfaces.
+ uint64_t data = (uint64_t)(SBE_BASE_ORIGIN) << 32;
+ PPE_STVD(g_ivprLoc, data);
+ // Jump to pk boot function
+ uint32_t addr = hdr->iv_kernelAddr;
+ JUMP_TO_ADDR(addr);
+
+ return rc;
+}
diff --git a/src/boot/loader_l2_setup.S b/src/boot/loader_l2_setup.S
new file mode 100644
index 00000000..99da6d5c
--- /dev/null
+++ b/src/boot/loader_l2_setup.S
@@ -0,0 +1,57 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/boot/loader_l2_setup.S $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+ .nolist
+#include "pk.h"
+ .list
+
+### ****************************************************************************
+### Do the initial setup for base loader
+###
+### ****************************************************************************
+
+__base_loader_setup:
+
+ ## Set up PowerPC EABI constant registers.
+
+ _liw %r2, _SDA2_BASE_
+ _liw %r13, _SDA_BASE_
+
+ ## The stack pointer is initialized for use by the remainder of the
+ ## initialization. The linker script defines the initial stack area.
+ ##
+ ## Stacks are always 8-byte aligned. A '0' is stored at the
+ ## stack pointer to indicate the end of the stack chain. Stack frames
+ ## always consist of at least 8 bytes - the backchain pointer and the
+ ## slot above the backchain pointer for the callee's LR.
+
+ _liw %r1, _BASE_LOADER_STACK_LIMIT
+ _clrfield %r1, %r1, 3, 29 # 8-byte align
+ li %r3, 0
+ li %r4, 0
+ stvd %r3, -8(%r1)
+
+ ## Call the base loader
+ bl base_loader
+
+ .epilogue __base_loader_setup
diff --git a/src/boot/otprom_init.S b/src/boot/otprom_init.S
new file mode 100644
index 00000000..719e158a
--- /dev/null
+++ b/src/boot/otprom_init.S
@@ -0,0 +1,178 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/boot/otprom_init.S $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 "pk.h"
+.set r0 , 0
+.set r1 , 1
+.set r2 , 2
+.set r3 , 3
+.set r4 , 4
+.set r5 , 5
+.set r6 , 6
+.set r7 , 7
+.set r8 , 8
+.set d0 , 0
+.set d2 , 2
+.set d7 , 7
+.global __reserved
+__reserved:
+#############################################################
+################## OTPROM location data contents ############
+# SBE Seeprom Config_0 18068
+# SBE Seeprom Config_1 18069
+# SBE Seeprom Config_2 1806A
+# SBE Seeprom Config_3 1806B
+# Magic number stored in OTP 1806C
+# Reserved 1806D
+# Reserved 1806E
+# Reserved 1806F
+# 0x0040 : otprom loader
+#############################################################
+_start:
+#lis r4 , 0x50 #dummy instruction
+.org __reserved + 0x0040
+.macro .pm_otprom_fixed_system
+ .section .fixed, "a", @progbits
+__seeprom0_config_reg:
+ .quad 0x80A91C7100000000
+__seeprom1_config_reg:
+ .quad 0x80AB1C7100001C71
+__seeprom2_config_reg:
+ .quad 0x80AD1C71000038E2
+__seeprom3_config_reg:
+ .quad 0x80AF1C7100005553
+__otprom_magic_num:
+ .quad 0x584950205345504D
+__sbe_config_reg:
+ .quad 0x000A800030000000
+ .endm
+oos_start: #R4 --> A0000 R5 --> 5003F R6 --> C000_0818
+ lis r4 , 0xA
+ ori r4 , r4 , 0x0
+ stvd d0 , 1(r4) #Write reset reg . A0001
+ lis r5 , 0x5 #Check the validity of scratch reg and then program the bit rate div
+ ori r5 , r5 , 0x0000
+ lvd d2 , 0x3F(r5) #loads scratch_8 and updates R5 to scratch_1
+ bb0wi r2 , 1 , oos_load_const_brd #checks if valid bit (bit1) is 1 if yes continue else branch
+ lvd d2 , 0x39(r5)
+ andis. r2 , r2 , 0xffff #delete last 2 bytes Confirmed first 2 bytes has Bit rate divisor
+
+oos_write_mode_reg:
+ lvd d0 , 6(r4) #D0 --> old mode reg and D2 --> has new brd
+ andi. r0 , r0 , 0xffff
+ or r0 , r0 , r2
+ stvd d0 , 6(r4) #Store mode register
+ lis r6 , 0xc000
+ ori r6 , r6, 0x0818 #Load clear address of local register FI2C_CFG
+ li r0 , 0xfff #Create the Clear mask
+ lis r1 , 0xf000
+ stvd d0 , 0(r6) #write to clear register of local register
+ rlwinm r3, r2, 12 , 0 , 3 #First move last nibble to R3 0:3
+ rlwinm r2, r2, 12 , 20, 31 #Store bit rate div in 20:35 location of local register 20:31
+ stvd d2 , -8(r6) #Set register = C0000810
+ b oos_write_mode_done
+
+oos_load_const_brd:
+ lis r2 , 0x3 #load constant BRD = 3 to first 2 bytes of R2
+ b oos_write_mode_reg
+
+oos_write_mode_done:
+
+oos_force_stop_to_both_ports:
+ lis r0 , 0x8000 #load 0x80000000 for port busy register write
+ stvd d0 , 0xE(r4) #Write port busy register to clear
+ andi. r0 , r0 ,0 #stop_command = 0x1000_0020_0000_0000
+ andi. r1 , r1 , 0
+ oris r0 , r0 , 0x1000
+ ori r0 , r0 , 0x0020
+ stvd d0 , 0(r4) #Write control register with Stop command
+
+oos_poll_status_bit_0:
+ lvd d2 , 2(r4) #Read Status register
+ bb1wi r3 , 0xc , oos_poll_status_bit_0
+ ori r0 , r0 , 0x0200 #stop_command = 0x1000_0220_0000_0000
+ stvd d0 , 0(r4) #write control register with stop command to port 1
+
+oos_poll_status_bit_1:
+ lvd d2 , 2(r4)
+ bb1wi r3 , 0xc , oos_poll_status_bit_1
+ lis r0 , 0xd8a9
+ ori r0 , r0 , 0x0090 #change the port number later after checking from the scratch register. Add the seeprom address pointer location by updating the R1
+ andi. r1 , r1 , 0x0 #Chose address 0x0 of SEEPROM : 0xA8
+
+oos_chk_port_num:
+ lvd d2 , 0x8(r5) #Read the port number from Selfboot control / status register ::
+ bb0wi r2 , 17 , oos_sel_prim_sprm #Check if backup seeprom select is '1' bit_17 according to Srinivas
+ ori r0 , r0 , 0x0200 #enable backup_sprm port
+ lvd d7, -24(r6) #load SBE_CONFIG local reg
+ oris r8 , r8 , 0x0200 #make bit 38 of sbe_config_reg bit '1'. (C0000800)
+ stvd d7, -24(r6) #Store SBE_CONFIG local reg
+
+oos_sel_prim_sprm:
+ stvd d0 , 0(r4) #write control register
+
+oos_poll_status_bit_2:
+ lvd d2 , 2(r4) #poll status reg
+ bb1wi r3 , 0xc , oos_poll_status_bit_2
+ lvd d0 , 3(r4) #Read data reg to get magic number
+
+oss_load_constant_magic_num: #Magic number of seeprom = 0x584950205345504D
+ lis r2 , 0x5849 #load constant otprom magic number
+ ori r2 , r2 , 0x5020
+ lis r3 , 0x5345
+ ori r3 , r3, 0x504d
+ cmplwbc 0, 2, r0, r2, oos_cmp_magic_fail
+ cmplwbc 0, 2, r1, r3, oos_cmp_magic_fail
+ lis r4 , 0x0001 #OTPROM address = 0xZZZZ_YYYY PIB_addr (R4 = 18070)
+ ori r4 , r4 , 0x8068
+ lis r5 , 0xc000 #local_reg_addr (R5 = C0000860)
+ ori r5 , r5 , 0x0860
+ lvd d0 , 0(r4)
+ stvd d0 , 0(r5) #Seeprom_0
+ lvd d0 , 1(r4)
+ stvd d0 , 32(r5) #Seeprom_1
+ lvd d0 , 2(r4)
+ stvd d0 , 64(r5) #Seeprom_2
+ lvd d0 , 3(r4)
+ stvd d0 , 96(r5) #Seeprom_3
+ lvd d0 , 5(r4) #SBE Config
+ stvd d0 , -96(r5)
+ ##### Branch to SEEPROM ###################
+ lis r4 , 0x8000 #Go and fetch the branch address from 0x8000_0001
+ ori r4 , r4 , 0x0008
+ lvd d0 , 0(r4)
+ mtctr r1
+ bctr #Branch to fetched address
+ ##### Branch to SEEPROM ###################
+ trap #FIXME hve to give branch to SEEPROM
+
+oos_cmp_magic_fail:
+ lis r5 , 0x5 #PIB_addr (R5 = 0x00050008)
+ ori r5 , r5 , 0x0000
+ lvd d0 , 8(r5)
+ andi. r1 , r1 , 0xfff0
+ ori r1 , r1 , 0x000e #59:63 : Error message : E = Magic number mismatch
+ stvd d0 ,8(r5)
+ trap
+
+.pm_otprom_fixed_system
diff --git a/src/boot/pibmem_repair.S b/src/boot/pibmem_repair.S
new file mode 100644
index 00000000..98b1ecfa
--- /dev/null
+++ b/src/boot/pibmem_repair.S
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/boot/pibmem_repair.S $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 "sbe_link.H"
+#include "pk.h"
+
+.set d0 , 0
+ .text
+ .section .loader_text, "ax", @progbits
+
+_pibmemRepair:
+
+ _liw %r3, SBE_FIXED_SECTION # Fixed Section Location
+ _liw %r9, SBE_SEEPROM_BASE_ORIGIN
+ lwz r8, 0(r3) # offset of Fixed section
+ adde r8, r8, r9 # add base address to offset to get absolute address
+ lis r5, 0x8
+ ori r5, r5 , 0x800B #point to repair reg 0 addr
+ lis r0, 0x4000 # load repair #0 with 0x4000_0000 --> enable fence and repr_mux_sel is disabled
+ stvd d0, 0(r5)
+ lvd d0, 0(r8) # r8 was pointing to attributes
+ stvd d0, 1(r5) # store repair reg 1
+ lvd d0, 8(r8) # r8 was pointing to attributes
+ stvd d0, 2(r5) # store repair reg 2
+ lvd d0, 16(r8) # r8 was pointing to attributes
+ stvd d0, 3(r5) # store repair reg 3
+ lis r0, 0x8000 # load repair #0 with 0x8000_0000 --> disable fence and repr_mux_sel is enabled
+ stvd d0 , 0(r5)
+
+###################################################################
+########### Update DBG_LCL_REG to enable trace ####################
+###################################################################
+
+ lis r5, 0xc000 # local_reg_addr (R5 = C0000120)
+ ori r5, r5, 0x0120
+ andi. r0, r0, 0x0
+ andi. r1, r1, 0x0
+ oris r0, r0, 0x8A00 # set the bit 0 to enable the debug blot-on
+ stvd d0, 0(r5) # DBG_LCL_REG
+
+ blr # back to pm_loader
+
diff --git a/src/build/models/n10_e9027_tp026_soa_sc_u285_01/base b/src/build/models/n10_e9027_tp026_soa_sc_u285_01/base
new file mode 100644
index 00000000..a5314f90
--- /dev/null
+++ b/src/build/models/n10_e9027_tp026_soa_sc_u285_01/base
@@ -0,0 +1,13 @@
+#base commit id
+base:3e4dac85ccc9e2a89f80931fe75dd918ef45dbe9
+#cherry-picks
+# fapi delay
+cp:refs/changes/57/21157/4
+# awan workarounds
+cp:refs/changes/05/22605/4
+# startclock_chiplets
+cp:refs/changes/33/22733/1
+# new compiler
+cp:refs/changes/52/22552/9
+# assert Support
+cp:refs/changes/81/22781/2
diff --git a/src/build/models/n10_e9030_tp029_soa_sc_u339_01/base b/src/build/models/n10_e9030_tp029_soa_sc_u339_01/base
new file mode 100644
index 00000000..06c64ab4
--- /dev/null
+++ b/src/build/models/n10_e9030_tp029_soa_sc_u339_01/base
@@ -0,0 +1,19 @@
+#base commit id
+base:3e4dac85ccc9e2a89f80931fe75dd918ef45dbe9
+#cherry-picks
+# fapi delay
+cp:refs/changes/57/21157/4
+# awan workarounds
+cp:refs/changes/05/22605/4
+# startclock_chiplets
+cp:refs/changes/33/22733/1
+# new compiler
+cp:refs/changes/52/22552/9
+# assert Support
+cp:refs/changes/81/22781/2
+# PBA support
+cp:refs/changes/36/20836/9
+# Remove eabi
+cp:refs/changes/24/22924/1
+# Remove pcb_arb
+cp:refs/changes/55/22955/1
diff --git a/src/build/models/n10_e9031_tp030_soa_sc_u008_01/base b/src/build/models/n10_e9031_tp030_soa_sc_u008_01/base
new file mode 100644
index 00000000..34f0793e
--- /dev/null
+++ b/src/build/models/n10_e9031_tp030_soa_sc_u008_01/base
@@ -0,0 +1,11 @@
+#base commit id
+base:177ed87bff3c7abc300069fe75cc8b89ea7b1681
+#cherry-picks
+# fapi delay
+cp:refs/changes/57/21157/4
+# awan workarounds
+cp:refs/changes/05/22605/4
+# startclock_chiplets
+cp:refs/changes/33/22733/1
+# PBA support
+cp:refs/changes/36/20836/10
diff --git a/src/build/models/n10_e9031_tp030_soa_sc_u012_01/base b/src/build/models/n10_e9031_tp030_soa_sc_u012_01/base
new file mode 100644
index 00000000..34f0793e
--- /dev/null
+++ b/src/build/models/n10_e9031_tp030_soa_sc_u012_01/base
@@ -0,0 +1,11 @@
+#base commit id
+base:177ed87bff3c7abc300069fe75cc8b89ea7b1681
+#cherry-picks
+# fapi delay
+cp:refs/changes/57/21157/4
+# awan workarounds
+cp:refs/changes/05/22605/4
+# startclock_chiplets
+cp:refs/changes/33/22733/1
+# PBA support
+cp:refs/changes/36/20836/10
diff --git a/src/build/models/n10_e9031_tp030_soa_sc_u022_01/base b/src/build/models/n10_e9031_tp030_soa_sc_u022_01/base
new file mode 100644
index 00000000..34f0793e
--- /dev/null
+++ b/src/build/models/n10_e9031_tp030_soa_sc_u022_01/base
@@ -0,0 +1,11 @@
+#base commit id
+base:177ed87bff3c7abc300069fe75cc8b89ea7b1681
+#cherry-picks
+# fapi delay
+cp:refs/changes/57/21157/4
+# awan workarounds
+cp:refs/changes/05/22605/4
+# startclock_chiplets
+cp:refs/changes/33/22733/1
+# PBA support
+cp:refs/changes/36/20836/10
diff --git a/src/build/tools/CommitSbeImageToCMVC.py b/src/build/tools/CommitSbeImageToCMVC.py
new file mode 100755
index 00000000..b6f4eca8
--- /dev/null
+++ b/src/build/tools/CommitSbeImageToCMVC.py
@@ -0,0 +1,376 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/CommitSbeImageToCMVC.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 CommitSbeImageToCMVC.py
+# @author: George Keishing <gkeishin@in.ibm.com>
+# Sangeetha TS <sangeet2@in.ibm.com>
+# @brief Main Module to support CMVC operation
+#
+# Created on March 03, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 03/03/16 Initial create
+###########################################################
+'''
+
+#-------------------------
+# Imports
+#-------------------------
+import getopt
+import os, sys, glob
+import shutil
+
+# Libraries/utility funcs and user define const
+import sbeCmvcConstants as errorcode
+import sbeCmvcUtility as utilcode
+
+#-------------------------
+# Main Function
+#-------------------------
+def main():
+
+ #------------------------------------------
+ # Usage tool option
+ #------------------------------------------
+ def usage():
+ print " ---------------------------------------------------------------------------------------------------"
+ print " :: Command line USAGE options for Uploading FW SBE image to CMVC :: \n"
+ print " CommitSbeImageToCMVC.py -d <cmvc defect/feature id> -r <fips release> -p <SBE repo Path> -i <file1,file2.file3>"
+
+ print " \n"
+ print " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ print " | By default user MUST pass CMVC/Release/Path input. |"
+ print " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ print " \n ***** Options Supported *****"
+ print " \t -d,--defect = Defect CMVC number"
+ print " \t -f,--feature = Feature CMVC number"
+ print " \t -r,--release = FW fips release string EX: fips910"
+ print " \t -p,--path = Absolute path of the SBE repo"
+ print " \t -i,--input = [ Optional ] List of image or file to upload"
+ print " \t -b,--bvt = BVT xml file for CI"
+ print " \t -h,--help = Help"
+ print " ------------------------------------------------------------------------------------"
+
+ #------------------------------------------
+ # Exit from this Main
+ #------------------------------------------
+ def exit_main(rc):
+ if rc == errorcode.HELP_EXIT:
+ print " [ HELP DOCUMENTATION ]\n"
+ sys.exit(0)
+
+ if rc:
+ print "\n [ ERROR - MAIN ] Exiting with error code = ", rc
+ sys.exit(rc)
+ else:
+ print "\n SBE Image Upload to CMVC completed [ OK ] "
+ sys.exit(0)
+
+ #------------------------------------------
+ # Local var place name holder's
+ #------------------------------------------
+ defect_num = "None"
+ feature_num = "None"
+ release_name = "None"
+ path_name = "None"
+ file_name = "None"
+ bvt = "None"
+
+ #----------------------------
+ # Read command line args
+ #----------------------------
+ opts, args = getopt.getopt(sys.argv[1:],"d:f:r:p:i:b:h",['defect=', 'feature=', 'release=', 'path=', 'input=', 'bvt=', 'help'])
+ for opt, arg in opts:
+ if opt in ('-h', '--help'):
+ usage()
+ exit_main(errorcode.HELP_EXIT)
+ elif opt in ('-d', '--defect'):
+ defect_num = arg
+ elif opt in ('-f', '--feature'):
+ feature_num = arg
+ elif opt in ('-r', '--release'):
+ release_name = arg
+ elif opt in ('-p', '--path'):
+ path_name = arg
+ elif opt in ('-i', '--input'):
+ file_name = arg
+ elif opt in ('-b', '--bvt'):
+ bvt = arg
+ else:
+ usage()
+ exit_main(errorcode.ERROR_EXIT)
+
+ #----------------------------------
+ # Preping the data for Image Upload
+ #----------------------------------
+ print " \n"
+ print " ******************************************************"
+ print " ****** Stagging PPE image Files Upload to CMVC ******"
+ print " ******************************************************"
+
+ #------------------------------------------------------
+ # Make sure that it has passed atleast one arg with it
+ #------------------------------------------------------
+ if len(sys.argv)<2:
+ usage()
+ exit_main(errorcode.ERROR_SYS_EXIT)
+
+ #-------------------------------------------------------------
+ # Check user inputs and display
+ #-------------------------------------------------------------
+ def input_setting():
+ print " ---------------------------------------------------------------------------------"
+ print " [ Display User Inputs ]"
+ print " ---------------------------------------------------------------------------------"
+ # Look elsewhere for the name instead of assigning to it locally.
+ # This is now gloabal var
+ global g_cmvc_num
+ if ( defect_num != "None" ) or ( feature_num != "None" ):
+ if not defect_num == "None":
+ g_cmvc_num = 'D'+defect_num #D1234
+ print " [ CMVC Defect ] \t\t#Number\t = %s"%(g_cmvc_num)
+ else:
+ g_cmvc_num = 'F'+feature_num # F1234
+ print " [ CMVC Feature ] \t\t#Number\t = %s"%(g_cmvc_num)
+ else:
+ print " [ CMVC Defect/Feature ] Neeed CMVC number. This can't be empty "
+ exit_main(errorcode.ERROR_EXIT)
+
+ if not release_name == "None":
+ print " [ Fips Release Name ] \t#String\t = %s"%(release_name)
+ else:
+ print " [ Fips release ] Neeed fips release string. This can't be empty "
+ exit_main(errorcode.ERROR_EXIT)
+
+ if not path_name == "None":
+ print " [ Build Repo Path ] \t\t#String\t = %s"%(path_name)
+ else:
+ print " [ User Build Repo Path ] \t\t#String\t = %s"%(path_name)
+
+ # Optional, by default looks up predefined files
+ if not file_name == "None":
+ print " [ Files for Check-in - User List ]"
+ for files in file_name.split(","):
+ print " \t\t\t\t#",files
+ else:
+ print " [ Files for Check-in - Default List ]"
+ for files in errorcode.CMVC_FILE_LIST.split(","):
+ print " \t\t\t\t# ",files
+
+ print " ---------------------------------------------------------------------------------"
+
+ #-------------------------------------------------------------
+ # CMVC ENV check
+ #-------------------------------------------------------------
+ def UserCmvcENV():
+ # Assumed the CMVC cofig is there in the user bash ENV
+ # In .bashrc the CMVX ENV would look like this
+ # CMVC specific example
+ #-----------------------------------------------------------
+ #export CMVC_FAMILY=aix@auscmvc1.austin.ibm.com@2035
+ #export CMVC_BECOME=gkeishin
+ #export CMVC_AUTH_METHOD=PWD
+ #-----------------------------------------------------------
+
+ l_found_cmvc_conf = False
+ for key in os.environ.keys():
+ if "CMVC" in key:
+ print "\t %s : %s" % (key,os.environ[key])
+ l_found_cmvc_conf = True
+
+ if l_found_cmvc_conf == False:
+ print "\n [ ERROR SETTING ] : The CMVC specific ENV is not set"
+ print " Please add the following CMVC details in ~/.bashrc"
+ print " ------------------------------------------------------"
+ print " export CMVC_FAMILY=aix@<yourcmvcdomian>@<portnumber>"
+ print " export CMVC_BECOME=<your cmvc id>"
+ print " export CMVC_AUTH_METHOD=PWD"
+ print " ------------------------------------------------------"
+ return errorcode.ERROR_SETTING
+
+ return errorcode.SUCCESS_EXIT
+
+ # Testing CMVC login session.. probe
+ def CheckCmvcAccess():
+ cmd='File -view src/sbei/sbfw/img/sbe_seeprom.bin -family aix -release fips910 >/dev/null 2>&1'
+ rc = os.system(cmd)
+ if rc:
+ return errorcode.ERROR_CMVC_LOGIN
+
+ #---------------------------------------------
+ # Callling the Func defs in order
+ #---------------------------------------------
+
+ #------------------------------
+ # 1) User input params/ Check ENV
+ #------------------------------
+ input_setting()
+
+ print "\n [ Checking PPE ENV Pre-req ] "
+ # Check if User has passed the path, else get it from ENV
+ if path_name == "None":
+ # Get the PPE path
+ l_ppe_path = utilcode.utilppeSbENV("SBEROOT")
+ if l_ppe_path == "None":
+ print " PPE Repo ENV Setting Path : [ ERROR CODE: %s ] " % l_ppe_path
+ exit_main(errorcode.ERROR_SETTING)
+ else:
+ print " PPE Repo path Setting : [ %s ]"% l_ppe_path
+ path_name = l_ppe_path
+
+ print "\n [ Checking CMVC user ENV Pre-req ] "
+ rc_code = UserCmvcENV()
+ if rc_code == errorcode.SUCCESS_EXIT :
+ print " CMVC Setting : [ OK ] "
+ else:
+ print " CMVC Setting : [ ERORR CODE: %s ]"% rc_code
+
+ #------------------------------
+ # 2) Check the CMVC login access
+ #------------------------------
+ print "\n [ Checking CMVC user Login Session access ] "
+ rc_cmvc = CheckCmvcAccess()
+ if rc_cmvc == errorcode.ERROR_CMVC_LOGIN:
+ print " CMVC Login Access : [ ERORR CODE: %s ]"% rc_cmvc
+ print "\t No cmvc login was found in this session."
+ print "\t Issue the cmvclog command to establish a login and re-run."
+ print "\t Command : cmvclog -in <login user id>"
+ exit_main(rc_cmvc)
+ else:
+ print " CMVC Session Login : [ OK ] "
+
+ # Call API/Utility funcs def here
+ #------------------------------
+ # 3) Check track status
+ #------------------------------
+ print "\n [ Checking CMVC track state ] "
+ l_trackFix = utilcode.utilCheckTrackState(g_cmvc_num,release_name)
+ if l_trackFix == errorcode.SUCCESS_TRACK_STATE :
+ print " Track in fix state. Suitable to continue."
+ else :
+ print " Track not in fix state. Aborting activity."
+ return errorcode.ERROR_TRACK_STATE
+
+ #------------------------------
+ # 4) Checkout the code
+ #------------------------------
+ print "\n [ Creating Sandbox ]"
+ origDir = os.getcwd()
+ utilcode.utilCmvcChangeDir(g_cmvc_num)
+ sbDir = os.getcwd()
+
+ print "\n [ Checkout Files from CMVC ] "
+ print " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ if file_name == "None":
+ file_name = errorcode.CMVC_FILE_LIST
+ for l_filename in file_name.split(","):
+ rc_checkout = utilcode.utilCmvcCheckout(l_filename,release_name,g_cmvc_num)
+ if rc_checkout == errorcode.ERROR_CMVC_CHECKOUT:
+ print " [ CMVC File Checkout Failed ] [Error code : %s]\t:%s"%(rc_checkout,l_filename)
+ # Undo checkout.. dont check errors just do it
+ utilcode.utilRollBack("checkout",g_cmvc_num,release_name)
+ # Return to initial directory of operation
+ os.chdir(origDir)
+ shutil.rmtree(sbDir)
+ exit_main(rc_checkout)
+ else:
+ print " CMVC File Checkout [ OK ]"
+ print " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+
+ #------------------------------
+ # 4) Copy the binaries and file
+ #------------------------------
+ # Find the files from the repo and copy to the Checkout dir
+ print "\n [ Find files and Overide the checkout file ] "
+ print " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ rc_copy = utilcode.utilCmvcRepoPath(path_name,g_cmvc_num,file_name)
+ if rc_copy == errorcode.ERROR_CMVC_FILE_COPY:
+ print " [ File copy Failed ] [ Error code : %s]"%rc_copy
+ # Return to initial directory of operation
+ os.chdir(origDir)
+ shutil.rmtree(sbDir)
+ exit_main(rc_copy)
+ else:
+ print " Files Copied Successfully : [ OK ] "
+
+ print " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+
+ #---------------------
+ # 6) Checkin the files
+ #---------------------
+ print "\n [ Check-in Files from CMVC ] "
+ print " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ if file_name == "None":
+ file_name = errorcode.CMVC_FILE_LIST
+ for files in file_name.split(","):
+ rc_checkin = utilcode.utilCmvcCheckin(files,release_name,g_cmvc_num)
+ if rc_checkin == errorcode.ERROR_CMVC_CHECKIN:
+ print " [ CMVC File Checkin Failed ] [Error code : %s]\t:%s"%(rc_checkin,files)
+ # Undo checkin.. dont check errors just do it
+ utilcode.utilRollBack("checkin",g_cmvc_num,release_name)
+ # Return to initial directory of operation
+ os.chdir(origDir)
+ shutil.rmtree(sbDir)
+ exit_main(rc_checkin)
+ else:
+ print " CMVC File Checkin [ OK ]"
+ print " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+
+ #---------------------------------
+ # 7) Fix record the defect/release
+ #---------------------------------
+ print "\n [ Fix the Record to complete in CMVC ] "
+ utilcode.utilCmvcFixComplete(g_cmvc_num, release_name)
+
+ #---------------------------------
+ # 8) Trigger Jenkins CI Job
+ #---------------------------------
+ print "\n [ Trigering Jenkins job ] "
+ rc_ci = utilcode.utilTriggerJenkins(g_cmvc_num, release_name, bvt)
+ if rc_ci == errorcode.ERROR_CI_TRIGGER :
+ print " [ CI Trigger Failed ] [Error code : %s]\t"%(rc_ci)
+ # Return to initial directory of operation
+ os.chdir(origDir)
+ shutil.rmtree(sbDir)
+ exit_main(rc_ci)
+ else :
+ print " CI Trigger [ OK ]"
+
+ #-----------------------------------------
+ # Return to initial directory of operation
+ #-----------------------------------------
+ os.chdir(origDir)
+ shutil.rmtree(sbDir)
+
+ # Clean exit
+ print "\n [ Manually Integrate on CMVC post CI ] "
+ exit_main(errorcode.SUCCESS_EXIT)
+
+
+if __name__=="__main__":
+ main()
+
diff --git a/src/build/tools/Debug/sbe-debug.py b/src/build/tools/Debug/sbe-debug.py
new file mode 100755
index 00000000..a6c20c47
--- /dev/null
+++ b/src/build/tools/Debug/sbe-debug.py
@@ -0,0 +1,136 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/Debug/sbe-debug.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import os
+import subprocess
+import re
+import random
+import argparse
+import sys
+err = False
+
+syms = {};
+
+def fillSymTable(sbeObjDir):
+ symFile = sbeObjDir + "/sbe.syms"
+ f = open( symFile, 'r' )
+ for line in f:
+ words = line.split()
+ if( len( words ) == 4 ):
+ syms[words[3]] = [words[0], words[1]]
+
+def collectTrace( hwpBinDir, sbeObjDir, target, proc ):
+ cmd1 = ("."+hwpBinDir+"/p9_sbe_pibMemDump_wrap.exe " + \
+ syms['g_pk_trace_buf'][0] +\
+ " " + syms['g_pk_trace_buf'][1] + " " + target)
+ cmd2 = "." + "/ppe2fsp dumpPibMem sbetrace.bin "
+ cmd3 = ("." + "/fsp-trace -s " + sbeObjDir +\
+ "/trexStringFile sbetrace.bin > "+\
+ "sbe_"+str(proc)+"_tracMERG")
+ cmd4 = "mv dumpPibMem dumpPibMem_trace"
+ print "\ncollecting trace with commands -\n"
+ print "cmd1:", cmd1
+ rc = os.system( cmd1 )
+ if ( rc ):
+ print "ERROR running %s: %d " % ( cmd1, rc )
+ return 1
+
+ print "cmd2:", cmd2
+ rc = os.system( cmd2 )
+ if ( rc ):
+ print "ERROR running %s: %d " % ( cmd2, rc )
+ return 1
+
+ print "cmd3:", cmd3
+ rc = os.system( cmd3 )
+ if ( rc ):
+ print "ERROR running %s: %d " % ( cmd3, rc )
+ return 1
+
+ print "cmd4:", cmd4
+ rc = os.system( cmd4 )
+ if ( rc ):
+ print "ERROR running %s: %d " % ( cmd4, rc )
+ return 1
+
+def collectAttr( hwpBinDir, sbeObjDir, target, proc ):
+ cmd1 = ("."+hwpBinDir+"/p9_sbe_pibMemDump_wrap.exe " +\
+ syms['G_sbe_attrs'][0] + " " + \
+ syms['G_sbe_attrs'][1] + " " + target)
+ cmd2 = "mv dumpPibMem sbeAttr.bin"
+ cmd3 = ("."+ sbeObjDir + "/p9_xip_tool " +\
+ sbeObjDir + "/sbe_seeprom.bin -ifs attrdump sbeAttr.bin > "+\
+ "sbe_"+str(proc)+"_attrs")
+ print "\ncollecting attributes with commands -\n"
+ print "cmd1:", cmd1
+ rc = os.system( cmd1 )
+ if ( rc ):
+ print "ERROR running %s: %d " % ( cmd1, rc )
+ return 1
+
+ print "cmd2:", cmd2
+ rc = os.system( cmd2 )
+ if ( rc ):
+ print "ERROR running %s: %d " % ( cmd2, rc )
+ return 1
+
+ print "cmd3:", cmd3
+ rc = os.system( cmd3 )
+ if ( rc ):
+ print "ERROR running %s: %d " % ( cmd3, rc )
+ return 1
+
+def main( argv ):
+ parser = argparse.ArgumentParser( description = "SBE Dump Parser" )
+
+ parser.add_argument( '-hwpBinDir', type=str, default = os.getcwd(), \
+ help = 'Path of p9_sbe_pibMemDump_wrap.exe')
+ parser.add_argument( '-sbeObjDir', type=str, default = os.getcwd(), \
+ help = 'Path of sbe.syms file')
+ parser.add_argument( '-l', '--level', choices = ['all', 'trace', 'attr'],\
+ default='all', help = 'Parser level' )
+ parser.add_argument( '-t', '--target', choices = ['AWAN', 'HW'], \
+ required = 'true', help = 'Target type' )
+ parser.add_argument( '-p', '--proc', type=int , default = 0, \
+ help = 'Proc Number' )
+
+ args = parser.parse_args()
+
+ if ( args.target == 'AWAN' ):
+ target = "1"
+ elif ( args.target == 'HW' ):
+ target = "0"
+
+ fillSymTable(args.sbeObjDir)
+ if ( args.level == 'all' ):
+ print "Parsing everything"
+ collectTrace( args.hwpBinDir, args.sbeObjDir, target, args.proc )
+ collectAttr( args.hwpBinDir, args.sbeObjDir, target, args.proc )
+ elif ( args.level == 'trace' ):
+ collectTrace( args.hwpBinDir, args.sbeObjDir, target, args.proc )
+ elif ( args.level == 'attr' ):
+ collectAttr( args.hwpBinDir, args.sbeObjDir, target, args.proc )
+
+if __name__ == "__main__":
+ main( sys.argv )
diff --git a/src/build/tools/README b/src/build/tools/README
new file mode 100644
index 00000000..3f27a6b0
--- /dev/null
+++ b/src/build/tools/README
@@ -0,0 +1,66 @@
+--------------------
+CONTENT OF THIS FILE
+--------------------
+1. Tools:
+ * Automate SBE Image integration into FIPS driver
+ * Developer SBE fips tool for copy and compile
+
+
+-------------------------------------------------
+* Automate SBE Image integration into FIPS driver
+-------------------------------------------------
+ [ Files ] : CommitSbeImageToCMVC.py (Main)
+ sbeCmvcConstants.py
+ sbeCmvcUtility.py
+
+ [ Brief ] : This tool will check in the SBE FW fips files to CMVC, Fix Complete the track and trigger Jenkin Job.
+
+ [ Feature ] :
+ - By default, the tool will check in the files from a default list pre-defined for sbe
+ Refer: sbeCmvcConstants.py
+
+ - User can selectively choose which file/files it wants to upload to CMVC from the default list
+
+ - The tool roll backs all the checkout/checkin in case of CMVC Operation failure
+
+ - The tool will auto complete fix record on completion of successful code check in
+
+ - The internal of the work flow validates the Hash of the files on the SBE repo vs files to be
+ check in to be sure that the files are correctly uploaded
+
+ - The pre-req checks CMVC bash env and CMVC access session availability and provides verbose
+ help to follow on failures
+
+ - Jenkin job trigger at the end after fix completing record.
+
+
+------------------------------------------------------------------
+* Developer SBE fips tool for copy,compile & simics action patches
+------------------------------------------------------------------
+
+ [ Files ] : sbeDistribute.py (Main)
+ sbePatchUtility.py
+ sbeCmvcConstants.py
+ sbeCmvcUtility.py
+
+ [ Brief ] : This tool will copy the SBFW files from PPE repo to fips sandbox and compile.
+ Additionaly it would patch the simics action files at the end of compilation.
+
+ [ Feature ] :
+ - By default, the tool doesn't need any input as an argument
+
+ - Refers the Sandbox and Repo ENV and identifies which fips sandbox and PPE Repo needed.
+
+ - Find the list of pre-define file list in the PPE repo and copies to fips sandbox
+ Refer: sbeCmvcConstants.py
+
+ - Loads the ENV and compiles the fips sandbox code.
+
+ - User can create a fips sandbox manually and still use this tool by passing -s <sandbox name >
+ as an argument
+
+ - User can specify file as an input but -ONLY- those pre-define files selectively using option
+ -i <file1,file2>
+
+ - Sets up simics directory and patches the action files needed.
+
diff --git a/src/build/tools/conv_rel_branch.pl b/src/build/tools/conv_rel_branch.pl
new file mode 100755
index 00000000..05ef52ea
--- /dev/null
+++ b/src/build/tools/conv_rel_branch.pl
@@ -0,0 +1,339 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/conv_rel_branch.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+use strict;
+use warnings;
+use Data::Dumper;
+use Getopt::Long qw(:config pass_through);
+
+# Globals
+my %power_platforms = ();
+my %relations = ();
+my $latest_power_platform = "";
+my $fsp_ci_jenkins_rel_file = "/gsa/ausgsa/home/f/s/fspcibld/patches/cipatch_xml";
+use constant MASTER => "master";
+my $debug = 0;
+my $help = 0;
+
+# Set local variables based on ENV variables
+my $PROJECT_ROOT = `git rev-parse --show-toplevel`;
+
+# Parse command line parameters
+GetOptions("debug!" => \$debug,
+ "help" => \$help);
+
+# List of commands tool can run
+my %commands = ( "rtob" => \&execute_rel_to_branch,
+ "btor" => \&execute_branch_to_rel,
+ );
+
+if ($help)
+{
+ execute_help();
+}
+else
+{
+ my $command = shift @ARGV;
+ if ($commands{$command})
+ {
+ system("git remote -v | grep gerrit -q");
+ die "Gerrit remote DNE, must run in repo with gerrit remote" if $?;
+ # Build release to branch relation hash.
+ build_relations();
+ &{$commands{$command}}();
+ }
+ else
+ {
+ execute_help();
+ }
+}
+
+############################## Begin Actions ###################################
+
+sub execute_rel_to_branch
+{
+ my $release = "";
+
+ GetOptions("release:s" => \$release);
+ die "Missing release" if $release eq "";
+
+ # Get power platform associated with release
+ my $power_platform = get_power_platform($release);
+ # Find release in relations hash.
+ my $branch = $relations{$power_platform}{$release};
+ die "Fips release => $release has no corresponding gerrit branch" if (!$branch);
+ print "$branch \n";
+}
+
+sub execute_branch_to_rel
+{
+ my $branch = "";
+
+ GetOptions("branch:s" => \$branch);
+ die "Missing branch" if $branch eq "";
+
+ # Get power platform associated with branch
+ my $power_platform = get_power_platform($branch);
+
+ # Find branch in relations hash.
+ my $release = "";
+ if( $power_platform )
+ {
+ foreach my $rel (sort keys %{$relations{$power_platform}})
+ {
+ if ($relations{$power_platform}{$rel} eq "$branch")
+ {
+ $release = $rel;
+ last;
+ }
+ }
+ }
+ die "Gerrit branch => $branch has no corresponding fips release" if ($release eq "");
+ print "$release \n";
+}
+
+sub execute_help
+{
+ my $command = shift @ARGV;
+
+ if ($command eq "")
+ {
+ print " Usage:\n";
+ print " conv_rel_branch <subtool> [options]\n\n";
+ print " Tool to convert fips release to branches and vice versa\n\n";
+ print " Requires:\n";
+ print " Tool to run in git repo that has gerrit remote\n\n";
+ print " Available subtools:\n";
+ foreach my $key (sort keys %commands)
+ {
+ print " $key\n";
+ }
+ print "\n";
+ print " Global options:\n";
+ print " --debug Enable debug mode.\n";
+ print " --help Display help on a specific tool.\n";
+ }
+ elsif (not defined $commands{$command})
+ {
+ die "Unknown subcommand: $command.\n";
+ }
+ else
+ {
+ my %help = (
+ "rtob" =>
+q(
+ Convert release to branch
+
+ Options:
+ --release=<release> Fips release name (e.g. fips810) [required].
+),
+ "btor" =>
+q(
+ Convert branch to fips release
+
+ Options:
+ --branch=<remote-gerrit-branch> Remote gerrit branch (e.g. release-fips910, master) [required].
+),
+ );
+
+ print "rel_branch $command:";
+ print $help{$command};
+ }
+}
+
+############################## Begin Sub Routines ##############################
+
+# sub get_release_branches
+#
+# Get all branches in gerrit that are prefixed 'release-' and remove the prefix
+# *Note branches with string 'master' are removed from this to result in direct
+# matches of fips releases only. Master branches will be dervied later.
+#
+# @return array - sorted names of branches (e.g release-fips810 ...)
+#
+sub get_release_branches
+{
+ chdir($PROJECT_ROOT);
+ die $? if ($?);
+
+ # Parse for remote gerrit branches associated directly with a release
+ my $cmd = "git branch -a | grep -e remotes/gerrit/release";
+ $cmd .= " | sed -e 's/^[ \\t]*remotes\\/gerrit\\///'";
+
+ my @release_branches = sort (split('\n',`$cmd`));
+ print "Release Branches:\n" if $debug;
+ print Dumper \@release_branches if $debug;
+ return @release_branches;
+}
+
+# sub get_fips_releases
+#
+# Get all fips releases that fsp-ci-jenkins uses in sorted order.
+#
+# @return array - sorted names of releases (e.g fips910, fips920, etc)
+#
+sub get_fips_releases
+{
+ chdir($PROJECT_ROOT);
+ die $? if ($?);
+
+ # Parse fsp-ci-jenkins xml file for releases
+ my $cmd = "cat $fsp_ci_jenkins_rel_file | grep release | ";
+ $cmd .= "sed -e 's/^[ \\t]*<release>//' -e 's/<\\/release>[ \\t]*//'";
+
+ my @fips_releases = sort (split('\n',`$cmd`));
+ print "Fips Release:\n" if $debug;
+ print Dumper \@fips_releases if $debug;
+ return @fips_releases;
+}
+
+# sub get_power_platform
+#
+# Takes a references (release or gerrit branch) and determines the power
+# platform it belongs to.
+#
+# @return string - power platform (e.g. p8, p9)
+#
+sub get_power_platform
+{
+ my $reference = shift;
+
+ my $power_platform = "";
+ if ($reference =~ m/master/)
+ {
+ # Remove prefix from older platforms (e.g. master-p8). If nothing is
+ # replaced then it is the latest power platform.
+ $reference =~ s/master-//;
+ if ($reference eq MASTER)
+ {
+ $power_platform = $latest_power_platform;
+ }
+ else
+ {
+ $power_platform = $reference;
+ }
+ }
+ else
+ {
+ ($power_platform) = $reference =~ /fips(.*)[0-9][0-9]/;
+ if ( $power_platform )
+ {
+ $power_platform = "p$power_platform";
+ $power_platforms{$power_platform} = 1;
+ }
+ }
+ return $power_platform;
+}
+
+
+# sub branchExists
+
+sub branchExists
+{
+ my $branch = shift;
+ chomp($branch);
+ my $brChk = `git branch -a | grep $branch`;
+ if ($brChk eq "")
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+# sub build_relations
+#
+# Build a relationship hash between fips releases and gerrit branches using
+# fsp-ci-jenkins xml and git branch command within PPE.
+#
+# Structure:
+# power_platform =>
+# fips-release => gerrit-branch
+# Example:
+# p9 =>
+# fips910 => master
+#
+sub build_relations
+{
+ my @releases = get_fips_releases();
+ my @branches = get_release_branches();
+
+ # Fill in fips release keys
+ foreach my $release (@releases)
+ {
+ my $power_platform = get_power_platform($release);
+ $relations{$power_platform}{$release} = "";
+ }
+
+ # Fill in fips release values, which are gerrit release branches.
+ foreach my $branch (@branches)
+ {
+ my $power_platform = get_power_platform($branch);
+ my $release = $branch;
+ $release =~ s/release-//;
+ $relations{$power_platform}{$release} = $branch;
+ }
+
+ # Handle master branches for each platform
+ my @platforms = sort keys %power_platforms;
+ foreach my $i (0 .. $#platforms)
+ {
+ my $power_platform = $platforms[$i];
+
+ # Lastest power platform matches branch master
+ my $master = MASTER;
+ # Previous power platforms match branch "master-$platform"
+ if ($i < $#platforms)
+ {
+ $master = MASTER."-$power_platform";
+ }
+ else
+ {
+ # Set latest power platform
+ $latest_power_platform = $power_platform;
+ }
+
+ # Check for first fips release without a gerrit branch. Due to sort
+ # order, it will be the next in order release. It is done this way
+ # to avoid issues when fips releases are ahead of gerrit branches. In
+ # other words it is possible to have fips releases past gerrit master.
+ foreach my $release (sort keys %{$relations{$power_platform}})
+ {
+ if ($relations{$power_platform}{$release} eq "")
+ {
+ if (branchExists($master))
+ {
+ $relations{$power_platform}{$release} = $master;
+ }
+ last;
+ }
+ }
+ }
+
+ print "Relations:\n" if $debug;
+ print Dumper \%relations if $debug;
+}
diff --git a/src/build/tools/gitRelease.pm b/src/build/tools/gitRelease.pm
new file mode 100755
index 00000000..e6a52e87
--- /dev/null
+++ b/src/build/tools/gitRelease.pm
@@ -0,0 +1,2102 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/gitRelease.pm $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+use strict;
+
+use Getopt::Long qw(:config pass_through);
+use POSIX;
+use Text::Wrap;
+use List::Util 'max';
+use Term::ReadKey;
+use File::Temp qw/tempfile/;
+
+use Data::Dumper;
+
+my $debug = 0;
+my $help = 0;
+
+# default globals
+my %globals = ( branch => "master");
+# Token used by git-CI-tool @execute_discover, update there too
+my $TOKEN = "!@#%^";
+
+GetOptions("debug!" => \$debug,
+ "help" => \$help,
+ "branch:s" => \$globals{"branch"});
+
+my %commands = ( "define" => \&execute_define,
+ "undef" => \&execute_undef,
+ "list-levels" => \&config_print_levels,
+ "query-gerrit" => \&execute_gerrit_query,
+ "query-git" => \&execute_git_query,
+ "query-level" => \&execute_level_query,
+ "add-patch" => \&execute_add_patch,
+ "add-forcedep" => \&execute_add_forcedep,
+ "verify-patches" => \&execute_verify_patches,
+ "release" => \&execute_release,
+ "build-name" => \&execute_build_name,
+ "gerrit-commit" => \&execute_gerrit_commit,
+ "help" => \&execute_help,
+ );
+
+if ($help)
+{
+ execute_help();
+}
+
+my $command = shift @ARGV;
+if ($commands{$command})
+{
+ &{$commands{$command}}();
+}
+else
+{
+ execute_help();
+}
+
+foreach my $arg (@ARGV)
+{
+ print "Unprocessed arg: $arg\n" if $debug;
+}
+
+############################## Begin Actions ##################################
+
+sub execute_define
+{
+ print "Defining new level...\n";
+
+ my %level = ();
+
+ GetOptions("level:s" => \$level{name},
+ "name:s" => \$level{name},
+ "baseline:s" => \$level{base},
+ "released:s" => \$level{released});
+
+ die "Missing level name" if ($level{name} eq "");
+ die "Missing baseline name" if ($level{base} eq "");
+ die "Missing released level name" if ($level{released} eq "");
+
+ print "New level: ".$level{name}.":".$level{base}.":".$level{released}."\n"
+ if $debug;
+
+ $level{base} = git_resolve_ref($level{base});
+ $level{released} = git_resolve_ref($level{released});
+
+ config_add_level(\%level);
+}
+
+sub execute_undef
+{
+ my $level = shift @ARGV;
+
+ die "Level to undefine not given" if ($level eq "");
+
+ my $levels = config_list_levels();
+ die "Level $level does not exist" if (not defined $levels->{$level});
+
+ print "Undefining level $level...\n";
+ config_del_level($level);
+}
+
+sub execute_gerrit_query
+{
+ my $project = "";
+
+ GetOptions("project:s" => \$project);
+
+ if ("" eq $project)
+ {
+ $project = config_project();
+ }
+
+ my $items = gerrit_query("status:open project:$project ".
+ "branch:".$globals{"branch"});
+
+ foreach my $item (@$items)
+ {
+ if (defined $item->{"project"})
+ {
+ print wrap("","",$item->{"subject"}) . "\n";
+ print "\t" . $item->{"id"} . "\n";
+ print "\n";
+ }
+ }
+}
+
+sub execute_git_query
+{
+ my $level = "";
+
+ GetOptions("name:s" => \$level,
+ "level:s" => \$level);
+
+ die "Missing level name" if ($level eq "");
+
+ $globals{"branch"} = git_resolve_ref($globals{"branch"});
+
+ my $level = config_get_level($level);
+
+ my $commits = git_commit_history($globals{"branch"}, $level->{base});
+
+ foreach my $commit (@{$commits})
+ {
+ my $subject = git_get_subject($commit);
+ print "$subject\n\t$commit\n\n";
+ }
+}
+
+sub execute_level_query
+{
+ my $level = "";
+
+ GetOptions("name:s" => \$level,
+ "level:s" => \$level);
+
+ die "Missing level name" if ($level eq "");
+
+ my $level_info = config_get_level($level);
+
+ print "Level $level\n";
+ print " Base: \n";
+ print " ".git_name_rev($level_info->{base})."\n";
+ print " Released:\n";
+ print " ".git_name_rev($level_info->{released})."\n";
+ if ($globals{"branch"} ne "master")
+ {
+ print " Branch:\n";
+ print " ".$globals{"branch"}."\n";
+ }
+ print " Patches:\n";
+ foreach my $patch (sort @{$level_info->{patches}})
+ {
+ print " $patch\n";
+ }
+ print " Forced Deps:\n";
+ foreach my $dep (sort keys %{$level_info->{forceDeps}})
+ {
+ my $deps = $level_info->{forceDeps};
+ print " $dep =>\n";
+ print " ".$deps->{$dep}."\n";
+ }
+}
+
+
+sub execute_add_patch
+{
+ my $level = "";
+ my $patch = "";
+
+ GetOptions("name:s" => \$level,
+ "level:s" => \$level,
+ "patch:s" => \$patch);
+
+ die "Missing level name" if ($level eq "");
+ die "Missing patch name" if ($patch eq "");
+
+ config_add_patch($level, $patch);
+}
+
+sub execute_add_forcedep
+{
+ my $level = "";
+ my $from = "";
+ my $to = "";
+
+ GetOptions("name:s" => \$level,
+ "level:s" => \$level,
+ "from:s" => \$from,
+ "to:s" => \$to);
+
+ die "Missing level name" if ($level eq "");
+ die "Missing from depend" if ($from eq "");
+ die "Missing to depend" if ($to eq "");
+
+ config_add_dep($level, $from, $to);
+}
+
+sub execute_verify_patches
+{
+ my $level = "";
+
+ GetOptions("name:s" => \$level,
+ "level:s" => \$level);
+
+ die "Missing level name" if ($level eq "");
+
+ my $level_info = config_get_level($level);
+ my $patches = $level_info->{patches};
+
+ $patches = gerrit_resolve_patches($patches);
+
+ config_verify_patches($level_info->{base}, $patches);
+}
+
+sub execute_release
+{
+ my $level = "";
+
+ GetOptions("name:s" => \$level,
+ "level:s" => \$level);
+
+ die "Missing level name" if ($level eq "");
+
+ my $level_info = config_get_level($level);
+
+ config_release($level_info,1);
+}
+
+sub execute_build_name
+{
+ # default release - 910, build letter - a, build prefix - sbe
+ my $release = "910";
+ my $build_letter = "a";
+ my $build_prefix = "sbe";
+
+ GetOptions("release:s" => \$release,
+ "letter:s" => \$build_letter,
+ "prefix:s" => \$build_prefix);
+
+ system ("date +".$build_prefix."%m%d".$build_letter."_%g%V.$release");
+}
+
+sub execute_gerrit_commit
+{
+ my $patches = "";
+
+ GetOptions("patches:s" => \$patches);
+
+ die "Missing patches" if ($patches eq "");
+
+ # Parse out csv list of patches
+ my @patches = split(/,+/, $patches);
+
+ my $commits = gerrit_resolve_patchset(\@patches);
+ foreach my $commit (@$commits)
+ {
+ print $commit;
+ print "," if( \$commit != \$commits->[-1] )
+ }
+ print "\n";
+}
+
+sub execute_help
+{
+ my $command = shift @ARGV;
+
+ if ($command eq "")
+ {
+ print "gitRelease:\n";
+ print " Prepare the git codebase for release.\n";
+ print "\n";
+ print " Syntax:\n";
+ print " gitRelease [options] <tool>\n";
+ print "\n";
+ print " Available subtools:\n";
+ foreach my $key (sort keys %commands)
+ {
+ print " $key\n";
+ }
+ print "\n";
+ print " Global options:\n";
+ print " --debug Enable debug mode.\n";
+ print " --help Display help on a specific tool.\n";
+ print " --branch Branch to use for release.\n";
+ print "\n";
+ print " Note: Generally a <commit> can be any git or gerrit\n";
+ print " reference. A git commit number, tag, branch, or\n";
+ print " a gerrit change-id are all valid.\n";
+ }
+ elsif (not defined $commands{$command})
+ {
+ die "Unknown subcommand: $command.\n";
+ }
+ else
+ {
+ my %help = (
+ "define" =>
+q(
+ Define a new level for release.
+
+ Options:
+ --level=<name> Name for the new level [required].
+ --base=<commit> Baseline commit [required].
+ --released=<commit> Commit of previous release [required].
+),
+ "undef" =>
+q(
+ Delete a previously defined release level.
+
+ Options:
+ --level=<name> Name for the level to delete [required].
+),
+ "list-levels" =>
+q(
+ Displays a list of currently defined levels.
+),
+
+ "query-gerrit" =>
+q(
+ Displays a list of open change-sets from the Gerrit server.
+),
+ "query-git" =>
+q(
+ Displays a list of merged commits which are NOT currently destined
+ for a release level.
+
+ Options:
+ --level=<name> Name for the level to query [required].
+ --branch=<commit> Branch to query against [default=master].
+),
+ "query-level" =>
+q(
+ Displays information about a defined release level.
+
+ Options:
+ --level=<name> Name for the level to query [required].
+),
+ "add-patch" =>
+q(
+ Adds a commit to the patch-list for a release.
+
+ Options:
+ --level=<name> Release to add patch to [required].
+ --patch=<commit> Commit to add to patch-list [required].
+),
+ "add-forcedep" =>
+q(
+ Add a commit-pair as a forced dependency for a release.
+
+ Options:
+ --level=<name> Release to add dependency to [required].
+ --from=<commit> Decendent commit in the dependency [required].
+ --to=<commit> Ancestor commit in the dependency [required].
+),
+ "verify-patches" =>
+q(
+ Verify patch-list to ensure all dependencies are met.
+
+ This tool will give a list of dependency candidates if an ancestor
+ commit is found modifying the same files as a commit in the
+ patch-list.
+
+ Options:
+ --level=<name> The level to verify [required].
+),
+ "release" =>
+q(
+ Create a branch / tag based on the definition of a release.
+
+ Options:
+ --level=<name> The level to release [required].
+),
+ "build-name" =>
+q(
+ Display a properly formatted build name based on the date.
+
+ Ex: sbe0402a_1412.910
+
+ Options:
+ --release=<id> Release name [default=910].
+ --letter=[a-z] Build letter [default=a].
+ --prefix=[a-z] Build prefix [default=sbe]
+),
+ "gerrit-commit" =>
+q(
+ Get commit number of gerrit change-id, patch-set pairs
+
+ Options:
+ --patches=<change-id:patchset> CSV of change-id:patchset [required].
+),
+ );
+
+ my $release = "";
+ my $level = "";
+ my $checkInDir = "";
+
+ print "gitRelease $command:";
+ print $help{$command};
+
+ }
+}
+
+
+######################### Begin Utility Subroutines ###########################
+
+
+
+# sub create_release_notes
+#
+# Generates an HTML file (releaseNotes.html) with the release notes for a
+# release.
+#
+# @param [in] level - The level name to release.
+# @param [in] level_info - The level_info hash (see config_get_level).
+#
+sub create_release_notes
+{
+ my $level = shift;
+ my $level_info = shift;
+
+ my $commits = git_commit_history("HEAD", $level_info->{released});
+
+ open RELNOTE, "> ".git_root()."/releaseNotes.html";
+ print RELNOTE "<html>\n";
+ print RELNOTE " <head><title>Release notes for $level</title></head>\n";
+ print RELNOTE <<STYLESHEET;
+ <style type="text/css">
+ table.release {
+ border-width: 1px;
+ border-spacing: 2px;
+ border-style: outset;
+ border-color: gray;
+ border-collapse: separate;
+ background-color: white;
+ }
+ table.release th {
+ border-width: 1px;
+ padding: 1px;
+ border-style: inset;
+ border-color: gray;
+ background-color: white;
+ }
+ table.release td {
+ border-width: 1px;
+ padding: 1px;
+ border-style: inset;
+ border-color: gray;
+ background-color: white;
+ }
+ </style>
+STYLESHEET
+ print RELNOTE " <body>\n";
+
+ print RELNOTE "<h1>Level: $level</h1>\n";
+ print RELNOTE "<h2>Included commits:</h2>\n";
+ print RELNOTE "<table class='release'>\n";
+ print RELNOTE " <tr>\n";
+ print RELNOTE " <th>RTC/CQ Number(s)</th>\n";
+ print RELNOTE " <th>Subject</th>\n";
+ print RELNOTE " <th>Git Commit</th>\n";
+ print RELNOTE " </tr>\n";
+
+
+ foreach my $commit (@{$commits})
+ {
+ my $subject = git_get_subject($commit);
+ my $rtc = rtc_workitem_num($commit);
+ my $rtc_hyper = "";
+ my $cq = cq_workitem_num($commit);
+ my $cq_hyper = "";
+
+ if ($rtc ne "")
+ {
+ $rtc_hyper = rtc_hyperlink($rtc);
+ $rtc_hyper = "<a href='$rtc_hyper' target='_blank'>$rtc</a>";
+ }
+ if ($cq ne "")
+ {
+ $cq_hyper = cq_hyperlink($cq);
+ $cq_hyper = "<a href='$cq_hyper' target='_blank'>$cq</a>";
+
+ if ($rtc_hyper ne "")
+ {
+ $cq_hyper = "<br>$cq_hyper";
+ }
+ }
+
+ print RELNOTE " <tr>\n";
+ print RELNOTE " <td>$rtc_hyper $cq_hyper</td>\n";
+ print RELNOTE " <td>$subject</td>\n";
+ print RELNOTE " <td>$commit</td>\n";
+ print RELNOTE " </tr>\n";
+ }
+ print RELNOTE "</table>\n";
+
+ print RELNOTE " </body>\n";
+ print RELNOTE "</html>\n";
+
+ close RELNOTE;
+
+ system "git add ".git_root()."/releaseNotes.html";
+ system "git commit -m \"Release notes for $level\"";
+
+}
+
+# sub git_resolve_ref
+#
+# Transforms a symbolic git reference into a commit number.
+#
+# @param [in] ref - The reference to resolve.
+#
+# @return string - Resolved git commit number.
+#
+sub git_resolve_ref
+{
+ my $ref = shift;
+ my $resolve = "";
+
+ if (gerrit_is_patch($ref))
+ {
+ my $gerrit = gerrit_resolve_patches([$ref]);
+ $resolve = @{$gerrit}[0];
+ }
+ else
+ {
+ open COMMAND, "git log -n1 --pretty=\"%H\" $ref |";
+ $resolve = <COMMAND>;
+ close COMMAND;
+ chomp $resolve;
+ }
+
+ die "Unable to resolve ref $ref" if ($resolve eq "");
+ print "Resolved $ref as $resolve\n" if $debug;
+
+ return $resolve;
+}
+
+# sub git_root
+#
+# Determines the path of the root of the git repository.
+#
+# @return string - Root of the git repository.
+sub git_root
+{
+ return $globals{git_root} if (defined $globals{git_root});
+
+ open COMMAND, "git rev-parse --show-toplevel |";
+ my $root = <COMMAND>;
+ close COMMAND;
+ chomp $root;
+
+ die "Unable to determine git_root" if ($root eq "");
+ print "Found git_root at $root\n" if $debug;
+
+ $globals{git_root} = $root;
+ return $root;
+}
+
+# sub git_commit_history
+#
+# Determines all the commits between two points in git history.
+#
+# @param[in] start - Beginning commit.
+# @param[in, optional] not_including - Starting point to exclude.
+#
+# @return array - Commit history.
+#
+sub git_commit_history
+{
+ my $start = shift;
+ my $not_including = shift;
+
+ my @commits = ();
+
+ unless ($not_including eq "") { $not_including = "^".$not_including; }
+
+ open COMMAND, "git rev-list --cherry-pick $start $not_including |";
+ while (my $line = <COMMAND>)
+ {
+ chomp $line;
+ push @commits, $line;
+ }
+ close COMMAND;
+
+ return \@commits;
+}
+
+# sub git_log_changeId
+#
+# Determines if a changeId exists in the base
+#
+# @param[in] base
+# @param[in] changeId
+#
+# @return bool - True if in commit history, False otherwise.
+#
+sub git_log_changeId
+{
+ my $base = shift;
+ my $changeId = shift;
+ my $exists = 0;
+ open COMMAND, "git log $base | grep \'Change-Id: $changeId\' |";
+ if(<COMMAND> ne "")
+ {
+ $exists = 1;
+ }
+ close COMMAND;
+
+ return $exists;
+}
+
+# sub git_name_rev
+#
+# Transforms a git commit number to a symbolic name for human readability.
+#
+# @param[in] rev - Git revision (commit number) to name.
+# @return string - The symbolic name git uses for that commit number.
+#
+sub git_name_rev
+{
+ my $rev = shift;
+
+ open COMMAND, "git name-rev $rev |";
+ my $line = <COMMAND>; chomp $line;
+ close COMMAND;
+
+ return $line;
+}
+
+# sub git_commit_deps
+#
+# Determines a list of dependent commits based on common files touched.
+#
+# @param[in] base - The end point, in git history, of commits to compare.
+# @param[in] commit - The commit to find dependents of.
+#
+# @return array - List of dependent commits.
+#
+sub git_commit_deps
+{
+ my $base = shift;
+ my $commit = shift;
+ chomp($base);
+ chomp($commit);
+
+ my @deps = ();
+
+ print "Searching for deps for $commit against $base\n" if $debug;
+
+ my @files = split('\n',`git diff-tree --name-only --no-commit-id -r $commit`);
+ foreach my $file (@files)
+ {
+ # If a commit introduces a new file, don't run rev-list as it fails
+ # when the file does not exists in base.
+ my $file_in_base = `git log $base -n1 --oneline -- $file`;
+ next if ($file_in_base eq "");
+
+ my $dep_commit = `git rev-list $commit~1 ^$base $file`;
+ if ($dep_commit ne "")
+ {
+ print "Found dep: $dep_commit" if $debug;
+
+ chomp $dep_commit;
+ push @deps, $dep_commit;
+ }
+ }
+
+ return \@deps;
+}
+
+# sub git_commit_files
+#
+# Find the files touched by a commit.
+#
+# @param[in] commit - The commit to examine.
+# @return array - List of files touched by the commit.
+#
+sub git_commit_files
+{
+ my $commit = shift;
+
+ my @files = ();
+ open COMMAND, "git diff-tree --name-only --no-commit-id -r $commit |";
+ while (my $line = <COMMAND>)
+ {
+ chomp $line;
+ push @files, $line;
+ }
+ close COMMAND;
+
+ return \@files;
+}
+
+# sub git_get_subject
+#
+# Get the subject of the commit message associated with a commit.
+# See git log --oneline.
+#
+# @param[in] commit - The commit to examine.
+# @return string - The subject of the commit.
+#
+sub git_get_subject
+{
+ my $commit = shift;
+
+ open COMMAND, "git log -n1 --pretty=\"%s\" $commit |";
+ my $subject = <COMMAND>; chomp($subject);
+ close COMMAND;
+
+ return $subject;
+}
+
+# sub git_commit_msg
+#
+# Get the entire commit message associated with a commit.
+#
+# @param[in] commit - The commit to examine.
+# @return string - The commit message.
+#
+sub git_commit_msg
+{
+ my $commit = shift;
+
+ open COMMAND, "git log -n1 --pretty=%B $commit |";
+ my $message = "";
+ while (my $line = <COMMAND>)
+ {
+ $message = $message.$line;
+ }
+ close COMMAND;
+
+ return $message;
+}
+
+# sub git_create_branch
+#
+# Create a branch for a release-level.
+#
+# @param[in] level - The release-level to use as basis for the branch name.
+# @param[in] base - The commit to use as the base for the new branch.
+#
+sub git_create_branch
+{
+ my $level = shift;
+ my $base = shift;
+
+ system("git checkout -b __sbeRelease_$level $base");
+ die "Could not create branch for $level" if ($?);
+}
+
+# sub git_create_tag
+#
+# Create a tag for a release-level.
+#
+# @param[in] level - The release-level to create a tag for.
+# @param[in] level_info - The level-info associated with the level.
+#
+sub git_create_tag
+{
+ my $level = shift;
+ my $level_info = shift;
+
+ # Create an annotated tag, taking annotation from stdin.
+ open COMMAND, "| git tag -a $level -F -" || die;
+
+ # Add information about the level to the tag.
+ print COMMAND "Release: $level\n\n";
+ print COMMAND "Base: ".$level_info->{base}."\n";
+ print COMMAND "Previous-Release: ".$level_info->{released}."\n";
+ print COMMAND "Branch: ".$globals{"branch"}."\n";
+ print COMMAND "\n";
+ foreach my $patch (@{$level_info->{patches}})
+ {
+ print COMMAND "Patch: $patch\n";
+ }
+ my $forceDeps = $level_info->{forceDeps};
+ foreach my $from (keys %{$forceDeps})
+ {
+ print COMMAND "Forced-Dep: $from:".$forceDeps->{$from}."\n";
+ }
+
+ # Commit annotated tag.
+ close COMMAND;
+}
+
+# sub git_cherry_pick
+#
+# Cherry-pick a commit onto the current branch.
+#
+# @param[in] commit - The commit to cherry-pick.
+#
+# @retval false - Error occurred during cherry-pick.
+sub git_cherry_pick
+{
+ my $commit = shift;
+
+ system("git cherry-pick -x $commit");
+ return ($? == 0);
+}
+
+# sub git_order_commits
+#
+# Order a list of commits so that they are in a good order with regard to
+# dependencies. The order returned should be the most likely to not fail
+# a cherry-pick sequence.
+#
+# @param[in] patches - The list of commits to order.
+# @param[in] level_info - The level_info for the release-level being created.
+#
+# @return array - Re-ordered list of commits (from patches).
+#
+sub git_order_commits
+{
+ my $patches = shift;
+ my $level_info = shift;
+ my $forceDeps = $level_info->{forceDeps};
+ my %patch_dep = ();
+
+ # Create patch -> { distance -> 0, deps -> [] } hash.
+ my %patch_hash =
+ map { $_ => \{ distance => 0, deps => [] }} @{$patches};
+
+ # Determine dependencies and distance for each patch.
+ foreach my $patch (@{$patches})
+ {
+ # Add dependencies for each patch to the hash.
+ my $deps = git_commit_deps($level_info->{base}, $patch);
+ push @{${$patch_hash{$patch}}->{deps}}, @{$deps};
+
+ # Add dependencies to hash for circular depends check later
+ foreach my $dep (@{$deps})
+ {
+ $patch_dep{$patch}{$dep} = 1;
+ }
+
+ # Determine the distance from previous release for each patch.
+ ${$patch_hash{$patch}}->{distance} =
+ scalar @{git_commit_history($patch, $level_info->{released})};
+ }
+
+ # Determine forced dependencies for each patch.
+ foreach my $patch (keys %{$forceDeps})
+ {
+ my $resolve_from = @{gerrit_resolve_patches([$patch])}[0];
+ my $resolve_to =
+ @{gerrit_resolve_patches([$forceDeps->{$patch}])}[0];
+
+ print "Force dep: $resolve_from : $resolve_to\n" if ($debug);
+
+ push @{${$patch_hash{$resolve_from}}->{deps}}, $resolve_to;
+ # Add dependencies to hash for circular depends check later
+ $patch_dep{$resolve_from}{$resolve_to} = 1;
+ }
+
+ # Calculate Dijkstra's on the patches.
+ my $changed = 1;
+ while ($changed != 0)
+ {
+ $changed = 0;
+ foreach my $patch (@{$patches})
+ {
+ my $distance = 1 + max( map
+ {
+ # If patches have a circular dependency, ignore distance check.
+ next if ($patch_dep{$_}{$patch} && $patch_dep{$patch}{$_});
+ ${$patch_hash{$_}}->{distance}
+ }
+ @{${$patch_hash{$patch}}->{deps}});
+ if ($distance > ${$patch_hash{$patch}}->{distance})
+ {
+ $changed = 1;
+ ${$patch_hash{$patch}}->{distance} = $distance;
+ }
+ }
+ }
+
+ # Sort the patches based on shortest distance from previous release
+ # (after Dijkstra).
+ my @commit_order =
+ sort { ${$patch_hash{$a}}->{distance} <=>
+ ${$patch_hash{$b}}->{distance} }
+ @{$patches};
+
+ return \@commit_order;
+}
+
+# sub config_filename
+#
+# @return The location of the gitRelease config file.
+#
+sub config_filename
+{
+ return git_root()."/.git/gitRelease.config";
+}
+
+# sub config_init
+#
+# Ensures the gitRelease tool is initialized properly.
+#
+sub config_init
+{
+ return if (defined $globals{config_init});
+
+ unless (-e config_filename())
+ {
+ open COMMAND, "git config --list | grep remote.*ssh |";
+ my $url = <COMMAND>;
+ close COMMAND;
+ chomp $url;
+
+ die "Undefined git-remote 'gerrit'" if ($url eq "");
+
+ die "Unexpected url found: $url" if (not ($url =~ m/ssh:\/\/.*\/.*/));
+
+ my $server = $url;
+ my $project = $url;
+
+ # match first occurance of '/' after ssh://
+ # eg: remote.hostboot.url=ssh://hostboot.gerrit/hostboot
+ # $2 is 'hostboot.gerrit'
+ $server =~ s/(.*)ssh:\/\/(.*?)\/(.*)/$2/;
+ # eg: remote.ppe.url=ssh://hw.gerrit/hw/ppe
+ # $3 is 'hw/ppe'
+ $project =~ s/(.*)ssh:\/\/(.*?)\/(.*)/$3/;
+
+ print "Gerrit Server: ".$server."\n" if $debug;
+ print "Gerrit Project: ".$project."\n" if $debug;
+
+ open(UNUSED, ">".config_filename()) || die;
+ close UNUSED;
+
+ system("git config --file ".config_filename().
+ " --add releaseLevels.server $server");
+ system("git config --file ".config_filename().
+ " --add releaseLevels.project $project");
+ }
+ $globals{config_init} = 1;
+
+}
+
+# sub config_list_levels
+#
+# Determines the previously defined release-levels.
+#
+# @return hash - { level => 1 } for each defined level.
+#
+sub config_list_levels
+{
+ return $globals{config_list_levels}
+ if (defined $globals{config_list_levels});
+
+ config_init();
+
+ open COMMAND, "git config --file ".config_filename().
+ " --get-all releaseLevels.levelname |";
+ my $names = {};
+ while (my $line = <COMMAND>)
+ {
+ chomp $line;
+ $names->{$line} = 1;
+ }
+ close COMMAND;
+
+ $globals{config_list_levels} = $names;
+ return $names;
+}
+
+# sub config_add_level
+#
+# Add a new level definition to the config file.
+#
+# @param level_def - A level info with the name/base/released for the new level.
+#
+sub config_add_level
+{
+ config_init();
+
+ my $level_def = shift;
+ my $levels = config_list_levels();
+
+ if (defined $levels->{$level_def->{name}})
+ {
+ die "Level ".$level_def->{name}." is already defined";
+ }
+
+ system("git config --file ".config_filename().
+ " --add releaseLevels.levelname ".$level_def->{name});
+
+ system("git config --file ".config_filename().
+ " --add level.".$level_def->{name}.".base ".$level_def->{base});
+
+ system("git config --file ".config_filename().
+ " --add level.".$level_def->{name}.".released ".
+ $level_def->{released});
+
+ if ($globals{"branch"} ne "master")
+ {
+ system("git config --file ".config_filename().
+ " --add level.".$level_def->{name}.".branch ".
+ $globals{"branch"});
+ }
+}
+
+# sub config_del_level
+#
+# Delete a level definition from the config file.
+#
+# @param level - The level name to delete.
+#
+sub config_del_level
+{
+ config_init();
+
+ my $level = shift;
+
+ system("git config --file ".config_filename().
+ " --unset releaseLevels.levelname ^".$level."\$");
+
+ system("git config --file ".config_filename().
+ " --remove-section level.".$level);
+}
+
+# sub config_add_patch
+#
+# Add a patch to a level definition.
+#
+# @param level - The level to add patch to.
+# @param patch - The patch to add.
+#
+sub config_add_patch
+{
+ my $level = shift;
+ my $patch = shift;
+
+ config_get_level($level);
+
+ unless (gerrit_is_patch($patch))
+ {
+ $patch = git_resolve_ref($patch);
+ }
+ die "Unknown patch requested" if ($patch eq "");
+
+ system("git config --file ".config_filename().
+ " --add level.$level.patch $patch");
+}
+
+# sub config_add_dep
+#
+# Add a forced dependency to a level definition.
+#
+# @param level - The level to add to.
+# @param from - The decendent patch.
+# @param to - THe ancestor patch.
+#
+sub config_add_dep
+{
+ my $level = shift;
+ my $from = shift;
+ my $to = shift;
+
+ config_get_level($level);
+
+ unless (gerrit_is_patch($from))
+ {
+ $from = git_resolve_ref($from);
+ }
+ die "Unknown patch requested for 'from' dep" if ($from eq "");
+
+ unless (gerrit_is_patch($to))
+ {
+ $to = git_resolve_ref($to);
+ }
+ die "Unknown patch requested for 'to' dep" if ($to eq "");
+
+ system("git config --file ".config_filename().
+ " --add level.$level.forceDep $from:$to");
+}
+
+# sub config_get_level
+#
+# Reads a level's information from the config file.
+#
+# @param level - The level to read.
+#
+# @return hash - { name => level, base => base release,
+# released => previous release,
+# patches => array of patches,
+# forceDep => hash of { from => to } pairs }.
+#
+sub config_get_level
+{
+ config_init();
+
+ my $level = shift;
+ my %level_data = ();
+
+ open COMMAND, "git config --file ".config_filename().
+ " --get releaseLevels.levelname $level |";
+ my $found_level = <COMMAND>; chomp($found_level);
+ close COMMAND;
+
+ die "Level $level not defined" if ($found_level eq "");
+
+ $level_data{name} = $level;
+
+ open COMMAND, "git config --file ".config_filename().
+ " --get level.$level.base |";
+ my $base = <COMMAND>; chomp($base);
+ close COMMAND;
+
+ $level_data{base} = $base;
+
+ open COMMAND, "git config --file ".config_filename().
+ " --get level.$level.released |";
+ my $released = <COMMAND>; chomp($released);
+ close COMMAND;
+
+ $level_data{released} = $released;
+
+ open COMMAND, "git config --file ".config_filename().
+ " --get level.$level.branch |";
+ my $branch = <COMMAND>; chomp($branch);
+ close COMMAND;
+
+ if ($branch ne "")
+ {
+ $globals{"branch"} = $branch;
+ }
+
+ my @patches = ();
+ open COMMAND, "git config --file ".config_filename().
+ " --get-all level.$level.patch |";
+ while (my $patch = <COMMAND>)
+ {
+ chomp($patch);
+ push @patches, $patch;
+ }
+ close COMMAND;
+
+ $level_data{patches} = \@patches;
+
+ my %forceDeps = ();
+ open COMMAND, "git config --file ".config_filename().
+ " --get-all level.$level.forceDep |";
+ while (my $forceDep = <COMMAND>)
+ {
+ $forceDep =~ m/(.*):(.*)/;
+ $forceDeps{$1} = $2;
+ }
+ close COMMAND;
+
+ $level_data{forceDeps} = \%forceDeps;
+
+ return \%level_data;
+}
+
+# sub config_print_levels
+#
+# Displays the name of each defined level.
+#
+sub config_print_levels
+{
+ my $levels = config_list_levels();
+ foreach my $level (sort keys %$levels)
+ {
+ print $level."\n";
+ }
+}
+
+# sub config_server
+#
+# Gets the Gerrit server name / address from the config file.
+#
+# @return string - The location of the Gerrit server.
+#
+sub config_server
+{
+ return $globals{config_server} if (defined $globals{config_server});
+
+ config_init();
+
+ open COMMAND, "git config --file ".config_filename().
+ " --get releaseLevels.server |";
+ my $server = <COMMAND>; chomp($server);
+ close COMMAND;
+
+ die "Server config does not exist" if ($server eq "");
+
+ $globals{config_server} = $server;
+ return $server;
+
+}
+
+# sub config_project
+#
+# Gets the Gerrit project managed by this repository from the config file.
+#
+# @return string - Project managed by this repository.
+#
+sub config_project
+{
+ return $globals{config_project} if (defined $globals{config_project});
+
+ config_init();
+
+ open COMMAND, "git config --file ".config_filename().
+ " --get releaseLevels.project |";
+ my $project = <COMMAND>; chomp($project);
+ close COMMAND;
+
+ die "Project config does not exist" if ($project eq "");
+
+ $globals{config_project} = $project;
+ return $project;
+}
+
+# sub config_resolve_level_dep
+#
+# Resolves dependencies for patches by parsing the commit messages for the
+# depends-on tag and checking if there are any open parents of a commit.
+# If a patch is dependent on a patch not already in the level, the patch is
+# added.
+#
+# @param[in] - level name
+# @param[in] - Array of patches to process.
+#
+# @TODO RTC:125235 - improve this to support cross project dependencies
+sub config_resolve_level_dep
+{
+ print "Resolving level dependencies...\n";
+ my $level = shift;
+ my $base = shift;
+ my @patches = @_;
+ my %level_patches = ();
+
+ while (@patches)
+ {
+ my $patchPair = shift @patches;
+ my ($patch,$patchSet) = split (":", $patchPair);
+
+ # Check if patch has already been added to level
+ if ($level_patches{$patch})
+ {
+ print "Skipping - already added patch = $patch to level\n" if $debug;
+ next;
+ }
+ # Check if patch already exists in release base
+ if (git_log_changeId($base, $patch))
+ {
+ print "Skipping - patch = $patch already exists in release base = $base\n" if $debug;
+ next;
+ }
+
+ # Mark patch as processed
+ $level_patches{$patch} = 1;
+
+ print "\n===========\nFirst time seeing patch = $patch\n" if $debug;
+
+ # Force use of changeId's
+ if (!gerrit_is_patch($patch))
+ {
+ die "Added patch: $patch is not of type changeId\n";
+ }
+
+ # Add patch to level with resolved git commit.
+ print "Adding patch - $patchPair\n" if $debug;
+ my $commits = gerrit_resolve_patchset([$patchPair]);
+ config_add_patch($level, $commits->[0]);
+
+ # Get commit message
+ my $patchInfo = gerrit_query_commit($patch);
+ my @commitMsgArray = split(/\\n/,$patchInfo->{commitMessage});
+ print Dumper @commitMsgArray if $debug;
+
+ # Check for OPEN parent
+ my $commit_info = gerrit_query_commit($patch);
+ my $parent_commit = $commit_info->{currentPatchSet}->{parents}[0];
+ my $parent_info = gerrit_query_commit($parent_commit);
+ if ($parent_info->{status} eq "NEW")
+ {
+ my $parent_id = $parent_info->{id};
+ # Add dependency if dependency is not already in base release
+ if(!git_log_changeId($base, $parent_id))
+ {
+ print "Adding forced dependency $patch:$parent_id\n" if $debug;
+ config_add_dep($level, $patch, $parent_id);
+ }
+
+ # Add dependent patch if not already added to level
+ if (!exists($level_patches{$parent_id}) )
+ {
+ push @patches, $parent_id;
+ }
+ }
+
+ # Search commit message for dependencies
+ foreach my $line (@commitMsgArray)
+ {
+ # Check for forced dependencies
+ if ($line =~ m/depends-on:/i)
+ {
+ $line =~ s/([^:]*):\s*//;
+ chomp($line);
+ print "Found depends-on: $line\n" if $debug;
+
+ # Add dependency if dependency is not already in base release
+ if(!git_log_changeId($base, $line))
+ {
+ print "Adding forced dependency $patch:$line\n" if $debug;
+ config_add_dep($level, $patch, $line);
+ }
+
+ # Add dependent patch if not already added to level
+ if (!exists($level_patches{$line}) )
+ {
+ push @patches, $line;
+ }
+ }
+ # Print out CMVC dependencies
+ if ($line =~ m/cmvc-([a-zA-Z]+):/i)
+ {
+ print "$TOKEN Need ".$line."\n";
+ }
+ }
+ }
+}
+
+# sub config_verify_patches
+#
+# Verify patch-list to ensure all dependencies are met
+#
+# @param[in] - level base patch
+# @param[in] - Array of patches to verify.
+#
+sub config_verify_patches
+{
+ print "Verifying patches...\n";
+
+ config_init();
+
+ my $base = shift;
+ my $patches = shift;
+
+ foreach my $patch (@{$patches})
+ {
+ print "Deps for $patch\n" if $debug;
+ my $displayed_header = 0;
+
+ my $deps = git_commit_deps($base, $patch);
+
+ foreach my $dep (@{$deps})
+ {
+ unless (grep {$_ eq $dep} @{$patches})
+ {
+ unless ($displayed_header)
+ {
+ print "-------------------------------------------------\n";
+ print "Potential missing dependency for:\n";
+ print wrap(" "," ",git_get_subject($patch)."\n");
+ print "\t$patch\n\n";
+ $displayed_header = 1;
+ }
+
+ print wrap(" ", " ", git_get_subject($dep)."\n");
+ print "\t$dep\n";
+
+ my $files = array_intersect(git_commit_files($patch),
+ git_commit_files($dep));
+
+ foreach my $file (@{$files})
+ {
+ print "\t$file\n";
+ }
+
+ print "\n";
+ }
+ }
+
+ if ($displayed_header)
+ {
+ print "-------------------------------------------------\n";
+ }
+ }
+
+}
+
+# sub config_release
+#
+# Create a branch / tag based on the definition of a release.
+#
+# @param[in] - level info
+# @param[in] - bool to create tag
+#
+sub config_release
+{
+ my $level_info = shift;
+ my $create_tag = shift;
+
+ print "Creating release branch...\n";
+ git_create_branch($level_info->{name}, $level_info->{base});
+
+ my $patches = $level_info->{patches};
+
+ print "Resolving and ordering patches...\n";
+ print Dumper $level_info->{patches} if $debug;
+ $patches = gerrit_resolve_patches($level_info->{patches});
+ $patches = git_order_commits($patches, $level_info);
+
+ print "\n========\nDetermined patch order as:\n";
+ my $i = 1;
+ foreach my $patch (@{$patches})
+ {
+ print "$i. $patch\n";
+ $i++;
+ }
+
+ print "\n========\nApplying patches...\n";
+ $i = 1;
+ foreach my $patch (@{$patches})
+ {
+ print "\n$i. Cherry-picking commit = $patch.\n\n";
+ unless (git_cherry_pick($patch))
+ {
+ print `git status`;
+ system("git reset HEAD --hard");
+ die "Cherry-pick of $patch failed";
+ }
+ $i++;
+ }
+
+ print "\nGenerating release notes...\n";
+ create_release_notes($level_info->{name}, $level_info);
+
+ if ($create_tag)
+ {
+ print "\nCreating tag...\n";
+ git_create_tag($level_info->{name}, $level_info);
+ }
+}
+
+# sub gerrit_ssh_command
+#
+# Creates a properly formed ssh command based on the server address.
+#
+# @return string - The basic ssh command to connect to the server.
+#
+sub gerrit_ssh_command
+{
+ return $globals{gerrit_ssh_command}
+ if (defined $globals{gerrit_ssh_command});
+
+ my $server = config_server();
+ my $port = "";
+
+ if ($server =~ m/.*:.*/)
+ {
+ $port = $server;
+ $server =~ s/(.*):.*/$1/;
+ $port =~ s/.*:(.*)/$1/;
+
+ $port = "-p $port";
+ }
+
+ my $command = "ssh -qx $port $server gerrit";
+ print "SSH command: $command\n" if $debug;
+
+ $globals{gerrit_ssh_command} = $command;
+ return $command;
+}
+
+# sub gerrit_query
+#
+# Performs a gerrit query and parses the resulting JSON.
+#
+# @param[in] query - The query to perform.
+#
+# @return array - A list of items from the JSON query. Each item is a
+# hash (key-value pair) for the item attributes.
+#
+sub gerrit_query
+{
+ my $query = shift;
+
+ my @items = ();
+
+ open COMMAND, gerrit_ssh_command()." query $query --current-patch-set".
+ " --patch-sets --format=JSON |";
+
+ while (my $line = <COMMAND>)
+ {
+ chomp $line;
+ push @items, json_parse($line);
+ }
+
+ return \@items;
+}
+
+# sub gerrit_query_commit
+#
+# Performs a gerrit query on a specific commit.
+#
+# @param[in] commit - The commit to query.
+#
+# @return hash - The parsed JSON for the queried commit.
+#
+sub gerrit_query_commit
+{
+ my $commit = shift;
+
+ my $project = config_project();
+
+ my $query_result = gerrit_query("$commit project:$project ".
+ "branch:".$globals{"branch"});
+ foreach my $result (@{$query_result})
+ {
+ if ($result->{id} eq $commit ||
+ $result->{currentPatchSet}->{revision} =~ m/$commit/)
+ {
+ return $result;
+ }
+ else
+ {
+ # If all patchsets queried, search all of them for the commit
+ foreach my $patchset (@{$result->{patchSets}})
+ {
+ if ($patchset->{revision} =~ m/$commit/)
+ {
+ return $result;
+ }
+ }
+ }
+ }
+
+ die "Cannot find $commit in $project/$globals{\"branch\"}";
+}
+
+# sub gerrit_is_patch
+#
+# Determines if a patch identifier is a Gerrit patch or not.
+#
+# @param[in] patch - The patch to make determination about.
+#
+# @retval true - Patch is a Gerrit patch ID.
+# @retval false - Patch does not appear to be a Gerrit patch ID.
+sub gerrit_is_patch
+{
+ my $patch = shift;
+ return 1 if ($patch =~ m/I[0-9a-f]+/);
+ return 0;
+}
+
+# sub gerrit_resolve_patches
+#
+# Resolves gerrit patch IDs to git commit numbers and ensures the git
+# commits are fetched from the gerrit server.
+#
+# Any git commit number is left unchanged.
+#
+# @param[in] patches - An array of patches.
+# @return array - An array of git commit numbers.
+#
+sub gerrit_resolve_patches
+{
+ my $patches = shift;
+ my @result = ();
+
+ foreach my $patch (@{$patches})
+ {
+ if (gerrit_is_patch($patch))
+ {
+ my $patch_info = gerrit_query_commit($patch);
+ gerrit_fetch($patch_info->{currentPatchSet}->{ref});
+ push @result, $patch_info->{currentPatchSet}->{revision};
+ }
+ else
+ {
+ push @result, $patch;
+ }
+ }
+
+ return \@result;
+}
+
+# sub gerrit_resolve_patchset
+#
+# Resolves an array of gerrit change-id and patch-set pairs to git commit
+# numbers and and ensures the git commits are fetched from the gerrit server.
+#
+# @param[in] patches - An array of change-id, patch-set pairs.
+# @return array - An array of git commit numbers.
+#
+sub gerrit_resolve_patchset
+{
+ my $patches = shift;
+
+ my @result = ();
+ foreach my $patchPair (@{$patches})
+ {
+ my ($changeId,$patchSet) = split(":",$patchPair);
+
+ if (gerrit_is_patch($changeId))
+ {
+ my $patch_info = gerrit_query_commit($changeId);
+ # Fail if patchset DNE
+ if ($patchSet > $patch_info->{currentPatchSet}->{number})
+ {
+ die "$patchSet does not have patch number $patchSet";
+ }
+ # JSON creates array of patchSets in number order
+ my $index = $patchSet - 1;
+ gerrit_fetch($patch_info->{patchSets}[$index]->{ref});
+ push @result, $patch_info->{patchSets}[$index]->{revision};
+ }
+ else
+ {
+ die "Requires gerrit change-id and patch-set";
+ }
+ }
+
+ return \@result;
+}
+
+# sub gerrit_fetch
+#
+# Fetches the contents of a Gerrit revision (refs/changes/*) to the local
+# git repository.
+#
+# @param[in] ref - The revision to fetch from the Gerrit server.
+#
+sub gerrit_fetch
+{
+ my $ref = shift;
+ open COMMAND, "git config --list | grep remote.*ssh |";
+ my $projecturl = <COMMAND>;
+ close COMMAND;
+ chomp $projecturl;
+ $projecturl =~ s/(.*?)\=(.*)/$2/;
+ system("git fetch $projecturl $ref -q");
+}
+
+# sub rtc_workitem_num
+#
+# Determines the RTC WorkItem associated with a git commit.
+#
+# @param[in] commit - The git commit.
+#
+# @return string - RTC WorkItem number (or "").
+#
+sub rtc_workitem_num
+{
+ my $commit = shift;
+ my $message = git_commit_msg($commit);
+
+ if ($message =~ m/RTC:\s*([0-9]+)/)
+ {
+ return $1;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+# sub cq_workitem_num
+#
+# Determine the CQ WorkItem associated with a git commit.
+#
+# @param[in] commit - The git commit.
+#
+# @return string - CQ WorkItem number (or "").
+#
+sub cq_workitem_num
+{
+ my $commit = shift;
+ my $message = git_commit_msg($commit);
+
+ if ($message =~ m/CQ:\s*([A-Z][A-Z][0-9]+)/)
+ {
+ return $1;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+# sub coreq_workitem_num
+#
+# Search through a git commit for all coReq instances.
+#
+# @param[in] commit - The git commit.
+#
+# @return array of strings - CMVC-Coreq numbers or "".
+#
+
+sub coreq_workitem_num
+{
+ my $commit = shift;
+
+ my @msg_lines = split('\n',git_commit_msg($commit));
+ my @coreqs = ();
+
+ foreach my $line (@msg_lines)
+ {
+ if ($line =~ m/CMVC-Coreq:\s*([0-9]+)/i)
+ {
+ push @coreqs, $1;
+ }
+ }
+ return @coreqs;
+}
+
+# sub prereq_workitem_num
+#
+# Search through a git commit for all preReq instances.
+#
+# @param[in] commit - The git commit.
+#
+# @return array of strings - CMVC-Prereq numbers or "".
+#
+
+sub prereq_workitem_num
+{
+ my $commit = shift;
+
+ my @msg_lines = split('\n',git_commit_msg($commit));
+ my @prereqs = ();
+
+ foreach my $line (@msg_lines)
+ {
+ if($line =~ m/CMVC-Prereq:\s*([0-9]+)/i)
+ {
+ push @prereqs, $1;
+ }
+ }
+ return @prereqs;
+}
+
+# sub gerrit_changeid_num
+#
+# Determine the Gerrit Change-Id associated with a git commit.
+#
+# @param[in] commit - The git commit.
+#
+# @return string - Gerrit Change-Id number (or "").
+#
+sub gerrit_changeid_num
+{
+ my $commit = shift;
+ my $message = git_commit_msg($commit);
+
+ if ($message =~ m/Change-Id:\s*(I[0-9a-z]+)/)
+ {
+ return $1;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+
+# sub rtc_hyperlink
+#
+# Turn an RTC WorkItem number into the https:// address to the RTC server.
+#
+# @param[in] workitem - RTC workitem number.
+#
+# @return string - The https:// address of the RTC item on the server.
+#
+sub rtc_hyperlink
+{
+ my $workitem = shift;
+ return "https://jazz07.rchland.ibm.com:13443/jazz/oslc/workitems/".
+ "$workitem.hover.html";
+}
+
+# sub cq_hyperlink
+#
+# Turn a CQ WorkItem number into the http:// address to the BQ server.
+#
+# @param[in] workitem - CQ workitem number.
+#
+# @return string - The http:// address of the CQ item on the server.
+#
+sub cq_hyperlink
+{
+ my $workitem = shift;
+ return "http://w3.rchland.ibm.com/projects/bestquest/?defect=$workitem";
+}
+
+# sub json_parse
+#
+# Parse a line of JSON into an hash-object.
+#
+# @param[in] line - The JSON content.
+#
+# @return hash - The parsed object.
+#
+# @note There are perl modules for doing this but they are not installed on
+# the pool machines. The parsing for JSON (at least the content from
+# the Gerrit server) isn't so bad...
+#
+sub json_parse
+{
+ my $line = shift;
+
+ die "Invalid JSON format: $line" unless ($line =~ m/^\{.*\}$/);
+ $line =~ s/^\{(.*)}$/$1/;
+
+ my %object = ();
+
+ while($line ne "")
+ {
+ my $key;
+ my $value;
+
+ ($key, $line) = json_get_string($line);
+ $key =~ s/^"(.*)"$/$1/;
+
+ $line =~ s/^://;
+ if ($line =~ m/^"/)
+ {
+ ($value, $line) = json_get_string($line);
+ $value =~ s/^"(.*)"$/$1/;
+ }
+ elsif ($line =~ m/^{/)
+ {
+ ($value, $line) = json_get_object($line);
+ $value = json_parse($value);
+ }
+ elsif ($line =~ m/^\[/)
+ {
+ ($value, $line) = json_get_array($line);
+ $value = json_parse_array($value);
+ }
+ else
+ {
+ $line =~ s/([^,]*)//;
+ $value = $1;
+ }
+
+ $object{$key} = $value;
+ }
+
+ return \%object;
+}
+
+# sub json_parse_array
+#
+# Utility function for json_parse.
+#
+sub json_parse_array
+{
+ my $line = shift;
+
+ $line =~ s/^\[(.*)\]$/$1/;
+
+ my @array = ();
+
+ while ($line ne "")
+ {
+ my $value;
+
+ if ($line =~ m/^"/)
+ {
+ ($value, $line) = json_get_string($line);
+ $value =~ s/^"(.*)"$/$1/;
+ }
+ elsif ($line =~ m/^\{/)
+ {
+ ($value, $line) = json_get_object($line);
+ $value = json_parse($value);
+ }
+ elsif ($line =~ m/^\[/)
+ {
+ ($value, $line) = json_get_array($line);
+ $value = json_parse_array($value);
+ }
+ else
+ {
+ $line =~ s/([^,]*)//;
+ $value = $1;
+ }
+
+ push @array, $value;
+ $line =~ s/^,//;
+ }
+
+ return \@array;
+}
+
+# sub json_get_string
+#
+# Utility function for json_parse.
+#
+sub json_get_string
+{
+ my $line = shift;
+
+ $line =~ /("[^"]*")(.*)/;
+ my $first = $1;
+ my $second = $2;
+
+ if ($first =~ m/\\"$/)
+ {
+ my ($more, $rest) = json_get_string($second);
+ return ($first.$more , $rest);
+ }
+ else
+ {
+ return ($first, $second);
+ }
+}
+
+# sub json_get_object
+#
+# Utility function for json_parse.
+#
+sub json_get_object
+{
+ my $line = shift;
+
+ $line =~ s/^{//;
+ my $object = "{";
+ my $frag = "";
+
+ my $found_object = 0;
+
+ until ((not $found_object) && ($object =~ m/}$/))
+ {
+ $found_object = 0;
+
+ if ($line =~ m/^\{/)
+ {
+ ($frag, $line) = json_get_object($line);
+ $object = $object.$frag;
+ $found_object = 1;
+ }
+ elsif ($line =~ m/^"/)
+ {
+ ($frag, $line) = json_get_string($line);
+ $object = $object.$frag;
+ }
+ elsif ($line =~ m/^\[/)
+ {
+ ($frag, $line) = json_get_array($line);
+ $object = $object.$frag;
+ }
+ elsif ($line =~ m/^[:,}]/)
+ {
+ $line =~ s/^([:,}])//;
+ $frag = $1;
+ $object = $object.$frag;
+ }
+ else
+ {
+ $line =~ s/([^,}]*)//;
+ $frag = $1;
+ $object = $object.$frag;
+ }
+ }
+
+ return ($object, $line);
+}
+
+# sub json_get_array
+#
+# Utility function for json_parse.
+#
+sub json_get_array
+{
+ my $line = shift;
+
+ $line =~ s/^\[//;
+ my $array = "[";
+ my $frag = "";
+
+ my $found_array = 0;
+
+ until ((not $found_array) && ($array =~ m/]$/))
+ {
+ $found_array = 0;
+
+ if ($line =~ m/^\[/)
+ {
+ ($frag, $line) = json_get_array($line);
+ $array = $array.$frag;
+ $found_array;
+ }
+ elsif ($line =~ m/^\{/)
+ {
+ ($frag, $line) = json_get_object($line);
+ $array = $array.$frag;
+ }
+ elsif ($line =~ m/^"/)
+ {
+ ($frag, $line) = json_get_string($line);
+ $array = $array.$frag;
+ }
+ elsif ($line =~ m/^[:,\]]/)
+ {
+ $line =~ s/^([:,\]])//;
+ $frag = $1;
+ $array = $array.$frag;
+ }
+ else
+ {
+ $line =~ s/([^,]*)//;
+ $frag = $1;
+ $array = $array.$frag;
+ }
+ }
+
+ return ($array, $line);
+}
+
+# sub array_intersect
+#
+# Perform set intersection on two arrays.
+#
+# @param[in] one - The first array.
+# @param[in] two - The second array.
+#
+# @return array - The set intersection.
+#
+sub array_intersect
+{
+ my $one = shift;
+ my $two = shift;
+
+ my %set = {};
+
+ map { $set{$_}++ } (@{$one}, @{$two});
+
+ my @result = map { ($set{$_} > 1) ? $_ : () } (keys %set);
+
+ return \@result;
+}
+
+# sub run_system_command
+#
+# Execute a system command, handle printing command and debug info, and return
+# system output for caller processing
+#
+# E.g. Execute a CMVC line command and return the results.
+#
+# @param[in] cmd - system command to be executed.
+#
+# @return string - output returned from running system command.
+#
+sub run_system_command
+{
+ my $cmd = shift;
+
+ print "$cmd\n";
+ my $output = `$cmd`;
+ die "failed running system command $cmd - $?" if ($?);
+ print $output if $debug;
+
+ return $output;
+}
diff --git a/src/build/tools/perl.modules/gitUtil.pm b/src/build/tools/perl.modules/gitUtil.pm
new file mode 100644
index 00000000..561c15cd
--- /dev/null
+++ b/src/build/tools/perl.modules/gitUtil.pm
@@ -0,0 +1,592 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/perl.modules/gitUtil.pm $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+package gitUtil;
+
+use strict;
+
+my %globals = {};
+
+# Function : gitRoot
+#
+# @brief : Determine the root of the GIT repository
+#
+# @return root : Root of GIT repository
+#
+sub gitRoot
+{
+ return $globals{git_root} if (defined $globals{git_root});
+
+ open COMMAND, "git rev-parse --show-toplevel |";
+ my $root = <COMMAND>;
+ close COMMAND;
+ chomp $root;
+
+ die "Unable to determine git_root" if ($root eq "");
+
+ $globals{git_root} = $root;
+ return $root;
+}
+
+#################### Begin Gerrit JSON Utility Subroutines #####################
+
+# @note There are perl modules for doing this but they are not installed on
+# the pool machines. The parsing for JSON (at least the content from
+# the Gerrit server) isn't so bad...
+
+# Function : jsonParse
+#
+# @brief : Parse a line of JSON into an hash-object.
+#
+# @param[in] line : The JSON content.
+#
+# @return hash : The parsed object.
+#
+sub jsonParse
+{
+ my $line = shift;
+
+ die "Invalid JSON format: $line" unless ($line =~ m/^\{.*\}$/);
+ $line =~ s/^\{(.*)}$/$1/;
+
+ my %object = ();
+
+ while($line ne "")
+ {
+ my $key;
+ my $value;
+
+ ($key, $line) = jsonGetString($line);
+ $key =~ s/^"(.*)"$/$1/;
+
+ $line =~ s/^://;
+ if ($line =~ m/^"/)
+ {
+ ($value, $line) = jsonGetString($line);
+ $value =~ s/^"(.*)"$/$1/;
+ }
+ elsif ($line =~ m/^{/)
+ {
+ ($value, $line) = jsonGetObject($line);
+ $value = jsonParse($value);
+ }
+ elsif ($line =~ m/^\[/)
+ {
+ ($value, $line) = jsonGetArray($line);
+ $value = jsonParseArray($value);
+ }
+ else
+ {
+ $line =~ s/([^,]*)//;
+ $value = $1;
+ }
+
+ $object{$key} = $value;
+ }
+
+ return \%object;
+}
+
+# Function : jsonGetString
+#
+# @brief : Utility function for jsonParse that extracts
+# the string data in a given object
+#
+# @param[in] line : The JSON line containing the strings.
+#
+# @return strings : The parsed strings.
+#
+sub jsonGetString
+{
+ my $line = shift;
+
+ $line =~ /("[^"]*")(.*)/;
+ my $first = $1;
+ my $second = $2;
+
+ if ($first =~ m/\\"$/)
+ {
+ my ($more, $rest) = jsonGetString($second);
+ return ($first.$more , $rest);
+ }
+ else
+ {
+ return ($first, $second);
+ }
+}
+
+# Function : jsonGetObject
+#
+# @brief : Utility function for jsonParse that extracts
+# the nested JSON object data in a given object
+#
+# @param[in] line : The JSON line containing the object
+#
+# @return object : The nested object
+#
+sub jsonGetObject
+{
+ my $line = shift;
+
+ $line =~ s/^{//;
+ my $object = "{";
+ my $frag = "";
+
+ my $found_object = 0;
+
+ until ((not $found_object) && ($object =~ m/}$/))
+ {
+ $found_object = 0;
+
+ if ($line =~ m/^\{/)
+ {
+ ($frag, $line) = jsonGetObject($line);
+ $object = $object.$frag;
+ $found_object = 1;
+ }
+ elsif ($line =~ m/^"/)
+ {
+ ($frag, $line) = jsonGetString($line);
+ $object = $object.$frag;
+ }
+ elsif ($line =~ m/^\[/)
+ {
+ ($frag, $line) = jsonGetArray($line);
+ $object = $object.$frag;
+ }
+ elsif ($line =~ m/^[:,}]/)
+ {
+ $line =~ s/^([:,}])//;
+ $frag = $1;
+ $object = $object.$frag;
+ }
+ else
+ {
+ $line =~ s/([^,}]*)//;
+ $frag = $1;
+ $object = $object.$frag;
+ }
+ }
+
+ return ($object, $line);
+}
+
+# Function : jsonGetArray
+#
+# @brief : Utility function for jsonParse that extracts
+# the array in a given object
+#
+# @param[in] line : The JSON line containing the array
+#
+# @return array : The array object
+#
+sub jsonGetArray
+{
+ my $line = shift;
+
+ $line =~ s/^\[//;
+ my $array = "[";
+ my $frag = "";
+
+ my $found_array = 0;
+
+ until ((not $found_array) && ($array =~ m/]$/))
+ {
+ $found_array = 0;
+
+ if ($line =~ m/^\[/)
+ {
+ ($frag, $line) = jsonGetArray($line);
+ $array = $array.$frag;
+ $found_array;
+ }
+ elsif ($line =~ m/^\{/)
+ {
+ ($frag, $line) = jsonGetObject($line);
+ $array = $array.$frag;
+ }
+ elsif ($line =~ m/^"/)
+ {
+ ($frag, $line) = jsonGetString($line);
+ $array = $array.$frag;
+ }
+ elsif ($line =~ m/^[:,\]]/)
+ {
+ $line =~ s/^([:,\]])//;
+ $frag = $1;
+ $array = $array.$frag;
+ }
+ else
+ {
+ $line =~ s/([^,]*)//;
+ $frag = $1;
+ $array = $array.$frag;
+ }
+ }
+
+ return ($array, $line);
+}
+
+# Function : jsonParseArray
+#
+# @brief : Utility function for jsonParse that parses
+# the array object
+#
+# @param[in] line : The array
+#
+# @return array : The parsed array object
+#
+#
+sub jsonParseArray
+{
+ my $line = shift;
+
+ $line =~ s/^\[(.*)\]$/$1/;
+
+ my @array = ();
+
+ while ($line ne "")
+ {
+ my $value;
+
+ if ($line =~ m/^"/)
+ {
+ ($value, $line) = jsonGetString($line);
+ $value =~ s/^"(.*)"$/$1/;
+ }
+ elsif ($line =~ m/^\{/)
+ {
+ ($value, $line) = jsonGetObject($line);
+ $value = jsonParse($value);
+ }
+ elsif ($line =~ m/^\[/)
+ {
+ ($value, $line) = jsonGetArray($line);
+ $value = jsonParseArray($value);
+ }
+ else
+ {
+ $line =~ s/([^,]*)//;
+ $value = $1;
+ }
+
+ push @array, $value;
+ $line =~ s/^,//;
+ }
+
+ return \@array;
+}
+
+#################### End Gerrit JSON Utility Subroutines #######################
+
+# Function : gerritIsPatch
+#
+# @brief : Determine if patch identifier is a Gerrit patch or not.
+#
+# @param[in] i_patch : The patch to make determination about.
+#
+# @retval flag : true/false (patch is/not a valid ID)
+#
+sub gerritIsPatch
+{
+ my $patch = shift;
+ return 1 if ($patch =~ m/I[0-9a-f]+/);
+ return 0;
+}
+
+# Function : configFilename
+#
+# @brief : Create the file that stroes the GIT server details
+#
+# @return : Location of the config file
+#
+sub configFilename
+{
+ return gitRoot()."/.git/gitRelease.config";
+}
+
+# Function : configInit
+#
+# @brief : Fetch & write server details to the config file
+#
+sub configInit
+{
+ return if (defined $globals{configInit});
+
+ unless (-e configFilename())
+ {
+ open COMMAND, "git config --list | grep remote.*ssh |";
+ my $url = <COMMAND>;
+ close COMMAND;
+ chomp $url;
+
+ die "Undefined git-remote 'gerrit'" if ($url eq "");
+
+ die "Unexpected url found: $url" if (not ($url =~ m/ssh:\/\/.*\/.*/));
+
+ my $server = $url;
+ my $project = $url;
+
+ # match first occurance of '/' after ssh://
+ # eg: remote.gerrit.url=ssh://hw.gerrit/hw/ppe
+ # $2 is 'hw.gerrit'
+ # $3 is 'hw/ppe'
+ $server =~ s/(.*)ssh:\/\/(.*?)\/(.*)/$2/;
+ $project =~ s/(.*)ssh:\/\/(.*?)\/(.*)/$3/;
+
+ open(UNUSED, ">".configFilename()) || die;
+ close UNUSED;
+
+ system("git config --file ".configFilename().
+ " --add releaseLevels.server $server");
+ system("git config --file ".configFilename().
+ " --add releaseLevels.project $project");
+ }
+ $globals{configInit} = 1;
+}
+
+# Function : configProject
+#
+# @brief : Fetch the project name of the current configured repository
+#
+# @return : GIT project name
+#
+sub configProject
+{
+ return $globals{config_project} if (defined $globals{config_project});
+
+ configInit();
+
+ open COMMAND, "git config --file ".configFilename().
+ " --get releaseLevels.project |";
+ my $project = <COMMAND>; chomp($project);
+ close COMMAND;
+
+ die "Project config does not exist" if ($project eq "");
+
+ $globals{config_project} = $project;
+
+ return $project;
+}
+
+# Function : configServer
+#
+# @brief : Fetch the server name of the current configured repository
+#
+# @return : GIT server location
+#
+sub configServer
+{
+ return $globals{config_server} if (defined $globals{config_server});
+
+ configInit();
+
+
+ open COMMAND, "git config --file ".configFilename().
+ " --get releaseLevels.server |";
+ my $server = <COMMAND>; chomp($server);
+ close COMMAND;
+
+ die "Server config does not exist" if ($server eq "");
+
+ $globals{config_server} = $server;
+ return $server;
+
+}
+
+# Function : gerritSSHCommand
+#
+# @brief : Creates a properly formed ssh command based on the server address
+#
+# @return : The basic ssh command to connect to the server.
+#
+sub gerritSSHCommand
+{
+ return $globals{gerrit_ssh_command}
+ if (defined $globals{gerrit_ssh_command});
+
+ my $server = configServer();
+ my $port = "";
+
+ if ($server =~ m/.*:.*/)
+ {
+ $port = $server;
+ $server =~ s/(.*):.*/$1/;
+ $port =~ s/.*:(.*)/$1/;
+
+ $port = "-p $port";
+ }
+
+ my $command = "ssh -qx $port $server gerrit";
+
+ $globals{gerrit_ssh_command} = $command;
+ return $command;
+}
+
+# Function : gerritQuery
+#
+# @brief : Performs a gerrit query and parses the resulting JSON.
+#
+# @param[in] query : The query to perform.
+#
+# @return item : A list of items from the JSON query. Each item is a
+# hash (key-value pair) for the item attributes.
+#
+sub gerritQuery
+{
+ my $query = shift;
+ my @items = ();
+
+ $query = gerritSSHCommand()." query $query --current-patch-set --patch-sets --format=JSON |";
+
+ open COMMAND, $query;
+ while (my $line = <COMMAND>)
+ {
+ chomp $line;
+ push @items, jsonParse($line);
+ }
+
+ return \@items;
+}
+
+# Function : gerritQueryReference
+#
+# @brief : Retrieves reference for a patch id, patchset number
+#
+# @param[in] changeId : Change id of the patch
+# @param[in] patchNumber : Patch set number
+#
+# @return reference : The reference string
+#
+sub gerritQueryReference
+{
+ my $changeId = shift;
+ my $patchNumber = shift;
+
+ my $project = configProject();
+
+ my $query_result = gerritQuery("$changeId project:$project");
+
+ foreach my $result (@{$query_result})
+ {
+ if ($result->{id} eq $changeId)
+ {
+ # If all patchsets queried, search all of them for the commit
+ foreach my $patchset (@{$result->{patchSets}})
+ {
+ if ($patchNumber eq " ")
+ {
+ return $patchset->{currentPatchSet}->{ref};
+ }
+ else
+ {
+ if ($patchset->{number} =~ m/$patchNumber/)
+ {
+ return $patchset->{ref};
+ }
+ }
+ }
+ }
+ }
+ die "Cannot find $changeId in $project";
+}
+
+# Function : gerritQueryCommit
+#
+# @brief : Retrieves commit for a patch id, patchset number
+#
+# @param[in] changeId : Change id of the patch
+# @param[in] patchNumber : Patch set number
+#
+# @return commit : The commit string
+#
+sub gerritQueryCommit
+{
+ my $changeId = shift;
+ my $patchNumber = shift;
+
+ my $project = configProject();
+
+ my $query_result = gerritQuery("$changeId project:$project");
+
+ foreach my $result (@{$query_result})
+ {
+ if ($result->{id} eq $changeId)
+ {
+ # If all patchsets queried, search all of them for the commit
+ foreach my $patchset (@{$result->{patchSets}})
+ {
+ if ($patchNumber eq "")
+ {
+ return $patchset->{currentPatchSet}->{revision};
+ }
+ else
+ {
+ if ($patchset->{number} =~ m/$patchNumber/)
+ {
+ return $patchset->{revision};
+ }
+ }
+ }
+ }
+ }
+ die "Cannot find $changeId in $project";
+}
+
+# Function : patchMergeStatus
+#
+# @brief : Check if given patch is merged into repository
+#
+# @param[in] changeId : Change id of the patch
+#
+# @return mergeStatus : 1 if merged; else 0
+#
+sub patchMergeStatus
+{
+ my $mergeStatus = 1;
+
+ my $changeId = shift;
+
+ my $project = configProject();
+
+ my $query_result = gerritQuery("$changeId project:$project");
+
+ foreach my $result (@{$query_result})
+ {
+ if ($result->{id} eq $changeId)
+ {
+ if ($result->{status} eq "MERGED" || $result->{status} eq "merged")
+ {
+ $mergeStatus = 1;
+ }
+ else
+ {
+ $mergeStatus = 0;
+ }
+ return $mergeStatus;
+ }
+ }
+ die "Cannot find $changeId in $project";
+}
diff --git a/src/build/tools/sandbox-create b/src/build/tools/sandbox-create
new file mode 100755
index 00000000..2f634358
--- /dev/null
+++ b/src/build/tools/sandbox-create
@@ -0,0 +1,60 @@
+#!/bin/bash
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/sandbox-create $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+echo " Creating ODE sandbox..."
+
+# Ensure backing build is accessible.
+if [ ! -d "$BACKING_BUILD" ];
+then
+ echo " Cannot access the backing build: $BACKING_BUILD"
+ exit -1
+fi
+
+SANDBOXRC=${SANDBOXROOT}/sbesandboxrc;
+
+# Delete existing sandbox if it exists.
+if [ -d "$SANDBOXBASE" ];
+then
+ # prompt the user to delete the sanbox or not if exist
+ echo -ne " Remove existing sandbox? {y/n}:"
+ read input
+ if [ "$input" == "y" ];then
+ echo " Executing : mksb -undo -auto -rc $SANDBOXRC -dir $SANDBOXROOT -sb $SANDBOXNAME"
+ mksb -undo -auto -rc $SANDBOXRC -dir $SANDBOXROOT -sb $SANDBOXNAME
+ else
+ exit 0
+ fi
+fi
+
+if [ -d "$SANDBOXBASE" ];
+then
+ rm -rf $SANDBOXBASE
+ rm -f $SANDBOXRC
+fi
+
+# Create sandbox.
+echo " Sandbox backing build = $BACKING_BUILD"
+echo " mksb -rc $SANDBOXRC -dir $SANDBOXROOT -back $BACKING_BUILD -sb $SANDBOXNAME -m ppc -auto"
+mksb -rc $SANDBOXRC -dir $SANDBOXROOT -back $BACKING_BUILD -sb $SANDBOXNAME -m ppc -auto || exit -1
diff --git a/src/build/tools/sbeCmvcConstants.py b/src/build/tools/sbeCmvcConstants.py
new file mode 100755
index 00000000..65a2d8a3
--- /dev/null
+++ b/src/build/tools/sbeCmvcConstants.py
@@ -0,0 +1,84 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/sbeCmvcConstants.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 sbeCmvcConstants.py
+# @author George Keishing <gkeishin@in.ibm.com>
+# Sangeetha TS <sangeet2@in.ibm.com>
+# @brief Constants support tool operation
+#
+# Created on March 03, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 03/03/16 Initial create
+###########################################################
+'''
+
+
+'''
+Generic Failure RC code
+'''
+SUCCESS_EXIT = 0
+SHELL_EXIT = 1 # Shell Exited with error
+ERROR_EXIT = 2
+HELP_EXIT = 3
+SUCCESS_DEV_EXIT = 4
+ERROR_SYS_EXIT = 100
+
+
+# This funcs specific error codes
+ERROR_SETTING = 10 # No CMV ENV set in the .bashrc or a generic error for Sandbox ENV not set
+ERROR_CMVC_LOGIN = 11 # No Cmvc login access session not established
+ERROR_CMVC_CHECKOUT = 12 # Failed file checkout
+ERROR_CMVC_CHECKIN = 13 # Failed file check in
+ERROR_CMVC_FIX_RECORD = 14 # Failed fixing complete record
+ERROR_CMVC_FILE_COPY = 15 # Copying file failed
+ERROR_TRACK_STATE = 16 # Track not in required state
+ERROR_CI_TRIGGER = 17 # CI not started successfully
+
+SUCCESS_CMVC_CHECKOUT = 50
+SUCCESS_CMVC_CHECKIN = 51
+SUCCESS_CMVC_FIX_RECORD = 52
+SUCCESS_TRACK_STATE = 53
+SUCCESS_CI_TRIGGER = 54
+
+# This is a default files list to Check-in
+CMVC_FILE_LIST ="sbe_sp_intf.H,simics.tar,sbe_pibmem.bin,sbe_seeprom.bin"
+CMVC_FILE_UNDO_LIST ="src/sbei/sbfw/sbe_sp_intf.H src/sbei/sbfw/simics.tar src/sbei/sbfw/img/sbe_pibmem.bin src/sbei/sbfw/img/sbe_seeprom.bin"
+
+CMVC_DIR_CREATE ="sandbox_"
+
+
+# Hashing specfic
+SUCCESS_HASH_CHECK = 100
+ERROR_HASH_CHECK = 101
+
+
+# For Development
+ERROR_SANDBOX_EXIST = 200 # Sandbox doesnt exist
+ERROR_FILE_INPUT = 201 # User have entered no file
+ERROR_BUILD_FAILED = 202 # Compilation failed
+ERROR_HOOKING_FILE = 203 # Error while building shell hooks
+FILE_LOOKUP_LIST ="src/sbei/sbfw/sbe_sp_intf.H,src/sbei/sbfw/simics.tar,src/sbei/sbfw/img/sbe_pibmem.bin,src/sbei/sbfw/img/sbe_seeprom.bin"
diff --git a/src/build/tools/sbeCmvcUtility.py b/src/build/tools/sbeCmvcUtility.py
new file mode 100755
index 00000000..793029af
--- /dev/null
+++ b/src/build/tools/sbeCmvcUtility.py
@@ -0,0 +1,570 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/sbeCmvcUtility.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 sbeCmvcUtility.py
+# @author: George Keishing <gkeishin@in.ibm.com>
+# Sangeetha TS <sangeet2@in.ibm.com>
+# @brief Utilility Module to support CMVC operation
+#
+# Created on March 03, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 03/03/16 Initial create
+###########################################################
+'''
+
+#-------------------------
+# Imports
+#-------------------------
+import os, sys
+import time
+import os.path
+import subprocess
+import shutil
+import hashlib
+from subprocess import Popen, PIPE
+from os.path import expanduser # for getting $HOME PATH
+import stat # for File permission op
+
+# Libraries/utility funcs and user define const
+import sbeCmvcConstants as errorcode
+
+
+##########################################################################
+# Function : utilCmvcChangeDir
+#
+# @param i_cmvcnum : CMVC defect or Feature number
+#
+# @brief Create a directory
+#
+##########################################################################
+def utilCmvcChangeDir(i_cmvcnum):
+ l_home_path= expanduser("~") + "/" + errorcode.CMVC_DIR_CREATE + i_cmvcnum
+
+ print " Sandbox path\t: ",l_home_path
+ cmd='mkdir -p ' + l_home_path
+ os.system(cmd)
+ os.chdir(l_home_path)
+
+##########################################################################
+# Function :utilCmvcRepoPath
+#
+# @param i_cmvcnum : CMVC defect or Feature number
+#
+# @param i_pathname : SBE repo Path location
+#
+# @param i_filename : Files to be copied
+#
+# @brief find the files in repo
+#
+##########################################################################
+def utilCmvcRepoPath(i_pathname, i_cmvcnum, i_filename):
+ l_home_path= expanduser("~") + "/" + errorcode.CMVC_DIR_CREATE + i_cmvcnum
+ # Strip the last string from the file path input
+
+ print " Sandbox path\t: ",l_home_path
+ print " SBE Repo path\t: ",i_pathname
+
+ if i_filename == "None":
+ i_filename = errorcode.CMVC_FILE_LIST
+
+ for l_filename in i_filename.split(","):
+
+ # Find the files and copy
+ l_sb_path = utilFindFile(l_filename,l_home_path)
+ l_repo_path = utilFindFile(l_filename,i_pathname)
+
+ if l_sb_path is None :
+ print " ERROR: Checked out sandbox does not contain " + l_filename
+ return errorcode.ERROR_CMVC_FILE_COPY
+ if l_repo_path is None :
+ print " ERROR: File Not Found in SBE repo " + l_filename
+ return errorcode.ERROR_CMVC_FILE_COPY
+
+ cp_cmd = 'cp ' + l_repo_path + ' ' + l_sb_path
+ rc=os.system(cp_cmd )
+ if rc:
+ return errorcode.ERROR_CMVC_FILE_COPY
+ else:
+ # validate the copied files via hashing
+ l_src = l_repo_path
+ l_dest = l_sb_path
+ hash_err = utilCheckFileHash(l_src,l_dest)
+ if hash_err == errorcode.ERROR_HASH_CHECK:
+ return hash_err
+
+ # Returned success
+ return errorcode.SUCCESS_EXIT
+
+##########################################################################
+# Function :utilFindFile
+#
+# @param i_filename : File Name
+#
+# @param i_path : Directory to search in
+#
+# @brief Finds a given file and returns the absoulte path
+#
+##########################################################################
+def utilFindFile(i_filename, i_path):
+ for root, dirs, files in os.walk(i_path):
+ if i_filename in files:
+ return os.path.join(root, i_filename)
+
+##########################################################################
+# Function :utilFindFilePPE
+#
+# @param i_filename : File Name
+#
+# @param i_path : Directory to search in
+#
+# @brief Finds a given file ins PPE repo and returns the absoulte path
+#
+##########################################################################
+def utilFindFilePPE(i_filename, i_path, i_sandbox_name):
+ for root, dirs, files in os.walk(i_path):
+ if i_filename in files:
+ # Ignore the test sandbox files in the PPE
+ if not i_sandbox_name in root:
+ return os.path.join(root, i_filename)
+ # Consider the path, if the repository is contanied in the sandbox
+ else:
+ if i_sandbox_name in i_path:
+ return os.path.join(root, i_filename)
+
+##########################################################################
+# Function :utilCmvcCheckout
+#
+# @param i_filename : File Name
+#
+# @param i_release : Fips FW Release to checkout (ex: fips910 )
+#
+# @param i_cmvcnum : CMVC defect or Feature number
+#
+# @brief Check out a given file
+#
+##########################################################################
+def utilCmvcCheckout(i_filename, i_release, i_cmvcnum):
+ print " File Name\t: ",i_filename
+ print " Release\t: ",i_release
+
+ # The file simics.tar is not unique so provide the relative path
+ if i_filename == "simics.tar":
+ i_filename = 'src/sbei/sbfw/simics.tar'
+
+ print " CMVC #\t: ",i_cmvcnum[1:]
+ l_home_path= expanduser("~") + "/" + errorcode.CMVC_DIR_CREATE + i_cmvcnum
+
+ cmd='File -checkout ' + i_filename + ' -release '+ i_release + ' -relative ' + l_home_path
+ if i_cmvcnum[:1] == "D":
+ cmd += ' -defect ' + i_cmvcnum[1:]
+ else:
+ cmd += ' -feature ' + i_cmvcnum[1:]
+
+ print " Executing\t: ", cmd
+ rc = os.system(cmd)
+ if rc:
+ # rc 256 File not found in CMVC
+ if rc == 256:
+ print " * File was not found or Error operation in CMVC"
+ return errorcode.ERROR_CMVC_CHECKOUT
+ else:
+ return errorcode.SUCCESS_CMVC_CHECKOUT
+
+
+##########################################################################
+# Function :utilCmvcCheckin
+#
+# @param i_filename : Relative Path of the File
+#
+# @param i_release : Fips FW Release to checkout (ex: fips910 )
+#
+# @param i_cmvcnum : CMVC defect or Feature number
+#
+# @brief Check in a given file
+#
+##########################################################################
+def utilCmvcCheckin(i_filename, i_release, i_cmvcnum):
+ print " File Name\t: ",i_filename
+ print " Release\t: ",i_release
+ print " CMVC #\t: ",i_cmvcnum[1:]
+
+ l_home_path= expanduser("~") + "/" + errorcode.CMVC_DIR_CREATE + i_cmvcnum
+ l_base_path = utilFindFile(i_filename,l_home_path)
+ # This will give the ablsolute path, strip it from src
+ for l_var in l_base_path.split("/src"):
+ if i_filename in l_var:
+ l_str = 'src' + l_var
+
+ cmd='File -checkin ' + l_str + ' -release '+ i_release + ' -relative ' + l_home_path
+ if i_cmvcnum[:1] == "D":
+ cmd += ' -defect ' + i_cmvcnum[1:]
+ else:
+ cmd += ' -feature ' + i_cmvcnum[1:]
+
+ print " Executing\t: ", cmd
+ rc = os.system(cmd)
+ if rc:
+ return errorcode.ERROR_CMVC_CHECKIN
+ else:
+ return errorcode.SUCCESS_CMVC_CHECKIN
+
+
+##########################################################################
+# Function :utilCmvcFixComplete
+#
+# @param i_cmvcnum : CMVC defect or Feature number
+#
+# @param i_release : Fips Release string
+#
+# @brief Fix the record to complete
+#
+##########################################################################
+def utilCmvcFixComplete(i_cmvcnum, i_release):
+ print " CMVC #\t: ",i_cmvcnum
+ l_cmvcnum =i_cmvcnum[1:]
+
+ if i_cmvcnum[:1] == "D":
+ cmd='Fix -complete ' + ' -defect ' + l_cmvcnum + ' -r ' + i_release + ' -component esw_sbei'
+ else:
+ cmd='Fix -complete ' + ' -feature ' + l_cmvcnum + ' -r ' + i_release + ' -component esw_sbei'
+
+ print " Executing\t: ", cmd
+ rc = os.system(cmd)
+ if rc:
+ return errorcode.ERROR_CMVC_FIX_RECORD
+ else:
+ return errorcode.SUCCESS_CMVC_FIX_RECORD
+
+##########################################################################
+# Function :utilCheckTrackState
+#
+# @param i_cmvcnum : CMVC defect or Feature number
+#
+# @param i_release : Fips Release string
+#
+# @brief Check if the track is in fix state or not
+#
+##########################################################################
+def utilCheckTrackState(i_cmvcnum, i_release):
+ print " CMVC #\t: ",i_cmvcnum
+ print " Release\t: ",i_release
+
+ l_cmvcnum =i_cmvcnum[1:]
+ cmd = 'Track -view -release ' + i_release
+ if i_cmvcnum[:1] == "D":
+ cmd += ' -defect ' + l_cmvcnum
+ else:
+ cmd += ' -feature ' + l_cmvcnum
+ cmd += ' | grep state '
+
+ print " Executing\t: ", cmd
+ ex_cmd = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
+ for line in ex_cmd.stdout :
+ if not line: continue
+ line = line.strip()
+ if "fix" in line :
+ return errorcode.SUCCESS_TRACK_STATE
+ return errorcode.ERROR_TRACK_STATE
+
+##########################################################################
+# Function :utilCheckFileHash
+#
+# @param i_src : Source location of the file to be copy from
+#
+# @param i_dest : Destination location of the file to be copied to
+#
+# @brief Make sure after copying files, the hash matches
+#
+##########################################################################
+def utilCheckFileHash(i_src, i_dest):
+ print " Source\t: ",i_src
+ print " Destination\t: ",i_dest
+
+ sha_orig = hashlib.sha256()
+ sha_orig.update(file(i_src).read())
+ orig_hash=sha_orig.hexdigest()
+ print " * Orig Hash\t [ %s : %s ] "% (os.path.basename(i_src),orig_hash)
+
+ sha_copy = hashlib.sha256()
+ sha_copy.update(file(i_dest).read())
+ copied_hash=sha_copy.hexdigest()
+ print " * Copied Hash\t [ %s : %s ] "% (os.path.basename(i_dest),copied_hash)
+
+ if orig_hash == copied_hash:
+ print " -> Hash Match .. Continue\n"
+ return errorcode.SUCCESS_HASH_CHECK
+ else:
+ print " Mismatch Hash.. Abort"
+ return errorcode.ERROR_HASH_CHECK
+
+##########################################################################
+# Function :utilRollBack
+#
+# @param i_action : Undo Checkout or checkin
+#
+# @param i_cmvcnum : CMVC defect or Feature number
+#
+# @param i_release : Fips FW Release to checkout (ex: fips910 )
+#
+# @brief Brute force undo of all files
+#
+##########################################################################
+def utilRollBack(i_action, i_cmvcnum, i_release):
+ print "\n * Action request\t: ",i_action
+ if i_action == "checkin":
+ print " * Undoing All default File list"
+ if i_cmvcnum[:1] == "D":
+ cmd = 'File -undo ' + errorcode.CMVC_FILE_UNDO_LIST + ' -release ' + i_release + ' -defect ' + i_cmvcnum[1:] + ' >/dev/null 2>&1'
+ else:
+ cmd = 'File -undo ' + errorcode.CMVC_FILE_UNDO_LIST + ' -release ' + i_release + ' -feature ' + i_cmvcnum[1:] + ' >/dev/null 2>&1'
+ else:
+ print " * Unlocking All default Files list"
+ if i_cmvcnum[:1] == "D":
+ cmd = 'File -unlock ' + errorcode.CMVC_FILE_UNDO_LIST + ' -release ' + i_release + ' >/dev/null 2>&1'
+ else:
+ cmd = 'File -unlock ' + errorcode.CMVC_FILE_UNDO_LIST + ' -release ' + i_release + ' >/dev/null 2>&1'
+
+ #print " Executing : ", cmd
+ rc = os.system(cmd)
+ # CMVC throws this rc even if its successfull
+ if rc != 1024 and rc !=0:
+ print "\n Error [ %s ] in Undoing/Unlocking Files.. Please check manually"%rc
+ else:
+ print "\n Roll Back Successfull.. Please Revisit your inputs [ OK ] "
+
+
+##########################################################################
+# Function :utilTriggerJenkins
+#
+# @param i_cmvcnum : CMVC defect or Feature number
+#
+# @param i_release : Fips FW Release to checkout (ex: fips910 )
+#
+# @param i_bvt : Fips BVT xml file
+#
+# @brief Trigger Jenkins CI job
+#
+##########################################################################
+def utilTriggerJenkins(i_cmvcnum,i_release,i_bvt):
+ print " Jenkins job for %s" % i_cmvcnum
+ #PATH : /afs/austin.ibm.com/projects/esw/bin/fsp-CI-jenkins
+ cmd = "fsp-CI-jenkins -r " + i_release + " -t " + i_cmvcnum[1:] + " --test_on_hardware=y"
+ if not i_bvt == "None" :
+ cmd += " -b " + i_bvt
+ rc = os.system(cmd)
+ if rc :
+ return errorcode.ERROR_CI_TRIGGER
+ else :
+ return errorcode.SUCCESS_CI_TRIGGER
+
+
+##########################################################################
+# Function :utilCopyFileToSandbox
+#
+# @param i_pathname : SBE repo Path location
+#
+# @param i_sandboxname : Sandbox repo Path location
+#
+# @param i_filename : Files to be copied
+#
+# @brief find the files in repo and copy to the sandbox
+#
+##########################################################################
+def utilCopyFileToSandbox(i_pathname,i_sandboxname,i_filename):
+
+ print "\n *** For Development *** \n"
+ print " Sandbox path\t: ",i_sandboxname
+ print " SBE Repo path\t: ",i_pathname
+ print "\n"
+
+ if i_filename == "None":
+ i_filename = errorcode.CMVC_FILE_LIST
+ #print " No User supplied Files to copy"
+ #return errorcode.ERROR_FILE_INPUT
+
+ for l_filename in i_filename.split(","):
+ # Find the files and copy
+ l_sandbox_name = os.path.basename(i_sandboxname)
+ l_repo_path = utilFindFilePPE(l_filename,i_pathname,l_sandbox_name)
+ if l_repo_path is None :
+ print " File [ %s ] not found in Repo..\t Check your repo and retry "%l_filename
+ return errorcode.ERROR_CMVC_FILE_COPY
+ else:
+ for files in errorcode.FILE_LOOKUP_LIST.split(","):
+ if l_filename in files:
+ break
+
+ # Append this src path and to the sanbox base and copy the file
+ sb_cp_path = i_sandboxname + '/' + files
+
+ # Check if this path exist in the sandbox , if not create and copy
+ if os.path.exists(sb_cp_path) == False:
+ cmd='mkdir -p ' + os.path.dirname(sb_cp_path)
+ #print " Creating dir %s "%cmd
+ os.system(cmd)
+
+ # Copy the file
+ copy_cmd = 'cp -rf ' + l_repo_path + ' ' + sb_cp_path
+ rc = os.system(copy_cmd)
+ if rc:
+ print " RC code :",rc
+ print " ERROR : Copying file : ",copy_cmd
+ return errorcode.ERROR_CMVC_FILE_COPY
+ else:
+ print " Copied file : ",copy_cmd
+
+ return errorcode.SUCCESS_DEV_EXIT
+
+
+##########################################################################
+# Function :utilppeSbENV
+#
+# @param i_env_key : ENV paramter
+#
+# @brief find the PPE Repo path from ENV and returns the path string
+#
+##########################################################################
+def utilppeSbENV(i_env_key):
+ #-----------------------------------------------------------
+ # SBEROOT=/gsa/ausgsa/projects/i/indiateam04/gkeishin/PPE_CHANGES
+ #-----------------------------------------------------------
+ l_found_ppe_conf = False
+ env_ppe_path="None"
+ for key in os.environ.keys():
+ if i_env_key in key:
+ #print "\t %s : %s" % (key,os.environ[key])
+ env_ppe_path = os.environ[key]
+ l_found_ppe_conf = True
+
+ if l_found_ppe_conf == False:
+ print " ---------------------------------------------------------"
+ print " | [ ERROR SETTING ] : The PPE Repository ENV is not set |"
+ print " | Please do ./sb workon to set/load the PPE repo ENV |"
+ print " ---------------------------------------------------------"
+
+ return env_ppe_path
+
+##########################################################################
+# Function : utilFind_sb_base
+#
+# @param i_sb_name : Sandbox name
+#
+# @brief find the sandbox base path
+#
+##########################################################################
+def utilFind_sb_base(i_sb_name):
+ out_str= "None"
+
+ # workon -m ppc sbeisb -c 'env | grep SANDBOXBASE'
+ find_sb_base = 'workon -m ppc ' + i_sb_name + " -c 'env | grep SANDBOXBASE ' | grep SANDBOXBASE"
+
+ # SANDBOXBASE=/gsa/ausgsa/projects/i/indiateam04/gkeishin/sbeisb
+ out_str = os.popen(find_sb_base).read()
+
+ if not out_str:
+ return "None"
+ else:
+ return out_str.strip('SANDBOXBASE=')
+
+##########################################################################
+# Function : utilFind_sb_rc
+#
+# @param i_sb_name : Sandbox RC path
+#
+# @brief find the sandbox RC path
+#
+##########################################################################
+def utilFind_sb_rc(i_sb_name):
+ out_str= "None"
+
+ # workon -m ppc sbeisb -c 'env | grep SANDBOXRC'
+ find_sb_rc = 'workon -m ppc ' + i_sb_name + " -c 'env | grep SANDBOXRC ' | grep SANDBOXRC"
+ # SANDBOXRC=/gsa/ausgsa/projects/i/indiateam04/gkeishin/.sandboxrc
+ out_str = os.popen(find_sb_rc).read()
+
+ if not out_str:
+ return "None"
+ else:
+ return os.path.dirname(out_str.strip('SANDBOXRC='))
+
+##########################################################################
+# Function : utilFind_ENV_string
+#
+# @param i_env_name : ENV string
+#
+# @brief find the ENV string set in the env
+#
+##########################################################################
+def utilFind_ENV_string(i_env_name):
+ out_str= "None"
+
+ find_env_name = "env | grep " + i_env_name
+
+ out_str = os.popen(find_env_name).read()
+
+ if not out_str:
+ return "None"
+ else:
+ # Strip string
+ l_strip=i_env_name +"="
+ return out_str.strip(l_strip)
+
+##########################################################################
+# Function : utilWriteShell_hooks
+#
+# @param i_sandbox_path : Sandbox full path
+#
+# @brief find the ENV string set in the env
+#
+##########################################################################
+def utilWriteShell_hooks(i_sandbox_path):
+ # Write the compile shell hook on the fips sandbox location
+ hook_file=i_sandbox_path + '/src/compilesb'
+ f = open(hook_file,'w')
+
+ # compilesb: This hook schell script will look like this
+ #
+ # #!/bin/sh
+ # cd /gsa/ausgsa/projects/i/indiateam04/gkeishin/sbeisb/src/sbei/sbfw/
+ # mk -a
+ # mk install_all
+
+ f.write('#!/bin/sh \n')
+ cd_cmd= 'cd ' + i_sandbox_path + '/src/sbei/sbfw/'
+ f.write(cd_cmd)
+ f.write('\n')
+ f.write('mk -a || exit -1 \n')
+ f.write('mk install_all || exit -1\n')
+ f.close()
+
+ # Change the file permission for execute
+ perm_st = os.stat(hook_file)
+ os.chmod(hook_file, perm_st.st_mode | stat.S_IEXEC)
+
+ return hook_file # path of the shell file
+
diff --git a/src/build/tools/sbeGitTool.pl b/src/build/tools/sbeGitTool.pl
new file mode 100755
index 00000000..4bb70348
--- /dev/null
+++ b/src/build/tools/sbeGitTool.pl
@@ -0,0 +1,332 @@
+#! /usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/sbeGitTool.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+use strict;
+#use lib "$ENV{'PERLMODULES'}";
+use lib "sbe/build/tools/perl.modules";
+use Getopt::Long qw(:config pass_through);
+use Data::Dumper;
+use Cwd;
+use gitUtil;
+
+# Global variables & constants
+my $debug = 0;
+my $help = 0;
+my %globals = ();
+my @references = ();
+my @patchList = ();
+my @commits = ();
+my $patches = "";
+my $sbbase = "";
+my $sbname = "";
+my $sbrc = "";
+my $release = "";
+
+my %commands = ( "extract" => \&execute_extract,
+ "get-commits" => \&execute_get_commits);
+
+# Handle input command
+GetOptions("debug!" => \$debug,
+ "help" => \$help);
+
+if ($help)
+{
+ execute_help();
+}
+else
+{
+ my $command = shift @ARGV;
+ if ($commands{$command})
+ {
+ &{$commands{$command}}();
+ }
+ else
+ {
+ execute_help();
+ }
+}
+
+foreach my $arg (@ARGV)
+{
+ print "Unprocessed arg: $arg\n" if $debug;
+}
+
+############################## Begin Actions ##################################
+
+sub execute_help
+{
+ my $command = shift @ARGV;
+
+ if ($command eq "")
+ {
+ print "sbeGitTool\n";
+ print " Run FSP-CI from a set of git commits\n";
+ print "\n";
+ print " Syntax:\n";
+ print " sbeGitTool <tool> [options]\n";
+ print "\n";
+ print " Available subtools:\n";
+ foreach my $key (sort keys %commands)
+ {
+ print " $key\n";
+ }
+ print "\n";
+ print " Global options:\n";
+ print " --debug Enable debug mode.\n";
+ print " --help Display help on a specific tool.\n";
+ print "\n";
+ print " Note: Generally a <commit> can be any git or gerrit\n";
+ print " reference. A git commit number, tag, branch, or\n";
+ print " a gerrit change-id are all valid.\n";
+ }
+ elsif (not defined $commands{$command})
+ {
+ die "Unknown subcommand: $command.\n";
+ }
+ else
+ {
+ my %help = (
+ "extract" =>
+q(
+ Create the SBE binaries with the patch and its CMVC/GIT dependencies.
+
+ Options:
+ --patches=<changeId:patch-set> CSV of changeId:patch-set's [required].
+ --sbbase=<full-path-to-sb-base> Sandbox base for FSP-CI [required].
+ --sbname=<name> Sandbox name [required].
+ --rc=<rc file name> RC file for the sandbox with absolute path [optional].
+),
+ "get-commits" =>
+q(
+ Given a patch, find the corresponding commit id.
+
+ Options:
+ --patches=<changeId:patch-set> CSV of changeId:patch-set's [required].
+ --sbbase=<full-path-to-sb-base> Sandbox base for FSP-CI [required].
+ --sbname=<name> Sandbox name [required].
+)
+ );
+
+ print "sbeGitTool $command:";
+ print $help{$command};
+ }
+}
+
+sub execute_get_commits
+{
+
+ # Set GIT environment
+ git_environ_init();
+
+ # Obtain the list of patches
+ retrivePatchList();
+
+ # Fetch the commits for the patches
+ fetchCommits();
+
+ # Prepare commit string
+ my $commitStr = prepareCommitStr();
+
+ print "The set of commits: $commitStr" if $debug;
+ print $commitStr;
+ return $commitStr;
+}
+
+sub execute_extract
+{
+ # Set GIT environment
+ git_environ_init();
+
+ # Obtain the list of patches
+ retrivePatchList();
+
+ # Fetch the references for the patches
+ fetchRefs();
+
+ # Apply the patches on the GIT repo
+ applyRefs();
+
+ # Compile the SBE and copy binaries to sandbox
+ compileAndCopy();
+}
+
+sub git_environ_init
+{
+ # Handle the i/p to the function
+ GetOptions("patches:s" => \$patches,
+ "sbbase:s" => \$sbbase,
+ "sbname:s" => \$sbname,
+ "rc:s" => \$sbrc);
+
+ die "Missing patch list" if ($patches eq "");
+ die "Missing sandbox base path" if ($sbbase eq "");
+ die "Missing sandbox name" if ($sbname eq "");
+
+ # Set global variables
+ $globals{sandbox} = $sbbase."/".$sbname;
+ $globals{sbe_git_root} = $globals{sandbox}."/git-ci";
+
+ print "Sandbox: $globals{sandbox}\n" if $debug;
+ print "GIT repository path: $globals{sbe_git_root}\n" if $debug;
+
+ chdir($globals{sbe_git_root});
+ die "ERROR $?: Invalid GIT repository path in the sandbox" if $? ;
+}
+
+sub retrivePatchList
+{
+ # Parse out the CSV patch list
+ @patchList = split(/,+/, $patches);
+
+ print ">>>Patches\n" if $debug;
+ print Dumper @patchList if $debug;
+ print "<<<End of Patches\n" if $debug;
+}
+
+sub fetchRefs
+{
+ my $currentRef = "";
+ my $validPatchCount = 0;
+
+ foreach my $patch (@patchList)
+ {
+ my ($changeId,$patchSet) = split(":",$patch);
+ if (gitUtil::gerritIsPatch($changeId))
+ {
+ $validPatchCount = $validPatchCount + 1;
+ print "Fetching reference for the patch : $patch \n" if $debug;
+ if (gitUtil::patchMergeStatus($changeId) == 0)
+ {
+ my $currentRef = gitUtil::gerritQueryReference($changeId, $patchSet);
+ push @references, $currentRef;
+ print "(patchset -> reference) = $patch -> $currentRef\n" if $debug;
+ }
+ }
+ else
+ {
+ print "\n Warning : Patchset $patch is invalid.. Continuing to check if there is any other valid patch \n";
+ }
+ }
+ die "ERROR: No valid patches given..\n" if ($validPatchCount == 0);
+}
+
+sub applyRefs
+{
+ my $statusFile = $globals{sbe_git_root}."/patchApply.status";
+
+ foreach my $ref (@references)
+ {
+ print "Cherrypicking reference $ref \n" if $debug;
+ open SBWORKON, " | ./sb workon";
+ print SBWORKON "git fetch gerrit $ref && echo \"Fetch Done \" > $statusFile \n";
+ #print SBWORKON "git cherry-pick FETCH_HEAD && echo \"Cherry-pick Done \" >> $statusFile \n"; // will be reused once appropriate support is there
+ print SBWORKON "git checkout FETCH_HEAD && echo \"Checkout Done \" >> $statusFile \n";
+ print SBWORKON "exit \n";
+ close SBWORKON;
+
+ print "\nChecking cherrypick status for $ref...\n" if $debug;
+ my $ch_status = `cat $statusFile`;
+ if( ($ch_status =~ m/Fetch/) && ($ch_status =~ m/Checkout/))
+ {
+ print "Checkout successful\n";
+ }
+ else
+ {
+ die "ERROR: Checkout of $ref failed\n";
+ }
+ }
+}
+
+sub compileAndCopy
+{
+ my $statusFile = $globals{sbe_git_root}."/compile.status";
+ my $compile_path = $globals{sbe_git_root};
+
+ print "Compiling and copying the generated binaries to sandbox\n" if $debug;
+ open SBWORKON, " | ./sb workon";
+ print SBWORKON "cd $compile_path \n";
+ print SBWORKON "make install && echo \"Compile Passed\" > $statusFile \n";
+ print SBWORKON "export SANDBOXBASE=$globals{sandbox} \n";
+ print SBWORKON "cd $globals{sbe_git_root} \n";
+ print SBWORKON "./sb prime --sb $sbname --no_build && echo \"Prime Passed\" >> $statusFile \n";
+ print SBWORKON "exit \n";
+ close SBWORKON;
+
+ print "\nChecking compile status...\n" if $debug;
+ my $compile_status = `cat $statusFile | grep "Compile"`;
+ if ($compile_status =~ m/Compile/)
+ {
+ print "SBE compile successful\n";
+ }
+ else
+ {
+ die "ERROR: SBE compile failed\n";
+ }
+
+ print "\nChecking sandbox status...\n" if $debug;
+ my $sb_status = `cat $statusFile | grep "Prime"`;
+ if ($sb_status =~ m/Prime/)
+ {
+ print "SBE prime successful\n";
+ }
+ else
+ {
+ die "ERROR: SBE prime failed\n";
+ }
+}
+
+sub fetchCommits
+{
+ my $currentCommit = "";
+
+ foreach my $patch (@patchList)
+ {
+ my ($changeId,$patchSet) = split(":",$patch);
+ if (gitUtil::gerritIsPatch($changeId))
+ {
+ print "Fetching commit for the patch : $patch \n" if $debug;
+ my $currentCommit = gitUtil::gerritQueryCommit($changeId, $patchSet);
+ push @commits, $currentCommit;
+ print "(patchset -> commit) = $patch -> $currentCommit\n" if $debug;
+ }
+ else
+ {
+ print "\n Warning : Patchset $patch is invalid.. Continuing to check if there is any other valid patch \n";
+ }
+ }
+ die "ERROR: No valid patches given..\n" if (scalar @commits == 0);
+}
+
+sub prepareCommitStr
+{
+ my $commitStr = "";
+
+ foreach my $commit (@commits)
+ {
+ $commitStr = $commitStr.",".$commit;
+ }
+ $commitStr =~ s/^,//g;
+ return $commitStr;
+}
diff --git a/src/build/tools/sbePatchUtility.py b/src/build/tools/sbePatchUtility.py
new file mode 100644
index 00000000..b5103610
--- /dev/null
+++ b/src/build/tools/sbePatchUtility.py
@@ -0,0 +1,179 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/sbePatchUtility.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 sbeCmvcUtility.py
+# @author: George Keishing <gkeishin@in.ibm.com>
+# @brief Utilility Module to Patching files for SBE simics
+#
+# Created on March 23, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 23/03/16 Initial create
+###########################################################
+'''
+
+#-------------------------
+# Imports
+#-------------------------
+import os, sys
+import time
+import os.path
+import subprocess
+import shutil
+import hashlib
+from subprocess import Popen, PIPE
+from os.path import expanduser # for getting $HOME PATH
+import stat # for File permission op
+
+# Libraries/utility funcs and user define const
+import sbeCmvcConstants as errorcode
+import sbeCmvcUtility as utilcode
+
+##########################################################################
+# Function : utilPatchSimics
+#
+# @param i_sandbox_path : Sandbox full path
+#
+# @param i_sandbox_root : Sandbox RC root path
+#
+# @brief Patch pre-req patches for simics
+#
+##########################################################################
+def utilPatchSimics(i_sandbox_path, i_sandbox_root):
+ print "\n ... Patching simics files "
+
+ sb_name=os.path.basename(i_sandbox_path)
+
+ # Write the hooks for sim setup
+ l_sim_file = utilShell_hooks(i_sandbox_path)
+
+ if not l_sim_file:
+ return errorcode.ERROR_HOOKING_FILE
+
+ l_sim_cmd = "workon -m ppc " + sb_name + " -c " + l_sim_file + " -rc " + i_sandbox_root +"/sbesandboxrc"
+ print " ", l_sim_cmd
+
+ os.system(l_sim_cmd)
+
+ # Copy action files. As we are taking actions files from ppe, copy them here
+ # so that any workaround necessary can be applied over them in pre-simsetup path
+ # mkdir -p $SANDBOXBASE/src/simu/data/cec-chip
+ # cp $SBEROOT/import/chips/p9/sw_simulation/* $SANDBOXBASE/src/simu/data/cec-chip || exit -1
+
+ print " [ Copying action files to fips Sandbox ]"
+ # Ge the Sandbox base
+ sandbox_base = utilcode.utilFind_ENV_string("SANDBOXBASE").rstrip('\n')
+ sandbox_path = sandbox_base + "/src/simu/data/cec-chip"
+ cmd = "mkdir -p " + sandbox_path
+ print " * Executing : ",cmd
+ os.system(cmd)
+
+ # Ge the ppe root
+ ppe_base = utilcode.utilFind_ENV_string("SBEROOT").rstrip('\n')
+ ppe_path = ppe_base + "/import/chips/p9/sw_simulation/"
+ p_cmd = "cp -f " + ppe_path + "* " + sandbox_path
+ print " * Executing : ",p_cmd
+ rc = os.system(p_cmd)
+ if rc:
+ print " ERROR rc :",rc
+ return rc
+
+ return errorcode.SUCCESS_EXIT
+
+##########################################################################
+# Function : utilExecuteShell
+#
+# @param i_ppe_root : Root folder for PPE. This script must be
+# from PPE repo.
+#
+# @param i_sandbox_path : fips Sandbox path
+#
+# @param i_shell_file : User defined shell script name
+#
+# @brief Apply the simics patches pre define in shell script.
+#
+##########################################################################
+def utilExecuteShell(i_ppe_root, i_sandbox_path, i_shell_file):
+ print "\n ... Executing shell : ",i_shell_file
+
+ # Sanbox name
+ if i_sandbox_path != "None":
+ sb_name=os.path.basename(i_sandbox_path)
+
+ # Find the file and execute
+ l_path_name = i_ppe_root + '/src/build/'
+ l_shell_path=utilcode.utilFindFile(i_shell_file, l_path_name)
+ print " [ %s ]"%l_shell_path
+
+ if i_sandbox_path != "None":
+ # Load the shell onto the Sandbox env and execute
+ l_shell_exec = "workon -m ppc " + sb_name + " -c " + l_shell_path + " -rc " + i_sandbox_path.replace(sb_name,"") +"/sbesandboxrc"
+ else:
+ # Execute a stand alone script
+ l_shell_exec = l_shell_path
+
+ #rc = subprocess.call([l_shell_exec])
+ rc = os.system(l_shell_exec)
+ if rc :
+ return rc
+
+ return errorcode.SUCCESS_EXIT
+
+##########################################################################
+# Function : utilShell_hooks
+#
+# @param i_sandbox_path : Sandbox full path
+#
+# @brief find the ENV string set in the env
+#
+##########################################################################
+def utilShell_hooks(i_sandbox_path):
+ # Find the simics machine from ENV
+ l_machine = os.environ['MACHINE'].rstrip('\n')
+ print " Machine : ",l_machine
+ l_cmd_exec = 'start_simics -no_start -machine ' + l_machine + ' -batch_mode '
+
+ # Write the compile shell hook on the fips sandbox location
+ hook_file=i_sandbox_path + '/src/simsb'
+ f = open(hook_file,'w')
+
+ # simsb: This hook schell script will look like this
+ #
+ # #!/bin/sh
+ # start_simics -no_start -machine NIMBUS -batch_mode
+
+ f.write('#!/bin/sh \n')
+ f.write('\n')
+ f.write(l_cmd_exec)
+ f.close()
+
+ # Change the file permission for execute
+ perm_st = os.stat(hook_file)
+ os.chmod(hook_file, perm_st.st_mode | stat.S_IEXEC)
+
+ return hook_file # path of the shell file
+
diff --git a/src/build/tools/sbePrime.py b/src/build/tools/sbePrime.py
new file mode 100755
index 00000000..479ee051
--- /dev/null
+++ b/src/build/tools/sbePrime.py
@@ -0,0 +1,296 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/sbePrime.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 sbePrime.py
+# @author: George Keishing <gkeishin@in.ibm.com>
+# @brief Main Module to support developer compilation
+# and patching.
+#
+# Created on March 03, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 022/03/16 Initial create
+###########################################################
+'''
+
+#-------------------------
+# Imports
+#-------------------------
+import getopt
+import os, sys, glob
+import shutil
+import stat # for File permission op
+
+# Libraries/utility funcs and user define const
+import sbeCmvcConstants as errorcode
+import sbeCmvcUtility as utilcode
+import sbePatchUtility as utilpatch
+
+#-------------------------
+# Main Function
+#-------------------------
+def main():
+
+ #------------------------------------------
+ # Usage tool option
+ #------------------------------------------
+ def usage():
+ print " \n"
+ print " :: Command line USAGE options for Copying SBE FW files for compilation :: \n"
+ print " sbeDistribute.py -s <Sandbox Name> -i <file1,file2...>"
+
+ print " \n"
+ print " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ print " | By default NO argument is needed as an input . |"
+ print " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ print " \n ***** Options Supported *****"
+ print " \t -p,--patch = [ Optional ] Patch Simics related files on Sandbox "
+ print " \t -s,--sb = [ Optional ] Sandbox base name"
+ print " \t By default it picks up the ppe Repo test_sb sandbox"
+ print " \t but if you have created a sandbox of your own manually "
+ print " \t and you want to compile, use this option then only"
+ print " \t -i,--files = [ Optional ] Firmware Files coma ',' separated input file1,file2"
+ print " \t Only the pre-define listed files bellow:"
+ print " \t sbe_sp_intf.H,simics.tar,sbe_pibmem.bin,sbe_seeprom.bin"
+ print " \t -r,--rc_file = [ Optional ] The RC file for the sandbox (with absolute path)"
+ print " \t -n,--no_build = [ Optional ] Flag to determine if sbei component should be compiled"
+ print " \t -h,--help = Help"
+ print " ------------------------------------------------------------------------------------"
+
+ #------------------------------------------
+ # Exit from this Main
+ #------------------------------------------
+ def exit_main(rc):
+ if rc == errorcode.HELP_EXIT:
+ print " [ HELP DOCUMENTATION ]\n"
+ sys.exit(0)
+
+ if rc == errorcode.ERROR_BUILD_FAILED:
+ print " Compilation Failed .. Error "
+
+ if rc == errorcode.SUCCESS_DEV_EXIT:
+ print " [ Files Copy done! ]\n"
+ sys.exit(0)
+
+ if rc:
+ print "\n [ ERROR - MAIN ] Exiting with error code = ", rc
+ sys.exit(rc)
+ else:
+ print "\n Fips Sandbox compilation and simics patching completed [ OK ] "
+ sys.exit(0)
+
+ #------------------------------------------
+ # Local var place name holder's
+ #------------------------------------------
+ sim_patch = "None"
+ sandbox_name = "None"
+ path_name = "None" # PPE Repo
+ file_name = "None"
+ rc_file = "None"
+ build = "1"
+
+ #----------------------------
+ # Read command line args
+ #----------------------------
+ opts, args = getopt.getopt(sys.argv[1:],"p:s:i:h:r:n",['patch=', 'sb=', 'files=', 'help', 'rc_file=', 'no_build'])
+ for opt, arg in opts:
+ if opt in ('-h', '--help'):
+ usage()
+ exit_main(errorcode.HELP_EXIT)
+ elif opt in ('-p', '--patch'):
+ sim_patch = arg
+ elif opt in ('-s', '--sb'):
+ sandbox_name = arg
+ elif opt in ('-i', '--files'):
+ file_name = arg
+ elif opt in ('-r', '--rc_file'):
+ rc_file = arg
+ elif opt in ('--no_build'):
+ build = "0"
+ else:
+ usage()
+ exit_main(errorcode.ERROR_EXIT)
+
+ #------------------------------------------------------
+ # Make sure that it has passed atleast one arg with it
+ #------------------------------------------------------
+ if len(sys.argv)<1:
+ usage()
+ exit_main(errorcode.ERROR_SYS_EXIT)
+
+ #---------------------------------------------
+ # Callling the Func defs in order
+ #---------------------------------------------
+
+ #------------------------------
+ # 1) User input params/ Check ENV
+ #------------------------------
+ print "\n [ Checking SBE user ENV Pre-req ] "
+ # Get it from ENV
+ if path_name == "None":
+ # Get the PPE path
+ l_ppe_path = utilcode.utilppeSbENV("SBEROOT")
+ if l_ppe_path == "None":
+ print "\n Couldn't find PPE repo info from ENV currently set... "
+ print " [ ERROR ] PPE Repo ENV Setting Path : %s " % l_ppe_path
+ exit_main(errorcode.ERROR_SETTING)
+ else:
+ print " PPE Repo path Setting\t : %s "% l_ppe_path
+ path_name = l_ppe_path
+
+ #-----------------------------------
+ # 2) Get the Sanbox and repo paths
+ #-----------------------------------
+ # Get the base path of the fips sandbox
+ if sandbox_name == "None":
+ # Find the sanbox name and base from ENV
+ # User must have done workon fips sandbox to work
+ sandbox_path = utilcode.utilFind_ENV_string("SANDBOXBASE").rstrip('\n')
+ else:
+ sandbox_path = utilcode.utilFind_sb_base(sandbox_name).rstrip('\n')
+ print " Fips Sandbox path\t : ",sandbox_path
+
+ #-----------------------------------
+ # 3) Get the Sanbox root path
+ #-----------------------------------
+ if sandbox_name == "None":
+ sandbox_root = utilcode.utilFind_ENV_string("SANDBOXROOT").rstrip('\n')
+ else:
+# sandbox_root = utilcode.utilFind_ENV_string("SANDBOXRC").rstrip('\n')
+ sandbox_root = utilcode.utilFind_sb_rc(sandbox_name).rstrip('\n')
+
+ if sandbox_root == "None":
+ print " ** [ ERROR ] Something Fishy about the ENV set -OR- Option used.. Please check manually ** "
+ usage()
+ exit_main(errorcode.ERROR_SETTING)
+ else:
+ print " Sandbox root path\t : ",sandbox_root
+
+ #---------------------------------------------
+ # sim setup if user initiates
+ #---------------------------------------------
+ if sim_patch != "None":
+ #---------------------------------------------
+ # Create sandbox for simics
+ #---------------------------------------------
+ rc_sb = utilpatch.utilExecuteShell(path_name,"None","sandbox-create")
+ if rc_sb == errorcode.SUCCESS_EXIT:
+ print " Sandbox Created.. [ OK ] \n"
+ else:
+ print " Sandbox Create.. [ ERROR ]",rc_sb
+ exit_main(rc_sb)
+
+ #----------------------------------------
+ # Patch up the simics patches files
+ #----------------------------------------
+
+ print "\n *** Update Simics patches onto Sandbox *** \n "
+ # Pre sim setup
+ rc_shell = utilpatch.utilExecuteShell(path_name,sandbox_path,"workarounds.presimsetup")
+ if rc_shell == errorcode.SUCCESS_EXIT:
+ print " presimsetup [ OK ]\n"
+ else:
+ print " presimsetup [ ERROR ] : ",rc_shell
+ exit_main(rc_shell)
+
+ # Patch the simics files
+ rc_sim = utilpatch.utilPatchSimics(sandbox_path,sandbox_root)
+ if rc_sim != errorcode.SUCCESS_EXIT:
+ exit_main(rc_sim)
+ else:
+ print " Patch the simics files on Sandbox [ OK ] \n"
+
+ # Post sim setup
+ rc_shell = utilpatch.utilExecuteShell(path_name,sandbox_path,"workarounds.postsimsetup")
+ if rc_shell == errorcode.SUCCESS_EXIT:
+ print " postsimsetup [ OK ]\n"
+ # Clean exit Get out from here
+ exit_main(errorcode.SUCCESS_EXIT)
+ else:
+ print " postsimsetup [ ERROR ] : ",rc_shell
+ exit_main(rc_shell)
+
+
+ #----------------------------------------
+ # 4) Copy the files from repo to sandbox
+ #----------------------------------------
+ # Find the files and copy to the sanbox dir
+ # Just take a quick check if the Sandbox exist or not
+ if sandbox_path != "None":
+ if os.path.isdir(sandbox_path) == True:
+ rc_copy = utilcode.utilCopyFileToSandbox(path_name,sandbox_path,file_name)
+ if rc_copy == errorcode.SUCCESS_DEV_EXIT:
+ print " Files Copied to Fips Sandbox : [ OK ]"
+ else:
+ exit_main(rc_copy)
+ else:
+ print " Sandbox : %s [ Either doesn't exist or do workon to fips sb to load the ENV.. ]" % os.path.basename(sandbox_path)
+ print " - OR - "
+ print " [ Optional ] You can specify your sandbox name as input as well"
+ print " -s <fips_sandbox Name >"
+ usage()
+ exit_main(errorcode.ERROR_SANDBOX_EXIST)
+ else:
+ print " Please Check your fips Sandbox and retry"
+ exit_main(errorcode.ERROR_SANDBOX_EXIST)
+
+ sb_name=os.path.basename(sandbox_path)
+ print "\n Sandbox :",sb_name
+
+ if build == "1":
+ #----------------------------------------
+ # 5) Wite the hook file into shell file
+ #----------------------------------------
+ # Write the compile shell hook on the fips sandbox location
+ hook_file = utilcode.utilWriteShell_hooks(sandbox_path)
+
+ #----------------------------------------
+ # 6) Compile the code
+ #----------------------------------------
+ # Use the hook script to compile the code
+ if sandbox_name == "None":
+ compile_cmd="workon -m ppc " + sb_name + " -c " + hook_file + " -rc " + sandbox_root +"/sbesandboxrc"
+ else:
+ if rc_file == "None":
+ compile_cmd="workon -m ppc " + sb_name + " -c " + hook_file + " -rc " + sandbox_root +"/.sandboxrc"
+ else:
+ print " getting rc file from user \n"
+ compile_cmd="workon -m ppc " + sb_name + " -c " + hook_file + " -rc " + rc_file
+ print "\n [ COMPILE ] Executing :%s \n"%compile_cmd
+ rc = os.system(compile_cmd)
+
+ print " Compilation returned rc :",rc
+ if rc != 0:
+ exit_main(errorcode.ERROR_BUILD_FAILED)
+
+ # Clean exit
+ exit_main(errorcode.SUCCESS_EXIT)
+
+
+if __name__=="__main__":
+ main()
+
diff --git a/src/hwpf/include/buffer_traits.H b/src/hwpf/include/buffer_traits.H
new file mode 100644
index 00000000..1b299fd6
--- /dev/null
+++ b/src/hwpf/include/buffer_traits.H
@@ -0,0 +1,241 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/buffer_traits.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 buffer_traits.H
+ * @brief trait definitions for fapi2 buffer base class
+ */
+
+#ifndef __FAPI2_BUFFER_TRAITS__
+#define __FAPI2_BUFFER_TRAITS__
+
+#include <stdint.h>
+#include <vector>
+#include <algorithm>
+#include <buffer_parameters.H>
+
+#ifdef FAPI2_DEBUG
+#include <iostream>
+#endif
+
+#if !defined(DOXYGEN) && defined(FAPI2_DEBUG)
+#include <iterator>
+#endif
+
+namespace fapi2
+{
+ /// @cond
+ /// Types representing a container of bits. Used to create
+ /// variable_buffer. container_unit must remain 32-bits
+ /// for now - there will be a lot of code to change if it
+ /// changes. There are assertions helping to enforce this
+ /// in places in the code.
+ typedef uint32_t container_unit;
+ typedef std::vector<container_unit> bits_container;
+
+ /// @brief Traits of buffers
+ // In general, we try to give buffers traits reflecting integral types. If
+ // this fails, the compiler will let someone know.
+ ///
+ /// @tparam T is the type of iv_data (std::vector, etc)
+ /// @tparam B is the type of the bit-specifier, typically uint32_t
+ template<typename T, typename B = uint32_t>
+ class bufferTraits
+ {
+ public:
+
+#if !defined(DOXYGEN) && defined(FAPI2_DEBUG)
+ ///
+ /// @brief Print a container of bits
+ /// @param[in] i_data the container of bits
+ ///
+ static inline void print(const T& i_data)
+ {
+ // convert to uint64_t to prevent uint8_t from being
+ // printed as a char.
+ std::cout << "\tdata is "
+ << std::hex
+ << static_cast<uint64_t>(i_data)
+ << std::dec << std::endl;
+ }
+#endif
+
+ ///
+ /// @brief Return the size of the buffer in E units
+ /// @tparam E, the element size.
+ /// @param[in] io_buffer the buffer which to size
+ /// @return The size of the buffer in E's rounded up
+ ///
+ template<typename E>
+ constexpr static B size(const T& i_buffer)
+ {
+ return (bit_length(i_buffer) +
+ (parameterTraits<E>::bit_length() - 1)) /
+ parameterTraits<E>::bit_length();
+ }
+
+ ///
+ /// @brief Return the size of the buffer itself
+ /// @param[in] io_buffer the buffer which to size
+ /// @return The size of the buffer in bits (not units)
+ ///
+ constexpr static B bit_length(const T&)
+ { return sizeof(T) * 8; }
+
+ ///
+ /// @brief Clear the buffer
+ /// @param[in,out] io_buffer the buffer which to clear
+ ///
+ static inline void clear(T& io_buffer)
+ { io_buffer = static_cast<T>(0); }
+
+ ///
+ /// @brief Set the buffer
+ /// @param[in,out] io_buffer the buffer which to set
+ ///
+ static inline void set(T& io_buffer)
+ { io_buffer = static_cast<T>(~0); }
+
+ ///
+ /// @brief Invert the buffer
+ /// @param[in,out] io_buffer the buffer which to invert
+ ///
+ static inline void invert(T& io_buffer)
+ { io_buffer = ~io_buffer; }
+
+ ///
+ /// @brief Reverse the buffer
+ /// @param[in,out] io_buffer the buffer which to reverse
+ ///
+ static inline void reverse(T& io_buffer)
+ {
+ io_buffer =
+ ((io_buffer & 0xAAAAAAAAAAAAAAAA) >> 1) |
+ ((io_buffer & 0x5555555555555555) << 1);
+ }
+
+ ///
+ /// @brief Get the address of the buffer as an array
+ /// @param[in] i_buffer the buffer which to invert
+ /// @return The address of the first element of the buffer
+ ///
+ static inline void* get_address(T& i_buffer)
+ { return (void*)&i_buffer; }
+
+ typedef B bits_type;
+ typedef T unit_type;
+ constexpr static uint32_t bits_per_unit(void)
+ { return sizeof(unit_type) * 8; }
+ };
+
+ //
+ //
+ /// @brief Traits for buffers which are a container of bits
+ //
+ //
+ template<>
+ class bufferTraits<bits_container, uint32_t>
+ {
+ public:
+#if !defined(DOXYGEN) && defined(FAPI2_DEBUG)
+ ///
+ /// @brief Print a container of bits
+ /// @param[in] i_data the container of bits
+ ///
+ static inline void print(const bits_container& i_data)
+ {
+ std::cout << "\tdata is " << std::hex;
+ std::copy(i_data.begin(), i_data.end(),
+ std::ostream_iterator<container_unit>(std::cout, " "));
+ std::cout << std::dec << std::endl;
+ }
+#endif
+
+ ///
+ /// @brief Return the size of the buffer in E units
+ /// @tparam E, the element size.
+ /// @param[in] io_buffer the buffer which to size
+ /// @return The size of the buffer in E's rounded up
+ ///
+ template<typename E>
+ constexpr static uint32_t size(const bits_container& i_buffer)
+ {
+ return (bit_length(i_buffer) +
+ (parameterTraits<E>::bit_length() - 1)) /
+ parameterTraits<E>::bit_length();
+ }
+
+ ///
+ /// @brief Return the size of the buffer itself
+ /// @param[in,out] io_buffer the buffer which to size
+ /// @return The size of the buffer in bits (not units)
+ ///
+ static inline uint32_t bit_length(const bits_container& i_buffer)
+ { return i_buffer.size() * sizeof(container_unit) * 8; }
+
+ ///
+ /// @brief Clear the buffer
+ /// @param[in,out] io_buffer the buffer which to clear
+ ///
+ static inline void clear(bits_container& io_buffer)
+ { io_buffer.assign(io_buffer.size(), 0); }
+
+ ///
+ /// @brief Set the buffer
+ /// @param[in,out] io_buffer the buffer which to set
+ ///
+ static inline void set(bits_container& io_buffer)
+ { io_buffer.assign(io_buffer.size(), ~0); }
+
+ ///
+ /// @brief Invert the buffer
+ /// @param[in,out] io_buffer the buffer which to invert
+ ///
+ static inline void invert(bits_container& io_buffer)
+ {
+ std::transform(io_buffer.begin(), io_buffer.end(),
+ io_buffer.begin(),
+ [](container_unit u) { return ~u; });
+ }
+
+ ///
+ /// @brief Get the address of the buffer as an array
+ /// @param[in] i_buffer the buffer which to invert
+ /// @return The address of the first element of the buffer
+ ///
+ static inline void* get_address(bits_container& i_buffer)
+ {
+ return (void*)&(i_buffer[0]);
+ }
+
+ typedef uint32_t bits_type;
+ typedef container_unit unit_type;
+ constexpr static uint32_t bits_per_unit(void)
+ { return sizeof(unit_type) * 8; }
+ };
+ /// @endcond
+}
+
+
+
+#endif
diff --git a/src/hwpf/include/error_info.H b/src/hwpf/include/error_info.H
new file mode 100644
index 00000000..cc0ae9a2
--- /dev/null
+++ b/src/hwpf/include/error_info.H
@@ -0,0 +1,685 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/error_info.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 error_info.H
+/// @brief Defines the Error Information structures and classes
+///
+
+#ifndef FAPI2_ERRORINFO_H_
+#define FAPI2_ERRORINFO_H_
+
+#include <stdint.h>
+#ifndef __PPE__
+#include <memory>
+#endif
+#include <vector>
+#include <target.H>
+#include <error_info_defs.H>
+
+namespace fapi2
+{
+#if defined(MINIMUM_FFDC)
+
+// convert generic type to uint64_t
+template<typename T>
+inline uint64_t convertType( T& i_value )
+{
+ // for simplicity sake, all FFDC chunks from the SBE
+ // are going to be sent as a uint64_t
+ return static_cast<uint64_t>(i_value);
+};
+
+// convert platform target handle to a uint64_t
+template<fapi2::TargetType T, typename V>
+inline uint64_t convertType( const fapi2::Target<T, V>& i_value)
+{
+ // TODO: via RTC 158868 : Update this for multicast targets
+ // get the SBE platform target handle
+ return static_cast<uint64_t>((static_cast<uint64_t>((static_cast<plat_target_handle_t>(i_value.get()).getFapiTargetType())) << 32) | static_cast<plat_target_handle_t>(i_value.get()).getTargetInstance());
+};
+#endif
+
+#if !defined(FAPI2_NO_FFDC) && !defined(MINIMUM_FFDC)
+// forward fapi2::Assert()
+extern void Assert(bool);
+
+///
+/// @class ErrorInfoFfdc
+///
+/// This class contains a copy of some FFDC data
+///
+class ErrorInfoFfdc
+{
+ public:
+ ///
+ /// @brief Constructor
+ ///
+ /// @param[in] i_ffdcId FFDC Identifier (used to decode FFDC)
+ /// @param[in] i_pFfdc Pointer to the FFDC to copy
+ /// @param[in] i_size Size of the FFDC to copy
+ ///
+ ErrorInfoFfdc(const uint32_t i_ffdcId,
+ const void* i_pFfdc,
+ const uint32_t i_size);
+
+ ///
+ /// @brief Get a pointer to the FfdcData
+ ///
+ /// @param[out] o_size Reference to uint32_t that is filled in with
+ /// the FFDC size
+ ///
+ /// @return void *. Pointer to the FFDC
+ ///
+ inline const void* getData(uint32_t& o_size) const
+ {
+ o_size = iv_size;
+ return iv_pFfdc.get();
+ }
+
+ ///
+ /// @brief Get a pointer to the FfdcData
+ /// @return void *. Pointer to the FFDC
+ ///
+ inline void* getData(void) const
+ {
+ return iv_pFfdc.get();
+ }
+
+ ///
+ /// @brief Get the FFDC Identifier
+ ///
+ /// @return uint32_t The FFDC Identifier
+ ///
+ inline uint32_t getFfdcId(void)
+ {
+ return iv_ffdcId;
+ }
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ private:
+
+ // FFDC Identifier
+ uint32_t iv_ffdcId;
+
+ // Pointer to the FFDC
+ std::shared_ptr<uint8_t> iv_pFfdc;
+
+ // Size of the FFDC
+ uint32_t iv_size;
+
+ // Disabled
+ ErrorInfoFfdc(const ErrorInfoFfdc&) = delete;
+ ErrorInfoFfdc& operator=(const ErrorInfoFfdc&) = delete;
+};
+
+///
+/// @struct ErrorInfoHwCallout
+///
+/// This struct contains hardware to callout
+///
+struct ErrorInfoHwCallout
+{
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_hw Hardware to callout
+ /// @param[in] i_calloutPriority Priority of callout
+ /// @param[in] i_refTarget Reference to reference target
+ ///
+ ErrorInfoHwCallout(
+ const HwCallouts::HwCallout i_hw,
+ const CalloutPriorities::CalloutPriority i_calloutPriority,
+ const Target<TARGET_TYPE_ALL>& i_refTarget);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The hw to callout
+ HwCallouts::HwCallout iv_hw;
+
+ // The callout priority
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+
+ // The reference target (needed for some HW callouts to identify what to
+ // callout). The target handle is NULL if there is no reference target.
+ Target<TARGET_TYPE_ALL> iv_refTarget;
+};
+
+///
+/// @struct ErrorInfoProcedureCallout
+///
+/// This struct contains a procedure to callout
+///
+struct ErrorInfoProcedureCallout
+{
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_procedure Procedure to callout
+ /// @param[in] i_calloutPriority Priority of callout
+ ///
+ ErrorInfoProcedureCallout(
+ const ProcedureCallouts::ProcedureCallout i_procedure,
+ const CalloutPriorities::CalloutPriority i_calloutPriority);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The procedure to callout
+ ProcedureCallouts::ProcedureCallout iv_procedure;
+
+ // The callout priority
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+};
+
+///
+/// @struct ErrorInfoBusCallout
+///
+/// This struct contains a bus to callout
+///
+struct ErrorInfoBusCallout
+{
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_target1 Reference to target on one end of the bus
+ /// @param[in] i_target2 Reference to target on other end of the bus
+ /// @param[in] i_calloutPriority Priority of callout
+ ///
+ ErrorInfoBusCallout(
+ const Target<TARGET_TYPE_ALL>& i_target1,
+ const Target<TARGET_TYPE_ALL>& i_target2,
+ const CalloutPriorities::CalloutPriority i_calloutPriority);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The targets on each end of the bus to callout
+ Target<TARGET_TYPE_ALL> iv_target1;
+ Target<TARGET_TYPE_ALL> iv_target2;
+
+ // The callout priority
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+};
+
+///
+/// @struct ErrorInfoCDG
+///
+/// This struct contains a target to callout/deconfigure/GARD
+///
+struct ErrorInfoCDG
+{
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_target Reference to the target to c/d/g
+ /// @param[in] i_callout True if Target should be called out
+ /// @param[in] i_deconfigure True if Target should be deconfigured
+ /// @param[in] i_gard True if Target should be GARDed
+ /// @param[in] i_priority The priority of any callout
+ ///
+ ErrorInfoCDG(const Target<TARGET_TYPE_ALL>& i_target,
+ const bool i_callout,
+ const bool i_deconfigure,
+ const bool i_gard,
+ const CalloutPriorities::CalloutPriority i_priority);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The target to callout/deconfigure/GARD
+ Target<TARGET_TYPE_ALL> iv_target;
+
+ // Callout Information
+ bool iv_callout;
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+
+ // Deconfigure Information
+ bool iv_deconfigure;
+
+ // GARD Information
+ bool iv_gard;
+};
+
+///
+/// @struct ErrorInfoChildrenCDG
+///
+/// This struct contains children targets to callout/deconfigure/GARD
+///
+/// Children by containment can be CDG (chiplets belonging to a parent chip)
+/// e.g.
+/// - PROC_CHIP -> EX_CHIPLET
+/// - MEMBUF_CHIP -> MBA_CHIPLET
+/// Children by affinity can be CDG.
+/// Any from PROC_CHIP->MCS_CHIPLET->MEMBUF_CHIP->MBA_CHIPLET->DIMM e.g.
+/// - PROC_CHIP->MEMBUF_CHIP
+/// - MEMBUF_CHIP->DIMM
+/// - MBA_CHIPLET->DIMM
+/// Port and Number criteria can be applied to the child target as
+/// detailed in the constructor
+///
+struct ErrorInfoChildrenCDG
+{
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_parentChip Reference to the parent target
+ /// @param[in] i_childType Child target type to c/d/g
+ /// @param[in] i_callout True if Target should be called out
+ /// @param[in] i_deconfigure True if Target should be deconfigured
+ /// @param[in] i_gard True if Target should be GARDed
+ /// @param[in] i_priority The priority of any callout
+ /// @param[in] i_childPort Child Port
+ /// For DIMM children, the MBA port number
+ /// @param[in] i_childNum Child Number
+ /// For DIMM children, the dimm socket number
+ /// For Chip children, the chip position
+ /// For Chiplet children, the chiplet unit pos
+ ///
+ ErrorInfoChildrenCDG(const Target<TARGET_TYPE_ALL>& i_parentChip,
+ const TargetType i_childType,
+ const bool i_callout,
+ const bool i_deconfigure,
+ const bool i_gard,
+ const CalloutPriorities::CalloutPriority i_priority,
+ const uint8_t i_childPort, const uint8_t i_childNum);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The parent chip
+ Target<TARGET_TYPE_ALL> iv_parent;
+
+ // The child target types to c/d/g
+ TargetType iv_childType;
+
+ // Callout Information
+ bool iv_callout;
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+
+ // Deconfigure Information
+ bool iv_deconfigure;
+
+ // GARD Information
+ bool iv_gard;
+
+ // Child Port
+ static const uint8_t ALL_CHILD_PORTS = 0xff;
+ uint8_t iv_childPort;
+
+ // Child Number
+ static const uint8_t ALL_CHILD_NUMBERS = 0xff;
+ uint8_t iv_childNumber;
+};
+
+///
+/// @struct ErrorInfoCollectTrace
+///
+/// This struct contains trace ID to add to the error log
+///
+struct ErrorInfoCollectTrace
+{
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_traceId
+ ///
+ ErrorInfoCollectTrace(CollectTraces::CollectTrace i_traceId);
+
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // trace
+ CollectTraces::CollectTrace iv_eiTraceId;
+};
+
+///
+/// @struct ErrorInfo
+///
+/// This struct defines the error information associated with a fapi2::ffdc
+/// Users are allowed to access the data directly
+///
+struct ErrorInfo
+{
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // Vector of FFDC Data
+ std::vector<std::shared_ptr<ErrorInfoFfdc> > iv_ffdcs;
+
+ // Vector of Hardware to callout
+ std::vector<std::shared_ptr<ErrorInfoHwCallout> > iv_hwCallouts;
+
+ // Vector of procedures to callout
+ std::vector<std::shared_ptr<ErrorInfoProcedureCallout> >
+ iv_procedureCallouts;
+
+ // Vector of buses to callout
+ std::vector<std::shared_ptr<ErrorInfoBusCallout> > iv_busCallouts;
+
+ // Vector of targets to callout/deconfigure/GARD
+ std::vector<std::shared_ptr<ErrorInfoCDG> > iv_CDGs;
+
+ // Vector of children targets to callout/deconfigure/GARD
+ std::vector<std::shared_ptr<ErrorInfoChildrenCDG> > iv_childrenCDGs;
+
+ // Vector of traces to collect
+ std::vector<std::shared_ptr<ErrorInfoCollectTrace> > iv_traces;
+};
+///
+/// @brief Structure representing a single ErrorInfo entry.
+///
+/// An array of these is passed to the addErrorInfo function when a HWP
+/// generates an error by calling the FAPI_SET_HWP_ERROR macro
+// Why aren't these inherited classes? Saves on allocation overhead.
+// We create an array of ErrorInfoEntries as automatics when we start
+// FFDC collection. If we did this as inherited classes it would either
+// be allocating and deallocating or we'd need to allocate an array of
+// the largest and map each struct in to it. That's messy to do without
+// unions (that's what they're for) so we do it like this. The inherited
+// model would result in a jump table anyway, so we're basically doing
+// all of that by hand to avoid the mess.
+//
+struct ErrorInfoEntryFfdc
+{
+ uint8_t iv_ffdcObjIndex;
+ uint16_t iv_ffdcSize;
+ uint32_t iv_ffdcId;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+};
+
+///
+/// @brief Structure representing a hardware callout
+///
+struct ErrorInfoEntryHwCallout
+{
+ uint8_t iv_hw;
+ uint8_t iv_calloutPriority;
+ uint8_t iv_refObjIndex;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+};
+
+///
+/// @brief Structure representing a procedure callout
+///
+struct ErrorInfoEntryProcCallout
+{
+ uint8_t iv_procedure;
+ uint8_t iv_calloutPriority;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+
+ ErrorInfoEntryProcCallout(uint8_t i_procedure, uint8_t i_calloutPriority):
+ iv_procedure(i_procedure),
+ iv_calloutPriority(i_calloutPriority)
+ {}
+
+ ErrorInfoEntryProcCallout(void) = default;
+};
+
+///
+/// @brief Structure representing a bus callout
+///
+struct ErrorInfoEntryBusCallout
+{
+ uint8_t iv_endpoint1ObjIndex;
+ uint8_t iv_endpoint2ObjIndex;
+ uint8_t iv_calloutPriority;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+};
+
+///
+/// @brief Structure representing a target callout
+///
+struct ErrorInfoEntryTargetCDG
+{
+ uint8_t iv_targetObjIndex;
+ uint8_t iv_callout;
+ uint8_t iv_deconfigure;
+ uint8_t iv_gard;
+ uint8_t iv_calloutPriority;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+};
+
+///
+/// @brief Structure representing a child callout
+///
+struct ErrorInfoEntryChildrenCDG
+{
+ uint8_t iv_parentObjIndex;
+ uint8_t iv_callout;
+ uint8_t iv_deconfigure;
+ uint32_t iv_childType;
+ uint8_t iv_childPort;
+ uint8_t iv_childNumber;
+ uint8_t iv_gard;
+ uint8_t iv_calloutPriority;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+};
+
+///
+/// @brief Structure representing collected trace information
+///
+struct ErrorInfoEntryCollectTrace
+{
+ uint32_t iv_eieTraceId;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+};
+
+///
+/// @brief Union of all the error info types
+///
+struct ErrorInfoEntry
+{
+ uint8_t iv_type; // Value from ErrorInfoType
+ union
+ {
+ ErrorInfoEntryFfdc ffdc;
+ ErrorInfoEntryHwCallout hw_callout;
+ ErrorInfoEntryProcCallout proc_callout;
+ ErrorInfoEntryBusCallout bus_callout;
+ ErrorInfoEntryTargetCDG target_cdg;
+ ErrorInfoEntryChildrenCDG children_cdg;
+ ErrorInfoEntryCollectTrace collect_trace;
+ };
+
+ ///
+ /// @brief Add error information to the FFDC object
+ /// @param[in] i_info a shared pointer to the error info
+ /// @param[in] i_object the list of ffdc objects being collected
+ ///
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ // "unhandled error info type");
+ fapi2::Assert(iv_type < EI_LAST_TYPE);
+
+ switch(iv_type)
+ {
+ case EI_TYPE_FFDC:
+ ffdc.addErrorInfo(i_info, i_object);
+ break;
+
+ case EI_TYPE_HW_CALLOUT:
+ hw_callout.addErrorInfo(i_info, i_object);
+ break;
+
+ case EI_TYPE_PROCEDURE_CALLOUT:
+ proc_callout.addErrorInfo(i_info, i_object);
+ break;
+
+ case EI_TYPE_BUS_CALLOUT:
+ bus_callout.addErrorInfo(i_info, i_object);
+ break;
+
+ case EI_TYPE_CDG:
+ target_cdg.addErrorInfo(i_info, i_object);
+ break;
+
+ case EI_TYPE_CHILDREN_CDG:
+ children_cdg.addErrorInfo(i_info, i_object);
+ break;
+
+ case EI_TYPE_COLLECT_TRACE:
+ collect_trace.addErrorInfo(i_info, i_object);
+ break;
+ };
+
+ return;
+ }
+};
+#endif
+}
+#endif // FAPI2_ERRORINFO_H_
diff --git a/src/hwpf/include/error_info_defs.H b/src/hwpf/include/error_info_defs.H
new file mode 100644
index 00000000..0f425b1f
--- /dev/null
+++ b/src/hwpf/include/error_info_defs.H
@@ -0,0 +1,331 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/error_info_defs.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 error_info_defs.H
+/// @brief Defines to support the Error Information class
+///
+
+#ifndef FAPI2_ERRORINFO_DEFS_H_
+#define FAPI2_ERRORINFO_DEFS_H_
+
+#include <stdint.h>
+#include <target.H>
+#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC)
+#include <variable_buffer.H>
+#include <utility>
+#endif
+namespace fapi2
+{
+
+///
+/// @brief Type to hold the ffdc data to be returned to caller
+/// when error occurs in sbe environment.
+///
+/// Note: Typical data sent seems to be register/addresss info
+/// rather than use extra space converting stuff just
+/// send a uint64 always
+///
+struct sbeFfdc_t
+{
+ uint32_t size;
+ uint64_t data;
+};
+
+// Data type for SBE ffdc buffer sent through fifo
+typedef struct
+{
+ uint32_t fapiRc; // Return code from failure
+ uint32_t ffdcLength; // length of Fapi FFDC data (in bytes)
+ struct sbeFfdc_t ffdcData[10]; // fapi FFDC data
+} SbeFfdcData_t; // 128 bytes
+
+///
+/// @brief Type to hold the ffdc element in the ffdc class
+/// Needed so that the size can be squirled away before the
+/// macro is called.
+///
+struct ffdc_struct
+{
+ const void* ptr;
+ int16_t size;
+};
+
+
+class ffdc_t
+{
+ public:
+ ffdc_t(void)
+ {}
+
+ void operator=(const ffdc_t& i )
+ {
+ iv_value.ptr = i.ptr();
+ iv_value.size = i.size();
+ }
+
+ operator const void* () const
+ {
+ return iv_value.ptr;
+ }
+ operator uint8_t() const
+ {
+ return *(reinterpret_cast<const uint8_t*>(iv_value.ptr));
+ }
+
+ int16_t size(void) const
+ {
+ return iv_value.size;
+ }
+ int16_t& size(void)
+ {
+ return iv_value.size;
+ }
+
+ const void* ptr(void) const
+ {
+ return iv_value.ptr;
+ }
+ const void*& ptr(void)
+ {
+ return iv_value.ptr;
+ }
+
+ private:
+ struct ffdc_struct iv_value;
+};
+
+///
+/// @brief Enumeration of ErrorInfo FFDC sizes that are used to indicate a
+/// special type that cannot simply be memcopied
+enum ErrorInfoFfdcSize
+{
+ EI_FFDC_SIZE_BUF = 0xffff, // fapi2::buffer<T>
+ EI_FFDC_SIZE_TARGET = 0xfffe, // fapi2::Target
+ EI_FFDC_SIZE_VBUF = 0xfffd, // fapi2::variable_buffer
+ EI_FFDC_MAX_SIZE = 0x1000, // Limit regular FFDC capture to 4kb
+};
+
+///
+/// @brief Enumeration of error log severity.
+///
+enum errlSeverity_t
+{
+ FAPI2_ERRL_SEV_UNDEFINED = 0x00, /// Used internally by ffdc mechanism
+ FAPI2_ERRL_SEV_RECOVERED = 0x10, /// Not seen by customer
+ FAPI2_ERRL_SEV_PREDICTIVE = 0x20, /// Error recovered but customer will see
+ FAPI2_ERRL_SEV_UNRECOVERABLE = 0x40 /// Unrecoverable, general
+};
+
+///
+/// @brief Enumeration of ErrorInfo types
+///
+enum ErrorInfoType
+{
+ EI_TYPE_FFDC = 0,
+ EI_TYPE_HW_CALLOUT = 1,
+ EI_TYPE_PROCEDURE_CALLOUT = 2,
+ EI_TYPE_BUS_CALLOUT = 3,
+ EI_TYPE_CDG = 4, // Target Callout/Deconfig/GARD
+ EI_TYPE_CHILDREN_CDG = 5, // Children Callout/Deconfig/GARD
+ EI_TYPE_COLLECT_TRACE = 6,
+ EI_LAST_TYPE = EI_TYPE_COLLECT_TRACE + 1,
+};
+
+#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC)
+///
+/// @enum HwCallout
+///
+/// This enumeration defines the possible Hardware Callouts that are not
+/// represented by fapi2::Targets
+///
+/// Note that platform code may depend on the enum values starting at 0 and
+/// incrementing in order to efficiently convert to a platform callout value
+/// so do not reorder without consulting all platforms
+///
+namespace HwCallouts
+{
+enum HwCallout
+{
+ // Where indicated, a HW Callout in FAPI Error XML must include a
+ // reference target that is used to identify the HW. e.g. for
+ // TOD_CLOCK, the proc chip that the clock is attached to must be
+ // specified
+ TOD_CLOCK = 0, // Include proc-chip ref (or child chiplet)
+ MEM_REF_CLOCK = 1, // Include membuf-chip ref (or child chiplet)
+ PROC_REF_CLOCK = 2, // Include proc-chip ref (or child chiplet)
+ PCI_REF_CLOCK = 3, // Include proc-chip ref (or child chiplet)
+ FLASH_CONTROLLER_PART = 4,
+ PNOR_PART = 5,
+ SBE_SEEPROM_PART = 6,
+ VPD_PART = 7,
+ LPC_SLAVE_PART = 8,
+ GPIO_EXPANDER_PART = 9,
+ SPIVID_SLAVE_PART = 10,
+};
+}
+
+///
+/// @enum ProcedureCallout
+///
+/// This enumeration defines the possible Procedure Callouts
+/// These instruct the customer/customer-engineer what to do
+///
+/// Note that platform code may depend on the enum values starting at 0 and
+/// incrementing in order to efficiently convert to a platform callout value
+/// so do not reorder without consulting all platforms
+///
+namespace ProcedureCallouts
+{
+enum ProcedureCallout
+{
+ CODE = 0, // Code problem
+ LVL_SUPPORT = 1, // Call next level of support
+ MEMORY_PLUGGING_ERROR = 2, // DIMM Plugging error
+ BUS_CALLOUT = 3, // Bus Called Out
+};
+}
+
+///
+/// @enum CalloutPriority
+///
+/// This enumeration defines the possible Procedure and Target callout priorities
+///
+/// Note that platform code may depend on the enum values starting at 0 and
+/// incrementing in order to efficiently convert to a platform priority value
+/// so do not reorder without consulting all platforms
+///
+namespace CalloutPriorities
+{
+enum CalloutPriority
+{
+ LOW = 0,
+ MEDIUM = 1,
+ HIGH = 2,
+};
+}
+
+///
+/// @enum CollectTrace
+///
+/// This enumeration defines the possible firmware traces to collect
+///
+namespace CollectTraces
+{
+const uint32_t TRACE_SIZE = 256; // limit collected trace size
+enum CollectTrace
+{
+ FSI = 1,
+ SCOM = 2,
+ SCAN = 3,
+ MBOX = 4,
+};
+}
+
+///
+/// @brief Get FFDC Data from FIFO buffer
+///
+/// This is called by hwsv/hb ffdc code when an error is returned in the
+/// sbe fifo area. It will translate the data based on type and convert
+/// the local data size to the correct length based on the known data size.
+///
+/// NOTE - this assumes no buffers are passed - mistake? maybe
+inline fapi2::ffdc_t getFfdcData( sbeFfdc_t& i_sbeFfdc )
+{
+ fapi2::ffdc_t temp;
+
+ // passed in size is a uint32_t but, needs to be uint16_t
+ temp.size() = static_cast<uint16_t>(i_sbeFfdc.size);
+
+ if(i_sbeFfdc.size == EI_FFDC_SIZE_TARGET )
+ {
+ fapi2::TargetType type = TARGET_TYPE_EX;
+ uint64_t targetData = i_sbeFfdc.data;
+ // call hostboot to get the fapi2 target
+ temp.ptr() = static_cast<void*>(getTarget((targetData >> 32), static_cast<uint8_t>(targetData & 0xFFFFFFFF)));
+ }
+ else
+ {
+ // adjust the pointer based on the data size.
+ temp.ptr() = reinterpret_cast<uint8_t*>(&i_sbeFfdc.data) + (sizeof(uint64_t) - i_sbeFfdc.size);
+ }
+
+ return temp;
+}
+#endif
+///
+/// @brief Get FFDC Size
+///
+/// This is called by the FAPI_SET_HWP_ERROR macro to find out the size of
+/// FFDC data. If the data is of a special type that is handled differently
+/// than types that are simply memcopied then it is handled by a template
+/// specialization.
+/// If this function template is instantiated with a pointer, the compile
+/// will fail.
+///
+/// @return uint16_t. Size of the FFDC data
+///
+template<typename T>
+inline uint16_t getErrorInfoFfdcSize(const T&)
+{
+ static_assert(sizeof(T) <= EI_FFDC_MAX_SIZE,
+ "FFDC too large to capture");
+ return sizeof(T);
+}
+#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC)
+///
+/// @brief Compile error if caller tries to get the FFDC size of a pointer
+///
+template<typename T>
+inline uint16_t getErrorInfoFfdcSize(const T*)
+{
+ static_assert(std::is_pointer<T>::value,
+ "pointer passed to getErrorInfoFfdcSize");
+ return 0;
+}
+#endif
+///
+/// @brief Get FFDC Size specialization for fapi2::Target
+///
+template<fapi2::TargetType T>
+inline uint16_t getErrorInfoFfdcSize(const fapi2::Target<T>&)
+{
+ return EI_FFDC_SIZE_TARGET;
+}
+
+#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC)
+///
+/// @brief Get FFDC Size specialization for variable buffers
+///
+template<>
+inline uint16_t getErrorInfoFfdcSize(const fapi2::variable_buffer& i_thing)
+{
+ // Limit a variable buffer to 4kb bytes, and we can memcpy the storage.
+ return std::min(static_cast<uint32_t>(EI_FFDC_MAX_SIZE),
+ i_thing.getLength<uint8_t>());
+}
+#endif
+};
+
+#endif // FAPI2_ERRORINFO_DEFS_H_
diff --git a/src/hwpf/include/fapi2.H b/src/hwpf/include/fapi2.H
new file mode 100644
index 00000000..136c69e2
--- /dev/null
+++ b/src/hwpf/include/fapi2.H
@@ -0,0 +1,77 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/fapi2.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 fapi2.H
+/// @brief top level header for fapi2
+///
+
+#ifndef __FAPI2_TOP_LEVEL__
+#define __FAPI2_TOP_LEVEL__
+
+// Define which platforms will not have FAPI Return Codes
+#undef __noRC__
+#if defined (__CME__) || defined (__SGPE__) || defined (__PGPE__)
+#define __noRC__
+#endif
+
+// Determine if running on a PPE platform
+#ifndef __PPE__
+#if defined (__SBE__) || defined (__CME__) || defined (__SGPE__) || defined (__PGPE__)
+#define __PPE__
+#endif
+#endif
+
+#include <plat_trace.H>
+#include <target.H>
+#include <return_code.H>
+#include <buffer.H>
+#include <hw_access.H>
+#include <utils.H>
+
+// In turn includes the needed generated headers (hwp_ffd_classes, etc.)
+#include <error_scope.H>
+#include <set_sbe_error.H> // Generated file
+#include <plat_attributes.H>
+#include <plat_target_utils.H>
+
+// Not supported by PPE
+#ifndef __PPE__
+#include <mvpdAccess.H>
+#endif
+
+#include <fapi2_hwp_executor.H>
+
+// Block of headers not currently in fapi2
+#ifdef FAPI2_MISSING_HEADERS
+ #include <mbvpdAccess.H>
+#endif
+
+
+#endif // __FAPI2_TOP_LEVEL__
+
+
+
+
+
+
diff --git a/src/hwpf/include/fapi2AttributeService.H b/src/hwpf/include/fapi2AttributeService.H
new file mode 100644
index 00000000..1f8eca5a
--- /dev/null
+++ b/src/hwpf/include/fapi2AttributeService.H
@@ -0,0 +1,150 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/fapi2AttributeService.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 fapi2AttributeService.H
+///
+/// @brief Defines the FAPI_ATTR_GET and FAPI_ATTR_SET macros that a user
+/// calls to get/set attributes and a check function that the macros use to
+/// verify correct usage
+///
+
+#ifndef FAPI2ATTRIBUTESERVICE_H_
+#define FAPI2ATTRIBUTESERVICE_H_
+#include <stdint.h>
+//#include <attribute_ids.H>
+#include <fapi2AttributeIds.H>
+#include <target.H>
+#include <target_types.H>
+//#include <plat_attribute_service.H>
+#include <fapi2PlatAttributeService.H>
+
+/// @brief Macros called by user to get/set attributes for FAPI2 targets
+///
+/// Code must have a reference to a FAPI2 Target and an attribute ID (from
+/// XML file):
+/// fapi2::ReturnCode l_rc;
+/// fapi2::Target<target type>& l_target = ????;
+/// Ex: Target<TARGET_TYPE_PROC_CHIP>& l_target = ????;
+///
+/// To get a copy of an integer attribute and set the attribute
+/// uint64_t l_val = 0;
+/// l_rc = FAPI_ATTR_GET(<ID>, l_target, l_val);
+/// l_rc = FAPI_ATTR_SET(<ID>, l_target, l_val);
+///
+/// To get a copy of an integer array attribute and set the attribute
+/// uint32_t l_pVal[4] = {0};
+/// l_rc = FAPI_ATTR_GET(<ID>, l_target, l_pVal);
+/// l_rc = FAPI_ATTR_SET(<ID>, l_target, l_pVal);
+///
+/// A priveleged attribute is one that a HWP should not generally access,
+/// examples include ATTR_NAME and ATTR_EC, where usage can lead to a non
+/// data-driven design. A privileged attribute can be accessed with
+/// FAPI_ATTR_GET_PRIVILEGED and FAPI_ATTR_SET_PRIVILEGED
+///
+/// The non-PRIVILEGED macros first call a template function (compiler will
+/// optimize out) that will cause a compile failure if the attribute is
+/// privileged, they then call a PRIVILEGED macro to get/set the attribute
+///
+/// The PRIVILEGED macros call a template function (compiler will optimize out)
+/// that will cause a compile failure if the ID is not valid or VAL is not the
+/// correct type.
+//
+
+#define FAPI_ATTR_GET(ID, TARGET, VAL) \
+ (fapi2::failIfPrivileged<ID##_Privileged>(), \
+ fapi2::checkIdType<ID##_Type>(ID, VAL), \
+ ID##_GETMACRO(ID, TARGET, VAL))
+
+#define FAPI_ATTR_SET(ID, TARGET, VAL) \
+ (fapi2::failIfPrivileged<ID##_Privileged>(), \
+ fapi2::checkIdType<ID##_Type>(ID, VAL), \
+ ID##_SETMACRO(ID, TARGET, VAL))
+
+#define FAPI_ATTR_GET_PRIVILEGED(ID, TARGET, VAL) \
+ (fapi2::checkIdType<ID##_Type>(ID, VAL), \
+ ID##_GETMACRO(ID, TARGET, VAL))
+
+#define FAPI_ATTR_SET_PRIVILEGED(ID, TARGET, VAL) \
+ (fapi2::checkIdType<ID##_Type>(ID, VAL), \
+ ID##_SETMACRO(ID, TARGET, VAL))
+
+namespace fapi2
+{
+
+///
+/// @brief Get an InitFile attribute for FAPI2
+///
+/// This function gets a copy of an attribute. In the case of an array attribute,
+/// The value in the specified index is retrieved. This should be used by the
+/// InitFile HWP only, that HWP processes a binary InitFile and therefore needs
+/// to read a variable ID of a variable data type. Standard HWPs should use the
+/// FAPI2_ATTR_GET macro which automatically checks the type for correct usage.
+///
+/// If there are ever attributes with more than 4 dimensions then this function
+/// will need to be updated.
+///
+/// @Tparam K template parameter, passed in target.
+/// @param[in] i_id AttributeID
+/// @param[in] i_target Reference to fapi2::Target (can be NULL for system)
+/// @param[out] o_val Reference to uint64_t where attribute value is set
+/// @param[in] i_arrayIndex1 If array attribute then index1
+/// @param[in] i_arrayIndex2 If at least 2D array attribute then index2
+/// @param[in] i_arrayIndex3 If at least 3D array attribute then index3
+/// @param[in] i_arrayIndex4 If at least 4D array attribute then index4
+///
+/// @return ReturnCode. Zero if success
+///
+template< TargetType K >
+ReturnCode getInitFileAttr(const AttributeId i_id,
+ const Target<K>& i_target,
+ uint64_t & o_val,
+ const uint32_t i_arrayIndex1 = 0,
+ const uint32_t i_arrayIndex2 = 0,
+ const uint32_t i_arrayIndex3 = 0,
+ const uint32_t i_arrayIndex4 = 0);
+
+/**
+ * @brief Check the ID and TYPE
+ *
+ * This is called by FAPI code to check at compile time that a FAPI attribute
+ * access is using the correct data type and a valid AttributeId
+ */
+template<typename T> inline void checkIdType(AttributeId, T &) {}
+
+/**
+ * @brief Fail if attribute privileged
+ *
+ * This is called by FAPI code to check at compile time that a standard FAPI
+ * attribute access (FAPI_ATTR_GET) is not accessing a privileged attribute
+ */
+class ErrorAccessingPrivilegedAttribute;
+template<const bool PRIVILEGED> void failIfPrivileged()
+{
+ ErrorAccessingPrivilegedAttribute();
+}
+template <> inline void failIfPrivileged<false>() {}
+
+}
+
+#endif // FAPI2ATTRIBUTESERVICE_H_
diff --git a/src/hwpf/include/fapi2Structs.H b/src/hwpf/include/fapi2Structs.H
new file mode 100644
index 00000000..75584f2b
--- /dev/null
+++ b/src/hwpf/include/fapi2Structs.H
@@ -0,0 +1,132 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/fapi2Structs.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 fapiStructs_h
+#define fapiStructs_h
+// Copyright **********************************************************
+//
+// File fapiStructs.H
+//
+// IBM Confidential
+// OCO Source Materials
+// 9400 Licensed Internal Code
+// (C) COPYRIGHT IBM CORP. 1996
+//
+// The source code for this program is not published or otherwise
+// divested of its trade secrets, irrespective of what has been
+// deposited with the U.S. Copyright Office.
+//
+// End Copyright ******************************************************
+
+/**
+ * @file fapiStructs.H
+ * @brief fapi eCMD Extension Structures
+
+ * Extension Owner : John Farrugia
+*/
+
+//--------------------------------------------------------------------
+// Includes
+//--------------------------------------------------------------------
+#include <string>
+
+
+//--------------------------------------------------------------------
+// Forward References
+//--------------------------------------------------------------------
+
+#define ECMD_FAPI_CAPI_VERSION "1.0" ///< eCMD FAPI Extension version
+
+
+
+#ifndef ECMD_PERLAPI
+
+namespace fapi
+{
+
+/**
+ * @brief Enumeration of fapi file types
+ */
+typedef enum {
+ FAPI_FILE_UNKNOWN, ///< Default for not initialized
+ FAPI_FILE_HWP
+} FileType_t;
+
+
+enum AttributeSource
+{
+ FAPI_ATTRIBUTE_SOURCE_UNKNOWN = 0x00000000,
+ FAPI_ATTRIBUTE_SOURCE_PLAT = 0x00000001,
+ FAPI_ATTRIBUTE_SOURCE_HWP = 0x00000002,
+};
+
+
+#define FAPI_ATTRIBUTE_TYPE_STRING 0x80000000
+#define FAPI_ATTRIBUTE_TYPE_UINT8 0x40000000
+#define FAPI_ATTRIBUTE_TYPE_UINT32 0x20000000
+#define FAPI_ATTRIBUTE_TYPE_UINT64 0x10000000
+#define FAPI_ATTRIBUTE_TYPE_UINT8ARY 0x04000000
+#define FAPI_ATTRIBUTE_TYPE_UINT32ARY 0x02000000
+#define FAPI_ATTRIBUTE_TYPE_UINT64ARY 0x01000000
+
+#define FAPI_ATTRIBUTE_MODE_CONST 0x80000000
+/**
+ @brief Used by the get/set configuration functions to return the data
+*/
+template<typename T>
+class Attribute
+{
+public:
+ // Constructor
+ Attribute();
+
+ // Destructor
+ ~Attribute();
+
+ //
+ /// @brief Assignment Operator.
+ /// @param[in] i_right Reference to Value to assign from.
+ /// @return Reference to 'this' Target
+ ///
+ Attribute<T>& operator=(const T& i_right)
+ {
+ this->value = i_right->value;
+ }
+
+private:
+ T value;
+
+};
+
+inline AttributeData::AttributeData() {}
+
+inline AttributeData::~AttributeData() {}
+
+} //namespace
+#endif // #ifndef ECMD_PERLAPI
+#endif
+
+
+
+
+
diff --git a/src/hwpf/include/fapi2_hw_access.H b/src/hwpf/include/fapi2_hw_access.H
new file mode 100644
index 00000000..f4af3515
--- /dev/null
+++ b/src/hwpf/include/fapi2_hw_access.H
@@ -0,0 +1,464 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/fapi2_hw_access.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 fapi2_hw_access.H
+/// @brief Common file that defines the hardware access functions that
+/// platform code must implement.
+///
+
+#ifndef _FAPI2_COMMON_HWACCESS_H_
+#define _FAPI2_COMMON_HWACCESS_H_
+
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+#include <spy_ids.H>
+typedef uint64_t spyId_t;
+#endif
+
+#include <stdint.h>
+#include <buffer.H>
+
+// thread/variable_buffer isn't supported on PPE
+#ifndef __PPE__
+#include <thread>
+#include <variable_buffer.H>
+#endif
+
+#include <return_code.H>
+#include <target.H>
+#include <hw_access_def.H>
+#include <plat_hw_access.H>
+#include "imageProcs/p9_ringId.H"
+
+#ifdef FAPI_SUPPORT_MULTI_SCOM
+#include <multi_scom.H>
+#endif
+
+namespace fapi2
+{
+ //--------------------------------------------------------------------------
+ // PIB Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Sets the PIB error mask - platform dependant
+ /// @param[in] i_mask The new error mask
+ inline void setPIBErrorMask(uint8_t i_mask);
+
+ /// @brief Gets the PIB error mask - platform dependant
+ /// @return uint8_t The current PIB error mask
+ inline uint8_t getPIBErrorMask(void);
+
+ //--------------------------------------------------------------------------
+ // Operational Mode Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Sets the operational mode
+ /// @param[in] i_mode The new mode
+ inline void setOpMode(const OpModes i_mode);
+
+ /// @brief Gets the operational mode
+ /// @return the operational mode
+ inline OpModes getOpMode(void);
+
+ //--------------------------------------------------------------------------
+ // HW Communication Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Reads a SCOM register from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ __attribute__((always_inline))
+ inline ReturnCode getScom(const Target<K, V>& i_target, const uint64_t i_address,
+ buffer<uint64_t>& o_data);
+
+ /// @brief Writes a SCOM register on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ __attribute__((always_inline))
+ inline ReturnCode putScom(const Target<K, V>& i_target, const uint64_t i_address,
+ const buffer<uint64_t> i_data);
+
+ /// @brief Writes a SCOM register under mask on a chip
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @param[in] i_mask Buffer that holds the mask value.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode putScomUnderMask(const Target<K, V>& i_target,
+ const uint64_t i_address,
+ const buffer<uint64_t> i_data,
+ const buffer<uint64_t> i_mask);
+
+ /// @brief Reads a CFAM register from a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode getCfamRegister(const Target<K, V>& i_target,
+ const uint32_t i_address,
+ buffer<uint32_t>& o_data);
+
+ /// @brief Writes a CFAM register on a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode putCfamRegister(const Target<K, V>& i_target,
+ const uint32_t i_address,
+ const buffer<uint32_t> i_data);
+
+ /// @brief Read-modify-write a CFAM register on a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to modify.
+ /// @param[in] i_data Buffer that holds data to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor).
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode modifyCfamRegister(const Target<K, V>& i_target,
+ const uint32_t i_address,
+ const buffer<uint32_t> i_data,
+ const ChipOpModifyMode i_modifyMode);
+
+/// @brief Writes a ring to a chip.
+/// @tparam K template parameter, passed in target.
+/// @param[in] i_target Target to operate on.
+/// @param[in] i_RingID Ring ID to write to.
+/// @param[in] i_ringMode Ring operation mode.
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+template< TargetType K, typename V >
+inline ReturnCode putRing(const Target<K, V>& i_target,
+ const RingID i_ringID,
+ const RingMode i_ringMode = RING_MODE_HEADER_CHECK);
+
+ // variable_buffer isn't supported on PPE
+#ifndef __PPE__
+ /// @brief Reads a ring from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode getRing(const Target<K, V>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& o_data,
+ const RingMode i_ringMode = 0);
+
+
+
+ /// @brief Read-modify-write a ring on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to modify.
+ /// @param[in] i_data Buffer that contains RS4 compressed ring data
+ /// to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor)
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode modifyRing(const Target<K, V>& i_target,
+ const scanRingId_t i_address,
+ const variable_buffer& i_data,
+ const ChipOpModifyMode i_modifyMode,
+ const RingMode i_ringMode = 0);
+#endif
+
+#ifdef FAPI_SUPPORT_MULTI_SCOM
+ /// @brief Performs a multiple SCOM operation
+ /// This interface performs multiple SCOM operations on a chip in the
+ /// order specified by the input MultiScom object.
+ /// See fapiMultiScom.H for details of how to populate the MultiScom
+ /// object with SCOM operations.
+ ///
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in,out] io_multiScomObj Reference to a MultiScom object,
+ /// pre-populated with SingleScomInfo entries
+ /// to perform multiple SCOMs on input target
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note This is a synchronous interface and would return after all the
+ /// SCOM operations are completed or on the first failed operation
+ ///
+ /// @note SCOMs will be performed in the order they were added to the
+ /// input MultiScom object
+ ///
+ /// @note In case of errors, the platform code is responsible to collect
+ /// and add all the required error info and FFDC into the error data
+ /// for debugging
+ ///
+ /// @note If the SCOM operations added are specific to a processor chip,
+ /// then the FSI Shift Engine configured in scatter-gather DMA mode
+ /// extension would be used to execute the SCOM operations in a
+ /// performance optimize mode. In this mode, the special
+ /// SCOM_BULK_READ_MODE and SCOM_BULK_WRITE_MODE operations are
+ /// supported that allow a large bulk of SCOM access (in multiple of
+ /// 64 bits) for targets that support auto-increment. The
+ /// SCOM_WRITE_UNDER_MASK operation is not supported in this mode
+ ///
+ /// @note If the SCOM operations added are specific to a memory buffer
+ /// chip, then the regular SCOM engine is used to execute the SCOM
+ /// operations. SCOM_WRITE_UNDER_MASK operation is supported in
+ /// this mode, but the special SCOM_BULK_READ_MODE and
+ /// SCOM_BULK_WRITE_MODE operations are not supported due to
+ /// hardware limitations.
+ ///
+ template< TargetType K, typename V >
+ fapi2::ReturnCode multiScom (const Target<K, V>& i_target,
+ MultiScom& io_multiScomObj);
+#endif
+
+ // --------------------------------------------------------------------------
+ // NOTE:
+ // Implement platform Spy access functions if platform supports them.
+ // --------------------------------------------------------------------------
+
+ // variable_buffer isn't supported on PPE
+#ifndef __PPE__
+ /// @brief Reads a spy from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy whose data to be read.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependant on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// it with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi2::ReturnCode rc = fapiGetSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN)
+
+#define FAPI_GET_SPY(TARGET, ID, DATA) fapi2::getSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA)
+
+ template< TargetType K, typename V >
+ inline ReturnCode getSpy(const Target<K, V>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+
+#define FAPI_GET_SPY(TARGET, ID, DATA) fapi2::getSpy(TARGET, #ID, DATA)
+
+ template< TargetType K, typename V >
+ inline ReturnCode getSpy(const Target<K, V>& i_target,
+ const char * const i_spyId,
+ variable_buffer& o_data);
+#endif
+
+ /// @brief Writes a spy on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy to write data to.
+ /// @param[out] i_data Buffer that holds data to write into spy.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// is with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi2::ReturnCode rc = fapiPutSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+ ///
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN)
+
+#define FAPI_PUT_SPY(TARGET, ID, DATA) fapi2::putSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA)
+
+ template< TargetType K, typename V >
+ inline ReturnCode putSpy(const Target<K, V>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& i_data);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+
+#define FAPI_PUT_SPY(TARGET, ID, DATA) fapi2::putSpy(TARGET, #ID, DATA)
+
+ template< TargetType K, typename V >
+ inline ReturnCode putSpy(const Target<K, V>& i_target,
+ const char* const i_spyId,
+ variable_buffer& i_data);
+#endif
+
+ /// @brief Writes spy data into a buffer holding ring data image
+ /// This API is used by L2/L3 repair to put column repair data
+ /// into a ring buffer image.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy.
+ /// @param[in] i_data Buffer that holds spy data to write into ring
+ /// image.
+ /// @param[out] o_data Buffer that holds updated ring image.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN)
+
+#define FAPI_PUT_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \
+ fapi2::putSpyImage(TARGET, FAPI_SPY_NAMES::ID.value, \
+ DATA1, DATA2)
+
+ template< TargetType K, typename V >
+ inline ReturnCode putSpyImage(const Target<K, V>& i_target,
+ const spyId_t i_spyId,
+ const variable_buffer& i_data,
+ variable_buffer& o_imageData);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+
+#define FAPI_PUT_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \
+ fapi2::putSpyImage(TARGET, #ID, DATA1,DATA2)
+
+ template< TargetType K, typename V >
+ inline ReturnCode putSpyImage(const Target<K, V>& i_target,
+ const char* const i_spyId,
+ const variable_buffer& i_data,
+ variable_buffer& o_imageData);
+#endif
+
+ /// @brief Reads spy data from a ring image buffer
+ /// @param[in] i_target Target to operate on
+ /// @param[in] i_spyId The spy's id
+ /// @param[out] o_data Buffer that holds data read from ring image.
+ /// @param[in] i_imageData Buffer that holds ring image to read data
+ /// from.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN)
+
+#define FAPI_GET_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \
+ fapi2:getSpyImage(TARGET, FAPI_SPY_NAMES::ID.value, \
+ DATA1, DATA2)
+
+ template< TargetType K, typename V >
+ inline ReturnCode getSpyImage(const Target<K, V>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data,
+ const variable_buffer& i_imageData);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+
+#define FAPI_GET_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \
+ fapi2::getSpyImage(TARGET, #ID, DATA1,DATA2)
+
+ template< TargetType K, typename V >
+ inline ReturnCode getSpyImage(const Target<K, V>& i_target,
+ const char * const i_spyId,
+ variable_buffer& o_data,
+ const variable_buffer& i_imageData);
+#endif
+
+#endif // PPE
+};
+
+#endif // _FAPI2_HWACCESS_H_
diff --git a/src/hwpf/include/fapi2_target.H b/src/hwpf/include/fapi2_target.H
new file mode 100644
index 00000000..6c031b7c
--- /dev/null
+++ b/src/hwpf/include/fapi2_target.H
@@ -0,0 +1,588 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/fapi2_target.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 fapi2_target.H
+/// @brief Common definitions for fapi2 targets
+///
+
+#ifndef __FAPI2_COMMON_TARGET__
+#define __FAPI2_COMMON_TARGET__
+
+#include <stdint.h>
+#include <vector>
+#include <target_types.H>
+#include <target_states.H>
+#include <plat_target.H>
+
+namespace fapi2
+{
+
+
+ ///
+ /// @brief Typedef for chiplet number values
+ ///
+ typedef uint8_t ChipletNumber_t;
+
+ ///
+ /// @brief Class representing a FAPI2 Target
+ /// @tparam K the type (Kind) of target
+ /// @tparam V the type of the target's Value
+ /// @remark TargetLite targets are uint64_t, Targets
+ /// are uintptr_t (void*).
+ ///
+ /// Assuming there are representations of a processor,
+ /// a membuf and a system here are some examples:
+ /// @code
+ /// #define PROCESSOR_CHIP_A 0xFFFF0000
+ /// #define MEMBUF_CHIP_B 0x0000FFFF
+ /// #define SYSTEM_C 0x0000AAAA
+ /// @endcode
+ ///
+ /// * To define a target:
+ /// @code
+ /// fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> A(PROCESSOR_CHIP_A);
+ /// fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> C(SYSTEM_C);
+ /// fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> B(MEMBUF_CHIP_B);
+ /// @endcode
+ ///
+ /// * Functions which take composite target types
+ /// @code
+ /// void takesProcOrMembuf(
+ /// const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP |
+ /// fapi2::TARGET_TYPE_MEMBUF_CHIP>& V );
+ ///
+ /// void takesAny(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& V );
+ ///
+ /// @endcode
+ ///
+ /// * Traversing the target "tree"
+ /// @code
+ /// fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> A(PROCESSOR_CHIP_A);
+ ///
+ /// // Get A's parent
+ /// A.getParent<fapi2::TARGET_TYPE_SYSTEM>();
+ ///
+ /// // Get the 0x53'd core
+ /// fapi2::getTarget<fapi2::TARGET_TYPE_CORE>(0x53);
+ ///
+ /// // Get all *my* present/functional children which are cores
+ /// A.getChildren<fapi2::TARGET_TYPE_CORE>();
+ ///
+ /// // Get all of the the cores relative to my base target
+ /// fapi2::getChildren<fapi2::TARGET_TYPE_CORE>();
+ /// @endcode
+ ///
+ /// * Invalid casts
+ /// @code
+ /// // Can't cast to a specialized target
+ /// fapi2::Target<fapi2::TARGET_TYPE_NONE> D(MEMBUF_CHIP_B);
+ /// takesProcOrMembuf( D );
+ ///
+ /// // Not one of the shared types
+ /// fapi2::Target<fapi2::TARGET_TYPE_ABUS_ENDPOINT> E;
+ /// takesProcOrMembuf( E );
+ /// @endcode
+ template<TargetType K, typename V = plat_target_handle_t>
+ class Target
+ {
+ public:
+
+ ///
+ /// @brief Delagate default constructor to constructor
+ /// that takes in a value as a param
+ ///
+ Target(): Target(V())
+ {};
+
+ ///
+ /// @brief Create a Target, with a value
+ /// @param[in] Value the value (i.e., specific element this
+ /// target represents, or pointer)
+ /// @note Platforms can mangle the value and K to get a
+ /// single uint64_t in value which represents all the information
+ /// they might need. value( K | V ), for example
+ ///
+ Target(const V& Value):
+ iv_handle(Value)
+ {};
+
+ ///
+ /// @brief Assignment Operator.
+ /// @param[in] i_right Reference to Target to assign from.
+ /// @return Reference to 'this' Target
+ ///
+ Target& operator=(const Target& i_right);
+
+ ///
+ /// @brief Equality Comparison Operator
+ /// @param[in] i_right Reference to Target to compare.
+ /// @return bool. True if equal.
+ /// @note Platforms need to define this so that the physical
+ /// targets are determined to be equivilent rather than just the handles
+ ///
+ bool operator==(const Target& i_right) const;
+
+ ///
+ /// @brief Inquality Comparison Operator
+ /// @param[in] i_right Reference to Target to compare.
+ /// @return bool. True if not equal.
+ /// @note Platforms need to define this so that the physical
+ /// targets are determined to be equivilent rather than just the handles
+ ///
+ bool operator!=(const Target& i_right) const;
+
+ ///
+ /// @brief Get the handle.
+ /// @return V The target's handle, or value
+ ///
+ V get(void) const
+ {
+ return iv_handle;
+ }
+
+ ///
+ /// @brief Get the handle as a V
+ /// @return V The target's handle, or value
+ ///
+ inline operator V() const
+ {
+ return iv_handle;
+ }
+
+ ///
+ /// @brief Get a target's value
+ /// @return V The target's handle, or value
+ ///
+ inline V& operator()(void)
+ {
+ return iv_handle;
+ }
+
+ ///
+ /// @brief Get the target type
+ /// @return The type of target represented by this target
+ ///
+ inline TargetType getType(void) const
+ {
+ return iv_type;
+ }
+
+ ///
+ /// @brief Get this target's immediate parent
+ /// @tparam T The type of the parent
+ /// @return Target<T, V> a target representing the parent
+ ///
+ template< TargetType T>
+ inline Target<T, V> getParent(void) const;
+
+ ///
+ /// @brief Is this target a chip?
+ /// @return Return true if this target is a chip, false otherwise
+ ///
+ inline constexpr bool isChip(void) const
+ {
+// return ( (K == TARGET_TYPE_PROC_CHIP) ||
+// (K == TARGET_TYPE_MEMBUF_CHIP) );
+
+ return ( (K == TARGET_TYPE_PROC_CHIP) );
+ }
+
+ ///
+ /// @brief Is this target a chiplet?
+ /// @return Return true if this target is a chiplet, false otherwise
+ ///
+ inline constexpr bool isChiplet(void) const
+ {
+ return ( (K == TARGET_TYPE_EX) ||
+// (K == TARGET_TYPE_MBA) ||
+ (K == TARGET_TYPE_MCS) ||
+// (K == TARGET_TYPE_XBUS) ||
+// (K == TARGET_TYPE_ABUS) ||
+// (K == TARGET_TYPE_L4) ||
+ (K == TARGET_TYPE_CORE) ||
+ (K == TARGET_TYPE_EQ) ||
+// (K == TARGET_TYPE_MCA) ||
+// (K == TARGET_TYPE_MCBIST) ||
+// (K == TARGET_TYPE_MI) ||
+// (K == TARGET_TYPE_DMI) ||
+// (K == TARGET_TYPE_OBUS) ||
+// (K == TARGET_TYPE_NV) ||
+// (K == TARGET_TYPE_SBE) ||
+// (K == TARGET_TYPE_PPE) ||
+// (K == TARGET_TYPE_PERV) ||
+ (K == TARGET_TYPE_PERV) );
+// (K == TARGET_TYPE_PEC) ||
+// (K == TARGET_TYPE_PHB) );
+ }
+
+ ///
+ /// @brief Get this target's children
+ /// @tparam T The type of the parent
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return std::vector<Target<T, V> > a vector of present/functional
+ /// children
+ /// @warning The children of EX's (cores) are expected to be returned
+ /// in order. That is, core 0 is std::vector[0].
+ ///
+ template< TargetType T>
+ std::vector<Target<T, V> >
+ getChildren(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const;
+
+ ///
+ /// @brief Get this target's children, filtered
+ /// @tparam T The type of the parent
+ /// @param[in], i_filter The desired chiplet filter
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return std::vector<Target<T, V> > a vector of present/functional
+ /// children
+ ///
+ template< TargetType T>
+ std::vector<Target<T, V>>
+ getChildren(const TargetFilter i_filter,
+ const TargetState i_state = TARGET_STATE_FUNCTIONAL) const;
+
+ ///
+ /// @brief Get the target at the other end of a bus - dimm included
+ /// @tparam T The type of the parent
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return Target<T, V> a target representing the thing on the other end
+ /// @note Can be easily changed to a vector if needed
+ ///
+ template<TargetType T>
+ inline Target<T, V>
+ getOtherEnd(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const;
+
+ ///
+ /// @brief Is the target functional?
+ /// @return true if target is functional, false if non-functional
+ ///
+
+ inline bool
+ isFunctional(void) const;
+
+ ///
+ /// @brief Copy from a Target<O, VO> to a Target<K, V>
+ /// @tparam O the target type of the other
+ ///
+ template<TargetType O, typename VO>
+ inline Target( const Target<O, VO>& Other ):
+ Target<K, V>(Other.get())
+ {
+ // In case of recursion depth failure, use -ftemplate-depth=
+ static_assert( (K & O) != 0,
+ "unable to cast Target, no shared types");
+
+ static_assert( bitCount<K>::count >= bitCount<O>::count,
+ "unable to cast to specialized Target");
+ }
+
+#ifdef __PPE__
+
+ ///
+ /// @brief Get the target present setting
+ /// @return Bool whether present
+ ///
+ inline bool getPresent(void) const
+ {
+ return (static_cast<plat_target_handle_t>(this->iv_handle).fields.present ? true : false);
+ }
+
+ ///
+ /// @brief Get the target functional setting
+ /// @return Bool whether functional
+ ///
+ inline bool getFunctional(void) const
+ {
+ return (static_cast<plat_target_handle_t>(this->iv_handle).fields.functional ? true : false);
+ }
+
+ ///
+ /// @brief Set the target present setting
+ /// @return Bool whether present
+ ///
+ inline void setPresent(void)
+ {
+ (static_cast<plat_target_handle_t&>(this->iv_handle)).fields.present = 1;
+ return;
+ }
+
+ ///
+ /// @brief Set the target functional setting
+ /// @return Bool whether functional
+ ///
+ inline void setFunctional(const bool &i_state)
+ {
+ (static_cast<plat_target_handle_t&>(this->iv_handle)).fields.functional = (i_state) ? 1 : 0;
+ return;
+ }
+
+
+ /// Need to optimize PPE Target resoulution in a cheap manner
+ /// Brian: not sure if the this is the place for this as
+ /// this is plaform specific.
+
+ ///
+ /// @brief Get address overlay to reduce runtime processing
+ /// @return Overlay as a type uint32_t
+ ///
+ inline uint32_t getAddressOverlay(void) const
+ {
+ return (static_cast<plat_target_handle_t>(iv_handle).value & 0xFF000000);
+ }
+
+ ///
+ /// @brief Get target number
+ /// @return Overlay as a type V
+ ///
+ inline uint32_t getTargetNumber(void) const
+ {
+ return static_cast<uint32_t>(static_cast<plat_target_handle_t>(iv_handle).fields.type_target_num);
+ }
+
+ ///
+ /// @brief Get target type directly from the handle
+ /// @return Overlay as a type V
+ ///
+ inline TargetType getTargetType(void) const
+ {
+ return static_cast<TargetType>(static_cast<plat_target_handle_t>(iv_handle).fields.type);
+ }
+
+ ///
+ /// @brief Get chiplet number from the handle
+ /// @return ChipletNumber_t Chiplet Number
+ ///
+ inline ChipletNumber_t getChipletNumber(void) const
+ {
+ return static_cast<ChipletNumber_t>(static_cast<plat_target_handle_t>(iv_handle).fields.chiplet_num);
+ }
+
+#endif
+
+
+ private:
+ // Don't use enums here as it makes it hard to assign
+ // in the platform target cast constructor.
+ static const TargetType iv_type = K;
+
+ V iv_handle;
+ };
+
+ // EX threads map to CORE threads:
+ // t0 / t2 / t4 / t6 fused = t0 / t1 / t2 / t3 normal (c0)
+ // t1 / t3 / t5 / t7 fused = t0 / t1 / t2 / t3 normal (c1)
+ // So when splitting the EX, we need to map from EX threads
+ // to CORE threads.
+
+ ///
+ /// @brief Given a normal core thread id, translate this to
+ /// a fused core thread id. (normal to fused)
+ /// @param[in] the ordinal number of the normal core this thread belongs to
+ /// @param[in] a normal core thread id - 0, ..., 3
+ /// @return the fused core thread id
+ ///
+ inline uint8_t thread_id_n2f(const uint8_t i_ordinal, const uint8_t i_thread_id)
+ {
+ return (i_thread_id << 1) | i_ordinal;
+ }
+
+ ///
+ /// @brief Given a fused core thread id, translate this to
+ /// a normal core thread id. (fused to normal)
+ /// @param[in] a fused core thread id - 0, ..., 7
+ /// @return the normal core thread id
+ ///
+ inline uint8_t thread_id_f2n(const uint8_t i_thread_id)
+ {
+ return i_thread_id >> 1;
+ }
+
+ ///
+ /// @brief Given a normal core thread id, translate this to a
+ /// normal core bitset.
+ /// @param[in] a normal core thread id - 0, ..., 3
+ /// @return the normal core bitset
+ /// @note to got from a fused core id to a normal core bitset,
+ /// translate from a fused core thread id first.
+ ///
+ inline uint8_t thread_id2bitset(const uint8_t i_thread_id)
+ {
+ // 0xff means "set all bits"
+ static const uint8_t all_threads = 0xff;
+ static const uint8_t all_normal_threads_bitset = 0x0f;
+
+ if (i_thread_id == all_threads)
+ {
+ return all_normal_threads_bitset;
+ }
+
+ // A thread_id is really just bit index.
+ return (1 << (4 - i_thread_id - 1));
+ }
+
+ ///
+ /// @brief Given a bitset of normal core thread ids, translate this to
+ /// a bit mask of fused core thread id. (normal to fused)
+ /// @param[in] the ordinal number of the normal core this thread belongs to
+ /// @param[in] a normal core thread bitset - b0000, ..., b1111
+ /// @return the corresponding fused core bitset
+ ///
+ inline uint8_t thread_bitset_n2f(const uint8_t i_ordinal, const uint8_t i_threads)
+ {
+ // Since we only have 4 bits I think this is better than a shift-type solution
+ // for interleaving bits
+ static uint8_t core_map[] = {
+ 0b00000000, // b0000
+ 0b00000010, // b0001
+ 0b00001000, // b0010
+ 0b00001010, // b0011
+ 0b00100000, // b0100
+ 0b00100010, // b0101
+ 0b00101000, // b0110
+ 0b00101010, // b0111
+ 0b10000000, // b1000
+ 0b10000010, // b1001
+ 0b10001000, // b1010
+ 0b10001010, // b1011
+ 0b10100000, // b1100
+ 0b10100010, // b1101
+ 0b10101000, // b1110
+ 0b10101010, // b1111
+ };
+
+ return core_map[i_threads] >> i_ordinal;
+ }
+
+ ///
+ /// @brief Given a fused core thread bitset, translate this to
+ /// a normal core thread bitset. (fused to normal)
+ /// @param[in] the ordinal number of the normal core this thread belongs to
+ /// @param[in] a fused core thread bitset - b00000000, ..., b11111111
+ /// @return the corresponding normal core bitset
+ ///
+ inline uint8_t thread_bitset_f2n(const uint8_t i_ordinal, const uint8_t i_threads)
+ {
+ uint8_t normal_set = 0;
+
+ // core 0 is the left-most bit in the pair
+ uint8_t pair_mask = (i_ordinal == 0) ? 0x2 : 0x1;
+
+ // For each bit which can be set in the normal core bit_set ...
+ for( auto i = 0; i <= 3; ++i )
+ {
+ // ... grab the two fused bits which represent it ...
+ // ... and mask off the bit in the pair which represents this normal core ...
+ // (the << 1 shifts the masks over as we walk the pairs of bits)
+ uint8_t bits = (((3 << (i << 1)) & i_threads) & (pair_mask << (i << 1)));
+
+ // ... if either bit is set, set the corresponding bit in
+ // the normal core bitset.
+ normal_set |= (bits != 0) << i;
+ }
+ return normal_set;
+ }
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @param[in] i_target Target<T, V>
+ /// @param[in] i_buffer buffer to write in to
+ /// @param[in] i_bsize size of the buffer
+ /// @return void
+ /// @post The contents of the buffer is replaced with the string
+ /// representation of the target
+ ///
+ template< TargetType T, typename V >
+ inline void toString(const Target<T, V>& i_target, char* i_buffer, size_t i_bsize);
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @tparam B The type of the buffer
+ /// @param[in] A pointer to the Target<T, V>
+ /// @param[in] i_buffer buffer to write in to
+ /// @param[in] i_bsize size of the buffer
+ /// @return void
+ /// @post The contents of the buffer is replaced with the string
+ /// representation of the target
+ ///
+ template< TargetType T, typename V >
+ inline void toString(const Target<T, V>* i_target, char* i_buffer, size_t i_bsize);
+
+ ///
+ /// @brief Get an enumerated target of a specific type
+ /// @tparam T The type of the target
+ /// @param[in] Ordinal representing the ordinal number of
+ /// the desired target
+ /// @return Target<T, V> the target requested
+ ///
+ template<TargetType T, typename V>
+ inline Target<T, V> getTarget(uint64_t Ordinal);
+
+ // Why has the been removed? For starters, the API name
+ // is probably wrong as it's already been confused with
+ // Target::getChildren(). And if I'm going to change it
+ // I really want to see if we need it. I'm still not
+ // clear on whether we're alloing this traversal or not.
+#if 0
+ ///
+ /// @brief Get the base target's children
+ /// @tparam T The type of the target
+ /// @return std::vector<Target<T> > a vector of present/functional
+ /// children
+ ///
+ template<TargetType T>
+ inline std::vector<Target<T> > getChildren()
+ {
+ // For testing
+ return {Target<T>(), Target<T>()};
+ }
+#endif
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @tparam B The type of the buffer
+ /// @param[in] i_target Target<T>
+ /// @param[in] i_buffer buffer
+ /// @return void
+ /// @post The contents of the buffer is replaced with the string
+ /// representation of the target
+ ///
+ template<TargetType T, typename V, typename B>
+ inline void toString(const Target<T, V>& i_target, B& i_buffer);
+
+ ///
+ /// @brief Check if the target is of a type, or in a type subset.
+ /// @tparam K the TargetType to check
+ /// @tparam T TargetType or TargetType composite to check against
+ /// @return True, iff K is a proper T
+ ///
+ template< TargetType K, TargetType T >
+ inline constexpr bool is_same(void)
+ { return (K & T) != 0; }
+
+
+}
+#endif
diff --git a/src/hwpf/include/ffdc.H b/src/hwpf/include/ffdc.H
new file mode 100644
index 00000000..47a977e7
--- /dev/null
+++ b/src/hwpf/include/ffdc.H
@@ -0,0 +1,35 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/ffdc.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 ffdc.H
+ * @brief Defines the FirstFailureData class
+ */
+
+#ifndef FAPI2_FFDC_H_
+#define FAPI2_FFDC_H_
+
+namespace fapi2
+{
+}
+#endif // FAPI2_FFDC_H_
diff --git a/src/hwpf/include/hw_access.H b/src/hwpf/include/hw_access.H
new file mode 100644
index 00000000..53ad6b14
--- /dev/null
+++ b/src/hwpf/include/hw_access.H
@@ -0,0 +1,603 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/hw_access.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 hw_access.H
+ *
+* @brief Defines the hardware access functions that platform code must
+ * implement.
+ */
+
+#ifndef FAPI2_HWACCESS_H_
+#define FAPI2_HWACCESS_H_
+
+
+// variable_buffer isn't supported on PPE
+#ifndef __PPE__
+#include <variable_buffer.H>
+#endif
+
+#include <utils.H>
+#include <plat_hw_access.H>
+#include <fapi2_hw_access.H>
+#include "plat_ring_traverse.H" // for findRS4InImageAndApply
+
+namespace fapi2
+{
+
+ //--------------------------------------------------------------------------
+ // PIB Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Sets the PIB error mask - platform dependant
+ /// @param[in] i_mask The new error mask
+ void setPIBErrorMask(uint8_t i_mask)
+ {
+ PLAT_SET_PIB_ERROR_MASK(i_mask);
+ }
+
+ /// @brief Gets the PIB error mask - platform dependant
+ /// @return uint8_t The current PIB error mask
+ uint8_t getPIBErrorMask(void)
+ {
+ PLAT_GET_PIB_ERROR_MASK(o_pib_mask);
+ return o_pib_mask;
+ }
+
+ //--------------------------------------------------------------------------
+ // Operational Mode Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Sets the operational mode
+ /// @param[in] i_mode The new mode
+ // note: this can be moved to a C file if desired
+ inline void setOpMode(const OpModes i_mode)
+ {
+ // Keeps the compiler from complaining about the unused i_mode
+ static_cast<void>(i_mode);
+
+ // No-op for now. Should set thread-local operational mode
+ return;
+ }
+
+ /// @brief Gets the operational mode
+ /// @return the operational mode
+ // note: this can be moved to a C file if desired
+ inline OpModes getOpMode(void)
+ {
+ // No-op for now. Should read thread-local operational mode
+ return NORMAL;
+ }
+
+ //--------------------------------------------------------------------------
+ // HW Communication Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Reads a SCOM register from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ __attribute__((always_inline))
+ inline ReturnCode getScom(const Target<K, V>& i_target, const uint64_t i_address,
+ buffer<uint64_t>& o_data)
+ {
+ fapi2::ReturnCode l_rc;
+ PLAT_GETSCOM(l_rc,
+ i_target,
+ i_address,
+ &(o_data()));
+
+ return l_rc;
+ }
+
+ /// @brief Writes a SCOM register on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ __attribute__((always_inline))
+ inline ReturnCode putScom(const Target<K, V>& i_target, const uint64_t i_address,
+ const buffer<uint64_t> i_data)
+ {
+ fapi2::ReturnCode l_rc;
+ PLAT_PUTSCOM(l_rc,
+ i_target,
+ i_address,
+ i_data());
+
+ return l_rc;
+ }
+
+ /// @brief Read-modify-write a SCOM register on a chip
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor).
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode modifyScom(const Target<K, V>& i_target,
+ const uint64_t i_address,
+ const buffer<uint64_t> i_data,
+ const ChipOpModifyMode i_modifyMode)
+ {
+ fapi2::buffer<uint64_t> l_modifyDataBuffer;
+
+ fapi2::ReturnCode l_rc;
+ PLAT_GETSCOM(l_rc,
+ i_target,
+ (uint32_t)(i_address & BITS(40,24)),
+ &(l_modifyDataBuffer()));
+ if (l_rc) goto __fapi2exit__;
+
+ if ( i_modifyMode == CHIP_OP_MODIFY_MODE_OR)
+ {
+ l_modifyDataBuffer |= i_data;
+ }
+
+ if ( i_modifyMode == CHIP_OP_MODIFY_MODE_AND)
+ {
+ l_modifyDataBuffer &= i_data;
+ }
+
+ if ( i_modifyMode == CHIP_OP_MODIFY_MODE_XOR)
+ {
+ l_modifyDataBuffer ^= i_data;
+ }
+
+ PLAT_PUTSCOM(l_rc,
+ i_target,
+ (uint32_t)(i_address & BITS(40,24)),
+ l_modifyDataBuffer());
+ if (l_rc) goto __fapi2exit__;
+
+
+__fapi2exit__:
+ return l_rc;
+
+ }
+
+ /// @brief Writes a SCOM register under mask on a chip
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @param[in] i_mask Buffer that holds the mask value.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode putScomUnderMask( const Target<K, V>& i_target,
+ const uint64_t i_address,
+ buffer<uint64_t> i_data,
+ buffer<uint64_t> i_mask)
+ {
+ fapi2::buffer<uint64_t> l_modifyDataBuffer = i_data;
+
+ l_modifyDataBuffer &= i_mask;
+
+ fapi2::ReturnCode l_rc;
+ PLAT_PUTSCOM(l_rc,
+ i_target,
+ (uint32_t)(i_address & BITS(40,24)),
+ l_modifyDataBuffer());
+
+ return l_rc;
+
+ }
+
+
+ /// @brief Reads a CFAM register from a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode getCfamRegister(const Target<K, V>& i_target,
+ const uint32_t i_address,
+ buffer<uint32_t>& o_data)
+ {
+ PLAT_GETCFAM(i_target.get(),
+ (uint32_t)(i_address & BITS(40,24)),
+ &(o_data()));
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Writes a CFAM register on a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode putCfamRegister(const Target<K, V>& i_target,
+ const uint32_t i_address,
+ buffer<uint32_t>& i_data)
+ {
+ PLAT_PUTCFAM(i_target.get(),
+ (uint32_t)(i_address & BITS(40,24)),
+ &(i_data()));
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Read-modify-write a CFAM register on a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to modify.
+ /// @param[in] i_data Buffer that holds data to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor).
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode modifyCfamRegister(const Target<K, V>& i_target,
+ const uint32_t i_address,
+ const buffer<uint32_t>& i_data,
+ const ChipOpModifyMode i_modifyMode)
+ {
+ PLAT_MODCFAM(i_target.get(),
+ (uint32_t)(i_address & BITS(40,24)),
+ &(i_data()),
+ i_modifyMode);
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Platform-level implementation of putRing()
+ /// Hardware procedures writers will not call this function.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_ringID Ring ID that will identify the Ring in the image.
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode putRing(const Target<K, V>& i_target,
+ const RingID i_ringID,
+ const RingMode i_ringMode)
+ {
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+
+ // Find the RS4 string in the SEEPROM
+ l_rc = findRS4InImageAndApply(i_target, i_ringID, i_ringMode);
+
+ return l_rc;
+ }
+
+ // variable_buffer isn't supported on PPE
+#ifndef __PPE__
+ /// @brief Reads a ring from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode getRing(const Target<K, V>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& o_data,
+ const RingMode i_ringMode = 0)
+ {
+ o_data.setBit(0);
+ o_data.setBit(3);
+#ifndef __PPE__
+ std::cout << std::hex << " getRing "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "ring address: " << i_address << "; "
+ << "ring mode: " << i_ringMode << "; "
+ << "output data:";
+ o_data.print();
+#endif
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Read-modify-write a ring on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to modify.
+ /// @param[in] i_data Buffer that contains RS4 compressed ring data
+ /// to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor)
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K, typename V >
+ inline ReturnCode modifyRing(const Target<K, V>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& i_data,
+ const ChipOpModifyMode i_modifyMode,
+ const RingMode i_ringMode = 0)
+ {
+
+ return FAPI2_RC_SUCCESS;
+ }
+#endif
+
+
+#ifdef FAPI_SUPPORT_MULTI_SCOM
+ /// @brief Performs a multiple SCOM operation
+ /// This interface performs multiple SCOM operations on a chip in the
+ /// order specified by the input MultiScom object.
+ /// See fapiMultiScom.H for details of how to populate the MultiScom
+ /// object with SCOM operations.
+ ///
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in,out] io_multiScomObj Reference to a MultiScom object,
+ /// pre-populated with SingleScomInfo entries
+ /// to perform multiple SCOMs on input target
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note This is a synchronous interface and would return after all the
+ /// SCOM operations are completed or on the first failed operation
+ ///
+ /// @note SCOMs will be performed in the order they were added to the
+ /// input MultiScom object
+ ///
+ /// @note In case of errors, the platform code is responsible to collect
+ /// and add all the required error info and FFDC into the error data
+ /// for debugging
+ ///
+ /// @note If the SCOM operations added are specific to a processor chip,
+ /// then the FSI Shift Engine configured in scatter-gather DMA mode
+ /// extension would be used to execute the SCOM operations in a
+ /// performance optimize mode. In this mode, the special
+ /// SCOM_BULK_READ_MODE and SCOM_BULK_WRITE_MODE operations are
+ /// supported that allow a large bulk of SCOM access (in multiple of
+ /// 64 bits) for targets that support auto-increment. The
+ /// SCOM_WRITE_UNDER_MASK operation is not supported in this mode
+ ///
+ /// @note If the SCOM operations added are specific to a memory buffer
+ /// chip, then the regular SCOM engine is used to execute the SCOM
+ /// operations. SCOM_WRITE_UNDER_MASK operation is supported in
+ /// this mode, but the special SCOM_BULK_READ_MODE and
+ /// SCOM_BULK_WRITE_MODE operations are not supported due to
+ /// hardware limitations.
+ ///
+ template< TargetType K, typename V >
+ fapi2::ReturnCode multiScom (const Target<K, V>& i_target,
+ MultiScom& io_multiScomObj)
+ {
+ }
+#endif
+
+ // --------------------------------------------------------------------------
+ // NOTE:
+ // Implement platform Spy access functions if platform supports them.
+ // --------------------------------------------------------------------------
+
+ // variable_buffer isn't supported on PPE
+#ifndef __PPE__
+ /// @brief Reads a spy from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy whose data to be read.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependant on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// it with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi2::ReturnCode rc = fapiGetSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+ ///
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+ template< TargetType K, typename V >
+ inline ReturnCode getSpy(const Target<K, V>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data)
+ {
+ static_assert(K == 0, "implement getSpy (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+ template< TargetType K, typename V >
+ inline ReturnCode getSpy(const Target<K, V>& i_target,
+ const char * const i_spyId,
+ variable_buffer& o_data)
+ {
+ static_assert(K == 0, "implement getSpy (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+ /// @brief Writes a spy on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy to write data to.
+ /// @param[out] i_data Buffer that holds data to write into spy.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// is with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi2::ReturnCode rc = fapiPutSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+ ///
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+ template< TargetType K, typename V >
+ inline ReturnCode putSpy(const Target<K, V>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& i_data)
+ {
+ static_assert(K == 0, "implement putSpy (enum)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+ template< TargetType K, typename V >
+ inline ReturnCode putSpy(const Target<K, V>& i_target,
+ const char* const i_spyId,
+ variable_buffer& i_data)
+ {
+ static_assert(K == 0, "implement putSpy (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+ /// @brief Writes spy data into a buffer holding ring data image
+ /// This API is used by L2/L3 repair to put column repair data
+ /// into a ring buffer image.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy.
+ /// @param[in] i_data Buffer that holds spy data to write into ring
+ /// image.
+ /// @param[out] o_data Buffer that holds updated ring image.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+ template< TargetType K, typename V >
+ inline ReturnCode putSpyImage(const Target<K, V>& i_target,
+ const spyId_t i_spyId,
+ const variable_buffer& i_data,
+ variable_buffer& o_imageData)
+ {
+ static_assert(K == 0, "implement putSpyImage (enum)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+ template< TargetType K, typename V >
+ inline ReturnCode putSpyImage(const Target<K, V>& i_target,
+ const char* const i_spyId,
+ const variable_buffer& i_data,
+ variable_buffer& o_imageData)
+ {
+ static_assert(K == 0, "implement putSpyImage (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+ /// @brief Reads spy data from a ring image buffer
+ /// @param[in] i_target Target to operate on
+ /// @param[in] i_spyId The spy's id
+ /// @param[out] o_data Buffer that holds data read from ring image.
+ /// @param[in] i_imageData Buffer that holds ring image to read data
+ /// from.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+ template< TargetType K, typename V >
+ inline ReturnCode getSpyImage(const Target<K, V>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data,
+ const variable_buffer& i_imageData)
+ {
+ static_assert(K == 0, "implement getSpyImage (enum)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+ template< TargetType K, typename V >
+ inline ReturnCode getSpyImage(const Target<K, V>& i_target,
+ const char * const i_spyId,
+ variable_buffer& o_data,
+ const variable_buffer& i_imageData)
+ {
+ static_assert(K == 0, "implement getSpyImage (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+
+#endif // PPE
+
+};
+
+#endif // _FAPI2_HWACCESS_H_
diff --git a/src/hwpf/include/hwp_ffdc_classes.H b/src/hwpf/include/hwp_ffdc_classes.H
new file mode 100644
index 00000000..90a3f9ce
--- /dev/null
+++ b/src/hwpf/include/hwp_ffdc_classes.H
@@ -0,0 +1,23 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/hwp_ffdc_classes.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
diff --git a/src/hwpf/include/plat/hwp_executor.H b/src/hwpf/include/plat/hwp_executor.H
new file mode 100644
index 00000000..ae7b5823
--- /dev/null
+++ b/src/hwpf/include/plat/hwp_executor.H
@@ -0,0 +1,64 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/hwp_executor.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 fapi2PlatHwpExecutor.H
+ *
+ * @brief Defines the FAPI HWP Executor Macro.
+ *
+ * The HWP Executor macro is called when a PLAT invoker function or a HWP wants
+ * to execute a HWP. Each platform can modify the macro to do any platform
+ * specific work to execute the HWP (e.g. dlopening a shared library)
+ */
+
+#ifndef FAPI2PLATHWPEXECUTOR_H_
+#define FAPI2PLATHWPEXECUTOR_H_
+
+/**
+ * @brief HWP Executor macro
+ *
+ * By default, this macro just calls the HWP directly. If this cannot be done
+ * then the platform needs to modify
+ */
+
+#include <return_code.H>
+#include <target.H>
+
+
+
+// Macro to execute an arbitrary function with an arbitray number of arguments. The
+// function is in a shared lib that must be dlopened. All that is required is that
+// there is a typedef for the function pointer available that is called <FUNC>_FP_t
+// i.e. if the function is called foo, then the typedef is called foo_FP_t
+#define FAPI_PLAT_EXEC_HWP(RC, FUNC, _args_...) \
+{\
+ RC = FUNC(_args_); \
+}
+
+#define FAPI_PLAT_EXEC_HWP_LAMBDA(FUNC, _args_...) \
+[&]()->fapi2::ReturnCode \
+{\
+ FUNC(_args_); \
+}()
+
+#endif // FAPI2PLATHWPEXECUTOR_H_
diff --git a/src/hwpf/include/plat/multicast.H b/src/hwpf/include/plat/multicast.H
new file mode 100644
index 00000000..46d64be8
--- /dev/null
+++ b/src/hwpf/include/plat/multicast.H
@@ -0,0 +1,54 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/multicast.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 __FAPI2_MULTICAST__
+#define __FAPI2_MULTICAST__
+
+#include <fapi2_multicast.H>
+
+namespace fapi2
+{
+
+template<MulticastType M, MulticastGroup G, typename V>
+template<MulticastType O, MulticastGroup N>
+inline void Multicast<M, G, V>::updateHandle(V& i_value)
+{
+ // Update handle only if multicast bit is set in handle, else we leave the
+ // handle unchanged. This enables the same procedure to work with both
+ // multicast and unicast targets
+ if(i_value.fields.is_multicast)
+ {
+ // Update the handle to reflect the new multicast type and group
+ i_value.fields.chiplet_num = (0x40) | (O << 3) | N;
+ }
+}
+
+template<MulticastType M, MulticastGroup G, typename V>
+inline bool Multicast<M, G, V>::isMulticast() const
+{
+ return iv_handle.fields.is_multicast;
+}
+
+}
+
+#endif
diff --git a/src/hwpf/include/plat/plat_attributes.H b/src/hwpf/include/plat/plat_attributes.H
new file mode 100644
index 00000000..6aec47e3
--- /dev/null
+++ b/src/hwpf/include/plat/plat_attributes.H
@@ -0,0 +1,36 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_attributes.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 plat_attributes.H
+ * @brief Platform specific attribute headers
+ */
+
+#ifndef __PLAT_ATTTRIBUTE_H__
+#define __PLAT_ATTTRIBUTE_H__
+
+#include <fapi2AttributeService.H>
+#include <fapi2AttributeIds.H> // Generated file
+//#include <plat_target_pg_attributes.H>
+
+#endif // __PLAT_ATTTRIBUTE_H__
diff --git a/src/hwpf/include/plat/plat_error_scope.H b/src/hwpf/include/plat/plat_error_scope.H
new file mode 100644
index 00000000..505ec6cb
--- /dev/null
+++ b/src/hwpf/include/plat/plat_error_scope.H
@@ -0,0 +1,70 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_error_scope.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 plat_error_scope.H
+ * @brief platform definitions which create a scope for automatic error handling
+ */
+
+#ifndef __FAPI2_PLAT_ERROR_SCOPE__
+#define __FAPI2_PLAT_ERROR_SCOPE__
+
+/// @cond
+#define PLAT_FAPI_TRY_NO_TRACE( __operation__ ) \
+ if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \
+ { \
+ goto fapi_try_exit; \
+ }
+
+#define PLAT_FAPI_TRY_TRACE( __operation__, ... ) \
+ if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \
+ { \
+ FAPI_ERR(__VA_ARGS__); \
+ goto fapi_try_exit; \
+ }
+
+///
+/// @brief Assert a conditional is true.
+/// If it is not, the FFDC gathering function is called and the
+/// trace is output as a FAPI error trace.
+/// @param[in] __conditional__ the condition to assert
+/// @param[in] __ffdc__ the FFDC gathering function
+/// @param[in] ... varargs, as input to FAPI_ERR
+///
+#define PLAT_FAPI_ASSERT( __conditional__, __ffdc__, ... ) \
+ if (! (__conditional__)) \
+ { \
+ (__ffdc__).execute(); \
+ FAPI_ERR(__VA_ARGS__); \
+ goto fapi_try_exit; \
+ }
+
+
+///
+/// @brief Temporary macro for error label until all are removed.
+/// @todo REMOVE this in time.
+#define FAPI_CLEANUP() \
+fapi_try_exit:
+/// @endcond
+
+#endif
diff --git a/src/hwpf/include/plat/plat_hw_access.H b/src/hwpf/include/plat/plat_hw_access.H
new file mode 100644
index 00000000..89c02f2a
--- /dev/null
+++ b/src/hwpf/include/plat/plat_hw_access.H
@@ -0,0 +1,148 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_hw_access.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 plat_hw_access.H
+ *
+ * @brief Define platform specific calls for hardware accesses.
+ */
+
+#ifndef PLATHWACCESS_H_
+#define PLATHWACCESS_H_
+
+#include <plat_includes.H>
+#include "hw_access_def.H"
+#include <return_code.H>
+
+
+/// PIB Error Mask
+
+#define PLAT_SET_PIB_ERROR_MASK(_m_mask) \
+ { /* Read MSR */ \
+ uint32_t msr_data = mfmsr(); \
+ /* Set SEM field */ \
+ msr_data &= ~(BITS(0,8)); \
+ msr_data |= (uint32_t)(i_mask << 24); \
+ /* Write MSR */ \
+ mtmsr(msr_data); \
+ };
+
+#define PLAT_GET_PIB_ERROR_MASK(_m_mask) \
+ uint8_t _m_mask; \
+ uint32_t _sem = mfmsr(); \
+ _m_mask = (uint8_t)((_sem & MSR_SEM) >> (32-(MSR_SEM_START_BIT + MSR_SEM_LEN)));
+
+// Building block PPE instructions
+#define PPE_MFMSR(_m_data) \
+asm volatile \
+ ( \
+ "mfmsr %[data] \n" \
+ : [data]"=&r"(*_m_data) \
+ : "[data]"(*_m_data) \
+ );
+
+#define PPE_MTMSR(_m_data) \
+asm volatile \
+ ( \
+ "mtmsr %[data] \n" \
+ : [data]"=&r"(*_m_data) \
+ : "[data]"(*_m_data) \
+ );
+
+/// GetScom
+#define PLAT_GETSCOM(_m_rc, _m_base, _m_offset, _m_data) \
+ _m_rc = fapi2::getscom_abs_wrap(getEffectiveAddress(_m_base, _m_offset), _m_data)
+
+/// PutScom
+#define PLAT_PUTSCOM(_m_rc, _m_base, _m_offset, _m_data) \
+ _m_rc = fapi2::putscom_abs_wrap(getEffectiveAddress(_m_base, _m_offset), _m_data)
+
+/// GetCFAM
+#define PLAT_GETCFAM(_m_base, _m_offset, _m_data) \
+ static_assert( K == TARGET_TYPE_NONE, \
+ "getCfamRegister is not supported by PPE platforms")
+
+/// PutCFAM
+#define PLAT_PUTCFAM(_m_base, _m_offset, _m_data) \
+ static_assert( K == TARGET_TYPE_NONE, \
+ "putCfamRegister is not supported by PPE platforms")
+
+/// ModifyCFAM
+#define PLAT_MODCFAM(_m_base, _m_offset, _m_data, _m_mode) \
+ static_assert( K == TARGET_TYPE_NONE, \
+ "modifyCfamRegister is not supported by PPE platforms")
+
+namespace fapi2
+{
+ // This function loads the scan region data for the given ring address and
+ // updates the check word data
+ // @param[in] : ring addtress
+ // @param[in]: ring mode
+ // @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ fapi2::ReturnCode getRing_setup(const uint32_t i_ringAddress,
+ const fapi2::RingMode i_ringMode);
+
+ // This function read the 64 bit data from the hardware
+ // @param[in] i_ringAddress - absolute ring address
+ // @param [out]: 64 bit data
+ // @param [in] i_bitShiftValue - Bit shift value that needs to rotate
+ // @note- If the ring length is divisble by 64, then bitshift will always be
+ // 64, else need to store the ring_length mod 64 and send that value in the
+ // last iteration.
+ // @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ fapi2::ReturnCode getRing_granule_data(const uint32_t i_ringAddress,
+ uint64_t *o_data,
+ const uint32_t i_bitShiftValue);
+
+ // This function verify the check word data is matching or not and will
+ // clean up the scan region data
+ // @param[in] i_ringAddress - absolute ring address
+ // @param[in] i_ringMode - Ring mode value
+ // @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ fapi2::ReturnCode getRing_verifyAndcleanup(const uint32_t i_ringAddress,
+ const fapi2::RingMode i_ringMode);
+
+ ///
+ /// @brief Platform wrapper over PK getscom_abs
+ ///
+ /// @param [in] i_addr The SCOM address
+ /// @param [out] o_data The data read
+ ///
+ /// @return PCB-PIB return code
+ ///
+ uint32_t getscom_abs_wrap(const uint32_t i_addr, uint64_t *o_data);
+
+ ///
+ /// @brief Platform wrapper over PK putscom_abs
+ ///
+ /// @param [in] i_addr The SCOM address
+ /// @param [in] i_data The data read
+ ///
+ /// @return PCB-PIB return code
+ ///
+ uint32_t putscom_abs_wrap(const uint32_t i_addr, uint64_t i_data);
+}
+
+
+#endif // PLATHWACCESS_H_
+
diff --git a/src/hwpf/include/plat/plat_includes.H b/src/hwpf/include/plat/plat_includes.H
new file mode 100644
index 00000000..62f8a9b0
--- /dev/null
+++ b/src/hwpf/include/plat/plat_includes.H
@@ -0,0 +1,39 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_includes.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 plat_includes.H
+ * @brief Platform specific include to implement FAPI2 APIs
+ */
+
+#ifndef __PLAT_INCLUDES_H__
+#define __PLAT_INCLUDES_H__
+
+#include <plat_hw_access.H>
+
+#include <ppe42_scom.h>
+#include <ppe42_msr.h>
+//#include <pk.h>
+
+
+#endif // __PLAT_INCLUDES_H__
diff --git a/src/hwpf/include/plat/plat_ring_traverse.H b/src/hwpf/include/plat/plat_ring_traverse.H
new file mode 100644
index 00000000..5fc470e2
--- /dev/null
+++ b/src/hwpf/include/plat/plat_ring_traverse.H
@@ -0,0 +1,116 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_ring_traverse.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 _PLAT_RING_TRAVERSE_H_
+#define _PLAT_RING_TRAVERSE_H_
+
+#include <p9_putRingUtils.H> // for RS4 decompression utilities
+
+using namespace RING_TYPES;
+
+/// @brief This structure represents the layout of the Section-TOR
+/// Section-TOR has the offsets to the different chiplet's
+/// Common Ring section and Instance Ring section
+struct SectionTOR
+{
+ uint32_t TOC_PERV_COMMON_RING; // Offset of Perv Common Ring section
+ uint32_t TOC_PERV_INSTANCE_RING; // Offset of Perv Instance Ring section
+
+ uint32_t TOC_N0_COMMON_RING; // Offset of N0 Common Ring section
+ uint32_t TOC_N0_INSTANCE_RING; // Offset of N0 Instance Ring section
+
+ uint32_t TOC_N1_COMMON_RING; // Offset of N1 Common Ring section
+ uint32_t TOC_N1_INSTANCE_RING; // Offset of N1 Instance Ring section
+
+ uint32_t TOC_N2_COMMON_RING; // Offset of N2 Common Ring section
+ uint32_t TOC_N2_INSTANCE_RING; // Offset of N2 Instance Ring section
+
+ uint32_t TOC_N3_COMMON_RING; // Offset of N3 Common Ring section
+ uint32_t TOC_N3_INSTANCE_RING; // Offset of N3 Instance Ring section
+
+ uint32_t TOC_XB_COMMON_RING; // Offset of XB Common Ring section
+ uint32_t TOC_XB_INSTANCE_RING; // Offset of XB Instance Ring section
+
+ uint32_t TOC_MC_COMMON_RING; // Offset of MC Common Ring section
+ uint32_t TOC_MC_INSTANCE_RING; // Offset of MC Instance Ring section
+
+ uint32_t TOC_OB0_COMMON_RING; // Offset of OB0 Common Ring section
+ uint32_t TOC_OB0_INSTANCE_RING; // Offset of OB0 Instance Ring section
+
+ uint32_t TOC_OB1_COMMON_RING; // Offset of OB1 Common Ring section
+ uint32_t TOC_OB1_INSTANCE_RING; // Offset of OB1 Instance Ring section
+
+ uint32_t TOC_OB2_COMMON_RING; // Offset of OB2 Common Ring section
+ uint32_t TOC_OB2_INSTANCE_RING; // Offset of OB2 Instance Ring section
+
+ uint32_t TOC_OB3_COMMON_RING; // Offset of OB3 Common Ring section
+ uint32_t TOC_OB3_INSTANCE_RING; // Offset of OB3 Instance Ring section
+
+ uint32_t TOC_PCI0_COMMON_RING; // Offset of PCI0 Common Ring section
+ uint32_t TOC_PCI0_INSTANCE_RING; // Offset of PCI0 Instance Ring section
+
+ uint32_t TOC_PCI1_COMMON_RING; // Offset of PCI1 Common Ring section
+ uint32_t TOC_PCI1_INSTANCE_RING; // Offset of PCI1 Instance Ring section
+
+ uint32_t TOC_PCI2_COMMON_RING; // Offset of PCI2 Common Ring section
+ uint32_t TOC_PCI2_INSTANCE_RING; // Offset of PCI2 Instance Ring section
+
+ uint32_t TOC_EQ_COMMON_RING; // Offset of Quad Common Ring section
+ uint32_t TOC_EQ_INSTANCE_RING; // Offset of Quad Instance Ring section
+
+ uint32_t TOC_EC_COMMON_RING; // Offset of Core Common Ring section
+ uint32_t TOC_EC_INSTANCE_RING; // Offset of Core Instance Ring section
+};
+
+
+///
+/// @brief This is a plat pecific (SBE Plat) function that locates the
+/// Ring Container in the image and calls the functin to decompress the
+/// RS4 string and apply it to the hardware.
+/// @param i_target The target of Ring apply.
+/// @param i_ringID The Ring ID that identifies the ring to be applied.
+/// @return FAPI2_RC_SUCCESS on success, else error code.
+///
+fapi2::ReturnCode findRS4InImageAndApply(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const RingID i_ringID,
+ const fapi2::RingMode i_ringMode);
+///
+/// @brief This is a plat pecific (SBE Plat) function that locates the
+/// Ring Container in the image and calls the functin to decompress the
+/// RS4 string and apply it to the hardware.
+/// @param i_target The target of Ring apply.
+/// @param i_ringID The Ring ID that identifies the ring to be applied.
+/// @param i_sectionTOR TOR section address
+/// @param i_applyOverride override is enabled or not
+/// @return FAPI2_RC_SUCCESS on success, else error code.
+///
+fapi2::ReturnCode getRS4ImageFromTor(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const RingID i_ringID,
+ SectionTOR *i_sectionTOR,
+ bool i_applyOverride,
+ const uint32_t i_sectionOffset,
+ const fapi2::RingMode i_ringMode);
+#endif
diff --git a/src/hwpf/include/plat/plat_target.H b/src/hwpf/include/plat/plat_target.H
new file mode 100644
index 00000000..a4eca5a8
--- /dev/null
+++ b/src/hwpf/include/plat/plat_target.H
@@ -0,0 +1,215 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_target.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 plat_target.H
+ * @brief platform definitions for fapi2 targets
+ */
+
+#ifndef __FAPI2_PLAT_TARGET__
+#define __FAPI2_PLAT_TARGET__
+
+#include <stdint.h>
+#include <target_types.H>
+#include <target_states.H>
+#include <assert.h>
+#include <plat_target_parms.H>
+#include <vector>
+
+static const uint8_t CORES_PER_QUAD = 4;
+static const uint8_t EX_PER_QUAD = 2;
+static const uint8_t CORES_PER_EX = 2;
+static const uint8_t N3_CHIPLET = 5;
+static const uint8_t MCS_PER_MCBIST = 2;
+
+//
+// Define what a platform handle looks like. For Hostboot,
+// for example, this might be a void*. For the SBE, this
+// will be a uint32_t ...
+//
+namespace fapi2
+{
+ typedef enum plat_target_type
+ {
+ PPE_TARGET_TYPE_NONE = 0x00,
+ PPE_TARGET_TYPE_PROC_CHIP = 0x01,
+ PPE_TARGET_TYPE_MCS = 0x02,
+ PPE_TARGET_TYPE_CORE = 0x04,
+ PPE_TARGET_TYPE_EQ = 0x08,
+ PPE_TARGET_TYPE_EX = 0x10,
+ PPE_TARGET_TYPE_PERV = 0x20,
+ PPE_TARGET_TYPE_MCBIST = 0x40,
+ PPE_TARGET_TYPE_SYSTEM = 0x80,
+ PPE_TARGET_TYPE_ALL = 0xFFF,
+ } plat_target_type_t;
+
+ typedef union plat_target_handle {
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t chiplet_num : 8;
+ uint32_t type_target_num : 8;
+ uint32_t present : 1;
+ uint32_t functional : 1;
+ uint32_t is_multicast : 1;
+ uint32_t valid : 1;
+ uint32_t type : 12;
+#else
+ uint32_t type : 12;
+ uint32_t valid : 1;
+ uint32_t is_multicast : 1;
+ uint32_t functional : 1;
+ uint32_t present : 1;
+ uint32_t type_target_num : 8;
+ uint32_t chiplet_num : 8;
+#endif
+ } fields;
+ ///
+ /// @brief Plat target handle constructor
+ ///
+ /// @param i_value Value to instantiate handle with
+ ///
+ plat_target_handle(uint32_t i_value = 0):value(i_value) {}
+
+ ///
+ /// @brief Get the fapi2::TargetType for this target
+ ///
+ /// @par Converts the internal PPE type for this target to fapi2 enum
+ ///
+ /// @return The fapi2::TargetType for this target
+ ///
+ TargetType getFapiTargetType() const;
+
+ ///
+ /// @brief Get the instance number for this target
+ ///
+ /// @return The instance number for this target
+ ///
+ inline uint32_t getTargetInstance() const
+ {
+ return fields.type_target_num;
+ }
+
+ ///
+ /// @brief Get this target's children
+ ///
+ /// @param [in] i_parentType fapi2 type of the parent
+ /// @param [in] i_childType fapi2 type of the child
+ /// @param [in] i_platType Plat type of the parent
+ /// @param [in] i_state Required state of the children
+ /// @param [out] o_children A vector of child target handles
+ ///
+ void getChildren(const TargetType i_parentType,
+ const TargetType i_childType,
+ const plat_target_type_t i_platType,
+ const TargetState i_state,
+ std::vector<plat_target_handle> &o_children) const;
+
+ ///
+ /// @brief Get proc chip target's children - filtered
+ ///
+ /// @param [in] i_filter Target filter
+ /// @param [in] i_state Required state of the children
+ /// @param [out] o_children A vector of child target handles
+ ///
+ void getChildren(const TargetFilter i_filter,
+ const TargetState i_state,
+ std::vector<plat_target_handle>& o_children) const;
+
+ ///
+ /// @brief Gets the plat target handle as a uint32
+ ///
+ /// @return Plat target handle as a uint32_t
+ ///
+ operator uint32_t() const {return value;}
+ } plat_target_handle_t;
+
+ typedef plat_target_handle_t plat_target_argument_t;
+
+ template<TargetType K, bool MULTICAST = false>
+ plat_target_handle_t createPlatTargetHandle(const uint32_t i_plat_argument)
+ {
+ static_assert((MULTICAST != true) || (K == TARGET_TYPE_PROC_CHIP),
+ "Only PROC_CHIP types can be multicast");
+ plat_target_handle_t l_handle = 0;
+
+ if(MULTICAST == true)
+ {
+ // Simply set the is multicast flag
+ l_handle.fields.is_multicast = 1;
+ }
+ else if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ l_handle.fields.chiplet_num = 0;
+ l_handle.fields.type = PPE_TARGET_TYPE_PROC_CHIP;
+ l_handle.fields.type_target_num = 0;
+ }
+ else if(K & TARGET_TYPE_PERV)
+ {
+ l_handle.fields.chiplet_num = i_plat_argument + NEST_GROUP1_CHIPLET_OFFSET;
+ l_handle.fields.type = PPE_TARGET_TYPE_PERV;
+ l_handle.fields.type_target_num = i_plat_argument;
+ }
+ else if(K & TARGET_TYPE_CORE)
+ {
+ l_handle.fields.chiplet_num = i_plat_argument + CORE_CHIPLET_OFFSET;
+ l_handle.fields.type = PPE_TARGET_TYPE_CORE | PPE_TARGET_TYPE_PERV;
+ l_handle.fields.type_target_num = i_plat_argument;
+ }
+ else if(K & TARGET_TYPE_EQ)
+ {
+ l_handle.fields.chiplet_num = i_plat_argument + EQ_CHIPLET_OFFSET;
+ l_handle.fields.type = PPE_TARGET_TYPE_EQ | PPE_TARGET_TYPE_PERV;
+ l_handle.fields.type_target_num = i_plat_argument;
+ }
+ else if(K & TARGET_TYPE_EX)
+ {
+ l_handle.fields.chiplet_num = (i_plat_argument / 2) + EX_CHIPLET_OFFSET;
+ l_handle.fields.type = PPE_TARGET_TYPE_EX;
+ l_handle.fields.type_target_num = i_plat_argument;
+ }
+ else if(K & TARGET_TYPE_MCBIST)
+ {
+ l_handle.fields.chiplet_num = i_plat_argument + MCBIST_CHIPLET_OFFSET;
+ l_handle.fields.type = PPE_TARGET_TYPE_MCBIST | PPE_TARGET_TYPE_PERV;
+ l_handle.fields.type_target_num = i_plat_argument;
+ }
+ else if(K & TARGET_TYPE_MCS)
+ {
+ l_handle.fields.chiplet_num = N3_CHIPLET - (MCS_PER_MCBIST * (i_plat_argument / MCS_PER_MCBIST));
+ l_handle.fields.type = PPE_TARGET_TYPE_MCS;
+ l_handle.fields.type_target_num = i_plat_argument;
+ }
+ else if(K == TARGET_TYPE_ALL)
+ {
+ l_handle.fields.chiplet_num = i_plat_argument;
+ l_handle.fields.type = PPE_TARGET_TYPE_ALL;
+ }
+
+ l_handle.fields.valid = 1;
+ return l_handle;
+ }
+
+};
+
+#endif
diff --git a/src/hwpf/include/plat/plat_target_definitions.H b/src/hwpf/include/plat/plat_target_definitions.H
new file mode 100644
index 00000000..daa9d228
--- /dev/null
+++ b/src/hwpf/include/plat/plat_target_definitions.H
@@ -0,0 +1,111 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_target_definitions.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 plat_ppe_target.H
+ * @brief Definitions for fapi2 PPE targets
+ */
+
+#ifndef __FAPI2_PPE_TARGET__
+#define __FAPI2_PPE_TARGET__
+
+#define TARGET_CHIP(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP > _name((uint64_t)_index);
+
+#define TARGET_CHIP_PERV(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_PERV> _name((uint64_t)_index);
+
+#define TARGET_EQ(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_EQ> _name((uint64_t)_index);
+
+#define TARGET_CORE(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_CORE> _name((uint64_t)_index);
+
+#define TARGET_EX(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_EX> _name((uint64_t)_index);
+
+namespace fapi2
+{
+
+ TARGET_CHIP (chip_target, 0);
+ TARGET_CHIP_PERV (perv_target, 1);
+ TARGET_CHIP_PERV (n0_target, 2);
+ TARGET_CHIP_PERV (n1_target, 3);
+ TARGET_CHIP_PERV (n2_target, 4);
+ TARGET_CHIP_PERV (n3_target, 5);
+ TARGET_CHIP_PERV (xb_target, 6);
+ TARGET_CHIP_PERV (mc0_target, 7);
+ TARGET_CHIP_PERV (mc1_target, 8);
+ TARGET_CHIP_PERV (ob0_target, 9);
+ TARGET_CHIP_PERV (ob1_target, 10);
+ TARGET_CHIP_PERV (ob2_target, 11);
+ TARGET_CHIP_PERV (ob3_target, 12);
+ TARGET_CHIP_PERV (pci0_target, 13);
+ TARGET_CHIP_PERV (pci1_target, 14);
+ TARGET_CHIP_PERV (pci2_target, 15);
+ TARGET_EQ (eq0_target, 0);
+ TARGET_EQ (eq1_target, 1);
+ TARGET_EQ (eq2_target, 2);
+ TARGET_EQ (eq3_target, 3);
+ TARGET_EQ (eq4_target, 4);
+ TARGET_EQ (eq5_target, 5);
+ TARGET_EX (ex0_target, 0);
+ TARGET_EX (ex1_target, 1);
+ TARGET_EX (ex2_target, 2);
+ TARGET_EX (ex3_target, 3);
+ TARGET_EX (ex4_target, 4);
+ TARGET_EX (ex5_target, 5);
+ TARGET_EX (ex6_target, 6);
+ TARGET_EX (ex7_target, 7);
+ TARGET_EX (ex8_target, 8);
+ TARGET_EX (ex9_target, 9);
+ TARGET_EX (ex10_target, 10);
+ TARGET_EX (ex11_target, 11);
+ TARGET_CORE (core0_target, 0);
+ TARGET_CORE (core1_target, 1);
+ TARGET_CORE (core2_target, 2);
+ TARGET_CORE (core3_target, 3);
+ TARGET_CORE (core4_target, 4);
+ TARGET_CORE (core5_target, 5);
+ TARGET_CORE (core6_target, 6);
+ TARGET_CORE (core7_target, 7);
+ TARGET_CORE (core8_target, 8);
+ TARGET_CORE (core9_target, 9);
+ TARGET_CORE (core10_target,10);
+ TARGET_CORE (core11_target,11);
+ TARGET_CORE (core12_target,12);
+ TARGET_CORE (core13_target,13);
+ TARGET_CORE (core14_target,14);
+ TARGET_CORE (core15_target,15);
+ TARGET_CORE (core16_target,16);
+ TARGET_CORE (core17_target,17);
+ TARGET_CORE (core18_target,18);
+ TARGET_CORE (core19_target,19);
+ TARGET_CORE (core20_target,20);
+ TARGET_CORE (core21_target,21);
+ TARGET_CORE (core22_target,22);
+ TARGET_CORE (core23_target,23);
+
+}; // fapi2 namespace
+
+#endif // __FAPI2_PPE_TARGET__
diff --git a/src/hwpf/include/plat/plat_target_filter.H b/src/hwpf/include/plat/plat_target_filter.H
new file mode 100644
index 00000000..aec258ab
--- /dev/null
+++ b/src/hwpf/include/plat/plat_target_filter.H
@@ -0,0 +1,89 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_target_filter.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 __FAPI2_PLAT_TARGET_FILTER__
+#define __FAPI2_PLAT_TARGET_FILTER__
+
+#include <stdint.h>
+
+//
+// Define TargetFilter enum values for the platform
+//
+namespace fapi2
+{
+namespace PlatTargetFilter
+{
+// These values must contain only 1 bit 'on' so that they can be ORed
+// together as composite filters
+
+constexpr uint64_t PLAT_TARGET_FILTER_TP = 0x8000000000000000; // Pervasive 1
+constexpr uint64_t PLAT_TARGET_FILTER_NEST_NORTH = 0x4000000000000000; // Pervasive 2
+constexpr uint64_t PLAT_TARGET_FILTER_NEST_EAST = 0x2000000000000000; // Pervasive 3
+constexpr uint64_t PLAT_TARGET_FILTER_NEST_SOUTH = 0x1000000000000000; // Pervasive 4
+constexpr uint64_t PLAT_TARGET_FILTER_NEST_WEST = 0x0800000000000000; // Pervasive 5
+constexpr uint64_t PLAT_TARGET_FILTER_XBUS = 0x0400000000000000; // Pervasive 6
+constexpr uint64_t PLAT_TARGET_FILTER_MC_WEST = 0x0200000000000000; // Pervasive 7
+constexpr uint64_t PLAT_TARGET_FILTER_MC_EAST = 0x0100000000000000; // Pervasive 8
+constexpr uint64_t PLAT_TARGET_FILTER_OBUS0 = 0x0080000000000000; // Pervasive 9
+constexpr uint64_t PLAT_TARGET_FILTER_OBUS1 = 0x0040000000000000; // Pervasive 10
+constexpr uint64_t PLAT_TARGET_FILTER_OBUS2 = 0x0020000000000000; // Pervasive 11
+constexpr uint64_t PLAT_TARGET_FILTER_OBUS3 = 0x0010000000000000; // Pervasive 12
+constexpr uint64_t PLAT_TARGET_FILTER_PCI0 = 0x0008000000000000; // Pervasive 13
+constexpr uint64_t PLAT_TARGET_FILTER_PCI1 = 0x0004000000000000; // Pervasive 14
+constexpr uint64_t PLAT_TARGET_FILTER_PCI2 = 0x0002000000000000; // Pervasive 15
+constexpr uint64_t PLAT_TARGET_FILTER_CACHE0 = 0x0001000000000000; // Pervasive 16
+constexpr uint64_t PLAT_TARGET_FILTER_CACHE1 = 0x0000800000000000; // Pervasive 17
+constexpr uint64_t PLAT_TARGET_FILTER_CACHE2 = 0x0000400000000000; // Pervasive 18
+constexpr uint64_t PLAT_TARGET_FILTER_CACHE3 = 0x0000200000000000; // Pervasive 19
+constexpr uint64_t PLAT_TARGET_FILTER_CACHE4 = 0x0000100000000000; // Pervasive 20
+constexpr uint64_t PLAT_TARGET_FILTER_CACHE5 = 0x0000080000000000; // Pervasive 21
+constexpr uint64_t PLAT_TARGET_FILTER_CORE0 = 0x0000040000000000; // Pervasive 32
+constexpr uint64_t PLAT_TARGET_FILTER_CORE1 = 0x0000020000000000; // Pervasive 33
+constexpr uint64_t PLAT_TARGET_FILTER_CORE2 = 0x0000010000000000; // Pervasive 34
+constexpr uint64_t PLAT_TARGET_FILTER_CORE3 = 0x0000008000000000; // Pervasive 35
+constexpr uint64_t PLAT_TARGET_FILTER_CORE4 = 0x0000004000000000; // Pervasive 36
+constexpr uint64_t PLAT_TARGET_FILTER_CORE5 = 0x0000002000000000; // Pervasive 37
+constexpr uint64_t PLAT_TARGET_FILTER_CORE6 = 0x0000001000000000; // Pervasive 38
+constexpr uint64_t PLAT_TARGET_FILTER_CORE7 = 0x0000000800000000; // Pervasive 39
+constexpr uint64_t PLAT_TARGET_FILTER_CORE8 = 0x0000000400000000; // Pervasive 40
+constexpr uint64_t PLAT_TARGET_FILTER_CORE9 = 0x0000000200000000; // Pervasive 41
+constexpr uint64_t PLAT_TARGET_FILTER_CORE10 = 0x0000000100000000; // Pervasive 42
+constexpr uint64_t PLAT_TARGET_FILTER_CORE11 = 0x0000000080000000; // Pervasive 43
+constexpr uint64_t PLAT_TARGET_FILTER_CORE12 = 0x0000000040000000; // Pervasive 44
+constexpr uint64_t PLAT_TARGET_FILTER_CORE13 = 0x0000000020000000; // Pervasive 45
+constexpr uint64_t PLAT_TARGET_FILTER_CORE14 = 0x0000000010000000; // Pervasive 46
+constexpr uint64_t PLAT_TARGET_FILTER_CORE15 = 0x0000000008000000; // Pervasive 47
+constexpr uint64_t PLAT_TARGET_FILTER_CORE16 = 0x0000000004000000; // Pervasive 48
+constexpr uint64_t PLAT_TARGET_FILTER_CORE17 = 0x0000000002000000; // Pervasive 49
+constexpr uint64_t PLAT_TARGET_FILTER_CORE18 = 0x0000000001000000; // Pervasive 50
+constexpr uint64_t PLAT_TARGET_FILTER_CORE19 = 0x0000000000800000; // Pervasive 51
+constexpr uint64_t PLAT_TARGET_FILTER_CORE20 = 0x0000000000400000; // Pervasive 52
+constexpr uint64_t PLAT_TARGET_FILTER_CORE21 = 0x0000000000200000; // Pervasive 53
+constexpr uint64_t PLAT_TARGET_FILTER_CORE22 = 0x0000000000100000; // Pervasive 54
+constexpr uint64_t PLAT_TARGET_FILTER_CORE23 = 0x0000000000080000; // Pervasive 55
+
+} // namespace PlatTargetFilter
+
+} // namespace fapi2
+
+#endif
diff --git a/src/hwpf/include/plat/plat_target_parms.H b/src/hwpf/include/plat/plat_target_parms.H
new file mode 100644
index 00000000..17103a78
--- /dev/null
+++ b/src/hwpf/include/plat/plat_target_parms.H
@@ -0,0 +1,92 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_target_parms.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 plat_ppe_target.H
+ * @brief Definitions for fapi2 PPE targets
+ */
+
+#ifndef __FAPI2_PPE_TARGET_PARMS__
+#define __FAPI2_PPE_TARGET_PARMS__
+
+#include "fapi_sbe_common.H"
+
+
+CONST_UINT32_T(CHIP_TARGET_OFFSET, 0);
+CONST_UINT32_T(CHIP_TARGET_COUNT , 1);
+
+// Nest targets - Group 1
+CONST_UINT32_T(NEST_GROUP1_TARGET_OFFSET, CHIP_TARGET_OFFSET + CHIP_TARGET_COUNT);
+CONST_UINT32_T(NEST_GROUP1_CHIPLET_OFFSET, 0x1);
+CONST_UINT32_T(NEST_GROUP1_TARGET_COUNT, 6);
+
+// MCBIST targets
+CONST_UINT32_T(MCBIST_TARGET_OFFSET, NEST_GROUP1_TARGET_OFFSET + NEST_GROUP1_TARGET_COUNT);
+CONST_UINT32_T(MCBIST_CHIPLET_OFFSET, 0x7);
+CONST_UINT32_T(MCBIST_TARGET_COUNT, 2);
+
+// Nest targets - Group 2
+CONST_UINT32_T(NEST_GROUP2_TARGET_OFFSET, MCBIST_TARGET_OFFSET + MCBIST_TARGET_COUNT);
+CONST_UINT32_T(NEST_GROUP2_TARGET_COUNT, 7);
+CONST_UINT32_T(NEST_GROUP2_CHIPLET_OFFSET, 0x9);
+
+// Cache Targets
+CONST_UINT32_T(EQ_TARGET_OFFSET, NEST_GROUP2_TARGET_OFFSET + NEST_GROUP2_TARGET_COUNT);
+CONST_UINT32_T(EQ_CHIPLET_OFFSET, 0x10);
+CONST_UINT32_T(EQ_TARGET_COUNT, 6);
+
+// Core Targets
+CONST_UINT32_T(CORE_TARGET_OFFSET, EQ_TARGET_OFFSET + EQ_TARGET_COUNT);
+CONST_UINT32_T(CORE_CHIPLET_OFFSET, 0x20);
+CONST_UINT32_T(CORE_TARGET_COUNT, 24);
+
+// Ex Targets
+CONST_UINT32_T(EX_TARGET_OFFSET, CORE_TARGET_OFFSET + CORE_TARGET_COUNT);
+CONST_UINT32_T(EX_CHIPLET_OFFSET, 0x10);
+CONST_UINT32_T(EX_TARGET_COUNT, 12);
+
+// MCS Targets
+CONST_UINT32_T(MCS_TARGET_OFFSET, EX_TARGET_OFFSET + EX_TARGET_COUNT);
+CONST_UINT32_T(MCS_TARGET_COUNT, 4);
+
+// System Target
+CONST_UINT32_T(SYSTEM_TARGET_OFFSET, MCS_TARGET_OFFSET + MCS_TARGET_COUNT);
+CONST_UINT32_T(SYSTEM_TARGET_COUNT, 1);
+
+CONST_UINT32_T(MCAST_TARGET_OFFSET, SYSTEM_TARGET_OFFSET + SYSTEM_TARGET_COUNT);
+CONST_UINT32_T(MCAST_CHIPLET_OFFSET, 4);
+CONST_UINT32_T(MCAST_TARGET_COUNT, 3); // PPE only needs multicast groups 4-6
+
+// Total number of pervasive targets (Both NEST groups + EQs + COREs +MCBISTs)
+CONST_UINT32_T(PERV_TARGET_COUNT, NEST_GROUP1_TARGET_COUNT + NEST_GROUP2_TARGET_COUNT +
+ MCBIST_TARGET_COUNT + EQ_TARGET_COUNT + CORE_TARGET_COUNT);
+
+// Total Target Count
+CONST_UINT32_T(TARGET_COUNT, CHIP_TARGET_COUNT +
+ PERV_TARGET_COUNT +
+ EX_TARGET_COUNT +
+ MCS_TARGET_COUNT +
+ SYSTEM_TARGET_COUNT +
+ MCAST_TARGET_COUNT);
+
+#endif // __FAPI2_PPE_TARGET_PARMS__
diff --git a/src/hwpf/include/plat/plat_target_utils.H b/src/hwpf/include/plat/plat_target_utils.H
new file mode 100644
index 00000000..c6ec5f37
--- /dev/null
+++ b/src/hwpf/include/plat/plat_target_utils.H
@@ -0,0 +1,86 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_target_utils.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 plat_target_util.H
+ * @brief platform utility definitions for fapi2 targets
+ */
+
+#ifndef __FAPI2_PLAT_TARGET_UTIL__
+#define __FAPI2_PLAT_TARGET_UTIL__
+
+#pragma pack(8) //Start of packing to 8byte boundary
+ typedef struct {
+ fapi2attr::SystemAttributes_t G_system_attrs;
+ fapi2attr::ProcChipAttributes_t G_proc_chip_attrs;
+ fapi2attr::PervAttributes_t G_perv_attrs;
+ fapi2attr::CoreAttributes_t G_core_attrs;
+ fapi2attr::EXAttributes_t G_ex_attrs;
+ fapi2attr::EQAttributes_t G_eq_attrs;
+ } G_sbe_attrs_t;
+#pragma pack()//End of packing to 8byte boundary
+
+//
+// Platform Utility functions..
+//
+namespace fapi2
+{
+ /// @brief Function to initialize the G_targets vector based on partial good
+ /// attributes
+ ReturnCode plat_TargetsInit();
+
+ /// @brief Function to apply any gard records set (via
+ // ATTR_EQ_GARD/ATTR_EC_GARD) to mark corresponding targets non functional
+ ReturnCode plat_ApplyGards();
+
+ /// @brief Function to initialize the G_targets vector based on partial good
+ /// attributes
+ Target<TARGET_TYPE_PROC_CHIP> plat_getChipTarget();
+
+ /// @brief Function to return a platform target handle, given the chiplet
+ // number and the fapi2 Target type
+ // @tparam K The fapi2 TargetType
+ // @param i_chipletNumber The chiplet number of the target
+ // @return Platform handle
+ // @note The caller can use the platform handle to construct a Target of
+ // it's choice. Ex:
+ // fapi2::Target<fapi2::TARGET_TYPE_CORE>
+ // l_core(plat_getTargetHandleByChipletNumber<fapi2::TARGET_TYPE_CORE>(0x20);
+ template <TargetType K>
+ plat_target_handle_t plat_getTargetHandleByChipletNumber(
+ const uint8_t i_chipletNumber);
+
+ /// @brief Function to return a platform target handle, given the target
+ /// instance number and the fapi2 Target type
+ // @tparam K The fapi2 TargetType
+ // @param i_targetNum The instance number for the target
+ // @return Platform handle
+ // @note The caller can use the platform handle to construct a Target of
+ // it's choice. Ex:
+ // fapi2::Target<fapi2::TARGET_TYPE_EX>
+ // l_ex(plat_getTargetHandleByInstance<fapi2::TARGET_TYPE_EX>(0);
+ template <TargetType K>
+ plat_target_handle_t plat_getTargetHandleByInstance(
+ const uint8_t i_targetNum);
+}
+#endif
diff --git a/src/hwpf/include/plat/plat_trace.H b/src/hwpf/include/plat/plat_trace.H
new file mode 100644
index 00000000..e4a2463f
--- /dev/null
+++ b/src/hwpf/include/plat/plat_trace.H
@@ -0,0 +1,113 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/plat_trace.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* */
+/* */
+/* 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 plat_trace.H
+ * @brief Defines the FAPI2 trace macros.
+ *
+ * Note that platform code must provide the implementation.
+ *
+ * FAPI has provided a default implementation. Platform code must
+ * provide an alternate implementation if needed.
+ */
+
+#ifndef FAPI2_PLATTRACE_H_
+#define FAPI2_PLATTRACE_H_
+
+#include <stdint.h>
+
+// @todo update these headers with extern "C" in a future commit
+// or not and leave this just as it is.
+extern "C"
+{
+#include "pk.h"
+#include <pk_trace.h>
+#include "trac_interface.h"
+}
+
+// Why not a #define, why is this in the fapi2 namespace?
+// To prevent problems with Cronus and the fapi1 definitions.
+namespace fapi2
+{
+ static const uint32_t MAX_ECMD_STRING_LEN = 64;
+};
+
+// Information traces (go into fast trace buffer that can wrap often)
+#define FAPI_TRACE(_id_, _fmt_, _args_...) \
+ PK_TRACE(_fmt_, ##_args_);
+
+
+/* The following is a desirous trace entry but the second line has a
+ compilation issue that is unresolved
+
+#define FAPI_TRACE(_id_, _fmt_, _args_...) \
+ PK_TRACE("%s: %s:%d ", _id_, __FUNCTION__, __LINE__); \
+ PK_TRACE(_fmt_, ##_args_);
+*/
+// FAPI_TRACE_LEVEL controls what traces are included in the code build
+// 0 == No tracing
+// 1 == ERR traces only
+// 2 == ERR and IMP only
+// 3 == ERR, IMP and INF only. This is the default in Makefile
+// > 4 == All traces (ERR, IMP, INF, DBG, SCAN, MFG)
+#if (FAPI_TRACE_LEVEL >= 3)
+#define FAPI_INF(_fmt_, _args_...) FAPI_TRACE("inf", _fmt_, ##_args_)
+#else
+#define FAPI_INF(_fmt_, _args_...)
+#endif
+
+// Important traces (go into slow trace buffer that should not wrap often)
+#if (FAPI_TRACE_LEVEL >= 2)
+#define FAPI_IMP(_fmt_, _args_...) FAPI_TRACE("imp", _fmt_, ##_args_)
+#else
+#define FAPI_IMP(_fmt_, _args_...)
+#endif
+
+// Error traces (go into slow trace buffer that should not wrap often)
+#if (FAPI_TRACE_LEVEL >= 1)
+#define FAPI_ERR(_fmt_, _args_...) FAPI_TRACE("err", _fmt_, ##_args_)
+#else
+#define FAPI_ERR(_fmt_, _args_...)
+#endif
+
+// Debug traces (go into fast trace buffer that can wrap often)
+#if (FAPI_TRACE_LEVEL >= 4)
+#define FAPI_DBG(_fmt_, _args_...) FAPI_TRACE("dbg", _fmt_, ##_args_)
+#else
+#define FAPI_DBG(_fmt_, _args_...)
+#endif
+
+// Scan traces
+#if (FAPI_TRACE_LEVEL >= 4)
+#define FAPI_SCAN(_fmt_, _args_...) FAPI_TRACE("scan", _fmt_, ##_args_)
+#else
+#define FAPI_SCAN(_fmt_, _args_...)
+#endif
+
+#if (FAPI_TRACE_LEVEL >= 4)
+#define FAPI_MFG(_fmt_, _args_...) FAPI_TRACE("mfg", _fmt_, ##_args_)
+#else
+#define FAPI_MFG(_fmt_, _args_...)
+#endif
+
+#endif // FAPI2_PLATTRACE_H_
diff --git a/src/hwpf/include/plat/target.H b/src/hwpf/include/plat/target.H
new file mode 100644
index 00000000..01250260
--- /dev/null
+++ b/src/hwpf/include/plat/target.H
@@ -0,0 +1,434 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/plat/target.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 target.H
+ * @brief platform specializations for fapi2 targets
+ */
+
+#ifndef __FAPI2_TARGET__
+#define __FAPI2_TARGET__
+
+#include <plat_target.H>
+#include <plat_target_parms.H>
+#include <fapi2_target.H>
+#include <multicast.H>
+#include <plat_trace.H>
+#include <utils.H>
+#include <stdint.h>
+#include <vector>
+
+extern "C"
+{
+ extern std::vector<fapi2::plat_target_handle_t> G_vec_targets;
+}
+
+struct ScomAddr
+{
+ ScomAddr(uint32_t i_addr) : iv_addr(i_addr)
+ {
+ }
+
+ operator uint32_t()
+ {
+ return iv_addr;
+ }
+
+ union
+ {
+ struct
+ {
+ uint32_t iv_unused : 1;
+ uint32_t iv_multicast : 1;
+ uint32_t iv_chiplet : 6;
+ uint32_t iv_pibMaster : 4;
+ uint32_t iv_port : 4;
+ uint32_t iv_unused2 : 2;
+ uint32_t iv_ring : 4;
+ uint32_t iv_satId : 4;
+ uint32_t iv_satOffset : 6;
+ };
+ uint32_t iv_addr;
+ };
+};
+
+
+namespace fapi2
+{
+
+ template<TargetType T>
+ constexpr plat_target_type_t fapiTargetTypeToPlatTargetType()
+ {
+ return PPE_TARGET_TYPE_NONE;
+ }
+
+ template<>
+ constexpr plat_target_type_t fapiTargetTypeToPlatTargetType<TARGET_TYPE_PROC_CHIP>()
+ {
+ return PPE_TARGET_TYPE_PROC_CHIP;
+ }
+
+ template<>
+ constexpr plat_target_type_t fapiTargetTypeToPlatTargetType<TARGET_TYPE_EQ>()
+ {
+ return PPE_TARGET_TYPE_EQ;
+ }
+
+ template<>
+ constexpr plat_target_type_t fapiTargetTypeToPlatTargetType<TARGET_TYPE_CORE>()
+ {
+ return PPE_TARGET_TYPE_CORE;
+ }
+
+ template<>
+ constexpr plat_target_type_t fapiTargetTypeToPlatTargetType<TARGET_TYPE_EX>()
+ {
+ return PPE_TARGET_TYPE_EX;
+ }
+
+ template<>
+ constexpr plat_target_type_t fapiTargetTypeToPlatTargetType<TARGET_TYPE_MCS>()
+ {
+ return PPE_TARGET_TYPE_MCS;
+ }
+
+ template<>
+ constexpr plat_target_type_t fapiTargetTypeToPlatTargetType<TARGET_TYPE_MCBIST>()
+ {
+ return PPE_TARGET_TYPE_MCBIST;
+ }
+
+ template<>
+ constexpr plat_target_type_t fapiTargetTypeToPlatTargetType<TARGET_TYPE_PERV>()
+ {
+ return PPE_TARGET_TYPE_PERV;
+ }
+
+ ///
+ /// @brief Assignment Operator.
+ /// @param[in] i_right Reference to Target to assign from.
+ /// @return Reference to 'this' Target
+ ///
+ template<TargetType K, typename V>
+ Target<K, V>& Target<K, V>::operator=(const Target& i_right)
+ {
+ this->iv_handle.value = i_right.iv_handle.value;
+ return *this;
+ }
+ ///
+ /// @brief Equality Comparison Operator
+ /// @param[in] i_right Reference to Target to compare.
+ /// @return bool. True if equal.
+ /// @note Platforms need to define this so that the physical
+ /// targets are determined to be equivilent rather than just the handles
+ ///
+ template<TargetType K, typename V>
+ bool Target<K, V>::operator==(const Target& i_right) const
+ {
+ if (this->iv_handle.value == i_right.iv_handle.value)
+ return true;
+ else
+ return false;
+ }
+
+ ///
+ /// @brief Inquality Comparison Operator
+ /// @param[in] i_right Reference to Target to compare.
+ /// @return bool. True if not equal.
+ /// @note Platforms need to define this so that the physical
+ /// targets are determined to be equivilent rather than just the handles
+ ///
+ template<TargetType K, typename V>
+ bool Target<K, V>::operator!=(const Target& i_right) const
+ {
+ if (this->iv_handle.value != i_right.iv_handle.value)
+ return true;
+ else
+ return false;
+ }
+
+ ///
+ /// @brief Get this target's immediate parent
+ /// @tparam T The type of the parent
+ /// @return Target<T, V> a target representing the parent
+ ///
+ template<TargetType K, typename V>
+ template<TargetType T>
+ inline Target<T, V> Target<K, V>::getParent(void) const
+ {
+ static_assert(((K == TARGET_TYPE_EQ) ||
+ (K == TARGET_TYPE_CORE) ||
+ (K == TARGET_TYPE_MCBIST) ||
+ (K == TARGET_TYPE_PERV) ||
+ (K == TARGET_TYPE_EX) ||
+ (K == TARGET_TYPE_PROC_CHIP) ||
+ (K == (TARGET_TYPE_PROC_CHIP | TARGET_TYPE_EQ)) ||
+ (K == (TARGET_TYPE_PROC_CHIP | TARGET_TYPE_CORE))) &&
+ ((T == TARGET_TYPE_EQ) ||
+ (T == TARGET_TYPE_EX) ||
+ (T == TARGET_TYPE_PROC_CHIP) ||
+ (T == TARGET_TYPE_PERV)),
+ "Invalid parent/child target type passed");
+
+ static_assert(!((K == TARGET_TYPE_EQ) &&
+ (T != TARGET_TYPE_PERV) &&
+ (T != TARGET_TYPE_PROC_CHIP)),
+ "Invalid parent for EQ target, must be PERV or "
+ "PROC_CHIP");
+
+ static_assert(!((K == TARGET_TYPE_MCBIST) &&
+ (T != TARGET_TYPE_PERV) &&
+ (T != TARGET_TYPE_PROC_CHIP)),
+ "Invalid parent for MCBIST target, must be PERV or "
+ "PROC_CHIP");
+
+ static_assert(!((K == TARGET_TYPE_CORE) &&
+ (T != TARGET_TYPE_PERV) &&
+ (T != TARGET_TYPE_PROC_CHIP) &&
+ (T != TARGET_TYPE_EQ) &&
+ (T != TARGET_TYPE_EX)),
+ "Invalid parent for CORE target, must be PERV or "
+ "PROC_CHIP or EQ or EX");
+
+ static_assert(!((K == TARGET_TYPE_PERV) &&
+ (T != TARGET_TYPE_PERV) &&
+ (T != TARGET_TYPE_PROC_CHIP)),
+ "Invalid parent for PERV target, must be PERV or "
+ "PROC_CHIP");
+
+ static_assert(!((K == TARGET_TYPE_EX) &&
+ (T != TARGET_TYPE_PROC_CHIP) &&
+ (T != TARGET_TYPE_EQ)),
+ "Invalid parent for EX target, must be PERV or "
+ "PROC_CHIP or EQ");
+
+ if(TARGET_TYPE_PERV == T) // EQ/EC/MCBIST/PERV ===> PERV
+ {
+ return static_cast<V>(this->iv_handle);
+ }
+ if(TARGET_TYPE_PROC_CHIP == T) // EQ/EC/EX/MCBIST/PERV ===> PROC
+ {
+ return static_cast<V>(G_vec_targets[CHIP_TARGET_OFFSET]);
+ }
+ if((TARGET_TYPE_EQ == T) && (TARGET_TYPE_CORE == K)) // EC ===> EQ
+ {
+ return static_cast<V>(G_vec_targets[(getTargetNumber() / CORES_PER_QUAD) + EQ_TARGET_OFFSET]);
+ }
+ if((TARGET_TYPE_EQ == T) && (TARGET_TYPE_EX == K)) // EX ===> EQ
+ {
+ return static_cast<V>(G_vec_targets[(getTargetNumber() / EX_PER_QUAD) + EQ_TARGET_OFFSET]);
+ }
+ if(TARGET_TYPE_EX == T) // EC ===> EX
+ {
+ return static_cast<V>(G_vec_targets[(getTargetNumber() / CORES_PER_EX) + EX_TARGET_OFFSET]);
+ }
+ }
+
+ /// @brief Get this target's children - handles EQ/EX/EC conversions
+ /// @tparam K The type of parent
+ /// @tparam V The plat target handle type
+ /// @tparam T The type of child
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return std::vector<Target<T, V> > a vector of present/functional
+ /// children
+ /// @warning The children are returned in order, ex child[0] is
+ /// std::vector[0]
+ template<TargetType K, typename V>
+ template<TargetType T>
+ std::vector<Target<T, V>>
+ Target<K, V>::getChildren(const TargetState i_state) const
+ {
+ constexpr TargetType L = static_cast<TargetType>(K & ~(TARGET_TYPE_PROC_CHIP));
+ constexpr plat_target_type_t P = fapiTargetTypeToPlatTargetType<T>();
+
+ static_assert(sizeof(Target<T, V>) == sizeof(plat_target_handle_t),
+ "Sizes of plat target and FAPI target must match");
+
+ static_assert(((L == TARGET_TYPE_EQ) || (L == TARGET_TYPE_EX) || (K == TARGET_TYPE_PROC_CHIP)),
+ "Invalid parent passed to getChildren");
+ // valid children for EQ
+ // EQ -> CORE
+ // EQ -> EX
+ static_assert(!((L == fapi2::TARGET_TYPE_EQ) &&
+ (T != fapi2::TARGET_TYPE_CORE) &&
+ (T != fapi2::TARGET_TYPE_EX)),
+ "improper child of fapi2::TARGET_TYPE_EQ");
+
+ // valid children for EX
+ // EX -> CORE
+ static_assert(!((L == fapi2::TARGET_TYPE_EX) &&
+ (T != fapi2::TARGET_TYPE_CORE)),
+ "improper child of fapi2::TARGET_TYPE_EX");
+
+
+ std::vector<Target<T, V> > l_children;
+ static_cast<plat_target_handle_t>(get()).getChildren(K, T, P, i_state, reinterpret_cast<std::vector<plat_target_handle>&>(l_children));
+ return l_children;
+ }
+
+ // Specialization of getChildren, filtered for the chip target
+ template<TargetType K, typename V>
+ template<TargetType T>
+ std::vector<Target<T, V> >
+ Target<K, V>::getChildren(const TargetFilter i_filter,
+ const TargetState i_state) const
+ {
+ static_assert(sizeof(Target<T, V>) == sizeof(plat_target_handle_t),
+ "Sizes of plat target and FAPI target must match");
+
+ static_assert((K == TARGET_TYPE_PROC_CHIP), "Parent target must be the proc chip");
+ static_assert((T == TARGET_TYPE_EQ) || (T == TARGET_TYPE_CORE)
+ || (T == TARGET_TYPE_PERV) || (T == TARGET_TYPE_MCBIST),
+ "Child target type must be a pervasive chiplet");
+
+ std::vector<Target<T> > l_children;
+
+ (static_cast<plat_target_handle_t>(get())).getChildren(i_filter, i_state, reinterpret_cast<std::vector<plat_target_handle_t>&>(l_children));
+
+ return l_children;
+ }
+
+ ///
+ /// @brief Get the target at the other end of a bus - dimm included
+ /// @tparam T The type of the parent
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return Target<T, V> a target representing the thing on the other end
+ /// @note Can be easily changed to a vector if needed
+ ///
+ template<TargetType K, typename V>
+ template<TargetType T>
+ inline Target<T, V>
+ Target<K, V>::getOtherEnd(const TargetState i_state) const
+ {
+// static_assert( false, "getOtherEnd() is not supported on PPE platforms");
+ }
+
+ ///
+ /// @brief Is the target functional?
+ /// @return true if target is functional, false if non-functional
+ ///
+
+ template<TargetType K, typename V>
+ inline bool
+ Target<K, V>::isFunctional(void) const
+ {
+ return getFunctional();
+ }
+
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @param[in] i_target Target<T>
+ /// @param[in] i_buffer buffer to write in to
+ /// @param[in] i_bsize size of the buffer
+ /// @return void
+ /// @post The contents of the buffer is replaced with the string
+ /// representation of the target
+ ///
+ template< TargetType T, typename V >
+ inline void toString(const Target<T, V>& i_target, char* i_buffer, size_t i_bsize)
+ {
+ snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target.get(), T);
+ }
+
+ template<TargetType T, typename V>
+ __attribute__((always_inline))
+ inline uint32_t getEffectiveAddress(const Target<T, V> &i_target,
+ const uint32_t i_addr)
+ {
+ ScomAddr l_addr = i_addr;
+ if(0 != i_target.getAddressOverlay())
+ {
+ l_addr.iv_chiplet = i_target.getChipletNumber();
+ }
+ return l_addr;
+ }
+
+ inline uint32_t getEffectiveAddress(const Target<TARGET_TYPE_EX> &i_target,
+ const uint32_t i_addr)
+ {
+ ScomAddr l_addr = i_addr;
+
+ if((EQ_CHIPLET_OFFSET <= l_addr.iv_chiplet) &&
+ ((EQ_CHIPLET_OFFSET + EQ_TARGET_COUNT) > l_addr.iv_chiplet))
+ {
+ l_addr.iv_chiplet = i_target.getChipletNumber();
+ l_addr.iv_ring = (l_addr.iv_ring - (l_addr.iv_ring % 2)) +
+ (i_target.getTargetNumber() % 2);
+ }
+ else if ((CORE_CHIPLET_OFFSET <= l_addr.iv_chiplet) &&
+ ((CORE_CHIPLET_OFFSET + CORE_TARGET_COUNT) > l_addr.iv_chiplet))
+ {
+ l_addr.iv_chiplet = CORE_CHIPLET_OFFSET + (l_addr.iv_chiplet % 2) +
+ (i_target.getTargetNumber() * 2);
+ }
+ else
+ {
+ assert(false);
+ }
+ return l_addr;
+ }
+
+ inline uint32_t getEffectiveAddress(const Target<TARGET_TYPE_MCS> &i_target,
+ const uint32_t i_addr)
+ {
+ ScomAddr l_addr = i_addr;
+ l_addr.iv_chiplet = i_target.getChipletNumber();
+ l_addr.iv_satId = (2 * (i_target.getTargetNumber() % 2));
+ return l_addr;
+ }
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @tparam B The type of the buffer
+ /// @param[in] A pointer to the Target<T, V>
+ /// @param[in] i_buffer buffer to write in to
+ /// @param[in] i_bsize size of the buffer
+ /// @return void
+ /// @post The contents of the buffer is replaced with the string
+ /// representation of the target
+ ///
+ template< TargetType T, typename V >
+ inline void toString(const Target<T, V>* i_target, char* i_buffer, size_t i_bsize)
+ {
+ snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target->get(), T);
+ }
+
+ ///
+ /// @brief Get an enumerated target of a specific type
+ /// @tparam T The type of the target
+ /// @param[in] Ordinal representing the ordinal number of
+ /// the desired target
+ /// @return Target<T, V> the target requested
+ ///
+ template<TargetType T, typename V>
+ inline Target<T, V> getTarget(uint64_t Ordinal)
+ {
+ // For testing
+ return Target<T, V>(Ordinal);
+ }
+}
+
+#endif
diff --git a/src/hwpf/include/return_code.H b/src/hwpf/include/return_code.H
new file mode 100644
index 00000000..385dd676
--- /dev/null
+++ b/src/hwpf/include/return_code.H
@@ -0,0 +1,107 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/return_code.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 return_code.H
+ * @brief definitions for fapi2 return codes
+ */
+
+#ifndef __FAPI2_RETURN_CODE__
+#define __FAPI2_RETURN_CODE__
+
+#include <stdint.h>
+#include <return_code_defs.H>
+
+#ifndef FAPI2_NO_FFDC
+#include <ffdc.H>
+#endif
+
+namespace fapi2
+{
+ ///
+ /// @brief Class representing a FAPI2 ReturnCode
+ ///
+ // Remove the inheritance relationship with FirstFailureData if
+ // the platform doesn't support FFDC.
+#if defined(FAPI2_NO_FFDC) || defined (MINIMUM_FFDC)
+ class ReturnCode
+#else
+ class ReturnCode : public FirstFailureData<ReturnCode>
+#endif
+ {
+ public:
+
+ ///
+ /// @brief Constructor.
+ /// @param[in] i_rc the rc to set
+ ///
+ ReturnCode(const uint32_t i_rc = FAPI2_RC_SUCCESS):
+ iv_rc(i_rc)
+ {};
+
+ ///
+ /// @brief integral type conversion function. Returns the error code
+ /// @return The error code
+ ///
+ inline operator uint32_t() const { return iv_rc; }
+
+ ///
+ /// @brief Returns true if iv_rc != SUCCESS
+ /// @return true or false
+ ///
+ inline operator bool() const { return iv_rc != FAPI2_RC_SUCCESS; }
+
+ ///
+ /// @brief Assignement operator
+ ///
+#ifdef DOXYGEN
+ inline ReturnCode& operator=(const uint32_t& rhs)
+ inline ReturnCode& operator=(const ReturnCodes& rhs)
+#endif
+
+ inline bool operator==(const uint32_t& rhs) const
+ { return rhs == iv_rc; }
+
+ inline bool operator==(const ReturnCodes& rhs) const
+ { return rhs == iv_rc; }
+
+ inline bool operator!=(const uint32_t& rhs) const
+ { return rhs != iv_rc; }
+
+ inline bool operator!=(const ReturnCodes& rhs) const
+ { return rhs != iv_rc; }
+
+ private:
+ uint32_t iv_rc;
+ };
+
+ /// This implementation assumes no exception handling and leverages thread-local
+ /// storage. For platforms without thread support, a global variable will
+ /// suffice for the error state.
+// extern thread_local ReturnCode current_err; /// the current error state
+ extern ReturnCode current_err; /// the current error state
+ extern thread_local uint64_t pib_error_mask; /// the pib mask
+ extern thread_local uint64_t operational_state; /// the operational mode
+}
+#endif
+
diff --git a/src/hwpf/include/set_sbe_error.H b/src/hwpf/include/set_sbe_error.H
new file mode 100644
index 00000000..ed817cdf
--- /dev/null
+++ b/src/hwpf/include/set_sbe_error.H
@@ -0,0 +1,23 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/set_sbe_error.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
diff --git a/src/hwpf/include/utils.H b/src/hwpf/include/utils.H
new file mode 100644
index 00000000..71de13ad
--- /dev/null
+++ b/src/hwpf/include/utils.H
@@ -0,0 +1,122 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/utils.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 utils.H
+ *
+ * @brief Defines common utility elements for FAPI2 use.
+ */
+
+#ifndef FAPI2_UTILS_H_
+#define FAPI2_UTILS_H_
+
+#include <return_code.H>
+
+#ifdef __ASSEMBLER__
+
+#ifndef ULL
+#define ULL(x) x
+#endif
+
+#else
+
+#ifndef ULL
+#define ULL(x) x##ull
+
+#endif
+
+#endif // __ASSEMBLER
+
+/// Create a multi-bit mask of \a n bits starting at bit \a b
+#ifndef BITS
+ #define BITS(b, n) ((ULL(0xffffffffffffffff) << (64 - (n))) >> (b))
+#endif
+
+/// Create a single bit mask at bit \a b
+#ifndef BIT
+ #define BIT(b) BITS((b), 1)
+#endif
+
+#ifdef _BIG_ENDIAN
+
+#define revle16(x) x
+#define revle32(x) x
+#define revle64(x) x
+
+#else
+
+uint16_t revle16(uint16_t i_x);
+uint32_t revle32(uint32_t i_x);
+uint64_t revle64(uint64_t i_x);
+
+#endif
+
+namespace fapi2
+{
+///
+/// @brief Delay this thread. Hostboot will use the nanoseconds parameter
+/// and make a syscall to nanosleep. While in the syscall, the hostboot
+/// kernel will continue to consume CPU cycles as it looks for a runnable
+/// task. When the delay time expires, the task becomes runnable and will soon
+/// return from the syscall. Callers of delay() in the hostboot environment
+/// will likely have to know the mHz clock speed they are running on and
+/// compute a non-zero value for i_nanoSeconds.
+///
+/// On the FSP, it was sometimes acceptable to just provide zero for the
+/// sleep delay time, causing the task to yield its time slice. By the
+/// time the calling task could run again, it was pretty certain enough
+/// host cycles had past. This is probably not acceptable in
+/// the hostboot environment. Callers should calculate and provide a
+/// sleep value in nanoseconds relative to host clock speed.
+///
+/// On FSP when VBU is the target, then the i_simCycles parameter will be
+/// used instead. The FSP needs to use the simdispatcher client/server
+/// API and issue a command to the awan to advance the simulation the
+/// specified number of cycles.
+///
+/// On SBE when __FAPI_DELAY_SIM__ is defined, then the i_simCycles parameter
+/// will be used instead and will use the number passed. The build parameter
+/// __FAPI_DELAY_SIM_CYCLES__ allows the delay to adjust for the number of
+/// simulation cycles that the PPE engine is running at. The delay algorithm
+/// takes the i_simCycles parameter, subtracts the loop overhead instructions
+/// times __FAPI_DELAY_SIM_CYCLES__ and then divides the remainder by the
+/// number of loop instructions times __FAPI_DELAY_SIM_CYCLES__.
+///
+/// On SBE when __FAPI_DELAY_SIM__ is NOT defined, the nanoseconds parameter
+/// will bus used to loop on the a call to pk_timebase32_get() function to
+/// determine the elapsed time. pk_sleep() is NOT used as there are not
+/// other threads to dispatch.
+///
+/// @param[in] i_nanoSeconds nanoseconds to sleep
+/// @param[in] i_simCycles count of Awan cycles to advance
+/// @param[in] i_fixed Determination, for DFT, if this time is
+/// fixed or not. Defaults to non-fixed
+///
+/// @return ReturnCode. Zero on success, else platform specified error.
+///
+ReturnCode delay(uint64_t i_nanoSeconds,
+ uint64_t i_simCycles,
+ bool i_fixed = false);
+}
+
+#endif // FAPI2_UTILS_H_
diff --git a/src/hwpf/include/vector.H b/src/hwpf/include/vector.H
new file mode 100644
index 00000000..7dd03d79
--- /dev/null
+++ b/src/hwpf/include/vector.H
@@ -0,0 +1,850 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/include/vector.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 stl_vector
+#define stl_vector
+
+/**
+ * @file vector
+ * @brief simple stl vector template class declaration.
+ */
+
+#include <stddef.h>
+
+#if !defined( __STDC_LIMIT_MACROS)
+#define __STDC_LIMIT_MACROS
+#endif
+#include <stdint.h>
+//#include <new>
+#include <algorithm>
+#include <assert.h>
+
+namespace std
+{
+
+ /**
+ * @class vector
+ * subset of stl vector
+ * @note Does not support allocators, reverse iterators.
+ */
+ template <class T>
+ class vector
+ {
+ public:
+
+ typedef T * iterator;
+ typedef const T * const_iterator;
+ typedef T & reference;
+ typedef const T & const_reference;
+ typedef size_t size_type;
+ typedef size_t difference_type;
+ // typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T * pointer;
+ typedef const T * const_pointer;
+
+
+ protected:
+
+ pointer iv_start;
+ pointer iv_finish;
+ pointer iv_end_of_storage;
+
+ public:
+
+ /**
+ * Constructor default
+ * @post The vector is created with no elements. size() == 0, capacity() == 0
+ */
+ __attribute__ ((always_inline))
+ explicit vector(void)
+ :
+ iv_start(NULL),
+ iv_finish(NULL),
+ iv_end_of_storage(NULL)
+ {}
+
+
+ /**
+ * Constructor to create a vector of size n elements of value.
+ * @param[in] n number of elements to create
+ * @param[in] value used to create the n elements
+ * @post The vector is created with n elements of value.
+ * Storage allocated. size() == n, capacity() == n
+ */
+ explicit vector(size_type n, const T& value = T())
+ :
+ iv_start(NULL),
+ iv_finish(NULL),
+ iv_end_of_storage(NULL)
+ {
+ reserve(n);
+ iv_finish = iv_start+n;
+ ctor_fill(iv_start,iv_finish,value);
+ }
+
+
+ /**
+ * COPY CTOR create a vector from another vector
+ * @param[in] x source vector
+ * @post vector of x.size() is created from x with same # nodes
+ * size() == capacity() == x.size()
+ */
+ vector(const vector<T>& x)
+ :
+ iv_start(NULL),
+ iv_finish(NULL),
+ iv_end_of_storage(NULL)
+ {
+ reserve(x.size());
+ iv_finish = ctor_copy(x.iv_start, x.iv_finish, iv_start);
+ }
+
+ /**
+ * CTOR create a vector from a container slice
+ * @param[in] first iterator first in source sequence
+ * @param[in] last iterator one past end of source sequence
+ * @returns None.
+ * @pre last > first; first,last contained within source vector
+ * @post vector is created from slice given
+ */
+ template<typename InputIterator>
+ vector(InputIterator first, InputIterator last)
+ :
+ iv_start(NULL),
+ iv_finish(NULL),
+ iv_end_of_storage(NULL)
+ {
+ // assert(last >= first);
+ // input iterators only support operator ( ++i, i++,==,!=,*,->,=)
+ size_type n = 0;
+ for(InputIterator i = first; i != last; ++i) ++n;
+ reserve(n);
+ iv_finish = ctor_copy(first,last,iv_start);
+ }
+
+ /**
+ * DTOR
+ * @post Storage released
+ */
+ __attribute__ ((always_inline))
+ ~vector()
+ {
+ clear(); // call dtors
+ free_storage(iv_start);
+ }
+
+ /**
+ * Assignment operator.
+ * @param[in] x A vector.
+ * @return A vector (for the purpose of multiple assigns).
+ * @pre None.
+ * @post *this == x, this->capacity() == x.size().
+ * All previously obtained iterators are invalid.
+ */
+ vector<T>& operator=(const vector<T>& x)
+ {
+ clear();
+ reserve(x.size());
+ iv_finish = ctor_copy(x.iv_start, x.iv_finish, iv_start);
+ return(*this);
+ }
+
+ // Iterators --------------------
+
+ /**
+ * Get iterator to the first vector element
+ * @return iterator of rist vector element
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ iterator begin()
+ {
+ return (iv_start);
+ }
+
+ /**
+ * Get const_iterator to the first vector element
+ * @return const_iterator of rist vector element
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ const_iterator begin() const
+ {
+ return (iv_start);
+ }
+
+ /**
+ * Get iterator to the last vector element + 1
+ * @return iterator
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ iterator end()
+ {
+ return (iv_finish);
+ }
+
+ /**
+ * Get const_iterator to the last vector element + 1
+ * @return const_iterator
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ const_iterator end() const
+ {
+ return (iv_finish);
+ }
+
+ /* TODO - Implement only if needed
+ reverse_iterator rbegin()
+ {
+ return(iv_finish -1);
+ }
+
+ const_reverse_iterator rend()
+ {
+ return (iv_start - 1);
+ }
+ */
+
+ // Capacity -----------------------------------------------
+
+ /**
+ * Get the number of elements in the container
+ * @return number of elements in the container
+ */
+ __attribute__ ((always_inline))
+ size_type size() const
+ {
+ return(iv_finish - iv_start);
+ }
+
+ /**
+ * Return the maximum potential size the container could reach.
+ * @return number of the maximum element count this container could reach
+ */
+ __attribute__ ((always_inline))
+ size_type max_size() const
+ {
+ return UINT64_MAX/sizeof(T);
+ }
+
+ /**
+ * Resize the vector to contain n elements
+ * @param[in] n new size
+ * @param[in] x object used to copy to any added elements if size() is increased
+ * @post All previously obtained iterators are invalid.
+ * @node if n < size(), vector is truncated.
+ * if n > size(), vector is padded with copies of x
+ */
+ void resize( size_type n, T x = T());
+
+ /**
+ * Get the number of elements the vector can hold before needing to reallocate storage.
+ * @return element capacity of the vector
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ size_type capacity() const
+ {
+ return(iv_end_of_storage - iv_start);
+ }
+
+ /**
+ * Query for empty container
+ * @return bool, true if size()==0 else false.
+ * @pre none
+ * @post none
+ */
+ __attribute__ ((always_inline))
+ bool empty() const
+ {
+ return(size() == 0);
+ }
+
+ /**
+ * Reserve storage for a given number of elements
+ * @param[in] n The requested capacity of the vector
+ * @pre None
+ * @post If current cpacity() < n then new capcity == n; else no change.
+ * All previously obtained iterators are invalid
+ */
+ void reserve(size_type n);
+
+ // - Element Access -----------------------------------
+
+ /**
+ * Access a mutable reference to an element in the container
+ * @param An index into the vector
+ * @return A reference to an element
+ * @pre 0 <= n < size()
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ reference operator[](size_type n)
+ {
+ return(*(iv_start + n));
+ }
+
+ /**
+ * Access a mutable reference to an element in the container
+ * @param[in] index An index into the vector
+ * @return A reference to an element
+ * @pre 0 <= n < size()
+ * @post None.
+ * @note no exception handling
+ */
+ __attribute__ ((always_inline))
+ reference at(size_type index)
+ {
+ assert(index < size());
+ return(*(iv_start + index));
+ }
+
+ /**
+ * Get an immutable reference to an element in the container
+ * @param[in] index An index into the vector
+ * @return A const_reference to an object or type T
+ * @pre 0 <= n < size()
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ const_reference operator[](size_type index) const
+ {
+ assert(index < size());
+ return(*(iv_start + index));
+ }
+
+ /**
+ * Get an immutable reference to an element in the container
+ * @param[in] index An index into the vector
+ * @return A const_reference to an object or type T
+ * @pre 0 <= n < size()
+ * @post None.
+ * @note no exception handling
+ */
+ __attribute__ ((always_inline))
+ const_reference at(size_type index) const
+ {
+ assert(index < size());
+ return(*(iv_start + index));
+ }
+
+ /**
+ * Get a mutable reference to the first element in the container
+ * @return reference to first element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ reference front()
+ {
+ return *iv_start;
+ }
+
+ /**
+ * Get an Immutable reference to the first element in the container
+ * @return const_reference to first element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ const_reference front() const
+ {
+ return *iv_start;
+ }
+
+ /**
+ * Get a mutable reference to the last element in the container
+ * @return reference to last element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ reference back()
+ {
+ return *(iv_finish-1);
+ }
+
+ /**
+ * Get an Immutable reference to the last element in the container
+ * @return reference to last element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ const_reference back() const
+ {
+ return *(iv_finish-1);
+ }
+
+ // -- Modifiers -----------------------------
+
+ /*
+ * Assign new content to the vector object
+ * @param[n] first iterator to first element to copy in
+ * @param[n] last iterator to last element + 1 to copy in
+ */
+ template <class InputIterator>
+ void assign (InputIterator first, InputIterator last)
+ {
+ clear();
+ size_type n = 0;
+ for(InputIterator i = first; i != last; ++i) ++n;
+ reserve(n);
+ iv_finish = ctor_copy(first,last,iv_start);
+ }
+
+
+ /*
+ * Assign new content to the vector object
+ * @param[in] n number of elements to assign
+ * @param[in] x reference to element to copy in
+ */
+ void assign ( size_type n, const T& x)
+ {
+ clear();
+ reserve(n);
+ ctor_fill_n(iv_start,n,x);
+ iv_finish = iv_start + n;
+ }
+
+
+ /**
+ * Add element to the back of the container
+ * @param[in] x reference to object used to create new element
+ * @pre none
+ * @post All previously obtained iterators are invalid.
+ */
+ __attribute__ ((always_inline))
+ void push_back(const T& x)
+ {
+ reserve(size() + 1);
+ new (iv_finish++) T(x);
+ }
+
+ /**
+ * Remove the last element in the container
+ * @return nothing
+ * @pre size() > 0
+ * @post size() decreased by one
+ */
+ __attribute__ ((always_inline))
+ void pop_back()
+ {
+ erase(iv_finish-1,iv_finish);
+ }
+
+ /**
+ * Insert an element into the container at a given position
+ * @param[in] position iterator to position to insert
+ * @param[in] x reference of element to insert
+ * @pre begin() <= position < end()
+ * @post Element inserted at position, storage adjusted as needed.
+ * All previously obtained iterators are invalid.
+ */
+ iterator insert(iterator position, const T& x)
+ {
+ // iv_start will change if the vector gets resized - so save the offset for
+ // return.
+ difference_type offset = position - iv_start;
+ insert(position, 1, x);
+ return (iv_start + offset);
+ }
+
+ /**
+ * Insert a number of copies of a given elements at a given position
+ * @param[in] postion iterator, postion to insert elements
+ * @param[in] n number of elements to insert
+ * @param[in] x A reference to the object to uses to create the new elements
+ * @pre begin() <= postion < end()
+ * @post All previously obtained iterators are invalid.
+ */
+ void insert (iterator position, size_type n, const T& x);
+
+ /**
+ * Insert a slice into the current container at a given position
+ * @param[in] position iterator, position to insert slice
+ * @param[in] first iterator to first element of slice insert
+ * @param[in] last iterator to last element + 1 of slice to insert
+ * @pre begin() <= postion <= end(), first < last.
+ * @post Elements inserted at postition. Storage adjusted as needed.
+ * All previously obtained iterators are invalid.
+ * @note element pointed to by last is not inserted.
+ */
+ template <class InputIterator>
+ void insert (iterator position, InputIterator first,
+ InputIterator last);
+
+
+ /**
+ * Remove an element from the container
+ * @param[in] position iterator, position of element to remove
+ * @return new location of the element that followed the last
+ * element erased, or end() if the operation erased
+ * the last element in the sequence.
+ * @pre begin() <= position < end()
+ * @post All previously obtained iterators are invalid.
+ */
+ __attribute__ ((always_inline))
+ iterator erase(iterator position)
+ {
+ return erase(position,position+1);
+ }
+
+ /**
+ * Remove a slice of elements from the container
+ * @param[in] first iterator, postion of the first element to remove
+ * @param[in] last iterator, postion of the last element + 1 to remove
+ * @return new location of the element that followed the last
+ * element erased, or end() if the operation erased
+ * the last element in the sequence.
+ * @pre begin() <= first,last <= end(), first <= last.
+ * @post All previously obtained iterators are invalid.
+ * @note The element pointed to be last is not deleted.
+ */
+ iterator erase(iterator first, iterator last)
+ {
+ assert(last >= first);
+ assert(first >= iv_start);
+ assert(first <= iv_finish);
+ assert(last >= iv_start);
+ assert(last <= iv_finish);
+
+ last = copy(last,iv_finish,first);
+ while(last != iv_finish)
+ {
+ --iv_finish;
+ iv_finish->~T();
+ }
+ return first;
+ }
+
+
+ /**
+ * Swap this vector with another
+ * @param reference to another vector of this type
+ */
+ void swap(vector<T>& x)
+ {
+ std::swap(iv_start,x.iv_start);
+ std::swap(iv_finish,x.iv_finish);
+ std::swap(iv_end_of_storage,x.iv_end_of_storage);
+ }
+
+ /**
+ * Clear the vector
+ * @pre none.
+ * @post size() = 0, All previously obtained iterators are invalid
+ * @note capacity unchanged
+ */
+ void clear ()
+ {
+ while(iv_finish != iv_start)
+ {
+ --iv_finish;
+ (iv_finish)->~T();
+ }
+ }
+
+ private:
+
+ /**
+ * Copy constructs elements into raw storage
+ * @param[in] first iterator of first element to copy
+ * @pararm[in] last iterator of last element + 1 to copy
+ * @param[in] destination iterator of destination
+ * @post elements moved
+ */
+ template <class InputIterator, class OutputIterator>
+ OutputIterator
+ ctor_copy(InputIterator first,
+ InputIterator last,
+ OutputIterator destination)
+ {
+ while(first != last)
+ {
+ new (destination) T(*first);
+ ++destination;
+ ++first;
+ }
+ return(destination);
+ }
+
+ /**
+ * Copy constructs elements into raw storage
+ * @param[in] first iterator of first element to copy
+ * @param[in] last iterator of last element + 1 to copy
+ * @param[in] destination iterator to end of destination + 1
+ * @post elements moved
+ */
+ template <class BidirectionalIterator1, class BidirectionalIterator2>
+ BidirectionalIterator2
+ ctor_copy_backward ( BidirectionalIterator1 first,
+ BidirectionalIterator1 last,
+ BidirectionalIterator2 destination)
+ {
+ while(last != first)
+ {
+ --destination;
+ --last;
+ new(destination) T(*last);
+ }
+ return destination;
+ }
+
+ /**
+ * fill by copy construct ino raw storage
+ * @param[in] first itertor fo first element
+ * @param[in] last iterator to last element + 1
+ * @param[in] value to use to fill
+ */
+ template < class ForwardIterator, class Tp >
+ void
+ ctor_fill (ForwardIterator first, ForwardIterator last, const Tp& value )
+ {
+ while (first != last)
+ {
+ new (first) T(value);
+ ++first;
+ }
+ }
+
+ /**
+ * fill by copy construct into raw storage
+ * @param[in] first iterator first location to fill
+ * @param[in] n number of elements to fill
+ * @param[in] value to use to fill
+ */
+ template < class OutputIterator, class Size, class Tp >
+ void
+ ctor_fill_n( OutputIterator first, Size n, const Tp& value )
+ {
+ for(; n>0; --n)
+ {
+ new (first) T(value);
+ ++first;
+ }
+ }
+
+
+ /**
+ * Free all the storage allocated to this vector
+ * @param[in] i_start iterator to start of storage block
+ */
+ __attribute__ ((always_inline))
+ void free_storage(iterator i_start)
+ {
+ delete [] (uint8_t *)i_start;
+ }
+
+ /**
+ * Allocate storage for this vector
+ * @param[in] n, number of elements required
+ */
+ __attribute__ ((always_inline))
+ iterator allocate_storage(size_type n)
+ {
+ return (iterator) new uint8_t[n * sizeof(T)];
+ }
+
+ /**
+ * debug dump
+ */
+ //void dump(const char * msg = "")
+ //{
+ // puts(msg);
+ // printf("vector_dump::start 0x%016lx finish 0x%016lx eos 0x%016lx\n",
+ // (uint64_t)iv_start, (uint64_t)iv_finish, (uint64_t)iv_end_of_storage);
+ //}
+ };
+
+}; // end namespace std
+
+// ------------------------------------------------------------------------------------------------
+
+template <class T>
+void std::vector<T>::reserve(size_type n)
+{
+ size_type c = capacity();
+ if(n > c)
+ {
+ // if requested new capacity < 10% of current capacity then increase by 10%
+ size_type dif = n - c;
+ size_type inc = 1 + (c/size_type(10));
+ if(dif < inc)
+ {
+ n += inc;
+ }
+
+ iterator newStart = allocate_storage(n);
+ if(NULL == iv_start)
+ {
+ iv_finish = newStart;
+ }
+ else
+ {
+ iterator newFinish = ctor_copy(iv_start, iv_finish, newStart);
+ clear();
+ iv_finish = newFinish;
+ free_storage(iv_start);
+ }
+ iv_end_of_storage = newStart + n;
+ iv_start = newStart;
+ }
+}
+
+
+// ------------------------------------------------------------------------------------------------
+
+template <class T>
+void std::vector<T>::insert (iterator position, size_type n, const T& x)
+{
+ //assert (position >= iv_start);
+ //assert (position <= iv_finish);
+ size_type new_size = size() + n;
+ if(position == end())
+ {
+ reserve(new_size);
+ while(n--) new (iv_finish++) T(x);
+ }
+ else if(new_size > capacity())
+ {
+ vector<T> new_vec;
+ new_vec.reserve(new_size);
+ for(const_iterator i = begin(); i != end(); ++i)
+ {
+ if(i == position)
+ {
+ while(n--) new_vec.push_back(x);
+ }
+ new_vec.push_back(*i);
+ }
+ swap(new_vec); // swap this with new_vec
+ }
+ else // already have enough space
+ {
+ size_type m = iv_finish - position; // # of existing elements to move
+ pointer new_finish = iv_finish + n;
+ if(m < n)
+ {
+ ctor_copy_backward(position,iv_finish,new_finish);
+ while(n--)
+ {
+ if(position < iv_finish) *position = x;
+ else new (position) T(x);
+ ++position;
+ }
+ }
+ else // n <= m
+ {
+ ctor_copy_backward(iv_finish-n,iv_finish,new_finish); // raw storage copy
+ copy_backward(position, iv_finish-n, iv_finish); // operator= copy
+ fill_n(position,n,x);
+ }
+ iv_finish = new_finish;
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+
+template <class T>
+template <class InputIterator>
+void std::vector<T>::insert (iterator position,
+ InputIterator first,
+ InputIterator last)
+// Should only move storage if there is not room
+// InputIterators are not random access (eg. can't do diff = last - first)
+{
+ size_type n = 0;
+ for(InputIterator i = first; i != last; ++i) ++n;
+ size_type new_size = size() + n;
+
+ if(position == end())
+ {
+ reserve(new_size);
+ iv_finish = ctor_copy(first,last,iv_finish);
+ }
+ else if(new_size > capacity()) // make a new vector
+ {
+ vector<T> new_vec;
+ new_vec.reserve(new_size);
+ for(const_iterator i = begin(); i != end(); ++i)
+ {
+ if(i == position)
+ {
+ while(n--) new_vec.push_back(*first++);
+ }
+ new_vec.push_back(*i);
+ }
+ swap(new_vec);
+ }
+ else // already have enough space
+ {
+ size_type m = iv_finish - position; // # of exising elements to adjust
+ if(m < n)
+ {
+ ctor_copy_backward(position,iv_finish,iv_finish+n); // cp all existing elements to raw storage
+ while(first != last)
+ {
+ if(position < iv_finish) *position = *first; // cp new elements to existing element locations
+ else new (position) T(*first); // cp remaining new elements to raw storage
+ ++position;
+ ++first;
+ }
+ }
+ else // n <= m
+ {
+ ctor_copy_backward(iv_finish-n, iv_finish, iv_finish+n); // cp existing elements to raw storage
+ copy_backward(position, iv_finish-n, iv_finish); // cp rest of existing elements to existing locations
+ copy(first,last,position); // cp in new elements to existing locations
+ }
+ iv_finish += n;
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+
+template <class T>
+void std::vector<T>::resize(size_type n, T x)
+{
+ size_type sz = size();
+ if(n < sz)
+ {
+ erase(iv_start + n,iv_finish);
+ }
+ else if(n > sz)
+ {
+ insert(iv_finish,n-sz,x);
+ }
+ // else n == size() do nothing
+}
+
+#endif
+/* vim: set filetype=cpp : */
diff --git a/src/hwpf/src/Makefile b/src/hwpf/src/Makefile
new file mode 100644
index 00000000..950c0ccc
--- /dev/null
+++ b/src/hwpf/src/Makefile
@@ -0,0 +1,51 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/hwpf/src/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+# This Makefile is designed to be invoked with the -I argument
+
+export SUB_OBJDIR = /fapi2
+
+include img_defs.mk
+include fapi2sbefiles.mk
+
+
+OBJS := $(addprefix $(OBJDIR)/, $(FAPI2LIB_OBJECTS))
+
+libfapi2.a: fapi2 hwpf plat
+ $(AR) crs $(OBJDIR)/libfapi2.a $(OBJDIR)/*.o
+
+.PHONY: clean fapi2 hwpf plat
+fapi2: $(OBJS)
+
+plat:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(PLAT_FAPI2_DIR)/src/plat
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
+
diff --git a/src/hwpf/src/fapi2sbefiles.mk b/src/hwpf/src/fapi2sbefiles.mk
new file mode 100644
index 00000000..b9c42fad
--- /dev/null
+++ b/src/hwpf/src/fapi2sbefiles.mk
@@ -0,0 +1,49 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/hwpf/src/fapi2sbefiles.mk $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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 fapi2ppefiles.mk
+#
+# @brief mk for including fapi2 object files
+#
+# @page ChangeLogs Change Logs
+# @section fapi2ppefiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+FAPI2-C-SOURCES += ffdc.C
+FAPI2-C-SOURCES += plat_ring_traverse.C
+FAPI2-S-SOURCES =
+
+
+FAPI2LIB_OBJECTS += $(FAPI2-C-SOURCES:.C=.o) $(FAPI2-S-SOURCES:.S=.o)
+
diff --git a/src/hwpf/src/ffdc.C b/src/hwpf/src/ffdc.C
new file mode 100644
index 00000000..806082d5
--- /dev/null
+++ b/src/hwpf/src/ffdc.C
@@ -0,0 +1,41 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/src/ffdc.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 ffdc.C
+ * @brief Implements the ffdc for sbe
+ */
+
+#include <ffdc.H>
+#include <error_info.H>
+
+
+namespace fapi2
+{
+
+#ifdef MINIMUM_FFDC
+ // buffer used to hold ffdc data
+ SbeFfdcData_t g_FfdcData;
+#endif
+
+};
diff --git a/src/hwpf/src/plat/Makefile b/src/hwpf/src/plat/Makefile
new file mode 100644
index 00000000..a6588194
--- /dev/null
+++ b/src/hwpf/src/plat/Makefile
@@ -0,0 +1,41 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/hwpf/src/plat/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+# This Makefile is designed to be invoked with the -I argument
+include img_defs.mk
+include fapi2sbeplatfiles.mk
+
+OBJS := $(addprefix $(OBJDIR)/, $(FAPI2PLATLIB_OBJECTS))
+
+all: $(OBJS)
+
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
+
diff --git a/src/hwpf/src/plat/fapi2sbeplatfiles.mk b/src/hwpf/src/plat/fapi2sbeplatfiles.mk
new file mode 100644
index 00000000..e555635b
--- /dev/null
+++ b/src/hwpf/src/plat/fapi2sbeplatfiles.mk
@@ -0,0 +1,52 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/hwpf/src/plat/fapi2sbeplatfiles.mk $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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 fapi2ppefiles.mk
+#
+# @brief mk for including fapi2 object files
+#
+# @page ChangeLogs Change Logs
+# @section fapi2ppefiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+FAPI2PLAT-CPP-SOURCES += plat_hw_access.C
+FAPI2PLAT-CPP-SOURCES += plat_utils.C
+FAPI2PLAT-CPP-SOURCES += target.C
+
+FAPI2PLAT-C-SOURCES =
+FAPI2PLAT-S-SOURCES =
+
+
+FAPI2PLATLIB_OBJECTS += $(FAPI2PLAT-CPP-SOURCES:.C=.o) $(FAPI2PLAT-C-SOURCES:.c=.o) $(FAPI2PLAT-S-SOURCES:.S=.o)
+
diff --git a/src/hwpf/src/plat/plat_hw_access.C b/src/hwpf/src/plat/plat_hw_access.C
new file mode 100644
index 00000000..5c2af1a8
--- /dev/null
+++ b/src/hwpf/src/plat/plat_hw_access.C
@@ -0,0 +1,72 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/src/plat/plat_hw_access.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 <fapi2.H>
+#include "plat_hw_access.H"
+
+namespace fapi2
+{
+
+ ReturnCode getRing_setup(const uint32_t i_ringAddress,
+ const RingMode i_ringMode)
+ {
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ReturnCode getRing_granule_data(const uint32_t i_ringAddress,
+ uint64_t *o_data,
+ const uint32_t i_bitShiftValue)
+ {
+ return FAPI2_RC_SUCCESS;
+ }
+
+
+ ReturnCode getRing_verifyAndcleanup(const uint32_t i_ringAddress,
+ const RingMode i_ringMode)
+ {
+ return FAPI2_RC_SUCCESS;
+ }
+
+ uint32_t getscom_abs_wrap(const uint32_t i_addr, uint64_t *o_data)
+ {
+ uint32_t l_rc = 0;
+ FAPI_INF("getScom: address: 0x%08X", i_addr);
+ l_rc = getscom_abs(i_addr, o_data);
+ FAPI_INF("getScom: returned rc: 0x%08X, data HI: 0x%08X, "
+ "data LO: 0x%08X", l_rc, (*o_data >> 32),
+ static_cast<uint32_t>(*o_data & 0xFFFFFFFF));
+ return l_rc;
+ }
+
+ uint32_t putscom_abs_wrap(const uint32_t i_addr, uint64_t i_data)
+ {
+ uint32_t l_rc = 0;
+ FAPI_INF("putScom: address: 0x%08X, data HI: 0x%08X, data LO: 0x%08X",
+ i_addr, (i_data >> 32),
+ static_cast<uint32_t>(i_data & 0xFFFFFFFF));
+ l_rc = putscom_abs(i_addr, i_data);
+ FAPI_INF("putScom: returned rc: 0x%08X", l_rc);
+ return l_rc;
+ }
+};
diff --git a/src/hwpf/src/plat/plat_utils.C b/src/hwpf/src/plat/plat_utils.C
new file mode 100644
index 00000000..44cce502
--- /dev/null
+++ b/src/hwpf/src/plat/plat_utils.C
@@ -0,0 +1,304 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/src/plat/plat_utils.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 plat_utils.C
+ * @brief Implements fapi2 common utilities
+ */
+
+#include <stdint.h>
+#include <fapi2AttributeService.H>
+#include <fapi2AttributeIds.H>
+#include <return_code.H>
+#include <plat_trace.H>
+#include <target.H>
+
+#ifndef __PPE__
+#include <error_info.H>
+#endif
+
+namespace fapi2
+{
+
+#ifndef __PPE__
+ ///
+ /// @brief Log an error.
+ ///
+ void logError(
+ fapi2::ReturnCode & io_rc,
+ fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE,
+ bool i_unitTestError = false )
+ {
+ // To keep the compiler from complaing about i_sevbeing unused.
+ static_cast<void>(i_sev);
+ static_cast<void>(i_unitTestError);
+
+ FAPI_DBG("logging 0x%lx.", uint64_t(io_rc));
+
+ // Iterate over the vectors and output what is in them.
+ const ErrorInfo* ei = io_rc.getErrorInfo();
+
+ FAPI_DBG("ffdcs: %lu", ei->iv_ffdcs.size());
+ for( auto i = ei->iv_ffdcs.begin(); i != ei->iv_ffdcs.end(); ++i )
+ {
+ uint32_t sz;
+ (*i)->getData(sz);
+ FAPI_DBG("\tid: 0x%x size %d", (*i)->getFfdcId(), sz);
+ }
+
+ FAPI_DBG("hwCallouts: %lu", ei->iv_hwCallouts.size());
+ for( auto i = ei->iv_hwCallouts.begin(); i != ei->iv_hwCallouts.end();
+ ++i )
+ {
+ FAPI_DBG("\thw: %d pri %d target: 0x%lx",
+ (*i)->iv_hw, (*i)->iv_calloutPriority,
+ (*i)->iv_refTarget.get());
+ }
+
+ FAPI_DBG("procedureCallouts: %lu", ei->iv_procedureCallouts.size());
+ for( auto i = ei->iv_procedureCallouts.begin();
+ i != ei->iv_procedureCallouts.end(); ++i )
+ {
+ FAPI_DBG("\tprocedure: %d pri %d",
+ (*i)->iv_procedure, (*i)->iv_calloutPriority);
+ }
+
+e FAPI_DBG("busCallouts: %lu", ei->iv_busCallouts.size());
+ for( auto i = ei->iv_busCallouts.begin(); i != ei->iv_busCallouts.end();
+ ++i )
+ {
+ FAPI_DBG("\tbus: t1: 0x%lx t2: 0x%lx pri: %d",
+ (*i)->iv_target1.get(), (*i)->iv_target2.get(),
+ (*i)->iv_calloutPriority);
+ }
+
+
+ FAPI_DBG("cdgs: %lu", ei->iv_CDGs.size());
+ for( auto i = ei->iv_CDGs.begin(); i != ei->iv_CDGs.end(); ++i )
+ {
+ FAPI_DBG("\ttarget: 0x%lx co: %d dc: %d gard: %d pri: %d",
+ (*i)->iv_target.get(),
+ (*i)->iv_callout,
+ (*i)->iv_deconfigure,
+ (*i)->iv_gard,
+ (*i)->iv_calloutPriority);
+
+ }
+
+ FAPI_DBG("childrenCDGs: %lu", ei->iv_childrenCDGs.size());
+ for( auto i = ei->iv_childrenCDGs.begin();
+ i != ei->iv_childrenCDGs.end(); ++i )
+ {
+ FAPI_DBG("\tchildren: parent 0x%lx co: %d dc: %d gard: %d pri: %d",
+ (*i)->iv_parent.get(),
+ (*i)->iv_callout,
+ (*i)->iv_deconfigure,
+ (*i)->iv_gard,
+ (*i)->iv_calloutPriority);
+ }
+
+ FAPI_DBG("traces: %lu", ei->iv_traces.size());
+ for( auto i = ei->iv_traces.begin(); i != ei->iv_traces.end(); ++i )
+ {
+ FAPI_DBG("\ttraces: 0x%x", (*i)->iv_eiTraceId);
+ }
+
+ // Release the ffdc information now that we're done with it.
+ io_rc.forgetData();
+
+ }
+#endif
+
+ ///
+ /// @brief Delay this thread.
+ ///
+ ReturnCode delay(uint64_t i_nanoSeconds, uint64_t i_simCycles, bool i_fixed /* = false*/)
+ {
+ // void statements to keep the compiler from complaining
+ // about unused variables.
+ static_cast<void>(i_nanoSeconds);
+ static_cast<void>(i_simCycles);
+
+
+#ifndef __FAPI_DELAY_SIM__
+
+#define PK_NANOSECONDS_SBE(n) ((PkInterval)((PK_BASE_FREQ_HZ * (PkInterval)(n)) / (1024*1024*1024)))
+
+ PkTimebase target_time;
+ PkTimebase current_time;
+ PkMachineContext ctx;
+
+
+ // Only execute if nanoSeconds is non-zero (eg a real wait)
+ if (i_nanoSeconds)
+ {
+ // @todo For SBE applications, the time accuracy can be traded off
+ // for space with the PK_NANOSECONDS_SBE implemenation as the compiler
+ // use shift operations for the unit normalizing division.
+
+ // The critical section enter/exit set is done to ensure the timebase
+ // operations are non-interrupible.
+
+ pk_critical_section_enter(&ctx);
+ //
+ // The "accurate" version is the next line.
+ // target_time = pk_timebase32_get() + PK_INTERVAL_SCALE(PK_NANOSECONDS(i_nanoSeconds));
+
+ target_time = pk_timebase32_get() + PK_INTERVAL_SCALE(PK_NANOSECONDS_SBE(i_nanoSeconds));
+
+ do
+ {
+ current_time = pk_timebase32_get();
+ } while (target_time > current_time);
+
+ pk_critical_section_exit(&ctx);
+
+
+ }
+#else
+
+ // Execute a tight loop that simply counts down the i_simCycles
+ // value.
+
+ // @todo This can might be optimized with a fused compare branch loop
+ // Note, though, that subwibnz instruction is optimized for word
+ // operations. i_simCycles are uint64_t values so the upper
+ // word values needs to be accounted for.
+ //
+ // Need to determine if this optimization is worth the effort.
+
+#ifndef __FAPI_DELAY_PPE_SIM_CYCLES__
+#define __FAPI_DELAY_PPE_SIM_CYCLES__ 8
+#endif
+
+ static const uint8_t NUM_OVERHEAD_INSTRS = 15;
+ static const uint8_t NUM_LOOP_INSTRS = 4;
+ static const uint64_t MIN_DELAY_CYCLES =
+ ((NUM_OVERHEAD_INSTRS + NUM_LOOP_INSTRS) * __FAPI_DELAY_PPE_SIM_CYCLES__);
+
+ uint64_t l_adjusted_simcycles;
+
+ if (i_simCycles < MIN_DELAY_CYCLES)
+ l_adjusted_simcycles = MIN_DELAY_CYCLES;
+ else
+ l_adjusted_simcycles = i_simCycles;
+
+ uint64_t delay_loop_count =
+ ((l_adjusted_simcycles - (NUM_OVERHEAD_INSTRS * __FAPI_DELAY_PPE_SIM_CYCLES__)) /
+ (NUM_LOOP_INSTRS * __FAPI_DELAY_PPE_SIM_CYCLES__));
+
+
+ for (auto i = delay_loop_count; i > 0; --i) {}
+
+#endif
+
+ // replace with platform specific implementation
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Queries the ATTR_NAME and ATTR_EC attributes
+ ///
+ ReturnCode queryChipEcAndName(
+ const Target < fapi2::TARGET_TYPE_PROC_CHIP > & i_target,
+ fapi2::ATTR_NAME_Type& o_chipName, fapi2::ATTR_EC_Type& o_chipEc )
+ {
+
+ ReturnCode l_rc = FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_target, o_chipName);
+
+ if ( l_rc != FAPI2_RC_SUCCESS )
+ {
+ FAPI_ERR("queryChipEcFeature: error getting chip name");
+ }
+ else
+ {
+ l_rc = FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, i_target, o_chipEc);
+
+ if ( l_rc != FAPI2_RC_SUCCESS )
+ {
+ FAPI_ERR("queryChipEcFeature: error getting chip ec");
+ }
+ }
+
+ return l_rc;
+ }
+};
+
+#ifndef _BIG_ENDIAN
+
+/// Byte-reverse a 16-bit integer if on a little-endian machine
+
+uint16_t
+revle16(uint16_t i_x)
+{
+ uint16_t rx;
+ uint8_t *pix = (uint8_t*)(&i_x);
+ uint8_t *prx = (uint8_t*)(&rx);
+
+ prx[0] = pix[1];
+ prx[1] = pix[0];
+
+ return rx;
+}
+
+/// Byte-reverse a 32-bit integer if on a little-endian machine
+
+uint32_t
+revle32(uint32_t i_x)
+{
+ uint32_t rx;
+ 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];
+
+ return rx;
+}
+
+
+/// Byte-reverse a 64-bit integer if on a little-endian machine
+
+uint64_t
+revle64(const uint64_t i_x)
+{
+ uint64_t rx;
+ 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];
+
+ return rx;
+}
+#endif
+
diff --git a/src/hwpf/src/plat/target.C b/src/hwpf/src/plat/target.C
new file mode 100644
index 00000000..7d7e4e0e
--- /dev/null
+++ b/src/hwpf/src/plat/target.C
@@ -0,0 +1,609 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/src/plat/target.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 <fapi2.H>
+#include <assert.h>
+#include <fapi2_target.H>
+#include <plat_target_utils.H>
+
+// Global Vector containing ALL targets. This structure is referenced by
+// fapi2::getChildren to produce the resultant returned vector from that
+// call.
+std::vector<fapi2::plat_target_handle_t> G_vec_targets;
+
+// Global variable for fixed section in pibmem
+G_sbe_attrs_t G_sbe_attrs;
+
+fapi2attr::SystemAttributes_t* G_system_attributes_ptr;
+fapi2attr::ProcChipAttributes_t* G_proc_chip_attributes_ptr;
+fapi2attr::PervAttributes_t* G_perv_attributes_ptr;
+fapi2attr::CoreAttributes_t* G_core_attributes_ptr;
+fapi2attr::EQAttributes_t* G_eq_attributes_ptr;
+fapi2attr::EXAttributes_t* G_ex_attributes_ptr;
+
+namespace fapi2
+{
+ // Get the plat target handle by chiplet number - For PERV targets
+ template<>
+ plat_target_handle_t plat_getTargetHandleByChipletNumber<TARGET_TYPE_PERV>(
+ const uint8_t i_chipletNumber)
+ {
+ uint32_t l_idx = 0;
+
+ if((i_chipletNumber > 0) &&
+ (i_chipletNumber < (EQ_CHIPLET_OFFSET + EQ_TARGET_COUNT)))
+ {
+ l_idx = (i_chipletNumber - NEST_GROUP1_CHIPLET_OFFSET) +
+ NEST_GROUP1_TARGET_OFFSET;
+ }
+ else if((i_chipletNumber >= CORE_CHIPLET_OFFSET) &&
+ (i_chipletNumber < (CORE_CHIPLET_OFFSET + CORE_TARGET_COUNT)))
+ {
+ l_idx = (i_chipletNumber - CORE_CHIPLET_OFFSET) +
+ CORE_TARGET_OFFSET;
+ }
+ else
+ {
+ assert(false);
+ }
+ return G_vec_targets[l_idx];
+ }
+
+ // Get the plat target handle by chiplet number - For EQ targets
+ template<>
+ plat_target_handle_t plat_getTargetHandleByChipletNumber<TARGET_TYPE_EQ>(
+ const uint8_t i_chipletNumber)
+ {
+ assert(((i_chipletNumber >= EQ_CHIPLET_OFFSET) &&
+ (i_chipletNumber < (EQ_CHIPLET_OFFSET + EQ_TARGET_COUNT))))
+
+ uint32_t l_idx = (i_chipletNumber - EQ_CHIPLET_OFFSET) +
+ EQ_TARGET_OFFSET;
+ return G_vec_targets[l_idx];
+ }
+
+ // Get the plat target handle by chiplet number - For CORE targets
+ template<>
+ plat_target_handle_t plat_getTargetHandleByChipletNumber<TARGET_TYPE_CORE>(
+ const uint8_t i_chipletNumber)
+ {
+ assert(((i_chipletNumber >= CORE_CHIPLET_OFFSET) &&
+ (i_chipletNumber < (CORE_CHIPLET_OFFSET + CORE_TARGET_COUNT))));
+
+ uint32_t l_idx = (i_chipletNumber - CORE_CHIPLET_OFFSET) +
+ CORE_TARGET_OFFSET;
+
+ return G_vec_targets[l_idx];
+ }
+
+ // Get the plat target handle by chiplet number - For EX targets
+ template<>
+ plat_target_handle_t plat_getTargetHandleByChipletNumber<TARGET_TYPE_EX>(
+ const uint8_t i_chipletNumber)
+ {
+ assert(((i_chipletNumber >= CORE_CHIPLET_OFFSET) &&
+ (i_chipletNumber < (CORE_CHIPLET_OFFSET + CORE_TARGET_COUNT))));
+
+ uint32_t l_idx = ((i_chipletNumber - CORE_CHIPLET_OFFSET) / 2) +
+ EX_TARGET_OFFSET;
+
+ return G_vec_targets[l_idx];
+ }
+
+ // Get plat target handle by instance number - For EX targets
+ template <>
+ plat_target_handle_t plat_getTargetHandleByInstance<TARGET_TYPE_EX>(
+ const uint8_t i_targetNum)
+ {
+ assert(i_targetNum < EX_TARGET_COUNT);
+
+ return G_vec_targets[i_targetNum + EX_TARGET_OFFSET];
+ }
+
+
+ TargetType plat_target_handle_t::getFapiTargetType() const
+ {
+ TargetType l_targetType = TARGET_TYPE_NONE;
+ switch(fields.type)
+ {
+ case PPE_TARGET_TYPE_PROC_CHIP:
+ l_targetType = TARGET_TYPE_PROC_CHIP;
+ break;
+ case PPE_TARGET_TYPE_MCS:
+ l_targetType = TARGET_TYPE_MCS;
+ break;
+ case PPE_TARGET_TYPE_CORE | PPE_TARGET_TYPE_PERV:
+ l_targetType = TARGET_TYPE_CORE;
+ break;
+ case PPE_TARGET_TYPE_EQ | PPE_TARGET_TYPE_PERV:
+ l_targetType = TARGET_TYPE_EQ;
+ break;
+ case PPE_TARGET_TYPE_EX:
+ l_targetType = TARGET_TYPE_EX;
+ break;
+ case PPE_TARGET_TYPE_PERV:
+ l_targetType = TARGET_TYPE_PERV;
+ break;
+ case PPE_TARGET_TYPE_SYSTEM:
+ l_targetType = TARGET_TYPE_SYSTEM;
+ break;
+ case PPE_TARGET_TYPE_MCBIST | PPE_TARGET_TYPE_PERV:
+ l_targetType = TARGET_TYPE_MCBIST;
+ break;
+ case PPE_TARGET_TYPE_NONE:
+ case PPE_TARGET_TYPE_ALL:
+ default:
+ assert(false);
+ break;
+ }
+ return l_targetType;
+ }
+
+ void plat_target_handle_t::getChildren(const TargetType i_parentType,
+ const TargetType i_childType,
+ const plat_target_type_t i_platType,
+ const TargetState i_state,
+ std::vector<plat_target_handle>
+ &o_children) const
+ {
+ uint32_t l_childPerChiplet = 0;
+ uint32_t l_childTargetOffset = 0;
+ uint32_t l_loopCount = G_vec_targets.size();
+ TargetType l_targetType = i_parentType;
+
+ if((i_parentType & ~(TARGET_TYPE_PROC_CHIP)) != 0)
+ {
+ // For composite targets, if multicast, treat as PROC_CHIP, else
+ // treat as other target
+ if(this->fields.is_multicast)
+ {
+ l_targetType = TARGET_TYPE_PROC_CHIP;
+ }
+ else
+ {
+ l_targetType =
+ static_cast<TargetType>(l_targetType & ~(TARGET_TYPE_PROC_CHIP));
+ }
+ }
+
+ // EQ ==> EX
+ if((l_targetType == TARGET_TYPE_EQ) && (i_childType == TARGET_TYPE_EX))
+ {
+ l_childPerChiplet = EX_PER_QUAD;
+ l_childTargetOffset = EX_TARGET_OFFSET;
+ l_loopCount = l_childPerChiplet;
+ }
+
+ // EQ ==> EC
+ if((l_targetType == TARGET_TYPE_EQ) && (i_childType == TARGET_TYPE_CORE))
+ {
+ l_childPerChiplet = CORES_PER_QUAD;
+ l_childTargetOffset = CORE_TARGET_OFFSET;
+ l_loopCount = l_childPerChiplet;
+ }
+
+ // EX ==> EC
+ if((l_targetType == TARGET_TYPE_EX) && (i_childType == TARGET_TYPE_CORE))
+ {
+ l_childPerChiplet = CORES_PER_EX;
+ l_childTargetOffset = CORE_TARGET_OFFSET;
+ l_loopCount = l_childPerChiplet;
+ }
+ // else it is TARGET_TYPE_PROC_CHIP ==> anything, and we iterate over
+ // all the targets
+
+ for(uint32_t i = 0; i < l_loopCount; ++i)
+ {
+ plat_target_handle_t l_temp =
+ G_vec_targets.at((this->fields.type_target_num *
+ l_childPerChiplet) + l_childTargetOffset + i);
+ if ((l_temp.fields.type & i_platType) == i_platType)
+ {
+ switch (i_state)
+ {
+ case TARGET_STATE_PRESENT:
+ if (l_temp.fields.present)
+ {
+ o_children.push_back(l_temp);
+ }
+ break;
+ case TARGET_STATE_FUNCTIONAL:
+ if (l_temp.fields.functional)
+ {
+ o_children.push_back(l_temp);
+ }
+ break;
+ default:
+ assert(false);
+ }
+ }
+ }
+ }
+
+ void plat_target_handle_t::getChildren(const TargetFilter i_filter,
+ const TargetState i_state,
+ std::vector<plat_target_handle_t>
+ &o_children) const
+ {
+ static const uint64_t mask = 1;
+
+ // Walk the bits in the input target filter. For every bit, at
+ // position x, that is set, x can be used as an index into our global
+ // target vector (indexed by chiplet number)
+ for (uint32_t l_idx = 0;
+ l_idx < sizeof(TargetFilter) * 8;
+ ++l_idx)
+ {
+ if (i_filter & (mask << (((sizeof(TargetFilter)*8)-1) - l_idx)))
+ {
+ plat_target_handle_t l_targetHandle = G_vec_targets.at(l_idx + NEST_GROUP1_CHIPLET_OFFSET);
+
+ if(l_targetHandle.fields.type & PPE_TARGET_TYPE_PERV) // Can be an assertion?
+ {
+ switch (i_state)
+ {
+ case TARGET_STATE_PRESENT:
+ if(l_targetHandle.fields.present)
+ {
+ o_children.push_back(l_targetHandle);
+ }
+ break;
+ case TARGET_STATE_FUNCTIONAL:
+ if(l_targetHandle.fields.functional)
+ {
+ o_children.push_back(l_targetHandle);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ #ifndef __noRC__
+ ReturnCode current_err;
+ #endif
+
+ fapi2::ReturnCode plat_PervPGTargets(const fapi2::Target<fapi2::TARGET_TYPE_PERV> & i_target,
+ bool & o_present)
+ {
+ o_present = false;
+ uint32_t attr_value = 0;
+ FAPI_ATTR_GET(fapi2::ATTR_PG,
+ i_target,
+ attr_value);
+ FAPI_DBG("Target: 0x%08X, ATTR_PG value = %x", static_cast<uint32_t>(i_target.get().value), attr_value);
+ if (0 == (attr_value & 0x1000))
+ {
+ o_present = true;
+ }
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Function to determine if pervsaive target within a chip is
+ /// present and, thus, considered functional per PG attributes
+ fapi2::ReturnCode
+ plat_TargetPresent( fapi2::Target<fapi2::TARGET_TYPE_PERV> & i_chiplet_target,
+ bool & b_present)
+ {
+
+ // Find the PERV target number in the partial good initialization
+ // array
+ FAPI_TRY(plat_PervPGTargets(i_chiplet_target, b_present));
+
+ if (b_present)
+ {
+ i_chiplet_target.setPresent();
+ i_chiplet_target.setFunctional(true);
+ }
+ else
+ {
+ FAPI_DBG("Perv target NOT present (nor functional): chiplet_number = %d",
+ i_chiplet_target.getChipletNumber());
+ }
+
+ FAPI_DBG("Target present = %u, Target functional = %u",
+ i_chiplet_target.getPresent(),
+ i_chiplet_target.getFunctional());
+
+fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+
+ /// @brief Function to initialize the G_targets vector based on partial good
+ /// attributes /// this will move to plat_target.H formally
+ fapi2::ReturnCode plat_TargetsInit()
+ {
+ bool b_present = false;
+
+ // Copy fixed section from SEEPROM to PIBMEM
+ G_sbe_attrs.G_system_attrs = G_system_attributes;
+ G_sbe_attrs.G_proc_chip_attrs = G_proc_chip_attributes;
+ G_sbe_attrs.G_perv_attrs = G_perv_attributes;
+ G_sbe_attrs.G_core_attrs = G_core_attributes;
+ G_sbe_attrs.G_eq_attrs = G_eq_attributes;
+ G_sbe_attrs.G_ex_attrs = G_ex_attributes;
+
+ // Initialise global attribute pointers
+ G_system_attributes_ptr = &(G_sbe_attrs.G_system_attrs);
+ G_proc_chip_attributes_ptr = &(G_sbe_attrs.G_proc_chip_attrs);
+ G_perv_attributes_ptr = &(G_sbe_attrs.G_perv_attrs);
+ G_core_attributes_ptr = &(G_sbe_attrs.G_core_attrs);
+ G_eq_attributes_ptr = &(G_sbe_attrs.G_eq_attrs);
+ G_ex_attributes_ptr = &(G_sbe_attrs.G_ex_attrs);
+
+
+ std::vector<fapi2::plat_target_handle_t>::iterator tgt_iter;
+ uint32_t l_beginning_offset;
+
+ FAPI_DBG("Platform target initialization. Target Count = %u", TARGET_COUNT);
+ /*
+ * Initialize all entries to NULL
+ */
+ for (uint32_t i = 0; i < TARGET_COUNT; ++i)
+ {
+ G_vec_targets.push_back((fapi2::plat_target_handle_t)0x0);
+ }
+
+ /*
+ * Chip Target is the first one
+ */
+ l_beginning_offset = CHIP_TARGET_OFFSET;
+
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> chip_target((createPlatTargetHandle<fapi2::TARGET_TYPE_PROC_CHIP>(0)));
+ G_vec_targets.at(l_beginning_offset) = revle32((fapi2::plat_target_handle_t)(chip_target.get()));
+
+ /*
+ * Nest Targets - group 1
+ */
+ l_beginning_offset = NEST_GROUP1_TARGET_OFFSET;
+ for (uint32_t i = 0; i < NEST_GROUP1_TARGET_COUNT; ++i)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_PERV> target_name((createPlatTargetHandle<fapi2::TARGET_TYPE_PERV>(i)));
+
+ // Determine if the chiplet is present and, thus, functional
+ // via partial good attributes
+ FAPI_TRY(plat_TargetPresent(target_name, b_present));
+
+ G_vec_targets.at(l_beginning_offset+i) = revle32((fapi2::plat_target_handle_t)(target_name.get()));
+ }
+
+ /*
+ * Memory Controller Synchronous (MCBIST) Targets
+ */
+
+ l_beginning_offset = MCBIST_TARGET_OFFSET;
+ for (uint32_t i = 0; i < MCBIST_TARGET_COUNT; ++i)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_MCBIST> target_name((createPlatTargetHandle<fapi2::TARGET_TYPE_MCBIST>(i)));
+ fapi2::Target<fapi2::TARGET_TYPE_PERV> l_perv = target_name.getParent<fapi2::TARGET_TYPE_PERV>();
+
+ // Determine if the chiplet is present and, thus, functional
+ // via partial good attributes
+ FAPI_TRY(plat_TargetPresent(l_perv, b_present));
+
+ G_vec_targets.at(l_beginning_offset+i) = revle32((fapi2::plat_target_handle_t)(l_perv.get()));
+
+ }
+
+ /*
+ * Nest Targets - group 2
+ */
+ l_beginning_offset = NEST_GROUP2_TARGET_OFFSET;
+ for (uint32_t i = NEST_GROUP2_TARGET_OFFSET;
+ i < (NEST_GROUP2_TARGET_OFFSET + NEST_GROUP2_TARGET_COUNT); ++i)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_PERV> target_name((createPlatTargetHandle<fapi2::TARGET_TYPE_PERV>(i - 1)));
+
+ // Determine if the chiplet is present and, thus, functional
+ // via partial good attributes
+ FAPI_TRY(plat_TargetPresent(target_name, b_present));
+
+ G_vec_targets.at(i) = revle32((fapi2::plat_target_handle_t)(target_name.get()));
+ }
+
+ /*
+ * Cache (EQ) Targets
+ */
+ l_beginning_offset = EQ_TARGET_OFFSET;
+ for (uint32_t i = 0; i < EQ_TARGET_COUNT; ++i)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_EQ> target_name((createPlatTargetHandle<fapi2::TARGET_TYPE_EQ>(i)));
+ fapi2::Target<fapi2::TARGET_TYPE_PERV> l_perv = target_name.getParent<fapi2::TARGET_TYPE_PERV>();
+
+ // Determine if the chiplet is present and, thus, functional
+ // via partial good attributes
+ FAPI_TRY(plat_TargetPresent(l_perv, b_present));
+
+ G_vec_targets.at(l_beginning_offset+i) = revle32((fapi2::plat_target_handle_t)(l_perv.get()));
+ }
+
+ /*
+ * Core (EC) Targets
+ */
+
+ l_beginning_offset = CORE_TARGET_OFFSET;
+ for (uint32_t i = 0; i < CORE_TARGET_COUNT; ++i)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_CORE> target_name((createPlatTargetHandle<fapi2::TARGET_TYPE_CORE>(i)));
+ fapi2::Target<fapi2::TARGET_TYPE_PERV> l_perv = target_name.getParent<fapi2::TARGET_TYPE_PERV>();
+
+ // Determine if the chiplet is present and, thus, functional
+ // via partial good attributes
+ FAPI_TRY(plat_TargetPresent(l_perv, b_present));
+
+ G_vec_targets.at(l_beginning_offset+i) = revle32((fapi2::plat_target_handle_t)(l_perv.get()));
+ }
+
+ /*
+ * EX Targets
+ */
+
+ l_beginning_offset = EX_TARGET_OFFSET;
+ for (uint32_t i = 0; i < EX_TARGET_COUNT; ++i)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_EX> target_name((createPlatTargetHandle<fapi2::TARGET_TYPE_EX>(i)));
+
+ fapi2::Target<fapi2::TARGET_TYPE_EQ> l_parent = target_name.getParent<fapi2::TARGET_TYPE_EQ>();
+
+ // Get the parent EQ's ATTR_PG
+ uint32_t l_eqAttrPg = 0;
+ FAPI_ATTR_GET(fapi2::ATTR_PG, l_parent.getParent<TARGET_TYPE_PERV>(), l_eqAttrPg);
+
+ // Check if this EX's L2 and L3 regions are marked "good"
+ if(0 == (i % EX_PER_QUAD))
+ {
+ // Bits 6 and 8 need to be 0
+ l_eqAttrPg &= 0x0280;
+ }
+ else
+ {
+ // Bits 7 and 9 need to be 0
+ l_eqAttrPg &= 0x0140;
+ }
+
+ if(0 == l_eqAttrPg)
+ {
+ target_name.setPresent();
+ target_name.setFunctional(true);
+ }
+ G_vec_targets.at(l_beginning_offset+i) = revle32((fapi2::plat_target_handle_t)(target_name.get()));
+ }
+
+ /*
+ * MCS Targets
+ */
+
+ l_beginning_offset = MCS_TARGET_OFFSET;
+ for (uint32_t i = 0; i < MCS_TARGET_COUNT; ++i)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_MCS> target_name(createPlatTargetHandle<fapi2::TARGET_TYPE_MCS>(i));
+
+ fapi2::Target<fapi2::TARGET_TYPE_PERV>
+ l_nestTarget((plat_getTargetHandleByChipletNumber<TARGET_TYPE_PERV>(N3_CHIPLET - (MCS_PER_MCBIST * (i / MCS_PER_MCBIST)))));
+
+ uint32_t l_attrPg = 0;
+
+ FAPI_ATTR_GET(fapi2::ATTR_PG, l_nestTarget, l_attrPg);
+
+ if(0 == (i / MCS_PER_MCBIST))
+ {
+ // Bit 10 needs to be 0 for MCS 0, 1
+ l_attrPg &= 0x0020;
+ }
+ else
+ {
+ // Bit 9 needs to be 0 for MCS 2, 3
+ l_attrPg &= 0x0040;
+ }
+
+ if(0 == l_attrPg)
+ {
+ target_name.setPresent();
+ target_name.setFunctional(true);
+ }
+
+ G_vec_targets.at(l_beginning_offset+i) = revle32((fapi2::plat_target_handle_t)(target_name.get()));
+ }
+
+
+fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ /// @brief Function to initialize the G_targets vector based on partial good
+ /// attributes
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> plat_getChipTarget()
+ {
+
+ // Get the chip specific target
+ return ((fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>)G_vec_targets.at(0));
+ }
+
+ /// @brief Function to apply any gard records set (via
+ // ATTR_EQ_GARD/ATTR_EC_GARD) to mark corresponding targets non functional
+ ReturnCode plat_ApplyGards()
+ {
+ uint8_t l_eqGards = 0;
+ uint32_t l_ecGards = 0;
+ static const uint32_t l_mask = 0x80000000;
+ bool l_coreGroupNonFunctional = true;
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_chip = plat_getChipTarget();
+
+ // Read the EQ and EC gard attributes from the chip target
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EQ_GARD, l_chip, l_eqGards));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EC_GARD, l_chip, l_ecGards));
+
+ FAPI_DBG("ATTR_EQ_GARD:: 0x%08x", l_eqGards);
+ FAPI_DBG("ATTR_EC_GARD:: 0x%08x", l_ecGards);
+
+ // Iterate over the bits in EQ and EC gards, if set, mark the
+ // corresponding target non-functional
+ for(uint32_t l_idx = 0; l_idx < EQ_TARGET_COUNT; ++l_idx)
+ {
+ if((l_mask >> l_idx) & (((uint32_t)(l_eqGards)) << 24))
+ {
+ FAPI_DBG("Making %d'th EQ non-functional", l_idx);
+ // EQ chiplet l_idx is to be marked non-functional
+ fapi2::Target<fapi2::TARGET_TYPE_EQ> l_target = G_vec_targets.at(l_idx + EQ_TARGET_OFFSET);
+ l_target.setFunctional(false);
+ G_vec_targets.at(l_idx + EQ_TARGET_OFFSET) = l_target.get();
+ }
+ }
+
+ for(uint32_t l_idx = 0; l_idx < CORE_TARGET_COUNT; ++l_idx)
+ {
+ if((l_mask >> l_idx) & (l_ecGards))
+ {
+ FAPI_DBG("Making %d'th EC non-functional", l_idx);
+ // EC chiplet l_idx is to be marked non-functional
+ fapi2::Target<fapi2::TARGET_TYPE_CORE> l_target = G_vec_targets.at(l_idx + CORE_TARGET_OFFSET);
+ l_target.setFunctional(false);
+ G_vec_targets.at(l_idx + CORE_TARGET_OFFSET) = l_target.get();
+ }
+ else
+ {
+ l_coreGroupNonFunctional = false;
+ }
+ if(0 == ((l_idx + 1) % CORES_PER_EX))
+ {
+ if(true == l_coreGroupNonFunctional)
+ {
+ // All cores of this group are non-functional. Mark the EX
+ // non-functional too.
+ G_vec_targets.at((l_idx / CORES_PER_EX) + EX_TARGET_OFFSET).fields.functional = false;
+ }
+ // Reset ex non-functional flag for the next group
+ l_coreGroupNonFunctional = true;
+ }
+ }
+fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+} // fapi2
diff --git a/src/hwpf/src/plat_ring_traverse.C b/src/hwpf/src/plat_ring_traverse.C
new file mode 100644
index 00000000..b7bdb73c
--- /dev/null
+++ b/src/hwpf/src/plat_ring_traverse.C
@@ -0,0 +1,467 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/src/plat_ring_traverse.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 <plat_ring_traverse.H>
+
+#include <p9_putRingUtils.H> // for RS4 decompression utilities
+#include <sbeXipUtils.H>
+#include <fapi2AttributeService.H> // for FAPI_ATTR_GET
+#include <plat_target_utils.H> // for plat_getChipTarget
+
+// SEEPROM start address
+const uint32_t g_seepromAddr = SBE_SEEPROM_BASE_ORIGIN;
+using namespace RING_TYPES;
+const uint32_t CACHE_CONTAINED_MODE = 4;
+const uint32_t RISK_LEVEL_MODE = 1;
+#define CACHE_CONTAINED_MODE_OFFSET_IN_TOR 1
+#define RISK_LEVEL_MODE_OFFSET_IN_TOR 2
+#define OVERRIDE_VARIANT_SIZE 1
+
+
+///
+/// @brief This is a plat pecific (SBE Plat) function that locates the
+/// Ring Container in the image and calls the functin to decompress the
+/// RS4 string and apply it to the hardware.
+/// @param i_target The target of Ring apply.
+/// @param i_ringID The Ring ID that identifies the ring to be applied.
+/// @return FAPI2_RC_SUCCESS on success, else error code.
+///
+fapi2::ReturnCode findRS4InImageAndApply(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const RingID i_ringID,
+ const fapi2::RingMode i_ringMode)
+{
+ SBE_TRACE(">> findRS4InImageAndApply");
+
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ bool l_applyOverride = false;
+
+ do
+ {
+ //Apply scanring from .ring section
+
+ // Get the address of the Section-TOR
+ P9XipHeader *l_hdr = getXipHdr();
+ P9XipSection *l_section =
+ &(l_hdr->iv_section[P9_XIP_SECTION_SBE_RINGS]);
+
+ if (!(l_section->iv_offset))
+ {
+ SBE_TRACE("No ring data in .RING section");
+ break;
+ }
+
+ SectionTOR *l_sectionTOR = (SectionTOR *)(g_seepromAddr +
+ l_section->iv_offset);
+
+ l_rc = getRS4ImageFromTor(i_target,i_ringID,l_sectionTOR,
+ l_applyOverride,
+ l_section->iv_offset,
+ i_ringMode);
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+
+ //Apply scanring from .ring section
+ l_applyOverride = true;
+ l_section = NULL;
+ l_section =
+ &(l_hdr->iv_section[P9_XIP_SECTION_SBE_OVERRIDES]);
+
+ if (!(l_section->iv_offset))
+ {
+ SBE_TRACE("No ring data in .OVERRIDE section");
+ break;
+ }
+
+ l_sectionTOR = NULL;
+ l_sectionTOR = (SectionTOR *)(g_seepromAddr +
+ l_section->iv_offset);
+
+
+ l_rc = getRS4ImageFromTor(i_target,i_ringID,l_sectionTOR,
+ l_applyOverride,
+ l_section->iv_offset,
+ i_ringMode);
+ }while(0);
+
+ return l_rc;
+}
+
+fapi2::ReturnCode getRS4ImageFromTor(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const RingID i_ringID,
+ SectionTOR *i_sectionTOR,
+ bool i_applyOverride,
+ const uint32_t i_sectionOffset,
+ const fapi2::RingMode i_ringMode)
+{
+
+ // Determine the Offset ID and Ring Type for the given Ring ID.
+ uint32_t l_torOffset = 0;
+ RINGTYPE l_ringType = COMMON_RING;
+ CHIPLET_TYPE l_chipLetType;
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ do
+ {
+
+ getRingProperties(i_ringID, l_torOffset, l_ringType,l_chipLetType);
+ if(INVALID_RING == l_torOffset)
+ {
+ SBE_TRACE("Invalid Ring ID - %d", i_ringID);
+ l_rc = fapi2::FAPI2_RC_INVALID_PARAMETER;
+ break;
+ }
+
+ CHIPLET_DATA l_chipletData;
+ l_chipletData.iv_base_chiplet_number = 0;
+ l_chipletData.iv_num_common_rings = 0;
+ l_chipletData.iv_num_instance_rings = 0;
+
+ uint8_t l_chipletID = i_target.getChipletNumber();
+ uint16_t l_cpltRingVariantSz = 0;
+ uint32_t l_sectionOffset = 0;
+ switch(l_chipLetType)
+ {
+ case PERV_TYPE: // PERV
+ l_chipletData = PERV::g_pervData;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(PERV::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_PERV_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_PERV_INSTANCE_RING;
+ }
+
+ break;
+
+ case N0_TYPE: // Nest - N0
+ l_chipletData = N0::g_n0Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(N0::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_N0_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_N0_INSTANCE_RING;
+ }
+
+ break;
+
+ case N1_TYPE: // Nest - N1
+ l_chipletData = N1::g_n1Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(N1::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_N1_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_N1_INSTANCE_RING;
+ }
+
+ break;
+
+ case N2_TYPE: // Nest - N2
+ l_chipletData = N2::g_n2Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(N2::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_N2_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_N2_INSTANCE_RING;
+ }
+
+ break;
+
+ case N3_TYPE: // Nest - N3
+ l_chipletData = N3::g_n3Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(N3::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_N3_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_N3_INSTANCE_RING;
+ }
+
+ break;
+
+ case XB_TYPE: // XB - XBus2
+ l_chipletData = XB::g_xbData;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(XB::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_XB_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_XB_INSTANCE_RING;
+ }
+
+ break;
+
+ case MC_TYPE: // MC - MC23
+ l_chipletData = MC::g_mcData;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(MC::RingVariants)/
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_MC_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_MC_INSTANCE_RING;
+ }
+
+ break;
+
+ case OB0_TYPE: // OB0
+ l_chipletData = OB0::g_ob0Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(OB0::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_OB0_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_OB0_INSTANCE_RING;
+ }
+
+ break;
+ case OB1_TYPE: // OB1
+ l_chipletData = OB1::g_ob1Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(OB1::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_OB1_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_OB1_INSTANCE_RING;
+ }
+
+ break;
+ case OB2_TYPE: // OB2
+ l_chipletData = OB2::g_ob2Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(OB2::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_OB2_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_OB2_INSTANCE_RING;
+ }
+
+ break;
+ case OB3_TYPE: // OB3
+ l_chipletData = OB3::g_ob3Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(OB3::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_OB3_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_OB3_INSTANCE_RING;
+ }
+
+ break;
+
+
+ case PCI0_TYPE: // PCI - PCI0
+ l_chipletData = PCI0::g_pci0Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(PCI0::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_PCI0_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_PCI0_INSTANCE_RING;
+ }
+
+ break;
+
+ case PCI1_TYPE: // PCI - PCI1
+ l_chipletData = PCI1::g_pci1Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(PCI1::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_PCI1_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_PCI1_INSTANCE_RING;
+ }
+
+ break;
+
+ case PCI2_TYPE: // PCI - PCI2
+ l_chipletData = PCI2::g_pci2Data;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(PCI2::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_PCI2_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_PCI2_INSTANCE_RING;
+ }
+
+ break;
+
+ case EQ_TYPE: // EQ - Quad 0 - Quad 5
+ l_chipletData = EQ::g_eqData;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ ( sizeof(EQ::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_EQ_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_EQ_INSTANCE_RING;
+ }
+
+ break;
+
+ case EC_TYPE: // EC - Core 0 - 23
+ l_chipletData = EC::g_ecData;
+ l_cpltRingVariantSz = i_applyOverride ? OVERRIDE_VARIANT_SIZE :
+ (sizeof(EC::RingVariants) /
+ sizeof(l_cpltRingVariantSz));
+
+ l_sectionOffset = i_sectionTOR->TOC_EC_COMMON_RING;
+ if(INSTANCE_RING == l_ringType)
+ {
+ l_sectionOffset = i_sectionTOR->TOC_EC_INSTANCE_RING;
+ }
+
+ break;
+
+ default:
+ SBE_TRACE("Invalid Target/ChipletID - %d", l_chipletID);
+ l_rc = fapi2::FAPI2_RC_INVALID_PARAMETER;
+ break;
+
+ } // end of switch(l_chipletID)
+
+ if (l_rc)
+ {
+ break;
+ }
+
+ FAPI_INF("l_sectionOffset %08x",l_sectionOffset);
+ // Determine the section TOR address for the ring
+ uint32_t *l_sectionAddr = reinterpret_cast<uint32_t *>(g_seepromAddr +
+ i_sectionOffset + l_sectionOffset);
+
+ SBE_TRACE ("l_sectionAddr %08X",l_sectionAddr);
+
+
+ if(INSTANCE_RING == l_ringType)
+ {
+ if ( l_chipletID > l_chipletData.iv_base_chiplet_number)
+ {
+ uint8_t l_chipletOffset =
+ (l_chipletID - l_chipletData.iv_base_chiplet_number);
+ l_sectionAddr += (l_chipletOffset *
+ (l_chipletData.iv_num_instance_rings ));
+ }
+ }
+
+ // The ring variants in section TOR are expected to be in the sequence -
+ // 1. Base
+ // 2. Cache-Contained
+ // 3. Risk Level
+
+ SBE_TRACE ("l_sectionAddr %08X",l_sectionAddr);
+
+ // TOR records of Ring TOR are 2 bytes in size.
+ uint16_t *l_ringTorAddr = reinterpret_cast<uint16_t *>(l_sectionAddr) +
+ (l_torOffset * l_cpltRingVariantSz);
+ SBE_TRACE ("ring tor address %04X\n",l_ringTorAddr);
+
+ // If there are non-base variants of the ring, we'll have to check
+ // attributes to determine the sequence of ring apply.
+ if( l_cpltRingVariantSz > 1)
+ {
+ // Check if this is cache-contained IPL
+ uint8_t l_iplPhase;
+ FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_IPL_PHASE,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> (),
+ l_iplPhase);
+
+ // 4 : Cache Contained mode
+ if(CACHE_CONTAINED_MODE == l_iplPhase)
+ {
+ l_ringTorAddr += CACHE_CONTAINED_MODE_OFFSET_IN_TOR;
+ }
+ else
+ {
+ // Check if this is risk-level IPL
+ uint8_t l_riskLevel;
+ FAPI_ATTR_GET(fapi2::ATTR_RISK_LEVEL,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> (),
+ l_riskLevel);
+ if(RISK_LEVEL_MODE == l_riskLevel)
+ {
+ l_ringTorAddr += RISK_LEVEL_MODE_OFFSET_IN_TOR;
+ }
+ }
+ }
+
+ SBE_TRACE("l_ringTorAddr %u",*l_ringTorAddr);
+ if(*l_ringTorAddr != 0)
+ {
+ uint8_t *l_addr = reinterpret_cast<uint8_t *>(l_sectionAddr);
+ uint8_t *l_rs4Address = reinterpret_cast<uint8_t *>
+ (l_addr + *l_ringTorAddr);
+ SBE_TRACE("l_rs4Address %08x",l_rs4Address);
+ l_rc = rs4DecompressionSvc(i_target,l_rs4Address,
+ i_applyOverride,i_ringMode);
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ SBE_TRACE("Error from applyRS4_SS");
+ break;
+ }
+ }
+ else
+ {
+ SBE_TRACE("Ring image is not found for this is ringId %u",i_ringID);
+ }
+ }while(0);
+
+ SBE_TRACE("<< findRS4InImageAndApply Exit for ringId %d",i_ringID);
+ return l_rc;
+}
+
diff --git a/src/hwpf/src/return_code.C b/src/hwpf/src/return_code.C
new file mode 100644
index 00000000..77ca80c8
--- /dev/null
+++ b/src/hwpf/src/return_code.C
@@ -0,0 +1,46 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/hwpf/src/return_code.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* */
+/* */
+/* 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 return_code.C
+ *
+ * @brief Fuctions that process PPE return codes
+ */
+
+#include <return_code.H>
+
+namespace fapi2
+{
+
+ /// @brief Takes a non-zero PIB return code and inssert the value into
+ /// a fapi2::ReturnCode
+ /// @param[in] i_msr Value read from the PPE MSR
+ /// @return fapi::ReturnCode. Built ReturnCode
+ ReturnCode& ReturnCode::insertPIBcode(uint32_t& rhs)
+ {
+ iv_rc = FAPI2_RC_PLAT_MASK | rhs;
+ return iv_rc;
+ }
+
+}
diff --git a/src/image/Makefile b/src/image/Makefile
new file mode 100644
index 00000000..7de0cfbc
--- /dev/null
+++ b/src/image/Makefile
@@ -0,0 +1,316 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/image/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+
+
+#Pull in the definitions that affect all makefiles for this image
+include img_defs.mk
+
+include ../boot/bootfiles.mk
+
+#Pull in object file names for the top directory
+include topfiles.mk
+
+SUBDIRS := $(PK_SRCDIR)/$(PPE_TYPE)
+LIB_DIRS += -L$(OBJDIR)/pk
+PKLIB := $(OBJDIR)/pk/libpk.a
+LLIBS += -lpk
+
+SUBDIRS += $(BOOT_SRCDIR)
+
+SUBDIRS += ../sbefw
+LIB_DIRS += -L$(OBJDIR)/sbefw
+SBEFWLIB := $(OBJDIR)/sbefw/libsbefw.a
+LLIBS += -lsbefw
+
+# FAPI2 library
+SUBDIRS += $(PLAT_FAPI2_DIR)/src
+LIB_DIRS += -L$(OBJDIR)/fapi2
+FAPI2LIB := $(OBJDIR)/fapi2/libfapi2.a
+LLIBS += -lfapi2
+
+LIB_DIRS += -L$(GCC-TOOL-PATH)/libgcc
+LLIBS += -lmath -leabi -lc
+
+# HWP LIB library
+SUBDIRS += $(HWPLIB_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/lib
+HWPLIB := $(OBJDIR)/libcommon.a
+LLIBS += -lcommon
+include $(HWPERR_SRCDIR)/hwpErrors.mk
+
+# Common Utils library
+SUBDIRS += $(UTILS_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/utils
+UTILSLIB := $(OBJDIR)/utils/libutils.a
+LLIBS += -lutils
+
+# Common Cache HWP Exit library
+SUBDIRS += $(CACHE_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/cache
+CACHELIB := $(OBJDIR)/cache/libcache.a
+LLIBS += -lcache
+
+# Common Core libraries
+SUBDIRS += $(CORE_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/core
+CORELIB := $(OBJDIR)/core/libcore.a
+LLIBS += -lcore
+
+# Common Perv libraries
+SUBDIRS += $(PERV_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/perv
+PERVLIB := $(OBJDIR)/perv/libperv.a
+LLIBS += -lperv
+
+# Common Nest libraries
+SUBDIRS += $(NEST_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/nest
+NESTLIB := $(OBJDIR)/nest/libnest.a
+LLIBS += -lnest
+
+# Initfiles library
+SUBDIRS += $(INITFILES_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/initfiles
+INITFILESLIB := $(OBJDIR)/initfiles/libinitfiles.a
+LLIBS += -linitfiles
+
+# Common Pm libraries
+SUBDIRS += $(PM_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/pm
+PMLIB := $(OBJDIR)/pm/libpm.a
+LLIBS += -lpm
+
+SIMICS_PPE_TAR_FILES += $(OBJDIR)/$(IMAGE_SBE_NAME).out
+SIMICS_PPE_TAR_FILES += $(OBJDIR)/$(IMAGE_SBE_NAME).map
+SIMICS_PPE_TAR_FILES += $(OBJDIR)/$(IMAGE_SBE_NAME).dis
+SIMICS_PPE_TAR_FILES += $(BOOT_OBJDIR)/$(IMAGE_LOADER_NAME).out
+SIMICS_PPE_TAR_FILES += $(BOOT_OBJDIR)/$(IMAGE_LOADER_NAME).map
+SIMICS_PPE_TAR_FILES += $(BOOT_OBJDIR)/$(IMAGE_LOADER_NAME).dis
+SIMICS_PPE_TAR_FILES += $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out
+SIMICS_PPE_TAR_FILES += $(OBJDIR)/$(IMAGE_SEEPROM_NAME).map
+SIMICS_PPE_TAR_FILES += $(OBJDIR)/$(IMAGE_SEEPROM_NAME).dis
+SIMICS_PPE_TAR_FILES += $(OBJDIR)/sbe.syms
+SIMICS_PPE_TAR_FILES += $(TEST_SRCDIR)/*.xml
+SIMICS_PPE_TAR_FILES += $(TEST_SRCDIR)/*.py
+SIMICS_PPE_TAR_FILES += $(PPETRACEPP_DIR)/fsp-trace
+SIMICS_PPE_TAR_FILES += $(OBJDIR)/sbeStringFile
+SIMICS_PPE_TAR_FILES += $(OBJDIR)/ppe2fsp
+SIMICS_BB_TAR_FILES += $(SIMICSTOOLS_SRCDIR)/*
+SIMICS_PPETRACEPP_TAR_FILES += $(PPETRACEPP_DIR)/cmvc/makefile
+SIMICS_PPETRACEPP_TAR_FILES += $(PPETRACEPP_DIR)/ppe2fsp.h
+SIMICS_PPETRACEPP_TAR_FILES += $(PPETRACEPP_DIR)/ppe2fsp.c
+SIMICS_PPETRACEPP_TAR_FILES += $(PPETRACEPP_DIR)/ppe2fsp_cmd.c
+SIMICS_PPETRACEPP_TAR_FILES += $(PPETRACEPP_DIR)/trac_interface.h
+SIMICS_PPETRACEPP_TAR_FILES += $(PK_SRCDIR)/trace/pk_trace.h
+SIMICS_PARSERPLUGINS_TAR_FILES += $(SBE_FW_DIR)/plugins/sbeUserDataParser.C
+SIMICS_PARSERPLUGINS_TAR_FILES += $(SBE_FW_DIR)/sbeFFDCType.H
+
+SBE_TOOLS := $(BASE_OBJDIR)/sbe_default_tool
+
+P9_XIP_TOOL := $(P9_XIP_BINDIR)/p9_xip_tool
+
+LINK_OBJS = $(OBJS)
+
+# Define the objects
+OBJS := $(addprefix $(OBJDIR)/, $(TOP_OBJECTS))
+LINK_OBJS += $(OBJS) $(GCCLIBS)
+
+LINK_SCRIPT_SEEPROM = $(addprefix $(OBJDIR)/, linkscriptseeprom)
+LINK_SCRIPT_SBE = $(addprefix $(OBJDIR)/, linkscriptsbe)
+
+# ---- SEEPROM Image ------
+# This removes all unecessary headers from the ELF executable
+$(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(OBJDIR)/$(IMAGE_SEEPROM_NAME).dis: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out
+ ./parsAndCutElf.py
+ $(OBJDUMP) -S $< > $(OBJDIR)/$(IMAGE_SEEPROM_NAME).dis
+
+#create a linked ELF executable
+$(OBJDIR)/$(IMAGE_SEEPROM_NAME).out: ppe_trace_bin buildInfo $(SUBDIRS) $(LINK_OBJS) $(LINK_SCRIPT_SEEPROM)
+ $(LD) -n -T$(LINK_SCRIPT_SEEPROM) -Map $(OBJDIR)/$(IMAGE_SEEPROM_NAME).map \
+ -Bstatic -o $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out $(BOOT_OBJDIR)/$(BOOT_OBJECTS) $(OBJS) $(LIB_DIRS) \
+ --start-group $(LLIBS) --end-group -leabi -lmath -lc
+
+# pass the link command file through the C preprocessor to evaluate macros
+# and remove comments
+$(LINK_SCRIPT_SEEPROM): linkseeprom.cmd
+ $(CPP) -I. -E -x c++ -P $(DEFS) linkseeprom.cmd -o $(LINK_SCRIPT_SEEPROM)
+
+# ---- PIBMEM Image ------
+#This removes all unecessary headers from the ELF executable
+$(OBJDIR)/$(IMAGE_SBE_NAME).bin $(OBJDIR)/$(IMAGE_SBE_NAME).dis: $(OBJDIR)/$(IMAGE_SBE_NAME).out
+ $(OBJCOPY) -O binary $< $(OBJDIR)/$(IMAGE_SBE_NAME).bin --pad-to \
+ 0x`/usr/bin/nm $(OBJDIR)/$(IMAGE_SBE_NAME).out | grep "A _sbe_end" \
+ | cut -d " " -f 1`
+ $(OBJDUMP) -S $< > $(OBJDIR)/$(IMAGE_SBE_NAME).dis
+ $(NM) $< > $(OBJDIR)/$(IMAGE_SBE_NAME).syms
+
+# create a linked ELF executable
+$(OBJDIR)/$(IMAGE_SBE_NAME).out: ppe_trace_bin buildInfo $(OBJDIR)/base_sbe_fixed.o $(SUBDIRS) $(LINK_OBJS) $(LINK_SCRIPT_SBE)
+ $(LD) -e __system_reset -T$(LINK_SCRIPT_SBE) -Map $(OBJDIR)/$(IMAGE_SBE_NAME).map -Bstatic -o $(OBJDIR)/$(IMAGE_SBE_NAME).out $(LIB_DIRS) $(OBJDIR)/base_sbe_fixed.o --start-group $(LLIBS) --end-group
+
+# pass the link command file through the C preprocessor to evaluate macros and remove comments
+$(LINK_SCRIPT_SBE): linksbe.cmd
+ $(CPP) -E -x c++ -I. -P $(DEFS) linksbe.cmd -o $(LINK_SCRIPT_SBE)
+
+all: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(OBJDIR)/$(IMAGE_SBE_NAME).bin \
+ $(SBE_TOOLS) normalize defaultset $(OBJDIR)/fixed.bin appendloader \
+ appendoverrides add_LoaderAddr symbols tracehash buildinfo report
+
+install: all
+ @echo "Installing simics.tar"
+ @rm -rf $(OBJDIR)/simics-tar-dir
+ @mkdir $(OBJDIR)/simics-tar-dir
+ @mkdir $(OBJDIR)/simics-tar-dir/ppetracepp
+ @mkdir $(OBJDIR)/simics-tar-dir/parserplugins
+ @cp $(SIMICS_PPE_TAR_FILES) $(OBJDIR)/simics-tar-dir
+ @cp $(SIMICS_BB_TAR_FILES) $(OBJDIR)/simics-tar-dir
+ @cp $(SIMICS_PPETRACEPP_TAR_FILES) $(OBJDIR)/simics-tar-dir/ppetracepp
+ @cp $(SIMICS_PARSERPLUGINS_TAR_FILES) $(OBJDIR)/simics-tar-dir/parserplugins
+ @cd $(OBJDIR)/simics-tar-dir && tar -cvf simics.tar * && mv simics.tar $(OBJDIR) && cd ..
+ @rm -rf $(OBJDIR)/simics-tar-dir
+ @echo "Generated simics.tar in Sbe Obj Directory"
+
+.PHONY: all normalize defaultset appendloader add_LoaderAddr symbols report \
+ appendoverrides xml tracehash topfixedheaders $(SUBDIRS)
+
+buildinfo: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set build_date `date +%Y%m%d`
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set build_time `date +%H%M`
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set build_user `id -un`
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set build_host `hostname`
+
+add_LoaderAddr: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set L1_LoaderAddr 0x`nm $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out | grep __pmLoader | cut -f 1 -d " "`
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set L2_LoaderAddr 0x`nm $(BOOT_OBJDIR)/$(IMAGE_LOADER_NAME).out | grep __base_loader_setup | cut -f 1 -d " "`
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin set kernelAddr 0x`nm $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out | grep __pk_boot | cut -f 1 -d " "`
+
+symbols: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out $(BOOT_OBJDIR)/$(IMAGE_LOADER_NAME).out $(OBJDIR)/$(IMAGE_SBE_NAME).out
+ $(NM) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out > $(OBJDIR)/$(SBE_SYMBOLS_NAME)
+ $(NM) $(BOOT_OBJDIR)/$(IMAGE_LOADER_NAME).out >> $(OBJDIR)/$(SBE_SYMBOLS_NAME)
+
+report: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin report > $(OBJDIR)/$(IMAGE_SEEPROM_NAME).rpt
+
+# Create build Info file
+buildInfo:
+ python buildInfo.py
+
+
+#Create an obj directory if needed
+$(LINK_OBJS) $(OBJS) $(OBJS:.o=.d) $(OBJDIR)/base_sbe_fixed.o $(OBJDIR)/base_sbe_fixed.d: | $(OBJDIR)
+
+ATTRFILES += $(IMPORT_XML_DIR)/attribute_info/pervasive_attributes.xml
+# TODO via RTC 142708
+# Workaound for ATTR_CHIP_UNIT_POS. Remove Mirror_WA_attributes.xml once fapi
+# support is in.
+ATTRFILES += $(IMAGE_SRCDIR)/Mirror_WA_attributes.xml
+ATTRFILES += $(IMPORT_XML_DIR)/attribute_info/p9_sbe_load_bootloader_attributes.xml
+ATTRFILES += $(IMPORT_XML_DIR)/attribute_info/core_attributes.xml
+ATTRFILES += $(IMPORT_XML_DIR)/attribute_info/nest_attributes.xml
+ATTRFILES += $(IMPORT_XML_DIR)/attribute_info/pm_plat_attributes.xml
+ATTRFILES += $(IMPORT_XML_DIR)/attribute_info/p9_cache_contained_attributes.xml
+ATTRFILES += $(BASE_FAPI2_DIR)/xml/attribute_info/chip_attributes.xml
+ATTRFILES += $(IMPORT_XML_DIR)/attribute_info/chip_ec_attributes.xml
+
+$(OBJDIR):
+ $(TOOLS_ATTR_DIR)/ppeParseProcSbeFixed.pl . $(IMPORT_XML_DIR)/attribute_info/p9_sbe_attributes.xml $(ATTRFILES)
+ $(TOOLS_ATTR_DIR)/ppeParseAttributeInfo.pl $(PLAT_FAPI2_DIR)/include $(IMPORT_XML_DIR)/attribute_info/p9_sbe_attributes.xml $(ATTRFILES)
+ $(TOOLS_ATTR_DIR)/ppeCreateAttrGetSetMacros.pl --path $(TOOLS_ATTR_DIR)/src --inc $(PLAT_FAPI2_DIR)/include --src $(PLAT_FAPI2_DIR)/src
+ $(TOOLS_ATTR_DIR)/ppeCreateIfAttrService.pl $(PLAT_FAPI2_DIR)/include $(IMPORT_XML_DIR)/attribute_info/p9_sbe_attributes.xml $(ATTRFILES)
+ mkdir -p $(OBJDIR)
+
+topfixedheaders:
+ $(TOOLS_ATTR_DIR)/ppeParseProcSbeFixed.pl . $(IMPORT_XML_DIR)/attribute_info/p9_sbe_attributes.xml $(ATTRFILES)
+
+attrids:
+ $(TOOLS_ATTR_DIR)/ppeParseAttributeInfo.pl $(PLAT_FAPI2_DIR)/include $(IMPORT_XML_DIR)/attribute_info/p9_sbe_attributes.xml $(ATTRFILES)
+
+platattr:
+ $(TOOLS_ATTR_DIR)/ppeCreateAttrGetSetMacros.pl --path $(TOOLS_ATTR_DIR)/src --inc $(PLAT_FAPI2_DIR)/include --src $(PLAT_FAPI2_DIR)/src
+
+attrserv:
+ $(TOOLS_ATTR_DIR)/ppeCreateIfAttrService.pl $(PLAT_FAPI2_DIR)/include $(IMPORT_XML_DIR)/attribute_info/p9_sbe_attributes.xml $(ATTRFILES)
+
+
+
+# Build the subdirectories
+$(SUBDIRS):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $@ -f Makefile
+
+
+#Build the SBE XIP Tools
+$(SBE_TOOLS): $(P9_XIP_TOOL)
+ $(info #######$(P9_XIP_TOOL)###########)
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(TOOLS_IMAGE_DIR) -f Makefile
+
+# Build the P9-XIP Tool
+$(P9_XIP_TOOL):
+ $(MAKE) -I $(P9_XIP_SRCDIR) -C $(P9_XIP_SRCDIR) -f Makefile BINDIR=$(P9_XIP_BINDIR)
+
+normalize: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin normalize
+
+defaultset: $(SBE_TOOLS) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin normalize
+ $(TOOLS_ATTR_DIR)/ppeSetFixed.pl $(BASE_OBJDIR) $(BASE_OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(IMPORT_XML_DIR)/attribute_info/p9_sbe_attributes.xml $(ATTRFILES)
+
+# Build the trace utilities
+ppe_trace_bin:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(PPETRACEPP_DIR) -f Makefile #$(PK trace util)
+
+
+# Build hwp_error_info.H. If the script fails then print the contents of
+# the header and then delete whatever garbage the script left to force it to
+# be built again.
+#
+
+xml: $(FAPI_RC)
+
+$(FAPI_RC): $(TOOLS_ATTR_DIR)/parseErrorInfo.pl $(ERROR_XML_FILES)
+ $(TOOLS_ATTR_DIR)/parseErrorInfo.pl --local-ffdc --output-dir=. $(ERROR_XML_FILES)
+
+$(OBJDIR)/fixed.bin: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin extract .fixed $(BASE_OBJDIR)/fixed.bin
+
+
+appendloader: $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(BOOT_OBJDIR)/$(IMAGE_LOADER_NAME).bin
+ $(P9_XIP_TOOL) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin append .baseloader $(BOOT_OBJDIR)/$(IMAGE_LOADER_NAME).bin
+
+# collect all of the trace hash files for this image into a single sbeStringFile
+tracehash:
+ mkdir -p $(OBJDIR)
+ $(THASH) -c -d $(OBJDIR) -s $(OBJDIR)/sbeStringFile
+
+#clean the kernel directory first, then the application level clean
+clean:
+ rm -fr $(OBJDIR)
+ rm -f $(TOP-FIXED-HEADERS)
+ rm -f collect_reg_ffdc.H hwp_return_codes.H hwp_error_info.H hwp_ffdc_classes.H collect_reg_ffdc.C set_sbe_error.H sbe_build_info.H
+ rm -f $(GEN-CREATEATTRGETSETMACROS)
+ rm -f $(GEN-PARSEATTRIBUTEINFO)
+ rm -f $(GEN-CREATEIFATTRSERVICE)
+
+#Add dependencies to header files
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/image/Mirror_WA_attributes.xml b/src/image/Mirror_WA_attributes.xml
new file mode 100644
index 00000000..6552eb27
--- /dev/null
+++ b/src/image/Mirror_WA_attributes.xml
@@ -0,0 +1,34 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/image/Mirror_WA_attributes.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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: proc_pll_ring_attributes.xml,v 1.17 2014/11/13 20:14:02 szhong Exp $ -->
+<!-- proc_pll_ring_attributes.xml -->
+<attributes>
+ <attribute>
+ <id>ATTR_CHIP_UNIT_POS</id>
+ <targetType>TARGET_TYPE_PERV</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+ </attribute>
+ <!-- ********************************************************************* -->
+</attributes>
diff --git a/src/image/base_ppe_header.S b/src/image/base_ppe_header.S
new file mode 100644
index 00000000..cf8e7c58
--- /dev/null
+++ b/src/image/base_ppe_header.S
@@ -0,0 +1,209 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/base_ppe_header.S $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file base_ppe_header.S
+/// \brief code to create header, toc, strings, fixed and fixed_toc sections
+///
+/// function P9XipHeader creates header section, function .proc_sbe_fixed
+/// creates fixed, fixed_toc sections
+#include "p9_xip_image.h"
+#include "proc_sbe_fixed.H"
+
+
+#define IMAGE_SPACE_UNDEFINED 0xffff
+#define IMAGE_SPACE_OCI 0x8000
+#define IMAGE_SPACE_PNOR 0x800b
+#define IMAGE_SPACE_OTPROM 0x0001
+#define IMAGE_SPACE_SEEPROM 0x800c
+#define IMAGE_SPACE_BASE 0x0008
+
+
+
+ .macro ..checku, x:req, bits:req, err="Unsigned value too large"
+
+ .if (((\bits) <= 0) || ((\bits) > 63))
+ .error "The number of bits must be in the range 0 < bits < 64"
+ .endif
+
+ .iflt (\x)
+ .error "An unsigned value is required here"
+ .endif
+
+ .ifgt ((\x) - (0xffffffffffffffff >> (64 - (\bits))))
+ .error "\err"
+ .endif
+
+ .endm
+
+ .macro ..check_u16, u16
+ ..checku (\u16), 16, "Unsigned immediate is larger than 16 bits"
+ .endm
+
+
+ .macro ..set_default_space, s
+ ..check_u16 (\s)
+ .set _PGAS_DEFAULT_SPACE, (\s)
+ .endm
+
+ .macro ..check_default_space
+ .if (_PGAS_DEFAULT_SPACE == IMAGE_SPACE_UNDEFINED)
+ .error "The PGAS default address space has not been defined"
+ .endif
+ .endm
+
+
+ .macro .quada, offset:req
+ ..check_default_space
+ .long _PGAS_DEFAULT_SPACE
+ .long (\offset)
+ .endm
+
+
+ .macro P9XipHeader, magic, link_address, entry_point, image_size
+
+ .section .header, "a", @progbits
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Identification - 8-byte aligned; 8 Entries; TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+__magic:
+ .quad (\magic)
+__L1_LoaderAddr:
+ .quad 0
+__L2_LoaderAddr:
+ .quad 0
+__kernelAddr:
+ .quad 0
+__link_address:
+ .quada (\link_address)
+__header_64_reserved:
+ .quad 0, 0, 0
+
+ .xip_toc magic, P9_XIP_UINT64, __magic
+ .xip_toc L1_LoaderAddr, P9_XIP_UINT64, __L1_LoaderAddr
+ .xip_toc L2_LoaderAddr, P9_XIP_UINT64, __L2_LoaderAddr
+ .xip_toc kernelAddr, P9_XIP_UINT64, __kernelAddr
+ .xip_toc link_address, P9_XIP_UINT64, __link_address
+
+ //////////////////////////////////////////////////////////////////////
+ // Section Table - Not TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+ .xip_section header
+ .xip_section fixed, 8
+ .xip_section fixed_toc, 8
+ .xip_section toc, 4
+ .xip_section strings
+ .xip_section loader_text, 4
+ .xip_section loader_data, 8, empty=1
+ .xip_section text, 4
+ .xip_section data, 8, empty=1
+ .xip_section base, 4
+ .xip_section baseloader, 8, empty=1
+ .xip_section overrides, 8, empty=1
+ .xip_section rings, 8, empty=1
+ .xip_section overlay, 8, empty=1
+ .xip_section hbbl, 8, empty=1
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Other Information - 4-byte aligned; 8 entries; TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+__image_size:
+ .long (\image_size)
+__build_date:
+ .long 0
+__build_time:
+ .long 0
+__header_32_reserved:
+ .long 0, 0, 0, 0, 0
+
+ .xip_toc image_size, P9_XIP_UINT32, __image_size
+ .xip_toc build_date, P9_XIP_UINT32, __build_date
+ .xip_toc build_time, P9_XIP_UINT32, __build_time
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Other Information - 1-byte aligned; 8 entries; TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+__header_version:
+ .byte P9_XIP_HEADER_VERSION
+__toc_normalized:
+ .byte 0
+__toc_sorted:
+ .byte 0
+__header_8_reserved:
+ .byte 0, 0, 0, 0, 0
+
+ .xip_toc header_version, P9_XIP_UINT8, __header_version
+ .xip_toc toc_normalized, P9_XIP_UINT8, __toc_normalized
+ .xip_toc toc_sorted, P9_XIP_UINT8, __toc_sorted
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Strings; 64 characters allocated; TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+__build_user:
+ .asciz "unknown " # 16 Characters allocated
+__build_host:
+ .asciz "unknown " # 24 characters allocated
+__header_string_reserved:
+ .space 24, 0
+
+ .xip_toc build_user, P9_XIP_STRING, __build_user
+ .xip_toc build_host, P9_XIP_STRING, __build_host
+
+
+ .endm
+
+
+ .section .fixed, "a", @progbits
+ .section .fixed_toc, "a", @progbits
+ .section .loader_data, "a", @progbits
+ .section .loader_text, "a", @progbits
+
+ .section .toc, "a", @progbits
+ .section .strings, "aS", @progbits
+ .section .base, "a", @progbits
+
+ ..set_default_space IMAGE_SPACE_SEEPROM
+ P9XipHeader P9_XIP_MAGIC_SEEPROM, 0x80000000, 0x00000000, _sbe_image_size
+
+ // Create the .fixed section
+ .proc_sbe_fixed_system
+ .proc_sbe_fixed_proc_chip
+ .proc_sbe_fixed_perv
+ .proc_sbe_fixed_core
+ .proc_sbe_fixed_ex
+ .proc_sbe_fixed_eq
diff --git a/src/image/base_sbe_fixed.S b/src/image/base_sbe_fixed.S
new file mode 100644
index 00000000..bcfc0e1e
--- /dev/null
+++ b/src/image/base_sbe_fixed.S
@@ -0,0 +1,67 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/base_sbe_fixed.S $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 sbefixed.S
+/// \brief code to generated fixed section in pibmem image
+///
+#include "p9_xip_image.h"
+#include "proc_sbe_fixed.H"
+
+
+ .macro ..checku, x:req, bits:req, err="Unsigned value too large"
+
+ .if (((\bits) <= 0) || ((\bits) > 63))
+ .error "The number of bits must be in the range 0 < bits < 64"
+ .endif
+
+ .iflt (\x)
+ .error "An unsigned value is required here"
+ .endif
+
+ .ifgt ((\x) - (0xffffffffffffffff >> (64 - (\bits))))
+ .error "\err"
+ .endif
+
+ .endm
+
+
+ .macro ..check_u16, u16
+ ..checku (\u16), 16, "Unsigned immediate is larger than 16 bits"
+ .endm
+
+
+ .macro ..set_default_space, s
+ ..check_u16 (\s)
+ .set _PGAS_DEFAULT_SPACE, (\s)
+ .endm
+
+ .section .fixed, "a", @progbits
+
+
+ // Create the .fixed section
+ .proc_sbe_fixed_system
+ .proc_sbe_fixed_proc_chip
+ .proc_sbe_fixed_perv
+ .proc_sbe_fixed_core
+ .proc_sbe_fixed_ex
+ .proc_sbe_fixed_eq
diff --git a/src/image/buildInfo.py b/src/image/buildInfo.py
new file mode 100755
index 00000000..a881cb88
--- /dev/null
+++ b/src/image/buildInfo.py
@@ -0,0 +1,48 @@
+#! /usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/image/buildInfo.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+# This script will create header file sbe_build_info.H which will have
+# buld information required by SBE code.
+import os
+buildInfoFileName = "sbe_build_info.H"
+
+def buildInfo():
+ header = \
+"#ifndef SBE_BUILD_INFO_H \n\
+#define SBE_BUILD_INFO_H \n\n"
+
+ footer = "\n#endif // SBE_BUILD_INFO_H"
+ commitId = "0x" + os.popen("git rev-parse --short=8 HEAD").read().rstrip()
+
+ f = open( buildInfoFileName, 'w')
+
+ f.write(header)
+ f.write("//Define SBE Commit ID \n")
+ f.write("#define SBE_COMMIT_ID " + commitId + "\n")
+ f.write(footer)
+ f.close()
+
+# Call buildInfo
+buildInfo()
diff --git a/src/image/img_defs.mk b/src/image/img_defs.mk
new file mode 100644
index 00000000..ea12c1bf
--- /dev/null
+++ b/src/image/img_defs.mk
@@ -0,0 +1,486 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/image/img_defs.mk $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+# Make header for SBE image build
+#
+# Settings to for SBE image file build
+#
+# IMG_INCLUDES : Aplication-specific header search paths
+#
+# DEFS : A string of -D<symbol>[=<value>] to control compilation
+#
+# PK : Default ..; The path to the PK source code.
+# The default is set for building the PK
+# subdirectories.
+#
+# PK_THREAD_SUPPORT : (0/1, default 1); Compile PK thread and
+# semaphore suppprt
+#
+# PK_TIMER_SUPPORT : (0/1, default 1); Compile PK timer suppprt
+#
+# GCC-O-LEVEL : The optimization level passed to GCC (default -Os). May
+# also be defined empty (GCC-O-LEVEL=) to disable
+# optimization. This variable can also be used to pass
+# any other non-default setting to GCC, e.g.
+# make GCC-O-LEVEL="-Os -fno-branch-count-reg"
+#
+# GCC-TOOL-PREFIX : The full path (including executable file prefixes) to
+# the GCC cross-development tools to use. The default is
+# "ppcnf-mcp5-"
+#
+# CTEPATH : This variable defaults to the afs/awd CTE tool
+# installation - The PORE binutils are stored there. If
+# you are not in Austin be sure to define CTEPATH in
+# your .profile.
+#
+# OBJDIR : target directory for all generated files
+
+IMAGE_SEEPROM_NAME := sbe_seeprom
+IMAGE_SBE_NAME := sbe_pibmem
+IMAGE_LOADER_NAME := sbe_loader
+IMAGE_OTPROM_NAME := sbe_otprom
+
+SBE_SYMBOLS_NAME := sbe.syms
+
+ifndef PPE_TYPE
+PPE_TYPE := std
+endif
+
+ifndef SBE_ROOT_DIR
+export SBE_ROOT_DIR = $(abspath ../..)
+endif
+
+ifndef SBE_SRC_DIR
+export SBE_SRC_DIR = $(SBE_ROOT_DIR)/src
+endif
+
+ifndef SBE_FW_DIR
+export SBE_FW_DIR = $(SBE_SRC_DIR)/sbefw
+endif
+
+ifndef IMAGE_SRCDIR
+export IMAGE_SRCDIR = $(SBE_SRC_DIR)/image
+endif
+
+ifndef BOOT_SRCDIR
+export BOOT_SRCDIR = $(SBE_SRC_DIR)/boot
+endif
+
+ifndef IMPORT_SRCDIR
+export IMPORT_SRCDIR = $(SBE_ROOT_DIR)/import
+endif
+
+ifndef TOOLS_SRCDIR
+export TOOLS_SRCDIR = $(SBE_SRC_DIR)/tools
+endif
+
+ifndef TEST_SRCDIR
+export TEST_SRCDIR = $(SBE_SRC_DIR)/test
+endif
+
+ifndef DEBUGTOOLS_SRCDIR
+export DEBUGTOOLS_SRCDIR = $(TOOLS_SRCDIR)/debug
+endif
+
+ifndef SIMICSTOOLS_SRCDIR
+export SIMICSTOOLS_SRCDIR = $(DEBUGTOOLS_SRCDIR)/simics
+endif
+
+ifndef UTILS_SRCDIR
+export UTILS_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/utils
+endif
+
+ifndef CACHE_SRCDIR
+export CACHE_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/procedures/hwp/cache
+endif
+
+ifndef CORE_SRCDIR
+export CORE_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/procedures/hwp/core
+endif
+
+ifndef PERV_SRCDIR
+export PERV_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/procedures/hwp/perv
+endif
+
+ifndef HWPERR_SRCDIR
+export HWPERR_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/procedures/xml/error_info
+endif
+
+ifndef NEST_SRCDIR
+export NEST_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/procedures/hwp/nest
+endif
+
+ifndef PM_SRCDIR
+export PM_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/procedures/hwp/pm
+endif
+
+ifndef INITFILES_SRCDIR
+export INITFILES_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/procedures/hwp/initfiles
+endif
+
+ifndef HWPLIB_SRCDIR
+export HWPLIB_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/procedures/hwp/lib
+endif
+
+ifndef IMAGEPROCS_SRCDIR
+export IMAGEPROCS_SRCDIR = $(IMPORT_SRCDIR)/tools/imageProcs
+endif
+
+ifndef BASE_OBJDIR
+export BASE_OBJDIR = $(SBE_ROOT_DIR)/obj
+endif
+
+ifndef P9_XIP_SRCDIR
+export P9_XIP_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/xip
+endif
+
+ifndef P9_XIP_BINDIR
+export P9_XIP_BINDIR = $(BASE_OBJDIR)/xip
+endif
+
+ifndef IMG_INCLUDES
+export IMG_INCLUDES = -I$(IMAGEPROCS_SRCDIR) -I$(P9_XIP_SRCDIR) -I$(IMAGE_SRCDIR) -I$(CACHE_SRCDIR) -I$(UTILS_SRCDIR) -I$(CORE_SRCDIR) -I$(PERV_SRCDIR) -I$(NEST_SRCDIR) -I$(PM_SRCDIR) -I$(INITFILES_SRCDIR)
+endif
+
+ifndef BOOT_OBJDIR
+export BOOT_OBJDIR = $(BASE_OBJDIR)/boot
+endif
+
+export IMG_OBJDIR = $(BASE_OBJDIR)/$(IMAGE_SEEPROM_NAME)
+
+ifndef PK_SRCDIR
+export PK_SRCDIR = $(IMPORT_SRCDIR)/chips/p9/procedures/ppe/pk
+endif
+
+
+ifndef TOOLS_ATTR_DIR
+export TOOLS_ATTR_DIR = $(TOOLS_SRCDIR)/scripts
+endif
+
+ifndef TOOLS_IMAGE_DIR
+export TOOLS_IMAGE_DIR = $(TOOLS_SRCDIR)/image
+endif
+
+ifndef IMPORT_XML_DIR
+export IMPORT_XML_DIR = $(IMPORT_SRCDIR)/chips/p9/procedures/xml
+endif
+
+ifndef IMPORT_UTILS_DIR
+export IMPORT_UTILS_DIR = $(IMPORT_SRCDIR)/chips/p9/utils
+endif
+
+ifndef IMPORT_COMMON_DIR
+export IMPORT_COMMON_DIR = $(IMPORT_SRCDIR)/chips/p9/common
+endif
+
+ifndef PPETRACEPP_DIR
+export PPETRACEPP_DIR = $(TOOLS_SRCDIR)/ppetracepp
+endif
+
+ifndef PPETRACEPP_BIN_DIR
+export PPETRACEPP_BIN_DIR = $(BASE_OBJDIR)
+endif
+
+ifndef PLAT_FAPI2_DIR
+export PLAT_FAPI2_DIR = $(SBE_SRC_DIR)/hwpf
+endif
+
+ifndef BASE_FAPI2_DIR
+export BASE_FAPI2_DIR = $(IMPORT_SRCDIR)/hwpf/fapi2
+endif
+
+ifndef FAPI2_TOOLS_DIR
+export FAPI2_TOOLS_DIR = $(IMPORT_SRCDIR)/hwpf/fapi2/tools/
+endif
+
+ifdef P2P_ENABLE
+ifndef CC_ROOT
+export CC_ROOT = ${CTEPATH}/tools/gcc405lin/prod
+endif
+endif
+
+GCC-TOOL-PATH = $(CTEPATH)/tools/ppetools/prod
+
+
+ifndef GCC-TOOL-PREFIX
+GCC-TOOL-PREFIX = $(GCC-TOOL-PATH)/bin/powerpc-eabi-
+endif
+
+ifndef BINUTILS-TOOL-PREFIX
+BINUTILS-TOOL-PREFIX = $(CTEPATH)/tools/ppetools/prod/powerpc-eabi/bin/
+endif
+
+ifndef FAPI_RC
+FAPI_RC = hwp_return_codes.H
+#FAPI_RC =
+endif
+
+OBJDIR = $(BASE_OBJDIR)$(SUB_OBJDIR)
+
+CC_ASM = $(GCC-TOOL-PREFIX)gcc
+#TCC = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)g++
+TCC = $(PPETRACEPP_BIN_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+CC = $(PPETRACEPP_BIN_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+AS = $(BINUTILS-TOOL-PREFIX)as
+AR = $(BINUTILS-TOOL-PREFIX)ar
+LD = $(BINUTILS-TOOL-PREFIX)ld
+NM = $(BINUTILS-TOOL-PREFIX)nm -S
+OBJDUMP = $(BINUTILS-TOOL-PREFIX)objdump
+OBJCOPY = $(BINUTILS-TOOL-PREFIX)objcopy
+TCPP = $(PPETRACEPP_BIN_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+THASH = $(PPETRACEPP_DIR)/tracehash.pl
+CPP = $(GCC-TOOL-PREFIX)gcc
+
+ifdef P2P_ENABLE
+PCP = $(P2P_SRCDIR)/ppc-ppe-pcp.py
+endif
+
+
+ifndef CTEPATH
+$(warning The CTEPATH variable is not defined; Defaulting to /afs/awd)
+export CTEPATH = /afs/awd/projects/cte
+endif
+
+ifeq "$(PK_TIMER_SUPPORT)" ""
+PK_TIMER_SUPPORT = 1
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" ""
+PK_THREAD_SUPPORT = 1
+endif
+
+ifeq "$(PK_TRACE_SUPPORT)" ""
+PK_TRACE_SUPPORT = 1
+endif
+
+ifdef SBE_ISTEP_STUBBED
+GCC-DEFS += -DSBE_ISTEP_STUBBED=1
+endif
+
+ifdef SIM_ONLY_OSC_SWC_CHK
+GCC-DEFS += -DSIM_ONLY_OSC_SWC_CHK=1
+endif
+
+ifdef __FAPI_DELAY_SIM__
+GCC-DEFS += -D__FAPI_DELAY_SIM__=1
+endif
+
+# Generate a 16bit trace string hash prefix value based on the name of this image. This will form
+# the upper 16 bits of the 32 bit trace hash values.
+ifndef PK_TRACE_HASH_PREFIX
+PK_TRACE_HASH_PREFIX := $(shell echo $(IMAGE_SEEPROM_NAME) | md5sum | cut -c1-4 | xargs -i printf "%d" 0x{})
+endif
+
+ifndef GCC-O-LEVEL
+ifdef P2P_ENABLE
+GCC-O-LEVEL = -O
+#GCC-O-LEVEL = -O -g
+else
+GCC-O-LEVEL = -Os
+#GCC-O-LEVEL = -Os -g
+endif
+endif
+
+FAPI_TRACE_LEVEL_DEF = 4
+ifdef FAPI_TRACE_LEVEL_ENV
+FAPI_TRACE_LEVEL_DEF = $(FAPI_TRACE_LEVEL_ENV)
+endif
+
+# Levels of SBE logging
+# 0 - No tracing
+# 1 - Error
+# 2 - Error, info
+# 3 - Error, info, entry/exit
+# 4 - Error, info, entry/exit, debug
+SBE_TRACE_LEVEL_DEF = 3
+
+GCC-DEFS += -DIMAGE_NAME=$(IMAGE_SEEPROM_NAME)
+GCC-DEFS += -DPK_TIMER_SUPPORT=$(PK_TIMER_SUPPORT)
+GCC-DEFS += -DPK_THREAD_SUPPORT=$(PK_THREAD_SUPPORT)
+GCC-DEFS += -DPK_TRACE_SUPPORT=$(PK_TRACE_SUPPORT)
+GCC-DEFS += -DPK_TRACE_HASH_PREFIX=$(PK_TRACE_HASH_PREFIX)
+GCC-DEFS += -DUSE_PK_APP_CFG_H=1
+GCC-DEFS += -D__PK__=1
+GCC-DEFS += -D__SBE__=1
+GCC-DEFS += -D__PPE__=1
+GCC-DEFS += -DMINIMUM_FFDC=1
+GCC-DEFS += -DFAPI_TRACE_LEVEL=$(FAPI_TRACE_LEVEL_DEF)
+GCC-DEFS += -DSBE_TRACE_LEVEL=$(SBE_TRACE_LEVEL_DEF)
+# use the default settings in the code unless a size is defined
+ifdef PK_TRACE_SZ
+GCC-DEFS += -DPK_TRACE_SZ=$(PK_TRACE_SZ)
+endif
+
+DEFS += $(GCC-DEFS)
+export LD_LIBRARY_PATH+=:$(GCC-TOOL-PATH)/lib
+############################################################################
+
+
+INCLUDES += $(IMG_INCLUDES)
+INCLUDES += -I$(IMAGE_SRCDIR)/../../include
+INCLUDES += -I$(HWPLIB_SRCDIR)
+INCLUDES += -I$(PLAT_FAPI2_DIR)/include/plat
+INCLUDES += -I$(PLAT_FAPI2_DIR)/include
+INCLUDES += -I$(BASE_FAPI2_DIR)/include
+INCLUDES += -I$(PK_SRCDIR)/../include
+INCLUDES += -I$(PK_SRCDIR)/$(PPE_TYPE)
+INCLUDES += -I$(PK_SRCDIR)/../include
+INCLUDES += -I$(PK_SRCDIR)/../include/std
+INCLUDES += -I$(PK_SRCDIR)/kernel
+INCLUDES += -I$(PK_SRCDIR)/ppe
+INCLUDES += -I$(PK_SRCDIR)/ppe42
+INCLUDES += -I$(SBE_FW_DIR)
+INCLUDES += -I$(BOOT_SRCDIR)
+INCLUDES += -I$(PK_SRCDIR)/trace
+INCLUDES += -I$(PPETRACEPP_DIR)
+INCLUDES += -I$(IMPORT_COMMON_DIR)/include
+INCLUDES += -I$(IMPORT_UTILS_DIR)/imageProcs
+INCLUDES += -I$(IMPORT_UTILS_DIR)/
+
+GCC-CFLAGS += -Wall -Werror -Wno-unused-label
+GCC-CFLAGS += -msoft-float
+GCC-CFLAGS += -meabi -msdata=eabi
+GCC-CFLAGS += -gpubnames -gdwarf-3
+GCC-CFLAGS += -ffreestanding
+GCC-CFLAGS += -fno-common
+GCC-CFLAGS += -fno-exceptions
+GCC-CFLAGS += -fsigned-char
+GCC-CFLAGS += -fno-inline-functions-called-once
+
+ifdef P2P_ENABLE
+## Flags specific to 405 compiler with PowerPc to PPE backend
+PIPE-CFLAGS = -pipe -Wa,-m405
+
+GCC-CFLAGS += -mcpu=405 -mmulhw
+GCC-CFLAGS += -ffixed-r11
+GCC-CFLAGS += -ffixed-r12
+GCC-CFLAGS += -ffixed-r14
+GCC-CFLAGS += -ffixed-r15
+GCC-CFLAGS += -ffixed-r16
+GCC-CFLAGS += -ffixed-r17
+GCC-CFLAGS += -ffixed-r18
+GCC-CFLAGS += -ffixed-r19
+GCC-CFLAGS += -ffixed-r20
+GCC-CFLAGS += -ffixed-r21
+GCC-CFLAGS += -ffixed-r22
+GCC-CFLAGS += -ffixed-r23
+GCC-CFLAGS += -ffixed-r24
+GCC-CFLAGS += -ffixed-r25
+GCC-CFLAGS += -ffixed-r26
+GCC-CFLAGS += -ffixed-r27
+GCC-CFLAGS += -ffixed-cr1
+GCC-CFLAGS += -ffixed-cr2
+GCC-CFLAGS += -ffixed-cr3
+GCC-CFLAGS += -ffixed-cr4
+GCC-CFLAGS += -ffixed-cr5
+GCC-CFLAGS += -ffixed-cr6
+GCC-CFLAGS += -ffixed-cr7
+else
+## Flags specific to ppe42 compiler
+PIPE-CFLAGS = -pipe
+
+GCC-CFLAGS += -mcpu=ppe42
+GCC-CFLAGS += -ffunction-sections
+GCC-CFLAGS += -fdata-sections
+endif
+
+CFLAGS =
+PPE-CFLAGS = $(CFLAGS) -c $(GCC-CFLAGS) $(PIPE-CFLAGS) $(GCC-O-LEVEL) $(INCLUDES)
+
+CXXFLAGS = -std=c++11 -nostdinc++ -fno-rtti -fno-threadsafe-statics -fno-strict-aliasing
+CPPFLAGS = -E
+
+ASFLAGS = -mppe42
+
+ifdef P2P_ENABLE
+#use this to disable optimizations (fused compare/branch etc.)
+PCP-FLAG = -b
+endif
+
+############################################################################
+
+#override the GNU Make implicit rule for going from a .C to a .o
+%.o: %.C
+
+# -Wno-conversion-null is necesary to allow mapping of NULL to TARGET_TYPE_SYSTEM
+# for attribute accesses
+$(OBJDIR)/%.s: %.C
+ $(TCC) $(PPE-CFLAGS) $(DEFS) -Wno-conversion-null -S $(CXXFLAGS) -o $@ $<
+
+
+#override the GNU Make implicit rule for going from a .c to a .o
+%.o: %.c
+
+$(OBJDIR)/%.s: %.c
+ $(CC) $(PPE-CFLAGS) $(DEFS) -S -o $@ $<
+
+#override the GNU Make implicit rule for going from a .S to a .o
+%.o: %.S
+
+$(OBJDIR)/%.s: %.S
+ $(TCPP) $(PPE-CFLAGS) $(DEFS) $(CPPFLAGS) -o $@ $<
+.PRECIOUS: $(OBJDIR)/%.s
+
+ifndef P2P_ENABLE
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.s
+ $(AS) $(ASFLAGS) -o $@ $<
+
+else
+
+$(OBJDIR)/%.es: $(OBJDIR)/%.s
+ $(PCP) $(PCP-FLAG) -f $<
+.PRECIOUS: $(OBJDIR)/%.es
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.es
+ $(AS) $(ASFLAGS) -o $@ $<
+
+endif
+
+# From the GNU 'Make' manual - these scripts uses the preprocessor to
+# create dependency files (*.d), then mungs them slightly to make them
+# work as Make targets. The *.d files are include-ed in the
+# subdirectory Makefiles.
+
+$(OBJDIR)/%.d: %.C $(FAPI_RC)
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.c $(FAPI_RC)
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ echo "$(INCLUDES)"; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.S $(FAPI_RC)
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
diff --git a/src/image/linkloader.cmd b/src/image/linkloader.cmd
new file mode 100755
index 00000000..5e08a692
--- /dev/null
+++ b/src/image/linkloader.cmd
@@ -0,0 +1,96 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/linkloader.cmd $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+
+// Need to do this so that elf32-powerpc is not modified!
+#undef powerpc
+
+#ifndef BASE_LOADER_STACK_SIZE
+#define BASE_LOADER_STACK_SIZE 128
+#endif
+#include "sbe_link.H"
+
+OUTPUT_FORMAT(elf32-powerpc);
+
+MEMORY
+{
+ sram : ORIGIN = SBE_LOADER_BASE_ORIGIN, LENGTH = SBE_LOADER_BASE_LENGTH
+}
+
+SECTIONS
+{
+ . = SBE_LOADER_BASE_ORIGIN;
+
+ ////////////////////////////////
+ // Read-only Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _RODATA_SECTION_BASE = .;
+
+ .text . : { *(.text) } > sram
+ .data . : { *(.data) } > sram
+
+ // SDA2 constant sections .sdata2 and .sbss2 must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA2_BASE_ = .;
+ .sdata2 . : { *(.sdata2) } > sram
+ .sbss2 . : { *(.sbss2) } > sram
+
+ // Other read-only data.
+
+ .rodata . : { *(.rodata*) *(.got2) } > sram
+
+ _RODATA_SECTION_SIZE = . - _RODATA_SECTION_BASE;
+
+ ////////////////////////////////
+ // Read-write Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _DATA_SECTION_BASE = .;
+
+ // SDA sections .sdata and .sbss must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA_BASE_ = .;
+ .sdata . : { *(.sdata) } > sram
+ .sbss . : { *(.sbss) } > sram
+
+ // Other read-write data
+ // It's not clear why boot.S is generating empty .glink,.iplt
+
+ .rela . : { *(.rela*) } > sram
+ .rwdata . : { *(.data) *(.bss) } > sram
+
+ _BASE_LOADER_STACK_LIMIT = .;
+ . = . + BASE_LOADER_STACK_SIZE;
+ _BASE_LOADER_STACK_LIMIT = . - 1;
+
+ . = ALIGN(8);
+ _loader_end = . - 0;
+
+}
diff --git a/src/image/linkotprom.cmd b/src/image/linkotprom.cmd
new file mode 100644
index 00000000..8da70f49
--- /dev/null
+++ b/src/image/linkotprom.cmd
@@ -0,0 +1,43 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/linkotprom.cmd $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+
+// Need to do this so that elf32-powerpc is not modified!
+#undef powerpc
+
+#include "sbe_link.H"
+
+OUTPUT_FORMAT(elf32-powerpc);
+
+MEMORY
+{
+ sram : ORIGIN = OTPROM_ORIGIN, LENGTH = OTPROM_BLOCK_SIZE
+}
+
+SECTIONS
+{
+ . = OTPROM_ORIGIN;
+ .text . : { *(.text)}
+ . = OTPROM_FIXED_SIZE;
+ .fixed . : { *(.fixed)}
+}
diff --git a/src/image/linksbe.cmd b/src/image/linksbe.cmd
new file mode 100644
index 00000000..67303295
--- /dev/null
+++ b/src/image/linksbe.cmd
@@ -0,0 +1,108 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/linksbe.cmd $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+
+// Need to do this so that elf32-powerpc is not modified!
+#undef powerpc
+
+#ifndef INITIAL_STACK_SIZE
+#define INITIAL_STACK_SIZE 256
+#endif
+#include <sbe_link.H>
+
+OUTPUT_FORMAT(elf32-powerpc);
+
+MEMORY
+{
+ // increasing ram size as workaround so that pibmem image compilation
+ // doe not fail.
+ // TODO: Reducing the SBE_BASE_ORIGIN by 0x1F000 to reduce the size of
+ // generated sbe_pibmem.bin. Just a workaround to use pibmem for poweron
+ sram : ORIGIN = SBE_BASE_ORIGIN - 0x1F000, LENGTH = SBE_BASE_LENGTH + 0x1F000
+}
+
+SECTIONS
+{
+ . = SBE_BASE_ORIGIN - 0x1F000;
+
+ .vectors : {. = ALIGN(512); *(.vectors)} > sram
+ .fixed . : {. = ALIGN(512); *(.fixed) } > sram
+ .text . : {. = ALIGN(512); *(.text)} > sram
+
+ ////////////////////////////////
+ // Read-only Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _RODATA_SECTION_BASE = .;
+
+ // SDA2 constant sections .sdata2 and .sbss2 must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA2_BASE_ = .;
+ .sdata2 . : { *(.sdata2*) } > sram
+ .sbss2 . : { *(.sbss2*) } > sram
+
+ // Other read-only data.
+
+ . = ALIGN(8);
+ .rodata . : { ctor_start_address = .;
+ *(.ctors) *(.ctors.*)
+ ctor_end_address = .;
+ *(rodata*) *(.got2) } > sram
+
+ _RODATA_SECTION_SIZE = . - _RODATA_SECTION_BASE;
+
+ ////////////////////////////////
+ // Read-write Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _DATA_SECTION_BASE = .;
+
+ // SDA sections .sdata and .sbss must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA_BASE_ = .;
+ .sdata . : { *(.sdata*) } > sram
+ _sbss_start = .;
+ .sbss . : { *(.sbss*) } > sram
+ _sbss_end = .;
+
+ // Other read-write data
+ // It's not clear why boot.S is generating empty .glink,.iplt
+
+ .rela . : { *(.rela*) } > sram
+ .rwdata . : { *(.data*) *(.bss*) } > sram
+
+ . = ALIGN(8);
+ _PK_INITIAL_STACK_LIMIT = .;
+ . = . + INITIAL_STACK_SIZE;
+ _PK_INITIAL_STACK = . - 1;
+
+ . = ALIGN(8);
+ _sbe_end = . - 0;
+
+}
diff --git a/src/image/linkseeprom.cmd b/src/image/linkseeprom.cmd
new file mode 100644
index 00000000..64cb6f77
--- /dev/null
+++ b/src/image/linkseeprom.cmd
@@ -0,0 +1,200 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/linkseeprom.cmd $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+// Need to do this so that elf32-powerpc is not modified!
+#undef powerpc
+#include <sbe_link.H>
+OUTPUT_FORMAT(elf32-powerpc);
+
+#ifndef INITIAL_STACK_SIZE
+#define INITIAL_STACK_SIZE 256
+#endif
+
+MEMORY
+{
+ pibmem : ORIGIN = SBE_BASE_ORIGIN, LENGTH = SBE_BASE_LENGTH
+ seeprom : ORIGIN = SBE_SEEPROM_BASE_ORIGIN, LENGTH = 0x40000
+}
+
+SECTIONS
+{
+ . = SBE_SEEPROM_BASE_ORIGIN;
+ _sbe_image_start_addr = . + SIZEOF_HEADERS;
+
+ // TODO via RTC 149153
+ // It seems first section in elf image is 8 byte aligned.
+ // We need to verify this assumption.
+
+ // Get 8 byte alligned address
+ _sbe_image_start_addr = ( ( _sbe_image_start_addr % 8) == 0 ) ? _sbe_image_start_addr : ( _sbe_image_start_addr + ( 8 - ( _sbe_image_start_addr % 8)));
+
+ // Get the image offset after elf header
+ _sbe_image_start_offset = _sbe_image_start_addr - .;
+ _seeprom_origin = . - 0;
+ _pibmem_origin = SBE_BASE_ORIGIN;
+
+ ////////////////////////////////
+ // Header
+ ////////////////////////////////
+ .header : {
+ _header_origin = .; _header_offset = . - _seeprom_origin; *(.header);
+ } > seeprom
+ _header_size = . - _header_origin;
+
+ // @TODO via RTC 136215
+ // We have used allignment 0x1000 so that it can be found
+ // at fixed location. once otprom loader support is enabled.
+ // alligment will not be required.
+
+ ////////////////////////////////
+ // LOADER_TEXT
+ ////////////////////////////////
+ .loader_text ALIGN(0x1000): {
+ _loader_text_origin = .; _loader_text_offset = . - _seeprom_origin;
+ *(.loader_text);
+ } > seeprom
+ _loader_text_size = . - _loader_text_origin;
+
+ // @TODO via RTC 136215
+ // loader_text section should come after fixed and related
+ // sections as we want fixed section at knowon offset. Currently we
+ // have shared SEEPROM start address ( IVPR register value ) with
+ // multiple teams. So keeping loader_text as first section. Once
+ // WE have otprom loader support, we will put loader_text at right
+ // position
+
+ ////////////////////////////////
+ // FIXED
+ ////////////////////////////////
+ .fixed ALIGN(0x200) : {
+ _fixed_origin = .; _fixed_offset = . - _seeprom_origin;
+ *(.fixed)
+ } > seeprom
+ _fixed_size = . - _fixed_origin;
+
+ ////////////////////////////////
+ // FIXED_TOC
+ ////////////////////////////////
+ .fixed_toc ALIGN(8) : {
+ _fixed_toc_origin = .; _fixed_toc_offset = . - _seeprom_origin; *(.fixed_toc);
+ } > seeprom
+ _fixed_toc_size = . - _fixed_toc_origin;
+
+ ////////////////////////////////
+ // TOC
+ ////////////////////////////////
+ .toc ALIGN(4): {
+ _toc_origin = .; _toc_offset = . - _seeprom_origin; *(.toc);
+ } > seeprom
+ _toc_size = . - _toc_origin;
+
+ ////////////////////////////////
+ // STRING
+ ////////////////////////////////
+ .strings : {
+ _strings_origin = .; _strings_offset = . - _seeprom_origin; *(.strings);
+ } > seeprom
+ _strings_size = . - _strings_origin;
+
+ .text ALIGN(8): {
+ _text_origin = .; _text_offset = . - _seeprom_origin;
+ *\libcore.a:(.text* ) *\libcache.a:(.text* ) *\libperv.a:(.text* )} > seeprom
+ _text_size = . - _text_origin;
+
+ _seeprom_size = . - _seeprom_origin;
+
+ // TODO via RTC 149153
+ // It seems when we jump across memory region, elf creates 32 byte offset.
+ // We need to verify this assumption.
+
+ _seeprom_size_with_elf_hdr = _seeprom_size + _sbe_image_start_offset;
+ _seeprom_size = ( ( _seeprom_size_with_elf_hdr % 32) == 0 ) ? _seeprom_size : ( _seeprom_size + ( 32 - (_seeprom_size_with_elf_hdr % 32)));
+
+
+ . = _pibmem_origin;
+ _base_origin = .;
+ _base_offset = . - _base_origin + _seeprom_size;
+
+ .pkVectors ALIGN(32) : {
+ *(.vectors)
+ } > pibmem
+
+ .base . : {
+ *(.text*) *(.eh_frame) *(.dtors*);
+ } > pibmem
+
+ . = ALIGN(8);
+ _RODATA_SECTION_BASE = .;
+
+ // SDA2 constant sections .sdata2 and .sbss2 must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA2_BASE_ = .;
+ .sdata2 . : { *(.sdata2*) } > pibmem
+ .sbss2 . : { *(.sbss2*) } > pibmem
+
+ . = ALIGN(8);
+ .rodata . : {
+ ctor_start_address = .;
+ *(.ctors) *(.ctors.*)
+ ctor_end_address = .;
+ *(.rodata*) *(.got2);
+ } > pibmem
+ _RODATA_SECTION_SIZE = . - _RODATA_SECTION_BASE;
+
+
+ . = ALIGN(8); _DATA_SECTION_BASE = .;
+ _SDA_BASE_ = .;
+ .data . : {
+ *(.data*) *(.comment)
+ } > pibmem
+ .sdata . : { *(.sdata*) } > pibmem
+ . = ALIGN(8);
+
+ // We do not want to store bss section in sbe image as laoder will take
+ // care of it while loading image on PIBMEM. It will save us space in
+ // SEEPROM. So define XIP image related variables here so that SBE image
+ // finishes here.
+
+ _base_size = . - _base_origin;
+ _pibmem_size = . - _pibmem_origin;
+ _sbe_image_size = _seeprom_size + ( . - _pibmem_origin );
+
+ _sbss_start = .;
+ .sbss . : {
+ *(.bss*) *(.sbss*);
+ . = ALIGN(8);
+ } > pibmem
+ _sbss_end = .;
+
+ . = ALIGN(8);
+ _sbss_size = SIZEOF(.sbss);
+
+ . = ALIGN(8);
+ _PK_INITIAL_STACK_LIMIT = .;
+ . = . + INITIAL_STACK_SIZE;
+ _PK_INITIAL_STACK = . - 1;
+ . = ALIGN(8);
+
+}
diff --git a/src/image/p9_sbe.H b/src/image/p9_sbe.H
new file mode 100644
index 00000000..0f5a402b
--- /dev/null
+++ b/src/image/p9_sbe.H
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/p9_sbe.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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_SBE_H
+#define __P9_SBE_H
+
+/// \file p9_sbe.H
+/// \brief A header to be included into all SBE assembler files and C++
+/// hardware procedures that interact with SBE images.
+///
+/// This header #include-s all generally useful headers required for SBE code
+/// development as well as defining other needed facilities. Note that any
+/// sub-includes must be done in an assembler-safe way.
+
+#include "sbe_common.H"
+//#include "p9_scom_addresses.H"
+//#include "p9_istep_num.H"
+
+// The #include of fapiHwpReturnCodes.H must be made here (instead of in
+// sbe_common.H) to guarantee that the P9-local copy is used.
+//#include "fapiHwpReturnCodes.H"
+
+#ifdef __ASSEMBLER__
+
+ // p9_sbe.H 'recursively' inserts itself into any hook code extracted
+ // from an assembly context that includes p9_sbe.H.
+
+ ##`#include "p9_sbe.H"
+
+#endif // __ASSEMBLER__
+
+#endif // __P9_SBE_H
diff --git a/src/image/parsAndCutElf.py b/src/image/parsAndCutElf.py
new file mode 100755
index 00000000..d550b517
--- /dev/null
+++ b/src/image/parsAndCutElf.py
@@ -0,0 +1,69 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/image/parsAndCutElf.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import os
+import subprocess
+import re
+import random
+import sys
+
+# Workaround to cut SBE image from elf image.
+def parserElf():
+ cmd = "readelf -S ../../obj/sbe_seeprom.out"
+ firstSection = ".header"
+ cmd1 = "nm ../../obj/sbe_seeprom.out | grep _sbe_image_size"
+ output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
+ i = 0;
+ for line in output.stdout:
+ line = line.strip()
+
+ if not line: continue
+
+ if( (line.find(firstSection) != -1) ):
+ tokens = line.split();
+ startSize = int( tokens[5], 16 )
+ print startSize
+ break;
+
+ # Get the location of sbe end
+ output = subprocess.Popen(cmd1, shell=True, stdout=subprocess.PIPE)
+ for line in output.stdout:
+ line = line.strip()
+ tokens = line.split();
+ endSize = int( tokens[0], 16 );
+ break;
+
+ print endSize;
+ if( (startSize == 0) or (endSize == 0)):
+ exit(-1)
+
+ # cut the image
+ cmd1 = "dd skip=" + str(startSize) + " count=" + str(endSize) + " if=../../obj/sbe_seeprom.out of=../../obj/sbe_seeprom.bin bs=1"
+ rc = os.system(cmd1)
+ if ( rc ):
+ print "ERROR running %s: %d "%( cmd1, rc )
+ exit(-1)
+
+parserElf()
+
diff --git a/src/image/proc_sbe_fixed.H b/src/image/proc_sbe_fixed.H
new file mode 100644
index 00000000..500e9b3b
--- /dev/null
+++ b/src/image/proc_sbe_fixed.H
@@ -0,0 +1,211 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/proc_sbe_fixed.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file proc_sbe_fixed.H
+/// \brief Define the layout of fixed-position data in the P9 SBE reference
+/// and IPL images
+///
+/// Contains struct ProcSbeFixed which contains functions, rings and
+/// attributes whose pointers are stored in the fixed and fixed_toc section
+///
+/// This file defines the layout of the special .fixed data section of P9 SBE
+/// reference and IPL images. The .fixed section is guaranteed to appear at a
+/// fixed offset from the beginning of the image, containing data required to
+/// be manipulated when images are resident in non-volatile memories, thereby
+/// avoiding having to search the TOC. Data manipulated during in-memory image
+/// processing can always be easily located using the SBE-XIP TOC APIs. All
+/// of the data stored in .fixed can also still be referenced via the SBE-XIP
+/// TOC.
+///
+/// This header file can be #include-ed into either C or SBE assembly language
+/// source code. In C, it creates simple structures 'ProcChipAttributes',
+/// 'PervAttributes', 'CoreAttributes', 'EQAttributes' and 'EXAttributes' that
+/// contain attribute information that are sized per XML definition per entry.
+///
+/// PPE image data is always stored big-endian, so applications on little-endian
+/// hosts will need to perform the appropriate endian converison when reading or
+/// writing images via this header.
+///
+/// In assembler code, this header creates macros '.proc_sbe_fixed_proc_chip',
+/// '.proc_sbe_fixed_perv', '.proc_sbe_fixed_core', '.proc_sbe_fixed_ex',
+/// '.proc_sbe_fixed_eq', that is expanded exactly once in the file
+/// 'sbe_base_header.S', creating the actual data allocation of the data
+/// equivalent to the C structure. Assembler code references the data symbols
+/// as normal.
+///
+/// To simplify programming a 'mini-TOC' is also provided for this data in
+/// the .fixed_toc section. This section is comprised of SbeXipHashedToc
+/// structures. When a symbol is indedxed in .fixed, a blank SbeXipHashedToc
+/// stucture is added to .fixed_toc. During image normalization the array of
+/// SbeXipHashedToc is filled in as each symbol in .fixed is re-indexed into
+/// .fixed_toc.
+
+#ifndef __PROC_SBE_FIXED_H__
+#define __PROC_SBE_FIXED_H__
+
+#include "p9_sbe.H"
+#include "plat_target_parms.H"
+#include "fapi2AttributeIds.H"
+
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_system
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_system_attributes
+G_system_attributes:
+#else
+
+extern "C" {
+namespace fapi2attr {
+typedef struct SystemAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_system.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} SystemAttributes;
+} // fapi2
+} // C
+#endif
+
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_proc_chip
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_proc_chip_attributes
+G_proc_chip_attributes:
+#else
+
+extern "C" {
+namespace fapi2attr {
+typedef struct ProcChipAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_proc_chip.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} ProcChipAttributes;
+} // fapi2
+} // C
+#endif
+
+///
+/// Pervasive Target Attributes
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_perv
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_perv_attributes
+G_perv_attributes:
+#else
+namespace fapi2attr {
+typedef struct PervAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_perv.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} PervAttributes;
+} // fapi2
+#endif
+
+///
+/// Core (EC) Target Attributes
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_core
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_core_attributes
+G_core_attributes:
+#else
+namespace fapi2attr {
+typedef struct CoreAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_core.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} CoreAttributes;
+} // fapi2
+#endif
+
+///
+/// EX Target Attributes
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_ex
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_ex_attributes
+G_ex_attributes:
+#else
+namespace fapi2attr {
+typedef struct EXAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_ex.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} EXAttributes;
+} // fapi2
+#endif
+
+///
+/// EQ Target Attributes
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_eq
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_eq_attributes
+G_eq_attributes:
+#else
+namespace fapi2attr {
+typedef struct EQAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_eq.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} EQAttributes;
+} // fapi2
+#endif
+
+
+#endif // __PROC_SBE_FIXED_H__
diff --git a/src/image/sbe_common.H b/src/image/sbe_common.H
new file mode 100644
index 00000000..c9061354
--- /dev/null
+++ b/src/image/sbe_common.H
@@ -0,0 +1,600 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/sbe_common.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 __SBE_COMMON_H
+#define __SBE_COMMON_H
+
+// $Id: Exp $
+
+/// \file sbe_common.H
+
+/// \brief This header contains #include-s and macro definitions common to P8
+/// and Centaur SBE code development. It is #include-ed into p8_sbe.H and
+/// cen_sbe.H which have other setup specific to each environment.
+
+
+#include "sbe_link.H"
+#include "p9_xip_image.h"
+//#include "sbe_xip_header.H"
+
+/// Macros for generating the .fixed section
+///
+/// The CPP macros PROC_SBE_FIXED_UINT64[_VECTOR] generate equivalent code
+/// depending on whether they are being called from assembler (where they
+/// actually create the .fixed section data) or from C (where they specifiy a
+/// C-structure form of the contents of the .fixed section.
+///
+/// In assembler each invocation also creates space in the .fixed_toc section
+/// for a fixed TOC entry. Unlike the normal TOC no data is generated for
+/// .fixed_toc by the data declaration. Instead, the fixed TOC table is
+/// filled in during image normalization by normalizeToc (p9_xip_image.c)
+/// which requires that there be one and only one fixed TOC entery allocated
+/// per TOC entry referencing the .fixed section. This means that in the
+/// current implementation it is not possible to create .fixed_toc entries
+/// for addresses or for data stored in sections other than .fixed.
+
+#ifdef __ASSEMBLER__
+
+ .macro proc_sbe_fixed_uint8, symbol:req, tnumber=1, elements=1
+ .global \symbol
+\symbol\():
+ .rept ((\tnumber)*(\elements))
+ .byte 0
+ .endr
+
+ .xip_toc \symbol, P9_XIP_UINT8, \symbol, ((\tnumber)*(\elements))
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_int8, symbol:req, tnumber=1, elements=1
+ .global \symbol
+\symbol\():
+ .rept ((\tnumber)*(\elements))
+ .byte 0
+ .endr
+
+ .xip_toc \symbol, P9_XIP_INT8, \symbol, ((\tnumber)*(\elements))
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_uint16, symbol:req, tnumber=1, elements=1
+ .balign 2
+ .global \symbol
+\symbol\():
+
+ .rept ((\tnumber)*(\elements))
+ .byte 0,0
+ .endr
+
+ .xip_toc \symbol, P9_XIP_UINT16, \symbol, ((\tnumber)*(\elements))
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_int16, symbol:req, tnumber=1, elements=1
+ .balign 2
+ .global \symbol
+\symbol\():
+
+ .rept ((\tnumber)*(\elements))
+ .byte 0,0
+ .endr
+
+ .xip_toc \symbol, P9_XIP_INT16, \symbol, ((\tnumber)*(\elements))
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_uint32, symbol:req, tnumber=1, elements=1
+ .balign 4
+ .global \symbol
+\symbol\():
+
+ .rept ((\tnumber)*(\elements))
+ .long 0
+ .endr
+
+ .xip_toc \symbol, P9_XIP_UINT32, \symbol, ((\tnumber)*(\elements))
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_int32, symbol:req, tnumber=1, elements=1
+ .balign 4
+ .global \symbol
+\symbol\():
+
+ .rept ((\tnumber)*(\elements))
+ .long 0
+ .endr
+
+ .xip_toc \symbol, P9_XIP_INT32, \symbol, ((\tnumber)*(\elements))
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_uint64, symbol:req, tnumber=1, elements=1
+ .balign 8
+ .global \symbol
+\symbol\():
+ .rept ((\tnumber)*(\elements))
+ .quad 0
+ .endr
+
+ .xip_toc \symbol, P9_XIP_UINT64, \symbol, ((\tnumber)*(\elements))
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_int64, symbol:req, tnumber=1, elements=1
+ .balign 8
+ .global \symbol
+\symbol\():
+ .rept ((\tnumber)*(\elements))
+ .quad 0
+ .endr
+
+ .xip_toc \symbol, P9_XIP_INT64, \symbol, ((\tnumber)*(\elements))
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_quadia, symbol:req, space:req, address:req
+ .global \symbol
+\symbol\():
+ .quadia (\space), (\address)
+
+ .xip_toc \symbol, P9_XIP_UINT64, \symbol
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+
+#define PROC_SBE_FIXED_UINT8(symbol) \
+ proc_sbe_fixed_uint8 symbol
+
+#define PROC_SBE_FIXED_INT8(symbol) \
+ proc_sbe_fixed_int8 symbol
+
+#define PROC_SBE_FIXED_UINT16(symbol) \
+ proc_sbe_fixed_uint16 symbol
+
+#define PROC_SBE_FIXED_INT16(symbol) \
+ proc_sbe_fixed_int16 symbol
+
+#define PROC_SBE_FIXED_UINT32(symbol) \
+ proc_sbe_fixed_uint32 symbol
+
+#define PROC_SBE_FIXED_INT32(symbol) \
+ proc_sbe_fixed_int32 symbol
+
+#define PROC_SBE_FIXED_UINT64(symbol) \
+ proc_sbe_fixed_uint64 symbol
+
+#define PROC_SBE_FIXED_INT64(symbol) \
+ proc_sbe_fixed_int64 symbol
+
+#define PROC_SBE_FIXED_UINT8_VECTOR(symbol, elements) \
+ proc_sbe_fixed_uint8 symbol, 1, elements
+
+#define PROC_SBE_FIXED_INT8_VECTOR(symbol, elements) \
+ proc_sbe_fixed_int8 symbol, 1, elements
+
+#define PROC_SBE_FIXED_UINT16_VECTOR(symbol, elements) \
+ proc_sbe_fixed_uint16 symbol, 1, elements
+
+#define PROC_SBE_FIXED_INT16_VECTOR(symbol, elements) \
+ proc_sbe_fixed_int16 symbol, 1, elements
+
+#define PROC_SBE_FIXED_UINT32_VECTOR(symbol, elements) \
+ proc_sbe_fixed_uint32 symbol, 1, elements
+
+#define PROC_SBE_FIXED_INT32_VECTOR(symbol, elements) \
+ proc_sbe_fixed_int32 symbol, 1, elements
+
+#define PROC_SBE_FIXED_UINT64_VECTOR(symbol, elements) \
+ proc_sbe_fixed_uint64 symbol, 1, elements
+
+#define PROC_SBE_FIXED_INT64_VECTOR(symbol, elements) \
+ proc_sbe_fixed_int64 symbol, 1, elements
+
+#define PROC_SBE_FIXED_UINT8_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_uint8 symbol, 1, dim1 * dim2
+
+#define PROC_SBE_FIXED_INT8_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_int8 symbol, 1, dim1 * dim2
+
+#define PROC_SBE_FIXED_UINT16_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_uint16 symbol, 1, dim1 * dim2
+
+#define PROC_SBE_FIXED_INT16_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_int16 symbol, 1, dim1 * dim2
+
+#define PROC_SBE_FIXED_UINT32_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_uint32 symbol, 1, dim1 * dim2
+
+#define PROC_SBE_FIXED_INT32_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_int32 symbol, 1, dim1 * dim2
+
+#define PROC_SBE_FIXED_UINT64_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_uint64 symbol, 1, dim1 * dim2
+
+#define PROC_SBE_FIXED_INT64_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_int64 symbol, 1, dim1 * dim2
+
+#define PROC_SBE_FIXED_UINT8_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint8 symbol, 1, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_INT8_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint8 symbol, 1, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_UINT16_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint16 symbol, 1, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_INT16_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint16 symbol, 1, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_UINT32_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint32 symbol, 1, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_INT32_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint32 symbol, 1, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_UINT64_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint64 symbol, 1, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_INT64_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint64 symbol, 1, dim1 * dim2 * dim3
+
+// Non-Chip Target Attributes
+
+#define PROC_SBE_FIXED_TARGET_UINT8(symbol, tnumber) \
+ proc_sbe_fixed_uint8 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_INT8(symbol, tnumber) \
+ proc_sbe_fixed_int8 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_UINT16(symbol, tnumber) \
+ proc_sbe_fixed_uint16 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_INT16(symbol, tnumber) \
+ proc_sbe_fixed_int16 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_UINT32(symbol, tnumber) \
+ proc_sbe_fixed_uint32 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_INT32(symbol, tnumber) \
+ proc_sbe_fixed_int32 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_UINT64(symbol, tnumber) \
+ proc_sbe_fixed_uint64 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_INT64(symbol, tnumber) \
+ proc_sbe_fixed_int64 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_uint8 symbol, tnumber, elements
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_int8 symbol, tnumber, elements
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_uint16 symbol, tnumber, elements
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_int16 symbol, tnumber, elements
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_uint32 symbol, tnumber, elements
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_int32 symbol, tnumber, elements
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_uint64 symbol, tnumber, elements
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_int64 symbol, tnumber, elements
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_uint8 symbol, tnumber, dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_int8 symbol, tnumber, dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_uint16 symbol, tnumber, dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_int16 symbol, tnumber, dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_uint32 symbol, tnumber, dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_int32 symbol, tnumber, dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_uint64 symbol, tnumber, dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_int64 symbol, tnumber, dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint8 symbol, tnumber, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint8 symbol, tnumber, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint16 symbol, tnumber, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint16 symbol, tnumber, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint32 symbol, tnumber, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint32 symbol, tnumber, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint64 symbol, tnumber, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint64 symbol, tnumber, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_QUADIA(symbol, space, address) \
+ proc_sbe_fixed_quadia symbol, (space), (address)
+
+
+#else // __ASSEMBLER__ (eg the C portion)
+
+#define PROC_SBE_FIXED_UINT8(symbol) \
+ uint8_t symbol
+
+#define PROC_SBE_FIXED_INT8(symbol) \
+ int8_t symbol
+
+#define PROC_SBE_FIXED_UINT16(symbol) \
+ uint16_t symbol
+
+#define PROC_SBE_FIXED_INT16(symbol) \
+ int16_t symbol
+
+#define PROC_SBE_FIXED_UINT32(symbol) \
+ uint32_t symbol
+
+#define PROC_SBE_FIXED_INT32(symbol) \
+ int32_t symbol
+
+#define PROC_SBE_FIXED_UINT64(symbol) \
+ uint64_t symbol
+
+#define PROC_SBE_FIXED_INT64(symbol) \
+ int64_t symbol
+
+#define PROC_SBE_FIXED_UINT8_VECTOR(symbol, elements) \
+ uint8_t symbol[elements]
+
+#define PROC_SBE_FIXED_INT8_VECTOR(symbol, elements) \
+ int8_t symbol[elements]
+
+#define PROC_SBE_FIXED_UINT16_VECTOR(symbol, elements) \
+ uint16_t symbol[elements]
+
+#define PROC_SBE_FIXED_INT16_VECTOR(symbol, elements) \
+ int16_t symbol[elements]
+
+#define PROC_SBE_FIXED_UINT32_VECTOR(symbol, elements) \
+ uint32_t symbol[elements]
+
+#define PROC_SBE_FIXED_INT32_VECTOR(symbol, elements) \
+ int32_t symbol[elements]
+
+#define PROC_SBE_FIXED_UINT64_VECTOR(symbol, elements) \
+ uint64_t symbol[elements]
+
+#define PROC_SBE_FIXED_INT64_VECTOR(symbol, elements) \
+ int64_t symbol[elements]
+
+#define PROC_SBE_FIXED_UINT8_VECTOR_2(symbol, dim1, dim2 ) \
+ uint8_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_INT8_VECTOR_2(symbol, dim1, dim2 ) \
+ int8_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_UINT16_VECTOR_2(symbol, dim1, dim2 ) \
+ uint16_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_INT16_VECTOR_2(symbol, dim1, dim2 ) \
+ int16_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_UINT32_VECTOR_2(symbol, dim1, dim2 ) \
+ uint32_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_INT32_VECTOR_2(symbol, dim1, dim2 ) \
+ int32_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_UINT64_VECTOR_2(symbol, dim1, dim2 ) \
+ uint64_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_INT64_VECTOR_2(symbol, dim1, dim2 ) \
+ int64_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_UINT8_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ uint8_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_INT8_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ int8_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_UINT16_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ uint16_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_INT16_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ int16_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_UINT32_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ uint32_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_INT32_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ int32_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_UINT64_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ uint64_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_INT64_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ int64_t symbol[dim1][dim2][dim3]
+
+// Non-Chip Target Attributes
+
+#define PROC_SBE_FIXED_TARGET_UINT8(symbol, tnumber) \
+ uint8_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_INT8(symbol, tnumber) \
+ int8_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_UINT16(symbol, tnumber) \
+ uint16_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_INT16(symbol, tnumber) \
+ int16_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_UINT32(symbol, tnumber) \
+ uint32_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_INT32(symbol, tnumber) \
+ int32_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_UINT64(symbol, tnumber) \
+ uint64_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_INT64(symbol, tnumber) \
+ int64_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR(symbol, tnumber, elements) \
+ uint8_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR(symbol, tnumber, elements) \
+ int8_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR(symbol, tnumber, elements) \
+ uint16_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR(symbol, tnumber, elements) \
+ int16_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR(symbol, tnumber, elements) \
+ uint32_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR(symbol, tnumber, elements) \
+ int32_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR(symbol, tnumber, elements) \
+ uint64_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR(symbol, tnumber, elements) \
+ int64_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ uint8_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ int8_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ uint16_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ int16_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ uint32_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ int32_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ uint64_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ int64_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ uint8_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ int8_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ uint16_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ int16_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ uint32_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ int32_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ uint64_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ int64_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_QUADIA(symbol, space, address) uint64_t symbol
+
+#endif // __ASSEMBLER__
+
+#endif // __SBE_COMMON_H
diff --git a/src/image/sbe_link.H b/src/image/sbe_link.H
new file mode 100644
index 00000000..6efcc753
--- /dev/null
+++ b/src/image/sbe_link.H
@@ -0,0 +1,102 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/image/sbe_link.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 __SBE_LINK_H
+#define __SBE_LINK_H
+
+// $Id: Exp $
+
+/// \file sbe_link.H
+/// \brief Constants required for linking SBE code images
+///
+/// This header contains those cpp manifest constants required for processing
+/// the linker scripts used to generate SBE code images. They may also be
+/// useful for PPE assembler programming so they are included in sbe.H as
+/// well.
+///
+/// The link address of OTPROM code as a byte-address
+///
+/// The OTPROM can be addressed both as an I2C slave and as a direct PIB
+/// slave. The I2C slave is at PIB local address 0x0 and the PIB memory
+/// interface is at local address 0x8000. SBE/IPL uses the PIB addressing
+/// mode, so the OTPROM image is linked at 0x40000 (the byte-address
+/// equivalent of 0x8000).
+#define OTPROM_ORIGIN 0xC0000
+
+/// The amount of memory contained in each OTPROM macro
+#define OTPROM_BLOCK_SIZE 1024
+
+/// The amount of memory reserved for OTPROM code
+///
+/// This amount is exclusive of physical OTPROM memory reserved for compressed
+/// scan ring images.
+#define OTPROM_CODE_SIZE (1 * OTPROM_BLOCK_SIZE)
+
+/// The link address of the P9 SBE Base image
+#define SBE_BASE_ORIGIN 0xFFFE8000
+/// SBE base image length ( 96 KB - 512 bytes for loader)
+#define SBE_BASE_LENGTH 0x17DFF
+
+///This Index depends upon XIP HEADER File
+// Start offset of sectionTable in XIP header. There are 8 entries
+// of 8 byte each.
+#define SBE_XIP_TOC_OFFSET 8*8
+
+/// The link address of the P9 SBE Base image
+#define SBE_SEEPROM_BASE_ORIGIN 0x80000000
+
+/// This Index depends upon XIP HEADER File
+/// Each section table entry is 12 bytes(SIZE_OF_SBE_XIP_SECTION) size,
+// Base Loader is 10 th (P9_XIP_SECTION_BASELOADER) section
+#define SBE_LOADER_BASE_SECTION SBE_SEEPROM_BASE_ORIGIN + SBE_XIP_TOC_OFFSET \
+ + 120
+// Base Loader start address
+#define SBE_LOADER_BASE_ORIGIN 0xFFFFFE00
+// Base Loader length
+#define SBE_LOADER_BASE_LENGTH 0x200
+
+// Base Loader entry function offset in header
+#define SBE_LOADER_ENTRY_HEADER_OFFSET 20
+
+/// The physical address offset where SBE-SEEPROM code is loaded
+///
+/// This address *must* be a constant known to the OTPROM code.
+#define SBE_SEEPROM_LOAD_ADDRESS 0x2000
+
+/// The offset (in bytes) of the .fixed section in P9 SBE-XIP images
+#define SBE_XIP_FIXED_OFFSET 512
+
+/// The link address of the PIBMEM image
+#define PIBMEM_ORIGIN 0
+
+/// The amount of space available in the PIBMEM, in bytes (96KB)
+#define PIBMEM_SIZE (96 * 1024)
+
+/// The fixed section of Otprom
+#define OTPROM_FIXED_SIZE (OTPROM_ORIGIN + 0x340)
+
+/// Sbe fixed sction for the pibmem repair
+#define SBE_FIXED_SECTION (SBE_SEEPROM_BASE_ORIGIN + SBE_XIP_TOC_OFFSET + 12)
+
+#endif // __SBE_LINK_H
+
diff --git a/src/image/topfiles.mk b/src/image/topfiles.mk
new file mode 100644
index 00000000..1f04d000
--- /dev/null
+++ b/src/image/topfiles.mk
@@ -0,0 +1,53 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/image/topfiles.mk $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+TOP-C-SOURCES =
+TOP-CPP-SOURCES =
+TOP-S-SOURCES = base_ppe_header.S
+
+# generated by ppeParseProcSbeFixed.pl
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_system.H
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_perv.H
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_proc_chip.H
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_core.H
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_ex.H
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_eq.H
+
+TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-CPP-SOURCES:.C=.o) $(TOP-S-SOURCES:.S=.o)
+PLAT_FAPI2_DIR_INCL = $(PLAT_FAPI2_DIR)/include
+# generated by ppeParseAttributeInfo.pl
+GEN-PARSEATTRIBUTEINFO += $(PLAT_FAPI2_DIR_INCL)/fapi2AttributeIds.H
+GEN-PARSEATTRIBUTEINFO += $(PLAT_FAPI2_DIR_INCL)/fapi2ChipEcFeature.C
+GEN-PARSEATTRIBUTEINFO += $(PLAT_FAPI2_DIR_INCL)/fapi2AttributePlatCheck.H
+GEN-PARSEATTRIBUTEINFO += $(PLAT_FAPI2_DIR_INCL)/fapi2AttributesSupported.html
+GEN-PARSEATTRIBUTEINFO += $(PLAT_FAPI2_DIR_INCL)/fapi2AttrInfo.csv
+GEN-PARSEATTRIBUTEINFO += $(PLAT_FAPI2_DIR_INCL)/fapi2AttrEnumInfo.csv
+
+PPE_FAPI2_DIR_SRC = $(PLAT_FAPI2_DIR)/src
+# generated by ppeCreateAttrGetSetMacros.pl
+GEN-CREATEATTRGETSETMACROS += fapi2PlatAttributeService.H.temp
+GEN-CREATEATTRGETSETMACROS += $(PPE_FAPI2_DIR_SRC)/fapi2PlatAttributeService.C
+GEN-CREATEATTRGETSETMACROS += $(PLAT_FAPI2_DIR_INCL)/fapi2PlatAttributeService.H
+
+# generated by ppeCreateIfAttrService.pl
+GEN-CREATEIFATTRSERVICE += $(PLAT_FAPI2_DIR_INCL)/fapi2AttributeService.C
diff --git a/src/sample/Makefile b/src/sample/Makefile
new file mode 100644
index 00000000..4d02b37e
--- /dev/null
+++ b/src/sample/Makefile
@@ -0,0 +1,99 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/sample/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+#remove this once we have a real compiler
+export P2P_ENABLE = 1
+
+#Pull in the definitions that affect all makefiles for this image
+include img_defs.mk
+
+#Pull in object file names for the top directory
+include topfiles.mk
+
+ifdef P2P_ENABLE
+include $(P2P_SRCDIR)/p2pfiles.mk
+endif
+
+PK_MAKE_DIR := $(PK_SRCDIR)/$(PPE_TYPE)
+OBJS := $(addprefix $(OBJDIR)/, $(TOP_OBJECTS))
+PKLIB := $(OBJDIR)/pk/libpk.a
+
+LIB_DIRS = -L$(OBJDIR)/pk #-L$(OBJDIR)/commonlib
+LINK_OBJS = $(OBJS) $(PKLIB) #$(COMMONLIB)
+LINK_SCRIPT = $(addprefix $(OBJDIR)/, linkscript)
+
+ifdef P2P_ENABLE
+P2PLIB := $(OBJDIR)/p2p/libp2p.a
+LIB_DIRS += -L$(OBJDIR)/p2p
+LINK_OBJS += $(P2PLIB)
+endif
+
+#default target is to make a binary application image
+#This removes all unecessary headers from the ELF executable
+$(OBJDIR)/$(IMAGE_NAME).bin $(OBJDIR)/$(IMAGE_NAME).dis: $(OBJDIR)/$(IMAGE_NAME).out
+ $(OBJCOPY) -O binary $< $(OBJDIR)/$(IMAGE_NAME).bin
+ $(OBJDUMP) -S $< > $(OBJDIR)/$(IMAGE_NAME).dis
+
+#create a linked ELF executable
+$(OBJDIR)/$(IMAGE_NAME).out: $(LINK_OBJS) $(LINK_SCRIPT)
+ $(LD) -e __system_reset -T$(LINK_SCRIPT) -Map $(OBJDIR)/$(IMAGE_NAME).map -Bstatic -o $(OBJDIR)/$(IMAGE_NAME).out $(LIB_DIRS) $(OBJS) -lpk -lp2p #-lcommon
+
+#pass the link command file through the C preprocessor to evaluate macros and remove comments
+$(LINK_SCRIPT): link.cmd
+ $(CPP) -E -x c++ -P $(DEFS) link.cmd -o $(LINK_SCRIPT)
+
+#Create an obj directory if needed
+$(LINK_OBJS) $(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+.PHONY: clean $(PKLIB) $(P2PLIB)
+
+#Build macro-specific kernel code
+$(PKLIB):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(PK_MAKE_DIR)
+
+#Build the code that is common for all processors (PPEs and 405)
+#$(COMMONLIB):
+# $(MAKE) -I $(IMAGE_SRCDIR) -C $(COMMONLIB_SRCDIR)
+
+ifdef P2P_ENABLE
+$(P2PLIB):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(P2P_SRCDIR)
+endif
+
+# collect all of the trace hash files for this image into a single trexStringFile
+.PHONY : tracehash
+tracehash:
+ mkdir -p $(OBJDIR)
+ $(THASH) -c -d $(OBJDIR) -s $(OBJDIR)/trexStringFile
+
+#clean the kernel directory first, then the application level clean
+clean:
+ rm -fr $(OBJDIR)
+
+#Add dependencies to header files
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/sample/img_defs.mk b/src/sample/img_defs.mk
new file mode 100644
index 00000000..8b4685cc
--- /dev/null
+++ b/src/sample/img_defs.mk
@@ -0,0 +1,264 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/sample/img_defs.mk $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+# Make header for GPE PK builds
+#
+# The application may define the following variables to control the
+# build process:
+#
+# IMG_INCLUDES : Aplication-specific header search paths
+#
+# DEFS : A string of -D<symbol>[=<value>] to control compilation
+#
+# PK : Default ..; The path to the PK source code.
+# The default is set for building the PK
+# subdirectories.
+#
+# PK_THREAD_SUPPORT : (0/1, default 1); Compile PK thread and
+# semaphore suppprt
+#
+# PK_TIMER_SUPPORT : (0/1, default 1); Compile PK timer suppprt
+#
+# SIMICS_ENVIRONMENT : (0/1, current default 0); Compile for Simics
+#
+# SIMICS_MAGIC_PANIC : (0/1, current default 0); Use Simics Magic
+# breakpoint for PK_PANIC() instead of PowerPC trap.
+# Note that Simics does not model trap correctly in
+# external debug mode.
+#
+# GCC-O-LEVEL : The optimization level passed to GCC (default -Os). May
+# also be defined empty (GCC-O-LEVEL=) to disable
+# optimization. This variable can also be used to pass
+# any other non-default setting to GCC, e.g.
+# make GCC-O-LEVEL="-Os -fno-branch-count-reg"
+#
+# GCC-TOOL-PREFIX : The full path (including executable file prefixes) to
+# the GCC cross-development tools to use. The default is
+# "ppcnf-mcp5-"
+#
+# CTEPATH : This variable defaults to the afs/awd CTE tool
+# installation - The PORE binutils are stored there. If
+# you are not in Austin be sure to define CTEPATH in
+# your .profile.
+#
+# OBJDIR : target directory for all generated files
+
+IMAGE_NAME := sample_ppe
+
+PPE_TYPE := ppe
+
+ifndef IMAGE_SRCDIR
+export IMAGE_SRCDIR = $(abspath .)
+endif
+
+ifndef IMG_INCLUDES
+export IMG_INCLUDES = -I$(IMAGE_SRCDIR)
+endif
+
+ifndef BASE_OBJDIR
+export BASE_OBJDIR = $(abspath ../../../obj)
+endif
+
+export IMG_OBJDIR = $(BASE_OBJDIR)/$(IMAGE_NAME)
+
+ifndef PK_SRCDIR
+export PK_SRCDIR = $(abspath ../../pk)
+endif
+
+ifndef GCC-TOOL-PREFIX
+#GCC-TOOL-PREFIX = $(CTEPATH)/tools/ppcgcc/prod/bin/powerpc-linux-
+GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/output/host/usr/bin/powerpc64-linux-
+#GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/buildroot/output/host/usr/bin/powerpc-linux-
+#GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/output/host/usr/powerpc64-buildroot-linux-gnu/bin/
+#GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/opcustom/op-build/buildroot/output/host/usr/bin/powerpc-linux-
+endif
+
+ifndef BINUTILS-TOOL-PREFIX
+BINUTILS-TOOL-PREFIX = $(CTEPATH)/tools/ppetools/prod/powerpc-eabi/bin/
+endif
+
+ifndef P2P_SRCDIR
+export P2P_SRCDIR = $(abspath ../../tools/PowerPCtoPPE)
+endif
+
+ifndef PPETRACEPP_DIR
+export PPETRACEPP_DIR = $(abspath ../../tools/ppetracepp)
+endif
+
+OBJDIR = $(BASE_OBJDIR)$(SUB_OBJDIR)
+
+
+CC_ASM = $(GCC-TOOL-PREFIX)gcc
+TCC = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+CC = $(GCC-TOOL-PREFIX)gcc
+AS = $(BINUTILS-TOOL-PREFIX)as
+AR = $(BINUTILS-TOOL-PREFIX)ar
+LD = $(BINUTILS-TOOL-PREFIX)ld
+OBJDUMP = $(BINUTILS-TOOL-PREFIX)objdump
+OBJCOPY = $(BINUTILS-TOOL-PREFIX)objcopy
+TCPP = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+THASH = $(PPETRACEPP_DIR)/tracehash.pl
+CPP = $(GCC-TOOL-PREFIX)gcc
+
+ifdef P2P_ENABLE
+PCP = $(P2P_SRCDIR)/ppc-ppe-pcp.py
+endif
+
+
+ifndef CTEPATH
+$(warning The CTEPATH variable is not defined; Defaulting to /afs/awd)
+export CTEPATH = /afs/awd/projects/cte
+endif
+
+ifeq "$(PK_TIMER_SUPPORT)" ""
+PK_TIMER_SUPPORT = 1
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" ""
+PK_THREAD_SUPPORT = 1
+endif
+
+ifeq "$(PK_TRACE_SUPPORT)" ""
+PK_TRACE_SUPPORT = 1
+endif
+
+# Generate a 16bit trace string hash prefix value based on the name of this image. This will form
+# the upper 16 bits of the 32 bit trace hash values.
+ifndef PK_TRACE_HASH_PREFIX
+PK_TRACE_HASH_PREFIX := $(shell echo $(IMAGE_NAME) | md5sum | cut -c1-4 | xargs -i printf "%d" 0x{})
+endif
+
+
+ifndef GCC-O-LEVEL
+#GCC-O-LEVEL = -Os
+GCC-O-LEVEL = -O -g
+endif
+
+GCC-DEFS += -DIMAGE_NAME=$(IMAGE_NAME)
+GCC-DEFS += -DPK_TIMER_SUPPORT=$(PK_TIMER_SUPPORT)
+GCC-DEFS += -DPK_THREAD_SUPPORT=$(PK_THREAD_SUPPORT)
+GCC-DEFS += -DPK_TRACE_SUPPORT=$(PK_TRACE_SUPPORT)
+GCC-DEFS += -DPK_TRACE_HASH_PREFIX=$(PK_TRACE_HASH_PREFIX)
+GCC-DEFS += -D__PK__=1
+DEFS += $(GCC-DEFS)
+
+############################################################################
+
+INCLUDES += $(IMG_INCLUDES) \
+ -I$(PK_SRCDIR)/kernel -I$(PK_SRCDIR)/ppe42 -I$(PK_SRCDIR)/trace \
+ -I$(PK_SRCDIR)/$(PPE_TYPE) -I$(PK_SRCDIR)/../include \
+ -I$(PK_SRCDIR)/../tools/ppetracepp
+
+PIPE-CFLAGS = -pipe -Wa,-m405
+
+GCC-CFLAGS += -Wall -fsigned-char -msoft-float \
+ -mcpu=405 -m32 -mmulhw -mmultiple \
+ -meabi -msdata=eabi \
+ -ffreestanding -fno-common -Werror \
+ -fno-inline-functions-called-once \
+ -ffixed-r11 -ffixed-r12 \
+ -ffixed-r14 -ffixed-r15 -ffixed-r16 -ffixed-r17 \
+ -ffixed-r18 -ffixed-r19 -ffixed-r20 -ffixed-r21 \
+ -ffixed-r22 -ffixed-r23 -ffixed-r24 -ffixed-r25 \
+ -ffixed-r26 -ffixed-r27 \
+ -ffixed-cr1 -ffixed-cr2 -ffixed-cr3 -ffixed-cr4 \
+ -ffixed-cr5 -ffixed-cr6 -ffixed-cr7 #-lstdc++
+
+
+CFLAGS = -c $(GCC-CFLAGS) $(PIPE-CFLAGS) $(GCC-O-LEVEL) $(INCLUDES)
+
+CPPFLAGS = -E
+
+ASFLAGS = -mppe42
+
+ifdef P2P_ENABLE
+#use this to disable optimizations (fused compare/branch etc.)
+PCP-FLAG =
+
+#use this to enable optimizations
+#PCP-FLAG =
+endif
+############################################################################
+
+#override the GNU Make implicit rule for going from a .C to a .o
+%.o: %.C
+
+$(OBJDIR)/%.s: %.C
+ $(TCC) $(CFLAGS) $(DEFS) -S -o $@ $<
+
+
+#override the GNU Make implicit rule for going from a .c to a .o
+%.o: %.c
+
+$(OBJDIR)/%.s: %.c
+ $(TCC) $(CFLAGS) $(DEFS) -S -o $@ $<
+
+#override the GNU Make implicit rule for going from a .S to a .o
+%.o: %.S
+
+$(OBJDIR)/%.s: %.S
+ $(TCPP) $(CFLAGS) $(DEFS) $(CPPFLAGS) -o $@ $<
+.PRECIOUS: $(OBJDIR)/%.s
+
+ifndef P2P_ENABLE
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.s
+ $(AS) $(ASFLAGS) -o $@ $<
+
+else
+
+$(OBJDIR)/%.es: $(OBJDIR)/%.s
+ $(PCP) $(PCP-FLAG) -f $<
+.PRECIOUS: $(OBJDIR)/%.es
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.es
+ $(AS) $(ASFLAGS) -o $@ $<
+
+endif
+
+# From the GNU 'Make' manual - these scripts uses the preprocessor to
+# create dependency files (*.d), then mungs them slightly to make them
+# work as Make targets. The *.d files are include-ed in the
+# subdirectory Makefiles.
+
+$(OBJDIR)/%.d: %.C
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.c
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.S
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
diff --git a/src/sample/link.cmd b/src/sample/link.cmd
new file mode 100644
index 00000000..1037564b
--- /dev/null
+++ b/src/sample/link.cmd
@@ -0,0 +1,91 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sample/link.cmd $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+
+// Need to do this so that elf32-powerpc is not modified!
+#undef powerpc
+
+#ifndef INITIAL_STACK_SIZE
+#define INITIAL_STACK_SIZE 256
+#endif
+
+OUTPUT_FORMAT(elf32-powerpc);
+
+MEMORY
+{
+ sram : ORIGIN = 0xFFF40000, LENGTH = 0xc0000
+}
+
+SECTIONS
+{
+ . = 0xfff40000;
+ .text : {. = ALIGN(512); *(.vectors) *(.text)} > sram
+
+ ////////////////////////////////
+ // Read-only Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _RODATA_SECTION_BASE = .;
+
+ // SDA2 constant sections .sdata2 and .sbss2 must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA2_BASE_ = .;
+ .sdata2 . : { *(.sdata2) } > sram
+ .sbss2 . : { *(.sbss2) } > sram
+
+ // Other read-only data.
+
+ .rodata . : { *(.rodata*) *(.got2) } > sram
+
+ _RODATA_SECTION_SIZE = . - _RODATA_SECTION_BASE;
+
+ ////////////////////////////////
+ // Read-write Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _DATA_SECTION_BASE = .;
+
+ // SDA sections .sdata and .sbss must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA_BASE_ = .;
+ .sdata . : { *(.sdata) } > sram
+ .sbss . : { *(.sbss) } > sram
+
+ // Other read-write data
+ // It's not clear why boot.S is generating empty .glink,.iplt
+
+ .rela . : { *(.rela*) } > sram
+ .rwdata . : { *(.data) *(.bss) } > sram
+// .iplt . : { *(.iplt) } > sram
+
+ _PK_INITIAL_STACK_LIMIT = .;
+ . = . + INITIAL_STACK_SIZE;
+ _PK_INITIAL_STACK = . - 1;
+
+}
diff --git a/src/sample/pk_scom.c b/src/sample/pk_scom.c
new file mode 100644
index 00000000..5b200566
--- /dev/null
+++ b/src/sample/pk_scom.c
@@ -0,0 +1,235 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sample/pk_scom.c $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_scom.c
+/// \brief Lowest level SCOM definitions.
+///
+/// A fapi-level SCOM should call these functions.
+///
+/// Todo:
+/// - Poll PCB master for SCOM completion.
+/// - Return error code of SCOM fails.
+/// - Return error code if SCOM input parms violate rules.
+
+#include "pk.h"
+#include "pk_scom.h"
+
+uint32_t putscom( uint32_t i_chiplet_id, uint32_t i_address, uint64_t i_data)
+{
+ uint32_t l_cid=0;
+
+ // CMO-Declaring variables tied to specific registers enables us to protect
+ // the SCOM data and address variables used in the new stvd and lvd 64-bit
+ // data instructions. This protection is needed since the new instructions
+ // are not yet properly considered by the compiler.
+ // l_dataH is used to represent the "beginning" of the 64-bit data in d8
+ // (i.e., r8+r9).
+ uint32_t register l_dataH asm("r8")=0;
+ uint32_t register l_dataL asm("r9")=0;
+ uint32_t register l_addr_eff asm("r10")=0;
+ uint32_t register l_scratch asm("r31")=0;
+
+ if (i_chiplet_id)
+ {
+ // Accommodate two different ways of supplying the chiplet ID:
+ // 0xNN000000: Only bits in high-order two nibbles : Valid
+ // 0x000000NN: Only bits in low-order two nibbles : Valid
+ //
+ if ((i_chiplet_id & 0xFF000000) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in high-order two nibbles.
+ l_cid = i_chiplet_id;
+ }
+ else if ((i_chiplet_id & 0x000000FF) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in low-order two nibbles. Convert to high-order.
+ l_cid = i_chiplet_id << 24;
+ }
+ else
+ {
+ // Invalid: Invalid type of chiplet ID
+ PK_TRACE("putscom() : Invalid value of i_chiplet_id (=0x%08X)",i_chiplet_id);
+ return 1; //CMO-improve Return sensible rc here.
+ }
+
+ l_addr_eff = (i_address & 0x00FFFFFF) | l_cid;
+ }
+ else
+ {
+ // Chiplet ID is zero. Accept address as is.
+ // This is useful for PIB addresses and non-EX chiplets, and even for
+ // EX chiplets if the fully qualified EX chiplet addr is already known.
+ l_addr_eff = i_address;
+
+ }
+
+ l_dataH = (uint32_t)(i_data>>32);
+ l_dataL = (uint32_t)(i_data);
+
+ // CMO-The following sequence forces usage of l_dataH/L and l_addr_eff
+ // and thus the population of them as well.
+ // Further note that unless l_dataH/L are placed right before the following
+ // sequence, more specifically, if they're placed at the top of putscom(),
+ // r8, or l_dataH, might be overwritten in the if(chiplet_id) section.
+ // Secondly, we test l_addr_eff for non-zero through the CR0 register
+ // (which was populated in the "mr." instruction.) This is to convince the
+ // compiler that we actually used l_addr_eff for something.
+ // At present the test result causes no action except to execute the stvd
+ // instruction in either case.
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_dataH) );
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_dataL) );
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_addr_eff) );
+ asm volatile ( \
+ "beq 0x4 \n" );
+
+
+/* asm volatile ( \
+ "stw %[data], 0(%[effective_address]) \n" \
+ : [data]"=r"(l_dataH) \
+ : [effective_address]"r"(l_addr_eff) );
+*/
+ // CMO-This instruction is not fully supported by the compiler (as of
+ // 20150108):
+ // - Correct: It is correctly translated into the proper OP code
+ // format.
+ // - Incorrect: The compiler does not seem to recognize the usage
+ // of the two l_xyz variables in that it doesn't
+ // know prior to this command that the registers that
+ // contain the values of l_xyz need to be protected
+ // up to this point. Thus, we are forced to use those
+ // two l_xyz variables in some dummy instructions just
+ // before this point in order to protect them.
+ asm volatile ( \
+ "stvd %[data], 0(%[effective_address]) \n" \
+ : [data]"=r"(l_dataH) \
+ : [effective_address]"r"(l_addr_eff) );
+
+ // CMO-TBD
+ // Check PIB response code in 0x00001007(17:19)
+ // Translate PIB rc to PK rc
+ // Does this rc get reset to zero on success?
+ // Do we need to check this rc prior to issuing the SCOM?
+
+ return 0;
+}
+
+
+uint32_t getscom( uint32_t i_chiplet_id, uint32_t i_address, uint64_t *o_data)
+{
+ uint32_t l_cid=0;
+
+ // CMO-Declaring variables tied to specific registers enables us to protect
+ // the SCOM data and address variables used in the new stvd and lvd 64-bit
+ // data instructions. This protection is needed since the new instructions
+ // are not yet properly considered by the compiler.
+ // l_dataH is used to represent the "beginning" of the 64-bit data in d8
+ // (i.e., r8+r9).
+ uint32_t register l_dataH asm("r8")=0;
+ uint32_t register l_dataL asm("r9")=0;
+ uint32_t register l_addr_eff asm("r10")=0;
+ uint32_t register l_scratch asm("r31")=0;
+
+ if (i_chiplet_id)
+ {
+ // Accommodate two different ways of supplying the chiplet ID:
+ // 0xNN000000: Only bits in high-order two nibbles : Valid
+ // 0x000000NN: Only bits in low-order two nibbles : Valid
+ //
+ if ((i_chiplet_id & 0xFF000000) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in high-order two nibbles.
+ l_cid = i_chiplet_id;
+ }
+ else if ((i_chiplet_id & 0x000000FF) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in low-order two nibbles. Convert to high-order.
+ l_cid = i_chiplet_id << 24;
+ }
+ else
+ {
+ // Invalid: Invalid type of chiplet ID
+ PK_TRACE("getscom() : Invalid value of i_chiplet_id (=0x%08X)",i_chiplet_id);
+ return 1; //CMO-improve Return sensible rc here.
+ }
+
+ l_addr_eff = (i_address & 0x00FFFFFF) | l_cid;
+ }
+ else
+ {
+ // Chiplet ID is zero. Accept address as is.
+ // This is useful for PIB addresses and non-EX chiplets, and even for
+ // EX chiplets if the fully qualified EX chiplet addr is already known.
+ l_addr_eff = i_address;
+ }
+
+ // CMO-The following sequence forces usage of l_addr_eff and thus the
+ // population of it as well.
+ // Secondly, we test l_addr_eff for non-zero through the CR0 register
+ // (which was populated in the "mr." instruction.) This is to convince the
+ // compiler that we actually used l_addr_eff for something.
+ // At present the test result causes no action except to execute the lvd
+ // instruction in either case.
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_addr_eff) );
+ asm volatile ( \
+ "beq 0x4 \n" );
+
+ asm volatile ( \
+ "lvd %[data], 0(%[effective_address]) \n" \
+ : [data]"=r"(l_dataH) \
+ : [effective_address]"r"(l_addr_eff) );
+
+ // CMO-The following sequence moves the read data, in l_dataH/L, into the
+ // 64-bit o_data location.
+ asm volatile ( \
+ "stw %0, 0(%1) \n" \
+ : "=r"(l_dataH) \
+ : "r"(o_data) );
+ asm volatile ( \
+ "stw %0, 4(%1) \n" \
+ : "=r"(l_dataL) \
+ : "r"(o_data) );
+
+ // CMO-TBD
+ // Check PIB response code in 0x00001007(17:19)
+ // Translate PIB rc to PK rc
+
+ return 0;
+}
diff --git a/src/sample/pk_scom.h b/src/sample/pk_scom.h
new file mode 100644
index 00000000..3d02e15e
--- /dev/null
+++ b/src/sample/pk_scom.h
@@ -0,0 +1,66 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sample/pk_scom.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sample_main.c
+/// \brief Sample program that creates and starts a thread
+///
+/// This file demonstrates how to create a thread and run it. It also provides
+/// an example of how to add traces to the code.
+
+#ifndef __PK_SCOM_H__
+#define __PK_SCOM_H__
+
+/// SCOM operations return non-zero error codes that may or may not indicate
+/// an actual error, depending on which SCOM is begin accessed. This error
+/// code is returned as the value of get/putscom(). The error code value
+/// increases with teh severity of the error.
+#define CFAM_FSI_STATUS_0x00001007 0x00001007
+typedef union cfam_fsi_status_reg {
+ uint64_t value;
+ struct {
+ uint64_t ignore_fields1 : 17 ;
+ uint64_t pib_error_code : 3 ;
+ uint64_t igore_fields2 : 44 ;
+ } fields;
+} cfam_fsi_status_reg_t;
+
+#define PCB_ERROR_NONE 0
+#define PCB_ERROR_RESOURCE_OCCUPIED 1
+#define PCB_ERROR_CHIPLET_OFFLINE 2
+#define PCB_ERROR_PARTIAL_GOOD 3
+#define PCB_ERROR_ADDRESS_ERROR 4
+#define PCB_ERROR_CLOCK_ERROR 5
+#define PCB_ERROR_PACKET_ERROR 6
+#define PCB_ERROR_TIMEOUT 7
+
+uint32_t putscom( uint32_t i_chiplet, uint32_t i_address, uint64_t i_data);
+
+uint32_t getscom( uint32_t i_chiplet, uint32_t i_address, uint64_t *o_data);
+
+#endif // __PK_SCOM_H__
diff --git a/src/sample/pk_trace_wrap.c b/src/sample/pk_trace_wrap.c
new file mode 100644
index 00000000..e9118e2d
--- /dev/null
+++ b/src/sample/pk_trace_wrap.c
@@ -0,0 +1,32 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sample/pk_trace_wrap.c $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 "pk_trace_wrap.h"
+#include "pk.h"
+#include "pk_trace.h"
+
+
+void pk_trace_wrap(const char* str)
+{
+ PK_TRACE("testsetest");
+}
diff --git a/src/sample/pk_trace_wrap.h b/src/sample/pk_trace_wrap.h
new file mode 100644
index 00000000..072d91c8
--- /dev/null
+++ b/src/sample/pk_trace_wrap.h
@@ -0,0 +1,30 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sample/pk_trace_wrap.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 __PK_WRAP_WRAP_H__
+#define __PK_WRAP_WRAP__H__
+
+
+void pk_trace_wrap(const char*);
+
+#endif // __PK_WRAP_WRAP_H__
diff --git a/src/sample/sample_main.C b/src/sample/sample_main.C
new file mode 100644
index 00000000..a2d460f4
--- /dev/null
+++ b/src/sample/sample_main.C
@@ -0,0 +1,122 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sample/sample_main.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sample_main.c
+/// \brief Sample program that creates and starts a thread
+///
+/// This file demonstrates how to create a thread and run it. It also provides
+/// an example of how to add traces to the code.
+extern "C" {
+#include "pk.h"
+#include "pk_trace.h"
+#include "pk_scom.h"
+#include "pk_trace_wrap.h"
+}
+#define KERNEL_STACK_SIZE 256
+#define MAIN_THREAD_STACK_SIZE 256
+
+
+
+uint8_t G_kernel_stack[KERNEL_STACK_SIZE];
+uint8_t G_main_thread_stack[MAIN_THREAD_STACK_SIZE];
+PkThread G_main_thread;
+
+class Thetest {
+
+ public:
+ int i;
+
+};
+
+// A simple thread that just increments a local variable and sleeps
+void main_thread(void* arg)
+{
+ //Thetest mytest;
+
+ //mytest.i = 0;
+
+ //std::cout << "sdfds" << std::endl;
+
+ uint16_t a = 0;
+
+ pk_trace_wrap("sdfsdf");
+ //PK_TRACE("thread started");
+
+
+ while(1)
+ {
+ // PK_TRACE can take up to 4 parameters
+ // (not including the format string)
+ //PK_TRACE("thread seconds = %d", a);
+ pk_sleep(PK_SECONDS(1));
+
+ uint64_t i_data = 0x0110;
+
+ putscom(0x33333, 0x11111, i_data);
+
+ getscom(0x33333, 0x11111, &i_data);
+
+ a++;
+ }
+}
+
+
+// The main function is called by the boot code (after initializing some
+// registers)
+int main(int argc, char **argv)
+{
+ // initializes kernel data (stack, threads, timebase, timers, etc.)
+ pk_initialize((PkAddress)G_kernel_stack,
+ KERNEL_STACK_SIZE,
+ 0,
+ 500000000);
+
+ //PK_TRACE("Kernel init completed");
+
+ //Initialize the thread control block for G_main_thread
+ pk_thread_create(&G_main_thread,
+ (PkThreadRoutine)main_thread,
+ (void*)NULL,
+ (PkAddress)G_main_thread_stack,
+ (size_t)MAIN_THREAD_STACK_SIZE,
+ (PkThreadPriority)1);
+
+ //PK_TRACE_BIN("G_main_thread", &G_main_thread, sizeof(G_main_thread));
+
+ //Make G_main_thread runnable
+ pk_thread_resume(&G_main_thread);
+
+ //PK_TRACE("Starting thread(s)");
+
+ // Start running the highest priority thread.
+ // This function never returns
+ pk_start_threads();
+
+ return 0;
+}
diff --git a/src/sample/topfiles.mk b/src/sample/topfiles.mk
new file mode 100644
index 00000000..8918a95c
--- /dev/null
+++ b/src/sample/topfiles.mk
@@ -0,0 +1,29 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/sample/topfiles.mk $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+TOP-C-SOURCES = pk_trace_wrap.c pk_scom.c
+TOP-CPP-SOURCES = sample_main.C
+TOP-S-SOURCES =
+
+
+TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-CPP-SOURCES:.C=.o) $(TOP-S-SOURCES:.S=.o)
diff --git a/src/sbefw/Makefile b/src/sbefw/Makefile
new file mode 100644
index 00000000..f25f44f5
--- /dev/null
+++ b/src/sbefw/Makefile
@@ -0,0 +1,56 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/sbefw/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+#export P2P_ENABLE = 1
+
+export SUB_OBJDIR = /sbefw
+
+include img_defs.mk
+include sbefwfiles.mk
+
+OBJS := $(addprefix $(OBJDIR)/, $(SBEFW_OBJECTS))
+
+libsbefw.a: $(OBJS)
+ $(AR) crs $(OBJDIR)/libsbefw.a $(OBJDIR)/*.o
+
+.PHONY: clean sbefw
+sbefw: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+
+#clean the kernel directory first, then the application level clean
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
+
+
+
+
+
diff --git a/src/sbefw/assert.h b/src/sbefw/assert.h
new file mode 100644
index 00000000..4a5be085
--- /dev/null
+++ b/src/sbefw/assert.h
@@ -0,0 +1,49 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/assert.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 assert.h
+ *
+ * @brief This file contains the assert macro for SBE
+ */
+#ifndef SBE_ASSERT_H
+#define SBE_ASSERT_H
+#include "sbetrace.H"
+#include "sbeutil.H"
+
+//@TODO via RTC 129166
+//inject exception to halt SBE. Also see if we can use some
+//PK kernel API.
+#ifndef NDEBUG
+#define assert(expr) \
+ if( !(expr )) \
+ { \
+ SBE_ERROR("assertion failed: "#expr); \
+ PK_PANIC(SBE::PANIC_ASSERT); \
+ } \
+
+#else
+#define assert(expr)
+#endif //NDEBUG
+
+#endif // SBE_ASSERT_H
diff --git a/src/sbefw/pk_app_cfg.h b/src/sbefw/pk_app_cfg.h
new file mode 100644
index 00000000..d2fbfceb
--- /dev/null
+++ b/src/sbefw/pk_app_cfg.h
@@ -0,0 +1,144 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/pk_app_cfg.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/pk_app_cfg.h
+ *
+ * @brief Application specific overrides go here.
+ *
+ */
+
+#ifndef __PK_APP_CFG_H__
+#define __PK_APP_CFG_H__
+
+#include "sbeirq.H"
+
+/*
+ * @brief Static configuration data for external interrupts:
+ * IRQ#, TYPE, POLARITY, ENABLE
+ *
+ */
+#define APPCFG_EXT_IRQS_CONFIG \
+ SBE_IRQ_START0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_START1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_INTR0 STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_INTR1 STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_DRTM_REQ STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_SBEFIFO_RESET STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_SBEFIFO_DATA STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ SBE_IRQ_HOST_PSU_INTR STD_IRQ_TYPE_LEVEL STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+
+
+/*
+ * @brief This 64 bit mask specifies which of the interrupts are not to be used.
+ *
+ */
+#define APPCFG_IRQ_INVALID_MASK \
+(\
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_8) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_9) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_10) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_11) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_12) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_13) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_14) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_15) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_16) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_17) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_18) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_19) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_20) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_21) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_22) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_23) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_24) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_25) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_26) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_27) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_28) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_29) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_30) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_31) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_32) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_33) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_34) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_35) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_36) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_37) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_38) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_39) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_40) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_41) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_42) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_43) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_44) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_45) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_46) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_47) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_48) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_49) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_50) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_51) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_52) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_53) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_54) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_55) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_56) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_57) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_58) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_59) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_60) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_61) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_62) | \
+ STD_IRQ_MASK64(SBE_IRQ_RESERVED_63))
+
+
+/*
+ * @brief Override the default behavior of the PK API error handling.
+ * Force PK to send the return code back to the application,
+ * instead of a kernel panic.
+ *
+ */
+#ifndef PK_ERROR_PANIC
+#define PK_ERROR_PANIC 0
+#endif
+
+/*
+ * @brief Override the default behavior of idle timer trace.
+ * As SBE trace buffer is small, we do not want idle timer traces.
+ *
+ */
+#define PK_TRACE_TIMER_OUTPUT 0
+
+#ifdef PPE42_MACHINE_CHECK_HANDLER
+#undef PPE42_MACHINE_CHECK_HANDLER
+#endif
+#define PPE42_MACHINE_CHECK_HANDLER SBE_MACHINE_CHECK_HANDLER
+
+// Set the trace buffer size
+#ifdef PK_TRACE_SZ
+#undef PK_TRACE_SZ
+#endif
+#define PK_TRACE_SZ 4*1024
+
+#endif /*__PK_APP_CFG_H__*/
diff --git a/src/sbefw/plugins/sbeUserDataParser.C b/src/sbefw/plugins/sbeUserDataParser.C
new file mode 100644
index 00000000..9ad2f48e
--- /dev/null
+++ b/src/sbefw/plugins/sbeUserDataParser.C
@@ -0,0 +1,292 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/plugins/sbeUserDataParser.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 <sys/stat.h>
+#include <errno.h>
+
+#include <cstdlib>
+#include <cstring>
+#include <sstream>
+
+#include <utilfile.H>
+#include <utilmem.H>
+
+#include "sbeFFDCType.H"
+
+#define SBE_TEMP_DUMP_FILE "/tmp/trace_dump.bin"
+#define SBE_TRACE_BIN "/tmp/sbe_trace.bin"
+#define PPE2FSP_TOOL "ppe2fsp"
+#define P9_XIP_TOOL "p9_xip_tool"
+#define SBE_TRACE_CMD "fsp-trace -s"
+#define SBE_TRACE_HEADLINE "SBE Traces"
+#define SBE_ATTR_DUMP_HEADLINE "SBE Attributes Dump"
+#define P9_XIP_ATTR_CMD "-ifs attrdump"
+#define SBE_STRING_FILE "sbeStringFile"
+#define SBE_SEEPROM_BIN "sbe_seeprom.bin"
+
+#define SBE_PARSER_MAX_LOCAL_BUFFER 8192
+
+#define SBE_PARSER_PRINT_DELIMITER {std::cout << \
+"*****************************************************************************"\
+<< std::endl;}
+#define SBE_PARSER_PRINT_HEADING(x) { SBE_PARSER_PRINT_DELIMITER \
+std::cout << \
+" "x<< std::endl;\
+SBE_PARSER_PRINT_DELIMITER }
+
+std::string findSbeFile(const char *name)
+{
+#ifdef CONTEXT_x86_nfp
+ //TODO via RTC:157433
+ std::string tmp = getenv("bb");
+ tmp += "obj/x86.nfp/sbei/sbfw/img/";
+ std::string file = tmp + name;
+
+ struct stat l_stat;
+ if(stat(file.c_str(), &l_stat) < 0)
+ {
+ //Can't find the file
+ }
+
+ return file;
+#endif
+#ifdef CONTEXT_ppc
+ std::string tmp = getenv("PATH");
+ tmp += ":/nfs:/maint";
+
+ char *path = strdup(tmp.c_str());
+ char *dir = NULL;
+
+ std::string file;
+
+ struct stat l_stat;
+
+ for(dir = strtok( path, ":" ); dir; dir = strtok(NULL, ":"))
+ {
+ file = file + dir + "/" + name;
+
+ if(stat(file.c_str(), &l_stat) < 0)
+ {
+ // String file not found, go to next one
+ file.clear();
+ }
+ else
+ {
+ // update where trexStringFile is
+ break;
+ }
+ }
+
+ free(path);
+ path = NULL; //sm05c
+
+ return file;
+#endif
+}
+
+void sbeParserSysCall(const char *cmd)
+{
+ FILE *stream;
+ char buffer[256];
+
+ stream = popen(cmd, "r" );
+ if(stream)
+ {
+ while(!feof(stream))
+ {
+ if(fgets(buffer, 256, stream) != NULL)
+ {
+ std::cout << buffer;
+ }
+ }
+ }
+ else
+ {
+ std::cout << "command failed :[" << cmd << "]" << std::endl;
+ std::cout << "errno [" << errno << "]" << std::endl;
+ }
+}
+
+int parseSbeFFDC(ErrlUsrParser & i_parser, const void * i_pBuffer,
+ const uint32_t i_buflen)
+{
+ int l_rc = 0;
+ uint32_t fapiRc = 0;
+ sbeFFDCDataHeader_t l_pData = {0};
+ char l_buffer[SBE_PARSER_MAX_LOCAL_BUFFER] = {0};
+ char *l_pBuffer = (char*)i_pBuffer;
+ uint32_t l_buflen = i_buflen;
+
+ do
+ {
+ if(i_pBuffer == NULL)
+ {
+ l_rc = -1;
+ break;
+ }
+ //seek l_mem to the binary blob of FFDC package
+ UtilMem l_mem(const_cast<void*>(i_pBuffer),i_buflen);
+
+ // The data is a buffer of SBE FFDC data
+ i_parser.PrintHeading("SBE FFDC Parser");
+
+ if(l_buflen < sizeof(fapiRc))
+ {
+ i_parser.PrintHexDump(l_pBuffer, l_buflen);
+ break;
+ }
+ l_buflen -= sizeof(fapiRc);
+ l_pBuffer += sizeof(fapiRc);
+ l_mem >> fapiRc;
+ i_parser.PrintNumber("FAPI RC ", "0x%08X", fapiRc);
+
+ if(l_buflen < sizeof(l_pData))
+ {
+ i_parser.PrintHexDump(l_pBuffer, l_buflen);
+ break;
+ }
+ l_buflen -= sizeof(l_pData);
+ l_pBuffer += sizeof(l_pData);
+ l_mem >> l_pData;
+
+ i_parser.PrintNumber("Primary Status ", "0x%04X",
+ (uint16_t)l_pData.primaryStatus);
+ i_parser.PrintNumber("Secondary Status ", "0x%04X",
+ (uint16_t)l_pData.secondaryStatus);
+
+ //loop through the number of fields configured
+ uint32_t l_dumpFields = l_pData.dumpFields.get();
+ while(l_dumpFields && !l_rc)
+ {
+ if(l_dumpFields & 0x0001)
+ {
+ if(l_buflen < sizeof(uint32_t))
+ {
+ //Complete this loop and let the tools print as much data
+ //as possible but break from next loop
+ l_rc = -1;
+ }
+ sbeFFDCUserDataIdentifier_t l_ffdcUserDataId = {0};
+ l_buflen -= sizeof(uint32_t); //l_ffdcUserDataId
+ l_pBuffer += sizeof(uint32_t); //l_ffdcUserDataId
+
+ l_mem >> l_ffdcUserDataId;
+
+ // TODO via RTC:158462 continue even for attribute dump
+ // Need to extend p9_xip_tool for partial attr dump handling
+ if((l_buflen < l_ffdcUserDataId.fieldLen) &&
+ (l_ffdcUserDataId.fieldId != SBE_FFDC_TRACE_DUMP))
+ {
+ i_parser.PrintHexDump(l_pBuffer, l_buflen);
+ break;
+ }
+
+ l_buflen -= l_ffdcUserDataId.fieldLen;
+ l_pBuffer += l_ffdcUserDataId.fieldLen;
+
+ l_mem.read(l_buffer, l_ffdcUserDataId.fieldLen);
+ std::ostringstream l_strFile;
+ //Generate temp dump file name
+ l_strFile << SBE_TEMP_DUMP_FILE;
+
+ //Write dump into the temporary file
+ UtilFile l_fileObj(l_strFile.str().c_str());
+ errlHndl_t l_errlHndl = l_fileObj.open("w");
+ if ( l_errlHndl )
+ {
+ std::cerr << "Error opening "
+ << l_strFile.str() << std::endl;
+ l_errlHndl->commit(HWSV_COMP_ID, ERRL_ACTION_REPORT);
+ delete l_errlHndl;
+ l_errlHndl = NULL;
+ i_parser.PrintHexDump(l_buffer, l_ffdcUserDataId.fieldLen);
+ return -1;
+ }
+ else
+ {
+ l_fileObj.write( l_buffer, l_ffdcUserDataId.fieldLen);
+ l_fileObj.Close();
+ }
+
+ //Specific handling
+ if(l_ffdcUserDataId.fieldId == SBE_FFDC_ATTR_DUMP)
+ {
+ SBE_PARSER_PRINT_HEADING(SBE_ATTR_DUMP_HEADLINE)
+ //command
+ std::ostringstream l_strCmd1;
+ // p9_xip_tool <sbe seeprom bin file>
+ // -ifs attrdump <attr dump file> 2>&1
+ l_strCmd1 << findSbeFile(P9_XIP_TOOL)
+ << " "
+ << findSbeFile(SBE_SEEPROM_BIN)
+ << " "
+ << P9_XIP_ATTR_CMD
+ << " "
+ << l_strFile.str().c_str()
+ << " "
+ << "2>&1";
+
+ //Call out the command
+ sbeParserSysCall( l_strCmd1.str().c_str() );
+ }
+ else if(l_ffdcUserDataId.fieldId == SBE_FFDC_TRACE_DUMP)
+ {
+ SBE_PARSER_PRINT_HEADING(SBE_TRACE_HEADLINE)
+ //command
+ std::ostringstream l_strCmd1, l_strCmd2;
+ // ppe2fsp <trace dump file> <trace bin file> 2>&1
+ l_strCmd1 << findSbeFile(PPE2FSP_TOOL)
+ << " "
+ << l_strFile.str().c_str()
+ << " "
+ << SBE_TRACE_BIN
+ << " "
+ << "2>&1";
+
+ // fsp-trace -s <sbe string file> <trace bin file> 2>&1
+ l_strCmd2 << SBE_TRACE_CMD
+ << " "
+ << findSbeFile(SBE_STRING_FILE)
+ << " "
+ << SBE_TRACE_BIN
+ << " "
+ << "2>&1";
+
+ //Call out the commands
+ sbeParserSysCall( l_strCmd1.str().c_str() );
+ sbeParserSysCall( l_strCmd2.str().c_str() );
+ }
+
+ //Delete the temp file
+ l_fileObj.Remove();
+ }
+ l_dumpFields >>= 1;
+ if(l_rc != 0)
+ {
+ break;
+ }
+ }
+ } while(false);
+
+ return l_rc;
+}
diff --git a/src/sbefw/pool.C b/src/sbefw/pool.C
new file mode 100644
index 00000000..6695135a
--- /dev/null
+++ b/src/sbefw/pool.C
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/pool.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 <stdint.h>
+#include <sbetrace.H>
+#include <stddef.h>
+#include<pool.H>
+#include "assert.h"
+
+namespace SBEVECTORPOOL
+{
+
+vectorMemPool_t g_pool[G_POOLSIZE];
+
+vectorMemPool_t * allocMem()
+{
+ vectorMemPool_t *pool = NULL;
+ for( size_t idx = 0; idx < G_POOLSIZE; idx++ )
+ {
+ if( 0 == g_pool[idx].refCount )
+ {
+ pool = g_pool + idx;
+ g_pool[idx].refCount++;
+ break;
+ }
+ }
+ SBE_DEBUG(" Giving pool 0x%08X", pool);
+ return pool;
+}
+
+void releaseMem( vectorMemPool_t * i_pool )
+{
+ do
+ {
+ if ( NULL == i_pool ) break;
+
+ // Assert here. This pool was not supposed to be in use.
+ assert( 0 != i_pool->refCount )
+ SBE_DEBUG(" Releasing pool 0x%08X", i_pool);
+ i_pool->refCount--;
+ SBE_DEBUG(" In releaseMem() RefCount:%u", i_pool->refCount);
+ }while(0);
+}
+
+} // namesspace SBEVECTORPOOL
diff --git a/src/sbefw/pool.H b/src/sbefw/pool.H
new file mode 100644
index 00000000..3968852c
--- /dev/null
+++ b/src/sbefw/pool.H
@@ -0,0 +1,58 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/pool.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 SBE_VECTOR_POOL_H
+#define SBE_VECTOR_POOL_H
+
+namespace SBEVECTORPOOL
+{
+
+// Size of a block for a vector
+static const size_t G_BLOCKSIZE = 512;
+
+//Pool size
+static const size_t G_POOLSIZE = 4;
+
+typedef struct
+{
+ size_t refCount;
+ uint8_t data[G_BLOCKSIZE] __attribute__ ((aligned (8)));
+}vectorMemPool_t;
+
+/**
+ * @brief Returns memory pool block.
+ *
+ * @return Memory block if available, NULL otherwise.
+ */
+vectorMemPool_t * allocMem();
+
+/**
+ * @brief Release memory pool block.
+ *
+ * @param[in] i_pool pool pointer.
+ */
+void releaseMem( vectorMemPool_t * i_pool );
+
+} // namespace SBEVECTORPOOL
+#endif //SBE_VECTOR_POOL_H
diff --git a/src/sbefw/sbeFFDC.C b/src/sbefw/sbeFFDC.C
new file mode 100644
index 00000000..88bee00d
--- /dev/null
+++ b/src/sbefw/sbeFFDC.C
@@ -0,0 +1,141 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFFDC.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "sberegaccess.H"
+#include "sbeFFDC.H"
+
+/*
+ * @brief sendOverFIFO - method to pack and send SBE internal FFDC
+ * only if isSendInternalFFDCSet() is true
+ * over FIFO interface
+ * @param[in] i_primStatus - Primary status of Chip op
+ * @param[in] i_secStatus - Secondary status of Chip op
+ * @param[in] i_fieldsConfig - bitmap indicating the field
+ * to be sent in FFDC
+ *
+ * @param[out] o_bytesSent -number of bytes sent
+ *
+ * @return - SBE secondary RC
+ */
+uint32_t SbeFFDCPackage::sendOverFIFO(uint32_t i_primStatus,
+ uint32_t i_secStatus,
+ uint32_t i_fieldsConfig,
+ uint32_t &o_bytesSent)
+{
+ #define SBE_FUNC "sbeSendFFDCPackageFIFO "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t length = 0;
+
+ do
+ {
+ //reset sent bytes
+ o_bytesSent = 0;
+
+ //check if SBE internal FFDC should be generated
+ if(SbeRegAccess::theSbeRegAccess().isSendInternalFFDCSet() == false)
+ {
+ SBE_INFO(SBE_FUNC" isSendInternalFFDCSet()=false, "
+ "not generating SBE InternalFFDC");
+ rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+
+ // update the primary and secondary status
+ iv_sbeFFDCDataHeader.primaryStatus = i_primStatus;
+ iv_sbeFFDCDataHeader.secondaryStatus = i_secStatus;
+ //Update the user data header with dump fields configuration
+ iv_sbeFFDCDataHeader.dumpFields.set(i_fieldsConfig);
+ iv_sbeFFDCHeader.lenInWords = (sizeof(sbeResponseFfdc_t) +
+ sizeof(sbeFFDCDataHeader_t))
+ /sizeof(uint32_t);
+ //Update the length in ffdc package header base on required fields
+ for(auto &sbeFFDCUserData:sbeFFDCUserDataArray)
+ {
+ if(sbeFFDCUserData.userDataId.fieldId & i_fieldsConfig)
+ {
+ iv_sbeFFDCHeader.lenInWords +=
+ (sbeFFDCUserData.userDataId.fieldLen +
+ sizeof(sbeFFDCUserDataIdentifier_t))
+ /sizeof(uint32_t);
+ }
+ }
+
+ //Send FFDC package header
+ length = sizeof(iv_sbeFFDCHeader) / sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult(length,
+ (uint32_t *)(&(iv_sbeFFDCHeader)));
+ if( rc!= SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ o_bytesSent += length;
+
+ //Send FFDC user data header
+ length = sizeof(iv_sbeFFDCDataHeader) / sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult(length,
+ (uint32_t *)(&(iv_sbeFFDCDataHeader)));
+ if( rc!= SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ o_bytesSent += length;
+
+ //Send FFDC user data blobs
+ for(auto &sbeFFDCUserData:sbeFFDCUserDataArray)
+ {
+ if(sbeFFDCUserData.userDataId.fieldId & i_fieldsConfig)
+ {
+ //Send User data identifer and length
+ length = sizeof(sbeFFDCUserDataIdentifier_t) / sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult(length,
+ (uint32_t*)&(sbeFFDCUserData.userDataId));
+ if( rc!= SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ o_bytesSent += length;
+
+ //Send User data
+ length = sbeFFDCUserData.userDataId.fieldLen / sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult(length,
+ (uint32_t*)sbeFFDCUserData.userDataPtr);
+ if( rc!= SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ o_bytesSent += length;
+ }
+ }
+
+ SBE_INFO(SBE_FUNC "Number of words sent [%d]", o_bytesSent);
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbeFFDC.H b/src/sbefw/sbeFFDC.H
new file mode 100644
index 00000000..514b9caf
--- /dev/null
+++ b/src/sbefw/sbeFFDC.H
@@ -0,0 +1,125 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFFDC.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 __SBE_FFDC_H
+#define __SBE_FFDC_H
+
+#include "fapi2.H"
+#include "plat_attributes.H"
+#include "pk_trace.h"
+#include "sbeFFDCType.H"
+#include "sbeSpMsg.H"
+
+//PIBMEM attribute dump
+extern G_sbe_attrs_t G_sbe_attrs;
+
+//Configuration of user data blobs present in SBE FFDC
+//Data is sent in the order defined here
+//Definition - Identifier
+// length of the blob
+// pointer to the data
+const sbeFFDCUserData_t sbeFFDCUserDataArray[] =
+ {{{SBE_FFDC_TRACE_DUMP,
+ sizeof(PkTraceBuffer)},
+ (const void *)&g_pk_trace_buf,
+ },
+ {{SBE_FFDC_ATTR_DUMP,
+ sizeof(G_sbe_attrs_t)},
+ (const void *)&G_sbe_attrs,
+ },
+ };
+
+//SBE internal FFDC package class
+class SbeFFDCPackage
+{
+private:
+ //Disable copy constructor
+ SbeFFDCPackage(SbeFFDCPackage const &) = delete;
+ //Disable assignment operator
+ SbeFFDCPackage& operator=(SbeFFDCPackage const &) = delete;
+
+ sbeResponseFfdc_t iv_sbeFFDCHeader;
+ //FFDC user data header
+ sbeFFDCDataHeader_t iv_sbeFFDCDataHeader;
+
+public:
+ /*ctor
+ *
+ */
+ SbeFFDCPackage()
+ {
+ //Making sure data is indeed aligned
+ static_assert((sizeof(G_sbe_attrs_t) % 4) == 0,
+ "G_sbe_attrs not 4byte aligned");
+ static_assert((sizeof(PkTraceBuffer) % 4) == 0,
+ "g_pk_trace_buf not 4byte aligned");
+
+ iv_sbeFFDCHeader.magicBytes = 0xFFDC;
+ iv_sbeFFDCHeader.fapiRc = fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+ iv_sbeFFDCDataHeader.primaryStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ iv_sbeFFDCDataHeader.secondaryStatus = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ //length and dumpFields will be filled up depending on the fields
+ //to be sent in send APIs
+ iv_sbeFFDCDataHeader.dumpFields = {0};
+ }
+ /*
+ * @brief sendOverFIFO - method to pack and send SBE internal FFDC
+ * only if isSendInternalFFDCSet() is true
+ * over FIFO interface
+ * @param[in] i_primStatus - Primary status of Chip op
+ * @param[in] i_secStatus - Secondary status of Chip op
+ * @param[in] i_fieldsConfig - bitmap indicating the field
+ * to be sent in FFDC
+ *
+ * @param[out] o_bytesSent -number of bytes sent
+ *
+ * @return - SBE secondary RC
+ */
+ uint32_t sendOverFIFO(uint32_t i_primStatus,
+ uint32_t i_secStatus,
+ uint32_t i_fieldsConfig,
+ uint32_t &o_bytesSent);
+
+ /* TODO via RTC:150786
+ * @brief sendOverHOST - method to pack and send SBE internal FFDC
+ * only if isSendInternalFFDCSet() is true
+ * over HOST interface
+ *
+ * @param[in] i_primStatus - Primary status of Chip op
+ * @param[in] i_secStatus - Secondary status of Chip op
+ * @param[in] i_fieldsConfig - bitmap indicating the field
+ * to be sent in FFDC
+ *
+ * @param[out] o_bytesSent - number of bytes sent
+ *
+ * @return - SBE secondary RC
+ */
+ //uint32_t sendOverHOST(uint32_t i_primStatus,
+ // uint32_t i_secStatus,
+ // uint32_t i_fieldsConfig,
+ // uint32_t &o_bytesSent) {};
+};
+
+#endif //__SBE_FFDC_H
diff --git a/src/sbefw/sbeFFDCType.H b/src/sbefw/sbeFFDCType.H
new file mode 100644
index 00000000..f4ef95ad
--- /dev/null
+++ b/src/sbefw/sbeFFDCType.H
@@ -0,0 +1,100 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFFDCType.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 __SBE_FFDC_TYPE_H
+#define __SBE_FFDC_TYPE_H
+
+//Bit mapped identifiers
+#define SBE_FFDC_ATTR_DUMP 0x0001
+#define SBE_FFDC_TRACE_DUMP 0x0002
+#define SBE_FFDC_ALL_DUMP 0xFFFF
+
+/* Structure indicating the contents of FFDC package
+ * value 'true' - field present;value 'false' - field not present
+ * bit_0 - attribute dump
+ * bit_1 - trace buffer dump
+ * bit 2-31 - reserved
+ */
+typedef struct
+{
+ uint32_t attrField:1;
+ uint32_t traceField:1;
+ uint32_t reserved:30;
+ /* @breif - set dump fields
+ *
+ * @param[in] - uint32_t value to be updated
+ */
+ void set(uint32_t val)
+ {
+ if(val & SBE_FFDC_ATTR_DUMP)
+ {
+ attrField = true;
+ }
+ if(val & SBE_FFDC_TRACE_DUMP)
+ {
+ traceField = true;
+ }
+ }
+ /* @brief - get dump fields as uint32_t
+ *
+ * @return - uint32_t value
+ */
+ uint32_t get()
+ {
+ uint32_t l_val = 0;
+ if(attrField)
+ {
+ l_val |= SBE_FFDC_ATTR_DUMP;
+ }
+ if(traceField)
+ {
+ l_val |= SBE_FFDC_TRACE_DUMP;
+ }
+ return l_val;
+ }
+} sbeFFDCDumpFields_t;
+
+//Sturcture indicating the type of ffdc user data blob
+//and its length in bytes
+typedef struct
+{
+ uint32_t fieldId:16;
+ uint32_t fieldLen:16;
+} sbeFFDCUserDataIdentifier_t;
+
+//Structure of ffdc user data blob
+typedef struct
+{
+ sbeFFDCUserDataIdentifier_t userDataId;
+ const void *userDataPtr;
+} sbeFFDCUserData_t;
+
+//keep it packed to 4byte boundary to avoid packing bytes
+typedef struct
+{
+ uint32_t primaryStatus:16;//Chip Op Primary status
+ uint32_t secondaryStatus:16;//Chip Op Secondary status
+ sbeFFDCDumpFields_t dumpFields;//bitmapped dumpFields
+} sbeFFDCDataHeader_t;
+
+#endif //__SBE_FFDC_TYPE_H
diff --git a/src/sbefw/sbeFifoMsgUtils.C b/src/sbefw/sbeFifoMsgUtils.C
new file mode 100644
index 00000000..99cf2709
--- /dev/null
+++ b/src/sbefw/sbeFifoMsgUtils.C
@@ -0,0 +1,375 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFifoMsgUtils.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeFifoMsgUtils.C
+ *
+ * @brief This file contains the SBE FIFO Access Common Utility Functions
+ *
+ */
+
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbeerrorcodes.H"
+#include "assert.h"
+#include "sbeFFDC.H"
+
+// If we can not perform FIFO operation ( FIFO FULL while writing
+// or EMPTY while reading ) we will sleep for FIFO_WAIT_SLEEP_TIME
+// ms so that FIFO can be ready.
+static const uint32_t FIFO_WAIT_SLEEP_TIME = 1;
+// Write this data to send EOT to DS FIFO. The register to send EOT
+// is 32 bit only. But our scom operations are 64 bit. So set a bit
+// in higher word to trigger EOT.
+static const uint64_t DOWNSTREAM_EOT_DATA = 0x100000000ull;
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeUpFifoDeq_mult (uint32_t &io_len,
+ uint32_t *o_pData,
+ const bool i_isEotExpected,
+ const bool i_flush)
+{
+ #define SBE_FUNC " sbeUpFifoDeq_mult "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_len = 0;
+
+ // If Caller didn't request flush operation
+ // and passed a non-zero valid length, we
+ // would expect a valid buffer
+ if ((!i_flush) && (io_len > 0))
+ {
+ assert ( NULL != o_pData)
+ }
+
+ do
+ {
+ sbeFifoEntry_t l_data = {0};
+
+ // Read Double word from the Upstream FIFO;
+ // The DW data represents the first 32 bits of data word entry
+ // followed by the status bits.
+
+ // Bit 0-31 : Data
+ // Bit 32 : Data valid flag
+ // Bit 33 : EOT flag
+ // Bit 34-63 : Status (2-31)
+ // Valid : EOT
+ // 1 : 0 -> data=message
+ // 0 : 1 -> data=dummy_data of EOT operation
+ // 0 : 0 -> data=dummy_data
+ // 1 : 1 -> Not used
+
+ l_rc = sbeUpFifoDeq ( reinterpret_cast<uint64_t*>(&l_data) );
+
+ if (l_rc)
+ {
+ // Error while dequeueing from upstream FIFO
+ SBE_ERROR(SBE_FUNC"sbeUpFifoDeq failed,"
+ "l_rc=[0x%08X]", l_rc);
+ // @TODO RTC via : 132295
+ // RC refactoring - reserve 3 bits in SBE RC for PCBPIB
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ SBE_DEBUG(SBE_FUNC"sbeUpFifoDeq, "
+ "l_data.fifo_data=[0x%08X],",
+ l_data.fifo_data);
+
+ // If FIFO reset is requested
+ if(l_data.statusOrReserved.req_upfifo_reset)
+ {
+ // @TODO via RTC : 126147
+ // Review reset loop flow in here.
+ // Received a FIFO reset request
+ l_rc = SBE_FIFO_RESET_RECEIVED;
+ break;
+ }
+
+ // if EOT flag is set, clear EOT and
+ // set the RC accordingly
+ if (l_data.statusOrReserved.eot_flag)
+ {
+ l_rc = sbeUpFifoAckEot();
+ if (l_rc)
+ {
+ // Error while ack'ing EOT in upstream FIFO
+ SBE_ERROR(SBE_FUNC"sbeUpFifoAckEot failed,"
+ "l_rc=[0x%08X]", l_rc);
+
+ // Collect FFDC and save off the l_rc
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ // Successfully Ack'ed the EOT in upstream FIFO
+ if ( ((!i_isEotExpected) || (l_len != io_len))
+ && (!i_flush) )
+ {
+ if (l_len < io_len)
+ {
+ // Unexpected EOT, got insufficient data
+ l_rc = SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA ;
+ }
+ else
+ {
+ // Unexpected EOT, got excess data
+ l_rc = SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA ;
+ }
+ }
+ break;
+ }
+
+ // if Upstream FIFO is empty,
+ if (l_data.statusOrReserved.fifo_empty)
+ {
+ pk_sleep(PK_MILLISECONDS(FIFO_WAIT_SLEEP_TIME));
+ continue;
+ }
+
+ if ((!i_flush) && (l_len < io_len))
+ {
+ o_pData[l_len] = l_data.fifo_data;
+ }
+
+ ++l_len;
+
+ } while(i_flush || i_isEotExpected || (l_len < io_len));
+
+ // Return the length of entries dequeued.
+ io_len = l_len;
+ return l_rc;
+
+ #undef SBE_FUNC
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeDownFifoEnq_mult (uint32_t &io_len,
+ const uint32_t *i_pData)
+{
+ #define SBE_FUNC " sbeDownFifoEnq_mult "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_len = 0;
+
+ do
+ {
+ sbeDownFifoStatusReg_t l_status = {0};
+
+ // Read the down stream FIFO status
+ l_rc = sbeDownFifoGetStatus (reinterpret_cast<uint64_t *>(&l_status));
+ if (l_rc)
+ {
+ // Error while reading downstream FIFO status
+ SBE_ERROR(SBE_FUNC"sbeDownFifoGetStatus failed, "
+ "l_rc=[0x%08X]", l_rc);
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ // Check if there was a FIFO reset request from SP
+ if (l_status.downfifo_status.req_upfifo_reset)
+ {
+ // @TODO via RTC : 126147
+ // Review reset loop flow in here.
+ // Received an upstream FIFO reset request
+ SBE_ERROR(SBE_FUNC"Received reset request");
+ l_rc = SBE_FIFO_RESET_RECEIVED;
+ break;
+ }
+
+ // Check if downstream FIFO is full
+ if (l_status.downfifo_status.fifo_full)
+ {
+ // Downstream FIFO is full
+ pk_sleep(PK_MILLISECONDS(FIFO_WAIT_SLEEP_TIME));
+ continue;
+ }
+
+ // PIB write data format:
+ // Bit 0 - 31 : Data
+ // Bit 32 - 63 : Unused
+
+ sbeFifoEntry_t l_data = {0};
+
+ l_data.fifo_data = *(i_pData+l_len);
+
+ SBE_DEBUG(SBE_FUNC"Downstream fifo data entry[0x%08X]",
+ l_data.fifo_data);
+
+ // Write the data into the downstream FIFO
+ uint64_t * tp = reinterpret_cast<uint64_t*>(&l_data);
+ l_rc = sbeDownFifoEnq ( *tp );
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoEnq failed, "
+ "l_rc[0x%08X]", l_rc);
+ // @TODO RTC via : 132295
+ // RC refactoring - reserve 3 bits in SBE RC for PCBPIB
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ ++l_len;
+
+ } while(l_len<io_len);
+
+ io_len = l_len;
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////
+void sbeBuildMinRespHdr ( uint32_t *io_pBuf,
+ uint32_t &io_curIndex,
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus,
+ const uint32_t i_pcbpibStatus,
+ const uint32_t i_startIndex )
+{
+ do
+ {
+ if (!io_pBuf)
+ {
+ break;
+ }
+
+ io_pBuf[io_curIndex] = sbeBuildRespHeaderMagicCodeCmdClass();
+ io_pBuf[++io_curIndex] = sbeBuildRespHeaderStatusWordLocal(
+ i_primStatus, i_secStatus);
+
+ // Pcb-Pib error is optional,
+ // not needed for success case
+ if ( (i_primStatus != SBE_PRI_OPERATION_SUCCESSFUL) ||
+ (i_pcbpibStatus != SBE_PCB_PIB_ERROR_NONE) )
+ {
+ io_pBuf[++io_curIndex] = i_pcbpibStatus;
+ }
+
+ // Somehow this compiler isn't allowing the
+ // index pre-increment for the last array entry
+ // directly embedded into the assignment
+ ++io_curIndex;
+ io_pBuf[io_curIndex] = io_curIndex - i_startIndex + 1;
+
+ } while(false);
+}
+
+////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////
+uint32_t sbeDownFifoSignalEot (void)
+{
+ uint32_t l_rc = 0;
+ #define SBE_FUNC "sbeDownFifoSignalEot "
+ SBE_ENTER(SBE_FUNC);
+ sbeDownFifoStatusReg_t l_status = {0};
+ do
+ {
+ // Read the down stream FIFO status
+ l_rc = sbeDownFifoGetStatus (reinterpret_cast<uint64_t *>(&l_status));
+ if (l_rc)
+ {
+ // Error while reading downstream FIFO status
+ SBE_ERROR(SBE_FUNC"sbeDownFifoGetStatus failed, "
+ "l_rc=[0x%08X]", l_rc);
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ // Check if downstream FIFO is full
+ if (l_status.downfifo_status.fifo_full)
+ {
+ pk_sleep(PK_MILLISECONDS(FIFO_WAIT_SLEEP_TIME));
+ continue;
+ }
+ l_rc = putscom_abs(SBE_DOWNSTREAM_FIFO_SIGNAL_EOT, DOWNSTREAM_EOT_DATA);
+ break;
+ } while(1);
+
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+uint32_t sbeDsSendRespHdr(const sbeRespGenHdr_t &i_hdr,
+ const sbeResponseFfdc_t &i_ffdc )
+{
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ do
+ {
+ uint32_t distance = 1; //initialise by 1 for entry count itself.
+ uint32_t len = sizeof( i_hdr )/sizeof(uint32_t);
+ // sbeDownFifoEnq_mult.
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &i_hdr);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+
+ // If no ffdc , exit;
+ if( i_ffdc.getRc() )
+ {
+ len = sizeof(i_ffdc)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &i_ffdc);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+ }
+
+ // If there is a SBE internal failure
+ if((i_hdr.primaryStatus != SBE_PRI_OPERATION_SUCCESSFUL) ||\
+ (i_hdr.secondaryStatus != SBE_SEC_OPERATION_SUCCESSFUL))
+ {
+ //Add FFDC data as well.
+ //Generate all the fields of FFDC package
+ SbeFFDCPackage sbeFfdc;
+ rc = sbeFfdc.sendOverFIFO(i_hdr.primaryStatus,
+ i_hdr.secondaryStatus,
+ SBE_FFDC_ALL_DUMP,
+ len);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+ }
+
+ len = sizeof(distance)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, &distance);
+ if (rc)
+ {
+ break;
+ }
+
+ }while(0);
+ return rc;
+}
diff --git a/src/sbefw/sbeFifoMsgUtils.H b/src/sbefw/sbeFifoMsgUtils.H
new file mode 100644
index 00000000..60492964
--- /dev/null
+++ b/src/sbefw/sbeFifoMsgUtils.H
@@ -0,0 +1,192 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeFifoMsgUtils.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeFifoMsgUtils.H
+ *
+ * @brief This file contains the SBE FIFO Access Common Utility Functions
+ *
+ */
+
+#ifndef __SBEFW_SBEFIFOMSGUTILS_H
+#define __SBEFW_SBEFIFOMSGUTILS_H
+
+#include <stdint.h>
+#include "sbeexeintf.H"
+
+
+/**********************************************************************/
+// SBE Utilities
+/**********************************************************************/
+
+/**
+ * @brief sbeUpFifoDeq_mult : Dequeue multiple entries from upstream FIFO
+ *
+ * @param[in/out] io_len
+ * On input: Non-zero number of entries (excluding EOT) to dequeue.
+ * Ignored when i_flush == true.
+ * On output: Number of entries dequeued (excluding EOT).
+ * @param[out] o_pData Entries dequeued into the buffer
+ * @param[in] i_isEotExpected true / false
+ * true - Default case.
+ * Caller expects an EOT entry after io_len entries are
+ * dequeued. Accordingly, this function will attempt to dequeue
+ * the EOT entry after io_len entries are dequeued.
+ * false - Caller doesn't expect an EOT after io_len entries are
+ * dequeued. Accordingly, this function will not attempt to
+ * dequeue the EOT entry after io_len entries are dequeued.
+ * @param[in] i_flush true / false
+ * true - caller requested FIFO flush
+ * Usually caller marks this flag as true to handle error scenario.
+ * All entries written in the US fifo (until an EOT is encountered),
+ * would be dequeued and discarded (not processed). Note that io_len
+ * and i_isEotExpected inputs are ignored in this case.
+ * However, flag i_isEotExpected is always interpreted as true in
+ * case.
+ * false - Default good path.
+ * US Fifo entries will be dequeued and processed per inputs io_len
+ * and i_isEotExpected.
+ *
+ * @return Return Code SUCCESS or a secondary response code
+ * SBE_SEC_OPERATION_SUCCESSFUL
+ * SBE_SEC_FIFO_ACCESS_FAILURE
+ * SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA
+ * SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA
+ * SBE_FIFO_RESET_RECEIVED
+ *
+ */
+extern uint32_t sbeUpFifoDeq_mult (uint32_t &io_len,
+ uint32_t *o_pData,
+ const bool i_isEotExpected = true,
+ const bool i_flush = false);
+
+
+/**
+ * @brief sbeDownFifoEnq_mult : Enqueue into downstream FIFO
+ *
+ * @param[in/out] io_len number of entries to enqueue as input,
+ * number of entries enqueued as output
+ * @param[in] i_pData buffer containting data to be enqueued
+ *
+ * @return Rc SUCCESS or a secondary response code
+ * SBE_SEC_OPERATION_SUCCESSFUL
+ * SBE_SEC_FIFO_ACCESS_FAILURE
+ * SBE_FIFO_RESET_RECEIVED
+ *
+ */
+extern uint32_t sbeDownFifoEnq_mult (uint32_t &io_len,
+ const uint32_t *i_pData) ;
+
+
+/**
+ * @brief sbeBuildRespHeaderMagicCodeCmdClass
+ * Builds the header word containing the magic code,
+ * the command class and the opcode
+ *
+ * @return Returns the header word in the response header
+ * containing the magic code, command class and opcode
+ *
+ */
+extern inline uint32_t sbeBuildRespHeaderMagicCodeCmdClass (void)
+{
+ return ( (0xC0DE0000) |
+ (uint32_t)(g_sbeFifoCmdHdr.cmdClass << 8) |
+ (uint32_t)(g_sbeFifoCmdHdr.command));
+}
+
+/**
+ * @brief sbeBuildRespHeaderStatusWordGlobal
+ * Builds the status header word from global variables
+ *
+ * @return Returns the status word in the response header
+ *
+ */
+extern inline uint32_t sbeBuildRespHeaderStatusWordGlobal (void)
+{
+ return ( (((uint32_t)g_sbeCmdRespHdr.prim_status)<<16) |
+ (g_sbeCmdRespHdr.sec_status) );
+}
+
+/**
+ * @brief sbeBuildRespHeaderStatusWordLocal
+ * Builds the status header word from passed in parameters
+ *
+ * @param[in] const uint16_t i_primStatus Primary Response Status Code
+ * @param[in] const uint16_t i_secStatus Secondary Response Status Code
+ *
+ * @return Returns the status word in the response header
+ *
+ */
+extern inline uint32_t sbeBuildRespHeaderStatusWordLocal (
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus)
+{
+ return ( (((uint32_t)i_primStatus)<<16) | (i_secStatus) );
+}
+
+/**
+ * @brief sbeBuildMinRespHdr : Builds minimum response header
+ *
+ * @desc This builds the buffer with the following status words
+ * - Magic Bytes, Command Class, Command opcode
+ * - Primary Status Code, Secondary Status Code
+ * - PCB / PIB Status Code [optional]
+ * - Distance to Status Header
+ * @param[in/out] uint32_t *io_pBuf Buffer to be filled in
+ * @param[in/out] uint32_t &io_curIndex Current Index into the buffer
+ * @param[in] const uint16_t i_primStatus Primary Response Status Code
+ * @param[in] const uint16_t i_secStatus Secondary Response Status Code
+ * @param[in] const uint32_t i_pcbpibStatus PCB-PIB Response Status Code
+ * @param[in] const uint32_t i_startIndex Starting Index into the buffer
+ */
+
+void sbeBuildMinRespHdr ( uint32_t *io_pBuf,
+ uint32_t &io_curIndex,
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus,
+ const uint32_t i_pcbpibStatus,
+ const uint32_t i_startIndex = 0 );
+
+/**
+ * @brief sbeDownFifoSignalEot : Signal EOT in Downstream FIFO
+ *
+ * @return Rc from the underlying scom utility
+ *
+ * @note This is a blocking call. If FIFO is full, it will wait
+ * in loop ( sleep ) till the time there is some space in
+ * FIFO.
+ */
+uint32_t sbeDownFifoSignalEot (void);
+
+/**
+ * @brief sbeDsSendRespHdr : Send response header to DS FIFO
+ * - This also sends the FFDC if exist.
+ *
+ * @param[in] i_hdr Response Header
+ * @param[in] i_ffdc FFDC object
+ *
+ * @return Rc from the underlying scom utility
+ */
+uint32_t sbeDsSendRespHdr(const sbeRespGenHdr_t &i_hdr,
+ const sbeResponseFfdc_t &i_ffdc );
+#endif // __SBEFW_SBEFIFOMSGUTILS_H
diff --git a/src/sbefw/sbeHostMsg.H b/src/sbefw/sbeHostMsg.H
new file mode 100644
index 00000000..3467d59c
--- /dev/null
+++ b/src/sbefw/sbeHostMsg.H
@@ -0,0 +1,132 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeHostMsg.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeHostMsg.H
+ *
+ * @brief This file contains the message structures for SBE Host
+ * communication.
+ *
+ */
+
+#ifndef __SBEFW_SBEHOST_MSG_H
+#define __SBEFW_SBEHOST_MSG_H
+
+#include <stdint.h>
+#include "sbe_host_intf.H"
+#include "sbe_sp_intf.H"
+
+/*****************************************************************/
+/* SBE->PSU request structures */
+/*****************************************************************/
+
+/**
+ * @brief structure for Host->SBE command request format denoting
+ * mininum header (as of now, contained in mbx 0)
+ */
+typedef struct
+{
+ // mbxReg0
+ uint64_t res:16;
+ uint64_t flags:16;
+ uint64_t seqID:16;
+ uint64_t cmdClass:8;
+ uint64_t command:8;
+
+ /**
+ * @brief initialize the fields contained in PSU Mbx0
+ *
+ */
+ void init()
+ {
+ res = 0;
+ flags = 0;
+ seqID = 0;
+ cmdClass = SBE_PSU_CMD_CLASS_UNKNOWN;
+ command = SBE_PSU_CMD_UNKNOWN;
+ }
+} sbePsu2SbeCmdReqHdr_t;
+
+extern sbePsu2SbeCmdReqHdr_t g_sbePsu2SbeCmdReqHdr;
+
+
+/*****************************************************************/
+/* SBE->PSU response structures */
+/*****************************************************************/
+
+/**
+ * @brief SBE->Host Generic response structure
+ *
+ */
+typedef struct
+{
+ uint64_t mbxReg4;
+ uint64_t mbxReg5;
+ uint64_t mbxReg6;
+ uint64_t mbxReg7;
+} sbeSbe2PsuGenericResp_t ;
+
+/**
+ * @brief Structure for SBE->Host response header contained in
+ * mbx4 register
+ *
+ */
+typedef struct
+{
+ // mbxReg 4
+ uint64_t primStatus:16;
+ uint64_t secStatus:16;
+ uint64_t seqID:16;
+ uint64_t cmdClass:8;
+ uint64_t command:8;
+
+ /**
+ * @brief set the primary and secondary status
+ *
+ * @param[in] i_prim Primary status
+ * @param[in] i_sec Secondary status
+ *
+ */
+ void setStatus(const uint16_t i_prim, const uint16_t i_sec)
+ {
+ primStatus = i_prim;
+ secStatus = i_sec;
+ }
+
+ /**
+ * @brief initialize the response fields contained in PSU Mbx3
+ *
+ */
+ void init()
+ {
+ primStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ secStatus = SBE_SEC_OPERATION_SUCCESSFUL;
+ seqID = g_sbePsu2SbeCmdReqHdr.seqID;
+ cmdClass = g_sbePsu2SbeCmdReqHdr.cmdClass;
+ command = g_sbePsu2SbeCmdReqHdr.command;
+ }
+} sbeSbe2PsuRespHdr_t;
+
+extern sbeSbe2PsuRespHdr_t g_sbeSbe2PsuRespHdr;
+
+#endif // __SBEFW_SBEHOST_MSG_H
diff --git a/src/sbefw/sbeHostUtils.C b/src/sbefw/sbeHostUtils.C
new file mode 100644
index 00000000..3e4605d0
--- /dev/null
+++ b/src/sbefw/sbeHostUtils.C
@@ -0,0 +1,226 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeHostUtils.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeHostUtils.C
+ *
+ * @brief This file contains the PSU Access Utility Functions
+ *
+ */
+
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeHostUtils.H"
+#include "sbeHostMsg.H"
+#include "sbe_host_intf.H"
+#include "sbeerrorcodes.H"
+#include "assert.h"
+#include "fapi2.H"
+
+
+///////////////////////////////////////////////////////////////////
+// PSU->SBE register access utilities
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+uint32_t sbeReadPsu2SbeMbxReg (uint32_t i_addr,
+ const uint8_t i_count,
+ uint64_t *o_pData,
+ bool i_isFinalRead)
+{
+ #define SBE_FUNC " sbeReadPsu2SbeMbxReg "
+ SBE_DEBUG(SBE_FUNC"i_count[0x%02X], i_addr=[0x%08X]", i_count, i_addr);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint8_t l_count = 0;
+
+ assert((i_count >0 ) && (NULL != o_pData))
+ assert( (SBE_HOST_PSU_MBOX_REG0 <= i_addr) &&
+ (SBE_HOST_PSU_MBOX_REG3 >= (i_addr + i_count - 1)) )
+
+ while (l_count < i_count)
+ {
+ l_rc = getscom_abs ( i_addr,
+ reinterpret_cast<uint64_t*>(&o_pData[l_count]) );
+
+ if (l_rc)
+ {
+ // Error while reading from PSU->SBE mbx register
+ SBE_ERROR(SBE_FUNC"getscom_abs failed,"
+ "l_rc=[0x%08X], i_addr=[0x%08X]",
+ l_rc, i_addr);
+ break;
+ }
+
+ SBE_DEBUG(SBE_FUNC"l_data=[0x%08X%08X]",
+ SBE::higher32BWord(o_pData[l_count]),
+ SBE::lower32BWord(o_pData[l_count]));
+ ++l_count;
+ ++i_addr;
+ }
+
+ // Set the Ack bit in SBE->PSU DB register
+ // if the message requires ack and if its a final read operation
+ if ((i_isFinalRead) && (SBE_SEC_OPERATION_SUCCESSFUL == l_rc))
+ {
+ l_rc = sbeAcknowledgeHost();
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed to Sent Ack to Host over "
+ "SBE_SBE2PSU_DOORBELL_SET_BIT1");
+ }
+ }
+ return l_rc;
+
+ #undef SBE_FUNC
+}
+
+///////////////////////////////////////////////////////////////////
+// SBE->PSU register access utilities
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+uint32_t sbeIntrHostUponRespWaiting ()
+{
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Interrupt the host by setting bit0 in SBE->PSU DB register
+ // if the caller requested for it.
+ if (g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_RESP_REQUIRED)
+ {
+ l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT0);
+ }
+ return l_rc;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+uint32_t sbeAcknowledgeHost ()
+{
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Set the Ack bit in SBE->PSU DB register
+ // if the caller requested for it.
+ if (g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_ACK_REQUIRED)
+ {
+ l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT1);
+ }
+ return l_rc;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+uint32_t sbeWriteSbe2PsuMbxReg (uint32_t i_addr,
+ const uint64_t *i_pData,
+ const uint8_t i_count,
+ bool i_setBit0ToIntrHB)
+{
+ #define SBE_FUNC " sbeWriteSbe2PsuMbxReg "
+ SBE_DEBUG(SBE_FUNC"i_count[0x%02X], i_addr=[0x%08X]", i_count, i_addr);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint8_t l_count = 0;
+
+ assert( (i_count >0 ) && (NULL != i_pData) )
+ assert( (SBE_HOST_PSU_MBOX_REG4 <= i_addr) &&
+ (SBE_HOST_PSU_MBOX_REG7 >= (i_addr + i_count - 1)) )
+
+ if( g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_RESP_REQUIRED )
+ {
+ while (l_count < i_count)
+ {
+ SBE_DEBUG(SBE_FUNC"l_data=[0x%08X%08X]",
+ SBE::higher32BWord(*(i_pData+l_count)),
+ SBE::lower32BWord(*(i_pData+l_count)));
+
+ l_rc = putscom_abs ( i_addr, *(i_pData+l_count) );
+ if (l_rc)
+ {
+ // Error while reading from PSU->SBE mbx register
+ SBE_ERROR(SBE_FUNC"putscom_abs failed,"
+ "l_rc=[0x%08X], i_addr=[0x%08X]",
+ l_rc, i_addr);
+ break;
+ }
+
+ ++l_count;
+ ++i_addr;
+ }
+
+ if( (i_setBit0ToIntrHB) && (SBE_SEC_OPERATION_SUCCESSFUL == l_rc) )
+ {
+ // indicate the Host via Bit SBE_SBE2PSU_DOORBELL_SET_BIT0
+ l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT0);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed to Sent Ack to Host over "
+ "SBE_SBE2PSU_DOORBELL_SET_BIT0");
+ }
+ }
+ }
+ return l_rc;
+
+ #undef SBE_FUNC
+}
+
+/* @brief - Send PSU Chip Op response
+ *
+ * @param[in] - i_sbe2PsuRespHdr - Response header
+ * @param[in] - i_fapiRc - fapi rc of the relevant hwp call
+ * @param[in/out] - io_rc - rc status of the PSU access utility
+ *
+ * @return - void
+ */
+void sbePSUSendResponse(sbeSbe2PsuRespHdr_t &i_sbe2PsuRespHdr,
+ uint32_t &i_fapiRc,
+ uint32_t &io_rc)
+{
+#define SBE_FUNC "sbePSUSendResponse"
+ do
+ {
+ // Making sure the PSU access utility is functional
+ if(io_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ // TODO via RTC:151555 Generate FFDC
+ if(i_fapiRc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ i_sbe2PsuRespHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ }
+
+ // Send the response header
+ io_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ (uint64_t*)(&i_sbe2PsuRespHdr),
+ (sizeof(i_sbe2PsuRespHdr)/sizeof(uint64_t)),
+ true);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != io_rc)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to write to "
+ "SBE_HOST_PSU_MBOX_REG4");
+ }
+ } while(0);
+#undef SBE_FUNC
+}
diff --git a/src/sbefw/sbeHostUtils.H b/src/sbefw/sbeHostUtils.H
new file mode 100644
index 00000000..efca6bf4
--- /dev/null
+++ b/src/sbefw/sbeHostUtils.H
@@ -0,0 +1,244 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeHostUtils.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeHostUtils.H
+ *
+ * @brief This file contains basic SBE PSU hardware specific
+ * definitions and operations.
+ *
+ */
+
+#ifndef __SBEFW_SBEHOSTUTILS_H
+#define __SBEFW_SBEHOSTUTILS_H
+
+#include <stdint.h>
+#include "ppe42_scom.h"
+#include "sbeHostMsg.H"
+
+/**
+ * @brief SBE PSU Access register addresses
+ *
+ */
+const uint32_t SBE_HOST_PSU_BASE = 0x000D0050;
+
+const uint32_t SBE_HOST_PSU_MBOX_REG0 = SBE_HOST_PSU_BASE + 0x0000;
+const uint32_t SBE_HOST_PSU_MBOX_REG1 = SBE_HOST_PSU_BASE + 0x0001;
+const uint32_t SBE_HOST_PSU_MBOX_REG2 = SBE_HOST_PSU_BASE + 0x0002;
+const uint32_t SBE_HOST_PSU_MBOX_REG3 = SBE_HOST_PSU_BASE + 0x0003;
+const uint32_t SBE_HOST_PSU_MBOX_REG4 = SBE_HOST_PSU_BASE + 0x0004;
+const uint32_t SBE_HOST_PSU_MBOX_REG5 = SBE_HOST_PSU_BASE + 0x0005;
+const uint32_t SBE_HOST_PSU_MBOX_REG6 = SBE_HOST_PSU_BASE + 0x0006;
+const uint32_t SBE_HOST_PSU_MBOX_REG7 = SBE_HOST_PSU_BASE + 0x0007;
+
+
+const uint32_t SBE_PSU2SBE_DOORBELL_REG_RW = 0x000D0060;
+const uint32_t SBE_PSU2SBE_DOORBELL_REG_AND = 0x000D0061;
+const uint32_t SBE_PSU2SBE_DOORBELL_REG_OR = 0x000D0062;
+const uint32_t SBE_PSU2HOST_DOORBELL_REG_RW = 0x000D0063;
+const uint32_t SBE_PSU2HOST_DOORBELL_REG_AND = 0x000D0064;
+const uint32_t SBE_PSU2HOST_DOORBELL_REG_OR = 0x000D0065;
+
+
+/**
+ * @brief SBE PSU door bell register Bit definitions
+ */
+typedef enum
+{
+ // Bit 0 AND flag for PSU->SBE Doorbell Register;
+ // When this is set by the host firmware, it would trigger an
+ // interrupt to the SBE about a waiting message in the Host/SBE
+ // Mailbox Registers. SBE is responsible for clearing this
+ // bit upon being interrupted.
+ SBE_PSU2SBE_DOORBELL_CLEAR_BIT0 = 0x7FFFFFFFFFFFFFFFull,
+} sbe_psu2sbeDoorbellReg_UpdateFlags;
+
+typedef enum
+{
+ // Bit 0 OR flag for SBE->PSU Doorbell Register;
+ // When this is set by SBE, it would trigger an interrupt to host
+ // firmware about a waiting response in the Host/SBE Mailbox Registers 4-7
+ SBE_SBE2PSU_DOORBELL_SET_BIT0 = 0x8000000000000000ull,
+
+ // Bit 1 OR flag for SBE->PSU Doorbell Register;
+ // When this is set by SBE, it would trigger an interrupt to host
+ // firmware indicating that the message in Host/SBE mailbox registers 0-3
+ // has been read by SBE and is being processed
+ SBE_SBE2PSU_DOORBELL_SET_BIT1 = 0x4000000000000000ull,
+
+ // Bit 2 OR flag for SBE->PSU Doorbell Register;
+ // When this is set by SBE, it would trigger an interrupt to host
+ // firmware to trigger Stop15 exit on thread 0 on the master core.
+ // This would be used to trigger hostboot in istep 16
+ SBE_SBE2PSU_DOORBELL_SET_BIT2 = 0x2000000000000000ull,
+} sbe_sbe2psuDoorbellReg_UpdateFlags;
+
+
+/*****************************************************************/
+/** PSU->SBE register access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeClearPsu2SbeDbBitX : Clear given bit in PSU->SBE DB register
+ *
+ * @param[in] 64-Bit Scom Data indicating bit position to be cleared
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeClearPsu2SbeDbBitX (const uint64_t i_bit)
+{
+ return putscom_abs (SBE_PSU2SBE_DOORBELL_REG_AND, i_bit) ;
+}
+
+
+/**
+ * @brief sbeReadPsu2SbeDbReg : Read PSU->SBE DB register
+ *
+ * @param[out] 64-Bit Data read from PSU->SBE DB register
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeReadPsu2SbeDbReg (uint64_t *o_data)
+{
+ return getscom_abs (SBE_PSU2SBE_DOORBELL_REG_RW, o_data) ;
+}
+
+
+/**
+ * @brief sbeReadPsu2SbeMbxReg : Read from PSU->SBE MBX register(s)
+ *
+ * @param[in] i_addr
+ * Starting Mbx Register Address
+ * @param[in] i_count
+ * Number of Mbx registers to be read.
+ * @param[in] i_isFinalRead
+ * Indicates if its a final read operation for this chip op and
+ * internally handle the ack
+ * By default it is false.
+ * @param[out] o_pData
+ * Contents of the Mbx registers read into the buffer
+ * @return Return Code
+ * SUCCESS or TBD
+ */
+uint32_t sbeReadPsu2SbeMbxReg (uint32_t i_addr,
+ const uint8_t i_count,
+ uint64_t *o_pData,
+ bool i_isFinalRead = false);
+
+/*****************************************************************/
+/** SBE->PSU register access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeSetSbe2PsuDbBitX : Set Bit-X in SBE->PSU DB register
+ *
+ * @param[in] 64-Bit Scom Data indicating bit position
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeSetSbe2PsuDbBitX (const uint64_t i_bit)
+{
+ return putscom_abs (SBE_PSU2HOST_DOORBELL_REG_OR, i_bit) ;
+}
+
+/**
+ * @brief sbeClearSbe2PsuDbBitX : Clear Bit-X in SBE->PSU DB register
+ *
+ * @param[in] 64-Bit Scom Data indicating bit position
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeClearSbe2PsuDbBitX (const uint64_t i_bit)
+{
+ return putscom_abs (SBE_PSU2HOST_DOORBELL_REG_AND, i_bit) ;
+}
+
+/**
+ * @brief sbeReadSbe2PsuDbReg : Read SBE->PSU DB register
+ *
+ * @param[out] 64-Bit Data read from SBE->PSU DB register
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+inline uint32_t sbeReadSbe2PsuDbReg (uint64_t *o_data)
+{
+ return getscom_abs (SBE_PSU2HOST_DOORBELL_REG_RW, o_data) ;
+}
+
+/**
+ * @brief sbeAcknowledgeHost : Acknowldge by setting bit 1 in
+ * SBE->PSU DB register if the host had requested for an ack
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+uint32_t sbeAcknowledgeHost();
+
+/**
+ * @brief sbeIntrHostUponRespWaiting : Interrupt Host by
+ * setting bit 0 in SBE->PSU DB register if the host had
+ * requested for response
+ *
+ * @return RC from the underlying scom utility
+ *
+ */
+uint32_t sbeIntrHostUponRespWaiting();
+
+
+/**
+ * @brief sbeWriteSbe2PsuMbxReg : Write to SBE->PSU MBX register(s)
+ *
+ * @param[in] i_addr
+ * Starting Mbx Register Address
+ * @param[in] i_pData
+ * Contains the data to be written into given Mbx registers
+ * @param[in] i_count
+ * Number of Mbx registers to be written.
+ * @param[in] i_setBit0ToIntrHB
+ * Indicates whether to write Bit0 to interrupt the Host,
+ * By default it is false.
+ * @return Return Code
+ * SUCCESS or TBD
+ */
+uint32_t sbeWriteSbe2PsuMbxReg (uint32_t i_addr,
+ const uint64_t *i_pData,
+ const uint8_t i_count,
+ bool i_setBit0ToIntrHB = false);
+
+/* @brief - Send PSU Chip Op response
+ *
+ * @param[in] - i_sbe2PsuRespHdr - Response header
+ * @param[in] - i_fapiRc - fapi rc of the relevant hwp call
+ * @param[in/out] - io_rc - rc status of the PSU access utility
+ *
+ * @return - void
+ */
+void sbePSUSendResponse(sbeSbe2PsuRespHdr_t &i_sbe2PsuRespHdr,
+ uint32_t &i_fapiRc,
+ uint32_t &io_rc);
+#endif // __SBEFW_SBEHOSTUTILS_H
diff --git a/src/sbefw/sbeSpMsg.H b/src/sbefw/sbeSpMsg.H
new file mode 100644
index 00000000..c1b972bf
--- /dev/null
+++ b/src/sbefw/sbeSpMsg.H
@@ -0,0 +1,634 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeSpMsg.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeSpMsg.H
+ *
+ * @brief This file contains the message structures for FIFO
+ * communication.
+ *
+ */
+
+#ifndef __SBEFW_SBESP_MSG_H
+#define __SBEFW_SBESP_MSG_H
+
+#include "sbe_sp_intf.H"
+
+// @NOTE Make sure all FIFO structures are 32 bit alligned ( the largest
+// member should be atleast 4 byte). It is required as in sbe fifo
+// operation we are casting these structures to uint32_t pointer. It can
+// cause alignment issue if largest member of structure is not atleast
+// 32 bit. We can use bit fields to optimize memory requirements.
+// These are two coding guidleines we will follow for this file
+// 1. All data members less than 32 bits will be bit fields
+// 2. All data members more than 32 buts will be divided into small
+// members of 32 bit each. This is required as compiler pads structure
+// to largest data member and we do not want extra padding for data
+// members gretater than 32 bits ( e.g. uint64_t )
+/**
+ * @brief Command Request Header
+ */
+typedef struct
+{
+ uint32_t len;
+ uint32_t reserved:16;
+ uint32_t cmdClass:8;
+ uint32_t command:8;
+}sbeFifoCmdReqBuf_t;
+
+extern sbeFifoCmdReqBuf_t g_sbeFifoCmdHdr;
+
+/**
+ * @brief structure for generic header for fifo response.
+ *
+ */
+typedef struct
+{
+ uint32_t magicCode:16;
+ uint32_t cmdClass:8;
+ uint32_t command:8;
+ uint32_t primaryStatus:16;
+ uint32_t secondaryStatus:16;
+
+ /**
+ * @brief set the primary and secondary status
+ *
+ * @param[in] i_prim Primary status
+ * @param[in] i_sec Secondary status
+ *
+ * @return
+ */
+ void setStatus( const uint16_t i_prim, const uint16_t i_sec)
+ {
+ primaryStatus = i_prim;
+ secondaryStatus = i_sec;
+ }
+
+ /**
+ * @brief set initial values for response header
+ *
+ * @note We did not set this in constructor as based on use case
+ * it is possible that g_sbeFifoCmdHdr does not have proper
+ * values at time of object creation.
+ *
+ */
+ void init()
+ {
+ magicCode = 0xC0DE;
+ cmdClass = g_sbeFifoCmdHdr.cmdClass;
+ command = g_sbeFifoCmdHdr.command;
+ primaryStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ secondaryStatus = SBE_SEC_OPERATION_SUCCESSFUL;
+ }
+
+}sbeRespGenHdr_t;
+
+/**
+ * @brief structure for generic Resp header with Len for fifo response.
+ *
+ */
+typedef struct
+{
+ uint32_t respLen;
+ sbeRespGenHdr_t respHdr;
+
+ /**
+ * @brief set response length
+ *
+ * @param[in] i_len Length
+ *
+ * @return
+ */
+ void setLength( const uint32_t i_len )
+ {
+ respLen = i_len;
+ }
+
+ /**
+ * @brief set initial values for response header
+ *
+ * @note We did not set this in constructor as based on use case
+ * it is possible that g_sbeCmdHdr does not have proper
+ * values at time of object creation.
+ *
+ */
+ void init()
+ {
+ respHdr.init();
+ }
+}sbeRespGenHdrWithLen_t;
+
+
+/**
+ * @brief structure for ffdc header for fifo response.
+ *
+ */
+typedef struct sbeResponseFfdc
+{
+ uint32_t magicBytes:16;
+ uint32_t lenInWords:16; // length in word( 4 byte )
+ uint32_t fapiRc;
+
+ /**
+ * @brief set rc
+ *
+ * @param[in] i_rc FAPI RC
+ *
+ * @return
+ */
+ void setRc(const uint32_t i_rc)
+ {
+ fapiRc = i_rc;
+ }
+
+ /**
+ * @brief return fapiRc
+ *
+ * @return fapiRc
+ */
+ uint32_t getRc() const
+ {
+ return fapiRc;
+ }
+
+ /**
+ * @brief constructor
+ *
+ * @param[in] i_rc FAPI RC
+ *
+ * @return
+ */
+ sbeResponseFfdc()
+ {
+ magicBytes = 0xFFDC;
+ //TODO via 129076.
+ //Need to change value for length once FFDC design is final.
+ lenInWords = ( sizeof(uint32_t ) // For magicBytes + lenInWords
+ + sizeof(fapiRc))
+ / sizeof(uint32_t);
+ fapiRc = 0;
+ }
+}sbeResponseFfdc_t;
+
+/**
+ * @brief structure for execute istep chipop (0xA101) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t reserved1:8;
+ uint32_t major:8;
+ uint32_t reserved2:8;
+ uint32_t minor:8;
+}sbeIstepReqMsg_t;
+
+
+/**
+ * @brief structure for GetScom Chipop (0xA201) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t hiAddr;
+ uint32_t lowAddr;
+}sbeGetScomReqMsg_t;
+
+/**
+ * @brief structure for PutScom Chipop (0xA202) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t hiAddr;
+ uint32_t lowAddr;
+ uint32_t hiInputData;
+ uint32_t lowInputData;
+
+ /**
+ * @brief return 64-bit Scom data
+ *
+ * @return 64-bit Scom data
+ */
+ uint64_t getScomData()
+ {
+ uint64_t data = ((uint64_t)hiInputData << 32) | lowInputData;
+ return data;
+ }
+}sbePutScomReqMsg_t;
+
+/**
+ * @brief structure for Modify_Scom Chipop (0xA203) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t reserved:24;
+ uint32_t opMode:8;
+ uint32_t hiAddr;
+ uint32_t lowAddr;
+ uint32_t hiInputData;
+ uint32_t lowInputData;
+
+ /**
+ * @brief return 64-bit modifying data
+ *
+ * @return 64-bit modifying data
+ */
+ uint64_t getModifyingData()
+ {
+ uint64_t data = ((uint64_t)hiInputData << 32) | lowInputData;
+ return data;
+ }
+}sbeModifyScomReqMsg_t;
+
+/**
+ * @brief structure for PutScom_UnderMask Chipop (0xA204) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t hiAddr;
+ uint32_t lowAddr;
+ uint32_t hiInputData;
+ uint32_t lowInputData;
+ uint32_t hiMaskData;
+ uint32_t lowMaskData;
+
+ /**
+ * @brief return 64-bit input data
+ *
+ * @return 64-bit input data
+ */
+ uint64_t getInputData()
+ {
+ uint64_t data = ((uint64_t)hiInputData << 32) | lowInputData;
+ return data;
+ }
+
+ /**
+ * @brief return 64-bit input mask
+ *
+ * @return 64-bit input mask
+ */
+ uint64_t getInputMask()
+ {
+ uint64_t data = ((uint64_t)hiMaskData << 32) | lowMaskData;
+ return data;
+ }
+
+ /**
+ * @brief Determines 64-bit Scom data
+ *
+ * @param[in/out] io_scomData 64-bit scom data
+ */
+ void getScomData(uint64_t &io_scomData)
+ {
+ uint64_t l_inputMask = getInputMask();
+ uint64_t l_inputData = getInputData();
+ io_scomData = (io_scomData & (~l_inputMask))
+ | (l_inputData & l_inputMask);
+ }
+}sbePutScomUnderMaskReqMsg_t;
+
+/**
+ * @brief Structure for SBE Memory Access ChipOps (0xA401/A402)
+ *
+ */
+typedef struct
+{
+ uint32_t coreChipletId:8; //Pervasive Core Chiplet Id for PBA
+ uint32_t eccByte:8; //Ecc Override Byte from user
+ uint32_t flags:16; //Operational Flags -refer enum sbeMemoryAccessFlags
+ uint32_t addrHi; //Higher 32-Bit Memory Address
+ uint32_t addrLo; //Lower 32-Bit Memory Address
+ uint32_t len; //Length of Data in Bytes
+
+ /**
+ * @brief Calculates 64-bit PBA ADU Address
+ *
+ * @return Return 64-bit PBA ADU address
+ */
+ uint64_t getAddr() const
+ {
+ return (((uint64_t)addrHi << 32) | addrLo);
+ }
+
+ /**
+ * @brief Determines if ECC Override bit is set
+ *
+ * @return Returns True if ECC Override bit is set
+ * False if ECC Override bit is not set
+ */
+ bool isEccOverrideFlagSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_ECC_OVERRIDE) ? true : false);
+ }
+
+ /**
+ * @brief Determines if ECC required bit is set
+ *
+ * @return Returns True if ECC required flag is set
+ * False if ECC required flag is not set
+ */
+ bool isEccFlagSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_ECC_REQUIRED) ? true : false);
+ }
+
+ /**
+ * @brief Determines if Itag required bit is set
+ *
+ * @return Returns True if Itag required flag is set
+ * False if Itag required flag is not set
+ */
+ bool isItagFlagSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_ITAG) ? true : false);
+ }
+
+ /**
+ * @brief Determines if Cache Inhibited mode is set
+ *
+ * @return Returns True if Cache Inhibited Mode flag is set
+ * False if Cache Inhibited Mode flag is not set
+ */
+ bool isCacheInhibitModeFlagSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_CACHE_INHIBIT) ? true : false);
+ }
+
+ /**
+ * @brief Determines if PBA flag is set
+ *
+ * @return Returns True if PBA Flag is set
+ * False if PBA flag is not set
+ */
+ bool isPbaFlagSet()
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_TARGET_PBA) ? true : false);
+ }
+
+ /**
+ * @brief Determines if Auto Increment Mode is set
+ *
+ * @return Returns True if Auto Increment mode is set
+ * False if Auto Increment is not set
+ */
+ bool isAutoIncrModeSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_AUTO_INCR_ON) ? true : false);
+ }
+
+ /**
+ * @brief Determines if Fast Mode is set
+ *
+ * @return Returns True if Fast mode is set
+ * False if Fast mode is not set
+ */
+ uint32_t isFastModeSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON) ? true : false);
+ }
+
+ /**
+ * @brief Determines if LCO Mode is set
+ *
+ * @return Returns True if LCO mode is set
+ * False if LCO mode is not set
+ */
+ uint32_t isPbaLcoModeSet() const
+ {
+ return ((flags & SBE_MEM_ACCESS_FLAGS_LCO_ENABLED) ? true : false);
+ }
+
+ /**
+ * @brief Calculates Data length in alignment with PBA/ADU Cacheline
+ * (128B/8B respectively)
+ *
+ * @return Returns Data length in alignment with PBA/ADU Cacheline
+ */
+ uint64_t getDataLenCacheAlign() const
+ {
+ uint64_t l_len = (len / 8);
+ if(flags & SBE_MEM_ACCESS_FLAGS_TARGET_PBA)
+ {
+ l_len = (l_len / 16);
+ }
+ return l_len;
+ }
+
+}sbeMemAccessReqMsgHdr_t;
+
+/**
+ * @brief Structure for SBE OCC Get/Put Sram Access ChipOps (0xA403/A404)
+ */
+typedef struct
+{
+ uint32_t reserved:24; // Not used
+ sbeSramAccessMode mode:8; // Channel select 0-3
+ uint32_t addr; // 32-Bit Memory Address
+ uint32_t len; // Length of Data in Bytes
+}sbeOccSramAccessReqMsgHdr_t;
+
+// Maximum number of capabilities
+static const uint32_t SBE_MAX_CAPABILITIES = 18;
+
+/**
+ * @brief structure for SBE Get Capabilities chipop (0xA802) contents.
+ *
+ */
+typedef struct sbeCapabilityRespMsg
+{
+ uint32_t verMajor:16;
+ uint32_t verMinor:16;
+ uint32_t fwCommitId;
+ uint32_t capability[SBE_MAX_CAPABILITIES];
+ // ctor. constructor will initialise all values.
+ sbeCapabilityRespMsg();
+}sbeCapabilityRespMsg_t;
+
+// TODO via RTC 128658
+// We may be able to replace this structure by sbeRespGenHdr_t
+
+/**
+ * @brief Command response structure to hold the primary and secondary
+ * status values. This will be utilized when a command class
+ * validation or state machine check fails.
+ *
+ */
+typedef struct
+{
+ uint32_t prim_status:16 ; // Primary Response Status
+ uint32_t sec_status:16 ; // Secondary Response Status
+
+ /**
+ * @brief initialize the response status
+ **/
+ void init()
+ {
+ prim_status = SBE_PRI_OPERATION_SUCCESSFUL;
+ sec_status = SBE_SEC_OPERATION_SUCCESSFUL;
+ }
+
+ /**
+ * @brief set the primary and secondary status
+ *
+ * @param[in] i_prim Primary status
+ * @param[in] i_sec Secondary status
+ *
+ **/
+ void setStatus(const uint16_t i_prim, const uint16_t i_sec)
+ {
+ prim_status = i_prim;
+ sec_status = i_sec;
+ }
+} sbeCmdRespHdr_t;
+
+extern sbeCmdRespHdr_t g_sbeCmdRespHdr;
+
+/**
+ * @brief structure for Control Instruction Chipop (0xA701) contents.
+ *
+ */
+typedef struct
+{
+ uint32_t reserved:12;
+ sbeErrorMode mode:4;
+ sbeCoreChipletId coreChipletId:8;
+ sbeThreadNum threadNum:4;
+ sbeThreadOps threadOps:4;
+
+ /**
+ * @brief Validate input arguments
+ *
+ * @return bool, true if the validation is success, else false for
+ * validation failure
+ */
+ bool validateInputArgs()
+ {
+ bool l_validatePassFlag = true;
+ // Validate Thread Command / Thread Num / Error Mode
+ if((threadOps > THREAD_SRESET_INS) ||
+ (mode > IGNORE_HW_ERRORS) ||
+ !((threadNum <= SMT4_THREAD3) || (threadNum == SMT4_THREAD_ALL)))
+ {
+ SBE_ERROR(SBE_FUNC "Invalid Parameter by User, ThreadOps[%d] "
+ "mode[%d] ThreadNum[%d]", threadOps, mode, threadNum);
+ l_validatePassFlag = false;
+ }
+ return l_validatePassFlag;
+ }
+
+ /**
+ * @brief Process the input to find out core/thread ids to iterate
+ * over HWP for the internal business logic
+ *
+ * @param[out] o_core, Core Id to start with in the iteration
+ * @param[out] o_coreCntMax, Core Max count to iterate, start from o_core
+ * @param[out] o_threadCnt, Thread Num to start with in the iteration
+ * @param[out] o_threadCntMax, Thread Max Num to iterate, start from
+ * o_threadCnt
+ *
+ * @return void
+ */
+ void processInputDataToIterate(uint8_t & o_core, uint8_t & o_coreCntMax,
+ uint8_t & o_threadCnt, uint8_t & o_threadCntMax)
+ {
+ //Default Init
+ o_threadCnt = SMT4_THREAD0;
+ o_threadCntMax = SMT4_THREAD_MAX;
+
+ o_core = SMT4_CORE0_ID;
+ o_coreCntMax = SMT4_CORE_ID_MAX;
+
+ if( SMT4_ALL_CORES != coreChipletId )
+ {
+ o_core = coreChipletId;
+ o_coreCntMax = coreChipletId;
+ }
+ if( SMT4_THREAD_ALL != threadNum )
+ {
+ o_threadCnt = threadNum;
+ o_threadCntMax = threadNum;
+ }
+ }
+}sbeCntlInstRegMsgHdr_t;
+
+/**
+ * @brief Get Ring access message header
+ */
+typedef struct
+{
+ uint32_t ringAddr;
+ uint32_t ringLenInBits;
+ uint32_t reserved:16;
+ uint32_t ringMode:16;
+}sbeGetRingAccessMsgHdr_t;
+
+/**
+ * @brief Reg access message header
+ */
+typedef struct
+{
+ uint32_t reserved:8;
+ uint32_t coreChiplet:8;
+ uint32_t threadNr:4;
+ uint32_t regType:4;
+ uint32_t numRegs:8;
+
+ /**
+ * @brief checks if it is valid request.
+ *
+ * @return true if valid request, false otherwise
+ */
+ bool isValidRequest() const
+ {
+ return (( SBE_REG_ACCESS_FPR >= regType )
+ &&( SBE_MAX_REG_ACCESS_REGS >= numRegs )
+ &&( SMT4_THREAD3 >= threadNr )
+ &&( SMT4_CORE0_ID <= coreChiplet )
+ &&( SMT4_CORE_ID_MAX >= coreChiplet )) ? true:false;
+ }
+}sbeRegAccessMsgHdr_t;
+
+/**
+ * @brief reg scom package
+ */
+typedef struct
+{
+ uint32_t regNr;
+ uint32_t hiData;
+ uint32_t lowData;
+
+ /**
+ * @brief data for a register.
+ *
+ * @return data.
+ */
+ uint64_t getData() const
+ {
+ return (((uint64_t)hiData << 32 ) | lowData );
+ }
+}sbeRegAccessPackage_t;
+
+#endif // __SBEFW_SBESP_MSG_H
diff --git a/src/sbefw/sbeXipUtils.H b/src/sbefw/sbeXipUtils.H
new file mode 100644
index 00000000..b9ce992e
--- /dev/null
+++ b/src/sbefw/sbeXipUtils.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeXipUtils.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 SBE_XIP_UTILS_H
+#define SBE_XIP_UTILS_H
+
+#include "p9_xip_image.h"
+#include "ppe42_scom.h" // for PPE_STVD
+#include "sbe_link.H" // for SBE_BASE_ORIGIN, SBE_SEEPROM_BASE_ORIGIN
+
+// Unconditional jump to a memory location
+#define JUMP_TO_ADDR(VAL ) \
+{ \
+asm volatile ( \
+ "mtlr %0 \n\t" \
+ : \
+ : "r" (VAL)); \
+asm volatile ( \
+ "blr \n\t" \
+ : \
+ );\
+}
+
+// PIBMEM start address
+const uint32_t g_pibMemAddr = SBE_BASE_ORIGIN;
+// SEEPROM start address
+const uint32_t g_headerAddr = SBE_SEEPROM_BASE_ORIGIN;
+// IVPR register address
+const uint32_t g_ivprLoc = 0xC0000160;
+
+// Get XIP image header
+inline P9XipHeader * getXipHdr()
+{
+ P9XipHeader *hdr = (P9XipHeader *)( g_headerAddr );
+ return hdr;
+}
+
+// Get Section start addess
+inline uint8_t * getSectionAddr( P9XipSection * i_section )
+{
+ return ( (uint8_t *)( g_headerAddr + i_section->iv_offset));
+}
+#endif // SBE_XIP_UTILS_H
diff --git a/src/sbefw/sbe_host_intf.H b/src/sbefw/sbe_host_intf.H
new file mode 100644
index 00000000..24658f16
--- /dev/null
+++ b/src/sbefw/sbe_host_intf.H
@@ -0,0 +1,89 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbe_host_intf.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbe_host_intf.H
+ *
+ * @brief This file contains the Host-SBE interface protocol common details
+ */
+
+#ifndef __SBEFW_SBE_HOST_INTF_H
+#define __SBEFW_SBE_HOST_INTF_H
+
+#include <stdint.h>
+
+/**
+ * $Version: Conforms to HOST-SBE Interface Spec v0.5a
+ */
+
+/*
+ * Constants for SBE FW major and minor number
+ */
+static const uint16_t SBE_SBEFW_HOST_MAJOR_VERSION = 1;
+static const uint16_t SBE_SBEFW_HOST_MINOR_VERSION = 0;
+
+/**
+ * @brief enums for SBE-Host interface command class
+ */
+enum sbePsuCommandClass
+ {
+ SBE_PSU_CMD_CLASS_UNKNOWN = 0,
+ SBE_PSU_CMD_CLASS_CORE_STATE = 0xD1,
+ SBE_PSU_CMD_CLASS_RING_ACCESS = 0xD3,
+ };
+
+/**
+ * @brief enums for SBE-Host interface core state control commands
+ */
+enum sbePsuCoreStateControlCommands
+{
+ SBE_PSU_CMD_CONTROL_DEADMAN = 0x01,
+ SBE_PSU_CMD_UNKNOWN = 0xFF,
+};
+
+/**
+ * @brief enums for SBE-Host interface ring access messages
+ */
+enum sbePsuRingAccessMessages
+{
+ SBE_PSU_MSG_PUT_RING_FROM_IMAGE = 0x01,
+ SBE_PSU_MSG_UNKNOWN = 0xFF,
+};
+
+/**
+ * @brief enums denoting control flags
+ *
+ */
+enum sbePsuControlFlags
+{
+ SBE_PSU_FLAGS_RESP_REQUIRED = 0x0100,
+ SBE_PSU_FLAGS_ACK_REQUIRED = 0x0200,
+};
+
+enum sbePsuDmtCmdFlags
+{
+ SBE_PSU_FLAGS_START_DMT = 0x0001,
+ SBE_PSU_FLAGS_STOP_DMT = 0x0002,
+};
+
+#endif // __SBEFW_SBE_HOST_INTF_H
diff --git a/src/sbefw/sbe_sp_intf.H b/src/sbefw/sbe_sp_intf.H
new file mode 100644
index 00000000..0734343d
--- /dev/null
+++ b/src/sbefw/sbe_sp_intf.H
@@ -0,0 +1,408 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbe_sp_intf.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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_sp_intf.H
+ *
+ * @brief This file contains the SP - SBE interface protocol common details
+ */
+
+#ifndef __SBEFW_SBE_SP_INTF_H
+#define __SBEFW_SBE_SP_INTF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * $Version: Conforms to SP-SBE Interface Spec v0.8e
+ */
+
+/*
+ * Constants for SBE FW major and minor number
+ */
+static const uint16_t SBE_FW_MAJOR_VERSION = 1;
+static const uint16_t SBE_FW_MINOR_VERSION = 1;
+
+/**
+ * @brief enums for SBE command classes
+ *
+*/
+enum sbeCommandClass
+{
+ SBE_CMD_CLASS_UNKNOWN = 0,
+ SBE_CMD_CLASS_IPL_CONTROL = 0xA1,
+ SBE_CMD_CLASS_SCOM_ACCESS = 0xA2,
+ SBE_CMD_CLASS_RING_ACCESS = 0xA3,
+ SBE_CMD_CLASS_MEMORY_ACCESS = 0xA4,
+ SBE_CMD_CLASS_REGISTER_ACCESS = 0xA5,
+ SBE_CMD_CLASS_ARRAY_ACCESS = 0xA6,
+ SBE_CMD_CLASS_INSTRUCTION_CONTROL = 0xA7,
+ SBE_CMD_CLASS_GENERIC_MESSAGE = 0xA8,
+ SBE_CMD_CLASS_MPIPL_COMMANDS = 0xA9,
+};
+
+/**
+ * @brief enums for SBE Istep Control command class
+ *
+*/
+enum sbeIplControlCommands
+{
+ SBE_CMD_EXECUTE_ISTEP = 0x01, /* Execute istep */
+ SBE_CMD_CONTINUE_BOOT = 0x02, /* Continue SBE Boot */
+};
+
+/**
+ * @brief enums for SCOM Access Messages
+ *
+*/
+enum sbeScomAccessCommands
+{
+ SBE_CMD_GETSCOM = 0x01, /* Get SCOM */
+ SBE_CMD_PUTSCOM = 0x02, /* Put SCOM */
+ SBE_CMD_MODIFYSCOM = 0x03, /* Modify SCOM */
+ SBE_CMD_PUTSCOM_MASK = 0x04, /* Put SCOM under mask */
+ SBE_CMD_MULTISCOM = 0x05, /* Execute Multi SCOM */
+};
+
+/**
+ * @brief enum for modify mode
+ *
+*/
+enum sbeChipOpModifyMode
+{
+ SBE_MODIFY_MODE_OR = 0x01,
+ SBE_MODIFY_MODE_AND = 0x02,
+ SBE_MODIFY_MODE_XOR = 0x03,
+};
+
+/**
+ * @brief enums for Ring Access Messages
+ *
+*/
+enum sbeRingAccessCommands
+{
+ SBE_CMD_GETRING = 0x01, /* Get Ring */
+ SBE_CMD_PUTRING = 0x02, /* Put Ring */
+};
+
+/**
+ * @brief enums for Memory Access Messages
+ *
+*/
+enum sbeMemoryAccesCommands
+{
+ SBE_CMD_GETMEM = 0x01, /* Get Memory (Proc/PBA) */
+ SBE_CMD_PUTMEM = 0x02, /* Put Memory (Proc/PBA) */
+ SBE_CMD_GETSRAM_OCC = 0x03, /* Get Memory (OCC SRAM) */
+ SBE_CMD_PUTSRAM_OCC = 0x04, /* Put Memory (OCC SRAM) */
+};
+
+/**
+ * @brief enums for GPR/SPR/FPR Access Messages
+ *
+*/
+enum sbeRegisterAccessCommands
+{
+ SBE_CMD_GETREG = 0x01, /* Get Register (GPR,SPR,FPR) */
+ SBE_CMD_PUTREG = 0x02, /* Put Register (GPR,SPR,FPR) */
+};
+
+/**
+ * @brief enums for Trace Array Access Messages
+ *
+*/
+enum sbeArrayAccessCommands
+{
+ SBE_CMD_GET_FAST_ARRAY = 0x01, /* Get Fast Array */
+ SBE_CMD_GET_TRACE_ARRAY = 0x02, /* Get Trace Array */
+ SBE_CMD_CONTROL_TRACE_ARRAY = 0x03, /* Control Trace Array */
+};
+
+/**
+ * @brief enums for Instruction Control Messages
+ *
+*/
+enum sbeInstructionControlCommands
+{
+ SBE_CMD_CONTROL_INSTRUCTIONS = 0x01, /* Control Instructions */
+};
+
+/**
+ * @brief enums for Generic Messages
+ *
+*/
+enum sbeGenericMessageCommands
+{
+ SBE_CMD_GET_SBE_FFDC = 0x01, /* Get FFDC */
+ SBE_CMD_GET_SBE_CAPABILITIES = 0x02, /* GET SBE capabilities */
+ SBE_CMD_GET_FREQ_SUPPORTED = 0x03, /* Get Supported frequencies */
+ SBE_CMD_ABORT = 0x05, /* Sbe Abort */
+};
+
+enum sbeMpIplCommands
+{
+ SBE_CMD_MPIPL_ENTER = 0x01, /* Enter MPIPL */
+ SBE_CMD_MPIPL_CONTINUE = 0x02, /* Continue MPIPL */
+};
+
+/**
+ * @brief enums for primary SBE response
+ *
+*/
+enum sbePrimResponse
+{
+ SBE_PRI_OPERATION_SUCCESSFUL = 0x00,
+ SBE_PRI_INVALID_COMMAND = 0x01,
+ SBE_PRI_INVALID_DATA = 0x02,
+ SBE_PRI_SEQUENCE_ERROR = 0x03,
+ SBE_PRI_INTERNAL_ERROR = 0x04,
+ SBE_PRI_GENERIC_EXECUTION_FAILURE = 0xFE,
+};
+
+/**
+ * @brief enums for secondary SBE response
+ * @TODO via RTC: 129763
+ * Discuss on SBE_SEC_INVALID_TARGET_ID_PASSED
+ *
+*/
+enum sbeSecondaryResponse
+{
+ SBE_SEC_OPERATION_SUCCESSFUL = 0x00,
+ SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED = 0x01,
+ SBE_SEC_COMMAND_NOT_SUPPORTED = 0x02,
+ SBE_SEC_INVALID_ADDRESS_PASSED = 0x03,
+ SBE_SEC_INVALID_TARGET_TYPE_PASSED = 0x04,
+ SBE_SEC_INVALID_TARGET_ID_PASSED = 0x05,
+ SBE_SEC_SPECIFIED_TARGET_NOT_PRESENT = 0x06,
+ SBE_SEC_SPECIFIED_TARGET_NOT_FUNCTIONAL = 0x07,
+ SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE = 0x08,
+ SBE_SEC_FUNCTIONALITY_NOT_SUPPORTED = 0x09,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION = 0x0A,
+ SBE_SEC_SECURITY_VALIDATION_FAILED = 0x0B,
+ SBE_SEC_OS_FAILURE = 0x0C,
+ SBE_SEC_FIFO_ACCESS_FAILURE = 0x0D,
+ SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA = 0x0E,
+ SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA = 0x0F,
+ SBE_SEC_HW_OP_TIMEOUT = 0x10,
+ SBE_SEC_PCB_PIB_ERR = 0x11,
+};
+
+/**
+ * @brief enums for SBE command timeout values
+ *
+*/
+enum sbeCmdRespTimeout
+{
+ SBE_CMD_TIMEOUT_SHORT_IN_MSEC = 100,
+ SBE_CMD_TIMEOUT_LONG_IN_MSEC = 30000,
+};
+
+/**
+ * @brief enums for PCB-PIB Generic Error codes
+ *
+*/
+enum sbePCBPIBErrorRC
+{
+ SBE_PCB_PIB_ERROR_NONE = 0x00,
+ SBE_PCB_PIB_ERROR_RESOURCE_OCCUPIED = 0x01,
+ SBE_PCB_PIB_ERROR_CHIPLET_OFFLINE = 0x02,
+ SBE_PCB_PIB_ERROR_PARTIAL_GOOD = 0x03,
+ SBE_PCB_PIB_ERROR_ADDRESS_ERROR = 0x04,
+ SBE_PCB_PIB_ERROR_CLOCK_ERROR = 0x05,
+ SBE_PCB_PIB_ERROR_PACKET_ERROR = 0x06,
+ SBE_PCB_PIB_ERROR_TIMEOUT = 0x07,
+};
+
+/**
+ * @brief capabilities index values.
+ * Get Capability response will return 18 capabilities. This
+ * enum tells the index for each capability. Currently each generic
+ * functionality( scom, IPL ) etc span across two capabilities.
+ */
+enum
+{
+ GENERIC_CAPABILTITY_START_IDX = 0,
+ IPL_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 2,
+ SCOM_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 4,
+ RING_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 6,
+ MEMORY_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 8,
+ REGISTER_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 10,
+ ARRAY_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 12,
+ INSTRUCTION_CTRL_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 14,
+ GENERIC_CHIPOP_CAPABILITY_START_IDX = GENERIC_CAPABILTITY_START_IDX + 16,
+};
+/**
+ * @brief capabilities enum values.
+ *
+ */
+enum
+{
+ HWP_FFDC_COLLECTION_SUPPPORTED = 0x00000001,
+ SBE_FFDC_COLLECTION_SUPPPORTED = 0x00000002,
+ ADDRESS_BLACKLISTING_SUPPPORTED = 0x00000004,
+ FIFO_RESET_SUPPPORTED = 0x00000008,
+ EXECUTE_ISTEP_SUPPPORTED = 0xA1000001,
+ IS_SBE_DONE_SUPPPORTED = 0xA1000002,
+ GET_SCOM_SUPPPORTED = 0xA2000001,
+ PUT_SCOM_SUPPPORTED = 0xA2000002,
+ MODIFY_SCOM_SUPPPORTED = 0xA2000004,
+ PUT_SCOM_UNDER_MASK_SUPPPORTED = 0xA2000008,
+ MULTI_SCOM_SUPPPORTED = 0xA2000010,
+ GET_RING_SUPPPORTED = 0xA3000001,
+ PUT_RING_SUPPPORTED = 0xA3000002,
+ GET_MEMORY_SUPPPORTED = 0xA4000001,
+ PUT_MEMORY_SUPPPORTED = 0xA4000002,
+ GET_SRAM_OCC_SUPPPORTED = 0xA4000004,
+ PUT_SRAM_OCC_SUPPPORTED = 0xA4000008,
+ GET_SRAM_CME_SUPPPORTED = 0xA4000010,
+ PUT_SRAM_CME_SUPPPORTED = 0xA4000011,
+ GET_REGISTER_SUPPPORTED = 0xA5000001,
+ PUT_REGISTER_SUPPPORTED = 0xA5000002,
+ READ_FAST_ARRAY_SUPPPORTED = 0xA6000001,
+ READ_TRACE_ARRAY_SUPPPORTED = 0xA6000002,
+ COLLECT_TRACE_ARRAY_SUPPPORTED = 0xA6000004,
+ CONTROL_INSTRUCTIONS_SUPPPORTED = 0xA7000001,
+ GET_SBE_FFDC_SUPPPORTED = 0xA8000001,
+ GET_SBE_CAPABILITIES_SUPPPORTED = 0xA8000002,
+ GET_SBE_FREQUENCIES_SUPPPORTED = 0xA8000004,
+ GET_SBE_STATE_SUPPPORTED = 0xA8000008,
+};
+
+/**
+ * * @brief enums for SBE Memory Access command flags
+ *
+ */
+enum sbeMemoryAccessFlags
+{
+ SBE_MEM_ACCESS_FLAGS_TARGET_PROC = 0x0001, //required in ADU
+ SBE_MEM_ACCESS_FLAGS_TARGET_PBA = 0x0002, //required in PBA
+ SBE_MEM_ACCESS_FLAGS_AUTO_INCR_ON = 0x0004,
+ SBE_MEM_ACCESS_FLAGS_ECC_REQUIRED = 0x0008, //required only in ADU-GET
+ SBE_MEM_ACCESS_FLAGS_ECC_OVERRIDE = 0x0008, //required only in ADU-PUT
+ SBE_MEM_ACCESS_FLAGS_ITAG = 0x0010, //ITAG Mode in ADU
+ SBE_MEM_ACCESS_FLAGS_FAST_MODE_ON = 0x0020,
+ SBE_MEM_ACCESS_FLAGS_LCO_ENABLED = 0x0040, //required only in PBA-PUT
+ SBE_MEM_ACCESS_FLAGS_CACHE_INHIBIT = 0x0080, //required in I/O oper ADU
+};
+
+/**
+ * @brief enum for various modes for Sram Access
+ */
+enum sbeSramAccessMode
+{
+ NORMAL_MODE = 0x1,
+ DEBUG_MODE = 0x2,
+ CIRCULAR_MODE = 0x3,
+};
+/*
+ * Constants for maximum number of register supported in reg access chipop.
+ */
+static const uint32_t SBE_MAX_REG_ACCESS_REGS = 64;
+
+/**
+ * @brief Error Mode enum
+ */
+enum sbeErrorMode
+{
+ EXIT_ON_FIRST_ERROR = 0x0, // Bail out on first error
+ IGNORE_HW_ERRORS = 0x01, // Attempt best case
+};
+
+/**
+ * @brief Core Chiplet Id Enum
+ */
+enum sbeCoreChipletId
+{
+ SMT4_CORE0_ID = 0x20,
+ SMT4_CORE_ID_MAX = 0x38,
+ SMT4_ALL_CORES = 0xFF,
+};
+
+/**
+ * @brief Thread Num Enum
+ */
+enum sbeThreadNum
+{
+ SMT4_THREAD0 = 0x0,
+ SMT4_THREAD1 = 0x1,
+ SMT4_THREAD2 = 0x2,
+ SMT4_THREAD3 = 0x3,
+ SMT4_THREAD_MAX = 0x4,
+ SMT4_THREAD_ALL = 0xF,
+};
+
+/**
+ * @brief Thread Operation Enum
+ */
+enum sbeThreadOps
+{
+ THREAD_START_INS = 0x0,
+ THREAD_STOP_INS = 0x1,
+ THREAD_STEP_INS = 0x2,
+ THREAD_SRESET_INS = 0x3,
+};
+
+/**
+ * @brief enums for Reg access register type
+ *
+ */
+enum sbeRegAccesRegType
+{
+ SBE_REG_ACCESS_GPR = 0x00,
+ SBE_REG_ACCESS_SPR = 0x01,
+ SBE_REG_ACCESS_FPR = 0x02,
+};
+
+/*
+ * @brief enums for target types used in ring access chip op
+*/
+typedef enum
+{
+ TARGET_PROC_CHIP = 0x0000,
+ TARGET_EX = 0x0001,
+ TARGET_PERV = 0x0002,
+ TARGET_MCS = 0x0003,
+} sbeRingTargetTypes_t;
+
+/*
+ * @brief enums for access modes used in ring access chip op
+ */
+typedef enum
+{
+ SBE_RING_MODE_NO_HEADER_CHECK = 0x0001, ///< Don't check header
+ SBE_RING_MODE_SET_PULSE_NO_OPCG_COND = 0x0002, ///< Set pulse with
+ /// no OPCG conditioning
+ SBE_RING_MODE_SET_PULSE_NSL = 0x0004, ///< Set pulse with NSL
+ /// pulse
+ SBE_RING_MODE_SET_PULSE_SL = 0x0008, ///< Set pulse with SL
+ /// pulse
+ SBE_RING_MODE_SET_PULSE_ALL = 0x0010, ///< Set pulse with pulse
+ /// to all hold types
+} sbeRingAccessModes_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SBEFW_SBE_SP_INTF_H */
diff --git a/src/sbefw/sbecmdcntlinst.C b/src/sbefw/sbecmdcntlinst.C
new file mode 100644
index 00000000..faed1e5b
--- /dev/null
+++ b/src/sbefw/sbecmdcntlinst.C
@@ -0,0 +1,203 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdcntlinst.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdcntlinst.C
+ *
+ * @brief This file contains the SBE Control Instruction chipOps
+ *
+ */
+
+#include "sbecmdcntlinst.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+
+#include "fapi2.H"
+#include "p9_thread_control.H"
+
+using namespace fapi2;
+
+// This is used to find out the array index in g_control_reg_map in
+// p9_thread_control.C
+static const uint8_t SINGLE_THREAD_BIT_MASK = 0x08;
+// TODO via RTC 152424
+// Currently all proecdures in core directory are in seeprom.
+// So we have to use function pointer to force a long call.
+p9_thread_control_FP_t threadCntlhwp = &p9_thread_control;
+
+/* @brief Map User Thread Command to Hwp ThreadCommands Enum */
+ThreadCommands getThreadCommand(const sbeCntlInstRegMsgHdr_t & i_req)
+{
+ ThreadCommands l_cmd = PTC_CMD_START;
+ switch(i_req.threadOps)
+ {
+ case THREAD_START_INS: l_cmd = PTC_CMD_START; break;
+ case THREAD_STOP_INS: l_cmd = PTC_CMD_STOP; break;
+ case THREAD_STEP_INS: l_cmd = PTC_CMD_STEP; break;
+ case THREAD_SRESET_INS: l_cmd = PTC_CMD_SRESET; break;
+ }
+ return l_cmd;
+}
+
+/* @brief Map User Mode Command to Hwp Warn Check flag */
+inline bool getWarnCheckFlag(const sbeCntlInstRegMsgHdr_t & i_req)
+{
+ bool l_warnCheck = false;
+ if( EXIT_ON_FIRST_ERROR != i_req.mode )
+ {
+ l_warnCheck = true;
+ }
+ return l_warnCheck;
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeCntlInst Sbe control instructions function
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeCntlInst(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeCntlInst "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+
+ // Create the req struct for Control Instructions Chip-op
+ sbeCntlInstRegMsgHdr_t l_req = {0};
+
+ do
+ {
+ // Get the Req Struct Data sbeCntlInstRegMsgHdr_t from upstream Fifo
+ uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_req, true);
+
+ // If FIFO failure
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ SBE_INFO("mode[0x%04X] coreChipletId[0x%08X] threadNum[0x%04X] "
+ "threadOps[0x%04X] ", l_req.mode, l_req.coreChipletId,
+ l_req.threadNum, l_req.threadOps);
+
+ // Validate Input Args
+ if( false == l_req.validateInputArgs())
+ {
+ SBE_ERROR(SBE_FUNC "ValidateAndMapInputArgs failed");
+ l_respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ break;
+ }
+
+ // Fetch HWP mapped values
+ bool l_warnCheck = getWarnCheckFlag(l_req);
+ ThreadCommands l_cmd = getThreadCommand(l_req);
+
+ // Default assignment not required since it is assigned below
+ uint8_t l_core, l_coreCntMax;
+ uint8_t l_threadCnt, l_threadCntMax;
+
+ l_req.processInputDataToIterate(l_core, l_coreCntMax,
+ l_threadCnt, l_threadCntMax);
+ fapi2::buffer<uint64_t> l_data64;
+ uint64_t l_state;
+ do
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_CORE>
+ l_coreTgt(plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_CORE>(l_core));
+ if(!l_coreTgt.isFunctional())
+ {
+ continue;
+ }
+
+ uint8_t l_thread = l_threadCnt;
+ do
+ {
+ // Call the Procedure
+ l_fapiRc = threadCntlhwp(
+ l_coreTgt,
+ (SINGLE_THREAD_BIT_MASK >> l_thread),
+ l_cmd, l_warnCheck,
+ l_data64, l_state);
+
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "Failed for Core[%d] Thread [%d] "
+ "Cmd[%d] Mode[%d]", l_core, l_thread, l_req.threadOps,
+ l_req.mode);
+ if(IGNORE_HW_ERRORS == l_req.mode)
+ {
+ // No need to delete the l_fapiRc handle,it will get
+ // over-written
+ SBE_INFO(SBE_FUNC "Continuing in case of HW Errors"
+ " As user has passed to ignore errors.");
+ continue;
+ }
+ else
+ {
+ SBE_ERROR(SBE_FUNC "Breaking out, since User has "
+ "Selected the mode to exit on first error.");
+ l_respHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ }
+ }while(++l_thread < l_threadCntMax);
+
+ // If FapiRc from the inner loop (thread loop), just break here
+ if ( l_fapiRc )
+ {
+ break; // From core while loop
+ }
+ }while(++l_core < l_coreCntMax);
+
+ }while(0);
+
+ // Create the Response to caller
+ do
+ {
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ break;
+ }
+
+ l_rc = sbeDsSendRespHdr(l_respHdr, l_ffdc);
+ }while(0);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdcntlinst.H b/src/sbefw/sbecmdcntlinst.H
new file mode 100644
index 00000000..39e84135
--- /dev/null
+++ b/src/sbefw/sbecmdcntlinst.H
@@ -0,0 +1,45 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdcntlinst.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdcntlinst.H
+ *
+ * @brief This file contains the Interfaces for Control Instructions chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDCNTLINST_H
+#define __SBEFW_SBECMDCNTLINST_H
+
+#include <stdint.h>
+
+/**
+ * @brief sbeCntlInst : Implements SBE Control instructions ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeCntlInst (uint8_t *i_pArg);
+
+#endif /* __SBEFW_SBECMDCNTLINST_H */
diff --git a/src/sbefw/sbecmdcntrldmt.C b/src/sbefw/sbecmdcntrldmt.C
new file mode 100644
index 00000000..a4cf8c97
--- /dev/null
+++ b/src/sbefw/sbecmdcntrldmt.C
@@ -0,0 +1,302 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdcntrldmt.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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/sbefw/sbecmdcntrldmt.C
+ *
+ * @brief This file contains the Core State Control Messages
+ *
+ */
+
+#include "sbecmdcntrldmt.H"
+#include "sbetrace.H"
+#include "sbe_build_info.H"
+#include "sbeHostMsg.H"
+#include "sbeHostUtils.H"
+#include "sberegaccess.H"
+#include "sbestates.H"
+#include "sbe_sp_intf.H"
+#include "fapi2.H"
+#include "p9_sbe_check_master_stop15.H"
+#include "p9_perv_scom_addresses.H"
+#include "p9_block_wakeup_intr.H"
+
+using namespace fapi2;
+
+// Using Function pointer to force long call
+p9_sbe_check_master_stop15_FP_t p9_sbe_check_master_stop15_hwp =
+ &p9_sbe_check_master_stop15;
+
+////////////////////////////////////////////////////////////////////
+//Static initialization of the Dmt Pk timer
+PkTimer g_sbe_pk_dmt_timer;
+// Global Flag to indicate Dmt Timer Expiry
+bool g_SbeDmtTimerExpired = false;
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+void sbeDmtPkExpiryCallback(void *)
+{
+ #define SBE_FUNC "sbeDmtPkExpiryCallback"
+ SBE_INFO(SBE_FUNC" DMT Callback Timer has expired..Checkstop the system ");
+ g_SbeDmtTimerExpired = true;
+
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_DUMP_FAILURE_EVENT);
+
+ // check stop the system
+ uint32_t l_status = SBE_PCB_PIB_ERROR_NONE;
+ l_status = putscom_abs (PERV_N3_LOCAL_FIR_OR, N3_FIR_CORE_CHECKSTOP_BIT);
+ if(SBE_PCB_PIB_ERROR_NONE != l_status)
+ {
+ // Scom failed
+ SBE_ERROR(SBE_FUNC "PutScom failed for REG PERV_N3_LOCAL_FIR");
+ // TODO - Store the response in Async Response
+ // RTC:149074
+ }
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+uint32_t sbeStartCntlDmt()
+{
+ #define SBE_FUNC "sbeStartCntlDmt"
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ int l_pkRc = 0;
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+ g_SbeDmtTimerExpired = false;
+
+ do
+ {
+ // Fetch the Timer Value and Start a Pk Timer
+ uint64_t l_timerVal = 0;
+ l_rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG1,
+ (sizeof(l_timerVal)/sizeof(uint64_t)),
+ &l_timerVal);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to extract SBE_HOST_PSU_MBOX_REG1");
+ break;
+ }
+
+ // Attach Callback
+ PkTimerCallback l_callback = &sbeDmtPkExpiryCallback;
+
+ // Create Timer with the above value
+ l_pkRc = pk_timer_create(&g_sbe_pk_dmt_timer, l_callback, NULL);
+ if(l_pkRc)
+ {
+ SBE_ERROR(SBE_FUNC" Pk Timer Create failed, RC=[%d]", l_pkRc);
+ l_rc = SBE_SEC_OS_FAILURE;
+ break;
+ }
+
+ // Schedule the timer
+ l_pkRc = pk_timer_schedule(&g_sbe_pk_dmt_timer,
+ PK_MILLISECONDS((uint32_t)l_timerVal));
+ if(l_pkRc)
+ {
+ SBE_ERROR(SBE_FUNC" Pk Timer Schedule failed, RC=[%d]", l_pkRc);
+ l_rc = SBE_SEC_OS_FAILURE;
+ break;
+ }
+
+ l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ (uint64_t*)(&g_sbeSbe2PsuRespHdr),
+ (sizeof(g_sbeSbe2PsuRespHdr)/sizeof(uint64_t)),
+ true);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to write to "
+ "SBE_HOST_PSU_MBOX_REG4");
+ break;
+ }
+ // Set DMT State
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_DMT_ENTER_EVENT);
+
+ // Fetch the master core
+ Target<TARGET_TYPE_PROC_CHIP > l_procTgt = plat_getChipTarget();
+
+ // Fetch the MASTER_CORE attribute
+ uint8_t l_coreId = 0;
+ FAPI_ATTR_GET(fapi2::ATTR_MASTER_CORE,l_procTgt,l_coreId);
+
+ // Construct the Master Core Target
+ fapi2::Target<fapi2::TARGET_TYPE_CORE > l_coreTgt(
+ (uint64_t)l_coreId);
+
+ // Call Hwp p9_sbe_check_master_stop15 and loop
+ // Go around a loop till you get FAPI2_RC_SUCCESS
+ do
+ {
+ l_fapiRc = p9_sbe_check_master_stop15_hwp(l_coreTgt);
+ //Conversion is required here, since ReturnCode doesn't support
+ //comparision '!=' or '=='
+ //TODO RTC:149021
+ uint32_t l_rcFapi = l_fapiRc;
+ if( (l_rcFapi != fapi2::RC_CHECK_MASTER_STOP15_PENDING) &&
+ (l_rcFapi != FAPI2_RC_SUCCESS))
+ {
+ SBE_ERROR(SBE_FUNC" p9_sbe_check_master_stop15 "
+ "returned failure");
+ // Async Response to be stored
+ // RTC:149074
+ break;
+ }
+
+ // Only for Pending and Success case
+ if(RC_CHECK_MASTER_STOP15_PENDING != l_rcFapi) // Success
+ {
+ l_fapiRc = p9_block_wakeup_intr(l_coreTgt,
+ p9pmblockwkup::CLEAR );
+ if( l_fapiRc )
+ {
+ SBE_ERROR(SBE_FUNC" p9_block_wakeup_intr failed ");
+ // TODO via RTC 149074
+ // Async Response to be stored.
+ // Also checkstop the system.
+ break;
+ }
+ // indicate the Host via Bit SBE_SBE2PSU_DOORBELL_SET_BIT2
+ // that Stop15 exit
+ l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT2);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed to Write "
+ "SBE_SBE2PSU_DOORBELL_SET_BIT2");
+ }
+ break; // Breakout from do..while()
+ }
+ // Stop 15 Pending Case
+ pk_sleep(PK_MILLISECONDS(SBE_DMT_SLEEP_INTERVAL));
+
+ }while(false == g_SbeDmtTimerExpired); // Inner Loop
+
+ }while(0); // Outer loop
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+uint32_t sbeStopCntlDmt()
+{
+ #define SBE_FUNC "sbeStopCntlDmt"
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ int l_pkRc = 0;
+
+ do
+ {
+ // Stop the Pk Timer - There is no call to check if the timer is
+ // still alive, if i call cancel on already expired timer, it
+ // returns error code.
+ if(false == g_SbeDmtTimerExpired)
+ {
+ SBE_INFO(SBE_FUNC " DmTimer hasn't expired yet.. stop it");
+ l_pkRc = pk_timer_cancel(&g_sbe_pk_dmt_timer);
+ if(l_pkRc)
+ {
+ // Check again if the failure is because of the timer already
+ // expired, in that case don't need to send any error response
+ // to hostboot
+ if(false == g_SbeDmtTimerExpired)
+ {
+ SBE_ERROR(SBE_FUNC " Pk Timer Cancel failed, RC=[%d]",
+ l_pkRc);
+ l_rc = SBE_SEC_OS_FAILURE;
+ }
+ break;
+ }
+ }
+
+ l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ (uint64_t*)(&g_sbeSbe2PsuRespHdr),
+ (sizeof(g_sbeSbe2PsuRespHdr)/sizeof(uint64_t)),
+ true);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to write to SBE_HOST_PSU_MBOX_REG4");
+ break;
+ }
+ // Set Runtime State
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_DMT_COMP_EVENT);
+ }while(0);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+uint32_t sbeControlDeadmanTimer (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeControlDeadmanTimer"
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ do
+ {
+ // Send Ack to Host via SBE_SBE2PSU_DOORBELL_SET_BIT1
+ // This util method will check internally on the mbox0 register if ACK
+ // is requested.
+ l_rc = sbeAcknowledgeHost();
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed to Sent Ack to Host over "
+ "SBE_SBE2PSU_DOORBELL_SET_BIT1");
+ break;
+ }
+
+ if(g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_START_DMT)
+ {
+ l_rc = sbeStartCntlDmt();
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed sbeStartCntlDmt");
+ break;
+ }
+ }
+ else if(g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_STOP_DMT)
+ {
+ l_rc = sbeStopCntlDmt();
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC " Failed sbeStopCntlDmt");
+ break;
+ }
+ }
+ else
+ {
+ SBE_ERROR(SBE_FUNC" Not a valid command ");
+ l_rc = SBE_SEC_COMMAND_NOT_SUPPORTED;
+ }
+ }while(0); // End of do-while
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbecmdcntrldmt.H b/src/sbefw/sbecmdcntrldmt.H
new file mode 100644
index 00000000..4f133947
--- /dev/null
+++ b/src/sbefw/sbecmdcntrldmt.H
@@ -0,0 +1,59 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdcntrldmt.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdcntrldmt.H
+ *
+ * @brief This file contains the Core State Control Messages API header
+ *
+ */
+
+#ifndef __SBEFW_SBECMDCNTRLDMT_H
+#define __SBEFW_SBECMDCNTRLDMT_H
+
+#include <stdint.h>
+
+// Define for the Sleep interval between continuous HWP calls
+// for DMT functionality in Millisecond
+static const uint8_t SBE_DMT_SLEEP_INTERVAL = 1;
+
+// Bit-32 used to checkstop the system
+static const uint64_t N3_FIR_CORE_CHECKSTOP_BIT = 32;
+
+/**
+ * @brief Callback for Timer Expiry for DMT
+ *
+ * @return void
+ */
+void sbeDmtPkExpiryCallback(void *arg);
+
+/**
+ * @brief Control Deadman Timer command (0xD101)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return RC from the PSU access utility
+ */
+uint32_t sbeControlDeadmanTimer(uint8_t *i_pArg);
+
+#endif // __SBEFW_SBECMDCNTRLDMT_H
diff --git a/src/sbefw/sbecmdgeneric.C b/src/sbefw/sbecmdgeneric.C
new file mode 100644
index 00000000..e883993a
--- /dev/null
+++ b/src/sbefw/sbecmdgeneric.C
@@ -0,0 +1,118 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdgeneric.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdgeneric.C
+ *
+ * @brief This file contains the SBE generic Commands
+ *
+ */
+
+#include "sbecmdgeneric.H"
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbe_build_info.H"
+#include "sbeFifoMsgUtils.H"
+
+// Forward declaration
+sbeCapabilityRespMsg::sbeCapabilityRespMsg()
+{
+ verMajor= SBE_FW_MAJOR_VERSION;
+ verMinor = SBE_FW_MINOR_VERSION;
+ fwCommitId = SBE_COMMIT_ID;
+ // We can remove this for llop once all capabilities
+ // are supported
+ for(uint32_t idx = 0; idx < SBE_MAX_CAPABILITIES; idx++ )
+ {
+ capability[idx] = 0;
+ }
+ capability[IPL_CAPABILITY_START_IDX] =
+ EXECUTE_ISTEP_SUPPPORTED;
+
+ capability[SCOM_CAPABILITY_START_IDX] =
+ GET_SCOM_SUPPPORTED |
+ PUT_SCOM_SUPPPORTED |
+ MODIFY_SCOM_SUPPPORTED |
+ PUT_SCOM_UNDER_MASK_SUPPPORTED ;
+
+ capability[GENERIC_CHIPOP_CAPABILITY_START_IDX] =
+ GET_SBE_CAPABILITIES_SUPPPORTED;
+
+ capability[MEMORY_CAPABILITY_START_IDX] =
+ GET_MEMORY_SUPPPORTED |
+ PUT_MEMORY_SUPPPORTED |
+ GET_SRAM_OCC_SUPPPORTED |
+ PUT_SRAM_OCC_SUPPPORTED;
+
+ capability[INSTRUCTION_CTRL_CAPABILITY_START_IDX] =
+ CONTROL_INSTRUCTIONS_SUPPPORTED;
+ capability[REGISTER_CAPABILITY_START_IDX] =
+ GET_REGISTER_SUPPPORTED |
+ PUT_REGISTER_SUPPPORTED ;
+
+ capability[RING_CAPABILITY_START_IDX] =
+ GET_RING_SUPPPORTED;
+}
+// Functions
+//----------------------------------------------------------------------------
+uint32_t sbeGetCapabilities (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeGetCapabilities "
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeCapabilityRespMsg_t capMsg;
+ sbeResponseFfdc_t l_ffdc;
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ rc = sbeUpFifoDeq_mult (len, NULL);
+ // @TODO via RTC : 130575
+ // Optimize both the RC handling and
+ // FIFO operation infrastructure.
+ if ( rc != SBE_SEC_OPERATION_SUCCESSFUL )
+ {
+ // Let command processor routine to handle the RC
+ break;
+ }
+
+ len = sizeof(capMsg)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &capMsg);
+ if (rc)
+ {
+ break;
+ }
+
+ rc = sbeDsSendRespHdr(respHdr, l_ffdc);
+ }while(0);
+
+ if( rc )
+ {
+ SBE_ERROR( SBE_FUNC"Failed. rc[0x%X]", rc);
+ }
+ return rc;
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbecmdgeneric.H b/src/sbefw/sbecmdgeneric.H
new file mode 100644
index 00000000..3fa174ad
--- /dev/null
+++ b/src/sbefw/sbecmdgeneric.H
@@ -0,0 +1,46 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdgeneric.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdgeneric.H
+ *
+ * @brief This file contains the SBE Generic command details
+ *
+ */
+
+#ifndef __SBEFW_SBECMDGENERIC_H
+#define __SBEFW_SBECMDGENERIC_H
+
+#include <stdint.h>
+
+
+/**
+ * @brief SBE Generic capabilities (0xA802)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetCapabilities(uint8_t *i_pArg);
+
+#endif // __SBEFW_SBECMDGENERIC_H
diff --git a/src/sbefw/sbecmdiplcontrol.C b/src/sbefw/sbecmdiplcontrol.C
new file mode 100644
index 00000000..0819a864
--- /dev/null
+++ b/src/sbefw/sbecmdiplcontrol.C
@@ -0,0 +1,830 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdiplcontrol.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdiplcontrol.C
+ *
+ * @brief This file contains the SBE istep chipOps
+ *
+ */
+
+#include "sbecmdiplcontrol.H"
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "assert.h"
+#include "sberegaccess.H"
+#include "sbestates.H"
+
+#include "fapi2.H"
+// Pervasive HWP Header Files ( istep 2)
+#include <p9_sbe_attr_setup.H>
+#include <p9_sbe_tp_chiplet_init1.H>
+#include <p9_sbe_tp_gptr_time_initf.H>
+#include <p9_sbe_npll_initf.H>
+#include <p9_sbe_npll_setup.H>
+#include <p9_sbe_tp_switch_gears.H>
+#include <p9_sbe_clock_test2.H>
+#include <p9_sbe_tp_chiplet_reset.H>
+#include <p9_sbe_tp_repr_initf.H>
+#include <p9_sbe_tp_chiplet_init2.H>
+#include <p9_sbe_tp_arrayinit.H>
+#include <p9_sbe_tp_initf.H>
+#include <p9_sbe_tp_chiplet_init3.H>
+
+// Pervasive HWP Header Files ( istep 3)
+#include <p9_sbe_chiplet_reset.H>
+#include <p9_sbe_gptr_time_initf.H>
+#include <p9_sbe_chiplet_init.H>
+#include <p9_sbe_chiplet_pll_initf.H>
+#include <p9_sbe_chiplet_pll_setup.H>
+#include <p9_sbe_repr_initf.H>
+#include <p9_sbe_arrayinit.H>
+#include <p9_sbe_tp_enable_ridi.H>
+#include <p9_sbe_setup_boot_freq.H>
+#include <p9_sbe_nest_initf.H>
+#include <p9_sbe_nest_startclocks.H>
+#include <p9_sbe_io_initf.H>
+#include <p9_sbe_nest_enable_ridi.H>
+#include <p9_sbe_startclock_chiplets.H>
+#include <p9_sbe_scominit.H>
+#include <p9_sbe_lpc_init.H>
+#include <p9_sbe_fabricinit.H>
+#include <p9_sbe_mcs_setup.H>
+#include <p9_sbe_select_ex.H>
+// Cache HWP header file
+#include <p9_hcd_cache.H>
+#include <p9_hcd_cache_dcc_skewadjust_setup.H>
+#include <p9_hcd_cache_chiplet_l3_dcc_setup.H>
+#include <p9_hcd_cache_dpll_initf.H>
+// Core HWP header file
+#include <p9_hcd_core.H>
+
+// istep 5 hwp header files
+#include "p9_sbe_instruct_start.H"
+#include "p9_sbe_load_bootloader.H"
+
+#include "sbeXipUtils.H" // For getting hbbl offset
+// Forward declaration
+using namespace fapi2;
+ReturnCode sbeExecuteIstep (uint8_t i_major, uint8_t i_minor);
+bool validateIstep (uint8_t i_major, uint8_t i_minor);
+
+//typedefs
+typedef ReturnCode (*sbeIstepHwpProc_t)
+ (const Target<TARGET_TYPE_PROC_CHIP> & i_target);
+
+typedef ReturnCode (*sbeIstepHwpEq_t)
+ (const Target<TARGET_TYPE_EQ> & i_target);
+
+typedef ReturnCode (*sbeIstepHwpCore_t)
+ (const Target<TARGET_TYPE_CORE> & i_target);
+
+typedef union
+{
+ sbeIstepHwpProc_t procHwp;
+ sbeIstepHwpEq_t eqHwp;
+ sbeIstepHwpCore_t coreHwp;
+}sbeIstepHwp_t;
+// Wrapper function for HWP IPl functions
+typedef ReturnCode (*sbeIstep_t)( sbeIstepHwp_t );
+
+// Wrapper function which will call HWP.
+ReturnCode istepWithProc( sbeIstepHwp_t i_hwp );
+ReturnCode istepAttrSetup( sbeIstepHwp_t i_hwp );
+ReturnCode istepNoOp( sbeIstepHwp_t i_hwp );
+ReturnCode istepWithEq( sbeIstepHwp_t i_hwp);
+ReturnCode istepWithCore( sbeIstepHwp_t i_hwp);
+ReturnCode istepSelectEx( sbeIstepHwp_t i_hwp);
+ReturnCode istepLoadBootLoader( sbeIstepHwp_t i_hwp);
+ReturnCode istepCheckSbeMaster( sbeIstepHwp_t i_hwp);
+ReturnCode istepStartInstruction( sbeIstepHwp_t i_hwp);
+ReturnCode istepWithCoreConditional( sbeIstepHwp_t i_hwp);
+ReturnCode istepWithEqConditional( sbeIstepHwp_t i_hwp);
+
+// Using function pointer to force long call.
+p9_sbe_select_ex_FP_t p9_sbe_select_ex_hwp = &p9_sbe_select_ex;
+
+//structure for mapping SBE wrapper and HWP functions
+typedef struct
+{
+ sbeIstep_t istepWrapper;
+ sbeIstepHwp_t istepHwp;
+}istepMap_t;
+
+// Major isteps which are supported
+typedef enum
+{
+ SBE_ISTEP2 = 2,
+ SBE_ISTEP_FIRST = SBE_ISTEP2,
+ SBE_ISTEP3 = 3,
+ SBE_ISTEP_LAST_SLAVE = SBE_ISTEP3,
+ SBE_ISTEP4 = 4,
+ SBE_ISTEP5 = 5,
+ SBE_ISTEP_LAST_MASTER = SBE_ISTEP5,
+}sbe_supported_steps_t;
+
+// constants
+const uint32_t ISTEP2_MAX_SUBSTEPS = 17;
+const uint32_t ISTEP3_MAX_SUBSTEPS = 22;
+const uint32_t ISTEP4_MAX_SUBSTEPS = 34;
+const uint32_t ISTEP5_MAX_SUBSTEPS = 2;
+static const uint8_t ISTEP_MINOR_START = 1;
+static const uint8_t SLAVE_LAST_MINOR_ISTEP = 20;
+static const uint8_t ISTEP2_MINOR_START = 2;
+static const uint32_t SBE_ROLE_MASK = 0x00000002;
+
+// Globals
+// TODO: via RTC 123602 This global needs to move to a class that will store the
+// SBE FFDC.
+fapi2::ReturnCode g_iplFailRc = FAPI2_RC_SUCCESS;
+
+sbeRole g_sbeRole = SBE_ROLE_MASTER;
+
+// File static data
+
+static istepMap_t g_istep2PtrTbl[ ISTEP2_MAX_SUBSTEPS ] =
+ {
+ { NULL, NULL },
+ { &istepAttrSetup, { .procHwp = &p9_sbe_attr_setup }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_init1 }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_gptr_time_initf }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_npll_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_npll_setup }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_switch_gears }},
+ { &istepWithProc, { .procHwp = &p9_sbe_clock_test2 }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_reset }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_repr_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_init2 }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_arrayinit }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_initf }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_init3 }},
+ };
+
+static istepMap_t g_istep3PtrTbl[ ISTEP3_MAX_SUBSTEPS ] =
+ {
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_reset }},
+ { &istepWithProc, { .procHwp = &p9_sbe_gptr_time_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_pll_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_pll_setup }},
+ { &istepWithProc, { .procHwp = &p9_sbe_repr_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_init }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_arrayinit }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_enable_ridi }},
+ { &istepWithProc, { .procHwp = &p9_sbe_setup_boot_freq }},
+ { &istepWithProc, { .procHwp = &p9_sbe_nest_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_nest_startclocks }},
+ { &istepWithProc, { .procHwp = &p9_sbe_nest_enable_ridi }},
+ { &istepWithProc, { .procHwp = &p9_sbe_io_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_startclock_chiplets }},
+ { &istepWithProc, { .procHwp = &p9_sbe_scominit }},
+ { &istepWithProc, { .procHwp = &p9_sbe_lpc_init }},
+ { &istepWithProc, { .procHwp = &p9_sbe_fabricinit }},
+ { &istepCheckSbeMaster, NULL },
+ { &istepWithProc, { .procHwp = &p9_sbe_mcs_setup }},
+ { &istepSelectEx, NULL },
+ };
+static istepMap_t g_istep4PtrTbl[ ISTEP4_MAX_SUBSTEPS ] =
+ {
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_poweron} },
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_chiplet_reset } },
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_chiplet_l3_dcc_setup }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_gptr_time_initf }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_dpll_initf }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_dpll_setup }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_dcc_skewadjust_setup }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_chiplet_init }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_repair_initf }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_arrayinit }},
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_initf }},
+ { &istepWithEqConditional, { .eqHwp = &p9_hcd_cache_startclocks }},
+ { &istepWithEqConditional, { .eqHwp = &p9_hcd_cache_scominit }},
+ { &istepWithEqConditional, { .eqHwp = &p9_hcd_cache_scomcust }},
+ { &istepNoOp, NULL }, // Runtime only
+ { &istepNoOp, NULL }, // Runtime only
+ { &istepNoOp, NULL }, // stub for SBE
+ { &istepNoOp, NULL }, // stub for SBE
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_poweron }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_chiplet_reset }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_gptr_time_initf }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_chiplet_init }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_repair_initf }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_arrayinit }},
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_initf }},
+ { &istepWithCoreConditional,
+ { .coreHwp = &p9_hcd_core_startclocks }},
+ { &istepWithCoreConditional, { .coreHwp = &p9_hcd_core_scominit }},
+ { &istepWithCoreConditional, { .coreHwp = &p9_hcd_core_scomcust }},
+ { &istepNoOp, NULL },
+ { &istepNoOp, NULL },
+ };
+
+// TODO via RTC 135345
+// Add the support for istep 5 HWP
+static istepMap_t g_istep5PtrTbl[ ISTEP5_MAX_SUBSTEPS ]
+ {
+ { &istepLoadBootLoader, NULL },
+ { &istepStartInstruction, { .coreHwp = &p9_sbe_instruct_start }},
+ };
+
+// Functions
+//----------------------------------------------------------------------------
+uint32_t sbeHandleIstep (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeHandleIstep "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
+ uint32_t len = 0;
+ sbeIstepReqMsg_t req;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t ffdc;
+
+ // NOTE: In this function we will have two loops
+ // First loop will deque data and prepare the response
+ // Second response will enque the data on DS FIFO
+ //loop 1
+ do
+ {
+ len = sizeof( req )/sizeof(uint32_t);
+ rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&req);
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL) //FIFO access issue
+ {
+ SBE_ERROR(SBE_FUNC"FIFO dequeue failed, rc[0x%X]", rc);
+ break;
+ }
+
+ if( false == validateIstep( req.major, req.minor ) )
+ {
+ SBE_ERROR(SBE_FUNC" Invalid Istep. major:0x%08x"
+ " minor:0x%08x", req.major, req.minor);
+ // @TODO via RTC 132295.
+ // Need to change code asper better error handling.
+ respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ break;
+ }
+
+ fapiRc = sbeExecuteIstep( req.major, req.minor );
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" sbeExecuteIstep() Failed. major:0x%08x"
+ " minor:0x%08x", req.major, req.minor);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+
+ }while(0);
+
+ //loop 2
+ do
+ {
+ // FIFO error
+ if ( rc )
+ {
+ break;
+ }
+
+ rc = sbeDsSendRespHdr(respHdr, ffdc);
+ }while(0);
+
+ if( rc )
+ {
+ SBE_ERROR( SBE_FUNC"Failed. rc[0x%X]", rc);
+ }
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+// @note This is the responsibilty of caller to verify major/minor
+// number before calling this function
+
+// @TODO via RTC 129077.
+// This function should check for system checkstop as well.
+ReturnCode sbeExecuteIstep (const uint8_t i_major, const uint8_t i_minor)
+{
+ #define SBE_FUNC "sbeExecuteIstep "
+ SBE_INFO(SBE_FUNC"Major number:0x%x minor number:0x%x",
+ i_major, i_minor );
+
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ switch( i_major )
+ {
+ case SBE_ISTEP2:
+ rc = (g_istep2PtrTbl[i_minor-1].istepWrapper)(
+ g_istep2PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP3:
+ rc = (g_istep3PtrTbl[i_minor-1].istepWrapper)(
+ g_istep3PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP4:
+ rc = (g_istep4PtrTbl[i_minor-1].istepWrapper)(
+ g_istep4PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP5:
+ rc = (g_istep5PtrTbl[i_minor-1].istepWrapper)(
+ g_istep5PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ // We should never reach here as before calling this validation has
+ // been done.
+ default:
+ assert(0);
+ break;
+ }
+
+ (void)SbeRegAccess::theSbeRegAccess().updateSbeStep(i_major, i_minor);
+
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ // If IPLing State
+ uint64_t l_state = SbeRegAccess::theSbeRegAccess().getSbeState();
+ if(l_state == SBE_STATE_IPLING)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().
+ stateTransition(SBE_DUMP_FAILURE_EVENT);
+ }
+ }
+
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+bool validateIstep (const uint8_t i_major, const uint8_t i_minor)
+{
+ bool valid = true;
+ do
+ {
+ if( 0 == i_minor )
+ {
+ valid = false;
+ break;
+ }
+
+ if((SBE_ROLE_SLAVE == g_sbeRole) &&
+ ((SBE_ISTEP_LAST_SLAVE < i_major) ||
+ ((SBE_ISTEP_LAST_SLAVE == i_major) &&
+ (SLAVE_LAST_MINOR_ISTEP < i_minor)
+ )))
+ {
+ // Cannot run beyond 3.20 on a slave SBE
+ valid = false;
+ break;
+ }
+
+ switch( i_major )
+ {
+ case SBE_ISTEP2:
+ // istep 2.1 loads image to PIBMEM
+ // So SBE control loop can not execute istep 2.1.
+ if(( i_minor > ISTEP2_MAX_SUBSTEPS ) || ( i_minor == 1) )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP3:
+ if( i_minor > ISTEP3_MAX_SUBSTEPS ) { valid = false; } ;
+ break;
+
+ case SBE_ISTEP4:
+ if( i_minor > ISTEP4_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP5:
+ if( i_minor > ISTEP5_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ default:
+ valid= false;
+ break;
+ }
+ } while(0);
+
+ return valid;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepAttrSetup( sbeIstepHwp_t i_hwp)
+{
+ SBE_ENTER("istepAttrSetup");
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ assert( NULL != i_hwp.procHwp );
+ rc = i_hwp.procHwp(proc);
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ break;
+ }
+ // Apply the gard records
+ rc = plat_ApplyGards();
+ }while(0);
+ SBE_EXIT("istepAttrSetup");
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithProc( sbeIstepHwp_t i_hwp)
+{
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ assert( NULL != i_hwp.procHwp );
+ return i_hwp.procHwp(proc);
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepSelectEx( sbeIstepHwp_t i_hwp)
+{
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ // TODO via RTC 135345
+ // Once multicast targets are supported, we may need to pass
+ // p9selectex::ALL as input.
+ return p9_sbe_select_ex_hwp(proc, p9selectex::SINGLE);
+}
+
+//----------------------------------------------------------------------------
+
+
+ReturnCode istepWithEq( sbeIstepHwp_t i_hwp)
+{
+ // TODO via RTC 135345
+ // Curently we are passing Hard code eq target. Finally it is
+ // going to be a multicast target. Once multicast support is
+ // present, use the right target.
+ fapi2::Target<fapi2::TARGET_TYPE_EQ > eqTgt;
+ // Put this in scope so that vector can be freed up before calling hwp.
+ {
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ auto eqList = proc.getChildren<fapi2::TARGET_TYPE_EQ>();
+ // As it is workaround lets assume there will always be atleast one
+ // functional eq. No need to validate.
+ eqTgt = eqList[0];
+ }
+
+ assert( NULL != i_hwp.eqHwp );
+ return i_hwp.eqHwp( eqTgt );
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithCore( sbeIstepHwp_t i_hwp)
+{
+ // TODO via RTC 135345
+ // Curently we are passing Hard code core target. Finally it is
+ // going to be a multicast target. Once multicast support is
+ // present, use the right target.
+ fapi2::Target<fapi2::TARGET_TYPE_CORE > coreTgt;
+ // Put this in scope so that vector can be freed up before calling hwp.
+ {
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ auto coreList = proc.getChildren<fapi2::TARGET_TYPE_CORE>();
+ // As it is workaround lets assume there will always be atleast one
+ // functional ec. No need to validate.
+ coreTgt = coreList[0];
+ }
+ assert( NULL != i_hwp.coreHwp );
+ return i_hwp.coreHwp( coreTgt );
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithEqConditional( sbeIstepHwp_t i_hwp)
+{
+ SBE_ENTER("istepWithEqCondtional");
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM > sysTgt;
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ uint8_t iplPhase = ENUM_ATTR_SYSTEM_IPL_PHASE_HB_IPL;
+ FAPI_ATTR_GET(ATTR_SYSTEM_IPL_PHASE, sysTgt, iplPhase);
+ if( ENUM_ATTR_SYSTEM_IPL_PHASE_CACHE_CONTAINED == iplPhase )
+ {
+ break;
+ }
+ rc = istepWithEq(i_hwp);
+ }while(0);
+ SBE_EXIT("istepWithEqCondtional");
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithCoreConditional( sbeIstepHwp_t i_hwp)
+{
+ SBE_ENTER("istepWithCoreCondtional");
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM > sysTgt;
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ uint8_t iplPhase = ENUM_ATTR_SYSTEM_IPL_PHASE_HB_IPL;
+ FAPI_ATTR_GET(ATTR_SYSTEM_IPL_PHASE, sysTgt, iplPhase);
+ if( ENUM_ATTR_SYSTEM_IPL_PHASE_CACHE_CONTAINED == iplPhase )
+ {
+ break;
+ }
+ rc = istepWithCore(i_hwp);
+ }while(0);
+ SBE_EXIT("istepWithCoreCondtional");
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepLoadBootLoader( sbeIstepHwp_t i_hwp)
+{
+ // Get master Ex
+ uint8_t exId = 0;
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ FAPI_ATTR_GET(fapi2::ATTR_MASTER_EX,proc,exId);
+ fapi2::Target<fapi2::TARGET_TYPE_EX >
+ exTgt(plat_getTargetHandleByInstance<fapi2::TARGET_TYPE_EX>(exId));
+ // Get hbbl section
+ P9XipHeader *hdr = getXipHdr();
+ P9XipSection *hbblSection = &(hdr->iv_section[P9_XIP_SECTION_SBE_HBBL]);
+
+ ReturnCode rc = p9_sbe_load_bootloader( proc, exTgt, hbblSection->iv_size,
+ getSectionAddr(hbblSection) );
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepStartInstruction( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ rc = istepWithCore(i_hwp);
+ if(rc == FAPI2_RC_SUCCESS)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_RUNTIME_EVENT);
+ }
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepCheckSbeMaster( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ g_sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ?
+ SBE_ROLE_SLAVE : SBE_ROLE_MASTER;
+ SBE_INFO("stepCheckSbeMaster g_sbeRole [%x]", g_sbeRole);
+ if(SBE_ROLE_SLAVE == g_sbeRole)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_RUNTIME_EVENT);
+ }
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepNoOp( sbeIstepHwp_t i_hwp)
+{
+ SBE_INFO("istepNoOp");
+ return FAPI2_RC_SUCCESS ;
+}
+
+// Only allowed in PLCK Mode, since FFDC State mode is set only in PLCK
+//----------------------------------------------------------------------------
+uint32_t sbeContinueBoot (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeContinueBoot "
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ rc = sbeUpFifoDeq_mult (len, NULL);
+ if(rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // let command processor routine handle the RC
+ break;
+ }
+
+ uint32_t distance = 1;
+ len = sizeof(respHdr)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &respHdr);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+
+ len = sizeof(distance)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, &distance);
+ if (rc)
+ {
+ break;
+ }
+ rc = sbeDownFifoSignalEot();
+ if (rc)
+ {
+ break;
+ }
+
+ // Expecting this to be in PLCK Mode and not in Istep mode
+ if(SbeRegAccess::theSbeRegAccess().isDestBitRuntime())
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_CONTINUE_BOOT_RUNTIME_EVENT);
+ // Nothing to do here.
+ }
+ else
+ {
+ SBE_INFO(SBE_FUNC"Continuous IPL Mode set... IPLing");
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_CONTINUE_BOOT_PLCK_EVENT);
+ sbeDoContinuousIpl();
+ }
+ }while(0);
+
+ SBE_DEBUG(SBE_FUNC "RC = 0x%08X", rc);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+void sbeDoContinuousIpl()
+{
+ #define SBE_FUNC "sbeDoContinuousIpl "
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ // An array that holds the max number of minor steps per major step
+ const uint8_t l_minorSteps[] =
+ {
+ ISTEP2_MAX_SUBSTEPS,
+ ISTEP3_MAX_SUBSTEPS,
+ ISTEP4_MAX_SUBSTEPS,
+ ISTEP5_MAX_SUBSTEPS
+ };
+
+ // Where does each minor istep start from?
+ const uint8_t l_minorStartStep[] =
+ {
+ ISTEP2_MINOR_START,
+ ISTEP_MINOR_START,
+ ISTEP_MINOR_START,
+ ISTEP_MINOR_START
+ };
+
+ // Set SBE state as IPLing
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_PLCK_EVENT);
+ bool l_done = false;
+ // Run isteps
+ for(uint8_t l_major = SBE_ISTEP_FIRST;
+ (l_major <= SBE_ISTEP_LAST_MASTER) &&
+ (false == l_done);
+ ++l_major)
+ {
+ for(uint8_t l_minor = l_minorStartStep[l_major - SBE_ISTEP_FIRST];
+ l_minor <= l_minorSteps[l_major - SBE_ISTEP_FIRST];
+ ++l_minor)
+ {
+ l_rc = sbeExecuteIstep(l_major, l_minor);
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC"Failed istep execution in plck mode: "
+ "Major: %d, Minor: %d", l_major, l_minor);
+ l_done = true;
+ break;
+ }
+ // Check if we are at step 3.20 on the slave SBE
+ if(((SBE_ISTEP_LAST_SLAVE == l_major) &&
+ (SLAVE_LAST_MINOR_ISTEP == l_minor)) &&
+ (SBE_ROLE_SLAVE == g_sbeRole))
+ {
+ l_done = true;
+ break;
+ }
+ }
+ }
+ } while(false);
+ // Store l_rc in a global variable that will be a part of the SBE FFDC
+ g_iplFailRc = l_rc;
+ SBE_EXIT(SBE_FUNC);
+ #undef SBE_FUNC
+}
+
+// TODO - RTC 133367
+//----------------------------------------------------------------------------
+uint32_t sbeEnterMpipl(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeEnterMpipl "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ l_rc = sbeUpFifoDeq_mult (len, NULL);
+ if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL )
+ {
+ // Let command processor routine to handle the RC
+ break;
+ }
+
+ sbeResponseFfdc_t l_ffdc;
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+
+ // set state to MPIPL Wait
+ (void)SbeRegAccess::theSbeRegAccess().
+ stateTransition(SBE_ENTER_MPIPL_EVENT);
+
+ //TODO RTC-123696 MPIPL Related procedure/steps
+ }while(0);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+// TODO - RTC 133367
+//----------------------------------------------------------------------------
+uint32_t sbeContinueMpipl(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeContinueMpipl "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ l_rc = sbeUpFifoDeq_mult (len, NULL);
+ if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL )
+ {
+ // Let command processor routine to handle the RC
+ break;
+ }
+
+ sbeResponseFfdc_t l_ffdc;
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+
+ //TODO RTC-134278 Continue MPIPL Related procedure/steps
+
+ // TODO - Once continue steps are over, it will trigger the
+ // istep5.2 and transition to runtime will happen
+
+ }while(0);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
diff --git a/src/sbefw/sbecmdiplcontrol.H b/src/sbefw/sbecmdiplcontrol.H
new file mode 100644
index 00000000..e06757c5
--- /dev/null
+++ b/src/sbefw/sbecmdiplcontrol.H
@@ -0,0 +1,117 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdiplcontrol.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdiplcontrol.H
+ *
+ * @brief This file contains the SBE command details
+ *
+ */
+
+#ifndef __SBEFW_SBECMDIPLCONTROL_H
+#define __SBEFW_SBECMDIPLCONTROL_H
+
+#include <stdint.h>
+
+namespace fapi2
+{
+ class ReturnCode;
+}
+
+/**
+ * @brief execute istep chipop (0xA101)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeHandleIstep(uint8_t *i_pArg);
+
+
+/**
+ * @brief Handles Sbe continue boot after collect ffdc chip-op (0xA102)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeContinueBoot(uint8_t *i_pArg);
+
+
+/**
+ * @brief Executes IPL steps in continuous mode.
+ *
+ * @par On the master SBE, this will run
+ * all steps from 2.2 to 5.2. On the slave SBE, it runs all steps from 2.2
+ * to 3.18.
+ * In case an error is encountered, the execution is aborted.
+ */
+void sbeDoContinuousIpl();
+
+/**
+ * @brief Handles Sbe Enter Mpipl chip-op (0xA901)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeEnterMpipl(uint8_t *i_pArg);
+
+/**
+ * @brief Handles Sbe Continue Mpipl chip-op (0xA902)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeContinueMpipl(uint8_t *i_pArg);
+
+/**
+ * @brief Handles Sbe Get FFDC chip-op (0xA801)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetSbeFfdc(uint8_t *i_pArg);
+
+/**
+ * @brief Handles Sbe Get FFDC chip-op (0xA803)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetFreqSupported(uint8_t *i_pArg);
+
+/**
+ * @brief Handles Sbe Abort chip-op (0xA804)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeAbort(uint8_t *i_pArg);
+
+
+#endif // __SBEFW_SBECMDIPLCONTROL_H
diff --git a/src/sbefw/sbecmdmemaccess.C b/src/sbefw/sbecmdmemaccess.C
new file mode 100644
index 00000000..942bb72d
--- /dev/null
+++ b/src/sbefw/sbecmdmemaccess.C
@@ -0,0 +1,778 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdmemaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdmemaccess.C
+ *
+ * @brief This file contains the SBE Memory Access chipOps
+ *
+ */
+
+#include "sbecmdmemaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbeutil.H"
+
+#include "fapi2.H"
+
+#include "p9_pba_setup.H"
+#include "p9_adu_setup.H"
+#include "p9_pba_access.H"
+#include "p9_adu_access.H"
+
+
+using namespace fapi2;
+
+// Buffer requirement for ADU and PBA on the stack
+static const uint32_t MAX_ADU_BUFFER = 40;
+static const uint32_t MAX_PBA_BUFFER = 32;
+// PBA / ADU Granule size as per the HWP Requirement
+static const uint32_t PBA_GRAN_SIZE_BYTES = 128;
+static const uint32_t ADU_GRAN_SIZE_BYTES = 8;
+
+// Multiplier factor with respect to the FIFO length
+static const uint32_t ADU_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT = 2;
+static const uint32_t PBA_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT = 32;
+
+//Default EX Target ChipletId to be used in PBA by default
+static const uint32_t PBA_DEFAULT_EX_CHIPLET_ID = 7;
+
+/**
+ * @brief static definition of parameters passed in adu chip-ops
+ */
+static const uint32_t SBE_ADU_LOCK_TRIES = 3;
+
+// Transaction size (choice is 1, 2, 4, or 8)
+// 0b00: TSIZE_1
+// 0b01: TSIZE_2
+// 0b10: TSIZE_4
+// 0b11: TSIZE_8
+static const uint32_t SBE_ADU_TRANSACTION_SIZE = 3;
+static const bool SBE_ADU_LEAVE_DIRTY_BOOL = false;
+static const bool SBE_ADU_LOCK_PICK_BOOL = false;
+
+/**
+ * @brief Mask used to build the Flag struct for ADU chip-op
+ **/
+static const uint32_t ADU_LOCK_TRIES_SHIFT = 16;
+static const uint32_t ADU_TRANSACTION_SIZE_SHIFT = 20;
+static const uint32_t ADU_ECC_OVERRIDE_BIT_SHIFT = 22;
+static const uint32_t ADU_ECC_REQUIRED_BIT_SHIFT = 23;
+static const uint32_t ADU_ITAG_REQUIRED_BIT_SHIFT = 24;
+static const uint32_t ADU_FAST_MODE_SHIFT = 25;
+static const uint32_t ADU_LEAVE_DIRTY_SHIFT = 26;
+static const uint32_t ADU_LOCK_PICK_SHIFT = 27;
+static const uint32_t ADU_AUTO_INCR_SHIFT = 28;
+static const uint32_t CACHE_INHIBIT_MODE_SHIFT = 29;
+
+// Fast Mode bit shift for PBA
+static const uint32_t PBA_FAST_MODE_SHIFT = 31;
+
+///////////////////////////////////////////////////////////////////////
+// @brief align4ByteWordLength - Internal Method to this file
+// Align the length passed and return number of words
+//
+// @param [in] i_len, length pass from user in Bytes
+//
+// @return Number of words (number of 4byte length)
+///////////////////////////////////////////////////////////////////////
+inline uint32_t align4ByteWordLength(uint32_t i_len)
+{
+ if(i_len % 4 != 0)
+ {
+ i_len = i_len + (4 - (i_len % 4));
+ }
+ return(i_len/4);
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief calInterAduLenForUpFifo - Internal Method to this file
+// Calculate Intermediate Adu Data length for Upstream Fifo
+//
+// @param [in] i_mod, Modulus number from user, (from numGranules % 4)
+// could be any values from 1,2,3
+// @param [in] i_itag, Itag flag
+// @param [in] i_ecc, Ecc flag
+//
+// @return length in bytes for intermediate ADU length
+///////////////////////////////////////////////////////////////////////
+inline uint32_t calInterAduLenForUpFifo(uint8_t i_mod, bool i_itag, bool i_ecc)
+{
+ //Default init length with either Ecc or Itag
+ uint32_t l_len =
+ ((ADU_GRAN_SIZE_BYTES + 1) * (1 + i_mod));
+ // If ECC and iTag bit is also part of the buffer
+ if(i_itag && i_ecc)
+ {
+ l_len = l_len + (1 + i_mod);
+ }
+ return (l_len);
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeAduLenInUpStreamFifo - Internal Method to this file
+// Calculate the Final Size which is write/read to/from HWP
+//
+// @param [in] i_numGranules, Number of granules read/write
+// @param [in] i_itag, Itag flag
+// @param [in] i_ecc, Ecc flag
+//
+// @return Length in bytes for ADU to be put in Upstream FIFO
+///////////////////////////////////////////////////////////////////////
+inline uint32_t sbeAduLenInUpStreamFifo(uint32_t i_numGranules,
+ bool i_itag,
+ bool i_ecc)
+{
+ uint32_t l_respLen = i_numGranules * ADU_GRAN_SIZE_BYTES;
+ if(i_itag)
+ {
+ // Add one byte for Itag for Each Granule Completed
+ l_respLen = l_respLen + i_numGranules;
+ }
+ if(i_ecc)
+ {
+ // Add one byte for Ecc for Each Granule Completed
+ l_respLen = l_respLen + i_numGranules;
+ }
+ return l_respLen;
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief flushUpstreamFifo - Internal Method to this file, to flush
+// out the upstream fifo
+//
+// @param [in] i_fapiRc, Fapi RC
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+inline uint32_t flushUpstreamFifo (const uint32_t &i_fapiRc)
+{
+ uint32_t l_len2dequeue = 0;
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ if ( i_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL,
+ true, true);
+ }
+ // For other success paths, just attempt to offload
+ // the next entry, which is supposed to be the EOT entry
+ else
+ {
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, true);
+ }
+ return l_rc;
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// @brief constructAduFlag - Internal Method to this file, to construct
+// ADU flag as the HWP expects
+//
+// @param [in] i_hdr, Message Request Header
+// @param [in] i_isFlagRead, Read/Write Flag
+//
+// @return Constructed ADU Flag
+///////////////////////////////////////////////////////////////////////
+uint32_t constructAduFlag(const sbeMemAccessReqMsgHdr_t & i_hdr,
+ const bool i_isFlagRead)
+{
+ #define SBE_FUNC " constructAduFlag"
+
+ // Fast Mode / Ecc mode / Cache Inhibit Mode / Auto Increment
+ // required in ADU operations.
+ bool l_isFastMode = i_hdr.isFastModeSet();
+ bool l_isCacheInhibitMode = i_hdr.isCacheInhibitModeFlagSet();
+ bool l_isItagBit = i_hdr.isItagFlagSet();
+ bool l_isAutoIncr = i_hdr.isAutoIncrModeSet();
+ bool l_isEccRequiredMode = false;
+ bool l_isEccOverrideMode = false;
+
+ if(!i_isFlagRead) // ECC override in write mode
+ {
+ l_isEccOverrideMode = i_hdr.isEccOverrideFlagSet();
+ if(l_isEccOverrideMode)
+ {
+ l_isEccRequiredMode = true;
+ }
+ }
+ else // ECC required in read mode
+ {
+ l_isEccRequiredMode = i_hdr.isEccFlagSet();
+ }
+
+ // Construct the flag required for adu setup
+ uint32_t l_aduSetupFlag =
+ ( (l_isCacheInhibitMode << CACHE_INHIBIT_MODE_SHIFT) |
+ // 3-bit of Cache mode placed in 31-30-29 bits
+ (l_isAutoIncr << ADU_AUTO_INCR_SHIFT) |
+ // 1-bit Auto increment placed at 28th bit
+ (SBE_ADU_LOCK_PICK_BOOL << ADU_LOCK_PICK_SHIFT) |
+ // 1-bit pick lock placed at 27th bit
+ (SBE_ADU_LEAVE_DIRTY_BOOL << ADU_LEAVE_DIRTY_SHIFT) |
+ // 1-bit leave dirty placed at 26th bit
+ (l_isFastMode << ADU_FAST_MODE_SHIFT) |
+ // 1-bit Fast mode placed at 25th bit
+ (l_isItagBit << ADU_ITAG_REQUIRED_BIT_SHIFT) |
+ // 1-bit itag placed at 24th bit
+ (l_isEccRequiredMode << ADU_ECC_REQUIRED_BIT_SHIFT) |
+ // 1-bit ecc required at 23rd bit
+ (l_isEccOverrideMode << ADU_ECC_OVERRIDE_BIT_SHIFT) |
+ // 1-bit ecc override at 22nd bit
+ (SBE_ADU_TRANSACTION_SIZE << ADU_TRANSACTION_SIZE_SHIFT) |
+ // 2-bit Transcation size at 21-20th bits
+ (SBE_ADU_LOCK_TRIES << ADU_LOCK_TRIES_SHIFT) );
+ // 4-bit Lock Tries at 19-18-17-16 bits
+
+ SBE_INFO(SBE_FUNC "Cache[%d] Itag[%d] AutoIncr[%d] FastMode[%d] ",
+ l_isCacheInhibitMode,l_isItagBit,l_isAutoIncr,l_isFastMode);
+ SBE_INFO(SBE_FUNC "EccRequiredMode[%d] EccOverrideMode[%d] EccOverrideByte"
+ "[0x%02X] AduSetupFlag[0x%04X]",l_isEccRequiredMode,l_isEccOverrideMode,
+ i_hdr.eccByte, l_aduSetupFlag);
+
+ return (l_aduSetupFlag);
+ #undef SBE_FUNC
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief processPbaRequest - Internal Method to this file,
+// To process the PBA Access request
+//
+// @param [in] i_hdr, Message Request Header
+// @param [in] i_isFlagRead, Read/Write Flag
+//
+// @return RC from the method
+///////////////////////////////////////////////////////////////////////
+uint32_t processPbaRequest(const sbeMemAccessReqMsgHdr_t &i_hdr,
+ const bool i_isFlagRead)
+{
+ #define SBE_FUNC " processPbaRequest "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+
+ // Default for PBA
+ uint32_t l_sizeMultiplier = PBA_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT;
+ uint32_t l_granuleSize = PBA_GRAN_SIZE_BYTES;
+ uint64_t l_addr = i_hdr.getAddr();
+
+ // Proc Chip Target
+ Target<fapi2::TARGET_TYPE_PROC_CHIP> l_proc = plat_getChipTarget();
+ // Default EX Target Init..Not changing it for the time being
+ Target<fapi2::TARGET_TYPE_EX > l_ex((uint64_t)PBA_DEFAULT_EX_CHIPLET_ID);
+
+ // Determine the access flags
+ // Fast mode flag
+ bool l_isFastMode = i_hdr.isFastModeSet();
+ //LCO Mode for PBA-Put
+ bool l_isLcoMode = i_hdr.isPbaLcoModeSet();
+ if(l_isLcoMode)
+ {
+ //Derive the EX target from the input Core Chiplet Id
+ //Core0/1 -> EX0, Core2/3 -> EX1, Core4/5 -> EX2, Core6/7 -> EX3
+ //..so on
+ l_ex = plat_getTargetHandleByChipletNumber<fapi2::TARGET_TYPE_EX>
+ (i_hdr.coreChipletId);
+ }
+ // By default, ex_chipletId printed below won't be used unless accompanied
+ // by LCO_mode.
+ SBE_INFO(SBE_FUNC "FAST_Mode[%d] LCO_Mode[%d] EX_ChipletId[%d]",
+ l_isFastMode, l_isLcoMode, (i_hdr.coreChipletId)/2);
+
+ // The max granule size for which the ADU/PBA interface if configured
+ uint32_t l_numGranules = 0;
+ // Keeps track of number of granules sent to HWP
+ uint64_t l_granulesCompleted = 0;
+
+ // Input Data length in alignment with PBA (128 Bytes)
+ uint64_t l_lenCacheAligned = i_hdr.getDataLenCacheAlign();
+ SBE_DEBUG(SBE_FUNC "Data Aligned Len / Number of data granules = %d",
+ l_lenCacheAligned);
+
+ while (l_granulesCompleted < l_lenCacheAligned)
+ {
+ // Call the PBA setup HWP
+ l_fapiRc = p9_pba_setup(
+ l_proc,
+ l_ex,
+ l_addr,
+ i_isFlagRead,
+ ((l_isFastMode) ? (1<<PBA_FAST_MODE_SHIFT) : 0),
+ l_numGranules);
+
+ // if p9_pba_setup returns error
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC" p9_pba_setup Failed");
+ // Respond with HWP FFDC
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ // Assumption is Hwp won't return zero for Num Granules
+ assert(0 != l_numGranules);
+
+ SBE_INFO(SBE_FUNC "Hwp returned l_numGranules=[0x%08X]",l_numGranules);
+ uint64_t l_numAcc = 0;
+
+ if (l_numGranules < (l_lenCacheAligned - l_granulesCompleted))
+ {
+ l_numAcc = l_numGranules;
+ }
+ else
+ {
+ l_numAcc = l_lenCacheAligned - l_granulesCompleted;
+ }
+
+ // 128Byte granule for PBA access
+ uint32_t l_dataFifo[MAX_PBA_BUFFER] = {0};
+
+ uint64_t l_numCurrAcc = 0;
+ while (l_numCurrAcc < l_numAcc)
+ {
+ bool l_lastGran = (l_numCurrAcc == (l_numAcc-1)) ? true : false;
+ bool l_firstGran = (l_numCurrAcc == 0) ? true : false;
+
+ // If this is putmem request, read input data from the upstream FIFO
+ if (!i_isFlagRead)
+ {
+ // l_sizeMultiplier * 4B Upstream FIFO = Granule size 128B
+ uint32_t l_len2dequeue = l_sizeMultiplier;
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue,
+ (uint32_t *)&l_dataFifo,
+ false);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+ // Call PBA access
+ l_fapiRc = p9_pba_access(
+ l_proc,
+ l_addr,
+ i_isFlagRead,
+ ((l_isFastMode) ? (1<<PBA_FAST_MODE_SHIFT) : 0),
+ l_firstGran,
+ l_lastGran,
+ (uint8_t *)&l_dataFifo);
+
+ // if p9_pba_access returns error
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" p9_pba_access Failed");
+ // Respond with HWP FFDC
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ // If this is a getmem request,
+ // need to push the data into the downstream FIFO
+ if (i_isFlagRead)
+ {
+ // Number of 4Bytes to put, to align with Granule Size
+ uint32_t l_len = l_sizeMultiplier; // l_len*4 = Granule Size
+ l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_dataFifo);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+ l_granulesCompleted++;
+ l_numCurrAcc++;
+ } // End inner while loop
+
+ if ( (l_fapiRc != FAPI2_RC_SUCCESS) ||
+ (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) )
+ {
+ break;
+ }
+ l_addr += l_granuleSize * l_granulesCompleted;
+ } // End..while (l_granulesCompleted < l_lenCacheAligned);
+
+ // Now build and enqueue response into downstream FIFO
+ do
+ {
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ // If there was a HWP failure for putmem request,
+ // need to Flush out upstream FIFO, until EOT arrives
+ if (!i_isFlagRead)
+ {
+ l_rc = flushUpstreamFifo(l_fapiRc);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+
+ // first enqueue the length of data actually written
+ uint32_t l_len = 1;
+ uint32_t l_respLen = l_granulesCompleted * l_granuleSize;
+
+ SBE_INFO(SBE_FUNC "Total length Pushed for ChipOp [%d]", l_respLen);
+ l_rc = sbeDownFifoEnq_mult ( l_len, &l_respLen );
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// @brief processAduRequest - Internal Method to this file,
+// To process the ADU Access request
+//
+// @param [in] i_hdr, Message Request Header
+// @param [in] i_isFlagRead, Read/Write Flag
+//
+// @return RC from the method
+///////////////////////////////////////////////////////////////////////
+uint32_t processAduRequest(const sbeMemAccessReqMsgHdr_t &i_hdr,
+ const bool i_isFlagRead)
+{
+ #define SBE_FUNC " processAduRequest "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+
+ // Default for ADU
+ uint32_t l_sizeMultiplier = ADU_SIZE_MULTIPLIER_FOR_LEN_ALIGNMENT;
+ uint32_t l_granuleSize = ADU_GRAN_SIZE_BYTES;
+
+ // Adu Setup Flag
+ uint32_t l_aduSetupFlags = constructAduFlag(i_hdr, i_isFlagRead);
+
+ // For local Use
+ bool l_isEccMode = i_hdr.isEccFlagSet();
+ bool l_isItagMode = i_hdr.isItagFlagSet();
+ uint64_t l_addr = i_hdr.getAddr();
+
+ // Proc Chip Target
+ Target<fapi2::TARGET_TYPE_PROC_CHIP> l_proc = plat_getChipTarget();
+
+ // The max granule size for which the ADU/PBA interface if configured
+ uint32_t l_numGranules = 0;
+ // Keeps track of number of granules sent to HWP
+ uint64_t l_granulesCompleted = 0;
+
+ // Input Data length in alignment with PBA (128 Bytes)
+ uint64_t l_lenCacheAligned = i_hdr.getDataLenCacheAlign();
+ SBE_DEBUG(SBE_FUNC "Data Aligned Len / Number of data granules = %d",
+ l_lenCacheAligned);
+
+ while (l_granulesCompleted < l_lenCacheAligned)
+ {
+ // Call the ADU setup HWP
+ l_fapiRc = p9_adu_setup (l_proc,
+ l_addr,
+ i_isFlagRead,
+ l_aduSetupFlags,
+ l_numGranules);
+ // if p9_adu_setup returns error
+ if( (l_fapiRc != FAPI2_RC_SUCCESS) )
+ {
+ SBE_ERROR(SBE_FUNC" p9_adu_setup Failed");
+ // Respond with HWP FFDC
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ // Assumption is Hwp won't return zero for Num Granules
+ assert(0 != l_numGranules);
+
+ SBE_INFO(SBE_FUNC "Hwp returned l_numGranules=[0x%08X]",l_numGranules);
+ uint64_t l_numAcc = 0;
+
+ if (l_numGranules < (l_lenCacheAligned - l_granulesCompleted))
+ {
+ l_numAcc = l_numGranules;
+ }
+ else
+ {
+ l_numAcc = l_lenCacheAligned - l_granulesCompleted;
+ }
+
+ // 8Byte granule for ADU access
+ uint32_t l_dataFifo[MAX_ADU_BUFFER] = {0};
+
+ uint64_t l_numCurrAcc = 0;
+ while (l_numCurrAcc < l_numAcc)
+ {
+ bool l_lastGran = (l_numCurrAcc == (l_numAcc-1)) ? true : false;
+ bool l_firstGran = (l_numCurrAcc == 0) ? true : false;
+
+ // With ECC or ITAG the output length of a granule will become
+ // 9 bytes instead of 8, To align it we will merge 4 output granule
+ // before putting it in the Downstream FIFO i.e. 9*4 = 36Bytes
+ // which is 4Bytes aligned size.
+ // With Both ECC and ITag, the o/p length of a granule will become
+ // 10Bytes instead of 8, To align it we will merge 4 output granule
+ // before putting it in the Downstream FIFO i.e. 10*4 = 40bytes
+ // So in ADU Read case we will use the same buffer with 10Bytes
+ // offset to fill the 40bytes.
+
+ // Both Ecc and ITag Present = 40Bytes is the alignment length
+ /* D[00] D[01] D[02] D[03] D[04] D[05] D[06] D[07] -> 8 Data Bytes
+ * D[08-Itag] D[09-Ecc] D[0a] D[0b] D[0c] D[0d] D[0e] D[0f] -> 6D B
+ * D[10] D[11] D [12-Itag] D[13-Ecc] D[14] D[15] D[16] D[17]
+ * D[18] D[19] D[1a] D[1b] D[1c-Itag] D[1d-Ecc] D[1e] D[1f]
+ * D[20] D[21] D[22] D[23] D[24] D[25] D[26-Itag] D[27-Ecc]
+ */
+ // Only Ecc Present = 36 Bytes is the alignment length
+ /* D[00] D[01] D[02] D[03] D[04] D[05] D[06] D[07] -> 8 Data Bytes
+ * D[08-Ecc] D[09] D[0a] D[0b] D[0c] D[0d] D[0e] D[0f] -> 7D B
+ * D[10] D[11-Ecc] D [12] D[13] D[14] D[15] D[16] D[17]
+ * D[18] D[19] D[1a-Ecc] D[1b] D[1c] D[1d] D[1e] D[1f]
+ * D[20] D[21] D[22] D[23-Ecc]
+ */
+ // Only ITag Present = 36 Bytes is the alignment length
+ /* D[00] D[01] D[02] D[03] D[04] D[05] D[06] D[07] -> 8 Data Bytes
+ * D[08-Itag] D[09] D[0a] D[0b] D[0c] D[0d] D[0e] D[0f] -> 7D B
+ * D[10] D[11-Itag] D [12] D[13] D[14] D[15] D[16] D[17]
+ * D[18] D[19] D[1a-Itag] D[1b] D[1c] D[1d] D[1e] D[1f]
+ * D[20] D[21] D[22] D[23-Itag]
+ */
+ uint8_t l_bufIdx = 0;
+
+ // If this is putmem request, read input data from the upstream FIFO
+ if (!i_isFlagRead)
+ {
+ // l_sizeMultiplier * 4B Upstream FIFO = Granule size 128B
+ uint32_t l_len2dequeue = l_sizeMultiplier;
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue,
+ (uint32_t *)&l_dataFifo,
+ false);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ // Insert the ECC if ECC Mode is set
+ if(l_isEccMode)
+ {
+ uint8_t l_eccPos = 8;
+ if(l_isItagMode)
+ {
+ l_eccPos = 9;
+ }
+ ((uint8_t*)&l_dataFifo)[l_eccPos] = i_hdr.eccByte;
+ }
+ }
+ else
+ {
+ //Adu Read Mode - with either ECC or ITag or Both
+ // Calculate the MODULUS
+ uint8_t l_mod = (l_numCurrAcc % 4);
+ if( (l_mod) && ((l_isEccMode) || (l_isItagMode)) )
+ {
+ // Default Init it for 1byte extra
+ l_bufIdx = (ADU_GRAN_SIZE_BYTES * l_mod) + l_mod;
+ if((l_isEccMode) && (l_isItagMode))
+ {
+ l_bufIdx = l_bufIdx + l_mod;
+ }
+ }
+ }
+
+ // Call ADU access HWP for ADU write/read request
+ l_fapiRc = p9_adu_access (
+ l_proc,
+ l_addr,
+ i_isFlagRead,
+ l_aduSetupFlags,
+ l_firstGran,
+ l_lastGran,
+ &(((uint8_t *)&(l_dataFifo))[l_bufIdx]));
+ // if p9_adu_access returns error
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" p9_adu_access Failed");
+ // Respond with HWP FFDC
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION );
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ // If this is a getmem request,
+ // need to push the data into the downstream FIFO
+ if (i_isFlagRead)
+ {
+ // Number of 4Bytes to put, to align with Granule Size
+ uint32_t l_len = l_sizeMultiplier; // l_len*4 = Granule Size
+
+ //Enter the below 'if' if ADU Read Mode with Either Ecc or ITag
+ //or both set. During non-aligned Transaction (but not the last)
+ //then set the len as zero so as to skip the unalign byte send,
+ //during next transaction when the data is aligned it will take
+ //care of sending all granules.
+ //If the below condition is not met then for ADU Read Mode will
+ //happen to write on DownStream FIFO for each granule.
+
+ //Calculate the MODULUS
+ uint8_t l_mod = (l_numCurrAcc % 4);
+ if((l_isEccMode) || (l_isItagMode))
+ {
+ if( (l_mod == 3) || (l_lastGran) )
+ {
+ l_len = calInterAduLenForUpFifo(l_mod,l_isItagMode,
+ l_isEccMode);
+ l_len = align4ByteWordLength(l_len);
+ }
+ else
+ {
+ // If it is not the last granule or on the 4th entry
+ // into the data buffer, need not send it to Upstream
+ // Fifo
+ l_len = 0;
+ }
+ }
+ if(l_len)
+ {
+ l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_dataFifo);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+ }
+ l_granulesCompleted++;
+ l_numCurrAcc++;
+ } // End inner while loop
+
+ if ( (l_fapiRc != FAPI2_RC_SUCCESS) ||
+ (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) )
+ {
+ break;
+ }
+
+ l_addr += l_granuleSize * l_granulesCompleted;
+ } // End..while (l_granulesCompleted < l_lenCacheAligned);
+
+ // Now build and enqueue response into downstream FIFO
+ do
+ {
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ // If there was a HWP failure for putmem request,
+ // need to Flush out upstream FIFO, until EOT arrives
+ if (!i_isFlagRead)
+ {
+ l_rc = flushUpstreamFifo(l_fapiRc);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ }
+
+ // first enqueue the length of data actually written
+ uint32_t l_len = 1;
+ uint32_t l_respLen = sbeAduLenInUpStreamFifo(
+ l_granulesCompleted,
+ l_isItagMode,
+ l_isEccMode);
+
+ SBE_INFO(SBE_FUNC "Total length Pushed for ChipOp [%d]", l_respLen);
+ l_rc = sbeDownFifoEnq_mult ( l_len, &l_respLen );
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeMemAccess_Wrap Memory Access Wrapper function
+//
+// @param [in] i_isFlagRead Flag to indicate the memory Access Type
+// true : GetMem ChipOp
+// false : PutMem ChipOp
+//
+// @return RC from the method
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeMemAccess_Wrap(const bool i_isFlagRead)
+{
+ #define SBE_FUNC " sbeMemAccess_Wrap "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ // Create an instance of Memory Access ChipOp structure
+ sbeMemAccessReqMsgHdr_t l_req = {0};
+
+ // Offload the common header from the Upstream FIFO
+ uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, (uint32_t *)&l_req, i_isFlagRead);
+
+ if(!l_rc)
+ {
+ // Calculate the PBA/ADU address from the given input
+ SBE_INFO(SBE_FUNC "Address Upper[0x%08X] Lower[0x%08X] Flags[0x%08X] "
+ "Length[0x%08X]", ((l_req.getAddr()>>32) & 0xFFFFFFFF),
+ (l_req.getAddr() & 0xFFFFFFFF), l_req.flags, l_req.len);
+
+ // PBA
+ bool l_isPBA = l_req.isPbaFlagSet();
+ if(l_isPBA)
+ {
+ l_rc = processPbaRequest(l_req, i_isFlagRead);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC "processPbaRequest failed");
+ }
+ }
+ // ADU
+ else
+ {
+ l_rc = processAduRequest(l_req, i_isFlagRead);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC "processAduRequest failed");
+ }
+ }
+ }
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutMem (uint8_t *i_pArg)
+{
+ return sbeMemAccess_Wrap (false);
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetMem (uint8_t *i_pArg)
+{
+ return sbeMemAccess_Wrap (true);
+}
+
diff --git a/src/sbefw/sbecmdmemaccess.H b/src/sbefw/sbecmdmemaccess.H
new file mode 100644
index 00000000..6a2449fc
--- /dev/null
+++ b/src/sbefw/sbecmdmemaccess.H
@@ -0,0 +1,54 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdmemaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdmemaccess.H
+ *
+ * @brief This file contains the Interfaces for the Memory Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDMEMACCESS_H
+#define __SBEFW_SBECMDMEMACCESS_H
+
+#include <stdint.h>
+
+/**
+ * @brief sbeGetMem : Implements SBE Get Memory ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetMem (uint8_t *i_pArg);
+
+/**
+ * @brief sbePutMem : Implements SBE Put Memory ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutMem (uint8_t *i_pArg);
+
+#endif /* __SBEFW_SBECMDMEMACCESS_H */
diff --git a/src/sbefw/sbecmdparser.C b/src/sbefw/sbecmdparser.C
new file mode 100644
index 00000000..c22e67c7
--- /dev/null
+++ b/src/sbefw/sbecmdparser.C
@@ -0,0 +1,483 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdparser.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdparser.C
+ *
+ * @brief This file contains the SBE FIFO Commands
+ *
+ */
+
+#include "sbecmdparser.H"
+#include "sbecmdscomaccess.H"
+#include "sbecmdiplcontrol.H"
+#include "sbecmdgeneric.H"
+#include "sbecmdmemaccess.H"
+#include "sbecmdregaccess.H"
+#include "sbecmdcntrldmt.H"
+#include "sbecmdringaccess.H"
+#include "sbecmdsram.H"
+#include "sbecmdcntlinst.H"
+#include "sbecmdringaccess.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeHostMsg.H"
+#include "sbe_host_intf.H"
+#include "sbestates.H"
+#include "sberegaccess.H"
+
+// Declaration
+static const uint16_t HARDWARE_FENCED_STATE =
+ SBE_FENCE_AT_CONTINUOUS_IPL|SBE_FENCE_AT_QUIESCE|
+ SBE_FENCE_AT_DMT;
+
+static const uint16_t PUT_HARDWARE_FENCED_STATE =
+ HARDWARE_FENCED_STATE|SBE_FENCE_AT_MPIPL;
+
+////////////////////////////////////////////////////////////////
+// @brief g_sbeScomCmdArray
+////////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeScomCmdArray [] =
+{
+ {sbeGetScom,
+ SBE_CMD_GETSCOM,
+ HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+ {sbePutScom,
+ SBE_CMD_PUTSCOM,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+ {sbeModifyScom,
+ SBE_CMD_MODIFYSCOM,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+ {sbePutScomUnderMask,
+ SBE_CMD_PUTSCOM_MASK,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+ {sbeMultiScom,
+ SBE_CMD_MULTISCOM,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+};
+
+////////////////////////////////////////////////////////////////
+// @brief g_sbeIplControlCmdArray
+//
+////////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeIplControlCmdArray [] =
+{
+ {sbeHandleIstep,
+ SBE_CMD_EXECUTE_ISTEP,
+ PUT_HARDWARE_FENCED_STATE|SBE_FENCE_AT_RUNTIME|
+ SBE_FENCE_AT_DUMPING,
+ // This is allowed in FFDC Collect state
+ // TODO - Issue 157287 - Allow MPIIPL in Isteps state
+ },
+
+ {sbeContinueBoot,
+ SBE_CMD_CONTINUE_BOOT,
+ PUT_HARDWARE_FENCED_STATE|SBE_FENCE_AT_RUNTIME|
+ SBE_FENCE_AT_DUMPING|SBE_FENCE_AT_ISTEP,
+ // This is allowed only in FFDC Collect State in PLCK mode
+ },
+};
+
+////////////////////////////////////////////////////////////////
+// @brief g_sbeGenericCmdArray
+//
+////////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeGenericCmdArray [] =
+{
+ {sbeGetCapabilities,
+ SBE_CMD_GET_SBE_CAPABILITIES,
+ SBE_STATE_FFDC_COLLECT,
+ // Fence in FFDC Collect State, since it might over-write traces
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeMemoryAccessCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeMemoryAccessCmdArray [] =
+{
+ {sbeGetMem,
+ SBE_CMD_GETMEM,
+ HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+
+ {sbePutMem,
+ SBE_CMD_PUTMEM,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+
+ {sbeGetOccSram,
+ SBE_CMD_GETSRAM_OCC,
+ HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+
+ {sbePutOccSram,
+ SBE_CMD_PUTSRAM_OCC,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeInstructionCntlCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeInstructionCntlCmdArray[] =
+{
+ {sbeCntlInst,
+ SBE_CMD_CONTROL_INSTRUCTIONS,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeRegAccessCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeRegAccessCmdArray [] =
+{
+ {sbeGetReg,
+ SBE_CMD_GETREG,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+
+ {sbePutReg,
+ SBE_CMD_PUTREG,
+ PUT_HARDWARE_FENCED_STATE|SBE_STATE_FFDC_COLLECT,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeMpiplCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeMpiplCmdArray[] =
+{
+ {sbeEnterMpipl,
+ SBE_CMD_MPIPL_ENTER,
+ PUT_HARDWARE_FENCED_STATE|SBE_FENCE_AT_ISTEP|
+ SBE_FENCE_AT_DUMPING|SBE_FENCE_AT_ABORT,
+ // Allow Fspless system to enter MPIPL
+ // Honour MPIPL at FFDC Collect state
+ // Issue 157287
+ },
+
+ {sbeContinueMpipl,
+ SBE_CMD_MPIPL_CONTINUE,
+ HARDWARE_FENCED_STATE|SBE_FENCE_AT_ISTEP|
+ SBE_FENCE_AT_RUNTIME|SBE_FENCE_AT_DUMPING|
+ SBE_FENCE_AT_ABORT|SBE_FENCE_AT_FFDC_COLLECT,
+ // Only allowed State is MPIPL
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeRingAccessCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeRingAccessCmdArray [] =
+{
+ {sbeGetRing,
+ SBE_CMD_GETRING,
+ SBE_FENCE_AT_CONTINUOUS_IPL,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbeCoreStateControlCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbeCoreStateControlCmdArray [] =
+{
+ {sbeControlDeadmanTimer,
+ SBE_PSU_CMD_CONTROL_DEADMAN,
+ SBE_FENCE_AT_CONTINUOUS_IPL|SBE_FENCE_AT_QUIESCE|
+ SBE_FENCE_AT_MPIPL|SBE_FENCE_AT_ISTEP|
+ SBE_FENCE_AT_DUMPING|SBE_FENCE_AT_ABORT|
+ SBE_FENCE_AT_FFDC_COLLECT,
+ },
+};
+
+//////////////////////////////////////////////////////////////
+// @brief g_sbePutRingFromImageCmdArray
+//
+//////////////////////////////////////////////////////////////
+static sbeCmdStruct_t g_sbePutRingFromImageCmdArray [] =
+{
+ {sbePutRingFromImagePSU,
+ SBE_PSU_MSG_PUT_RING_FROM_IMAGE,
+ SBE_FENCE_AT_CONTINUOUS_IPL,
+ },
+};
+
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+uint8_t sbeGetCmdStructAttr (const uint8_t i_cmdClass,
+ sbeCmdStruct_t **o_ppCmd)
+{
+ #define SBE_FUNC " sbeGetCmdStructAttr "
+ uint8_t l_numCmds = 0;
+ *o_ppCmd = NULL;
+
+ switch(i_cmdClass)
+ {
+ // FIFO Commands
+ case SBE_CMD_CLASS_IPL_CONTROL:
+ // @TODO via RTC : 128655
+ // Use C++ style typecase
+ l_numCmds = sizeof(g_sbeIplControlCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeIplControlCmdArray;
+ break;
+ case SBE_CMD_CLASS_SCOM_ACCESS:
+ l_numCmds = sizeof(g_sbeScomCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeScomCmdArray;
+ break;
+ case SBE_CMD_CLASS_GENERIC_MESSAGE:
+ l_numCmds = sizeof(g_sbeGenericCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeGenericCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_MEMORY_ACCESS:
+ l_numCmds = sizeof(g_sbeMemoryAccessCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeMemoryAccessCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_INSTRUCTION_CONTROL:
+ l_numCmds = sizeof(g_sbeInstructionCntlCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeInstructionCntlCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_REGISTER_ACCESS:
+ l_numCmds = sizeof(g_sbeRegAccessCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeRegAccessCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_RING_ACCESS:
+ l_numCmds = sizeof(g_sbeRingAccessCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeRingAccessCmdArray;
+ break;
+
+ case SBE_CMD_CLASS_MPIPL_COMMANDS:
+ l_numCmds = sizeof(g_sbeMpiplCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeMpiplCmdArray;
+ break;
+
+ // PSU Commands
+ case SBE_PSU_CMD_CLASS_CORE_STATE:
+ l_numCmds = sizeof(g_sbeCoreStateControlCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbeCoreStateControlCmdArray;
+ break;
+
+ case SBE_PSU_CMD_CLASS_RING_ACCESS:
+ l_numCmds = sizeof(g_sbePutRingFromImageCmdArray) /
+ sizeof(sbeCmdStruct_t);
+ *o_ppCmd = (sbeCmdStruct_t*)g_sbePutRingFromImageCmdArray;
+ break;
+
+ // This will grow with each class of chipOp in future
+ default:
+ break;
+ }
+ return l_numCmds;
+ #undef SBE_FUNC
+}
+
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+uint8_t sbeValidateCmdClass (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode)
+{
+ #define SBE_FUNC " sbeValidateCmdClass "
+ uint8_t l_rc = SBE_SEC_COMMAND_NOT_SUPPORTED;
+
+ SBE_INFO(SBE_FUNC"i_cmdClass[0x%02X], "
+ "i_cmdOpcode[0x%02X]", i_cmdClass, i_cmdOpcode);
+
+ do
+ {
+ uint8_t l_numCmds = 0;
+ sbeCmdStruct_t *l_pCmd = NULL;
+
+ l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd);
+ if (!l_numCmds)
+ {
+ SBE_ERROR(SBE_FUNC"SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED "
+ "i_cmdClass[0x%02X], i_cmdOpcode[0x%02X]",
+ i_cmdClass, i_cmdOpcode);
+ // Command class not supported
+ l_rc = SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED;
+ break;
+ }
+
+ // @TODO via RTC : 128654
+ // Analyze on merging the validation functions into one
+ // and also on using loop vs switch case performance
+ for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd)
+ {
+ if (i_cmdOpcode == l_pCmd->cmd_opcode)
+ {
+ // Command found
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+ }
+ } while (false);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+bool sbeIsCmdAllowedAtState (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode)
+{
+ #define SBE_FUNC " sbeIsCmdAllowedAtState "
+ uint8_t l_numCmds = 0;
+ sbeCmdStruct_t *l_pCmd = NULL;
+ bool l_ret = false;
+ l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd);
+
+ for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd)
+ {
+ if (i_cmdOpcode == l_pCmd->cmd_opcode)
+ {
+ // Get the Present State
+ uint64_t l_state =
+ SbeRegAccess::theSbeRegAccess().getSbeState();
+ SBE_INFO(SBE_FUNC "SBE State [0x%08X] Fence State[0x%04X]",
+ (uint32_t)(l_state & 0xFFFFFFFF),l_pCmd->cmd_state_fence);
+
+ switch(l_state)
+ {
+ case SBE_STATE_QUIESCE:
+ case SBE_STATE_UNKNOWN:
+ case SBE_STATE_FAILURE:
+ // All operations are fenced here, return false
+ // Reset is the only Option available
+ break;
+
+ case SBE_STATE_FFDC_COLLECT:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_FFDC_COLLECT)? false:true);
+ break;
+ }
+
+ case SBE_STATE_IPLING:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_CONTINUOUS_IPL)? false:true);
+ break;
+ }
+
+ case SBE_STATE_ISTEP:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_ISTEP)? false:true);
+ break;
+ }
+
+ case SBE_STATE_RUNTIME:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_RUNTIME)? false:true);
+ break;
+ }
+
+ case SBE_STATE_DUMP:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_DUMPING)? false:true);
+ break;
+ }
+
+ case SBE_STATE_MPIPL:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_MPIPL)? false:true);
+ break;
+ }
+
+ case SBE_STATE_DMT:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_DMT)? false:true);
+ break;
+ }
+
+ case SBE_STATE_ABORT:
+ {
+ l_ret = ((l_pCmd->cmd_state_fence &
+ SBE_FENCE_AT_ABORT)? false:true);
+ break;
+ }
+
+ default: break;
+ }
+ }
+ }
+ // For any other state, which is not handled above, return from here
+ return l_ret;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+sbeCmdFunc_t sbeFindCmdFunc (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode)
+
+{
+ #define SBE_FUNC " sbeFindCmdFunc "
+ uint8_t l_numCmds = 0;
+ sbeCmdStruct_t *l_pCmd = NULL;
+
+ l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd);
+
+ for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd)
+ {
+ if (i_cmdOpcode == l_pCmd->cmd_opcode)
+ {
+ break;
+ }
+ }
+
+ return l_pCmd ? (l_pCmd->cmd_func) : NULL;
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbecmdparser.H b/src/sbefw/sbecmdparser.H
new file mode 100644
index 00000000..d51995f2
--- /dev/null
+++ b/src/sbefw/sbecmdparser.H
@@ -0,0 +1,119 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdparser.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdparser.H
+ *
+ * @brief This file contains the SBE command details
+ *
+ */
+
+#ifndef __SBEFW_SBECMDPARSER_H
+#define __SBEFW_SBECMDPARSER_H
+
+#include <stdint.h>
+
+
+/**
+ * @brief SBE Command structure associating an opcode of a command
+ * to the processing function as well as the allowed states
+ *
+ */
+typedef uint32_t (*sbeChipOpFunc_t) (uint8_t *i_pArg);
+
+typedef struct {
+ sbeChipOpFunc_t cmd_func; /* Command function pointer */
+ uint8_t cmd_opcode; /* Command opcode */
+ uint16_t cmd_state_fence; /* Command fencing based on SBE state */
+} sbeCmdStruct_t;
+
+/**
+ * @brief SBE Command Fence attributes
+ *
+ */
+enum sbe_command_fence_attrs
+{
+ SBE_NO_FENCE = 0x0000, ///< Allow cmd in all states
+ SBE_FENCE_AT_ABORT = 0x0001, ///< Fence off at SBE Abort State
+ SBE_FENCE_AT_FFDC_COLLECT = 0x0002, ///< Fence off at FFDC Collect State
+ SBE_FENCE_AT_DUMPING = 0x0004, ///< Fence off at DUMPING State
+ SBE_FENCE_AT_MPIPL = 0x0010, ///< Fence off at MPIPL state
+ SBE_FENCE_AT_CONTINUOUS_IPL = 0x0040, ///< Fence off at cont IPL
+ SBE_FENCE_AT_ISTEP = 0x0080, ///< Fence off at istep state
+ SBE_FENCE_AT_RUNTIME = 0x0100, ///< Fence off at Runtime state
+ SBE_FENCE_AT_QUIESCE = 0x0200, ///< Fense off at Quiesce state
+ SBE_FENCE_AT_DMT = 0x0400, ///< Fense off at DMT state
+};
+
+/**
+ * @brief sbeValidateCmdClass Validates the command class and opcode
+ *
+ * @param[in] i_cmdClass Command class code
+ * @param[in] i_cmdOpcode Command opcode
+ *
+ * @return uint8_t return code
+ * SBE_SEC_OPERATION_SUCCESSFUL - Command found
+ * SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED
+ * SBE_SEC_COMMAND_NOT_SUPPORTED
+ */
+uint8_t sbeValidateCmdClass (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode);
+
+/**
+ * @brief sbeIsCmdAllowedAtState Validates if the command is allowed
+ * at the current SBE state
+ *
+ * @param[in] i_cmdClass Command class code
+ * @param[in] i_cmdOpcode Command opcode
+ *
+ * @return true command is allowed at the current state
+ * false command is not allowed at the current state
+ */
+bool sbeIsCmdAllowedAtState (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode);
+
+
+/**
+ * @brief sbeCmdFunc_t Typical signature for any SBE ChipOp back-end function
+ *
+ * @param[in] uint8_t *i_pArg Pointer to the argument to be passed to
+ * the chipOp function
+ *
+ * @return uint32_t Return code from the chipOp function
+ */
+typedef uint32_t ( *sbeCmdFunc_t ) (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbeFindCmdFunc Finds the function corresponding to the command
+ *
+ * @param[in] i_cmdClass Command class code
+ * @param[in] i_cmdOpcode Command opcode
+ *
+ * @return sbeCmdFunc_t A pointer to the corresponding ChipOps function
+ */
+sbeCmdFunc_t sbeFindCmdFunc (const uint8_t i_cmdClass,
+ const uint8_t i_cmdOpcode);
+
+
+#endif // __SBEFW_SBECMDPARSER_H
diff --git a/src/sbefw/sbecmdprocessor.C b/src/sbefw/sbecmdprocessor.C
new file mode 100644
index 00000000..6a945b4a
--- /dev/null
+++ b/src/sbefw/sbecmdprocessor.C
@@ -0,0 +1,376 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdprocessor.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdprocessor.C
+ *
+ * @brief This file contains the SBE Command processing Thread Routines
+ *
+ */
+
+
+#include "sbeexeintf.H"
+#include "sbefifo.H"
+#include "sbecmdparser.H"
+#include "sbeirq.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "assert.h"
+#include "sbeFifoMsgUtils.H"
+#include "sbeerrorcodes.H"
+#include "sbeHostUtils.H"
+#include "sbeHostMsg.H"
+#include "sbecmdiplcontrol.H"
+#include "sberegaccess.H"
+#include "sbestates.H"
+#include "fapi2.H"
+
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+void sbeHandlePsuResponse (const uint32_t i_rc)
+{
+ #define SBE_FUNC " sbeHandlePsuResponse "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ do
+ {
+ uint8_t l_cnt = 0;
+ switch (i_rc)
+ {
+ case SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED:
+ case SBE_SEC_COMMAND_NOT_SUPPORTED:
+ case SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE:
+ // Caller sent an invalid Command class/opcode
+ // Set the Ack bit in SBE->PSU DB register
+ l_rc = sbeAcknowledgeHost();
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ break;
+ }
+ // Set primary and secondary status
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INVALID_COMMAND, i_rc);
+
+ // Now Update SBE->PSU Mbx Reg4 with response
+ l_cnt = sizeof(g_sbeSbe2PsuRespHdr)/
+ sizeof(uint64_t);
+ l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ reinterpret_cast<const uint64_t *>(
+ &g_sbeSbe2PsuRespHdr), l_cnt, true);
+ break;
+
+ case SBE_SEC_OS_FAILURE:
+ // Set primary and secondary status
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ i_rc);
+
+ // Now Update SBE->PSU Mbx Reg4 with response
+ l_cnt = sizeof(g_sbeSbe2PsuRespHdr)/
+ sizeof(uint64_t);
+ l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4,
+ reinterpret_cast<const uint64_t *>(
+ &g_sbeSbe2PsuRespHdr), l_cnt, true);
+ break;
+
+ case SBE_SEC_OPERATION_SUCCESSFUL:
+ // Services code successfully executed the chipOp.
+ SBE_INFO(SBE_FUNC"PSU ChipOp Done");
+ break;
+
+ default:
+ // The only possibility (as of now) to reach till this point
+ // is when there was a mbx register access (scom) failure
+ // happened. Going to return to the waiting loop.
+ break;
+ }
+ } while(false);
+
+ #undef SBE_FUNC
+}
+
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+void sbeHandleFifoResponse (const uint32_t i_rc)
+{
+ #define SBE_FUNC " sbeHandleFifoResponse "
+ SBE_ENTER(SBE_FUNC);
+
+ do
+ {
+ uint16_t l_primStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Handle FIFO reset case
+ if (i_rc == SBE_FIFO_RESET_RECEIVED)
+ {
+ break;
+ }
+
+ if ( (i_rc == SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA) ||
+ (i_rc == SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA) )
+ {
+ l_primStatus = SBE_PRI_INVALID_DATA;
+ }
+
+ uint32_t l_len2dequeue = 0;
+ uint32_t l_dist2StatusHdr = 0;
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+ uint32_t l_secStatus = i_rc;
+
+ switch (i_rc)
+ {
+ case SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED:
+ case SBE_SEC_COMMAND_NOT_SUPPORTED:
+ case SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE:
+ // Caller sent Invalid Command
+
+ case SBE_SEC_OS_FAILURE:
+ // PK API Failures
+
+ // Flush out the upstream FIFO till EOT arrives
+ l_len2dequeue = 1;
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, NULL,
+ true, true);
+
+ if ( (l_rc == SBE_FIFO_RESET_RECEIVED) ||
+ (l_rc == SBE_SEC_FIFO_ACCESS_FAILURE) )
+ {
+ break;
+ }
+
+ if (l_rc)
+ {
+ l_secStatus = l_rc;
+ }
+
+ // Don't break here to force the flow through
+ // the next case to enqueue the response into
+ // the downstream FIFO
+
+ case SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA:
+ case SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA:
+ // EOT arrived prematurely in upstream FIFO
+ // or there were unexpected data in upstream FIFO
+
+ SBE_ERROR(SBE_FUNC"Operation failure, "
+ "l_primStatus[0x%08X], "
+ "l_secStatus[0x%08X]",
+ l_primStatus, l_secStatus);
+
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_dist2StatusHdr,
+ l_primStatus,
+ l_secStatus,
+ 0);
+ l_rc = sbeDownFifoEnq_mult (++l_dist2StatusHdr,
+ &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoEnq_mult failure,"
+ " l_rc[0x0%08X]", l_rc);
+ // not attempting to signal EOT
+ break;
+ }
+ // Follow through to signal EOT in downstream
+
+ case SBE_SEC_OPERATION_SUCCESSFUL: // Successful execution
+ // Signal EOT in Downstream FIFO
+ l_rc = sbeDownFifoSignalEot();
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoSignalEot failure,"
+ " l_rc[0x0%08X]", l_rc);
+ }
+ SBE_INFO(SBE_FUNC"ChipOp Done");
+ break;
+
+ default:
+ break;
+ }
+ } while (false);
+
+ #undef SBE_FUNC
+}
+
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+void sbeSyncCommandProcessor_routine(void *i_pArg)
+{
+ #define SBE_FUNC " sbeSyncCommandProcessor_routine "
+ SBE_ENTER(SBE_FUNC);
+
+ // Check the destination bit at the start
+ if(SbeRegAccess::theSbeRegAccess().isIstepMode())
+ {
+ // In this state, we need not take care of FFDC State, User may
+ // or may not fetch FFDC and may not issue sbeContinueboot
+ SBE_INFO(SBE_FUNC"Continuous IPL mode not set, will wait for "
+ "commands...");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_ISTEP);
+ }
+ // If Istep mode is not set, it makes sense to check if we are directly
+ // in runtime.
+ else if(true == SbeRegAccess::theSbeRegAccess().isDestBitRuntime())
+ {
+ SBE_INFO(SBE_FUNC"Destination bit tells us to go to runtime");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_RUNTIME);
+ }
+ // Now we can assume that we are in Continuous IPL mode, just check if
+ // FFDC needs to be collected before continuing with IPL
+ else if(true == SbeRegAccess::theSbeRegAccess().isCollectFFDCSet())
+ {
+ SBE_INFO(SBE_FUNC"FFDC Collect State - Waiting for FFDC to be picked");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_FFDC_COLLECT);
+ }
+ else
+ {
+ SBE_INFO(SBE_FUNC"Continuous IPL Mode set... IPLing");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_IPLING);
+ sbeDoContinuousIpl();
+ }
+
+ do
+ {
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Wait for new command processing
+ int l_rcPk = pk_semaphore_pend (
+ &g_sbeSemCmdProcess, PK_WAIT_FOREVER);
+
+ do
+ {
+ // Local Variables
+ uint8_t l_cmdClass = 0;
+ uint8_t l_cmdOpCode = 0;
+
+ // Reset the value of fapi2::current_err from previous value.
+ // This is required as none of procedure set this value in success
+ // case. So if we do not reset previous value, previous failure
+ // will impact new chipops also.
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Check on the Rx Thread Interrupt Bits for Interrupt Status
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_PSU) )
+ {
+ l_rc = g_sbeSbe2PsuRespHdr.secStatus;
+ l_cmdClass = g_sbePsu2SbeCmdReqHdr.cmdClass;
+ l_cmdOpCode = g_sbePsu2SbeCmdReqHdr.command;
+ // Set this here, so that during response handling we know which
+ // interrupt we are processing, need not check for
+ // g_sbeIntrSource again
+ g_sbeIntrSource.setIntrSource(SBE_PROC_ROUTINE,
+ SBE_INTERFACE_PSU);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ l_rc = g_sbeCmdRespHdr.sec_status;
+ l_cmdClass = g_sbeFifoCmdHdr.cmdClass;
+ l_cmdOpCode = g_sbeFifoCmdHdr.command;
+ // Set this here, so that during response handling we know which
+ // interrupt we are processing, need not check for
+ // g_sbeIntrSource again
+ g_sbeIntrSource.setIntrSource(SBE_PROC_ROUTINE,
+ SBE_INTERFACE_FIFO);
+ }
+ else // SBE_INTERFACE_FIFO_RESET or SBE_INTERFACE_UNKNOWN
+ {
+ SBE_ERROR(SBE_FUNC"Unexpected interrupt communicated to the "
+ "processor thread. Interrupt source: 0x%02X 0x%02X",
+ g_sbeIntrSource.intrSource, g_sbeIntrSource.rxThrIntrSource);
+ assert(false);
+ break;
+ }
+
+ // PK API failure
+ if (l_rcPk != PK_OK)
+ {
+ SBE_ERROR(SBE_FUNC"pk_semaphore_pend failed, "
+ "l_rcPk=%d, g_sbeSemCmdRecv.count=%d",
+ l_rcPk, g_sbeSemCmdRecv.count);
+
+ // If it's a semphore_pend error then update the same to show
+ // internal failure
+ l_rc = SBE_SEC_OS_FAILURE;
+ }
+
+ // Check for error which Receiver thread might have set
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+
+ // Get the command function
+ sbeCmdFunc_t l_pFuncP = sbeFindCmdFunc (l_cmdClass, l_cmdOpCode);
+ assert( l_pFuncP )
+
+ // Call the ChipOp function
+ l_rc = l_pFuncP ((uint8_t *)i_pArg);
+
+ } while(false); // Inner do..while loop ends here
+
+ SBE_INFO (SBE_FUNC"New cmd arrived, g_sbeSemCmdProcess.count=%d "
+ "l_rc=[0x%04X]",
+ g_sbeSemCmdProcess.count, l_rc);
+
+ if ( g_sbeIntrSource.isSet(SBE_PROC_ROUTINE, SBE_INTERFACE_PSU) )
+ {
+ sbeHandlePsuResponse (l_rc);
+
+ // Enable Host interrupt
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,SBE_INTERFACE_PSU);
+ pk_irq_enable(SBE_IRQ_HOST_PSU_INTR);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_PROC_ROUTINE, SBE_INTERFACE_FIFO) )
+ {
+ sbeHandleFifoResponse (l_rc);
+
+ // Enable the new data available interrupt
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,SBE_INTERFACE_FIFO);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
+ }
+ } while(true); // Thread always exists
+ SBE_EXIT(SBE_FUNC);
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+void sbeAsyncCommandProcessor_routine(void *arg)
+{
+ SBE_INFO("sbeAsyncCommandProcessor Thread started");
+
+ do
+ {
+ // @TODO RTC via : 130392
+ // Add infrastructure for host interface
+
+ } while(0);
+}
diff --git a/src/sbefw/sbecmdreceiver.C b/src/sbefw/sbecmdreceiver.C
new file mode 100644
index 00000000..50f24657
--- /dev/null
+++ b/src/sbefw/sbecmdreceiver.C
@@ -0,0 +1,325 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdreceiver.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdreceiver.C
+ *
+ * @brief This file contains the SBE Command Receiver Thread Routine
+ *
+ */
+
+
+#include "sbeexeintf.H"
+#include "sbefifo.H"
+#include "sbecmdparser.H"
+#include "sbeirq.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbeerrorcodes.H"
+#include "sbeHostMsg.H"
+#include "sbeHostUtils.H"
+#include "sberegaccess.H"
+#include "sbeutil.H"
+
+sbeFifoCmdReqBuf_t g_sbeFifoCmdHdr;
+sbeCmdRespHdr_t g_sbeCmdRespHdr;
+sbePsu2SbeCmdReqHdr_t g_sbePsu2SbeCmdReqHdr;
+sbeSbe2PsuRespHdr_t g_sbeSbe2PsuRespHdr;
+sbeIntrHandle_t g_sbeIntrSource;
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+void sbeCommandReceiver_routine(void *i_pArg)
+{
+ #define SBE_FUNC " sbeCommandReceiver_routine "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ // Update SBE msgg reg to indicate that control loop
+ // is ready now to receive data on its interfaces
+ (void)SbeRegAccess::theSbeRegAccess().setSbeReady();
+
+ // Set Current State to First State i.e. Unknown
+ (void)SbeRegAccess::theSbeRegAccess().updateSbeState(SBE_STATE_UNKNOWN);
+
+ do
+ {
+ // @TODO via RTC: 128944
+ // Read Scratchpad
+ // Wait for new data in FIFO or FIFO reset interrupt or PSU interrupt
+ int l_rcPk = pk_semaphore_pend (&g_sbeSemCmdRecv, PK_WAIT_FOREVER);
+
+ do
+ {
+ uint8_t l_cmdClass = SBE_CMD_CLASS_UNKNOWN;
+ uint8_t l_command = 0xFF;
+
+ // pk API failure
+ if (l_rcPk != PK_OK)
+ {
+ break;
+ }
+
+ SBE_DEBUG(SBE_FUNC"Receiver unblocked");
+
+ // The responsibility of this thread is limited to reading off
+ // the FIFO or PSU interfaces to be able to decode the command
+ // class and the command opcode parameters.
+
+ // Received FIFO Reset interrupt
+ if ( g_sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO_RESET) )
+ {
+ SBE_ERROR(SBE_FUNC"FIFO reset received");
+ l_rc = SBE_FIFO_RESET_RECEIVED;
+ break;
+ }
+
+ // Received PSU interrupt
+ if ( g_sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_PSU) )
+ {
+ //Clear the Interrupt Source bit for PSU
+ g_sbeIntrSource.clearIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_PSU);
+ g_sbeIntrSource.setIntrSource(SBE_RX_ROUTINE,
+ SBE_INTERFACE_PSU);
+ // First clear PSU->SBE DB bit 0
+ l_rc = sbeClearPsu2SbeDbBitX(SBE_PSU2SBE_DOORBELL_CLEAR_BIT0);
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize the g_sbePsu2SbeCmdReqHdr
+ g_sbePsu2SbeCmdReqHdr.init();
+ // Read the request field from PSU->SBE Mbx Reg0
+ uint8_t l_cnt = sizeof(g_sbePsu2SbeCmdReqHdr)/sizeof(uint64_t);
+
+ l_rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG0, l_cnt,
+ (uint64_t *)&g_sbePsu2SbeCmdReqHdr);
+
+ g_sbeSbe2PsuRespHdr.init();
+ l_cmdClass = g_sbePsu2SbeCmdReqHdr.cmdClass;
+ l_command = g_sbePsu2SbeCmdReqHdr.command;
+ } // end if loop for PSU interface chipOp handling
+
+ // Received FIFO New Data interrupt
+ else if ( g_sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ //Clear the Interrupt Source bit for FIFO
+ g_sbeIntrSource.clearIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO);
+ g_sbeIntrSource.setIntrSource(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO);
+
+ // This thread will attempt to unblock the command processor
+ // thread on the following scenarios:
+ // - Normal scenarios where SBE would need to respond to FSP
+ // via downstream FIFO. This includes SUCCESS cases as well
+ // as the cases for Invalid Data sequence or Command
+ // validation failure.
+ // - if there is a need to handle FIFO reset
+
+ // Accordingly, this will update g_sbeCmdRespHdr.prim_status
+ // and g_sbeCmdRespHdr.sec_status for command processor thread
+ // to handle them later in the sequence.
+
+ g_sbeFifoCmdHdr.cmdClass = SBE_CMD_CLASS_UNKNOWN;
+ g_sbeCmdRespHdr.init();
+ uint32_t len = sizeof(g_sbeFifoCmdHdr)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&g_sbeFifoCmdHdr,
+ false );
+
+ // If FIFO reset is requested,
+ if (l_rc == SBE_FIFO_RESET_RECEIVED)
+ {
+ SBE_ERROR(SBE_FUNC"FIFO reset received");
+ break;
+ }
+
+ // If we received EOT out-of-sequence
+ if ( (l_rc == SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA) ||
+ (l_rc == SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA) )
+ {
+ SBE_ERROR(SBE_FUNC"sbeUpFifoDeq_mult failure, "
+ " l_rc=[0x%08X]", l_rc);
+ g_sbeCmdRespHdr.setStatus(SBE_PRI_INVALID_DATA, l_rc);
+
+ // Reassign l_rc to Success to Unblock command processor
+ // thread and let that take the necessary action.
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+
+ l_cmdClass = g_sbeFifoCmdHdr.cmdClass;
+ l_command = g_sbeFifoCmdHdr.command;
+ } // end else if loop for FIFO interface chipOp handling
+
+ // Any other FIFO access issue
+ if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+
+ // validate the command class and sub-class opcodes
+ l_rc = sbeValidateCmdClass (l_cmdClass, l_command) ;
+
+ if (l_rc)
+ {
+ // Command Validation failed;
+ SBE_ERROR(SBE_FUNC"Command validation failed");
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_PSU) )
+ {
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INVALID_COMMAND,l_rc);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ g_sbeCmdRespHdr.setStatus(SBE_PRI_INVALID_COMMAND, l_rc);
+ }
+
+ // Reassign l_rc to Success to Unblock command processor
+ // thread and let that take the necessary action.
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+
+ // Need to return from receiver thread itself for fenced rejection
+ // of command, but there might be contention on the response sent
+ // over FIFO/Mailbox usage.
+ if(false == sbeIsCmdAllowedAtState(l_cmdClass, l_command))
+ {
+ // This command is not allowed in this state
+ SBE_ERROR("Chip-Op CmdClass[0x%02X] Cmd[0x%02X] not allowed in "
+ "State - [0x%04X] ",l_cmdClass,l_command,
+ SbeRegAccess::theSbeRegAccess().getSbeState());
+
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE, SBE_INTERFACE_PSU) )
+ {
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INVALID_COMMAND,
+ SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ g_sbeCmdRespHdr.setStatus(SBE_PRI_INVALID_COMMAND,
+ SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE);
+ }
+
+ l_rc = SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE;
+ break;
+ }
+
+ } while (false); // Inner do..while ends
+
+ // If there was a FIFO reset request,
+ if (l_rc == SBE_FIFO_RESET_RECEIVED)
+ {
+ // Perform FIFO Reset
+ uint32_t l_rc = sbeUpFifoPerformReset();
+ if (l_rc)
+ {
+ // Perform FIFO Reset failed
+ SBE_ERROR(SBE_FUNC"Perform FIFO Reset failed, "
+ "l_rc=[0x%08X]", l_rc);
+ // Collect FFDC?
+ }
+
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE, SBE_INTERFACE_FIFO) )
+ {
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,
+ SBE_INTERFACE_FIFO);
+ }
+
+ if ( g_sbeIntrSource.isSet(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO_RESET) )
+ {
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,
+ SBE_INTERFACE_FIFO_RESET);
+ }
+
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
+ continue;
+ } // FIFO reset handling ends
+
+ // Unblock the command processor thread
+ // if we could dequeue the header successfully,
+ if ((l_rcPk == PK_OK) && (l_rc == SBE_SEC_OPERATION_SUCCESSFUL))
+ {
+ l_rcPk = pk_semaphore_post(&g_sbeSemCmdProcess);
+ }
+
+ // Handle Cmd not in a valid state here
+
+ if ((l_rcPk != PK_OK) || (l_rc != SBE_SEC_OPERATION_SUCCESSFUL))
+ {
+ if(l_rc != SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE)
+ {
+ // It's likely a code bug or PK failure,
+ // or any other PSU/FIFO access (scom) failure.
+
+ // @TODO via RTC : 129166
+ // Review if we need to add ASSERT here
+
+ // Add Error trace, collect FFDC and
+ // continue wait for the next interrupt
+ SBE_ERROR(SBE_FUNC"Unexpected failure, "
+ "l_rcPk=[%d], g_sbeSemCmdProcess.count=[%d], l_rc=[%d]",
+ l_rcPk, g_sbeSemCmdProcess.count, l_rc);
+ }
+ if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_PSU) )
+ {
+ if(l_rc == SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE)
+ {
+ sbeHandlePsuResponse(l_rc);
+ }
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,
+ SBE_INTERFACE_PSU);
+ pk_irq_enable(SBE_IRQ_HOST_PSU_INTR);
+ }
+ else if ( g_sbeIntrSource.isSet(SBE_RX_ROUTINE,
+ SBE_INTERFACE_FIFO) )
+ {
+ if(l_rc == SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE)
+ {
+ sbeHandleFifoResponse(l_rc);
+ }
+ g_sbeIntrSource.clearIntrSource(SBE_ALL_HANDLER,
+ SBE_INTERFACE_FIFO);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ }
+ continue;
+ }
+
+ SBE_DEBUG(SBE_FUNC"Posted g_sbeSemCmdProcess, "
+ "g_sbeSemCmdProcess.count=[%d]", g_sbeSemCmdProcess.count);
+
+ } while (true); // thread always exists
+ #undef SBE_FUNC
+}
diff --git a/src/sbefw/sbecmdregaccess.C b/src/sbefw/sbecmdregaccess.C
new file mode 100644
index 00000000..d4023f73
--- /dev/null
+++ b/src/sbefw/sbecmdregaccess.C
@@ -0,0 +1,274 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdregaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdregaccess.C
+ *
+ * @brief This file contains the SBE Reg Access chipOps
+ *
+ */
+
+#include "sbecmdregaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+#include "p9_ram_core.H"
+
+using namespace fapi2;
+
+Enum_RegType getRegType( const sbeRegAccessMsgHdr_t &regReq)
+{
+ Enum_RegType type = REG_GPR;
+ switch( regReq.regType )
+ {
+ case SBE_REG_ACCESS_SPR:
+ type = REG_SPR;
+ break;
+
+ case SBE_REG_ACCESS_FPR:
+ type = REG_FPR;
+ break;
+ }
+ return type;
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetReg(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetReg "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbeRegAccessMsgHdr_t regReqMsg;
+ uint32_t reqData[SBE_MAX_REG_ACCESS_REGS];
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t ffdc;
+ ReturnCode fapiRc;
+
+ do
+ {
+ // Get the reg access header
+ uint32_t len = sizeof(sbeRegAccessMsgHdr_t)/sizeof(uint32_t);
+ rc = sbeUpFifoDeq_mult (len, (uint32_t *)&regReqMsg, false);
+
+ // If FIFO access failure
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+ if( false == regReqMsg.isValidRequest() )
+ {
+ SBE_ERROR(SBE_FUNC" Invalid request. core: 0x%02x threadNr:0x%x"
+ " regType:0x%01x numRegs:0x%02x", regReqMsg.coreChiplet,
+ regReqMsg.threadNr, regReqMsg.regType, regReqMsg.numRegs);
+
+ respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ break;
+ }
+
+ len = regReqMsg.numRegs;
+ rc = sbeUpFifoDeq_mult (len, reqData, true);
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ uint8_t core = regReqMsg.coreChiplet;
+ RamCore ramCore( plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_CORE>(core),
+ regReqMsg.threadNr );
+
+ fapiRc = ramCore.ram_setup();
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" ram_setup failed. threadNr:0x%x"
+ "chipletId:0x%02x", regReqMsg.threadNr, core);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+
+ fapi2::buffer<uint64_t> data64;
+ uint64_t respData = 0;
+ for( uint32_t regIdx = 0; regIdx < regReqMsg.numRegs; regIdx++ )
+ {
+ fapiRc = ramCore.get_reg( getRegType(regReqMsg), reqData[regIdx],
+ &data64, true );
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" get_reg failed. threadNr:0x%x"
+ "chipletId:0x%02x, regNr:%u regType:%u ",
+ regReqMsg.threadNr, core, reqData[regIdx],
+ regReqMsg.regType);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+ respData = data64;
+ // Now enqueue into the downstream FIFO
+ len = sizeof( respData )/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult (len, ( uint32_t *)&respData);
+ if (rc)
+ {
+ break;
+ }
+ }
+ // HWP team does not care about cleanup for failure case.
+ // So call cleaup only for success case.
+ if( ffdc.getRc() )
+ {
+ break;
+ }
+ fapiRc = ramCore.ram_cleanup();
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" ram_cleanup failed. threadNr:0x%x"
+ "chipletId:0x%02x", regReqMsg.threadNr, core);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ }
+ }while(false);
+
+ if ( SBE_SEC_OPERATION_SUCCESSFUL == rc )
+ {
+ rc = sbeDsSendRespHdr( respHdr, ffdc);
+ }
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutReg(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbePutReg "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbeRegAccessMsgHdr_t regReqMsg;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t ffdc;
+ ReturnCode fapiRc;
+
+ do
+ {
+ // Get the reg access header
+ uint32_t len = sizeof(sbeRegAccessMsgHdr_t)/sizeof(uint32_t);
+ rc = sbeUpFifoDeq_mult (len, (uint32_t *)&regReqMsg, false);
+
+ // If FIFO access failure
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+ if( false == regReqMsg.isValidRequest() )
+ {
+ SBE_ERROR(SBE_FUNC" Invalid request. threadNr:0x%x"
+ " regType:0x%02x numRegs:0x%02x", regReqMsg.threadNr,
+ regReqMsg.regType, regReqMsg.numRegs);
+ respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ break;
+ }
+
+ sbeRegAccessPackage_t regPkg[SBE_MAX_REG_ACCESS_REGS];
+ len = (sizeof(sbeRegAccessPackage_t)/sizeof(uint32_t)) *
+ regReqMsg.numRegs;
+ rc = sbeUpFifoDeq_mult (len, (uint32_t *) regPkg,true );
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ break;
+ }
+ uint8_t core = regReqMsg.coreChiplet;
+ RamCore ramCore( plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_CORE>(core),
+ regReqMsg.threadNr );
+
+ fapiRc = ramCore.ram_setup();
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" ram_setup failed. threadNr:0x%x"
+ "chipletId:0x%02x", regReqMsg.threadNr, core);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+
+ fapi2::buffer<uint64_t> data64;
+ for( uint32_t regIdx = 0; regIdx < regReqMsg.numRegs; regIdx++ )
+ {
+ data64 = regPkg[regIdx].getData();
+ fapiRc = ramCore.put_reg( getRegType(regReqMsg),
+ regPkg[regIdx].regNr,
+ &data64, true );
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" get_reg failed. threadNr:0x%x"
+ "chipletId:0x%02x, regNr:%u regType:%u ",
+ regReqMsg.threadNr, core, regPkg[regIdx].regNr,
+ regReqMsg.regType);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+ }
+ // HWP team does not care about cleanup for failure case.
+ // So call cleaup only for success case.
+ if( ffdc.getRc() )
+ {
+ break;
+ }
+ fapiRc = ramCore.ram_cleanup();
+ if( fapiRc )
+ {
+ SBE_ERROR(SBE_FUNC" ram_cleanup failed. threadNr:0x%x"
+ " chipletId:0x%02x", regReqMsg.threadNr, core);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ }
+
+ }while(false);
+
+ if ( SBE_SEC_OPERATION_SUCCESSFUL == rc )
+ {
+ rc = sbeDsSendRespHdr( respHdr, ffdc);
+ }
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdregaccess.H b/src/sbefw/sbecmdregaccess.H
new file mode 100644
index 00000000..01199816
--- /dev/null
+++ b/src/sbefw/sbecmdregaccess.H
@@ -0,0 +1,56 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdregaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdregaccess.H
+ *
+ * @brief This file contains the Interfaces for the SCOM Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDREGACCESS_H
+#define __SBEFW_SBECMDREGACCESS_H
+
+#include <stdint.h>
+
+/**
+ * @brief sbeGetRegs : Get the reg data
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetReg(uint8_t *i_pArg);
+
+
+/**
+ * @brief sbePutRegs : Put the reg data
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutReg(uint8_t *i_pArg);
+
+
+#endif /* __SBEFW_SBECMDREGACCESS_H */
diff --git a/src/sbefw/sbecmdringaccess.C b/src/sbefw/sbecmdringaccess.C
new file mode 100644
index 00000000..3fdc8f7e
--- /dev/null
+++ b/src/sbefw/sbecmdringaccess.C
@@ -0,0 +1,305 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdringaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdringaccess.C
+ *
+ * @brief This file contains the SBE Ring Access chipOps
+ *
+ */
+
+#include "sbecmdringaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeHostMsg.H"
+#include "sbeHostUtils.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbeutil.H"
+#include "fapi2.H"
+#include "plat_hw_access.H"
+
+using namespace fapi2;
+
+static const uint32_t SIZE_OF_LENGTH_INWORDS = 1;
+static const uint32_t NUM_WORDS_PER_GRANULE = 2;
+static const uint32_t GETRING_GRANULE_SIZE_IN_BITS = 64;
+
+/*@brief - Map sbe ring access modes to fapi ring access modes
+ *
+ * @param[in] - i_ringMode - sbe ring access mode
+ *
+ * @return - l_fapiRingMode - fapi ring mode
+ */
+uint16_t sbeToFapiRingMode(uint16_t i_ringMode)
+{
+ uint16_t l_fapiRingMode = RING_MODE_HEADER_CHECK;
+
+ if(i_ringMode & SBE_RING_MODE_SET_PULSE_NO_OPCG_COND)
+ {
+ l_fapiRingMode |= RING_MODE_SET_PULSE_NO_OPCG_COND;
+ }
+ if(i_ringMode & SBE_RING_MODE_NO_HEADER_CHECK)
+ {
+ l_fapiRingMode |= RING_MODE_NO_HEADER_CHECK;
+ }
+ if(i_ringMode & SBE_RING_MODE_SET_PULSE_NSL)
+ {
+ l_fapiRingMode |= RING_MODE_SET_PULSE_NSL;
+ }
+ if(i_ringMode & SBE_RING_MODE_SET_PULSE_SL)
+ {
+ l_fapiRingMode |= RING_MODE_SET_PULSE_SL;
+ }
+ if(i_ringMode & SBE_RING_MODE_SET_PULSE_ALL)
+ {
+ l_fapiRingMode |= RING_MODE_SET_PULSE_ALL;
+ }
+ return l_fapiRingMode;
+}
+
+/*@brief - create fapi target handle for the target type
+ *
+ * @param[in] - i_taretType - sbe ring target type
+ * @param[in] - i_chipletId - chiplet id
+ * @param[out] - o_tgtHndl - fapi target handle
+ *
+ * @return - true - on success
+ * false - on failure
+ */
+bool sbeGetFapiTargetHandle(uint16_t i_targetType,
+ uint16_t i_chipletId,
+ fapi2::plat_target_handle_t &o_tgtHndl)
+{
+ bool l_rc = true;
+ o_tgtHndl = NULL;
+ switch(i_targetType)
+ {
+ case TARGET_EX:
+ o_tgtHndl = plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_EX>(i_chipletId);
+ break;
+ case TARGET_PERV:
+ o_tgtHndl = plat_getTargetHandleByChipletNumber
+ <fapi2::TARGET_TYPE_PERV>(i_chipletId);
+ break;
+ case TARGET_PROC_CHIP:
+ o_tgtHndl = plat_getChipTarget().get();
+ break;
+ default:
+ l_rc = false;
+ break;
+ }
+ return l_rc;
+}
+
+uint32_t sbePutRingFromImagePSU (uint8_t *i_pArg)
+{
+#define SBE_FUNC " sbePutRingFromImagePSU "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_fapiRc = FAPI2_RC_SUCCESS;
+ sbePSUPutRingCMD_t l_cmd = {0};
+ do
+ {
+ // Fetch Ring ID, Ring mode and pervasive chiplet id from the message
+ // and also send Ack to Host via SBE_SBE2PSU_DOORBELL_SET_BIT1
+ l_rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG1,
+ (sizeof(l_cmd)/sizeof(uint64_t)),
+ (uint64_t*)&l_cmd,
+ true);
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC "Failed to extract SBE_HOST_PSU_MBOX_REG1 and "
+ "SBE_HOST_PSU_MBOX_REG2");
+ break;
+ }
+
+ // Construct a Target from Chiplet ID and Target Type
+ fapi2::plat_target_handle_t l_tgtHndl = {0};
+ if(!sbeGetFapiTargetHandle(l_cmd.TargetType, l_cmd.ChipletID,
+ l_tgtHndl))
+ {
+ SBE_ERROR(SBE_FUNC "Invalid target type [0x%04x]",
+ (uint16_t)l_cmd.TargetType);
+ g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INVALID_DATA,
+ SBE_SEC_INVALID_TARGET_TYPE_PASSED);
+ break;
+ }
+ fapi2::Target<TARGET_TYPE_ALL> l_Tgt(l_tgtHndl);
+
+ // Initialize with HEADER CHECK mode
+ uint16_t l_ringMode = sbeToFapiRingMode(l_cmd.RingMode);
+
+ l_fapiRc = (uint32_t)putRing(l_Tgt, (RingID)l_cmd.RingID,
+ (RingMode)l_ringMode);
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "putRing HWP failure - "
+ "MSG - Target Type [0x%04x] Ring ID [0x%04x]"
+ " Ring Mode [0x%04x] Chiplet ID [0x%04x]",
+ l_cmd.TargetType,
+ l_cmd.RingID,
+ l_cmd.RingMode,
+ l_cmd.ChipletID);
+ break;
+ }
+ }while(0); // End of do-while
+
+ // Send the response
+ sbePSUSendResponse(g_sbeSbe2PsuRespHdr, l_fapiRc, l_rc);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+#undef SBE_FUNC
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetRing(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetRing "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbeGetRingAccessMsgHdr_t l_reqMsg;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+ ReturnCode l_fapiRc;
+ uint32_t l_len = 0;
+ uint32_t l_bitSentCnt = 0;
+
+ do
+ {
+ // Get the ring access header
+ l_len = sizeof(sbeGetRingAccessMsgHdr_t)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len, (uint32_t *)&l_reqMsg); // EOT fetch
+
+ // If FIFO access failure
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ SBE_INFO(SBE_FUNC "Ring Address 0x%08X User Ring Mode 0x%04X "
+ "Length in Bits 0x%08X",
+ l_reqMsg.ringAddr, l_reqMsg.ringMode, l_reqMsg.ringLenInBits);
+
+ uint16_t l_ringMode = sbeToFapiRingMode(l_reqMsg.ringMode);
+
+ // Call getRing_setup - loads the scan region data for the given ring
+ // address and updates the check word data
+ l_fapiRc = fapi2::getRing_setup(l_reqMsg.ringAddr,
+ (fapi2::RingMode)l_ringMode);
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" getRing_setup failed. RingAddress:0x%08X "
+ "RingMode:0x%04x", l_reqMsg.ringAddr, l_ringMode);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ // Calculate the iteration length
+ uint32_t l_loopCnt =
+ (l_reqMsg.ringLenInBits / GETRING_GRANULE_SIZE_IN_BITS);
+ // Check for modulus - remainder
+ uint8_t l_mod = (l_reqMsg.ringLenInBits % GETRING_GRANULE_SIZE_IN_BITS);
+ if(l_mod)
+ {
+ ++l_loopCnt;
+ }
+
+ // fix for the alignment issue
+ uint32_t l_buf[NUM_WORDS_PER_GRANULE]__attribute__ ((aligned (8))) ={0};
+ uint32_t l_bitShift = 0;
+ l_len = NUM_WORDS_PER_GRANULE;
+
+ // Fetch the ring data in bits, each iteration will give you 64bits
+ for(uint32_t l_cnt=0; l_cnt < l_loopCnt; l_cnt++)
+ {
+ if((l_cnt == (l_loopCnt-1)) && (l_mod))
+ {
+ l_bitShift = l_mod;
+ }
+ else
+ {
+ l_bitShift = GETRING_GRANULE_SIZE_IN_BITS;
+ }
+ // Call getRing_granule_data - read the 64 bit data from the HW
+ l_fapiRc = getRing_granule_data((uint32_t)(l_reqMsg.ringAddr),
+ (uint64_t*)&l_buf,
+ l_bitShift);
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" getRing_granule_data failed. "
+ "RingAddress:0x%08X RingMode:0x%04x",
+ l_reqMsg.ringAddr, l_ringMode);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ // Send it to DS Fifo
+ // If this is the last iteration in the loop, let the full 64bit
+ // go, even for 1bit of remaining length. The length passed to
+ // the user will take care of actual number of bits.
+ l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_buf);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ l_bitSentCnt = l_bitSentCnt + l_bitShift;
+ }
+ if ( (l_fapiRc == FAPI2_RC_SUCCESS) &&
+ (l_rc == SBE_SEC_OPERATION_SUCCESSFUL) )
+ {
+ // Call getRing_verifyAndcleanup - verify the check word data is
+ // matching or not and will clean up the scan region data
+ l_fapiRc = getRing_verifyAndcleanup((uint32_t)(l_reqMsg.ringAddr),
+ (fapi2::RingMode)l_ringMode);
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" getRing_verifyAndcleanup failed. "
+ "RingAddress:0x%08X RingMode:0x%04x",
+ l_reqMsg.ringAddr, l_ringMode);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ }
+ }
+ }while(false);
+
+ // Now build and enqueue response into downstream FIFO
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ if ( SBE_SEC_OPERATION_SUCCESSFUL == l_rc )
+ {
+ l_len = SIZE_OF_LENGTH_INWORDS;
+ l_rc = sbeDownFifoEnq_mult (l_len, &(l_bitSentCnt));
+ if(SBE_SEC_OPERATION_SUCCESSFUL == l_rc)
+ {
+ l_rc = sbeDsSendRespHdr( respHdr, l_ffdc);
+ }
+ }
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+#undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdringaccess.H b/src/sbefw/sbecmdringaccess.H
new file mode 100644
index 00000000..d2163646
--- /dev/null
+++ b/src/sbefw/sbecmdringaccess.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdringaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdringaccess.H
+ *
+ * @brief This file contains the Interfaces for the RING Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDRINGACCESS_H
+#define __SBEFW_SBECMDRINGACCESS_H
+
+#include <stdint.h>
+
+typedef struct
+{
+ uint64_t TargetType:16;
+ uint64_t ChipletID:16;
+ uint64_t RingID:16;
+ uint64_t RingMode:16;
+} sbePSUPutRingCMD_t;
+
+/**
+ * @brief Put Ring From Image Command (0xD301)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return RC from the PSU access utility
+ */
+uint32_t sbePutRingFromImagePSU(uint8_t *i_pArg);
+
+/**
+ * @brief sbeGetRing : Get the ring data
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetRing(uint8_t *i_pArg);
+
+
+#endif /* __SBEFW_SBECMDRINGACCESS_H */
diff --git a/src/sbefw/sbecmdscomaccess.C b/src/sbefw/sbecmdscomaccess.C
new file mode 100644
index 00000000..e99ce89f
--- /dev/null
+++ b/src/sbefw/sbecmdscomaccess.C
@@ -0,0 +1,495 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdscomaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdscomaccess.C
+ *
+ * @brief This file contains the SBE SCOM Access chipOps
+ *
+ */
+
+#include "sbecmdscomaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbescom.H"
+#include "sbeutil.H"
+#include "sbeFifoMsgUtils.H"
+
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetScom "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbeGetScomReqMsg_t l_getScomReqMsg;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue two entries for
+ // the scom addresses plus the expected
+ // EOT entry at the end
+
+ uint32_t l_len2dequeue = sizeof(l_getScomReqMsg)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_getScomReqMsg);
+
+ // If FIFO access failure
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ uint32_t l_sbeDownFifoRespBuf[6] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint32_t l_len2enqueue = 0;
+ uint32_t l_index = 0;
+
+ uint64_t l_addr = ( (uint64_t)l_getScomReqMsg.hiAddr << 32) |
+ l_getScomReqMsg.lowAddr;
+ uint64_t l_scomData = 0;
+ SBE_DEBUG(SBE_FUNC"scomAddr[0x%08X%08X]",
+ l_getScomReqMsg.hiAddr, l_getScomReqMsg.lowAddr);
+ l_rc = checkIndirectAndDoScom(true, l_addr,
+ l_scomData, l_pcbpibStatus);
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"getscom failed, l_pcbpibStatus[0x%08X], "
+ "scomAddr[0x%08X%08X]", l_pcbpibStatus,
+ l_getScomReqMsg.hiAddr, l_getScomReqMsg.lowAddr);
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ }
+ else // successful scom
+ {
+ SBE_DEBUG(SBE_FUNC"getscom succeeds, l_scomData[0x%016X]",
+ l_scomData);
+
+ l_sbeDownFifoRespBuf[0] = (uint32_t)(l_scomData>>32);
+ l_sbeDownFifoRespBuf[1] = (uint32_t)(l_scomData);
+
+ // Push the data into downstream FIFO
+ l_len2enqueue = 2;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue,
+ &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+ l_index = 2;
+ } // end successful scom
+
+ // Build the response header packet
+
+ uint32_t l_curIndex = l_index ;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus,
+ l_index);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex - l_index;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue,
+ &l_sbeDownFifoRespBuf[l_index]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbePutScom "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbePutScomReqMsg_t l_putScomReqMsg;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue four entries for
+ // the scom address (two entries) and the
+ // corresponding data (two entries) plus
+ // the expected EOT entry at the end
+
+ uint32_t l_len2dequeue = sizeof(l_putScomReqMsg)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_putScomReqMsg);
+
+ // If FIFO access failure
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ uint64_t l_scomData = 0;
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint32_t l_len2enqueue = 0;
+ // successfully dequeued two entries for
+ // scom address followed by the EOT entry
+
+ // Data entry 0 : Scom Register Address (0..31)
+ // Data entry 1 : Scom Register Address (32..63)
+ // Data entry 2 : Scom Register Data (0..31)
+ // Data entry 3 : Scom Register Data (32..63)
+ // For Direct SCOM, will ignore entry 0
+
+ l_scomData = l_putScomReqMsg.getScomData();
+
+ uint64_t l_addr = ( (uint64_t) l_putScomReqMsg.hiAddr << 32) |
+ l_putScomReqMsg.lowAddr;
+ SBE_DEBUG(SBE_FUNC"scomAddr[0x%08X%08X]",
+ l_putScomReqMsg.hiAddr, l_putScomReqMsg.lowAddr);
+ l_rc = checkIndirectAndDoScom(false, l_addr,
+ l_scomData, l_pcbpibStatus);
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"putscom failed, l_pcbpibStatus[0x%08X]",
+ l_pcbpibStatus);
+ SBE_ERROR(SBE_FUNC"putscom failure data, "
+ "scomAddr[0x%08X%08X], "
+ "scomData[0x%08X%08X]",
+ l_putScomReqMsg.hiAddr,
+ l_putScomReqMsg.lowAddr,
+ SBE::higher32BWord(l_scomData),
+ SBE::lower32BWord(l_scomData));
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ }
+
+ // Build the response header packet
+
+ uint32_t l_curIndex = 0;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue, &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeModifyScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeModifyScom "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ sbeModifyScomReqMsg_t l_modifyScomMsg;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue the following entries:
+ // Entry 1 : Operation Mode
+ // Entry 2 : Scom Register Address (0..31)
+ // Entry 3 : Scom Register Address (32..63)
+ // Entry 4 : Modifying Data (0..31)
+ // Entry 5 : Modifying Data (32..63)
+ // Entry 6 : EOT entry at the end
+
+ uint32_t l_len2dequeue = sizeof(l_modifyScomMsg)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_modifyScomMsg);
+
+ // If FIFO access failure
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint32_t l_len2enqueue = 0;
+
+ // Modifying Data
+ uint64_t l_modifyingData = l_modifyScomMsg.getModifyingData();
+
+ SBE_DEBUG(SBE_FUNC"OpMode[0x%02X], modifyingData[0x%016X]",
+ l_modifyScomMsg.opMode,
+ SBE::higher32BWord(l_modifyingData),
+ SBE::lower32BWord(l_modifyingData));
+
+ // The following steps need to be done as part of this command :
+ // 1. Read Register Data (getscom)
+ // 2. 'AND' the Mask with the data read from register
+ // 3. 'OR' the modifying data with the result of step 2
+ // 4. Write the result of step 3 into the register (putscom)
+ do
+ {
+ // Check for a valid OpMode
+ if ( (l_modifyScomMsg.opMode != SBE_MODIFY_MODE_OR) &&
+ (l_modifyScomMsg.opMode != SBE_MODIFY_MODE_AND) &&
+ (l_modifyScomMsg.opMode != SBE_MODIFY_MODE_XOR) )
+ {
+ // Invalid Data passed
+ SBE_ERROR(SBE_FUNC"Invalid OpMode");
+ l_primStatus = SBE_PRI_INVALID_DATA;
+ l_secStatus = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION;
+ break;
+ }
+
+ uint64_t l_addr = ( (uint64_t) l_modifyScomMsg.hiAddr << 32) |
+ l_modifyScomMsg.lowAddr;
+ uint64_t l_scomData = 0;
+ SBE_DEBUG(SBE_FUNC"scomAddr[0x%08X%08X]",
+ l_modifyScomMsg.hiAddr, l_modifyScomMsg.lowAddr);
+ l_rc = checkIndirectAndDoScom(true, l_addr,
+ l_scomData, l_pcbpibStatus);
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"getscom failed, l_pcbpibStatus[0x%08X],"
+ " ScomAddress[0x%08X %08X]", l_pcbpibStatus,
+ l_modifyScomMsg.hiAddr, l_modifyScomMsg.lowAddr);
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ break;
+ }
+
+ if (l_modifyScomMsg.opMode == SBE_MODIFY_MODE_OR)
+ {
+ l_modifyingData |= l_scomData;
+ }
+ else if (l_modifyScomMsg.opMode == SBE_MODIFY_MODE_AND)
+ {
+ l_modifyingData &= l_scomData;
+ }
+ else
+ {
+ l_modifyingData ^= l_scomData;
+ }
+
+ // Write the modified data
+ l_rc = checkIndirectAndDoScom(false, l_addr,
+ l_modifyingData, l_pcbpibStatus);
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"putscom failed, l_pcbpibStatus[0x%08X],"
+ " ScomAddress[0x%08X%08X]", l_pcbpibStatus,
+ l_modifyScomMsg.hiAddr, l_modifyScomMsg.lowAddr);
+ SBE_ERROR(SBE_FUNC"modifyingData[0x%08X%08X]",
+ SBE::higher32BWord(l_modifyingData),
+ SBE::lower32BWord(l_modifyingData));
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ break;
+ }
+ } while (false);
+
+ // Build the response header packet
+
+ uint32_t l_curIndex = 0;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue,
+ (uint32_t *)&l_sbeDownFifoRespBuf);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutScomUnderMask (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbePutScomUnderMask "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbePutScomUnderMaskReqMsg_t l_putScomUmaskMsg;
+
+ do
+ {
+ uint16_t l_primStatus = g_sbeCmdRespHdr.prim_status;
+ uint16_t l_secStatus = g_sbeCmdRespHdr.sec_status ;
+
+ // Will attempt to dequeue the following entries:
+ // Entry 1 : Scom Register Address (0..31)
+ // Entry 2 : Scom Register Address (32..63)
+ // Entry 3 : Modifying Data (0..31)
+ // Entry 4 : Modifying Data (32..63)
+ // Entry 5 : Mask Data (0..31)
+ // Entry 6 : Mask Data (32..63)
+ // Entry 7 : EOT entry at the end
+
+ uint32_t l_len2dequeue = sizeof(l_putScomUmaskMsg)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue,
+ (uint32_t *)&l_putScomUmaskMsg);
+
+ // If FIFO access failure
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ uint32_t l_sbeDownFifoRespBuf[4] = {0};
+ uint32_t l_pcbpibStatus = SBE_PCB_PIB_ERROR_NONE;
+ uint32_t l_len2enqueue = 0;
+
+ SBE_DEBUG(SBE_FUNC"scomAddr[0x%08X%08X],"
+ "modifyingData[0x%08X%08X]",
+ l_putScomUmaskMsg.hiAddr,
+ l_putScomUmaskMsg.lowAddr,
+ l_putScomUmaskMsg.hiInputData,
+ l_putScomUmaskMsg.lowInputData);
+ SBE_INFO(SBE_FUNC"maskData[0x%08X%08X]",
+ l_putScomUmaskMsg.hiMaskData,
+ l_putScomUmaskMsg.lowMaskData);
+
+ // PutScomUnderMask formula:
+ // dest_reg = (dest_reg & ~input_mask) | (input_data & input_mask)
+
+ do
+ {
+ uint64_t l_scomData = 0;
+
+ uint64_t l_addr = ( (uint64_t) l_putScomUmaskMsg.hiAddr << 32) |
+ l_putScomUmaskMsg.lowAddr;
+ l_rc = checkIndirectAndDoScom(true, l_addr,
+ l_scomData, l_pcbpibStatus);
+
+ if (l_rc == SBE_SEC_OPERATION_SUCCESSFUL) // scom success
+ {
+ l_putScomUmaskMsg.getScomData(l_scomData);
+
+ // Write the modified data
+ l_rc = checkIndirectAndDoScom(false, l_addr,
+ l_scomData, l_pcbpibStatus);
+ }
+
+ if (l_rc != SBE_SEC_OPERATION_SUCCESSFUL) // scom failed
+ {
+ SBE_ERROR(SBE_FUNC"scom failed, l_pcbpibStatus[0x%08X], "
+ "ScomAddress[0x%08X%08X]", l_pcbpibStatus,
+ l_putScomUmaskMsg.hiAddr,
+ l_putScomUmaskMsg.lowAddr);
+ SBE_ERROR(SBE_FUNC"modifyingData[0x%08X%08X]"
+ "maskData[0x%08X%08X]",
+ l_putScomUmaskMsg.hiInputData,
+ l_putScomUmaskMsg.lowInputData,
+ l_putScomUmaskMsg.hiMaskData,
+ l_putScomUmaskMsg.lowMaskData);
+
+ l_primStatus = SBE_PRI_GENERIC_EXECUTION_FAILURE;
+ l_secStatus = l_rc;
+ break;
+ }
+ } while (false);
+
+ // Build the response header packet
+ uint32_t l_curIndex = 0;
+ sbeBuildMinRespHdr(&l_sbeDownFifoRespBuf[0],
+ l_curIndex,
+ l_primStatus,
+ l_secStatus,
+ l_pcbpibStatus);
+
+ // Now enqueue into the downstream FIFO
+ l_len2enqueue = ++l_curIndex;
+ l_rc = sbeDownFifoEnq_mult (l_len2enqueue, &l_sbeDownFifoRespBuf[0]);
+ if (l_rc)
+ {
+ // will let command processor routine
+ // handle the failure
+ break;
+ }
+ } while(false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeMultiScom (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeMultiScom "
+ return 0;
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdscomaccess.H b/src/sbefw/sbecmdscomaccess.H
new file mode 100644
index 00000000..8a4a4a28
--- /dev/null
+++ b/src/sbefw/sbecmdscomaccess.H
@@ -0,0 +1,93 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdscomaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdscomaccess.H
+ *
+ * @brief This file contains the Interfaces for the SCOM Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDSCOMACCESS_H
+#define __SBEFW_SBECMDSCOMACCESS_H
+
+#include <stdint.h>
+
+/**
+ * @brief sbeDownFifoGetStatus : Write data into Downstream FIFO
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetScom (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbeDownFifoGetStatus : Write data into Downstream FIFO
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutScom (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbeModifyScom : Modify the Scom data
+ * This chipOp needs to do the following
+ * 1. Read Register Data (getscom)
+ * 2. modify the scomData using the given op mode
+ * 3. Write the modified Data into the Register (putscom)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeModifyScom (uint8_t *i_pArg);
+
+
+/**
+ * @brief sbePutScomUnderMask : Write data into Downstream FIFO
+ * The following steps need to be done as part of this command :
+ * 1. Read Register Data (getscom)
+ * 2. 'AND' the Mask with the data read from register
+ * 3. 'OR' the modifying data with the result of step 2
+ * 4. Write the result of step 3 into the register (putscom)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutScomUnderMask (uint8_t *i_pArg);
+
+/**
+ * @brief sbeMultiScom:
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeMultiScom (uint8_t *i_pArg);
+
+#endif /* __SBEFW_SBECMDSCOMACCESS_H */
diff --git a/src/sbefw/sbecmdsram.C b/src/sbefw/sbecmdsram.C
new file mode 100644
index 00000000..ac11ffc6
--- /dev/null
+++ b/src/sbefw/sbecmdsram.C
@@ -0,0 +1,337 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdsram.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdsram.C
+ *
+ * @brief This file contains the SBE Sram Access chipOps
+ *
+ */
+
+#include "sbecmdsram.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+#include "sberegaccess.H"
+
+#include "fapi2.H"
+#include "p9_pm_ocb_init.H"
+#include "p9_pm_ocb_indir_setup_linear.H"
+#include "p9_pm_ocb_indir_access.H"
+#include "p9_perv_scom_addresses.H"
+
+using namespace fapi2;
+
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeOccSramAccess_Wrap Occ Sran Access Wrapper function
+//
+// @param [in] i_isGetFlag Flag to indicate the sram Access Type
+// true : GetOccSram ChipOp
+// false : PutOccSram ChipOp
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeOccSramAccess_Wrap(const bool i_isGetFlag)
+{
+ #define SBE_FUNC " sbeOccSramAccess_Wrap "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+
+ sbeRespGenHdrWithLen_t l_respHdr;
+ l_respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+
+ // Total Returned length from the procedure
+ uint32_t l_totalReturnLen = 0;
+
+ // Create the req struct for the OCC Sram Chip-op
+ sbeOccSramAccessReqMsgHdr_t l_req = {0};
+
+ // Check if True - Get / False - Put
+ p9ocb::PM_OCB_ACCESS_OP l_ocb_access =
+ (i_isGetFlag)? p9ocb::OCB_GET : p9ocb::OCB_PUT;
+
+ do
+ {
+ // Get the Req Struct Size Data from upstream Fifo
+ uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len2dequeue,
+ (uint32_t *)&l_req,
+ i_isGetFlag);
+
+ // If FIFO failure
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+
+ SBE_INFO("mode [0x%08X] addr[0x%08X] len[0x%08X]",
+ l_req.mode, l_req.addr, l_req.len);
+
+ // Get the Proc Chip Target to be passed in to the procedure call
+ Target<fapi2::TARGET_TYPE_PROC_CHIP> l_proc = plat_getChipTarget();
+
+ // Do linear setup for indirect access HWP for Chan0, Chan2 and Chan3
+ // For Circular Mode, Chan1 is assumed to be setup by default
+ // Linear mode is setup with Linear streaming mode only
+
+ // Sram Access condition to pass valid address during the first access
+ bool l_validAddrForFirstAccess = true;
+
+ // Channel Selection based on Mode as well as Fsp attchament
+ p9ocb::PM_OCB_CHAN_NUM l_chan = p9ocb::OCB_CHAN0;
+ switch(l_req.mode)
+ {
+ case NORMAL_MODE:
+ if(false == SbeRegAccess::theSbeRegAccess().isFspSystem())
+ {
+ l_chan = p9ocb::OCB_CHAN2;
+ }
+ break;
+
+ case DEBUG_MODE:
+ l_chan = p9ocb::OCB_CHAN3;
+ break;
+
+ case CIRCULAR_MODE:
+ l_chan = p9ocb::OCB_CHAN1;
+ l_validAddrForFirstAccess = false;
+ break;
+
+ default:
+ SBE_ERROR(SBE_FUNC "Invalid Mode Passed by User");
+ l_rc = SBE_SEC_GENERIC_FAILURE_IN_EXECUTION;
+ l_respHdr.respHdr.setStatus( SBE_PRI_INVALID_DATA, l_rc);
+ break;
+ }
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ break;
+ }
+
+ // Setup Needs to be called in Normal and Debug Mode only
+ if( (l_req.mode == NORMAL_MODE) || (l_req.mode == DEBUG_MODE) )
+ {
+ l_fapiRc = p9_pm_ocb_indir_setup_linear(l_proc, l_chan,
+ p9ocb::OCB_TYPE_LINSTR,
+ l_req.addr);
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "p9_pm_ocb_indir_setup_linear failed, "
+ "Channel[0x%02X] Addr[0x%08X]",
+ l_chan, l_req.addr);
+
+ // Respond with HWP FFDC
+ l_respHdr.respHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ }
+
+ //Create a 128 Byte Buffer - 16 64-Bit buffer
+ // This is our Granule size as well for this HWP
+ uint32_t l_getBuf[SBE_OCC_SRAM_GRANULE/SBE_32BIT_ALIGN_FACTOR] = {};
+ uint32_t l_remainingLen = l_req.len; // Initialize with Total Len
+ uint32_t l_lenPassedToHwp = 0;
+ uint32_t l_actLen = 0; // Return Len from Hwp not used
+
+ while(l_remainingLen)
+ {
+ if(l_remainingLen <= SBE_OCC_SRAM_GRANULE)
+ {
+ l_lenPassedToHwp = l_remainingLen;
+ }
+ else
+ {
+ l_lenPassedToHwp = SBE_OCC_SRAM_GRANULE;
+ }
+ l_remainingLen = l_remainingLen - l_lenPassedToHwp;
+
+ // Fetch buffer from Upstream Fifo for the HWP if it is PutOCC Sram
+ if(!i_isGetFlag)
+ {
+ l_len2dequeue = (l_lenPassedToHwp/SBE_32BIT_ALIGN_FACTOR);
+ l_rc = sbeUpFifoDeq_mult ( l_len2dequeue,
+ l_getBuf,
+ false);
+ // If there was an underlying FIFO operation failure
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+ }
+
+ // Don't need to put any check for Linear/Circular - It's the same
+ // API for access, For circular valid address flag is false, Hwp
+ // doesn't need the address field from us.
+ l_fapiRc = p9_pm_ocb_indir_access(
+ l_proc,
+ l_chan,
+ l_ocb_access, // Get/Put
+ (l_lenPassedToHwp/SBE_64BIT_ALIGN_FACTOR), // 64-bit aligned
+ l_validAddrForFirstAccess, // If requested addr is valid
+ l_req.addr, // Requested Addr being passed
+ l_actLen, // O/p from hwp not used
+ (uint64_t *)l_getBuf); // O/p buffer
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "p9_pm_ocb_indir_access failed, "
+ "Channel[0x%02X] Addr[0x%08X] 64Bit Aligned Len[0x%08X]",
+ l_chan, l_req.addr, (l_lenPassedToHwp/SBE_64BIT_ALIGN_FACTOR));
+
+ // Respond with HWP FFDC
+ l_respHdr.respHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ l_totalReturnLen = l_totalReturnLen + l_lenPassedToHwp;
+ // Change this to false, so that Indirect Access Hwp doesn't
+ // reset the Address to starting point.
+ l_validAddrForFirstAccess = false;
+
+ if(i_isGetFlag) // Get Occ Sram
+ {
+ l_len2dequeue = (l_lenPassedToHwp/SBE_32BIT_ALIGN_FACTOR);
+ // Push this into the downstream FIFO
+ l_rc = sbeDownFifoEnq_mult (l_len2dequeue, l_getBuf);
+
+ // If FIFO failure
+ if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ // Let command processor routine to handle the RC.
+ break;
+ }
+ }
+ } // End of while Put/Get from Hwp
+
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+
+ do
+ {
+ l_len2dequeue = 0;
+ if (!i_isGetFlag)
+ {
+ // If there was a HWP failure for put sram occ request,
+ // need to Flush out upstream FIFO, until EOT arrives
+ if ( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL,
+ true, true);
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+ }
+ // For other success paths, just attempt to offload
+ // the next entry, which is supposed to be the EOT entry
+ else
+ {
+ l_rc = sbeUpFifoDeq_mult(l_len2dequeue, NULL, true);
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+ }
+ }
+
+ // Distance to Header is minus the length field in the response
+ // buffer. So when we do sizeof(l_respHdr) It will add an extra byte
+ // for the length. So it compensates for the length, if we start the
+ // distance from hdr as zero.
+ uint32_t l_dist2Hdr = 0;
+
+ // Now enqueue the minimum response header
+ // first enqueue the length of data actually written
+ l_respHdr.setLength(l_totalReturnLen);
+ uint32_t l_len = sizeof(l_respHdr) / sizeof(uint32_t);
+ l_rc = sbeDownFifoEnq_mult(l_len, (uint32_t *)(&l_respHdr));
+
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+
+ l_dist2Hdr += l_len;
+
+ // Enqueue FFDC data if there is one
+ if( l_ffdc.getRc() )
+ {
+ l_len = sizeof(l_ffdc) / sizeof(uint32_t);
+ l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)(&l_ffdc));
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+
+ l_dist2Hdr += l_len;
+ }
+
+ l_len = sizeof(l_dist2Hdr) / sizeof(uint32_t);
+ l_rc = sbeDownFifoEnq_mult ( l_len, &l_dist2Hdr);
+
+ if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc )
+ {
+ break;
+ }
+ }while(0);
+ }while(0);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbePutOccSram (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbePutOccSram "
+ return sbeOccSramAccess_Wrap (false);
+ #undef SBE_FUNC
+}
+
+/////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetOccSram (uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetOccSram "
+ return sbeOccSramAccess_Wrap (true);
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sbecmdsram.H b/src/sbefw/sbecmdsram.H
new file mode 100644
index 00000000..1c86aa2b
--- /dev/null
+++ b/src/sbefw/sbecmdsram.H
@@ -0,0 +1,64 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdsram.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbecmdsram.H
+ *
+ * @brief This file contains the Interfaces for the Sram Access chip-ops
+ *
+ */
+
+#ifndef __SBEFW_SBECMDSRAM_H
+#define __SBEFW_SBECMDSRAM_H
+
+#include <stdint.h>
+
+static const uint8_t SBE_32BIT_ALIGN_FACTOR = 4;
+static const uint8_t SBE_64BIT_ALIGN_FACTOR = 8;
+
+static const uint64_t SBE_FWCTRLFLG3_FSP_ATTACHED = 0X1000000000000000;
+
+/*
+ * @brief Granule size in Bytes for 'Get from Hwp'/'Put to Hwp'
+ */
+static const uint32_t SBE_OCC_SRAM_GRANULE = 128;
+
+/**
+ * @brief sbeGetOccSram : Implements SBE Get Occ Sram ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeGetOccSram (uint8_t *i_pArg);
+
+/**
+ * @brief sbePutOccSram : Implements SBE Put Occ Sram ChipOp
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbePutOccSram (uint8_t *i_pArg);
+
+#endif /* __SBEFW_SBECMDSRAM_H */
diff --git a/src/sbefw/sbeerrorcodes.H b/src/sbefw/sbeerrorcodes.H
new file mode 100644
index 00000000..2e37bb2b
--- /dev/null
+++ b/src/sbefw/sbeerrorcodes.H
@@ -0,0 +1,49 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeerrorcodes.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeerrorcodes.H
+ *
+ * @brief This file contains the SBE internal error status codes
+ *
+ */
+
+#ifndef __SBEFW_SBEERRORCODES_H
+#define __SBEFW_SBEERRORCODES_H
+
+#include <stdint.h>
+
+
+/**
+ * @brief enums SBE internal error codes
+ *
+*/
+enum sbeInternalResponseCodes
+{
+ SBE_FIFO_RESET_RECEIVED = 0xFA00,
+ SBE_FIFO_RESET_HANDLING_FAILED = 0xFB00,
+ SBE_FUNC_NOT_SUPPORTED = 0xFC00,
+};
+
+
+#endif // __SBEFW_SBEERRORCODES_H \ No newline at end of file
diff --git a/src/sbefw/sbeevents.H b/src/sbefw/sbeevents.H
new file mode 100644
index 00000000..6506a050
--- /dev/null
+++ b/src/sbefw/sbeevents.H
@@ -0,0 +1,96 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeevents.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeevents.H
+ *
+ * @brief This file contains interfaces pertaining to the events for state
+ * transition trigger.
+ *
+ */
+
+#ifndef __SBEFW_SBEEVENTS_H
+#define __SBEFW_SBEEVENTS_H
+
+/**
+ * @brief An enumeration of all SBE state transition events
+ *
+ */
+enum sbeEvent
+{
+ SBE_CONTINUE_BOOT_PLCK_EVENT = 0x0, // From FFDC State
+ SBE_CONTINUE_BOOT_RUNTIME_EVENT = 0x1, // From FFDC State
+ SBE_RUNTIME_EVENT = 0x2, // From FFDC/Unknown/ISTEP/IPLING State
+ SBE_ISTEP_EVENT = 0x3, // From FFDC/Unknown State
+ SBE_PLCK_EVENT = 0x4, // From FFDC/Unknown state
+ SBE_DUMP_FAILURE_EVENT = 0x5, // From IPLING/RUNTIME/MPIPL/DMT/Unknown State
+ SBE_ENTER_MPIPL_EVENT = 0x6, // From Runtime State
+ SBE_CONTINUE_MPIPL_EVENT = 0x7, // From MPIPL Wait State
+ SBE_ABORT_EVENT = 0x8, // From Any state
+ SBE_DMT_ENTER_EVENT = 0x9, // From Runtime State
+ SBE_DMT_COMP_EVENT = 0xA, // From DMT State
+ SBE_FAILURE_EVENT = 0xB, // From Any State
+ SBE_FFDC_COLLECT_EVENT = 0xC, // From Unknown State
+};
+
+// Maximum number of Events per State
+enum maxEventPerState
+{
+ SBE_STATE_UNKNOWN_MAX_EVENT = 5,
+ SBE_STATE_FFDC_COLLECT_MAX_EVENT = 4,
+ SBE_STATE_IPLING_MAX_EVENT = 4,
+ SBE_STATE_ISTEP_MAX_EVENT = 3,
+ SBE_STATE_RUNTIME_MAX_EVENT = 4,
+ SBE_STATE_MPIPL_MAX_EVENT = 2,
+ SBE_STATE_DMT_MAX_EVENT = 1,
+ SBE_STATE_DUMP_MAX_EVENT = 0,
+ SBE_STATE_FAILURE_MAX_EVENT = 0,
+ SBE_STATE_QUIESCE_MAX_EVENT = 0,
+ SBE_STATE_ABORT_MAX_EVENT = 0,
+
+ // Total number of State Transition Events, Addition of all the above
+ SBE_MAX_TRANSITIONS = 23,
+};
+
+
+// Entry Point to stateTransitionStr_t Map Structure, This adds up all the state
+// transition of the previous state, If any more transition is added, this will
+// add up to all subsequent entries. This is closely mapped with the sbestates.H
+// as well.
+enum entryToStateMap
+{
+ SBE_STATE_UNKNOWN_ENTRY_TO_MAP = 0,
+ SBE_STATE_FFDC_COLLECT_ENTRY_TO_MAP = SBE_STATE_UNKNOWN_ENTRY_TO_MAP + SBE_STATE_UNKNOWN_MAX_EVENT, // 5
+ SBE_STATE_IPLING_ENTRY_TO_MAP = SBE_STATE_FFDC_COLLECT_ENTRY_TO_MAP + SBE_STATE_FFDC_COLLECT_MAX_EVENT, //9
+ SBE_STATE_ISTEP_ENTRY_TO_MAP = SBE_STATE_IPLING_ENTRY_TO_MAP + SBE_STATE_IPLING_MAX_EVENT, //13
+ SBE_STATE_RUNTIME_ENTRY_TO_MAP = SBE_STATE_ISTEP_ENTRY_TO_MAP + SBE_STATE_ISTEP_MAX_EVENT, //16
+ SBE_STATE_MPIPL_ENTRY_TO_MAP = SBE_STATE_RUNTIME_ENTRY_TO_MAP + SBE_STATE_RUNTIME_MAX_EVENT, //20
+ SBE_STATE_DMT_ENTRY_TO_MAP = SBE_STATE_MPIPL_ENTRY_TO_MAP + SBE_STATE_MPIPL_MAX_EVENT, //22
+ SBE_STATE_DUMP_ENTRY_TO_MAP = SBE_STATE_DMT_ENTRY_TO_MAP + SBE_STATE_DMT_MAX_EVENT, //23
+ SBE_STATE_FAILURE_ENTRY_TO_MAP = SBE_STATE_DUMP_ENTRY_TO_MAP + SBE_STATE_DUMP_MAX_EVENT, //23
+ SBE_STATE_QUIESCE_ENTRY_TO_MAP = SBE_STATE_FAILURE_ENTRY_TO_MAP + SBE_STATE_FAILURE_MAX_EVENT, //23
+ SBE_STATE_ABORT_ENTRY_TO_MAP = SBE_STATE_QUIESCE_ENTRY_TO_MAP + SBE_STATE_QUIESCE_MAX_EVENT, //23
+};
+
+#endif //__SBEFW_SBEEVENTS_H
+
diff --git a/src/sbefw/sbeexeintf.H b/src/sbefw/sbeexeintf.H
new file mode 100644
index 00000000..8a8aff66
--- /dev/null
+++ b/src/sbefw/sbeexeintf.H
@@ -0,0 +1,256 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeexeintf.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeexeintf.H
+ *
+ * @brief This file contains the SBE control loop firmware details like
+ * - Thread priority enums
+ * - Thread stack size and space enums
+ * - Thread sub-rountine declarations
+ * - IRQ setup and ISR declarations
+ * - Other Common declaration among all the threads
+ */
+
+#ifndef __SBEFW_SBE_H
+#define __SBEFW_SBE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pk.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @brief enums for priorities for thread creation
+ *
+ */
+typedef enum
+{
+ THREAD_PRIORITY_MAX_0,
+ THREAD_PRIORITY_1,
+ THREAD_PRIORITY_2,
+ THREAD_PRIORITY_3,
+ THREAD_PRIORITY_4,
+ THREAD_PRIORITY_5,
+ THREAD_PRIORITY_6,
+ THREAD_PRIORITY_7,
+ THREAD_PRIORITY_8,
+ THREAD_PRIORITY_MIN_30 = 30,
+} sbeThreadPriorities ;
+
+/**
+ * @brief enums for thread stack sizes
+ * - Non-Critical Stack used by non-critical interrupt handlers
+ * - Critical Stack used for critical interrupts
+ * - Stacks for each thread
+ *
+ * @TODO via RTC : 128657
+ * - Measure the actual thread stack utilization
+ * - This will be a continuous activity
+ */
+enum sbeThreadStackSize
+{
+ SBE_NONCRITICAL_STACK_SIZE = 256,
+ SBE_THREAD_ASYNC_CMD_PROC_STACK_SIZE = 256,
+ SBE_THREAD_CMD_RECV_STACK_SIZE = 512,
+ SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE = 2048,
+};
+
+/**
+ * @brief Global semaphore : g_sbeSemCmdRecv
+ *
+ * This is used to synchronize between the ISR and
+ * the command receiver thread.
+ *
+ */
+extern PkSemaphore g_sbeSemCmdRecv;
+
+/**
+ * @brief Global semaphore : g_sbeSemCmdProcess
+ *
+ * This is used to synchronize between command receiver thread
+ * and synchronous command processor thread.
+ *
+ */
+extern PkSemaphore g_sbeSemCmdProcess;
+
+
+/**
+ * @brief SBE Interface source
+ *
+ */
+typedef enum
+{
+ SBE_INTERFACE_UNKNOWN = 0x00,
+ SBE_INTERFACE_FIFO = 0x01,
+ SBE_INTERFACE_PSU = 0x02,
+ SBE_INTERFACE_FIFO_RESET = 0x04,
+} sbeInterfaceSrc_t;
+
+/*
+ * @brief Enum for Handler, handling the interrupt and setting/clearing the
+ * interrupt variable
+ */
+typedef enum
+{
+ SBE_ALL_HANDLER = 0x0,
+ SBE_INTERRUPT_ROUTINE = 0x1,
+ SBE_RX_ROUTINE = 0x2,
+ SBE_PROC_ROUTINE = 0x3,
+} sbeHandler_t;
+
+/**
+ * @brief structure for SBE external Interrupt handling
+ *
+ */
+typedef struct
+{
+ uint8_t intrSource;
+ uint8_t rxThrIntrSource;
+ uint8_t procThrIntrSource;
+
+ void setIntrSource(const sbeHandler_t i_handler,
+ const sbeInterfaceSrc_t i_val)
+ {
+ switch(i_handler)
+ {
+ case SBE_INTERRUPT_ROUTINE: intrSource |= i_val; break;
+ case SBE_RX_ROUTINE: rxThrIntrSource |= i_val; break;
+ case SBE_PROC_ROUTINE: procThrIntrSource |= i_val; break;
+ case SBE_ALL_HANDLER: break;
+ }
+ }
+
+ void clearIntrSource(const sbeHandler_t i_handler,
+ const sbeInterfaceSrc_t i_val)
+ {
+ switch(i_handler)
+ {
+ case SBE_INTERRUPT_ROUTINE: intrSource &= ~i_val; break;
+ case SBE_RX_ROUTINE: rxThrIntrSource &= ~i_val; break;
+ case SBE_PROC_ROUTINE: procThrIntrSource &= ~i_val; break;
+ case SBE_ALL_HANDLER:
+ {
+ intrSource &= ~i_val;
+ rxThrIntrSource &= ~i_val;
+ procThrIntrSource &= ~i_val;
+ break;
+ }
+ }
+ }
+
+ bool isSet (const sbeHandler_t i_handler, const sbeInterfaceSrc_t i_val)
+ {
+ bool l_ret = false;
+ switch(i_handler)
+ {
+ case SBE_INTERRUPT_ROUTINE: l_ret = (intrSource & i_val); break;
+ case SBE_RX_ROUTINE: l_ret = (rxThrIntrSource & i_val); break;
+ case SBE_PROC_ROUTINE: l_ret = (procThrIntrSource & i_val); break;
+ case SBE_ALL_HANDLER: break;
+ }
+ return l_ret;
+ }
+} sbeIntrHandle_t;
+extern sbeIntrHandle_t g_sbeIntrSource ;
+
+
+/**
+ * @TODO via RTC : 128658
+ * Mutex protect the critical data
+ * e.g., add Mutex g_sbeMutCmdReqBuf etc.
+ */
+
+/**
+ * @brief sbeCommandReceiver_routine
+ * The major responsibilities of this thread are :
+ * - Determine the reason for the interrupt
+ * - FIFO New data
+ * - FIFO reset
+ * - Host services
+ * - Dequeue the mandatory 2 entry header from upstream FIFO
+ * - Command input data validation
+ * - SBE State and pre-requirements validation
+ * - FFDC collection and FIFO flush upon validation failure
+ * - Unblock SBE command processor thread
+ * - Perform FIFO reset upon request from SP
+ *
+ * @param[in] i_pArg - Any buffer needed to be passed to the thread routine
+ */
+void sbeCommandReceiver_routine(void *i_pArg);
+
+/**
+ * @brief sbeSyncCommandProcessor_routine
+ * The major responsibilities of this thread are :
+ * - Dequeue data payload from upstream FIFO
+ * - Un-marshalling of the command request data
+ * - Blacklist validation
+ * - FFDC collection upon validation failure
+ * - Invoke the corresponding Hardware access utility
+ * or the HWP corresponding to the chipOp request
+ * - FFDC collection and FIFO flush upon hardware access / HWP failure
+ * - Build the response buffer with the data and the header
+ * - Enqueue the response into the Downstream FIFO
+ * - Un-mask the new data available interrupt
+ *
+ * @param[in] i_pArg - Any buffer needed to be passed to the thread routine
+ */
+void sbeSyncCommandProcessor_routine(void *i_pArg);
+
+/**
+ * @brief sbeAsyncCommandProcessor_routine
+ * @TODO RTC via : 130392
+ * Add infrastructure for host interface
+ *
+ * @param[in] i_pArg - Any buffer needed to be passed to the thread routine
+ */
+void sbeAsyncCommandProcessor_routine(void *i_pArg);
+
+
+/* @brief ISR for all SBE External Interrupts
+ * - FIFO : New data available
+ * - FIFO : Reset Request
+ * - PSU : New data available
+ *
+ * @param[in/out] i_pArg - Any buffer needed to be passed to the handler
+ * @param[in] i_irq - IRQ number as defined in the SBE PPE spec
+ */
+void sbe_interrupt_handler(void* i_pArg, PkIrqId i_irq);
+
+
+/* brief : Register SBE interrupt handlers and enable the IRQs
+ *
+ * @return int PK_OK - Success (IRQ Setup was successful)
+ * PK_INVALID_ARGUMENT_IRQ_HANDLER - Invalid argument passed
+ * (Code bug)
+ *
+ */
+int sbeIRQSetup (void);
+
+
+#endif /* __SBEFW_SBE_H */
diff --git a/src/sbefw/sbefifo.H b/src/sbefw/sbefifo.H
new file mode 100644
index 00000000..47ce5beb
--- /dev/null
+++ b/src/sbefw/sbefifo.H
@@ -0,0 +1,227 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbefifo.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbefifo.H
+ *
+ * @brief This file contains basic SBE FIFO hardware specific
+ * definitions and operations.
+ *
+ */
+
+#ifndef __SBEFW_SBEFIFO_H
+#define __SBEFW_SBEFIFO_H
+
+#include "sbeexeintf.H"
+#include "sbetrace.H"
+#include "ppe42_scom.h"
+#include "sbe_sp_intf.H"
+#include "sbeSpMsg.H"
+
+/**
+ * @brief SBE FIFO Access addresses
+ *
+ */
+const uint32_t SBE_FIFO_BASE = 0x000B0000;
+
+const uint32_t SBE_UPSTREAM_FIFO_DEQ_ADD = SBE_FIFO_BASE + 0x0000;
+const uint32_t SBE_UPSTREAM_FIFO_STATUS = SBE_FIFO_BASE + 0x0001;
+const uint32_t SBE_UPSTREAM_FIFO_SIGNAL_EOT = SBE_FIFO_BASE + 0x0002;
+const uint32_t SBE_UPSTREAM_FIFO_REQ_RESET = SBE_FIFO_BASE + 0x0003;
+const uint32_t SBE_UPSTREAM_FIFO_PERFORM_RESET = SBE_FIFO_BASE + 0x0004;
+const uint32_t SBE_UPSTREAM_FIFO_ACK_EOT = SBE_FIFO_BASE + 0x0005;
+
+const uint32_t SBE_DOWNSTREAM_FIFO_ENQ_ADD = SBE_FIFO_BASE + 0x0010;
+const uint32_t SBE_DOWNSTREAM_FIFO_STATUS = SBE_FIFO_BASE + 0x0011;
+const uint32_t SBE_DOWNSTREAM_FIFO_SIGNAL_EOT = SBE_FIFO_BASE + 0x0012;
+const uint32_t SBE_DOWNSTREAM_FIFO_REQ_RESET = SBE_FIFO_BASE + 0x0013;
+const uint32_t SBE_DOWNSTREAM_FIFO_PERFORM_RESET = SBE_FIFO_BASE + 0x0014;
+const uint32_t SBE_DOWNSTREAM_FIFO_ACK_EOT = SBE_FIFO_BASE + 0x0015;
+
+/**
+ * @brief SBE Upstream FIFO Status bits
+ *
+ */
+
+typedef struct
+{
+ uint32_t valid_flag:1; // Bit 0
+ uint32_t eot_flag:1; // Bit 1
+ uint32_t parity_err:1; // Bit 2
+ uint32_t reserved3_5:3; // Bit 3:5
+ uint32_t req_upfifo_reset:1; // Bit 6
+ uint32_t req_downfifo_reset:1; // Bit 7
+ uint32_t signaling_eot:1; // Bit 8
+ uint32_t reserved9:1; // Bit 9
+ uint32_t fifo_full:1; // Bit 10
+ uint32_t fifo_empty:1; // Bit 11
+ uint32_t fifo_entry_count:4; // Bit 12:15
+ uint32_t fifo_valid_flags:8; // Bit 16:23
+ uint32_t fifo_eot_flags:8; // Bit 24:31
+
+} sbe_upfifo_status_t ;
+
+/**
+ * @brief 64-bit DW structure for Upstream FIFO Dequeue
+ * or Downstream FIFO Enqueue
+ * For Upstream FIFO,
+ * Bit 0 - 31 : Data, Bit 32 - 63 : Status
+ * For Downstream FIFO,
+ * Bit 0 - 31 : Data, Bit 32 - 63 : Unused
+ *
+ */
+typedef struct
+{
+ uint32_t fifo_data;
+
+ // The following status field is applicable only for
+ // upstream FIFO access and will remain reserved for
+ // downstream FIFO access
+ sbe_upfifo_status_t statusOrReserved;
+} sbeFifoEntry_t ;
+
+
+/**
+ * @brief 64-bit DW structure for Upstream FIFO Status Reg Read
+ * Bit 0 - 31 : Status Data, Bit 32 - 63 : Unused
+ *
+ */
+typedef struct
+{
+ sbe_upfifo_status_t upfifo_status;
+ uint32_t reserved;
+} sbeUpFifoStatusReg_t ;
+
+
+/**
+ * @brief SBE Downstream FIFO Status bits
+ *
+ */
+typedef struct
+{
+ uint32_t reserved0_1:2; // Bit 0:1
+ uint32_t parity_err:1; // Bit 2
+ uint32_t reserved3_5:3; // Bit 3:5
+ uint32_t req_downfifo_reset:1; // Bit 6
+ uint32_t req_upfifo_reset:1; // Bit 7
+ uint32_t signaling_eot:1; // Bit 8
+ uint32_t reserved9:1; // Bit 9
+ uint32_t fifo_full:1; // Bit 10
+ uint32_t fifo_empty:1; // Bit 11
+ uint32_t fifo_entry_count:4; // Bit 12:15
+ uint32_t fifo_valid_flags:8; // Bit 16:23
+ uint32_t fifo_eot_flags:8; // Bit 24:31
+
+} sbe_downfifo_status_t ;
+
+/**
+ * @brief 64-bit DW structure for Downstream FIFO Status Reg Read
+ * Bit 0 - 31 : Status Data, Bit 32 - 63 : Unused
+ *
+ */
+typedef struct
+{
+ sbe_downfifo_status_t downfifo_status;
+ uint32_t reserved;
+} sbeDownFifoStatusReg_t;
+
+/*****************************************************************/
+/** Upstream FIFO access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeUpFifoDeq : Read entry and status from Upstream FIFO
+ *
+ * @param[out] 64-Bit Data read from Upstream FIFO
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeUpFifoDeq (uint64_t *o_data)
+{
+ /* For SBE FIFO (PIB) access, chiplet ID should be passed as 0 */
+ return getscom_abs(SBE_UPSTREAM_FIFO_DEQ_ADD, o_data);
+}
+
+
+/**
+ * @brief sbeUpFifoPerformReset : Perform Upstream FIFO reset request
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeUpFifoPerformReset (void)
+{
+ SBE_INFO("sbeUpFifoPerformReset");
+ return putscom_abs(SBE_UPSTREAM_FIFO_PERFORM_RESET, ((uint64_t)0x1)<<32);
+}
+
+
+/**
+ * @brief sbeUpFifoAckEot : Acknowledge EOT in Upstream FIFO
+ *
+ * @return Rc from the underlying scom utility
+ *
+ */
+extern inline uint32_t sbeUpFifoAckEot (void)
+{
+ SBE_INFO("sbeUpFifoAckEot");
+ return putscom_abs(SBE_UPSTREAM_FIFO_ACK_EOT, ((uint64_t)0x1)<<32);
+}
+
+
+/*****************************************************************/
+/** Downstream FIFO access utilities **/
+/*****************************************************************/
+
+/**
+ * @brief sbeDownFifoEnq : Write data into Downstream FIFO
+ *
+ * @param[in] 64-Bit Data write into Downstream FIFO
+ * Bit 0-31 : Data
+ * Bit 32-63 : Unused
+ *
+ * @return Rc from the underlying scom utility
+ */
+extern inline uint32_t sbeDownFifoEnq (const uint64_t i_data)
+{
+ SBE_DEBUG(">sbeDownFifoEnq");
+ return putscom_abs(SBE_DOWNSTREAM_FIFO_ENQ_ADD, i_data);
+}
+
+
+/**
+ * @brief sbeDownFifoGetStatus : Read status from downstream FIFO
+ *
+ * @param[out] 64-Bit Read status from downstream FIFO
+ * Bit 0-31 : Data
+ * Bit 32-63 : Unused
+ *
+ * @return Rc from the underlying scom utility
+ */
+extern inline uint32_t sbeDownFifoGetStatus (uint64_t *o_data)
+{
+ return getscom_abs(SBE_DOWNSTREAM_FIFO_STATUS, o_data);
+}
+
+#endif // __SBEFW_SBEFIFO_H
diff --git a/src/sbefw/sbefwfiles.mk b/src/sbefw/sbefwfiles.mk
new file mode 100644
index 00000000..24f9318e
--- /dev/null
+++ b/src/sbefw/sbefwfiles.mk
@@ -0,0 +1,48 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/sbefw/sbefwfiles.mk $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+SBEFW-CPP-SOURCES = sbemain.C
+SBEFW-CPP-SOURCES += sbeirq.C
+SBEFW-CPP-SOURCES += sbecmdreceiver.C
+SBEFW-CPP-SOURCES += sbecmdprocessor.C
+SBEFW-CPP-SOURCES += sbecmdparser.C
+SBEFW-CPP-SOURCES += sbecmdscomaccess.C
+SBEFW-CPP-SOURCES += sbecmdiplcontrol.C
+SBEFW-CPP-SOURCES += pool.C
+SBEFW-CPP-SOURCES += sbecmdgeneric.C
+SBEFW-CPP-SOURCES += sbeFifoMsgUtils.C
+SBEFW-CPP-SOURCES += sbecmdmemaccess.C
+SBEFW-CPP-SOURCES += sbeHostUtils.C
+SBEFW-CPP-SOURCES += sbecmdcntrldmt.C
+SBEFW-CPP-SOURCES += sbecmdsram.C
+SBEFW-CPP-SOURCES += sberegaccess.C
+SBEFW-CPP-SOURCES += sbecmdcntlinst.C
+SBEFW-CPP-SOURCES += sbecmdregaccess.C
+SBEFW-CPP-SOURCES += sbeFFDC.C
+SBEFW-CPP-SOURCES += sbecmdringaccess.C
+SBEFW-CPP-SOURCES += sbescom.C
+
+SBEFW-C-SOURCES =
+SBEFW-S-SOURCES =
+
+SBEFW_OBJECTS = $(SBEFW-C-SOURCES:.c=.o) $(SBEFW-CPP-SOURCES:.C=.o) $(SBEFW-S-SOURCES:.S=.o)
diff --git a/src/sbefw/sbeirq.C b/src/sbefw/sbeirq.C
new file mode 100644
index 00000000..bf445245
--- /dev/null
+++ b/src/sbefw/sbeirq.C
@@ -0,0 +1,195 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeirq.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeirq.C
+ *
+ * @brief This sets up and registers SBE ISRs
+ *
+ */
+
+#include "sbeexeintf.H"
+#include "sbeirq.H"
+#include "sbetrace.H"
+#include "assert.h"
+
+extern sbeIntrHandle_t g_sbeIntrSource ;
+
+////////////////////////////////////////////////////////////////
+// @brief: SBE control loop ISR:
+// - FIFO new data available
+// - FIFO reset request
+// - PSU new data available
+//
+// @param[in] i_pArg - Unused
+// @param[in] i_irq - IRQ number as defined in sbeirq.h
+//
+////////////////////////////////////////////////////////////////
+void sbe_interrupt_handler (void *i_pArg, PkIrqId i_irq)
+{
+ #define SBE_FUNC " sbe_interrupt_handler "
+ SBE_ENTER(SBE_FUNC"i_irq=[0x%02X]",i_irq);
+
+ int l_rc = 0;
+
+ switch (i_irq)
+ {
+ case SBE_IRQ_HOST_PSU_INTR:
+ g_sbeIntrSource.setIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_PSU);
+ break;
+
+ case SBE_IRQ_SBEFIFO_DATA:
+ g_sbeIntrSource.setIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_RESET);
+ break;
+
+ case SBE_IRQ_SBEFIFO_RESET:
+ g_sbeIntrSource.setIntrSource(SBE_INTERRUPT_ROUTINE,
+ SBE_INTERFACE_FIFO_RESET);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_DATA);
+ break;
+
+ default:
+ SBE_ERROR(SBE_FUNC"Unknown IRQ, assert");
+ assert(0);
+ break;
+ }
+ // Mask the interrupt
+ pk_irq_disable(i_irq);
+
+ // Unblock the command receiver thread
+ l_rc = pk_semaphore_post(&g_sbeSemCmdRecv);
+ if (l_rc)
+ {
+ // If we received an error while posting the semaphore,
+ // unmask the interrupt back and assert
+ SBE_ERROR(SBE_FUNC"pk_semaphore_post failed, rc=[%d]", l_rc);
+ pk_irq_enable(i_irq);
+ assert(!l_rc);
+ }
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+// See sbeexeintf.h for more details
+////////////////////////////////////////////////////////////////
+int sbeIRQSetup (void)
+{
+ #define SBE_FUNC " sbeIRQSetup "
+ int l_rc = 0;
+ PkIrqId l_irq;
+
+ // Disable the relevant IRQs while we set them up
+ pk_irq_disable(SBE_IRQ_HOST_PSU_INTR);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_RESET);
+
+ do
+ {
+ // Register the IRQ handler with PK
+
+ // PSU New data available interrupt
+ l_irq = SBE_IRQ_HOST_PSU_INTR;
+ l_rc = pk_irq_handler_set(l_irq, sbe_interrupt_handler, NULL);
+ if(l_rc)
+ {
+ break;
+ }
+
+ // FIFO New data available interrupt
+ l_irq = SBE_IRQ_SBEFIFO_DATA;
+ l_rc = pk_irq_handler_set(l_irq, sbe_interrupt_handler, NULL);
+ if(l_rc)
+ {
+ break;
+ }
+
+ // FIFO Reset request
+ l_irq = SBE_IRQ_SBEFIFO_RESET;
+ l_rc = pk_irq_handler_set(l_irq, sbe_interrupt_handler, NULL);
+ if(l_rc)
+ {
+ break;
+ }
+
+ // Enable the IRQ
+ pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_enable(SBE_IRQ_HOST_PSU_INTR);
+ } while(false);
+
+ if (l_rc)
+ {
+ SBE_ERROR (SBE_FUNC"pk_irq_handler_set failed, IRQ=[0x%02X], "
+ "rc=[%d]", l_irq, l_rc);
+ }
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////////////
+// SBE handler for the PPE machine check interrupt
+////////////////////////////////////////////////////////////////
+// TODO: via RTC 155896 - Change the way bad scoms are handled.
+// Once HW375602 is fixed, there will be no need for this
+// interrupt handler.
+extern "C" void __sbe_machine_check_handler()
+{
+ asm(
+ "# Save r4 to stack, since it is going to be used by\n"
+ "# this handler\n"
+ "stwu %r1, -8(%r1)\n"
+ "stw %r4, 0(%r1)\n"
+ "# Check the MCS bits (29:31) in the ISR to determine the cause for the machine check\n"
+ "# For a data machine check, the MCS should be 0x001 to 0x011\n"
+ "mfisr %r4\n"
+ "andi. %r4, %r4, 0x0007\n"
+ "bwz %r4, __hang_forever\n"
+ "cmpwibgt %r4, 0x0003, __hang_forever\n"
+ "# The EDR contains the address that caused the machine check\n"
+ "mfedr %r4\n"
+ "srawi %r4, %r4, 16\n"
+ "# If the address is in the range 0x00000000 - 0x7f000000, we treat it as a\n"
+ "# failed scom and jump to __scom_error\n"
+ "cmplwi %r4, 0x8000\n"
+ "blt __scom_error\n"
+ "# Else, just hang here forever\n"
+ "__hang_forever:\n"
+ "b .\n"
+ "__scom_error:\n"
+ "# The srr0 contains the address of the instruction that caused the machine\n"
+ "# check (since the the interrupt is raised *before* the instruction\n"
+ "# completed execution). Since we want the code to continue with the next\n"
+ "# instruction, we increment srr0 by 4, restore r4, and rfi to branch to srr0\n"
+ "mfsrr0 %r4\n"
+ "addi %r4, %r4, 4\n"
+ "mtsrr0 %r4\n"
+ "lwz %r4, 0(%r1)\n"
+ "addi %r1, %r1, 8\n"
+ "rfi\n"
+ );
+}
+
diff --git a/src/sbefw/sbeirq.H b/src/sbefw/sbeirq.H
new file mode 100644
index 00000000..8102ce81
--- /dev/null
+++ b/src/sbefw/sbeirq.H
@@ -0,0 +1,109 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeirq.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbeirq.H
+ *
+ * @brief This file contains the SBE PPE Interrupt Request numbers
+ */
+
+#ifndef _SBE_IRQ_H
+#define _SBE_IRQ_H
+
+/**
+ * @brief SBE PPE IRQ numbers
+ *
+ */
+
+#define SBE_IRQ_START0 0 /* SBE Start Vector 0 */
+#define SBE_IRQ_START1 1 /* SBE Start Vector 1 */
+#define SBE_IRQ_INTR0 2 /* SBE Interrupt S0 */
+#define SBE_IRQ_INTR1 3 /* SBE Interrupt S1 */
+#define SBE_IRQ_DRTM_REQ 4 /* DRTM late launch request */
+#define SBE_IRQ_SBEFIFO_RESET 5 /* FIFO - Reset request from SE */
+#define SBE_IRQ_SBEFIFO_DATA 6 /* FIFO - Incoming Data Available */
+#define SBE_IRQ_HOST_PSU_INTR 7 /* PSU - Incoming Data Available */
+
+
+#define SBE_IRQ_RESERVED_8 8
+#define SBE_IRQ_RESERVED_9 9
+
+#define SBE_IRQ_RESERVED_10 10
+#define SBE_IRQ_RESERVED_11 11
+#define SBE_IRQ_RESERVED_12 12
+#define SBE_IRQ_RESERVED_13 13
+#define SBE_IRQ_RESERVED_14 14
+#define SBE_IRQ_RESERVED_15 15
+#define SBE_IRQ_RESERVED_16 16
+#define SBE_IRQ_RESERVED_17 17
+#define SBE_IRQ_RESERVED_18 18
+#define SBE_IRQ_RESERVED_19 19
+#define SBE_IRQ_RESERVED_20 20
+#define SBE_IRQ_RESERVED_21 21
+#define SBE_IRQ_RESERVED_22 22
+#define SBE_IRQ_RESERVED_23 23
+#define SBE_IRQ_RESERVED_24 24
+#define SBE_IRQ_RESERVED_25 25
+#define SBE_IRQ_RESERVED_26 26
+#define SBE_IRQ_RESERVED_27 27
+#define SBE_IRQ_RESERVED_28 28
+#define SBE_IRQ_RESERVED_29 29
+#define SBE_IRQ_RESERVED_30 30
+#define SBE_IRQ_RESERVED_31 31
+#define SBE_IRQ_RESERVED_32 32
+#define SBE_IRQ_RESERVED_33 33
+#define SBE_IRQ_RESERVED_34 34
+#define SBE_IRQ_RESERVED_35 35
+#define SBE_IRQ_RESERVED_36 36
+#define SBE_IRQ_RESERVED_37 37
+#define SBE_IRQ_RESERVED_38 38
+#define SBE_IRQ_RESERVED_39 39
+#define SBE_IRQ_RESERVED_40 40
+#define SBE_IRQ_RESERVED_41 41
+#define SBE_IRQ_RESERVED_42 42
+#define SBE_IRQ_RESERVED_43 43
+#define SBE_IRQ_RESERVED_44 44
+#define SBE_IRQ_RESERVED_45 45
+#define SBE_IRQ_RESERVED_46 46
+#define SBE_IRQ_RESERVED_47 47
+#define SBE_IRQ_RESERVED_48 48
+#define SBE_IRQ_RESERVED_49 49
+#define SBE_IRQ_RESERVED_50 50
+#define SBE_IRQ_RESERVED_51 51
+#define SBE_IRQ_RESERVED_52 52
+#define SBE_IRQ_RESERVED_53 53
+#define SBE_IRQ_RESERVED_54 54
+#define SBE_IRQ_RESERVED_55 55
+#define SBE_IRQ_RESERVED_56 56
+#define SBE_IRQ_RESERVED_57 57
+#define SBE_IRQ_RESERVED_58 58
+#define SBE_IRQ_RESERVED_59 59
+#define SBE_IRQ_RESERVED_60 60
+#define SBE_IRQ_RESERVED_61 61
+#define SBE_IRQ_RESERVED_62 62
+#define SBE_IRQ_RESERVED_63 63
+
+#define SBE_MACHINE_CHECK_HANDLER \
+ b __sbe_machine_check_handler
+
+#endif //_SBE_IRQ_H
diff --git a/src/sbefw/sbemain.C b/src/sbefw/sbemain.C
new file mode 100644
index 00000000..06488c14
--- /dev/null
+++ b/src/sbefw/sbemain.C
@@ -0,0 +1,352 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbemain.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbemain.C
+ *
+ * @brief This file does the following
+ * - SBE Application Main entry point
+ * - PK initialization
+ * - Thread initialization
+ * - Semaphore initialization
+ * - IRQ setup
+ * - Scheduling of the threads and
+ * - Starting of the control loop code flow
+ *
+ */
+
+
+#include "sbeexeintf.H"
+#include "sbetrace.H"
+#include "sberegaccess.H"
+#include "sbestates.H"
+#include "fapi2.H" // For target init
+
+////////////////////////////////////////////////////////////////
+// @brief Global semaphores
+////////////////////////////////////////////////////////////////
+PkSemaphore g_sbeSemCmdRecv;
+PkSemaphore g_sbeSemCmdProcess;
+
+// Max defines for Semaphores
+static uint32_t MAX_SEMAPHORE_COUNT = 3;
+
+////////////////////////////////////////////////////////////////
+// @brief Stacks for Non-critical Interrupts and Threads
+////////////////////////////////////////////////////////////////
+uint8_t g_sbe_Kernel_NCInt_stack[SBE_NONCRITICAL_STACK_SIZE];
+uint8_t g_sbeCommandReceiver_stack[SBE_THREAD_CMD_RECV_STACK_SIZE];
+uint8_t g_sbeSyncCommandProcessor_stack[SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE];
+uint8_t g_sbeAsyncCommandProcessor_stack[SBE_THREAD_ASYNC_CMD_PROC_STACK_SIZE];
+
+////////////////////////////////////////////////////////////////
+// @brief PkThread structure for SBE Command Receiver thread
+////////////////////////////////////////////////////////////////
+PkThread g_sbeCommandReceiver_thread;
+
+////////////////////////////////////////////////////////////////
+// @brief PkThread structure for SBE Synchronous ChipOps
+// processing thread
+////////////////////////////////////////////////////////////////
+PkThread g_sbeSyncCommandProcessor_thread;
+
+////////////////////////////////////////////////////////////////
+//// @brief PkThread structure for SBE Asynchronous ChipOps
+//// processing thread
+////////////////////////////////////////////////////////////////
+PkThread g_sbeAsyncCommandProcessor_thread;
+
+extern "C"
+{
+// These variables are declared in linker script to keep track of
+// global constructor pointer functions and sbss section.
+extern void (*ctor_start_address)() __attribute__ ((section (".rodata")));
+extern void (*ctor_end_address)() __attribute__ ((section (".rodata")));
+extern uint64_t _sbss_start __attribute__ ((section (".sbss")));
+extern uint64_t _sbss_end __attribute__ ((section (".sbss")));
+// This function will be used to do any C++ handling required before doing
+// any main job. Call to this function should get generated by
+// compiler.
+// TODO via RTC 152070
+// We are also initialising sbss section to zero this function.
+// Though it does not do any harm as of now, it is better if we use loader
+// or linker script to zero init sbss section. This way we will be future
+// garded if pk boot uses some static/global data initialised to
+// false in future.
+void __eabi()
+{
+ // Initialise sbss section
+ uint64_t *startAddr = &_sbss_start;
+ while ( startAddr != &_sbss_end )
+ {
+ *startAddr = 0;
+ startAddr++;
+ }
+
+ // Call global constructors
+ void(**ctors)() = &ctor_start_address;
+ while( ctors != &ctor_end_address)
+ {
+ (*ctors)();
+ ctors++;
+ }
+}
+} // end extern "C"
+
+////////////////////////////////////////////////////////////////
+// @brief sbeInitSems - Create the necessary semaphores
+//
+// @return PK_OK - Success
+// PK_INVALID_SEMAPHORE_AT_CREATE - Invalid PkSemaphore
+// PK_INVALID_ARGUMENT_SEMAPHORE - max_count is non-zero
+// and less than the initial_count
+////////////////////////////////////////////////////////////////
+uint32_t sbeInitSems(void)
+{
+ SBE_ENTER("sbeInitSems");
+ int l_rc = PK_OK;
+
+ do
+ {
+ l_rc = pk_semaphore_create(&g_sbeSemCmdRecv, 0, MAX_SEMAPHORE_COUNT);
+ if (l_rc)
+ {
+ break;
+ }
+ l_rc = pk_semaphore_create(&g_sbeSemCmdProcess, 0, MAX_SEMAPHORE_COUNT);
+ if (l_rc)
+ {
+ break;
+ }
+ } while (false);
+
+ if (l_rc)
+ {
+ SBE_ERROR ("pk_semaphore_create, rc=[%d]", l_rc);
+ }
+ return l_rc;
+}
+
+////////////////////////////////////////////////////////////////
+// @brief createAndResumeThreadHelper
+// - Create and resume the given thread
+//
+// @param[in/out] io_thread A pointer to an PkThread structure to initialize
+// @param[in] i_thread_routine The subroutine that implements the thread
+// @param[in/out] io_arg Private data to be passed as the argument to the
+// thread routine when it begins execution
+// @param[in] i_stack The stack space of the thread
+// @param[in] i_stack_size The size of the stack in bytes
+// @param[in] i_priority The initial priority of the thread
+//
+// @return PK_OK Successfully created and resumed the thread
+//
+// @return PK_INVALID_THREAD_AT_CREATE io_thread is null
+// @return PK_INVALID_ARGUMENT_THREAD1 i_thread_routine is null
+// @return PK_INVALID_ARGUMENT_THREAD2 i_priority is invalid
+// @return PK_INVALID_ARGUMENT_THREAD3 the stack area wraps around
+// the end of memory.
+// @return PK_STACK_OVERFLOW The stack area at thread creation
+// is smaller than the min safe size
+// @return PK_INVALID_THREAD_AT_RESUME1 io_thread is null (unlikely)
+// @return PK_INVALID_THREAD_AT_RESUME2 The thread is not active,
+// i.e. has completed or been deleted,
+// @return PK_PRIORITY_IN_USE_AT_RESUME Another thread is already
+// mapped at the priority of the thread
+////////////////////////////////////////////////////////////////
+uint32_t createAndResumeThreadHelper(PkThread *io_pThread,
+ PkThreadRoutine i_thread_routine,
+ void *io_pArg,
+ PkAddress i_stack,
+ size_t i_stack_size,
+ sbeThreadPriorities i_priority)
+{
+ int l_rc = PK_OK;
+
+ // Thread creation
+ l_rc = pk_thread_create(io_pThread,
+ i_thread_routine,
+ io_pArg,
+ i_stack,
+ i_stack_size,
+ (PkThreadPriority)i_priority);
+ if(l_rc == PK_OK)
+ {
+ // resume the thread once created
+ l_rc = pk_thread_resume(io_pThread);
+ }
+
+ // Check for errors creating or resuming the thread
+ if(l_rc != PK_OK)
+ {
+ SBE_ERROR ("Failure creating/resuming thread, rc=[%d]", l_rc);
+ }
+
+ return l_rc;
+}
+
+////////////////////////////////////////////////////////////////
+// @brief sbeInitThreads
+// Create the resume all the firmware threads
+//
+// @return See createAndResumeThreadHelper for more details
+////////////////////////////////////////////////////////////////
+int sbeInitThreads(void)
+{
+ // Locals
+ uint32_t l_rc = PK_OK;
+
+ do
+ {
+ // Initialize Command receiver thread
+ l_rc = createAndResumeThreadHelper(&g_sbeCommandReceiver_thread,
+ sbeCommandReceiver_routine,
+ (void *)0,
+ (PkAddress)g_sbeCommandReceiver_stack,
+ SBE_THREAD_CMD_RECV_STACK_SIZE,
+ THREAD_PRIORITY_5);
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize Synchronous Command Processor thread
+ l_rc = createAndResumeThreadHelper(&g_sbeSyncCommandProcessor_thread,
+ sbeSyncCommandProcessor_routine,
+ (void *)0,
+ (PkAddress)g_sbeSyncCommandProcessor_stack,
+ SBE_THREAD_SYNC_CMD_PROC_STACK_SIZE,
+ THREAD_PRIORITY_7);
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize Asynchronous Command Processor thread
+ l_rc = createAndResumeThreadHelper(&g_sbeAsyncCommandProcessor_thread,
+ sbeAsyncCommandProcessor_routine,
+ (void *)0,
+ (PkAddress)g_sbeAsyncCommandProcessor_stack,
+ SBE_THREAD_ASYNC_CMD_PROC_STACK_SIZE,
+ THREAD_PRIORITY_6);
+ if (l_rc)
+ {
+ break;
+ }
+ } while (false);
+
+ // If there are any errors initializing the threads
+ if( l_rc )
+ {
+ SBE_ERROR ("Error Initializing a thread, rc=[%d]", l_rc);
+ }
+
+ return l_rc;
+}
+
+////////////////////////////////////////////////////////////////
+// @brief - main : SBE Application main
+////////////////////////////////////////////////////////////////
+uint32_t main(int argc, char **argv)
+{
+ #define SBE_FUNC "main "
+ SBE_ENTER(SBE_FUNC);
+ int l_rc = 0;
+
+ // @TODO via RTC : 128818
+ // Explore on reclaiming the stack
+ // used by this Initialization code
+
+ do
+ {
+ // initializes kernel data -
+ // stack, threads, timebase, timers, etc.
+ l_rc = pk_initialize((PkAddress)g_sbe_Kernel_NCInt_stack,
+ SBE_NONCRITICAL_STACK_SIZE,
+ 0,
+ 500000000); // @TODO via RTC : 128819
+ // Need to obtain at Runtime, a new attribute?
+ if (l_rc)
+ {
+ break;
+ }
+
+ SBE_INFO("Completed PK init");
+
+ // Initialize the semaphores
+ l_rc = sbeInitSems();
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Initialize SBE control loop threads
+ l_rc = sbeInitThreads();
+ if (l_rc)
+ {
+ break;
+ }
+
+ // Setup SBE PPE IRQs
+ l_rc = sbeIRQSetup();
+ if (l_rc)
+ {
+ break;
+ }
+
+ // TODO via RTC 126146.
+ // Check if we should call plat_TargetsInit in some other thread.
+ // We may want to keep only PK init in main and can move
+ // plat init to some other thread. Only if this is required by more
+ // than one thread and there can be some race condition, we will
+ // keep it here before starting other threads.
+ fapi2::ReturnCode fapiRc = fapi2::plat_TargetsInit();
+ if( fapiRc != fapi2::FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC"plat_TargetsInit failed");
+ (void)SbeRegAccess::theSbeRegAccess().
+ stateTransition(SBE_FAILURE_EVENT);
+ // Hard Reset SBE to recover
+ break;
+ }
+
+ if(SbeRegAccess::theSbeRegAccess().init())
+ {
+ SBE_ERROR(SBE_FUNC"Failed to initialize SbeRegAccess");
+ // init failure could mean the below will fail too, but attempt it
+ // anyway
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_FAILURE_EVENT);
+ // Hard Reset SBE to recover
+ break;
+ }
+
+ // Start running the highest priority thread.
+ // This function never returns
+ pk_start_threads();
+
+ } while (false);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+}
diff --git a/src/sbefw/sberegaccess.C b/src/sbefw/sberegaccess.C
new file mode 100644
index 00000000..71540e56
--- /dev/null
+++ b/src/sbefw/sberegaccess.C
@@ -0,0 +1,331 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sberegaccess.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sberegaccess.C
+ *
+ * @brief This file contains interfaces to get/set FW flags either in the
+ * scratch registers and/or the FW attributes.
+ */
+
+#include "sberegaccess.H"
+#include "sbetrace.H"
+#include "fapi2.H"
+#include <ppe42_scom.h>
+#include <p9_perv_scom_addresses.H>
+
+using namespace fapi2;
+
+// Struct to Map Current State - Event - Final State Transition
+typedef struct stateTransitionStr
+{
+ uint16_t currState:4;
+ uint16_t event:4;
+ uint16_t finalState:4;
+ uint16_t reserved:4;
+} stateTransitionStr_t;
+
+// Start and End point of Event Transition in stateTransMap Table
+typedef struct stateEventRangeStr
+{
+ uint16_t start:8;
+ uint16_t end:8;
+}stateEventRangeStr_t;
+
+// Entry Point and End point to the StateTransition Map for a State
+// It is sequenced as per the sbeState enum, Don't change the sequence
+// of states. Events are incremented w.r.t previous event.
+static const stateEventRangeStr_t eventRangePerState[SBE_MAX_STATE] =
+{
+ {SBE_STATE_UNKNOWN_ENTRY_TO_MAP, SBE_STATE_UNKNOWN_MAX_EVENT},
+ {SBE_STATE_FFDC_COLLECT_ENTRY_TO_MAP, SBE_STATE_FFDC_COLLECT_MAX_EVENT},
+ {SBE_STATE_IPLING_ENTRY_TO_MAP, SBE_STATE_IPLING_MAX_EVENT},
+ {SBE_STATE_ISTEP_ENTRY_TO_MAP, SBE_STATE_ISTEP_MAX_EVENT},
+ {SBE_STATE_RUNTIME_ENTRY_TO_MAP, SBE_STATE_RUNTIME_MAX_EVENT},
+ {SBE_STATE_MPIPL_ENTRY_TO_MAP, SBE_STATE_MPIPL_MAX_EVENT},
+ {SBE_STATE_DMT_ENTRY_TO_MAP, SBE_STATE_DMT_MAX_EVENT},
+ {SBE_STATE_DUMP_ENTRY_TO_MAP, SBE_STATE_DUMP_MAX_EVENT},
+ {SBE_STATE_FAILURE_ENTRY_TO_MAP, SBE_STATE_FAILURE_MAX_EVENT},
+ {SBE_STATE_QUIESCE_ENTRY_TO_MAP, SBE_STATE_QUIESCE_MAX_EVENT},
+ {SBE_STATE_ABORT_ENTRY_TO_MAP, SBE_STATE_ABORT_MAX_EVENT},
+};
+
+// Map to connect the current State with an event along with the final state
+// transition. It is sequenced according to the sbeState enums, Don't change the
+// sequence of states.
+static const stateTransitionStr_t stateTransMap[SBE_MAX_TRANSITIONS] = {
+ {SBE_STATE_UNKNOWN, SBE_FAILURE_EVENT, SBE_STATE_FAILURE},
+ {SBE_STATE_UNKNOWN, SBE_RUNTIME_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_UNKNOWN, SBE_ISTEP_EVENT, SBE_STATE_ISTEP},
+ {SBE_STATE_UNKNOWN, SBE_PLCK_EVENT, SBE_STATE_IPLING},
+ {SBE_STATE_UNKNOWN, SBE_FFDC_COLLECT_EVENT, SBE_STATE_FFDC_COLLECT},
+ {SBE_STATE_FFDC_COLLECT, SBE_CONTINUE_BOOT_PLCK_EVENT, SBE_STATE_IPLING},
+ {SBE_STATE_FFDC_COLLECT, SBE_CONTINUE_BOOT_RUNTIME_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_FFDC_COLLECT, SBE_ISTEP_EVENT, SBE_STATE_ISTEP},
+ {SBE_STATE_FFDC_COLLECT, SBE_FAILURE_EVENT, SBE_STATE_DUMP},
+ {SBE_STATE_IPLING, SBE_RUNTIME_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_IPLING, SBE_DUMP_FAILURE_EVENT, SBE_STATE_DUMP},
+ {SBE_STATE_IPLING, SBE_FAILURE_EVENT, SBE_STATE_FAILURE},
+ {SBE_STATE_IPLING, SBE_ABORT_EVENT, SBE_STATE_ABORT},
+ {SBE_STATE_ISTEP, SBE_RUNTIME_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_ISTEP, SBE_ABORT_EVENT, SBE_STATE_ABORT},
+ {SBE_STATE_ISTEP, SBE_FAILURE_EVENT, SBE_STATE_FAILURE},
+ {SBE_STATE_RUNTIME, SBE_DUMP_FAILURE_EVENT, SBE_STATE_DUMP},
+ {SBE_STATE_RUNTIME, SBE_ENTER_MPIPL_EVENT, SBE_STATE_MPIPL},
+ {SBE_STATE_RUNTIME, SBE_DMT_ENTER_EVENT, SBE_STATE_DMT},
+ {SBE_STATE_RUNTIME, SBE_FAILURE_EVENT, SBE_STATE_FAILURE},
+ {SBE_STATE_MPIPL, SBE_CONTINUE_MPIPL_EVENT, SBE_STATE_RUNTIME},
+ {SBE_STATE_MPIPL, SBE_DUMP_FAILURE_EVENT, SBE_STATE_DUMP},
+ {SBE_STATE_DMT, SBE_DMT_COMP_EVENT, SBE_STATE_RUNTIME},
+};
+
+/**
+ * @brief Initizlize the class
+ *
+ * @return An RC indicating success/failure
+ */
+
+void SbeRegAccess::stateTransition(const sbeEvent &i_event)
+{
+ #define SBE_FUNC "SbeRegAccess::stateTransition "
+ //Fetch Current State
+ uint32_t l_state = (uint32_t)getSbeState();
+ uint8_t l_startCnt = eventRangePerState[l_state].start;
+ SBE_INFO(SBE_FUNC "Event Received %d CurrState 0x%08X StartCnt%d EndCnt%d",
+ i_event, l_state, l_startCnt, eventRangePerState[l_state].end);
+ // Fetch the final State from the Map
+ while(l_startCnt <
+ (eventRangePerState[l_state].end + eventRangePerState[l_state].start))
+ {
+ if(stateTransMap[l_startCnt].event == i_event)
+ {
+ SBE_INFO(SBE_FUNC "Updating State as %d",
+ (sbeState)stateTransMap[l_startCnt].finalState);
+ updateSbeState((sbeState)stateTransMap[l_startCnt].finalState);
+ break;
+ }
+ else
+ ++l_startCnt;
+ }
+ #undef SBE_FUNC
+}
+
+uint32_t SbeRegAccess::init()
+{
+ #define SBE_FUNC "SbeRegAccess::SbeRegAccess "
+ static bool l_initDone = false;
+ uint32_t l_rc = 0;
+ uint64_t l_mbx8 = 0;
+ do
+ {
+ if(l_initDone)
+ {
+ break;
+ }
+ // Read SBE messaging register into iv_messagingReg
+ l_rc = getscom_abs(PERV_SB_MSG_SCOM, &iv_messagingReg);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading sbe messaging reg., RC: 0x%08X. ",
+ l_rc);
+ break;
+ }
+ // Read Mailbox register 8 to check if the mailbox registers 3 and 6 are
+ // valid
+ l_rc = getscom_abs(PERV_SCRATCH_REGISTER_8_SCOM, &l_mbx8);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading mailbox reg 7, RC: 0x%08X. ",
+ l_rc);
+ break;
+ }
+ if(l_mbx8 & SBE_MBX8_MBX3_VALID_MASK)
+ {
+ // Read MBX3
+ l_rc = getscom_abs(PERV_SCRATCH_REGISTER_3_SCOM, &iv_mbx3);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading mailbox reg 3, RC: 0x%08X. ",
+ l_rc);
+ break;
+ }
+ }
+ else
+ {
+ // Need to read the values off the attributes
+ uint32_t l_attr = 0;
+ FAPI_ATTR_GET(ATTR_BOOT_FLAGS, Target<TARGET_TYPE_SYSTEM>(),
+ l_attr);
+ iv_mbx3 = ((uint64_t) l_attr ) << 32;
+ }
+ if(l_mbx8 & SBE_MBX8_MBX6_VALID_MASK)
+ {
+ // Read MBX6
+ l_rc = getscom_abs(PERV_SCRATCH_REGISTER_6_SCOM, &iv_mbx6);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading mailbox reg 6, RC: 0x%08X. "
+ l_rc);
+ break;
+ }
+ }
+ // If the master/slave bit is 0 (either default or read from mbx6),
+ // check the C4 board pin to determine role
+ if(0 == iv_isSlave)
+ {
+ uint64_t l_sbeDevIdReg = 0;
+ // Read device ID register
+ l_rc = getscom_abs(PERV_DEVICE_ID_REG, &l_sbeDevIdReg);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading device id reg, RC: 0x%08X. "
+ l_rc);
+ break;
+ }
+ iv_isSlave = l_sbeDevIdReg & SBE_DEV_ID_C4_PIN_MASK;
+ SBE_INFO(SBE_FUNC"Overriding master/slave with data read from "
+ "C4 pin: HI: 0x%08X, LO: 0x%08X",
+ (uint32_t)(l_sbeDevIdReg >> 32),
+ (uint32_t)(l_sbeDevIdReg & 0xFFFFFFFF));
+ }
+ } while(false);
+
+ SBE_INFO(SBE_FUNC"Read mailbox registers: mbx8: 0x%08X, mbx3: 0x%08X, "
+ "mbx6: 0x%08X", (uint32_t)(l_mbx8 >> 32),
+ (uint32_t)(iv_mbx3 >> 32), (uint32_t)(iv_mbx6 >> 32));
+ l_initDone = true;
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/**
+ * @brief Update the SBE states into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the state
+ * bits are preserved. The current state of the register is set to
+ * i_state, whereas the old current state is copied to previous state
+ *
+ * @param [in] i_state The current SBE state
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::updateSbeState(const sbeState &i_state)
+{
+ #define SBE_FUNC "SbeRegAccess::updateSbeState "
+ uint32_t l_rc = 0;
+
+ iv_prevState = iv_currState;
+ iv_currState = i_state;
+ l_rc = putscom_abs(PERV_SB_MSG_SCOM, iv_messagingReg);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to update state to messaging "
+ "register. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/**
+ * @brief Update the SBE IPL steps into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the IPL
+ * steps are retianed
+ *
+ * @param [in] i_major IPL major step number
+ * @param [in] i_minor IPL minor step number
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::updateSbeStep(const uint8_t i_major,
+ const uint8_t i_minor)
+{
+ #define SBE_FUNC "SbeRegAccess::updateSbeStep "
+ uint32_t l_rc = 0;
+
+ iv_majorStep = i_major;
+ iv_minorStep = i_minor;
+
+ l_rc = putscom_abs(PERV_SB_MSG_SCOM, iv_messagingReg);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to update SBE step to messaging "
+ "register. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/**
+ * @brief Set the SBE ready bit into the SBE messaging register
+ * (meaning that SBE control loop is initialized) The function does a
+ * read-modify-write, so any bits other than the SBE ready bit remain
+ * unchanged.
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::setSbeReady()
+{
+ #define SBE_FUNC "SbeRegAccess::setSbeReady "
+ uint32_t l_rc = 0;
+
+ iv_sbeBooted = true;
+ l_rc = putscom_abs(PERV_SB_MSG_SCOM, iv_messagingReg);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to update SBE ready state to "
+ "messaging register. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+/**
+ * @brief Set the MPIPL mode bit into the mailbox scratch reg. 3
+ * The function does a read-modify-write, so any bits other than the
+ * SBE ready bit remain unchanged.
+ *
+ * @param i_set [in] Whether to set or clear the MPIPL flag
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::setMpIplMode(const bool i_set)
+{
+ #define SBE_FUNC "SbeRegAccess::setMpIplMode"
+ uint32_t l_rc = 0;
+ uint8_t l_set = i_set;
+ iv_mpiplMode = i_set;
+ FAPI_ATTR_SET(ATTR_IS_MPIPL, Target<TARGET_TYPE_SYSTEM>(), l_set);
+ l_rc = putscom_abs(PERV_SCRATCH_REGISTER_3_SCOM, iv_mbx3);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to set/clear MPIPL flag in "
+ "mbx reg. 3. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/sberegaccess.H b/src/sbefw/sberegaccess.H
new file mode 100644
index 00000000..84e2c87e
--- /dev/null
+++ b/src/sbefw/sberegaccess.H
@@ -0,0 +1,266 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sberegaccess.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sberegaccess.H
+ *
+ * @brief This file contains interfaces to get/set FW flags either in the
+ * scratch registers and/or the FW attributes.
+ */
+
+#ifndef __SBEFW_SBEREGACCESS_H
+#define __SBEFW_SBEREGACCESS_H
+
+#include <stdint.h>
+#include "sbestates.H"
+#include "sbeevents.H"
+
+/**
+ * @brief Utility singleton that SBEFW can use to read write various scratch
+ * registers/FW attributes
+ * TODO: via RTC ??????: Need to change the read of scratch registers to FAPI
+ * attribute accesses once we have the attributes defined in the HWP code.
+ */
+class SbeRegAccess
+{
+ public:
+ // Disable copy construction and assignment operators
+ SbeRegAccess(const SbeRegAccess&) = delete;
+ SbeRegAccess& operator=(const SbeRegAccess&) = delete;
+
+ /**
+ * @brief Returns the instance of this class
+ *
+ * @return A reference to SbeRegAccess
+ *
+ */
+ static SbeRegAccess& theSbeRegAccess()
+ {
+ static SbeRegAccess iv_instance;
+ return iv_instance;
+ }
+
+ /**
+ * @brief Initializes the class for use
+ *
+ * @return An RC indicating success/failure
+ *
+ */
+ uint32_t init();
+
+ /**
+ * @brief Update the SBE states into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the state
+ * bits are preserved. The current state of the register is set to
+ * i_state, whereas the old current state is copied to previous state
+ *
+ * @param [in] i_state The current SBE state
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t updateSbeState(const sbeState &i_state);
+
+ /**
+ * @brief Update the SBE IPL steps into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the IPL
+ * steps are retianed
+ *
+ * @param [in] i_major IPL major step number
+ * @param [in] i_minor IPL minor step number
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t updateSbeStep(const uint8_t i_major, const uint8_t i_minor);
+
+ /**
+ * @brief Set the SBE ready bit into the SBE messaging register
+ * (meaning that SBE control loop is initialized) The function does a
+ * read-modify-write, so any bits other than the SBE ready bit remain
+ * unchanged.
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t setSbeReady();
+
+ /**
+ * @brief Set the MPIPL mode bit into the mailbox scratch reg. 3
+ * The function does a read-modify-write, so any bits other than the
+ * SBE ready bit remain unchanged. It also updates the attribute
+ * ATTR_MPIPL
+ *
+ * @param i_set [in] true == set, false == clear
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t setMpIplMode(const bool i_set);
+
+ /**
+ * @brief Check if we are on an FSP attached
+ *
+ * @return true if FSP attached system, false otherwise
+ *
+ */
+ inline bool isFspSystem() const
+ {
+ return iv_fspAttached;
+ }
+
+ /**
+ * @brief Check if we are in ISTEP IPL mode
+ *
+ * @return true if in istep mode, false otherwise
+ *
+ */
+ inline bool isIstepMode() const
+ {
+ return iv_istepMode;
+ }
+
+ /**
+ * @brief Check if SBE should directly go to runtime state
+ *
+ * @return true if SBE should go directly to runtime state,
+ * false otherwise
+ *
+ */
+ inline bool isDestBitRuntime() const
+ {
+ return iv_sbeDestRuntime;
+ }
+
+ /**
+ * @brief Check if SBE should collect FFDC
+ *
+ * @return true if in istep mode, false otherwise
+ *
+ */
+ inline bool isCollectFFDCSet() const
+ {
+ return iv_collectFFDC;
+ }
+
+ /**
+ * @brief Check if SBE should send internal FFDC for any chip op
+ * failures as a part of the response
+ *
+ * @return true if in istep mode, false otherwise
+ *
+ */
+ inline bool isSendInternalFFDCSet() const
+ {
+ return iv_sendFFDC;
+ }
+
+ /**
+ * @brief Check if SBE is slave/master
+ *
+ * @return true if SBE is slave, false if master
+ *
+ */
+ inline bool isSbeSlave() const
+ {
+ return iv_isSlave;
+ }
+
+ /**
+ * @brief Get the SBE current State
+ *
+ * @return SBE current State, sbeState enum
+ *
+ */
+ uint64_t getSbeState() const
+ {
+ return iv_currState;
+ }
+
+ /**
+ * @brief Update the SBE State as per the transition event
+ *
+ * @param [in] i_event Transition Event
+ */
+ void stateTransition(const sbeEvent &i_event);
+
+ private:
+
+ /**
+ * @brief Constructor
+ */
+ SbeRegAccess() : iv_mbx3(0), iv_mbx6(0), iv_messagingReg(0)
+ {}
+
+ union
+ {
+ struct
+ {
+ uint64_t iv_istepMode : 1;
+ uint64_t iv_sbeDestRuntime : 1;
+ uint64_t iv_mpiplMode : 1;
+ uint64_t iv_fspAttached : 1;
+ uint64_t iv_collectFFDC : 1;
+ uint64_t iv_sendFFDC : 1;
+ uint64_t iv_mbx3DontCare : 26;
+ uint64_t iv_mbx3Unused : 32;
+ };
+ uint64_t iv_mbx3;
+ };
+
+ union
+ {
+ struct
+ {
+ uint64_t iv_mbx6DontCare : 24;
+ uint64_t iv_isSlave : 1;
+ uint64_t iv_mbx6DontCare2 : 7;
+ uint64_t iv_mbx6Unused : 32;
+ };
+ uint64_t iv_mbx6;
+ };
+
+ union
+ {
+ struct
+ {
+ uint64_t iv_sbeBooted : 1;
+ uint64_t iv_reserved1 : 3;
+ uint64_t iv_prevState : 4;
+ uint64_t iv_currState : 4;
+ uint64_t iv_majorStep : 4;
+ uint64_t iv_minorStep : 8;
+ uint64_t iv_reserved2 : 8;
+ uint64_t iv_unused : 32;
+ };
+ uint64_t iv_messagingReg;
+ };
+
+ // Bit masks defining bits in the above registers that the SBE is
+ // interested in
+ static const uint64_t SBE_MBX8_MBX3_VALID_MASK = 0x2000000000000000ULL;
+ static const uint64_t SBE_MBX8_MBX6_VALID_MASK = 0x0400000000000000ULL;
+ static const uint64_t SBE_DEV_ID_C4_PIN_MASK = 0x0000000000800000ULL;
+};
+#endif //__SBEFW_SBEREGACCESS_H
+
diff --git a/src/sbefw/sbescom.C b/src/sbefw/sbescom.C
new file mode 100644
index 00000000..9a2fc38c
--- /dev/null
+++ b/src/sbefw/sbescom.C
@@ -0,0 +1,198 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbescom.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 <stdint.h>
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "ppe42_scom.h"
+
+/**
+ * @brief Indirect SCOM Status
+ */
+union IndirectScom_t
+{
+ uint64_t data64;
+ struct
+ {
+ uint64_t :12; //0:11
+ uint64_t addr:20; //12:31
+ uint64_t done:1; //32
+ uint64_t piberr:3; //33:35
+ uint64_t userstat:4; //36:39
+ uint64_t :8; //40:47
+ uint64_t data:16; //48:63
+ };
+
+};
+
+// Wait time slice to check indirect scom status register
+static const uint32_t SBE_INDIRECT_SCOM_WAIT_TIME_NS = 10000;
+// Indirect scom timeout
+static const uint32_t MAX_INDSCOM_TIMEOUT_NS = 100000; //0.1 ns
+
+static const uint64_t DIRECT_SCOM_ADDR_MASK = 0x8000000000000000;
+static const uint64_t INDIRECT_SCOM_NEW_ADDR_MASK = 0x9000000000000000;
+
+// Scom types
+enum sbeScomType
+{
+ SBE_SCOM_TYPE_DIRECT = 0, // Direct scom
+ SBE_SCOM_TYPE_INDIRECT1 = 1, // Indirect scom. Old form
+ SBE_SCOM_TYPE_INDIRECT_2 = 2, // Indirect scom. New form
+};
+
+uint32_t checkIndirectAndDoScom( const bool i_isRead,
+ const uint64_t i_addr,
+ uint64_t & io_data,
+ uint32_t & o_pcbPibStatus )
+{
+
+ #define SBE_FUNC " checkIndirectAndDoScom "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t elapsedIndScomTimeNs = 0;
+ uint64_t tempBuffer = io_data;
+ sbeScomType scomType = SBE_SCOM_TYPE_DIRECT;
+ do
+ {
+ // If the indirect scom bit is 0, then doing a regular scom
+ if( (i_addr & DIRECT_SCOM_ADDR_MASK) == 0)
+ {
+ SBE_INFO(SBE_FUNC "Performing Direct scom");
+ if( i_isRead )
+ {
+ o_pcbPibStatus = getscom_abs ( (uint32_t)i_addr,
+ & io_data);
+ }
+ else
+ {
+ o_pcbPibStatus = putscom_abs ( (uint32_t)i_addr,
+ io_data);
+ }
+ break;
+ }
+ // We are performing an indirect scom.
+ if( ( i_addr & INDIRECT_SCOM_NEW_ADDR_MASK ) ==
+ INDIRECT_SCOM_NEW_ADDR_MASK )
+ {
+ scomType = SBE_SCOM_TYPE_INDIRECT_2;
+ if( i_isRead )
+ {
+ // Not allowed write on new format.
+ SBE_ERROR(SBE_FUNC "Read not allowed in new form");
+ l_rc = SBE_SEC_INVALID_ADDRESS_PASSED;
+ break;
+ }
+ // Zero out the indirect address location.. leave the 52bits of data
+ // Get the 12bit indirect scom address
+ // OR in the 20bit indirect address
+ tempBuffer = ( tempBuffer & 0x000FFFFFFFFFFFFF ) |
+ ( ( i_addr & 0x00000FFF00000000) << 20 );
+ }
+ else
+ {
+ scomType = SBE_SCOM_TYPE_INDIRECT1;
+ // Zero out the indirect address location.. leave the 16bits of data
+ // Get the 20bit indirect scom address
+ // OR in the 20bit indirect address
+ tempBuffer = ( tempBuffer & 0x000000000000FFFF) |
+ ( i_addr & 0x000FFFFF00000000 );
+ }
+
+ SBE_INFO(SBE_FUNC "Performing Indirect scom. Type :%u", scomType);
+
+ // zero out the indirect address from the buffer..
+ // bit 0-31 - indirect area..
+ // bit 32 - always 0
+ // bit 33-47 - bcast/chipletID/port
+ // bit 48-63 - local addr
+ uint64_t tempAddr = i_addr & 0x000000007FFFFFFF;
+
+ // If we are doing a read. We need to do a write first..
+ if( i_isRead)
+ {
+ // turn the read bit on.
+ tempBuffer = tempBuffer | 0x8000000000000000;
+ }
+ else //write
+ {
+ // Turn the read bit off.
+ tempBuffer = tempBuffer & 0x7FFFFFFFFFFFFFFF;
+
+ } // end of write
+
+ // perform write before the read with the new
+ // IO_buffer with the imbedded indirect scom addr.
+ o_pcbPibStatus = putscom_abs ( tempAddr, tempBuffer);
+
+ if( ( o_pcbPibStatus ) || ( scomType == SBE_SCOM_TYPE_INDIRECT_2 ))
+ {
+ break;
+ }
+
+ // Need to check loop on read until we see done, error,
+ // or we timeout
+ IndirectScom_t scomout;
+ do
+ {
+ // Now perform the op requested using the passed in
+ // IO_Buffer to pass the read data back to caller.
+ o_pcbPibStatus = getscom_abs ( tempAddr, &(scomout.data64));
+
+ if( o_pcbPibStatus ) break;
+ // if bit 32 is on indicating a complete bit
+ // or we saw an error, then we're done
+ if (scomout.piberr)
+ {
+
+ SBE_ERROR(SBE_FUNC "pib error reading status register");
+ o_pcbPibStatus = scomout.piberr;
+ break;
+ }
+ if (scomout.done )
+ {
+ io_data = scomout.data;
+ break;
+ }
+
+ pk_sleep(PK_NANOSECONDS(SBE_INDIRECT_SCOM_WAIT_TIME_NS));
+ elapsedIndScomTimeNs += SBE_INDIRECT_SCOM_WAIT_TIME_NS;
+
+ }while ( elapsedIndScomTimeNs <= MAX_INDSCOM_TIMEOUT_NS);
+
+ if( o_pcbPibStatus ) break;
+ if( ! scomout.done)
+ {
+ SBE_ERROR(SBE_FUNC "Indirect scom timeout");
+ l_rc = SBE_SEC_HW_OP_TIMEOUT;
+ break;
+ }
+
+ }while(0);
+
+ if (o_pcbPibStatus ) l_rc = SBE_SEC_PCB_PIB_ERR;
+
+ SBE_DEBUG(SBE_FUNC "o_pcbPibStatus:%u l_rc:0x%08X", o_pcbPibStatus, l_rc);
+ return l_rc;
+}
+
diff --git a/src/sbefw/sbescom.H b/src/sbefw/sbescom.H
new file mode 100644
index 00000000..3809ba10
--- /dev/null
+++ b/src/sbefw/sbescom.H
@@ -0,0 +1,38 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbescom.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+
+/**
+ * @brief check if scom address is Indirect scom and perform scom
+ *
+ * @param[in] i_isRead True if read operation, false otherwise
+ * @param[in] i_addr scom addess
+ * @param[in] io_data data for scom operation. For read, it is output operand.
+ * @param[in] o_pcbPibStatus pcbpib status
+ *
+ * @return seconday error code.
+ */
+uint32_t checkIndirectAndDoScom( const bool i_isRead,
+ const uint64_t i_addr,
+ uint64_t & io_data,
+ uint32_t & o_pcbPibStatus );
diff --git a/src/sbefw/sbestates.H b/src/sbefw/sbestates.H
new file mode 100644
index 00000000..6acaba4d
--- /dev/null
+++ b/src/sbefw/sbestates.H
@@ -0,0 +1,67 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbestates.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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: ppe/sbe/sbefw/sbestates.H
+ *
+ * @brief This file contains interfaces pertaining to SBE state/role management
+ *
+ */
+
+#ifndef __SBEFW_SBESTATES_H
+#define __SBEFW_SBESTATES_H
+
+/**
+ * @brief An enumeration of all SBE states
+ *
+ */
+enum sbeState
+{
+ SBE_STATE_UNKNOWN = 0x0, // Unkown, initial state
+ SBE_STATE_FFDC_COLLECT = 0x1, // Waiting for FFDC collection after a reset
+ SBE_STATE_IPLING = 0x2, // IPL'ing - autonomous mode (transient)
+ SBE_STATE_ISTEP = 0x3, // ISTEP - Running IPL by steps (transient)
+ SBE_STATE_RUNTIME = 0x4, // SBE Runtime
+ SBE_STATE_MPIPL = 0x5, // MPIPL
+ SBE_STATE_DMT = 0x6, // Dead Man Timer State (transient)
+ SBE_STATE_DUMP = 0x7, // Dumping
+ SBE_STATE_FAILURE = 0x8, // Internal SBE failure
+ SBE_STATE_QUIESCE = 0x9, // Final state - needs SBE reset to get out
+ SBE_STATE_ABORT = 0xA, // SBE was asked to abort - need reset to get out
+
+ // Max States, Always keep it at the last of the enum and sequential
+ SBE_MAX_STATE = 0xB,
+ // Don't count this in the state, just to intialize the state variables
+ SBE_INVALID_STATE = 0xF,
+};
+
+enum sbeRole
+{
+ SBE_ROLE_MASTER = 0,
+ SBE_ROLE_SLAVE = 1
+};
+
+extern sbeRole g_sbeRole;
+
+#endif //__SBEFW_SBESTATES_H
+
diff --git a/src/sbefw/sbetrace.H b/src/sbefw/sbetrace.H
new file mode 100644
index 00000000..1d7df7e4
--- /dev/null
+++ b/src/sbefw/sbetrace.H
@@ -0,0 +1,75 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbetrace.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 __SBEFW_SBE_TRACE_H
+#define __SBEFW_SBE_TRACE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pk_api.h"
+#include "trac_interface.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#define SBE_ENTER_MRK ">>"
+#define SBE_EXIT_MRK "<<"
+#define SBE_ERR_MRK "E>"
+#define SBE_INF_MRK "I>"
+#define SBE_DEBUG_MRK "D>"
+
+#define SBE_ERROR(args...)
+#define SBE_INFO(args...)
+#define SBE_ENTER(args...)
+#define SBE_EXIT(args...)
+#define SBE_DEBUG(args...)
+
+// Levels of logging
+// 0 - No tracing
+// 1 - Error
+// 2 - Error, info
+// 3 - Error, info, entry/exit
+// 4 - Error, info, entry/exit, debug
+#if (SBE_TRACE_LEVEL >= 1)
+#undef SBE_ERROR
+#define SBE_ERROR(args...) PK_TRACE(SBE_ERR_MRK"" args)
+#endif
+#if (SBE_TRACE_LEVEL >= 2)
+#undef SBE_INFO
+#define SBE_INFO(args...) PK_TRACE(SBE_INF_MRK"" args)
+#endif
+#if (SBE_TRACE_LEVEL >= 3)
+#undef SBE_ENTER
+#undef SBE_EXIT
+#define SBE_ENTER(args...) PK_TRACE(SBE_ENTER_MRK"" args)
+#define SBE_EXIT(args...) PK_TRACE(SBE_EXIT_MRK"" args)
+#endif
+#if (SBE_TRACE_LEVEL >= 4)
+#undef SBE_DEBUG
+#define SBE_DEBUG(args...) PK_TRACE(SBE_DEBUG_MRK"" args)
+#endif
+#define SBE_TRACE(args...) PK_TRACE(args)
+#endif // __SBEFW_SBE_TRACE_H
diff --git a/src/sbefw/sbeutil.H b/src/sbefw/sbeutil.H
new file mode 100644
index 00000000..07fc6b7f
--- /dev/null
+++ b/src/sbefw/sbeutil.H
@@ -0,0 +1,81 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbeutil.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 SBE_UTIL_H
+#define SBE_UTIL_H
+#include "pk.h"
+#include "pk_api.h"
+
+#define MASK_ZERO_L32B_UINT64(x) ((x) & 0xFFFFFFFF00000000)
+#define MASK_ZERO_H32B_UINT64(x) ((x) & 0x00000000FFFFFFFF)
+#define SHIFT_RIGHT(x, bits) ((x) >> bits)
+
+// Macros Defined for Internal RC Check, Break if Error
+#define CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc) \
+if ((l_rc) != SBE_SEC_OPERATION_SUCCESSFUL) \
+{ \
+ break; \
+} \
+
+void sbeHandleFifoResponse (const uint32_t i_rc);
+
+void sbeHandlePsuResponse (const uint32_t i_rc);
+
+namespace SBE
+{
+
+ // Currently PK does not define start range for app
+ // specifc panic code as enum. It is implicit understanding
+ // through code comments. Expectation is 0x1cxx range is for
+ // non-pk code.
+ static const uint32_t PK_APP_OFFSET_SBE_START = 0x1c00;
+ enum
+ {
+ // For defining new panic codes refer to pk/ppe42/pk_panic_codes.h
+ PANIC_ASSERT = PK_APP_OFFSET_SBE_START
+ };
+
+ /*@brief - Get higher 32bit number from uint64
+ *
+ * @param[in] - i_lWord - 64bit long word
+ *
+ * @return - uint32_t word
+ */
+ inline uint32_t higher32BWord(uint64_t i_lWord)
+ {
+ return (uint32_t)(SHIFT_RIGHT(MASK_ZERO_L32B_UINT64(i_lWord), 32));
+ }
+
+ /*@brief - Get lower 32bit number from uint64
+ *
+ * @param[in] - i_lWord - 64bit long word
+ *
+ * @return - uint32_t word
+ */
+ inline uint32_t lower32BWord(uint64_t i_lWord)
+ {
+ return (uint32_t)(MASK_ZERO_H32B_UINT64(i_lWord));
+ }
+
+} // namespace SBE
+#endif //SBE_UTIL_H
diff --git a/src/sbefw/vector b/src/sbefw/vector
new file mode 100644
index 00000000..5929f85f
--- /dev/null
+++ b/src/sbefw/vector
@@ -0,0 +1,397 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/vector $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 stl_vector
+#define stl_vector
+
+/**
+ * @file vector
+ * @brief simple stl vector template class declaration.
+ */
+
+#include <stddef.h>
+
+#if !defined( __STDC_LIMIT_MACROS)
+#define __STDC_LIMIT_MACROS
+#endif
+#include <stdint.h>
+#include <pool.H>
+#include <assert.h>
+#include <new>
+namespace std
+{
+
+ /**
+ * @class vector
+ * subset of stl vector
+ * @note Does not support allocators, reverse iterators.
+ */
+ template <class T>
+ class vector
+ {
+ public:
+
+ typedef T * iterator;
+ typedef const T * const_iterator;
+ typedef T & reference;
+ typedef const T & const_reference;
+ typedef size_t size_type;
+ typedef T value_type;
+ typedef T * pointer;
+ typedef const T * const_pointer;
+
+ protected:
+
+ pointer iv_start __attribute__ ((aligned (8)));
+ pointer iv_finish;
+ SBEVECTORPOOL::vectorMemPool_t *iv_poolPtr;
+ public:
+
+ /**
+ * Constructor default
+ * @post The vector is created with storage of
+ * G_BLOCKSIZE bytes.
+ */
+ explicit vector(void)
+ {
+ iv_poolPtr = SBEVECTORPOOL::allocMem();
+ assert ( NULL != iv_poolPtr)
+ iv_start = ( T* )iv_poolPtr->data;
+ iv_finish = iv_start;
+ }
+
+
+ /**
+ * MOVE COPY CTOR create a vector from another vector
+ * @param[in] x source vector
+ * @post Vector of x.size() is created from x with same
+ * memory.
+ * size() == capacity() == x.size()
+ * @note move Copy construtor willuse shallow copy. So input
+ * as well as output vector will point to same data
+ */
+ vector(const vector<T>&& x)
+ {
+ iv_start = x.iv_start;
+ iv_finish = x.iv_finish;
+ iv_poolPtr = x.iv_poolPtr;
+ iv_poolPtr->refCount++;
+ }
+
+ /**
+ * Reserve space for atleast n elements
+ * @param[in] n Number of elements
+ * @note We are having fixed size vectors in ppe. Defining
+ * this function to avoid compile issues in standard
+ * library. This function is noop for less than 512
+ * bytes requirement. For more than 512 bytes, it will
+ * assert.
+ */
+ void reserve(size_type n)
+ {
+ assert(n < max_size());
+ return;
+ }
+ /**
+ * DTOR
+ * @post Storage released
+ */
+ __attribute__ ((always_inline))
+ ~vector()
+ {
+ clear(); // call dtors
+ SBEVECTORPOOL::releaseMem(iv_poolPtr);
+ }
+
+ /**
+ * Move Assignment operator.
+ * @param[in] x A vector.
+ * @return A vector (for the purpose of multiple assigns).
+ * @pre None.
+ * @post *this == x, this->capacity() == x.size().
+ * All previously obtained iterators are invalid.
+ */
+ vector<T>& operator=(const vector<T>&& x)
+ {
+ // Just check here for pool to make sure
+ // input vector and current vector are not same;
+ if( iv_poolPtr != x.iv_poolPtr)
+ {
+ clear();
+ SBEVECTORPOOL::releaseMem(iv_poolPtr);
+ iv_start = x.iv_start;
+ iv_finish = x.iv_finish;
+ iv_poolPtr = x.iv_poolPtr;
+ iv_poolPtr->refCount++;
+ }
+ return(*this);
+ }
+
+ // Iterators --------------------
+
+ /**
+ * Get iterator to the first vector element
+ * @return iterator of rist vector element
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ iterator begin()
+ {
+ return (iv_start);
+ }
+
+ /**
+ * Get const_iterator to the first vector element
+ * @return const_iterator of rist vector element
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ const_iterator begin() const
+ {
+ return (iv_start);
+ }
+
+ /**
+ * Get iterator to the last vector element + 1
+ * @return iterator
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ iterator end()
+ {
+ return (iv_finish);
+ }
+
+ /**
+ * Get const_iterator to the last vector element + 1
+ * @return const_iterator
+ * @pre None.
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ const_iterator end() const
+ {
+ return (iv_finish);
+ }
+
+ // Capacity -----------------------------------------------
+
+ /**
+ * Get the number of elements in the container
+ * @return number of elements in the container
+ */
+ __attribute__ ((always_inline))
+ size_type size() const
+ {
+ return(iv_finish - iv_start);
+ }
+
+ /**
+ * Return the maximum potential size the container could reach.
+ * @return number of the maximum element count this container
+ * could reach
+ */
+ __attribute__ ((always_inline))
+ size_type max_size() const
+ {
+ return SBEVECTORPOOL::G_BLOCKSIZE/(sizeof(T));
+ }
+
+ /**
+ * Query for empty container
+ * @return bool, true if size()==0 else false.
+ * @pre none
+ * @post none
+ */
+ __attribute__ ((always_inline))
+ bool empty() const
+ {
+ return(size() == 0);
+ }
+
+ // - Element Access -----------------------------------
+
+ /**
+ * Access a mutable reference to an element in the container
+ * @param An index into the vector
+ * @return A reference to an element
+ * @pre 0 <= n < size()
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ reference operator[](size_type n)
+ {
+ assert(n < size());
+ return(*(iv_start + n));
+ }
+
+ /**
+ * Access a mutable reference to an element in the container
+ * @param[in] index An index into the vector
+ * @return A reference to an element
+ * @pre 0 <= n < size()
+ * @post None.
+ * @note no exception handling
+ */
+ __attribute__ ((always_inline))
+ reference at(size_type index)
+ {
+ assert(index < size());
+ return(*(iv_start + index));
+ }
+
+ /**
+ * Get an immutable reference to an element in the container
+ * @param[in] index An index into the vector
+ * @return A const_reference to an object or type T
+ * @pre 0 <= n < size()
+ * @post None.
+ */
+ __attribute__ ((always_inline))
+ const_reference operator[](size_type index) const
+ {
+ assert(index < size());
+ return(*(iv_start + index));
+ }
+
+ /**
+ * Get an immutable reference to an element in the container
+ * @param[in] index An index into the vector
+ * @return A const_reference to an object or type T
+ * @pre 0 <= n < size()
+ * @post None.
+ * @note no exception handling
+ */
+ __attribute__ ((always_inline))
+ const_reference at(size_type index) const
+ {
+ assert(index < size());
+ return(*(iv_start + index));
+ }
+
+ /**
+ * Get a mutable reference to the first element in the container
+ * @return reference to first element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ reference front()
+ {
+ return *iv_start;
+ }
+
+ /**
+ * Get an Immutable reference to the first element in the
+ * container
+ * @return const_reference to first element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ const_reference front() const
+ {
+ return *iv_start;
+ }
+
+ /**
+ * Get a mutable reference to the last element in the container
+ * @return reference to last element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ reference back()
+ {
+ return *(iv_finish-1);
+ }
+
+ /**
+ * Get an Immutable reference to the last element in the
+ * container
+ * @return reference to last element
+ * @pre none
+ * @post None
+ */
+ __attribute__ ((always_inline))
+ const_reference back() const
+ {
+ return *(iv_finish-1);
+ }
+
+ /**
+ * Add element to the back of the container
+ * @param[in] x reference to object used to create new element
+ * @pre none
+ * @post All previously obtained iterators are invalid.
+ */
+ __attribute__ ((always_inline))
+ void push_back(const T& x)
+ {
+ assert(max_size() > size());
+ new (iv_finish++) T(x);
+ }
+
+ /**
+ * Clear the vector
+ * @pre none.
+ * @post size() = 0, All previously obtained iterators are
+ * invalid
+ * @note capacity unchanged
+ */
+ void clear ()
+ {
+ while(iv_finish != iv_start)
+ {
+ --iv_finish;
+ (iv_finish)->~T();
+ }
+ }
+
+ /*
+ * Assign new content to the vector object
+ * @param[in] n number of elements to assign
+ * @param[in] x reference to element to copy in
+ */
+ void assign ( size_type n, const T& x)
+ {
+ assert(n < max_size());
+ clear();
+ for ( ; n> 0; n--)
+ push_back( x);
+ }
+
+ private:
+ vector(const vector<T>& x);
+ vector<T>& operator=(const vector<T>& x);
+};
+
+}; // end namespace std
+
+
+#endif
+/* vim: set filetype=cpp : */
diff --git a/src/test/citest/autocitest b/src/test/citest/autocitest
new file mode 100755
index 00000000..088bb58b
--- /dev/null
+++ b/src/test/citest/autocitest
@@ -0,0 +1,96 @@
+#!/bin/bash
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/autocitest $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+################################################################################
+## Simics automation using run-fsp-it
+################################################################################
+
+## verbose is the default.
+VERBOSE=" --verbose"
+if [ "$1" = "--quiet" ] ; then
+ VERBOSE=""
+ shift
+fi
+
+##
+## set up
+##
+DRIVER="$1" ## backing tree
+export bb=$DRIVER ## simulate a workon
+
+export SHELL="/bin/bash" ## Needed to fool workon to launch a bash
+ ## shell, which autosim expects.
+NOWIN="--nowin" ## remote execution does not have a display
+
+## jenkins creates a new workspace for every compile.
+## sbetest-start.sh will verify this and then export WORKSPACE_DIR for us.
+SBXHOME=$SBEROOT
+
+if [ "$DRIVER" = "" ] ; then
+ echo "ERROR: you must specify a driver (backing tree) to run the tests with"
+ usage
+ exit 1
+fi
+
+## let's get set up
+cd $SANDBOXROOT
+
+echo "$0"
+echo "VERBOSE = $VERBOSE"
+echo "NOWIN = $NOWIN"
+echo "BACKING_TREE = $DRIVER"
+echo "SANDBOXRC = $SANDBOXRC"
+echo "SBXHOME = $SBXHOME"
+echo "AUTOSIM_FFDC_XML = $AUTOSIM_FFDC_XML"
+echo "current directory is " `pwd`
+
+
+timestamp=`date +'%H:%M:%S'`
+echo "$timestamp Starting SBE test..."
+
+# Check preconditions for run-fsp-it
+# This is just workaround. It is expected
+# that user already either have this file
+# or tokens have been taken by klog command.
+# This is just to make run-fsp-it work in user
+# sandbox
+if [ -z $RUNNING_UNDER_JENKINS ]
+then
+ mkdir -p ~/private
+ if [ ! -f ~/private/.p ]; then
+ echo "Creating p file"
+ touch ~/private/.p
+ fi
+
+ if [ ! -f ~/private/password ]; then
+ echo "Creating passwd file"
+ touch ~/private/password
+ echo "dummy" > ~/private/password
+ fi
+fi
+
+execute_in_sandbox "run-fsp-it $NOWIN --machine $MACHINE $SBE_TEST_XML" "ppc" || exit -1
+
+exit 0
+
diff --git a/src/test/citest/build-script b/src/test/citest/build-script
new file mode 100755
index 00000000..5ad6b1bd
--- /dev/null
+++ b/src/test/citest/build-script
@@ -0,0 +1,72 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/build-script $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+
+if [ -z $WORKSPACE ]; then
+ export WORKSPACE=`pwd`
+fi
+
+if [ -z $SBEROOT ]; then
+ source "$WORKSPACE/env.bash"
+fi
+
+source "$SBEROOT/src/test/citest/setup-env"
+
+# Check copyright.
+#check-copyright > copyright.log 2>&1 &
+#COPYRIGHT_PID=$!
+
+
+# Build .
+scl enable devtoolset-2 " bash -c \"make install\"" || exit -1
+
+# Create simics sandbox.
+create-sandbox > create-sandbox.log 2>&1 &
+CREATESANDBOX_PID=$!
+
+# Check sandbox create completion.
+wait $CREATESANDBOX_PID
+if [ $? -eq 0 ]; then
+ cat create-sandbox.log
+else
+ echo "----Sandbox creation failed."
+ cat create-sandbox.log
+ exit -1
+fi
+
+# Add SBE files to simics sandbox.
+populate-sandbox || exit -1
+
+sbetest-start.sh || exit -1
+
+# Check copyright completion.
+#wait $COPYRIGHT_PID
+#if [ $? -eq 0 ]; then
+# cat copyright.log
+#else
+# echo "----Copyright check failed."
+# cat copyright.log
+# exit -1
+#fi
+
diff --git a/src/test/citest/check-copyright b/src/test/citest/check-copyright
new file mode 100755
index 00000000..28db5512
--- /dev/null
+++ b/src/test/citest/check-copyright
@@ -0,0 +1,30 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/check-copyright $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+COPYRIGHT_CHECK=${SBEROOT}/src/test/citest/copyright-check.sh
+COMMIT_CHECK=${SBEROOT}/src/tools/hooks/verify-commit
+
+$COPYRIGHT_CHECK || exit -1
+$COMMIT_CHECK || exit -1
diff --git a/src/test/citest/copyright-check.sh b/src/test/citest/copyright-check.sh
new file mode 100755
index 00000000..3d7c5d54
--- /dev/null
+++ b/src/test/citest/copyright-check.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/copyright-check.sh $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+#
+# Front end to addCopyright - script to check for copyright block during
+# Gerrit checkin.
+#
+
+export WORKSPACE_DIR=`pwd`
+export ADDCOPYRIGHT=${WORKSPACE_DIR}/src/tools/hooks/addCopyright
+
+## run git show to get a list of checked in files
+CHECKINFILES=`git show --pretty=format: --name-only -n1 | tr '\n' ' '`
+## use git log to determine the year of the commit.
+## Since commits have their copyright updated at the time they are
+## committed, a commit might have a copyright date in its prolog of
+## last year. Set the DATE_OVERRIDE variable to the 'validate' to allow
+## slightly-old prologs (ie. ones corresponding to the date in the msg).
+export DATE_OVERRIDE=`git log -n1 --date=short | grep "Date" | sed "s/Date: *//" | sed "s/-.*//"`
+
+echo "========================================================================"
+
+echo " Checking Copyright blocks for checked-in files:"
+echo " $CHECKINFILES"
+echo
+$ADDCOPYRIGHT validate $CHECKINFILES --copyright-check
+
+if [ $? -eq 0 ]; then
+ echo "Copyright Check passed OK, $?"
+ exit 0
+else
+ echo "ERROR: $?"
+ exit 1
+fi
diff --git a/src/test/citest/create-sandbox b/src/test/citest/create-sandbox
new file mode 100755
index 00000000..b6a1e7e8
--- /dev/null
+++ b/src/test/citest/create-sandbox
@@ -0,0 +1,73 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/create-sandbox $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+
+echo "Creating ODE sandbox..."
+
+# Ensure backing build is accessible.
+if [ ! -d "$BACKING_BUILD" ];
+then
+ echo "Cannot access the backing build: $BACKING_BUILD"
+ exit -1
+fi
+
+# Delete existing sandbox if it exists.
+if [ -d "$SANDBOXBASE" ];
+then
+ echo "----Removing old sandbox."
+ mksb -undo -auto -rc $SANDBOXRC -dir $SANDBOXROOT -sb $SANDBOXNAME
+fi
+if [ -d "$SANDBOXBASE" ];
+then
+ rm -rf $SANDBOXBASE
+fi
+
+# Create sandbox.
+mksb -rc $SANDBOXRC -dir $SANDBOXROOT -back $BACKING_BUILD -sb $SANDBOXNAME \
+ -m ppc -auto || exit -1
+
+# workaround scripts expect $sb variable to be populated.
+export sb=$SANDBOXBASE/src
+
+execute_in_sandbox "ecc --inject ${SBE_IMG_OUT_LOC}/sbe_seeprom.bin --output ${SBE_IMG_OUT_LOC}/sbe_seeprom.bin.ecc --p8 " "ppc" || exit -1
+
+# Run presimsetup workarounds.
+echo "----Running presimsetup workarounds."
+if [ -f ${CITESTPATH}/etc/workarounds.presimsetup ];
+then
+ ${CITESTPATH}/etc/workarounds.presimsetup || exit -1
+fi
+
+# Run start_simics to populate simics directories.
+echo "----Setting up simics."
+execute_in_sandbox "start_simics -no_start -machine $MACHINE -batch_mode" \
+ "ppc" || exit -1
+
+# Run postsimsetup workarounds.
+echo "----Running postsimsetup workarounds."
+if [ -f ${CITESTPATH}/etc/workarounds.postsimsetup ];
+then
+ ${CITESTPATH}/etc/workarounds.postsimsetup || exit -1
+fi
+
diff --git a/src/test/citest/etc/patches/chip.act.patch b/src/test/citest/etc/patches/chip.act.patch
new file mode 100644
index 00000000..0b9cf0f0
--- /dev/null
+++ b/src/test/citest/etc/patches/chip.act.patch
@@ -0,0 +1,146 @@
+184,240c184
+< # ==========================================================================
+< # Actions for p9_adu_access and p9_adu_setup procedures
+< # ==========================================================================
+< #If a read/write is done to the ALTD_DATA Register set the ALTD_STATUS Register so things are as expected
+< CAUSE_EFFECT{
+< LABEL=[ADU Read or write to set ALTD_STATUS Register]
+< #If the data register is read
+< WATCH_READ=[REG(0x00090004)]
+< #If the data register is written
+< WATCH=[REG(0x00090004)]
+<
+< #Set the ALTD_STATUS Register so these bits are set:
+< #FBC_ALTD_BUSY = WAIT_CMD_ARBIT = WAIT_RESP = OVERRUN_ERR = AUTOINC_ERR = COMMAND_ERR = ADDRESS_ERR = COMMAND_HANG_ERR = DATA_HANG_ERR = PBINIT_MISSING = ECC_CE = ECC_UE = ECC_SUE = 0
+< EFFECT: TARGET=[REG(0x00090003)] OP=[BUF,AND] DATA=[LITERAL(64,001FDFFF FFFF1FFF)]
+< EFFECT: TARGET=[REG(0x00090003)] OP=[BUF,OR] DATA=[LITERAL(64,30000000 00000000)]
+< }
+<
+< #If a read/write is done to the ALTD_DATA Register and the Address only bit is not set then set the DATA_DONE bit to 1
+< CAUSE_EFFECT{
+< LABEL=[ADU Read or write to set ALTD_STATUS[DATA_DONE] bit]
+< #If the data register is read
+< WATCH_READ=[REG(0x00090004)]
+< #If the data register is written
+< WATCH=[REG(0x00090004)]
+< CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6]
+<
+< #Set the DATA_DONE bit
+< EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3]
+< }
+<
+< #If a read/write is done to the ALTD_DATA Register and the Data only bit is not set then set the ADDR_DONE bit to 1
+< CAUSE_EFFECT{
+< LABEL=[ADU Read or write to set ALTD_STATUS[ADDR_DONE] bit]
+< #If the data register is read
+< WATCH_READ=[REG(0x00090004)]
+< #If the data register is written
+< WATCH=[REG(0x00090004)]
+< CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7]
+<
+< #Set the ADDR_DONE bit
+< EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2]
+< }
+<
+< #If a read is done to the ALTD_CMD Register and it sets the lock set the ALTD_STATUS Register so the ALTD_STATUS_BUSY bit is set
+< CAUSE_EFFECT{
+< LABEL=[ADU Write to set ALTD_STATUS_BUSY]
+< WATCH=[REG(0x00090001)]
+< CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[11]
+<
+< #Set the ALTD_STATUS Register so the ALTD_STATUS_BUSY bit is set
+< EFFECT: TARGET=[REG(0x090003)] OP=[BIT,ON] BIT=[0]
+< }
+< #If a write is done to the ALD_CMD_REG to set the FBC_ALTD_START_OP bit it should turn FBC_ALTD_BUSY off
+< CAUSE_EFFECT{
+< LABEL=[ADU Write to ALTD_CMD_REG to unset set ALTD_STATUS FBC_ALTD_BUSY bit]
+< WATCH=[REG(0x00090001)]
+< CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2]
+---
+> ### ADU ACTIONS - READ WRITE RESET ###
+242,243c186,265
+< #Unset the ALTD_STATUS Register so the ALTD_STATUS_BUSY is unset
+< EFFECT: TARGET=[REG(0x090003)] OP=[BIT,OFF] BIT=[0]
+---
+> # Reset ALTD Status Reg
+> CAUSE_EFFECT {
+> LABEL=[RESET FSM ALTD Status Register]
+> WATCH=[REG(0x00090001)] # ALTD_Cmd_Reg
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[4] #Reset FSM bit
+> EFFECT: TARGET=[REG(0x00090003)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000000)]
+> }
+>
+> # ADU Transaction Complete Status - Busy Bit Low
+> CAUSE_EFFECT {
+> LABEL=[ALTD_BUSY Status Register Clear]
+> WATCH=[REG(0x00090003)] # ALTD_Status_Reg
+> CAUSE: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE
+> CAUSE: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[19] #AUTO INCR Mode OFF
+>
+> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,OFF] BIT=[0] #BUSY Bit low
+> }
+>
+> # Read without AutoIncr
+> CAUSE_EFFECT{
+> LABEL=[READ Mainstore without AutoIncr]
+> WATCH=[REG(0x00090001)] # ALTD_Cmd_Reg
+>
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2] #start ADU Operation
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[5] #READ ADU Operation
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6] #addr Only Type Command
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7] #data
+>
+> EFFECT: TARGET=[MODULE(readMainstore, 0x00090000)] OP=[MODULECALL] DATA=[REG(0x00090004)] # read the memory
+> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE
+> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE
+> }
+>
+> # Read with AutoIncr
+> CAUSE_EFFECT{
+> LABEL=[READ Mainstore with AutoIncr]
+> WATCH_READ=[REG(0x00090004)] # ALTD_Data_reg
+>
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2] #start ADU Operation
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[5] #READ ADU Operation
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6] #addr Only Type Command
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7] #data
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[19] #AutoInc bit on
+>
+> EFFECT: TARGET=[MODULE(readMainstore, 0x00090000)] OP=[MODULECALL] DATA=[REG(0x00090004)] # read the memory
+> EFFECT: TARGET=[REG(0x00090000)] OP=[INCREMENT,MASK] INCVAL=[8] MASK=[LITERAL(64,00000000 0000FFFF)] # incr addr reg by 8
+> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE
+> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE
+> }
+>
+> # Write without AutoIncr
+> CAUSE_EFFECT{
+> LABEL=[WRITE Mainstore without AutoIncr]
+> WATCH=[REG(0x00090001)] # ALTD_Cmd_Reg
+> WATCH=[REG(0x00090004)] # ALTD_Data_reg
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2] #start ADU Operation
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[5] #WRITE ADU Operation
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6] #addr Only Type Command
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7] #data
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[19] #AutoInc bit off
+> EFFECT: TARGET=[MODULE(writeMainstore, 0x00090000)] OP=[MODULECALL] DATA=[REG(0x00090004)] # write the memory
+> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE
+> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE
+> }
+>
+> # Write with AutoIncr
+> CAUSE_EFFECT{
+> LABEL=[WRITE Mainstore with AutoIncr]
+> WATCH=[REG(0x00090001)] # ALTD_Cmd_reg
+> WATCH=[REG(0x00090004)] # ALTD_Data_reg
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[2] #start ADU Operation
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[5] #WRITE ADU Operation
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[6] #addr Only Type Command
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,OFF] BIT=[7] #data
+> CAUSE: TARGET=[REG(0x00090001)] OP=[BIT,ON] BIT=[19] #AutoInc bit on
+> EFFECT: TARGET=[MODULE(writeMainstore, 0x00090000)] OP=[MODULECALL] DATA=[REG(0x00090004)] # write the memory
+> EFFECT: TARGET=[REG(0x00090000)] OP=[INCREMENT,MASK] INCVAL=[8] MASK=[LITERAL(64, 00000000 0000FFFF)] # incr addr reg by 8
+> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[2] #FBC_ALTD_ADDR_DONE
+> EFFECT: TARGET=[REG(0x00090003)] OP=[BIT,ON] BIT=[3] #FBC_ALTD_DATA_DONE
+265a288
+> EFFECT: TARGET=[MODULE(executeInstruction, MYCORE)] OP=[MODULECALL] DATA=[REG(MYCHIPLET, 0x00010A4F)]
diff --git a/src/test/citest/etc/patches/patchlist.txt b/src/test/citest/etc/patches/patchlist.txt
new file mode 100644
index 00000000..4fd0444a
--- /dev/null
+++ b/src/test/citest/etc/patches/patchlist.txt
@@ -0,0 +1,14 @@
+# Example Format
+#Brief description of the problem or reason for patch
+#-RTC: Task/Story used to remove this patch
+#-CQ: Defect/Req for checking the changes into fips910
+#-Files: list of files
+#-Coreq: list of associated changes, e.g. workarounds.presimsetup
+
+RTC: 144728
+Files : pervasive.act.patch. Currently SUET does not support FSIMBOX KW. Once
+ support is in, remove this patch.
+
+RTC: 128984
+Files: chip.act.patch. Added call for executeInstruction module call.
+ p9.inst.patch. Added P9 specific commands for ramming.
diff --git a/src/test/citest/etc/patches/pervasive.act.patch b/src/test/citest/etc/patches/pervasive.act.patch
new file mode 100644
index 00000000..5531bef6
--- /dev/null
+++ b/src/test/citest/etc/patches/pervasive.act.patch
@@ -0,0 +1,28 @@
+55c55
+< WATCH=[REG(0x00050018)]
+---
+> WATCH=[FSIMBOX(0x18)]
+57c57
+< CAUSE: TARGET=[REG(0x00050018)] OP=[BIT,OFF] BIT=[12]
+---
+> CAUSE: TARGET=[FSIMBOX(0x18)] OP=[BIT,OFF] BIT=[12]
+59c59
+< CAUSE: TARGET=[REG(0x00050018)] OP=[BIT,OFF] BIT=[0]
+---
+> CAUSE: TARGET=[FSIMBOX(0x18)] OP=[BIT,OFF] BIT=[0]
+67c67
+< WATCH=[REG(0x00050018)]
+---
+> WATCH=[FSIMBOX(0x18)]
+69c69
+< CAUSE: TARGET=[REG(0x00050018)] OP=[BIT,OFF] BIT=[4]
+---
+> CAUSE: TARGET=[FSIMBOX(0x18)] OP=[BIT,OFF] BIT=[4]
+78c78
+< WATCH=[REG(0x00050018)]
+---
+> WATCH=[FSIMBOX(0x18)]
+80c80
+< CAUSE: TARGET=[REG(0x00050018)] OP=[BIT,OFF] BIT=[4]
+---
+> CAUSE: TARGET=[FSIMBOX(0x18)] OP=[BIT,OFF] BIT=[4]
diff --git a/src/test/citest/etc/patches/powermgmt.act.patch b/src/test/citest/etc/patches/powermgmt.act.patch
new file mode 100644
index 00000000..efb03845
--- /dev/null
+++ b/src/test/citest/etc/patches/powermgmt.act.patch
@@ -0,0 +1,1057 @@
+43,112d42
+< ## Actions for Procedure - p9_pm_occ_control
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[PPC405 HALT]
+< WATCH=[REG(0x0006D006)]
+< CAUSE: TARGET=[REG(0x0006D006)] OP=[EQUALTO,BUF] DATA=[LITERAL(64, 02000000 00000000)]
+< #suet PPC405_UNHALT:tc1- EFFECT: TARGET=[REG(0x01010800)] OP=[BIT,OFF] BIT=[31]
+< EFFECT: TARGET=[REG(0x01010800)] OP=[BIT,ON] BIT=[31]
+< }
+<
+< ##
+< ## Actions for Procedure - p9_pm_occ_gpe_init
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[OCC GPE0 HALT]
+< WATCH=[REG(0x00060010)]
+< CAUSE: TARGET=[REG(0x00060010)] OP=[BIT,OFF] BIT=[1]
+< CAUSE: TARGET=[REG(0x00060010)] OP=[BIT,OFF] BIT=[2]
+< CAUSE: TARGET=[REG(0x00060010)] OP=[BIT,ON] BIT=[3]
+< #suet OCCGPE0_HALT_FAIL:tc1- EFFECT: TARGET=[REG(0x00060021)] OP=[BIT,OFF] BIT=[0]
+< EFFECT: TARGET=[REG(0x00060021)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[OCC GPE1 HALT]
+< WATCH=[REG(0x00062010)]
+< CAUSE: TARGET=[REG(0x00062010)] OP=[BIT,OFF] BIT=[1]
+< CAUSE: TARGET=[REG(0x00062010)] OP=[BIT,OFF] BIT=[2]
+< CAUSE: TARGET=[REG(0x00062010)] OP=[BIT,ON] BIT=[3]
+< #suet OCCGPE1_HALT_FAIL:tc1- EFFECT: TARGET=[REG(0x00062021)] OP=[BIT,OFF] BIT=[0]
+< EFFECT: TARGET=[REG(0x00062021)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Upon writing the PU_OCB_PIB_OCR[DBG_HALT} bit, set the OCCLFIR_PPC405_DBGSTOPACK_BIT.
+< CAUSE_EFFECT {
+< LABEL=[PPC405 SAFE_HALT]
+< WATCH=[REG(00x0006D002)]
+< CAUSE: TARGET=[REG(0x0006D002)] OP=[EQUALTO,BUF] DATA=[LITERAL(64, 00200000 00000000)]
+< EFFECT: TARGET=[REG(0x01010800)] OP=[BIT,ON] BIT=[31]
+< }
+<
+<
+< ##
+< ## Actions for Procedure - p9_pm_occ_gpe_init
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[OCC GPE0 HALT]
+< WATCH=[REG(0x00060010)]
+< CAUSE: TARGET=[REG(0x00060010)] OP=[BIT,OFF] BIT=[1]
+< CAUSE: TARGET=[REG(0x00060010)] OP=[BIT,OFF] BIT=[2]
+< CAUSE: TARGET=[REG(0x00060010)] OP=[BIT,ON] BIT=[3]
+< #suet OCCGPE0_HALT_FAIL:tc1- EFFECT: TARGET=[REG(0x00060021)] OP=[BIT,OFF] BIT=[0]
+< EFFECT: TARGET=[REG(0x00060021)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[OCC GPE1 HALT]
+< WATCH=[REG(0x00062010)]
+< CAUSE: TARGET=[REG(0x00062010)] OP=[BIT,OFF] BIT=[1]
+< CAUSE: TARGET=[REG(0x00062010)] OP=[BIT,OFF] BIT=[2]
+< CAUSE: TARGET=[REG(0x00062010)] OP=[BIT,ON] BIT=[3]
+< #suet OCCGPE1_HALT_FAIL:tc1- EFFECT: TARGET=[REG(0x00062021)] OP=[BIT,OFF] BIT=[0]
+< EFFECT: TARGET=[REG(0x00062021)] OP=[BIT,ON] BIT=[0]
+< }
+<
+<
+< ##
+134,409c64
+<
+< ## Core0 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x200F0110)]
+< CAUSE: TARGET=[REG(0x200F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x200F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x200F0110)]
+< EFFECT: TARGET=[REG(0x200F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x200F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x200F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x200F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core0 End
+<
+< ## Core1 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x210F0110)]
+< CAUSE: TARGET=[REG(0x210F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x210F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x210F0110)]
+< EFFECT: TARGET=[REG(0x210F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x210F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x210F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x210F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core1 End
+<
+< ## Core2 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x220F0110)]
+< CAUSE: TARGET=[REG(0x220F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x220F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x200F0110)]
+< EFFECT: TARGET=[REG(0x220F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x220F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x220F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x220F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core2 End
+<
+< ## Core3 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x230F0110)]
+< CAUSE: TARGET=[REG(0x230F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x230F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x230F0110)]
+< EFFECT: TARGET=[REG(0x230F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x230F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x230F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x230F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core3 End
+<
+< ## Core4 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x240F0110)]
+< CAUSE: TARGET=[REG(0x240F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x240F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x240F0110)]
+< EFFECT: TARGET=[REG(0x240F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x240F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x240F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x240F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core4 End
+<
+< ## Core5 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x250F0110)]
+< CAUSE: TARGET=[REG(0x250F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x250F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x250F0110)]
+< EFFECT: TARGET=[REG(0x250F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x250F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x250F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x250F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core5 End
+<
+< ## Core6 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x260F0110)]
+< CAUSE: TARGET=[REG(0x260F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x260F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x200F0110)]
+< EFFECT: TARGET=[REG(0x260F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x260F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x260F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x260F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core6 End
+<
+< ## Core7 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x270F0110)]
+< CAUSE: TARGET=[REG(0x270F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x270F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x270F0110)]
+< EFFECT: TARGET=[REG(0x270F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x270F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x270F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x270F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core7 End
+<
+< ## Core8 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x280F0110)]
+< CAUSE: TARGET=[REG(0x280F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x280F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x280F0110)]
+< EFFECT: TARGET=[REG(0x280F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x280F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x280F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x200F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core8 End
+<
+< ## Core9 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x290F0110)]
+< CAUSE: TARGET=[REG(0x290F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x290F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x290F0110)]
+< EFFECT: TARGET=[REG(0x290F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x290F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x290F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x290F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core9 End
+<
+< ## Core10 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x2A0F0110)]
+< CAUSE: TARGET=[REG(0x2A0F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x2A0F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x2A0F0110)]
+< EFFECT: TARGET=[REG(0x2A0F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2A0F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2A0F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2A0F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core10 End
+<
+< ## Core11 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x2B0F0110)]
+< CAUSE: TARGET=[REG(0x2B0F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x2B0F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x2B0F0110)]
+< EFFECT: TARGET=[REG(0x2B0F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2B0F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2B0F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2B0F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core11 End
+<
+< ## Core12 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x2C0F0110)]
+< CAUSE: TARGET=[REG(0x2C0F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x2C0F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x2C0F0110)]
+< EFFECT: TARGET=[REG(0x2C0F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2C0F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2C0F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2C0F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core12 End
+<
+< ## Core13 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x2D0F0110)]
+< CAUSE: TARGET=[REG(0x2D0F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x2D0F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x2D0F0110)]
+< EFFECT: TARGET=[REG(0x2D0F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2D0F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2D0F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2D0F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core13 End
+<
+< ## Core14 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x2E0F0110)]
+< CAUSE: TARGET=[REG(0x2E0F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x2E0F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x2E0F0110)]
+< EFFECT: TARGET=[REG(0x2E0F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2E0F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2E0F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2E0F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core14 End
+<
+< ## Core15 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x2F0F0110)]
+< CAUSE: TARGET=[REG(0x2F0F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x2F0F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x2F0F0110)]
+< EFFECT: TARGET=[REG(0x2F0F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2F0F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2F0F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x2F0F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core15 End
+<
+< ## Core16 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x300F0110)]
+< CAUSE: TARGET=[REG(0x300F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x300F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x300F0110)]
+< EFFECT: TARGET=[REG(0x300F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x300F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x300F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x300F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core16 End
+<
+< ## Core17 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x310F0110)]
+< CAUSE: TARGET=[REG(0x310F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x310F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x310F0110)]
+< EFFECT: TARGET=[REG(0x310F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x310F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x310F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x310F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core17 End
+<
+< ## Core18 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x320F0110)]
+< CAUSE: TARGET=[REG(0x320F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x320F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x320F0110)]
+< EFFECT: TARGET=[REG(0x320F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x320F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x320F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x320F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core18 End
+<
+< ## Core19 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x330F0110)]
+< CAUSE: TARGET=[REG(0x330F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x330F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x330F0110)]
+< EFFECT: TARGET=[REG(0x330F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x330F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x330F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x330F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core19 End
+<
+< ## Core20 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x340F0110)]
+< CAUSE: TARGET=[REG(0x340F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x340F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x340F0110)]
+< EFFECT: TARGET=[REG(0x340F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x340F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x340F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x340F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core20 End
+<
+< ## Core21 Start
+< CAUSE_EFFECT {
+---
+> CAUSE_EFFECT CHIPLETS ec {
+411,478c66,89
+< WATCH=[REG(0x350F0110)]
+< CAUSE: TARGET=[REG(0x350F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x350F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x350F0110)]
+< EFFECT: TARGET=[REG(0x350F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x350F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x350F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x350F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core21 End
+<
+< ## Core22 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x360F0110)]
+< CAUSE: TARGET=[REG(0x360F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x360F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x360F0110)]
+< EFFECT: TARGET=[REG(0x360F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x360F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x360F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x360F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core22 End
+<
+< ## Core23 Start
+< CAUSE_EFFECT {
+< LABEL=[SSH_SRC_WRITE]
+< WATCH=[REG(0x370F0110)]
+< CAUSE: TARGET=[REG(0x370F0110)] OP=[EQUALTO,BUF] DATA=[REG(0x370F0110)]
+< EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(0x370F0110)]
+< EFFECT: TARGET=[REG(0x370F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x370F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x370F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< EFFECT: TARGET=[REG(0x370F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+< }
+< ## Core23 End
+<
+< ##
+< # Actions for Procedure - p9_block_wakeup_intr
+< ##
+<
+< # Core Power Management Mode Register
+< CAUSE_EFFECT {
+< LABEL=[CPMMR Write OR of PPM Write Override]
+< WATCH=[REG(0x290F0108)]
+< CAUSE: TARGET=[REG(0x290F0108)] OP=[BIT,ON] BIT=[1]
+< EFFECT: TARGET=[REG(0x290F0106)] OP=[BIT,ON] BIT=[1]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[CPMMR Write CLEAR of PPM Write Override]
+< WATCH=[REG(0x290F0107)]
+< CAUSE: TARGET=[REG(0x290F0107)] OP=[BIT,ON] BIT=[1]
+< EFFECT: TARGET=[REG(0x290F0106)] OP=[BIT,OFF] BIT=[1]
+< }
+<
+< # General Power Management Mode Register
+< CAUSE_EFFECT {
+< LABEL=[GPMMR Write OR of Block Wakeup Events]
+< WATCH=[REG(0x290F0102)]
+< CAUSE: TARGET=[REG(0x290F0102)] OP=[BIT,ON] BIT=[6]
+< EFFECT: TARGET=[REG(0x290F0100)] OP=[BIT,ON] BIT=[6]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[GPMMR Write CLEAR of PPM Write Override]
+< WATCH=[REG(0x290F0101)]
+< CAUSE: TARGET=[REG(0x290F0101)] OP=[BIT,ON] BIT=[6]
+< EFFECT: TARGET=[REG(0x290F0100)] OP=[BIT,OFF] BIT=[6]
+---
+> WATCH=[REG(MYCHIPLET, 0x0F0110)]
+> CAUSE: TARGET=[REG(MYCHIPLET, 0x0F0110)] OP=[EQUALTO,BUF] DATA=[REG(MYCHIPLET, 0x0F0110)]
+> EFFECT: TARGET=[SSH(0x0)] OP=[EQUALTO,BUF] DATA=[REG(MYCHIPLET, 0x0F0110)]
+> EFFECT: TARGET=[REG(MYCHIPLET, 0x0F0111)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+> EFFECT: TARGET=[REG(MYCHIPLET, 0x0F0112)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+> EFFECT: TARGET=[REG(MYCHIPLET, 0x0F0113)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+> EFFECT: TARGET=[REG(MYCHIPLET, 0x0F0114)] OP=[EQUALTO,BUF] DATA=[SSH(0x0)]
+> }
+>
+> ## Action triggered when all threads are idle
+> # Used for istep 16 to have hostboot properly wake up on SBE-set PSU
+> # interrupt as well as to have p9_sbe_check_master_stop15.C properly
+> # execute in firmware simics.
+> # TODO: RTC 147787
+> CAUSE_EFFECT CHIPLETS ec {
+> LABEL=[Master Winkle LPCR]
+> WATCH=[IDLESTATE(MYCHIPLET,0x0)]
+> # look for stop15
+> CAUSE: TARGET=[IDLESTATE(MYCHIPLET,0x0)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,0F000000)] MASK=[LITERAL(32,FF000000)]
+> # Restore LPCR for wake-up options.
+> EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 0)] OP=[BIT,ON] BIT=[17]
+> EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 0)] OP=[BIT,ON] BIT=[49]
+> # Set required C_PPM_SSHOTR register required by procedure
+> EFFECT: TARGET=[REG(0x200F0113)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,8BB00000 FFFFFFFF)]
+514c125
+< ## Actions for p9_pm_ocb_init
+---
+> # Actions for Procedure - p9_hcd_core_poweron / p9_hcd_cache_poweron
+517,524c128,133
+< CAUSE_EFFECT {
+< LABEL=[Channel 0 linear stream]
+< WATCH=[REG(0x0006D013)]
+< WATCH=[REG(0x0006D012)]
+< CAUSE: TARGET=[REG(0x0006D013)] OP=[BIT,ON] BIT=[4]
+< CAUSE: TARGET=[REG(0x0006D012)] OP=[BIT,ON] BIT=[5]
+< EFFECT: TARGET=[REG(0x0006D011)] OP=[BIT,ON] BIT=[4]
+< EFFECT: TARGET=[REG(0x0006D011)] OP=[BIT,OFF] BIT=[5]
+---
+> CAUSE_EFFECT CHIPLETS ec cache {
+> LABEL=[Power on core/cache vdd pfet then fsm is idle and sense is enabled]
+> WATCH=[REG(MYCHIPLET, 0x0F011A)]
+> CAUSE: TARGET=[REG(MYCHIPLET, 0x0F011A)] OP=[BIT,ON] BIT=[0]
+> EFFECT: TARGET=[REG(MYCHIPLET, 0x0F0118)] OP=[BIT,ON] BIT=[42]
+> EFFECT: TARGET=[REG(MYCHIPLET, 0x0F011C)] OP=[BIT,ON] BIT=[0]
+527,1071c136
+< CAUSE_EFFECT {
+< LABEL=[Channel 1 linear stream]
+< WATCH=[REG(0x0006D033)]
+< WATCH=[REG(0x0006D032)]
+< CAUSE: TARGET=[REG(0x0006D033)] OP=[BIT,ON] BIT=[4]
+< CAUSE: TARGET=[REG(0x0006D032)] OP=[BIT,ON] BIT=[5]
+< EFFECT: TARGET=[REG(0x0006D031)] OP=[BIT,ON] BIT=[4]
+< EFFECT: TARGET=[REG(0x0006D031)] OP=[BIT,OFF] BIT=[5]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Channel 1 circular push interupt enable]
+< WATCH=[REG(0x0006D033)]
+< CAUSE: TARGET=[REG(0x0006D033)] OP=[BIT,ON] BIT=[3]
+< CAUSE: TARGET=[REG(0x0006D033)] OP=[BIT,ON] BIT=[4]
+< CAUSE: TARGET=[REG(0x0006D033)] OP=[BIT,ON] BIT=[5]
+< EFFECT: TARGET=[REG(0x0006D031)] OP=[BIT,ON] BIT=[3]
+< EFFECT: TARGET=[REG(0x0006D031)] OP=[BIT,ON] BIT=[4]
+< EFFECT: TARGET=[REG(0x0006D031)] OP=[BIT,ON] BIT=[5]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Channel 1 circular push interrupt disable]
+< WATCH=[REG(0x0006D033)]
+< WATCH=[REG(0x0006D032)]
+< CAUSE: TARGET=[REG(0x0006D032)] OP=[BIT,ON] BIT=[3]
+< CAUSE: TARGET=[REG(0x0006D033)] OP=[BIT,ON] BIT=[4]
+< CAUSE: TARGET=[REG(0x0006D033)] OP=[BIT,ON] BIT=[5]
+< EFFECT: TARGET=[REG(0x0006D031)] OP=[BIT,OFF] BIT=[3]
+< EFFECT: TARGET=[REG(0x0006D031)] OP=[BIT,ON] BIT=[4]
+< EFFECT: TARGET=[REG(0x0006D031)] OP=[BIT,ON] BIT=[5]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Channel 2 linear stream]
+< WATCH=[REG(0x0006D053)]
+< WATCH=[REG(0x0006D052)]
+< CAUSE: TARGET=[REG(0x0006D053)] OP=[BIT,ON] BIT=[4]
+< CAUSE: TARGET=[REG(0x0006D052)] OP=[BIT,ON] BIT=[5]
+< EFFECT: TARGET=[REG(0x0006D051)] OP=[BIT,ON] BIT=[4]
+< EFFECT: TARGET=[REG(0x0006D051)] OP=[BIT,OFF] BIT=[5]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Channel 3 linear stream]
+< WATCH=[REG(0x0006D073)]
+< WATCH=[REG(0x0006D072)]
+< CAUSE: TARGET=[REG(0x0006D073)] OP=[BIT,ON] BIT=[4]
+< CAUSE: TARGET=[REG(0x0006D072)] OP=[BIT,ON] BIT=[5]
+< EFFECT: TARGET=[REG(0x0006D071)] OP=[BIT,ON] BIT=[4]
+< EFFECT: TARGET=[REG(0x0006D071)] OP=[BIT,OFF] BIT=[5]
+< ## Actions for Procedure - p9_setup_evid
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[AVSBus Write data register 0B]
+< WATCH=[REG(0x0006C718)]
+< CAUSE: TARGET=[REG(0x0006C718)] OP=[BIT,ON] BIT=[1]
+< EFFECT: TARGET=[REG(0x0006C716)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[AVSBus Status register 0B]
+< WATCH_READ=[REG(0x0006C716)]
+< CAUSE: TARGET=[REG(0x0006C716)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x0006C716)] OP=[BIT,OFF] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[AVSBus Write data register 1B]
+< WATCH=[REG(0x0006C738)]
+< CAUSE: TARGET=[REG(0x0006C738)] OP=[BIT,ON] BIT=[1]
+< EFFECT: TARGET=[REG(0x0006C736)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[AVSBus Status register 1B]
+< WATCH_READ=[REG(0x0006C736)]
+< CAUSE: TARGET=[REG(0x0006C736)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x0006C736)] OP=[BIT,OFF] BIT=[0]
+< }
+<
+< ## Core 0 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x200F011A)]
+< CAUSE: TARGET=[REG(0x200F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x200F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x200F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 0 End
+< ## Core 1 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x210F011A)]
+< CAUSE: TARGET=[REG(0x210F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x210F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x210F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 1 End
+< ## Core 2 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x220F011A)]
+< CAUSE: TARGET=[REG(0x220F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x220F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x220F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 2 End
+< ## Core 3 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x230F011A)]
+< CAUSE: TARGET=[REG(0x230F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x230F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x230F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 3 End
+< ## Core 4 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x240F011A)]
+< CAUSE: TARGET=[REG(0x240F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x240F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x240F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 4 End
+< ## Core 5 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x250F011A)]
+< CAUSE: TARGET=[REG(0x250F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x250F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x250F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 5 End
+< ## Core 6 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x260F011A)]
+< CAUSE: TARGET=[REG(0x260F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x260F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x260F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 6 End
+< ## Core 7 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x270F011A)]
+< CAUSE: TARGET=[REG(0x270F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x270F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x270F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 7 End
+< ## Core 8 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x280F011A)]
+< CAUSE: TARGET=[REG(0x280F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x280F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x280F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 8 End
+< ## Core 9 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x290F011A)]
+< CAUSE: TARGET=[REG(0x290F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x290F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x290F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 9 End
+< ## Core 10 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x2a0F011A)]
+< CAUSE: TARGET=[REG(0x2a0F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x2a0F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x2a0F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 10 End
+< ## Core 11 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x2b0F011A)]
+< CAUSE: TARGET=[REG(0x2b0F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x2b0F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x2b0F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 11 End
+< ## Core 12 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x2c0F011A)]
+< CAUSE: TARGET=[REG(0x2c0F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x2c0F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x2c0F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 12 End
+< ## Core 13 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x2d0F011A)]
+< CAUSE: TARGET=[REG(0x2d0F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x2d0F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x2d0F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 13 End
+< ## Core 14 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x2e0F011A)]
+< CAUSE: TARGET=[REG(0x2e0F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x2e0F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x2e0F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 14 End
+< ## Core 15 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x2f0F011A)]
+< CAUSE: TARGET=[REG(0x2f0F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x2f0F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x2f0F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 15 End
+< ## Core 16 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x300F011A)]
+< CAUSE: TARGET=[REG(0x300F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x300F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x300F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 16 End
+< ## Core 17 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x310F011A)]
+< CAUSE: TARGET=[REG(0x310F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x310F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x310F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 17 End
+< ## Core 18 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x320F011A)]
+< CAUSE: TARGET=[REG(0x320F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x320F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x320F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 18 End
+< ## Core 19 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x330F011A)]
+< CAUSE: TARGET=[REG(0x330F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x330F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x330F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 19 End
+< ## Core 20 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x340F011A)]
+< CAUSE: TARGET=[REG(0x340F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x340F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x340F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 20 End
+< ## Core 21 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x350F011A)]
+< CAUSE: TARGET=[REG(0x350F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x350F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x350F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 21 End
+< ## Core 22 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x360F011A)]
+< CAUSE: TARGET=[REG(0x360F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x360F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x360F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 22 End
+< ## Core 23 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_core_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on core vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x370F011A)]
+< CAUSE: TARGET=[REG(0x370F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x370F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x370F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< # Core 23 End
+< ## EQ 0 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_cache_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x100F011A)]
+< CAUSE: TARGET=[REG(0x100F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x100F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x100F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vcs pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x100F011A)]
+< CAUSE: TARGET=[REG(0x100F011A)] OP=[BIT,ON] BIT=[2]
+< EFFECT: TARGET=[REG(0x100F0118)] OP=[BIT,ON] BIT=[50]
+< EFFECT: TARGET=[REG(0x100F011C)] OP=[BIT,ON] BIT=[2]
+< }
+<
+< ## EQ 0 End
+<
+< ## EQ 1 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_cache_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x110F011A)]
+< CAUSE: TARGET=[REG(0x110F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x110F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x110F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vcs pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x110F011A)]
+< CAUSE: TARGET=[REG(0x110F011A)] OP=[BIT,ON] BIT=[2]
+< EFFECT: TARGET=[REG(0x110F0118)] OP=[BIT,ON] BIT=[50]
+< EFFECT: TARGET=[REG(0x110F011C)] OP=[BIT,ON] BIT=[2]
+< }
+<
+< ## EQ 1 End
+<
+< ## EQ 2 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_cache_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x120F011A)]
+< CAUSE: TARGET=[REG(0x120F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x120F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x120F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vcs pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x120F011A)]
+< CAUSE: TARGET=[REG(0x120F011A)] OP=[BIT,ON] BIT=[2]
+< EFFECT: TARGET=[REG(0x120F0118)] OP=[BIT,ON] BIT=[50]
+< EFFECT: TARGET=[REG(0x120F011C)] OP=[BIT,ON] BIT=[2]
+< }
+<
+< ## EQ 2 End
+<
+< ## EQ 3 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_cache_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x130F011A)]
+< CAUSE: TARGET=[REG(0x130F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x130F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x130F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vcs pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x130F011A)]
+< CAUSE: TARGET=[REG(0x130F011A)] OP=[BIT,ON] BIT=[2]
+< EFFECT: TARGET=[REG(0x130F0118)] OP=[BIT,ON] BIT=[50]
+< EFFECT: TARGET=[REG(0x130F011C)] OP=[BIT,ON] BIT=[2]
+< }
+<
+< ## EQ 3 End
+<
+< ## EQ 4 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_cache_poweron
+< ##
+<
+< CAUSE_EFFECT {
+---
+> CAUSE_EFFECT CHIPLETS cache {
+1073,1084c138,141
+< WATCH=[REG(0x140F011A)]
+< CAUSE: TARGET=[REG(0x140F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x140F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x140F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vcs pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x140F011A)]
+< CAUSE: TARGET=[REG(0x140F011A)] OP=[BIT,ON] BIT=[2]
+< EFFECT: TARGET=[REG(0x140F0118)] OP=[BIT,ON] BIT=[50]
+< EFFECT: TARGET=[REG(0x140F011C)] OP=[BIT,ON] BIT=[2]
+---
+> WATCH=[REG(MYCHIPLET, 0x0F011A)]
+> CAUSE: TARGET=[REG(MYCHIPLET, 0x0F011A)] OP=[BIT,ON] BIT=[2]
+> EFFECT: TARGET=[REG(MYCHIPLET, 0x0F0118)] OP=[BIT,ON] BIT=[50]
+> EFFECT: TARGET=[REG(MYCHIPLET, 0x0F011C)] OP=[BIT,ON] BIT=[2]
+1087,1112d143
+< ## EQ 4 End
+<
+< ## EQ 5 Start
+<
+< ##
+< # Actions for Procedure - p9_hcd_cache_poweron
+< ##
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vdd pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x150F011A)]
+< CAUSE: TARGET=[REG(0x150F011A)] OP=[BIT,ON] BIT=[0]
+< EFFECT: TARGET=[REG(0x150F0118)] OP=[BIT,ON] BIT=[42]
+< EFFECT: TARGET=[REG(0x150F011C)] OP=[BIT,ON] BIT=[0]
+< }
+<
+< CAUSE_EFFECT {
+< LABEL=[Power on cache vcs pfet then fsm is idle and sense is enabled]
+< WATCH=[REG(0x150F011A)]
+< CAUSE: TARGET=[REG(0x150F011A)] OP=[BIT,ON] BIT=[2]
+< EFFECT: TARGET=[REG(0x150F0118)] OP=[BIT,ON] BIT=[50]
+< EFFECT: TARGET=[REG(0x150F011C)] OP=[BIT,ON] BIT=[2]
+< }
+<
+< ## EQ 5 End
+<
diff --git a/src/test/citest/etc/patches/standalone.simics.patch b/src/test/citest/etc/patches/standalone.simics.patch
new file mode 100644
index 00000000..bdc40fd8
--- /dev/null
+++ b/src/test/citest/etc/patches/standalone.simics.patch
@@ -0,0 +1,4 @@
+52c52
+< ($hb_masterproc).proc_chip.invoke parallel_store SCOM 0x5003A "00000000_00000000" 64
+---
+> ($hb_masterproc).proc_chip.invoke parallel_store SCOM 0x5003A "80000000_00000000" 64
diff --git a/src/test/citest/etc/workarounds.postsimsetup b/src/test/citest/etc/workarounds.postsimsetup
new file mode 100755
index 00000000..057c3b00
--- /dev/null
+++ b/src/test/citest/etc/workarounds.postsimsetup
@@ -0,0 +1,43 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/etc/workarounds.postsimsetup $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+## Workarounds that are run after start_simics is executed for the first time
+## to setup the sandbox
+##
+
+### Example applying a patch to cec-chip files
+#echo "+++ Updating something wonderful in a simics file"
+#mkdir -p $sb/simu/data/cec-chip/
+#cp $BACKING_BUILD/src/simu/data/cec-chip/base_cec_chip_file $sb/simu/data/cec-chip
+#patch -p0 $sb/simu/data/cec-chip/base_cec_chip_file $SBEROOT/src/build/citest/etc/patches/my_patch_File
+
+# NOTE: The below patch removes mailbox settings in standalone.simics (comes
+# from HB) that cause the SBE to run in plck mode. For our CI, we need the SBE
+# to be in istep mode. This patch is likely never going to be removed as long as
+# we need our CI to run in istep mode.
+echo "+++ Patching standalone.simics"
+mkdir -p $SANDBOXBASE/obj/ppc/simu/scripts/hbfw
+cp $BACKING_BUILD/obj/ppc/simu/scripts/hbfw/standalone.simics $SANDBOXBASE/obj/ppc/simu/scripts/hbfw
+patch -p0 $SANDBOXBASE/obj/ppc/simu/scripts/hbfw/standalone.simics $SBEROOT/src/test/citest/etc/patches/standalone.simics.patch
+
diff --git a/src/test/citest/etc/workarounds.presimsetup b/src/test/citest/etc/workarounds.presimsetup
new file mode 100755
index 00000000..638a1e84
--- /dev/null
+++ b/src/test/citest/etc/workarounds.presimsetup
@@ -0,0 +1,31 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/etc/workarounds.presimsetup $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+
+#### Examples ####
+#echo "+++ Some message about why you need to do this."
+#mkdir -p $sb/simu/data
+#egrep -v "WSALIAS DEFAULT FIPSLEVEL|WSALIAS DEFAULT SIMICSLEVEL" $BACKING_BUILD/src/simu/data/simicsInfo > $sb/simu/data/simicsInfo
+#echo "WSALIAS DEFAULT FIPSLEVEL env/gfwb/simics-4.2.0/simics-4.2.83/fips/fld36/fi120201a700.42" >> $sb/simu/data/simicsInfo
+#echo "WSALIAS DEFAULT SIMICSLEVEL env/vtechb/simics-4.2.0/simics-4.2.83/bin" >> $sb/simu/data/simicsInfo
diff --git a/src/test/citest/populate-sandbox b/src/test/citest/populate-sandbox
new file mode 100755
index 00000000..d28b0f76
--- /dev/null
+++ b/src/test/citest/populate-sandbox
@@ -0,0 +1,60 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/populate-sandbox $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+
+# Ensure sandbox exists (create-sandbox has been called).
+if [ -z $SANDBOXBASE ];
+then
+ echo "SANDBOXBASE variable uninitialized.."
+ exit -1
+fi
+
+if [ ! -d "$SANDBOXBASE" ];
+then
+ echo "Cannot find sandbox: $SANDBOXBASE"
+ exit -1
+fi
+
+# Create test directory.
+mkdir -p $SBETESTDIR || exit -1
+
+# Create test directory.
+mkdir -p $SBEFW_IMG_DIR || exit -1
+
+# Copy sbe binaries
+cp $SBEROOT/obj/*.bin $SBEFW_IMG_DIR/ || exit -1
+cp $SBEROOT/obj/simics.tar $SBEFW_DIR/ || exit -1
+# Compile sbe code in sandbox to copy binaries at right place
+echo "---Setup sandbox for sbe binaries."
+
+execute_in_sandbox "cd $SBEFW_DIR; mk -a" \
+ "ppc" || exit -1
+
+execute_in_sandbox "cd $SBEFW_DIR; mk install_all" \
+ "ppc" || exit -1
+
+
+# Copy test files.
+cp -r $SBEROOT/src/test/* $SBETESTDIR/ || exit -1
+
diff --git a/src/test/citest/sbetest-start.sh b/src/test/citest/sbetest-start.sh
new file mode 100755
index 00000000..f39ed84e
--- /dev/null
+++ b/src/test/citest/sbetest-start.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/sbetest-start.sh $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+if [ -z $SBE_CI_ENV_SETUP ];
+then
+ unset $SANDBOXBASE
+ unset $SANDBOXNAME
+ source "$SBEROOT/src/test/citest/setup-env"
+fi
+
+# Front end to autocitest - script to execute unit tests under simics.
+#
+## when jenkins runs it will create a workspace with the built code tree
+## and drop us into it.
+autocitest ${BACKING_BUILD}
+
+exit $?
diff --git a/src/test/citest/setup-env b/src/test/citest/setup-env
new file mode 100755
index 00000000..ee0bc18b
--- /dev/null
+++ b/src/test/citest/setup-env
@@ -0,0 +1,84 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/citest/setup-env $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+
+export CITESTPATH=${SBEROOT}/src/test/citest
+export PATH=${CITESTPATH}:${PATH}
+
+# If we are running under Jenkins we need to pick a random-ish sandbox name
+# so that the autoipl tools do not have a /tmp name collision.
+if [ -z $JOB_NAME -o -z $BUILD_NUMBER ];
+then
+ SBECI_SANDBOX="test_sb"
+else
+ export RUNNING_UNDER_JENKINS=1
+ SBECI_SANDBOX=`echo $JOB_NAME $BUILD_NUMBER | md5sum | head -c10`
+fi
+
+# Setup sandbox location variables.
+if [ -z $SANDBOXROOT ];
+then
+ export SANDBOXROOT=${SBEROOT}
+fi
+
+if [ -z $SANDBOXNAME ] || [ "$RUNNING_UNDER_JENKINS" = "1" ];
+then
+ export SANDBOXNAME=${SBECI_SANDBOX}
+fi
+
+export SANDBOXBASE=${SANDBOXROOT}/${SANDBOXNAME}
+
+if [ -z $SANDBOXRC ];
+then
+ export SANDBOXRC=${SANDBOXROOT}/sbesandboxrc
+fi
+# Useful utility function.
+execute_in_sandbox()
+{
+ WORKON_CMD="workon -rc ${SANDBOXRC} -sb ${SANDBOXNAME} -m $2 "
+ echo $1 > ${SANDBOXBASE}/src/sandbox_execute_cmd
+ chmod 700 ${SANDBOXBASE}/src/sandbox_execute_cmd
+
+ TEST="${WORKON_CMD} -c ./sandbox_execute_cmd "
+ echo $TEST
+ ${WORKON_CMD} -c ./sandbox_execute_cmd
+
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ rm ${SANDBOXBASE}/src/sandbox_execute_cmd
+}
+export -f execute_in_sandbox
+
+# Setup machine type.
+export MACHINE=${MACHINE:-$DEFAULT_MACHINE}
+
+export SBETESTDIR=$SANDBOXBASE/simics/targets/p9_nimbus/sbeTest
+export SBEFW_DIR=$SANDBOXBASE/src/sbei/sbfw/
+export SBEFW_IMG_DIR=$SANDBOXBASE/src/sbei/sbfw/img
+export AUTOSIM_FFDC_XML=$SBETESTDIR/ffdc.xml
+export SBE_TEST_XML=$SBETESTDIR/test.xml
+# Indicate we setup the CI environment.
+export SBE_CI_ENV_SETUP=1
diff --git a/src/test/ffdc.xml b/src/test/ffdc.xml
new file mode 100755
index 00000000..65364249
--- /dev/null
+++ b/src/test/ffdc.xml
@@ -0,0 +1,41 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/ffdc.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+ <!--Collect FFDC -->
+ <test>
+ <subtest>
+ <testcase>
+ <simcmd>sbe-trace 0</simcmd>
+ </testcase>
+ <testcase>
+ <simcmd>p9Proc0.sbe.ppe->ppe_state</simcmd>
+ </testcase>
+ <testcase>
+ <simcmd>p9Proc0.proc_fifo->upstream_hw_fifo</simcmd>
+ </testcase>
+ <testcase>
+ <simcmd>p9Proc0.proc_fifo->downstream_hw_fifo</simcmd>
+ </testcase>
+ </subtest>
+ </test>
diff --git a/src/test/test.xml b/src/test/test.xml
new file mode 100755
index 00000000..2172b8f6
--- /dev/null
+++ b/src/test/test.xml
@@ -0,0 +1,49 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/test.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+
+<integrationtest>
+ <platform startsimargs="--notar --norun --sim_parms -nre">
+ <machine>%%machine%%</machine>
+ <test>
+ <testcase>
+ <simcmd>p9Proc0.pib_psu->tppsu_tpbr_interrupt_msg_available=[NIL]</simcmd>
+ </testcase>
+ <include>../simics/targets/p9_nimbus/sbeTest/testIstep.xml</include>
+ <include>../simics/targets/p9_nimbus/sbeTest/testScom.xml</include>
+ <include>../simics/targets/p9_nimbus/sbeTest/testGeneric.xml</include>
+ <!-- TODO via 158768: Enable pba test case-->
+ <!-- include>../simics/targets/p9_nimbus/sbeTest/testPutGetMem.xml</include -->
+ <include>../simics/targets/p9_nimbus/sbeTest/testSram.xml</include>
+ <include>../simics/targets/p9_nimbus/sbeTest/testCntlInstruction.xml</include>
+ <include>../simics/targets/p9_nimbus/sbeTest/testRegAccess.xml</include>
+ <include>../simics/targets/p9_nimbus/sbeTest/testFifoReset.xml</include>
+ <include>../simics/targets/p9_nimbus/sbeTest/testAduMem.xml</include>
+ <include>../simics/targets/p9_nimbus/sbeTest/testExecutorPutRing.xml</include>
+ <include>../simics/targets/p9_nimbus/sbeTest/testGetRing.xml</include>
+ <testcase>
+ <simcmd>sbe-trace 0</simcmd>
+ </testcase>
+ </test>
+ </platform>
+</integrationtest>
diff --git a/src/test/testAbort.py b/src/test/testAbort.py
new file mode 100755
index 00000000..7039c70b
--- /dev/null
+++ b/src/test/testAbort.py
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testAbort.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+TESTDATA = [0,0,0,2,
+ 0,0,0xA8,0x04 ]
+
+EXPDATA = [0xc0,0xde,0xa8,0x04,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x3];
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testAduMem.xml b/src/test/testAduMem.xml
new file mode 100644
index 00000000..1fcbe12d
--- /dev/null
+++ b/src/test/testAduMem.xml
@@ -0,0 +1,42 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testAduMem.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testAduMem_ecc.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testAduMem_itag.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testAduMem_withEccItag.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testAduMem_noEccNoItag.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+
diff --git a/src/test/testAduMem_ecc.py b/src/test/testAduMem_ecc.py
new file mode 100644
index 00000000..f60af64e
--- /dev/null
+++ b/src/test/testAduMem_ecc.py
@@ -0,0 +1,68 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testAduMem_ecc.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+LOOP_COUNT = 1
+
+GETMEMADU_TESTDATA_ECC = [0,0,0,0x6,
+ 0,0,0xA4,0x01,
+ 0,0,0x0,0xAD, #CoreChipletId/EccByte/Flags - CacheInhibit/FastMode/NoTag/Ecc/AutoIncr/Adu/Proc
+ 0,0,0,0, # Addr Upper 32 bit
+ 0x08,0x00,0x00,0x00, # Addr Lower 32 bit
+ 0x00,0x00,0x00,0x20] # length of data
+
+GETMEMADU_EXPDATA_ECC = [0x00,0x00,0x00,0x24, # length of data
+ 0xc0,0xde,0xa4,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ # GetMemAdu with Ecc
+ testUtil.writeUsFifo( GETMEMADU_TESTDATA_ECC)
+ testUtil.writeEot( )
+
+ testUtil.readDsEntry ( 9 )
+ testUtil.readDsFifo( GETMEMADU_EXPDATA_ECC)
+ testUtil.runCycles( 10000000 )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testAduMem_itag.py b/src/test/testAduMem_itag.py
new file mode 100644
index 00000000..8c7d9a3c
--- /dev/null
+++ b/src/test/testAduMem_itag.py
@@ -0,0 +1,66 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testAduMem_itag.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+GETMEMADU_TESTDATA_ITAG = [0,0,0,0x6,
+ 0,0,0xA4,0x01,
+ 0,0,0x0,0xB5, #CoreChipletId/EccByte/Flags -> CacheInhibit/FastMode/Tag/NoEcc/AutoIncr/Adu/Proc
+ 0,0,0,0, # Addr Upper 32 bit
+ 0x08,0x00,0x00,0x00, # Addr Lower 32 bit
+ 0x00,0x00,0x00,0x40] # length of data
+
+GETMEMADU_EXPDATA_ITAG = [0x00,0x00,0x00,0x48, # length of data
+ 0xc0,0xde,0xa4,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ # GetMemAdu with Itag
+ testUtil.writeUsFifo( GETMEMADU_TESTDATA_ITAG )
+ testUtil.writeEot( )
+
+ testUtil.readDsEntry ( 18 )
+ testUtil.readDsFifo( GETMEMADU_EXPDATA_ITAG )
+ testUtil.runCycles( 10000000 )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testAduMem_noEccNoItag.py b/src/test/testAduMem_noEccNoItag.py
new file mode 100644
index 00000000..ccbad942
--- /dev/null
+++ b/src/test/testAduMem_noEccNoItag.py
@@ -0,0 +1,99 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testAduMem_noEccNoItag.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+LOOP_COUNT = 1
+
+PUTMEMADU_CNTLDATA = [0,0,0,0,
+ 0,0,0xA4,0x02,
+ 0,0,0x0,0xA5, #CoreChipletId/EccByte/Flags -> NoEccOverride/CacheInhibit/FastMode/NoTag/NoEcc/AutoIncr/Adu/Proc
+ 0,0,0,0, # Addr Upper 32 bit
+ 0x08,0x00,0x00,0x00, # Addr Lower 32 bit
+ 0x00,0x00,0x00,0x10] # length of data
+
+PUTMEMADU_TESTDATA = [0xab,0xcd,0xef,0x12,
+ 0xba,0xdc,0xfe,0x21,
+ 0x34,0x56,0x78,0x9a,
+ 0x43,0x65,0x87,0xa9]
+
+PUTMEMADU_EXPDATA = [0x00,0x00,0x00,0x10, # length of data
+ 0xc0,0xde,0xa4,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+
+
+GETMEMADU_TESTDATA = [0,0,0,0x6,
+ 0,0,0xA4,0x01,
+ 0,0,0x0,0xA5, #CoreChipletId/EccByte/Flags -> CacheInhibit/FastMode/NoTag/NoEcc/AutoIncr/Adu/Proc
+ 0,0,0,0, # Addr Upper 32 bit
+ 0x08,0x00,0x00,0x00, # Addr Lower 32 bit
+ 0x00,0x00,0x00,0x10] # length of data
+
+GETMEMADU_EXPDATA = [0xab,0xcd,0xef,0x12, #data
+ 0xba,0xdc,0xfe,0x21,
+ 0x34,0x56,0x78,0x9a,
+ 0x43,0x65,0x87,0xa9,
+ 0x00,0x00,0x00,0x10, # length of data
+ 0xc0,0xde,0xa4,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ #PutMemAdu Test
+ testUtil.writeUsFifo( PUTMEMADU_CNTLDATA )
+ testUtil.writeUsFifo( PUTMEMADU_TESTDATA )
+ testUtil.writeEot( )
+
+ testUtil.readDsFifo( PUTMEMADU_EXPDATA )
+ testUtil.readEot( )
+
+ # GetMemAdu test
+ testUtil.writeUsFifo( GETMEMADU_TESTDATA )
+ testUtil.writeEot( )
+
+ testUtil.readDsFifo( GETMEMADU_EXPDATA )
+ testUtil.runCycles( 10000000 )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testAduMem_withEccItag.py b/src/test/testAduMem_withEccItag.py
new file mode 100644
index 00000000..7db53813
--- /dev/null
+++ b/src/test/testAduMem_withEccItag.py
@@ -0,0 +1,66 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testAduMem_withEccItag.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+GETMEMADU_TESTDATA_ECC_ITAG = [0,0,0,0x6,
+ 0,0,0xA4,0x01,
+ 0,0,0x0,0xBD, #CoreChipletId/EccByte/Flags -> CacheInhibit/FastMode/Tag/Ecc/AutoIncr/Adu/Proc
+ 0,0,0,0, # Addr Upper 32 bit
+ 0x08,0x00,0x00,0x00, # Addr Lower 32 bit
+ 0x00,0x00,0x00,0x40] # length of data
+
+GETMEMADU_EXPDATA_ECC_ITAG = [0x00,0x00,0x00,0x50, # length of data
+ 0xc0,0xde,0xa4,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ # GetMemAdu with Ecc with Itag test
+ testUtil.writeUsFifo( GETMEMADU_TESTDATA_ECC_ITAG )
+ testUtil.writeEot( )
+
+ testUtil.readDsEntry ( 20 )
+ testUtil.readDsFifo( GETMEMADU_EXPDATA_ECC_ITAG )
+ testUtil.runCycles( 10000000 )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testAduMem_withEccWithItagReadWrite.py b/src/test/testAduMem_withEccWithItagReadWrite.py
new file mode 100644
index 00000000..95578979
--- /dev/null
+++ b/src/test/testAduMem_withEccWithItagReadWrite.py
@@ -0,0 +1,96 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testAduMem_withEccWithItagReadWrite.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+LOOP_COUNT = 1
+
+PUTMEMADU_CNTLDATA = [0,0,0,0,
+ 0,0,0xA4,0x02,
+ 0,0x07,0x0,0xBD, #CoreChipletId/EccByteTrue/Flags -> EccOverride/CacheInhibit/FastMode/Tag/EccOverride/AutoIncr/Adu/Proc
+ 0,0,0,0, # Addr Upper 32 bit
+ 0x08,0x00,0x00,0x00, # Addr Lower 32 bit
+ 0x00,0x00,0x00,0x08] # length of data
+
+PUTMEMADU_TESTDATA = [0xab,0xcd,0xef,0x12,
+ 0xba,0xdc,0xfe,0x21]
+
+PUTMEMADU_EXPDATA = [0x00,0x00,0x00,0x0a, # length of data
+ 0xc0,0xde,0xa4,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03]
+
+
+
+GETMEMADU_TESTDATA = [0,0,0,0x6,
+ 0,0,0xA4,0x01,
+ 0,0,0x0,0xBD, #CoreChipletId/EccByte/Flags -> CacheInhibit/FastMode/Tag/Ecc/AutoIncr/Adu/Proc
+ 0,0,0,0, # Addr Upper 32 bit
+ 0x08,0x00,0x00,0x00, # Addr Lower 32 bit
+ 0x00,0x00,0x00,0x08] # length of data
+
+GETMEMADU_EXPDATA = [0xab,0xcd,0xef,0x12, #data
+ 0xba,0xdc,0xfe,0x21,
+ 0x01,0x07,0,0, #First Byte is iTag / Second Byte is ECC
+ 0x00,0x00,0x00,0x0a, # length of data
+ 0xc0,0xde,0xa4,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ #PutMemAdu Test
+ testUtil.writeUsFifo( PUTMEMADU_CNTLDATA )
+ testUtil.writeUsFifo( PUTMEMADU_TESTDATA )
+ testUtil.writeEot( )
+
+ testUtil.readDsFifo( PUTMEMADU_EXPDATA )
+ testUtil.readEot( )
+
+ # GetMemAdu test
+ testUtil.writeUsFifo( GETMEMADU_TESTDATA )
+ testUtil.writeEot( )
+
+ testUtil.readDsFifo( GETMEMADU_EXPDATA )
+ testUtil.runCycles( 10000000 )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testCntlInstruction.py b/src/test/testCntlInstruction.py
new file mode 100644
index 00000000..125b1b67
--- /dev/null
+++ b/src/test/testCntlInstruction.py
@@ -0,0 +1,473 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testCntlInstruction.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+LOOP_COUNT = 1
+
+#Invalid Input
+INST_INVALID_TESTDATA = [0,0,0,3,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0xee]
+
+
+INST_INVALID_EXPDATA_ERR = [0xc0,0xde,0xa7,0x01,
+ 0x00,0x02,0x00,0x0A,
+ 0x00,0x00,0x00,0x03]
+
+# STOP Ins
+# core 0 thread 0 STOP WARN FLAG as true
+INST_STOP_0_0_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x01]
+
+# core 0 thread 1 STOP WARN FLAG as true
+INST_STOP_0_1_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x11]
+
+# core 0 thread 2 STOP WARN FLAG as true
+INST_STOP_0_2_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x21]
+
+# core 0 thread 3 STOP with WARN FLAG as true
+INST_STOP_0_3_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x31]
+
+# core 0 thread 0 STOP WARN FLAG as false
+INST_STOP_0_0_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x01]
+
+# core 0 thread 1 STOP WARN FLAG as false
+INST_STOP_0_1_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x11]
+
+# core 0 thread 2 STOP WARN FLAG as false
+INST_STOP_0_2_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x21]
+
+# core 0 thread 3 STOP WARN FLAG as false
+INST_STOP_0_3_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x31]
+
+# Stop All thread in Core0 with warn flag true
+INST_STOP0_ALL_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0xf1]
+
+# Stop All thread in Core0 with warn flag false
+INST_STOP0_ALL_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0xf1]
+
+
+# START Ins
+# core 0 thread 0 START WARN FLAG as true
+INST_START_0_0_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x00]
+
+# core 0 thread 1 START WARN FLAG as true
+INST_START_0_1_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x10]
+
+# core 0 thread 2 START WARN FLAG as true
+INST_START_0_2_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x20]
+
+# core 0 thread 3 START with WARN FLAG as true
+INST_START_0_3_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x30]
+
+# core 0 thread 0 START WARN FLAG as false
+INST_START_0_0_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x00]
+
+# core 0 thread 1 START WARN FLAG as false
+INST_START_0_1_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x10]
+
+# core 0 thread 2 START WARN FLAG as false
+INST_START_0_2_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x20]
+
+# core 0 thread 3 START WARN FLAG as false
+INST_START_0_3_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x30]
+
+# Start All thread in Core0 with warn flag true
+INST_START0_ALL_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0xf0]
+
+# Start All thread in Core0 with warn flag false
+INST_START0_ALL_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0xf0]
+
+# STEP Ins
+# core 0 thread 0 STEP WARN FLAG as true
+INST_STEP_0_0_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x02]
+
+# core 0 thread 1 STEP WARN FLAG as true
+INST_STEP_0_1_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x12]
+
+# core 0 thread 2 STEP WARN FLAG as true
+INST_STEP_0_2_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x22]
+
+# core 0 thread 3 STEP with WARN FLAG as true
+INST_STEP_0_3_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x32]
+
+# core 0 thread 0 STEP WARN FLAG as false
+INST_STEP_0_0_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x02]
+
+# core 0 thread 1 STEP WARN FLAG as false
+INST_STEP_0_1_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x12]
+
+# core 0 thread 2 STEP WARN FLAG as false
+INST_STEP_0_2_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x22]
+
+# core 0 thread 3 STEP WARN FLAG as false
+INST_STEP_0_3_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x32]
+
+# Step All thread in Core0 with warn flag true
+INST_STEP0_ALL_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0xf2]
+
+# Step All thread in Core0 with warn flag false
+INST_STEP0_ALL_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0xf2]
+
+# SRESET Ins
+# core 0 thread 0 SRESET WARN FLAG as true
+INST_SRESET_0_0_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x03]
+
+# core 0 thread 1 SRESET WARN FLAG as true
+INST_SRESET_0_1_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x13]
+
+# core 0 thread 2 SRESET WARN FLAG as true
+INST_SRESET_0_2_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x23]
+
+# core 0 thread 3 SRESET with WARN FLAG as true
+INST_SRESET_0_3_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0x33]
+
+# core 0 thread 0 SRESET WARN FLAG as false
+INST_SRESET_0_0_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x03]
+
+# core 0 thread 1 SRESET WARN FLAG as false
+INST_SRESET_0_1_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x13]
+
+# core 0 thread 2 SRESET WARN FLAG as false
+INST_SRESET_0_2_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x23]
+
+# core 0 thread 3 SRESET WARN FLAG as false
+INST_SRESET_0_3_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0x33]
+
+# Sreset All thread in Core0 with warn flag true
+INST_SRESET0_ALL_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0xf3]
+
+# Sreset All thread in Core0 with warn flag false
+INST_SRESET0_ALL_TESTDATA_WITHOUT_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,0,0x20,0xf3]
+
+
+INST_EXPDATA = [0xc0,0xde,0xa7,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03]
+
+INST_EXPDATA_ERR = [0xc0,0xde,0xa7,0x01,
+ 0x00,0xFE,0x00,0x0A,
+ 0x00,0x00,0x00,0x03]
+
+STOP_INST_EXPDATA_ERR_WTH_FFDC = [0xc0,0xde,0xa7,0x01,
+ 0x00,0xFE,0x00,0x0A,
+ 0xFF,0xDC,0x00,0x02,
+ 0x00,0xCE,0xBC,0xB2,
+ 0x00,0x00,0x00,0x05]
+
+START_INST_EXPDATA_ERR_WTH_FFDC = [0xc0,0xde,0xa7,0x01,
+ 0x00,0xFE,0x00,0x0A,
+ 0xFF,0xDC,0x00,0x02,
+ 0x00,0x25,0x64,0xDB,
+ 0x00,0x00,0x00,0x05]
+
+STEP_INST_EXPDATA_ERR_WTH_FFDC = [0xc0,0xde,0xa7,0x01,
+ 0x00,0xFE,0x00,0x0A,
+ 0xFF,0xDC,0x00,0x02,
+ 0x00,0x0D,0x06,0x8E,
+ 0x00,0x00,0x00,0x05]
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ #Try an invalid data case
+ testUtil.writeUsFifo( INST_INVALID_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_INVALID_EXPDATA_ERR )
+ testUtil.readEot( )
+
+ # Control Instruction Message - Stop
+ testUtil.writeUsFifo( INST_STOP_0_0_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STOP_0_1_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STOP_0_2_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STOP_0_3_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STOP_0_0_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STOP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STOP_0_1_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STOP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STOP_0_2_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STOP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STOP_0_3_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STOP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+
+ #stop all thread in core0
+ testUtil.writeUsFifo( INST_STOP0_ALL_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STOP0_ALL_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STOP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+
+ # Control Instruction Message - Start
+ testUtil.writeUsFifo( INST_START_0_0_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_START_0_1_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_START_0_2_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_START_0_3_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+
+ testUtil.writeUsFifo( INST_START_0_0_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( START_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_START_0_1_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( START_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_START_0_2_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( START_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_START_0_3_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( START_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+
+ #start all thread in core0
+ testUtil.writeUsFifo( INST_START0_ALL_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_START0_ALL_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( START_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+
+ # Control Instruction Message - Step
+ testUtil.writeUsFifo( INST_STEP_0_0_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STEP_0_1_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STEP_0_2_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STEP_0_3_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STEP_0_0_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STEP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STEP_0_1_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STEP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STEP_0_2_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STEP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STEP_0_3_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STEP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+
+ #step all thread in core0
+ testUtil.writeUsFifo( INST_STEP0_ALL_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_STEP0_ALL_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( STEP_INST_EXPDATA_ERR_WTH_FFDC )
+ testUtil.readEot( )
+
+ # Control Instruction Message - Sreset
+ testUtil.writeUsFifo( INST_SRESET_0_0_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_SRESET_0_1_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_SRESET_0_2_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_SRESET_0_3_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_SRESET_0_0_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_SRESET_0_1_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_SRESET_0_2_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_SRESET_0_3_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+
+ #step all thread in core0
+ testUtil.writeUsFifo( INST_SRESET0_ALL_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( INST_SRESET0_ALL_TESTDATA_WITHOUT_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testCntlInstruction.xml b/src/test/testCntlInstruction.xml
new file mode 100755
index 00000000..07e22ee3
--- /dev/null
+++ b/src/test/testCntlInstruction.xml
@@ -0,0 +1,30 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testCntlInstruction.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testCntlInstruction.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+
diff --git a/src/test/testContinueMpipl.py b/src/test/testContinueMpipl.py
new file mode 100755
index 00000000..080e479a
--- /dev/null
+++ b/src/test/testContinueMpipl.py
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testContinueMpipl.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+TESTDATA = [0,0,0,2,
+ 0,0,0xA9,0x02 ]
+
+EXPDATA = [0xc0,0xde,0xa9,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x3];
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testContinueSbeBoot.py b/src/test/testContinueSbeBoot.py
new file mode 100755
index 00000000..5f64f0fa
--- /dev/null
+++ b/src/test/testContinueSbeBoot.py
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testContinueSbeBoot.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+TESTDATA = [0,0,0,2,
+ 0,0,0xA1,0x02 ]
+
+EXPDATA = [0xc0,0xde,0xa1,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x3];
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testEnterMpipl.py b/src/test/testEnterMpipl.py
new file mode 100755
index 00000000..8d225831
--- /dev/null
+++ b/src/test/testEnterMpipl.py
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testEnterMpipl.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+TESTDATA = [0,0,0,2,
+ 0,0,0xA9,0x01 ]
+
+EXPDATA = [0xc0,0xde,0xa9,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x3];
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testExecutorMemory.py b/src/test/testExecutorMemory.py
new file mode 100644
index 00000000..125528bf
--- /dev/null
+++ b/src/test/testExecutorMemory.py
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testExecutorMemory.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 testExecutor.py
+# @author: George Keishing <gkeishin@in.ibm.com>
+# @brief Framework to test Host SBE interface on simics
+#
+# Created on March 29, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 29/03/16 Initial create
+#############################################################
+'''
+
+import testClass as testObj
+import testRegistry as reg
+
+#-------------------------------
+# This is a Test Expected Data
+#-------------------------------
+'''
+This data are the values or strings that needs to be validated for the test.
+'''
+SBE_TEST_EXPECT_DEFAULT = "None"
+
+HOST_TEST_EXPECT_MAGIC = "00000000DEADBEEF"
+
+sbe_test_data = (
+ #-----------------------------------------------------------------------------------------------------
+ # OP Reg Mem Length (bytes) size Test Expected Data Description
+ #-----------------------------------------------------------------------------------------------------
+ #["memRead", reg.MEM_ADDR, 0xA00000, 8, HOST_TEST_EXPECT_MAGIC, "Reading data from the address"],
+ ["memRead", reg.MEM_ADDR, 0x50, 8, HOST_TEST_EXPECT_MAGIC, "Reading data from the address"],
+ )
+
+#-------------------------
+# Main Function
+#-------------------------
+def main():
+
+ # Intialize the class obj instances
+ print "\n Initializing Registry instances ...."
+ regObj = testObj.registry() # Registry obj def for operation
+
+ print "\n Execute SBE Test set [ Indirect Commands ] ...\n"
+ # Sim obj Target Test set
+ rc_test = regObj.ExecuteTestOp(testObj.simMemObj,sbe_test_data)
+ if rc_test != testObj.SUCCESS:
+ print " SBE Test data set .. [ FAILED ] .."
+ else:
+ print " SBE Test data set .. [ SUCCESS ] "
+ print "\n"
+
+if __name__=="__main__":
+ main()
+
diff --git a/src/test/testExecutorPSU.py b/src/test/testExecutorPSU.py
new file mode 100644
index 00000000..5c58a954
--- /dev/null
+++ b/src/test/testExecutorPSU.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testExecutorPSU.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 testExecutor.py
+# @author: George Keishing <gkeishin@in.ibm.com>
+# @brief Framework to test Host SBE interface on simics
+#
+# Created on March 29, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 29/03/16 Initial create
+#############################################################
+'''
+
+import testPSUUtil
+import testRegistry as reg
+
+#-------------------------------
+# This is a Test Expected Data
+#-------------------------------
+'''
+This data are the values or strings that needs to be validated for the test.
+'''
+SBE_TEST_EXPECT_DEFAULT = "None"
+
+HOST_TEST_EXPECT_DEFAULT = "None"
+HOST_TEST_EXPECT_MBOX04 = "0000000000F0D101"
+
+'''
+The test data is designed to accomodate as many as new entries a test needs
+and can also increase the field in it to add new action associated with it.
+'''
+#---------------------
+# SBE side test data
+#---------------------
+'''
+Every test data entry itself represent an action associated with it's data.
+The data is validated as it executes.
+
+The Test Expected Data if "None" signifies that this test entry is not to be
+validated else it would validated against the expected value in the field.
+On success returns macro SUCCESS else FAILURE
+
+Refer Documentation for the data used here directly.
+'''
+
+sbe_test_data = (
+ #-----------------------------------------------------------------------------------------------------
+ # OP Reg Value size Test Expected Data Description
+ #-----------------------------------------------------------------------------------------------------
+ ["write", reg.REG_MBOX0, "0000030100F0D101", 8, SBE_TEST_EXPECT_DEFAULT, "Writing to MBOX0 address"],
+ ["write", reg.REG_MBOX1, "0000000000001000", 8, SBE_TEST_EXPECT_DEFAULT, "Writing to MBOX1 address"],
+ ["write", reg.PSU_SBE_DOORBELL_REG_WO_OR, "8000000000000000", 8, SBE_TEST_EXPECT_DEFAULT, "Update SBE Doorbell register to interrupt SBE"],
+ )
+
+#---------------------
+# Host side test data
+#---------------------
+'''
+This Host data indicates that this will validate the SBE test set execution
+if the overall test is a success or failure.
+
+It can have as many entries which are needed to be validated.
+'''
+host_test_data = (
+ #----------------------------------------------------------------------------------------------------------------
+ # OP Reg Value size Test Expected Data Description
+ #----------------------------------------------------------------------------------------------------------------
+ ["read", reg.REG_MBOX4, "0000000000000000", 8, HOST_TEST_EXPECT_MBOX04, "Reading Host MBOX4 data to Validate"],
+ )
+
+'''
+User can define a function which does some task and returns SUCCESS or FAILURE.
+one can simply call that function like any OP in the test data and still work.
+
+Define those function in testClassUtil.py context for this to work.
+'''
+
+SAMPLE_TEST_EXPECT_FUNC = "None"
+PARM_DATA = [1, 2, 3, 4] # sample 4 input paramters
+sample_test_data = (
+ #----------------------------------------------------------------------------------------------------------------
+ # OP function Name Parameters NA Test Expected Data Description
+ #----------------------------------------------------------------------------------------------------------------
+ ["func", "classUtilFuncSample", PARM_DATA, 0, SAMPLE_TEST_EXPECT_FUNC, "Load func and do task"],
+ )
+
+#-------------------------
+# Main Function
+#-------------------------
+def main():
+
+ # Intialize the class obj instances
+ print "\n Initializing Registry instances ...."
+ regObj = testPSUUtil.registry() # Registry obj def for operation
+
+ print "\n Execute SBE Test set [ PSU ] ...\n"
+ # Sim obj Target Test set Raise Exception
+ rc_test = regObj.ExecuteTestOp(testPSUUtil.simSbeObj,sbe_test_data, True)
+ if rc_test != testPSUUtil.SUCCESS:
+ print " SBE Test data set .. [ Failed ] .."
+ else:
+ print " SBE Test data set .. [ OK ] "
+ print "\n Poll on Host side for INTR ...\n"
+ # Sim obj Target Test set Max timedout
+ rc_intr = regObj.pollingOn(testPSUUtil.simSbeObj,host_test_data,20)
+ if rc_intr == testPSUUtil.SUCCESS:
+ print " Interrupt Event Recieved .. Success !!"
+ else:
+ print " Interrupt not Recieved.. Exiting .."
+
+ print "\n"
+
+if __name__=="__main__":
+ main()
+
diff --git a/src/test/testExecutorPutRing.py b/src/test/testExecutorPutRing.py
new file mode 100644
index 00000000..d6c74bb8
--- /dev/null
+++ b/src/test/testExecutorPutRing.py
@@ -0,0 +1,225 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testExecutorPutRing.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import testPSUUtil
+import testRegistry as reg
+import testUtil
+
+#-------------------------------
+# This is a Test Expected Data
+#-------------------------------
+'''
+This data are the values or strings that needs to be validated for the test.
+'''
+'''
+#------------------------------------------------------------------------------------------------------------------------------
+# SBE side test data - Target - Pervasive(Core), Chiplet Id - 32, Ring ID - ec_func(224), mode - 0x0020(RING_MODE_HEADER_CHECK)
+#------------------------------------------------------------------------------------------------------------------------------
+'''
+sbe_test_data1 = (
+ #-----------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #-----------------------------------------------------------------------------------------------------
+ ["write", reg.REG_MBOX0, "0000010000F0D301", 8, "None", "Writing to MBOX0 address"],
+ ["write", reg.REG_MBOX1, "0002002000E00020", 8, "None", "Writing to MBOX1 address"],
+ ["write", reg.PSU_SBE_DOORBELL_REG_WO_OR, "8000000000000000", 8, "None", "Update SBE Doorbell register to interrupt SBE"],
+ )
+'''
+#------------------------------------------------------------------------------------------------------------------------------
+# SBE side test data - Target - Pervasive(Perv), Chiplet Id - 1, Ring ID - perv_fure(00), mode - 0x0020(RING_MODE_HEADER_CHECK)
+#------------------------------------------------------------------------------------------------------------------------------
+'''
+sbe_test_data2 = (
+ #--------------------------------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #--------------------------------------------------------------------------------------------------------------------------
+ ["write", reg.REG_MBOX0, "0000010000F0D301", 8, "None", "Writing to MBOX0 address"],
+ ["write", reg.REG_MBOX1, "0002000100000020", 8, "None", "Writing to MBOX1 address"],
+ ["write", reg.PSU_SBE_DOORBELL_REG_WO_OR, "8000000000000000", 8, "None", "Update SBE Doorbell register to interrupt SBE"],
+ )
+'''
+#---------------------
+# SBE side test data - Target - PROC CHIP, Chiplet Id - x, Ring ID - ob0_fure(118), mode - 0x0020(RING_MODE_HEADER_CHECK)
+#---------------------
+'''
+sbe_test_data3 = (
+ #--------------------------------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #--------------------------------------------------------------------------------------------------------------------------
+ ["write", reg.REG_MBOX0, "0000010000F0D301", 8, "None", "Writing to MBOX0 address"],
+ ["write", reg.REG_MBOX1, "0000000600760020", 8, "None", "Writing to MBOX1 address"],
+ ["write", reg.PSU_SBE_DOORBELL_REG_WO_OR, "8000000000000000", 8, "None", "Update SBE Doorbell register to interrupt SBE"],
+ )
+'''
+#------------------------------------------------------------------------------------------------------------------------------
+# SBE side test data - Target - EX, Chiplet Id - 32, Ring ID - ex_l3_fure(176), mode - 0x0020(RING_MODE_HEADER_CHECK)
+#------------------------------------------------------------------------------------------------------------------------------
+'''
+sbe_test_data4 = (
+ #-----------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #-----------------------------------------------------------------------------------------------------
+ ["write", reg.REG_MBOX0, "0000010000F0D301", 8, "None", "Writing to MBOX0 address"],
+ ["write", reg.REG_MBOX1, "0001002000B00020", 8, "None", "Writing to MBOX1 address"],
+ ["write", reg.PSU_SBE_DOORBELL_REG_WO_OR, "8000000000000000", 8, "None", "Update SBE Doorbell register to interrupt SBE"],
+ )
+'''
+#------------------------------------------------------------------------------------------------------------------------------
+# SBE side test data - Target - Invalid target 0x10, Chiplet Id - 32, Ring ID - ex_l3_refr_repr(248), mode - 0x0020(RING_MODE_HEADER_CHECK)
+#------------------------------------------------------------------------------------------------------------------------------
+'''
+sbe_test_data5 = (
+ #-----------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #-----------------------------------------------------------------------------------------------------
+ ["write", reg.REG_MBOX0, "0000010000F0D301", 8, "None", "Writing to MBOX0 address"],
+ ["write", reg.REG_MBOX1, "0010002000F80020", 8, "None", "Writing to MBOX1 address"],
+ ["write", reg.PSU_SBE_DOORBELL_REG_WO_OR, "8000000000000000", 8, "None", "Update SBE Doorbell register to interrupt SBE"],
+ )
+'''
+#---------------------
+# Host side test data - SUCCESS
+#---------------------
+'''
+host_test_data_success = (
+ #----------------------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #----------------------------------------------------------------------------------------------------------------
+ ["read", reg.REG_MBOX4, "0", 8, "0000000000F0D301", "Reading Host MBOX4 data to Validate"],
+ )
+'''
+#---------------------
+# Host side test data - FAILURE
+#---------------------
+'''
+host_test_data_failure5 = (
+ #----------------------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #----------------------------------------------------------------------------------------------------------------
+ ["read", reg.REG_MBOX4, "0", 8, "0002000400F0D301", "Reading Host MBOX4 data to Validate"],
+ )
+
+'''
+#-----------------------------------------------------------------------
+# Do not modify - Used to simulate interrupt on Ringing Doorbell on Host
+#-----------------------------------------------------------------------
+'''
+host_polling_data = (
+ #----------------------------------------------------------------------------------------------------------------
+ # OP Reg ValueToWrite size Test Expected Data Description
+ #----------------------------------------------------------------------------------------------------------------
+ ["read", reg.PSU_HOST_DOORBELL_REG_WO_OR, "0", 8, "8000000000000000", "Reading Host Doorbell for Interrupt"],
+ )
+
+#-------------------------
+# Main Function
+#-------------------------
+def main():
+ # Run Simics initially
+ testUtil.runCycles( 10000000 );
+
+ # Intialize the class obj instances
+ regObj = testPSUUtil.registry() # Registry obj def for operation
+
+ print "\n Execute SBE Test set1 [ Put Ring ] ...\n"
+
+ '''
+ Test Case 1
+ '''
+ # HOST->SBE data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, sbe_test_data1 )
+
+ print "\n Poll on Host side for INTR ...\n"
+ #Poll on HOST DoorBell Register for interrupt
+ regObj.pollingOn( testPSUUtil.simSbeObj, host_polling_data, 5 )
+
+ #SBE->HOST data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, host_test_data_success )
+
+ print "\n Execute SBE Test set2 [ Put Ring ] ...\n"
+ '''
+ Test Case 2
+ '''
+ # HOST->SBE data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, sbe_test_data2 )
+
+ print "\n Poll on Host side for INTR ...\n"
+ #Poll on HOST DoorBell Register for interrupt
+ regObj.pollingOn( testPSUUtil.simSbeObj, host_polling_data, 5 )
+
+ #SBE->HOST data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, host_test_data_success )
+
+ print "\n Execute SBE Test set3 [ Put Ring ] ...\n"
+ '''
+ Test Case 3
+ '''
+ # HOST->SBE data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, sbe_test_data3 )
+
+ print "\n Poll on Host side for INTR ...\n"
+ #Poll on HOST DoorBell Register for interrupt
+ regObj.pollingOn( testPSUUtil.simSbeObj, host_polling_data, 5 )
+
+ #SBE->HOST data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, host_test_data_success )
+
+ print "\n Execute SBE Test set4 [ Put Ring ] ...\n"
+ '''
+ Test Case 4
+ '''
+ # HOST->SBE data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, sbe_test_data4 )
+
+ print "\n Poll on Host side for INTR ...\n"
+ #Poll on HOST DoorBell Register for interrupt
+ regObj.pollingOn( testPSUUtil.simSbeObj, host_polling_data, 5 )
+
+ #SBE->HOST data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, host_test_data_success )
+
+ print "\n Execute SBE Test set5 [ Put Ring ] ...\n"
+ '''
+ Test Case 5
+ '''
+ # HOST->SBE data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, sbe_test_data5 )
+
+ print "\n Poll on Host side for INTR ...\n"
+ #Poll on HOST DoorBell Register for interrupt
+ regObj.pollingOn( testPSUUtil.simSbeObj, host_polling_data, 5 )
+
+ #SBE->HOST data set execution
+ regObj.ExecuteTestOp( testPSUUtil.simSbeObj, host_test_data_failure5 )
+
+if __name__ == "__main__":
+ main()
+ if err:
+ print ( "\nTest Suite completed with error(s)" )
+ #sys.exit(1)
+ else:
+ print ( "\nTest Suite completed with no errors" )
+ #sys.exit(0);
+
+
diff --git a/src/test/testExecutorPutRing.xml b/src/test/testExecutorPutRing.xml
new file mode 100755
index 00000000..56aabc0c
--- /dev/null
+++ b/src/test/testExecutorPutRing.xml
@@ -0,0 +1,30 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testExecutorPutRing.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testExecutorPutRing.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+
diff --git a/src/test/testFifoReset.py b/src/test/testFifoReset.py
new file mode 100644
index 00000000..3b03e6c6
--- /dev/null
+++ b/src/test/testFifoReset.py
@@ -0,0 +1,80 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testFifoReset.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest")
+import testUtil
+
+err = False
+
+# Test data that only contains the command header
+TESTDATA = [0, 0, 0, 3,
+ 0, 0, 0xA1, 0x01]
+
+# Complete test data
+TESTDATA_FULL = [0, 0, 0, 3,
+ 0, 0, 0xA1, 0x01,
+ 0, 0x02, 0x00, 0x01]
+
+# Get capabilities command. This will ensure the DS FIFO gets full
+TESTDATA_2 = [0, 0, 0, 2,
+ 0, 0, 0xA8, 0x02]
+
+def main():
+ try:
+ testUtil.runCycles(10000000)
+ # Send a partial chip-op
+ testUtil.writeUsFifo(TESTDATA)
+ testUtil.resetFifo()
+ # Make sure both the upstream and downstrem FIFOs are clear after the reset
+ testUtil.waitTillUsFifoEmpty()
+ testUtil.waitTillDsFifoEmpty()
+ # Now send a complete chip-op on the upstream FIFO
+ testUtil.writeUsFifo(TESTDATA_FULL)
+ testUtil.writeEot()
+ testUtil.resetFifo()
+ # Make sure both the upstream and downstrem FIFOs are clear after the reset
+ testUtil.waitTillUsFifoEmpty()
+ testUtil.waitTillDsFifoEmpty()
+ # Now send a get capabilities chip-op, so that in response, the DS FIFO
+ # gets full before we do a reset
+ testUtil.writeUsFifo(TESTDATA_2)
+ testUtil.writeEot()
+ testUtil.resetFifo()
+ # Make sure both the upstream and downstrem FIFOs are clear after the reset
+ testUtil.waitTillUsFifoEmpty()
+ testUtil.waitTillDsFifoEmpty()
+ except:
+ print("\nTest completed with error(s), Raise error")
+ raise
+ print("\nTest completed with no errors")
+
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testFifoReset.xml b/src/test/testFifoReset.xml
new file mode 100644
index 00000000..48b12a3e
--- /dev/null
+++ b/src/test/testFifoReset.xml
@@ -0,0 +1,35 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testFifoReset.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!-- SBE FIFO reset Test case -->
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testFifoReset.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <!-- An istep chip-op should succeed post the FIFO reset -->
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testIstepInvalidFenced.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
diff --git a/src/test/testGeneric.xml b/src/test/testGeneric.xml
new file mode 100755
index 00000000..cc49a78b
--- /dev/null
+++ b/src/test/testGeneric.xml
@@ -0,0 +1,30 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testGeneric.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!-- SBE Get Capabilities Test case -->
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testGetCapabilities.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
diff --git a/src/test/testGetCapabilities.py b/src/test/testGetCapabilities.py
new file mode 100755
index 00000000..e6831352
--- /dev/null
+++ b/src/test/testGetCapabilities.py
@@ -0,0 +1,82 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testGetCapabilities.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+TESTDATA = [0,0,0,2,
+ 0,0,0xA8,0x02 ]
+
+EXPDATA1 = [0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,
+ 0xa1,0x0,0x0,0x01, # istep
+ 0x0,0x0,0x0,0x0,
+ 0xa2,0x0,0x0,0x0f, #getscom/putscom/modifyscom/putscomundermask
+ 0x0,0x0,0x0,0x0,
+ 0xa3,0x0,0x0,0x1, #getring
+ 0x00,0x0,0x0,0x0];
+
+EXPDATA2 = [0xa4,0x0,0x0,0x0f, #GetMemPba/PutMemPba/GetSramOcc/PutSramOcc
+ 0x0,0x0,0x0,0x0,
+ 0xa5,0x0,0x0,0x03, #GetReg/PutReg
+ 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,
+ 0xa7,0x0,0x0,0x1, # control Instruction
+ 0x00,0x0,0x0,0x0];
+
+EXPDATA3 = [0xa8,0x0,0x0,0x02, #getcapability
+ 0x0,0x0,0x0,0x0,
+ 0xc0,0xde,0xa8,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x3];
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( TESTDATA )
+ testUtil.writeEot( )
+ # Ignore first two enteries ( major number, minor number
+ # and fw version) as they will keep on changing
+ testUtil.readDsEntry( 2 )
+ testUtil.readDsFifo( EXPDATA1 )
+ testUtil.readDsFifo( EXPDATA2 )
+ testUtil.readDsFifo( EXPDATA3 )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testGetMem.py b/src/test/testGetMem.py
new file mode 100644
index 00000000..a927f250
--- /dev/null
+++ b/src/test/testGetMem.py
@@ -0,0 +1,74 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testGetMem.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+LOOP_COUNT = 1
+
+GETMEM_TESTDATA = [0,0,0,0x6,
+ 0,0,0xA4,0x01,
+ 0,0,0x0,0x02,
+ 0,0,0,0,
+ 0x08,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x80] # length of data
+
+GETMEM_EXPDATA = [0x00,0x00,0x00,0x80, # length of data
+ 0xc0,0xde,0xa4,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ # GetMem test
+ testUtil.writeUsFifo( GETMEM_TESTDATA )
+ testUtil.writeEot( )
+ # GetMem chipOp would send the read data first,
+ # thus, would attempt to read the expected length of data first
+ loop = 1
+ while ( loop <= LOOP_COUNT ):
+ testUtil.readDsEntry ( 32 ) ## 32 entries ~ 128B PBA granule
+ loop += 1
+ testUtil.readDsFifo( GETMEM_EXPDATA )
+ testUtil.readEot( )
+
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testGetMem_expdata.py b/src/test/testGetMem_expdata.py
new file mode 100644
index 00000000..56b43119
--- /dev/null
+++ b/src/test/testGetMem_expdata.py
@@ -0,0 +1,83 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testGetMem_expdata.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+LOOP_COUNT = 4
+
+GETMEM_TESTDATA = [0,0,0,0x6,
+ 0,0,0xA4,0x01,
+ 0,0,0x0,0x02,
+ 0,0,0,0,
+ 0x08,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x80] # length of data
+
+GETMEM_EXP_RESPHDR = [0x00,0x00,0x00,0x80, # length of data
+ 0xc0,0xde,0xa4,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03]
+
+GETMEM_EXP_RESPDATA = [0xAB,0xCD,0xEF,0x01,
+ 0xAB,0xCD,0xEF,0x02,
+ 0xAB,0xCD,0xEF,0x03,
+ 0xAB,0xCD,0xEF,0x04,
+ 0xAB,0xCD,0xEF,0x05,
+ 0xAB,0xCD,0xEF,0x06,
+ 0xAB,0xCD,0xEF,0x07,
+ 0xAB,0xCD,0xEF,0x08]
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ # GetMem test
+ testUtil.writeUsFifo( GETMEM_TESTDATA )
+ testUtil.writeEot( )
+ # GetMem chipOp would send the read data first,
+ # thus, would attempt to read the expected length of data first
+ loop = 1
+ while ( loop <= LOOP_COUNT ):
+ testUtil.readDsFifo ( GETMEM_EXP_RESPDATA )
+ loop += 1
+ testUtil.readDsFifo( GETMEM_EXP_RESPHDR )
+ testUtil.readEot( )
+
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testGetRing.py b/src/test/testGetRing.py
new file mode 100644
index 00000000..d6d786b8
--- /dev/null
+++ b/src/test/testGetRing.py
@@ -0,0 +1,95 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testGetRing.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+LOOP_COUNT = 1
+
+#aligned Data
+GETRING_TESTDATA = [0,0,0,0x6,
+ 0,0,0xA3,0x01,
+ 0xa,0xa,0xa,0xa, # address
+ 0,0,0,0x40, # length of data
+ 0x00,0x00,0x00,0x01]
+
+GETRING_EXPDATA = [0,0,0,0, #data
+ 0,0,0,0, #data
+ 0,0,0,0x40, # length of data
+ 0xc0,0xde,0xa3,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+#Un-aligned Data
+GETRING_TESTDATA1 = [0,0,0,0x6,
+ 0,0,0xA3,0x01,
+ 0xa,0xa,0xa,0xa, # address
+ 0,0,0,0x45, # length of data
+ 0x00,0x00,0x00,0x01]
+
+GETRING_EXPDATA1 = [0,0,0,0, #data
+ 0,0,0,0, #data
+ 0,0,0,0, #data
+ 0,0,0,0, #data
+ 0,0,0,0x45, # length of data
+ 0xc0,0xde,0xa3,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ # GetRing test - Aligned Data
+ testUtil.writeUsFifo( GETRING_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETRING_EXPDATA )
+ testUtil.runCycles( 10000000 )
+ testUtil.readEot( )
+
+ # GetRing test - un-aligned Data
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( GETRING_TESTDATA1 )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETRING_EXPDATA1 )
+ testUtil.runCycles( 10000000 )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testGetRing.xml b/src/test/testGetRing.xml
new file mode 100755
index 00000000..a30802c2
--- /dev/null
+++ b/src/test/testGetRing.xml
@@ -0,0 +1,29 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testGetRing.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testGetRing.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+
diff --git a/src/test/testIstep.xml b/src/test/testIstep.xml
new file mode 100644
index 00000000..f0e71d61
--- /dev/null
+++ b/src/test/testIstep.xml
@@ -0,0 +1,332 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testIstep.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!-- Invalid Istep Test case -->
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testIstepInvalid.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <!-- Positive Istep Test case -->
+ <testcase>
+ <simcmd>sbe-istep 2 2</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 3</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 4</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 5</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 6</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 7</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 8</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 9</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 10</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 11</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 12</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 13</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 14</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 15</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 16</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 2 17</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 1</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 2</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 3</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 4</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 5</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 6</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 7</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 8</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 9</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 10</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 11</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 12</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 13</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 14</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 15</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 16</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 17</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 18</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 19</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 20</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 21</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 3 22</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 1</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 2</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 3</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 4</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 5</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 6</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 7</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 8</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 9</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 10</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 11</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 12</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 13</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 14</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 15</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 16</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 17</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 18</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 19</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 20</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 21</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 22</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 23</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 24</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 25</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 26</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 27</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 28</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 29</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 30</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 31</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 32</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 33</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 4 34</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 5 1</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>sbe-istep 5 2</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <!-- Invalid Istep Test case -->
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testIstepInvalidFenced.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
diff --git a/src/test/testIstepAuto.py b/src/test/testIstepAuto.py
new file mode 100755
index 00000000..8cbccffa
--- /dev/null
+++ b/src/test/testIstepAuto.py
@@ -0,0 +1,54 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testIstepAuto.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+from sim_commands import *
+import imp
+err = False
+testUtil = imp.load_source("testUtil", os.environ['SBE_TOOLS_PATH'] + "/testUtil.py")
+EXPDATA = [0xc0,0xde,0xa1,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def sbe_istep_func( major, minor ):
+ try:
+ TESTDATA = [0,0,0,3,
+ 0,0,0xA1,0x01,
+ 0,major,0,minor ]
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( EXPDATA )
+ testUtil.readEot( )
+ except:
+ print ("\nTest completed with error(s). Raise error")
+ # TODO via RTC 142706
+ # Currently simics commands created using hooks always return
+ # success. Need to check from simics command a way to return
+ # Calling non existant command to return failure
+ run_command("Command Failed");
+ raise
+ print ("\nTest completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testIstepInvalid.py b/src/test/testIstepInvalid.py
new file mode 100755
index 00000000..5af909d7
--- /dev/null
+++ b/src/test/testIstepInvalid.py
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testIstepInvalid.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+TESTDATA = [0,0,0,3,
+ 0,0,0xA1,0x01,
+ 0,0x02,0x00,0x1]
+
+EXPDATA = [0xc0,0xde,0xa1,0x01,
+ 0x00,0x02,0x00,0x0A,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( EXPDATA )
+ testUtil.readEot( )
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testIstepInvalidFenced.py b/src/test/testIstepInvalidFenced.py
new file mode 100755
index 00000000..568253af
--- /dev/null
+++ b/src/test/testIstepInvalidFenced.py
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testIstepInvalidFenced.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+TESTDATA = [0,0,0,3,
+ 0,0,0xA1,0x01,
+ 0,0x02,0x00,0x1]
+
+EXPDATA = [0xc0,0xde,0xa1,0x01,
+ 0x00,0x00,0x00,0x08,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( EXPDATA )
+ testUtil.readEot( )
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testIstepSuccess.py b/src/test/testIstepSuccess.py
new file mode 100755
index 00000000..83871896
--- /dev/null
+++ b/src/test/testIstepSuccess.py
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testIstepSuccess.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+TESTDATA = [0,0,0,3,
+ 0,0,0xA1,0x01,
+ 0,0x02,0x00,0x2]
+
+EXPDATA = [0xc0,0xde,0xa1,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( EXPDATA )
+ testUtil.readEot( )
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testModifyScom.py b/src/test/testModifyScom.py
new file mode 100755
index 00000000..703ad680
--- /dev/null
+++ b/src/test/testModifyScom.py
@@ -0,0 +1,97 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testModifyScom.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+
+PUTSCOM_TESTDATA = [0,0,0,6,
+ 0,0,0xA2,0x02,
+ 0,0,0x0,0x00,
+ 0,0x05,0x00,0x3E, #scratch reg 7 (32-bit)
+ 0x00,0xff,0x00,0xff,
+ 0x00,0x00,0x00,0x00 ]
+
+PUTSCOM_EXPDATA = [0xc0,0xde,0xa2,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+
+MODIFYSCOM_TESTDATA = [0,0,0,7,
+ 0,0,0xA2,0x03,
+ 0,0,0x0,0x01,
+ 0,0,0x0,0x00,
+ 0,0x05,0x00,0x3E,
+ 0xde,0x00,0xff,0x00,
+ 0x00,0x00,0x00,0x00]
+
+MODIFYSCOM_EXPDATA = [0xc0,0xde,0xa2,0x03,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+GETSCOM4MODIFYSCOM_TESTDATA = [0,0,0,4,
+ 0,0,0xA2,0x01,
+ 0,0,0x0,0x00,
+ 0,0x05,0x0,0x3E]
+
+GETSCOM4MODIFYSCOM_EXPDATA = [0xde,0xff,0xff,0xff,
+ 0x00,0x00,0x00,0x00,
+ 0xc0,0xde,0xa2,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ testUtil.writeUsFifo( PUTSCOM_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( PUTSCOM_EXPDATA )
+ testUtil.readEot( )
+
+ testUtil.writeUsFifo( MODIFYSCOM_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( MODIFYSCOM_EXPDATA )
+ testUtil.readEot( )
+
+ testUtil.writeUsFifo( GETSCOM4MODIFYSCOM_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETSCOM4MODIFYSCOM_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testPSUUserUtil.py b/src/test/testPSUUserUtil.py
new file mode 100644
index 00000000..df586ab7
--- /dev/null
+++ b/src/test/testPSUUserUtil.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPSUUserUtil.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 testClassUtil.py
+# @author: George Keishing <gkeishin@in.ibm.com>
+# @brief Framework utility fucntions for Host SBE
+# interface on simics
+#
+# Created on March 29, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 29/03/16 Initial create
+#############################################################
+'''
+
+import testPSUUtil
+
+'''
+Add your personalize functions here for execution but ensure it returns
+either SUCCESS or FAILURE as an end result for generalization purpose.
+'''
+
+##########################################################################
+# Function : classUtilFuncSample
+#
+# @param i_paramArray : user supplied input array parameters
+#
+# @brief Function to do a task and returns SUCCCES or FAILURE
+#
+##########################################################################
+def classUtilFuncSample(i_paramArray):
+ for input in i_paramArray:
+ print " classUtilFuncSample : parm: ",input
+ return testPSUUtil.SUCCESS
diff --git a/src/test/testPSUUtil.py b/src/test/testPSUUtil.py
new file mode 100644
index 00000000..84b91ff7
--- /dev/null
+++ b/src/test/testPSUUtil.py
@@ -0,0 +1,376 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPSUUtil.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 testClass.py
+# @author: George Keishing <gkeishin@in.ibm.com>
+# @brief Framework class Host SBE interface on simics
+#
+# Created on March 29, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 29/03/16 Initial create
+#############################################################
+'''
+
+#-------------------------
+# Imports packages
+#-------------------------
+import time
+import conf
+import testUtil
+import testPSUUserUtil
+from sim_commands import *
+
+#-------------------------
+# Macros constants
+#-------------------------
+SUCCESS = 1
+FAILURE = 0
+
+#-------------------------
+# SIM OBJs
+#-------------------------
+'''
+This is a simulator obj mapped. Refer simics folks if new objects are needed.
+'''
+simSbeObj = conf.p9Proc0.sbe.mibo_space
+simHostObj = conf.p9Proc0.p9_mem_map.host_xscom_device_mm
+simMemObj = conf.system_cmp0.phys_mem
+
+'''
+This is a base MBOX registry address from 0..7
+'''
+# Register MBOX 0..3 SBE side address in order
+REGDATA_SBE = [
+ 0x00680500,
+ 0x00680510,
+ 0x00680520,
+ 0x00680530
+ ]
+
+# Register MBOX 4..7 host side address in order
+REGDATA_HOST = [
+ 0x00680540,
+ 0x00680550,
+ 0x00680560,
+ 0x00680570
+ ]
+
+# Supporting Class objects
+'''
+Base function members definitions for set,get,read, write and others needed.
+Keep it simple and modular so that it can be extended as a base class.
+'''
+#------------------
+# Registry class
+#------------------
+class registry(object):
+ #------------------------------
+ # Set the reg data
+ #------------------------------
+ def setRegData(self, addr, value, size):
+ self.regAddr = addr
+ self.regVal = value
+ self.regSize = size
+
+ #------------------------------
+ # Read Reg value set or updated
+ #------------------------------
+ def getRegData(self):
+ print " Addr : ",hex(self.regAddr)
+ print " Value : ",self.regVal
+ print " Size : ",self.regSize
+
+ #------------------------------
+ # Write to a Registry
+ #------------------------------
+ def writeToReg(self, objType):
+ address = self.regAddr
+ value = self.stringToByte(self.regVal)
+ size = self.regSize
+ print " WData : 0x%s -> Byte Data %s"% (self.regVal,value)
+ print " Addr :", hex(address)
+ print " Size : %s Bytes"% size
+
+ self.__write(objType,address,value,size)
+ return
+
+ #------------------------------
+ # Write to Registry 0..3 using
+ # test data directly.
+ #------------------------------
+ def writeTestData(self, data):
+ simObj = SIM_get_interface(simSbeObj, "memory_space")
+ entryCount = len(data)
+ size = 8
+ for i in range (entryCount):
+ value = stringToByte(data[i])
+ print "\n Writting ", hex(REGDATA_SBE[i])
+ print " %x %x %x %x %x %x %x %x" % (value[0],value[1],value[2],value[3],value[4],value[5],value[6],value[7])
+ simObj.write(None, REGDATA_SBE[regIndex],
+ (value[0],value[1],value[2],value[3],value[4],value[5],value[6],value[7]),
+ size)
+ return
+
+ #------------------------------
+ # Write using SIM object
+ # 4/8 Bytes data
+ #------------------------------
+ def __write(self, Targetobj, address, value, size):
+ simObj = SIM_get_interface(Targetobj, "memory_space")
+ if int(size) == 4:
+ simObj.write(None, address,
+ (value[0],value[1],value[2],value[3]),
+ size)
+ elif int(size) == 8:
+ simObj.write(None, address,
+ (value[0],value[1],value[2],value[3],value[4],value[5],value[6],value[7]),
+ size)
+ print " SIM obj: Write %s bytes [ OK ] " % size
+ return
+
+ #---------------------------
+ # Read from a Registry
+ #---------------------------
+ def readFromReg(self, objType):
+ address = self.regAddr
+ size = self.regSize
+ value = self.regVal
+ if int(value) !=0:
+ print " RData :", value
+ print " Addr :", hex(address)
+ print " Size : %s Bytes"% size
+
+ value = self.__read(objType,address,size)
+ return value
+
+ #---------------------------
+ # Read from a memomry
+ # Max Sim interface can read 8
+ # byte data at a given time
+ #---------------------------
+ def readFromMemory(self, objType, magicNum):
+ # Start addr + 8 bytes
+ address = self.regAddr
+ size = self.regSize # Max it can read is 8 Bytes
+ value = self.regVal # Max lentgth it should read
+
+ MaxAddr = address + value # This is the addres range it could read
+ print " MaxAddr Range:",hex(MaxAddr)
+ OffsetAddr = address
+ print " OffsetAddr:",hex(OffsetAddr)
+
+ print " Memory Entries to be read : %d" % (value/8)
+ print " Match Magic Number : ", magicNum
+
+ while ( OffsetAddr <= MaxAddr):
+ sim_data = self.__read(objType,OffsetAddr,size)
+ print " ", hex(OffsetAddr),self.joinListDataToHex(sim_data).upper()
+ OffsetAddr += 8
+
+ if self.validateTestMemOp(sim_data,magicNum) == True:
+ print " Test validated .. [ OK ]"
+ return SUCCESS
+
+ return FAILURE # Failed validation
+
+ #------------------------------
+ # Read using SIM Object
+ #------------------------------
+ def __read(self, Targetobj, address, size):
+ simObj = SIM_get_interface(Targetobj, "memory_space")
+ value = simObj.read(None, address, size, 0x0)
+ #print " SIM obj: Read %s bytes [ OK ] " % size
+ return value
+
+ #--------------------------------
+ # Prepare the byte data from the
+ # string and return the list set
+ #-------------------------------
+ def stringToByte(self,value):
+ '''
+ The sim interface doesnt take the values as it is ..
+ it takes as byte arrays
+ Ex: "0000030100F0D101"
+ '\x00\x00\x03\x01\x00\xf0\xd1\x01'
+ [0, 0, 3, 1, 0, 240, 209, 1]
+ '''
+ # Convert it to a hex string
+ hex_val= value.decode("hex")
+ # Prepare the conversion to a list of byte values
+ value=map(ord, hex_val)
+ return value
+
+ #---------------------------------------
+ # Joing the list set data to hex data
+ # Reverse of the stringToByte logic
+ #---------------------------------------
+ def joinListDataToHex(self, data):
+ # simics> (0, 0, 3, 1, 0, 240, 209, 1)
+ # Join this data into hex string 0xf0d101
+ bit_shift=56
+ hex_val = 0x0
+ for val in data:
+ hex_val |= int(val) << bit_shift
+ bit_shift -=8
+ return hex(hex_val)
+
+ #----------------------------------------------------
+ # Execute the read or write operation in loop as per
+ # Test data set pre-defined
+ #----------------------------------------------------
+ def ExecuteTestOp(self, testOp, test_bucket, raiseException=True):
+ '''
+ 3 prong steps : set data, read/write data, validate
+ '''
+ #--------------------------------------------
+ for l_params in test_bucket:
+ #--------------------------------------------
+ print " Desc : %s " % l_params[5]
+ print " Op : %s " % l_params[0]
+ if "func" == l_params[0]:
+ print " Func : %s " % l_params[1]
+ if l_params[4] != "None":
+ print " Expect : %s " % l_params[4]
+ if "func" == l_params[0]:
+ print " Function Params :",l_params[2]
+ else:
+ # addr, value, size
+ self.setRegData(l_params[1],l_params[2],l_params[3])
+
+ # ---------------------------------------------
+ # Check the Op and perform the action
+ # read/write
+ # ---------------------------------------------
+ if "read" == l_params[0]:
+ sim_data = self.readFromReg(testOp)
+ print " ++++++++++++++++++++++++++++++++++++++++++"
+ print " simics Data : ", sim_data
+ print " simics Hex : ", self.joinListDataToHex(sim_data).upper()
+
+ # Validate the test data
+ '''
+ This field in the test entry holds the data
+ that needs validation against sim data.
+ '''
+ if l_params[4] != "None":
+ if self.validateTestOp(sim_data,l_params[4]) == True:
+ print " Test validated .. [ OK ]"
+ else:
+ if(raiseException == True):
+ raise Exception('Data mistmach');
+ return FAILURE # Failed validation
+ else:
+ print " ++++++++++++++++++++++++++++++++++++++++++"
+ elif "write" == l_params[0]:
+ self.writeToReg(testOp)
+ elif "memRead" == l_params[0]:
+ # (Sim obj) (Validate)
+ return self.readFromMemory(testOp, l_params[4])
+ elif "func" == l_params[0]:
+ # Func name Params
+ rc = self.loadFunc( l_params[1], l_params[2] )
+ return rc
+ else:
+ print "\n Invalid Test Data"
+ if(raiseException == True):
+ raise Exception('Invalid Test Data');
+ return FAILURE # Unknown entry op
+
+ print "\n"
+ return SUCCESS
+
+ #----------------------------------------------------
+ # Validate simulator data against test data
+ #----------------------------------------------------
+ def validateTestOp(self, sim_data, test_data):
+ print " Test Expects : 0x%s " % test_data
+ print " Expect bytes : ", self.stringToByte(test_data)
+ if self.compareList(self.stringToByte(test_data), sim_data, "None") == True:
+ print " Test ... [ OK ] "
+ print " ++++++++++++++++++++++++++++++++++++++++++"
+ return SUCCESS
+ else:
+ print " Test Failed... !!!"
+ print " ++++++++++++++++++++++++++++++++++++++++++"
+ return FAILURE
+
+ #----------------------------------------------------
+ # Validate simulator data against test data
+ #----------------------------------------------------
+ def validateTestMemOp(self, sim_data, test_data):
+ if self.compareList(self.stringToByte(test_data), sim_data,"memRead") == True:
+ return SUCCESS
+ return # Return nothing to check next memory entry
+
+
+ #----------------------------------------------------
+ # Compare the result vs expected list data
+ # byte by byte
+ #----------------------------------------------------
+ def compareList(self, expList, resList, opType):
+ for i in range(0,8):
+ if int(expList[i]) == int(resList[i]):
+ #print " %s : %s " % (expList[i],resList[i])
+ continue
+ else:
+ if opType != "memRead":
+ print " Error \t %s : %s [ Mismatch ]" % (expList[i],resList[i])
+ return False # mismatch
+ return # Return nothing for Next Mem byte read
+ return True
+
+ #----------------------------------------------------
+ # A basic loop poll mechanism
+ #----------------------------------------------------
+ def pollingOn(self, simObj, test_data, retries=20):
+ for l_param in test_data:
+ while True:
+ print "\n***** Polling On result - retrials left [%d] " % retries
+ print "\n"
+ testUtil.runCycles( 1000000);
+ test_d = (l_param,)
+ rc = self.ExecuteTestOp(simObj, test_d, False)
+ if rc == SUCCESS:
+ print ('Polling Successful for - ' + l_param[5])
+ break
+ elif retries <= 0:
+ print " Retrials exhausted... Exiting polling"
+ raise Exception('Polling Failed for - ' + l_param[5]);
+ break
+ else:
+ retries = retries - 1
+ return FAILURE
+
+ #----------------------------------------------------
+ # Load the function and execute
+ #----------------------------------------------------
+ def loadFunc(self, func_name, i_pArray ):
+ rc = testPSUUserUtil.__getattribute__(func_name)(i_pArray)
+ return rc # Either success or failure from func
+
+
diff --git a/src/test/testPutGetInScom.py b/src/test/testPutGetInScom.py
new file mode 100755
index 00000000..03571eaa
--- /dev/null
+++ b/src/test/testPutGetInScom.py
@@ -0,0 +1,82 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPutGetInScom.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+# @TODO via RTC : 141905
+# Modify the test sequence in such a way that
+# the test does not leave the Register value altered.
+
+# Indirect scom form 0 test case
+PUTSCOM_TESTDATA = [0,0,0,6,
+ 0,0,0xA2,0x02,
+ 0x80,0x0,0x0,0x83,
+ 0x0D,0x01,0x0C,0x3F,
+ 0xde,0xca,0xff,0xee,
+ 0x00,0x00,0x12,0x34 ]
+
+PUTSCOM_EXPDATA = [0xc0,0xde,0xa2,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+GETSCOM_TESTDATA = [0,0,0,4,
+ 0,0,0xA2,0x01,
+ 0x80,0x0,0x0,0x83,
+ 0x0D,0x01,0x0C,0x3F]
+
+GETSCOM_EXPDATA = [0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x12,0x34, # Only last 16 bits will be returned
+ 0xc0,0xde,0xa2,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( PUTSCOM_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( PUTSCOM_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( GETSCOM_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETSCOM_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testPutGetMem.xml b/src/test/testPutGetMem.xml
new file mode 100644
index 00000000..c386c933
--- /dev/null
+++ b/src/test/testPutGetMem.xml
@@ -0,0 +1,34 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testPutGetMem.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testPutMem.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testGetMem_expdata.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+
diff --git a/src/test/testPutGetRegFpr.py b/src/test/testPutGetRegFpr.py
new file mode 100755
index 00000000..2b2cd75c
--- /dev/null
+++ b/src/test/testPutGetRegFpr.py
@@ -0,0 +1,81 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPutGetRegFpr.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+PUTREG_TESTDATA = [0,0,0,9,
+ 0,0,0xA5,0x02,
+ 0x00,0x20,0x02,0x02, # two fpr registers
+ 0,0,0x0,0x01,
+ 0,0,0x0,0x0,
+ 0,0,0x0,0x1,
+ 0,0,0x0,0x02,
+ 0,0,0x0,0x0,
+ 0,0,0x0,0x2 ]
+
+PUTREG_EXPDATA = [0xc0,0xde,0xa5,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+GETREG_TESTDATA = [0,0,0,5,
+ 0,0,0xA5,0x01,
+ 0x00,0x20,0x02,0x02, #two fpr registers
+ 0,0,0x0,0x01,
+ 0,0,0x0,0x02 ]
+
+GETREG_EXPDATA = [0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x02,
+ 0xc0,0xde,0xa5,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( PUTREG_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( PUTREG_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( GETREG_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETREG_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testPutGetRegGpr.py b/src/test/testPutGetRegGpr.py
new file mode 100755
index 00000000..cd1e31b4
--- /dev/null
+++ b/src/test/testPutGetRegGpr.py
@@ -0,0 +1,81 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPutGetRegGpr.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+PUTREG_TESTDATA = [0,0,0,9,
+ 0,0,0xA5,0x02,
+ 0x00,0x20,0x00,0x02, # two gpr registers
+ 0,0,0x0,0x07,
+ 0,0,0x0,0x0,
+ 0,0,0x0,0x1,
+ 0,0,0x0,0x08,
+ 0,0,0x0,0x0,
+ 0,0,0x0,0x2 ]
+
+PUTREG_EXPDATA = [0xc0,0xde,0xa5,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+GETREG_TESTDATA = [0,0,0,5,
+ 0,0,0xA5,0x01,
+ 0x00,0x20,0x00,0x02, # two gpr registers
+ 0,0,0x0,0x07,
+ 0,0,0x0,0x08 ]
+
+GETREG_EXPDATA = [0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x02,
+ 0xc0,0xde,0xa5,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( PUTREG_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( PUTREG_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( GETREG_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETREG_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testPutGetRegSpr.py b/src/test/testPutGetRegSpr.py
new file mode 100755
index 00000000..55c6fa09
--- /dev/null
+++ b/src/test/testPutGetRegSpr.py
@@ -0,0 +1,81 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPutGetRegSpr.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+
+PUTREG_TESTDATA = [0,0,0,9,
+ 0,0,0xA5,0x02,
+ 0x00,0x20,0x01,0x02, # two spr registers
+ 0,0,0x0,0x08,
+ 0,0,0x0,0x0,
+ 0,0,0x0,0x1,
+ 0,0,0x0,0x09,
+ 0,0,0x0,0x0,
+ 0,0,0x0,0x2 ]
+
+PUTREG_EXPDATA = [0xc0,0xde,0xa5,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+GETREG_TESTDATA = [0,0,0,5,
+ 0,0,0xA5,0x01,
+ 0x00,0x20,0x01,0x02, # two spr registers
+ 0,0,0x0,0x08,
+ 0,0,0x0,0x09 ]
+
+GETREG_EXPDATA = [0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x02,
+ 0xc0,0xde,0xa5,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( PUTREG_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( PUTREG_EXPDATA )
+ testUtil.readEot( )
+ testUtil.writeUsFifo( GETREG_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETREG_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testPutGetScom.py b/src/test/testPutGetScom.py
new file mode 100755
index 00000000..de020fb2
--- /dev/null
+++ b/src/test/testPutGetScom.py
@@ -0,0 +1,118 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPutGetScom.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+# @TODO via RTC : 141905
+# Modify the test sequence in such a way that
+# the test does not leave the Register value altered.
+
+PUTSCOM_TESTDATA = [0,0,0,6,
+ 0,0,0xA2,0x02,
+ 0,0,0x0,0x00,
+ 0,0x05,0x00,0x3E, #scratch reg 7 (32-bit)
+ 0xde,0xca,0xff,0xee,
+ 0x00,0x00,0x00,0x00 ]
+
+PUTSCOM_TESTDATA_INVALID = [0,0,0,6,
+ 0,0,0xA2,0x02,
+ 0,0,0x0,0x00,
+ # TODO via RTC 152952: This address is invalid for
+ # Nimbus but not for Cumulus
+ 0x0a,0x00,0x00,0x00,
+ 0xde,0xca,0xff,0xee,
+ 0x00,0x00,0x00,0x00 ]
+
+PUTSCOM_EXPDATA = [0xc0,0xde,0xa2,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+PUTSCOM_EXPDATA_INVALID = [0xc0,0xde,0xa2,0x02,
+ 0x0,0xfe,0x0,0x11,
+ 0x00,0x0,0x0,0x04,
+ 0x00,0x0,0x0,0x04];
+
+GETSCOM_TESTDATA = [0,0,0,4,
+ 0,0,0xA2,0x01,
+ 0,0,0x0,0x00,
+ 0,0x05,0x0,0x3E]
+
+GETSCOM_TESTDATA_INVALID = [0,0,0,4,
+ 0,0,0xA2,0x01,
+ 0,0,0x0,0x00,
+ # TODO via RTC: 152952: This address is invalid for
+ # Nimbus but not for Cumulus
+ 0x0a,0x0,0x0,0x0]
+
+GETSCOM_EXPDATA = [0xde,0xca,0xff,0xee,
+ 0x00,0x00,0x00,0x00,
+ 0xc0,0xde,0xa2,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+GETSCOM_EXPDATA_INVALID = [0xc0,0xde,0xa2,0x01,
+ 0x0,0xfe,0x0,0x11,
+ 0x00,0x0,0x0,0x04,
+ 0x00,0x0,0x0,0x04];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+ print ("\nStarting putscom test")
+ testUtil.writeUsFifo( PUTSCOM_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( PUTSCOM_EXPDATA )
+ testUtil.readEot( )
+ print ("\nStarting invalid putscom test")
+ testUtil.writeUsFifo( PUTSCOM_TESTDATA_INVALID )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( PUTSCOM_EXPDATA_INVALID )
+ testUtil.readEot( )
+ print ("\nStarting getscom test")
+ testUtil.writeUsFifo( GETSCOM_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETSCOM_EXPDATA )
+ testUtil.readEot( )
+ print ("\nStarting invalid getscom test")
+ testUtil.writeUsFifo( GETSCOM_TESTDATA_INVALID )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETSCOM_EXPDATA_INVALID )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testPutMem.py b/src/test/testPutMem.py
new file mode 100644
index 00000000..eec39f5f
--- /dev/null
+++ b/src/test/testPutMem.py
@@ -0,0 +1,83 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPutMem.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+LOOP_COUNT = 4
+
+PUTMEM_TEST_HDR = [0,0,0,0x86,
+ 0,0,0xA4,0x02,
+ 0,0,0x0,0x02,
+ 0,0,0,0,
+ 0x08,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x80]
+
+PUTMEM_TEST_DATA = [0xAB,0xCD,0xEF,0x01,
+ 0xAB,0xCD,0xEF,0x02,
+ 0xAB,0xCD,0xEF,0x03,
+ 0xAB,0xCD,0xEF,0x04,
+ 0xAB,0xCD,0xEF,0x05,
+ 0xAB,0xCD,0xEF,0x06,
+ 0xAB,0xCD,0xEF,0x07,
+ 0xAB,0xCD,0xEF,0x08]
+
+PUTMEM_EXPDATA = [0x00,0x00,0x00,0x80,
+ 0xc0,0xde,0xa4,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03]
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ testUtil.writeUsFifo( PUTMEM_TEST_HDR )
+
+ loop = 1
+ while (loop <= LOOP_COUNT):
+ #testUtil.runCycles( 10000000 )
+ testUtil.writeUsFifo( PUTMEM_TEST_DATA )
+ loop += 1
+ testUtil.writeEot( )
+
+ #testUtil.runCycles( 10000000 )
+ testUtil.readDsFifo( PUTMEM_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testPutMem_fail.py b/src/test/testPutMem_fail.py
new file mode 100644
index 00000000..b13032a1
--- /dev/null
+++ b/src/test/testPutMem_fail.py
@@ -0,0 +1,84 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPutMem_fail.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+LOOP_COUNT = 4
+
+PUTMEM_TEST_HDR = [0,0,0x00,0x86,
+ 0,0,0xA4,0x02,
+ 0,0,0x0,0x02,
+ 0,0,0,0,
+ 0x08,0x00,0x00,0x04, # Un-aligned PBA Address
+ 0x00,0x00,0x00,0x80]
+
+PUTMEM_TEST_DATA = [0xAB,0xCD,0xEF,0x01,
+ 0xAB,0xCD,0xEF,0x02,
+ 0xAB,0xCD,0xEF,0x03,
+ 0xAB,0xCD,0xEF,0x04,
+ 0xAB,0xCD,0xEF,0x05,
+ 0xAB,0xCD,0xEF,0x06,
+ 0xAB,0xCD,0xEF,0x07,
+ 0xAB,0xCD,0xEF,0x08]
+
+PUTMEM_EXPDATA = [0x00,0x00,0x00,0x00,
+ 0xc0,0xde,0xa4,0x02,
+ 0x00,0xfe,0x00,0x0a,
+ 0xff,0xdc,0x00,0x03,
+ 0x00,0x00,0x00,0x00,
+ 0x00,0xf8,0x82,0x19,
+ 0x00,0x00,0x00,0x06]
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ testUtil.writeUsFifo( PUTMEM_TEST_HDR )
+
+ loop = 1
+ while (loop <= LOOP_COUNT):
+ testUtil.writeUsFifo( PUTMEM_TEST_DATA )
+ loop += 1
+ testUtil.writeEot( )
+
+ testUtil.readDsFifo( PUTMEM_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testPutScomUnderMask.py b/src/test/testPutScomUnderMask.py
new file mode 100755
index 00000000..c8c58427
--- /dev/null
+++ b/src/test/testPutScomUnderMask.py
@@ -0,0 +1,98 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testPutScomUnderMask.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+PUTSCOM_TESTDATA = [0,0,0,6,
+ 0,0,0xA2,0x02,
+ 0,0,0x0,0x00,
+ 0,0x05,0x00,0x3E, #scratch reg 7 (32-bit)
+ 0xff,0xff,0xff,0xff,
+ 0x00,0x00,0x00,0x00 ]
+
+PUTSCOM_EXPDATA = [0xc0,0xde,0xa2,0x02,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+
+PUTSCOMUMASK_TESTDATA = [0,0,0,8,
+ 0,0,0xA2,0x04,
+ 0,0,0x0,0x00,
+ 0,0x05,0x00,0x3E,
+ 0xde,0xca,0xff,0xee,
+ 0x00,0x00,0x00,0x00,
+ 0xff,0x00,0xff,0x00,
+ 0x00,0x00,0x00,0x00]
+
+
+PUTSCOMUMASK_EXPDATA = [0xc0,0xde,0xa2,0x04,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+GETSCOMUMASK_TESTDATA = [0,0,0,4,
+ 0,0,0xA2,0x01,
+ 0,0,0x0,0x00,
+ 0,0x05,0x0,0x3E]
+
+GETSCOMUMASK_EXPDATA = [0xde, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xc0,0xde,0xa2,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ testUtil.writeUsFifo( PUTSCOM_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( PUTSCOM_EXPDATA )
+ testUtil.readEot( )
+
+ testUtil.writeUsFifo( PUTSCOMUMASK_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( PUTSCOMUMASK_EXPDATA )
+ testUtil.readEot( )
+
+ testUtil.writeUsFifo( GETSCOMUMASK_TESTDATA )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( GETSCOMUMASK_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testRegAccess.xml b/src/test/testRegAccess.xml
new file mode 100755
index 00000000..a44eecac
--- /dev/null
+++ b/src/test/testRegAccess.xml
@@ -0,0 +1,46 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testRegAccess.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testStopInstruction.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testPutGetRegGpr.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testPutGetRegFpr.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testPutGetRegSpr.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testStartInstruction.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+
diff --git a/src/test/testRegistry.py b/src/test/testRegistry.py
new file mode 100644
index 00000000..ff205dbd
--- /dev/null
+++ b/src/test/testRegistry.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testRegistry.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 testClass.py
+# @author: George Keishing <gkeishin@in.ibm.com>
+# @brief Framework class Host SBE interface on simics
+#
+# Created on March 29, 2016
+# ----------------------------------------------------
+# @version Developer Date Description
+# ----------------------------------------------------
+# 1.0 gkeishin 29/03/16 Initial create
+#############################################################
+'''
+
+# Test OP keywords for reference
+'''
+ - read : Read from a Registry
+ - write : write to a Registry
+ - memRead : Read from a memory address block
+'''
+
+# Registry address for direct usage
+REG_MBOX0 = 0x00680500
+REG_MBOX1 = 0x00680510
+REG_MBOX2 = 0x00680520
+REG_MBOX3 = 0x00680530
+REG_MBOX4 = 0x00680540
+REG_MBOX5 = 0x00680550
+REG_MBOX6 = 0x00680560
+REG_MBOX7 = 0x00680570
+
+# PSU doorbell regs
+PSU_SBE_DOORBELL_REG = 0x00680600
+PSU_SBE_DOORBELL_REG_WO_AND = 0x00680610
+PSU_SBE_DOORBELL_REG_WO_OR = 0x00680620
+
+PSU_HOST_DOORBELL_REG = 0x00680630
+PSU_HOST_DOORBELL_REG_WO_AND = 0x00680640
+PSU_HOST_DOORBELL_REG_WO_OR = 0x00680650
+
+
+# Memory space address
+'''
+simics> system_cmp0.phys_mem.map
+ Base Object Fn Offset Length
+-------------------------------------------------------------------------
+0x0000008000000 p9Proc0.l3_cache_ram 0 0x0 0xa00000
+ width 8192 bytes
+0x6030000000000 p9Proc0.lpcm 0 0x6030000000000 0xffffffff
+ width 4 bytes
+0x603fc00000000 proc_p9chip0.mc_freeze 0 0x0 0x400000000
+ target -> proc_p9chip0.xscom_memspc, width 8 bytes
+
+'''
+MEM_ADDR = 0x0000008000000
diff --git a/src/test/testSbeDump.py b/src/test/testSbeDump.py
new file mode 100644
index 00000000..72d089e0
--- /dev/null
+++ b/src/test/testSbeDump.py
@@ -0,0 +1,110 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testSbeDump.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest")
+import testUtil
+err = False
+#from testWrite import *
+
+TESTDATA = [0, 0, 0, 3,
+ 0, 0, 0xA1, 0x01,
+ 0, 0x02, 0x00, 0x2]
+
+EXPDATA = [0xc0, 0xde, 0xa1, 0x01]
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main():
+ testUtil.runCycles(10000000)
+ testUtil.writeUsFifo(TESTDATA)
+ testUtil.writeEot()
+ testUtil.readDsFifo(EXPDATA)
+ #flush out primary and secondary status
+ data = testUtil.readDsEntryReturnVal()
+
+ #flush hwp ffdc
+ data = testUtil.readDsEntryReturnVal()
+ data = testUtil.readDsEntryReturnVal()
+
+ #start processing sbe ffdc
+ data = testUtil.readDsEntryReturnVal()
+ magicBytes = ((data[0] << 8) | data[1])
+ if (magicBytes == 0xFFDC) :
+ print ("\nMagic Bytes Match")
+ else :
+ raise Exception('data mistmach')
+ packLen = ((data[2] << 8) | data[3])
+ print ("\nFFDC package length = " + str(packLen))
+
+ data = testUtil.readDsEntryReturnVal()
+ fapiRc = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3])
+ print ("\nFAPI rc = " + str(hex(fapiRc)))
+
+ data = testUtil.readDsEntryReturnVal()
+ primaryStatus = ((data[0] << 8) | data[1])
+ secondaryStatus = ((data[2] << 8) | data[3])
+ print ("\nPrimary Status " + str(hex(primaryStatus)) + " Secondary Status "\
+ + str(hex(secondaryStatus)))
+
+ data = testUtil.readDsEntryReturnVal()
+ header = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3])
+ print ("\nHeader = " + str(hex(header)))
+
+ for i in range(0, (bin(header).count("1"))):
+ #read user data id
+ data = testUtil.readDsEntryReturnVal()
+ id = (data[0] << 8) | data[1]
+ print "User data Id ["+str(hex(id))+"]"
+ len = (data[2] << 8) | data[3]
+ #if it is trace field SBE_FFDC_TRACE_DUMP
+ fileName = ""
+ if(id == 0x0002):
+ fileName = "trace.bin"
+ print ("\nlength of trace dump " + str(len))
+ #if it is trace field SBE_FFDC_ATTR_DUMP
+ elif(id == 0x0001):
+ fileName = "attr.bin"
+ print ("\nlength of attr dump " + str(len))
+ myBin = open(fileName, 'wb')
+ print ("\nwriting "+fileName)
+ loopCount = (len ) / 4
+ for j in range(0, loopCount):
+ data = testUtil.readDsEntryReturnVal()
+ myBin.write(bytearray(data))
+ print("write to a file Done")
+ myBin.close()
+ #flush out distance
+ data = testUtil.readDsEntryReturnVal()
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testScom.xml b/src/test/testScom.xml
new file mode 100755
index 00000000..d3df6196
--- /dev/null
+++ b/src/test/testScom.xml
@@ -0,0 +1,42 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testScom.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testPutGetScom.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testPutScomUnderMask.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testModifyScom.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testPutGetInScom.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+
diff --git a/src/test/testSram.py b/src/test/testSram.py
new file mode 100644
index 00000000..2b62597f
--- /dev/null
+++ b/src/test/testSram.py
@@ -0,0 +1,129 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testSram.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+LOOP_COUNT = 1
+
+PUTSRAM_OCC_CNTLDATA = [0,0,0,0x20,
+ 0,0,0xa4,0x04, #magic
+ 0,0,0,0x01,
+ 0xe7,0xf0,0x00,0x00, #addr
+ 0,0,0x01,0x00] # length
+
+PUTSRAM_OCC_TESTDATA = [0xab,0xcd,0xef,0x12,
+ 0xba,0xdc,0xfe,0x21,
+ 0x34,0x56,0x78,0x9a,
+ 0x43,0x65,0x87,0xa9,
+ 0xab,0xcd,0xef,0x12,
+ 0xba,0xdc,0xfe,0x21,
+ 0x34,0x56,0x78,0x9a,
+ 0x43,0x65,0x87,0xa9]
+
+PUTSRAM_OCC_EXP_CNTLDATA = [0,0,0x01,0x00,
+ 0xc0,0xde,0xa4,0x04,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03]
+
+GETSRAM_OCC_CNTLDATA = [0,0,0,0x5,
+ 0,0,0xa4,0x03,
+ 0,0,0,0x01,
+ 0xe7,0xf0,0x00,0x00, #address
+ 0x00,0x00,0x01,0x00] # length of data
+
+GETSRAM_OCC_EXP_TESTDATA = [0xab,0xcd,0xef,0x12, #data
+ 0xba,0xdc,0xfe,0x21,
+ 0x34,0x56,0x78,0x9a,
+ 0x43,0x65,0x87,0xa9,
+ 0xab,0xcd,0xef,0x12,
+ 0xba,0xdc,0xfe,0x21,
+ 0x34,0x56,0x78,0x9a,
+ 0x43,0x65,0x87,0xa9]
+
+GETSRAM_OCC_EXP_CNTLDATA = [0x00,0x00,0x01,0x00, # length
+ 0xc0,0xde,0xa4,0x03,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03];
+
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ # Put Occ Sram test - Linear - Can be tested over Normal
+ # Debug mode
+ testUtil.writeUsFifo( PUTSRAM_OCC_CNTLDATA )
+ # Write 32 bytes of data 8 times => 32*8 = 256 = 0x100
+ i_cnt = 0
+ while i_cnt < 8:
+ testUtil.writeUsFifo( PUTSRAM_OCC_TESTDATA )
+ i_cnt = i_cnt+1
+
+ testUtil.writeEot( )
+
+ # Read the expected data for put sram
+ testUtil.readDsFifo( PUTSRAM_OCC_EXP_CNTLDATA )
+ testUtil.readEot( )
+
+ # Get Sram Linear
+ testUtil.writeUsFifo( GETSRAM_OCC_CNTLDATA )
+ testUtil.writeEot( )
+
+ # Read the Expected Data for get Sram
+ i_cnt = 0
+ while i_cnt < 8:
+ testUtil.readDsFifo( GETSRAM_OCC_EXP_TESTDATA )
+ i_cnt = i_cnt+1
+
+ testUtil.readDsFifo( GETSRAM_OCC_EXP_CNTLDATA )
+ testUtil.readEot( )
+
+ # Put Occ Sram test - Circular - Can be enabled once we get
+ # valid address range to read the circular data
+ #testUtil.writeUsFifo( PUTSRAM_OCC_TESTDATA_1 )
+ #testUtil.writeEot( )
+ #testUtil.readDsFifo( PUTSRAM_OCC_EXPDATA_1 )
+ #testUtil.readEot( )
+ #testUtil.writeUsFifo( GETSRAM_OCC_TESTDATA_1 )
+ #testUtil.writeEot( )
+ #testUtil.readDsFifo( GETSRAM_OCC_EXPDATA_1 )
+ #testUtil.readEot( )
+
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testSram.xml b/src/test/testSram.xml
new file mode 100755
index 00000000..902786ad
--- /dev/null
+++ b/src/test/testSram.xml
@@ -0,0 +1,31 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/test/testSram.xml $ -->
+<!-- -->
+<!-- OpenPOWER sbe Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2016 -->
+<!-- -->
+<!-- -->
+<!-- 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 -->
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <testcase>
+ <!-- TODO RTC - 150091 - Add the Occ sram test case -->
+ <!--<simcmd>run-python-file targets/p9_nimbus/sbeTest/testSram.py</simcmd>-->
+ <!--<exitonerror>yes</exitonerror>-->
+ </testcase>
+
diff --git a/src/test/testStartInstruction.py b/src/test/testStartInstruction.py
new file mode 100644
index 00000000..d45e791c
--- /dev/null
+++ b/src/test/testStartInstruction.py
@@ -0,0 +1,64 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testStartInstruction.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+LOOP_COUNT = 1
+
+
+# Start All thread in Core0 with warn flag true
+INST_START0_ALL_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0xf0]
+
+INST_EXPDATA = [0xc0,0xde,0xa7,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03]
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ #stop all thread in core0
+ testUtil.writeUsFifo( INST_START0_ALL_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testStopInstruction.py b/src/test/testStopInstruction.py
new file mode 100644
index 00000000..a43463c7
--- /dev/null
+++ b/src/test/testStopInstruction.py
@@ -0,0 +1,64 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testStopInstruction.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest" )
+import testUtil
+err = False
+#from testWrite import *
+
+LOOP_COUNT = 1
+
+
+# Stop All thread in Core0 with warn flag true
+INST_STOP0_ALL_TESTDATA_WITH_WARN_FLG = [0,0,0,0x03,
+ 0,0,0xa7,0x01,
+ 0,1,0x20,0xf1]
+
+INST_EXPDATA = [0xc0,0xde,0xa7,0x01,
+ 0x0,0x0,0x0,0x0,
+ 0x00,0x0,0x0,0x03]
+
+# MAIN Test Run Starts Here...
+#-------------------------------------------------
+def main( ):
+ testUtil.runCycles( 10000000 )
+
+ #stop all thread in core0
+ testUtil.writeUsFifo( INST_STOP0_ALL_TESTDATA_WITH_WARN_FLG )
+ testUtil.writeEot( )
+ testUtil.readDsFifo( INST_EXPDATA )
+ testUtil.readEot( )
+
+#-------------------------------------------------
+# Calling all test code
+#-------------------------------------------------
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/src/test/testUtil.py b/src/test/testUtil.py
new file mode 100644
index 00000000..444319ab
--- /dev/null
+++ b/src/test/testUtil.py
@@ -0,0 +1,170 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/test/testUtil.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+import time
+import conf
+from sim_commands import *
+
+#err = False
+lbus = conf.p9Proc0.proc_lbus_map
+def writeUsFifo( data):
+ """Main test Loop"""
+ loopCount = len(data)/4;
+ for i in range (loopCount):
+ idx = i * 4;
+ writeEntry(lbus, 0x2400, (data[idx], data[idx+1], data[idx+2], data[idx+3]) )
+
+def readDsFifo(data):
+ """Main test Loop"""
+ loopCount = len(data)/4;
+ for i in range (loopCount):
+ idx = i * 4;
+ checkEqual(readEntry(lbus, 0x2440, 4), (data[idx], data[idx+1], data[idx+2], data[idx+3]))
+
+def writeEot():
+ write(lbus, 0x2408, (0, 0, 0, 1) )
+
+def write(obj, address, value ):
+ """ Write to memory space """
+ iface = SIM_get_interface(obj, "memory_space")
+ iface.write(None, address, value, 0x0)
+
+def readEot():
+ """ Read from memory space """
+ status = read(lbus, 0x2444, 4)
+ checkEqual( (status[3] & 0x80), 0x80 );
+ read(lbus, 0x2440, 4)
+
+def resetFifo():
+ write(lbus, 0x240C, (0, 0, 0, 1))
+ return
+
+def readUsFifoStatus():
+ status = read(lbus, 0x2404, 4)
+ return status
+
+def readDsFifoStatus():
+ status = read(lbus, 0x2444, 4)
+ return status
+
+def waitTillFifoEmpty(func):
+ count = 0
+ loop = True
+ while(loop is True):
+ status = func()
+ if(status[1] == 0x10):
+ loop = False
+ break
+ else:
+ count = count + 1
+ runCycles(200000)
+ if(count > 10):
+ raise Exception('Timed out waiting for FIFO to get flushed')
+
+
+def waitTillUsFifoEmpty():
+ try:
+ waitTillFifoEmpty(readUsFifoStatus)
+ except:
+ raise Exception('US FIFO did not get empty')
+
+
+def waitTillDsFifoEmpty():
+ try:
+ waitTillFifoEmpty(readDsFifoStatus)
+ except:
+ raise Exception('DS FIFO did not get empty')
+
+
+# This function will only read the entry but will not compare it
+# with anything. This can be used to flush out enteries.
+def readDsEntry(entryCount):
+ for i in range (entryCount):
+ readEntry(lbus, 0x2440, 4)
+
+def writeEntry(obj, address, value ):
+
+ loop = 1;
+ count = 0;
+ while( loop ):
+ status = read(lbus, 0x2404, 4) # Address 0x2404: Upstream Fifo Status
+
+ if( status[2] & 0x02):
+ count = count + 1
+ runCycles(200000)
+ # This will cause test to fail
+ if(count > 10):
+ raise Exception('Timeout. FIFO FULL');
+ else:
+ # write entry
+ write(obj, address, value)
+ loop = 0
+
+ return value
+def readDsEntryReturnVal():
+ data = readEntry(lbus, 0x2440, 4)
+ runCycles(200000)
+ return data
+def readEntry(obj, address, size):
+
+ """ Read from memory space """
+ loop = 1;
+ count = 0;
+ value = (0,0,0,0)
+ while( loop ):
+ status = read(lbus, 0x2444, 4) # Address 0x2444: Downstream Fifo Status
+
+ if( status[1] & 0x0F):
+ # read entry
+ value = read(lbus, address, size)
+ loop = 0
+ else:
+ count = count + 1
+ runCycles(200000)
+ # This will cause test to fail
+ if(count > 10):
+ raise Exception('Timeout. Empty FIFO');
+
+ return value
+
+def read(obj, address, size):
+ """ Read from memory space """
+ iface = SIM_get_interface(obj, "memory_space")
+ value = iface.read(None, address, size, 0x0)
+ return value
+
+def runCycles( cycles ):
+ if (not SIM_simics_is_running()):
+ syscmd = "run-cycles %d"%(cycles)
+ ( rc, out ) = quiet_run_command( syscmd, output_modes.regular )
+ if ( rc ):
+ print "simics ERROR running %s: %d "%( syscmd, rc )
+
+def checkEqual( data, expdata ):
+ """ Throw exception if data is not equal """
+ if( cmp(data, expdata )):
+ print "Eqality check failed"
+ print "Data:", data
+ print "Expected Data", expdata
+ raise Exception('data mistmach');
+
diff --git a/src/tools/debug/simics/makefile b/src/tools/debug/simics/makefile
new file mode 100755
index 00000000..473c0088
--- /dev/null
+++ b/src/tools/debug/simics/makefile
@@ -0,0 +1,53 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/debug/simics/makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+#
+# FSP Destination: obj/ppc/sbei/sbfw/simics/makefile
+#
+# NOTE: Do NOT modify this file in CMVC directly! It comes from the SBE
+# repository and will be overwritten.
+
+.include <${RULES_MK}>
+
+OTHERS = copy_scripts
+
+SBE_SIMICS_PATH = ${MAKETOP}simu/scripts/sbfw/
+
+SBE_SRC_PATHS = ${.PATH:M*src*sbei*sbfw*simics*} ${.PATH:M*obj*sbei*sbfw*simics*}
+SBE_SRC_DIRS = ${SBE_SRC_PATHS:XD}
+SBE_SRC_FILES = ${:!${SBE_SRC_DIRS:@path@ls ${path};@}!}
+
+SBE_SCRIPTS_TO_COPY = ${SBE_SRC_FILES:Nmakefile}
+SBE_SCRIPTS_PATHS = ${SBE_SCRIPTS_TO_COPY:p}
+
+SBE_COPY_COMMAND = \
+ ${SBE_SCRIPTS_PATHS:@file@cp -r ${file} ${SBE_SIMICS_PATH}; @}
+SBE_REMOVE_COMMAND = \
+ ${SBE_SCRIPTS_TO_COPY:@file@rm -rf ${SBE_SIMICS_PATH}${file}; @}
+
+copy_scripts:
+ mkdir -p ${SBE_SIMICS_PATH}
+ ${SBE_COPY_COMMAND}
+
+clobber_copy_scripts:
+ ${SBE_REMOVE_COMMAND}
diff --git a/src/tools/debug/simics/sbe_standalone.simics b/src/tools/debug/simics/sbe_standalone.simics
new file mode 100755
index 00000000..8fd3bdb0
--- /dev/null
+++ b/src/tools/debug/simics/sbe_standalone.simics
@@ -0,0 +1,2 @@
+echo "SBE standalone Tools"
+
diff --git a/src/tools/debug/simics/sbe_startup.simics b/src/tools/debug/simics/sbe_startup.simics
new file mode 100755
index 00000000..5d466a20
--- /dev/null
+++ b/src/tools/debug/simics/sbe_startup.simics
@@ -0,0 +1,14 @@
+echo "Attempting to register SBE Tools"
+
+# Load SBE debug tools.
+try {
+ $sbe_startup_path = (lookup-file sbfw/simics-debug-framework.py);
+ $sbe_script_location = (python "''.join(map('/'.__add__,\""+$sbe_startup_path+"\"[1:].split('/')[0:-1]))")
+ python "os.environ['SBE_TOOLS_PATH'] = \""+$sbe_script_location+"\""
+ echo $sbe_script_location;
+ run-python-file (lookup-file sbfw/simics-debug-framework.py)
+ # Set mailbox scratch registers so that the SBE starts in plck mode
+ # p9Proc0.proc_chip.invoke parallel_store SCOM 0x5003F "20000000_00000000" 64
+ # p9Proc0.proc_chip.invoke parallel_store SCOM 0x5003A "00000000_00000000" 64
+} except { echo "ERROR: Failed to load SBE debug tools." }
+
diff --git a/src/tools/debug/simics/simics-debug-framework.py b/src/tools/debug/simics/simics-debug-framework.py
new file mode 100755
index 00000000..87d3656b
--- /dev/null
+++ b/src/tools/debug/simics/simics-debug-framework.py
@@ -0,0 +1,88 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/debug/simics/simics-debug-framework.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import os
+import os.path
+import subprocess
+import re
+import random
+import sys
+import imp
+testIstepAuto = imp.load_source("testIstepAuto", os.environ['SBE_TOOLS_PATH'] + "/testIstepAuto.py")
+err = False
+
+syms = {};
+
+def check_sbe_tools_path ():
+ global SBE_TOOLS_PATH
+ SBE_TOOLS_PATH = os.environ['SBE_TOOLS_PATH'];
+
+def register_sbe_debug_framework_tools():
+ check_sbe_tools_path ()
+ fillSymTable()
+ # Create command hook.
+ new_command("sbe-istep",testIstepAuto.sbe_istep_func,
+ args = [arg(int_t, "major"), arg(int_t, "minor")],
+ alias = "istep",
+ type = ["sbe-commands"],
+ short = "Runs the debug framework for istep ",
+ doc = "")
+ new_command("sbe-trace", collectTrace,
+ args = [arg(int_t, "procNr")],
+ alias = "strace",
+ type = ["sbe-commands"],
+ short = "Runs the debug framework for trace ",
+ doc = "")
+ print "SBE Debug Framework: Registered tool:", "sbe-istep"
+ print "SBE Debug Framework: Registered tool:", "sbe-trace"
+
+
+def fillSymTable():
+# symFile = os.environ['SBE_IMG_OUT_LOC'] + "/sbe.syms"
+ symFile = SBE_TOOLS_PATH + "/sbe.syms"
+# symFile = os.environ['sb'] + "/../obj/ppc/sbei/sbfw/simics/sbe.syms"
+ f = open( symFile, 'r')
+ for line in f:
+ words = line.split()
+ if( len( words ) == 4 ):
+ syms[words[3]] = [words[0], words[1]]
+
+def collectTrace ( procNr ):
+ fileName = "sbe_" + `procNr` + "_tracMERG"
+ cmd1 = "pipe \"p9Proc" + `procNr` + ".sbe.mibo_space.x 0x" + syms['g_pk_trace_buf'][0] + " 0x2028\" \"sed 's/^p:0x........ //g' | sed 's/ ................$//g' | sed 's/ //g' | xxd -r -p> ppetrace.bin\""
+ cmd2 = "shell \"" + SBE_TOOLS_PATH + "/ppe2fsp ppetrace.bin sbetrace.bin \""
+ cmd3 = "shell \"" + SBE_TOOLS_PATH + "/fsp-trace -s " + SBE_TOOLS_PATH + "/sbeStringFile sbetrace.bin >" + fileName + "\""
+ cmd4 = "shell \"" + "cat " + fileName + "\""
+
+ ( rc, out ) = quiet_run_command( cmd1, output_modes.regular )
+ if ( rc ):
+ print "simics ERROR running %s: %d "%( cmd1, rc )
+
+ SIM_run_alone( run_command, cmd2 )
+ SIM_run_alone( run_command, cmd3 )
+ SIM_run_alone( run_command, cmd4 )
+
+
+# Run the registration automatically whenever this script is loaded.
+register_sbe_debug_framework_tools()
+
diff --git a/src/tools/hooks/addCopyright b/src/tools/hooks/addCopyright
new file mode 100755
index 00000000..13867e7e
--- /dev/null
+++ b/src/tools/hooks/addCopyright
@@ -0,0 +1,1167 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: sbe/tools/hooks/addCopyright.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+# [+] 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
+#################################### ABOUT ####################################
+# Forked from: #
+# Author: Mark Jerde (mjerde@us.ibm.com) #
+# Date: Fri Mar 19 17:40:32 2010 UTC #
+# #
+# addCopyright will automatically insert appropriate copyright statements #
+# in source files following the IBM copyright guidelines (and templates) #
+# referenced below : #
+# FSP ClearCase Architecture #
+# Version 1.9 #
+# 10/12/2010 #
+# Editor: Alan Hlava #
+# #
+# Section 3.14.1 of the above doc has templates for different files #
+# #
+# NOTE: FSP uses the phrase "OCO Source materials" in their copyright #
+# block, which is classified as 'p1' . We will use the same #
+# classification here. #
+# NOTE: to list all files in src EXCEPT the build dir, run: #
+# make clean # remove autogenerated files #
+# find src -path 'src/build' -prune -o ! -type d -print | tr '\n' ' ' #
+# #
+# addCopyright does not support piping, but you can send these #
+# to a file, add "addCopyright update" to the beginning of the line, #
+# and run the file to update all #
+###############################################################################
+
+use strict;
+use warnings;
+use POSIX;
+use Getopt::Long;
+use File::Basename;
+use lib dirname (__FILE__);
+use Cwd;
+
+#------------------------------------------------------------------------------
+# Project-specific settings.
+#------------------------------------------------------------------------------
+my $ReleaseYear = `date +%Y`;
+chomp( $ReleaseYear );
+$ReleaseYear = $ENV{'DATE_OVERRIDE'} if defined $ENV{'DATE_OVERRIDE'};
+
+my $copyrightSymbol = "";
+# my $copyrightSymbol = "(C)"; # Uncomment if unable to use  character.
+
+# set by environment variable in project env.bash
+my $projectName = $ENV{'PROJECT_NAME'};
+my $copyrightPrefix = "Contributors Listed Below - ";
+my $copyrightStr = $copyrightPrefix."COPYRIGHT";
+my $projectRoot = $ENV{'SBEROOT'};
+# Relative path of import tree from project root
+my $importPrefix = $ENV{'IMPORT_REL_PATH'}."/";
+
+## note that these use single ticks so that the escape chars are NOT evaluated yet.
+my $OLD_DELIMITER_END = 'IBM_PROLOG_END';
+my $DELIMITER_END = 'IBM_PROLOG_END_TAG';
+my $DELIMITER_BEGIN = 'IBM_PROLOG_BEGIN_TAG';
+
+my $SOURCE_BEGIN_TAG = "\$Source:";
+my $SOURCE_END_TAG = "\$";
+
+# Desired License, set by environment variable in project env.bash
+my $LicenseFile = $ENV{'LICENSE'};
+use constant LICENSE_PROLOG => "LICENSE_PROLOG";
+
+#------------------------------------------------------------------------------
+# Contributer info
+#------------------------------------------------------------------------------
+
+# Constants for company's copyright
+# When adding a new company add constant here and to %fileContributorsCompany
+use constant IBM => 'International Business Machines Corp.';
+use constant GOOGLE => 'Google Inc.';
+
+# Create mapping for git contrubitors to companies
+my %fileContributorsCompany = (
+ "ibm.com" => IBM,
+ "ozlabs.org" => IBM,
+ "google.com" => GOOGLE,
+ "Google Shared Technology" => GOOGLE,
+);
+
+#------------------------------------------------------------------------------
+# Constants
+#------------------------------------------------------------------------------
+use constant RC_INVALID_PARAMETERS => 1;
+use constant RC_NO_COPYRIGHT_BLOCK => 2;
+use constant RC_BAD_CONTRIBUTORS_BLOCK => 3;
+use constant RC_INVALID_FILETYPE => 4;
+use constant RC_DIFFERS_FROM_LICENSE_PROLOG => 5;
+use constant RC_NO_LICENSE_PROLOG_FILE => 6;
+
+#------------------------------------------------------------------------------
+# Global Vars
+#------------------------------------------------------------------------------
+my $opt_help = 0;
+my $opt_debug = 0;
+my $operation = "";
+my $opt_logfile = "";
+
+my $DelimiterBegin = "";
+my $CopyrightBlock = "";
+my $DelimiterEnd = "";
+my $CopyRightString = "";
+my $copyright_check = 0;
+
+my $TempFile = "";
+my @Files = ();
+
+my $rc = 0;
+
+# NOTE: $OLD_DELIMITER_END is a subset of $DELIMITER_END so must match
+# $DELIMITER_END first in order to return the entire string.
+my $g_end_del_re = "($DELIMITER_END|$OLD_DELIMITER_END)";
+my $g_prolog_re = "($DELIMITER_BEGIN)((.|\n)+?)$g_end_del_re";
+
+#######################################################################
+# Main
+#######################################################################
+if (scalar(@ARGV) < 2)
+{
+ ## needs at least one filename and an operation as a parameter
+ usage();
+}
+
+
+my @SaveArgV = @ARGV;
+#------------------------------------------------------------------------------
+# Parse optional input arguments
+#------------------------------------------------------------------------------
+GetOptions( "help|?" => \$opt_help,
+ "validate" => sub { $operation="validate"; },
+ "update" => sub { $operation="update"; },
+ "copyright-check" => \$copyright_check,
+ "log-failed-files=s" => \$opt_logfile,
+ "debug" => \$opt_debug,
+ );
+
+## scan through remaining args and store all files in @Files
+## check for old-type parms, just in case
+foreach ( @ARGV )
+{
+ ## print $_;
+ if ( m/^debug$/ ) { $opt_debug = 1; next; }
+ if ( m/^update$/ ) { $operation = $_; next; }
+ if ( m/^validate$/ ) { $operation = $_; next; }
+
+ push @Files, $_ ;
+}
+
+
+if ( $opt_debug )
+{
+ print STDERR __LINE__, " : ---- DEBUG -----\n";
+ print STDERR "help = $opt_help\n";
+ print STDERR "debug = $opt_debug\n";
+ print STDERR "operation = $operation\n";
+ print STDERR "log-failed-files = $opt_logfile\n";
+
+ ## dump files specified
+ print STDERR "Files:\n";
+ print STDERR join( ' ', @Files ), "\n";
+
+ print STDERR "ReleaseYear = $ReleaseYear\n";
+
+ print "\n";
+}
+
+if ( $operation eq "" )
+{
+ print STDOUT "No operation specified\n";
+ usage();
+ exit RC_INVALID_PARAMETERS;
+}
+
+if ( ( $opt_logfile ne "" )
+ ## && ( $operation eq "validate" )
+ )
+{
+ my $logdate = `date +%Y-%m-%d:%H%M`;
+ chomp $logdate;
+ open( LOGFH, "> $opt_logfile" ) or die "ERROR $?: Failed to open $opt_logfile: $!";
+ print LOGFH "## logfile generated $logdate from command line:\n";
+ print LOGFH $0, " ", join( ' ', @SaveArgV );
+ print LOGFH "\nFAILING files:\n";
+}
+
+########################################################################
+## MAIN
+########################################################################
+# Loop through all files and process.
+foreach ( @Files )
+{
+
+ ## clear global vars
+ $DelimiterBegin = "";
+ $CopyrightBlock = "";
+ $DelimiterEnd = "";
+ $CopyRightString = "";
+ $rc = 0;
+
+
+ ## get filetype
+ my $filetype = filetype($_);
+ print STDOUT "File $_: Type $filetype\n";
+
+ ## set Temporary file name.
+ $TempFile = "$_.gitCPYWRT";
+ if ( $opt_debug ) { print STDERR __LINE__, ": Temporary file name = $TempFile\n"; }
+
+ ##
+ ## Special case is this file, just return 0 and add copyright manually.
+ ##
+ if ( m/addCopyright/ )
+ {
+ print STDOUT "---------------------------------------------------------\n";
+ print STDOUT "Skipping special case file: $_\n";
+ print STDOUT " Please add the copyright prolog manually.\n";
+ print STDOUT "---------------------------------------------------------\n";
+ next;
+ }
+
+ ##
+ ## Gerrit submissions can include deleted files, just warn and continue
+ if ( ! -e $_ )
+ {
+ print STDOUT "---------------------------------------------------------\n";
+ print STDOUT "Skipping deleted file: $_\n";
+ print STDOUT "---------------------------------------------------------\n";
+ next;
+ }
+
+ ##
+ ## Unknown files are valid, but should generate a warning.
+ if ("Unknown" eq $filetype)
+ {
+ print STDOUT "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+ print STDOUT "WARNING:: File $_ :Unknown Filetype: $filetype\n";
+ print STDOUT " Skipping this file and continuing.\n";
+ print STDOUT " Please add the copyright prolog manually.\n";
+ print STDOUT "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+
+ next;
+ }
+
+ ##
+ ## text files are valid, but should generate a warning.
+ if (("txt" eq $filetype) || "Initfile" eq $filetype)
+ {
+ print STDOUT "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+ print STDOUT "WARNING:: File $_ : Filetype: $filetype\n";
+ print STDOUT " Skipping this file and continuing.\n";
+ print STDOUT " If needed, Please add the copyright \n";
+ print STDOUT " prolog manually.\n";
+ print STDOUT "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+
+ next;
+ }
+
+ ##
+ ## Check if any parent directory below $projectRoot has a LICENSE_PROLOG file
+ ## Backtrack from the directory where the file lives and find the first
+ ## custom LICENSE_PROLOG file.
+ my $path = cwd."/".$_;
+ do
+ {
+ # Remove everything after last slash
+ $path =~ s|/[^/]*$||;
+ # Check if path has LICENSE_PROLOG file
+ my $custom_license_file = $path."/".LICENSE_PROLOG;
+ if (-e $custom_license_file)
+ {
+ # Set LicenseFile to closest custom LICENSE_PROLOG to file.
+ $LicenseFile = $custom_license_file;
+ # Exit loop, 'last' breaks out of both loops.
+ $path = $projectRoot;
+ }
+ } while ($path ne $projectRoot);
+
+ $CopyrightBlock = extractCopyrightBlock( $_ );
+
+ ##
+ ## validate the file.
+ ## if $logfile exists, print failing filename to $logfile and
+ ## keep going.
+ ## Otherwise, exit with $rc
+ ##
+ if ( $operation =~ m/validate/i )
+ {
+ $rc = validate( $_ );
+ if ( $rc )
+ {
+ print STDOUT "$_ FAILED copyright validation: $rc \n";
+ if ( $opt_logfile ne "" )
+ {
+ print LOGFH "$_ # FAILED $rc \n";
+ }
+ else
+ {
+ exit $rc;
+ }
+ }
+
+ ## continue to next file
+ next;
+ } ## endif validate
+
+ ##
+ ## update
+ ##
+ if ($operation =~ m/update/i)
+ {
+ $rc = update( $_, $filetype );
+ if ( $rc )
+ {
+ print STDOUT "$_ FAILED copyright update: $rc \n";
+ exit $rc;
+ }
+
+ ## continue to next file
+ next;
+ } ## endif update
+
+} # end foreach
+
+if ( $opt_logfile ne "" )
+{
+ close( LOGFH );
+}
+
+#########################################################################
+## Subroutines
+#########################################################################
+
+#######################################
+## usage: print usage and quit
+#######################################
+sub usage
+{
+ print STDOUT "Usage: addCopyright { update | validate } \n";
+ print STDOUT " [ --log-failed-files ]\n";
+ print STDOUT " [ --debug ] \n";
+ print STDOUT " file1 file2 ...\n";
+
+}
+
+#######################################
+## validate the file
+## param[in] $filename to validate
+## returns 0 success, nonzero failure
+## See constants above for values of failure
+#######################################
+sub validate
+{
+ my ( $filename ) = @_;
+ my $rc = 0;
+
+ if ( $CopyrightBlock eq "" )
+ {
+ print STDOUT "WARNING: No copyright block.\n";
+ return RC_NO_COPYRIGHT_BLOCK;
+ }
+
+ $rc = checkCopyrightBlock( $CopyrightBlock, $filename);
+
+ # good file
+ return $rc;
+}
+
+##
+## @sub update the copyright block.
+##
+## @param[in] filename
+## @param[in] filetype
+##
+## @return success or failure (currently only return success)
+##
+sub update
+{
+ my ( $filename, $filetype ) = @_;
+ my $olddelimiter = 0;
+ my $localrc = 0;
+ $localrc = validate( $filename );
+
+ if ( $localrc != 0 )
+ {
+ print STDOUT "Copyright Block check returned $localrc , fixing...\n";
+
+ if ( $localrc != RC_NO_COPYRIGHT_BLOCK )
+ {
+ if ( $opt_debug) { print STDERR __LINE__, ": remove old copyright block...\n"; }
+ removeCopyrightBlock( $filename, $filetype );
+ }
+
+ if ($opt_debug) { print STDERR __LINE__, ": Add empty copyright block...\n"; }
+ addEmptyCopyrightBlock( $filename, $filetype, $localrc );
+
+ if ( $opt_debug ) { print STDERR __LINE__, ": fill in new copyright block...\n"; }
+ fillinEmptyCopyrightBlock( $filename, $filetype);
+ }
+
+ ## return OK by default.
+ return 0;
+}
+
+
+#####################################
+## Analyze file and return a text string of the file type
+#####################################
+sub filetype
+{
+ my $filename = shift;
+ my $fileinfo = `file $filename | sed 's/^.*: //'`;
+ chomp $fileinfo;
+
+ # Sorted by anticipated frequency of occurrence.
+ if ( $filename =~ m/\.xml$/i )
+ # Added XML file to the top of the list because some comments in
+ # an XML file cause older versions of 'file' to incorrectly return
+ # "ASCII C++ program text" even though the file is obviously XML.
+ # Specifically we are seeing "<!-- // ..." cause this trouble.
+ {
+ return "xml"
+ }
+ if ( $filename =~ m/\.txt$/i )
+ {
+ return "txt"
+ }
+ if ( $filename =~ m/\.initfile$/i )
+ {
+ return "Initfile"
+ }
+ if ( ( $filename =~ m/\.[cht]$/i )
+ ||( $filename =~ m/\.[cht]\+\+$/i )
+ ||( $filename =~ m/\.[cht]pp$/i )
+ ||( $filename =~ m/\.inl$/ ) # inline C functions
+ ||( $filename =~ m/\.y$/ ) # yacc
+ ||( $filename =~ m/\.lex$/ ) # flex
+ ||( $fileinfo =~ m/c program text/i )
+ ||( $fileinfo =~ m/c\+\+ program text/i )
+ ||( $fileinfo =~ m/c source/i )
+ ||( $fileinfo =~ m/c\+\+ source/i )
+ )
+ {
+ return "C";
+ }
+ if ( ( $filename =~ m/\.pl$/ )
+ ||( $filename =~ m/\.perl$/ )
+ ||( $filename =~ m/\.pm$/ )
+ ||( $fileinfo =~ m/perl.*script.*text executable/i) )
+ {
+ return "Perl";
+ }
+ if ($filename =~ m/\.s$/i)
+ {
+ return "Assembly";
+ }
+ if (($filename =~ m/Makefile$/i) or
+ ($filename =~ m/\.mk$/i))
+ {
+ return "Makefile";
+ }
+ if ( $filename =~ m/\.am$/i )
+ {
+ return "Automake";
+ }
+ if ( ($filename =~ m/configure\.ac$/i)
+ ||($filename =~ m/Makefile\.in$/i) )
+ {
+ return "Autoconf";
+ }
+ if ( ( $filename =~ m/\.[kc]{0,1}sh$/i )
+ ||( $filename =~ m/\.bash$/i )
+ ||( $fileinfo =~ m/shell script/i )
+ ||( $fileinfo =~ m/^a \/bin\/[af]sh( -x|) *script text( executable|)$/ )
+ ||( $fileinfo eq "Bourne shell script text")
+ ||( $fileinfo eq "Bourne shell script text executable")
+ ||( $fileinfo eq "Bourne-Again shell script text")
+ ||( $fileinfo eq "Bourne-Again shell script text executable") )
+ {
+ return "Shellscript";
+ }
+ if ( $filename =~ m/\.py$/ )
+ {
+ return "Python";
+ }
+ if ( $filename =~ m/\.tcl$/ )
+ {
+ return "Tcl";
+ }
+ if ( $filename =~ m/\.x$/ )
+ {
+ return "RPC";
+ }
+ if ( ($filename =~ m/^commitinfo$/)
+ ||($filename =~ m/^checkoutlist$/)
+ ||($filename =~ m/^loginfo$/) )
+ {
+ return "CVS";
+ }
+ if ( $filename =~ m/\.emx$/ )
+ {
+ # Used by Rational Software Architect. modelling file.
+ return "EmxFile";
+ }
+ if ( $filename =~ m/\.mof$/ )
+ {
+ return "MofFile";
+ }
+ if ( $filename =~ m/\.ld$/ )
+ {
+ return "LinkerScript";
+ }
+ if ( $filename =~ m/\.rule$/i )
+ {
+ return "PrdRuleFile"
+ }
+ if ( ( $filename =~ m/\.emx$/i )
+ ||( $filename =~ m/\.odt$/i )
+ ||( $filename =~ m/\.gitignore$/i )
+ ||( $filename =~ m/\.conf$/i )
+ ||( $filename =~ m/\.lidhdr$/i )
+ ||( $filename =~ m/\.vpdinfo$/i )
+ ||( $filename =~ m/\.pdf$/i )
+
+ )
+ {
+ # Known, but we can't deal with it so call it unknown.
+ return "Unknown";
+ }
+ if ( -f $filename )
+ {
+ my $type = `grep "\\\$Filetype:.*\\\$" $filename`;
+ if ( $type =~ m/\$Filetype:([^\$]*)\$/ )
+ {
+ $type = $1;
+ }
+ $type =~ s/^\s*//;
+ $type =~ s/\s*$//;
+ my %knownTypes = qw/Assembly Assembly Automake Automake Autoconf Autoconf C C CVS CVS EmxFile EmxFile LinkerScript LinkerScript Makefile Makefile MofFile MofFile Perl Perl PrdRuleFile PrdRuleFile Python Python RPC RPC Shellscript Shellscript Tcl Tcl/;
+ return $type if defined($knownTypes{$type});
+ }
+ { # Other random files containing non-printable characters.
+ my $file = `cat $filename`;
+ if ( $file =~ m/([^\x20-\x7E\s])/ )
+ {
+ return "Unknown";
+ }
+ }
+ return "Unknown";
+}
+
+########################################################################
+## extractCopyrightBlock
+##
+## param[in] $infile - filename
+##
+## param[out] returns block or ""
+########################################################################
+sub extractCopyrightBlock
+{
+ my ( $infile ) = shift;
+
+ # Extract the prolog
+ my $prolog = `sed -n \"/$DELIMITER_BEGIN/,/$DELIMITER_END/p\" $infile`;
+ # Critical to remove newline for validate step
+ chomp($prolog);
+
+ ## As long as we're here extract the copyright string within the block
+ ## and save it to a global var
+ $CopyRightString = $1 if ( $prolog =~ /(^.*$copyrightStr.*$)/m );
+
+ return $prolog;
+}
+
+
+#######################################
+## Check Copyright Block
+##
+## @param[in] - Copyright block
+## @parma[in] - filename
+##
+## @return 0 if success, nonzero otherwise
+#######################################
+use File::Temp;
+sub checkCopyrightBlock
+{
+ my ( $block, $filename ) = @_;
+
+ ## Check if custom LICENSE_PROLOG
+ if ($LicenseFile ne "")
+ {
+ ## Get desired license
+ my $license_prolog = genCopyrightBlock($filename, filetype($filename));
+
+ if ($block ne $license_prolog)
+ {
+ # Print strings to files to use unix diff, do not need to add the
+ # File::Diff module this way.
+ my ($blockHndl, $blockFile) = File::Temp::tempfile();
+ my ($licenseHndl, $licenseFile)= File::Temp::tempfile();
+ print $blockHndl $block;
+ print $licenseHndl $license_prolog;
+ close($blockHndl);
+ close($licenseHndl);
+
+ print STDOUT "\nERROR> Prolog not correct for $filename.\n";
+ print STDOUT "To fix run: git show --pretty=\"format:\" --name-only | xargs addCopyright update\n";
+ print STDOUT "\nDiff:\n";
+ print STDOUT `diff $blockFile $licenseFile`;
+ my $relLicensePath = $LicenseFile;
+ $relLicensePath =~ s/$projectRoot//;
+ print STDOUT "\nWARNING: Copyright block does not match LICENSE_PROLOG file found at $relLicensePath\n";
+ system("rm -f $blockFile $licenseFile");
+ return RC_DIFFERS_FROM_LICENSE_PROLOG;
+ }
+ }
+ else
+ {
+ print STDOUT "WARNING: Missing LICNESE_PROLOG file in directory structure\n";
+ return RC_NO_LICENSE_PROLOG_FILE;
+ }
+
+ return 0;
+}
+
+sub createYearString
+{
+ my ( $filename ) = @_;
+ my $yearstr = "";
+ my @years = ();
+
+ ## Analyse the CopyRightString for begin and end years - this is for old
+ ## files that are checked in from FSP. In this case the earliest
+ ## year will be before it was checked into git . We have to construct
+ ## a yearstring based on the earliest year.
+ if ( $CopyRightString =~ m/$copyrightStr/ )
+ {
+ @years = ( $CopyRightString =~ /([0-9]{4})/g );
+ }
+ push @years, $ReleaseYear; # Add the current year.
+
+ ##
+ ## Make a call to git to find the earliest commit date of the file
+ ## new files will not have a log, so the "git log" call above will
+ # return nothing.
+ ## Push any year we find onto the @years array
+ my $cmd = "git log -- $filename | grep Date: | tail -n 1";
+ ## print "run $cmd\n";
+ my @logstrings = split( " ", `$cmd` );
+ if ( $? ) { die "ERROR $? : Could not run $cmd $!\n"; }
+
+ if ( scalar(@logstrings) >= 5 )
+ {
+ push @years, $logstrings[5] ;
+ }
+
+ ## sort and remove duplicates by loading it into a hash
+ my %temphash;
+ @temphash{@years} = ();
+ my @outyears = sort keys %temphash;
+
+ if ( $opt_debug )
+ { print STDERR __LINE__, ": years: ", join( ',', @outyears ), "\n"; }
+
+ ## lowest year, which may be the only one.
+ $yearstr = $outyears[0] ;
+
+ ## if there is more than one index then also output the highest one.
+ if ( $#outyears > 0 )
+ {
+ # A '-' is preferred but CMVC uses ',' so using ','.
+ $yearstr .= ",$outyears[$#outyears]";
+ }
+
+
+ return $yearstr;
+}
+
+###################################
+## Helper function for removeCopyrightBlock()
+###################################
+sub removeProlog
+{
+ my ( $data, $begin_re, $end_re ) = @_;
+
+ $data =~ s/(\n?)(.*?$begin_re.*$g_prolog_re(.|\n)*?$end_re.*?\n)/$1/;
+
+ return $data;
+}
+
+###################################
+## remove old Copyright Block in preparation for making a new one.
+## makes up a debug file named "<filename>.remove"
+###################################
+sub removeCopyrightBlock
+{
+ my ( $filename, $filetype ) = @_ ;
+ my $data = "" ;
+
+ ## Modify file in place with temp file Perl Cookbook 7.8
+ my $savedbgfile = "$filename.remove";
+ system( "cp -p $filename $TempFile" ); ## preserve file permissions
+ open( INPUT, "< $filename" ) or die " $? can't open $filename: $!" ;
+ read( INPUT, $data, -s INPUT ) or die "ERROR $? : reading $filename: $!";
+ close( INPUT ) or die " $? can't close $filename: $!" ;
+
+ open( OUTPUT, "> $TempFile" ) or die " $? can't open $TempFile: $!" ;
+ select( OUTPUT ); ## new default filehandle for print
+
+ ## preprocess to get rid of OLD_DELIMITER_END
+ $data =~ s/$OLD_DELIMITER_END(\s+?)/$DELIMITER_END$1/;
+
+ if ( "C" eq $filetype )
+ {
+ ## pre-process this for /* */ comments
+ $data = removeProlog( $data, '\/\*', '\*\/' );
+
+ ## Now apply filter for // comments
+ $data = removeProlog( $data, '\/\/', '' );
+ }
+ elsif ( ("RPC" eq $filetype) or
+ ("LinkerScript" eq $filetype)
+ )
+ {
+ $data = removeProlog( $data, '\/\*', '\*\/' );
+ }
+ elsif ( $filetype eq "xml" )
+ {
+ $data = removeProlog( $data, '<!--', '-->' );
+ }
+ elsif ( "Assembly" eq $filetype )
+ {
+ $data = removeProlog( $data, '\#', '' );
+ }
+ elsif ( ("Autoconf" eq $filetype) or
+ ("Automake" eq $filetype) or
+ ("CVS" eq $filetype) or
+ ("Makefile" eq $filetype) or
+ ("Perl" eq $filetype) or
+ ("PrdRuleFile" eq $filetype) or
+ ("Python" eq $filetype) or
+ ("Shellscript" eq $filetype) or
+ ("Tcl" eq $filetype)
+ )
+ {
+ # Don't wipe the the '#!' line at the top.
+ $data = removeProlog( $data, '\#', '' );
+ }
+ else
+ {
+ print STDOUT "ERROR: Don't know how to remove old block from $filetype file.\n";
+ close OUTPUT;
+ return RC_INVALID_FILETYPE;
+ }
+
+ print OUTPUT $data;
+
+ ## finish up the files
+ close( OUTPUT ) or die " $? can't close $TempFile: $!" ;
+ rename( $filename, "$savedbgfile" ) or die " $? can't rename $filename: $!" ;
+ rename( $TempFile, $filename ) or die " $? can't rename $TempFile: $!" ;
+ if ( !$opt_debug )
+ {
+ ## leave the files around for debug
+ unlink( $savedbgfile ) or die " $? can't delete $savedbgfile: $!";
+
+ }
+}
+
+###################################
+## Add an empty copyright block to the file, for example (C/C++ files):
+##
+## // IBM_PROLOG_BEGIN_TAG IBM_PROLOG_END_TAG
+##
+## - The block will be filled-in in the next step.
+##
+## @param[in] - filename to modify
+## @param[in] - filetype
+## @param[in] - returncode from validate
+##
+## @return none
+##
+## - Makes up a debug file called "<filename>.empty"
+##################################
+sub addEmptyCopyrightBlock
+{
+ my ( $filename, $filetype, $validaterc ) = @_;
+ my $line;
+
+ ## Modify file in place with temp file Perl Cookbook 7.8
+ my $savedbgfile = "$filename.empty";
+ system( "cp -p $filename $TempFile" ) ; ## preserve permissions
+ open( INPUT, "< $filename" ) or die " $? can't open $filename: $!" ;
+ open( OUTPUT, "> $TempFile" ) or die " $? can't open $TempFile: $!" ;
+ select( OUTPUT ); ## new default filehandle for print
+
+ if (("Autoconf" eq $filetype) or
+ ("Automake" eq $filetype) or
+ ("CVS" eq $filetype) or
+ ("Perl" eq $filetype) or
+ ("Python" eq $filetype) or
+ ("Shellscript" eq $filetype) or
+ ("Tcl" eq $filetype))
+ {
+ ## All files with a "shebang" at the beginning
+ $line = <INPUT>;
+ # Keep the '#!' line at the top.
+ ## The following says : if the first line is a "shebang" line
+ ## (e.g. "#!/usr/bin/perl"), then print it _before_ the copyright
+ ## block, otherwise (the unless line), print it _after_ the copyright
+ ## block.
+ if ($line =~ m/^#!/)
+ {
+ print OUTPUT $line;
+ }
+ print OUTPUT "$DELIMITER_BEGIN $DELIMITER_END\n";
+ unless ($line =~ m/^#!/)
+ {
+ print OUTPUT $line;
+ }
+ }
+ else
+ {
+ print OUTPUT "$DELIMITER_BEGIN $DELIMITER_END\n";
+ }
+
+ # Copy rest of file
+ while (defined($line = <INPUT>))
+ {
+ print OUTPUT $line;
+ }
+
+ ## finish up the files
+ close( INPUT ) or die " $? can't close $filename: $!" ;
+ close( OUTPUT ) or die " $? can't close $TempFile: $!" ;
+ rename( $filename, "$savedbgfile" ) or die " $? can't rename $filename: $!" ;
+ rename( $TempFile, $filename ) or die " $? can't rename $TempFile: $!" ;
+ if ( !$opt_debug )
+ {
+ ## leave the files around for debug
+ unlink( $savedbgfile ) or die " $? can't delete $savedbgfile: $!";
+ }
+}
+
+############################################
+## Helper functions for fillinEmptyCopyrightBlock()
+############################################
+sub addPrologComments
+{
+ my ( $data, $begin, $end ) = @_;
+
+ my @lines = split( /\n/, $data );
+
+ $data = '';
+ for my $line ( @lines )
+ {
+ # If there is an block comment end tag, fill the end of the line with
+ # spaces.
+ if ( $end )
+ {
+ my $max_line_len = 70;
+ my $len = length($line);
+ if ( $len < $max_line_len )
+ {
+ my $fill = ' ' x ($max_line_len - $len);
+ $line .= $fill;
+ }
+ }
+
+ # NOTE: CMVC prologs with inline comments will have a single trailing
+ # space at the end of the line. This is undesirable for most
+ # developers so it will not be added.
+ if ( $line =~ m/$DELIMITER_BEGIN/)
+ {
+ $line = "$line $end" if ( $end );
+ $line = "$begin $line\n";
+ }
+ elsif ( $line =~ m/$DELIMITER_END/ )
+ {
+ $line = "$line $end" if ( $end );
+ $line = "$begin $line";
+ }
+ else
+ {
+ if ( not $end and not $line )
+ {
+ # Compensate for blank lines with no end delimeter.
+ $line = "$begin\n";
+ }
+ else
+ {
+ $line = "$begin $line";
+ $line = "$line $end" if ( $end );
+ $line = "$line\n";
+ }
+ }
+
+ $data .= $line;
+ }
+
+ return $data;
+}
+
+############################################
+## Generates final copyright block
+##
+## @parma[in] filename
+##
+## @return final copyright block string
+############################################
+sub genCopyrightBlock
+{
+ my ($filename, $filetype) = @_;
+
+ my $copyrightYear = createYearString( $filename );
+
+ # Get copyright contributors based on hash so no duplicates
+ my %fileContributors = getFileContributors( $filename );
+ my $copyright_Contributors = "";
+
+ foreach my $key (sort keys %fileContributors)
+ {
+ $copyright_Contributors .= "[+] ".$key."\n";
+ }
+
+ ## Get desired license
+ my $LicenseContent = "";
+ open(LICENSE, "< $LicenseFile") or die " $? can't open $LicenseFile: $!" ;
+ while (my $line = <LICENSE>)
+ {
+ my $evalLine = eval "qq($line)";
+ $LicenseContent .= $evalLine;
+ }
+ close(LICENSE);
+
+ ## define the final copyright block template here.
+ my $IBMCopyrightBlock = <<EOF;
+$DELIMITER_BEGIN
+$LicenseContent
+$DELIMITER_END
+EOF
+
+ if ("Assembly" eq $filetype)
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '#', '');
+ }
+ elsif ( ("Makefile" eq $filetype) or
+ ("PrdRuleFile" eq $filetype) )
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '#', '');
+ }
+ elsif (("Autoconf" eq $filetype) or
+ ("Automake" eq $filetype) or
+ ("CVS" eq $filetype) or
+ ("Perl" eq $filetype) or
+ ("Python" eq $filetype) or
+ ("Shellscript" eq $filetype) or
+ ("Tcl" eq $filetype))
+ {
+ ## all files with a "shebang"
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '#', '');
+ }
+ elsif ( "C" eq $filetype )
+ {
+ ## lex files are classified as C, but do not recognize '//' comments
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '/*', '*/');
+ }
+ elsif ( ("RPC" eq $filetype) or
+ ("LinkerScript" eq $filetype)
+ )
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '/*', '*/');
+ }
+ elsif ("EmxFile" eq $filetype)
+ {
+ # Not yet formatted correctly for EmxFile needs, but should coexist.
+ $IBMCopyrightBlock = "$DELIMITER_BEGIN IBM Confidential OCO Source Materials (C) Copyright IBM Corp. $copyrightYear The source code for this program is not published or otherwise divested of its trade secrets, irrespective of what has been deposited with the U.S. Copyright Office. $DELIMITER_END";
+ }
+ elsif ("MofFile" eq $filetype)
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '//', '');
+ }
+ elsif ( "xml" eq $filetype)
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '<!--', '-->');
+ }
+ else
+ {
+ print STDOUT "ERROR: Can\'t handle filetype: $filetype\n";
+ return RC_INVALID_FILETYPE;
+ }
+
+ return $IBMCopyrightBlock;
+}
+
+############################################
+## fill in the empty copyright block
+## Copyright guidelines from:
+## FSP ClearCase Architecture
+## Version 1.9
+## 10/12/2010
+## Editor: Alan Hlava
+##
+## Section 3.14.1 has templates for different files
+##
+############################################
+sub fillinEmptyCopyrightBlock
+{
+ my ( $filename, $filetype ) = @_;
+
+ my $copyrightYear = createYearString( $filename );
+
+ ## define the final copyright block template here.
+ my $IBMCopyrightBlock = genCopyrightBlock($filename,$filetype);
+
+ ## Modify file in place with temp file Perl Cookbook 7.8
+ my $savedbgfile = "$filename.fillin";
+ system( "cp -p $filename $TempFile" ); ## preserve file permissions
+ open( INPUT, "< $filename" ) or die " $? can't open $filename: $!" ;
+ my $newline;
+ my $lines = "";
+ while ( defined($newline = <INPUT>) ) { $lines .= $newline; }
+
+ # Replace existing block with the current content.
+ $lines =~ s/$DELIMITER_BEGIN[^\$]*$DELIMITER_END/$IBMCopyrightBlock/s;
+
+ open( OUTPUT, "> $TempFile" ) or die " $? can't open $TempFile: $!" ;
+ select( OUTPUT ); ## new default filehandle for print
+ print OUTPUT $lines;
+
+ ## finish up the files
+ close( INPUT ) or die " $? can't close $filename: $!" ;
+ close( OUTPUT ) or die " $? can't close $TempFile: $!" ;
+ rename( $filename, "$savedbgfile" ) or die " $? can't rename $filename: $!" ;
+ rename( $TempFile, $filename ) or die " $? can't rename $TempFile: $!" ;
+ if ( !$opt_debug )
+ {
+ ## leave the files around for debug
+ unlink( $savedbgfile ) or die " $? can't delete $savedbgfile: $!";
+ }
+}
+
+#######################################
+## Gets file contirbutors based on git log of a file
+##
+## @parma[in] filename
+##
+## @return hash of contributors (key,value) => (name/company, 1)
+#######################################
+sub getFileContributors
+{
+ my ( $filename ) = @_;
+ # Create a "set like" hash for file contributors to handle duplicates
+ # so key is the only important information
+ my %fileContributors = ();
+
+ # Check file for company Origin
+ my $gitDomain = `git log --follow --find-copies-harder -C85% -M85% -- $filename | grep Origin: | sort | uniq`;
+ my @gitDomain = split('\n', $gitDomain);
+ foreach my $origin (@gitDomain)
+ {
+ chomp($origin);
+ # Remove all characters through word "Origin:"
+ $origin =~ s/[^:]*\://;
+ # Remove white space after colon
+ $origin =~ s/^\s+//;
+ if (exists($fileContributorsCompany{$origin}))
+ {
+ # Add company info for copyright contribution
+ $fileContributors{$fileContributorsCompany{$origin}} = 1;
+ }
+ }
+
+ # Check file for all contributors
+ my $gitAuthors = `git log --follow --find-copies-harder -C85% -M85% --pretty="%aN <%aE>" -- $filename | sort | uniq`;
+ my @gitAuthors = split('\n', $gitAuthors);
+
+ # Get commit's author
+ # # If running copyright_check run 'git log' as a commit is not taking place
+ # # Else we currently have no way of getting the current author. Because
+ # # this is a pre-commit hook, the commit staged to be committed does not
+ # # show up in 'git log' until commit has completed. We cannot look up
+ # # current user's info because the user pushing the commit may not be
+ # # the author.
+
+ if($copyright_check)
+ {
+ my $curAuthorEmail = `git log -n1 --pretty=format:"%aN <%aE>"`;
+ chomp($curAuthorEmail);
+ push(@gitAuthors, $curAuthorEmail);
+ }
+ # Internal mirror, add IBM as contributor
+ elsif (defined $ENV{'MIRROR'})
+ {
+ push(@gitAuthors, "\@ibm.com>");
+ }
+
+ foreach my $contributor (@gitAuthors)
+ {
+ my $companyExists = 0;
+ chomp($contributor);
+ # Grab company domain out of contributor's email
+ my $domain = substr ($contributor, index($contributor, '@') + 1, -1);
+
+ # Due to multiple prefixes for IBM like us, in, linux, etc will try
+ # removing characters up to each period (.) until correct domain
+ # address found
+ my @domainSections = split(/\./,$domain);
+ for (my $i = 0; $i < @domainSections; $i++)
+ {
+ if (exists($fileContributorsCompany{$domain}))
+ {
+ $companyExists = 1;
+ last;
+ }
+ # Remove all characters upto & including the first period (.) seen
+ $domain =~ s/[^.]*\.//;
+ }
+
+ #Check if contributor's company exists
+ if ($companyExists)
+ {
+ # Add company info for copyright contribution
+ $fileContributors{$fileContributorsCompany{$domain}} = 1;
+ }
+ else
+ {
+ my $name = substr ($contributor, 0, index($contributor, '<') -1);
+ if($name)
+ {
+ # Add individual info for copyright contribution
+ $fileContributors{$name} = 1;
+ }
+ else
+ {
+ die("Cannot find name of contributor in git commit");
+ }
+ }
+ }
+ return %fileContributors;
+}
diff --git a/src/tools/hooks/gerrit-hostname b/src/tools/hooks/gerrit-hostname
new file mode 100755
index 00000000..58c68d63
--- /dev/null
+++ b/src/tools/hooks/gerrit-hostname
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/gerrit-hostname $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+## Usage
+# It is imperative that there are no prints other than the die command or
+# "export GERRIT_SRV=$host" as this script is evaluated by env.bash and not
+# called directly
+
+use strict;
+
+my $homeDir = $ENV{'HOME'};
+my $sshConfigFile = $homeDir."/.ssh/config";
+# If the server changes location these will change
+my $gerritHostname = "ralgit01.raleigh.ibm.com";
+my $gerritPort = "29418";
+
+open(CONFIG, "< $sshConfigFile") or die " $? can't open $sshConfigFile: $!" ;
+
+my $host = "";
+my $hostname = "";
+my $port = "";
+while (my $line = <CONFIG>)
+{
+ # Whitespace after each constant is important
+ if ($line =~ m/^Host [^\s]/)
+ {
+ ($host) = $line =~ m/^Host (.*?)\s/
+ }
+ elsif ($line =~ m/Hostname [^\s]/)
+ {
+ ($hostname) = $line =~ m/^*Hostname (.*)/;
+ }
+ elsif ($line =~ m/Port [^\s]/)
+ {
+ ($port) = $line =~ m/^*Port (.*)/;
+ }
+
+ # Check if we found the gerrit host name
+ if ($host ne "" &&
+ $hostname eq $gerritHostname &&
+ $port eq $gerritPort)
+ {
+ last;
+ }
+}
+close(CONFIG);
+
+if ($host eq "")
+{
+ die "Error> Could not find gerrit host in $sshConfigFile";
+}
+else
+{
+ # Set gerrit server env variable by returning command to env.bash
+ print "export GERRIT_SRV=$host\n";
+}
diff --git a/src/tools/hooks/post-commit b/src/tools/hooks/post-commit
new file mode 100755
index 00000000..21751582
--- /dev/null
+++ b/src/tools/hooks/post-commit
@@ -0,0 +1,32 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/post-commit $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+# NOTE: pre-commit hook and its associated helper functions are all
+# maintained same as that of Hoostboot except for minor changes to
+# suit the PPE environment.
+
+if [ -z $MIRROR ]; then
+ $TOOLSDIR/verify-commit
+fi
diff --git a/src/tools/hooks/pre-commit b/src/tools/hooks/pre-commit
new file mode 100755
index 00000000..9e05432f
--- /dev/null
+++ b/src/tools/hooks/pre-commit
@@ -0,0 +1,38 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/pre-commit $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+# NOTE: pre-commit hook and its associated helper functions are all
+# maintained same as that of Hoostboot except for minor changes to
+# suit the PPE environment.
+
+if [ -f $TOOLSDIR/pre-commit-actions ]; then
+ $TOOLSDIR/pre-commit-actions
+# Legacy support for older releases
+elif [ -f $TOOLSDIR/pre-commit-prologs ]; then
+ $TOOLSDIR/pre-commit-prologs
+else
+ echo "Missing pre-commit files"
+ exit -1
+fi
diff --git a/src/tools/hooks/pre-commit-actions b/src/tools/hooks/pre-commit-actions
new file mode 100755
index 00000000..821e78de
--- /dev/null
+++ b/src/tools/hooks/pre-commit-actions
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/pre-commit-actions $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+# This hook is used to add or update copyright prolog statements and run
+# the code beautifier astyle.
+
+my $copyrightScript = "addCopyright";
+
+## Make up a list of all staged files ( --cached --name-only )
+## Filter for only Added or Modified ( --diff-filter=AM )
+chomp( my @fileList = `git diff --cached --name-only --diff-filter=AM` );
+
+
+if ( @fileList )
+{
+ print "run $copyrightScript update ...\n";
+ print " $_\n" foreach @fileList;
+ print "\n";
+
+ system "$ENV{'TOOLSDIR'}/$copyrightScript update @fileList";
+ die("$?") if ($? != 0);
+
+ system "git add @fileList";
+ exit 1 if ($? != 0);
+}
+
+exit 0;
diff --git a/src/tools/hooks/pre-commit-prologs b/src/tools/hooks/pre-commit-prologs
new file mode 100755
index 00000000..eb53e316
--- /dev/null
+++ b/src/tools/hooks/pre-commit-prologs
@@ -0,0 +1,46 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/pre-commit-prologs $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+# This hook is used to add or update copyright prolog statements
+
+my $script = "addCopyright";
+
+## Make up a list of all staged files ( --cached --name-only )
+## Filter for only Added or Modified ( --diff-filter=AM )
+chomp( my @fileList = `git diff --cached --name-only --diff-filter=AM` );
+
+if ( @fileList )
+{
+ print "run $script update ...\n";
+ print " $_\n" foreach @fileList;
+ print "\n";
+
+ system "$ENV{'TOOLS_DIR'}/$script update @fileList";
+ die("$?") if ($? != 0);
+
+ system "git add @fileList";
+ exit 1 if ($? != 0);
+}
+
+exit 0;
diff --git a/src/tools/hooks/setupgithooks.sh b/src/tools/hooks/setupgithooks.sh
new file mode 100755
index 00000000..ae38b253
--- /dev/null
+++ b/src/tools/hooks/setupgithooks.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/setupgithooks.sh $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+# Each developer runs this from the git_repo base dir, where it will copy the
+# needed scripts into .git/hooks/ directory and make them executable.
+
+if [ -d $HOOKSDIR ]
+then
+
+ # Get hooks from Gerrit, if needed.
+ if [ ! -f $HOOKSDIR/commit-msg ]
+ then
+ echo "Copying Gerrit hooks..."
+ scp -p -q $GERRIT_SRV:hooks/commit-msg $HOOKSDIR
+ fi
+
+ # Copy custom pre/post commit hooks from tools directory.
+ if [ -f "$TOOLSDIR/pre-commit" -a \
+ -f "$TOOLSDIR/post-commit" ]
+ then
+ echo "Copying pre/post commit hooks..."
+
+ cp $TOOLSDIR/pre-commit $HOOKSDIR/
+ cp $TOOLSDIR/pre-commit $HOOKSDIR/pre-applypatch
+ cp $TOOLSDIR/post-commit $HOOKSDIR/
+
+ chmod u+x $HOOKSDIR/pre-commit
+ chmod u+x $HOOKSDIR/pre-applypatch
+ chmod u+x $HOOKSDIR/post-commit
+
+ else
+ echo "Cannot find or access pre or post commit scripts"
+ exit 1
+ fi
+
+else
+ echo "Cannot find or access .git/hooks directory"
+ exit 1
+fi
+
+exit 0
diff --git a/src/tools/hooks/verify-commit b/src/tools/hooks/verify-commit
new file mode 100755
index 00000000..68beebf5
--- /dev/null
+++ b/src/tools/hooks/verify-commit
@@ -0,0 +1,358 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/verify-commit $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+use strict;
+
+my $issueFound = 0;
+my $errorFound = 0;
+
+my $projectName = $ENV{'PROJECT_NAME'};
+# Relative path of import tree from project root
+my $importPrefix = $ENV{'IMPORT_REL_PATH'}."/";
+
+verifyPatchSet(); # Verify the patch contents.
+verifyCommitMsg(); # Verify the commit message.
+
+# Finish out the divider.
+if ($issueFound)
+{
+ print "------------------------------------------------------------\n";
+}
+
+# Return a bad RC if we found an error. Let warnings pass.
+exit ($errorFound ? -1 : 0);
+
+
+########################### Subroutines ################################
+
+# @sub verifyPatchSet
+#
+# Extract the contents (lines changed) from the patch set and verify.
+#
+sub verifyPatchSet
+{
+ # git-diff options:
+ # * Diff against the previous commit (HEAD~1)
+ # * Filter only added and modified files (AM).
+ # * Show only the lines changed, with no context (U0).
+ # Grep only the lines marked with "+" (instead of "-") to find just the
+ # actions done by this patchset and not the content removed.
+ open PATCH_CONTENTS, "git diff HEAD~1 --diff-filter=AM -U0 | ".
+ "grep -e \"^+\" -e \"^@@.*+[0-9]\\+\" |";
+
+ my %fileContents = ();
+
+ my $lastFile = "";
+ my $fileLines = ();
+ my $lineCount = 0;
+ while (my $line = <PATCH_CONTENTS>)
+ {
+ chomp $line;
+
+ # Line starting with "+++ b/path/to/file" indicate a new file.
+ if ($line =~ m/^\+\+\+ b\/(.*)/)
+ {
+ # Save previous file into the map.
+ if ($lastFile ne "")
+ {
+ $fileContents{$lastFile} = $fileLines;
+ $fileLines = ();
+ $lineCount = 0;
+ }
+ $lastFile = $1;
+ }
+ # Lines starting with "@@" indicates a seek in the file, so update
+ # line numbers.
+ elsif ($line =~ m/^@@.*\+([0-9]+)/)
+ {
+ $lineCount = $1 - 1;
+ }
+ else
+ {
+ $line =~ s/^\+//; # filter off the leading + symbol.
+ $lineCount++;
+ push @{$fileLines}, [$line, $lineCount];
+ }
+ }
+ if ($lastFile ne "") # Save last file into the map.
+ {
+ $fileContents{$lastFile} = $fileLines;
+ $fileLines = ();
+ }
+
+ # Verify each line of each file.
+ foreach my $file (sort keys %fileContents)
+ {
+ foreach my $line (@{$fileContents{$file}})
+ {
+ verifyFileLine($file, @{$line}[0], @{$line}[1]);
+ }
+ }
+}
+
+# @sub verifyFileLine
+#
+# Checks a particular line of the file for the following issues:
+# * Warning: Lines longer than 80 characters, except in trace statement.
+# * Warning: Trailing whitespace.
+# * Warning: Tab characters outside of makefiles.
+# * Warning: TODO or FIXME type tag without a corresponding RTC number.
+# * Warning: NOMERGE tag found.
+#
+sub verifyFileLine
+{
+ my ($file,$line,$count) = @_;
+
+ # Check if file was mirrored
+ my $mirror = 0;
+ if ($file =~ m/^$importPrefix/)
+ {
+ $mirror = 1;
+ }
+
+ # Check line length.
+ if (length($line) > 80)
+ {
+ # Allow trace statements to slide.
+ if (($line =~ m/TRAC[DSFU]/) ||
+ ($line =~m/TS_FAIL/) ||
+ ($line =~m/printk/) ||
+ ($line =~m/displayf/) ||
+ ($line =~ m/FAPI_(INF|IMP|ERR|DBG|SCAN)/))
+ {
+ }
+ else
+ {
+ warning($file,$line,$count,
+ (sprintf "Length is more than 80 characters (%d).",
+ length($line))
+ );
+ }
+ }
+
+ # Check trailing whitespace.
+ if ($line =~ m/\s$/)
+ {
+ warning($file,$line,$count,
+ "Trailing whitespace found.");
+ }
+
+ # Check tabs.
+ if ($line =~ m/\t/)
+ {
+ # Makefiles are ok (require tabs).
+ if (not (($file =~ m/makefile/) || ($file =~ m/\.mk/)))
+ {
+ warning($file,$line,$count,
+ "Tab character found.");
+ }
+ }
+
+ # Check "TODO" or "FIXME" type comments.
+ if (($line =~ m/TODO/i) || ($line =~ m/FIXME/i))
+ {
+ if ( (not ($line =~ m/RTC[\s:]\s*[0-9]+/)) &&
+ (not ($line =~ m/CQ[\s:]\s*[A-Z][A-Z][0-9]+/)))
+ {
+ warning($file,$line,$count,
+ "TODO/FIXME tag without corresponding RTC or CQ number.");
+ }
+ }
+
+ # Check "NOMERGE" type comment.
+ if ($line =~ m/NOMERGE/i)
+ {
+ warning($file,$line,$count,
+ "NOMERGE tag found.");
+ }
+
+ # Check for "Confidential", unless it's a mirrored commit
+ if ($line =~ m/Confidential/i && $projectName =~ m/HostBoot/i && !$mirror)
+ {
+ unless (($file =~ m/verify-commit/) ||
+ ($file =~ m/addCopyright/))
+ {
+ error($file,$line,$count,
+ "File contains 'Confidential'.");
+ }
+ }
+}
+
+# @sub verifyCommitMsg
+#
+# Looks at the commit message to verify the following items:
+# * Topic is exactly 1 line long.
+# * Lines are less than 80 characters.
+# * No trailing whitespace.
+# * Tags, such as 'RTC:', are only found in the footer.
+# * Untagged lines are not found in the footer.
+# * RTC tag is formatted correctly.
+# * Warning for lacking RTC tag.
+#
+sub verifyCommitMsg
+{
+ open COMMIT_CONTENTS, "git log -n1 --pretty=format:%B |";
+ my $lineCount = 0;
+ my $rtcTag = "";
+ my $cqTag = "";
+ my $taggedLine = "";
+ my $untaggedLine = "";
+
+ while (my $line = <COMMIT_CONTENTS>)
+ {
+ $lineCount++;
+ chomp $line;
+
+ # Check line length over 80 characters.
+ if (length($line) > 80)
+ {
+ error("Commit Message",$line,$lineCount,
+ (sprintf "Length is more than 80 characters (%d).",
+ length($line))
+ );
+ }
+
+ # Check trailing whitespace.
+ if ($line =~ m/[^\s]+\s$/)
+ {
+ error("Commit Message",$line,$lineCount,
+ "Trailing whitespace found.");
+ }
+
+ # Blank line indicates a new "section".
+ if ($line =~ m/^$/)
+ {
+ # Check for tags outside of the footer.
+ # (new section implies previous section was not a footer)
+ if ("" ne $taggedLine)
+ {
+ error("Commit Message",$taggedLine,$lineCount,
+ "Tagged line found outside commit-msg footer.");
+ }
+
+ $rtcTag = "";
+ $cqTag = "";
+ $untaggedLine = "";
+ $taggedLine = "";
+ }
+ else
+ {
+ # Check for multi-line topic.
+ if ($lineCount == 2)
+ {
+ error("Commit Message",$line,$lineCount,
+ "Topic must be only one line long.");
+ }
+ }
+
+ # Verify format of RTC message.
+ if ($line =~ m/^\s*RTC:\s*[0-9]+(.*)/)
+ {
+ if ("" ne $rtcTag)
+ {
+ error("Commit Message",$line,$lineCount,
+ "Duplicate RTC tag found.");
+ }
+
+ $rtcTag = $line;
+ if ("" ne $1)
+ {
+ error("Commit Message",$line,$lineCount,
+ (sprintf "RTC tag format incorrect (%s).", $1));
+ }
+ }
+
+ if ($line =~ m/^\s*CQ:\s*[A-Z][A-Z][0-9]+(.*)/)
+ {
+ if ("" ne $cqTag)
+ {
+ error("Commit Message",$line,$lineCount,
+ "Duplicate CQ tag found.");
+ }
+
+ $cqTag = $line;
+ if ("" ne $1)
+ {
+ error("Commit Message",$line,$lineCount,
+ (sprintf "CQ tag format incorrect (%s).", $1));
+ }
+ }
+
+ # Identify if this is a tagged line or a non-tagged line and store
+ # away.
+ if ($line =~ m/^\s*[A-Za-z0-9\-_]+:[^:]/)
+ {
+ # We allow lines that look like tags in the topic like...
+ # "FOO: Adding support for BAR."
+ if ($lineCount > 1)
+ {
+ $taggedLine = $line;
+ }
+ }
+ else
+ {
+ $untaggedLine = $line;
+ }
+ }
+
+ # Warn for missing RTC tag.
+ if (("" eq $rtcTag) && ("" eq $cqTag))
+ {
+ warning("Commit Message","<end-of-file>",$lineCount,
+ "Neither RTC nor CQ tag found.");
+ }
+
+ # Error for a mix of tag / untagged in the last section (ie. untagged
+ # lines in the footer).
+ if (("" ne $untaggedLine) && ("" ne $taggedLine))
+ {
+ error("Commit Message",$untaggedLine,$lineCount,
+ "Untagged line found in footer.");
+ }
+}
+
+sub warning
+{
+ my ($file, $line, $count, $statement) = @_;
+ print "------------------------------------------------------------\n";
+ print "WARNING: $statement\n";
+ print " $file:$count\n";
+ print " $line\n";
+
+ $issueFound = 1;
+}
+
+sub error
+{
+ my ($file, $line, $count, $statement) = @_;
+ print "------------------------------------------------------------\n";
+ print "ERROR: $statement\n";
+ print " $file:$count\n";
+ print " $line\n";
+
+ $issueFound = 1;
+ $errorFound = 1;
+}
+
diff --git a/src/tools/image/Makefile b/src/tools/image/Makefile
new file mode 100644
index 00000000..fab89e66
--- /dev/null
+++ b/src/tools/image/Makefile
@@ -0,0 +1,86 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/image/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+#
+# utilities : Build utility programs and procedures
+#
+# clean : Removes generated files
+#
+
+############################################################################
+include img_defs.mk
+
+# 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
+CXX = g++
+endif
+
+UTILITIES-SOURCES = sbe_default_tool.c
+UTILITIES = sbe_default_tool
+
+# Utility targets
+UTILITIES-OBJc = $(patsubst %.c,$(BASE_OBJDIR)/%.o,$(UTILITIES-SOURCES))
+UTILITIES-OBJECTS += $(patsubst %.C,$(BASE_OBJDIR)/%.o,$(UTILITIES-OBJc))
+UTILITIES-DEPENDENCIES = $(patsubst %.o,%.d,$(UTILITIES-OBJECTS))
+UTILITIES-EXECUTABLES = $(patsubst %,$(BASE_OBJDIR)/%,$(UTILITIES))
+
+.PHONY : all utilities clean
+
+all: utilities
+
+utilities: $(UTILITIES-EXECUTABLES)
+
+CXXFLAGS+=-DFAPI2_NO_FFDC
+
+$(BASE_OBJDIR)/%.o: %.c
+ $(CXX) -std=c++11 $(INCLUDES) $(CXXFLAGS) -c -o $@ $<
+
+$(BASE_OBJDIR)/sbe_default_tool: $(P9_XIP_BINDIR)/p9_xip_image.o $(BASE_OBJDIR)/sbe_default_tool.o
+ $(CXX) $(CXXFLAGS) ${INCLUDES} -o $@ $^
+
+clean:
+ rm -f $(BASE_OBJDIR)/sbe_default_tool*
diff --git a/src/tools/image/sbe_default_tool.c b/src/tools/image/sbe_default_tool.c
new file mode 100644
index 00000000..ae2bbf53
--- /dev/null
+++ b/src/tools/image/sbe_default_tool.c
@@ -0,0 +1,310 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/image/sbe_default_tool.c $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 P9-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"
+#include "p9_xip_image.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_SYSTEM: system target\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_SYSTEM") == 0 || (strcmp(str, "TARGET_TYPE_PROC_CHIP") == 0)) {
+ if (index > 0) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than 0\n", index);
+ exit(1);
+ }
+ } else if(strcmp(str, "TARGET_TYPE_EX") == 0) {
+ if (index > EX_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than EX_TARGET_COUNT (%d)\n",
+ index, EX_TARGET_COUNT);
+ exit(1);
+ }
+ } else if(strcmp(str, "TARGET_TYPE_EQ") == 0) {
+ if (index > EQ_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than EQ_TARGET_COUNT (%d)\n",
+ index, EQ_TARGET_COUNT);
+ exit(1);
+ }
+ } else if(strcmp(str, "TARGET_TYPE_CORE") == 0) {
+ if (index > CORE_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than CORE_TARGET_COUNT (%d)\n",
+ index, CORE_TARGET_COUNT);
+ exit(1);
+ }
+ } else if(strcmp(str, "TARGET_TYPE_PERV") == 0) {
+ if (index > PERV_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than PERV_TARGET_COUNT (%d)\n",
+ index, PERV_TARGET_COUNT);
+ exit(1);
+ }
+ } else {
+ if (index >= PERV_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: target not supported:");
+ fprintf(stderr, " %s\n", str);
+ exit(1);
+ }
+ }
+ return;
+}
+
+void setAttribute(void* image, const char* attribute, unsigned int index, uint64_t val) {
+
+
+ P9XipItem item;
+ void *thePointer;
+ int rc;
+
+ rc = p9_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 index: %2d 0x%x\n", item.iv_address, index, index);
+
+ p9_xip_image2host(image, item.iv_address, &thePointer);
+
+ // debug purpose
+ //printf("pointer1: 0x%x val: 0x%llx \n", thePointer, val);
+
+ if(item.iv_toc->iv_type == P9_XIP_UINT8) {
+
+ *((uint8_t*)thePointer + index) = (uint8_t)val;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT8) {
+
+ *((int8_t*)thePointer + index) = (int8_t)val;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT16) {
+
+ *((uint16_t*)thePointer + index) = htobe16((uint16_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT16) {
+
+ *((int16_t*)thePointer + index) = htobe16((int16_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT32) {
+
+ *((uint32_t*)thePointer + index) = htobe32((uint32_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT32) {
+
+ *((int32_t*)thePointer + index) = htobe32((int32_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT64) {
+
+ *((uint64_t*)thePointer + index) = htobe64((uint64_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT64) {
+
+ *((int64_t*)thePointer + index) = htobe64((int64_t)val);
+
+ } else {
+ fprintf(stderr, "sbe_default_tool: type not available");
+ exit(1);
+ }
+
+
+
+
+ P9_XIP_SECTION_NAMES(section_name);
+ P9_XIP_TYPE_STRINGS(type_name);
+
+ // debug purpose
+ //printf("pointer2: 0x%x \n", thePointer + index);
+ //printf("elements: %d \n", item.iv_elements);
+ //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;
+
+ P9XipItem item;
+ void *thePointer;
+ int rc;
+
+ rc = p9_xip_find(image, attribute, &item);
+ if (rc) {
+ fprintf(stderr, "sbe_default_tool: attribute not existing:");
+ fprintf(stderr, " %s", attribute);
+ exit(1);
+ }
+
+ p9_xip_image2host(image, item.iv_address, &thePointer);
+
+ if(item.iv_toc->iv_type == P9_XIP_UINT8) {
+
+ val = *((uint8_t*)thePointer + index);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT8) {
+
+ val = *((int8_t*)thePointer + index);
+ val &= 0xFF;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT16) {
+
+ val = htobe16(*((uint16_t*)thePointer + index));
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT16) {
+
+ val = htobe16(*((int16_t*)thePointer + index));
+ val &= 0xFFFF;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT32) {
+
+ val = htobe32(*((uint32_t*)thePointer + (index)));
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT32) {
+
+ val = htobe32(*((int32_t*)thePointer + index));
+ val &= 0xFFFFFFFF;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT64) {
+
+ val = htobe64(*((uint64_t*)thePointer + index));
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT64) {
+
+ val = htobe64(*((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/tools/ppetracepp/Makefile b/src/tools/ppetracepp/Makefile
new file mode 100644
index 00000000..eec6da6a
--- /dev/null
+++ b/src/tools/ppetracepp/Makefile
@@ -0,0 +1,37 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/ppetracepp/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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 img_defs.mk
+
+all: ppetracepp ppe2fsp
+
+ppetracepp: ppetracepp.C
+ g++ -m32 -O3 -w -g -I./ ppetracepp.C -o $(PPETRACEPP_BIN_DIR)/ppetracepp
+# g++ -O3 -w -x c++ -fPIC -g -I./ ppetracepp.C -o ppetracepp
+
+ppe2fsp: ppe2fsp.c ppe2fsp_cmd.c
+ gcc -m32 -w -g -I./ -I$(PK_SRCDIR)/trace ppe2fsp.c ppe2fsp_cmd.c -o $(PPETRACEPP_BIN_DIR)/ppe2fsp
+
+clean:
+ rm $(PPETRACEPP_BIN_DIR)/ppetracepp $(PPETRACEPP_BIN_DIR)/ppe2fsp
+
diff --git a/src/tools/ppetracepp/cmvc/makefile b/src/tools/ppetracepp/cmvc/makefile
new file mode 100644
index 00000000..cf2ad437
--- /dev/null
+++ b/src/tools/ppetracepp/cmvc/makefile
@@ -0,0 +1,28 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/ppetracepp/cmvc/makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+PROGRAMS += ppe2fsp
+ppe2fsp_OFILES = ppe2fsp.o ppe2fsp_cmd.o
+
+.include <${RULES_MK}>
+
diff --git a/src/tools/ppetracepp/jhash.h b/src/tools/ppetracepp/jhash.h
new file mode 100755
index 00000000..0dcc3bf3
--- /dev/null
+++ b/src/tools/ppetracepp/jhash.h
@@ -0,0 +1,166 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/jhash.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 _LINUX_JHASH_H
+#define _LINUX_JHASH_H
+
+/* jhash.h: Jenkins hash support.
+ *
+ * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
+ *
+ * http://burtleburtle.net/bob/hash/
+ *
+ * These are the credits from Bob's sources:
+ *
+ * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
+ * hash(), hash2(), hash3, and mix() are externally useful functions.
+ * Routines to test the hash are included if SELF_TEST is defined.
+ * You can use this free for any purpose. It has no warranty.
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ *
+ * I've modified Bob's hash to be useful in the Linux kernel, and
+ * any bugs present are surely my fault. -DaveM
+ */
+
+/* NOTE: Arguments are modified. */
+#define __jhash_mix(a, b, c) \
+{ \
+ a -= b; a -= c; a ^= (c>>13); \
+ b -= c; b -= a; b ^= (a<<8); \
+ c -= a; c -= b; c ^= (b>>13); \
+ a -= b; a -= c; a ^= (c>>12); \
+ b -= c; b -= a; b ^= (a<<16); \
+ c -= a; c -= b; c ^= (b>>5); \
+ a -= b; a -= c; a ^= (c>>3); \
+ b -= c; b -= a; b ^= (a<<10); \
+ c -= a; c -= b; c ^= (b>>15); \
+}
+
+/* The golden ration: an arbitrary value */
+#define JHASH_GOLDEN_RATIO 0x9e3779b9
+
+/* The most generic version, hashes an arbitrary sequence
+ * of bytes. No alignment or length assumptions are made about
+ * the input key.
+ */
+static inline u32 jhash(const void *key, u32 length, u32 initval)
+{
+ u32 a, b, c, len;
+ const u8 *k = (const u8*)key;
+
+ len = length;
+ a = b = JHASH_GOLDEN_RATIO;
+ c = initval;
+
+ while (len >= 12) {
+ a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24));
+ b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24));
+ c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24));
+
+ __jhash_mix(a,b,c);
+
+ k += 12;
+ len -= 12;
+ }
+
+ c += length;
+ switch (len) {
+ case 11: c += ((u32)k[10]<<24);
+ case 10: c += ((u32)k[9]<<16);
+ case 9 : c += ((u32)k[8]<<8);
+ case 8 : b += ((u32)k[7]<<24);
+ case 7 : b += ((u32)k[6]<<16);
+ case 6 : b += ((u32)k[5]<<8);
+ case 5 : b += k[4];
+ case 4 : a += ((u32)k[3]<<24);
+ case 3 : a += ((u32)k[2]<<16);
+ case 2 : a += ((u32)k[1]<<8);
+ case 1 : a += k[0];
+ };
+
+ __jhash_mix(a,b,c);
+
+ return c;
+}
+
+/* A special optimized version that handles 1 or more of u32s.
+ * The length parameter here is the number of u32s in the key.
+ */
+static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
+{
+ u32 a, b, c, len;
+
+ a = b = JHASH_GOLDEN_RATIO;
+ c = initval;
+ len = length;
+
+ while (len >= 3) {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ __jhash_mix(a, b, c);
+ k += 3; len -= 3;
+ }
+
+ c += length * 4;
+
+ switch (len) {
+ case 2 : b += k[1];
+ case 1 : a += k[0];
+ };
+
+ __jhash_mix(a,b,c);
+
+ return c;
+}
+
+
+/* A special ultra-optimized versions that knows they are hashing exactly
+ * 3, 2 or 1 word(s).
+ *
+ * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
+ * done at the end is not done here.
+ */
+static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
+{
+ a += JHASH_GOLDEN_RATIO;
+ b += JHASH_GOLDEN_RATIO;
+ c += initval;
+
+ __jhash_mix(a, b, c);
+
+ return c;
+}
+
+static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
+{
+ return jhash_3words(a, b, 0, initval);
+}
+
+static inline u32 jhash_1word(u32 a, u32 initval)
+{
+ return jhash_3words(a, 0, 0, initval);
+}
+
+#endif /* _LINUX_JHASH_H */
diff --git a/src/tools/ppetracepp/ppe2fsp.c b/src/tools/ppetracepp/ppe2fsp.c
new file mode 100755
index 00000000..d681b147
--- /dev/null
+++ b/src/tools/ppetracepp/ppe2fsp.c
@@ -0,0 +1,532 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/ppe2fsp.c $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 "pk_trace.h"
+#include "ppe2fsp.h"
+#include "trac_interface.h"
+#include <arpa/inet.h>
+#include <string.h>
+#include <stdint.h>
+
+#define TRACE_BUF_VERSION 0x01 /*!< Trace buffer version */
+#define TRACE_FIELDTRACE 0x4654 /*!< Field Trace - "FT" */
+#define TRACE_FIELDBIN 0x4644 /*!< Binary Field Trace - "FD" */
+
+#define TRAC_TIME_REAL 0 // upper 32 = seconds, lower 32 = nanoseconds
+#define TRAC_TIME_50MHZ 1
+#define TRAC_TIME_200MHZ 2
+#define TRAC_TIME_167MHZ 3 // 166666667Hz
+
+typedef struct
+{
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+ union
+ {
+ uint8_t data[PK_TRACE_MAX_BINARY + 1]; //add 1 byte for padding
+ uint32_t parms[PK_TRACE_MAX_PARMS];
+ };
+ uint32_t size;
+}largest_fsp_entry_t;
+
+typedef struct
+{
+ union
+ {
+ uint8_t binary_data[PK_TRACE_MAX_BINARY + 1];
+ struct
+ {
+ uint8_t rsvd[(PK_TRACE_MAX_BINARY + 1) - (PK_TRACE_MAX_PARMS * sizeof(uint32_t))];
+ uint32_t parms[PK_TRACE_MAX_PARMS];
+ };
+ };
+ PkTraceEntryFooter footer;
+}LargestPpeEntry;
+
+//convert a ppe timestamp to an fsp trace timestamp
+uint64_t ppe2fsp_time(uint64_t ppe_time, uint32_t hz)
+{
+ uint32_t seconds;
+ uint32_t remainder;
+ uint32_t nseconds;
+
+ //convert from ppe ticks to seconds and nanoseconds
+ seconds = ppe_time / hz;
+ remainder = ppe_time - (((uint64_t)seconds) * hz);
+ nseconds = (((uint64_t)remainder) * 1000000000) / hz;
+ return (((uint64_t)seconds) << 32) | nseconds;
+}
+
+//Writes an fsp trace entry to the fsp trace buffer
+void fsp_put_entry(trace_buf_head_t* tb, largest_fsp_entry_t* fte, size_t entry_size, uint32_t bytes_left)
+{
+ char* buffer = ((char*)tb) + sizeof(trace_buf_head_t);
+ char* tb_start;
+ char* fte_start;
+ uint32_t copy_bytes;
+
+ if(entry_size <= bytes_left)
+ {
+ tb_start = buffer + bytes_left - entry_size;
+ fte_start = (char*)fte;
+ copy_bytes = entry_size;
+ }
+ else
+ {
+ tb_start = buffer;
+ fte_start = ((char*)fte) + (entry_size - bytes_left);
+ copy_bytes = bytes_left;
+ }
+
+ memcpy(tb_start, fte_start, copy_bytes);
+}
+
+
+//convert a ppe trace entry to an fsp trace entry
+size_t pte2fte(PkTraceBuffer* ptb,
+ LargestPpeEntry* pte,
+ size_t pte_size,
+ largest_fsp_entry_t* fte,
+ uint64_t ppe_time64)
+{
+ size_t entry_size;
+ PkTraceGeneric* pte_footer = &pte->footer.generic;
+ uint32_t format;
+ uint32_t hash32;
+ uint32_t hash32_partial;
+ uint32_t* parm_start;
+ uint32_t parm_bytes;
+ uint64_t fsp_time64;
+
+ //convert the ppe trace time to an fsp trace time
+ fsp_time64 = ppe2fsp_time(ppe_time64, ntohl(ptb->hz));
+
+ //fill in the 64 bit timestamp
+ fte->stamp.tbh = htonl((uint32_t)(fsp_time64 >> 32));
+ fte->stamp.tbl = htonl((uint32_t)(fsp_time64 & 0x00000000ffffffffull));
+
+ //use the ppe instance id as the thread id.
+ fte->stamp.tid = htonl((uint32_t)ntohs(ptb->instance_id));
+
+ //merge the hash prefix and the string_id fields together for a 32 bit hash value
+ hash32 = ((uint32_t)ntohs(ptb->hash_prefix)) << 16;
+ hash32 |= pte_footer->string_id;
+ fte->head.hash = htonl(hash32);
+
+ //generate the 32bit hash value for a partial trace entry in case it's needed
+ hash32_partial = ((uint32_t)ntohs(ptb->hash_prefix)) << 16;
+ hash32_partial |= ntohs(ptb->partial_trace_hash);
+
+ //set the line number to 1
+ fte->head.line = htonl(1);
+
+ //determine the FSP trace format
+ format = PK_GET_TRACE_FORMAT(pte_footer->time_format.word32);
+ if(format == PK_TRACE_FORMAT_BINARY)
+ {
+ fte->head.tag = htons(TRACE_FIELDBIN);
+ }
+ else
+ {
+ fte->head.tag = htons(TRACE_FIELDTRACE);
+ }
+
+ parm_start = (uint32_t*)(((char*)pte) + (sizeof(LargestPpeEntry) - pte_size));
+
+ //fill in the parameters/binary data and size at the end
+ switch(format)
+ {
+
+ case PK_TRACE_FORMAT_TINY:
+ //one or 0 parameters
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ sizeof(uint32_t);
+ fte->parms[0] = htonl((uint32_t)(pte_footer->parm16));
+ fte->head.length = htons(sizeof(uint32_t));
+ parm_bytes = 0;
+ break;
+
+ case PK_TRACE_FORMAT_BIG:
+ //1 - 4 parameters
+ //
+ //If the trace entry data is incomplete (not all parm data
+ //had been written at the time the trace was captured) then
+ //we will write a trace to the fsp buffer that says
+ //"PARTIAL TRACE ENTRY. HASH_ID = %d"
+ if(pte_footer->complete)
+ {
+ parm_bytes = pte_footer->bytes_or_parms_count * sizeof(uint32_t);
+ fte->head.length = htons(parm_bytes + sizeof(uint32_t));
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ parm_bytes + sizeof(uint32_t);
+ }
+ else
+ {
+ parm_bytes = 0;
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ sizeof(uint32_t);
+ fte->parms[0] = fte->head.hash; //already corrected for endianess
+ fte->head.hash = htonl(hash32_partial);
+ fte->head.length = htons(sizeof(uint32_t));
+ }
+ break;
+
+ case PK_TRACE_FORMAT_BINARY:
+ //If the trace entry data is incomplete (not all parm data
+ //had been written at the time the trace was captured) then
+ //we will write a trace to the fsp buffer that says
+ //"PARTIAL TRACE ENTRY. HASH_ID = %d"
+ if(pte_footer->complete)
+ {
+ parm_bytes = pte_footer->bytes_or_parms_count;
+ fte->head.length = htons((uint16_t)parm_bytes);
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ parm_bytes;
+
+ //pad to 4 byte boundary
+ entry_size = (entry_size + 3) & ~3;
+ }
+ else
+ {
+ parm_bytes = 0;
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ sizeof(uint32_t);
+ fte->parms[0] = fte->head.hash;
+ fte->head.hash = htonl(hash32_partial);
+ fte->head.length = htons(sizeof(uint32_t));
+ fte->head.tag = htons(TRACE_FIELDTRACE);
+ }
+ break;
+
+
+ default:
+ entry_size = 0;
+ parm_bytes = 0;
+ break;
+ }
+
+ //copy parameter bytes to the fsp entry if necessary
+ if(parm_bytes)
+ {
+ memcpy(fte->data, parm_start, parm_bytes);
+ }
+
+ //add the entry size to the end
+ if(entry_size)
+ {
+ uint32_t new_entry_size = entry_size + sizeof(uint32_t);
+ *((uint32_t*)(((char*)fte) + entry_size)) = htonl(new_entry_size);
+ entry_size = new_entry_size;
+ }
+
+ return entry_size;
+}
+
+//retrieve a ppe trace entry from a ppe trace buffer
+size_t ppe_get_entry(PkTraceBuffer* tb, uint32_t offset, LargestPpeEntry* pte)
+{
+ uint32_t mask = ntohs(tb->size) - 1;
+ PkTraceEntryFooter* footer;
+ size_t entry_size;
+ size_t parm_size;
+ char* dest = (char*)pte;
+ uint32_t format;
+ uint32_t start_index;
+ uint32_t bytes_left;
+ uint32_t bytes_to_copy;
+
+ //Find the footer in the circular buffer
+ footer = (PkTraceEntryFooter*)(&tb->cb[(offset - sizeof(PkTraceEntryFooter)) & mask]);
+
+ //always correct endianess for the time and string id words
+ pte->footer.generic.time_format.word32 = ntohl(footer->generic.time_format.word32);
+ pte->footer.generic.string_id = ntohs(footer->generic.string_id);
+
+ //only need to byte swap the parm16 value if this is a tiny format
+ pte->footer.generic.parm16 = footer->generic.parm16;
+
+ //use footer data to determine the length of the binary data or parameters
+ format = PK_GET_TRACE_FORMAT(pte->footer.generic.time_format.word32);
+ switch(format)
+ {
+ case PK_TRACE_FORMAT_TINY:
+ pte->footer.generic.parm16 = ntohs(pte->footer.generic.parm16);
+ parm_size = 0;
+ entry_size = sizeof(PkTraceEntryFooter);
+ break;
+
+ case PK_TRACE_FORMAT_BIG:
+ parm_size = pte->footer.generic.bytes_or_parms_count * sizeof(uint32_t);
+ entry_size = sizeof(PkTraceEntryFooter);
+ break;
+
+ case PK_TRACE_FORMAT_BINARY:
+ parm_size = pte->footer.generic.bytes_or_parms_count;
+ entry_size = sizeof(PkTraceEntryFooter);
+ break;
+
+ default:
+ entry_size = 0;
+ parm_size = 0;
+ break;
+ }
+
+ //pad to 8 byte boundary
+ parm_size = (parm_size + 7) & ~0x00000007ul;
+
+ //add the parameter size to the total entry size
+ entry_size += parm_size;
+
+ //copy the entry from the circular buffer to pte
+ start_index = (offset - entry_size) & mask;
+ bytes_left = ntohs(tb->size) - start_index;
+
+ //only copy up to the end of the circular buffer
+ if(parm_size < bytes_left)
+ {
+ bytes_to_copy = parm_size;
+ }
+ else
+ {
+ bytes_to_copy = bytes_left;
+ }
+
+ dest += sizeof(LargestPpeEntry) - entry_size;
+ memcpy(dest, &tb->cb[start_index], bytes_to_copy);
+
+ //now copy the rest of the data starting from the beginning of the
+ //circular buffer.
+ if(bytes_to_copy < parm_size)
+ {
+ memcpy(dest + bytes_to_copy, tb->cb, parm_size - bytes_to_copy);
+ }
+
+ //return the size of the entry
+ return entry_size;
+}
+
+//convert a ppe trace buffer to an fsp trace buffer
+int ppe2fsp(void* in, size_t in_size, void* out, size_t* io_size)
+{
+ PkTraceBuffer* ptb = (PkTraceBuffer*)in;
+ trace_buf_head_t* ftb = (trace_buf_head_t*)out;
+ uint32_t ppe_bytes_left;
+ uint32_t fsp_bytes_left;
+ int rc = 0;
+ uint32_t ptb_offset;
+ uint64_t ppe_time64;
+ uint32_t fte_size, pte_size;
+ uint32_t fsp_te_count = 0;
+ uint32_t time_diff32, prev_time32, new_time32;
+ PkTraceGeneric* pte_footer;
+ largest_fsp_entry_t fte;
+ LargestPpeEntry pte;
+ uint64_t time_adj64;
+
+ do
+ {
+ if(!ptb || !ftb || !io_size)
+ {
+ rc = P2F_NULL_POINTER;
+ break;
+ }
+
+ if(ntohs(ptb->version) != PK_TRACE_VERSION)
+ {
+ rc = P2F_INVALID_VERSION;
+ break;
+ }
+
+ //check that the input buffer is large enough to have a ppe trace buffer
+ if(in_size < (((uintptr_t)(&ptb->cb[0])) - (uintptr_t)(ptb)))
+ {
+ rc = P2F_INPUT_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ //initialize some locals
+ fsp_bytes_left = *io_size - sizeof(trace_buf_head_t);
+ ppe_bytes_left = ntohs(ptb->size);
+ ptb_offset = ntohl(ptb->state.offset);
+ if(htonl(1) == 1)
+ {
+ time_adj64 = ptb->time_adj64;
+ }
+ else
+ {
+ time_adj64 = ntohl((uint32_t)(ptb->time_adj64 >> 32));
+ time_adj64 |= ((uint64_t)(ntohl((uint32_t)(ptb->time_adj64 & 0x00000000ffffffff)))) << 32;
+ }
+
+ //make sure the ppe buffer size is a power of two
+ if((ppe_bytes_left - 1) & ppe_bytes_left)
+ {
+ //size is not a power of two
+ rc = P2F_INVALID_INPUT_SIZE;
+ break;
+ }
+
+ //The ppe bytes field should always be a multiple of 8
+ if(ptb_offset & 0x7)
+ {
+ rc = P2F_INVALID_PPE_OFFSET;
+ break;
+ }
+
+ //make sure there is enough room for the fsp header
+ if(*io_size < sizeof(trace_buf_head_t))
+ {
+ rc = P2F_OUTPUT_BUFFER_TOO_SMALL;
+ break;
+ }
+
+
+ //initialize the fsp header
+ ftb->ver = TRACE_BUF_VERSION;
+ ftb->hdr_len = sizeof(trace_buf_head_t);
+ ftb->time_flg = TRAC_TIME_REAL;
+ ftb->endian_flg = 'B'; //big endian
+ memcpy(ftb->comp, ptb->image_str, sizeof(ftb->comp));
+ ftb->times_wrap = htonl(1);
+ ftb->size = htonl(sizeof(trace_buf_head_t) + sizeof(uint32_t));
+ ftb->next_free = htonl(sizeof(trace_buf_head_t));
+ ftb->extracted = htonl(0);
+ ftb->te_count = htonl(0);
+
+ //find the latest timestamp so that we can work back from there
+ ppe_time64 = ((uint64_t)(ntohl(ptb->state.tbu32) & 0xefffffff)) << 32;
+ pte_size = ppe_get_entry(ptb, ptb_offset, &pte);
+ prev_time32 = PK_GET_TRACE_TIME(pte.footer.generic.time_format.word32);
+ ppe_time64 |= prev_time32;
+
+ //process all of the input bytes one trace entry at a time
+ //from newest to oldest (backwards) until we run out of input bytes or
+ //we run out of output space.
+ while(1)
+ {
+ //check if we have enough data for a ppe footer
+ if(ppe_bytes_left < sizeof(PkTraceEntryFooter))
+ {
+ break;
+ }
+
+ //get the next ppe entry
+ pte_size = ppe_get_entry(ptb, ptb_offset, &pte);
+
+ //Stop if there are no more entries to retrieve from the ppe trace buffer
+ if(!pte_size)
+ {
+ break;
+ }
+ pte_footer = &pte.footer.generic;
+
+ //mark the entry as incomplete if we didn't have enough data
+ //for the entire entry
+ if(pte_size > ppe_bytes_left)
+ {
+ pte_footer->complete = 0;
+ ppe_bytes_left = 0;
+ }
+ else
+ {
+ ppe_bytes_left -= pte_size;
+ ptb_offset -= pte_size;
+ }
+
+ //Calculate the 64 bit timestamp for this entry....
+ //On PPE, getting the timestamp is not done atomically with writing
+ //the entry to the buffer. This means that an entry with an older
+ //timestamp could possibly be added to the buffer after an entry
+ //with a newer timestamp. Detect this condition by checking if the
+ //time difference is bigger than the max difference. The max
+ //difference is enforced by the PPE having a trace added on a
+ //shorter time boundary (using a timer).
+ new_time32 = PK_GET_TRACE_TIME(pte_footer->time_format.word32);
+ time_diff32 = prev_time32 - new_time32;
+
+ if(time_diff32 > ntohl(ptb->max_time_change))
+ {
+ time_diff32 = new_time32 - prev_time32;
+ ppe_time64 += time_diff32;
+ }
+ else
+ {
+ ppe_time64 -= time_diff32;
+ }
+
+ //save off the lower 32bit timestamp for the next iteration
+ prev_time32 = new_time32;
+
+ //convert the ppe trace entry to an fsp trace entry
+ fte_size = pte2fte(ptb, &pte, pte_size, &fte, ppe_time64 + time_adj64);
+
+ //fit as much of the entry into the fsp trace buffer as possible
+ fsp_put_entry(ftb, &fte, fte_size, fsp_bytes_left);
+
+ //update the fsp trace entry count
+ fsp_te_count++;
+
+ //stop if there is no more room left in the fsp trace buffer
+ if(fte_size >= fsp_bytes_left)
+ {
+ fsp_bytes_left = 0;
+ ftb->times_wrap = htonl(1);
+ break;
+ }
+ else
+ {
+ fsp_bytes_left -= fte_size;
+ }
+ }//while(1)
+
+
+ //shift the trace data up if there is space to do so
+ if(fsp_bytes_left)
+ {
+ char* dest = ((char*)ftb) + sizeof(trace_buf_head_t);
+ char* src = dest + fsp_bytes_left;
+ size_t data_size = *io_size - sizeof(trace_buf_head_t) - fsp_bytes_left;
+ memmove(dest, src, data_size);
+ }
+
+ //update the fsp header to reflect the true size and entry count
+ ftb->te_count = htonl(fsp_te_count);
+
+ //inform the caller of how many bytes were actually used
+ *io_size -= fsp_bytes_left;
+
+ //shrink the size field to what we actually ended up using
+ ftb->size = htonl(*io_size);
+
+ }while(0);
+
+ return rc;
+}
+
+
+
diff --git a/src/tools/ppetracepp/ppe2fsp.h b/src/tools/ppetracepp/ppe2fsp.h
new file mode 100644
index 00000000..2abb146c
--- /dev/null
+++ b/src/tools/ppetracepp/ppe2fsp.h
@@ -0,0 +1,33 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/ppe2fsp.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 <stdio.h>
+
+#define P2F_NULL_POINTER 1
+#define P2F_INVALID_INPUT_SIZE 2
+#define P2F_INVALID_PPE_OFFSET 3
+#define P2F_OUTPUT_BUFFER_TOO_SMALL 4
+#define P2F_INPUT_BUFFER_TOO_SMALL 5
+#define P2F_INVALID_VERSION 6
+
+int ppe2fsp(void* in, size_t in_size, void* out, size_t* io_size);
diff --git a/src/tools/ppetracepp/ppe2fsp_cmd.c b/src/tools/ppetracepp/ppe2fsp_cmd.c
new file mode 100644
index 00000000..c36d735c
--- /dev/null
+++ b/src/tools/ppetracepp/ppe2fsp_cmd.c
@@ -0,0 +1,138 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/ppe2fsp_cmd.c $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 <stdio.h>
+#include "ppe2fsp.h"
+#include "pk_trace.h"
+
+#define MAX_INPUT_SIZE 0x2040 //8k
+#define MAX_OUTPUT_SIZE (4 * MAX_INPUT_SIZE)
+
+char* inbuf[MAX_INPUT_SIZE];
+char* outbuf[MAX_OUTPUT_SIZE];
+;
+int main(int argc, char** argv)
+{
+ FILE* in;
+ FILE* out;
+ size_t input_size;
+ size_t output_size;
+ size_t bytes_written;
+ int rc = -1;
+
+ do
+ {
+ if(argc > 3)
+ {
+ fprintf(stderr, "Usage: %s [input file] [output file]\n", argv[0]);
+ }
+
+ if(argc < 3)
+ {
+ out = stdout;
+ }
+ else
+ {
+ //open the output file for writing
+ out = fopen(argv[2], "w");
+ if(!out)
+ {
+ perror("failed to open file for writing");
+ break;
+ }
+ }
+
+ if(argc < 2)
+ {
+ in = stdin;
+ }
+ else
+ {
+ //open the input file for reading
+ in = fopen(argv[1], "r");
+ if(!in)
+ {
+ perror("failed to open file for reading");
+ break;
+ }
+ }
+
+ //read the input stream until we reach EOF or the max size
+ input_size = fread(inbuf, 1, MAX_INPUT_SIZE, in);
+ if(!feof(in))
+ {
+ if(ferror(in))
+ {
+ perror("failed to read input file");
+ break;
+ }
+ else
+ {
+ fprintf(stderr, "Input stream exceeds max size of %d bytes. Exiting.\n", MAX_INPUT_SIZE);
+ break;
+ }
+ }
+
+ output_size = MAX_OUTPUT_SIZE;
+
+ //Actual size of output buffer will be set upon successful completion
+ rc = ppe2fsp(inbuf, input_size, outbuf, &output_size);
+ if(rc)
+ {
+ fprintf(stderr, "Failed converting ppe trace to fsp trace. rc = %d\n", rc);
+ if(rc == P2F_INVALID_VERSION)
+ {
+ fprintf(stderr, "PPE trace buffer must be version %d.\n", PK_TRACE_VERSION);
+ }
+ break;
+ }
+
+ rc = -1;
+ //operation was successful. Write out the fsp trace data
+ bytes_written = fwrite(outbuf, 1, output_size, out);
+ if(bytes_written != output_size)
+ {
+ if(ferror(out))
+ {
+ perror("Failed to write output stream");
+ break;
+ }
+ fprintf(stderr, "Failure: Only able to write %d of %d bytes to output stream\n", bytes_written, output_size);
+ break;
+ }
+
+ fclose(in);
+ fclose(out);
+ fclose(stderr);
+
+ rc = 0;
+ }while(0);
+
+ return rc;
+}
+
+
+
+
+
+
diff --git a/src/tools/ppetracepp/ppetracepp.C b/src/tools/ppetracepp/ppetracepp.C
new file mode 100755
index 00000000..2829e4dd
--- /dev/null
+++ b/src/tools/ppetracepp/ppetracepp.C
@@ -0,0 +1,949 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/ppetracepp.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+
+/*
+# *** ppetracepp - a fsp/common Linux trace pre processor
+# this one replaces the trace strings by the corresponding hash value
+# (i.e. the complete call to trace_ppe_hash is replaced)
+
+# *** Usage
+#
+# prepend compiler call with the call of this pre processor, i.e if you have
+# $(CC) $(CFLAGS) -o $@ $<
+# in your Makefile change it to this:
+# ppetracepp $(CC) $(CFLAGS) -o $@ $<
+# ppetracepp will use "$(CC) -E" to call the C pre processor "cpp".
+# you can set a env var "REALCPP" to the name of a program to select
+# a different programm as cpp
+#
+# ppetracepp creates a file "$target.ppe.hash" with the trace strings and the hash values.
+#
+# to enable debug mode set envvar PPETRACEPPDEBUG to 1 or give '-d' as first arg
+
+# *** Change History
+#
+# 2003-02-26 RBa created from scratch
+# 2003-02-28 RBa add C++ support (C++ interface uses own type for the hash)
+# 2003-05-28 RBa if cc should link instead of compile just call compiler
+# 2003-07-11 AGe Change search alg. slightly and put just format back
+# 2003-07-25 RBa just call gcc if called to link instead to compile
+# eat argument for option -x
+# 2003-11-26 RBa fix c/c++ algo: compile as c++ if realcc=*g++
+# 2004-02-02 RBa remove explicit test whether source file is readable
+# it is obsolete and might lead to an error if afs is used
+# 2004-02-13 RBa add support for dependency generation (-MD/-MG, -MF)
+# don't prepend './' to object filename
+# 2006-04-19 RBa rewrite trace_ppe_write_all support, handle C and C++ the same
+# 2006-05-24 RBa fix handling of missing -o ; add TRAC_PPVER for macro/API version
+# 2006-09-15 RBa add handling of \" in trace format strings ; reduce non-error output
+# put object file in current dir if no -o given
+# 2007-03-22 RBa handle more gcc options (-i) ; protect " in call to shell
+# store output of cpp as "unmodified" output for debug
+# only write string/hash file if strings found
+# 2012-09-24 hlava Rewritten as C program for better build performance (was perl)
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <string>
+#include <time.h>
+#include <fcntl.h>
+#include <map>
+#include <vector>
+#include <unistd.h>
+#include <sys/types.h>
+typedef u_int32_t u32 ;
+typedef u_int8_t u8 ;
+#include <jhash.h>
+
+using namespace std;
+
+static string version = "2.0";
+static string macro_version = "1";
+
+static bool debug = false;
+#define dprintf(format, ...) if (debug) { printf(format, ##__VA_ARGS__); fflush(stdout); }
+static map<string,string> hashtab;
+static string hashtype;
+static string hashtype_suffix;
+
+static string tmp;
+static string cmd;
+static FILE* CPP = NULL; // pipe from preprocessor
+static FILE* CC = NULL; // pipe to compiler
+static FILE* DEBUG = NULL;
+static FILE* DEBUGIN = NULL;
+
+//*****************************************************************************
+// replace_substr
+//*****************************************************************************
+void replace_substr(std::string& str, const std::string& oldStr, const std::string& newStr)
+{
+ size_t pos = 0;
+ while((pos = str.find(oldStr, pos)) != std::string::npos)
+ {
+ str.replace(pos, oldStr.length(), newStr);
+ pos += newStr.length();
+ }
+
+}
+
+//*****************************************************************************
+// fileparse
+//*****************************************************************************
+void fileparse(const string& in_str, string& name, string& dir, string& suff)
+{
+ string str(in_str);
+ size_t pos;
+ name = "";
+ dir = "";
+ suff = "";
+ pos = str.find_last_of('.');
+ if (pos != string::npos)
+ {
+ suff = str.substr(pos);
+ str = str.substr(0, pos);
+ }
+ pos = str.find_last_of('/');
+ if (pos != string::npos)
+ {
+ name = str.substr(pos+1);
+ str = str.substr(0, pos+1);
+ }
+ dir = str;
+}
+
+static const size_t TRACE_PPE_HASH_LEN = 13;
+//*****************************************************************************
+// chop_up_line
+//*****************************************************************************
+bool chop_up_line(string& in_line, string& prefix, string& strings, string& salt, string& suffix)
+{
+ // First see if this line matches the pattern we're looking for
+ // Since this will return false 95%+ of the time this function it called, we do it
+ // before doing any other init for performance reasons.
+ size_t pos = in_line.find("trace_ppe_hash");
+ if (pos == string::npos) { return(false); }
+
+ // trace_ppe_hash ( "..." ".." "..." , 2 )
+ // regex: PREFIX 'trace_ppe_hash' space '(' space STRINGS space ',' space NUMBER space ')' SUFFIX
+ // STRINGS: '"' .* '"' space? +
+
+ // Original perl magic incantation:
+ // while($line =~ m/^(.*?)trace_ppe_hash\s*\(\s*((".*?(?<!\\)"\s*)+),\s*(-?\d+)\s*\)(.*)$/) {
+ // ($prefix, $strings, $salt, $suffix) = ($1, $2, $4, $5);
+ //
+ // Decrypting the magic pattern matching...
+ // (.*?) => $1 = everything up to the word "trace_ppe_hash"
+ // trace_ppe_hash = delimiter
+ // \s*\(\s* = delimiter = <0-n whitespace chars>, left paren, <0-n whitespace chars>
+ // ((".*?(?<!\\)"\s*)+) => $2 = double-quote, some chars up to last closing double-quote ($3 used for nested regex)
+ // ,\s* = delimiter = comma followed by some whitespace
+ // (-?\d+)\s*\)(.*) => $4 and $5
+ // $/) = end of the line input string
+ string line(in_line);
+ prefix = "";
+ strings = "";
+ salt = "";
+ suffix = "";
+ size_t pos1;
+ size_t pos2;
+ size_t pos3;
+
+ pos1 = pos + 14; // pos1 = after "trace_ppe_hash"
+ pos2 = line.find("(", pos1);
+ if (pos2 == string::npos) { return(false); }
+ ++pos2;
+ pos3 = line.find("\"", pos2);
+ if (pos3 == string::npos) { return(false); }
+ dprintf("--------\nchop_up_line: Passed basic checks. line= %s\n", line.c_str());
+ dprintf("pos1=%d, pos2=%d, pos3=%d\n", pos1, pos2, pos3);
+ if ((pos1 != (pos2-1)) && (line.find_first_not_of(" \t", pos1, (pos2-pos1)+1) != string::npos)) { return(false); } //non-whitespace?
+ if ((pos2 != pos3) && (line.find_first_not_of(" \t", pos2, (pos3-pos2)) != string::npos)) { return(false); } //non-whitespace?
+
+ // Get the prefix data
+ dprintf(">chop_up_line(\"%s\",...)\n", line.c_str());
+ prefix = line.substr(0, pos);
+ line = line.substr(pos + TRACE_PPE_HASH_LEN);
+ dprintf(" prefix=\"%s\"\n", prefix.c_str());
+
+ // Get the strings and join/fix them: Store all strings between paired double-quotes up to the
+ // first comma not inside a string
+ pos = line.find_first_of('(');
+ if (pos == string::npos) { return(false); }
+ line = line.substr(pos + 1);
+ strings = "";
+ while(!line.empty())
+ {
+ pos = line.find_first_of(',');
+ pos1 = line.find_first_of('"');
+ if ((pos1 == string::npos) || ((pos != string::npos) && (pos < pos1))) { break; } // found comma before next quote
+ pos2 = line.find_first_of('"', (pos1+1));
+ if (pos2 == string::npos) { return(false); } // unbalanced quotes!
+ while(line[pos2-1] == '\\') // skip escaped quotes in the string (they're not the ending quote)
+ {
+ pos2 = line.find_first_of('"', (pos2+1));
+ if (pos2 == string::npos) { return(false); } // unbalanced quotes!
+ }
+ if (!strings.empty()) { strings += " "; }
+ strings += line.substr(pos1, (pos2-pos1)+1);
+ line = line.substr(pos2+1);
+ }
+ replace_substr(strings, "\" \"", "");
+ replace_substr(strings, "\\\"", "ESCAPEDQUOTE");
+ replace_substr(strings, "\"", "");
+ replace_substr(strings, "ESCAPEDQUOTE", "\"");
+ // Remove trailing whitespace ah20130717
+ pos = strings.find_last_not_of(" \t\n");
+ if ((pos != string::npos) && (pos < (strings.length()-1)))
+ {
+ strings = strings.substr(0, pos+1);
+ }
+
+ dprintf(" strings>%s<\n", strings.c_str());
+
+ // Get the salt
+ pos = line.find(",");
+ if (pos != string::npos) { line = line.substr(pos+1); }
+ pos = line.find_first_of(')');
+ if (pos == string::npos) { return(false); }
+ salt = line.substr(0, pos);
+ line = line.substr(pos+1);
+ //dprintf(" salt=\"%s\"\n", salt.c_str());
+ pos = salt.find_first_not_of(" \t\n");
+ if (pos == string::npos) { return(false); }
+ salt = salt.substr(pos);
+ pos = salt.find_last_not_of(" \t\n");
+ if (pos == string::npos) { return(false); }
+ salt = salt.substr(0, pos+1);
+ dprintf(" salt=\"%s\"\n", salt.c_str());
+
+ // Get the suffix (i.e. the rest)
+ suffix = line;
+ if (suffix[suffix.length()-1] == '\n') { suffix = suffix.substr(0, suffix.length()-1); }
+ dprintf(" suffix=\"%s\"\n<chop_up_line() returning true\n", suffix.c_str());
+
+ return(true);
+}
+
+//*****************************************************************************
+// get_format_string
+//*****************************************************************************
+int get_format_string(const string& in_str, string& format)
+{
+ int format_salt = 0;
+ size_t pos;
+ size_t pos_end;
+ string str(in_str);
+ // (@format_param) = ($strings =~ /(%[#0\- +'I]*\d*(?:\.\d*)?[hlLqjzt]*[diouxXeEfFgGaAcsCSpn])/g);
+ // $format = join(',', @format_param);
+ // Decrypting the regular expression magic...
+ // (%[#0\- +'I]*\d*(?:\.\d*)?[hlLqjzt]*[diouxXeEfFgGaAcsCSpn])
+
+ format = "";
+ while(!str.empty())
+ {
+ pos = str.find("%");
+ if (pos == string::npos) { break; }
+ if (pos == (str.length()-1)) { break; } // last char in string? just skip it
+ if (str[pos+1] == '%') // double percent sign? just skip first one
+ {
+ str = str.substr(pos+1);
+ continue;
+ }
+ pos_end = str.find_first_of("cdieEfgGosuxXpn", pos); // find formatting specifier
+ if (pos_end == string::npos)
+ {
+ fprintf(stderr, "ERROR: ppetracepp could not parse trace formatting string \"%s\" in \"%s\"\n", str.c_str(), in_str.c_str());
+ break;
+ }
+
+ if (!format.empty())
+ format += ",";
+ format += str.substr(pos, (pos_end-pos)+1);
+ ++format_salt;
+
+ str = str.substr(pos_end+1);
+ }
+ // Correct for escaped percent signs
+ string temp_str(in_str);
+ while((pos = temp_str.find("%%")) != string::npos)
+ {
+ if (pos < (temp_str.length()-2)) // Not the last thing in the string?
+ {
+ dprintf(" decrementing salt value %d\n", format_salt);
+ --format_salt;
+ temp_str = temp_str.substr(pos+2);
+ }
+ else
+ {
+ temp_str = "";
+ }
+ }
+
+ return(format_salt);
+}
+
+#define BUF_SIZE 40
+//*****************************************************************************
+// get_hash
+//*****************************************************************************
+void get_hash(const string& i_str, const unsigned int salt_num, string& hash32, string& hash16)
+{
+ string str(i_str);
+ unsigned int hash_num = 0;
+ char buf[BUF_SIZE];
+
+ hash16 = "";
+ hash32 = "";
+ dprintf(">get_hash(\"%s\",%d)\n", str.c_str(), salt_num);
+
+ // Call jhash function to get the hash value
+ hash_num = jhash((void*)str.c_str(), str.length(), salt_num);
+ dprintf("jhash() returned: %u\n", hash_num);
+ sprintf(buf, "%u", hash_num & 0x0000ffff);
+ hash16 = buf;
+ sprintf(buf, "%u", ((salt_num << 16) | (hash_num & 0x0000ffff)));
+ hash32 = buf;
+
+ // validate the hash value
+ size_t pos = hash32.find_first_not_of("0123456789");
+ if (pos != string::npos)
+ {
+ fprintf(stderr, "trexhash error: %s\n", hash32.c_str());
+ fprintf(stderr, "for call <<%s>>\n", cmd.c_str());
+ exit(1);
+ }
+
+//removing this since it doesn't seem to have any affect on the output
+#if 0
+ // If hash is empty, use the sum of the ord values in the original string
+ if ((hash == "")||(hash == "0"))
+ {
+ unsigned int len = str.length();
+ unsigned int hash_num = 0;
+ //unsigned char conv_buf[2] = { '\0', '\0' };
+ u_int8_t conv_num;
+ for (unsigned int i=0; i < len; ++i)
+ {
+ //conv_buf[0] = str[i];
+ conv_num = (u_int8_t)str[i];
+ hash_num += (unsigned int)conv_num;
+ }
+ }
+#endif
+
+ dprintf("<get_hash(\"%s\",%d) returned hash: %s\n", str.c_str(), salt_num, hash32.c_str());
+}
+
+//*****************************************************************************
+// parse_line
+//*****************************************************************************
+void parse_line(map<string,string>& rhash, string& line, string& out_line)
+{
+ // NOTE: "line" arg may get modified by this function! Caller must not assume it's unchanged.
+ string format;
+ string prefix;
+ string strings;
+ string tmp;
+ string salt;
+ string hash16;
+ string hash32;
+ int salt_num;
+ int format_salt;
+ string suffix;
+ string write_all_suffix;
+ size_t pos;
+
+ out_line = "";
+ // trace_ppe_hash ( "..." ".." "..." , 2 )
+ // regex: PREFIX 'trace_ppe_hash' space '(' space STRINGS space ',' space NUMBER space ')' SUFFIX
+ // STRINGS: '"' .* '"' space? +
+ //while($line =~ m/^(.*?)trace_ppe_hash\s*\(\s*((".*?(?<!\\)"\s*)+),\s*(-?\d+)\s*\)(.*)$/) {
+ // Attempt to approximate the above amazing perl regex...
+ while( chop_up_line(line, prefix, strings, salt, suffix) )
+ {
+ //dprintf("\n\nprefix = %s\nstrings = %s\nsalt = %s\nsuffix = %s\n",
+ // prefix.c_str(), strings.c_str(), salt.c_str(), suffix.c_str());
+ // is this a trace_ppe_write_all call?
+ pos = prefix.find("trace_ppe_write_all");
+ if (pos != string::npos)
+ {
+ // yes. replace trace_ppe_hash with hash value and reduced format string
+ format_salt = get_format_string(strings, format);
+ // reduced format string will be added after hash value
+ write_all_suffix = ",\" ";
+ write_all_suffix += format;
+ write_all_suffix += "\"";
+
+ if (!salt.empty())
+ {
+ salt_num = atoi(salt.c_str());
+ }
+ else
+ {
+ salt_num = -1;
+ }
+
+ if (salt_num == -1)
+ {
+ salt_num = format_salt;
+ }
+ else if (salt_num != format_salt)
+ {
+ fprintf(stderr, "ERROR: printf mismatch in '%s': TRACE says %d, format says %d args\n",
+ line.c_str(), salt_num, format_salt);
+ }
+ }
+ else
+ {
+ write_all_suffix = "";
+ salt_num = atoi(salt.c_str());
+ }
+
+ // get the trex hash value for the strings
+ get_hash(strings, salt_num, hash32, hash16);
+
+ // check for duplicate and store the mapping
+ if ((rhash.find(hash32) != rhash.end()) && (rhash[hash32] != strings))
+ {
+ fprintf(stderr, "hash collision: two different strings give the same hash value '%s'\n", hash32.c_str());
+ fprintf(stderr, "%s\n%s\n", strings.c_str(), rhash[hash32].c_str());
+ // Not breaking the compilation here. This is same as if we get hash
+ // collision across files. As in SBE we are using mirroring, these
+ // hash collisions will take some time to resolve. Till that time,
+ // let us allow compilation of procedures.
+ //return;
+ }
+ rhash[hash32] = strings;
+
+ // add the modified line to the output
+ tmp = prefix;
+ tmp += "(";
+ tmp += hashtype;
+ tmp += " ";
+ tmp += hash16;
+ tmp += hashtype_suffix;
+ tmp += ")";
+ tmp += write_all_suffix;
+ out_line += tmp;
+ dprintf("changed call: %s...\n", tmp.c_str());
+ line = suffix;
+ }
+ out_line += line;
+ if (out_line[out_line.length()-1] != '\n')
+ out_line += "\n";
+}
+
+//*****************************************************************************
+// main
+//*****************************************************************************
+int main(int argc, char** argv)
+{
+ char* p_env = getenv("PPETRACEPPDEBUG");
+ if (p_env)
+ debug = true;
+
+
+ int argi = 1;
+ string arg;
+ string optarg;
+ if (argc > 1) arg = argv[1];
+ if ((argc < 2) || (arg == "-h"))
+ {
+ fprintf(stderr, "usage: %s realcompiler compileroptions -o target source\n", argv[0]);
+ exit(9);
+ }
+ string realcc(argv[argi++]);
+ string cctype("c++");
+ bool optx_found = false;
+
+ if (realcc == "-d")
+ {
+ debug = true;
+ realcc = argv[argi++];
+ }
+
+ // wait until -d options is handled before checking $debug
+ dprintf("ppetracepp version %s - API/macro version %s\n", version.c_str(), macro_version.c_str());
+
+ p_env = getenv("REALCPP");
+ string realcpp;
+ if (p_env)
+ realcpp = p_env;
+ if (realcpp.empty())
+ {
+ dprintf("cannot find cpp, using <realcompiler> -E\n");
+ realcpp = realcc;
+ realcpp += " -E";
+ }
+ dprintf("realcpp is %s\n", realcpp.c_str());
+
+//------------------------------------------------------------------------------
+// parse all the arguments
+//------------------------------------------------------------------------------
+string source;
+string object;
+vector<string> ccopts;
+vector<string> cppopts;
+bool dodeps = false;
+string depfile;
+string pfx;
+string sfx;
+int origargi = argi;
+for( ; argi < argc; ++argi)
+{
+ arg = argv[argi];
+ dprintf("Processing argv[%d]: \"%s\"\n", argi, arg.c_str());
+ if (arg.length() > 2)
+ {
+ pfx = arg.substr(0,2);
+ sfx = arg.substr(arg.length()-2);
+ }
+ else
+ {
+ pfx = arg;
+ sfx = arg;
+ }
+ dprintf(" pfx: \"%s\" sfx: \"%s\"\n", pfx.c_str(), sfx.c_str());
+
+ if (pfx == "-o")
+ {
+ if (! object.empty())
+ {
+ fprintf(stderr, "two -o options, aborting\n");
+ exit(1);
+ }
+ if (arg.length() > 2)
+ {
+ object = sfx;
+ }
+ else
+ {
+ object = argv[++argi];
+ }
+ dprintf("object is now %s\n", object.c_str());
+ }
+ else if (arg == "-c")
+ {
+ // don't call cpp with -c, this is for the compiler
+ ccopts.push_back(arg);
+ dprintf("found -c option\n");
+ }
+ else if (pfx == "-l")
+ {
+ // cpp doesn't need library arguments
+ cppopts.push_back(arg);
+ }
+ else if (pfx == "-i")
+ {
+ // option takes an argument, handle it too
+ optarg = argv[argi++];
+ ccopts.push_back(arg);
+ ccopts.push_back(optarg);
+ cppopts.push_back(arg);
+ cppopts.push_back(optarg);
+ dprintf("found option '%s %s'\n", arg.c_str(), optarg.c_str());
+ }
+ else if ((arg == "-L") ||
+ (arg == "-I") ||
+ (arg == "-x") ||
+ (arg == "-b") ||
+ (arg == "-B") ||
+ (arg == "-V") ||
+ (arg == "-D") ||
+ (arg == "--param") ||
+ (arg == "-MQ") ||
+ (arg == "-MT"))
+ {
+ // option takes an argument, handle it too
+ optarg = argv[argi++];
+ ccopts.push_back(arg);
+ ccopts.push_back(optarg);
+ cppopts.push_back(arg);
+ cppopts.push_back(optarg);
+ dprintf("found option '%s %s'\n", arg.c_str(), optarg.c_str());
+ if (arg == "-x")
+ {
+ // option x sets the language - c or c++
+ if ((optarg != "c") && (optarg != "c++") && (optarg != "assembler-with-cpp"))
+ {
+ fprintf(stderr, "cannot process language '%s', aborting\n", optarg.c_str());
+ exit(1);
+ }
+ cctype = optarg;
+ optx_found = true;
+ }
+ }
+ else if ((arg == "-MD")||(arg == "-MG"))
+ {
+ // gen deps
+ dodeps = true;
+ dprintf("found %s, creating dependencies\n", arg.c_str());
+ }
+ else if (arg == "-MF")
+ {
+ // set dependencies file
+ depfile = argv[argi++];
+ dprintf("set dependencies file to '%s'\n", depfile.c_str());
+ }
+ else if (arg[0] == '-')
+ {
+ // arg starts with - so it's an option
+ ccopts.push_back(arg);
+ cppopts.push_back(arg);
+ dprintf("found option '%s'\n", arg.c_str());
+ }
+ else if ((sfx == ".a") ||
+ (sfx == ".o"))
+ {
+ // an object or archive, ignore this but give it to cc
+ ccopts.push_back(arg);
+ dprintf("found object/archive '%s'\n", arg.c_str());
+ }
+ else if ((sfx == ".c") ||
+ (sfx == ".C") ||
+ (sfx == ".S") ||
+ (arg.substr(arg.length()-4) == ".cpp") ||
+ (arg.substr(arg.length()-4) == ".cxx"))
+ {
+ // the source file(s). we should only get one
+ if (!source.empty())
+ {
+ fprintf(stderr, "don't know to handle two source files, aborting\n");
+ exit(1);
+ }
+ source = arg;
+ // put the - (for read-from-stdin) where the source file was
+ // (order is important!)
+ ccopts.push_back("-");
+ dprintf("found source file %s\n", source.c_str());
+ }
+ else if (access(arg.c_str(), F_OK))
+ {
+ // option but not a file, an unknown option?
+ ccopts.push_back(arg);
+ cppopts.push_back(arg);
+ dprintf("found unknown option '%s'\n", arg.c_str());
+ }
+}
+
+//------------------------------------------------------------------------------
+// set other parameters based on arguments specified
+//------------------------------------------------------------------------------
+if (source.empty())
+{
+ // this might be a call to link a program instead of compile a source (or asm source)
+ dprintf("NOTME: starting as cc '%s ...'\n", realcc.c_str());
+ execvp(realcc.c_str(), &(argv[origargi]));
+ fprintf(stderr, "ERROR: returned from execvp() call to run %s\n", realcc.c_str());
+}
+if (object.empty())
+{
+ dprintf("no object file given, default to source name\n");
+ // gcc builds object name from source name if no -o given, replacing
+ // suffix with .o. The file is placed in the current directory,
+ // not in the source directory!
+ string n;
+ string d;
+ string s;
+ fileparse(source, n, d, s);
+ if (!n.empty() && !s.empty())
+ {
+ object = n + ".o";
+ dprintf("tracpp: guessing object name %s\n", object.c_str());
+ dprintf(" from source name %s\n", source.c_str());
+ }
+ else
+ {
+ fprintf(stderr, "Unable to determine Source File Name\n");
+ exit(1);;
+ }
+}
+
+// set value of trace hash according to language
+// check source file extension if no explicit -x option given
+if (!optx_found)
+{
+ if (realcc.find("g++") != string::npos)
+ {
+ dprintf("compiler language: C++ (from compiler name)\n");
+ cctype = "c++";
+ }
+ else
+ {
+ if (source.substr(source.length()-2) == ".c")
+ {
+ dprintf("compiler language: C (from source file extension)\n");
+ cctype = "c";
+ }
+ else if (source.substr(source.length()-2) == ".S")
+ {
+ dprintf("compiler language: assembly (from source file extension)\n");
+ cctype = "assembler-with-cpp";
+ }
+ else
+ {
+ dprintf("compiler language: C++ (default)\n");
+ cctype = "c++";
+ }
+ }
+}
+else
+{
+ dprintf("compiler language: %s (from option '-x')\n", cctype.c_str());
+}
+
+if (cctype == "c")
+{
+ hashtype = "(unsigned short)";
+ hashtype_suffix = "U";
+}
+else if (cctype == "assembler-with-cpp")
+{
+ hashtype = "";
+ hashtype_suffix = "";
+}
+else
+{
+ hashtype = "(trace_hash_val)";
+ hashtype_suffix = "U";
+}
+// define TRAC_PPETRACEPP for macros
+tmp = "-DTRAC_PPETRACEPP -DTRAC_PPVER=";
+tmp += macro_version;
+cppopts.push_back(tmp);
+if (dodeps)
+{
+ if (depfile.empty())
+ {
+ if ((p_env = getenv("DEPENDENCIES_OUTPUT")) != NULL)
+ {
+ depfile = p_env;
+ }
+ else if ((p_env = getenv("SUNPRO_DEPENDENCIES")) != NULL)
+ {
+ depfile = p_env;
+ }
+ else
+ {
+ depfile = object;
+ if (depfile.substr(depfile.length()-2) == ".o")
+ {
+ depfile = depfile.substr(0, depfile.length()-2);
+ depfile += ".d";
+ }
+ }
+ }
+ tmp = "-MD -MF ";
+ tmp += depfile;
+ cppopts.push_back(tmp);
+}
+
+//------------------------------------------------------------------------------
+// start cpp
+//------------------------------------------------------------------------------
+cmd = realcpp;
+for(vector<string>::iterator p = cppopts.begin(); p != cppopts.end(); ++p)
+{
+ cmd += " ";
+ cmd += *p;
+}
+cmd += " ";
+cmd += source;
+cmd += " -o-";
+dprintf("starting as cpp '%s'\n", cmd.c_str());
+CPP = popen(cmd.c_str(), "r");
+if (CPP == NULL)
+{
+ fprintf(stderr, "cannot start cpp '%s'\n", realcpp.c_str());
+ perror("");
+ exit(1);
+}
+
+//------------------------------------------------------------------------------
+// start cc. manually set language as source file extension not available to cc
+//------------------------------------------------------------------------------
+string type_str = "";
+if (!optx_found)
+{
+ // no option -x given by caller, set manually
+ type_str = "-x ";
+ type_str += cctype;
+}
+cmd = realcc;
+cmd += " ";
+cmd += type_str;
+for(vector<string>::iterator p = ccopts.begin(); p != ccopts.end(); ++p)
+{
+ cmd += " ";
+ cmd += *p;
+}
+cmd += " -o ";
+cmd += object;
+dprintf("starting as cc '%s'\n", cmd.c_str());
+CC = popen(cmd.c_str(), "w");
+if (CC == NULL)
+{
+ fprintf(stderr, "cannot start cc '%s'\n", realcc.c_str());
+ perror("");
+ exit(1);
+}
+
+string modifiedfile;
+string unmodifiedfile;
+if (debug)
+{
+ modifiedfile = object + ".debug";
+ DEBUG = fopen(modifiedfile.c_str(), "w");
+ if (DEBUG == NULL)
+ {
+ string msg = "cannot open file ";
+ msg += modifiedfile;
+ perror(msg.c_str());
+ modifiedfile = "";
+ }
+ else
+ {
+ fprintf(stderr, "writing preprocessed source to %s\n", modifiedfile.c_str());
+ }
+ unmodifiedfile = object + ".debug_in";
+ DEBUGIN = fopen(unmodifiedfile.c_str(), "w");
+ if (DEBUGIN == NULL)
+ {
+ string msg = "cannot open file ";
+ msg += unmodifiedfile;
+ perror(msg.c_str());
+ unmodifiedfile = "";
+ }
+ else
+ {
+ fprintf(stderr, "writing unprocessed source to %s\n", unmodifiedfile.c_str());
+ }
+}
+
+string oldline;
+string newline;
+static const int MAX_BUFFER = 51200;
+char buf[MAX_BUFFER];
+while (!feof(CPP))
+{
+ if (fgets(buf, MAX_BUFFER, CPP) != NULL)
+ {
+ oldline = buf;
+ if (DEBUGIN) { fprintf(DEBUGIN, "%s", oldline.c_str()); }
+ parse_line(hashtab, oldline, newline);
+ //#print "oldline = $oldline";
+ //#print "newline = $newline";
+ if (newline.empty())
+ {
+ fprintf(stderr, "hash error in/with file %s\n", source.c_str());
+ exit(1);
+ }
+ //#print "newline = $newline\n";
+ fprintf(CC, "%s", newline.c_str());
+ if (DEBUG) { fprintf(DEBUG, "%s", newline.c_str()); }
+ }
+}
+if (DEBUG) { fclose(DEBUG); }
+if (DEBUGIN) { fclose(DEBUGIN); }
+int cmd_rc = pclose(CPP);
+if (cmd_rc)
+{
+ fprintf(stderr, "error from cpp\n");
+ if (cmd_rc & 127)
+ {
+ fprintf(stderr, "cpp got signal %d\n", (cmd_rc & 127));
+ exit(1);
+ }
+ else if (cmd_rc >> 8)
+ {
+ fprintf(stderr, "cpp returned %d\n", (cmd_rc >> 8));
+ exit(cmd_rc >> 8);
+ }
+}
+cmd_rc = pclose(CC);
+if (cmd_rc)
+{
+ fprintf(stderr, "error from cc\n");
+ if (cmd_rc & 127)
+ {
+ fprintf(stderr, "cc got signal %d\n", (cmd_rc & 127));
+ exit(1);
+ }
+ else if (cmd_rc >> 8)
+ {
+ fprintf(stderr, "cc returned %d\n", (cmd_rc >> 8));
+ exit(cmd_rc >> 8);
+ }
+}
+
+if (!hashtab.empty())
+{
+ string stringfile = object;
+ stringfile += ".ppe.hash";
+ // open trace string file
+ FILE* TRC = fopen(stringfile.c_str(), "w");
+ if (TRC == NULL)
+ {
+ fprintf(stderr, "cannot write trace string file '%s'\n", stringfile.c_str());
+ exit(1);
+ }
+ dprintf("Writing to file %s\n", stringfile.c_str());
+
+ string pwd;
+ FILE* PWD = popen("pwd", "r");
+ fgets(buf, MAX_BUFFER, PWD);
+ pwd = buf;
+ pclose(PWD);
+ time_t tt = time(NULL);
+ sprintf(buf, "%s", asctime(localtime(&tt)));
+ buf[strlen(buf)-1] = '\0'; // chop off extra newline
+ fprintf(TRC, "#FSP_TRACE_v2|||%s|||BUILD:%s", buf, pwd.c_str());
+
+ string srch_str = "||";
+ srch_str += source;
+ int srch_str_len = srch_str.length();
+ size_t pos;
+ for(map<string,string>::iterator p = hashtab.begin(); p != hashtab.end(); ++p)
+ {
+ pos = (p->second).find(srch_str);
+ if ((pos != string::npos) && ((pos + srch_str_len) == (p->second).length()))
+ {
+ // source file name is already part of the string
+ fprintf(TRC, "%s||%s\n", (p->first).c_str(), (p->second).c_str());
+ }
+ else
+ {
+ fprintf(TRC, "%s||%s||%s\n", (p->first).c_str(), (p->second).c_str(), source.c_str());
+ }
+ //#print TRC "$key||$source||$hashtab{$key}\n";
+ }
+ fclose(TRC);
+}
+else
+{
+ dprintf("No trace calls/strings found, not writing hash file\n");
+}
+} // end main
diff --git a/src/tools/ppetracepp/trac_interface.h b/src/tools/ppetracepp/trac_interface.h
new file mode 100755
index 00000000..2ff9dff0
--- /dev/null
+++ b/src/tools/ppetracepp/trac_interface.h
@@ -0,0 +1,369 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/trac_interface.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 trac_interface.h
+// @brief Interface codes for TRAC component.
+*/
+/******************************************************************************
+ *
+ * @page ChangeLogs Change Logs
+ * @section _trac_interface_h trac_interface.h
+ * @verbatim
+ *
+ * Flag Def/Fea Userid Date Description
+ * ------- ---------- -------- ---------- ----------------------------------
+ * TEAM 06/16/2010 Port
+ * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+ * @pb00E pbavari 03/11/2012 Added correct include file
+ * @at009 859308 alvinwan 10/15/2012 Added tracepp support
+ * @ai005 860268 ailutsar 11/20/2012 Create trace test applet
+ * @rc005 864101 rickylie 12/12/2012 add small circ buffer to handle ISR semaphore conflict
+ *
+ * @endverbatim
+ *
+ *///*************************************************************************/
+
+#ifndef _TRAC_INTERFACE_H
+#define _TRAC_INTERFACE_H
+
+/** \defgroup Trace Trace Component
+ * Port of the trace code used in the fsp and tpmd.
+ */
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+/**
+ * \defgroup TracMacros Trace Component Macro Interfaces
+ * \ingroup Trace
+ * Used to trace 0 - 5 arguments or a binary buffer when using a hash value.
+ */
+/*@{*/
+
+
+// @at009c - start
+#define TRACE(i_td,i_string,args...) \
+ trace_adal_write_all(i_td,trace_adal_hash(i_string,-1),__LINE__,0,##args)
+
+#define TRACEBIN(i_td,i_string,i_ptr,i_size) \
+ trac_write_bin(i_td,trace_adal_hash(i_string,0),__LINE__,i_ptr,i_size)
+
+#ifndef NO_TRAC_STRINGS
+
+#define FIELD(a) \
+ printf("%s",a)
+
+#define FIELD1(a,b) \
+ printf("%s%lx",a,(unsigned long)b)
+
+#else // NO_TRAC_STRINGS
+
+#define FIELD(a)
+
+#define FIELD1(a,b)
+
+#endif // NO_TRAC_STRINGS
+
+#define SUCCESS 0
+// @at009c - end
+
+
+
+/*@}*/
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+#define TRACE_MAX_ARGS 5 /*!< Maximum number of args to trace */
+
+typedef uint32_t trace_hash_val;
+
+// NOTE! Increment this when new components are added!
+#define TRAC_NUM_TRACE_COMPONENTS 1
+
+
+#define TRACE_BUFFER_SIZE 8192 // @ai005a
+
+#define CIRCULAR_BUFFER_SIZE 4 // @rc005a
+
+typedef uint32_t UINT32;
+typedef int32_t INT32;
+typedef uint8_t UCHAR;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef char CHAR;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+typedef int INT;
+typedef void VOID;
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+/*
+ * @brief Structure is put at beginning of all trace buffers
+ */
+typedef struct trace_buf_head {
+ UCHAR ver; /*!< version of this struct (1) */
+ UCHAR hdr_len; /*!< size of this struct in bytes */
+ UCHAR time_flg; /*!< meaning of timestamp entry field */
+ UCHAR endian_flg; /*!< flag for big ('B') or little ('L') endian */
+ CHAR comp[16]; /*!< the buffer name as specified in init call */
+ UINT32 size; /*!< size of buffer, including this struct */
+ UINT32 times_wrap; /*!< how often the buffer wrapped */
+ UINT32 next_free; /*!< offset of the byte behind the latest entry */
+ UINT32 te_count; /*!< Updated each time a trace is done */
+ UINT32 extracted; /*!< Not currently used */
+}trace_buf_head_t;
+
+/*!
+ * @brief Timestamp and thread id for each trace entry.
+ */
+typedef struct trace_entry_stamp {
+ UINT32 tbh; /*!< timestamp upper part */
+ UINT32 tbl; /*!< timestamp lower part */
+ UINT32 tid; /*!< process/thread id */
+}trace_entry_stamp_t;
+
+/*
+ * @brief Structure is used by adal app. layer to fill in trace info.
+ */
+typedef struct trace_entry_head {
+ UINT16 length; /*!< size of trace entry */
+ UINT16 tag; /*!< type of entry: xTRACE xDUMP, (un)packed */
+ UINT32 hash; /*!< a value for the (format) string */
+ UINT32 line; /*!< source file line number of trace call */
+}trace_entry_head_t;
+
+/*
+ * @brief Parameter traces can be all contained in one write.
+ */
+typedef struct trace_entire_entry {
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+ UINT32 args[TRACE_MAX_ARGS + 1];
+} trace_entire_entry_t;
+
+
+/*
+ * @brief Binary first writes header and time stamp.
+ */
+typedef struct trace_bin_entry {
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+} trace_bin_entry_t;
+
+/**
+ * @brief Used as input to traces to get to correct buffer.
+ */
+typedef trace_buf_head_t * tracDesc_t;
+
+/*
+ * @brief Structure is used to hold array of all trace descriptors
+ */
+typedef struct trace_descriptor_array
+{
+ tracDesc_t *entry; /*!< Pointer to trace descriptor */
+ CHAR *comp; /*!< Pointer to component name */
+}trace_descriptor_array_t;
+
+// @rc005a - start
+typedef struct circular_buf_head
+{
+ UINT32 head; // pointer to head
+ UINT32 tail; // pointer to tail
+ UINT32 entryCount; // nums of entry
+} circular_buf_header_t;
+
+
+typedef struct circular_entire_data {
+ UINT32 len;
+ CHAR comp[4];
+ trace_entire_entry_t entry;
+} circular_entire_data_t;
+
+// @rc005a - end
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+// All TPMF component trace descriptors.
+extern tracDesc_t g_trac_inf; // @at009a
+extern tracDesc_t g_trac_err; // @at009a
+extern tracDesc_t g_trac_imp; // @at009a
+
+extern const trace_descriptor_array_t g_des_array[];
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+
+/**
+ * \defgroup TracIntefaces Trace Component Interfaces for External Use
+ * \ingroup Trace
+ */
+/*@{*/
+
+
+/**
+ * @brief Allocate and initialize all trace buffers in memory.
+ *
+ * This function will allocate memory for each of the pre-defined trace
+ * buffers, initilize the buffers with starting data, and setup the
+ * trace descriptors which each component will use to trace.
+ *
+ * This function must be called first before any components try to trace!
+ *
+ * @return Non-zero return code on error.
+ */
+UINT TRAC_init_buffers(void);
+
+/**
+ * @brief Retrieve full trace buffer for component i_comp
+ *
+ * This function assumes memory has already been allocated for
+ * the full trace buffer in o_data.
+ *
+ * @param i_td_ptr Trace descriptor of buffer to retrieve.
+ * @param o_data Pre-allocated pointer to where data will be stored.
+ *
+ * @return Non-zero return code on error
+ */
+UINT TRAC_get_buffer(const tracDesc_t i_td_ptr,
+ void *o_data);
+
+/**
+ * @brief Retrieve partial trace buffer for component i_comp
+ *
+ * This function assumes memory has already been allocated for
+ * the trace buffer (size io_size). This function will copy
+ * in up to io_size in bytes to the buffer and set io_size
+ * to the exact size that is copied in.
+ *
+ * @param i_td_ptr Trace descriptor of buffer to retrieve.
+ * @param o_data Pre-allocated pointer to where data will be stored.
+ * @param io_size Size of trace data to retrieve (input)
+ * Actual size of trace data stored (output)
+ *
+ * @return Non-zero return code on error
+ */
+UINT TRAC_get_buffer_partial(const tracDesc_t i_td_ptr,
+ void *o_data,
+ UINT *io_size);
+
+/**
+ * @brief Retrieve trace descriptor for input component name
+ *
+ * @param i_comp Component name to retrieve trace descriptor for.
+ *
+ * @return Valid trace descriptor on success, NULL on failure.
+ */
+tracDesc_t TRAC_get_td(const char *i_comp);
+
+/**
+ * @brief Reset all trace buffers
+ *
+ * @return Non-zero return code on error
+ */
+UINT TRAC_reset_buf(void);
+
+/*@}*/ // Ending tag for external interface module in doxygen
+
+
+/**
+ * @brief Trace input integers to trace buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * @param io_td Intialized trace descriptor point to buffer to trace to.
+ * @param i_hash Hash value to be recorded for this trace.
+ * @param i_fmt Output format
+ * @param i_line Line number trace is occurring on.
+ * @param i_type trace type. filed or debug.
+ * @param ... parames that are limited to a size of 4 bytes, i.e. int, uint32_t, nnn*
+ *
+ * @return Non-zero return code on error.
+ */
+UINT trace_adal_write_all(tracDesc_t io_td,const trace_hash_val i_hash,
+ const char *i_fmt,const ULONG i_line, const ULONG i_type,...);
+
+
+/**
+ * @brief Trace input integers to trace buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * @param io_td Intialized trace descriptor point to buffer to trace to.
+ * @param i_hash Hash value to be recorded for this trace.
+ * @param i_line Line number trace is occurring on.
+ * @param i_num_args Number of arguments to trace.
+ * @param i_1 Input Parameter 1
+ * @param i_2 Input Parameter 2
+ * @param i_3 Input Parameter 3
+ * @param i_4 Input Parameter 4
+ * @param i_5 Input Parameter 5
+ *
+ * @return Non-zero return code on error.
+ */
+UINT trac_write_int(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const UINT i_num_args,
+ const ULONG i_1,const ULONG i_2,const ULONG i_3,
+ const ULONG i_4,const ULONG i_5
+ );
+
+
+ /**
+ * @brief Trace binary data to buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * @param io_td Intialized trace descriptor point to buffer to trace to.
+ * @param i_hash Hash value to be recorded for this trace.
+ * @param i_line Line number trace is occurring on.
+ * @param i_ptr Pointer to binary data to trace.
+ * @param i_size Size of data to copy from i_ptr.
+ *
+ * @return Non-zero return code on error.
+ */
+UINT trac_write_bin(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const void *i_ptr,
+ const ULONG i_size);
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+#endif //_TRAC_INTERFACE_H
diff --git a/src/tools/ppetracepp/tracehash.pl b/src/tools/ppetracepp/tracehash.pl
new file mode 100755
index 00000000..8855adee
--- /dev/null
+++ b/src/tools/ppetracepp/tracehash.pl
@@ -0,0 +1,896 @@
+#!/usr/bin/perl -w
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/ppetracepp/tracehash.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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 tracehash.pl created by B J Zander.
+
+use strict;
+
+sub determine_args();
+sub launch_cpp_and_parse($$);
+sub cpp_dir($);
+sub read_string_file();
+sub collect_files($);
+sub assimilate_file($);
+sub hash_strings();
+sub write_string_file();
+sub help();
+
+select (STDERR);
+$| = 1; # Make all prints to STDERR flush the buffer immediately
+select (STDOUT);
+$| = 1; # Make all prints to STDOUT flush the buffer immediately
+
+# Constants
+my $HEAD_SEP = "|||";
+my $HEAD_EYE_CATCHER = "#FSP_TRACE_v";
+my $HEAD_BUILD_FLAG = "BUILD:";
+my $HEAD_VER_FLAG = 2;
+my $BB_STRING_FILE = "/opt/fsp/etc/BB_StringFile";
+
+# Global Variables
+my $debug = 0;
+my $seperator = "&&&&";
+my $file_name = "sbeStringFile";
+my $in_sand;
+my ($backing) = $ENV{'bb'};
+my $hash_prog = "trexhash"; #default to in path
+my $build = "";
+my ($sandbox) = $ENV{'SANDBOX'} || "";
+my ($context) = $ENV{'CONTEXT'} || "";
+my ($sandboxbase) = $ENV{'SANDBOXBASE'} || "";
+my ($bb);
+my ($sourcebase) = "$sandboxbase/src";
+my ($version) = $HEAD_VER_FLAG; # default to oldest version
+my ($collect) = 0;
+my ($INCLUDE, $Arg, $file, $dir, $string_file);
+my $args = "";
+
+my $fail_on_collision = 0; # 1 = exit with error if hash collision occurs
+my $hash_filename_too = 0; # 1 = hash is calculated over format string + filename
+
+print "sourcebase = $sourcebase\n" if $debug;
+print "sandbox = $sandbox\n" if $debug;
+print "backing = $backing\n" if $debug;
+print "context = $context\n" if $debug;
+
+if ($context =~ /x86/)
+{
+ $bb = "i586-pc-linux-gnu";
+}
+else
+{
+ $bb = "powerpc-linux";
+}
+
+if(($sourcebase =~ /\w+/) && ($sandbox =~ /\w+/))
+{
+ $INCLUDE = "-I $sandboxbase/export/$context/fips/include -I $backing/export/$context/fips/include -I /opt/fsp/$bb/include/fsp -I/opt/fsp/$bb/include/ -include /opt/fsp/$bb/include/fsp/tracinterface.H";
+}
+else
+{
+ print "Not in Sandbox so guessing Include Paths...\n" if $debug;
+ $INCLUDE = "-I/opt/fsp/i586-pc-linux-gnu/include/fsp -I/opt/fsp/i586-pc-linux-gnu/include/ -include /opt/fsp/i586-pc-linux-gnu/include/fsp/tracinterface.H";
+}
+
+# I/P Series work in ODE sandbox env.
+if ($sandboxbase =~ /\w+/)
+{
+ $in_sand = 1;
+ print "backing = $backing\n" if $debug;
+}
+else
+{
+ $in_sand = 0;
+}
+
+
+
+# Parse the input parameters.
+
+while (@ARGV) {
+ $Arg = shift;
+
+ if ($Arg eq "-h" || $Arg eq "-H") {
+ help();
+ exit(127);
+ }
+ if ($Arg eq "-f") {
+ $file = shift;
+ next;
+ }
+ if ($Arg eq "-d") {
+ $dir = shift;
+ next;
+ }
+ if ($Arg eq "-s") {
+ $string_file = shift;
+ next;
+ }
+ if ($Arg eq "-c") {
+ $collect = 1;
+ next;
+ }
+ if ($Arg eq "-v") {
+ $debug = 1;
+ print "debug on\n" if $debug;
+ next;
+ }
+ if ($Arg eq "-C") { # fail if a hash collision is detected
+ $fail_on_collision = 1;
+ next;
+ }
+ if ($Arg eq "-F") { # hash is calculated over format string + file name
+ $hash_filename_too = 1;
+ next;
+ }
+ if ($Arg eq "-S") {
+ $BB_STRING_FILE = "";
+ next;
+ }
+
+ #just pass it onto compiler
+ $args = $args . " " . $Arg;
+}
+
+print "args = $args\n" if $debug;
+
+if (!$file && !$dir && !$in_sand) {
+ help();
+ exit(127);
+}
+
+#################################
+# M A I N #
+#################################
+
+my $clock = `date`;
+
+$build = $HEAD_EYE_CATCHER . "$HEAD_VER_FLAG" . $HEAD_SEP . $clock . $HEAD_SEP . $HEAD_BUILD_FLAG;
+
+$build =~ s/\n//g;
+
+# Global array to hold the parsed TRAC macro calls.
+my @strings = ();
+
+# Assoc. arrays to hold hash|string values.
+my %string_file_array = ();
+my %hash_strings_array = ();
+
+# Check all provided arguments and look for defaults if not provided by user
+determine_args();
+
+# Scan the appropriate files or directories for TRAC macro calls.
+
+if (defined $dir)
+{
+
+ $build = $build . $dir; # default to put at top of string file
+ if($collect)
+ {
+ collect_files($dir);
+ }
+ else
+ {
+ cpp_dir($dir);
+ # Hash the string that have been scanned.
+ %hash_strings_array = hash_strings();
+ }
+}
+else
+{
+ $build = $build . $file; # default to put at top of string file
+
+ if($collect)
+ {
+ assimilate_file($file);
+ }
+ else
+ {
+ # make sure include path includes directory that file is in
+ if($file =~ /^(.+)\/[^\/]+\.C$/)
+ {
+
+ launch_cpp_and_parse($file,$1);
+ }
+ else
+ {
+ # No path in front of file so it has to be local dir
+ launch_cpp_and_parse($file,"./");
+ }
+ # Hash the string that have been scanned.
+ %hash_strings_array = hash_strings();
+ }
+}
+
+# Read the existing string file into memory.
+%string_file_array = read_string_file();
+
+# Write out the new string file. check for collisions of new/old string here
+write_string_file();
+
+print "Hashing Started at $clock\n";
+$clock = `date`;
+print "Hashing Finished at $clock\n";
+
+exit 0;
+
+
+#################################
+# S U B R O U T I N E S #
+#################################
+
+#=============================================================================
+# Enhance usability by figuring out which build env. we are in
+#=============================================================================
+sub determine_args() {
+
+
+ # Find trexhash program
+ # but only if needed (i.e. not in collect mode)
+ if (!$collect) {
+ my $tmp = `which $hash_prog`;
+ chomp $tmp;
+
+ if ($tmp eq '') {
+ print STDOUT "\nWarning: Program trexhash does not exist in path.\n" if $debug;
+ $hash_prog = "./trexhash";
+
+ $tmp = `which $hash_prog`;
+ chomp $tmp;
+ if ($tmp eq '') {
+ print STDOUT "\nError: Unable to find trexhash \n";
+ exit(127);
+ }
+ }
+ }
+
+ # Verify input values.
+ if ((!defined $file) && (!defined $dir)) {
+ if(!($in_sand))
+ {
+ print STDOUT "\nError: No input directory or file provided as input to scan\n";
+ exit(127);
+ }
+
+ # Assume they want sandbox scanned
+ if($collect)
+ {
+ # collect all string files generated by tracepp and merge
+ $dir = "$sandboxbase/obj/";
+ }
+ else
+ {
+ # generate our own string file by pre-compiling all source code
+ $dir = "$sandboxbase/src/";
+ }
+ print STDOUT "\n-f <file> or -d <dir> not found...scanning $dir by default\n\n";
+ }
+
+ if (!defined $string_file)
+ {
+ if ($in_sand)
+ {
+
+ # Copy the current string file from backing build into our sandbox
+ system ("cp $backing/obj/$file_name $sandboxbase/obj/$file_name")
+ if !(-e "$sandboxbase/obj/$file_name");
+
+ $string_file = "$sandboxbase/obj/$file_name";
+ }
+ else
+ {
+ $string_file = "./$file_name";
+ }
+ print STDOUT "-sf <string_file> not specified, using $string_file instead...\n\n" if $debug;
+
+ }
+
+ # Try Creating the string file
+ `touch $string_file`;
+
+ if (! -f $string_file) {
+ print STDOUT "\nError: File $string_file does not exist. Current directory may not be writable.\n\n";
+ help();
+ exit(127);
+ }
+
+ # Make sure sbeStringFile is readable/writeable
+ system("chmod ugo+rw $string_file");
+
+}
+
+#=============================================================================
+# Launch cpp script and grab input from it looking for trace calls.
+#=============================================================================
+sub launch_cpp_and_parse($$) {
+
+ my ($l_loc, $l_dir) = @_;
+
+ print "Processing file $l_loc\n" if $debug;
+ my $cmd = "/usr/bin/cpp $INCLUDE -I $l_dir $args $l_loc|";
+ print "$cmd\n" if $debug;
+ open(FH,"$cmd")
+ or die ("Cannot open $_:$!,stopped");
+
+ # Read through all lines in the file..
+ my $line = <FH>;
+ while (defined $line)
+ {
+ chop $line; # remove EOL
+ $line =~ s/^\s*//; # remove unneccesary beginning white space.
+ $line =~ s/\s*$//; # remove unneccesary ending white space.
+ # Look for lines that are trace macro calls.
+ #if (/(trace_adal_hash)(\()( *)(".+")(,)(\d)/)
+ #if ($line =~ /(.*?)(trace_adal_hash)(\()( *)(".+")(,)(\d)\)+(.*\d.*)/)
+ while($line =~ m/^(.*?)trace_adal_hash\s*\(\s*(("[^"]*"\s*)+),\s*(\d+)\s*\)(.*)$/)
+ {
+ my ($prefix, $strings, $salt, $suffix) = ($1, $2, $4, $5);
+ print STDOUT "$strings $salt\n" if $debug;
+ $strings =~ s/"\s*$//; # remove trailing " and space
+ $strings =~ s/^"//; # remove leading "
+ $strings =~ s/"\s*"//g;
+ # Check to see if it's contained on a single line, or if we
+ # have to combine lines to get a complete trace call.
+
+ # Save the macro call so it can be hashed later..
+ push (@strings, [$l_loc, $strings, $salt]);
+ $line = $suffix; # check rest of line for a second trace call
+ }
+ my $nextline = <FH>;
+ last if !defined $nextline;
+ # if a trace call is spread over multiple lines we have to add the next
+ # line from the source. the only problem is the definition/declaration
+ # of trace_adal_hash: we have to ignore that. we catch that by requiring
+ # a " after the function name. hopefully nobody writes a comment with
+ # a " after the function declaration ...
+ if ($line =~ /trace_adal_hash.*"/) {
+ $line .= $nextline;
+ } else {
+ $line = $nextline;
+ }
+ }
+ close(FH);
+}
+
+#=============================================================================
+# run cpp on all files in this directory and return the output
+#=============================================================================
+sub cpp_dir($) {
+
+ my ($l_dir) = @_;
+ my @dir_entry;
+ my $l_entry;
+
+ # Open the directory and read all entry names.
+ opendir ( DH , "$l_dir")
+ or die ("Cannot open $l_dir: $!, stopped");
+
+ print STDOUT "Processing directory $l_dir\n" if $debug;
+ @dir_entry = readdir(DH);
+ closedir(DH);
+
+ while (@dir_entry) {
+ $l_entry = shift(@dir_entry);
+
+ if ($l_dir =~ m"/$") {
+ $l_entry = "$l_dir$l_entry";
+ }
+ else {
+ $l_entry = "$l_dir/$l_entry";
+ }
+
+ # Is the entry a directory?
+ if (-d $l_entry) {
+
+ if($l_entry =~ m"/?([^/]+)$")
+ {
+ # check dir we are going into
+ print "dir = $1\n" if $debug;
+ # should we recurse into this directory.
+ if ($1 =~ m/^(\.\.?|sim[ou]|bldv)$/)
+ {
+ next; # skip '.', '..' and some fips dirs
+ }
+ cpp_dir($l_entry);
+ }
+ else
+ {
+ # unable to determine name of dir (no / in filename)
+ # should we recurse into this directory.
+ if ($l_entry =~ m/^(\.\.?|sim[ou]|bldv)$/)
+ {
+ next; # skip '.', '..' and some fips dirs
+ }
+ cpp_dir($l_entry);
+ }
+ }
+ # Is the entry a file?
+ elsif ((-f $l_entry) && ($l_entry =~ m/\.C$/)) {
+ # it's a file so
+ launch_cpp_and_parse($l_entry,$l_dir);
+ }
+ else {
+ # Not a file or directory so ignore it...
+ }
+ }
+}
+
+#=============================================================================
+# Read in strings from the existing trace string file....
+#=============================================================================
+sub read_string_file() {
+
+ my %o_strings;
+ my ($line) = "";
+ my ($l_hash) = "";
+ my ($l_str) = "";
+ my ($cur_build) = "";
+ my ($l_file) = "";
+
+
+ # Make sure we can open each file.
+ open ( FH , "<$string_file")
+ or die ("Cannot open $_: $!, stopped");
+
+ $line = <FH>;
+
+ print "first line in sbeStringFile= $line\n" if $debug;
+
+ if((defined $line) && ($line =~ /^$HEAD_EYE_CATCHER(\d)/))
+ {
+ $version = $1;
+
+ print "version = $version\n" if $debug;
+
+ #Always put latest version in file
+ $line =~ s/^$HEAD_EYE_CATCHER\d/${HEAD_EYE_CATCHER}${HEAD_VER_FLAG}/;
+
+ # Take previous version in file and use it.
+ $build = $line;
+ chomp($build);
+ $line = <FH>;
+
+ while (defined $line) {
+ chomp $line; # remove EOL
+ if($version eq "1")
+ {
+ ($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ }
+ elsif($version eq "2")
+ {
+ ($l_hash, $l_str ,$l_file) = split(/\|\|/, $line);
+ }
+ else
+ {
+ print "Unknown version of stringfile $version\n";
+ exit(127);
+ }
+ $o_strings{$l_hash} = $l_str . "||" . $l_file;
+ $line = <FH>;
+ }
+
+ }
+ else
+ { # If there is a file then we are dealing with the first
+ # version of sbeStringFile so don't look for file name.
+ if ($debug) {
+ print "version 0 stringfile detected: $string_file\n";
+ }
+
+ # there is a file and it doesn't have a header
+ $version = 0;
+
+ while (defined $line) {
+ chomp $line; # remove EOL
+ ($l_hash,$l_str) = split(/\|\|/, $line);
+ $o_strings{$l_hash} =$l_str . "||" . "NO FILE";
+ $line = <FH>;
+ }
+ }
+
+ close(FH);
+
+ #Time to look for a building block string file
+ if($BB_STRING_FILE ne "" and $string_file ne $BB_STRING_FILE and -f $BB_STRING_FILE)
+ {
+
+ # Make sure we can open the file.
+ open ( FH , "<$BB_STRING_FILE")
+ or die ("Cannot open $_: $!, stopped");
+
+ $line = <FH>;
+
+ print "first line in BB_StringFile = $line\n" if $debug;
+ if((defined $line) && ($line =~ /^$HEAD_EYE_CATCHER(\d)/))
+ {
+ $version = $1;
+
+ $line = <FH>;
+ while (defined $line)
+ {
+ chop $line; # remove EOL
+ if($version eq "1")
+ {
+ ($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ }
+ elsif($version eq "2")
+ {
+ ($l_hash, $l_str ,$l_file) = split(/\|\|/, $line);
+ }
+ #($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ $o_strings{$l_hash} = $l_str . "||" . $l_file ;
+ $line = <FH>;
+ }
+ }
+ else
+ {
+ print "*** ERROR: BB_StringFile '$BB_STRING_FILE' should always have version!!!\n"
+ }
+
+ }
+ else
+ {
+ print "$BB_STRING_FILE is not available\n" if $debug;
+ }
+ #All files are latest version now.
+ $version = $HEAD_VER_FLAG;
+ return %o_strings;
+}
+
+#=============================================================================
+# Read in strings from the existing trace string file....
+#=============================================================================
+sub collect_files($) {
+
+ my ($l_dir) = @_;
+ my (@dir_entry);
+ my ($l_entry) = "";
+
+ # Open the directory and read all entry names.
+ opendir ( DH , "$l_dir")
+ or die ("Cannot open $l_dir: $!, stopped");
+
+ print STDOUT "Processing directory $l_dir\n" if $debug;
+ @dir_entry = readdir(DH);
+ closedir(DH);
+
+ while (@dir_entry) {
+ $l_entry = shift(@dir_entry);
+
+ if ($l_dir =~ m"/$") {
+ $l_entry = "$l_dir$l_entry";
+ }
+ else {
+ $l_entry = "$l_dir/$l_entry";
+ }
+
+ # Is the entry a directory?
+ if (-d $l_entry) {
+
+ # should we recurse into this directory.
+ if ($l_entry =~ m/\/(\.\.?|sim[ou]|bldv)$/)
+ {
+ next; # skip '.', '..' and some fips dirs
+ }
+ collect_files($l_entry);
+ }
+ # Is the entry a file?
+ elsif ((-f $l_entry) && ($l_entry =~ m"\.hash$")) {
+ # it's a file so
+ assimilate_file($l_entry);
+ }
+ else {
+ # Not a file or directory so ignore it...
+ }
+ }
+
+}
+
+#=============================================================================
+# Read in data from file and add to master one
+#=============================================================================
+sub assimilate_file($) {
+
+ my ($l_loc) = @_;
+
+ my (%o_strings);
+ my ($line) = "";
+ my ($l_hash) = "";
+ my ($l_str) = "";
+ my ($l_file) = "";
+
+ # Make sure we can open each file.
+ open ( FH , "<$l_loc")
+ or die ("Cannot open $_: $!, stopped");
+
+ $line = <FH>;
+
+ print "Assimilate: first line in $l_loc = $line" if $debug;
+
+ if((defined $line) && ($line =~ /^$HEAD_EYE_CATCHER(\d)/))
+ {
+ $version = $1;
+ if ($version eq "1") {
+ if ($hash_filename_too) {
+ print "*** ERROR: hash_filename_too (-F) isn't possible with trace version 1\n";
+ print " please rebuild all .hash files and global sbeStringFile\n";
+ print " version 1 file is '$l_loc'\n";
+ exit(127);
+ }
+ } elsif ($version ne "2") {
+ print "Unknown version of stringfile $version\n";
+ exit(127);
+ }
+
+ $line = <FH>;
+
+
+ while (defined $line) {
+ chop $line; # remove EOL
+ if($version eq "1")
+ {
+ ($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ }
+ elsif($version eq "2")
+ {
+ ($l_hash, $l_str ,$l_file) = split(/\|\|/, $line);
+ }
+ my $newstring = $l_str . "||" . $l_file;
+ if (exists $hash_strings_array{$l_hash}) {
+ my $hashstr1 = $hash_strings_array{$l_hash};
+ my $hashstr2 = $newstring;
+ if (!$hash_filename_too) {
+ # hash was made over format string only, remove file name
+ $hashstr1 =~ s/\|\|.*$//;
+ $hashstr2 = $l_str;
+ }
+ if ($debug) {
+ print "a_f: compare $hashstr1\n",
+ " vs. $hashstr2\n";
+ }
+ if ($hashstr1 ne $hashstr2)
+ {
+ print "*** ERROR: HASH Collision! (a_f)\n",
+ " Two different strings have the same hash value ($l_hash)\n",
+ " String 1: $hash_strings_array{$l_hash}\n",
+ " String 2: $newstring\n";
+ if ($fail_on_collision) {
+ exit(1);
+ }
+ }
+ }
+ $hash_strings_array{$l_hash} = $newstring;
+ $line = <FH>;
+ }
+
+ }
+ else
+ { # If there is a file then we are dealing with the first
+ # version of sbeStringFile so don't look for file name.
+ # these files shouldn't be there anymore. we don't check for collisions here
+ if ($debug) {
+ print "version 0 stringfile detected: $string_file\n";
+ }
+
+ if(defined $line)
+ {
+ # there is a file and it doesn't have a header
+ $version = 0;
+ }
+
+ while (defined $line) {
+ chop $line; # remove EOL
+ ($l_hash,$l_str) = split(/\|\|/, $line);
+ $hash_strings_array{$l_hash} = $l_str . "||" . "NO FILE";
+ $line = <FH>;
+ }
+ }
+ $version = $HEAD_VER_FLAG;
+ close(FH);
+}
+
+#=============================================================================
+
+#=============================================================================
+sub hash_strings() {
+
+ my ($hash_val, $l_key, $l_hash, %l_hash_strings);
+ my ($line_feed) = chr(10);
+ my ($l_file_name) = "NO FILENAME";
+ print "\nHashing printf strings.\n\n";
+
+ foreach my $str (@strings) {
+ my $printf_string;
+ $l_file_name = $str->[0];
+ $printf_string = $str->[1];
+ $l_key = $str->[2];
+ print "printf_string = $printf_string\n" if $debug;
+ $printf_string =~ s/"\s?"//g; #multi line traces will have extra " in them
+ $printf_string =~ s/`/\\`/g; # excape '
+ $printf_string =~ s/\\n/$line_feed/g; # escape \n
+ if ($hash_filename_too) {
+ $printf_string .= "||" . $l_file_name;
+ }
+
+ # call the hasher.
+ print "$hash_prog \"$printf_string\" $l_key\n" if $debug;
+ $hash_val = `$hash_prog \"$printf_string\" $l_key`;
+ if ($?) {
+ my ($hp_ret, $hp_sig) = ($? >> 8, $? & 127);
+ if ($hp_sig) {
+ print "*** ERROR: $hash_prog died with signal $hp_sig\n";
+ } elsif ($hp_ret) {
+ print "*** ERROR: $hash_prog returned the error $hp_ret\n";
+ if ($hash_val) {
+ print " error from $hash_prog:\n$hash_val";
+ }
+ }
+ exit(1);
+ }
+ print "printf_string = $printf_string l_key = $l_key hash val = $hash_val\n" if $debug;
+
+ # undo escaping
+ $printf_string =~ s/$line_feed/\\n/g;
+ $printf_string =~ s/\\`/`/g;
+
+ if (exists $l_hash_strings{$hash_val})
+ {
+ # hash val was found before. check if it's the same string
+ # else we have a hash collision
+ my $l_tmp = $l_hash_strings{$hash_val};
+ if (!$hash_filename_too) {
+ $l_tmp =~ s/\|\|.*$//;
+ }
+ if ($l_tmp ne $printf_string)
+ {
+ print "*** ERROR: HASH Collision! (h_s)\n",
+ " Two different strings have the same hash value ($hash_val)\n",
+ " String 1: $l_hash_strings{$hash_val}\n",
+ " String 2: $printf_string (file $l_file_name)\n";
+ if ($fail_on_collision) {
+ exit(1);
+ }
+ }
+ }
+ # this will overwrite an old string with a new one if a collision occurred
+ # but we might want to bail out in this case anyway
+ $printf_string = $printf_string . "||" . $l_file_name;
+ $l_hash_strings{$hash_val} = $printf_string;
+ }
+ return %l_hash_strings;
+}
+#=============================================================================
+
+#=============================================================================
+sub write_string_file() {
+
+ my (@keys) = ();
+ my ($l_key) = "";
+
+ # Combine the contents of the existing string file with the trace calls
+ # that we have just hashed.
+ print STDOUT "\nCombining Hash strings...\n\n";
+
+ @keys = keys(%hash_strings_array);
+
+ foreach $l_key (@keys) {
+ my $l_tmp = $hash_strings_array{$l_key}; # freshly collected strings
+ if (exists $string_file_array{$l_key})
+ { # hash exists in list from sbeStringFile
+ my $l_tmp2 = $string_file_array{$l_key};
+ if (!$hash_filename_too) {
+ $l_tmp =~ s/\|\|.*$//;
+ $l_tmp2 =~ s/\|\|.*$//;
+ }
+
+ # Check for hash collisions.
+ if ($l_tmp ne $l_tmp2)
+ {
+ print "*** ERROR: HASH Collision! (w_s_f)\n",
+ " Two different strings have the same hash value ($l_key)\n",
+ " String 1: $hash_strings_array{$l_key}\n",
+ " String 2: $string_file_array{$l_key}\n";
+ if ($fail_on_collision) {
+ exit(1);
+ }
+ # don't fail, write new one
+ }
+ }
+ if($version > 0)
+ {
+ # add/replace the new string to the string_file_array.
+ $string_file_array{$l_key} = $hash_strings_array{$l_key}
+ }
+ else
+ {
+ # old version so only write out format string (not file name to)
+ $string_file_array{$l_key} = $l_tmp;
+ }
+ }
+
+ # Write out the updated string file.
+ print STDOUT "\nWriting updated hash||string file...\n\n";
+
+ @keys = sort(keys(%string_file_array));
+
+ open ( FH , ">$string_file")
+ or die ("Cannot open $_: $!, stopped");
+
+ if($version > 0)
+ {
+ print FH "$build\n"; # only print version if newer then version 0
+ }
+ foreach $l_key (@keys) {
+ print FH "$l_key||$string_file_array{$l_key}\n";
+ }
+ close FH;
+}
+#=============================================================================
+
+#=============================================================================
+# Display command invokation help for this program...
+#=============================================================================
+sub help() {
+ print << "EOF";
+tracehash.pl - create a trace string file from sources or collect tracepp files
+Usage: tracehash.pl [options]
+ General options:
+ -h - Print this help text.
+ -v - Be verbose, tell what's going on (debug output)
+ Operation modes
+ -c - Collect StringFiles created by tracepp and merge.
+ default - Scan source files for trace calls.
+
+Collect mode: tracehash.pl -c [-vFCS] [-d <dir>] [-s <string_file>]
+ tracehash.pl -c [-vFCS] [-f <file>] [-s <string_file>]
+ Collect string files created by tracepp (.hash) from directory tree at
+ <dir> or read them from string file <file> and write to file
+ <string_file>, adding entries already in this file.
+ -f - String file to read and write/add to <string_file>.
+ -d - Start of directory tree to scan for .hash files. Default = .
+ -s - File with trace strings (and hashes) to read from and write to
+ default = ./sbeStringFile
+ -F - hash is calculated over trace string and source file name,
+ otherwise without source file name
+ -C - report an error if a hash collisions occurs
+ -S - don't read global FLD-2.2 string file ($BB_STRING_FILE)
+ If tracehash.pl is called in a FipS build sandbox without -d and -f
+ defaults for the sandbox will be used.
+
+Scan mode: tracehash.pl [-vFCS] [-d <dir>] [-s <string_file>] [ccpopts]
+ tracehash.pl [-vFCS] [-f <file>] [-s <string_file>] [cppopts]
+ Scan all files in directory tree <dir> or scan file <file> and write
+ strings to file <string_file>. Strings already in this file will be merged.
+ -f - Source file to scan for trace entries.
+ -d - Source directory to scan for trace entries.
+ -s - File with trace strings (and hashes) to read from and write to.
+ default = ./sbeStringFile
+ -F - hash for string was build from format string + source file name
+ -C - report an error if hash collisions occur
+ -S - don't read global FLD-2.2 string file ($BB_STRING_FILE)
+ All other arguments will be passed verbatim to cpp
+EOF
+}
+#=============================================================================
+
diff --git a/src/tools/scripts/parseErrorInfo.pl b/src/tools/scripts/parseErrorInfo.pl
new file mode 100755
index 00000000..839a836c
--- /dev/null
+++ b/src/tools/scripts/parseErrorInfo.pl
@@ -0,0 +1,1663 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/parseErrorInfo.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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 parseErrorInfo.pl
+# @brief This perl script will parse HWP Error XML files and generate required
+# FAPI code to create and error log and add FFDC to the error.
+#
+# *HWP HWP Owner: N/A
+# *HWP FW Owner: Thi Tran <thi@us.ibm.com>
+# *HWP Team: N/A
+# *HWP Level: 1
+# *HWP Consumed by: HB
+#
+# Usage:
+# parseErrorInfo.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";
+my $mcast_type = "fapi2::mcast_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_local_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,
+ "local-ffdc" => \$arg_local_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.H. 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;
+ my $objectNumber = 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 = "\ttemplate< typename T >\n";
+ $method .= "\tinline $class_name& set_$ffdc_uc(const T& $param)\n";
+
+ if(!$arg_local_ffdc)
+ {
+ $method_body = " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() =";
+ $method_body .= " fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+ else
+ {
+ # need to use the objectNumber here so when we decode the info at the hwsv/hb side we have a reference, they will
+ # be copied into/out of the sbe buffer in the correct order
+ $method_body .= "\t{\n\t\tfapi2::g_FfdcData.ffdcData[$objectNumber].data= convertType(i_value);\n";
+ $method_body .= "\t\tfapi2::g_FfdcData.ffdcData[$objectNumber].size =";
+ $method_body .=" fapi2::getErrorInfoFfdcSize(i_value);\n";
+ $method_body .= "\t\tfapi2::g_FfdcData.ffdcLength += sizeof(sbeFfdc_t);\n";
+ $method_body .= "\t\treturn *this;\n\t};\n\n";
+ }
+
+ }
+ elsif ($type eq $mcast_type )
+ {
+# uncomment once multicast is understood more
+# $method = "\n\t\ttemplate< typename T >\n";
+# $method .= "\t\tinline $class_name& set_$ffdc_uc(const T& $param)\n";
+#
+# if(!$arg_local_ffdc)
+# {
+# $method_body = " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+# $methods->{$key}{member} = "$mcast_type $ffdc_uc;\n ";
+# }
+# else
+# {
+# $method_body .= "\t\t{\n\t\t\tfapi2::g_ErrorInfoFfdc[$objectNumber].iv_ffdcId = fapi2::EI_TYPE_FFDC;\n";
+# $method_body .= "\t\t\tfapi2::g_ErrorInfoFfdc[$objectNumber].iv_ffdc.ptr() = &i_value;\n";
+# $method_body .= "\t\t\tfapi2::g_ErrorInfoFfdc[$objectNumber].iv_ffdc.size() = fapi2::getErrorInfoFfdcSize(i_value);";
+# $method_body .= "\n\t\t\treturn *this;\n\t\t};\n\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\n");
+ 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.H";
+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 "#if !defined(FAPI2_NO_FFDC) && !defined(MINIMUM_FFDC)\n";
+#print ECFILE "#include <collect_reg_ffdc.H>\n";
+print ECFILE "#endif\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";
+if($arg_local_ffdc)
+{
+ print ECFILE "extern SbeFfdcData_t g_FfdcData; \n";
+}
+#------------------------------------------------------------------------------
+# Print start of file information to collectRegFfdc.H
+#------------------------------------------------------------------------------
+print CRFILE "// collect_reg_ffdc.H\n";
+print CRFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print CRFILE "#ifndef FAPI2_COLLECT_REG_FFDC_H_\n";
+print CRFILE "#define FAPI2_COLLECT_REG_FFDC_H_\n";
+print CRFILE "#include <stdint.h>\n";
+print CRFILE "#include <vector>\n";
+print CRFILE "#include <ffdc.H>\n";
+print CRFILE "#include <hwp_error_info.H>\n";
+print CRFILE "#include <error_info_defs.H>\n";
+print CRFILE "#include <buffer.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";
+print CRFILE "namespace fapi2\n";
+print CRFILE "{\n";
+print CRFILE "template< TargetType C, TargetType P >\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 " uint32_t i_childOffsetMult = 0)\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_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, FFDC_BUFFER)\\\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','mcastId', '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}})
+ {
+ my $objectStr = "";
+ # 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});
+
+
+ #----------------------------------------------------------------------
+ # 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.
+ $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]}};
+#
+# $TODO for SBE errors we need to get the parameters from the FFDC_BUFFER passed
+ for (my $i = 1; $i <= $#elements; $i++)
+ {
+ @elements[$i] =~ s/^\s+|\s+$//g;
+ addFfdcMethod(\%methods, @elements[$i], $err->{rc});
+ }
+ }
+
+ if ($count > 0)
+ {
+ print EIFILE "}";
+ }
+ 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) ";
+
+ if(!$arg_local_ffdc)
+ {
+ 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);
+ }
+=begin
+ 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<fapi2::TARGET_TYPE_NONE, fapi2::TARGET_TYPE_NONE>($collectRegisterFfdc->{target}, ";
+ print EIFILE "fapi2::$id, RC); ";
+ 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<fapi2::$collectRegisterFfdc->{childTargets}->{childType}, fapi2::TARGET_TYPE_NONE>";
+ print EIFILE "($collectRegisterFfdc->{childTargets}->{parent}, fapi2::$id, RC); ";
+ 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<fapi2::$collectRegisterFfdc->{basedOnPresentChildren}->{childType}, fapi2::TARGET_TYPE_NONE>";
+ print EIFILE "($collectRegisterFfdc->{basedOnPresentChildren}->{target}, fapi2::$id, RC, ";
+ 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);
+ }
+ }
+=cut
+ }
+
+ }
+ 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 $eiEntryStr = "";
+ my $eiObjectMap = ""; #object names to buffer address mapping
+ my $eiObjectStr = "const void * l_objects[] = {";
+ my $executeStr = "";
+ 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_type,$objNum);
+
+ $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++;
+ }
+
+ # Multicast ID
+ foreach my $mcast (@{$err->{mcastId}})
+ {
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $ffdcName = $err->{rc} . "_";
+ $ffdcName = $ffdcName . $mcast;
+ setFfdcIdValue($ffdcName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $mcast);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $mcast, $err->{rc},$mcast_type,$objNum);
+
+ $mcast = $mangle_names{$mcast} if ($mangle_names{$mcast} 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 = 4; \\\n";
+ $eiEntryCount++;
+ }
+
+ if(!$arg_local_ffdc)
+ {
+ # 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";
+
+ if ((exists $err->{sbeError}) )
+ {
+ $objectStr .= "\t\tfapi2::ffdc_t $eiObject = getFfdcData(FFDC_BUFFER[$objCount]); \\\n";
+ }
+ }
+ 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)
+ {
+ if(!$arg_local_ffdc)
+ {
+ 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
+ {
+ print ECFILE " $class_name()\n";
+ print ECFILE " {\n\t\tfapi2::current_err = RC_$class_name;\n\t\tFAPI_ERR(\"$err->{description}\");\n";
+ print ECFILE " \tfapi2::g_FfdcData.fapiRc = RC_$class_name;\n\t}\n\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";
+ }
+
+ my $method_count = 0;
+ # Methods
+ foreach my $key (keys %methods)
+ {
+ print ECFILE $methods{$key}{method};
+ $method_count++;
+ }
+ if(!$arg_local_ffdc)
+ {
+ # add a method to adjust the severity if desired
+ print ECFILE " inline void setSev(const fapi2::errlSeverity_t i_sev)\n";
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " { iv_sev = i_sev; };\n\n";
+ }
+ else
+ {
+ print ECFILE " { static_cast<void>(i_sev); };\n\n";
+ }
+
+ # add a method to read the severity if desired
+ print ECFILE " inline fapi2::errlSeverity_t getSev() const\n";
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " { return iv_sev; };\n\n";
+ }
+ else
+ {
+ print ECFILE " { return fapi2::FAPI2_ERRL_SEV_UNDEFINED; };\n\n";
+ }
+
+ }
+
+ if( $arg_local_ffdc eq undef )
+ {
+ # 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," .
+ "bool commit = false )\n";
+ if ($arg_empty_ffdc eq undef )
+ {
+ print ECFILE " {\n";
+ print ECFILE " FAPI_SET_HWP_ERROR(iv_rc, $err->{rc});\n";
+ print ECFILE " if( commit )\n";
+ print ECFILE " {\n";
+ print ECFILE " fapi2::logError(iv_rc, " .
+ "(i_sev == fapi2::FAPI2_ERRL_SEV_UNDEFINED)" .
+ " ? iv_sev : i_sev);\n";
+ print ECFILE " }\n";
+ print ECFILE " }\n";
+
+ }
+ else
+ {
+ print ECFILE " {\n";
+ print ECFILE " static_cast<void>(i_sev);\n";
+ print ECFILE " static_cast<void>(commit);\n";
+ print ECFILE " }\n\n";
+ }
+
+ # Instance variables
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " public:\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";
+ }
+
+ }
+ else
+ {
+ print ECFILE " void execute()\n";
+ print ECFILE " {\n";
+ print ECFILE "$executeStr\n";
+ print ECFILE " }\n";
+ }
+
+ print ECFILE "};\n\n";
+
+ #----------------------------------------------------------------------
+ # If this is an SBE error, add it to set_sbe_error.H
+ #----------------------------------------------------------------------
+ if (exists $err->{sbeError})
+ {
+ print SBFILE "\tcase fapi2::$err->{rc}: \\\n";
+ print SBFILE "\t{ \\\n$objectStr";
+ print SBFILE "\t\tFAPI_SET_HWP_ERROR(RC, $err->{rc});\\\n";
+ print SBFILE " break; \\\n\t} \\\n";
+ }
+
+ }
+
+=pos
+ #
+ #--------------------------------------------------------------------------
+ # 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";
+
+# TODO: RTC 132226
+=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";
+ }
+=cut
+}
+
+#------------------------------------------------------------------------------
+# 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";
+
+# TODO: RTC 132226
+=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 (C != TARGET_TYPE_NONE)\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 (P != TARGET_TYPE_NONE)\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 CRFILE "#endif\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";
+if($arg_local_ffdc)
+{
+ print EIFILE " extern SbeFfdcData_t g_FfdcData;\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,0);\\\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/tools/scripts/ppeCreateAttrGetSetMacros.pl b/src/tools/scripts/ppeCreateAttrGetSetMacros.pl
new file mode 100755
index 00000000..72ae2aa8
--- /dev/null
+++ b/src/tools/scripts/ppeCreateAttrGetSetMacros.pl
@@ -0,0 +1,571 @@
+#!/usr/bin/perl -w
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeCreateAttrGetSetMacros.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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 $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*TargetType\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*TargetType\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/uint16_t/) {
+ $macroPostfix = "_UINT16_" . $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/int16_t/) {
+ $macroPostfix = "_INT16_" . $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_SYSTEM") {
+ $macroTarget = "SystemAttributes_t";
+ } elsif ($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<> inline void __get<fapi2::$targetMacro, fapi2attr::$macroTarget, $type, fapi2::${attribute}> ( const fapi2::Target<fapi2::$targetMacro>& i_ptarget, const fapi2attr::$macroTarget* object, const fapi2::AttributeId attrid, $type* o_pvalue )";
+ push(@newTargetDefines, $targetFunction . ";");
+
+ my $targetImplementation = "";
+ if($targetMacro eq "TARGET_TYPE_PROC_CHIP" | $targetMacro eq "TARGET_TYPE_SYSTEM") {
+
+ $targetImplementation .= "\n" . $targetFunction . "\n{\n *o_pvalue = object->fapi2attr::${macroTarget}::${attribute};\n}\n";
+
+ } elsif($targetMacro eq "TARGET_TYPE_PERV") {
+
+ $targetImplementation .= "\n" . $targetFunction .
+"\n{
+ *o_pvalue = object->fapi2attr::${macroTarget}::${attribute}[getPervAttrIndex(i_ptarget)];
+}\n";
+
+ } else {
+$targetImplementation .= "\n" . $targetFunction . "\n{\n uint32_t index = i_ptarget.getTargetNumber();\n *o_pvalue = 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<> inline void __set<fapi2::$targetMacro, fapi2attr::$macroTarget, $type, fapi2::${attribute}> ( const fapi2::Target<fapi2::$targetMacro>& i_ptarget, fapi2attr::$macroTarget* object, const fapi2::AttributeId attrid, const $type& i_pvalue )";
+ push(@newTargetDefines, $targetFunction . ";");
+
+ my $targetImplementation = "";
+
+ if($targetMacro eq "TARGET_TYPE_PROC_CHIP" | $targetMacro eq "TARGET_TYPE_SYSTEM") {
+
+ $targetImplementation = "\n" . $targetFunction . "\n{\n object->fapi2attr::${macroTarget}::${attribute} = i_pvalue;\n}\n";
+ } else {
+ $targetImplementation = "\n" . $targetFunction . "\n{\n uint32_t index = i_ptarget.getTargetNumber();\n object->fapi2attr::${macroTarget}::${attribute}[index] = i_pvalue;\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"; }
+ }
+ print OUTFILE "
+ __attribute__((always_inline)) inline uint32_t getPervAttrIndex(const fapi2::Target<TARGET_TYPE_PERV> &i_target)
+ {
+ uint32_t l_index = i_target.getTargetNumber();
+ if(PPE_TARGET_TYPE_EQ & i_target.getTargetType())
+ {
+ l_index += (EQ_TARGET_OFFSET);
+ }
+ else if(PPE_TARGET_TYPE_CORE & i_target.getTargetType())
+ {
+ l_index += (CORE_TARGET_OFFSET);
+ }
+ else if(PPE_TARGET_TYPE_MCBIST & i_target.getTargetType())
+ {
+ l_index += (MCBIST_TARGET_OFFSET);
+ }
+ else
+ {
+ l_index += (NEST_GROUP1_TARGET_OFFSET);
+ }
+ return (l_index - NEST_GROUP1_TARGET_OFFSET);
+ }
+ ";
+
+
+ foreach my $impl (@newTargetImplementations) {
+
+ print OUTFILE $impl;
+
+ }
+ }
+
+
+ }
+ 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");
+ }
+}
+
+
+
+
+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/tools/scripts/ppeCreateIfAttrService.pl b/src/tools/scripts/ppeCreateIfAttrService.pl
new file mode 100755
index 00000000..1202505a
--- /dev/null
+++ b/src/tools/scripts/ppeCreateIfAttrService.pl
@@ -0,0 +1,240 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeCreateIfAttrService.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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/tools/scripts/ppeParseAttrGetSetMacros.pl b/src/tools/scripts/ppeParseAttrGetSetMacros.pl
new file mode 100644
index 00000000..013cad96
--- /dev/null
+++ b/src/tools/scripts/ppeParseAttrGetSetMacros.pl
@@ -0,0 +1,286 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeParseAttrGetSetMacros.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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 .= "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);
+
+
+#------------------------------------------------------------------------------
+# 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 @attrSystemIds;
+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_SYSTEM") {
+
+ push(@attrSystemIds, $attr);
+
+ } elsif($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 SYFILE "// proc_sbe_fixed_system.H\n";
+print SYFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print SYFILE "#ifndef __PROC_SBE_FIXED_SYSTEM_H__\n";
+print SYFILE "#define __PROC_SBE_FIXED_SYSTEM_H__\n\n";
+foreach my $attr (@attrSystemIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print SYFILE "PROC_SBE_FIXED_$value($attr->{id});\n"
+
+
+}
+print SYFILE "\n#endif // __PROC_SBE_FIXED_SYSTEM_H__";
+
+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/tools/scripts/ppeParseAttributeInfo.pl b/src/tools/scripts/ppeParseAttributeInfo.pl
new file mode 100755
index 00000000..1b881a4d
--- /dev/null
+++ b/src/tools/scripts/ppeParseAttributeInfo.pl
@@ -0,0 +1,746 @@
+#!/usr/bin/perl -w
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeParseAttributeInfo.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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;
+
+sub help {
+ 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");
+}
+
+my $DEBUG = 0;
+my $VERBOSE = 0;
+my $help = 0;
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 2)
+{
+ print ("Invalid number of arguments\n\n");
+ help();
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use Getopt::Long;
+use Digest::MD5 qw(md5_hex);
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+GetOptions ("verbose" => \$VERBOSE,
+ "help" => \$help,
+ "debug" => \$DEBUG,
+ );
+
+if ($help)
+{
+ help();
+ exit(0);
+}
+
+if ($DEBUG)
+{
+ print "DEBUG enabled!!!!\n";
+}
+
+# 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 $echFile = $ARGV[0];
+$echFile .= "/";
+$echFile .= "fapi2ChipEcFeature.H";
+open(ECHFILE, ">", $echFile);
+
+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 fapi2_chip_ec_feature.H
+#------------------------------------------------------------------------------
+print ECHFILE "// This file is generated by perl script parseAttributeInfo.pl\n";
+print ECHFILE "// It implements the fapi2_chip_ec_feature function\n\n";
+print ECHFILE "#ifndef __FAPI2_CHIP_EC_FEATURE_H_\n";
+print ECHFILE "#define __FAPI2_CHIP_EC_FEATURE_H_\n";
+print ECHFILE "#include <fapi2AttributeService.H>\n";
+print ECHFILE "#include <fapi2AttributeIds.H>\n";
+print ECHFILE "namespace fapi2\n";
+print ECHFILE "{\n\n";
+print ECHFILE "// create a unique type from an int ( or attribute id) \n";
+print ECHFILE "template<int I>\n";
+print ECHFILE "struct int2Type {\n";
+print ECHFILE "enum { value = I };\n";
+print ECHFILE "};\n";
+print ECHFILE "ReturnCode queryChipEcAndName(\n";
+print ECHFILE " const Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,\n";
+print ECHFILE " fapi2::ATTR_NAME_Type& , fapi2::ATTR_EC_Type & );\n\n";
+print ECHFILE "template<int T>\n";
+print ECHFILE "ReturnCode queryChipEcFeature(int2Type<T> id,\n";
+print ECHFILE " const Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,\n";
+print ECHFILE " uint8_t & o_hasFeature)\n";
+print ECHFILE "{\n";
+print ECHFILE " fapi2::ATTR_NAME_Type l_chipName;\n";
+print ECHFILE " fapi2::ATTR_EC_Type l_chipEc;\n\n";
+print ECHFILE " o_hasFeature = 0;\n\n";
+print ECHFILE " ReturnCode l_rc = queryChipEcAndName(i_target, l_chipName, l_chipEc);\n";
+print ECHFILE " if (l_rc)\n";
+print ECHFILE " {\n";
+print ECHFILE " FAPI_ERR(\"queryChipEcFeature: error getting chip name\");\n";
+print ECHFILE " }\n";
+print ECHFILE " else\n";
+print ECHFILE " {\n";
+print ECHFILE " o_hasFeature = hasFeature(int2Type<T>(), l_chipName, l_chipEc);\n";
+print ECHFILE " }\n";
+print ECHFILE " return l_rc;\n";
+print ECHFILE "}\n\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];
+if ($DEBUG) { print "DEBUG:: XML filter file - $argfile\n" }
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+foreach my $entr (@{$entries->{entry}}) {
+
+ my $inname = $entr->{name};
+ if ($DEBUG) { print "DEBUG:: entr->file = $entr->{file}; \n" }
+
+ 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', 'chip']);
+
+ if ($DEBUG) { print "DEBUG:: File: ", $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', 'chip']);
+
+ # Uncomment to get debug output of all attributes
+ if ($DEBUG) { print "DEBUG:: File: ", $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 TargetType $attr->{id}_TargetTypes = ";
+
+ # Split on commas
+ my @targTypes = split(',', $attr->{targetType});
+ my $targType = $targTypes[0];
+
+ foreach my $targType (@targTypes)
+ {
+ # Remove newlines and leading/trailing whitespace
+ $targType =~ s/\n//;
+ $targType =~ s/^\s+//;
+ $targType =~ s/\s+$//;
+
+ # Consider only supported target types. The rest are ignored
+ if($targType ~~ ["TARGET_TYPE_PROC_CHIP", "TARGET_TYPE_SYSTEM",
+ "TARGET_TYPE_CORE", "TARGET_TYPE_MCS", "TARGET_TYPE_PERV",
+ "TARGET_TYPE_EQ", "TARGET_TYPE_EX"])
+ {
+ print AIFILE "$targType";
+ last;
+ }
+ else
+ {
+ next;
+ }
+ }
+ 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) ? fapi2::FAPI2_RC_SUCCESS : \\\n";
+ print AIFILE " fapi2::queryChipEcFeature(fapi2::int2Type<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 fapi2_chip_ec_feature.H
+ #----------------------------------------------------------------------
+ # Each EC attribute will generate a new inline overloaded version of
+ # hasFeature with the attribute specific logic
+ if (exists $attr->{chipEcFeature})
+ {
+ my $chipCount = 0;
+ print ECHFILE " inline uint8_t hasFeature(int2Type<$attr->{id}>,\n";
+ print ECHFILE " fapi2::ATTR_NAME_Type i_name,\n";
+ print ECHFILE " fapi2::ATTR_EC_Type i_ec)\n";
+ print ECHFILE " {\n";
+ print ECHFILE " uint8_t hasFeature = 0;\n\n";
+ print ECHFILE " if(";
+
+ foreach my $chip (@{$attr->{chipEcFeature}->{chip}})
+ {
+ if (! exists $chip->{name})
+ {
+ print ("parseAttributeInfo.pl ERROR. Att 'name' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec})
+ {
+ print ("parseAttributeInfo.pl ERROR. Att 'ec' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec}->{value})
+ {
+ print ("parseAttributeInfo.pl ERROR. Att 'value' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec}->{test})
+ {
+ print ("parseAttributeInfo.pl ERROR. Att 'test' missing\n");
+ exit(1);
+ }
+
+ if($chip->{name} eq 'ENUM_ATTR_NAME_CENTAUR')
+ {
+ # Skip Centaur chip
+ next;
+ }
+
+ $chipCount++;
+ 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 ("parseAttributeInfo.pl ERROR. test '$chip->{ec}->{test}' unrecognized\n");
+ exit(1);
+ }
+
+ if ($chipCount > 1)
+ {
+ print ECHFILE " ||\n\t";
+ }
+ print ECHFILE "((i_name == $chip->{name}) && ";
+ print ECHFILE " (i_ec $test $chip->{ec}->{value}))";
+ }
+ print ECHFILE ")\n";
+ print ECHFILE " {\n";
+ print ECHFILE " hasFeature = 1;\n";
+ print ECHFILE " }\n";
+ print ECHFILE " return hasFeature;\n";
+ print ECHFILE " };\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";
+
+
+
+
+
+ }
+ };
+ }
+}
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiAttributeIds.H
+#------------------------------------------------------------------------------
+print AIFILE "} //fapi2 \n\n";
+print AIFILE "#endif // __ASSEMBLER__\n\n";
+print AIFILE "#endif\n";
+
+print ECHFILE "}\n";
+print ECHFILE "#endif\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(ECHFILE);
+close(ACFILE);
+close(ASFILE);
+close(ITFILE);
+close(ETFILE);
diff --git a/src/tools/scripts/ppeParseProcSbeFixed.pl b/src/tools/scripts/ppeParseProcSbeFixed.pl
new file mode 100755
index 00000000..4279ca3b
--- /dev/null
+++ b/src/tools/scripts/ppeParseProcSbeFixed.pl
@@ -0,0 +1,318 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeParseProcSbeFixed.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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 $sysFile = $ARGV[0];
+$sysFile .= "/";
+$sysFile .= "proc_sbe_fixed_system.H";
+open(SYFILE, ">", $sysFile);
+
+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 @attrSystemIds;
+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};
+
+ # Skip virtual attributes
+ if(exists $entr->{virtual})
+ {
+ next;
+ }
+
+ # 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);
+ }
+
+ my @targets = split(",", $attr->{targetType});
+ my $targetTypeMatched = 0;
+
+ foreach my $target (@targets)
+ {
+
+ if ($target eq "TARGET_TYPE_SYSTEM") {
+
+ push(@attrSystemIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_PROC_CHIP") {
+
+ push(@attrChipIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_CORE") {
+
+ push(@attrCoreIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_EQ") {
+
+ push(@attrEqIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_EX") {
+
+ push(@attrExIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_PERV") {
+
+ push(@attrPervIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } else {
+
+ print ("ppeParseProcSbeFixed.pl WARNING. Unsupported ".
+ "target type: $target for attribute $inname in $infile\n");
+ next;
+
+ }
+ }
+ if($targetTypeMatched eq 0)
+ {
+ print ("ppeParseProcSbeFixed.pl ERROR. Unsupported ".
+ "target type: $attr->{targetType} for attribute $inname in $infile\n");
+ exit(1);
+ }
+ }
+ }
+ }
+}
+
+
+print SYFILE "// proc_sbe_fixed_system.H\n";
+print SYFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print SYFILE "#ifndef __PROC_SBE_FIXED_SYSTEM_H__\n";
+print SYFILE "#define __PROC_SBE_FIXED_SYSTEM_H__\n\n";
+foreach my $attr (@attrSystemIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print SYFILE "PROC_SBE_FIXED_$value($attr->{id});\n"
+
+
+}
+print SYFILE "\n#endif // __PROC_SBE_FIXED_SYSTEM_H__";
+
+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/tools/scripts/ppeSetFixed.pl b/src/tools/scripts/ppeSetFixed.pl
new file mode 100755
index 00000000..ab92ec42
--- /dev/null
+++ b/src/tools/scripts/ppeSetFixed.pl
@@ -0,0 +1,259 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeSetFixed.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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 (" ../../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");
+ print ("$attrpath/attribute_info/nest_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 @attrSystemIds;
+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}}) {
+
+ # Skip virtual attributes
+ if(exists $entr->{virtual})
+ {
+ next;
+ }
+
+ 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);
+ }
+
+ my @targets = split(",", $attr->{targetType});
+
+ my $targetTypeMatched = 0;
+
+ foreach my $target (@targets)
+ {
+ if($target eq "TARGET_TYPE_SYSTEM") {
+
+ push(@attrSystemIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_PROC_CHIP") {
+
+ push(@attrChipIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_CORE") {
+
+ push(@attrCoreIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_EQ") {
+
+ push(@attrEqIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_EX") {
+
+ push(@attrExIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_PERV") {
+
+ push(@attrPervIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } else {
+
+ print ("ppeSetFixed.pl WARNING. Ignoring unsupported".
+ " target type: $target for attribute: $inname\n");
+ next;
+
+ }
+ }
+ if($targetTypeMatched eq 0)
+ {
+ print ("ppeSetFixed.pl ERROR. No matching target type ".
+ "found for attribute: $inname\n");
+ exit(1);
+ }
+
+ }
+ }
+ }
+}
+
+
+setFixed("TARGET_TYPE_SYSTEM", @attrSystemIds);
+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/tools/scripts/src/fapi2PlatAttributeService.H b/src/tools/scripts/src/fapi2PlatAttributeService.H
new file mode 100644
index 00000000..7c992d65
--- /dev/null
+++ b/src/tools/scripts/src/fapi2PlatAttributeService.H
@@ -0,0 +1,1416 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/scripts/src/fapi2PlatAttributeService.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 <type_traits>
+#include <fapi2AttributeIds.H>
+#include <fapi2ChipEcFeature.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) \
+ _getEcFeatureOverride<ID##_Type>(ID, PTARGET, VAL)
+
+/* INSERT NEW ATTRIBUTES HERE */
+
+
+/******************************************************************************/
+/* * 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) \
+ _getAttributeArrayShort<ID##_Type, static_cast<fapi2::TargetType>(ID##_TargetTypes), ID> \
+ (ID, PTARGET, VAL)
+
+/* global set uint8_t 1D array macro */
+#define PLAT_ATTR_SET_UINT8_1D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayShort<ID##_Type, static_cast<fapi2::TargetType>(ID##_TargetTypes), ID> \
+ (ID, PTARGET, VAL)
+
+/* global get uint8_t 2D array macro */
+#define PLAT_ATTR_GET_UINT8_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayShort(ID, PTARGET, VAL[0])
+/* global set uint8_t 2D array macro */
+#define PLAT_ATTR_SET_UINT8_2D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayShort(ID, PTARGET, VAL[0])
+
+/* global get uint8_t 3D array macro */
+#define PLAT_ATTR_GET_UINT8_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayShort(ID, PTARGET, VAL[0][0])
+/* global set uint8_t 3D array macro */
+#define PLAT_ATTR_SET_UINT8_3D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayShort(ID, PTARGET, VAL[0][0])
+
+/* global get uint8_t 4D array macro */
+#define PLAT_ATTR_GET_UINT8_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayShort(ID, PTARGET, VAL[0][0][0])
+/* global set uint8_t 4D array macro */
+#define PLAT_ATTR_SET_UINT8_4D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayShort(ID, PTARGET, VAL[0][0][0])
+
+/* global get uint32_t 1D array macro */
+#define PLAT_ATTR_GET_UINT32_1D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayWord(ID, PTARGET, VAL)
+/* global set uint32_t 1D array macro */
+#define PLAT_ATTR_SET_UINT32_1D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayWord(ID, PTARGET, VAL)
+
+/* global get uint32_t 2D array macro */
+#define PLAT_ATTR_GET_UINT32_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayWord(ID, PTARGET, VAL[0])
+/* global set uint32_t 2D array macro */
+#define PLAT_ATTR_SET_UINT32_2D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayWord(ID, PTARGET, VAL[0])
+
+/* global get uint32_t 3D array macro */
+#define PLAT_ATTR_GET_UINT32_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayWord(ID, PTARGET, VAL[0][0])
+/* global set uint32_t 3D array macro */
+#define PLAT_ATTR_SET_UINT32_3D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayWord(ID, PTARGET, VAL[0][0])
+
+/* global get uint32_t 4D array macro */
+#define PLAT_ATTR_GET_UINT32_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayWord(ID, PTARGET, VAL[0][0][0])
+/* global set uint32_t 4D array macro */
+#define PLAT_ATTR_SET_UINT32_4D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayWord(ID, PTARGET, VAL[0][0][0])
+
+
+/* global get uint64_t 1D array macro */
+#define PLAT_ATTR_GET_UINT64_1D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayDoubleWord(ID, PTARGET, VAL)
+/* global set uint64_t 1D array macro */
+#define PLAT_ATTR_SET_UINT64_1D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayDoubleWord(ID, PTARGET, VAL)
+
+/* global get uint64_t 2D array macro */
+#define PLAT_ATTR_GET_UINT64_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayDoubleWord(ID, PTARGET, VAL[0])
+/* global set uint64_t 2D array macro */
+#define PLAT_ATTR_SET_UINT64_2D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayDoubleWord(ID, PTARGET, VAL[0])
+
+/* global get uint64_t 3D array macro */
+#define PLAT_ATTR_GET_UINT64_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayDoubleWord(ID, PTARGET, VAL[0][0])
+/* global set uint64_t 3D array macro */
+#define PLAT_ATTR_SET_UINT64_3D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayDoubleWord(ID, PTARGET, VAL[0][0])
+
+/* global get uint64_t 4D array macro */
+#define PLAT_ATTR_GET_UINT64_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayDoubleWord(ID, PTARGET, VAL[0][0][0])
+/* global set uint64_t 4D array macro */
+#define PLAT_ATTR_SET_UINT64_4D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayDoubleWord(ID, PTARGET, VAL[0][0][0])
+
+/* global get int macro (uint8_t, 16, 32 and 64) */
+#define PLAT_ATTR_GET_GLOBAL_INT(ID, PTARGET, VAL) \
+ _get<ID##_Type, static_cast<fapi2::TargetType>(ID##_TargetTypes), ID> \
+ (ID, PTARGET, VAL)
+
+/* global set int macro (uint8_t, 16, 32 and 64) */
+#define PLAT_ATTR_SET_GLOBAL_INT(ID, PTARGET, VAL) \
+ _set<ID##_Type, static_cast<fapi2::TargetType>(ID##_TargetTypes), ID> \
+ (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) \
+ _getAttributeOverrideArrayShort(ID, PTARGET, VAL)
+/* global get override uint8_t 2D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayShort(ID, PTARGET, VAL[0])
+/* global get override uint8_t 3D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayShort(ID, PTARGET, VAL[0][0])
+/* global get override uint8_t 4D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayShort(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) \
+ _getAttributeOverrideArrayWord(ID, PTARGET, VAL)
+/* global get override uint32_t 2D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayWord(ID, PTARGET, VAL[0])
+/* global get override uint32_t 3D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayWord(ID, PTARGET, VAL[0][0])
+/* global get override uint32_t 4D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayWord(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) \
+ _getAttributeOverrideArrayDoubleWord(ID, PTARGET, VAL)
+/* global get override uint64_t 2D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayDoubleWord(ID, PTARGET, VAL[0])
+/* global get override uint64_t 3D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayDoubleWord(ID, PTARGET, VAL[0][0])
+/* global get override uint64_t 4D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayDoubleWord(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) \
+ _getOverride<ID##_Type>(ID, PTARGET, VAL)
+
+/******************************************************************************/
+// Get string
+/******************************************************************************/
+
+extern "C"
+{
+ extern fapi2attr::SystemAttributes_t G_system_attributes asm("G_system_attributes") __attribute__ ((section (".fixed")));
+ 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")));
+
+ extern fapi2attr::SystemAttributes_t* G_system_attributes_ptr;
+ extern fapi2attr::ProcChipAttributes_t* G_proc_chip_attributes_ptr;
+ extern fapi2attr::PervAttributes_t* G_perv_attributes_ptr;
+ extern fapi2attr::CoreAttributes_t* G_core_attributes_ptr;
+ extern fapi2attr::EQAttributes_t* G_eq_attributes_ptr;
+ extern fapi2attr::EXAttributes_t* G_ex_attributes_ptr;
+
+}
+
+namespace fapi2
+{
+
+
+// Parameters are done as pointers (vs references) to allow the attribute
+// storage to be relocated
+template<TargetType K, typename TAttrStruct, typename TValue, AttributeId AId>
+void __set( const Target<K>& i_ptarget, TAttrStruct* object, const AttributeId attrid, const TValue& value );
+
+template<TargetType K, typename TAttrStruct, typename TValue, AttributeId AId>
+void __get( const Target<K>& i_ptarget, const TAttrStruct* object, const 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> & i_pTarget,
+ T& o_value)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint8_t& o_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_t& o_value)
+{
+ static_assert(std::is_same<T, uint16_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, 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> & i_pTarget,
+ uint32_t& o_value)
+{
+ static_assert(std::is_same<T, uint32_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, 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> & i_pTarget,
+ uint64_t& o_value)
+{
+ static_assert(std::is_same<T, uint64_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, 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> & i_pTarget,
+ uint8_t& o_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override uint16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_t& o_value)
+{
+ static_assert(std::is_same<T, uint16_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> & 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> & 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>
+ReturnCode _getEcFeatureOverride(const AttributeId i_id,
+ const Target<K> & 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> & 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> & i_pTarget,
+ uint8_t * i_pValues)
+{
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, *i_pValues );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint16_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeArrayWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint16_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _setAttributeArrayWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_t * 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> & 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> & 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> & 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> & 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> & i_pTarget,
+ uint8_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override uint16_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeOverrideArrayWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_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> & 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> & 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> & i_pTarget,
+ const T& i_value)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+
+//******************************************************************************
+// Set uint8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const uint8_t& i_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set uint16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const uint16_t& i_value)
+{
+ static_assert(std::is_same<T, uint16_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const uint32_t& i_value)
+{
+ static_assert(std::is_same<T, uint32_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id,i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, 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> & 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_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, 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> & i_pTarget,
+ int8_t& o_value)
+{
+ static_assert(std::is_same<T, int8_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get int16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t& o_value)
+{
+ static_assert(std::is_same<T, int16_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, 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> & i_pTarget,
+ int32_t& o_value)
+{
+ static_assert(std::is_same<T, int32_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, 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> & i_pTarget,
+ int64_t& o_value)
+{
+ static_assert(std::is_same<T, int64_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, 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> & i_pTarget,
+ int8_t& o_value)
+{
+ static_assert(std::is_same<T, int8_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t& o_value)
+{
+ static_assert(std::is_same<T, int16_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> & 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> & 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> & 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> & i_pTarget,
+ int8_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get int16_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeArraySignedWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int16_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _setAttributeArraySignedWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get int32_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeArraySignedWord(const AttributeId i_id,
+ const Target<K> & 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> & 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> & 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> & 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> & i_pTarget,
+ int8_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int16_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeOverrideArraySignedWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int32_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeOverrideArraySignedWord(const AttributeId i_id,
+ const Target<K> & 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> & 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> & i_pTarget,
+ const int8_t& i_value)
+{
+ static_assert(std::is_same<T, int8_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set int16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const int16_t& i_value)
+{
+ static_assert(std::is_same<T, int16_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, 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> & i_pTarget,
+ const int32_t& i_value)
+{
+ static_assert(std::is_same<T, int32_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, 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> & 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_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+} // namespace fapi2
+#endif // FAPIPLATATTRIBUTESERVICE_H_
OpenPOWER on IntegriCloud