blob: 20a1913f007e4ec56b793fe6431e31699f443322 [file] [log] [blame]
#!/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