Created primary API wrappers for the Isolator class
This is an attempt to abstract the internal workings of the isolator
class from the user application.
Change-Id: Ic898b202da6a0ddb368411c11218ca019d1f23fd
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/README.md b/README.md
index 5a37a51..5c75e94 100644
--- a/README.md
+++ b/README.md
@@ -5,15 +5,14 @@
hardware registers on POWER Systems chips.
The primary consumers (and requirements drivers) will be:
- * [OpenBMC Hardware Diagnostics]
- * [POWER Systems Hostboot firmware]
+ * [OpenBMC Hardware Diagnostics][]
+ * [POWER Systems Hostboot firmware][]
* POWER Systems FSP firmware
Core API
--------
-The primary APIs are in the [Isolator class]. See the class definition for
-details on how to use it.
+See the [primary API definitions][] for details on how to use this library.
Integration
-----------
@@ -27,21 +26,21 @@
--------------------------------------
* The method to access hardware register data will vary per user application.
- Therefore, this library will declare the hardware access [user APIs], but
+ Therefore, this library will declare the hardware access [user APIs][], but
each containing user application must implement the APIs for their own
environment.
* This library will not contain data regarding hardware specific information.
Instead, that information will be provided by the user application in the
- form of the [Chip Data Files].
+ form of the [Chip Data Files][].
* Tracing, or logging, methods will vary per user application. Specifically,
FSP and Hostboot firmware utilize specialized macros as a mechanism to save
code image space. Therefore, the user application will need to provide a
specific header file that defines these macros. Details are included in the
- [user APIs].
+ [user APIs][].
* Methods to assert programming bugs will vary per user application. Therefore,
much like tracing, the user application will need to provide a specific
header file that defines macros for assertion. Details are included in the
- [user APIs].
+ [user APIs][].
Environment configuration
-------------------------
@@ -60,11 +59,11 @@
* Hostboot has a very limited environment. It does not include libc or
libstdc++. However, Hostboot has implemented select functions from those
libraries as needed. For details, you can reference `src/include/` in the
- [POWER Systems Hostboot firmware].
+ [POWER Systems Hostboot firmware][].
[OpenBMC Hardware Diagnostics]: https://github.com/openbmc/openpower-hw-diags
[POWER Systems Hostboot firmware]: https://github.com/open-power/hostboot
-[Isolator class]: src/hei_isolator.hpp
+[primary API definitions]: src/hei_main.hpp
[user APIs]: src/hei_user_interface.hpp
[Chip Data Files]: src/chip_data/CHIP_DATA.md
diff --git a/src/hei_includes.hpp b/src/hei_includes.hpp
index dbb8b35..36aa51a 100644
--- a/src/hei_includes.hpp
+++ b/src/hei_includes.hpp
@@ -10,5 +10,5 @@
#include <hei_user_defines.hpp> // For HEI_ASSERT, HEI_INF, and HEI_ERR
// Internal includes
-#include "hei_return_code.hpp"
+#include <hei_return_code.hpp>
diff --git a/src/hei_isolation_data.hpp b/src/hei_isolation_data.hpp
index 57344bd..66de234 100644
--- a/src/hei_isolation_data.hpp
+++ b/src/hei_isolation_data.hpp
@@ -1,6 +1,7 @@
#pragma once
-#include "hei_includes.hpp"
+#include <hei_includes.hpp>
+#include <chip_data/hei_chip_data.hpp>
namespace libhei
{
@@ -14,8 +15,17 @@
{
public:
- /** @brief Default constructor. */
- IsolationData() = default;
+ /**
+ * @brief Default constructor.
+ * @param i_chip See iv_chip.
+ * @param i_chipType See iv_chipType.
+ */
+ IsolationData( void * i_chip, ChipType_t i_chipType ) :
+ iv_chip(i_chip), iv_chipType(i_chipType)
+ {}
+
+ /** @brief Destructor. */
+ ~IsolationData() = default;
/** @brief Copy constructor. */
IsolationData( const IsolationData & ) = default;
@@ -23,11 +33,35 @@
/** @brief Assignment operator. */
IsolationData & operator=( const IsolationData & ) = default;
- /** @brief Destructor. */
- ~IsolationData() = default;
+ /** @return The target chip pointer. */
+ void * getChip() const { return iv_chip; }
+
+ /** @return The target chip type. */
+ ChipType_t getChipType() const { return iv_chipType; }
+
+ /** @brief Flushes the data to ensure a clean slate for next isolation. */
+ void clear() {}
private:
+ /**
+ * This is simply a pointer to a user application object that represents
+ * the target chip. The isolator does not know anything about this object
+ * nor how to use it. This parameter's only purpose is to eventually get
+ * passed back to the user application in a hardware access operation, which
+ * will be defined by the user application.
+ */
+ void * const iv_chip;
+
+ /**
+ * Each Chip Data File contains a unique chip type identifier. The user
+ * application will need to input this value so that the isolator will know
+ * which set of the isolation objects to reference.
+ */
+ const ChipType_t iv_chipType;
+
+ // TODO: add error signature list and register dump.
+
}; // end class IsolationData
} // end namespace libhei
diff --git a/src/hei_isolator.cpp b/src/hei_isolator.cpp
deleted file mode 100644
index 6a81707..0000000
--- a/src/hei_isolator.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-
-#include "hei_isolator.hpp"
-
-namespace libhei
-{
-
-ReturnCode Isolator::initialize( void * i_buffer, size_t i_bufferSize,
- bool i_forceInit )
-{
- ReturnCode rc;
-
- // BEGIN temporary code for compilation
- HEI_INF( "Isolator::initialize(%p,%lu,%d)", i_buffer, i_bufferSize,
- i_forceInit );
- // END temporary code for compilation
-
- return rc;
-}
-
-ReturnCode Isolator::isolate( void * i_chip, ChipType_t i_chipType,
- IsolationData & o_isoData )
-{
- ReturnCode rc;
-
- // BEGIN temporary code for compilation
- o_isoData = IsolationData();
- HEI_INF( "Isolator::isolate(%p,%u)", i_chip, i_chipType );
- // END temporary code for compilation
-
- return rc;
-}
-
-} // end namespace libhei
diff --git a/src/hei_isolator.hpp b/src/hei_isolator.hpp
deleted file mode 100644
index 3a07d75..0000000
--- a/src/hei_isolator.hpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#pragma once
-
-#include "hei_includes.hpp"
-#include "hei_isolation_data.hpp"
-#include "chip_data/hei_chip_data.hpp"
-
-namespace libhei
-{
-
-/**
- * @brief This is the main API for Hardware Error Isolation (aka the isolator).
- *
- * The intended flow is to:
- * - Create a singleton instance of an Isolator object.
- * - Use initialize() to input each necessary Chip Data File (provided by the
- * user application).
- * - Call isolate() each time you want to find all active errors being
- * reported by a chip.
- * - Once isolation is no longer needed, the Isolator singleton can be deleted
- * to free up internal resources.
- *
- * The purpose of the singleton instance is to avoid initializing the object
- * each time isolation is required. The data provided by the Chip Data Files is
- * static. So reinitializing would be a waste of time, unless for some reason
- * the Chip Data Files themselves are updated, which would require
- * reinitialization anyway. Of course, leaving the object in memory chews up
- * resources. So, some users may need to weigh performance vs. memory usage.
- */
-class Isolator
-{
- public:
-
- /** @brief Default constructor. */
- Isolator() = default;
-
- /** @brief Destructor. */
- ~Isolator() = default;
-
- /** @brief Copy constructor. */
- Isolator( const Isolator & ) = delete;
-
- /** @brief Assignment operator. */
- Isolator & operator=( const Isolator & ) = delete;
-
- /**
- * @brief Initializes internal isolation objects based on data from the
- * given Chip Data File.
- *
- * This function only takes one Chip Data File at a time. Therefore, the
- * user application must call this function for each Chip Data File required
- * for isolation.
- *
- * Storage and management of the Chip Data Files will vary per user
- * application. Therefore, the user application is responsible for loading
- * the Chip Data Files into memory, as needed, and providing the location
- * and size of the data.
- *
- * Once initialization has successfully completed with a Chip Data File, the
- * file is no longer needed in memory.
- *
- * Details of the Chip Data File format can be found in CHIP_DATA.md.
- *
- * @param i_buffer A pointer to the buffer containing a single Chip
- * Data File.
- *
- * @param i_bufferSize The size (in bytes) of the target Chip Data File.
- *
- * @param i_forceInit It is possible the user application could call this
- * function for a chip type that has already been
- * initialized. This is useful if for some reason the
- * Chip Data File is for a chip type has been updated.
- * If this function is called and a chip type has
- * already been initialized:
- * - false (default), the function will return
- * RC_CDF_INITIALIZED and exit.
- * - true, the function will delete previous isolation
- * objects for this chip type and reinitialize.
- *
- * @return RC_SUCCESS or RC_CDF_INVALID or RC_CDF_INITIALIZED
- */
- ReturnCode initialize( void * i_buffer, size_t i_bufferSize,
- bool i_forceInit = false );
-
- /**
- * @brief Isolates all active hardware errors found on the given chip.
- *
- * This functions requires initialize() to be called with the Chip Data File
- * corresponding to the given chip type.
- *
- * @param i_chip This is simply a pointer to a user application object
- * that represents the target chip. The isolator does not
- * know anything about this object or how to use it. This
- * parameter's only purpose is to eventually get passed
- * back to the user application in a deviceRead()
- * operation.
- *
- * @param i_chipType Each Chip Data File contains a unique chip type
- * identifier. The user application will need to input
- * this value so the isolator will know which set of the
- * isolation objects to reference.
- *
- * @param o_isoData This return object will contain a list of all active
- * hardware errors on this chip, the contents of any
- * registers associated with the active errors, and any
- * other data that can be useful for debug.
- *
- * @return RC_SUCCESS or RC_CHIP_DATA_MISSING
- */
- ReturnCode isolate( void * i_chip, ChipType_t i_chipType,
- IsolationData & o_isoData );
-
- private:
-
-}; // end class Isolator
-
-} // end namespace libhei
diff --git a/src/hei_main.hpp b/src/hei_main.hpp
new file mode 100644
index 0000000..241b625
--- /dev/null
+++ b/src/hei_main.hpp
@@ -0,0 +1,103 @@
+/**
+ * @file hei_main.hpp
+ *
+ * These are the primary APIs for Hardware Error Isolation (aka the isolator).
+ * The intended flow is to:
+ *
+ * - Call initialize() for each necessary Chip Data File.
+ *
+ * - Call isolate() for each chip that needs error isolation.
+ *
+ * - Once isolation is no longer needed, call uninitialize() to free up
+ * resources used for isolation.
+ *
+ * Note that initialize() allocates many objects used for isolation and keeps
+ * them in memory. Its purpose is to avoid initializing the objects each time
+ * isolation is required. The data provided by the Chip Data Files is static.
+ * So reinitializing would be a waste of time, unless for some reason the Chip
+ * Data Files themselves are updated, which would require reinitialization
+ * anyway. Of course, leaving the object in memory chews up resources. So, some
+ * users may need to weigh performance vs. memory usage.
+ */
+
+#pragma once
+
+#include <hei_includes.hpp>
+#include <hei_isolation_data.hpp>
+#include <isolator/hei_isolator.hpp>
+
+namespace libhei
+{
+
+/**
+ * @brief Initializes all isolation objects based on data from the given Chip
+ * Data File.
+ *
+ * This function only takes one Chip Data File at a time. Therefore, the
+ * user application must call this function for each Chip Data File required
+ * for isolation.
+ *
+ * Storage and management of the Chip Data Files will vary per user application.
+ * Therefore, the user application is responsible for loading the Chip Data
+ * Files into memory as needed, and providing the location and size of the data.
+ *
+ * Once this function returns, the Chip Data File is no longer needed in memory.
+ *
+ * Details of the Chip Data File format can be found in CHIP_DATA.md.
+ *
+ * @param i_buffer A pointer to the buffer containing a single Chip
+ * Data File.
+ *
+ * @param i_bufferSize The size (in bytes) of the target Chip Data File.
+ *
+ * @param i_forceInit It is possible the user application could call this
+ * function for a chip type that has already been
+ * initialized. This is useful if for some reason the Chip
+ * Data File for a specific chip type has been updated. If
+ * this function is called and a chip type has already been
+ * initialized:
+ * - false (default), the function will return
+ * RC_CDF_INITIALIZED and exit.
+ * - true, the function will delete the previous isolation
+ * objects for this chip type and reinitialize.
+ *
+ * @return RC_SUCCESS or RC_CDF_INVALID or RC_CDF_INITIALIZED
+ */
+inline ReturnCode initialize( void * i_buffer, size_t i_bufferSize,
+ bool i_forceInit = false )
+{
+ return Isolator::getSingleton().initialize( i_buffer, i_bufferSize,
+ i_forceInit );
+}
+
+/**
+ * @brief Deletes all internal isolation objects that were created by
+ * initialize().
+ */
+inline void uninitialize()
+{
+ Isolator::getSingleton().uninitialize();
+}
+
+/**
+ * @brief Isolates all active hardware errors found on the given chip.
+ *
+ * This functions requires initialize() to be called with the Chip Data File
+ * corresponding to the given chip type.
+ *
+ * @param o_isoData This parameter will contain a reference to the target chip
+ * and its chip type. The rest of the data in the object will
+ * be flushed and then repopulated with a list of all active
+ * hardware errors on this chip, the contents of any
+ * registers associated with the active errors, and any
+ * other data that can be useful for debug.
+ *
+ * @return RC_SUCCESS or RC_CHIP_DATA_MISSING
+ */
+inline ReturnCode isolate( IsolationData & o_isoData )
+{
+ return Isolator::getSingleton().isolate( o_isoData );
+}
+
+} // end namespace libhei
+
diff --git a/src/isolator/hei_isolator.cpp b/src/isolator/hei_isolator.cpp
new file mode 100644
index 0000000..64cfe3e
--- /dev/null
+++ b/src/isolator/hei_isolator.cpp
@@ -0,0 +1,42 @@
+
+#include <isolator/hei_isolator.hpp>
+
+namespace libhei
+{
+
+ReturnCode Isolator::initialize( void * i_buffer, size_t i_bufferSize,
+ bool i_forceInit )
+{
+ ReturnCode rc;
+
+ // BEGIN temporary code
+ HEI_INF( "Isolator::initialize(%p,%lu,%d)", i_buffer, i_bufferSize,
+ i_forceInit );
+ // END temporary code
+
+ return rc;
+}
+
+void Isolator::uninitialize()
+{
+ // BEGIN temporary code
+ HEI_INF( "Isolator::uninitialize()" );
+ // END temporary code
+}
+
+ReturnCode Isolator::isolate( IsolationData & o_isoData ) const
+{
+ ReturnCode rc;
+
+ // Flush the isolation data to ensure a clean slate.
+ o_isoData.clear();
+
+ // BEGIN temporary code
+ HEI_INF( "Isolator::isolate(%p,%u)", o_isoData.getChip(),
+ o_isoData.getChipType() );
+ // END temporary code
+
+ return rc;
+}
+
+} // end namespace libhei
diff --git a/src/isolator/hei_isolator.hpp b/src/isolator/hei_isolator.hpp
new file mode 100644
index 0000000..4687b4f
--- /dev/null
+++ b/src/isolator/hei_isolator.hpp
@@ -0,0 +1,78 @@
+#pragma once
+
+#include <hei_includes.hpp>
+#include <hei_isolation_data.hpp>
+#include <chip_data/hei_chip_data.hpp>
+
+namespace libhei
+{
+
+/**
+ * @brief This class is a complement to the main APIs. Its purpose is to store
+ * and maintain all of the objects necessary for isolation.
+ *
+ * The intended flow is to:
+ * - Create a singleton instance of an Isolator object via getSingleton().
+ * - Use initialize() to input each necessary Chip Data File provided by the
+ * user application.
+ * - Call isolate() each time you want to find all active errors being
+ * reported by a chip.
+ * - Once isolation is no longer needed, use uninitialize() to free up
+ * internal resources.
+ *
+ * The purpose of the singleton instance is to avoid initializing the object
+ * each time isolation is required. The data provided by the Chip Data Files is
+ * static. So reinitializing would be a waste of time, unless for some reason
+ * the Chip Data Files themselves are updated, which would require
+ * reinitialization anyway. Of course, leaving the object in memory chews up
+ * resources. So, some users may need to weigh performance vs. memory usage.
+ */
+class Isolator
+{
+ private: // This class cannot be instantiated. Use getSingleton() instead.
+
+ /** @brief Default constructor. */
+ Isolator() = default;
+
+ /** @brief Destructor. */
+ ~Isolator()
+ {
+ // Clear out all of the internal isolation objects.
+ uninitialize();
+ }
+
+ /** @brief Copy constructor. */
+ Isolator( const Isolator & ) = delete;
+
+ /** @brief Assignment operator. */
+ Isolator & operator=( const Isolator & ) = delete;
+
+ public:
+
+ /** @brief Provides access to a singleton instance of this object. */
+ static Isolator & getSingleton()
+ {
+ static Isolator theIsolator;
+ return theIsolator;
+ }
+
+ /** @brief See API wrapper description in hei_main.hpp. */
+ ReturnCode initialize( void * i_buffer, size_t i_bufferSize,
+ bool i_forceInit = false );
+
+ /**
+ * @brief See API wrapper description in hei_main.hpp.
+ *
+ * This function is called in the destructor. Therefore, it should never
+ * throw an exception.
+ */
+ void uninitialize();
+
+ /** @brief See API wrapper description in hei_main.hpp. */
+ ReturnCode isolate( IsolationData & o_isoData ) const;
+
+ private:
+
+}; // end class Isolator
+
+} // end namespace libhei
diff --git a/test/simulator/hei_sim_main.cpp b/test/simulator/hei_sim_main.cpp
index e83a577..b3291aa 100644
--- a/test/simulator/hei_sim_main.cpp
+++ b/test/simulator/hei_sim_main.cpp
@@ -1,19 +1,19 @@
-#include "hei_isolator.hpp"
+#include <hei_main.hpp>
int main()
{
- libhei::Isolator iso;
-
void * buffer = nullptr;
size_t sz_buffer = 0;
- iso.initialize( buffer, sz_buffer );
+ libhei::initialize( buffer, sz_buffer );
void * chip = nullptr;
libhei::ChipType_t chipType = 0;
- libhei::IsolationData isoData;
+ libhei::IsolationData isoData { chip, chipType };
- iso.isolate( chip, chipType, isoData );
+ libhei::isolate( isoData );
+
+ libhei::uninitialize();
return 0;
}
diff --git a/test/simulator/meson.build b/test/simulator/meson.build
index 4f72f2e..e581b1a 100644
--- a/test/simulator/meson.build
+++ b/test/simulator/meson.build
@@ -1,6 +1,6 @@
sim_sources = [
'hei_sim_main.cpp',
- '../../src/hei_isolator.cpp'
+ '../../src/isolator/hei_isolator.cpp'
]
sim = executable('simulator', sim_sources, \