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

debug=0
m95m02_page_size=256
m95m02_page_count=1024
fpga_header_size=112

ret=0
trap cleanup_spi INT TERM QUIT EXIT

PIDFILE="/var/run/spi_util.pid"
check_duplicate_process()
{
    exec 2>$PIDFILE
    flock -n 2 || (echo "Another process is running" && exit 1)
    ret=$?
    if [ $ret -eq 1 ]; then
      exit 1
    fi
    pid=$$
    echo $pid 1>&200
}

remove_pid_file()
{
    if [ -f $PIDFILE ]; then
        rm $PIDFILE
    fi
}

check_board_type()
{
    board_type=$(wedge_board_type)
    if [ "$((board_type))" -eq 0 ]; then # Wedge400 any version
        SWITCH_PCIE_FLASH="TH3_PCIE_FLASH"
        MAC_TYPE="W400"
    elif [ "$((board_type))" -eq 1 ]; then # Wedge400-C any version
        SWITCH_PCIE_FLASH="GB_PCIE_FLASH"
        MAC_TYPE="W400C"
    else
        SWITCH_PCIE_FLASH="GB_PCIE_FLASH"
        MAC_TYPE="W400?"
    fi
}

check_flash_info()
{
    spi_no=$1
    flashrom -p linux_spi:dev=/dev/spidev"$spi_no".0
}

get_flash_first_type()
{
    ori_str=$(check_flash_info "$spi_no")
    type=$(echo "$ori_str" | grep -m 1 '"' | cut -d '"' -f 2)
    if [ "$type" ]; then
        echo "$type"
        return 0
    else
        echo "Get flash type error: [$ori_str]"
        exit 1
    fi
}

get_flash_size()
{
    spi_no=$1
    ori_str=$(check_flash_info "$spi_no")
    flash_sz=$(echo "$ori_str" | grep -m 1 '"' | cut -d '(' -f 2 | cut -d ' ' -f 1)
    echo "$flash_sz" | grep -E -q '^[0-9]+$'
    num_ret=$?
    if [ $num_ret -eq 0 ]; then
        echo "$flash_sz"
        return 0
    else
        echo "Get flash size error: [$ori_str]"
        return 1
    fi
}

# $1: input file size $2: flash size $3: output file path
pad_ff()
{
    out_file=$3
    pad_size=$(($2 - $1))
    dd if=/dev/zero bs=$pad_size count=1 | tr "\000" "\377" >> "$out_file"
}

resize_file()
{
    in_file=$1
    out_file=$2
    spi_no=$3
    storage_type=$4
    in_file_sz=$(stat -c%s "$in_file")
    storage_sz=0
    if [ "$storage_type" ] && [ "$storage_type" = "m95m02" ]; then
        storage_sz=$((m95m02_page_count * m95m02_page_size))
    else
        flash_sz=$(get_flash_size "$spi_no")
        ret=$?
        if [ $((ret)) -eq 0 ]; then
            storage_sz=$((flash_sz * 1024))
        else
            echo "debug message: $flash_sz"
            exit 1
        fi
    fi

    if [ $((in_file_sz)) -ne $((storage_sz)) ]; then
        cp "$in_file" "$out_file"
        pad_ff "$in_file_sz" "$storage_sz" "$out_file"
    else
        ln -s "$(realpath "$in_file")" "$out_file"
    fi
}

dump_gpio_config(){
    if [ $debug = 0 ]; then
        return 0
    fi
    echo "Dump SPI configurations..."
    if [ "$1" = "SPI1" ]; then
        openbmc_gpio_util.py dump | grep SPI1
    else
        openbmc_gpio_util.py dump | grep SPI2
    fi
}

export_spi1_pins(){
    gpiocli --shadow BMC_SPI1_CS0 -c aspeed-gpio -n GPIOI4 export > /dev/null 2>&1
    gpiocli --shadow BMC_SPI1_CLK -c aspeed-gpio -n GPIOI5 export > /dev/null 2>&1
    gpiocli --shadow BMC_SPI1_MOSI -c aspeed-gpio -n GPIOI6 export > /dev/null 2>&1
    gpiocli --shadow BMC_SPI1_MISO -c aspeed-gpio -n GPIOI7 export > /dev/null 2>&1
}

unexport_spi1_pins(){
    gpiocli --shadow BMC_SPI1_CS0 -c aspeed-gpio -n GPIOI4 unexport > /dev/null 2>&1
    gpiocli --shadow BMC_SPI1_CLK -c aspeed-gpio -n GPIOI5 unexport > /dev/null 2>&1
    gpiocli --shadow BMC_SPI1_MOSI -c aspeed-gpio -n GPIOI6 unexport > /dev/null 2>&1
    gpiocli --shadow BMC_SPI1_MISO -c aspeed-gpio -n GPIOI7 unexport > /dev/null 2>&1
}

# currently only EEPROM
set_spi1_to_gpio(){
    devmem_set_bit "$(scu_addr 7C)" 12
    devmem_set_bit "$(scu_addr 7C)" 13
    devmem_set_bit "$(scu_addr 80)" 15
    export_spi1_pins
    gpiocli --shadow BMC_SPI1_CLK set-direction out
    gpiocli --shadow BMC_SPI1_CS0 set-direction out
    gpiocli --shadow BMC_SPI1_MISO set-direction in
    gpiocli --shadow BMC_SPI1_MOSI set-direction out
    dump_gpio_config SPI1
}

set_spi1_to_spi(){
    devmem_set_bit "$(scu_addr 70)" 12
    unexport_spi1_pins
    dump_gpio_config SPI1
}

# currently no use
set_spi2_to_spi_cs(){
    cs=$1
    if [ $((cs)) -eq 0 ]; then
        # spi2 cs0
        devmem_set_bit "$(scu_addr 88)" 26
        devmem_set_bit "$(scu_addr 88)" 27
        devmem_set_bit "$(scu_addr 88)" 28
        devmem_set_bit "$(scu_addr 88)" 29
    else
        # spi2 cs1
        devmem_set_bit "$(scu_addr 8C)" 0
        devmem_set_bit "$(scu_addr 88)" 27
        devmem_set_bit "$(scu_addr 88)" 28
        devmem_set_bit "$(scu_addr 88)" 29
    fi
    dump_gpio_config SPI2
}

# currently no use
set_spi2_to_gpio(){
    devmem_clear_bit "$(scu_addr 88)" 26
    devmem_clear_bit "$(scu_addr 88)" 27
    devmem_clear_bit "$(scu_addr 88)" 28
    devmem_clear_bit "$(scu_addr 88)" 29
    devmem_clear_bit "$(scu_addr 8C)" 0
    gpiocli --shadow BMC_SPI2_CLK set-direction out
    gpiocli --shadow BMC_SPI2_CS0 set-direction out
    gpiocli --shadow BMC_SPI2_CS1 set-direction out
    gpiocli --shadow BMC_SPI2_MISO set-direction in
    gpiocli --shadow BMC_SPI2_MOSI set-direction out
    dump_gpio_config SPI2
}

read_flash_to_file()
{
    spi_no=$1
    tmp_file=$2
    type=$(get_flash_first_type "$spi_no")
    flashrom -p linux_spi:dev=/dev/spidev"$spi_no".0 -r "$tmp_file" -c "$type"
    ret=$?
    if [ $((ret)) -ne 0 ]; then
        echo "debug cmd: [flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 -r $tmp_file -c $type]"
        exit 1
    fi
}

write_flash_to_file(){
    spi_no=$1
    in_file=$2
    out_file="/tmp/${3}_spi${1}_tmp"
    resize_file "$in_file" "$out_file" "$spi_no"
    type=$(get_flash_first_type "$spi_no")
    flashrom -p linux_spi:dev=/dev/spidev"${spi_no}".0 -w "$out_file" -c "$type"
    ret=$?
    if [ $((ret)) -ne 0 ]; then
        echo "debug cmd: [flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 -w $out_file -c $type]"
        exit 1
    fi
}

erase_flash(){
    spi_no=$1
    type=$(get_flash_first_type "$spi_no")
    flashrom -p linux_spi:dev=/dev/spidev"${spi_no}".0 -E -c "$type"
    ret=$?
    if [ $((ret)) -ne 0 ]; then
        echo "debug cmd: [flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 -E -c $type]"
        exit 1
    fi
}

read_m95m02_to_file(){
    spi_no=$1
    file=$2
    eeprom_node="/sys/bus/spi/devices/spi${spi_no}.1/eeprom"
    modprobe -r at25
    modprobe at25
    dd if="$eeprom_node" of="$file" count=$m95m02_page_count bs=$m95m02_page_size
}

write_m95m02(){
    spi_no=$1
    file=$2
    out_file="/tmp/${3}_spi${1}_tmp"
    eeprom_node="/sys/bus/spi/devices/spi${spi_no}.1/eeprom"
    modprobe -r at25
    modprobe at25
    tr '\0' '\377' < /dev/zero | dd count=$m95m02_page_count bs=$m95m02_page_size of="$eeprom_node"
    resize_file "$file" "$out_file" "$spi_no" 'm95m02'
    dd of="$eeprom_node" if="$out_file" count=$m95m02_page_count bs=$m95m02_page_size
}

erase_m95m02(){
    spi_no=$1
    eeprom_node="/sys/bus/spi/devices/spi${spi_no}.1/eeprom"
    modprobe -r at25
    modprobe at25
    tr '\0' '\377' < /dev/zero | dd count=$m95m02_page_count bs=$m95m02_page_size of="$eeprom_node"
}

bios_flash_pre_operate() {
    curr_flash=$(boot_info.sh bios)
    if [ "$curr_flash" = "slave" ]; then
        wedge_power.sh off > /dev/null
    fi
}

bios_flash_post_operate() {
    curr_flash=$(boot_info.sh bios)
    if [ "$curr_flash" = "slave" ]; then
        wedge_power.sh on > /dev/null
    fi
}

read_spi1_dev(){
    spi_no=1
    dev=$1
    file=$2
    case ${dev} in
        ## W25Q128 , W25Q128 , W25Q257
        "BIOS" | "TH3_PCIE_FLASH" | "GB_PCIE_FLASH")
            echo "Reading flash to $file..."
            read_flash_to_file $spi_no "$file"
        ;;
        "SYSTEM_EE" | "BCM5389_EE")
            echo "Reading eeprom to $file..."
            # read_flash_to_file $spi_no $file
            cs=$(gpio_name2value BMC_SPI1_CS0)
            clk=$(gpio_name2value BMC_SPI1_CLK)
            miso=$(gpio_name2value BMC_SPI1_MISO)
            mosi=$(gpio_name2value BMC_SPI1_MOSI)
            at93cx6_util_py3.py --cs "$cs" --clk "$clk" --mosi "$mosi" --miso "$miso" chip read --file "$file"
        ;;
        "DOM_FPGA_FLASH1" | "DOM_FPGA_FLASH2")
            echo "Reading flash to $file..."
            read_flash_to_file $spi_no /tmp/fpga_fw_tmp
            in_file_sz=$(stat -c%s /tmp/fpga_fw_tmp)
            if [ -e "$file" ]; then
                rm "$file"
            fi
            pad_ff 0 $fpga_header_size "$file"
            dd if=/tmp/fpga_fw_tmp bs="$in_file_sz" count=1 >> "$file"
            rm /tmp/fpga_fw_tmp
        ;;
    esac
}

