target-arm queue:

* MAINTAINERS update for arm hvf
  * target/arm: Make RETA[AB] UNDEF when pauth is not implemented
  * target/arm: Refactoring of ID register value storage
  * target/arm: Various refactoring/cleanup patches
  * virt: Don't show an ITS in ACPI tables when no ITS is present
  * tests/functional: test device passthrough on aarch64
  * tests/functional: Expand Aarch64 SMMU tests to run on HVF accelerator
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmhkE/IZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vNeD/9ZcHiqTxLyuurYntf63VLP
 55NRozF0By7f83dOja5r+NWeGSPqhDBO05PpBVArt+giE2dkkVCoJ5stNrls5ACl
 oi5glXQL/bW+A3nN+WmcD+s2RMVHn5jZ6f5ChRsFo2bWYl0rtrR1raC/wl415ag/
 MMRjbXj6sabEITY7794KBN4M5RDVS+Zcu7dzPZecsttbxLIGLBvvJ0bFSmh91tH4
 Tyy889v2GHou1BxSWVcSWNCTQ9jLYV7a+VHHs4uTlsBc3Pw7LXS4DcPhEdfZ3+gy
 RaZUu1Eq213qd3r75FqFgR4mrY/nIm/CXd+mWjC5LsLOX0BYQKlAFiDH599AeZV3
 f1Wa0+POJDSKLDux+hPu3/2eeggI4d5XKAW9dgCYKicCtfhFEKXmTtaJtZyW+vTR
 Vpl8SDVoljDd3q/045CXzOdM5N+5xj2WNNNKYYW4stHJrAIxa88pBeK2bqzT372x
 V8FENVzK+7owTibi63XEshgdVlBcCB9Xpp+9p4TEbMZcd8EEUVDFC5F6iF9hNUYT
 s1cqphTVscWDXxkTSok6POHOIvotRdT7EcIVQ9VfJxVREGrtWkioDii1O+olMhyF
 uoeoxkFE1Jih4LQz937pqCCgP0PPd9DMtXdX/WeiAcZSDEHlO8gbRiIIyf11qL2i
 aiMIF0rHY9PvxIisnukkLQ==
 =x5Ur
 -----END PGP SIGNATURE-----

Merge tag 'pull-target-arm-20250701-1' of https://gitlab.com/pm215/qemu into staging

target-arm queue:
 * MAINTAINERS update for arm hvf
 * target/arm: Make RETA[AB] UNDEF when pauth is not implemented
 * target/arm: Refactoring of ID register value storage
 * target/arm: Various refactoring/cleanup patches
 * virt: Don't show an ITS in ACPI tables when no ITS is present
 * tests/functional: test device passthrough on aarch64
 * tests/functional: Expand Aarch64 SMMU tests to run on HVF accelerator

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmhkE/IZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vNeD/9ZcHiqTxLyuurYntf63VLP
# 55NRozF0By7f83dOja5r+NWeGSPqhDBO05PpBVArt+giE2dkkVCoJ5stNrls5ACl
# oi5glXQL/bW+A3nN+WmcD+s2RMVHn5jZ6f5ChRsFo2bWYl0rtrR1raC/wl415ag/
# MMRjbXj6sabEITY7794KBN4M5RDVS+Zcu7dzPZecsttbxLIGLBvvJ0bFSmh91tH4
# Tyy889v2GHou1BxSWVcSWNCTQ9jLYV7a+VHHs4uTlsBc3Pw7LXS4DcPhEdfZ3+gy
# RaZUu1Eq213qd3r75FqFgR4mrY/nIm/CXd+mWjC5LsLOX0BYQKlAFiDH599AeZV3
# f1Wa0+POJDSKLDux+hPu3/2eeggI4d5XKAW9dgCYKicCtfhFEKXmTtaJtZyW+vTR
# Vpl8SDVoljDd3q/045CXzOdM5N+5xj2WNNNKYYW4stHJrAIxa88pBeK2bqzT372x
# V8FENVzK+7owTibi63XEshgdVlBcCB9Xpp+9p4TEbMZcd8EEUVDFC5F6iF9hNUYT
# s1cqphTVscWDXxkTSok6POHOIvotRdT7EcIVQ9VfJxVREGrtWkioDii1O+olMhyF
# uoeoxkFE1Jih4LQz937pqCCgP0PPd9DMtXdX/WeiAcZSDEHlO8gbRiIIyf11qL2i
# aiMIF0rHY9PvxIisnukkLQ==
# =x5Ur
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 01 Jul 2025 12:59:30 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-20250701-1' of https://gitlab.com/pm215/qemu: (43 commits)
  tests/functional: test device passthrough on aarch64
  tests/functional: Expand Aarch64 SMMU tests to run on HVF accelerator
  tests/functional: Add hvf_available() helper
  tests/functional: Require TCG to run Aarch64 imx8mp-evk test
  tests/functional: Restrict nested Aarch64 Xen test to TCG
  tests/functional: Set sbsa-ref machine type in each test function
  hw/arm/sbsa-ref: Tidy up use of RAMLIMIT_GB definition
  hw/arm/virt: Rename cpu_post_init() -> post_cpus_gic_realized()
  hw/arm/virt: Make EL2 accelerator check an accept-list
  hw/arm/virt: Make EL3-guest accel check an accept-list
  target/arm: Restrict system register properties to system binary
  target/arm/hvf: Pass @target_el argument to hvf_raise_exception()
  target/arm: Correct KVM & HVF dtb_compatible value
  target/arm/hvf: Log $pc in hvf_unknown_hvc() trace event
  accel/hvf: Trace VM memory mapping
  target/arm/hvf: Trace hv_vcpu_run() failures
  target/arm/hvf: Directly re-lock BQL after hv_vcpu_run()
  target/arm: Unify gen_exception_internal()
  target/arm: Reduce arm_cpu_post_init() declaration scope
  target/arm: Remove arm_handle_psci_call() stub
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2025-07-02 04:24:14 -04:00
commit 7698afc42b
42 changed files with 1432 additions and 1057 deletions

View file

@ -511,6 +511,7 @@ F: system/cpus.c
Apple Silicon HVF CPUs Apple Silicon HVF CPUs
M: Alexander Graf <agraf@csgraf.de> M: Alexander Graf <agraf@csgraf.de>
R: Mads Ynddal <mads@ynddal.dk>
S: Maintained S: Maintained
F: target/arm/hvf/ F: target/arm/hvf/
F: target/arm/hvf-stub.c F: target/arm/hvf-stub.c
@ -527,6 +528,7 @@ HVF
M: Cameron Esfahani <dirty@apple.com> M: Cameron Esfahani <dirty@apple.com>
M: Roman Bolshakov <rbolshakov@ddn.com> M: Roman Bolshakov <rbolshakov@ddn.com>
R: Phil Dennis-Jordan <phil@philjordan.eu> R: Phil Dennis-Jordan <phil@philjordan.eu>
R: Mads Ynddal <mads@ynddal.dk>
W: https://wiki.qemu.org/Features/HVF W: https://wiki.qemu.org/Features/HVF
S: Maintained S: Maintained
F: accel/hvf/ F: accel/hvf/

View file

