#!/bin/bash
#
#
# Script to build the following firmwares:
# - icss dualemac
# - icss switch
# - icss hsr/prp
#
# Toolchain:
# -----------
# Download latest PRU toolchain from:
#  http://syntaxerror.dal.design.ti.com/release/release.cgi and search for PRU
# latest toolchain as of July 2020 is 2_3_2:
#  http://syntaxerror.dal.design.ti.com/release/releases/pru/rel2_3_2/build/install/
#
# PDK for dual_emac and switch firmware:
# --------------------------------------
# Tree: ssh://git@bitbucket.itg.ti.com/processor-sdk/pdk.git
# Branch: master
#
# ICSS for HSR/PRP:
# -----------------
# Tree: ssh://git@bitbucket.itg.ti.com/pindsw/industrial_communications_dev.git
# Branch: int_procsdk_ind_01_00_00
#

# Change below 3 paths accrodingly
export CL_PRU_INSTALL_PATH="/home/vineet/ti/icss_m_work/ti-cgt-pru_2.3.3"
PDK='/home/vineet/repo/pdk'
#Ignore this
ICSS_DEV='/home/vineet/ti/icss_m_work/industrial_communications_dev'

VALID_FIRMWARES="emac switch hsr prp"
outdir='ti-pruss'

# Firmware source path within the repositories
declare -A firmware_source
firmware_source["emac"]="$PDK/packages/ti/drv/icss_emac/firmware/icss_dualemac"
firmware_source["switch"]="$PDK/packages/ti/drv/icss_emac/firmware/icss_switch"
firmware_source["hsr"]="$ICSS_DEV/ti_internal/protocols/hsr_prp"
firmware_source["prp"]="$ICSS_DEV/ti_internal/protocols/hsr_prp"

# Firmware output paths in firmware repos
declare -A firmware_op
firmware_op["emac"]='elf/REV'
firmware_op["switch"]='elf/REV'
firmware_op["hsr"]='out/rev'
firmware_op["prp"]='out/rev'

# Firmware prefixes that are generated by firmware repos
declare -A firmware_prefix
firmware_prefix["emac"]='icss_dualemac_PRU'
firmware_prefix["switch"]='icss_stp_switch_PRU'
firmware_prefix["hsr"]='icss_hsr_pru'
firmware_prefix["prp"]='icss_prp_pru'

# SoCs corresponding to Firmware revisions
declare -A firmware_rev
firmware_rev[1]='am335x am437x'
firmware_rev[2]='am57xx k2g'

# Firmware postfixes that are expected by Linux
declare -A output_postfix
output_postfix["emac"]='-prueth-fw.elf'
output_postfix["switch"]='-prusw-fw.elf'
output_postfix["hsr"]='-pruhsr-fw.elf'
output_postfix["prp"]='-pruprp-fw.elf'

declare -A options_help
usage () {
	if [ -n "$*" ]; then
		echo "ERROR: $*"
	fi
	echo -n "Usage: $0 "
	for option in "${!options_help[@]}"
	do
		arg=`echo ${options_help[$option]}|cut -d ':' -f1`
		if [ -n "$arg" ]; then
			arg=" $arg"
		fi
		echo -n "[-$option$arg] "
	done
	echo
	echo -e "\nWhere:"
	for option in "${!options_help[@]}"
	do
		arg=`echo ${options_help[$option]}|cut -d ':' -f1`
		txt=`echo ${options_help[$option]}|cut -d ':' -f2`
		tb="\t\t\t"
		if [ -n "$arg" ]; then
			arg=" $arg"
			tb="\t"
		fi
		echo -e "   -$option$arg:$tb$txt"
	done
	echo
	echo "Examples of usage:-"
	echo "# Build dual emac firmware"
	echo "    $0 -f emac"
	echo "# Build switch firmware"
	echo "    $0 -f switch"
	echo "# Build hsr firmware"
	echo "    $0 -f hsr"
	echo "# Build prp firmware"
	echo "    $0 -f prp"
}

options_help[f]="firmware:Firmware to be built. Available firmware types are '$VALID_FIRMWARES'"
options_help[o]="output_directory:Output directory where firmware images are copied. Default dir is '$outdir'"

while getopts "f:o:h" opt
do
	case $opt in
	f)
		firmware=$OPTARG
	;;
	o)
		outdir=$OPTARG
	;;
	h)
		usage
		exit 0
	;;
	\?)
		usage "Invalid option '-$OPTARG'"
		exit 1
	;;
	:)
		usage "Option '-$OPTARG' Needs an argument."
		exit 1
	;;
	esac
done

# Valid firmware?
valid_firmware=0
for f in $VALID_FIRMWARES
do
	if [ "$f" == "$firmware" ]; then
		valid_firmware=1
	fi
done
if [ $valid_firmware == 0 ]; then
	usage "Invalid firmware name $firmware"
	exit 1
fi

mkdir -p $outdir

# Build firmware.
( cd ${firmware_source["$firmware"]} ; make clean ; make )
# ToDo: Check if build is successful.
echo
echo "-----------------------------------------"
echo " $firmware Firmware is built successfully"
echo "-----------------------------------------"
echo " Copying Firmware images to $outdir"
echo "-----------------------------------------"

# For each firmware revision
for v in ${!firmware_rev[@]}
do
	# for each SoC
	for soc in ${firmware_rev[$v]}
	do
		# for each PRU instance
		for i in 0 1
		do
			cp -vf ${firmware_source[$firmware]}/${firmware_op[$firmware]}$v/${firmware_prefix[$firmware]}$i.elf $outdir/$soc-pru$i${output_postfix[$firmware]}
		done
	done
done