write_spi1_dev(){
    spi_no=1
    dev=$1
    file=$2
    case ${dev} in
        ## W25Q128 , W25Q128 , W25Q257
        "BIOS")
            echo "Writing $file to flash..."
            bios_flash_pre_operate
            write_flash_to_file "$spi_no" "$file" "$dev"
            bios_flash_post_operate
        ;;
        "TH3_PCIE_FLASH" | "GB_PCIE_FLASH")
            echo "Writing $file to flash..."
            write_flash_to_file "$spi_no" "$file" "$dev"
        ;;
        "SYSTEM_EE" | "BCM5389_EE")
            # write_flash_to_file $spi_no $file
            echo "Writing $file to eeprom..."
            cs=$(gpio_name2value BMC_SPI1_CS0)
            clk=$(gpio_name2value BMC_SPI1_CLK)
            miso=$(gpio_name2value BMC_SPI1_MISO)
            mosi=$(gpio_name2value BMC_SPI1_MOSI)
            at93cx6_util_py3.py --cs "$cs" --clk "$clk" --mosi "$mosi" --miso "$miso" chip write --file "$file"
        ;;
        "DOM_FPGA_FLASH1" | "DOM_FPGA_FLASH2")
            echo "Writing $file to flash..."
            if [ -e /tmp/fpga_fw_tmp ]; then
                rm /tmp/fpga_fw_tmp
            fi
            # remove header unused of fpga bit file
            dd if="$file" skip=1 bs=$fpga_header_size of=/tmp/fpga_fw_tmp
            write_flash_to_file "$spi_no" /tmp/fpga_fw_tmp "$dev"
            rm /tmp/fpga_fw_tmp
        ;;
    esac
}

erase_spi1_dev(){
    spi_no=1
    dev=$1
    file=$2
    case ${dev} in
        ## W25Q128 , W25Q128 , W25Q257
        "BIOS" | "DOM_FPGA_FLASH1" | "DOM_FPGA_FLASH2" | "TH3_PCIE_FLASH" | "GB_PCIE_FLASH")
            echo "Erasing flash..."
            erase_flash "$spi_no"
        ;;
        "SYSTEM_EE" | "BCM5389_EE")
            echo "Erasing eeprom..."
            # erase_flash $spi_no
            cs=$(gpio_name2value BMC_SPI1_CS0)
            clk=$(gpio_name2value BMC_SPI1_CLK)
            miso=$(gpio_name2value BMC_SPI1_MISO)
            mosi=$(gpio_name2value BMC_SPI1_MOSI)
            at93cx6_util_py3.py --cs "$cs" --clk "$clk" --mosi "$mosi" --miso "$miso" chip erase
        ;;
    esac
}

get_smb_cpld_spi_1b(){
    b0=$(cat "$SMBCPLD_SYSFS_DIR"/spi_1_b0)
    b1=$(cat "$SMBCPLD_SYSFS_DIR"/spi_1_b1)
    b2=$(cat "$SMBCPLD_SYSFS_DIR"/spi_1_b2)
    echo "spi_1b [ $b2 $b1 $b0 ]"
}

set_smb_cpld_spi_1b(){
    if [ $# = 3 ]; then
        echo "$3" > "$SMBCPLD_SYSFS_DIR"/spi_1_b0
        echo "$2" > "$SMBCPLD_SYSFS_DIR"/spi_1_b1
        echo "$1" > "$SMBCPLD_SYSFS_DIR"/spi_1_b2
    else
        echo "Set SPI1 BIT FAILED"
    fi
}

config_spi1_pin_and_path(){
    dev=$1

    case ${dev} in
        "SYSTEM_EE")
            set_spi1_to_gpio
            echo 0 > "$SMBCPLD_SYSFS_DIR"/spi_1_sel
        ;;
        "BIOS")
            set_spi1_to_spi
            echo 1 > "$SMBCPLD_SYSFS_DIR"/spi_1_sel
        ;;
        "BCM5389_EE")
            set_spi1_to_gpio
            echo 2 > "$SMBCPLD_SYSFS_DIR"/spi_1_sel
        ;;
        "TH3_PCIE_FLASH" | "GB_PCIE_FLASH")
            set_spi1_to_spi
            echo 3 > "$SMBCPLD_SYSFS_DIR"/spi_1_sel
        ;;
        "DOM_FPGA_FLASH1")
            set_spi1_to_spi
            echo 4 > "$SMBCPLD_SYSFS_DIR"/spi_1_sel
        ;;
        "DOM_FPGA_FLASH2")
            set_spi1_to_spi
            echo 5 > "$SMBCPLD_SYSFS_DIR"/spi_1_sel
        ;;

        *)
            echo "Please enter {SYSTEM_EE, BIOS, BCM5389_EE, $SWITCH_PCIE_FLASH, DOM_FPGA_FLASH1, DOM_FPGA_FLASH2}"
            exit 1
        ;;
    esac
    echo "Config SPI1 Done."
}

operate_spi1_dev(){
    op=$1
    dev=$2
    file=$3
    ## Operate devices ##
    case ${op} in
        "read")
                read_spi1_dev "$dev" "$file"
        ;;
        "write")
                write_spi1_dev "$dev" "$file"
        ;;
        "erase")
                erase_spi1_dev "$dev"
        ;;
        *)
            echo "Operation $op is not defined."
        ;;
    esac
}

