#!/bin/bash export PATH=$PATH:/usr/sbin:/usr/libexec # shellcheck source=meta-facebook/meta-bletchley/recipes-bletchley/plat-tools/files/bletchley-common-functions source /usr/libexec/bletchley-common-functions MDIO_TOOL="/usr/sbin/mdio" SWITCH_MDIO_BUS="1e650000.mdio-1" declare -a PORT_NUM_MAP=(10 3 2 1 7 6 5) declare -a HOST_PREVIOUS_STATE=("" "" "" "" "" "" "") declare -a HOST_STATE_CHANGE_CHECK=(0 0 0 0 0 0 0) HOST_STATE_CHANGE_CHECH_CNT=5 declare -A HOST_ACPI_ST_MAP HOST_ACPI_ST_MAP["UNKNOW"]="Unknow" HOST_ACPI_ST_MAP["NOT_PRESENT"]="G3" HOST_ACPI_ST_MAP["AC_OFF"]="G3" HOST_ACPI_ST_MAP["OFF"]="G3" HOST_ACPI_ST_MAP["SLEEP"]="SLEEP" HOST_ACPI_ST_MAP["ON"]="S0_G0_D0" declare -A HOST_STATE_MAP HOST_STATE_MAP["UNKNOW"]="Quiesced" HOST_STATE_MAP["NOT_PRESENT"]="Off" HOST_STATE_MAP["AC_OFF"]="Off" HOST_STATE_MAP["OFF"]="Off" HOST_STATE_MAP["SLEEP"]="Standby" HOST_STATE_MAP["ON"]="Running" declare -A CHASSIS_PWR_STATE_MAP CHASSIS_PWR_STATE_MAP["UNKNOW"]="On" CHASSIS_PWR_STATE_MAP["NOT_PRESENT"]="Off" CHASSIS_PWR_STATE_MAP["AC_OFF"]="Off" CHASSIS_PWR_STATE_MAP["OFF"]="On" CHASSIS_PWR_STATE_MAP["SLEEP"]="On" CHASSIS_PWR_STATE_MAP["ON"]="On" is_host_ac_on() { local HOST_ID=$1 local I2C_BUS local P1_OUTPUT_REG local P1_CONFIG_REG local HOST_PWR local IS_OUTPUT I2C_BUS=$((HOST_ID-1)) P1_OUTPUT_REG=$(i2cget -f -y "$I2C_BUS" 0x76 0x03) P1_CONFIG_REG=$(i2cget -f -y "$I2C_BUS" 0x76 0x07) HOST_PWR="$(( (P1_OUTPUT_REG & 0x80)>>7 ))" IS_OUTPUT="$(( (~P1_CONFIG_REG & 0x80)>>7 ))" if [ "$((HOST_PWR & IS_OUTPUT))" -eq 1 ];then return 0 fi return 1 } update_host_acpi_power_state() { local BUS_NAME="xyz.openbmc_project.Settings" local OBJ_PATH="/xyz/openbmc_project/control/host$1/acpi_power_state" local DBUS_PROPERTIES_INTF_NAME="org.freedesktop.DBus.Properties" local INTF_NAME="xyz.openbmc_project.Control.Power.ACPIPowerState" local PROPERTY_NAME="SysACPIStatus" local PROPERTY_VAL="xyz.openbmc_project.Control.Power.ACPIPowerState.ACPI.$2" busctl call "$BUS_NAME" "$OBJ_PATH" "$DBUS_PROPERTIES_INTF_NAME" Set ssv "$INTF_NAME" "$PROPERTY_NAME" s "$PROPERTY_VAL" } update_host_state() { local BUS_NAME="xyz.openbmc_project.State.Host$1" local OBJ_PATH="/xyz/openbmc_project/state/host$1" local DBUS_PROPERTIES_INTF_NAME="org.freedesktop.DBus.Properties" local INTF_NAME="xyz.openbmc_project.State.Host" local PROPERTY_NAME="CurrentHostState" local PROPERTY_VAL="xyz.openbmc_project.State.Host.HostState.$2" busctl call "$BUS_NAME" "$OBJ_PATH" "$DBUS_PROPERTIES_INTF_NAME" Set ssv "$INTF_NAME" "$PROPERTY_NAME" s "$PROPERTY_VAL" } update_chassis_power_state() { local BUS_NAME="xyz.openbmc_project.State.Chassis$1" local OBJ_PATH="/xyz/openbmc_project/state/chassis$1" local DBUS_PROPERTIES_INTF_NAME="org.freedesktop.DBus.Properties" local INTF_NAME="xyz.openbmc_project.State.Chassis" local PROPERTY_NAME="CurrentPowerState" local PROPERTY_VAL="xyz.openbmc_project.State.Chassis.PowerState.$2" busctl call "$BUS_NAME" "$OBJ_PATH" "$DBUS_PROPERTIES_INTF_NAME" Set ssv "$INTF_NAME" "$PROPERTY_NAME" s "$PROPERTY_VAL" } update_sled_led_state() { local HOST_ID=$1 local HOST_STATE=$2 case "$HOST_STATE" in ON|SLEEP) systemctl start obmc-led-group-start@sled"$i"_good.service ;; AC_OFF|OFF) systemctl start obmc-led-group-stop@sled"$i"_good.service ;; *) ;; esac } check_host_state() { if ! PORT_ST_VAL=$("$MDIO_TOOL" "$SWITCH_MDIO_BUS" phy "${PORT_NUM_MAP[$1]}" 0x00); then # failed to get port status via mdio echo "UNKNOW" return 1 fi if [ $((PORT_ST_VAL&16#0800)) -eq $((16#0000)) ]; then echo "OFF" elif [ $((PORT_ST_VAL&16#0A00)) -eq $((16#0A00)) ]; then echo "ON" elif [ $((PORT_ST_VAL&16#0900)) -eq $((16#0900)) ]; then echo "SLEEP" else echo "UNKNOW" fi return 0 } while true do for i in {1..6} do HOST_STATE="" if ! is_sled_present "$i"; then HOST_STATE="NOT_PRESENT" elif ! is_host_ac_on "$i"; then HOST_STATE="AC_OFF" else HOST_STATE=$(check_host_state "$i") fi if [ "$HOST_STATE" = "${HOST_PREVIOUS_STATE[$i]}" ]; then HOST_STATE_CHANGE_CHECK[i]="$HOST_STATE_CHANGE_CHECH_CNT" elif [ "${HOST_STATE_CHANGE_CHECK[$i]}" -gt "0" ]; then echo "SLED$i: detected state changed (previous:${HOST_PREVIOUS_STATE[$i]}, current:$HOST_STATE), check count: ${HOST_STATE_CHANGE_CHECK[$i]}" HOST_STATE_CHANGE_CHECK[i]=$((HOST_STATE_CHANGE_CHECK[i]-1)) else echo "SLED$i: detected state changed, update host state to $HOST_STATE" update_host_acpi_power_state "$i" "${HOST_ACPI_ST_MAP[$HOST_STATE]}" update_host_state "$i" "${HOST_STATE_MAP[$HOST_STATE]}" update_chassis_power_state "$i" "${CHASSIS_PWR_STATE_MAP[$HOST_STATE]}" update_sled_led_state "$i" "$HOST_STATE" HOST_STATE_CHANGE_CHECK[i]="$HOST_STATE_CHANGE_CHECH_CNT" HOST_PREVIOUS_STATE[i]="$HOST_STATE" fi done sleep 1 done