Add hardware access support HardwareRegister class
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
Change-Id: Id0ff5a3c06e02ae5dc2c9ca5096fe636391daa56
diff --git a/src/register/hei_hardware_register.hpp b/src/register/hei_hardware_register.hpp
index c6722fb..066f6db 100755
--- a/src/register/hei_hardware_register.hpp
+++ b/src/register/hei_hardware_register.hpp
@@ -14,10 +14,6 @@
#include <register/hei_register.hpp>
#include <util/hei_bit_string.hpp>
-#if 0
-#include <prdfHomRegisterAccess.H>
-#endif
-
namespace libhei
{
@@ -28,11 +24,28 @@
class ExtensibleChip;
#endif
+/**
+ * @brief Stores information (e.g. address, type, length, etc.) for an actual
+ * hardware register.
+ *
+ * Hardware access:
+ *
+ * Actual hardware access is defined by the user application via the user
+ * interface APIs. In order to tell the user application which chip to target,
+ * the user application gives the isolator pointers to its chip objects. As
+ * each chip needs to be accessed, the isolator must store the chip in a
+ * static variable defined in this class. The intended use is:
+ *
+ * - Call HardwareRegister::setAccessor() with the target chip.
+ * - Perform all necessary hardware accesses to that chip.
+ * - Call HardwareRegister::clearAccessor() to remove the chip access. This
+ * helps ensure we don't try to access the wrong chip.
+ */
class HardwareRegister : public Register
{
-#if 0
public:
+#if 0
/**
* @brief constructor
* @param i_address address of the register
@@ -81,26 +94,31 @@
* @return length of bit string
*/
uint32_t GetBitLength(void) const { return iv_bitLength ;}
+#endif
/**
- * @brief Directly reads from hardware register
- * @return SUCCESS|FAIL
+ * @brief Reads a register from hardware via the user interface APIs.
+ * @param i_force When false, this function will only read from hardware if
+ * an entry for this instance does not already exist in the
+ * register cache. When true, the entry in the register
+ * cache is flushed, if it exists. Then this function will
+ * read from hardware and update the cache.
+ * @return See the return code from the registerRead() user interface API.
*/
- virtual uint32_t ForceRead() const;
+ ReturnCode read( bool i_force = false ) const;
+
+ #ifndef __HEI_READ_ONLY
/**
- * @brief Returns contents of register.If entry does not exist in cache
- * a fresh entry is created and hardware is read.
- * @return SUCCESS|FAIL
- */
- virtual uint32_t Read() const;
-
- /**
- * @brief Writes cache contents to register.
- * @return SUCCESS|FAIL
+ * @brief Writes the value stored in the register cache to hardware via the
+ * user interface APIs.
+ * @return See the return code from the registerWrite() user interface API.
*/
- virtual uint32_t Write();
+ ReturnCode write() const;
+ #endif // __HEI_READ_ONLY
+
+#if 0
/**
* @brief Returns the hash id of register
* @return returns hash id of register
@@ -173,21 +191,6 @@
* @return Refer to function description
*/
virtual BitString & AccessBitString( );
- /**
- * @brief Gets the register read and write done by calling access
- * function of scom accessor service.
- * @param reference to bit string maintained in caller class
- * @param Read or write operation
- * @return [SUCCESS|FAIL]
- */
- uint32_t Access( BitString & bs,
- RegisterAccess::Operation op )const;
-
- /**
- * @brief Returns rulechip pointer associated with the register
- * @return Refer to function description
- */
- virtual ExtensibleChip * getChip() const;
private: // functions
@@ -218,6 +221,90 @@
AccessLevel iv_operationType; // Operation supported (RO, WO, or RW)
#endif
+
+ private: // Hardware accessor class variable
+
+ /** @brief A simple class that stores the chip used to access hardware. */
+ class Accessor
+ {
+ public:
+
+ /**
+ * @brief Constructor.
+ * @param i_chip The chip used to access hardware.
+ */
+ explicit Accessor( const Chip & i_chip ) :
+ iv_chip( i_chip )
+ {}
+
+ /** @brief Destructor. */
+ ~Accessor() = default;
+
+ /** @brief Copy constructor. */
+ Accessor( const Accessor & ) = delete;
+
+ /** @brief Assignment operator. */
+ Accessor & operator=( const Accessor & ) = delete;
+
+ /** @return The chip used to access hardware. */
+ const Chip & getChip() const { return iv_chip; }
+
+ private:
+
+ /**
+ * A Chip object provided by the user application. The isolator does not
+ * know anything about this object nor how to use it. Its only purpose
+ * is to get passed back to the user application for hardware access
+ * operations.
+ */
+ const Chip iv_chip;
+
+ }; // end class Accessor
+
+ /**
+ * This allows all HardwareRegister objects access to a chip via the user
+ * interface APIs. It is intentially defined as a pointer. It can be set to
+ * nullptr to signify that access is restricted at this time. This is useful
+ * to prevent users from accidentally accessing registers on the wrong chip.
+ * It is recommended to use setAccessor() and clearAccessor() to manage this
+ * variable.
+ */
+ static Accessor * cv_accessor;
+
+ public: // Hardware accessor management functions.
+
+ /**
+ * @brief Initializes a new hardware accessor.
+ * @param i_chip The chip used to access hardware.
+ */
+ static void setAccessor( const Chip & i_chip )
+ {
+ clearAccessor();
+ cv_accessor = new Accessor( i_chip );
+ }
+
+ /** @brief Deletes the current hardware accessor. */
+ static void clearAccessor()
+ {
+ delete cv_accessor;
+ cv_accessor = nullptr;
+ }
+
+ private: // Hardware accessor management functions.
+
+ /** @return The chip stored in cv_accessor. */
+ const Chip & getAccessorChip() const
+ {
+ HEI_ASSERT( nullptr != cv_accessor );
+
+#if 0
+ // Extra sanity check to verify this register belongs on the target
+ // accessor chip.
+ HEI_ASSERT( getChipType() != cv_accessor->getChip().getChipType() );
+#endif
+
+ return cv_accessor->getChip();
+ }
};
} // end namespace libhei