@ -59,6 +59,7 @@
#include "system/hvf_int.h" #include "system/hvf_int.h"
#include "system/runstate.h" #include "system/runstate.h"
#include "qemu/guest-random.h" #include "qemu/guest-random.h"
#include "trace.h"
HVFState *hvf_state; HVFState *hvf_state;
@ -97,6 +98,7 @@ static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
if (macslot->present) { if (macslot->present) {
if (macslot->size != slot->size) { if (macslot->size != slot->size) {
macslot->present = 0; macslot->present = 0;
trace_hvf_vm_unmap(macslot->gpa_start, macslot->size);
ret = hv_vm_unmap(macslot->gpa_start, macslot->size); ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
assert_hvf_ok(ret); assert_hvf_ok(ret);
} }
@ -109,6 +111,10 @@ static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
macslot->present = 1; macslot->present = 1;
macslot->gpa_start = slot->start; macslot->gpa_start = slot->start;
macslot->size = slot->size; macslot->size = slot->size;
trace_hvf_vm_map(slot->start, slot->size, slot->mem, flags,
flags & HV_MEMORY_READ ? 'R' : '-',
flags & HV_MEMORY_WRITE ? 'W' : '-',
flags & HV_MEMORY_EXEC ? 'E' : '-');
ret = hv_vm_map(slot->mem, slot->start, slot->size, flags); ret = hv_vm_map(slot->mem, slot->start, slot->size, flags);
assert_hvf_ok(ret); assert_hvf_ok(ret);
return 0; return 0;

7
accel/hvf/trace-events Normal file
View file

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# See docs/devel/tracing.rst for syntax documentation.
# hvf-accel-ops.c
hvf_vm_map(uint64_t paddr, uint64_t size, void *vaddr, uint8_t flags, const char r, const char w, const char e) "paddr:0x%016"PRIx64" size:0x%08"PRIx64" vaddr:%p flags:0x%02x/%c%c%c"
hvf_vm_unmap(uint64_t paddr, uint64_t size) "paddr:0x%016"PRIx64" size:0x%08"PRIx64

2
accel/hvf/trace.h Normal file
View file

@ -0,0 +1,2 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "trace/trace-accel_hvf.h"

View file

@ -19,6 +19,7 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qemu/datadir.h" #include "qemu/datadir.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
@ -53,8 +54,7 @@
#include "target/arm/cpu-qom.h" #include "target/arm/cpu-qom.h"
#include "target/arm/gtimer.h" #include "target/arm/gtimer.h"
#define RAMLIMIT_GB 8192 #define RAMLIMIT_BYTES (8 * TiB)
#define RAMLIMIT_BYTES (RAMLIMIT_GB * GiB)
#define NUM_IRQS 256 #define NUM_IRQS 256
#define NUM_SMMU_IRQS 4 #define NUM_SMMU_IRQS 4
@ -756,7 +756,9 @@ static void sbsa_ref_init(MachineState *machine)
sms->smp_cpus = smp_cpus; sms->smp_cpus = smp_cpus;
if (machine->ram_size > sbsa_ref_memmap[SBSA_MEM].size) { if (machine->ram_size > sbsa_ref_memmap[SBSA_MEM].size) {
error_report("sbsa-ref: cannot model more than %dGB RAM", RAMLIMIT_GB); char *size_str = size_to_str(RAMLIMIT_BYTES);
error_report("sbsa-ref: cannot model more than %s of RAM", size_str);
exit(1); exit(1);
} }

View file

@ -266,6 +266,43 @@ static int iort_idmap_compare(gconstpointer a, gconstpointer b)
return idmap_a->input_base - idmap_b->input_base; return idmap_a->input_base - idmap_b->input_base;
} }
/* Compute ID ranges (RIDs) from RC that are directed to the ITS Group node */
static void create_rc_its_idmaps(GArray *its_idmaps, GArray *smmu_idmaps)
{
AcpiIortIdMapping *idmap;
AcpiIortIdMapping next_range = {0};
/*
* Based on the RID ranges that are directed to the SMMU, determine the
* bypassed RID ranges, i.e., the ones that are directed to the ITS Group
* node and do not pass through the SMMU, by subtracting the SMMU-bound
* ranges from the full RID range (0x00000xFFFF).
*/
for (int i = 0; i < smmu_idmaps->len; i++) {
idmap = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i);
if (next_range.input_base < idmap->input_base) {
next_range.id_count = idmap->input_base - next_range.input_base;
g_array_append_val(its_idmaps, next_range);
}
next_range.input_base = idmap->input_base + idmap->id_count;
}
/*
* Append the last RC -> ITS ID mapping.
*
* RIDs are 16-bit, according to the PCI Express 2.0 Base Specification, rev
* 0.9, section 2.2.6.2, "Transaction Descriptor - Transaction ID Field",
* hence the end of the range is 0x10000.
*/
if (next_range.input_base < 0x10000) {
next_range.id_count = 0x10000 - next_range.input_base;
g_array_append_val(its_idmaps, next_range);
}
}
/* /*
* Input Output Remapping Table (IORT) * Input Output Remapping Table (IORT)
* Conforms to "IO Remapping Table System Software on ARM Platforms", * Conforms to "IO Remapping Table System Software on ARM Platforms",
@ -276,10 +313,9 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
{ {
int i, nb_nodes, rc_mapping_count; int i, nb_nodes, rc_mapping_count;
size_t node_size, smmu_offset = 0; size_t node_size, smmu_offset = 0;
AcpiIortIdMapping *idmap;
uint32_t id = 0; uint32_t id = 0;
GArray *smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping)); GArray *rc_smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
GArray *its_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping)); GArray *rc_its_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
AcpiTable table = { .sig = "IORT", .rev = 3, .oem_id = vms->oem_id, AcpiTable table = { .sig = "IORT", .rev = 3, .oem_id = vms->oem_id,
.oem_table_id = vms->oem_table_id }; .oem_table_id = vms->oem_table_id };
@ -287,40 +323,39 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
acpi_table_begin(&table, table_data); acpi_table_begin(&table, table_data);
if (vms->iommu == VIRT_IOMMU_SMMUV3) { if (vms->iommu == VIRT_IOMMU_SMMUV3) {
AcpiIortIdMapping next_range = {0};
object_child_foreach_recursive(object_get_root(), object_child_foreach_recursive(object_get_root(),
iort_host_bridges, smmu_idmaps); iort_host_bridges, rc_smmu_idmaps);
/* Sort the smmu idmap by input_base */ /* Sort the smmu idmap by input_base */
g_array_sort(smmu_idmaps, iort_idmap_compare); g_array_sort(rc_smmu_idmaps, iort_idmap_compare);
/* /*
* Split the whole RIDs by mapping from RC to SMMU, * Knowing the ID ranges from the RC to the SMMU, it's possible to
* build the ID mapping from RC to ITS directly. * determine the ID ranges from RC that are directed to the ITS.
*/ */
for (i = 0; i < smmu_idmaps->len; i++) { create_rc_its_idmaps(rc_its_idmaps, rc_smmu_idmaps);
idmap = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i);
if (next_range.input_base < idmap->input_base) { nb_nodes = 2; /* RC and SMMUv3 */
next_range.id_count = idmap->input_base - next_range.input_base; rc_mapping_count = rc_smmu_idmaps->len;
g_array_append_val(its_idmaps, next_range);
}
next_range.input_base = idmap->input_base + idmap->id_count; if (vms->its) {
/*
* Knowing the ID ranges from the RC to the SMMU, it's possible to
* determine the ID ranges from RC that go directly to ITS.
*/
create_rc_its_idmaps(rc_its_idmaps, rc_smmu_idmaps);
nb_nodes++; /* ITS */
rc_mapping_count += rc_its_idmaps->len;
} }
/* Append the last RC -> ITS ID mapping */
if (next_range.input_base < 0x10000) {
next_range.id_count = 0x10000 - next_range.input_base;
g_array_append_val(its_idmaps, next_range);
}
nb_nodes = 3; /* RC, ITS, SMMUv3 */
rc_mapping_count = smmu_idmaps->len + its_idmaps->len;
} else { } else {
nb_nodes = 2; /* RC, ITS */ if (vms->its) {
rc_mapping_count = 1; nb_nodes = 2; /* RC and ITS */
rc_mapping_count = 1; /* Direct map to ITS */
} else {
nb_nodes = 1; /* RC only */
rc_mapping_count = 0; /* No output mapping */
}
} }
/* Number of IORT Nodes */ /* Number of IORT Nodes */
build_append_int_noprefix(table_data, nb_nodes, 4); build_append_int_noprefix(table_data, nb_nodes, 4);
@ -329,31 +364,43 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, IORT_NODE_OFFSET, 4); build_append_int_noprefix(table_data, IORT_NODE_OFFSET, 4);
build_append_int_noprefix(table_data, 0, 4); /* Reserved */ build_append_int_noprefix(table_data, 0, 4); /* Reserved */
/* Table 12 ITS Group Format */ if (vms->its) {
build_append_int_noprefix(table_data, 0 /* ITS Group */, 1); /* Type */ /* Table 12 ITS Group Format */
node_size = 20 /* fixed header size */ + 4 /* 1 GIC ITS Identifier */; build_append_int_noprefix(table_data, 0 /* ITS Group */, 1); /* Type */
build_append_int_noprefix(table_data, node_size, 2); /* Length */ node_size = 20 /* fixed header size */ + 4 /* 1 GIC ITS Identifier */;
build_append_int_noprefix(table_data, 1, 1); /* Revision */ build_append_int_noprefix(table_data, node_size, 2); /* Length */
build_append_int_noprefix(table_data, id++, 4); /* Identifier */ build_append_int_noprefix(table_data, 1, 1); /* Revision */
build_append_int_noprefix(table_data, 0, 4); /* Number of ID mappings */ build_append_int_noprefix(table_data, id++, 4); /* Identifier */
build_append_int_noprefix(table_data, 0, 4); /* Reference to ID Array */ build_append_int_noprefix(table_data, 0, 4); /* Number of ID mappings */
build_append_int_noprefix(table_data, 1, 4); /* Number of ITSs */ build_append_int_noprefix(table_data, 0, 4); /* Reference to ID Array */
/* GIC ITS Identifier Array */ build_append_int_noprefix(table_data, 1, 4); /* Number of ITSs */
build_append_int_noprefix(table_data, 0 /* MADT translation_id */, 4); /* GIC ITS Identifier Array */
build_append_int_noprefix(table_data, 0 /* MADT translation_id */, 4);
}
if (vms->iommu == VIRT_IOMMU_SMMUV3) { if (vms->iommu == VIRT_IOMMU_SMMUV3) {
int irq = vms->irqmap[VIRT_SMMU] + ARM_SPI_BASE; int irq = vms->irqmap[VIRT_SMMU] + ARM_SPI_BASE;
int smmu_mapping_count, offset_to_id_array;
if (vms->its) {
smmu_mapping_count = 1; /* ITS Group node */
offset_to_id_array = SMMU_V3_ENTRY_SIZE; /* Just after the header */
} else {
smmu_mapping_count = 0; /* No ID mappings */
offset_to_id_array = 0; /* No ID mappings array */
}
smmu_offset = table_data->len - table.table_offset; smmu_offset = table_data->len - table.table_offset;
/* Table 9 SMMUv3 Format */ /* Table 9 SMMUv3 Format */
build_append_int_noprefix(table_data, 4 /* SMMUv3 */, 1); /* Type */ build_append_int_noprefix(table_data, 4 /* SMMUv3 */, 1); /* Type */
node_size = SMMU_V3_ENTRY_SIZE + ID_MAPPING_ENTRY_SIZE; node_size = SMMU_V3_ENTRY_SIZE +
(ID_MAPPING_ENTRY_SIZE * smmu_mapping_count);
build_append_int_noprefix(table_data, node_size, 2); /* Length */ build_append_int_noprefix(table_data, node_size, 2); /* Length */
build_append_int_noprefix(table_data, 4, 1); /* Revision */ build_append_int_noprefix(table_data, 4, 1); /* Revision */
build_append_int_noprefix(table_data, id++, 4); /* Identifier */ build_append_int_noprefix(table_data, id++, 4); /* Identifier */
build_append_int_noprefix(table_data, 1, 4); /* Number of ID mappings */ /* Number of ID mappings */
build_append_int_noprefix(table_data, smmu_mapping_count, 4);
/* Reference to ID Array */ /* Reference to ID Array */
build_append_int_noprefix(table_data, SMMU_V3_ENTRY_SIZE, 4); build_append_int_noprefix(table_data, offset_to_id_array, 4);
/* Base address */ /* Base address */
build_append_int_noprefix(table_data, vms->memmap[VIRT_SMMU].base, 8); build_append_int_noprefix(table_data, vms->memmap[VIRT_SMMU].base, 8);
/* Flags */ /* Flags */
@ -369,9 +416,11 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, 0, 4); /* Proximity domain */ build_append_int_noprefix(table_data, 0, 4); /* Proximity domain */
/* DeviceID mapping index (ignored since interrupts are GSIV based) */ /* DeviceID mapping index (ignored since interrupts are GSIV based) */
build_append_int_noprefix(table_data, 0, 4); build_append_int_noprefix(table_data, 0, 4);
/* Array of ID mappings */
/* output IORT node is the ITS group node (the first node) */ if (smmu_mapping_count) {
build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET); /* Output IORT node is the ITS Group node (the first node). */
build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET);
}
} }
/* Table 17 Root Complex Node */ /* Table 17 Root Complex Node */
@ -407,29 +456,44 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
if (vms->iommu == VIRT_IOMMU_SMMUV3) { if (vms->iommu == VIRT_IOMMU_SMMUV3) {
AcpiIortIdMapping *range; AcpiIortIdMapping *range;
/* translated RIDs connect to SMMUv3 node: RC -> SMMUv3 -> ITS */ /*
for (i = 0; i < smmu_idmaps->len; i++) { * Map RIDs (input) from RC to SMMUv3 nodes: RC -> SMMUv3.
range = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i); *
/* output IORT node is the smmuv3 node */ * N.B.: The mapping from SMMUv3 to ITS Group node (SMMUv3 -> ITS) is
* defined in the SMMUv3 table, where all SMMUv3 IDs are mapped to the
* ITS Group node, if ITS is available.
*/
for (i = 0; i < rc_smmu_idmaps->len; i++) {
range = &g_array_index(rc_smmu_idmaps, AcpiIortIdMapping, i);
/* Output IORT node is the SMMUv3 node. */
build_iort_id_mapping(table_data, range->input_base, build_iort_id_mapping(table_data, range->input_base,
range->id_count, smmu_offset); range->id_count, smmu_offset);
} }
/* bypassed RIDs connect to ITS group node directly: RC -> ITS */ if (vms->its) {
for (i = 0; i < its_idmaps->len; i++) { /*
range = &g_array_index(its_idmaps, AcpiIortIdMapping, i); * Map bypassed (don't go through the SMMU) RIDs (input) to
/* output IORT node is the ITS group node (the first node) */ * ITS Group node directly: RC -> ITS.
build_iort_id_mapping(table_data, range->input_base, */
range->id_count, IORT_NODE_OFFSET); for (i = 0; i < rc_its_idmaps->len; i++) {
range = &g_array_index(rc_its_idmaps, AcpiIortIdMapping, i);
/* Output IORT node is the ITS Group node (the first node). */
build_iort_id_mapping(table_data, range->input_base,
range->id_count, IORT_NODE_OFFSET);
}
} }
} else { } else {
/* output IORT node is the ITS group node (the first node) */ /*
* Map all RIDs (input) to ITS Group node directly, since there is no
* SMMU: RC -> ITS.
* Output IORT node is the ITS Group node (the first node).
*/
build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET); build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET);
} }
acpi_table_end(linker, &table); acpi_table_end(linker, &table);
g_array_free(smmu_idmaps, true); g_array_free(rc_smmu_idmaps, true);
g_array_free(its_idmaps, true); g_array_free(rc_its_idmaps, true);
} }
/* /*
@ -737,7 +801,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()) { if (vms->its) {
/* /*
* 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)
@ -969,10 +1033,8 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
vms->oem_table_id); vms->oem_table_id);
} }
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);
}
#ifdef CONFIG_TPM #ifdef CONFIG_TPM
if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) { if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {

View file

@ -705,21 +705,18 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
static void create_its(VirtMachineState *vms) static void create_its(VirtMachineState *vms)
{ {
const char *itsclass = its_class_name();
DeviceState *dev; DeviceState *dev;
if (!strcmp(itsclass, "arm-gicv3-its")) { assert(vms->its);
if (!vms->tcg_its) { if (!kvm_irqchip_in_kernel() && !vms->tcg_its) {
itsclass = NULL; /*
} * Do nothing if ITS is neither supported by the host nor emulated by
} * the machine.
*/
if (!itsclass) {
/* Do nothing if not supported */
return; return;
} }
dev = qdev_new(itsclass); dev = qdev_new(its_class_name());
object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(vms->gic), object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(vms->gic),
&error_abort); &error_abort);
@ -2029,10 +2026,11 @@ static void finalize_gic_version(VirtMachineState *vms)
} }
/* /*
* virt_cpu_post_init() must be called after the CPUs have * virt_post_cpus_gic_realized() must be called after the CPUs and
* been realized and the GIC has been created. * the GIC have both been realized.
*/ */
static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem) static void virt_post_cpus_gic_realized(VirtMachineState *vms,
MemoryRegion *sysmem)
{ {
int max_cpus = MACHINE(vms)->smp.max_cpus; int max_cpus = MACHINE(vms)->smp.max_cpus;
bool aarch64, pmu, steal_time; bool aarch64, pmu, steal_time;
@ -2203,14 +2201,14 @@ static void machvirt_init(MachineState *machine)
exit(1); exit(1);
} }
if (vms->secure && (kvm_enabled() || hvf_enabled())) { if (vms->secure && !tcg_enabled() && !qtest_enabled()) {
error_report("mach-virt: %s does not support providing " error_report("mach-virt: %s does not support providing "
"Security extensions (TrustZone) to the guest CPU", "Security extensions (TrustZone) to the guest CPU",
current_accel_name()); current_accel_name());
exit(1); exit(1);
} }
if (vms->virt && (kvm_enabled() || hvf_enabled())) { if (vms->virt && !tcg_enabled() && !qtest_enabled()) {
error_report("mach-virt: %s does not support providing " error_report("mach-virt: %s does not support providing "
"Virtualization extensions to the guest CPU", "Virtualization extensions to the guest CPU",
current_accel_name()); current_accel_name());
@ -2349,7 +2347,7 @@ static void machvirt_init(MachineState *machine)
create_gic(vms, sysmem); create_gic(vms, sysmem);
virt_cpu_post_init(vms, sysmem); virt_post_cpus_gic_realized(vms, sysmem);
fdt_add_pmu_nodes(vms); fdt_add_pmu_nodes(vms);
@ -3342,12 +3340,8 @@ static void virt_instance_init(Object *obj)
/* Default allows ITS instantiation */ /* Default allows ITS instantiation */
vms->its = true; vms->its = true;
/* Allow ITS emulation if the machine version supports it */
if (vmc->no_tcg_its) { vms->tcg_its = !vmc->no_tcg_its;
vms->tcg_its = false;
} else {
vms->tcg_its = true;
}
/* Default disallows iommu instantiation */ /* Default disallows iommu instantiation */
vms->iommu = VIRT_IOMMU_NONE; vms->iommu = VIRT_IOMMU_NONE;

View file

@ -988,6 +988,7 @@ static void nvic_nmi_trigger(void *opaque, int n, int level)
static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
{ {
ARMCPU *cpu = s->cpu; ARMCPU *cpu = s->cpu;
ARMISARegisters *isar = &cpu->isar;
uint32_t val; uint32_t val;
switch (offset) { switch (offset) {
@ -1263,17 +1264,17 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_pfr0; return GET_IDREG(isar, ID_PFR0);
case 0xd44: /* PFR1. */ case 0xd44: /* PFR1. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_pfr1; return GET_IDREG(isar, ID_PFR1);
case 0xd48: /* DFR0. */ case 0xd48: /* DFR0. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_dfr0; return GET_IDREG(isar, ID_DFR0);
case 0xd4c: /* AFR0. */ case 0xd4c: /* AFR0. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
@ -1283,52 +1284,52 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_mmfr0; return GET_IDREG(isar, ID_MMFR0);
case 0xd54: /* MMFR1. */ case 0xd54: /* MMFR1. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_mmfr1; return GET_IDREG(isar, ID_MMFR1);
case 0xd58: /* MMFR2. */ case 0xd58: /* MMFR2. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_mmfr2; return GET_IDREG(isar, ID_MMFR2);
case 0xd5c: /* MMFR3. */ case 0xd5c: /* MMFR3. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_mmfr3; return GET_IDREG(isar, ID_MMFR3);
case 0xd60: /* ISAR0. */ case 0xd60: /* ISAR0. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_isar0; return GET_IDREG(&cpu->isar, ID_ISAR0);
case 0xd64: /* ISAR1. */ case 0xd64: /* ISAR1. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_isar1; return GET_IDREG(&cpu->isar, ID_ISAR1);
case 0xd68: /* ISAR2. */ case 0xd68: /* ISAR2. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_isar2; return GET_IDREG(&cpu->isar, ID_ISAR2);
case 0xd6c: /* ISAR3. */ case 0xd6c: /* ISAR3. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_isar3; return GET_IDREG(&cpu->isar, ID_ISAR3);
case 0xd70: /* ISAR4. */ case 0xd70: /* ISAR4. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_isar4; return GET_IDREG(&cpu->isar, ID_ISAR4);
case 0xd74: /* ISAR5. */ case 0xd74: /* ISAR5. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset; goto bad_offset;
} }
return cpu->isar.id_isar5; return GET_IDREG(&cpu->isar, ID_ISAR5);
case 0xd78: /* CLIDR */ case 0xd78: /* CLIDR */
return cpu->clidr; return cpu->clidr;
case 0xd7c: /* CTR */ case 0xd7c: /* CTR */

View file

@ -128,7 +128,7 @@ struct GICv3ITSCommonClass {
* Return the ITS class name to use depending on whether KVM acceleration * Return the ITS class name to use depending on whether KVM acceleration
* and KVM CAP_SIGNAL_MSI are supported * and KVM CAP_SIGNAL_MSI are supported
* *
* Returns: class name to use or NULL * Returns: class name to use
*/ */
const char *its_class_name(void); const char *its_class_name(void);

View file

@ -3630,6 +3630,7 @@ if have_block
endif endif
if have_system if have_system
trace_events_subdirs += [ trace_events_subdirs += [
'accel/hvf',
'accel/kvm', 'accel/kvm',
'audio', 'audio',
'backends', 'backends',

View file

@ -23,13 +23,19 @@ import textwrap
from typing import Optional from typing import Optional
# pylint: disable=import-error # pylint: disable=import-error
from .accel import kvm_available, list_accel, tcg_available from .accel import (
hvf_available,
kvm_available,
list_accel,
tcg_available,
)
__all__ = ( __all__ = (
'VerboseProcessError', 'VerboseProcessError',
'add_visual_margin', 'add_visual_margin',
'get_info_usernet_hostfwd_port', 'get_info_usernet_hostfwd_port',
'hvf_available',
'kvm_available', 'kvm_available',
'list_accel', 'list_accel',
'tcg_available', 'tcg_available',

View file

@ -82,3 +82,12 @@ def tcg_available(qemu_bin: str) -> bool:
@param qemu_bin (str): path to the QEMU binary @param qemu_bin (str): path to the QEMU binary
""" """
return 'tcg' in list_accel(qemu_bin) return 'tcg' in list_accel(qemu_bin)
def hvf_available(qemu_bin: str) -> bool:
"""
Check if HVF is available.
@param qemu_bin (str): path to the QEMU binary
"""
return 'hvf' in list_accel(qemu_bin)

View file

@ -23,6 +23,7 @@
#include "hw/registerfields.h" #include "hw/registerfields.h"
#include "qemu/host-utils.h" #include "qemu/host-utils.h"
#include "cpu.h" #include "cpu.h"
#include "cpu-sysregs.h"
/* /*
* Naming convention for isar_feature functions: * Naming convention for isar_feature functions:
@ -45,103 +46,103 @@
*/ */
static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id) static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0; return FIELD_EX32_IDREG(id, ID_ISAR0, DIVIDE) != 0;
} }
static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id) static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1; return FIELD_EX32_IDREG(id, ID_ISAR0, DIVIDE) > 1;
} }
static inline bool isar_feature_aa32_lob(const ARMISARegisters *id) static inline bool isar_feature_aa32_lob(const ARMISARegisters *id)
{ {
/* (M-profile) low-overhead loops and branch future */ /* (M-profile) low-overhead loops and branch future */
return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3; return FIELD_EX32_IDREG(id, ID_ISAR0, CMPBRANCH) >= 3;
} }
static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id) static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0; return FIELD_EX32_IDREG(id, ID_ISAR1, JAZELLE) != 0;
} }
static inline bool isar_feature_aa32_aes(const ARMISARegisters *id) static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0; return FIELD_EX32_IDREG(id, ID_ISAR5, AES) != 0;
} }
static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id) static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1; return FIELD_EX32_IDREG(id, ID_ISAR5, AES) > 1;
} }
static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id) static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0; return FIELD_EX32_IDREG(id, ID_ISAR5, SHA1) != 0;
} }
static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id) static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0; return FIELD_EX32_IDREG(id, ID_ISAR5, SHA2) != 0;
} }
static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id) static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0; return FIELD_EX32_IDREG(id, ID_ISAR5, CRC32) != 0;
} }
static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id) static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0; return FIELD_EX32_IDREG(id, ID_ISAR5, RDM) != 0;
} }
static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id) static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0; return FIELD_EX32_IDREG(id, ID_ISAR5, VCMA) != 0;
} }
static inline bool isar_feature_aa32_jscvt(const ARMISARegisters *id) static inline bool isar_feature_aa32_jscvt(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar6, ID_ISAR6, JSCVT) != 0; return FIELD_EX32_IDREG(id, ID_ISAR6, JSCVT) != 0;
} }
static inline bool isar_feature_aa32_dp(const ARMISARegisters *id) static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0; return FIELD_EX32_IDREG(id, ID_ISAR6, DP) != 0;
} }
static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id) static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0; return FIELD_EX32_IDREG(id, ID_ISAR6, FHM) != 0;
} }
static inline bool isar_feature_aa32_sb(const ARMISARegisters *id) static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0; return FIELD_EX32_IDREG(id, ID_ISAR6, SB) != 0;
} }
static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id) static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0; return FIELD_EX32_IDREG(id, ID_ISAR6, SPECRES) != 0;
} }
static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id) static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar6, ID_ISAR6, BF16) != 0; return FIELD_EX32_IDREG(id, ID_ISAR6, BF16) != 0;
} }
static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id) static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_isar6, ID_ISAR6, I8MM) != 0; return FIELD_EX32_IDREG(id, ID_ISAR6, I8MM) != 0;
} }
static inline bool isar_feature_aa32_ras(const ARMISARegisters *id) static inline bool isar_feature_aa32_ras(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0; return FIELD_EX32_IDREG(id, ID_PFR0, RAS) != 0;
} }
static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id) static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0; return FIELD_EX32_IDREG(id, ID_PFR1, MPROGMOD) != 0;
} }
static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id) static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
@ -150,7 +151,7 @@ static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
* Return true if M-profile state handling insns * Return true if M-profile state handling insns
* (VSCCLRM, CLRM, FPCTX access insns) are implemented * (VSCCLRM, CLRM, FPCTX access insns) are implemented
*/ */
return FIELD_EX32(id->id_pfr1, ID_PFR1, SECURITY) >= 3; return FIELD_EX32_IDREG(id, ID_PFR1, SECURITY) >= 3;
} }
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id) static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
@ -283,88 +284,88 @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
static inline bool isar_feature_aa32_pxn(const ARMISARegisters *id) static inline bool isar_feature_aa32_pxn(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_mmfr0, ID_MMFR0, VMSA) >= 4; return FIELD_EX32_IDREG(id, ID_MMFR0, VMSA) >= 4;
} }
static inline bool isar_feature_aa32_pan(const ARMISARegisters *id) static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0; return FIELD_EX32_IDREG(id, ID_MMFR3, PAN) != 0;
} }
static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id) static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2; return FIELD_EX32_IDREG(id, ID_MMFR3, PAN) >= 2;
} }
static inline bool isar_feature_aa32_pmuv3p1(const ARMISARegisters *id) static inline bool isar_feature_aa32_pmuv3p1(const ARMISARegisters *id)
{ {
/* 0xf means "non-standard IMPDEF PMU" */ /* 0xf means "non-standard IMPDEF PMU" */
return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 && return FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) >= 4 &&
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf; FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) != 0xf;
} }
static inline bool isar_feature_aa32_pmuv3p4(const ARMISARegisters *id) static inline bool isar_feature_aa32_pmuv3p4(const ARMISARegisters *id)
{ {
/* 0xf means "non-standard IMPDEF PMU" */ /* 0xf means "non-standard IMPDEF PMU" */
return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 && return FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) >= 5 &&
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf; FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) != 0xf;
} }
static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id) static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id)
{ {
/* 0xf means "non-standard IMPDEF PMU" */ /* 0xf means "non-standard IMPDEF PMU" */
return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 6 && return FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) >= 6 &&
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf; FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) != 0xf;
} }
static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id) static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0; return FIELD_EX32_IDREG(id, ID_MMFR4, HPDS) != 0;
} }
static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id) static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0; return FIELD_EX32_IDREG(id, ID_MMFR4, AC2) != 0;
} }
static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id) static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0; return FIELD_EX32_IDREG(id, ID_MMFR4, CCIDX) != 0;
} }
static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id) static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0; return FIELD_EX32_IDREG(id, ID_MMFR4, XNX) != 0;
} }
static inline bool isar_feature_aa32_half_evt(const ARMISARegisters *id) static inline bool isar_feature_aa32_half_evt(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 1; return FIELD_EX32_IDREG(id, ID_MMFR4, EVT) >= 1;
} }
static inline bool isar_feature_aa32_evt(const ARMISARegisters *id) static inline bool isar_feature_aa32_evt(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 2; return FIELD_EX32_IDREG(id, ID_MMFR4, EVT) >= 2;
} }
static inline bool isar_feature_aa32_dit(const ARMISARegisters *id) static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0; return FIELD_EX32_IDREG(id, ID_PFR0, DIT) != 0;
} }
static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id) static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0; return FIELD_EX32_IDREG(id, ID_PFR2, SSBS) != 0;
} }
static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id) static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 5; return FIELD_EX32_IDREG(id, ID_DFR0, COPDBG) >= 5;
} }
static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id) static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
{ {
return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8; return FIELD_EX32_IDREG(id, ID_DFR0, COPDBG) >= 8;
} }
static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id) static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id)
@ -377,107 +378,107 @@ static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id)
*/ */
static inline bool isar_feature_aa64_aes(const ARMISARegisters *id) static inline bool isar_feature_aa64_aes(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, AES) != 0;
} }
static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id) static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) > 1; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, AES) > 1;
} }
static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id) static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SHA1) != 0;
} }
static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id) static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SHA2) != 0;
} }
static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id) static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SHA2) > 1;
} }
static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id) static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, CRC32) != 0;
} }
static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id) static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, ATOMIC) != 0;
} }
static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id) static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RDM) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, RDM) != 0;
} }
static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id) static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SHA3) != 0;
} }
static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id) static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM3) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SM3) != 0;
} }
static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id) static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM4) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SM4) != 0;
} }
static inline bool isar_feature_aa64_dp(const ARMISARegisters *id) static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, DP) != 0;
} }
static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id) static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, FHM) != 0;
} }
static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id) static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, TS) != 0;
} }
static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id) static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, TS) >= 2;
} }
static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id) static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, RNDR) != 0;
} }
static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id) static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, TLB) == 2;
} }
static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id) static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR0, TLB) != 0;
} }
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id) static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, JSCVT) != 0;
} }
static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id) static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, FCMA) != 0;
} }
static inline bool isar_feature_aa64_xs(const ARMISARegisters *id) static inline bool isar_feature_aa64_xs(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, XS) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, XS) != 0;
} }
/* /*
@ -501,9 +502,9 @@ isar_feature_pauth_feature(const ARMISARegisters *id)
* Architecturally, only one of {APA,API,APA3} may be active (non-zero) * Architecturally, only one of {APA,API,APA3} may be active (non-zero)
* and the other two must be zero. Thus we may avoid conditionals. * and the other two must be zero. Thus we may avoid conditionals.
*/ */
return (FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) | return (FIELD_EX64_IDREG(id, ID_AA64ISAR1, APA) |
FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, API) | FIELD_EX64_IDREG(id, ID_AA64ISAR1, API) |
FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3)); FIELD_EX64_IDREG(id, ID_AA64ISAR2, APA3));
} }
static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id) static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
@ -521,7 +522,7 @@ static inline bool isar_feature_aa64_pauth_qarma5(const ARMISARegisters *id)
* Return true if pauth is enabled with the architected QARMA5 algorithm. * Return true if pauth is enabled with the architected QARMA5 algorithm.
* QEMU will always enable or disable both APA and GPA. * QEMU will always enable or disable both APA and GPA.
*/ */
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, APA) != 0;
} }
static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id) static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id)
@ -530,144 +531,144 @@ static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id)
* Return true if pauth is enabled with the architected QARMA3 algorithm. * Return true if pauth is enabled with the architected QARMA3 algorithm.
* QEMU will always enable or disable both APA3 and GPA3. * QEMU will always enable or disable both APA3 and GPA3.
*/ */
return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR2, APA3) != 0;
} }
static inline bool isar_feature_aa64_sb(const ARMISARegisters *id) static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, SB) != 0;
} }
static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id) static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, SPECRES) != 0;
} }
static inline bool isar_feature_aa64_frint(const ARMISARegisters *id) static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, FRINTTS) != 0;
} }
static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id) static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, DPB) != 0;
} }
static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id) static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, DPB) >= 2;
} }
static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id) static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, BF16) != 0;
} }
static inline bool isar_feature_aa64_ebf16(const ARMISARegisters *id) static inline bool isar_feature_aa64_ebf16(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) > 1; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, BF16) > 1;
} }
static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id) static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, LRCPC) != 0;
} }
static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id) static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, LRCPC) >= 2;
} }
static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id) static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR1, I8MM) != 0;
} }
static inline bool isar_feature_aa64_wfxt(const ARMISARegisters *id) static inline bool isar_feature_aa64_wfxt(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, WFXT) >= 2; return FIELD_EX64_IDREG(id, ID_AA64ISAR2, WFXT) >= 2;
} }
static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id) static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0; return FIELD_EX64_IDREG(id, ID_AA64ISAR2, BC) != 0;
} }
static inline bool isar_feature_aa64_mops(const ARMISARegisters *id) static inline bool isar_feature_aa64_mops(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, MOPS); return FIELD_EX64_IDREG(id, ID_AA64ISAR2, MOPS);
} }
static inline bool isar_feature_aa64_rpres(const ARMISARegisters *id) static inline bool isar_feature_aa64_rpres(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, RPRES); return FIELD_EX64_IDREG(id, ID_AA64ISAR2, RPRES);
} }
static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id) static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
{ {
/* We always set the AdvSIMD and FP fields identically. */ /* We always set the AdvSIMD and FP fields identically. */
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) != 0xf; return FIELD_EX64_IDREG(id, ID_AA64PFR0, FP) != 0xf;
} }
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id) static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
{ {
/* We always set the AdvSIMD and FP fields identically wrt FP16. */ /* We always set the AdvSIMD and FP fields identically wrt FP16. */
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1; return FIELD_EX64_IDREG(id, ID_AA64PFR0, FP) == 1;
} }
static inline bool isar_feature_aa64_aa32(const ARMISARegisters *id) static inline bool isar_feature_aa64_aa32(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL0) >= 2; return FIELD_EX64_IDREG(id, ID_AA64PFR0, EL0) >= 2;
} }
static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id) static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2; return FIELD_EX64_IDREG(id, ID_AA64PFR0, EL1) >= 2;
} }
static inline bool isar_feature_aa64_aa32_el2(const ARMISARegisters *id) static inline bool isar_feature_aa64_aa32_el2(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL2) >= 2; return FIELD_EX64_IDREG(id, ID_AA64PFR0, EL2) >= 2;
} }
static inline bool isar_feature_aa64_ras(const ARMISARegisters *id) static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR0, RAS) != 0;
} }
static inline bool isar_feature_aa64_doublefault(const ARMISARegisters *id) static inline bool isar_feature_aa64_doublefault(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) >= 2; return FIELD_EX64_IDREG(id, ID_AA64PFR0, RAS) >= 2;
} }
static inline bool isar_feature_aa64_sve(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR0, SVE) != 0;
} }
static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id) static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR0, SEL2) != 0;
} }
static inline bool isar_feature_aa64_rme(const ARMISARegisters *id) static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR0, RME) != 0;
} }
static inline bool isar_feature_aa64_dit(const ARMISARegisters *id) static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR0, DIT) != 0;
} }
static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id) static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
{ {
int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2); int key = FIELD_EX64_IDREG(id, ID_AA64PFR0, CSV2);
if (key >= 2) { if (key >= 2) {
return true; /* FEAT_CSV2_2 */ return true; /* FEAT_CSV2_2 */
} }
if (key == 1) { if (key == 1) {
key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC); key = FIELD_EX64_IDREG(id, ID_AA64PFR1, CSV2_FRAC);
return key >= 2; /* FEAT_CSV2_1p2 */ return key >= 2; /* FEAT_CSV2_1p2 */
} }
return false; return false;
@ -675,320 +676,320 @@ static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id) static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR1, SSBS) != 0;
} }
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id) static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR1, BT) != 0;
} }
static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id) static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR1, MTE) != 0;
} }
static inline bool isar_feature_aa64_mte(const ARMISARegisters *id) static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2; return FIELD_EX64_IDREG(id, ID_AA64PFR1, MTE) >= 2;
} }
static inline bool isar_feature_aa64_mte3(const ARMISARegisters *id) static inline bool isar_feature_aa64_mte3(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 3; return FIELD_EX64_IDREG(id, ID_AA64PFR1, MTE) >= 3;
} }
static inline bool isar_feature_aa64_sme(const ARMISARegisters *id) static inline bool isar_feature_aa64_sme(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR1, SME) != 0;
} }
static inline bool isar_feature_aa64_nmi(const ARMISARegisters *id) static inline bool isar_feature_aa64_nmi(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, NMI) != 0; return FIELD_EX64_IDREG(id, ID_AA64PFR1, NMI) != 0;
} }
static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
{ {
return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1; return FIELD_SEX64_IDREG(id, ID_AA64MMFR0, TGRAN4) >= 1;
} }
static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
{ {
unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2); unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN4_2);
return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id)); return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
} }
static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2; return FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN16) >= 2;
} }
static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
{ {
unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2); unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN16_2);
return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id)); return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
} }
static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
{ {
return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0; return FIELD_SEX64_IDREG(id, ID_AA64MMFR0, TGRAN4) >= 0;
} }
static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1; return FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN16) >= 1;
} }
static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
{ {
return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0; return FIELD_SEX64_IDREG(id, ID_AA64MMFR0, TGRAN64) >= 0;
} }
static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
{ {
unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2); unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN4_2);
return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id)); return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
} }
static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
{ {
unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2); unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN16_2);
return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id)); return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
} }
static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
{ {
unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2); unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN64_2);
return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id)); return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
} }
static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id) static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR0, FGT) != 0;
} }
static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id) static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR0, ECV) > 0;
} }
static inline bool isar_feature_aa64_ecv(const ARMISARegisters *id) static inline bool isar_feature_aa64_ecv(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 1; return FIELD_EX64_IDREG(id, ID_AA64MMFR0, ECV) > 1;
} }
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id) static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, VH) != 0;
} }
static inline bool isar_feature_aa64_lor(const ARMISARegisters *id) static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, LO) != 0;
} }
static inline bool isar_feature_aa64_pan(const ARMISARegisters *id) static inline bool isar_feature_aa64_pan(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, PAN) != 0;
} }
static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id) static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, PAN) >= 2;
} }
static inline bool isar_feature_aa64_pan3(const ARMISARegisters *id) static inline bool isar_feature_aa64_pan3(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 3; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, PAN) >= 3;
} }
static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id) static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, HCX) != 0;
} }
static inline bool isar_feature_aa64_afp(const ARMISARegisters *id) static inline bool isar_feature_aa64_afp(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, AFP) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, AFP) != 0;
} }
static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id) static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, TIDCP1) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, TIDCP1) != 0;
} }
static inline bool isar_feature_aa64_cmow(const ARMISARegisters *id) static inline bool isar_feature_aa64_cmow(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, CMOW) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, CMOW) != 0;
} }
static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id) static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, HAFDBS) != 0;
} }
static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id) static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, HAFDBS) >= 2;
} }
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id) static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR1, XNX) != 0;
} }
static inline bool isar_feature_aa64_uao(const ARMISARegisters *id) static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, UAO) != 0;
} }
static inline bool isar_feature_aa64_st(const ARMISARegisters *id) static inline bool isar_feature_aa64_st(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, ST) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, ST) != 0;
} }
static inline bool isar_feature_aa64_lse2(const ARMISARegisters *id) static inline bool isar_feature_aa64_lse2(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, AT) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, AT) != 0;
} }
static inline bool isar_feature_aa64_fwb(const ARMISARegisters *id) static inline bool isar_feature_aa64_fwb(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, FWB) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, FWB) != 0;
} }
static inline bool isar_feature_aa64_ids(const ARMISARegisters *id) static inline bool isar_feature_aa64_ids(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, IDS) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, IDS) != 0;
} }
static inline bool isar_feature_aa64_half_evt(const ARMISARegisters *id) static inline bool isar_feature_aa64_half_evt(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 1; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, EVT) >= 1;
} }
static inline bool isar_feature_aa64_evt(const ARMISARegisters *id) static inline bool isar_feature_aa64_evt(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 2; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, EVT) >= 2;
} }
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id) static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, CCIDX) != 0;
} }
static inline bool isar_feature_aa64_lva(const ARMISARegisters *id) static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, VARANGE) != 0;
} }
static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id) static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, E0PD) != 0;
} }
static inline bool isar_feature_aa64_nv(const ARMISARegisters *id) static inline bool isar_feature_aa64_nv(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) != 0; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, NV) != 0;
} }
static inline bool isar_feature_aa64_nv2(const ARMISARegisters *id) static inline bool isar_feature_aa64_nv2(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) >= 2; return FIELD_EX64_IDREG(id, ID_AA64MMFR2, NV) >= 2;
} }
static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id) static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 && return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 4 &&
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf; FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) != 0xf;
} }
static inline bool isar_feature_aa64_pmuv3p4(const ARMISARegisters *id) static inline bool isar_feature_aa64_pmuv3p4(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 && return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 5 &&
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf; FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) != 0xf;
} }
static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id) static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 6 && return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 6 &&
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf; FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) != 0xf;
} }
static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id) static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8; return FIELD_EX64_IDREG(id, ID_AA64DFR0, DEBUGVER) >= 8;
} }
static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id) static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
{ {
return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0; return FIELD_SEX64_IDREG(id, ID_AA64DFR0, DOUBLELOCK) >= 0;
} }
static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, SVEVER) != 0;
} }
static inline bool isar_feature_aa64_sve2_aes(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve2_aes(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) != 0; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, AES) != 0;
} }
static inline bool isar_feature_aa64_sve2_pmull128(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve2_pmull128(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) >= 2; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, AES) >= 2;
} }
static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, BITPERM) != 0;
} }
static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BFLOAT16) != 0; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, BFLOAT16) != 0;
} }
static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, SHA3) != 0;
} }
static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SM4) != 0; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, SM4) != 0;
} }
static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, I8MM) != 0; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, I8MM) != 0;
} }
static inline bool isar_feature_aa64_sve_f32mm(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve_f32mm(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F32MM) != 0; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, F32MM) != 0;
} }
static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F64MM) != 0; return FIELD_EX64_IDREG(id, ID_AA64ZFR0, F64MM) != 0;
} }
static inline bool isar_feature_aa64_sme_f64f64(const ARMISARegisters *id) static inline bool isar_feature_aa64_sme_f64f64(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, F64F64); return FIELD_EX64_IDREG(id, ID_AA64SMFR0, F64F64);
} }
static inline bool isar_feature_aa64_sme_i16i64(const ARMISARegisters *id) static inline bool isar_feature_aa64_sme_i16i64(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, I16I64) == 0xf; return FIELD_EX64_IDREG(id, ID_AA64SMFR0, I16I64) == 0xf;
} }
static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id) static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64); return FIELD_EX64_IDREG(id, ID_AA64SMFR0, FA64);
} }
/* /*

42
target/arm/cpu-sysregs.h Normal file
View file

@ -0,0 +1,42 @@
/*
* Definitions for Arm ID system registers
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef ARM_CPU_SYSREGS_H
#define ARM_CPU_SYSREGS_H
/*
* Following is similar to the coprocessor regs encodings, but with an argument
* ordering that matches the ARM ARM. We also reuse the various CP_REG_ defines
* that actually are the same as the equivalent KVM_REG_ values.
*/
#define ENCODE_ID_REG(op0, op1, crn, crm, op2) \
(((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) NAME##_IDX,
typedef enum ARMIDRegisterIdx {
#include "cpu-sysregs.h.inc"
NUM_ID_IDX,
} ARMIDRegisterIdx;
#undef DEF
#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
SYS_##NAME = ENCODE_ID_REG(OP0, OP1, CRN, CRM, OP2),
typedef enum ARMSysRegs {
#include "cpu-sysregs.h.inc"
} ARMSysRegs;
#undef DEF
extern const uint32_t id_register_sysreg[NUM_ID_IDX];
int get_sysreg_idx(ARMSysRegs sysreg);
#endif /* ARM_CPU_SYSREGS_H */

View file

@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0)
DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1)
DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5)
DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0)
DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1)
DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0)
DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1)
DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2)
DEF(ID_AA64MMFR0_EL1, 3, 0, 0, 7, 0)
DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1)
DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2)
DEF(ID_AA64MMFR3_EL1, 3, 0, 0, 7, 3)
DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2)
DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4)
DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5)
DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6)
DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7)
DEF(ID_ISAR0_EL1, 3, 0, 0, 2, 0)
DEF(ID_ISAR1_EL1, 3, 0, 0, 2, 1)
DEF(ID_ISAR2_EL1, 3, 0, 0, 2, 2)
DEF(ID_ISAR3_EL1, 3, 0, 0, 2, 3)
DEF(ID_ISAR4_EL1, 3, 0, 0, 2, 4)
DEF(ID_ISAR5_EL1, 3, 0, 0, 2, 5)
DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6)
DEF(ID_ISAR6_EL1, 3, 0, 0, 2, 7)
DEF(MVFR0_EL1, 3, 0, 0, 3, 0)
DEF(MVFR1_EL1, 3, 0, 0, 3, 1)
DEF(MVFR2_EL1, 3, 0, 0, 3, 2)
DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5)
DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6)
DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4)
DEF(CTR_EL0, 3, 3, 0, 0, 1)

