aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS6
-rw-r--r--accel/hvf/hvf-accel-ops.c6
-rw-r--r--accel/hvf/trace-events7
-rw-r--r--accel/hvf/trace.h2
-rw-r--r--hw/arm/sbsa-ref.c8
-rw-r--r--hw/arm/virt-acpi-build.c186
-rw-r--r--hw/arm/virt.c38
-rw-r--r--hw/intc/armv7m_nvic.c27
-rw-r--r--include/hw/intc/arm_gicv3_its_common.h2
-rw-r--r--meson.build1
-rw-r--r--python/qemu/utils/__init__.py8
-rw-r--r--python/qemu/utils/accel.py9
-rw-r--r--qga/vss-win32/install.cpp15
-rw-r--r--target/arm/cpu-features.h317
-rw-r--r--target/arm/cpu-sysregs.h42
-rw-r--r--target/arm/cpu-sysregs.h.inc36
-rw-r--r--target/arm/cpu.c124
-rw-r--r--target/arm/cpu.h82
-rw-r--r--target/arm/cpu64.c128
-rw-r--r--target/arm/helper.c68
-rw-r--r--target/arm/hvf/hvf.c72
-rw-r--r--target/arm/hvf/trace-events5
-rw-r--r--target/arm/internals.h12
-rw-r--r--target/arm/kvm.c141
-rw-r--r--target/arm/ptw.c6
-rw-r--r--target/arm/tcg/cpu-v7m.c174
-rw-r--r--target/arm/tcg/cpu32.c320
-rw-r--r--target/arm/tcg/cpu64.c459
-rw-r--r--target/arm/tcg/translate-a64.c10
-rw-r--r--target/arm/tcg/translate.c2
-rw-r--r--target/arm/tcg/translate.h1
-rw-r--r--tests/data/acpi/aarch64/virt/APIC.its_offbin0 -> 164 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/IORT.its_offbin0 -> 172 bytes
-rw-r--r--tests/functional/meson.build2
-rw-r--r--tests/functional/qemu_test/testcase.py6
-rwxr-xr-xtests/functional/test_aarch64_device_passthrough.py142
-rwxr-xr-xtests/functional/test_aarch64_imx8mp_evk.py1
-rwxr-xr-xtests/functional/test_aarch64_sbsaref.py5
-rwxr-xr-xtests/functional/test_aarch64_sbsaref_alpine.py3
-rwxr-xr-xtests/functional/test_aarch64_sbsaref_freebsd.py3
-rwxr-xr-xtests/functional/test_aarch64_smmu.py12
-rwxr-xr-xtests/functional/test_aarch64_xen.py1
-rw-r--r--tests/qtest/bios-tables-test.c21
43 files changed, 1446 insertions, 1064 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index d1672fd..7128e0b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -511,6 +511,7 @@ F: system/cpus.c
Apple Silicon HVF CPUs
M: Alexander Graf <agraf@csgraf.de>
+R: Mads Ynddal <mads@ynddal.dk>
S: Maintained
F: target/arm/hvf/
F: target/arm/hvf-stub.c
@@ -527,6 +528,7 @@ HVF
M: Cameron Esfahani <dirty@apple.com>
M: Roman Bolshakov <rbolshakov@ddn.com>
R: Phil Dennis-Jordan <phil@philjordan.eu>
+R: Mads Ynddal <mads@ynddal.dk>
W: https://wiki.qemu.org/Features/HVF
S: Maintained
F: accel/hvf/
@@ -3383,7 +3385,7 @@ T: git https://repo.or.cz/qemu/armbru.git qapi-next
QEMU Guest Agent
M: Michael Roth <michael.roth@amd.com>
-M: Konstantin Kostiuk <kkostiuk@redhat.com>
+M: Kostiantyn Kostiuk <kkostiuk@redhat.com>
S: Maintained
F: qga/
F: contrib/systemd/qemu-guest-agent.service
@@ -3394,7 +3396,7 @@ F: tests/*/test-qga*
T: git https://github.com/mdroth/qemu.git qga
QEMU Guest Agent Win32
-M: Konstantin Kostiuk <kkostiuk@redhat.com>
+M: Kostiantyn Kostiuk <kkostiuk@redhat.com>
S: Maintained
F: qga/*win32*
F: qga/vss-win32/
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index d60446b..b389772 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -59,6 +59,7 @@
#include "system/hvf_int.h"
#include "system/runstate.h"
#include "qemu/guest-random.h"
+#include "trace.h"
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->size != slot->size) {
macslot->present = 0;
+ trace_hvf_vm_unmap(macslot->gpa_start, macslot->size);
ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
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->gpa_start = slot->start;
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);
assert_hvf_ok(ret);
return 0;
diff --git a/accel/hvf/trace-events b/accel/hvf/trace-events
new file mode 100644
index 0000000..2fd3e12
--- /dev/null
+++ b/accel/hvf/trace-events
@@ -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
diff --git a/accel/hvf/trace.h b/accel/hvf/trace.h
new file mode 100644
index 0000000..83a1883
--- /dev/null
+++ b/accel/hvf/trace.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "trace/trace-accel_hvf.h"
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index deae5cf..15c1ff4 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/cutils.h"
#include "qemu/datadir.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
@@ -53,8 +54,7 @@
#include "target/arm/cpu-qom.h"
#include "target/arm/gtimer.h"
-#define RAMLIMIT_GB 8192
-#define RAMLIMIT_BYTES (RAMLIMIT_GB * GiB)
+#define RAMLIMIT_BYTES (8 * TiB)
#define NUM_IRQS 256
#define NUM_SMMU_IRQS 4
@@ -756,7 +756,9 @@ static void sbsa_ref_init(MachineState *machine)
sms->smp_cpus = smp_cpus;
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);
}
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 7e8e0f0..cd90c47 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -266,6 +266,43 @@ static int iort_idmap_compare(gconstpointer a, gconstpointer b)
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 (0x0000–0xFFFF).
+ */
+ 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)
* 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;
size_t node_size, smmu_offset = 0;
- AcpiIortIdMapping *idmap;
uint32_t id = 0;
- GArray *smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
- GArray *its_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
+ GArray *rc_smmu_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,
.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);
if (vms->iommu == VIRT_IOMMU_SMMUV3) {
- AcpiIortIdMapping next_range = {0};
-
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 */
- 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,
- * build the ID mapping from RC to ITS directly.
+ * Knowing the ID ranges from the RC to the SMMU, it's possible to
+ * determine the ID ranges from RC that are directed to the ITS.
*/
- for (i = 0; i < smmu_idmaps->len; i++) {
- idmap = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i);
+ create_rc_its_idmaps(rc_its_idmaps, rc_smmu_idmaps);
- 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);
- }
+ nb_nodes = 2; /* RC and SMMUv3 */
+ rc_mapping_count = rc_smmu_idmaps->len;
- 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);
- /* 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++; /* ITS */
+ rc_mapping_count += rc_its_idmaps->len;
}
-
- nb_nodes = 3; /* RC, ITS, SMMUv3 */
- rc_mapping_count = smmu_idmaps->len + its_idmaps->len;
} else {
- nb_nodes = 2; /* RC, ITS */
- rc_mapping_count = 1;
+ if (vms->its) {
+ 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 */
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, 0, 4); /* Reserved */
- /* Table 12 ITS Group Format */
- build_append_int_noprefix(table_data, 0 /* ITS Group */, 1); /* Type */
- node_size = 20 /* fixed header size */ + 4 /* 1 GIC ITS Identifier */;
- build_append_int_noprefix(table_data, node_size, 2); /* Length */
- build_append_int_noprefix(table_data, 1, 1); /* Revision */
- build_append_int_noprefix(table_data, id++, 4); /* Identifier */
- build_append_int_noprefix(table_data, 0, 4); /* Number of ID mappings */
- build_append_int_noprefix(table_data, 0, 4); /* Reference to ID Array */
- build_append_int_noprefix(table_data, 1, 4); /* Number of ITSs */
- /* GIC ITS Identifier Array */
- build_append_int_noprefix(table_data, 0 /* MADT translation_id */, 4);
+ if (vms->its) {
+ /* Table 12 ITS Group Format */
+ build_append_int_noprefix(table_data, 0 /* ITS Group */, 1); /* Type */
+ node_size = 20 /* fixed header size */ + 4 /* 1 GIC ITS Identifier */;
+ build_append_int_noprefix(table_data, node_size, 2); /* Length */
+ build_append_int_noprefix(table_data, 1, 1); /* Revision */
+ build_append_int_noprefix(table_data, id++, 4); /* Identifier */
+ build_append_int_noprefix(table_data, 0, 4); /* Number of ID mappings */
+ build_append_int_noprefix(table_data, 0, 4); /* Reference to ID Array */
+ build_append_int_noprefix(table_data, 1, 4); /* Number of ITSs */
+ /* GIC ITS Identifier Array */
+ build_append_int_noprefix(table_data, 0 /* MADT translation_id */, 4);
+ }
if (vms->iommu == VIRT_IOMMU_SMMUV3) {
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;
/* Table 9 SMMUv3 Format */
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, 4, 1); /* Revision */
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 */
- build_append_int_noprefix(table_data, SMMU_V3_ENTRY_SIZE, 4);
+ build_append_int_noprefix(table_data, offset_to_id_array, 4);
/* Base address */
build_append_int_noprefix(table_data, vms->memmap[VIRT_SMMU].base, 8);
/* Flags */
@@ -369,9 +416,11 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, 0, 4); /* Proximity domain */
/* DeviceID mapping index (ignored since interrupts are GSIV based) */
build_append_int_noprefix(table_data, 0, 4);
-
- /* output IORT node is the ITS group node (the first node) */
- build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET);
+ /* Array of ID mappings */
+ if (smmu_mapping_count) {
+ /* 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 */
@@ -407,29 +456,44 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
if (vms->iommu == VIRT_IOMMU_SMMUV3) {
AcpiIortIdMapping *range;
- /* translated RIDs connect to SMMUv3 node: RC -> SMMUv3 -> ITS */
- for (i = 0; i < smmu_idmaps->len; i++) {
- range = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i);
- /* output IORT node is the smmuv3 node */
+ /*
+ * Map RIDs (input) from RC to SMMUv3 nodes: RC -> SMMUv3.
+ *
+ * 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,
range->id_count, smmu_offset);
}
- /* bypassed RIDs connect to ITS group node directly: RC -> ITS */
- for (i = 0; i < its_idmaps->len; i++) {
- range = &g_array_index(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);
+ if (vms->its) {
+ /*
+ * Map bypassed (don't go through the SMMU) RIDs (input) to
+ * ITS Group node directly: RC -> ITS.
+ */
+ 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 {
- /* 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);
}
acpi_table_end(linker, &table);
- g_array_free(smmu_idmaps, true);
- g_array_free(its_idmaps, true);
+ g_array_free(rc_smmu_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);
}
- if (its_class_name()) {
+ if (vms->its) {
/*
* ACPI spec, Revision 6.0 Errata A
* (original 6.0 definition has invalid Length)
@@ -969,10 +1033,8 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
vms->oem_table_id);
}
- if (its_class_name()) {
- acpi_add_table(table_offsets, tables_blob);
- build_iort(tables_blob, tables->linker, vms);
- }
+ acpi_add_table(table_offsets, tables_blob);
+ build_iort(tables_blob, tables->linker, vms);
#ifdef CONFIG_TPM
if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 99fde58..3bcdf92 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -705,21 +705,18 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
static void create_its(VirtMachineState *vms)
{
- const char *itsclass = its_class_name();
DeviceState *dev;
- if (!strcmp(itsclass, "arm-gicv3-its")) {
- if (!vms->tcg_its) {
- itsclass = NULL;
- }
- }
-
- if (!itsclass) {
- /* Do nothing if not supported */
+ assert(vms->its);
+ if (!kvm_irqchip_in_kernel() && !vms->tcg_its) {
+ /*
+ * Do nothing if ITS is neither supported by the host nor emulated by
+ * the machine.
+ */
return;
}
- dev = qdev_new(itsclass);
+ dev = qdev_new(its_class_name());
object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(vms->gic),
&error_abort);
@@ -2029,10 +2026,11 @@ static void finalize_gic_version(VirtMachineState *vms)
}
/*
- * virt_cpu_post_init() must be called after the CPUs have
- * been realized and the GIC has been created.
+ * virt_post_cpus_gic_realized() must be called after the CPUs and
+ * 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;
bool aarch64, pmu, steal_time;
@@ -2203,14 +2201,14 @@ static void machvirt_init(MachineState *machine)
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 "
"Security extensions (TrustZone) to the guest CPU",
current_accel_name());
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 "
"Virtualization extensions to the guest CPU",
current_accel_name());
@@ -2349,7 +2347,7 @@ static void machvirt_init(MachineState *machine)
create_gic(vms, sysmem);
- virt_cpu_post_init(vms, sysmem);
+ virt_post_cpus_gic_realized(vms, sysmem);
fdt_add_pmu_nodes(vms);
@@ -3342,12 +3340,8 @@ static void virt_instance_init(Object *obj)
/* Default allows ITS instantiation */
vms->its = true;
-
- if (vmc->no_tcg_its) {
- vms->tcg_its = false;
- } else {
- vms->tcg_its = true;
- }
+ /* Allow ITS emulation if the machine version supports it */
+ vms->tcg_its = !vmc->no_tcg_its;
/* Default disallows iommu instantiation */
vms->iommu = VIRT_IOMMU_NONE;
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 83ff74f..6d85720 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -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)
{
ARMCPU *cpu = s->cpu;
+ ARMISARegisters *isar = &cpu->isar;
uint32_t val;
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)) {
goto bad_offset;
}
- return cpu->isar.id_pfr0;
+ return GET_IDREG(isar, ID_PFR0);
case 0xd44: /* PFR1. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_pfr1;
+ return GET_IDREG(isar, ID_PFR1);
case 0xd48: /* DFR0. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_dfr0;
+ return GET_IDREG(isar, ID_DFR0);
case 0xd4c: /* AFR0. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
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)) {
goto bad_offset;
}
- return cpu->isar.id_mmfr0;
+ return GET_IDREG(isar, ID_MMFR0);
case 0xd54: /* MMFR1. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_mmfr1;
+ return GET_IDREG(isar, ID_MMFR1);
case 0xd58: /* MMFR2. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_mmfr2;
+ return GET_IDREG(isar, ID_MMFR2);
case 0xd5c: /* MMFR3. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_mmfr3;
+ return GET_IDREG(isar, ID_MMFR3);
case 0xd60: /* ISAR0. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar0;
+ return GET_IDREG(&cpu->isar, ID_ISAR0);
case 0xd64: /* ISAR1. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar1;
+ return GET_IDREG(&cpu->isar, ID_ISAR1);
case 0xd68: /* ISAR2. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar2;
+ return GET_IDREG(&cpu->isar, ID_ISAR2);
case 0xd6c: /* ISAR3. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar3;
+ return GET_IDREG(&cpu->isar, ID_ISAR3);
case 0xd70: /* ISAR4. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar4;
+ return GET_IDREG(&cpu->isar, ID_ISAR4);
case 0xd74: /* ISAR5. */
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
- return cpu->isar.id_isar5;
+ return GET_IDREG(&cpu->isar, ID_ISAR5);
case 0xd78: /* CLIDR */
return cpu->clidr;
case 0xd7c: /* CTR */
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
index 7dc712b..3c7b543 100644
--- a/include/hw/intc/arm_gicv3_its_common.h
+++ b/include/hw/intc/arm_gicv3_its_common.h
@@ -128,7 +128,7 @@ struct GICv3ITSCommonClass {
* Return the ITS class name to use depending on whether KVM acceleration
* 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);
diff --git a/meson.build b/meson.build
index dbc97bf..b5f74aa 100644
--- a/meson.build
+++ b/meson.build
@@ -3630,6 +3630,7 @@ if have_block
endif
if have_system
trace_events_subdirs += [
+ 'accel/hvf',
'accel/kvm',
'audio',
'backends',
diff --git a/python/qemu/utils/__init__.py b/python/qemu/utils/__init__.py
index 017cfdc..be5daa8 100644
--- a/python/qemu/utils/__init__.py
+++ b/python/qemu/utils/__init__.py
@@ -23,13 +23,19 @@ import textwrap
from typing import Optional
# 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__ = (
'VerboseProcessError',
'add_visual_margin',
'get_info_usernet_hostfwd_port',
+ 'hvf_available',
'kvm_available',
'list_accel',
'tcg_available',
diff --git a/python/qemu/utils/accel.py b/python/qemu/utils/accel.py
index 386ff64..f915b64 100644
--- a/python/qemu/utils/accel.py
+++ b/python/qemu/utils/accel.py
@@ -82,3 +82,12 @@ def tcg_available(qemu_bin: str) -> bool:
@param qemu_bin (str): path to the QEMU binary
"""
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)
diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp
index 5cea5bc..7b25d90 100644
--- a/qga/vss-win32/install.cpp
+++ b/qga/vss-win32/install.cpp
@@ -287,9 +287,13 @@ STDAPI COMRegister(void)
chk(QGAProviderFind(QGAProviderCount, (void *)&count));
if (count) {
- errmsg(E_ABORT, "QGA VSS Provider is already installed");
- qga_debug_end;
- return E_ABORT;
+ qga_debug("QGA VSS Provider is already installed. Attempting to unregister first.");
+ hr = COMUnregister();
+ if (FAILED(hr)) {
+ errmsg(hr, "Failed to unregister existing QGA VSS Provider. Aborting installation.");
+ qga_debug_end;
+ return E_ABORT;
+ }
}
chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER,
@@ -385,7 +389,10 @@ out:
STDAPI_(void) CALLBACK DLLCOMRegister(HWND, HINSTANCE, LPSTR, int);
STDAPI_(void) CALLBACK DLLCOMRegister(HWND, HINSTANCE, LPSTR, int)
{
- COMRegister();
+ HRESULT hr = COMRegister();
+ if (FAILED(hr)) {
+ exit(hr);
+ }
}
STDAPI_(void) CALLBACK DLLCOMUnregister(HWND, HINSTANCE, LPSTR, int);
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index 4452e7c..5d8adfb 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -23,6 +23,7 @@
#include "hw/registerfields.h"
#include "qemu/host-utils.h"
#include "cpu.h"
+#include "cpu-sysregs.h"
/*
* Naming convention for isar_feature functions:
@@ -45,103 +46,103 @@
*/
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)
{
- 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)
{
/* (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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
@@ -150,7 +151,7 @@ static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
* Return true if M-profile state handling insns
* (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)
@@ -283,88 +284,88 @@ static inline bool isar_feature_aa32_vminmaxnm(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)
{
- 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)
{
- 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)
{
/* 0xf means "non-standard IMPDEF PMU" */
- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+ return FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) >= 4 &&
+ FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) != 0xf;
}
static inline bool isar_feature_aa32_pmuv3p4(const ARMISARegisters *id)
{
/* 0xf means "non-standard IMPDEF PMU" */
- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+ return FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) >= 5 &&
+ FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) != 0xf;
}
static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id)
{
/* 0xf means "non-standard IMPDEF PMU" */
- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 6 &&
- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+ return FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) >= 6 &&
+ FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) != 0xf;
}
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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
@@ -377,107 +378,107 @@ static inline bool isar_feature_aa32_doublelock(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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
* and the other two must be zero. Thus we may avoid conditionals.
*/
- return (FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) |
- FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, API) |
- FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3));
+ return (FIELD_EX64_IDREG(id, ID_AA64ISAR1, APA) |
+ FIELD_EX64_IDREG(id, ID_AA64ISAR1, API) |
+ FIELD_EX64_IDREG(id, ID_AA64ISAR2, APA3));
}
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.
* 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)
@@ -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.
* 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
/* 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)
{
/* 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
+ int key = FIELD_EX64_IDREG(id, ID_AA64PFR0, CSV2);
if (key >= 2) {
return true; /* FEAT_CSV2_2 */
}
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 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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));
}
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)
{
- 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));
}
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)
{
- 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)
{
- 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)
{
- 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));
}
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));
}
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));
}
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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+ return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 4 &&
+ FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) != 0xf;
}
static inline bool isar_feature_aa64_pmuv3p4(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+ return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 5 &&
+ FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) != 0xf;
}
static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
{
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 6 &&
- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+ return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 6 &&
+ FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) != 0xf;
}
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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- 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)
{
- return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64);
+ return FIELD_EX64_IDREG(id, ID_AA64SMFR0, FA64);
}
/*
diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h
new file mode 100644
index 0000000..7877a3b
--- /dev/null
+++ b/target/arm/cpu-sysregs.h
@@ -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 */
diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
new file mode 100644
index 0000000..cb99286
--- /dev/null
+++ b/target/arm/cpu-sysregs.h.inc
@@ -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)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index e025e24..a59a5b5 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1500,6 +1500,7 @@ static void arm_cpu_initfn(Object *obj)
* 0 means "unset, use the default value". That default might vary depending
* on the CPU type, and is set in the realize fn.
*/
+#ifndef CONFIG_USER_ONLY
static const Property arm_cpu_gt_cntfrq_property =
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 =
DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false);
-#ifndef CONFIG_USER_ONLY
static const Property arm_cpu_has_el2_property =
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 =
DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true);
+#ifndef CONFIG_USER_ONLY
static const Property arm_cpu_has_mpu_property =
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,
pmsav7_dregion,
qdev_prop_uint32, uint32_t);
+#endif
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);
@@ -1731,6 +1733,7 @@ void arm_cpu_post_init(Object *obj)
"Set on/off to enable/disable aarch64 "
"execution state ");
}
+#ifndef CONFIG_USER_ONLY
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
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);
}
-#ifndef CONFIG_USER_ONLY
if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
/* 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.
@@ -1818,6 +1820,7 @@ void arm_cpu_post_init(Object *obj)
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property);
}
+#ifndef CONFIG_USER_ONLY
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property);
if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
@@ -1854,8 +1857,6 @@ void arm_cpu_post_init(Object *obj)
&cpu->psci_conduit,
OBJ_PROP_FLAG_READWRITE);
- qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
-
if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) {
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);
}
-#ifndef CONFIG_USER_ONLY
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) &&
cpu_isar_feature(aa64_mte, cpu)) {
object_property_add_link(obj, "tag-memory",
@@ -1882,6 +1882,7 @@ void arm_cpu_post_init(Object *obj)
}
}
#endif
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
}
static void arm_cpu_finalizefn(Object *obj)
@@ -1962,6 +1963,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
ARMCPU *cpu = ARM_CPU(dev);
+ ARMISARegisters *isar = &cpu->isar;
ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);
CPUARMState *env = &cpu->env;
Error *local_err = NULL;
@@ -2119,21 +2121,16 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
if (!cpu->has_vfp) {
- uint64_t t;
uint32_t u;
- t = cpu->isar.id_aa64isar1;
- t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0);
- cpu->isar.id_aa64isar1 = t;
+ FIELD_DP64_IDREG(isar, ID_AA64ISAR1, JSCVT, 0);
- t = cpu->isar.id_aa64pfr0;
- t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf);
- cpu->isar.id_aa64pfr0 = t;
+ FIELD_DP64_IDREG(isar, ID_AA64PFR0, FP, 0xf);
- 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, BF16, 0);
- cpu->isar.id_isar6 = u;
+ SET_IDREG(isar, ID_ISAR6, u);
u = cpu->isar.mvfr0;
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);
- 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, SHA1, 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, SM4, 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, BF16, 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;
- t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf);
- cpu->isar.id_aa64pfr0 = t;
+ FIELD_DP64_IDREG(isar, ID_AA64PFR0, ADVSIMD, 0xf);
- 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, SHA1, 0);
u = FIELD_DP32(u, ID_ISAR5, SHA2, 0);
u = FIELD_DP32(u, ID_ISAR5, RDM, 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, FHM, 0);
u = FIELD_DP32(u, ID_ISAR6, BF16, 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)) {
u = cpu->isar.mvfr1;
@@ -2217,16 +2212,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
if (!cpu->has_neon && !cpu->has_vfp) {
- uint64_t t;
uint32_t u;
- t = cpu->isar.id_aa64isar0;
- t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0);
- cpu->isar.id_aa64isar0 = t;
+ FIELD_DP64_IDREG(isar, ID_AA64ISAR0, FHM, 0);
- t = cpu->isar.id_aa64isar1;
- t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0);
- cpu->isar.id_aa64isar1 = t;
+ FIELD_DP64_IDREG(isar, ID_AA64ISAR1, FRINTTS, 0);
u = cpu->isar.mvfr0;
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);
- u = cpu->isar.id_isar1;
- u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1);
- cpu->isar.id_isar1 = u;
+ FIELD_DP32_IDREG(isar, ID_ISAR1, EXTEND, 1);
- 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, 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, 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
* feature registers as well.
*/
- cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
- cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
- cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
- ID_AA64PFR0, EL3, 0);
+ FIELD_DP32_IDREG(isar, ID_PFR1, SECURITY, 0);
+ FIELD_DP32_IDREG(isar, ID_DFR0, COPSDBG, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64PFR0, EL3, 0);
/* Disable the realm management extension, which requires EL3. */
- cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
- ID_AA64PFR0, RME, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64PFR0, RME, 0);
}
if (!cpu->has_el2) {
@@ -2360,9 +2346,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
cpu);
#endif
} else {
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
- cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64DFR0, PMUVER, 0);
+ FIELD_DP32_IDREG(isar, ID_DFR0, PERFMON, 0);
cpu->pmceid0 = 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
* registers if we don't have EL2.
*/
- cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
- ID_AA64PFR0, EL2, 0);
- cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1,
- ID_PFR1, VIRTUALIZATION, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64PFR0, EL2, 0);
+ FIELD_DP32_IDREG(isar, ID_PFR1, VIRTUALIZATION, 0);
}
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.
*/
if (tcg_enabled() && cpu->tag_memory == NULL) {
- cpu->isar.id_aa64pfr1 =
- FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1);
+ FIELD_DP64_IDREG(isar, 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."
*/
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
}
@@ -2423,32 +2405,22 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* try to access the non-existent system registers for them.
*/
/* FEAT_SPE (Statistical Profiling Extension) */
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMSVER, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64DFR0, PMSVER, 0);
/* FEAT_TRBE (Trace Buffer Extension) */
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEBUFFER, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEBUFFER, 0);
/* FEAT_TRF (Self-hosted Trace Extension) */
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEFILT, 0);
- cpu->isar.id_dfr0 =
- FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, TRACEFILT, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEFILT, 0);
+ FIELD_DP32_IDREG(isar, ID_DFR0, TRACEFILT, 0);
/* Trace Macrocell system register access */
- cpu->isar.id_aa64dfr0 =
- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEVER, 0);
- cpu->isar.id_dfr0 =
- FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPTRC, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEVER, 0);
+ FIELD_DP32_IDREG(isar, ID_DFR0, COPTRC, 0);
/* Memory mapped trace */
- cpu->isar.id_dfr0 =
- FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0);
+ FIELD_DP32_IDREG(isar, ID_DFR0, MMAPTRC, 0);
/* FEAT_AMU (Activity Monitors Extension) */
- cpu->isar.id_aa64pfr0 =
- FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, AMU, 0);
- cpu->isar.id_pfr0 =
- FIELD_DP32(cpu->isar.id_pfr0, ID_PFR0, AMU, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64PFR0, AMU, 0);
+ FIELD_DP32_IDREG(isar, ID_PFR0, AMU, 0);
/* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
- cpu->isar.id_aa64pfr0 =
- FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
+ FIELD_DP64_IDREG(isar, ID_AA64PFR0, MPAM, 0);
}
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 302c24e..0338153 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -32,6 +32,7 @@
#include "qapi/qapi-types-common.h"
#include "target/arm/multiprocessing.h"
#include "target/arm/gtimer.h"
+#include "target/arm/cpu-sysregs.h"
#define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */
@@ -834,6 +835,53 @@ typedef struct {
uint32_t map, init, supported;
} 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:
* @env: #CPUARMState
@@ -1002,44 +1050,14 @@ struct ArchCPU {
* field by reading the value from the KVM vCPU.
*/
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 mvfr1;
uint32_t mvfr2;
- uint32_t id_dfr0;
- uint32_t id_dfr1;
uint32_t dbgdidr;
uint32_t dbgdevid;
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 idregs[NUM_ID_IDX];
} isar;
uint64_t midr;
uint32_t revidr;
@@ -1150,8 +1168,6 @@ void arm_gt_sel2vtimer_cb(void *opaque);
unsigned int gt_cntfrq_period_ns(ARMCPU *cpu);
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_MASK (0xFFULL << ARM_AFF0_SHIFT)
#define ARM_AFF1_SHIFT 8
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 200da1c..1f34067 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -36,6 +36,28 @@
#include "cpu-features.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)
{
/*
@@ -114,7 +136,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
* SVE is disabled and so are all vector lengths. Good.
* Disable all SVE extensions as well.
*/
- cpu->isar.id_aa64zfr0 = 0;
+ SET_IDREG(&cpu->isar, ID_AA64ZFR0, 0);
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)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
error_setg(errp, "'sve' feature not supported by KVM on this host");
return;
}
- t = cpu->isar.id_aa64pfr0;
- t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
- cpu->isar.id_aa64pfr0 = t;
+ FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR0, SVE, value);
}
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 (!cpu_isar_feature(aa64_sme, cpu)) {
- cpu->isar.id_aa64smfr0 = 0;
+ SET_IDREG(&cpu->isar, ID_AA64SMFR0, 0);
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)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
- t = cpu->isar.id_aa64pfr1;
- t = FIELD_DP64(t, ID_AA64PFR1, SME, value);
- cpu->isar.id_aa64pfr1 = t;
+ FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR1, SME, value);
}
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)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
- t = cpu->isar.id_aa64smfr0;
- t = FIELD_DP64(t, ID_AA64SMFR0, FA64, value);
- cpu->isar.id_aa64smfr0 = t;
+ FIELD_DP64_IDREG(&cpu->isar, ID_AA64SMFR0, FA64, value);
}
#ifdef CONFIG_USER_ONLY
@@ -480,6 +493,7 @@ void aarch64_add_sme_properties(Object *obj)
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
{
ARMPauthFeature features = cpu_isar_feature(pauth_feature, cpu);
+ ARMISARegisters *isar = &cpu->isar;
uint64_t isar1, isar2;
/*
@@ -490,13 +504,13 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
*
* 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, GPA, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, 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, GPA3, 0);
@@ -558,8 +572,8 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
}
}
- cpu->isar.id_aa64isar1 = isar1;
- cpu->isar.id_aa64isar2 = isar2;
+ SET_IDREG(isar, ID_AA64ISAR1, isar1);
+ SET_IDREG(isar, ID_AA64ISAR2, isar2);
}
static const Property arm_cpu_pauth_property =
@@ -606,17 +620,18 @@ void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
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, 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, 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)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a57";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -637,25 +652,25 @@ static void aarch64_a57_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(isar, ID_PFR0, 0x00000131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10101105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_isar6 = 0;
- cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64isar0 = 0x00011120;
- cpu->isar.id_aa64mmfr0 = 0x00001124;
+ SET_IDREG(isar, ID_MMFR0, 0x10101105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02102211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00011142);
+ SET_IDREG(isar, ID_ISAR5, 0x00011121);
+ SET_IDREG(isar, ID_ISAR6, 0);
+ SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
+ SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
+ SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x00001124);
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x2;
@@ -678,6 +693,7 @@ static void aarch64_a57_initfn(Object *obj)
static void aarch64_a53_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a53";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -698,25 +714,25 @@ static void aarch64_a53_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x84448004; /* L1Ip = VIPT */
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(isar, ID_PFR0, 0x00000131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10101105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_isar6 = 0;
- cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64isar0 = 0x00011120;
- cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
+ SET_IDREG(isar, ID_MMFR0, 0x10101105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02102211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00011142);
+ SET_IDREG(isar, ID_ISAR5, 0x00011121);
+ SET_IDREG(isar, ID_ISAR6, 0);
+ SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
+ SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
+ SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x00001122); /* 40 bit physical addr */
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x00110f13;
cpu->isar.dbgdevid1 = 0x1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 889d308..c311d2d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6932,7 +6932,7 @@ static void define_pmu_regs(ARMCPU *cpu)
static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
ARMCPU *cpu = env_archcpu(env);
- uint64_t pfr1 = cpu->isar.id_pfr1;
+ uint64_t pfr1 = GET_IDREG(&cpu->isar, ID_PFR1);
if (env->gicv3state) {
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)
{
ARMCPU *cpu = env_archcpu(env);
- uint64_t pfr0 = cpu->isar.id_aa64pfr0;
+ uint64_t pfr0 = GET_IDREG(&cpu->isar, ID_AA64PFR0);
if (env->gicv3state) {
pfr0 |= 1 << 24;
@@ -7750,6 +7750,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{
/* Register all the coprocessor registers based on feature bits */
CPUARMState *env = &cpu->env;
+ ARMISARegisters *isar = &cpu->isar;
+
if (arm_feature(env, ARM_FEATURE_M)) {
/* M profile has no coprocessor registers */
return;
@@ -7775,7 +7777,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
.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
* 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,
#ifdef CONFIG_USER_ONLY
.type = ARM_CP_CONST,
- .resetvalue = cpu->isar.id_pfr1,
+ .resetvalue = GET_IDREG(isar, ID_PFR1),
#else
.type = ARM_CP_NO_RAW,
.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,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_dfr0 },
+ .resetvalue = GET_IDREG(isar, ID_DFR0)},
{ .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
.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,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr0 },
+ .resetvalue = GET_IDREG(isar, ID_MMFR0)},
{ .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr1 },
+ .resetvalue = GET_IDREG(isar, ID_MMFR1)},
{ .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr2 },
+ .resetvalue = GET_IDREG(isar, ID_MMFR2)},
{ .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr3 },
+ .resetvalue = GET_IDREG(isar, ID_MMFR3)},
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar0 },
+ .resetvalue = GET_IDREG(isar, ID_ISAR0)},
{ .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar1 },
+ .resetvalue = GET_IDREG(isar, ID_ISAR1)},
{ .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar2 },
+ .resetvalue = GET_IDREG(isar, ID_ISAR2)},
{ .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar3 },
+ .resetvalue = GET_IDREG(isar, ID_ISAR3) },
{ .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar4 },
+ .resetvalue = GET_IDREG(isar, ID_ISAR4) },
{ .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_isar5 },
+ .resetvalue = GET_IDREG(isar, ID_ISAR5) },
{ .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa32_tid3,
- .resetvalue = cpu->isar.id_mmfr4 },
+ .resetvalue = GET_IDREG(isar, ID_MMFR4)},
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.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_cp_reginfo);
@@ -7914,7 +7916,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.access = PL1_R,
#ifdef CONFIG_USER_ONLY
.type = ARM_CP_CONST,
- .resetvalue = cpu->isar.id_aa64pfr0
+ .resetvalue = GET_IDREG(isar, ID_AA64PFR0)
#else
.type = ARM_CP_NO_RAW,
.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,
.access = PL1_R, .type = ARM_CP_CONST,
.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,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
.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,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64zfr0 },
+ .resetvalue = GET_IDREG(isar, ID_AA64ZFR0)},
{ .name = "ID_AA64SMFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.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,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,
.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,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64dfr0 },
+ .resetvalue = GET_IDREG(isar, ID_AA64DFR0) },
{ .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.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,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
.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,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64isar0 },
+ .resetvalue = GET_IDREG(isar, ID_AA64ISAR0)},
{ .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64isar1 },
+ .resetvalue = GET_IDREG(isar, ID_AA64ISAR1)},
{ .name = "ID_AA64ISAR2_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.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,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
.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,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64mmfr0 },
+ .resetvalue = GET_IDREG(isar, ID_AA64MMFR0)},
{ .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64mmfr1 },
+ .resetvalue = GET_IDREG(isar, ID_AA64MMFR1) },
{ .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_aa64mmfr2 },
+ .resetvalue = GET_IDREG(isar, ID_AA64MMFR2) },
{ .name = "ID_AA64MMFR3_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.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,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
.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,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_pfr2 },
+ .resetvalue = GET_IDREG(isar, ID_PFR2)},
{ .name = "ID_DFR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.accessfn = access_aa64_tid3,
- .resetvalue = cpu->isar.id_dfr1 },
+ .resetvalue = GET_IDREG(isar, ID_DFR1)},
{ .name = "ID_MMFR5", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.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,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 42258cc..7b6d291 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -19,6 +19,7 @@
#include "system/hw_accel.h"
#include "hvf_arm.h"
#include "cpregs.h"
+#include "cpu-sysregs.h"
#include <mach/mach_time.h>
@@ -845,14 +846,17 @@ static uint64_t hvf_get_reg(CPUState *cpu, int rt)
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 ?
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. */
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)
@@ -862,16 +866,16 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
int reg;
uint64_t *val;
} regs[] = {
- { HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.id_aa64pfr0 },
- { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.id_aa64pfr1 },
- { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.id_aa64dfr0 },
- { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.id_aa64dfr1 },
- { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.id_aa64isar0 },
- { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.id_aa64isar1 },
+ { HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.idregs[ID_AA64PFR0_EL1_IDX] },
+ { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.idregs[ID_AA64PFR1_EL1_IDX] },
+ { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.idregs[ID_AA64DFR0_EL1_IDX] },
+ { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.idregs[ID_AA64DFR1_EL1_IDX] },
+ { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.idregs[ID_AA64ISAR0_EL1_IDX] },
+ { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.idregs[ID_AA64ISAR1_EL1_IDX] },
/* Add ID_AA64ISAR2_EL1 here when HVF supports it */
- { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 },
- { HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 },
- { HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.id_aa64mmfr2 },
+ { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.idregs[ID_AA64MMFR0_EL1_IDX] },
+ { HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.idregs[ID_AA64MMFR1_EL1_IDX] },
+ { HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.idregs[ID_AA64MMFR2_EL1_IDX] },
/* Add ID_AA64MMFR3_EL1 here when HVF supports it */
};
hv_vcpu_t fd;
@@ -879,7 +883,7 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
hv_vcpu_exit_t *exit;
int i;
- ahcf->dtb_compatible = "arm,arm-v8";
+ ahcf->dtb_compatible = "arm,armv8";
ahcf->features = (1ULL << ARM_FEATURE_V8) |
(1ULL << ARM_FEATURE_NEON) |
(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_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.
@@ -910,7 +914,8 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* - fix any assumptions we made that SME implies SVE (since
* 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;
@@ -927,7 +932,7 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ahcf->reset_sctlr |= 0x00800000;
/* 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;
}
@@ -1065,12 +1070,12 @@ int hvf_arch_init_vcpu(CPUState *cpu)
/* 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,
- &arm_cpu->isar.id_aa64mmfr0);
+ &arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]);
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,
- arm_cpu->isar.id_aa64mmfr0);
+ arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]);
assert_hvf_ok(ret);
return 0;
@@ -1083,13 +1088,13 @@ void hvf_kick_vcpu_thread(CPUState *cpu)
}
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);
CPUARMState *env = &arm_cpu->env;
cpu->exception_index = excp;
- env->exception.target_el = 1;
+ env->exception.target_el = target_el;
env->exception.syndrome = syndrome;
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_CRM(reg),
SYSREG_OP2(reg));
- hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized(), 1);
return 1;
}
@@ -1759,7 +1764,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
SYSREG_CRN(reg),
SYSREG_CRM(reg),
SYSREG_OP2(reg));
- hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized(), 1);
return 1;
}
@@ -1910,7 +1915,17 @@ int hvf_vcpu_exec(CPUState *cpu)
flush_cpu_state(cpu);
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 */
uint64_t exit_reason = hvf_exit->reason;
@@ -1918,7 +1933,6 @@ int hvf_vcpu_exec(CPUState *cpu)
uint32_t ec = syn_get_ec(syndrome);
ret = 0;
- bql_lock();
switch (exit_reason) {
case HV_EXIT_REASON_EXCEPTION:
/* 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)) {
/* Re-inject into the guest */
ret = 0;
- hvf_raise_exception(cpu, EXCP_BKPT, syn_aa64_bkpt(0));
+ hvf_raise_exception(cpu, EXCP_BKPT, syn_aa64_bkpt(0), 1);
}
break;
}
@@ -2058,13 +2072,13 @@ int hvf_vcpu_exec(CPUState *cpu)
cpu_synchronize_state(cpu);
if (arm_cpu->psci_conduit == QEMU_PSCI_CONDUIT_HVC) {
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 */
env->xregs[0] = -1;
}
} else {
- trace_hvf_unknown_hvc(env->xregs[0]);
- hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
+ trace_hvf_unknown_hvc(env->pc, env->xregs[0]);
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized(), 1);
}
break;
case EC_AA64_SMC:
@@ -2079,7 +2093,7 @@ int hvf_vcpu_exec(CPUState *cpu)
}
} else {
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;
default:
diff --git a/target/arm/hvf/trace-events b/target/arm/hvf/trace-events
index 4fbbe4b..b49746f 100644
--- a/target/arm/hvf/trace-events
+++ b/target/arm/hvf/trace-events
@@ -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_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_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_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_read(const char *name, uint64_t val) "vgic read from %s [val=0x%016"PRIx64"]"
+hvf_illegal_guest_state(void) "HV_ILLEGAL_GUEST_STATE"
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 3360de9..21a8d67 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -650,16 +650,12 @@ static inline bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
{
return false;
}
-static inline void arm_handle_psci_call(ARMCPU *cpu)
-{
- g_assert_not_reached();
-}
#else
/* 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);
+#endif
/* Actually handle a PSCI call */
void arm_handle_psci_call(ARMCPU *cpu);
-#endif
/**
* 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)
{
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 {
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)
{
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 {
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)
{
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 {
return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1;
}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 74fda8b..426f8b1 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -26,6 +26,7 @@
#include "system/kvm_int.h"
#include "kvm_arm.h"
#include "cpu.h"
+#include "cpu-sysregs.h"
#include "trace.h"
#include "internals.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));
}
+
+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)
{
/* 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->dtb_compatible = "arm,arm-v8";
+ ahcf->dtb_compatible = "arm,armv8";
+ int fd = fdarray[2];
- err = read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr0,
- ARM64_SYS_REG(3, 0, 0, 4, 0));
+ err = get_host_cpu_reg(fd, ahcf, ID_AA64PFR0_EL1_IDX);
if (unlikely(err < 0)) {
/*
* 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
* 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;
} else {
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1,
- ARM64_SYS_REG(3, 0, 0, 4, 1));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64smfr0,
- ARM64_SYS_REG(3, 0, 0, 4, 5));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0,
- ARM64_SYS_REG(3, 0, 0, 5, 0));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1,
- ARM64_SYS_REG(3, 0, 0, 5, 1));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0,
- ARM64_SYS_REG(3, 0, 0, 6, 0));
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
- 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));
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64DFR0_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64DFR1_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR0_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR1_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR2_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR0_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR1_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR2_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR3_EL1_IDX);
/*
* 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
* considering the values in every case.
*/
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr0,
- ARM64_SYS_REG(3, 0, 0, 1, 0));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1,
- ARM64_SYS_REG(3, 0, 0, 1, 1));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
- ARM64_SYS_REG(3, 0, 0, 1, 2));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
- ARM64_SYS_REG(3, 0, 0, 1, 4));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
- ARM64_SYS_REG(3, 0, 0, 1, 5));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
- ARM64_SYS_REG(3, 0, 0, 1, 6));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
- ARM64_SYS_REG(3, 0, 0, 1, 7));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
- 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 |= get_host_cpu_reg(fd, ahcf, ID_PFR0_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_PFR1_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_DFR0_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_MMFR0_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_MMFR1_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_MMFR2_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_MMFR3_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_ISAR0_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_ISAR1_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_ISAR2_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_ISAR3_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_ISAR4_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_ISAR5_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_ISAR6_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_MMFR4_EL1_IDX);
+
+ err |= read_sys_reg32(fd, &ahcf->isar.mvfr0,
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));
- 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));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
- ARM64_SYS_REG(3, 0, 0, 3, 4));
- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr1,
- 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));
+ err |= get_host_cpu_reg(fd, ahcf, ID_PFR2_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX);
+ err |= get_host_cpu_reg(fd, ahcf, ID_MMFR5_EL1_IDX);
/*
* 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.
* We only do this if the CPU supports AArch32 at EL1.
*/
- if (FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL1) >= 2) {
- int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS);
- int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS);
+ if (FIELD_EX32_IDREG(&ahcf->isar, ID_AA64PFR0, EL1) >= 2) {
+ int wrps = FIELD_EX64_IDREG(&ahcf->isar, ID_AA64DFR0, WRPS);
+ int brps = FIELD_EX64_IDREG(&ahcf->isar, ID_AA64DFR0, BRPS);
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 */
bool has_el3 =
- !!FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL3);
+ !!FIELD_EX32_IDREG(&ahcf->isar, ID_AA64PFR0, EL3);
uint32_t dbgdidr = 0;
dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps);
@@ -396,7 +390,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
if (pmu_supported) {
/* 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));
}
@@ -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.
* So only read the register if we set KVM_ARM_VCPU_SVE above.
*/
- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64zfr0,
- ARM64_SYS_REG(3, 0, 0, 4, 4));
+ err |= get_host_cpu_reg(fd, ahcf, ID_AA64ZFR0_EL1_IDX);
}
}
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 44170d8..561bf26 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -122,7 +122,7 @@ unsigned int arm_pamax(ARMCPU *cpu)
{
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
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
@@ -332,7 +332,7 @@ static bool granule_protection_check(CPUARMState *env, uint64_t paddress,
* physical address size is invalid.
*/
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;
}
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
* 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);
assert(ps < ARRAY_SIZE(pamax_map));
outputsize = pamax_map[ps];
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
index 8e1a083..eddd711 100644
--- a/target/arm/tcg/cpu-v7m.c
+++ b/target/arm/tcg/cpu-v7m.c
@@ -45,6 +45,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
static void cortex_m0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V6);
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
* for the M3.
*/
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000200;
- cpu->isar.id_dfr0 = 0x00100000;
+ SET_IDREG(isar, ID_PFR0, 0x00000030);
+ SET_IDREG(isar, ID_PFR1, 0x00000200);
+ SET_IDREG(isar, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00000030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x00000000;
- cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01141110;
- cpu->isar.id_isar1 = 0x02111000;
- cpu->isar.id_isar2 = 0x21112231;
- cpu->isar.id_isar3 = 0x01111110;
- cpu->isar.id_isar4 = 0x01310102;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(isar, ID_MMFR0, 0x00000030);
+ SET_IDREG(isar, ID_MMFR1, 0x00000000);
+ SET_IDREG(isar, ID_MMFR2, 0x00000000);
+ SET_IDREG(isar, ID_MMFR3, 0x00000000);
+ SET_IDREG(isar, ID_ISAR0, 0x01141110);
+ SET_IDREG(isar, ID_ISAR1, 0x02111000);
+ SET_IDREG(isar, ID_ISAR2, 0x21112231);
+ SET_IDREG(isar, ID_ISAR3, 0x01111110);
+ SET_IDREG(isar, ID_ISAR4, 0x01310102);
+ SET_IDREG(isar, ID_ISAR5, 0x00000000);
+ SET_IDREG(isar, ID_ISAR6, 0x00000000);
}
static void cortex_m3_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
cpu->midr = 0x410fc231;
cpu->pmsav7_dregion = 8;
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000200;
- cpu->isar.id_dfr0 = 0x00100000;
+ SET_IDREG(isar, ID_PFR0, 0x00000030);
+ SET_IDREG(isar, ID_PFR1, 0x00000200);
+ SET_IDREG(isar, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00000030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x00000000;
- cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01141110;
- cpu->isar.id_isar1 = 0x02111000;
- cpu->isar.id_isar2 = 0x21112231;
- cpu->isar.id_isar3 = 0x01111110;
- cpu->isar.id_isar4 = 0x01310102;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(isar, ID_MMFR0, 0x00000030);
+ SET_IDREG(isar, ID_MMFR1, 0x00000000);
+ SET_IDREG(isar, ID_MMFR2, 0x00000000);
+ SET_IDREG(isar, ID_MMFR3, 0x00000000);
+ SET_IDREG(isar, ID_ISAR0, 0x01141110);
+ SET_IDREG(isar, ID_ISAR1, 0x02111000);
+ SET_IDREG(isar, ID_ISAR2, 0x21112231);
+ SET_IDREG(isar, ID_ISAR3, 0x01111110);
+ SET_IDREG(isar, ID_ISAR4, 0x01310102);
+ SET_IDREG(isar, ID_ISAR5, 0x00000000);
+ SET_IDREG(isar, ID_ISAR6, 0x00000000);
}
static void cortex_m4_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
@@ -113,26 +116,27 @@ static void cortex_m4_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000000;
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000200;
- cpu->isar.id_dfr0 = 0x00100000;
+ SET_IDREG(isar, ID_PFR0, 0x00000030);
+ SET_IDREG(isar, ID_PFR1, 0x00000200);
+ SET_IDREG(isar, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00000030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x00000000;
- cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01141110;
- cpu->isar.id_isar1 = 0x02111000;
- cpu->isar.id_isar2 = 0x21112231;
- cpu->isar.id_isar3 = 0x01111110;
- cpu->isar.id_isar4 = 0x01310102;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(isar, ID_MMFR0, 0x00000030);
+ SET_IDREG(isar, ID_MMFR1, 0x00000000);
+ SET_IDREG(isar, ID_MMFR2, 0x00000000);
+ SET_IDREG(isar, ID_MMFR3, 0x00000000);
+ SET_IDREG(isar, ID_ISAR0, 0x01141110);
+ SET_IDREG(isar, ID_ISAR1, 0x02111000);
+ SET_IDREG(isar, ID_ISAR2, 0x21112231);
+ SET_IDREG(isar, ID_ISAR3, 0x01111110);
+ SET_IDREG(isar, ID_ISAR4, 0x01310102);
+ SET_IDREG(isar, ID_ISAR5, 0x00000000);
+ SET_IDREG(isar, ID_ISAR6, 0x00000000);
}
static void cortex_m7_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
@@ -143,26 +147,27 @@ static void cortex_m7_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x12000011;
cpu->isar.mvfr2 = 0x00000040;
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000200;
- cpu->isar.id_dfr0 = 0x00100000;
+ SET_IDREG(isar, ID_PFR0, 0x00000030);
+ SET_IDREG(isar, ID_PFR1, 0x00000200);
+ SET_IDREG(isar, ID_DFR0, 0x00100000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00100030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x01000000;
- cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01101110;
- cpu->isar.id_isar1 = 0x02112000;
- cpu->isar.id_isar2 = 0x20232231;
- cpu->isar.id_isar3 = 0x01111131;
- cpu->isar.id_isar4 = 0x01310132;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(isar, ID_MMFR0, 0x00100030);
+ SET_IDREG(isar, ID_MMFR1, 0x00000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01000000);
+ SET_IDREG(isar, ID_MMFR3, 0x00000000);
+ SET_IDREG(isar, ID_ISAR0, 0x01101110);
+ SET_IDREG(isar, ID_ISAR1, 0x02112000);
+ SET_IDREG(isar, ID_ISAR2, 0x20232231);
+ SET_IDREG(isar, ID_ISAR3, 0x01111131);
+ SET_IDREG(isar, ID_ISAR4, 0x01310132);
+ SET_IDREG(isar, ID_ISAR5, 0x00000000);
+ SET_IDREG(isar, ID_ISAR6, 0x00000000);
}
static void cortex_m33_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_M);
@@ -175,21 +180,21 @@ static void cortex_m33_initfn(Object *obj)
cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000040;
- cpu->isar.id_pfr0 = 0x00000030;
- cpu->isar.id_pfr1 = 0x00000210;
- cpu->isar.id_dfr0 = 0x00200000;
+ SET_IDREG(isar, ID_PFR0, 0x00000030);
+ SET_IDREG(isar, ID_PFR1, 0x00000210);
+ SET_IDREG(isar, ID_DFR0, 0x00200000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00101F40;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x01000000;
- cpu->isar.id_mmfr3 = 0x00000000;
- cpu->isar.id_isar0 = 0x01101110;
- cpu->isar.id_isar1 = 0x02212000;
- cpu->isar.id_isar2 = 0x20232232;
- cpu->isar.id_isar3 = 0x01111131;
- cpu->isar.id_isar4 = 0x01310132;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(isar, ID_MMFR0, 0x00101F40);
+ SET_IDREG(isar, ID_MMFR1, 0x00000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01000000);
+ SET_IDREG(isar, ID_MMFR3, 0x00000000);
+ SET_IDREG(isar, ID_ISAR0, 0x01101110);
+ SET_IDREG(isar, ID_ISAR1, 0x02212000);
+ SET_IDREG(isar, ID_ISAR2, 0x20232232);
+ SET_IDREG(isar, ID_ISAR3, 0x01111131);
+ SET_IDREG(isar, ID_ISAR4, 0x01310132);
+ SET_IDREG(isar, ID_ISAR5, 0x00000000);
+ SET_IDREG(isar, ID_ISAR6, 0x00000000);
cpu->clidr = 0x00000000;
cpu->ctr = 0x8000c000;
}
@@ -197,6 +202,7 @@ static void cortex_m33_initfn(Object *obj)
static void cortex_m55_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V8);
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.mvfr1 = 0x12100211;
cpu->isar.mvfr2 = 0x00000040;
- cpu->isar.id_pfr0 = 0x20000030;
- cpu->isar.id_pfr1 = 0x00000230;
- cpu->isar.id_dfr0 = 0x10200000;
+ SET_IDREG(isar, ID_PFR0, 0x20000030);
+ SET_IDREG(isar, ID_PFR1, 0x00000230);
+ SET_IDREG(isar, ID_DFR0, 0x10200000);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00111040;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x01000000;
- cpu->isar.id_mmfr3 = 0x00000011;
- cpu->isar.id_isar0 = 0x01103110;
- cpu->isar.id_isar1 = 0x02212000;
- cpu->isar.id_isar2 = 0x20232232;
- cpu->isar.id_isar3 = 0x01111131;
- cpu->isar.id_isar4 = 0x01310132;
- cpu->isar.id_isar5 = 0x00000000;
- cpu->isar.id_isar6 = 0x00000000;
+ SET_IDREG(isar, ID_MMFR0, 0x00111040);
+ SET_IDREG(isar, ID_MMFR1, 0x00000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01000000);
+ SET_IDREG(isar, ID_MMFR3, 0x00000011);
+ SET_IDREG(isar, ID_ISAR0, 0x01103110);
+ SET_IDREG(isar, ID_ISAR1, 0x02212000);
+ SET_IDREG(isar, ID_ISAR2, 0x20232232);
+ SET_IDREG(isar, ID_ISAR3, 0x01111131);
+ SET_IDREG(isar, ID_ISAR4, 0x01310132);
+ SET_IDREG(isar, ID_ISAR5, 0x00000000);
+ SET_IDREG(isar, ID_ISAR6, 0x00000000);
cpu->clidr = 0x00000000; /* caches not implemented */
cpu->ctr = 0x8303c003;
}
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index 2c45b7e..942b636 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -23,18 +23,19 @@
void aa32_max_features(ARMCPU *cpu)
{
uint32_t t;
+ ARMISARegisters *isar = &cpu->isar;
/* 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, SHA1, 1); /* FEAT_SHA1 */
t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */
t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */
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, DP, 1); /* Feat_DotProd */
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, BF16, 1); /* FEAT_AA32BF16 */
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 = 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 */
cpu->isar.mvfr2 = t;
- t = cpu->isar.id_mmfr3;
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
- cpu->isar.id_mmfr3 = t;
+ FIELD_DP32_IDREG(isar, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
- 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, AC2, 1); /* ACTLR2, HACTLR2 */
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, EVT, 2); /* FEAT_EVT */
- cpu->isar.id_mmfr4 = t;
+ SET_IDREG(isar, ID_MMFR4, t);
- t = cpu->isar.id_mmfr5;
- t = FIELD_DP32(t, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
- cpu->isar.id_mmfr5 = t;
+ FIELD_DP32_IDREG(isar, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
- 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, DIT, 1); /* FEAT_DIT */
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, 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, COPSDBG, 10); /* FEAT_Debugv8p8 */
t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */
- cpu->isar.id_dfr0 = t;
+ SET_IDREG(isar, ID_DFR0, t);
/* Debug ID registers. */
@@ -115,9 +112,7 @@ void aa32_max_features(ARMCPU *cpu)
t = FIELD_DP32(t, DBGDEVID1, PCSROFFSET, 2);
cpu->isar.dbgdevid1 = t;
- t = cpu->isar.id_dfr1;
- t = FIELD_DP32(t, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
- cpu->isar.id_dfr1 = t;
+ FIELD_DP32_IDREG(isar, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
}
/* 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
* 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
* 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
* 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
* 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)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
/*
* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
* 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->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
- cpu->isar.id_pfr0 = 0x111;
- cpu->isar.id_pfr1 = 0x1;
- cpu->isar.id_dfr0 = 0x2;
+ SET_IDREG(isar, ID_PFR0, 0x111);
+ SET_IDREG(isar, ID_PFR1, 0x1);
+ SET_IDREG(isar, ID_DFR0, 0x2);
cpu->id_afr0 = 0x3;
- cpu->isar.id_mmfr0 = 0x01130003;
- cpu->isar.id_mmfr1 = 0x10030302;
- cpu->isar.id_mmfr2 = 0x01222110;
- cpu->isar.id_isar0 = 0x00140011;
- cpu->isar.id_isar1 = 0x12002111;
- cpu->isar.id_isar2 = 0x11231111;
- cpu->isar.id_isar3 = 0x01102131;
- cpu->isar.id_isar4 = 0x141;
+ SET_IDREG(isar, ID_MMFR0, 0x01130003);
+ SET_IDREG(isar, ID_MMFR1, 0x10030302);
+ SET_IDREG(isar, ID_MMFR2, 0x01222110);
+ SET_IDREG(isar, ID_ISAR0, 0x00140011);
+ SET_IDREG(isar, ID_ISAR1, 0x12002111);
+ SET_IDREG(isar, ID_ISAR2, 0x11231111);
+ SET_IDREG(isar, ID_ISAR3, 0x01102131);
+ SET_IDREG(isar, ID_ISAR4, 0x141);
cpu->reset_auxcr = 7;
}
static void arm1136_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,arm1136";
set_feature(&cpu->env, ARM_FEATURE_V6K);
@@ -257,24 +254,25 @@ static void arm1136_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
- cpu->isar.id_pfr0 = 0x111;
- cpu->isar.id_pfr1 = 0x1;
- cpu->isar.id_dfr0 = 0x2;
+ SET_IDREG(isar, ID_PFR0, 0x111);
+ SET_IDREG(isar, ID_PFR1, 0x1);
+ SET_IDREG(isar, ID_DFR0, 0x2);
cpu->id_afr0 = 0x3;
- cpu->isar.id_mmfr0 = 0x01130003;
- cpu->isar.id_mmfr1 = 0x10030302;
- cpu->isar.id_mmfr2 = 0x01222110;
- cpu->isar.id_isar0 = 0x00140011;
- cpu->isar.id_isar1 = 0x12002111;
- cpu->isar.id_isar2 = 0x11231111;
- cpu->isar.id_isar3 = 0x01102131;
- cpu->isar.id_isar4 = 0x141;
+ SET_IDREG(isar, ID_MMFR0, 0x01130003);
+ SET_IDREG(isar, ID_MMFR1, 0x10030302);
+ SET_IDREG(isar, ID_MMFR2, 0x01222110);
+ SET_IDREG(isar, ID_ISAR0, 0x00140011);
+ SET_IDREG(isar, ID_ISAR1, 0x12002111);
+ SET_IDREG(isar, ID_ISAR2, 0x11231111);
+ SET_IDREG(isar, ID_ISAR3, 0x01102131);
+ SET_IDREG(isar, ID_ISAR4, 0x141);
cpu->reset_auxcr = 7;
}
static void arm1176_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,arm1176";
set_feature(&cpu->env, ARM_FEATURE_V6K);
@@ -289,24 +287,25 @@ static void arm1176_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
- cpu->isar.id_pfr0 = 0x111;
- cpu->isar.id_pfr1 = 0x11;
- cpu->isar.id_dfr0 = 0x33;
+ SET_IDREG(isar, ID_PFR0, 0x111);
+ SET_IDREG(isar, ID_PFR1, 0x11);
+ SET_IDREG(isar, ID_DFR0, 0x33);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x01130003;
- cpu->isar.id_mmfr1 = 0x10030302;
- cpu->isar.id_mmfr2 = 0x01222100;
- cpu->isar.id_isar0 = 0x0140011;
- cpu->isar.id_isar1 = 0x12002111;
- cpu->isar.id_isar2 = 0x11231121;
- cpu->isar.id_isar3 = 0x01102131;
- cpu->isar.id_isar4 = 0x01141;
+ SET_IDREG(isar, ID_MMFR0, 0x01130003);
+ SET_IDREG(isar, ID_MMFR1, 0x10030302);
+ SET_IDREG(isar, ID_MMFR2, 0x01222100);
+ SET_IDREG(isar, ID_ISAR0, 0x0140011);
+ SET_IDREG(isar, ID_ISAR1, 0x12002111);
+ SET_IDREG(isar, ID_ISAR2, 0x11231121);
+ SET_IDREG(isar, ID_ISAR3, 0x01102131);
+ SET_IDREG(isar, ID_ISAR4, 0x01141);
cpu->reset_auxcr = 7;
}
static void arm11mpcore_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,arm11mpcore";
set_feature(&cpu->env, ARM_FEATURE_V6K);
@@ -318,18 +317,18 @@ static void arm11mpcore_initfn(Object *obj)
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
- cpu->isar.id_pfr0 = 0x111;
- cpu->isar.id_pfr1 = 0x1;
- cpu->isar.id_dfr0 = 0;
+ SET_IDREG(isar, ID_PFR0, 0x111);
+ SET_IDREG(isar, ID_PFR1, 0x1);
+ SET_IDREG(isar, ID_DFR0, 0);
cpu->id_afr0 = 0x2;
- cpu->isar.id_mmfr0 = 0x01100103;
- cpu->isar.id_mmfr1 = 0x10020302;
- cpu->isar.id_mmfr2 = 0x01222000;
- cpu->isar.id_isar0 = 0x00100011;
- cpu->isar.id_isar1 = 0x12002111;
- cpu->isar.id_isar2 = 0x11221011;
- cpu->isar.id_isar3 = 0x01102131;
- cpu->isar.id_isar4 = 0x141;
+ SET_IDREG(isar, ID_MMFR0, 0x01100103);
+ SET_IDREG(isar, ID_MMFR1, 0x10020302);
+ SET_IDREG(isar, ID_MMFR2, 0x01222000);
+ SET_IDREG(isar, ID_ISAR0, 0x00100011);
+ SET_IDREG(isar, ID_ISAR1, 0x12002111);
+ SET_IDREG(isar, ID_ISAR2, 0x11221011);
+ SET_IDREG(isar, ID_ISAR3, 0x01102131);
+ SET_IDREG(isar, ID_ISAR4, 0x141);
cpu->reset_auxcr = 1;
}
@@ -343,6 +342,7 @@ static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
static void cortex_a8_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a8";
set_feature(&cpu->env, ARM_FEATURE_V7);
@@ -357,19 +357,19 @@ static void cortex_a8_initfn(Object *obj)
cpu->isar.mvfr1 = 0x00011111;
cpu->ctr = 0x82048004;
cpu->reset_sctlr = 0x00c50078;
- cpu->isar.id_pfr0 = 0x1031;
- cpu->isar.id_pfr1 = 0x11;
- cpu->isar.id_dfr0 = 0x400;
+ SET_IDREG(isar, ID_PFR0, 0x1031);
+ SET_IDREG(isar, ID_PFR1, 0x11);
+ SET_IDREG(isar, ID_DFR0, 0x400);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x31100003;
- cpu->isar.id_mmfr1 = 0x20000000;
- cpu->isar.id_mmfr2 = 0x01202000;
- cpu->isar.id_mmfr3 = 0x11;
- cpu->isar.id_isar0 = 0x00101111;
- cpu->isar.id_isar1 = 0x12112111;
- cpu->isar.id_isar2 = 0x21232031;
- cpu->isar.id_isar3 = 0x11112131;
- cpu->isar.id_isar4 = 0x00111142;
+ SET_IDREG(isar, ID_MMFR0, 0x31100003);
+ SET_IDREG(isar, ID_MMFR1, 0x20000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01202000);
+ SET_IDREG(isar, ID_MMFR3, 0x11);
+ SET_IDREG(isar, ID_ISAR0, 0x00101111);
+ SET_IDREG(isar, ID_ISAR1, 0x12112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232031);
+ SET_IDREG(isar, ID_ISAR3, 0x11112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00111142);
cpu->isar.dbgdidr = 0x15141000;
cpu->clidr = (1 << 27) | (2 << 24) | 3;
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
@@ -412,6 +412,7 @@ static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
static void cortex_a9_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a9";
set_feature(&cpu->env, ARM_FEATURE_V7);
@@ -432,19 +433,19 @@ static void cortex_a9_initfn(Object *obj)
cpu->isar.mvfr1 = 0x01111111;
cpu->ctr = 0x80038003;
cpu->reset_sctlr = 0x00c50078;
- cpu->isar.id_pfr0 = 0x1031;
- cpu->isar.id_pfr1 = 0x11;
- cpu->isar.id_dfr0 = 0x000;
+ SET_IDREG(isar, ID_PFR0, 0x1031);
+ SET_IDREG(isar, ID_PFR1, 0x11);
+ SET_IDREG(isar, ID_DFR0, 0x000);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x00100103;
- cpu->isar.id_mmfr1 = 0x20000000;
- cpu->isar.id_mmfr2 = 0x01230000;
- cpu->isar.id_mmfr3 = 0x00002111;
- cpu->isar.id_isar0 = 0x00101111;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232041;
- cpu->isar.id_isar3 = 0x11112131;
- cpu->isar.id_isar4 = 0x00111142;
+ SET_IDREG(isar, ID_MMFR0, 0x00100103);
+ SET_IDREG(isar, ID_MMFR1, 0x20000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01230000);
+ SET_IDREG(isar, ID_MMFR3, 0x00002111);
+ SET_IDREG(isar, ID_ISAR0, 0x00101111);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232041);
+ SET_IDREG(isar, ID_ISAR3, 0x11112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00111142);
cpu->isar.dbgdidr = 0x35141000;
cpu->clidr = (1 << 27) | (1 << 24) | 3;
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
@@ -479,6 +480,7 @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
static void cortex_a7_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a7";
set_feature(&cpu->env, ARM_FEATURE_V7VE);
@@ -497,23 +499,23 @@ static void cortex_a7_initfn(Object *obj)
cpu->isar.mvfr1 = 0x11111111;
cpu->ctr = 0x84448003;
cpu->reset_sctlr = 0x00c50078;
- cpu->isar.id_pfr0 = 0x00001131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_dfr0 = 0x02010555;
+ SET_IDREG(isar, ID_PFR0, 0x00001131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_DFR0, 0x02010555);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10101105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01240000;
- cpu->isar.id_mmfr3 = 0x02102211;
+ SET_IDREG(isar, ID_MMFR0, 0x10101105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01240000);
+ SET_IDREG(isar, ID_MMFR3, 0x02102211);
/*
* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
* table 4-41 gives 0x02101110, which includes the arm div insns.
*/
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232041;
- cpu->isar.id_isar3 = 0x11112131;
- cpu->isar.id_isar4 = 0x10011142;
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232041);
+ SET_IDREG(isar, ID_ISAR3, 0x11112131);
+ SET_IDREG(isar, ID_ISAR4, 0x10011142);
cpu->isar.dbgdidr = 0x3515f005;
cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x1;
@@ -528,6 +530,7 @@ static void cortex_a7_initfn(Object *obj)
static void cortex_a15_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a15";
set_feature(&cpu->env, ARM_FEATURE_V7VE);
@@ -548,19 +551,19 @@ static void cortex_a15_initfn(Object *obj)
cpu->isar.mvfr1 = 0x11111111;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50078;
- cpu->isar.id_pfr0 = 0x00001131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_dfr0 = 0x02010555;
+ SET_IDREG(isar, ID_PFR0, 0x00001131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_DFR0, 0x02010555);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x20000000;
- cpu->isar.id_mmfr2 = 0x01240000;
- cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232041;
- cpu->isar.id_isar3 = 0x11112131;
- cpu->isar.id_isar4 = 0x10011142;
+ SET_IDREG(isar, ID_MMFR0, 0x10201105);
+ SET_IDREG(isar, ID_MMFR1, 0x20000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01240000);
+ SET_IDREG(isar, ID_MMFR3, 0x02102211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232041);
+ SET_IDREG(isar, ID_ISAR3, 0x11112131);
+ SET_IDREG(isar, ID_ISAR4, 0x10011142);
cpu->isar.dbgdidr = 0x3515f021;
cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x0;
@@ -585,27 +588,28 @@ static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
static void cortex_r5_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_V7MP);
set_feature(&cpu->env, ARM_FEATURE_PMSA);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->midr = 0x411fc153; /* r1p3 */
- cpu->isar.id_pfr0 = 0x0131;
- cpu->isar.id_pfr1 = 0x001;
- cpu->isar.id_dfr0 = 0x010400;
+ SET_IDREG(isar, ID_PFR0, 0x0131);
+ SET_IDREG(isar, ID_PFR1, 0x001);
+ SET_IDREG(isar, ID_DFR0, 0x010400);
cpu->id_afr0 = 0x0;
- cpu->isar.id_mmfr0 = 0x0210030;
- cpu->isar.id_mmfr1 = 0x00000000;
- cpu->isar.id_mmfr2 = 0x01200000;
- cpu->isar.id_mmfr3 = 0x0211;
- cpu->isar.id_isar0 = 0x02101111;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232141;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x0010142;
- cpu->isar.id_isar5 = 0x0;
- cpu->isar.id_isar6 = 0x0;
+ SET_IDREG(isar, ID_MMFR0, 0x0210030);
+ SET_IDREG(isar, ID_MMFR1, 0x00000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01200000);
+ SET_IDREG(isar, ID_MMFR3, 0x0211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101111);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232141);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x0010142);
+ SET_IDREG(isar, ID_ISAR5, 0x0);
+ SET_IDREG(isar, ID_ISAR6, 0x0);
cpu->mp_is_up = true;
cpu->pmsav7_dregion = 16;
cpu->isar.reset_pmcr_el0 = 0x41151800;
@@ -720,6 +724,7 @@ static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
static void cortex_r52_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_EL2);
@@ -737,21 +742,21 @@ static void cortex_r52_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8144c004;
cpu->reset_sctlr = 0x30c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x10111001;
- cpu->isar.id_dfr0 = 0x03010006;
+ SET_IDREG(isar, ID_PFR0, 0x00000131);
+ SET_IDREG(isar, ID_PFR1, 0x10111001);
+ SET_IDREG(isar, ID_DFR0, 0x03010006);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x00211040;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01200000;
- cpu->isar.id_mmfr3 = 0xf0102211;
- cpu->isar.id_mmfr4 = 0x00000010;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232142;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x00010001;
+ SET_IDREG(isar, ID_MMFR0, 0x00211040);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01200000);
+ SET_IDREG(isar, ID_MMFR3, 0xf0102211);
+ SET_IDREG(isar, ID_MMFR4, 0x00000010);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232142);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00010142);
+ SET_IDREG(isar, ID_ISAR5, 0x00010001);
cpu->isar.dbgdidr = 0x77168000;
cpu->clidr = (1 << 27) | (1 << 24) | 0x3;
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
@@ -949,6 +954,7 @@ static void pxa270c5_initfn(Object *obj)
static void arm_max_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
/* aarch64_a57_initfn, advertising none of the aarch64 features */
cpu->dtb_compatible = "arm,cortex-a57";
@@ -968,21 +974,21 @@ static void arm_max_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(isar, ID_PFR0, 0x00000131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10101105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_isar6 = 0;
+ SET_IDREG(isar, ID_MMFR0, 0x10101105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02102211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00011142);
+ SET_IDREG(isar, ID_ISAR5, 0x00011121);
+ SET_IDREG(isar, ID_ISAR6, 0);
cpu->isar.reset_pmcr_el0 = 0x41013000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 5d8ed27..937f29e2 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -32,6 +32,7 @@
static void aarch64_a35_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a35";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -48,28 +49,28 @@ static void aarch64_a35_initfn(Object *obj)
cpu->midr = 0x411fd040;
cpu->revidr = 0;
cpu->ctr = 0x84448004;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(isar, ID_PFR0, 0x00000131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->isar.id_aa64pfr1 = 0;
- cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64dfr1 = 0;
- cpu->isar.id_aa64isar0 = 0x00011120;
- cpu->isar.id_aa64isar1 = 0;
- cpu->isar.id_aa64mmfr0 = 0x00101122;
- cpu->isar.id_aa64mmfr1 = 0;
+ SET_IDREG(isar, ID_MMFR0, 0x10201105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02102211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00011142);
+ SET_IDREG(isar, ID_ISAR5, 0x00011121);
+ SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
+ SET_IDREG(isar, ID_AA64PFR1, 0);
+ SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
+ SET_IDREG(isar, ID_AA64DFR1, 0);
+ SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
+ SET_IDREG(isar, ID_AA64ISAR1, 0);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x00101122);
+ SET_IDREG(isar, ID_AA64MMFR1, 0);
cpu->clidr = 0x0a200023;
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)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
- t = cpu->isar.id_aa64pfr0;
- t = FIELD_DP64(t, ID_AA64PFR0, RME, value);
- cpu->isar.id_aa64pfr0 = t;
+ FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR0, RME, value);
}
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)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a55";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -220,31 +219,31 @@ static void aarch64_a55_initfn(Object *obj)
cpu->clidr = 0x82000023;
cpu->ctr = 0x84448004; /* L1Ip = VIPT */
cpu->dcz_blocksize = 4; /* 64 bytes */
- cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
- cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
- cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
- cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
- cpu->isar.id_aa64pfr0 = 0x0000000010112222ull;
- cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
+ SET_IDREG(isar, ID_AA64DFR0, 0x0000000010305408ull);
+ SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull);
+ SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101122ull);
+ SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011ull);
+ SET_IDREG(isar, ID_AA64PFR0, 0x0000000010112222ull);
+ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_dfr0 = 0x04010088;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x01011121;
- cpu->isar.id_isar6 = 0x00000010;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_mmfr4 = 0x00021110;
- cpu->isar.id_pfr0 = 0x10010131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(isar, ID_DFR0, 0x04010088);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00011142);
+ SET_IDREG(isar, ID_ISAR5, 0x01011121);
+ SET_IDREG(isar, ID_ISAR6, 0x00000010);
+ SET_IDREG(isar, ID_MMFR0, 0x10201105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02122211);
+ SET_IDREG(isar, ID_MMFR4, 0x00021110);
+ SET_IDREG(isar, ID_PFR0, 0x10010131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x412FD050; /* r2p0 */
cpu->revidr = 0;
@@ -276,6 +275,7 @@ static void aarch64_a55_initfn(Object *obj)
static void aarch64_a72_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a72";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -295,24 +295,24 @@ static void aarch64_a72_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(isar, ID_PFR0, 0x00000131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02102211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64isar0 = 0x00011120;
- cpu->isar.id_aa64mmfr0 = 0x00001124;
+ SET_IDREG(isar, ID_MMFR0, 0x10201105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02102211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00011142);
+ SET_IDREG(isar, ID_ISAR5, 0x00011121);
+ SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
+ SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
+ SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x00001124);
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x2;
@@ -335,6 +335,7 @@ static void aarch64_a72_initfn(Object *obj)
static void aarch64_a76_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a76";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -351,31 +352,31 @@ static void aarch64_a76_initfn(Object *obj)
cpu->clidr = 0x82000023;
cpu->ctr = 0x8444C004;
cpu->dcz_blocksize = 4;
- cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
- cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
- cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
- cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
- cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
+ SET_IDREG(isar, ID_AA64DFR0, 0x0000000010305408ull),
+ SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull);
+ SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101122ull);
+ SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011ull);
+ SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
+ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_dfr0 = 0x04010088;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x01011121;
- cpu->isar.id_isar6 = 0x00000010;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_mmfr4 = 0x00021110;
- cpu->isar.id_pfr0 = 0x10010131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(isar, ID_DFR0, 0x04010088);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00010142);
+ SET_IDREG(isar, ID_ISAR5, 0x01011121);
+ SET_IDREG(isar, ID_ISAR6, 0x00000010);
+ SET_IDREG(isar, ID_MMFR0, 0x10201105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02122211);
+ SET_IDREG(isar, ID_MMFR4, 0x00021110);
+ SET_IDREG(isar, ID_PFR0, 0x10010131);
+ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
+ SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x414fd0b1; /* r4p1 */
cpu->revidr = 0;
@@ -408,6 +409,7 @@ static void aarch64_a76_initfn(Object *obj)
static void aarch64_a64fx_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,a64fx";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -422,18 +424,18 @@ static void aarch64_a64fx_initfn(Object *obj)
cpu->revidr = 0x00000000;
cpu->ctr = 0x86668006;
cpu->reset_sctlr = 0x30000180;
- cpu->isar.id_aa64pfr0 = 0x0000000101111111; /* No RAS Extensions */
- cpu->isar.id_aa64pfr1 = 0x0000000000000000;
- cpu->isar.id_aa64dfr0 = 0x0000000010305408;
- cpu->isar.id_aa64dfr1 = 0x0000000000000000;
+ SET_IDREG(isar, ID_AA64PFR0, 0x0000000101111111); /* No RAS Extensions */
+ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000000);
+ SET_IDREG(isar, ID_AA64DFR0, 0x0000000010305408),
+ SET_IDREG(isar, ID_AA64DFR1, 0x0000000000000000),
cpu->id_aa64afr0 = 0x0000000000000000;
cpu->id_aa64afr1 = 0x0000000000000000;
- cpu->isar.id_aa64mmfr0 = 0x0000000000001122;
- cpu->isar.id_aa64mmfr1 = 0x0000000011212100;
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011;
- cpu->isar.id_aa64isar0 = 0x0000000010211120;
- cpu->isar.id_aa64isar1 = 0x0000000000010001;
- cpu->isar.id_aa64zfr0 = 0x0000000000000000;
+ SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000001122);
+ SET_IDREG(isar, ID_AA64MMFR1, 0x0000000011212100);
+ SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011);
+ SET_IDREG(isar, ID_AA64ISAR0, 0x0000000010211120);
+ SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000010001);
+ SET_IDREG(isar, ID_AA64ZFR0, 0x0000000000000000);
cpu->clidr = 0x0000000080000023;
/* 64KB L1 dcache */
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)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,neoverse-n1";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -597,31 +600,31 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
cpu->clidr = 0x82000023;
cpu->ctr = 0x8444c004;
cpu->dcz_blocksize = 4;
- cpu->isar.id_aa64dfr0 = 0x0000000110305408ull;
- cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
- cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
- cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
- cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
+ SET_IDREG(isar, ID_AA64DFR0, 0x0000000110305408ull);
+ SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull);
+ SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101125ull);
+ SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011ull);
+ SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */
+ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_dfr0 = 0x04010088;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x01011121;
- cpu->isar.id_isar6 = 0x00000010;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_mmfr4 = 0x00021110;
- cpu->isar.id_pfr0 = 0x10010131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(isar, ID_DFR0, 0x04010088);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00010142);
+ SET_IDREG(isar, ID_ISAR5, 0x01011121);
+ SET_IDREG(isar, ID_ISAR6, 0x00000010);
+ SET_IDREG(isar, ID_MMFR0, 0x10201105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02122211);
+ SET_IDREG(isar, ID_MMFR4, 0x00021110);
+ SET_IDREG(isar, ID_PFR0, 0x10010131);
+ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
+ SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x414fd0c1; /* r4p1 */
cpu->revidr = 0;
@@ -656,6 +659,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj)
static void aarch64_neoverse_v1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,neoverse-v1";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -674,32 +678,32 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->dcz_blocksize = 4;
cpu->id_aa64afr0 = 0x00000000;
cpu->id_aa64afr1 = 0x00000000;
- cpu->isar.id_aa64dfr0 = 0x000001f210305519ull;
- cpu->isar.id_aa64dfr1 = 0x00000000;
- cpu->isar.id_aa64isar0 = 0x1011111110212120ull; /* with FEAT_RNG */
- cpu->isar.id_aa64isar1 = 0x0011100001211032ull;
- cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull;
- cpu->isar.id_aa64pfr0 = 0x1101110120111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
+ SET_IDREG(isar, ID_AA64DFR0, 0x000001f210305519ull),
+ SET_IDREG(isar, ID_AA64DFR1, 0x00000000),
+ SET_IDREG(isar, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */
+ SET_IDREG(isar, ID_AA64ISAR1, 0x0011000001211032ull);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101125ull);
+ SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull),
+ SET_IDREG(isar, ID_AA64MMFR2, 0x0220011102101011ull),
+ SET_IDREG(isar, ID_AA64PFR0, 0x1101110120111112ull); /* GIC filled in later */
+ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull);
cpu->id_afr0 = 0x00000000;
- cpu->isar.id_dfr0 = 0x15011099;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x11011121;
- cpu->isar.id_isar6 = 0x01100111;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_mmfr4 = 0x01021110;
- cpu->isar.id_pfr0 = 0x21110131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
- cpu->isar.id_pfr2 = 0x00000011;
+ SET_IDREG(isar, ID_DFR0, 0x15011099);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00010142);
+ SET_IDREG(isar, ID_ISAR5, 0x11011121);
+ SET_IDREG(isar, ID_ISAR6, 0x01100111);
+ SET_IDREG(isar, ID_MMFR0, 0x10201105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02122211);
+ SET_IDREG(isar, ID_MMFR4, 0x01021110);
+ SET_IDREG(isar, ID_PFR0, 0x21110131);
+ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
+ SET_IDREG(isar, ID_PFR2, 0x00000011);
cpu->midr = 0x411FD402; /* r1p2 */
cpu->revidr = 0;
@@ -735,7 +739,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
/* 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 */
| (1 << 1); /* 256bit */
@@ -882,6 +886,7 @@ static const ARMCPRegInfo cortex_a710_cp_reginfo[] = {
static void aarch64_a710_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a710";
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 */
cpu->midr = 0x412FD471; /* r2p1 */
cpu->revidr = 0;
- cpu->isar.id_pfr0 = 0x21110131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
- cpu->isar.id_dfr0 = 0x16011099;
+ SET_IDREG(isar, ID_PFR0, 0x21110131);
+ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
+ SET_IDREG(isar, ID_DFR0, 0x16011099);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x11011121; /* with Crypto */
- cpu->isar.id_mmfr4 = 0x21021110;
- cpu->isar.id_isar6 = 0x01111111;
+ SET_IDREG(isar, ID_MMFR0, 0x10201105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02122211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00010142);
+ SET_IDREG(isar, ID_ISAR5, 0x11011121); /* with Crypto */
+ SET_IDREG(isar, ID_MMFR4, 0x21021110);
+ SET_IDREG(isar, ID_ISAR6, 0x01111111);
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043;
- cpu->isar.id_pfr2 = 0x00000011;
- cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
- cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */
- cpu->isar.id_aa64dfr0 = 0x000011f010305619ull;
- cpu->isar.id_aa64dfr1 = 0;
+ SET_IDREG(isar, ID_PFR2, 0x00000011);
+ SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
+ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull);
+ SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
+ SET_IDREG(isar, ID_AA64DFR0, 0x000011f010305619ull);
+ SET_IDREG(isar, ID_AA64DFR1, 0);
cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0;
- cpu->isar.id_aa64isar0 = 0x0221111110212120ull; /* with Crypto */
- cpu->isar.id_aa64isar1 = 0x0010111101211052ull;
- cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x1221011110101011ull;
+ SET_IDREG(isar, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */
+ SET_IDREG(isar, ID_AA64ISAR1, 0x0010111101211052ull);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x0000022200101122ull);
+ SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(isar, ID_AA64MMFR2, 0x1221011110101011ull);
cpu->clidr = 0x0000001482000023ull;
cpu->gm_blocksize = 4;
cpu->ctr = 0x000000049444c004ull;
@@ -983,6 +988,7 @@ static const ARMCPRegInfo neoverse_n2_cp_reginfo[] = {
static void aarch64_neoverse_n2_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,neoverse-n2";
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 */
cpu->midr = 0x410FD493; /* r0p3 */
cpu->revidr = 0;
- cpu->isar.id_pfr0 = 0x21110131;
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
- cpu->isar.id_dfr0 = 0x16011099;
+ SET_IDREG(isar, ID_PFR0, 0x21110131);
+ SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */
+ SET_IDREG(isar, ID_DFR0, 0x16011099);
cpu->id_afr0 = 0;
- cpu->isar.id_mmfr0 = 0x10201105;
- cpu->isar.id_mmfr1 = 0x40000000;
- cpu->isar.id_mmfr2 = 0x01260000;
- cpu->isar.id_mmfr3 = 0x02122211;
- cpu->isar.id_isar0 = 0x02101110;
- cpu->isar.id_isar1 = 0x13112111;
- cpu->isar.id_isar2 = 0x21232042;
- cpu->isar.id_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00010142;
- cpu->isar.id_isar5 = 0x11011121; /* with Crypto */
- cpu->isar.id_mmfr4 = 0x01021110;
- cpu->isar.id_isar6 = 0x01111111;
+ SET_IDREG(isar, ID_MMFR0, 0x10201105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02122211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00010142);
+ SET_IDREG(isar, ID_ISAR5, 0x11011121); /* with Crypto */
+ SET_IDREG(isar, ID_MMFR4, 0x01021110);
+ SET_IDREG(isar, ID_ISAR6, 0x01111111);
cpu->isar.mvfr0 = 0x10110222;
cpu->isar.mvfr1 = 0x13211111;
cpu->isar.mvfr2 = 0x00000043;
- cpu->isar.id_pfr2 = 0x00000011;
- cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
- cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
- cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */
- cpu->isar.id_aa64dfr0 = 0x000011f210305619ull;
- cpu->isar.id_aa64dfr1 = 0;
+ SET_IDREG(isar, ID_PFR2, 0x00000011);
+ SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */
+ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull);
+ SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */
+ SET_IDREG(isar, ID_AA64DFR0, 0x000011f210305619ull);
+ SET_IDREG(isar, ID_AA64DFR1, 0);
cpu->id_aa64afr0 = 0;
cpu->id_aa64afr1 = 0;
- cpu->isar.id_aa64isar0 = 0x1221111110212120ull; /* with Crypto and FEAT_RNG */
- cpu->isar.id_aa64isar1 = 0x0011111101211052ull;
- cpu->isar.id_aa64mmfr0 = 0x0000022200101125ull;
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
- cpu->isar.id_aa64mmfr2 = 0x1221011112101011ull;
+ SET_IDREG(isar, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */
+ SET_IDREG(isar, ID_AA64ISAR1, 0x0011111101211052ull);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x0000022200101125ull);
+ SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull);
+ SET_IDREG(isar, ID_AA64MMFR2, 0x1221011112101011ull);
cpu->clidr = 0x0000001482000023ull;
cpu->gm_blocksize = 4;
cpu->ctr = 0x00000004b444c004ull;
@@ -1083,6 +1089,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
void aarch64_max_tcg_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
uint64_t t;
uint32_t u;
@@ -1133,7 +1140,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = FIELD_DP64(t, CTR_EL0, DIC, 1);
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, SHA1, 1); /* FEAT_SHA1 */
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, TLB, 2); /* FEAT_TLBIRANGE */
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, APA, PauthFeat_FPACCOMBINED);
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, I8MM, 1); /* FEAT_I8MM */
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, MOPS, 1); /* FEAT_MOPS */
t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */
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, ADVSIMD, 1); /* FEAT_FP16 */
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, CSV2, 3); /* FEAT_CSV2_3 */
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, 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, CSV2_FRAC, 0); /* FEAT_CSV2_3 */
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, TGRAN16, 1); /* 16k pages 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, FGT, 1); /* FEAT_FGT */
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, VMIDBITS, 2); /* FEAT_VMID16 */
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, TIDCP1, 1); /* FEAT_TIDCP1 */
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, UAO, 1); /* FEAT_UAO */
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, EVT, 2); /* FEAT_EVT */
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;
- t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
- cpu->isar.id_aa64mmfr3 = t;
+ FIELD_DP64_IDREG(isar, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
- 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, AES, 2); /* FEAT_SVE_PMULL128 */
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, F32MM, 1); /* FEAT_F32MM */
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, PMUVER, 6); /* FEAT_PMUv3p5 */
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, B16F32, 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, I16I64, 0xf); /* FEAT_SME_I16I64 */
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. */
aa32_max_features(cpu);
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index ac80f57..815225b 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -433,12 +433,6 @@ static void gen_rebuild_hflags(DisasContext *s)
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)
{
gen_a64_update_pc(s, 0);
@@ -1816,6 +1810,10 @@ static bool trans_RETA(DisasContext *s, arg_reta *a)
{
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);
gen_a64_set_pc(s, dst);
s->base.is_jmp = DISAS_JUMP;
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index 9962f43..f7d6d8c 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -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));
gen_helper_exception_internal(tcg_env, tcg_constant_i32(excp));
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 1bfdb0f..0004a97 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -347,6 +347,7 @@ void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
void arm_gen_test_cc(int cc, TCGLabel *label);
MemOp pow2_align(unsigned i);
void unallocated_encoding(DisasContext *s);
+void gen_exception_internal(int excp);
void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp,
uint32_t syn, uint32_t target_el);
void gen_exception_insn(DisasContext *s, target_long pc_diff,
diff --git a/tests/data/acpi/aarch64/virt/APIC.its_off b/tests/data/acpi/aarch64/virt/APIC.its_off
new file mode 100644
index 0000000..6130cb7
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/APIC.its_off
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/IORT.its_off b/tests/data/acpi/aarch64/virt/IORT.its_off
new file mode 100644
index 0000000..c10da4e
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/IORT.its_off
Binary files differ
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index e9f19d5..8515856 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -13,6 +13,7 @@ endif
test_timeouts = {
'aarch64_aspeed_ast2700' : 600,
'aarch64_aspeed_ast2700fc' : 600,
+ 'aarch64_device_passthrough' : 720,
'aarch64_imx8mp_evk' : 240,
'aarch64_raspi4' : 480,
'aarch64_reverse_debug' : 180,
@@ -83,6 +84,7 @@ tests_aarch64_system_quick = [
tests_aarch64_system_thorough = [
'aarch64_aspeed_ast2700',
'aarch64_aspeed_ast2700fc',
+ 'aarch64_device_passthrough',
'aarch64_imx8mp_evk',
'aarch64_raspi3',
'aarch64_raspi4',
diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py
index 50c401b..2082c6f 100644
--- a/tests/functional/qemu_test/testcase.py
+++ b/tests/functional/qemu_test/testcase.py
@@ -23,7 +23,7 @@ import unittest
import uuid
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 .asset import Asset
@@ -317,7 +317,9 @@ class QemuSystemTest(QemuBaseTest):
:type accelerator: str
"""
checker = {'tcg': tcg_available,
- 'kvm': kvm_available}.get(accelerator)
+ 'kvm': kvm_available,
+ 'hvf': hvf_available,
+ }.get(accelerator)
if checker is None:
self.skipTest("Don't know how to check for the presence "
"of accelerator %s" % accelerator)
diff --git a/tests/functional/test_aarch64_device_passthrough.py b/tests/functional/test_aarch64_device_passthrough.py
new file mode 100755
index 0000000..1f3f158
--- /dev/null
+++ b/tests/functional/test_aarch64_device_passthrough.py
@@ -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()
diff --git a/tests/functional/test_aarch64_imx8mp_evk.py b/tests/functional/test_aarch64_imx8mp_evk.py
index 638bf9e..99ddcde 100755
--- a/tests/functional/test_aarch64_imx8mp_evk.py
+++ b/tests/functional/test_aarch64_imx8mp_evk.py
@@ -49,6 +49,7 @@ class Imx8mpEvkMachine(LinuxKernelTest):
self.DTB_OFFSET, self.DTB_SIZE)
def test_aarch64_imx8mp_evk_usdhc(self):
+ self.require_accelerator("tcg")
self.set_machine('imx8mp-evk')
self.vm.set_console(console_index=1)
self.vm.add_args('-m', '2G',
diff --git a/tests/functional/test_aarch64_sbsaref.py b/tests/functional/test_aarch64_sbsaref.py
index e6a55ae..d3402f5 100755
--- a/tests/functional/test_aarch64_sbsaref.py
+++ b/tests/functional/test_aarch64_sbsaref.py
@@ -40,8 +40,6 @@ def fetch_firmware(test):
with open(path, "ab+") as fd:
fd.truncate(256 << 20) # Expand volumes to 256MiB
- test.set_machine('sbsa-ref')
- test.vm.set_console()
test.vm.add_args(
"-drive", f"if=pflash,file={fs0_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):
+ self.set_machine('sbsa-ref')
+
fetch_firmware(self)
+ self.vm.set_console()
self.vm.add_args('-cpu', 'cortex-a57')
self.vm.launch()
diff --git a/tests/functional/test_aarch64_sbsaref_alpine.py b/tests/functional/test_aarch64_sbsaref_alpine.py
index 6108ec6..8776999 100755
--- a/tests/functional/test_aarch64_sbsaref_alpine.py
+++ b/tests/functional/test_aarch64_sbsaref_alpine.py
@@ -26,8 +26,9 @@ class Aarch64SbsarefAlpine(QemuSystemTest):
# We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots
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()
self.vm.set_console()
diff --git a/tests/functional/test_aarch64_sbsaref_freebsd.py b/tests/functional/test_aarch64_sbsaref_freebsd.py
index 26dfc58..3cddc08 100755
--- a/tests/functional/test_aarch64_sbsaref_freebsd.py
+++ b/tests/functional/test_aarch64_sbsaref_freebsd.py
@@ -26,8 +26,9 @@ class Aarch64SbsarefFreeBSD(QemuSystemTest):
# We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots
def boot_freebsd14(self, cpu=None):
- fetch_firmware(self)
+ self.set_machine('sbsa-ref')
+ fetch_firmware(self)
img_path = self.ASSET_FREEBSD_ISO.fetch()
self.vm.set_console()
diff --git a/tests/functional/test_aarch64_smmu.py b/tests/functional/test_aarch64_smmu.py
index c65d0f2..e0f4a92 100755
--- a/tests/functional/test_aarch64_smmu.py
+++ b/tests/functional/test_aarch64_smmu.py
@@ -17,7 +17,7 @@ import time
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import BUILD_DIR
-from qemu.utils import kvm_available
+from qemu.utils import kvm_available, hvf_available
class SMMU(LinuxKernelTest):
@@ -45,11 +45,17 @@ class SMMU(LinuxKernelTest):
self.vm.add_args('-device', 'virtio-net,netdev=n1' + self.IOMMU_ADDON)
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.set_machine("virt")
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("-machine", "iommu=smmuv3")
self.vm.add_args("-d", "guest_errors")
diff --git a/tests/functional/test_aarch64_xen.py b/tests/functional/test_aarch64_xen.py
index 3399042..261d796 100755
--- a/tests/functional/test_aarch64_xen.py
+++ b/tests/functional/test_aarch64_xen.py
@@ -33,6 +33,7 @@ class BootXen(LinuxKernelTest):
"""
Launch Xen with a dom0 guest kernel
"""
+ self.require_accelerator("tcg") # virtualization=on
self.set_machine('virt')
self.cpu = "cortex-a57"
self.kernel_path = self.ASSET_KERNEL.fetch()
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 0b2bdf9..4dbc07e 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -2146,6 +2146,25 @@ static void test_acpi_aarch64_virt_tcg_topology(void)
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)
{
test_data data = {
@@ -2577,6 +2596,8 @@ int main(int argc, char *argv[])
test_acpi_aarch64_virt_tcg_acpi_hmat);
qtest_add_func("acpi/virt/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",
test_acpi_aarch64_virt_tcg_numamem);
qtest_add_func("acpi/virt/memhp", test_acpi_aarch64_virt_tcg_memhp);