cleanup_spi(){
    if [ $ret -eq 1 ]; then
        exit 1
    fi
    echo 0 > "$SMBCPLD_SYSFS_DIR"/spi_1_sel

    rm -rf /tmp/*_spi*_tmp
    remove_pid_file
}

ui(){
    . /usr/local/bin/openbmc-utils.sh
    op=$1
    spi=$2

    # SPI 1.0 speed
    devmem 0x1e630010 32 0x07
    # SPI 2.0 speed
    devmem 0x1e631010 32 0x407
    # SPI 2.1 speed
    devmem 0x1e631014 32 0x2007
	## Open the path to device ##
    case ${spi} in
        "spi1")
            dev=$3
            file=$4
            config_spi1_pin_and_path "$dev"
            operate_spi1_dev "$op" "$dev" "$file"
            # set gpio to normal mode
            set_spi1_to_gpio
        ;;
        *)
            echo "No such SPI bus."
            return 1
        ;;
    esac
}

usage(){
    program=$(basename "$0")
    echo "Usage:"
    echo "$program <op> spi1 <spi1 device> <file>"
    echo "  <op>          : read, write, erase"
    echo "  <spi1 device> : SYSTEM_EE, BIOS, BCM5389_EE, $SWITCH_PCIE_FLASH, DOM_FPGA_FLASH1, DOM_FPGA_FLASH2"
    echo "                  (SYSTEM_EE not support for Wedge400-C)"
    echo "Examples:"
    echo "  $program write spi1 DOM_FPGA_FLASH domfpga.bit"
    echo ""
}

check_parameter(){
    program=$(basename "$0")
    op=$1
    spi=$2
    case ${op} in
        "read" | "write" | "erase")
            ;;
        *)
            return 1
            ;;
    esac
    if [ "$spi" ] && [ "$spi" = "spi1" ]; then
        dev=$3
        file=$4

        # SYSTEM_EE disable on Wedge400-C
        if [ "$dev" = "SYSTEM_EE" ] && [ "$MAC_TYPE" = "W400C" ]; then
            return 1
        fi

        ## Check device
        case ${dev} in
            "SYSTEM_EE"|"BIOS"|"BCM5389_EE"|"TH3_PCIE_FLASH"|"GB_PCIE_FLASH"|"DOM_FPGA_FLASH1"|"DOM_FPGA_FLASH2")
                ## Check operation
                case ${op} in
                    "read" | "write")
                        if [ $# -ne 4 ]; then
                            return 1
                        fi
                        ;;
                    "erase")
                        if [ $# -ne 3 ]; then
                            return 1
                        fi
                        ;;
                esac
                ;;
            *)
                return 1
                ;;
        esac
    else
        return 1
    fi

    return 0
}

check_board_type
check_duplicate_process
check_parameter "$@"
is_par_ok=$?

if [ $is_par_ok -eq 0 ]; then
    ui "$@"
else
    usage
    exit 1
fi


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

if [ "$(wedge_board_type)" != "1" ]; then
    echo "$(basename "$0") only support on Wedge400C"
    exit 1
fi

SMB_CPLD_I2C_BUS="12"
SMB_CPLD_I2C_ADDR="0x3e"

i2c_wr() {
    i2cset "$@"; sleep 0.01;
}

# Wedge400-C GB switch reset commands collection
gb_reset() {
    if [ "$1" = "cycle" ];then
        # gb power off
        i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x42 0x0e
        sleep 0.5
        # gb power on
        i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x42 0x0f
        sleep 1
    fi

    # [3] mux_ps=1, ps=1, scan=0, tri_l=1
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x60 0xd
    # [0] a_rstn=0
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x05 0xfe
    # [0] tri_l=0
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x60 0xc
    # [1] scan_mode=1
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x60 0xe
    # [1] scan_mode=0
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x60 0xc
    # [0] tri_l=1
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x60 0xd
    # [0] a_rstn=1
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x05 0xff
    # [0] a_rstn=0
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x05 0xfe
    # [2] ps=0
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x60 0x9
    # [2] ps=1
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x60 0xd
    sleep 0.5
    # [0] a_rstn=1
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x05 0xff
    # [3] mux_ps=0
    i2c_wr -f -y $SMB_CPLD_I2C_BUS $SMB_CPLD_I2C_ADDR 0x60 0x5
}

case "$1" in
    "--help" | "?" | "-h")
        program=$(basename "$0")
        echo "Usage: switch chip reset command"
        echo "  <$program> only reset switch without switch power cycle"
        echo "  <$program cycle> to reset switch after switch power cycle"
    ;;

    *)
        shift
        gb_reset "$1"
    ;;
esac


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

usage() {
    echo "$0 <connect | disconnect>"
}

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

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

if [ "$1" == "connect" ]; then
    VALUE=1
elif [ "$1" == "disconnect" ]; then
    VALUE=0
else
    usage
    exit 1
fi

# GPIOS5 (32) controls if uS console connects to UART5 or not.
# To enable GPIOS5, SCU8C[5] must be 0
devmem_clear_bit $(scu_addr 8C) 5

gpiocli --shadow BMC_UART_SEL5 set-direction out
gpiocli --shadow BMC_UART_SEL5 set-value $VALUE


#!/bin/bash
#
# Copyright 2019-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/openbmc-utils.sh

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

prog="$0"

PWR_USRV_RST_SYSFS="${SCMCPLD_SYSFS_DIR}/iso_com_rst_n"
PWR_CYCLE_SYSFS="${PWRCPLD_SYSFS_DIR}/power_cycle_go"
PWR_TIMER_BASE_1S_SYSFS="${PWRCPLD_SYSFS_DIR}/timer_base_1s"
PWR_TIMER_BASE_10S_SYSFS="${PWRCPLD_SYSFS_DIR}/timer_base_10s"
PWR_TIMER_COUNTER_SETTING_SYSFS="${PWRCPLD_SYSFS_DIR}/timer_counter_setting"
PWR_TIMER_COUNTER_SETTING_UPDATE_SYSFS="${PWRCPLD_SYSFS_DIR}/timer_counter_setting_update"

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 wedge400 system ungracefully"
    echo "      -s -t [1-2550]: Setting boot up time."
    echo "            From 1 to 249 the step is 1 second."
    echo "            From 250 to 2550 the step is 10 seconds"
    echo "            and don't care ones-digits."
    echo
    echo
}

main_power_status() {
    return 0
}

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_com_e() {
    echo 1 > "$PWR_USRV_SYSFS"
    echo 1 > "$PWR_USRV_FORCE_OFF"
    return $?
}

do_on() {
    local force opt ret
    force=0
    while getopts "f" opt; do
        case $opt in
            f)
                force=1
                ;;
            *)
                usage
                exit 1
                ;;
        esac
    done
    logger -p user.crit "Power on microserver ..."
    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

    # reset TH
    # reset_brcm.sh
    # power on sequence
    do_on_com_e
    ret=$?
    if [ $ret -eq 0 ]; then
        echo " Done"
    else
        echo " Failed"
    fi
    return $ret
}

do_off_com_e() {
    echo 0 > "$PWR_USRV_FORCE_OFF"
    return $?
}

do_off() {
    local ret
    logger -p user.crit "Power off microserver ..."
    echo -n "Power off microserver ..."
    do_off_com_e
    ret=$?
    if [ $ret -eq 0 ]; then
        echo " Done"
    else
        echo " Failed"
    fi
    return $ret
}

do_config_reset_timer() {
    # Check numeric
    wake_t=$1
    echo "$wake_t" | grep -E -q '^[0-9]+$'
    ret=$?
    if [ $ret -ne 0 ]; then
        usage
        exit 1
    else
        if [ "$wake_t" -ge 1 ] && [ "$wake_t" -lt 250 ];then
            echo 1 > "$PWR_TIMER_BASE_1S_SYSFS"
            echo 0 > "$PWR_TIMER_BASE_10S_SYSFS"
            logger "Waiting $wake_t seconds for the system boot up"
            echo "Waiting $wake_t seconds for the system boot up"
        elif [ "$wake_t" -ge 250 ] && [ "$wake_t" -le 2550 ];then
            echo 0 > "$PWR_TIMER_BASE_1S_SYSFS"
            echo 1 > "$PWR_TIMER_BASE_10S_SYSFS"
            wake_t=$((wake_t/10))
            logger "Waiting $((wake_t * 10)) seconds for the system boot up"
            echo "Waiting $((wake_t * 10)) seconds for the system boot up"
        else
            usage
            exit 1
        fi
        echo $wake_t > "$PWR_TIMER_COUNTER_SETTING_SYSFS"
        echo 1 > "$PWR_TIMER_COUNTER_SETTING_UPDATE_SYSFS"
    fi
}

do_reset() {
    local system timer wake_t opt
    system=0
    timer=0
    wake_t=0
    while getopts "st:" opt; do
        case $opt in
            s)
                system=1
                ;;
            t)
                timer=1
                wake_t=$OPTARG
                ;;
            *)
                usage
                exit 1
                ;;
        esac
    done

    if [ $system -eq 1 ]; then
        if [ $timer -eq 1 ]; then
            do_config_reset_timer "$wake_t"
        fi
        logger -p user.crit "Power reset the whole system ..."
        echo  "Power reset the whole system ..."
        # Synchronize cached writes to persistent storage
        # We found somethimes /mnt/data data lost after wedge_power.sh reset -s,
        # add sync in case of file system will be broken by random power cycle.
        sync
        mmc hwreset enable /dev/mmcblk0
        gpio_set_value BMC_EMMC_RST_N_R 1
        gpio_set_value BMC_EMMC_RST_N_R 0
        sleep 0.01
        gpio_set_value BMC_EMMC_RST_N_R 1
        echo 1 > "$PWR_CYCLE_SYSFS"
        sleep 3
        # Control should not reach here, but if it failed to reset
        # the system through PSU, then run a workaround to reset
        # most of the system instead (if not all)
        logger -p user.crit "Failed to reset the system. Will start workaround in 3 sec.."
        echo "Failed to reset the system. Will start workaround in 3 sec.."
        i2cset -f -y 1 0x3a 0x12 0
    else
        if ! wedge_is_us_on; then
            echo "Power resetting microserver that is powered off has no effect."
            echo "Use '$prog on' to power the microserver on"
            return 1
        fi
        # reset TH first
        # reset_brcm.sh
        logger -p user.crit "Power reset microserver ..."
        echo -n "Power reset microserver ..."
        echo 0 > "$PWR_USRV_RST_SYSFS"
        sleep 1
        echo 1 > "$PWR_USRV_RST_SYSFS"
        echo "Done"
    fi
    return 0
}

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

command="$1"
shift

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

if [ $set_bic -ne 0 ]; then
    (sleep 10; setup_bic.sh) &
fi

exit $?


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

# Get output from bic-util
bic_output=`bic-util scm --read_mac`

# Check if the read was successful and output matches with our format
match=`echo $bic_output| grep -e 'MAC address: [0-9a-f][0-9a-f]:'|wc -l`
if [ "$match" == "1" ]; then
    # Mac address: xx:xx:xx:xx:xx:xx
    echo $bic_output| cut -d ' ' -f 3
    exit 0
else
    echo "Cannot find out the microserver MAC" 1>&2
    exit -1
fi


#!/bin/sh
#
# Copyright 2019-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-bic-cached
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Set Cachcing for Bridge IC info
### END INIT INFO

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

echo -n "Setup Caching for Bridge IC info.."

/usr/local/bin/bic-cached 0 > /dev/null 2>&1 &

echo "done."


#!/bin/bash

SLOT_NAME=$1

case $SLOT_NAME in
    scm)
      SLOT_NUM=1
      ;;
    *)
      N=${0##*/}
      N=${N#[SK]??}
      echo "Usage: $N {scm}"
      exit 1
      ;;
esac

# File format autodump<slot_id>.pid (See pal_is_crashdump_ongoing()
# function definition)
PID_FILE="/var/run/autodump$SLOT_NUM.pid"

# check if auto crashdump is already running
if [ -f $PID_FILE ]; then
  echo "Another auto crashdump for $SLOT_NAME is runnung"
  exit 1
else
  touch $PID_FILE
fi

# Set crashdump timestamp
sys_runtime=$(awk '{print $1}' /proc/uptime)
sys_runtime=$(printf "%0.f" $sys_runtime)
echo $((sys_runtime+630)) > /tmp/cache_store/fru${SLOT_NUM}_crashdump

DUMP_SCRIPT="/usr/local/bin/dump.sh"
CRASHDUMP_FILE="/mnt/data/crashdump_$SLOT_NAME"
CRASHDUMP_LOG_ARCHIVE="/mnt/data/crashdump_$SLOT_NAME.tar.gz"

echo "Auto Dump for $SLOT_NAME Started"

#HEADER LINE for the dump
$DUMP_SCRIPT "time" > $CRASHDUMP_FILE
#COREID dump
$DUMP_SCRIPT $SLOT_NAME "coreid" >> $CRASHDUMP_FILE
#MSR dump
$DUMP_SCRIPT $SLOT_NAME "msr" >> $CRASHDUMP_FILE
# Sensors & sensor thresholds
echo "Sensor history at dump:" >> $CRASHDUMP_FILE 2>&1
$DUMP_SCRIPT $SLOT_NAME "sensors" >> $CRASHDUMP_FILE
echo "Sensor threshold at dump:" >> $CRASHDUMP_FILE 2>&1
$DUMP_SCRIPT $SLOT_NAME "threshold" >> $CRASHDUMP_FILE

tar zcf $CRASHDUMP_LOG_ARCHIVE -C `dirname $CRASHDUMP_FILE` `basename $CRASHDUMP_FILE` && \
rm -rf $CRASHDUMP_FILE && \
logger -t "ipmid" -p daemon.crit "Crashdump for $SLOT_NAME is generated at $CRASHDUMP_LOG_ARCHIVE"

echo "Auto Dump for $SLOT_NAME Completed"

rm $PID_FILE
exit 0


#!/bin/bash

BIC_UTIL="/usr/bin/bic-util"
SENSOR_HISTORY=180

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

if [ "$#" -ne 2 ]; then
  echo "$0 <slot#> coreid    ==> for CPU CoreID"
  echo "$0 <slot#> msr       ==> for CPU MSR"
  echo "$0 <slot#> sensors   ==> for sensor history"
  echo "$0 <slot#> threshold ==> for sensor threshold"
  exit 1
fi

echo ""

if [ "$2" = "coreid" ]; then
  [ -r /usr/local/fbpackages/crashdump/crashdump_coreid ] && $BIC_UTIL $1 --me_file /usr/local/fbpackages/crashdump/crashdump_coreid
elif [ "$2" = "msr" ]; then
  [ -r /usr/local/fbpackages/crashdump/crashdump_msr ] && $BIC_UTIL $1 --me_file /usr/local/fbpackages/crashdump/crashdump_msr
elif [ "$2" = "sensors" ]; then
  /usr/local/bin/sensor-util all --history $SENSOR_HISTORY
elif [ "$2" = "threshold" ]; then
  /usr/local/bin/sensor-util all --threshold
fi

exit 0


#!/bin/sh
#
# Copyright 2019-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
#
exec /usr/local/bin/front-paneld


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

exec /usr/local/bin/gpiod


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

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

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

echo "done."


#!/bin/sh
#
# Copyright 2019-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/openbmc-utils.sh
if [ -e /sys/bus/i2c/devices/0-1010 ]; then
    i2c_device_delete 0 0x1010
fi
i2c_device_add 0 0x1010 slave-mqueue
exec /usr/local/bin/ipmbd 0 1


#!/bin/sh
#
# Copyright 2019-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/openbmc-utils.sh
if [ -e /sys/bus/i2c/devices/4-1010 ]; then
    i2c_device_delete 4 0x1010
fi
i2c_device_add 4 0x1010 slave-mqueue
exec /usr/local/bin/ipmbd 4 1


#! /bin/bash
#
# Copyright 2019-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 "Starting IPMB Rx/Tx Daemon"

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


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

exec /usr/local/bin/ipmid


#!/bin/bash
#
# Copyright 2019-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-ipmid
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Set IPMI Message handler
### END INIT INFO

echo -n "Setup IPMI message handler... "
runsv /etc/sv/ipmid > /dev/null 2>&1 &
echo "done."


#!/bin/sh
#
# Copyright 2019-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
exec /usr/local/bin/pemd pem1 pem2


#!/bin/sh
#
# Copyright 2019-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/bin/openbmc-utils.sh

# If either one pem is present, pemd will start
if [ "$(wedge_power_supply_type)" != "PEM" ]; then
    echo "Skip pemd as PEM is not present"
    exit 0
fi

# shellcheck disable=SC2039
echo -n "Setup pem monitoring for wedge400... "

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

echo "done."


#!/bin/sh

#shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh
brd_type=$(wedge_full_board_type)

# Wedge400 MP Respin or newer, change to use FT4232 for rackmon uart
if [ $((brd_type)) -ge $((0x2)) ]; then

    # Detect FTDI chip
    /usr/local/bin/ftdi_control -L
    ftdi_detected=$?
    # exit when can't detect FTDI Chip
    if [ $((ftdi_detected)) -ne 0 ]; then
        echo "run-rackmond.sh : cannot detect FTDI chip" > /dev/kmsg
        exit 1
    fi

    # set FT4232 port 1 to GPIO Input
    /usr/local/bin/ftdi_bitbang -I 1 -i 0 -i 1 -i 2 -i 4 -i 5 -i 6

    rs485_cfg=0
    rs485_cfg=$((rs485_cfg + $(/usr/local/bin/ftdi_control -o | grep CHANNEL_B_RS485 | grep -c 1 ) ))
    rs485_cfg=$((rs485_cfg + $(/usr/local/bin/ftdi_control -o | grep CHANNEL_C_RS485 | grep -c 1 ) ))
    rs485_cfg=$((rs485_cfg + $(/usr/local/bin/ftdi_control -o | grep CHANNEL_D_RS485 | grep -c 1 ) ))
    if [ $((rs485_cfg)) -lt 3 ]; then
        /usr/local/bin/ftdi_control -N -B1 -C1 -D1
        touch /tmp/need_to_pwrcycle
        echo "run-rackmond.sh : Need to power cycle to reload the FTDI configuration" > /dev/kmsg
        exit 1
    fi
    if [ -e /tmp/need_to_pwrcycle ]; then
        echo "run-rackmond.sh : Need to power cycle to reload the FTDI configuration" > /dev/kmsg
        exit 1
    fi
    # Replace with multiport configuration.
    ln -s /etc/usb_ft4232.conf /etc/rackmon.conf
else
  ln -s /etc/usb_ft232.conf /etc/rackmon.conf
fi

exec /usr/local/bin/rackmond


#!/bin/bash
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
### BEGIN INIT INFO
# Provides:          setup-rackmond
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Start Rackmon service
### END INIT INFO

#
# No need to start rackmond if the according tty device cannot be found:
#

#shellcheck disable=SC1091

. /usr/local/bin/openbmc-utils.sh
brd_type=$(wedge_full_board_type)

if [ $((brd_type)) -ge $((0x2)) ]; then
    # workaround on Respin SKU2 USB mux default isn't BMC
    # need force it to select BMC <--> RACK
    echo 1 > $SMBCPLD_SYSFS_DIR/cpld_usb_mux2_sel
    sleep 5
fi

BMC_PSU_TTY="/dev/ttyUSB0"
if ! [ -e "$BMC_PSU_TTY" ]; then
    echo "rackmond not started: $BMC_PSU_TTY does not exist!"
    exit 1
fi

runsv /etc/sv/rackmond > /dev/null 2>&1 &
sv "$1" rackmond


#!/bin/sh
#
# Copyright 2019-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/openbmc-utils.sh

ARGS="scm smb fan1 fan2 fan3 fan4"

#
# PSU and PEM will never be plugged to a switch at the same time, and
# they won't be hotswapped. So we only need to mointor the power units
# that are plugged at present.
#
# TODO: improve the logic to monitor only one PEM.
#
if [ "$(wedge_power_supply_type)" = "PEM" ]; then
    ARGS="$ARGS pem1 pem2"
else
    ARGS="$ARGS psu1 psu2"
fi

#shellcheck disable=SC2086
exec /usr/local/bin/sensord $ARGS


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

echo -n "Setup sensor monitoring for WEDGE400... "

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

echo "done."


#!/bin/sh

### BEGIN INIT INFO
# Provides:		tcsd trousers
# Required-Start:	$local_fs $remote_fs $network
# Required-Stop:	$local_fs $remote_fs $network
# Should-Start:
# Should-Stop:
# Default-Start:	2 3 4 5
# Default-Stop:		0 1 6
# Short-Description:	starts tcsd
# Description:		tcsd belongs to the TrouSerS TCG Software Stack
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/tcsd
NAME=tcsd
DESC="Trusted Computing daemon"
USER="root"

test -x "${DAEMON}" || exit 0

# Read configuration variable file if it is present
# shellcheck disable=SC1090
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

case "${1}" in
	start)
		echo "Starting $DESC: "

    # If TPM chip has not been discovered, probe the chip here
	    for file in /dev/tpm*
		do
		  if [ ! -e "$file" ]
		  then
      # Finally, register the device and install the driver
            # shellcheck disable=SC1091
            . /usr/local/bin/openbmc-utils.sh
            i2c_device_add 7 0x20 tpm_i2c_infineon
          fi
		done

    # Additionally, Generate symlink to tpm0 or tpm1, so that tcsd can use it
    rm -f /dev/tpm
		if [ -e /dev/tpm0 ]
    then
      ln -s /dev/tpm0 /dev/tpm
    else
      ln -s /dev/tpm1 /dev/tpm
    fi
                # shellcheck disable=SC2086
		start-stop-daemon --start --quiet --oknodo --pidfile /var/run/${NAME}.pid --user ${USER} --chuid ${USER} --exec ${DAEMON} -- ${DAEMON_OPTS}
		RETVAL="$?"
		echo "$NAME."
		[ "$RETVAL" = 0 ] && pidof $DAEMON > /var/run/${NAME}.pid
		exit $RETVAL
		;;

	stop)
		echo "Stopping $DESC: "

		start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/${NAME}.pid --user ${USER} --exec ${DAEMON}
		RETVAL="$?"
                echo  "$NAME."
		rm -f /var/run/${NAME}.pid
		exit $RETVAL
		;;

	restart|force-reload)
		"${0}" stop
		sleep 1
		"${0}" start
		exit $?
		;;
	*)
		echo "Usage: ${NAME} {start|stop|restart|force-reload|status}" >&2
		exit 3
		;;