View file

@ -1500,6 +1500,7 @@ static void arm_cpu_initfn(Object *obj)
* 0 means "unset, use the default value". That default might vary depending * 0 means "unset, use the default value". That default might vary depending
* on the CPU type, and is set in the realize fn. * on the CPU type, and is set in the realize fn.
*/ */
#ifndef CONFIG_USER_ONLY
static const Property arm_cpu_gt_cntfrq_property = static const Property arm_cpu_gt_cntfrq_property =
DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq_hz, 0); DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq_hz, 0);
@ -1509,7 +1510,6 @@ static const Property arm_cpu_reset_cbar_property =
static const Property arm_cpu_reset_hivecs_property = static const Property arm_cpu_reset_hivecs_property =
DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false); DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false);
#ifndef CONFIG_USER_ONLY
static const Property arm_cpu_has_el2_property = static const Property arm_cpu_has_el2_property =
DEFINE_PROP_BOOL("has_el2", ARMCPU, has_el2, true); DEFINE_PROP_BOOL("has_el2", ARMCPU, has_el2, true);
@ -1532,6 +1532,7 @@ static const Property arm_cpu_has_neon_property =
static const Property arm_cpu_has_dsp_property = static const Property arm_cpu_has_dsp_property =
DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true); DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true);
#ifndef CONFIG_USER_ONLY
static const Property arm_cpu_has_mpu_property = static const Property arm_cpu_has_mpu_property =
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
@ -1544,6 +1545,7 @@ static const Property arm_cpu_pmsav7_dregion_property =
DEFINE_PROP_UNSIGNED_NODEFAULT("pmsav7-dregion", ARMCPU, DEFINE_PROP_UNSIGNED_NODEFAULT("pmsav7-dregion", ARMCPU,
pmsav7_dregion, pmsav7_dregion,
qdev_prop_uint32, uint32_t); qdev_prop_uint32, uint32_t);
#endif
static bool arm_get_pmu(Object *obj, Error **errp) static bool arm_get_pmu(Object *obj, Error **errp)
{ {
@ -1713,7 +1715,7 @@ static void arm_cpu_propagate_feature_implications(ARMCPU *cpu)
} }
} }
void arm_cpu_post_init(Object *obj) static void arm_cpu_post_init(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
@ -1731,6 +1733,7 @@ void arm_cpu_post_init(Object *obj)
"Set on/off to enable/disable aarch64 " "Set on/off to enable/disable aarch64 "
"execution state "); "execution state ");
} }
#ifndef CONFIG_USER_ONLY
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) || if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) { arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property); qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property);
@ -1746,7 +1749,6 @@ void arm_cpu_post_init(Object *obj)
OBJ_PROP_FLAG_READWRITE); OBJ_PROP_FLAG_READWRITE);
} }
#ifndef CONFIG_USER_ONLY
if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
/* Add the has_el3 state CPU property only if EL3 is allowed. This will /* Add the has_el3 state CPU property only if EL3 is allowed. This will
* prevent "has_el3" from existing on CPUs which cannot support EL3. * prevent "has_el3" from existing on CPUs which cannot support EL3.
@ -1818,6 +1820,7 @@ void arm_cpu_post_init(Object *obj)
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property); qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property);
} }
#ifndef CONFIG_USER_ONLY
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) { if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property); qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property);
if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
@ -1854,8 +1857,6 @@ void arm_cpu_post_init(Object *obj)
&cpu->psci_conduit, &cpu->psci_conduit,
OBJ_PROP_FLAG_READWRITE); OBJ_PROP_FLAG_READWRITE);
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) { if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) {
qdev_property_add_static(DEVICE(cpu), &arm_cpu_gt_cntfrq_property); qdev_property_add_static(DEVICE(cpu), &arm_cpu_gt_cntfrq_property);
} }
@ -1864,7 +1865,6 @@ void arm_cpu_post_init(Object *obj)
kvm_arm_add_vcpu_properties(cpu); kvm_arm_add_vcpu_properties(cpu);
} }
#ifndef CONFIG_USER_ONLY
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) &&
cpu_isar_feature(aa64_mte, cpu)) { cpu_isar_feature(aa64_mte, cpu)) {
object_property_add_link(obj, "tag-memory", object_property_add_link(obj, "tag-memory",
@ -1882,6 +1882,7 @@ void arm_cpu_post_init(Object *obj)
} }
} }
#endif #endif
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
} }
static void arm_cpu_finalizefn(Object *obj) static void arm_cpu_finalizefn(Object *obj)
@ -1962,6 +1963,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
{ {
CPUState *cs = CPU(dev); CPUState *cs = CPU(dev);
ARMCPU *cpu = ARM_CPU(dev); ARMCPU *cpu = ARM_CPU(dev);
ARMISARegisters *isar = &cpu->isar;
ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev); ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
Error *local_err = NULL; Error *local_err = NULL;
@ -2119,21 +2121,16 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
} }
if (!cpu->has_vfp) { if (!cpu->has_vfp) {
uint64_t t;
uint32_t u; uint32_t u;
t = cpu->isar.id_aa64isar1; FIELD_DP64_IDREG(isar, ID_AA64ISAR1, JSCVT, 0);
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0);
cpu->isar.id_aa64isar1 = t;
t = cpu->isar.id_aa64pfr0; FIELD_DP64_IDREG(isar, ID_AA64PFR0, FP, 0xf);
t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf);
cpu->isar.id_aa64pfr0 = t;
u = cpu->isar.id_isar6; u = GET_IDREG(isar, ID_ISAR6);
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0); u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
u = FIELD_DP32(u, ID_ISAR6, BF16, 0); u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
cpu->isar.id_isar6 = u; SET_IDREG(isar, ID_ISAR6, u);
u = cpu->isar.mvfr0; u = cpu->isar.mvfr0;
u = FIELD_DP32(u, MVFR0, FPSP, 0); u = FIELD_DP32(u, MVFR0, FPSP, 0);
@ -2167,7 +2164,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
unset_feature(env, ARM_FEATURE_NEON); unset_feature(env, ARM_FEATURE_NEON);
t = cpu->isar.id_aa64isar0; t = GET_IDREG(isar, ID_AA64ISAR0);
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 0); t = FIELD_DP64(t, ID_AA64ISAR0, AES, 0);
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 0); t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 0);
t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 0); t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 0);
@ -2175,32 +2172,30 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 0); t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 0);
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 0); t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 0);
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0); t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0);
cpu->isar.id_aa64isar0 = t; SET_IDREG(isar, ID_AA64ISAR0, t);
t = cpu->isar.id_aa64isar1; t = GET_IDREG(isar, ID_AA64ISAR1);
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0); t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 0); t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 0);
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0); t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0);
cpu->isar.id_aa64isar1 = t; SET_IDREG(isar, ID_AA64ISAR1, t);
t = cpu->isar.id_aa64pfr0; FIELD_DP64_IDREG(isar, ID_AA64PFR0, ADVSIMD, 0xf);
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf);
cpu->isar.id_aa64pfr0 = t;
u = cpu->isar.id_isar5; u = GET_IDREG(isar, ID_ISAR5);
u = FIELD_DP32(u, ID_ISAR5, AES, 0); u = FIELD_DP32(u, ID_ISAR5, AES, 0);
u = FIELD_DP32(u, ID_ISAR5, SHA1, 0); u = FIELD_DP32(u, ID_ISAR5, SHA1, 0);
u = FIELD_DP32(u, ID_ISAR5, SHA2, 0); u = FIELD_DP32(u, ID_ISAR5, SHA2, 0);
u = FIELD_DP32(u, ID_ISAR5, RDM, 0); u = FIELD_DP32(u, ID_ISAR5, RDM, 0);
u = FIELD_DP32(u, ID_ISAR5, VCMA, 0); u = FIELD_DP32(u, ID_ISAR5, VCMA, 0);
cpu->isar.id_isar5 = u; SET_IDREG(isar, ID_ISAR5, u);
u = cpu->isar.id_isar6; u = GET_IDREG(isar, ID_ISAR6);
u = FIELD_DP32(u, ID_ISAR6, DP, 0); u = FIELD_DP32(u, ID_ISAR6, DP, 0);
u = FIELD_DP32(u, ID_ISAR6, FHM, 0); u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
u = FIELD_DP32(u, ID_ISAR6, BF16, 0); u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
u = FIELD_DP32(u, ID_ISAR6, I8MM, 0); u = FIELD_DP32(u, ID_ISAR6, I8MM, 0);
cpu->isar.id_isar6 = u; SET_IDREG(isar, ID_ISAR6, u);
if (!arm_feature(env, ARM_FEATURE_M)) { if (!arm_feature(env, ARM_FEATURE_M)) {
u = cpu->isar.mvfr1; u = cpu->isar.mvfr1;
@ -2217,16 +2212,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
} }
if (!cpu->has_neon && !cpu->has_vfp) { if (!cpu->has_neon && !cpu->has_vfp) {
uint64_t t;
uint32_t u; uint32_t u;
t = cpu->isar.id_aa64isar0; FIELD_DP64_IDREG(isar, ID_AA64ISAR0, FHM, 0);
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0);
cpu->isar.id_aa64isar0 = t;
t = cpu->isar.id_aa64isar1; FIELD_DP64_IDREG(isar, ID_AA64ISAR1, FRINTTS, 0);
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0);
cpu->isar.id_aa64isar1 = t;
u = cpu->isar.mvfr0; u = cpu->isar.mvfr0;
u = FIELD_DP32(u, MVFR0, SIMDREG, 0); u = FIELD_DP32(u, MVFR0, SIMDREG, 0);
@ -2243,19 +2233,17 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
unset_feature(env, ARM_FEATURE_THUMB_DSP); unset_feature(env, ARM_FEATURE_THUMB_DSP);
u = cpu->isar.id_isar1; FIELD_DP32_IDREG(isar, ID_ISAR1, EXTEND, 1);
u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1);
cpu->isar.id_isar1 = u;
u = cpu->isar.id_isar2; u = GET_IDREG(isar, ID_ISAR2);
u = FIELD_DP32(u, ID_ISAR2, MULTU, 1); u = FIELD_DP32(u, ID_ISAR2, MULTU, 1);
u = FIELD_DP32(u, ID_ISAR2, MULTS, 1); u = FIELD_DP32(u, ID_ISAR2, MULTS, 1);
cpu->isar.id_isar2 = u; SET_IDREG(isar, ID_ISAR2, u);
u = cpu->isar.id_isar3; u = GET_IDREG(isar, ID_ISAR3);
u = FIELD_DP32(u, ID_ISAR3, SIMD, 1); u = FIELD_DP32(u, ID_ISAR3, SIMD, 1);
u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0); u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0);
cpu->isar.id_isar3 = u; SET_IDREG(isar, ID_ISAR3, u);
} }
@ -2330,14 +2318,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* Disable the security extension feature bits in the processor * Disable the security extension feature bits in the processor
* feature registers as well. * feature registers as well.
*/ */
cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0); FIELD_DP32_IDREG(isar, ID_PFR1, SECURITY, 0);
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0); FIELD_DP32_IDREG(isar, ID_DFR0, COPSDBG, 0);
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0, FIELD_DP64_IDREG(isar, ID_AA64PFR0, EL3, 0);
ID_AA64PFR0, EL3, 0);
/* Disable the realm management extension, which requires EL3. */ /* Disable the realm management extension, which requires EL3. */
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0, FIELD_DP64_IDREG(isar, ID_AA64PFR0, RME, 0);
ID_AA64PFR0, RME, 0);
} }
if (!cpu->has_el2) { if (!cpu->has_el2) {
@ -2360,9 +2346,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
cpu); cpu);
#endif #endif
} else { } else {
cpu->isar.id_aa64dfr0 = FIELD_DP64_IDREG(isar, ID_AA64DFR0, PMUVER, 0);
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0); FIELD_DP32_IDREG(isar, ID_DFR0, PERFMON, 0);
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
cpu->pmceid0 = 0; cpu->pmceid0 = 0;
cpu->pmceid1 = 0; cpu->pmceid1 = 0;
} }
@ -2372,10 +2357,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* Disable the hypervisor feature bits in the processor feature * Disable the hypervisor feature bits in the processor feature
* registers if we don't have EL2. * registers if we don't have EL2.
*/ */
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0, FIELD_DP64_IDREG(isar, ID_AA64PFR0, EL2, 0);
ID_AA64PFR0, EL2, 0); FIELD_DP32_IDREG(isar, ID_PFR1, VIRTUALIZATION, 0);
cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1,
ID_PFR1, VIRTUALIZATION, 0);
} }
if (cpu_isar_feature(aa64_mte, cpu)) { if (cpu_isar_feature(aa64_mte, cpu)) {
@ -2394,8 +2377,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* This matches Cortex-A710 BROADCASTMTE input being LOW. * This matches Cortex-A710 BROADCASTMTE input being LOW.
*/ */
if (tcg_enabled() && cpu->tag_memory == NULL) { if (tcg_enabled() && cpu->tag_memory == NULL) {
cpu->isar.id_aa64pfr1 = FIELD_DP64_IDREG(isar, ID_AA64PFR1, MTE, 1);
FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1);
} }
/* /*
@ -2403,7 +2385,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* enabled on the guest (i.e mte=off), clear guest's MTE bits." * enabled on the guest (i.e mte=off), clear guest's MTE bits."
*/ */
if (kvm_enabled() && !cpu->kvm_mte) { if (kvm_enabled() && !cpu->kvm_mte) {
FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0); FIELD_DP64_IDREG(isar, ID_AA64PFR1, MTE, 0);
} }
#endif #endif
} }
@ -2423,32 +2405,22 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* try to access the non-existent system registers for them. * try to access the non-existent system registers for them.
*/ */
/* FEAT_SPE (Statistical Profiling Extension) */ /* FEAT_SPE (Statistical Profiling Extension) */
cpu->isar.id_aa64dfr0 = FIELD_DP64_IDREG(isar, ID_AA64DFR0, PMSVER, 0);
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMSVER, 0);
/* FEAT_TRBE (Trace Buffer Extension) */ /* FEAT_TRBE (Trace Buffer Extension) */
cpu->isar.id_aa64dfr0 = FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEBUFFER, 0);
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEBUFFER, 0);
/* FEAT_TRF (Self-hosted Trace Extension) */ /* FEAT_TRF (Self-hosted Trace Extension) */
cpu->isar.id_aa64dfr0 = FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEFILT, 0);
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEFILT, 0); FIELD_DP32_IDREG(isar, ID_DFR0, TRACEFILT, 0);
cpu->isar.id_dfr0 =
FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, TRACEFILT, 0);
/* Trace Macrocell system register access */ /* Trace Macrocell system register access */
cpu->isar.id_aa64dfr0 = FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEVER, 0);
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEVER, 0); FIELD_DP32_IDREG(isar, ID_DFR0, COPTRC, 0);
cpu->isar.id_dfr0 =
FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPTRC, 0);
/* Memory mapped trace */ /* Memory mapped trace */
cpu->isar.id_dfr0 = FIELD_DP32_IDREG(isar, ID_DFR0, MMAPTRC, 0);
FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0);
/* FEAT_AMU (Activity Monitors Extension) */ /* FEAT_AMU (Activity Monitors Extension) */
cpu->isar.id_aa64pfr0 = FIELD_DP64_IDREG(isar, ID_AA64PFR0, AMU, 0);
FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, AMU, 0); FIELD_DP32_IDREG(isar, ID_PFR0, AMU, 0);
cpu->isar.id_pfr0 =
FIELD_DP32(cpu->isar.id_pfr0, ID_PFR0, AMU, 0);
/* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */ /* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
cpu->isar.id_aa64pfr0 = FIELD_DP64_IDREG(isar, ID_AA64PFR0, MPAM, 0);
FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
} }
/* MPU can be configured out of a PMSA CPU either by setting has-mpu /* MPU can be configured out of a PMSA CPU either by setting has-mpu

View file

@ -32,6 +32,7 @@
#include "qapi/qapi-types-common.h" #include "qapi/qapi-types-common.h"
#include "target/arm/multiprocessing.h" #include "target/arm/multiprocessing.h"
#include "target/arm/gtimer.h" #include "target/arm/gtimer.h"
#include "target/arm/cpu-sysregs.h"
#define EXCP_UDEF 1 /* undefined instruction */ #define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */ #define EXCP_SWI 2 /* software interrupt */
@ -834,6 +835,53 @@ typedef struct {
uint32_t map, init, supported; uint32_t map, init, supported;
} ARMVQMap; } ARMVQMap;
/* REG is ID_XXX */
#define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \
({ \
ARMISARegisters *i_ = (ISAR); \
uint64_t regval = i_->idregs[REG ## _EL1_IDX]; \
regval = FIELD_DP64(regval, REG, FIELD, VALUE); \
i_->idregs[REG ## _EL1_IDX] = regval; \
})
#define FIELD_DP32_IDREG(ISAR, REG, FIELD, VALUE) \
({ \
ARMISARegisters *i_ = (ISAR); \
uint64_t regval = i_->idregs[REG ## _EL1_IDX]; \
regval = FIELD_DP32(regval, REG, FIELD, VALUE); \
i_->idregs[REG ## _EL1_IDX] = regval; \
})
#define FIELD_EX64_IDREG(ISAR, REG, FIELD) \
({ \
const ARMISARegisters *i_ = (ISAR); \
FIELD_EX64(i_->idregs[REG ## _EL1_IDX], REG, FIELD); \
})
#define FIELD_EX32_IDREG(ISAR, REG, FIELD) \
({ \
const ARMISARegisters *i_ = (ISAR); \
FIELD_EX32(i_->idregs[REG ## _EL1_IDX], REG, FIELD); \
})
#define FIELD_SEX64_IDREG(ISAR, REG, FIELD) \
({ \
const ARMISARegisters *i_ = (ISAR); \
FIELD_SEX64(i_->idregs[REG ## _EL1_IDX], REG, FIELD); \
})
#define SET_IDREG(ISAR, REG, VALUE) \
({ \
ARMISARegisters *i_ = (ISAR); \
i_->idregs[REG ## _EL1_IDX] = VALUE; \
})
#define GET_IDREG(ISAR, REG) \
({ \
const ARMISARegisters *i_ = (ISAR); \
i_->idregs[REG ## _EL1_IDX]; \
})
/** /**
* ARMCPU: * ARMCPU:
* @env: #CPUARMState * @env: #CPUARMState
@ -1002,44 +1050,14 @@ struct ArchCPU {
* field by reading the value from the KVM vCPU. * field by reading the value from the KVM vCPU.
*/ */
struct ARMISARegisters { struct ARMISARegisters {
uint32_t id_isar0;
uint32_t id_isar1;
uint32_t id_isar2;
uint32_t id_isar3;
uint32_t id_isar4;
uint32_t id_isar5;
uint32_t id_isar6;
uint32_t id_mmfr0;
uint32_t id_mmfr1;
uint32_t id_mmfr2;
uint32_t id_mmfr3;
uint32_t id_mmfr4;
uint32_t id_mmfr5;
uint32_t id_pfr0;
uint32_t id_pfr1;
uint32_t id_pfr2;
uint32_t mvfr0; uint32_t mvfr0;
uint32_t mvfr1; uint32_t mvfr1;
uint32_t mvfr2; uint32_t mvfr2;
uint32_t id_dfr0;
uint32_t id_dfr1;
uint32_t dbgdidr; uint32_t dbgdidr;
uint32_t dbgdevid; uint32_t dbgdevid;
uint32_t dbgdevid1; uint32_t dbgdevid1;
uint64_t id_aa64isar0;
uint64_t id_aa64isar1;
uint64_t id_aa64isar2;
uint64_t id_aa64pfr0;
uint64_t id_aa64pfr1;
uint64_t id_aa64mmfr0;
uint64_t id_aa64mmfr1;
uint64_t id_aa64mmfr2;
uint64_t id_aa64mmfr3;
uint64_t id_aa64dfr0;
uint64_t id_aa64dfr1;
uint64_t id_aa64zfr0;
uint64_t id_aa64smfr0;
uint64_t reset_pmcr_el0; uint64_t reset_pmcr_el0;
uint64_t idregs[NUM_ID_IDX];
} isar; } isar;
uint64_t midr; uint64_t midr;
uint32_t revidr; uint32_t revidr;
@ -1150,8 +1168,6 @@ void arm_gt_sel2vtimer_cb(void *opaque);
unsigned int gt_cntfrq_period_ns(ARMCPU *cpu); unsigned int gt_cntfrq_period_ns(ARMCPU *cpu);
void gt_rme_post_el_change(ARMCPU *cpu, void *opaque); void gt_rme_post_el_change(ARMCPU *cpu, void *opaque);
void arm_cpu_post_init(Object *obj);
#define ARM_AFF0_SHIFT 0 #define ARM_AFF0_SHIFT 0
#define ARM_AFF0_MASK (0xFFULL << ARM_AFF0_SHIFT) #define ARM_AFF0_MASK (0xFFULL << ARM_AFF0_SHIFT)
#define ARM_AFF1_SHIFT 8 #define ARM_AFF1_SHIFT 8

View file

@ -36,6 +36,28 @@
#include "cpu-features.h" #include "cpu-features.h"
#include "cpregs.h" #include "cpregs.h"
/* convert between <register>_IDX and SYS_<register> */
#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
[NAME##_IDX] = SYS_##NAME,
const uint32_t id_register_sysreg[NUM_ID_IDX] = {
#include "cpu-sysregs.h.inc"
};
#undef DEF
#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
case SYS_##NAME: return NAME##_IDX;
int get_sysreg_idx(ARMSysRegs sysreg)
{
switch (sysreg) {
#include "cpu-sysregs.h.inc"
}
g_assert_not_reached();
}
#undef DEF
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
{ {
/* /*
@ -114,7 +136,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
* SVE is disabled and so are all vector lengths. Good. * SVE is disabled and so are all vector lengths. Good.
* Disable all SVE extensions as well. * Disable all SVE extensions as well.
*/ */
cpu->isar.id_aa64zfr0 = 0; SET_IDREG(&cpu->isar, ID_AA64ZFR0, 0);
return; return;
} }
@ -288,16 +310,13 @@ static bool cpu_arm_get_sve(Object *obj, Error **errp)
static void cpu_arm_set_sve(Object *obj, bool value, Error **errp) static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
uint64_t t;
if (value && kvm_enabled() && !kvm_arm_sve_supported()) { if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
error_setg(errp, "'sve' feature not supported by KVM on this host"); error_setg(errp, "'sve' feature not supported by KVM on this host");
return; return;
} }
t = cpu->isar.id_aa64pfr0; FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR0, SVE, value);
t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
cpu->isar.id_aa64pfr0 = t;
} }
void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp) void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
@ -309,7 +328,7 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
if (vq_map == 0) { if (vq_map == 0) {
if (!cpu_isar_feature(aa64_sme, cpu)) { if (!cpu_isar_feature(aa64_sme, cpu)) {
cpu->isar.id_aa64smfr0 = 0; SET_IDREG(&cpu->isar, ID_AA64SMFR0, 0);
return; return;
} }
@ -348,11 +367,8 @@ static bool cpu_arm_get_sme(Object *obj, Error **errp)
static void cpu_arm_set_sme(Object *obj, bool value, Error **errp) static void cpu_arm_set_sme(Object *obj, bool value, Error **errp)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
uint64_t t;
t = cpu->isar.id_aa64pfr1; FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR1, SME, value);
t = FIELD_DP64(t, ID_AA64PFR1, SME, value);
cpu->isar.id_aa64pfr1 = t;
} }
static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp) static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp)
@ -365,11 +381,8 @@ static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp)
static void cpu_arm_set_sme_fa64(Object *obj, bool value, Error **errp) static void cpu_arm_set_sme_fa64(Object *obj, bool value, Error **errp)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
uint64_t t;
t = cpu->isar.id_aa64smfr0; FIELD_DP64_IDREG(&cpu->isar, ID_AA64SMFR0, FA64, value);
t = FIELD_DP64(t, ID_AA64SMFR0, FA64, value);
cpu->isar.id_aa64smfr0 = t;
} }
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
@ -480,6 +493,7 @@ void aarch64_add_sme_properties(Object *obj)
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
{ {
ARMPauthFeature features = cpu_isar_feature(pauth_feature, cpu); ARMPauthFeature features = cpu_isar_feature(pauth_feature, cpu);
ARMISARegisters *isar = &cpu->isar;
uint64_t isar1, isar2; uint64_t isar1, isar2;
/* /*
@ -490,13 +504,13 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
* *
* Begin by disabling all fields. * Begin by disabling all fields.
*/ */
isar1 = cpu->isar.id_aa64isar1; isar1 = GET_IDREG(isar, ID_AA64ISAR1);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, 0); isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 0); isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, 0); isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 0); isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 0);
isar2 = cpu->isar.id_aa64isar2; isar2 = GET_IDREG(isar, ID_AA64ISAR2);
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, 0); isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, 0);
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 0); isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 0);
@ -558,8 +572,8 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
} }
} }
cpu->isar.id_aa64isar1 = isar1; SET_IDREG(isar, ID_AA64ISAR1, isar1);
cpu->isar.id_aa64isar2 = isar2; SET_IDREG(isar, ID_AA64ISAR2, isar2);
} }
static const Property arm_cpu_pauth_property = static const Property arm_cpu_pauth_property =
@ -606,17 +620,18 @@ void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
return; return;
} }
t = cpu->isar.id_aa64mmfr0; t = GET_IDREG(&cpu->isar, ID_AA64MMFR0);
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2); /* 16k pages w/ LPA2 */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2); /* 16k pages w/ LPA2 */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1); /* 4k pages w/ LPA2 */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1); /* 4k pages w/ LPA2 */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3); /* 16k stage2 w/ LPA2 */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3); /* 16k stage2 w/ LPA2 */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3); /* 4k stage2 w/ LPA2 */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3); /* 4k stage2 w/ LPA2 */
cpu->isar.id_aa64mmfr0 = t; SET_IDREG(&cpu->isar, ID_AA64MMFR0, t);
} }
static void aarch64_a57_initfn(Object *obj) static void aarch64_a57_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a57"; cpu->dtb_compatible = "arm,cortex-a57";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -637,25 +652,25 @@ static void aarch64_a57_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043; cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004; cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838; cpu->reset_sctlr = 0x00c50838;
cpu->isar.id_pfr0 = 0x00000131; SET_IDREG(isar, ID_PFR0, 0x00000131);
cpu->isar.id_pfr1 = 0x00011011; SET_IDREG(isar, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066; SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105; SET_IDREG(isar, ID_MMFR0, 0x10101105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02102211; SET_IDREG(isar, ID_MMFR3, 0x02102211);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00011142; SET_IDREG(isar, ID_ISAR4, 0x00011142);
cpu->isar.id_isar5 = 0x00011121; SET_IDREG(isar, ID_ISAR5, 0x00011121);
cpu->isar.id_isar6 = 0; SET_IDREG(isar, ID_ISAR6, 0);
cpu->isar.id_aa64pfr0 = 0x00002222; SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
cpu->isar.id_aa64isar0 = 0x00011120; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64mmfr0 = 0x00001124; SET_IDREG(isar, ID_AA64MMFR0, 0x00001124);
cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x01110f13; cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x2; cpu->isar.dbgdevid1 = 0x2;
@ -678,6 +693,7 @@ static void aarch64_a57_initfn(Object *obj)
static void aarch64_a53_initfn(Object *obj) static void aarch64_a53_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a53"; cpu->dtb_compatible = "arm,cortex-a53";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -698,25 +714,25 @@ static void aarch64_a53_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043; cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x84448004; /* L1Ip = VIPT */ cpu->ctr = 0x84448004; /* L1Ip = VIPT */
cpu->reset_sctlr = 0x00c50838; cpu->reset_sctlr = 0x00c50838;
cpu->isar.id_pfr0 = 0x00000131; SET_IDREG(isar, ID_PFR0, 0x00000131);
cpu->isar.id_pfr1 = 0x00011011; SET_IDREG(isar, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066; SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105; SET_IDREG(isar, ID_MMFR0, 0x10101105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02102211; SET_IDREG(isar, ID_MMFR3, 0x02102211);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00011142; SET_IDREG(isar, ID_ISAR4, 0x00011142);
cpu->isar.id_isar5 = 0x00011121; SET_IDREG(isar, ID_ISAR5, 0x00011121);
cpu->isar.id_isar6 = 0; SET_IDREG(isar, ID_ISAR6, 0);
cpu->isar.id_aa64pfr0 = 0x00002222; SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
cpu->isar.id_aa64isar0 = 0x00011120; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ SET_IDREG(isar, ID_AA64MMFR0, 0x00001122); /* 40 bit physical addr */
cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x00110f13; cpu->isar.dbgdevid = 0x00110f13;
cpu->isar.dbgdevid1 = 0x1; cpu->isar.dbgdevid1 = 0x1;

View file

@ -6932,7 +6932,7 @@ static void define_pmu_regs(ARMCPU *cpu)
static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
{ {
ARMCPU *cpu = env_archcpu(env); ARMCPU *cpu = env_archcpu(env);
uint64_t pfr1 = cpu->isar.id_pfr1; uint64_t pfr1 = GET_IDREG(&cpu->isar, ID_PFR1);
if (env->gicv3state) { if (env->gicv3state) {
pfr1 |= 1 << 28; pfr1 |= 1 << 28;
@ -6943,7 +6943,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri) static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
{ {
ARMCPU *cpu = env_archcpu(env); ARMCPU *cpu = env_archcpu(env);
uint64_t pfr0 = cpu->isar.id_aa64pfr0; uint64_t pfr0 = GET_IDREG(&cpu->isar, ID_AA64PFR0);
if (env->gicv3state) { if (env->gicv3state) {
pfr0 |= 1 << 24; pfr0 |= 1 << 24;
@ -7750,6 +7750,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{ {
/* Register all the coprocessor registers based on feature bits */ /* Register all the coprocessor registers based on feature bits */
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
ARMISARegisters *isar = &cpu->isar;
if (arm_feature(env, ARM_FEATURE_M)) { if (arm_feature(env, ARM_FEATURE_M)) {
/* M profile has no coprocessor registers */ /* M profile has no coprocessor registers */
return; return;
@ -7775,7 +7777,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_pfr0 }, .resetvalue = GET_IDREG(isar, ID_PFR0)},
/* /*
* ID_PFR1 is not a plain ARM_CP_CONST because we don't know * ID_PFR1 is not a plain ARM_CP_CONST because we don't know
* the value of the GIC field until after we define these regs. * the value of the GIC field until after we define these regs.
@ -7786,7 +7788,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
.type = ARM_CP_CONST, .type = ARM_CP_CONST,
.resetvalue = cpu->isar.id_pfr1, .resetvalue = GET_IDREG(isar, ID_PFR1),
#else #else
.type = ARM_CP_NO_RAW, .type = ARM_CP_NO_RAW,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
@ -7798,7 +7800,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_dfr0 }, .resetvalue = GET_IDREG(isar, ID_DFR0)},
{ .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH, { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
@ -7808,62 +7810,62 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_mmfr0 }, .resetvalue = GET_IDREG(isar, ID_MMFR0)},
{ .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH, { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_mmfr1 }, .resetvalue = GET_IDREG(isar, ID_MMFR1)},
{ .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH, { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_mmfr2 }, .resetvalue = GET_IDREG(isar, ID_MMFR2)},
{ .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH, { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_mmfr3 }, .resetvalue = GET_IDREG(isar, ID_MMFR3)},
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH, { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_isar0 }, .resetvalue = GET_IDREG(isar, ID_ISAR0)},
{ .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH, { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_isar1 }, .resetvalue = GET_IDREG(isar, ID_ISAR1)},
{ .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH, { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_isar2 }, .resetvalue = GET_IDREG(isar, ID_ISAR2)},
{ .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH, { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_isar3 }, .resetvalue = GET_IDREG(isar, ID_ISAR3) },
{ .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH, { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_isar4 }, .resetvalue = GET_IDREG(isar, ID_ISAR4) },
{ .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH, { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_isar5 }, .resetvalue = GET_IDREG(isar, ID_ISAR5) },
{ .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH, { .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_mmfr4 }, .resetvalue = GET_IDREG(isar, ID_MMFR4)},
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH, { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3, .accessfn = access_aa32_tid3,
.resetvalue = cpu->isar.id_isar6 }, .resetvalue = GET_IDREG(isar, ID_ISAR6) },
}; };
define_arm_cp_regs(cpu, v6_idregs); define_arm_cp_regs(cpu, v6_idregs);
define_arm_cp_regs(cpu, v6_cp_reginfo); define_arm_cp_regs(cpu, v6_cp_reginfo);
@ -7914,7 +7916,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.access = PL1_R, .access = PL1_R,
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
.type = ARM_CP_CONST, .type = ARM_CP_CONST,
.resetvalue = cpu->isar.id_aa64pfr0 .resetvalue = GET_IDREG(isar, ID_AA64PFR0)
#else #else
.type = ARM_CP_NO_RAW, .type = ARM_CP_NO_RAW,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
@ -7926,7 +7928,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64pfr1}, .resetvalue = GET_IDREG(isar, ID_AA64PFR1)},
{ .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
@ -7941,12 +7943,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64zfr0 }, .resetvalue = GET_IDREG(isar, ID_AA64ZFR0)},
{ .name = "ID_AA64SMFR0_EL1", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64SMFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64smfr0 }, .resetvalue = GET_IDREG(isar, ID_AA64SMFR0)},
{ .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
@ -7961,12 +7963,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64dfr0 }, .resetvalue = GET_IDREG(isar, ID_AA64DFR0) },
{ .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64dfr1 }, .resetvalue = GET_IDREG(isar, ID_AA64DFR1) },
{ .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
@ -8001,17 +8003,17 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64isar0 }, .resetvalue = GET_IDREG(isar, ID_AA64ISAR0)},
{ .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64isar1 }, .resetvalue = GET_IDREG(isar, ID_AA64ISAR1)},
{ .name = "ID_AA64ISAR2_EL1", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64ISAR2_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64isar2 }, .resetvalue = GET_IDREG(isar, ID_AA64ISAR2)},
{ .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
@ -8041,22 +8043,22 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64mmfr0 }, .resetvalue = GET_IDREG(isar, ID_AA64MMFR0)},
{ .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64mmfr1 }, .resetvalue = GET_IDREG(isar, ID_AA64MMFR1) },
{ .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64mmfr2 }, .resetvalue = GET_IDREG(isar, ID_AA64MMFR2) },
{ .name = "ID_AA64MMFR3_EL1", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64MMFR3_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_aa64mmfr3 }, .resetvalue = GET_IDREG(isar, ID_AA64MMFR3) },
{ .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64, { .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
@ -8128,17 +8130,17 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_pfr2 }, .resetvalue = GET_IDREG(isar, ID_PFR2)},
{ .name = "ID_DFR1", .state = ARM_CP_STATE_BOTH, { .name = "ID_DFR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_dfr1 }, .resetvalue = GET_IDREG(isar, ID_DFR1)},
{ .name = "ID_MMFR5", .state = ARM_CP_STATE_BOTH, { .name = "ID_MMFR5", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3, .accessfn = access_aa64_tid3,
.resetvalue = cpu->isar.id_mmfr5 }, .resetvalue = GET_IDREG(isar, ID_MMFR5)},
{ .name = "RES_0_C0_C3_7", .state = ARM_CP_STATE_BOTH, { .name = "RES_0_C0_C3_7", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST, .access = PL1_R, .type = ARM_CP_CONST,

View file

@ -19,6 +19,7 @@
#include "system/hw_accel.h" #include "system/hw_accel.h"
#include "hvf_arm.h" #include "hvf_arm.h"
#include "cpregs.h" #include "cpregs.h"
#include "cpu-sysregs.h"
#include <mach/mach_time.h> #include <mach/mach_time.h>
@ -845,14 +846,17 @@ static uint64_t hvf_get_reg(CPUState *cpu, int rt)
return val; return val;
} }
static void clamp_id_aa64mmfr0_parange_to_ipa_size(uint64_t *id_aa64mmfr0) static void clamp_id_aa64mmfr0_parange_to_ipa_size(ARMISARegisters *isar)
{ {
uint32_t ipa_size = chosen_ipa_bit_size ? uint32_t ipa_size = chosen_ipa_bit_size ?
chosen_ipa_bit_size : hvf_arm_get_max_ipa_bit_size(); chosen_ipa_bit_size : hvf_arm_get_max_ipa_bit_size();
uint64_t id_aa64mmfr0;
/* Clamp down the PARange to the IPA size the kernel supports. */ /* Clamp down the PARange to the IPA size the kernel supports. */
uint8_t index = round_down_to_parange_index(ipa_size); uint8_t index = round_down_to_parange_index(ipa_size);
*id_aa64mmfr0 = (*id_aa64mmfr0 & ~R_ID_AA64MMFR0_PARANGE_MASK) | index; id_aa64mmfr0 = GET_IDREG(isar, ID_AA64MMFR0);
id_aa64mmfr0 = (id_aa64mmfr0 & ~R_ID_AA64MMFR0_PARANGE_MASK) | index;
SET_IDREG(isar, ID_AA64MMFR0, id_aa64mmfr0);
} }
static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
@ -862,16 +866,16 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
int reg; int reg;
uint64_t *val; uint64_t *val;
} regs[] = { } regs[] = {
{ HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.id_aa64pfr0 }, { HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.idregs[ID_AA64PFR0_EL1_IDX] },
{ HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.id_aa64pfr1 }, { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.idregs[ID_AA64PFR1_EL1_IDX] },
{ HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.id_aa64dfr0 }, { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.idregs[ID_AA64DFR0_EL1_IDX] },
{ HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.id_aa64dfr1 }, { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.idregs[ID_AA64DFR1_EL1_IDX] },
{ HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.id_aa64isar0 }, { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.idregs[ID_AA64ISAR0_EL1_IDX] },
{ HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.id_aa64isar1 }, { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.idregs[ID_AA64ISAR1_EL1_IDX] },
/* Add ID_AA64ISAR2_EL1 here when HVF supports it */ /* Add ID_AA64ISAR2_EL1 here when HVF supports it */
{ HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 }, { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.idregs[ID_AA64MMFR0_EL1_IDX] },
{ HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 }, { HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.idregs[ID_AA64MMFR1_EL1_IDX] },
{ HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.id_aa64mmfr2 }, { HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.idregs[ID_AA64MMFR2_EL1_IDX] },
/* Add ID_AA64MMFR3_EL1 here when HVF supports it */ /* Add ID_AA64MMFR3_EL1 here when HVF supports it */
}; };
hv_vcpu_t fd; hv_vcpu_t fd;
@ -879,7 +883,7 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
hv_vcpu_exit_t *exit; hv_vcpu_exit_t *exit;
int i; int i;
ahcf->dtb_compatible = "arm,arm-v8"; ahcf->dtb_compatible = "arm,armv8";
ahcf->features = (1ULL << ARM_FEATURE_V8) | ahcf->features = (1ULL << ARM_FEATURE_V8) |
(1ULL << ARM_FEATURE_NEON) | (1ULL << ARM_FEATURE_NEON) |
(1ULL << ARM_FEATURE_AARCH64) | (1ULL << ARM_FEATURE_AARCH64) |
@ -898,7 +902,7 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
r |= hv_vcpu_get_sys_reg(fd, HV_SYS_REG_MIDR_EL1, &ahcf->midr); r |= hv_vcpu_get_sys_reg(fd, HV_SYS_REG_MIDR_EL1, &ahcf->midr);
r |= hv_vcpu_destroy(fd); r |= hv_vcpu_destroy(fd);
clamp_id_aa64mmfr0_parange_to_ipa_size(&host_isar.id_aa64mmfr0); clamp_id_aa64mmfr0_parange_to_ipa_size(&host_isar);
/* /*
* Disable SME, which is not properly handled by QEMU hvf yet. * Disable SME, which is not properly handled by QEMU hvf yet.
@ -910,7 +914,8 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* - fix any assumptions we made that SME implies SVE (since * - fix any assumptions we made that SME implies SVE (since
* on the M4 there is SME but not SVE) * on the M4 there is SME but not SVE)
*/ */
host_isar.id_aa64pfr1 &= ~R_ID_AA64PFR1_SME_MASK; SET_IDREG(&host_isar, ID_AA64PFR1,
GET_IDREG(&host_isar, ID_AA64PFR1) & ~R_ID_AA64PFR1_SME_MASK);
ahcf->isar = host_isar; ahcf->isar = host_isar;
@ -927,7 +932,7 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ahcf->reset_sctlr |= 0x00800000; ahcf->reset_sctlr |= 0x00800000;
/* Make sure we don't advertise AArch32 support for EL0/EL1 */ /* Make sure we don't advertise AArch32 support for EL0/EL1 */
if ((host_isar.id_aa64pfr0 & 0xff) != 0x11) { if ((GET_IDREG(&host_isar, ID_AA64PFR0) & 0xff) != 0x11) {
return false; return false;
} }
@ -1065,12 +1070,12 @@ int hvf_arch_init_vcpu(CPUState *cpu)
/* We're limited to underlying hardware caps, override internal versions */ /* We're limited to underlying hardware caps, override internal versions */
ret = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_ID_AA64MMFR0_EL1, ret = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_ID_AA64MMFR0_EL1,
&arm_cpu->isar.id_aa64mmfr0); &arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]);
assert_hvf_ok(ret); assert_hvf_ok(ret);
clamp_id_aa64mmfr0_parange_to_ipa_size(&arm_cpu->isar.id_aa64mmfr0); clamp_id_aa64mmfr0_parange_to_ipa_size(&arm_cpu->isar);
ret = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_ID_AA64MMFR0_EL1, ret = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_ID_AA64MMFR0_EL1,
arm_cpu->isar.id_aa64mmfr0); arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]);
assert_hvf_ok(ret); assert_hvf_ok(ret);
return 0; return 0;
@ -1083,13 +1088,13 @@ void hvf_kick_vcpu_thread(CPUState *cpu)
} }
static void hvf_raise_exception(CPUState *cpu, uint32_t excp, static void hvf_raise_exception(CPUState *cpu, uint32_t excp,
uint32_t syndrome) uint32_t syndrome, int target_el)
{ {
ARMCPU *arm_cpu = ARM_CPU(cpu); ARMCPU *arm_cpu = ARM_CPU(cpu);
CPUARMState *env = &arm_cpu->env; CPUARMState *env = &arm_cpu->env;
cpu->exception_index = excp; cpu->exception_index = excp;
env->exception.target_el = 1; env->exception.target_el = target_el;
env->exception.syndrome = syndrome; env->exception.syndrome = syndrome;
arm_cpu_do_interrupt(cpu); arm_cpu_do_interrupt(cpu);
@ -1449,7 +1454,7 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint64_t *val)
SYSREG_CRN(reg), SYSREG_CRN(reg),
SYSREG_CRM(reg), SYSREG_CRM(reg),
SYSREG_OP2(reg)); SYSREG_OP2(reg));
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized()); hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized(), 1);
return 1; return 1;
} }
@ -1759,7 +1764,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
SYSREG_CRN(reg), SYSREG_CRN(reg),
SYSREG_CRM(reg), SYSREG_CRM(reg),
SYSREG_OP2(reg)); SYSREG_OP2(reg));
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized()); hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized(), 1);
return 1; return 1;
} }
@ -1910,7 +1915,17 @@ int hvf_vcpu_exec(CPUState *cpu)
flush_cpu_state(cpu); flush_cpu_state(cpu);
bql_unlock(); bql_unlock();
assert_hvf_ok(hv_vcpu_run(cpu->accel->fd)); r = hv_vcpu_run(cpu->accel->fd);
bql_lock();
switch (r) {
case HV_SUCCESS:
break;
case HV_ILLEGAL_GUEST_STATE:
trace_hvf_illegal_guest_state();
/* fall through */
default:
g_assert_not_reached();
}
/* handle VMEXIT */ /* handle VMEXIT */
uint64_t exit_reason = hvf_exit->reason; uint64_t exit_reason = hvf_exit->reason;
@ -1918,7 +1933,6 @@ int hvf_vcpu_exec(CPUState *cpu)
uint32_t ec = syn_get_ec(syndrome); uint32_t ec = syn_get_ec(syndrome);
ret = 0; ret = 0;
bql_lock();
switch (exit_reason) { switch (exit_reason) {
case HV_EXIT_REASON_EXCEPTION: case HV_EXIT_REASON_EXCEPTION:
/* This is the main one, handle below. */ /* This is the main one, handle below. */
@ -1953,7 +1967,7 @@ int hvf_vcpu_exec(CPUState *cpu)
if (!hvf_find_sw_breakpoint(cpu, env->pc)) { if (!hvf_find_sw_breakpoint(cpu, env->pc)) {
/* Re-inject into the guest */ /* Re-inject into the guest */
ret = 0; ret = 0;
hvf_raise_exception(cpu, EXCP_BKPT, syn_aa64_bkpt(0)); hvf_raise_exception(cpu, EXCP_BKPT, syn_aa64_bkpt(0), 1);
} }
break; break;
} }
@ -2058,13 +2072,13 @@ int hvf_vcpu_exec(CPUState *cpu)
cpu_synchronize_state(cpu); cpu_synchronize_state(cpu);
if (arm_cpu->psci_conduit == QEMU_PSCI_CONDUIT_HVC) { if (arm_cpu->psci_conduit == QEMU_PSCI_CONDUIT_HVC) {
if (!hvf_handle_psci_call(cpu)) { if (!hvf_handle_psci_call(cpu)) {
trace_hvf_unknown_hvc(env->xregs[0]); trace_hvf_unknown_hvc(env->pc, env->xregs[0]);
/* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */ /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
env->xregs[0] = -1; env->xregs[0] = -1;
} }
} else { } else {
trace_hvf_unknown_hvc(env->xregs[0]); trace_hvf_unknown_hvc(env->pc, env->xregs[0]);
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized()); hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized(), 1);
} }
break; break;
case EC_AA64_SMC: case EC_AA64_SMC:
@ -2079,7 +2093,7 @@ int hvf_vcpu_exec(CPUState *cpu)
} }
} else { } else {
trace_hvf_unknown_smc(env->xregs[0]); trace_hvf_unknown_smc(env->xregs[0]);
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized()); hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized(), 1);
} }
break; break;
default: default:

