mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-docs-xen-updates-100321-2' into staging
Testing, guest-loader and other misc tweaks - add warning text to quickstart example - add CFI tests to CI - use --arch-only for docker pre-requisites - fix .editorconfig for emacs - add guest-loader for Xen-like hypervisor testing - move generic-loader docs into manual proper - move semihosting out of hw/ # gpg: Signature made Wed 10 Mar 2021 15:35:31 GMT # gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44 # gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full] # Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44 * remotes/stsquad/tags/pull-testing-docs-xen-updates-100321-2: semihosting: Move hw/semihosting/ -> semihosting/ semihosting: Move include/hw/semihosting/ -> include/semihosting/ tests/avocado: add boot_xen tests docs: add some documentation for the guest-loader docs: move generic-loader documentation into the main manual hw/core: implement a guest-loader to support static hypervisor guests device_tree: add qemu_fdt_setprop_string_array helper hw/riscv: migrate fdt field to generic MachineState hw/board: promote fdt from ARM VirtMachineState to MachineState .editorconfig: update the automatic mode setting for Emacs tests/docker: Use --arch-only when building Debian cross image gitlab-ci.yml: Add jobs to test CFI flags gitlab-ci.yml: Allow custom # of parallel linkers tests/docker: add a test-tcg for building then running check-tcg docs/system: add a gentle prompt for the complexity to come Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+11
-6
@@ -4,6 +4,11 @@
|
||||
# plugin.
|
||||
#
|
||||
# Check https://editorconfig.org for details.
|
||||
#
|
||||
# Emacs: you need https://github.com/10sr/editorconfig-custom-majormode-el
|
||||
# to automatically enable the appropriate major-mode for your files
|
||||
# that aren't already caught by your existing config.
|
||||
#
|
||||
|
||||
root = true
|
||||
|
||||
@@ -15,17 +20,17 @@ charset = utf-8
|
||||
[*.mak]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
file_type_emacs = makefile
|
||||
emacs_mode = makefile
|
||||
|
||||
[Makefile*]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
file_type_emacs = makefile
|
||||
emacs_mode = makefile
|
||||
|
||||
[*.{c,h,c.inc,h.inc}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
file_type_emacs = c
|
||||
emacs_mode = c
|
||||
|
||||
[*.sh]
|
||||
indent_style = space
|
||||
@@ -34,11 +39,11 @@ indent_size = 4
|
||||
[*.{s,S}]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
file_type_emacs = asm
|
||||
emacs_mode = asm
|
||||
|
||||
[*.{vert,frag}]
|
||||
file_type_emacs = glsl
|
||||
emacs_mode = glsl
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
file_type_emacs = python
|
||||
emacs_mode = python
|
||||
|
||||
+123
@@ -27,6 +27,10 @@ include:
|
||||
else
|
||||
../configure --enable-werror $CONFIGURE_ARGS ;
|
||||
fi || { cat config.log meson-logs/meson-log.txt && exit 1; }
|
||||
- if test -n "$LD_JOBS";
|
||||
then
|
||||
meson configure . -Dbackend_max_links="$LD_JOBS" ;
|
||||
fi || exit 1;
|
||||
- make -j"$JOBS"
|
||||
- if test -n "$MAKE_CHECK_ARGS";
|
||||
then
|
||||
@@ -481,6 +485,125 @@ clang-user:
|
||||
--extra-cflags=-fsanitize=undefined --extra-cflags=-fno-sanitize-recover=undefined
|
||||
MAKE_CHECK_ARGS: check-unit check-tcg
|
||||
|
||||
# Set LD_JOBS=1 because this requires LTO and ld consumes a large amount of memory.
|
||||
# On gitlab runners, default value sometimes end up calling 2 lds concurrently and
|
||||
# triggers an Out-Of-Memory error
|
||||
#
|
||||
# Since slirp callbacks are used in QEMU Timers, slirp needs to be compiled together
|
||||
# with QEMU and linked as a static library to avoid false positives in CFI checks.
|
||||
# This can be accomplished by using -enable-slirp=git, which avoids the use of
|
||||
# a system-wide version of the library
|
||||
#
|
||||
# Split in three sets of build/check/acceptance to limit the execution time of each
|
||||
# job
|
||||
build-cfi-aarch64:
|
||||
<<: *native_build_job_definition
|
||||
needs:
|
||||
- job: amd64-fedora-container
|
||||
variables:
|
||||
LD_JOBS: 1
|
||||
AR: llvm-ar
|
||||
IMAGE: fedora
|
||||
CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-cfi --enable-cfi-debug
|
||||
--enable-safe-stack --enable-slirp=git
|
||||
TARGETS: aarch64-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- build
|
||||
|
||||
check-cfi-aarch64:
|
||||
<<: *native_test_job_definition
|
||||
needs:
|
||||
- job: build-cfi-aarch64
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
acceptance-cfi-aarch64:
|
||||
<<: *native_test_job_definition
|
||||
needs:
|
||||
- job: build-cfi-aarch64
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check-acceptance
|
||||
<<: *acceptance_definition
|
||||
|
||||
build-cfi-ppc64-s390x:
|
||||
<<: *native_build_job_definition
|
||||
needs:
|
||||
- job: amd64-fedora-container
|
||||
variables:
|
||||
LD_JOBS: 1
|
||||
AR: llvm-ar
|
||||
IMAGE: fedora
|
||||
CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-cfi --enable-cfi-debug
|
||||
--enable-safe-stack --enable-slirp=git
|
||||
TARGETS: ppc64-softmmu s390x-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- build
|
||||
|
||||
check-cfi-ppc64-s390x:
|
||||
<<: *native_test_job_definition
|
||||
needs:
|
||||
- job: build-cfi-ppc64-s390x
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
acceptance-cfi-ppc64-s390x:
|
||||
<<: *native_test_job_definition
|
||||
needs:
|
||||
- job: build-cfi-ppc64-s390x
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check-acceptance
|
||||
<<: *acceptance_definition
|
||||
|
||||
build-cfi-x86_64:
|
||||
<<: *native_build_job_definition
|
||||
needs:
|
||||
- job: amd64-fedora-container
|
||||
variables:
|
||||
LD_JOBS: 1
|
||||
AR: llvm-ar
|
||||
IMAGE: fedora
|
||||
CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-cfi --enable-cfi-debug
|
||||
--enable-safe-stack --enable-slirp=git
|
||||
TARGETS: x86_64-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- build
|
||||
|
||||
check-cfi-x86_64:
|
||||
<<: *native_test_job_definition
|
||||
needs:
|
||||
- job: build-cfi-x86_64
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
acceptance-cfi-x86_64:
|
||||
<<: *native_test_job_definition
|
||||
needs:
|
||||
- job: build-cfi-x86_64
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check-acceptance
|
||||
<<: *acceptance_definition
|
||||
|
||||
tsan-build:
|
||||
<<: *native_build_job_definition
|
||||
variables:
|
||||
|
||||
@@ -2,3 +2,4 @@ source Kconfig.host
|
||||
source backends/Kconfig
|
||||
source accel/Kconfig
|
||||
source hw/Kconfig
|
||||
source semihosting/Kconfig
|
||||
|
||||
+10
-3
@@ -2027,7 +2027,14 @@ M: Alistair Francis <alistair@alistair23.me>
|
||||
S: Maintained
|
||||
F: hw/core/generic-loader.c
|
||||
F: include/hw/core/generic-loader.h
|
||||
F: docs/generic-loader.txt
|
||||
F: docs/system/generic-loader.rst
|
||||
|
||||
Guest Loader
|
||||
M: Alex Bennée <alex.bennee@linaro.org>
|
||||
S: Maintained
|
||||
F: hw/core/guest-loader.c
|
||||
F: docs/system/guest-loader.rst
|
||||
F: tests/acceptance/boot_xen.py
|
||||
|
||||
Intel Hexadecimal Object File Loader
|
||||
M: Su Hang <suhang16@mails.ucas.ac.cn>
|
||||
@@ -3255,8 +3262,8 @@ F: qapi/rdma.json
|
||||
Semihosting
|
||||
M: Alex Bennée <alex.bennee@linaro.org>
|
||||
S: Maintained
|
||||
F: hw/semihosting/
|
||||
F: include/hw/semihosting/
|
||||
F: semihosting/
|
||||
F: include/semihosting/
|
||||
|
||||
Multi-process QEMU
|
||||
M: Elena Ufimtseva <elena.ufimtseva@oracle.com>
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
Copyright (c) 2016 Xilinx Inc.
|
||||
|
||||
This work is licensed under the terms of the GNU GPL, version 2 or later. See
|
||||
the COPYING file in the top-level directory.
|
||||
|
||||
|
||||
The 'loader' device allows the user to load multiple images or values into
|
||||
QEMU at startup.
|
||||
|
||||
Loading Data into Memory Values
|
||||
-------------------------------
|
||||
The loader device allows memory values to be set from the command line. This
|
||||
can be done by following the syntax below:
|
||||
|
||||
-device loader,addr=<addr>,data=<data>,data-len=<data-len>
|
||||
[,data-be=<data-be>][,cpu-num=<cpu-num>]
|
||||
|
||||
<addr> - The address to store the data in.
|
||||
<data> - The value to be written to the address. The maximum size of
|
||||
the data is 8 bytes.
|
||||
<data-len> - The length of the data in bytes. This argument must be
|
||||
included if the data argument is.
|
||||
<data-be> - Set to true if the data to be stored on the guest should be
|
||||
written as big endian data. The default is to write little
|
||||
endian data.
|
||||
<cpu-num> - The number of the CPU's address space where the data should
|
||||
be loaded. If not specified the address space of the first
|
||||
CPU is used.
|
||||
|
||||
All values are parsed using the standard QemuOps parsing. This allows the user
|
||||
to specify any values in any format supported. By default the values
|
||||
will be parsed as decimal. To use hex values the user should prefix the number
|
||||
with a '0x'.
|
||||
|
||||
An example of loading value 0x8000000e to address 0xfd1a0104 is:
|
||||
-device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4
|
||||
|
||||
Setting a CPU's Program Counter
|
||||
-------------------------------
|
||||
The loader device allows the CPU's PC to be set from the command line. This
|
||||
can be done by following the syntax below:
|
||||
|
||||
-device loader,addr=<addr>,cpu-num=<cpu-num>
|
||||
|
||||
<addr> - The value to use as the CPU's PC.
|
||||
<cpu-num> - The number of the CPU whose PC should be set to the
|
||||
specified value.
|
||||
|
||||
All values are parsed using the standard QemuOps parsing. This allows the user
|
||||
to specify any values in any format supported. By default the values
|
||||
will be parsed as decimal. To use hex values the user should prefix the number
|
||||
with a '0x'.
|
||||
|
||||
An example of setting CPU 0's PC to 0x8000 is:
|
||||
-device loader,addr=0x8000,cpu-num=0
|
||||
|
||||
Loading Files
|
||||
-------------
|
||||
The loader device also allows files to be loaded into memory. It can load ELF,
|
||||
U-Boot, and Intel HEX executable formats as well as raw images. The syntax is
|
||||
shown below:
|
||||
|
||||
-device loader,file=<file>[,addr=<addr>][,cpu-num=<cpu-num>][,force-raw=<raw>]
|
||||
|
||||
<file> - A file to be loaded into memory
|
||||
<addr> - The memory address where the file should be loaded. This is
|
||||
required for raw images and ignored for non-raw files.
|
||||
<cpu-num> - This specifies the CPU that should be used. This is an
|
||||
optional argument and will cause the CPU's PC to be set to
|
||||
the memory address where the raw file is loaded or the entry
|
||||
point specified in the executable format header. This option
|
||||
should only be used for the boot image.
|
||||
This will also cause the image to be written to the specified
|
||||
CPU's address space. If not specified, the default is CPU 0.
|
||||
<force-raw> - Setting force-raw=on forces the file to be treated as a raw
|
||||
image. This can be used to load supported executable formats
|
||||
as if they were raw.
|
||||
|
||||
All values are parsed using the standard QemuOps parsing. This allows the user
|
||||
to specify any values in any format supported. By default the values
|
||||
will be parsed as decimal. To use hex values the user should prefix the number
|
||||
with a '0x'.
|
||||
|
||||
An example of loading an ELF file which CPU0 will boot is shown below:
|
||||
-device loader,file=./images/boot.elf,cpu-num=0
|
||||
|
||||
Restrictions and ToDos
|
||||
----------------------
|
||||
- At the moment it is just assumed that if you specify a cpu-num then you
|
||||
want to set the PC as well. This might not always be the case. In future
|
||||
the internal state 'set_pc' (which exists in the generic loader now) should
|
||||
be exposed to the user so that they can choose if the PC is set or not.
|
||||
@@ -0,0 +1,117 @@
|
||||
..
|
||||
Copyright (c) 2016, Xilinx Inc.
|
||||
|
||||
This work is licensed under the terms of the GNU GPL, version 2 or later. See
|
||||
the COPYING file in the top-level directory.
|
||||
|
||||
Generic Loader
|
||||
--------------
|
||||
|
||||
The 'loader' device allows the user to load multiple images or values into
|
||||
QEMU at startup.
|
||||
|
||||
Loading Data into Memory Values
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The loader device allows memory values to be set from the command line. This
|
||||
can be done by following the syntax below::
|
||||
|
||||
-device loader,addr=<addr>,data=<data>,data-len=<data-len> \
|
||||
[,data-be=<data-be>][,cpu-num=<cpu-num>]
|
||||
|
||||
``<addr>``
|
||||
The address to store the data in.
|
||||
|
||||
``<data>``
|
||||
The value to be written to the address. The maximum size of the data
|
||||
is 8 bytes.
|
||||
|
||||
``<data-len>``
|
||||
The length of the data in bytes. This argument must be included if
|
||||
the data argument is.
|
||||
|
||||
``<data-be>``
|
||||
Set to true if the data to be stored on the guest should be written
|
||||
as big endian data. The default is to write little endian data.
|
||||
|
||||
``<cpu-num>``
|
||||
The number of the CPU's address space where the data should be
|
||||
loaded. If not specified the address space of the first CPU is used.
|
||||
|
||||
All values are parsed using the standard QemuOps parsing. This allows the user
|
||||
to specify any values in any format supported. By default the values
|
||||
will be parsed as decimal. To use hex values the user should prefix the number
|
||||
with a '0x'.
|
||||
|
||||
An example of loading value 0x8000000e to address 0xfd1a0104 is::
|
||||
|
||||
-device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4
|
||||
|
||||
Setting a CPU's Program Counter
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The loader device allows the CPU's PC to be set from the command line. This
|
||||
can be done by following the syntax below::
|
||||
|
||||
-device loader,addr=<addr>,cpu-num=<cpu-num>
|
||||
|
||||
``<addr>``
|
||||
The value to use as the CPU's PC.
|
||||
|
||||
``<cpu-num>``
|
||||
The number of the CPU whose PC should be set to the specified value.
|
||||
|
||||
All values are parsed using the standard QemuOpts parsing. This allows the user
|
||||
to specify any values in any format supported. By default the values
|
||||
will be parsed as decimal. To use hex values the user should prefix the number
|
||||
with a '0x'.
|
||||
|
||||
An example of setting CPU 0's PC to 0x8000 is::
|
||||
|
||||
-device loader,addr=0x8000,cpu-num=0
|
||||
|
||||
Loading Files
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The loader device also allows files to be loaded into memory. It can load ELF,
|
||||
U-Boot, and Intel HEX executable formats as well as raw images. The syntax is
|
||||
shown below:
|
||||
|
||||
-device loader,file=<file>[,addr=<addr>][,cpu-num=<cpu-num>][,force-raw=<raw>]
|
||||
|
||||
``<file>``
|
||||
A file to be loaded into memory
|
||||
|
||||
``<addr>``
|
||||
The memory address where the file should be loaded. This is required
|
||||
for raw images and ignored for non-raw files.
|
||||
|
||||
``<cpu-num>``
|
||||
This specifies the CPU that should be used. This is an
|
||||
optional argument and will cause the CPU's PC to be set to the
|
||||
memory address where the raw file is loaded or the entry point
|
||||
specified in the executable format header. This option should only
|
||||
be used for the boot image. This will also cause the image to be
|
||||
written to the specified CPU's address space. If not specified, the
|
||||
default is CPU 0. <force-raw> - Setting force-raw=on forces the file
|
||||
to be treated as a raw image. This can be used to load supported
|
||||
executable formats as if they were raw.
|
||||
|
||||
All values are parsed using the standard QemuOpts parsing. This allows the user
|
||||
to specify any values in any format supported. By default the values
|
||||
will be parsed as decimal. To use hex values the user should prefix the number
|
||||
with a '0x'.
|
||||
|
||||
An example of loading an ELF file which CPU0 will boot is shown below::
|
||||
|
||||
-device loader,file=./images/boot.elf,cpu-num=0
|
||||
|
||||
Restrictions and ToDos
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
At the moment it is just assumed that if you specify a cpu-num then
|
||||
you want to set the PC as well. This might not always be the case. In
|
||||
future the internal state 'set_pc' (which exists in the generic loader
|
||||
now) should be exposed to the user so that they can choose if the PC
|
||||
is set or not.
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
..
|
||||
Copyright (c) 2020, Linaro
|
||||
|
||||
Guest Loader
|
||||
------------
|
||||
|
||||
The guest loader is similar to the `generic-loader` although it is
|
||||
aimed at a particular use case of loading hypervisor guests. This is
|
||||
useful for debugging hypervisors without having to jump through the
|
||||
hoops of firmware and boot-loaders.
|
||||
|
||||
The guest loader does two things:
|
||||
|
||||
- load blobs (kernels and initial ram disks) into memory
|
||||
- sets platform FDT data so hypervisors can find and boot them
|
||||
|
||||
This is what is typically done by a boot-loader like grub using it's
|
||||
multi-boot capability. A typical example would look like:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
|qemu_system| -kernel ~/xen.git/xen/xen \
|
||||
-append "dom0_mem=1G,max:1G loglvl=all guest_loglvl=all" \
|
||||
-device guest-loader,addr=0x42000000,kernel=Image,bootargs="root=/dev/sda2 ro console=hvc0 earlyprintk=xen" \
|
||||
-device guest-loader,addr=0x47000000,initrd=rootfs.cpio
|
||||
|
||||
In the above example the Xen hypervisor is loaded by the -kernel
|
||||
parameter and passed it's boot arguments via -append. The Dom0 guest
|
||||
is loaded into the areas of memory. Each blob will get
|
||||
`/chosen/module@<addr>` entry in the FDT to indicate it's location and
|
||||
size. Additional information can be passed with by using additional
|
||||
arguments.
|
||||
|
||||
Currently the only supported machines which use FDT data to boot are
|
||||
the ARM and RiscV `virt` machines.
|
||||
|
||||
Arguments
|
||||
^^^^^^^^^
|
||||
|
||||
The full syntax of the guest-loader is::
|
||||
|
||||
-device guest-loader,addr=<addr>[,kernel=<file>,[bootargs=<args>]][,initrd=<file>]
|
||||
|
||||
``addr=<addr>``
|
||||
This is mandatory and indicates the start address of the blob.
|
||||
|
||||
``kernel|initrd=<file>``
|
||||
Indicates the filename of the kernel or initrd blob. Both blobs will
|
||||
have the "multiboot,module" compatibility string as well as
|
||||
"multiboot,kernel" or "multiboot,ramdisk" as appropriate.
|
||||
|
||||
``bootargs=<args>``
|
||||
This is an optional field for kernel blobs which will pass command
|
||||
like via the `/chosen/module@<addr>/bootargs` node.
|
||||
@@ -25,6 +25,8 @@ Contents:
|
||||
usb
|
||||
ivshmem
|
||||
linuxboot
|
||||
generic-loader
|
||||
guest-loader
|
||||
vnc-security
|
||||
tls
|
||||
gdb
|
||||
|
||||
@@ -11,3 +11,11 @@ Download and uncompress a PC hard disk image with Linux installed (e.g.
|
||||
|qemu_system| linux.img
|
||||
|
||||
Linux should boot and give you a prompt.
|
||||
|
||||
Users should be aware the above example elides a lot of the complexity
|
||||
of setting up a VM with x86_64 specific defaults and assumes the
|
||||
first non switch argument is a PC compatible disk image with a boot
|
||||
sector. For a non-x86 system where we emulate a broad range of machine
|
||||
types, the command lines are generally more explicit in defining the
|
||||
machine and boot behaviour. You will find more example command lines
|
||||
in the :ref:`system-targets-ref` section of the manual.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _system-targets-ref:
|
||||
|
||||
QEMU System Emulator Targets
|
||||
============================
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include "sysemu/hw_accel.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "hw/semihosting/semihost.h"
|
||||
#include "semihosting/semihost.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "sysemu/replay.h"
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ source remote/Kconfig
|
||||
source rtc/Kconfig
|
||||
source scsi/Kconfig
|
||||
source sd/Kconfig
|
||||
source semihosting/Kconfig
|
||||
source smbios/Kconfig
|
||||
source ssi/Kconfig
|
||||
source timer/Kconfig
|
||||
|
||||
+185
-171
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Guest Loader
|
||||
*
|
||||
* Copyright (C) 2020 Linaro
|
||||
* Written by Alex Bennée <alex.bennee@linaro.org>
|
||||
* (based on the generic-loader by Li Guang <lig.fnst@cn.fujitsu.com>)
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Much like the generic-loader this is treated as a special device
|
||||
* inside QEMU. However unlike the generic-loader this device is used
|
||||
* to load guest images for hypervisors. As part of that process the
|
||||
* hypervisor needs to have platform information passed to it by the
|
||||
* lower levels of the stack (e.g. firmware/bootloader). If you boot
|
||||
* the hypervisor directly you use the guest-loader to load the Dom0
|
||||
* or equivalent guest images in the right place in the same way a
|
||||
* boot loader would.
|
||||
*
|
||||
* This is only relevant for full system emulation.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/core/cpu.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "hw/loader.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/module.h"
|
||||
#include "guest-loader.h"
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "hw/boards.h"
|
||||
|
||||
/*
|
||||
* Insert some FDT nodes for the loaded blob.
|
||||
*/
|
||||
static void loader_insert_platform_data(GuestLoaderState *s, int size,
|
||||
Error **errp)
|
||||
{
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
void *fdt = machine->fdt;
|
||||
g_autofree char *node = g_strdup_printf("/chosen/module@0x%08" PRIx64,
|
||||
s->addr);
|
||||
uint64_t reg_attr[2] = {cpu_to_be64(s->addr), cpu_to_be64(size)};
|
||||
|
||||
if (!fdt) {
|
||||
error_setg(errp, "Cannot modify FDT fields if the machine has none");
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_fdt_add_subnode(fdt, node);
|
||||
qemu_fdt_setprop(fdt, node, "reg", ®_attr, sizeof(reg_attr));
|
||||
|
||||
if (s->kernel) {
|
||||
const char *compat[2] = { "multiboot,module", "multiboot,kernel" };
|
||||
if (qemu_fdt_setprop_string_array(fdt, node, "compatible",
|
||||
(char **) &compat,
|
||||
ARRAY_SIZE(compat)) < 0) {
|
||||
error_setg(errp, "couldn't set %s/compatible", node);
|
||||
return;
|
||||
}
|
||||
if (s->args) {
|
||||
if (qemu_fdt_setprop_string(fdt, node, "bootargs", s->args) < 0) {
|
||||
error_setg(errp, "couldn't set %s/bootargs", node);
|
||||
}
|
||||
}
|
||||
} else if (s->initrd) {
|
||||
const char *compat[2] = { "multiboot,module", "multiboot,ramdisk" };
|
||||
if (qemu_fdt_setprop_string_array(fdt, node, "compatible",
|
||||
(char **) &compat,
|
||||
ARRAY_SIZE(compat)) < 0) {
|
||||
error_setg(errp, "couldn't set %s/compatible", node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void guest_loader_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
GuestLoaderState *s = GUEST_LOADER(dev);
|
||||
char *file = s->kernel ? s->kernel : s->initrd;
|
||||
int size = 0;
|
||||
|
||||
/* Perform some error checking on the user's options */
|
||||
if (s->kernel && s->initrd) {
|
||||
error_setg(errp, "Cannot specify a kernel and initrd in same stanza");
|
||||
return;
|
||||
} else if (!s->kernel && !s->initrd) {
|
||||
error_setg(errp, "Need to specify a kernel or initrd image");
|
||||
return;
|
||||
} else if (!s->addr) {
|
||||
error_setg(errp, "Need to specify the address of guest blob");
|
||||
return;
|
||||
} else if (s->args && !s->kernel) {
|
||||
error_setg(errp, "Boot args only relevant to kernel blobs");
|
||||
}
|
||||
|
||||
/* Default to the maximum size being the machine's ram size */
|
||||
size = load_image_targphys_as(file, s->addr, current_machine->ram_size,
|
||||
NULL);
|
||||
if (size < 0) {
|
||||
error_setg(errp, "Cannot load specified image %s", file);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now the image is loaded we need to update the platform data */
|
||||
loader_insert_platform_data(s, size, errp);
|
||||
}
|
||||
|
||||
static Property guest_loader_props[] = {
|
||||
DEFINE_PROP_UINT64("addr", GuestLoaderState, addr, 0),
|
||||
DEFINE_PROP_STRING("kernel", GuestLoaderState, kernel),
|
||||
DEFINE_PROP_STRING("bootargs", GuestLoaderState, args),
|
||||
DEFINE_PROP_STRING("initrd", GuestLoaderState, initrd),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void guest_loader_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->realize = guest_loader_realize;
|
||||
device_class_set_props(dc, guest_loader_props);
|
||||
dc->desc = "Guest Loader";
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
}
|
||||
|
||||
static TypeInfo guest_loader_info = {
|
||||
.name = TYPE_GUEST_LOADER,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(GuestLoaderState),
|
||||
.class_init = guest_loader_class_init,
|
||||
};
|
||||
|
||||
static void guest_loader_register_type(void)
|
||||
{
|
||||
type_register_static(&guest_loader_info);
|
||||
}
|
||||
|
||||
type_init(guest_loader_register_type)
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Guest Loader
|
||||
*
|
||||
* Copyright (C) 2020 Linaro
|
||||
* Written by Alex Bennée <alex.bennee@linaro.org>
|
||||
* (based on the generic-loader by Li Guang <lig.fnst@cn.fujitsu.com>)
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef GUEST_LOADER_H
|
||||
#define GUEST_LOADER_H
|
||||
|
||||
#include "hw/qdev-core.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
struct GuestLoaderState {
|
||||
/* <private> */
|
||||
DeviceState parent_obj;
|
||||
|
||||
/* <public> */
|
||||
uint64_t addr;
|
||||
char *kernel;
|
||||
char *args;
|
||||
char *initrd;
|
||||
};
|
||||
|
||||
#define TYPE_GUEST_LOADER "guest-loader"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(GuestLoaderState, GUEST_LOADER)
|
||||
|
||||
#endif
|
||||
@@ -37,6 +37,8 @@ softmmu_ss.add(files(
|
||||
'clock-vmstate.c',
|
||||
))
|
||||
|
||||
softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('guest-loader.c'))
|
||||
|
||||
specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files(
|
||||
'machine-qmp-cmds.c',
|
||||
'numa.c',
|
||||
|
||||
@@ -30,7 +30,6 @@ subdir('rdma')
|
||||
subdir('rtc')
|
||||
subdir('scsi')
|
||||
subdir('sd')
|
||||
subdir('semihosting')
|
||||
subdir('smbios')
|
||||
subdir('ssi')
|
||||
subdir('timer')
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/misc/empty_slot.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "hw/semihosting/semihost.h"
|
||||
#include "semihosting/semihost.h"
|
||||
#include "hw/mips/cps.h"
|
||||
#include "hw/qdev-clock.h"
|
||||
|
||||
|
||||
+10
-10
@@ -195,14 +195,14 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
|
||||
hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
|
||||
|
||||
if (mc->dtb) {
|
||||
fdt = s->fdt = load_device_tree(mc->dtb, &s->fdt_size);
|
||||
fdt = mc->fdt = load_device_tree(mc->dtb, &s->fdt_size);
|
||||
if (!fdt) {
|
||||
error_report("load_device_tree() failed");
|
||||
exit(1);
|
||||
}
|
||||
goto update_bootargs;
|
||||
} else {
|
||||
fdt = s->fdt = create_device_tree(&s->fdt_size);
|
||||
fdt = mc->fdt = create_device_tree(&s->fdt_size);
|
||||
if (!fdt) {
|
||||
error_report("create_device_tree() failed");
|
||||
exit(1);
|
||||
@@ -444,12 +444,12 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
|
||||
g_free(name);
|
||||
|
||||
name = g_strdup_printf("/soc/flash@%" PRIx64, flashbase);
|
||||
qemu_fdt_add_subnode(s->fdt, name);
|
||||
qemu_fdt_setprop_string(s->fdt, name, "compatible", "cfi-flash");
|
||||
qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
|
||||
qemu_fdt_add_subnode(mc->fdt, name);
|
||||
qemu_fdt_setprop_string(mc->fdt, name, "compatible", "cfi-flash");
|
||||
qemu_fdt_setprop_sized_cells(mc->fdt, name, "reg",
|
||||
2, flashbase, 2, flashsize,
|
||||
2, flashbase + flashsize, 2, flashsize);
|
||||
qemu_fdt_setprop_cell(s->fdt, name, "bank-width", 4);
|
||||
qemu_fdt_setprop_cell(mc->fdt, name, "bank-width", 4);
|
||||
g_free(name);
|
||||
|
||||
update_bootargs:
|
||||
@@ -667,9 +667,9 @@ static void virt_machine_init(MachineState *machine)
|
||||
hwaddr end = riscv_load_initrd(machine->initrd_filename,
|
||||
machine->ram_size, kernel_entry,
|
||||
&start);
|
||||
qemu_fdt_setprop_cell(s->fdt, "/chosen",
|
||||
qemu_fdt_setprop_cell(machine->fdt, "/chosen",
|
||||
"linux,initrd-start", start);
|
||||
qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
|
||||
qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end",
|
||||
end);
|
||||
}
|
||||
} else {
|
||||
@@ -690,12 +690,12 @@ static void virt_machine_init(MachineState *machine)
|
||||
|
||||
/* Compute the fdt load address in dram */
|
||||
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
|
||||
machine->ram_size, s->fdt);
|
||||
machine->ram_size, machine->fdt);
|
||||
/* load the reset vector */
|
||||
riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr,
|
||||
virt_memmap[VIRT_MROM].base,
|
||||
virt_memmap[VIRT_MROM].size, kernel_entry,
|
||||
fdt_load_addr, s->fdt);
|
||||
fdt_load_addr, machine->fdt);
|
||||
|
||||
/* SiFive Test MMIO device */
|
||||
sifive_test_create(memmap[VIRT_TEST].base);
|
||||
|
||||
@@ -153,7 +153,6 @@ struct VirtMachineState {
|
||||
MemMapEntry *memmap;
|
||||
char *pciehb_nodename;
|
||||
const int *irqmap;
|
||||
void *fdt;
|
||||
int fdt_size;
|
||||
uint32_t clock_phandle;
|
||||
uint32_t gic_phandle;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user