qemu/tests/vm/aarch64vm.py
<<
>>
Prefs
   1#!/usr/bin/env python3
   2#
   3# VM testing aarch64 library
   4#
   5# Copyright 2020 Linaro
   6#
   7# Authors:
   8#  Robert Foley <robert.foley@linaro.org>
   9#
  10# This code is licensed under the GPL version 2 or later.  See
  11# the COPYING file in the top-level directory.
  12#
  13import os
  14import sys
  15import subprocess
  16import basevm
  17from qemu.utils import kvm_available
  18
  19# This is the config needed for current version of QEMU.
  20# This works for both kvm and tcg.
  21CURRENT_CONFIG = {
  22    'cpu'          : "max",
  23    'machine'      : "virt,gic-version=max",
  24}
  25
  26# The minimum minor version of QEMU we will support with aarch64 VMs is 3.
  27# QEMU versions less than 3 have various issues running these VMs.
  28QEMU_AARCH64_MIN_VERSION = 3
  29
  30# The DEFAULT_CONFIG will default to a version of
  31# parameters that works for backwards compatibility.
  32DEFAULT_CONFIG = {'kvm' : {'cpu'          : "host",
  33                           'machine'      : "virt,gic-version=host"},
  34                  'tcg' : {'cpu'          : "cortex-a57",
  35                           'machine'      : "virt"},
  36}
  37
  38def get_config_defaults(vmcls, default_config):
  39    """Fetch the configuration defaults for this VM,
  40       taking into consideration the defaults for
  41       aarch64 first, followed by the defaults for this VM."""
  42    config = default_config
  43    config.update(aarch_get_config_defaults(vmcls))
  44    return config
  45
  46def aarch_get_config_defaults(vmcls):
  47    """Set the defaults for current version of QEMU."""
  48    config = CURRENT_CONFIG
  49    args = basevm.parse_args(vmcls)
  50    qemu_path = basevm.get_qemu_path(vmcls.arch, args.build_path)
  51    qemu_version = basevm.get_qemu_version(qemu_path)
  52    if qemu_version < QEMU_AARCH64_MIN_VERSION:
  53        error = "\nThis major version of QEMU {} is to old for aarch64 VMs.\n"\
  54                "The major version must be at least {}.\n"\
  55                "To continue with the current build of QEMU, "\
  56                "please restart with QEMU_LOCAL=1 .\n"
  57        print(error.format(qemu_version, QEMU_AARCH64_MIN_VERSION))
  58        exit(1)
  59    if qemu_version == QEMU_AARCH64_MIN_VERSION:
  60        # We have an older version of QEMU,
  61        # set the config values for backwards compatibility.
  62        if kvm_available('aarch64'):
  63            config.update(DEFAULT_CONFIG['kvm'])
  64        else:
  65            config.update(DEFAULT_CONFIG['tcg'])
  66    return config
  67
  68def create_flash_images(flash_dir="./", efi_img=""):
  69    """Creates the appropriate pflash files
  70       for an aarch64 VM."""
  71    flash0_path = get_flash_path(flash_dir, "flash0")
  72    flash1_path = get_flash_path(flash_dir, "flash1")
  73    fd_null = open(os.devnull, 'w')
  74    subprocess.check_call(["dd", "if=/dev/zero", "of={}".format(flash0_path),
  75                           "bs=1M", "count=64"],
  76                           stdout=fd_null, stderr=subprocess.STDOUT)
  77    # A reliable way to get the QEMU EFI image is via an installed package or
  78    # via the bios included with qemu.
  79    if not os.path.exists(efi_img):
  80        sys.stderr.write("*** efi argument is invalid ({})\n".format(efi_img))
  81        sys.stderr.write("*** please check --efi-aarch64 argument or "\
  82                         "install qemu-efi-aarch64 package\n")
  83        exit(3)
  84    subprocess.check_call(["dd", "if={}".format(efi_img),
  85                           "of={}".format(flash0_path),
  86                           "conv=notrunc"],
  87                           stdout=fd_null, stderr=subprocess.STDOUT)
  88    subprocess.check_call(["dd", "if=/dev/zero",
  89                           "of={}".format(flash1_path),
  90                           "bs=1M", "count=64"],
  91                           stdout=fd_null, stderr=subprocess.STDOUT)
  92    fd_null.close()
  93
  94def get_pflash_args(flash_dir="./"):
  95    """Returns a string that can be used to
  96       boot qemu using the appropriate pflash files
  97       for aarch64."""
  98    flash0_path = get_flash_path(flash_dir, "flash0")
  99    flash1_path = get_flash_path(flash_dir, "flash1")
 100    pflash_args_str = "-drive file={},format=raw,if=pflash "\
 101                      "-drive file={},format=raw,if=pflash"
 102    pflash_args = pflash_args_str.format(flash0_path, flash1_path)
 103    return pflash_args.split(" ")
 104
 105def get_flash_path(flash_dir, name):
 106    return os.path.join(flash_dir, "{}.img".format(name))
 107