summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Maydell2020-12-11 14:50:35 +0100
committerPeter Maydell2020-12-11 14:50:35 +0100
commitb785d25e91718a660546a6550f64b3c543af7754 (patch)
treea69f546d903351e4db899b8f080468ff12fe14e0
parentMerge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request... (diff)
parentscripts: kernel-doc: remove unnecessary change wrt Linux (diff)
downloadqemu-b785d25e91718a660546a6550f64b3c543af7754.tar.gz
qemu-b785d25e91718a660546a6550f64b3c543af7754.tar.xz
qemu-b785d25e91718a660546a6550f64b3c543af7754.zip
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
* Fix for NULL segments (Bin Meng) * Support for 32768 CPUs on x86 without IOMMU (David) * PDEP/PEXT fix and testcase (myself) * Remove bios_name and ram_size globals (myself) * qemu_init rationalization (myself) * Update kernel-doc (myself + upstream patches) * Propagate MemTxResult across DMA and PCI functions (Philippe) * Remove master/slave when applicable (Philippe) * WHPX support for in-kernel irqchip (Sunil) # gpg: Signature made Thu 10 Dec 2020 17:21:50 GMT # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini-gitlab/tags/for-upstream: (113 commits) scripts: kernel-doc: remove unnecessary change wrt Linux Revert "docs: temporarily disable the kernel-doc extension" scripts: kernel-doc: use :c:union when needed scripts: kernel-doc: split typedef complex regex scripts: kernel-doc: fix typedef parsing Revert "kernel-doc: Handle function typedefs that return pointers" Revert "kernel-doc: Handle function typedefs without asterisks" scripts: kernel-doc: try to use c:function if possible scripts: kernel-doc: fix line number handling scripts: kernel-doc: allow passing desired Sphinx C domain dialect scripts: kernel-doc: don't mangle with parameter list scripts: kernel-doc: fix typedef identification scripts: kernel-doc: reimplement -nofunction argument scripts: kernel-doc: fix troubles with line counts scripts: kernel-doc: use a less pedantic markup for funcs on Sphinx 3.x scripts: kernel-doc: make it more compatible with Sphinx 3.x Revert "kernel-doc: Use c:struct for Sphinx 3.0 and later" Revert "scripts/kerneldoc: For Sphinx 3 use c:macro for macros with arguments" scripts: kernel-doc: add support for typedef enum kernel-doc: add support for ____cacheline_aligned attribute ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--MAINTAINERS1
-rw-r--r--docs/devel/loads-stores.rst2
-rw-r--r--docs/specs/tpm.rst2
-rw-r--r--docs/sphinx/kerneldoc.py6
-rw-r--r--hw/alpha/dp264.c3
-rw-r--r--hw/arm/aspeed.c8
-rw-r--r--hw/arm/boot.c1
-rw-r--r--hw/arm/cubieboard.c2
-rw-r--r--hw/arm/digic_boards.c20
-rw-r--r--hw/arm/highbank.c9
-rw-r--r--hw/arm/npcm7xx_boards.c6
-rw-r--r--hw/arm/orangepi.c2
-rw-r--r--hw/arm/sbsa-ref.c3
-rw-r--r--hw/arm/spitz.c32
-rw-r--r--hw/arm/stellaris.c4
-rw-r--r--hw/arm/tosa.c12
-rw-r--r--hw/arm/vexpress.c9
-rw-r--r--hw/arm/virt.c3
-rw-r--r--hw/arm/z2.c14
-rw-r--r--hw/avr/boot.c1
-rw-r--r--hw/block/m25p80.c14
-rw-r--r--hw/char/serial.c13
-rw-r--r--hw/core/generic-loader.c3
-rw-r--r--hw/core/loader.c1
-rw-r--r--hw/core/machine.c56
-rw-r--r--hw/core/numa.c10
-rw-r--r--hw/core/stream.c20
-rw-r--r--hw/cris/axis_dev88.c1
-rw-r--r--hw/cris/boot.c2
-rw-r--r--hw/cris/boot.h1
-rw-r--r--hw/display/ads7846.c12
-rw-r--r--hw/display/cg3.c1
-rw-r--r--hw/display/pxa2xx_lcd.c5
-rw-r--r--hw/display/ssd0323.c12
-rw-r--r--hw/display/tcx.c1
-rw-r--r--hw/dma/xilinx_axidma.c58
-rw-r--r--hw/hppa/machine.c14
-rw-r--r--hw/i386/fw_cfg.c2
-rw-r--r--hw/i386/kvm/apic.c7
-rw-r--r--hw/i386/microvm.c7
-rw-r--r--hw/i386/pc.c16
-rw-r--r--hw/i386/pc_sysfw.c4
-rw-r--r--hw/i386/vmport.c3
-rw-r--r--hw/i386/x86.c17
-rw-r--r--hw/i386/xen/xen-hvm.c2
-rw-r--r--hw/intc/apic_common.c3
-rw-r--r--hw/lm32/milkymist.c5
-rw-r--r--hw/m68k/mcf5206.c4
-rw-r--r--hw/m68k/mcf5208.c14
-rw-r--r--hw/m68k/next-cube.c4
-rw-r--r--hw/m68k/q800.c5
-rw-r--r--hw/microblaze/boot.c9
-rw-r--r--hw/mips/fuloong2e.c11
-rw-r--r--hw/mips/jazz.c7
-rw-r--r--hw/mips/malta.c9
-rw-r--r--hw/mips/mipssim.c7
-rw-r--r--hw/misc/max111x.c18
-rw-r--r--hw/moxie/moxiesim.c8
-rw-r--r--hw/net/xilinx_axienet.c44
-rw-r--r--hw/nios2/boot.c9
-rw-r--r--hw/nvram/fw_cfg.c1
-rw-r--r--hw/pci-host/prep.c1
-rw-r--r--hw/pci/pci.c1
-rw-r--r--hw/ppc/e500.c5
-rw-r--r--hw/ppc/mac_newworld.c5
-rw-r--r--hw/ppc/mac_oldworld.c5
-rw-r--r--hw/ppc/pnv.c6
-rw-r--r--hw/ppc/ppc405_boards.c7
-rw-r--r--hw/ppc/ppc440_bamboo.c1
-rw-r--r--hw/ppc/prep.c6
-rw-r--r--hw/ppc/sam460ex.c1
-rw-r--r--hw/ppc/spapr.c11
-rw-r--r--hw/ppc/spapr_vio.c4
-rw-r--r--hw/ppc/virtex_ml507.c1
-rw-r--r--hw/riscv/boot.c6
-rw-r--r--hw/rx/rx-gdbsim.c10
-rw-r--r--hw/rx/rx62n.c9
-rw-r--r--hw/s390x/ipl.c19
-rw-r--r--hw/s390x/s390-skeys.c6
-rw-r--r--hw/s390x/s390-virtio-ccw.c7
-rw-r--r--hw/sd/ssi-sd.c12
-rw-r--r--hw/sh4/shix.c3
-rw-r--r--hw/smbios/smbios.c8
-rw-r--r--hw/sparc/leon3.c5
-rw-r--r--hw/sparc/sun4m.c3
-rw-r--r--hw/sparc64/sparc64.c3
-rw-r--r--hw/sparc64/sun4u.c7
-rw-r--r--hw/ssi/aspeed_smc.c53
-rw-r--r--hw/ssi/pl022.c2
-rw-r--r--hw/ssi/ssi.c48
-rw-r--r--hw/ssi/xilinx_spips.c9
-rw-r--r--hw/virtio/virtio-balloon.c3
-rw-r--r--include/exec/cpu-common.h2
-rw-r--r--include/hw/boards.h2
-rw-r--r--include/hw/i386/x86.h3
-rw-r--r--include/hw/misc/max111x.h2
-rw-r--r--include/hw/pci/pci.h50
-rw-r--r--include/hw/qdev-core.h8
-rw-r--r--include/hw/ssi/aspeed_smc.h2
-rw-r--r--include/hw/ssi/ssi.h56
-rw-r--r--include/hw/ssi/xilinx_spips.h2
-rw-r--r--include/hw/stream.h41
-rw-r--r--include/migration/misc.h1
-rw-r--r--include/qemu-common.h21
-rw-r--r--include/qemu/config-file.h1
-rw-r--r--include/qemu/datadir.h28
-rw-r--r--include/qemu/option.h3
-rw-r--r--include/standard-headers/asm-x86/kvm_para.h1
-rw-r--r--include/sysemu/dma.h117
-rw-r--r--include/sysemu/sysemu.h10
-rw-r--r--include/sysemu/whpx.h22
-rw-r--r--migration/migration.c37
-rw-r--r--monitor/hmp.c18
-rw-r--r--monitor/qmp-cmds.c3
-rw-r--r--python/qemu/machine.py2
-rw-r--r--qemu-options.hx32
-rw-r--r--qom/object.c36
-rwxr-xr-xscripts/kernel-doc455
-rw-r--r--softmmu/cpus.c3
-rw-r--r--softmmu/datadir.c129
-rw-r--r--softmmu/dma-helpers.c7
-rw-r--r--softmmu/meson.build2
-rw-r--r--softmmu/qdev-monitor.c6
-rw-r--r--softmmu/rtc.c190
-rw-r--r--softmmu/vl.c1667
-rw-r--r--target/arm/arm-semi.c3
-rw-r--r--target/i386/cpu.c8
-rw-r--r--target/i386/kvm.c77
-rw-r--r--target/i386/kvm_i386.h2
-rw-r--r--target/i386/meson.build1
-rw-r--r--target/i386/seg_helper.c5
-rw-r--r--target/i386/translate.c8
-rw-r--r--target/i386/whp-dispatch.h9
-rw-r--r--target/i386/whpx-all.c291
-rw-r--r--target/i386/whpx-apic.c274
-rw-r--r--target/m68k/m68k-semi.c5
-rw-r--r--target/s390x/excp_helper.c3
-rw-r--r--target/s390x/mem_helper.c10
-rw-r--r--target/s390x/mmu_helper.c4
-rw-r--r--tests/qtest/bios-tables-test.c4
-rw-r--r--tests/qtest/fuzz/fuzz.c1
-rw-r--r--tests/qtest/pflash-cfi02-test.c4
-rw-r--r--tests/qtest/test-filter-redirector.c8
-rw-r--r--tests/qtest/vhost-user-test.c8
-rw-r--r--tests/tcg/i386/Makefile.target3
-rw-r--r--tests/tcg/i386/test-i386-bmi2.c42
-rw-r--r--tests/test-char.c8
-rw-r--r--tests/test-qemu-opts.c20
-rw-r--r--ui/keymaps.c1
-rw-r--r--util/qemu-config.c33
-rw-r--r--util/qemu-option.c9
151 files changed, 2879 insertions, 1768 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index a83416d54c..aa39490a24 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -452,6 +452,7 @@ WHPX CPUs
M: Sunil Muthuswamy <sunilmut@microsoft.com>
S: Supported
F: target/i386/whpx-all.c
+F: target/i386/whpx-apic.c
F: target/i386/whpx-cpus.c
F: target/i386/whp-dispatch.h
F: accel/stubs/whpx-stub.c
diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst
index 59c1225391..ee43f5dfee 100644
--- a/docs/devel/loads-stores.rst
+++ b/docs/devel/loads-stores.rst
@@ -483,6 +483,8 @@ make sure our existing code is doing things correctly.
Regexes for git grep
- ``\<dma_memory_\(read\|write\|rw\)\>``
+ - ``\<ldu\?[bwlq]\(_[bl]e\)\?_dma\>``
+ - ``\<st[bwlq]\(_[bl]e\)\?_dma\>``
``pci_dma_*`` and ``{ld,st}*_pci_dma``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/specs/tpm.rst b/docs/specs/tpm.rst
index 5e9aef4db3..3be190343a 100644
--- a/docs/specs/tpm.rst
+++ b/docs/specs/tpm.rst
@@ -343,7 +343,7 @@ In case an Arm virt machine is emulated, use the following command line:
-device tpm-tis-device,tpmdev=tpm0 \
-device virtio-blk-pci,drive=drv0 \
-drive format=qcow2,file=hda.qcow2,if=none,id=drv0 \
- -drive if=pflash,format=raw,file=flash0.img,readonly \
+ -drive if=pflash,format=raw,file=flash0.img,readonly=on \
-drive if=pflash,format=raw,file=flash1.img
In case SeaBIOS is used as firmware, it should show the TPM menu item
diff --git a/docs/sphinx/kerneldoc.py b/docs/sphinx/kerneldoc.py
index 3ac277d162..bf44215016 100644
--- a/docs/sphinx/kerneldoc.py
+++ b/docs/sphinx/kerneldoc.py
@@ -69,6 +69,11 @@ class KernelDocDirective(Directive):
env = self.state.document.settings.env
cmd = env.config.kerneldoc_bin + ['-rst', '-enable-lineno']
+ # Pass the version string to kernel-doc, as it needs to use a different
+ # dialect, depending what the C domain supports for each specific
+ # Sphinx versions
+ cmd += ['-sphinx-version', sphinx.__version__]
+
filename = env.config.kerneldoc_srctree + '/' + self.arguments[0]
export_file_patterns = []
@@ -99,7 +104,6 @@ class KernelDocDirective(Directive):
env.note_dependency(os.path.abspath(f))
cmd += ['-export-file', f]
- cmd += ['-sphinx-version', sphinx.__version__]
cmd += [filename]
try:
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index 4d24518d1d..c8e300d93f 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -21,6 +21,7 @@
#include "hw/dma/i8257.h"
#include "net/net.h"
#include "qemu/cutils.h"
+#include "qemu/datadir.h"
#include "net/net.h"
#define MAX_IDE_BUS 2
@@ -107,7 +108,7 @@ static void clipper_init(MachineState *machine)
but one explicitly written for the emulation, we might as
well load it directly from and ELF image. */
palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
- bios_name ? bios_name : "palcode-clipper");
+ machine->firmware ?: "palcode-clipper");
if (palcode_filename == NULL) {
error_report("no palcode provided");
exit(1);
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index bfe2051cfe..a17b75f494 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -309,7 +309,7 @@ static void aspeed_machine_init(MachineState *machine)
/*
* This will error out if isize is not supported by memory controller.
*/
- object_property_set_uint(OBJECT(&bmc->soc), "ram-size", ram_size,
+ object_property_set_uint(OBJECT(&bmc->soc), "ram-size", machine->ram_size,
&error_fatal);
for (i = 0; i < sc->macs_num; i++) {
@@ -346,8 +346,8 @@ static void aspeed_machine_init(MachineState *machine)
max_ram_size = object_property_get_uint(OBJECT(&bmc->soc), "max-ram-size",
&error_abort);
memory_region_init_io(&bmc->max_ram, NULL, &max_ram_ops, NULL,
- "max_ram", max_ram_size - ram_size);
- memory_region_add_subregion(&bmc->ram_container, ram_size, &bmc->max_ram);
+ "max_ram", max_ram_size - machine->ram_size);
+ memory_region_add_subregion(&bmc->ram_container, machine->ram_size, &bmc->max_ram);
aspeed_board_init_flashes(&bmc->soc.fmc, bmc->fmc_model ?
bmc->fmc_model : amc->fmc_model);
@@ -392,7 +392,7 @@ static void aspeed_machine_init(MachineState *machine)
aspeed_board_binfo.smp_loader_start = AST_SMP_MBOX_CODE;
}
- aspeed_board_binfo.ram_size = ram_size;
+ aspeed_board_binfo.ram_size = machine->ram_size;
aspeed_board_binfo.loader_start = sc->memmap[ASPEED_DEV_SDRAM];
aspeed_board_binfo.nb_cpus = sc->num_cpus;
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index cf97600a91..4d9d47ba1c 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -9,6 +9,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include <libfdt.h>
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index 1c6c792eb6..9d0d728180 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -40,7 +40,7 @@ static void cubieboard_init(MachineState *machine)
DeviceState *carddev;
/* BIOS is not supported by this board */
- if (bios_name) {
+ if (machine->firmware) {
error_report("BIOS not supported for this machine");
exit(1);
}
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index d5524d3e72..be12873673 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -26,6 +26,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/boards.h"
#include "exec/address-spaces.h"
@@ -70,19 +71,20 @@ static void digic4_board_init(MachineState *machine, DigicBoard *board)
memory_region_add_subregion(get_system_memory(), 0, machine->ram);
if (board->add_rom0) {
- board->add_rom0(s, DIGIC4_ROM0_BASE, board->rom0_def_filename);
+ board->add_rom0(s, DIGIC4_ROM0_BASE,
+ machine->firmware ?: board->rom0_def_filename);
}
if (board->add_rom1) {
- board->add_rom1(s, DIGIC4_ROM1_BASE, board->rom1_def_filename);
+ board->add_rom1(s, DIGIC4_ROM1_BASE,
+ machine->firmware ?: board->rom1_def_filename);
}
}
static void digic_load_rom(DigicState *s, hwaddr addr,
- hwaddr max_size, const char *def_filename)
+ hwaddr max_size, const char *filename)
{
target_long rom_size;
- const char *filename;
if (qtest_enabled()) {
/* qtest runs no code so don't attempt a ROM load which
@@ -91,12 +93,6 @@ static void digic_load_rom(DigicState *s, hwaddr addr,
return;
}
- if (bios_name) {
- filename = bios_name;
- } else {
- filename = def_filename;
- }
-
if (filename) {
char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
@@ -119,7 +115,7 @@ static void digic_load_rom(DigicState *s, hwaddr addr,
* 64M Bit (4Mx16) Page Mode / Multi-Bank NOR Flash Memory
*/
static void digic4_add_k8p3215uqb_rom(DigicState *s, hwaddr addr,
- const char *def_filename)
+ const char *filename)
{
#define FLASH_K8P3215UQB_SIZE (4 * 1024 * 1024)
#define FLASH_K8P3215UQB_SECTOR_SIZE (64 * 1024)
@@ -131,7 +127,7 @@ static void digic4_add_k8p3215uqb_rom(DigicState *s, hwaddr addr,
0x00EC, 0x007E, 0x0003, 0x0001,
0x0555, 0x2aa, 0);
- digic_load_rom(s, addr, FLASH_K8P3215UQB_SIZE, def_filename);
+ digic_load_rom(s, addr, FLASH_K8P3215UQB_SIZE, filename);
}
static DigicBoard digic4_board_canon_a1100 = {
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index f71087860d..bf7b8f4c64 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
@@ -297,16 +298,16 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
memory_region_init_ram(sysram, NULL, "highbank.sysram", 0x8000,
&error_fatal);
memory_region_add_subregion(sysmem, 0xfff88000, sysram);
- if (bios_name != NULL) {
- sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (machine->firmware != NULL) {
+ sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware);
if (sysboot_filename != NULL) {
if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000) < 0) {
- error_report("Unable to load %s", bios_name);
+ error_report("Unable to load %s", machine->firmware);
exit(1);
}
g_free(sysboot_filename);
} else {
- error_report("Unable to find %s", bios_name);
+ error_report("Unable to find %s", machine->firmware);
exit(1);
}
}
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 79e2e2744c..306260fa67 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -23,6 +23,7 @@
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "sysemu/sysemu.h"
@@ -33,13 +34,10 @@ static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
static void npcm7xx_load_bootrom(MachineState *machine, NPCM7xxState *soc)
{
+ const char *bios_name = machine->firmware ?: npcm7xx_default_bootrom;
g_autofree char *filename = NULL;
int ret;
- if (!bios_name) {
- bios_name = npcm7xx_default_bootrom;
- }
-
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (!filename) {
error_report("Could not find ROM image '%s'", bios_name);
diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
index 17a568a2b4..d6306dfdda 100644
--- a/hw/arm/orangepi.c
+++ b/hw/arm/orangepi.c
@@ -41,7 +41,7 @@ static void orangepi_init(MachineState *machine)
DeviceState *carddev;
/* BIOS is not supported by this board */
- if (bios_name) {
+ if (machine->firmware) {
error_report("BIOS not supported for this machine");
exit(1);
}
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index 4a5ea42938..9f70735153 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/units.h"
@@ -319,6 +320,7 @@ static bool sbsa_firmware_init(SBSAMachineState *sms,
MemoryRegion *sysmem,
MemoryRegion *secure_sysmem)
{
+ const char *bios_name;
int i;
BlockBackend *pflash_blk0;
@@ -332,6 +334,7 @@ static bool sbsa_firmware_init(SBSAMachineState *sms,
pflash_blk0 = pflash_cfi01_get_blk(sms->flash[0]);
+ bios_name = MACHINE(sms)->firmware;
if (bios_name) {
char *fname;
MemoryRegion *mr;
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 772662f149..6b3bf9828b 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -578,7 +578,7 @@ static void spitz_keyboard_realize(DeviceState *dev, Error **errp)
OBJECT_DECLARE_SIMPLE_TYPE(SpitzLCDTG, SPITZ_LCDTG)
struct SpitzLCDTG {
- SSISlave ssidev;
+ SSIPeripheral ssidev;
uint32_t bl_intensity;
uint32_t bl_power;
};
@@ -612,7 +612,7 @@ static inline void spitz_bl_power(void *opaque, int line, int level)
spitz_bl_update(s);
}
-static uint32_t spitz_lcdtg_transfer(SSISlave *dev, uint32_t value)
+static uint32_t spitz_lcdtg_transfer(SSIPeripheral *dev, uint32_t value)
{
SpitzLCDTG *s = SPITZ_LCDTG(dev);
int addr;
@@ -641,7 +641,7 @@ static uint32_t spitz_lcdtg_transfer(SSISlave *dev, uint32_t value)
return 0;
}
-static void spitz_lcdtg_realize(SSISlave *ssi, Error **errp)
+static void spitz_lcdtg_realize(SSIPeripheral *ssi, Error **errp)
{
SpitzLCDTG *s = SPITZ_LCDTG(ssi);
DeviceState *dev = DEVICE(s);
@@ -667,12 +667,12 @@ OBJECT_DECLARE_SIMPLE_TYPE(CorgiSSPState, CORGI_SSP)
/* "Demux" the signal based on current chipselect */
struct CorgiSSPState {
- SSISlave ssidev;
+ SSIPeripheral ssidev;
SSIBus *bus[3];
uint32_t enable[3];
};
-static uint32_t corgi_ssp_transfer(SSISlave *dev, uint32_t value)
+static uint32_t corgi_ssp_transfer(SSIPeripheral *dev, uint32_t value)
{
CorgiSSPState *s = CORGI_SSP(dev);
int i;
@@ -700,7 +700,7 @@ static void corgi_ssp_gpio_cs(void *opaque, int line, int level)
#define SPITZ_BATTERY_VOLT 0xd0 /* About 4.0V */
#define SPITZ_CHARGEON_ACIN 0x80 /* About 5.0V */
-static void corgi_ssp_realize(SSISlave *d, Error **errp)
+static void corgi_ssp_realize(SSIPeripheral *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
CorgiSSPState *s = CORGI_SSP(d);
@@ -715,14 +715,14 @@ static void spitz_ssp_attach(SpitzMachineState *sms)
{
void *bus;
- sms->mux = ssi_create_slave(sms->mpu->ssp[CORGI_SSP_PORT - 1],
- TYPE_CORGI_SSP);
+ sms->mux = ssi_create_peripheral(sms->mpu->ssp[CORGI_SSP_PORT - 1],
+ TYPE_CORGI_SSP);
bus = qdev_get_child_bus(sms->mux, "ssi0");
- sms->lcdtg = ssi_create_slave(bus, TYPE_SPITZ_LCDTG);
+ sms->lcdtg = ssi_create_peripheral(bus, TYPE_SPITZ_LCDTG);
bus = qdev_get_child_bus(sms->mux, "ssi1");
- sms->ads7846 = ssi_create_slave(bus, "ads7846");
+ sms->ads7846 = ssi_create_peripheral(bus, "ads7846");
qdev_connect_gpio_out(sms->ads7846, 0,
qdev_get_gpio_in(sms->mpu->gpio, SPITZ_GPIO_TP_INT));
@@ -1204,7 +1204,7 @@ static const VMStateDescription vmstate_corgi_ssp_regs = {
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(ssidev, CorgiSSPState),
+ VMSTATE_SSI_PERIPHERAL(ssidev, CorgiSSPState),
VMSTATE_UINT32_ARRAY(enable, CorgiSSPState, 3),
VMSTATE_END_OF_LIST(),
}
@@ -1213,7 +1213,7 @@ static const VMStateDescription vmstate_corgi_ssp_regs = {
static void corgi_ssp_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
k->realize = corgi_ssp_realize;
k->transfer = corgi_ssp_transfer;
@@ -1222,7 +1222,7 @@ static void corgi_ssp_class_init(ObjectClass *klass, void *data)
static const TypeInfo corgi_ssp_info = {
.name = TYPE_CORGI_SSP,
- .parent = TYPE_SSI_SLAVE,
+ .parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(CorgiSSPState),
.class_init = corgi_ssp_class_init,
};
@@ -1232,7 +1232,7 @@ static const VMStateDescription vmstate_spitz_lcdtg_regs = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(ssidev, SpitzLCDTG),
+ VMSTATE_SSI_PERIPHERAL(ssidev, SpitzLCDTG),
VMSTATE_UINT32(bl_intensity, SpitzLCDTG),
VMSTATE_UINT32(bl_power, SpitzLCDTG),
VMSTATE_END_OF_LIST(),
@@ -1242,7 +1242,7 @@ static const VMStateDescription vmstate_spitz_lcdtg_regs = {
static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
k->realize = spitz_lcdtg_realize;
k->transfer = spitz_lcdtg_transfer;
@@ -1251,7 +1251,7 @@ static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
static const TypeInfo spitz_lcdtg_info = {
.name = TYPE_SPITZ_LCDTG,
- .parent = TYPE_SSI_SLAVE,
+ .parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(SpitzLCDTG),
.class_init = spitz_lcdtg_class_init,
};
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 1237f5af02..652823195b 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1397,8 +1397,8 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
*/
bus = qdev_get_child_bus(dev, "ssi");
- sddev = ssi_create_slave(bus, "ssi-sd");
- ssddev = ssi_create_slave(bus, "ssd0323");
+ sddev = ssi_create_peripheral(bus, "ssi-sd");
+ ssddev = ssi_create_peripheral(bus, "ssd0323");
gpio_out[GPIO_D][0] = qemu_irq_split(
qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 66b244aeff..d5a6763cf9 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -148,13 +148,13 @@ static void tosa_gpio_setup(PXA2xxState *cpu,
qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_USB_IN));
}
-static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
+static uint32_t tosa_ssp_tansfer(SSIPeripheral *dev, uint32_t value)
{
fprintf(stderr, "TG: %u %02x\n", value >> 5, value & 0x1f);
return 0;
}
-static void tosa_ssp_realize(SSISlave *dev, Error **errp)
+static void tosa_ssp_realize(SSIPeripheral *dev, Error **errp)
{
/* Nothing to do. */
}
@@ -225,7 +225,7 @@ static void tosa_tg_init(PXA2xxState *cpu)
{
I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
i2c_slave_create_simple(bus, TYPE_TOSA_DAC, DAC_BASE);
- ssi_create_slave(cpu->ssp[1], "tosa-ssp");
+ ssi_create_peripheral(cpu->ssp[1], "tosa-ssp");
}
@@ -292,7 +292,7 @@ static const TypeInfo tosa_dac_info = {
static void tosa_ssp_class_init(ObjectClass *klass, void *data)
{
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
k->realize = tosa_ssp_realize;
k->transfer = tosa_ssp_tansfer;
@@ -300,8 +300,8 @@ static void tosa_ssp_class_init(ObjectClass *klass, void *data)
static const TypeInfo tosa_ssp_info = {
.name = "tosa-ssp",
- .parent = TYPE_SSI_SLAVE,
- .instance_size = sizeof(SSISlave),
+ .parent = TYPE_SSI_PERIPHERAL,
+ .instance_size = sizeof(SSIPeripheral),
.class_init = tosa_ssp_class_init,
};
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 531f3a122a..ac098375c1 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/sysbus.h"
#include "hw/arm/boot.h"
@@ -560,7 +561,7 @@ static void vexpress_common_init(MachineState *machine)
/*
* If a bios file was provided, attempt to map it into memory
*/
- if (bios_name) {
+ if (machine->firmware) {
char *fn;
int image_size;
@@ -570,16 +571,16 @@ static void vexpress_common_init(MachineState *machine)
"but you cannot use both options at once");
exit(1);
}
- fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware);
if (!fn) {
- error_report("Could not find ROM image '%s'", bios_name);
+ error_report("Could not find ROM image '%s'", machine->firmware);
exit(1);
}
image_size = load_image_targphys(fn, map[VE_NORFLASH0],
VEXPRESS_FLASH_SIZE);
g_free(fn);
if (image_size < 0) {
- error_report("Could not load ROM image '%s'", bios_name);
+ error_report("Could not load ROM image '%s'", machine->firmware);
exit(1);
}
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 22572c32b7..556592012e 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -30,6 +30,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qemu/option.h"
#include "monitor/qdev.h"
@@ -1047,6 +1048,7 @@ static bool virt_firmware_init(VirtMachineState *vms,
MemoryRegion *secure_sysmem)
{
int i;
+ const char *bios_name;
BlockBackend *pflash_blk0;
/* Map legacy -drive if=pflash to machine properties */
@@ -1059,6 +1061,7 @@ static bool virt_firmware_init(VirtMachineState *vms,
pflash_blk0 = pflash_cfi01_get_blk(vms->flash[0]);
+ bios_name = MACHINE(vms)->firmware;
if (bios_name) {
char *fname;
MemoryRegion *mr;
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 4fc5699dae..308c4da956 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -104,7 +104,7 @@ static struct arm_boot_info z2_binfo = {
#define Z2_GPIO_LCD_CS 88
struct ZipitLCD {
- SSISlave ssidev;
+ SSIPeripheral ssidev;
int32_t selected;
int32_t enabled;
uint8_t buf[3];
@@ -115,7 +115,7 @@ struct ZipitLCD {
#define TYPE_ZIPIT_LCD "zipit-lcd"
OBJECT_DECLARE_SIMPLE_TYPE(ZipitLCD, ZIPIT_LCD)
-static uint32_t zipit_lcd_transfer(SSISlave *dev, uint32_t value)
+static uint32_t zipit_lcd_transfer(SSIPeripheral *dev, uint32_t value)
{
ZipitLCD *z = ZIPIT_LCD(dev);
uint16_t val;
@@ -155,7 +155,7 @@ static void z2_lcd_cs(void *opaque, int line, int level)
z2_lcd->selected = !level;
}
-static void zipit_lcd_realize(SSISlave *dev, Error **errp)
+static void zipit_lcd_realize(SSIPeripheral *dev, Error **errp)
{
ZipitLCD *z = ZIPIT_LCD(dev);
z->selected = 0;
@@ -168,7 +168,7 @@ static VMStateDescription vmstate_zipit_lcd_state = {
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(ssidev, ZipitLCD),
+ VMSTATE_SSI_PERIPHERAL(ssidev, ZipitLCD),
VMSTATE_INT32(selected, ZipitLCD),
VMSTATE_INT32(enabled, ZipitLCD),
VMSTATE_BUFFER(buf, ZipitLCD),
@@ -181,7 +181,7 @@ static VMStateDescription vmstate_zipit_lcd_state = {
static void zipit_lcd_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
k->realize = zipit_lcd_realize;
k->transfer = zipit_lcd_transfer;
@@ -190,7 +190,7 @@ static void zipit_lcd_class_init(ObjectClass *klass, void *data)
static const TypeInfo zipit_lcd_info = {
.name = TYPE_ZIPIT_LCD,
- .parent = TYPE_SSI_SLAVE,
+ .parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(ZipitLCD),
.class_init = zipit_lcd_class_init,
};
@@ -329,7 +329,7 @@ static void z2_init(MachineState *machine)
type_register_static(&zipit_lcd_info);
type_register_static(&aer915_info);
- z2_lcd = ssi_create_slave(mpu->ssp[1], TYPE_ZIPIT_LCD);
+ z2_lcd = ssi_create_peripheral(mpu->ssp[1], TYPE_ZIPIT_LCD);
bus = pxa2xx_i2c_bus(mpu->i2c[0]);
i2c_slave_create_simple(bus, TYPE_AER915, 0x55);
wm = DEVICE(i2c_slave_create_simple(bus, TYPE_WM8750, 0x1b));
diff --git a/hw/avr/boot.c b/hw/avr/boot.c
index d16bb3dbe1..cbede775ce 100644
--- a/hw/avr/boot.c
+++ b/hw/avr/boot.c
@@ -10,6 +10,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "hw/loader.h"
#include "elf.h"
#include "boot.h"
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 483925f57a..d09a811767 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -416,7 +416,7 @@ typedef enum {
#define M25P80_INTERNAL_DATA_BUFFER_SZ 16
struct Flash {
- SSISlave parent_obj;
+ SSIPeripheral parent_obj;
BlockBackend *blk;
@@ -458,7 +458,7 @@ struct Flash {
};
struct M25P80Class {
- SSISlaveClass parent_class;
+ SSIPeripheralClass parent_class;
FlashPartInfo *pi;
};
@@ -1170,7 +1170,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
}
}
-static int m25p80_cs(SSISlave *ss, bool select)
+static int m25p80_cs(SSIPeripheral *ss, bool select)
{
Flash *s = M25P80(ss);
@@ -1190,7 +1190,7 @@ static int m25p80_cs(SSISlave *ss, bool select)
return 0;
}
-static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
+static uint32_t m25p80_transfer8(SSIPeripheral *ss, uint32_t tx)
{
Flash *s = M25P80(ss);
uint32_t r = 0;
@@ -1265,7 +1265,7 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
return r;
}
-static void m25p80_realize(SSISlave *ss, Error **errp)
+static void m25p80_realize(SSIPeripheral *ss, Error **errp)
{
Flash *s = M25P80(ss);
M25P80Class *mc = M25P80_GET_CLASS(s);
@@ -1386,7 +1386,7 @@ static const VMStateDescription vmstate_m25p80 = {
static void m25p80_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
M25P80Class *mc = M25P80_CLASS(klass);
k->realize = m25p80_realize;
@@ -1401,7 +1401,7 @@ static void m25p80_class_init(ObjectClass *klass, void *data)
static const TypeInfo m25p80_info = {
.name = TYPE_M25P80,
- .parent = TYPE_SSI_SLAVE,
+ .parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(Flash),
.class_size = sizeof(M25P80Class),
.abstract = true,
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 97f71879ff..62c627f486 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -24,6 +24,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/bitops.h"
#include "hw/char/serial.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
@@ -338,11 +339,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
default:
case 0:
if (s->lcr & UART_LCR_DLAB) {
- if (size == 1) {
- s->divider = (s->divider & 0xff00) | val;
- } else {
- s->divider = val;
- }
+ s->divider = deposit32(s->divider, 8 * addr, 8, val);
serial_update_parameters(s);
} else {
s->thr = (uint8_t) val;
@@ -364,7 +361,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
break;
case 1:
if (s->lcr & UART_LCR_DLAB) {
- s->divider = (s->divider & 0x00ff) | (val << 8);
+ s->divider = deposit32(s->divider, 8 * addr, 8, val);
serial_update_parameters(s);
} else {
uint8_t changed = (s->ier ^ val) & 0x0f;
@@ -478,7 +475,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
default:
case 0:
if (s->lcr & UART_LCR_DLAB) {
- ret = s->divider & 0xff;
+ ret = extract16(s->divider, 8 * addr, 8);
} else {
if(s->fcr & UART_FCR_FE) {
ret = fifo8_is_empty(&s->recv_fifo) ?
@@ -502,7 +499,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
break;
case 1:
if (s->lcr & UART_LCR_DLAB) {
- ret = (s->divider >> 8) & 0xff;
+ ret = extract16(s->divider, 8 * addr, 8);
} else {
ret = s->ier;
}
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
index a242c076f6..2b2a7b5e9a 100644
--- a/hw/core/generic-loader.c
+++ b/hw/core/generic-loader.c
@@ -35,6 +35,7 @@
#include "hw/sysbus.h"
#include "sysemu/dma.h"
#include "sysemu/reset.h"
+#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
@@ -154,7 +155,7 @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
if (size < 0 || s->force_raw) {
/* Default to the maximum size being the machine's ram size */
- size = load_image_targphys_as(s->file, s->addr, ram_size, as);
+ size = load_image_targphys_as(s->file, s->addr, current_machine->ram_size, as);
} else {
s->addr = entry;
}
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 8bbb1797a4..fea22d265c 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -44,6 +44,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qapi/error.h"
#include "trace.h"
#include "hw/hw.h"
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 9c41b94e0d..d7f8fdee45 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -877,9 +877,13 @@ static void machine_initfn(Object *obj)
MachineState *ms = MACHINE(obj);
MachineClass *mc = MACHINE_GET_CLASS(obj);
+ container_get(obj, "/peripheral");
+ container_get(obj, "/peripheral-anon");
+
ms->dump_guest_core = true;
ms->mem_merge = true;
ms->enable_graphics = true;
+ ms->kernel_cmdline = g_strdup("");
if (mc->nvdimm_supported) {
Object *obj = OBJECT(ms);
@@ -1077,12 +1081,40 @@ MemoryRegion *machine_consume_memdev(MachineState *machine,
return ret;
}
+bool machine_smp_parse(MachineState *ms, QemuOpts *opts, Error **errp)
+{
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+
+ mc->smp_parse(ms, opts);
+
+ /* sanity-check smp_cpus and max_cpus against mc */
+ if (ms->smp.cpus < mc->min_cpus) {
+ error_setg(errp, "Invalid SMP CPUs %d. The min CPUs "
+ "supported by machine '%s' is %d",
+ ms->smp.cpus,
+ mc->name, mc->min_cpus);
+ return false;
+ } else if (ms->smp.max_cpus > mc->max_cpus) {
+ error_setg(errp, "Invalid SMP CPUs %d. The max CPUs "
+ "supported by machine '%s' is %d",
+ current_machine->smp.max_cpus,
+ mc->name, mc->max_cpus);
+ return false;
+ }
+ return true;
+}
+
void machine_run_board_init(MachineState *machine)
{
MachineClass *machine_class = MACHINE_GET_CLASS(machine);
ObjectClass *oc = object_class_by_name(machine->cpu_type);
CPUClass *cc;
+ /* This checkpoint is required by replay to separate prior clock
+ reading from the other reads, because timer polling functions query
+ clock values from the log. */
+ replay_checkpoint(CHECKPOINT_INIT);
+
if (machine->ram_memdev_id) {
Object *o;
o = object_resolve_path_type(machine->ram_memdev_id,
@@ -1137,6 +1169,30 @@ void machine_run_board_init(MachineState *machine)
machine_class->init(machine);
}
+static NotifierList machine_init_done_notifiers =
+ NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
+
+bool machine_init_done;
+
+void qemu_add_machine_init_done_notifier(Notifier *notify)
+{
+ notifier_list_add(&machine_init_done_notifiers, notify);
+ if (machine_init_done) {
+ notify->notify(notify, NULL);
+ }
+}
+
+void qemu_remove_machine_init_done_notifier(Notifier *notify)
+{
+ notifier_remove(notify);
+}
+
+void qemu_run_machine_init_done_notifiers(void)
+{
+ machine_init_done = true;
+ notifier_list_notify(&machine_init_done_notifiers, NULL);
+}
+
static const TypeInfo machine_info = {
.name = TYPE_MACHINE,
.parent = TYPE_OBJECT,
diff --git a/hw/core/numa.c b/hw/core/numa.c
index 7c4dd4e68e..68cee65f61 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -642,7 +642,7 @@ void numa_complete_configuration(MachineState *ms)
/*
* If memory hotplug is enabled (slot > 0) or memory devices are enabled
- * (ms->maxram_size > ram_size) but without '-numa' options explicitly on
+ * (ms->maxram_size > ms->ram_size) but without '-numa' options explicitly on
* CLI, guests will break.
*
* Windows: won't enable memory hotplug without SRAT table at all
@@ -663,7 +663,7 @@ void numa_complete_configuration(MachineState *ms)
mc->auto_enable_numa)) {
NumaNodeOptions node = { };
parse_numa_node(ms, &node, &error_abort);
- numa_info[0].node_mem = ram_size;
+ numa_info[0].node_mem = ms->ram_size;
}
assert(max_numa_nodeid <= MAX_NODES);
@@ -687,10 +687,10 @@ void numa_complete_configuration(MachineState *ms)
for (i = 0; i < ms->numa_state->num_nodes; i++) {
numa_total += numa_info[i].node_mem;
}
- if (numa_total != ram_size) {
+ if (numa_total != ms->ram_size) {
error_report("total memory for NUMA nodes (0x%" PRIx64 ")"
" should equal RAM size (0x" RAM_ADDR_FMT ")",
- numa_total, ram_size);
+ numa_total, ms->ram_size);
exit(1);
}
@@ -702,7 +702,7 @@ void numa_complete_configuration(MachineState *ms)
}
ms->ram = g_new(MemoryRegion, 1);
memory_region_init(ms->ram, OBJECT(ms), mc->default_ram_id,
- ram_size);
+ ms->ram_size);
numa_init_memdev_container(ms, ms->ram);
}
/* QEMU needs at least all unique node pair distances to build
diff --git a/hw/core/stream.c b/hw/core/stream.c
index a65ad1208d..19477d0f2d 100644
--- a/hw/core/stream.c
+++ b/hw/core/stream.c
@@ -3,32 +3,32 @@
#include "qemu/module.h"
size_t
-stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop)
+stream_push(StreamSink *sink, uint8_t *buf, size_t len, bool eop)
{
- StreamSlaveClass *k = STREAM_SLAVE_GET_CLASS(sink);
+ StreamSinkClass *k = STREAM_SINK_GET_CLASS(sink);
return k->push(sink, buf, len, eop);
}
bool
-stream_can_push(StreamSlave *sink, StreamCanPushNotifyFn notify,
+stream_can_push(StreamSink *sink, StreamCanPushNotifyFn notify,
void *notify_opaque)
{
- StreamSlaveClass *k = STREAM_SLAVE_GET_CLASS(sink);
+ StreamSinkClass *k = STREAM_SINK_GET_CLASS(sink);
return k->can_push ? k->can_push(sink, notify, notify_opaque) : true;
}
-static const TypeInfo stream_slave_info = {
- .name = TYPE_STREAM_SLAVE,
+static const TypeInfo stream_sink_info = {
+ .name = TYPE_STREAM_SINK,
.parent = TYPE_INTERFACE,
- .class_size = sizeof(StreamSlaveClass),
+ .class_size = sizeof(StreamSinkClass),
};
-static void stream_slave_register_types(void)
+static void stream_sink_register_types(void)
{
- type_register_static(&stream_slave_info);
+ type_register_static(&stream_sink_info);
}
-type_init(stream_slave_register_types)
+type_init(stream_sink_register_types)
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index dab7423c73..b0cb6d84af 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -333,6 +333,7 @@ void axisdev88_init(MachineState *machine)
if (kernel_filename) {
li.image_filename = kernel_filename;
li.cmdline = kernel_cmdline;
+ li.ram_size = machine->ram_size;
cris_load_image(cpu, &li);
} else if (!qtest_enabled()) {
fprintf(stderr, "Kernel image must be specified\n");
diff --git a/hw/cris/boot.c b/hw/cris/boot.c
index aa8d2756d6..9fa09cfd83 100644
--- a/hw/cris/boot.c
+++ b/hw/cris/boot.c
@@ -81,7 +81,7 @@ void cris_load_image(CRISCPU *cpu, struct cris_load_info *li)
if (image_size < 0) {
/* Takes a kimage from the axis devboard SDK. */
image_size = load_image_targphys(li->image_filename, 0x40004000,
- ram_size);
+ li->ram_size);
li->entry = 0x40004000;
}
diff --git a/hw/cris/boot.h b/hw/cris/boot.h
index 218854e5d1..9f1e0e340c 100644
--- a/hw/cris/boot.h
+++ b/hw/cris/boot.h
@@ -6,6 +6,7 @@ struct cris_load_info
const char *image_filename;
const char *cmdline;
int image_size;
+ ram_addr_t ram_size;
hwaddr entry;
};
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index cb3a431cfd..1d4e04a2dc 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -19,7 +19,7 @@
#include "qom/object.h"
struct ADS7846State {
- SSISlave ssidev;
+ SSIPeripheral ssidev;
qemu_irq interrupt;
int input[8];
@@ -63,7 +63,7 @@ static void ads7846_int_update(ADS7846State *s)
qemu_set_irq(s->interrupt, s->pressure == 0);
}
-static uint32_t ads7846_transfer(SSISlave *dev, uint32_t value)
+static uint32_t ads7846_transfer(SSIPeripheral *dev, uint32_t value)
{
ADS7846State *s = ADS7846(dev);
@@ -131,7 +131,7 @@ static const VMStateDescription vmstate_ads7846 = {
.minimum_version_id = 1,
.post_load = ads7856_post_load,
.fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(ssidev, ADS7846State),
+ VMSTATE_SSI_PERIPHERAL(ssidev, ADS7846State),
VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
VMSTATE_INT32(noise, ADS7846State),
VMSTATE_INT32(cycle, ADS7846State),
@@ -140,7 +140,7 @@ static const VMStateDescription vmstate_ads7846 = {
}
};
-static void ads7846_realize(SSISlave *d, Error **errp)
+static void ads7846_realize(SSIPeripheral *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
ADS7846State *s = ADS7846(d);
@@ -164,7 +164,7 @@ static void ads7846_realize(SSISlave *d, Error **errp)
static void ads7846_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
k->realize = ads7846_realize;
k->transfer = ads7846_transfer;
@@ -173,7 +173,7 @@ static void ads7846_class_init(ObjectClass *klass, void *data)
static const TypeInfo ads7846_info = {
.name = TYPE_ADS7846,
- .parent = TYPE_SSI_SLAVE,
+ .parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(ADS7846State),
.class_init = ads7846_class_init,
};
diff --git a/hw/display/cg3.c b/hw/display/cg3.c
index 42fcf40010..4b7e78d919 100644
--- a/hw/display/cg3.c
+++ b/hw/display/cg3.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "ui/console.h"
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
index ff90104b80..dfff994962 100644
--- a/hw/display/pxa2xx_lcd.c
+++ b/hw/display/pxa2xx_lcd.c
@@ -17,6 +17,7 @@
#include "ui/console.h"
#include "hw/arm/pxa.h"
#include "ui/pixel_ops.h"
+#include "hw/boards.h"
/* FIXME: For graphic_rotate. Should probably be done in common code. */
#include "sysemu/sysemu.h"
#include "framebuffer.h"
@@ -305,7 +306,7 @@ static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
descptr = s->dma_ch[i].descriptor;
if (!((descptr >= PXA2XX_SDRAM_BASE && descptr +
- sizeof(desc) <= PXA2XX_SDRAM_BASE + ram_size) ||
+ sizeof(desc) <= PXA2XX_SDRAM_BASE + current_machine->ram_size) ||
(descptr >= PXA2XX_INTERNAL_BASE && descptr + sizeof(desc) <=
PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
continue;
@@ -850,7 +851,7 @@ static void pxa2xx_update_display(void *opaque)
}
fbptr = s->dma_ch[ch].source;
if (!((fbptr >= PXA2XX_SDRAM_BASE &&
- fbptr <= PXA2XX_SDRAM_BASE + ram_size) ||
+ fbptr <= PXA2XX_SDRAM_BASE + current_machine->ram_size) ||
(fbptr >= PXA2XX_INTERNAL_BASE &&
fbptr <= PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
pxa2xx_dma_ber_set(s, ch);
diff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c
index cbfd21dfd5..ab229d32b7 100644
--- a/hw/display/ssd0323.c
+++ b/hw/display/ssd0323.c
@@ -49,7 +49,7 @@ enum ssd0323_mode
};
struct ssd0323_state {
- SSISlave ssidev;
+ SSIPeripheral ssidev;
QemuConsole *con;
uint32_t cmd_len;
@@ -71,7 +71,7 @@ struct ssd0323_state {
OBJECT_DECLARE_SIMPLE_TYPE(ssd0323_state, SSD0323)
-static uint32_t ssd0323_transfer(SSISlave *dev, uint32_t data)
+static uint32_t ssd0323_transfer(SSIPeripheral *dev, uint32_t data)
{
ssd0323_state *s = SSD0323(dev);
@@ -338,7 +338,7 @@ static const VMStateDescription vmstate_ssd0323 = {
VMSTATE_INT32(remap, ssd0323_state),
VMSTATE_UINT32(mode, ssd0323_state),
VMSTATE_BUFFER(framebuffer, ssd0323_state),
- VMSTATE_SSI_SLAVE(ssidev, ssd0323_state),
+ VMSTATE_SSI_PERIPHERAL(ssidev, ssd0323_state),
VMSTATE_END_OF_LIST()
}
};
@@ -348,7 +348,7 @@ static const GraphicHwOps ssd0323_ops = {
.gfx_update = ssd0323_update_display,
};
-static void ssd0323_realize(SSISlave *d, Error **errp)
+static void ssd0323_realize(SSIPeripheral *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
ssd0323_state *s = SSD0323(d);
@@ -364,7 +364,7 @@ static void ssd0323_realize(SSISlave *d, Error **errp)
static void ssd0323_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
k->realize = ssd0323_realize;
k->transfer = ssd0323_transfer;
@@ -375,7 +375,7 @@ static void ssd0323_class_init(ObjectClass *klass, void *data)
static const TypeInfo ssd0323_info = {
.name = TYPE_SSD0323,
- .parent = TYPE_SSI_SLAVE,
+ .parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(ssd0323_state),
.class_init = ssd0323_class_init,
};
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
index 3799d29b75..965f92ff6b 100644
--- a/hw/display/tcx.c
+++ b/hw/display/tcx.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qapi/error.h"
#include "ui/console.h"
#include "ui/pixel_ops.h"
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 0a7f5acb4b..bc383f53cc 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -45,11 +45,11 @@
OBJECT_DECLARE_SIMPLE_TYPE(XilinxAXIDMA, XILINX_AXI_DMA)
-typedef struct XilinxAXIDMAStreamSlave XilinxAXIDMAStreamSlave;
-DECLARE_INSTANCE_CHECKER(XilinxAXIDMAStreamSlave, XILINX_AXI_DMA_DATA_STREAM,
+typedef struct XilinxAXIDMAStreamSink XilinxAXIDMAStreamSink;
+DECLARE_INSTANCE_CHECKER(XilinxAXIDMAStreamSink, XILINX_AXI_DMA_DATA_STREAM,
TYPE_XILINX_AXI_DMA_DATA_STREAM)
-DECLARE_INSTANCE_CHECKER(XilinxAXIDMAStreamSlave, XILINX_AXI_DMA_CONTROL_STREAM,
+DECLARE_INSTANCE_CHECKER(XilinxAXIDMAStreamSink, XILINX_AXI_DMA_CONTROL_STREAM,
TYPE_XILINX_AXI_DMA_CONTROL_STREAM)
#define R_DMACR (0x00 / 4)
@@ -115,7 +115,7 @@ struct Stream {
unsigned char txbuf[16 * 1024];
};
-struct XilinxAXIDMAStreamSlave {
+struct XilinxAXIDMAStreamSink {
Object parent;
struct XilinxAXIDMA *dma;
@@ -128,10 +128,10 @@ struct XilinxAXIDMA {
AddressSpace as;
uint32_t freqhz;
- StreamSlave *tx_data_dev;
- StreamSlave *tx_control_dev;
- XilinxAXIDMAStreamSlave rx_data_dev;
- XilinxAXIDMAStreamSlave rx_control_dev;
+ StreamSink *tx_data_dev;
+ StreamSink *tx_control_dev;
+ XilinxAXIDMAStreamSink rx_data_dev;
+ XilinxAXIDMAStreamSink rx_control_dev;
struct Stream streams[2];
@@ -261,8 +261,8 @@ static void stream_complete(struct Stream *s)
ptimer_transaction_commit(s->ptimer);
}
-static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
- StreamSlave *tx_control_dev)
+static void stream_process_mem2s(struct Stream *s, StreamSink *tx_data_dev,
+ StreamSink *tx_control_dev)
{
uint32_t prev_d;
uint32_t txlen;
@@ -384,10 +384,10 @@ static void xilinx_axidma_reset(DeviceState *dev)
}
static size_t
-xilinx_axidma_control_stream_push(StreamSlave *obj, unsigned char *buf,
+xilinx_axidma_control_stream_push(StreamSink *obj, unsigned char *buf,
size_t len, bool eop)
{
- XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(obj);
+ XilinxAXIDMAStreamSink *cs = XILINX_AXI_DMA_CONTROL_STREAM(obj);
struct Stream *s = &cs->dma->streams[1];
if (len != CONTROL_PAYLOAD_SIZE) {
@@ -400,11 +400,11 @@ xilinx_axidma_control_stream_push(StreamSlave *obj, unsigned char *buf,
}
static bool
-xilinx_axidma_data_stream_can_push(StreamSlave *obj,
+xilinx_axidma_data_stream_can_push(StreamSink *obj,
StreamCanPushNotifyFn notify,
void *notify_opaque)
{
- XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
+ XilinxAXIDMAStreamSink *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
struct Stream *s = &ds->dma->streams[1];
if (!stream_running(s) || stream_idle(s)) {
@@ -417,10 +417,10 @@ xilinx_axidma_data_stream_can_push(StreamSlave *obj,
}
static size_t
-xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len,
+xilinx_axidma_data_stream_push(StreamSink *obj, unsigned char *buf, size_t len,
bool eop)
{
- XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
+ XilinxAXIDMAStreamSink *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
struct Stream *s = &ds->dma->streams[1];
size_t ret;
@@ -531,8 +531,8 @@ static const MemoryRegionOps axidma_ops = {
static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
{
XilinxAXIDMA *s = XILINX_AXI_DMA(dev);
- XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev);
- XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
+ XilinxAXIDMAStreamSink *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev);
+ XilinxAXIDMAStreamSink *cs = XILINX_AXI_DMA_CONTROL_STREAM(
&s->rx_control_dev);
int i;
@@ -588,9 +588,9 @@ static void xilinx_axidma_init(Object *obj)
static Property axidma_properties[] = {
DEFINE_PROP_UINT32("freqhz", XilinxAXIDMA, freqhz, 50000000),
DEFINE_PROP_LINK("axistream-connected", XilinxAXIDMA,
- tx_data_dev, TYPE_STREAM_SLAVE, StreamSlave *),
+ tx_data_dev, TYPE_STREAM_SINK, StreamSink *),
DEFINE_PROP_LINK("axistream-control-connected", XilinxAXIDMA,
- tx_control_dev, TYPE_STREAM_SLAVE, StreamSlave *),
+ tx_control_dev, TYPE_STREAM_SINK, StreamSink *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -603,21 +603,21 @@ static void axidma_class_init(ObjectClass *klass, void *data)
device_class_set_props(dc, axidma_properties);
}
-static StreamSlaveClass xilinx_axidma_data_stream_class = {
+static StreamSinkClass xilinx_axidma_data_stream_class = {
.push = xilinx_axidma_data_stream_push,
.can_push = xilinx_axidma_data_stream_can_push,
};
-static StreamSlaveClass xilinx_axidma_control_stream_class = {
+static StreamSinkClass xilinx_axidma_control_stream_class = {
.push = xilinx_axidma_control_stream_push,
};
static void xilinx_axidma_stream_class_init(ObjectClass *klass, void *data)
{
- StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
+ StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
- ssc->push = ((StreamSlaveClass *)data)->push;
- ssc->can_push = ((StreamSlaveClass *)data)->can_push;
+ ssc->push = ((StreamSinkClass *)data)->push;
+ ssc->can_push = ((StreamSinkClass *)data)->can_push;
}
static const TypeInfo axidma_info = {
@@ -631,11 +631,11 @@ static const TypeInfo axidma_info = {
static const TypeInfo xilinx_axidma_data_stream_info = {
.name = TYPE_XILINX_AXI_DMA_DATA_STREAM,
.parent = TYPE_OBJECT,
- .instance_size = sizeof(XilinxAXIDMAStreamSlave),
+ .instance_size = sizeof(XilinxAXIDMAStreamSink),
.class_init = xilinx_axidma_stream_class_init,
.class_data = &xilinx_axidma_data_stream_class,
.interfaces = (InterfaceInfo[]) {
- { TYPE_STREAM_SLAVE },
+ { TYPE_STREAM_SINK },
{ }
}
};
@@ -643,11 +643,11 @@ static const TypeInfo xilinx_axidma_data_stream_info = {
static const TypeInfo xilinx_axidma_control_stream_info = {
.name = TYPE_XILINX_AXI_DMA_CONTROL_STREAM,
.parent = TYPE_OBJECT,
- .instance_size = sizeof(XilinxAXIDMAStreamSlave),
+ .instance_size = sizeof(XilinxAXIDMAStreamSink),
.class_init = xilinx_axidma_stream_class_init,
.class_data = &xilinx_axidma_control_stream_class,
.interfaces = (InterfaceInfo[]) {
- { TYPE_STREAM_SLAVE },
+ { TYPE_STREAM_SINK },
{ }
}
};
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index d5164457ee..f2b71db9bd 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -5,6 +5,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "elf.h"
#include "hw/loader.h"
@@ -97,7 +98,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms)
fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4);
fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus);
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS);
- fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ram_size);
+ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ms->ram_size);
val = cpu_to_le64(MIN_SEABIOS_HPPA_VERSION);
fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version",
@@ -213,8 +214,7 @@ static void machine_hppa_init(MachineState *machine)
but one explicitly written for the emulation, we might as
well load it directly from an ELF image. */
firmware_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
- bios_name ? bios_name :
- "hppa-firmware.img");
+ machine->firmware ?: "hppa-firmware.img");
if (firmware_filename == NULL) {
error_report("no firmware provided");
exit(1);
@@ -289,7 +289,7 @@ static void machine_hppa_init(MachineState *machine)
(1) Due to sign-extension problems and PDC,
put the initrd no higher than 1G.
(2) Reserve 64k for stack. */
- initrd_base = MIN(ram_size, 1 * GiB);
+ initrd_base = MIN(machine->ram_size, 1 * GiB);
initrd_base = initrd_base - 64 * KiB;
initrd_base = (initrd_base - initrd_size) & TARGET_PAGE_MASK;
@@ -317,7 +317,7 @@ static void machine_hppa_init(MachineState *machine)
* various parameters in registers. After firmware initialization,
* firmware will start the Linux kernel with ramdisk and cmdline.
*/
- cpu[0]->env.gr[26] = ram_size;
+ cpu[0]->env.gr[26] = machine->ram_size;
cpu[0]->env.gr[25] = kernel_entry;
/* tell firmware how many SMP CPUs to present in inventory table */
@@ -343,11 +343,11 @@ static void hppa_machine_reset(MachineState *ms)
}
/* already initialized by machine_hppa_init()? */
- if (cpu[0]->env.gr[26] == ram_size) {
+ if (cpu[0]->env.gr[26] == ms->ram_size) {
return;
}
- cpu[0]->env.gr[26] = ram_size;
+ cpu[0]->env.gr[26] = ms->ram_size;
cpu[0]->env.gr[25] = 0; /* no firmware boot menu */
cpu[0]->env.gr[24] = 'c';
/* gr22/gr23 unused, no initrd while reboot. */
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index e06579490c..b87f0e5070 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -118,7 +118,7 @@ FWCfgState *fw_cfg_arch_create(MachineState *ms,
* "etc/max-cpus" actually being apic_id_limit
*/
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, apic_id_limit);
- fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ms->ram_size);
#ifdef CONFIG_ACPI
fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
acpi_tables, acpi_tables_len);
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index dd29906061..b226b674e8 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -183,6 +183,13 @@ static void kvm_send_msi(MSIMessage *msg)
{
int ret;
+ /*
+ * The message has already passed through interrupt remapping if enabled,
+ * but the legacy extended destination ID in low bits still needs to be
+ * handled.
+ */
+ msg->address = kvm_swizzle_msi_ext_dest_id(msg->address);
+
ret = kvm_irqchip_send_msi(kvm_state, *msg);
if (ret < 0) {
fprintf(stderr, "KVM: injection failed, MSI lost (%s)\n",
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 5688608613..f111ef87d8 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -158,6 +158,7 @@ static int microvm_ioapics(MicrovmMachineState *mms)
static void microvm_devices_init(MicrovmMachineState *mms)
{
+ const char *default_firmware;
X86MachineState *x86ms = X86_MACHINE(mms);
ISABus *isa_bus;
ISADevice *rtc_state;
@@ -274,12 +275,10 @@ static void microvm_devices_init(MicrovmMachineState *mms)
serial_hds_isa_init(isa_bus, 0, 1);
}
- if (bios_name == NULL) {
- bios_name = x86_machine_is_acpi_enabled(x86ms)
+ default_firmware = x86_machine_is_acpi_enabled(x86ms)
? MICROVM_BIOS_FILENAME
: MICROVM_QBOOT_FILENAME;
- }
- x86_bios_rom_init(get_system_memory(), true);
+ x86_bios_rom_init(MACHINE(mms), default_firmware, get_system_memory(), true);
}
static void microvm_memory_init(MicrovmMachineState *mms)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 9e29f3792b..640fb5b0b7 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -104,6 +104,7 @@ const size_t pc_compat_5_2_len = G_N_ELEMENTS(pc_compat_5_2);
GlobalProperty pc_compat_5_1[] = {
{ "ICH9-LPC", "x-smi-cpu-hotplug", "off" },
+ { TYPE_X86_CPU, "kvm-msi-ext-dest-id", "off" },
};
const size_t pc_compat_5_1_len = G_N_ELEMENTS(pc_compat_5_1);
@@ -796,17 +797,12 @@ void pc_machine_done(Notifier *notifier, void *data)
fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
}
- if (x86ms->apic_id_limit > 255 && !xen_enabled()) {
- IntelIOMMUState *iommu = INTEL_IOMMU_DEVICE(x86_iommu_get_default());
- if (!iommu || !x86_iommu_ir_supported(X86_IOMMU_DEVICE(iommu)) ||
- iommu->intr_eim != ON_OFF_AUTO_ON) {
- error_report("current -smp configuration requires "
- "Extended Interrupt Mode enabled. "
- "You can add an IOMMU using: "
- "-device intel-iommu,intremap=on,eim=on");
- exit(EXIT_FAILURE);
- }
+ if (x86ms->apic_id_limit > 255 && !xen_enabled() &&
+ !kvm_irqchip_in_kernel()) {
+ error_report("current -smp configuration requires kernel "
+ "irqchip support.");
+ exit(EXIT_FAILURE);
}
}
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index f8bd3a8b85..92e90ff013 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -213,7 +213,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)];
if (!pcmc->pci_enabled) {
- x86_bios_rom_init(rom_memory, true);
+ x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, true);
return;
}
@@ -234,7 +234,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
if (!pflash_blk[0]) {
/* Machine property pflash0 not set, use ROM mode */
- x86_bios_rom_init(rom_memory, false);
+ x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, false);
} else {
if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
/*
diff --git a/hw/i386/vmport.c b/hw/i386/vmport.c
index 20d605506b..490a57f52c 100644
--- a/hw/i386/vmport.c
+++ b/hw/i386/vmport.c
@@ -32,6 +32,7 @@
#include "hw/isa/isa.h"
#include "hw/i386/vmport.h"
#include "hw/qdev-properties.h"
+#include "hw/boards.h"
#include "sysemu/sysemu.h"
#include "sysemu/hw_accel.h"
#include "sysemu/qtest.h"
@@ -188,7 +189,7 @@ static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr)
return -1;
}
cpu->env.regs[R_EBX] = 0x1177;
- return ram_size;
+ return current_machine->ram_size;
}
static uint32_t vmport_cmd_get_hz(void *opaque, uint32_t addr)
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index d68a9eaefc..49e1d419b2 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -26,11 +26,13 @@
#include "qemu/cutils.h"
#include "qemu/units.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qapi-visit-common.h"
#include "qapi/visitor.h"
#include "sysemu/qtest.h"
+#include "sysemu/whpx.h"
#include "sysemu/numa.h"
#include "sysemu/replay.h"
#include "sysemu/sysemu.h"
@@ -54,8 +56,6 @@
#include CONFIG_DEVICES
#include "kvm_i386.h"
-#define BIOS_FILENAME "bios.bin"
-
/* Physical Address of PVH entry point read from kernel ELF NOTE */
static size_t pvh_start_addr;
@@ -532,7 +532,8 @@ static void pic_irq_request(void *opaque, int irq, int level)
X86CPU *cpu = X86_CPU(cs);
trace_x86_pic_interrupt(irq, level);
- if (cpu->apic_state && !kvm_irqchip_in_kernel()) {
+ if (cpu->apic_state && !kvm_irqchip_in_kernel() &&
+ !whpx_apic_in_platform()) {
CPU_FOREACH(cs) {
cpu = X86_CPU(cs);
if (apic_accept_pic_intr(cpu->apic_state)) {
@@ -558,7 +559,7 @@ int cpu_get_pic_interrupt(CPUX86State *env)
X86CPU *cpu = env_archcpu(env);
int intno;
- if (!kvm_irqchip_in_kernel()) {
+ if (!kvm_irqchip_in_kernel() && !whpx_apic_in_platform()) {
intno = apic_get_interrupt(cpu->apic_state);
if (intno >= 0) {
return intno;
@@ -1078,17 +1079,17 @@ void x86_load_linux(X86MachineState *x86ms,
nb_option_roms++;
}
-void x86_bios_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
+void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
+ MemoryRegion *rom_memory, bool isapc_ram_fw)
{
+ const char *bios_name;
char *filename;
MemoryRegion *bios, *isa_bios;
int bios_size, isa_bios_size;
int ret;
/* BIOS load */
- if (bios_name == NULL) {
- bios_name = BIOS_FILENAME;
- }
+ bios_name = ms->firmware ?: default_firmware;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
bios_size = get_image_size(filename);
diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 9519c33c09..096c46fef1 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -1493,7 +1493,7 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory)
#else
xen_map_cache_init(NULL, state);
#endif
- xen_ram_init(pcms, ram_size, ram_memory);
+ xen_ram_init(pcms, ms->ram_size, ram_memory);
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 502e94effc..97dd96dffa 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -27,6 +27,7 @@
#include "hw/i386/apic.h"
#include "hw/i386/apic_internal.h"
#include "trace.h"
+#include "hw/boards.h"
#include "sysemu/hax.h"
#include "sysemu/kvm.h"
#include "hw/qdev-properties.h"
@@ -297,7 +298,7 @@ static void apic_common_realize(DeviceState *dev, Error **errp)
/* Note: We need at least 1M to map the VAPIC option ROM */
if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK &&
- !hax_enabled() && ram_size >= 1024 * 1024) {
+ !hax_enabled() && current_machine->ram_size >= 1024 * 1024) {
vapic = sysbus_create_simple("kvmvapic", -1, NULL);
}
s->vapic = vapic;
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 9ef94883d5..72d1326531 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -21,6 +21,7 @@
#include "qemu/units.h"
#include "qemu/error-report.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
@@ -108,6 +109,7 @@ static void
milkymist_init(MachineState *machine)
{
MachineClass *mc = MACHINE_GET_CLASS(machine);
+ const char *bios_name = machine->firmware ?: BIOS_FILENAME;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
@@ -162,9 +164,6 @@ milkymist_init(MachineState *machine)
}
/* load bios rom */
- if (bios_name == NULL) {
- bios_name = BIOS_FILENAME;
- }
bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (bios_filename) {
diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c
index 92a194dbc4..6d93d761a5 100644
--- a/hw/m68k/mcf5206.c
+++ b/hw/m68k/mcf5206.c
@@ -10,6 +10,7 @@
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "cpu.h"
+#include "hw/boards.h"
#include "hw/irq.h"
#include "hw/m68k/mcf.h"
#include "qemu/timer.h"
@@ -312,8 +313,9 @@ static uint64_t m5206_mbar_read(m5206_mbar_state *s,
/* FIXME: currently hardcoded to 128Mb. */
{
uint32_t mask = ~0;
- while (mask > ram_size)
+ while (mask > current_machine->ram_size) {
mask >>= 1;
+ }
return mask & 0x0ffe0000;
}
case 0x5c: return 1; /* DRAM bank 1 empty. */
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index d310a98e7b..7a03c71059 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -12,6 +12,7 @@
#include "qemu/log.h"
#include "qapi/error.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/irq.h"
#include "hw/m68k/mcf.h"
@@ -157,8 +158,9 @@ static uint64_t m5208_sys_read(void *opaque, hwaddr addr,
{
int n;
for (n = 0; n < 32; n++) {
- if (ram_size < (2u << n))
+ if (current_machine->ram_size < (2u << n)) {
break;
+ }
}
return (n - 1) | 0x40000000;
}
@@ -301,17 +303,17 @@ static void mcf5208evb_init(MachineState *machine)
/* 0xfc0a8000 SDRAM controller. */
/* Load firmware */
- if (bios_name) {
+ if (machine->firmware) {
char *fn;
uint8_t *ptr;
- fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware);
if (!fn) {
- error_report("Could not find ROM image '%s'", bios_name);
+ error_report("Could not find ROM image '%s'", machine->firmware);
exit(1);
}
if (load_image_targphys(fn, 0x0, ROM_SIZE) < 8) {
- error_report("Could not load ROM image '%s'", bios_name);
+ error_report("Could not load ROM image '%s'", machine->firmware);
exit(1);
}
g_free(fn);
@@ -323,7 +325,7 @@ static void mcf5208evb_init(MachineState *machine)
/* Load kernel. */
if (!kernel_filename) {
- if (qtest_enabled() || bios_name) {
+ if (qtest_enabled() || machine->firmware) {
return;
}
error_report("Kernel image must be specified");
diff --git a/hw/m68k/next-cube.c b/hw/m68k/next-cube.c
index e7045980b7..37bc35dfa4 100644
--- a/hw/m68k/next-cube.c
+++ b/hw/m68k/next-cube.c
@@ -868,6 +868,7 @@ static void next_cube_init(MachineState *machine)
MemoryRegion *bmapm1 = g_new(MemoryRegion, 1);
MemoryRegion *bmapm2 = g_new(MemoryRegion, 1);
MemoryRegion *sysmem = get_system_memory();
+ const char *bios_name = machine->firmware ?: ROM_FILE;
NeXTState *ns = NEXT_MACHINE(machine);
DeviceState *dev;
@@ -924,9 +925,6 @@ static void next_cube_init(MachineState *machine)
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x0200e000);
/* Load ROM here */
- if (bios_name == NULL) {
- bios_name = ROM_FILE;
- }
/* still not sure if the rom should also be mapped at 0x0*/
memory_region_init_rom(rom, NULL, "next.rom", 0x20000, &error_fatal);
memory_region_add_subregion(sysmem, 0x01000000, rom);
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index ce4b47c3e3..4db2b9bbc7 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -23,6 +23,7 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "sysemu/sysemu.h"
#include "cpu.h"
#include "hw/hw.h"
@@ -167,6 +168,7 @@ static void q800_init(MachineState *machine)
const char *kernel_filename = machine->kernel_filename;
const char *initrd_filename = machine->initrd_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
+ const char *bios_name = machine->firmware ?: MACROM_FILENAME;
hwaddr parameters_base;
CPUState *cs;
DeviceState *dev;
@@ -400,9 +402,6 @@ static void q800_init(MachineState *machine)
rom = g_malloc(sizeof(*rom));
memory_region_init_rom(rom, NULL, "m68k_mac.rom", MACROM_SIZE,
&error_abort);
- if (bios_name == NULL) {
- bios_name = MACROM_FILENAME;
- }
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom);
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 8ad3c27f2c..6715ba2ff9 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -26,6 +26,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
@@ -170,7 +171,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
/* Not an ELF image nor an u-boot image, try a RAW image. */
if (kernel_size < 0) {
kernel_size = load_image_targphys(kernel_filename, ddr_base,
- ram_size);
+ ramsize);
boot_info.bootstrap_pc = ddr_base;
high = (ddr_base + kernel_size + 3) & ~3;
}
@@ -185,11 +186,11 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
initrd_size = load_ramdisk(initrd_filename,
boot_info.initrd_start,
- ram_size - initrd_offset);
+ ramsize - initrd_offset);
if (initrd_size < 0) {
initrd_size = load_image_targphys(initrd_filename,
boot_info.initrd_start,
- ram_size - initrd_offset);
+ ramsize - initrd_offset);
}
if (initrd_size < 0) {
error_report("could not load initrd '%s'",
@@ -206,7 +207,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
}
/* Provide a device-tree. */
boot_info.fdt = boot_info.cmdline + 4096;
- microblaze_load_dtb(boot_info.fdt, ram_size,
+ microblaze_load_dtb(boot_info.fdt, ramsize,
boot_info.initrd_start,
boot_info.initrd_end,
kernel_cmdline,
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index a9e0c2f8d3..45c596f4fe 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "cpu.h"
@@ -134,14 +135,14 @@ static int64_t load_kernel(CPUMIPSState *env)
initrd_size = get_image_size(loaderparams.initrd_filename);
if (initrd_size > 0) {
initrd_offset = ROUND_UP(kernel_high, INITRD_PAGE_SIZE);
- if (initrd_offset + initrd_size > ram_size) {
+ if (initrd_offset + initrd_size > loaderparams.ram_size) {
error_report("memory too small for initial ram disk '%s'",
loaderparams.initrd_filename);
exit(1);
}
initrd_size = load_image_targphys(loaderparams.initrd_filename,
initrd_offset,
- ram_size - initrd_offset);
+ loaderparams.ram_size - initrd_offset);
}
if (initrd_size == (target_ulong) -1) {
error_report("could not load initial ram disk '%s'",
@@ -338,7 +339,7 @@ static void mips_fuloong2e_init(MachineState *machine)
write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
} else {
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
- bios_name ?: FULOONG_BIOSNAME);
+ machine->firmware ?: FULOONG_BIOSNAME);
if (filename) {
bios_size = load_image_targphys(filename, 0x1fc00000LL,
BIOS_SIZE);
@@ -348,8 +349,8 @@ static void mips_fuloong2e_init(MachineState *machine)
}
if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
- bios_name && !qtest_enabled()) {
- error_report("Could not load MIPS bios '%s'", bios_name);
+ machine->firmware && !qtest_enabled()) {
+ error_report("Could not load MIPS bios '%s'", machine->firmware);
exit(1);
}
}
diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index 71448f72ac..f9442731dd 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "hw/clock.h"
#include "hw/mips/mips.h"
#include "hw/mips/cpudevs.h"
@@ -218,7 +219,7 @@ static void mips_jazz_init(MachineState *machine,
memory_region_add_subregion(address_space, 0xfff00000LL, bios2);
/* load the BIOS image. */
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name ?: BIOS_FILENAME);
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware ?: BIOS_FILENAME);
if (filename) {
bios_size = load_image_targphys(filename, 0xfff00000LL,
MAGNUM_BIOS_SIZE);
@@ -227,8 +228,8 @@ static void mips_jazz_init(MachineState *machine,
bios_size = -1;
}
if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE)
- && bios_name && !qtest_enabled()) {
- error_report("Could not load MIPS bios '%s'", bios_name);
+ && machine->firmware && !qtest_enabled()) {
+ error_report("Could not load MIPS bios '%s'", machine->firmware);
exit(1);
}
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 9d1a3b50b7..5c11eecec1 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/clock.h"
#include "hw/southbridge/piix.h"
@@ -1087,7 +1088,7 @@ static int64_t load_kernel(void)
}
initrd_size = load_image_targphys(loaderparams.initrd_filename,
initrd_offset,
- ram_size - initrd_offset);
+ loaderparams.ram_size - initrd_offset);
}
if (initrd_size == (target_ulong) -1) {
error_report("could not load initial ram disk '%s'",
@@ -1333,7 +1334,7 @@ void mips_malta_init(MachineState *machine)
if (!dinfo) {
/* Load a BIOS image. */
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
- bios_name ?: BIOS_FILENAME);
+ machine->firmware ?: BIOS_FILENAME);
if (filename) {
bios_size = load_image_targphys(filename, FLASH_ADDRESS,
BIOS_SIZE);
@@ -1342,8 +1343,8 @@ void mips_malta_init(MachineState *machine)
bios_size = -1;
}
if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
- bios_name && !qtest_enabled()) {
- error_report("Could not load MIPS bios '%s'", bios_name);
+ machine->firmware && !qtest_enabled()) {
+ error_report("Could not load MIPS bios '%s'", machine->firmware);
exit(1);
}
}
diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c
index aaa62a0f4b..f2e6273525 100644
--- a/hw/mips/mipssim.c
+++ b/hw/mips/mipssim.c
@@ -28,6 +28,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/clock.h"
#include "hw/mips/mips.h"
@@ -177,7 +178,7 @@ mips_mipssim_init(MachineState *machine)
/* Map the BIOS / boot exception handler. */
memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios);
/* Load a BIOS / boot exception handler image. */
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name ?: BIOS_FILENAME);
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware ?: BIOS_FILENAME);
if (filename) {
bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE);
g_free(filename);
@@ -185,9 +186,9 @@ mips_mipssim_init(MachineState *machine)
bios_size = -1;
}
if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
- bios_name && !qtest_enabled()) {
+ machine->firmware && !qtest_enabled()) {
/* Bail out if we have neither a kernel image nor boot vector code. */
- error_report("Could not load MIPS bios '%s'", bios_name);
+ error_report("Could not load MIPS bios '%s'", machine->firmware);
exit(1);
} else {
/* We have a boot vector start address. */
diff --git a/hw/misc/max111x.c b/hw/misc/max111x.c
index eae0f9b598..1b3234a519 100644
--- a/hw/misc/max111x.c
+++ b/hw/misc/max111x.c
@@ -85,7 +85,7 @@ static void max111x_write(MAX111xState *s, uint32_t value)
qemu_irq_raise(s->interrupt);
}
-static uint32_t max111x_transfer(SSISlave *dev, uint32_t value)
+static uint32_t max111x_transfer(SSIPeripheral *dev, uint32_t value)
{
MAX111xState *s = MAX_111X(dev);
max111x_write(s, value);
@@ -97,7 +97,7 @@ static const VMStateDescription vmstate_max111x = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(parent_obj, MAX111xState),
+ VMSTATE_SSI_PERIPHERAL(parent_obj, MAX111xState),
VMSTATE_UINT8(tb1, MAX111xState),
VMSTATE_UINT8(rb2, MAX111xState),
VMSTATE_UINT8(rb3, MAX111xState),
@@ -117,7 +117,7 @@ static void max111x_input_set(void *opaque, int line, int value)
s->input[line] = value;
}
-static int max111x_init(SSISlave *d, int inputs)
+static int max111x_init(SSIPeripheral *d, int inputs)
{
DeviceState *dev = DEVICE(d);
MAX111xState *s = MAX_111X(dev);
@@ -130,12 +130,12 @@ static int max111x_init(SSISlave *d, int inputs)
return 0;
}
-static void max1110_realize(SSISlave *dev, Error **errp)
+static void max1110_realize(SSIPeripheral *dev, Error **errp)
{
max111x_init(dev, 8);
}
-static void max1111_realize(SSISlave *dev, Error **errp)
+static void max1111_realize(SSIPeripheral *dev, Error **errp)
{
max111x_init(dev, 4);
}
@@ -179,7 +179,7 @@ static Property max1111_properties[] = {
static void max111x_class_init(ObjectClass *klass, void *data)
{
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->transfer = max111x_transfer;
@@ -190,7 +190,7 @@ static void max111x_class_init(ObjectClass *klass, void *data)
static const TypeInfo max111x_info = {
.name = TYPE_MAX_111X,
- .parent = TYPE_SSI_SLAVE,
+ .parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(MAX111xState),
.class_init = max111x_class_init,
.abstract = true,
@@ -198,7 +198,7 @@ static const TypeInfo max111x_info = {
static void max1110_class_init(ObjectClass *klass, void *data)
{
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->realize = max1110_realize;
@@ -213,7 +213,7 @@ static const TypeInfo max1110_info = {
static void max1111_class_init(ObjectClass *klass, void *data)
{
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->realize = max1111_realize;
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index a765e9f6be..f7b57fcae1 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -82,7 +82,7 @@ static void load_kernel(MoxieCPU *cpu, LoaderParams *loader_params)
}
initrd_size = load_image_targphys(loader_params->initrd_filename,
initrd_offset,
- ram_size);
+ loader_params->ram_size);
}
if (initrd_size == (target_ulong)-1) {
error_report("could not load initial ram disk '%s'",
@@ -133,9 +133,9 @@ static void moxiesim_init(MachineState *machine)
loader_params.initrd_filename = initrd_filename;
load_kernel(cpu, &loader_params);
}
- if (bios_name) {
- if (load_image_targphys(bios_name, FIRMWARE_BASE, FIRMWARE_SIZE) < 0) {
- error_report("Failed to load firmware '%s'", bios_name);
+ if (machine->firmware) {
+ if (load_image_targphys(machine->firmware, FIRMWARE_BASE, FIRMWARE_SIZE) < 0) {
+ error_report("Failed to load firmware '%s'", machine->firmware);
}
}
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index f8cf5290e1..990ff3a1c2 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -45,11 +45,11 @@
OBJECT_DECLARE_SIMPLE_TYPE(XilinxAXIEnet, XILINX_AXI_ENET)
-typedef struct XilinxAXIEnetStreamSlave XilinxAXIEnetStreamSlave;
-DECLARE_INSTANCE_CHECKER(XilinxAXIEnetStreamSlave, XILINX_AXI_ENET_DATA_STREAM,
+typedef struct XilinxAXIEnetStreamSink XilinxAXIEnetStreamSink;
+DECLARE_INSTANCE_CHECKER(XilinxAXIEnetStreamSink, XILINX_AXI_ENET_DATA_STREAM,
TYPE_XILINX_AXI_ENET_DATA_STREAM)
-DECLARE_INSTANCE_CHECKER(XilinxAXIEnetStreamSlave, XILINX_AXI_ENET_CONTROL_STREAM,
+DECLARE_INSTANCE_CHECKER(XilinxAXIEnetStreamSink, XILINX_AXI_ENET_CONTROL_STREAM,
TYPE_XILINX_AXI_ENET_CONTROL_STREAM)
/* Advertisement control register. */
@@ -310,7 +310,7 @@ struct TEMAC {
};
-struct XilinxAXIEnetStreamSlave {
+struct XilinxAXIEnetStreamSink {
Object parent;
struct XilinxAXIEnet *enet;
@@ -320,10 +320,10 @@ struct XilinxAXIEnet {
SysBusDevice busdev;
MemoryRegion iomem;
qemu_irq irq;
- StreamSlave *tx_data_dev;
- StreamSlave *tx_control_dev;
- XilinxAXIEnetStreamSlave rx_data_dev;
- XilinxAXIEnetStreamSlave rx_control_dev;
+ StreamSink *tx_data_dev;
+ StreamSink *tx_control_dev;
+ XilinxAXIEnetStreamSink rx_data_dev;
+ XilinxAXIEnetStreamSink rx_control_dev;
NICState *nic;
NICConf conf;
@@ -852,11 +852,11 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
}
static size_t
-xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len,
+xilinx_axienet_control_stream_push(StreamSink *obj, uint8_t *buf, size_t len,
bool eop)
{
int i;
- XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(obj);
+ XilinxAXIEnetStreamSink *cs = XILINX_AXI_ENET_CONTROL_STREAM(obj);
XilinxAXIEnet *s = cs->enet;
assert(eop);
@@ -874,10 +874,10 @@ xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len,
}
static size_t
-xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
+xilinx_axienet_data_stream_push(StreamSink *obj, uint8_t *buf, size_t size,
bool eop)
{
- XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
+ XilinxAXIEnetStreamSink *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
XilinxAXIEnet *s = ds->enet;
/* TX enable ? */
@@ -951,8 +951,8 @@ static NetClientInfo net_xilinx_enet_info = {
static void xilinx_enet_realize(DeviceState *dev, Error **errp)
{
XilinxAXIEnet *s = XILINX_AXI_ENET(dev);
- XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev);
- XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(
+ XilinxAXIEnetStreamSink *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev);
+ XilinxAXIEnetStreamSink *cs = XILINX_AXI_ENET_CONTROL_STREAM(
&s->rx_control_dev);
object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
@@ -1002,9 +1002,9 @@ static Property xilinx_enet_properties[] = {
DEFINE_PROP_UINT32("txmem", XilinxAXIEnet, c_txmem, 0x1000),
DEFINE_NIC_PROPERTIES(XilinxAXIEnet, conf),
DEFINE_PROP_LINK("axistream-connected", XilinxAXIEnet,
- tx_data_dev, TYPE_STREAM_SLAVE, StreamSlave *),
+ tx_data_dev, TYPE_STREAM_SINK, StreamSink *),
DEFINE_PROP_LINK("axistream-control-connected", XilinxAXIEnet,
- tx_control_dev, TYPE_STREAM_SLAVE, StreamSlave *),
+ tx_control_dev, TYPE_STREAM_SINK, StreamSink *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1020,14 +1020,14 @@ static void xilinx_enet_class_init(ObjectClass *klass, void *data)
static void xilinx_enet_control_stream_class_init(ObjectClass *klass,
void *data)
{
- StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
+ StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
ssc->push = xilinx_axienet_control_stream_push;
}
static void xilinx_enet_data_stream_class_init(ObjectClass *klass, void *data)
{
- StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
+ StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
ssc->push = xilinx_axienet_data_stream_push;
}
@@ -1043,10 +1043,10 @@ static const TypeInfo xilinx_enet_info = {
static const TypeInfo xilinx_enet_data_stream_info = {
.name = TYPE_XILINX_AXI_ENET_DATA_STREAM,
.parent = TYPE_OBJECT,
- .instance_size = sizeof(XilinxAXIEnetStreamSlave),
+ .instance_size = sizeof(XilinxAXIEnetStreamSink),
.class_init = xilinx_enet_data_stream_class_init,
.interfaces = (InterfaceInfo[]) {
- { TYPE_STREAM_SLAVE },
+ { TYPE_STREAM_SINK },
{ }
}
};
@@ -1054,10 +1054,10 @@ static const TypeInfo xilinx_enet_data_stream_info = {
static const TypeInfo xilinx_enet_control_stream_info = {
.name = TYPE_XILINX_AXI_ENET_CONTROL_STREAM,
.parent = TYPE_OBJECT,
- .instance_size = sizeof(XilinxAXIEnetStreamSlave),
+ .instance_size = sizeof(XilinxAXIEnetStreamSink),
.class_init = xilinx_enet_control_stream_class_init,
.interfaces = (InterfaceInfo[]) {
- { TYPE_STREAM_SLAVE },
+ { TYPE_STREAM_SINK },
{ }
}
};
diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c
index 1df3b66c29..95a8697906 100644
--- a/hw/nios2/boot.c
+++ b/hw/nios2/boot.c
@@ -31,6 +31,7 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
@@ -181,7 +182,7 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
/* Not an ELF image nor an u-boot image, try a RAW image. */
if (kernel_size < 0) {
kernel_size = load_image_targphys(kernel_filename, ddr_base,
- ram_size);
+ ramsize);
boot_info.bootstrap_pc = ddr_base;
high = ddr_base + kernel_size;
}
@@ -198,11 +199,11 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
initrd_size = load_ramdisk(initrd_filename,
boot_info.initrd_start,
- ram_size - initrd_offset);
+ ramsize - initrd_offset);
if (initrd_size < 0) {
initrd_size = load_image_targphys(initrd_filename,
boot_info.initrd_start,
- ram_size - initrd_offset);
+ ramsize - initrd_offset);
}
if (initrd_size < 0) {
error_report("could not load initrd '%s'",
@@ -216,7 +217,7 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
/* Device tree must be placed right after initrd (if available) */
boot_info.fdt = high;
- fdt_size = nios2_load_dtb(boot_info, ram_size, kernel_cmdline,
+ fdt_size = nios2_load_dtb(boot_info, ramsize, kernel_cmdline,
/* Preference a -dtb argument */
dtb_arg ? dtb_arg : filename);
high += fdt_size;
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 282ba93e2e..44cb274a32 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "sysemu/sysemu.h"
#include "sysemu/dma.h"
#include "sysemu/reset.h"
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index d0323fefb1..0469db8c1d 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/pci/pci.h"
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 0131d9d02c..9424231542 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "hw/irq.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_bridge.h"
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index ae39b9358e..6a64eb31ab 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -16,6 +16,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "e500.h"
@@ -1035,7 +1036,7 @@ void ppce500_init(MachineState *machine)
* -kernel to users but allows them to run through u-boot as well.
*/
kernel_as_payload = false;
- if (bios_name == NULL) {
+ if (machine->firmware == NULL) {
if (machine->kernel_filename) {
payload_name = machine->kernel_filename;
kernel_as_payload = true;
@@ -1043,7 +1044,7 @@ void ppce500_init(MachineState *machine)
payload_name = "u-boot.e500";
}
} else {
- payload_name = bios_name;
+ payload_name = machine->firmware;
}
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, payload_name);
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index f9a1cc8944..c0accda592 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -48,6 +48,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qapi/error.h"
#include "hw/ppc/ppc.h"
#include "hw/qdev-properties.h"
@@ -109,6 +110,7 @@ static void ppc_core99_reset(void *opaque)
static void ppc_core99_init(MachineState *machine)
{
ram_addr_t ram_size = machine->ram_size;
+ const char *bios_name = machine->firmware ?: PROM_FILENAME;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
@@ -161,9 +163,6 @@ static void ppc_core99_init(MachineState *machine)
&error_fatal);
memory_region_add_subregion(get_system_memory(), PROM_BASE, bios);
- if (!bios_name) {
- bios_name = PROM_FILENAME;
- }
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
/* Load OpenBIOS (ELF) */
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 6c59aa5601..04f98a4d81 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -26,6 +26,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/ppc/ppc.h"
@@ -83,6 +84,7 @@ static void ppc_heathrow_reset(void *opaque)
static void ppc_heathrow_init(MachineState *machine)
{
ram_addr_t ram_size = machine->ram_size;
+ const char *bios_name = machine->firmware ?: PROM_FILENAME;
const char *boot_device = machine->boot_order;
PowerPCCPU *cpu = NULL;
CPUPPCState *env = NULL;
@@ -130,9 +132,6 @@ static void ppc_heathrow_init(MachineState *machine)
&error_fatal);
memory_region_add_subregion(get_system_memory(), PROM_BASE, bios);
- if (!bios_name) {
- bios_name = PROM_FILENAME;
- }
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
/* Load OpenBIOS (ELF) */
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 50ebd4a484..14fc9758a9 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "sysemu/qtest.h"
@@ -713,6 +714,7 @@ static void pnv_chip_power10_pic_print_info(PnvChip *chip, Monitor *mon)
static void pnv_init(MachineState *machine)
{
+ const char *bios_name = machine->firmware ?: FW_FILE_NAME;
PnvMachineState *pnv = PNV_MACHINE(machine);
MachineClass *mc = MACHINE_GET_CLASS(machine);
char *fw_filename;
@@ -739,10 +741,6 @@ static void pnv_init(MachineState *machine)
pnv->pnor = PNV_PNOR(dev);
/* load skiboot firmware */
- if (bios_name == NULL) {
- bios_name = FW_FILE_NAME;
- }
-
fw_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (!fw_filename) {
error_report("Could not find OPAL firmware '%s'", bios_name);
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 4687715b15..b7249f21cf 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -26,6 +26,7 @@
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/ppc/ppc.h"
#include "hw/qdev-properties.h"
@@ -141,6 +142,7 @@ static void ref405ep_fpga_init(MemoryRegion *sysmem, uint32_t base)
static void ref405ep_init(MachineState *machine)
{
MachineClass *mc = MACHINE_GET_CLASS(machine);
+ const char *bios_name = machine->firmware ?: BIOS_FILENAME;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
@@ -206,8 +208,6 @@ static void ref405ep_init(MachineState *machine)
memory_region_init_rom(bios, NULL, "ef405ep.bios", BIOS_SIZE,
&error_fatal);
- if (bios_name == NULL)
- bios_name = BIOS_FILENAME;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
bios_size = load_image_size(filename,
@@ -425,6 +425,7 @@ static void taihu_cpld_init(MemoryRegion *sysmem, uint32_t base)
static void taihu_405ep_init(MachineState *machine)
{
MachineClass *mc = MACHINE_GET_CLASS(machine);
+ const char *bios_name = machine->firmware ?: BIOS_FILENAME;
const char *kernel_filename = machine->kernel_filename;
const char *initrd_filename = machine->initrd_filename;
char *filename;
@@ -475,8 +476,6 @@ static void taihu_405ep_init(MachineState *machine)
} else
#endif
{
- if (bios_name == NULL)
- bios_name = BIOS_FILENAME;
bios = g_new(MemoryRegion, 1);
memory_region_init_rom(bios, NULL, "taihu_405ep.bios", BIOS_SIZE,
&error_fatal);
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 74028dc986..665bc1784e 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -15,6 +15,7 @@
#include "qemu/units.h"
#include "qemu/error-report.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/error-report.h"
#include "net/net.h"
#include "hw/pci/pci.h"
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 4a0cb434a6..7e72f6e4a9 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -237,6 +237,7 @@ static int prep_set_cmos_checksum(DeviceState *dev, void *opaque)
static void ibm_40p_init(MachineState *machine)
{
+ const char *bios_name = machine->firmware ?: "openbios-ppc";
CPUPPCState *env = NULL;
uint16_t cmos_checksum;
PowerPCCPU *cpu;
@@ -271,9 +272,6 @@ static void ibm_40p_init(MachineState *machine)
/* PCI host */
dev = qdev_new("raven-pcihost");
- if (!bios_name) {
- bios_name = "openbios-ppc";
- }
qdev_prop_set_string(dev, "bios-name", bios_name);
qdev_prop_set_uint32(dev, "elf-machine", PPC_ELF_MACHINE);
pcihost = SYS_BUS_DEVICE(dev);
@@ -422,7 +420,7 @@ static void ibm_40p_init(MachineState *machine)
/* Prepare firmware configuration for Open Hack'Ware */
if (m48t59) {
- PPC_NVRAM_set_params(m48t59, NVRAM_SIZE, "PREP", ram_size,
+ PPC_NVRAM_set_params(m48t59, NVRAM_SIZE, "PREP", machine->ram_size,
boot_device,
kernel_base, kernel_size,
machine->kernel_cmdline,
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 7e59a91981..14e6583eb0 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -14,6 +14,7 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "hw/boards.h"
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c060702013..6abb45d0ed 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -26,6 +26,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "sysemu/sysemu.h"
@@ -2657,6 +2658,7 @@ static void spapr_machine_init(MachineState *machine)
SpaprMachineState *spapr = SPAPR_MACHINE(machine);
SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
MachineClass *mc = MACHINE_GET_CLASS(machine);
+ const char *bios_name = machine->firmware ?: FW_FILE_NAME;
const char *kernel_filename = machine->kernel_filename;
const char *initrd_filename = machine->initrd_filename;
PCIHostState *phb;
@@ -2876,10 +2878,8 @@ static void spapr_machine_init(MachineState *machine)
/* Set up VIO bus */
spapr->vio_bus = spapr_vio_bus_init();
- for (i = 0; i < serial_max_hds(); i++) {
- if (serial_hd(i)) {
- spapr_vty_create(spapr->vio_bus, serial_hd(i));
- }
+ for (i = 0; serial_hd(i); i++) {
+ spapr_vty_create(spapr->vio_bus, serial_hd(i));
}
/* We always have at least the nvram device on VIO */
@@ -2980,9 +2980,6 @@ static void spapr_machine_init(MachineState *machine)
}
}
- if (bios_name == NULL) {
- bios_name = FW_FILE_NAME;
- }
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (!filename) {
error_report("Could not find LPAR firmware '%s'", bios_name);
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 5d6c56473f..3cc9421526 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -525,10 +525,10 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
uint32_t liobn = SPAPR_VIO_LIOBN(dev->reg);
memory_region_init(&dev->mrroot, OBJECT(dev), "iommu-spapr-root",
- ram_size);
+ MACHINE(spapr)->ram_size);
memory_region_init_alias(&dev->mrbypass, OBJECT(dev),
"iommu-spapr-bypass", get_system_memory(),
- 0, ram_size);
+ 0, MACHINE(spapr)->ram_size);
memory_region_add_subregion_overlap(&dev->mrroot, 0, &dev->mrbypass, 1);
address_space_init(&dev->as, &dev->mrroot, qdev->id);
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index c790c1113f..7f1bca928c 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "cpu.h"
#include "hw/sysbus.h"
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 9b3fe3fb1e..d62f3dc758 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qemu/error-report.h"
#include "exec/cpu-defs.h"
@@ -120,7 +121,8 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
}
firmware_size = load_image_targphys_as(firmware_filename,
- firmware_load_addr, ram_size, NULL);
+ firmware_load_addr,
+ current_machine->ram_size, NULL);
if (firmware_size > 0) {
return firmware_load_addr + firmware_size;
@@ -148,7 +150,7 @@ target_ulong riscv_load_kernel(const char *kernel_filename,
}
if (load_image_targphys_as(kernel_filename, kernel_start_addr,
- ram_size, NULL) > 0) {
+ current_machine->ram_size, NULL) > 0) {
return kernel_start_addr;
}
diff --git a/hw/rx/rx-gdbsim.c b/hw/rx/rx-gdbsim.c
index 285549c79b..b1d7c2488f 100644
--- a/hw/rx/rx-gdbsim.c
+++ b/hw/rx/rx-gdbsim.c
@@ -106,6 +106,16 @@ static void rx_gdbsim_init(MachineState *machine)
rxc->xtal_freq_hz, &error_abort);
object_property_set_bool(OBJECT(&s->mcu), "load-kernel",
kernel_filename != NULL, &error_abort);
+
+ if (!kernel_filename) {
+ if (machine->firmware) {
+ rom_add_file_fixed(machine->firmware, RX62N_CFLASH_BASE, 0);
+ } else if (!qtest_enabled()) {
+ error_report("No bios or kernel specified");
+ exit(1);
+ }
+ }
+
qdev_realize(DEVICE(&s->mcu), NULL, &error_abort);
/* Load kernel and dtb */
diff --git a/hw/rx/rx62n.c b/hw/rx/rx62n.c
index 6eb4eea700..17ec73fc7b 100644
--- a/hw/rx/rx62n.c
+++ b/hw/rx/rx62n.c
@@ -245,15 +245,6 @@ static void rx62n_realize(DeviceState *dev, Error **errp)
rxc->rom_flash_size, &error_abort);
memory_region_add_subregion(s->sysmem, RX62N_CFLASH_BASE, &s->c_flash);
- if (!s->kernel) {
- if (bios_name) {
- rom_add_file_fixed(bios_name, RX62N_CFLASH_BASE, 0);
- } else if (!qtest_enabled()) {
- error_report("No bios or kernel specified");
- exit(1);
- }
- }
-
/* Initialize CPU */
object_initialize_child(OBJECT(s), "cpu", &s->cpu, TYPE_RX62N_CPU);
qdev_realize(DEVICE(&s->cpu), NULL, &error_abort);
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 3d2652d75a..ff6b55e816 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -14,6 +14,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qapi/error.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
@@ -112,6 +113,7 @@ static uint64_t bios_translate_addr(void *opaque, uint64_t srcaddr)
static void s390_ipl_realize(DeviceState *dev, Error **errp)
{
+ MachineState *ms = MACHINE(qdev_get_machine());
S390IPLState *ipl = S390_IPL(dev);
uint32_t *ipl_psw;
uint64_t pentry;
@@ -126,13 +128,9 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
* even if an external kernel has been defined.
*/
if (!ipl->kernel || ipl->enforce_bios) {
- uint64_t fwbase = (MIN(ram_size, 0x80000000U) - 0x200000) & ~0xffffUL;
+ uint64_t fwbase = (MIN(ms->ram_size, 0x80000000U) - 0x200000) & ~0xffffUL;
- if (bios_name == NULL) {
- bios_name = ipl->firmware;
- }
-
- bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->firmware);
if (bios_filename == NULL) {
error_setg(errp, "could not find stage1 bootloader");
return;
@@ -154,7 +152,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
g_free(bios_filename);
if (bios_size == -1) {
- error_setg(errp, "could not load bootloader '%s'", bios_name);
+ error_setg(errp, "could not load bootloader '%s'", ipl->firmware);
return;
}
@@ -167,7 +165,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
&pentry, NULL,
NULL, NULL, 1, EM_S390, 0, 0);
if (kernel_size < 0) {
- kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
+ kernel_size = load_image_targphys(ipl->kernel, 0, ms->ram_size);
if (kernel_size < 0) {
error_setg(errp, "could not load kernel '%s'", ipl->kernel);
return;
@@ -214,7 +212,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
initrd_offset += 0x100000;
}
initrd_size = load_image_targphys(ipl->initrd, initrd_offset,
- ram_size - initrd_offset);
+ ms->ram_size - initrd_offset);
if (initrd_size == -1) {
error_setg(errp, "could not load initrd '%s'", ipl->initrd);
return;
@@ -452,6 +450,7 @@ int s390_ipl_set_loadparm(uint8_t *loadparm)
static int load_netboot_image(Error **errp)
{
+ MachineState *ms = MACHINE(qdev_get_machine());
S390IPLState *ipl = get_ipl_device();
char *netboot_filename;
MemoryRegion *sysmem = get_system_memory();
@@ -484,7 +483,7 @@ static int load_netboot_image(Error **errp)
false);
if (img_size < 0) {
- img_size = load_image_size(netboot_filename, ram_ptr, ram_size);
+ img_size = load_image_size(netboot_filename, ram_ptr, ms->ram_size);
ipl->start_addr = KERN_IMAGE_START;
}
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index 5cc559fe4c..9a8d60d1d9 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -109,7 +109,8 @@ void qmp_dump_skeys(const char *filename, Error **errp)
{
S390SKeysState *ss = s390_get_skeys_device();
S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss);
- const uint64_t total_count = ram_size / TARGET_PAGE_SIZE;
+ MachineState *ms = MACHINE(qdev_get_machine());
+ const uint64_t total_count = ms->ram_size / TARGET_PAGE_SIZE;
uint64_t handled_count = 0, cur_count;
Error *lerr = NULL;
vaddr cur_gfn = 0;
@@ -256,7 +257,8 @@ static void s390_storage_keys_save(QEMUFile *f, void *opaque)
{
S390SKeysState *ss = S390_SKEYS(opaque);
S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss);
- uint64_t pages_left = ram_size / TARGET_PAGE_SIZE;
+ MachineState *ms = MACHINE(qdev_get_machine());
+ uint64_t pages_left = ms->ram_size / TARGET_PAGE_SIZE;
uint64_t read_count, eos = S390_SKEYS_SAVE_FLAG_EOS;
vaddr cur_gfn = 0;
int error = 0;
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index f0ee8dae68..a2d9a79c84 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -17,6 +17,7 @@
#include "hw/boards.h"
#include "exec/address-spaces.h"
#include "exec/ram_addr.h"
+#include "hw/boards.h"
#include "hw/s390x/s390-virtio-hcall.h"
#include "hw/s390x/sclp.h"
#include "hw/s390x/s390_flic.h"
@@ -142,8 +143,9 @@ static int virtio_ccw_hcall_notify(const uint64_t *args)
static int virtio_ccw_hcall_early_printk(const uint64_t *args)
{
uint64_t mem = args[0];
+ MachineState *ms = MACHINE(qdev_get_machine());
- if (mem < ram_size) {
+ if (mem < ms->ram_size) {
/* Early printk */
return 0;
}
@@ -259,7 +261,8 @@ static void ccw_init(MachineState *machine)
/* get a BUS */
css_bus = virtual_css_bus_init();
s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
- machine->initrd_filename, "s390-ccw.img",
+ machine->initrd_filename,
+ machine->firmware ?: "s390-ccw.img",
"s390-netboot.img", true);
dev = qdev_new(TYPE_S390_PCI_HOST_BRIDGE);
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 14c8e04a89..9a75e0095c 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -42,7 +42,7 @@ typedef enum {
} ssi_sd_mode;
struct ssi_sd_state {
- SSISlave ssidev;
+ SSIPeripheral ssidev;
uint32_t mode;
int cmd;
uint8_t cmdarg[4];
@@ -73,7 +73,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state, SSI_SD)
#define SSI_SDR_ADDRESS_ERROR 0x2000
#define SSI_SDR_PARAMETER_ERROR 0x4000
-static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
+static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
{
ssi_sd_state *s = SSI_SD(dev);
@@ -235,12 +235,12 @@ static const VMStateDescription vmstate_ssi_sd = {
VMSTATE_INT32(arglen, ssi_sd_state),
VMSTATE_INT32(response_pos, ssi_sd_state),
VMSTATE_INT32(stopping, ssi_sd_state),
- VMSTATE_SSI_SLAVE(ssidev, ssi_sd_state),
+ VMSTATE_SSI_PERIPHERAL(ssidev, ssi_sd_state),
VMSTATE_END_OF_LIST()
}
};
-static void ssi_sd_realize(SSISlave *d, Error **errp)
+static void ssi_sd_realize(SSIPeripheral *d, Error **errp)
{
ERRP_GUARD();
ssi_sd_state *s = SSI_SD(d);
@@ -291,7 +291,7 @@ static void ssi_sd_reset(DeviceState *dev)
static void ssi_sd_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
k->realize = ssi_sd_realize;
k->transfer = ssi_sd_transfer;
@@ -304,7 +304,7 @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
static const TypeInfo ssi_sd_info = {
.name = TYPE_SSI_SD,
- .parent = TYPE_SSI_SLAVE,
+ .parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(ssi_sd_state),
.class_init = ssi_sd_class_init,
};
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index f410c08883..d9a9fcbc59 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -49,6 +49,7 @@ static void shix_init(MachineState *machine)
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *rom = g_new(MemoryRegion, 1);
MemoryRegion *sdram = g_new(MemoryRegion, 2);
+ const char *bios_name = machine->firmware ?: BIOS_FILENAME;
cpu = SUPERH_CPU(cpu_create(machine->cpu_type));
@@ -63,8 +64,6 @@ static void shix_init(MachineState *machine)
memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1]);
/* Load BIOS in 0 (and access it through P2, 0xA0000000) */
- if (bios_name == NULL)
- bios_name = BIOS_FILENAME;
ret = load_image_targphys(bios_name, 0, 0x4000);
if (ret < 0 && !qtest_enabled()) {
error_report("Could not load SHIX bios '%s'", bios_name);
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 6a3d39793b..f22c4f5b73 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -678,13 +678,13 @@ static void smbios_build_type_16_table(unsigned dimm_cnt)
t->location = 0x01; /* Other */
t->use = 0x03; /* System memory */
t->error_correction = 0x06; /* Multi-bit ECC (for Microsoft, per SeaBIOS) */
- size_kb = QEMU_ALIGN_UP(ram_size, KiB) / KiB;
+ size_kb = QEMU_ALIGN_UP(current_machine->ram_size, KiB) / KiB;
if (size_kb < MAX_T16_STD_SZ) {
t->maximum_capacity = cpu_to_le32(size_kb);
t->extended_maximum_capacity = cpu_to_le64(0);
} else {
t->maximum_capacity = cpu_to_le32(MAX_T16_STD_SZ);
- t->extended_maximum_capacity = cpu_to_le64(ram_size);
+ t->extended_maximum_capacity = cpu_to_le64(current_machine->ram_size);
}
t->memory_error_information_handle = cpu_to_le16(0xFFFE); /* Not provided */
t->number_of_memory_devices = cpu_to_le16(dimm_cnt);
@@ -911,9 +911,9 @@ void smbios_get_tables(MachineState *ms,
#define MAX_DIMM_SZ (16 * GiB)
#define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
- : ((ram_size - 1) % MAX_DIMM_SZ) + 1)
+ : ((current_machine->ram_size - 1) % MAX_DIMM_SZ) + 1)
- dimm_cnt = QEMU_ALIGN_UP(ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ;
+ dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ;
smbios_build_type_16_table(dimm_cnt);
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index d40b7891f6..4bc4ebea84 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -27,6 +27,7 @@
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/irq.h"
#include "qemu/timer.h"
@@ -185,6 +186,7 @@ static void leon3_set_pil_in(void *opaque, int n, int level)
static void leon3_generic_hw_init(MachineState *machine)
{
ram_addr_t ram_size = machine->ram_size;
+ const char *bios_name = machine->firmware ?: LEON3_PROM_FILENAME;
const char *kernel_filename = machine->kernel_filename;
SPARCCPU *cpu;
CPUSPARCState *env;
@@ -259,9 +261,6 @@ static void leon3_generic_hw_init(MachineState *machine)
memory_region_add_subregion(address_space_mem, LEON3_PROM_OFFSET, prom);
/* Load boot prom */
- if (bios_name == NULL) {
- bios_name = LEON3_PROM_FILENAME;
- }
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 66fecb152a..8686371318 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
+#include "qemu/datadir.h"
#include "qemu-common.h"
#include "cpu.h"
#include "hw/sysbus.h"
@@ -882,7 +883,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
hwdef->max_mem - machine->ram_size);
}
- prom_init(hwdef->slavio_base, bios_name);
+ prom_init(hwdef->slavio_base, machine->firmware);
slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
hwdef->intctl_base + 0x10000ULL,
diff --git a/hw/sparc64/sparc64.c b/hw/sparc64/sparc64.c
index 100b2fab17..e3f9219a10 100644
--- a/hw/sparc64/sparc64.c
+++ b/hw/sparc64/sparc64.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
+#include "hw/boards.h"
#include "hw/char/serial.h"
#include "hw/sparc/sparc64.h"
#include "qemu/timer.h"
@@ -180,7 +181,7 @@ static void main_cpu_reset(void *opaque)
cpu_timer_reset(env->hstick);
env->gregs[1] = 0; /* Memory start */
- env->gregs[2] = ram_size; /* Memory size */
+ env->gregs[2] = current_machine->ram_size; /* Memory size */
env->gregs[3] = 0; /* Machine description XXX */
if (nr_resets++ == 0) {
/* Power on reset */
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 2f8fc670cf..0fa13a7330 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -27,6 +27,7 @@
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "cpu.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_bridge.h"
@@ -578,7 +579,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
/* set up devices */
ram_init(0, machine->ram_size);
- prom_init(hwdef->prom_addr, bios_name);
+ prom_init(hwdef->prom_addr, machine->firmware);
/* Init sabre (PCI host bridge) */
sabre = SABRE(qdev_new(TYPE_SABRE));
@@ -690,7 +691,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
initrd_addr = 0;
kernel_size = sun4u_load_kernel(machine->kernel_filename,
machine->initrd_filename,
- ram_size, &initrd_size, &initrd_addr,
+ machine->ram_size, &initrd_size, &initrd_addr,
&kernel_addr, &kernel_entry);
sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", machine->ram_size,
@@ -713,7 +714,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
fw_cfg = FW_CFG(dev);
fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)machine->smp.cpus);
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus);
- fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)machine->ram_size);
fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index e3d5e26058..16addee4dc 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -191,7 +191,7 @@
#define SNOOP_START 0x0
/*
- * Default segments mapping addresses and size for each slave per
+ * Default segments mapping addresses and size for each peripheral per
* controller. These can be changed when board is initialized with the
* Segment Address Registers.
*/
@@ -269,7 +269,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_TIMINGS,
.nregs_timings = 1,
.conf_enable_w0 = CONF_ENABLE_W0,
- .max_slaves = 1,
+ .max_peripherals = 1,
.segments = aspeed_segments_legacy,
.flash_window_base = ASPEED_SOC_SMC_FLASH_BASE,
.flash_window_size = 0x6000000,
@@ -285,7 +285,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_TIMINGS,
.nregs_timings = 1,
.conf_enable_w0 = CONF_ENABLE_W0,
- .max_slaves = 5,
+ .max_peripherals = 5,
.segments = aspeed_segments_fmc,
.flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
.flash_window_size = 0x10000000,
@@ -303,7 +303,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_SPI_TIMINGS,
.nregs_timings = 1,
.conf_enable_w0 = SPI_CONF_ENABLE_W0,
- .max_slaves = 1,
+ .max_peripherals = 1,
.segments = aspeed_segments_spi,
.flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
.flash_window_size = 0x10000000,
@@ -319,7 +319,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_TIMINGS,
.nregs_timings = 1,
.conf_enable_w0 = CONF_ENABLE_W0,
- .max_slaves = 3,
+ .max_peripherals = 3,
.segments = aspeed_segments_ast2500_fmc,
.flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
.flash_window_size = 0x10000000,
@@ -337,7 +337,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_TIMINGS,
.nregs_timings = 1,
.conf_enable_w0 = CONF_ENABLE_W0,
- .max_slaves = 2,
+ .max_peripherals = 2,
.segments = aspeed_segments_ast2500_spi1,
.flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
.flash_window_size = 0x8000000,
@@ -353,7 +353,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_TIMINGS,
.nregs_timings = 1,
.conf_enable_w0 = CONF_ENABLE_W0,
- .max_slaves = 2,
+ .max_peripherals = 2,
.segments = aspeed_segments_ast2500_spi2,
.flash_window_base = ASPEED_SOC_SPI2_FLASH_BASE,
.flash_window_size = 0x8000000,
@@ -369,7 +369,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_TIMINGS,
.nregs_timings = 1,
.conf_enable_w0 = CONF_ENABLE_W0,
- .max_slaves = 3,
+ .max_peripherals = 3,
.segments = aspeed_segments_ast2600_fmc,
.flash_window_base = ASPEED26_SOC_FMC_FLASH_BASE,
.flash_window_size = 0x10000000,
@@ -387,7 +387,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_TIMINGS,
.nregs_timings = 2,
.conf_enable_w0 = CONF_ENABLE_W0,
- .max_slaves = 2,
+ .max_peripherals = 2,
.segments = aspeed_segments_ast2600_spi1,
.flash_window_base = ASPEED26_SOC_SPI_FLASH_BASE,
.flash_window_size = 0x10000000,
@@ -405,7 +405,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_TIMINGS,
.nregs_timings = 3,
.conf_enable_w0 = CONF_ENABLE_W0,
- .max_slaves = 3,
+ .max_peripherals = 3,
.segments = aspeed_segments_ast2600_spi2,
.flash_window_base = ASPEED26_SOC_SPI2_FLASH_BASE,
.flash_window_size = 0x10000000,
@@ -420,7 +420,7 @@ static const AspeedSMCController controllers[] = {
/*
* The Segment Registers of the AST2400 and AST2500 have a 8MB
- * unit. The address range of a flash SPI slave is encoded with
+ * unit. The address range of a flash SPI peripheral is encoded with
* absolute addresses which should be part of the overall controller
* window.
*/
@@ -442,7 +442,7 @@ static void aspeed_smc_reg_to_segment(const AspeedSMCState *s,
/*
* The Segment Registers of the AST2600 have a 1MB unit. The address
- * range of a flash SPI slave is encoded with offsets in the overall
+ * range of a flash SPI peripheral is encoded with offsets in the overall
* controller window. The previous SoC AST2400 and AST2500 used
* absolute addresses. Only bits [27:20] are relevant and the end
* address is an upper bound limit.
@@ -486,7 +486,7 @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
AspeedSegments seg;
int i;
- for (i = 0; i < s->ctrl->max_slaves; i++) {
+ for (i = 0; i < s->ctrl->max_peripherals; i++) {
if (i == cs) {
continue;
}
@@ -547,7 +547,7 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
*/
if ((s->ctrl->segments == aspeed_segments_ast2500_spi1 ||
s->ctrl->segments == aspeed_segments_ast2500_spi2) &&
- cs == s->ctrl->max_slaves &&
+ cs == s->ctrl->max_peripherals &&
seg.addr + seg.size != s->ctrl->segments[cs].addr +
s->ctrl->segments[cs].size) {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -949,14 +949,14 @@ static void aspeed_smc_reset(DeviceState *d)
memset(s->regs, 0, sizeof s->regs);
- /* Unselect all slaves */
+ /* Unselect all peripherals */
for (i = 0; i < s->num_cs; ++i) {
s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
qemu_set_irq(s->cs_lines[i], true);
}
/* setup the default segment register values and regions for all */
- for (i = 0; i < s->ctrl->max_slaves; ++i) {
+ for (i = 0; i < s->ctrl->max_peripherals; ++i) {
aspeed_smc_flash_set_segment_region(s, i,
s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
}
@@ -1004,8 +1004,9 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
(s->ctrl->has_dma && addr == R_DMA_DRAM_ADDR) ||
(s->ctrl->has_dma && addr == R_DMA_LEN) ||
(s->ctrl->has_dma && addr == R_DMA_CHECKSUM) ||
- (addr >= R_SEG_ADDR0 && addr < R_SEG_ADDR0 + s->ctrl->max_slaves) ||
- (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->ctrl->max_slaves)) {
+ (addr >= R_SEG_ADDR0 &&
+ addr < R_SEG_ADDR0 + s->ctrl->max_peripherals) ||
+ (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->ctrl->max_peripherals)) {
trace_aspeed_smc_read(addr, size, s->regs[addr]);
@@ -1279,7 +1280,7 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
int cs = addr - s->r_ctrl0;
aspeed_smc_flash_update_ctrl(&s->flashes[cs], value);
} else if (addr >= R_SEG_ADDR0 &&
- addr < R_SEG_ADDR0 + s->ctrl->max_slaves) {
+ addr < R_SEG_ADDR0 + s->ctrl->max_peripherals) {
int cs = addr - R_SEG_ADDR0;
if (value != s->regs[R_SEG_ADDR0 + cs]) {
@@ -1352,10 +1353,10 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
s->conf_enable_w0 = s->ctrl->conf_enable_w0;
/* Enforce some real HW limits */
- if (s->num_cs > s->ctrl->max_slaves) {
+ if (s->num_cs > s->ctrl->max_peripherals) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: num_cs cannot exceed: %d\n",
- __func__, s->ctrl->max_slaves);
- s->num_cs = s->ctrl->max_slaves;
+ __func__, s->ctrl->max_peripherals);
+ s->num_cs = s->ctrl->max_peripherals;
}
/* DMA irq. Keep it first for the initialization in the SoC */
@@ -1363,7 +1364,7 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
s->spi = ssi_create_bus(dev, "spi");
- /* Setup cs_lines for slaves */
+ /* Setup cs_lines for peripherals */
s->cs_lines = g_new0(qemu_irq, s->num_cs);
for (i = 0; i < s->num_cs; ++i) {
@@ -1387,16 +1388,16 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
s->ctrl->flash_window_size);
sysbus_init_mmio(sbd, &s->mmio_flash);
- s->flashes = g_new0(AspeedSMCFlash, s->ctrl->max_slaves);
+ s->flashes = g_new0(AspeedSMCFlash, s->ctrl->max_peripherals);
/*
- * Let's create a sub memory region for each possible slave. All
+ * Let's create a sub memory region for each possible peripheral. All
* have a configurable memory segment in the overall flash mapping
* window of the controller but, there is not necessarily a flash
* module behind to handle the memory accesses. This depends on
* the board configuration.
*/
- for (i = 0; i < s->ctrl->max_slaves; ++i) {
+ for (i = 0; i < s->ctrl->max_peripherals; ++i) {
AspeedSMCFlash *fl = &s->flashes[i];
snprintf(name, sizeof(name), "%s.%d", s->ctrl->name, i);
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index cade2e92a8..8954ffebb1 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -174,7 +174,7 @@ static void pl022_write(void *opaque, hwaddr offset,
s->cr1 = value;
if ((s->cr1 & (PL022_CR1_MS | PL022_CR1_SSE))
== (PL022_CR1_MS | PL022_CR1_SSE)) {
- BADF("SPI slave mode not implemented\n");
+ BADF("SPI peripheral mode not implemented\n");
}
pl022_xfer(s);
break;
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 4278d0e444..e5d7ce9523 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -34,11 +34,11 @@ static const TypeInfo ssi_bus_info = {
static void ssi_cs_default(void *opaque, int n, int level)
{
- SSISlave *s = SSI_SLAVE(opaque);
+ SSIPeripheral *s = SSI_PERIPHERAL(opaque);
bool cs = !!level;
assert(n == 0);
if (s->cs != cs) {
- SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
+ SSIPeripheralClass *ssc = SSI_PERIPHERAL_GET_CLASS(s);
if (ssc->set_cs) {
ssc->set_cs(s, cs);
}
@@ -46,9 +46,9 @@ static void ssi_cs_default(void *opaque, int n, int level)
s->cs = cs;
}
-static uint32_t ssi_transfer_raw_default(SSISlave *dev, uint32_t val)
+static uint32_t ssi_transfer_raw_default(SSIPeripheral *dev, uint32_t val)
{
- SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(dev);
+ SSIPeripheralClass *ssc = SSI_PERIPHERAL_GET_CLASS(dev);
if ((dev->cs && ssc->cs_polarity == SSI_CS_HIGH) ||
(!dev->cs && ssc->cs_polarity == SSI_CS_LOW) ||
@@ -58,10 +58,10 @@ static uint32_t ssi_transfer_raw_default(SSISlave *dev, uint32_t val)
return 0;
}
-static void ssi_slave_realize(DeviceState *dev, Error **errp)
+static void ssi_peripheral_realize(DeviceState *dev, Error **errp)
{
- SSISlave *s = SSI_SLAVE(dev);
- SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
+ SSIPeripheral *s = SSI_PERIPHERAL(dev);
+ SSIPeripheralClass *ssc = SSI_PERIPHERAL_GET_CLASS(s);
if (ssc->transfer_raw == ssi_transfer_raw_default &&
ssc->cs_polarity != SSI_CS_NONE) {
@@ -71,23 +71,23 @@ static void ssi_slave_realize(DeviceState *dev, Error **errp)
ssc->realize(s, errp);
}
-static void ssi_slave_class_init(ObjectClass *klass, void *data)
+static void ssi_peripheral_class_init(ObjectClass *klass, void *data)
{
- SSISlaveClass *ssc = SSI_SLAVE_CLASS(klass);
+ SSIPeripheralClass *ssc = SSI_PERIPHERAL_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- dc->realize = ssi_slave_realize;
+ dc->realize = ssi_peripheral_realize;
dc->bus_type = TYPE_SSI_BUS;
if (!ssc->transfer_raw) {
ssc->transfer_raw = ssi_transfer_raw_default;
}
}
-static const TypeInfo ssi_slave_info = {
- .name = TYPE_SSI_SLAVE,
+static const TypeInfo ssi_peripheral_info = {
+ .name = TYPE_SSI_PERIPHERAL,
.parent = TYPE_DEVICE,
- .class_init = ssi_slave_class_init,
- .class_size = sizeof(SSISlaveClass),
+ .class_init = ssi_peripheral_class_init,
+ .class_size = sizeof(SSIPeripheralClass),
.abstract = true,
};
@@ -96,7 +96,7 @@ bool ssi_realize_and_unref(DeviceState *dev, SSIBus *bus, Error **errp)
return qdev_realize_and_unref(dev, &bus->parent_obj, errp);
}
-DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
+DeviceState *ssi_create_peripheral(SSIBus *bus, const char *name)
{
DeviceState *dev = qdev_new(name);
@@ -115,32 +115,32 @@ uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
{
BusState *b = BUS(bus);
BusChild *kid;
- SSISlaveClass *ssc;
+ SSIPeripheralClass *ssc;
uint32_t r = 0;
QTAILQ_FOREACH(kid, &b->children, sibling) {
- SSISlave *slave = SSI_SLAVE(kid->child);
- ssc = SSI_SLAVE_GET_CLASS(slave);
- r |= ssc->transfer_raw(slave, val);
+ SSIPeripheral *peripheral = SSI_PERIPHERAL(kid->child);
+ ssc = SSI_PERIPHERAL_GET_CLASS(peripheral);
+ r |= ssc->transfer_raw(peripheral, val);
}
return r;
}
-const VMStateDescription vmstate_ssi_slave = {
+const VMStateDescription vmstate_ssi_peripheral = {
.name = "SSISlave",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_BOOL(cs, SSISlave),
+ VMSTATE_BOOL(cs, SSIPeripheral),
VMSTATE_END_OF_LIST()
}
};
-static void ssi_slave_register_types(void)
+static void ssi_peripheral_register_types(void)
{
type_register_static(&ssi_bus_info);
- type_register_static(&ssi_slave_info);
+ type_register_static(&ssi_peripheral_info);
}
-type_init(ssi_slave_register_types)
+type_init(ssi_peripheral_register_types)
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index b9371dbf8d..a897034601 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -236,7 +236,8 @@ static void xilinx_spips_update_cs(XilinxSPIPS *s, int field)
if (old_state != new_state) {
s->cs_lines_state[i] = new_state;
s->rx_discard = ARRAY_FIELD_EX32(s->regs, CMND, RX_DISCARD);
- DB_PRINT_L(1, "%sselecting slave %d\n", new_state ? "" : "de", i);
+ DB_PRINT_L(1, "%sselecting peripheral %d\n",
+ new_state ? "" : "de", i);
}
qemu_set_irq(s->cs_lines[i], !new_state);
}
@@ -1154,7 +1155,7 @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
int i;
int flash_addr = ((addr & ~(LQSPI_CACHE_SIZE - 1))
/ num_effective_busses(s));
- int slave = flash_addr >> LQSPI_ADDRESS_BITS;
+ int peripheral = flash_addr >> LQSPI_ADDRESS_BITS;
int cache_entry = 0;
uint32_t u_page_save = s->regs[R_LQSPI_STS] & ~LQSPI_CFG_U_PAGE;
@@ -1162,7 +1163,7 @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
addr > q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) {
xilinx_qspips_invalidate_mmio_ptr(q);
s->regs[R_LQSPI_STS] &= ~LQSPI_CFG_U_PAGE;
- s->regs[R_LQSPI_STS] |= slave ? LQSPI_CFG_U_PAGE : 0;
+ s->regs[R_LQSPI_STS] |= peripheral ? LQSPI_CFG_U_PAGE : 0;
DB_PRINT_L(0, "config reg status: %08x\n", s->regs[R_LQSPI_CFG]);
@@ -1353,7 +1354,7 @@ static void xlnx_zynqmp_qspips_init(Object *obj)
{
XlnxZynqMPQSPIPS *rq = XLNX_ZYNQMP_QSPIPS(obj);
- object_property_add_link(obj, "stream-connected-dma", TYPE_STREAM_SLAVE,
+ object_property_add_link(obj, "stream-connected-dma", TYPE_STREAM_SINK,
(Object **)&rq->dma,
object_property_allow_set_link,
OBJ_PROP_LINK_STRONG);
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index b22b5beda3..e83017c02d 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -20,6 +20,7 @@
#include "hw/virtio/virtio.h"
#include "hw/mem/pc-dimm.h"
#include "hw/qdev-properties.h"
+#include "hw/boards.h"
#include "sysemu/balloon.h"
#include "hw/virtio/virtio-balloon.h"
#include "exec/address-spaces.h"
@@ -748,7 +749,7 @@ static int build_dimm_list(Object *obj, void *opaque)
static ram_addr_t get_current_ram_size(void)
{
GSList *list = NULL, *item;
- ram_addr_t size = ram_size;
+ ram_addr_t size = current_machine->ram_size;
build_dimm_list(qdev_get_machine(), &list);
for (item = list; item; item = g_slist_next(item)) {
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 19805ed6db..bd5e15dd7d 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -42,8 +42,6 @@ typedef uintptr_t ram_addr_t;
# define RAM_ADDR_FMT "%" PRIxPTR
#endif
-extern ram_addr_t ram_size;
-
/* memory API */
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index f94f4ad5d8..17b1f3f0b9 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -26,6 +26,7 @@ OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)
extern MachineState *current_machine;
void machine_run_board_init(MachineState *machine);
+bool machine_smp_parse(MachineState *ms, QemuOpts *opts, Error **errp);
bool machine_usb(MachineState *machine);
int machine_phandle_start(MachineState *machine);
bool machine_dump_guest_core(MachineState *machine);
@@ -282,6 +283,7 @@ struct MachineState {
ram_addr_t maxram_size;
uint64_t ram_slots;
const char *boot_order;
+ const char *boot_once;
char *kernel_filename;
char *kernel_cmdline;
char *initrd_filename;
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index 3f9b052cfc..56080bd1fb 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -102,7 +102,8 @@ void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
-void x86_bios_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw);
+void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
+ MemoryRegion *rom_memory, bool isapc_ram_fw);
void x86_load_linux(X86MachineState *x86ms,
FWCfgState *fw_cfg,
diff --git a/include/hw/misc/max111x.h b/include/hw/misc/max111x.h
index 606cf1e0a2..beff59c815 100644
--- a/include/hw/misc/max111x.h
+++ b/include/hw/misc/max111x.h
@@ -33,7 +33,7 @@
* be lowered once it has been asserted.
*/
struct MAX111xState {
- SSISlave parent_obj;
+ SSIPeripheral parent_obj;
qemu_irq interrupt;
/* Values of inputs at system reset (settable by QOM property) */
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 72ce649eee..259f9c992d 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -781,20 +781,58 @@ static inline AddressSpace *pci_get_address_space(PCIDevice *dev)
return &dev->bus_master_as;
}
-static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
- void *buf, dma_addr_t len, DMADirection dir)
+/**
+ * pci_dma_rw: Read from or write to an address space from PCI device.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @dev: #PCIDevice doing the memory access
+ * @addr: address within the #PCIDevice address space
+ * @buf: buffer with the data transferred
+ * @len: the number of bytes to read or write
+ * @dir: indicates the transfer direction
+ */
+static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
+ void *buf, dma_addr_t len,
+ DMADirection dir)
{
return dma_memory_rw(pci_get_address_space(dev), addr, buf, len, dir);
}
-static inline int pci_dma_read(PCIDevice *dev, dma_addr_t addr,
- void *buf, dma_addr_t len)
+/**
+ * pci_dma_read: Read from an address space from PCI device.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault). Called within RCU critical section.
+ *
+ * @dev: #PCIDevice doing the memory access
+ * @addr: address within the #PCIDevice address space
+ * @buf: buffer with the data transferred
+ * @len: length of the data transferred
+ */
+static inline MemTxResult pci_dma_read(PCIDevice *dev, dma_addr_t addr,
+ void *buf, dma_addr_t len)
{
return pci_dma_rw(dev, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
}
-static inline int pci_dma_write(PCIDevice *dev, dma_addr_t addr,
- const void *buf, dma_addr_t len)
+/**
+ * pci_dma_write: Write to address space from PCI device.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @dev: #PCIDevice doing the memory access
+ * @addr: address within the #PCIDevice address space
+ * @buf: buffer with the data transferred
+ * @len: the number of bytes to write
+ */
+static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
+ const void *buf, dma_addr_t len)
{
return pci_dma_rw(dev, addr, (void *) buf, len, DMA_DIRECTION_FROM_DEVICE);
}
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 6ac86db44e..9fbb22a48d 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -788,14 +788,6 @@ char *qdev_get_fw_dev_path(DeviceState *dev);
char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev);
/**
- * @qdev_machine_init
- *
- * Initialize platform devices before machine init. This is a hack until full
- * support for composition is added.
- */
-void qdev_machine_init(void);
-
-/**
* device_legacy_reset:
*
* Reset a single device (by calling the reset method).
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index 3dd354b52e..16c03fe64f 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -43,7 +43,7 @@ typedef struct AspeedSMCController {
uint8_t r_timings;
uint8_t nregs_timings;
uint8_t conf_enable_w0;
- uint8_t max_slaves;
+ uint8_t max_peripherals;
const AspeedSegments *segments;
hwaddr flash_window_base;
uint32_t flash_window_size;
diff --git a/include/hw/ssi/ssi.h b/include/hw/ssi/ssi.h
index fe3028c39d..f411858ab0 100644
--- a/include/hw/ssi/ssi.h
+++ b/include/hw/ssi/ssi.h
@@ -1,12 +1,14 @@
/* QEMU Synchronous Serial Interface support. */
-/* In principle SSI is a point-point interface. As such the qemu
- implementation has a single slave device on a "bus".
- However it is fairly common for boards to have multiple slaves
- connected to a single master, and select devices with an external
- chip select. This is implemented in qemu by having an explicit mux device.
- It is assumed that master and slave are both using the same transfer width.
- */
+/*
+ * In principle SSI is a point-point interface. As such the qemu
+ * implementation has a single peripheral on a "bus".
+ * However it is fairly common for boards to have multiple peripherals
+ * connected to a single master, and select devices with an external
+ * chip select. This is implemented in qemu by having an explicit mux device.
+ * It is assumed that master and peripheral are both using the same transfer
+ * width.
+ */
#ifndef QEMU_SSI_H
#define QEMU_SSI_H
@@ -16,9 +18,9 @@
typedef enum SSICSMode SSICSMode;
-#define TYPE_SSI_SLAVE "ssi-slave"
-OBJECT_DECLARE_TYPE(SSISlave, SSISlaveClass,
- SSI_SLAVE)
+#define TYPE_SSI_PERIPHERAL "ssi-peripheral"
+OBJECT_DECLARE_TYPE(SSIPeripheral, SSIPeripheralClass,
+ SSI_PERIPHERAL)
#define SSI_GPIO_CS "ssi-gpio-cs"
@@ -28,21 +30,21 @@ enum SSICSMode {
SSI_CS_HIGH,
};
-/* Slave devices. */
-struct SSISlaveClass {
+/* Peripherals. */
+struct SSIPeripheralClass {
DeviceClass parent_class;
- void (*realize)(SSISlave *dev, Error **errp);
+ void (*realize)(SSIPeripheral *dev, Error **errp);
/* if you have standard or no CS behaviour, just override transfer.
* This is called when the device cs is active (true by default).
*/
- uint32_t (*transfer)(SSISlave *dev, uint32_t val);
+ uint32_t (*transfer)(SSIPeripheral *dev, uint32_t val);
/* called when the CS line changes. Optional, devices only need to implement
* this if they have side effects associated with the cs line (beyond
* tristating the txrx lines).
*/
- int (*set_cs)(SSISlave *dev, bool select);
+ int (*set_cs)(SSIPeripheral *dev, bool select);
/* define whether or not CS exists and is active low/high */
SSICSMode cs_polarity;
@@ -51,30 +53,30 @@ struct SSISlaveClass {
* cs_polarity are unused if this is overwritten. Transfer_raw will
* always be called for the device for every txrx access to the parent bus
*/
- uint32_t (*transfer_raw)(SSISlave *dev, uint32_t val);
+ uint32_t (*transfer_raw)(SSIPeripheral *dev, uint32_t val);
};
-struct SSISlave {
+struct SSIPeripheral {
DeviceState parent_obj;
/* Chip select state */
bool cs;
};
-extern const VMStateDescription vmstate_ssi_slave;
+extern const VMStateDescription vmstate_ssi_peripheral;
-#define VMSTATE_SSI_SLAVE(_field, _state) { \
+#define VMSTATE_SSI_PERIPHERAL(_field, _state) { \
.name = (stringify(_field)), \
- .size = sizeof(SSISlave), \
- .vmsd = &vmstate_ssi_slave, \
+ .size = sizeof(SSIPeripheral), \
+ .vmsd = &vmstate_ssi_peripheral, \
.flags = VMS_STRUCT, \
- .offset = vmstate_offset_value(_state, _field, SSISlave), \
+ .offset = vmstate_offset_value(_state, _field, SSIPeripheral), \
}
-DeviceState *ssi_create_slave(SSIBus *bus, const char *name);
+DeviceState *ssi_create_peripheral(SSIBus *bus, const char *name);
/**
- * ssi_realize_and_unref: realize and unref an SSI slave device
- * @dev: SSI slave device to realize
+ * ssi_realize_and_unref: realize and unref an SSI peripheral
+ * @dev: SSI peripheral to realize
* @bus: SSI bus to put it on
* @errp: error pointer
*
@@ -85,10 +87,10 @@ DeviceState *ssi_create_slave(SSIBus *bus, const char *name);
* This function is useful if you have created @dev via qdev_new()
* (which takes a reference to the device it returns to you), so that
* you can set properties on it before realizing it. If you don't need
- * to set properties then ssi_create_slave() is probably better (as it
+ * to set properties then ssi_create_peripheral() is probably better (as it
* does the create, init and realize in one step).
*
- * If you are embedding the SSI slave into another QOM device and
+ * If you are embedding the SSI peripheral into another QOM device and
* initialized it via some variant on object_initialize_child() then
* do not use this function, because that family of functions arrange
* for the only reference to the child device to be held by the parent
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
index b96de21b34..3eae73480e 100644
--- a/include/hw/ssi/xilinx_spips.h
+++ b/include/hw/ssi/xilinx_spips.h
@@ -99,7 +99,7 @@ typedef struct XilinxQSPIPS XilinxQSPIPS;
struct XlnxZynqMPQSPIPS {
XilinxQSPIPS parent_obj;
- StreamSlave *dma;
+ StreamSink *dma;
int gqspi_irqline;
uint32_t regs[XLNX_ZYNQMP_SPIPS_R_MAX];
diff --git a/include/hw/stream.h b/include/hw/stream.h
index e39d5a5b55..f166facb09 100644
--- a/include/hw/stream.h
+++ b/include/hw/stream.h
@@ -3,51 +3,50 @@
#include "qom/object.h"
-/* stream slave. Used until qdev provides a generic way. */
-#define TYPE_STREAM_SLAVE "stream-slave"
+#define TYPE_STREAM_SINK "stream-sink"
-typedef struct StreamSlaveClass StreamSlaveClass;
-DECLARE_CLASS_CHECKERS(StreamSlaveClass, STREAM_SLAVE,
- TYPE_STREAM_SLAVE)
-#define STREAM_SLAVE(obj) \
- INTERFACE_CHECK(StreamSlave, (obj), TYPE_STREAM_SLAVE)
+typedef struct StreamSinkClass StreamSinkClass;
+DECLARE_CLASS_CHECKERS(StreamSinkClass, STREAM_SINK,
+ TYPE_STREAM_SINK)
+#define STREAM_SINK(obj) \
+ INTERFACE_CHECK(StreamSink, (obj), TYPE_STREAM_SINK)
-typedef struct StreamSlave StreamSlave;
+typedef struct StreamSink StreamSink;
typedef void (*StreamCanPushNotifyFn)(void *opaque);
-struct StreamSlaveClass {
+struct StreamSinkClass {
InterfaceClass parent;
/**
- * can push - determine if a stream slave is capable of accepting at least
+ * can push - determine if a stream sink is capable of accepting at least
* one byte of data. Returns false if cannot accept. If not implemented, the
- * slave is assumed to always be capable of receiving.
- * @notify: Optional callback that the slave will call when the slave is
+ * sink is assumed to always be capable of receiving.
+ * @notify: Optional callback that the sink will call when the sink is
* capable of receiving again. Only called if false is returned.
* @notify_opaque: opaque data to pass to notify call.
*/
- bool (*can_push)(StreamSlave *obj, StreamCanPushNotifyFn notify,
+ bool (*can_push)(StreamSink *obj, StreamCanPushNotifyFn notify,
void *notify_opaque);
/**
- * push - push data to a Stream slave. The number of bytes pushed is
- * returned. If the slave short returns, the master must wait before trying
- * again, the slave may continue to just return 0 waiting for the vm time to
+ * push - push data to a Stream sink. The number of bytes pushed is
+ * returned. If the sink short returns, the master must wait before trying
+ * again, the sink may continue to just return 0 waiting for the vm time to
* advance. The can_push() function can be used to trap the point in time
- * where the slave is ready to receive again, otherwise polling on a QEMU
+ * where the sink is ready to receive again, otherwise polling on a QEMU
* timer will work.
- * @obj: Stream slave to push to
+ * @obj: Stream sink to push to
* @buf: Data to write
* @len: Maximum number of bytes to write
* @eop: End of packet flag
*/
- size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len, bool eop);
+ size_t (*push)(StreamSink *obj, unsigned char *buf, size_t len, bool eop);
};
size_t
-stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop);
+stream_push(StreamSink *sink, uint8_t *buf, size_t len, bool eop);
bool
-stream_can_push(StreamSlave *sink, StreamCanPushNotifyFn notify,
+stream_can_push(StreamSink *sink, StreamCanPushNotifyFn notify,
void *notify_opaque);
diff --git a/include/migration/misc.h b/include/migration/misc.h
index 34e7d75713..bccc1b6b44 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -58,7 +58,6 @@ void dump_vmstate_json_to_file(FILE *out_fp);
/* migration/migration.c */
void migration_object_init(void);
void migration_shutdown(void);
-void qemu_start_incoming_migration(const char *uri, Error **errp);
bool migration_is_idle(void);
bool migration_is_active(MigrationState *);
void add_migration_state_change_notifier(Notifier *notify);
diff --git a/include/qemu-common.h b/include/qemu-common.h
index fda7dc6ca7..654621444e 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -108,27 +108,6 @@ void qemu_progress_end(void);
void qemu_progress_print(float delta, int max);
const char *qemu_get_vm_name(void);
-#define QEMU_FILE_TYPE_BIOS 0
-#define QEMU_FILE_TYPE_KEYMAP 1
-/**
- * qemu_find_file:
- * @type: QEMU_FILE_TYPE_BIOS (for BIOS, VGA BIOS)
- * or QEMU_FILE_TYPE_KEYMAP (for keymaps).
- * @name: Relative or absolute file name
- *
- * If @name exists on disk as an absolute path, or a path relative
- * to the current directory, then returns @name unchanged.
- * Otherwise searches for @name file in the data directories, either
- * configured at build time (DATADIR) or registered with the -L command
- * line option.
- *
- * The caller must use g_free() to free the returned data when it is
- * no longer required.
- *
- * Returns: a path that can access @name, or NULL if no matching file exists.
- */
-char *qemu_find_file(int type, const char *name);
-
/* OS specific functions */
void os_setup_early_signal_handling(void);
int os_parse_cmd_args(int index, const char *optarg);
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index d74f920152..29226107bd 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -8,7 +8,6 @@ QemuOpts *qemu_find_opts_singleton(const char *group);
void qemu_add_opts(QemuOptsList *list);
void qemu_add_drive_opts(QemuOptsList *list);
-int qemu_set_option(const char *str);
int qemu_global_option(const char *str);
void qemu_config_write(FILE *fp);
diff --git a/include/qemu/datadir.h b/include/qemu/datadir.h
new file mode 100644
index 0000000000..21f9097f58
--- /dev/null
+++ b/include/qemu/datadir.h
@@ -0,0 +1,28 @@
+#ifndef QEMU_DATADIR_H
+#define QEMU_DATADIR_H
+
+#define QEMU_FILE_TYPE_BIOS 0
+#define QEMU_FILE_TYPE_KEYMAP 1
+/**
+ * qemu_find_file:
+ * @type: QEMU_FILE_TYPE_BIOS (for BIOS, VGA BIOS)
+ * or QEMU_FILE_TYPE_KEYMAP (for keymaps).
+ * @name: Relative or absolute file name
+ *
+ * If @name exists on disk as an absolute path, or a path relative
+ * to the current directory, then returns @name unchanged.
+ * Otherwise searches for @name file in the data directories, either
+ * configured at build time (DATADIR) or registered with the -L command
+ * line option.
+ *
+ * The caller must use g_free() to free the returned data when it is
+ * no longer required.
+ *
+ * Returns: a path that can access @name, or NULL if no matching file exists.
+ */
+char *qemu_find_file(int type, const char *name);
+void qemu_add_default_firmwarepath(void);
+void qemu_add_data_dir(char *path);
+void qemu_list_data_dirs(void);
+
+#endif
diff --git a/include/qemu/option.h b/include/qemu/option.h
index ac69352e0e..f73e0dc7d9 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -119,8 +119,7 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp);
void qemu_opts_reset(QemuOptsList *list);
void qemu_opts_loc_restore(QemuOpts *opts);
-bool qemu_opts_set(QemuOptsList *list, const char *id,
- const char *name, const char *value, Error **errp);
+bool qemu_opts_set(QemuOptsList *list, const char *name, const char *value, Error **errp);
const char *qemu_opts_id(QemuOpts *opts);
void qemu_opts_set_id(QemuOpts *opts, char *id);
void qemu_opts_del(QemuOpts *opts);
diff --git a/include/standard-headers/asm-x86/kvm_para.h b/include/standard-headers/asm-x86/kvm_para.h
index 07877d3295..215d01b4ec 100644
--- a/include/standard-headers/asm-x86/kvm_para.h
+++ b/include/standard-headers/asm-x86/kvm_para.h
@@ -32,6 +32,7 @@
#define KVM_FEATURE_POLL_CONTROL 12
#define KVM_FEATURE_PV_SCHED_YIELD 13
#define KVM_FEATURE_ASYNC_PF_INT 14
+#define KVM_FEATURE_MSI_EXT_DEST_ID 15
#define KVM_HINTS_REALTIME 0
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 80c5bc3e02..a052f7bca3 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -1,7 +1,7 @@
/*
* DMA helper functions
*
- * Copyright (c) 2009 Red Hat
+ * Copyright (c) 2009, 2020 Red Hat
*
* This work is licensed under the terms of the GNU General Public License
* (GNU GPL), version 2 or later.
@@ -80,51 +80,118 @@ static inline bool dma_memory_valid(AddressSpace *as,
MEMTXATTRS_UNSPECIFIED);
}
-static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
- void *buf, dma_addr_t len,
- DMADirection dir)
+static inline MemTxResult dma_memory_rw_relaxed(AddressSpace *as,
+ dma_addr_t addr,
+ void *buf, dma_addr_t len,
+ DMADirection dir)
{
- return (bool)address_space_rw(as, addr, MEMTXATTRS_UNSPECIFIED,
- buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
+ return address_space_rw(as, addr, MEMTXATTRS_UNSPECIFIED,
+ buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
}
-static inline int dma_memory_read_relaxed(AddressSpace *as, dma_addr_t addr,
- void *buf, dma_addr_t len)
+static inline MemTxResult dma_memory_read_relaxed(AddressSpace *as,
+ dma_addr_t addr,
+ void *buf, dma_addr_t len)
{
return dma_memory_rw_relaxed(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
}
-static inline int dma_memory_write_relaxed(AddressSpace *as, dma_addr_t addr,
- const void *buf, dma_addr_t len)
+static inline MemTxResult dma_memory_write_relaxed(AddressSpace *as,
+ dma_addr_t addr,
+ const void *buf,
+ dma_addr_t len)
{
return dma_memory_rw_relaxed(as, addr, (void *)buf, len,
DMA_DIRECTION_FROM_DEVICE);
}
-static inline int dma_memory_rw(AddressSpace *as, dma_addr_t addr,
- void *buf, dma_addr_t len,
- DMADirection dir)
+/**
+ * dma_memory_rw: Read from or write to an address space from DMA controller.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ * @len: the number of bytes to read or write
+ * @dir: indicates the transfer direction
+ */
+static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr,
+ void *buf, dma_addr_t len,
+ DMADirection dir)
{
dma_barrier(as, dir);
return dma_memory_rw_relaxed(as, addr, buf, len, dir);
}
-static inline int dma_memory_read(AddressSpace *as, dma_addr_t addr,
- void *buf, dma_addr_t len)
+/**
+ * dma_memory_read: Read from an address space from DMA controller.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault). Called within RCU critical section.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ * @len: length of the data transferred
+ */
+static inline MemTxResult dma_memory_read(AddressSpace *as, dma_addr_t addr,
+ void *buf, dma_addr_t len)
{
return dma_memory_rw(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
}
-static inline int dma_memory_write(AddressSpace *as, dma_addr_t addr,
- const void *buf, dma_addr_t len)
+/**
+ * address_space_write: Write to address space from DMA controller.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ * @len: the number of bytes to write
+ */
+static inline MemTxResult dma_memory_write(AddressSpace *as, dma_addr_t addr,
+ const void *buf, dma_addr_t len)
{
return dma_memory_rw(as, addr, (void *)buf, len,
DMA_DIRECTION_FROM_DEVICE);
}
-int dma_memory_set(AddressSpace *as, dma_addr_t addr, uint8_t c, dma_addr_t len);
+/**
+ * dma_memory_set: Fill memory with a constant byte from DMA controller.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @c: constant byte to fill the memory
+ * @len: the number of bytes to fill with the constant byte
+ */
+MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
+ uint8_t c, dma_addr_t len);
+/**
+ * address_space_map: Map a physical memory region into a host virtual address.
+ *
+ * May map a subset of the requested range, given by and returned in @plen.
+ * May return %NULL and set *@plen to zero(0), if resources needed to perform
+ * the mapping are exhausted.
+ * Use only for reads OR writes - not for read-modify-write operations.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @len: pointer to length of buffer; updated on return
+ * @dir: indicates the transfer direction
+ */
static inline void *dma_memory_map(AddressSpace *as,
dma_addr_t addr, dma_addr_t *len,
DMADirection dir)
@@ -138,6 +205,20 @@ static inline void *dma_memory_map(AddressSpace *as,
return p;
}
+/**
+ * address_space_unmap: Unmaps a memory region previously mapped
+ * by dma_memory_map()
+ *
+ * Will also mark the memory as dirty if @dir == %DMA_DIRECTION_FROM_DEVICE.
+ * @access_len gives the amount of memory that was actually read or written
+ * by the caller.
+ *
+ * @as: #AddressSpace used
+ * @buffer: host pointer as returned by address_space_map()
+ * @len: buffer length as returned by address_space_map()
+ * @dir: indicates the transfer direction
+ * @access_len: amount of data actually transferred
+ */
static inline void dma_memory_unmap(AddressSpace *as,
void *buffer, dma_addr_t len,
DMADirection dir, dma_addr_t access_len)
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 817ff4cf75..29c32f9851 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -8,22 +8,22 @@
/* vl.c */
-extern const char *bios_name;
extern int only_migratable;
extern const char *qemu_name;
extern QemuUUID qemu_uuid;
extern bool qemu_uuid_set;
-void qemu_add_data_dir(char *path);
-
void qemu_add_exit_notifier(Notifier *notify);
void qemu_remove_exit_notifier(Notifier *notify);
extern bool machine_init_done;
+void qemu_run_machine_init_done_notifiers(void);
void qemu_add_machine_init_done_notifier(Notifier *notify);
void qemu_remove_machine_init_done_notifier(Notifier *notify);
+void configure_rtc(QemuOpts *opts);
+
extern int autostart;
typedef enum {
@@ -71,10 +71,6 @@ void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict);
/* Return the Chardev for serial port i, or NULL if none */
Chardev *serial_hd(int i);
-/* return the number of serial ports defined by the user. serial_hd(i)
- * will always return NULL for any i which is greater than or equal to this.
- */
-int serial_max_hds(void);
/* parallel ports */
diff --git a/include/sysemu/whpx.h b/include/sysemu/whpx.h
index 59edf13742..9346fd92e9 100644
--- a/include/sysemu/whpx.h
+++ b/include/sysemu/whpx.h
@@ -15,11 +15,33 @@
#ifdef CONFIG_WHPX
+#include "whp-dispatch.h"
+
+struct whpx_state {
+ uint64_t mem_quota;
+ WHV_PARTITION_HANDLE partition;
+ bool kernel_irqchip_allowed;
+ bool kernel_irqchip_required;
+ bool apic_in_platform;
+};
+
+struct whpx_lapic_state {
+ struct {
+ uint32_t data;
+ uint32_t padding[3];
+ } fields[256];
+};
+
+extern struct whpx_state whpx_global;
int whpx_enabled(void);
+void whpx_apic_get(DeviceState *s);
+#define whpx_apic_in_platform() (whpx_global.apic_in_platform)
+
#else /* CONFIG_WHPX */
#define whpx_enabled() (0)
+#define whpx_apic_in_platform() (0)
#endif /* CONFIG_WHPX */
diff --git a/migration/migration.c b/migration/migration.c
index 87a9b59f83..e0dbde4091 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -118,8 +118,6 @@
static NotifierList migration_state_notifiers =
NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
-static bool deferred_incoming;
-
/* Messages sent on the return path from destination to source */
enum mig_rp_message_type {
MIG_RP_MSG_INVALID = 0, /* Must be 0 */
@@ -182,6 +180,10 @@ void migration_object_init(void)
error_report_err(err);
exit(1);
}
+
+ blk_mig_init();
+ ram_mig_init();
+ dirty_bitmap_mig_init();
}
void migration_shutdown(void)
@@ -272,19 +274,6 @@ static bool migrate_late_block_activate(void)
}
/*
- * Called on -incoming with a defer: uri.
- * The migration can be started later after any parameters have been
- * changed.
- */
-static void deferred_incoming_migration(Error **errp)
-{
- if (deferred_incoming) {
- error_setg(errp, "Incoming migration already deferred");
- }
- deferred_incoming = true;
-}
-
-/*
* Send a message on the return channel back to the source
* of the migration.
*/
@@ -425,16 +414,14 @@ void migrate_add_address(SocketAddress *address)
addrs->value = QAPI_CLONE(SocketAddress, address);
}
-void qemu_start_incoming_migration(const char *uri, Error **errp)
+static void qemu_start_incoming_migration(const char *uri, Error **errp)
{
const char *p = NULL;
qapi_event_send_migration(MIGRATION_STATUS_SETUP);
- if (!strcmp(uri, "defer")) {
- deferred_incoming_migration(errp);
- } else if (strstart(uri, "tcp:", &p) ||
- strstart(uri, "unix:", NULL) ||
- strstart(uri, "vsock:", NULL)) {
+ if (strstart(uri, "tcp:", &p) ||
+ strstart(uri, "unix:", NULL) ||
+ strstart(uri, "vsock:", NULL)) {
socket_start_incoming_migration(p ? p : uri, errp);
#ifdef CONFIG_RDMA
} else if (strstart(uri, "rdma:", &p)) {
@@ -1984,14 +1971,14 @@ void qmp_migrate_incoming(const char *uri, Error **errp)
Error *local_err = NULL;
static bool once = true;
- if (!deferred_incoming) {
- error_setg(errp, "For use with '-incoming defer'");
- return;
- }
if (!once) {
error_setg(errp, "The incoming migration has already been started");
return;
}
+ if (!runstate_check(RUN_STATE_INMIGRATE)) {
+ error_setg(errp, "'-incoming' was not specified on the command line");
+ return;
+ }
qemu_start_incoming_migration(uri, &local_err);
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 1204233999..d40f4f4391 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -213,6 +213,11 @@ static bool cmd_can_preconfig(const HMPCommand *cmd)
return strchr(cmd->flags, 'p');
}
+static bool cmd_available(const HMPCommand *cmd)
+{
+ return !runstate_check(RUN_STATE_PRECONFIG) || cmd_can_preconfig(cmd);
+}
+
static void help_cmd_dump_one(Monitor *mon,
const HMPCommand *cmd,
char **prefix_args,
@@ -220,7 +225,7 @@ static void help_cmd_dump_one(Monitor *mon,
{
int i;
- if (runstate_check(RUN_STATE_PRECONFIG) && !cmd_can_preconfig(cmd)) {
+ if (!cmd_available(cmd)) {
return;
}
@@ -248,8 +253,7 @@ static void help_cmd_dump(Monitor *mon, const HMPCommand *cmds,
/* Find one entry to dump */
for (cmd = cmds; cmd->name != NULL; cmd++) {
if (hmp_compare_cmd(args[arg_index], cmd->name) &&
- ((!runstate_check(RUN_STATE_PRECONFIG) ||
- cmd_can_preconfig(cmd)))) {
+ cmd_available(cmd)) {
if (cmd->sub_table) {
/* continue with next arg */
help_cmd_dump(mon, cmd->sub_table,
@@ -653,7 +657,7 @@ static const HMPCommand *monitor_parse_command(MonitorHMP *hmp_mon,
(int)(p - cmdp_start), cmdp_start);
return NULL;
}
- if (runstate_check(RUN_STATE_PRECONFIG) && !cmd_can_preconfig(cmd)) {
+ if (!cmd_available(cmd)) {
monitor_printf(mon, "Command '%.*s' not available with -preconfig "
"until after exit_preconfig.\n",
(int)(p - cmdp_start), cmdp_start);
@@ -1225,8 +1229,7 @@ static void monitor_find_completion_by_table(MonitorHMP *mon,
}
readline_set_completion_index(mon->rs, strlen(cmdname));
for (cmd = cmd_table; cmd->name != NULL; cmd++) {
- if (!runstate_check(RUN_STATE_PRECONFIG) ||
- cmd_can_preconfig(cmd)) {
+ if (cmd_available(cmd)) {
cmd_completion(mon, cmdname, cmd->name);
}
}
@@ -1234,8 +1237,7 @@ static void monitor_find_completion_by_table(MonitorHMP *mon,
/* find the command */
for (cmd = cmd_table; cmd->name != NULL; cmd++) {
if (hmp_compare_cmd(args[0], cmd->name) &&
- (!runstate_check(RUN_STATE_PRECONFIG) ||
- cmd_can_preconfig(cmd))) {
+ cmd_available(cmd)) {
break;
}
}
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index ffbf948d55..6223a28e8b 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -384,8 +384,9 @@ ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp)
MemoryInfo *qmp_query_memory_size_summary(Error **errp)
{
MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo));
+ MachineState *ms = MACHINE(qdev_get_machine());
- mem_info->base_memory = ram_size;
+ mem_info->base_memory = ms->ram_size;
mem_info->plugged_memory = get_plugged_memory_size();
mem_info->has_plugged_memory =
diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 64d966aeeb..7a40f4604b 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -292,7 +292,7 @@ class QEMUMachine:
for _ in range(self._console_index):
args.extend(['-serial', 'null'])
if self._console_set:
- chardev = ('socket,id=console,path=%s,server,nowait' %
+ chardev = ('socket,id=console,path=%s,server=on,wait=off' %
self._console_address)
args.extend(['-chardev', chardev])
if self._console_device_type is None:
diff --git a/qemu-options.hx b/qemu-options.hx
index 104632ea34..e60ad42976 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1406,25 +1406,25 @@ ERST
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
"-fsdev local,id=id,path=path,security_model=mapped-xattr|mapped-file|passthrough|none\n"
- " [,writeout=immediate][,readonly][,fmode=fmode][,dmode=dmode]\n"
+ " [,writeout=immediate][,readonly=on][,fmode=fmode][,dmode=dmode]\n"
" [[,throttling.bps-total=b]|[[,throttling.bps-read=r][,throttling.bps-write=w]]]\n"
" [[,throttling.iops-total=i]|[[,throttling.iops-read=r][,throttling.iops-write=w]]]\n"
" [[,throttling.bps-total-max=bm]|[[,throttling.bps-read-max=rm][,throttling.bps-write-max=wm]]]\n"
" [[,throttling.iops-total-max=im]|[[,throttling.iops-read-max=irm][,throttling.iops-write-max=iwm]]]\n"
" [[,throttling.iops-size=is]]\n"
- "-fsdev proxy,id=id,socket=socket[,writeout=immediate][,readonly]\n"
- "-fsdev proxy,id=id,sock_fd=sock_fd[,writeout=immediate][,readonly]\n"
+ "-fsdev proxy,id=id,socket=socket[,writeout=immediate][,readonly=on]\n"
+ "-fsdev proxy,id=id,sock_fd=sock_fd[,writeout=immediate][,readonly=on]\n"
"-fsdev synth,id=id\n",
QEMU_ARCH_ALL)
SRST
-``-fsdev local,id=id,path=path,security_model=security_model [,writeout=writeout][,readonly][,fmode=fmode][,dmode=dmode] [,throttling.option=value[,throttling.option=value[,...]]]``
+``-fsdev local,id=id,path=path,security_model=security_model [,writeout=writeout][,readonly=on][,fmode=fmode][,dmode=dmode] [,throttling.option=value[,throttling.option=value[,...]]]``
\
-``-fsdev proxy,id=id,socket=socket[,writeout=writeout][,readonly]``
+``-fsdev proxy,id=id,socket=socket[,writeout=writeout][,readonly=on]``
\
-``-fsdev proxy,id=id,sock_fd=sock_fd[,writeout=writeout][,readonly]``
+``-fsdev proxy,id=id,sock_fd=sock_fd[,writeout=writeout][,readonly=on]``
\
-``-fsdev synth,id=id[,readonly]``
+``-fsdev synth,id=id[,readonly=on]``
Define a new file system device. Valid options are:
``local``
@@ -1467,7 +1467,7 @@ SRST
guest only when the data has been reported as written by the
storage subsystem.
- ``readonly``
+ ``readonly=on``
Enables exporting 9p share as a readonly mount for guests. By
default read-write access is given.
@@ -1532,18 +1532,18 @@ ERST
DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs,
"-virtfs local,path=path,mount_tag=tag,security_model=mapped-xattr|mapped-file|passthrough|none\n"
- " [,id=id][,writeout=immediate][,readonly][,fmode=fmode][,dmode=dmode][,multidevs=remap|forbid|warn]\n"
- "-virtfs proxy,mount_tag=tag,socket=socket[,id=id][,writeout=immediate][,readonly]\n"
- "-virtfs proxy,mount_tag=tag,sock_fd=sock_fd[,id=id][,writeout=immediate][,readonly]\n"
- "-virtfs synth,mount_tag=tag[,id=id][,readonly]\n",
+ " [,id=id][,writeout=immediate][,readonly=on][,fmode=fmode][,dmode=dmode][,multidevs=remap|forbid|warn]\n"
+ "-virtfs proxy,mount_tag=tag,socket=socket[,id=id][,writeout=immediate][,readonly=on]\n"
+ "-virtfs proxy,mount_tag=tag,sock_fd=sock_fd[,id=id][,writeout=immediate][,readonly=on]\n"
+ "-virtfs synth,mount_tag=tag[,id=id][,readonly=on]\n",
QEMU_ARCH_ALL)
SRST
-``-virtfs local,path=path,mount_tag=mount_tag ,security_model=security_model[,writeout=writeout][,readonly] [,fmode=fmode][,dmode=dmode][,multidevs=multidevs]``
+``-virtfs local,path=path,mount_tag=mount_tag ,security_model=security_model[,writeout=writeout][,readonly=on] [,fmode=fmode][,dmode=dmode][,multidevs=multidevs]``
\
-``-virtfs proxy,socket=socket,mount_tag=mount_tag [,writeout=writeout][,readonly]``
+``-virtfs proxy,socket=socket,mount_tag=mount_tag [,writeout=writeout][,readonly=on]``
\
-``-virtfs proxy,sock_fd=sock_fd,mount_tag=mount_tag [,writeout=writeout][,readonly]``
+``-virtfs proxy,sock_fd=sock_fd,mount_tag=mount_tag [,writeout=writeout][,readonly=on]``
\
``-virtfs synth,mount_tag=mount_tag``
Define a new virtual filesystem device and expose it to the guest using
@@ -1598,7 +1598,7 @@ SRST
guest only when the data has been reported as written by the
storage subsystem.
- ``readonly``
+ ``readonly=on``
Enables exporting 9p share as a readonly mount for guests. By
default read-write access is given.
diff --git a/qom/object.c b/qom/object.c
index e73d70a993..f2ae6e6b2a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -2175,11 +2175,10 @@ static void property_set_str(Object *obj, Visitor *v, const char *name,
g_free(value);
}
-static void property_release_str(Object *obj, const char *name,
- void *opaque)
+static void property_release_data(Object *obj, const char *name,
+ void *opaque)
{
- StringProperty *prop = opaque;
- g_free(prop);
+ g_free(opaque);
}
ObjectProperty *
@@ -2195,7 +2194,7 @@ object_property_add_str(Object *obj, const char *name,
return object_property_add(obj, name, "string",
get ? property_get_str : NULL,
set ? property_set_str : NULL,
- property_release_str,
+ property_release_data,
prop);
}
@@ -2252,13 +2251,6 @@ static void property_set_bool(Object *obj, Visitor *v, const char *name,
prop->set(obj, value, errp);
}
-static void property_release_bool(Object *obj, const char *name,
- void *opaque)
-{
- BoolProperty *prop = opaque;
- g_free(prop);
-}
-
ObjectProperty *
object_property_add_bool(Object *obj, const char *name,
bool (*get)(Object *, Error **),
@@ -2272,7 +2264,7 @@ object_property_add_bool(Object *obj, const char *name,
return object_property_add(obj, name, "bool",
get ? property_get_bool : NULL,
set ? property_set_bool : NULL,
- property_release_bool,
+ property_release_data,
prop);
}
@@ -2321,13 +2313,6 @@ static void property_set_enum(Object *obj, Visitor *v, const char *name,
prop->set(obj, value, errp);
}
-static void property_release_enum(Object *obj, const char *name,
- void *opaque)
-{
- EnumProperty *prop = opaque;
- g_free(prop);
-}
-
ObjectProperty *
object_property_add_enum(Object *obj, const char *name,
const char *typename,
@@ -2344,7 +2329,7 @@ object_property_add_enum(Object *obj, const char *name,
return object_property_add(obj, name, typename,
get ? property_get_enum : NULL,
set ? property_set_enum : NULL,
- property_release_enum,
+ property_release_data,
prop);
}
@@ -2411,13 +2396,6 @@ out_end:
visit_end_struct(v, NULL);
}
-static void property_release_tm(Object *obj, const char *name,
- void *opaque)
-{
- TMProperty *prop = opaque;
- g_free(prop);
-}
-
ObjectProperty *
object_property_add_tm(Object *obj, const char *name,
void (*get)(Object *, struct tm *, Error **))
@@ -2428,7 +2406,7 @@ object_property_add_tm(Object *obj, const char *name,
return object_property_add(obj, name, "struct tm",
get ? property_get_tm : NULL, NULL,
- property_release_tm,
+ property_release_data,
prop);
}
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 4fbaaa05e3..4b19851b2d 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -56,6 +56,13 @@ Output format selection (mutually exclusive):
-rst Output reStructuredText format.
-none Do not output documentation, only warnings.
+Output format selection modifier (affects only ReST output):
+
+ -sphinx-version Use the ReST C domain dialect compatible with an
+ specific Sphinx Version.
+ If not specified, kernel-doc will auto-detect using
+ the sphinx-build version found on PATH.
+
Output selection (mutually exclusive):
-export Only output documentation for symbols that have been
exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL()
@@ -66,13 +73,10 @@ Output selection (mutually exclusive):
-function NAME Only output documentation for the given function(s)
or DOC: section title(s). All other functions and DOC:
sections are ignored. May be specified multiple times.
- -nofunction NAME Do NOT output documentation for the given function(s);
- only output documentation for the other functions and
- DOC: sections. May be specified multiple times.
+ -nosymbol NAME Exclude the specified symbols from the output
+ documentation. May be specified multiple times.
Output selection modifiers:
- -sphinx-version VER Generate rST syntax for the specified Sphinx version.
- Only works with reStructuredTextFormat.
-no-doc-sections Do not output DOC: sections.
-enable-lineno Enable output of #define LINENO lines. Only works with
reStructuredText format.
@@ -83,6 +87,7 @@ Output selection modifiers:
Other parameters:
-v Verbose output, more warnings and other information.
-h Print this help.
+ -Werror Treat warnings as errors.
EOF
print $message;
@@ -215,7 +220,9 @@ my $type_constant = '\b``([^\`]+)``\b';
my $type_constant2 = '\%([-_\w]+)';
my $type_func = '(\w+)\(\)';
my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
+my $type_param_ref = '([\!]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params
+my $type_fp_param2 = '\@(\w+->\S+)\(\)'; # Special RST handling for structs with func ptr params
my $type_env = '(\$\w+)';
my $type_enum = '#(enum\s*([_\w]+))';
my $type_struct = '#(struct\s*([_\w]+))';
@@ -238,6 +245,7 @@ my @highlights_man = (
[$type_typedef, "\\\\fI\$1\\\\fP"],
[$type_union, "\\\\fI\$1\\\\fP"],
[$type_param, "\\\\fI\$1\\\\fP"],
+ [$type_param_ref, "\\\\fI\$1\$2\\\\fP"],
[$type_member, "\\\\fI\$1\$2\$3\\\\fP"],
[$type_fallback, "\\\\fI\$1\\\\fP"]
);
@@ -251,6 +259,7 @@ my @highlights_rst = (
[$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"],
[$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"],
[$type_fp_param, "**\$1\\\\(\\\\)**"],
+ [$type_fp_param2, "**\$1\\\\(\\\\)**"],
[$type_func, "\$1()"],
[$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"],
[$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"],
@@ -258,7 +267,7 @@ my @highlights_rst = (
[$type_union, "\\:c\\:type\\:`\$1 <\$2>`"],
# in rst this can refer to any type
[$type_fallback, "\\:c\\:type\\:`\$1`"],
- [$type_param, "**\$1**"]
+ [$type_param_ref, "**\$1\$2**"]
);
my $blankline_rst = "\n";
@@ -268,9 +277,12 @@ if ($#ARGV == -1) {
}
my $kernelversion;
+my ($sphinx_major, $sphinx_minor, $sphinx_patch);
+
my $dohighlight = "";
my $verbose = 0;
+my $Werror = 0;
my $output_mode = "rst";
my $output_preformatted = 0;
my $no_doc_sections = 0;
@@ -282,13 +294,11 @@ my $modulename = "Kernel API";
use constant {
OUTPUT_ALL => 0, # output all symbols and doc sections
OUTPUT_INCLUDE => 1, # output only specified symbols
- OUTPUT_EXCLUDE => 2, # output everything except specified symbols
- OUTPUT_EXPORTED => 3, # output exported symbols
- OUTPUT_INTERNAL => 4, # output non-exported symbols
+ OUTPUT_EXPORTED => 2, # output exported symbols
+ OUTPUT_INTERNAL => 3, # output non-exported symbols
};
my $output_selection = OUTPUT_ALL;
my $show_not_found = 0; # No longer used
-my $sphinx_version = "0.0"; # if not specified, assume old
my @export_file_list;
@@ -310,6 +320,7 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
# CAVEAT EMPTOR! Some of the others I localised may not want to be, which
# could cause "use of undefined value" or other bugs.
my ($function, %function_table, %parametertypes, $declaration_purpose);
+my %nosymbol_table = ();
my $declaration_start_line;
my ($type, $declaration_name, $return_type);
my ($newsection, $newcontents, $prototype, $brcount, %source_map);
@@ -318,9 +329,21 @@ if (defined($ENV{'KBUILD_VERBOSE'})) {
$verbose = "$ENV{'KBUILD_VERBOSE'}";
}
+if (defined($ENV{'KDOC_WERROR'})) {
+ $Werror = "$ENV{'KDOC_WERROR'}";
+}
+
+if (defined($ENV{'KCFLAGS'})) {
+ my $kcflags = "$ENV{'KCFLAGS'}";
+
+ if ($kcflags =~ /Werror/) {
+ $Werror = 1;
+ }
+}
+
# Generated docbook code is inserted in a template at a point where
# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
-# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
+# https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
# We keep track of number of generated entries and generate a dummy
# if needs be to ensure the expanded template can be postprocessed
# into html.
@@ -330,13 +353,14 @@ my $lineprefix="";
# Parser states
use constant {
- STATE_NORMAL => 0, # normal code
- STATE_NAME => 1, # looking for function name
- STATE_BODY_MAYBE => 2, # body - or maybe more description
- STATE_BODY => 3, # the body of the comment
- STATE_PROTO => 4, # scanning prototype
- STATE_DOCBLOCK => 5, # documentation block
- STATE_INLINE => 6, # gathering documentation outside main block
+ STATE_NORMAL => 0, # normal code
+ STATE_NAME => 1, # looking for function name
+ STATE_BODY_MAYBE => 2, # body - or maybe more description
+ STATE_BODY => 3, # the body of the comment
+ STATE_BODY_WITH_BLANK_LINE => 4, # the body, which has a blank line
+ STATE_PROTO => 5, # scanning prototype
+ STATE_DOCBLOCK => 6, # documentation block
+ STATE_INLINE => 7, # gathering doc outside main block
};
my $state;
my $in_doc_sect;
@@ -416,10 +440,9 @@ while ($ARGV[0] =~ m/^--?(.*)/) {
$output_selection = OUTPUT_INCLUDE;
$function = shift @ARGV;
$function_table{$function} = 1;
- } elsif ($cmd eq "nofunction") { # output all except specific functions
- $output_selection = OUTPUT_EXCLUDE;
- $function = shift @ARGV;
- $function_table{$function} = 1;
+ } elsif ($cmd eq "nosymbol") { # Exclude specific symbols
+ my $symbol = shift @ARGV;
+ $nosymbol_table{$symbol} = 1;
} elsif ($cmd eq "export") { # only exported symbols
$output_selection = OUTPUT_EXPORTED;
%function_table = ();
@@ -431,6 +454,8 @@ while ($ARGV[0] =~ m/^--?(.*)/) {
push(@export_file_list, $file);
} elsif ($cmd eq "v") {
$verbose = 1;
+ } elsif ($cmd eq "Werror") {
+ $Werror = 1;
} elsif (($cmd eq "h") || ($cmd eq "help")) {
usage();
} elsif ($cmd eq 'no-doc-sections') {
@@ -439,8 +464,23 @@ while ($ARGV[0] =~ m/^--?(.*)/) {
$enable_lineno = 1;
} elsif ($cmd eq 'show-not-found') {
$show_not_found = 1; # A no-op but don't fail
- } elsif ($cmd eq 'sphinx-version') {
- $sphinx_version = shift @ARGV;
+ } elsif ($cmd eq "sphinx-version") {
+ my $ver_string = shift @ARGV;
+ if ($ver_string =~ m/^(\d+)(\.\d+)?(\.\d+)?/) {
+ $sphinx_major = $1;
+ if (defined($2)) {
+ $sphinx_minor = substr($2,1);
+ } else {
+ $sphinx_minor = 0;
+ }
+ if (defined($3)) {
+ $sphinx_patch = substr($3,1)
+ } else {
+ $sphinx_patch = 0;
+ }
+ } else {
+ die "Sphinx version should either major.minor or major.minor.patch format\n";
+ }
} else {
# Unknown argument
usage();
@@ -449,6 +489,51 @@ while ($ARGV[0] =~ m/^--?(.*)/) {
# continue execution near EOF;
+# The C domain dialect changed on Sphinx 3. So, we need to check the
+# version in order to produce the right tags.
+sub findprog($)
+{
+ foreach(split(/:/, $ENV{PATH})) {
+ return "$_/$_[0]" if(-x "$_/$_[0]");
+ }
+}
+
+sub get_sphinx_version()
+{
+ my $ver;
+
+ my $cmd = "sphinx-build";
+ if (!findprog($cmd)) {
+ my $cmd = "sphinx-build3";
+ if (!findprog($cmd)) {
+ $sphinx_major = 1;
+ $sphinx_minor = 2;
+ $sphinx_patch = 0;
+ printf STDERR "Warning: Sphinx version not found. Using default (Sphinx version %d.%d.%d)\n",
+ $sphinx_major, $sphinx_minor, $sphinx_patch;
+ return;
+ }
+ }
+
+ open IN, "$cmd --version 2>&1 |";
+ while (<IN>) {
+ if (m/^\s*sphinx-build\s+([\d]+)\.([\d\.]+)(\+\/[\da-f]+)?$/) {
+ $sphinx_major = $1;
+ $sphinx_minor = $2;
+ $sphinx_patch = $3;
+ last;
+ }
+ # Sphinx 1.2.x uses a different format
+ if (m/^\s*Sphinx.*\s+([\d]+)\.([\d\.]+)$/) {
+ $sphinx_major = $1;
+ $sphinx_minor = $2;
+ $sphinx_patch = $3;
+ last;
+ }
+ }
+ close IN;
+}
+
# get kernel version from env
sub get_kernel_version() {
my $version = 'unknown kernel version';
@@ -515,11 +600,11 @@ sub dump_doc_section {
return;
}
+ return if (defined($nosymbol_table{$name}));
+
if (($output_selection == OUTPUT_ALL) ||
- ($output_selection == OUTPUT_INCLUDE &&
- defined($function_table{$name})) ||
- ($output_selection == OUTPUT_EXCLUDE &&
- !defined($function_table{$name})))
+ (($output_selection == OUTPUT_INCLUDE) &&
+ defined($function_table{$name})))
{
dump_section($file, $name, $contents);
output_blockhead({'sectionlist' => \@sectionlist,
@@ -602,10 +687,10 @@ sub output_function_man(%) {
$type = $args{'parametertypes'}{$parameter};
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
- print ".BI \"" . $parenth . $1 . "\" " . $parameter . " \") (" . $2 . ")" . $post . "\"\n";
+ print ".BI \"" . $parenth . $1 . "\" " . " \") (" . $2 . ")" . $post . "\"\n";
} else {
$type =~ s/([^\*])$/$1 /;
- print ".BI \"" . $parenth . $type . "\" " . $parameter . " \"" . $post . "\"\n";
+ print ".BI \"" . $parenth . $type . "\" " . " \"" . $post . "\"\n";
}
$count++;
$parenth = "";
@@ -745,6 +830,8 @@ sub output_blockhead_rst(%) {
my ($parameter, $section);
foreach $section (@{$args{'sectionlist'}}) {
+ next if (defined($nosymbol_table{$section}));
+
if ($output_selection != OUTPUT_INCLUDE) {
print "**$section**\n\n";
}
@@ -830,32 +917,37 @@ sub output_function_rst(%) {
my ($parameter, $section);
my $oldprefix = $lineprefix;
my $start = "";
-
- if ($args{'typedef'}) {
- print ".. c:type:: ". $args{'function'} . "\n\n";
- print_lineno($declaration_start_line);
- print " **Typedef**: ";
- $lineprefix = "";
- output_highlight_rst($args{'purpose'});
- $start = "\n\n**Syntax**\n\n ``";
+ my $is_macro = 0;
+
+ if ($sphinx_major < 3) {
+ if ($args{'typedef'}) {
+ print ".. c:type:: ". $args{'function'} . "\n\n";
+ print_lineno($declaration_start_line);
+ print " **Typedef**: ";
+ $lineprefix = "";
+ output_highlight_rst($args{'purpose'});
+ $start = "\n\n**Syntax**\n\n ``";
+ $is_macro = 1;
+ } else {
+ print ".. c:function:: ";
+ }
} else {
- if ((split(/\./, $sphinx_version))[0] >= 3) {
- # Sphinx 3 and later distinguish macros and functions and
- # complain if you use c:function with something that's not
- # syntactically valid as a function declaration.
- # We assume that anything with a return type is a function
- # and anything without is a macro.
- if ($args{'functiontype'} ne "") {
- print ".. c:function:: ";
- } else {
- print ".. c:macro:: ";
- }
- } else {
- # Older Sphinx don't support documenting macros that take
- # arguments with c:macro, and don't complain about the use
- # of c:function for this.
- print ".. c:function:: ";
- }
+ if ($args{'typedef'} || $args{'functiontype'} eq "") {
+ $is_macro = 1;
+ print ".. c:macro:: ". $args{'function'} . "\n\n";
+ } else {
+ print ".. c:function:: ";
+ }
+
+ if ($args{'typedef'}) {
+ print_lineno($declaration_start_line);
+ print " **Typedef**: ";
+ $lineprefix = "";
+ output_highlight_rst($args{'purpose'});
+ $start = "\n\n**Syntax**\n\n ``";
+ } else {
+ print "``" if ($is_macro);
+ }
}
if ($args{'functiontype'} ne "") {
$start .= $args{'functiontype'} . " " . $args{'function'} . " (";
@@ -876,13 +968,15 @@ sub output_function_rst(%) {
# pointer-to-function
print $1 . $parameter . ") (" . $2 . ")";
} else {
- print $type . " " . $parameter;
+ print $type;
}
}
- if ($args{'typedef'}) {
- print ");``\n\n";
+ if ($is_macro) {
+ print ")``\n\n";
} else {
print ")\n\n";
+ }
+ if (!$args{'typedef'}) {
print_lineno($declaration_start_line);
$lineprefix = " ";
output_highlight_rst($args{'purpose'});
@@ -897,7 +991,7 @@ sub output_function_rst(%) {
$type = $args{'parametertypes'}{$parameter};
if ($type ne "") {
- print "``$type $parameter``\n";
+ print "``$type``\n";
} else {
print "``$parameter``\n";
}
@@ -938,9 +1032,14 @@ sub output_enum_rst(%) {
my ($parameter);
my $oldprefix = $lineprefix;
my $count;
- my $name = "enum " . $args{'enum'};
- print "\n\n.. c:type:: " . $name . "\n\n";
+ if ($sphinx_major < 3) {
+ my $name = "enum " . $args{'enum'};
+ print "\n\n.. c:type:: " . $name . "\n\n";
+ } else {
+ my $name = $args{'enum'};
+ print "\n\n.. c:enum:: " . $name . "\n\n";
+ }
print_lineno($declaration_start_line);
$lineprefix = " ";
output_highlight_rst($args{'purpose'});
@@ -966,8 +1065,13 @@ sub output_typedef_rst(%) {
my %args = %{$_[0]};
my ($parameter);
my $oldprefix = $lineprefix;
- my $name = "typedef " . $args{'typedef'};
+ my $name;
+ if ($sphinx_major < 3) {
+ $name = "typedef " . $args{'typedef'};
+ } else {
+ $name = $args{'typedef'};
+ }
print "\n\n.. c:type:: " . $name . "\n\n";
print_lineno($declaration_start_line);
$lineprefix = " ";
@@ -982,17 +1086,17 @@ sub output_struct_rst(%) {
my %args = %{$_[0]};
my ($parameter);
my $oldprefix = $lineprefix;
- my $name = $args{'type'} . " " . $args{'struct'};
-
- # Sphinx 3.0 and up will emit warnings for "c:type:: struct Foo".
- # It wants to see "c:struct:: Foo" (and will add the word 'struct' in
- # the rendered output).
- if ((split(/\./, $sphinx_version))[0] >= 3) {
- my $sname = $name;
- $sname =~ s/^struct //;
- print "\n\n.. c:struct:: " . $sname . "\n\n";
+
+ if ($sphinx_major < 3) {
+ my $name = $args{'type'} . " " . $args{'struct'};
+ print "\n\n.. c:type:: " . $name . "\n\n";
} else {
- print "\n\n.. c:type:: " . $name . "\n\n";
+ my $name = $args{'struct'};
+ if ($args{'type'} eq 'union') {
+ print "\n\n.. c:union:: " . $name . "\n\n";
+ } else {
+ print "\n\n.. c:struct:: " . $name . "\n\n";
+ }
}
print_lineno($declaration_start_line);
$lineprefix = " ";
@@ -1052,12 +1156,14 @@ sub output_declaration {
my $name = shift;
my $functype = shift;
my $func = "output_${functype}_$output_mode";
+
+ return if (defined($nosymbol_table{$name}));
+
if (($output_selection == OUTPUT_ALL) ||
(($output_selection == OUTPUT_INCLUDE ||
$output_selection == OUTPUT_EXPORTED) &&
defined($function_table{$name})) ||
- (($output_selection == OUTPUT_EXCLUDE ||
- $output_selection == OUTPUT_INTERNAL) &&
+ ($output_selection == OUTPUT_INTERNAL &&
!($functype eq "function" && defined($function_table{$name}))))
{
&$func(@_);
@@ -1092,7 +1198,7 @@ sub dump_struct($$) {
my $x = shift;
my $file = shift;
- if ($x =~ /(struct|union)\s+(\w+)\s*\{(.*)\}(\s*(__packed|__aligned|__attribute__\s*\(\([a-z0-9,_\s\(\)]*\)\)))*/) {
+ if ($x =~ /(struct|union)\s+(\w+)\s*\{(.*)\}(\s*(__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned|__attribute__\s*\(\([a-z0-9,_\s\(\)]*\)\)))*/) {
my $decl_type = $1;
$declaration_name = $2;
my $members = $3;
@@ -1103,11 +1209,15 @@ sub dump_struct($$) {
# strip comments:
$members =~ s/\/\*.*?\*\///gos;
# strip attributes
- $members =~ s/\s*__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)//gi;
- $members =~ s/\s*__aligned\s*\([^;]*\)//gos;
- $members =~ s/\s*__packed\s*//gos;
- $members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos;
+ $members =~ s/\s*__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)/ /gi;
+ $members =~ s/\s*__aligned\s*\([^;]*\)/ /gos;
+ $members =~ s/\s*__packed\s*/ /gos;
+ $members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos;
+ $members =~ s/\s*____cacheline_aligned_in_smp/ /gos;
+ $members =~ s/\s*____cacheline_aligned/ /gos;
+
# replace DECLARE_BITMAP
+ $members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos;
$members =~ s/DECLARE_BITMAP\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos;
# replace DECLARE_HASHTABLE
$members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos;
@@ -1234,6 +1344,8 @@ sub show_warnings($$) {
my $functype = shift;
my $name = shift;
+ return 0 if (defined($nosymbol_table{$name}));
+
return 1 if ($output_selection == OUTPUT_ALL);
if ($output_selection == OUTPUT_EXPORTED) {
@@ -1257,27 +1369,28 @@ sub show_warnings($$) {
return 0;
}
}
- if ($output_selection == OUTPUT_EXCLUDE) {
- if (!defined($function_table{$name})) {
- return 1;
- } else {
- return 0;
- }
- }
die("Please add the new output type at show_warnings()");
}
sub dump_enum($$) {
my $x = shift;
my $file = shift;
+ my $members;
+
$x =~ s@/\*.*?\*/@@gos; # strip comments.
# strip #define macros inside enums
$x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos;
- if ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) {
+ if ($x =~ /typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;/) {
+ $declaration_name = $2;
+ $members = $1;
+ } elsif ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) {
$declaration_name = $1;
- my $members = $2;
+ $members = $2;
+ }
+
+ if ($declaration_name) {
my %_members;
$members =~ s/\s+$//;
@@ -1312,27 +1425,31 @@ sub dump_enum($$) {
'sections' => \%sections,
'purpose' => $declaration_purpose
});
- }
- else {
+ } else {
print STDERR "${file}:$.: error: Cannot parse enum!\n";
++$errors;
}
}
+my $typedef_type = qr { ((?:\s+[\w\*]+){1,8})\s* }x;
+my $typedef_ident = qr { \*?\s*(\w\S+)\s* }x;
+my $typedef_args = qr { \s*\((.*)\); }x;
+
+my $typedef1 = qr { typedef$typedef_type\($typedef_ident\)$typedef_args }x;
+my $typedef2 = qr { typedef$typedef_type$typedef_ident$typedef_args }x;
+
sub dump_typedef($$) {
my $x = shift;
my $file = shift;
$x =~ s@/\*.*?\*/@@gos; # strip comments.
- # Parse function prototypes
- if ($x =~ /typedef\s+(\w+\s*\**)\s*\(\*?\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
- $x =~ /typedef\s+(\w+\s*\**)\s*(\w\S+)\s*\s*\((.*)\);/) {
-
- # Function typedefs
+ # Parse function typedef prototypes
+ if ($x =~ $typedef1 || $x =~ $typedef2) {
$return_type = $1;
$declaration_name = $2;
my $args = $3;
+ $return_type =~ s/^\s+//;
create_parameterlist($args, ',', $file, $declaration_name);
@@ -1408,7 +1525,7 @@ sub create_parameterlist($$$$) {
# Treat preprocessor directive as a typeless variable just to fill
# corresponding data structures "correctly". Catch it later in
# output_* subs.
- push_parameter($arg, "", $file);
+ push_parameter($arg, "", "", $file);
} elsif ($arg =~ m/\(.+\)\s*\(/) {
# pointer-to-function
$arg =~ tr/#/,/;
@@ -1417,7 +1534,7 @@ sub create_parameterlist($$$$) {
$type = $arg;
$type =~ s/([^\(]+\(\*?)\s*$param/$1/;
save_struct_actual($param);
- push_parameter($param, $type, $file, $declaration_name);
+ push_parameter($param, $type, $arg, $file, $declaration_name);
} elsif ($arg) {
$arg =~ s/\s*:\s*/:/g;
$arg =~ s/\s*\[/\[/g;
@@ -1442,26 +1559,28 @@ sub create_parameterlist($$$$) {
foreach $param (@args) {
if ($param =~ m/^(\*+)\s*(.*)/) {
save_struct_actual($2);
- push_parameter($2, "$type $1", $file, $declaration_name);
+
+ push_parameter($2, "$type $1", $arg, $file, $declaration_name);
}
elsif ($param =~ m/(.*?):(\d+)/) {
if ($type ne "") { # skip unnamed bit-fields
save_struct_actual($1);
- push_parameter($1, "$type:$2", $file, $declaration_name)
+ push_parameter($1, "$type:$2", $arg, $file, $declaration_name)
}
}
else {
save_struct_actual($param);
- push_parameter($param, $type, $file, $declaration_name);
+ push_parameter($param, $type, $arg, $file, $declaration_name);
}
}
}
}
}
-sub push_parameter($$$$) {
+sub push_parameter($$$$$) {
my $param = shift;
my $type = shift;
+ my $org_arg = shift;
my $file = shift;
my $declaration_name = shift;
@@ -1479,6 +1598,10 @@ sub push_parameter($$$$) {
# handles unnamed variable parameters
$param = "...";
}
+ elsif ($param =~ /\w\.\.\.$/) {
+ # for named variable parameters of the form `x...`, remove the dots
+ $param =~ s/\.\.\.$//;
+ }
if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
$parameterdescs{$param} = "variable arguments";
}
@@ -1521,8 +1644,8 @@ sub push_parameter($$$$) {
# "[blah" in a parameter string;
###$param =~ s/\s*//g;
push @parameterlist, $param;
- $type =~ s/\s\s+/ /g;
- $parametertypes{$param} = $type;
+ $org_arg =~ s/\s\s+/ /g;
+ $parametertypes{$param} = $org_arg;
}
sub check_sections($$$$$) {
@@ -1596,6 +1719,8 @@ sub dump_function($$) {
my $file = shift;
my $noret = 0;
+ print_lineno($new_start_line);
+
$prototype =~ s/^static +//;
$prototype =~ s/^extern +//;
$prototype =~ s/^asmlinkage +//;
@@ -1633,7 +1758,7 @@ sub dump_function($$) {
# If you mess with these regexps, it's a good idea to check that
# the following functions' documentation still comes out right:
# - parport_register_device (function pointer parameters)
- # - qatomic_set (macro)
+ # - atomic_set (macro)
# - pci_match_device, __copy_to_user (long return type)
if ($define && $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s+/) {
@@ -1671,30 +1796,48 @@ sub dump_function($$) {
return;
}
- my $prms = join " ", @parameterlist;
- check_sections($file, $declaration_name, "function", $sectcheck, $prms);
+ my $prms = join " ", @parameterlist;
+ check_sections($file, $declaration_name, "function", $sectcheck, $prms);
- # This check emits a lot of warnings at the moment, because many
- # functions don't have a 'Return' doc section. So until the number
- # of warnings goes sufficiently down, the check is only performed in
- # verbose mode.
- # TODO: always perform the check.
- if ($verbose && !$noret) {
- check_return_section($file, $declaration_name, $return_type);
- }
+ # This check emits a lot of warnings at the moment, because many
+ # functions don't have a 'Return' doc section. So until the number
+ # of warnings goes sufficiently down, the check is only performed in
+ # verbose mode.
+ # TODO: always perform the check.
+ if ($verbose && !$noret) {
+ check_return_section($file, $declaration_name, $return_type);
+ }
- output_declaration($declaration_name,
- 'function',
- {'function' => $declaration_name,
- 'module' => $modulename,
- 'functiontype' => $return_type,
- 'parameterlist' => \@parameterlist,
- 'parameterdescs' => \%parameterdescs,
- 'parametertypes' => \%parametertypes,
- 'sectionlist' => \@sectionlist,
- 'sections' => \%sections,
- 'purpose' => $declaration_purpose
- });
+ # The function parser can be called with a typedef parameter.
+ # Handle it.
+ if ($return_type =~ /typedef/) {
+ output_declaration($declaration_name,
+ 'function',
+ {'function' => $declaration_name,
+ 'typedef' => 1,
+ 'module' => $modulename,
+ 'functiontype' => $return_type,
+ 'parameterlist' => \@parameterlist,
+ 'parameterdescs' => \%parameterdescs,
+ 'parametertypes' => \%parametertypes,
+ 'sectionlist' => \@sectionlist,
+ 'sections' => \%sections,
+ 'purpose' => $declaration_purpose
+ });
+ } else {
+ output_declaration($declaration_name,
+ 'function',
+ {'function' => $declaration_name,
+ 'module' => $modulename,
+ 'functiontype' => $return_type,
+ 'parameterlist' => \@parameterlist,
+ 'parameterdescs' => \%parameterdescs,
+ 'parametertypes' => \%parametertypes,
+ 'sectionlist' => \@sectionlist,
+ 'sections' => \%sections,
+ 'purpose' => $declaration_purpose
+ });
+ }
}
sub reset_state {
@@ -1789,6 +1932,11 @@ sub process_proto_function($$) {
$prototype =~ s@/\*.*?\*/@@gos; # strip comments.
$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
$prototype =~ s@^\s+@@gos; # strip leading spaces
+
+ # Handle prototypes for function pointers like:
+ # int (*pcs_config)(struct foo)
+ $prototype =~ s@^(\S+\s+)\(\s*\*(\S+)\)@$1$2@gos;
+
if ($prototype =~ /SYSCALL_DEFINE/) {
syscall_munge();
}
@@ -1867,6 +2015,7 @@ sub process_export_file($) {
while (<IN>) {
if (/$export_symbol/) {
+ next if (defined($nosymbol_table{$2}));
$function_table{$2} = 1;
}
}
@@ -1898,7 +2047,7 @@ sub process_name($$) {
if (/$doc_block/o) {
$state = STATE_DOCBLOCK;
$contents = "";
- $new_start_line = $. + 1;
+ $new_start_line = $.;
if ( $1 eq "" ) {
$section = $section_intro;
@@ -1966,6 +2115,25 @@ sub process_name($$) {
sub process_body($$) {
my $file = shift;
+ # Until all named variable macro parameters are
+ # documented using the bare name (`x`) rather than with
+ # dots (`x...`), strip the dots:
+ if ($section =~ /\w\.\.\.$/) {
+ $section =~ s/\.\.\.$//;
+
+ if ($verbose) {
+ print STDERR "${file}:$.: warning: Variable macro arguments should be documented without dots\n";
+ ++$warnings;
+ }
+ }
+
+ if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) {
+ dump_section($file, $section, $contents);
+ $section = $section_default;
+ $new_start_line = $.;
+ $contents = "";
+ }
+
if (/$doc_sect/i) { # case insensitive for supported section names
$newsection = $1;
$newcontents = $2;
@@ -2018,19 +2186,23 @@ sub process_body($$) {
$prototype = "";
$state = STATE_PROTO;
$brcount = 0;
+ $new_start_line = $. + 1;
} elsif (/$doc_content/) {
- # miguel-style comment kludge, look for blank lines after
- # @parameter line to signify start of description
if ($1 eq "") {
- if ($section =~ m/^@/ || $section eq $section_context) {
+ if ($section eq $section_context) {
dump_section($file, $section, $contents);
$section = $section_default;
$contents = "";
$new_start_line = $.;
+ $state = STATE_BODY;
} else {
+ if ($section ne $section_default) {
+ $state = STATE_BODY_WITH_BLANK_LINE;
+ } else {
+ $state = STATE_BODY;
+ }
$contents .= "\n";
}
- $state = STATE_BODY;
} elsif ($state == STATE_BODY_MAYBE) {
# Continued declaration purpose
chomp($declaration_purpose);
@@ -2162,7 +2334,7 @@ sub process_file($) {
$file = map_filename($orig_file);
- if (!open(IN,"<$file")) {
+ if (!open(IN_FILE,"<$file")) {
print STDERR "Error: Cannot open file $file\n";
++$errors;
return;
@@ -2171,9 +2343,9 @@ sub process_file($) {
$. = 1;
$section_counter = 0;
- while (<IN>) {
+ while (<IN_FILE>) {
while (s/\\\s*$//) {
- $_ .= <IN>;
+ $_ .= <IN_FILE>;
}
# Replace tabs by spaces
while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {};
@@ -2182,7 +2354,8 @@ sub process_file($) {
process_normal();
} elsif ($state == STATE_NAME) {
process_name($file, $_);
- } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) {
+ } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE ||
+ $state == STATE_BODY_WITH_BLANK_LINE) {
process_body($file, $_);
} elsif ($state == STATE_INLINE) { # scanning for inline parameters
process_inline($file, $_);
@@ -2204,9 +2377,14 @@ sub process_file($) {
print STDERR "${file}:1: warning: no structured comments found\n";
}
}
+ close IN_FILE;
}
+if ($output_mode eq "rst") {
+ get_sphinx_version() if (!$sphinx_major);
+}
+
$kernelversion = get_kernel_version();
# generate a sequence of code that will splice in highlighting information
@@ -2253,4 +2431,9 @@ if ($verbose && $warnings) {
print STDERR "$warnings warnings\n";
}
-exit($output_mode eq "none" ? 0 : $errors);
+if ($Werror && $warnings) {
+ print STDERR "$warnings warnings as Errors\n";
+ exit($warnings);
+} else {
+ exit($output_mode eq "none" ? 0 : $errors)
+}
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
index e46ac68ad0..1dc20b9dc3 100644
--- a/softmmu/cpus.c
+++ b/softmmu/cpus.c
@@ -41,6 +41,7 @@
#include "sysemu/replay.h"
#include "sysemu/runstate.h"
#include "sysemu/cpu-timers.h"
+#include "sysemu/whpx.h"
#include "hw/boards.h"
#include "hw/hw.h"
@@ -88,7 +89,7 @@ bool cpu_thread_is_idle(CPUState *cpu)
return true;
}
if (!cpu->halted || cpu_has_work(cpu) ||
- kvm_halt_in_kernel()) {
+ kvm_halt_in_kernel() || whpx_apic_in_platform()) {
return false;
}
return true;
diff --git a/softmmu/datadir.c b/softmmu/datadir.c
new file mode 100644
index 0000000000..504c4665be
--- /dev/null
+++ b/softmmu/datadir.c
@@ -0,0 +1,129 @@
+/*
+ * QEMU firmware and keymap file search
+ *
+ * Copyright (c) 2003-2020 QEMU contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/datadir.h"
+#include "qemu/cutils.h"
+#include "trace.h"
+
+static const char *data_dir[16];
+static int data_dir_idx;
+
+char *qemu_find_file(int type, const char *name)
+{
+ int i;
+ const char *subdir;
+ char *buf;
+
+ /* Try the name as a straight path first */
+ if (access(name, R_OK) == 0) {
+ trace_load_file(name, name);
+ return g_strdup(name);
+ }
+
+ switch (type) {
+ case QEMU_FILE_TYPE_BIOS:
+ subdir = "";
+ break;
+ case QEMU_FILE_TYPE_KEYMAP:
+ subdir = "keymaps/";
+ break;
+ default:
+ abort();
+ }
+
+ for (i = 0; i < data_dir_idx; i++) {
+ buf = g_strdup_printf("%s/%s%s", data_dir[i], subdir, name);
+ if (access(buf, R_OK) == 0) {
+ trace_load_file(name, buf);
+ return buf;
+ }
+ g_free(buf);
+ }
+ return NULL;
+}
+
+void qemu_add_data_dir(char *path)
+{
+ int i;
+
+ if (path == NULL) {
+ return;
+ }
+ if (data_dir_idx == ARRAY_SIZE(data_dir)) {
+ return;
+ }
+ for (i = 0; i < data_dir_idx; i++) {
+ if (strcmp(data_dir[i], path) == 0) {
+ g_free(path); /* duplicate */
+ return;
+ }
+ }
+ data_dir[data_dir_idx++] = path;
+}
+
+/*
+ * Find a likely location for support files using the location of the binary.
+ * When running from the build tree this will be "$bindir/pc-bios".
+ * Otherwise, this is CONFIG_QEMU_DATADIR (possibly relocated).
+ *
+ * The caller must use g_free() to free the returned data when it is
+ * no longer required.
+ */
+static char *find_datadir(void)
+{
+ g_autofree char *dir = NULL;
+
+ dir = g_build_filename(qemu_get_exec_dir(), "pc-bios", NULL);
+ if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
+ return g_steal_pointer(&dir);
+ }
+
+ return get_relocated_path(CONFIG_QEMU_DATADIR);
+}
+
+void qemu_add_default_firmwarepath(void)
+{
+ char **dirs;
+ size_t i;
+
+ /* add configured firmware directories */
+ dirs = g_strsplit(CONFIG_QEMU_FIRMWAREPATH, G_SEARCHPATH_SEPARATOR_S, 0);
+ for (i = 0; dirs[i] != NULL; i++) {
+ qemu_add_data_dir(get_relocated_path(dirs[i]));
+ }
+ g_strfreev(dirs);
+
+ /* try to find datadir relative to the executable path */
+ qemu_add_data_dir(find_datadir());
+}
+
+void qemu_list_data_dirs(void)
+{
+ int i;
+ for (i = 0; i < data_dir_idx; i++) {
+ printf("%s\n", data_dir[i]);
+ }
+}
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index 03c92e0cc6..29001b5459 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -1,7 +1,7 @@
/*
* DMA helper functions
*
- * Copyright (c) 2009 Red Hat
+ * Copyright (c) 2009,2020 Red Hat
*
* This work is licensed under the terms of the GNU General Public License
* (GNU GPL), version 2 or later.
@@ -18,14 +18,15 @@
/* #define DEBUG_IOMMU */
-int dma_memory_set(AddressSpace *as, dma_addr_t addr, uint8_t c, dma_addr_t len)
+MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
+ uint8_t c, dma_addr_t len)
{
dma_barrier(as, DMA_DIRECTION_FROM_DEVICE);
#define FILLBUF_SIZE 512
uint8_t fillbuf[FILLBUF_SIZE];
int l;
- bool error = false;
+ MemTxResult error = MEMTX_OK;
memset(fillbuf, c, FILLBUF_SIZE);
while (len > 0) {
diff --git a/softmmu/meson.build b/softmmu/meson.build
index 8f7210b4f0..d098d89653 100644
--- a/softmmu/meson.build
+++ b/softmmu/meson.build
@@ -3,8 +3,10 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files(
'balloon.c',
'cpus.c',
'cpu-throttle.c',
+ 'datadir.c',
'physmem.c',
'ioport.c',
+ 'rtc.c',
'memory.c',
'memory_mapping.c',
'qtest.c',
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 31e5b589b7..832e254842 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -928,12 +928,6 @@ BlockBackend *blk_by_qdev_id(const char *id, Error **errp)
return blk;
}
-void qdev_machine_init(void)
-{
- qdev_get_peripheral_anon();
- qdev_get_peripheral();
-}
-
QemuOptsList qemu_device_opts = {
.name = "device",
.implied_opt_name = "driver",
diff --git a/softmmu/rtc.c b/softmmu/rtc.c
new file mode 100644
index 0000000000..e1e15ef613
--- /dev/null
+++ b/softmmu/rtc.c
@@ -0,0 +1,190 @@
+/*
+ * RTC configuration and clock read
+ *
+ * Copyright (c) 2003-2020 QEMU contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qerror.h"
+#include "qemu/error-report.h"
+#include "qemu/option.h"
+#include "qemu/timer.h"
+#include "qom/object.h"
+#include "sysemu/replay.h"
+#include "sysemu/sysemu.h"
+
+static enum {
+ RTC_BASE_UTC,
+ RTC_BASE_LOCALTIME,
+ RTC_BASE_DATETIME,
+} rtc_base_type = RTC_BASE_UTC;
+static time_t rtc_ref_start_datetime;
+static int rtc_realtime_clock_offset; /* used only with QEMU_CLOCK_REALTIME */
+static int rtc_host_datetime_offset = -1; /* valid & used only with
+ RTC_BASE_DATETIME */
+QEMUClockType rtc_clock;
+/***********************************************************/
+/* RTC reference time/date access */
+static time_t qemu_ref_timedate(QEMUClockType clock)
+{
+ time_t value = qemu_clock_get_ms(clock) / 1000;
+ switch (clock) {
+ case QEMU_CLOCK_REALTIME:
+ value -= rtc_realtime_clock_offset;
+ /* fall through */
+ case QEMU_CLOCK_VIRTUAL:
+ value += rtc_ref_start_datetime;
+ break;
+ case QEMU_CLOCK_HOST:
+ if (rtc_base_type == RTC_BASE_DATETIME) {
+ value -= rtc_host_datetime_offset;
+ }
+ break;
+ default:
+ assert(0);
+ }
+ return value;
+}
+
+void qemu_get_timedate(struct tm *tm, int offset)
+{
+ time_t ti = qemu_ref_timedate(rtc_clock);
+
+ ti += offset;
+
+ switch (rtc_base_type) {
+ case RTC_BASE_DATETIME:
+ case RTC_BASE_UTC:
+ gmtime_r(&ti, tm);
+ break;
+ case RTC_BASE_LOCALTIME:
+ localtime_r(&ti, tm);
+ break;
+ }
+}
+
+int qemu_timedate_diff(struct tm *tm)
+{
+ time_t seconds;
+
+ switch (rtc_base_type) {
+ case RTC_BASE_DATETIME:
+ case RTC_BASE_UTC:
+ seconds = mktimegm(tm);
+ break;
+ case RTC_BASE_LOCALTIME:
+ {
+ struct tm tmp = *tm;
+ tmp.tm_isdst = -1; /* use timezone to figure it out */
+ seconds = mktime(&tmp);
+ break;
+ }
+ default:
+ abort();
+ }
+
+ return seconds - qemu_ref_timedate(QEMU_CLOCK_HOST);
+}
+
+static void configure_rtc_base_datetime(const char *startdate)
+{
+ time_t rtc_start_datetime;
+ struct tm tm;
+
+ if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon,
+ &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6) {
+ /* OK */
+ } else if (sscanf(startdate, "%d-%d-%d",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday) == 3) {
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ } else {
+ goto date_fail;
+ }
+ tm.tm_year -= 1900;
+ tm.tm_mon--;
+ rtc_start_datetime = mktimegm(&tm);
+ if (rtc_start_datetime == -1) {
+ date_fail:
+ error_report("invalid datetime format");
+ error_printf("valid formats: "
+ "'2006-06-17T16:01:21' or '2006-06-17'\n");
+ exit(1);
+ }
+ rtc_host_datetime_offset = rtc_ref_start_datetime - rtc_start_datetime;
+ rtc_ref_start_datetime = rtc_start_datetime;
+}
+
+void configure_rtc(QemuOpts *opts)
+{
+ const char *value;
+
+ /* Set defaults */
+ rtc_clock = QEMU_CLOCK_HOST;
+ rtc_ref_start_datetime = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
+ rtc_realtime_clock_offset = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
+
+ value = qemu_opt_get(opts, "base");
+ if (value) {
+ if (!strcmp(value, "utc")) {
+ rtc_base_type = RTC_BASE_UTC;
+ } else if (!strcmp(value, "localtime")) {
+ Error *blocker = NULL;
+ rtc_base_type = RTC_BASE_LOCALTIME;
+ error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED,
+ "-rtc base=localtime");
+ replay_add_blocker(blocker);
+ } else {
+ rtc_base_type = RTC_BASE_DATETIME;
+ configure_rtc_base_datetime(value);
+ }
+ }
+ value = qemu_opt_get(opts, "clock");
+ if (value) {
+ if (!strcmp(value, "host")) {
+ rtc_clock = QEMU_CLOCK_HOST;
+ } else if (!strcmp(value, "rt")) {
+ rtc_clock = QEMU_CLOCK_REALTIME;
+ } else if (!strcmp(value, "vm")) {
+ rtc_clock = QEMU_CLOCK_VIRTUAL;
+ } else {
+ error_report("invalid option value '%s'", value);
+ exit(1);
+ }
+ }
+ value = qemu_opt_get(opts, "driftfix");
+ if (value) {
+ if (!strcmp(value, "slew")) {
+ object_register_sugar_prop("mc146818rtc",
+ "lost_tick_policy",
+ "slew");
+ } else if (!strcmp(value, "none")) {
+ /* discard is default */
+ } else {
+ error_report("invalid option value '%s'", value);
+ exit(1);
+ }
+ }
+}
diff --git a/softmmu/vl.c b/softmmu/vl.c
index e6e0ad5a92..7146fbe219 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "hw/boards.h"
#include "hw/qdev-properties.h"
@@ -109,6 +110,8 @@
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qapi-visit-ui.h"
#include "qapi/qapi-commands-block-core.h"
+#include "qapi/qapi-commands-migration.h"
+#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-run-state.h"
#include "qapi/qapi-commands-ui.h"
#include "qapi/qmp/qerror.h"
@@ -117,32 +120,44 @@
#define MAX_VIRTIO_CONSOLES 1
-static const char *data_dir[16];
-static int data_dir_idx;
-const char *bios_name = NULL;
+typedef struct BlockdevOptionsQueueEntry {
+ BlockdevOptions *bdo;
+ Location loc;
+ QSIMPLEQ_ENTRY(BlockdevOptionsQueueEntry) entry;
+} BlockdevOptionsQueueEntry;
+
+typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue;
+
+static const char *cpu_option;
+static const char *mem_path;
+static const char *incoming;
+static const char *loadvm;
+static ram_addr_t maxram_size;
+static uint64_t ram_slots;
+static int display_remote;
+static int snapshot;
+static bool preconfig_requested;
+static QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
+static BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
+static bool nographic = false;
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
+static int mem_prealloc; /* force preallocation of physical target memory */
int display_opengl;
const char* keyboard_layout = NULL;
-ram_addr_t ram_size;
+static ram_addr_t ram_size;
bool enable_mlock = false;
bool enable_cpu_pm = false;
int nb_nics;
NICInfo nd_table[MAX_NICS];
-int autostart;
-static enum {
- RTC_BASE_UTC,
- RTC_BASE_LOCALTIME,
- RTC_BASE_DATETIME,
-} rtc_base_type = RTC_BASE_UTC;
-static time_t rtc_ref_start_datetime;
-static int rtc_realtime_clock_offset; /* used only with QEMU_CLOCK_REALTIME */
-static int rtc_host_datetime_offset = -1; /* valid & used only with
- RTC_BASE_DATETIME */
-QEMUClockType rtc_clock;
+int autostart = 1;
int vga_interface_type = VGA_NONE;
+static const char *vga_model = NULL;
static DisplayOptions dpy;
static int num_serial_hds;
static Chardev **serial_hds;
+static const char *log_mask;
+static const char *log_file;
+static bool list_data_dirs;
Chardev *parallel_hds[MAX_PARALLEL_PORTS];
int win2k_install_hack = 0;
int singlestep = 0;
@@ -150,7 +165,7 @@ int fd_bootchk = 1;
static int no_reboot;
int no_shutdown = 0;
int graphic_rotate = 0;
-const char *watchdog;
+static const char *watchdog;
QEMUOptionRom option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int old_param = 0;
@@ -177,9 +192,6 @@ bool qemu_uuid_set;
static NotifierList exit_notifiers =
NOTIFIER_LIST_INITIALIZER(exit_notifiers);
-static NotifierList machine_init_done_notifiers =
- NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
-
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
bool xen_domid_restrict;
@@ -748,152 +760,6 @@ void qemu_system_vmstop_request(RunState state)
qemu_mutex_unlock(&vmstop_lock);
qemu_notify_event();
}
-
-/***********************************************************/
-/* RTC reference time/date access */
-static time_t qemu_ref_timedate(QEMUClockType clock)
-{
- time_t value = qemu_clock_get_ms(clock) / 1000;
- switch (clock) {
- case QEMU_CLOCK_REALTIME:
- value -= rtc_realtime_clock_offset;
- /* fall through */
- case QEMU_CLOCK_VIRTUAL:
- value += rtc_ref_start_datetime;
- break;
- case QEMU_CLOCK_HOST:
- if (rtc_base_type == RTC_BASE_DATETIME) {
- value -= rtc_host_datetime_offset;
- }
- break;
- default:
- assert(0);
- }
- return value;
-}
-
-void qemu_get_timedate(struct tm *tm, int offset)
-{
- time_t ti = qemu_ref_timedate(rtc_clock);
-
- ti += offset;
-
- switch (rtc_base_type) {
- case RTC_BASE_DATETIME:
- case RTC_BASE_UTC:
- gmtime_r(&ti, tm);
- break;
- case RTC_BASE_LOCALTIME:
- localtime_r(&ti, tm);
- break;
- }
-}
-
-int qemu_timedate_diff(struct tm *tm)
-{
- time_t seconds;
-
- switch (rtc_base_type) {
- case RTC_BASE_DATETIME:
- case RTC_BASE_UTC:
- seconds = mktimegm(tm);
- break;
- case RTC_BASE_LOCALTIME:
- {
- struct tm tmp = *tm;
- tmp.tm_isdst = -1; /* use timezone to figure it out */
- seconds = mktime(&tmp);
- break;
- }
- default:
- abort();
- }
-
- return seconds - qemu_ref_timedate(QEMU_CLOCK_HOST);
-}
-
-static void configure_rtc_base_datetime(const char *startdate)
-{
- time_t rtc_start_datetime;
- struct tm tm;
-
- if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon,
- &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6) {
- /* OK */
- } else if (sscanf(startdate, "%d-%d-%d",
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday) == 3) {
- tm.tm_hour = 0;
- tm.tm_min = 0;
- tm.tm_sec = 0;
- } else {
- goto date_fail;
- }
- tm.tm_year -= 1900;
- tm.tm_mon--;
- rtc_start_datetime = mktimegm(&tm);
- if (rtc_start_datetime == -1) {
- date_fail:
- error_report("invalid datetime format");
- error_printf("valid formats: "
- "'2006-06-17T16:01:21' or '2006-06-17'\n");
- exit(1);
- }
- rtc_host_datetime_offset = rtc_ref_start_datetime - rtc_start_datetime;
- rtc_ref_start_datetime = rtc_start_datetime;
-}
-
-static void configure_rtc(QemuOpts *opts)
-{
- const char *value;
-
- /* Set defaults */
- rtc_clock = QEMU_CLOCK_HOST;
- rtc_ref_start_datetime = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
- rtc_realtime_clock_offset = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
-
- value = qemu_opt_get(opts, "base");
- if (value) {
- if (!strcmp(value, "utc")) {
- rtc_base_type = RTC_BASE_UTC;
- } else if (!strcmp(value, "localtime")) {
- Error *blocker = NULL;
- rtc_base_type = RTC_BASE_LOCALTIME;
- error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED,
- "-rtc base=localtime");
- replay_add_blocker(blocker);
- } else {
- rtc_base_type = RTC_BASE_DATETIME;
- configure_rtc_base_datetime(value);
- }
- }
- value = qemu_opt_get(opts, "clock");
- if (value) {
- if (!strcmp(value, "host")) {
- rtc_clock = QEMU_CLOCK_HOST;
- } else if (!strcmp(value, "rt")) {
- rtc_clock = QEMU_CLOCK_REALTIME;
- } else if (!strcmp(value, "vm")) {
- rtc_clock = QEMU_CLOCK_VIRTUAL;
- } else {
- error_report("invalid option value '%s'", value);
- exit(1);
- }
- }
- value = qemu_opt_get(opts, "driftfix");
- if (value) {
- if (!strcmp(value, "slew")) {
- object_register_sugar_prop("mc146818rtc",
- "lost_tick_policy",
- "slew");
- } else if (!strcmp(value, "none")) {
- /* discard is default */
- } else {
- error_report("invalid option value '%s'", value);
- exit(1);
- }
- }
-}
-
static int parse_name(void *opaque, QemuOpts *opts, Error **errp)
{
const char *proc_name;
@@ -1030,14 +896,6 @@ static void default_drive(int enable, int snapshot, BlockInterfaceType type,
}
-typedef struct BlockdevOptionsQueueEntry {
- BlockdevOptions *bdo;
- Location loc;
- QSIMPLEQ_ENTRY(BlockdevOptionsQueueEntry) entry;
-} BlockdevOptionsQueueEntry;
-
-typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue;
-
static void configure_blockdev(BlockdevOptionsQueue *bdo_queue,
MachineClass *machine_class, int snapshot)
{
@@ -1225,7 +1083,8 @@ struct VMChangeStateEntry {
int priority;
};
-static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_state_head;
+static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_state_head =
+ QTAILQ_HEAD_INITIALIZER(vm_change_state_head);
/**
* qemu_add_vm_change_state_handler_prio:
@@ -1973,59 +1832,6 @@ static void parse_display(const char *p)
}
}
-char *qemu_find_file(int type, const char *name)
-{
- int i;
- const char *subdir;
- char *buf;
-
- /* Try the name as a straight path first */
- if (access(name, R_OK) == 0) {
- trace_load_file(name, name);
- return g_strdup(name);
- }
-
- switch (type) {
- case QEMU_FILE_TYPE_BIOS:
- subdir = "";
- break;
- case QEMU_FILE_TYPE_KEYMAP:
- subdir = "keymaps/";
- break;
- default:
- abort();
- }
-
- for (i = 0; i < data_dir_idx; i++) {
- buf = g_strdup_printf("%s/%s%s", data_dir[i], subdir, name);
- if (access(buf, R_OK) == 0) {
- trace_load_file(name, buf);
- return buf;
- }
- g_free(buf);
- }
- return NULL;
-}
-
-void qemu_add_data_dir(char *path)
-{
- int i;
-
- if (path == NULL) {
- return;
- }
- if (data_dir_idx == ARRAY_SIZE(data_dir)) {
- return;
- }
- for (i = 0; i < data_dir_idx; i++) {
- if (strcmp(data_dir[i], path) == 0) {
- g_free(path); /* duplicate */
- return;
- }
- }
- data_dir[data_dir_idx++] = path;
-}
-
static inline bool nonempty_str(const char *str)
{
return str && *str;
@@ -2213,6 +2019,115 @@ static int foreach_device_config(int type, int (*func)(const char *cmdline))
return 0;
}
+static void qemu_disable_default_devices(void)
+{
+ MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
+
+ qemu_opts_foreach(qemu_find_opts("device"),
+ default_driver_check, NULL, NULL);
+ qemu_opts_foreach(qemu_find_opts("global"),
+ default_driver_check, NULL, NULL);
+
+ if (!vga_model && !default_vga) {
+ vga_interface_type = VGA_DEVICE;
+ }
+ if (!has_defaults || machine_class->no_serial) {
+ default_serial = 0;
+ }
+ if (!has_defaults || machine_class->no_parallel) {
+ default_parallel = 0;
+ }
+ if (!has_defaults || machine_class->no_floppy) {
+ default_floppy = 0;
+ }
+ if (!has_defaults || machine_class->no_cdrom) {
+ default_cdrom = 0;
+ }
+ if (!has_defaults || machine_class->no_sdcard) {
+ default_sdcard = 0;
+ }
+ if (!has_defaults) {
+ default_monitor = 0;
+ default_net = 0;
+ default_vga = 0;
+ }
+}
+
+static void qemu_create_default_devices(void)
+{
+ MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
+
+ if (is_daemonized()) {
+ /* According to documentation and historically, -nographic redirects
+ * serial port, parallel port and monitor to stdio, which does not work
+ * with -daemonize. We can redirect these to null instead, but since
+ * -nographic is legacy, let's just error out.
+ * We disallow -nographic only if all other ports are not redirected
+ * explicitly, to not break existing legacy setups which uses
+ * -nographic _and_ redirects all ports explicitly - this is valid
+ * usage, -nographic is just a no-op in this case.
+ */
+ if (nographic
+ && (default_parallel || default_serial || default_monitor)) {
+ error_report("-nographic cannot be used with -daemonize");
+ exit(1);
+ }
+ }
+
+ if (nographic) {
+ if (default_parallel)
+ add_device_config(DEV_PARALLEL, "null");
+ if (default_serial && default_monitor) {
+ add_device_config(DEV_SERIAL, "mon:stdio");
+ } else {
+ if (default_serial)
+ add_device_config(DEV_SERIAL, "stdio");
+ if (default_monitor)
+ monitor_parse("stdio", "readline", false);
+ }
+ } else {
+ if (default_serial)
+ add_device_config(DEV_SERIAL, "vc:80Cx24C");
+ if (default_parallel)
+ add_device_config(DEV_PARALLEL, "vc:80Cx24C");
+ if (default_monitor)
+ monitor_parse("vc:80Cx24C", "readline", false);
+ }
+
+ if (default_net) {
+ QemuOptsList *net = qemu_find_opts("net");
+ qemu_opts_parse(net, "nic", true, &error_abort);
+#ifdef CONFIG_SLIRP
+ qemu_opts_parse(net, "user", true, &error_abort);
+#endif
+ }
+
+#if defined(CONFIG_VNC)
+ if (!QTAILQ_EMPTY(&(qemu_find_opts("vnc")->head))) {
+ display_remote++;
+ }
+#endif
+ if (dpy.type == DISPLAY_TYPE_DEFAULT && !display_remote) {
+ if (!qemu_display_find_default(&dpy)) {
+ dpy.type = DISPLAY_TYPE_NONE;
+#if defined(CONFIG_VNC)
+ vnc_parse("localhost:0,to=99,id=default", &error_abort);
+#endif
+ }
+ }
+ if (dpy.type == DISPLAY_TYPE_DEFAULT) {
+ dpy.type = DISPLAY_TYPE_NONE;
+ }
+
+ /* If no default VGA is requested, the default is "none". */
+ if (default_vga) {
+ vga_model = get_default_vga_model(machine_class);
+ }
+ if (vga_model) {
+ select_vgahw(machine_class, vga_model);
+ }
+}
+
static int serial_parse(const char *devname)
{
int index = num_serial_hds;
@@ -2242,11 +2157,6 @@ Chardev *serial_hd(int i)
return NULL;
}
-int serial_max_hds(void)
-{
- return num_serial_hds;
-}
-
static int parallel_parse(const char *devname)
{
static int index = 0;
@@ -2375,27 +2285,6 @@ static void qemu_unlink_pidfile(Notifier *n, void *data)
}
}
-bool machine_init_done;
-
-void qemu_add_machine_init_done_notifier(Notifier *notify)
-{
- notifier_list_add(&machine_init_done_notifiers, notify);
- if (machine_init_done) {
- notify->notify(notify, NULL);
- }
-}
-
-void qemu_remove_machine_init_done_notifier(Notifier *notify)
-{
- notifier_remove(notify);
-}
-
-static void qemu_run_machine_init_done_notifiers(void)
-{
- machine_init_done = true;
- notifier_list_notify(&machine_init_done_notifiers, NULL);
-}
-
static const QEMUOption *lookup_opt(int argc, char **argv,
const char **poptarg, int *poptind)
{
@@ -2501,11 +2390,15 @@ static int machine_set_property(void *opaque,
object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), qom_name, value);
return 0;
}
- if (g_str_equal(qom_name, "kvm-shadow-mem") ||
- g_str_equal(qom_name, "kernel-irqchip")) {
+ if (g_str_equal(qom_name, "kvm-shadow-mem")) {
object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value);
return 0;
}
+ if (g_str_equal(qom_name, "kernel-irqchip")) {
+ object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value);
+ object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), qom_name, value);
+ return 0;
+ }
return object_parse_property_opt(opaque, name, value, "type", errp);
}
@@ -2517,7 +2410,7 @@ static int machine_set_property(void *opaque,
* cannot be created here, as it depends on the chardev
* already existing.
*/
-static bool object_create_initial(const char *type, QemuOpts *opts)
+static bool object_create_early(const char *type, QemuOpts *opts)
{
if (user_creatable_print_help(type, opts)) {
exit(0);
@@ -2573,19 +2466,187 @@ static bool object_create_initial(const char *type, QemuOpts *opts)
return true;
}
+static void qemu_apply_machine_options(void)
+{
+ MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
+ QemuOpts *machine_opts = qemu_get_machine_opts();
+ const char *boot_order = NULL;
+ const char *boot_once = NULL;
+ QemuOpts *opts;
+
+ qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
+ &error_fatal);
+ current_machine->ram_size = ram_size;
+ current_machine->maxram_size = maxram_size;
+ current_machine->ram_slots = ram_slots;
+
+ opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
+ if (opts) {
+ boot_order = qemu_opt_get(opts, "order");
+ if (boot_order) {
+ validate_bootdevices(boot_order, &error_fatal);
+ }
+
+ boot_once = qemu_opt_get(opts, "once");
+ if (boot_once) {
+ validate_bootdevices(boot_once, &error_fatal);
+ }
+
+ boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu);
+ boot_strict = qemu_opt_get_bool(opts, "strict", false);
+ }
+
+ if (!boot_order) {
+ boot_order = machine_class->default_boot_order;
+ }
+
+ current_machine->boot_order = boot_order;
+ current_machine->boot_once = boot_once;
+
+ if (semihosting_enabled() && !semihosting_get_argc()) {
+ const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
+ const char *kernel_cmdline = qemu_opt_get(machine_opts, "append") ?: "";
+ /* fall back to the -kernel/-append */
+ semihosting_arg_fallback(kernel_filename, kernel_cmdline);
+ }
+}
+
+static void qemu_create_early_backends(void)
+{
+ MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
+
+ if ((alt_grab || ctrl_grab) && dpy.type != DISPLAY_TYPE_SDL) {
+ error_report("-alt-grab and -ctrl-grab are only valid "
+ "for SDL, ignoring option");
+ }
+ if (dpy.has_window_close &&
+ (dpy.type != DISPLAY_TYPE_GTK && dpy.type != DISPLAY_TYPE_SDL)) {
+ error_report("-no-quit is only valid for GTK and SDL, "
+ "ignoring option");
+ }
+
+ qemu_display_early_init(&dpy);
+ qemu_console_early_init();
+
+ if (dpy.has_gl && dpy.gl != DISPLAYGL_MODE_OFF && display_opengl == 0) {
+#if defined(CONFIG_OPENGL)
+ error_report("OpenGL is not supported by the display");
+#else
+ error_report("OpenGL support is disabled");
+#endif
+ exit(1);
+ }
+
+ qemu_opts_foreach(qemu_find_opts("object"),
+ user_creatable_add_opts_foreach,
+ object_create_early, &error_fatal);
+
+ /* spice needs the timers to be initialized by this point */
+ /* spice must initialize before audio as it changes the default auiodev */
+ /* spice must initialize before chardevs (for spicevmc and spiceport) */
+ qemu_spice.init();
+
+ qemu_opts_foreach(qemu_find_opts("chardev"),
+ chardev_init_func, NULL, &error_fatal);
+
+#ifdef CONFIG_VIRTFS
+ qemu_opts_foreach(qemu_find_opts("fsdev"),
+ fsdev_init_func, NULL, &error_fatal);
+#endif
+
+ /*
+ * Note: we need to create audio and block backends before
+ * machine_set_property(), so machine properties can refer to
+ * them.
+ */
+ configure_blockdev(&bdo_queue, machine_class, snapshot);
+ audio_init_audiodevs();
+}
+
/*
* The remainder of object creation happens after the
* creation of chardev, fsdev, net clients and device data types.
*/
-static bool object_create_delayed(const char *type, QemuOpts *opts)
+static bool object_create_late(const char *type, QemuOpts *opts)
{
- return !object_create_initial(type, opts);
+ return !object_create_early(type, opts);
}
+static void qemu_create_late_backends(void)
+{
+ if (qtest_chrdev) {
+ qtest_server_init(qtest_chrdev, qtest_log, &error_fatal);
+ }
+
+ net_init_clients(&error_fatal);
+
+ qemu_opts_foreach(qemu_find_opts("object"),
+ user_creatable_add_opts_foreach,
+ object_create_late, &error_fatal);
+
+ if (tpm_init() < 0) {
+ exit(1);
+ }
+
+ qemu_opts_foreach(qemu_find_opts("mon"),
+ mon_init_func, NULL, &error_fatal);
-static bool set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
- MachineClass *mc)
+ if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
+ exit(1);
+ if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
+ exit(1);
+ if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
+ exit(1);
+
+ /* now chardevs have been created we may have semihosting to connect */
+ qemu_semihosting_connect_chardevs();
+ qemu_semihosting_console_init();
+}
+
+static bool have_custom_ram_size(void)
+{
+ QemuOpts *opts = qemu_find_opts_singleton("memory");
+ return !!qemu_opt_get_size(opts, "size", 0);
+}
+
+static void qemu_resolve_machine_memdev(void)
+{
+ if (current_machine->ram_memdev_id) {
+ Object *backend;
+ ram_addr_t backend_size;
+
+ backend = object_resolve_path_type(current_machine->ram_memdev_id,
+ TYPE_MEMORY_BACKEND, NULL);
+ if (!backend) {
+ error_report("Memory backend '%s' not found",
+ current_machine->ram_memdev_id);
+ exit(EXIT_FAILURE);
+ }
+ backend_size = object_property_get_uint(backend, "size", &error_abort);
+ if (have_custom_ram_size() && backend_size != ram_size) {
+ error_report("Size specified by -m option must match size of "
+ "explicitly specified 'memory-backend' property");
+ exit(EXIT_FAILURE);
+ }
+ if (mem_path) {
+ error_report("'-mem-path' can't be used together with"
+ "'-machine memory-backend'");
+ exit(EXIT_FAILURE);
+ }
+ ram_size = backend_size;
+ }
+
+ if (!xen_enabled()) {
+ /* On 32-bit hosts, QEMU is limited by virtual address space */
+ if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
+ error_report("at most 2047 MB RAM can be simulated");
+ exit(1);
+ }
+ }
+}
+
+static void set_memory_options(MachineClass *mc)
{
uint64_t sz;
const char *mem_str;
@@ -2635,7 +2696,7 @@ static bool set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
/* store value for the future use */
qemu_opt_set_number(opts, "size", ram_size, &error_abort);
- *maxram_size = ram_size;
+ maxram_size = ram_size;
if (qemu_opt_get(opts, "maxmem")) {
uint64_t slots;
@@ -2656,15 +2717,59 @@ static bool set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
exit(EXIT_FAILURE);
}
- *maxram_size = sz;
- *ram_slots = slots;
+ maxram_size = sz;
+ ram_slots = slots;
} else if (qemu_opt_get(opts, "slots")) {
error_report("invalid -m option value: missing 'maxmem' option");
exit(EXIT_FAILURE);
}
loc_pop(&loc);
- return !!mem_str;
+}
+
+static void qemu_create_machine(MachineClass *machine_class)
+{
+ object_set_machine_compat_props(machine_class->compat_props);
+
+ set_memory_options(machine_class);
+
+ current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
+ if (machine_help_func(qemu_get_machine_opts(), current_machine)) {
+ exit(0);
+ }
+ object_property_add_child(object_get_root(), "machine",
+ OBJECT(current_machine));
+ object_property_add_child(container_get(OBJECT(current_machine),
+ "/unattached"),
+ "sysbus", OBJECT(sysbus_get_default()));
+
+ if (machine_class->minimum_page_bits) {
+ if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
+ /* This would be a board error: specifying a minimum smaller than
+ * a target's compile-time fixed setting.
+ */
+ g_assert_not_reached();
+ }
+ }
+
+ cpu_exec_init_all();
+ page_size_init();
+
+ if (machine_class->hw_version) {
+ qemu_set_hw_version(machine_class->hw_version);
+ }
+
+ machine_smp_parse(current_machine,
+ qemu_opts_find(qemu_find_opts("smp-opts"), NULL), &error_fatal);
+
+ /*
+ * Get the default machine options from the machine if it is not already
+ * specified either by the configuration file or by the command line.
+ */
+ if (machine_class->default_machine_opts) {
+ qemu_opts_set_defaults(qemu_find_opts("machine"),
+ machine_class->default_machine_opts, 0);
+ }
}
static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
@@ -2692,6 +2797,39 @@ static int qemu_read_default_config_file(void)
return 0;
}
+static int qemu_set_option(const char *str)
+{
+ Error *local_err = NULL;
+ char group[64], id[64], arg[64];
+ QemuOptsList *list;
+ QemuOpts *opts;
+ int rc, offset;
+
+ rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
+ if (rc < 3 || str[offset] != '=') {
+ error_report("can't parse: \"%s\"", str);
+ return -1;
+ }
+
+ list = qemu_find_opts(group);
+ if (list == NULL) {
+ return -1;
+ }
+
+ opts = qemu_opts_find(list, id);
+ if (!opts) {
+ error_report("there is no %s \"%s\" defined",
+ list->name, id);
+ return -1;
+ }
+
+ if (!qemu_opt_set(opts, arg, str + offset + 1, &local_err)) {
+ error_report_err(local_err);
+ return -1;
+ }
+ return 0;
+}
+
static void user_register_global_props(void)
{
qemu_opts_foreach(qemu_find_opts("global"),
@@ -2843,79 +2981,328 @@ static void create_default_memdev(MachineState *ms, const char *path)
&error_fatal);
}
-/*
- * Find a likely location for support files using the location of the binary.
- * When running from the build tree this will be "$bindir/pc-bios".
- * Otherwise, this is CONFIG_QEMU_DATADIR (possibly relocated).
- *
- * The caller must use g_free() to free the returned data when it is
- * no longer required.
- */
-static char *find_datadir(void)
+static void qemu_validate_options(void)
{
- g_autofree char *dir = NULL;
+ QemuOpts *machine_opts = qemu_get_machine_opts();
+ const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
+ const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");
+ const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
+
+ if (kernel_filename == NULL) {
+ if (kernel_cmdline != NULL) {
+ error_report("-append only allowed with -kernel option");
+ exit(1);
+ }
- dir = g_build_filename(qemu_get_exec_dir(), "pc-bios", NULL);
- if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
- return g_steal_pointer(&dir);
+ if (initrd_filename != NULL) {
+ error_report("-initrd only allowed with -kernel option");
+ exit(1);
+ }
}
- return get_relocated_path(CONFIG_QEMU_DATADIR);
+ if (loadvm && preconfig_requested) {
+ error_report("'preconfig' and 'loadvm' options are "
+ "mutually exclusive");
+ exit(EXIT_FAILURE);
+ }
+ if (incoming && preconfig_requested) {
+ error_report("'preconfig' and 'incoming' options are "
+ "mutually exclusive");
+ exit(EXIT_FAILURE);
+ }
+
+#ifdef CONFIG_CURSES
+ if (is_daemonized() && dpy.type == DISPLAY_TYPE_CURSES) {
+ error_report("curses display cannot be used with -daemonize");
+ exit(1);
+ }
+#endif
}
-void qemu_init(int argc, char **argv, char **envp)
+static void qemu_process_sugar_options(void)
{
- int i;
- int snapshot, linux_boot;
- const char *initrd_filename;
- const char *kernel_filename, *kernel_cmdline;
- const char *boot_order = NULL;
- const char *boot_once = NULL;
- DisplayState *ds;
- QemuOpts *opts, *machine_opts;
- QemuOpts *icount_opts = NULL, *accel_opts = NULL;
- QemuOptsList *olist;
- int optind;
- const char *optarg;
- const char *loadvm = NULL;
- MachineClass *machine_class;
- const char *cpu_option;
- const char *vga_model = NULL;
- const char *incoming = NULL;
- bool userconfig = true;
- bool nographic = false;
- int display_remote = 0;
- const char *log_mask = NULL;
- const char *log_file = NULL;
- ram_addr_t maxram_size;
- uint64_t ram_slots = 0;
- FILE *vmstate_dump_file = NULL;
- Error *main_loop_err = NULL;
- Error *err = NULL;
- bool list_data_dirs = false;
- char **dirs;
- const char *mem_path = NULL;
- bool have_custom_ram_size;
- BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
- QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
- int mem_prealloc = 0; /* force preallocation of physical target memory */
+ if (mem_prealloc) {
+ char *val;
+
+ val = g_strdup_printf("%d",
+ (uint32_t) qemu_opt_get_number(qemu_find_opts_singleton("smp-opts"), "cpus", 1));
+ object_register_sugar_prop("memory-backend", "prealloc-threads", val);
+ g_free(val);
+ object_register_sugar_prop("memory-backend", "prealloc", "on");
+ }
+
+ if (watchdog) {
+ int i = select_watchdog(watchdog);
+ if (i > 0)
+ exit (i == 1 ? 1 : 0);
+ }
+}
+
+static void qemu_process_early_options(void)
+{
+#ifdef CONFIG_SECCOMP
+ QemuOptsList *olist = qemu_find_opts_err("sandbox", NULL);
+ if (olist) {
+ qemu_opts_foreach(olist, parse_sandbox, NULL, &error_fatal);
+ }
+#endif
+
+ qemu_opts_foreach(qemu_find_opts("name"),
+ parse_name, NULL, &error_fatal);
+
+#ifndef _WIN32
+ qemu_opts_foreach(qemu_find_opts("add-fd"),
+ parse_add_fd, NULL, &error_fatal);
+
+ qemu_opts_foreach(qemu_find_opts("add-fd"),
+ cleanup_add_fd, NULL, &error_fatal);
+#endif
+
+ if (!trace_init_backends()) {
+ exit(1);
+ }
+ trace_init_file();
+
+ /* Open the logfile at this point and set the log mask if necessary. */
+ qemu_set_log_filename(log_file, &error_fatal);
+ if (log_mask) {
+ int mask;
+ mask = qemu_str_to_log_mask(log_mask);
+ if (!mask) {
+ qemu_print_log_usage(stdout);
+ exit(1);
+ }
+ qemu_set_log(mask);
+ } else {
+ qemu_set_log(0);
+ }
+
+ qemu_add_default_firmwarepath();
+}
+
+static void qemu_process_help_options(void)
+{
+ /*
+ * Check for -cpu help and -device help before we call select_machine(),
+ * which will return an error if the architecture has no default machine
+ * type and the user did not specify one, so that the user doesn't need
+ * to say '-cpu help -machine something'.
+ */
+ if (cpu_option && is_help_option(cpu_option)) {
+ list_cpus(cpu_option);
+ exit(0);
+ }
+
+ if (qemu_opts_foreach(qemu_find_opts("device"),
+ device_help_func, NULL, NULL)) {
+ exit(0);
+ }
+
+ /* -L help lists the data directories and exits. */
+ if (list_data_dirs) {
+ qemu_list_data_dirs();
+ exit(0);
+ }
+}
+
+static void qemu_maybe_daemonize(const char *pid_file)
+{
+ Error *err;
+
+ os_daemonize();
+ rcu_disable_atfork();
+
+ if (pid_file && !qemu_write_pidfile(pid_file, &err)) {
+ error_reportf_err(err, "cannot create PID file: ");
+ exit(1);
+ }
+
+ qemu_unlink_pidfile_notifier.notify = qemu_unlink_pidfile;
+ qemu_add_exit_notifier(&qemu_unlink_pidfile_notifier);
+}
+
+static void qemu_init_subsystems(void)
+{
+ Error *err;
os_set_line_buffering();
- error_init(argv[0]);
module_call_init(MODULE_INIT_TRACE);
qemu_init_cpu_list();
qemu_init_cpu_loop();
-
qemu_mutex_lock_iothread();
atexit(qemu_run_exit_notifiers);
- qemu_init_exec_dir(argv[0]);
module_call_init(MODULE_INIT_QOM);
module_call_init(MODULE_INIT_MIGRATION);
+ runstate_init();
+ precopy_infrastructure_init();
+ postcopy_infrastructure_init();
+ monitor_init_globals();
+
+ if (qcrypto_init(&err) < 0) {
+ error_reportf_err(err, "cannot initialize crypto: ");
+ exit(1);
+ }
+
+ os_setup_early_signal_handling();
+
+ bdrv_init_with_whitelist();
+ socket_init();
+}
+
+static void qemu_init_displays(void)
+{
+ DisplayState *ds;
+
+ /* init local displays */
+ ds = init_displaystate();
+ qemu_display_init(ds, &dpy);
+
+ /* must be after terminal init, SDL library changes signal handlers */
+ os_setup_signal_handling();
+
+ /* init remote displays */
+#ifdef CONFIG_VNC
+ qemu_opts_foreach(qemu_find_opts("vnc"),
+ vnc_init_func, NULL, &error_fatal);
+#endif
+
+ if (using_spice) {
+ qemu_spice.display_init();
+ }
+}
+
+/*
+ * Called after leaving preconfig state. From here on runstate is
+ * RUN_STATE_PRELAUNCH or RUN_STATE_INMIGRATE.
+ */
+static void qemu_init_board(void)
+{
+ MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
+
+ if (machine_class->default_ram_id && current_machine->ram_size &&
+ numa_uses_legacy_mem() && !current_machine->ram_memdev_id) {
+ create_default_memdev(current_machine, mem_path);
+ }
+
+ /* process plugin before CPUs are created, but once -smp has been parsed */
+ if (qemu_plugin_load_list(&plugin_list)) {
+ exit(1);
+ }
+
+ machine_run_board_init(current_machine);
+
+ /*
+ * TODO To drop support for deprecated bogus if=..., move
+ * drive_check_orphaned() here, replacing this call. Also drop
+ * its deprecation warning, along with DriveInfo member
+ * @claimed_by_board.
+ */
+ drive_mark_claimed_by_board();
+
+ realtime_init();
+
+ if (hax_enabled()) {
+ /* FIXME: why isn't cpu_synchronize_all_post_init enough? */
+ hax_sync_vcpus();
+ }
+}
+
+static void qemu_create_cli_devices(void)
+{
+ soundhw_init();
+
+ qemu_opts_foreach(qemu_find_opts("fw_cfg"),
+ parse_fw_cfg, fw_cfg_find(), &error_fatal);
+
+ /* init USB devices */
+ if (machine_usb(current_machine)) {
+ if (foreach_device_config(DEV_USB, usb_parse) < 0)
+ exit(1);
+ }
+
+ /* init generic devices */
+ rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
+ qemu_opts_foreach(qemu_find_opts("device"),
+ device_init_func, NULL, &error_fatal);
+ rom_reset_order_override();
+}
+
+static void qemu_machine_creation_done(void)
+{
+ cpu_synchronize_all_post_init();
+
+ /* Did we create any drives that we failed to create a device for? */
+ drive_check_orphaned();
+
+ /* Don't warn about the default network setup that you get if
+ * no command line -net or -netdev options are specified. There
+ * are two cases that we would otherwise complain about:
+ * (1) board doesn't support a NIC but the implicit "-net nic"
+ * requested one
+ * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
+ * sets up a nic that isn't connected to anything.
+ */
+ if (!default_net && (!qtest_enabled() || has_defaults)) {
+ net_check_clients();
+ }
+
+ qdev_prop_check_globals();
+
+ if (current_machine->boot_once) {
+ qemu_boot_set(current_machine->boot_once, &error_fatal);
+ qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));
+ }
+
+ if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
+ exit(1);
+ }
+
+ qdev_machine_creation_done();
+
+ /* TODO: once all bus devices are qdevified, this should be done
+ * when bus is created by qdev.c */
+ /*
+ * TODO: If we had a main 'reset container' that the whole system
+ * lived in, we could reset that using the multi-phase reset
+ * APIs. For the moment, we just reset the sysbus, which will cause
+ * all devices hanging off it (and all their child buses, recursively)
+ * to be reset. Note that this will *not* reset any Device objects
+ * which are not attached to some part of the qbus tree!
+ */
+ qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
+ qemu_run_machine_init_done_notifiers();
+
+ if (rom_check_and_register_reset() != 0) {
+ error_report("rom check and register reset failed");
+ exit(1);
+ }
+
+ replay_start();
+
+ /* This checkpoint is required by replay to separate prior clock
+ reading from the other reads, because timer polling functions query
+ clock values from the log. */
+ replay_checkpoint(CHECKPOINT_RESET);
+ qemu_system_reset(SHUTDOWN_CAUSE_NONE);
+ register_global_state();
+}
+
+void qemu_init(int argc, char **argv, char **envp)
+{
+ QemuOpts *opts;
+ QemuOpts *icount_opts = NULL, *accel_opts = NULL;
+ QemuOptsList *olist;
+ int optind;
+ const char *optarg;
+ MachineClass *machine_class;
+ bool userconfig = true;
+ FILE *vmstate_dump_file = NULL;
+
qemu_add_opts(&qemu_drive_opts);
qemu_add_drive_opts(&qemu_legacy_drive_opts);
qemu_add_drive_opts(&qemu_common_drive_opts);
@@ -2950,27 +3337,10 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_fw_cfg_opts);
module_call_init(MODULE_INIT_OPTS);
- runstate_init();
- precopy_infrastructure_init();
- postcopy_infrastructure_init();
- monitor_init_globals();
-
- if (qcrypto_init(&err) < 0) {
- error_reportf_err(err, "cannot initialize crypto: ");
- exit(1);
- }
-
- QTAILQ_INIT(&vm_change_state_head);
- os_setup_early_signal_handling();
-
- cpu_option = NULL;
- snapshot = 0;
-
- nb_nics = 0;
-
- bdrv_init_with_whitelist();
+ error_init(argv[0]);
+ qemu_init_exec_dir(argv[0]);
- autostart = 1;
+ qemu_init_subsystems();
/* first pass of option parsing */
optind = 1;
@@ -3107,20 +3477,16 @@ void qemu_init(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_kernel:
- qemu_opts_set(qemu_find_opts("machine"), NULL, "kernel", optarg,
- &error_abort);
+ qemu_opts_set(qemu_find_opts("machine"), "kernel", optarg, &error_abort);
break;
case QEMU_OPTION_initrd:
- qemu_opts_set(qemu_find_opts("machine"), NULL, "initrd", optarg,
- &error_abort);
+ qemu_opts_set(qemu_find_opts("machine"), "initrd", optarg, &error_abort);
break;
case QEMU_OPTION_append:
- qemu_opts_set(qemu_find_opts("machine"), NULL, "append", optarg,
- &error_abort);
+ qemu_opts_set(qemu_find_opts("machine"), "append", optarg, &error_abort);
break;
case QEMU_OPTION_dtb:
- qemu_opts_set(qemu_find_opts("machine"), NULL, "dtb", optarg,
- &error_abort);
+ qemu_opts_set(qemu_find_opts("machine"), "dtb", optarg, &error_abort);
break;
case QEMU_OPTION_cdrom:
drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
@@ -3230,8 +3596,7 @@ void qemu_init(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_bios:
- qemu_opts_set(qemu_find_opts("machine"), NULL, "firmware", optarg,
- &error_abort);
+ qemu_opts_set(qemu_find_opts("machine"), "firmware", optarg, &error_abort);
break;
case QEMU_OPTION_singlestep:
singlestep = 1;
@@ -3492,6 +3857,7 @@ void qemu_init(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_preconfig:
preconfig_exit_requested = false;
+ preconfig_requested = true;
break;
case QEMU_OPTION_enable_kvm:
olist = qemu_find_opts("machine");
@@ -3842,330 +4208,33 @@ void qemu_init(int argc, char **argv, char **envp)
*/
loc_set_none();
+ qemu_validate_options();
+ qemu_process_sugar_options();
+
/*
- * Check for -cpu help and -device help before we call select_machine(),
- * which will return an error if the architecture has no default machine
- * type and the user did not specify one, so that the user doesn't need
- * to say '-cpu help -machine something'.
+ * These options affect everything else and should be processed
+ * before daemonizing.
*/
- if (cpu_option && is_help_option(cpu_option)) {
- list_cpus(cpu_option);
- exit(0);
- }
+ qemu_process_early_options();
- if (qemu_opts_foreach(qemu_find_opts("device"),
- device_help_func, NULL, NULL)) {
- exit(0);
- }
+ qemu_process_help_options();
+ qemu_maybe_daemonize(pid_file);
- user_register_global_props();
+ qemu_init_main_loop(&error_fatal);
+ cpu_timers_init();
+ user_register_global_props();
replay_configure(icount_opts);
- if (incoming && !preconfig_exit_requested) {
- error_report("'preconfig' and 'incoming' options are "
- "mutually exclusive");
- exit(EXIT_FAILURE);
- }
-
configure_rtc(qemu_find_opts_singleton("rtc"));
- machine_class = select_machine();
- object_set_machine_compat_props(machine_class->compat_props);
-
- have_custom_ram_size = set_memory_options(&ram_slots, &maxram_size,
- machine_class);
-
- os_daemonize();
- rcu_disable_atfork();
-
- if (pid_file && !qemu_write_pidfile(pid_file, &err)) {
- error_reportf_err(err, "cannot create PID file: ");
- exit(1);
- }
-
- qemu_unlink_pidfile_notifier.notify = qemu_unlink_pidfile;
- qemu_add_exit_notifier(&qemu_unlink_pidfile_notifier);
-
- if (qemu_init_main_loop(&main_loop_err)) {
- error_report_err(main_loop_err);
- exit(1);
- }
-
-#ifdef CONFIG_SECCOMP
- olist = qemu_find_opts_err("sandbox", NULL);
- if (olist) {
- qemu_opts_foreach(olist, parse_sandbox, NULL, &error_fatal);
- }
-#endif
-
- qemu_opts_foreach(qemu_find_opts("name"),
- parse_name, NULL, &error_fatal);
-
-#ifndef _WIN32
- qemu_opts_foreach(qemu_find_opts("add-fd"),
- parse_add_fd, NULL, &error_fatal);
-
- qemu_opts_foreach(qemu_find_opts("add-fd"),
- cleanup_add_fd, NULL, &error_fatal);
-#endif
-
- current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
- if (machine_help_func(qemu_get_machine_opts(), current_machine)) {
- exit(0);
- }
- object_property_add_child(object_get_root(), "machine",
- OBJECT(current_machine));
- object_property_add_child(container_get(OBJECT(current_machine),
- "/unattached"),
- "sysbus", OBJECT(sysbus_get_default()));
-
- if (machine_class->minimum_page_bits) {
- if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
- /* This would be a board error: specifying a minimum smaller than
- * a target's compile-time fixed setting.
- */
- g_assert_not_reached();
- }
- }
-
- cpu_exec_init_all();
-
- if (machine_class->hw_version) {
- qemu_set_hw_version(machine_class->hw_version);
- }
-
- if (!trace_init_backends()) {
- exit(1);
- }
- trace_init_file();
-
- /* Open the logfile at this point and set the log mask if necessary.
- */
- qemu_set_log_filename(log_file, &error_fatal);
- if (log_mask) {
- int mask;
- mask = qemu_str_to_log_mask(log_mask);
- if (!mask) {
- qemu_print_log_usage(stdout);
- exit(1);
- }
- qemu_set_log(mask);
- } else {
- qemu_set_log(0);
- }
-
- /* add configured firmware directories */
- dirs = g_strsplit(CONFIG_QEMU_FIRMWAREPATH, G_SEARCHPATH_SEPARATOR_S, 0);
- for (i = 0; dirs[i] != NULL; i++) {
- qemu_add_data_dir(get_relocated_path(dirs[i]));
- }
- g_strfreev(dirs);
-
- /* try to find datadir relative to the executable path */
- qemu_add_data_dir(find_datadir());
-
- /* -L help lists the data directories and exits. */
- if (list_data_dirs) {
- for (i = 0; i < data_dir_idx; i++) {
- printf("%s\n", data_dir[i]);
- }
- exit(0);
- }
-
- machine_class->smp_parse(current_machine,
- qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
-
- /* sanity-check smp_cpus and max_cpus against machine_class */
- if (current_machine->smp.cpus < machine_class->min_cpus) {
- error_report("Invalid SMP CPUs %d. The min CPUs "
- "supported by machine '%s' is %d",
- current_machine->smp.cpus,
- machine_class->name, machine_class->min_cpus);
- exit(1);
- }
- if (current_machine->smp.max_cpus > machine_class->max_cpus) {
- error_report("Invalid SMP CPUs %d. The max CPUs "
- "supported by machine '%s' is %d",
- current_machine->smp.max_cpus,
- machine_class->name, machine_class->max_cpus);
- exit(1);
- }
+ qemu_create_machine(select_machine());
- if (mem_prealloc) {
- char *val;
+ qemu_disable_default_devices();
+ qemu_create_default_devices();
+ qemu_create_early_backends();
- val = g_strdup_printf("%d", current_machine->smp.cpus);
- object_register_sugar_prop("memory-backend", "prealloc-threads", val);
- g_free(val);
- object_register_sugar_prop("memory-backend", "prealloc", "on");
- }
-
- /*
- * Get the default machine options from the machine if it is not already
- * specified either by the configuration file or by the command line.
- */
- if (machine_class->default_machine_opts) {
- qemu_opts_set_defaults(qemu_find_opts("machine"),
- machine_class->default_machine_opts, 0);
- }
-
- /* process plugin before CPUs are created, but once -smp has been parsed */
- if (qemu_plugin_load_list(&plugin_list)) {
- exit(1);
- }
-
- qemu_opts_foreach(qemu_find_opts("device"),
- default_driver_check, NULL, NULL);
- qemu_opts_foreach(qemu_find_opts("global"),
- default_driver_check, NULL, NULL);
-
- if (!vga_model && !default_vga) {
- vga_interface_type = VGA_DEVICE;
- }
- if (!has_defaults || machine_class->no_serial) {
- default_serial = 0;
- }
- if (!has_defaults || machine_class->no_parallel) {
- default_parallel = 0;
- }
- if (!has_defaults || machine_class->no_floppy) {
- default_floppy = 0;
- }
- if (!has_defaults || machine_class->no_cdrom) {
- default_cdrom = 0;
- }
- if (!has_defaults || machine_class->no_sdcard) {
- default_sdcard = 0;
- }
- if (!has_defaults) {
- default_monitor = 0;
- default_net = 0;
- default_vga = 0;
- }
-
- if (is_daemonized()) {
- if (!preconfig_exit_requested) {
- error_report("'preconfig' and 'daemonize' options are "
- "mutually exclusive");
- exit(EXIT_FAILURE);
- }
-
- /* According to documentation and historically, -nographic redirects
- * serial port, parallel port and monitor to stdio, which does not work
- * with -daemonize. We can redirect these to null instead, but since
- * -nographic is legacy, let's just error out.
- * We disallow -nographic only if all other ports are not redirected
- * explicitly, to not break existing legacy setups which uses
- * -nographic _and_ redirects all ports explicitly - this is valid
- * usage, -nographic is just a no-op in this case.
- */
- if (nographic
- && (default_parallel || default_serial || default_monitor)) {
- error_report("-nographic cannot be used with -daemonize");
- exit(1);
- }
-#ifdef CONFIG_CURSES
- if (dpy.type == DISPLAY_TYPE_CURSES) {
- error_report("curses display cannot be used with -daemonize");
- exit(1);
- }
-#endif
- }
-
- if (nographic) {
- if (default_parallel)
- add_device_config(DEV_PARALLEL, "null");
- if (default_serial && default_monitor) {
- add_device_config(DEV_SERIAL, "mon:stdio");
- } else {
- if (default_serial)
- add_device_config(DEV_SERIAL, "stdio");
- if (default_monitor)
- monitor_parse("stdio", "readline", false);
- }
- } else {
- if (default_serial)
- add_device_config(DEV_SERIAL, "vc:80Cx24C");
- if (default_parallel)
- add_device_config(DEV_PARALLEL, "vc:80Cx24C");
- if (default_monitor)
- monitor_parse("vc:80Cx24C", "readline", false);
- }
-
-#if defined(CONFIG_VNC)
- if (!QTAILQ_EMPTY(&(qemu_find_opts("vnc")->head))) {
- display_remote++;
- }
-#endif
- if (dpy.type == DISPLAY_TYPE_DEFAULT && !display_remote) {
- if (!qemu_display_find_default(&dpy)) {
- dpy.type = DISPLAY_TYPE_NONE;
-#if defined(CONFIG_VNC)
- vnc_parse("localhost:0,to=99,id=default", &error_abort);
-#endif
- }
- }
- if (dpy.type == DISPLAY_TYPE_DEFAULT) {
- dpy.type = DISPLAY_TYPE_NONE;
- }
-
- if ((alt_grab || ctrl_grab) && dpy.type != DISPLAY_TYPE_SDL) {
- error_report("-alt-grab and -ctrl-grab are only valid "
- "for SDL, ignoring option");
- }
- if (dpy.has_window_close &&
- (dpy.type != DISPLAY_TYPE_GTK && dpy.type != DISPLAY_TYPE_SDL)) {
- error_report("-no-quit is only valid for GTK and SDL, "
- "ignoring option");
- }
-
- qemu_display_early_init(&dpy);
- qemu_console_early_init();
-
- if (dpy.has_gl && dpy.gl != DISPLAYGL_MODE_OFF && display_opengl == 0) {
-#if defined(CONFIG_OPENGL)
- error_report("OpenGL is not supported by the display");
-#else
- error_report("OpenGL support is disabled");
-#endif
- exit(1);
- }
-
- page_size_init();
- socket_init();
-
- qemu_opts_foreach(qemu_find_opts("object"),
- user_creatable_add_opts_foreach,
- object_create_initial, &error_fatal);
-
- /* spice needs the timers to be initialized by this point */
- /* spice must initialize before audio as it changes the default auiodev */
- /* spice must initialize before chardevs (for spicevmc and spiceport) */
- qemu_spice.init();
-
- qemu_opts_foreach(qemu_find_opts("chardev"),
- chardev_init_func, NULL, &error_fatal);
-
-#ifdef CONFIG_VIRTFS
- qemu_opts_foreach(qemu_find_opts("fsdev"),
- fsdev_init_func, NULL, &error_fatal);
-#endif
-
- /*
- * Note: we need to create audio and block backends before
- * machine_set_property(), so machine properties can refer to
- * them.
- */
- configure_blockdev(&bdo_queue, machine_class, snapshot);
- audio_init_audiodevs();
-
- machine_opts = qemu_get_machine_opts();
- qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
- &error_fatal);
- current_machine->ram_size = ram_size;
- current_machine->maxram_size = maxram_size;
- current_machine->ram_slots = ram_slots;
+ qemu_apply_machine_options();
/*
* Note: uses machine properties such as kernel-irqchip, must run
@@ -4189,6 +4258,7 @@ void qemu_init(int argc, char **argv, char **envp)
* called from configure_accelerator().
*/
+ machine_class = MACHINE_GET_CLASS(current_machine);
if (!qtest_enabled() && machine_class->deprecation_reason) {
error_report("Machine type '%s' is deprecated: %s",
machine_class->name, machine_class->deprecation_reason);
@@ -4200,121 +4270,7 @@ void qemu_init(int argc, char **argv, char **envp)
*/
migration_object_init();
- if (qtest_chrdev) {
- qtest_server_init(qtest_chrdev, qtest_log, &error_fatal);
- }
-
- machine_opts = qemu_get_machine_opts();
- kernel_filename = qemu_opt_get(machine_opts, "kernel");
- initrd_filename = qemu_opt_get(machine_opts, "initrd");
- kernel_cmdline = qemu_opt_get(machine_opts, "append");
- bios_name = qemu_opt_get(machine_opts, "firmware");
-
- opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
- if (opts) {
- boot_order = qemu_opt_get(opts, "order");
- if (boot_order) {
- validate_bootdevices(boot_order, &error_fatal);
- }
-
- boot_once = qemu_opt_get(opts, "once");
- if (boot_once) {
- validate_bootdevices(boot_once, &error_fatal);
- }
-
- boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu);
- boot_strict = qemu_opt_get_bool(opts, "strict", false);
- }
-
- if (!boot_order) {
- boot_order = machine_class->default_boot_order;
- }
-
- if (!kernel_cmdline) {
- kernel_cmdline = "";
- current_machine->kernel_cmdline = (char *)kernel_cmdline;
- }
-
- linux_boot = (kernel_filename != NULL);
-
- if (!linux_boot && *kernel_cmdline != '\0') {
- error_report("-append only allowed with -kernel option");
- exit(1);
- }
-
- if (!linux_boot && initrd_filename != NULL) {
- error_report("-initrd only allowed with -kernel option");
- exit(1);
- }
-
- if (semihosting_enabled() && !semihosting_get_argc() && kernel_filename) {
- /* fall back to the -kernel/-append */
- semihosting_arg_fallback(kernel_filename, kernel_cmdline);
- }
-
- /* initialize cpu timers and VCPU throttle modules */
- cpu_timers_init();
-
- if (default_net) {
- QemuOptsList *net = qemu_find_opts("net");
- qemu_opts_set(net, NULL, "type", "nic", &error_abort);
-#ifdef CONFIG_SLIRP
- qemu_opts_set(net, NULL, "type", "user", &error_abort);
-#endif
- }
-
- if (net_init_clients(&err) < 0) {
- error_report_err(err);
- exit(1);
- }
-
- qemu_opts_foreach(qemu_find_opts("object"),
- user_creatable_add_opts_foreach,
- object_create_delayed, &error_fatal);
-
- if (tpm_init() < 0) {
- exit(1);
- }
-
- blk_mig_init();
- ram_mig_init();
- dirty_bitmap_mig_init();
-
- qemu_opts_foreach(qemu_find_opts("mon"),
- mon_init_func, NULL, &error_fatal);
-
- if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
- exit(1);
- if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
- exit(1);
- if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
- exit(1);
-
- /* now chardevs have been created we may have semihosting to connect */
- qemu_semihosting_connect_chardevs();
- qemu_semihosting_console_init();
-
- /* If no default VGA is requested, the default is "none". */
- if (default_vga) {
- vga_model = get_default_vga_model(machine_class);
- }
- if (vga_model) {
- select_vgahw(machine_class, vga_model);
- }
-
- if (watchdog) {
- i = select_watchdog(watchdog);
- if (i > 0)
- exit (i == 1 ? 1 : 0);
- }
-
- /* This checkpoint is required by replay to separate prior clock
- reading from the other reads, because timer polling functions query
- clock values from the log. */
- replay_checkpoint(CHECKPOINT_INIT);
- qdev_machine_init();
-
- current_machine->boot_order = boot_order;
+ qemu_create_late_backends();
/* parse features once if machine provides default cpu_type */
current_machine->cpu_type = machine_class->default_cpu_type;
@@ -4322,155 +4278,26 @@ void qemu_init(int argc, char **argv, char **envp)
current_machine->cpu_type = parse_cpu_option(cpu_option);
}
- if (current_machine->ram_memdev_id) {
- Object *backend;
- ram_addr_t backend_size;
-
- backend = object_resolve_path_type(current_machine->ram_memdev_id,
- TYPE_MEMORY_BACKEND, NULL);
- if (!backend) {
- error_report("Memory backend '%s' not found",
- current_machine->ram_memdev_id);
- exit(EXIT_FAILURE);
- }
- backend_size = object_property_get_uint(backend, "size", &error_abort);
- if (have_custom_ram_size && backend_size != ram_size) {
- error_report("Size specified by -m option must match size of "
- "explicitly specified 'memory-backend' property");
- exit(EXIT_FAILURE);
- }
- if (mem_path) {
- error_report("'-mem-path' can't be used together with"
- "'-machine memory-backend'");
- exit(EXIT_FAILURE);
- }
- ram_size = backend_size;
- }
+ qemu_resolve_machine_memdev();
+ parse_numa_opts(current_machine);
- if (!xen_enabled()) {
- /* On 32-bit hosts, QEMU is limited by virtual address space */
- if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
- error_report("at most 2047 MB RAM can be simulated");
- exit(1);
- }
+ if (preconfig_requested) {
+ qemu_init_displays();
}
- parse_numa_opts(current_machine);
-
/* do monitor/qmp handling at preconfig state if requested */
qemu_main_loop();
- if (machine_class->default_ram_id && current_machine->ram_size &&
- numa_uses_legacy_mem() && !current_machine->ram_memdev_id) {
- create_default_memdev(current_machine, mem_path);
- }
-
- /* from here on runstate is RUN_STATE_PRELAUNCH */
- machine_run_board_init(current_machine);
-
- /*
- * TODO To drop support for deprecated bogus if=..., move
- * drive_check_orphaned() here, replacing this call. Also drop
- * its deprecation warning, along with DriveInfo member
- * @claimed_by_board.
- */
- drive_mark_claimed_by_board();
-
- realtime_init();
+ qemu_init_board();
- soundhw_init();
+ qemu_create_cli_devices();
- if (hax_enabled()) {
- hax_sync_vcpus();
+ /* initialize displays after all errors have been reported */
+ if (!preconfig_requested) {
+ qemu_init_displays();
}
+ qemu_machine_creation_done();
- qemu_opts_foreach(qemu_find_opts("fw_cfg"),
- parse_fw_cfg, fw_cfg_find(), &error_fatal);
-
- /* init USB devices */
- if (machine_usb(current_machine)) {
- if (foreach_device_config(DEV_USB, usb_parse) < 0)
- exit(1);
- }
-
- /* init generic devices */
- rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
- qemu_opts_foreach(qemu_find_opts("device"),
- device_init_func, NULL, &error_fatal);
-
- cpu_synchronize_all_post_init();
-
- rom_reset_order_override();
-
- /* Did we create any drives that we failed to create a device for? */
- drive_check_orphaned();
-
- /* Don't warn about the default network setup that you get if
- * no command line -net or -netdev options are specified. There
- * are two cases that we would otherwise complain about:
- * (1) board doesn't support a NIC but the implicit "-net nic"
- * requested one
- * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
- * sets up a nic that isn't connected to anything.
- */
- if (!default_net && (!qtest_enabled() || has_defaults)) {
- net_check_clients();
- }
-
- if (boot_once) {
- qemu_boot_set(boot_once, &error_fatal);
- qemu_register_reset(restore_boot_order, g_strdup(boot_order));
- }
-
- /* init local displays */
- ds = init_displaystate();
- qemu_display_init(ds, &dpy);
-
- /* must be after terminal init, SDL library changes signal handlers */
- os_setup_signal_handling();
-
- /* init remote displays */
-#ifdef CONFIG_VNC
- qemu_opts_foreach(qemu_find_opts("vnc"),
- vnc_init_func, NULL, &error_fatal);
-#endif
-
- if (using_spice) {
- qemu_spice.display_init();
- }
-
- if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
- exit(1);
- }
-
- qdev_machine_creation_done();
-
- /* TODO: once all bus devices are qdevified, this should be done
- * when bus is created by qdev.c */
- /*
- * TODO: If we had a main 'reset container' that the whole system
- * lived in, we could reset that using the multi-phase reset
- * APIs. For the moment, we just reset the sysbus, which will cause
- * all devices hanging off it (and all their child buses, recursively)
- * to be reset. Note that this will *not* reset any Device objects
- * which are not attached to some part of the qbus tree!
- */
- qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
- qemu_run_machine_init_done_notifiers();
-
- if (rom_check_and_register_reset() != 0) {
- error_report("rom check and register reset failed");
- exit(1);
- }
-
- replay_start();
-
- /* This checkpoint is required by replay to separate prior clock
- reading from the other reads, because timer polling functions query
- clock values from the log. */
- replay_checkpoint(CHECKPOINT_RESET);
- qemu_system_reset(SHUTDOWN_CAUSE_NONE);
- register_global_state();
if (loadvm) {
Error *local_err = NULL;
if (load_snapshot(loadvm, &local_err) < 0) {
@@ -4483,22 +4310,22 @@ void qemu_init(int argc, char **argv, char **envp)
replay_vmstate_init();
}
- qdev_prop_check_globals();
if (vmstate_dump_file) {
/* dump and exit */
dump_vmstate_json_to_file(vmstate_dump_file);
exit(0);
}
-
if (incoming) {
Error *local_err = NULL;
- qemu_start_incoming_migration(incoming, &local_err);
- if (local_err) {
- error_reportf_err(local_err, "-incoming %s: ", incoming);
- exit(1);
+ if (strcmp(incoming, "defer") != 0) {
+ qmp_migrate_incoming(incoming, &local_err);
+ if (local_err) {
+ error_reportf_err(local_err, "-incoming %s: ", incoming);
+ exit(1);
+ }
}
} else if (autostart) {
- vm_start();
+ qmp_cont(NULL);
}
accel_setup_post(current_machine);
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
index c892e0e674..f7b7bff522 100644
--- a/target/arm/arm-semi.c
+++ b/target/arm/arm-semi.c
@@ -37,6 +37,7 @@
#include "exec/gdbstub.h"
#include "qemu/cutils.h"
#include "hw/arm/boot.h"
+#include "hw/boards.h"
#endif
#define TARGET_SYS_OPEN 0x01
@@ -1048,7 +1049,7 @@ target_ulong do_arm_semihosting(CPUARMState *env)
retvals[2] = ts->stack_base;
retvals[3] = 0; /* Stack limit. */
#else
- limit = ram_size;
+ limit = current_machine->ram_size;
/* TODO: Make this use the limit of the loaded application. */
retvals[0] = rambase + limit / 2;
retvals[1] = rambase + limit;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 900ea08283..6c11feeb92 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -30,6 +30,7 @@
#include "sysemu/hvf.h"
#include "sysemu/cpus.h"
#include "sysemu/xen.h"
+#include "sysemu/whpx.h"
#include "kvm_i386.h"
#include "sev_i386.h"
@@ -800,7 +801,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"kvmclock", "kvm-nopiodelay", "kvm-mmu", "kvmclock",
"kvm-asyncpf", "kvm-steal-time", "kvm-pv-eoi", "kvm-pv-unhalt",
NULL, "kvm-pv-tlb-flush", NULL, "kvm-pv-ipi",
- "kvm-poll-control", "kvm-pv-sched-yield", "kvm-asyncpf-int", NULL,
+ "kvm-poll-control", "kvm-pv-sched-yield", "kvm-asyncpf-int", "kvm-msi-ext-dest-id",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
"kvmclock-stable-bit", NULL, NULL, NULL,
@@ -4139,6 +4140,7 @@ static PropValue kvm_default_props[] = {
{ "kvm-pv-eoi", "on" },
{ "kvmclock-stable-bit", "on" },
{ "x2apic", "on" },
+ { "kvm-msi-ext-dest-id", "off" },
{ "acpi", "off" },
{ "monitor", "off" },
{ "svm", "off" },
@@ -5165,6 +5167,8 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
if (kvm_enabled()) {
if (!kvm_irqchip_in_kernel()) {
x86_cpu_change_kvm_default("x2apic", "off");
+ } else if (kvm_irqchip_is_split() && kvm_enable_x2apic()) {
+ x86_cpu_change_kvm_default("kvm-msi-ext-dest-id", "on");
}
x86_cpu_apply_props(cpu, kvm_default_props);
@@ -6173,6 +6177,8 @@ APICCommonClass *apic_get_class(void)
apic_type = "kvm-apic";
} else if (xen_enabled()) {
apic_type = "xen-apic";
+ } else if (whpx_apic_in_platform()) {
+ apic_type = "whpx-apic";
}
return APIC_COMMON_CLASS(object_class_by_name(apic_type));
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index a2934dda02..bcfa4b03e0 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -416,6 +416,9 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
if (!kvm_irqchip_in_kernel()) {
ret &= ~(1U << KVM_FEATURE_PV_UNHALT);
}
+ if (kvm_irqchip_is_split()) {
+ ret |= 1U << KVM_FEATURE_MSI_EXT_DEST_ID;
+ }
} else if (function == KVM_CPUID_FEATURES && reg == R_EDX) {
ret |= 1U << KVM_HINTS_REALTIME;
}
@@ -4589,38 +4592,74 @@ int kvm_arch_irqchip_create(KVMState *s)
}
}
+uint64_t kvm_swizzle_msi_ext_dest_id(uint64_t address)
+{
+ CPUX86State *env;
+ uint64_t ext_id;
+
+ if (!first_cpu) {
+ return address;
+ }
+ env = &X86_CPU(first_cpu)->env;
+ if (!(env->features[FEAT_KVM] & (1 << KVM_FEATURE_MSI_EXT_DEST_ID))) {
+ return address;
+ }
+
+ /*
+ * If the remappable format bit is set, or the upper bits are
+ * already set in address_hi, or the low extended bits aren't
+ * there anyway, do nothing.
+ */
+ ext_id = address & (0xff << MSI_ADDR_DEST_IDX_SHIFT);
+ if (!ext_id || (ext_id & (1 << MSI_ADDR_DEST_IDX_SHIFT)) || (address >> 32)) {
+ return address;
+ }
+
+ address &= ~ext_id;
+ address |= ext_id << 35;
+ return address;
+}
+
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint64_t address, uint32_t data, PCIDevice *dev)
{
X86IOMMUState *iommu = x86_iommu_get_default();
if (iommu) {
- int ret;
- MSIMessage src, dst;
X86IOMMUClass *class = X86_IOMMU_DEVICE_GET_CLASS(iommu);
- if (!class->int_remap) {
- return 0;
- }
+ if (class->int_remap) {
+ int ret;
+ MSIMessage src, dst;
- src.address = route->u.msi.address_hi;
- src.address <<= VTD_MSI_ADDR_HI_SHIFT;
- src.address |= route->u.msi.address_lo;
- src.data = route->u.msi.data;
+ src.address = route->u.msi.address_hi;
+ src.address <<= VTD_MSI_ADDR_HI_SHIFT;
+ src.address |= route->u.msi.address_lo;
+ src.data = route->u.msi.data;
- ret = class->int_remap(iommu, &src, &dst, dev ? \
- pci_requester_id(dev) : \
- X86_IOMMU_SID_INVALID);
- if (ret) {
- trace_kvm_x86_fixup_msi_error(route->gsi);
- return 1;
- }
+ ret = class->int_remap(iommu, &src, &dst, dev ? \
+ pci_requester_id(dev) : \
+ X86_IOMMU_SID_INVALID);
+ if (ret) {
+ trace_kvm_x86_fixup_msi_error(route->gsi);
+ return 1;
+ }
+
+ /*
+ * Handled untranslated compatibilty format interrupt with
+ * extended destination ID in the low bits 11-5. */
+ dst.address = kvm_swizzle_msi_ext_dest_id(dst.address);
- route->u.msi.address_hi = dst.address >> VTD_MSI_ADDR_HI_SHIFT;
- route->u.msi.address_lo = dst.address & VTD_MSI_ADDR_LO_MASK;
- route->u.msi.data = dst.data;
+ route->u.msi.address_hi = dst.address >> VTD_MSI_ADDR_HI_SHIFT;
+ route->u.msi.address_lo = dst.address & VTD_MSI_ADDR_LO_MASK;
+ route->u.msi.data = dst.data;
+ return 0;
+ }
}
+ address = kvm_swizzle_msi_ext_dest_id(address);
+ route->u.msi.address_hi = address >> VTD_MSI_ADDR_HI_SHIFT;
+ route->u.msi.address_lo = address & VTD_MSI_ADDR_LO_MASK;
return 0;
}
diff --git a/target/i386/kvm_i386.h b/target/i386/kvm_i386.h
index a4a619cebb..dc72508389 100644
--- a/target/i386/kvm_i386.h
+++ b/target/i386/kvm_i386.h
@@ -48,4 +48,6 @@ bool kvm_has_waitpkg(void);
bool kvm_hv_vpindex_settable(void);
+uint64_t kvm_swizzle_msi_ext_dest_id(uint64_t address);
+
#endif
diff --git a/target/i386/meson.build b/target/i386/meson.build
index a1a02f3e99..fc3ee80386 100644
--- a/target/i386/meson.build
+++ b/target/i386/meson.build
@@ -33,6 +33,7 @@ i386_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
i386_softmmu_ss.add(when: 'CONFIG_WHPX', if_true: files(
'whpx-all.c',
'whpx-cpus.c',
+ 'whpx-apic.c',
))
i386_softmmu_ss.add(when: 'CONFIG_HAX', if_true: files(
'hax-all.c',
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 09b6554660..e6ffa1f018 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -2108,7 +2108,10 @@ static inline void validate_seg(CPUX86State *env, int seg_reg, int cpl)
if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
/* data or non conforming code segment */
if (dpl < cpl) {
- cpu_x86_load_seg_cache(env, seg_reg, 0, 0, 0, 0);
+ cpu_x86_load_seg_cache(env, seg_reg, 0,
+ env->segs[seg_reg].base,
+ env->segs[seg_reg].limit,
+ env->segs[seg_reg].flags & ~DESC_P_MASK);
}
}
}
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 4c57307e42..e8f5f5803a 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -3936,14 +3936,14 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
}
ot = mo_64_32(s->dflag);
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
- /* Note that by zero-extending the mask operand, we
+ /* Note that by zero-extending the source operand, we
automatically handle zero-extending the result. */
if (ot == MO_64) {
tcg_gen_mov_tl(s->T1, cpu_regs[s->vex_v]);
} else {
tcg_gen_ext32u_tl(s->T1, cpu_regs[s->vex_v]);
}
- gen_helper_pdep(cpu_regs[reg], s->T0, s->T1);
+ gen_helper_pdep(cpu_regs[reg], s->T1, s->T0);
break;
case 0x2f5: /* pext Gy, By, Ey */
@@ -3954,14 +3954,14 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
}
ot = mo_64_32(s->dflag);
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
- /* Note that by zero-extending the mask operand, we
+ /* Note that by zero-extending the source operand, we
automatically handle zero-extending the result. */
if (ot == MO_64) {
tcg_gen_mov_tl(s->T1, cpu_regs[s->vex_v]);
} else {
tcg_gen_ext32u_tl(s->T1, cpu_regs[s->vex_v]);
}
- gen_helper_pext(cpu_regs[reg], s->T0, s->T1);
+ gen_helper_pext(cpu_regs[reg], s->T1, s->T0);
break;
case 0x1f6: /* adcx Gy, Ey */
diff --git a/target/i386/whp-dispatch.h b/target/i386/whp-dispatch.h
index b18aba20ed..cef5d848bd 100644
--- a/target/i386/whp-dispatch.h
+++ b/target/i386/whp-dispatch.h
@@ -30,6 +30,14 @@
*/
#define LIST_WINHVPLATFORM_FUNCTIONS_SUPPLEMENTAL(X) \
X(HRESULT, WHvSuspendPartitionTime, (WHV_PARTITION_HANDLE Partition)) \
+ X(HRESULT, WHvRequestInterrupt, (WHV_PARTITION_HANDLE Partition, \
+ WHV_INTERRUPT_CONTROL* Interrupt, UINT32 InterruptControlSize)) \
+ X(HRESULT, WHvGetVirtualProcessorInterruptControllerState2, \
+ (WHV_PARTITION_HANDLE Partition, UINT32 VpIndex, PVOID State, \
+ UINT32 StateSize, UINT32* WrittenSize)) \
+ X(HRESULT, WHvSetVirtualProcessorInterruptControllerState2, \
+ (WHV_PARTITION_HANDLE Partition, UINT32 VpIndex, PVOID State, \
+ UINT32 StateSize)) \
#define LIST_WINHVEMULATION_FUNCTIONS(X) \
X(HRESULT, WHvEmulatorCreateEmulator, (const WHV_EMULATOR_CALLBACKS* Callbacks, WHV_EMULATOR_HANDLE* Emulator)) \
@@ -37,7 +45,6 @@
X(HRESULT, WHvEmulatorTryIoEmulation, (WHV_EMULATOR_HANDLE Emulator, VOID* Context, const WHV_VP_EXIT_CONTEXT* VpContext, const WHV_X64_IO_PORT_ACCESS_CONTEXT* IoInstructionContext, WHV_EMULATOR_STATUS* EmulatorReturnStatus)) \
X(HRESULT, WHvEmulatorTryMmioEmulation, (WHV_EMULATOR_HANDLE Emulator, VOID* Context, const WHV_VP_EXIT_CONTEXT* VpContext, const WHV_MEMORY_ACCESS_CONTEXT* MmioInstructionContext, WHV_EMULATOR_STATUS* EmulatorReturnStatus)) \
-
#define WHP_DEFINE_TYPE(return_type, function_name, signature) \
typedef return_type (WINAPI *function_name ## _t) signature;
diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c
index f4f3e33eac..3b824fc9d7 100644
--- a/target/i386/whpx-all.c
+++ b/target/i386/whpx-all.c
@@ -19,10 +19,15 @@
#include "sysemu/runstate.h"
#include "qemu/main-loop.h"
#include "hw/boards.h"
+#include "hw/i386/ioapic.h"
+#include "hw/i386/apic_internal.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
+#include "qapi/qapi-types-common.h"
+#include "qapi/qapi-visit-common.h"
#include "migration/blocker.h"
#include "whp-dispatch.h"
+#include <winerror.h>
#include "whpx-cpus.h"
@@ -31,11 +36,6 @@
#define HYPERV_APIC_BUS_FREQUENCY (200000000ULL)
-struct whpx_state {
- uint64_t mem_quota;
- WHV_PARTITION_HANDLE partition;
-};
-
static const WHV_REGISTER_NAME whpx_register_names[] = {
/* X64 General purpose registers */
@@ -152,6 +152,7 @@ struct whpx_vcpu {
WHV_EMULATOR_HANDLE emulator;
bool window_registered;
bool interruptable;
+ bool ready_for_pic_interrupt;
uint64_t tpr;
uint64_t apic_base;
bool interruption_pending;
@@ -163,7 +164,7 @@ struct whpx_vcpu {
static bool whpx_allowed;
static bool whp_dispatch_initialized;
static HMODULE hWinHvPlatform, hWinHvEmulation;
-
+static uint32_t max_vcpu_index;
struct whpx_state whpx_global;
struct WHPDispatch whp_dispatch;
@@ -599,6 +600,10 @@ static void whpx_get_registers(CPUState *cpu)
assert(idx == RTL_NUMBER_OF(whpx_register_names));
+ if (whpx_apic_in_platform()) {
+ whpx_apic_get(x86_cpu->apic_state);
+ }
+
return;
}
@@ -820,26 +825,42 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
}
/* Get pending hard interruption or replay one that was overwritten */
- if (!vcpu->interruption_pending &&
- vcpu->interruptable && (env->eflags & IF_MASK)) {
- assert(!new_int.InterruptionPending);
- if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
- cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
- irq = cpu_get_pic_interrupt(env);
- if (irq >= 0) {
- new_int.InterruptionType = WHvX64PendingInterrupt;
- new_int.InterruptionPending = 1;
- new_int.InterruptionVector = irq;
+ if (!whpx_apic_in_platform()) {
+ if (!vcpu->interruption_pending &&
+ vcpu->interruptable && (env->eflags & IF_MASK)) {
+ assert(!new_int.InterruptionPending);
+ if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
+ cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
+ irq = cpu_get_pic_interrupt(env);
+ if (irq >= 0) {
+ new_int.InterruptionType = WHvX64PendingInterrupt;
+ new_int.InterruptionPending = 1;
+ new_int.InterruptionVector = irq;
+ }
}
}
- }
- /* Setup interrupt state if new one was prepared */
- if (new_int.InterruptionPending) {
- reg_values[reg_count].PendingInterruption = new_int;
- reg_names[reg_count] = WHvRegisterPendingInterruption;
- reg_count += 1;
- }
+ /* Setup interrupt state if new one was prepared */
+ if (new_int.InterruptionPending) {
+ reg_values[reg_count].PendingInterruption = new_int;
+ reg_names[reg_count] = WHvRegisterPendingInterruption;
+ reg_count += 1;
+ }
+ } else if (vcpu->ready_for_pic_interrupt &&
+ (cpu->interrupt_request & CPU_INTERRUPT_HARD)) {
+ cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
+ irq = cpu_get_pic_interrupt(env);
+ if (irq >= 0) {
+ reg_names[reg_count] = WHvRegisterPendingEvent;
+ reg_values[reg_count].ExtIntEvent = (WHV_X64_PENDING_EXT_INT_EVENT)
+ {
+ .EventPending = 1,
+ .EventType = WHvX64PendingEventExtInt,
+ .Vector = irq,
+ };
+ reg_count += 1;
+ }
+ }
/* Sync the TPR to the CR8 if was modified during the intercept */
tpr = cpu_get_apic_tpr(x86_cpu->apic_state);
@@ -854,14 +875,17 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
/* Update the state of the interrupt delivery notification */
if (!vcpu->window_registered &&
cpu->interrupt_request & CPU_INTERRUPT_HARD) {
- reg_values[reg_count].DeliverabilityNotifications.InterruptNotification
- = 1;
+ reg_values[reg_count].DeliverabilityNotifications =
+ (WHV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER) {
+ .InterruptNotification = 1
+ };
vcpu->window_registered = 1;
reg_names[reg_count] = WHvX64RegisterDeliverabilityNotifications;
reg_count += 1;
}
qemu_mutex_unlock_iothread();
+ vcpu->ready_for_pic_interrupt = false;
if (reg_count) {
hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
@@ -948,7 +972,7 @@ static int whpx_vcpu_run(CPUState *cpu)
int ret;
whpx_vcpu_process_async_events(cpu);
- if (cpu->halted) {
+ if (cpu->halted && !whpx_apic_in_platform()) {
cpu->exception_index = EXCP_HLT;
qatomic_set(&cpu->exit_request, false);
return 0;
@@ -992,14 +1016,114 @@ static int whpx_vcpu_run(CPUState *cpu)
break;
case WHvRunVpExitReasonX64InterruptWindow:
+ vcpu->ready_for_pic_interrupt = 1;
vcpu->window_registered = 0;
ret = 0;
break;
+ case WHvRunVpExitReasonX64ApicEoi:
+ assert(whpx_apic_in_platform());
+ ioapic_eoi_broadcast(vcpu->exit_ctx.ApicEoi.InterruptVector);
+ break;
+
case WHvRunVpExitReasonX64Halt:
ret = whpx_handle_halt(cpu);
break;
+ case WHvRunVpExitReasonX64ApicInitSipiTrap: {
+ WHV_INTERRUPT_CONTROL ipi = {0};
+ uint64_t icr = vcpu->exit_ctx.ApicInitSipi.ApicIcr;
+ uint32_t delivery_mode =
+ (icr & APIC_ICR_DELIV_MOD) >> APIC_ICR_DELIV_MOD_SHIFT;
+ int dest_shorthand =
+ (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
+ bool broadcast = false;
+ bool include_self = false;
+ uint32_t i;
+
+ /* We only registered for INIT and SIPI exits. */
+ if ((delivery_mode != APIC_DM_INIT) &&
+ (delivery_mode != APIC_DM_SIPI)) {
+ error_report(
+ "WHPX: Unexpected APIC exit that is not a INIT or SIPI");
+ break;
+ }
+
+ if (delivery_mode == APIC_DM_INIT) {
+ ipi.Type = WHvX64InterruptTypeInit;
+ } else {
+ ipi.Type = WHvX64InterruptTypeSipi;
+ }
+
+ ipi.DestinationMode =
+ ((icr & APIC_ICR_DEST_MOD) >> APIC_ICR_DEST_MOD_SHIFT) ?
+ WHvX64InterruptDestinationModeLogical :
+ WHvX64InterruptDestinationModePhysical;
+
+ ipi.TriggerMode =
+ ((icr & APIC_ICR_TRIGGER_MOD) >> APIC_ICR_TRIGGER_MOD_SHIFT) ?
+ WHvX64InterruptTriggerModeLevel :
+ WHvX64InterruptTriggerModeEdge;
+
+ ipi.Vector = icr & APIC_VECTOR_MASK;
+ switch (dest_shorthand) {
+ /* no shorthand. Bits 56-63 contain the destination. */
+ case 0:
+ ipi.Destination = (icr >> 56) & APIC_VECTOR_MASK;
+ hr = whp_dispatch.WHvRequestInterrupt(whpx->partition,
+ &ipi, sizeof(ipi));
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to request interrupt hr=%08lx",
+ hr);
+ }
+
+ break;
+
+ /* self */
+ case 1:
+ include_self = true;
+ break;
+
+ /* broadcast, including self */
+ case 2:
+ broadcast = true;
+ include_self = true;
+ break;
+
+ /* broadcast, excluding self */
+ case 3:
+ broadcast = true;
+ break;
+ }
+
+ if (!broadcast && !include_self) {
+ break;
+ }
+
+ for (i = 0; i <= max_vcpu_index; i++) {
+ if (i == cpu->cpu_index && !include_self) {
+ continue;
+ }
+
+ /*
+ * Assuming that APIC Ids are identity mapped since
+ * WHvX64RegisterApicId & WHvX64RegisterInitialApicId registers
+ * are not handled yet and the hypervisor doesn't allow the
+ * guest to modify the APIC ID.
+ */
+ ipi.Destination = i;
+ hr = whp_dispatch.WHvRequestInterrupt(whpx->partition,
+ &ipi, sizeof(ipi));
+ if (FAILED(hr)) {
+ error_report(
+ "WHPX: Failed to request SIPI for %d, hr=%08lx",
+ i, hr);
+ }
+ }
+
+ break;
+ }
+
case WHvRunVpExitReasonCanceled:
cpu->exception_index = EXCP_INTERRUPT;
ret = 1;
@@ -1314,6 +1438,7 @@ int whpx_init_vcpu(CPUState *cpu)
vcpu->interruptable = true;
cpu->vcpu_dirty = true;
cpu->hax_vcpu = (struct hax_vcpu_state *)vcpu;
+ max_vcpu_index = max(max_vcpu_index, cpu->cpu_index);
qemu_add_vm_change_state_handler(whpx_cpu_update_state, cpu->env_ptr);
return 0;
@@ -1549,6 +1674,43 @@ error:
return false;
}
+static void whpx_set_kernel_irqchip(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ struct whpx_state *whpx = &whpx_global;
+ OnOffSplit mode;
+
+ if (!visit_type_OnOffSplit(v, name, &mode, errp)) {
+ return;
+ }
+
+ switch (mode) {
+ case ON_OFF_SPLIT_ON:
+ whpx->kernel_irqchip_allowed = true;
+ whpx->kernel_irqchip_required = true;
+ break;
+
+ case ON_OFF_SPLIT_OFF:
+ whpx->kernel_irqchip_allowed = false;
+ whpx->kernel_irqchip_required = false;
+ break;
+
+ case ON_OFF_SPLIT_SPLIT:
+ error_setg(errp, "WHPX: split irqchip currently not supported");
+ error_append_hint(errp,
+ "Try without kernel-irqchip or with kernel-irqchip=on|off");
+ break;
+
+ default:
+ /*
+ * The value was checked in visit_type_OnOffSplit() above. If
+ * we get here, then something is wrong in QEMU.
+ */
+ abort();
+ }
+}
+
/*
* Partition support
*/
@@ -1562,6 +1724,7 @@ static int whpx_accel_init(MachineState *ms)
UINT32 whpx_cap_size;
WHV_PARTITION_PROPERTY prop;
UINT32 cpuidExitList[] = {1, 0x80000001};
+ WHV_CAPABILITY_FEATURES features = {0};
whpx = &whpx_global;
@@ -1570,7 +1733,6 @@ static int whpx_accel_init(MachineState *ms)
goto error;
}
- memset(whpx, 0, sizeof(struct whpx_state));
whpx->mem_quota = ms->ram_size;
hr = whp_dispatch.WHvGetCapability(
@@ -1582,6 +1744,14 @@ static int whpx_accel_init(MachineState *ms)
goto error;
}
+ hr = whp_dispatch.WHvGetCapability(
+ WHvCapabilityCodeFeatures, &features, sizeof(features), NULL);
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to query capabilities, hr=%08lx", hr);
+ ret = -EINVAL;
+ goto error;
+ }
+
hr = whp_dispatch.WHvCreatePartition(&whpx->partition);
if (FAILED(hr)) {
error_report("WHPX: Failed to create partition, hr=%08lx", hr);
@@ -1604,18 +1774,55 @@ static int whpx_accel_init(MachineState *ms)
goto error;
}
+ /*
+ * Error out if WHP doesn't support apic emulation and user is requiring
+ * it.
+ */
+ if (whpx->kernel_irqchip_required && (!features.LocalApicEmulation ||
+ !whp_dispatch.WHvSetVirtualProcessorInterruptControllerState2)) {
+ error_report("WHPX: kernel irqchip requested, but unavailable. "
+ "Try without kernel-irqchip or with kernel-irqchip=off");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (whpx->kernel_irqchip_allowed && features.LocalApicEmulation &&
+ whp_dispatch.WHvSetVirtualProcessorInterruptControllerState2) {
+ WHV_X64_LOCAL_APIC_EMULATION_MODE mode =
+ WHvX64LocalApicEmulationModeXApic;
+ printf("WHPX: setting APIC emulation mode in the hypervisor\n");
+ hr = whp_dispatch.WHvSetPartitionProperty(
+ whpx->partition,
+ WHvPartitionPropertyCodeLocalApicEmulationMode,
+ &mode,
+ sizeof(mode));
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to enable kernel irqchip hr=%08lx", hr);
+ if (whpx->kernel_irqchip_required) {
+ error_report("WHPX: kernel irqchip requested, but unavailable");
+ ret = -EINVAL;
+ goto error;
+ }
+ } else {
+ whpx->apic_in_platform = true;
+ }
+ }
+
+ /* Register for MSR and CPUID exits */
memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
prop.ExtendedVmExits.X64MsrExit = 1;
prop.ExtendedVmExits.X64CpuidExit = 1;
- hr = whp_dispatch.WHvSetPartitionProperty(
- whpx->partition,
- WHvPartitionPropertyCodeExtendedVmExits,
- &prop,
- sizeof(WHV_PARTITION_PROPERTY));
+ if (whpx_apic_in_platform()) {
+ prop.ExtendedVmExits.X64ApicInitSipiExitTrap = 1;
+ }
+ hr = whp_dispatch.WHvSetPartitionProperty(
+ whpx->partition,
+ WHvPartitionPropertyCodeExtendedVmExits,
+ &prop,
+ sizeof(WHV_PARTITION_PROPERTY));
if (FAILED(hr)) {
- error_report("WHPX: Failed to enable partition extended X64MsrExit and"
- " X64CpuidExit hr=%08lx", hr);
+ error_report("WHPX: Failed to enable MSR & CPUIDexit, hr=%08lx", hr);
ret = -EINVAL;
goto error;
}
@@ -1668,11 +1875,27 @@ static void whpx_accel_class_init(ObjectClass *oc, void *data)
ac->name = "WHPX";
ac->init_machine = whpx_accel_init;
ac->allowed = &whpx_allowed;
+
+ object_class_property_add(oc, "kernel-irqchip", "on|off|split",
+ NULL, whpx_set_kernel_irqchip,
+ NULL, NULL);
+ object_class_property_set_description(oc, "kernel-irqchip",
+ "Configure WHPX in-kernel irqchip");
+}
+
+static void whpx_accel_instance_init(Object *obj)
+{
+ struct whpx_state *whpx = &whpx_global;
+
+ memset(whpx, 0, sizeof(struct whpx_state));
+ /* Turn on kernel-irqchip, by default */
+ whpx->kernel_irqchip_allowed = true;
}
static const TypeInfo whpx_accel_type = {
.name = ACCEL_CLASS_NAME("whpx"),
.parent = TYPE_ACCEL,
+ .instance_init = whpx_accel_instance_init,
.class_init = whpx_accel_class_init,
};
diff --git a/target/i386/whpx-apic.c b/target/i386/whpx-apic.c
new file mode 100644
index 0000000000..b127a3cb8a
--- /dev/null
+++ b/target/i386/whpx-apic.c
@@ -0,0 +1,274 @@
+/*
+ * WHPX platform APIC support
+ *
+ * Copyright (c) 2011 Siemens AG
+ *
+ * Authors:
+ * Jan Kiszka <jan.kiszka@siemens.com>
+ * John Starks <jostarks@microsoft.com>
+ *
+ * This work is licensed under the terms of the GNU GPL version 2.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "hw/i386/apic_internal.h"
+#include "hw/i386/apic-msidef.h"
+#include "hw/pci/msi.h"
+#include "sysemu/hw_accel.h"
+#include "sysemu/whpx.h"
+#include "whp-dispatch.h"
+
+static void whpx_put_apic_state(APICCommonState *s,
+ struct whpx_lapic_state *kapic)
+{
+ int i;
+
+ memset(kapic, 0, sizeof(*kapic));
+ kapic->fields[0x2].data = s->id << 24;
+ kapic->fields[0x3].data = s->version | ((APIC_LVT_NB - 1) << 16);
+ kapic->fields[0x8].data = s->tpr;
+ kapic->fields[0xd].data = s->log_dest << 24;
+ kapic->fields[0xe].data = s->dest_mode << 28 | 0x0fffffff;
+ kapic->fields[0xf].data = s->spurious_vec;
+ for (i = 0; i < 8; i++) {
+ kapic->fields[0x10 + i].data = s->isr[i];
+ kapic->fields[0x18 + i].data = s->tmr[i];
+ kapic->fields[0x20 + i].data = s->irr[i];
+ }
+
+ kapic->fields[0x28].data = s->esr;
+ kapic->fields[0x30].data = s->icr[0];
+ kapic->fields[0x31].data = s->icr[1];
+ for (i = 0; i < APIC_LVT_NB; i++) {
+ kapic->fields[0x32 + i].data = s->lvt[i];
+ }
+
+ kapic->fields[0x38].data = s->initial_count;
+ kapic->fields[0x3e].data = s->divide_conf;
+}
+
+static void whpx_get_apic_state(APICCommonState *s,
+ struct whpx_lapic_state *kapic)
+{
+ int i, v;
+
+ s->id = kapic->fields[0x2].data >> 24;
+ s->tpr = kapic->fields[0x8].data;
+ s->arb_id = kapic->fields[0x9].data;
+ s->log_dest = kapic->fields[0xd].data >> 24;
+ s->dest_mode = kapic->fields[0xe].data >> 28;
+ s->spurious_vec = kapic->fields[0xf].data;
+ for (i = 0; i < 8; i++) {
+ s->isr[i] = kapic->fields[0x10 + i].data;
+ s->tmr[i] = kapic->fields[0x18 + i].data;
+ s->irr[i] = kapic->fields[0x20 + i].data;
+ }
+
+ s->esr = kapic->fields[0x28].data;
+ s->icr[0] = kapic->fields[0x30].data;
+ s->icr[1] = kapic->fields[0x31].data;
+ for (i = 0; i < APIC_LVT_NB; i++) {
+ s->lvt[i] = kapic->fields[0x32 + i].data;
+ }
+
+ s->initial_count = kapic->fields[0x38].data;
+ s->divide_conf = kapic->fields[0x3e].data;
+
+ v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
+ s->count_shift = (v + 1) & 7;
+
+ s->initial_count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ apic_next_timer(s, s->initial_count_load_time);
+}
+
+static void whpx_apic_set_base(APICCommonState *s, uint64_t val)
+{
+ s->apicbase = val;
+}
+
+static void whpx_put_apic_base(CPUState *cpu, uint64_t val)
+{
+ HRESULT hr;
+ WHV_REGISTER_VALUE reg_value = {.Reg64 = val};
+ WHV_REGISTER_NAME reg_name = WHvX64RegisterApicBase;
+
+ hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
+ whpx_global.partition,
+ cpu->cpu_index,
+ &reg_name, 1,
+ &reg_value);
+
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to set MSR APIC base, hr=%08lx", hr);
+ }
+}
+
+static void whpx_apic_set_tpr(APICCommonState *s, uint8_t val)
+{
+ s->tpr = val;
+}
+
+static uint8_t whpx_apic_get_tpr(APICCommonState *s)
+{
+ return s->tpr;
+}
+
+static void whpx_apic_vapic_base_update(APICCommonState *s)
+{
+ /* not implemented yet */
+}
+
+static void whpx_apic_put(CPUState *cs, run_on_cpu_data data)
+{
+ APICCommonState *s = data.host_ptr;
+ struct whpx_lapic_state kapic;
+ HRESULT hr;
+
+ whpx_put_apic_base(CPU(s->cpu), s->apicbase);
+ whpx_put_apic_state(s, &kapic);
+
+ hr = whp_dispatch.WHvSetVirtualProcessorInterruptControllerState2(
+ whpx_global.partition,
+ cs->cpu_index,
+ &kapic,
+ sizeof(kapic));
+ if (FAILED(hr)) {
+ fprintf(stderr,
+ "WHvSetVirtualProcessorInterruptControllerState failed: %08lx\n",
+ hr);
+
+ abort();
+ }
+}
+
+void whpx_apic_get(DeviceState *dev)
+{
+ APICCommonState *s = APIC_COMMON(dev);
+ CPUState *cpu = CPU(s->cpu);
+ struct whpx_lapic_state kapic;
+
+ HRESULT hr = whp_dispatch.WHvGetVirtualProcessorInterruptControllerState2(
+ whpx_global.partition,
+ cpu->cpu_index,
+ &kapic,
+ sizeof(kapic),
+ NULL);
+ if (FAILED(hr)) {
+ fprintf(stderr,
+ "WHvSetVirtualProcessorInterruptControllerState failed: %08lx\n",
+ hr);
+
+ abort();
+ }
+
+ whpx_get_apic_state(s, &kapic);
+}
+
+static void whpx_apic_post_load(APICCommonState *s)
+{
+ run_on_cpu(CPU(s->cpu), whpx_apic_put, RUN_ON_CPU_HOST_PTR(s));
+}
+
+static void whpx_apic_external_nmi(APICCommonState *s)
+{
+}
+
+static void whpx_send_msi(MSIMessage *msg)
+{
+ uint64_t addr = msg->address;
+ uint32_t data = msg->data;
+ uint8_t dest = (addr & MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
+ uint8_t vector = (data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT;
+ uint8_t dest_mode = (addr >> MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
+ uint8_t trigger_mode = (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;
+ uint8_t delivery = (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
+
+ WHV_INTERRUPT_CONTROL interrupt = {
+ /* Values correspond to delivery modes */
+ .Type = delivery,
+ .DestinationMode = dest_mode ?
+ WHvX64InterruptDestinationModeLogical :
+ WHvX64InterruptDestinationModePhysical,
+
+ .TriggerMode = trigger_mode ?
+ WHvX64InterruptTriggerModeLevel : WHvX64InterruptTriggerModeEdge,
+ .Reserved = 0,
+ .Vector = vector,
+ .Destination = dest,
+ };
+ HRESULT hr = whp_dispatch.WHvRequestInterrupt(whpx_global.partition,
+ &interrupt, sizeof(interrupt));
+ if (FAILED(hr)) {
+ fprintf(stderr, "whpx: injection failed, MSI (%llx, %x) delivery: %d, "
+ "dest_mode: %d, trigger mode: %d, vector: %d, lost (%08lx)\n",
+ addr, data, delivery, dest_mode, trigger_mode, vector, hr);
+ }
+}
+
+static uint64_t whpx_apic_mem_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ return ~(uint64_t)0;
+}
+
+static void whpx_apic_mem_write(void *opaque, hwaddr addr,
+ uint64_t data, unsigned size)
+{
+ MSIMessage msg = { .address = addr, .data = data };
+ whpx_send_msi(&msg);
+}
+
+static const MemoryRegionOps whpx_apic_io_ops = {
+ .read = whpx_apic_mem_read,
+ .write = whpx_apic_mem_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void whpx_apic_reset(APICCommonState *s)
+{
+ /* Not used by WHPX. */
+ s->wait_for_sipi = 0;
+
+ run_on_cpu(CPU(s->cpu), whpx_apic_put, RUN_ON_CPU_HOST_PTR(s));
+}
+
+static void whpx_apic_realize(DeviceState *dev, Error **errp)
+{
+ APICCommonState *s = APIC_COMMON(dev);
+
+ memory_region_init_io(&s->io_memory, OBJECT(s), &whpx_apic_io_ops, s,
+ "whpx-apic-msi", APIC_SPACE_SIZE);
+
+ msi_nonbroken = true;
+}
+
+static void whpx_apic_class_init(ObjectClass *klass, void *data)
+{
+ APICCommonClass *k = APIC_COMMON_CLASS(klass);
+
+ k->realize = whpx_apic_realize;
+ k->reset = whpx_apic_reset;
+ k->set_base = whpx_apic_set_base;
+ k->set_tpr = whpx_apic_set_tpr;
+ k->get_tpr = whpx_apic_get_tpr;
+ k->post_load = whpx_apic_post_load;
+ k->vapic_base_update = whpx_apic_vapic_base_update;
+ k->external_nmi = whpx_apic_external_nmi;
+ k->send_msi = whpx_send_msi;
+}
+
+static const TypeInfo whpx_apic_info = {
+ .name = "whpx-apic",
+ .parent = TYPE_APIC_COMMON,
+ .instance_size = sizeof(APICCommonState),
+ .class_init = whpx_apic_class_init,
+};
+
+static void whpx_apic_register_types(void)
+{
+ type_register_static(&whpx_apic_info);
+}
+
+type_init(whpx_apic_register_types)
diff --git a/target/m68k/m68k-semi.c b/target/m68k/m68k-semi.c
index 8e5fbfc8fa..27600e0cc0 100644
--- a/target/m68k/m68k-semi.c
+++ b/target/m68k/m68k-semi.c
@@ -26,6 +26,7 @@
#else
#include "exec/gdbstub.h"
#include "exec/softmmu-semi.h"
+#include "hw/boards.h"
#endif
#include "qemu/log.h"
@@ -455,8 +456,8 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
* FIXME: This is wrong for boards where RAM does not start at
* address zero.
*/
- env->dregs[1] = ram_size;
- env->aregs[7] = ram_size;
+ env->dregs[1] = current_machine->ram_size;
+ env->aregs[7] = current_machine->ram_size;
#endif
return;
default:
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 0adfbbda27..9cf66d3690 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -156,9 +156,10 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
!address_space_access_valid(&address_space_memory, raddr,
TARGET_PAGE_SIZE, access_type,
MEMTXATTRS_UNSPECIFIED)) {
+ MachineState *ms = MACHINE(qdev_get_machine());
qemu_log_mask(CPU_LOG_MMU,
"%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n",
- __func__, (uint64_t)raddr, (uint64_t)ram_size);
+ __func__, (uint64_t)raddr, (uint64_t)ms->ram_size);
excp = PGM_ADDRESSING;
tec = 0; /* unused */
}
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index bd25eed3e8..0108611cc9 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -31,6 +31,7 @@
#if !defined(CONFIG_USER_ONLY)
#include "hw/s390x/storage-keys.h"
+#include "hw/boards.h"
#endif
/*****************************************************************************/
@@ -2075,12 +2076,13 @@ uint32_t HELPER(tprot)(CPUS390XState *env, uint64_t a1, uint64_t a2)
/* insert storage key extended */
uint64_t HELPER(iske)(CPUS390XState *env, uint64_t r2)
{
+ MachineState *ms = MACHINE(qdev_get_machine());
static S390SKeysState *ss;
static S390SKeysClass *skeyclass;
uint64_t addr = wrap_address(env, r2);
uint8_t key;
- if (addr > ram_size) {
+ if (addr > ms->ram_size) {
return 0;
}
@@ -2098,12 +2100,13 @@ uint64_t HELPER(iske)(CPUS390XState *env, uint64_t r2)
/* set storage key extended */
void HELPER(sske)(CPUS390XState *env, uint64_t r1, uint64_t r2)
{
+ MachineState *ms = MACHINE(qdev_get_machine());
static S390SKeysState *ss;
static S390SKeysClass *skeyclass;
uint64_t addr = wrap_address(env, r2);
uint8_t key;
- if (addr > ram_size) {
+ if (addr > ms->ram_size) {
return;
}
@@ -2124,11 +2127,12 @@ void HELPER(sske)(CPUS390XState *env, uint64_t r1, uint64_t r2)
/* reset reference bit extended */
uint32_t HELPER(rrbe)(CPUS390XState *env, uint64_t r2)
{
+ MachineState *ms = MACHINE(qdev_get_machine());
static S390SKeysState *ss;
static S390SKeysClass *skeyclass;
uint8_t re, key;
- if (r2 > ram_size) {
+ if (r2 > ms->ram_size) {
return 0;
}
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index 7d9f3059cd..d492b23a17 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -27,6 +27,7 @@
#include "trace.h"
#include "hw/hw.h"
#include "hw/s390x/storage-keys.h"
+#include "hw/boards.h"
/* Fetch/store bits in the translation exception code: */
#define FS_READ 0x800
@@ -292,10 +293,11 @@ static void mmu_handle_skey(target_ulong addr, int rw, int *flags)
{
static S390SKeysClass *skeyclass;
static S390SKeysState *ss;
+ MachineState *ms = MACHINE(qdev_get_machine());
uint8_t key;
int rc;
- if (unlikely(addr >= ram_size)) {
+ if (unlikely(addr >= ms->ram_size)) {
return;
}
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index f2f79dd6a4..4e026f90d0 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -674,14 +674,14 @@ static void test_acpi_one(const char *params, test_data *data)
if (data->cd) {
args = g_strdup_printf("-machine %s %s -accel tcg "
"-nodefaults -nographic "
- "-drive if=pflash,format=raw,file=%s,readonly "
+ "-drive if=pflash,format=raw,file=%s,readonly=on "
"-drive if=pflash,format=raw,file=%s,snapshot=on -cdrom %s %s",
data->machine, data->tcg_only ? "" : "-accel kvm",
data->uefi_fl1, data->uefi_fl2, data->cd, params ? params : "");
} else {
args = g_strdup_printf("-machine %s %s -accel tcg "
"-nodefaults -nographic "
- "-drive if=pflash,format=raw,file=%s,readonly "
+ "-drive if=pflash,format=raw,file=%s,readonly=on "
"-drive if=pflash,format=raw,file=%s,snapshot=on %s",
data->machine, data->tcg_only ? "" : "-accel kvm",
data->uefi_fl1, data->uefi_fl2, params ? params : "");
diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c
index 7be7226bc0..238866a037 100644
--- a/tests/qtest/fuzz/fuzz.c
+++ b/tests/qtest/fuzz/fuzz.c
@@ -15,6 +15,7 @@
#include <wordexp.h>
+#include "qemu/datadir.h"
#include "sysemu/qtest.h"
#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"
diff --git a/tests/qtest/pflash-cfi02-test.c b/tests/qtest/pflash-cfi02-test.c
index afb702b565..60db81a3a2 100644
--- a/tests/qtest/pflash-cfi02-test.c
+++ b/tests/qtest/pflash-cfi02-test.c
@@ -261,7 +261,7 @@ static void test_geometry(const void *opaque)
const FlashConfig *config = opaque;
QTestState *qtest;
qtest = qtest_initf("-M musicpal"
- " -drive if=pflash,file=%s,format=raw,copy-on-read"
+ " -drive if=pflash,file=%s,format=raw,copy-on-read=on"
/* Device geometry properties. */
" -global driver=cfi.pflash02,"
"property=num-blocks0,value=%d"
@@ -581,7 +581,7 @@ static void test_cfi_in_autoselect(const void *opaque)
const FlashConfig *config = opaque;
QTestState *qtest;
qtest = qtest_initf("-M musicpal"
- " -drive if=pflash,file=%s,format=raw,copy-on-read",
+ " -drive if=pflash,file=%s,format=raw,copy-on-read=on",
image_path);
FlashConfig explicit_config = expand_config_defaults(config);
explicit_config.qtest = qtest;
diff --git a/tests/qtest/test-filter-redirector.c b/tests/qtest/test-filter-redirector.c
index 829db8c2ea..4269b2cdd9 100644
--- a/tests/qtest/test-filter-redirector.c
+++ b/tests/qtest/test-filter-redirector.c
@@ -95,8 +95,8 @@ static void test_redirector_tx(void)
qts = qtest_initf(
"-netdev socket,id=qtest-bn0,fd=%d "
"-device %s,netdev=qtest-bn0,id=qtest-e0 "
- "-chardev socket,id=redirector0,path=%s,server,nowait "
- "-chardev socket,id=redirector1,path=%s,server,nowait "
+ "-chardev socket,id=redirector0,path=%s,server=on,wait=off "
+ "-chardev socket,id=redirector1,path=%s,server=on,wait=off "
"-chardev socket,id=redirector2,path=%s "
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
"queue=tx,outdev=redirector0 "
@@ -165,8 +165,8 @@ static void test_redirector_rx(void)
qts = qtest_initf(
"-netdev socket,id=qtest-bn0,fd=%d "
"-device %s,netdev=qtest-bn0,id=qtest-e0 "
- "-chardev socket,id=redirector0,path=%s,server,nowait "
- "-chardev socket,id=redirector1,path=%s,server,nowait "
+ "-chardev socket,id=redirector0,path=%s,server=on,wait=off "
+ "-chardev socket,id=redirector1,path=%s,server=on,wait=off "
"-chardev socket,id=redirector2,path=%s "
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
"queue=rx,indev=redirector0 "
diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c
index 3df5322614..1a5f5313ff 100644
--- a/tests/qtest/vhost-user-test.c
+++ b/tests/qtest/vhost-user-test.c
@@ -537,7 +537,7 @@ static void test_server_create_chr(TestServer *server, const gchar *opt)
static void test_server_listen(TestServer *server)
{
- test_server_create_chr(server, ",server,nowait");
+ test_server_create_chr(server, ",server=on,wait=off");
}
static void test_server_free(TestServer *server)
@@ -846,7 +846,7 @@ static void *vhost_user_test_setup_reconnect(GString *cmd_line, void *arg)
g_thread_new("connect", connect_thread, s);
append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
- s->vu_ops->append_opts(s, cmd_line, ",server");
+ s->vu_ops->append_opts(s, cmd_line, ",server=on");
g_test_queue_destroy(vhost_user_test_cleanup, s);
@@ -883,7 +883,7 @@ static void *vhost_user_test_setup_connect_fail(GString *cmd_line, void *arg)
g_thread_new("connect", connect_thread, s);
append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
- s->vu_ops->append_opts(s, cmd_line, ",server");
+ s->vu_ops->append_opts(s, cmd_line, ",server=on");
g_test_queue_destroy(vhost_user_test_cleanup, s);
@@ -898,7 +898,7 @@ static void *vhost_user_test_setup_flags_mismatch(GString *cmd_line, void *arg)
g_thread_new("connect", connect_thread, s);
append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
- s->vu_ops->append_opts(s, cmd_line, ",server");
+ s->vu_ops->append_opts(s, cmd_line, ",server=on");
g_test_queue_destroy(vhost_user_test_cleanup, s);
diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target
index a66232a67d..ad187cb2c9 100644
--- a/tests/tcg/i386/Makefile.target
+++ b/tests/tcg/i386/Makefile.target
@@ -18,6 +18,9 @@ test-i386-pcmpistri: CFLAGS += -msse4.2
run-test-i386-pcmpistri: QEMU_OPTS += -cpu max
run-plugin-test-i386-pcmpistri-%: QEMU_OPTS += -cpu max
+run-test-i386-bmi2: QEMU_OPTS += -cpu max
+run-plugin-test-i386-bmi2-%: QEMU_OPTS += -cpu max
+
#
# hello-i386 is a barebones app
#
diff --git a/tests/tcg/i386/test-i386-bmi2.c b/tests/tcg/i386/test-i386-bmi2.c
new file mode 100644
index 0000000000..935a4d2a73
--- /dev/null
+++ b/tests/tcg/i386/test-i386-bmi2.c
@@ -0,0 +1,42 @@
+/* See if various BMI2 instructions give expected results */
+#include <assert.h>
+#include <stdint.h>
+
+int main(int argc, char *argv[]) {
+ uint64_t ehlo = 0x202020204f4c4845ull;
+ uint64_t mask = 0xa080800302020001ull;
+ uint32_t result32;
+
+#ifdef __x86_64
+ uint64_t result64;
+
+ /* 64 bits */
+ asm volatile ("pextq %2, %1, %0" : "=r"(result64) : "r"(ehlo), "m"(mask));
+ assert(result64 == 133);
+
+ asm volatile ("pdepq %2, %1, %0" : "=r"(result64) : "r"(result64), "m"(mask));
+ assert(result64 == (ehlo & mask));
+
+ asm volatile ("pextq %2, %1, %0" : "=r"(result64) : "r"(-1ull), "m"(mask));
+ assert(result64 == 511); /* mask has 9 bits set */
+
+ asm volatile ("pdepq %2, %1, %0" : "=r"(result64) : "r"(-1ull), "m"(mask));
+ assert(result64 == mask);
+#endif
+
+ /* 32 bits */
+ asm volatile ("pextl %2, %k1, %k0" : "=r"(result32) : "r"((uint32_t) ehlo), "m"(mask));
+ assert(result32 == 5);
+
+ asm volatile ("pdepl %2, %k1, %k0" : "=r"(result32) : "r"(result32), "m"(mask));
+ assert(result32 == (uint32_t)(ehlo & mask));
+
+ asm volatile ("pextl %2, %k1, %k0" : "=r"(result32) : "r"(-1ull), "m"(mask));
+ assert(result32 == 7); /* mask has 3 bits set */
+
+ asm volatile ("pdepl %2, %k1, %k0" : "=r"(result32) : "r"(-1ull), "m"(mask));
+ assert(result32 == (uint32_t)mask);
+
+ return 0;
+}
+
diff --git a/tests/test-char.c b/tests/test-char.c
index 9196e566e9..953e0d1c1f 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -413,7 +413,7 @@ static void char_websock_test(void)
CharBackend client_be;
Chardev *chr_client;
Chardev *chr = qemu_chr_new("server",
- "websocket:127.0.0.1:0,server,nowait", NULL);
+ "websocket:127.0.0.1:0,server=on,wait=off", NULL);
const char handshake[] = "GET / HTTP/1.1\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
@@ -696,7 +696,7 @@ char_socket_addr_to_opt_str(SocketAddress *addr, bool fd_pass,
fd = ioc->fd;
ioc->fd = -1;
optstr = g_strdup_printf("socket,id=cdev0,fd=%d%s",
- fd, is_listen ? ",server,nowait" : "");
+ fd, is_listen ? ",server=on,wait=off" : "");
object_unref(OBJECT(ioc));
return optstr;
} else {
@@ -706,13 +706,13 @@ char_socket_addr_to_opt_str(SocketAddress *addr, bool fd_pass,
addr->u.inet.host,
addr->u.inet.port,
reconnect ? reconnect : "",
- is_listen ? ",server,nowait" : "");
+ is_listen ? ",server=on,wait=off" : "");
case SOCKET_ADDRESS_TYPE_UNIX:
return g_strdup_printf("socket,id=cdev0,path=%s%s%s",
addr->u.q_unix.path,
reconnect ? reconnect : "",
- is_listen ? ",server,nowait" : "");
+ is_listen ? ",server=on,wait=off" : "");
default:
g_assert_not_reached();
diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c
index 297ffe79dd..2aab831d10 100644
--- a/tests/test-qemu-opts.c
+++ b/tests/test-qemu-opts.c
@@ -84,11 +84,25 @@ static QemuOptsList opts_list_03 = {
},
};
+static QemuOptsList opts_list_04 = {
+ .name = "opts_list_04",
+ .head = QTAILQ_HEAD_INITIALIZER(opts_list_04.head),
+ .merge_lists = true,
+ .desc = {
+ {
+ .name = "str3",
+ .type = QEMU_OPT_STRING,
+ },
+ { /* end of list */ }
+ },
+};
+
static void register_opts(void)
{
qemu_add_opts(&opts_list_01);
qemu_add_opts(&opts_list_02);
qemu_add_opts(&opts_list_03);
+ qemu_add_opts(&opts_list_04);
}
static void test_find_unknown_opts(void)
@@ -402,17 +416,17 @@ static void test_qemu_opts_set(void)
QemuOpts *opts;
const char *opt;
- list = qemu_find_opts("opts_list_01");
+ list = qemu_find_opts("opts_list_04");
g_assert(list != NULL);
g_assert(QTAILQ_EMPTY(&list->head));
- g_assert_cmpstr(list->name, ==, "opts_list_01");
+ g_assert_cmpstr(list->name, ==, "opts_list_04");
/* should not find anything at this point */
opts = qemu_opts_find(list, NULL);
g_assert(opts == NULL);
/* implicitly create opts and set str3 value */
- qemu_opts_set(list, NULL, "str3", "value", &error_abort);
+ qemu_opts_set(list, "str3", "value", &error_abort);
g_assert(!QTAILQ_EMPTY(&list->head));
/* get the just created opts */
diff --git a/ui/keymaps.c b/ui/keymaps.c
index 4e5fca57a8..d4a647464b 100644
--- a/ui/keymaps.c
+++ b/ui/keymaps.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/datadir.h"
#include "keymaps.h"
#include "trace.h"
#include "qemu/ctype.h"
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 660f47b005..725e3d7e4b 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -313,39 +313,6 @@ void qemu_add_opts(QemuOptsList *list)
abort();
}
-int qemu_set_option(const char *str)
-{
- Error *local_err = NULL;
- char group[64], id[64], arg[64];
- QemuOptsList *list;
- QemuOpts *opts;
- int rc, offset;
-
- rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
- if (rc < 3 || str[offset] != '=') {
- error_report("can't parse: \"%s\"", str);
- return -1;
- }
-
- list = qemu_find_opts(group);
- if (list == NULL) {
- return -1;
- }
-
- opts = qemu_opts_find(list, id);
- if (!opts) {
- error_report("there is no %s \"%s\" defined",
- list->name, id);
- return -1;
- }
-
- if (!qemu_opt_set(opts, arg, str + offset + 1, &local_err)) {
- error_report_err(local_err);
- return -1;
- }
- return 0;
-}
-
struct ConfigWriteData {
QemuOptsList *list;
FILE *fp;
diff --git a/util/qemu-option.c b/util/qemu-option.c
index acefbc23fa..25792159ba 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -670,15 +670,12 @@ void qemu_opts_loc_restore(QemuOpts *opts)
loc_restore(&opts->loc);
}
-bool qemu_opts_set(QemuOptsList *list, const char *id,
- const char *name, const char *value, Error **errp)
+bool qemu_opts_set(QemuOptsList *list, const char *name, const char *value, Error **errp)
{
QemuOpts *opts;
- opts = qemu_opts_create(list, id, 1, errp);
- if (!opts) {
- return false;
- }
+ assert(list->merge_lists);
+ opts = qemu_opts_create(list, NULL, 0, &error_abort);
return qemu_opt_set(opts, name, value, errp);
}