#!/bin/bash

ME_UTIL="/usr/bin/me-util"
PECI_UTIL="/usr/bin/bic-util"
CMD_DIR="/usr/bin/crashdump"
INTERFACE=$3
SENSOR_HISTORY=180

# read command from stdin
function execute_via_me {
  # if ME_UTIL cannot be executed, return
  [ -x $ME_UTIL ] || \
    return

  # Adapt command to ME-UTIL format
  cat | \
    sed 's/^0x/0xb8 0x40 0x57 0x01 0x00 0x/g' $1 | \
      $ME_UTIL server --file /dev/stdin | \
        sed 's/^57 01 00 //g'
}

# read command from stdin
function execute_via_peci {
  # if PECI_UTIL cannot be executed, return
  [ -x $PECI_UTIL ] || \
    return

  cat | \
    sed 's/^0x/0xe0 0x29 0x9c 0x9c 0x00 0x/g' $1 | \
      $PECI_UTIL server --file /dev/stdin | \
        sed 's/^9C 9C 00 //g'
}

function execute_cmd {
  if [ "$INTERFACE" == "ME_INTERFACE" ]; then
    cat | execute_via_me
  else
    cat | execute_via_peci
  fi
}

# ARG: Bus[8], Device[5], Function[3], Register[12] (unit: bits)
# OUT: PCI config address
function PCI_Config_Addr {
  # BUS
  RESULT=$((($1 & 0xFF) << 20))
  # DEV
  RESULT=$((RESULT | (($2 & 0x1F) << 15)))
  # FUN
  RESULT=$((RESULT | (($3 & 0x7) << 12)))
  # REG
  RESULT=$((RESULT | (($4 & 0xFFF) << 0)))
  printf "0x%x 0x%x 0x%x 0x%x" \
    $((RESULT & 0xFF)) \
    $(((RESULT >> 8) & 0xFF)) \
    $(((RESULT >> 16) & 0xFF)) \
    $(((RESULT >> 24) & 0xFF))
  return 0
}

function print_bus_device {
  MAX_FUN=0
  MAX_DEV=4
  BUS=$(printf "0x%02x" $1)
  BUSM=$(($1 >> 4))
  BUSL=$((($1 & 0xF) << 4))
  for (( DEV=0; DEV<=$MAX_DEV; DEV++ )); do
    DEVM=$((DEV >> 1))
    DEVL=$(((DEV & 0x1) << 3))
    for (( FUN=0; FUN<=$MAX_FUN; FUN++ )); do
      printf "echo \"BUS 0x%02x, Dev 0x%02x, Fun 0x%02x, Reg: 0x100 ~ 0x147\"\n" $1 $DEV $FUN
      BYTE1=$(((DEVL | FUN) << 4 | 0x1))
      BYTE2=$((BUSL | DEVM))
      for REG in {0..68..4}; do
        printf "0x30 0x06 0x05 0x61 0x00 0x%02x 0x%02x 0x%02x 0x0%x\n" $REG $BYTE1 $BYTE2 $BUSM
      done
    done
  done
}

function find_end_device {
  echo "Find Root Port Bus $1 Dev $2 Fun $3..."
  RES=$(echo "0x30 0x06 0x05 0x61 0x00 $(PCI_Config_Addr $1 $2 $3 0x18)" | execute_cmd)
  echo "$RES"
  CC=$(echo $RES| awk '{print $1;}')
  SECONDARY_BUS=0x$(echo $RES| awk '{print $3;}')
  SUBORDINATE_BUS=0x$(echo $RES| awk '{print $4;}')
  if [ "$CC" == "40" ] && [ "$SECONDARY_BUS" != "0x00" ] && [ "$SUBORDINATE_BUS" != "0x00" ]; then
    for (( BUS=$SECONDARY_BUS; BUS<=$SUBORDINATE_BUS; BUS++ )); do
      printf "End Device on Bus 0x%02x\n" $BUS
      echo "$(print_bus_device $BUS)" | execute_cmd
    done
  fi
}

function pcie_dump {

  # Buses
  RES=$(echo "0x30 0x06 0x05 0x61 0x00 0xcc 0x20 0x04 0x00" | execute_cmd)
  echo "Get CPUBUSNO: $RES"

  # Completion Code
  CC=$(echo $RES| awk '{print $1;}')

  # Success
  if [ "$CC" == "40" ]; then
    # CPU root port - Bus 0x16/0x64, Dev 0~3, Fun:0
    # Root port buses
    ROOT_BUSES=$(echo $RES | awk '{printf "0x%s 0x%s", $3, $4;}')
    ROOT_BUS=$(echo $RES | awk '{printf "0x%s", $2;}')
    echo ROOT_BUSES=$ROOT_BUSES
    for ROOT in $ROOT_BUSES; do
      for DEV in {0..3}; do
        find_end_device $ROOT $DEV 0
      done
    done

    # CPU root port - Bus 0,Dev 0, Fun:0
    echo ROOT_BUS=$ROOT_BUS
    find_end_device $ROOT_BUS 0 0

    # PCH root port - Bus 0,Dev 0x1B, Fun:0
    find_end_device $ROOT_BUS 0x1B 0

    # PCH root port - Bus 0,Dev 0x1D, Fun:0
    find_end_device $ROOT_BUS 0x1D 0

    # PCH root port - Bus 0,Dev 0x1D, Fun:4
    find_end_device $ROOT_BUS 0x1D 4
  fi

  # CPU and PCH
  [ -r $CMD_DIR/crashdump_pcie ] && \
    cat $CMD_DIR/crashdump_pcie | execute_cmd
}

function dwr_dump {

  echo
  echo DWR assert check:
  echo =================
  echo

  # Get biosscratchpad7[26]: DWR assert check
  RES=$(echo "0x30 0x06 0x05 0x61 0x00 0xbc 0x20 0x04 0x00" | execute_cmd)

  echo "< Get biosscratchpad7[26]: DWR assert check >"
  echo "$RES"
  echo

  # Completion Code
  CC=$(echo $RES| awk '{print $1;}')
  DWR=0x$(echo $RES| awk '{print $5;}')

  # Success
  if [ "$CC" == "40" ]; then
    if [ $((DWR & 0x04)) == 4 ]; then
      echo "Auto Dump in DWR mode"
      return 2
    else
      echo "Auto Dump in non-DWR mode"
      return 1
    fi
  else
    echo "get DWR mode fail"
    return 0
  fi
}

function print_dump_help {
  echo "$0 server coreid <INTERFACE> ==> for CPU CoreID"
  echo "$0 server msr    <INTERFACE> ==> for CPU MSR"
  echo "$0 server sensors            ==> for sensor history"
  echo "$0 server threshold          ==> for sensor threshold"
  echo "$0 server pcie   <INTERFACE> ==> for PCIe"
  echo "$0 server dwr    <INTERFACE> ==> for DWR check"
  exit 1
}

if [ "$#" -eq 1 ] && [ $1 = "time" ]; then
  now=$(date)
  echo "Crash Dump generated at $now"
  exit 0
fi

if [ "$#" -eq 2 ]; then
  if [ "$2" != "sensors" ] && [ "$2" != "threshold" ]; then
    print_dump_help
  fi
elif [ "$#" -eq 3 ]; then
  if [ "$2" != "coreid" ] && [ "$2" != "msr" ] && [ "$2" != "pcie" ] && [ "$2" != "dwr" ]; then
    print_dump_help
  fi
  if [ "$INTERFACE" != "ME_INTERFACE" ] && [ "$INTERFACE" != "PECI_INTERFACE" ]; then
    print_dump_help
  fi
else
  print_dump_help
fi

echo ""

if [ "$2" = "coreid" ]; then
  [ -r $CMD_DIR/crashdump_coreid ] && \
      cat $CMD_DIR/crashdump_coreid | execute_cmd
elif [ "$2" = "msr" ]; then
  [ -r $CMD_DIR/crashdump_msr ] && \
      cat $CMD_DIR/crashdump_msr | execute_cmd
elif [ "$2" = "sensors" ]; then
  /usr/local/bin/sensor-util all --history $SENSOR_HISTORY
elif [ "$2" = "threshold" ]; then
  /usr/local/bin/sensor-util all --threshold
elif [ "$2" = "pcie" ]; then
  pcie_dump
elif [ "$2" = "dwr" ]; then
  dwr_dump
  exit $?
fi

exit 0


#!/bin/sh
#
# Copyright 2020-present Facebook. All Rights Reserved.
#
### BEGIN INIT INFO
# Provides:          setup-exp-cached
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Set Cachcing for SCC expander info
### END INIT INFO

echo "Setup Caching for SCC Expander info.."

/usr/bin/exp-cached --booting > /dev/null 2>&1 &

echo "done."


#!/bin/sh
#
# Copyright 2020-present Facebook. All Rights Reserved.
#
### BEGIN INIT INFO
# Provides:          setup-front-paneld
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Start front panel control daemon
### END INIT INFO

echo -n "Setup Front Panel Daemon.."
runsv /etc/sv/front-paneld > /dev/null 2>&1 &
echo "done."


#!/bin/sh
#
# Copyright 2021-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          setup-fan
# Required-Start:    board-id
# Required-Stop:
# Default-Start:     5
# Default-Stop:
# Short-Description: Set fan speed
### END INIT INFO

echo "Setup fan speed... "

sh /usr/local/bin/setup-fsc-config.sh &


#!/bin/sh

. /usr/local/fbpackages/utils/ast-functions

FAN_SOURCE="DELTA"

wait_sensord_ready()
{
  RETRY=180   #timeout: 3 minutes
  while [ $RETRY -gt 0 ]
  do
    ret=$($KV_CMD get flag_sensord_monitor)
    if [ "$ret" = "1" ]; then
      return 0
    fi
    RETRY=$((RETRY-1))
    sleep 1
  done

  logger -s -p user.warn -t setup-fsc-config "Waiting sensord ready timeout"
  return 1
}

wait_fan_fru_dumped()
{
  RETRY=180   #timeout: 3 minutes
  i=0

  #Check fan present
  while [ $i -lt "$FAN_FRU_CNT" ]
  do
    if [ "$(gpio_get FAN_${i}_INS_N)" != "$STR_VALUE_0" ]; then
      echo $i
      return
    fi
    i=$((i+1))
  done

  #Check fan FRU dumped
  i=0
  for _ in $(seq $RETRY);  do
    while [ $i -lt "$FAN_FRU_CNT" ]
    do
      ret=$($KV_CMD get fan${i}_dumped)
      [ "$ret" != "$STR_VALUE_1" ] && break
      i=$((i+1))
    done
    [ $i -eq "$FAN_FRU_CNT" ] && break
    sleep 1
  done

  echo $i
}