View file

@ -5,9 +5,10 @@ hvf_inject_irq(void) "injecting IRQ"
hvf_data_abort(uint64_t pc, uint64_t va, uint64_t pa, bool isv, bool iswrite, bool s1ptw, uint32_t len, uint32_t srt) "data abort: [pc=0x%"PRIx64" va=0x%016"PRIx64" pa=0x%016"PRIx64" isv=%d iswrite=%d s1ptw=%d len=%d srt=%d]" hvf_data_abort(uint64_t pc, uint64_t va, uint64_t pa, bool isv, bool iswrite, bool s1ptw, uint32_t len, uint32_t srt) "data abort: [pc=0x%"PRIx64" va=0x%016"PRIx64" pa=0x%016"PRIx64" isv=%d iswrite=%d s1ptw=%d len=%d srt=%d]"
hvf_sysreg_read(uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2, uint64_t val) "sysreg read 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d) = 0x%016"PRIx64 hvf_sysreg_read(uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2, uint64_t val) "sysreg read 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d) = 0x%016"PRIx64
hvf_sysreg_write(uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2, uint64_t val) "sysreg write 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d, val=0x%016"PRIx64")" hvf_sysreg_write(uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2, uint64_t val) "sysreg write 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d, val=0x%016"PRIx64")"
hvf_unknown_hvc(uint64_t x0) "unknown HVC! 0x%016"PRIx64 hvf_unknown_hvc(uint64_t pc, uint64_t x0) "pc=0x%"PRIx64" unknown HVC! 0x%016"PRIx64
hvf_unknown_smc(uint64_t x0) "unknown SMC! 0x%016"PRIx64 hvf_unknown_smc(uint64_t x0) "unknown SMC! 0x%016"PRIx64
hvf_exit(uint64_t syndrome, uint32_t ec, uint64_t pc) "exit: 0x%"PRIx64" [ec=0x%x pc=0x%"PRIx64"]" hvf_exit(uint64_t syndrome, uint32_t ec, uint64_t pc) "exit: 0x%"PRIx64" [ec=0x%x pc=0x%"PRIx64"]"
hvf_psci_call(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint32_t cpuid) "PSCI Call x0=0x%016"PRIx64" x1=0x%016"PRIx64" x2=0x%016"PRIx64" x3=0x%016"PRIx64" cpu=0x%x" hvf_psci_call(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint32_t cpuid) "PSCI Call x0=0x%016"PRIx64" x1=0x%016"PRIx64" x2=0x%016"PRIx64" x3=0x%016"PRIx64" cpuid=0x%x"
hvf_vgic_write(const char *name, uint64_t val) "vgic write to %s [val=0x%016"PRIx64"]" hvf_vgic_write(const char *name, uint64_t val) "vgic write to %s [val=0x%016"PRIx64"]"
hvf_vgic_read(const char *name, uint64_t val) "vgic read from %s [val=0x%016"PRIx64"]" hvf_vgic_read(const char *name, uint64_t val) "vgic read from %s [val=0x%016"PRIx64"]"
hvf_illegal_guest_state(void) "HV_ILLEGAL_GUEST_STATE"

