blob: 35bd338c225678c47603783a1b95c52cc349bb1a [file] [log] [blame]
# -*- mode: python -*-
# qemu_helpers: Helpers to find QEMU and handle its quirks
# Copyright © 2014 Andy Lutomirski
# Licensed under the GPLv2, which is available in the virtme distribution
# as a file called LICENSE with SHA-256 hash:
# 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643
import os
class Arch(object):
def __init__(self, name):
self.virtmename = name
self.qemuname = name
self.linuxname = name
self.gccname = name
defconfig_target = 'defconfig'
@staticmethod
def serial_dev_name(index):
return 'ttyS%d' % index
@staticmethod
def qemuargs(is_native):
return []
@staticmethod
def virtio_dev_type(virtiotype):
# Return a full name for a virtio device. It would be
# nice if QEMU abstracted this away, but it doesn't.
return 'virtio-%s-pci' % virtiotype
@staticmethod
def earlyconsole_args():
return []
@staticmethod
def serial_console_args():
return []
@staticmethod
def qemu_nodisplay_args():
return ['-vga', 'none', '-display', 'none']
@staticmethod
def config_base():
return []
def kimg_path(self):
return 'arch/%s/boot/bzImage' % self.linuxname
@staticmethod
def dtb_path():
return None
class Arch_unknown(Arch):
@staticmethod
def qemuargs(is_native):
return Arch.qemuargs(is_native)
class Arch_x86(Arch):
def __init__(self, name):
Arch.__init__(self, name)
self.linuxname = 'x86'
self.defconfig_target = '%s_defconfig' % name
@staticmethod
def qemuargs(is_native):
ret = Arch.qemuargs(is_native)
# Add a watchdog. This is useful for testing.
ret.extend(['-watchdog', 'i6300esb'])
if is_native and os.access('/dev/kvm', os.R_OK):
# If we're likely to use KVM, request a full-featured CPU.
# (NB: if KVM fails, this will cause problems. We should probe.)
ret.extend(['-cpu', 'host']) # We can't migrate regardless.
return ret
@staticmethod
def earlyconsole_args():
return ['earlyprintk=serial,ttyS0,115200']
@staticmethod
def serial_console_args():
return ['console=ttyS0']
@staticmethod
def config_base():
return ['CONFIG_SERIO=y',
'CONFIG_PCI=y',
'CONFIG_INPUT=y',
'CONFIG_INPUT_KEYBOARD=y',
'CONFIG_KEYBOARD_ATKBD=y',
'CONFIG_SERIAL_8250=y',
'CONFIG_SERIAL_8250_CONSOLE=y',
'CONFIG_X86_VERBOSE_BOOTUP=y',
'CONFIG_VGA_CONSOLE=y',
'CONFIG_FB=y',
'CONFIG_FB_VESA=y',
'CONFIG_FRAMEBUFFER_CONSOLE=y',
'CONFIG_RTC_CLASS=y',
'CONFIG_RTC_HCTOSYS=y',
'CONFIG_RTC_DRV_CMOS=y',
'CONFIG_HYPERVISOR_GUEST=y',
'CONFIG_PARAVIRT=y',
'CONFIG_KVM_GUEST=y',
# Depending on the host kernel, virtme can nest!
'CONFIG_KVM=y',
'CONFIG_KVM_INTEL=y',
'CONFIG_KVM_AMD=y',
]
class Arch_arm(Arch):
def __init__(self):
Arch.__init__(self, 'arm')
self.defconfig_target = 'vexpress_defconfig'
@staticmethod
def qemuargs(is_native):
ret = Arch.qemuargs(is_native)
# Emulate a vexpress-a15.
ret.extend(['-M', 'vexpress-a15'])
# TODO: consider adding a PCI bus (and figuring out how)
# TODO: This won't boot unless -dtb is set, but we need to figure
# out how to find the dtb file.
return ret
@staticmethod
def virtio_dev_type(virtiotype):
return 'virtio-%s-device' % virtiotype
@staticmethod
def earlyconsole_args():
return ['earlyprintk=serial,ttyAMA0,115200']
@staticmethod
def serial_console_args():
return ['console=ttyAMA0']
def kimg_path(self):
return 'arch/arm/boot/zImage'
def dtb_path(self):
return 'arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb'
class Arch_aarch64(Arch):
def __init__(self):
Arch.__init__(self, 'aarch64')
self.qemuname = 'aarch64'
self.linuxname = 'arm64'
self.gccname = 'aarch64'
@staticmethod
def qemuargs(is_native):
ret = Arch.qemuargs(is_native)
# Emulate a fully virtual system.
ret.extend(['-M', 'virt'])
# Despite being called qemu-system-aarch64, QEMU defaults to
# emulating a 32-bit CPU. Override it.
ret.extend(['-cpu', 'cortex-a57'])
return ret
@staticmethod
def virtio_dev_type(virtiotype):
return 'virtio-%s-device' % virtiotype
@staticmethod
def earlyconsole_args():
return ['earlyprintk=serial,ttyAMA0,115200']
@staticmethod
def serial_console_args():
return ['console=ttyAMA0']
def kimg_path(self):
return 'arch/arm64/boot/Image'
class Arch_ppc64(Arch):
def __init__(self):
Arch.__init__(self, 'ppc64')
self.defconfig_target = 'ppc64_defconfig'
self.qemuname = 'ppc64'
self.linuxname = 'powerpc'
self.gccname = 'ppc64'
def qemuargs(self, is_native):
ret = Arch.qemuargs(is_native)
ret.extend(['-M', 'pseries'])
return ret
def kimg_path(self):
# Apparently SLOF (QEMU's bundled firmware?) can't boot a zImage.
return 'vmlinux'
class Arch_riscv64(Arch):
def __init__(self):
Arch.__init__(self, 'riscv64')
self.defconfig_target = 'defconfig'
self.qemuname = 'riscv64'
self.linuxname = 'riscv'
self.gccname = 'riscv64'
def qemuargs(self, is_native):
ret = Arch.qemuargs(is_native)
ret.extend(['-machine', 'virt'])
ret.extend(['-bios', 'default'])
return ret
@staticmethod
def serial_console_args():
return ['console=ttyS0']
def kimg_path(self):
return 'arch/riscv/boot/Image'
class Arch_sparc64(Arch):
def __init__(self):
Arch.__init__(self, 'sparc64')
self.defconfig_target = 'sparc64_defconfig'
self.qemuname = 'sparc64'
self.linuxname = 'sparc'
self.gccname = 'sparc64'
def qemuargs(self, is_native):
ret = Arch.qemuargs(is_native)
return ret
def kimg_path(self):
return 'arch/sparc/boot/image'
def qemu_nodisplay_args(self):
# qemu-system-sparc fails to boot if -display none is set.
return ['-nographic', '-vga', 'none']
class Arch_s390x(Arch):
def __init__(self):
Arch.__init__(self, 's390x')
self.qemuname = 's390x'
self.linuxname = 's390'
self.gccname = 's390x'
@staticmethod
def virtio_dev_type(virtiotype):
return 'virtio-%s-ccw' % virtiotype
def qemuargs(self, is_native):
ret = Arch.qemuargs(is_native)
# Ask for the latest version of s390-ccw
ret.extend(['-M', 's390-ccw-virtio'])
# To be able to configure a console, we need to get rid of the
# default console
ret.extend(['-nodefaults'])
ret.extend(['-device', 'sclpconsole,chardev=console'])
return ret
@staticmethod
def config_base():
return ['CONFIG_MARCH_Z900=y']
ARCHES = {arch.virtmename: arch for arch in [
Arch_x86('x86_64'),
Arch_x86('i386'),
Arch_arm(),
Arch_aarch64(),
Arch_ppc64(),
Arch_riscv64(),
Arch_sparc64(),
Arch_s390x(),
]}
def get(arch):
if arch in ARCHES:
return ARCHES[arch]
else:
return Arch_unknown(arch)