#!/usr/bin/env bash

# Copyright 2020 The Android KVM Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

source "$(dirname "${BASH_SOURCE[0]}")/../common.inc"

default_var QEMU	"${PREBUILTS_QEMU_BIN}"
default_var ROM_DIR	"${PREBUILTS_QEMU_ROM_DIR}"
default_var KERNEL	"${LINUX_OUT_IMAGE}"
default_var ROOTFS	"${PREBUILTS_KUT_ROOTFS}"
default_var CPU		"max"
default_var SMP		2
default_var RAM		512
default_var GIC		3
default_var GDB		0
default_var VERBOSE	0
default_var TIMEOUT	""

function usage() {
	cat <<EOF

Usage: $0 [-h] [-v]
       [-e QEMU] [-L ROM_DIR] [-k KERNEL] [-r ROOTFS] [-R DRIVE]
       [-c CPU] [-s NUM_CPUS] [-m MEM] [-g GIC] [-G]
       [-t TIMEOUT]

    -h    output this help text
    -v    print invoked command
    -e    QEMU emulator binary
    -L    directory where QEMU should look for BIOS image
    -k    kernel image
    -r    root filesystem image
    -R    additional drive image(s) to mount as read-only
    -c    CPU model (defaults to "${DEFAULT_CPU}")
    -s    number of CPU cores (defaults to ${DEFAULT_SMP})
    -m    amount of memory in MB (defaults to ${DEFAULT_RAM})
    -g    version of GIC (defaults to ${DEFAULT_GIC})
    -G    enable debugging of emulated system with GDB
    -t    kill QEMU after given number of seconds
EOF
}

CMD=()
EXTRA_ARGS=()
EXTRA_RO_MOUNTS=()

while getopts ":e:L:k:r:R:c:s:m:g:t:vGh" OPT; do
	case "${OPT}" in
	e)	QEMU="${OPTARG}"		;;
	L)	ROM_DIR="${OPTARG}"		;;
	k)	KERNEL="${OPTARG}"		;;
	r)	ROOTFS="${OPTARG}"		;;
	R)	EXTRA_RO_MOUNTS+=("${OPTARG}")	;;
	c)	CPU="${OPTARG}"			;;
	s)	SMP="${OPTARG}"			;;
	m)	RAM="${OPTARG}"			;;
	g)	GIC="${OPTARG}"			;;
	t)	TIMEOUT="${OPTARG}"		;;
	v)	VERBOSE=1			;;
	G)	GDB=1				;;
	h)
		usage
		exit 0
		;;
	\?)
		echo "Invalid option: ${!OPTIND}" 1>&2
		usage 1>&2
		exit 1
		;;
	:)
		echo "Invalid option: -${OPTARG} requires an argument" 1>&2
		usage 1>&2
		exit 1
		;;
    esac
done
shift $((OPTIND -1))
if [ $# -ne 0 ]; then
	echo "Unrecognized options: $@" 1>&2
	usage 1>&2
	exit 1
fi

if [ "${TIMEOUT}" != "" ]; then
	CMD+=(timeout -k 1s --foreground "${TIMEOUT}")
fi
CMD+=("${QEMU}")

for MOUNT in "${EXTRA_RO_MOUNTS[@]}"; do
	EXTRA_ARGS+=(-drive "file=${MOUNT},readonly,if=virtio,format=raw")
done

if [ "${GDB}" -eq 1 ]; then
	EXTRA_ARGS+=(-S -s)
fi

if [ "${VERBOSE}" -eq 1 ]; then
	set -x
fi

exec "${CMD[@]}"							\
	-M virt								\
	-machine virtualization=true -machine virt,gic-version=${GIC}	\
	-cpu "${CPU}" -smp "${SMP}" -m "${RAM}"				\
	-L "${ROM_DIR}" -kernel "${KERNEL}"				\
	-drive file="${ROOTFS}",readonly,if=virtio,format=raw		\
	-object rng-random,filename=/dev/urandom,id=rng0		\
	-device virtio-rng-pci,rng=rng0					\
	-nographic -nodefaults -serial stdio				\
	-append "rootwait root=/dev/vda"				\
	"${EXTRA_ARGS[@]}"						\
