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