mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 10:34:58 -06:00
target-arm queue:
* hw/arm/npcm8xx_boards: Correct valid_cpu_types setting of NPCM8XX SoC * arm/hvf: fix crashes when using gdbstub * target/arm/ptw: fix arm_cpu_get_phys_page_attrs_debug * hw/arm/virt: Remove deprecated old versions of 'virt' machine * tests/functional: Add test for imx8mp-evk board with USDHC coverage * hw/arm: Attach PSPI module to NPCM8XX SoC * target/arm: Don't assert() for ISB/SB inside IT block * docs: Don't define duplicate label in qemu-block-drivers.rst.inc * target/arm/kvm: Drop support for kernels without KVM_ARM_PREFERRED_TARGET * hw/pci-host/designware: Fix viewport configuration * hw/gpio/imx_gpio: Fix interpretation of GDIR polarity -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmgaH50ZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3l4ED/0QOV6oev1ILqA1INBjY7Ct VrjzjsynFnUkyU0MLKyuK+mBRYmeR1OWtIRTkbgIsRA23XqV4de/BhGsVCGrRA0r VS/hV2kTQM0GYU2dCr9LpOC3jX0dDzft5uW9GjW/sW9infAwXRwKhGgkIV6q/G5V Y6cMN7UXrOnomF8Spk5VvK8HH9OHV/fuSlWenk9X1bXPpVQ3jymqZ1eRSDXOzDdM uP6lVdI3oHCpRPeXKa1EA8cfQa9M/y9XSzDIrF8OTZKVcIzbX8/XR+y74e4UMIvK DD3nAuAXcezy3286Pu7OfciRBJfq3eFHZVXOKfQWFI3MStPmexKqoHm8JtQxXJOT uJdaugItLahlPtNk41nAydYzYimK/MBKCWAfTqecEhZ9Cd64jeOPM9zXwRkXwyuu n9XQUhm5Ll22urd4q2M8cCxKBP2OoaEBFS4Hn9uDpVDcWpRMLe2DP7ywzZjdLU9b jLSlana5+wpMuwIasXlNzWgT37RA+xlDE2Snaz7K/Z3JV/XNZAZD6WXV72zTzhFs EI10edHI+JXXlbT1Ev/yVv4cN9h/Kr3hyoOKat2ySaomW26H27wNPuvPTto4rCYU 6VQJmJvwPSBWELI5eRbcN269K0ar1UXUsvDsy97cq35me3gFvfAZFksLpnPWKef6 pvwwPuxLWQXs+chepuQyXA== =c21p -----END PGP SIGNATURE----- Merge tag 'pull-target-arm-20250506' of https://git.linaro.org/people/pmaydell/qemu-arm into staging target-arm queue: * hw/arm/npcm8xx_boards: Correct valid_cpu_types setting of NPCM8XX SoC * arm/hvf: fix crashes when using gdbstub * target/arm/ptw: fix arm_cpu_get_phys_page_attrs_debug * hw/arm/virt: Remove deprecated old versions of 'virt' machine * tests/functional: Add test for imx8mp-evk board with USDHC coverage * hw/arm: Attach PSPI module to NPCM8XX SoC * target/arm: Don't assert() for ISB/SB inside IT block * docs: Don't define duplicate label in qemu-block-drivers.rst.inc * target/arm/kvm: Drop support for kernels without KVM_ARM_PREFERRED_TARGET * hw/pci-host/designware: Fix viewport configuration * hw/gpio/imx_gpio: Fix interpretation of GDIR polarity # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmgaH50ZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3l4ED/0QOV6oev1ILqA1INBjY7Ct # VrjzjsynFnUkyU0MLKyuK+mBRYmeR1OWtIRTkbgIsRA23XqV4de/BhGsVCGrRA0r # VS/hV2kTQM0GYU2dCr9LpOC3jX0dDzft5uW9GjW/sW9infAwXRwKhGgkIV6q/G5V # Y6cMN7UXrOnomF8Spk5VvK8HH9OHV/fuSlWenk9X1bXPpVQ3jymqZ1eRSDXOzDdM # uP6lVdI3oHCpRPeXKa1EA8cfQa9M/y9XSzDIrF8OTZKVcIzbX8/XR+y74e4UMIvK # DD3nAuAXcezy3286Pu7OfciRBJfq3eFHZVXOKfQWFI3MStPmexKqoHm8JtQxXJOT # uJdaugItLahlPtNk41nAydYzYimK/MBKCWAfTqecEhZ9Cd64jeOPM9zXwRkXwyuu # n9XQUhm5Ll22urd4q2M8cCxKBP2OoaEBFS4Hn9uDpVDcWpRMLe2DP7ywzZjdLU9b # jLSlana5+wpMuwIasXlNzWgT37RA+xlDE2Snaz7K/Z3JV/XNZAZD6WXV72zTzhFs # EI10edHI+JXXlbT1Ev/yVv4cN9h/Kr3hyoOKat2ySaomW26H27wNPuvPTto4rCYU # 6VQJmJvwPSBWELI5eRbcN269K0ar1UXUsvDsy97cq35me3gFvfAZFksLpnPWKef6 # pvwwPuxLWQXs+chepuQyXA== # =c21p # -----END PGP SIGNATURE----- # gpg: Signature made Tue 06 May 2025 10:41:33 EDT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [full] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20250506' of https://git.linaro.org/people/pmaydell/qemu-arm: (32 commits) hw/arm/virt: Remove deprecated virt-4.0 machine hw/arm/virt: Remove deprecated virt-3.1 machine hw/arm/virt: Remove deprecated virt-3.0 machine hw/arm/virt: Update comment about Multiprocessor Affinity Register hw/gpio/imx_gpio: Fix interpretation of GDIR polarity hw/pci-host/designware: Fix viewport configuration hw/pci-host/designware: Remove unused include target/arm/kvm: Drop support for kernels without KVM_ARM_PREFERRED_TARGET docs: Don't define duplicate label in qemu-block-drivers.rst.inc target/arm: Don't assert() for ISB/SB inside IT block hw/arm: Attach PSPI module to NPCM8XX SoC tests/functional: Add test for imx8mp-evk board with USDHC coverage hw/arm/virt: Remove VirtMachineClass::no_highmem_ecam field hw/arm/virt: Remove deprecated virt-2.12 machine hw/arm/virt: Remove VirtMachineClass::smbios_old_sys_ver field hw/arm/virt: Remove deprecated virt-2.11 machine hw/arm/virt: Remove deprecated virt-2.10 machine hw/arm/virt: Remove deprecated virt-2.9 machine hw/arm/virt: Remove VirtMachineClass::claim_edge_triggered_timers field hw/arm/virt: Remove deprecated virt-2.8 machine ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
57b6f8d07f
20 changed files with 188 additions and 249 deletions
|
@ -842,6 +842,7 @@ F: include/hw/arm/fsl-imx8mp.h
|
||||||
F: include/hw/misc/imx8mp_*.h
|
F: include/hw/misc/imx8mp_*.h
|
||||||
F: include/hw/pci-host/fsl_imx8m_phy.h
|
F: include/hw/pci-host/fsl_imx8m_phy.h
|
||||||
F: docs/system/arm/imx8mp-evk.rst
|
F: docs/system/arm/imx8mp-evk.rst
|
||||||
|
F: tests/functional/test_aarch64_imx8mp_evk.py
|
||||||
F: tests/qtest/rs5c372-test.c
|
F: tests/qtest/rs5c372-test.c
|
||||||
|
|
||||||
MPS2 / MPS3
|
MPS2 / MPS3
|
||||||
|
|
|
@ -58,8 +58,13 @@ int hvf_sw_breakpoints_active(CPUState *cpu)
|
||||||
return !QTAILQ_EMPTY(&hvf_state->hvf_sw_breakpoints);
|
return !QTAILQ_EMPTY(&hvf_state->hvf_sw_breakpoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hvf_update_guest_debug(CPUState *cpu)
|
static void do_hvf_update_guest_debug(CPUState *cpu, run_on_cpu_data arg)
|
||||||
{
|
{
|
||||||
hvf_arch_update_guest_debug(cpu);
|
hvf_arch_update_guest_debug(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hvf_update_guest_debug(CPUState *cpu)
|
||||||
|
{
|
||||||
|
run_on_cpu(cpu, do_hvf_update_guest_debug, RUN_ON_CPU_NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ yet, so sometimes the source code is all you have.
|
||||||
* `monitor <https://gitlab.com/qemu-project/qemu/-/tree/master/monitor>`_:
|
* `monitor <https://gitlab.com/qemu-project/qemu/-/tree/master/monitor>`_:
|
||||||
`Monitor <QEMU monitor>` implementation (HMP & QMP).
|
`Monitor <QEMU monitor>` implementation (HMP & QMP).
|
||||||
* `nbd <https://gitlab.com/qemu-project/qemu/-/tree/master/nbd>`_:
|
* `nbd <https://gitlab.com/qemu-project/qemu/-/tree/master/nbd>`_:
|
||||||
QEMU `NBD (Network Block Device) <nbd>` server.
|
QEMU NBD (Network Block Device) server.
|
||||||
* `net <https://gitlab.com/qemu-project/qemu/-/tree/master/net>`_:
|
* `net <https://gitlab.com/qemu-project/qemu/-/tree/master/net>`_:
|
||||||
Network (host) support.
|
Network (host) support.
|
||||||
* `pc-bios <https://gitlab.com/qemu-project/qemu/-/tree/master/pc-bios>`_:
|
* `pc-bios <https://gitlab.com/qemu-project/qemu/-/tree/master/pc-bios>`_:
|
||||||
|
|
|
@ -500,8 +500,6 @@ What you should *never* do:
|
||||||
- expect it to work when loadvm'ing
|
- expect it to work when loadvm'ing
|
||||||
- write to the FAT directory on the host system while accessing it with the guest system
|
- write to the FAT directory on the host system while accessing it with the guest system
|
||||||
|
|
||||||
.. _nbd:
|
|
||||||
|
|
||||||
NBD access
|
NBD access
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,9 @@
|
||||||
/* SDHCI Modules */
|
/* SDHCI Modules */
|
||||||
#define NPCM8XX_MMC_BA 0xf0842000
|
#define NPCM8XX_MMC_BA 0xf0842000
|
||||||
|
|
||||||
|
/* PSPI Modules */
|
||||||
|
#define NPCM8XX_PSPI_BA 0xf0201000
|
||||||
|
|
||||||
/* Run PLL1 at 1600 MHz */
|
/* Run PLL1 at 1600 MHz */
|
||||||
#define NPCM8XX_PLLCON1_FIXUP_VAL 0x00402101
|
#define NPCM8XX_PLLCON1_FIXUP_VAL 0x00402101
|
||||||
/* Run the CPU from PLL1 and UART from PLL2 */
|
/* Run the CPU from PLL1 and UART from PLL2 */
|
||||||
|
@ -83,6 +86,7 @@ enum NPCM8xxInterrupt {
|
||||||
NPCM8XX_PECI_IRQ = 6,
|
NPCM8XX_PECI_IRQ = 6,
|
||||||
NPCM8XX_KCS_HIB_IRQ = 9,
|
NPCM8XX_KCS_HIB_IRQ = 9,
|
||||||
NPCM8XX_MMC_IRQ = 26,
|
NPCM8XX_MMC_IRQ = 26,
|
||||||
|
NPCM8XX_PSPI_IRQ = 28,
|
||||||
NPCM8XX_TIMER0_IRQ = 32, /* Timer Module 0 */
|
NPCM8XX_TIMER0_IRQ = 32, /* Timer Module 0 */
|
||||||
NPCM8XX_TIMER1_IRQ,
|
NPCM8XX_TIMER1_IRQ,
|
||||||
NPCM8XX_TIMER2_IRQ,
|
NPCM8XX_TIMER2_IRQ,
|
||||||
|
@ -441,6 +445,7 @@ static void npcm8xx_init(Object *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI);
|
object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI);
|
||||||
|
object_initialize_child(obj, "pspi", &s->pspi, TYPE_NPCM_PSPI);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void npcm8xx_realize(DeviceState *dev, Error **errp)
|
static void npcm8xx_realize(DeviceState *dev, Error **errp)
|
||||||
|
@ -705,6 +710,11 @@ static void npcm8xx_realize(DeviceState *dev, Error **errp)
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0,
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0,
|
||||||
npcm8xx_irq(s, NPCM8XX_MMC_IRQ));
|
npcm8xx_irq(s, NPCM8XX_MMC_IRQ));
|
||||||
|
|
||||||
|
/* PSPI */
|
||||||
|
sysbus_realize(SYS_BUS_DEVICE(&s->pspi), &error_abort);
|
||||||
|
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pspi), 0, NPCM8XX_PSPI_BA);
|
||||||
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pspi), 0,
|
||||||
|
npcm8xx_irq(s, NPCM8XX_PSPI_IRQ));
|
||||||
|
|
||||||
create_unimplemented_device("npcm8xx.shm", 0xc0001000, 4 * KiB);
|
create_unimplemented_device("npcm8xx.shm", 0xc0001000, 4 * KiB);
|
||||||
create_unimplemented_device("npcm8xx.gicextra", 0xdfffa000, 24 * KiB);
|
create_unimplemented_device("npcm8xx.gicextra", 0xdfffa000, 24 * KiB);
|
||||||
|
@ -720,7 +730,6 @@ static void npcm8xx_realize(DeviceState *dev, Error **errp)
|
||||||
create_unimplemented_device("npcm8xx.siox[1]", 0xf0101000, 4 * KiB);
|
create_unimplemented_device("npcm8xx.siox[1]", 0xf0101000, 4 * KiB);
|
||||||
create_unimplemented_device("npcm8xx.siox[2]", 0xf0102000, 4 * KiB);
|
create_unimplemented_device("npcm8xx.siox[2]", 0xf0102000, 4 * KiB);
|
||||||
create_unimplemented_device("npcm8xx.tmps", 0xf0188000, 4 * KiB);
|
create_unimplemented_device("npcm8xx.tmps", 0xf0188000, 4 * KiB);
|
||||||
create_unimplemented_device("npcm8xx.pspi", 0xf0201000, 4 * KiB);
|
|
||||||
create_unimplemented_device("npcm8xx.viru1", 0xf0204000, 4 * KiB);
|
create_unimplemented_device("npcm8xx.viru1", 0xf0204000, 4 * KiB);
|
||||||
create_unimplemented_device("npcm8xx.viru2", 0xf0205000, 4 * KiB);
|
create_unimplemented_device("npcm8xx.viru2", 0xf0205000, 4 * KiB);
|
||||||
create_unimplemented_device("npcm8xx.jtm1", 0xf0208000, 4 * KiB);
|
create_unimplemented_device("npcm8xx.jtm1", 0xf0208000, 4 * KiB);
|
||||||
|
|
|
@ -213,7 +213,7 @@ static void npcm8xx_machine_class_init(ObjectClass *oc, const void *data)
|
||||||
{
|
{
|
||||||
MachineClass *mc = MACHINE_CLASS(oc);
|
MachineClass *mc = MACHINE_CLASS(oc);
|
||||||
static const char * const valid_cpu_types[] = {
|
static const char * const valid_cpu_types[] = {
|
||||||
ARM_CPU_TYPE_NAME("cortex-a9"),
|
ARM_CPU_TYPE_NAME("cortex-a35"),
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -537,15 +537,12 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
static void
|
static void
|
||||||
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
|
||||||
/*
|
/*
|
||||||
* Table 5-117 Flag Definitions
|
* Table 5-117 Flag Definitions
|
||||||
* set only "Timer interrupt Mode" and assume "Timer Interrupt
|
* set only "Timer interrupt Mode" and assume "Timer Interrupt
|
||||||
* polarity" bit as '0: Interrupt is Active high'
|
* polarity" bit as '0: Interrupt is Active high'
|
||||||
*/
|
*/
|
||||||
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
|
const uint32_t irqflags = 0; /* Interrupt is Level triggered */
|
||||||
1 : /* Interrupt is Edge triggered */
|
|
||||||
0; /* Interrupt is Level triggered */
|
|
||||||
AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
|
AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
|
||||||
.oem_table_id = vms->oem_table_id };
|
.oem_table_id = vms->oem_table_id };
|
||||||
|
|
||||||
|
@ -670,7 +667,6 @@ static void
|
||||||
build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
|
||||||
const MemMapEntry *memmap = vms->memmap;
|
const MemMapEntry *memmap = vms->memmap;
|
||||||
AcpiTable table = { .sig = "APIC", .rev = 4, .oem_id = vms->oem_id,
|
AcpiTable table = { .sig = "APIC", .rev = 4, .oem_id = vms->oem_id,
|
||||||
.oem_table_id = vms->oem_table_id };
|
.oem_table_id = vms->oem_table_id };
|
||||||
|
@ -741,7 +737,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
memmap[VIRT_HIGH_GIC_REDIST2].size);
|
memmap[VIRT_HIGH_GIC_REDIST2].size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (its_class_name() && !vmc->no_its) {
|
if (its_class_name()) {
|
||||||
/*
|
/*
|
||||||
* ACPI spec, Revision 6.0 Errata A
|
* ACPI spec, Revision 6.0 Errata A
|
||||||
* (original 6.0 definition has invalid Length)
|
* (original 6.0 definition has invalid Length)
|
||||||
|
@ -973,7 +969,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
||||||
vms->oem_table_id);
|
vms->oem_table_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (its_class_name() && !vmc->no_its) {
|
if (its_class_name()) {
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_iort(tables_blob, tables->linker, vms);
|
build_iort(tables_blob, tables->linker, vms);
|
||||||
}
|
}
|
||||||
|
|
153
hw/arm/virt.c
153
hw/arm/virt.c
|
@ -370,14 +370,9 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
|
||||||
* the correct information.
|
* the correct information.
|
||||||
*/
|
*/
|
||||||
ARMCPU *armcpu;
|
ARMCPU *armcpu;
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
|
||||||
uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI;
|
uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI;
|
||||||
MachineState *ms = MACHINE(vms);
|
MachineState *ms = MACHINE(vms);
|
||||||
|
|
||||||
if (vmc->claim_edge_triggered_timers) {
|
|
||||||
irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vms->gic_version == VIRT_GIC_VERSION_2) {
|
if (vms->gic_version == VIRT_GIC_VERSION_2) {
|
||||||
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
|
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
|
||||||
GIC_FDT_IRQ_PPI_CPU_WIDTH,
|
GIC_FDT_IRQ_PPI_CPU_WIDTH,
|
||||||
|
@ -1704,7 +1699,6 @@ static void virt_build_smbios(VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(vms);
|
MachineClass *mc = MACHINE_GET_CLASS(vms);
|
||||||
MachineState *ms = MACHINE(vms);
|
MachineState *ms = MACHINE(vms);
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
|
||||||
uint8_t *smbios_tables, *smbios_anchor;
|
uint8_t *smbios_tables, *smbios_anchor;
|
||||||
size_t smbios_tables_len, smbios_anchor_len;
|
size_t smbios_tables_len, smbios_anchor_len;
|
||||||
struct smbios_phys_mem_area mem_array;
|
struct smbios_phys_mem_area mem_array;
|
||||||
|
@ -1714,8 +1708,7 @@ static void virt_build_smbios(VirtMachineState *vms)
|
||||||
product = "KVM Virtual Machine";
|
product = "KVM Virtual Machine";
|
||||||
}
|
}
|
||||||
|
|
||||||
smbios_set_defaults("QEMU", product,
|
smbios_set_defaults("QEMU", product, mc->name);
|
||||||
vmc->smbios_old_sys_ver ? "1.0" : mc->name);
|
|
||||||
|
|
||||||
/* build the array of physical mem area from base_memmap */
|
/* build the array of physical mem area from base_memmap */
|
||||||
mem_array.address = vms->memmap[VIRT_MEM].base;
|
mem_array.address = vms->memmap[VIRT_MEM].base;
|
||||||
|
@ -1770,24 +1763,18 @@ void virt_machine_done(Notifier *notifier, void *data)
|
||||||
|
|
||||||
static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
|
static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
|
||||||
{
|
{
|
||||||
uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER;
|
uint8_t clustersz;
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
|
||||||
|
|
||||||
if (!vmc->disallow_affinity_adjustment) {
|
/*
|
||||||
/* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
|
* Adjust MPIDR to make TCG consistent (with 64-bit KVM hosts)
|
||||||
* GIC's target-list limitations. 32-bit KVM hosts currently
|
* and to improve SGI efficiency.
|
||||||
* always create clusters of 4 CPUs, but that is expected to
|
*/
|
||||||
* change when they gain support for gicv3. When KVM is enabled
|
if (vms->gic_version == VIRT_GIC_VERSION_2) {
|
||||||
* it will override the changes we make here, therefore our
|
clustersz = GIC_TARGETLIST_BITS;
|
||||||
* purposes are to make TCG consistent (with 64-bit KVM hosts)
|
} else {
|
||||||
* and to improve SGI efficiency.
|
clustersz = GICV3_TARGETLIST_BITS;
|
||||||
*/
|
|
||||||
if (vms->gic_version == VIRT_GIC_VERSION_2) {
|
|
||||||
clustersz = GIC_TARGETLIST_BITS;
|
|
||||||
} else {
|
|
||||||
clustersz = GICV3_TARGETLIST_BITS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return arm_build_mp_affinity(idx, clustersz);
|
return arm_build_mp_affinity(idx, clustersz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2273,10 +2260,6 @@ static void machvirt_init(MachineState *machine)
|
||||||
object_property_set_bool(cpuobj, "kvm-steal-time", false, NULL);
|
object_property_set_bool(cpuobj, "kvm-steal-time", false, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vmc->no_pmu && object_property_find(cpuobj, "pmu")) {
|
|
||||||
object_property_set_bool(cpuobj, "pmu", false, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vmc->no_tcg_lpa2 && object_property_find(cpuobj, "lpa2")) {
|
if (vmc->no_tcg_lpa2 && object_property_find(cpuobj, "lpa2")) {
|
||||||
object_property_set_bool(cpuobj, "lpa2", false, NULL);
|
object_property_set_bool(cpuobj, "lpa2", false, NULL);
|
||||||
}
|
}
|
||||||
|
@ -3348,21 +3331,17 @@ static void virt_instance_init(Object *obj)
|
||||||
vms->highmem_compact = !vmc->no_highmem_compact;
|
vms->highmem_compact = !vmc->no_highmem_compact;
|
||||||
vms->gic_version = VIRT_GIC_VERSION_NOSEL;
|
vms->gic_version = VIRT_GIC_VERSION_NOSEL;
|
||||||
|
|
||||||
vms->highmem_ecam = !vmc->no_highmem_ecam;
|
vms->highmem_ecam = true;
|
||||||
vms->highmem_mmio = true;
|
vms->highmem_mmio = true;
|
||||||
vms->highmem_redists = true;
|
vms->highmem_redists = true;
|
||||||
|
|
||||||
if (vmc->no_its) {
|
/* Default allows ITS instantiation */
|
||||||
vms->its = false;
|
vms->its = true;
|
||||||
} else {
|
|
||||||
/* Default allows ITS instantiation */
|
|
||||||
vms->its = true;
|
|
||||||
|
|
||||||
if (vmc->no_tcg_its) {
|
if (vmc->no_tcg_its) {
|
||||||
vms->tcg_its = false;
|
vms->tcg_its = false;
|
||||||
} else {
|
} else {
|
||||||
vms->tcg_its = true;
|
vms->tcg_its = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default disallows iommu instantiation */
|
/* Default disallows iommu instantiation */
|
||||||
|
@ -3583,99 +3562,3 @@ static void virt_machine_4_1_options(MachineClass *mc)
|
||||||
mc->auto_enable_numa_with_memhp = false;
|
mc->auto_enable_numa_with_memhp = false;
|
||||||
}
|
}
|
||||||
DEFINE_VIRT_MACHINE(4, 1)
|
DEFINE_VIRT_MACHINE(4, 1)
|
||||||
|
|
||||||
static void virt_machine_4_0_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
virt_machine_4_1_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(4, 0)
|
|
||||||
|
|
||||||
static void virt_machine_3_1_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
virt_machine_4_0_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(3, 1)
|
|
||||||
|
|
||||||
static void virt_machine_3_0_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
virt_machine_3_1_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(3, 0)
|
|
||||||
|
|
||||||
static void virt_machine_2_12_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
|
||||||
|
|
||||||
virt_machine_3_0_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len);
|
|
||||||
vmc->no_highmem_ecam = true;
|
|
||||||
mc->max_cpus = 255;
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(2, 12)
|
|
||||||
|
|
||||||
static void virt_machine_2_11_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
|
||||||
|
|
||||||
virt_machine_2_12_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len);
|
|
||||||
vmc->smbios_old_sys_ver = true;
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(2, 11)
|
|
||||||
|
|
||||||
static void virt_machine_2_10_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
virt_machine_2_11_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len);
|
|
||||||
/* before 2.11 we never faulted accesses to bad addresses */
|
|
||||||
mc->ignore_memory_transaction_failures = true;
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(2, 10)
|
|
||||||
|
|
||||||
static void virt_machine_2_9_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
virt_machine_2_10_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(2, 9)
|
|
||||||
|
|
||||||
static void virt_machine_2_8_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
|
||||||
|
|
||||||
virt_machine_2_9_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
|
|
||||||
/* For 2.8 and earlier we falsely claimed in the DT that
|
|
||||||
* our timers were edge-triggered, not level-triggered.
|
|
||||||
*/
|
|
||||||
vmc->claim_edge_triggered_timers = true;
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(2, 8)
|
|
||||||
|
|
||||||
static void virt_machine_2_7_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
|
||||||
|
|
||||||
virt_machine_2_8_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len);
|
|
||||||
/* ITS was introduced with 2.8 */
|
|
||||||
vmc->no_its = true;
|
|
||||||
/* Stick with 1K pages for migration compatibility */
|
|
||||||
mc->minimum_page_bits = 0;
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(2, 7)
|
|
||||||
|
|
||||||
static void virt_machine_2_6_options(MachineClass *mc)
|
|
||||||
{
|
|
||||||
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
|
||||||
|
|
||||||
virt_machine_2_7_options(mc);
|
|
||||||
compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len);
|
|
||||||
vmc->disallow_affinity_adjustment = true;
|
|
||||||
/* Disable PMU for 2.6 as PMU support was first introduced in 2.7 */
|
|
||||||
vmc->no_pmu = true;
|
|
||||||
}
|
|
||||||
DEFINE_VIRT_MACHINE(2, 6)
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ static void imx_gpio_update_int(IMXGPIOState *s)
|
||||||
static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel level)
|
static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel level)
|
||||||
{
|
{
|
||||||
/* if this signal isn't configured as an input signal, nothing to do */
|
/* if this signal isn't configured as an input signal, nothing to do */
|
||||||
if (!extract32(s->gdir, line, 1)) {
|
if (extract32(s->gdir, line, 1)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/module.h"
|
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "qemu/bitops.h"
|
#include "qemu/bitops.h"
|
||||||
#include "hw/pci/msi.h"
|
#include "hw/pci/msi.h"
|
||||||
|
@ -349,14 +348,14 @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
|
||||||
|
|
||||||
case DESIGNWARE_PCIE_ATU_LOWER_BASE:
|
case DESIGNWARE_PCIE_ATU_LOWER_BASE:
|
||||||
case DESIGNWARE_PCIE_ATU_UPPER_BASE:
|
case DESIGNWARE_PCIE_ATU_UPPER_BASE:
|
||||||
viewport->base = deposit64(root->msi.base,
|
viewport->base = deposit64(viewport->base,
|
||||||
address == DESIGNWARE_PCIE_ATU_LOWER_BASE
|
address == DESIGNWARE_PCIE_ATU_LOWER_BASE
|
||||||
? 0 : 32, 32, val);
|
? 0 : 32, 32, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DESIGNWARE_PCIE_ATU_LOWER_TARGET:
|
case DESIGNWARE_PCIE_ATU_LOWER_TARGET:
|
||||||
case DESIGNWARE_PCIE_ATU_UPPER_TARGET:
|
case DESIGNWARE_PCIE_ATU_UPPER_TARGET:
|
||||||
viewport->target = deposit64(root->msi.base,
|
viewport->target = deposit64(viewport->target,
|
||||||
address == DESIGNWARE_PCIE_ATU_LOWER_TARGET
|
address == DESIGNWARE_PCIE_ATU_LOWER_TARGET
|
||||||
? 0 : 32, 32, val);
|
? 0 : 32, 32, val);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "hw/usb/hcd-ehci.h"
|
#include "hw/usb/hcd-ehci.h"
|
||||||
#include "hw/usb/hcd-ohci.h"
|
#include "hw/usb/hcd-ohci.h"
|
||||||
#include "target/arm/cpu.h"
|
#include "target/arm/cpu.h"
|
||||||
|
#include "hw/ssi/npcm_pspi.h"
|
||||||
|
|
||||||
#define NPCM8XX_MAX_NUM_CPUS (4)
|
#define NPCM8XX_MAX_NUM_CPUS (4)
|
||||||
|
|
||||||
|
@ -99,6 +100,7 @@ struct NPCM8xxState {
|
||||||
OHCISysBusState ohci[2];
|
OHCISysBusState ohci[2];
|
||||||
NPCM7xxFIUState fiu[3];
|
NPCM7xxFIUState fiu[3];
|
||||||
NPCM7xxSDHCIState mmc;
|
NPCM7xxSDHCIState mmc;
|
||||||
|
NPCMPSPIState pspi;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NPCM8xxClass {
|
struct NPCM8xxClass {
|
||||||
|
|
|
@ -117,14 +117,8 @@ typedef enum VirtGICType {
|
||||||
|
|
||||||
struct VirtMachineClass {
|
struct VirtMachineClass {
|
||||||
MachineClass parent;
|
MachineClass parent;
|
||||||
bool disallow_affinity_adjustment;
|
|
||||||
bool no_its;
|
|
||||||
bool no_tcg_its;
|
bool no_tcg_its;
|
||||||
bool no_pmu;
|
|
||||||
bool claim_edge_triggered_timers;
|
|
||||||
bool smbios_old_sys_ver;
|
|
||||||
bool no_highmem_compact;
|
bool no_highmem_compact;
|
||||||
bool no_highmem_ecam;
|
|
||||||
bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */
|
bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */
|
||||||
bool kvm_no_adjvtime;
|
bool kvm_no_adjvtime;
|
||||||
bool no_kvm_steal_time;
|
bool no_kvm_steal_time;
|
||||||
|
|
|
@ -46,7 +46,7 @@ static inline void gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3)
|
||||||
#ifdef CONFIG_KVM
|
#ifdef CONFIG_KVM
|
||||||
int fdarray[3];
|
int fdarray[3];
|
||||||
|
|
||||||
if (!kvm_arm_create_scratch_host_vcpu(NULL, fdarray, NULL)) {
|
if (!kvm_arm_create_scratch_host_vcpu(fdarray, NULL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2278,28 +2278,23 @@ static inline bool hvf_arm_hw_debug_active(CPUState *cpu)
|
||||||
return ((cur_hw_wps > 0) || (cur_hw_bps > 0));
|
return ((cur_hw_wps > 0) || (cur_hw_bps > 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hvf_arch_set_traps(void)
|
static void hvf_arch_set_traps(CPUState *cpu)
|
||||||
{
|
{
|
||||||
CPUState *cpu;
|
|
||||||
bool should_enable_traps = false;
|
bool should_enable_traps = false;
|
||||||
hv_return_t r = HV_SUCCESS;
|
hv_return_t r = HV_SUCCESS;
|
||||||
|
|
||||||
/* Check whether guest debugging is enabled for at least one vCPU; if it
|
/* Check whether guest debugging is enabled for at least one vCPU; if it
|
||||||
* is, enable exiting the guest on all vCPUs */
|
* is, enable exiting the guest on all vCPUs */
|
||||||
CPU_FOREACH(cpu) {
|
should_enable_traps |= cpu->accel->guest_debug_enabled;
|
||||||
should_enable_traps |= cpu->accel->guest_debug_enabled;
|
/* Set whether debug exceptions exit the guest */
|
||||||
}
|
r = hv_vcpu_set_trap_debug_exceptions(cpu->accel->fd,
|
||||||
CPU_FOREACH(cpu) {
|
should_enable_traps);
|
||||||
/* Set whether debug exceptions exit the guest */
|
assert_hvf_ok(r);
|
||||||
r = hv_vcpu_set_trap_debug_exceptions(cpu->accel->fd,
|
|
||||||
should_enable_traps);
|
|
||||||
assert_hvf_ok(r);
|
|
||||||
|
|
||||||
/* Set whether accesses to debug registers exit the guest */
|
/* Set whether accesses to debug registers exit the guest */
|
||||||
r = hv_vcpu_set_trap_debug_reg_accesses(cpu->accel->fd,
|
r = hv_vcpu_set_trap_debug_reg_accesses(cpu->accel->fd,
|
||||||
should_enable_traps);
|
should_enable_traps);
|
||||||
assert_hvf_ok(r);
|
assert_hvf_ok(r);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hvf_arch_update_guest_debug(CPUState *cpu)
|
void hvf_arch_update_guest_debug(CPUState *cpu)
|
||||||
|
@ -2340,7 +2335,7 @@ void hvf_arch_update_guest_debug(CPUState *cpu)
|
||||||
deposit64(env->cp15.mdscr_el1, MDSCR_EL1_MDE_SHIFT, 1, 0);
|
deposit64(env->cp15.mdscr_el1, MDSCR_EL1_MDE_SHIFT, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
hvf_arch_set_traps();
|
hvf_arch_set_traps(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hvf_arch_supports_guest_debug(void)
|
bool hvf_arch_supports_guest_debug(void)
|
||||||
|
|
|
@ -100,8 +100,7 @@ static int kvm_arm_vcpu_finalize(ARMCPU *cpu, int feature)
|
||||||
return kvm_vcpu_ioctl(CPU(cpu), KVM_ARM_VCPU_FINALIZE, &feature);
|
return kvm_vcpu_ioctl(CPU(cpu), KVM_ARM_VCPU_FINALIZE, &feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
|
bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
|
||||||
int *fdarray,
|
|
||||||
struct kvm_vcpu_init *init)
|
struct kvm_vcpu_init *init)
|
||||||
{
|
{
|
||||||
int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
|
int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
|
||||||
|
@ -150,40 +149,13 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
|
||||||
struct kvm_vcpu_init preferred;
|
struct kvm_vcpu_init preferred;
|
||||||
|
|
||||||
ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred);
|
ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred);
|
||||||
if (!ret) {
|
if (ret < 0) {
|
||||||
init->target = preferred.target;
|
goto err;
|
||||||
}
|
}
|
||||||
|
init->target = preferred.target;
|
||||||
}
|
}
|
||||||
if (ret >= 0) {
|
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
|
||||||
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
|
if (ret < 0) {
|
||||||
if (ret < 0) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
} else if (cpus_to_try) {
|
|
||||||
/* Old kernel which doesn't know about the
|
|
||||||
* PREFERRED_TARGET ioctl: we know it will only support
|
|
||||||
* creating one kind of guest CPU which is its preferred
|
|
||||||
* CPU type.
|
|
||||||
*/
|
|
||||||
struct kvm_vcpu_init try;
|
|
||||||
|
|
||||||
while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) {
|
|
||||||
try.target = *cpus_to_try++;
|
|
||||||
memcpy(try.features, init->features, sizeof(init->features));
|
|
||||||
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, &try);
|
|
||||||
if (ret >= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ret < 0) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
init->target = try.target;
|
|
||||||
} else {
|
|
||||||
/* Treat a NULL cpus_to_try argument the same as an empty
|
|
||||||
* list, which means we will fail the call since this must
|
|
||||||
* be an old kernel which doesn't support PREFERRED_TARGET.
|
|
||||||
*/
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,17 +231,6 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
uint64_t features = 0;
|
uint64_t features = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
|
|
||||||
* we know these will only support creating one kind of guest CPU,
|
|
||||||
* which is its preferred CPU type. Fortunately these old kernels
|
|
||||||
* support only a very limited number of CPUs.
|
|
||||||
*/
|
|
||||||
static const uint32_t cpus_to_try[] = {
|
|
||||||
KVM_ARM_TARGET_AEM_V8,
|
|
||||||
KVM_ARM_TARGET_FOUNDATION_V8,
|
|
||||||
KVM_ARM_TARGET_CORTEX_A57,
|
|
||||||
QEMU_KVM_ARM_TARGET_NONE
|
|
||||||
};
|
|
||||||
/*
|
/*
|
||||||
* target = -1 informs kvm_arm_create_scratch_host_vcpu()
|
* target = -1 informs kvm_arm_create_scratch_host_vcpu()
|
||||||
* to use the preferred target
|
* to use the preferred target
|
||||||
|
@ -300,7 +261,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
features |= 1ULL << ARM_FEATURE_PMU;
|
features |= 1ULL << ARM_FEATURE_PMU;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
|
if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1835,7 +1796,7 @@ uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
|
||||||
|
|
||||||
probed = true;
|
probed = true;
|
||||||
|
|
||||||
if (!kvm_arm_create_scratch_host_vcpu(NULL, fdarray, &init)) {
|
if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) {
|
||||||
error_report("failed to create scratch VCPU with SVE enabled");
|
error_report("failed to create scratch VCPU with SVE enabled");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,10 +97,6 @@ void kvm_arm_reset_vcpu(ARMCPU *cpu);
|
||||||
#ifdef CONFIG_KVM
|
#ifdef CONFIG_KVM
|
||||||
/**
|
/**
|
||||||
* kvm_arm_create_scratch_host_vcpu:
|
* kvm_arm_create_scratch_host_vcpu:
|
||||||
* @cpus_to_try: array of QEMU_KVM_ARM_TARGET_* values (terminated with
|
|
||||||
* QEMU_KVM_ARM_TARGET_NONE) to try as fallback if the kernel does not
|
|
||||||
* know the PREFERRED_TARGET ioctl. Passing NULL is the same as passing
|
|
||||||
* an empty array.
|
|
||||||
* @fdarray: filled in with kvmfd, vmfd, cpufd file descriptors in that order
|
* @fdarray: filled in with kvmfd, vmfd, cpufd file descriptors in that order
|
||||||
* @init: filled in with the necessary values for creating a host
|
* @init: filled in with the necessary values for creating a host
|
||||||
* vcpu. If NULL is provided, will not init the vCPU (though the cpufd
|
* vcpu. If NULL is provided, will not init the vCPU (though the cpufd
|
||||||
|
@ -113,8 +109,7 @@ void kvm_arm_reset_vcpu(ARMCPU *cpu);
|
||||||
* Returns: true on success (and fdarray and init are filled in),
|
* Returns: true on success (and fdarray and init are filled in),
|
||||||
* false on failure (and fdarray and init are not valid).
|
* false on failure (and fdarray and init are not valid).
|
||||||
*/
|
*/
|
||||||
bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
|
bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
|
||||||
int *fdarray,
|
|
||||||
struct kvm_vcpu_init *init);
|
struct kvm_vcpu_init *init);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3551,13 +3551,9 @@ bool get_phys_addr_with_space_nogpc(CPUARMState *env, vaddr address,
|
||||||
memop, result, fi);
|
memop, result, fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_phys_addr(CPUARMState *env, vaddr address,
|
static ARMSecuritySpace
|
||||||
MMUAccessType access_type, MemOp memop, ARMMMUIdx mmu_idx,
|
arm_mmu_idx_to_security_space(CPUARMState *env, ARMMMUIdx mmu_idx)
|
||||||
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
|
||||||
{
|
{
|
||||||
S1Translate ptw = {
|
|
||||||
.in_mmu_idx = mmu_idx,
|
|
||||||
};
|
|
||||||
ARMSecuritySpace ss;
|
ARMSecuritySpace ss;
|
||||||
|
|
||||||
switch (mmu_idx) {
|
switch (mmu_idx) {
|
||||||
|
@ -3618,32 +3614,67 @@ bool get_phys_addr(CPUARMState *env, vaddr address,
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
ptw.in_space = ss;
|
return ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_phys_addr(CPUARMState *env, vaddr address,
|
||||||
|
MMUAccessType access_type, MemOp memop, ARMMMUIdx mmu_idx,
|
||||||
|
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
||||||
|
{
|
||||||
|
S1Translate ptw = {
|
||||||
|
.in_mmu_idx = mmu_idx,
|
||||||
|
.in_space = arm_mmu_idx_to_security_space(env, mmu_idx),
|
||||||
|
};
|
||||||
|
|
||||||
return get_phys_addr_gpc(env, &ptw, address, access_type,
|
return get_phys_addr_gpc(env, &ptw, address, access_type,
|
||||||
memop, result, fi);
|
memop, result, fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static hwaddr arm_cpu_get_phys_page(CPUARMState *env, vaddr addr,
|
||||||
|
MemTxAttrs *attrs, ARMMMUIdx mmu_idx)
|
||||||
|
{
|
||||||
|
S1Translate ptw = {
|
||||||
|
.in_mmu_idx = mmu_idx,
|
||||||
|
.in_space = arm_mmu_idx_to_security_space(env, mmu_idx),
|
||||||
|
.in_debug = true,
|
||||||
|
};
|
||||||
|
GetPhysAddrResult res = {};
|
||||||
|
ARMMMUFaultInfo fi = {};
|
||||||
|
bool ret = get_phys_addr_gpc(env, &ptw, addr, MMU_DATA_LOAD, 0, &res, &fi);
|
||||||
|
*attrs = res.f.attrs;
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res.f.phys_addr;
|
||||||
|
}
|
||||||
|
|
||||||
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
|
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
|
||||||
MemTxAttrs *attrs)
|
MemTxAttrs *attrs)
|
||||||
{
|
{
|
||||||
ARMCPU *cpu = ARM_CPU(cs);
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
CPUARMState *env = &cpu->env;
|
CPUARMState *env = &cpu->env;
|
||||||
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
|
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
|
||||||
ARMSecuritySpace ss = arm_security_space(env);
|
|
||||||
S1Translate ptw = {
|
|
||||||
.in_mmu_idx = mmu_idx,
|
|
||||||
.in_space = ss,
|
|
||||||
.in_debug = true,
|
|
||||||
};
|
|
||||||
GetPhysAddrResult res = {};
|
|
||||||
ARMMMUFaultInfo fi = {};
|
|
||||||
bool ret;
|
|
||||||
|
|
||||||
ret = get_phys_addr_gpc(env, &ptw, addr, MMU_DATA_LOAD, 0, &res, &fi);
|
hwaddr res = arm_cpu_get_phys_page(env, addr, attrs, mmu_idx);
|
||||||
*attrs = res.f.attrs;
|
|
||||||
|
|
||||||
if (ret) {
|
if (res != -1) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Memory may be accessible for an "unprivileged load/store" variant.
|
||||||
|
* In this case, get_a64_user_mem_index function generates an op using an
|
||||||
|
* unprivileged mmu idx, so we need to try with it.
|
||||||
|
*/
|
||||||
|
switch (mmu_idx) {
|
||||||
|
case ARMMMUIdx_E10_1:
|
||||||
|
case ARMMMUIdx_E10_1_PAN:
|
||||||
|
return arm_cpu_get_phys_page(env, addr, attrs, ARMMMUIdx_E10_0);
|
||||||
|
case ARMMMUIdx_E20_2:
|
||||||
|
case ARMMMUIdx_E20_2_PAN:
|
||||||
|
return arm_cpu_get_phys_page(env, addr, attrs, ARMMMUIdx_E20_0);
|
||||||
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return res.f.phys_addr;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7760,7 +7760,8 @@ static bool arm_check_ss_active(DisasContext *dc)
|
||||||
|
|
||||||
static void arm_post_translate_insn(DisasContext *dc)
|
static void arm_post_translate_insn(DisasContext *dc)
|
||||||
{
|
{
|
||||||
if (dc->condjmp && dc->base.is_jmp == DISAS_NEXT) {
|
if (dc->condjmp &&
|
||||||
|
(dc->base.is_jmp == DISAS_NEXT || dc->base.is_jmp == DISAS_TOO_MANY)) {
|
||||||
if (dc->pc_save != dc->condlabel.pc_save) {
|
if (dc->pc_save != dc->condlabel.pc_save) {
|
||||||
gen_update_pc(dc, dc->condlabel.pc_save - dc->pc_save);
|
gen_update_pc(dc, dc->condlabel.pc_save - dc->pc_save);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ endif
|
||||||
test_timeouts = {
|
test_timeouts = {
|
||||||
'aarch64_aspeed_ast2700' : 600,
|
'aarch64_aspeed_ast2700' : 600,
|
||||||
'aarch64_aspeed_ast2700fc' : 600,
|
'aarch64_aspeed_ast2700fc' : 600,
|
||||||
|
'aarch64_imx8mp_evk' : 240,
|
||||||
'aarch64_raspi4' : 480,
|
'aarch64_raspi4' : 480,
|
||||||
'aarch64_reverse_debug' : 180,
|
'aarch64_reverse_debug' : 180,
|
||||||
'aarch64_rme_virt' : 1200,
|
'aarch64_rme_virt' : 1200,
|
||||||
|
@ -82,6 +83,7 @@ tests_aarch64_system_quick = [
|
||||||
tests_aarch64_system_thorough = [
|
tests_aarch64_system_thorough = [
|
||||||
'aarch64_aspeed_ast2700',
|
'aarch64_aspeed_ast2700',
|
||||||
'aarch64_aspeed_ast2700fc',
|
'aarch64_aspeed_ast2700fc',
|
||||||
|
'aarch64_imx8mp_evk',
|
||||||
'aarch64_raspi3',
|
'aarch64_raspi3',
|
||||||
'aarch64_raspi4',
|
'aarch64_raspi4',
|
||||||
'aarch64_replay',
|
'aarch64_replay',
|
||||||
|
|
67
tests/functional/test_aarch64_imx8mp_evk.py
Executable file
67
tests/functional/test_aarch64_imx8mp_evk.py
Executable file
|
@ -0,0 +1,67 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Functional test that boots a Linux kernel and checks the console
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
from qemu_test import LinuxKernelTest, Asset
|
||||||
|
|
||||||
|
|
||||||
|
class Imx8mpEvkMachine(LinuxKernelTest):
|
||||||
|
|
||||||
|
ASSET_IMAGE = Asset(
|
||||||
|
('https://cloud.debian.org/images/cloud/bookworm/20231210-1590/'
|
||||||
|
'debian-12-generic-arm64-20231210-1590.tar.xz'),
|
||||||
|
'7ebf1577b32d5af6204df74b54ca2e4675de9b5a9fa14f3ff70b88eeb7b3b359')
|
||||||
|
|
||||||
|
KERNEL_OFFSET = 0x51000000
|
||||||
|
KERNEL_SIZE = 32622528
|
||||||
|
INITRD_OFFSET = 0x76000000
|
||||||
|
INITRD_SIZE = 30987766
|
||||||
|
DTB_OFFSET = 0x64F51000
|
||||||
|
DTB_SIZE = 45 * 1024
|
||||||
|
|
||||||
|
def extract(self, in_path, out_path, offset, size):
|
||||||
|
try:
|
||||||
|
with open(in_path, "rb") as source:
|
||||||
|
source.seek(offset)
|
||||||
|
data = source.read(size)
|
||||||
|
with open(out_path, "wb") as target:
|
||||||
|
target.write(data)
|
||||||
|
except (IOError, ValueError) as e:
|
||||||
|
self.log.error(f"Failed to extract {out_path}: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
self.image_path = self.scratch_file("disk.raw")
|
||||||
|
self.kernel_path = self.scratch_file("linux")
|
||||||
|
self.initrd_path = self.scratch_file("initrd.zstd")
|
||||||
|
self.dtb_path = self.scratch_file("imx8mp-evk.dtb")
|
||||||
|
|
||||||
|
self.archive_extract(self.ASSET_IMAGE)
|
||||||
|
self.extract(self.image_path, self.kernel_path,
|
||||||
|
self.KERNEL_OFFSET, self.KERNEL_SIZE)
|
||||||
|
self.extract(self.image_path, self.initrd_path,
|
||||||
|
self.INITRD_OFFSET, self.INITRD_SIZE)
|
||||||
|
self.extract(self.image_path, self.dtb_path,
|
||||||
|
self.DTB_OFFSET, self.DTB_SIZE)
|
||||||
|
|
||||||
|
def test_aarch64_imx8mp_evk_usdhc(self):
|
||||||
|
self.set_machine('imx8mp-evk')
|
||||||
|
self.vm.set_console(console_index=1)
|
||||||
|
self.vm.add_args('-m', '2G',
|
||||||
|
'-smp', '4',
|
||||||
|
'-kernel', self.kernel_path,
|
||||||
|
'-initrd', self.initrd_path,
|
||||||
|
'-dtb', self.dtb_path,
|
||||||
|
'-append', 'root=/dev/mmcblk2p1',
|
||||||
|
'-drive', f'file={self.image_path},if=sd,bus=2,'
|
||||||
|
'format=raw,id=mmcblk2,snapshot=on')
|
||||||
|
|
||||||
|
self.vm.launch()
|
||||||
|
self.wait_for_console_pattern('Welcome to ')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
LinuxKernelTest.main()
|
Loading…
Add table
Add a link
Reference in a new issue