phal: Added proc-pre-poweroff support
Changes:
-Adding new service which will be called during
chassis poweroff.
Test:
-Did poweroff to check, if the service file
is getting picked up or not and new added
procedure is getting called.
Signed-off-by: Chirag Sharma <chirshar@in.ibm.com>
Signed-off-by: Ramesh Iyyar <rameshi1@in.ibm.com>
Change-Id: Ic533433c4771216e5681b61cccf154f7ed029457
diff --git a/Makefile.am b/Makefile.am
index 895e28c..bdf512a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,7 +10,8 @@
if ENABLE_PHAL
systemdsystemunit_DATA += set-spi-mux.service \
- phal-reinit-devtree.service
+ phal-reinit-devtree.service \
+ proc-pre-poweroff@.service
endif
bin_PROGRAMS = \
diff --git a/configure.ac b/configure.ac
index ebe40bc..a9b6c53 100644
--- a/configure.ac
+++ b/configure.ac
@@ -83,6 +83,7 @@
CHIPS+=" phal common"
AC_CONFIG_FILES([set-spi-mux.service])
AC_CONFIG_FILES([phal-reinit-devtree.service])
+ AC_CONFIG_FILES([proc-pre-poweroff@.service])
]
)
diff --git a/meson.build b/meson.build
index 173f2ee..bb9c5e9 100644
--- a/meson.build
+++ b/meson.build
@@ -64,6 +64,8 @@
extra_sources += [
'procedures/phal/start_host.cpp',
'procedures/phal/set_SPI_mux.cpp',
+ 'procedures/phal/proc_pre_poweroff.cpp',
+ 'procedures/phal/common_utils.cpp',
'phalerror/create_pel.cpp',
'phalerror/phal_error.cpp',
]
@@ -76,6 +78,7 @@
extra_unit_files = [
'set-spi-mux.service',
'phal-reinit-devtree.service',
+ 'proc-pre-poweroff@.service',
]
unit_subs.set('ENABLE_PHAL_TRUE', '')
endif
diff --git a/proc-pre-poweroff@.service.in b/proc-pre-poweroff@.service.in
new file mode 100644
index 0000000..c665841
--- /dev/null
+++ b/proc-pre-poweroff@.service.in
@@ -0,0 +1,15 @@
+[Unit]
+Description=Preparation to poweroff host%i
+Wants=op-cfam-reset.service
+Before=op-cfam-reset.service
+Wants=obmc-power-stop-pre@%i.target
+Before=obmc-power-stop-pre@%i.target
+Conflicts=obmc-chassis-poweron@%i.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+ExecStart=/usr/bin/openpower-proc-control prePoweroff
+
+[Install]
+WantedBy=obmc-power-stop-pre@%i.target
diff --git a/procedures/phal/common_utils.cpp b/procedures/phal/common_utils.cpp
new file mode 100644
index 0000000..99daa7b
--- /dev/null
+++ b/procedures/phal/common_utils.cpp
@@ -0,0 +1,49 @@
+extern "C"
+{
+#include <libpdbg.h>
+}
+
+#include "phalerror/phal_error.hpp"
+#include "procedures/phal/common_utils.hpp"
+
+#include <libekb.H>
+
+#include <phosphor-logging/log.hpp>
+
+namespace openpower
+{
+namespace phal
+{
+
+using namespace phosphor::logging;
+
+void phal_init(enum ipl_mode mode)
+{
+ // TODO: Setting boot error callback should not be in common code
+ // because, we wont get proper reason in PEL for failure.
+ // So, need to make code like caller of this function pass error
+ // handling callback.
+ // add callback methods for debug traces and for boot failures
+ openpower::pel::addBootErrorCallbacks();
+
+ if (!pdbg_targets_init(NULL))
+ {
+ log<level::ERR>("pdbg_targets_init failed");
+ throw std::runtime_error("pdbg target initialization failed");
+ }
+
+ if (libekb_init())
+ {
+ log<level::ERR>("libekb_init failed");
+ throw std::runtime_error("libekb initialization failed");
+ }
+
+ if (ipl_init(mode) != 0)
+ {
+ log<level::ERR>("ipl_init failed");
+ throw std::runtime_error("libipl initialization failed");
+ }
+}
+
+} // namespace phal
+} // namespace openpower
diff --git a/procedures/phal/common_utils.hpp b/procedures/phal/common_utils.hpp
new file mode 100644
index 0000000..f9703bc
--- /dev/null
+++ b/procedures/phal/common_utils.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <libipl.H>
+
+namespace openpower
+{
+namespace phal
+{
+
+/**
+ * @brief This function will initialize required phal
+ * libraries.
+ * Throws an exception on error.
+ *
+ * @param[in] mode - IPL mode, default IPL_AUTOBOOT
+ *
+ */
+void phal_init(enum ipl_mode mode = IPL_AUTOBOOT);
+
+} // namespace phal
+} // namespace openpower
diff --git a/procedures/phal/proc_pre_poweroff.cpp b/procedures/phal/proc_pre_poweroff.cpp
new file mode 100644
index 0000000..3997b19
--- /dev/null
+++ b/procedures/phal/proc_pre_poweroff.cpp
@@ -0,0 +1,49 @@
+#include "phalerror/phal_error.hpp"
+#include "procedures/phal/common_utils.hpp"
+#include "registration.hpp"
+
+#include <libekb.H>
+
+#include <phosphor-logging/log.hpp>
+
+namespace openpower
+{
+namespace phal
+{
+
+using namespace phosphor::logging;
+
+void prePoweroff(void)
+{
+ try
+ {
+ phal_init();
+ }
+ catch (const std::exception& ex)
+ {
+ log<level::ERR>("Exception raised during init PHAL",
+ entry("EXCEPTION=%s", ex.what()));
+ openpower::pel::detail::processBootErrorCallback(false);
+ // Dont throw exception on failure because, we need to proceed
+ // further eventhough there is failure for proc-pre-poweroff
+ return;
+ }
+
+ // To clear trace if success
+ openpower::pel::detail::processBootErrorCallback(true);
+
+ // callback method will be called upon failure which will create the PEL
+ int rc = ipl_pre_poweroff();
+ if (rc)
+ {
+ log<level::ERR>("pre_poweroff failed");
+ // Dont throw exception on failure because, we need to proceed
+ // further eventhough there is failure for proc-pre-poweroff
+ return;
+ }
+}
+
+REGISTER_PROCEDURE("prePoweroff", prePoweroff)
+
+} // namespace phal
+} // namespace openpower
diff --git a/procedures/phal/start_host.cpp b/procedures/phal/start_host.cpp
index b82a584..c1f39a6 100644
--- a/procedures/phal/start_host.cpp
+++ b/procedures/phal/start_host.cpp
@@ -6,9 +6,9 @@
#include "attributes_info.H"
#include "phalerror/phal_error.hpp"
+#include "procedures/phal/common_utils.hpp"
#include <libekb.H>
-#include <libipl.H>
#include <ext_interface.hpp>
#include <phosphor-logging/log.hpp>
@@ -120,35 +120,18 @@
*/
void startHost(enum ipl_type iplType = IPL_TYPE_NORMAL)
{
- // add callback methods for debug traces and for boot failures
- openpower::pel::addBootErrorCallbacks();
-
- if (!pdbg_targets_init(NULL))
+ try
{
- log<level::ERR>("pdbg_targets_init failed");
- openpower::pel::detail::processBootErrorCallback(false);
- throw std::runtime_error("pdbg target initialization failed");
+ phal_init();
+ ipl_set_type(iplType);
}
- // To clear trace if success
- openpower::pel::detail::processBootErrorCallback(true);
-
- if (libekb_init())
+ catch (std::exception& ex)
{
- log<level::ERR>("libekb_init failed");
+ log<level::ERR>("Exception raised during init PHAL",
+ entry("EXCEPTION=%s", ex.what()));
openpower::pel::detail::processBootErrorCallback(false);
- throw std::runtime_error("libekb initialization failed");
+ throw std::runtime_error("PHAL initialization failed");
}
- // To clear trace if success
- openpower::pel::detail::processBootErrorCallback(true);
-
- if (ipl_init(IPL_AUTOBOOT) != 0)
- {
- log<level::ERR>("ipl_init failed");
- openpower::pel::detail::processBootErrorCallback(false);
- throw std::runtime_error("Boot initialization failed");
- }
-
- ipl_set_type(iplType);
// To clear trace if success
openpower::pel::detail::processBootErrorCallback(true);