meta-facebook: greatlakes: initial phopsphor-state-manager support

Added machine layer support for greatlakes to support control the
BMC, Chassis, and Host.  It supports requests to power on and off
the system by the user.

Signed-off-by: Karthikeyan Pasupathi <pkarthikeyan1509@gmail.com>
Change-Id: Ie62cc289783d47d8b50cd0c555157749f160c253
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweroff b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweroff
new file mode 100644
index 0000000..2bdf491
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweroff
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# Provide source directive to shellcheck.
+# shellcheck source=meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/power-cmd
+source /usr/libexec/power-cmd
+
+POWER_OK_SLOT=$(( $1+9 ))
+slot=$(( $1-1 ))
+OFFSET=$(( 0x9 + slot ))
+
+# Server 12v power off
+chassis-power-off()
+{
+        result=$(i2cset -y $BUS_NUM $CPLD_PWR_CTRL_ADDR $OFFSET $POW_OFF_SLOT)
+        echo "$result"
+	sleep 1
+        chassis_status=$(gpioget 0 $POWER_OK_SLOT)
+        if [ "$chassis_status" == 0 ]
+        then
+                echo "Chassis is power off"
+        else
+                echo "Chassis is already off"
+                exit 1;
+        fi
+}
+chassis-power-gpio-status()
+{
+        if [ "$slot" -le 4 ]
+        then
+                status=$(gpioget 0 $POWER_OK_SLOT)
+                if [ "$status" == 1 ]
+                then
+                        chassis-power-off
+                        exit 0;
+                else
+                        echo "Chassis is already off"
+                        exit 1;
+                fi
+        fi
+        echo "Invalid slot id"
+        exit 1;
+}
+chassis-power-gpio-status
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweroff@.service b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweroff@.service
new file mode 100644
index 0000000..b996b34
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweroff@.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=power off chassis:%i
+
+[Service]
+Type=oneshot
+ExecStart=/usr/libexec/chassis-poweroff %i
+
+[Install]
+WantedBy=obmc-chassis-hard-poweroff@%i.target
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweron b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweron
new file mode 100644
index 0000000..0e8b702
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweron
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# Provide source directive to shellcheck.
+# shellcheck source=meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/power-cmd
+source /usr/libexec/power-cmd
+
+POWER_OK_SLOT=$(( $1+9 ))
+slot=$(( $1-1 ))
+OFFSET=$(( 0x9 + slot ))
+
+# Server 12v power on
+chassis-power-on()
+{
+       result=$(i2cset -y $BUS_NUM $CPLD_PWR_CTRL_ADDR $OFFSET $POW_ON_SLOT)
+       echo "$result"
+       sleep 1
+       chassis_status=$(gpioget 0 $POWER_OK_SLOT)
+       if [ "$chassis_status" == 1 ]
+       then
+               echo "Chassis is power on"
+       else
+               echo "Chassis is already on"
+               exit 1;
+       fi
+}
+chassis-power-gpio-status()
+{
+        if [ "$slot" -le 4  ]
+        then
+                status=$(gpioget 0 $POWER_OK_SLOT)
+                if [ "$status" == 0 ]
+                then
+                        chassis-power-on
+                        exit 0;
+                else
+                        echo "Chassis is already on"
+                        exit 1;
+                fi
+        fi
+        echo "Invalid slot id"
+        exit 1;
+}
+chassis-power-gpio-status
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweron@.service b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweron@.service
new file mode 100644
index 0000000..d19d59f
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/chassis-poweron@.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=power on chassis:%i
+
+[Service]
+Type=oneshot
+ExecStart=/usr/libexec/chassis-poweron %i
+
+[Install]
+WantedBy=obmc-chassis-poweron@%i.target
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-powercycle b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-powercycle
new file mode 100644
index 0000000..ab39bcb
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-powercycle
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# Provide source directive to shellcheck.
+# shellcheck source=meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweron
+source /usr/libexec/power-cmd
+
+SLOT_ID=$(( $1-1  << 2 ))
+
+# Host Reboot
+host-reboot()
+{
+        power_delay=$1
+        for pwr_cmd in "${power_seq[@]}"
+        do
+             result="$(busctl call $SERVICE $OBJECT_PATH $INTERFACE sendRequest yyyyay $SLOT_ID $NETFN $LUN $CMD $DATA_LEN 0x01 0x42 0x01 0x00 "$pwr_cmd")"
+             echo "$result"
+             if [ "$pwr_cmd" == $POWER_BTN_LOW ]
+             then
+                     sleep "$power_delay"
+             fi
+        done
+}
+
+# Check Host Response and Status
+check-response()
+{
+   response="$(busctl call $SERVICE $OBJECT_PATH $INTERFACE sendRequest yyyyay $SLOT_ID 0x38 $LUN 0x3 0x03 0x15 0xa0 0x00)"
+
+   result=$(echo "$response" | cut -d" " -f $PWRGD_SYS_PWROK_INDEX)
+   res="$(( "$result" & 0x80  ))"
+   pgood="$(( "$res" >> 7 ))"
+   if [ "$pgood" == $STATE_ON ]
+   then
+     host-reboot 6
+     sleep 15
+     host-reboot 2
+     exit 0;
+   else
+       echo "Host is Off"
+       exit 1;
+   fi
+}
+check-response
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-powercycle@.service b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-powercycle@.service
new file mode 100644
index 0000000..57bd2a0
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-powercycle@.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Host Power Cycle: %i
+
+[Service]
+Type=oneshot
+ExecStart=/usr/libexec/host-powercycle %i
+
+[Install]
+WantedBy=obmc-host-reboot@%i.target
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweroff b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweroff
new file mode 100644
index 0000000..096e08f
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweroff
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+# Provide source directive to shellcheck.
+# shellcheck source=meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/power-cmd
+source /usr/libexec/power-cmd
+
+SLOT_ID=$(( $1-1  << 2 ))
+
+# Host Power Off
+host-power-off()
+{
+        for pwr_cmd in "${power_seq[@]}"
+        do
+             result="$(busctl call $SERVICE $OBJECT_PATH $INTERFACE sendRequest yyyyay $SLOT_ID $NETFN $LUN $CMD $DATA_LEN 0x01 0x42 0x01 0x00 "$pwr_cmd")"
+             echo "$result"
+             if [ "$pwr_cmd" == $POWER_BTN_LOW ]
+             then
+                     sleep 6
+             fi
+        done
+        echo "Host power off"
+        exit 0;
+}
+
+# Check Host Response and Status
+host-power-status()
+{
+   response="$(busctl call $SERVICE $OBJECT_PATH $INTERFACE sendRequest yyyyay $SLOT_ID 0x38 $LUN 0x3 0x03 0x15 0xa0 0x00)"
+
+   result=$(echo "$response" | cut -d" " -f $PWRGD_SYS_PWROK_INDEX)
+   res="$(( "$result" & 0x80  ))"
+   pgood="$(( "$res" >> 7 ))"
+   if [ "$pgood" == $STATE_ON ]
+   then
+         host-power-off
+   fi
+   echo "Power is already off"
+   exit 1;
+}
+host-power-status
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweroff@.service b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweroff@.service
new file mode 100644
index 0000000..69723d3
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweroff@.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=power off host:%i
+
+[Service]
+Type=oneshot
+ExecStart=/usr/libexec/host-poweroff %i
+
+[Install]
+WantedBy=obmc-host-shutdown@%i.target
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweron b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweron
new file mode 100644
index 0000000..234423e
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweron
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# Provide source directive to shellcheck.
+# shellcheck source=meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/power-cmd
+source /usr/libexec/power-cmd
+
+SLOT_ID=$(( $1-1  << 2 ))
+# Host Power On
+host-power-on()
+{
+        for pwr_cmd in "${power_seq[@]}"
+        do
+             result="$(busctl call $SERVICE $OBJECT_PATH $INTERFACE sendRequest yyyyay $SLOT_ID $NETFN $LUN $CMD $DATA_LEN 0x01 0x42 0x01 0x00 "$pwr_cmd")"
+             echo "$result"
+             if [ "$pwr_cmd" == $POWER_BTN_LOW ]
+             then
+                     sleep 2
+             fi
+        done
+        echo "Host power on"
+        exit 0;
+}
+
+# Check Host Response and Status
+host-power-status()
+{
+   response="$(busctl call $SERVICE $OBJECT_PATH $INTERFACE sendRequest yyyyay $SLOT_ID 0x38 $LUN 0x03 0x03 0x15 0xa0 0x00)"
+
+   result=$(echo "$response" | cut -d" " -f $PWRGD_SYS_PWROK_INDEX)
+   res="$(( "$result" & 0x80  ))"
+   pgood="$(( "$res" >> 7 ))"
+   if [ "$pgood" == $STATE_OFF ]
+   then
+       host-power-on
+   fi
+   echo "Power is already on"
+   exit 1;
+}
+host-power-status
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweron@.service b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweron@.service
new file mode 100644
index 0000000..a90793a
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/host-poweron@.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=power on host:%i
+
+[Service]
+Type=oneshot
+ExecStart=/usr/libexec/host-poweron %i
+
+[Install]
+WantedBy=obmc-host-start@%i.target
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/power-cmd b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/power-cmd
new file mode 100644
index 0000000..e9c7ed7
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager/greatlakes/power-cmd
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+export POWER_BTN_HIGH=0xFF
+export POWER_BTN_LOW=0xFE
+export power_seq=( "$POWER_BTN_HIGH" "$POWER_BTN_LOW" "$POWER_BTN_HIGH" )
+export SERVICE="xyz.openbmc_project.Ipmi.Channel.Ipmb"
+export OBJECT_PATH="/xyz/openbmc_project/Ipmi/Channel/Ipmb"
+export INTERFACE="org.openbmc.Ipmb"
+export DATA_LEN=0x05
+export NETFN=0x06
+export LUN=0x00
+export CMD=0x52
+export STATE_OFF=0
+export STATE_ON=1
+export BUS_NUM=12
+export POW_ON_SLOT=0x01
+export POW_OFF_SLOT=0x00
+export CPLD_PWR_CTRL_ADDR=0xf
+export PWRGD_SYS_PWROK_INDEX=12
diff --git a/meta-facebook/recipes-phosphor/state/phosphor-state-manager_%.bbappend b/meta-facebook/recipes-phosphor/state/phosphor-state-manager_%.bbappend
new file mode 100644
index 0000000..77f4be7
--- /dev/null
+++ b/meta-facebook/recipes-phosphor/state/phosphor-state-manager_%.bbappend
@@ -0,0 +1,40 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+
+DEFAULT_TARGETS = " \
+    multi-user.target.requires/obmc-host-reset@{}.target \
+    obmc-chassis-poweron@{}.target.wants/chassis-poweron@{}.service \
+    obmc-chassis-hard-poweroff@{}.target.wants/chassis-poweroff@{}.service \
+    obmc-host-shutdown@{}.target.wants/host-poweroff@{}.service \
+    obmc-host-start@{}.target.wants/host-poweron@{}.service \
+    obmc-host-reboot@{}.target.wants/host-powercycle@{}.service \
+"
+
+SRC_URI:append:greatlakes = " \
+    file://chassis-poweroff@.service \
+    file://chassis-poweron@.service \
+    file://host-poweroff@.service \
+    file://host-poweron@.service \
+    file://host-powercycle@.service \
+    file://chassis-poweroff \
+    file://chassis-poweron \
+    file://host-poweroff \
+    file://host-poweron \
+    file://host-powercycle \
+    file://power-cmd \
+    "
+
+RDEPENDS:${PN}:append:greatlakes = " bash"
+
+do_install:append:greatlakes() {
+    install -d ${D}${systemd_system_unitdir}
+    install -m 0644 ${WORKDIR}/*.service ${D}${systemd_system_unitdir}/
+
+    install -d ${D}${libexecdir}
+    install -m 0777 ${WORKDIR}/chassis-poweroff ${D}${libexecdir}/
+    install -m 0777 ${WORKDIR}/chassis-poweron ${D}${libexecdir}/
+    install -m 0777 ${WORKDIR}/host-poweroff ${D}${libexecdir}/
+    install -m 0777 ${WORKDIR}/host-poweron ${D}${libexecdir}/
+    install -m 0777 ${WORKDIR}/host-powercycle ${D}${libexecdir}/
+    install -m 0777 ${WORKDIR}/power-cmd ${D}${libexecdir}/
+}
+FILES:${PN} += " /lib/systemd/system/*.service"