2015-05-29 12:28:54 +02:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Copyright (c) 2015 Linaro Limited
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms and conditions of the GNU General Public License,
|
|
|
|
* version 2 or later, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Emulate a virtual board which works by passing Linux all the information
|
|
|
|
* it needs about what devices are present via the device tree.
|
|
|
|
* There are some restrictions about what we can do here:
|
|
|
|
* + we can only present devices whose Linux drivers will work based
|
|
|
|
* purely on the device tree with no platform data at all
|
|
|
|
* + we want to present a very stripped-down minimalist platform,
|
|
|
|
* both because this reduces the security attack surface from the guest
|
|
|
|
* and also because it reduces our exposure to being broken when
|
|
|
|
* the kernel updates its device tree bindings and requires further
|
|
|
|
* information in a device binding that we aren't providing.
|
|
|
|
* This is essentially the same approach kvmtool uses.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef QEMU_ARM_VIRT_H
|
|
|
|
#define QEMU_ARM_VIRT_H
|
|
|
|
|
2016-03-15 16:58:45 +01:00
|
|
|
#include "exec/hwaddr.h"
|
2017-01-09 12:40:22 +01:00
|
|
|
#include "qemu/notify.h"
|
2017-01-09 12:40:22 +01:00
|
|
|
#include "hw/boards.h"
|
2019-05-23 15:47:43 +02:00
|
|
|
#include "hw/arm/boot.h"
|
2023-09-19 11:02:28 +02:00
|
|
|
#include "hw/arm/bsa.h"
|
hw/arm/virt: Support firmware configuration with -blockdev
The ARM virt machines put firmware in flash memory. To configure it,
you use -drive if=pflash,unit=0,... and optionally -drive
if=pflash,unit=1,...
Why two -drive? This permits setting up one part of the flash memory
read-only, and the other part read/write. It also makes upgrading
firmware on the host easier. Below the hood, we get two separate
flash devices, because we were too lazy to improve our flash device
models to support sector protection.
The problem at hand is to do the same with -blockdev somehow, as one
more step towards deprecating -drive.
We recently solved this problem for x86 PC machines, in commit
ebc29e1beab. See the commit message for design rationale.
This commit solves it for ARM virt basically the same way: new machine
properties pflash0, pflash1 forward to the onboard flash devices'
properties. Requires creating the onboard devices in the
.instance_init() method virt_instance_init(). The existing code to
pick up drives defined with -drive if=pflash is replaced by code to
desugar into the machine properties.
There are a few behavioral differences, though:
* The flash devices are always present (x86: only present if
configured)
* Flash base addresses and sizes are fixed (x86: sizes depend on
images, mapped back to back below a fixed address)
* -bios configures contents of first pflash (x86: -bios configures ROM
contents)
* -bios is rejected when first pflash is also configured with -machine
pflash0=... (x86: bios is silently ignored then)
* -machine pflash1=... does not require -machine pflash0=... (x86: it
does).
The actual code is a bit simpler than for x86 mostly due to the first
two differences.
Before the patch, all the action is in create_flash(), called from the
machine's .init() method machvirt_init():
main()
machine_run_board_init()
machvirt_init()
create_flash()
create_one_flash() for flash[0]
create
configure
includes obeying -drive if=pflash,unit=0
realize
map
fall back to -bios
create_one_flash() for flash[1]
create
configure
includes obeying -drive if=pflash,unit=1
realize
map
update FDT
To make the machine properties work, we need to move device creation
to its .instance_init() method virt_instance_init().
Another complication is machvirt_init()'s computation of
@firmware_loaded: it predicts what create_flash() will do. Instead of
predicting what create_flash()'s replacement virt_firmware_init() will
do, I decided to have virt_firmware_init() return what it did.
Requires calling it a bit earlier.
Resulting call tree:
main()
current_machine = object_new()
...
virt_instance_init()
virt_flash_create()
virt_flash_create1() for flash[0]
create
configure: set defaults
become child of machine [NEW]
add machine prop pflash0 as alias for drive [NEW]
virt_flash_create1() for flash[1]
create
configure: set defaults
become child of machine [NEW]
add machine prop pflash1 as alias for drive [NEW]
for all machine props from the command line: machine_set_property()
...
property_set_alias() for machine props pflash0, pflash1
...
set_drive() for cfi.pflash01 prop drive
this is how -machine pflash0=... etc set
machine_run_board_init(current_machine);
virt_firmware_init()
pflash_cfi01_legacy_drive()
legacy -drive if=pflash,unit=0 and =1 [NEW]
virt_flash_map()
virt_flash_map1() for flash[0]
configure: num-blocks
realize
map
virt_flash_map1() for flash[1]
configure: num-blocks
realize
map
fall back to -bios
virt_flash_fdt()
update FDT
You have László to thank for making me explain this in detail.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Message-id: 20190416091348.26075-4-armbru@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-07 13:55:02 +02:00
|
|
|
#include "hw/block/flash.h"
|
2018-06-22 14:28:36 +02:00
|
|
|
#include "sysemu/kvm.h"
|
|
|
|
#include "hw/intc/arm_gicv3_common.h"
|
2020-09-03 22:43:22 +02:00
|
|
|
#include "qom/object.h"
|
2015-05-29 12:28:54 +02:00
|
|
|
|
2015-06-02 15:56:23 +02:00
|
|
|
#define NUM_GICV2M_SPIS 64
|
2015-05-29 12:28:54 +02:00
|
|
|
#define NUM_VIRTIO_TRANSPORTS 32
|
2018-05-04 19:05:52 +02:00
|
|
|
#define NUM_SMMU_IRQS 4
|
2015-05-29 12:28:54 +02:00
|
|
|
|
2020-10-01 08:17:18 +02:00
|
|
|
/* See Linux kernel arch/arm64/include/asm/pvclock-abi.h */
|
|
|
|
#define PVTIME_SIZE_PER_CPU 64
|
|
|
|
|
2015-05-29 12:28:54 +02:00
|
|
|
enum {
|
|
|
|
VIRT_FLASH,
|
|
|
|
VIRT_MEM,
|
|
|
|
VIRT_CPUPERIPHS,
|
|
|
|
VIRT_GIC_DIST,
|
|
|
|
VIRT_GIC_CPU,
|
2015-09-24 02:29:37 +02:00
|
|
|
VIRT_GIC_V2M,
|
2018-08-14 18:17:21 +02:00
|
|
|
VIRT_GIC_HYP,
|
|
|
|
VIRT_GIC_VCPU,
|
2015-09-24 02:29:37 +02:00
|
|
|
VIRT_GIC_ITS,
|
|
|
|
VIRT_GIC_REDIST,
|
2018-05-04 19:05:52 +02:00
|
|
|
VIRT_SMMU,
|
2015-05-29 12:28:54 +02:00
|
|
|
VIRT_UART,
|
|
|
|
VIRT_MMIO,
|
|
|
|
VIRT_RTC,
|
|
|
|
VIRT_FW_CFG,
|
|
|
|
VIRT_PCIE,
|
2015-05-29 12:28:54 +02:00
|
|
|
VIRT_PCIE_MMIO,
|
|
|
|
VIRT_PCIE_PIO,
|
|
|
|
VIRT_PCIE_ECAM,
|
2015-06-02 13:29:13 +02:00
|
|
|
VIRT_PLATFORM_BUS,
|
2015-12-17 14:37:13 +01:00
|
|
|
VIRT_GPIO,
|
2016-01-21 15:15:07 +01:00
|
|
|
VIRT_SECURE_UART,
|
2016-03-04 12:30:17 +01:00
|
|
|
VIRT_SECURE_MEM,
|
2021-01-28 13:00:11 +01:00
|
|
|
VIRT_SECURE_GPIO,
|
2019-09-18 15:06:27 +02:00
|
|
|
VIRT_PCDIMM_ACPI,
|
|
|
|
VIRT_ACPI_GED,
|
2020-04-21 14:59:30 +02:00
|
|
|
VIRT_NVDIMM_ACPI,
|
2020-10-01 08:17:18 +02:00
|
|
|
VIRT_PVTIME,
|
2019-03-04 11:13:32 +01:00
|
|
|
VIRT_LOWMEMMAP_LAST,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* indices of IO regions located after the RAM */
|
|
|
|
enum {
|
|
|
|
VIRT_HIGH_GIC_REDIST2 = VIRT_LOWMEMMAP_LAST,
|
|
|
|
VIRT_HIGH_PCIE_ECAM,
|
|
|
|
VIRT_HIGH_PCIE_MMIO,
|
2015-05-29 12:28:54 +02:00
|
|
|
};
|
|
|
|
|
2018-05-04 19:05:52 +02:00
|
|
|
typedef enum VirtIOMMUType {
|
|
|
|
VIRT_IOMMU_NONE,
|
|
|
|
VIRT_IOMMU_SMMUV3,
|
|
|
|
VIRT_IOMMU_VIRTIO,
|
|
|
|
} VirtIOMMUType;
|
|
|
|
|
2020-07-03 17:59:42 +02:00
|
|
|
typedef enum VirtMSIControllerType {
|
|
|
|
VIRT_MSI_CTRL_NONE,
|
|
|
|
VIRT_MSI_CTRL_GICV2M,
|
|
|
|
VIRT_MSI_CTRL_ITS,
|
|
|
|
} VirtMSIControllerType;
|
|
|
|
|
2020-03-11 14:16:14 +01:00
|
|
|
typedef enum VirtGICType {
|
2022-12-23 10:01:06 +01:00
|
|
|
VIRT_GIC_VERSION_MAX = 0,
|
|
|
|
VIRT_GIC_VERSION_HOST = 1,
|
|
|
|
/* The concrete GIC values have to match the GIC version number */
|
|
|
|
VIRT_GIC_VERSION_2 = 2,
|
|
|
|
VIRT_GIC_VERSION_3 = 3,
|
|
|
|
VIRT_GIC_VERSION_4 = 4,
|
2020-03-11 14:16:15 +01:00
|
|
|
VIRT_GIC_VERSION_NOSEL,
|
2020-03-11 14:16:14 +01:00
|
|
|
} VirtGICType;
|
|
|
|
|
2022-12-23 10:01:06 +01:00
|
|
|
#define VIRT_GIC_VERSION_2_MASK BIT(VIRT_GIC_VERSION_2)
|
|
|
|
#define VIRT_GIC_VERSION_3_MASK BIT(VIRT_GIC_VERSION_3)
|
|
|
|
#define VIRT_GIC_VERSION_4_MASK BIT(VIRT_GIC_VERSION_4)
|
|
|
|
|
2020-09-03 22:43:22 +02:00
|
|
|
struct VirtMachineClass {
|
2017-01-09 12:40:22 +01:00
|
|
|
MachineClass parent;
|
|
|
|
bool disallow_affinity_adjustment;
|
|
|
|
bool no_its;
|
2021-09-13 17:07:24 +02:00
|
|
|
bool no_tcg_its;
|
2017-01-09 12:40:22 +01:00
|
|
|
bool no_pmu;
|
|
|
|
bool claim_edge_triggered_timers;
|
2018-03-23 19:26:46 +01:00
|
|
|
bool smbios_old_sys_ver;
|
hw/arm/virt: Add 'compact-highmem' property
After the improvement to high memory region address assignment is
applied, the memory layout can be changed, introducing possible
migration breakage. For example, VIRT_HIGH_PCIE_MMIO memory region
is disabled or enabled when the optimization is applied or not, with
the following configuration. The configuration is only achievable by
modifying the source code until more properties are added to allow
users selectively disable those high memory regions.
pa_bits = 40;
vms->highmem_redists = false;
vms->highmem_ecam = false;
vms->highmem_mmio = true;
# qemu-system-aarch64 -accel kvm -cpu host \
-machine virt-7.2,compact-highmem={on, off} \
-m 4G,maxmem=511G -monitor stdio
Region compact-highmem=off compact-highmem=on
----------------------------------------------------------------
MEM [1GB 512GB] [1GB 512GB]
HIGH_GIC_REDISTS2 [512GB 512GB+64MB] [disabled]
HIGH_PCIE_ECAM [512GB+256MB 512GB+512MB] [disabled]
HIGH_PCIE_MMIO [disabled] [512GB 1TB]
In order to keep backwords compatibility, we need to disable the
optimization on machine, which is virt-7.1 or ealier than it. It
means the optimization is enabled by default from virt-7.2. Besides,
'compact-highmem' property is added so that the optimization can be
explicitly enabled or disabled on all machine types by users.
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Tested-by: Zhenyu Zhang <zhenyzha@redhat.com>
Message-id: 20221029224307.138822-7-gshan@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2022-12-14 15:27:06 +01:00
|
|
|
bool no_highmem_compact;
|
2018-06-22 14:28:37 +02:00
|
|
|
bool no_highmem_ecam;
|
2021-10-20 16:21:18 +02:00
|
|
|
bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */
|
2020-01-30 17:02:06 +01:00
|
|
|
bool kvm_no_adjvtime;
|
2020-10-01 08:17:18 +02:00
|
|
|
bool no_kvm_steal_time;
|
2020-07-03 17:59:43 +02:00
|
|
|
bool acpi_expose_flash;
|
2021-01-28 13:00:11 +01:00
|
|
|
bool no_secure_gpio;
|
2021-10-20 16:21:18 +02:00
|
|
|
/* Machines < 6.2 have no support for describing cpu topology to guest */
|
|
|
|
bool no_cpu_topology;
|
2022-03-01 22:59:58 +01:00
|
|
|
bool no_tcg_lpa2;
|
2020-09-03 22:43:22 +02:00
|
|
|
};
|
2017-01-09 12:40:22 +01:00
|
|
|
|
2020-09-03 22:43:22 +02:00
|
|
|
struct VirtMachineState {
|
2017-01-09 12:40:22 +01:00
|
|
|
MachineState parent;
|
|
|
|
Notifier machine_done;
|
2018-05-10 19:10:56 +02:00
|
|
|
DeviceState *platform_bus_dev;
|
2017-01-09 12:40:23 +01:00
|
|
|
FWCfgState *fw_cfg;
|
hw/arm/virt: Support firmware configuration with -blockdev
The ARM virt machines put firmware in flash memory. To configure it,
you use -drive if=pflash,unit=0,... and optionally -drive
if=pflash,unit=1,...
Why two -drive? This permits setting up one part of the flash memory
read-only, and the other part read/write. It also makes upgrading
firmware on the host easier. Below the hood, we get two separate
flash devices, because we were too lazy to improve our flash device
models to support sector protection.
The problem at hand is to do the same with -blockdev somehow, as one
more step towards deprecating -drive.
We recently solved this problem for x86 PC machines, in commit
ebc29e1beab. See the commit message for design rationale.
This commit solves it for ARM virt basically the same way: new machine
properties pflash0, pflash1 forward to the onboard flash devices'
properties. Requires creating the onboard devices in the
.instance_init() method virt_instance_init(). The existing code to
pick up drives defined with -drive if=pflash is replaced by code to
desugar into the machine properties.
There are a few behavioral differences, though:
* The flash devices are always present (x86: only present if
configured)
* Flash base addresses and sizes are fixed (x86: sizes depend on
images, mapped back to back below a fixed address)
* -bios configures contents of first pflash (x86: -bios configures ROM
contents)
* -bios is rejected when first pflash is also configured with -machine
pflash0=... (x86: bios is silently ignored then)
* -machine pflash1=... does not require -machine pflash0=... (x86: it
does).
The actual code is a bit simpler than for x86 mostly due to the first
two differences.
Before the patch, all the action is in create_flash(), called from the
machine's .init() method machvirt_init():
main()
machine_run_board_init()
machvirt_init()
create_flash()
create_one_flash() for flash[0]
create
configure
includes obeying -drive if=pflash,unit=0
realize
map
fall back to -bios
create_one_flash() for flash[1]
create
configure
includes obeying -drive if=pflash,unit=1
realize
map
update FDT
To make the machine properties work, we need to move device creation
to its .instance_init() method virt_instance_init().
Another complication is machvirt_init()'s computation of
@firmware_loaded: it predicts what create_flash() will do. Instead of
predicting what create_flash()'s replacement virt_firmware_init() will
do, I decided to have virt_firmware_init() return what it did.
Requires calling it a bit earlier.
Resulting call tree:
main()
current_machine = object_new()
...
virt_instance_init()
virt_flash_create()
virt_flash_create1() for flash[0]
create
configure: set defaults
become child of machine [NEW]
add machine prop pflash0 as alias for drive [NEW]
virt_flash_create1() for flash[1]
create
configure: set defaults
become child of machine [NEW]
add machine prop pflash1 as alias for drive [NEW]
for all machine props from the command line: machine_set_property()
...
property_set_alias() for machine props pflash0, pflash1
...
set_drive() for cfi.pflash01 prop drive
this is how -machine pflash0=... etc set
machine_run_board_init(current_machine);
virt_firmware_init()
pflash_cfi01_legacy_drive()
legacy -drive if=pflash,unit=0 and =1 [NEW]
virt_flash_map()
virt_flash_map1() for flash[0]
configure: num-blocks
realize
map
virt_flash_map1() for flash[1]
configure: num-blocks
realize
map
fall back to -bios
virt_flash_fdt()
update FDT
You have László to thank for making me explain this in detail.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Message-id: 20190416091348.26075-4-armbru@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-07 13:55:02 +02:00
|
|
|
PFlashCFI01 *flash[2];
|
2017-01-09 12:40:22 +01:00
|
|
|
bool secure;
|
|
|
|
bool highmem;
|
hw/arm/virt: Improve high memory region address assignment
There are three high memory regions, which are VIRT_HIGH_REDIST2,
VIRT_HIGH_PCIE_ECAM and VIRT_HIGH_PCIE_MMIO. Their base addresses
are floating on highest RAM address. However, they can be disabled
in several cases.
(1) One specific high memory region is likely to be disabled by
code by toggling vms->highmem_{redists, ecam, mmio}.
(2) VIRT_HIGH_PCIE_ECAM region is disabled on machine, which is
'virt-2.12' or ealier than it.
(3) VIRT_HIGH_PCIE_ECAM region is disabled when firmware is loaded
on 32-bits system.
(4) One specific high memory region is disabled when it breaks the
PA space limit.
The current implementation of virt_set_{memmap, high_memmap}() isn't
optimized because the high memory region's PA space is always reserved,
regardless of whatever the actual state in the corresponding
vms->highmem_{redists, ecam, mmio} flag. In the code, 'base' and
'vms->highest_gpa' are always increased for case (1), (2) and (3).
It's unnecessary since the assigned PA space for the disabled high
memory region won't be used afterwards.
Improve the address assignment for those three high memory region by
skipping the address assignment for one specific high memory region if
it has been disabled in case (1), (2) and (3). The memory layout may
be changed after the improvement is applied, which leads to potential
migration breakage. So 'vms->highmem_compact' is added to control if
the improvement should be applied. For now, 'vms->highmem_compact' is
set to false, meaning that we don't have memory layout change until it
becomes configurable through property 'compact-highmem' in next patch.
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Tested-by: Zhenyu Zhang <zhenyzha@redhat.com>
Message-id: 20221029224307.138822-6-gshan@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2022-12-14 15:27:06 +01:00
|
|
|
bool highmem_compact;
|
2018-06-22 14:28:37 +02:00
|
|
|
bool highmem_ecam;
|
2022-01-14 15:07:36 +01:00
|
|
|
bool highmem_mmio;
|
2022-01-14 15:07:37 +01:00
|
|
|
bool highmem_redists;
|
2017-02-28 13:08:16 +01:00
|
|
|
bool its;
|
2021-09-13 17:07:24 +02:00
|
|
|
bool tcg_its;
|
2017-01-20 12:15:11 +01:00
|
|
|
bool virt;
|
2020-05-12 05:06:01 +02:00
|
|
|
bool ras;
|
2020-07-20 11:25:36 +02:00
|
|
|
bool mte;
|
2022-07-07 12:36:07 +02:00
|
|
|
bool dtb_randomness;
|
2020-03-20 11:01:36 +01:00
|
|
|
OnOffAuto acpi;
|
2020-03-11 14:16:14 +01:00
|
|
|
VirtGICType gic_version;
|
2018-05-04 19:05:52 +02:00
|
|
|
VirtIOMMUType iommu;
|
2021-07-08 14:55:13 +02:00
|
|
|
bool default_bus_bypass_iommu;
|
2020-07-03 17:59:42 +02:00
|
|
|
VirtMSIControllerType msi_controller;
|
2020-02-14 14:27:44 +01:00
|
|
|
uint16_t virtio_iommu_bdf;
|
2017-01-09 12:40:22 +01:00
|
|
|
struct arm_boot_info bootinfo;
|
2019-03-04 11:13:32 +01:00
|
|
|
MemMapEntry *memmap;
|
2020-02-14 14:27:44 +01:00
|
|
|
char *pciehb_nodename;
|
2017-01-09 12:40:22 +01:00
|
|
|
const int *irqmap;
|
|
|
|
int fdt_size;
|
|
|
|
uint32_t clock_phandle;
|
|
|
|
uint32_t gic_phandle;
|
|
|
|
uint32_t msi_phandle;
|
2018-05-04 19:05:52 +02:00
|
|
|
uint32_t iommu_phandle;
|
2017-01-20 12:15:10 +01:00
|
|
|
int psci_conduit;
|
2019-03-04 11:13:36 +01:00
|
|
|
hwaddr highest_gpa;
|
2019-12-09 10:03:06 +01:00
|
|
|
DeviceState *gic;
|
2019-09-18 15:06:27 +02:00
|
|
|
DeviceState *acpi_dev;
|
2019-09-18 15:06:29 +02:00
|
|
|
Notifier powerdown_notifier;
|
2020-11-19 02:48:35 +01:00
|
|
|
PCIBus *bus;
|
2021-01-19 01:32:13 +01:00
|
|
|
char *oem_id;
|
|
|
|
char *oem_table_id;
|
2020-09-03 22:43:22 +02:00
|
|
|
};
|
2017-01-09 12:40:22 +01:00
|
|
|
|
2019-03-04 11:13:31 +01:00
|
|
|
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
|
2018-06-22 14:28:37 +02:00
|
|
|
|
2017-01-09 12:40:22 +01:00
|
|
|
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
|
2020-09-16 20:25:18 +02:00
|
|
|
OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE)
|
2017-01-09 12:40:22 +01:00
|
|
|
|
2017-01-09 12:40:22 +01:00
|
|
|
void virt_acpi_setup(VirtMachineState *vms);
|
2020-03-20 11:01:36 +01:00
|
|
|
bool virt_is_acpi_enabled(VirtMachineState *vms);
|
2017-01-09 12:40:22 +01:00
|
|
|
|
2022-04-08 16:15:49 +02:00
|
|
|
/* Return number of redistributors that fit in the specified region */
|
|
|
|
static uint32_t virt_redist_capacity(VirtMachineState *vms, int region)
|
|
|
|
{
|
2022-04-08 16:15:50 +02:00
|
|
|
uint32_t redist_size;
|
|
|
|
|
|
|
|
if (vms->gic_version == VIRT_GIC_VERSION_3) {
|
|
|
|
redist_size = GICV3_REDIST_SIZE;
|
|
|
|
} else {
|
|
|
|
redist_size = GICV4_REDIST_SIZE;
|
|
|
|
}
|
|
|
|
return vms->memmap[region].size / redist_size;
|
2022-04-08 16:15:49 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 14:28:36 +02:00
|
|
|
/* Return the number of used redistributor regions */
|
|
|
|
static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
|
|
|
|
{
|
2022-04-08 16:15:49 +02:00
|
|
|
uint32_t redist0_capacity = virt_redist_capacity(vms, VIRT_GIC_REDIST);
|
2018-06-22 14:28:36 +02:00
|
|
|
|
2022-04-08 16:15:50 +02:00
|
|
|
assert(vms->gic_version != VIRT_GIC_VERSION_2);
|
2018-06-22 14:28:36 +02:00
|
|
|
|
2022-01-14 15:07:37 +01:00
|
|
|
return (MACHINE(vms)->smp.cpus > redist0_capacity &&
|
|
|
|
vms->highmem_redists) ? 2 : 1;
|
2018-06-22 14:28:36 +02:00
|
|
|
}
|
|
|
|
|
2017-01-09 12:40:22 +01:00
|
|
|
#endif /* QEMU_ARM_VIRT_H */
|