From 8f221bfb0979fa018f6c16b5af153c1549448e7d Mon Sep 17 00:00:00 2001 From: Tung Nguyen Date: Wed, 16 Dec 2020 05:52:18 +0000 Subject: meta-ampere: Support Ampere power control Implement the Ampere power control requirements for Altra system. Tested: - Check the ipmi commands: ipmi power on/off/soft/reset/cycle - Check the redfish commands: On, Off, ForceOn, ForceOff, GracefulShutdown, GracefulRestart, ForceRestart, PowerCycle Signed-off-by: Tung Nguyen Change-Id: Id0c64c1284a6338ce47ca720d0ef75e99d21aa3c --- .../recipes-ac01/host/ampere-hostctrl.bb | 85 ++++++++++++++++ .../ampere-chassis-poweroff.service | 11 +++ .../ampere-hostctrl/ampere-chassis-poweron.service | 9 ++ .../ampere-host-force-reset.service | 11 +++ .../ampere-host-power-cycle.service | 10 ++ .../ampere-hostctrl/ampere-host-reset-ack.service | 10 ++ .../host/ampere-hostctrl/ampere-host-reset.service | 9 ++ .../ampere-hostctrl/ampere-host-shutdown.service | 10 ++ .../recipes-ac01/host/files/ampere_power_util.sh | 109 +++++++++++++++++++++ .../recipes-ac01/host/files/obmc/gpio/reboot_ack | 4 + .../recipes-ac01/host/files/obmc/gpio/shutdown_ack | 4 + .../packagegroups/packagegroup-ampere-apps.bb | 27 +++++ .../state/phosphor-state-manager/resetreason.conf | 2 + .../state/phosphor-state-manager_%.bbappend | 24 +++++ 14 files changed, 325 insertions(+) create mode 100644 meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb create mode 100644 meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service create mode 100644 meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweron.service create mode 100644 meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-force-reset.service create mode 100644 meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-power-cycle.service create mode 100644 meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset-ack.service create mode 100644 meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset.service create mode 100644 meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service create mode 100644 meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh create mode 100644 meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/reboot_ack create mode 100644 meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/shutdown_ack create mode 100644 meta-ampere/meta-common/recipes-ac01/packagegroups/packagegroup-ampere-apps.bb create mode 100644 meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager/resetreason.conf create mode 100644 meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend (limited to 'meta-ampere') diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb new file mode 100644 index 0000000000..e7c3cc160e --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb @@ -0,0 +1,85 @@ +SUMMARY = "Ampere Computing LLC Host Control Implementation" +DESCRIPTION = "A host control implementation suitable for Ampere Computing LLC's systems" +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd +inherit obmc-phosphor-systemd + +# For now, monitoring shutdown_ack and reboot_ack are the only usecases +OBMC_HOST_MONITOR_INSTANCES = "shutdown_ack reboot_ack" +SYSTEMD_ENVIRONMENT_FILE_${PN} +="obmc/gpio/shutdown_ack obmc/gpio/reboot_ack" + +S = "${WORKDIR}" + +SRC_URI = "file://ampere-host-shutdown.service \ + file://ampere-host-reset.service \ + file://ampere_power_util.sh \ + file://ampere-chassis-poweroff.service \ + file://ampere-chassis-poweron.service \ + file://ampere-host-reset-ack.service \ + file://ampere-host-force-reset.service \ + file://ampere-host-power-cycle.service \ + " + +DEPENDS = "systemd virtual/obmc-gpio-monitor" +RDEPENDS_${PN} = "bash virtual/obmc-gpio-monitor" + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = " \ + ampere-host-shutdown.service \ + ampere-host-reset.service \ + ampere-chassis-poweroff.service \ + ampere-chassis-poweron.service \ + ampere-host-reset-ack.service \ + ampere-host-force-reset.service \ + ampere-host-power-cycle.service \ + " +# host power control +# overwrite the host shutdown to graceful shutdown +HOST_SHUTDOWN_TMPL = "ampere-host-shutdown.service" +HOST_SHUTDOWN_TGTFMT = "obmc-host-shutdown@{0}.target" +HOST_SHUTDOWN_FMT = "../${HOST_SHUTDOWN_TMPL}:${HOST_SHUTDOWN_TGTFMT}.requires/${HOST_SHUTDOWN_TMPL}" +SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_SHUTDOWN_FMT', 'OBMC_HOST_INSTANCES')}" + +# Force the power cycle target to run the ampere power cycle +HOST_REBOOT_SVC = "ampere-host-power-cycle.service" +HOST_REBOOT_SVC_TGTFMT = "obmc-host-reboot@{0}.target" +HOST_REBOOT_SVC_FMT = "../${HOST_REBOOT_SVC}:${HOST_REBOOT_SVC_TGTFMT}.requires/${HOST_REBOOT_SVC}" +SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_REBOOT_SVC_FMT', 'OBMC_HOST_INSTANCES')}" + +# overwrite the host reset to graceful reset +HOST_WARM_REBOOT_SOFT_SVC = "ampere-host-reset.service" +HOST_WARM_REBOOT_TGTFMT = "obmc-host-warm-reboot@{0}.target" +HOST_WARM_REBOOT_SOFT_SVC_FMT = "../${HOST_WARM_REBOOT_SOFT_SVC}:${HOST_WARM_REBOOT_TGTFMT}.requires/${HOST_WARM_REBOOT_SOFT_SVC}" +SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_WARM_REBOOT_SOFT_SVC_FMT', 'OBMC_HOST_INSTANCES')}" + +# overwrite force reboot +HOST_WARM_REBOOT_FORCE_TGT = "ampere-host-force-reset.service" +HOST_WARM_REBOOT_FORCE_TGTFMT = "obmc-host-force-warm-reboot@{0}.target" +HOST_WARM_REBOOT_FORCE_TARGET_FMT = "../${HOST_WARM_REBOOT_FORCE_TGT}:${HOST_WARM_REBOOT_FORCE_TGTFMT}.requires/${HOST_WARM_REBOOT_FORCE_TGT}" +SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_WARM_REBOOT_FORCE_TARGET_FMT', 'OBMC_HOST_INSTANCES')}" + +# chassis power control +CHASSIS_POWERON_SVC = "ampere-chassis-poweron.service" +CHASSIS_POWERON_TGTFMT = "obmc-chassis-poweron@{0}.target" +CHASSIS_POWERON_FMT = "../${CHASSIS_POWERON_SVC}:${CHASSIS_POWERON_TGTFMT}.requires/${CHASSIS_POWERON_SVC}" +SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'CHASSIS_POWERON_FMT', 'OBMC_CHASSIS_INSTANCES')}" + +CHASSIS_POWEROFF_SVC = "ampere-chassis-poweroff.service" +CHASSIS_POWEROFF_TGTFMT = "obmc-chassis-poweroff@{0}.target" +CHASSIS_POWEROFF_FMT = "../${CHASSIS_POWEROFF_SVC}:${CHASSIS_POWEROFF_TGTFMT}.requires/${CHASSIS_POWEROFF_SVC}" +SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'CHASSIS_POWEROFF_FMT', 'OBMC_CHASSIS_INSTANCES')}" + +TMPL = "phosphor-gpio-monitor@.service" +INSTFMT = "phosphor-gpio-monitor@{0}.service" +TGT = "multi-user.target" +FMT = "../${TMPL}:${TGT}.requires/${INSTFMT}" +SYSTEMD_LINK_${PN} += "${@compose_list(d, 'FMT', 'OBMC_HOST_MONITOR_INSTANCES')}" + +do_install() { + install -d ${D}/usr/sbin + install -m 0755 ${WORKDIR}/ampere_power_util.sh ${D}/${sbindir}/ampere_power_util.sh +} + diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service new file mode 100644 index 0000000000..b0a1af7855 --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service @@ -0,0 +1,11 @@ +[Unit] +Description=Ampere Computing LLC Power OFF Chassis +Requires=op-wait-power-off@%i.service +Before=op-wait-power-off@%i.service +Conflicts=obmc-chassis-poweron@0.target + +[Service] +RemainAfterExit=no +Type=oneshot +ExecStart=/usr/bin/env ampere_power_util.sh mb off +SyslogIdentifier=ampere_power_util.sh diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweron.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweron.service new file mode 100644 index 0000000000..76ceb88560 --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweron.service @@ -0,0 +1,9 @@ +[Unit] +Description=Ampere Computing LLC Power ON Chassis +Conflicts=obmc-chassis-poweroff@0.target + +[Service] +RemainAfterExit=yes +Type=oneshot +ExecStart=/usr/bin/env ampere_power_util.sh mb on +SyslogIdentifier=ampere_power_util.sh diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-force-reset.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-force-reset.service new file mode 100644 index 0000000000..8a40baf7bd --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-force-reset.service @@ -0,0 +1,11 @@ +[Unit] +Description=Ampere Computing LLC force reset host +Conflicts=obmc-chassis-poweroff@0.target +OnFailure=obmc-chassis-powerreset@0.target + +[Service] +RemainAfterExit=no +Type=oneshot +ExecStart=/usr/bin/env ampere_power_util.sh mb force_reset +SyslogIdentifier=ampere_power_util.sh + diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-power-cycle.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-power-cycle.service new file mode 100644 index 0000000000..2fb03effb7 --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-power-cycle.service @@ -0,0 +1,10 @@ +[Unit] +Description=Ampere Computing LLC power cycle service +Conflicts=obmc-host-start@0.target +OnFailure=obmc-chassis-powerreset@0.target + +[Service] +RemainAfterExit=no +Type=oneshot +ExecStart=/usr/bin/env ampere_power_util.sh mb cycle +SyslogIdentifier=ampere_power_util.sh diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset-ack.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset-ack.service new file mode 100644 index 0000000000..504186ec67 --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset-ack.service @@ -0,0 +1,10 @@ +[Unit] +Description=Ampere Computing LLC triggering reset ACK +Conflicts=obmc-host-start@0.target +OnFailure=obmc-chassis-powerreset@0.target + +[Service] +RemainAfterExit=no +Type=oneshot +ExecStart=/usr/bin/env ampere_power_util.sh mb force_reset +SyslogIdentifier=ampere_power_util.sh diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset.service new file mode 100644 index 0000000000..ac7618ad0d --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-reset.service @@ -0,0 +1,9 @@ +[Unit] +Description=Ampere Computing LLC warm reset host +Conflicts=obmc-chassis-poweroff@0.target + +[Service] +RemainAfterExit=no +Type=oneshot +ExecStart=/usr/bin/env ampere_power_util.sh mb graceful_reset +SyslogIdentifier=ampere_power_util.sh diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service new file mode 100644 index 0000000000..be4d45260a --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service @@ -0,0 +1,10 @@ +[Unit] +Description=Ampere Computing LLC graceful shutdown host +Conflicts=obmc-host-start@0.target +OnFailure=obmc-chassis-poweroff@0.target + +[Service] +RemainAfterExit=no +Type=oneshot +ExecStart=/usr/bin/env ampere_power_util.sh mb graceful_shutdown +SyslogIdentifier=ampere_power_util.sh diff --git a/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh b/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh new file mode 100644 index 0000000000..8bab9a3707 --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh @@ -0,0 +1,109 @@ +#!/bin/bash +# Usage of this utility +function usage() { + echo "usage: power-util mb [on|off|status|cycle|reset|graceful_shutdown|graceful_reset|force_reset]"; +} + +power_off() { + echo "Shutting down Server $2" + busctl set-property xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis RequestedPowerTransition s xyz.openbmc_project.State.Chassis.Transition.Off +} + +power_on() { + echo "Powering on Server $2" + busctl set-property xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis RequestedPowerTransition s xyz.openbmc_project.State.Chassis.Transition.On +} + +power_status() { + st=$(busctl get-property xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis CurrentPowerState | cut -d"." -f6) + if [ "$st" == "On\"" ]; then + echo "on" + else + echo "off" + fi +} + +power_reset() { + echo "Reset on server $2" + busctl set-property xyz.openbmc_project.State.Host /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host RequestedHostTransition s xyz.openbmc_project.State.Host.Transition.Reboot +} + +graceful_shutdown() { + if [ -f "/run/openbmc/host@0-request" ]; then + echo "shutdown host immediately" + power_off + else + echo "Triggering graceful shutdown" + gpioset -l 0 49=1 + sleep 1 + gpioset -l 0 49=0 + sleep 30s + fi +} + +force_reset() { + echo "Triggering sysreset pin" + gpioset -l 0 91=1 + sleep 1 + gpioset -l 0 91=0 +} + +if [ $# -lt 2 ]; then + echo "Total number of parameter=$#" + echo "Insufficient parameter" + usage; + exit 0; +fi + +if [ $1 != "mb" ]; then + echo "Invalid parameter1=$1" + usage; + exit 0; +fi + +if [ $2 = "on" ]; then + if [ $(power_status) == "off" ]; then + power_on + fi +elif [ $2 = "off" ]; then + if [ $(power_status) == "on" ]; then + power_off + fi + # If any request of graceful reset, need to power on + if [ -f "/run/openbmc/host@0-graceful-reset" ]; then + sleep 20s + power_on + rm -f "/run/openbmc/host@0-graceful-reset" + fi +elif [ $2 == "cycle" ]; then + if [ $(power_status) == "on" ]; then + echo "Powering off server" + power_off + sleep 20s + power_on + else + echo "Host is already off, do nothing" + fi +elif [ $2 == "reset" ]; then + if [ $(power_status) == "on" ]; then + power_reset + else + echo "ERROR: Server not powered on" + fi +elif [[ $2 == "graceful_shutdown" ]]; then + graceful_shutdown +elif [ $2 == "graceful_reset" ]; then + mkdir -p "/run/openbmc/" + touch "/run/openbmc/host@0-graceful-reset" + graceful_shutdown + sleep 20s +elif [ $2 == "status" ]; then + power_status +elif [ $2 == "force_reset" ]; then + force_reset +else + echo "Invalid parameter2=$2" + usage; +fi + +exit 0; diff --git a/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/reboot_ack b/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/reboot_ack new file mode 100644 index 0000000000..0436d32da1 --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/reboot_ack @@ -0,0 +1,4 @@ +DEVPATH=/dev/input/event0 +KEY=75 +POLARITY=1 +TARGET=ampere-host-reset-ack.service diff --git a/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/shutdown_ack b/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/shutdown_ack new file mode 100644 index 0000000000..a0e857fac4 --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/host/files/obmc/gpio/shutdown_ack @@ -0,0 +1,4 @@ +DEVPATH=/dev/input/event0 +KEY=50 +POLARITY=1 +TARGET=ampere-chassis-poweroff.service diff --git a/meta-ampere/meta-common/recipes-ac01/packagegroups/packagegroup-ampere-apps.bb b/meta-ampere/meta-common/recipes-ac01/packagegroups/packagegroup-ampere-apps.bb new file mode 100644 index 0000000000..2990d8ec03 --- /dev/null +++ b/meta-ampere/meta-common/recipes-ac01/packagegroups/packagegroup-ampere-apps.bb @@ -0,0 +1,27 @@ +SUMMARY = "OpenBMC for Ampere - Applications" +PR = "r1" + +inherit packagegroup +inherit obmc-phosphor-utils + +PROVIDES = "${PACKAGES}" +PACKAGES = " \ + ${PN}-chassis \ + ${PN}-system \ + " + +PROVIDES += "virtual/obmc-chassis-mgmt" +PROVIDES += "virtual/obmc-system-mgmt" + +RPROVIDES_${PN}-chassis += "virtual-obmc-chassis-mgmt" +RPROVIDES_${PN}-system += "virtual-obmc-system-mgmt" + +SUMMARY_${PN}-chassis = "Ampere Chassis" +RDEPENDS_${PN}-chassis = " \ + obmc-op-control-power \ + ampere-hostctrl \ + " + +SUMMARY_${PN}-system = "Ampere System" +RDEPENDS_${PN}-system = " \ + " diff --git a/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager/resetreason.conf b/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager/resetreason.conf new file mode 100644 index 0000000000..828d98b8e6 --- /dev/null +++ b/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager/resetreason.conf @@ -0,0 +1,2 @@ +[Unit] +ConditionKernelCommandLine=resetreason=power diff --git a/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend b/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend new file mode 100644 index 0000000000..d54407ba3f --- /dev/null +++ b/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend @@ -0,0 +1,24 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +DEPS_CFG = "resetreason.conf" +DEPS_TGT = "phosphor-discover-system-state@.service" +SYSTEMD_OVERRIDE_${PN}-discover_append = "${DEPS_CFG}:${DEPS_TGT}.d/${DEPS_CFG}" + +# We don't want the obmc-host-shutdown (softoff) to require +# obmc-chassis-poweroff. obmc-chassis-poweroff will be activated once +# the Shutdown ACK pin is toggled (monitored by phosphor-gpio-monitor) +HOST_STOP_FMT = "" +HOST_REBOOT_FMT = "" + +pkg_postinst_${PN}-obmc-targets_append() { + rm "$D$systemd_system_unitdir/obmc-host-shutdown@0.target.requires/obmc-chassis-poweroff@0.target" + + rm "$D$systemd_system_unitdir/obmc-host-warm-reboot@0.target.requires/xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service" + rm "$D$systemd_system_unitdir/obmc-host-warm-reboot@0.target.requires/obmc-host-force-warm-reboot@0.target" + + rm "$D$systemd_system_unitdir/obmc-host-reboot@0.target.requires/phosphor-reboot-host@0.service" + rm "$D$systemd_system_unitdir/obmc-host-reboot@0.target.requires/obmc-host-shutdown@0.target" + + rm "$D$systemd_system_unitdir/obmc-host-force-warm-reboot@0.target.requires/obmc-host-stop@0.target" + rm "$D$systemd_system_unitdir/obmc-host-force-warm-reboot@0.target.requires/phosphor-reboot-host@0.service" +} -- cgit v1.2.3