esac

exit 0


#!/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
#
TTY=/dev/ttyS1

mTerm_server_running() {
  pid=$(ps | grep -v grep | grep '/usr/local/bin/mTerm_server' -m 1 |
      awk '{print $1}')
  if [ $pid ] ; then
    return 0
  fi
  return 1
}

start_sol_session() {
  echo "You are in SOL session."
  echo "Use ctrl-x to quit."
  echo "-----------------------"
  echo

  /usr/bin/microcom -s 57600 $TTY

  echo
  echo
  echo "-----------------------"
  echo "Exit from SOL session."
}

# if mTerm server is running use mTerm_client to connect to userver
# otherwise fallback to the old method

if mTerm_server_running; then
  exec /usr/local/bin/mTerm_client wedge
else
  start_sol_session
fi


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

# YAMP get_fan : the fan configuration of YAMP is totally different
# from Minipack (1x5 vs 2x4), therefore logic for reading fan RPM
# is also very different, but the output of this function will be
# of the same format as Minipack, so as to reuse the existing code
# as much as possible
usage() {
    echo "Usage: $0 [Fan Unit (1..5)]" >&2
}

FCMCPLD="/sys/bus/i2c/drivers/fancpld/13-0060"

show_pwm()
{
    pwm="$FCMCPLD/fan$1_pwm"
    val=$(cat $pwm | head -n 1)
    # Val is [0,255], so let's scale the value down to [0,100]
    float_val=$(echo "$val 100 * 255 / p" | dc)
    rounded=`printf '%.*f' 0 $float_val`
    echo "$rounded%"
}

show_rpm()
{
    rpm=`cat $FCMCPLD/fan$1_input|head -n 1`
    # Keep the output in the same format as Minipack
    echo "$rpm, $rpm"
}

set -e

# If user input is given, use it as FAN TRAY instance
# Otherwise, read all
if [ "$#" -eq 0 ]; then
    FANS="1 2 3 4 5"
elif [ "$#" -eq 1 ]; then
    if [ "$1" -le 0 ] || [ "$1" -ge 6 ]; then
        echo "Fan $1: Should be between 1 and 5"
        exit 1
    fi
    FANS="$1"
else
    usage
    exit 1
fi

for fan in $FANS; do
    echo "Fan $fan RPMs: $(show_rpm $fan), ($(show_pwm $fan))"
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
#

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

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

echo -n "Setup fan speed... "
/usr/local/bin/set_fan_speed.sh 50
runsv /etc/sv/fscd > /dev/null 2>&1 &
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
#

# YAMP fan set utility for fscd.

usage() {
  echo "Usage: $0 <PWM_PERCENT> [FAN_TRAY] "
  echo "<PWM_PERCENT> : From 0 to 100 "
  echo "[FAN_TRAY] : 1, 2, 3, 4 or 5."
  echo "If no FAN_TRAY is specified, all FANs will be programmed"
}

set -e

# Make sure we only have 1 or 2 arguments
if [ "$#" -ne 2 ] && [ "$#" -ne 1 ]; then
    usage
    exit 1
fi

# Also make sure that percent value is really between 0 and 100
if [ "$1" -lt 0 ] || [ "$1" -gt 100 ]; then
    echo "PWM_PERCENT $1: should be between 0 and 100"
    exit 1
fi

# Read FAN_TRAY value from user argument.
# If no FAN_TRAY is given, configure all FANs
if [ "$#" -eq 1 ]; then
    FAN_UNIT="1 2 3 4 5"
else
    if [ "$2" -le 0 ] || [ "$2" -ge 6 ]; then
        echo "Fan $2: should be between 1 and 5"
        exit 1
    fi
    FAN_UNIT="$2"
fi

# Convert the percentage to our 1/32th level (0-31).
# The user input is given in percent (0-100),
# but YAMP FANCPLD takes PWM as 8bit value (0-255)
# So scale the value by multiplying 2.5
float_step=$(echo "$1 255 * 100 / p" | dc)
step=`printf '%.*f' 0 $float_step`

