PHAL: Added clock register data in the clock daily data logger

    Informational log includes all the present clock register information
    required for clock debug.

Tested:
    "Clock0": "Functional",
    "Clock0 path": "/bmc0/i2c-0/oscrefclk0",
    "Clock0_0x00": " 37 d0 40 03 00 bf 00 02",
    "Clock0_0x08": " 01 00 00 00 00 00 21 0b",
    "Clock0_0x10": " 17 12 01 00 30 24 04 72",
    :: ::
    "Clock0_0xe0": " 00 00 00 00 00 00 00 00",
    "Clock0_0xe8": " 00 00 c1 00 00 00 00 00",
    "Clock0_0xf0": " 00 00 00 00 00 00 00 00",
    "Clock0_0xf8": " 00 00 00 00 00 00 00 00"

Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
Change-Id: Ic536337f494febfa92162c0387cf2995e24e9b10
diff --git a/extensions/phal/clock_logger.cpp b/extensions/phal/clock_logger.cpp
index 399b01f..5de6047 100644
--- a/extensions/phal/clock_logger.cpp
+++ b/extensions/phal/clock_logger.cpp
@@ -155,6 +155,9 @@
         addCFAMData(procTarget, clockDataLog);
     }
 
+    // Add clock register information
+    addClockRegData(clockDataLog);
+
     openpower::pel::createPEL("org.open_power.PHAL.Info.ClockDailyLog",
                               clockDataLog);
 }
@@ -190,4 +193,80 @@
     }
 }
 
+void Manager::addClockRegData(openpower::pel::FFDCData& clockDataLog)
+{
+    info("Adding clock register information to daily logger");
+
+    struct pdbg_target* clockTarget;
+    pdbg_for_each_class_target("oscrefclk", clockTarget)
+    {
+        ATTR_HWAS_STATE_Type hwasState;
+        if (DT_GET_PROP(ATTR_HWAS_STATE, clockTarget, hwasState))
+        {
+            error("({TARGET}) Could not read HWAS_STATE attribute", "TARGET",
+                  pdbg_target_path(clockTarget));
+            continue;
+        }
+
+        if (!hwasState.present)
+        {
+            continue;
+        }
+
+        std::string funState = "Non Functional";
+
+        if (hwasState.functional)
+        {
+            funState = "Functional";
+        }
+
+        auto index = std::to_string(pdbg_target_index(clockTarget));
+
+        std::stringstream ssState;
+        ssState << "Clock" << index;
+        clockDataLog.push_back(std::make_pair(ssState.str(), funState));
+
+        // Add clcok device path information
+        std::stringstream ssName;
+        ssName << "Clock" << index << " path";
+        clockDataLog.push_back(
+            std::make_pair(ssName.str(), pdbg_target_path(clockTarget)));
+
+        auto status = pdbg_target_probe(clockTarget);
+        if (status != PDBG_TARGET_ENABLED)
+        {
+            continue;
+        }
+
+        // Update Buffer with clock I2C register data.
+        auto constexpr I2C_READ_SIZE = 0x08;
+        auto constexpr I2C_ADDR_MAX = 0xFF;
+
+        for (auto addr = 0; addr <= I2C_ADDR_MAX; addr += I2C_READ_SIZE)
+        {
+            std::stringstream ssData;
+
+            uint8_t data[0x8];
+            auto i2cRc = i2c_read(clockTarget, 0, addr, I2C_READ_SIZE, data);
+            if (i2cRc)
+            {
+                error("({TARGET}) I2C read error({ERROR}) reported {ADDRESS} ",
+                      "TARGET", pdbg_target_path(clockTarget), "ERROR", i2cRc,
+                      "ADDRESS", addr);
+                continue;
+            }
+
+            for (auto i = 0; i < I2C_READ_SIZE; i++)
+            {
+                ssData << " " << std::hex << std::setfill('0') << std::setw(2)
+                       << (uint16_t)data[i];
+            }
+            std::stringstream ssAddr;
+            ssAddr << "Clock" << index << "_0x" << std::hex << std::setfill('0')
+                   << std::setw(2) << addr;
+            clockDataLog.push_back(make_pair(ssAddr.str(), ssData.str()));
+        }
+    }
+}
+
 } // namespace openpower::phal::clock
diff --git a/extensions/phal/clock_logger.hpp b/extensions/phal/clock_logger.hpp
index 2d56cef..d52293a 100644
--- a/extensions/phal/clock_logger.hpp
+++ b/extensions/phal/clock_logger.hpp
@@ -75,6 +75,13 @@
     void addCFAMData(struct pdbg_target* proc,
                      openpower::pel::FFDCData& clockDataLog);
 
+    /**
+     * @brief Add clock specific register data to daily logger.
+     *
+     * @param[out] ffdcData - reference to clock data log
+     */
+    void addClockRegData(openpower::pel::FFDCData& clockDataLog);
+
   private:
     /* The sdeventplus even loop to use */
     sdeventplus::Event _event;