From f2d94b5f809410300fe10dc9d0786790018463a0 Mon Sep 17 00:00:00 2001 From: Shakeeb Date: Sat, 27 Aug 2016 10:50:49 -0500 Subject: SBE code restructure: sbe -> src rename Change-Id: I6e4378d0e71a00ed2b239658d43f180df2a9b748 RTC:159709 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28875 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: RAJA DAS Reviewed-by: Sachin Gupta --- src/hwpf/src/Makefile | 51 +++ src/hwpf/src/fapi2sbefiles.mk | 49 +++ src/hwpf/src/ffdc.C | 41 +++ src/hwpf/src/plat/Makefile | 41 +++ src/hwpf/src/plat/fapi2sbeplatfiles.mk | 52 +++ src/hwpf/src/plat/plat_hw_access.C | 72 ++++ src/hwpf/src/plat/plat_utils.C | 304 ++++++++++++++++ src/hwpf/src/plat/target.C | 609 +++++++++++++++++++++++++++++++++ src/hwpf/src/plat_ring_traverse.C | 467 +++++++++++++++++++++++++ src/hwpf/src/return_code.C | 46 +++ 10 files changed, 1732 insertions(+) create mode 100644 src/hwpf/src/Makefile create mode 100644 src/hwpf/src/fapi2sbefiles.mk create mode 100644 src/hwpf/src/ffdc.C create mode 100644 src/hwpf/src/plat/Makefile create mode 100644 src/hwpf/src/plat/fapi2sbeplatfiles.mk create mode 100644 src/hwpf/src/plat/plat_hw_access.C create mode 100644 src/hwpf/src/plat/plat_utils.C create mode 100644 src/hwpf/src/plat/target.C create mode 100644 src/hwpf/src/plat_ring_traverse.C create mode 100644 src/hwpf/src/return_code.C (limited to 'src/hwpf/src') 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 +#include + + +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 +#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(*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(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 +#include +#include +#include +#include +#include + +#ifndef __PPE__ +#include +#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(i_sev); + static_cast(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(i_nanoSeconds); + static_cast(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 +#include +#include +#include + +// Global Vector containing ALL targets. This structure is referenced by +// fapi2::getChildren to produce the resultant returned vector from that +// call. +std::vector 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( + 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( + 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( + 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( + 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( + 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 + &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(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 + &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 & 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(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 & 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::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 chip_target((createPlatTargetHandle(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 target_name((createPlatTargetHandle(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 target_name((createPlatTargetHandle(i))); + fapi2::Target l_perv = target_name.getParent(); + + // 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 target_name((createPlatTargetHandle(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 target_name((createPlatTargetHandle(i))); + fapi2::Target l_perv = target_name.getParent(); + + // 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 target_name((createPlatTargetHandle(i))); + fapi2::Target l_perv = target_name.getParent(); + + // 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 target_name((createPlatTargetHandle(i))); + + fapi2::Target l_parent = target_name.getParent(); + + // Get the parent EQ's ATTR_PG + uint32_t l_eqAttrPg = 0; + FAPI_ATTR_GET(fapi2::ATTR_PG, l_parent.getParent(), 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 target_name(createPlatTargetHandle(i)); + + fapi2::Target + l_nestTarget((plat_getTargetHandleByChipletNumber(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 plat_getChipTarget() + { + + // Get the chip specific target + return ((fapi2::Target)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 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 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 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 + +#include // for RS4 decompression utilities +#include +#include // for FAPI_ATTR_GET +#include // 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& 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& 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(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(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 (), + 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 (), + 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(l_sectionAddr); + uint8_t *l_rs4Address = reinterpret_cast + (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 + +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; + } + +} -- cgit v1.2.1