113336606SRobert Foley#!/usr/bin/env python3 213336606SRobert Foley# 313336606SRobert Foley# VM testing aarch64 library 413336606SRobert Foley# 513336606SRobert Foley# Copyright 2020 Linaro 613336606SRobert Foley# 713336606SRobert Foley# Authors: 813336606SRobert Foley# Robert Foley <robert.foley@linaro.org> 913336606SRobert Foley# 1013336606SRobert Foley# This code is licensed under the GPL version 2 or later. See 1113336606SRobert Foley# the COPYING file in the top-level directory. 1213336606SRobert Foley# 1313336606SRobert Foleyimport os 1413336606SRobert Foleyimport sys 1513336606SRobert Foleyimport subprocess 1613336606SRobert Foleyimport basevm 17*beb6b57bSJohn Snowfrom qemu.utils import kvm_available 1813336606SRobert Foley 1913336606SRobert Foley# This is the config needed for current version of QEMU. 2013336606SRobert Foley# This works for both kvm and tcg. 2113336606SRobert FoleyCURRENT_CONFIG = { 2213336606SRobert Foley 'cpu' : "max", 2313336606SRobert Foley 'machine' : "virt,gic-version=max", 2413336606SRobert Foley} 2513336606SRobert Foley 2613336606SRobert Foley# The minimum minor version of QEMU we will support with aarch64 VMs is 3. 2713336606SRobert Foley# QEMU versions less than 3 have various issues running these VMs. 2813336606SRobert FoleyQEMU_AARCH64_MIN_VERSION = 3 2913336606SRobert Foley 3013336606SRobert Foley# The DEFAULT_CONFIG will default to a version of 3113336606SRobert Foley# parameters that works for backwards compatibility. 3213336606SRobert FoleyDEFAULT_CONFIG = {'kvm' : {'cpu' : "host", 3313336606SRobert Foley 'machine' : "virt,gic-version=host"}, 3413336606SRobert Foley 'tcg' : {'cpu' : "cortex-a57", 3513336606SRobert Foley 'machine' : "virt"}, 3613336606SRobert Foley} 3713336606SRobert Foley 3813336606SRobert Foleydef get_config_defaults(vmcls, default_config): 3913336606SRobert Foley """Fetch the configuration defaults for this VM, 4013336606SRobert Foley taking into consideration the defaults for 4113336606SRobert Foley aarch64 first, followed by the defaults for this VM.""" 4213336606SRobert Foley config = default_config 4313336606SRobert Foley config.update(aarch_get_config_defaults(vmcls)) 4413336606SRobert Foley return config 4513336606SRobert Foley 4613336606SRobert Foleydef aarch_get_config_defaults(vmcls): 4713336606SRobert Foley """Set the defaults for current version of QEMU.""" 4813336606SRobert Foley config = CURRENT_CONFIG 492fea3a12SAlex Bennée args = basevm.parse_args(vmcls) 5013336606SRobert Foley qemu_path = basevm.get_qemu_path(vmcls.arch, args.build_path) 5113336606SRobert Foley qemu_version = basevm.get_qemu_version(qemu_path) 5213336606SRobert Foley if qemu_version < QEMU_AARCH64_MIN_VERSION: 5313336606SRobert Foley error = "\nThis major version of QEMU {} is to old for aarch64 VMs.\n"\ 5413336606SRobert Foley "The major version must be at least {}.\n"\ 5513336606SRobert Foley "To continue with the current build of QEMU, "\ 5613336606SRobert Foley "please restart with QEMU_LOCAL=1 .\n" 5713336606SRobert Foley print(error.format(qemu_version, QEMU_AARCH64_MIN_VERSION)) 5813336606SRobert Foley exit(1) 5913336606SRobert Foley if qemu_version == QEMU_AARCH64_MIN_VERSION: 6013336606SRobert Foley # We have an older version of QEMU, 6113336606SRobert Foley # set the config values for backwards compatibility. 6213336606SRobert Foley if kvm_available('aarch64'): 6313336606SRobert Foley config.update(DEFAULT_CONFIG['kvm']) 6413336606SRobert Foley else: 6513336606SRobert Foley config.update(DEFAULT_CONFIG['tcg']) 6613336606SRobert Foley return config 6713336606SRobert Foley 6813336606SRobert Foleydef create_flash_images(flash_dir="./", efi_img=""): 6913336606SRobert Foley """Creates the appropriate pflash files 7013336606SRobert Foley for an aarch64 VM.""" 7113336606SRobert Foley flash0_path = get_flash_path(flash_dir, "flash0") 7213336606SRobert Foley flash1_path = get_flash_path(flash_dir, "flash1") 7313336606SRobert Foley fd_null = open(os.devnull, 'w') 7413336606SRobert Foley subprocess.check_call(["dd", "if=/dev/zero", "of={}".format(flash0_path), 7513336606SRobert Foley "bs=1M", "count=64"], 7613336606SRobert Foley stdout=fd_null, stderr=subprocess.STDOUT) 7713336606SRobert Foley # A reliable way to get the QEMU EFI image is via an installed package or 7813336606SRobert Foley # via the bios included with qemu. 7913336606SRobert Foley if not os.path.exists(efi_img): 8013336606SRobert Foley sys.stderr.write("*** efi argument is invalid ({})\n".format(efi_img)) 8113336606SRobert Foley sys.stderr.write("*** please check --efi-aarch64 argument or "\ 8213336606SRobert Foley "install qemu-efi-aarch64 package\n") 8313336606SRobert Foley exit(3) 8413336606SRobert Foley subprocess.check_call(["dd", "if={}".format(efi_img), 8513336606SRobert Foley "of={}".format(flash0_path), 8613336606SRobert Foley "conv=notrunc"], 8713336606SRobert Foley stdout=fd_null, stderr=subprocess.STDOUT) 8813336606SRobert Foley subprocess.check_call(["dd", "if=/dev/zero", 8913336606SRobert Foley "of={}".format(flash1_path), 9013336606SRobert Foley "bs=1M", "count=64"], 9113336606SRobert Foley stdout=fd_null, stderr=subprocess.STDOUT) 9213336606SRobert Foley fd_null.close() 9313336606SRobert Foley 9413336606SRobert Foleydef get_pflash_args(flash_dir="./"): 9513336606SRobert Foley """Returns a string that can be used to 9613336606SRobert Foley boot qemu using the appropriate pflash files 9713336606SRobert Foley for aarch64.""" 9813336606SRobert Foley flash0_path = get_flash_path(flash_dir, "flash0") 9913336606SRobert Foley flash1_path = get_flash_path(flash_dir, "flash1") 10013336606SRobert Foley pflash_args_str = "-drive file={},format=raw,if=pflash "\ 10113336606SRobert Foley "-drive file={},format=raw,if=pflash" 10213336606SRobert Foley pflash_args = pflash_args_str.format(flash0_path, flash1_path) 10313336606SRobert Foley return pflash_args.split(" ") 10413336606SRobert Foley 10513336606SRobert Foleydef get_flash_path(flash_dir, name): 10613336606SRobert Foley return os.path.join(flash_dir, "{}.img".format(name)) 107