for unit in ${FAN_UNIT}; do
    pwm="/sys/bus/i2c/drivers/fancpld/13-0060/fan${unit}_pwm"
    echo "$step" > "${pwm}"
    echo "$step will be set to ${pwm} !!!!"
    echo "Successfully set fan ${unit} speed to $1%"
done


#!/bin/sh

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

trap cleanup INT TERM QUIT EXIT

ABOOT_CONF_START=$((0x9FA000))
FLASH_SIZE=$((0x1000000))
ABOOT_CONF_SIZE=$((0x5000))
SECTION_BLOCK_SIZE=$((0x1000))

# Temp files for storing bios file.
TEMP_BIOS_IMAGE="/tmp/tmp_bios_image"
# Temp file for storing aboot_conf data
TEMP_ABOOT_CONF="/tmp/aboot_conf.bin"

DEFAULT_ABOOT_CONF="BOOT_METHOD1=IPV6_PXE,BOOT_METHOD2=LOCAL,BOOT_METHOD3=ARISTA"

cleanup() {
    disconnect_spi
    rm -f $TEMP_ABOOT_CONF $TEMP_BIOS_IMAGE
}

usage() {
    program=$(basename "$0")
    echo "Usage:"
    echo "$program <OP> <bios file>"
    echo "      <OP> : read, write, erase, recover"
    exit 1
}

disconnect_spi() {
    # connect through CPLD
    echo 0x0 > "${SUPCPLD_SYSFS_DIR}/bios_select"
}

connect_spi() {
    # spi2 cs0
    devmem_set_bit "$(scu_addr 88)" 26
    devmem_set_bit "$(scu_addr 88)" 27
    devmem_set_bit "$(scu_addr 88)" 28
    devmem_set_bit "$(scu_addr 88)" 29

    # connect through CPLD
    echo 0x1 > "${SUPCPLD_SYSFS_DIR}/bios_select"
}

# Arista added a 3rd source, so this function is needed in case we are dealing with the 3rd source
do_retry(){
  if [ "$1" = "write" ]; then
    if ! flashrom --layout /etc/yamp_bios.layout --image header --image payload -p linux_spi:dev=/dev/spidev2.0 -w "$2"; then
      echo "flashrom without -c failed"
    fi
  elif [ "$1" = "erase" ]; then
    if ! flashrom -p linux_spi:dev=/dev/spidev2.0 -E; then
       echo "flashrom without -c option failed as well"
    fi
  else # reading
    if ! flashrom -p linux_spi:dev=/dev/spidev2.0 -r "$2"; then
      echo "flashrom without -c option failed"
    fi
  fi
}

create_bios_image() {
    start_block="$(($1 / SECTION_BLOCK_SIZE))"
    num_blocks="$(($2 / SECTION_BLOCK_SIZE))"
    rm -f "$TEMP_BIOS_IMAGE"
    dd if="$3" of="$TEMP_BIOS_IMAGE" bs="$SECTION_BLOCK_SIZE" count="$start_block" \
       2> /dev/null
    dd if="$4" bs="$SECTION_BLOCK_SIZE" count="$num_blocks" >> "$TEMP_BIOS_IMAGE" \
       2> /dev/null
    end_blocks=$(( (FLASH_SIZE / SECTION_BLOCK_SIZE) - start_block - num_blocks ))
    dd if="$3" bs="$SECTION_BLOCK_SIZE" count="$end_blocks" skip=$((start_block + num_blocks)) \
       >> "$TEMP_BIOS_IMAGE" 2> /dev/null
}

create_aboot_conf() {
    echo "Using Aboot conf: $1"

    nvs="$1,"

    rm -f "$TEMP_ABOOT_CONF"
    touch "$TEMP_ABOOT_CONF"
    while [ -n "${nvs%%,*}" ]; do
        nv="${nvs%%,*}"
        name="${nv%%=*}"
        if [ "$name" == "$nv" ]; then
            echo "Invalid name-value argument $nv" >&2
            return 1
        fi
        echo -n "${nv%%=*}=" >> "$TEMP_ABOOT_CONF"
        echo -n "${nv#*=}" | base64 >> "$TEMP_ABOOT_CONF"
        nvs="${nvs#*,}"
    done

    size="$(ls -l "$TEMP_ABOOT_CONF" | awk '{print $5}')"
    pad_size="$((ABOOT_CONF_SIZE - size))"
    dd if=/dev/zero bs=1 count="$pad_size" >> "$TEMP_ABOOT_CONF" 2> /dev/null
}

aboot_version() {
    grep -a CONFIG_LOCALVERSION "$1" 2> /dev/null | awk -F'"' '{print $2}'
}

do_erase() {
    # Layout is not supported in Erase.
    # So we need to manually recover pdr (which include idprom) after erase.
    if [ ! -e /mnt/data/header_pdr.data ]; then
      backup_image
    fi

    # Do the erase
    echo "Erasing the flash"
    if ! flashrom -p linux_spi:dev=/dev/spidev2.0 -E -c "MX25L12835F/MX25L12845E/MX25L12865E"; then
      echo "flashrom failed. Retrying without -c"
      do_retry "erase"
    fi

    # Recover header and pdr (which includes the idprom)
    do_recover
}

do_read() {
    echo "Reading flash content..."
    if ! flashrom -p linux_spi:dev=/dev/spidev2.0 -r "$1" -c "MX25L12835F/MX25L12845E/MX25L12865E"; then
      echo "flashrom failed. Retrying without -c"
      do_retry "read" "$1"
    fi
}

backup_image(){
    echo "Backing up pdr"

    # Get complete image
    if ! tempfile=$(mktemp); then
      echo "Running mktemp in backup_image failed"
      exit 1
    fi

    # /mnt/data should always exist
    if [ ! -d /mnt/data ]; then
      echo "Partition /mnt/data doesn't exist"
      exit 1
    fi

    # Create /mnt/data fixed name which will be used to recover later
    header_pdr_file="/mnt/data/header_pdr.data"

    if ! flashrom -p linux_spi:dev=/dev/spidev2.0 -r "${tempfile}" -c "MX25L12835F/MX25L12845E/MX25L12865E"; then
      echo "Flashrom failed. Retrying without -c"
      do_retry "read" "${tempfile}"
    fi

    # Make sure data is fully read
    datasize=$(stat -c%s "${tempfile}")
    if [ "${datasize}" -lt "${FLASH_SIZE}" ]; then
       echo "Unable to store all the data. Will not erase SPI"
       rm "${tempfile}"
       exit 1
    fi

    # saving header, and pdr.
    # conv option not available in bmc busybox dd (can't do conv=nosync to prevent file from being truncated), so saving header as well.
    # we are backing from 00000000 to 00020fff which is 18 bits total. so we will use 9 bits for bs and 9 bits for count to get to the needed regions.
    if ! /bin/dd if="${tempfile}" of="${header_pdr_file}" bs=512 count=512; then
      echo "Running dd in backup_image failed"
      exit 1
    fi

    # The full image is no longer needed, so removed it
    rm "${tempfile}"

}

do_write() {
    bios_image="$1"
    if [ -n "$(aboot_version "$bios_image")" ]; then
        create_aboot_conf "$DEFAULT_ABOOT_CONF" || exit 1
        create_bios_image "$ABOOT_CONF_START" "$ABOOT_CONF_SIZE" \
                          "$bios_image" "$TEMP_ABOOT_CONF" || exit 1
        bios_image="$TEMP_BIOS_IMAGE"
    fi

    if [ ! -e /mnt/data/header_pdr.data ]; then
      backup_image
    fi
    echo " writing header and payload ... "
    if ! flashrom --layout /etc/yamp_bios.layout --image header --image payload -p linux_spi:dev=/dev/spidev2.0 -w "$bios_image" -c "MX25L12835F/MX25L12845E/MX25L12865E"; then
      echo "flashrom failed. Retrying without -c"
      do_retry "write" "$bios_image"
    fi
}

do_recover() {
  echo "Recovering PDR region"
  if [ ! -e /mnt/data/header_pdr.data ]; then
    echo "recovery data /mnt/data/header_pdr.data doesn't exist. Exiting ..."
    exit 1
  fi

  # Getting full image ready. Image must be the same as original size
  if ! file=$(mktemp); then
    echo "Running mktemp in do_recover failed"
    exit 1
  fi
  cp /mnt/data/header_pdr.data "${file}"

  # So we have 16515072 bytes left which we will pad with zero so that we can get to the flashsize which is 16777216 bytes
  # Therefore, we will use a bs of 512 with a 32256 as count
  if ! /bin/dd if=/dev/zero bs=512 count=32256 >> "${file}"; then
    echo "Running dd in do_recover failed"
    exit 1
  fi

  #Recover pdr region which includes the idprom region
  if ! flashrom --layout /etc/yamp_bios.layout --image header --image pdr -p linux_spi:dev=/dev/spidev2.0 -w "${file}" -c "MX25L12835F/MX25L12845E/MX25L12865E"; then
    echo "flashrom failed. Retrying without the -c"
    do_retry "write" "${file}"
  fi
  rm "${file}"
}

connect_spi

if [ "$1" == "erase" ]; then
    do_erase
elif [ "$1" == "read" ]; then
    do_read "$2"
elif [ "$1" == "write" ]; then
    do_write "$2"
elif [ "${1}" == "recover" ]; then
    do_recover
else
    usage
fi


#!/bin/sh

# Copyright 2018-present Facebook. All Rights Reserved.

SUPCPLD_SYSFS_DIR="/sys/bus/i2c/devices/12-0043"
SCDCPLD_SYSFS_DIR="/sys/bus/i2c/devices/4-0023"
SUP_PWR_ON_SYSFS="${SUPCPLD_SYSFS_DIR}/cpu_control"
PWR_SYSTEM_SYSFS="${SUPCPLD_SYSFS_DIR}/chassis_power_cycle"
SCD_TH3_RST_ON_SYSFS="${SCDCPLD_SYSFS_DIR}/th3_reset"
SCD_TH3_PCI_RST_ON_SYSFS="${SCDCPLD_SYSFS_DIR}/th3_pci_reset"
SCD_RST="${SCDCPLD_SYSFS_DIR}/scd_reset"
LC_SMB_MUX_RST="${SCDCPLD_SYSFS_DIR}/lc_smb_mux_rst"

wedge_iso_buf_enable() {
    return 0
}

wedge_iso_buf_disable() {
    return 0
}

wedge_is_us_on() {
    local val
    val=$(cat $SUP_PWR_ON_SYSFS 2> /dev/null | head -n 1)
    if [ -z "$val" ]; then
        return $default
    elif [ "$val" == "0x1" ]; then
        return 0            # powered on
    else
        return 1
    fi
}

wedge_board_type() {
    echo 'YAMP'
}

wedge_slot_id() {
    printf "1\n"
}

wedge_board_rev() {
    # assume P2
    return 2
}