check_fan_source()
{
  i=0
  AVC_CNT=0

  while [ $i -lt "$FAN_FRU_CNT" ]
  do
    fan_source=$($FRUIDUTIL_CMD fan${i} 2>/dev/null | grep 'Product Manufacturer')
    ret=$?
    # Get fan FRU failed
    if [ "$ret" -ne "0" ]; then
      logger -s -p user.warn -t setup-fsc-config "Get fan${i} FRU failed, use DELTA fan table."
      FAN_SOURCE="DELTA"
      return
    fi

    fan_source=${fan_source##*: }

    if [ "$fan_source" = "AVC" ]; then
      AVC_CNT=$((AVC_CNT+1))
    fi
    i=$((i+1))
  done

  if [ $AVC_CNT -eq "$FAN_FRU_CNT" ]; then
    FAN_SOURCE="AVC"
  elif [ $AVC_CNT -gt 0 ]; then
    logger -s -p user.warn -t setup-fsc-config "Mix using fan source, use DELTA fan table."
    FAN_SOURCE="DELTA"
  fi
}

set_default_fan_table="/usr/local/bin/set_default_fan_table.py"

default_fsc_config_path="/etc/fsc-config.json"
fsc_type5_default_config_path="/etc/FSC_GC_PVT_default_config.json"
fsc_type5_avc_config_path="/etc/FSC_GC_Type5_PVT_AVC_v1_config.json"
fsc_type5_delta_config_path="/etc/FSC_GC_Type5_PVT_DELTA_v1_config.json"
fsc_type7_avc_config_path="/etc/FSC_GC_Type7_PVT_AVC_v1_config.json"
fsc_type7_delta_config_path="/etc/FSC_GC_Type7_PVT_DELTA_v1_config.json"

fsc_type5_zone_config_path="/etc/fsc/FSC_GC_Type5_PVT_v1_zone0.fsc"

get_uic_location
uic_location=$?

get_chassis_type
chassis_type=$?

# Check fan source to use different fan table
fan_fru_dumped_cnt=$(wait_fan_fru_dumped)
if [ "$fan_fru_dumped_cnt" -eq "$FAN_FRU_CNT" ]; then
  check_fan_source
else
  logger -s -p user.warn -t setup-fsc-config "Waiting fan${fan_fru_dumped_cnt} dumped timeout or fan${fan_fru_dumped_cnt} not present, use DELTA fan table."
fi

if [ "$chassis_type" = "$UIC_TYPE_7_HEADNODE" ]; then
  if [ "$FAN_SOURCE" = "AVC" ]; then
    cp ${fsc_type7_avc_config_path} ${default_fsc_config_path}
  else
    cp ${fsc_type7_delta_config_path} ${default_fsc_config_path}
  fi
  echo "Setup fscd: Use Type 7 ${FAN_SOURCE} fan table... "
elif [ "$chassis_type" = "$UIC_TYPE_5" ]; then
  if [ "$FAN_SOURCE" = "AVC" ]; then
    cp ${fsc_type5_avc_config_path} ${default_fsc_config_path}
  else
    cp ${fsc_type5_delta_config_path} ${default_fsc_config_path}
  fi

  if [ "$uic_location" = "$UIC_LOCATION_A" ]; then
    sed -i "s/_x/_a/g" ${fsc_type5_zone_config_path}
    echo "Setup fscd: Use Type 5 side A ${FAN_SOURCE} fan table... "
  elif [ "$uic_location" = "$UIC_LOCATION_B" ]; then
    sed -i "s/_x/_b/g" ${fsc_type5_zone_config_path}
    echo "Setup fscd: Use Type 5 side B ${FAN_SOURCE} fan table... "
  else
    echo "Setup fscd: UIC location is unknown. Please confirm the UIC location... "
  fi
else
  python ${set_default_fan_table}
  cp ${fsc_type5_default_config_path} ${default_fsc_config_path}
  echo "Setup fscd: Unknown chassis type. Use default fan table. Please confirm chassis type... "
fi

wait_sensord_ready

runsv /etc/sv/fscd > /dev/null 2>&1 &

echo "Setup fan speed done... "


#!/bin/sh
#
# Copyright 2021-present Facebook. All Rights Reserved.
#
### BEGIN INIT INFO
# Provides:          setup-gpiod
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Start gpiod daemon
### END INIT INFO

. /usr/local/fbpackages/utils/ast-functions

echo -n "Setup gpiod for fbgc..."
runsv /etc/sv/gpiod > /dev/null 2>&1 &
echo "done."


#!/bin/sh
#
# Copyright 2021-present Facebook. All Rights Reserved.
#
### BEGIN INIT INFO
# Provides:          setup-gpiointrd
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Start gpiointrd daemon
### END INIT INFO

. /usr/local/fbpackages/utils/ast-functions

echo -n "Setup gpiointrd for fbgc..."
runsv /etc/sv/gpiointrd > /dev/null 2>&1 &
echo "done."


#!/bin/sh
#
# Copyright 2021-present Facebook. All Rights Reserved.
#
### BEGIN INIT INFO
# Provides:          setup-iocd
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Start IOC daemon
### END INIT INFO

. /usr/local/fbpackages/utils/ast-functions

echo -n "Setup iocd for fbgc..."

get_chassis_type
uic_type=$?

runsv /etc/sv/iocd_11 > /dev/null 2>&1 &

if [ "$uic_type" = "$UIC_TYPE_7_HEADNODE" ]; then
  runsv /etc/sv/iocd_12 > /dev/null 2>&1 &
fi

echo "done."


#!/bin/sh
# for expander, payload id: FRU_SCC(5)
exec /usr/local/bin/ipmbd 10 5


#!/bin/sh
# for BIC
exec /usr/local/bin/ipmbd 2 1


#!/bin/sh
# for USB debug card
exec /usr/local/bin/ipmbd 7 2


#! /bin/sh
#
# Copyright 2020-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          ipmbd
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:      0 6
# Short-Description: Provides ipmb message tx/rx service
#
### END INIT INFO

echo -n "Starting IPMB Rx/Tx Daemon.."

echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-2/new_device
runsv /etc/sv/ipmbd_2 > /dev/null 2>&1 &

echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-7/new_device
runsv /etc/sv/ipmbd_7 > /dev/null 2>&1 &

echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-10/new_device
runsv /etc/sv/ipmbd_10 > /dev/null 2>&1 &

echo "Done."


#!/bin/sh

# PLATFORM MAY CHOOSE TO OVERRIDE THIS FILE
echo -n "Starting mTerm console server..."
runsv /etc/sv/mTerm-scc_exp_smart > /dev/null 2>&1 &
runsv /etc/sv/mTerm-scc_exp_sdb > /dev/null 2>&1 &
runsv /etc/sv/mTerm-scc_ioc_smart > /dev/null 2>&1 &
runsv /etc/sv/mTerm-server > /dev/null 2>&1 &
runsv /etc/sv/mTerm-bic > /dev/null 2>&1 &
runsv /etc/sv/mTerm-iocm_ioc_smart > /dev/null 2>&1 &

echo "done."


#!/bin/sh

# Address of SRAM that is used to store "reboot by command" flag.
SRAM_BMC_REBOOT_BY_CMD="0x10015C04"

# Set 0x101 as flag for healthd logging reboot cause.
val=$(devmem "$SRAM_BMC_REBOOT_BY_CMD" 32 2>/dev/null)
devmem "$SRAM_BMC_REBOOT_BY_CMD" 32 $((val | 0x101)) 2>/dev/null


#!/bin/sh
#
# Copyright 2021-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/fbpackages/utils/ast-functions

I2CGET_CMD=/usr/sbin/i2cget
I2C13_LTC2990_ADDR=0x4c
I2C13_ADS1015_ADDR=0x49
I2C9_LTC2991_ADDR=0x48
I2C9_ADC128_ADDR=0x1d
DPB_FRU_PATH="/tmp/fruid_dpb.bin"
IOCM_FRU_PATH="/tmp/fruid_iocm.bin"
DPB_KEY="dpb_source_info"
IOCM_KEY="iocm_source_info"

UNKNOWN_SRC=0
MAIN_SRC=1
SECOND_SRC=2

FRU=$1

if [ "$FRU" = "dpb" ]; then
  I2C_BUS=9
  I2C_ADDR_MAIN=$I2C9_ADC128_ADDR
  I2C_ADDR_SECOND=$I2C9_LTC2991_ADDR
  FRU_PATH=$DPB_FRU_PATH
  KEY_SOURCE_INFO=$DPB_KEY
elif [ "$FRU" = "e1s_iocm" ]; then
  I2C_BUS=13
  I2C_ADDR_MAIN=$I2C13_ADS1015_ADDR
  I2C_ADDR_SECOND=$I2C13_LTC2990_ADDR
  FRU_PATH=$IOCM_FRU_PATH
  KEY_SOURCE_INFO=$IOCM_KEY
else
  logger -s -p user.warn -t check_2nd_src "Abort by invalid input"
  exit
fi

check_fru_content() {
  RET=$UNKNOWN_SRC
  RETRY=5
  while [ $RETRY -gt 0 ]
  do
    if [ -f $FRU_PATH ]; then
      PCD=$($FRUIDUTIL_CMD "$FRU" | grep "Product Custom Data")
      if echo "$PCD" | grep -q "Non-TI"; then
        echo $SECOND_SRC
        return 0
      else
        echo $MAIN_SRC
        return 0
      fi
    else
      RETRY=$((RETRY-1))
      sleep 1
    fi
  done
  logger -s -p user.warn -t check_2nd_src "Fail to read $FRU FRU: $FRU_PATH doesn't exist"
  echo $UNKNOWN_SRC
}

check_i2c_dev() {
  RET_MAIN=$($I2CGET_CMD -y -f $I2C_BUS $I2C_ADDR_MAIN 0 2>&1 1>/dev/null)
  RET_SECOND=$($I2CGET_CMD -y -f $I2C_BUS $I2C_ADDR_SECOND 0 2>&1 1>/dev/null)

  if ! echo "$RET_MAIN" | grep -q "Read failed"; then
    echo $MAIN_SRC
  elif ! echo "$RET_SECOND" | grep -q "Read failed"; then
     echo $SECOND_SRC
  else
    logger -s -p user.warn -t check_2nd_src "i2c dev doesn't exist on $FRU"
    echo $UNKNOWN_SRC
  fi
}

RET=$(check_fru_content)
printf "Source checking by FRU: %s\n" "$RET"

if [ "$RET" = "$UNKNOWN_SRC" ]; then
  RET=$(check_i2c_dev)
  printf "Source checking by i2c dev: %s\n" "$RET"
fi

logger -s -p user.warn -t check_2nd_src "$FRU source: $RET"

$KV_CMD set $KEY_SOURCE_INFO "$RET"

if [ -f /etc/modprobe.d/modprobe.conf ]; then
  rm /etc/modprobe.d/modprobe.conf
fi

if [ "$FRU" = "dpb" ]; then
  if [ ! -d /sys/bus/i2c/drivers/adc128d818 ] && [ "$RET" = "$MAIN_SRC" ]; then
    modprobe adc128d818
  fi
  if [ ! -d /sys/bus/i2c/drivers/ltc2991 ] && [ "$RET" = "$SECOND_SRC" ]; then
    modprobe ltc2991
  fi
fi

if [ "$FRU" = "e1s_iocm" ]; then
  if [ ! -d /sys/bus/i2c/drivers/ads1015 ] && [ "$RET" = "$MAIN_SRC" ]; then
    modprobe ti_ads1015
  fi
  if [ ! -d /sys/bus/i2c/drivers/ltc2990 ] && [ "$RET" = "$SECOND_SRC" ]; then
    modprobe ltc2990
  fi
fi


#!/bin/sh

. /usr/local/fbpackages/utils/ast-functions

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

MAX_RETRY=600         # wait 10 mins before give up

total_daemon="sensord ipmid fscd front-paneld gpiod gpiointrd ncsid healthd ipmbd_2 ipmbd_7 ipmbd_10"

sensord_list="flag_sensord_monitor flag_sensord_health"
ipmid_list="flag_ipmid"
front_paneld_list="flag_front_led_sync flag_front_sys_status_led flag_front_health flag_front_err_code flag_front_hb"
gpiod_list="flag_gpiod_fru_miss flag_gpiod_server_pwr flag_gpiod_scc_pwr"
gpiointrd_list="flag_gpiointrd"
ncsid_list="flag_ncsid"
healthd_list="flag_healthd_wtd flag_healthd_hb_led flag_healthd_crit_proc flag_healthd_cpu flag_healthd_mem flag_healthd_ecc flag_healthd_bmc_timestamp flag_healthd_bic_health"
ipmbd_2_list="flag_ipmbd_rx_2 flag_ipmbd_res_2 flag_ipmbd_req_2"
ipmbd_7_list="flag_ipmbd_rx_7 flag_ipmbd_res_7 flag_ipmbd_req_7"
ipmbd_10_list="flag_ipmbd_rx_10 flag_ipmbd_res_10 flag_ipmbd_req_10"

check_daemon_flag() {
  flag_list=$1

  for flag_name in $flag_list
  do
    result="$($KV_CMD get "$flag_name")"
    if [ "$result" != "1" ] || [ "$result" = "" ]; then
      echo "$flag_name"
      break
    fi
  done
}

check_daemon_status() {
  daemon_name=$1

  daemon_status="$(sv status "$daemon_name" | grep 'run')"
  if [ "$daemon_status" = "" ]; then
    echo "$daemon_name"
  else
    # check ready flag of each thread
    if [ "$daemon_name" = "sensord" ]; then
      not_ready="$(check_daemon_flag "$sensord_list" "$daemon_name")"
    elif [ "$daemon" = "ipmid" ]; then
      not_ready="$(check_daemon_flag "$ipmid_list" "$daemon_name")"
    elif [ "$daemon" = "front-paneld" ]; then
      not_ready="$(check_daemon_flag "$front_paneld_list" "$daemon_name")"
    elif [ "$daemon" = "gpiod" ]; then
      not_ready="$(check_daemon_flag "$gpiod_list" "$daemon_name")"
    elif [ "$daemon" = "gpiointrd" ]; then
      not_ready="$(check_daemon_flag "$gpiointrd_list" "$daemon_name")"
    elif [ "$daemon" = "ncsid" ]; then
      not_ready="$(check_daemon_flag "$ncsid_list" "$daemon_name")"
    elif [ "$daemon" = "healthd" ]; then
      not_ready="$(check_daemon_flag "$healthd_list" "$daemon_name")"
    elif [ "$daemon" = "ipmbd_2" ]; then
      not_ready="$(check_daemon_flag "$ipmbd_2_list" "$daemon_name")"
    elif [ "$daemon" = "ipmbd_7" ]; then
      not_ready="$(check_daemon_flag "$ipmbd_7_list" "$daemon_name")"
    elif [ "$daemon" = "ipmbd_10" ]; then
      not_ready="$(check_daemon_flag "$ipmbd_10_list" "$daemon_name")"
    fi
    echo "$not_ready"
  fi
}

check_bmc_ready() {
  retry=0

  while [ "$retry" -lt "$MAX_RETRY" ]
  do
    NOT_READY_DAEMON=""

    for daemon in $total_daemon
    do
      result="$(check_daemon_status "$daemon")"

      # daemon not ready
      if [ "$result" = "$daemon" ]; then
        NOT_READY_DAEMON=$daemon
        break
      elif [ "$result" != "" ]; then
        NOT_READY_DAEMON=$daemon
        NOT_READY_FLAG=$result
        break
      fi
    done

    # all daemons are ready
    if [ "$NOT_READY_DAEMON" = "" ]; then
      break
    else
      sleep 1
      retry=$((retry+1))
    fi
  done

  if [ "$NOT_READY_DAEMON" = "" ]; then
    "$KV_CMD" set "bmc_ready_flag" "$STR_VALUE_1"
    logger -s -p user.info -t ready-flag "BMC is ready"
  else
    logger -s -p user.info -t ready-flag "daemon: $NOT_READY_DAEMON ($NOT_READY_FLAG) is not ready"
  fi
}

echo "check bmc ready..."
check_bmc_ready &


#!/bin/sh
#
# Copyright 2020-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/fbpackages/utils/ast-functions

get_sku()
{
  get_uic_location
  uic_id=$?
  get_chassis_type
  uic_type=$?

  if [ "$uic_type" = "$UIC_TYPE_5" ]; then
    printf "System: Type5\n"
    if [ "$uic_id" = "$UIC_LOCATION_A" ]; then
      printf "UIC Location: Side A\n"
    elif [ "$uic_id" = "$UIC_LOCATION_B" ]; then
      printf "UIC Location: Side B\n"
    else
      printf "UIC Location: Unknown\n"
    fi
  elif [ "$uic_type" = "$UIC_TYPE_7_HEADNODE" ]; then
    printf "System: Type7 Headnode\n"
  else
    printf "System: Unknown\n"
  fi

  pal_sku=$(((uic_id << UIC_TYPE_SIZE) | uic_type))

  return $pal_sku
}

get_sku
pal_sku=$?
printf "Platform SKU: %s (" "$pal_sku"

i=0
while [ "${i}" -lt "$PAL_SKU_SIZE" ]
do
  tmp_sku_bit=$(((pal_sku >> i) & 1))
  sku_bit=$tmp_sku_bit$sku_bit
  i=$((i+1))
done

printf "%s" "$sku_bit"
printf ")\n"
printf "<SKU[5:0] = {UIC_ID0, UIC_ID1, UIC_TYPE0, UIC_TYPE1, UIC_TYPE2, UIC_TYPE3}>\n"

exit $pal_sku


#!/bin/sh

. /usr/local/fbpackages/utils/ast-functions

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

KEYDIR=/mnt/data/kv_store
IS_NEEDED_SERVER_POWER_ON=true
RETRY=0
RETRY_TIME=30
POWER_12V_ON_TIMEOUT=0
POWER_12V_ON_COMPLETE=1
SYNC_DATE=/usr/local/bin/sync_date.sh

# Check power policy
check_por_config()
{
  # Check if the file/key doesn't exist
  if [ ! -f "${KEYDIR}/server_por_cfg" ]; then
    PWR_POLICY="on"
    IS_NEEDED_SERVER_POWER_ON=true
  else
    PWR_POLICY=$(cat ${KEYDIR}/server_por_cfg)

    # Case ON
    if [ "$PWR_POLICY" = "on" ]; then
      IS_NEEDED_SERVER_POWER_ON=true

    # Case OFF
    elif [ "$PWR_POLICY" = "off" ]; then
      IS_NEEDED_SERVER_POWER_ON=false

    # Case LPS
    elif [ "$PWR_POLICY" = "lps" ]; then
      logger -s -p user.warn -t power-on "LPS state is deprecated, set the power policy to be ON by default."
      # LPS doesn't be supported, set power policy on
      $KV_CMD set "server_por_cfg" "on" persistent

      PWR_POLICY="on"
      IS_NEEDED_SERVER_POWER_ON=true

    fi
  fi

  logger -s -p user.info -t power-on "Power Policy: $PWR_POLICY"
}

# Check Server is present or not:
if [ "$(is_server_prsnt)" = "$SERVER_ABSENT" ]; then
  logger -s -p user.warn -t power-on "The Server is absent, turn off Server HSC 12V."
  $POWERUTIL_CMD server 12V-off
  $SYNC_DATE
  exit 1
elif [ "$(is_server_prsnt)" = "$SERVER_PRESENT" ]; then
  if [ "$(is_bmc_por)" = "$STR_VALUE_0" ]; then  # BMC is not Power-On-Reset (POR, AC-on)
    logger -s -p user.info -t power-on "BMC is not POR"
    $SYNC_DATE
    exit 0
  fi

  logger -s -p user.info -t power-on "Server 12V-On..."
  $POWERUTIL_CMD server 12V-on

  RETRY=0
  FINISH="$POWER_12V_ON_TIMEOUT"
  # Wait for server finish 12V-on
  while [ $RETRY -lt $RETRY_TIME ]
  do
    if [ "$(is_server_12v_on)" = true ]; then
      FINISH="$POWER_12V_ON_COMPLETE"
      logger -s -p user.info -t power-on "Server 12V-On done"
      break
    fi

    RETRY=$((RETRY+1))
    sleep 1
  done

  if [ "$FINISH" = "$POWER_12V_ON_TIMEOUT" ]; then
    logger -s -p user.warn -t power-on "Server 12V-On timeout"
    $SYNC_DATE
    exit 1
  fi

  check_por_config
  # Check server DC status according to power policy
  if [ "$IS_NEEDED_SERVER_POWER_ON" = true ]; then
    RETRY=0

    while [ $RETRY -lt $RETRY_TIME ]
    do
      status="$(server_power_status)"
      if [ "$status" = "$SERVER_STATUS_DC_ON" ]; then
        logger -s -p user.info -t power-on "Server DC-On done"
        $SYNC_DATE
        exit 0
      fi

      RETRY=$((RETRY+1))
      sleep 1
    done

    logger -s -p user.warn -t power-on "Server DC-On timeout"
    $SYNC_DATE
    exit 1
  fi
  $SYNC_DATE
fi

exit 0


#!/bin/sh
#
# Copyright 2020-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

### BEGIN INIT INFO
# Provides:          run_power_on
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Power on Server
### END INIT INFO

echo "Run power-on.sh for FBGC..."

sh /usr/local/bin/power-on.sh &


#!/bin/sh
#
# Copyright 2020-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/fbpackages/utils/ast-functions

# Get platform SKU
sleep 1
sh /usr/local/bin/check_pal_sku.sh > /dev/NULL
pal_sku=$?

#Set pal_sku value to key value of system_info
"$CFGUTIL_CMD" "$KEY_SYSTEM_INFO" "$pal_sku"
ret=$?
if [ "$ret" != "0" ]; then
  logger -s -p user.warn -t setup-platform "Failed to set key value of $KEY_SYSTEM_INFO"
  exit 1
fi

# Record the platform SKU in syslog
uic_type=$(($pal_sku & $UIC_TYPE_MASK))
uic_id=$(($(($pal_sku >> $UIC_TYPE_SIZE)) & $UIC_LOCATION_MASK))

if [ "$uic_type" = "$UIC_TYPE_5" ]; then
  if [ "$uic_id" = "$UIC_LOCATION_A" ]; then
    UIC_LOCAL="side A"
  elif [ "$uic_id" = "$UIC_LOCATION_B" ]; then
    UIC_LOCAL="side B"
  else
    UIC_LOCAL="unknown"
  fi
  logger -s -p user.info -t setup-platform "System: type 5, UIC location: $UIC_LOCAL"
elif [ "$uic_type" = "$UIC_TYPE_7_HEADNODE" ]; then
  logger -s -p user.info -t setup-platform "System: type 7"
else
  logger -s -p user.info -t setup-platform "System: unknown"
fi


#!/bin/sh
#
# Copyright 2021-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
. /usr/local/fbpackages/utils/ast-functions

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

MAX_RETRY=15

##### sync time from NTP server
retry=0
while [ $retry -lt "$MAX_RETRY" ]
do
  if ! $NTP_CMD -p | grep '^\*' > /dev/null ; then
    retry=$((retry+1))
    sleep 1
  else
    logger -s -p user.crit -t sync-date "Syncing up BMC time from NTP"
    exit 0
  fi
done
logger -s -p user.info -t sync-date "Syncing up BMC time from NTP failed because NTP server not exist"

##### sync time from Host
if [ "$(is_server_prsnt)" = "$SERVER_PRESENT" ] ; then
  retry=0
  while [ $retry -lt "$MAX_RETRY" ]
  do
    output=$("$ME_CMD" server "$NETFN_STORAGE_REQ" "$CMD_GET_SEL_TIME")

    # sync BMC time only when ME returns correct response length
    if [ "$(echo $output | wc -c)" = "$SEL_TIME_RESPONSE_LEN" ] ; then
      time_hex0=$(echo "$output" | cut -d' ' -f1 | sed 's/^0*//') # get byte0
      time_hex1=$(echo "$output" | cut -d' ' -f2 | sed 's/^0*//') # get byte1
      time_hex2=$(echo "$output" | cut -d' ' -f3 | sed 's/^0*//') # get byte2
      time_hex3=$(echo "$output" | cut -d' ' -f4 | sed 's/^0*//') # get byte3

      # change hexadecimal to decimal
      time_dec=$((0x$time_hex3 << 24 | 0x$time_hex2 << 16 | 0x$time_hex1 << 8 | 0x$time_hex0))

      # change decimal number to date formate
      sync_date=$(date -s @$time_dec +"%Y.%m.%d-%H:%M:%S")
      ret=$?
      if [ $ret = "$SYNC_TIME_OK" ]; then
        logger -s -p user.crit -t sync-date "Syncing up BMC time from Host(ME)"
        exit 0
      else
        # get invalid SEL time
        logger -s -p user.info -t sync-date "Syncing up BMC time from Host(ME) failed because get invalid SEL time: $output"
        retry=$((retry+1))
      fi
    else
      retry=$((retry+1))
    fi
  done
  logger -s -p user.info -t sync-date "Syncing up BMC time from Host(ME) failed because get SEL time from ME failed"
fi

##### sync time from default time
logger -s -p user.crit -t sync-date "Syncing up BMC time from Default(OpenBMC build time)"


#!/bin/sh

# shellcheck source=/usr/local/fbpackages/utils/ast-functions
. /usr/local/fbpackages/utils/ast-functions

echo "Setup sensor monitoring for FBGC... "

FRUS="dpb server uic scc nic e1s_iocm"

exec /usr/local/bin/sensord $FRUS


#!/bin/sh
#
# Copyright 2020-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          setup-sensord
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Setup sensor monitoring
### END INIT INFO

. /usr/local/fbpackages/utils/ast-functions

echo "Setup sensor monitoring for FBGC... "

# Store vr information before sensor monitoring
if [ "$(is_sb_bic_ready 1)" -eq "1" ]; then
    /usr/bin/fw-util server --version vr > /dev/null
fi

runsv /etc/sv/sensord > /dev/null 2>&1 &

echo "done."


#!/bin/sh
#
# Copyright 2023-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

/usr/local/bin/fan-util --set 100


#!/bin/sh
i2cset -y 9 0x71 0 0x05 # MUX to Channel 1 (MEB BIC)
exec /usr/local/bin/mctpd smbus 9 0x10


#! /bin/sh
#
# Copyright 2023-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          ipmbd
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:      0 6
# Short-Description: Provides ipmb message tx/rx service
#
### END INIT INFO

# shellcheck disable=SC1091,SC2039
. /usr/local/fbpackages/utils/ast-functions

echo -n "Starting MCTPD Rx/Tx Daemon.."

echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-3/new_device  #BIC
echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-4/new_device  #NIC
echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-9/new_device  #BIC

#Set NIC1 EID to 0x22
/usr/local/bin/mctp-util -d 0x4 0x64 0x00 0x00 0x80 0x01 0x00 0x22

ulimit -q 1024000
runsv /etc/sv/mctpd_3 > /dev/null 2>&1 &
runsv /etc/sv/mctpd_4 > /dev/null 2>&1 &
runsv /etc/sv/mctpd_9 > /dev/null 2>&1 &

echo "done."


#!/bin/sh
#
# Copyright 2023-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

connect_uart2_4() {
  printf "uart2" > /sys/devices/platform/ahb/ahb:apb/1e789000.lpc/1e789098.uart_routing/uart4
  printf "uart4" > /sys/devices/platform/ahb/ahb:apb/1e789000.lpc/1e789098.uart_routing/uart2
}

connect_uart2_4


#!/bin/bash
#
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

kv set mb_polling_status      1
kv set nic0_polling_status    1
kv set nic1_polling_status    1
kv set scm_polling_status     1
kv set vpdb_polling_status    1
kv set hpdb_polling_status    1
kv set fan_bp1_polling_status 1
kv set fan_bp2_polling_status 1


#!/bin/sh
exec /usr/local/bin/pldmd --bus 9


#! /bin/sh
#
# Copyright 2023-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

echo -n "Starting PLDMD Rx/Tx Daemon.."

runsv /etc/sv/pldmd_3 > /dev/null 2>&1 &
runsv /etc/sv/pldmd_4 > /dev/null 2>&1 &
runsv /etc/sv/pldmd_9 > /dev/null 2>&1 &

echo "done."


#!/bin/bash

PID=$$
# File format autodump<fru>.pid (See pal_is_crashdump_ongoing()
# function definition)
PID_FILE='/var/run/autodump1.pid'
DUMP_DIR='/var/lib/amd-ras'
CURRENT_INDEX_FILE="$DUMP_DIR/fru1_current_index"
INFODUMP_FILE="$DUMP_DIR/sensordump.log"
DUMP_UTIL='/usr/bin/amd-ras'
LOG_ARCHIVE='/mnt/data/autodump.tar.gz'

SENSOR_HISTORY=180

# check crashdump binary file exists
if [ ! -f $DUMP_UTIL ]; then
  logger -t "ipmid" -p daemon.crit "AMD ADDC crashdump not supported"
  exit 1
fi

# check if auto crashdump is already running
if [ -f $PID_FILE ]; then
  logger -t "ipmid" -p daemon.warning "Another crashdump is runnung"
  exit 1
else
  echo $PID > $PID_FILE
fi

# Set crashdump timestamp
# this timestamp is used by pal_is_crashdump_ongoing() and it can
# prevent the power control when crashdump is ongoing
sys_runtime=$(awk '{print $1}' /proc/uptime)
sys_runtime=$(printf "%0.f" "$sys_runtime")
kv set fru1_crashdump $((sys_runtime+300))

# check number of crashdump file exists
[ -r $CURRENT_INDEX_FILE ] && PREVIOUS_INDEX=$(cat $CURRENT_INDEX_FILE) || PREVIOUS_INDEX=0
DUMP_FILE="$DUMP_DIR/fru1_ras-error${PREVIOUS_INDEX}.cper"

for i in {0..1}; do
  if ! id[$i]=$(kv get cpu"${i}"_id persistent); then
    id[$i]="0 0 0 0"
  fi
done
IFS=" " read -r -a CPUID <<< "${id[@]}"

echo "Auto Dump Started"
{ echo -n "Sensor Dump Start at "; date; } > $INFODUMP_FILE

# Sensors
{
  echo ""
  echo "Sensor history of last ${SENSOR_HISTORY}s at dump:"
  /usr/local/bin/sensor-util all --history $SENSOR_HISTORY

  echo "Sensor threshold at dump:"
  /usr/local/bin/sensor-util all --threshold

  echo -n "Dump End at "; date
} >> $INFODUMP_FILE 2>&1

$DUMP_UTIL --fru 1 --ncpu 2 --cid "${CPUID[@]}"

[ -r $CURRENT_INDEX_FILE ] && CURRENT_INDEX=$(cat $CURRENT_INDEX_FILE) || CURRENT_INDEX=0
if [ "$PREVIOUS_INDEX" == "$CURRENT_INDEX" ]; then
  DUMP_FILE=
fi

IFS=" " read -r -a LOGS <<< "$(basename "$INFODUMP_FILE") $(basename "$DUMP_FILE")"
tar zcf $LOG_ARCHIVE -C $DUMP_DIR "${LOGS[@]}"
logger -t "ipmid" -p daemon.crit "Crashdump for FRU: 1 is generated at $LOG_ARCHIVE"

# Remove current pid file
rm $PID_FILE

echo "Auto Dump Stored in $LOG_ARCHIVE"
exit 0


#!/bin/bash
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          setup-fan
# Required-Start:    board-id
# Required-Stop:
# Default-Start:     5
# Default-Stop:
# Short-Description: Set fan speed
### END INIT INFO

# shellcheck disable=SC1091
. /usr/local/fbpackages/utils/ast-functions

default_fsc_config="/etc/fsc-config.json"
if [[ -f ${default_fsc_config} ]]; then
  rm ${default_fsc_config}
fi

rev_id=$(kv get mb_rev)
if [[ "$rev_id" == "2" ]]; then
  ln -s /etc/fsc-config-2-retimer.json ${default_fsc_config}
else
  ln -s /etc/fsc-config-8-retimer.json ${default_fsc_config}
fi

/etc/init.d/check-fan-cache.sh &


#!/bin/sh
#
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

. /usr/local/bin/openbmc-utils.sh

RETRY=0

rebind_i2c_dev() {
  dev="$1-00$2"
  dri=$3

  while [ ! -L "${SYSFS_I2C_DEVICES}/$dev/driver" ] && [ $RETRY -lt 10 ];
  do
    sleep 1
    i2c_bind_driver "$dri" "$dev"
    ((RETRY++))
  done
}

rebind_i2c_dev 6 70 pca954x


#!/bin/bash
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/fbpackages/utils/ast-functions

for retry in {1..20};
do
    bp2_sensor238=$(kv get fan_bp2_sensor238)
    if [ $? -ne 0 ]; then
        sleep 3
    else
        break
    fi
done

i2cget -f -y 8 0x48 0x01
rev=$?
if [ "$rev" -ne 0 ]; then
    val=$(i2cget -f -y 40 0x21 0x00)
    fan_present1=$(("$val"))

    val=$(i2cget -f -y 41 0x21 0x00)
    fan_present2=$(("$val"))

    if [ "$fan_present1" -eq 255 ] && [ "$fan_present2" -eq 255 ]; then
      echo "Don't enable fscd due to fan not present"
    else
      echo "Start fscd"
      runsv /etc/sv/fscd > /dev/null 2>&1 &
    fi
fi
echo "done."


#!/bin/sh
#
# Copyright 2018-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh

mb_sku=$(($(/usr/bin/kv get mb_sku) & 0x0F))
# sku_id[3:0] | HSC     | ADC        | VR             | RT VR        |config
# 0000        | MPS5990 | ADC128D818 | RAA229620      | ISL69260IRAZ |  0
# 0100        | LTC4282 | MAXIM11617 | XDPE192C3B     | XDPE15284D   |  1
# 0010        | TBD     | ADC128D818 | RAA229620      | TBD          |  2
# 0110        | LTC4286 | MAXIM11617 | MP2857GQKT-001 | TBD          |  3
# 0001        | MPS5990 | ADC128D818 | MP2857GQKT-001 | ISL69260IRAZ |  4

# Artemis
# 1001        | LTC4282 | ADC128D818 | XDPE192C3B     |   9

config0="0"
config1="4"
config4="1"

# Artemis
config9="9"

#TBD
#config2="2"
#config3="6"

MB_1ST_SOURCE="0"
MB_2ND_SOURCE="1"
MB_3RD_SOURCE="2"

mbrev=$(kv get mb_rev)
MB_DVT_BORAD_ID="2"

#HSC
probe_hsc_mp5990() {
  i2c_device_add 6 0x20 mp5990
  kv set mb_hsc_source "$MB_1ST_SOURCE"
}

probe_hsc_ltc() {
  val=$(i2cget -f -y 21 0x42 0x02)
  data=$(("$val"))

  #Read ADC 1.5v:LTC4286 1v:LTC4282
  if [ "$mbrev" -ge "$MB_DVT_BORAD_ID" ]
  then
    if [ "$data" -ge 4 ]
    then
      i2c_device_add 6 0x41 ltc4286
      kv set mb_hsc_source "$MB_3RD_SOURCE"
    else
      i2c_device_add 6 0x41 ltc4282
      kv set mb_hsc_source "$MB_2ND_SOURCE"
    fi
  else
    if [ "$data" -gt 4 ]
    then
      i2c_device_add 6 0x41 ltc4286
      kv set mb_hsc_source "$MB_3RD_SOURCE"
    else
      i2c_device_add 6 0x41 ltc4282
      kv set mb_hsc_source "$MB_2ND_SOURCE"
    fi
  fi

  #HSC Temp
  i2c_device_add 25 0x4C lm75
  #HSC module's eeprom
  i2c_device_add 6 0x51 24c64
  kv set mb_hsc_module "1"
}

#ADC
probe_adc_ti() {
  i2cset -f -y 20 0x1d 0x0b 0x02
  i2c_device_add 20 0x1d adc128d818
  i2cset -f -y 26 0x1d 0x0b 0x02
  i2c_device_add 26 0x1d adc128d818
  kv set mb_adc_source "$MB_1ST_SOURCE"

}

probe_adc_maxim() {
  i2c_device_add 20 0x35 max11617
  i2c_device_add 26 0x35 max11617
  kv set mb_adc_source "$MB_2ND_SOURCE"
}

#VR
probe_vr_raa() {
  i2c_device_add 20 0x61 isl69260
  i2c_device_add 20 0x62 isl69260
  i2c_device_add 20 0x63 isl69260
  i2c_device_add 20 0x72 isl69260
  i2c_device_add 20 0x74 isl69260
  i2c_device_add 20 0x75 isl69260
  kv set mb_vr_source "$MB_1ST_SOURCE"
}

probe_vr_xdpe() {
  i2c_device_add 20 0x4a xdpe152c4
  i2c_device_add 20 0x49 xdpe152c4
  i2c_device_add 20 0x4c xdpe152c4
  i2c_device_add 20 0x4d xdpe152c4
  i2c_device_add 20 0x4e xdpe152c4
  i2c_device_add 20 0x4f xdpe152c4
  kv set mb_vr_source "$MB_2ND_SOURCE"
}

probe_vr_mp2856() {
  #To do - Probe mp2856 driver
  i2c_device_add 20 0x49 mp2856
  i2c_device_add 20 0x4a mp2856
  i2c_device_add 20 0x4c mp2856
  i2c_device_add 20 0x4d mp2856
  i2c_device_add 20 0x4e mp2856
  i2c_device_add 20 0x4f mp2856
  kv set mb_vr_source "$MB_3RD_SOURCE"
}

#MB retimer VR
probe_mb_retimer_vr_isl() {
  i2c_device_add 20 0x60 isl69260
  i2c_device_add 20 0x76 isl69260
}

probe_mb_retimer_vr_xdpe() {
  i2c_device_add 20 0x60 xdpe152c4
  i2c_device_add 20 0x76 xdpe152c4
}

#MB DPM
# rev_id[2:0] | ID2 | ID1 | ID0 |
# 000         |  0  |  0  |  0  | EVT  (no retimer)
# 001         |  0  |  0  |  1  | DVT1 (8 retimer)
# 010         |  0  |  1  |  0  | DVT2 (2 retimer)
# 011         |  0  |  1  |  1  | PVT  (TBD)

mbrev=$(kv get mb_rev)
MB_DVT_BOARD_ID="1"
MB_PVT_BOARD_ID="3"

if [ "$mbrev" -ge "$MB_DVT_BOARD_ID" ]; then
  if [ "$mb_sku" -ne "$config9" ]; then
    i2c_device_add 34 0x41 ina230
    i2c_device_add 34 0x42 ina230
    i2c_device_add 34 0x43 ina230
    i2c_device_add 34 0x44 ina230
    i2c_device_add 34 0x45 ina230
  fi
  kv set mb_dpm_source "$MB_1ST_SOURCE"
fi

if [ "$mbrev" -eq "$MB_DVT_BOARD_ID" ] &&
   [ "$mbrev" -ge "$MB_PVT_BOARD_ID" ]; then
  probe_mb_retimer_vr
fi

if [ "$mb_sku" -eq "$config0" ]; then
  probe_hsc_mp5990
  probe_adc_ti
  probe_vr_raa
  probe_mb_retimer_vr_isl
elif [ "$mb_sku" -eq "$config1" ]; then
  probe_hsc_ltc
  probe_adc_maxim
  probe_vr_xdpe
  probe_mb_retimer_vr_xdpe
elif [ "$mb_sku" -eq "$config4" ]; then
  probe_hsc_mp5990
  probe_adc_ti
  probe_vr_mp2856
  probe_mb_retimer_vr_isl
# Artemis config
elif [ "$mb_sku" -eq "$config9" ]; then
  probe_hsc_ltc
  probe_adc_ti
  probe_vr_xdpe
  probe_mb_retimer_vr_xdpe
fi

if ! i2cget -f -y 0 0x70 0 >/dev/null 2>&1; then
  kv set apml_mux 0
else
  i2cset -f -y 0 0x70 0x46 0x01
  i2cset -f -y 0 0x70 0x40 0xc0
  i2cset -f -y 0 0x70 0x41 0xc0
  kv set apml_mux 1
fi


#!/bin/bash
#
# Copyright 2022-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          gpio-cover
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Set up GPIO pins as appropriate can be cover
### END INIT INFO

. /usr/local/fbpackages/utils/ast-functions

# ==SGPIO Input Cover==
sgpio_export PWRGD_OCP_SFF_PWR_GOOD 0
sgpio_export IRQ_SML1_PMBUS_ALERT_N 2
sgpio_export FM_PWRGD_PVDD18_S5_P0 4

sgpio_export APML_CPU0_ALERT_R_N 10
sgpio_export APML_CPU1_ALERT_R_N 12
sgpio_export FM_PVDD11_S3_P0_OCP_N 14
sgpio_export FM_PVDD11_S3_P1_OCP_N 16

sgpio_export PRSNT_OCP_SFF_N 28
sgpio_export PRSNT_OCP_V3_2_N 30

sgpio_export GPU_FPGA_EROT_FATALERR_ISO_R_N 34
sgpio_export IRQ_HSC_FAULT_R1_N 36
sgpio_export FM_OCP_V3_2_PWR_GOOD 38

sgpio_export FM_PWRGD_PVDD33_S5 44

sgpio_export PWRGD_PVDD18_S5_R_P1 48
sgpio_export OCP_V3_2_P3V3_PWRGD 50

sgpio_export PWRGD_P3V3_R2 56
sgpio_export PWRGD_PVDDCR_SOC_P0 58

sgpio_export PWRGD_PVDDCR_CPU0_P0 66
sgpio_export FM_PWRGD_PVDDIO_P0 68
sgpio_export PWRGD_P3V3_AUX_R 70
sgpio_export FM_PWRGD_PVDD11_S3_P0 72
sgpio_export FM_PWRGD_PVDDIO_P1 74
sgpio_export PWRGD_PS_PWROK_PLD_ISO_R 76
sgpio_export FM_PWRGD_PVDDCR_CPU0_P1 78
sgpio_export PWRGD_PVDDCR_SOC_P1 80
sgpio_export FM_PWRGD_PVDD11_S3_P1 82
sgpio_export FM_PWRGD_PVDDCR_CPU1_P1 84
sgpio_export FM_PWRGD_PVDDCR_CPU1_P0 86
sgpio_export PWRGD_P1V2_AUX_R 88
sgpio_export PWRGD_P1V8_AUX_R 90
sgpio_export SCM_SYS_PWROK 92
sgpio_export PWRGD_P5V_AUX_R3 94

sgpio_export FM_PRSNT_CPU0_R_N 112
sgpio_export FM_PRSNT_CPU1_R_N 114
sgpio_export CPU1_THERMTRIP_R_N 118
sgpio_export FM_PVDDCR_CPU0_P0_OCP_N 122
sgpio_export FM_PVDDCR_CPU0_P1_OCP_N 124
sgpio_export FM_PVDDCR_CPU1_P0_OCP_N 126
sgpio_export FM_PVDDCR_CPU1_P1_OCP_N 128
sgpio_export PWRGD_CHGL_CPU0 130
sgpio_export PWRGD_CHAF_CPU0 132
sgpio_export PWRGD_CHAF_CPU1 134
sgpio_export CPU0_THERMTRIP_R_N 136
sgpio_export FM_CPU0_RSMRST_N 138
sgpio_export FM_SCM_PRSNT1_N 140
sgpio_export FM_CPU0_SMERR_N 142
sgpio_export FM_CPU1_SMERR_N 144
sgpio_export FM_BIOS_POST_CMPLT_BUF_R_N 146
sgpio_export SWB_HSC_PWRGD_ISO_R 148
sgpio_export FM_SMB_1_ALERT_GPU_ISO_R_N 150
sgpio_export FM_SMB_2_ALERT_GPU_ISO_R_N 152
sgpio_export PVDDCR_CPU0_P0_PMALERT 154
sgpio_export PVDDCR_CPU0_P1_PMALERT 156
sgpio_export PVDDCR_CPU1_P0_SMB_ALERT 158
sgpio_export PVDDCR_CPU1_P1_SMB_ALERT 160
sgpio_export PRSNT_HDT_N 162
sgpio_export FM_CPU0_SLP_S3_N 164
sgpio_export FM_CPU0_SLP_S5_N 166
sgpio_export E1S_0_PRSNT_R_N 172
sgpio_export P0_PWR_ERR 174
sgpio_export P1_PWR_ERR 176
sgpio_export OC_ALERT_N 178
sgpio_export PWRGD_CHGL_CPU1 180
sgpio_export PVDD11_S3_P0_PMALERT 182
sgpio_export PVDD11_S3_P1_PMALERT 184
sgpio_export FM_CPU1_PROCHOT_R_N 186
sgpio_export UV_ALERT_N 188

sgpio_export FM_SWB_PWRGD_ISO_R 192
sgpio_export CPU0_PCC_N 194
sgpio_export CPU1_PCC_N 196
sgpio_export FM_RST_CPU0_RESETL_N 198
sgpio_export FM_RST_CPU1_RESETL_N 200
sgpio_export FM_CPU0_PROCHOT_R_N 202

sgpio_export BMC_JTAG_SEL_R 228
sgpio_export RST_PERST_CPUx_SWB_N 230
sgpio_export P12V_HSC_TEMP_ALERT_R_N 232
sgpio_export P12V_HSC_T_CRIT_R_N 234
sgpio_export FM_CPU1_PWRGD_OUT 236
sgpio_export FM_PWRGD_CPU0_PWROK 238
sgpio_export FM_PWRGD_CPU1_PWROK 240
sgpio_export PWRGD_P12V_MEM_R 242
sgpio_export P12V_SCM_PWRGD_R 244
sgpio_export P12V_E1S_0_PWRGD 246
sgpio_export P3V3_E1S_PWRGD_0_R 248
sgpio_export P12V_OCP_V3_1_PWRGD 250
sgpio_export OCP_V3_1_P3V3_PWRGD 252
sgpio_export HP_LVC3_OCP_V3_2_P12V_PWRGD_R 254

sgpio_export CPLD_SGPIO_READY_ID0 18
sgpio_export CPLD_SGPIO_READY_ID1 22
sgpio_export CPLD_SGPIO_READY_ID2 116
sgpio_export CPLD_SGPIO_READY_ID3 120

# == SGPIO OUT Cover==
sgpio_export RST_SMB_SWITCH_N 5
gpio_set RST_SMB_SWITCH_N 1

sgpio_export FM_SMM_CRASHDUMP_R 7
gpio_set FM_SMM_CRASHDUMP_R 1

sgpio_export FM_DEBUG_PORT_PRSNT_R1_N 9
gpio_set FM_DEBUG_PORT_PRSNT_R1_N 1

sgpio_export FM_JTAG_BMC_MUX_SEL_R1 15
gpio_set FM_JTAG_BMC_MUX_SEL_R1 0

sgpio_export FM_SMB_RT_ROM_SEL 29
gpio_set FM_SMB_RT_ROM_SEL 0

sgpio_export NV_DUMP_END 33
gpio_set NV_DUMP_END 0

sgpio_export FM_BIOS_DEBUG_EN_N 41
gpio_set FM_BIOS_DEBUG_EN_N 1

sgpio_export CLK_GEN2_BMC_RC_OE_R_N 47
gpio_set CLK_GEN2_BMC_RC_OE_R_N 0

sgpio_export USB_OC0_REAR_R_N 63
gpio_set USB_OC0_REAR_R_N 1

sgpio_export GPU_FPGA_RST_N 65
gpio_set GPU_FPGA_RST_N 1

sgpio_export CLK_GEN2_GPU_FPGA_OE_R_N 69
gpio_set CLK_GEN2_GPU_FPGA_OE_R_N 0

sgpio_export JTAG_SCM_TRST_R_N 91
gpio_set JTAG_SCM_TRST_R_N 1

sgpio_export FM_BMC_PWRBRK_N 95
gpio_set FM_BMC_PWRBRK_N 1

sgpio_export BMC_FORCE_NM_THROTTLE_N 99
gpio_set BMC_FORCE_NM_THROTTLE_N 1

sgpio_export FM_APML_MUX2_SEL_R 103
gpio_set FM_APML_MUX2_SEL_R 1

sgpio_export FM_SEC_MUX_R_SEL 107
gpio_set FM_SEC_MUX_R_SEL 1

sgpio_export IRQ_BMC_SMI_R_N 109
gpio_set IRQ_BMC_SMI_R_N 1

sgpio_export IRQ_CPU_BMC_NMI_R_N 111
gpio_set IRQ_CPU_BMC_NMI_R_N 1

sgpio_export IRQ_SMI_ACTIVE_N_R 113
gpio_set IRQ_SMI_ACTIVE_N_R 1

sgpio_export IRQ_TPM_SPI_R1_N 115
gpio_set IRQ_TPM_SPI_R1_N 1


#!/bin/bash

connect_uart2_4() {
  echo -ne "uart1" > /sys/devices/platform/ahb/ahb:apb/1e789000.lpc/1e789098.uart_routing/uart4
  echo -ne "uart4" > /sys/devices/platform/ahb/ahb:apb/1e789000.lpc/1e789098.uart_routing/uart1
  echo -ne "io1" > /sys/devices/platform/ahb/ahb:apb/1e789000.lpc/1e789098.uart_routing/uart2
  echo -ne "uart2" > /sys/devices/platform/ahb/ahb:apb/1e789000.lpc/1e789098.uart_routing/io1
}

connect_uart2_4


#!/bin/bash
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

PATH=/sbin:/bin:/usr/sbin:/usr/bin

# shellcheck disable=SC1091
. /usr/local/fbpackages/utils/ast-functions

DEBUG_ENABLE=false

update_ntp_config_from_kv() {
  local ntp_server
  ntp_server=$(/usr/bin/kv get ntp_server persistent)
  if [ -z "$ntp_server" ]; then
    return
  fi

  sed -i "s/.*# REPLACE WITH KV.*/server $ntp_server iburst # REPLACE WITH KV/" /etc/ntp.conf
  /etc/init.d/ntpd restart
}

is_ntp_time_synced() {
  local str
  local ret

  str=$(/usr/sbin/ntpq -np | grep '^\*')
  ret=$?
  # logger -t "ipmid" -p daemon.crit "ret: $ret"
  if [ "$DEBUG_ENABLE" = true ] ; then
    echo "=================================="
    echo "ret: $ret"
    echo "----------------------------------"
    echo "$str"
    echo "=================================="
  fi

  # ret == 0, synced
  # ret == 1, not synced
  return $ret
}

ntp_sync_delay() {
    local NTP_DELAY_COUNT

    NTP_DELAY_COUNT=0
    echo "[$(/bin/date)] ntp is enabled, ntp_server: $(/usr/bin/kv get ntp_server persistent)"

    while [ $NTP_DELAY_COUNT -lt 30 ];
    do
      if is_ntp_time_synced ; then
        break
      fi
      ((NTP_DELAY_COUNT++))
      [ "$DEBUG_ENABLE" = true ] && echo "[$(/bin/date)] system time not synced, count: ${NTP_DELAY_COUNT}"
      sleep 1
    done
    if is_ntp_time_synced ; then
      echo "[$(/bin/date)] system time synced after $NTP_DELAY_COUNT sec"
    else
      echo "[$(/bin/date)] system time not synced after $NTP_DELAY_COUNT sec"
    fi
}

sync_date()
{
  if [ "$(is_bmc_por)" -eq 1 ]; then

    sleep 5
    update_ntp_config_from_kv
    ntp_sync_delay
    echo Syncing up BMC time with server...
  fi
}

sync_date


#!/bin/bash

PID=$$
# File format autodump<fru>.pid (See pal_is_crashdump_ongoing()
# function definition)
PID_FILE='/var/run/autodump1.pid'
DUMP_DIR='/tmp/crashdump/output'
MAP_DIR='/var/bafi'
PARSE_FILE="$DUMP_DIR/bafi.log"
DUMP_FILE="$DUMP_DIR/sensordump.log"
DUMP_UTIL='/usr/bin/crashdump'
PARSE_UTIL='/usr/bin/bafi'
LOG_ARCHIVE='/mnt/data/autodump.tar.gz'
ACD=true

if [ ! -f $DUMP_UTIL ] ; then
  # shellcheck disable=SC1091
  . /usr/local/bin/gpio-utils.sh

  ACD=false
  DUMP_FILE="$DUMP_DIR/autodump.log"
  DUMP_UTIL='/usr/local/bin/dump.sh'
  mkdir -p $DUMP_DIR
fi

# check if running auto dump
[ -r $PID_FILE ] && OLDPID=$(cat $PID_FILE) || OLDPID=''

# Set current pid
echo $PID > $PID_FILE

# Set crashdump timestamp
sys_runtime=$(awk '{print $1}' /proc/uptime)
sys_runtime=$(printf "%0.f" "$sys_runtime")
kv set fru1_crashdump $((sys_runtime+630))

# kill previous autodump if exist
if [ -n "$OLDPID" ] && (grep "autodump" /proc/$OLDPID/cmdline &> /dev/null) ; then
  echo "kill pid $OLDPID..."
  kill -s 9 $OLDPID
  killall -s 9 dump.sh >/dev/null 2>&1
  killall -s 9 peci-util >/dev/null 2>&1
  killall -s 9 crashdump >/dev/null 2>&1
  killall -s 9 bafi >/dev/null 2>&1

  if [ "$ACD" != true ] ; then
    { echo -n "(uncompleted) Auto Dump End at "; date; } >> $DUMP_FILE
    tar zcf '/mnt/data/autodump_uncompleted.tar.gz' -C $DUMP_DIR "$(basename $DUMP_FILE)"
  fi
fi
unset OLDPID

DELAY_SEC=30
SENSOR_HISTORY=180

while test $# -gt 0
do
  case "$1" in
  --now)
    DELAY_SEC=0
    ;;
  *)
    echo "unknown argument $1"
    ;;
  esac
  shift
