summaryrefslogtreecommitdiff
path: root/meta-facebook/meta-bletchley/recipes-bletchley/plat-svc/files/bletchley-host-state-monitor
blob: 20a1913f007e4ec56b793fe6431e31699f443322 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/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