Log istep info on watchdog timeout

1. SBE istep info (cfam 2809)
2. HB istep info (cfam 283C)

Change-Id: I67632c58fe1148b980791dc017e5c099107caae5
Signed-off-by: Shakeeb Pasha <shakeebbk@in.ibm.com>
diff --git a/p9_cfam.hpp b/p9_cfam.hpp
index 0cf5c02..43bbaa5 100644
--- a/p9_cfam.hpp
+++ b/p9_cfam.hpp
@@ -16,8 +16,10 @@
 static constexpr uint16_t P9_FSI2PIB_TRUE_MASK     = 0x100D;
 static constexpr uint16_t P9_CBS_CS                = 0x2801;
 static constexpr uint16_t P9_SBE_CTRL_STATUS       = 0x2808;
+static constexpr uint16_t P9_SBE_MSG_REGISTER      = 0x2809;
 static constexpr uint16_t P9_ROOT_CTRL0            = 0x2810;
 static constexpr uint16_t P9_PERV_CTRL0            = 0x281A;
+static constexpr uint16_t P9_HB_MBX5_REG           = 0x283C;
 static constexpr uint16_t P9_SCRATCH_REGISTER_8    = 0x283F;
 static constexpr uint16_t P9_ROOT_CTRL8            = 0x2918;
 }
diff --git a/procedures/p9/collect_sbe_hb_data.cpp b/procedures/p9/collect_sbe_hb_data.cpp
new file mode 100644
index 0000000..3764520
--- /dev/null
+++ b/procedures/p9/collect_sbe_hb_data.cpp
@@ -0,0 +1,150 @@
+/**
+ * Copyright © 2017 IBM Corporation
+ *
+ * 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.
+ */
+#include <phosphor-logging/log.hpp>
+#include "cfam_access.hpp"
+#include "p9_cfam.hpp"
+#include "registration.hpp"
+#include "targeting.hpp"
+
+namespace openpower
+{
+namespace p9
+{
+namespace debug
+{
+// SBE messaging register - cfam 2809
+union sbeMsgReg_t
+{
+    uint32_t data32;
+
+    struct
+    {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+        uint32_t reserved2 : 6;
+        uint32_t minorStep : 6;
+        uint32_t majorStep : 8;
+        uint32_t currState : 4;
+        uint32_t prevState : 4;
+        uint32_t reserved1 : 2;
+        uint32_t asyncFFDC : 1;
+        uint32_t sbeBooted : 1;
+#else
+        uint32_t sbeBooted : 1;
+        uint32_t asyncFFDC : 1;
+        uint32_t reserved1 : 2;
+        uint32_t prevState : 4;
+        uint32_t currState : 4;
+        uint32_t majorStep : 8;
+        uint32_t minorStep : 6;
+        uint32_t reserved2 : 6;
+#endif
+    } PACKED;
+};
+
+// HB mailbox scratch register 5 - cfam 283C
+union MboxScratch5_HB_t
+{
+    uint32_t data32;
+    struct
+    {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+        uint32_t minorStep           :8;    //24:31
+        uint32_t majorStep           :8;    //16:23
+        uint32_t internalStep        :4;    //12:15
+        uint32_t reserved            :2;    //10:11
+        uint32_t stepFinish          :1;    //9
+        uint32_t stepStart           :1;    //8
+        uint32_t magic               :8;    //0:7
+#else
+        uint32_t magic               :8;    //0:7
+        uint32_t stepStart           :1;    //8
+        uint32_t stepFinish          :1;    //9
+        uint32_t reserved            :2;    //10:11
+        uint32_t internalStep        :4;    //12:15
+        uint32_t majorStep           :8;    //16:23
+        uint32_t minorStep           :8;    //24:31
+#endif
+    } PACKED;
+};
+
+static constexpr uint8_t HB_MBX5_VALID_FLAG = 0xAA;
+
+/**
+ * @brief Capture SBE and HB istep information on watchdog timeout
+ * @return void
+ */
+void collectSBEHBData()
+{
+    using namespace openpower::targeting;
+    using namespace openpower::cfam::p9;
+    using namespace openpower::cfam::access;
+    using namespace phosphor::logging;
+
+    Targeting targets;
+
+    for (const auto& proc: targets)
+    {
+        // Read and parse SBE messaging register
+        try
+        {
+            auto readData = readReg(proc, P9_SBE_MSG_REGISTER);
+            auto msg = reinterpret_cast<const sbeMsgReg_t*>(&readData);
+            log<level::INFO>("SBE status register",
+                             entry("PROC=%d",
+                                    proc->getPos()),
+                             entry("SBE_MAJOR_ISTEP=%d",
+                                    msg->PACKED.majorStep),
+                             entry("SBE_MINOR_ISTEP=%d",
+                                    msg->PACKED.minorStep),
+                             entry("REG_VAL=0x%08X",
+                                    msg->data32));
+        }
+        catch (const std::exception& e)
+        {
+            log<level::ERR>(e.what());
+            // We want to continue - capturing as much info as possible
+        }
+    }
+
+    const auto& master = *(targets.begin());
+    // Read and parse HB messaging register
+    try
+    {
+        auto readData = readReg(master, P9_HB_MBX5_REG);
+        auto msg = reinterpret_cast<const MboxScratch5_HB_t*>(&readData);
+        if (HB_MBX5_VALID_FLAG == msg->PACKED.magic)
+        {
+            log<level::INFO>("HB MBOX 5 register",
+                             entry("HB_MAJOR_ISTEP=%d",
+                                    msg->PACKED.majorStep),
+                             entry("HB_MINOR_ISTEP=%d",
+                                    msg->PACKED.minorStep),
+                             entry("REG_VAL=0x%08X",
+                                    msg->data32));
+        }
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        // We want to continue - capturing as much info as possible
+    }
+}
+
+REGISTER_PROCEDURE("collectSBEHBData", collectSBEHBData);
+
+} // namespace debug
+} // namespace p9
+} // namespace openpower