Update primary SRC field based on callout list

Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
Change-Id: I41f3eda5c27b8ec74d6329b8f145181f400547f8
diff --git a/analyzer/service_data.cpp b/analyzer/service_data.cpp
index c13bc8b..2a7d5f5 100644
--- a/analyzer/service_data.cpp
+++ b/analyzer/service_data.cpp
@@ -18,6 +18,7 @@
     ffdc["Priority"]     = callout::getStringFFDC(i_priority);
     ffdc["Guard"]        = i_guard;
     addCalloutFFDC(ffdc);
+    setSrcSubsystem(getTargetSubsystem(i_target), i_priority);
 }
 
 //------------------------------------------------------------------------------
@@ -41,6 +42,7 @@
     ffdc["Priority"]     = callout::getStringFFDC(i_priority);
     ffdc["Guard"]        = i_guard;
     addCalloutFFDC(ffdc);
+    setSrcSubsystem(getTargetSubsystem(txTarget), i_priority);
 }
 
 //------------------------------------------------------------------------------
@@ -71,6 +73,7 @@
     ffdc["Priority"]     = callout::getStringFFDC(i_priority);
     ffdc["Guard"]        = i_guard;
     addCalloutFFDC(ffdc);
+    setSrcSubsystem(i_busType.getSrcSubsystem(), i_priority);
 }
 
 //------------------------------------------------------------------------------
@@ -91,6 +94,7 @@
     ffdc["Clock Type"]   = i_clockType.getString();
     ffdc["Priority"]     = callout::getStringFFDC(i_priority);
     addCalloutFFDC(ffdc);
+    setSrcSubsystem(i_clockType.getSrcSubsystem(), i_priority);
 }
 
 //------------------------------------------------------------------------------
@@ -110,6 +114,7 @@
     ffdc["Procedure"]    = i_procedure.getString();
     ffdc["Priority"]     = callout::getStringFFDC(i_priority);
     addCalloutFFDC(ffdc);
+    setSrcSubsystem(i_procedure.getSrcSubsystem(), i_priority);
 }
 
 //------------------------------------------------------------------------------
@@ -135,6 +140,7 @@
     ffdc["Part Type"]    = i_part.getString();
     ffdc["Priority"]     = callout::getStringFFDC(i_priority);
     addCalloutFFDC(ffdc);
+    setSrcSubsystem(i_part.getSrcSubsystem(), i_priority);
 }
 
 //------------------------------------------------------------------------------
@@ -235,4 +241,78 @@
 
 //------------------------------------------------------------------------------
 
+void ServiceData::setSrcSubsystem(callout::SrcSubsystem i_subsystem,
+                                  callout::Priority i_priority)
+{
+    // clang-format off
+    static const std::map<callout::Priority, unsigned int> m =
+    {
+        // Note that all medium priorities, including groups A, B, and C, are
+        // the same priority.
+        {callout::Priority::HIGH,  3},
+        {callout::Priority::MED,   2},
+        {callout::Priority::MED_A, 2},
+        {callout::Priority::MED_B, 2},
+        {callout::Priority::MED_C, 2},
+        {callout::Priority::LOW,   1},
+    };
+    // clang-format on
+
+    // The default subsystem is CEC_HARDWARE with LOW priority. Change the
+    // subsystem if the given subsystem has a higher priority or if the stored
+    // subsystem is still the default.
+    if (m.at(iv_srcSubsystem.second) < m.at(i_priority) ||
+        (callout::SrcSubsystem::CEC_HARDWARE == iv_srcSubsystem.first &&
+         callout::Priority::LOW == iv_srcSubsystem.second))
+    {
+        iv_srcSubsystem.first  = i_subsystem;
+        iv_srcSubsystem.second = i_priority;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+callout::SrcSubsystem ServiceData::getTargetSubsystem(pdbg_target* i_target)
+{
+    using TargetType_t = util::pdbg::TargetType_t;
+
+    // Default the subsystem to CEC_HARDWARE
+    callout::SrcSubsystem o_subSys = callout::SrcSubsystem::CEC_HARDWARE;
+
+    // clang-format off
+    static const std::map<uint8_t, callout::SrcSubsystem> subSysMap =
+    {
+        {TargetType_t::TYPE_DIMM,     callout::SrcSubsystem::MEMORY_DIMM   },
+        {TargetType_t::TYPE_PROC,     callout::SrcSubsystem::PROCESSOR     },
+        {TargetType_t::TYPE_CORE,     callout::SrcSubsystem::PROCESSOR_UNIT},
+        {TargetType_t::TYPE_EQ,       callout::SrcSubsystem::PROCESSOR     },
+        {TargetType_t::TYPE_PEC,      callout::SrcSubsystem::PHB           },
+        {TargetType_t::TYPE_PHB,      callout::SrcSubsystem::PHB           },
+        {TargetType_t::TYPE_MC,       callout::SrcSubsystem::MEMORY        },
+        {TargetType_t::TYPE_IOLINK,   callout::SrcSubsystem::CEC_HARDWARE  },
+        {TargetType_t::TYPE_OMI,      callout::SrcSubsystem::MEMORY        },
+        {TargetType_t::TYPE_MCC,      callout::SrcSubsystem::MEMORY        },
+        {TargetType_t::TYPE_OMIC,     callout::SrcSubsystem::MEMORY        },
+        {TargetType_t::TYPE_OCMB,     callout::SrcSubsystem::MEMORY        },
+        {TargetType_t::TYPE_MEM_PORT, callout::SrcSubsystem::MEMORY        },
+        {TargetType_t::TYPE_NMMU,     callout::SrcSubsystem::PROCESSOR     },
+        {TargetType_t::TYPE_PAU,      callout::SrcSubsystem::PROCESSOR_BUS },
+        {TargetType_t::TYPE_IOHS,     callout::SrcSubsystem::PROCESSOR_BUS },
+        {TargetType_t::TYPE_PAUC,     callout::SrcSubsystem::PROCESSOR     },
+    };
+    // clang-format on
+
+    auto targetType = util::pdbg::getTrgtType(i_target);
+
+    // If the type of the input target exists in the map, update the output
+    if (subSysMap.count(targetType) > 0)
+    {
+        o_subSys = subSysMap.at(targetType);
+    }
+
+    return o_subSys;
+}
+
+//------------------------------------------------------------------------------
+
 } // namespace analyzer