1#!/usr/bin/env bash
2
3DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4
5# host operating system
6readonly HOST_OS=$(uname -s)
7
8# host architecture
9HOST_OS_ARCH=$(uname -m)
10case $HOST_OS_ARCH in
11  aarch64*|arm64)
12    # flatten either aarch64 or arm64 to arm64 to keep it simple
13    readonly HOST_ARCH="arm64"
14    ;;
15  *)
16    readonly HOST_ARCH
17    ;;
18esac
19
20#echo HOST_OS = $HOST_OS
21#echo HOST_OS_ARCH = $HOST_OS_ARCH
22
23function HELP {
24    echo "help:"
25    echo "-6                : 64bit arm"
26    echo "-3                : cortex-m3 based platform"
27    echo "-v                : boot kernel at EL2"
28    echo "-k                : use KVM or HVF acceleration if present (only on 64bit)"
29    echo "-m <memory in MB>"
30    echo "-s <number of cpus>"
31    echo
32    echo "-c                : cmpctmalloc instead of dlmalloc"
33    echo "-M                : miniheap instead of dlmalloc"
34    echo
35    echo "-d <disk image>   : a virtio disk device"
36    echo "-n                : a virtio network device"
37    echo "-t                : a virtio tap network device"
38    echo "-g                : a virtio display"
39    echo "-f <shared dir>   : a virtio 9p device with a host shared directory"
40    echo
41    echo "-h for help"
42    echo "all arguments after -- are passed to qemu directly"
43    exit 1
44}
45
46DO_NET=0
47DO_NET_TAP=0
48DO_DISK=0
49DO_DISK_IMAGE=""
50DO_64BIT=0
51DO_VIRT=0
52DO_CORTEX_M3=0
53DO_KVM=0
54DO_DISPLAY=0
55DO_CMPCTMALLOC=0
56DO_MINIHEAP=0
57DO_V9P=0
58DO_V9P_DIR=""
59SMP=1
60MEMSIZE=512
61SUDO=""
62PROJECT=""
63
64while getopts cd:ghkm:Mnt36vp:s:f: FLAG; do
65    case $FLAG in
66        c) DO_CMPCTMALLOC=1;;
67        d) DO_DISK=1; DISK_IMAGE=$OPTARG;;
68        g) DO_DISPLAY=1;;
69        f) DO_V9P=1; DO_V9P_DIR=$OPTARG;;
70        k) DO_KVM=1;;
71        M) DO_MINIHEAP=1;;
72        n) DO_NET=1;;
73        t) DO_NET_TAP=1;;
74        3) DO_CORTEX_M3=1;;
75        6) DO_64BIT=1;;
76        v) DO_VIRT=1;;
77        m) MEMSIZE=$OPTARG;;
78        s) SMP=$OPTARG;;
79        p) PROJECT=$OPTARG;;
80        h) HELP;;
81        \?)
82            echo unrecognized option
83            HELP
84    esac
85done
86
87shift $((OPTIND-1))
88
89# pick the appropriate qemu and project
90if [ $DO_64BIT == 1 ]; then
91    QEMU="qemu-system-aarch64"
92    CPU="cortex-a53"
93    MACHINE="virt"
94    if [ $DO_KVM == 1 ]; then
95        CPU="host"
96        if [ $HOST_OS == "Darwin" ]; then
97            MACHINE+=",gic_version=2,accel=hvf"
98        elif [ $HOST_OS == "Linux" ]; then
99            MACHINE+=",gic_version=host,accel=kvm"
100        fi
101    elif [ $DO_VIRT == 1 ]; then
102        MACHINE+=",virtualization=on"
103    fi
104    _PROJECT="qemu-virt-arm64-test"
105elif [ $DO_CORTEX_M3 == 1 ]; then
106    QEMU="qemu-system-arm"
107    CPU="cortex-m3"
108    MACHINE="lm3s6965evb"
109    _PROJECT="lm3s6965evb-test"
110else
111    QEMU="qemu-system-arm"
112    CPU="cortex-a15"
113    MACHINE="virt"
114    MACHINE+=",highmem=off" # disable the high PCI ECAM, since we dont support LPAE to map it
115    _PROJECT="qemu-virt-arm32-test"
116fi
117
118# allow overriding the project from the environment
119if [ "$PROJECT" == "" ]; then
120    PROJECT=$_PROJECT
121fi
122
123ARGS=" -cpu $CPU -m $MEMSIZE -smp $SMP -machine $MACHINE -kernel build-${PROJECT}/lk.elf"
124
125if (( $DO_DISK )); then
126    ARGS+=" -drive if=none,file=${DISK_IMAGE},id=blk,format=raw"
127    ARGS+=" -device virtio-blk-device,drive=blk"
128fi
129
130if (( $DO_NET )); then
131    ARGS+=" -netdev user,id=vmnic,hostname=qemu "
132    ARGS+=" -device virtio-net-device,netdev=vmnic"
133elif (( $DO_NET_TAP )); then
134    # quick note to enable tap interface
135    # IFNAME=qemu0
136    # BRIDGE=bridge0
137    # sudo tunctl -u $(whoami) -t ${IFNAME}
138    # sudo ifconfig ${IFNAME} up
139    # sudo ip link set ${IFNAME} master ${BRIDGE}
140    ARGS+=" -netdev tap,id=vmnic,ifname=qemu0,script=no,downscript=no"
141    ARGS+=" -device virtio-net-device,netdev=vmnic"
142    #SUDO="sudo "
143else
144    NO_NET_ARGS=" -net none"
145    ARGS+=$NO_NET_ARGS
146fi
147
148if (( $DO_DISPLAY )); then
149    ARGS+=" -device virtio-gpu-device -serial stdio"
150    ARGS+=" -device virtio-keyboard-device"
151    ARGS+=" -device virtio-mouse-device"
152else
153    ARGS+=" -nographic"
154fi
155
156if (( $DO_V9P )); then
157    ARGS+=" -fsdev local,path=$DO_V9P_DIR,security_model=mapped,id=v9p0"
158    ARGS+=" -device virtio-9p-device,fsdev=v9p0,mount_tag=V9P0"
159fi
160
161MAKE_VARS=""
162
163if (( $DO_CMPCTMALLOC )); then
164    MAKE_VARS=LK_HEAP_IMPLEMENTATION=cmpctmalloc
165elif (( $DO_MINIHEAP )); then
166    MAKE_VARS=LK_HEAP_IMPLEMENTATION=miniheap
167fi
168
169$DIR/make-parallel $MAKE_VARS $PROJECT &&
170echo $SUDO $QEMU $ARGS $@ &&
171$SUDO $QEMU $ARGS $@
172