meta-ampere: host-check: verify the host state

When phosphor-state-manager handles the power action to turn on the
host, phosphor-state-manager does not use the software interfaces to
verify the host state. It set the host state to running after all of
required services of the power action target are done. The power on
watchdog is used to verify the host state and handle the failure in
the host state changing. But Mt.Jade platforms do not handle power on
watchdog. This causes the CurrentHostState dbus property is Running
before the host is ready.

In Mt.Jade platform, the SCP drives S0_FW_BOOT_OK to high when the
host is already on. This GPIO can be used to identify the host state.
One service should be added to the required list. This service checks
the host state in power on and triggers obmc-host-quiesce@%i.target
when the host is failed to boot. ampere-host-check package adds
ampere-host-on-host-check@.service for that purpose.

Tested:
    1. Boot up BMC with the host is off/on. Check CurrentHostState.
    2. Call Ipmitool power off/on. Check the CurrentHostState.
    3. Call Ipmitool chassis power off/on. Check the CurrentHostState.
    4. Call Ipmitool power cycle. Check the CurrentHostState.
    5. Call Ipmitool chassis power cycle. Check the CurrentHostState.
    6. Power off the host. Set power policty to Always-on. AC power.
    The host should be on. And CurrentHostState should be Running.
    7. Power on the host. Set power policty to Always-off. AC power.
    The host should be off. And CurrentHostState should be Off.

Change-Id: I9b0b346883a5f0203bf078453065c18ae4603311
Signed-off-by: ThuBaNguyen <thu@os.amperecomputing.com>
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb
index cfefa8d..5c4b6a0 100644
--- a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb
@@ -11,6 +11,7 @@
 
 SRC_URI = " \
           file://ampere-host-force-reset@.service \
+          file://ampere-host-on-host-check@.service \
           "
 
 SYSTEMD_PACKAGES = "${PN}"
@@ -24,4 +25,11 @@
 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_INSTMPL}"
 SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_WARM_REBOOT_FORCE_TARGET_FMT', 'OBMC_HOST_INSTANCES')}"
+SYSTEMD_SERVICE_${PN} += "${HOST_WARM_REBOOT_FORCE_TGT}"
 
+HOST_ON_RESET_HOSTTMPL = "ampere-host-on-host-check@.service"
+HOST_ON_RESET_HOSTINSTMPL = "ampere-host-on-host-check@{0}.service"
+HOST_ON_RESET_HOSTTGTFMT = "obmc-host-startmin@{0}.target"
+HOST_ON_RESET_HOSTFMT = "../${HOST_ON_RESET_HOSTTMPL}:${HOST_ON_RESET_HOSTTGTFMT}.requires/${HOST_ON_RESET_HOSTINSTMPL}"
+SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_ON_RESET_HOSTFMT', 'OBMC_HOST_INSTANCES')}"
+SYSTEMD_SERVICE_${PN} += "${HOST_ON_RESET_HOSTTMPL}"
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-on-host-check@.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-on-host-check@.service
new file mode 100644
index 0000000..36e5a64
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-on-host-check@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Check Host%i status before obmc-host-startmin
+Wants=obmc-host-started@%i.target
+After=obmc-host-started@%i.target
+Conflicts=obmc-host-stop@%i.target
+Conflicts=phosphor-reset-host-check@%i.service
+OnFailure=obmc-host-quiesce@%i.target
+OnFailureJobMode=flush
+ConditionPathExists=!/run/openbmc/host@%i-on
+
+[Service]
+Type=oneshot
+ExecStart=/usr/sbin/ampere_host_check.sh 1 0
diff --git a/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils.bb b/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils.bb
index 184d643..159ccdd 100644
--- a/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils.bb
+++ b/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils.bb
@@ -6,13 +6,17 @@
 
 SRC_URI = " \
           file://gpio-defs.sh \
+          file://gpio-lib.sh \
           file://ampere_power_util.sh \
+          file://ampere_host_check.sh \
           "
 
 RDEPENDS_${PN} = "bash"
 
 do_install() {
     install -d ${D}/usr/sbin
+    install -m 0755 ${WORKDIR}/gpio-lib.sh ${D}/${sbindir}/
     install -m 0755 ${WORKDIR}/gpio-defs.sh ${D}/${sbindir}/
     install -m 0755 ${WORKDIR}/ampere_power_util.sh ${D}/${sbindir}/
+    install -m 0755 ${WORKDIR}/ampere_host_check.sh ${D}/${sbindir}/
 }
\ No newline at end of file
diff --git a/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils/ampere_host_check.sh b/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils/ampere_host_check.sh
new file mode 100644
index 0000000..9eeeeca
--- /dev/null
+++ b/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils/ampere_host_check.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+source /usr/sbin/gpio-defs.sh
+source /usr/sbin/gpio-lib.sh
+
+host_status() {
+    st=$(busctl get-property xyz.openbmc_project.State.Host /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host CurrentHostState | cut -d"." -f6)
+    if [ "$st" == "Running\"" ]; then
+        echo "on"
+    else
+        echo "off"
+    fi
+}
+
+createFile=$1
+setState=$2
+
+if [ $(host_status) == "on" ]; then
+    exit 0
+fi
+
+# Time out to check S0_FW_BOOT_OK is 60 seconds
+cnt=60
+val=0
+while [ $cnt -gt 0 ];
+do
+    val=$(gpio_get_val $S0_CPU_FW_BOOT_OK)
+    cnt=$((cnt - 1))
+    echo "$cnt S0_CPU_FW_BOOT_OK = $val"
+    if [ $val == 1 ]; then
+        # Sleep 5 second before the host is ready
+        sleep 5
+        if [ $createFile == 1 ]; then
+            if [ ! -d "/run/openbmc" ]; then
+                mkdir -p /run/openbmc
+            fi
+            echo "Creating /run/openbmc/host@0-on"
+            touch /run/openbmc/host@0-on
+        fi
+        exit 0
+    fi
+    sleep 1
+done
+
+exit 1
diff --git a/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils/gpio-lib.sh b/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils/gpio-lib.sh
new file mode 100644
index 0000000..fcc2d54
--- /dev/null
+++ b/meta-ampere/meta-jade/recipes-ampere/platform/mtjade-utils/gpio-lib.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+function gpio_number() {
+	GPIO_BASE=$(cat /sys/class/gpio/gpio*/base)
+	echo $((${GPIO_BASE} + $1))
+}
+
+# Configure GPIO as output and set its value
+function gpio_configure_output() {
+	gpioId=$(gpio_number $1)
+	echo $gpioId > /sys/class/gpio/export
+	echo out > /sys/class/gpio/gpio${gpioId}/direction
+	echo $2 > /sys/class/gpio/gpio${gpioId}/value
+	echo $gpioId > /sys/class/gpio/unexport
+}
+
+function gpio_get_val() {
+	gpioId=$(gpio_number $1)
+	echo $gpioId > /sys/class/gpio/export
+	echo $(cat /sys/class/gpio/gpio$gpioId/value)
+	echo $gpioId > /sys/class/gpio/unexport
+}
+
+# Configure GPIO as input
+function gpio_configure_input() {
+	gpioId=$(gpio_number $1)
+	echo $gpioId > /sys/class/gpio/export
+	echo "in" > /sys/class/gpio/gpio${gpioId}/direction
+	echo $gpioId > /sys/class/gpio/unexport
+}