View file

@ -650,16 +650,12 @@ static inline bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
{ {
return false; return false;
} }
static inline void arm_handle_psci_call(ARMCPU *cpu)
{
g_assert_not_reached();
}
#else #else
/* Return true if the r0/x0 value indicates that this SMC/HVC is a PSCI call. */ /* Return true if the r0/x0 value indicates that this SMC/HVC is a PSCI call. */
bool arm_is_psci_call(ARMCPU *cpu, int excp_type); bool arm_is_psci_call(ARMCPU *cpu, int excp_type);
#endif
/* Actually handle a PSCI call */ /* Actually handle a PSCI call */
void arm_handle_psci_call(ARMCPU *cpu); void arm_handle_psci_call(ARMCPU *cpu);
#endif
/** /**
* arm_clear_exclusive: clear the exclusive monitor * arm_clear_exclusive: clear the exclusive monitor
@ -1175,7 +1171,7 @@ static inline bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
static inline int arm_num_brps(ARMCPU *cpu) static inline int arm_num_brps(ARMCPU *cpu)
{ {
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1; return FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, BRPS) + 1;
} else { } else {
return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1; return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1;
} }
@ -1189,7 +1185,7 @@ static inline int arm_num_brps(ARMCPU *cpu)
static inline int arm_num_wrps(ARMCPU *cpu) static inline int arm_num_wrps(ARMCPU *cpu)
{ {
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1; return FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, WRPS) + 1;
} else { } else {
return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1; return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1;
} }
@ -1203,7 +1199,7 @@ static inline int arm_num_wrps(ARMCPU *cpu)
static inline int arm_num_ctx_cmps(ARMCPU *cpu) static inline int arm_num_ctx_cmps(ARMCPU *cpu)
{ {
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1; return FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, CTX_CMPS) + 1;
} else { } else {
return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1; return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1;
} }

View file

@ -26,6 +26,7 @@
#include "system/kvm_int.h" #include "system/kvm_int.h"
#include "kvm_arm.h" #include "kvm_arm.h"
#include "cpu.h" #include "cpu.h"
#include "cpu-sysregs.h"
#include "trace.h" #include "trace.h"
#include "internals.h" #include "internals.h"
#include "hw/pci/pci.h" #include "hw/pci/pci.h"
@ -218,6 +219,28 @@ static bool kvm_arm_pauth_supported(void)
kvm_check_extension(kvm_state, KVM_CAP_ARM_PTRAUTH_GENERIC)); kvm_check_extension(kvm_state, KVM_CAP_ARM_PTRAUTH_GENERIC));
} }
static uint64_t idregs_sysreg_to_kvm_reg(ARMSysRegs sysreg)
{
return ARM64_SYS_REG((sysreg & CP_REG_ARM64_SYSREG_OP0_MASK) >> CP_REG_ARM64_SYSREG_OP0_SHIFT,
(sysreg & CP_REG_ARM64_SYSREG_OP1_MASK) >> CP_REG_ARM64_SYSREG_OP1_SHIFT,
(sysreg & CP_REG_ARM64_SYSREG_CRN_MASK) >> CP_REG_ARM64_SYSREG_CRN_SHIFT,
(sysreg & CP_REG_ARM64_SYSREG_CRM_MASK) >> CP_REG_ARM64_SYSREG_CRM_SHIFT,
(sysreg & CP_REG_ARM64_SYSREG_OP2_MASK) >> CP_REG_ARM64_SYSREG_OP2_SHIFT);
}
/* read a sysreg value and store it in the idregs */
static int get_host_cpu_reg(int fd, ARMHostCPUFeatures *ahcf, ARMIDRegisterIdx index)
{
uint64_t *reg;
int ret;
reg = &ahcf->isar.idregs[index];
ret = read_sys_reg64(fd, reg,
idregs_sysreg_to_kvm_reg(id_register_sysreg[index]));
return ret;
}
static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{ {
/* Identify the feature bits corresponding to the host CPU, and /* Identify the feature bits corresponding to the host CPU, and
@ -266,10 +289,10 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
} }
ahcf->target = init.target; ahcf->target = init.target;
ahcf->dtb_compatible = "arm,arm-v8"; ahcf->dtb_compatible = "arm,armv8";
int fd = fdarray[2];
err = read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr0, err = get_host_cpu_reg(fd, ahcf, ID_AA64PFR0_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 4, 0));
if (unlikely(err < 0)) { if (unlikely(err < 0)) {
/* /*
* Before v4.15, the kernel only exposed a limited number of system * Before v4.15, the kernel only exposed a limited number of system
@ -287,31 +310,20 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* ??? Either of these sounds like too much effort just * ??? Either of these sounds like too much effort just
* to work around running a modern host kernel. * to work around running a modern host kernel.
*/ */
ahcf->isar.id_aa64pfr0 = 0x00000011; /* EL1&0, AArch64 only */ SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */
err = 0; err = 0;
} else { } else {
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1, err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 4, 1)); err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX);
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64smfr0, err |= get_host_cpu_reg(fd, ahcf, ID_AA64DFR0_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 4, 5)); err |= get_host_cpu_reg(fd, ahcf, ID_AA64DFR1_EL1_IDX);
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0, err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR0_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 5, 0)); err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR1_EL1_IDX);
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1, err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR2_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 5, 1)); err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR0_EL1_IDX);
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0, err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR1_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 6, 0)); err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR2_EL1_IDX);
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1, err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR3_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 6, 1));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar2,
ARM64_SYS_REG(3, 0, 0, 6, 2));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0,
ARM64_SYS_REG(3, 0, 0, 7, 0));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
ARM64_SYS_REG(3, 0, 0, 7, 1));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
ARM64_SYS_REG(3, 0, 0, 7, 2));
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr3,
ARM64_SYS_REG(3, 0, 0, 7, 3));
/* /*
* Note that if AArch32 support is not present in the host, * Note that if AArch32 support is not present in the host,
@ -320,49 +332,31 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* than skipping the reads and leaving 0, as we must avoid * than skipping the reads and leaving 0, as we must avoid
* considering the values in every case. * considering the values in every case.
*/ */
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr0, err |= get_host_cpu_reg(fd, ahcf, ID_PFR0_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 1, 0)); err |= get_host_cpu_reg(fd, ahcf, ID_PFR1_EL1_IDX);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1, err |= get_host_cpu_reg(fd, ahcf, ID_DFR0_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 1, 1)); err |= get_host_cpu_reg(fd, ahcf, ID_MMFR0_EL1_IDX);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0, err |= get_host_cpu_reg(fd, ahcf, ID_MMFR1_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 1, 2)); err |= get_host_cpu_reg(fd, ahcf, ID_MMFR2_EL1_IDX);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0, err |= get_host_cpu_reg(fd, ahcf, ID_MMFR3_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 1, 4)); err |= get_host_cpu_reg(fd, ahcf, ID_ISAR0_EL1_IDX);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1, err |= get_host_cpu_reg(fd, ahcf, ID_ISAR1_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 1, 5)); err |= get_host_cpu_reg(fd, ahcf, ID_ISAR2_EL1_IDX);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2, err |= get_host_cpu_reg(fd, ahcf, ID_ISAR3_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 1, 6)); err |= get_host_cpu_reg(fd, ahcf, ID_ISAR4_EL1_IDX);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3, err |= get_host_cpu_reg(fd, ahcf, ID_ISAR5_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 1, 7)); err |= get_host_cpu_reg(fd, ahcf, ID_ISAR6_EL1_IDX);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0, err |= get_host_cpu_reg(fd, ahcf, ID_MMFR4_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 2, 0));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
ARM64_SYS_REG(3, 0, 0, 2, 1));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar2,
ARM64_SYS_REG(3, 0, 0, 2, 2));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar3,
ARM64_SYS_REG(3, 0, 0, 2, 3));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar4,
ARM64_SYS_REG(3, 0, 0, 2, 4));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5,
ARM64_SYS_REG(3, 0, 0, 2, 5));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
ARM64_SYS_REG(3, 0, 0, 2, 6));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6,
ARM64_SYS_REG(3, 0, 0, 2, 7));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0, err |= read_sys_reg32(fd, &ahcf->isar.mvfr0,
ARM64_SYS_REG(3, 0, 0, 3, 0)); ARM64_SYS_REG(3, 0, 0, 3, 0));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr1, err |= read_sys_reg32(fd, &ahcf->isar.mvfr1,
ARM64_SYS_REG(3, 0, 0, 3, 1)); ARM64_SYS_REG(3, 0, 0, 3, 1));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2, err |= read_sys_reg32(fd, &ahcf->isar.mvfr2,
ARM64_SYS_REG(3, 0, 0, 3, 2)); ARM64_SYS_REG(3, 0, 0, 3, 2));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2, err |= get_host_cpu_reg(fd, ahcf, ID_PFR2_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 3, 4)); err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX);
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr1, err |= get_host_cpu_reg(fd, ahcf, ID_MMFR5_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 3, 5));
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr5,
ARM64_SYS_REG(3, 0, 0, 3, 6));
/* /*
* DBGDIDR is a bit complicated because the kernel doesn't * DBGDIDR is a bit complicated because the kernel doesn't
@ -374,14 +368,14 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* arch/arm64/kvm/sys_regs.c:trap_dbgidr() does. * arch/arm64/kvm/sys_regs.c:trap_dbgidr() does.
* We only do this if the CPU supports AArch32 at EL1. * We only do this if the CPU supports AArch32 at EL1.
*/ */
if (FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL1) >= 2) { if (FIELD_EX32_IDREG(&ahcf->isar, ID_AA64PFR0, EL1) >= 2) {
int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS); int wrps = FIELD_EX64_IDREG(&ahcf->isar, ID_AA64DFR0, WRPS);
int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS); int brps = FIELD_EX64_IDREG(&ahcf->isar, ID_AA64DFR0, BRPS);
int ctx_cmps = int ctx_cmps =
FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS); FIELD_EX64_IDREG(&ahcf->isar, ID_AA64DFR0, CTX_CMPS);
int version = 6; /* ARMv8 debug architecture */ int version = 6; /* ARMv8 debug architecture */
bool has_el3 = bool has_el3 =
!!FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL3); !!FIELD_EX32_IDREG(&ahcf->isar, ID_AA64PFR0, EL3);
uint32_t dbgdidr = 0; uint32_t dbgdidr = 0;
dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps); dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps);
@ -396,7 +390,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
if (pmu_supported) { if (pmu_supported) {
/* PMCR_EL0 is only accessible if the vCPU has feature PMU_V3 */ /* PMCR_EL0 is only accessible if the vCPU has feature PMU_V3 */
err |= read_sys_reg64(fdarray[2], &ahcf->isar.reset_pmcr_el0, err |= read_sys_reg64(fd, &ahcf->isar.reset_pmcr_el0,
ARM64_SYS_REG(3, 3, 9, 12, 0)); ARM64_SYS_REG(3, 3, 9, 12, 0));
} }
@ -408,8 +402,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* enabled SVE support, which resulted in an error rather than RAZ. * enabled SVE support, which resulted in an error rather than RAZ.
* So only read the register if we set KVM_ARM_VCPU_SVE above. * So only read the register if we set KVM_ARM_VCPU_SVE above.
*/ */
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64zfr0, err |= get_host_cpu_reg(fd, ahcf, ID_AA64ZFR0_EL1_IDX);
ARM64_SYS_REG(3, 0, 0, 4, 4));
} }
} }

View file

@ -122,7 +122,7 @@ unsigned int arm_pamax(ARMCPU *cpu)
{ {
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
unsigned int parange = unsigned int parange =
FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); FIELD_EX64_IDREG(&cpu->isar, ID_AA64MMFR0, PARANGE);
/* /*
* id_aa64mmfr0 is a read-only register so values outside of the * id_aa64mmfr0 is a read-only register so values outside of the
@ -332,7 +332,7 @@ static bool granule_protection_check(CPUARMState *env, uint64_t paddress,
* physical address size is invalid. * physical address size is invalid.
*/ */
pps = FIELD_EX64(gpccr, GPCCR, PPS); pps = FIELD_EX64(gpccr, GPCCR, PPS);
if (pps > FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE)) { if (pps > FIELD_EX64_IDREG(&cpu->isar, ID_AA64MMFR0, PARANGE)) {
goto fault_walk; goto fault_walk;
} }
pps = pamax_map[pps]; pps = pamax_map[pps];
@ -1703,7 +1703,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
* ID_AA64MMFR0 is a read-only register so values outside of the * ID_AA64MMFR0 is a read-only register so values outside of the
* supported mappings can be considered an implementation error. * supported mappings can be considered an implementation error.
*/ */
ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); ps = FIELD_EX64_IDREG(&cpu->isar, ID_AA64MMFR0, PARANGE);
ps = MIN(ps, param.ps); ps = MIN(ps, param.ps);
assert(ps < ARRAY_SIZE(pamax_map)); assert(ps < ARRAY_SIZE(pamax_map));
outputsize = pamax_map[ps]; outputsize = pamax_map[ps];

View file

@ -45,6 +45,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
static void cortex_m0_initfn(Object *obj) static void cortex_m0_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V6); set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_M); set_feature(&cpu->env, ARM_FEATURE_M);
@ -58,51 +59,53 @@ static void cortex_m0_initfn(Object *obj)
* by looking at ID register fields. We use the same values as * by looking at ID register fields. We use the same values as
* for the M3. * for the M3.
*/ */
cpu->isar.id_pfr0 = 0x00000030; SET_IDREG(isar, ID_PFR0, 0x00000030);
cpu->isar.id_pfr1 = 0x00000200; SET_IDREG(isar, ID_PFR1, 0x00000200);
cpu->isar.id_dfr0 = 0x00100000; SET_IDREG(isar, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030; SET_IDREG(isar, ID_MMFR0, 0x00000030);
cpu->isar.id_mmfr1 = 0x00000000; SET_IDREG(isar, ID_MMFR1, 0x00000000);
cpu->isar.id_mmfr2 = 0x00000000; SET_IDREG(isar, ID_MMFR2, 0x00000000);
cpu->isar.id_mmfr3 = 0x00000000; SET_IDREG(isar, ID_MMFR3, 0x00000000);
cpu->isar.id_isar0 = 0x01141110; SET_IDREG(isar, ID_ISAR0, 0x01141110);
cpu->isar.id_isar1 = 0x02111000; SET_IDREG(isar, ID_ISAR1, 0x02111000);
cpu->isar.id_isar2 = 0x21112231; SET_IDREG(isar, ID_ISAR2, 0x21112231);
cpu->isar.id_isar3 = 0x01111110; SET_IDREG(isar, ID_ISAR3, 0x01111110);
cpu->isar.id_isar4 = 0x01310102; SET_IDREG(isar, ID_ISAR4, 0x01310102);
cpu->isar.id_isar5 = 0x00000000; SET_IDREG(isar, ID_ISAR5, 0x00000000);
cpu->isar.id_isar6 = 0x00000000; SET_IDREG(isar, ID_ISAR6, 0x00000000);
} }
static void cortex_m3_initfn(Object *obj) static void cortex_m3_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M); set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN); set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
cpu->midr = 0x410fc231; cpu->midr = 0x410fc231;
cpu->pmsav7_dregion = 8; cpu->pmsav7_dregion = 8;
cpu->isar.id_pfr0 = 0x00000030; SET_IDREG(isar, ID_PFR0, 0x00000030);
cpu->isar.id_pfr1 = 0x00000200; SET_IDREG(isar, ID_PFR1, 0x00000200);
cpu->isar.id_dfr0 = 0x00100000; SET_IDREG(isar, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030; SET_IDREG(isar, ID_MMFR0, 0x00000030);
cpu->isar.id_mmfr1 = 0x00000000; SET_IDREG(isar, ID_MMFR1, 0x00000000);
cpu->isar.id_mmfr2 = 0x00000000; SET_IDREG(isar, ID_MMFR2, 0x00000000);
cpu->isar.id_mmfr3 = 0x00000000; SET_IDREG(isar, ID_MMFR3, 0x00000000);
cpu->isar.id_isar0 = 0x01141110; SET_IDREG(isar, ID_ISAR0, 0x01141110);
cpu->isar.id_isar1 = 0x02111000; SET_IDREG(isar, ID_ISAR1, 0x02111000);
cpu->isar.id_isar2 = 0x21112231; SET_IDREG(isar, ID_ISAR2, 0x21112231);
cpu->isar.id_isar3 = 0x01111110; SET_IDREG(isar, ID_ISAR3, 0x01111110);
cpu->isar.id_isar4 = 0x01310102; SET_IDREG(isar, ID_ISAR4, 0x01310102);
cpu->isar.id_isar5 = 0x00000000; SET_IDREG(isar, ID_ISAR5, 0x00000000);
cpu->isar.id_isar6 = 0x00000000; SET_IDREG(isar, ID_ISAR6, 0x00000000);
} }
static void cortex_m4_initfn(Object *obj) static void cortex_m4_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M); set_feature(&cpu->env, ARM_FEATURE_M);
@ -113,26 +116,27 @@ static void cortex_m4_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110021; cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011; cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000000; cpu->isar.mvfr2 = 0x00000000;
cpu->isar.id_pfr0 = 0x00000030; SET_IDREG(isar, ID_PFR0, 0x00000030);
cpu->isar.id_pfr1 = 0x00000200; SET_IDREG(isar, ID_PFR1, 0x00000200);
cpu->isar.id_dfr0 = 0x00100000; SET_IDREG(isar, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030; SET_IDREG(isar, ID_MMFR0, 0x00000030);
cpu->isar.id_mmfr1 = 0x00000000; SET_IDREG(isar, ID_MMFR1, 0x00000000);
cpu->isar.id_mmfr2 = 0x00000000; SET_IDREG(isar, ID_MMFR2, 0x00000000);
cpu->isar.id_mmfr3 = 0x00000000; SET_IDREG(isar, ID_MMFR3, 0x00000000);
cpu->isar.id_isar0 = 0x01141110; SET_IDREG(isar, ID_ISAR0, 0x01141110);
cpu->isar.id_isar1 = 0x02111000; SET_IDREG(isar, ID_ISAR1, 0x02111000);
cpu->isar.id_isar2 = 0x21112231; SET_IDREG(isar, ID_ISAR2, 0x21112231);
cpu->isar.id_isar3 = 0x01111110; SET_IDREG(isar, ID_ISAR3, 0x01111110);
cpu->isar.id_isar4 = 0x01310102; SET_IDREG(isar, ID_ISAR4, 0x01310102);
cpu->isar.id_isar5 = 0x00000000; SET_IDREG(isar, ID_ISAR5, 0x00000000);
cpu->isar.id_isar6 = 0x00000000; SET_IDREG(isar, ID_ISAR6, 0x00000000);
} }
static void cortex_m7_initfn(Object *obj) static void cortex_m7_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M); set_feature(&cpu->env, ARM_FEATURE_M);
@ -143,26 +147,27 @@ static void cortex_m7_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110221; cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x12000011; cpu->isar.mvfr1 = 0x12000011;
cpu->isar.mvfr2 = 0x00000040; cpu->isar.mvfr2 = 0x00000040;
cpu->isar.id_pfr0 = 0x00000030; SET_IDREG(isar, ID_PFR0, 0x00000030);
cpu->isar.id_pfr1 = 0x00000200; SET_IDREG(isar, ID_PFR1, 0x00000200);
cpu->isar.id_dfr0 = 0x00100000; SET_IDREG(isar, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00100030; SET_IDREG(isar, ID_MMFR0, 0x00100030);
cpu->isar.id_mmfr1 = 0x00000000; SET_IDREG(isar, ID_MMFR1, 0x00000000);
cpu->isar.id_mmfr2 = 0x01000000; SET_IDREG(isar, ID_MMFR2, 0x01000000);
cpu->isar.id_mmfr3 = 0x00000000; SET_IDREG(isar, ID_MMFR3, 0x00000000);
cpu->isar.id_isar0 = 0x01101110; SET_IDREG(isar, ID_ISAR0, 0x01101110);
cpu->isar.id_isar1 = 0x02112000; SET_IDREG(isar, ID_ISAR1, 0x02112000);
cpu->isar.id_isar2 = 0x20232231; SET_IDREG(isar, ID_ISAR2, 0x20232231);
cpu->isar.id_isar3 = 0x01111131; SET_IDREG(isar, ID_ISAR3, 0x01111131);
cpu->isar.id_isar4 = 0x01310132; SET_IDREG(isar, ID_ISAR4, 0x01310132);
cpu->isar.id_isar5 = 0x00000000; SET_IDREG(isar, ID_ISAR5, 0x00000000);
cpu->isar.id_isar6 = 0x00000000; SET_IDREG(isar, ID_ISAR6, 0x00000000);
} }
static void cortex_m33_initfn(Object *obj) static void cortex_m33_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_M); set_feature(&cpu->env, ARM_FEATURE_M);
@ -175,21 +180,21 @@ static void cortex_m33_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110021; cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011; cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000040; cpu->isar.mvfr2 = 0x00000040;
cpu->isar.id_pfr0 = 0x00000030; SET_IDREG(isar, ID_PFR0, 0x00000030);
cpu->isar.id_pfr1 = 0x00000210; SET_IDREG(isar, ID_PFR1, 0x00000210);
cpu->isar.id_dfr0 = 0x00200000; SET_IDREG(isar, ID_DFR0, 0x00200000);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00101F40; SET_IDREG(isar, ID_MMFR0, 0x00101F40);
cpu->isar.id_mmfr1 = 0x00000000; SET_IDREG(isar, ID_MMFR1, 0x00000000);
cpu->isar.id_mmfr2 = 0x01000000; SET_IDREG(isar, ID_MMFR2, 0x01000000);
cpu->isar.id_mmfr3 = 0x00000000; SET_IDREG(isar, ID_MMFR3, 0x00000000);
cpu->isar.id_isar0 = 0x01101110; SET_IDREG(isar, ID_ISAR0, 0x01101110);
cpu->isar.id_isar1 = 0x02212000; SET_IDREG(isar, ID_ISAR1, 0x02212000);
cpu->isar.id_isar2 = 0x20232232; SET_IDREG(isar, ID_ISAR2, 0x20232232);
cpu->isar.id_isar3 = 0x01111131; SET_IDREG(isar, ID_ISAR3, 0x01111131);
cpu->isar.id_isar4 = 0x01310132; SET_IDREG(isar, ID_ISAR4, 0x01310132);
cpu->isar.id_isar5 = 0x00000000; SET_IDREG(isar, ID_ISAR5, 0x00000000);
cpu->isar.id_isar6 = 0x00000000; SET_IDREG(isar, ID_ISAR6, 0x00000000);
cpu->clidr = 0x00000000; cpu->clidr = 0x00000000;
cpu->ctr = 0x8000c000; cpu->ctr = 0x8000c000;
} }
@ -197,6 +202,7 @@ static void cortex_m33_initfn(Object *obj)
static void cortex_m55_initfn(Object *obj) static void cortex_m55_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_V8_1M); set_feature(&cpu->env, ARM_FEATURE_V8_1M);
@ -212,21 +218,21 @@ static void cortex_m55_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110221; cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x12100211; cpu->isar.mvfr1 = 0x12100211;
cpu->isar.mvfr2 = 0x00000040; cpu->isar.mvfr2 = 0x00000040;
cpu->isar.id_pfr0 = 0x20000030; SET_IDREG(isar, ID_PFR0, 0x20000030);
cpu->isar.id_pfr1 = 0x00000230; SET_IDREG(isar, ID_PFR1, 0x00000230);
cpu->isar.id_dfr0 = 0x10200000; SET_IDREG(isar, ID_DFR0, 0x10200000);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00111040; SET_IDREG(isar, ID_MMFR0, 0x00111040);
cpu->isar.id_mmfr1 = 0x00000000; SET_IDREG(isar, ID_MMFR1, 0x00000000);
cpu->isar.id_mmfr2 = 0x01000000; SET_IDREG(isar, ID_MMFR2, 0x01000000);
cpu->isar.id_mmfr3 = 0x00000011; SET_IDREG(isar, ID_MMFR3, 0x00000011);
cpu->isar.id_isar0 = 0x01103110; SET_IDREG(isar, ID_ISAR0, 0x01103110);
cpu->isar.id_isar1 = 0x02212000; SET_IDREG(isar, ID_ISAR1, 0x02212000);
cpu->isar.id_isar2 = 0x20232232; SET_IDREG(isar, ID_ISAR2, 0x20232232);
cpu->isar.id_isar3 = 0x01111131; SET_IDREG(isar, ID_ISAR3, 0x01111131);
cpu->isar.id_isar4 = 0x01310132; SET_IDREG(isar, ID_ISAR4, 0x01310132);
cpu->isar.id_isar5 = 0x00000000; SET_IDREG(isar, ID_ISAR5, 0x00000000);
cpu->isar.id_isar6 = 0x00000000; SET_IDREG(isar, ID_ISAR6, 0x00000000);
cpu->clidr = 0x00000000; /* caches not implemented */ cpu->clidr = 0x00000000; /* caches not implemented */
cpu->ctr = 0x8303c003; cpu->ctr = 0x8303c003;
} }

