#!/bin/bash
#
# 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
#

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

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

prog="$0"

usage() {
    echo "Usage: $prog <command> [command options]"
    echo
    echo "Commands:"
    echo "  status: Get the current microserver power status"
    echo
    echo "  on: Power on microserver if not powered on already"
    echo "    options:"
    echo "      -f: Re-do power on sequence no matter if microserver has "
    echo "          been powered on or not."
    echo
    echo "  off: Power off microserver ungracefully"
    echo
    echo "  reset: Power reset microserver ungracefully"
    echo "    options:"
    echo "      -s: Power reset whole elbert system ungracefully"
    echo "      -s -t [0-7]: Setting boot up time."
    echo "            0: 10 seconds (default), 1: 20 seconds, 2: 30 seconds, 3: 40 seconds"
    echo "            4: 1 minute, 5: 2 minutes, 6: 5 minutes, 7: 10 minutes"
    echo
    echo "  pimreset: Power-cycle one or all PIM(s)"
    echo "    options:"
    echo "      -a  : Reset all PIMs or "
    echo "      -2 , -3 , ... , -9 : Reset a single PIM (2, 3 ... 9) "
    echo
}

do_status() {
    echo -n "Microserver power is "
    return_code=0

    if wedge_is_us_on; then
        echo "on"
    else
        echo "off"
        return_code=1
    fi

    return $return_code
}

do_on() {
    local force opt ret
    force=0
    while getopts "f" opt; do
        case $opt in
            f)
                force=1
                ;;
            *)
                usage
                exit 1
                ;;
        esac
    done
    echo -n "Power on microserver ..."
    if [ $force -eq 0 ]; then
        # need to check if uS is on or not
        if wedge_is_us_on; then
            echo " Already on. Skip!"
            return 1
        fi
    fi

    wedge_power_on_board
    ret=$?
    if [ $ret -eq 0 ]; then
        echo " Done"
        logger "Successfully power on micro-server"
    else
        echo " Failed"
        logger "Failed to power on micro-server"
    fi
    return $ret
}

do_off() {
    local ret
    echo -n "Power off microserver ..."
    wedge_power_off_board
    ret=$?
    if [ $ret -eq 0 ]; then
        echo " Done"
        logger "Successfully power off micro-server"
    else
        echo " Failed"
        logger "Failed to power off micro-server"
    fi
    return $ret
}

do_config_reset_duration() {
   # Check valid numeric value
    duration=$1
    echo "$duration" | grep -q '^[0-7]$'
    ret=$?
    if [ $ret -ne 0 ]; then
        usage
        exit 1
    else
        values=( 10 20 30 40 1 2 5 10 )
        units="seconds"
        if [ "$duration" -eq 4 ]; then
            units="minute"
        elif [ "$duration" -gt 4 ]; then
            units="minutes"
        fi
        echo "$duration" > "$SMBCPLD_SYSFS_DIR"/powercycle_duration
        logger "Waiting ${values[$duration]} $units for the system boot up"
        echo "Waiting ${values[$duration]} $units for the system boot up"
    fi
}

do_sync() {
   # Try to flush all data to MMC and remount the drive read-only. Sync again
   # because the remount is asynchronous.
   partition="/dev/mmcblk0"
   mountpoint="/mnt/data1"

   sync
   # rsyslogd logs to eMMC, so we must stop it prior to remouting.
   kill -TERM "$(cat /var/run/rsyslogd.pid)"
   sleep .05
   if [ -e $mountpoint ]; then
      retry_command 5 mount -o remount,ro $partition $mountpoint
      sleep 1
   fi
   sync
}

do_reset() {
    local system opt
    system=0
    timer=0
    duration=0
    while getopts "st:" opt; do
        case $opt in
            s)
                system=1
                ;;
            t)
                timer=1
                duration=$OPTARG
                ;;
            *)
                usage
                exit 1
                ;;
        esac
    done
    if [ $system -eq 1 ]; then
        if [ $timer -eq 1 ]; then
            do_config_reset_duration "$duration"
        fi
        # Log before do_sync since do_sync kills logging.
        logger "Power reset the whole system ..."
        do_sync
        echo -n "Power reset the whole system ..."
        sleep 1
        echo 0xde > "$PWR_SYSTEM_SYSFS"
        sleep 8
        # The chassis shall be reset now... if not, we are in trouble
        echo " Failed"
        return 254
    else
        do_off
        sleep 1
        do_on
    fi

}

toggle_pim_reset() {
    pim=$1
    # Set the selected PIM to powercycle
    for slot in 2 3 4 5 6 7 8 9; do
        if [ "$pim" -eq 0 ] || [ "$slot" -eq "$pim" ]; then
            echo "Reset PIM${slot}..."
            echo '1' > "$SMBCPLD_SYSFS_DIR"/pim"$slot"_reset
            touch /tmp/.pim"$slot"_reset
        fi
    done
    echo 'Waiting for PIMs to be re-enabled...'

    i=0
    while true; do
        i=$((i+1))
        # Wait for all cards to be be re-enabled
        if [ "$(head -n 1 "$SMBCPLD_SYSFS_DIR"/pim_reset)" == '0x0' ]; then
            echo 'All cards enabled!'
            break;
        fi

        if [ $i -gt 60 ]; then
            echo 'Timed out waiting for cards to be re-enabled...'
            exit 1
        fi
        sleep 1
     done

    # Re-initialize reset pims
    for slot in 2 3 4 5 6 7 8 9; do
        if [ "$pim" -eq 0 ] || [ "$slot" -eq "$pim" ]; then
            if wedge_is_pim_present "$slot"; then
                power_on_pim "$slot"
            fi
        fi
    done
}

do_pimreset() {
    local pim opt retval
    retval=0
    pim=-1
    while getopts "23456789a" opt; do
        case $opt in
            a)
                pim=0
                ;;
            2)
                pim=2
                ;;
            3)
                pim=3
                ;;
            4)
                pim=4
                ;;
            5)
                pim=5
                ;;
            6)
                pim=6
                ;;
            7)
                pim=7
                ;;
            8)
                pim=8
                ;;
            9)
                pim=9
                ;;
            *)
                usage
                exit 1
                ;;
        esac
    done
    if [ $pim -eq -1 ]; then
      usage
      exit 1
    fi

    toggle_pim_reset $pim

    return $retval
}

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

command="$1"
shift

case "$command" in
    status)
        do_status "$@"
        ;;
    on)
        do_on "$@"
        ;;
    off)
        do_off "$@"
        ;;
    reset)
        do_reset "$@"
        ;;
    pimreset)
        do_pimreset "$@"
        ;;
    *)
        usage
        exit 1
        ;;
esac

exit $?


#!/bin/bash

# ELBERT's SCM MAC address is the first address of the block
# allocated from "Extended MAC Base" field in SCM's EEPROM.
weutil SCM 2>&1 | grep "MAC Base" | cut -d ' ' -f 4


#!/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
#
logger "run-dhc6.sh: dhclient -6 Started.."
pid="/var/run/dhclient6.eth0.pid"

# shellcheck disable=SC2086
mac_to_ll() {
  IFS=':'; set $1; unset IFS
  echo "fe80::$(printf %x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6" | \
    sed -E 's/:0+/:/g; s/:{3,}/::/; s/:$/:0/'
}

exp_ll=
ll=