done

if [ "$DELAY_SEC" != "0" ]; then
  echo "Auto Dump will start after ${DELAY_SEC}s..."
  sleep ${DELAY_SEC}
fi

echo "Auto Dump Started"
LOGS=$(basename $DUMP_FILE)
if [ "$ACD" == true ] ; then
  $DUMP_UTIL

  # shellcheck disable=SC2012
  LOG_FILE=$(ls $DUMP_DIR/crashdump_* -t1 |head -n 1)
  ${PARSE_UTIL} "$LOG_FILE" > $PARSE_FILE 2>&1

  LOGS="$LOGS $(basename "$LOG_FILE") $(basename $PARSE_FILE)"
  { echo -n "Sensor Dump Start at "; date; } > $DUMP_FILE

else

  { echo -n "Auto Dump Start at "; date; } > $DUMP_FILE

  # CPU0
  { $DUMP_UTIL 48 coreid; $DUMP_UTIL 48 msr; } >> $DUMP_FILE 2>&1

  # CPU1
  if [ "$(gpio_get_value FM_CPU1_SKTOCC_LVT3_PLD_N)" -eq "0" ]; then
    { $DUMP_UTIL 49 coreid; $DUMP_UTIL 49 msr; } >> $DUMP_FILE 2>&1
  else
    echo "<<---------- CPU1 is not present, skip it. ---------->>" >> $DUMP_FILE
  fi

  # PCIe
  #$DUMP_UTIL pcie >> $DUMP_FILE 2>&1