# Should we enable OOB interface or not
wedge_should_enable_oob() {
    # YAMP uses BMC MAC since beginning
    return 1
}

wedge_power_off_asic() {
    # It is not exact power off.
    # Instead, the ASIC is kept in reset in this case.
    echo 1 > $SCD_TH3_RST_ON_SYSFS
    echo 1 > $SCD_RST
    sleep 1
    echo 1 > $SCD_TH3_PCI_RST_ON_SYSFS
}

wedge_power_on_asic() {
    # Order matters here
    echo 0 > $SCD_TH3_RST_ON_SYSFS
    echo 0 > $SCD_RST
    usleep 250000
    echo 0 > $SCD_TH3_PCI_RST_ON_SYSFS
}

wedge_power_on_board() {
    # Order matters here
    echo 1 > $SUP_PWR_ON_SYSFS
    sleep 1
    wedge_power_off_asic
    sleep 1
    wedge_power_on_asic
    sleep 1
}

wedge_power_off_board() {
    # Order matters here
    echo 0 > $SUP_PWR_ON_SYSFS
    sleep 1
    wedge_power_off_asic
    sleep 1
}


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

dpm_path="/sys/bus/i2c/drivers/ucd9000/3-004e"
logfile="/mnt/data1/log/dpm_log"
logfile_old="${logfile}.1"
max_loglines=1000

trap cleanup INT TERM QUIT EXIT

REBIND=false

if [ -d "$dpm_path" ]; then
    REBIND=true
    echo "# Unbinding SWITCHCARD DPM from ucd9000 driver"
    echo "3-004e" > /sys/bus/i2c/drivers/ucd9000/unbind
fi

# Check to see if the log file needs to be rotated
touch $logfile $logfile_old
lines="$(wc -l $logfile|cut -d' ' -f1)"
if [ "$lines" -gt $max_loglines ]
then
    echo "Rotating DPM log file"
    rm -f "$logfile_old"
    cp "$logfile" "$logfile_old"
    rm -f "$logfile"
fi

echo "Reading DPM logs..."

log=''
log="$log{'Date':'$(date -u "+%Y-%m-%d %T")'"
log="$log,'Log':'$(i2cget -y 3 0x4e 0xea i | tail -n 1)'"

eb="$(i2cget -y 3 0x4e 0xeb w)"

len="${eb:2:2}"

for (( i = 0 ; i < "$len" ; i++ ))
do
  i2cset -y 3 0x4e 0xeb 0x"$len""$(printf '%02x' "$i")" w
  man="$(i2cget -y 3 0x4e 0xec i | tail -n 1)"
  exp="$(i2cget -y 3 0x4e 0x20 | tail -n 1)"
  log="$log,'detail_$i':{'m':'$man','e':'$exp'}"
done

log="$log}"

echo "$log" >> "$logfile"

echo "Clearing DPM logs..."
i2cset -y 3 0x4e 0xea 0 0 0 0 0 0 0 0 0 0 0 0 0 0 s

cleanup() {
    if [ "$REBIND" = true ]; then
        echo "# Re-Binding SWITCHCARD DPM to ucd9000 driver"
        echo "3-004e" > /sys/bus/i2c/drivers/ucd9000/bind
    fi
}


#!/bin/bash
. /usr/local/bin/openbmc-utils.sh

show_dps_ver() {
  name=$1
  bus=$2
  addr=$3
  drvload=$4
  if [ $drvload -eq 1 ]; then
     i2c_device_delete $bus $addr
     sleep 1
  fi
  dump=`i2cdump -y ${bus} ${addr} s 0x9e |grep -v abcdef`
  dps_ver=`echo ${dump##* }`
  echo $name $dps_ver
  if [ $drvload -eq 1 ]; then
     i2c_device_add $bus $addr ucd90120
  fi
}
echo "!!!"
echo "!!! WARNING: Displaying DSP version will disrupt sensor reading !!!"
echo "!!!"
show_dps_ver "SUP.:" 9 0x11 0
show_dps_ver "SCD.:" 3 0x4e 1
show_dps_ver "PIM1:" 14 0x4e 1
show_dps_ver "PIM2:" 15 0x4e 1
show_dps_ver "PIM3:" 16 0x4e 1
show_dps_ver "PIM4:" 17 0x4e 1
show_dps_ver "PIM5:" 18 0x4e 1
show_dps_ver "PIM6:" 19 0x4e 1
show_dps_ver "PIM7:" 20 0x4e 1
show_dps_ver "PIM8:" 21 0x4e 1
echo "!!! Done."


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

for index in 1 2 3 4 5 6 7 8
do
    cache_file="/tmp/pim${index}_serial.txt"

    if [ ! -s "$cache_file" ] || [ -z "$(cat $cache_file)" ]; then
        /usr/bin/weutil lc${index} |grep Product|grep Serial|cut -d ' ' -f 4 > "$cache_file"
    fi
    serial="$(cat $cache_file)"
    echo PIM${index} : ${serial}
done


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

### BEGIN INIT INFO
# Provides:          eth0_mac_fixup.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description:  Fixup the MAC address for eth0 based on wedge EEPROM
### END INIT INFO

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

#
# FIXME restart eth0 interface to refresh ipv6 link-local address. The
# workaround is needed for yamp mainly because ipv6 link-local address
# might be derived from the "random" mac address which leads to DHCP
# request failures.
#
# Below explains why the problem happens. We are still investigating the
# official fix, which most likely goes to kernel space.
#   1) when "ftgmac100" driver is binded to BMC's MAC Controller, the
#      controller is assigned with a "random" MAC address.
#   2) later when "/etc/init.d/networking start" is executed for the first
#      time, "ftgmac100" driver starts to communicate with (Broadcom) NCSI
#      NIC, including issuing "GET_MAC_ADDR" command to NCSI NIC.
#   3) given ftgmac100->ndo_open() and NCSI command-handling are running
#      asynchronously, BMC's ipv6 link-local address is "undefined": it may
#      be derived from the "random" mac address, or the permanent one (from
#      NCSI NIC), depending on which task (ipv6 link-local address generation
#      or handling "GET_DMA_ADDR" response from NCSI NIC) happens first.
#   4) If unfortunately random MAC is used (which happens most times), DHCP
#      server will ignore BMC's DHCP request due to UUID mismatch.
#
# Note:
#   1) the workaround is not needed by kernel 4.1 because ftgmac100->ndo_open
#      won't return until "GET_MAC_ADDR" NSCI command is handled.
#
KERNEL_VERSION=`uname -r`
if [[ ${KERNEL_VERSION} != 4.1.* ]]; then
  echo "fixup eth0 interface.."
  sleep 1
  ifdown eth0
  ifup eth0
fi

# set the MAC from ifconfig back to u-boot environment so that u-boot
# can use it
mac=$(ifconfig eth0  |grep HWaddr  |awk '{ print $5 }')
ethaddr=$(fw_printenv ethaddr  | cut -d'=' -f2 )
if [ "$ethaddr" != "$mac" ]; then
    fw_setenv "ethaddr" "$mac"
fi


#!/bin/sh

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

CPLD_JTAG_SEL_L="CPLD_JTAG_SEL_L"
JTAG_EN="${SUPCPLD_SYSFS_DIR}/jtag_en"
JTAG_SEL="${SUPCPLD_SYSFS_DIR}/jtag_sel"
JTAG_LC_FAN_CTRL="${SCDCPLD_SYSFS_DIR}/jtag_ctrl"
JTAG_FAN_WP="${SCDCPLD_SYSFS_DIR}/fancpld_wp"

LINECARD=0

SUP_PROGRAM=false
SCD_PROGRAM=false

trap disconnect_jtag INT TERM QUIT EXIT

usage() {
    program=$(basename "$0")
    echo "Usage:"
    echo "$program <fpga> <action> <fpga file>"
    echo "      <fpga> : sup, scd, lc1, lc2, ..., lc8, fan"
    echo "      <action> : program, verify"
    exit 1
}

disconnect_jtag() {
    gpio_set_value $CPLD_JTAG_SEL_L 1
    if [ "$SUP_PROGRAM" = false ]; then
        echo 0 > "$JTAG_EN"
        echo 0 > "$JTAG_SEL"
    fi
    if [ "$SCD_PROGRAM" = false ]; then
        # enable fancpld write protection
        echo 1 > "$JTAG_FAN_WP"
        # do not select any linecard or fan
        echo 0x0 > "$JTAG_LC_FAN_CTRL"
    fi
    if [ $LINECARD -ne 0 ]; then
        # cycle the linecard FPGA
        gpio_set_value LC${LINECARD}_FAST_JTAG_EN 0
        gpio_set_value LC${LINECARD}_SCD_CONFIG_L 0
        sleep 1
        gpio_set_value LC${LINECARD}_SCD_CONFIG_L 1
    fi
}

connect_scd_jtag() {
    gpio_set_value $CPLD_JTAG_SEL_L 1
    echo 1 > "$JTAG_EN"
    echo 1 > "$JTAG_SEL"
}

connect_sup_jtag() {
    gpio_set_value $CPLD_JTAG_SEL_L 0
    echo 0 > "$JTAG_EN"
}

connect_linecard_jtag() {
    lc=$1
    LINECARD=${lc}
    gpio_set_value $CPLD_JTAG_SEL_L 1
    echo 1 > "$JTAG_EN"
    echo 0 > "$JTAG_SEL"
    # choose correct LC
    echo "${lc}" > "$JTAG_LC_FAN_CTRL"
    gpio_set_value LC"${lc}"_FAST_JTAG_EN 1
}

connect_fan_jtag() {
    gpio_set_value $CPLD_JTAG_SEL_L 1
    echo 1 > "$JTAG_EN"
    echo 0 > "$JTAG_SEL"
    echo 0xa > "$JTAG_LC_FAN_CTRL"
}

do_scd() {
    # verify the fpga file
    if ! grep "DESIGN.*scd" "$2" > /dev/null; then
        echo "$2 is not a vaild SCD FPGA file"
        exit 1
    fi
    SCD_PROGRAM=true
    connect_scd_jtag
    jam -l/usr/lib/libcpldupdate_dll_ioctl.so -v -a"${1^^}" "$2" \
      --ioctl RUN_CYCLE
}

do_sup() {
    # verify the fpga file
    if ! grep "DESIGN.*son" "$2" > /dev/null; then
        echo "$2 is not a vaild SUP FPGA file"
        exit 1
    fi
    SUP_PROGRAM=true
    connect_sup_jtag
    jam -l/usr/lib/libcpldupdate_dll_ioctl.so -v -a"${1^^}" "$2" \
      --ioctl RUN_CYCLE
}

do_fan() {
    echo "Fan CPLD upgrade is not supported"
    exit 1
}