for _ in {1..30}; do
  # wait getting address from NC-SI
  if [ "$(cat /sys/class/net/eth0/addr_assign_type)" = "3" ]; then
    if [ "$(cat /sys/class/net/eth0/address)" != "$(cat /sys/class/net/br0/address)" ]; then
      ifconfig br0 hw ether "$(cat /sys/class/net/eth0/address)"
    fi
    exp_ll=$(mac_to_ll "$(cat /sys/class/net/eth0/address)")
    ll=$(ip -6 addr show dev eth0 scope link | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d')
    br_ll=$(ip -6 addr show dev br0 scope link | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d')
    # re-generate link-local address
    if [ "$ll" != "$exp_ll" ]; then
      ip -6 addr flush dev eth0
      echo 1 > /proc/sys/net/ipv6/conf/eth0/addr_gen_mode
      echo 0 > /proc/sys/net/ipv6/conf/eth0/addr_gen_mode
    fi
    if [ "$br_ll" != "$exp_ll" ]; then
      ip -6 addr flush dev br0
      echo 1 > /proc/sys/net/ipv6/conf/br0/addr_gen_mode
      echo 0 > /proc/sys/net/ipv6/conf/br0/addr_gen_mode
    fi
    break;
  fi
  sleep 1
done

if [[ "$ll" != "$exp_ll" || "$br_ll" != "$exp_ll" ]]; then
  for _ in {1..100}; do
    usleep 10000
    ll=$(ip -6 addr show dev eth0 scope link | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d')
    br_ll=$(ip -6 addr show dev br0 scope link | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d')
    if [[ "$ll" = "$exp_ll" && "$br_ll" = "$exp_ll" ]]; then
      break;
    fi
  done
fi

exec dhclient -6 -d -D LL --address-prefix-len 64 -pf ${pid} br0 "$@"


#!/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

# Block Power Cycle
/usr/local/bin/ipmb-util 8 0x68 0xd8 0xf2 0x00 0x07 0x01
echo "Auto Dump Started"

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

  mode=$(($(/usr/bin/kv get mb_skt) >> 1))
  if [ "$mode" -eq 0 ]; then
    PARSE_UTIL+=" -p $MAP_DIR/4s_device_map.json -m $MAP_DIR/4s_memory_map.json"
  elif [ "$mode" -eq 1 ]; then
    PARSE_UTIL+=" -p $MAP_DIR/ex_device_map.json -m $MAP_DIR/ex_memory_map.json"
  fi

  # 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

# Unblock Power Cycle
/usr/local/bin/ipmb-util 8 0x68 0xd8 0xf2 0x00 0x07 0x00
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/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-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

echo "Setup fan speed... "
/usr/local/bin/ipmb-util 8 0x68 0xd8 0x08 0x46 0xff

default_fsc_config_path="/etc/fsc-config.json"

host=$(($(/usr/bin/kv get mb_skt) & 0x1))  #Master:host=0, Slave:host=1
mode=$(($(/usr/bin/kv get mb_skt) >> 1))   #2S:mode=2, 4S_EX:mode=1, 4S_EP:mode=0

#echo host = $host
#echo mode = $mode

if [ "$mode" -eq 2 ]; then
  echo probe 2s fan table
  ln -s /etc/fsc-config2s.json ${default_fsc_config_path}
elif [ "$host" -eq 0 ]; then  #4S Master Mode
  echo probe 4s master fan table
  ln -s /etc/fsc-config4s_M.json ${default_fsc_config_path}
else  #4S Slave
  echo probe slave fan table
  ln -s /etc/fsc-config_Slave.json ${default_fsc_config_path}
fi

runsv /etc/sv/fscd > /dev/null 2>&1 &
echo "done."


#!/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 -n "Setup gpio monitoring for angelslanding... "

/usr/local/bin/gpiod &

echo "done."


#! /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.."

mode=$(($(/usr/bin/kv get mb_skt) >> 1))  #2S:mode=2 4S_EX:mode=1 4S_EP:mode=0
if [ $mode -eq 2 ]; then
  addr=0x1010
else
  addr=$((0x1010 | $(/usr/bin/kv get mb_pos)))
fi

echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-0/new_device  #USB DBG
echo slave-mqueue $addr > /sys/bus/i2c/devices/i2c-2/new_device   #BMC Slave Addr
echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-5/new_device  #ME
echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-6/new_device  #JG7
echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-8/new_device  #CM

ulimit -q 1024000
runsv /etc/sv/ipmbd_0 > /dev/null 2>&1 &
runsv /etc/sv/ipmbd_2 > /dev/null 2>&1 &
runsv /etc/sv/ipmbd_5 > /dev/null 2>&1 &
runsv /etc/sv/ipmbd_6 > /dev/null 2>&1 &
runsv /etc/sv/ipmbd_8 > /dev/null 2>&1 &

echo "done."


#!/bin/bash
#This is workaround for IPV4 lost There is slim chance ipv4 lost when AC cycle.
#DHCP Client can't get OFFER package from server.
#This script is for reinitial ipv4 to prevnet it lost.

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

KERNEL_VERSION=$(uname -r)
if [[ ${KERNEL_VERSION} != 4.1.* ]]; then
  for _ in {1..10}; do
    ip=$(ip -4 address |grep br0 |grep inet)
    if [ -z "$ip" ]; then
      # shellcheck disable=SC2009
      vid=$(ps |grep "dhclient.eth0" |grep -v grep |awk '{print $1}')
      kill "$vid"
      dhclient -d -pf /var/run/dhclient.eth0.pid br0 > /dev/null 2>&1 &
      sleep 10
    else
      break;
    fi
  done
fi


#!/bin/bash

/etc/init.d/setup-bridge.sh &


#!/bin/bash

/etc/init.d/eth0_mac_fixup.sh &


#!/bin/bash

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

ncsi_cmd() {
  for _ in {0..2}; do
    resp=$(/usr/local/bin/ncsi-util "$@" | grep "COMMAND_COMPLETED(0x0000)")
    if [ "$resp" != "" ]; then
      break
    fi
    sleep 0.1
  done
}

asic_mac_check() {
  mac3=$(/usr/local/bin/ncsi-util 0x17 | grep "mac_3" | awk '{print $3}')

  if [ "$mac3" == "0x0" ]; then
    logger -s -p user.warn -t setup-bridge "Recover Bridge MAC Address Filter"
    ncsi_cmd 0x0e "${mac_peer[@]:1}" 0x02 0x01
    ncsi_cmd 0x03
  fi
}

usb_dev_lost() {
  loop=0
  while true; do
    usb_pre=$(ifconfig -a | grep usb)

    if [ "$usb_pre" == "" ]; then
      echo "==Lost Usb Ethernet Device=="
      break
    elif [ $loop -ge 3 ]; then
      loop=0
      asic_mac_check
    fi

    loop=$((loop + 1))
    sleep 10
  done
}

usb_dev_detect() {
  while true; do
    usb_pre=$(ifconfig -a | grep usb)

    if [ "$usb_pre" != "" ]; then
      echo "==Find Usb Ethernet Device=="
      break
    fi

    sleep 10
  done
}

#Check MAC Filter for AL
for _ in {0..2}; do
  mapfile mac <<< "$(/usr/local/bin/ncsi-util 0x17 | grep -E "mac_[1-2]" | awk '{print $3}')"
  if [ ${#mac[@]} -ne 2 ]; then
    continue
  fi

  mac_al=$(for i in {24..0..8}; do printf "%02x:" $((mac[0]>>i & 0xff)); done; \
        printf %02x:%02x $((mac[1]>>24 & 0xff)) $((mac[1]>>16 & 0xff)))
  exp_mac=$(cat /sys/class/net/eth0/address)
  if [ "$exp_mac" == "$mac_al" ]; then
    break
  fi
  logger -s -p user.warn -t setup-bridge "Recover MAC Address Filter: $mac_al to $exp_mac"
  IFS=":" read -r -a mac <<< "$exp_mac"
  mac_al=("${mac[@]/#/0x}")
  ncsi_cmd 0x0e "${mac_al[@]}" 0x01 0x01
  ncsi_cmd 0x03
done

#Detect Cable Present
while true; do
  cable_pre1=$(($(gpio_get PRSNT_PCIE_CABLE_1_N)))
  cable_pre2=$(($(gpio_get PRSNT_PCIE_CABLE_2_N)))

  if [[ "$cable_pre1" -eq 0 || "$cable_pre2" -eq 0 ]]; then
    echo "==Usb Cable Present=="
    break
  fi

  sleep 10
done

#Detect USB Ethernet Device
usb_dev_detect

echo "Initialize IP Bridge..."

#Get EP/CC MAC Address
position=$(($(/usr/bin/kv get mb_pos)))
mode=$(($(/usr/bin/kv get mb_skt) >> 1))  #2S:mode=2, 4S_EX:mode=1, 4S_EP:mode=0

if [[ "$position" -eq 0 || "$mode" -eq 2 ]]; then
  peer_name="EP"
  peer_addr="0x2c"
else
  peer_name="CC"
  peer_addr="0x2e"
fi

while true; do
  echo "Get $peer_name MAC"
  IFS=" " read -r -a mac <<< "$(/usr/local/bin/ipmb-util 6 $peer_addr 0x30 0x02 0x00 0x05 2>/dev/null)"
  #mac=(11 78 03 9B 96 FC 99)
  if [[ ${#mac[@]} -ge 7 && ${mac[0]} == "11" && $((16#${mac[1]} & 1)) -ne 1 ]]; then
    if [ "${mac[*]:1}" != "00 00 00 00 00 00" ]; then
      echo "==Get MAC address Success=="
      break
    fi
  fi

  sleep 3
done

#Set MAC Filter for EP/CC
mac_peer=("${mac[@]/#/0x}")
echo "Set MAC Address Filter for $peer_name: ${mac_peer[*]:1}"
ncsi_cmd 0x0e "${mac_peer[@]:1}" 0x02 0x01
ncsi_cmd 0x03

brctl addif br0 usb0
ip link set up usb0

echo "Detect USB Lost..."
while true; do
  usb_dev_lost
  usb_dev_detect
  brctl addif br0 usb0
  ip link set up usb0
  sleep 5
done


#!/bin/sh

echo "Initial CMC Config"
#Unblock command
/usr/local/bin/ipmb-util 8 0x68 0xd8 0xf2 0x00 0xff 0x00


#!/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
#

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

# This file contains definitions for the GPIO pins that were not otherwise
# defined in other files.  We should probably move some more of the
# definitions to this file at some point.

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

# FM_BOARD_BMC_REV_ID0
gpio_export FM_BOARD_BMC_REV_ID0 GPIOA0

# FM_BOARD_BMC_REV_ID1 / FM_CPU0_THERMTRIP_LVT3_PLD_N
gpio_export FM_CPU0_THERMTRIP_LVT3_PLD_N GPIOA1
ln -n /tmp/gpionames/FM_CPU0_THERMTRIP_LVT3_PLD_N /tmp/gpionames/FM_BOARD_BMC_REV_ID1

# BMC_EMMC_RST_N
gpio_export BMC_EMMC_RST_N GPIOA2

# FM_SPD_DDRCPU_LVLSHFT_EN
gpio_export FM_SPD_DDRCPU_LVLSHFT_EN GPIOA3

# SMB_SLOT1_ALT_N
gpio_export SMB_SLOT1_ALT_N GPIOA6

# SMB_SLOT2_ALT_N
gpio_export SMB_SLOT2_ALT_N GPIOA7

# FM_BOARD_BMC_SKU_ID0 / FM_MEM_THERM_EVENT_CPU0_LVT3_N
gpio_export FM_MEM_THERM_EVENT_CPU0_LVT3_N GPIOB0
ln -n /tmp/gpionames/FM_MEM_THERM_EVENT_CPU0_LVT3_N /tmp/gpionames/FM_BOARD_BMC_SKU_ID0

# FM_BOARD_BMC_SKU_ID1 / FM_MEM_THERM_EVENT_CPU1_LVT3_N
gpio_export FM_MEM_THERM_EVENT_CPU1_LVT3_N GPIOB1
ln -n /tmp/gpionames/FM_MEM_THERM_EVENT_CPU1_LVT3_N /tmp/gpionames/FM_BOARD_BMC_SKU_ID1

# FM_BOARD_BMC_SKU_ID2 / FM_CPU0_FIVR_FAULT_LVT3_PLD
gpio_export FM_CPU0_FIVR_FAULT_LVT3_PLD GPIOB2
ln -n /tmp/gpionames/FM_CPU0_FIVR_FAULT_LVT3_PLD /tmp/gpionames/FM_BOARD_BMC_SKU_ID2

# FM_BOARD_BMC_SKU_ID3 / FM_CPU1_FIVR_FAULT_LVT3_PLD
gpio_export FM_CPU1_FIVR_FAULT_LVT3_PLD GPIOB3
ln -n /tmp/gpionames/FM_CPU1_FIVR_FAULT_LVT3_PLD /tmp/gpionames/FM_BOARD_BMC_SKU_ID3

# FM_BOARD_BMC_SKU_ID4
gpio_export FM_BOARD_BMC_SKU_ID4 GPIOB4

# FM_BOARD_BMC_SKU_ID5
gpio_export FM_BOARD_BMC_SKU_ID5 GPIOB5

# FM_CPU0_PROCHOT_LVT3_BMC_N
gpio_export FM_CPU0_PROCHOT_LVT3_BMC_N GPIOB6

# FM_CPU1_PROCHOT_LVT3_BMC_N
gpio_export FM_CPU1_PROCHOT_LVT3_BMC_N GPIOB7

# FM_BOARD_BMC_REV_ID2 / FM_CPU1_THERMTRIP_LVT3_PLD_N
gpio_export FM_CPU1_THERMTRIP_LVT3_PLD_N GPIOD0
ln -n /tmp/gpionames/FM_CPU1_THERMTRIP_LVT3_PLD_N /tmp/gpionames/FM_BOARD_BMC_REV_ID2

# IRQ_TPM_BMC_SPI_N
gpio_export IRQ_TPM_BMC_SPI_N GPIOD1

# SMB_BMC_ADM1278_ALT_N
gpio_export SMB_BMC_ADM1278_ALT_N GPIOD6

# SMB_BMC_ADM1278_RST_N
gpio_export SMB_BMC_ADM1278_RST_N GPIOD7

# FP_BMC_RST_BTN_N
gpio_export FP_BMC_RST_BTN_N GPIOE0

# RST_BMC_RSTBTN_OUT_R_N, power reset to PCH
gpio_export RST_BMC_RSTBTN_OUT_R_N GPIOE1
gpio_set RST_BMC_RSTBTN_OUT_R_N 1

# FM_BMC_PWR_BTN_R_N
gpio_export FM_BMC_PWR_BTN_R_N GPIOE2

# FM_BMC_PWRBTN_OUT_R_N, power button to CPLD
gpio_export FM_BMC_PWRBTN_OUT_R_N GPIOE3
gpio_set FM_BMC_PWRBTN_OUT_R_N 1

# JTAG_MUX_SEL_0
gpio_export JTAG_MUX_SEL_0 GPIOE4
gpio_set JTAG_MUX_SEL_0 1

# JTAG_MUX_SEL_1
gpio_export JTAG_MUX_SEL_1 GPIOE5
gpio_set JTAG_MUX_SEL_1 1

# FP_FAULT_LED_N
gpio_export FP_FAULT_LED_N GPIOE6
gpio_set FP_FAULT_LED_N 1

# FM_CPU_ERR0_LVT3_N
gpio_export FM_CPU_ERR0_LVT3_N GPIOF0

# FM_CPU_ERR1_LVT3_N
gpio_export FM_CPU_ERR1_LVT3_N GPIOF1

# FM_CPU_ERR2_LVT3_N
gpio_export FM_CPU_ERR2_LVT3_N GPIOF2

# FM_BMC_DEBUG_ENABLE_N
gpio_export FM_BMC_DEBUG_ENABLE_N GPIOF3

# FM_BMC_UV_ADR_TRIGGER_EN
gpio_export FM_BMC_UV_ADR_TRIGGER_EN GPIOF4

# FM_BMC_FORCE_ADR_N
gpio_export FM_BMC_FORCE_ADR_N GPIOF5

# RST_PLTRST_BMC_N
gpio_export RST_PLTRST_BMC_N GPIOF6

# IRQ_BMC_PRDY_N
gpio_export IRQ_BMC_PRDY_N GPIOF7

# FM_CPU1_DISABLE_COD_N
gpio_export FM_CPU1_DISABLE_COD_N GPIOG0

# FM_CPU_MSMI_CATERR_LVT3_N
gpio_export FM_CPU_MSMI_CATERR_LVT3_N GPIOG1

# FM_PCH_BMC_THERMTRIP_N
gpio_export FM_PCH_BMC_THERMTRIP_N GPIOG2

# BMC_READY_N
gpio_export BMC_READY_N GPIOG3
gpio_set BMC_READY_N 1
# To disable Reset Tolerant
devmem_clear_bit 0x1e78003c 19

# IRQ_NMI_EVENT_N
gpio_export IRQ_NMI_EVENT_N GPIOG4

# IRQ_BMC_PCH_SMI_LPC_N
gpio_export IRQ_BMC_PCH_SMI_LPC_N GPIOG5

# IRQ_SMB3_M2_ALERT_N
gpio_export IRQ_SMB3_M2_ALERT_N GPIOG6

# LED_POSTCODE_0
gpio_export LED_POSTCODE_0 GPIOH0

# LED_POSTCODE_1
gpio_export LED_POSTCODE_1 GPIOH1

# LED_POSTCODE_2
gpio_export LED_POSTCODE_2 GPIOH2

# LED_POSTCODE_3
gpio_export LED_POSTCODE_3 GPIOH3

# LED_POSTCODE_4
gpio_export LED_POSTCODE_4 GPIOH4

# LED_POSTCODE_5
gpio_export LED_POSTCODE_5 GPIOH5

# LED_POSTCODE_6
gpio_export LED_POSTCODE_6 GPIOH6

# LED_POSTCODE_7
gpio_export LED_POSTCODE_7 GPIOH7

# PRSNT_PCIE_CABLE_1_N
gpio_export PRSNT_PCIE_CABLE_1_N GPIOI0

# PRSNT_PCIE_CABLE_2_N
gpio_export PRSNT_PCIE_CABLE_2_N GPIOI1

# FM_PFR_ACTIVE_N
gpio_export FM_PFR_ACTIVE_N GPIOI3

# FM_UARTSW_LSB_N
gpio_export FM_UARTSW_LSB_N GPIOL0

# FM_UARTSW_MSB_N
gpio_export FM_UARTSW_MSB_N GPIOL1

# IRQ_HSC_FAULT_N
gpio_export IRQ_HSC_FAULT_N GPIOL2

# FM_CPU1_MEMHOT_OUT_N
gpio_export FM_CPU1_MEMHOT_OUT_N GPIOL3

# FM_MASTER_MB_N
gpio_export FM_MASTER_MB_N GPIOL4
gpio_set FM_MASTER_MB_N 1

# JTAG_MUX_EN_N
gpio_export JTAG_MUX_EN_N GPIOL5

# IRQ_OC_DETECT_N
gpio_export IRQ_OC_DETECT_N GPIOM0

# IRQ_UV_DETECT_N
gpio_export IRQ_UV_DETECT_N GPIOM1

# FM_HSC_TIMER_EXP_N
gpio_export FM_HSC_TIMER_EXP_N GPIOM2

# P3V3_STBY_MON_ALERT
gpio_export P3V3_STBY_MON_ALERT GPIOM3

# FM_TPM_BMC_PRES_N
gpio_export FM_TPM_BMC_PRES_N GPIOM4

# SPI_BMC_BT_WP0_N
gpio_export SPI_BMC_BT_WP0_N GPIOM5

# SMB_BMC_MM5_ALT_N
gpio_export SMB_BMC_MM5_ALT_N GPIOM6

# SMB_BMC_MM5_RST_N
gpio_export SMB_BMC_MM5_RST_N GPIOM7

# REMOTE_DEBUG_DIS_N
gpio_export REMOTE_DEBUG_DIS_N GPION2

# FM_SOL_UART_CH_SEL
gpio_export FM_SOL_UART_CH_SEL GPION3

# IRQ_DIMM_SAVE_LVT3_N
gpio_export IRQ_DIMM_SAVE_LVT3_N GPION4

# LED_8S_2S_MODE_N
gpio_export LED_4S_2S_MODE_N GPION5

# Set debounce timer #1 value to 0x12E1FC ~= 100ms
$DEVMEM 0x1e780050 32 0x12E1FC

# Select debounce timer #1 for GPION6
devmem_clear_bit 0x1e780100 14
devmem_set_bit 0x1e780104 14

# FM_POST_CARD_PRES_BMC_N
gpio_export FM_POST_CARD_PRES_BMC_N GPION6

# FM_PWRBRK_N
gpio_export FM_PWRBRK_N GPION7

# FM_BMC_SKT_ID_0
gpio_export FM_BMC_SKT_ID_0 GPIOO0

# FM_BMC_SKT_ID_1
gpio_export FM_BMC_SKT_ID_1 GPIOO1

# FM_BMC_SKT_ID_2
gpio_export FM_BMC_SKT_ID_2 GPIOO2
mode=$(($(gpio_get FM_BMC_SKT_ID_2)))
kv set mb_skt $((mode<<2 |
        $(gpio_get FM_BMC_SKT_ID_1)<<1 |
        $(gpio_get FM_BMC_SKT_ID_0)))

# FM_SMB_RETIMER_1_ISO_EN
gpio_export FM_SMB_RETIMER_1_ISO_EN GPIOO3

# FM_SMB_RETIMER_2_ISO_EN
gpio_export FM_SMB_RETIMER_2_ISO_EN GPIOO4

# PRSNT_UPI_BD_1_N
gpio_export PRSNT_UPI_BD_1_N GPIOO5

# PRSNT_UPI_BD_2_N
gpio_export PRSNT_UPI_BD_2_N GPIOO6

# PRSNT_UPI_BD_3_N
gpio_export PRSNT_UPI_BD_3_N GPIOO7

# PRSNT_UPI_BD_4_N
gpio_export PRSNT_UPI_BD_4_N GPIOP0

# SMB_BMC_ASICBOX_EN
gpio_export SMB_BMC_ASICBOX_EN GPIOP1
gpio_set SMB_BMC_ASICBOX_EN 1

# FM_CM_READY_N
gpio_export FM_CM_READY_N GPIOP2

# RST_CM_N
gpio_export RST_CM_N GPIOP3
gpio_set RST_CM_N 1

# FM_ASIC_POWER_EN
gpio_export FM_ASIC_POWER_EN GPIOP4

# FM_ASIC_PWRGD
gpio_export FM_ASIC_PWRGD GPIOP5

# FM_BLADE_ID_0
gpio_export FM_BLADE_ID_0 GPIOP6

# FM_BLADE_ID_1
gpio_export FM_BLADE_ID_1 GPIOP7
if [ "$mode" -eq 1 ]; then  # 2S
  kv set mb_pos 0
else
  kv set mb_pos $(($(gpio_get FM_BLADE_ID_1)<<1 | $(gpio_get FM_BLADE_ID_0)))
fi

# RST_TCA9545_DDR_MUX_N
gpio_export RST_TCA9545_DDR_MUX_N GPIOQ6

# FM_BMC_CPU_PWR_DEBUG_N
gpio_export FM_BMC_CPU_PWR_DEBUG_N GPIOQ7

# DBP_PRESENT_N
gpio_export DBP_PRESENT_N GPIOR1

# FM_BIOS_SPI_BMC_CTRL
gpio_export FM_BIOS_SPI_BMC_CTRL GPIOR6

# FM_SYS_THROTTLE_LVC3
gpio_export FM_SYS_THROTTLE_LVC3 GPIOR7

# FM_MODULAR_ASD_EN
gpio_export FM_MODULAR_ASD_EN GPIOS0

# DBP_SYSPWROK
gpio_export DBP_SYSPWROK GPIOS1

# RST_RSMRST_BMC_N
gpio_export RST_RSMRST_BMC_N GPIOS2

# IRQ_SML0_ALERT_MUX_N
gpio_export IRQ_SML0_ALERT_MUX_N GPIOS3

# FP_LOCATE_LED, ID LED
gpio_export FP_LOCATE_LED GPIOS4
gpio_set FP_LOCATE_LED 0

# FM_2S_FAN_IO_EXP_RST
gpio_export FM_2S_FAN_IO_EXP_RST GPIOS6

# RST_SMB_OCP_MUX_N
gpio_export RST_SMB_OCP_MUX_N GPIOS7

# FM_FORCE_BMC_UPDATE_N
gpio_export FM_FORCE_BMC_UPDATE_N GPIOT0

# FP_LOCATE_LED_ACT
gpio_export FP_LOCATE_LED_ACT GPIOT5
gpio_set FP_LOCATE_LED_ACT 0

# OCP_V3_NIC_2_PWR_GOOD
gpio_export OCP_V3_NIC_2_PWR_GOOD GPIOT6

# BOARD_ID_MUX_SEL
gpio_export BOARD_ID_MUX_SEL GPIOU2
gpio_set BOARD_ID_MUX_SEL 0
kv set mb_rev $(($(gpio_get FM_BOARD_BMC_REV_ID2)<<2 |
        $(gpio_get FM_BOARD_BMC_REV_ID1)<<1 |
        $(gpio_get FM_BOARD_BMC_REV_ID0)))

kv set mb_sku $(($(gpio_get FM_BOARD_BMC_SKU_ID5)<<5 |
        $(gpio_get FM_BOARD_BMC_SKU_ID4)<<4 |
        $(gpio_get FM_BOARD_BMC_SKU_ID3)<<3 |
        $(gpio_get FM_BOARD_BMC_SKU_ID2)<<2 |
        $(gpio_get FM_BOARD_BMC_SKU_ID1)<<1 |
        $(gpio_get FM_BOARD_BMC_SKU_ID0)))

gpio_set BOARD_ID_MUX_SEL 1

# BMC_FORCE_NM_THROTTLE_N
gpio_export BMC_FORCE_NM_THROTTLE_N GPIOU3

# FM_CPU0_MEMHOT_OUT_N
gpio_export FM_CPU0_MEMHOT_OUT_N GPIOU5

# OCP_V3_NIC_1_PWR_GOOD
gpio_export OCP_V3_NIC_1_PWR_GOOD GPIOV3

# FM_SLPS3_N
gpio_export FM_SLPS3_N GPIOY0

# FM_SLPS4_N
gpio_export FM_SLPS4_N GPIOY1

# PWRGD_SYS_PWROK, power GOOD from CPLD
gpio_export PWRGD_SYS_PWROK GPIOY2

# FM_BMC_ONCTL_N
gpio_export FM_BMC_ONCTL_N GPIOY3

# FM_CPU_CATERR_LVT3_N
gpio_export FM_CPU_CATERR_LVT3_N GPIOZ0

# PWRGD_CPU0_LVC3
gpio_export PWRGD_CPU0_LVC3 GPIOZ1

# FM_CPU_MSMI_LVT3_N
gpio_export FM_CPU_MSMI_LVT3_N GPIOZ2

# FM_BMC_PCH_SCI_LPC_N
gpio_export FM_BMC_PCH_SCI_LPC_N GPIOZ3

# UV_HIGH_SET
gpio_export UV_HIGH_SET GPIOZ4

# FM_OC_DETECT_EN_N
gpio_export FM_OC_DETECT_EN_N GPIOZ5

# FM_SML1_PMBUS_ALERT_EN_N
gpio_export FM_SML1_PMBUS_ALERT_EN_N GPIOZ6

# FM_BMC_LED_CATERR_N
gpio_export FM_BMC_LED_CATERR_N GPIOZ7
gpio_set FM_BMC_LED_CATERR_N 1

# P3V_BAT_SCALED_EN
gpio_export P3V_BAT_SCALED_EN GPIOAA0
gpio_set P3V_BAT_SCALED_EN 0

# IRQ_SML1_PMBUS_BMC_ALERT_N
gpio_export IRQ_SML1_PMBUS_BMC_ALERT_N GPIOAA1

# FM_PVCCIN_CPU0_PWR_IN_ALERT_N
gpio_export FM_PVCCIN_CPU0_PWR_IN_ALERT_N GPIOAA2

# FM_PVCCIN_CPU1_PWR_IN_ALERT_N
gpio_export FM_PVCCIN_CPU1_PWR_IN_ALERT_N GPIOAA3

# FM_BMC_PREQ_N
gpio_export FM_BMC_PREQ_N GPIOAA4

# FM_JTAG_TCK_MUX_SEL
gpio_export FM_JTAG_TCK_MUX_SEL GPIOAA5
gpio_set FM_JTAG_TCK_MUX_SEL 0

# IRQ_SMI_ACTIVE_BMC_N
gpio_export IRQ_SMI_ACTIVE_BMC_N GPIOAA6

# FM_BIOS_POST_CMPLT_BMC_N
gpio_export FM_BIOS_POST_CMPLT_BMC_N GPIOAA7

# FM_BMC_BMCINIT
gpio_export FM_BMC_BMCINIT GPIOAB0

# PECI_MUX_SELECT
gpio_export PECI_MUX_SELECT GPIOAB1
gpio_set PECI_MUX_SELECT 0

# PWRGD_BMC_PS_PWROK
gpio_export PWRGD_BMC_PS_PWROK GPIOAB3

# workaround for unexpected DIMM_MUX status
if [ ! -L "${SYSFS_I2C_DEVICES}/4-0076/driver" ] ||
   [ ! -L "${SYSFS_I2C_DEVICES}/4-0077/driver" ]; then
  logger -t "setup-gpio" -p user.warn "Reset DIMM_MUX"
  echo low > /tmp/gpionames/RST_TCA9545_DDR_MUX_N/direction
  usleep 10000
  echo in > /tmp/gpionames/RST_TCA9545_DDR_MUX_N/direction
  usleep 10000
fi

if [ ! -L "${SYSFS_I2C_DEVICES}/4-0076/driver" ]; then
  if i2c_bind_driver pca953x 4-0076 2 2>/dev/null; then
    echo "rebind 4-0076 to driver pca953x successfully"
  fi
fi

# I/O Expander TCA9539 0xEC
gpio_export_ioexp 4-0076 FM_SLOT1_PRSNT_N 0
gpio_export_ioexp 4-0076 FM_SLOT2_PRSNT_N 1
gpio_export_ioexp 4-0076 RST_RTCRST_N 10
gpio_export_ioexp 4-0076 RST_USB_HUB_N 11

if [ ! -L "${SYSFS_I2C_DEVICES}/4-0077/driver" ]; then
  if i2c_bind_driver pca953x 4-0077 2 2>/dev/null; then
    echo "rebind 4-0077 to driver pca953x successfully"
  fi
fi

# I/O Expander TCA9539 0xEE
gpio_export_ioexp 4-0077 IRQ_PVCCIN_CPU0_VRHOT_LVC3_N 0
gpio_export_ioexp 4-0077 IRQ_PVCCIN_CPU1_VRHOT_LVC3_N 1
gpio_export_ioexp 4-0077 IRQ_PVDDQ_ABC_CPU0_VRHOT_LVC3_N 2
gpio_export_ioexp 4-0077 IRQ_PVDDQ_DEF_CPU0_VRHOT_LVC3_N 3
gpio_export_ioexp 4-0077 IRQ_PVDDQ_ABC_CPU1_VRHOT_LVC3_N 4
gpio_export_ioexp 4-0077 IRQ_PVDDQ_DEF_CPU1_VRHOT_LVC3_N 5
gpio_export_ioexp 4-0077 FM_CPU0_SKTOCC_LVT3_PLD_N 6
gpio_export_ioexp 4-0077 FM_CPU1_SKTOCC_LVT3_PLD_N 7
gpio_export_ioexp 4-0077 HP_LVC3_OCP_V3_2_PRSNT2_N 8
gpio_export_ioexp 4-0077 HP_LVC3_OCP_V3_1_PRSNT2_N 9

# Mode Setting (2S: mode=1 4S: mode=0)
if [ "$mode" -eq 1 ]; then
    gpio_set LED_4S_2S_MODE_N 0
else
    gpio_set LED_4S_2S_MODE_N 1
fi


#!/bin/sh
#
# 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

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

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

store_clear_por


#!/bin/sh

# check usb hub i2c register
Result=$(i2cget -f -y 4 0x2C 0xFF i 2>&1 1>/dev/null)

# reset usb hub if usb hub i2c register was not available
if [ -n "$Result" ]; then
    echo "Reset USB Hub"
    i2cset -f -y 4 0x76 0x07 0xf7
    i2cset -f -y 4 0x76 0x03 0xf7
    sleep 1
    i2cset -f -y 4 0x76 0x07 0xff
fi

echo "Config USB Hub"
i2cset -f -y 4 0x2c 0x00 0x24 0x04 0x14 0x25 0x00 0x02 0xBB 0x20 0x02 0x00 0x00 0x00 0x01 0x32 0x01 0x32 0x32 s
i2cset -f -y 4 0x2c 0xff 0x01 s


#!/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

sku=$(kv get mb_sku)
rev=$(kv get mb_rev)

# retry to probe pxe1110c (pxe1211c).
# note: still keep pxe1110c in dts, so it's the
# 1st device to be probed on i2c-1
if [ ! -L "${SYSFS_I2C_DEVICES}/1-004a/driver" ]; then
  if i2c_bind_driver pxe1211c 1-004a 4 2>/dev/null; then
    echo "rebind 1-004a to driver pxe1211c successfully"
  fi
fi

#DVT SKU_ID[2:1] = 00(TI), 01(INFINEON), TODO: 10(3rd Source)
sku=$((sku & 0x2))
if [ $sku -eq 0 ]; then
  i2c_device_add 1 0x60 tps53688
  i2c_device_add 1 0x62 tps53688
  i2c_device_add 1 0x66 tps53688
  i2c_device_add 1 0x68 tps53688
  i2c_device_add 1 0x6c tps53688
  i2c_device_add 1 0x70 tps53688
  i2c_device_add 1 0x72 tps53688
  i2c_device_add 1 0x76 tps53688
else
  i2c_device_add 1 0x60 xdpe12284
  i2c_device_add 1 0x62 xdpe12284
  i2c_device_add 1 0x66 xdpe12284
  i2c_device_add 1 0x68 xdpe12284
  i2c_device_add 1 0x6c xdpe12284
  i2c_device_add 1 0x70 xdpe12284
  i2c_device_add 1 0x72 xdpe12284
  i2c_device_add 1 0x76 xdpe12284
fi

if [ "$rev" -lt 2 ]; then
  i2c_device_add 4 0x54 24c64
else
  i2c_device_add 4 0x57 24c64
fi

if [ "$(gpio_get HP_LVC3_OCP_V3_1_PRSNT2_N)" = "0" ]; then
  i2c_device_add 17 0x50 24c32
fi

if [ "$(gpio_get HP_LVC3_OCP_V3_2_PRSNT2_N)" = "0" ]; then
  i2c_device_add 18 0x52 24c32
  if [ "$(kv get eth1_disable_ipv6 persistent 2>/dev/null)" != "0" ]; then
    echo 1 > /proc/sys/net/ipv6/conf/eth1/disable_ipv6
  fi
  ifconfig eth1 up
fi


#!/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

# Sync BMC's date with the server
sync_date()
{
  sleep 1
  # if no ntp peer has been declared the system peer
  if ! /usr/sbin/ntpq -p | grep '^\*' > /dev/null ; then
    echo Syncing up BMC time with server...

    position=$(($(/usr/bin/kv get mb_pos)))
    host=$(($(/usr/bin/kv get mb_skt) & 0x1))  #0: Master 1:Slave

    if [ $position -eq 0 ]; then #position 0
      addr=$((16#22))
    else
      addr=$((16#20))
    fi

    # Use standard IPMI command 'get-sel-time' to read RTC time
    for i in {1..10};
    do
    #Master
      if [ $host -eq 0 ]; then
        output=$(/usr/local/bin/ipmb-util 5 0x2c 0x28 0x48)
        if [ ${#output} == 12 ]
        then
          break;
        fi

        if [ ${i} == 10 ]
        then
          exit
        fi
    #Slave
      else
        output=$(/usr/local/bin/ipmb-util 2 $addr 0xC0 0x34 0x01 0x0a 0x48)
        if [ ${#output} == 12 ]
        then
          break;
        fi

        if [ ${i} == 10 ]
        then
          echo Sync time with Master BMC
          output=$(/usr/local/bin/ipmb-util 2 $addr 0x28 0x48)
        fi
      fi
      usleep 300
    done

    sys_date=$(date +%s)
    set_date=$((16#$(echo "$output" | awk '{print $4$3$2$1}')))

    if [ "$sys_date" -ge $set_date ]; then
      echo "Use BMC date"
      set_date="$sys_date"
    fi

    date -s @"$set_date"
    test -x /etc/init.d/hwclock.sh && /etc/init.d/hwclock.sh stop
  fi
}

sync_date


#!/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-sensord
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Setup sensor monitoring
### END INIT INFO

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

# Call "fw-util vr --version" once before sensor monitoring to store vr information
echo "Get VR FW version... "
/usr/bin/fw-util vr --version > /dev/null

# shellcheck disable=2039
echo -n "Setup sensor monitoring for FBAL... "
runsv /etc/sv/sensord > /dev/null 2>&1 &

echo "done."


#!/bin/bash

# Read AST2620 register SCU014 [23:16] to retrieve the board hardware revision.

SCU014_REG=0x1e6e2014
HW_REV_BIT=16
BOARD_REV=$(($(($(devmem "${SCU014_REG}") >> "${HW_REV_BIT}")) & 0xff))
echo "BMC Board Revision: A${BOARD_REV}"


#!/bin/bash

# Copyright 2022-present Facebook. All Rights Reserved.

# shellcheck disable=SC2034

wedge_board_type() {
    echo 'FBDARWIN'
}

wedge_slot_id() {
    printf "1\n"
}

wedge_board_rev() {
    # Assume P1
    return 1
}

retry_command() {
    # Retry command up to $1 attempts
    local retries=$1
    shift

    local count=0
    until "$@"; do
        exit=$?
        count=$((count+1))
        if [ "$count" -lt "$retries" ]; then
            msg="Attempt $count/$retries failed with $exit, retrying..."
            echo "$msg"
            logger retry_command: "$msg"
        else
            msg="Retry $count/$retries failed with $exit, no more retries left"
            echo "$msg"
            logger retry_command: "$msg"
            return $exit
        fi
    done
    return 0
}

do_sync() {
   # Try to flush all data to MMC and remount the drive read-only. Sync again
   # because the remount is asynchronous.
   partition="/dev/mmcblk0"
   mountpoint="/mnt/data1"

   sync
   # rsyslogd logs to eMMC, so we must stop it prior to remouting.
   systemctl stop syslog.socket rsyslog.service
   sleep .05
   if [ -e $mountpoint ]; then
      retry_command 5 mount -o remount,ro $partition $mountpoint
      sleep 1
   fi
   sync
}

userver_power_is_on() {
    return 0
}

userver_power_on() {
    return 0
}

userver_power_off() {
    echo "FBDARWIN doesn't support SCM power off!"
    return 1
}

userver_reset() {
    retries=3
    for _ in $(seq $retries); do
        gpio_set_value BMC_SYS_PWR_CYC1 1
        sleep 1
        gpio_set_value BMC_SYS_PWR_CYC1 0
        sleep 5
    done
}

chassis_power_cycle() {
    do_sync

    gpio_set_value BMC_SYS_PWR_CYC0 1
    sleep 8

    # The chassis shall be reset now... if not, we are in trouble
    echo "ERROR: unable to power cycle chassis!!!"
    gpio_set_value BMC_SYS_PWR_CYC0 0
    exit 1
}

bmc_mac_addr() {
    weutil bmc | grep '^Extended MAC Base' | cut -d' ' -f 4
}

userver_mac_addr() {
    weutil CHASSIS 2>&1 | grep "MAC Base" | cut -d ' ' -f 4
}


#!/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

# shellcheck disable=SC2039
usage() {
    echo "Reads/writes Bcm53134 registers"
    echo
    echo "read[(8|16|32|64)] <page> <addr>"
    echo "write[(8|16|32|64)] <page> <addr> <val>"
    echo
    echo "read/write are equivalent to read8/write8"
}

mdio0_base_reg=0x1e650000
mdio_ctrl_reg=0x0
mdio_read_reg=0x4
pseudo_phy_port_addr=0x1e

scu_reset_set2=0x1e6e2050
scu_reset_clear2=$((scu_reset_set2 + 0x4))
scu_reset_mii_controller=$((1 << 3))
scu_pin_control8=0x1e6e2430
scu_mdcmdio_enable=$(( (1 << 16) | (1 << 17) ))

trap cleanup EXIT INT TERM QUIT

MDIO_INITIALIZED=0
cleanup() {
    if [ $MDIO_INITIALIZED -eq 1 ]
    then
        mdio_restore
    fi
}

mdio_init() {
    MDIO_INITIALIZED=1
    devmem "$scu_reset_clear2" 32 "$scu_reset_mii_controller"

    val=$(devmem "$scu_pin_control8")
    devmem "$scu_pin_control8" 32 $((val | scu_mdcmdio_enable))
}

mdio_restore() {
    devmem "$scu_reset_set2" 32 "$scu_reset_mii_controller"
    val=$(devmem "$scu_pin_control8")
    devmem "$scu_pin_control8" 32 $((val & ~scu_mdcmdio_enable))
    MDIO_INITIALIZED=0
}

to_hex() {
    local val=$1
    printf "0x%x" "$val"
}

devmem_read() {
    local reg_addr=$1
    local mem_addr

    mem_addr=$(to_hex $((mdio0_base_reg + reg_addr)))
    devmem "$mem_addr"
}

devmem_write() {
    local reg_addr=$1
    local val mem_addr

    val=$(to_hex "$2")
    mem_addr=$(to_hex $((mdio0_base_reg + reg_addr)))
    devmem "$mem_addr" 32 "$val"
}

mdio_read() {
    local addr=$1
    local fire_busy clause_22 read_request reg_val read_reg_val ctrl_idle

    fire_busy=$(( 1 << 31 ))
    clause_22=$(( 1 << 28 ))
    read_request=$(( 1 << 27 ))
    reg_val=$(( fire_busy \
              | clause_22 \
              | read_request \
              | ( pseudo_phy_port_addr << 21 ) \
              | ( addr << 16 ) ))

    devmem_write $mdio_ctrl_reg $reg_val
    ctrl_idle=$(( 1 << 16 ))
    desc=$(printf "read 0x%x" "$addr")
    mdio_wait_op_complete "$mdio_read_reg" "$ctrl_idle" "$ctrl_idle" "$desc"

    read_reg_val=$(devmem_read $mdio_read_reg)
    echo $(( read_reg_val & 0xffff ))
}

mdio_write() {
    local addr=$1
    local val=$2
    local fire_busy clause_22 write_request reg_val

    fire_busy=$(( 1 << 31 ))
    clause_22=$(( 1 << 28 ))
    write_request=$(( 1 << 26 ))
    reg_val=$(( fire_busy \
              | clause_22 \
              | write_request \
              | ( pseudo_phy_port_addr << 21 ) \
              | ( addr << 16 ) \
              | val ))

    devmem_write $mdio_ctrl_reg "$reg_val"

    desc=$(printf "write 0x%x 0x%x" "$addr" "$val")
    mdio_wait_op_complete "$mdio_ctrl_reg" "$fire_busy" 0 "$desc"
}

mdio_wait_op_complete() {
    local mdio_reg=$1
    local mask=$2
    local wait_val=$3
    local desc=$4
    local timeout=5
    local interval=0.1
    local val

    local time_limit=$(( $(date +%s) + timeout ))
    while [ "$(date +%s)" -lt $time_limit ]
    do
        val=$(devmem_read "$mdio_reg")
        if [ $(( val & "$mask" )) -eq "$wait_val" ]
        then
            return
        fi
        sleep $interval
    done

    echo "Error: timed out waiting for operation to complete: $desc" >&2
    exit 1
}

oob_page_reg=16
oob_addr_reg=17
oob_data_reg_base=24

reg_read() {
    local page=$1
    local addr=$2
    local data_size=$3
    local data data_reg_num reg_val

    data=$(reg_page_data "$page" 1)
    mdio_write $oob_page_reg "$data"

    data=$(reg_addr_data "$addr" 0x2)
    mdio_write $oob_addr_reg "$data"

    reg_wait_addr_reg_acked

    # Read data registers
    local val=0
    num_data_regs=$(( ( data_size + 1 ) / 2 ))
    local reg_idx=0
    while [ $reg_idx -lt $num_data_regs ]
    do
        data_reg_num=$(( oob_data_reg_base + reg_idx ))
        reg_val=$(mdio_read $data_reg_num)
        val=$(( val | ( reg_val << ( reg_idx * 16 ) ) ))

        reg_idx=$(( reg_idx + 1 ))
    done

    binary_str=$(val_to_binary_str "$val" "$data_size")
    printf "0x%x/0x%x 0x%x == $binary_str\n" "$page" "$addr" $val

    reg_clear_access_enable
}

reg_write() {
    local page=$1
    local addr=$2
    local val=$3
    local data_size=$4
    local data reg_val data_reg_num

    data=$(reg_page_data "$page" 1)
    mdio_write $oob_page_reg "$data"

    # Write data registers
    num_data_regs=$(( ( data_size + 1 ) / 2 ))
    local reg_idx=0
    while [ $reg_idx -lt $num_data_regs ]
    do
        data_reg_num=$(( oob_data_reg_base + reg_idx ))
        reg_val=$(( ( val >> ( reg_idx * 16 ) ) & 0xffff ))
        mdio_write $data_reg_num $reg_val

        reg_idx=$(( reg_idx + 1 ))
    done

    data=$(reg_addr_data "$addr" 0x1)
    mdio_write $oob_addr_reg "$data"

    reg_wait_addr_reg_acked
    reg_clear_access_enable
}

reg_wait_addr_reg_acked() {
    local timeout=60
    local interval=0.1
    local time_limit response op

    time_limit=$(( $(date +%s) + timeout ))
    while [ "$(date +%s)" -lt $time_limit ]
    do
        response=$(mdio_read $oob_addr_reg)
        op=$(( response & 0x3 ))
        if [ $op -eq 0 ]
        then
            return
        fi

        sleep $interval
    done

    echo "Error: timed out waiting for addr reg to be acknowledged" >&2
    exit 1
}

reg_clear_access_enable() {
    data=$(reg_page_data 0 0)
    mdio_write $oob_page_reg "$data"
}

reg_page_data() {
    local page=$1
    local access_enable=$2
    local data=$(( page << 8 ))
    data=$(( data | access_enable ))
    echo $data
}

reg_addr_data() {
    local addr=$1
    local op=$2
    local data=$(( addr << 8 ))
    data=$(( data | op ))
    echo $data
}

val_to_binary_str() {
    local val=$1
    local data_size=$2
    local i=$(( data_size * 8 ))

    while [ $i -gt 0 ]
    do
        i=$(( i - 1 ))
        printf "%d" $(( ( val >> i ) & 0x1 ))
        if [ $i -gt 0 ] && [ $(( i % 4 )) -eq 0 ]
        then
            printf " "
        fi
    done
}

handle_read() {
    local size=$1
    shift
    if [ $# -lt 2 ]
    then
        echo "Error: missing arguments" >&2
        usage
        exit 1
    fi
    local page=$1
    local addr=$2
    local data_size=$(( size / 8 ))
    reg_read "$page" "$addr" "$data_size"
}

handle_write() {
    local size=$1
    shift
    if [ $# -lt 3 ]
    then
        echo "Error: missing arguments" >&2
        usage
        exit 1
    fi
    local page=$1
    local addr=$2
    local val=$3
    local data_size=$(( size / 8 ))
    reg_write "$page" "$addr" "$val" "$data_size"
}

if [ $# -lt 1 ]
then
    echo "Error: missing command" >&2
    usage
    exit 1
fi

command="$1"
shift
case "$command" in
    read8) cmd_type="read"; size="8";;
    read16) cmd_type="read"; size="16";;
    read32) cmd_type="read"; size="32";;
    read64) cmd_type="read"; size="64";;
    write8) cmd_type="write"; size="8";;
    write16) cmd_type="write"; size="16";;
    write32) cmd_type="write"; size="32";;
    write64) cmd_type="write"; size="64";;
    *)
        usage
        exit 1
        ;;
esac

mdio_init

if [ "$cmd_type" = "read" ]
then
    handle_read "$size" "$@"
else
    handle_write "$size" "$@"
fi


#!/bin/bash
#
# 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:          gpio-setup
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description:  Set up GPIO pins as appropriate
### END INIT INFO

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

setup_gpio_fbdarwin_evt() {
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOB1 BMC_ALIVE
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOC3 TPM_BFLSH_WP_L
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOC4 BMC_MODE
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOG6 BMC_BOARD_EEPROM_WP_L
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOO0 BMC_SYS_PWR_CYC0
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOO2 BMC_SYS_PWR_CYC1
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOO4 OOB_EEPROM_SPI_SEL
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOO6 OOB_RST
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOX7 SPI_TPM_PIRQ_N
    gpio_export_by_name  "${ASPEED_GPIO}" GPIOY3 BMC_EMMC_RST
}

setup_gpio_fbdarwin_evt

gpio_set_direction BMC_ALIVE out
gpio_set_direction TPM_BFLSH_WP_L in
gpio_set_direction BMC_MODE in
gpio_set_direction BMC_BOARD_EEPROM_WP_L out
gpio_set_direction BMC_SYS_PWR_CYC0 out
gpio_set_direction BMC_SYS_PWR_CYC1 out
gpio_set_direction OOB_EEPROM_SPI_SEL out
gpio_set_direction OOB_RST out
gpio_set_direction BMC_EMMC_RST out
gpio_set_direction SPI_TPM_PIRQ_N in

# Once we set "out", output values will be random unless we set them
# Set Default GPIO values
# Set BMC_EMMC_RST High to prevent EMMC disable
gpio_set BMC_EMMC_RST 1

gpio_set_value BMC_ALIVE 1
gpio_set_value BMC_BOARD_EEPROM_WP_L 1 # Disabled
gpio_set_value BMC_SYS_PWR_CYC0 0
gpio_set_value BMC_SYS_PWR_CYC1 0
gpio_set_value OOB_EEPROM_SPI_SEL 0
gpio_set_value OOB_RST 0


#!/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_board.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Setup the board
### END INIT INFO

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

#
# Setup oob switch BCM53134, just in case the settings are not expected.
#
setup_oob_switch() {
    control_page="0x0"
    port_state_reg="0xe"
    port_state_reg_val="0x8b"
    imp_rgmi_control_reg="0x60"
    imp_rgmi_control_reg_val="0x0"
    ieee_vlan_control_page="0x34"
    vlan_port2_reg="0x14"
    vlan_port2_val="0xffa"

    # Check BCM53134 registers
    curr_speed=$(oob-mdio-util.sh read8 "$control_page" "$port_state_reg"|
               cut -d' ' -f2)
    curr_clk_dly=$(oob-mdio-util.sh read8 "$control_page" "$imp_rgmi_control_reg"|
                 cut -d' ' -f2)
    if [ "$curr_speed" = "$port_state_reg_val" ] && \
       [ "$curr_clk_dly" = "$imp_rgmi_control_reg_val" ]; then
        # Register values are as expected
        return 0
    fi

    echo "BCM53134 registers not as expected. Configuring now."
    echo "Re-program the BCM53134 EEPROM to fix this permanently."

    oob-mdio-util.sh write8 "$control_page" "$port_state_reg" "$port_state_reg_val"
    oob-mdio-util.sh write8 "$control_page" "$imp_rgmi_control_reg" \
                            "$imp_rgmi_control_reg_val"

    # Enable Port 2 which is used on some platforms
    oob-mdio-util.sh write16 "$ieee_vlan_control_page" "$vlan_port2_reg" "$vlan_port2_val"
}

setup_oob_switch


#!/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:          find_serfmon.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description:  Find Serfmon string from mTerm log and cache it
### END INIT INFO

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

MTERM_LOGFILE="/var/log/mTerm_wedge.log"
SERFMON_CACHE="/mnt/data1/.serfmon.txt"
MACMON_CACHE="/mnt/data1/.macmon.txt"
CHASSIS_EEPROM_CACHE="/mnt/data1/.chassis_eeprom"
SERFMON_REGEX="\!serfmon\:.*\:.*\:.*$"
MACMON_REGEX="\!macmon\:.*\:.*\:.*$"

create_dummy_chassis_eeprom() {
    dummy_pca="PCA000000000"

    # Don't create dummy EEPROM until serfmon string is seen
    if [ ! -f "$SERFMON_CACHE" ]; then
       return
    fi

    # Extract SN from Serfmon Format \!serfmon\:.*\:.*\:.*$
    chassis_serial="$(awk -F":" '{print $3}' "$SERFMON_CACHE")"

    # Create Fake EEPROM file for weutil in expected format
    printf "\x00\x00\x00\x03\x00\x00\x00\x00\x30\x30\x30\x32%s%s\x31\x31\x31"\
        "$dummy_pca" "$chassis_serial" > "$CHASSIS_EEPROM_CACHE"

    # How many bytes to pad EEPROM file
    pad_bytes=211

    # If a cached Macmon string exists, add that to the EEPROM
    if [ -f "$MACMON_CACHE" ]; then
       chassis_mac="$(awk -F":" '{print $3}' "$MACMON_CACHE")"

       # Add MAC TLV. MAC is 12 (0x43 = C) bytes in length
       printf "\x30\x35\x30\x30\x30\x43%s" "$chassis_mac" >> "$CHASSIS_EEPROM_CACHE"
       pad_bytes=$((pad_bytes - 18))
    fi

    # Add an end TLV.
    printf "\x30\x30\x30\x30\x30\x30" >> "$CHASSIS_EEPROM_CACHE"

    # Pad file with all 0xFFs to size
    dd if=/dev/zero bs=1 count=$pad_bytes \
       2>/dev/null | tr "\000" "\377" >> "$CHASSIS_EEPROM_CACHE"
}

maybe_update_cache() {
    # Check the mTerm logfile for the given regex. If found, update the cache_file
    local -n cached_value="$1"
    local -n cache_updated="$2"
    regex="$3"
    cache_file="$4"
    name="$5"

    # Always clear update flag first
    cache_updated=0

    if grep -qE "$regex" "$MTERM_LOGFILE"; then
        # Detect if string found in mTerm log
        read_value="$(grep -oE "$regex" "$MTERM_LOGFILE" | tail -n 1)"

        # Read cached string from eMMC
        if [ -f "$cache_file" ]; then
            cached_value="$(cat "$cache_file")"
        else
            cached_value=""
        fi

        # If mTerm's string value doesn't match the cache, update it
        if [ "$read_value" != "$cached_value" ]; then
            echo "$read_value" > "$cache_file"
            echo "Registered new $name string!"
            cached_value="$(cat "$cache_file")"
            echo "$read_value"
            cache_updated=1
        fi
    fi
}

# Print cached Serfmon/Macmon strings on starting service
cached_serfmon=""
if [ -f "$SERFMON_CACHE" ]; then
    cached_serfmon="$(cat "$SERFMON_CACHE")"
    echo "$cached_serfmon"
fi

cached_macmon=""
if [ -f "$MACMON_CACHE" ]; then
    cached_macmon="$(cat "$MACMON_CACHE")"
    echo "$cached_macmon"
fi

if [ "$cached_serfmon" != "" ] || [ "$cached_macmon" != "" ]; then
    create_dummy_chassis_eeprom
fi

serfmon_updated=0
macmon_updated=0
while true; do
    if [ -f "$MTERM_LOGFILE" ]; then
        maybe_update_cache cached_serfmon serfmon_updated "$SERFMON_REGEX" \
            "$SERFMON_CACHE" "Serfmon"
        maybe_update_cache cached_macmon macmon_updated "$MACMON_REGEX" \
            "$MACMON_CACHE" "Macmon"

        if [ "$serfmon_updated" != 0 ] || [ "$macmon_updated" != 0 ]; then
            create_dummy_chassis_eeprom
        fi
    fi

    # Sleep 15 seconds until the next loop.
    # reduce for faster scan.
    sleep 15
done


#!/bin/bash

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

printf "%-1s | %-3s | %-30s\n" "v" "dir" "GPIONAME"
for i in /tmp/gpionames/*
do
   gpio="$(basename "$i")"
   val="$(gpio_get_value "$gpio")"
   direction="$(gpio_get_direction "$gpio")"
   printf "%-1s | %-3s | %-30s\n" "$val" "$direction" "$gpio"
done


#!/bin/bash
#
# 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
#

# This utility prints the meta information for specified boot flash
# mtd partition
START_OFFSET_KB=960
LEN_KB=64

usage() {
    echo "Usage $0 [flash0|flash1]"
}

case "$1" in
    flash0)
        mtd="$(grep flash0 /proc/mtd | awk '{print $1}' | tr -d ':')"
        ;;
    flash1)
        mtd="$(grep flash1 /proc/mtd | awk '{print $1}' | tr -d ':')"
        ;;
    *)
        usage
        exit 1
        ;;
esac

dd if=/dev/"$mtd" of=/tmp/."$1"_meta bs=1K skip="$START_OFFSET_KB" count="$LEN_KB"
strings /tmp/."$1"_meta


#!/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
#

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

trap cleanup EXIT
trap handle_signal INT TERM QUIT

OOB_EEPROM_SPI_PATH="/sys/bus/spi/devices/spi1.1/spi1.10/nvmem"

usage() {
    echo "Read or write to the BCM53134 OOB EEPROM"
    echo
    echo "read <file>"
    echo "write <file>"
    echo "version"
}

grab_uWire() {
    gpio_set_value OOB_EEPROM_SPI_SEL 1
}

ungrab_uWire() {
    gpio_set_value OOB_EEPROM_SPI_SEL 0
}

cleanup() {
    ungrab_uWire
}

handle_signal() {
    echo "Exiting because of signal" >&2
    cleanup
    exit 1
}

eeprom_read() {
    file="$1"
    file_temp="$file"_temp
    echo "Reading spi1.1 BCM53134P EEPROM to $file..."
    # Add retry to BCM53134_EE read in case it fails
    for n in 1 2 3 4 5
    do
        echo "Reading $file $n times"
        dd if="$OOB_EEPROM_SPI_PATH" of="$file"
        dd if="$OOB_EEPROM_SPI_PATH" of="$file_temp"
        if ! diff "$file" "$file_temp" >/dev/null; then
            echo "Readback file differ on attempt $n"
            # read-back file differ
            rm -rf "$file"*
        else
            # read-back file same
            rm -rf "$file_temp";
            return;
        fi
    done
    logger -p user.err "Unable to read the correct $file after 5 retries"
    exit 1
}

eeprom_write() {
    file=$1
    echo "Verifying target binary to program..."
    # We expect 0x01FF to be read in a certain offset of the binary
    # If we get 0xFF01, the endianness of the binary is likely incorrect
    # If we get neither, the binary is not recognized
    magic_bytes="$(dd if="$file" bs=1 skip=2 count=2 2>/dev/null | hexdump -n2)"
    if echo "$magic_bytes" | grep -q "01ff"; then
        echo "Binary endianness is big endian"
    elif echo "$magic_bytes" | grep -q "ff01"; then
        echo "Binary endianness is little endian"
        echo "Are you sure the binary is in the correct format?"
        exit 1
    else
        echo "Unable to match magic byte in binary"
        echo "Are you sure the binary is correct?"
        exit 1
    fi
    echo "Writing $file to spi1.1 BCM53134P EEPROM..."
    dd if="$file" of="$OOB_EEPROM_SPI_PATH"
}

eeprom_version() {
    local version
    version_file="/tmp/version.bin"
    eeprom_read $version_file >/dev/null 2>&1
    # Failure of eemprom_read terminates the process;
    # don't need to check return value
    version="0x$(hexdump $version_file | awk '{$1=""}1' | tr -d "[:space:]" | tail -c 4)"
    printf "Version: %d.%d\n" $(( version & 0xff )) $(( version >> 8 ))
    rm -rf $version_file
}

if [ $# -lt 1 ]
then
    echo "Error: missing command" >&2
    usage
    exit 1
fi

# Only allow one instance of script to run at a time.
script=$(realpath "$0")
exec 100< "$script"
flock -n 100 || { echo "ERROR: $0 already running" && exit 1; }

command="$1"
shift

grab_uWire
case "$command" in
    read)
        eeprom_read "$@"
        ;;
    write)
        eeprom_write "$@"
        ;;
    version)
        eeprom_version
        ;;
    *)
        echo "Error: invalid command: $command" >&2
        usage
        exit 1
        ;;
esac


#!/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
#

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

trap handle_signal INT TERM QUIT

# mdio prints in the format "PAGE_HEX/OFFSET_HEX VALUE_HEX == VALUE_BIN\n"
MDIO_READ_PATTERN="^.* (0x[a-fA-F0-9]+).*$"

# Global variable to stack tabs for formatting
tab=""

usage() {
    echo "Read BCM53134P (oob switch) port status registers"
    echo ""
    echo "# To dump all port status"
    echo "oob-status.sh"
    echo "# To dump port status for ports in 0, 1, 2, IMP"
    echo "oob-status.sh [Port(s)]"
    echo "# To print only link status"
    echo "oob-status.sh link_status [Port(s)]"
    echo "# To print only link speed"
    echo "oob-status.sh link_speed [Port(s)]"
    echo ""
    echo "Example:"
    echo ""
    echo "oob-status.sh link_status 0 IMP"
    echo "Link Status:"
    echo "	Port 0: Link Up"
    echo "	Port IMP: Link Up"

}

handle_signal() {
    echo "Exiting because of signal" >&2
    exit 1
}

check_sts_args() {
    # Convert arguments to port numbers
    local port val
    ret="$*"
    if [ $# -lt 1 ]; then
       # No arguments: do all ports
       ret="0 1 2 IMP"
    else
        for port in "$@"; do
            if [ "${port^^}" != "IMP" ] && (! [[ "$port" =~ ^[0-9]+$ ]] \
                || [ "$port" -lt 0 ] || [ "$port" -gt 2 ]); then
                echo "Invalid port $port"
                exit 1
            fi
        done
    fi
}

port_to_val() {
    local val
    if [ "$1" == "IMP" ]; then
        val=8
    else
        val="$1"
    fi
    echo "$val"
}

do_read_lnksts() {
    local page offset result ports port val
    page=0x1
    offset=0x0
    result=$(oob-mdio-util.sh read16 "$page" "$offset" \
        | sed -E "s/$MDIO_READ_PATTERN/\1/")
    ports="$*"

    printf "%sLink status:\n" "$tab"
    tab="	$tab"

    for port in $ports; do
        port=${port^^}
        val=$(port_to_val "$port")
        val=$(( (result >> val) & 0x1 ))
        case "$val" in
            0)
                printf "%sPort: %s Link Down\n" "$tab" "$port"
                ;;
            1)
                printf "%sPort: %s Link Up\n" "$tab" "$port"
                ;;
        esac
    done
    tab=${tab:1}
}

do_read_spdsts() {
    local page offset result ports port val
    page=0x1
    offset=0x4
    result=$(oob-mdio-util.sh read32 "$page" "$offset" \
        | sed -E "s/$MDIO_READ_PATTERN/\1/")
    ports="$*"

    printf "%sLink speed:\n" "$tab"
    tab="	$tab"

    for port in $ports; do
        port=${port^^}
        val=$(port_to_val "$port")
        val=$(( (result >> (val * 2)) & 0x3 ))
        case "$val" in
            0)
                printf "%sPort: %s 10 Mb/s\n" "$tab" "$port"
                ;;
            1)
                printf "%sPort: %s 100 Mb/s\n" "$tab" "$port"
                ;;
            2)
                printf "%sPort: %s 1000 Mb/s\n" "$tab" "$port"
                ;;
        esac
    done
    tab=${tab:1}
}

read_lnksts() {
    check_sts_args "$@"
    do_read_lnksts "$ret"
}

read_spdsts() {
    check_sts_args "$@"
    do_read_spdsts "$ret"
}

read_status() {
    check_sts_args "$@"
    printf "%sStatus:\n" "$tab"
    tab="	$tab"
    do_read_lnksts "$ret"
    do_read_spdsts "$ret"
    tab=${tab:1}
}

# Only allow one instance of script to run at a time.
script=$(realpath "$0")
exec 100< "$script"
flock -n 100 || { echo "ERROR: $0 already running" && exit 1; }

command="$1"

case "$command" in
    link_status)
        shift
        read_lnksts "$@"
        ;;
    link_speed)
        shift
        read_spdsts "$@"
        ;;
    "--help")
        usage
        exit 1
        ;;
    *)
        read_status "$@"
        ;;
esac


#!/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
#
logger "run-dhc6.sh: dhclient -6 Started.."
pid="/var/run/dhclient6.usb0.pid"
exec dhclient -1 -6 -d -D LL --address-prefix-len 64 -pf ${pid} usb0 "$@"


#!/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

echo -n "Setup Front Panel Daemon.."

/usr/local/bin/front-paneld &

echo "done."


#!/bin/bash
# execute <fscd.py> <min syslog level>
# log_level = <debug, warning, info>
# Default log level in fscd is set to warning, if any other level is needed
# set here
. /usr/local/fbpackages/utils/ast-functions

vr_ic=$(kv get VR_IC)
# check the switch IC
Result=$(gpio_get BOARD_ID0)

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

vendor=$(/usr/local/bin/cfg-util asic_mfr)
if [[ "$vendor" == "AMD" && "$vr_ic" == "VI" && "$Result" == "1" ]]; then
  ln -s /etc/fsc-config_AMD_vicor_brcm.json ${default_fsc_config}
elif [[ "$vendor" == "AMD" && "$vr_ic" == "VI" && "$Result" == "0" ]]; then
  ln -s /etc/fsc-config_AMD_vicor_micp.json ${default_fsc_config}
elif [[ "$vendor" == "AMD" && "$vr_ic" == "IF" && "$Result" == "1" ]]; then
  ln -s /etc/fsc-config_AMD_infineon_brcm.json ${default_fsc_config}
elif [[ "$vendor" == "AMD" && "$vr_ic" == "IF" && "$Result" == "0" ]]; then
  ln -s /etc/fsc-config_AMD_infineon_micp.json ${default_fsc_config}
elif [[ "$vendor" == "NVIDIA" && "$vr_ic" == "VI" && "$Result" == "1" ]]; then
  ln -s /etc/fsc-config_NVIDIA_vicor_brcm.json ${default_fsc_config}
elif [[ "$vendor" == "NVIDIA" && "$vr_ic" == "VI" && "$Result" == "0" ]]; then
  ln -s /etc/fsc-config_NVIDIA_vicor_micp.json ${default_fsc_config}
elif [[ "$vendor" == "NVIDIA" && "$vr_ic" == "IF" && "$Result" == "1" ]]; then
  ln -s /etc/fsc-config_NVIDIA_infineon_brcm.json ${default_fsc_config}
elif [[ "$vendor" == "NVIDIA" && "$vr_ic" == "IF" && "$Result" == "0" ]]; then
  ln -s /etc/fsc-config_NVIDIA_infineon_micp.json ${default_fsc_config}
else
  ln -s /etc/fsc-config_NVIDIA_vicor_micp.json ${default_fsc_config}
fi

exec /usr/bin/fscd.py 'warning'


#!/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-fan
# Required-Start:    board-id
# Required-Stop:
# Default-Start:     5
# Default-Stop:
# Short-Description: Set fan speed
### END INIT INFO

echo -n "Setup fan speed... "
runsv /etc/sv/fscd > /dev/null 2>&1 &
echo "done."


#!/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

echo -n "Setup gpio monitoring for emeraldpools... "

/usr/local/bin/gpiod &

echo "done."


#!/bin/sh
exec /usr/local/bin/ipmbd 13 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

. /usr/local/bin/openbmc-utils.sh
echo -n "Starting IPMB Rx/Tx Daemon.."

i2c_mslave_add 0 0x16 #MB1
i2c_mslave_add 1 0x16 #MB2
i2c_mslave_add 2 0x16 #MB3
i2c_mslave_add 3 0x16 #MB4
i2c_mslave_add 13 0x10 #USB DBG

ulimit -q 1024000
runsv /etc/sv/ipmbd_13 > /dev/null 2>&1 &
runsv /etc/sv/ipmbd_0 > /dev/null 2>&1 &
runsv /etc/sv/ipmbd_1 > /dev/null 2>&1 &
runsv /etc/sv/ipmbd_2 > /dev/null 2>&1 &
runsv /etc/sv/ipmbd_3 > /dev/null 2>&1 &

echo "done."


#!/bin/sh
 . /usr/local/bin/openbmc-utils.sh
 . /usr/local/fbpackages/utils/ast-functions

KVSET_CMD=/usr/bin/kv

# check the switch IC
Result=$(gpio_get BOARD_ID0)

if [ "$Result" == "1" ]; then
    $KVSET_CMD set "switch_chip" "BRCM"
    # remove unnecessary aggregate sensors
    rm -f /etc/aggregate-sensors.d/0001-vrs.json
else
    $KVSET_CMD set "switch_chip" "MICRO"
fi


#!/bin/sh
 . /usr/local/bin/openbmc-utils.sh
 . /usr/local/fbpackages/utils/ast-functions

KVSET_CMD=/usr/bin/kv

# check the VR IC
Result=$(i2cget -f -y 17 0x45 0x1b 2>&1 1>/dev/null)

if [ -n "$Result" ]; then
    $KVSET_CMD set "VR_IC" "VI"
else
    $KVSET_CMD set "VR_IC" "IF"
fi