# -*- Mode: Python -*- # vim: filetype=python # # Copyright (C) 2018 Red Hat, Inc. # # Authors: # Daniel P. Berrange # Laszlo Ersek # # This work is licensed under the terms of the GNU GPL, version 2 or # later. See the COPYING file in the top-level directory. ## # = Firmware ## { 'pragma': { 'member-name-exceptions': [ 'FirmwareArchitecture' # x86_64 ] } } ## # @FirmwareOSInterface: # # Lists the firmware-OS interface types provided by various firmware # that is commonly used with QEMU virtual machines. # # @bios: Traditional x86 BIOS interface. For example, firmware built # from the SeaBIOS project usually provides this interface. # # @openfirmware: The interface is defined by the (historical) IEEE # 1275-1994 standard. Examples for firmware projects that # provide this interface are: OpenBIOS and SLOF. # # @uboot: Firmware interface defined by the U-Boot project. # # @uefi: Firmware interface defined by the UEFI specification. For # example, firmware built from the edk2 (EFI Development Kit II) # project usually provides this interface. # # Since: 3.0 ## { 'enum' : 'FirmwareOSInterface', 'data' : [ 'bios', 'openfirmware', 'uboot', 'uefi' ] } ## # @FirmwareDevice: # # Defines the device types that firmware can be mapped into. # # @flash: The firmware executable and its accompanying NVRAM file are to # be mapped into a pflash chip each. # # @kernel: The firmware is to be loaded like a Linux kernel. This is # similar to @memory but may imply additional processing that # is specific to the target architecture and machine type. # # @memory: The firmware is to be mapped into memory. # # Since: 3.0 ## { 'enum' : 'FirmwareDevice', 'data' : [ 'flash', 'kernel', 'memory' ] } ## # @FirmwareArchitecture: # # Enumeration of architectures for which Qemu uses additional # firmware files. # # @aarch64: 64-bit Arm. # # @arm: 32-bit Arm. # # @i386: 32-bit x86. # # @loongarch64: 64-bit LoongArch. (since: 7.1) # # @x86_64: 64-bit x86. # # Since: 3.0 ## { 'enum' : 'FirmwareArchitecture', 'data' : [ 'aarch64', 'arm', 'i386', 'loongarch64', 'x86_64' ] } ## # @FirmwareTarget: # # Defines the machine types that firmware may execute on. # # @architecture: Determines the emulation target (the QEMU system # emulator) that can execute the firmware. # # @machines: Lists the machine types (known by the emulator that is # specified through @architecture) that can execute the # firmware. Elements of @machines are supposed to be concrete # machine types, not aliases. Glob patterns are understood, # which is especially useful for versioned machine types. # (For example, the glob pattern "pc-i440fx-*" matches # "pc-i440fx-2.12".) On the QEMU command line, "-machine # type=..." specifies the requested machine type (but that # option does not accept glob patterns). # # Since: 3.0 ## { 'struct' : 'FirmwareTarget', 'data' : { 'architecture' : 'FirmwareArchitecture', 'machines' : [ 'str' ] } } ## # @FirmwareFeature: # # Defines the features that firmware may support, and the platform # requirements that firmware may present. # # @acpi-s3: The firmware supports S3 sleep (suspend to RAM), as defined # in the ACPI specification. On the "pc-i440fx-*" machine # types of the @i386 and @x86_64 emulation targets, S3 can be # enabled with "-global PIIX4_PM.disable_s3=0" and disabled # with "-global PIIX4_PM.disable_s3=1". On the "pc-q35-*" # machine types of the @i386 and @x86_64 emulation targets, S3 # can be enabled with "-global ICH9-LPC.disable_s3=0" and # disabled with "-global ICH9-LPC.disable_s3=1". # # @acpi-s4: The firmware supports S4 hibernation (suspend to disk), as # defined in the ACPI specification. On the "pc-i440fx-*" # machine types of the @i386 and @x86_64 emulation targets, S4 # can be enabled with "-global PIIX4_PM.disable_s4=0" and # disabled with "-global PIIX4_PM.disable_s4=1". On the # "pc-q35-*" machine types of the @i386 and @x86_64 emulation # targets, S4 can be enabled with "-global # ICH9-LPC.disable_s4=0" and disabled with "-global # ICH9-LPC.disable_s4=1". # # @amd-sev: The firmware supports running under AMD Secure Encrypted # Virtualization, as specified in the AMD64 Architecture # Programmer's Manual. QEMU command line options related to # this feature are documented in # "docs/system/i386/amd-memory-encryption.rst". # # @amd-sev-es: The firmware supports running under AMD Secure Encrypted # Virtualization - Encrypted State, as specified in the AMD64 # Architecture Programmer's Manual. QEMU command line options # related to this feature are documented in # "docs/system/i386/amd-memory-encryption.rst". # # @amd-sev-snp: The firmware supports running under AMD Secure Encrypted # Virtualization - Secure Nested Paging, as specified in the # AMD64 Architecture Programmer's Manual. QEMU command line # options related to this feature are documented in # "docs/system/i386/amd-memory-encryption.rst". # # @intel-tdx: The firmware supports running under Intel Trust Domain # Extensions (TDX). # # @enrolled-keys: The variable store (NVRAM) template associated with # the firmware binary has the UEFI Secure Boot # operational mode turned on, with certificates # enrolled. # # @requires-smm: The firmware requires the platform to emulate SMM # (System Management Mode), as defined in the AMD64 # Architecture Programmer's Manual, and in the Intel(R)64 # and IA-32 Architectures Software Developer's Manual. On # the "pc-q35-*" machine types of the @i386 and @x86_64 # emulation targets, SMM emulation can be enabled with # "-machine smm=on". (On the "pc-q35-*" machine types of # the @i386 emulation target, @requires-smm presents # further CPU requirements; one combination known to work # is "-cpu coreduo,nx=off".) If the firmware is marked as # both @secure-boot and @requires-smm, then write # accesses to the pflash chip (NVRAM) that holds the UEFI # variable store must be restricted to code that executes # in SMM, using the additional option "-global # driver=cfi.pflash01,property=secure,value=on". # Furthermore, a large guest-physical address space # (comprising guest RAM, memory hotplug range, and 64-bit # PCI MMIO aperture), and/or a high VCPU count, may # present high SMRAM requirements from the firmware. On # the "pc-q35-*" machine types of the @i386 and @x86_64 # emulation targets, the SMRAM size may be increased # above the default 16MB with the "-global # mch.extended-tseg-mbytes=uint16" option. As a rule of # thumb, the default 16MB size suffices for 1TB of # guest-phys address space and a few tens of VCPUs; for # every further TB of guest-phys address space, add 8MB # of SMRAM. 48MB should suffice for 4TB of guest-phys # address space and 2-3 hundred VCPUs. # # @secure-boot: The firmware implements the software interfaces for UEFI # Secure Boot, as defined in the UEFI specification. Note # that without @requires-smm, guest code running with # kernel privileges can undermine the security of Secure # Boot. # # @verbose-dynamic: When firmware log capture is enabled, the firmware # logs a large amount of debug messages, which may # impact boot performance. With log capture disabled, # there is no boot performance impact. On the # "pc-i440fx-*" and "pc-q35-*" machine types of the # @i386 and @x86_64 emulation targets, firmware log # capture can be enabled with the QEMU command line # options "-chardev file,id=fwdebug,path=LOGFILEPATH # -device isa-debugcon,iobase=0x402,chardev=fwdebug". # @verbose-dynamic is mutually exclusive with # @verbose-static. # # @verbose-static: The firmware unconditionally produces a large amount # of debug messages, which may impact boot performance. # This feature may typically be carried by certain UEFI # firmware for the "virt-*" machine types of the @arm # and @aarch64 emulation targets, where the debug # messages are written to the first (always present) # PL011 UART. @verbose-static is mutually exclusive # with @verbose-dynamic. # # Since: 3.0 ## { 'enum' : 'FirmwareFeature', 'data' : [ 'acpi-s3', 'acpi-s4', 'amd-sev', 'amd-sev-es', 'amd-sev-snp', 'intel-tdx', 'enrolled-keys', 'requires-smm', 'secure-boot', 'verbose-dynamic', 'verbose-static' ] } ## # @FirmwareFormat: # # Formats that are supported for firmware images. # # @raw: Raw disk image format. # # @qcow2: The QCOW2 image format. # # Since: 3.0 ## { 'enum': 'FirmwareFormat', 'data': [ 'raw', 'qcow2' ] } ## # @FirmwareFlashFile: # # Defines common properties that are necessary for loading a firmware # file into a pflash chip. The corresponding QEMU command line option is # "-drive file=@filename,format=@format". Note however that the # option-argument shown here is incomplete; it is completed under # @FirmwareMappingFlash. # # @filename: Specifies the filename on the host filesystem where the # firmware file can be found. # # @format: Specifies the block format of the file pointed-to by # @filename, such as @raw or @qcow2. # # Since: 3.0 ## { 'struct' : 'FirmwareFlashFile', 'data' : { 'filename' : 'str', 'format' : 'FirmwareFormat' } } ## # @FirmwareFlashMode: # # Describes how the firmware build handles code versus variable # persistence. # # @split: the executable file contains code while the NVRAM # template provides variable storage. The executable # must be configured read-only and can be shared between # multiple guests. The NVRAM template must be cloned # for each new guest and configured read-write. # # @combined: the executable file contains both code and # variable storage. The executable must be cloned # for each new guest and configured read-write. # No NVRAM template will be specified. # # @stateless: the executable file contains code and variable # storage is not persisted. The executable must # be configured read-only and can be shared # between multiple guests. No NVRAM template # will be specified. # # Since: 7.0.0 ## { 'enum': 'FirmwareFlashMode', 'data': [ 'split', 'combined', 'stateless' ] } ## # @FirmwareMappingFlash: # # Describes loading and mapping properties for the firmware executable # and its accompanying NVRAM file, when @FirmwareDevice is @flash. # # @mode: Describes how the firmware build handles code versus variable # storage. If not present, it must be treated as if it was # configured with value @split. Since: 7.0.0 # # @executable: Identifies the firmware executable. The @mode # indicates whether there will be an associated # NVRAM template present. The preferred # corresponding QEMU command line options are # -drive if=none,id=pflash0,readonly=on,file=@executable.@filename,format=@executable.@format # -machine pflash0=pflash0 # or equivalent -blockdev instead of -drive. When # @mode is @combined the executable must be # cloned before use and configured with readonly=off. # With QEMU versions older than 4.0, you have to use # -drive if=pflash,unit=0,readonly=on,file=@executable.@filename,format=@executable.@format # # @nvram-template: Identifies the NVRAM template compatible with # @executable, when @mode is set to @split, # otherwise it should not be present. # Management software instantiates an # individual copy -- a specific NVRAM file -- from # @nvram-template.@filename for each new virtual # machine definition created. @nvram-template.@filename # itself is never mapped into virtual machines, only # individual copies of it are. An NVRAM file is # typically used for persistently storing the # non-volatile UEFI variables of a virtual machine # definition. The preferred corresponding QEMU # command line options are # -drive if=none,id=pflash1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format # -machine pflash1=pflash1 # or equivalent -blockdev instead of -drive. # With QEMU versions older than 4.0, you have to use # -drive if=pflash,unit=1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format # # Since: 3.0 ## { 'struct' : 'FirmwareMappingFlash', 'data' : { '*mode': 'FirmwareFlashMode', 'executable' : 'FirmwareFlashFile', '*nvram-template' : 'FirmwareFlashFile' } } ## # @FirmwareMappingKernel: # # Describes loading and mapping properties for the firmware executable, # when @FirmwareDevice is @kernel. # # @filename: Identifies the firmware executable. The firmware executable # may be shared by multiple virtual machine definitions. The # corresponding QEMU command line option is "-kernel # @filename". # # Since: 3.0 ## { 'struct' : 'FirmwareMappingKernel', 'data' : { 'filename' : 'str' } } ## # @FirmwareMappingMemory: # # Describes loading and mapping properties for the firmware executable, # when @FirmwareDevice is @memory. # # @filename: Identifies the firmware executable. The firmware executable # may be shared by multiple virtual machine definitions. The # corresponding QEMU command line option is "-bios # @filename". # # Since: 3.0 ## { 'struct' : 'FirmwareMappingMemory', 'data' : { 'filename' : 'str' } } ## # @FirmwareMapping: # # Provides a discriminated structure for firmware to describe its # loading / mapping properties. # # @device: Selects the device type that the firmware must be mapped # into. # # Since: 3.0 ## { 'union' : 'FirmwareMapping', 'base' : { 'device' : 'FirmwareDevice' }, 'discriminator' : 'device', 'data' : { 'flash' : 'FirmwareMappingFlash', 'kernel' : 'FirmwareMappingKernel', 'memory' : 'FirmwareMappingMemory' } } ## # @Firmware: # # Describes a firmware (or a firmware use case) to management software. # # It is possible for multiple @Firmware elements to match the search # criteria of management software. Applications thus need rules to pick # one of the many matches, and users need the ability to override distro # defaults. # # It is recommended to create firmware JSON files (each containing a # single @Firmware root element) with a double-digit prefix, for example # "50-ovmf.json", "50-seabios-256k.json", etc, so they can be sorted in # predictable order. The firmware JSON files should be searched for in # three directories: # # - /usr/share/qemu/firmware -- populated by distro-provided firmware # packages (XDG_DATA_DIRS covers # /usr/share by default), # # - /etc/qemu/firmware -- exclusively for sysadmins' local additions, # # - $XDG_CONFIG_HOME/qemu/firmware -- exclusively for per-user local # additions (XDG_CONFIG_HOME # defaults to $HOME/.config). # # Top-down, the list of directories goes from general to specific. # # Management software should build a list of files from all three # locations, then sort the list by filename (i.e., last pathname # component). Management software should choose the first JSON file on # the sorted list that matches the search criteria. If a more specific # directory has a file with same name as a less specific directory, then # the file in the more specific directory takes effect. If the more # specific file is zero length, it hides the less specific one. # # For example, if a distro ships # # - /usr/share/qemu/firmware/50-ovmf.json # # - /usr/share/qemu/firmware/50-seabios-256k.json # # then the sysadmin can prevent the default OVMF being used at all with # # $ touch /etc/qemu/firmware/50-ovmf.json # # The sysadmin can replace/alter the distro default OVMF with # # $ vim /etc/qemu/firmware/50-ovmf.json # # or they can provide a parallel OVMF with higher priority # # $ vim /etc/qemu/firmware/10-ovmf.json # # or they can provide a parallel OVMF with lower priority # # $ vim /etc/qemu/firmware/99-ovmf.json # # @description: Provides a human-readable description of the firmware. # Management software may or may not display @description. # # @interface-types: Lists the types of interfaces that the firmware can # expose to the guest OS. This is a non-empty, ordered # list; entries near the beginning of @interface-types # are considered more native to the firmware, and/or # to have a higher quality implementation in the # firmware, than entries near the end of # @interface-types. # # @mapping: Describes the loading / mapping properties of the firmware. # # @targets: Collects the target architectures (QEMU system emulators) # and their machine types that may execute the firmware. # # @features: Lists the features that the firmware supports, and the # platform requirements it presents. # # @tags: A list of auxiliary strings associated with the firmware for # which @description is not appropriate, due to the latter's # possible exposure to the end-user. @tags serves development and # debugging purposes only, and management software shall # explicitly ignore it. # # Since: 3.0 # # .. qmp-example:: # # { # "description": "SeaBIOS", # "interface-types": [ # "bios" # ], # "mapping": { # "device": "memory", # "filename": "/usr/share/seabios/bios-256k.bin" # }, # "targets": [ # { # "architecture": "i386", # "machines": [ # "pc-i440fx-*", # "pc-q35-*" # ] # }, # { # "architecture": "x86_64", # "machines": [ # "pc-i440fx-*", # "pc-q35-*" # ] # } # ], # "features": [ # "acpi-s3", # "acpi-s4" # ], # "tags": [ # "CONFIG_BOOTSPLASH=n", # "CONFIG_ROM_SIZE=256", # "CONFIG_USE_SMM=n" # ] # } # # { # "description": "OVMF with SB+SMM, empty varstore", # "interface-types": [ # "uefi" # ], # "mapping": { # "device": "flash", # "executable": { # "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd", # "format": "raw" # }, # "nvram-template": { # "filename": "/usr/share/OVMF/OVMF_VARS.fd", # "format": "raw" # } # }, # "targets": [ # { # "architecture": "x86_64", # "machines": [ # "pc-q35-*" # ] # } # ], # "features": [ # "acpi-s3", # "amd-sev", # "requires-smm", # "secure-boot", # "verbose-dynamic" # ], # "tags": [ # "-a IA32", # "-a X64", # "-p OvmfPkg/OvmfPkgIa32X64.dsc", # "-t GCC48", # "-b DEBUG", # "-D SMM_REQUIRE", # "-D SECURE_BOOT_ENABLE", # "-D FD_SIZE_4MB" # ] # } # # { # "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled", # "interface-types": [ # "uefi" # ], # "mapping": { # "device": "flash", # "executable": { # "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd", # "format": "raw" # }, # "nvram-template": { # "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd", # "format": "raw" # } # }, # "targets": [ # { # "architecture": "x86_64", # "machines": [ # "pc-q35-*" # ] # } # ], # "features": [ # "acpi-s3", # "amd-sev", # "enrolled-keys", # "requires-smm", # "secure-boot", # "verbose-dynamic" # ], # "tags": [ # "-a IA32", # "-a X64", # "-p OvmfPkg/OvmfPkgIa32X64.dsc", # "-t GCC48", # "-b DEBUG", # "-D SMM_REQUIRE", # "-D SECURE_BOOT_ENABLE", # "-D FD_SIZE_4MB" # ] # } # # { # "description": "OVMF with SEV-ES support", # "interface-types": [ # "uefi" # ], # "mapping": { # "device": "flash", # "executable": { # "filename": "/usr/share/OVMF/OVMF_CODE.fd", # "format": "raw" # }, # "nvram-template": { # "filename": "/usr/share/OVMF/OVMF_VARS.fd", # "format": "raw" # } # }, # "targets": [ # { # "architecture": "x86_64", # "machines": [ # "pc-q35-*" # ] # } # ], # "features": [ # "acpi-s3", # "amd-sev", # "amd-sev-es", # "verbose-dynamic" # ], # "tags": [ # "-a X64", # "-p OvmfPkg/OvmfPkgX64.dsc", # "-t GCC48", # "-b DEBUG", # "-D FD_SIZE_4MB" # ] # } # # { # "description": "UEFI firmware for ARM64 virtual machines", # "interface-types": [ # "uefi" # ], # "mapping": { # "device": "flash", # "executable": { # "filename": "/usr/share/AAVMF/AAVMF_CODE.fd", # "format": "raw" # }, # "nvram-template": { # "filename": "/usr/share/AAVMF/AAVMF_VARS.fd", # "format": "raw" # } # }, # "targets": [ # { # "architecture": "aarch64", # "machines": [ # "virt-*" # ] # } # ], # "features": [ # # ], # "tags": [ # "-a AARCH64", # "-p ArmVirtPkg/ArmVirtQemu.dsc", # "-t GCC48", # "-b DEBUG", # "-D DEBUG_PRINT_ERROR_LEVEL=0x80000000" # ] # } ## { 'struct' : 'Firmware', 'data' : { 'description' : 'str', 'interface-types' : [ 'FirmwareOSInterface' ], 'mapping' : 'FirmwareMapping', 'targets' : [ 'FirmwareTarget' ], 'features' : [ 'FirmwareFeature' ], 'tags' : [ 'str' ] } }