do_linecard() {
    lc="$1"
    action="${2,,}"

    if [ "$action" != "program" ]; then
        echo "Only 'program' action is supported for linecard"
        exit 1
    fi

    if [ ${#lc} -ne 3 ]; then
        echo "'$lc' is not a valid linecard. Expect 'lc1', 'lc2', ..., 'lc8'"
        exit 1
    fi

    lc=${lc:2:1}
    if [[ $lc -lt 1 || $lc -gt 8 ]]; then
        echo "'$lc' is not a valid linecard. Expect 'lc1', 'lc2', ..., 'lc8'"
        exit 1
    fi

    connect_linecard_jtag "$lc"

    xapp -l /usr/lib/libcpldupdate_dll_ast_jtag.so "$3"
}

if [ $# -ne 3 ]; then
    usage
fi

if uname -r | grep "4\.1\.*" > /dev/null 2>&1; then
  modprobe ast_jtag
fi

if [ "$1" = "scd" ]; then
    shift 1
    do_scd "$@"
elif [ "$1" = "sup" ]; then
    shift 1
    do_sup "$@"
elif [ "$1" = "fan" ]; then
    shift 1
    do_fan "$@"
elif [[ "$1" = "lc"* ]]; then
    do_linecard "$@"
else
    usage
fi


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

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

maj_ver="cpld_ver_major"
min_ver="cpld_ver_minor"
exitCode=0

echo "------SUP-FPGA------"

if [ ! -d $SUPCPLD_SYSFS_DIR ]; then
    echo "SUP FPGA is not detected"
else
    val_major=$(head -n 1 $SUPCPLD_SYSFS_DIR/$maj_ver)
    val_minor=$(head -n 1 $SUPCPLD_SYSFS_DIR/$min_ver)
    echo "SUP_FPGA: $(($val_major)).$(($val_minor))"
fi

echo "------SCD-FPGA------"
if [ ! -d $SCDCPLD_SYSFS_DIR ]; then
    echo "SCD FPGA is not detected"
    echo "Unable to retrieve PIM FPGA versions eihter"
else
    val_major=$(head -n 1 $SCDCPLD_SYSFS_DIR/$maj_ver)
    val_minor=$(head -n 1 $SCDCPLD_SYSFS_DIR/$min_ver)
    echo "SCD_FPGA: $(($val_major)).$(($val_minor))"

    echo "------PIM-FPGA------"
    pim_list="1 2 3 4 5 6 7 8"
    for pim in ${pim_list}; do
      pim_maj_ver_file="lc${pim}_fpga_rev_major"
      pim_min_ver_file="lc${pim}_fpga_rev_minor"
      val1=$(head -n 1 $SCDCPLD_SYSFS_DIR/$pim_maj_ver_file)
      val2=$(head -n 1 $SCDCPLD_SYSFS_DIR/$pim_min_ver_file)
      if [ "$((val1))" -eq 255 ]; then
        # Print all the PIM status then exit
        echo "PIM $pim: NOT DETECTED"
        exitCode=1
      else
        # val1 can never be 0 under normal operation
        # so let's set the exitCode to 1 in case val1
        # is 0
        if [ "$((val1))" -eq 0 ]; then
          exitCode=1
        fi
        echo "PIM $pim : $((val1)).$((val2))"
      fi
    done
fi

if [ "$exitCode" -ne 0 ]; then
    echo "Since all the PIMs detection didn't succeed as listed above... exiting"
    exit 1
fi


#!/bin/bash
#
# 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
#
# This script will wake up every 10 seconds and do the following
#    1. Try to discover any new PIM(s) plugged in
#    2. For all discovered PIMs, attempt to turn on the PIM and
#       the gearbox chip on it
#

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

pim_list=$(seq 0 7)
pim_found=(0 0 0 0 0 0 0 0)
pim_bus=(14 15 16 17 18 19 20 21)
pca_addr=20

create_pim_gpio() {
  local base lc
  lc=$1
  chip=$2

  if [ -e LC${lc}_STATUS_GREEN_L ]; then
      # already created GPIOs for such pim
      return
  fi

  gpio_export_by_offset ${chip} 1 LC${lc}_DPM_POWER_UP
  gpio_export_by_offset ${chip} 4 LC${lc}_SCD_RESET_L
  gpio_export_by_offset ${chip} 5 LC${lc}_SCD_CONFIG_L
  gpio_export_by_offset ${chip} 6 LC${lc}_SATELLITE_PROG
  gpio_export_by_offset ${chip} 7 LC${lc}_LC_PWR_CYC
  gpio_export_by_offset ${chip} 8 LC${lc}_BAB_SYS_RESET_L
  gpio_export_by_offset ${chip} $((8 + 5)) LC${lc}_FAST_JTAG_EN
  gpio_export_by_offset ${chip} $((8 + 6)) LC${lc}_STATUS_RED_L
  gpio_export_by_offset ${chip} $((8 + 7)) LC${lc}_STATUS_GREEN_L
  logger pim_enable: registered PIM${lc} with GPIO chip ${chip}
}

power_on_pim() {
  local lc old ver
  lc=$1
  old=$(gpio_get LC${lc}_DPM_POWER_UP keepdirection)
  if [ $old -eq 1 ]; then
      # already powered on, skip
      return
  fi
  gpio_set LC${lc}_DPM_POWER_UP 1 # all power on
  sleep 1
  gpio_set LC${lc}_SCD_RESET_L 1     # scd out of reset
  gpio_set LC${lc}_SCD_CONFIG_L 1    # scd not in config
  gpio_set LC${lc}_BAB_SYS_RESET_L 1 # gearbox out of reset
  # If linecard FPGA version is before v6, need to set SATELLITE_PROG to 0.
  # Otherwise, need to set it to 1.
  # However, the reading of the linecard FPGA version is not reliable,
  # we will set SATELLITE_PROG to 1 at all time, assuming the linecard FPGA
  # is upgraded to the latest.
  gpio_set LC${lc}_SATELLITE_PROG 1
  gpio_set LC${lc}_STATUS_RED_L 1 # turn off red
  gpio_set LC${lc}_STATUS_GREEN_L 0 # turn on green
  logger pim_enbale: powered on PIM${lc}
}

#clear pimserial endpoint cache if pim doesn't exist but the pimserial file does.
clear_pimserial_cache(){
  for i in "${pim_list[@]}"
  do
    pimserial_number="${1}"
    pimserial_path="$SCDCPLD_SYSFS_DIR/lc${pimserial_number}_prsnt_sta"
    pimserial_present="$(cat ${pimserial_path} 2> /dev/null | head -n 1)"
    pimserial_cache_path=/tmp/pim${pimserial_number}_serial.txt

    if [ "${pimserial_present}" == 0x0 ] && [ -f "${pimserial_cache_path}" ]; then
      #pim device doesn't exist but pimserial cache txt file exist, so remove it.
      rm -rf "${pimserial_cache_path}"
    fi
  done
}

while true; do
  # 1. For any uncovered PIM, try to discover
  for i in ${pim_list[@]}
  do
    if [ "${pim_found[$i]}" -eq "0" ]; then
      pim_number=$(expr $i + 1)
      pim_addr=${pim_bus[$i]}-00$pca_addr  # 14-0020 for example
      # Check if Switch card senses the PIM presence
      pim_path="$SCDCPLD_SYSFS_DIR/lc${pim_number}_prsnt_sta"
      pim_present=`cat $pim_path 2> /dev/null | head -n 1`
      # There is a HW bug which makes pim presence unreliable.
      #if [ "$pim_present" == "0x1" ]; then
      if true; then
         dev_path=/sys/bus/i2c/devices/$pim_addr
         drv_path=/sys/bus/i2c/drivers/pca953x/$pim_addr
         if [ ! -e $drv_path ]; then
           # Driver doesn't exist
           if [ -e $dev_path ]; then
              # Device exists. Meaning previous probe failed. Clean up previous failure first
              i2c_device_delete ${pim_bus[$i]} 0x$pca_addr
              # Give some time to kernel
              sleep 1
           fi
           # Probe this device
           reg0_val=`i2cget -y ${pim_bus[$i]} 0x$pca_addr 0 2>&1`
           if [[ ! "$reg0_val" == *"Error"* ]]; then
              i2c_device_add ${pim_bus[$i]} 0x$pca_addr pca9555
           fi
         fi
         # Check if device was probed and driver was installed
         if [ -e $drv_path/gpio ]; then
           create_pim_gpio $((i+1)) ${pim_addr}
           pim_found[$i]=1
         fi
      fi
    fi
  done
  # 2. For discovered gpios, try turning it on
  for i in ${pim_list[@]}
  do
    if [ "${pim_found[$i]}" -eq "1" ]; then
       power_on_pim $((i + 1))
    fi

    #clear pimserial endpoint cache
    clear_pimserial_cache $((i+1))

  done
  # Sleep 5 seconds until the next loop.
  # reduce to 5 seconds for faster scan.
  sleep 5
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

### BEGIN INIT INFO
# Provides:          power-on
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Power on micro-server
### END INIT INFO
. /usr/local/bin/openbmc-utils.sh

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

# Power-on script now includes TH3 toggle.That is, when BMC is booting up
# while TH3 is already running, it should not blindly toggle reset TH3.
# Otherwise (if we blindly toggle reset TH3), BMC upgrade will become
# disruptive upgrade. Therefore we will run board power up sequence only
# if CPU is currently turned off.
if wedge_is_us_on; then
    echo "uServer is already up. Skipping board power-on sequence"
else
    echo "uServer is not up. Running board power-on sequence"
    wedge_power_on_board
fi

# Now, double check if power is on, and do forced power up ad needed.
echo  "Checking microserver power status ... "
if wedge_is_us_on; then
    echo "on"
    on=1
else
    echo "off"
    on=0
fi

if [ $on -eq 0 ]; then
    # Power on now
    echo "uServer still not up. Running forced power-up sequence"
    wedge_power.sh on -f
fi

pim_enable.sh > /dev/null 2>&1 &


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

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

logger "Power off TH3"
echo "Power off TH3"
wedge_power_off_asic
sleep 1
logger "Power on TH3"
echo "Power on TH3"
wedge_power_on_asic
sleep 1


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

### BEGIN INIT INFO
# Provides:          setup_board.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Setup the board
### END INIT INFO

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

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

# TODO: Light up sys led


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

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

# First, we will Enable write in WRITE_PROTECT(0x10) reg before adding the i2c
# pmbus device for dps1900. This will prevent some sysfs node from disappearing
# when we powercycle
i2c_dsp1900_create(){
  if ! i2cset -f -y "$1" 0x58 0x10 0; then
    echo "Fail to clear PSU pmbus WRITE_PROTECT(0x10) register"
  fi
  i2c_device_add "$1" 0x58 pmbus
}

# if applicable, saved the debug log for ir35223
ir35223_dbg_log(){
  log_data=("${!1}")
  if [ ${#log_data[@]} != 0 ]; then
    touch /var/log/failed_ir35223_log.txt
    for cmd in "${log_data[@]}"
    do
      echo "${cmd}" >> /var/log/failed_ir35223_log.txt;
    done
  fi
}

# There are some registers that need to be initialized in IR35223
# prior to loading PMBus module for yamp devices
i2c_ir35223_init(){
  # Array to hold failed data
  declare -a failed_ir35223_cmds

  # Step 1:0x005C [15:0] = 0x0102
  if ! i2cset -y 3 0x12 0xff 0x00; then
    failed_ir35223_cmds+=("Running i2cset -y 3 0x12 0xff 0x00 failed")
  fi
  if ! i2cset -y 3 0x12 0x5c 0x0102 w; then
    failed_ir35223_cmds+=("Running i2cset -y 3 0x12 0x5c 0x0102 w failed")
  fi

  # Step 2: 0x043A [7:4] = 0xD
  if ! i2cset -y 3 0x12 0xff 0x04; then
    echo "Running i2cset -y 3 0x12 0xff 0x04 failed"
  fi
  if ! i2cset -y -m 0xf0 3 0x12 0x3a 0xd0; then
    echo "Running i2cset -y -m 0xf0 3 0x12 0x3a 0xd0 failed"
  fi

  # Step 3: 0x0040 [7:0] = 0xFF
  if ! i2cset -y 3 0x12 0xff 0x00; then
    echo "Running i2cset -y 3 0x12 0xff 0x00 failed"
  fi
  if ! i2cset -y 3 0x12 0x40 0xff; then
    echo "Running i2cset -y 3 0x12 0x40 0xff failed"
  fi

  # Step 4: 0x0428 [3:0] = 0x2
  if ! i2cset -y 3 0x12 0xff 0x04; then
    echo "Running i2cset -y 3 0x12 0xff 0x04 failed"
  fi
  if ! i2cset -y -m 0x0f 3 0x12 0x28 0x02; then
    echo "Running i2cset -y -m 0x0f 3 0x12 0x28 0x02"
  fi

  # Step 5: 0x042E [5:0] = 0x0D
  if ! i2cset -y 3 0x12 0xff 0x04; then
    echo "Running i2cset -y 3 0x12 0xff 0x04"
  fi
  if ! i2cset -y -m 0x1f 3 0x12 0x2e 0x0d; then
    echo "i2cset -y -m 0x1f 3 0x12 0x2e 0x0d failed"
  fi

  # Step 6: 0x0444 [7:7] = 0x1
  if ! i2cset -y 3 0x12 0xff 0x04; then
    echo "Running i2cset -y -m 0x1f 3 0x12 0x2e 0x0d failed"
  fi
  if ! i2cset -y -m 0x80 3 0x12 0x44 0x80; then
    echo "Running i2cset -y -m 0x80 3 0x12 0x44 0x80 failed"
  fi

  # Step 7: Set Page back to 0
  if ! i2cset -y 3 0x12 0xff 0x00; then
    echo "i2cset -y 3 0x12 0xff 0x00"
  fi

  # Saved debug log
  ir35223_dbg_log failed_ir35223_cmds[@]
}

# First, take TPM out of reset, so that we can probe it later
# Active low - 1 means out of reset, 0 means in reset
gpio_set TPM_RST_N 1

# Probe the devices used by fscd first, just in case probing
# taking too long, when one of modules are not in good shape.
# 1. Probe SUP Inlet1/2 sensor, used for fscd
i2c_device_add 11 0x4c max6658
# 2. Probe TH3 temp sensor, also used for fscd
i2c_device_add 4 0x4d max6581

# Bus  0 - SMBus 1
i2c_device_add 0 0x20 tpm_i2c_infineon

# Bus  1 - SMBus 2
i2c_device_add 1 0x50 supsfp

# Bus  3 - SMBus 4 - SCB ECB/VRD and sensors
i2c_device_add 3 0x40 pmbus
i2c_device_add 3 0x41 pmbus
i2c_device_add 3 0x4e ucd90120
i2c_ir35223_init
i2c_device_add 3 0x42 pmbus
i2c_device_add 3 0x44 pmbus

# Bus  4 - SMBus 5 SCD
i2c_device_add 4 0x23 scdcpld
i2c_device_add 4 0x50 24c512

#
# Bus  2 - SMBus 3 - LC, MUXED as Bus 14-21
#
# Note:
#  1) 2-0075 may not be created if yamp is running an older kernel, so
#     let's check and create the device if needed.
#  2) if 2-0075 is already created (in device tree) but driver binding
#     failed, then we will need to bind the driver manually. The failure
#     usually happens when the chassis is power cycled, because 2-0075
#     cannot be detected until it's taken out of reset (by writing scdcpld
#     register LC_SMB_MUX_RST).
#
echo 0 > "$LC_SMB_MUX_RST"  # take the mux (2-0075) out of reset

SMB_MUX_DEV="2-0075"
SMB_MUX_PATH=$(i2c_device_sysfs_abspath "$SMB_MUX_DEV")
if [ ! -d "$SMB_MUX_PATH" ]; then
    i2c_mux_add_sync 2 0x75 pca9548 8
elif [ ! -L "${SMB_MUX_PATH}/driver" ]; then
    mux_driver="pca954x"
    echo "Manually bind $mux_driver to $SMB_MUX_DEV.."
    i2c_bind_driver "$mux_driver" "$SMB_MUX_DEV"

    # Wait till all the 8 channels (0-7) are populated; otherwise devices
    # behind the switch cannot be created.
    MUX_RETRY=0
    until [ -d "${SMB_MUX_PATH}/channel-7" ]; do
        usleep 10000 # sleep for 10 milliseconds
        MUX_RETRY=$((MUX_RETRY + 1))
        if [ "$MUX_RETRY" -gt 3 ]; then
            break
        fi
    done
fi

# Bus  5 - SMBus 6 PSU1
i2c_dsp1900_create 5

# For now, we assume that PSU2 and PSU3 are not present
#i2c_device_add 6 0x58 pmbus
#i2c_device_add 7 0x58 pmbus

# Bus  8 - SMBus 9 PSU4
i2c_dsp1900_create 8

# Bus  9 - SMBus 10 SUP DPM
#i2c_device_add 9 0x11 pmbus

# Bus  10 - SMBus 11 SUP POWER
i2c_device_add 10 0x21 cpupwr
i2c_device_add 10 0x27 mempwr

# Bus  11 - SMBus 12 SUP TEMP
i2c_device_add 11 0x40 pmbus

# Bus  12 - SMBus 13 SUP CPLD
i2c_device_add 12 0x43 supcpld

# Bus  13 - SMBus 14 FAN CTRL
i2c_device_add 13 0x4c max6658
i2c_device_add 13 0x52 24c512
i2c_device_add 13 0x60 fancpld

# Bus  14 - Muxed LC1
i2c_device_add 14 0x4e ucd90120
i2c_device_add 14 0x42 pmbus
i2c_device_add 14 0x20 pca9555
i2c_device_add 14 0x4c max6658
i2c_device_add 14 0x50 24c512

# Bus  15 - Muxed LC2
i2c_device_add 15 0x4e ucd90120
i2c_device_add 15 0x42 pmbus
i2c_device_add 15 0x20 pca9555
i2c_device_add 15 0x4c max6658
i2c_device_add 15 0x50 24c512

# Bus  16 - Muxed LC3
i2c_device_add 16 0x4e ucd90120
i2c_device_add 16 0x42 pmbus
i2c_device_add 16 0x20 pca9555
i2c_device_add 16 0x4c max6658
i2c_device_add 16 0x50 24c512

# Bus  17 - Muxed LC4
i2c_device_add 17 0x4e ucd90120
i2c_device_add 17 0x42 pmbus
i2c_device_add 17 0x20 pca9555
i2c_device_add 17 0x4c max6658
i2c_device_add 17 0x50 24c512

# Bus  18 - Muxed LC5
i2c_device_add 18 0x4e ucd90120
i2c_device_add 18 0x42 pmbus
i2c_device_add 18 0x20 pca9555
i2c_device_add 18 0x4c max6658
i2c_device_add 18 0x50 24c512

# Bus  19 - Muxed LC6
i2c_device_add 19 0x4e ucd90120
i2c_device_add 19 0x42 pmbus
i2c_device_add 19 0x20 pca9555
i2c_device_add 19 0x4c max6658
i2c_device_add 19 0x50 24c512

# Bus  20 - Muxed LC7
i2c_device_add 20 0x4e ucd90120
i2c_device_add 20 0x42 pmbus
i2c_device_add 20 0x20 pca9555
i2c_device_add 20 0x4c max6658
i2c_device_add 20 0x50 24c512

# Bus  21 - Muxed LC8
i2c_device_add 21 0x4e ucd90120
i2c_device_add 21 0x42 pmbus
i2c_device_add 21 0x20 pca9555
i2c_device_add 21 0x4c max6658
i2c_device_add 21 0x50 24c512


#!/bin/bash

# shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh
SUPCPLD_SYSFS_DIR=$(i2c_device_sysfs_abspath 12-0043)
SUP_PWR_ON_SYSFS="${SUPCPLD_SYSFS_DIR}/cpu_control"

echo "=== USERVER PWR STATUS ==="
if ! val=$(head -n 1 2>/dev/null < "${SUP_PWR_ON_SYSFS}"); then
  echo "Error when trying to read $SUP_PWR_ON_SYSFS, exiting..."
  exit 1
fi

if [ -z "$val" ]; then
  echo "cpu_control register is 0"
else
  echo "cpu_control register is 1"
fi
echo "=== BMC SYSTEM TIME ==="
date
echo "=== BMC VERSION ==="
cat /etc/issue
echo "=== BMC UPTIME ==="
uptime
echo "=== FPGA VERSIONS ==="
fpga_ver.sh
echo "=== CHASSIS SERIAL NUMBER ==="
weutil CHASSIS
echo "=== SWITCH CARD SERIAL NUMBER ==="
weutil SCD
echo "=== SUP SERIAL NUMBER ==="
weutil SUP
echo "=== LC1 SERIAL NUMBER ==="
weutil LC1
echo "=== LC2 SERIAL NUMBER ==="
weutil LC2
echo "=== LC3 SERIAL NUMBER ==="
weutil LC3
echo "=== LC4 SERIAL NUMBER ==="
weutil LC4
echo "=== LC5 SERIAL NUMBER ==="
weutil LC5
echo "=== LC6 SERIAL NUMBER ==="
weutil LC6
echo "=== LC7 SERIAL NUMBER ==="
weutil LC7
echo "=== LC8 SERIAL NUMBER ==="
weutil LC8
echo "=== PSU SHOWTECH AT BUS 5 ==="
python /usr/local/bin/psu_show_tech.py 5 0x58 -c dps1900
echo "=== PSU SHOWTECH AT BUS 8 ==="
python /usr/local/bin/psu_show_tech.py 8 0x58 -c dps1900


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

weutil SUP > /tmp/sup_weutil.txt