fi

# Sensors
{
  echo ""
  echo "Sensor history of last ${SENSOR_HISTORY}s at dump:"
  /usr/local/bin/sensor-util all --history $SENSOR_HISTORY

  echo "Sensor threshold at dump:"
  /usr/local/bin/sensor-util all --threshold

  echo -n "Dump End at "; date
} >> $DUMP_FILE 2>&1

# shellcheck disable=SC2086
tar zcf $LOG_ARCHIVE -C $DUMP_DIR $LOGS
logger -t "ipmid" -p daemon.crit "Crashdump for FRU: 1 is generated at $LOG_ARCHIVE"

# Remove current pid file
rm $PID_FILE

echo "Auto Dump Stored in $LOG_ARCHIVE"
exit 0


#!/bin/bash

PROGRAM=$0
PECI_UTIL="/usr/local/bin/peci-util"
CMD_DIR="/etc/peci"

CPU_ID=$(($1 - 48))
DUMP_FILE=crashdump_p"$CPU_ID"_

#2S:MODE=2, 4S_EX:MODE=1, 4S_EP:MODE=0
MODE=$(($(/usr/bin/kv get mb_skt) >> 1))
if [ "$MODE" -eq 2 ]; then
  MAX_CPU=2;
else
  MAX_CPU=4;
