Create SCOM and ID SCOM register classes

SCOM and ID SCOM registers are specialized register that will exist
under the HardwareRegister abstract class.

Change-Id: I40c39536ca7321c9ef36347cef2320cf7fc4da49
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/src/register/hei_hardware_register.cpp b/src/register/hei_hardware_register.cpp
index e007eca..0c1e871 100755
--- a/src/register/hei_hardware_register.cpp
+++ b/src/register/hei_hardware_register.cpp
@@ -51,9 +51,13 @@
 namespace libhei
 {
 
-#if 0
-// ---------------------------------------------------------------------
+//------------------------------------------------------------------------------
 
+HardwareRegister::~HardwareRegister() {}
+
+//------------------------------------------------------------------------------
+
+#if 0
 void HardwareRegister::SetBitString( const BitString *bs )
 {
     BitString & l_string  = AccessBitString();
diff --git a/src/register/hei_hardware_register.hpp b/src/register/hei_hardware_register.hpp
index 255cf5a..3d2f974 100755
--- a/src/register/hei_hardware_register.hpp
+++ b/src/register/hei_hardware_register.hpp
@@ -18,8 +18,8 @@
 {
 
 /**
- * @brief Stores information (e.g. address, type, length, etc.) for an actual
- *        hardware register.
+ * @brief An abstract class containing information (e.g. address, type, length,
+ *        etc.) for an actual hardware register.
  *
  * Hardware access:
  *
@@ -52,6 +52,69 @@
 {
   public:
 
+    /** @brief Pure virtual destructor. */
+    virtual ~HardwareRegister() = 0;
+
+  protected:
+
+    /**
+     * @brief Constructor from components.
+     * @param i_chipType    Type of chip associated with this register.
+     * @param i_id          Unique ID for this register.
+     * @param i_instance    Instance of this register
+     * @param i_accessLevel Hardware access level for this register.
+     */
+    HardwareRegister( ChipType_t i_chipType, RegisterId_t i_id,
+                      RegisterInstance_t i_instance,
+                      RegisterAccessLevel_t i_accessLevel ) :
+        Register(), iv_chipType( i_chipType ), iv_id( i_id ),
+        iv_instance( i_instance ), iv_accessLevel( i_accessLevel )
+    {}
+
+  private: // Instance variables
+
+    /** The type of chip associated with register. */
+    const ChipType_t iv_chipType;
+
+    /** The unique ID for this register. */
+    const RegisterId_t iv_id;
+
+    /** A register may have multiple instances. All of which will have the same
+     *  ID. This variable is used to distinguish between each instance of the
+     *  register. */
+    const RegisterInstance_t iv_instance;
+
+    /** The hardware access level of this register (read/write, read-only,
+     *  write-only, etc.). */
+    const RegisterAccessLevel_t iv_accessLevel;
+
+  public: // Accessor functions
+
+    /** @return The type of chip associated with this register. */
+    ChipType_t getChipType() const { return iv_chipType; }
+
+    /* @return The unique ID for this register. */
+    RegisterId_t getId() const { return iv_id; }
+
+    /* @return The instance of this register. */
+    RegisterInstance_t getInstance() const { return iv_instance; }
+
+    /** @return The hardware access level of this register. */
+    RegisterAccessLevel_t getAccessLevel() const { return iv_accessLevel; }
+
+    // NOTE: The following are determined by child classes.
+
+    /** @return This register's type. */
+    virtual RegisterType_t getRegisterType() const = 0;
+
+    /** @return The address of this register. */
+    virtual RegisterAddress_t getAddress() const = 0;
+
+    /** @return The size (in bytes) of this register. */
+    virtual size_t getSize() const = 0;
+
+  public:
+
 #if 0
     /**
      * @brief     constructor
diff --git a/src/register/hei_scom_register.hpp b/src/register/hei_scom_register.hpp
new file mode 100644
index 0000000..b781694
--- /dev/null
+++ b/src/register/hei_scom_register.hpp
@@ -0,0 +1,188 @@
+#pragma once
+
+#include <register/hei_hardware_register.hpp>
+
+namespace libhei
+{
+
+/**
+ * @brief A Power Systems SCOM register.
+ *
+ * Address width:   4 bytes
+ * Register width:  8 bytes
+ * Bit order:       Ascending (0-63 left to right)
+ */
+class ScomRegister : public HardwareRegister
+{
+  public: // Constructor, destructors, assignment, etc.
+
+    /**
+     * @brief Constructor from components.
+     * @param i_chipType    Type of chip associated with this register.
+     * @param i_id          Unique ID for this register.
+     * @param i_instance    Instance of this register
+     * @param i_accessLevel Hardware access level for this register.
+     * @param i_address     A 4-byte address for this SCOM register.
+     */
+    ScomRegister( ChipType_t i_chipType, RegisterId_t i_id,
+                  RegisterInstance_t i_instance,
+                  RegisterAccessLevel_t i_accessLevel, uint32_t i_address ) :
+        HardwareRegister( i_chipType, i_id, i_instance, i_accessLevel ),
+        iv_address( i_address )
+    {}
+
+    /** @brief Destructor. */
+    ~ScomRegister() = default;
+
+    /**
+     * @brief Copy constructor.
+     *
+     * Would prefer to delete this to prevent implicit copy assignments, but it
+     * is needed by the Flyweight class.
+     */
+    ScomRegister( const ScomRegister & ) = default;
+
+    /**
+     * @brief Explicitly disables assignment operator.
+     *
+     * This is redundant since the compilier will implicitly delete this because
+     * of the constant instance variables, but helps communicate it is not
+     * allowed.
+     */
+    ScomRegister & operator=( const ScomRegister & ) = delete;
+
+  public: // Accessor functions
+
+    /** Function overloaded from parent HardwareRegister class. */
+    RegisterType_t getRegisterType() const { return REG_TYPE_SCOM; }
+
+    /** Function overloaded from parent HardwareRegister class. */
+    RegisterAddress_t getAddress() const
+    {
+        return static_cast<RegisterAddress_t>( iv_address );
+    }
+
+    /** Function overloaded from parent HardwareRegister class. */
+    size_t getSize() const { return 8; }
+
+  public: // Operators
+
+    /** @brief Equals operator. */
+    bool operator==( const ScomRegister & i_r ) const
+    {
+        // Comparing address and chip type should be sufficient.
+        return ( getAddress()  == i_r.getAddress()  ) &&
+               ( getChipType() == i_r.getChipType() );
+    }
+
+    /** @brief Less than operator. */
+    bool operator<( const ScomRegister & i_r ) const
+    {
+        // Comparing address and chip type should be sufficient.
+        return (   getAddress()  <  i_r.getAddress()       ) ||
+               ( ( getAddress()  == i_r.getAddress()  ) &&
+                 ( getChipType() <  i_r.getChipType() )    );
+    }
+
+  private: // Instance variables
+
+    /** This register's address. */
+    const uint32_t iv_address;
+
+}; // end class ScomRegister
+
+/**
+ * @brief A Power Systems Indirect SCOM register.
+ *
+ * Address width:   8 bytes
+ * Register width:  2* bytes (see note below)
+ * Bit order:       Ascending (0-63 left to right)
+ *
+ * IMPORTANT NOTE:
+ *   Technically, only two bytes of data are actually used. However, the bit
+ *   definition of these registers put the two bytes at the end of the returned
+ *   value (bit 48-63). Therefore, this class will be made to look like the
+ *   width is 8 bytes in order to make the bit indexing work in the returned
+ *   BitString.
+ */
+class IdScomRegister : public HardwareRegister
+{
+  public: // Constructor, destructors, assignment, etc.
+
+    /**
+     * @brief Constructor from components.
+     * @param i_chipType    Type of chip associated with this register.
+     * @param i_id          Unique ID for this register.
+     * @param i_instance    Instance of this register
+     * @param i_accessLevel Hardware access level for this register.
+     * @param i_address     An 8-byte address for this Indirect SCOM register.
+     */
+    IdScomRegister( ChipType_t i_chipType, RegisterId_t i_id,
+                    RegisterInstance_t i_instance,
+                    RegisterAccessLevel_t i_accessLevel, uint64_t i_address ) :
+        HardwareRegister( i_chipType, i_id, i_instance, i_accessLevel ),
+        iv_address( i_address )
+    {}
+
+    /** @brief Destructor. */
+    ~IdScomRegister() = default;
+
+    /**
+     * @brief Copy constructor.
+     *
+     * Would prefer to delete this to prevent implicit copy assignments, but it
+     * is needed by the Flyweight class.
+     */
+    IdScomRegister( const IdScomRegister & ) = default;
+
+    /**
+     * @brief Explicitly disables assignment operator.
+     *
+     * This is redundant since the compilier will implicitly delete this because
+     * of the constant instance variables, but helps communicate it is not
+     * allowed.
+     */
+    IdScomRegister & operator=( const IdScomRegister & ) = delete;
+
+  public: // Accessor functions
+
+    /** Function overloaded from parent HardwareRegister class. */
+    RegisterType_t getRegisterType() const { return REG_TYPE_ID_SCOM; }
+
+    /** Function overloaded from parent HardwareRegister class. */
+    RegisterAddress_t getAddress() const
+    {
+        return static_cast<RegisterAddress_t>( iv_address );
+    }
+
+    /** Function overloaded from parent HardwareRegister class. */
+    size_t getSize() const { return 8; } // See note in class documentation.
+
+  public: // Operators
+
+    /** @brief Equals operator. */
+    bool operator==( const IdScomRegister & i_r ) const
+    {
+        // Comparing address and chip type should be sufficient.
+        return ( getAddress()  == i_r.getAddress()  ) &&
+               ( getChipType() == i_r.getChipType() );
+    }
+
+    /** @brief Less than operator. */
+    bool operator<( const IdScomRegister & i_r ) const
+    {
+        // Comparing address and chip type should be sufficient.
+        return (   getAddress()  <  i_r.getAddress()       ) ||
+               ( ( getAddress()  == i_r.getAddress()  ) &&
+                 ( getChipType() <  i_r.getChipType() )    );
+    }
+
+  private: // Instance variables
+
+    /** This register's address. */
+    const uint64_t iv_address;
+
+}; // end class IdScomRegister
+
+} // end namespace libhei
+