summaryrefslogtreecommitdiffstats
path: root/src/hwpf/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/hwpf/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/hwpf/src')
-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
10 files changed, 1732 insertions, 0 deletions
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;
+ }
+
+}
OpenPOWER on IntegriCloud