fi

function print_help_msg {
  for ((i=0; i<MAX_CPU; i++))
  do
    addr=$((i+48))
    echo "$PROGRAM $addr coreid  ==> for CPU $i CoreID"
    echo "$PROGRAM $addr msr     ==> for CPU $i MSR"
  done
  echo "$PROGRAM pcie       ==> for PCIe"
  echo "$PROGRAM dwr        ==> for DWR check"
}

# read command from stdin
function execute_via_peci {
  # if PECI_UTIL cannot be executed, return
  [ -x $PECI_UTIL ] || \
    return

  cat | \
    $PECI_UTIL -i 10 -r 5 --file /dev/stdin
}

# read command from stdin
function execute_cmd {
  # echo "Use BMC wired PECI interface"
  cat | execute_via_peci
}

# ARG: Bus[8], Device[5], Function[3], Register[12]
function PCI_Config_Addr {
  RESULT=0
  # BUS
  RESULT=$((RESULT | (($1 & 0xFF) << 20) ))
  # DEV
  RESULT=$((RESULT | (($2 & 0x1F) << 15) ))
  # FUN
  RESULT=$((RESULT | (($3 & 0x7) << 12) ))
  # REG
  RESULT=$((RESULT | (($4 & 0xFFF) << 0) ))
  printf "0x%x 0x%x 0x%x 0x%x"\
    $(( RESULT & 0xFF )) \
    $(( (RESULT >> 8) & 0xFF )) \
    $(( (RESULT >> 16) & 0xFF )) \
    $(( (RESULT >> 24) & 0xFF ))
  return 0
}

function pcie_dump {
  # CPU and PCH
  [ -r $CMD_DIR/crashdump_pcie ] && \
    execute_cmd < $CMD_DIR/crashdump_pcie

  # Buses
  RES=$(echo "0x30 0x06 0x05 0x61 0x00 0xcc 0x20 0x04 0x00" | execute_cmd)
  echo "Get CPUBUSNO: $RES"
  # Completion Code
  CC=$(echo "$RES"| awk '{print $1;}')
  # Root port buses
  ROOT_BUSES=$(echo "$RES" | awk '{printf "0x%s 0x%s 0x%s", $3, $4, $5;}')

  # Success
  if [ "$CC" == "40" ]; then
    for ROOT in $ROOT_BUSES; do
      for DEV in {0..3}; do
        echo "Find Root Port Bus $ROOT Dev $DEV..."
        RES=$(echo "0x30 0x06 0x05 0x61 0x00 $(PCI_Config_Addr "$ROOT" $DEV 0x00 0x18)" | execute_cmd)
        echo "$RES"
        CC=$(echo "$RES"| awk '{print $1;}')
        SECONDARY_BUS=0x$(echo "$RES"| awk '{print $3;}')
        SUBORDINATE_BUS=0x$(echo "$RES"| awk '{print $4;}')
        if [ "$CC" == "40" ] && [ "$SECONDARY_BUS" != "0x00" ] && [ "$SUBORDINATE_BUS" != "0x00" ]; then
          for (( BUS=SECONDARY_BUS; BUS<=SUBORDINATE_BUS; BUS++ )); do
            BUS_MS_NIBBLE=$(printf "%x" $((BUS >> 4)) )
            BUS_LS_NIBBLE=$(printf "%x" $((BUS & 0xF)) )
            [ -r $CMD_DIR/crashdump_pcie_bus ] && \
              sed "s/<BUSM>/$BUS_MS_NIBBLE/g; s/<BUSL>/$BUS_LS_NIBBLE/g" $CMD_DIR/crashdump_pcie_bus | execute_cmd
          done
        fi
      done
    done
  fi
}

