#!/bin/sh
#
# This software is a part of ISAR.
# Copyright (C) 2015-2017 ilbers GmbH

set -e

ES_OK=0
ES_BUG=3

# Convert bitbake assignments to shell ones
# a = b         a=b
# a ?= b        a=b
# TODO: Use bitbake to parse vars correctly (overriding in local.conf, etc.)
bb2sh() {
    sed 's/[[:space:]]*?*=[[:space:]]*/=/'
}

start_qemu() {
    root=`echo $QEMU_DISK_ARGS \
        | sed 's,##ROOTFS_IMAGE##,'$IMAGE_DIR/$ROOTFS_IMAGE','`
    local had_x
    echo $- | grep -q x && had_x=1 || had_x=0
    [ $had_x -eq 0 ] && set -x
    qemu-system-$QEMU_ARCH \
	-m 1024M \
	-M $QEMU_MACHINE \
	$QCPU \
	-nographic \
	$EXTRA_ARGS \
        -append "$KARGS$EXTRA_KARGS" \
	$root
    [ $had_x -eq 0 ] && set +x
}

show_help() {
    echo "This script runs ISAR image in QEMU emulator."
    echo
    echo "Usage:"
    echo "    $0 [params] [BUILD_DIR]"
    echo "BUILD_DIR is your ISAR build folder. If not set, current folder"
    echo "is used."
    echo
    echo "Parameters:"
    echo "    -a, --arch ARCH       set isar machine architecture."
    echo "                          Supported: arm, i386, amd64, arm64, mipsel, riscv64."
    echo "    -b, --build BUILD     set path to build directory."
    echo "    -d, --distro DISTRO   set isar Debian distribution."
    echo "                          Supported: stretch, buster"
    echo "    -o, --out FILE        Route QEMU console output to"
    echo "                          specified file."
    echo "    -p, --pid FILE        Store QEMU pid to file."
    echo "    --help                display this message and exit."
    echo
    echo "Exit status:"
    echo " 0  if OK,"
    echo " 3  if invalid parameters are passed."
}

# Set default values, that can be overwritten from command line
ARCH=arm
DISTRO=buster
BUILD_DIR=$PWD

# Parse command line to get user configuration
while [ $# -gt 0 ]
do
    key="$1"

    case $key in
    -h|--help)
        show_help
        exit 0
        ;;
    -a|--arch)
        ARCH=$2
        shift
        ;;
    -b|--build)
        BUILD_DIR=$2
        shift
        ;;
    -d|--distro)
        DISTRO=$2
        shift
        ;;
    -o|--out)
        EXTRA_ARGS="$EXTRA_ARGS -serial file:$2"
        shift
        ;;
    -p|--pid)
        EXTRA_ARGS="$EXTRA_ARGS -pidfile $2"
        shift
        ;;
    *)
        echo "error: invalid parameter '$key', please try '--help' to get list of supported parameters"
        exit $ES_BUG
        ;;
    esac

    shift
done

eval $(bitbake -e mc:qemu$ARCH-$DISTRO:isar-image-base | grep "^DEPLOY_DIR_IMAGE=")
readonly IMAGE_DIR=$DEPLOY_DIR_IMAGE

readonly ISARROOT="$(dirname "$0")"/..

readonly MACHINE_CONF=$ISARROOT/meta-isar/conf/machine/qemu$ARCH.conf
eval "$(egrep 'MACHINE_SERIAL|QEMU_' $MACHINE_CONF |bb2sh)"

eval $(bitbake -e mc:qemu$ARCH-$DISTRO:isar-image-base | grep "\(^IMAGE_FSTYPES=\|^IMAGE_FULLNAME=\)")
# Take first image type for VM if there are several defined
IMAGE_FSTYPES=$(echo "$IMAGE_FSTYPES" | awk '{print $1}')
case "$IMAGE_FSTYPES" in
    ext4-img)
    readonly ROOTFS_IMAGE=$IMAGE_FULLNAME.ext4.img

    eval $(bitbake -e mc:qemu$ARCH-$DISTRO:isar-image-base | grep "^KERNEL_IMAGE=")
    eval $(bitbake -e mc:qemu$ARCH-$DISTRO:isar-image-base | grep "^INITRD_IMAGE=")
    QKERNEL=$IMAGE_DIR/${KERNEL_IMAGE}
    QINITRD=/dev/null
    [ -n "$INITRD_IMAGE" ] && QINITRD=$IMAGE_DIR/${INITRD_IMAGE}
    if [ "$ARCH" = "riscv64" ]; then
        EXTRA_ARGS="$EXTRA_ARGS -device loader,file=$QKERNEL,addr=0x80200000"
        QKERNEL="/usr/lib/riscv64-linux-gnu/opensbi/qemu/virt/fw_jump.elf"
    fi
    EXTRA_ARGS="$EXTRA_ARGS \
	-kernel $QKERNEL \
	-initrd $QINITRD"
    KARGS="console=$MACHINE_SERIAL root=/dev/$QEMU_ROOTFS_DEV rw $QEMU_KARGS"
    ;;
    wic-img)
    readonly ROOTFS_IMAGE=$IMAGE_FULLNAME.wic.img
    EXTRA_ARGS="$EXTRA_ARGS -snapshot"
    ;;
    *)
    echo "IMAGE_FSTYPES \"$IMAGE_FSTYPES\" not supported"
    exit 1
    ;;
esac

QCPU=
[ -n "$QEMU_CPU" ] && QCPU="-cpu $QEMU_CPU"

start_qemu

exit $ES_OK
