Copied PRD register access code from Hostboot project
This is just a straight copy from the Hostboot project. No modifications
have been made. Those will come in later commits.
Change-Id: Id9985f5542944ba88498b348b24b711fe2c30704
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/src/register/iipCaptureData.h b/src/register/iipCaptureData.h
new file mode 100755
index 0000000..e65e94d
--- /dev/null
+++ b/src/register/iipCaptureData.h
@@ -0,0 +1,405 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/iipCaptureData.h $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef iipCaptureData_h
+#define iipCaptureData_h
+
+// Class Specification *************************************************
+//
+// Class name: CaptureData
+// Parent class: None.
+//
+// Summary: This class provides a queue-like buffer for recording Scan
+// Comm Register data.
+//
+// When this class is constructed or the Clear() member
+// function is called, the buffer is empty. The Add()
+// function adds data to the front or back of this buffer.
+// The data is ordered according to the sequence of Add()
+// calls and the Place parameter (FRONT or BACK). A Scan
+// Comm Register is passed to the Add() function and the
+// register is read during the Add() function. The data is
+// then stored internally. Whenever the Copy() member
+// function is called, the current internal data is copied to
+// the specified buffer with respect to the current ordering.
+// Only the number of bytes specified are copied. Therefore,
+// any data that MUST be copied should be added using the
+// FRONT placement.
+//
+// Cardinality: N
+//
+// Performance/Implementation:
+// Space Complexity: Linear based on the number of Add() calls
+// Time Complexity: All member functions constant unless otherwise
+// stated.
+//
+// Usage Examples:
+//
+// BIT8 data[BUFFER_SIZE];
+//
+// void foo(TARGETING::TargetHandle_t chipId, ScanCommRegisterAccess & scr)
+// {
+// CaptureData captureData;
+//
+// captureData.Add(chipId, scr, CaptureData::FRONT);
+// captureData.Add(chipId, scr, CaptureData::BACK);
+//
+// int bytesCopied = captureData.Copy(data, BUFFER_SIZE);
+// }
+//
+// End Class Specification *********************************************
+
+/*--------------------------------------------------------------------*/
+/* Reference the virtual function tables and inline function
+ defintions in another translation unit. */
+/*--------------------------------------------------------------------*/
+
+#include <list>
+
+#ifndef IIPCONST_H
+#include <iipconst.h>
+#endif
+#include <prdfPlatServices.H>
+#include <functional> // @jl04 a Needed for the unary function in new predicate.
+
+#ifdef __HOSTBOOT_MODULE
+
+ // FIXME: RTC 73204 was opened to add support for these in hostboot. They will
+ // need to be removed once the issue has been resolved.
+ #ifndef htonl
+ #define htonl(foo) (foo)
+ #endif
+
+ #ifndef htons
+ #define htons(foo) (foo)
+ #endif
+
+ #ifndef ntohl
+ #define ntohl(foo) (foo)
+ #endif
+
+ #ifndef ntohs
+ #define ntohs(foo) (foo)
+ #endif
+
+#else
+
+ #include <netinet/in.h>
+
+#endif
+
+namespace PRDF
+{
+
+// Forward Declarations
+class SCAN_COMM_REGISTER_CLASS;
+class ScanCommRegisterAccess;
+class BitString;
+
+// @jl04 a start
+// @jl04 a Added this enumeration for error log compression, elimination of secondary regs.
+ enum RegType
+ {
+ PRIMARY = 1,
+ SECONDARY = 2
+ };
+// @jl04 a Stop
+
+/**
+ Capture data class
+ @author Doug Gilbert
+ @version V5R2
+*/
+class CaptureData
+{
+public:
+
+ enum Place
+ {
+ FRONT,
+ BACK
+ };
+
+ enum
+ {
+ INITIAL_DATA_COUNT = 80,
+ ENTRY_FIXED_SIZE = 8,
+ MAX_ENTRY_SIZE = 128
+ };
+
+ /**
+ Constructor
+ */
+ CaptureData(void);
+
+ /*
+ Copy constructor - default is ok
+ */
+// CaptureData(const CaptureData & c);
+
+ /*
+ Assignment operator - default is ok
+ */
+// CaptureData & operator=(const CaptureData & c);
+
+ /**
+ Destructor
+ */
+// dg05d ~CaptureData(void); // compiler default is ok
+
+ /**
+ Clear out capture data
+ <ul>
+ <br><b>Parameters:None
+ <br><b>Returns:Nothing
+ <br><b>Requirments:None.
+ <br><b>Promises: All capture data cleared ( copy(...) == 0 )
+ </ul><br>
+ */
+ void Clear(void);
+
+ // dg00 start
+ /**
+ Add scr & data to capture log
+ <ul>
+ <br><b>Parameter: chipHandle target handle of chip object
+ <br><b>Parameter: scan comm id (unique one btye code representing scan comm address)
+ <br><b>Parameter: Scan comm register object
+ <br><b>Parameter: Optional location in capure vector [FRONT | BACK] def = BACK
+ <br><b>Returns: Nothing
+ <br><b>Requires: Nothing
+ <br><b>Promises: scr.Read()
+ <br><b>Notes: This is the required Add() method for Regatta and beyond
+ </ul><br>
+ */
+ void Add( TARGETING::TargetHandle_t i_pchipHandle, int scomId,
+ SCAN_COMM_REGISTER_CLASS & scr, Place place = BACK,
+ RegType type = PRIMARY); // @jl04 c. Changed this to add the type to the end of the parms.
+ // dg00 end
+
+ /* REMOVE for FSP
+ Add scr & data to capture log
+ <ul>
+ <br><b>Parameter: chipHandle target handle of chip object
+ <br><b>Parameter: Scan comm register object
+ <br><b>Parameter: Optional location in capure vector [FRONT | BACK] def = BACK
+ <br><b>Returns: Nothing
+ <br><b>Requires: Nothing
+ <br><b>Promises: scr.Read()
+ <br><b>Notes: This is the required Add() method for pre-Regatta
+ </ul><br>
+
+ void Add(TARGETING::TargetHandle_t chipId, SCAN_COMM_REGISTER_CLASS & scr,
+ Place place = BACK);
+*/
+
+ // dg02 start
+ /**
+ Add scr & data to capture log
+ <ul>
+ <br><b>Parameter: i_pchipHandle Handle of chip object
+ <br><b>Parameter: scan comm id (unique one btye code representing scan comm address)
+ <br><b>Parameter: BitString
+ <br><b>Parameter: Optional location in capure vector [FRONT | BACK] def = BACK
+ <br><b>Returns: Nothing
+ <br><b>Requires: Nothing
+ <br><b>Promises:
+ <br><b>Notes: This is available for Regatta and beyond. Not implemented on Condor
+ </ul><br>
+ */
+ void Add( TARGETING::TargetHandle_t i_pchipHandle, int scomId,
+ const BitString & bs, Place place = BACK);
+
+ // dg02 end
+
+// start @jl04a
+ /**
+ Drop scr & data from capture log
+ <ul>
+ <br><b>Parameter: Type of capture vector [PRIMARY | SECONDARY] def = PRIMARY. SECONDARIES dropped on connected.
+ <br><b>Returns: Nothing
+ <br><b>Requires: Nothing
+ <br><b>Promises:
+ </ul><br>
+ */
+void Drop(RegType type); //@jl04a
+// end @jl04a
+
+ /**
+ * @brief Copies the capture data to a buffer.
+ *
+ * The capture data is copied to the buffer in the order it exists in the
+ * vector until all entries have been added or until the buffer is full.
+ *
+ * @param i_buffer Pointer to buffer.
+ * @param i_bufferSize Maximum size of the buffer.
+ * @return The actual size of the data buffer. The value will always be less
+ * than or equal to the maximum buffer size.
+ */
+ uint32_t Copy( uint8_t * i_buffer, uint32_t i_bufferSize ) const;
+
+ // dg08a -->
+ /**
+ Reconstruct data from flat data
+ <ul>
+ <br><b>Parameter: i_flatdata ptr to flat data
+ <br><b>Returns: reference to the new capture data
+ <br><b>Requirements: None
+ <br><b>Promises: CaptureData created form flatdata
+ <br><b>Note: i_flatdata -> (uin32_t)size + data created by Copy()
+ data is network ordered bytes.
+ <ul><br>
+ */
+ CaptureData & operator=(const uint8_t *i_flatdata);
+ // <-- dg08a
+
+private:
+
+ // Notes *************************************************************
+ //
+ // Instead of maintaining an actual data buffer, an auxiliary data
+ // structure is used to maintain data in a specific order. The main
+ // reason for this is that since data can be entered in the front or
+ // back of the buffer, the data must be copied to maintain the order.
+ // It is more efficient to copy a number of pointers than a large
+ // data buffer. However, there is added complexity since the data
+ // structure contains a pointer to dynamic data that must be
+ // allocated/deallocated properly.
+ //
+ // A vector of data structures is maintained that is given an initial
+ // size. The vector can grow dynamically, but this can be expensive
+ // in terms of copying and memory fragmentation. To prevent this, the
+ // number of calls to Add() between calls to Clear() should not exceed
+ // the enum INITIAL_DATA_COUNT.
+ //
+ // End Notes *********************************************************
+
+ class Data
+ {
+ public:
+ // Ctor
+ Data(TARGETING::TargetHandle_t i_pchipHandle= NULL, // dg01
+ uint16_t a = 0,
+ uint16_t dbl = 0,
+ uint8_t * dPtr = NULL)
+ :
+ chipHandle(i_pchipHandle),
+ address(a),
+ dataByteLength(dbl),
+ dataPtr(dPtr)
+ {}
+
+ ~Data(void) // dg05a
+ { // dg05a
+ if(dataPtr != NULL) // dg05a
+ { // dg05a
+ delete [] dataPtr; // pw01
+ } // dg05a
+ } // dg05a
+ // Data
+ TARGETING::TargetHandle_t chipHandle;
+ uint16_t address;
+ uint16_t dataByteLength;
+ uint8_t * dataPtr;
+
+ RegType registerType; // @jl04a
+
+ Data(const Data & d);
+ Data & operator=(const Data & d);
+ };
+
+// We should probably use a link list instead of a vector
+ typedef std::list<Data> DataContainerType;
+ typedef DataContainerType::iterator DataIterator;
+ typedef DataContainerType::const_iterator ConstDataIterator;
+
+ DataContainerType data;
+
+ /** Private function to facilitate the adding of caputre data to the
+ * internal vector */
+ void AddDataElement( TARGETING::TargetHandle_t i_trgt, int i_scomId,
+ const BitString * i_bs, Place i_place,
+ RegType i_type = PRIMARY );
+
+ // Predicate for deciding to delete an element of data from a Capture Data list.
+ class prdfCompareCaptureDataType : public std::unary_function<Data &, bool>
+ {
+ public:
+ prdfCompareCaptureDataType(RegType i_ctor_input) : __private_storage(i_ctor_input){};
+ bool operator() (Data &i)
+ {
+ return (i.registerType == __private_storage);
+ };
+
+
+ private:
+ //Private storage for value passed in.
+ RegType __private_storage;
+ //Constructor allows a value to be passed in to compare against.
+ };
+
+ // Predicate for deciding whether to delete an
+ // element of data from a Capture Data list.
+ class prdfCompareCaptureDataEntry :
+ public std::unary_function<Data &, bool>
+ {
+ public:
+ prdfCompareCaptureDataEntry(
+ TARGETING::TargetHandle_t chipHandle,
+ uint16_t address) :
+ __chipHandle(chipHandle),
+ __address(address) {};
+ bool operator() (Data &i)
+ {
+ return ((i.chipHandle == __chipHandle) &&
+ (i.address == __address));
+ };
+
+ private:
+ TARGETING::TargetHandle_t __chipHandle;
+ uint16_t __address;
+ };
+
+public:
+
+ /**
+ * @brief Merge scom register data from two captures
+ * @param i_cd secondary capture data to merge
+ */
+ void mergeData(CaptureData & i_cd);
+
+ /**
+ * @brief Get the Scom data pointer
+ * @return the Scom data pointer
+ */
+ DataContainerType * getData() { return &data; }
+
+
+
+};
+
+} // end namespace PRDF
+
+#endif
diff --git a/src/register/iipMopRegisterAccess.h b/src/register/iipMopRegisterAccess.h
new file mode 100755
index 0000000..1e7ad59
--- /dev/null
+++ b/src/register/iipMopRegisterAccess.h
@@ -0,0 +1,184 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/iipMopRegisterAccess.h $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef iipMopRegisterAccess_h
+#define iipMopRegisterAccess_h
+
+// Class Specification *************************************************
+//
+// Class name: MopRegisterAccess
+// Parent class: None.
+//
+// Summary: This class provides access to hardware register via
+// a MOP routine. A single pure virtual function Access()
+// is declared for this purpose.
+//
+// Cardinality: 0
+//
+// Performance/Implementation:
+// Space Complexity: Constant
+// Time Complexity: All member functions constant unless otherwise
+// stated.
+//
+// Usage Examples:
+//
+//
+// void foo(MopRegisterAccess & mra)
+// {
+// BitStringBuffer bitString(80); // 80 bits
+//
+// mra.Access(bitString, READ);
+// ...
+//
+// }
+//
+//
+// End Class Specification *********************************************
+
+// Includes
+#if !defined(IIPCONST_H)
+#include <iipconst.h>
+#endif
+#include <prdfPlatServices.H>
+
+namespace PRDF
+{
+// Forward References
+class BitString;
+
+class MopRegisterAccess
+{
+public:
+
+ enum Operation
+ {
+ READ = 0,
+ WRITE = 1
+ };
+
+ // MopRegisterAccess(void);
+ // Function Specification ********************************************
+ //
+ // Purpose: Initialization
+ // Parameters: None.
+ // Returns: No value returned.
+ // Requirements: None.
+ // Promises: All data members are initialized.
+ // Exceptions: None.
+ // Concurrency: N/A
+ // Notes: This constructor is not declared. This compiler generated
+ // default definition is sufficient.
+ //
+ // End Function Specification //////////////////////////////////////
+
+ // MopRegisterAccess(const MopRegisterAccess & scr);
+ // Function Specification ********************************************
+ //
+ // Purpose: Copy
+ // Parameters: scr: Reference to instance to copy
+ // Returns: No value returned.
+ // Requirements: None.
+ // Promises: All data members will be copied (Deep copy).
+ // Exceptions: None.
+ // Concurrency: N/A.
+ // Notes: This constructor is not declared. This compiler generated
+ // default definition is sufficient.
+ //
+ // End Function Specification ****************************************
+
+ virtual ~MopRegisterAccess() {}
+
+ // Function Specification ********************************************
+ //
+ // Purpose: Destruction
+ // Parameters: None.
+ // Returns: No value returned
+ // Requirements: None.
+ // Promises: None.
+ // Exceptions: None.
+ // Concurrency: N/A
+ //
+ // End Function Specification ****************************************
+
+ // MopRegisterAccess & operator=(const MopRegisterAccess & scr);
+ // Function Specification ********************************************
+ //
+ // Purpose: Assigment
+ // Parameters: d: Reference to instance to assign from
+ // Returns: Reference to this instance
+ // Requirements: None.
+ // Promises: All data members are assigned to
+ // Exceptions: None.
+ // Concurrency: N/A.
+ // Notes: This assingment operator is not declared. The compiler
+ // generated default definition is sufficient.
+ //
+ // End Function Specification ****************************************
+
+ virtual uint32_t Access(BitString & bs,
+ uint64_t registerId,
+ Operation operation) const = 0;
+ // Function Specification ********************************************
+ //
+ // Purpose: This function reads or writes the hardware according
+ // to the specified operation.
+ // Parameters: bs: Bit string to retrieve(for write) or store data
+ // (from read)
+ // registerId: SCR Address or scan offset
+ // operation: Indicates either read or write operation
+ // Returns: Hardware OPs return code
+ // Requirements: bs.Length() == long enough
+ // Promises: For read operation, bs is modified to reflect hardware
+ // register state
+ // Exceptions: None.
+ // Concurrency: Nonreentrant.
+ // Note: The first bs.Length() bits from the Hardware OPs read
+ // are set/reset in bs (from left to right)
+ // For a write, the first bs.Length() bits are written
+ // to the hardware register with right padded 0's if
+ // needed
+ //
+ // End Function Specification ****************************************
+ //Get Ids and count
+ virtual const TARGETING::TargetHandle_t * GetChipIds(int & count) const = 0;
+ // Function Specification ********************************************
+ //
+ // Purpose: Access Chip Ids and # of chips to access
+ // Parameters: count: Var to return chip count of valid IDs
+ // Returns: ptr to Chip ids
+ // Requirements: None
+ // Promises: None
+ // Exceptions: None.
+ // Concurrency: Reentrant.
+ //
+ // End Function Specification ****************************************
+
+ private:
+
+ };
+
+} // end namespace PRDF
+
+#endif
diff --git a/src/register/iipMopRegisterAccessScanComm.h b/src/register/iipMopRegisterAccessScanComm.h
new file mode 100755
index 0000000..e87d702
--- /dev/null
+++ b/src/register/iipMopRegisterAccessScanComm.h
@@ -0,0 +1,158 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.h $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 1996,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef iipMopRegisterAccessScanComm_h
+#define iipMopRegisterAccessScanComm_h
+
+// Class Specification *************************************************
+//
+// Class name: MopRegisterAccessScanComm
+// Parent class: MopRegisterAccess.
+//
+// Summary: This class provides access to hardware register data via
+// a MOP Scan Comm routine.
+//
+// Cardinality: 0
+//
+// Performance/Implementation:
+// Space Complexity: Constant
+// Time Complexity: All member functions constant unless otherwise
+// stated.
+//
+// Usage Examples:
+//
+//
+//
+// End Class Specification *********************************************
+
+// Includes
+
+#pragma interface
+
+#ifndef iipMopRegisterAccess_h
+#include <iipMopRegisterAccess.h>
+#endif
+
+namespace PRDF
+{
+
+// Forward References
+class MopRegisterAccessScanComm : public MopRegisterAccess
+{
+public:
+
+ // Function Specification ********************************************
+ //
+ // Purpose: CTOR
+ // Parameters: None
+ // Returns: No value returned.
+ // Requirements: None.
+ // Promises: All data members are initialized.
+ // Exceptions: None.
+ // Concurrency: N/A
+ // Note: Multiple chip IDs are for chips that MOPs must
+ // access at the same time when performing a Scan
+ // Comm operation (ie STINGER & ARROW chips)
+ //
+ // End Function Specification //////////////////////////////////////
+
+ // MopRegisterAccessScanComm(const MopRegisterAccessScanComm & scr);
+ // Function Specification ********************************************
+ //
+ // Purpose: Copy
+ // Parameters: scr: Reference to instance to copy
+ // Returns: No value returned.
+ // Requirements: None.
+ // Promises: All data members will be copied (Deep copy).
+ // Exceptions: None.
+ // Concurrency: N/A.
+ // Notes: This constructor is not declared. This compiler generated
+ // default definition is sufficient.
+ //
+ // End Function Specification ****************************************
+
+ // virtual ~MopRegisterAccessScanComm(void);
+ // Function Specification ********************************************
+ //
+ // Purpose: Destruction
+ // Parameters: None.
+ // Returns: No value returned
+ // Requirements: None.
+ // Promises: None.
+ // Exceptions: None.
+ // Concurrency: N/A
+ // Notes: This destructor is not declared. This compiler generated
+ // default definition is sufficient.
+ //
+ // End Function Specification ****************************************
+
+ // MopRegisterAccessScanComm & operator=(const MopRegisterAccessScanComm & scr);
+ // Function Specification ********************************************
+ //
+ // Purpose: Assigment
+ // Parameters: d: Reference to instance to assign from
+ // Returns: Reference to this instance
+ // Requirements: None.
+ // Promises: All data members are assigned to
+ // Exceptions: None.
+ // Concurrency: N/A.
+ // Notes: This assingment operator is not declared. The compiler
+ // generated default definition is sufficient.
+ //
+ // End Function Specification ****************************************
+
+ virtual uint32_t Access(BitString & bs,
+ uint32_t registerId,
+ Operation operation) const;
+ // Function Specification ********************************************
+ //
+ // Purpose: This function reads or writes the hardware according
+ // to the specified operation.
+ // Parameters: bs: Bit string to retrieve(for write) or store data
+ // (from read)
+ // registerId: ScanComm register address
+ // operation: Indicates either read or write operation
+ // Returns: Hardware OPs return code
+ // Requirements: bs.Length() == long enough
+ // Promises: For read operation, bs is modified to reflect hardware
+ // register state
+ // Exceptions: None.
+ // Concurrency: Nonreentrant.
+ // Note: The first bs.Length() bits from the Hardware OPs read
+ // are set/reset in bs (from left to right)
+ // For a write, the first bs.Length() bits are written
+ // to the hardware register with right padded 0's if
+ // needed
+ //
+ // End Function Specification ****************************************
+
+
+private: // DATA
+
+};
+
+} // end namespace PRDF
+
+#endif
diff --git a/src/register/iipMopRegisterAccessScanComm.inl b/src/register/iipMopRegisterAccessScanComm.inl
new file mode 100755
index 0000000..ad08084
--- /dev/null
+++ b/src/register/iipMopRegisterAccessScanComm.inl
@@ -0,0 +1,67 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.inl $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* COPYRIGHT International Business Machines Corp. 1996,2014 */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+// Module Description **************************************************
+//
+// Description: This module provides the inline implementation for the
+// PRD MOP Register Access Scan Comm class.
+//
+// End Module Description **********************************************
+
+namespace PRDF
+{
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// User Types
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Constants
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Macros
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Internal Function Prototypes
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Global Variables
+//----------------------------------------------------------------------
+
+//---------------------------------------------------------------------
+// Member Function Specifications
+//---------------------------------------------------------------------
+
+inline
+MopRegisterAccessScanComm::MopRegisterAccessScanComm(void)
+ {
+ }
+
+} // end namespace PRDF
diff --git a/src/register/iipscr.C b/src/register/iipscr.C
new file mode 100755
index 0000000..d4d7017
--- /dev/null
+++ b/src/register/iipscr.C
@@ -0,0 +1,274 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/iipscr.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 1997,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#define IIPSCR_C
+
+/* Module Description *************************************************/
+/* */
+/* Description: This module contains the implementation for the */
+/* Processor Runtime Diagnostics Scan Communication */
+/* Register class. */
+/* */
+/* Notes: Unless stated otherwise, assume that each function */
+/* specification has no side-effects, no dependencies, and */
+/* constant time complexity. */
+/* */
+/* End Module Description *********************************************/
+
+/*--------------------------------------------------------------------*/
+/* Includes */
+/*--------------------------------------------------------------------*/
+
+#include <iipbits.h>
+#include <iipscr.h>
+#include <iipconst.h>
+
+#include <prdfAssert.h>
+
+namespace PRDF
+{
+/*--------------------------------------------------------------------*/
+/* User Types */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Constants */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Macros */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Internal Function Prototypes */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Global Variables */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Static Variables */
+/*--------------------------------------------------------------------*/
+
+// Function Specification //////////////////////////////////////////
+//
+// Title: ~SCAN_COMM_REGISTER_CLASS (Virtual destructor)
+//
+// Purpose: This destructor deallocates the Bit String.
+//
+// Side-effects: Memory is deallocated.
+//
+// Dependencies: None.
+//
+// End Function Specification //////////////////////////////////////
+
+SCAN_COMM_REGISTER_CLASS::~SCAN_COMM_REGISTER_CLASS
+(
+ void
+ /*!i No parameters */
+ )
+/*!o No value returned */
+{
+}
+
+// Function Specification ///////////////////////////////////////////
+//
+// Title: Read
+//
+// Purpose: This function reads the actual hardware register and
+// sets the Bit String data member values. The specified
+// Bit String is then used to mask the Bit String data
+// member. If an error occur, then the error is reported
+// and the Bit String values are undefined.
+//
+// Side-effects: Hardware register is read.
+// Bit String data member is modified.
+// Memory is reallocated.
+//
+// End Function Specification //////////////////////////////////////
+
+uint32_t SCAN_COMM_REGISTER_CLASS::Read
+(
+ BitString & mask
+ /*!i Reference to Bit String mask */
+ )
+/*!o Error return code */
+{
+ uint32_t rc = Read();
+
+ if(rc == SUCCESS)
+ {
+ BitString & bitString = AccessBitString();
+ bitString.maskString(mask);
+ }
+
+ return(rc);
+}
+// Function Specification //////////////////////////////////////////
+//
+// Title: Set Bit
+//
+// Purpose: This function sets(1) the specified bit position in
+// the Bit String. If the Bit String is NULL, then a
+// new Bit String is allocated and cleared to all zero
+// before setting the bit.
+//
+// Side-effects: Bit String is modified.
+// Memory may be allocated.
+//
+// Dependencies: bit_position must be in the string
+//
+// End Function Specification //////////////////////////////////////
+
+void SCAN_COMM_REGISTER_CLASS::SetBit
+(
+ uint32_t bit_position
+ /*!i Bit position in string */
+ )
+/*!o No value returned */
+{
+
+ BitString & bitString = AccessBitString();
+ bitString.setBit(bit_position);
+}
+
+// Function Specification //////////////////////////////////////////
+//
+// Title: Clear Bit
+//
+// Purpose: This function clears(0) the specified bit position in
+// the Bit String. If the Bit String is NULL, then a
+// new Bit String is allocated and cleared to all zeros.
+//
+// Side-effects: Bit String is modified.
+// Memory may be allocated.
+//
+// Dependencies: bit_position must be in the string
+//
+// End Function Specification //////////////////////////////////////
+
+void SCAN_COMM_REGISTER_CLASS::ClearBit
+(
+ uint32_t bit_position
+ /*!i Bit position in string */
+ )
+/*!o No value returned */
+{
+ BitString & bitString = AccessBitString();
+ bitString.clearBit(bit_position);
+}
+
+
+
+// Function Specification ///////////////////////////////////////////
+//
+// Title: Clear Bit String
+//
+// Purpose: This function clears the Bit String. If the data
+// member is NULL, then a new Bit String is allocated.
+// Upon return, the state of the Bit String is all zero.
+//
+// Side-effects: Bit String data member is modified.
+// Memory is allocated or reallocated.
+//
+// End Function Specification //////////////////////////////////////
+
+void SCAN_COMM_REGISTER_CLASS::clearAllBits()
+{
+ BitString & bitString = AccessBitString();
+ bitString.clearAll();
+}
+
+void SCAN_COMM_REGISTER_CLASS::setAllBits()
+{
+ BitString & bitString = AccessBitString();
+ bitString.setAll();
+}
+
+//------------------------------------------------------------------------------
+
+uint64_t SCAN_COMM_REGISTER_CLASS::GetBitFieldJustified( uint32_t i_pos,
+ uint32_t i_len ) const
+{
+ uint64_t o_value = 0;
+
+ const uint32_t len_cpu_word = sizeof(CPU_WORD) * 8;
+ const uint32_t len_uint64 = sizeof(uint64_t) * 8;
+ const uint32_t pos_end = i_pos + i_len;
+
+ PRDF_ASSERT( pos_end <= len_uint64 );
+
+ const BitString * bs = GetBitString();
+
+ for ( uint32_t pos = i_pos; pos < pos_end; pos += len_cpu_word )
+ {
+ // Calculate chunk length.
+ uint32_t len_chunk = len_cpu_word;
+ if ( len_chunk > pos_end - pos )
+ len_chunk = pos_end - pos;
+
+ o_value <<= len_chunk; // Make room for new chunk.
+
+ // Get chunk.
+ o_value |= static_cast<uint64_t>(bs->getFieldJustify(pos, len_chunk));
+ }
+
+ return o_value;
+}
+
+//------------------------------------------------------------------------------
+
+void SCAN_COMM_REGISTER_CLASS::SetBitFieldJustified( uint32_t i_pos,
+ uint32_t i_len,
+ uint64_t i_value )
+{
+ const uint32_t len_cpu_word = sizeof(CPU_WORD) * 8;
+ const uint32_t len_uint64 = sizeof(uint64_t) * 8;
+
+ PRDF_ASSERT( i_pos + i_len <= len_uint64 );
+
+ BitString & bs = AccessBitString();
+
+ for ( uint32_t offset = 0; offset < i_len; offset += len_cpu_word )
+ {
+ // Calculate chunk length.
+ uint32_t len_chunk = len_cpu_word;
+ if ( len_chunk > i_len - offset )
+ len_chunk = i_len - offset;
+
+ uint64_t value = i_value;
+ value >>= i_len - (offset + len_chunk); // right justify
+
+ // Set chunk.
+ bs.setFieldJustify( i_pos + offset, len_chunk,
+ static_cast<CPU_WORD>(value) );
+ }
+}
+
+} // end namespace PRDF
+
+#undef IIPSCR_C
+
diff --git a/src/register/iipscr.h b/src/register/iipscr.h
new file mode 100755
index 0000000..53c9bfa
--- /dev/null
+++ b/src/register/iipscr.h
@@ -0,0 +1,431 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/iipscr.h $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef IIPSCR_H
+#define IIPSCR_H
+
+// Module Description **************************************************
+//
+// Description: This module contains the declarations for the
+// Processor Runtime Diagnostics Scan Communication
+// Register class.
+//
+// Notes: Unless stated otherwise, assume that each function
+// specification has no side-effects, no dependencies, and
+// constant time complexity.
+//
+// End Module Description **********************************************
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+
+#include <iipbits.h>
+#include <iipconst.h>
+#include <iipsdbug.h>
+#include <prdfMain.H>
+#include <prdfTrace.H>
+
+namespace PRDF
+{
+
+/*--------------------------------------------------------------------*/
+/* Forward References */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* User Types */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Constants */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Macros */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Global Variables */
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Function Prototypes */
+/*--------------------------------------------------------------------*/
+
+// Class Specification *************************************************
+//
+// Name: SCAN_COMM_REGISTER_CLASS
+//
+// Title: Scan Communication Register
+//
+// Purpose: SCAN_COMM_REGISTER_CLASS provides the representation
+// and access to a physical register.
+//
+// Usage: This is an abstract base class.
+//
+// Side-effects: Memory is allocated.
+//
+// Dependencies: None.
+//
+// Notes: The Scan Communication Register is a model of an actual
+// physical register. The bits in the register are represented by the
+// bit_string data member which is modified dynamically as operations
+// are preformed. It acts as a temporarily cached value of the
+// register. When a read is performed, the bit values are updated in
+// the bit string. When a write is performed, the current value of the
+// bits are used as the value to write. The current value of this
+// cached bit string can be accessed or modified by other objects via
+// the public interface. The physical address and bit length of the
+// hardware register are set during initialization and used on all
+// acceses.
+//
+// The basic Read() and Write() functions are virtual. The
+// actual implemenations are dependent on the actual hardware
+// and the software Hardware Manual Ops Scan Control Routines.
+// These function specifications describe a common behaviour
+// that every derived class must follow. Additional,
+// information may also be specified.
+//
+// A Read() function is also provided that has a Bit String
+// mask parameter. This function calls the virtual Read()
+// and then applies the mask so that the internal Bit String
+// contains the hardware register contents with certain bits
+// ignored (masked off).
+//
+// Cardinality: 0
+//
+// Space Complexity: Linear
+// K + Mn where K and M are constants and n is the
+// number of bits in the register.
+//
+// End Class Specification *********************************************
+/**
+ SCAN_COMM_REGISTER_CLASS
+ @author Doug Gilbert
+ @V5R2
+ */
+class SCAN_COMM_REGISTER_CLASS
+{
+ public: // enums, structs, typedefs
+
+ /** The register access level */
+ enum AccessLevel
+ {
+ ACCESS_NONE = 0x0, ///< No access
+ ACCESS_RO = 0x1, ///< Read-only access
+ ACCESS_WO = 0x2, ///< Write-only access
+ ACCESS_RW = 0x3, ///< Read/Write access
+ };
+
+ public: // functions
+
+ /**
+ Destructor
+ */
+ virtual ~SCAN_COMM_REGISTER_CLASS(void);
+
+ /**
+ Read hardware register (virtual)
+ <ul>
+ <br><b>Parameters: </b> None
+ <br><b>Returns: </b> [SUCCESS | MOPs return code]
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> Internal bit string represents the value of the
+ hardware register (if rc == SUCCESS)
+ <br><b>Sideaffects: </b> Value guaranteed to be read from hardware.
+ <br><b>Exceptions: </b> None.
+ <br><b>Notes: </b> Default is to call Read(). If a child class cannot
+ guarantee hardware access every time Read() is
+ called then the function ForceRead() should be
+ overridden.
+ </ul><br>
+ */
+ virtual uint32_t ForceRead(void) const { return Read(); }
+
+ /**
+ Read hardware register (pure virtual)
+ <ul>
+ <br><b>Parameters: </b> None
+ <br><b>Returns: </b> [SUCCESS | MOPs return code]
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> Internal bit string represents the value of the
+ hardware register (if rc == SUCCESS)
+ <br><b>Sideaffects: </b> The bit string value may or may not be retrieved
+ from hardware; a buffered copy may be used.
+ <br><b>Exceptions: </b> None.
+ </ul><br>
+ */
+ virtual uint32_t Read(void) const = 0;
+
+ /**
+ Read hardware register and apply a mask
+ <ul>
+ <br><b>Parameters: </b> Mask to apply
+ <br><b>Returns: </b> [SUCCESS | MOPs return code]
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> Internal bit string represents the value of the
+ hardware register with the bits turned off as
+ specified by the mask.
+ <br><b>Sideaffects: </b> The bit string value may or may not be retrieved
+ from hardware. a buffered copy may be used.
+ <br><b>Exceptions: </b> None.
+ <br><b>Notes: </b> if bits read from hardware = '00110100'
+ and mask = '01110000'
+ then internal bit sting = '00000100'
+
+ if mask.Length() < GetBitString()->Length()
+ then mask is right extended with 0's
+ if mask.Length() > GetBitString()->Length()
+ then extra mask bits are ignored.
+ </ul><br>
+ */
+ uint32_t Read(BitString & mask);
+
+ /**
+ Write hardware register (pure virtual)
+ <ul>
+ <br><b>Parameters: </b> None
+ <br><b>Returns: </b> [SUCCESS | MOPs return code]
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> Internal bit string value written to hardware
+ <br><b>Exceptions: </b> None.
+ <br><b>Notes: </b> If internal bitstring was never read/set/modified then
+ zeros are written to corresponding hardware register.
+ </ul><br>
+ */
+ virtual uint32_t Write(void) = 0;
+
+ /**
+ Access a copy of the scan comm address
+ <ul>
+ <br><b>Parameters: </b> None
+ <br><b>Returns: </b> Returns scom address
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> None.
+ <br><b>Exceptions: </b> None.
+ </ul><br>
+ */
+ virtual uint64_t GetAddress(void) const {return 0 ;}
+
+ /**
+ Access a copy of the short id for signatures.
+ <ul>
+ <br><b>Parameters: </b> None
+ <br><b>Returns: </b> ID.
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> None.
+ <br><b>Exceptions: </b> None.
+ </ul><br>
+ */
+ virtual uint16_t GetId(void) const = 0;
+
+ /**
+ Set the short id for signatures.
+ <ul>
+ <br><b>Parameters: </b> ID.
+ <br><b>Returns: </b> None.
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> None.
+ <br><b>Exceptions: </b> For virtual registers, this is not required to have
+ any effect.
+ </ul><br>
+ */
+ virtual void SetId(uint16_t) = 0;
+
+
+ /**
+ Access the bit length of the register
+ <ul>
+ <br><b>Parameters: </b> None
+ <br><b>Returns: </b> bit length of the register
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> None.
+ <br><b>Exceptions: </b> None.
+ </ul><br>
+ */
+ virtual uint32_t GetBitLength(void) const { return DEFAULT_BIT_LENGTH ;}
+
+ /**
+ Access the internal bit string (pure virtual)
+ <ul>
+ <br><b>Parameters: </b> None
+ <br><b>Returns: </b> ptr to the internal bit string (const)
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> None.
+ <br><b>Exceptions: </b> None.
+ <br><b>Notes: </b> If the internal bit string was never read/modified then
+ all bits are zero
+ </ul><br>
+ */
+ virtual
+ const BitString * GetBitString(ATTENTION_TYPE
+ i_type = INVALID_ATTENTION_TYPE
+ ) const = 0;
+
+ /**
+ Modify the internal bit string (pure virtual)
+ <ul>
+ <br><b>Parameters: </b> a bit string
+ <br><b>Returns: </b> Nothing
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> Internal bit string == *bs for first len bits where
+ len is the smaller of the two lengths.
+ Memory may be (re)allocated
+ <br><b>Exceptions: </b> None.
+ <br><b>Notes: </b> The hardware register value is not modified until
+ Write() is called
+ </ul><br>
+ */
+ virtual void SetBitString(const BitString * bs) = 0;
+
+ /**
+ SetBit
+ <ul>
+ <br><b>Parameters: </b> Position of bit to set (= 1)
+ <br><b>Returns: </b> None.
+ <br><b>Requirements:</b> bit position < GetBitString()->Length()
+ <br><b>Promises: </b> GetBitString()->isBitSet(bit_position) == true
+ <br><b>Exceptions: </b> None.
+ <br><b> Notes: </b> Register value is not reflected in hardware until
+ Write() is called
+ </ul><br>
+ */
+ void SetBit(uint32_t bit_position);
+
+ /**
+ ClearBit (reset bit)
+ <ul>
+ <br><b>Parameters: </b> Position of bit to clear (= 0)
+ <br><b>Returns: </b> None.
+ <br><b>Requirements:</b> bit position < GetBitString()->Length()
+ <br><b>Promises: </b> GetBitString()->isBitSet(bit_position) == false
+ <br><b>Exceptions: </b> None.
+ <br><b> Notes: </b> Register value is not reflected in hardware until
+ Write() is called
+ </ul><br>
+ */
+ void ClearBit(uint32_t bit_position);
+
+ /**
+ * @brief Will query if a bit is set.
+ * @param i_bitPos The bit position to query.
+ * @pre The bit position must be less than GetBitString()->Length()
+ * @return TRUE if the bit is set, FALSE otherwise.
+ */
+ bool IsBitSet( uint32_t i_bitPos )
+ { return GetBitString()->isBitSet(i_bitPos); }
+
+ /** @brief Flushes all bits to 0. */
+ void clearAllBits();
+
+ /** @brief Flushes all bits to 1. */
+ void setAllBits();
+
+ /**
+ * @brief Returns target value from the BitString (right justified).
+ * @param i_pos Starting position in the bit string.
+ * @param i_len Length of target value.
+ * @pre i_pos + i_len must be less than or equal 64 bits.
+ * @return The target value (right justified).
+ */
+ uint64_t GetBitFieldJustified( uint32_t i_pos, uint32_t i_len ) const;
+
+ /**
+ * @brief Set a field within the BitString with a value (right justified).
+ * @param i_pos Starting position in the bit string.
+ * @param i_len Length of target value.
+ * @param i_value Value to add to BitString.
+ * @pre i_pos + i_len must be less than or equal 64 bits.
+ */
+ void SetBitFieldJustified( uint32_t i_pos, uint32_t i_len,
+ uint64_t i_value );
+
+ /**
+ Query if bit string is all zeros
+ <ul>
+ <br><b>Parameters: </b> None.
+ <br><b>Returns: </b> [true | false]
+ <br><b>Requirements:</b> None.
+ <br><b>Promises: </b> None.
+ <br><b>Exceptions: </b> None.
+ </ul><br>
+ */
+ bool BitStringIsZero()
+ { return GetBitString()->isZero(); }
+
+ /**
+ *@brief Returns TYPE_NA as type of Target associated with register.Actual
+ * implementation is expected in derived class
+ *@return TYPE_NA
+ */
+ virtual TARGETING::TYPE getChipType(void)const { return TARGETING::TYPE_NA; }
+
+ /** @return The register access level (see enum AccessLevel). */
+ virtual AccessLevel getAccessLevel() const { return ACCESS_RW; }
+
+ /** @brief Sets the register access level (see enum AccessLevel). */
+ virtual void setAccessLevel( AccessLevel i_op ) {}
+
+protected:
+
+ /**
+ Get modifiable reference to internal bit string (don't even thing about making this public!!!)
+ <ul>
+ <br><b>Parameters: </b> None.
+ <br><b>Returns </b> Reference to the internal bit string
+ <br><b>Requirments </b> None.
+ <br><b>Promises </b> None.
+ </ul><br>
+ */
+ virtual BitString & AccessBitString(void) = 0;
+private: // Data
+ static const int DEFAULT_BIT_LENGTH = 64;
+
+ // Enum Specification //////////////////////////////////////////////
+ //
+ // Purpose: These enumerated constants specify implementation data.
+ //
+ // End Enum Specification //////////////////////////////////////////
+
+ enum
+ {
+ ODD_PARITY_SET_BIT_POSITION = 16
+ };
+
+ // Data Specification //////////////////////////////////////////////
+ //
+ // Purpose: These data members specify the physical properties of
+ // register.
+ //
+ // End Data Specification //////////////////////////////////////////
+
+
+};
+
+}//namespace PRDF
+
+#endif
diff --git a/src/register/prdfCaptureData.C b/src/register/prdfCaptureData.C
new file mode 100755
index 0000000..3911350
--- /dev/null
+++ b/src/register/prdfCaptureData.C
@@ -0,0 +1,403 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfCaptureData.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/**
+ @file prdfCaptureData.C
+ @brief Squadrons implementation of capture data
+*/
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+
+#include <iipbits.h>
+#include <prdfHomRegisterAccess.H> // dg06a
+#include <prdfScomRegister.H>
+#include <iipchip.h>
+#include <iipCaptureData.h>
+#include <string.h>
+#include <algorithm> // @jl04 a Add this for the Drop function.
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+//---------------------------------------------------------------------
+// Member Function Specifications
+//---------------------------------------------------------------------
+
+CaptureData::CaptureData(void):data()
+{
+// data.reserve(INITIAL_DATA_COUNT);
+}
+
+// dg05d CaptureData::~CaptureData(void)
+// dg05d {
+// dg05d if(!data.empty())
+// dg05d {
+// dg05d Clear();
+// dg05d }
+// dg05d }
+
+void CaptureData::Clear(void)
+{
+
+ if(!data.empty())
+ {
+// dg05d for(DataContainerType::iterator i = data.begin();i != data.end();i++)
+// dg05d {
+// dg05d delete [] (*i).dataPtr;
+// dg05d }
+
+ data.erase(data.begin(), data.end());
+
+ } /* if not empty */
+}
+
+//------------------------------------------------------------------------------
+
+void CaptureData::AddDataElement( TargetHandle_t i_trgt, int i_scomId,
+ const BitString * i_bs,
+ Place i_place, RegType i_type )
+{
+ // Initial values of the bit string buffer if i_bs has a zero value.
+ uint8_t * buf = nullptr;
+ size_t sz_buf = 0;
+
+ // Add buffer only if the value is non-zero.
+ if ( !i_bs->isZero() )
+ {
+ // Get the size of i_bs and ensure byte alignment.
+ sz_buf = (i_bs->getBitLen() + 8-1) / 8;
+
+ // Since we are using a BitString below, which does everything on a
+ // CPU_WORD boundary, we must make sure the buffer is CPU_WORD aligned.
+ const size_t sz_word = sizeof(CPU_WORD);
+ sz_buf = ((sz_buf + sz_word-1) / sz_word) * sz_word;
+
+ // Allocate memory for the buffer.
+ buf = new uint8_t[sz_buf];
+ memset( buf, 0x00, sz_buf );
+
+ // Use a BitString to copy i_bs to the buffer.
+ BitString bs ( i_bs->getBitLen(), (CPU_WORD *)buf );
+ bs.setString( *i_bs );
+
+ // Create the new data element.
+ Data element( i_trgt, i_scomId, sz_buf, buf );
+ element.registerType = i_type;
+
+ // Add the new element to the data.
+ if ( FRONT == i_place )
+ data.insert( data.begin(), element );
+ else
+ data.push_back( element );
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void CaptureData::Add( TargetHandle_t i_trgt, int32_t i_scomId,
+ SCAN_COMM_REGISTER_CLASS & io_scr,
+ Place i_place, RegType i_type )
+{
+ if ( SUCCESS == io_scr.Read() )
+ {
+ AddDataElement( i_trgt, i_scomId, io_scr.GetBitString(),
+ i_place, i_type );
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void CaptureData::Add( TargetHandle_t i_trgt, int i_scomId,
+ const BitString & i_bs, Place i_place )
+{
+ AddDataElement( i_trgt, i_scomId, &i_bs, i_place );
+}
+
+//------------------------------------------------------------------------------
+
+// start jl04a
+void CaptureData::Drop(RegType i_type)
+{
+ // Function below requires a predicate function above to Drop
+ // a data element from the capture data if it is
+ // defined as secondary data instead of primary data in the rule files.
+ // This predicate has to exist within the CaptureData Class because the
+ // class "Data" is defined within CaptureData class.
+ data.erase( std::remove_if(data.begin(),data.end(),
+ prdfCompareCaptureDataType(i_type)), data.end() );
+}
+// end jl04a
+
+//------------------------------------------------------------------------------
+
+template <class T>
+void __bufferAdd( uint8_t* & i_idx, T i_val )
+{
+ memcpy( i_idx, &i_val, sizeof(i_val) );
+ i_idx += sizeof(i_val);
+}
+
+bool __bufferFull( uint8_t * i_buf, size_t i_bufSize,
+ uint8_t * i_idx, size_t i_idxSize )
+{
+ if ( (i_buf + i_bufSize) < (i_idx + i_idxSize) )
+ {
+ PRDF_ERR( "[CaptureData::Copy] Buffer is full. Some data may have "
+ "been lost" );
+ return true;
+ }
+
+ return false;
+}
+
+/* CaptureData Format:
+ * capture data -> ( <chip header> <registers> )*
+ * chip header -> ( <chip id:32> <# registers:32> )
+ * registers -> ( <reg id:16> <reg byte len:16> <bytes>+ )
+ */
+uint32_t CaptureData::Copy( uint8_t * i_buffer, uint32_t i_bufferSize ) const
+{
+ TargetHandle_t curTrgt = nullptr;
+
+ uint32_t * regCntPtr = nullptr;
+
+ uint8_t * curIdx = i_buffer;
+
+ for ( auto & entry : data )
+ {
+ // We only need the target data when the target for this entry does not
+ // match the previous entry.
+ if ( entry.chipHandle != curTrgt )
+ {
+ // Ensure we have enough space for the entry header.
+ if ( __bufferFull( i_buffer, i_bufferSize, curIdx,
+ (sizeof(HUID) + sizeof(uint32_t)) ) )
+ {
+ break;
+ }
+
+ // Update current target.
+ curTrgt = entry.chipHandle;
+
+ // Add HUID to buffer.
+ __bufferAdd( curIdx, htonl(PlatServices::getHuid(curTrgt)) );
+
+ // Update the current count pointer.
+ regCntPtr = (uint32_t *)curIdx;
+
+ // Zero out the register count.
+ __bufferAdd( curIdx, htonl(0) );
+ }
+
+ // Go to next entry if the data byte length is 0.
+ if ( 0 == entry.dataByteLength )
+ continue;
+
+ // Ensure we have enough space for the entry header.
+ if ( __bufferFull( i_buffer, i_bufferSize, curIdx,
+ (2 * sizeof(uint16_t) + entry.dataByteLength) ) )
+ {
+ break;
+ }
+
+ // Write register ID.
+ __bufferAdd( curIdx, htons(entry.address) );
+
+ // Write data length.
+ __bufferAdd( curIdx, htons(entry.dataByteLength) );
+
+ // Write the data.
+ // >>> TODO: RTC 199045 The data should already be in network format.
+ // However, that is not the case. Instead, the data is
+ // converted here, which would be is fine if we were only
+ // adding registers, but we have additional capture data,
+ // especially in the memory subsytem, that are actually stored
+ // in the network format, but swizzled before adding to the
+ // capture data. Which means we are doing too much.
+ // Unfortunately, it currently works and will take some time
+ // to actually do it right. Therefore, we will leave this
+ // as-is and try to make the appropriate fix later.
+ uint32_t l_dataWritten = 0;
+ while ((l_dataWritten + 4) <= entry.dataByteLength)
+ {
+ uint32_t l_temp32;
+ memcpy(&l_temp32, &entry.dataPtr[l_dataWritten], sizeof(l_temp32));
+ l_temp32 = htonl(l_temp32);
+ memcpy(curIdx, &l_temp32, 4);
+ l_dataWritten += 4; curIdx += 4;
+ }
+ if (l_dataWritten != entry.dataByteLength)
+ {
+ // TODO: RTC 199045 This is actually pretty bad because it will read
+ // four bytes of memory, sizzle the four bytes, then write
+ // less than four bytes to the buffer. This could cause a
+ // buffer overrun exception if we were at the end of memory.
+ // Also, how can we trust the right most bytes to be correct
+ // since they technically should not be part of the entry
+ // data? Again, we don't seem to be hitting this bug and it
+ // will take time to fix it (see note above). Therefore, we
+ // will leave it for now and fix it when we have time.
+ uint32_t l_temp32;
+ memcpy(&l_temp32, &entry.dataPtr[l_dataWritten], sizeof(l_temp32));
+ l_temp32 = htonl(l_temp32);
+ memcpy(curIdx, &l_temp32, entry.dataByteLength - l_dataWritten);
+ curIdx += entry.dataByteLength - l_dataWritten;
+ }
+ // <<< TODO: RTC 199045
+
+ // Update entry count. It is important to update the buffer just in
+ // case we happen to run out of room in the buffer and need to exit
+ // early.
+ *regCntPtr = htonl( ntohl(*regCntPtr) + 1 );
+ }
+
+ return curIdx - i_buffer;
+}
+
+// dg08a -->
+CaptureData & CaptureData::operator=(const uint8_t *i_flatdata)
+{
+ uint32_t l_tmp32 = 0;
+ uint16_t l_tmp16 = 0;
+
+ HUID l_chipHuid = INVALID_HUID;
+ const size_t l_huidSize = sizeof(l_chipHuid);
+
+ // Read size.
+ memcpy(&l_tmp32, i_flatdata, sizeof(uint32_t));
+ uint32_t size = ntohl(l_tmp32);
+ i_flatdata += sizeof(uint32_t);
+
+ Clear();
+
+ // Calculate end of buffer.
+ const uint8_t *eptr = i_flatdata + size;
+
+ while(i_flatdata < eptr)
+ {
+ // Read chip Handle.
+ memcpy(&l_chipHuid , i_flatdata,l_huidSize );
+ i_flatdata += l_huidSize ;
+ TargetHandle_t l_pchipHandle =NULL;
+ l_chipHuid = ntohl(l_chipHuid);
+ l_pchipHandle = PlatServices::getTarget(l_chipHuid );
+ if(NULL ==l_pchipHandle)
+ {
+ continue;
+ }
+
+ // Read # of entries.
+ memcpy(&l_tmp32, i_flatdata, sizeof(uint32_t));
+ i_flatdata += sizeof(l_tmp32);
+ uint32_t entries = ntohl(l_tmp32);
+
+ // Input each entry.
+ for(uint32_t i = 0; i < entries; ++i)
+ {
+ // Read register id.
+ memcpy(&l_tmp16, i_flatdata, sizeof(uint16_t));
+ i_flatdata += sizeof(uint16_t);
+ int regid = ntohs(l_tmp16);
+
+ // Read byte count.
+ memcpy(&l_tmp16, i_flatdata, sizeof(uint16_t));
+ i_flatdata += sizeof(uint16_t);
+ uint32_t bytecount = ntohs(l_tmp16);
+
+ // Read data for register.
+ BitStringBuffer bs(bytecount * 8);
+ for(uint32_t bc = 0; bc < bytecount; ++bc)
+ {
+ bs.setFieldJustify(bc*8,8,(CPU_WORD)(*(i_flatdata+bc))); //mp01a
+ }
+ i_flatdata += bytecount;
+
+ // Add to capture data.
+ Add(l_pchipHandle, regid, bs);
+ }
+ }
+
+ return *this;
+}
+
+// <-- dg08a
+
+void CaptureData::mergeData(CaptureData & i_cd)
+{
+ DataContainerType l_data = *(i_cd.getData());
+
+ if( !l_data.empty() )
+ {
+ // Remove duplicate entries from secondary capture data
+ for (ConstDataIterator i = data.begin(); i != data.end(); i++)
+ {
+ l_data.remove_if(prdfCompareCaptureDataEntry(i->chipHandle,
+ i->address) );
+ }
+
+ // Add secondary capture data to primary one
+ data.insert( data.end(),
+ l_data.begin(),
+ l_data.end() );
+ }
+}
+
+
+// copy ctor for Data class
+CaptureData::Data::Data(const Data & d):
+chipHandle(d.chipHandle), address(d.address),
+dataByteLength(d.dataByteLength), dataPtr(NULL)
+{
+ if(d.dataPtr != NULL)
+ {
+ dataPtr = new uint8_t[dataByteLength];
+
+ memcpy(dataPtr, d.dataPtr, dataByteLength);
+ }
+}
+
+CaptureData::Data & CaptureData::Data::operator=(const Data & d)
+{
+ chipHandle = d.chipHandle;
+ address = d.address;
+ dataByteLength = d.dataByteLength;
+ if(dataPtr != NULL)
+ {
+ delete[]dataPtr;
+ dataPtr = NULL;
+ }
+ if(d.dataPtr != NULL)
+ {
+ dataPtr = new uint8_t[dataByteLength];
+ memcpy(dataPtr, d.dataPtr, dataByteLength);
+ }
+
+ return *this;
+}
+
+} // end of namespace PRDF
diff --git a/src/register/prdfHomRegisterAccess.C b/src/register/prdfHomRegisterAccess.C
new file mode 100755
index 0000000..a9d2a61
--- /dev/null
+++ b/src/register/prdfHomRegisterAccess.C
@@ -0,0 +1,226 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/**
+ @file prdfHomRegisterAccess.C
+ @brief definition of HomRegisterAccess
+*/
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#define prdfHomRegisterAccess_C
+
+#include <prdfHomRegisterAccess.H>
+#include <prdf_service_codes.H>
+#include <iipbits.h>
+#include <prdfMain.H>
+#include <prdfPlatServices.H>
+#include <prdfGlobal.H>
+#include <prdfErrlUtil.H>
+#include <prdfTrace.H>
+
+#ifdef __HOSTBOOT_RUNTIME
+#include <pm_common_ext.H>
+#include <p9_stop_api.H>
+#endif
+
+#undef prdfHomRegisterAccess_C
+
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+//----------------------------------------------------------------------
+// User Types
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Constants
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Macros
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Internal Function Prototypes
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Global Variables
+//----------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Member Function Specifications
+//------------------------------------------------------------------------------
+
+ScomService& getScomService()
+{
+ return PRDF_GET_SINGLETON(theScomService);
+}
+
+ScomService::ScomService() :
+ iv_ScomAccessor(NULL)
+{
+ PRDF_DTRAC("ScomService() initializing default iv_ScomAccessor");
+ iv_ScomAccessor = new ScomAccessor();
+}
+
+ScomService::~ScomService()
+{
+ if(NULL != iv_ScomAccessor)
+ {
+ PRDF_DTRAC("~ScomService() deleting iv_ScomAccessor");
+ delete iv_ScomAccessor;
+ iv_ScomAccessor = NULL;
+ }
+}
+
+void ScomService::setScomAccessor(ScomAccessor & i_ScomAccessor)
+{
+ PRDF_DTRAC("ScomService::setScomAccessor() setting new scom accessor");
+
+ if(NULL != iv_ScomAccessor)
+ {
+ PRDF_TRAC("ScomService::setScomAccessor() deleting old iv_ScomAccessor");
+ delete iv_ScomAccessor;
+ iv_ScomAccessor = NULL;
+ }
+
+ iv_ScomAccessor = &i_ScomAccessor;
+}
+
+uint32_t ScomService::Access(TargetHandle_t i_target,
+ BitString & bs,
+ uint64_t registerId,
+ MopRegisterAccess::Operation operation) const
+{
+ PRDF_DENTER("ScomService::Access()");
+ uint32_t rc = SUCCESS;
+
+ rc = iv_ScomAccessor->Access( i_target,
+ bs,
+ registerId,
+ operation);
+
+ PRDF_DEXIT("ScomService::Access(): rc=%d", rc);
+
+ return rc;
+}
+
+
+uint32_t ScomAccessor::Access(TargetHandle_t i_target,
+ BitString & bs,
+ uint64_t registerId,
+ MopRegisterAccess::Operation operation) const
+{
+ PRDF_DENTER("ScomAccessor::Access()");
+
+ uint32_t rc = SUCCESS;
+
+ if(i_target != NULL)
+ {
+ switch (operation)
+ {
+ case MopRegisterAccess::WRITE:
+ {
+ rc = PRDF::PlatServices::putScom(i_target, bs, registerId);
+
+ #ifdef __HOSTBOOT_RUNTIME
+ using namespace stopImageSection;
+
+ // Update CORE/EQ/EX Fir masks in HCODE image
+ TARGETING::TYPE type = PlatServices::getTargetType(i_target);
+ if( TYPE_EX == type || TYPE_EQ == type || TYPE_CORE == type )
+ {
+ uint32_t l_MaskReg[7] = {
+ 0x2004000f, // EC_LFIR_MASK_OR
+ 0x20010a45, // EC_COREFIR_MASK_OR
+ 0x1004000f, // EQ_LOCAL_FIR_MASK_OR
+ 0x10010805, // EX_L2FIR_MASK_OR
+ 0x10011005, // EX_NCUFIR_MASK_OR
+ 0x10011805, // EX_L3FIR_MASK_OR
+ 0x10012005 }; // EX_CMEFIR_MASK_OR
+
+ for(uint32_t l_count = 0; l_count < 7; l_count++)
+ {
+ if( l_MaskReg[l_count] == registerId )
+ {
+ errlHndl_t err = nullptr;
+ uint32_t sec = (TYPE_CORE == type) ?
+ P9_STOP_SECTION_CORE_SCOM :
+ P9_STOP_SECTION_EQ_SCOM;
+
+ uint64_t scomVal =
+ (((uint64_t)bs.getFieldJustify(0, 32)) << 32) |
+ ((uint64_t)bs.getFieldJustify(32, 32));
+
+ err = RTPM::hcode_update(sec,
+ P9_STOP_SCOM_OR_APPEND,
+ i_target,
+ registerId,
+ scomVal);
+ if( nullptr != err)
+ {
+ PRDF_ERR("[ScomAccessor::Access()] Error in"
+ " hcode_update");
+ PRDF_COMMIT_ERRL( err, ERRL_ACTION_REPORT );
+ }
+ break;
+ }
+ }
+ }
+ #endif
+ break;
+ }
+
+ case MopRegisterAccess::READ:
+ bs.clearAll(); // clear all bits
+
+ rc = PRDF::PlatServices::getScom(i_target, bs, registerId);
+
+ break;
+
+ default:
+ PRDF_ERR("ScomAccessor::Access() unsuppported scom op: 0x%08X",
+ operation);
+ break;
+
+ } // end switch operation
+
+ }
+ else // Invalid target
+ {
+ rc = PRD_SCANCOM_FAILURE;
+ }
+
+ PRDF_DEXIT("ScomAccessor::Access()");
+
+ return rc;
+}
+
+} // End namespace PRDF
diff --git a/src/register/prdfHomRegisterAccess.H b/src/register/prdfHomRegisterAccess.H
new file mode 100755
index 0000000..6426b4a
--- /dev/null
+++ b/src/register/prdfHomRegisterAccess.H
@@ -0,0 +1,159 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef PRDFHOMREGISTERACCESS_H
+#define PRDFHOMREGISTERACCESS_H
+/**
+ @file prdfHomRegisterAccess.H
+ @brief Provide access to scan & scan com registers via the HOM
+*/
+
+
+//--------------------------------------------------------------------
+// Includes
+//--------------------------------------------------------------------
+
+#include <iipMopRegisterAccess.h>
+#include <vector>
+#include <prdfPlatServices.H>
+#include <prdfErrlUtil.H>
+#include <prdfGlobal.H>
+//--------------------------------------------------------------------
+// Forward References
+//--------------------------------------------------------------------
+
+namespace PRDF
+{
+
+class ScomAccessor
+{
+ public:
+
+ /**
+ * @brief ctor
+ */
+ inline ScomAccessor() {}
+
+ /**
+ * @brief dtor
+ */
+ inline virtual ~ScomAccessor() {}
+
+ /**
+ * @brief Access the scan com register
+ * @param i_target Target to access the register
+ * @param bs holds data read or to write
+ * @param registerId register address
+ * @param operation [READ|WRITE]
+ * @returns SUCCESS or PRD_SCANCOM_FAILURE
+ * @pre bs.Length() must be size of register data to read/write
+ * @post For read operation, bs is modified to reflect hardware
+ * register state
+ */
+ virtual uint32_t Access( TARGETING::TargetHandle_t i_target,
+ BitString & bs,
+ uint64_t registerId,
+ MopRegisterAccess::Operation operation) const;
+
+ private:
+
+ /**
+ * @brief disable copy
+ */
+ ScomAccessor(const ScomAccessor &);
+
+ /**
+ * @brief disable assignment
+ */
+ ScomAccessor & operator=(const ScomAccessor &);
+
+};
+
+/**
+ * @brief Singleton to access the only ScomService
+ */
+class ScomService;
+PRDF_DECLARE_SINGLETON(ScomService, theScomService);
+
+/**
+ * @brief Returns a reference to the ScomService singleton
+ *
+ * @return Reference to the ScomService
+ */
+ScomService& getScomService();
+
+/**
+ * @brief ScomService class
+ */
+class ScomService
+{
+ public:
+
+ /**
+ * @brief Construct ScomService
+ */
+ ScomService();
+
+ /**
+ * @brief Destroys ScomService
+ */
+ ~ScomService();
+
+ /**
+ * @brief set the scom accessor to be used
+ *
+ * @param[in] i_ScomAccessor new scom accessor
+ */
+ void setScomAccessor(ScomAccessor & i_ScomAccessor);
+
+ /**
+ Access the scan com register
+ @param i_target Target to access the register
+ @param BitString - holds data read or to write
+ @param register address
+ @param [READ|WRITE]
+ @returns [SUCCESS|FAIL]
+ @pre bs.Length() must be size of register data to read/write
+ @post For read operation, bs is modified to reflect hardware register state
+ @note
+ */
+ virtual uint32_t Access(TARGETING::TargetHandle_t i_target,
+ BitString & bs,
+ uint64_t registerId,
+ MopRegisterAccess::Operation operation) const;
+
+ private:
+
+ // Disable copy constructor / assignment operator
+ ScomService(const ScomService& i_right);
+ ScomService& operator=(const ScomService& i_right);
+
+ // Scom access to actual HW or Sim
+ ScomAccessor * iv_ScomAccessor;
+};
+
+} // End namespace PRDF
+
+#endif /* PRDFHOMREGISTERACCESS_H */
diff --git a/src/register/prdfOperatorRegister.H b/src/register/prdfOperatorRegister.H
new file mode 100755
index 0000000..00f39fd
--- /dev/null
+++ b/src/register/prdfOperatorRegister.H
@@ -0,0 +1,698 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __PRDFOPERATORREGISTER_H
+#define __PRDFOPERATORREGISTER_H
+
+#include <algorithm>
+
+#include <iipscr.h>
+#include <prdrCommon.H>
+
+namespace PRDF
+{
+
+class NotRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+ NotRegister() :
+ SCAN_COMM_REGISTER_CLASS( ), iv_child(NULL), iv_iBS(0)
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ NotRegister(SCAN_COMM_REGISTER_CLASS & i_arg) :
+ SCAN_COMM_REGISTER_CLASS( ), iv_child(&i_arg),
+ iv_iBS(i_arg.GetBitLength())
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ NotRegister & operator=(const NotRegister & r)
+ {
+ iv_child = r.iv_child;
+ iv_iBS = r.iv_iBS;
+ //iv_bs = r.iv_bs; <-- don't do this!
+ return *this;
+ }
+
+ virtual uint32_t Read() const { return iv_child->Read(); }
+ virtual uint32_t Write() { return iv_child->Write(); }
+
+ const BitString * GetBitString(
+ ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+ {
+ (*iv_bs) = ~(*iv_child->GetBitString(i_type));
+ return iv_bs;
+ }
+
+ virtual uint16_t GetId() const { return iv_child->GetId(); }
+ virtual void SetId(uint16_t i_id) {}
+
+ bool operator==(const NotRegister & r) const
+ { return r.iv_child == iv_child; }
+
+ bool operator<(const NotRegister & r) const
+ { return iv_child < r.iv_child; }
+
+ bool operator>=(const NotRegister & r) const
+ { return iv_child >= r.iv_child; }
+
+ protected:
+ BitString & AccessBitString(void) { return iv_iBS; }
+ void SetBitString(const BitString *) {}
+
+ private:
+ SCAN_COMM_REGISTER_CLASS * iv_child;
+
+ BitStringBuffer * iv_bs;
+ BitStringBuffer iv_iBS;
+};
+
+class SummaryRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+ SummaryRegister() :
+ SCAN_COMM_REGISTER_CLASS( ), iv_child(NULL), iv_amount(0), iv_iBS(0)
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ SummaryRegister(SCAN_COMM_REGISTER_CLASS & i_arg, uint16_t i_amount) :
+ SCAN_COMM_REGISTER_CLASS( ), iv_child(&i_arg), iv_amount(i_amount),
+ iv_iBS(i_arg.GetBitLength())
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ SummaryRegister & operator=(const SummaryRegister & r)
+ {
+ iv_child = r.iv_child;
+ iv_amount = r.iv_amount;
+ iv_iBS = r.iv_iBS;
+ //iv_bs = r.iv_bs; <-- don't do this!
+ return *this;
+ }
+
+ virtual uint32_t Read() const
+ {
+ uint32_t rc = iv_child->Read();
+ if ( PRD_SCANCOM_FAILURE == rc )
+ {
+ // This is a bit unusual, but we are going to ignore SCOM failures.
+ // This takes care of a corner case where one of the summary
+ // registers in the list returns an error, but there is another
+ // summary register with an active attention, which would be ignored
+ // if we return a bad rc.
+ PRDF_INF( "[SummaryRegister::read] SCOM failure on register ID "
+ "0x%04x, ignoring error", iv_child->GetId() );
+ rc = SUCCESS;
+ iv_child->clearAllBits(); // just in case
+ }
+ return rc;
+ }
+
+ virtual uint32_t Write() { return iv_child->Write(); }
+
+ const BitString * GetBitString(
+ ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+ {
+ iv_bs->clearAll();
+
+ PRDF::BitString tmp = *iv_child->GetBitString(i_type);
+
+ //if any bits are set in iv_child, then set the iv_amount bit
+ if (0 != tmp.getSetCount())
+ {
+ iv_bs->setBit(0);
+ *iv_bs = *iv_bs >> iv_amount;
+ }
+ return iv_bs;
+ }
+
+ virtual uint16_t GetId() const { return iv_child->GetId(); }
+ virtual void SetId(uint16_t i_id) {}
+
+ bool operator==(const SummaryRegister & r) const
+ { return (r.iv_child == iv_child) && (r.iv_amount == iv_amount); }
+
+ bool operator<(const SummaryRegister & r) const
+ {
+ if (iv_child == r.iv_child)
+ return iv_amount < r.iv_amount;
+ return iv_child < r.iv_child;
+ }
+
+ bool operator>=(const SummaryRegister & r) const
+ {
+ if (iv_child == r.iv_child)
+ return iv_amount >= r.iv_amount;
+ return iv_child >= r.iv_child;
+ }
+
+ protected:
+ BitString & AccessBitString(void) { return iv_iBS; }
+ void SetBitString(const BitString *) {}
+
+ private:
+ SCAN_COMM_REGISTER_CLASS * iv_child;
+ uint16_t iv_amount;
+
+ BitStringBuffer * iv_bs;
+ BitStringBuffer iv_iBS;
+};
+
+class LeftShiftRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+ LeftShiftRegister() :
+ SCAN_COMM_REGISTER_CLASS( ), iv_child(NULL), iv_amount(0), iv_iBS(0)
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ LeftShiftRegister(SCAN_COMM_REGISTER_CLASS & i_arg, uint16_t i_amount) :
+ SCAN_COMM_REGISTER_CLASS( ), iv_child(&i_arg), iv_amount(i_amount),
+ iv_iBS(i_arg.GetBitLength())
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ LeftShiftRegister & operator=(const LeftShiftRegister & r)
+ {
+ iv_child = r.iv_child;
+ iv_amount = r.iv_amount;
+ iv_iBS = r.iv_iBS;
+ //iv_bs = r.iv_bs; <-- don't do this!
+ return *this;
+ }
+
+ virtual uint32_t Read() const { return iv_child->Read(); }
+ virtual uint32_t Write() { return iv_child->Write(); }
+
+ const BitString * GetBitString(
+ ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+ {
+ (*iv_bs) = (*iv_child->GetBitString(i_type)) << iv_amount;
+ return iv_bs;
+ }
+
+ virtual uint16_t GetId() const { return iv_child->GetId(); }
+ virtual void SetId(uint16_t i_id) {}
+
+ bool operator==(const LeftShiftRegister & r) const
+ { return (r.iv_child == iv_child) && (r.iv_amount == iv_amount); }
+
+ bool operator<(const LeftShiftRegister & r) const
+ {
+ if (iv_child == r.iv_child)
+ return iv_amount < r.iv_amount;
+ return iv_child < r.iv_child;
+ }
+
+ bool operator>=(const LeftShiftRegister & r) const
+ {
+ if (iv_child == r.iv_child)
+ return iv_amount >= r.iv_amount;
+ return iv_child >= r.iv_child;
+ }
+
+ protected:
+ BitString & AccessBitString(void) { return iv_iBS; }
+ void SetBitString(const BitString *) {}
+
+ private:
+ SCAN_COMM_REGISTER_CLASS * iv_child;
+ uint16_t iv_amount;
+
+ BitStringBuffer * iv_bs;
+ BitStringBuffer iv_iBS;
+};
+
+class RightShiftRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+ RightShiftRegister() :
+ SCAN_COMM_REGISTER_CLASS( ), iv_child(NULL), iv_amount(0), iv_iBS(0)
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ RightShiftRegister(SCAN_COMM_REGISTER_CLASS & i_arg, uint16_t i_amount) :
+ SCAN_COMM_REGISTER_CLASS( ), iv_child(&i_arg), iv_amount(i_amount),
+ iv_iBS(i_arg.GetBitLength())
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ RightShiftRegister & operator=(const RightShiftRegister & r)
+ {
+ iv_child = r.iv_child;
+ iv_amount = r.iv_amount;
+ iv_iBS = r.iv_iBS;
+ //iv_bs = r.iv_bs; <-- don't do this!
+ return *this;
+ }
+
+ virtual uint32_t Read() const { return iv_child->Read(); }
+ virtual uint32_t Write() { return iv_child->Write(); }
+
+ const BitString * GetBitString(
+ ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+ {
+ (*iv_bs) = (*iv_child->GetBitString(i_type)) >> iv_amount;
+ return iv_bs;
+ }
+
+ virtual uint16_t GetId() const { return iv_child->GetId(); }
+ virtual void SetId(uint16_t i_id) {}
+
+ bool operator==(const RightShiftRegister & r) const
+ { return (r.iv_child == iv_child) && (r.iv_amount == iv_amount); }
+
+ bool operator<(const RightShiftRegister & r) const
+ {
+ if (iv_child == r.iv_child)
+ return iv_amount < r.iv_amount;
+ return iv_child < r.iv_child;
+ }
+
+ bool operator>=(const RightShiftRegister & r) const
+ {
+ if (iv_child == r.iv_child)
+ return iv_amount >= r.iv_amount;
+ return iv_child >= r.iv_child;
+ }
+
+ protected:
+ BitString & AccessBitString(void) { return iv_iBS; }
+ void SetBitString(const BitString *) {}
+
+ private:
+ SCAN_COMM_REGISTER_CLASS * iv_child;
+ uint16_t iv_amount;
+
+ BitStringBuffer * iv_bs;
+ BitStringBuffer iv_iBS;
+};
+
+
+class AndRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+ AndRegister() :
+ SCAN_COMM_REGISTER_CLASS( ), iv_left(NULL), iv_right(NULL), iv_iBS(0)
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ AndRegister( SCAN_COMM_REGISTER_CLASS & i_left,
+ SCAN_COMM_REGISTER_CLASS & i_right ) :
+ SCAN_COMM_REGISTER_CLASS( ), iv_left(&i_left), iv_right(&i_right),
+ iv_iBS(std::min(i_left.GetBitLength(),
+ i_right.GetBitLength()))
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ AndRegister & operator=(const AndRegister & r)
+ {
+ iv_left = r.iv_left;
+ iv_right = r.iv_right;
+ iv_iBS = r.iv_iBS;
+ //iv_bs = r.iv_bs; <-- don't do this!
+ return *this;
+ }
+
+ virtual uint32_t Read() const
+ {
+ return iv_left->Read() | iv_right->Read();
+ }
+ virtual uint32_t Write()
+ {
+ return iv_left->Write() | iv_right->Write();
+ }
+
+ const BitString * GetBitString(
+ ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+ {
+ (*iv_bs) = *iv_left->GetBitString(i_type);
+ (*iv_bs) = (*iv_bs) & (*iv_right->GetBitString(i_type));
+ return iv_bs;
+ }
+
+ virtual uint16_t GetId() const
+ {
+ return Prdr::SignatureOp::combineSig(iv_left->GetId(),
+ iv_right->GetId());
+ }
+
+ virtual void SetId(uint16_t i_id) {}
+
+ bool operator==(const AndRegister & r) const
+ { return (r.iv_left == iv_left) && (r.iv_right == iv_right); }
+
+ bool operator<(const AndRegister & r) const
+ {
+ if (iv_left == r.iv_left)
+ return iv_right < r.iv_right;
+ return iv_left < r.iv_left;
+ }
+
+ bool operator>=(const AndRegister & r) const
+ {
+ if (iv_left == r.iv_left)
+ return iv_right >= r.iv_right;
+ return iv_left >= r.iv_left;
+ }
+
+ protected:
+ BitString & AccessBitString(void) { return iv_iBS; }
+ void SetBitString(const BitString *) {}
+
+ private:
+ SCAN_COMM_REGISTER_CLASS * iv_left;
+ SCAN_COMM_REGISTER_CLASS * iv_right;
+
+ BitStringBuffer * iv_bs;
+ BitStringBuffer iv_iBS;
+};
+
+class OrRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+
+ OrRegister() :
+ SCAN_COMM_REGISTER_CLASS( ), iv_left(NULL), iv_right(NULL), iv_iBS(0)
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ OrRegister( SCAN_COMM_REGISTER_CLASS & i_left,
+ SCAN_COMM_REGISTER_CLASS & i_right ) :
+ SCAN_COMM_REGISTER_CLASS( ), iv_left(&i_left), iv_right(&i_right),
+ iv_iBS(std::min(i_left.GetBitLength(),
+ i_right.GetBitLength()))
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ OrRegister & operator=(const OrRegister & r)
+ {
+ iv_left = r.iv_left;
+ iv_right = r.iv_right;
+ iv_iBS = r.iv_iBS;
+ //iv_bs = r.iv_bs; <-- don't do this!
+ return *this;
+ }
+
+ virtual uint32_t Read() const
+ {
+ return iv_left->Read() | iv_right->Read();
+ }
+
+ virtual uint32_t Write()
+ {
+ return iv_left->Write() | iv_right->Write();
+ }
+
+ const BitString * GetBitString(
+ ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE ) const
+ {
+ (*iv_bs) = *iv_left->GetBitString(i_type);
+ (*iv_bs) = (*iv_bs) | (*iv_right->GetBitString(i_type));
+ return iv_bs;
+ }
+
+ virtual uint16_t GetId() const
+ {
+ return Prdr::SignatureOp::combineSig( iv_left->GetId(),
+ iv_right->GetId() );
+ }
+
+ virtual void SetId(uint16_t i_id) {}
+
+ bool operator==(const OrRegister & r) const
+ { return (r.iv_left == iv_left) && (r.iv_right == iv_right); }
+
+ bool operator<(const OrRegister & r) const
+ {
+ if (iv_left == r.iv_left)
+ return iv_right < r.iv_right;
+ return iv_left < r.iv_left;
+ }
+
+ bool operator>=(const OrRegister & r) const
+ {
+ if (iv_left == r.iv_left)
+ return iv_right >= r.iv_right;
+ return iv_left >= r.iv_left;
+ }
+
+ protected:
+ BitString & AccessBitString(void) { return iv_iBS; }
+ void SetBitString(const BitString *) {}
+
+ private:
+ SCAN_COMM_REGISTER_CLASS * iv_left;
+ SCAN_COMM_REGISTER_CLASS * iv_right;
+
+ BitStringBuffer * iv_bs;
+ BitStringBuffer iv_iBS;
+};
+
+class NullRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+ NullRegister(int size) :
+ SCAN_COMM_REGISTER_CLASS( ), iv_iBS(size)
+ {}
+
+ NullRegister & operator=(const NullRegister & r)
+ {
+ iv_iBS = r.iv_iBS;
+ return *this;
+ }
+
+ virtual uint32_t Read() const { return 0; }
+ virtual uint32_t Write() { return 0; }
+
+ const BitString * GetBitString(
+ ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+ {
+ return &iv_iBS;
+ }
+
+ protected:
+ BitString & AccessBitString(void) { return iv_iBS; }
+ void SetBitString(const BitString *) {}
+
+ private:
+ BitStringBuffer iv_iBS;
+
+ virtual uint16_t GetId() const
+ { return Prdr::SignatureOp::DEFAULT_SIGNATURE; }
+
+ virtual void SetId(uint16_t i_id) {}
+
+};
+
+class AttnTypeRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+ AttnTypeRegister() :
+ SCAN_COMM_REGISTER_CLASS( ), iv_check(&cv_null), iv_recov(&cv_null),
+ iv_special(&cv_null), iv_proccs(&cv_null), iv_hostattn(&cv_null),
+ iv_iBS(0)
+ {
+ iv_bs = &iv_iBS;
+ }
+
+ AttnTypeRegister( SCAN_COMM_REGISTER_CLASS *i_check,
+ SCAN_COMM_REGISTER_CLASS *i_recov,
+ SCAN_COMM_REGISTER_CLASS *i_special,
+ SCAN_COMM_REGISTER_CLASS *i_proccs,
+ SCAN_COMM_REGISTER_CLASS *i_hostattn ) :
+ SCAN_COMM_REGISTER_CLASS( ),
+ iv_check( NULL == i_check ? &cv_null : i_check),
+ iv_recov( NULL == i_recov ? &cv_null : i_recov),
+ iv_special( NULL == i_special ? &cv_null : i_special),
+ iv_proccs( NULL == i_proccs ? &cv_null : i_proccs),
+ iv_hostattn( NULL == i_hostattn ? &cv_null : i_hostattn),
+ iv_iBS(0) // will fully initialize this inside ctor.
+ {
+ uint32_t l_length = 1024;
+ l_length = std::min(l_length, iv_check->GetBitLength());
+ l_length = std::min(l_length, iv_recov->GetBitLength());
+ l_length = std::min(l_length, iv_special->GetBitLength());
+ l_length = std::min(l_length, iv_proccs->GetBitLength());
+ l_length = std::min(l_length, iv_hostattn->GetBitLength());
+ iv_iBS = BitStringBuffer(l_length);
+ iv_bs = &iv_iBS;
+ }
+
+ AttnTypeRegister & operator=(const AttnTypeRegister & r)
+ {
+ //iv_null = r.iv_null; <-- don't do this!
+ iv_check = (r.iv_check == &r.cv_null ? &cv_null : r.iv_check);
+ iv_recov = (r.iv_recov == &r.cv_null ? &cv_null : r.iv_recov);
+ iv_special = (r.iv_special == &r.cv_null ? &cv_null : r.iv_special);
+ iv_proccs = (r.iv_proccs == &r.cv_null ? &cv_null : r.iv_proccs);
+ iv_hostattn = (r.iv_hostattn == &r.cv_null ? &cv_null : r.iv_hostattn);
+ iv_iBS = r.iv_iBS;
+ //iv_bs = r.iv_bs; <-- don't do this!
+ return *this;
+ }
+
+ virtual uint32_t Read() const
+ {
+ return iv_check->Read() | iv_recov->Read() |
+ iv_special->Read() | iv_proccs->Read() |
+ iv_hostattn->Read();
+ }
+
+ virtual uint32_t Write()
+ {
+ return iv_check->Write() | iv_recov->Write() |
+ iv_special->Write() | iv_proccs->Write() |
+ iv_hostattn->Write();
+ }
+
+ const BitString * GetBitString(
+ ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+ {
+ switch (i_type)
+ {
+ case CHECK_STOP:
+ (*iv_bs) = BitStringBuffer(
+ *iv_check->GetBitString(i_type));
+ break;
+
+ case RECOVERABLE:
+ (*iv_bs) = BitStringBuffer(
+ *iv_recov->GetBitString(i_type));
+ break;
+
+ case SPECIAL:
+ (*iv_bs) = BitStringBuffer(
+ *iv_special->GetBitString(i_type));
+ break;
+
+ case PROC_CS:
+ (*iv_bs) = BitStringBuffer(
+ *iv_proccs->GetBitString(i_type));
+ break;
+
+ case HOST_ATTN:
+ (*iv_bs) = BitStringBuffer(
+ *iv_hostattn->GetBitString(i_type));
+ break;
+ }
+
+ return iv_bs;
+ }
+
+ virtual uint16_t GetId() const
+ {
+ uint16_t l_rc = Prdr::SignatureOp::DEFAULT_SIGNATURE;
+ l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_check->GetId());
+ l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_recov->GetId());
+ l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_special->GetId());
+ l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_proccs->GetId());
+ l_rc = Prdr::SignatureOp::combineSig(l_rc, iv_hostattn->GetId());
+ return l_rc;
+ }
+
+ virtual void SetId(uint16_t i_id) {}
+
+ bool operator==(const AttnTypeRegister & r) const
+ {
+ return (r.iv_check == iv_check) && (r.iv_recov == iv_recov) &&
+ (r.iv_special == iv_special) && (r.iv_proccs == iv_proccs) &&
+ (r.iv_special == iv_hostattn);
+ }
+
+ protected:
+ BitString & AccessBitString(void) { return iv_iBS; }
+ void SetBitString(const BitString *) {}
+
+ private:
+ static NullRegister cv_null;
+
+ SCAN_COMM_REGISTER_CLASS * iv_check;
+ SCAN_COMM_REGISTER_CLASS * iv_recov;
+ SCAN_COMM_REGISTER_CLASS * iv_special;
+ SCAN_COMM_REGISTER_CLASS * iv_proccs;
+ SCAN_COMM_REGISTER_CLASS * iv_hostattn;
+
+ BitStringBuffer * iv_bs;
+ BitStringBuffer iv_iBS;
+};
+
+class ConstantRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+ ConstantRegister() :
+ SCAN_COMM_REGISTER_CLASS( ), iv_iBS(0)
+ {}
+
+ ConstantRegister( const BitStringBuffer & i_arg ) :
+ SCAN_COMM_REGISTER_CLASS( ), iv_iBS(i_arg)
+ {}
+
+ ConstantRegister & operator=(const ConstantRegister & r)
+ {
+ iv_iBS = r.iv_iBS;
+ return *this;
+ }
+
+ virtual uint32_t Read() const { return SUCCESS; }
+ virtual uint32_t Write() { return SUCCESS; }
+
+ const BitString * GetBitString(
+ ATTENTION_TYPE i_type = INVALID_ATTENTION_TYPE) const
+ {
+ return &iv_iBS;
+ }
+
+ virtual uint16_t GetId() const
+ { return Prdr::SignatureOp::DEFAULT_SIGNATURE; }
+
+ virtual void SetId(uint16_t i_id) {}
+
+ bool operator==(const ConstantRegister & r) const
+ { return r.iv_iBS == iv_iBS; }
+
+ protected:
+ BitString & AccessBitString(void) { return iv_iBS; }
+ void SetBitString(const BitString *) {}
+
+ private:
+ BitStringBuffer iv_iBS;
+};
+
+} // end namespace PRDF
+
+#endif
diff --git a/src/register/prdfRegisterCache.C b/src/register/prdfRegisterCache.C
new file mode 100644
index 0000000..e7d29ff
--- /dev/null
+++ b/src/register/prdfRegisterCache.C
@@ -0,0 +1,123 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfRegisterCache.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <prdfRegisterCache.H>
+#include <iipconst.h>
+
+namespace PRDF
+{
+
+//------------------------------------------------------------------------------
+
+RegDataCache & RegDataCache::getCachedRegisters()
+{
+ return PRDF_GET_SINGLETON( ReadCache );
+}
+
+//------------------------------------------------------------------------------
+
+RegDataCache::~RegDataCache()
+{
+ flush();
+}
+
+//------------------------------------------------------------------------------
+
+BitString & RegDataCache::read( ExtensibleChip * i_chip,
+ const SCAN_COMM_REGISTER_CLASS * i_reg )
+{
+ ScomRegisterAccess l_scomAccessKey ( *i_reg, i_chip );
+ BitString * l_pBitString = queryCache( l_scomAccessKey );
+
+ if ( NULL == l_pBitString )
+ {
+ // Creating new entry
+ l_pBitString = new BitStringBuffer( i_reg->GetBitLength() );
+ // Adding register in the cache
+ iv_cachedRead[l_scomAccessKey] = l_pBitString;
+ }
+
+ return *l_pBitString;
+}
+
+//------------------------------------------------------------------------------
+
+void RegDataCache::flush()
+{
+ for ( CacheDump::iterator it = iv_cachedRead.begin();
+ it != iv_cachedRead.end(); it++ )
+ {
+ // Freeing up the bit string memory reserved on heap
+ delete it->second;
+ }
+
+ // Deleting all the entry from the cache
+ iv_cachedRead.clear();
+}
+
+//------------------------------------------------------------------------------
+
+void RegDataCache::flush( ExtensibleChip* i_pChip,
+ const SCAN_COMM_REGISTER_CLASS * i_pRegister )
+{
+ ScomRegisterAccess l_scomAccessKey ( *i_pRegister,i_pChip );
+ // Find the entries associated with the given target in the map
+ CacheDump::iterator it = iv_cachedRead.find( l_scomAccessKey );
+
+ // If entry exists delete the entry for given scom address
+ if ( it !=iv_cachedRead.end() )
+ {
+ delete it->second;
+ iv_cachedRead.erase( it );
+ }
+}
+
+//------------------------------------------------------------------------------
+
+BitString * RegDataCache::queryCache(
+ ExtensibleChip* i_pChip,
+ const SCAN_COMM_REGISTER_CLASS * i_pRegister )const
+{
+ ScomRegisterAccess l_scomAccessKey ( *i_pRegister,i_pChip );
+ return queryCache( l_scomAccessKey );
+}
+
+//------------------------------------------------------------------------------
+
+BitString * RegDataCache::queryCache(
+ const ScomRegisterAccess & i_scomAccessKey ) const
+{
+ BitString * l_pBitString = NULL;
+ CacheDump::const_iterator itDump = iv_cachedRead.find( i_scomAccessKey );
+ if( iv_cachedRead.end() != itDump )
+ {
+ l_pBitString = itDump->second ;
+ }
+
+ return l_pBitString;
+}
+
+//------------------------------------------------------------------------------
+}// end namespace PRDF
diff --git a/src/register/prdfRegisterCache.H b/src/register/prdfRegisterCache.H
new file mode 100644
index 0000000..be34884
--- /dev/null
+++ b/src/register/prdfRegisterCache.H
@@ -0,0 +1,124 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfRegisterCache.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef REG_CACHE_H
+#define REG_CACHE_H
+
+/** @file prdfRegisterCache.H */
+
+#include <map>
+#include <iipbits.h>
+#include <prdfGlobal.H>
+#include <prdfScanFacility.H>
+#include <prdfScomRegisterAccess.H>
+#include <prdfTargetFwdRef.H>
+
+class BitString;
+
+namespace PRDF
+{
+/**
+ * @brief Caches the contents of registers used during analysis.
+ *
+ * It maintains the latest content of a register in a map. If contents of the
+ * register remain unchanged, register read returns contents stored in
+ * cache rather than reading from hardware. Hence it brings efficiency in read.
+ * Whenever write to actual hardware takes place, it is expected that once write
+ * to hardware succeeds, the user of cache shall call flush. It drops the
+ * particular register from map. As a result, when read takes place from same
+ * register next time, read from cache fails and actual access to hardware
+ * takes place.
+ */
+class RegDataCache
+{
+ public:
+
+ /**
+ * @brief Constructor
+ */
+ RegDataCache()
+ { }
+
+ /**
+ * @brief Destructor
+ */
+ ~RegDataCache();
+
+ /**
+ * @brief Returns reference to singleton instance of the RegDataCache.
+ * @return The singleton reference.
+ */
+ static RegDataCache & getCachedRegisters();
+
+ /**
+ * @brief Returns the data buffer for the given target and address.
+ * @param i_chip The target associated with the register.
+ * @param i_reg Pointer to register to be read.
+ * @return A reference to the data buffer associated with the register.
+ */
+ BitString & read( ExtensibleChip * i_chip,
+ const SCAN_COMM_REGISTER_CLASS * i_reg );
+
+ /**
+ * @brief Flushes entire contents from cache.
+ */
+ void flush();
+
+ /**
+ * @brief Removes a single entry from the cache.
+ * @param i_pChip The rulechip associated with the register.
+ * @param i_pRegister points to the register to be flushed from cache.
+ */
+ void flush( ExtensibleChip* i_pChip,
+ const SCAN_COMM_REGISTER_CLASS * i_pRegister );
+ /**
+ * @brief Queries if a specific entry exist in cache.
+ * @param i_pChip The rulechip associated with the register.
+ * @param i_pRegister base part of register entry to be queried in cache.
+ * @return pointer to cache entry associated with a given register
+ */
+ BitString * queryCache( ExtensibleChip* i_pChip,
+ const SCAN_COMM_REGISTER_CLASS * i_pRegister )const;
+ /**
+ * @brief Queries if a specific entry exist in cache.
+ * @param i_scomAccessKey Reference to register to be queried.
+ * @return pointer to cache entry associated with a given register
+ */
+
+ BitString * queryCache(
+ const ScomRegisterAccess & i_scomAccessKey )const;
+ private: // data
+
+ typedef std::map<ScomRegisterAccess, BitString *> CacheDump;
+ CacheDump iv_cachedRead;
+
+};
+
+PRDF_DECLARE_SINGLETON(RegDataCache, ReadCache);
+
+} // namespace PRDF
+
+#endif // REG_CACHE_H
+
diff --git a/src/register/prdfScanFacility.C b/src/register/prdfScanFacility.C
new file mode 100755
index 0000000..1607d95
--- /dev/null
+++ b/src/register/prdfScanFacility.C
@@ -0,0 +1,237 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfScanFacility.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/**
+ @file prdfScanFacility.C
+ @brief PRD ScanFaclity class definition
+*/
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#define prdfScanFacility_C
+
+#include <iipscr.h>
+#include <prdfScanFacility.H>
+#include <prdfFlyWeight.C>
+#include <prdfFlyWeightS.C>
+#include <prdfScomRegisterAccess.H>
+
+#undef prdfScanFacility_C
+
+namespace PRDF
+{
+
+//----------------------------------------------------------------------
+// Constants
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Macros
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Internal Function Prototypes
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Global Variables
+//----------------------------------------------------------------------
+
+NullRegister AttnTypeRegister::cv_null(1024);
+
+//---------------------------------------------------------------------
+// Member Function Specifications
+//---------------------------------------------------------------------
+
+
+ScanFacility & ScanFacility::Access(void)
+{
+ static ScanFacility sf;
+ return sf;
+}
+//-----------------------------------------------------------------------------
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetScanCommRegister( uint64_t address,
+ uint32_t i_scomLength, TARGETING::TYPE i_type,
+ SCAN_COMM_REGISTER_CLASS::AccessLevel i_regOp )
+{
+ /* i_regOp is not used to determine uniqueness of the object for following
+ reason -
+ There can not be two registers in hardware with same address and target
+ type supporting different operations say one supports only write and
+ other both read and write.
+ */
+
+ ScomRegister scrKey( address, i_scomLength, i_type, i_regOp );
+ // in case we get a object with different default operation, we shall reset
+ // it to what it should be as per rule file.
+ ScomRegister ®Created = iv_scomRegFw.get(scrKey);
+ regCreated.setAccessLevel( i_regOp );
+ return regCreated;
+}
+
+//------------------------------------------------------------------------------
+
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetNotRegister(
+ SCAN_COMM_REGISTER_CLASS & i_arg )
+{
+ NotRegister r(i_arg);
+ return iv_notRegFw.get(r);
+}
+
+//-----------------------------------------------------------------------------
+
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetLeftShiftRegister(
+ SCAN_COMM_REGISTER_CLASS & i_arg,
+ uint16_t i_amount )
+{
+ LeftShiftRegister r(i_arg, i_amount);
+ return iv_leftRegFw.get(r);
+}
+
+//-----------------------------------------------------------------------------
+
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetSummaryRegister(
+ SCAN_COMM_REGISTER_CLASS & i_arg,
+ uint16_t i_bit )
+{
+ SummaryRegister r(i_arg, i_bit);
+ return iv_sumRegFw.get(r);
+}
+
+//------------------------------------------------------------------------------
+
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetRightShiftRegister(
+ SCAN_COMM_REGISTER_CLASS & i_arg,
+ uint16_t i_amount )
+{
+ RightShiftRegister r(i_arg, i_amount);
+ return iv_rightRegFw.get(r);
+}
+
+
+//------------------------------------------------------------------------------
+
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetAndRegister(
+ SCAN_COMM_REGISTER_CLASS & i_left,
+ SCAN_COMM_REGISTER_CLASS & i_right )
+{
+ AndRegister r(i_left,i_right);
+ return iv_andRegFw.get(r);
+}
+
+//------------------------------------------------------------------------------
+
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetOrRegister(
+ SCAN_COMM_REGISTER_CLASS & i_left,
+ SCAN_COMM_REGISTER_CLASS & i_right )
+{
+ OrRegister r(i_left,i_right);
+ return iv_orRegFw.get(r);
+}
+
+//-----------------------------------------------------------------------------
+
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetAttnTypeRegister(
+ SCAN_COMM_REGISTER_CLASS * i_check,
+ SCAN_COMM_REGISTER_CLASS * i_recov,
+ SCAN_COMM_REGISTER_CLASS * i_special,
+ SCAN_COMM_REGISTER_CLASS * i_proccs,
+ SCAN_COMM_REGISTER_CLASS * i_hostattn )
+{
+ AttnTypeRegister r(i_check, i_recov, i_special, i_proccs, i_hostattn);
+ return iv_attnRegFw.get(r);
+}
+
+//------------------------------------------------------------------------------
+
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetConstantRegister(
+ const BitStringBuffer & i_val )
+{
+ ConstantRegister r(i_val);
+ return iv_constRegFw.get(r);
+}
+//------------------------------------------------------------------------------
+SCAN_COMM_REGISTER_CLASS & ScanFacility::GetPluginRegister(
+ SCAN_COMM_REGISTER_CLASS & i_flyweight,
+ ExtensibleChip & i_RuleChip )
+{
+ ScomRegisterAccess l_regKey ( i_flyweight,&i_RuleChip );
+ return iv_pluginRegFw.get(l_regKey);
+
+}
+//-----------------------------------------------------------------------------
+void ScanFacility::ResetPluginRegister()
+{
+ iv_pluginRegFw.clear();
+
+
+}
+
+//-----------------------------------------------------------------------------
+
+void ScanFacility::reset()
+{
+ iv_scomRegFw.clear();
+ iv_attnRegFw.clear();
+ iv_andRegFw.clear();
+ iv_orRegFw.clear();
+ iv_notRegFw.clear();
+ iv_leftRegFw.clear();
+ iv_sumRegFw.clear();
+ iv_rightRegFw.clear();
+ iv_constRegFw.clear();
+ iv_pluginRegFw.clear();
+}
+
+//------------------------------------------------------------------------------
+#ifdef FLYWEIGHT_PROFILING
+void ScanFacility::printStats()
+{
+ PRDF_TRAC("ScomRegister");
+ iv_scomRegFw.printStats();
+ PRDF_TRAC("Not Register");
+ iv_notRegFw.printStats();
+ PRDF_TRAC("Left Register");
+ iv_leftRegFw.printStats();
+ PRDF_TRAC("Right Register");
+ iv_rightRegFw.printStats();
+ PRDF_TRAC("And Register");
+ iv_andRegFw.printStats();
+ PRDF_TRAC("Or Register");
+ iv_orRegFw.printStats();
+ PRDF_TRAC("AttnTypeRegisters FW" );
+ iv_attnRegFw.printStats();
+ PRDF_TRAC("SummaryRegisters FW" );
+ iv_sumRegFw.printStats();
+ PRDF_TRAC("ConstantRegisters FW" );
+ iv_constRegFw.printStats();
+ PRDF_TRAC("PluginRegisters FW" );
+ iv_pluginRegFw.printStats();
+}
+
+#endif
+
+} // end namespace PRDF
+
diff --git a/src/register/prdfScanFacility.H b/src/register/prdfScanFacility.H
new file mode 100755
index 0000000..02644f7
--- /dev/null
+++ b/src/register/prdfScanFacility.H
@@ -0,0 +1,236 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfScanFacility.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef PRDFSCANFACILITY_H
+#define PRDFSCANFACILITY_H
+/**
+ @file prdfScanFacility.H
+ @brief Description
+*/
+
+
+//--------------------------------------------------------------------
+// Includes
+//--------------------------------------------------------------------
+
+#include <prdfFlyWeight.H>
+#include <prdfFlyWeightS.H>
+#include <vector>
+#include <prdfHomRegisterAccess.H>
+#include <prdfScomRegister.H>
+#include <prdfScomRegisterAccess.H>
+#include <prdfOperatorRegister.H>
+#include <prdfPlatServices.H>
+
+namespace PRDF
+{
+
+
+/**
+ PRD Scan Facility
+ @author Doug Gilbert
+ @par The Scan facility is used by PRD to access Scan and Scan Comm
+ @ functions.It attempts to reduce duplicate objects and their
+ @ aggragates as must as possible.
+*/
+class ScanFacility
+{
+public:
+ /**
+ The Scan Facility is a singleton - this function provides access to it.
+ */
+ static ScanFacility & Access(void);
+
+ /**
+ * @brief Returns reference to flyweight object of type ScomRegister.
+ * An object of given address is first searched in flyweight.
+ * If object exist, reference to existing object is returned
+ * else a new one is created.
+ * @param i_address address of the register
+ * @param i_scomLength length of the bit string
+ * @param i_type type of target associated with register
+ * @param i_regOp operations supported for given register
+ * @return returns reference to flyweight object from factory
+ */
+ SCAN_COMM_REGISTER_CLASS & GetScanCommRegister( uint64_t address,
+ uint32_t i_scomLength, TARGETING::TYPE i_type,
+ SCAN_COMM_REGISTER_CLASS::AccessLevel i_regOp );
+
+ /**
+ * @brief Get a register that bitwise inverts the bitstring of a register
+ * when read or written to
+ * @param SCAN_COMM_REGISTER_CLASS source
+ * @post Only one instance of the register with this SCR parameter will
+ * exist
+ */
+ SCAN_COMM_REGISTER_CLASS & GetNotRegister(SCAN_COMM_REGISTER_CLASS & i_arg);
+
+ /**
+ * @brief Get a register that bitwise left shift the bitstring of a register
+ * when read or written to
+ * @param SCAN_COMM_REGISTER_CLASS source
+ * @post Only one instance of the register with this SCR parameter and
+ * amount will exist
+ */
+ SCAN_COMM_REGISTER_CLASS & GetLeftShiftRegister(
+ SCAN_COMM_REGISTER_CLASS & i_arg, uint16_t i_amount);
+
+ /**
+ * @brief Get a register that bitwise right shift the bitstring of a register
+ * when read or written to
+ * @param SCAN_COMM_REGISTER_CLASS source
+ * @post Only one instance of the register with this SCR parameter and amount
+ * @ will exist
+ */
+ SCAN_COMM_REGISTER_CLASS & GetRightShiftRegister(
+ SCAN_COMM_REGISTER_CLASS & i_arg, uint16_t i_amount);
+
+ /**
+ * @brief Get a register for the summary construct
+ * @param SCAN_COMM_REGISTER_CLASS source
+ * @param uint16_t i_bit bit to set if any attentions found in i_arg
+ * @post Only one instance of the register with this SCR parameter and
+ * amount will exist
+ */
+ SCAN_COMM_REGISTER_CLASS & GetSummaryRegister(
+ SCAN_COMM_REGISTER_CLASS & i_arg, uint16_t i_bit);
+
+ /**
+ * @brief Get a register that bit-wise ANDs the bitstring of two register
+ * when read or written to
+ * @param The 2 SCR 's to AND
+ * @posrt Only one instance of the register with these SCRs will exist
+ */
+ SCAN_COMM_REGISTER_CLASS & GetAndRegister(SCAN_COMM_REGISTER_CLASS & i_left,
+ SCAN_COMM_REGISTER_CLASS & i_right);
+
+ /**
+ * @brief Get a register that bitwise ORs the bitstrings of two register when
+ * read or written
+ * @param the 2 SCR's to OR
+ * @post Only one instance of the register with these SCR's will exist
+ */
+ SCAN_COMM_REGISTER_CLASS & GetOrRegister(SCAN_COMM_REGISTER_CLASS & i_left,
+ SCAN_COMM_REGISTER_CLASS & i_right);
+
+ /**
+ * @brief Get a AttnTypeRegister
+ * @params 5 pointers to scr Registers
+ * @post only one instance of the register with these SCR's will exist
+ */
+ SCAN_COMM_REGISTER_CLASS & GetAttnTypeRegister(
+ SCAN_COMM_REGISTER_CLASS * i_check,
+ SCAN_COMM_REGISTER_CLASS * i_recov,
+ SCAN_COMM_REGISTER_CLASS * i_special,
+ SCAN_COMM_REGISTER_CLASS * i_proccs,
+ SCAN_COMM_REGISTER_CLASS * i_hostattn );
+
+ /**
+ * @brief Get a PrdfConstantRegister
+ * @param BitString - the bit string constant to use.
+ * @post only one instance of the register with this BIT_STRING value will
+ * exist.
+ */
+ SCAN_COMM_REGISTER_CLASS & GetConstantRegister(const BitStringBuffer & i_val);
+ /**
+ * @brief Get a plugin register
+ * @param Reference to target less flyweight object
+ * @param RuleChip associatd with register
+ * @post only one instance of the register with this BIT_STRING value will
+ * exist.
+ */
+ SCAN_COMM_REGISTER_CLASS & GetPluginRegister(
+ SCAN_COMM_REGISTER_CLASS & i_flyweight,
+ ExtensibleChip & i_RuleChip );
+ /**
+ * @brief Delete all the plugin register
+ * @param None
+ * @post all the ScomRegisterAccess register flyweight object created for
+ * plugin shall be deleted
+ * exist.
+ */
+ void ResetPluginRegister();
+
+ /**
+ * @brief Intended to reset all the flyweights if PRD is uninitialized due to
+ * a reIPL, reset/reload, or failover. This free up the memory and
+ * avoids memory leaks in the flyweights.
+ */
+ void reset();
+
+#ifdef FLYWEIGHT_PROFILING
+/**
+ * @brief prints memory allocated for object residing on flyweight
+ */
+ void printStats();
+#endif
+
+ /**
+ Destructor
+ */
+// ~ScanFacility();
+private: // functions
+ /**
+ Constructor
+ * @param
+ * @returns
+ * @pre
+ * @post
+ * @see
+ * @note
+ */
+ ScanFacility() {}
+
+
+private: // Data
+ typedef FlyWeightS<ScomRegister,50> ScanCommRegisters;
+ //FIXME RTC 64345 Investigate benefit of changing below from FlyWeight to
+ //FlyWeightS
+ typedef FlyWeight<AttnTypeRegister,50> AttnTypeRegisters;
+ typedef FlyWeightS<AndRegister,50> AndRegisters;
+ typedef FlyWeightS<OrRegister,10> OrRegisters;
+ typedef FlyWeightS<NotRegister,50> NotRegisters;
+ typedef FlyWeightS<LeftShiftRegister,10> LeftShiftRegisters;
+ typedef FlyWeightS<RightShiftRegister, 10> RightShiftRegisters;
+ typedef FlyWeightS<SummaryRegister,10> SummaryRegisters;
+ typedef FlyWeight<ConstantRegister, 10> ConstantRegisters;
+ typedef FlyWeightS<ScomRegisterAccess, 10> PluginRegisters;
+
+ ScanCommRegisters iv_scomRegFw;
+ AttnTypeRegisters iv_attnRegFw;
+ AndRegisters iv_andRegFw;
+ OrRegisters iv_orRegFw;
+ NotRegisters iv_notRegFw;
+ LeftShiftRegisters iv_leftRegFw;
+ SummaryRegisters iv_sumRegFw;
+ RightShiftRegisters iv_rightRegFw;
+ ConstantRegisters iv_constRegFw;
+ PluginRegisters iv_pluginRegFw;
+
+};
+
+} // end namespace PRDF
+
+#endif /* PRDFSCANFACILITY_H */
diff --git a/src/register/prdfScomRegister.C b/src/register/prdfScomRegister.C
new file mode 100755
index 0000000..7e4cce8
--- /dev/null
+++ b/src/register/prdfScomRegister.C
@@ -0,0 +1,301 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfScomRegister.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+// Module Description **************************************************
+//
+// Description: This module provides the implementation for the PRD Scan
+// Comm Register Chip class.
+//
+// End Module Description **********************************************
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+
+#include <iipchip.h>
+#include <prdfScomRegister.H>
+#include <iipconst.h>
+#include <iipbits.h>
+#include <prdfMain.H>
+#include <prdfRasServices.H>
+#include <prdfRegisterCache.H>
+#include <prdfHomRegisterAccess.H>
+#include <prdfPlatServices.H>
+#include <prdfExtensibleChip.H>
+
+//----------------------------------------------------------------------
+// User Types
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Constants
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Macros
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Internal Function Prototypes
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Global Variables
+//----------------------------------------------------------------------
+
+//---------------------------------------------------------------------
+// Member Function Specifications
+//---------------------------------------------------------------------
+
+// --------------------------------------------------------------------
+namespace PRDF
+{
+
+// ---------------------------------------------------------------------
+
+void ScomRegister::SetBitString( const BitString *bs )
+{
+ BitString & l_string = AccessBitString();
+ l_string.setString(*bs);
+}
+
+
+//------------------------------------------------------------------------------
+
+const BitString * ScomRegister::GetBitString(ATTENTION_TYPE i_type) const
+{
+ // Calling Read() will ensure that an entry exists in the cache and the
+ // entry has at been synched with hardware at least once. Note that we
+ // cannot read hardware for write-only registers. In this case, an entry
+ // will be created in the cache, if it does not exist, when readCache() is
+ // called below.
+ if ( ( ACCESS_NONE != iv_operationType ) &&
+ ( ACCESS_WO != iv_operationType ) )
+ {
+ Read();
+ }
+ return &(readCache());
+}
+
+//------------------------------------------------------------------------------
+
+BitString & ScomRegister::AccessBitString()
+{
+ // Calling Read() will ensure that an entry exists in the cache and the
+ // entry has at been synched with hardware at least once. Note that we
+ // cannot read hardware for write-only registers. In this case, an entry
+ // will be created in the cache, if it does not exist, when readCache() is
+ // called below.
+ if ( ( ACCESS_NONE != iv_operationType ) &&
+ ( ACCESS_WO != iv_operationType ) )
+ {
+ Read();
+ }
+
+ return readCache();
+}
+
+//------------------------------------------------------------------------------
+
+uint32_t ScomRegister::Read() const
+{
+ uint32_t o_rc = SUCCESS;
+
+ // First query the cache for an existing entry.
+ if ( !queryCache() )
+ {
+ // There was not a previous entry in the cache, so do a ForceRead() to
+ // sync the cache with hardware.
+ o_rc = ForceRead();
+ }
+
+ return o_rc;
+}
+
+//------------------------------------------------------------------------------
+
+uint32_t ScomRegister::ForceRead() const
+{
+ #define PRDF_FUNC "[ScomRegister::ForceRead] "
+
+ uint32_t o_rc = FAIL;
+
+ do
+ {
+ // No read allowed if register access attribute is write-only or no
+ // access.
+ if ( ( ACCESS_NONE == iv_operationType ) &&
+ ( ACCESS_WO == iv_operationType ) )
+ {
+ PRDF_ERR( PRDF_FUNC "Write-only register: 0x%08x 0x%016llx",
+ getChip()->GetId(), iv_scomAddress );
+ break;
+ }
+
+ // Read hardware.
+ o_rc = Access( readCache(), MopRegisterAccess::READ );
+ if ( SUCCESS != o_rc )
+ {
+ // The read failed. Remove the entry from the cache so a subsequent
+ // Read() will attempt to read from hardware again.
+ flushCache( getChip() );
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+uint32_t ScomRegister::Write()
+{
+ #define PRDF_FUNC "[ScomRegister::Write] "
+
+ uint32_t o_rc = FAIL;
+
+ do
+ {
+ // No write allowed if register access attribute is read-only or no
+ // access.
+ if ( ( ACCESS_NONE == iv_operationType ) &&
+ ( ACCESS_RO == iv_operationType ) )
+ {
+ PRDF_ERR( PRDF_FUNC "Read-only register: 0x%08x 0x%016llx",
+ getChip()->GetId(), iv_scomAddress );
+ break;
+ }
+
+ // Query the cache for an existing entry.
+ if ( !queryCache() )
+ {
+ // Something bad happened and there was nothing in the cache to
+ // write to hardware.
+ PRDF_ERR( PRDF_FUNC "No entry found in cache: 0x%08x 0x%016llx",
+ getChip()->GetId(), iv_scomAddress );
+ break;
+ }
+
+ // Write hardware.
+ o_rc = Access( readCache(), MopRegisterAccess::WRITE );
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+uint32_t ScomRegister::Access( BitString & bs,
+ MopRegisterAccess::Operation op ) const
+{
+ int32_t l_rc = SCR_ACCESS_FAILED;
+ TARGETING::TargetHandle_t i_pchipTarget = getChip()->GetChipHandle();
+ l_rc = getScomService().Access( i_pchipTarget,bs,iv_scomAddress,op );
+
+ return(l_rc);
+}
+//-----------------------------------------------------------------------------
+ExtensibleChip* ScomRegister::getChip( )const
+{
+ ExtensibleChip* l_pchip = NULL;
+ l_pchip = ServiceDataCollector::getChipAnalyzed();
+ TARGETING::TYPE l_type = PlatServices::getTargetType(
+ l_pchip->GetChipHandle() );
+ PRDF_ASSERT( iv_chipType == l_type )
+ return l_pchip;
+}
+
+//------------------------------------------------------------------------------
+
+bool ScomRegister::queryCache() const
+{
+ RegDataCache & cache = RegDataCache::getCachedRegisters();
+ BitString * bs = cache.queryCache( getChip(), this );
+ return ( NULL != bs );
+}
+
+//------------------------------------------------------------------------------
+
+BitString & ScomRegister::readCache() const
+{
+ RegDataCache & cache = RegDataCache::getCachedRegisters();
+ return cache.read( getChip(), this );
+}
+
+//------------------------------------------------------------------------------
+
+void ScomRegister::flushCache( ExtensibleChip *i_pChip ) const
+{
+ RegDataCache & regDump = RegDataCache::getCachedRegisters();
+ if( NULL == i_pChip )
+ {
+ regDump.flush();
+ }
+ else
+ {
+ regDump.flush( i_pChip ,this );
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+bool ScomRegister::operator == ( const ScomRegister & i_rightRegister ) const
+{
+ if( iv_scomAddress == i_rightRegister.GetAddress() )
+ {
+ return ( iv_chipType == i_rightRegister.getChipType() );
+ }
+ else
+ {
+ return false ;
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+bool ScomRegister::operator < ( const ScomRegister & i_rightRegister ) const
+{
+ if( iv_scomAddress == i_rightRegister.GetAddress() )
+ {
+ return ( iv_chipType < i_rightRegister.getChipType() );
+ }
+ else
+ {
+ return( iv_scomAddress < i_rightRegister.GetAddress() );
+ }
+
+
+}
+//-----------------------------------------------------------------------------
+bool ScomRegister::operator >= ( const ScomRegister & i_rightRegister ) const
+{
+ return !( *this < i_rightRegister );
+}
+}//namespace PRDF ends
diff --git a/src/register/prdfScomRegister.H b/src/register/prdfScomRegister.H
new file mode 100755
index 0000000..655f4d5
--- /dev/null
+++ b/src/register/prdfScomRegister.H
@@ -0,0 +1,244 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfScomRegister.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 1996,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef iipScomRegister_h
+#define iipScomRegister_h
+
+/**
+ * @brief Models register.It does not contain target.
+ *
+ * This class stores the hash id and bit length of scom registers It models
+ * registers without maintaining target information. Instances of this class
+ * are shared across rule chip objects of same type.Once prd object model is
+ * built, instances of this register are saved in flyweight.These instances
+ * persist as long as prd object model survives.
+ */
+
+#include <iipscr.h>
+#include <iipbits.h>
+#include <iipMopRegisterAccess.h>
+#include <prdfTrace.H>
+
+namespace PRDF
+{
+
+// Forward References
+class CHIP_CLASS;
+class MopsRegisterAccess;
+class ExtensibleChip;
+
+class ScomRegister : public SCAN_COMM_REGISTER_CLASS
+{
+ public:
+
+ /**
+ * @brief constructor
+ * @param i_address address of the register
+ * @param i_bitLength bit length of register
+ * @param i_targetType target type associated with register
+ */
+ ScomRegister( uint64_t i_address, uint32_t i_bitLength,
+ TARGETING::TYPE i_targetType, AccessLevel i_access ) :
+ SCAN_COMM_REGISTER_CLASS(),
+ iv_bitLength( i_bitLength ),
+ iv_chipType( i_targetType ),
+ iv_scomAddress( i_address ),
+ iv_operationType( i_access )
+ {}
+
+ /**
+ * @brief constructor .Added this because we save object of this type in
+ * @ FlyweightS
+ */
+ ScomRegister():
+ SCAN_COMM_REGISTER_CLASS(),
+ iv_bitLength( 0 ),
+ iv_chipType( TARGETING::TYPE_NA ),
+ iv_scomAddress( 0 ),
+ iv_operationType( ACCESS_NONE )
+ {}
+
+ /**
+ * @brief Returns the pointer to bit string
+ * @param i_type attention type
+ * @return BitString * pointer to bit string
+ */
+
+ virtual const BitString * GetBitString(ATTENTION_TYPE i_type =
+ INVALID_ATTENTION_TYPE) const;
+ /**
+ * @brief Updates bit string contents associated with register
+ * @param i_bs poiner to bit string
+ * @return Nil
+ */
+
+ virtual void SetBitString(const BitString * i_bs) ;
+
+ /**
+ * @brief Returns length of the bits string associated with register
+ * @return length of bit string
+ */
+ uint32_t GetBitLength(void) const { return iv_bitLength ;}
+
+ /**
+ * @brief Directly reads from hardware register
+ * @return SUCCESS|FAIL
+ */
+ virtual uint32_t ForceRead() const;
+
+ /**
+ * @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
+ */
+ virtual uint32_t Write();
+
+ /**
+ * @brief Returns the hash id of register
+ * @return returns hash id of register
+ * @pre None
+ * @post None
+ * @note
+ */
+ virtual uint16_t GetId(void) const { return iv_shortId; };
+
+ /**
+ * @brief Sets the hash id of register
+ * @param i_id hash id of register
+ * @return Nil
+ */
+ virtual void SetId(uint16_t i_id) { iv_shortId = i_id; };
+
+ /**
+ * @brief Returns type of Target associated with register.
+ * @return Refer to function description
+ */
+ TARGETING::TYPE getChipType()const{ return iv_chipType ;} ;
+ /**
+ * @brief Returns scom address of register
+ * @return Refer to function description
+ */
+ uint64_t GetAddress( ) const {return iv_scomAddress ;};
+ /**
+ * @brief compares two ScomRegisterAccess register for equality
+ * @param i_rightRegister register to be compared against
+ * @return Returns true if registers are equal false otherwise
+ */
+ bool operator == ( const ScomRegister & i_rightRegister ) const ;
+ /**
+ * @brief defines < operation for ScomRegisterAccess
+ * @param i_rightRegister register to be compared against
+ * @return Returns false if i_rightRegisters is less and true otherwise
+ */
+ bool operator < ( const ScomRegister & i_rightRegister ) const ;
+ /**
+ * @brief defines >= operation for ScomRegisterAccess
+ * @param i_rightRegister register to be compared against
+ * @return Returns true if registers is >= i_rightRegister false
+ * otherwise
+ */
+ bool operator >= ( const ScomRegister & i_rightRegister ) const;
+
+ /** @return The register access level (see enum AccessLevel). */
+ virtual AccessLevel getAccessLevel() const { return iv_operationType; }
+
+ /** @brief Sets the register access level (see enum AccessLevel). */
+ virtual void setAccessLevel( AccessLevel i_op ) { iv_operationType = i_op; }
+
+ protected: // Functions
+
+ /**
+ * @brief copy constructor
+ * @param i_scomRegister scomRegister instance to be copied
+ */
+ ScomRegister( const SCAN_COMM_REGISTER_CLASS & i_scomRegister ):
+ SCAN_COMM_REGISTER_CLASS(),
+ iv_bitLength( i_scomRegister.GetBitLength() ),
+ iv_shortId( i_scomRegister.GetId() ),
+ iv_chipType( i_scomRegister.getChipType() ),
+ iv_scomAddress( i_scomRegister.GetAddress() ),
+ iv_operationType( i_scomRegister.getAccessLevel() )
+ {}
+
+ /**
+ * @brief Returns reference to bit string associated with register
+ * @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,
+ MopRegisterAccess::Operation op )const;
+
+ /**
+ * @brief Returns rulechip pointer associated with the register
+ * @return Refer to function description
+ */
+ virtual ExtensibleChip * getChip() const;
+
+private: // functions
+
+ friend class CaptureData;
+
+ /** @return TRUE if entry for this register exist in this cache. */
+ bool queryCache() const;
+
+ /**
+ * @brief Reads register contents from cache.
+ * @return Reference to bit string buffer maintained in cache.
+ */
+ BitString & readCache() const;
+
+ /**
+ * @brief Deletes one or all entry in the cache
+ * @param RuleChip pointer associated with register
+ * @return Nil
+ */
+ void flushCache( ExtensibleChip *i_pChip = NULL ) const;
+
+ private: // Data
+
+ uint32_t iv_bitLength; // bit length of scom
+ uint16_t iv_shortId; // unique hash id of register
+ TARGETING::TYPE iv_chipType; // type of target associated with register
+ uint64_t iv_scomAddress; // scom address associated with regiser
+ AccessLevel iv_operationType; // Operation supported (RO, WO, or RW)
+
+};
+
+}//namespace PRDF ends
+
+#endif
diff --git a/src/register/prdfScomRegisterAccess.C b/src/register/prdfScomRegisterAccess.C
new file mode 100644
index 0000000..a185d63
--- /dev/null
+++ b/src/register/prdfScomRegisterAccess.C
@@ -0,0 +1,83 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfScomRegisterAccess.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <prdfScomRegisterAccess.H>
+#include <prdfScanFacility.H>
+#include <prdfRegisterCache.H>
+#include <prdfExtensibleChip.H>
+namespace PRDF
+{
+
+ScomRegisterAccess::ScomRegisterAccess(
+ const SCAN_COMM_REGISTER_CLASS & i_pRegister,
+ ExtensibleChip * i_pRuleChip ) :
+ ScomRegister( i_pRegister ),
+ iv_containerChip( i_pRuleChip )
+{}
+
+//----------------------------------------------------------------------
+
+ExtensibleChip* ScomRegisterAccess::getChip( )const
+{
+ return iv_containerChip;
+}
+
+//----------------------------------------------------------------------
+
+bool ScomRegisterAccess::operator == (
+ const ScomRegisterAccess & i_rightRegister ) const
+{
+ if( GetAddress() == i_rightRegister.GetAddress() )
+ {
+ return ( getChip() == i_rightRegister.getChip() );
+ }
+ else
+ {
+ return false ;
+ }
+
+}
+//----------------------------------------------------------------------
+
+bool ScomRegisterAccess::operator < (
+ const ScomRegisterAccess & i_rightRegister ) const
+{
+ if( GetAddress() == i_rightRegister.GetAddress() )
+ {
+ return ( getChip() < i_rightRegister.getChip() );
+ }
+ else
+ {
+ return ( GetAddress() < i_rightRegister.GetAddress() );
+ }
+}
+
+//----------------------------------------------------------------------
+bool ScomRegisterAccess::operator >= (
+ const ScomRegisterAccess & i_right ) const
+{
+ return !( *this < i_right );
+}
+
+//----------------------------------------------------------------------
+}//namespace PRDF ends
diff --git a/src/register/prdfScomRegisterAccess.H b/src/register/prdfScomRegisterAccess.H
new file mode 100644
index 0000000..17e1032
--- /dev/null
+++ b/src/register/prdfScomRegisterAccess.H
@@ -0,0 +1,109 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/framework/register/prdfScomRegisterAccess.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __PRDF_REGISTER_
+#define __PRDF_REGISTER_
+
+#include <prdfScomRegister.H>
+#include <prdfBitString.H>
+#include <prdfPlatServices.H>
+
+/**
+ * @brief Models register.This model of register has target info
+ *
+ * In order to reduce the register objects required by PRD to do attention
+ * analysis, these are shared across all the RuleChip objects associated with
+ * target of same type.In order to realize this,target info is taken out of
+ * register object .RuleChip contains target info.During Analysis ,pointer to
+ * Rulechip under analysis is maintained in Service Data collector.During
+ * register Read and Write,target info is obtained by register from service data
+ * collector.This idea fails when getRegister is called for Register read and
+ * write.It may be called from plugin code which may use a RuleChip different
+ * from the one in SDC.We would like to avoid SDC getting updated from multiple
+ * places.To simplify solution for this use case, a wrapper register is required
+ * .This register model knows which rule chip it is associated with.When plugin
+ * code calls getRegister ,instead of returning targetless flyweight object,it
+ * returns an object of class ScomRegisterAccess.Since register Read Write is
+ * in parent class ,it's just a container for Rulechip pointer giving us a way
+ * to do scom without having to look for associated target/rule chip somewhere
+ * else.
+ */
+
+namespace PRDF
+{
+class ScomRegisterAccess : public ScomRegister
+{
+ public :
+ /**
+ * @brief constructor
+ * @param i_Register Reference to flyweight register
+ * @param i_pchip RuleChip associated with register
+ */
+ ScomRegisterAccess( const SCAN_COMM_REGISTER_CLASS & i_Register,
+ ExtensibleChip* i_pchip );
+ /**
+ * @brief constructor
+ */
+ ScomRegisterAccess():ScomRegister( ),iv_containerChip ( NULL ){ };
+
+ /**
+ * @brief Destructor
+ */
+ ~ScomRegisterAccess(){ };
+ /**
+ * @brief Returns pointer to rulechip associated with register
+ * @return Returns rule chip pointer
+ */
+
+ virtual ExtensibleChip* getChip( ) const;
+ /**
+ * @brief compares two ScomRegisterAccess register for equality
+ * @param i_rightRegister register to be compared against
+ * @return Returns true if registers are equal false otherwise
+ */
+ bool operator == ( const ScomRegisterAccess & i_rightRegister ) const;
+ /**
+ * @brief defines < operation for ScomRegisterAccess
+ * @param i_rightRegister register to be compared against
+ * @return Returns false if i_rightRegisters is less and true otherwise
+ */
+ bool operator < ( const ScomRegisterAccess & i_rightRegister ) const;
+ /**
+ * @brief defines >= operation for ScomRegisterAccess
+ * @param i_right register to be compared against
+ * @return Returns true if registers is >= i_rightRegister false
+ * otherwise
+ */
+ bool operator >= ( const ScomRegisterAccess & i_right ) const;
+
+
+ private://Data
+
+ ExtensibleChip* iv_containerChip;
+
+
+};
+
+}//namepsace PRDF ends
+#endif
+
diff --git a/src/util/prdfBitString.C b/src/util/prdfBitString.C
new file mode 100755
index 0000000..b4e7f9b
--- /dev/null
+++ b/src/util/prdfBitString.C
@@ -0,0 +1,509 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/util/prdfBitString.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/** @file BitString.C
+ * @brief BitString and BitStringBuffer class Definitions
+ */
+
+#include <prdfBitString.H>
+
+#include <prdfAssert.h>
+
+#include <algorithm>
+
+namespace PRDF
+{
+#if defined(PRDF_HOSTBOOT_ERRL_PLUGIN)
+namespace HOSTBOOT
+{
+#elif defined(PRDF_FSP_ERRL_PLUGIN)
+namespace FSP
+{
+#endif
+
+
+//##############################################################################
+// BitString class
+//##############################################################################
+
+const uint32_t BitString::CPU_WORD_BIT_LEN = sizeof(CPU_WORD) * 8;
+
+const CPU_WORD BitString::CPU_WORD_MASK = static_cast<CPU_WORD>(-1);
+
+//------------------------------------------------------------------------------
+
+CPU_WORD BitString::getField( uint32_t i_pos, uint32_t i_len ) const
+{
+ PRDF_ASSERT( nullptr != getBufAddr() ); // must to have a valid address
+ PRDF_ASSERT( 0 < i_len ); // must have at least one bit
+ PRDF_ASSERT( i_len <= CPU_WORD_BIT_LEN ); // i_len length must be valid
+ PRDF_ASSERT( i_pos + i_len <= getBitLen() ); // field must be within range
+
+ // The returned value.
+ CPU_WORD o_val = 0;
+
+ // Get the relative address and position of the field.
+ uint32_t relPos = 0;
+ CPU_WORD * relAddr = getRelativePosition( relPos, i_pos );
+
+ // The return value may cross two CPU_WORD addresses. Get length of each
+ // chunk, mask to clear the right-handed bits, and the shift value to make
+ // each chunk left-justified.
+ uint32_t len0 = i_len, len1 = 0;
+ if ( CPU_WORD_BIT_LEN < relPos + i_len )
+ {
+ len0 = CPU_WORD_BIT_LEN - relPos;
+ len1 = i_len - len0;
+ }
+
+ CPU_WORD mask0 = CPU_WORD_MASK << (CPU_WORD_BIT_LEN - len0);
+ CPU_WORD mask1 = CPU_WORD_MASK << (CPU_WORD_BIT_LEN - len1);
+
+ uint32_t shift0 = relPos;
+ uint32_t shift1 = CPU_WORD_BIT_LEN - relPos;
+
+ // Get first half of the value.
+ o_val = (*relAddr << shift0) & mask0;
+
+ // Get the second half of the value, if needed
+ if ( CPU_WORD_BIT_LEN < relPos + i_len )
+ {
+ ++relAddr;
+ o_val |= (*relAddr & mask1) >> shift1;
+ }
+
+ return o_val;
+}
+
+//------------------------------------------------------------------------------
+
+void BitString::setField( uint32_t i_pos, uint32_t i_len, CPU_WORD i_val )
+{
+ PRDF_ASSERT( nullptr != getBufAddr() ); // must to have a valid address
+ PRDF_ASSERT( 0 < i_len ); // must have at least one bit
+ PRDF_ASSERT( i_len <= CPU_WORD_BIT_LEN ); // i_len length must be valid
+ PRDF_ASSERT( i_pos + i_len <= getBitLen() ); // field must be within range
+
+ // Get the relative address and position of the field.
+ uint32_t relPos = 0;
+ CPU_WORD * relAddr = getRelativePosition( relPos, i_pos );
+
+ // The value is left-justified. Ignore all other bits.
+ CPU_WORD mask = CPU_WORD_MASK << (CPU_WORD_BIT_LEN - i_len);
+ CPU_WORD val = i_val & mask;
+
+ // Set first half of the value.
+ *relAddr &= ~(mask >> relPos); // Clear field
+ *relAddr |= (val >> relPos); // Set field
+
+ // Get the second half of the value, if needed
+ if ( CPU_WORD_BIT_LEN < relPos + i_len )
+ {
+ relAddr++;
+ *relAddr &= ~(mask << (CPU_WORD_BIT_LEN - relPos)); // Clear field
+ *relAddr |= (val << (CPU_WORD_BIT_LEN - relPos)); // Set field
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void BitString::setPattern( uint32_t i_sPos, uint32_t i_sLen,
+ CPU_WORD i_pattern, uint32_t i_pLen )
+{
+ PRDF_ASSERT(nullptr != getBufAddr()); // must to have a valid address
+ PRDF_ASSERT(0 < i_sLen); // must have at least one bit
+ PRDF_ASSERT(i_sPos + i_sLen <= getBitLen()); // field must be within range
+ PRDF_ASSERT(0 < i_pLen); // must have at least one bit
+ PRDF_ASSERT(i_pLen <= CPU_WORD_BIT_LEN); // i_pLen length must be valid
+
+ // Get a bit string for the pattern subset (right justified).
+ BitString bso ( i_pLen, &i_pattern, CPU_WORD_BIT_LEN - i_pLen );
+
+ // Iterate the range in chunks the size of i_pLen.
+ uint32_t endPos = i_sPos + i_sLen;
+ for ( uint32_t pos = i_sPos; pos < endPos; pos += i_pLen )
+ {
+ // The true chunk size is either i_pLen or the leftovers at the end.
+ uint32_t len = std::min( i_pLen, endPos - pos );
+
+ // Get this chunk's pattern value, truncate (left justified) if needed.
+ CPU_WORD pattern = bso.getField( 0, len );
+
+ // Set the pattern in this string.
+ setField( pos, len, pattern );
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void BitString::setString( const BitString & i_sStr, uint32_t i_sPos,
+ uint32_t i_sLen, uint32_t i_dPos )
+{
+ // Ensure the source parameters are valid.
+ PRDF_ASSERT( nullptr != i_sStr.getBufAddr() );
+ PRDF_ASSERT( 0 < i_sLen ); // at least one bit to copy
+ PRDF_ASSERT( i_sPos + i_sLen <= i_sStr.getBitLen() );
+
+ // Ensure the destination has at least one bit available to copy.
+ PRDF_ASSERT( nullptr != getBufAddr() );
+ PRDF_ASSERT( i_dPos < getBitLen() );
+
+ // If the source length is greater than the destination length than the
+ // extra source bits are ignored.
+ uint32_t actLen = std::min( i_sLen, getBitLen() - i_dPos );
+
+ // The bit strings may be in overlapping memory spaces. So we need to copy
+ // the data in the correct direction to prevent overlapping.
+ uint32_t sRelOffset = 0, dRelOffset = 0;
+ CPU_WORD * sRelAddr = i_sStr.getRelativePosition( sRelOffset, i_sPos );
+ CPU_WORD * dRelAddr = getRelativePosition( dRelOffset, i_dPos );
+
+ // Copy the data.
+ if ( (dRelAddr == sRelAddr) && (dRelOffset == sRelOffset) )
+ {
+ // Do nothing. The source and destination are the same.
+ }
+ else if ( (dRelAddr < sRelAddr) ||
+ ((dRelAddr == sRelAddr) && (dRelOffset < sRelOffset)) )
+ {
+ // Copy the data forward.
+ for ( uint32_t pos = 0; pos < actLen; pos += CPU_WORD_BIT_LEN )
+ {
+ uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN );
+
+ CPU_WORD value = i_sStr.getField( i_sPos + pos, len );
+ setField( i_dPos + pos, len, value );
+ }
+ }
+ else // Copy the data backwards.
+ {
+ // Get the first position of the last chunk (CPU_WORD aligned).
+ uint32_t lastPos = ((actLen-1) / CPU_WORD_BIT_LEN) * CPU_WORD_BIT_LEN;
+
+ // Start with the last chunk and work backwards.
+ for ( int32_t pos = lastPos; 0 <= pos; pos -= CPU_WORD_BIT_LEN )
+ {
+ uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN );
+
+ CPU_WORD value = i_sStr.getField( i_sPos + pos, len );
+ setField( i_dPos + pos, len, value );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void BitString::maskString( const BitString & i_mask )
+{
+ // Get the length of the smallest string.
+ uint32_t actLen = std::min( getBitLen(), i_mask.getBitLen() );
+
+ for ( uint32_t pos = 0; pos < actLen; pos += CPU_WORD_BIT_LEN )
+ {
+ uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN );
+
+ CPU_WORD dVal = getField( pos, len );
+ CPU_WORD sVal = i_mask.getField( pos, len );
+
+ setField( pos, len, dVal & ~sVal );
+ }
+}
+
+//------------------------------------------------------------------------------
+
+bool BitString::isEqual( const BitString & i_str ) const
+{
+ if ( getBitLen() != i_str.getBitLen() )
+ return false; // size not equal
+
+ for ( uint32_t pos = 0; pos < getBitLen(); pos += CPU_WORD_BIT_LEN )
+ {
+ uint32_t len = std::min( getBitLen() - pos, CPU_WORD_BIT_LEN );
+
+ if ( getField(pos, len) != i_str.getField(pos, len) )
+ return false; // bit strings do not match
+ }
+
+ return true; // bit strings match
+}
+
+//------------------------------------------------------------------------------
+
+bool BitString::isZero() const
+{
+ for ( uint32_t pos = 0; pos < getBitLen(); pos += CPU_WORD_BIT_LEN )
+ {
+ uint32_t len = std::min( getBitLen() - pos, CPU_WORD_BIT_LEN );
+
+ if ( 0 != getField(pos, len) )
+ return false; // something is non-zero
+ }
+
+ return true; // everything was zero
+}
+
+//------------------------------------------------------------------------------
+
+uint32_t BitString::getSetCount( uint32_t i_pos, uint32_t i_len ) const
+{
+ uint32_t endPos = i_pos + i_len;
+
+ PRDF_ASSERT( endPos <= getBitLen() );
+
+ uint32_t count = 0;
+
+ for ( uint32_t i = i_pos; i < endPos; i++ )
+ {
+ if ( isBitSet(i) ) count++;
+ }
+
+ return count;
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer BitString::operator~() const
+{
+ BitStringBuffer bsb( getBitLen() );
+
+ for ( uint32_t pos = 0; pos < getBitLen(); pos += CPU_WORD_BIT_LEN )
+ {
+ uint32_t len = std::min( getBitLen() - pos, CPU_WORD_BIT_LEN );
+
+ CPU_WORD dVal = getField( pos, len );
+
+ bsb.setField( pos, len, ~dVal );
+ }
+
+ return bsb;
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer BitString::operator&( const BitString & i_bs ) const
+{
+ // Get the length of the smallest string.
+ uint32_t actLen = std::min( getBitLen(), i_bs.getBitLen() );
+
+ BitStringBuffer bsb( actLen );
+
+ for ( uint32_t pos = 0; pos < actLen; pos += CPU_WORD_BIT_LEN )
+ {
+ uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN );
+
+ CPU_WORD dVal = getField( pos, len );
+ CPU_WORD sVal = i_bs.getField( pos, len );
+
+ bsb.setField( pos, len, dVal & sVal );
+ }
+
+ return bsb;
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer BitString::operator|( const BitString & i_bs ) const
+{
+ // Get the length of the smallest string.
+ uint32_t actLen = std::min( getBitLen(), i_bs.getBitLen() );
+
+ BitStringBuffer bsb( actLen );
+
+ for ( uint32_t pos = 0; pos < actLen; pos += CPU_WORD_BIT_LEN )
+ {
+ uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN );
+
+ CPU_WORD dVal = getField( pos, len );
+ CPU_WORD sVal = i_bs.getField( pos, len );
+
+ bsb.setField( pos, len, dVal | sVal );
+ }
+
+ return bsb;
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer BitString::operator>>( uint32_t i_shift ) const
+{
+ BitStringBuffer bsb( getBitLen() ); // default all zeros
+
+ if ( i_shift < getBitLen() )
+ {
+ // bso overlays bsb, containing the shifted offset.
+ BitString bso ( bsb.getBitLen() - i_shift, bsb.getBufAddr(), i_shift );
+
+ // Copy this into bso.
+ bso.setString( *this );
+ }
+
+ return bsb;
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer BitString::operator<<( uint32_t i_shift ) const
+{
+ BitStringBuffer bsb( getBitLen() ); // default all zeros
+
+ if ( i_shift < getBitLen() )
+ {
+ // bso overlays *this, containing the shifted offset.
+ BitString bso ( this->getBitLen() - i_shift, this->getBufAddr(),
+ i_shift );
+
+ // Copy bso into bsb.
+ bsb.setString( bso );
+ }
+
+ return bsb;
+}
+
+//------------------------------------------------------------------------------
+
+CPU_WORD * BitString::getRelativePosition( uint32_t & o_relPos,
+ uint32_t i_absPos ) const
+{
+ PRDF_ASSERT( nullptr != getBufAddr() ); // must to have a valid address
+ PRDF_ASSERT( i_absPos < getBitLen() ); // must be a valid position
+
+ o_relPos = (i_absPos + iv_offset) % CPU_WORD_BIT_LEN;
+
+ return iv_bufAddr + ((i_absPos + iv_offset) / CPU_WORD_BIT_LEN);
+}
+
+//##############################################################################
+// BitStringBuffer class
+//##############################################################################
+
+BitStringBuffer::BitStringBuffer( uint32_t i_bitLen ) :
+ BitString( i_bitLen, nullptr )
+{
+ initBuffer();
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer::~BitStringBuffer()
+{
+ delete [] getBufAddr();
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer::BitStringBuffer( const BitString & i_bs ) :
+ BitString( i_bs.getBitLen(), nullptr )
+{
+ initBuffer();
+ if ( !i_bs.isZero() ) setString( i_bs );
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer::BitStringBuffer( const BitStringBuffer & i_bsb ) :
+ BitString( i_bsb.getBitLen(), nullptr )
+{
+ initBuffer();
+ if ( !i_bsb.isZero() ) setString( i_bsb );
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer & BitStringBuffer::operator=( const BitString & i_bs )
+{
+ // The initBuffer() function will deallocate the buffer as well, however we
+ // also need to deallocate the buffer here before we set the length.
+ delete [] getBufAddr();
+ setBufAddr( nullptr );
+
+ setBitLen( i_bs.getBitLen() );
+ initBuffer();
+ if ( !i_bs.isZero() ) setString( i_bs );
+
+ return *this;
+}
+
+//------------------------------------------------------------------------------
+
+BitStringBuffer & BitStringBuffer::operator=( const BitStringBuffer & i_bsb )
+{
+ if ( this != &i_bsb ) // Check for assignment to self
+ {
+ // The initBuffer() function will deallocate the buffer as well, however
+ // we also need to deallocate the buffer here before we set the length.
+ delete [] getBufAddr();
+ setBufAddr( nullptr );
+
+ setBitLen( i_bsb.getBitLen() );
+ initBuffer();
+ if ( !i_bsb.isZero() ) setString( i_bsb );
+ }
+
+ return *this;
+}
+
+//------------------------------------------------------------------------------
+
+void BitStringBuffer::initBuffer()
+{
+ // Deallocate the current buffer.
+ delete [] getBufAddr();
+
+ // Allocate the new buffer.
+ setBufAddr( new CPU_WORD[ getNumCpuWords(getBitLen()) ] );
+
+ // Clear the new buffer.
+ if ( !isZero() ) clearAll();
+}
+
+/*--------------------------------------------------------------------*/
+/* IO Stream Conditional Support */
+/*--------------------------------------------------------------------*/
+
+#ifdef _USE_IOSTREAMS_
+
+std::ostream & operator<<(std::ostream & out,
+ const BitString & bit_string )
+{
+ const uint32_t bit_field_length = BitString::CPU_WORD_BIT_LEN;
+ out << std::hex;
+ for(uint32_t pos = 0; pos < bit_string.getBitLen(); pos += bit_field_length)
+ {
+ uint32_t len = bit_string.getBitLen() - pos;
+ len = std::min(len,bit_field_length);
+ CPU_WORD value = bit_string.getField(pos,len);
+ out << std::setw(bit_field_length/4) << std::setfill('0') << value << " ";
+ }
+
+ return(out);
+}
+
+#endif
+
+#if defined(PRDF_HOSTBOOT_ERRL_PLUGIN) || defined(PRDF_FSP_ERRL_PLUGIN)
+} // end namespace FSP/HOSTBOOT
+#endif
+} // end namespace PRDF
+
diff --git a/src/util/prdfBitString.H b/src/util/prdfBitString.H
new file mode 100755
index 0000000..130d379
--- /dev/null
+++ b/src/util/prdfBitString.H
@@ -0,0 +1,469 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/util/prdfBitString.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef PRDFBITSTRING_H
+#define PRDFBITSTRING_H
+
+/** @file prdBitString.H
+ * @brief BitString and BitStringBuffer class declarations
+ */
+
+#include <prdf_types.h>
+
+#if defined(ESW_SIM_COMPILE)
+#define _USE_IOSTREAMS_
+#endif
+
+#ifdef _USE_IOSTREAMS_
+ #include <iostream>
+ #include <iomanip>
+#endif
+
+namespace PRDF
+{
+#if defined(PRDF_HOSTBOOT_ERRL_PLUGIN)
+namespace HOSTBOOT
+{
+#elif defined(PRDF_FSP_ERRL_PLUGIN)
+namespace FSP
+{
+#endif
+
+
+class BitStringBuffer;
+
+/** This type is used to take advantage of the most efficient memory reference
+ * size for a specific CPU architecture. */
+typedef uint32_t CPU_WORD;
+
+//##############################################################################
+// BitString class
+//##############################################################################
+
+/**
+ * A BitString is general purpose class providing the ability to manipulate
+ * individual bits within an allocated section of contiguous memory.
+ *
+ * A BitString does not "own" the memory, it only accesses and manipulates the
+ * bits in the range specified. Users will need to ensure memory is allocated
+ * and deallocated appropriately. As an alternative, a BitStringBuffer is a
+ * BitString that will allocate and maintain its own memory.
+ *
+ * The length of a BitString is only limited by the amount of memory that
+ * contains the data buffer.
+ *
+ * The CPU_WORD type is used internally to reference memory and as the interface
+ * type for the field. Ensure that any buffer allocated for a BitString is
+ * CPU_WORD aligned so that the BitString does not accidentally access memory
+ * beyond availability. For example, say we have a buffer allocated for 6 byte
+ * (48 bits) and those 6 bytes are allocated at the very end of accessible
+ * memory. When the BitString tries to access the second CPU_WORD, which
+ * contains the last 2 bytes of the buffer, an expection will be thrown because
+ * the BitString always access an entire CPU_WORD (4 bytes) at a time and the
+ * last two bytes are not accessible. Utilize the static function
+ * getNumCpuWords() to get the minimum number of CPU_WORDs required to allocate
+ * sufficient space in the buffer. For example, getNumCpuWords(48) returns 2.
+ *
+ * The bit positions are ordered 0 to n (left to right), where n is the bit
+ * length minus one. By default, position 0 will be the first bit of the
+ * buffer's start address. The optional constructor allows users to input an
+ * offset anywhere within the buffer, which is then used as position 0. This is
+ * useful when the data within the buffer is a right-justified.
+ */
+class BitString
+{
+ public: // constants
+
+ /** Bit length of a CPU_WORD */
+ static const uint32_t CPU_WORD_BIT_LEN;
+
+ /** A CPU_WORD with all of the bits set to 1 */
+ static const CPU_WORD CPU_WORD_MASK;
+
+ public: // functions
+
+ /**
+ * @brief Constructor
+ * @param i_bitLen The number of bits in the bit string.
+ * @param i_bufAddr The starting address of the memory buffer.
+ * @param i_offset Optional input to indicate the actual starting position
+ * of the bit string within the memory buffer.
+ * @post It is possible that i_bitLen + i_offset may not be CPU_WORD
+ * aligned, however, the memory space allocated for i_bufAddr must be
+ * CPU_WORD aligned to avoid functions in this class accessing memory
+ * outside the available memory space. Use getNumCpuWords() to
+ * calulate the number of CPU_WORDs needed to allocate sufficient
+ * memory space.
+ */
+ BitString( uint32_t i_bitLen, CPU_WORD * i_bufAddr,
+ uint32_t i_offset = 0 ) :
+ iv_bitLen(i_bitLen), iv_bufAddr(i_bufAddr), iv_offset(i_offset)
+ {}
+
+ /** @brief Destructor */
+ virtual ~BitString() {}
+
+ /** @return The number of bits in the bit string buffer. */
+ uint32_t getBitLen() const { return iv_bitLen; }
+
+ /** @return The address of the bit string buffer. Note that this may
+ * return nullptr. */
+ CPU_WORD * getBufAddr() const { return iv_bufAddr; }
+
+ /**
+ * @param i_bitLen The number of bits for a bit string.
+ * @param i_offset Optional starting position of the bit string within the
+ * memory buffer.
+ * @return The minimum number of CPU_WORDs required to allocate sufficient
+ * memory space for a bit string.
+ */
+ static uint32_t getNumCpuWords( uint32_t i_bitLen, uint32_t i_offset = 0 )
+ {
+ return (i_bitLen + i_offset + CPU_WORD_BIT_LEN-1) / CPU_WORD_BIT_LEN;
+ }
+
+ /**
+ * @brief Returns a left-justified value of the given length from the bit
+ * string starting at the given position.
+ * @param i_pos The starting position of the target range.
+ * @param i_len The number of bits of the target range.
+ * @return The value of the field range specified (left-justified).
+ * @pre nullptr != getBufAddr()
+ * @pre 0 < i_len
+ * @pre i_len <= CPU_WORD_BIT_LEN
+ * @pre i_pos + i_len <= getBitLen()
+ */
+ CPU_WORD getField( uint32_t i_pos, uint32_t i_len ) const;
+
+ /**
+ * @brief Returns a right-justified value of the given length from the bit
+ * string starting at the given position.
+ * @param i_pos The starting position of the target range.
+ * @param i_len The number of bits of the target range.
+ * @return The value of the field range specified (right-justified).
+ * @pre nullptr != getBufAddr()
+ * @pre 0 < i_len
+ * @pre i_len <= CPU_WORD_BIT_LEN
+ * @pre i_pos + i_len <= getBitLen()
+ */
+ CPU_WORD getFieldJustify( uint32_t i_pos, uint32_t i_len ) const
+ {
+ return getField(i_pos, i_len) >> (CPU_WORD_BIT_LEN - i_len);
+ }
+
+ /**
+ * @brief Sets a left-justified value of the given length into the bit
+ * string starting at the given position.
+ * @param i_pos The starting position of the target range.
+ * @param i_len The number of bits of the target range.
+ * @param i_val The left-justified value to set.
+ * @pre nullptr != getBufAddr()
+ * @pre 0 < i_len
+ * @pre i_len <= CPU_WORD_BIT_LEN
+ * @pre i_pos + i_len <= getBitLen()
+ */
+ void setField( uint32_t i_pos, uint32_t i_len, CPU_WORD i_val );
+
+ /**
+ * @brief Sets a right-justified value of the given length into the bit
+ * string starting at the given position.
+ * @param i_pos The starting position of the target range.
+ * @param i_len The number of bits of the target range.
+ * @param i_val The right-justified value to set.
+ * @pre nullptr != getBufAddr()
+ * @pre 0 < i_len
+ * @pre i_len <= CPU_WORD_BIT_LEN
+ * @pre i_pos + i_len <= getBitLen()
+ */
+ void setFieldJustify( uint32_t i_pos, uint32_t i_len, CPU_WORD i_val )
+ {
+ setField( i_pos, i_len, i_val << (CPU_WORD_BIT_LEN - i_len) );
+ }
+
+ /**
+ * @param i_pos The target position.
+ * @return True if the bit at the given position is set(1), false otherwise.
+ * @pre i_pos < getBitLen().
+ */
+ bool isBitSet( uint32_t i_pos ) const { return 0 != getField(i_pos, 1); }
+
+ /**
+ * @brief Sets the target position to 1.
+ * @param i_pos The target position.
+ * @pre i_pos < getBitLen().
+ */
+ void setBit( uint32_t i_pos ) { setFieldJustify( i_pos, 1, 1 ); }
+
+ /** @brief Sets the entire bit string to 1's. */
+ void setAll() { setPattern(CPU_WORD_MASK); }
+
+ /**
+ * @brief Sets the target position to 0.
+ * @param i_pos The target position.
+ * @pre i_pos < getBitLen().
+ */
+ void clearBit( uint32_t i_pos ) { setFieldJustify( i_pos, 1, 0 ); }
+
+ /** @brief Sets the entire bit string to 0's. */
+ void clearAll() { setPattern(0); }
+
+ /**
+ * @brief Sets a range within the string based on the pattern and length
+ * provided.
+ * @param i_sPos Starting position of this string.
+ * @param i_sLen The length of the target range.
+ * @param i_pattern The pattern to set (right justified).
+ * @param i_pLen The length of the pattern.
+ * @pre nullptr != getBufAddr()
+ * @pre 0 < i_sLen
+ * @pre i_sPos + i_sLen <= getBitLen()
+ * @pre 0 < i_pLen <= CPU_WORD_BIT_LEN
+ * @post The pattern is repeated/truncated as needed.
+ *
+ * Examples: i_sPos(0), i_sLen(10), i_pattern(0xA), i_pLen(4)
+ * Old String: 0000000000
+ * New String: 1010101010
+ *
+ * i_sPos(3), i_sLen(4), i_pattern(0x3), i_pLen(3)
+ * Old String: 0001001000
+ * New String: 0000110000
+ */
+ void setPattern( uint32_t i_sPos, uint32_t i_sLen,
+ CPU_WORD i_pattern, uint32_t i_pLen );
+
+ /**
+ * @brief Sets entire string based on the pattern and length provided.
+ * @param i_pattern The pattern to set (right justified).
+ * @param i_pLen The length of the pattern.
+ * @note See definition above for prerequisites.
+ * @post The entire string is filled with the pattern.
+ * @post The pattern is repeated/truncated as needed.
+ */
+ void setPattern( CPU_WORD i_pattern, uint32_t i_pLen )
+ {
+ setPattern( 0, getBitLen(), i_pattern, i_pLen );
+ }
+
+ /**
+ * @brief Sets entire string based on the pattern provided (length of
+ * CPU_WORD).
+ * @param i_pattern The pattern to set.
+ * @note See definition above for prerequisites.
+ * @post The entire string is filled with the pattern.
+ * @post The pattern is repeated/truncated as needed.
+ */
+ void setPattern( CPU_WORD i_pattern )
+ {
+ setPattern( i_pattern, CPU_WORD_BIT_LEN );
+ }
+
+ /**
+ * @brief Set bits in this string based on the given string.
+ * @param i_sStr The source string.
+ * @param i_sPos The starting position of the source string.
+ * @param i_sLen The number of bits to copy from the source string.
+ * @param i_dPos The starting position of the this string.
+ * @pre nullptr != getBufAddr()
+ * @pre nullptr != i_sStr.getBufAddr()
+ * @pre 0 < i_sLen
+ * @pre i_sPos + i_sLen <= i_sStr.getBitLen()
+ * @pre i_dPos < getBitLen()
+ * @post Source bits in given range are copied to this starting at i_dPos.
+ * @note If the length of the given string is greater than the length of
+ * this string, then the extra bits are ignored.
+ * @note If the length of the given string is less than the length of this
+ * string, then the extra bits in this string are not modified.
+ * @note This string and the source string may specify overlapping memory.
+ */
+ void setString( const BitString & i_sStr, uint32_t i_sPos,
+ uint32_t i_sLen, uint32_t i_dPos = 0 );
+
+ /**
+ * @brief Set bits in this string based on the provided string.
+ * @param i_sStr The source string.
+ * @note This will try to copy as much of the source as possible to this
+ * string, starting with the first bit in each string.
+ * @note See the other definition of this function for details and
+ * restrictions.
+ */
+ void setString( const BitString & i_sStr )
+ {
+ setString( i_sStr, 0, i_sStr.getBitLen() );
+ }
+
+ /**
+ * @brief Masks (clears) any bits set in this string that correspond to bits
+ * set in the given string (this & ~mask).
+ * @param i_mask The mask string.
+ * @note If the length of the given string is greater than the length of
+ * this string, then the extra bits are ignored.
+ * @note If the length of the given string is less than the length of this
+ * string, then the extra bits in this string are not modified.
+ */
+ void maskString( const BitString & i_mask );
+
+ /**
+ * @param i_str The string to compare.
+ * @return True if the strings are equivalent, false otherwise.
+ * @pre Both strings must be of equal length and have same values to be
+ * equal.
+ */
+ bool isEqual( const BitString & i_str ) const;
+
+ /** @return True if there are no bit set(1) in this bit string, false
+ * otherwise. */
+ bool isZero() const;
+
+ /**
+ * @param i_pos The starting position of the target range.
+ * @param i_len The length of the target range.
+ * @return The number of bits that are set(1) in given range of this string.
+ * @pre nullptr != getBufAddr()
+ * @pre i_pos + i_len <= getBitLen()
+ */
+ uint32_t getSetCount( uint32_t i_pos, uint32_t i_len ) const;
+
+ /** @return The number of bits that are set(1) in this string. */
+ uint32_t getSetCount() const { return getSetCount( 0, getBitLen() ); }
+
+ /** @brief Comparison operator. */
+ bool operator==( const BitString & i_str ) const { return isEqual(i_str); }
+
+ /** @brief Bitwise NOT operator. */
+ BitStringBuffer operator~() const;
+
+ /** @brief Bitwise AND operator. */
+ BitStringBuffer operator&( const BitString & i_bs ) const;
+
+ /** @brief Bitwise OR operator. */
+ BitStringBuffer operator|( const BitString & i_bs ) const;
+
+ /** @brief Right shift operator. */
+ BitStringBuffer operator>>( uint32_t i_shift ) const;
+
+ /** @brief Left shift operator. */
+ BitStringBuffer operator<<( uint32_t i_shift ) const;
+
+ protected: // functions
+
+ /**
+ * @param i_newBufAddr The starting address of the new bit string buffer.
+ * @pre Before calling this function, make sure you deallocate the old
+ * buffer to avoid memory leaks.
+ */
+ void setBufAddr( CPU_WORD * i_newBufAddr ) { iv_bufAddr = i_newBufAddr; }
+
+ /** @param i_newBitLen The new bit length of this bit string buffer. */
+ void setBitLen( uint32_t i_newBitLen ) { iv_bitLen = i_newBitLen; }
+
+ private: // functions
+
+ // Prevent the assignment operator and copy constructor from a
+ // BitStringBuffer. While technically these could be done. We run into
+ // serious problems like with the operator functions above that all return
+ // a BitStringBuffer. If we allowed these, the BitString would end up
+ // pointing to memory that is no longer in context.
+ BitString & operator=( const BitStringBuffer & i_bsb );
+ BitString( const BitStringBuffer & i_bsb );
+
+ /**
+ * @brief Given a bit position within the bit string, this function returns
+ * the address that contains the bit position and the bit position
+ * relative to that address.
+ * @param o_relPos The returned relative position.
+ * @param i_absPos The inputted absolute position.
+ * @return The relative address.
+ * @pre nullptr != getBufAddr()
+ * @pre i_absPos < getBitLen()
+ */
+ CPU_WORD * getRelativePosition( uint32_t & o_relPos,
+ uint32_t i_absPos ) const;
+
+ private: // instance variables
+
+ uint32_t iv_bitLen; ///< The bit length of this buffer.
+ CPU_WORD * iv_bufAddr; ///< The beginning address of this buffer.
+ uint32_t iv_offset; ///< Start position offset
+};
+
+//##############################################################################
+// BitStringBuffer class
+//##############################################################################
+
+/** A BitStringBuffer is a BitString that maintains its own buffer in memory. It
+ * guarantees that sufficient memory is allocated and deallocated in the
+ * constructor and destructor, respectively. In addition, the assignment
+ * operator will adjust the amount of memory needed, as necessary, for the
+ * assignment. */
+class BitStringBuffer : public BitString
+{
+ public: // functions
+
+ /**
+ * @brief Constructor
+ * @param i_bitLen Number of bits in the string.
+ */
+ explicit BitStringBuffer( uint32_t i_bitLen );
+
+ /** @brief Destructor */
+ ~BitStringBuffer();
+
+ /** @brief Copy constructor from BitString */
+ BitStringBuffer( const BitString & i_bs );
+
+ /** @brief Copy constructor from BitStringBuffer */
+ BitStringBuffer( const BitStringBuffer & i_bsb );
+
+ /** @brief Assignment from BitString */
+ BitStringBuffer & operator=( const BitString & i_bs );
+
+ /** @brief Assignment from BitStringBuffer */
+ BitStringBuffer & operator=( const BitStringBuffer & i_bsb );
+
+ private: // functions
+
+ /** @brief Deallocates the old buffer, if needed, and initializes the new
+ * buffer. */
+ void initBuffer();
+};
+
+/*--------------------------------------------------------------------*/
+/* IO Stream Conditional Support */
+/*--------------------------------------------------------------------*/
+
+#ifdef _USE_IOSTREAMS_
+
+
+std::ostream & operator<<( std::ostream & out,
+ const BitString & bit_string);
+
+#endif
+
+#if defined(PRDF_HOSTBOOT_ERRL_PLUGIN) || defined(PRDF_FSP_ERRL_PLUGIN)
+} // end namespace FSP/HOSTBOOT
+#endif
+} // end namespace PRDF
+
+#endif