aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-08-26 18:03:57 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-08-26 18:03:57 +0100
commitf214d8e0150766c31172e16ef4b17674f549d852 (patch)
treebf264f12784e006e52ee326149259ea4940b6ab9
parentc83fcfaf8a54d0d034bd0edf7bbb3b0d16669be9 (diff)
parentd2e6f370138a7f32bc28b20dcd55374b7a638f39 (diff)
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210826' into staging
target-arm queue: * hw/dma/xlnx-zdma, xlnx_csu_dma: Require 'dma' link property to be set * hw/arm/Kconfig: no need to enable ACPI_MEMORY_HOTPLUG/ACPI_NVDIMM explicitly * target/arm/cpu: Introduce sve_vq_supported bitmap * docs/specs: Convert ACPI spec docs to rST * arch_init: Clean up and refactoring * hw/core/loader: In gunzip(), check index is in range before use, not after * softmmu/physmem.c: Remove unneeded NULL check in qemu_ram_alloc_from_fd() * softmmu/physmem.c: Check return value from realpath() * Zero-initialize sockaddr_in structs * raspi: Use error_fatal for SoC realize errors, not error_abort * target/arm: Avoid assertion trying to use KVM and multiple ASes * target/arm: Implement HSTR.TTEE * target/arm: Implement HSTR.TJDBX * target/arm: Do hflags rebuild in cpsr_write() * hw/arm/xlnx-versal, xlnx-zynqmp: Add unimplemented APU mmio # gpg: Signature made Thu 26 Aug 2021 18:02:10 BST # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20210826: (37 commits) hw/arm/xlnx-zynqmp: Add unimplemented APU mmio hw/arm/xlnx-versal: Add unimplemented APU mmio target/arm: Do hflags rebuild in cpsr_write() target/arm: Implement HSTR.TJDBX target/arm: Implement HSTR.TTEE hw/arm/virt: Delete EL3 error checksnow provided in CPU realize target/arm: Avoid assertion trying to use KVM and multiple ASes raspi: Use error_fatal for SoC realize errors, not error_abort tests/tcg/multiarch/linux-test: Zero-initialize sockaddr structs tests/qtest/ipmi-bt-test: Zero-initialize sockaddr struct gdbstub: Zero-initialize sockaddr structs net: Zero sockaddr_in in parse_host_port() softmmu/physmem.c: Check return value from realpath() softmmu/physmem.c: Remove unneeded NULL check in qemu_ram_alloc_from_fd() hw/core/loader: In gunzip(), check index is in range before use, not after stubs: Remove unused arch_type.c stub arch_init.h: Don't include arch_init.h unnecessarily arch_init.h: Move QEMU_ARCH_VIRTIO_* to qdev-monitor.c arch_init.h: Add QEMU_ARCH_HEXAGON meson.build: Define QEMU_ARCH in config-target.h ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--MAINTAINERS5
-rw-r--r--blockdev.c1
-rw-r--r--docs/specs/acpi_cpu_hotplug.rst235
-rw-r--r--docs/specs/acpi_cpu_hotplug.txt160
-rw-r--r--docs/specs/acpi_mem_hotplug.rst128
-rw-r--r--docs/specs/acpi_mem_hotplug.txt94
-rw-r--r--docs/specs/acpi_nvdimm.rst228
-rw-r--r--docs/specs/acpi_nvdimm.txt188
-rw-r--r--docs/specs/acpi_pci_hotplug.rst (renamed from docs/specs/acpi_pci_hotplug.txt)37
-rw-r--r--docs/specs/index.rst4
-rw-r--r--gdbstub.c4
-rw-r--r--hw/arm/Kconfig2
-rw-r--r--hw/arm/raspi.c2
-rw-r--r--hw/arm/virt.c5
-rw-r--r--hw/arm/xlnx-versal.c4
-rw-r--r--hw/arm/xlnx-zynqmp.c86
-rw-r--r--hw/core/loader.c35
-rw-r--r--hw/dma/xlnx-zdma.c24
-rw-r--r--hw/dma/xlnx_csu_dma.c31
-rw-r--r--hw/i386/pc.c1
-rw-r--r--hw/i386/pc_piix.c1
-rw-r--r--hw/i386/pc_q35.c1
-rw-r--r--hw/mips/jazz.c1
-rw-r--r--hw/mips/malta.c1
-rw-r--r--hw/ppc/prep.c1
-rw-r--r--hw/riscv/sifive_e.c1
-rw-r--r--hw/riscv/sifive_u.c1
-rw-r--r--hw/riscv/spike.c1
-rw-r--r--hw/riscv/virt.c1
-rw-r--r--include/hw/arm/xlnx-versal.h2
-rw-r--r--include/hw/arm/xlnx-zynqmp.h7
-rw-r--r--include/hw/dma/xlnx-zdma.h2
-rw-r--r--include/hw/dma/xlnx_csu_dma.h2
-rw-r--r--include/sysemu/arch_init.h15
-rw-r--r--linux-user/arm/signal.c2
-rw-r--r--meson.build2
-rw-r--r--monitor/qmp-cmds.c3
-rw-r--r--net/net.c2
-rw-r--r--softmmu/arch_init.c66
-rw-r--r--softmmu/physmem.c5
-rw-r--r--softmmu/qdev-monitor.c9
-rw-r--r--softmmu/vl.c6
-rw-r--r--stubs/arch_type.c4
-rw-r--r--stubs/meson.build1
-rw-r--r--target/arm/cpu.c23
-rw-r--r--target/arm/cpu.h17
-rw-r--r--target/arm/cpu64.c118
-rw-r--r--target/arm/helper.c40
-rw-r--r--target/arm/helper.h2
-rw-r--r--target/arm/kvm64.c2
-rw-r--r--target/arm/op_helper.c16
-rw-r--r--target/arm/syndrome.h7
-rw-r--r--target/arm/translate.c12
-rw-r--r--target/ppc/cpu_init.c1
-rw-r--r--target/s390x/cpu-sysemu.c1
-rw-r--r--tests/qtest/ipmi-bt-test.c2
-rw-r--r--tests/tcg/multiarch/linux-test.c4
57 files changed, 949 insertions, 707 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 6b3697962c..dffcb651f4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1751,6 +1751,10 @@ F: qapi/acpi.json
F: tests/qtest/bios-tables-test*
F: tests/qtest/acpi-utils.[hc]
F: tests/data/acpi/
+F: docs/specs/acpi_cpu_hotplug.rst
+F: docs/specs/acpi_mem_hotplug.rst
+F: docs/specs/acpi_pci_hotplug.rst
+F: docs/specs/acpi_hw_reduced_hotplug.rst
ACPI/HEST/GHES
R: Dongjiu Geng <gengdongjiu1@gmail.com>
@@ -2057,6 +2061,7 @@ F: hw/acpi/nvdimm.c
F: hw/mem/nvdimm.c
F: include/hw/mem/nvdimm.h
F: docs/nvdimm.txt
+F: docs/specs/acpi_nvdimm.rst
e1000x
M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
diff --git a/blockdev.c b/blockdev.c
index 3d8ac368a1..e79c5f3b5e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -56,7 +56,6 @@
#include "sysemu/iothread.h"
#include "block/block_int.h"
#include "block/trace.h"
-#include "sysemu/arch_init.h"
#include "sysemu/runstate.h"
#include "sysemu/replay.h"
#include "qemu/cutils.h"
diff --git a/docs/specs/acpi_cpu_hotplug.rst b/docs/specs/acpi_cpu_hotplug.rst
new file mode 100644
index 0000000000..351057c967
--- /dev/null
+++ b/docs/specs/acpi_cpu_hotplug.rst
@@ -0,0 +1,235 @@
+QEMU<->ACPI BIOS CPU hotplug interface
+======================================
+
+QEMU supports CPU hotplug via ACPI. This document
+describes the interface between QEMU and the ACPI BIOS.
+
+ACPI BIOS GPE.2 handler is dedicated for notifying OS about CPU hot-add
+and hot-remove events.
+
+
+Legacy ACPI CPU hotplug interface registers
+-------------------------------------------
+
+CPU present bitmap for:
+
+- ICH9-LPC (IO port 0x0cd8-0xcf7, 1-byte access)
+- PIIX-PM (IO port 0xaf00-0xaf1f, 1-byte access)
+- One bit per CPU. Bit position reflects corresponding CPU APIC ID. Read-only.
+- The first DWORD in bitmap is used in write mode to switch from legacy
+ to modern CPU hotplug interface, write 0 into it to do switch.
+
+QEMU sets corresponding CPU bit on hot-add event and issues SCI
+with GPE.2 event set. CPU present map is read by ACPI BIOS GPE.2 handler
+to notify OS about CPU hot-add events. CPU hot-remove isn't supported.
+
+
+Modern ACPI CPU hotplug interface registers
+-------------------------------------------
+
+Register block base address:
+
+- ICH9-LPC IO port 0x0cd8
+- PIIX-PM IO port 0xaf00
+
+Register block size:
+
+- ACPI_CPU_HOTPLUG_REG_LEN = 12
+
+All accesses to registers described below, imply little-endian byte order.
+
+Reserved registers behavior:
+
+- write accesses are ignored
+- read accesses return all bits set to 0.
+
+The last stored value in 'CPU selector' must refer to a possible CPU, otherwise
+
+- reads from any register return 0
+- writes to any other register are ignored until valid value is stored into it
+
+On QEMU start, 'CPU selector' is initialized to a valid value, on reset it
+keeps the current value.
+
+Read access behavior
+^^^^^^^^^^^^^^^^^^^^
+
+offset [0x0-0x3]
+ Command data 2: (DWORD access)
+
+ If value last stored in 'Command field' is:
+
+ 0:
+ reads as 0x0
+ 3:
+ upper 32 bits of architecture specific CPU ID value
+ other values:
+ reserved
+
+offset [0x4]
+ CPU device status fields: (1 byte access)
+
+ bits:
+
+ 0:
+ Device is enabled and may be used by guest
+ 1:
+ Device insert event, used to distinguish device for which
+ no device check event to OSPM was issued.
+ It's valid only when bit 0 is set.
+ 2:
+ Device remove event, used to distinguish device for which
+ no device eject request to OSPM was issued. Firmware must
+ ignore this bit.
+ 3:
+ reserved and should be ignored by OSPM
+ 4:
+ if set to 1, OSPM requests firmware to perform device eject.
+ 5-7:
+ reserved and should be ignored by OSPM
+
+offset [0x5-0x7]
+ reserved
+
+offset [0x8]
+ Command data: (DWORD access)
+
+ If value last stored in 'Command field' is one of:
+
+ 0:
+ contains 'CPU selector' value of a CPU with pending event[s]
+ 3:
+ lower 32 bits of architecture specific CPU ID value
+ (in x86 case: APIC ID)
+ otherwise:
+ contains 0
+
+Write access behavior
+^^^^^^^^^^^^^^^^^^^^^
+
+offset [0x0-0x3]
+ CPU selector: (DWORD access)
+
+ Selects active CPU device. All following accesses to other
+ registers will read/store data from/to selected CPU.
+ Valid values: [0 .. max_cpus)
+
+offset [0x4]
+ CPU device control fields: (1 byte access)
+
+ bits:
+
+ 0:
+ reserved, OSPM must clear it before writing to register.
+ 1:
+ if set to 1 clears device insert event, set by OSPM
+ after it has emitted device check event for the
+ selected CPU device
+ 2:
+ if set to 1 clears device remove event, set by OSPM
+ after it has emitted device eject request for the
+ selected CPU device.
+ 3:
+ if set to 1 initiates device eject, set by OSPM when it
+ triggers CPU device removal and calls _EJ0 method or by firmware
+ when bit #4 is set. In case bit #4 were set, it's cleared as
+ part of device eject.
+ 4:
+ if set to 1, OSPM hands over device eject to firmware.
+ Firmware shall issue device eject request as described above
+ (bit #3) and OSPM should not touch device eject bit (#3) in case
+ it's asked firmware to perform CPU device eject.
+ 5-7:
+ reserved, OSPM must clear them before writing to register
+
+offset[0x5]
+ Command field: (1 byte access)
+
+ value:
+
+ 0:
+ selects a CPU device with inserting/removing events and
+ following reads from 'Command data' register return
+ selected CPU ('CPU selector' value).
+ If no CPU with events found, the current 'CPU selector' doesn't
+ change and corresponding insert/remove event flags are not modified.
+
+ 1:
+ following writes to 'Command data' register set OST event
+ register in QEMU
+ 2:
+ following writes to 'Command data' register set OST status
+ register in QEMU
+ 3:
+ following reads from 'Command data' and 'Command data 2' return
+ architecture specific CPU ID value for currently selected CPU.
+ other values:
+ reserved
+
+offset [0x6-0x7]
+ reserved
+
+offset [0x8]
+ Command data: (DWORD access)
+
+ If last stored 'Command field' value is:
+
+ 1:
+ stores value into OST event register
+ 2:
+ stores value into OST status register, triggers
+ ACPI_DEVICE_OST QMP event from QEMU to external applications
+ with current values of OST event and status registers.
+ other values:
+ reserved
+
+Typical usecases
+----------------
+
+(x86) Detecting and enabling modern CPU hotplug interface
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+QEMU starts with legacy CPU hotplug interface enabled. Detecting and
+switching to modern interface is based on the 2 legacy CPU hotplug features:
+
+#. Writes into CPU bitmap are ignored.
+#. CPU bitmap always has bit #0 set, corresponding to boot CPU.
+
+Use following steps to detect and enable modern CPU hotplug interface:
+
+#. Store 0x0 to the 'CPU selector' register, attempting to switch to modern mode
+#. Store 0x0 to the 'CPU selector' register, to ensure valid selector value
+#. Store 0x0 to the 'Command field' register
+#. Read the 'Command data 2' register.
+ If read value is 0x0, the modern interface is enabled.
+ Otherwise legacy or no CPU hotplug interface available
+
+Get a cpu with pending event
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+#. Store 0x0 to the 'CPU selector' register.
+#. Store 0x0 to the 'Command field' register.
+#. Read the 'CPU device status fields' register.
+#. If both bit #1 and bit #2 are clear in the value read, there is no CPU
+ with a pending event and selected CPU remains unchanged.
+#. Otherwise, read the 'Command data' register. The value read is the
+ selector of the CPU with the pending event (which is already selected).
+
+Enumerate CPUs present/non present CPUs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+#. Set the present CPU count to 0.
+#. Set the iterator to 0.
+#. Store 0x0 to the 'CPU selector' register, to ensure that it's in
+ a valid state and that access to other registers won't be ignored.
+#. Store 0x0 to the 'Command field' register to make 'Command data'
+ register return 'CPU selector' value of selected CPU
+#. Read the 'CPU device status fields' register.
+#. If bit #0 is set, increment the present CPU count.
+#. Increment the iterator.
+#. Store the iterator to the 'CPU selector' register.
+#. Read the 'Command data' register.
+#. If the value read is not zero, goto 05.
+#. Otherwise store 0x0 to the 'CPU selector' register, to put it
+ into a valid state and exit.
+ The iterator at this point equals "max_cpus".
diff --git a/docs/specs/acpi_cpu_hotplug.txt b/docs/specs/acpi_cpu_hotplug.txt
deleted file mode 100644
index 9bd59ae0da..0000000000
--- a/docs/specs/acpi_cpu_hotplug.txt
+++ /dev/null
@@ -1,160 +0,0 @@
-QEMU<->ACPI BIOS CPU hotplug interface
---------------------------------------
-
-QEMU supports CPU hotplug via ACPI. This document
-describes the interface between QEMU and the ACPI BIOS.
-
-ACPI BIOS GPE.2 handler is dedicated for notifying OS about CPU hot-add
-and hot-remove events.
-
-============================================
-Legacy ACPI CPU hotplug interface registers:
---------------------------------------------
-CPU present bitmap for:
- ICH9-LPC (IO port 0x0cd8-0xcf7, 1-byte access)
- PIIX-PM (IO port 0xaf00-0xaf1f, 1-byte access)
- One bit per CPU. Bit position reflects corresponding CPU APIC ID. Read-only.
- The first DWORD in bitmap is used in write mode to switch from legacy
- to modern CPU hotplug interface, write 0 into it to do switch.
----------------------------------------------------------------
-QEMU sets corresponding CPU bit on hot-add event and issues SCI
-with GPE.2 event set. CPU present map is read by ACPI BIOS GPE.2 handler
-to notify OS about CPU hot-add events. CPU hot-remove isn't supported.
-
-=====================================
-Modern ACPI CPU hotplug interface registers:
--------------------------------------
-Register block base address:
- ICH9-LPC IO port 0x0cd8
- PIIX-PM IO port 0xaf00
-Register block size:
- ACPI_CPU_HOTPLUG_REG_LEN = 12
-
-All accesses to registers described below, imply little-endian byte order.
-
-Reserved resisters behavior:
- - write accesses are ignored
- - read accesses return all bits set to 0.
-
-The last stored value in 'CPU selector' must refer to a possible CPU, otherwise
- - reads from any register return 0
- - writes to any other register are ignored until valid value is stored into it
-On QEMU start, 'CPU selector' is initialized to a valid value, on reset it
-keeps the current value.
-
-read access:
- offset:
- [0x0-0x3] Command data 2: (DWORD access)
- if value last stored in 'Command field':
- 0: reads as 0x0
- 3: upper 32 bits of architecture specific CPU ID value
- other values: reserved
- [0x4] CPU device status fields: (1 byte access)
- bits:
- 0: Device is enabled and may be used by guest
- 1: Device insert event, used to distinguish device for which
- no device check event to OSPM was issued.
- It's valid only when bit 0 is set.
- 2: Device remove event, used to distinguish device for which
- no device eject request to OSPM was issued. Firmware must
- ignore this bit.
- 3: reserved and should be ignored by OSPM
- 4: if set to 1, OSPM requests firmware to perform device eject.
- 5-7: reserved and should be ignored by OSPM
- [0x5-0x7] reserved
- [0x8] Command data: (DWORD access)
- contains 0 unless value last stored in 'Command field' is one of:
- 0: contains 'CPU selector' value of a CPU with pending event[s]
- 3: lower 32 bits of architecture specific CPU ID value
- (in x86 case: APIC ID)
-
-write access:
- offset:
- [0x0-0x3] CPU selector: (DWORD access)
- selects active CPU device. All following accesses to other
- registers will read/store data from/to selected CPU.
- Valid values: [0 .. max_cpus)
- [0x4] CPU device control fields: (1 byte access)
- bits:
- 0: reserved, OSPM must clear it before writing to register.
- 1: if set to 1 clears device insert event, set by OSPM
- after it has emitted device check event for the
- selected CPU device
- 2: if set to 1 clears device remove event, set by OSPM
- after it has emitted device eject request for the
- selected CPU device.
- 3: if set to 1 initiates device eject, set by OSPM when it
- triggers CPU device removal and calls _EJ0 method or by firmware
- when bit #4 is set. In case bit #4 were set, it's cleared as
- part of device eject.
- 4: if set to 1, OSPM hands over device eject to firmware.
- Firmware shall issue device eject request as described above
- (bit #3) and OSPM should not touch device eject bit (#3) in case
- it's asked firmware to perform CPU device eject.
- 5-7: reserved, OSPM must clear them before writing to register
- [0x5] Command field: (1 byte access)
- value:
- 0: selects a CPU device with inserting/removing events and
- following reads from 'Command data' register return
- selected CPU ('CPU selector' value).
- If no CPU with events found, the current 'CPU selector' doesn't
- change and corresponding insert/remove event flags are not modified.
- 1: following writes to 'Command data' register set OST event
- register in QEMU
- 2: following writes to 'Command data' register set OST status
- register in QEMU
- 3: following reads from 'Command data' and 'Command data 2' return
- architecture specific CPU ID value for currently selected CPU.
- other values: reserved
- [0x6-0x7] reserved
- [0x8] Command data: (DWORD access)
- if last stored 'Command field' value:
- 1: stores value into OST event register
- 2: stores value into OST status register, triggers
- ACPI_DEVICE_OST QMP event from QEMU to external applications
- with current values of OST event and status registers.
- other values: reserved
-
-Typical usecases:
- - (x86) Detecting and enabling modern CPU hotplug interface.
- QEMU starts with legacy CPU hotplug interface enabled. Detecting and
- switching to modern interface is based on the 2 legacy CPU hotplug features:
- 1. Writes into CPU bitmap are ignored.
- 2. CPU bitmap always has bit#0 set, corresponding to boot CPU.
-
- Use following steps to detect and enable modern CPU hotplug interface:
- 1. Store 0x0 to the 'CPU selector' register,
- attempting to switch to modern mode
- 2. Store 0x0 to the 'CPU selector' register,
- to ensure valid selector value
- 3. Store 0x0 to the 'Command field' register,
- 4. Read the 'Command data 2' register.
- If read value is 0x0, the modern interface is enabled.
- Otherwise legacy or no CPU hotplug interface available
-
- - Get a cpu with pending event
- 1. Store 0x0 to the 'CPU selector' register.
- 2. Store 0x0 to the 'Command field' register.
- 3. Read the 'CPU device status fields' register.
- 4. If both bit#1 and bit#2 are clear in the value read, there is no CPU
- with a pending event and selected CPU remains unchanged.
- 5. Otherwise, read the 'Command data' register. The value read is the
- selector of the CPU with the pending event (which is already
- selected).
-
- - Enumerate CPUs present/non present CPUs
- 01. Set the present CPU count to 0.
- 02. Set the iterator to 0.
- 03. Store 0x0 to the 'CPU selector' register, to ensure that it's in
- a valid state and that access to other registers won't be ignored.
- 04. Store 0x0 to the 'Command field' register to make 'Command data'
- register return 'CPU selector' value of selected CPU
- 05. Read the 'CPU device status fields' register.
- 06. If bit#0 is set, increment the present CPU count.
- 07. Increment the iterator.
- 08. Store the iterator to the 'CPU selector' register.
- 09. Read the 'Command data' register.
- 10. If the value read is not zero, goto 05.
- 11. Otherwise store 0x0 to the 'CPU selector' register, to put it
- into a valid state and exit.
- The iterator at this point equals "max_cpus".
diff --git a/docs/specs/acpi_mem_hotplug.rst b/docs/specs/acpi_mem_hotplug.rst
new file mode 100644
index 0000000000..069819bc3e
--- /dev/null
+++ b/docs/specs/acpi_mem_hotplug.rst
@@ -0,0 +1,128 @@
+QEMU<->ACPI BIOS memory hotplug interface
+=========================================
+
+ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add
+and hot-remove events.
+
+Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access)
+----------------------------------------------------------------
+
+Read access behavior
+^^^^^^^^^^^^^^^^^^^^
+
+[0x0-0x3]
+ Lo part of memory device phys address
+[0x4-0x7]
+ Hi part of memory device phys address
+[0x8-0xb]
+ Lo part of memory device size in bytes
+[0xc-0xf]
+ Hi part of memory device size in bytes
+[0x10-0x13]
+ Memory device proximity domain
+[0x14]
+ Memory device status fields
+
+ bits:
+
+ 0:
+ Device is enabled and may be used by guest
+ 1:
+ Device insert event, used to distinguish device for which
+ no device check event to OSPM was issued.
+ It's valid only when bit 1 is set.
+ 2:
+ Device remove event, used to distinguish device for which
+ no device eject request to OSPM was issued.
+ 3-7:
+ reserved and should be ignored by OSPM
+
+[0x15-0x17]
+ reserved
+
+Write access behavior
+^^^^^^^^^^^^^^^^^^^^^
+
+
+[0x0-0x3]
+ Memory device slot selector, selects active memory device.
+ All following accesses to other registers in 0xa00-0xa17
+ region will read/store data from/to selected memory device.
+[0x4-0x7]
+ OST event code reported by OSPM
+[0x8-0xb]
+ OST status code reported by OSPM
+[0xc-0x13]
+ reserved, writes into it are ignored
+[0x14]
+ Memory device control fields
+
+ bits:
+
+ 0:
+ reserved, OSPM must clear it before writing to register.
+ Due to BUG in versions prior 2.4 that field isn't cleared
+ when other fields are written. Keep it reserved and don't
+ try to reuse it.
+ 1:
+ if set to 1 clears device insert event, set by OSPM
+ after it has emitted device check event for the
+ selected memory device
+ 2:
+ if set to 1 clears device remove event, set by OSPM
+ after it has emitted device eject request for the
+ selected memory device
+ 3:
+ if set to 1 initiates device eject, set by OSPM when it
+ triggers memory device removal and calls _EJ0 method
+ 4-7:
+ reserved, OSPM must clear them before writing to register
+
+Selecting memory device slot beyond present range has no effect on platform:
+
+- write accesses to memory hot-plug registers not documented above are ignored
+- read accesses to memory hot-plug registers not documented above return
+ all bits set to 1.
+
+Memory hot remove process diagram
+---------------------------------
+
+::
+
+ +-------------+ +-----------------------+ +------------------+
+ | 1. QEMU | | 2. QEMU | |3. QEMU |
+ | device_del +---->+ device unplug request +----->+Send SCI to guest,|
+ | | | cb | |return control to |
+ | | | | |management |
+ +-------------+ +-----------------------+ +------------------+
+
+ +---------------------------------------------------------------------+
+
+ +---------------------+ +-------------------------+
+ | OSPM: | remove event | OSPM: |
+ | send Eject Request, | | Scan memory devices |
+ | clear remove event +<-------------+ for event flags |
+ | | | |
+ +---------------------+ +-------------------------+
+ |
+ |
+ +---------v--------+ +-----------------------+
+ | Guest OS: | success | OSPM: |
+ | process Ejection +----------->+ Execute _EJ0 method, |
+ | request | | set eject bit in flags|
+ +------------------+ +-----------------------+
+ |failure |
+ v v
+ +------------------------+ +-----------------------+
+ | OSPM: | | QEMU: |
+ | set OST event & status | | call device unplug cb |
+ | fields | | |
+ +------------------------+ +-----------------------+
+ | |
+ v v
+ +------------------+ +-------------------+
+ |QEMU: | |QEMU: |
+ |Send OST QMP event| |Send device deleted|
+ | | |QMP event |
+ +------------------+ | |
+ +-------------------+
diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
deleted file mode 100644
index 3df3620ce4..0000000000
--- a/docs/specs/acpi_mem_hotplug.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-QEMU<->ACPI BIOS memory hotplug interface
---------------------------------------
-
-ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add
-and hot-remove events.
-
-Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access):
----------------------------------------------------------------
-0xa00:
- read access:
- [0x0-0x3] Lo part of memory device phys address
- [0x4-0x7] Hi part of memory device phys address
- [0x8-0xb] Lo part of memory device size in bytes
- [0xc-0xf] Hi part of memory device size in bytes
- [0x10-0x13] Memory device proximity domain
- [0x14] Memory device status fields
- bits:
- 0: Device is enabled and may be used by guest
- 1: Device insert event, used to distinguish device for which
- no device check event to OSPM was issued.
- It's valid only when bit 1 is set.
- 2: Device remove event, used to distinguish device for which
- no device eject request to OSPM was issued.
- 3-7: reserved and should be ignored by OSPM
- [0x15-0x17] reserved
-
- write access:
- [0x0-0x3] Memory device slot selector, selects active memory device.
- All following accesses to other registers in 0xa00-0xa17
- region will read/store data from/to selected memory device.
- [0x4-0x7] OST event code reported by OSPM
- [0x8-0xb] OST status code reported by OSPM
- [0xc-0x13] reserved, writes into it are ignored
- [0x14] Memory device control fields
- bits:
- 0: reserved, OSPM must clear it before writing to register.
- Due to BUG in versions prior 2.4 that field isn't cleared
- when other fields are written. Keep it reserved and don't
- try to reuse it.
- 1: if set to 1 clears device insert event, set by OSPM
- after it has emitted device check event for the
- selected memory device
- 2: if set to 1 clears device remove event, set by OSPM
- after it has emitted device eject request for the
- selected memory device
- 3: if set to 1 initiates device eject, set by OSPM when it
- triggers memory device removal and calls _EJ0 method
- 4-7: reserved, OSPM must clear them before writing to register
-
-Selecting memory device slot beyond present range has no effect on platform:
- - write accesses to memory hot-plug registers not documented above are
- ignored
- - read accesses to memory hot-plug registers not documented above return
- all bits set to 1.
-
-Memory hot remove process diagram:
-----------------------------------
- +-------------+     +-----------------------+      +------------------+     
- |  1. QEMU    |     | 2. QEMU               |      |3. QEMU           |     
- |  device_del +---->+ device unplug request +----->+Send SCI to guest,|     
- |             |     |         cb            |      |return control to |     
- +-------------+     +-----------------------+      |management        |     
-                                                    +------------------+     
-                                                                             
- +---------------------------------------------------------------------+     
-                                                                             
- +---------------------+              +-------------------------+            
- | OSPM:               | remove event | OSPM:                   |            
- | send Eject Request, |              | Scan memory devices     |            
- | clear remove event  +<-------------+ for event flags         |            
- |                     |              |                         |            
- +---------------------+              +-------------------------+            
-           |                                                                 
-           |                                                                 
- +---------v--------+            +-----------------------+                   
- | Guest OS:        |  success   | OSPM:                 |                   
- | process Ejection +----------->+ Execute _EJ0 method,  |                   
- | request          |            | set eject bit in flags|                   
- +------------------+            +-----------------------+                   
-           |failure                         |                                
-           v                                v                                
- +------------------------+      +-----------------------+                   
- | OSPM:                  |      | QEMU:                 |                   
- | set OST event & status |      | call device unplug cb |                   
- | fields                 |      |                       |                   
- +------------------------+      +-----------------------+                   
-          |                                  |                               
-          v                                  v                               
- +------------------+              +-------------------+                     
- |QEMU:             |              |QEMU:              |                     
- |Send OST QMP event|              |Send device deleted|                     
- |                  |              |QMP event          |                     
- +------------------+              |                   |                     
-                                   +-------------------+
diff --git a/docs/specs/acpi_nvdimm.rst b/docs/specs/acpi_nvdimm.rst
new file mode 100644
index 0000000000..ab0335253d
--- /dev/null
+++ b/docs/specs/acpi_nvdimm.rst
@@ -0,0 +1,228 @@
+QEMU<->ACPI BIOS NVDIMM interface
+=================================
+
+QEMU supports NVDIMM via ACPI. This document describes the basic concepts of
+NVDIMM ACPI and the interface between QEMU and the ACPI BIOS.
+
+NVDIMM ACPI Background
+----------------------
+
+NVDIMM is introduced in ACPI 6.0 which defines an NVDIMM root device under
+_SB scope with a _HID of "ACPI0012". For each NVDIMM present or intended
+to be supported by platform, platform firmware also exposes an ACPI
+Namespace Device under the root device.
+
+The NVDIMM child devices under the NVDIMM root device are defined with _ADR
+corresponding to the NFIT device handle. The NVDIMM root device and the
+NVDIMM devices can have device specific methods (_DSM) to provide additional
+functions specific to a particular NVDIMM implementation.
+
+This is an example from ACPI 6.0, a platform contains one NVDIMM::
+
+ Scope (\_SB){
+ Device (NVDR) // Root device
+ {
+ Name (_HID, "ACPI0012")
+ Method (_STA) {...}
+ Method (_FIT) {...}
+ Method (_DSM, ...) {...}
+ Device (NVD)
+ {
+ Name(_ADR, h) //where h is NFIT Device Handle for this NVDIMM
+ Method (_DSM, ...) {...}
+ }
+ }
+ }
+
+Methods supported on both NVDIMM root device and NVDIMM device
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+_DSM (Device Specific Method)
+ It is a control method that enables devices to provide device specific
+ control functions that are consumed by the device driver.
+ The NVDIMM DSM specification can be found at
+ http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf
+
+ Arguments:
+
+ Arg0
+ A Buffer containing a UUID (16 Bytes)
+ Arg1
+ An Integer containing the Revision ID (4 Bytes)
+ Arg2
+ An Integer containing the Function Index (4 Bytes)
+ Arg3
+ A package containing parameters for the function specified by the
+ UUID, Revision ID, and Function Index
+
+ Return Value:
+
+ If Function Index = 0, a Buffer containing a function index bitfield.
+ Otherwise, the return value and type depends on the UUID, revision ID
+ and function index which are described in the DSM specification.
+
+Methods on NVDIMM ROOT Device
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+_FIT(Firmware Interface Table)
+ It evaluates to a buffer returning data in the format of a series of NFIT
+ Type Structure.
+
+ Arguments: None
+
+ Return Value:
+ A Buffer containing a list of NFIT Type structure entries.
+
+ The detailed definition of the structure can be found at ACPI 6.0: 5.2.25
+ NVDIMM Firmware Interface Table (NFIT).
+
+QEMU NVDIMM Implementation
+--------------------------
+
+QEMU uses 4 bytes IO Port starting from 0x0a18 and a RAM-based memory page
+for NVDIMM ACPI.
+
+Memory:
+ QEMU uses BIOS Linker/loader feature to ask BIOS to allocate a memory
+ page and dynamically patch its address into an int32 object named "MEMA"
+ in ACPI.
+
+ This page is RAM-based and it is used to transfer data between _DSM
+ method and QEMU. If ACPI has control, this pages is owned by ACPI which
+ writes _DSM input data to it, otherwise, it is owned by QEMU which
+ emulates _DSM access and writes the output data to it.
+
+ ACPI writes _DSM Input Data (based on the offset in the page):
+
+ [0x0 - 0x3]
+ 4 bytes, NVDIMM Device Handle.
+
+ The handle is completely QEMU internal thing, the values in
+ range [1, 0xFFFF] indicate nvdimm device. Other values are
+ reserved for other purposes.
+
+ Reserved handles:
+
+ - 0 is reserved for nvdimm root device named NVDR.
+ - 0x10000 is reserved for QEMU internal DSM function called on
+ the root device.
+
+ [0x4 - 0x7]
+ 4 bytes, Revision ID, that is the Arg1 of _DSM method.
+
+ [0x8 - 0xB]
+ 4 bytes. Function Index, that is the Arg2 of _DSM method.
+
+ [0xC - 0xFFF]
+ 4084 bytes, the Arg3 of _DSM method.
+
+ QEMU writes Output Data (based on the offset in the page):
+
+ [0x0 - 0x3]
+ 4 bytes, the length of result
+
+ [0x4 - 0xFFF]
+ 4092 bytes, the DSM result filled by QEMU
+
+IO Port 0x0a18 - 0xa1b:
+ ACPI writes the address of the memory page allocated by BIOS to this
+ port then QEMU gets the control and fills the result in the memory page.
+
+ Write Access:
+
+ [0x0a18 - 0xa1b]
+ 4 bytes, the address of the memory page allocated by BIOS.
+
+_DSM process diagram
+--------------------
+
+"MEMA" indicates the address of memory page allocated by BIOS.
+
+::
+
+ +----------------------+ +-----------------------+
+ | 1. OSPM | | 2. OSPM |
+ | save _DSM input data | | write "MEMA" to | Exit to QEMU
+ | to the page +----->| IO port 0x0a18 +------------+
+ | indicated by "MEMA" | | | |
+ +----------------------+ +-----------------------+ |
+ |
+ v
+ +--------------------+ +-----------+ +------------------+--------+
+ | 5 QEMU | | 4 QEMU | | 3. QEMU |
+ | write _DSM result | | emulate | | get _DSM input data from |
+ | to the page +<------+ _DSM +<-----+ the page indicated by the |
+ | | | | | value from the IO port |
+ +--------+-----------+ +-----------+ +---------------------------+
+ |
+ | Enter Guest
+ |
+ v
+ +--------------------------+ +--------------+
+ | 6 OSPM | | 7 OSPM |
+ | result size is returned | | _DSM return |
+ | by reading DSM +----->+ |
+ | result from the page | | |
+ +--------------------------+ +--------------+
+
+NVDIMM hotplug
+--------------
+
+ACPI BIOS GPE.4 handler is dedicated for notifying OS about nvdimm device
+hot-add event.
+
+QEMU internal use only _DSM functions
+-------------------------------------
+
+Read FIT
+^^^^^^^^
+
+_FIT method uses _DSM method to fetch NFIT structures blob from QEMU
+in 1 page sized increments which are then concatenated and returned
+as _FIT method result.
+
+Input parameters:
+
+Arg0
+ UUID {set to 648B9CF2-CDA1-4312-8AD9-49C4AF32BD62}
+Arg1
+ Revision ID (set to 1)
+Arg2
+ Function Index, 0x1
+Arg3
+ A package containing a buffer whose layout is as follows:
+
+ +----------+--------+--------+-------------------------------------------+
+ | Field | Length | Offset | Description |
+ +----------+--------+--------+-------------------------------------------+
+ | offset | 4 | 0 | offset in QEMU's NFIT structures blob to |
+ | | | | read from |
+ +----------+--------+--------+-------------------------------------------+
+
+Output layout in the dsm memory page:
+
+ +----------+--------+--------+-------------------------------------------+
+ | Field | Length | Offset | Description |
+ +----------+--------+--------+-------------------------------------------+
+ | length | 4 | 0 | length of entire returned data |
+ | | | | (including this header) |
+ +----------+--------+--------+-------------------------------------------+
+ | | | | return status codes |
+ | | | | |
+ | | | | - 0x0 - success |
+ | | | | - 0x100 - error caused by NFIT update |
+ | status | 4 | 4 | while read by _FIT wasn't completed |
+ | | | | - other codes follow Chapter 3 in |
+ | | | | DSM Spec Rev1 |
+ +----------+--------+--------+-------------------------------------------+
+ | fit data | Varies | 8 | contains FIT data. This field is present |
+ | | | | if status field is 0. |
+ +----------+--------+--------+-------------------------------------------+
+
+The FIT offset is maintained by the OSPM itself, current offset plus
+the size of the fit data returned by the function is the next offset
+OSPM should read. When all FIT data has been read out, zero fit data
+size is returned.
+
+If it returns status code 0x100, OSPM should restart to read FIT (read
+from offset 0 again).
diff --git a/docs/specs/acpi_nvdimm.txt b/docs/specs/acpi_nvdimm.txt
deleted file mode 100644
index 3ec42ecbce..0000000000
--- a/docs/specs/acpi_nvdimm.txt
+++ /dev/null
@@ -1,188 +0,0 @@
-QEMU<->ACPI BIOS NVDIMM interface
----------------------------------
-
-QEMU supports NVDIMM via ACPI. This document describes the basic concepts of
-NVDIMM ACPI and the interface between QEMU and the ACPI BIOS.
-
-NVDIMM ACPI Background
-----------------------
-NVDIMM is introduced in ACPI 6.0 which defines an NVDIMM root device under
-_SB scope with a _HID of “ACPI0012”. For each NVDIMM present or intended
-to be supported by platform, platform firmware also exposes an ACPI
-Namespace Device under the root device.
-
-The NVDIMM child devices under the NVDIMM root device are defined with _ADR
-corresponding to the NFIT device handle. The NVDIMM root device and the
-NVDIMM devices can have device specific methods (_DSM) to provide additional
-functions specific to a particular NVDIMM implementation.
-
-This is an example from ACPI 6.0, a platform contains one NVDIMM:
-
-Scope (\_SB){
- Device (NVDR) // Root device
- {
- Name (_HID, “ACPI0012”)
- Method (_STA) {...}
- Method (_FIT) {...}
- Method (_DSM, ...) {...}
- Device (NVD)
- {
- Name(_ADR, h) //where h is NFIT Device Handle for this NVDIMM
- Method (_DSM, ...) {...}
- }
- }
-}
-
-Method supported on both NVDIMM root device and NVDIMM device
-_DSM (Device Specific Method)
- It is a control method that enables devices to provide device specific
- control functions that are consumed by the device driver.
- The NVDIMM DSM specification can be found at:
- http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf
-
- Arguments:
- Arg0 – A Buffer containing a UUID (16 Bytes)
- Arg1 – An Integer containing the Revision ID (4 Bytes)
- Arg2 – An Integer containing the Function Index (4 Bytes)
- Arg3 – A package containing parameters for the function specified by the
- UUID, Revision ID, and Function Index
-
- Return Value:
- If Function Index = 0, a Buffer containing a function index bitfield.
- Otherwise, the return value and type depends on the UUID, revision ID
- and function index which are described in the DSM specification.
-
-Methods on NVDIMM ROOT Device
-_FIT(Firmware Interface Table)
- It evaluates to a buffer returning data in the format of a series of NFIT
- Type Structure.
-
- Arguments: None
-
- Return Value:
- A Buffer containing a list of NFIT Type structure entries.
-
- The detailed definition of the structure can be found at ACPI 6.0: 5.2.25
- NVDIMM Firmware Interface Table (NFIT).
-
-QEMU NVDIMM Implementation
-==========================
-QEMU uses 4 bytes IO Port starting from 0x0a18 and a RAM-based memory page
-for NVDIMM ACPI.
-
-Memory:
- QEMU uses BIOS Linker/loader feature to ask BIOS to allocate a memory
- page and dynamically patch its address into an int32 object named "MEMA"
- in ACPI.
-
- This page is RAM-based and it is used to transfer data between _DSM
- method and QEMU. If ACPI has control, this pages is owned by ACPI which
- writes _DSM input data to it, otherwise, it is owned by QEMU which
- emulates _DSM access and writes the output data to it.
-
- ACPI writes _DSM Input Data (based on the offset in the page):
- [0x0 - 0x3]: 4 bytes, NVDIMM Device Handle.
-
- The handle is completely QEMU internal thing, the values in
- range [1, 0xFFFF] indicate nvdimm device. Other values are
- reserved for other purposes.
-
- Reserved handles:
- 0 is reserved for nvdimm root device named NVDR.
- 0x10000 is reserved for QEMU internal DSM function called on
- the root device.
-
- [0x4 - 0x7]: 4 bytes, Revision ID, that is the Arg1 of _DSM method.
- [0x8 - 0xB]: 4 bytes. Function Index, that is the Arg2 of _DSM method.
- [0xC - 0xFFF]: 4084 bytes, the Arg3 of _DSM method.
-
- QEMU Writes Output Data (based on the offset in the page):
- [0x0 - 0x3]: 4 bytes, the length of result
- [0x4 - 0xFFF]: 4092 bytes, the DSM result filled by QEMU
-
-IO Port 0x0a18 - 0xa1b:
- ACPI writes the address of the memory page allocated by BIOS to this
- port then QEMU gets the control and fills the result in the memory page.
-
- write Access:
- [0x0a18 - 0xa1b]: 4 bytes, the address of the memory page allocated
- by BIOS.
-
-_DSM process diagram:
----------------------
-"MEMA" indicates the address of memory page allocated by BIOS.
-
- +----------------------+   +-----------------------+
- |   1. OSPM   |      | 2. OSPM |
- | save _DSM input data | | write "MEMA" to | Exit to QEMU
- | to the page +----->| IO port 0x0a18 +------------+
- | indicated by "MEMA" | | | |
- +----------------------+ +-----------------------+ |
-  |
-  v
- +------------- ----+ +-----------+ +------------------+--------+
- | 5 QEMU | | 4 QEMU | | 3. QEMU |
- | write _DSM result | | emulate | | get _DSM input data from |
- | to the page +<------+ _DSM +<-----+ the page indicated by the |
- | | | | | value from the IO port |
- +--------+-----------+ +-----------+ +---------------------------+
- |
- | Enter Guest
- |
- v
- +--------------------------+ +--------------+
- | 6 OSPM | | 7 OSPM |
- | result size is returned | | _DSM return |
- | by reading DSM +----->+ |
- | result from the page | | |
- +--------------------------+ +--------------+
-
-NVDIMM hotplug
---------------
-ACPI BIOS GPE.4 handler is dedicated for notifying OS about nvdimm device
-hot-add event.
-
-QEMU internal use only _DSM function
-------------------------------------
-1) Read FIT
- _FIT method uses _DSM method to fetch NFIT structures blob from QEMU
- in 1 page sized increments which are then concatenated and returned
- as _FIT method result.
-
- Input parameters:
- Arg0 – UUID {set to 648B9CF2-CDA1-4312-8AD9-49C4AF32BD62}
- Arg1 – Revision ID (set to 1)
- Arg2 - Function Index, 0x1
- Arg3 - A package containing a buffer whose layout is as follows:
-
- +----------+--------+--------+-------------------------------------------+
- | Field | Length | Offset | Description |
- +----------+--------+--------+-------------------------------------------+
- | offset | 4 | 0 | offset in QEMU's NFIT structures blob to |
- | | | | read from |
- +----------+--------+--------+-------------------------------------------+
-
- Output layout in the dsm memory page:
- +----------+--------+--------+-------------------------------------------+
- | Field | Length | Offset | Description |
- +----------+--------+--------+-------------------------------------------+
- | length | 4 | 0 | length of entire returned data |
- | | | | (including this header) |
- +----------+-----------------+-------------------------------------------+
- | | | | return status codes |
- | | | | 0x0 - success |
- | | | | 0x100 - error caused by NFIT update while |
- | status | 4 | 4 | read by _FIT wasn't completed, other |
- | | | | codes follow Chapter 3 in DSM Spec Rev1 |
- +----------+-----------------+-------------------------------------------+
- | fit data | Varies | 8 | contains FIT data, this field is present |
- | | | | if status field is 0; |
- +----------+--------+--------+-------------------------------------------+
-
- The FIT offset is maintained by the OSPM itself, current offset plus
- the size of the fit data returned by the function is the next offset
- OSPM should read. When all FIT data has been read out, zero fit data
- size is returned.
-
- If it returns status code 0x100, OSPM should restart to read FIT (read
- from offset 0 again).
diff --git a/docs/specs/acpi_pci_hotplug.txt b/docs/specs/acpi_pci_hotplug.rst
index a839434f31..685bc5c322 100644
--- a/docs/specs/acpi_pci_hotplug.txt
+++ b/docs/specs/acpi_pci_hotplug.rst
@@ -1,45 +1,48 @@
QEMU<->ACPI BIOS PCI hotplug interface
---------------------------------------
+======================================
QEMU supports PCI hotplug via ACPI, for PCI bus 0. This document
describes the interface between QEMU and the ACPI BIOS.
-ACPI GPE block (IO ports 0xafe0-0xafe3, byte access):
------------------------------------------
+ACPI GPE block (IO ports 0xafe0-0xafe3, byte access)
+----------------------------------------------------
Generic ACPI GPE block. Bit 1 (GPE.1) used to notify PCI hotplug/eject
event to ACPI BIOS, via SCI interrupt.
-PCI slot injection notification pending (IO port 0xae00-0xae03, 4-byte access):
----------------------------------------------------------------
+PCI slot injection notification pending (IO port 0xae00-0xae03, 4-byte access)
+------------------------------------------------------------------------------
+
Slot injection notification pending. One bit per slot.
Read by ACPI BIOS GPE.1 handler to notify OS of injection
events. Read-only.
-PCI slot removal notification (IO port 0xae04-0xae07, 4-byte access):
------------------------------------------------------
+PCI slot removal notification (IO port 0xae04-0xae07, 4-byte access)
+--------------------------------------------------------------------
+
Slot removal notification pending. One bit per slot.
Read by ACPI BIOS GPE.1 handler to notify OS of removal
events. Read-only.
-PCI device eject (IO port 0xae08-0xae0b, 4-byte access):
-----------------------------------------
+PCI device eject (IO port 0xae08-0xae0b, 4-byte access)
+-------------------------------------------------------
Write: Used by ACPI BIOS _EJ0 method to request device removal.
One bit per slot.
Read: Hotplug features register. Used by platform to identify features
available. Current base feature set (no bits set):
- - Read-only "up" register @0xae00, 4-byte access, bit per slot
- - Read-only "down" register @0xae04, 4-byte access, bit per slot
- - Read/write "eject" register @0xae08, 4-byte access,
- write: bit per slot eject, read: hotplug feature set
- - Read-only hotplug capable register @0xae0c, 4-byte access, bit per slot
-PCI removability status (IO port 0xae0c-0xae0f, 4-byte access):
------------------------------------------------
+- Read-only "up" register @0xae00, 4-byte access, bit per slot
+- Read-only "down" register @0xae04, 4-byte access, bit per slot
+- Read/write "eject" register @0xae08, 4-byte access,
+ write: bit per slot eject, read: hotplug feature set
+- Read-only hotplug capable register @0xae0c, 4-byte access, bit per slot
+
+PCI removability status (IO port 0xae0c-0xae0f, 4-byte access)
+--------------------------------------------------------------
Used by ACPI BIOS _RMV method to indicate removability status to OS. One
-bit per slot. Read-only
+bit per slot. Read-only.
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index b7b08ea30d..65e9663916 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -13,3 +13,7 @@ guest hardware that is specific to QEMU.
acpi_hw_reduced_hotplug
tpm
acpi_hest_ghes
+ acpi_cpu_hotplug
+ acpi_mem_hotplug
+ acpi_pci_hotplug
+ acpi_nvdimm
diff --git a/gdbstub.c b/gdbstub.c
index 52bde5bdc9..5d8e6ae3cd 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -3218,7 +3218,7 @@ static bool gdb_accept_socket(int gdb_fd)
static int gdbserver_open_socket(const char *path)
{
- struct sockaddr_un sockaddr;
+ struct sockaddr_un sockaddr = {};
int fd, ret;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -3247,7 +3247,7 @@ static int gdbserver_open_socket(const char *path)
static bool gdb_accept_tcp(int gdb_fd)
{
- struct sockaddr_in sockaddr;
+ struct sockaddr_in sockaddr = {};
socklen_t len;
int fd;
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 4ba0aca067..dc050b5c37 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -25,9 +25,7 @@ config ARM_VIRT
select ACPI_PCI
select MEM_DEVICE
select DIMM
- select ACPI_MEMORY_HOTPLUG
select ACPI_HW_REDUCED
- select ACPI_NVDIMM
select ACPI_APEI
config CHEETAH
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index b30a17871f..0ada91c05e 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -281,7 +281,7 @@ static void raspi_machine_init(MachineState *machine)
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(machine->ram));
object_property_set_int(OBJECT(&s->soc), "board-rev", board_rev,
&error_abort);
- qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
+ qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
/* Create and plug in the SD cards */
di = drive_get_next(IF_SD);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 81eda46b0b..86c8a4ca3d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1852,11 +1852,6 @@ static void machvirt_init(MachineState *machine)
}
if (vms->secure) {
- if (kvm_enabled()) {
- error_report("mach-virt: KVM does not support Security extensions");
- exit(1);
- }
-
/*
* The Secure view of the world is the same as the NonSecure,
* but with a few extra devices. Create it as a container region
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index fb776834f7..547a26603a 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -218,6 +218,8 @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
TYPE_XLNX_ZDMA);
dev = DEVICE(&s->lpd.iou.adma[i]);
object_property_set_int(OBJECT(dev), "bus-width", 128, &error_abort);
+ object_property_set_link(OBJECT(dev), "dma",
+ OBJECT(get_system_memory()), &error_fatal);
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
@@ -376,6 +378,8 @@ static void versal_unimp(Versal *s)
MM_CRL, MM_CRL_SIZE);
versal_unimp_area(s, "crf", &s->mr_ps,
MM_FPD_CRF, MM_FPD_CRF_SIZE);
+ versal_unimp_area(s, "apu", &s->mr_ps,
+ MM_FPD_FPD_APU, MM_FPD_FPD_APU_SIZE);
versal_unimp_area(s, "crp", &s->mr_ps,
MM_PMC_CRP, MM_PMC_CRP_SIZE);
versal_unimp_area(s, "iou-scntr", &s->mr_ps,
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 3597e8db4d..4e5a471e30 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -20,6 +20,7 @@
#include "qemu/module.h"
#include "hw/arm/xlnx-zynqmp.h"
#include "hw/intc/arm_gic_common.h"
+#include "hw/misc/unimp.h"
#include "hw/boards.h"
#include "sysemu/kvm.h"
#include "sysemu/sysemu.h"
@@ -56,6 +57,9 @@
#define DPDMA_ADDR 0xfd4c0000
#define DPDMA_IRQ 116
+#define APU_ADDR 0xfd5c0000
+#define APU_SIZE 0x100
+
#define IPI_ADDR 0xFF300000
#define IPI_IRQ 64
@@ -222,6 +226,32 @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s,
qdev_realize(DEVICE(&s->rpu_cluster), NULL, &error_fatal);
}
+static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
+{
+ static const struct UnimpInfo {
+ const char *name;
+ hwaddr base;
+ hwaddr size;
+ } unimp_areas[ARRAY_SIZE(s->mr_unimp)] = {
+ { .name = "apu", APU_ADDR, APU_SIZE },
+ };
+ unsigned int nr;
+
+ for (nr = 0; nr < ARRAY_SIZE(unimp_areas); nr++) {
+ const struct UnimpInfo *info = &unimp_areas[nr];
+ DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+ assert(info->name && info->base && info->size > 0);
+ qdev_prop_set_string(dev, "name", info->name);
+ qdev_prop_set_uint64(dev, "size", info->size);
+ object_property_add_child(OBJECT(s), info->name, OBJECT(dev));
+
+ sysbus_realize_and_unref(sbd, &error_fatal);
+ sysbus_mmio_map(sbd, 0, info->base);
+ }
+}
+
static void xlnx_zynqmp_init(Object *obj)
{
MachineState *ms = MACHINE(qdev_get_machine());
@@ -570,26 +600,6 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
g_free(bus_name);
}
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->qspi), errp)) {
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 0, QSPI_ADDR);
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 1, LQSPI_ADDR);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi), 0, gic_spi[QSPI_IRQ]);
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_QSPI_BUS; i++) {
- gchar *bus_name;
- gchar *target_bus;
-
- /* Alias controller SPI bus to the SoC itself */
- bus_name = g_strdup_printf("qspi%d", i);
- target_bus = g_strdup_printf("spi%d", i);
- object_property_add_alias(OBJECT(s), bus_name,
- OBJECT(&s->qspi), target_bus);
- g_free(bus_name);
- g_free(target_bus);
- }
-
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dp), errp)) {
return;
}
@@ -616,11 +626,17 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, RTC_ADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, gic_spi[RTC_IRQ]);
+ xlnx_zynqmp_create_unimp_mmio(s);
+
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
if (!object_property_set_uint(OBJECT(&s->gdma[i]), "bus-width", 128,
errp)) {
return;
}
+ if (!object_property_set_link(OBJECT(&s->gdma[i]), "dma",
+ OBJECT(system_memory), errp)) {
+ return;
+ }
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gdma[i]), errp)) {
return;
}
@@ -631,6 +647,10 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
}
for (i = 0; i < XLNX_ZYNQMP_NUM_ADMA_CH; i++) {
+ if (!object_property_set_link(OBJECT(&s->adma[i]), "dma",
+ OBJECT(system_memory), errp)) {
+ return;
+ }
if (!sysbus_realize(SYS_BUS_DEVICE(&s->adma[i]), errp)) {
return;
}
@@ -640,14 +660,36 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
gic_spi[adma_ch_intr[i]]);
}
+ if (!object_property_set_link(OBJECT(&s->qspi_dma), "dma",
+ OBJECT(system_memory), errp)) {
+ return;
+ }
if (!sysbus_realize(SYS_BUS_DEVICE(&s->qspi_dma), errp)) {
return;
}
sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi_dma), 0, QSPI_DMA_ADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi_dma), 0, gic_spi[QSPI_IRQ]);
- object_property_set_link(OBJECT(&s->qspi), "stream-connected-dma",
- OBJECT(&s->qspi_dma), errp);
+
+ if (!object_property_set_link(OBJECT(&s->qspi), "stream-connected-dma",
+ OBJECT(&s->qspi_dma), errp)) {
+ return;
+ }
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->qspi), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 0, QSPI_ADDR);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 1, LQSPI_ADDR);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi), 0, gic_spi[QSPI_IRQ]);
+
+ for (i = 0; i < XLNX_ZYNQMP_NUM_QSPI_BUS; i++) {
+ g_autofree gchar *bus_name = g_strdup_printf("qspi%d", i);
+ g_autofree gchar *target_bus = g_strdup_printf("spi%d", i);
+
+ /* Alias controller SPI bus to the SoC itself */
+ object_property_add_alias(OBJECT(s), bus_name,
+ OBJECT(&s->qspi), target_bus);
+ }
}
static Property xlnx_zynqmp_props[] = {
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 5b34869a54..c623318b73 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -555,24 +555,35 @@ ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, size_t srclen)
/* skip header */
i = 10;
+ if (srclen < 4) {
+ goto toosmall;
+ }
flags = src[3];
if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
puts ("Error: Bad gzipped data\n");
return -1;
}
- if ((flags & EXTRA_FIELD) != 0)
+ if ((flags & EXTRA_FIELD) != 0) {
+ if (srclen < 12) {
+ goto toosmall;
+ }
i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
+ }
+ if ((flags & ORIG_NAME) != 0) {
+ while (i < srclen && src[i++] != 0) {
+ /* do nothing */
+ }
+ }
+ if ((flags & COMMENT) != 0) {
+ while (i < srclen && src[i++] != 0) {
+ /* do nothing */
+ }
+ }
+ if ((flags & HEAD_CRC) != 0) {
i += 2;
+ }
if (i >= srclen) {
- puts ("Error: gunzip out of data in header\n");
- return -1;
+ goto toosmall;
}
s.zalloc = zalloc;
@@ -596,6 +607,10 @@ ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, size_t srclen)
inflateEnd(&s);
return dstbytes;
+
+toosmall:
+ puts("Error: gunzip out of data in header\n");
+ return -1;
}
/* Load a U-Boot image. */
diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c
index fa38a55634..a5a92b4ff8 100644
--- a/hw/dma/xlnx-zdma.c
+++ b/hw/dma/xlnx-zdma.c
@@ -320,9 +320,9 @@ static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr,
return false;
}
- descr->addr = address_space_ldq_le(s->dma_as, addr, s->attr, NULL);
- descr->size = address_space_ldl_le(s->dma_as, addr + 8, s->attr, NULL);
- descr->attr = address_space_ldl_le(s->dma_as, addr + 12, s->attr, NULL);
+ descr->addr = address_space_ldq_le(&s->dma_as, addr, s->attr, NULL);
+ descr->size = address_space_ldl_le(&s->dma_as, addr + 8, s->attr, NULL);
+ descr->attr = address_space_ldl_le(&s->dma_as, addr + 12, s->attr, NULL);
return true;
}
@@ -354,7 +354,7 @@ static void zdma_update_descr_addr(XlnxZDMA *s, bool type,
} else {
addr = zdma_get_regaddr64(s, basereg);
addr += sizeof(s->dsc_dst);
- next = address_space_ldq_le(s->dma_as, addr, s->attr, NULL);
+ next = address_space_ldq_le(&s->dma_as, addr, s->attr, NULL);
}
zdma_put_regaddr64(s, basereg, next);
@@ -421,7 +421,7 @@ static void zdma_write_dst(XlnxZDMA *s, uint8_t *buf, uint32_t len)
}
}
- address_space_write(s->dma_as, s->dsc_dst.addr, s->attr, buf, dlen);
+ address_space_write(&s->dma_as, s->dsc_dst.addr, s->attr, buf, dlen);
if (burst_type == AXI_BURST_INCR) {
s->dsc_dst.addr += dlen;
}
@@ -497,7 +497,7 @@ static void zdma_process_descr(XlnxZDMA *s)
len = s->cfg.bus_width / 8;
}
} else {
- address_space_read(s->dma_as, src_addr, s->attr, s->buf, len);
+ address_space_read(&s->dma_as, src_addr, s->attr, s->buf, len);
if (burst_type == AXI_BURST_INCR) {
src_addr += len;
}
@@ -765,6 +765,12 @@ static void zdma_realize(DeviceState *dev, Error **errp)
XlnxZDMA *s = XLNX_ZDMA(dev);
unsigned int i;
+ if (!s->dma_mr) {
+ error_setg(errp, TYPE_XLNX_ZDMA " 'dma' link not set");
+ return;
+ }
+ address_space_init(&s->dma_as, s->dma_mr, "zdma-dma");
+
for (i = 0; i < ARRAY_SIZE(zdma_regs_info); ++i) {
RegisterInfo *r = &s->regs_info[zdma_regs_info[i].addr / 4];
@@ -777,12 +783,6 @@ static void zdma_realize(DeviceState *dev, Error **errp)
};
}
- if (s->dma_mr) {
- s->dma_as = g_malloc0(sizeof(AddressSpace));
- address_space_init(s->dma_as, s->dma_mr, NULL);
- } else {
- s->dma_as = &address_space_memory;
- }
s->attr = MEMTXATTRS_UNSPECIFIED;
}
diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
index 797b4fed8f..896bb3574d 100644
--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -201,11 +201,11 @@ static uint32_t xlnx_csu_dma_read(XlnxCSUDMA *s, uint8_t *buf, uint32_t len)
for (i = 0; i < len && (result == MEMTX_OK); i += s->width) {
uint32_t mlen = MIN(len - i, s->width);
- result = address_space_rw(s->dma_as, addr, s->attr,
+ result = address_space_rw(&s->dma_as, addr, s->attr,
buf + i, mlen, false);
}
} else {
- result = address_space_rw(s->dma_as, addr, s->attr, buf, len, false);
+ result = address_space_rw(&s->dma_as, addr, s->attr, buf, len, false);
}
if (result == MEMTX_OK) {
@@ -232,12 +232,12 @@ static uint32_t xlnx_csu_dma_write(XlnxCSUDMA *s, uint8_t *buf, uint32_t len)
for (i = 0; i < len && (result == MEMTX_OK); i += s->width) {
uint32_t mlen = MIN(len - i, s->width);
- result = address_space_rw(s->dma_as, addr, s->attr,
+ result = address_space_rw(&s->dma_as, addr, s->attr,
buf, mlen, true);
buf += mlen;
}
} else {
- result = address_space_rw(s->dma_as, addr, s->attr, buf, len, true);
+ result = address_space_rw(&s->dma_as, addr, s->attr, buf, len, true);
}
if (result != MEMTX_OK) {
@@ -626,6 +626,17 @@ static void xlnx_csu_dma_realize(DeviceState *dev, Error **errp)
XlnxCSUDMA *s = XLNX_CSU_DMA(dev);
RegisterInfoArray *reg_array;
+ if (!s->is_dst && !s->tx_dev) {
+ error_setg(errp, "zynqmp.csu-dma: Stream not connected");
+ return;
+ }
+
+ if (!s->dma_mr) {
+ error_setg(errp, TYPE_XLNX_CSU_DMA " 'dma' link not set");
+ return;
+ }
+ address_space_init(&s->dma_as, s->dma_mr, "csu-dma");
+
reg_array =
register_init_block32(dev, xlnx_csu_dma_regs_info[!!s->is_dst],
XLNX_CSU_DMA_R_MAX,
@@ -640,21 +651,9 @@ static void xlnx_csu_dma_realize(DeviceState *dev, Error **errp)
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
- if (!s->is_dst && !s->tx_dev) {
- error_setg(errp, "zynqmp.csu-dma: Stream not connected");
- return;
- }
-
s->src_timer = ptimer_init(xlnx_csu_dma_src_timeout_hit,
s, PTIMER_POLICY_DEFAULT);
- if (s->dma_mr) {
- s->dma_as = g_malloc0(sizeof(AddressSpace));
- address_space_init(s->dma_as, s->dma_mr, NULL);
- } else {
- s->dma_as = &address_space_memory;
- }
-
s->attr = MEMTXATTRS_UNSPECIFIED;
s->r_size_last_word = 0;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c2b9d62a35..102b223946 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -65,7 +65,6 @@
#include "hw/xen/start_info.h"
#include "ui/qemu-spice.h"
#include "exec/memory.h"
-#include "sysemu/arch_init.h"
#include "qemu/bitmap.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 30b8bd6ea9..1bc30167ac 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -43,7 +43,6 @@
#include "sysemu/kvm.h"
#include "hw/kvm/clock.h"
#include "hw/sysbus.h"
-#include "sysemu/arch_init.h"
#include "hw/i2c/smbus_eeprom.h"
#include "hw/xen/xen-x86.h"
#include "exec/memory.h"
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 04b4a4788d..eeb0b185b1 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -31,7 +31,6 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "hw/loader.h"
-#include "sysemu/arch_init.h"
#include "hw/i2c/smbus_eeprom.h"
#include "hw/rtc/mc146818rtc.h"
#include "sysemu/kvm.h"
diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index d6183e1882..f5a26e174d 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -35,7 +35,6 @@
#include "hw/isa/isa.h"
#include "hw/block/fdc.h"
#include "sysemu/sysemu.h"
-#include "sysemu/arch_init.h"
#include "hw/boards.h"
#include "net/net.h"
#include "hw/scsi/esp.h"
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 7dcf175d72..b770b8d367 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -38,7 +38,6 @@
#include "hw/mips/mips.h"
#include "hw/mips/cpudevs.h"
#include "hw/pci/pci.h"
-#include "sysemu/arch_init.h"
#include "qemu/log.h"
#include "hw/mips/bios.h"
#include "hw/ide.h"
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index acfc2a91d8..25a2e86b42 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -40,7 +40,6 @@
#include "hw/rtc/mc146818rtc.h"
#include "hw/isa/pc87312.h"
#include "hw/qdev-properties.h"
-#include "sysemu/arch_init.h"
#include "sysemu/kvm.h"
#include "sysemu/reset.h"
#include "trace.h"
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index ddc658c8d6..5b7b245e1f 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -45,7 +45,6 @@
#include "hw/intc/sifive_plic.h"
#include "hw/misc/sifive_e_prci.h"
#include "chardev/char.h"
-#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
static const MemMapEntry sifive_e_memmap[] = {
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 87bbd10b21..6cc1a62b0f 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -55,7 +55,6 @@
#include "hw/intc/sifive_plic.h"
#include "chardev/char.h"
#include "net/eth.h"
-#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index fead77f0c4..aae36f2cb4 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -37,7 +37,6 @@
#include "hw/char/riscv_htif.h"
#include "hw/intc/sifive_clint.h"
#include "chardev/char.h"
-#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "sysemu/sysemu.h"
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4a3cd2599a..0e55411045 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -36,7 +36,6 @@
#include "hw/intc/sifive_plic.h"
#include "hw/misc/sifive_test.h"
#include "chardev/char.h"
-#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "sysemu/sysemu.h"
#include "hw/pci/pci.h"
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 22a8fa5d11..9b79051747 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -167,6 +167,8 @@ struct Versal {
#define MM_IOU_SCNTRS_SIZE 0x10000
#define MM_FPD_CRF 0xfd1a0000U
#define MM_FPD_CRF_SIZE 0x140000
+#define MM_FPD_FPD_APU 0xfd5c0000
+#define MM_FPD_FPD_APU_SIZE 0x100
#define MM_PMC_SD0 0xf1040000U
#define MM_PMC_SD0_SIZE 0x10000
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index d3e2ef97f6..c84fe15996 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -79,6 +79,11 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
+/*
+ * Unimplemented mmio regions needed to boot some images.
+ */
+#define XLNX_ZYNQMP_NUM_UNIMP_AREAS 1
+
struct XlnxZynqMPState {
/*< private >*/
DeviceState parent_obj;
@@ -96,6 +101,8 @@ struct XlnxZynqMPState {
MemoryRegion *ddr_ram;
MemoryRegion ddr_ram_low, ddr_ram_high;
+ MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS];
+
CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN];
diff --git a/include/hw/dma/xlnx-zdma.h b/include/hw/dma/xlnx-zdma.h
index 6602e7ffa7..efc75217d5 100644
--- a/include/hw/dma/xlnx-zdma.h
+++ b/include/hw/dma/xlnx-zdma.h
@@ -56,7 +56,7 @@ struct XlnxZDMA {
MemoryRegion iomem;
MemTxAttrs attr;
MemoryRegion *dma_mr;
- AddressSpace *dma_as;
+ AddressSpace dma_as;
qemu_irq irq_zdma_ch_imr;
struct {
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 204d94c673..9e9dc551e9 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -30,7 +30,7 @@ typedef struct XlnxCSUDMA {
MemoryRegion iomem;
MemTxAttrs attr;
MemoryRegion *dma_mr;
- AddressSpace *dma_as;
+ AddressSpace dma_as;
qemu_irq irq;
StreamSink *tx_dev; /* Used as generic StreamSink */
ptimer_state *src_timer;
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index e723c467eb..70c579560a 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -23,22 +23,9 @@ enum {
QEMU_ARCH_RISCV = (1 << 19),
QEMU_ARCH_RX = (1 << 20),
QEMU_ARCH_AVR = (1 << 21),
-
- QEMU_ARCH_NONE = (1 << 31),
+ QEMU_ARCH_HEXAGON = (1 << 22),
};
extern const uint32_t arch_type;
-int kvm_available(void);
-int xen_available(void);
-
-/* default virtio transport per architecture */
-#define QEMU_ARCH_VIRTIO_PCI (QEMU_ARCH_ALPHA | QEMU_ARCH_ARM | \
- QEMU_ARCH_HPPA | QEMU_ARCH_I386 | \
- QEMU_ARCH_MIPS | QEMU_ARCH_PPC | \
- QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \
- QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA)
-#define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X)
-#define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K)
-
#endif
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
index 32b68ee302..1dfcfd2d57 100644
--- a/linux-user/arm/signal.c
+++ b/linux-user/arm/signal.c
@@ -289,7 +289,6 @@ setup_return(CPUARMState *env, struct target_sigaction *ka,
env->regs[14] = retcode;
env->regs[15] = handler & (thumb ? ~1 : ~3);
cpsr_write(env, cpsr, CPSR_IT | CPSR_T | CPSR_E, CPSRWriteByInstr);
- arm_rebuild_hflags(env);
return 0;
}
@@ -547,7 +546,6 @@ restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
__get_user(env->regs[15], &sc->arm_pc);
__get_user(cpsr, &sc->arm_cpsr);
cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
- arm_rebuild_hflags(env);
err |= !valid_user_regs(env);
diff --git a/meson.build b/meson.build
index b3e7ec0e92..bf63784812 100644
--- a/meson.build
+++ b/meson.build
@@ -1625,6 +1625,8 @@ foreach target : target_dirs
config_target_data.set(k, v)
endif
endforeach
+ config_target_data.set('QEMU_ARCH',
+ 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
config_target_h += {target: configure_file(output: target + '-config-target.h',
configuration: config_target_data)}
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index f7d64a6457..5c0d5e116b 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -27,7 +27,6 @@
#include "sysemu/kvm.h"
#include "sysemu/runstate.h"
#include "sysemu/runstate-action.h"
-#include "sysemu/arch_init.h"
#include "sysemu/blockdev.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
@@ -58,7 +57,7 @@ KvmInfo *qmp_query_kvm(Error **errp)
KvmInfo *info = g_malloc0(sizeof(*info));
info->enabled = kvm_enabled();
- info->present = kvm_available();
+ info->present = accel_find("kvm");
return info;
}
diff --git a/net/net.c b/net/net.c
index 76bbb7c31b..52c99196c6 100644
--- a/net/net.c
+++ b/net/net.c
@@ -75,6 +75,8 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str,
const char *addr, *p, *r;
int port, ret = 0;
+ memset(saddr, 0, sizeof(*saddr));
+
substrings = g_strsplit(str, ":", 2);
if (!substrings || !substrings[0] || !substrings[1]) {
error_setg(errp, "host address '%s' doesn't contain ':' "
diff --git a/softmmu/arch_init.c b/softmmu/arch_init.c
index 6ff9f30bad..8919405c7b 100644
--- a/softmmu/arch_init.c
+++ b/softmmu/arch_init.c
@@ -23,13 +23,6 @@
*/
#include "qemu/osdep.h"
#include "sysemu/arch_init.h"
-#include "hw/pci/pci.h"
-#include "hw/audio/soundhw.h"
-#include "qapi/error.h"
-#include "qemu/config-file.h"
-#include "qemu/error-report.h"
-#include "hw/acpi/acpi.h"
-#include "qemu/help_option.h"
#ifdef TARGET_SPARC
int graphic_width = 1024;
@@ -45,63 +38,4 @@ int graphic_height = 600;
int graphic_depth = 32;
#endif
-
-#if defined(TARGET_ALPHA)
-#define QEMU_ARCH QEMU_ARCH_ALPHA
-#elif defined(TARGET_ARM)
-#define QEMU_ARCH QEMU_ARCH_ARM
-#elif defined(TARGET_CRIS)
-#define QEMU_ARCH QEMU_ARCH_CRIS
-#elif defined(TARGET_HPPA)
-#define QEMU_ARCH QEMU_ARCH_HPPA
-#elif defined(TARGET_I386)
-#define QEMU_ARCH QEMU_ARCH_I386
-#elif defined(TARGET_M68K)
-#define QEMU_ARCH QEMU_ARCH_M68K
-#elif defined(TARGET_MICROBLAZE)
-#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
-#elif defined(TARGET_MIPS)
-#define QEMU_ARCH QEMU_ARCH_MIPS
-#elif defined(TARGET_NIOS2)
-#define QEMU_ARCH QEMU_ARCH_NIOS2
-#elif defined(TARGET_OPENRISC)
-#define QEMU_ARCH QEMU_ARCH_OPENRISC
-#elif defined(TARGET_PPC)
-#define QEMU_ARCH QEMU_ARCH_PPC
-#elif defined(TARGET_RISCV)
-#define QEMU_ARCH QEMU_ARCH_RISCV
-#elif defined(TARGET_RX)
-#define QEMU_ARCH QEMU_ARCH_RX
-#elif defined(TARGET_S390X)
-#define QEMU_ARCH QEMU_ARCH_S390X
-#elif defined(TARGET_SH4)
-#define QEMU_ARCH QEMU_ARCH_SH4
-#elif defined(TARGET_SPARC)
-#define QEMU_ARCH QEMU_ARCH_SPARC
-#elif defined(TARGET_TRICORE)
-#define QEMU_ARCH QEMU_ARCH_TRICORE
-#elif defined(TARGET_XTENSA)
-#define QEMU_ARCH QEMU_ARCH_XTENSA
-#elif defined(TARGET_AVR)
-#define QEMU_ARCH QEMU_ARCH_AVR
-#endif
-
const uint32_t arch_type = QEMU_ARCH;
-
-int kvm_available(void)
-{
-#ifdef CONFIG_KVM
- return 1;
-#else
- return 0;
-#endif
-}
-
-int xen_available(void)
-{
-#ifdef CONFIG_XEN
- return 1;
-#else
- return 0;
-#endif
-}
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 2e18947598..23e77cb771 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -1451,6 +1451,9 @@ static int64_t get_file_align(int fd)
path = g_strdup_printf("/sys/dev/char/%d:%d",
major(st.st_rdev), minor(st.st_rdev));
rpath = realpath(path, NULL);
+ if (!rpath) {
+ return -errno;
+ }
rc = daxctl_new(&ctx);
if (rc) {
@@ -2075,7 +2078,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
}
file_align = get_file_align(fd);
- if (file_align > 0 && mr && file_align > mr->align) {
+ if (file_align > 0 && file_align > mr->align) {
error_setg(errp, "backing store align 0x%" PRIx64
" is larger than 'align' option 0x%" PRIx64,
file_align, mr->align);
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 721dec2d82..a304754ab9 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -52,6 +52,15 @@ typedef struct QDevAlias
uint32_t arch_mask;
} QDevAlias;
+/* default virtio transport per architecture */
+#define QEMU_ARCH_VIRTIO_PCI (QEMU_ARCH_ALPHA | QEMU_ARCH_ARM | \
+ QEMU_ARCH_HPPA | QEMU_ARCH_I386 | \
+ QEMU_ARCH_MIPS | QEMU_ARCH_PPC | \
+ QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \
+ QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA)
+#define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X)
+#define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K)
+
/* Please keep this table sorted by typename. */
static const QDevAlias qdev_alias_table[] = {
{ "AC97", "ac97" }, /* -soundhw name */
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 5ca11e7469..82d574fe4b 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -3448,21 +3448,21 @@ void qemu_init(int argc, char **argv, char **envp)
has_defaults = 0;
break;
case QEMU_OPTION_xen_domid:
- if (!(xen_available())) {
+ if (!(accel_find("xen"))) {
error_report("Option not supported for this target");
exit(1);
}
xen_domid = atoi(optarg);
break;
case QEMU_OPTION_xen_attach:
- if (!(xen_available())) {
+ if (!(accel_find("xen"))) {
error_report("Option not supported for this target");
exit(1);
}
xen_mode = XEN_ATTACH;
break;
case QEMU_OPTION_xen_domid_restrict:
- if (!(xen_available())) {
+ if (!(accel_find("xen"))) {
error_report("Option not supported for this target");
exit(1);
}
diff --git a/stubs/arch_type.c b/stubs/arch_type.c
deleted file mode 100644
index fc5423bc98..0000000000
--- a/stubs/arch_type.c
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "qemu/osdep.h"
-#include "sysemu/arch_init.h"
-
-const uint32_t arch_type = QEMU_ARCH_NONE;
diff --git a/stubs/meson.build b/stubs/meson.build
index d3fa8646b3..717bfa9a99 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -1,4 +1,3 @@
-stub_ss.add(files('arch_type.c'))
stub_ss.add(files('bdrv-next-monitor-owned.c'))
stub_ss.add(files('blk-commit-all.c'))
stub_ss.add(files('blk-exp-close-all.c'))
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index a82e39dd97..d631c4683c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1422,6 +1422,29 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
}
+ if (kvm_enabled()) {
+ /*
+ * Catch all the cases which might cause us to create more than one
+ * address space for the CPU (otherwise we will assert() later in
+ * cpu_address_space_init()).
+ */
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ error_setg(errp,
+ "Cannot enable KVM when using an M-profile guest CPU");
+ return;
+ }
+ if (cpu->has_el3) {
+ error_setg(errp,
+ "Cannot enable KVM when guest CPU has EL3 enabled");
+ return;
+ }
+ if (cpu->tag_memory) {
+ error_setg(errp,
+ "Cannot enable KVM when guest CPUs has MTE enabled");
+ return;
+ }
+ }
+
{
uint64_t scale;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 5cf8996ae3..6a987f65e4 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1020,9 +1020,13 @@ struct ARMCPU {
* While processing properties during initialization, corresponding
* sve_vq_init bits are set for bits in sve_vq_map that have been
* set by properties.
+ *
+ * Bits set in sve_vq_supported represent valid vector lengths for
+ * the CPU type.
*/
DECLARE_BITMAP(sve_vq_map, ARM_MAX_VQ);
DECLARE_BITMAP(sve_vq_init, ARM_MAX_VQ);
+ DECLARE_BITMAP(sve_vq_supported, ARM_MAX_VQ);
/* Generic timer counter frequency, in Hz */
uint64_t gt_cntfrq_hz;
@@ -1394,11 +1398,17 @@ uint32_t cpsr_read(CPUARMState *env);
typedef enum CPSRWriteType {
CPSRWriteByInstr = 0, /* from guest MSR or CPS */
CPSRWriteExceptionReturn = 1, /* from guest exception return insn */
- CPSRWriteRaw = 2, /* trust values, do not switch reg banks */
+ CPSRWriteRaw = 2,
+ /* trust values, no reg bank switch, no hflags rebuild */
CPSRWriteByGDBStub = 3, /* from the GDB stub */
} CPSRWriteType;
-/* Set the CPSR. Note that some bits of mask must be all-set or all-clear.*/
+/*
+ * Set the CPSR. Note that some bits of mask must be all-set or all-clear.
+ * This will do an arm_rebuild_hflags() if any of the bits in @mask
+ * correspond to TB flags bits cached in the hflags, unless @write_type
+ * is CPSRWriteRaw.
+ */
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
CPSRWriteType write_type);
@@ -1537,6 +1547,9 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
#define SCR_ENSCXT (1U << 25)
#define SCR_ATA (1U << 26)
+#define HSTR_TTEE (1 << 16)
+#define HSTR_TJDBX (1 << 17)
+
/* Return the current FPSCR value. */
uint32_t vfp_get_fpscr(CPUARMState *env);
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index c690318a9b..2f0cbddab5 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -265,14 +265,17 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
* any of the above. Finally, if SVE is not disabled, then at least one
* vector length must be enabled.
*/
- DECLARE_BITMAP(kvm_supported, ARM_MAX_VQ);
DECLARE_BITMAP(tmp, ARM_MAX_VQ);
uint32_t vq, max_vq = 0;
- /* Collect the set of vector lengths supported by KVM. */
- bitmap_zero(kvm_supported, ARM_MAX_VQ);
+ /*
+ * CPU models specify a set of supported vector lengths which are
+ * enabled by default. Attempting to enable any vector length not set
+ * in the supported bitmap results in an error. When KVM is enabled we
+ * fetch the supported bitmap from the host.
+ */
if (kvm_enabled() && kvm_arm_sve_supported()) {
- kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
+ kvm_arm_sve_get_vls(CPU(cpu), cpu->sve_vq_supported);
} else if (kvm_enabled()) {
assert(!cpu_isar_feature(aa64_sve, cpu));
}
@@ -299,7 +302,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
* For KVM we have to automatically enable all supported unitialized
* lengths, even when the smaller lengths are not all powers-of-two.
*/
- bitmap_andnot(tmp, kvm_supported, cpu->sve_vq_init, max_vq);
+ bitmap_andnot(tmp, cpu->sve_vq_supported, cpu->sve_vq_init, max_vq);
bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq);
} else {
/* Propagate enabled bits down through required powers-of-two. */
@@ -322,39 +325,30 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
/* Disabling a supported length disables all larger lengths. */
for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
if (test_bit(vq - 1, cpu->sve_vq_init) &&
- test_bit(vq - 1, kvm_supported)) {
+ test_bit(vq - 1, cpu->sve_vq_supported)) {
break;
}
}
- max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
- bitmap_andnot(cpu->sve_vq_map, kvm_supported,
- cpu->sve_vq_init, max_vq);
- if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
- error_setg(errp, "cannot disable sve%d", vq * 128);
- error_append_hint(errp, "Disabling sve%d results in all "
- "vector lengths being disabled.\n",
- vq * 128);
- error_append_hint(errp, "With SVE enabled, at least one "
- "vector length must be enabled.\n");
- return;
- }
} else {
/* Disabling a power-of-two disables all larger lengths. */
- if (test_bit(0, cpu->sve_vq_init)) {
- error_setg(errp, "cannot disable sve128");
- error_append_hint(errp, "Disabling sve128 results in all "
- "vector lengths being disabled.\n");
- error_append_hint(errp, "With SVE enabled, at least one "
- "vector length must be enabled.\n");
- return;
- }
- for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
+ for (vq = 1; vq <= ARM_MAX_VQ; vq <<= 1) {
if (test_bit(vq - 1, cpu->sve_vq_init)) {
break;
}
}
- max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
- bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
+ }
+
+ max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
+ bitmap_andnot(cpu->sve_vq_map, cpu->sve_vq_supported,
+ cpu->sve_vq_init, max_vq);
+ if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
+ error_setg(errp, "cannot disable sve%d", vq * 128);
+ error_append_hint(errp, "Disabling sve%d results in all "
+ "vector lengths being disabled.\n",
+ vq * 128);
+ error_append_hint(errp, "With SVE enabled, at least one "
+ "vector length must be enabled.\n");
+ return;
}
max_vq = find_last_bit(cpu->sve_vq_map, max_vq) + 1;
@@ -390,46 +384,44 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
assert(max_vq != 0);
bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq);
- if (kvm_enabled()) {
- /* Ensure the set of lengths matches what KVM supports. */
- bitmap_xor(tmp, cpu->sve_vq_map, kvm_supported, max_vq);
- if (!bitmap_empty(tmp, max_vq)) {
- vq = find_last_bit(tmp, max_vq) + 1;
- if (test_bit(vq - 1, cpu->sve_vq_map)) {
- if (cpu->sve_max_vq) {
- error_setg(errp, "cannot set sve-max-vq=%d",
- cpu->sve_max_vq);
- error_append_hint(errp, "This KVM host does not support "
- "the vector length %d-bits.\n",
- vq * 128);
- error_append_hint(errp, "It may not be possible to use "
- "sve-max-vq with this KVM host. Try "
- "using only sve<N> properties.\n");
- } else {
- error_setg(errp, "cannot enable sve%d", vq * 128);
- error_append_hint(errp, "This KVM host does not support "
- "the vector length %d-bits.\n",
- vq * 128);
- }
+ /* Ensure the set of lengths matches what is supported. */
+ bitmap_xor(tmp, cpu->sve_vq_map, cpu->sve_vq_supported, max_vq);
+ if (!bitmap_empty(tmp, max_vq)) {
+ vq = find_last_bit(tmp, max_vq) + 1;
+ if (test_bit(vq - 1, cpu->sve_vq_map)) {
+ if (cpu->sve_max_vq) {
+ error_setg(errp, "cannot set sve-max-vq=%d", cpu->sve_max_vq);
+ error_append_hint(errp, "This CPU does not support "
+ "the vector length %d-bits.\n", vq * 128);
+ error_append_hint(errp, "It may not be possible to use "
+ "sve-max-vq with this CPU. Try "
+ "using only sve<N> properties.\n");
} else {
+ error_setg(errp, "cannot enable sve%d", vq * 128);
+ error_append_hint(errp, "This CPU does not support "
+ "the vector length %d-bits.\n", vq * 128);
+ }
+ return;
+ } else {
+ if (kvm_enabled()) {
error_setg(errp, "cannot disable sve%d", vq * 128);
error_append_hint(errp, "The KVM host requires all "
"supported vector lengths smaller "
"than %d bits to also be enabled.\n",
max_vq * 128);
- }
- return;
- }
- } else {
- /* Ensure all required powers-of-two are enabled. */
- for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
- if (!test_bit(vq - 1, cpu->sve_vq_map)) {
- error_setg(errp, "cannot disable sve%d", vq * 128);
- error_append_hint(errp, "sve%d is required as it "
- "is a power-of-two length smaller than "
- "the maximum, sve%d\n",
- vq * 128, max_vq * 128);
return;
+ } else {
+ /* Ensure all required powers-of-two are enabled. */
+ for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
+ if (!test_bit(vq - 1, cpu->sve_vq_map)) {
+ error_setg(errp, "cannot disable sve%d", vq * 128);
+ error_append_hint(errp, "sve%d is required as it "
+ "is a power-of-two length smaller "
+ "than the maximum, sve%d\n",
+ vq * 128, max_vq * 128);
+ return;
+ }
+ }
}
}
}
@@ -840,6 +832,8 @@ static void aarch64_max_initfn(Object *obj)
/* Default to PAUTH on, with the architected algorithm. */
qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_property);
qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_impdef_property);
+
+ bitmap_fill(cpu->sve_vq_supported, ARM_MAX_VQ);
}
aarch64_add_sve_properties(obj);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 56c520cf8e..a7ae78146d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2446,20 +2446,34 @@ static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
env->teecr = value;
}
+static CPAccessResult teecr_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ /*
+ * HSTR.TTEE only exists in v7A, not v8A, but v8A doesn't have T2EE
+ * at all, so we don't need to check whether we're v8A.
+ */
+ if (arm_current_el(env) < 2 && !arm_is_secure_below_el3(env) &&
+ (env->cp15.hstr_el2 & HSTR_TTEE)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ return CP_ACCESS_OK;
+}
+
static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
if (arm_current_el(env) == 0 && (env->teecr & 1)) {
return CP_ACCESS_TRAP;
}
- return CP_ACCESS_OK;
+ return teecr_access(env, ri, isread);
}
static const ARMCPRegInfo t2ee_cp_reginfo[] = {
{ .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr),
.resetvalue = 0,
- .writefn = teecr_write },
+ .writefn = teecr_write, .accessfn = teecr_access },
{ .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
.accessfn = teehbr_access, .resetvalue = 0 },
@@ -7588,6 +7602,21 @@ static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
return CP_ACCESS_OK;
}
+static CPAccessResult access_joscr_jmcr(CPUARMState *env,
+ const ARMCPRegInfo *ri, bool isread)
+{
+ /*
+ * HSTR.TJDBX traps JOSCR and JMCR accesses, but it exists only
+ * in v7A, not in v8A.
+ */
+ if (!arm_feature(env, ARM_FEATURE_V8) &&
+ arm_current_el(env) < 2 && !arm_is_secure_below_el3(env) &&
+ (env->cp15.hstr_el2 & HSTR_TJDBX)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ return CP_ACCESS_OK;
+}
+
static const ARMCPRegInfo jazelle_regs[] = {
{ .name = "JIDR",
.cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
@@ -7595,9 +7624,11 @@ static const ARMCPRegInfo jazelle_regs[] = {
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "JOSCR",
.cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
+ .accessfn = access_joscr_jmcr,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "JMCR",
.cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
+ .accessfn = access_joscr_jmcr,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -9215,6 +9246,8 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
CPSRWriteType write_type)
{
uint32_t changed_daif;
+ bool rebuild_hflags = (write_type != CPSRWriteRaw) &&
+ (mask & (CPSR_M | CPSR_E | CPSR_IL));
if (mask & CPSR_NZCV) {
env->ZF = (~val) & CPSR_Z;
@@ -9334,6 +9367,9 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
}
mask &= ~CACHED_CPSR_BITS;
env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
+ if (rebuild_hflags) {
+ arm_rebuild_hflags(env);
+ }
}
/* Sign/zero extend */
diff --git a/target/arm/helper.h b/target/arm/helper.h
index aee8f0019b..448a86edfd 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -73,6 +73,8 @@ DEF_HELPER_2(v7m_vlldm, void, env, i32)
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
+DEF_HELPER_FLAGS_2(check_bxj_trap, TCG_CALL_NO_WG, void, env, i32)
+
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
DEF_HELPER_2(get_cp_reg, i32, env, ptr)
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 59982d470d..e790d6c9a5 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -740,7 +740,7 @@ void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map)
uint32_t vq = 0;
int i, j;
- bitmap_clear(map, 0, ARM_MAX_VQ);
+ bitmap_zero(map, ARM_MAX_VQ);
/*
* KVM ensures all host CPUs support the same set of vector lengths.
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index e98fd86305..70b42b55fd 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -224,6 +224,22 @@ void HELPER(setend)(CPUARMState *env)
arm_rebuild_hflags(env);
}
+void HELPER(check_bxj_trap)(CPUARMState *env, uint32_t rm)
+{
+ /*
+ * Only called if in NS EL0 or EL1 for a BXJ for a v7A CPU;
+ * check if HSTR.TJDBX means we need to trap to EL2.
+ */
+ if (env->cp15.hstr_el2 & HSTR_TJDBX) {
+ /*
+ * We know the condition code check passed, so take the IMPDEF
+ * choice to always report CV=1 COND 0xe
+ */
+ uint32_t syn = syn_bxjtrap(1, 0xe, rm);
+ raise_exception_ra(env, EXCP_HYP_TRAP, syn, 2, GETPC());
+ }
+}
+
#ifndef CONFIG_USER_ONLY
/* Function checks whether WFx (WFI/WFE) instructions are set up to be trapped.
* The function returns the target EL (1-3) if the instruction is to be trapped;
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 39a31260f2..8dd88a0cb1 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -36,6 +36,7 @@ enum arm_exception_class {
EC_ADVSIMDFPACCESSTRAP = 0x07,
EC_FPIDTRAP = 0x08,
EC_PACTRAP = 0x09,
+ EC_BXJTRAP = 0x0a,
EC_CP14RRTTRAP = 0x0c,
EC_BTITRAP = 0x0d,
EC_ILLEGALSTATE = 0x0e,
@@ -215,6 +216,12 @@ static inline uint32_t syn_btitrap(int btype)
return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype;
}
+static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
+{
+ return (EC_BXJTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL |
+ (cv << 24) | (cond << 20) | rm;
+}
+
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
{
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 115aa768b6..24b7f49d76 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -6440,6 +6440,18 @@ static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
return false;
}
+ /*
+ * v7A allows BXJ to be trapped via HSTR.TJDBX. We don't waste a
+ * TBFLAGS bit on a basically-never-happens case, so call a helper
+ * function to check for the trap and raise the exception if needed
+ * (passing it the register number for the syndrome value).
+ * v8A doesn't have this HSTR bit.
+ */
+ if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
+ arm_dc_feature(s, ARM_FEATURE_EL2) &&
+ s->current_el < 2 && s->ns) {
+ gen_helper_check_bxj_trap(cpu_env, tcg_constant_i32(a->rm));
+ }
/* Trivial implementation equivalent to bx. */
gen_bx(s, load_reg(s, a->rm));
return true;
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 505a0ed6ac..319a272d4c 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -22,7 +22,6 @@
#include "disas/dis-asm.h"
#include "exec/gdbstub.h"
#include "kvm_ppc.h"
-#include "sysemu/arch_init.h"
#include "sysemu/cpus.h"
#include "sysemu/hw_accel.h"
#include "sysemu/tcg.h"
diff --git a/target/s390x/cpu-sysemu.c b/target/s390x/cpu-sysemu.c
index df2c6bf694..5471e01ee8 100644
--- a/target/s390x/cpu-sysemu.c
+++ b/target/s390x/cpu-sysemu.c
@@ -34,7 +34,6 @@
#include "hw/s390x/pv.h"
#include "hw/boards.h"
-#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "sysemu/tcg.h"
#include "hw/core/sysemu-cpu-ops.h"
diff --git a/tests/qtest/ipmi-bt-test.c b/tests/qtest/ipmi-bt-test.c
index 8492f02a9c..19612e9405 100644
--- a/tests/qtest/ipmi-bt-test.c
+++ b/tests/qtest/ipmi-bt-test.c
@@ -378,7 +378,7 @@ static void test_enable_irq(void)
*/
static void open_socket(void)
{
- struct sockaddr_in myaddr;
+ struct sockaddr_in myaddr = {};
socklen_t addrlen;
myaddr.sin_family = AF_INET;
diff --git a/tests/tcg/multiarch/linux-test.c b/tests/tcg/multiarch/linux-test.c
index c8c6aeddeb..019d8175ca 100644
--- a/tests/tcg/multiarch/linux-test.c
+++ b/tests/tcg/multiarch/linux-test.c
@@ -251,7 +251,7 @@ static void test_time(void)
static int server_socket(void)
{
int val, fd;
- struct sockaddr_in sockaddr;
+ struct sockaddr_in sockaddr = {};
/* server socket */
fd = chk_error(socket(PF_INET, SOCK_STREAM, 0));
@@ -271,7 +271,7 @@ static int server_socket(void)
static int client_socket(uint16_t port)
{
int fd;
- struct sockaddr_in sockaddr;
+ struct sockaddr_in sockaddr = {};
/* server socket */
fd = chk_error(socket(PF_INET, SOCK_STREAM, 0));