function dwr_dump {
  echo
  echo DWR assert check:
  echo =================
  echo

  # Get biosscratchpad7[26]: DWR assert check
  RES=$(echo "0x30 0x06 0x05 0x61 0x00 0xbc 0x20 0x04 0x00" | execute_cmd)

  echo "< Get biosscratchpad7[26]: DWR assert check >"
  echo "$RES"
  echo

  # Completion Code
  CC=$(echo "$RES"| awk '{print $1;}')
  DWR=0x$(echo "$RES"| awk '{print $5;}')

  # Success
  if [ "$CC" == "40" ]; then
    if [ $((DWR & 0x04)) == 4 ]; then
      echo "Auto Dump in DWR mode"
      return 2
    else
      echo "Auto Dump in non-DWR mode"
      return 1
    fi
  else
    echo "get DWR mode fail"
    return 0
  fi
}

if [ "$#" -eq 1 ] && [ "$1" = "time" ]; then
  now=$(date)
  echo "Crash Dump generated at $now"
  exit 0
fi

echo ""

if [ "$#" -eq 1 ] && [ "$1" = "pcie" ]; then
  pcie_dump
  exit 0
fi

if [ "$#" -eq 1 ] && [ "$1" = "dwr" ]; then
  dwr_dump
  exit $?
fi

if [ "$#" -ne 2 ]; then

  print_help_msg
  exit 1

elif [ "$CPU_ID" -ge "$MAX_CPU" ] || [ "$CPU_ID" -lt 0 ]; then

  print_help_msg
  exit 1

elif [ "$2" = "coreid" ] || [ "$2" = "msr" ]; then

  DUMP_FILE="$CMD_DIR/${DUMP_FILE}$2"
  if [ -r "$DUMP_FILE" ]; then
    execute_cmd < "$DUMP_FILE"
  else
    echo "$DUMP_FILE" not exist
  fi
  exit 0

fi

exit 0


#!/bin/sh
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
### BEGIN INIT INFO
# Provides:          setup-front-paneld
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Start front panel control daemon
### END INIT INFO

# shellcheck disable=SC2039
echo -n "Setup Front Panel Daemon.."
runsv /etc/sv/front-paneld > /dev/null 2>&1 &
echo "done."


#!/bin/bash
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

/etc/init.d/check-fan-cache.sh &


#!/bin/bash

dump_nv_log() {
  echo "Start to dump NVDIA FPGA Register"

  TIME=$(date +"%Y%m%d-%S")
  echo $TIME

  DUMP_DIR='/tmp/nv_reg/output'
  DUMP_REG0B="$DUMP_DIR/reg_0x0b.log"
  DUMP_REG13="$DUMP_DIR/reg_0x13.log"
  DUMP_REG14="$DUMP_DIR/reg_0x14.log"
  LOG_ARCHIVE="/mnt/data/nvlog/${TIME}_nvlog.tar.gz"

  mkdir -p "/mnt/data/nvlog"
  mkdir -p $DUMP_DIR

  /usr/sbin/i2cdump -y 11 0x0b > $DUMP_REG0B 2>&1
  /usr/sbin/i2cdump -y 7  0x13 > $DUMP_REG13 2>&1
  /usr/sbin/i2cdump -y 7  0x14 > $DUMP_REG14 2>&1

  tar -zcvf $LOG_ARCHIVE -C $DUMP_DIR reg_0x0b.log reg_0x13.log reg_0x14.log

  echo high > /tmp/gpionames/NV_DUMP_END/direction
  sleep 1
  echo low > /tmp/gpionames/NV_DUMP_END/direction

  echo "End of to dump NVDIA FPGA Register"
}

dump_nv_log &


#!/bin/sh
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          setup-gpiod
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Setup sensor monitoring
### END INIT INFO

# shellcheck disable=SC2039
echo "Setup gpio monitoring for Grandteton "

sleep 1
runsv /etc/sv/gpiod > /dev/null 2>&1 &

echo "done."


#!/bin/sh
exec /usr/local/bin/ipmbd 14 5


#! /bin/sh
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          ipmbd
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:      0 6
# Short-Description: Provides ipmb message tx/rx service
#
### END INIT INFO

# shellcheck disable=SC1091,SC2039
. /usr/local/fbpackages/utils/ast-functions

echo -n "Starting IPMB Rx/Tx Daemon.."

echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-14/new_device  #USB DBG

ulimit -q 1024000
runsv /etc/sv/ipmbd_14 > /dev/null 2>&1 &


#! /bin/sh
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          ipmbd
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:      0 6
# Short-Description: Provides ipmb message tx/rx service
#
### END INIT INFO

# shellcheck disable=SC1091,SC2039
. /usr/local/fbpackages/utils/ast-functions

echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-6/new_device   #ME

ulimit -q 1024000
runsv /etc/sv/ipmbd_6 > /dev/null 2>&1 &


#!/bin/sh
exec /usr/local/bin/mctpd smbus 3 0x10


#!/bin/sh
exec /usr/local/bin/mctpd smbus 4 0x10


#! /bin/sh
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          ipmbd
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:      0 6
# Short-Description: Provides ipmb message tx/rx service
#
### END INIT INFO

# shellcheck disable=SC1091,SC2039
. /usr/local/fbpackages/utils/ast-functions

echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-3/new_device  #BIC
echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-4/new_device  #NIC

#Set NIC1 EID to 0x22
if ! /usr/local/bin/mctp-util -d 0x4 0x64 0x0 0x00 0x80 0x01 0x00 0x22 >/dev/null; then
  echo "Failed to set nic1 EID"
fi

echo -n "Starting MCTPD Rx/Tx Daemon.."
ulimit -q 1024000
runsv /etc/sv/mctpd_3 > /dev/null 2>&1 &
runsv /etc/sv/mctpd_4 > /dev/null 2>&1 &

echo "done."


#!/bin/sh

. /usr/local/fbpackages/utils/ast-functions
echo "Starting mTerm console server..."
runsv /etc/sv/mTerm1 > /dev/null 2>&1 &
runsv /etc/sv/mTerm2 > /dev/null 2>&1 &
echo "done."


#!/bin/bash
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/fbpackages/utils/ast-functions

do_fscd_configure () {
  default_fsc_config="/etc/fsc-config.json"
  hgx_ppn=$(/usr/local/bin/fruid-util hgx | grep 'Product Part Number' | grep -o '[0-9A-Za-z-]*$')

  rm ${default_fsc_config}
  if [[ $hgx_ppn == "" ]]; then
    # If hgx not ready
    echo probe 700w config
    ln -s /etc/fsc-config-700w.json ${default_fsc_config}
    return 1
  elif [[ $hgx_ppn == "935-24287-A510-300" ]]; then
    # If hgx is 500w
    echo probe 500w config
    ln -s /etc/fsc-config-500w.json ${default_fsc_config}
    return 0
  else
    # If hgx is 700w
    echo probe 700w config
    ln -s /etc/fsc-config-700w.json ${default_fsc_config}
    return 0
  fi
}

for retry in {1..20};
do
    bp2_sensor238=$(kv get fan_bp2_sensor238)
    if [ $? -ne 0 ]; then
        sleep 3
    else
        break
    fi
done

i2cget -f -y 8 0x48 0x01
rev=$?
if [ "$rev" -ne 0 ]; then
  val=$(i2cget -f -y 40 0x21 0x00)
  fan_present1=$(("$val"))

  val=$(i2cget -f -y 41 0x21 0x00)
  fan_present2=$(("$val"))

  if [ "$fan_present1" -eq 255 ] && [ "$fan_present2" -eq 255 ]; then
    echo "Don't enable fscd due to fan not present"
  else
    echo "Start fscd"
    do_fscd_configure
    result=$?
    runsv /etc/sv/fscd > /dev/null 2>&1 &

    if [[ $result == 1 ]]; then
      while true; do
        if [[ $result == 0 ]]; then
          sv restart fscd
          break
        else
          sleep 5
          do_fscd_configure
          result=$?
        fi
      done
    fi
  fi
fi
echo "done."


#!/bin/bash
#
# Copyright 2022-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# shellcheck source=common/recipes-utils/openbmc-utils/files/openbmc-utils.sh
. /usr/local/bin/openbmc-utils.sh
# shellcheck source=meta-facebook/meta-grandteton/recipes-grandteton/plat-utils/files/ast-functions
. /usr/local/fbpackages/utils/ast-functions

read_dev() {
  for _ in {1..3}; do
    if /usr/sbin/i2cget -f -y "$1" "$2" "$3" 2>/dev/null; then
      return 0
    fi
  done
  return 1
}

rebind_i2c_dev() {
  dev="$1-00$2"
  dri=$3

  if [ ! -L "${SYSFS_I2C_DEVICES}/$dev/driver" ]; then
    if i2c_bind_driver "$dri" "$dev" >/dev/null; then
      echo "rebind $dev to driver $dri successfully"
    fi
  fi
}
#echo set SGPIO ready
gpio_set FM_BMC_SGPIO_READY_N 1

echo "Probe MB MUX"
rebind_i2c_dev 1 70 pca954x
rebind_i2c_dev 5 70 pca954x
rebind_i2c_dev 8 72 pca954x

echo "Probe PDBH MUX"
rebind_i2c_dev 37 71 pca954x

#MB TEMP Device"
i2c_device_add 21 0x48 stlm75
i2c_device_add 22 0x48 stlm75
i2c_device_add 23 0x48 stlm75
i2c_device_add 24 0x48 stlm75

#MB Expender
i2c_device_add 29 0x74 pca9539
# I/O Expander PCA9539 0xE8 BIC and GPU
gpio_export_ioexp 29-0074 RST_USB_HUB             0
gpio_export_ioexp 29-0074 RST_SWB_BIC_N           1
gpio_export_ioexp 29-0074 SWB_CABLE_PRSNT_G_N     4
gpio_export_ioexp 29-0074 GPU_CABLE_PRSNT_H_N     5
gpio_export_ioexp 29-0074 SWB_CABLE_PRSNT_F_N     6
gpio_export_ioexp 29-0074 SWB_CABLE_PRSNT_C_N     7

gpio_export_ioexp 29-0074 GPU_CABLE_PRSNT_D_N     8
gpio_export_ioexp 29-0074 SWB_CABLE_PRSNT_B_N     9
gpio_export_ioexp 29-0074 GPU_BASE_ID0            10
gpio_export_ioexp 29-0074 GPU_BASE_ID1            11
gpio_export_ioexp 29-0074 GPU_PEX_STRAP0          12
gpio_export_ioexp 29-0074 GPU_PEX_STRAP1          13
gpio_export_ioexp 29-0074 GPU_CABLE_PRSNT_A_N     14
gpio_export_ioexp 29-0074 GPU_CABLE_PRSNT_E_N     15

#MB FRU
i2c_device_add 33 0x51 24c64

# Swith Board
echo "Probe SWB Device"
SWB_1ST_SOURCE="0"
SWB_2ND_SOURCE="1"
SWB_3RD_SOURCE="2"
SWB_4TH_SOURCE="3"

# BIC I/O Expander PCA9539 0xEC BIC
i2c_device_add 32 0x76 pca9539

gpio_export_ioexp 32-0076 BIC_FWSPICK        0
gpio_export_ioexp 32-0076 BIC_UART_BMC_SEL   1

#Set IO Expender
gpio_set BIC_FWSPICK 0
gpio_set RST_SWB_BIC_N 1
gpio_set BIC_UART_BMC_SEL 0