View file

@ -23,18 +23,19 @@
void aa32_max_features(ARMCPU *cpu) void aa32_max_features(ARMCPU *cpu)
{ {
uint32_t t; uint32_t t;
ARMISARegisters *isar = &cpu->isar;
/* Add additional features supported by QEMU */ /* Add additional features supported by QEMU */
t = cpu->isar.id_isar5; t = GET_IDREG(isar, ID_ISAR5);
t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */ t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */
t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */
t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */
t = FIELD_DP32(t, ID_ISAR5, CRC32, 1); t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */ t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */
t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */
cpu->isar.id_isar5 = t; SET_IDREG(isar, ID_ISAR5, t);
t = cpu->isar.id_isar6; t = GET_IDREG(isar, ID_ISAR6);
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */
t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */ t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */
t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */ t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */
@ -42,7 +43,7 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */
t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */ t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */
t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */
cpu->isar.id_isar6 = t; SET_IDREG(isar, ID_ISAR6, t);
t = cpu->isar.mvfr1; t = cpu->isar.mvfr1;
t = FIELD_DP32(t, MVFR1, FPHP, 3); /* FEAT_FP16 */ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* FEAT_FP16 */
@ -54,38 +55,34 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
cpu->isar.mvfr2 = t; cpu->isar.mvfr2 = t;
t = cpu->isar.id_mmfr3; FIELD_DP32_IDREG(isar, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
cpu->isar.id_mmfr3 = t;
t = cpu->isar.id_mmfr4; t = GET_IDREG(isar, ID_MMFR4);
t = FIELD_DP32(t, ID_MMFR4, HPDS, 2); /* FEAT_HPDS2 */ t = FIELD_DP32(t, ID_MMFR4, HPDS, 2); /* FEAT_HPDS2 */
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */
t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX */ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX */
t = FIELD_DP32(t, ID_MMFR4, EVT, 2); /* FEAT_EVT */ t = FIELD_DP32(t, ID_MMFR4, EVT, 2); /* FEAT_EVT */
cpu->isar.id_mmfr4 = t; SET_IDREG(isar, ID_MMFR4, t);
t = cpu->isar.id_mmfr5; FIELD_DP32_IDREG(isar, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
t = FIELD_DP32(t, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
cpu->isar.id_mmfr5 = t;
t = cpu->isar.id_pfr0; t = GET_IDREG(isar, ID_PFR0);
t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CSV2 */ t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CSV2 */
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */ t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */ t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
cpu->isar.id_pfr0 = t; SET_IDREG(isar, ID_PFR0, t);
t = cpu->isar.id_pfr2; t = GET_IDREG(isar, ID_PFR2);
t = FIELD_DP32(t, ID_PFR2, CSV3, 1); /* FEAT_CSV3 */ t = FIELD_DP32(t, ID_PFR2, CSV3, 1); /* FEAT_CSV3 */
t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */ t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
cpu->isar.id_pfr2 = t; SET_IDREG(isar, ID_PFR2, t);
t = cpu->isar.id_dfr0; t = GET_IDREG(isar, ID_DFR0);
t = FIELD_DP32(t, ID_DFR0, COPDBG, 10); /* FEAT_Debugv8p8 */ t = FIELD_DP32(t, ID_DFR0, COPDBG, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP32(t, ID_DFR0, COPSDBG, 10); /* FEAT_Debugv8p8 */ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */ t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */
cpu->isar.id_dfr0 = t; SET_IDREG(isar, ID_DFR0, t);
/* Debug ID registers. */ /* Debug ID registers. */
@ -115,9 +112,7 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, DBGDEVID1, PCSROFFSET, 2); t = FIELD_DP32(t, DBGDEVID1, PCSROFFSET, 2);
cpu->isar.dbgdevid1 = t; cpu->isar.dbgdevid1 = t;
t = cpu->isar.id_dfr1; FIELD_DP32_IDREG(isar, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
t = FIELD_DP32(t, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
cpu->isar.id_dfr1 = t;
} }
/* CPU models. These are not needed for the AArch64 linux-user build. */ /* CPU models. These are not needed for the AArch64 linux-user build. */
@ -140,7 +135,7 @@ static void arm926_initfn(Object *obj)
* ARMv5 does not have the ID_ISAR registers, but we can still * ARMv5 does not have the ID_ISAR registers, but we can still
* set the field to indicate Jazelle support within QEMU. * set the field to indicate Jazelle support within QEMU.
*/ */
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1); FIELD_DP32_IDREG(&cpu->isar, ID_ISAR1, JAZELLE, 1);
/* /*
* Similarly, we need to set MVFR0 fields to enable vfp and short vector * Similarly, we need to set MVFR0 fields to enable vfp and short vector
* support even though ARMv5 doesn't have this register. * support even though ARMv5 doesn't have this register.
@ -182,7 +177,7 @@ static void arm1026_initfn(Object *obj)
* ARMv5 does not have the ID_ISAR registers, but we can still * ARMv5 does not have the ID_ISAR registers, but we can still
* set the field to indicate Jazelle support within QEMU. * set the field to indicate Jazelle support within QEMU.
*/ */
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1); FIELD_DP32_IDREG(&cpu->isar, ID_ISAR1, JAZELLE, 1);
/* /*
* Similarly, we need to set MVFR0 fields to enable vfp and short vector * Similarly, we need to set MVFR0 fields to enable vfp and short vector
* support even though ARMv5 doesn't have this register. * support even though ARMv5 doesn't have this register.
@ -206,6 +201,7 @@ static void arm1026_initfn(Object *obj)
static void arm1136_r2_initfn(Object *obj) static void arm1136_r2_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
/* /*
* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an * What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
* older core than plain "arm1136". In particular this does not * older core than plain "arm1136". In particular this does not
@ -226,24 +222,25 @@ static void arm1136_r2_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00000000; cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2; cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078; cpu->reset_sctlr = 0x00050078;
cpu->isar.id_pfr0 = 0x111; SET_IDREG(isar, ID_PFR0, 0x111);
cpu->isar.id_pfr1 = 0x1; SET_IDREG(isar, ID_PFR1, 0x1);
cpu->isar.id_dfr0 = 0x2; SET_IDREG(isar, ID_DFR0, 0x2);
cpu->id_afr0 = 0x3; cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003; SET_IDREG(isar, ID_MMFR0, 0x01130003);
cpu->isar.id_mmfr1 = 0x10030302; SET_IDREG(isar, ID_MMFR1, 0x10030302);
cpu->isar.id_mmfr2 = 0x01222110; SET_IDREG(isar, ID_MMFR2, 0x01222110);
cpu->isar.id_isar0 = 0x00140011; SET_IDREG(isar, ID_ISAR0, 0x00140011);
cpu->isar.id_isar1 = 0x12002111; SET_IDREG(isar, ID_ISAR1, 0x12002111);
cpu->isar.id_isar2 = 0x11231111; SET_IDREG(isar, ID_ISAR2, 0x11231111);
cpu->isar.id_isar3 = 0x01102131; SET_IDREG(isar, ID_ISAR3, 0x01102131);
cpu->isar.id_isar4 = 0x141; SET_IDREG(isar, ID_ISAR4, 0x141);
cpu->reset_auxcr = 7; cpu->reset_auxcr = 7;
} }
static void arm1136_initfn(Object *obj) static void arm1136_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,arm1136"; cpu->dtb_compatible = "arm,arm1136";
set_feature(&cpu->env, ARM_FEATURE_V6K); set_feature(&cpu->env, ARM_FEATURE_V6K);
@ -257,24 +254,25 @@ static void arm1136_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00000000; cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2; cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078; cpu->reset_sctlr = 0x00050078;
cpu->isar.id_pfr0 = 0x111; SET_IDREG(isar, ID_PFR0, 0x111);
cpu->isar.id_pfr1 = 0x1; SET_IDREG(isar, ID_PFR1, 0x1);
cpu->isar.id_dfr0 = 0x2; SET_IDREG(isar, ID_DFR0, 0x2);
cpu->id_afr0 = 0x3; cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003; SET_IDREG(isar, ID_MMFR0, 0x01130003);
cpu->isar.id_mmfr1 = 0x10030302; SET_IDREG(isar, ID_MMFR1, 0x10030302);
cpu->isar.id_mmfr2 = 0x01222110; SET_IDREG(isar, ID_MMFR2, 0x01222110);
cpu->isar.id_isar0 = 0x00140011; SET_IDREG(isar, ID_ISAR0, 0x00140011);
cpu->isar.id_isar1 = 0x12002111; SET_IDREG(isar, ID_ISAR1, 0x12002111);
cpu->isar.id_isar2 = 0x11231111; SET_IDREG(isar, ID_ISAR2, 0x11231111);
cpu->isar.id_isar3 = 0x01102131; SET_IDREG(isar, ID_ISAR3, 0x01102131);
cpu->isar.id_isar4 = 0x141; SET_IDREG(isar, ID_ISAR4, 0x141);
cpu->reset_auxcr = 7; cpu->reset_auxcr = 7;
} }
static void arm1176_initfn(Object *obj) static void arm1176_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,arm1176"; cpu->dtb_compatible = "arm,arm1176";
set_feature(&cpu->env, ARM_FEATURE_V6K); set_feature(&cpu->env, ARM_FEATURE_V6K);
@ -289,24 +287,25 @@ static void arm1176_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00000000; cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2; cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078; cpu->reset_sctlr = 0x00050078;
cpu->isar.id_pfr0 = 0x111; SET_IDREG(isar, ID_PFR0, 0x111);
cpu->isar.id_pfr1 = 0x11; SET_IDREG(isar, ID_PFR1, 0x11);
cpu->isar.id_dfr0 = 0x33; SET_IDREG(isar, ID_DFR0, 0x33);
cpu->id_afr0 = 0; cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x01130003; SET_IDREG(isar, ID_MMFR0, 0x01130003);
cpu->isar.id_mmfr1 = 0x10030302; SET_IDREG(isar, ID_MMFR1, 0x10030302);
cpu->isar.id_mmfr2 = 0x01222100; SET_IDREG(isar, ID_MMFR2, 0x01222100);
cpu->isar.id_isar0 = 0x0140011; SET_IDREG(isar, ID_ISAR0, 0x0140011);
cpu->isar.id_isar1 = 0x12002111; SET_IDREG(isar, ID_ISAR1, 0x12002111);
cpu->isar.id_isar2 = 0x11231121; SET_IDREG(isar, ID_ISAR2, 0x11231121);
cpu->isar.id_isar3 = 0x01102131; SET_IDREG(isar, ID_ISAR3, 0x01102131);
cpu->isar.id_isar4 = 0x01141; SET_IDREG(isar, ID_ISAR4, 0x01141);
cpu->reset_auxcr = 7; cpu->reset_auxcr = 7;
} }
static void arm11mpcore_initfn(Object *obj) static void arm11mpcore_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,arm11mpcore"; cpu->dtb_compatible = "arm,arm11mpcore";
set_feature(&cpu->env, ARM_FEATURE_V6K); set_feature(&cpu->env, ARM_FEATURE_V6K);
@ -318,18 +317,18 @@ static void arm11mpcore_initfn(Object *obj)
cpu->isar.mvfr0 = 0x11111111; cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000; cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */ cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
cpu->isar.id_pfr0 = 0x111; SET_IDREG(isar, ID_PFR0, 0x111);
cpu->isar.id_pfr1 = 0x1; SET_IDREG(isar, ID_PFR1, 0x1);
cpu->isar.id_dfr0 = 0; SET_IDREG(isar, ID_DFR0, 0);
cpu->id_afr0 = 0x2; cpu->id_afr0 = 0x2;
cpu->isar.id_mmfr0 = 0x01100103; SET_IDREG(isar, ID_MMFR0, 0x01100103);
cpu->isar.id_mmfr1 = 0x10020302; SET_IDREG(isar, ID_MMFR1, 0x10020302);
cpu->isar.id_mmfr2 = 0x01222000; SET_IDREG(isar, ID_MMFR2, 0x01222000);
cpu->isar.id_isar0 = 0x00100011; SET_IDREG(isar, ID_ISAR0, 0x00100011);
cpu->isar.id_isar1 = 0x12002111; SET_IDREG(isar, ID_ISAR1, 0x12002111);
cpu->isar.id_isar2 = 0x11221011; SET_IDREG(isar, ID_ISAR2, 0x11221011);
cpu->isar.id_isar3 = 0x01102131; SET_IDREG(isar, ID_ISAR3, 0x01102131);
cpu->isar.id_isar4 = 0x141; SET_IDREG(isar, ID_ISAR4, 0x141);
cpu->reset_auxcr = 1; cpu->reset_auxcr = 1;
} }
@ -343,6 +342,7 @@ static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
static void cortex_a8_initfn(Object *obj) static void cortex_a8_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a8"; cpu->dtb_compatible = "arm,cortex-a8";
set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_V7);
@ -357,19 +357,19 @@ static void cortex_a8_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00011111; cpu->isar.mvfr1 = 0x00011111;
cpu->ctr = 0x82048004; cpu->ctr = 0x82048004;
cpu->reset_sctlr = 0x00c50078; cpu->reset_sctlr = 0x00c50078;
cpu->isar.id_pfr0 = 0x1031; SET_IDREG(isar, ID_PFR0, 0x1031);
cpu->isar.id_pfr1 = 0x11; SET_IDREG(isar, ID_PFR1, 0x11);
cpu->isar.id_dfr0 = 0x400; SET_IDREG(isar, ID_DFR0, 0x400);
cpu->id_afr0 = 0; cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x31100003; SET_IDREG(isar, ID_MMFR0, 0x31100003);
cpu->isar.id_mmfr1 = 0x20000000; SET_IDREG(isar, ID_MMFR1, 0x20000000);
cpu->isar.id_mmfr2 = 0x01202000; SET_IDREG(isar, ID_MMFR2, 0x01202000);
cpu->isar.id_mmfr3 = 0x11; SET_IDREG(isar, ID_MMFR3, 0x11);
cpu->isar.id_isar0 = 0x00101111; SET_IDREG(isar, ID_ISAR0, 0x00101111);
cpu->isar.id_isar1 = 0x12112111; SET_IDREG(isar, ID_ISAR1, 0x12112111);
cpu->isar.id_isar2 = 0x21232031; SET_IDREG(isar, ID_ISAR2, 0x21232031);
cpu->isar.id_isar3 = 0x11112131; SET_IDREG(isar, ID_ISAR3, 0x11112131);
cpu->isar.id_isar4 = 0x00111142; SET_IDREG(isar, ID_ISAR4, 0x00111142);
cpu->isar.dbgdidr = 0x15141000; cpu->isar.dbgdidr = 0x15141000;
cpu->clidr = (1 << 27) | (2 << 24) | 3; cpu->clidr = (1 << 27) | (2 << 24) | 3;
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
@ -412,6 +412,7 @@ static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
static void cortex_a9_initfn(Object *obj) static void cortex_a9_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a9"; cpu->dtb_compatible = "arm,cortex-a9";
set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_V7);
@ -432,19 +433,19 @@ static void cortex_a9_initfn(Object *obj)
cpu->isar.mvfr1 = 0x01111111; cpu->isar.mvfr1 = 0x01111111;
cpu->ctr = 0x80038003; cpu->ctr = 0x80038003;
cpu->reset_sctlr = 0x00c50078; cpu->reset_sctlr = 0x00c50078;
cpu->isar.id_pfr0 = 0x1031; SET_IDREG(isar, ID_PFR0, 0x1031);
cpu->isar.id_pfr1 = 0x11; SET_IDREG(isar, ID_PFR1, 0x11);
cpu->isar.id_dfr0 = 0x000; SET_IDREG(isar, ID_DFR0, 0x000);
cpu->id_afr0 = 0; cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x00100103; SET_IDREG(isar, ID_MMFR0, 0x00100103);
cpu->isar.id_mmfr1 = 0x20000000; SET_IDREG(isar, ID_MMFR1, 0x20000000);
cpu->isar.id_mmfr2 = 0x01230000; SET_IDREG(isar, ID_MMFR2, 0x01230000);
cpu->isar.id_mmfr3 = 0x00002111; SET_IDREG(isar, ID_MMFR3, 0x00002111);
cpu->isar.id_isar0 = 0x00101111; SET_IDREG(isar, ID_ISAR0, 0x00101111);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232041; SET_IDREG(isar, ID_ISAR2, 0x21232041);
cpu->isar.id_isar3 = 0x11112131; SET_IDREG(isar, ID_ISAR3, 0x11112131);
cpu->isar.id_isar4 = 0x00111142; SET_IDREG(isar, ID_ISAR4, 0x00111142);
cpu->isar.dbgdidr = 0x35141000; cpu->isar.dbgdidr = 0x35141000;
cpu->clidr = (1 << 27) | (1 << 24) | 3; cpu->clidr = (1 << 27) | (1 << 24) | 3;
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */ cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
@ -479,6 +480,7 @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
static void cortex_a7_initfn(Object *obj) static void cortex_a7_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a7"; cpu->dtb_compatible = "arm,cortex-a7";
set_feature(&cpu->env, ARM_FEATURE_V7VE); set_feature(&cpu->env, ARM_FEATURE_V7VE);
@ -497,23 +499,23 @@ static void cortex_a7_initfn(Object *obj)
cpu->isar.mvfr1 = 0x11111111; cpu->isar.mvfr1 = 0x11111111;
cpu->ctr = 0x84448003; cpu->ctr = 0x84448003;
cpu->reset_sctlr = 0x00c50078; cpu->reset_sctlr = 0x00c50078;
cpu->isar.id_pfr0 = 0x00001131; SET_IDREG(isar, ID_PFR0, 0x00001131);
cpu->isar.id_pfr1 = 0x00011011; SET_IDREG(isar, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x02010555; SET_IDREG(isar, ID_DFR0, 0x02010555);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105; SET_IDREG(isar, ID_MMFR0, 0x10101105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01240000; SET_IDREG(isar, ID_MMFR2, 0x01240000);
cpu->isar.id_mmfr3 = 0x02102211; SET_IDREG(isar, ID_MMFR3, 0x02102211);
/* /*
* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
* table 4-41 gives 0x02101110, which includes the arm div insns. * table 4-41 gives 0x02101110, which includes the arm div insns.
*/ */
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232041; SET_IDREG(isar, ID_ISAR2, 0x21232041);
cpu->isar.id_isar3 = 0x11112131; SET_IDREG(isar, ID_ISAR3, 0x11112131);
cpu->isar.id_isar4 = 0x10011142; SET_IDREG(isar, ID_ISAR4, 0x10011142);
cpu->isar.dbgdidr = 0x3515f005; cpu->isar.dbgdidr = 0x3515f005;
cpu->isar.dbgdevid = 0x01110f13; cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x1; cpu->isar.dbgdevid1 = 0x1;
@ -528,6 +530,7 @@ static void cortex_a7_initfn(Object *obj)
static void cortex_a15_initfn(Object *obj) static void cortex_a15_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a15"; cpu->dtb_compatible = "arm,cortex-a15";
set_feature(&cpu->env, ARM_FEATURE_V7VE); set_feature(&cpu->env, ARM_FEATURE_V7VE);
@ -548,19 +551,19 @@ static void cortex_a15_initfn(Object *obj)
cpu->isar.mvfr1 = 0x11111111; cpu->isar.mvfr1 = 0x11111111;
cpu->ctr = 0x8444c004; cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50078; cpu->reset_sctlr = 0x00c50078;
cpu->isar.id_pfr0 = 0x00001131; SET_IDREG(isar, ID_PFR0, 0x00001131);
cpu->isar.id_pfr1 = 0x00011011; SET_IDREG(isar, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x02010555; SET_IDREG(isar, ID_DFR0, 0x02010555);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10201105; SET_IDREG(isar, ID_MMFR0, 0x10201105);
cpu->isar.id_mmfr1 = 0x20000000; SET_IDREG(isar, ID_MMFR1, 0x20000000);
cpu->isar.id_mmfr2 = 0x01240000; SET_IDREG(isar, ID_MMFR2, 0x01240000);
cpu->isar.id_mmfr3 = 0x02102211; SET_IDREG(isar, ID_MMFR3, 0x02102211);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232041; SET_IDREG(isar, ID_ISAR2, 0x21232041);
cpu->isar.id_isar3 = 0x11112131; SET_IDREG(isar, ID_ISAR3, 0x11112131);
cpu->isar.id_isar4 = 0x10011142; SET_IDREG(isar, ID_ISAR4, 0x10011142);
cpu->isar.dbgdidr = 0x3515f021; cpu->isar.dbgdidr = 0x3515f021;
cpu->isar.dbgdevid = 0x01110f13; cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x0; cpu->isar.dbgdevid1 = 0x0;
@ -585,27 +588,28 @@ static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
static void cortex_r5_initfn(Object *obj) static void cortex_r5_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_V7MP); set_feature(&cpu->env, ARM_FEATURE_V7MP);
set_feature(&cpu->env, ARM_FEATURE_PMSA); set_feature(&cpu->env, ARM_FEATURE_PMSA);
set_feature(&cpu->env, ARM_FEATURE_PMU); set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->midr = 0x411fc153; /* r1p3 */ cpu->midr = 0x411fc153; /* r1p3 */
cpu->isar.id_pfr0 = 0x0131; SET_IDREG(isar, ID_PFR0, 0x0131);
cpu->isar.id_pfr1 = 0x001; SET_IDREG(isar, ID_PFR1, 0x001);
cpu->isar.id_dfr0 = 0x010400; SET_IDREG(isar, ID_DFR0, 0x010400);
cpu->id_afr0 = 0x0; cpu->id_afr0 = 0x0;
cpu->isar.id_mmfr0 = 0x0210030; SET_IDREG(isar, ID_MMFR0, 0x0210030);
cpu->isar.id_mmfr1 = 0x00000000; SET_IDREG(isar, ID_MMFR1, 0x00000000);
cpu->isar.id_mmfr2 = 0x01200000; SET_IDREG(isar, ID_MMFR2, 0x01200000);
cpu->isar.id_mmfr3 = 0x0211; SET_IDREG(isar, ID_MMFR3, 0x0211);
cpu->isar.id_isar0 = 0x02101111; SET_IDREG(isar, ID_ISAR0, 0x02101111);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232141; SET_IDREG(isar, ID_ISAR2, 0x21232141);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x0010142; SET_IDREG(isar, ID_ISAR4, 0x0010142);
cpu->isar.id_isar5 = 0x0; SET_IDREG(isar, ID_ISAR5, 0x0);
cpu->isar.id_isar6 = 0x0; SET_IDREG(isar, ID_ISAR6, 0x0);
cpu->mp_is_up = true; cpu->mp_is_up = true;
cpu->pmsav7_dregion = 16; cpu->pmsav7_dregion = 16;
cpu->isar.reset_pmcr_el0 = 0x41151800; cpu->isar.reset_pmcr_el0 = 0x41151800;
@ -720,6 +724,7 @@ static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
static void cortex_r52_initfn(Object *obj) static void cortex_r52_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_EL2); set_feature(&cpu->env, ARM_FEATURE_EL2);
@ -737,21 +742,21 @@ static void cortex_r52_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043; cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8144c004; cpu->ctr = 0x8144c004;
cpu->reset_sctlr = 0x30c50838; cpu->reset_sctlr = 0x30c50838;
cpu->isar.id_pfr0 = 0x00000131; SET_IDREG(isar, ID_PFR0, 0x00000131);
cpu->isar.id_pfr1 = 0x10111001; SET_IDREG(isar, ID_PFR1, 0x10111001);
cpu->isar.id_dfr0 = 0x03010006; SET_IDREG(isar, ID_DFR0, 0x03010006);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00211040; SET_IDREG(isar, ID_MMFR0, 0x00211040);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01200000; SET_IDREG(isar, ID_MMFR2, 0x01200000);
cpu->isar.id_mmfr3 = 0xf0102211; SET_IDREG(isar, ID_MMFR3, 0xf0102211);
cpu->isar.id_mmfr4 = 0x00000010; SET_IDREG(isar, ID_MMFR4, 0x00000010);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232142; SET_IDREG(isar, ID_ISAR2, 0x21232142);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00010142; SET_IDREG(isar, ID_ISAR4, 0x00010142);
cpu->isar.id_isar5 = 0x00010001; SET_IDREG(isar, ID_ISAR5, 0x00010001);
cpu->isar.dbgdidr = 0x77168000; cpu->isar.dbgdidr = 0x77168000;
cpu->clidr = (1 << 27) | (1 << 24) | 0x3; cpu->clidr = (1 << 27) | (1 << 24) | 0x3;
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */ cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
@ -949,6 +954,7 @@ static void pxa270c5_initfn(Object *obj)
static void arm_max_initfn(Object *obj) static void arm_max_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
/* aarch64_a57_initfn, advertising none of the aarch64 features */ /* aarch64_a57_initfn, advertising none of the aarch64 features */
cpu->dtb_compatible = "arm,cortex-a57"; cpu->dtb_compatible = "arm,cortex-a57";
@ -968,21 +974,21 @@ static void arm_max_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043; cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004; cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838; cpu->reset_sctlr = 0x00c50838;
cpu->isar.id_pfr0 = 0x00000131; SET_IDREG(isar, ID_PFR0, 0x00000131);
cpu->isar.id_pfr1 = 0x00011011; SET_IDREG(isar, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066; SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10101105; SET_IDREG(isar, ID_MMFR0, 0x10101105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02102211; SET_IDREG(isar, ID_MMFR3, 0x02102211);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00011142; SET_IDREG(isar, ID_ISAR4, 0x00011142);
cpu->isar.id_isar5 = 0x00011121; SET_IDREG(isar, ID_ISAR5, 0x00011121);
cpu->isar.id_isar6 = 0; SET_IDREG(isar, ID_ISAR6, 0);
cpu->isar.reset_pmcr_el0 = 0x41013000; cpu->isar.reset_pmcr_el0 = 0x41013000;
cpu->clidr = 0x0a200023; cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */

View file

@ -32,6 +32,7 @@
static void aarch64_a35_initfn(Object *obj) static void aarch64_a35_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a35"; cpu->dtb_compatible = "arm,cortex-a35";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -48,28 +49,28 @@ static void aarch64_a35_initfn(Object *obj)
cpu->midr = 0x411fd040; cpu->midr = 0x411fd040;
cpu->revidr = 0; cpu->revidr = 0;
cpu->ctr = 0x84448004; cpu->ctr = 0x84448004;
cpu->isar.id_pfr0 = 0x00000131; SET_IDREG(isar, ID_PFR0, 0x00000131);
cpu->isar.id_pfr1 = 0x00011011; SET_IDREG(isar, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066; SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0; cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x10201105; SET_IDREG(isar, ID_MMFR0, 0x10201105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02102211; SET_IDREG(isar, ID_MMFR3, 0x02102211);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00011142; SET_IDREG(isar, ID_ISAR4, 0x00011142);
cpu->isar.id_isar5 = 0x00011121; SET_IDREG(isar, ID_ISAR5, 0x00011121);
cpu->isar.id_aa64pfr0 = 0x00002222; SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64pfr1 = 0; SET_IDREG(isar, ID_AA64PFR1, 0);
cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
cpu->isar.id_aa64dfr1 = 0; SET_IDREG(isar, ID_AA64DFR1, 0);
cpu->isar.id_aa64isar0 = 0x00011120; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64isar1 = 0; SET_IDREG(isar, ID_AA64ISAR1, 0);
cpu->isar.id_aa64mmfr0 = 0x00101122; SET_IDREG(isar, ID_AA64MMFR0, 0x00101122);
cpu->isar.id_aa64mmfr1 = 0; SET_IDREG(isar, ID_AA64MMFR1, 0);
cpu->clidr = 0x0a200023; cpu->clidr = 0x0a200023;
cpu->dcz_blocksize = 4; cpu->dcz_blocksize = 4;
@ -157,11 +158,8 @@ static bool cpu_arm_get_rme(Object *obj, Error **errp)
static void cpu_arm_set_rme(Object *obj, bool value, Error **errp) static void cpu_arm_set_rme(Object *obj, bool value, Error **errp)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
uint64_t t;
t = cpu->isar.id_aa64pfr0; FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR0, RME, value);
t = FIELD_DP64(t, ID_AA64PFR0, RME, value);
cpu->isar.id_aa64pfr0 = t;
} }
static void cpu_max_set_l0gptsz(Object *obj, Visitor *v, const char *name, static void cpu_max_set_l0gptsz(Object *obj, Visitor *v, const char *name,
@ -204,6 +202,7 @@ static const Property arm_cpu_lpa2_property =
static void aarch64_a55_initfn(Object *obj) static void aarch64_a55_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a55"; cpu->dtb_compatible = "arm,cortex-a55";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -220,31 +219,31 @@ static void aarch64_a55_initfn(Object *obj)
cpu->clidr = 0x82000023; cpu->clidr = 0x82000023;
cpu->ctr = 0x84448004; /* L1Ip = VIPT */ cpu->ctr = 0x84448004; /* L1Ip = VIPT */
cpu->dcz_blocksize = 4; /* 64 bytes */ cpu->dcz_blocksize = 4; /* 64 bytes */
cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; SET_IDREG(isar, ID_AA64DFR0, 0x0000000010305408ull);
cpu->isar.id_aa64isar0 = 0x0000100010211120ull; SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull);
cpu->isar.id_aa64isar1 = 0x0000000000100001ull; SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull);
cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101122ull);
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011ull);
cpu->isar.id_aa64pfr0 = 0x0000000010112222ull; SET_IDREG(isar, ID_AA64PFR0, 0x0000000010112222ull);
cpu->isar.id_aa64pfr1 = 0x0000000000000010ull; SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x04010088; SET_IDREG(isar, ID_DFR0, 0x04010088);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00011142; SET_IDREG(isar, ID_ISAR4, 0x00011142);
cpu->isar.id_isar5 = 0x01011121; SET_IDREG(isar, ID_ISAR5, 0x01011121);
cpu->isar.id_isar6 = 0x00000010; SET_IDREG(isar, ID_ISAR6, 0x00000010);
cpu->isar.id_mmfr0 = 0x10201105; SET_IDREG(isar, ID_MMFR0, 0x10201105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02122211; SET_IDREG(isar, ID_MMFR3, 0x02122211);
cpu->isar.id_mmfr4 = 0x00021110; SET_IDREG(isar, ID_MMFR4, 0x00021110);
cpu->isar.id_pfr0 = 0x10010131; SET_IDREG(isar, ID_PFR0, 0x10010131);
cpu->isar.id_pfr1 = 0x00011011; SET_IDREG(isar, ID_PFR1, 0x00011011);
cpu->isar.id_pfr2 = 0x00000011; SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x412FD050; /* r2p0 */ cpu->midr = 0x412FD050; /* r2p0 */
cpu->revidr = 0; cpu->revidr = 0;
@ -276,6 +275,7 @@ static void aarch64_a55_initfn(Object *obj)
static void aarch64_a72_initfn(Object *obj) static void aarch64_a72_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a72"; cpu->dtb_compatible = "arm,cortex-a72";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -295,24 +295,24 @@ static void aarch64_a72_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043; cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004; cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838; cpu->reset_sctlr = 0x00c50838;
cpu->isar.id_pfr0 = 0x00000131; SET_IDREG(isar, ID_PFR0, 0x00000131);
cpu->isar.id_pfr1 = 0x00011011; SET_IDREG(isar, ID_PFR1, 0x00011011);
cpu->isar.id_dfr0 = 0x03010066; SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x10201105; SET_IDREG(isar, ID_MMFR0, 0x10201105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02102211; SET_IDREG(isar, ID_MMFR3, 0x02102211);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00011142; SET_IDREG(isar, ID_ISAR4, 0x00011142);
cpu->isar.id_isar5 = 0x00011121; SET_IDREG(isar, ID_ISAR5, 0x00011121);
cpu->isar.id_aa64pfr0 = 0x00002222; SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
cpu->isar.id_aa64isar0 = 0x00011120; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
cpu->isar.id_aa64mmfr0 = 0x00001124; SET_IDREG(isar, ID_AA64MMFR0, 0x00001124);
cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x01110f13; cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x2; cpu->isar.dbgdevid1 = 0x2;
@ -335,6 +335,7 @@ static void aarch64_a72_initfn(Object *obj)
static void aarch64_a76_initfn(Object *obj) static void aarch64_a76_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a76"; cpu->dtb_compatible = "arm,cortex-a76";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -351,31 +352,31 @@ static void aarch64_a76_initfn(Object *obj)
cpu->clidr = 0x82000023; cpu->clidr = 0x82000023;
cpu->ctr = 0x8444C004; cpu->ctr = 0x8444C004;
cpu->dcz_blocksize = 4; cpu->dcz_blocksize = 4;
cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; SET_IDREG(isar, ID_AA64DFR0, 0x0000000010305408ull),
cpu->isar.id_aa64isar0 = 0x0000100010211120ull; SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull);
cpu->isar.id_aa64isar1 = 0x0000000000100001ull; SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull);
cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101122ull);
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011ull);
cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
cpu->isar.id_aa64pfr1 = 0x0000000000000010ull; SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x04010088; SET_IDREG(isar, ID_DFR0, 0x04010088);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00010142; SET_IDREG(isar, ID_ISAR4, 0x00010142);
cpu->isar.id_isar5 = 0x01011121; SET_IDREG(isar, ID_ISAR5, 0x01011121);
cpu->isar.id_isar6 = 0x00000010; SET_IDREG(isar, ID_ISAR6, 0x00000010);
cpu->isar.id_mmfr0 = 0x10201105; SET_IDREG(isar, ID_MMFR0, 0x10201105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02122211; SET_IDREG(isar, ID_MMFR3, 0x02122211);
cpu->isar.id_mmfr4 = 0x00021110; SET_IDREG(isar, ID_MMFR4, 0x00021110);
cpu->isar.id_pfr0 = 0x10010131; SET_IDREG(isar, ID_PFR0, 0x10010131);
cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
cpu->isar.id_pfr2 = 0x00000011; SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x414fd0b1; /* r4p1 */ cpu->midr = 0x414fd0b1; /* r4p1 */
cpu->revidr = 0; cpu->revidr = 0;
@ -408,6 +409,7 @@ static void aarch64_a76_initfn(Object *obj)
static void aarch64_a64fx_initfn(Object *obj) static void aarch64_a64fx_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,a64fx"; cpu->dtb_compatible = "arm,a64fx";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -422,18 +424,18 @@ static void aarch64_a64fx_initfn(Object *obj)
cpu->revidr = 0x00000000; cpu->revidr = 0x00000000;
cpu->ctr = 0x86668006; cpu->ctr = 0x86668006;
cpu->reset_sctlr = 0x30000180; cpu->reset_sctlr = 0x30000180;
cpu->isar.id_aa64pfr0 = 0x0000000101111111; /* No RAS Extensions */ SET_IDREG(isar, ID_AA64PFR0, 0x0000000101111111); /* No RAS Extensions */
cpu->isar.id_aa64pfr1 = 0x0000000000000000; SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000000);
cpu->isar.id_aa64dfr0 = 0x0000000010305408; SET_IDREG(isar, ID_AA64DFR0, 0x0000000010305408),
cpu->isar.id_aa64dfr1 = 0x0000000000000000; SET_IDREG(isar, ID_AA64DFR1, 0x0000000000000000),
cpu->id_aa64afr0 = 0x0000000000000000; cpu->id_aa64afr0 = 0x0000000000000000;
cpu->id_aa64afr1 = 0x0000000000000000; cpu->id_aa64afr1 = 0x0000000000000000;
cpu->isar.id_aa64mmfr0 = 0x0000000000001122; SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000001122);
cpu->isar.id_aa64mmfr1 = 0x0000000011212100; SET_IDREG(isar, ID_AA64MMFR1, 0x0000000011212100);
cpu->isar.id_aa64mmfr2 = 0x0000000000001011; SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011);
cpu->isar.id_aa64isar0 = 0x0000000010211120; SET_IDREG(isar, ID_AA64ISAR0, 0x0000000010211120);
cpu->isar.id_aa64isar1 = 0x0000000000010001; SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000010001);
cpu->isar.id_aa64zfr0 = 0x0000000000000000; SET_IDREG(isar, ID_AA64ZFR0, 0x0000000000000000);
cpu->clidr = 0x0000000080000023; cpu->clidr = 0x0000000080000023;
/* 64KB L1 dcache */ /* 64KB L1 dcache */
cpu->ccsidr[0] = make_ccsidr(CCSIDR_FORMAT_LEGACY, 4, 256, 64 * KiB, 7); cpu->ccsidr[0] = make_ccsidr(CCSIDR_FORMAT_LEGACY, 4, 256, 64 * KiB, 7);
@ -581,6 +583,7 @@ static void define_neoverse_v1_cp_reginfo(ARMCPU *cpu)
static void aarch64_neoverse_n1_initfn(Object *obj) static void aarch64_neoverse_n1_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,neoverse-n1"; cpu->dtb_compatible = "arm,neoverse-n1";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -597,31 +600,31 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
cpu->clidr = 0x82000023; cpu->clidr = 0x82000023;
cpu->ctr = 0x8444c004; cpu->ctr = 0x8444c004;
cpu->dcz_blocksize = 4; cpu->dcz_blocksize = 4;
cpu->isar.id_aa64dfr0 = 0x0000000110305408ull; SET_IDREG(isar, ID_AA64DFR0, 0x0000000110305408ull);
cpu->isar.id_aa64isar0 = 0x0000100010211120ull; SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull);
cpu->isar.id_aa64isar1 = 0x0000000000100001ull; SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull);
cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101125ull);
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011ull);
cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
cpu->isar.id_aa64pfr1 = 0x0000000000000020ull; SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x04010088; SET_IDREG(isar, ID_DFR0, 0x04010088);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00010142; SET_IDREG(isar, ID_ISAR4, 0x00010142);
cpu->isar.id_isar5 = 0x01011121; SET_IDREG(isar, ID_ISAR5, 0x01011121);
cpu->isar.id_isar6 = 0x00000010; SET_IDREG(isar, ID_ISAR6, 0x00000010);
cpu->isar.id_mmfr0 = 0x10201105; SET_IDREG(isar, ID_MMFR0, 0x10201105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02122211; SET_IDREG(isar, ID_MMFR3, 0x02122211);
cpu->isar.id_mmfr4 = 0x00021110; SET_IDREG(isar, ID_MMFR4, 0x00021110);
cpu->isar.id_pfr0 = 0x10010131; SET_IDREG(isar, ID_PFR0, 0x10010131);
cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
cpu->isar.id_pfr2 = 0x00000011; SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x414fd0c1; /* r4p1 */ cpu->midr = 0x414fd0c1; /* r4p1 */
cpu->revidr = 0; cpu->revidr = 0;
@ -656,6 +659,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
static void aarch64_neoverse_v1_initfn(Object *obj) static void aarch64_neoverse_v1_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,neoverse-v1"; cpu->dtb_compatible = "arm,neoverse-v1";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -674,32 +678,32 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->dcz_blocksize = 4; cpu->dcz_blocksize = 4;
cpu->id_aa64afr0 = 0x00000000; cpu->id_aa64afr0 = 0x00000000;
cpu->id_aa64afr1 = 0x00000000; cpu->id_aa64afr1 = 0x00000000;
cpu->isar.id_aa64dfr0 = 0x000001f210305519ull; SET_IDREG(isar, ID_AA64DFR0, 0x000001f210305519ull),
cpu->isar.id_aa64dfr1 = 0x00000000; SET_IDREG(isar, ID_AA64DFR1, 0x00000000),
cpu->isar.id_aa64isar0 = 0x1011111110212120ull; /* with FEAT_RNG */ SET_IDREG(isar, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */
cpu->isar.id_aa64isar1 = 0x0011100001211032ull; SET_IDREG(isar, ID_AA64ISAR1, 0x0011000001211032ull);
cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101125ull);
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull),
cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull; SET_IDREG(isar, ID_AA64MMFR2, 0x0220011102101011ull),
cpu->isar.id_aa64pfr0 = 0x1101110120111112ull; /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR0, 0x1101110120111112ull); /* GIC filled in later */
cpu->isar.id_aa64pfr1 = 0x0000000000000020ull; SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000; cpu->id_afr0 = 0x00000000;
cpu->isar.id_dfr0 = 0x15011099; SET_IDREG(isar, ID_DFR0, 0x15011099);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00010142; SET_IDREG(isar, ID_ISAR4, 0x00010142);
cpu->isar.id_isar5 = 0x11011121; SET_IDREG(isar, ID_ISAR5, 0x11011121);
cpu->isar.id_isar6 = 0x01100111; SET_IDREG(isar, ID_ISAR6, 0x01100111);
cpu->isar.id_mmfr0 = 0x10201105; SET_IDREG(isar, ID_MMFR0, 0x10201105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02122211; SET_IDREG(isar, ID_MMFR3, 0x02122211);
cpu->isar.id_mmfr4 = 0x01021110; SET_IDREG(isar, ID_MMFR4, 0x01021110);
cpu->isar.id_pfr0 = 0x21110131; SET_IDREG(isar, ID_PFR0, 0x21110131);
cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
cpu->isar.id_pfr2 = 0x00000011; SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x411FD402; /* r1p2 */ cpu->midr = 0x411FD402; /* r1p2 */
cpu->revidr = 0; cpu->revidr = 0;
@ -735,7 +739,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043; cpu->isar.mvfr2 = 0x00000043;
/* From 3.7.5 ID_AA64ZFR0_EL1 */ /* From 3.7.5 ID_AA64ZFR0_EL1 */
cpu->isar.id_aa64zfr0 = 0x0000100000100000; SET_IDREG(isar, ID_AA64ZFR0, 0x0000100000100000);
cpu->sve_vq.supported = (1 << 0) /* 128bit */ cpu->sve_vq.supported = (1 << 0) /* 128bit */
| (1 << 1); /* 256bit */ | (1 << 1); /* 256bit */
@ -882,6 +886,7 @@ static const ARMCPRegInfo cortex_a710_cp_reginfo[] = {
static void aarch64_a710_initfn(Object *obj) static void aarch64_a710_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a710"; cpu->dtb_compatible = "arm,cortex-a710";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -897,38 +902,38 @@ static void aarch64_a710_initfn(Object *obj)
/* Ordered by Section B.4: AArch64 registers */ /* Ordered by Section B.4: AArch64 registers */
cpu->midr = 0x412FD471; /* r2p1 */ cpu->midr = 0x412FD471; /* r2p1 */
cpu->revidr = 0; cpu->revidr = 0;
cpu->isar.id_pfr0 = 0x21110131; SET_IDREG(isar, ID_PFR0, 0x21110131);
cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
cpu->isar.id_dfr0 = 0x16011099; SET_IDREG(isar, ID_DFR0, 0x16011099);
cpu->id_afr0 = 0; cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x10201105; SET_IDREG(isar, ID_MMFR0, 0x10201105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02122211; SET_IDREG(isar, ID_MMFR3, 0x02122211);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00010142; SET_IDREG(isar, ID_ISAR4, 0x00010142);
cpu->isar.id_isar5 = 0x11011121; /* with Crypto */ SET_IDREG(isar, ID_ISAR5, 0x11011121); /* with Crypto */
cpu->isar.id_mmfr4 = 0x21021110; SET_IDREG(isar, ID_MMFR4, 0x21021110);
cpu->isar.id_isar6 = 0x01111111; SET_IDREG(isar, ID_ISAR6, 0x01111111);
cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111; cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043; cpu->isar.mvfr2 = 0x00000043;
cpu->isar.id_pfr2 = 0x00000011; SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
cpu->isar.id_aa64pfr1 = 0x0000000000000221ull; SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull);
cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */ SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
cpu->isar.id_aa64dfr0 = 0x000011f010305619ull; SET_IDREG(isar, ID_AA64DFR0, 0x000011f010305619ull);
cpu->isar.id_aa64dfr1 = 0; SET_IDREG(isar, ID_AA64DFR1, 0);
cpu->id_aa64afr0 = 0; cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0; cpu->id_aa64afr1 = 0;
cpu->isar.id_aa64isar0 = 0x0221111110212120ull; /* with Crypto */ SET_IDREG(isar, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */
cpu->isar.id_aa64isar1 = 0x0010111101211052ull; SET_IDREG(isar, ID_AA64ISAR1, 0x0010111101211052ull);
cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull; SET_IDREG(isar, ID_AA64MMFR0, 0x0000022200101122ull);
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
cpu->isar.id_aa64mmfr2 = 0x1221011110101011ull; SET_IDREG(isar, ID_AA64MMFR2, 0x1221011110101011ull);
cpu->clidr = 0x0000001482000023ull; cpu->clidr = 0x0000001482000023ull;
cpu->gm_blocksize = 4; cpu->gm_blocksize = 4;
cpu->ctr = 0x000000049444c004ull; cpu->ctr = 0x000000049444c004ull;
@ -983,6 +988,7 @@ static const ARMCPRegInfo neoverse_n2_cp_reginfo[] = {
static void aarch64_neoverse_n2_initfn(Object *obj) static void aarch64_neoverse_n2_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,neoverse-n2"; cpu->dtb_compatible = "arm,neoverse-n2";
set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8);
@ -998,38 +1004,38 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
/* Ordered by Section B.5: AArch64 ID registers */ /* Ordered by Section B.5: AArch64 ID registers */
cpu->midr = 0x410FD493; /* r0p3 */ cpu->midr = 0x410FD493; /* r0p3 */
cpu->revidr = 0; cpu->revidr = 0;
cpu->isar.id_pfr0 = 0x21110131; SET_IDREG(isar, ID_PFR0, 0x21110131);
cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
cpu->isar.id_dfr0 = 0x16011099; SET_IDREG(isar, ID_DFR0, 0x16011099);
cpu->id_afr0 = 0; cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x10201105; SET_IDREG(isar, ID_MMFR0, 0x10201105);
cpu->isar.id_mmfr1 = 0x40000000; SET_IDREG(isar, ID_MMFR1, 0x40000000);
cpu->isar.id_mmfr2 = 0x01260000; SET_IDREG(isar, ID_MMFR2, 0x01260000);
cpu->isar.id_mmfr3 = 0x02122211; SET_IDREG(isar, ID_MMFR3, 0x02122211);
cpu->isar.id_isar0 = 0x02101110; SET_IDREG(isar, ID_ISAR0, 0x02101110);
cpu->isar.id_isar1 = 0x13112111; SET_IDREG(isar, ID_ISAR1, 0x13112111);
cpu->isar.id_isar2 = 0x21232042; SET_IDREG(isar, ID_ISAR2, 0x21232042);
cpu->isar.id_isar3 = 0x01112131; SET_IDREG(isar, ID_ISAR3, 0x01112131);
cpu->isar.id_isar4 = 0x00010142; SET_IDREG(isar, ID_ISAR4, 0x00010142);
cpu->isar.id_isar5 = 0x11011121; /* with Crypto */ SET_IDREG(isar, ID_ISAR5, 0x11011121); /* with Crypto */
cpu->isar.id_mmfr4 = 0x01021110; SET_IDREG(isar, ID_MMFR4, 0x01021110);
cpu->isar.id_isar6 = 0x01111111; SET_IDREG(isar, ID_ISAR6, 0x01111111);
cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111; cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043; cpu->isar.mvfr2 = 0x00000043;
cpu->isar.id_pfr2 = 0x00000011; SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
cpu->isar.id_aa64pfr1 = 0x0000000000000221ull; SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull);
cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */ SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
cpu->isar.id_aa64dfr0 = 0x000011f210305619ull; SET_IDREG(isar, ID_AA64DFR0, 0x000011f210305619ull);
cpu->isar.id_aa64dfr1 = 0; SET_IDREG(isar, ID_AA64DFR1, 0);
cpu->id_aa64afr0 = 0; cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0; cpu->id_aa64afr1 = 0;
cpu->isar.id_aa64isar0 = 0x1221111110212120ull; /* with Crypto and FEAT_RNG */ SET_IDREG(isar, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */
cpu->isar.id_aa64isar1 = 0x0011111101211052ull; SET_IDREG(isar, ID_AA64ISAR1, 0x0011111101211052ull);
cpu->isar.id_aa64mmfr0 = 0x0000022200101125ull; SET_IDREG(isar, ID_AA64MMFR0, 0x0000022200101125ull);
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
cpu->isar.id_aa64mmfr2 = 0x1221011112101011ull; SET_IDREG(isar, ID_AA64MMFR2, 0x1221011112101011ull);
cpu->clidr = 0x0000001482000023ull; cpu->clidr = 0x0000001482000023ull;
cpu->gm_blocksize = 4; cpu->gm_blocksize = 4;
cpu->ctr = 0x00000004b444c004ull; cpu->ctr = 0x00000004b444c004ull;
@ -1083,6 +1089,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
void aarch64_max_tcg_initfn(Object *obj) void aarch64_max_tcg_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
ARMISARegisters *isar = &cpu->isar;
uint64_t t; uint64_t t;
uint32_t u; uint32_t u;
@ -1133,7 +1140,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, CTR_EL0, DIC, 1); t = FIELD_DP64(t, CTR_EL0, DIC, 1);
cpu->ctr = t; cpu->ctr = t;
t = cpu->isar.id_aa64isar0; t = GET_IDREG(isar, ID_AA64ISAR0);
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */ t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */ t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
@ -1148,9 +1155,9 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* FEAT_FlagM2 */ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* FEAT_FlagM2 */
t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */ t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */ t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */
cpu->isar.id_aa64isar0 = t; SET_IDREG(isar, ID_AA64ISAR0, t);
t = cpu->isar.id_aa64isar1; t = GET_IDREG(isar, ID_AA64ISAR1);
t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_FPACCOMBINED); t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_FPACCOMBINED);
t = FIELD_DP64(t, ID_AA64ISAR1, API, 1); t = FIELD_DP64(t, ID_AA64ISAR1, API, 1);
@ -1164,16 +1171,16 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */ t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */ t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
t = FIELD_DP64(t, ID_AA64ISAR1, XS, 1); /* FEAT_XS */ t = FIELD_DP64(t, ID_AA64ISAR1, XS, 1); /* FEAT_XS */
cpu->isar.id_aa64isar1 = t; SET_IDREG(isar, ID_AA64ISAR1, t);
t = cpu->isar.id_aa64isar2; t = GET_IDREG(isar, ID_AA64ISAR2);
t = FIELD_DP64(t, ID_AA64ISAR2, RPRES, 1); /* FEAT_RPRES */ t = FIELD_DP64(t, ID_AA64ISAR2, RPRES, 1); /* FEAT_RPRES */
t = FIELD_DP64(t, ID_AA64ISAR2, MOPS, 1); /* FEAT_MOPS */ t = FIELD_DP64(t, ID_AA64ISAR2, MOPS, 1); /* FEAT_MOPS */
t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */ t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */
t = FIELD_DP64(t, ID_AA64ISAR2, WFXT, 2); /* FEAT_WFxT */ t = FIELD_DP64(t, ID_AA64ISAR2, WFXT, 2); /* FEAT_WFxT */
cpu->isar.id_aa64isar2 = t; SET_IDREG(isar, ID_AA64ISAR2, t);
t = cpu->isar.id_aa64pfr0; t = GET_IDREG(isar, ID_AA64PFR0);
t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */ t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */
t = FIELD_DP64(t, ID_AA64PFR0, RAS, 2); /* FEAT_RASv1p1 + FEAT_DoubleFault */ t = FIELD_DP64(t, ID_AA64PFR0, RAS, 2); /* FEAT_RASv1p1 + FEAT_DoubleFault */
@ -1182,9 +1189,9 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */ t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 3); /* FEAT_CSV2_3 */ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 3); /* FEAT_CSV2_3 */
t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */ t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
cpu->isar.id_aa64pfr0 = t; SET_IDREG(isar, ID_AA64PFR0, t);
t = cpu->isar.id_aa64pfr1; t = GET_IDREG(isar, ID_AA64PFR1);
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1); /* FEAT_BTI */ t = FIELD_DP64(t, ID_AA64PFR1, BT, 1); /* FEAT_BTI */
t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); /* FEAT_SSBS2 */ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); /* FEAT_SSBS2 */
/* /*
@ -1197,9 +1204,9 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */ t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */
t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_3 */ t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_3 */
t = FIELD_DP64(t, ID_AA64PFR1, NMI, 1); /* FEAT_NMI */ t = FIELD_DP64(t, ID_AA64PFR1, NMI, 1); /* FEAT_NMI */
cpu->isar.id_aa64pfr1 = t; SET_IDREG(isar, ID_AA64PFR1, t);
t = cpu->isar.id_aa64mmfr0; t = GET_IDREG(isar, ID_AA64MMFR0);
t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */ t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
@ -1207,9 +1214,9 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */ t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */
t = FIELD_DP64(t, ID_AA64MMFR0, ECV, 2); /* FEAT_ECV */ t = FIELD_DP64(t, ID_AA64MMFR0, ECV, 2); /* FEAT_ECV */
cpu->isar.id_aa64mmfr0 = t; SET_IDREG(isar, ID_AA64MMFR0, t);
t = cpu->isar.id_aa64mmfr1; t = GET_IDREG(isar, ID_AA64MMFR1);
t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */ t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */ t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */ t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
@ -1222,9 +1229,9 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64MMFR1, AFP, 1); /* FEAT_AFP */ t = FIELD_DP64(t, ID_AA64MMFR1, AFP, 1); /* FEAT_AFP */
t = FIELD_DP64(t, ID_AA64MMFR1, TIDCP1, 1); /* FEAT_TIDCP1 */ t = FIELD_DP64(t, ID_AA64MMFR1, TIDCP1, 1); /* FEAT_TIDCP1 */
t = FIELD_DP64(t, ID_AA64MMFR1, CMOW, 1); /* FEAT_CMOW */ t = FIELD_DP64(t, ID_AA64MMFR1, CMOW, 1); /* FEAT_CMOW */
cpu->isar.id_aa64mmfr1 = t; SET_IDREG(isar, ID_AA64MMFR1, t);
t = cpu->isar.id_aa64mmfr2; t = GET_IDREG(isar, ID_AA64MMFR2);
t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */ t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */ t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */ t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
@ -1238,13 +1245,11 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */ t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
t = FIELD_DP64(t, ID_AA64MMFR2, EVT, 2); /* FEAT_EVT */ t = FIELD_DP64(t, ID_AA64MMFR2, EVT, 2); /* FEAT_EVT */
t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */ t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */
cpu->isar.id_aa64mmfr2 = t; SET_IDREG(isar, ID_AA64MMFR2, t);
t = cpu->isar.id_aa64mmfr3; FIELD_DP64_IDREG(isar, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
cpu->isar.id_aa64mmfr3 = t;
t = cpu->isar.id_aa64zfr0; t = GET_IDREG(isar, ID_AA64ZFR0);
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1); t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */ t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */
t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); /* FEAT_SVE_BitPerm */ t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); /* FEAT_SVE_BitPerm */
@ -1254,15 +1259,15 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); /* FEAT_I8MM */ t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); /* FEAT_I8MM */
t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); /* FEAT_F32MM */ t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); /* FEAT_F32MM */
t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */ t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */
cpu->isar.id_aa64zfr0 = t; SET_IDREG(isar, ID_AA64ZFR0, t);
t = cpu->isar.id_aa64dfr0; t = GET_IDREG(isar, ID_AA64DFR0);
t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 10); /* FEAT_Debugv8p8 */ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 6); /* FEAT_PMUv3p5 */ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 6); /* FEAT_PMUv3p5 */
t = FIELD_DP64(t, ID_AA64DFR0, HPMN0, 1); /* FEAT_HPMN0 */ t = FIELD_DP64(t, ID_AA64DFR0, HPMN0, 1); /* FEAT_HPMN0 */
cpu->isar.id_aa64dfr0 = t; SET_IDREG(isar, ID_AA64DFR0, t);
t = cpu->isar.id_aa64smfr0; t = GET_IDREG(isar, ID_AA64SMFR0);
t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1); /* FEAT_SME */ t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1); /* FEAT_SME */
t = FIELD_DP64(t, ID_AA64SMFR0, B16F32, 1); /* FEAT_SME */ t = FIELD_DP64(t, ID_AA64SMFR0, B16F32, 1); /* FEAT_SME */
t = FIELD_DP64(t, ID_AA64SMFR0, F16F32, 1); /* FEAT_SME */ t = FIELD_DP64(t, ID_AA64SMFR0, F16F32, 1); /* FEAT_SME */
@ -1270,7 +1275,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64SMFR0, F64F64, 1); /* FEAT_SME_F64F64 */ t = FIELD_DP64(t, ID_AA64SMFR0, F64F64, 1); /* FEAT_SME_F64F64 */
t = FIELD_DP64(t, ID_AA64SMFR0, I16I64, 0xf); /* FEAT_SME_I16I64 */ t = FIELD_DP64(t, ID_AA64SMFR0, I16I64, 0xf); /* FEAT_SME_I16I64 */
t = FIELD_DP64(t, ID_AA64SMFR0, FA64, 1); /* FEAT_SME_FA64 */ t = FIELD_DP64(t, ID_AA64SMFR0, FA64, 1); /* FEAT_SME_FA64 */
cpu->isar.id_aa64smfr0 = t; SET_IDREG(isar, ID_AA64SMFR0, t);
/* Replicate the same data to the 32-bit id registers. */ /* Replicate the same data to the 32-bit id registers. */
aa32_max_features(cpu); aa32_max_features(cpu);

