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/include/buffer_traits.H | 241 +++++++ src/hwpf/include/error_info.H | 685 +++++++++++++++++++ src/hwpf/include/error_info_defs.H | 331 +++++++++ src/hwpf/include/fapi2.H | 77 +++ src/hwpf/include/fapi2AttributeService.H | 150 +++++ src/hwpf/include/fapi2Structs.H | 132 ++++ src/hwpf/include/fapi2_hw_access.H | 464 +++++++++++++ src/hwpf/include/fapi2_target.H | 588 ++++++++++++++++ src/hwpf/include/ffdc.H | 35 + src/hwpf/include/hw_access.H | 603 +++++++++++++++++ src/hwpf/include/hwp_ffdc_classes.H | 23 + src/hwpf/include/plat/hwp_executor.H | 64 ++ src/hwpf/include/plat/multicast.H | 54 ++ src/hwpf/include/plat/plat_attributes.H | 36 + src/hwpf/include/plat/plat_error_scope.H | 70 ++ src/hwpf/include/plat/plat_hw_access.H | 148 +++++ src/hwpf/include/plat/plat_includes.H | 39 ++ src/hwpf/include/plat/plat_ring_traverse.H | 116 ++++ src/hwpf/include/plat/plat_target.H | 215 ++++++ src/hwpf/include/plat/plat_target_definitions.H | 111 ++++ src/hwpf/include/plat/plat_target_filter.H | 89 +++ src/hwpf/include/plat/plat_target_parms.H | 92 +++ src/hwpf/include/plat/plat_target_utils.H | 86 +++ src/hwpf/include/plat/plat_trace.H | 113 ++++ src/hwpf/include/plat/target.H | 434 ++++++++++++ src/hwpf/include/return_code.H | 107 +++ src/hwpf/include/set_sbe_error.H | 23 + src/hwpf/include/utils.H | 122 ++++ src/hwpf/include/vector.H | 850 ++++++++++++++++++++++++ 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 ++ 39 files changed, 7830 insertions(+) create mode 100644 src/hwpf/include/buffer_traits.H create mode 100644 src/hwpf/include/error_info.H create mode 100644 src/hwpf/include/error_info_defs.H create mode 100644 src/hwpf/include/fapi2.H create mode 100644 src/hwpf/include/fapi2AttributeService.H create mode 100644 src/hwpf/include/fapi2Structs.H create mode 100644 src/hwpf/include/fapi2_hw_access.H create mode 100644 src/hwpf/include/fapi2_target.H create mode 100644 src/hwpf/include/ffdc.H create mode 100644 src/hwpf/include/hw_access.H create mode 100644 src/hwpf/include/hwp_ffdc_classes.H create mode 100644 src/hwpf/include/plat/hwp_executor.H create mode 100644 src/hwpf/include/plat/multicast.H create mode 100644 src/hwpf/include/plat/plat_attributes.H create mode 100644 src/hwpf/include/plat/plat_error_scope.H create mode 100644 src/hwpf/include/plat/plat_hw_access.H create mode 100644 src/hwpf/include/plat/plat_includes.H create mode 100644 src/hwpf/include/plat/plat_ring_traverse.H create mode 100644 src/hwpf/include/plat/plat_target.H create mode 100644 src/hwpf/include/plat/plat_target_definitions.H create mode 100644 src/hwpf/include/plat/plat_target_filter.H create mode 100644 src/hwpf/include/plat/plat_target_parms.H create mode 100644 src/hwpf/include/plat/plat_target_utils.H create mode 100644 src/hwpf/include/plat/plat_trace.H create mode 100644 src/hwpf/include/plat/target.H create mode 100644 src/hwpf/include/return_code.H create mode 100644 src/hwpf/include/set_sbe_error.H create mode 100644 src/hwpf/include/utils.H create mode 100644 src/hwpf/include/vector.H 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') diff --git a/src/hwpf/include/buffer_traits.H b/src/hwpf/include/buffer_traits.H new file mode 100644 index 00000000..1b299fd6 --- /dev/null +++ b/src/hwpf/include/buffer_traits.H @@ -0,0 +1,241 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/buffer_traits.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file buffer_traits.H + * @brief trait definitions for fapi2 buffer base class + */ + +#ifndef __FAPI2_BUFFER_TRAITS__ +#define __FAPI2_BUFFER_TRAITS__ + +#include +#include +#include +#include + +#ifdef FAPI2_DEBUG +#include +#endif + +#if !defined(DOXYGEN) && defined(FAPI2_DEBUG) +#include +#endif + +namespace fapi2 +{ + /// @cond + /// Types representing a container of bits. Used to create + /// variable_buffer. container_unit must remain 32-bits + /// for now - there will be a lot of code to change if it + /// changes. There are assertions helping to enforce this + /// in places in the code. + typedef uint32_t container_unit; + typedef std::vector bits_container; + + /// @brief Traits of buffers + // In general, we try to give buffers traits reflecting integral types. If + // this fails, the compiler will let someone know. + /// + /// @tparam T is the type of iv_data (std::vector, etc) + /// @tparam B is the type of the bit-specifier, typically uint32_t + template + class bufferTraits + { + public: + +#if !defined(DOXYGEN) && defined(FAPI2_DEBUG) + /// + /// @brief Print a container of bits + /// @param[in] i_data the container of bits + /// + static inline void print(const T& i_data) + { + // convert to uint64_t to prevent uint8_t from being + // printed as a char. + std::cout << "\tdata is " + << std::hex + << static_cast(i_data) + << std::dec << std::endl; + } +#endif + + /// + /// @brief Return the size of the buffer in E units + /// @tparam E, the element size. + /// @param[in] io_buffer the buffer which to size + /// @return The size of the buffer in E's rounded up + /// + template + constexpr static B size(const T& i_buffer) + { + return (bit_length(i_buffer) + + (parameterTraits::bit_length() - 1)) / + parameterTraits::bit_length(); + } + + /// + /// @brief Return the size of the buffer itself + /// @param[in] io_buffer the buffer which to size + /// @return The size of the buffer in bits (not units) + /// + constexpr static B bit_length(const T&) + { return sizeof(T) * 8; } + + /// + /// @brief Clear the buffer + /// @param[in,out] io_buffer the buffer which to clear + /// + static inline void clear(T& io_buffer) + { io_buffer = static_cast(0); } + + /// + /// @brief Set the buffer + /// @param[in,out] io_buffer the buffer which to set + /// + static inline void set(T& io_buffer) + { io_buffer = static_cast(~0); } + + /// + /// @brief Invert the buffer + /// @param[in,out] io_buffer the buffer which to invert + /// + static inline void invert(T& io_buffer) + { io_buffer = ~io_buffer; } + + /// + /// @brief Reverse the buffer + /// @param[in,out] io_buffer the buffer which to reverse + /// + static inline void reverse(T& io_buffer) + { + io_buffer = + ((io_buffer & 0xAAAAAAAAAAAAAAAA) >> 1) | + ((io_buffer & 0x5555555555555555) << 1); + } + + /// + /// @brief Get the address of the buffer as an array + /// @param[in] i_buffer the buffer which to invert + /// @return The address of the first element of the buffer + /// + static inline void* get_address(T& i_buffer) + { return (void*)&i_buffer; } + + typedef B bits_type; + typedef T unit_type; + constexpr static uint32_t bits_per_unit(void) + { return sizeof(unit_type) * 8; } + }; + + // + // + /// @brief Traits for buffers which are a container of bits + // + // + template<> + class bufferTraits + { + public: +#if !defined(DOXYGEN) && defined(FAPI2_DEBUG) + /// + /// @brief Print a container of bits + /// @param[in] i_data the container of bits + /// + static inline void print(const bits_container& i_data) + { + std::cout << "\tdata is " << std::hex; + std::copy(i_data.begin(), i_data.end(), + std::ostream_iterator(std::cout, " ")); + std::cout << std::dec << std::endl; + } +#endif + + /// + /// @brief Return the size of the buffer in E units + /// @tparam E, the element size. + /// @param[in] io_buffer the buffer which to size + /// @return The size of the buffer in E's rounded up + /// + template + constexpr static uint32_t size(const bits_container& i_buffer) + { + return (bit_length(i_buffer) + + (parameterTraits::bit_length() - 1)) / + parameterTraits::bit_length(); + } + + /// + /// @brief Return the size of the buffer itself + /// @param[in,out] io_buffer the buffer which to size + /// @return The size of the buffer in bits (not units) + /// + static inline uint32_t bit_length(const bits_container& i_buffer) + { return i_buffer.size() * sizeof(container_unit) * 8; } + + /// + /// @brief Clear the buffer + /// @param[in,out] io_buffer the buffer which to clear + /// + static inline void clear(bits_container& io_buffer) + { io_buffer.assign(io_buffer.size(), 0); } + + /// + /// @brief Set the buffer + /// @param[in,out] io_buffer the buffer which to set + /// + static inline void set(bits_container& io_buffer) + { io_buffer.assign(io_buffer.size(), ~0); } + + /// + /// @brief Invert the buffer + /// @param[in,out] io_buffer the buffer which to invert + /// + static inline void invert(bits_container& io_buffer) + { + std::transform(io_buffer.begin(), io_buffer.end(), + io_buffer.begin(), + [](container_unit u) { return ~u; }); + } + + /// + /// @brief Get the address of the buffer as an array + /// @param[in] i_buffer the buffer which to invert + /// @return The address of the first element of the buffer + /// + static inline void* get_address(bits_container& i_buffer) + { + return (void*)&(i_buffer[0]); + } + + typedef uint32_t bits_type; + typedef container_unit unit_type; + constexpr static uint32_t bits_per_unit(void) + { return sizeof(unit_type) * 8; } + }; + /// @endcond +} + + + +#endif diff --git a/src/hwpf/include/error_info.H b/src/hwpf/include/error_info.H new file mode 100644 index 00000000..cc0ae9a2 --- /dev/null +++ b/src/hwpf/include/error_info.H @@ -0,0 +1,685 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/error_info.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file error_info.H +/// @brief Defines the Error Information structures and classes +/// + +#ifndef FAPI2_ERRORINFO_H_ +#define FAPI2_ERRORINFO_H_ + +#include +#ifndef __PPE__ +#include +#endif +#include +#include +#include + +namespace fapi2 +{ +#if defined(MINIMUM_FFDC) + +// convert generic type to uint64_t +template +inline uint64_t convertType( T& i_value ) +{ + // for simplicity sake, all FFDC chunks from the SBE + // are going to be sent as a uint64_t + return static_cast(i_value); +}; + +// convert platform target handle to a uint64_t +template +inline uint64_t convertType( const fapi2::Target& i_value) +{ + // TODO: via RTC 158868 : Update this for multicast targets + // get the SBE platform target handle + return static_cast((static_cast((static_cast(i_value.get()).getFapiTargetType())) << 32) | static_cast(i_value.get()).getTargetInstance()); +}; +#endif + +#if !defined(FAPI2_NO_FFDC) && !defined(MINIMUM_FFDC) +// forward fapi2::Assert() +extern void Assert(bool); + +/// +/// @class ErrorInfoFfdc +/// +/// This class contains a copy of some FFDC data +/// +class ErrorInfoFfdc +{ + public: + /// + /// @brief Constructor + /// + /// @param[in] i_ffdcId FFDC Identifier (used to decode FFDC) + /// @param[in] i_pFfdc Pointer to the FFDC to copy + /// @param[in] i_size Size of the FFDC to copy + /// + ErrorInfoFfdc(const uint32_t i_ffdcId, + const void* i_pFfdc, + const uint32_t i_size); + + /// + /// @brief Get a pointer to the FfdcData + /// + /// @param[out] o_size Reference to uint32_t that is filled in with + /// the FFDC size + /// + /// @return void *. Pointer to the FFDC + /// + inline const void* getData(uint32_t& o_size) const + { + o_size = iv_size; + return iv_pFfdc.get(); + } + + /// + /// @brief Get a pointer to the FfdcData + /// @return void *. Pointer to the FFDC + /// + inline void* getData(void) const + { + return iv_pFfdc.get(); + } + + /// + /// @brief Get the FFDC Identifier + /// + /// @return uint32_t The FFDC Identifier + /// + inline uint32_t getFfdcId(void) + { + return iv_ffdcId; + } + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + private: + + // FFDC Identifier + uint32_t iv_ffdcId; + + // Pointer to the FFDC + std::shared_ptr iv_pFfdc; + + // Size of the FFDC + uint32_t iv_size; + + // Disabled + ErrorInfoFfdc(const ErrorInfoFfdc&) = delete; + ErrorInfoFfdc& operator=(const ErrorInfoFfdc&) = delete; +}; + +/// +/// @struct ErrorInfoHwCallout +/// +/// This struct contains hardware to callout +/// +struct ErrorInfoHwCallout +{ + /// + /// @brief Constructor. + /// + /// @param[in] i_hw Hardware to callout + /// @param[in] i_calloutPriority Priority of callout + /// @param[in] i_refTarget Reference to reference target + /// + ErrorInfoHwCallout( + const HwCallouts::HwCallout i_hw, + const CalloutPriorities::CalloutPriority i_calloutPriority, + const Target& i_refTarget); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The hw to callout + HwCallouts::HwCallout iv_hw; + + // The callout priority + CalloutPriorities::CalloutPriority iv_calloutPriority; + + // The reference target (needed for some HW callouts to identify what to + // callout). The target handle is NULL if there is no reference target. + Target iv_refTarget; +}; + +/// +/// @struct ErrorInfoProcedureCallout +/// +/// This struct contains a procedure to callout +/// +struct ErrorInfoProcedureCallout +{ + /// + /// @brief Constructor. + /// + /// @param[in] i_procedure Procedure to callout + /// @param[in] i_calloutPriority Priority of callout + /// + ErrorInfoProcedureCallout( + const ProcedureCallouts::ProcedureCallout i_procedure, + const CalloutPriorities::CalloutPriority i_calloutPriority); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The procedure to callout + ProcedureCallouts::ProcedureCallout iv_procedure; + + // The callout priority + CalloutPriorities::CalloutPriority iv_calloutPriority; +}; + +/// +/// @struct ErrorInfoBusCallout +/// +/// This struct contains a bus to callout +/// +struct ErrorInfoBusCallout +{ + /// + /// @brief Constructor. + /// + /// @param[in] i_target1 Reference to target on one end of the bus + /// @param[in] i_target2 Reference to target on other end of the bus + /// @param[in] i_calloutPriority Priority of callout + /// + ErrorInfoBusCallout( + const Target& i_target1, + const Target& i_target2, + const CalloutPriorities::CalloutPriority i_calloutPriority); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The targets on each end of the bus to callout + Target iv_target1; + Target iv_target2; + + // The callout priority + CalloutPriorities::CalloutPriority iv_calloutPriority; +}; + +/// +/// @struct ErrorInfoCDG +/// +/// This struct contains a target to callout/deconfigure/GARD +/// +struct ErrorInfoCDG +{ + /// + /// @brief Constructor. + /// + /// @param[in] i_target Reference to the target to c/d/g + /// @param[in] i_callout True if Target should be called out + /// @param[in] i_deconfigure True if Target should be deconfigured + /// @param[in] i_gard True if Target should be GARDed + /// @param[in] i_priority The priority of any callout + /// + ErrorInfoCDG(const Target& i_target, + const bool i_callout, + const bool i_deconfigure, + const bool i_gard, + const CalloutPriorities::CalloutPriority i_priority); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The target to callout/deconfigure/GARD + Target iv_target; + + // Callout Information + bool iv_callout; + CalloutPriorities::CalloutPriority iv_calloutPriority; + + // Deconfigure Information + bool iv_deconfigure; + + // GARD Information + bool iv_gard; +}; + +/// +/// @struct ErrorInfoChildrenCDG +/// +/// This struct contains children targets to callout/deconfigure/GARD +/// +/// Children by containment can be CDG (chiplets belonging to a parent chip) +/// e.g. +/// - PROC_CHIP -> EX_CHIPLET +/// - MEMBUF_CHIP -> MBA_CHIPLET +/// Children by affinity can be CDG. +/// Any from PROC_CHIP->MCS_CHIPLET->MEMBUF_CHIP->MBA_CHIPLET->DIMM e.g. +/// - PROC_CHIP->MEMBUF_CHIP +/// - MEMBUF_CHIP->DIMM +/// - MBA_CHIPLET->DIMM +/// Port and Number criteria can be applied to the child target as +/// detailed in the constructor +/// +struct ErrorInfoChildrenCDG +{ + /// + /// @brief Constructor. + /// + /// @param[in] i_parentChip Reference to the parent target + /// @param[in] i_childType Child target type to c/d/g + /// @param[in] i_callout True if Target should be called out + /// @param[in] i_deconfigure True if Target should be deconfigured + /// @param[in] i_gard True if Target should be GARDed + /// @param[in] i_priority The priority of any callout + /// @param[in] i_childPort Child Port + /// For DIMM children, the MBA port number + /// @param[in] i_childNum Child Number + /// For DIMM children, the dimm socket number + /// For Chip children, the chip position + /// For Chiplet children, the chiplet unit pos + /// + ErrorInfoChildrenCDG(const Target& i_parentChip, + const TargetType i_childType, + const bool i_callout, + const bool i_deconfigure, + const bool i_gard, + const CalloutPriorities::CalloutPriority i_priority, + const uint8_t i_childPort, const uint8_t i_childNum); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The parent chip + Target iv_parent; + + // The child target types to c/d/g + TargetType iv_childType; + + // Callout Information + bool iv_callout; + CalloutPriorities::CalloutPriority iv_calloutPriority; + + // Deconfigure Information + bool iv_deconfigure; + + // GARD Information + bool iv_gard; + + // Child Port + static const uint8_t ALL_CHILD_PORTS = 0xff; + uint8_t iv_childPort; + + // Child Number + static const uint8_t ALL_CHILD_NUMBERS = 0xff; + uint8_t iv_childNumber; +}; + +/// +/// @struct ErrorInfoCollectTrace +/// +/// This struct contains trace ID to add to the error log +/// +struct ErrorInfoCollectTrace +{ + /// + /// @brief Constructor. + /// + /// @param[in] i_traceId + /// + ErrorInfoCollectTrace(CollectTraces::CollectTrace i_traceId); + + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // trace + CollectTraces::CollectTrace iv_eiTraceId; +}; + +/// +/// @struct ErrorInfo +/// +/// This struct defines the error information associated with a fapi2::ffdc +/// Users are allowed to access the data directly +/// +struct ErrorInfo +{ + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // Vector of FFDC Data + std::vector > iv_ffdcs; + + // Vector of Hardware to callout + std::vector > iv_hwCallouts; + + // Vector of procedures to callout + std::vector > + iv_procedureCallouts; + + // Vector of buses to callout + std::vector > iv_busCallouts; + + // Vector of targets to callout/deconfigure/GARD + std::vector > iv_CDGs; + + // Vector of children targets to callout/deconfigure/GARD + std::vector > iv_childrenCDGs; + + // Vector of traces to collect + std::vector > iv_traces; +}; +/// +/// @brief Structure representing a single ErrorInfo entry. +/// +/// An array of these is passed to the addErrorInfo function when a HWP +/// generates an error by calling the FAPI_SET_HWP_ERROR macro +// Why aren't these inherited classes? Saves on allocation overhead. +// We create an array of ErrorInfoEntries as automatics when we start +// FFDC collection. If we did this as inherited classes it would either +// be allocating and deallocating or we'd need to allocate an array of +// the largest and map each struct in to it. That's messy to do without +// unions (that's what they're for) so we do it like this. The inherited +// model would result in a jump table anyway, so we're basically doing +// all of that by hand to avoid the mess. +// +struct ErrorInfoEntryFfdc +{ + uint8_t iv_ffdcObjIndex; + uint16_t iv_ffdcSize; + uint32_t iv_ffdcId; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; +}; + +/// +/// @brief Structure representing a hardware callout +/// +struct ErrorInfoEntryHwCallout +{ + uint8_t iv_hw; + uint8_t iv_calloutPriority; + uint8_t iv_refObjIndex; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; +}; + +/// +/// @brief Structure representing a procedure callout +/// +struct ErrorInfoEntryProcCallout +{ + uint8_t iv_procedure; + uint8_t iv_calloutPriority; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; + + ErrorInfoEntryProcCallout(uint8_t i_procedure, uint8_t i_calloutPriority): + iv_procedure(i_procedure), + iv_calloutPriority(i_calloutPriority) + {} + + ErrorInfoEntryProcCallout(void) = default; +}; + +/// +/// @brief Structure representing a bus callout +/// +struct ErrorInfoEntryBusCallout +{ + uint8_t iv_endpoint1ObjIndex; + uint8_t iv_endpoint2ObjIndex; + uint8_t iv_calloutPriority; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; +}; + +/// +/// @brief Structure representing a target callout +/// +struct ErrorInfoEntryTargetCDG +{ + uint8_t iv_targetObjIndex; + uint8_t iv_callout; + uint8_t iv_deconfigure; + uint8_t iv_gard; + uint8_t iv_calloutPriority; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; +}; + +/// +/// @brief Structure representing a child callout +/// +struct ErrorInfoEntryChildrenCDG +{ + uint8_t iv_parentObjIndex; + uint8_t iv_callout; + uint8_t iv_deconfigure; + uint32_t iv_childType; + uint8_t iv_childPort; + uint8_t iv_childNumber; + uint8_t iv_gard; + uint8_t iv_calloutPriority; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; +}; + +/// +/// @brief Structure representing collected trace information +/// +struct ErrorInfoEntryCollectTrace +{ + uint32_t iv_eieTraceId; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; +}; + +/// +/// @brief Union of all the error info types +/// +struct ErrorInfoEntry +{ + uint8_t iv_type; // Value from ErrorInfoType + union + { + ErrorInfoEntryFfdc ffdc; + ErrorInfoEntryHwCallout hw_callout; + ErrorInfoEntryProcCallout proc_callout; + ErrorInfoEntryBusCallout bus_callout; + ErrorInfoEntryTargetCDG target_cdg; + ErrorInfoEntryChildrenCDG children_cdg; + ErrorInfoEntryCollectTrace collect_trace; + }; + + /// + /// @brief Add error information to the FFDC object + /// @param[in] i_info a shared pointer to the error info + /// @param[in] i_object the list of ffdc objects being collected + /// + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const + { + // "unhandled error info type"); + fapi2::Assert(iv_type < EI_LAST_TYPE); + + switch(iv_type) + { + case EI_TYPE_FFDC: + ffdc.addErrorInfo(i_info, i_object); + break; + + case EI_TYPE_HW_CALLOUT: + hw_callout.addErrorInfo(i_info, i_object); + break; + + case EI_TYPE_PROCEDURE_CALLOUT: + proc_callout.addErrorInfo(i_info, i_object); + break; + + case EI_TYPE_BUS_CALLOUT: + bus_callout.addErrorInfo(i_info, i_object); + break; + + case EI_TYPE_CDG: + target_cdg.addErrorInfo(i_info, i_object); + break; + + case EI_TYPE_CHILDREN_CDG: + children_cdg.addErrorInfo(i_info, i_object); + break; + + case EI_TYPE_COLLECT_TRACE: + collect_trace.addErrorInfo(i_info, i_object); + break; + }; + + return; + } +}; +#endif +} +#endif // FAPI2_ERRORINFO_H_ diff --git a/src/hwpf/include/error_info_defs.H b/src/hwpf/include/error_info_defs.H new file mode 100644 index 00000000..0f425b1f --- /dev/null +++ b/src/hwpf/include/error_info_defs.H @@ -0,0 +1,331 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/error_info_defs.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file error_info_defs.H +/// @brief Defines to support the Error Information class +/// + +#ifndef FAPI2_ERRORINFO_DEFS_H_ +#define FAPI2_ERRORINFO_DEFS_H_ + +#include +#include +#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC) +#include +#include +#endif +namespace fapi2 +{ + +/// +/// @brief Type to hold the ffdc data to be returned to caller +/// when error occurs in sbe environment. +/// +/// Note: Typical data sent seems to be register/addresss info +/// rather than use extra space converting stuff just +/// send a uint64 always +/// +struct sbeFfdc_t +{ + uint32_t size; + uint64_t data; +}; + +// Data type for SBE ffdc buffer sent through fifo +typedef struct +{ + uint32_t fapiRc; // Return code from failure + uint32_t ffdcLength; // length of Fapi FFDC data (in bytes) + struct sbeFfdc_t ffdcData[10]; // fapi FFDC data +} SbeFfdcData_t; // 128 bytes + +/// +/// @brief Type to hold the ffdc element in the ffdc class +/// Needed so that the size can be squirled away before the +/// macro is called. +/// +struct ffdc_struct +{ + const void* ptr; + int16_t size; +}; + + +class ffdc_t +{ + public: + ffdc_t(void) + {} + + void operator=(const ffdc_t& i ) + { + iv_value.ptr = i.ptr(); + iv_value.size = i.size(); + } + + operator const void* () const + { + return iv_value.ptr; + } + operator uint8_t() const + { + return *(reinterpret_cast(iv_value.ptr)); + } + + int16_t size(void) const + { + return iv_value.size; + } + int16_t& size(void) + { + return iv_value.size; + } + + const void* ptr(void) const + { + return iv_value.ptr; + } + const void*& ptr(void) + { + return iv_value.ptr; + } + + private: + struct ffdc_struct iv_value; +}; + +/// +/// @brief Enumeration of ErrorInfo FFDC sizes that are used to indicate a +/// special type that cannot simply be memcopied +enum ErrorInfoFfdcSize +{ + EI_FFDC_SIZE_BUF = 0xffff, // fapi2::buffer + EI_FFDC_SIZE_TARGET = 0xfffe, // fapi2::Target + EI_FFDC_SIZE_VBUF = 0xfffd, // fapi2::variable_buffer + EI_FFDC_MAX_SIZE = 0x1000, // Limit regular FFDC capture to 4kb +}; + +/// +/// @brief Enumeration of error log severity. +/// +enum errlSeverity_t +{ + FAPI2_ERRL_SEV_UNDEFINED = 0x00, /// Used internally by ffdc mechanism + FAPI2_ERRL_SEV_RECOVERED = 0x10, /// Not seen by customer + FAPI2_ERRL_SEV_PREDICTIVE = 0x20, /// Error recovered but customer will see + FAPI2_ERRL_SEV_UNRECOVERABLE = 0x40 /// Unrecoverable, general +}; + +/// +/// @brief Enumeration of ErrorInfo types +/// +enum ErrorInfoType +{ + EI_TYPE_FFDC = 0, + EI_TYPE_HW_CALLOUT = 1, + EI_TYPE_PROCEDURE_CALLOUT = 2, + EI_TYPE_BUS_CALLOUT = 3, + EI_TYPE_CDG = 4, // Target Callout/Deconfig/GARD + EI_TYPE_CHILDREN_CDG = 5, // Children Callout/Deconfig/GARD + EI_TYPE_COLLECT_TRACE = 6, + EI_LAST_TYPE = EI_TYPE_COLLECT_TRACE + 1, +}; + +#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC) +/// +/// @enum HwCallout +/// +/// This enumeration defines the possible Hardware Callouts that are not +/// represented by fapi2::Targets +/// +/// Note that platform code may depend on the enum values starting at 0 and +/// incrementing in order to efficiently convert to a platform callout value +/// so do not reorder without consulting all platforms +/// +namespace HwCallouts +{ +enum HwCallout +{ + // Where indicated, a HW Callout in FAPI Error XML must include a + // reference target that is used to identify the HW. e.g. for + // TOD_CLOCK, the proc chip that the clock is attached to must be + // specified + TOD_CLOCK = 0, // Include proc-chip ref (or child chiplet) + MEM_REF_CLOCK = 1, // Include membuf-chip ref (or child chiplet) + PROC_REF_CLOCK = 2, // Include proc-chip ref (or child chiplet) + PCI_REF_CLOCK = 3, // Include proc-chip ref (or child chiplet) + FLASH_CONTROLLER_PART = 4, + PNOR_PART = 5, + SBE_SEEPROM_PART = 6, + VPD_PART = 7, + LPC_SLAVE_PART = 8, + GPIO_EXPANDER_PART = 9, + SPIVID_SLAVE_PART = 10, +}; +} + +/// +/// @enum ProcedureCallout +/// +/// This enumeration defines the possible Procedure Callouts +/// These instruct the customer/customer-engineer what to do +/// +/// Note that platform code may depend on the enum values starting at 0 and +/// incrementing in order to efficiently convert to a platform callout value +/// so do not reorder without consulting all platforms +/// +namespace ProcedureCallouts +{ +enum ProcedureCallout +{ + CODE = 0, // Code problem + LVL_SUPPORT = 1, // Call next level of support + MEMORY_PLUGGING_ERROR = 2, // DIMM Plugging error + BUS_CALLOUT = 3, // Bus Called Out +}; +} + +/// +/// @enum CalloutPriority +/// +/// This enumeration defines the possible Procedure and Target callout priorities +/// +/// Note that platform code may depend on the enum values starting at 0 and +/// incrementing in order to efficiently convert to a platform priority value +/// so do not reorder without consulting all platforms +/// +namespace CalloutPriorities +{ +enum CalloutPriority +{ + LOW = 0, + MEDIUM = 1, + HIGH = 2, +}; +} + +/// +/// @enum CollectTrace +/// +/// This enumeration defines the possible firmware traces to collect +/// +namespace CollectTraces +{ +const uint32_t TRACE_SIZE = 256; // limit collected trace size +enum CollectTrace +{ + FSI = 1, + SCOM = 2, + SCAN = 3, + MBOX = 4, +}; +} + +/// +/// @brief Get FFDC Data from FIFO buffer +/// +/// This is called by hwsv/hb ffdc code when an error is returned in the +/// sbe fifo area. It will translate the data based on type and convert +/// the local data size to the correct length based on the known data size. +/// +/// NOTE - this assumes no buffers are passed - mistake? maybe +inline fapi2::ffdc_t getFfdcData( sbeFfdc_t& i_sbeFfdc ) +{ + fapi2::ffdc_t temp; + + // passed in size is a uint32_t but, needs to be uint16_t + temp.size() = static_cast(i_sbeFfdc.size); + + if(i_sbeFfdc.size == EI_FFDC_SIZE_TARGET ) + { + fapi2::TargetType type = TARGET_TYPE_EX; + uint64_t targetData = i_sbeFfdc.data; + // call hostboot to get the fapi2 target + temp.ptr() = static_cast(getTarget((targetData >> 32), static_cast(targetData & 0xFFFFFFFF))); + } + else + { + // adjust the pointer based on the data size. + temp.ptr() = reinterpret_cast(&i_sbeFfdc.data) + (sizeof(uint64_t) - i_sbeFfdc.size); + } + + return temp; +} +#endif +/// +/// @brief Get FFDC Size +/// +/// This is called by the FAPI_SET_HWP_ERROR macro to find out the size of +/// FFDC data. If the data is of a special type that is handled differently +/// than types that are simply memcopied then it is handled by a template +/// specialization. +/// If this function template is instantiated with a pointer, the compile +/// will fail. +/// +/// @return uint16_t. Size of the FFDC data +/// +template +inline uint16_t getErrorInfoFfdcSize(const T&) +{ + static_assert(sizeof(T) <= EI_FFDC_MAX_SIZE, + "FFDC too large to capture"); + return sizeof(T); +} +#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC) +/// +/// @brief Compile error if caller tries to get the FFDC size of a pointer +/// +template +inline uint16_t getErrorInfoFfdcSize(const T*) +{ + static_assert(std::is_pointer::value, + "pointer passed to getErrorInfoFfdcSize"); + return 0; +} +#endif +/// +/// @brief Get FFDC Size specialization for fapi2::Target +/// +template +inline uint16_t getErrorInfoFfdcSize(const fapi2::Target&) +{ + return EI_FFDC_SIZE_TARGET; +} + +#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC) +/// +/// @brief Get FFDC Size specialization for variable buffers +/// +template<> +inline uint16_t getErrorInfoFfdcSize(const fapi2::variable_buffer& i_thing) +{ + // Limit a variable buffer to 4kb bytes, and we can memcpy the storage. + return std::min(static_cast(EI_FFDC_MAX_SIZE), + i_thing.getLength()); +} +#endif +}; + +#endif // FAPI2_ERRORINFO_DEFS_H_ diff --git a/src/hwpf/include/fapi2.H b/src/hwpf/include/fapi2.H new file mode 100644 index 00000000..136c69e2 --- /dev/null +++ b/src/hwpf/include/fapi2.H @@ -0,0 +1,77 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/fapi2.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file fapi2.H +/// @brief top level header for fapi2 +/// + +#ifndef __FAPI2_TOP_LEVEL__ +#define __FAPI2_TOP_LEVEL__ + +// Define which platforms will not have FAPI Return Codes +#undef __noRC__ +#if defined (__CME__) || defined (__SGPE__) || defined (__PGPE__) +#define __noRC__ +#endif + +// Determine if running on a PPE platform +#ifndef __PPE__ +#if defined (__SBE__) || defined (__CME__) || defined (__SGPE__) || defined (__PGPE__) +#define __PPE__ +#endif +#endif + +#include +#include +#include +#include +#include +#include + +// In turn includes the needed generated headers (hwp_ffd_classes, etc.) +#include +#include // Generated file +#include +#include + +// Not supported by PPE +#ifndef __PPE__ +#include +#endif + +#include + +// Block of headers not currently in fapi2 +#ifdef FAPI2_MISSING_HEADERS + #include +#endif + + +#endif // __FAPI2_TOP_LEVEL__ + + + + + + diff --git a/src/hwpf/include/fapi2AttributeService.H b/src/hwpf/include/fapi2AttributeService.H new file mode 100644 index 00000000..1f8eca5a --- /dev/null +++ b/src/hwpf/include/fapi2AttributeService.H @@ -0,0 +1,150 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/fapi2AttributeService.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file fapi2AttributeService.H +/// +/// @brief Defines the FAPI_ATTR_GET and FAPI_ATTR_SET macros that a user +/// calls to get/set attributes and a check function that the macros use to +/// verify correct usage +/// + +#ifndef FAPI2ATTRIBUTESERVICE_H_ +#define FAPI2ATTRIBUTESERVICE_H_ +#include +//#include +#include +#include +#include +//#include +#include + +/// @brief Macros called by user to get/set attributes for FAPI2 targets +/// +/// Code must have a reference to a FAPI2 Target and an attribute ID (from +/// XML file): +/// fapi2::ReturnCode l_rc; +/// fapi2::Target& l_target = ????; +/// Ex: Target& l_target = ????; +/// +/// To get a copy of an integer attribute and set the attribute +/// uint64_t l_val = 0; +/// l_rc = FAPI_ATTR_GET(, l_target, l_val); +/// l_rc = FAPI_ATTR_SET(, l_target, l_val); +/// +/// To get a copy of an integer array attribute and set the attribute +/// uint32_t l_pVal[4] = {0}; +/// l_rc = FAPI_ATTR_GET(, l_target, l_pVal); +/// l_rc = FAPI_ATTR_SET(, l_target, l_pVal); +/// +/// A priveleged attribute is one that a HWP should not generally access, +/// examples include ATTR_NAME and ATTR_EC, where usage can lead to a non +/// data-driven design. A privileged attribute can be accessed with +/// FAPI_ATTR_GET_PRIVILEGED and FAPI_ATTR_SET_PRIVILEGED +/// +/// The non-PRIVILEGED macros first call a template function (compiler will +/// optimize out) that will cause a compile failure if the attribute is +/// privileged, they then call a PRIVILEGED macro to get/set the attribute +/// +/// The PRIVILEGED macros call a template function (compiler will optimize out) +/// that will cause a compile failure if the ID is not valid or VAL is not the +/// correct type. +// + +#define FAPI_ATTR_GET(ID, TARGET, VAL) \ + (fapi2::failIfPrivileged(), \ + fapi2::checkIdType(ID, VAL), \ + ID##_GETMACRO(ID, TARGET, VAL)) + +#define FAPI_ATTR_SET(ID, TARGET, VAL) \ + (fapi2::failIfPrivileged(), \ + fapi2::checkIdType(ID, VAL), \ + ID##_SETMACRO(ID, TARGET, VAL)) + +#define FAPI_ATTR_GET_PRIVILEGED(ID, TARGET, VAL) \ + (fapi2::checkIdType(ID, VAL), \ + ID##_GETMACRO(ID, TARGET, VAL)) + +#define FAPI_ATTR_SET_PRIVILEGED(ID, TARGET, VAL) \ + (fapi2::checkIdType(ID, VAL), \ + ID##_SETMACRO(ID, TARGET, VAL)) + +namespace fapi2 +{ + +/// +/// @brief Get an InitFile attribute for FAPI2 +/// +/// This function gets a copy of an attribute. In the case of an array attribute, +/// The value in the specified index is retrieved. This should be used by the +/// InitFile HWP only, that HWP processes a binary InitFile and therefore needs +/// to read a variable ID of a variable data type. Standard HWPs should use the +/// FAPI2_ATTR_GET macro which automatically checks the type for correct usage. +/// +/// If there are ever attributes with more than 4 dimensions then this function +/// will need to be updated. +/// +/// @Tparam K template parameter, passed in target. +/// @param[in] i_id AttributeID +/// @param[in] i_target Reference to fapi2::Target (can be NULL for system) +/// @param[out] o_val Reference to uint64_t where attribute value is set +/// @param[in] i_arrayIndex1 If array attribute then index1 +/// @param[in] i_arrayIndex2 If at least 2D array attribute then index2 +/// @param[in] i_arrayIndex3 If at least 3D array attribute then index3 +/// @param[in] i_arrayIndex4 If at least 4D array attribute then index4 +/// +/// @return ReturnCode. Zero if success +/// +template< TargetType K > +ReturnCode getInitFileAttr(const AttributeId i_id, + const Target& i_target, + uint64_t & o_val, + const uint32_t i_arrayIndex1 = 0, + const uint32_t i_arrayIndex2 = 0, + const uint32_t i_arrayIndex3 = 0, + const uint32_t i_arrayIndex4 = 0); + +/** + * @brief Check the ID and TYPE + * + * This is called by FAPI code to check at compile time that a FAPI attribute + * access is using the correct data type and a valid AttributeId + */ +template inline void checkIdType(AttributeId, T &) {} + +/** + * @brief Fail if attribute privileged + * + * This is called by FAPI code to check at compile time that a standard FAPI + * attribute access (FAPI_ATTR_GET) is not accessing a privileged attribute + */ +class ErrorAccessingPrivilegedAttribute; +template void failIfPrivileged() +{ + ErrorAccessingPrivilegedAttribute(); +} +template <> inline void failIfPrivileged() {} + +} + +#endif // FAPI2ATTRIBUTESERVICE_H_ diff --git a/src/hwpf/include/fapi2Structs.H b/src/hwpf/include/fapi2Structs.H new file mode 100644 index 00000000..75584f2b --- /dev/null +++ b/src/hwpf/include/fapi2Structs.H @@ -0,0 +1,132 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/fapi2Structs.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef fapiStructs_h +#define fapiStructs_h +// Copyright ********************************************************** +// +// File fapiStructs.H +// +// IBM Confidential +// OCO Source Materials +// 9400 Licensed Internal Code +// (C) COPYRIGHT IBM CORP. 1996 +// +// The source code for this program is not published or otherwise +// divested of its trade secrets, irrespective of what has been +// deposited with the U.S. Copyright Office. +// +// End Copyright ****************************************************** + +/** + * @file fapiStructs.H + * @brief fapi eCMD Extension Structures + + * Extension Owner : John Farrugia +*/ + +//-------------------------------------------------------------------- +// Includes +//-------------------------------------------------------------------- +#include + + +//-------------------------------------------------------------------- +// Forward References +//-------------------------------------------------------------------- + +#define ECMD_FAPI_CAPI_VERSION "1.0" ///< eCMD FAPI Extension version + + + +#ifndef ECMD_PERLAPI + +namespace fapi +{ + +/** + * @brief Enumeration of fapi file types + */ +typedef enum { + FAPI_FILE_UNKNOWN, ///< Default for not initialized + FAPI_FILE_HWP +} FileType_t; + + +enum AttributeSource +{ + FAPI_ATTRIBUTE_SOURCE_UNKNOWN = 0x00000000, + FAPI_ATTRIBUTE_SOURCE_PLAT = 0x00000001, + FAPI_ATTRIBUTE_SOURCE_HWP = 0x00000002, +}; + + +#define FAPI_ATTRIBUTE_TYPE_STRING 0x80000000 +#define FAPI_ATTRIBUTE_TYPE_UINT8 0x40000000 +#define FAPI_ATTRIBUTE_TYPE_UINT32 0x20000000 +#define FAPI_ATTRIBUTE_TYPE_UINT64 0x10000000 +#define FAPI_ATTRIBUTE_TYPE_UINT8ARY 0x04000000 +#define FAPI_ATTRIBUTE_TYPE_UINT32ARY 0x02000000 +#define FAPI_ATTRIBUTE_TYPE_UINT64ARY 0x01000000 + +#define FAPI_ATTRIBUTE_MODE_CONST 0x80000000 +/** + @brief Used by the get/set configuration functions to return the data +*/ +template +class Attribute +{ +public: + // Constructor + Attribute(); + + // Destructor + ~Attribute(); + + // + /// @brief Assignment Operator. + /// @param[in] i_right Reference to Value to assign from. + /// @return Reference to 'this' Target + /// + Attribute& operator=(const T& i_right) + { + this->value = i_right->value; + } + +private: + T value; + +}; + +inline AttributeData::AttributeData() {} + +inline AttributeData::~AttributeData() {} + +} //namespace +#endif // #ifndef ECMD_PERLAPI +#endif + + + + + diff --git a/src/hwpf/include/fapi2_hw_access.H b/src/hwpf/include/fapi2_hw_access.H new file mode 100644 index 00000000..f4af3515 --- /dev/null +++ b/src/hwpf/include/fapi2_hw_access.H @@ -0,0 +1,464 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/fapi2_hw_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file fapi2_hw_access.H +/// @brief Common file that defines the hardware access functions that +/// platform code must implement. +/// + +#ifndef _FAPI2_COMMON_HWACCESS_H_ +#define _FAPI2_COMMON_HWACCESS_H_ + +#ifdef FAPI_SUPPORT_SPY_AS_ENUM +#include +typedef uint64_t spyId_t; +#endif + +#include +#include + +// thread/variable_buffer isn't supported on PPE +#ifndef __PPE__ +#include +#include +#endif + +#include +#include +#include +#include +#include "imageProcs/p9_ringId.H" + +#ifdef FAPI_SUPPORT_MULTI_SCOM +#include +#endif + +namespace fapi2 +{ + //-------------------------------------------------------------------------- + // PIB Error Functions + //-------------------------------------------------------------------------- + + /// @brief Sets the PIB error mask - platform dependant + /// @param[in] i_mask The new error mask + inline void setPIBErrorMask(uint8_t i_mask); + + /// @brief Gets the PIB error mask - platform dependant + /// @return uint8_t The current PIB error mask + inline uint8_t getPIBErrorMask(void); + + //-------------------------------------------------------------------------- + // Operational Mode Error Functions + //-------------------------------------------------------------------------- + + /// @brief Sets the operational mode + /// @param[in] i_mode The new mode + inline void setOpMode(const OpModes i_mode); + + /// @brief Gets the operational mode + /// @return the operational mode + inline OpModes getOpMode(void); + + //-------------------------------------------------------------------------- + // HW Communication Functions + //-------------------------------------------------------------------------- + + /// @brief Reads a SCOM register from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to read from. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + __attribute__((always_inline)) + inline ReturnCode getScom(const Target& i_target, const uint64_t i_address, + buffer& o_data); + + /// @brief Writes a SCOM register on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + __attribute__((always_inline)) + inline ReturnCode putScom(const Target& i_target, const uint64_t i_address, + const buffer i_data); + + /// @brief Writes a SCOM register under mask on a chip + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @param[in] i_mask Buffer that holds the mask value. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode putScomUnderMask(const Target& i_target, + const uint64_t i_address, + const buffer i_data, + const buffer i_mask); + + /// @brief Reads a CFAM register from a chip. + /// CFAM register is 32-bit wide. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to read from. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode getCfamRegister(const Target& i_target, + const uint32_t i_address, + buffer& o_data); + + /// @brief Writes a CFAM register on a chip. + /// CFAM register is 32-bit wide. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode putCfamRegister(const Target& i_target, + const uint32_t i_address, + const buffer i_data); + + /// @brief Read-modify-write a CFAM register on a chip. + /// CFAM register is 32-bit wide. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to modify. + /// @param[in] i_data Buffer that holds data to be modified. + /// @param[in] i_modifyMode The modify mode (or/and/xor). + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode modifyCfamRegister(const Target& i_target, + const uint32_t i_address, + const buffer i_data, + const ChipOpModifyMode i_modifyMode); + +/// @brief Writes a ring to a chip. +/// @tparam K template parameter, passed in target. +/// @param[in] i_target Target to operate on. +/// @param[in] i_RingID Ring ID to write to. +/// @param[in] i_ringMode Ring operation mode. +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +template< TargetType K, typename V > +inline ReturnCode putRing(const Target& i_target, + const RingID i_ringID, + const RingMode i_ringMode = RING_MODE_HEADER_CHECK); + + // variable_buffer isn't supported on PPE +#ifndef __PPE__ + /// @brief Reads a ring from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_address Ring address to read from. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode getRing(const Target& i_target, + const scanRingId_t i_address, + variable_buffer& o_data, + const RingMode i_ringMode = 0); + + + + /// @brief Read-modify-write a ring on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_address Ring address to modify. + /// @param[in] i_data Buffer that contains RS4 compressed ring data + /// to be modified. + /// @param[in] i_modifyMode The modify mode (or/and/xor) + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode modifyRing(const Target& i_target, + const scanRingId_t i_address, + const variable_buffer& i_data, + const ChipOpModifyMode i_modifyMode, + const RingMode i_ringMode = 0); +#endif + +#ifdef FAPI_SUPPORT_MULTI_SCOM + /// @brief Performs a multiple SCOM operation + /// This interface performs multiple SCOM operations on a chip in the + /// order specified by the input MultiScom object. + /// See fapiMultiScom.H for details of how to populate the MultiScom + /// object with SCOM operations. + /// + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in,out] io_multiScomObj Reference to a MultiScom object, + /// pre-populated with SingleScomInfo entries + /// to perform multiple SCOMs on input target + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note This is a synchronous interface and would return after all the + /// SCOM operations are completed or on the first failed operation + /// + /// @note SCOMs will be performed in the order they were added to the + /// input MultiScom object + /// + /// @note In case of errors, the platform code is responsible to collect + /// and add all the required error info and FFDC into the error data + /// for debugging + /// + /// @note If the SCOM operations added are specific to a processor chip, + /// then the FSI Shift Engine configured in scatter-gather DMA mode + /// extension would be used to execute the SCOM operations in a + /// performance optimize mode. In this mode, the special + /// SCOM_BULK_READ_MODE and SCOM_BULK_WRITE_MODE operations are + /// supported that allow a large bulk of SCOM access (in multiple of + /// 64 bits) for targets that support auto-increment. The + /// SCOM_WRITE_UNDER_MASK operation is not supported in this mode + /// + /// @note If the SCOM operations added are specific to a memory buffer + /// chip, then the regular SCOM engine is used to execute the SCOM + /// operations. SCOM_WRITE_UNDER_MASK operation is supported in + /// this mode, but the special SCOM_BULK_READ_MODE and + /// SCOM_BULK_WRITE_MODE operations are not supported due to + /// hardware limitations. + /// + template< TargetType K, typename V > + fapi2::ReturnCode multiScom (const Target& i_target, + MultiScom& io_multiScomObj); +#endif + + // -------------------------------------------------------------------------- + // NOTE: + // Implement platform Spy access functions if platform supports them. + // -------------------------------------------------------------------------- + + // variable_buffer isn't supported on PPE +#ifndef __PPE__ + /// @brief Reads a spy from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy whose data to be read. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependant on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// 1. if the spy name contains a # procedure writers should replace + /// it with an __P__ for example - + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// becomes + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// 2. if the spy name has a number following a "." it must have an + /// underscore prepended to the number. + /// + /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY + /// becomes + /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY + /// + /// Example SPY name: + /// The hardware procedure should call the function like: + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// fapi2::ReturnCode rc = fapiGetSpy( targ, + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data ); + /// + /// @note The ID is not in quotes the fapi code will handle adding + /// the quotes for the cronus environment +#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN) + +#define FAPI_GET_SPY(TARGET, ID, DATA) fapi2::getSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA) + + template< TargetType K, typename V > + inline ReturnCode getSpy(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& o_data); +#endif + +#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN) + +#define FAPI_GET_SPY(TARGET, ID, DATA) fapi2::getSpy(TARGET, #ID, DATA) + + template< TargetType K, typename V > + inline ReturnCode getSpy(const Target& i_target, + const char * const i_spyId, + variable_buffer& o_data); +#endif + + /// @brief Writes a spy on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy to write data to. + /// @param[out] i_data Buffer that holds data to write into spy. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// 1. if the spy name contains a # procedure writers should replace + /// is with an __P__ for example - + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// becomes + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// 2. if the spy name has a number following a "." it must have an + /// underscore prepended to the number. + /// + /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY + /// becomes + /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY + /// + /// Example SPY name: + /// The hardware procedure should call the function like: + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// fapi2::ReturnCode rc = fapiPutSpy( targ, + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data ); + /// + /// @note The ID is not in quotes the fapi code will handle adding + /// the quotes for the cronus environment + /// +#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN) + +#define FAPI_PUT_SPY(TARGET, ID, DATA) fapi2::putSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA) + + template< TargetType K, typename V > + inline ReturnCode putSpy(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& i_data); +#endif + +#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN) + +#define FAPI_PUT_SPY(TARGET, ID, DATA) fapi2::putSpy(TARGET, #ID, DATA) + + template< TargetType K, typename V > + inline ReturnCode putSpy(const Target& i_target, + const char* const i_spyId, + variable_buffer& i_data); +#endif + + /// @brief Writes spy data into a buffer holding ring data image + /// This API is used by L2/L3 repair to put column repair data + /// into a ring buffer image. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy. + /// @param[in] i_data Buffer that holds spy data to write into ring + /// image. + /// @param[out] o_data Buffer that holds updated ring image. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// See fapiPutSpy for details on spy id specifics. + /// +#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN) + +#define FAPI_PUT_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \ + fapi2::putSpyImage(TARGET, FAPI_SPY_NAMES::ID.value, \ + DATA1, DATA2) + + template< TargetType K, typename V > + inline ReturnCode putSpyImage(const Target& i_target, + const spyId_t i_spyId, + const variable_buffer& i_data, + variable_buffer& o_imageData); +#endif + +#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN) + +#define FAPI_PUT_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \ + fapi2::putSpyImage(TARGET, #ID, DATA1,DATA2) + + template< TargetType K, typename V > + inline ReturnCode putSpyImage(const Target& i_target, + const char* const i_spyId, + const variable_buffer& i_data, + variable_buffer& o_imageData); +#endif + + /// @brief Reads spy data from a ring image buffer + /// @param[in] i_target Target to operate on + /// @param[in] i_spyId The spy's id + /// @param[out] o_data Buffer that holds data read from ring image. + /// @param[in] i_imageData Buffer that holds ring image to read data + /// from. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// See fapiPutSpy for details on spy id specifics. + /// +#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN) + +#define FAPI_GET_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \ + fapi2:getSpyImage(TARGET, FAPI_SPY_NAMES::ID.value, \ + DATA1, DATA2) + + template< TargetType K, typename V > + inline ReturnCode getSpyImage(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& o_data, + const variable_buffer& i_imageData); +#endif + +#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN) + +#define FAPI_GET_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \ + fapi2::getSpyImage(TARGET, #ID, DATA1,DATA2) + + template< TargetType K, typename V > + inline ReturnCode getSpyImage(const Target& i_target, + const char * const i_spyId, + variable_buffer& o_data, + const variable_buffer& i_imageData); +#endif + +#endif // PPE +}; + +#endif // _FAPI2_HWACCESS_H_ diff --git a/src/hwpf/include/fapi2_target.H b/src/hwpf/include/fapi2_target.H new file mode 100644 index 00000000..6c031b7c --- /dev/null +++ b/src/hwpf/include/fapi2_target.H @@ -0,0 +1,588 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/fapi2_target.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file fapi2_target.H +/// @brief Common definitions for fapi2 targets +/// + +#ifndef __FAPI2_COMMON_TARGET__ +#define __FAPI2_COMMON_TARGET__ + +#include +#include +#include +#include +#include + +namespace fapi2 +{ + + + /// + /// @brief Typedef for chiplet number values + /// + typedef uint8_t ChipletNumber_t; + + /// + /// @brief Class representing a FAPI2 Target + /// @tparam K the type (Kind) of target + /// @tparam V the type of the target's Value + /// @remark TargetLite targets are uint64_t, Targets + /// are uintptr_t (void*). + /// + /// Assuming there are representations of a processor, + /// a membuf and a system here are some examples: + /// @code + /// #define PROCESSOR_CHIP_A 0xFFFF0000 + /// #define MEMBUF_CHIP_B 0x0000FFFF + /// #define SYSTEM_C 0x0000AAAA + /// @endcode + /// + /// * To define a target: + /// @code + /// fapi2::Target A(PROCESSOR_CHIP_A); + /// fapi2::Target C(SYSTEM_C); + /// fapi2::Target B(MEMBUF_CHIP_B); + /// @endcode + /// + /// * Functions which take composite target types + /// @code + /// void takesProcOrMembuf( + /// const fapi2::Target& V ); + /// + /// void takesAny(const fapi2::Target& V ); + /// + /// @endcode + /// + /// * Traversing the target "tree" + /// @code + /// fapi2::Target A(PROCESSOR_CHIP_A); + /// + /// // Get A's parent + /// A.getParent(); + /// + /// // Get the 0x53'd core + /// fapi2::getTarget(0x53); + /// + /// // Get all *my* present/functional children which are cores + /// A.getChildren(); + /// + /// // Get all of the the cores relative to my base target + /// fapi2::getChildren(); + /// @endcode + /// + /// * Invalid casts + /// @code + /// // Can't cast to a specialized target + /// fapi2::Target D(MEMBUF_CHIP_B); + /// takesProcOrMembuf( D ); + /// + /// // Not one of the shared types + /// fapi2::Target E; + /// takesProcOrMembuf( E ); + /// @endcode + template + class Target + { + public: + + /// + /// @brief Delagate default constructor to constructor + /// that takes in a value as a param + /// + Target(): Target(V()) + {}; + + /// + /// @brief Create a Target, with a value + /// @param[in] Value the value (i.e., specific element this + /// target represents, or pointer) + /// @note Platforms can mangle the value and K to get a + /// single uint64_t in value which represents all the information + /// they might need. value( K | V ), for example + /// + Target(const V& Value): + iv_handle(Value) + {}; + + /// + /// @brief Assignment Operator. + /// @param[in] i_right Reference to Target to assign from. + /// @return Reference to 'this' Target + /// + Target& operator=(const Target& i_right); + + /// + /// @brief Equality Comparison Operator + /// @param[in] i_right Reference to Target to compare. + /// @return bool. True if equal. + /// @note Platforms need to define this so that the physical + /// targets are determined to be equivilent rather than just the handles + /// + bool operator==(const Target& i_right) const; + + /// + /// @brief Inquality Comparison Operator + /// @param[in] i_right Reference to Target to compare. + /// @return bool. True if not equal. + /// @note Platforms need to define this so that the physical + /// targets are determined to be equivilent rather than just the handles + /// + bool operator!=(const Target& i_right) const; + + /// + /// @brief Get the handle. + /// @return V The target's handle, or value + /// + V get(void) const + { + return iv_handle; + } + + /// + /// @brief Get the handle as a V + /// @return V The target's handle, or value + /// + inline operator V() const + { + return iv_handle; + } + + /// + /// @brief Get a target's value + /// @return V The target's handle, or value + /// + inline V& operator()(void) + { + return iv_handle; + } + + /// + /// @brief Get the target type + /// @return The type of target represented by this target + /// + inline TargetType getType(void) const + { + return iv_type; + } + + /// + /// @brief Get this target's immediate parent + /// @tparam T The type of the parent + /// @return Target a target representing the parent + /// + template< TargetType T> + inline Target getParent(void) const; + + /// + /// @brief Is this target a chip? + /// @return Return true if this target is a chip, false otherwise + /// + inline constexpr bool isChip(void) const + { +// return ( (K == TARGET_TYPE_PROC_CHIP) || +// (K == TARGET_TYPE_MEMBUF_CHIP) ); + + return ( (K == TARGET_TYPE_PROC_CHIP) ); + } + + /// + /// @brief Is this target a chiplet? + /// @return Return true if this target is a chiplet, false otherwise + /// + inline constexpr bool isChiplet(void) const + { + return ( (K == TARGET_TYPE_EX) || +// (K == TARGET_TYPE_MBA) || + (K == TARGET_TYPE_MCS) || +// (K == TARGET_TYPE_XBUS) || +// (K == TARGET_TYPE_ABUS) || +// (K == TARGET_TYPE_L4) || + (K == TARGET_TYPE_CORE) || + (K == TARGET_TYPE_EQ) || +// (K == TARGET_TYPE_MCA) || +// (K == TARGET_TYPE_MCBIST) || +// (K == TARGET_TYPE_MI) || +// (K == TARGET_TYPE_DMI) || +// (K == TARGET_TYPE_OBUS) || +// (K == TARGET_TYPE_NV) || +// (K == TARGET_TYPE_SBE) || +// (K == TARGET_TYPE_PPE) || +// (K == TARGET_TYPE_PERV) || + (K == TARGET_TYPE_PERV) ); +// (K == TARGET_TYPE_PEC) || +// (K == TARGET_TYPE_PHB) ); + } + + /// + /// @brief Get this target's children + /// @tparam T The type of the parent + /// @param[in] i_state The desired TargetState of the children + /// @return std::vector > a vector of present/functional + /// children + /// @warning The children of EX's (cores) are expected to be returned + /// in order. That is, core 0 is std::vector[0]. + /// + template< TargetType T> + std::vector > + getChildren(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const; + + /// + /// @brief Get this target's children, filtered + /// @tparam T The type of the parent + /// @param[in], i_filter The desired chiplet filter + /// @param[in] i_state The desired TargetState of the children + /// @return std::vector > a vector of present/functional + /// children + /// + template< TargetType T> + std::vector> + getChildren(const TargetFilter i_filter, + const TargetState i_state = TARGET_STATE_FUNCTIONAL) const; + + /// + /// @brief Get the target at the other end of a bus - dimm included + /// @tparam T The type of the parent + /// @param[in] i_state The desired TargetState of the children + /// @return Target a target representing the thing on the other end + /// @note Can be easily changed to a vector if needed + /// + template + inline Target + getOtherEnd(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const; + + /// + /// @brief Is the target functional? + /// @return true if target is functional, false if non-functional + /// + + inline bool + isFunctional(void) const; + + /// + /// @brief Copy from a Target to a Target + /// @tparam O the target type of the other + /// + template + inline Target( const Target& Other ): + Target(Other.get()) + { + // In case of recursion depth failure, use -ftemplate-depth= + static_assert( (K & O) != 0, + "unable to cast Target, no shared types"); + + static_assert( bitCount::count >= bitCount::count, + "unable to cast to specialized Target"); + } + +#ifdef __PPE__ + + /// + /// @brief Get the target present setting + /// @return Bool whether present + /// + inline bool getPresent(void) const + { + return (static_cast(this->iv_handle).fields.present ? true : false); + } + + /// + /// @brief Get the target functional setting + /// @return Bool whether functional + /// + inline bool getFunctional(void) const + { + return (static_cast(this->iv_handle).fields.functional ? true : false); + } + + /// + /// @brief Set the target present setting + /// @return Bool whether present + /// + inline void setPresent(void) + { + (static_cast(this->iv_handle)).fields.present = 1; + return; + } + + /// + /// @brief Set the target functional setting + /// @return Bool whether functional + /// + inline void setFunctional(const bool &i_state) + { + (static_cast(this->iv_handle)).fields.functional = (i_state) ? 1 : 0; + return; + } + + + /// Need to optimize PPE Target resoulution in a cheap manner + /// Brian: not sure if the this is the place for this as + /// this is plaform specific. + + /// + /// @brief Get address overlay to reduce runtime processing + /// @return Overlay as a type uint32_t + /// + inline uint32_t getAddressOverlay(void) const + { + return (static_cast(iv_handle).value & 0xFF000000); + } + + /// + /// @brief Get target number + /// @return Overlay as a type V + /// + inline uint32_t getTargetNumber(void) const + { + return static_cast(static_cast(iv_handle).fields.type_target_num); + } + + /// + /// @brief Get target type directly from the handle + /// @return Overlay as a type V + /// + inline TargetType getTargetType(void) const + { + return static_cast(static_cast(iv_handle).fields.type); + } + + /// + /// @brief Get chiplet number from the handle + /// @return ChipletNumber_t Chiplet Number + /// + inline ChipletNumber_t getChipletNumber(void) const + { + return static_cast(static_cast(iv_handle).fields.chiplet_num); + } + +#endif + + + private: + // Don't use enums here as it makes it hard to assign + // in the platform target cast constructor. + static const TargetType iv_type = K; + + V iv_handle; + }; + + // EX threads map to CORE threads: + // t0 / t2 / t4 / t6 fused = t0 / t1 / t2 / t3 normal (c0) + // t1 / t3 / t5 / t7 fused = t0 / t1 / t2 / t3 normal (c1) + // So when splitting the EX, we need to map from EX threads + // to CORE threads. + + /// + /// @brief Given a normal core thread id, translate this to + /// a fused core thread id. (normal to fused) + /// @param[in] the ordinal number of the normal core this thread belongs to + /// @param[in] a normal core thread id - 0, ..., 3 + /// @return the fused core thread id + /// + inline uint8_t thread_id_n2f(const uint8_t i_ordinal, const uint8_t i_thread_id) + { + return (i_thread_id << 1) | i_ordinal; + } + + /// + /// @brief Given a fused core thread id, translate this to + /// a normal core thread id. (fused to normal) + /// @param[in] a fused core thread id - 0, ..., 7 + /// @return the normal core thread id + /// + inline uint8_t thread_id_f2n(const uint8_t i_thread_id) + { + return i_thread_id >> 1; + } + + /// + /// @brief Given a normal core thread id, translate this to a + /// normal core bitset. + /// @param[in] a normal core thread id - 0, ..., 3 + /// @return the normal core bitset + /// @note to got from a fused core id to a normal core bitset, + /// translate from a fused core thread id first. + /// + inline uint8_t thread_id2bitset(const uint8_t i_thread_id) + { + // 0xff means "set all bits" + static const uint8_t all_threads = 0xff; + static const uint8_t all_normal_threads_bitset = 0x0f; + + if (i_thread_id == all_threads) + { + return all_normal_threads_bitset; + } + + // A thread_id is really just bit index. + return (1 << (4 - i_thread_id - 1)); + } + + /// + /// @brief Given a bitset of normal core thread ids, translate this to + /// a bit mask of fused core thread id. (normal to fused) + /// @param[in] the ordinal number of the normal core this thread belongs to + /// @param[in] a normal core thread bitset - b0000, ..., b1111 + /// @return the corresponding fused core bitset + /// + inline uint8_t thread_bitset_n2f(const uint8_t i_ordinal, const uint8_t i_threads) + { + // Since we only have 4 bits I think this is better than a shift-type solution + // for interleaving bits + static uint8_t core_map[] = { + 0b00000000, // b0000 + 0b00000010, // b0001 + 0b00001000, // b0010 + 0b00001010, // b0011 + 0b00100000, // b0100 + 0b00100010, // b0101 + 0b00101000, // b0110 + 0b00101010, // b0111 + 0b10000000, // b1000 + 0b10000010, // b1001 + 0b10001000, // b1010 + 0b10001010, // b1011 + 0b10100000, // b1100 + 0b10100010, // b1101 + 0b10101000, // b1110 + 0b10101010, // b1111 + }; + + return core_map[i_threads] >> i_ordinal; + } + + /// + /// @brief Given a fused core thread bitset, translate this to + /// a normal core thread bitset. (fused to normal) + /// @param[in] the ordinal number of the normal core this thread belongs to + /// @param[in] a fused core thread bitset - b00000000, ..., b11111111 + /// @return the corresponding normal core bitset + /// + inline uint8_t thread_bitset_f2n(const uint8_t i_ordinal, const uint8_t i_threads) + { + uint8_t normal_set = 0; + + // core 0 is the left-most bit in the pair + uint8_t pair_mask = (i_ordinal == 0) ? 0x2 : 0x1; + + // For each bit which can be set in the normal core bit_set ... + for( auto i = 0; i <= 3; ++i ) + { + // ... grab the two fused bits which represent it ... + // ... and mask off the bit in the pair which represents this normal core ... + // (the << 1 shifts the masks over as we walk the pairs of bits) + uint8_t bits = (((3 << (i << 1)) & i_threads) & (pair_mask << (i << 1))); + + // ... if either bit is set, set the corresponding bit in + // the normal core bitset. + normal_set |= (bits != 0) << i; + } + return normal_set; + } + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @param[in] i_target Target + /// @param[in] i_buffer buffer to write in to + /// @param[in] i_bsize size of the buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template< TargetType T, typename V > + inline void toString(const Target& i_target, char* i_buffer, size_t i_bsize); + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @tparam B The type of the buffer + /// @param[in] A pointer to the Target + /// @param[in] i_buffer buffer to write in to + /// @param[in] i_bsize size of the buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template< TargetType T, typename V > + inline void toString(const Target* i_target, char* i_buffer, size_t i_bsize); + + /// + /// @brief Get an enumerated target of a specific type + /// @tparam T The type of the target + /// @param[in] Ordinal representing the ordinal number of + /// the desired target + /// @return Target the target requested + /// + template + inline Target getTarget(uint64_t Ordinal); + + // Why has the been removed? For starters, the API name + // is probably wrong as it's already been confused with + // Target::getChildren(). And if I'm going to change it + // I really want to see if we need it. I'm still not + // clear on whether we're alloing this traversal or not. +#if 0 + /// + /// @brief Get the base target's children + /// @tparam T The type of the target + /// @return std::vector > a vector of present/functional + /// children + /// + template + inline std::vector > getChildren() + { + // For testing + return {Target(), Target()}; + } +#endif + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @tparam B The type of the buffer + /// @param[in] i_target Target + /// @param[in] i_buffer buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template + inline void toString(const Target& i_target, B& i_buffer); + + /// + /// @brief Check if the target is of a type, or in a type subset. + /// @tparam K the TargetType to check + /// @tparam T TargetType or TargetType composite to check against + /// @return True, iff K is a proper T + /// + template< TargetType K, TargetType T > + inline constexpr bool is_same(void) + { return (K & T) != 0; } + + +} +#endif diff --git a/src/hwpf/include/ffdc.H b/src/hwpf/include/ffdc.H new file mode 100644 index 00000000..47a977e7 --- /dev/null +++ b/src/hwpf/include/ffdc.H @@ -0,0 +1,35 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/ffdc.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file ffdc.H + * @brief Defines the FirstFailureData class + */ + +#ifndef FAPI2_FFDC_H_ +#define FAPI2_FFDC_H_ + +namespace fapi2 +{ +} +#endif // FAPI2_FFDC_H_ diff --git a/src/hwpf/include/hw_access.H b/src/hwpf/include/hw_access.H new file mode 100644 index 00000000..53ad6b14 --- /dev/null +++ b/src/hwpf/include/hw_access.H @@ -0,0 +1,603 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/hw_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file hw_access.H + * +* @brief Defines the hardware access functions that platform code must + * implement. + */ + +#ifndef FAPI2_HWACCESS_H_ +#define FAPI2_HWACCESS_H_ + + +// variable_buffer isn't supported on PPE +#ifndef __PPE__ +#include +#endif + +#include +#include +#include +#include "plat_ring_traverse.H" // for findRS4InImageAndApply + +namespace fapi2 +{ + + //-------------------------------------------------------------------------- + // PIB Error Functions + //-------------------------------------------------------------------------- + + /// @brief Sets the PIB error mask - platform dependant + /// @param[in] i_mask The new error mask + void setPIBErrorMask(uint8_t i_mask) + { + PLAT_SET_PIB_ERROR_MASK(i_mask); + } + + /// @brief Gets the PIB error mask - platform dependant + /// @return uint8_t The current PIB error mask + uint8_t getPIBErrorMask(void) + { + PLAT_GET_PIB_ERROR_MASK(o_pib_mask); + return o_pib_mask; + } + + //-------------------------------------------------------------------------- + // Operational Mode Error Functions + //-------------------------------------------------------------------------- + + /// @brief Sets the operational mode + /// @param[in] i_mode The new mode + // note: this can be moved to a C file if desired + inline void setOpMode(const OpModes i_mode) + { + // Keeps the compiler from complaining about the unused i_mode + static_cast(i_mode); + + // No-op for now. Should set thread-local operational mode + return; + } + + /// @brief Gets the operational mode + /// @return the operational mode + // note: this can be moved to a C file if desired + inline OpModes getOpMode(void) + { + // No-op for now. Should read thread-local operational mode + return NORMAL; + } + + //-------------------------------------------------------------------------- + // HW Communication Functions + //-------------------------------------------------------------------------- + + /// @brief Reads a SCOM register from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to read from. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + __attribute__((always_inline)) + inline ReturnCode getScom(const Target& i_target, const uint64_t i_address, + buffer& o_data) + { + fapi2::ReturnCode l_rc; + PLAT_GETSCOM(l_rc, + i_target, + i_address, + &(o_data())); + + return l_rc; + } + + /// @brief Writes a SCOM register on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + __attribute__((always_inline)) + inline ReturnCode putScom(const Target& i_target, const uint64_t i_address, + const buffer i_data) + { + fapi2::ReturnCode l_rc; + PLAT_PUTSCOM(l_rc, + i_target, + i_address, + i_data()); + + return l_rc; + } + + /// @brief Read-modify-write a SCOM register on a chip + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to write to. + /// @param[in] i_data Buffer that holds data to be modified. + /// @param[in] i_modifyMode The modify mode (or/and/xor). + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode modifyScom(const Target& i_target, + const uint64_t i_address, + const buffer i_data, + const ChipOpModifyMode i_modifyMode) + { + fapi2::buffer l_modifyDataBuffer; + + fapi2::ReturnCode l_rc; + PLAT_GETSCOM(l_rc, + i_target, + (uint32_t)(i_address & BITS(40,24)), + &(l_modifyDataBuffer())); + if (l_rc) goto __fapi2exit__; + + if ( i_modifyMode == CHIP_OP_MODIFY_MODE_OR) + { + l_modifyDataBuffer |= i_data; + } + + if ( i_modifyMode == CHIP_OP_MODIFY_MODE_AND) + { + l_modifyDataBuffer &= i_data; + } + + if ( i_modifyMode == CHIP_OP_MODIFY_MODE_XOR) + { + l_modifyDataBuffer ^= i_data; + } + + PLAT_PUTSCOM(l_rc, + i_target, + (uint32_t)(i_address & BITS(40,24)), + l_modifyDataBuffer()); + if (l_rc) goto __fapi2exit__; + + +__fapi2exit__: + return l_rc; + + } + + /// @brief Writes a SCOM register under mask on a chip + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @param[in] i_mask Buffer that holds the mask value. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode putScomUnderMask( const Target& i_target, + const uint64_t i_address, + buffer i_data, + buffer i_mask) + { + fapi2::buffer l_modifyDataBuffer = i_data; + + l_modifyDataBuffer &= i_mask; + + fapi2::ReturnCode l_rc; + PLAT_PUTSCOM(l_rc, + i_target, + (uint32_t)(i_address & BITS(40,24)), + l_modifyDataBuffer()); + + return l_rc; + + } + + + /// @brief Reads a CFAM register from a chip. + /// CFAM register is 32-bit wide. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to read from. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode getCfamRegister(const Target& i_target, + const uint32_t i_address, + buffer& o_data) + { + PLAT_GETCFAM(i_target.get(), + (uint32_t)(i_address & BITS(40,24)), + &(o_data())); + + return FAPI2_RC_SUCCESS; + } + + /// @brief Writes a CFAM register on a chip. + /// CFAM register is 32-bit wide. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode putCfamRegister(const Target& i_target, + const uint32_t i_address, + buffer& i_data) + { + PLAT_PUTCFAM(i_target.get(), + (uint32_t)(i_address & BITS(40,24)), + &(i_data())); + + return FAPI2_RC_SUCCESS; + } + + /// @brief Read-modify-write a CFAM register on a chip. + /// CFAM register is 32-bit wide. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to modify. + /// @param[in] i_data Buffer that holds data to be modified. + /// @param[in] i_modifyMode The modify mode (or/and/xor). + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode modifyCfamRegister(const Target& i_target, + const uint32_t i_address, + const buffer& i_data, + const ChipOpModifyMode i_modifyMode) + { + PLAT_MODCFAM(i_target.get(), + (uint32_t)(i_address & BITS(40,24)), + &(i_data()), + i_modifyMode); + + return FAPI2_RC_SUCCESS; + } + + /// @brief Platform-level implementation of putRing() + /// Hardware procedures writers will not call this function. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_ringID Ring ID that will identify the Ring in the image. + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode putRing(const Target& i_target, + const RingID i_ringID, + const RingMode i_ringMode) + { + ReturnCode l_rc = FAPI2_RC_SUCCESS; + + // Find the RS4 string in the SEEPROM + l_rc = findRS4InImageAndApply(i_target, i_ringID, i_ringMode); + + return l_rc; + } + + // variable_buffer isn't supported on PPE +#ifndef __PPE__ + /// @brief Reads a ring from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_address Ring address to read from. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode getRing(const Target& i_target, + const scanRingId_t i_address, + variable_buffer& o_data, + const RingMode i_ringMode = 0) + { + o_data.setBit(0); + o_data.setBit(3); +#ifndef __PPE__ + std::cout << std::hex << " getRing " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "ring address: " << i_address << "; " + << "ring mode: " << i_ringMode << "; " + << "output data:"; + o_data.print(); +#endif + + return FAPI2_RC_SUCCESS; + } + + /// @brief Read-modify-write a ring on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_address Ring address to modify. + /// @param[in] i_data Buffer that contains RS4 compressed ring data + /// to be modified. + /// @param[in] i_modifyMode The modify mode (or/and/xor) + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K, typename V > + inline ReturnCode modifyRing(const Target& i_target, + const scanRingId_t i_address, + variable_buffer& i_data, + const ChipOpModifyMode i_modifyMode, + const RingMode i_ringMode = 0) + { + + return FAPI2_RC_SUCCESS; + } +#endif + + +#ifdef FAPI_SUPPORT_MULTI_SCOM + /// @brief Performs a multiple SCOM operation + /// This interface performs multiple SCOM operations on a chip in the + /// order specified by the input MultiScom object. + /// See fapiMultiScom.H for details of how to populate the MultiScom + /// object with SCOM operations. + /// + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in,out] io_multiScomObj Reference to a MultiScom object, + /// pre-populated with SingleScomInfo entries + /// to perform multiple SCOMs on input target + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note This is a synchronous interface and would return after all the + /// SCOM operations are completed or on the first failed operation + /// + /// @note SCOMs will be performed in the order they were added to the + /// input MultiScom object + /// + /// @note In case of errors, the platform code is responsible to collect + /// and add all the required error info and FFDC into the error data + /// for debugging + /// + /// @note If the SCOM operations added are specific to a processor chip, + /// then the FSI Shift Engine configured in scatter-gather DMA mode + /// extension would be used to execute the SCOM operations in a + /// performance optimize mode. In this mode, the special + /// SCOM_BULK_READ_MODE and SCOM_BULK_WRITE_MODE operations are + /// supported that allow a large bulk of SCOM access (in multiple of + /// 64 bits) for targets that support auto-increment. The + /// SCOM_WRITE_UNDER_MASK operation is not supported in this mode + /// + /// @note If the SCOM operations added are specific to a memory buffer + /// chip, then the regular SCOM engine is used to execute the SCOM + /// operations. SCOM_WRITE_UNDER_MASK operation is supported in + /// this mode, but the special SCOM_BULK_READ_MODE and + /// SCOM_BULK_WRITE_MODE operations are not supported due to + /// hardware limitations. + /// + template< TargetType K, typename V > + fapi2::ReturnCode multiScom (const Target& i_target, + MultiScom& io_multiScomObj) + { + } +#endif + + // -------------------------------------------------------------------------- + // NOTE: + // Implement platform Spy access functions if platform supports them. + // -------------------------------------------------------------------------- + + // variable_buffer isn't supported on PPE +#ifndef __PPE__ + /// @brief Reads a spy from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy whose data to be read. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependant on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// 1. if the spy name contains a # procedure writers should replace + /// it with an __P__ for example - + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// becomes + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// 2. if the spy name has a number following a "." it must have an + /// underscore prepended to the number. + /// + /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY + /// becomes + /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY + /// + /// Example SPY name: + /// The hardware procedure should call the function like: + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// fapi2::ReturnCode rc = fapiGetSpy( targ, + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data ); + /// + /// @note The ID is not in quotes the fapi code will handle adding + /// the quotes for the cronus environment + /// +#ifdef FAPI_SUPPORT_SPY_AS_ENUM + template< TargetType K, typename V > + inline ReturnCode getSpy(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& o_data) + { + static_assert(K == 0, "implement getSpy (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif +#ifdef FAPI_SUPPORT_SPY_AS_STRING + template< TargetType K, typename V > + inline ReturnCode getSpy(const Target& i_target, + const char * const i_spyId, + variable_buffer& o_data) + { + static_assert(K == 0, "implement getSpy (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif + /// @brief Writes a spy on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy to write data to. + /// @param[out] i_data Buffer that holds data to write into spy. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// 1. if the spy name contains a # procedure writers should replace + /// is with an __P__ for example - + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// becomes + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// 2. if the spy name has a number following a "." it must have an + /// underscore prepended to the number. + /// + /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY + /// becomes + /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY + /// + /// Example SPY name: + /// The hardware procedure should call the function like: + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// fapi2::ReturnCode rc = fapiPutSpy( targ, + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data ); + /// + /// @note The ID is not in quotes the fapi code will handle adding + /// the quotes for the cronus environment + /// +#ifdef FAPI_SUPPORT_SPY_AS_ENUM + template< TargetType K, typename V > + inline ReturnCode putSpy(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& i_data) + { + static_assert(K == 0, "implement putSpy (enum)"); + return ~FAPI2_RC_SUCCESS; + } +#endif +#ifdef FAPI_SUPPORT_SPY_AS_STRING + template< TargetType K, typename V > + inline ReturnCode putSpy(const Target& i_target, + const char* const i_spyId, + variable_buffer& i_data) + { + static_assert(K == 0, "implement putSpy (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif + /// @brief Writes spy data into a buffer holding ring data image + /// This API is used by L2/L3 repair to put column repair data + /// into a ring buffer image. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy. + /// @param[in] i_data Buffer that holds spy data to write into ring + /// image. + /// @param[out] o_data Buffer that holds updated ring image. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// See fapiPutSpy for details on spy id specifics. + /// +#ifdef FAPI_SUPPORT_SPY_AS_ENUM + template< TargetType K, typename V > + inline ReturnCode putSpyImage(const Target& i_target, + const spyId_t i_spyId, + const variable_buffer& i_data, + variable_buffer& o_imageData) + { + static_assert(K == 0, "implement putSpyImage (enum)"); + return ~FAPI2_RC_SUCCESS; + } +#endif +#ifdef FAPI_SUPPORT_SPY_AS_STRING + template< TargetType K, typename V > + inline ReturnCode putSpyImage(const Target& i_target, + const char* const i_spyId, + const variable_buffer& i_data, + variable_buffer& o_imageData) + { + static_assert(K == 0, "implement putSpyImage (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif + /// @brief Reads spy data from a ring image buffer + /// @param[in] i_target Target to operate on + /// @param[in] i_spyId The spy's id + /// @param[out] o_data Buffer that holds data read from ring image. + /// @param[in] i_imageData Buffer that holds ring image to read data + /// from. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// See fapiPutSpy for details on spy id specifics. + /// +#ifdef FAPI_SUPPORT_SPY_AS_ENUM + template< TargetType K, typename V > + inline ReturnCode getSpyImage(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& o_data, + const variable_buffer& i_imageData) + { + static_assert(K == 0, "implement getSpyImage (enum)"); + return ~FAPI2_RC_SUCCESS; + } +#endif +#ifdef FAPI_SUPPORT_SPY_AS_STRING + template< TargetType K, typename V > + inline ReturnCode getSpyImage(const Target& i_target, + const char * const i_spyId, + variable_buffer& o_data, + const variable_buffer& i_imageData) + { + static_assert(K == 0, "implement getSpyImage (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif + +#endif // PPE + +}; + +#endif // _FAPI2_HWACCESS_H_ diff --git a/src/hwpf/include/hwp_ffdc_classes.H b/src/hwpf/include/hwp_ffdc_classes.H new file mode 100644 index 00000000..90a3f9ce --- /dev/null +++ b/src/hwpf/include/hwp_ffdc_classes.H @@ -0,0 +1,23 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/hwp_ffdc_classes.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ diff --git a/src/hwpf/include/plat/hwp_executor.H b/src/hwpf/include/plat/hwp_executor.H new file mode 100644 index 00000000..ae7b5823 --- /dev/null +++ b/src/hwpf/include/plat/hwp_executor.H @@ -0,0 +1,64 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/hwp_executor.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file fapi2PlatHwpExecutor.H + * + * @brief Defines the FAPI HWP Executor Macro. + * + * The HWP Executor macro is called when a PLAT invoker function or a HWP wants + * to execute a HWP. Each platform can modify the macro to do any platform + * specific work to execute the HWP (e.g. dlopening a shared library) + */ + +#ifndef FAPI2PLATHWPEXECUTOR_H_ +#define FAPI2PLATHWPEXECUTOR_H_ + +/** + * @brief HWP Executor macro + * + * By default, this macro just calls the HWP directly. If this cannot be done + * then the platform needs to modify + */ + +#include +#include + + + +// Macro to execute an arbitrary function with an arbitray number of arguments. The +// function is in a shared lib that must be dlopened. All that is required is that +// there is a typedef for the function pointer available that is called _FP_t +// i.e. if the function is called foo, then the typedef is called foo_FP_t +#define FAPI_PLAT_EXEC_HWP(RC, FUNC, _args_...) \ +{\ + RC = FUNC(_args_); \ +} + +#define FAPI_PLAT_EXEC_HWP_LAMBDA(FUNC, _args_...) \ +[&]()->fapi2::ReturnCode \ +{\ + FUNC(_args_); \ +}() + +#endif // FAPI2PLATHWPEXECUTOR_H_ diff --git a/src/hwpf/include/plat/multicast.H b/src/hwpf/include/plat/multicast.H new file mode 100644 index 00000000..46d64be8 --- /dev/null +++ b/src/hwpf/include/plat/multicast.H @@ -0,0 +1,54 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/multicast.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __FAPI2_MULTICAST__ +#define __FAPI2_MULTICAST__ + +#include + +namespace fapi2 +{ + +template +template +inline void Multicast::updateHandle(V& i_value) +{ + // Update handle only if multicast bit is set in handle, else we leave the + // handle unchanged. This enables the same procedure to work with both + // multicast and unicast targets + if(i_value.fields.is_multicast) + { + // Update the handle to reflect the new multicast type and group + i_value.fields.chiplet_num = (0x40) | (O << 3) | N; + } +} + +template +inline bool Multicast::isMulticast() const +{ + return iv_handle.fields.is_multicast; +} + +} + +#endif diff --git a/src/hwpf/include/plat/plat_attributes.H b/src/hwpf/include/plat/plat_attributes.H new file mode 100644 index 00000000..6aec47e3 --- /dev/null +++ b/src/hwpf/include/plat/plat_attributes.H @@ -0,0 +1,36 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_attributes.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_attributes.H + * @brief Platform specific attribute headers + */ + +#ifndef __PLAT_ATTTRIBUTE_H__ +#define __PLAT_ATTTRIBUTE_H__ + +#include +#include // Generated file +//#include + +#endif // __PLAT_ATTTRIBUTE_H__ diff --git a/src/hwpf/include/plat/plat_error_scope.H b/src/hwpf/include/plat/plat_error_scope.H new file mode 100644 index 00000000..505ec6cb --- /dev/null +++ b/src/hwpf/include/plat/plat_error_scope.H @@ -0,0 +1,70 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_error_scope.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_error_scope.H + * @brief platform definitions which create a scope for automatic error handling + */ + +#ifndef __FAPI2_PLAT_ERROR_SCOPE__ +#define __FAPI2_PLAT_ERROR_SCOPE__ + +/// @cond +#define PLAT_FAPI_TRY_NO_TRACE( __operation__ ) \ + if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \ + { \ + goto fapi_try_exit; \ + } + +#define PLAT_FAPI_TRY_TRACE( __operation__, ... ) \ + if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \ + { \ + FAPI_ERR(__VA_ARGS__); \ + goto fapi_try_exit; \ + } + +/// +/// @brief Assert a conditional is true. +/// If it is not, the FFDC gathering function is called and the +/// trace is output as a FAPI error trace. +/// @param[in] __conditional__ the condition to assert +/// @param[in] __ffdc__ the FFDC gathering function +/// @param[in] ... varargs, as input to FAPI_ERR +/// +#define PLAT_FAPI_ASSERT( __conditional__, __ffdc__, ... ) \ + if (! (__conditional__)) \ + { \ + (__ffdc__).execute(); \ + FAPI_ERR(__VA_ARGS__); \ + goto fapi_try_exit; \ + } + + +/// +/// @brief Temporary macro for error label until all are removed. +/// @todo REMOVE this in time. +#define FAPI_CLEANUP() \ +fapi_try_exit: +/// @endcond + +#endif diff --git a/src/hwpf/include/plat/plat_hw_access.H b/src/hwpf/include/plat/plat_hw_access.H new file mode 100644 index 00000000..89c02f2a --- /dev/null +++ b/src/hwpf/include/plat/plat_hw_access.H @@ -0,0 +1,148 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_hw_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_hw_access.H + * + * @brief Define platform specific calls for hardware accesses. + */ + +#ifndef PLATHWACCESS_H_ +#define PLATHWACCESS_H_ + +#include +#include "hw_access_def.H" +#include + + +/// PIB Error Mask + +#define PLAT_SET_PIB_ERROR_MASK(_m_mask) \ + { /* Read MSR */ \ + uint32_t msr_data = mfmsr(); \ + /* Set SEM field */ \ + msr_data &= ~(BITS(0,8)); \ + msr_data |= (uint32_t)(i_mask << 24); \ + /* Write MSR */ \ + mtmsr(msr_data); \ + }; + +#define PLAT_GET_PIB_ERROR_MASK(_m_mask) \ + uint8_t _m_mask; \ + uint32_t _sem = mfmsr(); \ + _m_mask = (uint8_t)((_sem & MSR_SEM) >> (32-(MSR_SEM_START_BIT + MSR_SEM_LEN))); + +// Building block PPE instructions +#define PPE_MFMSR(_m_data) \ +asm volatile \ + ( \ + "mfmsr %[data] \n" \ + : [data]"=&r"(*_m_data) \ + : "[data]"(*_m_data) \ + ); + +#define PPE_MTMSR(_m_data) \ +asm volatile \ + ( \ + "mtmsr %[data] \n" \ + : [data]"=&r"(*_m_data) \ + : "[data]"(*_m_data) \ + ); + +/// GetScom +#define PLAT_GETSCOM(_m_rc, _m_base, _m_offset, _m_data) \ + _m_rc = fapi2::getscom_abs_wrap(getEffectiveAddress(_m_base, _m_offset), _m_data) + +/// PutScom +#define PLAT_PUTSCOM(_m_rc, _m_base, _m_offset, _m_data) \ + _m_rc = fapi2::putscom_abs_wrap(getEffectiveAddress(_m_base, _m_offset), _m_data) + +/// GetCFAM +#define PLAT_GETCFAM(_m_base, _m_offset, _m_data) \ + static_assert( K == TARGET_TYPE_NONE, \ + "getCfamRegister is not supported by PPE platforms") + +/// PutCFAM +#define PLAT_PUTCFAM(_m_base, _m_offset, _m_data) \ + static_assert( K == TARGET_TYPE_NONE, \ + "putCfamRegister is not supported by PPE platforms") + +/// ModifyCFAM +#define PLAT_MODCFAM(_m_base, _m_offset, _m_data, _m_mode) \ + static_assert( K == TARGET_TYPE_NONE, \ + "modifyCfamRegister is not supported by PPE platforms") + +namespace fapi2 +{ + // This function loads the scan region data for the given ring address and + // updates the check word data + // @param[in] : ring addtress + // @param[in]: ring mode + // @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + fapi2::ReturnCode getRing_setup(const uint32_t i_ringAddress, + const fapi2::RingMode i_ringMode); + + // This function read the 64 bit data from the hardware + // @param[in] i_ringAddress - absolute ring address + // @param [out]: 64 bit data + // @param [in] i_bitShiftValue - Bit shift value that needs to rotate + // @note- If the ring length is divisble by 64, then bitshift will always be + // 64, else need to store the ring_length mod 64 and send that value in the + // last iteration. + // @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + fapi2::ReturnCode getRing_granule_data(const uint32_t i_ringAddress, + uint64_t *o_data, + const uint32_t i_bitShiftValue); + + // This function verify the check word data is matching or not and will + // clean up the scan region data + // @param[in] i_ringAddress - absolute ring address + // @param[in] i_ringMode - Ring mode value + // @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + fapi2::ReturnCode getRing_verifyAndcleanup(const uint32_t i_ringAddress, + const fapi2::RingMode i_ringMode); + + /// + /// @brief Platform wrapper over PK getscom_abs + /// + /// @param [in] i_addr The SCOM address + /// @param [out] o_data The data read + /// + /// @return PCB-PIB return code + /// + uint32_t getscom_abs_wrap(const uint32_t i_addr, uint64_t *o_data); + + /// + /// @brief Platform wrapper over PK putscom_abs + /// + /// @param [in] i_addr The SCOM address + /// @param [in] i_data The data read + /// + /// @return PCB-PIB return code + /// + uint32_t putscom_abs_wrap(const uint32_t i_addr, uint64_t i_data); +} + + +#endif // PLATHWACCESS_H_ + diff --git a/src/hwpf/include/plat/plat_includes.H b/src/hwpf/include/plat/plat_includes.H new file mode 100644 index 00000000..62f8a9b0 --- /dev/null +++ b/src/hwpf/include/plat/plat_includes.H @@ -0,0 +1,39 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_includes.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_includes.H + * @brief Platform specific include to implement FAPI2 APIs + */ + +#ifndef __PLAT_INCLUDES_H__ +#define __PLAT_INCLUDES_H__ + +#include + +#include +#include +//#include + + +#endif // __PLAT_INCLUDES_H__ diff --git a/src/hwpf/include/plat/plat_ring_traverse.H b/src/hwpf/include/plat/plat_ring_traverse.H new file mode 100644 index 00000000..5fc470e2 --- /dev/null +++ b/src/hwpf/include/plat/plat_ring_traverse.H @@ -0,0 +1,116 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_ring_traverse.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef _PLAT_RING_TRAVERSE_H_ +#define _PLAT_RING_TRAVERSE_H_ + +#include // for RS4 decompression utilities + +using namespace RING_TYPES; + +/// @brief This structure represents the layout of the Section-TOR +/// Section-TOR has the offsets to the different chiplet's +/// Common Ring section and Instance Ring section +struct SectionTOR +{ + uint32_t TOC_PERV_COMMON_RING; // Offset of Perv Common Ring section + uint32_t TOC_PERV_INSTANCE_RING; // Offset of Perv Instance Ring section + + uint32_t TOC_N0_COMMON_RING; // Offset of N0 Common Ring section + uint32_t TOC_N0_INSTANCE_RING; // Offset of N0 Instance Ring section + + uint32_t TOC_N1_COMMON_RING; // Offset of N1 Common Ring section + uint32_t TOC_N1_INSTANCE_RING; // Offset of N1 Instance Ring section + + uint32_t TOC_N2_COMMON_RING; // Offset of N2 Common Ring section + uint32_t TOC_N2_INSTANCE_RING; // Offset of N2 Instance Ring section + + uint32_t TOC_N3_COMMON_RING; // Offset of N3 Common Ring section + uint32_t TOC_N3_INSTANCE_RING; // Offset of N3 Instance Ring section + + uint32_t TOC_XB_COMMON_RING; // Offset of XB Common Ring section + uint32_t TOC_XB_INSTANCE_RING; // Offset of XB Instance Ring section + + uint32_t TOC_MC_COMMON_RING; // Offset of MC Common Ring section + uint32_t TOC_MC_INSTANCE_RING; // Offset of MC Instance Ring section + + uint32_t TOC_OB0_COMMON_RING; // Offset of OB0 Common Ring section + uint32_t TOC_OB0_INSTANCE_RING; // Offset of OB0 Instance Ring section + + uint32_t TOC_OB1_COMMON_RING; // Offset of OB1 Common Ring section + uint32_t TOC_OB1_INSTANCE_RING; // Offset of OB1 Instance Ring section + + uint32_t TOC_OB2_COMMON_RING; // Offset of OB2 Common Ring section + uint32_t TOC_OB2_INSTANCE_RING; // Offset of OB2 Instance Ring section + + uint32_t TOC_OB3_COMMON_RING; // Offset of OB3 Common Ring section + uint32_t TOC_OB3_INSTANCE_RING; // Offset of OB3 Instance Ring section + + uint32_t TOC_PCI0_COMMON_RING; // Offset of PCI0 Common Ring section + uint32_t TOC_PCI0_INSTANCE_RING; // Offset of PCI0 Instance Ring section + + uint32_t TOC_PCI1_COMMON_RING; // Offset of PCI1 Common Ring section + uint32_t TOC_PCI1_INSTANCE_RING; // Offset of PCI1 Instance Ring section + + uint32_t TOC_PCI2_COMMON_RING; // Offset of PCI2 Common Ring section + uint32_t TOC_PCI2_INSTANCE_RING; // Offset of PCI2 Instance Ring section + + uint32_t TOC_EQ_COMMON_RING; // Offset of Quad Common Ring section + uint32_t TOC_EQ_INSTANCE_RING; // Offset of Quad Instance Ring section + + uint32_t TOC_EC_COMMON_RING; // Offset of Core Common Ring section + uint32_t TOC_EC_INSTANCE_RING; // Offset of Core Instance Ring section +}; + + +/// +/// @brief This is a plat pecific (SBE Plat) function that locates the +/// Ring Container in the image and calls the functin to decompress the +/// RS4 string and apply it to the hardware. +/// @param i_target The target of Ring apply. +/// @param i_ringID The Ring ID that identifies the ring to be applied. +/// @return FAPI2_RC_SUCCESS on success, else error code. +/// +fapi2::ReturnCode findRS4InImageAndApply( + const fapi2::Target& i_target, + const RingID i_ringID, + const fapi2::RingMode i_ringMode); +/// +/// @brief This is a plat pecific (SBE Plat) function that locates the +/// Ring Container in the image and calls the functin to decompress the +/// RS4 string and apply it to the hardware. +/// @param i_target The target of Ring apply. +/// @param i_ringID The Ring ID that identifies the ring to be applied. +/// @param i_sectionTOR TOR section address +/// @param i_applyOverride override is enabled or not +/// @return FAPI2_RC_SUCCESS on success, else error code. +/// +fapi2::ReturnCode getRS4ImageFromTor( + const fapi2::Target& i_target, + const RingID i_ringID, + SectionTOR *i_sectionTOR, + bool i_applyOverride, + const uint32_t i_sectionOffset, + const fapi2::RingMode i_ringMode); +#endif diff --git a/src/hwpf/include/plat/plat_target.H b/src/hwpf/include/plat/plat_target.H new file mode 100644 index 00000000..a4eca5a8 --- /dev/null +++ b/src/hwpf/include/plat/plat_target.H @@ -0,0 +1,215 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_target.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_target.H + * @brief platform definitions for fapi2 targets + */ + +#ifndef __FAPI2_PLAT_TARGET__ +#define __FAPI2_PLAT_TARGET__ + +#include +#include +#include +#include +#include +#include + +static const uint8_t CORES_PER_QUAD = 4; +static const uint8_t EX_PER_QUAD = 2; +static const uint8_t CORES_PER_EX = 2; +static const uint8_t N3_CHIPLET = 5; +static const uint8_t MCS_PER_MCBIST = 2; + +// +// Define what a platform handle looks like. For Hostboot, +// for example, this might be a void*. For the SBE, this +// will be a uint32_t ... +// +namespace fapi2 +{ + typedef enum plat_target_type + { + PPE_TARGET_TYPE_NONE = 0x00, + PPE_TARGET_TYPE_PROC_CHIP = 0x01, + PPE_TARGET_TYPE_MCS = 0x02, + PPE_TARGET_TYPE_CORE = 0x04, + PPE_TARGET_TYPE_EQ = 0x08, + PPE_TARGET_TYPE_EX = 0x10, + PPE_TARGET_TYPE_PERV = 0x20, + PPE_TARGET_TYPE_MCBIST = 0x40, + PPE_TARGET_TYPE_SYSTEM = 0x80, + PPE_TARGET_TYPE_ALL = 0xFFF, + } plat_target_type_t; + + typedef union plat_target_handle { + uint32_t value; + struct { +#ifdef _BIG_ENDIAN + uint32_t chiplet_num : 8; + uint32_t type_target_num : 8; + uint32_t present : 1; + uint32_t functional : 1; + uint32_t is_multicast : 1; + uint32_t valid : 1; + uint32_t type : 12; +#else + uint32_t type : 12; + uint32_t valid : 1; + uint32_t is_multicast : 1; + uint32_t functional : 1; + uint32_t present : 1; + uint32_t type_target_num : 8; + uint32_t chiplet_num : 8; +#endif + } fields; + /// + /// @brief Plat target handle constructor + /// + /// @param i_value Value to instantiate handle with + /// + plat_target_handle(uint32_t i_value = 0):value(i_value) {} + + /// + /// @brief Get the fapi2::TargetType for this target + /// + /// @par Converts the internal PPE type for this target to fapi2 enum + /// + /// @return The fapi2::TargetType for this target + /// + TargetType getFapiTargetType() const; + + /// + /// @brief Get the instance number for this target + /// + /// @return The instance number for this target + /// + inline uint32_t getTargetInstance() const + { + return fields.type_target_num; + } + + /// + /// @brief Get this target's children + /// + /// @param [in] i_parentType fapi2 type of the parent + /// @param [in] i_childType fapi2 type of the child + /// @param [in] i_platType Plat type of the parent + /// @param [in] i_state Required state of the children + /// @param [out] o_children A vector of child target handles + /// + void getChildren(const TargetType i_parentType, + const TargetType i_childType, + const plat_target_type_t i_platType, + const TargetState i_state, + std::vector &o_children) const; + + /// + /// @brief Get proc chip target's children - filtered + /// + /// @param [in] i_filter Target filter + /// @param [in] i_state Required state of the children + /// @param [out] o_children A vector of child target handles + /// + void getChildren(const TargetFilter i_filter, + const TargetState i_state, + std::vector& o_children) const; + + /// + /// @brief Gets the plat target handle as a uint32 + /// + /// @return Plat target handle as a uint32_t + /// + operator uint32_t() const {return value;} + } plat_target_handle_t; + + typedef plat_target_handle_t plat_target_argument_t; + + template + plat_target_handle_t createPlatTargetHandle(const uint32_t i_plat_argument) + { + static_assert((MULTICAST != true) || (K == TARGET_TYPE_PROC_CHIP), + "Only PROC_CHIP types can be multicast"); + plat_target_handle_t l_handle = 0; + + if(MULTICAST == true) + { + // Simply set the is multicast flag + l_handle.fields.is_multicast = 1; + } + else if(K & TARGET_TYPE_PROC_CHIP) + { + l_handle.fields.chiplet_num = 0; + l_handle.fields.type = PPE_TARGET_TYPE_PROC_CHIP; + l_handle.fields.type_target_num = 0; + } + else if(K & TARGET_TYPE_PERV) + { + l_handle.fields.chiplet_num = i_plat_argument + NEST_GROUP1_CHIPLET_OFFSET; + l_handle.fields.type = PPE_TARGET_TYPE_PERV; + l_handle.fields.type_target_num = i_plat_argument; + } + else if(K & TARGET_TYPE_CORE) + { + l_handle.fields.chiplet_num = i_plat_argument + CORE_CHIPLET_OFFSET; + l_handle.fields.type = PPE_TARGET_TYPE_CORE | PPE_TARGET_TYPE_PERV; + l_handle.fields.type_target_num = i_plat_argument; + } + else if(K & TARGET_TYPE_EQ) + { + l_handle.fields.chiplet_num = i_plat_argument + EQ_CHIPLET_OFFSET; + l_handle.fields.type = PPE_TARGET_TYPE_EQ | PPE_TARGET_TYPE_PERV; + l_handle.fields.type_target_num = i_plat_argument; + } + else if(K & TARGET_TYPE_EX) + { + l_handle.fields.chiplet_num = (i_plat_argument / 2) + EX_CHIPLET_OFFSET; + l_handle.fields.type = PPE_TARGET_TYPE_EX; + l_handle.fields.type_target_num = i_plat_argument; + } + else if(K & TARGET_TYPE_MCBIST) + { + l_handle.fields.chiplet_num = i_plat_argument + MCBIST_CHIPLET_OFFSET; + l_handle.fields.type = PPE_TARGET_TYPE_MCBIST | PPE_TARGET_TYPE_PERV; + l_handle.fields.type_target_num = i_plat_argument; + } + else if(K & TARGET_TYPE_MCS) + { + l_handle.fields.chiplet_num = N3_CHIPLET - (MCS_PER_MCBIST * (i_plat_argument / MCS_PER_MCBIST)); + l_handle.fields.type = PPE_TARGET_TYPE_MCS; + l_handle.fields.type_target_num = i_plat_argument; + } + else if(K == TARGET_TYPE_ALL) + { + l_handle.fields.chiplet_num = i_plat_argument; + l_handle.fields.type = PPE_TARGET_TYPE_ALL; + } + + l_handle.fields.valid = 1; + return l_handle; + } + +}; + +#endif diff --git a/src/hwpf/include/plat/plat_target_definitions.H b/src/hwpf/include/plat/plat_target_definitions.H new file mode 100644 index 00000000..daa9d228 --- /dev/null +++ b/src/hwpf/include/plat/plat_target_definitions.H @@ -0,0 +1,111 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_target_definitions.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_ppe_target.H + * @brief Definitions for fapi2 PPE targets + */ + +#ifndef __FAPI2_PPE_TARGET__ +#define __FAPI2_PPE_TARGET__ + +#define TARGET_CHIP(_name, _index) \ + fapi2::Target _name((uint64_t)_index); + +#define TARGET_CHIP_PERV(_name, _index) \ + fapi2::Target _name((uint64_t)_index); + +#define TARGET_EQ(_name, _index) \ + fapi2::Target _name((uint64_t)_index); + +#define TARGET_CORE(_name, _index) \ + fapi2::Target _name((uint64_t)_index); + +#define TARGET_EX(_name, _index) \ + fapi2::Target _name((uint64_t)_index); + +namespace fapi2 +{ + + TARGET_CHIP (chip_target, 0); + TARGET_CHIP_PERV (perv_target, 1); + TARGET_CHIP_PERV (n0_target, 2); + TARGET_CHIP_PERV (n1_target, 3); + TARGET_CHIP_PERV (n2_target, 4); + TARGET_CHIP_PERV (n3_target, 5); + TARGET_CHIP_PERV (xb_target, 6); + TARGET_CHIP_PERV (mc0_target, 7); + TARGET_CHIP_PERV (mc1_target, 8); + TARGET_CHIP_PERV (ob0_target, 9); + TARGET_CHIP_PERV (ob1_target, 10); + TARGET_CHIP_PERV (ob2_target, 11); + TARGET_CHIP_PERV (ob3_target, 12); + TARGET_CHIP_PERV (pci0_target, 13); + TARGET_CHIP_PERV (pci1_target, 14); + TARGET_CHIP_PERV (pci2_target, 15); + TARGET_EQ (eq0_target, 0); + TARGET_EQ (eq1_target, 1); + TARGET_EQ (eq2_target, 2); + TARGET_EQ (eq3_target, 3); + TARGET_EQ (eq4_target, 4); + TARGET_EQ (eq5_target, 5); + TARGET_EX (ex0_target, 0); + TARGET_EX (ex1_target, 1); + TARGET_EX (ex2_target, 2); + TARGET_EX (ex3_target, 3); + TARGET_EX (ex4_target, 4); + TARGET_EX (ex5_target, 5); + TARGET_EX (ex6_target, 6); + TARGET_EX (ex7_target, 7); + TARGET_EX (ex8_target, 8); + TARGET_EX (ex9_target, 9); + TARGET_EX (ex10_target, 10); + TARGET_EX (ex11_target, 11); + TARGET_CORE (core0_target, 0); + TARGET_CORE (core1_target, 1); + TARGET_CORE (core2_target, 2); + TARGET_CORE (core3_target, 3); + TARGET_CORE (core4_target, 4); + TARGET_CORE (core5_target, 5); + TARGET_CORE (core6_target, 6); + TARGET_CORE (core7_target, 7); + TARGET_CORE (core8_target, 8); + TARGET_CORE (core9_target, 9); + TARGET_CORE (core10_target,10); + TARGET_CORE (core11_target,11); + TARGET_CORE (core12_target,12); + TARGET_CORE (core13_target,13); + TARGET_CORE (core14_target,14); + TARGET_CORE (core15_target,15); + TARGET_CORE (core16_target,16); + TARGET_CORE (core17_target,17); + TARGET_CORE (core18_target,18); + TARGET_CORE (core19_target,19); + TARGET_CORE (core20_target,20); + TARGET_CORE (core21_target,21); + TARGET_CORE (core22_target,22); + TARGET_CORE (core23_target,23); + +}; // fapi2 namespace + +#endif // __FAPI2_PPE_TARGET__ diff --git a/src/hwpf/include/plat/plat_target_filter.H b/src/hwpf/include/plat/plat_target_filter.H new file mode 100644 index 00000000..aec258ab --- /dev/null +++ b/src/hwpf/include/plat/plat_target_filter.H @@ -0,0 +1,89 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_target_filter.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __FAPI2_PLAT_TARGET_FILTER__ +#define __FAPI2_PLAT_TARGET_FILTER__ + +#include + +// +// Define TargetFilter enum values for the platform +// +namespace fapi2 +{ +namespace PlatTargetFilter +{ +// These values must contain only 1 bit 'on' so that they can be ORed +// together as composite filters + +constexpr uint64_t PLAT_TARGET_FILTER_TP = 0x8000000000000000; // Pervasive 1 +constexpr uint64_t PLAT_TARGET_FILTER_NEST_NORTH = 0x4000000000000000; // Pervasive 2 +constexpr uint64_t PLAT_TARGET_FILTER_NEST_EAST = 0x2000000000000000; // Pervasive 3 +constexpr uint64_t PLAT_TARGET_FILTER_NEST_SOUTH = 0x1000000000000000; // Pervasive 4 +constexpr uint64_t PLAT_TARGET_FILTER_NEST_WEST = 0x0800000000000000; // Pervasive 5 +constexpr uint64_t PLAT_TARGET_FILTER_XBUS = 0x0400000000000000; // Pervasive 6 +constexpr uint64_t PLAT_TARGET_FILTER_MC_WEST = 0x0200000000000000; // Pervasive 7 +constexpr uint64_t PLAT_TARGET_FILTER_MC_EAST = 0x0100000000000000; // Pervasive 8 +constexpr uint64_t PLAT_TARGET_FILTER_OBUS0 = 0x0080000000000000; // Pervasive 9 +constexpr uint64_t PLAT_TARGET_FILTER_OBUS1 = 0x0040000000000000; // Pervasive 10 +constexpr uint64_t PLAT_TARGET_FILTER_OBUS2 = 0x0020000000000000; // Pervasive 11 +constexpr uint64_t PLAT_TARGET_FILTER_OBUS3 = 0x0010000000000000; // Pervasive 12 +constexpr uint64_t PLAT_TARGET_FILTER_PCI0 = 0x0008000000000000; // Pervasive 13 +constexpr uint64_t PLAT_TARGET_FILTER_PCI1 = 0x0004000000000000; // Pervasive 14 +constexpr uint64_t PLAT_TARGET_FILTER_PCI2 = 0x0002000000000000; // Pervasive 15 +constexpr uint64_t PLAT_TARGET_FILTER_CACHE0 = 0x0001000000000000; // Pervasive 16 +constexpr uint64_t PLAT_TARGET_FILTER_CACHE1 = 0x0000800000000000; // Pervasive 17 +constexpr uint64_t PLAT_TARGET_FILTER_CACHE2 = 0x0000400000000000; // Pervasive 18 +constexpr uint64_t PLAT_TARGET_FILTER_CACHE3 = 0x0000200000000000; // Pervasive 19 +constexpr uint64_t PLAT_TARGET_FILTER_CACHE4 = 0x0000100000000000; // Pervasive 20 +constexpr uint64_t PLAT_TARGET_FILTER_CACHE5 = 0x0000080000000000; // Pervasive 21 +constexpr uint64_t PLAT_TARGET_FILTER_CORE0 = 0x0000040000000000; // Pervasive 32 +constexpr uint64_t PLAT_TARGET_FILTER_CORE1 = 0x0000020000000000; // Pervasive 33 +constexpr uint64_t PLAT_TARGET_FILTER_CORE2 = 0x0000010000000000; // Pervasive 34 +constexpr uint64_t PLAT_TARGET_FILTER_CORE3 = 0x0000008000000000; // Pervasive 35 +constexpr uint64_t PLAT_TARGET_FILTER_CORE4 = 0x0000004000000000; // Pervasive 36 +constexpr uint64_t PLAT_TARGET_FILTER_CORE5 = 0x0000002000000000; // Pervasive 37 +constexpr uint64_t PLAT_TARGET_FILTER_CORE6 = 0x0000001000000000; // Pervasive 38 +constexpr uint64_t PLAT_TARGET_FILTER_CORE7 = 0x0000000800000000; // Pervasive 39 +constexpr uint64_t PLAT_TARGET_FILTER_CORE8 = 0x0000000400000000; // Pervasive 40 +constexpr uint64_t PLAT_TARGET_FILTER_CORE9 = 0x0000000200000000; // Pervasive 41 +constexpr uint64_t PLAT_TARGET_FILTER_CORE10 = 0x0000000100000000; // Pervasive 42 +constexpr uint64_t PLAT_TARGET_FILTER_CORE11 = 0x0000000080000000; // Pervasive 43 +constexpr uint64_t PLAT_TARGET_FILTER_CORE12 = 0x0000000040000000; // Pervasive 44 +constexpr uint64_t PLAT_TARGET_FILTER_CORE13 = 0x0000000020000000; // Pervasive 45 +constexpr uint64_t PLAT_TARGET_FILTER_CORE14 = 0x0000000010000000; // Pervasive 46 +constexpr uint64_t PLAT_TARGET_FILTER_CORE15 = 0x0000000008000000; // Pervasive 47 +constexpr uint64_t PLAT_TARGET_FILTER_CORE16 = 0x0000000004000000; // Pervasive 48 +constexpr uint64_t PLAT_TARGET_FILTER_CORE17 = 0x0000000002000000; // Pervasive 49 +constexpr uint64_t PLAT_TARGET_FILTER_CORE18 = 0x0000000001000000; // Pervasive 50 +constexpr uint64_t PLAT_TARGET_FILTER_CORE19 = 0x0000000000800000; // Pervasive 51 +constexpr uint64_t PLAT_TARGET_FILTER_CORE20 = 0x0000000000400000; // Pervasive 52 +constexpr uint64_t PLAT_TARGET_FILTER_CORE21 = 0x0000000000200000; // Pervasive 53 +constexpr uint64_t PLAT_TARGET_FILTER_CORE22 = 0x0000000000100000; // Pervasive 54 +constexpr uint64_t PLAT_TARGET_FILTER_CORE23 = 0x0000000000080000; // Pervasive 55 + +} // namespace PlatTargetFilter + +} // namespace fapi2 + +#endif diff --git a/src/hwpf/include/plat/plat_target_parms.H b/src/hwpf/include/plat/plat_target_parms.H new file mode 100644 index 00000000..17103a78 --- /dev/null +++ b/src/hwpf/include/plat/plat_target_parms.H @@ -0,0 +1,92 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_target_parms.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_ppe_target.H + * @brief Definitions for fapi2 PPE targets + */ + +#ifndef __FAPI2_PPE_TARGET_PARMS__ +#define __FAPI2_PPE_TARGET_PARMS__ + +#include "fapi_sbe_common.H" + + +CONST_UINT32_T(CHIP_TARGET_OFFSET, 0); +CONST_UINT32_T(CHIP_TARGET_COUNT , 1); + +// Nest targets - Group 1 +CONST_UINT32_T(NEST_GROUP1_TARGET_OFFSET, CHIP_TARGET_OFFSET + CHIP_TARGET_COUNT); +CONST_UINT32_T(NEST_GROUP1_CHIPLET_OFFSET, 0x1); +CONST_UINT32_T(NEST_GROUP1_TARGET_COUNT, 6); + +// MCBIST targets +CONST_UINT32_T(MCBIST_TARGET_OFFSET, NEST_GROUP1_TARGET_OFFSET + NEST_GROUP1_TARGET_COUNT); +CONST_UINT32_T(MCBIST_CHIPLET_OFFSET, 0x7); +CONST_UINT32_T(MCBIST_TARGET_COUNT, 2); + +// Nest targets - Group 2 +CONST_UINT32_T(NEST_GROUP2_TARGET_OFFSET, MCBIST_TARGET_OFFSET + MCBIST_TARGET_COUNT); +CONST_UINT32_T(NEST_GROUP2_TARGET_COUNT, 7); +CONST_UINT32_T(NEST_GROUP2_CHIPLET_OFFSET, 0x9); + +// Cache Targets +CONST_UINT32_T(EQ_TARGET_OFFSET, NEST_GROUP2_TARGET_OFFSET + NEST_GROUP2_TARGET_COUNT); +CONST_UINT32_T(EQ_CHIPLET_OFFSET, 0x10); +CONST_UINT32_T(EQ_TARGET_COUNT, 6); + +// Core Targets +CONST_UINT32_T(CORE_TARGET_OFFSET, EQ_TARGET_OFFSET + EQ_TARGET_COUNT); +CONST_UINT32_T(CORE_CHIPLET_OFFSET, 0x20); +CONST_UINT32_T(CORE_TARGET_COUNT, 24); + +// Ex Targets +CONST_UINT32_T(EX_TARGET_OFFSET, CORE_TARGET_OFFSET + CORE_TARGET_COUNT); +CONST_UINT32_T(EX_CHIPLET_OFFSET, 0x10); +CONST_UINT32_T(EX_TARGET_COUNT, 12); + +// MCS Targets +CONST_UINT32_T(MCS_TARGET_OFFSET, EX_TARGET_OFFSET + EX_TARGET_COUNT); +CONST_UINT32_T(MCS_TARGET_COUNT, 4); + +// System Target +CONST_UINT32_T(SYSTEM_TARGET_OFFSET, MCS_TARGET_OFFSET + MCS_TARGET_COUNT); +CONST_UINT32_T(SYSTEM_TARGET_COUNT, 1); + +CONST_UINT32_T(MCAST_TARGET_OFFSET, SYSTEM_TARGET_OFFSET + SYSTEM_TARGET_COUNT); +CONST_UINT32_T(MCAST_CHIPLET_OFFSET, 4); +CONST_UINT32_T(MCAST_TARGET_COUNT, 3); // PPE only needs multicast groups 4-6 + +// Total number of pervasive targets (Both NEST groups + EQs + COREs +MCBISTs) +CONST_UINT32_T(PERV_TARGET_COUNT, NEST_GROUP1_TARGET_COUNT + NEST_GROUP2_TARGET_COUNT + + MCBIST_TARGET_COUNT + EQ_TARGET_COUNT + CORE_TARGET_COUNT); + +// Total Target Count +CONST_UINT32_T(TARGET_COUNT, CHIP_TARGET_COUNT + + PERV_TARGET_COUNT + + EX_TARGET_COUNT + + MCS_TARGET_COUNT + + SYSTEM_TARGET_COUNT + + MCAST_TARGET_COUNT); + +#endif // __FAPI2_PPE_TARGET_PARMS__ diff --git a/src/hwpf/include/plat/plat_target_utils.H b/src/hwpf/include/plat/plat_target_utils.H new file mode 100644 index 00000000..c6ec5f37 --- /dev/null +++ b/src/hwpf/include/plat/plat_target_utils.H @@ -0,0 +1,86 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_target_utils.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_target_util.H + * @brief platform utility definitions for fapi2 targets + */ + +#ifndef __FAPI2_PLAT_TARGET_UTIL__ +#define __FAPI2_PLAT_TARGET_UTIL__ + +#pragma pack(8) //Start of packing to 8byte boundary + typedef struct { + fapi2attr::SystemAttributes_t G_system_attrs; + fapi2attr::ProcChipAttributes_t G_proc_chip_attrs; + fapi2attr::PervAttributes_t G_perv_attrs; + fapi2attr::CoreAttributes_t G_core_attrs; + fapi2attr::EXAttributes_t G_ex_attrs; + fapi2attr::EQAttributes_t G_eq_attrs; + } G_sbe_attrs_t; +#pragma pack()//End of packing to 8byte boundary + +// +// Platform Utility functions.. +// +namespace fapi2 +{ + /// @brief Function to initialize the G_targets vector based on partial good + /// attributes + ReturnCode plat_TargetsInit(); + + /// @brief Function to apply any gard records set (via + // ATTR_EQ_GARD/ATTR_EC_GARD) to mark corresponding targets non functional + ReturnCode plat_ApplyGards(); + + /// @brief Function to initialize the G_targets vector based on partial good + /// attributes + Target plat_getChipTarget(); + + /// @brief Function to return a platform target handle, given the chiplet + // number and the fapi2 Target type + // @tparam K The fapi2 TargetType + // @param i_chipletNumber The chiplet number of the target + // @return Platform handle + // @note The caller can use the platform handle to construct a Target of + // it's choice. Ex: + // fapi2::Target + // l_core(plat_getTargetHandleByChipletNumber(0x20); + template + plat_target_handle_t plat_getTargetHandleByChipletNumber( + const uint8_t i_chipletNumber); + + /// @brief Function to return a platform target handle, given the target + /// instance number and the fapi2 Target type + // @tparam K The fapi2 TargetType + // @param i_targetNum The instance number for the target + // @return Platform handle + // @note The caller can use the platform handle to construct a Target of + // it's choice. Ex: + // fapi2::Target + // l_ex(plat_getTargetHandleByInstance(0); + template + plat_target_handle_t plat_getTargetHandleByInstance( + const uint8_t i_targetNum); +} +#endif diff --git a/src/hwpf/include/plat/plat_trace.H b/src/hwpf/include/plat/plat_trace.H new file mode 100644 index 00000000..e4a2463f --- /dev/null +++ b/src/hwpf/include/plat/plat_trace.H @@ -0,0 +1,113 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/plat_trace.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_trace.H + * @brief Defines the FAPI2 trace macros. + * + * Note that platform code must provide the implementation. + * + * FAPI has provided a default implementation. Platform code must + * provide an alternate implementation if needed. + */ + +#ifndef FAPI2_PLATTRACE_H_ +#define FAPI2_PLATTRACE_H_ + +#include + +// @todo update these headers with extern "C" in a future commit +// or not and leave this just as it is. +extern "C" +{ +#include "pk.h" +#include +#include "trac_interface.h" +} + +// Why not a #define, why is this in the fapi2 namespace? +// To prevent problems with Cronus and the fapi1 definitions. +namespace fapi2 +{ + static const uint32_t MAX_ECMD_STRING_LEN = 64; +}; + +// Information traces (go into fast trace buffer that can wrap often) +#define FAPI_TRACE(_id_, _fmt_, _args_...) \ + PK_TRACE(_fmt_, ##_args_); + + +/* The following is a desirous trace entry but the second line has a + compilation issue that is unresolved + +#define FAPI_TRACE(_id_, _fmt_, _args_...) \ + PK_TRACE("%s: %s:%d ", _id_, __FUNCTION__, __LINE__); \ + PK_TRACE(_fmt_, ##_args_); +*/ +// FAPI_TRACE_LEVEL controls what traces are included in the code build +// 0 == No tracing +// 1 == ERR traces only +// 2 == ERR and IMP only +// 3 == ERR, IMP and INF only. This is the default in Makefile +// > 4 == All traces (ERR, IMP, INF, DBG, SCAN, MFG) +#if (FAPI_TRACE_LEVEL >= 3) +#define FAPI_INF(_fmt_, _args_...) FAPI_TRACE("inf", _fmt_, ##_args_) +#else +#define FAPI_INF(_fmt_, _args_...) +#endif + +// Important traces (go into slow trace buffer that should not wrap often) +#if (FAPI_TRACE_LEVEL >= 2) +#define FAPI_IMP(_fmt_, _args_...) FAPI_TRACE("imp", _fmt_, ##_args_) +#else +#define FAPI_IMP(_fmt_, _args_...) +#endif + +// Error traces (go into slow trace buffer that should not wrap often) +#if (FAPI_TRACE_LEVEL >= 1) +#define FAPI_ERR(_fmt_, _args_...) FAPI_TRACE("err", _fmt_, ##_args_) +#else +#define FAPI_ERR(_fmt_, _args_...) +#endif + +// Debug traces (go into fast trace buffer that can wrap often) +#if (FAPI_TRACE_LEVEL >= 4) +#define FAPI_DBG(_fmt_, _args_...) FAPI_TRACE("dbg", _fmt_, ##_args_) +#else +#define FAPI_DBG(_fmt_, _args_...) +#endif + +// Scan traces +#if (FAPI_TRACE_LEVEL >= 4) +#define FAPI_SCAN(_fmt_, _args_...) FAPI_TRACE("scan", _fmt_, ##_args_) +#else +#define FAPI_SCAN(_fmt_, _args_...) +#endif + +#if (FAPI_TRACE_LEVEL >= 4) +#define FAPI_MFG(_fmt_, _args_...) FAPI_TRACE("mfg", _fmt_, ##_args_) +#else +#define FAPI_MFG(_fmt_, _args_...) +#endif + +#endif // FAPI2_PLATTRACE_H_ diff --git a/src/hwpf/include/plat/target.H b/src/hwpf/include/plat/target.H new file mode 100644 index 00000000..01250260 --- /dev/null +++ b/src/hwpf/include/plat/target.H @@ -0,0 +1,434 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/plat/target.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file target.H + * @brief platform specializations for fapi2 targets + */ + +#ifndef __FAPI2_TARGET__ +#define __FAPI2_TARGET__ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" +{ + extern std::vector G_vec_targets; +} + +struct ScomAddr +{ + ScomAddr(uint32_t i_addr) : iv_addr(i_addr) + { + } + + operator uint32_t() + { + return iv_addr; + } + + union + { + struct + { + uint32_t iv_unused : 1; + uint32_t iv_multicast : 1; + uint32_t iv_chiplet : 6; + uint32_t iv_pibMaster : 4; + uint32_t iv_port : 4; + uint32_t iv_unused2 : 2; + uint32_t iv_ring : 4; + uint32_t iv_satId : 4; + uint32_t iv_satOffset : 6; + }; + uint32_t iv_addr; + }; +}; + + +namespace fapi2 +{ + + template + constexpr plat_target_type_t fapiTargetTypeToPlatTargetType() + { + return PPE_TARGET_TYPE_NONE; + } + + template<> + constexpr plat_target_type_t fapiTargetTypeToPlatTargetType() + { + return PPE_TARGET_TYPE_PROC_CHIP; + } + + template<> + constexpr plat_target_type_t fapiTargetTypeToPlatTargetType() + { + return PPE_TARGET_TYPE_EQ; + } + + template<> + constexpr plat_target_type_t fapiTargetTypeToPlatTargetType() + { + return PPE_TARGET_TYPE_CORE; + } + + template<> + constexpr plat_target_type_t fapiTargetTypeToPlatTargetType() + { + return PPE_TARGET_TYPE_EX; + } + + template<> + constexpr plat_target_type_t fapiTargetTypeToPlatTargetType() + { + return PPE_TARGET_TYPE_MCS; + } + + template<> + constexpr plat_target_type_t fapiTargetTypeToPlatTargetType() + { + return PPE_TARGET_TYPE_MCBIST; + } + + template<> + constexpr plat_target_type_t fapiTargetTypeToPlatTargetType() + { + return PPE_TARGET_TYPE_PERV; + } + + /// + /// @brief Assignment Operator. + /// @param[in] i_right Reference to Target to assign from. + /// @return Reference to 'this' Target + /// + template + Target& Target::operator=(const Target& i_right) + { + this->iv_handle.value = i_right.iv_handle.value; + return *this; + } + /// + /// @brief Equality Comparison Operator + /// @param[in] i_right Reference to Target to compare. + /// @return bool. True if equal. + /// @note Platforms need to define this so that the physical + /// targets are determined to be equivilent rather than just the handles + /// + template + bool Target::operator==(const Target& i_right) const + { + if (this->iv_handle.value == i_right.iv_handle.value) + return true; + else + return false; + } + + /// + /// @brief Inquality Comparison Operator + /// @param[in] i_right Reference to Target to compare. + /// @return bool. True if not equal. + /// @note Platforms need to define this so that the physical + /// targets are determined to be equivilent rather than just the handles + /// + template + bool Target::operator!=(const Target& i_right) const + { + if (this->iv_handle.value != i_right.iv_handle.value) + return true; + else + return false; + } + + /// + /// @brief Get this target's immediate parent + /// @tparam T The type of the parent + /// @return Target a target representing the parent + /// + template + template + inline Target Target::getParent(void) const + { + static_assert(((K == TARGET_TYPE_EQ) || + (K == TARGET_TYPE_CORE) || + (K == TARGET_TYPE_MCBIST) || + (K == TARGET_TYPE_PERV) || + (K == TARGET_TYPE_EX) || + (K == TARGET_TYPE_PROC_CHIP) || + (K == (TARGET_TYPE_PROC_CHIP | TARGET_TYPE_EQ)) || + (K == (TARGET_TYPE_PROC_CHIP | TARGET_TYPE_CORE))) && + ((T == TARGET_TYPE_EQ) || + (T == TARGET_TYPE_EX) || + (T == TARGET_TYPE_PROC_CHIP) || + (T == TARGET_TYPE_PERV)), + "Invalid parent/child target type passed"); + + static_assert(!((K == TARGET_TYPE_EQ) && + (T != TARGET_TYPE_PERV) && + (T != TARGET_TYPE_PROC_CHIP)), + "Invalid parent for EQ target, must be PERV or " + "PROC_CHIP"); + + static_assert(!((K == TARGET_TYPE_MCBIST) && + (T != TARGET_TYPE_PERV) && + (T != TARGET_TYPE_PROC_CHIP)), + "Invalid parent for MCBIST target, must be PERV or " + "PROC_CHIP"); + + static_assert(!((K == TARGET_TYPE_CORE) && + (T != TARGET_TYPE_PERV) && + (T != TARGET_TYPE_PROC_CHIP) && + (T != TARGET_TYPE_EQ) && + (T != TARGET_TYPE_EX)), + "Invalid parent for CORE target, must be PERV or " + "PROC_CHIP or EQ or EX"); + + static_assert(!((K == TARGET_TYPE_PERV) && + (T != TARGET_TYPE_PERV) && + (T != TARGET_TYPE_PROC_CHIP)), + "Invalid parent for PERV target, must be PERV or " + "PROC_CHIP"); + + static_assert(!((K == TARGET_TYPE_EX) && + (T != TARGET_TYPE_PROC_CHIP) && + (T != TARGET_TYPE_EQ)), + "Invalid parent for EX target, must be PERV or " + "PROC_CHIP or EQ"); + + if(TARGET_TYPE_PERV == T) // EQ/EC/MCBIST/PERV ===> PERV + { + return static_cast(this->iv_handle); + } + if(TARGET_TYPE_PROC_CHIP == T) // EQ/EC/EX/MCBIST/PERV ===> PROC + { + return static_cast(G_vec_targets[CHIP_TARGET_OFFSET]); + } + if((TARGET_TYPE_EQ == T) && (TARGET_TYPE_CORE == K)) // EC ===> EQ + { + return static_cast(G_vec_targets[(getTargetNumber() / CORES_PER_QUAD) + EQ_TARGET_OFFSET]); + } + if((TARGET_TYPE_EQ == T) && (TARGET_TYPE_EX == K)) // EX ===> EQ + { + return static_cast(G_vec_targets[(getTargetNumber() / EX_PER_QUAD) + EQ_TARGET_OFFSET]); + } + if(TARGET_TYPE_EX == T) // EC ===> EX + { + return static_cast(G_vec_targets[(getTargetNumber() / CORES_PER_EX) + EX_TARGET_OFFSET]); + } + } + + /// @brief Get this target's children - handles EQ/EX/EC conversions + /// @tparam K The type of parent + /// @tparam V The plat target handle type + /// @tparam T The type of child + /// @param[in] i_state The desired TargetState of the children + /// @return std::vector > a vector of present/functional + /// children + /// @warning The children are returned in order, ex child[0] is + /// std::vector[0] + template + template + std::vector> + Target::getChildren(const TargetState i_state) const + { + constexpr TargetType L = static_cast(K & ~(TARGET_TYPE_PROC_CHIP)); + constexpr plat_target_type_t P = fapiTargetTypeToPlatTargetType(); + + static_assert(sizeof(Target) == sizeof(plat_target_handle_t), + "Sizes of plat target and FAPI target must match"); + + static_assert(((L == TARGET_TYPE_EQ) || (L == TARGET_TYPE_EX) || (K == TARGET_TYPE_PROC_CHIP)), + "Invalid parent passed to getChildren"); + // valid children for EQ + // EQ -> CORE + // EQ -> EX + static_assert(!((L == fapi2::TARGET_TYPE_EQ) && + (T != fapi2::TARGET_TYPE_CORE) && + (T != fapi2::TARGET_TYPE_EX)), + "improper child of fapi2::TARGET_TYPE_EQ"); + + // valid children for EX + // EX -> CORE + static_assert(!((L == fapi2::TARGET_TYPE_EX) && + (T != fapi2::TARGET_TYPE_CORE)), + "improper child of fapi2::TARGET_TYPE_EX"); + + + std::vector > l_children; + static_cast(get()).getChildren(K, T, P, i_state, reinterpret_cast&>(l_children)); + return l_children; + } + + // Specialization of getChildren, filtered for the chip target + template + template + std::vector > + Target::getChildren(const TargetFilter i_filter, + const TargetState i_state) const + { + static_assert(sizeof(Target) == sizeof(plat_target_handle_t), + "Sizes of plat target and FAPI target must match"); + + static_assert((K == TARGET_TYPE_PROC_CHIP), "Parent target must be the proc chip"); + static_assert((T == TARGET_TYPE_EQ) || (T == TARGET_TYPE_CORE) + || (T == TARGET_TYPE_PERV) || (T == TARGET_TYPE_MCBIST), + "Child target type must be a pervasive chiplet"); + + std::vector > l_children; + + (static_cast(get())).getChildren(i_filter, i_state, reinterpret_cast&>(l_children)); + + return l_children; + } + + /// + /// @brief Get the target at the other end of a bus - dimm included + /// @tparam T The type of the parent + /// @param[in] i_state The desired TargetState of the children + /// @return Target a target representing the thing on the other end + /// @note Can be easily changed to a vector if needed + /// + template + template + inline Target + Target::getOtherEnd(const TargetState i_state) const + { +// static_assert( false, "getOtherEnd() is not supported on PPE platforms"); + } + + /// + /// @brief Is the target functional? + /// @return true if target is functional, false if non-functional + /// + + template + inline bool + Target::isFunctional(void) const + { + return getFunctional(); + } + + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @param[in] i_target Target + /// @param[in] i_buffer buffer to write in to + /// @param[in] i_bsize size of the buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template< TargetType T, typename V > + inline void toString(const Target& i_target, char* i_buffer, size_t i_bsize) + { + snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target.get(), T); + } + + template + __attribute__((always_inline)) + inline uint32_t getEffectiveAddress(const Target &i_target, + const uint32_t i_addr) + { + ScomAddr l_addr = i_addr; + if(0 != i_target.getAddressOverlay()) + { + l_addr.iv_chiplet = i_target.getChipletNumber(); + } + return l_addr; + } + + inline uint32_t getEffectiveAddress(const Target &i_target, + const uint32_t i_addr) + { + ScomAddr l_addr = i_addr; + + if((EQ_CHIPLET_OFFSET <= l_addr.iv_chiplet) && + ((EQ_CHIPLET_OFFSET + EQ_TARGET_COUNT) > l_addr.iv_chiplet)) + { + l_addr.iv_chiplet = i_target.getChipletNumber(); + l_addr.iv_ring = (l_addr.iv_ring - (l_addr.iv_ring % 2)) + + (i_target.getTargetNumber() % 2); + } + else if ((CORE_CHIPLET_OFFSET <= l_addr.iv_chiplet) && + ((CORE_CHIPLET_OFFSET + CORE_TARGET_COUNT) > l_addr.iv_chiplet)) + { + l_addr.iv_chiplet = CORE_CHIPLET_OFFSET + (l_addr.iv_chiplet % 2) + + (i_target.getTargetNumber() * 2); + } + else + { + assert(false); + } + return l_addr; + } + + inline uint32_t getEffectiveAddress(const Target &i_target, + const uint32_t i_addr) + { + ScomAddr l_addr = i_addr; + l_addr.iv_chiplet = i_target.getChipletNumber(); + l_addr.iv_satId = (2 * (i_target.getTargetNumber() % 2)); + return l_addr; + } + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @tparam B The type of the buffer + /// @param[in] A pointer to the Target + /// @param[in] i_buffer buffer to write in to + /// @param[in] i_bsize size of the buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template< TargetType T, typename V > + inline void toString(const Target* i_target, char* i_buffer, size_t i_bsize) + { + snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target->get(), T); + } + + /// + /// @brief Get an enumerated target of a specific type + /// @tparam T The type of the target + /// @param[in] Ordinal representing the ordinal number of + /// the desired target + /// @return Target the target requested + /// + template + inline Target getTarget(uint64_t Ordinal) + { + // For testing + return Target(Ordinal); + } +} + +#endif diff --git a/src/hwpf/include/return_code.H b/src/hwpf/include/return_code.H new file mode 100644 index 00000000..385dd676 --- /dev/null +++ b/src/hwpf/include/return_code.H @@ -0,0 +1,107 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/return_code.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file return_code.H + * @brief definitions for fapi2 return codes + */ + +#ifndef __FAPI2_RETURN_CODE__ +#define __FAPI2_RETURN_CODE__ + +#include +#include + +#ifndef FAPI2_NO_FFDC +#include +#endif + +namespace fapi2 +{ + /// + /// @brief Class representing a FAPI2 ReturnCode + /// + // Remove the inheritance relationship with FirstFailureData if + // the platform doesn't support FFDC. +#if defined(FAPI2_NO_FFDC) || defined (MINIMUM_FFDC) + class ReturnCode +#else + class ReturnCode : public FirstFailureData +#endif + { + public: + + /// + /// @brief Constructor. + /// @param[in] i_rc the rc to set + /// + ReturnCode(const uint32_t i_rc = FAPI2_RC_SUCCESS): + iv_rc(i_rc) + {}; + + /// + /// @brief integral type conversion function. Returns the error code + /// @return The error code + /// + inline operator uint32_t() const { return iv_rc; } + + /// + /// @brief Returns true if iv_rc != SUCCESS + /// @return true or false + /// + inline operator bool() const { return iv_rc != FAPI2_RC_SUCCESS; } + + /// + /// @brief Assignement operator + /// +#ifdef DOXYGEN + inline ReturnCode& operator=(const uint32_t& rhs) + inline ReturnCode& operator=(const ReturnCodes& rhs) +#endif + + inline bool operator==(const uint32_t& rhs) const + { return rhs == iv_rc; } + + inline bool operator==(const ReturnCodes& rhs) const + { return rhs == iv_rc; } + + inline bool operator!=(const uint32_t& rhs) const + { return rhs != iv_rc; } + + inline bool operator!=(const ReturnCodes& rhs) const + { return rhs != iv_rc; } + + private: + uint32_t iv_rc; + }; + + /// This implementation assumes no exception handling and leverages thread-local + /// storage. For platforms without thread support, a global variable will + /// suffice for the error state. +// extern thread_local ReturnCode current_err; /// the current error state + extern ReturnCode current_err; /// the current error state + extern thread_local uint64_t pib_error_mask; /// the pib mask + extern thread_local uint64_t operational_state; /// the operational mode +} +#endif + diff --git a/src/hwpf/include/set_sbe_error.H b/src/hwpf/include/set_sbe_error.H new file mode 100644 index 00000000..ed817cdf --- /dev/null +++ b/src/hwpf/include/set_sbe_error.H @@ -0,0 +1,23 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/set_sbe_error.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ diff --git a/src/hwpf/include/utils.H b/src/hwpf/include/utils.H new file mode 100644 index 00000000..71de13ad --- /dev/null +++ b/src/hwpf/include/utils.H @@ -0,0 +1,122 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/utils.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file utils.H + * + * @brief Defines common utility elements for FAPI2 use. + */ + +#ifndef FAPI2_UTILS_H_ +#define FAPI2_UTILS_H_ + +#include + +#ifdef __ASSEMBLER__ + +#ifndef ULL +#define ULL(x) x +#endif + +#else + +#ifndef ULL +#define ULL(x) x##ull + +#endif + +#endif // __ASSEMBLER + +/// Create a multi-bit mask of \a n bits starting at bit \a b +#ifndef BITS + #define BITS(b, n) ((ULL(0xffffffffffffffff) << (64 - (n))) >> (b)) +#endif + +/// Create a single bit mask at bit \a b +#ifndef BIT + #define BIT(b) BITS((b), 1) +#endif + +#ifdef _BIG_ENDIAN + +#define revle16(x) x +#define revle32(x) x +#define revle64(x) x + +#else + +uint16_t revle16(uint16_t i_x); +uint32_t revle32(uint32_t i_x); +uint64_t revle64(uint64_t i_x); + +#endif + +namespace fapi2 +{ +/// +/// @brief Delay this thread. Hostboot will use the nanoseconds parameter +/// and make a syscall to nanosleep. While in the syscall, the hostboot +/// kernel will continue to consume CPU cycles as it looks for a runnable +/// task. When the delay time expires, the task becomes runnable and will soon +/// return from the syscall. Callers of delay() in the hostboot environment +/// will likely have to know the mHz clock speed they are running on and +/// compute a non-zero value for i_nanoSeconds. +/// +/// On the FSP, it was sometimes acceptable to just provide zero for the +/// sleep delay time, causing the task to yield its time slice. By the +/// time the calling task could run again, it was pretty certain enough +/// host cycles had past. This is probably not acceptable in +/// the hostboot environment. Callers should calculate and provide a +/// sleep value in nanoseconds relative to host clock speed. +/// +/// On FSP when VBU is the target, then the i_simCycles parameter will be +/// used instead. The FSP needs to use the simdispatcher client/server +/// API and issue a command to the awan to advance the simulation the +/// specified number of cycles. +/// +/// On SBE when __FAPI_DELAY_SIM__ is defined, then the i_simCycles parameter +/// will be used instead and will use the number passed. The build parameter +/// __FAPI_DELAY_SIM_CYCLES__ allows the delay to adjust for the number of +/// simulation cycles that the PPE engine is running at. The delay algorithm +/// takes the i_simCycles parameter, subtracts the loop overhead instructions +/// times __FAPI_DELAY_SIM_CYCLES__ and then divides the remainder by the +/// number of loop instructions times __FAPI_DELAY_SIM_CYCLES__. +/// +/// On SBE when __FAPI_DELAY_SIM__ is NOT defined, the nanoseconds parameter +/// will bus used to loop on the a call to pk_timebase32_get() function to +/// determine the elapsed time. pk_sleep() is NOT used as there are not +/// other threads to dispatch. +/// +/// @param[in] i_nanoSeconds nanoseconds to sleep +/// @param[in] i_simCycles count of Awan cycles to advance +/// @param[in] i_fixed Determination, for DFT, if this time is +/// fixed or not. Defaults to non-fixed +/// +/// @return ReturnCode. Zero on success, else platform specified error. +/// +ReturnCode delay(uint64_t i_nanoSeconds, + uint64_t i_simCycles, + bool i_fixed = false); +} + +#endif // FAPI2_UTILS_H_ diff --git a/src/hwpf/include/vector.H b/src/hwpf/include/vector.H new file mode 100644 index 00000000..7dd03d79 --- /dev/null +++ b/src/hwpf/include/vector.H @@ -0,0 +1,850 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/include/vector.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef stl_vector +#define stl_vector + +/** + * @file vector + * @brief simple stl vector template class declaration. + */ + +#include + +#if !defined( __STDC_LIMIT_MACROS) +#define __STDC_LIMIT_MACROS +#endif +#include +//#include +#include +#include + +namespace std +{ + + /** + * @class vector + * subset of stl vector + * @note Does not support allocators, reverse iterators. + */ + template + class vector + { + public: + + typedef T * iterator; + typedef const T * const_iterator; + typedef T & reference; + typedef const T & const_reference; + typedef size_t size_type; + typedef size_t difference_type; + // typedef ptrdiff_t difference_type; + typedef T value_type; + typedef T * pointer; + typedef const T * const_pointer; + + + protected: + + pointer iv_start; + pointer iv_finish; + pointer iv_end_of_storage; + + public: + + /** + * Constructor default + * @post The vector is created with no elements. size() == 0, capacity() == 0 + */ + __attribute__ ((always_inline)) + explicit vector(void) + : + iv_start(NULL), + iv_finish(NULL), + iv_end_of_storage(NULL) + {} + + + /** + * Constructor to create a vector of size n elements of value. + * @param[in] n number of elements to create + * @param[in] value used to create the n elements + * @post The vector is created with n elements of value. + * Storage allocated. size() == n, capacity() == n + */ + explicit vector(size_type n, const T& value = T()) + : + iv_start(NULL), + iv_finish(NULL), + iv_end_of_storage(NULL) + { + reserve(n); + iv_finish = iv_start+n; + ctor_fill(iv_start,iv_finish,value); + } + + + /** + * COPY CTOR create a vector from another vector + * @param[in] x source vector + * @post vector of x.size() is created from x with same # nodes + * size() == capacity() == x.size() + */ + vector(const vector& x) + : + iv_start(NULL), + iv_finish(NULL), + iv_end_of_storage(NULL) + { + reserve(x.size()); + iv_finish = ctor_copy(x.iv_start, x.iv_finish, iv_start); + } + + /** + * CTOR create a vector from a container slice + * @param[in] first iterator first in source sequence + * @param[in] last iterator one past end of source sequence + * @returns None. + * @pre last > first; first,last contained within source vector + * @post vector is created from slice given + */ + template + vector(InputIterator first, InputIterator last) + : + iv_start(NULL), + iv_finish(NULL), + iv_end_of_storage(NULL) + { + // assert(last >= first); + // input iterators only support operator ( ++i, i++,==,!=,*,->,=) + size_type n = 0; + for(InputIterator i = first; i != last; ++i) ++n; + reserve(n); + iv_finish = ctor_copy(first,last,iv_start); + } + + /** + * DTOR + * @post Storage released + */ + __attribute__ ((always_inline)) + ~vector() + { + clear(); // call dtors + free_storage(iv_start); + } + + /** + * Assignment operator. + * @param[in] x A vector. + * @return A vector (for the purpose of multiple assigns). + * @pre None. + * @post *this == x, this->capacity() == x.size(). + * All previously obtained iterators are invalid. + */ + vector& operator=(const vector& x) + { + clear(); + reserve(x.size()); + iv_finish = ctor_copy(x.iv_start, x.iv_finish, iv_start); + return(*this); + } + + // Iterators -------------------- + + /** + * Get iterator to the first vector element + * @return iterator of rist vector element + * @pre None. + * @post None. + */ + __attribute__ ((always_inline)) + iterator begin() + { + return (iv_start); + } + + /** + * Get const_iterator to the first vector element + * @return const_iterator of rist vector element + * @pre None. + * @post None. + */ + __attribute__ ((always_inline)) + const_iterator begin() const + { + return (iv_start); + } + + /** + * Get iterator to the last vector element + 1 + * @return iterator + * @pre None. + * @post None. + */ + __attribute__ ((always_inline)) + iterator end() + { + return (iv_finish); + } + + /** + * Get const_iterator to the last vector element + 1 + * @return const_iterator + * @pre None. + * @post None. + */ + __attribute__ ((always_inline)) + const_iterator end() const + { + return (iv_finish); + } + + /* TODO - Implement only if needed + reverse_iterator rbegin() + { + return(iv_finish -1); + } + + const_reverse_iterator rend() + { + return (iv_start - 1); + } + */ + + // Capacity ----------------------------------------------- + + /** + * Get the number of elements in the container + * @return number of elements in the container + */ + __attribute__ ((always_inline)) + size_type size() const + { + return(iv_finish - iv_start); + } + + /** + * Return the maximum potential size the container could reach. + * @return number of the maximum element count this container could reach + */ + __attribute__ ((always_inline)) + size_type max_size() const + { + return UINT64_MAX/sizeof(T); + } + + /** + * Resize the vector to contain n elements + * @param[in] n new size + * @param[in] x object used to copy to any added elements if size() is increased + * @post All previously obtained iterators are invalid. + * @node if n < size(), vector is truncated. + * if n > size(), vector is padded with copies of x + */ + void resize( size_type n, T x = T()); + + /** + * Get the number of elements the vector can hold before needing to reallocate storage. + * @return element capacity of the vector + * @pre None. + * @post None. + */ + __attribute__ ((always_inline)) + size_type capacity() const + { + return(iv_end_of_storage - iv_start); + } + + /** + * Query for empty container + * @return bool, true if size()==0 else false. + * @pre none + * @post none + */ + __attribute__ ((always_inline)) + bool empty() const + { + return(size() == 0); + } + + /** + * Reserve storage for a given number of elements + * @param[in] n The requested capacity of the vector + * @pre None + * @post If current cpacity() < n then new capcity == n; else no change. + * All previously obtained iterators are invalid + */ + void reserve(size_type n); + + // - Element Access ----------------------------------- + + /** + * Access a mutable reference to an element in the container + * @param An index into the vector + * @return A reference to an element + * @pre 0 <= n < size() + * @post None. + */ + __attribute__ ((always_inline)) + reference operator[](size_type n) + { + return(*(iv_start + n)); + } + + /** + * Access a mutable reference to an element in the container + * @param[in] index An index into the vector + * @return A reference to an element + * @pre 0 <= n < size() + * @post None. + * @note no exception handling + */ + __attribute__ ((always_inline)) + reference at(size_type index) + { + assert(index < size()); + return(*(iv_start + index)); + } + + /** + * Get an immutable reference to an element in the container + * @param[in] index An index into the vector + * @return A const_reference to an object or type T + * @pre 0 <= n < size() + * @post None. + */ + __attribute__ ((always_inline)) + const_reference operator[](size_type index) const + { + assert(index < size()); + return(*(iv_start + index)); + } + + /** + * Get an immutable reference to an element in the container + * @param[in] index An index into the vector + * @return A const_reference to an object or type T + * @pre 0 <= n < size() + * @post None. + * @note no exception handling + */ + __attribute__ ((always_inline)) + const_reference at(size_type index) const + { + assert(index < size()); + return(*(iv_start + index)); + } + + /** + * Get a mutable reference to the first element in the container + * @return reference to first element + * @pre none + * @post None + */ + __attribute__ ((always_inline)) + reference front() + { + return *iv_start; + } + + /** + * Get an Immutable reference to the first element in the container + * @return const_reference to first element + * @pre none + * @post None + */ + __attribute__ ((always_inline)) + const_reference front() const + { + return *iv_start; + } + + /** + * Get a mutable reference to the last element in the container + * @return reference to last element + * @pre none + * @post None + */ + __attribute__ ((always_inline)) + reference back() + { + return *(iv_finish-1); + } + + /** + * Get an Immutable reference to the last element in the container + * @return reference to last element + * @pre none + * @post None + */ + __attribute__ ((always_inline)) + const_reference back() const + { + return *(iv_finish-1); + } + + // -- Modifiers ----------------------------- + + /* + * Assign new content to the vector object + * @param[n] first iterator to first element to copy in + * @param[n] last iterator to last element + 1 to copy in + */ + template + void assign (InputIterator first, InputIterator last) + { + clear(); + size_type n = 0; + for(InputIterator i = first; i != last; ++i) ++n; + reserve(n); + iv_finish = ctor_copy(first,last,iv_start); + } + + + /* + * Assign new content to the vector object + * @param[in] n number of elements to assign + * @param[in] x reference to element to copy in + */ + void assign ( size_type n, const T& x) + { + clear(); + reserve(n); + ctor_fill_n(iv_start,n,x); + iv_finish = iv_start + n; + } + + + /** + * Add element to the back of the container + * @param[in] x reference to object used to create new element + * @pre none + * @post All previously obtained iterators are invalid. + */ + __attribute__ ((always_inline)) + void push_back(const T& x) + { + reserve(size() + 1); + new (iv_finish++) T(x); + } + + /** + * Remove the last element in the container + * @return nothing + * @pre size() > 0 + * @post size() decreased by one + */ + __attribute__ ((always_inline)) + void pop_back() + { + erase(iv_finish-1,iv_finish); + } + + /** + * Insert an element into the container at a given position + * @param[in] position iterator to position to insert + * @param[in] x reference of element to insert + * @pre begin() <= position < end() + * @post Element inserted at position, storage adjusted as needed. + * All previously obtained iterators are invalid. + */ + iterator insert(iterator position, const T& x) + { + // iv_start will change if the vector gets resized - so save the offset for + // return. + difference_type offset = position - iv_start; + insert(position, 1, x); + return (iv_start + offset); + } + + /** + * Insert a number of copies of a given elements at a given position + * @param[in] postion iterator, postion to insert elements + * @param[in] n number of elements to insert + * @param[in] x A reference to the object to uses to create the new elements + * @pre begin() <= postion < end() + * @post All previously obtained iterators are invalid. + */ + void insert (iterator position, size_type n, const T& x); + + /** + * Insert a slice into the current container at a given position + * @param[in] position iterator, position to insert slice + * @param[in] first iterator to first element of slice insert + * @param[in] last iterator to last element + 1 of slice to insert + * @pre begin() <= postion <= end(), first < last. + * @post Elements inserted at postition. Storage adjusted as needed. + * All previously obtained iterators are invalid. + * @note element pointed to by last is not inserted. + */ + template + void insert (iterator position, InputIterator first, + InputIterator last); + + + /** + * Remove an element from the container + * @param[in] position iterator, position of element to remove + * @return new location of the element that followed the last + * element erased, or end() if the operation erased + * the last element in the sequence. + * @pre begin() <= position < end() + * @post All previously obtained iterators are invalid. + */ + __attribute__ ((always_inline)) + iterator erase(iterator position) + { + return erase(position,position+1); + } + + /** + * Remove a slice of elements from the container + * @param[in] first iterator, postion of the first element to remove + * @param[in] last iterator, postion of the last element + 1 to remove + * @return new location of the element that followed the last + * element erased, or end() if the operation erased + * the last element in the sequence. + * @pre begin() <= first,last <= end(), first <= last. + * @post All previously obtained iterators are invalid. + * @note The element pointed to be last is not deleted. + */ + iterator erase(iterator first, iterator last) + { + assert(last >= first); + assert(first >= iv_start); + assert(first <= iv_finish); + assert(last >= iv_start); + assert(last <= iv_finish); + + last = copy(last,iv_finish,first); + while(last != iv_finish) + { + --iv_finish; + iv_finish->~T(); + } + return first; + } + + + /** + * Swap this vector with another + * @param reference to another vector of this type + */ + void swap(vector& x) + { + std::swap(iv_start,x.iv_start); + std::swap(iv_finish,x.iv_finish); + std::swap(iv_end_of_storage,x.iv_end_of_storage); + } + + /** + * Clear the vector + * @pre none. + * @post size() = 0, All previously obtained iterators are invalid + * @note capacity unchanged + */ + void clear () + { + while(iv_finish != iv_start) + { + --iv_finish; + (iv_finish)->~T(); + } + } + + private: + + /** + * Copy constructs elements into raw storage + * @param[in] first iterator of first element to copy + * @pararm[in] last iterator of last element + 1 to copy + * @param[in] destination iterator of destination + * @post elements moved + */ + template + OutputIterator + ctor_copy(InputIterator first, + InputIterator last, + OutputIterator destination) + { + while(first != last) + { + new (destination) T(*first); + ++destination; + ++first; + } + return(destination); + } + + /** + * Copy constructs elements into raw storage + * @param[in] first iterator of first element to copy + * @param[in] last iterator of last element + 1 to copy + * @param[in] destination iterator to end of destination + 1 + * @post elements moved + */ + template + BidirectionalIterator2 + ctor_copy_backward ( BidirectionalIterator1 first, + BidirectionalIterator1 last, + BidirectionalIterator2 destination) + { + while(last != first) + { + --destination; + --last; + new(destination) T(*last); + } + return destination; + } + + /** + * fill by copy construct ino raw storage + * @param[in] first itertor fo first element + * @param[in] last iterator to last element + 1 + * @param[in] value to use to fill + */ + template < class ForwardIterator, class Tp > + void + ctor_fill (ForwardIterator first, ForwardIterator last, const Tp& value ) + { + while (first != last) + { + new (first) T(value); + ++first; + } + } + + /** + * fill by copy construct into raw storage + * @param[in] first iterator first location to fill + * @param[in] n number of elements to fill + * @param[in] value to use to fill + */ + template < class OutputIterator, class Size, class Tp > + void + ctor_fill_n( OutputIterator first, Size n, const Tp& value ) + { + for(; n>0; --n) + { + new (first) T(value); + ++first; + } + } + + + /** + * Free all the storage allocated to this vector + * @param[in] i_start iterator to start of storage block + */ + __attribute__ ((always_inline)) + void free_storage(iterator i_start) + { + delete [] (uint8_t *)i_start; + } + + /** + * Allocate storage for this vector + * @param[in] n, number of elements required + */ + __attribute__ ((always_inline)) + iterator allocate_storage(size_type n) + { + return (iterator) new uint8_t[n * sizeof(T)]; + } + + /** + * debug dump + */ + //void dump(const char * msg = "") + //{ + // puts(msg); + // printf("vector_dump::start 0x%016lx finish 0x%016lx eos 0x%016lx\n", + // (uint64_t)iv_start, (uint64_t)iv_finish, (uint64_t)iv_end_of_storage); + //} + }; + +}; // end namespace std + +// ------------------------------------------------------------------------------------------------ + +template +void std::vector::reserve(size_type n) +{ + size_type c = capacity(); + if(n > c) + { + // if requested new capacity < 10% of current capacity then increase by 10% + size_type dif = n - c; + size_type inc = 1 + (c/size_type(10)); + if(dif < inc) + { + n += inc; + } + + iterator newStart = allocate_storage(n); + if(NULL == iv_start) + { + iv_finish = newStart; + } + else + { + iterator newFinish = ctor_copy(iv_start, iv_finish, newStart); + clear(); + iv_finish = newFinish; + free_storage(iv_start); + } + iv_end_of_storage = newStart + n; + iv_start = newStart; + } +} + + +// ------------------------------------------------------------------------------------------------ + +template +void std::vector::insert (iterator position, size_type n, const T& x) +{ + //assert (position >= iv_start); + //assert (position <= iv_finish); + size_type new_size = size() + n; + if(position == end()) + { + reserve(new_size); + while(n--) new (iv_finish++) T(x); + } + else if(new_size > capacity()) + { + vector new_vec; + new_vec.reserve(new_size); + for(const_iterator i = begin(); i != end(); ++i) + { + if(i == position) + { + while(n--) new_vec.push_back(x); + } + new_vec.push_back(*i); + } + swap(new_vec); // swap this with new_vec + } + else // already have enough space + { + size_type m = iv_finish - position; // # of existing elements to move + pointer new_finish = iv_finish + n; + if(m < n) + { + ctor_copy_backward(position,iv_finish,new_finish); + while(n--) + { + if(position < iv_finish) *position = x; + else new (position) T(x); + ++position; + } + } + else // n <= m + { + ctor_copy_backward(iv_finish-n,iv_finish,new_finish); // raw storage copy + copy_backward(position, iv_finish-n, iv_finish); // operator= copy + fill_n(position,n,x); + } + iv_finish = new_finish; + } +} + +// ------------------------------------------------------------------------------------------------ + +template +template +void std::vector::insert (iterator position, + InputIterator first, + InputIterator last) +// Should only move storage if there is not room +// InputIterators are not random access (eg. can't do diff = last - first) +{ + size_type n = 0; + for(InputIterator i = first; i != last; ++i) ++n; + size_type new_size = size() + n; + + if(position == end()) + { + reserve(new_size); + iv_finish = ctor_copy(first,last,iv_finish); + } + else if(new_size > capacity()) // make a new vector + { + vector new_vec; + new_vec.reserve(new_size); + for(const_iterator i = begin(); i != end(); ++i) + { + if(i == position) + { + while(n--) new_vec.push_back(*first++); + } + new_vec.push_back(*i); + } + swap(new_vec); + } + else // already have enough space + { + size_type m = iv_finish - position; // # of exising elements to adjust + if(m < n) + { + ctor_copy_backward(position,iv_finish,iv_finish+n); // cp all existing elements to raw storage + while(first != last) + { + if(position < iv_finish) *position = *first; // cp new elements to existing element locations + else new (position) T(*first); // cp remaining new elements to raw storage + ++position; + ++first; + } + } + else // n <= m + { + ctor_copy_backward(iv_finish-n, iv_finish, iv_finish+n); // cp existing elements to raw storage + copy_backward(position, iv_finish-n, iv_finish); // cp rest of existing elements to existing locations + copy(first,last,position); // cp in new elements to existing locations + } + iv_finish += n; + } +} + +// ------------------------------------------------------------------------------------------------ + +template +void std::vector::resize(size_type n, T x) +{ + size_type sz = size(); + if(n < sz) + { + erase(iv_start + n,iv_finish); + } + else if(n > sz) + { + insert(iv_finish,n-sz,x); + } + // else n == size() do nothing +} + +#endif +/* vim: set filetype=cpp : */ diff --git a/src/hwpf/src/Makefile b/src/hwpf/src/Makefile new file mode 100644 index 00000000..950c0ccc --- /dev/null +++ b/src/hwpf/src/Makefile @@ -0,0 +1,51 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/hwpf/src/Makefile $ +# +# OpenPOWER sbe Project +# +# Contributors Listed Below - COPYRIGHT 2015,2016 +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG +# This Makefile is designed to be invoked with the -I argument + +export SUB_OBJDIR = /fapi2 + +include img_defs.mk +include fapi2sbefiles.mk + + +OBJS := $(addprefix $(OBJDIR)/, $(FAPI2LIB_OBJECTS)) + +libfapi2.a: fapi2 hwpf plat + $(AR) crs $(OBJDIR)/libfapi2.a $(OBJDIR)/*.o + +.PHONY: clean fapi2 hwpf plat +fapi2: $(OBJS) + +plat: + $(MAKE) -I $(IMAGE_SRCDIR) -C $(PLAT_FAPI2_DIR)/src/plat + +$(OBJS) $(OBJS:.o=.d): | $(OBJDIR) + +$(OBJDIR): + mkdir -p $(OBJDIR) + +ifneq ($(MAKECMDGOALS),clean) +include $(OBJS:.o=.d) +endif + diff --git a/src/hwpf/src/fapi2sbefiles.mk b/src/hwpf/src/fapi2sbefiles.mk new file mode 100644 index 00000000..b9c42fad --- /dev/null +++ b/src/hwpf/src/fapi2sbefiles.mk @@ -0,0 +1,49 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/hwpf/src/fapi2sbefiles.mk $ +# +# OpenPOWER sbe Project +# +# Contributors Listed Below - COPYRIGHT 2015,2016 +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG +# @file fapi2ppefiles.mk +# +# @brief mk for including fapi2 object files +# +# @page ChangeLogs Change Logs +# @section fapi2ppefiles.mk +# @verbatim +# +# +# Change Log ****************************************************************** +# Flag Defect/Feature User Date Description +# ------ -------------- ---------- ------------ ----------- +# +# @endverbatim +# +########################################################################## +# Object Files +########################################################################## + +FAPI2-C-SOURCES += ffdc.C +FAPI2-C-SOURCES += plat_ring_traverse.C +FAPI2-S-SOURCES = + + +FAPI2LIB_OBJECTS += $(FAPI2-C-SOURCES:.C=.o) $(FAPI2-S-SOURCES:.S=.o) + diff --git a/src/hwpf/src/ffdc.C b/src/hwpf/src/ffdc.C new file mode 100644 index 00000000..806082d5 --- /dev/null +++ b/src/hwpf/src/ffdc.C @@ -0,0 +1,41 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/hwpf/src/ffdc.C $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file ffdc.C + * @brief Implements the ffdc for sbe + */ + +#include +#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