mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-12-11 16:00:50 -07:00
target-arm queue:
* MAINTAINERS update for arm hvf * target/arm: Make RETA[AB] UNDEF when pauth is not implemented * target/arm: Refactoring of ID register value storage * target/arm: Various refactoring/cleanup patches * virt: Don't show an ITS in ACPI tables when no ITS is present * tests/functional: test device passthrough on aarch64 * tests/functional: Expand Aarch64 SMMU tests to run on HVF accelerator -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmhkE/IZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vNeD/9ZcHiqTxLyuurYntf63VLP 55NRozF0By7f83dOja5r+NWeGSPqhDBO05PpBVArt+giE2dkkVCoJ5stNrls5ACl oi5glXQL/bW+A3nN+WmcD+s2RMVHn5jZ6f5ChRsFo2bWYl0rtrR1raC/wl415ag/ MMRjbXj6sabEITY7794KBN4M5RDVS+Zcu7dzPZecsttbxLIGLBvvJ0bFSmh91tH4 Tyy889v2GHou1BxSWVcSWNCTQ9jLYV7a+VHHs4uTlsBc3Pw7LXS4DcPhEdfZ3+gy RaZUu1Eq213qd3r75FqFgR4mrY/nIm/CXd+mWjC5LsLOX0BYQKlAFiDH599AeZV3 f1Wa0+POJDSKLDux+hPu3/2eeggI4d5XKAW9dgCYKicCtfhFEKXmTtaJtZyW+vTR Vpl8SDVoljDd3q/045CXzOdM5N+5xj2WNNNKYYW4stHJrAIxa88pBeK2bqzT372x V8FENVzK+7owTibi63XEshgdVlBcCB9Xpp+9p4TEbMZcd8EEUVDFC5F6iF9hNUYT s1cqphTVscWDXxkTSok6POHOIvotRdT7EcIVQ9VfJxVREGrtWkioDii1O+olMhyF uoeoxkFE1Jih4LQz937pqCCgP0PPd9DMtXdX/WeiAcZSDEHlO8gbRiIIyf11qL2i aiMIF0rHY9PvxIisnukkLQ== =x5Ur -----END PGP SIGNATURE----- Merge tag 'pull-target-arm-20250701-1' of https://gitlab.com/pm215/qemu into staging target-arm queue: * MAINTAINERS update for arm hvf * target/arm: Make RETA[AB] UNDEF when pauth is not implemented * target/arm: Refactoring of ID register value storage * target/arm: Various refactoring/cleanup patches * virt: Don't show an ITS in ACPI tables when no ITS is present * tests/functional: test device passthrough on aarch64 * tests/functional: Expand Aarch64 SMMU tests to run on HVF accelerator # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmhkE/IZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vNeD/9ZcHiqTxLyuurYntf63VLP # 55NRozF0By7f83dOja5r+NWeGSPqhDBO05PpBVArt+giE2dkkVCoJ5stNrls5ACl # oi5glXQL/bW+A3nN+WmcD+s2RMVHn5jZ6f5ChRsFo2bWYl0rtrR1raC/wl415ag/ # MMRjbXj6sabEITY7794KBN4M5RDVS+Zcu7dzPZecsttbxLIGLBvvJ0bFSmh91tH4 # Tyy889v2GHou1BxSWVcSWNCTQ9jLYV7a+VHHs4uTlsBc3Pw7LXS4DcPhEdfZ3+gy # RaZUu1Eq213qd3r75FqFgR4mrY/nIm/CXd+mWjC5LsLOX0BYQKlAFiDH599AeZV3 # f1Wa0+POJDSKLDux+hPu3/2eeggI4d5XKAW9dgCYKicCtfhFEKXmTtaJtZyW+vTR # Vpl8SDVoljDd3q/045CXzOdM5N+5xj2WNNNKYYW4stHJrAIxa88pBeK2bqzT372x # V8FENVzK+7owTibi63XEshgdVlBcCB9Xpp+9p4TEbMZcd8EEUVDFC5F6iF9hNUYT # s1cqphTVscWDXxkTSok6POHOIvotRdT7EcIVQ9VfJxVREGrtWkioDii1O+olMhyF # uoeoxkFE1Jih4LQz937pqCCgP0PPd9DMtXdX/WeiAcZSDEHlO8gbRiIIyf11qL2i # aiMIF0rHY9PvxIisnukkLQ== # =x5Ur # -----END PGP SIGNATURE----- # gpg: Signature made Tue 01 Jul 2025 12:59:30 EDT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [full] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20250701-1' of https://gitlab.com/pm215/qemu: (43 commits) tests/functional: test device passthrough on aarch64 tests/functional: Expand Aarch64 SMMU tests to run on HVF accelerator tests/functional: Add hvf_available() helper tests/functional: Require TCG to run Aarch64 imx8mp-evk test tests/functional: Restrict nested Aarch64 Xen test to TCG tests/functional: Set sbsa-ref machine type in each test function hw/arm/sbsa-ref: Tidy up use of RAMLIMIT_GB definition hw/arm/virt: Rename cpu_post_init() -> post_cpus_gic_realized() hw/arm/virt: Make EL2 accelerator check an accept-list hw/arm/virt: Make EL3-guest accel check an accept-list target/arm: Restrict system register properties to system binary target/arm/hvf: Pass @target_el argument to hvf_raise_exception() target/arm: Correct KVM & HVF dtb_compatible value target/arm/hvf: Log $pc in hvf_unknown_hvc() trace event accel/hvf: Trace VM memory mapping target/arm/hvf: Trace hv_vcpu_run() failures target/arm/hvf: Directly re-lock BQL after hv_vcpu_run() target/arm: Unify gen_exception_internal() target/arm: Reduce arm_cpu_post_init() declaration scope target/arm: Remove arm_handle_psci_call() stub ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
7698afc42b
42 changed files with 1432 additions and 1057 deletions
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
7
accel/hvf/trace-events
Normal file
7
accel/hvf/trace-events
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# See docs/devel/tracing.rst for syntax documentation.
|
||||
|
||||
# hvf-accel-ops.c
|
||||
hvf_vm_map(uint64_t paddr, uint64_t size, void *vaddr, uint8_t flags, const char r, const char w, const char e) "paddr:0x%016"PRIx64" size:0x%08"PRIx64" vaddr:%p flags:0x%02x/%c%c%c"
|
||||
hvf_vm_unmap(uint64_t paddr, uint64_t size) "paddr:0x%016"PRIx64" size:0x%08"PRIx64
|
||||
2
accel/hvf/trace.h
Normal file
2
accel/hvf/trace.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
#include "trace/trace-accel_hvf.h"
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -266,40 +266,19 @@ static int iort_idmap_compare(gconstpointer a, gconstpointer b)
|
|||
return idmap_a->input_base - idmap_b->input_base;
|
||||
}
|
||||
|
||||
/*
|
||||
* Input Output Remapping Table (IORT)
|
||||
* Conforms to "IO Remapping Table System Software on ARM Platforms",
|
||||
* Document number: ARM DEN 0049E.b, Feb 2021
|
||||
*/
|
||||
static void
|
||||
build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
/* 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)
|
||||
{
|
||||
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));
|
||||
|
||||
AcpiTable table = { .sig = "IORT", .rev = 3, .oem_id = vms->oem_id,
|
||||
.oem_table_id = vms->oem_table_id };
|
||||
/* Table 2 The IORT */
|
||||
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);
|
||||
|
||||
/* Sort the smmu idmap by input_base */
|
||||
g_array_sort(smmu_idmaps, iort_idmap_compare);
|
||||
|
||||
/*
|
||||
* Split the whole RIDs by mapping from RC to SMMU,
|
||||
* build the ID mapping from RC to ITS directly.
|
||||
* 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 (i = 0; i < smmu_idmaps->len; i++) {
|
||||
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) {
|
||||
|
|
@ -310,17 +289,73 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
next_range.input_base = idmap->input_base + idmap->id_count;
|
||||
}
|
||||
|
||||
/* Append the last RC -> ITS ID mapping */
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
nb_nodes = 3; /* RC, ITS, SMMUv3 */
|
||||
rc_mapping_count = smmu_idmaps->len + its_idmaps->len;
|
||||
|
||||
/*
|
||||
* Input Output Remapping Table (IORT)
|
||||
* Conforms to "IO Remapping Table System Software on ARM Platforms",
|
||||
* Document number: ARM DEN 0049E.b, Feb 2021
|
||||
*/
|
||||
static void
|
||||
build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
{
|
||||
int i, nb_nodes, rc_mapping_count;
|
||||
size_t node_size, smmu_offset = 0;
|
||||
uint32_t id = 0;
|
||||
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 };
|
||||
/* Table 2 The IORT */
|
||||
acpi_table_begin(&table, table_data);
|
||||
|
||||
if (vms->iommu == VIRT_IOMMU_SMMUV3) {
|
||||
object_child_foreach_recursive(object_get_root(),
|
||||
iort_host_bridges, rc_smmu_idmaps);
|
||||
|
||||
/* Sort the smmu idmap by input_base */
|
||||
g_array_sort(rc_smmu_idmaps, iort_idmap_compare);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
create_rc_its_idmaps(rc_its_idmaps, rc_smmu_idmaps);
|
||||
|
||||
nb_nodes = 2; /* RC and SMMUv3 */
|
||||
rc_mapping_count = rc_smmu_idmaps->len;
|
||||
|
||||
if (vms->its) {
|
||||
/*
|
||||
* Knowing the ID ranges from the RC to the SMMU, it's possible to
|
||||
* determine the ID ranges from RC that go directly to ITS.
|
||||
*/
|
||||
create_rc_its_idmaps(rc_its_idmaps, rc_smmu_idmaps);
|
||||
|
||||
nb_nodes++; /* ITS */
|
||||
rc_mapping_count += rc_its_idmaps->len;
|
||||
}
|
||||
} 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,6 +364,7 @@ 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 */
|
||||
|
||||
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 */;
|
||||
|
|
@ -340,20 +376,31 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
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,10 +416,12 @@ 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) */
|
||||
/* 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 */
|
||||
build_append_int_noprefix(table_data, 2 /* Root complex */, 1); /* Type */
|
||||
|
|
@ -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) */
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TPM
|
||||
if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -3630,6 +3630,7 @@ if have_block
|
|||
endif
|
||||
if have_system
|
||||
trace_events_subdirs += [
|
||||
'accel/hvf',
|
||||
'accel/kvm',
|
||||
'audio',
|
||||
'backends',
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
42
target/arm/cpu-sysregs.h
Normal file
42
target/arm/cpu-sysregs.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Definitions for Arm ID system registers
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef ARM_CPU_SYSREGS_H
|
||||
#define ARM_CPU_SYSREGS_H
|
||||
|
||||
/*
|
||||
* Following is similar to the coprocessor regs encodings, but with an argument
|
||||
* ordering that matches the ARM ARM. We also reuse the various CP_REG_ defines
|
||||
* that actually are the same as the equivalent KVM_REG_ values.
|
||||
*/
|
||||
#define ENCODE_ID_REG(op0, op1, crn, crm, op2) \
|
||||
(((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
|
||||
((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
|
||||
((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
|
||||
((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
|
||||
((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
|
||||
|
||||
#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) NAME##_IDX,
|
||||
|
||||
typedef enum ARMIDRegisterIdx {
|
||||
#include "cpu-sysregs.h.inc"
|
||||
NUM_ID_IDX,
|
||||
} ARMIDRegisterIdx;
|
||||
|
||||
#undef DEF
|
||||
#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
|
||||
SYS_##NAME = ENCODE_ID_REG(OP0, OP1, CRN, CRM, OP2),
|
||||
|
||||
typedef enum ARMSysRegs {
|
||||
#include "cpu-sysregs.h.inc"
|
||||
} ARMSysRegs;
|
||||
|
||||
#undef DEF
|
||||
|
||||
extern const uint32_t id_register_sysreg[NUM_ID_IDX];
|
||||
|
||||
int get_sysreg_idx(ARMSysRegs sysreg);
|
||||
|
||||
#endif /* ARM_CPU_SYSREGS_H */
|
||||
36
target/arm/cpu-sysregs.h.inc
Normal file
36
target/arm/cpu-sysregs.h.inc
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0)
|
||||
DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1)
|
||||
DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5)
|
||||
DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0)
|
||||
DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1)
|
||||
DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0)
|
||||
DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1)
|
||||
DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2)
|
||||
DEF(ID_AA64MMFR0_EL1, 3, 0, 0, 7, 0)
|
||||
DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1)
|
||||
DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2)
|
||||
DEF(ID_AA64MMFR3_EL1, 3, 0, 0, 7, 3)
|
||||
DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
|
||||
DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
|
||||
DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2)
|
||||
DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4)
|
||||
DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5)
|
||||
DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6)
|
||||
DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7)
|
||||
DEF(ID_ISAR0_EL1, 3, 0, 0, 2, 0)
|
||||
DEF(ID_ISAR1_EL1, 3, 0, 0, 2, 1)
|
||||
DEF(ID_ISAR2_EL1, 3, 0, 0, 2, 2)
|
||||
DEF(ID_ISAR3_EL1, 3, 0, 0, 2, 3)
|
||||
DEF(ID_ISAR4_EL1, 3, 0, 0, 2, 4)
|
||||
DEF(ID_ISAR5_EL1, 3, 0, 0, 2, 5)
|
||||
DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6)
|
||||
DEF(ID_ISAR6_EL1, 3, 0, 0, 2, 7)
|
||||
DEF(MVFR0_EL1, 3, 0, 0, 3, 0)
|
||||
DEF(MVFR1_EL1, 3, 0, 0, 3, 1)
|
||||
DEF(MVFR2_EL1, 3, 0, 0, 3, 2)
|
||||
DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
|
||||
DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5)
|
||||
DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6)
|
||||
DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4)
|
||||
DEF(CTR_EL0, 3, 3, 0, 0, 1)
|
||||
124
target/arm/cpu.c
124
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
139
target/arm/kvm.c
139
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 |= 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(fdarray[2], &ahcf->isar.mvfr0,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
BIN
tests/data/acpi/aarch64/virt/APIC.its_off
Normal file
BIN
tests/data/acpi/aarch64/virt/APIC.its_off
Normal file
Binary file not shown.
BIN
tests/data/acpi/aarch64/virt/IORT.its_off
Normal file
BIN
tests/data/acpi/aarch64/virt/IORT.its_off
Normal file
Binary file not shown.
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
142
tests/functional/test_aarch64_device_passthrough.py
Executable file
142
tests/functional/test_aarch64_device_passthrough.py
Executable file
|
|
@ -0,0 +1,142 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# Boots a nested guest and compare content of a device (passthrough) to a
|
||||
# reference image. Both vfio group and iommufd passthrough methods are tested.
|
||||
#
|
||||
# Copyright (c) 2025 Linaro Ltd.
|
||||
#
|
||||
# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import exec_command, wait_for_console_pattern
|
||||
from qemu_test import exec_command_and_wait_for_pattern
|
||||
from random import randbytes
|
||||
|
||||
guest_script = '''
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
set -x
|
||||
|
||||
# find disks from nvme serial
|
||||
dev_vfio=$(lsblk --nvme | grep vfio | cut -f 1 -d ' ')
|
||||
dev_iommufd=$(lsblk --nvme | grep iommufd | cut -f 1 -d ' ')
|
||||
pci_vfio=$(basename $(readlink -f /sys/block/$dev_vfio/../../../))
|
||||
pci_iommufd=$(basename $(readlink -f /sys/block/$dev_iommufd/../../../))
|
||||
|
||||
# bind disks to vfio
|
||||
for p in "$pci_vfio" "$pci_iommufd"; do
|
||||
if [ "$(cat /sys/bus/pci/devices/$p/driver_override)" == vfio-pci ]; then
|
||||
continue
|
||||
fi
|
||||
echo $p > /sys/bus/pci/drivers/nvme/unbind
|
||||
echo vfio-pci > /sys/bus/pci/devices/$p/driver_override
|
||||
echo $p > /sys/bus/pci/drivers/vfio-pci/bind
|
||||
done
|
||||
|
||||
# boot nested guest and execute /host/nested_guest.sh
|
||||
# one disk is passed through vfio group, the other, through iommufd
|
||||
qemu-system-aarch64 \
|
||||
-M virt \
|
||||
-display none \
|
||||
-serial stdio \
|
||||
-cpu host \
|
||||
-enable-kvm \
|
||||
-m 1G \
|
||||
-kernel /host/Image.gz \
|
||||
-drive format=raw,file=/host/guest.ext4,if=virtio \
|
||||
-append "root=/dev/vda init=/init -- bash /host/nested_guest.sh" \
|
||||
-virtfs local,path=/host,mount_tag=host,security_model=mapped,readonly=off \
|
||||
-device vfio-pci,host=$pci_vfio \
|
||||
-object iommufd,id=iommufd0 \
|
||||
-device vfio-pci,host=$pci_iommufd,iommufd=iommufd0
|
||||
'''
|
||||
|
||||
nested_guest_script = '''
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
set -x
|
||||
|
||||
image_vfio=/host/disk_vfio
|
||||
image_iommufd=/host/disk_iommufd
|
||||
|
||||
dev_vfio=$(lsblk --nvme | grep vfio | cut -f 1 -d ' ')
|
||||
dev_iommufd=$(lsblk --nvme | grep iommufd | cut -f 1 -d ' ')
|
||||
|
||||
# compare if devices are identical to original images
|
||||
diff $image_vfio /dev/$dev_vfio
|
||||
diff $image_iommufd /dev/$dev_iommufd
|
||||
|
||||
echo device_passthrough_test_ok
|
||||
'''
|
||||
|
||||
class Aarch64DevicePassthrough(QemuSystemTest):
|
||||
|
||||
# https://github.com/pbo-linaro/qemu-linux-stack
|
||||
#
|
||||
# Linux kernel is compiled with defconfig +
|
||||
# IOMMUFD + VFIO_DEVICE_CDEV + ARM_SMMU_V3_IOMMUFD
|
||||
# https://docs.kernel.org/driver-api/vfio.html#vfio-device-cde
|
||||
ASSET_DEVICE_PASSTHROUGH_STACK = Asset(
|
||||
('https://fileserver.linaro.org/s/fx5DXxBYme8dw2G/'
|
||||
'download/device_passthrough.tar.xz'),
|
||||
'812750b664d61c2986f2b149939ae28cafbd60d53e9c7e4b16e97143845e196d')
|
||||
|
||||
# This tests the device passthrough implementation, by booting a VM
|
||||
# supporting it with two nvme disks attached, and launching a nested VM
|
||||
# reading their content.
|
||||
def test_aarch64_device_passthrough(self):
|
||||
self.set_machine('virt')
|
||||
self.require_accelerator('tcg')
|
||||
|
||||
self.vm.set_console()
|
||||
|
||||
stack_path_tar_gz = self.ASSET_DEVICE_PASSTHROUGH_STACK.fetch()
|
||||
self.archive_extract(stack_path_tar_gz, format="tar")
|
||||
|
||||
stack = self.scratch_file('out')
|
||||
kernel = os.path.join(stack, 'Image.gz')
|
||||
rootfs_host = os.path.join(stack, 'host.ext4')
|
||||
disk_vfio = os.path.join(stack, 'disk_vfio')
|
||||
disk_iommufd = os.path.join(stack, 'disk_iommufd')
|
||||
guest_cmd = os.path.join(stack, 'guest.sh')
|
||||
nested_guest_cmd = os.path.join(stack, 'nested_guest.sh')
|
||||
# we generate two random disks
|
||||
with open(disk_vfio, "wb") as d: d.write(randbytes(512))
|
||||
with open(disk_iommufd, "wb") as d: d.write(randbytes(1024))
|
||||
with open(guest_cmd, 'w') as s: s.write(guest_script)
|
||||
with open(nested_guest_cmd, 'w') as s: s.write(nested_guest_script)
|
||||
|
||||
self.vm.add_args('-cpu', 'max')
|
||||
self.vm.add_args('-m', '2G')
|
||||
self.vm.add_args('-M', 'virt,'
|
||||
'virtualization=on,'
|
||||
'gic-version=max,'
|
||||
'iommu=smmuv3')
|
||||
self.vm.add_args('-kernel', kernel)
|
||||
self.vm.add_args('-drive', f'format=raw,file={rootfs_host}')
|
||||
self.vm.add_args('-drive',
|
||||
f'file={disk_vfio},if=none,id=vfio,format=raw')
|
||||
self.vm.add_args('-device', 'nvme,serial=vfio,drive=vfio')
|
||||
self.vm.add_args('-drive',
|
||||
f'file={disk_iommufd},if=none,id=iommufd,format=raw')
|
||||
self.vm.add_args('-device', 'nvme,serial=iommufd,drive=iommufd')
|
||||
self.vm.add_args('-virtfs',
|
||||
f'local,path={stack}/,mount_tag=host,'
|
||||
'security_model=mapped,readonly=off')
|
||||
# boot and execute guest script
|
||||
# init will trigger a kernel panic if script fails
|
||||
self.vm.add_args('-append',
|
||||
'root=/dev/vda init=/init -- bash /host/guest.sh')
|
||||
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'device_passthrough_test_ok',
|
||||
failure_message='Kernel panic')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
||||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue