Add simulated SCOM/CFAM read support for test
Change-Id: I615f1819cd309528735d63f2e6e4b4181c58fd34
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/test/sim-hw-access.hpp b/test/sim-hw-access.hpp
new file mode 100644
index 0000000..6bc7a30
--- /dev/null
+++ b/test/sim-hw-access.hpp
@@ -0,0 +1,190 @@
+#include <assert.h>
+
+#include <util/pdbg.hpp>
+
+#include <map>
+
+namespace sim
+{
+
+class ScomAccess
+{
+ private:
+ /** @brief Default constructor. */
+ ScomAccess() = default;
+
+ /** @brief Destructor. */
+ ~ScomAccess() = default;
+
+ /** @brief Copy constructor. */
+ ScomAccess(const ScomAccess&) = delete;
+
+ /** @brief Assignment operator. */
+ ScomAccess& operator=(const ScomAccess&) = delete;
+
+ public:
+ /** @brief Provides access to a singleton instance of this object. */
+ static ScomAccess& getSingleton()
+ {
+ static ScomAccess theScomAccess;
+ return theScomAccess;
+ }
+
+ private:
+ /** The SCOM values for each chip and address. */
+ std::map<pdbg_target*, std::map<uint64_t, uint64_t>> iv_values;
+
+ /** All addresses that will return a SCOM error. */
+ std::map<pdbg_target*, std::map<uint64_t, bool>> iv_errors;
+
+ public:
+ /**
+ * @brief Stores a SCOM register value, which can be accessed later in test.
+ * @param i_target The target chip.
+ * @param i_addr A SCOM address on the given chip.
+ * @param i_val The value of the given address.
+ */
+ void add(pdbg_target* i_target, uint64_t i_addr, uint64_t i_val)
+ {
+ assert(nullptr != i_target);
+
+ iv_values[i_target][i_addr] = i_val;
+ }
+
+ /**
+ * @brief This can be used to specify if a specific SCOM address will return
+ * an error when accessed. This is useful for error path testing.
+ * @param i_target The target chip.
+ * @param i_addr A SCOM address on the given chip.
+ */
+ void error(pdbg_target* i_target, uint64_t i_addr)
+ {
+ assert(nullptr != i_target);
+
+ iv_errors[i_target][i_addr] = true;
+ }
+
+ /**
+ * @brief Clears all SCOM value/error data.
+ */
+ void flush()
+ {
+ iv_values.clear();
+ iv_errors.clear();
+ }
+
+ /**
+ * @brief Returns the stored SCOM register value.
+ * @param i_target The target chip.
+ * @param i_addr A SCOM address on the given chip.
+ * @param o_val The value of the given address. If the target address
+ * does not exist in iv_values, a value of 0 is returned.
+ * @return Will return 1 if the target address exists in iv_errors.
+ * Otherwise, will return 0 for a successful SCOM access.
+ */
+ int get(pdbg_target* i_target, uint64_t i_addr, uint64_t& o_val)
+ {
+ assert(nullptr != i_target);
+
+ if (iv_errors[i_target][i_addr])
+ {
+ return 1;
+ }
+
+ o_val = iv_values[i_target][i_addr];
+
+ return 0;
+ }
+};
+
+class CfamAccess
+{
+ private:
+ /** @brief Default constructor. */
+ CfamAccess() = default;
+
+ /** @brief Destructor. */
+ ~CfamAccess() = default;
+
+ /** @brief Copy constructor. */
+ CfamAccess(const CfamAccess&) = delete;
+
+ /** @brief Assignment operator. */
+ CfamAccess& operator=(const CfamAccess&) = delete;
+
+ public:
+ /** @brief Provides access to a singleton instance of this object. */
+ static CfamAccess& getSingleton()
+ {
+ static CfamAccess theCfamAccess;
+ return theCfamAccess;
+ }
+
+ private:
+ /** The CFAM values for each chip and address. */
+ std::map<pdbg_target*, std::map<uint32_t, uint32_t>> iv_values;
+
+ /** All addresses that will return a CFAM error. */
+ std::map<pdbg_target*, std::map<uint32_t, bool>> iv_errors;
+
+ public:
+ /**
+ * @brief Stores a CFAM register value, which can be accessed later in test.
+ * @param i_target The target chip.
+ * @param i_addr A CFAM address on the given chip.
+ * @param i_val The value of the given address.
+ */
+ void add(pdbg_target* i_target, uint32_t i_addr, uint32_t i_val)
+ {
+ assert(nullptr != i_target);
+
+ iv_values[i_target][i_addr] = i_val;
+ }
+
+ /**
+ * @brief This can be used to specify if a specific CFAM address will return
+ * an error when accessed. This is useful for error path testing.
+ * @param i_target The target chip.
+ * @param i_addr A CFAM address on the given chip.
+ */
+ void error(pdbg_target* i_target, uint32_t i_addr)
+ {
+ assert(nullptr != i_target);
+
+ iv_errors[i_target][i_addr] = true;
+ }
+
+ /**
+ * @brief Clears all CFAM value/error data.
+ */
+ void flush()
+ {
+ iv_values.clear();
+ iv_errors.clear();
+ }
+
+ /**
+ * @brief Returns the stored CFAM register value.
+ * @param i_target The target chip.
+ * @param i_addr A CFAM address on the given chip.
+ * @param o_val The value of the given address. If the target address
+ * does not exist in iv_values, a value of 0 is returned.
+ * @return Will return 1 if the target address exists in iv_errors.
+ * Otherwise, will return 0 for a successful CFAM access.
+ */
+ int get(pdbg_target* i_target, uint32_t i_addr, uint32_t& o_val)
+ {
+ assert(nullptr != i_target);
+
+ if (iv_errors[i_target][i_addr])
+ {
+ return 1;
+ }
+
+ o_val = iv_values[i_target][i_addr];
+
+ return 0;
+ }
+};
+
+} // namespace sim