nmi: Use libpdbg directly

This avoids calling DBus to run a systemd unit that is effectively a
shell script when we already have libpdbg on the system anyway.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I9a36c38f075d402b9bc406433475a371d1cdbe62
diff --git a/Makefile.am b/Makefile.am
index 1280311..d9760ca 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,8 +2,7 @@
 
 systemdsystemunit_DATA = \
   pcie-poweroff@.service \
-  xyz.openbmc_project.Control.Host.NMI.service \
-  nmi.service
+  xyz.openbmc_project.Control.Host.NMI.service
 
 bin_PROGRAMS = \
 	openpower-proc-control \
diff --git a/configure.ac b/configure.ac
index ece0591..ce8e755 100644
--- a/configure.ac
+++ b/configure.ac
@@ -45,6 +45,8 @@
     [${srcdir}/gen_makefile.sh ${srcdir} "$myChips" > Makefile.generated],
     [myChips="$CHIPS"])
 
+AC_CHECK_LIB([pdbg], [thread_sreset_all])
+
 PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 221])
 PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging])
 PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces])
@@ -68,5 +70,4 @@
 AC_CONFIG_FILES([Makefile test/Makefile])
 AC_CONFIG_FILES([pcie-poweroff@.service])
 AC_CONFIG_FILES([xyz.openbmc_project.Control.Host.NMI.service])
-AC_CONFIG_FILES([nmi.service])
 AC_OUTPUT
diff --git a/nmi.service.in b/nmi.service.in
deleted file mode 100644
index 304faea..0000000
--- a/nmi.service.in
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Enable Open Power NMI service
-
-[Service]
-Type=oneshot
-RemainAfterExit=no
-ExecStart=@bindir@/pdbg -a stop
-ExecStart=@bindir@/pdbg -a sreset
-SyslogIdentifier=openpower-proc-nmi
-
diff --git a/nmi_interface.cpp b/nmi_interface.cpp
index aea38ae..fcce451 100644
--- a/nmi_interface.cpp
+++ b/nmi_interface.cpp
@@ -16,6 +16,8 @@
 
 #include "nmi_interface.hpp"
 
+#include <libpdbg.h>
+
 #include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/elog.hpp>
 #include <xyz/openbmc_project/Common/error.hpp>
@@ -33,24 +35,27 @@
 void NMI::nMI()
 {
     using namespace phosphor::logging;
-    using sdbusplus::exception::SdBusError;
     using InternalFailure =
         sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
 
-    constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
-    constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
-    constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
+    struct pdbg_target* target;
 
-    auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
-                                      SYSTEMD_INTERFACE, "StartUnit");
-    method.append("nmi.service", "replace");
-    try
+    pdbg_for_each_class_target("thread", target)
     {
-        bus.call_noreply(method);
+        if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)
+            continue;
+
+        if (thread_stop(target) < 0 || !thread_status(target).quiesced)
+        {
+            log<level::ERR>("Failed to stop all threads");
+            report<InternalFailure>();
+            return;
+        }
     }
-    catch (const SdBusError& e)
+
+    if (thread_sreset_all() < 0)
     {
-        log<level::ALERT>("Error in starting NMI service. ");
+        log<level::ERR>("Failed to sreset all threads");
         report<InternalFailure>();
     }
 }
diff --git a/nmi_main.cpp b/nmi_main.cpp
index dafc9b1..3a12bce 100644
--- a/nmi_main.cpp
+++ b/nmi_main.cpp
@@ -16,6 +16,8 @@
 
 #include "nmi_interface.hpp"
 
+#include <libpdbg.h>
+
 #include <sdbusplus/bus.hpp>
 
 int main(int argc, char* argv[])
@@ -25,6 +27,8 @@
     constexpr auto BUSNAME_NMI = "xyz.openbmc_project.Control.Host.NMI";
     auto bus = sdbusplus::bus::new_default();
 
+    pdbg_targets_init(NULL);
+
     // Add sdbusplus ObjectManager
     sdbusplus::server::manager::manager objManager(bus, BUSPATH_NMI);
     openpower::proc::NMI NMI(bus, BUSPATH_NMI);