bic_ready=$(gpio_get FM_SWB_BIC_READY_ISO_R_N)
#SWB HSC
if [ "$bic_ready" -eq 0 ]; then
  cnt=3
  while [ $cnt -ne 0 ]
  do
    sleep 1
    str=$(pldmd-util --bus 3 -e 0x0a raw 0x02 0x11 0xf0 0x00 0x01 |grep "PLDM Data")
    rev=$?
    if [ "$rev" -eq 1 ]; then
      cnt=$(("$cnt"-1))
      val=0
    else
      IFS=' ' read -ra  array <<< "$str"
      cnt=0
      for i in "${array[@]}"
      do
        array["$cnt"]=${i:2}
        cnt=$(("$cnt"+1))
      done

      int=$(((16#${array[9]}|16#${array[10]} << 8)*1000))
      dec=$((16#${array[11]}|16#${array[12]} << 8))
      val=$(("$int"+"$dec"))
      break;
    fi
  done

#kv set swb_hsc_module "0"
  if [ "$val" -gt 750 ] && [ "$val" -lt 1250 ]
  then
    kv set swb_hsc_source "$SWB_2ND_SOURCE" #ltc4282
    kv set swb_hsc_module "1"
  elif [ "$val" -gt 1250 ]
  then
    kv set swb_hsc_source "$SWB_3RD_SOURCE" #ltc4287
    kv set swb_hsc_module "1"
  else
    kv set swb_hsc_source "$SWB_1ST_SOURCE" #mp5990
  fi

#SWB VR
  cnt=3
  while [ "$cnt" -ne 0 ]
  do
    sleep 1
    str=$(pldmd-util --bus 3 -e 0x0a raw 0x02 0x11 0xf1 0x00 0x01 |grep "PLDM Data")
    rev=$?
    if [ "$rev" -eq 1 ]; then
      cnt=$(("$cnt"-1))
    else
      IFS=' ' read -ra  array <<< "$str"
      cnt=0
      for i in "${array[@]}"
      do
        array["$cnt"]=${i:2}
        cnt=$(("$cnt"+1))
      done

      int=$(((16#${array[9]}|16#${array[10]} << 8)*1000))
      dec=$((16#${array[11]}|16#${array[12]} << 8))
      val=$(("$int"+"$dec"))
      break;
    fi
  done

  if [ "$val" -gt 250 ] && [ "$val" -lt 750 ]
  then
    kv set swb_vr_source "$SWB_2ND_SOURCE" #INF
  elif [ "$val" -gt 750 ] && [ "$val" -lt 1250 ]
  then
    kv set swb_vr_source "$SWB_3RD_SOURCE" #MPS
  elif [ "$val" -gt 1250 ] && [ "$val" -lt 1750 ]
  then
    kv set swb_vr_source "$SWB_4TH_SOURCE" #TI
  else
    kv set swb_vr_source "$SWB_1ST_SOURCE" #RAA
  fi
fi

VPDB_EVT2="2"
VPDB_PVT="5"
VPDB_DISCRETE_PVT="3"
VPDB_1ST_SOURCE="0"
VPDB_2ND_SOURCE="1"
VPDB_3RD_SOURCE="2"
VPDB_HSC_MAIN="0"
#VPDB_HSC_SECOND="1"

# VPDB
echo "Probe VPDB Device"
#VPDB Expender
i2c_device_add 36 0x22 pca9555
gpio_export_ioexp 36-0022  HPDB_PRESENT     9
gpio_export_ioexp 36-0022  VPDB_BOARD_ID_0  10
gpio_export_ioexp 36-0022  VPDB_BOARD_ID_1  11
gpio_export_ioexp 36-0022  VPDB_BOARD_ID_2  12
gpio_export_ioexp 36-0022  VPDB_SKU_ID_0    13
gpio_export_ioexp 36-0022  VPDB_SKU_ID_1    14
gpio_export_ioexp 36-0022  VPDB_SKU_ID_2    15

if read_dev 36 0x25 0 >/dev/null; then
  gpio_export_ioexp 36-0025  VPDB_BOARD_ID_3_IO   0
  gpio_export_ioexp 36-0025  VPDB_SKU_ID_3_IO     15
  VPDB_BOARD_ID_3=$VPDB_BOARD_ID_3_IO
  VPDB_SKU_ID_3=$VPDB_SKU_ID_3_IO
else
  VPDB_BOARD_ID_3=0
  VPDB_SKU_ID_3=0
fi

kv set vpdb_rev "$((VPDB_BOARD_ID_3 << 3 |
                    $(gpio_get VPDB_BOARD_ID_2) << 2 |
                    $(gpio_get VPDB_BOARD_ID_1) << 1 |
                    $(gpio_get VPDB_BOARD_ID_0)))"

kv set vpdb_sku "$((VPDB_SKU_ID_3 << 3 |
                    $(gpio_get VPDB_SKU_ID_2) << 2 |
                    $(gpio_get VPDB_SKU_ID_1) << 1 |
                    $(gpio_get VPDB_SKU_ID_0)))"

#VPDB ADM1272/LTC4286 CONFIG
vpdb_hsc=$(gpio_get VPDB_SKU_ID_2)
vrev=$(kv get vpdb_rev)

if [ "$vpdb_hsc" -eq "$VPDB_HSC_MAIN" ] && [ "$vrev" -gt 1 ]; then
  i2c_device_add 38 0x44 ltc4286
  kv set vpdb_hsc_source "$VPDB_1ST_SOURCE"
else
  i2cset -y -f 38 0x10 0xd4 0x3F1F w
  i2c_device_add 38 0x10 adm1272
  kv set vpdb_hsc_source "$VPDB_2ND_SOURCE"
fi

vsku=$(kv get vpdb_sku)

if [ "$vsku" -eq "2" ] || [ "$vsku" -eq "5" ]; then
  brick_driver="raa228006"
  i2c_device_add 38 0x54 $brick_driver
  kv set vpdb_brick_source "$VPDB_3RD_SOURCE"

  if [ "$vrev" -gt "$VPDB_DISCRETE_PVT" ]; then
    if [ "$(gpio_get VPDB_SKU_ID_0)" -eq $VPDB_1ST_SOURCE ]; then
      i2c_device_add 36 0x67 ltc2945
      i2c_device_add 36 0x68 ltc2945
      kv set vpdb_adc_source "$VPDB_1ST_SOURCE"
    else
      i2c_device_add 36 0x40 ina238
      i2c_device_add 36 0x41 ina238
      kv set vpdb_adc_source "$VPDB_2ND_SOURCE"
    fi
  fi
else
  brick_driver="bmr491"
  vpdb_brick=$(gpio_get VPDB_SKU_ID_1)

  if [ "$vpdb_brick" -eq "$VPDB_1ST_SOURCE" ]; then
    brick_driver="pmbus"
    kv set vpdb_brick_source "$VPDB_1ST_SOURCE"
  else
    kv set vpdb_brick_source "$VPDB_2ND_SOURCE"
  fi

  vpdb_rev=$(kv get vpdb_rev)
  if [ "$vpdb_rev" -ge $VPDB_EVT2 ]; then
    i2c_device_add 38 0x67 $brick_driver
    i2c_device_add 38 0x68 $brick_driver
    i2c_device_add 38 0x69 $brick_driver
  else
    i2c_device_add 38 0x69 $brick_driver
    i2c_device_add 38 0x6a $brick_driver
    i2c_device_add 38 0x6b $brick_driver
  fi

  #vpdb ADC sensors
  if [ "$vrev" -gt "$VPDB_PVT" ]; then
    if [ "$(gpio_get VPDB_SKU_ID_0)" -eq $VPDB_1ST_SOURCE ]; then
      i2c_device_add 36 0x67 ltc2945
      i2c_device_add 36 0x68 ltc2945
      kv set vpdb_adc_source "$VPDB_1ST_SOURCE"
    else
      i2c_device_add 36 0x40 ina238
      i2c_device_add 36 0x41 ina238
      kv set vpdb_adc_source "$VPDB_2ND_SOURCE"
    fi
  fi
fi
# VPDB FRU
i2c_device_add 36 0x52 24c64 #VPDB FRU

#***HPDB Board Device Probe***
HPDB_PVT=5
HPDB_1ST_SOURCE="0"
HPDB_2ND_SOURCE="1"
#HPDB_3RD_SOURCE="2"
HPDB_HSC_MAIN="0"
#HPDB_HSC_SECOND="1"

echo "Probe HPDB Device"
#HPDB ID Expender
i2c_device_add 37 0x23 pca9555
gpio_export_ioexp 37-0023  FAN_BP1_PRSNT_N  2
gpio_export_ioexp 37-0023  FAN_BP2_PRSNT_N  3
gpio_export_ioexp 37-0023  HPDB_BOARD_ID_0  10
gpio_export_ioexp 37-0023  HPDB_BOARD_ID_1  11
gpio_export_ioexp 37-0023  HPDB_BOARD_ID_2  12
gpio_export_ioexp 37-0023  HPDB_SKU_ID_0    13
gpio_export_ioexp 37-0023  HPDB_SKU_ID_1    14
gpio_export_ioexp 37-0023  HPDB_SKU_ID_2    15

i2c_device_add 37 0x25 pca9555
gpio_export_ioexp 37-0025  FM_HS1_EN_BUSBAR_BUF  1
gpio_export_ioexp 37-0025  FM_HS2_EN_BUSBAR_BUF  3

if read_dev 37 0x25 0 >/dev/null; then
  gpio_export_ioexp 37-0025  HPDB_BOARD_ID_3_IO    15
  HPDB_BOARD_ID_3=$HPDB_BOARD_ID_3_IO
else
  HPDB_BOARD_ID_3=0
fi

hpdb_rc="$(($(gpio_get HPDB_BOARD_ID_2) << 2 |
      $(gpio_get HPDB_BOARD_ID_1) << 1 |
      $(gpio_get HPDB_BOARD_ID_0)))"

if [ $hpdb_rc -ge 11 ] && [ $hpdb_rc -le 15 ]; then
   HPDB_BOARD_ID_3=0
fi

kv set hpdb_rev "$((HPDB_BOARD_ID_3 << 3 | hpdb_rc))"

kv set hpdb_sku "$(($(gpio_get HPDB_SKU_ID_2) << 2 |
                    $(gpio_get HPDB_SKU_ID_1) << 1 |
                    $(gpio_get HPDB_SKU_ID_0)))"

# HPDB ADM1272/LTC4286 CONFIG
hpdb_hsc=$(gpio_get HPDB_SKU_ID_2)
hrev=$(kv get hpdb_rev)

if [ "$hpdb_hsc" -eq "$HPDB_HSC_MAIN" ] && [ "$hrev" -gt 1 ]; then
  i2c_device_add 39 0x40 ltc4286
  i2c_device_add 39 0x41 ltc4286
  kv set hpdb_hsc_source "$HPDB_1ST_SOURCE"
else
  i2cset -y -f 39 0x13 0xd4 0x3F1F w
  i2cset -y -f 39 0x1c 0xd4 0x3F1F w
  i2c_device_add 39 0x13 adm1272
  i2c_device_add 39 0x1c adm1272
  kv set hpdb_hsc_source "$HPDB_2ND_SOURCE"
fi

if [ "$hrev" -gt "$HPDB_PVT" ]; then
  if [ "$(gpio_get HPDB_SKU_ID_1)" -eq "$HPDB_1ST_SOURCE" ]; then
    i2c_device_add 37 0x69 ltc2945
    i2c_device_add 37 0x6a ltc2945
    i2c_device_add 37 0x6b ltc2945
    i2c_device_add 37 0x6c ltc2945
    kv set hpdb_adc_source "$HPDB_1ST_SOURCE"
  else
    i2c_device_add 37 0x42 ina238
    i2c_device_add 37 0x43 ina238
    i2c_device_add 37 0x44 ina238
    i2c_device_add 37 0x45 ina238
    kv set hpdb_adc_source "$HPDB_2ND_SOURCE"
  fi
fi

# HPDB FRU
i2c_device_add 37 0x51 24c64

#***FAN Board Device Probe***
BP_1ST_SOURCE="0"
BP_2ND_SOURCE="1"
BP_FAN_MAIN="0"
echo "Probe FAN Board Device"
# FAN_BP1 I/O Expander PCA9555
i2c_device_add 40 0x21 pca9555
gpio_export_ioexp 40-0021 FAN_BP1_SKU_ID_0    8
gpio_export_ioexp 40-0021 FAN_BP1_SKU_ID_1    9
gpio_export_ioexp 40-0021 FAN_BP1_SKU_ID_2    10

kv set fan_bp1_fan_sku "$(($(gpio_get FAN_BP1_SKU_ID_2) << 2 |
                           $(gpio_get FAN_BP1_SKU_ID_1) << 1 |
                           $(gpio_get FAN_BP1_SKU_ID_0)))"

# FAN_BP2 I/O Expander PCA9555
i2c_device_add 41 0x21 pca9555
gpio_export_ioexp 41-0021 FAN_BP2_SKU_ID_0    8
gpio_export_ioexp 41-0021 FAN_BP2_SKU_ID_1    9
gpio_export_ioexp 41-0021 FAN_BP2_SKU_ID_2    10

kv set fan_bp2_fan_sku "$(($(gpio_get FAN_BP2_SKU_ID_2) << 2 |
                           $(gpio_get FAN_BP2_SKU_ID_1) << 1 |
                           $(gpio_get FAN_BP2_SKU_ID_0)))"

fan_bp1_fan=$(gpio_get FAN_BP1_SKU_ID_0)
if [ "$fan_bp1_fan" -eq "$BP_FAN_MAIN" ]; then
# Max31790
  # FAN_BP1 Max31790 FAN CHIP
  i2cset -f -y 40 0x20 0x01 0xbb
  i2cset -f -y 40 0x20 0x02 0x08
  i2cset -f -y 40 0x20 0x03 0x19
  i2cset -f -y 40 0x20 0x04 0x08
  i2cset -f -y 40 0x20 0x05 0x08
  i2cset -f -y 40 0x20 0x06 0x19
  i2cset -f -y 40 0x20 0x07 0x08
  i2cset -f -y 40 0x20 0x08 0x6C
  i2cset -f -y 40 0x20 0x09 0x6C
  i2cset -f -y 40 0x20 0x0A 0x6C
  i2cset -f -y 40 0x20 0x0B 0x6C
  i2cset -f -y 40 0x20 0x0C 0x6C
  i2cset -f -y 40 0x20 0x0D 0x6C

  i2cset -f -y 40 0x2f 0x01 0xbb
  i2cset -f -y 40 0x2f 0x02 0x08
  i2cset -f -y 40 0x2f 0x03 0x19
  i2cset -f -y 40 0x2f 0x04 0x08
  i2cset -f -y 40 0x2f 0x05 0x08
  i2cset -f -y 40 0x2f 0x06 0x19
  i2cset -f -y 40 0x2f 0x07 0x08
  i2cset -f -y 40 0x2f 0x08 0x6C
  i2cset -f -y 40 0x2f 0x09 0x6C
  i2cset -f -y 40 0x2f 0x0A 0x6C
  i2cset -f -y 40 0x2f 0x0B 0x6C
  i2cset -f -y 40 0x2f 0x0C 0x6C
  i2cset -f -y 40 0x2f 0x0D 0x6C

  i2c_device_add 40 0x20 max31790
  i2c_device_add 40 0x2f max31790
  kv set fan_bp1_fan_chip_source "$BP_1ST_SOURCE"
