Updates to Isolator class interfaces
Change-Id: I9c7abeba489507de9f4a2a075a5c94d7fcf25247
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/README.md b/README.md
index a2977f8..5a37a51 100644
--- a/README.md
+++ b/README.md
@@ -5,14 +5,15 @@
hardware registers on POWER Systems chips.
The primary consumers (and requirements drivers) will be:
- * [OpenBMC Hardware Diagnostics](https://github.com/openbmc/openpower-hw-diags)
- * [POWER Systems Hostboot firmware](https://github.com/open-power/hostboot)
+ * [OpenBMC Hardware Diagnostics]
+ * [POWER Systems Hostboot firmware]
* POWER Systems FSP firmware
Core API
--------
-Details TBD.
+The primary APIs are in the [Isolator class]. See the class definition for
+details on how to use it.
Integration
-----------
@@ -24,6 +25,7 @@
User Application Requirements and APIs
--------------------------------------
+
* The method to access hardware register data will vary per user application.
Therefore, this library will declare the hardware access [user APIs], but
each containing user application must implement the APIs for their own
@@ -41,9 +43,6 @@
header file that defines macros for assertion. Details are included in the
[user APIs].
-[user APIs]: src/hei_user_interface.hpp
-[Chip Data Files]: src/chip_data/CHIP_DATA.md
-
Environment configuration
-------------------------
@@ -61,5 +60,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
- [Hostboot project](https://github.com/open-power/hostboot).
+ [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
+[user APIs]: src/hei_user_interface.hpp
+[Chip Data Files]: src/chip_data/CHIP_DATA.md
diff --git a/src/chip_data/hei_chip_data.hpp b/src/chip_data/hei_chip_data.hpp
new file mode 100644
index 0000000..810198c
--- /dev/null
+++ b/src/chip_data/hei_chip_data.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "hei_includes.hpp"
+
+namespace libhei
+{
+
+typedef uint32_t ChipType_t;
+
+} // end namespace libhei
diff --git a/src/hei_includes.hpp b/src/hei_includes.hpp
index fa2506b..dbb8b35 100644
--- a/src/hei_includes.hpp
+++ b/src/hei_includes.hpp
@@ -3,8 +3,12 @@
// The purpose of this file is to include common headers that will be used
// throughout this library.
+// Standard library includes
#include <stdint.h>
-#include <hei_return_code.hpp>
+// External includes
#include <hei_user_defines.hpp> // For HEI_ASSERT, HEI_INF, and HEI_ERR
+// Internal includes
+#include "hei_return_code.hpp"
+
diff --git a/src/hei_isolation_data.hpp b/src/hei_isolation_data.hpp
new file mode 100644
index 0000000..57344bd
--- /dev/null
+++ b/src/hei_isolation_data.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "hei_includes.hpp"
+
+namespace libhei
+{
+
+/**
+ * @brief Contain a list of all active hardware errors on a chip, the contents
+ * of any registers associated with the active errors, and any other data
+ * that can be useful for debug.
+ */
+class IsolationData
+{
+ public:
+
+ /** @brief Default constructor. */
+ IsolationData() = default;
+
+ /** @brief Copy constructor. */
+ IsolationData( const IsolationData & ) = default;
+
+ /** @brief Assignment operator. */
+ IsolationData & operator=( const IsolationData & ) = default;
+
+ /** @brief Destructor. */
+ ~IsolationData() = default;
+
+ private:
+
+}; // end class IsolationData
+
+} // end namespace libhei
+
diff --git a/src/hei_isolator.cpp b/src/hei_isolator.cpp
index fda761f..6a81707 100644
--- a/src/hei_isolator.cpp
+++ b/src/hei_isolator.cpp
@@ -4,24 +4,30 @@
namespace libhei
{
-Isolator::Isolator()
+ReturnCode Isolator::initialize( void * i_buffer, size_t i_bufferSize,
+ bool i_forceInit )
{
- HEI_INF( "Isolator::Isolator()" );
+ 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;
}
-Isolator::~Isolator()
+ReturnCode Isolator::isolate( void * i_chip, ChipType_t i_chipType,
+ IsolationData & o_isoData )
{
- HEI_INF( "Isolator::~Isolator()" );
-}
+ ReturnCode rc;
-void Isolator::initialize()
-{
- HEI_INF( "Isolator::initialize()" );
-}
+ // BEGIN temporary code for compilation
+ o_isoData = IsolationData();
+ HEI_INF( "Isolator::isolate(%p,%u)", i_chip, i_chipType );
+ // END temporary code for compilation
-void Isolator::isolate()
-{
- HEI_INF( "Isolator::isolate()" );
+ return rc;
}
} // end namespace libhei
diff --git a/src/hei_isolator.hpp b/src/hei_isolator.hpp
index 483b260..3a07d75 100644
--- a/src/hei_isolator.hpp
+++ b/src/hei_isolator.hpp
@@ -1,22 +1,113 @@
-
#pragma once
-#include "hei_user_interface.hpp"
+#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:
- Isolator();
+ /** @brief Default constructor. */
+ Isolator() = default;
- ~Isolator();
+ /** @brief Destructor. */
+ ~Isolator() = default;
- void initialize();
+ /** @brief Copy constructor. */
+ Isolator( const Isolator & ) = delete;
- void isolate();
+ /** @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:
diff --git a/src/hei_return_code.hpp b/src/hei_return_code.hpp
index cdb1700..ce32468 100644
--- a/src/hei_return_code.hpp
+++ b/src/hei_return_code.hpp
@@ -59,7 +59,17 @@
};
/** Function returned successfully. */
-static constexpr ReturnCode RC_SUCCESS = ReturnCode();
+static constexpr ReturnCode RC_SUCCESS = ReturnCode();
-}; // end namespace libhei
+/** The given Chip Data File is malformed or unsupported. */
+static constexpr ReturnCode RC_CHIP_DATA_INVALID = ReturnCode(0x00000001);
+
+/** The given Chip Data File contains a chip type that has already been
+ * initialized. */
+static constexpr ReturnCode RC_CHIP_DATA_INITIALIZED = ReturnCode(0x00000002);
+
+/** The given chip type has not been initialized. */
+static constexpr ReturnCode RC_CHIP_DATA_MISSING = ReturnCode(0x00000003);
+
+} // end namespace libhei
diff --git a/src/hei_user_interface.hpp b/src/hei_user_interface.hpp
index 30e869d..1d3b5d3 100644
--- a/src/hei_user_interface.hpp
+++ b/src/hei_user_interface.hpp
@@ -1,4 +1,3 @@
-
#pragma once
// The user application must define this header file with the following macros:
@@ -16,16 +15,26 @@
{
/**
- * @brief Perform a hardware read operation.
+ * @brief Perform a hardware read operation.
+ * @param i_chip This is 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. It is provide by the user application
+ * via the Isolator APIs. The user application is responsible for
+ * knowing what to do with this parameter.
*/
-void deviceRead();
+ReturnCode deviceRead( void * i_chip );
#ifndef __HEI_READ_ONLY
/**
- * @brief Perform a hardware write operation.
+ * @brief Perform a hardware write operation.
+ * @param i_chip This is 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. It is provide by the user application
+ * via the Isolator APIs. The user application is responsible for
+ * knowing what to do with this parameter.
*/
-void deviceWrite();
+ReturnCode deviceWrite( void * i_chip );
#endif
diff --git a/test/simulator/hei_sim_main.cpp b/test/simulator/hei_sim_main.cpp
index 41ffe7f..e83a577 100644
--- a/test/simulator/hei_sim_main.cpp
+++ b/test/simulator/hei_sim_main.cpp
@@ -4,9 +4,16 @@
{
libhei::Isolator iso;
- iso.initialize();
+ void * buffer = nullptr;
+ size_t sz_buffer = 0;
- iso.isolate();
+ iso.initialize( buffer, sz_buffer );
+
+ void * chip = nullptr;
+ libhei::ChipType_t chipType = 0;
+ libhei::IsolationData isoData;
+
+ iso.isolate( chip, chipType, isoData );
return 0;
}