#!/bin/sh

# Build a BlueField bootstream file to boot off a disk that has
# the disk.img file burned into it (or boot.img, if used with --no-gpt).
# By default assume we are running in the directory where the script lives.

set -e

usage ()
{
    echo "syntax: build-bfb [--bfb INPUT_BFBFILE] [--kernel IMAGE] \\"
    echo "  [--root ROOTPATH] [--bootarg BOOTARG] [--bootdesc BOOTDESC] \\"
    echo "  [--initramfs INITRAMFS] [--uart 0|1|rshim|all] [--sys SYSTEM] \\"
    echo "  [--no-gpt] [-i]  rshim|mmc0|nvme0 OUTPUT"
}

bfb=
kernel=Image
initramfs=initramfs
use_initramfs=
verbose=
gpt=1
kernelargs=
root=
uart=
sys=

options=`getopt -n build-bfb -o ivh \
        -l help,kernel:,initramfs:,bfb:,verbose,no-gpt,bootdesc:,bootarg:,sys:,uart:,root: -- "$@"`
eval set -- $options
while [ "$1" != -- ]; do
    case $1 in
        --help|-h) usage; exit 0 ;;
        --kernel) shift; kernel=$1 ;;
        --initramfs) shift; initramfs=$1 ;;
        -i) use_initramfs=1 ;;
        --bfb) shift; bfb=$1 ;;
        --verbose|-v) verbose=1 ;;
        --no-gpt) gpt= ;;
        --bootdesc) shift; bootdesc="$1" ;;
        --bootarg) shift; kernelargs="$kernelargs $1" ;;
        --uart) shift; uart="$1" ;;
        --sys) shift; sys="$1" ;;
        --root) shift; root=$1 ;;
    esac
    shift
done
shift

if [ $# -ne 2 ]; then
    usage >&2
    exit 1
fi
device=$1
output=$2

if [ -z "$bfb" ]; then
    if [ -z "$sys" ]; then
        echo "build-bfb: must specify system or provide bfb" >&2
        exit 1
    else
        bfb=../boot/default.bfb
    fi
fi

if [ -z "$uart" ]; then
    case $sys in
        MBE1x0x)
            # Use UART 1 for Bluewhale
            uart="1"
            ;;
        sim)
            uart="0"
            use_initramfs=1
            gpt=
            ;;
        hw)
            uart="all"
            ;;
        *)
            uart="0"
            ;;
    esac
fi

case $device in
    mmc0)
        bootdesc=${bootdesc:-"Linux from mmc0"}
        uefidev="VenHw(8C91E049-9BF9-440E-BBAD-7DC5FC082C02)"
        linuxdev=mmcblk0
        ;;
    nvme0)
        bootdesc=${bootdesc:-"Linux from nvme0"}
        uefidev="PciRoot(0x0)/Pci(0x0,0x0)/Pci(0x0,0x0)/Pci(0x0,0x0)/Pci(0x0,0x0)/Pci(0x0,0x0)/Pci(0x0,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)"
        linuxdev=nvme0n1
        ;;
    rshim)
        bootdesc=${bootdesc:-"Linux from rshim"}
        if [ -n "$gpt" ]; then
            echo "build-bfb: using device 'rshim' requires --no-gpt" >&2
            exit 1
        fi
        extra_mkbootargs="--image $kernel"
        if [ -n "$use_initramfs" ]; then
            extra_mkbootargs="$extra_mkbootargs --initramfs $initramfs"
        fi
        uefidev="VenHw(F019E406-8C9C-11E5-8797-001ACA00BFC4)"
        ;;
    *)
        echo "build-bfb: must specify device as rshim, mmc0, or nvme0" >&2
        exit 1
        ;;
esac

if [ -n "$use_initramfs" ]; then
    # Ignore the root partition
    kernelargs="$kernelargs initrd=initramfs"
else
    if [ -z "$root" ]; then
        # If no root specified for a GPT boot, assume root is 2nd partition
        if [ -n "$gpt" ]; then
            root="/dev/${linuxdev}p2"
        else
            echo "build-bfb --no-gpt: must specify --root or -i" >&2
            exit 1
        fi
    fi
    # Ignore the initramfs in the boot partition
    kernelargs="$kernelargs root=$root rootwait"
fi

if [ -n "$gpt" ]; then
    # Note that we assume the partition table generated in build-image.
    kernelpath="$uefidev/HD(1,GPT,3DCADB7E-BCCC-4897-A766-3C070EDD7C25,0x800,0xAE800)/Image"
else
    kernelpath="$uefidev/Image"
fi

if [ ."$uart" = ."0" ]; then
    consolearg="console=ttyAMA0 earlycon=pl011,0x01000000"
elif [ ."$uart" = ."1" ]; then
    consolearg="console=ttyAMA1 earlycon=pl011,0x01800000"
elif [ ."$uart" = ."rshim" ]; then
    consolearg="console=hvc0"
elif [ ."$uart" = ."all" ]; then
    consolearg="console=ttyAMA1 console=hvc0 console=ttyAMA0 earlycon=pl011,0x01000000 earlycon=pl011,0x01800000"
else
    echo "build-bfb --uart: UART must be 0, 1, rshim or all" >&2
    exit 1
fi

if [ -n "$verbose" ]; then
    echo "boot desc: $bootdesc"
    echo "boot path: $kernelpath"
    echo "boot args: $consolearg $kernelargs"
    if [ -n "$extra_mkbootargs" ]; then
        echo "extra tile-mkboot args: $extra_mkbootargs"
    fi
fi

mlx-mkbfb --boot-desc "=$bootdesc" --boot-path "=$kernelpath" \
        --boot-args "=$consolearg $kernelargs" \
    $extra_mkbootargs $bfb $output.tmp
mv -f $output.tmp $output