else
  # FAN_BP1 NCT3763Y FAN CHIP
  # Config FAN PWM and FAIN FAN_BP1
  i2cset -f -y -a 40 0x01 0x20 0xA9
  i2cset -f -y -a 40 0x01 0x21 0x99
  i2cset -f -y -a 40 0x01 0x22 0x9A
  i2cset -f -y -a 40 0x01 0x38 0x51
  i2cset -f -y -a 40 0x01 0x39 0x04
  i2cset -f -y -a 40 0x01 0x41 0x0B
  i2cset -f -y -a 40 0x01 0x42 0xAE

  i2cset -f -y -a 40 0x02 0x20 0xA9
  i2cset -f -y -a 40 0x02 0x21 0x99
  i2cset -f -y -a 40 0x02 0x22 0x9A
  i2cset -f -y -a 40 0x02 0x38 0x51
  i2cset -f -y -a 40 0x02 0x39 0x04
  i2cset -f -y -a 40 0x02 0x41 0x0B
  i2cset -f -y -a 40 0x02 0x42 0xAE

  # Set FAN 25KHZ
  i2cset -f -y -a 40 0x01 0xB0 0x00
  i2cset -f -y -a 40 0x01 0xB1 0x00
  i2cset -f -y -a 40 0x01 0xB2 0x00
  i2cset -f -y -a 40 0x01 0xB3 0x00
  i2cset -f -y -a 40 0x01 0xB4 0x00
  i2cset -f -y -a 40 0x01 0xB5 0x00
  i2cset -f -y -a 40 0x01 0xB6 0x00
  i2cset -f -y -a 40 0x01 0xB7 0x00

  i2cset -f -y -a 40 0x01 0x91 0x04
  i2cset -f -y -a 40 0x01 0x93 0x04
  i2cset -f -y -a 40 0x01 0x97 0x04
  i2cset -f -y -a 40 0x01 0xA3 0x04
  i2cset -f -y -a 40 0x01 0xA5 0x04
  i2cset -f -y -a 40 0x01 0xA7 0x04
  i2cset -f -y -a 40 0x01 0xAB 0x04
  i2cset -f -y -a 40 0x01 0xAF 0x04

  i2cset -f -y -a 40 0x02 0xB0 0x00
  i2cset -f -y -a 40 0x02 0xB1 0x00
  i2cset -f -y -a 40 0x02 0xB2 0x00
  i2cset -f -y -a 40 0x02 0xB3 0x00
  i2cset -f -y -a 40 0x02 0xB4 0x00
  i2cset -f -y -a 40 0x02 0xB5 0x00
  i2cset -f -y -a 40 0x02 0xB6 0x00
  i2cset -f -y -a 40 0x02 0xB7 0x00

  i2cset -f -y -a 40 0x02 0x91 0x04
  i2cset -f -y -a 40 0x02 0x93 0x04
  i2cset -f -y -a 40 0x02 0x97 0x04
  i2cset -f -y -a 40 0x02 0xA3 0x04
  i2cset -f -y -a 40 0x02 0xA5 0x04
  i2cset -f -y -a 40 0x02 0xA7 0x04
  i2cset -f -y -a 40 0x02 0xAB 0x04
  i2cset -f -y -a 40 0x02 0xAF 0x04
  kv set fan_bp1_fan_chip_source "$BP_2ND_SOURCE"
fi

fan_bp2_fan=$(gpio_get FAN_BP2_SKU_ID_0)
if [ "$fan_bp2_fan" -eq "$BP_1ST_SOURCE" ]; then
  # FAN_BP2 MAX31790 FAN CHIP
  i2cset -f -y 41 0x20 0x01 0xbb
  i2cset -f -y 41 0x20 0x02 0x08
  i2cset -f -y 41 0x20 0x03 0x19
  i2cset -f -y 41 0x20 0x04 0x08
  i2cset -f -y 41 0x20 0x05 0x08
  i2cset -f -y 41 0x20 0x06 0x19
  i2cset -f -y 41 0x20 0x07 0x08
  i2cset -f -y 41 0x20 0x08 0x6C
  i2cset -f -y 41 0x20 0x09 0x6C
  i2cset -f -y 41 0x20 0x0A 0x6C
  i2cset -f -y 41 0x20 0x0B 0x6C
  i2cset -f -y 41 0x20 0x0C 0x6C
  i2cset -f -y 41 0x20 0x0D 0x6C

  i2cset -f -y 41 0x2f 0x01 0xbb
  i2cset -f -y 41 0x2f 0x02 0x08
  i2cset -f -y 41 0x2f 0x03 0x19
  i2cset -f -y 41 0x2f 0x04 0x08
  i2cset -f -y 41 0x2f 0x05 0x08
  i2cset -f -y 41 0x2f 0x06 0x19
  i2cset -f -y 41 0x2f 0x07 0x08
  i2cset -f -y 41 0x2f 0x08 0x6C
  i2cset -f -y 41 0x2f 0x09 0x6C
  i2cset -f -y 41 0x2f 0x0A 0x6C
  i2cset -f -y 41 0x2f 0x0B 0x6C
  i2cset -f -y 41 0x2f 0x0C 0x6C
  i2cset -f -y 41 0x2f 0x0D 0x6C

  i2c_device_add 41 0x20 max31790
  i2c_device_add 41 0x2f max31790
  kv set fan_bp2_fan_chip_source "$BP_1ST_SOURCE"
else
  # FAN_BP2 NCT3763Y FAN CHIP
  # Config FAN PWM and FAIN FAN_BP2
  i2cset -f -y -a 41 0x01 0x20 0xA9
  i2cset -f -y -a 41 0x01 0x21 0x99
  i2cset -f -y -a 41 0x01 0x22 0x9A
  i2cset -f -y -a 41 0x01 0x38 0x51
  i2cset -f -y -a 41 0x01 0x39 0x04
  i2cset -f -y -a 41 0x01 0x41 0x0B
  i2cset -f -y -a 41 0x01 0x42 0xAE

  i2cset -f -y -a 41 0x02 0x20 0xA9
  i2cset -f -y -a 41 0x02 0x21 0x99
  i2cset -f -y -a 41 0x02 0x22 0x9A
  i2cset -f -y -a 41 0x02 0x38 0x51
  i2cset -f -y -a 41 0x02 0x39 0x04
  i2cset -f -y -a 41 0x02 0x41 0x0B
  i2cset -f -y -a 41 0x02 0x42 0xAE
  # Set FAN 25KHZ
  i2cset -f -y -a 41 0x01 0xB0 0x00
  i2cset -f -y -a 41 0x01 0xB1 0x00
  i2cset -f -y -a 41 0x01 0xB2 0x00
  i2cset -f -y -a 41 0x01 0xB3 0x00
  i2cset -f -y -a 41 0x01 0xB4 0x00
  i2cset -f -y -a 41 0x01 0xB5 0x00
  i2cset -f -y -a 41 0x01 0xB6 0x00
  i2cset -f -y -a 41 0x01 0xB7 0x00

  i2cset -f -y -a 41 0x01 0x91 0x04
  i2cset -f -y -a 41 0x01 0x93 0x04
  i2cset -f -y -a 41 0x01 0x97 0x04
  i2cset -f -y -a 41 0x01 0xA3 0x04
  i2cset -f -y -a 41 0x01 0xA5 0x04
  i2cset -f -y -a 41 0x01 0xA7 0x04
  i2cset -f -y -a 41 0x01 0xAB 0x04
  i2cset -f -y -a 41 0x01 0xAF 0x04

  i2cset -f -y -a 41 0x02 0xB0 0x00
  i2cset -f -y -a 41 0x02 0xB1 0x00
  i2cset -f -y -a 41 0x02 0xB2 0x00
  i2cset -f -y -a 41 0x02 0xB3 0x00
  i2cset -f -y -a 41 0x02 0xB4 0x00
  i2cset -f -y -a 41 0x02 0xB5 0x00
  i2cset -f -y -a 41 0x02 0xB6 0x00
  i2cset -f -y -a 41 0x02 0xB7 0x00

  i2cset -f -y -a 41 0x02 0x91 0x04
  i2cset -f -y -a 41 0x02 0x93 0x04
  i2cset -f -y -a 41 0x02 0x97 0x04
  i2cset -f -y -a 41 0x02 0xA3 0x04
  i2cset -f -y -a 41 0x02 0xA5 0x04
  i2cset -f -y -a 41 0x02 0xA7 0x04
  i2cset -f -y -a 41 0x02 0xAB 0x04
  i2cset -f -y -a 41 0x02 0xAF 0x04
  kv set fan_bp2_fan_chip_source "$BP_2ND_SOURCE"
fi

FAN_BP1_LED_SKU=$(gpio_get FAN_BP1_SKU_ID_1)
FAN_BP2_LED_SKU=$(gpio_get FAN_BP2_SKU_ID_1)

# FAN LED Device"
rebind_i2c_dev 40 62 leds-pca955x
rebind_i2c_dev 41 62 leds-pca955x

# FAN Board FRU
i2c_device_add 40 0x56 24c64 #FAN_BP1 FRU
i2c_device_add 41 0x56 24c64 #FAN_BP2 FRU

gpio_export_ioexp 40-0021 FAN0_PRESENT   7
gpio_export_ioexp 40-0021 FAN4_PRESENT   6
gpio_export_ioexp 40-0021 FAN8_PRESENT   5
gpio_export_ioexp 40-0021 FAN12_PRESENT  4
gpio_export_ioexp 40-0021 FAN1_PRESENT   0
gpio_export_ioexp 40-0021 FAN5_PRESENT   1
gpio_export_ioexp 40-0021 FAN9_PRESENT   2
gpio_export_ioexp 40-0021 FAN13_PRESENT  3

gpio_export_ioexp 41-0021 FAN2_PRESENT   7
gpio_export_ioexp 41-0021 FAN6_PRESENT   6
gpio_export_ioexp 41-0021 FAN10_PRESENT  5
gpio_export_ioexp 41-0021 FAN14_PRESENT  4
gpio_export_ioexp 41-0021 FAN3_PRESENT   0
gpio_export_ioexp 41-0021 FAN7_PRESENT   1
gpio_export_ioexp 41-0021 FAN11_PRESENT  2
gpio_export_ioexp 41-0021 FAN15_PRESENT  3

# I/O Expander PCA955X FAN LED
gpio_export_ioexp 40-0062  FAN1_LED_GOOD   0
gpio_export_ioexp 40-0062  FAN1_LED_FAIL   1
gpio_export_ioexp 40-0062  FAN5_LED_GOOD   2
gpio_export_ioexp 40-0062  FAN5_LED_FAIL   3
gpio_export_ioexp 40-0062  FAN9_LED_GOOD   4
gpio_export_ioexp 40-0062  FAN9_LED_FAIL   5
gpio_export_ioexp 40-0062  FAN13_LED_GOOD  6
gpio_export_ioexp 40-0062  FAN13_LED_FAIL  7
gpio_export_ioexp 40-0062  FAN12_LED_GOOD  8
gpio_export_ioexp 40-0062  FAN12_LED_FAIL  9
gpio_export_ioexp 40-0062  FAN8_LED_GOOD   10
gpio_export_ioexp 40-0062  FAN8_LED_FAIL   11
gpio_export_ioexp 40-0062  FAN4_LED_GOOD   12
gpio_export_ioexp 40-0062  FAN4_LED_FAIL   13
gpio_export_ioexp 40-0062  FAN0_LED_GOOD   14
gpio_export_ioexp 40-0062  FAN0_LED_FAIL   15

gpio_export_ioexp 41-0062  FAN3_LED_GOOD   0
gpio_export_ioexp 41-0062  FAN3_LED_FAIL   1
gpio_export_ioexp 41-0062  FAN7_LED_GOOD   2
gpio_export_ioexp 41-0062  FAN7_LED_FAIL   3
gpio_export_ioexp 41-0062  FAN11_LED_GOOD  4
gpio_export_ioexp 41-0062  FAN11_LED_FAIL  5
gpio_export_ioexp 41-0062  FAN15_LED_GOOD  6
gpio_export_ioexp 41-0062  FAN15_LED_FAIL  7
gpio_export_ioexp 41-0062  FAN14_LED_GOOD  8
gpio_export_ioexp 41-0062  FAN14_LED_FAIL  9
gpio_export_ioexp 41-0062  FAN10_LED_GOOD  10
gpio_export_ioexp 41-0062  FAN10_LED_FAIL  11
gpio_export_ioexp 41-0062  FAN6_LED_GOOD   12
gpio_export_ioexp 41-0062  FAN6_LED_FAIL   13
gpio_export_ioexp 41-0062  FAN2_LED_GOOD   14
gpio_export_ioexp 41-0062  FAN2_LED_FAIL   15

if [ "$FAN_BP1_LED_SKU" -eq "$BP_FAN_MAIN" ]; then
  FAN_LED_GOOD=1
  FAN_LED_FAIL=0
  kv set fan_bp1_fan_led_source "$BP_1ST_SOURCE"
else
  FAN_LED_GOOD=0
  FAN_LED_FAIL=1
  kv set fan_bp1_fan_led_source "$BP_2ND_SOURCE"
fi

if [ "$FAN_BP2_LED_SKU" -eq "$BP_FAN_MAIN" ]; then
  FAN_LED_GOOD=1
  FAN_LED_FAIL=0
  kv set fan_bp2_fan_led_source "$BP_1ST_SOURCE"
else
  FAN_LED_GOOD=0
  FAN_LED_FAIL=1
  kv set fan_bp2_fan_led_source "$BP_2ND_SOURCE"
fi

gpio_set  FAN0_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN1_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN2_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN3_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN4_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN5_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN6_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN7_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN8_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN9_LED_GOOD  $FAN_LED_GOOD
gpio_set  FAN10_LED_GOOD $FAN_LED_GOOD
gpio_set  FAN11_LED_GOOD $FAN_LED_GOOD
gpio_set  FAN12_LED_GOOD $FAN_LED_GOOD
gpio_set  FAN13_LED_GOOD $FAN_LED_GOOD
gpio_set  FAN14_LED_GOOD $FAN_LED_GOOD
gpio_set  FAN15_LED_GOOD $FAN_LED_GOOD

gpio_set  FAN0_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN1_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN2_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN3_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN4_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN5_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN6_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN7_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN8_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN9_LED_FAIL  $FAN_LED_FAIL
gpio_set  FAN10_LED_FAIL $FAN_LED_FAIL
gpio_set  FAN11_LED_FAIL $FAN_LED_FAIL
gpio_set  FAN12_LED_FAIL $FAN_LED_FAIL
gpio_set  FAN13_LED_FAIL $FAN_LED_FAIL
gpio_set  FAN14_LED_FAIL $FAN_LED_FAIL
gpio_set  FAN15_LED_FAIL $FAN_LED_FAIL

/usr/local/bin/fan-util --set 70

#GPU Reset USB Hub
if [ "$(is_bmc_por)" -eq 1 ]; then
  echo "Reset SWB USB Hub"
  # set gpio 98 LOW
  pldmd-util -b 3 -e 0x0a raw 0x02 0x39 0x62 0xFF 0x02 0x00 0x00 0x01 0x01 >/dev/null
  # add delay
  sleep 0.5
  # set gpio 98 HIGH
  pldmd-util -b 3 -e 0x0a raw 0x02 0x39 0x62 0xFF 0x02 0x00 0x00 0x01 0x02 >/dev/null
  sleep 3
fi