#!/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 TEMPLATE		""
default_var CPU			"max"
default_var SMP			4
default_var RAM			512
default_var GIC			3
default_var GDB			0
default_var KVM_PROTECTED	1
default_var VERBOSE		0
default_var KEEP_TEMP		0
default_var TIMEOUT		""

KiB=1024
MiB=$((1024 * KiB))
GiB=$((1024 * MiB))

function usage() {
	cat <<EOF

Usage: $0 [-h] [-v] [-K]
       [-e QEMU] [-L ROM_DIR] [-k KERNEL] [-r ROOTFS] [-R DRIVE] [-T TEMPLATE]
       [-c CPU] [-s NUM_CPUS] [-m MEM] [-g GIC] [-G] [-N]
       [-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
    -T    VM template image
    -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
    -N    disable protected KVM configuration
    -t    kill QEMU after given number of seconds
    -K    keep temp files
EOF
}

# Note: Due to a bug in older versions of Bash, use '${array[@]+"${array[@]}"}'
# to expand potentially empty arrays. '${array[@]}' is treated as undefined.
TMP_FILES=()
function cleanup() {
	rm -f ${TMP_FILES[@]+"${TMP_FILES[@]}"}
}

function file_size() {
	stat --format=%s "$1"
}

function align_up_pow2() {
	local val="$1"
	local align="$2"
	echo $(( (val + (align - 1)) & (~(align - 1)) ))
}

function hex() {
	printf '0x%x\n' $1
}

function template_overlay() {
	local in="$1"
	local out="$2"
	local tmp="$3"
	local addr="$4"
	local size="$5"

	# Convert input DTB back to source.
	dtc -I dtb -O dts -o "${tmp}" "${in}"

	# Append an overlay describing the template.
	cat <<EOF >> "${tmp}"
&{/} {
	pkvm_template@${addr} {
		compatible = "pkvm,arm64";
		#address-cells = <2>;
		#size-cells = <1>;
		reg = <0x00 ${addr} ${size}>;
	};
};
EOF

	# Compile back to DTB.
	dtc -I dts -O dtb -o "${out}" "${tmp}"
}

CMD=()
APPEND=()
EXTRA_RO_MOUNTS=()

while getopts ":e:L:k:r:R:T:c:s:m:g:t:vGNKh" OPT; do
	case "${OPT}" in
	e)	QEMU="${OPTARG}"		;;
	L)	ROM_DIR="${OPTARG}"		;;
	k)	KERNEL="${OPTARG}"		;;
	r)	ROOTFS="${OPTARG}"		;;
	R)	EXTRA_RO_MOUNTS+=("${OPTARG}")	;;
	T)	TEMPLATE="${OPTARG}"		;;
	c)	CPU="${OPTARG}"			;;
	s)	SMP="${OPTARG}"			;;
	m)	RAM="${OPTARG}"			;;
	g)	GIC="${OPTARG}"			;;
	t)	TIMEOUT="${OPTARG}"		;;
	v)	VERBOSE=1			;;
	G)	GDB=1				;;
	N)	KVM_PROTECTED=0			;;
	K)	KEEP_TEMP=1			;;
	h)
		usage
		exit 0
		;;
	\?)
		echo "Invalid option: -${OPTARG}" 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 [ "${KEEP_TEMP}" -ne 1 ]; then
	trap cleanup EXIT
fi

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

CMD+=("${QEMU}")
CMD+=(-M virt)
CMD+=(-machine virtualization=true -machine virt,gic-version=${GIC})
CMD+=(-cpu "${CPU}")
CMD+=(-smp "${SMP}")
CMD+=(-m "${RAM}")
CMD+=(-L "${ROM_DIR}")
CMD+=(-kernel "${KERNEL}")
CMD+=(-drive file="${ROOTFS}",readonly,if=virtio,format=raw)
CMD+=(-object rng-random,filename=/dev/urandom,id=rng0)
CMD+=(-device virtio-rng-pci,rng=rng0)
CMD+=(-nographic -nodefaults -serial stdio)

APPEND+=(rootwait root=/dev/vda)

# Note: Due to a bug in older versions of Bash, use '${array[@]+"${array[@]}"}'
# to expand potentially empty arrays. '${array[@]}' is treated as undefined.
for MOUNT in ${EXTRA_RO_MOUNTS[@]+"${EXTRA_RO_MOUNTS[@]}"}; do
	CMD+=(-drive "file=${MOUNT},readonly,if=virtio,format=raw")
done

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

if [ "${KVM_PROTECTED}" -eq 1 ]; then
	APPEND+=(kvm-arm.mode=protected)
fi

CMD+=(-append "${APPEND[*]}")

if [ -n "${TEMPLATE}" ]; then
	QEMU_DTB="$(mktemp)"
	QEMU_PATCHED_DTB="$(mktemp)"
	TMP_DTS="$(mktemp)"

	# Mark files for deletion on EXIT.
	TMP_FILES+=("${QEMU_DTB}" "${QEMU_PATCHED_DTB}" "${TMP_DTS}")

	# Dump the QEMU DTB.
	"${CMD[@]}" -machine dumpdtb="${QEMU_DTB}" > /dev/null

	# Compile the overlayed DTB with dummy values to determine its size.
	template_overlay "${QEMU_DTB}" "${QEMU_PATCHED_DTB}" "${TMP_DTS}" 0x0 0x0
	TMP_DTB_SIZE=$(file_size "${QEMU_PATCHED_DTB}")

	# From QEMU's hw/arm/boot.c:
	# RAM always starts at 1GiB PA offset. The kernel is placed there.
	# 128MiB (or RAM/2 if RAM<256MiB) is left to the kernel to decompress.
	# This is followed by the ramdisk and then 2MiB-aligned DTB.
	# We place the template at the following page (assume 64KiB page size).
	TEMPLATE_ADDR=$(( 1*GiB + 128*MiB + TMP_DTB_SIZE ))
	TEMPLATE_ADDR=$(hex $(align_up_pow2 $TEMPLATE_ADDR 64*KiB))
	TEMPLATE_SIZE=$(hex $(file_size "${TEMPLATE}"))

	template_overlay "${QEMU_DTB}" "${QEMU_PATCHED_DTB}" "${TMP_DTS}" \
			 "${TEMPLATE_ADDR}" "${TEMPLATE_SIZE}"

	CMD+=(-dtb "${QEMU_PATCHED_DTB}")
	CMD+=(-device loader,file="${TEMPLATE}",addr=${TEMPLATE_ADDR},force-raw=true)
fi

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

# Invoke QEMU and then propagate its exit code.
# We do this instead of `exec` to delete TMP_FILES in the EXIT handler.
set +e; "${CMD[@]}"; exit $?