View file

@ -433,12 +433,6 @@ static void gen_rebuild_hflags(DisasContext *s)
gen_helper_rebuild_hflags_a64(tcg_env, tcg_constant_i32(s->current_el)); gen_helper_rebuild_hflags_a64(tcg_env, tcg_constant_i32(s->current_el));
} }
static void gen_exception_internal(int excp)
{
assert(excp_is_internal(excp));
gen_helper_exception_internal(tcg_env, tcg_constant_i32(excp));
}
static void gen_exception_internal_insn(DisasContext *s, int excp) static void gen_exception_internal_insn(DisasContext *s, int excp)
{ {
gen_a64_update_pc(s, 0); gen_a64_update_pc(s, 0);
@ -1816,6 +1810,10 @@ static bool trans_RETA(DisasContext *s, arg_reta *a)
{ {
TCGv_i64 dst; TCGv_i64 dst;
if (!dc_isar_feature(aa64_pauth, s)) {
return false;
}
dst = auth_branch_target(s, cpu_reg(s, 30), cpu_X[31], !a->m); dst = auth_branch_target(s, cpu_reg(s, 30), cpu_X[31], !a->m);
gen_a64_set_pc(s, dst); gen_a64_set_pc(s, dst);
s->base.is_jmp = DISAS_JUMP; s->base.is_jmp = DISAS_JUMP;

View file

@ -372,7 +372,7 @@ static void gen_rebuild_hflags(DisasContext *s, bool new_el)
} }
} }
static void gen_exception_internal(int excp) void gen_exception_internal(int excp)
{ {
assert(excp_is_internal(excp)); assert(excp_is_internal(excp));
gen_helper_exception_internal(tcg_env, tcg_constant_i32(excp)); gen_helper_exception_internal(tcg_env, tcg_constant_i32(excp));

View file

@ -347,6 +347,7 @@ void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
void arm_gen_test_cc(int cc, TCGLabel *label); void arm_gen_test_cc(int cc, TCGLabel *label);
MemOp pow2_align(unsigned i); MemOp pow2_align(unsigned i);
void unallocated_encoding(DisasContext *s); void unallocated_encoding(DisasContext *s);
void gen_exception_internal(int excp);
void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp, void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp,
uint32_t syn, uint32_t target_el); uint32_t syn, uint32_t target_el);
void gen_exception_insn(DisasContext *s, target_long pc_diff, void gen_exception_insn(DisasContext *s, target_long pc_diff,

Binary file not shown.

Binary file not shown.

View file

@ -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_device_passthrough' : 720,
'aarch64_imx8mp_evk' : 240, 'aarch64_imx8mp_evk' : 240,
'aarch64_raspi4' : 480, 'aarch64_raspi4' : 480,
'aarch64_reverse_debug' : 180, 'aarch64_reverse_debug' : 180,
@ -83,6 +84,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_device_passthrough',
'aarch64_imx8mp_evk', 'aarch64_imx8mp_evk',
'aarch64_raspi3', 'aarch64_raspi3',
'aarch64_raspi4', 'aarch64_raspi4',

View file

@ -23,7 +23,7 @@ import unittest
import uuid import uuid
from qemu.machine import QEMUMachine from qemu.machine import QEMUMachine
from qemu.utils import kvm_available, tcg_available from qemu.utils import hvf_available, kvm_available, tcg_available
from .archive import archive_extract from .archive import archive_extract
from .asset import Asset from .asset import Asset
@ -317,7 +317,9 @@ class QemuSystemTest(QemuBaseTest):
:type accelerator: str :type accelerator: str
""" """
checker = {'tcg': tcg_available, checker = {'tcg': tcg_available,
'kvm': kvm_available}.get(accelerator) 'kvm': kvm_available,
'hvf': hvf_available,
}.get(accelerator)
if checker is None: if checker is None:
self.skipTest("Don't know how to check for the presence " self.skipTest("Don't know how to check for the presence "
"of accelerator %s" % accelerator) "of accelerator %s" % accelerator)

View file

@ -0,0 +1,142 @@
#!/usr/bin/env python3
#
# Boots a nested guest and compare content of a device (passthrough) to a
# reference image. Both vfio group and iommufd passthrough methods are tested.
#
# Copyright (c) 2025 Linaro Ltd.
#
# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later
import os
from qemu_test import QemuSystemTest, Asset
from qemu_test import exec_command, wait_for_console_pattern
from qemu_test import exec_command_and_wait_for_pattern
from random import randbytes
guest_script = '''
#!/usr/bin/env bash
set -euo pipefail
set -x
# find disks from nvme serial
dev_vfio=$(lsblk --nvme | grep vfio | cut -f 1 -d ' ')
dev_iommufd=$(lsblk --nvme | grep iommufd | cut -f 1 -d ' ')
pci_vfio=$(basename $(readlink -f /sys/block/$dev_vfio/../../../))
pci_iommufd=$(basename $(readlink -f /sys/block/$dev_iommufd/../../../))
# bind disks to vfio
for p in "$pci_vfio" "$pci_iommufd"; do
if [ "$(cat /sys/bus/pci/devices/$p/driver_override)" == vfio-pci ]; then
continue
fi
echo $p > /sys/bus/pci/drivers/nvme/unbind
echo vfio-pci > /sys/bus/pci/devices/$p/driver_override
echo $p > /sys/bus/pci/drivers/vfio-pci/bind
done
# boot nested guest and execute /host/nested_guest.sh
# one disk is passed through vfio group, the other, through iommufd
qemu-system-aarch64 \
-M virt \
-display none \
-serial stdio \
-cpu host \
-enable-kvm \
-m 1G \
-kernel /host/Image.gz \
-drive format=raw,file=/host/guest.ext4,if=virtio \
-append "root=/dev/vda init=/init -- bash /host/nested_guest.sh" \
-virtfs local,path=/host,mount_tag=host,security_model=mapped,readonly=off \
-device vfio-pci,host=$pci_vfio \
-object iommufd,id=iommufd0 \
-device vfio-pci,host=$pci_iommufd,iommufd=iommufd0
'''
nested_guest_script = '''
#!/usr/bin/env bash
set -euo pipefail
set -x
image_vfio=/host/disk_vfio
image_iommufd=/host/disk_iommufd
dev_vfio=$(lsblk --nvme | grep vfio | cut -f 1 -d ' ')
dev_iommufd=$(lsblk --nvme | grep iommufd | cut -f 1 -d ' ')
# compare if devices are identical to original images
diff $image_vfio /dev/$dev_vfio
diff $image_iommufd /dev/$dev_iommufd
echo device_passthrough_test_ok
'''
class Aarch64DevicePassthrough(QemuSystemTest):
# https://github.com/pbo-linaro/qemu-linux-stack
#
# Linux kernel is compiled with defconfig +
# IOMMUFD + VFIO_DEVICE_CDEV + ARM_SMMU_V3_IOMMUFD
# https://docs.kernel.org/driver-api/vfio.html#vfio-device-cde
ASSET_DEVICE_PASSTHROUGH_STACK = Asset(
('https://fileserver.linaro.org/s/fx5DXxBYme8dw2G/'
'download/device_passthrough.tar.xz'),
'812750b664d61c2986f2b149939ae28cafbd60d53e9c7e4b16e97143845e196d')
# This tests the device passthrough implementation, by booting a VM
# supporting it with two nvme disks attached, and launching a nested VM
# reading their content.
def test_aarch64_device_passthrough(self):
self.set_machine('virt')
self.require_accelerator('tcg')
self.vm.set_console()
stack_path_tar_gz = self.ASSET_DEVICE_PASSTHROUGH_STACK.fetch()
self.archive_extract(stack_path_tar_gz, format="tar")
stack = self.scratch_file('out')
kernel = os.path.join(stack, 'Image.gz')
rootfs_host = os.path.join(stack, 'host.ext4')
disk_vfio = os.path.join(stack, 'disk_vfio')
disk_iommufd = os.path.join(stack, 'disk_iommufd')
guest_cmd = os.path.join(stack, 'guest.sh')
nested_guest_cmd = os.path.join(stack, 'nested_guest.sh')
# we generate two random disks
with open(disk_vfio, "wb") as d: d.write(randbytes(512))
with open(disk_iommufd, "wb") as d: d.write(randbytes(1024))
with open(guest_cmd, 'w') as s: s.write(guest_script)
with open(nested_guest_cmd, 'w') as s: s.write(nested_guest_script)
self.vm.add_args('-cpu', 'max')
self.vm.add_args('-m', '2G')
self.vm.add_args('-M', 'virt,'
'virtualization=on,'
'gic-version=max,'
'iommu=smmuv3')
self.vm.add_args('-kernel', kernel)
self.vm.add_args('-drive', f'format=raw,file={rootfs_host}')
self.vm.add_args('-drive',
f'file={disk_vfio},if=none,id=vfio,format=raw')
self.vm.add_args('-device', 'nvme,serial=vfio,drive=vfio')
self.vm.add_args('-drive',
f'file={disk_iommufd},if=none,id=iommufd,format=raw')
self.vm.add_args('-device', 'nvme,serial=iommufd,drive=iommufd')
self.vm.add_args('-virtfs',
f'local,path={stack}/,mount_tag=host,'
'security_model=mapped,readonly=off')
# boot and execute guest script
# init will trigger a kernel panic if script fails
self.vm.add_args('-append',
'root=/dev/vda init=/init -- bash /host/guest.sh')
self.vm.launch()
wait_for_console_pattern(self, 'device_passthrough_test_ok',
failure_message='Kernel panic')
if __name__ == '__main__':
QemuSystemTest.main()

View file

@ -49,6 +49,7 @@ class Imx8mpEvkMachine(LinuxKernelTest):
self.DTB_OFFSET, self.DTB_SIZE) self.DTB_OFFSET, self.DTB_SIZE)
def test_aarch64_imx8mp_evk_usdhc(self): def test_aarch64_imx8mp_evk_usdhc(self):
self.require_accelerator("tcg")
self.set_machine('imx8mp-evk') self.set_machine('imx8mp-evk')
self.vm.set_console(console_index=1) self.vm.set_console(console_index=1)
self.vm.add_args('-m', '2G', self.vm.add_args('-m', '2G',

View file

@ -40,8 +40,6 @@ def fetch_firmware(test):
with open(path, "ab+") as fd: with open(path, "ab+") as fd:
fd.truncate(256 << 20) # Expand volumes to 256MiB fd.truncate(256 << 20) # Expand volumes to 256MiB
test.set_machine('sbsa-ref')
test.vm.set_console()
test.vm.add_args( test.vm.add_args(
"-drive", f"if=pflash,file={fs0_path},format=raw", "-drive", f"if=pflash,file={fs0_path},format=raw",
"-drive", f"if=pflash,file={fs1_path},format=raw", "-drive", f"if=pflash,file={fs1_path},format=raw",
@ -68,8 +66,11 @@ class Aarch64SbsarefMachine(QemuSystemTest):
def test_sbsaref_edk2_firmware(self): def test_sbsaref_edk2_firmware(self):
self.set_machine('sbsa-ref')
fetch_firmware(self) fetch_firmware(self)
self.vm.set_console()
self.vm.add_args('-cpu', 'cortex-a57') self.vm.add_args('-cpu', 'cortex-a57')
self.vm.launch() self.vm.launch()

View file

@ -26,8 +26,9 @@ class Aarch64SbsarefAlpine(QemuSystemTest):
# We only boot a whole OS for the current top level CPU and GIC # We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots # Other test profiles should use more minimal boots
def boot_alpine_linux(self, cpu=None): def boot_alpine_linux(self, cpu=None):
fetch_firmware(self) self.set_machine('sbsa-ref')
fetch_firmware(self)
iso_path = self.ASSET_ALPINE_ISO.fetch() iso_path = self.ASSET_ALPINE_ISO.fetch()
self.vm.set_console() self.vm.set_console()

View file

@ -26,8 +26,9 @@ class Aarch64SbsarefFreeBSD(QemuSystemTest):
# We only boot a whole OS for the current top level CPU and GIC # We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots # Other test profiles should use more minimal boots
def boot_freebsd14(self, cpu=None): def boot_freebsd14(self, cpu=None):
fetch_firmware(self) self.set_machine('sbsa-ref')
fetch_firmware(self)
img_path = self.ASSET_FREEBSD_ISO.fetch() img_path = self.ASSET_FREEBSD_ISO.fetch()
self.vm.set_console() self.vm.set_console()

View file

@ -17,7 +17,7 @@ import time
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import BUILD_DIR from qemu_test import BUILD_DIR
from qemu.utils import kvm_available from qemu.utils import kvm_available, hvf_available
class SMMU(LinuxKernelTest): class SMMU(LinuxKernelTest):
@ -45,11 +45,17 @@ class SMMU(LinuxKernelTest):
self.vm.add_args('-device', 'virtio-net,netdev=n1' + self.IOMMU_ADDON) self.vm.add_args('-device', 'virtio-net,netdev=n1' + self.IOMMU_ADDON)
def common_vm_setup(self, kernel, initrd, disk): def common_vm_setup(self, kernel, initrd, disk):
self.require_accelerator("kvm") if hvf_available(self.qemu_bin):
accel = "hvf"
elif kvm_available(self.qemu_bin):
accel = "kvm"
else:
self.skipTest("Neither HVF nor KVM accelerator is available")
self.require_accelerator(accel)
self.require_netdev('user') self.require_netdev('user')
self.set_machine("virt") self.set_machine("virt")
self.vm.add_args('-m', '1G') self.vm.add_args('-m', '1G')
self.vm.add_args("-accel", "kvm") self.vm.add_args("-accel", accel)
self.vm.add_args("-cpu", "host") self.vm.add_args("-cpu", "host")
self.vm.add_args("-machine", "iommu=smmuv3") self.vm.add_args("-machine", "iommu=smmuv3")
self.vm.add_args("-d", "guest_errors") self.vm.add_args("-d", "guest_errors")

View file

@ -33,6 +33,7 @@ class BootXen(LinuxKernelTest):
""" """
Launch Xen with a dom0 guest kernel Launch Xen with a dom0 guest kernel
""" """
self.require_accelerator("tcg") # virtualization=on
self.set_machine('virt') self.set_machine('virt')
self.cpu = "cortex-a57" self.cpu = "cortex-a57"
self.kernel_path = self.ASSET_KERNEL.fetch() self.kernel_path = self.ASSET_KERNEL.fetch()

View file

@ -2146,6 +2146,25 @@ static void test_acpi_aarch64_virt_tcg_topology(void)
free_test_data(&data); free_test_data(&data);
} }
static void test_acpi_aarch64_virt_tcg_its_off(void)
{
test_data data = {
.machine = "virt",
.arch = "aarch64",
.variant = ".its_off",
.tcg_only = true,
.uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
.scan_len = 128ULL * 1024 * 1024,
};
test_acpi_one("-cpu cortex-a57 "
"-M gic-version=3,iommu=smmuv3,its=off", &data);
free_test_data(&data);
}
static void test_acpi_q35_viot(void) static void test_acpi_q35_viot(void)
{ {
test_data data = { test_data data = {
@ -2577,6 +2596,8 @@ int main(int argc, char *argv[])
test_acpi_aarch64_virt_tcg_acpi_hmat); test_acpi_aarch64_virt_tcg_acpi_hmat);
qtest_add_func("acpi/virt/topology", qtest_add_func("acpi/virt/topology",
test_acpi_aarch64_virt_tcg_topology); test_acpi_aarch64_virt_tcg_topology);
qtest_add_func("acpi/virt/its_off",
test_acpi_aarch64_virt_tcg_its_off);
qtest_add_func("acpi/virt/numamem", qtest_add_func("acpi/virt/numamem",
test_acpi_aarch64_virt_tcg_numamem); test_acpi_aarch64_virt_tcg_numamem);
qtest_add_func("acpi/virt/memhp", test_acpi_aarch64_virt_tcg_memhp); qtest_add_func("acpi/virt/memhp", test_acpi_aarch64_virt_tcg_memhp);