* [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model
@ 2026-09-16 14:45 Eric Auger
2026-09-16 14:45 ` [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
` (25 more replies)
0 siblings, 26 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
This series enhances the current host KVM model with capability to
set writable ID reg fields.
Since v6.7 kernel, KVM/arm allows the userspace to overwrite the values
of a subset of ID regs. The list of writable fields continues to grow.
The feature ID range is defined as the AArch64 System register space
with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}.
The end goal is to get more flexibility when migrating guests
between different host hardware.
QEMU retrieves the writable ID fields from KVM UAPI and
match them against a generated description of ID regs and their
named fields that stem from AARCHMRS Registers.json file.
Current description is based on latest 2026-03 edition.
The content of the generated files was compared against kernel
linux/arch/arm64/tools/sysreg file. It is not straightforward
to have unit tests for python scripts as there are many cases for
field extraction.
For each writable named field a uint64 property is created
following the "SYSREG_<REG>_<FIELD>" naming convention. REG and
FIELD names are those described in ARM ARM Reference manual.
SYSREG properties are applied at the end of the initialization
chain, after legacy composite options (sve, pauth, ...). They
do not substitute to them because legacy options do more than
just changing the value of ID registers. They may also interact
with KVM to init the vcpu with specific features or set some
VM capabilities. SYSREG properties just affect the corresponding
ID register field. Some checks are performed to make sure their
value is not inconsistent with legacy composite options.
The list of SYSREG properties can be retrieved through the qmp
monitor using query-cpu-model-expansion. They return the current
value for the corresponding field. The qmp command also allows to
test setting new values. In static mode, they are tested at qemu
level only, against field length, arch enum values if any and
consistency with legacy composite options. With full expansion,
the values are tested against KVM using a scratch vcpu initialized
with the right legacy composite property values.
Connie & Eric
This series can be found at:
https://github.com/eauger/qemu/tree/arm-cpu-model-v9
History:
--------
v8 -> v9:
- Eventually turned this series into non RFC series as main
blockers have been removed I think
- Changed the way SYSREG props are applied, first stored into
a hashkey and applied at the very end of the init chain, after
legacy composite options. This fixes the issue with NV.
- Also we are running the expansion code on a scratch vcpu mode
that should be similar to the final one, initialized with the
right composite options.
- Introduced the static support for expansion. In static mode,
we don't run checks against the scratch vcpu
- Added consistency checks between legacy composite options and
SYSREG props
- Addressed the 2 bugs reported by Khushit & Shameer (scrach vcpu
leak in expansion code and RES field handling)
- pass errp to kvm_arch_init_vcpu()
- introduced kvm_arm_vcpu_prepare_init_features
Cornelia Huck (3):
target/arm/kvm: Retrieve writable ID reg map
arm-qmp-cmds: introspection for ID register props
arm/cpu-features: document ID reg properties
Eric Auger (22):
scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py
target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order
target/arm/cpu-sysregs.h.inc: Update with automatic generation
arm/cpu: Add infra to handle generated ID register definitions
scripts: Introduce scripts/aarch64_sysreg_helpers module
scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py
target/arm/cpu-idregs.h.inc: generate with script
target/arm/cpu-idregs.h.inc: Generate enum values
hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as
0
arm/kvm: Initialize isar.idregs[] with all writable host ID regs
target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
target/arm/kvm: Implement SYSREG property setter and getter
target/arm/kvm: Pass an Error handle to kvm_arch_init_vcpu
target/arm/kvm: Apply SYSREG props to the final vcpu
target/arm/kvm: Add consistency checking for SYSREG props
target/arm/cpu: Expose writable ID reg field properties on the kvm
host vcpu model
target/arm/cpu-idregs.h.inc: Generate reserved fields
target/arm/kvm: Ignore and trace unexpected writable reserved fields
target/arm/kvm: add helper to test SYSREG props against a scratch vcpu
target/arm/kvm: Add an error handle to
kvm_arm_create_scratch_host_vcpu
target/arm/kvm: Introduce kvm_arm_vcpu_prepare_init_features helper
target/arm/kvm: Introduce kvm_arm_create_init_scratch_vcpu()
Shaju Abraham (1):
target/arm/cpu_idregs: generate tables for Arm64 ID registers and
fields
docs/system/arm/cpu-features.rst | 100 +-
include/system/kvm.h | 2 +-
target/arm/cpu-idregs.h | 36 +
target/arm/cpu.h | 2 +
target/arm/kvm_arm.h | 28 +-
target/arm/cpu-idregs.h.inc | 2512 +++++++++++++++++
target/arm/cpu-sysregs.h.inc | 55 +-
accel/kvm/kvm-all.c | 15 +-
hw/arm/virt.c | 4 +
target/arm/arm-qmp-cmds.c | 107 +-
target/arm/cpu-idregs.c | 96 +
target/arm/cpu.c | 5 +-
target/arm/cpu64.c | 5 +
target/arm/kvm-stub.c | 17 +
target/arm/kvm.c | 560 +++-
target/i386/kvm/kvm.c | 22 +-
target/loongarch/kvm/kvm.c | 24 +-
target/ppc/kvm.c | 6 +-
target/riscv/kvm/kvm-cpu.c | 3 +-
target/s390x/kvm/kvm.c | 2 +-
scripts/aarch64_sysreg_helpers.py | 121 +
.../update-aarch64-cpu-sysreg-properties.py | 299 ++
scripts/update-aarch64-cpu-sysregs-header.py | 51 +
target/arm/meson.build | 1 +
target/arm/trace-events | 9 +
25 files changed, 3987 insertions(+), 95 deletions(-)
create mode 100644 target/arm/cpu-idregs.h
create mode 100644 target/arm/cpu-idregs.h.inc
create mode 100644 target/arm/cpu-idregs.c
create mode 100644 scripts/aarch64_sysreg_helpers.py
create mode 100644 scripts/update-aarch64-cpu-sysreg-properties.py
create mode 100755 scripts/update-aarch64-cpu-sysregs-header.py
--
2.53.0
^ permalink raw reply [flat|nested] 82+ messages in thread
* [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-23 7:08 ` Khushit Shah
2026-09-24 10:24 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 02/26] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
` (24 subsequent siblings)
25 siblings, 2 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Introduce a script that takes as input the Registers.json file
delivered in the AARCHMRS Features Model downloadable from the
Arm Developer A-Profile Architecture Exploration Tools page:
https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads
and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>).
We only care about IDregs with opcodes satisfying:
op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
[CH: note correct op1 range, don't skip CCSIDR]
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Message-ID: <20251208163751.611186-2-eric.auger@redhat.com>
---
| 146 +++++++++++++++++++
1 file changed, 146 insertions(+)
create mode 100755 scripts/update-aarch64-cpu-sysregs-header.py
--git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
new file mode 100755
index 0000000000..ef1471a197
--- /dev/null
+++ b/scripts/update-aarch64-cpu-sysregs-header.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python3
+
+# This script takes as input the Registers.json file delivered in
+# the AARCHMRS Features Model downloadable from the Arm Developer
+# A-Profile Architecture Exploration Tools page:
+# https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads
+# and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
+# under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
+#
+# Copyright (C) 2026 Red Hat, Inc.
+#
+# Authors: Eric Auger <eric.auger@redhat.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+
+import json
+import os
+import sys
+
+def is_demux_register(r):
+ name = r.get('name', '')
+
+ if name.startswith("CCSIDR"):
+ return True
+
+ return False
+
+# Some regs have op code values like 000x, 001x. Anyway we don't need
+# them. Besides some regs are undesired in the generated file such as
+# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
+# are interested in and are tricky to decode as their system accessor
+# refer to MPIDR_EL1/MIDR_EL1 respectively
+
+skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
+ 'VMPIDR_EL2', 'VPIDR_EL2']
+
+# returns the int value of a given @opcode for a reg @encoding
+def get_opcode(encoding, opcode):
+ fvalue = encoding.get(opcode)
+ if fvalue:
+ value = fvalue.get('value')
+ if isinstance(value, str):
+ value = value.strip("'")
+ value = int(value, 2)
+ return value
+ return -1
+
+def extract_idregs_from_registers_json(filename):
+ """
+ Load a Registers.json file and extract all ID registers, decode their
+ opcode and dump the information in target/arm/cpu-sysregs.h.inc
+
+ Args:
+ filename (str): The path to the Registers.json
+ returns:
+ idregs: list of ID regs and their encoding
+ """
+ if not os.path.exists(filename):
+ print(f"Error: {filename} could not be found!")
+ return {}
+
+ try:
+ with open(filename, 'r') as f:
+ register_data = json.load(f)
+
+ except json.JSONDecodeError:
+ print(f"Could not decode json from '{filename}'!")
+ return {}
+ except Exception as e:
+ print(f"Unexpected error while reading {filename}: {e}")
+ return {}
+
+ registers = [
+ r for r in register_data
+ if isinstance(r, dict)
+ and r.get('_type') == 'Register'
+ and not is_demux_register(r)
+ ]
+
+ idregs = {}
+
+ for register in registers:
+ reg_name = register.get('name')
+
+ is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
+
+ if reg_name and not is_skipped:
+ accessors = register.get('accessors', [])
+
+ for accessor in accessors:
+ type = accessor.get('_type')
+ if type in ['Accessors.SystemAccessor']:
+ encoding_list = accessor.get('encoding')
+
+ if isinstance(encoding_list, list) and encoding_list and \
+ isinstance(encoding_list[0], dict):
+ encoding_wrapper = encoding_list[0]
+ encoding_source = encoding_wrapper.get('encodings', \
+ encoding_wrapper)
+
+ if isinstance(encoding_source, dict):
+ op0 = get_opcode(encoding_source, 'op0')
+ op1 = get_opcode(encoding_source, 'op1')
+ op2 = get_opcode(encoding_source, 'op2')
+ crn = get_opcode(encoding_source, 'CRn')
+ crm = get_opcode(encoding_source, 'CRm')
+ encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
+
+ # ID regs are assumed within this scope
+ if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
+ crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
+ idregs[reg_name] = encoding_str
+
+ return idregs
+
+if __name__ == "__main__":
+ # Single arg expected: the path to the Registers.json file
+ if len(sys.argv) < 2:
+ print("Usage: python scripts/update-aarch64-cpu-sysregs-header.py "
+ "<path_to_registers_json>")
+ sys.exit(1)
+ else:
+ json_file_path = sys.argv[1]
+
+ extracted_registers = extract_idregs_from_registers_json(json_file_path)
+
+ if extracted_registers:
+ output_list = extracted_registers.items()
+
+ # Sort by register name
+ sorted_output = sorted(output_list, key=lambda item: item[0])
+
+ # format lines as DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
+ final_output = ""
+ for reg_name, encoding in sorted_output:
+ reformatted_encoding = encoding.replace(" ", ", ")
+ final_output += f"DEF({reg_name}, {reformatted_encoding})\n"
+
+ with open("target/arm/cpu-sysregs.h.inc", 'w') as f:
+ f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
+ f.write("/* This file is autogenerated by ")
+ f.write("scripts/update-aarch64-cpu-sysregs-header.py */\n")
+ f.write("/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */\n\n")
+ f.write(final_output)
+ print("updated target/arm/cpu-sysregs.h.inc")
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 02/26] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
2026-09-16 14:45 ` [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 03/26] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger
` (23 subsequent siblings)
25 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Sort by register name alphabetical order. This will allow to
easily diff with the future content, automatically generated.
No functional change intended.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
---
v5 -> v6:
- v5 version conflicted because ID_AA64FPFR0_EL1 has been
added
v4 -> v5:
- remove spurious CCSIDR definition
---
target/arm/cpu-sysregs.h.inc | 44 ++++++++++++++++++------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
index 6e8b335b8f..ec5a12b0f4 100644
--- a/target/arm/cpu-sysregs.h.inc
+++ b/target/arm/cpu-sysregs.h.inc
@@ -1,13 +1,12 @@
/* 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_AA64PFR2_EL1, 3, 0, 0, 4, 2)
-DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5)
-DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7)
-DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0)
-DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1)
+DEF(CLIDR_EL1, 3, 1, 0, 0, 1)
+DEF(CTR_EL0, 3, 3, 0, 0, 1)
+DEF(DCZID_EL0, 3, 3, 0, 0, 7)
DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4)
DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5)
+DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0)
+DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1)
+DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7)
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)
@@ -17,29 +16,30 @@ 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_AA64MMFR4_EL1, 3, 0, 0, 7, 4)
-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_AA64PFR0_EL1, 3, 0, 0, 4, 0)
+DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1)
+DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2)
+DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5)
+DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4)
DEF(ID_AFR0_EL1, 3, 0, 0, 1, 3)
-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_DFR0_EL1, 3, 0, 0, 1, 2)
+DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5)
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(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_MMFR4_EL1, 3, 0, 0, 2, 6)
+DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6)
+DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
+DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
+DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
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(CLIDR_EL1, 3, 1, 0, 0, 1)
-DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4)
-DEF(CTR_EL0, 3, 3, 0, 0, 1)
-DEF(DCZID_EL0, 3, 3, 0, 0, 7)
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 03/26] target/arm/cpu-sysregs.h.inc: Update with automatic generation
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
2026-09-16 14:45 ` [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
2026-09-16 14:45 ` [PATCH v9 02/26] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-23 9:13 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 04/26] arm/cpu: Add infra to handle generated ID register definitions Eric Auger
` (22 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Generated definitions with scripts/update-aarch64-cpu-sysregs-header.py
based on "AARCHMRS containing the JSON files for Arm A-profile
architecture (2026-03)" Registers.json file.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
---
target/arm/cpu-sysregs.h.inc | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
index ec5a12b0f4..8b77c490d4 100644
--- a/target/arm/cpu-sysregs.h.inc
+++ b/target/arm/cpu-sysregs.h.inc
@@ -1,11 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/* This file is autogenerated by scripts/update-aarch64-cpu-sysregs-header.py */
+/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */
+
+DEF(AIDR_EL1, 3, 1, 0, 0, 7)
DEF(CLIDR_EL1, 3, 1, 0, 0, 1)
DEF(CTR_EL0, 3, 3, 0, 0, 1)
DEF(DCZID_EL0, 3, 3, 0, 0, 7)
+DEF(GMID_EL1, 3, 1, 0, 0, 4)
DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4)
DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5)
DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0)
DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1)
+DEF(ID_AA64DFR2_EL1, 3, 0, 0, 5, 2)
DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7)
DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0)
DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1)
@@ -40,6 +47,10 @@ DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6)
DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
+DEF(MIDR_EL1, 3, 0, 0, 0, 0)
+DEF(MPIDR_EL1, 3, 0, 0, 0, 5)
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(REVIDR_EL1, 3, 0, 0, 0, 6)
+DEF(SMIDR_EL1, 3, 1, 0, 0, 6)
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 04/26] arm/cpu: Add infra to handle generated ID register definitions
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (2 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 03/26] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-24 10:01 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 05/26] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger
` (21 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Introduce an infrastructure to store the definition of all ID regs:
This include their name, index and array of named fields.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Co-authored-by: Khushit Shah <khushit.shah@nutanix.com>
Signed-off-by: Khushit Shah <khushit.shah@nutanix.com>
---
v7 -> v8:
- remove typedef struct ArmIdRegArchVal
v5 -> v6:
- add ArmIdRegArchVal
---
target/arm/cpu-idregs.h | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 target/arm/cpu-idregs.h
diff --git a/target/arm/cpu-idregs.h b/target/arm/cpu-idregs.h
new file mode 100644
index 0000000000..98c7a7518f
--- /dev/null
+++ b/target/arm/cpu-idregs.h
@@ -0,0 +1,36 @@
+/*
+ * handle ID registers and their fields
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef TARGET_ARM_CPU_IDREGS_H
+#define TARGET_ARM_CPU_IDREGS_H
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "cpu.h"
+#include "cpu-sysregs.h"
+
+typedef struct ARM64SysRegField {
+ const char *name; /* name of the field, for instance CTR_EL0_IDC */
+ ARMIDRegisterIdx index; /* parent register, e.g. CTR_EL0_IDX */
+ int shift; /* lsb of the field in the register */
+ int length; /* highest bit number */
+ uint64_t *arch_vals;
+ uint32_t arch_vals_count;
+} ARM64SysRegField;
+
+typedef struct ARM64SysReg {
+ const char *name; /* name of the sysreg, for instance CTR_EL0 */
+ ARMIDRegisterIdx index; /* register index, e.g. CTR_EL0_IDX */
+ struct ARM64SysRegField *fields;
+ uint32_t fields_count;
+ uint64_t writable_mask;
+} ARM64SysReg;
+
+/*
+ * List of exposed ID regs (automatically populated from AARCHMRS Registers.json)
+ */
+extern ARM64SysReg arm64_id_regs[NUM_ID_IDX];
+
+#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 05/26] scripts: Introduce scripts/aarch64_sysreg_helpers module
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (3 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 04/26] arm/cpu: Add infra to handle generated ID register definitions Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-24 10:18 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 06/26] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger
` (20 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
We plan to reuse get_opcode() and extract_idregs_from_registers_json()
functions in another script. So let's move them into a module
No functional change intended.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
---
scripts/aarch64_sysreg_helpers.py | 121 +++++++++++++++++++
| 97 +--------------
2 files changed, 122 insertions(+), 96 deletions(-)
create mode 100644 scripts/aarch64_sysreg_helpers.py
diff --git a/scripts/aarch64_sysreg_helpers.py b/scripts/aarch64_sysreg_helpers.py
new file mode 100644
index 0000000000..24bbc5bb3d
--- /dev/null
+++ b/scripts/aarch64_sysreg_helpers.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+
+# Helpers used in aarch64 sysreg definition generation
+#
+# Copyright (C) 2026 Red Hat, Inc.
+#
+# Authors: Eric Auger <eric.auger@redhat.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+
+import json
+import os
+
+def is_demux_register(r):
+ name = r.get('name', '')
+
+ if name.startswith("CCSIDR"):
+ return True
+
+ return False
+
+# Some regs have op code values like 000x, 001x. Anyway we don't need
+# them. Besides some regs are undesired in the generated file such as
+# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
+# are interested in and are tricky to decode as their system accessor
+# refer to MPIDR_EL1/MIDR_EL1 respectively
+
+skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
+ 'VMPIDR_EL2', 'VPIDR_EL2']
+
+# returns the int value of a given @opcode for a reg @encoding
+def get_opcode(encoding, opcode):
+ fvalue = encoding.get(opcode)
+ if fvalue:
+ value = fvalue.get('value')
+ if isinstance(value, str):
+ value = value.strip("'")
+ value = int(value, 2)
+ return value
+ return -1
+
+def extract_idregs_from_registers_json(filename):
+ """
+ Load a Registers.json file and extract all ID registers, decode their
+ opcode and dump the information in target/arm/cpu-sysregs.h.inc
+
+ Args:
+ filename (str): The path to the Registers.json
+ returns:
+ idregs: list of ID regs and their encoding
+ """
+ if not os.path.exists(filename):
+ print(f"Error: {filename} could not be found!")
+ return {}
+
+ try:
+ with open(filename, 'r') as f:
+ register_data = json.load(f)
+
+ except json.JSONDecodeError:
+ print(f"Could not decode json from '{filename}'!")
+ return {}
+ except Exception as e:
+ print(f"Unexpected error while reading {filename}: {e}")
+ return {}
+
+ registers = [
+ r for r in register_data
+ if isinstance(r, dict)
+ and r.get('_type') == 'Register'
+ and not is_demux_register(r)
+ ]
+
+ idregs = {}
+
+ # Some regs have op code values like 000x, 001x. Anyway we don't need
+ # them. Besides some regs are undesired in the generated file such as
+ # VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
+ # are interested in and are tricky to decode as their system accessor
+ # refer to MPIDR_EL1/MIDR_EL1 respectively
+
+ skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
+ 'VMPIDR_EL2', 'VPIDR_EL2']
+
+ for register in registers:
+ reg_name = register.get('name')
+
+ is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
+
+ if reg_name and not is_skipped:
+ accessors = register.get('accessors', [])
+
+ for accessor in accessors:
+ type = accessor.get('_type')
+ if type in ['Accessors.SystemAccessor']:
+ encoding_list = accessor.get('encoding')
+
+ if isinstance(encoding_list, list) and encoding_list and \
+ isinstance(encoding_list[0], dict):
+ encoding_wrapper = encoding_list[0]
+ encoding_source = encoding_wrapper.get('encodings', \
+ encoding_wrapper)
+
+ if isinstance(encoding_source, dict):
+ op0 = get_opcode(encoding_source, 'op0')
+ op1 = get_opcode(encoding_source, 'op1')
+ op2 = get_opcode(encoding_source, 'op2')
+ crn = get_opcode(encoding_source, 'CRn')
+ crm = get_opcode(encoding_source, 'CRm')
+ encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
+
+ # ID regs are assumed within this scope
+ if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
+ crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
+ idregs[reg_name] = encoding_str
+
+ return idregs
+
+
+
--git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
index ef1471a197..43107264e9 100755
--- a/scripts/update-aarch64-cpu-sysregs-header.py
+++ b/scripts/update-aarch64-cpu-sysregs-header.py
@@ -17,102 +17,7 @@
import json
import os
import sys
-
-def is_demux_register(r):
- name = r.get('name', '')
-
- if name.startswith("CCSIDR"):
- return True
-
- return False
-
-# Some regs have op code values like 000x, 001x. Anyway we don't need
-# them. Besides some regs are undesired in the generated file such as
-# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
-# are interested in and are tricky to decode as their system accessor
-# refer to MPIDR_EL1/MIDR_EL1 respectively
-
-skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
- 'VMPIDR_EL2', 'VPIDR_EL2']
-
-# returns the int value of a given @opcode for a reg @encoding
-def get_opcode(encoding, opcode):
- fvalue = encoding.get(opcode)
- if fvalue:
- value = fvalue.get('value')
- if isinstance(value, str):
- value = value.strip("'")
- value = int(value, 2)
- return value
- return -1
-
-def extract_idregs_from_registers_json(filename):
- """
- Load a Registers.json file and extract all ID registers, decode their
- opcode and dump the information in target/arm/cpu-sysregs.h.inc
-
- Args:
- filename (str): The path to the Registers.json
- returns:
- idregs: list of ID regs and their encoding
- """
- if not os.path.exists(filename):
- print(f"Error: {filename} could not be found!")
- return {}
-
- try:
- with open(filename, 'r') as f:
- register_data = json.load(f)
-
- except json.JSONDecodeError:
- print(f"Could not decode json from '{filename}'!")
- return {}
- except Exception as e:
- print(f"Unexpected error while reading {filename}: {e}")
- return {}
-
- registers = [
- r for r in register_data
- if isinstance(r, dict)
- and r.get('_type') == 'Register'
- and not is_demux_register(r)
- ]
-
- idregs = {}
-
- for register in registers:
- reg_name = register.get('name')
-
- is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
-
- if reg_name and not is_skipped:
- accessors = register.get('accessors', [])
-
- for accessor in accessors:
- type = accessor.get('_type')
- if type in ['Accessors.SystemAccessor']:
- encoding_list = accessor.get('encoding')
-
- if isinstance(encoding_list, list) and encoding_list and \
- isinstance(encoding_list[0], dict):
- encoding_wrapper = encoding_list[0]
- encoding_source = encoding_wrapper.get('encodings', \
- encoding_wrapper)
-
- if isinstance(encoding_source, dict):
- op0 = get_opcode(encoding_source, 'op0')
- op1 = get_opcode(encoding_source, 'op1')
- op2 = get_opcode(encoding_source, 'op2')
- crn = get_opcode(encoding_source, 'CRn')
- crm = get_opcode(encoding_source, 'CRm')
- encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
-
- # ID regs are assumed within this scope
- if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
- crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
- idregs[reg_name] = encoding_str
-
- return idregs
+from aarch64_sysreg_helpers import extract_idregs_from_registers_json
if __name__ == "__main__":
# Single arg expected: the path to the Registers.json file
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 06/26] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (4 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 05/26] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-25 9:29 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 07/26] target/arm/cpu-idregs.h.inc: generate with script Eric Auger
` (19 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Introduce a script that takes as input the Registers.json file
delivered in the AARCHMRS Features Model downloadable from the
Arm Developer A-Profile Architecture Exploration Tools page:
https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads
and automates the generation of system register properties definitions.
generates target/arm/cpu-idregs.h.inc containing definitions for
feature ID registers.
We only care about IDregs with opcodes satisfying:
op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
v5 -> v6
- add ident
---
.../update-aarch64-cpu-sysreg-properties.py | 166 ++++++++++++++++++
1 file changed, 166 insertions(+)
create mode 100644 scripts/update-aarch64-cpu-sysreg-properties.py
diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py
new file mode 100644
index 0000000000..6f5edb88d2
--- /dev/null
+++ b/scripts/update-aarch64-cpu-sysreg-properties.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python3
+
+# This script takes as input the Registers.json file delivered in
+# the AARCHMRS Features Model downloadable from the Arm Developer
+# A-Profile Architecture Exploration Tools page:
+# https://developer.arm.com/Architectures/A-Profile%20Architecture#Downloads
+# and outputs target/arm/cpu-idregs.h.inc content.
+# ID regs are defined using this pattern:
+#
+# IDREG_START(REG)
+# IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
+# ...
+# IDREG_END(REG)
+#
+# Copyright (C) 2026 Red Hat, Inc.
+#
+# Authors: Eric Auger <eric.auger@redhat.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+
+import json
+import os
+import sys
+from aarch64_sysreg_helpers import extract_idregs_from_registers_json
+
+def collect_fields(item, bit_offset=0):
+ """
+ Recursively finds all field-like objects, handling Fields.Array,
+ Fields.ArrayField, and ConditionalField structures.
+ Applies bit_offset from containers to child fields.
+ """
+ fields = []
+ if not isinstance(item, dict):
+ return fields
+
+ _type = item.get('_type', '')
+
+ # Array types (for example CLIDR_EL1 Ctype<n>, Ttype<n>)
+ if _type == 'Fields.Array':
+ name_template = item.get('name') or item.get('label', '')
+ index_info = item.get('indexes', [{}])[0]
+ start_idx = index_info.get('start', 0)
+ count = index_info.get('width', 0)
+
+ full_range = item.get('rangeset', [{}])[0]
+ bit_start = full_range.get('start', 0) + bit_offset
+ elem_width = full_range.get('width', 0) // count if count else 0
+
+ for i in range(count):
+ idx = start_idx + i
+ # Correctly handle indexed names like Ctype1, Ctype2
+ field_name = name_template.replace('<n>', str(idx))
+ fields.append({
+ 'name': field_name,
+ 'rangeset': [{
+ 'start': bit_start + (i * elem_width),
+ 'width': elem_width
+ }],
+ '_type': 'Fields.Field'
+ })
+ return fields
+
+ # ConditionalFields
+ elif _type == 'Fields.ConditionalField':
+ inner_offset = bit_offset
+ if item.get('rangeset'):
+ # Parent container defines the absolute start bit
+ inner_offset = item['rangeset'][0].get('start', bit_offset)
+
+ for entry in item.get('fields', []):
+ inner = entry.get('field')
+ if inner:
+ fields.extend(collect_fields(inner, inner_offset))
+ return fields
+
+ # Normal Field Types
+ leaf_types = ['Fields.Field', 'Fields.ConstantField',
+ 'Fields.EnumeratedField', 'Fields.Bitfield']
+ if _type in leaf_types:
+ field_copy = item.copy()
+ if field_copy.get('rangeset'):
+ new_ranges = []
+ for r in field_copy['rangeset']:
+ nr = r.copy()
+ # Apply the cumulative offset to the field's start bit
+ nr['start'] = r.get('start', 0) + bit_offset
+ new_ranges.append(nr)
+ field_copy['rangeset'] = new_ranges
+ fields.append(field_copy)
+ return fields
+
+ # Traverse the hierarchy for other cases
+ for key in ['fields', 'values', 'fieldsets']:
+ for nested in item.get(key, []):
+ fields.extend(collect_fields(nested, bit_offset))
+
+ return fields
+
+
+def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
+ with open(raw_json_path, 'r') as f:
+ register_data = json.load(f)
+
+ regs = {r.get('name'): r for r in register_data if r.get('_type') == 'Register'}
+
+ final_output = ""
+
+ for reg_name in id_reg_names:
+ register = regs.get(reg_name)
+ if not register:
+ continue
+
+ final_output += f"IDREG_START({reg_name})\n"
+
+ unique_fields = {}
+ for fieldset in register.get('fieldsets', []):
+ candidates = collect_fields(fieldset)
+ for val in candidates:
+ name = (val.get('name') or val.get('label', '')).strip()
+ if not name or "RESERVED" in name.upper():
+ continue
+ for r in val.get('rangeset', []):
+ lsb = int(r.get('start'))
+ width = r.get('width')
+ msb = lsb + int(width) - 1
+
+ # Only keep the fields with the highest MSB
+ # needed fir CCSIDR_EL1
+ if name not in unique_fields or msb > unique_fields[name]['msb']:
+ unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width}
+
+ # Sort decreasing lsbs
+ sorted_fields = sorted(unique_fields.items(),
+ key=lambda x: x[1]['lsb'], reverse=True)
+
+ for name, bits in sorted_fields:
+ line = (f" IDREG_FIELD({reg_name}, "
+ f"{name}, {bits['lsb']}, {bits['width']})\n")
+ final_output += line
+ final_output += f"IDREG_END({reg_name})\n"
+ final_output += "\n"
+
+ os.makedirs("target/arm", exist_ok=True)
+ with open("target/arm/cpu-idregs.h.inc", 'w') as f:
+ f.write("/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n\n")
+ f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
+ f.write("/* IDREG_START(REG) */\n")
+ f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n")
+ f.write("/* ... */\n")
+ f.write("/* IDREG_END(REG) */\n\n")
+ f.write(final_output)
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ print("Usage: python scripts/update-aarch64-cpu-sysreg-properties.py "
+ "<path_to_registers_json>")
+ else:
+ json_path = sys.argv[1]
+
+ id_regs_dict = extract_idregs_from_registers_json(json_path)
+ sorted_names = sorted(id_regs_dict.keys())
+
+ if sorted_names:
+ generate_sysreg_properties_from_registers_json(sorted_names, json_path)
+ print("Generated target/arm/cpu-idregs.h.inc")
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 07/26] target/arm/cpu-idregs.h.inc: generate with script
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (5 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 06/26] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-25 11:19 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 08/26] target/arm/cpu-idregs.h.inc: Generate enum values Eric Auger
` (18 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Generate ID reg definitions with the scripts/update-aarch64-cpu-sysreg-properties.py
based on AARCHMRS_OPENSOURCE_A_profile_FAT-2026-03 Registers.json
Each register and fields are described with this pattern:
IDREG_START(REG)
IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
...
IDREG_END(REG)
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Suggested-by: Khushit Shah <khushit.shah@nutanix.com>
Suggested-by: Shaju Abraham <shaju.abraham@nutanix.com>
---
target/arm/cpu-idregs.h.inc | 607 ++++++++++++++++++++++++++++++++++++
1 file changed, 607 insertions(+)
create mode 100644 target/arm/cpu-idregs.h.inc
diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
new file mode 100644
index 0000000000..c9745e2fb6
--- /dev/null
+++ b/target/arm/cpu-idregs.h.inc
@@ -0,0 +1,607 @@
+/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/* IDREG_START(REG) */
+/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */
+/* ... */
+/* IDREG_END(REG) */
+
+IDREG_START(AIDR_EL1)
+IDREG_END(AIDR_EL1)
+
+IDREG_START(CLIDR_EL1)
+ IDREG_FIELD(CLIDR_EL1, Ttype7, 45, 2)
+ IDREG_FIELD(CLIDR_EL1, Ttype6, 43, 2)
+ IDREG_FIELD(CLIDR_EL1, Ttype5, 41, 2)
+ IDREG_FIELD(CLIDR_EL1, Ttype4, 39, 2)
+ IDREG_FIELD(CLIDR_EL1, Ttype3, 37, 2)
+ IDREG_FIELD(CLIDR_EL1, Ttype2, 35, 2)
+ IDREG_FIELD(CLIDR_EL1, Ttype1, 33, 2)
+ IDREG_FIELD(CLIDR_EL1, ICB, 30, 3)
+ IDREG_FIELD(CLIDR_EL1, LoUU, 27, 3)
+ IDREG_FIELD(CLIDR_EL1, LoC, 24, 3)
+ IDREG_FIELD(CLIDR_EL1, LoUIS, 21, 3)
+ IDREG_FIELD(CLIDR_EL1, Ctype7, 18, 3)
+ IDREG_FIELD(CLIDR_EL1, Ctype6, 15, 3)
+ IDREG_FIELD(CLIDR_EL1, Ctype5, 12, 3)
+ IDREG_FIELD(CLIDR_EL1, Ctype4, 9, 3)
+ IDREG_FIELD(CLIDR_EL1, Ctype3, 6, 3)
+ IDREG_FIELD(CLIDR_EL1, Ctype2, 3, 3)
+ IDREG_FIELD(CLIDR_EL1, Ctype1, 0, 3)
+IDREG_END(CLIDR_EL1)
+
+IDREG_START(CTR_EL0)
+ IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
+ IDREG_FIELD(CTR_EL0, DIC, 29, 1)
+ IDREG_FIELD(CTR_EL0, IDC, 28, 1)
+ IDREG_FIELD(CTR_EL0, CWG, 24, 4)
+ IDREG_FIELD(CTR_EL0, ERG, 20, 4)
+ IDREG_FIELD(CTR_EL0, DminLine, 16, 4)
+ IDREG_FIELD(CTR_EL0, L1Ip, 14, 2)
+ IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
+IDREG_END(CTR_EL0)
+
+IDREG_START(DCZID_EL0)
+ IDREG_FIELD(DCZID_EL0, TBS, 5, 4)
+ IDREG_FIELD(DCZID_EL0, DZP, 4, 1)
+ IDREG_FIELD(DCZID_EL0, BS, 0, 4)
+IDREG_END(DCZID_EL0)
+
+IDREG_START(GMID_EL1)
+ IDREG_FIELD(GMID_EL1, BS, 0, 4)
+IDREG_END(GMID_EL1)
+
+IDREG_START(ID_AA64AFR0_EL1)
+IDREG_END(ID_AA64AFR0_EL1)
+
+IDREG_START(ID_AA64AFR1_EL1)
+IDREG_END(ID_AA64AFR1_EL1)
+
+IDREG_START(ID_AA64DFR0_EL1)
+ IDREG_FIELD(ID_AA64DFR0_EL1, HPMN0, 60, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, BRBE, 52, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, MTPMU, 48, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, PMSVer, 32, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, WRPs, 20, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, PMSS, 16, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, BRPs, 12, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, PMUVer, 8, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, TraceVer, 4, 4)
+ IDREG_FIELD(ID_AA64DFR0_EL1, DebugVer, 0, 4)
+IDREG_END(ID_AA64DFR0_EL1)
+
+IDREG_START(ID_AA64DFR1_EL1)
+ IDREG_FIELD(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
+ IDREG_FIELD(ID_AA64DFR1_EL1, DPFZS, 52, 4)
+ IDREG_FIELD(ID_AA64DFR1_EL1, EBEP, 48, 4)
+ IDREG_FIELD(ID_AA64DFR1_EL1, ITE, 44, 4)
+ IDREG_FIELD(ID_AA64DFR1_EL1, ABLE, 40, 4)
+ IDREG_FIELD(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
+ IDREG_FIELD(ID_AA64DFR1_EL1, SPMU, 32, 4)
+ IDREG_FIELD(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
+ IDREG_FIELD(ID_AA64DFR1_EL1, WRPs, 16, 8)
+ IDREG_FIELD(ID_AA64DFR1_EL1, BRPs, 8, 8)
+ IDREG_FIELD(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
+IDREG_END(ID_AA64DFR1_EL1)
+
+IDREG_START(ID_AA64DFR2_EL1)
+ IDREG_FIELD(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
+ IDREG_FIELD(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
+ IDREG_FIELD(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
+ IDREG_FIELD(ID_AA64DFR2_EL1, BWE, 4, 4)
+ IDREG_FIELD(ID_AA64DFR2_EL1, STEP, 0, 4)
+IDREG_END(ID_AA64DFR2_EL1)
+
+IDREG_START(ID_AA64FPFR0_EL1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
+IDREG_END(ID_AA64FPFR0_EL1)
+
+IDREG_START(ID_AA64ISAR0_EL1)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, RNDR, 60, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, TLB, 56, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, TS, 52, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, FHM, 48, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, DP, 44, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, SM4, 40, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, SM3, 36, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, SHA3, 32, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, RDM, 28, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, Atomic, 20, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, CRC32, 16, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, SHA2, 12, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, SHA1, 8, 4)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, AES, 4, 4)
+IDREG_END(ID_AA64ISAR0_EL1)
+
+IDREG_START(ID_AA64ISAR1_EL1)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, LS64, 60, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, XS, 56, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, I8MM, 52, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, DGH, 48, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, BF16, 44, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, SB, 36, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, GPI, 28, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, GPA, 24, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, FCMA, 16, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, API, 8, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, APA, 4, 4)
+ IDREG_FIELD(ID_AA64ISAR1_EL1, DPB, 0, 4)
+IDREG_END(ID_AA64ISAR1_EL1)
+
+IDREG_START(ID_AA64ISAR2_EL1)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, LUT, 56, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, CSSC, 52, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, BC, 20, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, MOPS, 16, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, APA3, 12, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, GPA3, 8, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, RPRES, 4, 4)
+ IDREG_FIELD(ID_AA64ISAR2_EL1, WFxT, 0, 4)
+IDREG_END(ID_AA64ISAR2_EL1)
+
+IDREG_START(ID_AA64ISAR3_EL1)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, LSCP, 44, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, MTETC, 36, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, LSUI, 24, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, LSFE, 16, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, PACM, 12, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, CPA, 0, 4)
+IDREG_END(ID_AA64ISAR3_EL1)
+
+IDREG_START(ID_AA64MMFR0_EL1)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, ECV, 60, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, FGT, 56, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, ExS, 44, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4, 28, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64, 24, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16, 20, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, PARange, 0, 4)
+IDREG_END(ID_AA64MMFR0_EL1)
+
+IDREG_START(ID_AA64MMFR1_EL1)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, CMOW, 56, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, AFP, 44, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, HCX, 40, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, ETS, 36, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, TWED, 32, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, XNX, 28, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, PAN, 20, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, LO, 16, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, HPDS, 12, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, VH, 8, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
+ IDREG_FIELD(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
+IDREG_END(ID_AA64MMFR1_EL1)
+
+IDREG_START(ID_AA64MMFR2_EL1)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, E0PD, 60, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, EVT, 56, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, BBM, 52, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, TTL, 48, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, FWB, 40, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, IDS, 36, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, AT, 32, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, ST, 28, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, NV, 24, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, VARange, 16, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, IESB, 12, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, LSM, 8, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, UAO, 4, 4)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, CnP, 0, 4)
+IDREG_END(ID_AA64MMFR2_EL1)
+
+IDREG_START(ID_AA64MMFR3_EL1)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, ADERR, 56, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, SDERR, 52, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, ANERR, 44, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, SNERR, 40, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, D128_2, 36, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, D128, 32, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, MEC, 28, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, AIE, 24, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, S2POE, 20, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, S1POE, 16, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, TCRX, 0, 4)
+IDREG_END(ID_AA64MMFR3_EL1)
+
+IDREG_START(ID_AA64MMFR4_EL1)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, SCRX, 56, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, TEV, 52, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, TPS, 48, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, TLBID, 40, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, EAESR, 32, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, E2H0, 24, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, ASID2, 8, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, EIESB, 4, 4)
+ IDREG_FIELD(ID_AA64MMFR4_EL1, PoPS, 0, 4)
+IDREG_END(ID_AA64MMFR4_EL1)
+
+IDREG_START(ID_AA64PFR0_EL1)
+ IDREG_FIELD(ID_AA64PFR0_EL1, CSV3, 60, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, CSV2, 56, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, RME, 52, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, DIT, 48, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, AMU, 44, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, MPAM, 40, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, SEL2, 36, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, SVE, 32, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, RAS, 28, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, GIC, 24, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, FP, 16, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, EL3, 12, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, EL2, 8, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, EL1, 4, 4)
+ IDREG_FIELD(ID_AA64PFR0_EL1, EL0, 0, 4)
+IDREG_END(ID_AA64PFR0_EL1)
+
+IDREG_START(ID_AA64PFR1_EL1)
+ IDREG_FIELD(ID_AA64PFR1_EL1, PFAR, 60, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, DF2, 56, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, MTEX, 52, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, THE, 48, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, GCS, 44, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, NMI, 36, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, SME, 24, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, MTE, 8, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, SSBS, 4, 4)
+ IDREG_FIELD(ID_AA64PFR1_EL1, BT, 0, 4)
+IDREG_END(ID_AA64PFR1_EL1)
+
+IDREG_START(ID_AA64PFR2_EL1)
+ IDREG_FIELD(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, VMTETC, 40, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, VMTE, 36, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, FPMR, 32, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, MPAM2, 28, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, FGDT, 24, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, UINJ, 16, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, GCIE, 12, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
+ IDREG_FIELD(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
+IDREG_END(ID_AA64PFR2_EL1)
+
+IDREG_START(ID_AA64SMFR0_EL1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, FA64, 63, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, LUT6, 61, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, SMEver, 56, 4)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, I16I64, 52, 4)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, F64F64, 48, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, I16I32, 44, 4)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, B16B16, 43, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, F16F16, 42, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, F8F16, 41, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, F8F32, 40, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, I8I32, 36, 4)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, F16F32, 35, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, B16F32, 34, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, F32F32, 32, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, AES, 24, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, STMOP, 16, 1)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
+IDREG_END(ID_AA64SMFR0_EL1)
+
+IDREG_START(ID_AA64ZFR0_EL1)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, F64MM, 56, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, F32MM, 52, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, F16MM, 48, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, I8MM, 44, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, SM4, 40, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, SHA3, 32, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, B16B16, 24, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, BF16, 20, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, AES, 4, 4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, SVEver, 0, 4)
+IDREG_END(ID_AA64ZFR0_EL1)
+
+IDREG_START(ID_AFR0_EL1)
+IDREG_END(ID_AFR0_EL1)
+
+IDREG_START(ID_DFR0_EL1)
+ IDREG_FIELD(ID_DFR0_EL1, TraceFilt, 28, 4)
+ IDREG_FIELD(ID_DFR0_EL1, PerfMon, 24, 4)
+ IDREG_FIELD(ID_DFR0_EL1, MProfDbg, 20, 4)
+ IDREG_FIELD(ID_DFR0_EL1, MMapTrc, 16, 4)
+ IDREG_FIELD(ID_DFR0_EL1, CopTrc, 12, 4)
+ IDREG_FIELD(ID_DFR0_EL1, MMapDbg, 8, 4)
+ IDREG_FIELD(ID_DFR0_EL1, CopSDbg, 4, 4)
+ IDREG_FIELD(ID_DFR0_EL1, CopDbg, 0, 4)
+IDREG_END(ID_DFR0_EL1)
+
+IDREG_START(ID_DFR1_EL1)
+ IDREG_FIELD(ID_DFR1_EL1, HPMN0, 4, 4)
+ IDREG_FIELD(ID_DFR1_EL1, MTPMU, 0, 4)
+IDREG_END(ID_DFR1_EL1)
+
+IDREG_START(ID_ISAR0_EL1)
+ IDREG_FIELD(ID_ISAR0_EL1, Divide, 24, 4)
+ IDREG_FIELD(ID_ISAR0_EL1, Debug, 20, 4)
+ IDREG_FIELD(ID_ISAR0_EL1, Coproc, 16, 4)
+ IDREG_FIELD(ID_ISAR0_EL1, CmpBranch, 12, 4)
+ IDREG_FIELD(ID_ISAR0_EL1, BitField, 8, 4)
+ IDREG_FIELD(ID_ISAR0_EL1, BitCount, 4, 4)
+ IDREG_FIELD(ID_ISAR0_EL1, Swap, 0, 4)
+IDREG_END(ID_ISAR0_EL1)
+
+IDREG_START(ID_ISAR1_EL1)
+ IDREG_FIELD(ID_ISAR1_EL1, Jazelle, 28, 4)
+ IDREG_FIELD(ID_ISAR1_EL1, Interwork, 24, 4)
+ IDREG_FIELD(ID_ISAR1_EL1, Immediate, 20, 4)
+ IDREG_FIELD(ID_ISAR1_EL1, IfThen, 16, 4)
+ IDREG_FIELD(ID_ISAR1_EL1, Extend, 12, 4)
+ IDREG_FIELD(ID_ISAR1_EL1, Except_AR, 8, 4)
+ IDREG_FIELD(ID_ISAR1_EL1, Except, 4, 4)
+ IDREG_FIELD(ID_ISAR1_EL1, Endian, 0, 4)
+IDREG_END(ID_ISAR1_EL1)
+
+IDREG_START(ID_ISAR2_EL1)
+ IDREG_FIELD(ID_ISAR2_EL1, Reversal, 28, 4)
+ IDREG_FIELD(ID_ISAR2_EL1, PSR_AR, 24, 4)
+ IDREG_FIELD(ID_ISAR2_EL1, MultU, 20, 4)
+ IDREG_FIELD(ID_ISAR2_EL1, MultS, 16, 4)
+ IDREG_FIELD(ID_ISAR2_EL1, Mult, 12, 4)
+ IDREG_FIELD(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
+ IDREG_FIELD(ID_ISAR2_EL1, MemHint, 4, 4)
+ IDREG_FIELD(ID_ISAR2_EL1, LoadStore, 0, 4)
+IDREG_END(ID_ISAR2_EL1)
+
+IDREG_START(ID_ISAR3_EL1)
+ IDREG_FIELD(ID_ISAR3_EL1, T32EE, 28, 4)
+ IDREG_FIELD(ID_ISAR3_EL1, TrueNOP, 24, 4)
+ IDREG_FIELD(ID_ISAR3_EL1, T32Copy, 20, 4)
+ IDREG_FIELD(ID_ISAR3_EL1, TabBranch, 16, 4)
+ IDREG_FIELD(ID_ISAR3_EL1, SynchPrim, 12, 4)
+ IDREG_FIELD(ID_ISAR3_EL1, SVC, 8, 4)
+ IDREG_FIELD(ID_ISAR3_EL1, SIMD, 4, 4)
+ IDREG_FIELD(ID_ISAR3_EL1, Saturate, 0, 4)
+IDREG_END(ID_ISAR3_EL1)
+
+IDREG_START(ID_ISAR4_EL1)
+ IDREG_FIELD(ID_ISAR4_EL1, SWP_frac, 28, 4)
+ IDREG_FIELD(ID_ISAR4_EL1, PSR_M, 24, 4)
+ IDREG_FIELD(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
+ IDREG_FIELD(ID_ISAR4_EL1, Barrier, 16, 4)
+ IDREG_FIELD(ID_ISAR4_EL1, SMC, 12, 4)
+ IDREG_FIELD(ID_ISAR4_EL1, Writeback, 8, 4)
+ IDREG_FIELD(ID_ISAR4_EL1, WithShifts, 4, 4)
+ IDREG_FIELD(ID_ISAR4_EL1, Unpriv, 0, 4)
+IDREG_END(ID_ISAR4_EL1)
+
+IDREG_START(ID_ISAR5_EL1)
+ IDREG_FIELD(ID_ISAR5_EL1, VCMA, 28, 4)
+ IDREG_FIELD(ID_ISAR5_EL1, RDM, 24, 4)
+ IDREG_FIELD(ID_ISAR5_EL1, CRC32, 16, 4)
+ IDREG_FIELD(ID_ISAR5_EL1, SHA2, 12, 4)
+ IDREG_FIELD(ID_ISAR5_EL1, SHA1, 8, 4)
+ IDREG_FIELD(ID_ISAR5_EL1, AES, 4, 4)
+ IDREG_FIELD(ID_ISAR5_EL1, SEVL, 0, 4)
+IDREG_END(ID_ISAR5_EL1)
+
+IDREG_START(ID_ISAR6_EL1)
+ IDREG_FIELD(ID_ISAR6_EL1, CLRBHB, 28, 4)
+ IDREG_FIELD(ID_ISAR6_EL1, I8MM, 24, 4)
+ IDREG_FIELD(ID_ISAR6_EL1, BF16, 20, 4)
+ IDREG_FIELD(ID_ISAR6_EL1, SPECRES, 16, 4)
+ IDREG_FIELD(ID_ISAR6_EL1, SB, 12, 4)
+ IDREG_FIELD(ID_ISAR6_EL1, FHM, 8, 4)
+ IDREG_FIELD(ID_ISAR6_EL1, DP, 4, 4)
+ IDREG_FIELD(ID_ISAR6_EL1, JSCVT, 0, 4)
+IDREG_END(ID_ISAR6_EL1)
+
+IDREG_START(ID_MMFR0_EL1)
+ IDREG_FIELD(ID_MMFR0_EL1, InnerShr, 28, 4)
+ IDREG_FIELD(ID_MMFR0_EL1, FCSE, 24, 4)
+ IDREG_FIELD(ID_MMFR0_EL1, AuxReg, 20, 4)
+ IDREG_FIELD(ID_MMFR0_EL1, TCM, 16, 4)
+ IDREG_FIELD(ID_MMFR0_EL1, ShareLvl, 12, 4)
+ IDREG_FIELD(ID_MMFR0_EL1, OuterShr, 8, 4)
+ IDREG_FIELD(ID_MMFR0_EL1, PMSA, 4, 4)
+ IDREG_FIELD(ID_MMFR0_EL1, VMSA, 0, 4)
+IDREG_END(ID_MMFR0_EL1)
+
+IDREG_START(ID_MMFR1_EL1)
+ IDREG_FIELD(ID_MMFR1_EL1, BPred, 28, 4)
+ IDREG_FIELD(ID_MMFR1_EL1, L1TstCln, 24, 4)
+ IDREG_FIELD(ID_MMFR1_EL1, L1Uni, 20, 4)
+ IDREG_FIELD(ID_MMFR1_EL1, L1Hvd, 16, 4)
+ IDREG_FIELD(ID_MMFR1_EL1, L1UniSW, 12, 4)
+ IDREG_FIELD(ID_MMFR1_EL1, L1HvdSW, 8, 4)
+ IDREG_FIELD(ID_MMFR1_EL1, L1UniVA, 4, 4)
+ IDREG_FIELD(ID_MMFR1_EL1, L1HvdVA, 0, 4)
+IDREG_END(ID_MMFR1_EL1)
+
+IDREG_START(ID_MMFR2_EL1)
+ IDREG_FIELD(ID_MMFR2_EL1, HWAccFlg, 28, 4)
+ IDREG_FIELD(ID_MMFR2_EL1, WFIStall, 24, 4)
+ IDREG_FIELD(ID_MMFR2_EL1, MemBarr, 20, 4)
+ IDREG_FIELD(ID_MMFR2_EL1, UniTLB, 16, 4)
+ IDREG_FIELD(ID_MMFR2_EL1, HvdTLB, 12, 4)
+ IDREG_FIELD(ID_MMFR2_EL1, L1HvdRng, 8, 4)
+ IDREG_FIELD(ID_MMFR2_EL1, L1HvdBG, 4, 4)
+ IDREG_FIELD(ID_MMFR2_EL1, L1HvdFG, 0, 4)
+IDREG_END(ID_MMFR2_EL1)
+
+IDREG_START(ID_MMFR3_EL1)
+ IDREG_FIELD(ID_MMFR3_EL1, Supersec, 28, 4)
+ IDREG_FIELD(ID_MMFR3_EL1, CMemSz, 24, 4)
+ IDREG_FIELD(ID_MMFR3_EL1, CohWalk, 20, 4)
+ IDREG_FIELD(ID_MMFR3_EL1, PAN, 16, 4)
+ IDREG_FIELD(ID_MMFR3_EL1, MaintBcst, 12, 4)
+ IDREG_FIELD(ID_MMFR3_EL1, BPMaint, 8, 4)
+ IDREG_FIELD(ID_MMFR3_EL1, CMaintSW, 4, 4)
+ IDREG_FIELD(ID_MMFR3_EL1, CMaintVA, 0, 4)
+IDREG_END(ID_MMFR3_EL1)
+
+IDREG_START(ID_MMFR4_EL1)
+ IDREG_FIELD(ID_MMFR4_EL1, EVT, 28, 4)
+ IDREG_FIELD(ID_MMFR4_EL1, CCIDX, 24, 4)
+ IDREG_FIELD(ID_MMFR4_EL1, LSM, 20, 4)
+ IDREG_FIELD(ID_MMFR4_EL1, HPDS, 16, 4)
+ IDREG_FIELD(ID_MMFR4_EL1, CnP, 12, 4)
+ IDREG_FIELD(ID_MMFR4_EL1, XNX, 8, 4)
+ IDREG_FIELD(ID_MMFR4_EL1, AC2, 4, 4)
+ IDREG_FIELD(ID_MMFR4_EL1, SpecSEI, 0, 4)
+IDREG_END(ID_MMFR4_EL1)
+
+IDREG_START(ID_MMFR5_EL1)
+ IDREG_FIELD(ID_MMFR5_EL1, nTLBPA, 4, 4)
+ IDREG_FIELD(ID_MMFR5_EL1, ETS, 0, 4)
+IDREG_END(ID_MMFR5_EL1)
+
+IDREG_START(ID_PFR0_EL1)
+ IDREG_FIELD(ID_PFR0_EL1, RAS, 28, 4)
+ IDREG_FIELD(ID_PFR0_EL1, DIT, 24, 4)
+ IDREG_FIELD(ID_PFR0_EL1, AMU, 20, 4)
+ IDREG_FIELD(ID_PFR0_EL1, CSV2, 16, 4)
+ IDREG_FIELD(ID_PFR0_EL1, State3, 12, 4)
+ IDREG_FIELD(ID_PFR0_EL1, State2, 8, 4)
+ IDREG_FIELD(ID_PFR0_EL1, State1, 4, 4)
+ IDREG_FIELD(ID_PFR0_EL1, State0, 0, 4)
+IDREG_END(ID_PFR0_EL1)
+
+IDREG_START(ID_PFR1_EL1)
+ IDREG_FIELD(ID_PFR1_EL1, GIC, 28, 4)
+ IDREG_FIELD(ID_PFR1_EL1, Virt_frac, 24, 4)
+ IDREG_FIELD(ID_PFR1_EL1, Sec_frac, 20, 4)
+ IDREG_FIELD(ID_PFR1_EL1, GenTimer, 16, 4)
+ IDREG_FIELD(ID_PFR1_EL1, Virtualization, 12, 4)
+ IDREG_FIELD(ID_PFR1_EL1, MProgMod, 8, 4)
+ IDREG_FIELD(ID_PFR1_EL1, Security, 4, 4)
+ IDREG_FIELD(ID_PFR1_EL1, ProgMod, 0, 4)
+IDREG_END(ID_PFR1_EL1)
+
+IDREG_START(ID_PFR2_EL1)
+ IDREG_FIELD(ID_PFR2_EL1, RAS_frac, 8, 4)
+ IDREG_FIELD(ID_PFR2_EL1, SSBS, 4, 4)
+ IDREG_FIELD(ID_PFR2_EL1, CSV3, 0, 4)
+IDREG_END(ID_PFR2_EL1)
+
+IDREG_START(MIDR_EL1)
+ IDREG_FIELD(MIDR_EL1, Implementer, 24, 8)
+ IDREG_FIELD(MIDR_EL1, Variant, 20, 4)
+ IDREG_FIELD(MIDR_EL1, Architecture, 16, 4)
+ IDREG_FIELD(MIDR_EL1, PartNum, 4, 12)
+ IDREG_FIELD(MIDR_EL1, Revision, 0, 4)
+IDREG_END(MIDR_EL1)
+
+IDREG_START(MPIDR_EL1)
+ IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
+ IDREG_FIELD(MPIDR_EL1, U, 30, 1)
+ IDREG_FIELD(MPIDR_EL1, MT, 24, 1)
+ IDREG_FIELD(MPIDR_EL1, Aff2, 16, 8)
+ IDREG_FIELD(MPIDR_EL1, Aff1, 8, 8)
+ IDREG_FIELD(MPIDR_EL1, Aff0, 0, 8)
+IDREG_END(MPIDR_EL1)
+
+IDREG_START(MVFR0_EL1)
+ IDREG_FIELD(MVFR0_EL1, FPRound, 28, 4)
+ IDREG_FIELD(MVFR0_EL1, FPShVec, 24, 4)
+ IDREG_FIELD(MVFR0_EL1, FPSqrt, 20, 4)
+ IDREG_FIELD(MVFR0_EL1, FPDivide, 16, 4)
+ IDREG_FIELD(MVFR0_EL1, FPTrap, 12, 4)
+ IDREG_FIELD(MVFR0_EL1, FPDP, 8, 4)
+ IDREG_FIELD(MVFR0_EL1, FPSP, 4, 4)
+ IDREG_FIELD(MVFR0_EL1, SIMDReg, 0, 4)
+IDREG_END(MVFR0_EL1)
+
+IDREG_START(MVFR1_EL1)
+ IDREG_FIELD(MVFR1_EL1, SIMDFMAC, 28, 4)
+ IDREG_FIELD(MVFR1_EL1, FPHP, 24, 4)
+ IDREG_FIELD(MVFR1_EL1, SIMDHP, 20, 4)
+ IDREG_FIELD(MVFR1_EL1, SIMDSP, 16, 4)
+ IDREG_FIELD(MVFR1_EL1, SIMDInt, 12, 4)
+ IDREG_FIELD(MVFR1_EL1, SIMDLS, 8, 4)
+ IDREG_FIELD(MVFR1_EL1, FPDNaN, 4, 4)
+ IDREG_FIELD(MVFR1_EL1, FPFtZ, 0, 4)
+IDREG_END(MVFR1_EL1)
+
+IDREG_START(MVFR2_EL1)
+ IDREG_FIELD(MVFR2_EL1, FPMisc, 4, 4)
+ IDREG_FIELD(MVFR2_EL1, SIMDMisc, 0, 4)
+IDREG_END(MVFR2_EL1)
+
+IDREG_START(REVIDR_EL1)
+IDREG_END(REVIDR_EL1)
+
+IDREG_START(SMIDR_EL1)
+ IDREG_FIELD(SMIDR_EL1, NSMC, 56, 4)
+ IDREG_FIELD(SMIDR_EL1, HIP, 52, 4)
+ IDREG_FIELD(SMIDR_EL1, Affinity2, 32, 20)
+ IDREG_FIELD(SMIDR_EL1, Implementer, 24, 8)
+ IDREG_FIELD(SMIDR_EL1, Revision, 16, 8)
+ IDREG_FIELD(SMIDR_EL1, SMPS, 15, 1)
+ IDREG_FIELD(SMIDR_EL1, SH, 13, 2)
+ IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
+IDREG_END(SMIDR_EL1)
+
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 08/26] target/arm/cpu-idregs.h.inc: Generate enum values
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (6 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 07/26] target/arm/cpu-idregs.h.inc: generate with script Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-25 11:59 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 09/26] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields Eric Auger
` (17 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Modify the python script so that enum values are also
extracted from Registers.json.
If enum values are found, the field and its enum values are
defined within IDREG_FIELD_START/END. Each enum value is
defined with IDREG_FIELD_ARCH_VAL() macro.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
v7 -> v8:
Properly handle ValueRange
---
target/arm/cpu-idregs.h.inc | 2657 ++++++++++++++---
.../update-aarch64-cpu-sysreg-properties.py | 86 +-
2 files changed, 2332 insertions(+), 411 deletions(-)
diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
index c9745e2fb6..10ddfdf43a 100644
--- a/target/arm/cpu-idregs.h.inc
+++ b/target/arm/cpu-idregs.h.inc
@@ -4,7 +4,11 @@
/* IDREG_START(REG) */
/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */
+/* or for fields with enum values */
+/* IDREG_FIELD_START(REG, FIELD, SHIFT, LENGTH) */
+/* IDREG_FIELD_ARCH_VAL(VALUE) */
/* ... */
+/* IDREG_FIELD_END(REG, FIELD) */
/* IDREG_END(REG) */
IDREG_START(AIDR_EL1)
@@ -18,7 +22,16 @@ IDREG_START(CLIDR_EL1)
IDREG_FIELD(CLIDR_EL1, Ttype3, 37, 2)
IDREG_FIELD(CLIDR_EL1, Ttype2, 35, 2)
IDREG_FIELD(CLIDR_EL1, Ttype1, 33, 2)
- IDREG_FIELD(CLIDR_EL1, ICB, 30, 3)
+ IDREG_FIELD_START(CLIDR_EL1, ICB, 30, 3)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_END(CLIDR_EL1, ICB)
IDREG_FIELD(CLIDR_EL1, LoUU, 27, 3)
IDREG_FIELD(CLIDR_EL1, LoC, 24, 3)
IDREG_FIELD(CLIDR_EL1, LoUIS, 21, 3)
@@ -33,12 +46,23 @@ IDREG_END(CLIDR_EL1)
IDREG_START(CTR_EL0)
IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
- IDREG_FIELD(CTR_EL0, DIC, 29, 1)
- IDREG_FIELD(CTR_EL0, IDC, 28, 1)
+ IDREG_FIELD_START(CTR_EL0, DIC, 29, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(CTR_EL0, DIC)
+ IDREG_FIELD_START(CTR_EL0, IDC, 28, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(CTR_EL0, IDC)
IDREG_FIELD(CTR_EL0, CWG, 24, 4)
IDREG_FIELD(CTR_EL0, ERG, 20, 4)
IDREG_FIELD(CTR_EL0, DminLine, 16, 4)
- IDREG_FIELD(CTR_EL0, L1Ip, 14, 2)
+ IDREG_FIELD_START(CTR_EL0, L1Ip, 14, 2)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(CTR_EL0, L1Ip)
IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
IDREG_END(CTR_EL0)
@@ -59,549 +83,2368 @@ IDREG_START(ID_AA64AFR1_EL1)
IDREG_END(ID_AA64AFR1_EL1)
IDREG_START(ID_AA64DFR0_EL1)
- IDREG_FIELD(ID_AA64DFR0_EL1, HPMN0, 60, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, BRBE, 52, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, MTPMU, 48, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, PMSVer, 32, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, WRPs, 20, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, PMSS, 16, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, BRPs, 12, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, PMUVer, 8, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, TraceVer, 4, 4)
- IDREG_FIELD(ID_AA64DFR0_EL1, DebugVer, 0, 4)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, HPMN0, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, HPMN0)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, ExtTrcBuff)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, BRBE, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, BRBE)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, MTPMU, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, MTPMU)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, TraceBuffer)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, TraceFilt)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, DoubleLock)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, PMSVer, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, PMSVer)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, CTX_CMPs)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, WRPs, 20, 4)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, WRPs)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, PMSS, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, PMSS)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, BRPs, 12, 4)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, BRPs)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, PMUVer, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, PMUVer)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, TraceVer, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, TraceVer)
+ IDREG_FIELD_START(ID_AA64DFR0_EL1, DebugVer, 0, 4)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_END(ID_AA64DFR0_EL1, DebugVer)
IDREG_END(ID_AA64DFR0_EL1)
IDREG_START(ID_AA64DFR1_EL1)
- IDREG_FIELD(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
- IDREG_FIELD(ID_AA64DFR1_EL1, DPFZS, 52, 4)
- IDREG_FIELD(ID_AA64DFR1_EL1, EBEP, 48, 4)
- IDREG_FIELD(ID_AA64DFR1_EL1, ITE, 44, 4)
- IDREG_FIELD(ID_AA64DFR1_EL1, ABLE, 40, 4)
- IDREG_FIELD(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
- IDREG_FIELD(ID_AA64DFR1_EL1, SPMU, 32, 4)
- IDREG_FIELD(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
- IDREG_FIELD(ID_AA64DFR1_EL1, WRPs, 16, 8)
- IDREG_FIELD(ID_AA64DFR1_EL1, BRPs, 8, 8)
- IDREG_FIELD(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_ARCH_VAL(16)
+ IDREG_FIELD_ARCH_VAL(17)
+ IDREG_FIELD_ARCH_VAL(18)
+ IDREG_FIELD_ARCH_VAL(19)
+ IDREG_FIELD_ARCH_VAL(20)
+ IDREG_FIELD_ARCH_VAL(21)
+ IDREG_FIELD_ARCH_VAL(22)
+ IDREG_FIELD_ARCH_VAL(23)
+ IDREG_FIELD_ARCH_VAL(24)
+ IDREG_FIELD_ARCH_VAL(25)
+ IDREG_FIELD_ARCH_VAL(26)
+ IDREG_FIELD_ARCH_VAL(27)
+ IDREG_FIELD_ARCH_VAL(28)
+ IDREG_FIELD_ARCH_VAL(29)
+ IDREG_FIELD_ARCH_VAL(30)
+ IDREG_FIELD_ARCH_VAL(31)
+ IDREG_FIELD_ARCH_VAL(32)
+ IDREG_FIELD_ARCH_VAL(33)
+ IDREG_FIELD_ARCH_VAL(34)
+ IDREG_FIELD_ARCH_VAL(35)
+ IDREG_FIELD_ARCH_VAL(36)
+ IDREG_FIELD_ARCH_VAL(37)
+ IDREG_FIELD_ARCH_VAL(38)
+ IDREG_FIELD_ARCH_VAL(39)
+ IDREG_FIELD_ARCH_VAL(40)
+ IDREG_FIELD_ARCH_VAL(41)
+ IDREG_FIELD_ARCH_VAL(42)
+ IDREG_FIELD_ARCH_VAL(43)
+ IDREG_FIELD_ARCH_VAL(44)
+ IDREG_FIELD_ARCH_VAL(45)
+ IDREG_FIELD_ARCH_VAL(46)
+ IDREG_FIELD_ARCH_VAL(47)
+ IDREG_FIELD_ARCH_VAL(48)
+ IDREG_FIELD_ARCH_VAL(49)
+ IDREG_FIELD_ARCH_VAL(50)
+ IDREG_FIELD_ARCH_VAL(51)
+ IDREG_FIELD_ARCH_VAL(52)
+ IDREG_FIELD_ARCH_VAL(53)
+ IDREG_FIELD_ARCH_VAL(54)
+ IDREG_FIELD_ARCH_VAL(55)
+ IDREG_FIELD_ARCH_VAL(56)
+ IDREG_FIELD_ARCH_VAL(57)
+ IDREG_FIELD_ARCH_VAL(58)
+ IDREG_FIELD_ARCH_VAL(59)
+ IDREG_FIELD_ARCH_VAL(60)
+ IDREG_FIELD_ARCH_VAL(61)
+ IDREG_FIELD_ARCH_VAL(62)
+ IDREG_FIELD_ARCH_VAL(63)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, ABL_CMPs)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, DPFZS, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, DPFZS)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, EBEP, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, EBEP)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, ITE, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, ITE)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, ABLE, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, ABLE)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, PMICNTR)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, SPMU, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, SPMU)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_ARCH_VAL(16)
+ IDREG_FIELD_ARCH_VAL(17)
+ IDREG_FIELD_ARCH_VAL(18)
+ IDREG_FIELD_ARCH_VAL(19)
+ IDREG_FIELD_ARCH_VAL(20)
+ IDREG_FIELD_ARCH_VAL(21)
+ IDREG_FIELD_ARCH_VAL(22)
+ IDREG_FIELD_ARCH_VAL(23)
+ IDREG_FIELD_ARCH_VAL(24)
+ IDREG_FIELD_ARCH_VAL(25)
+ IDREG_FIELD_ARCH_VAL(26)
+ IDREG_FIELD_ARCH_VAL(27)
+ IDREG_FIELD_ARCH_VAL(28)
+ IDREG_FIELD_ARCH_VAL(29)
+ IDREG_FIELD_ARCH_VAL(30)
+ IDREG_FIELD_ARCH_VAL(31)
+ IDREG_FIELD_ARCH_VAL(32)
+ IDREG_FIELD_ARCH_VAL(33)
+ IDREG_FIELD_ARCH_VAL(34)
+ IDREG_FIELD_ARCH_VAL(35)
+ IDREG_FIELD_ARCH_VAL(36)
+ IDREG_FIELD_ARCH_VAL(37)
+ IDREG_FIELD_ARCH_VAL(38)
+ IDREG_FIELD_ARCH_VAL(39)
+ IDREG_FIELD_ARCH_VAL(40)
+ IDREG_FIELD_ARCH_VAL(41)
+ IDREG_FIELD_ARCH_VAL(42)
+ IDREG_FIELD_ARCH_VAL(43)
+ IDREG_FIELD_ARCH_VAL(44)
+ IDREG_FIELD_ARCH_VAL(45)
+ IDREG_FIELD_ARCH_VAL(46)
+ IDREG_FIELD_ARCH_VAL(47)
+ IDREG_FIELD_ARCH_VAL(48)
+ IDREG_FIELD_ARCH_VAL(49)
+ IDREG_FIELD_ARCH_VAL(50)
+ IDREG_FIELD_ARCH_VAL(51)
+ IDREG_FIELD_ARCH_VAL(52)
+ IDREG_FIELD_ARCH_VAL(53)
+ IDREG_FIELD_ARCH_VAL(54)
+ IDREG_FIELD_ARCH_VAL(55)
+ IDREG_FIELD_ARCH_VAL(56)
+ IDREG_FIELD_ARCH_VAL(57)
+ IDREG_FIELD_ARCH_VAL(58)
+ IDREG_FIELD_ARCH_VAL(59)
+ IDREG_FIELD_ARCH_VAL(60)
+ IDREG_FIELD_ARCH_VAL(61)
+ IDREG_FIELD_ARCH_VAL(62)
+ IDREG_FIELD_ARCH_VAL(63)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, CTX_CMPs)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, WRPs, 16, 8)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_ARCH_VAL(16)
+ IDREG_FIELD_ARCH_VAL(17)
+ IDREG_FIELD_ARCH_VAL(18)
+ IDREG_FIELD_ARCH_VAL(19)
+ IDREG_FIELD_ARCH_VAL(20)
+ IDREG_FIELD_ARCH_VAL(21)
+ IDREG_FIELD_ARCH_VAL(22)
+ IDREG_FIELD_ARCH_VAL(23)
+ IDREG_FIELD_ARCH_VAL(24)
+ IDREG_FIELD_ARCH_VAL(25)
+ IDREG_FIELD_ARCH_VAL(26)
+ IDREG_FIELD_ARCH_VAL(27)
+ IDREG_FIELD_ARCH_VAL(28)
+ IDREG_FIELD_ARCH_VAL(29)
+ IDREG_FIELD_ARCH_VAL(30)
+ IDREG_FIELD_ARCH_VAL(31)
+ IDREG_FIELD_ARCH_VAL(32)
+ IDREG_FIELD_ARCH_VAL(33)
+ IDREG_FIELD_ARCH_VAL(34)
+ IDREG_FIELD_ARCH_VAL(35)
+ IDREG_FIELD_ARCH_VAL(36)
+ IDREG_FIELD_ARCH_VAL(37)
+ IDREG_FIELD_ARCH_VAL(38)
+ IDREG_FIELD_ARCH_VAL(39)
+ IDREG_FIELD_ARCH_VAL(40)
+ IDREG_FIELD_ARCH_VAL(41)
+ IDREG_FIELD_ARCH_VAL(42)
+ IDREG_FIELD_ARCH_VAL(43)
+ IDREG_FIELD_ARCH_VAL(44)
+ IDREG_FIELD_ARCH_VAL(45)
+ IDREG_FIELD_ARCH_VAL(46)
+ IDREG_FIELD_ARCH_VAL(47)
+ IDREG_FIELD_ARCH_VAL(48)
+ IDREG_FIELD_ARCH_VAL(49)
+ IDREG_FIELD_ARCH_VAL(50)
+ IDREG_FIELD_ARCH_VAL(51)
+ IDREG_FIELD_ARCH_VAL(52)
+ IDREG_FIELD_ARCH_VAL(53)
+ IDREG_FIELD_ARCH_VAL(54)
+ IDREG_FIELD_ARCH_VAL(55)
+ IDREG_FIELD_ARCH_VAL(56)
+ IDREG_FIELD_ARCH_VAL(57)
+ IDREG_FIELD_ARCH_VAL(58)
+ IDREG_FIELD_ARCH_VAL(59)
+ IDREG_FIELD_ARCH_VAL(60)
+ IDREG_FIELD_ARCH_VAL(61)
+ IDREG_FIELD_ARCH_VAL(62)
+ IDREG_FIELD_ARCH_VAL(63)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, WRPs)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, BRPs, 8, 8)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_ARCH_VAL(16)
+ IDREG_FIELD_ARCH_VAL(17)
+ IDREG_FIELD_ARCH_VAL(18)
+ IDREG_FIELD_ARCH_VAL(19)
+ IDREG_FIELD_ARCH_VAL(20)
+ IDREG_FIELD_ARCH_VAL(21)
+ IDREG_FIELD_ARCH_VAL(22)
+ IDREG_FIELD_ARCH_VAL(23)
+ IDREG_FIELD_ARCH_VAL(24)
+ IDREG_FIELD_ARCH_VAL(25)
+ IDREG_FIELD_ARCH_VAL(26)
+ IDREG_FIELD_ARCH_VAL(27)
+ IDREG_FIELD_ARCH_VAL(28)
+ IDREG_FIELD_ARCH_VAL(29)
+ IDREG_FIELD_ARCH_VAL(30)
+ IDREG_FIELD_ARCH_VAL(31)
+ IDREG_FIELD_ARCH_VAL(32)
+ IDREG_FIELD_ARCH_VAL(33)
+ IDREG_FIELD_ARCH_VAL(34)
+ IDREG_FIELD_ARCH_VAL(35)
+ IDREG_FIELD_ARCH_VAL(36)
+ IDREG_FIELD_ARCH_VAL(37)
+ IDREG_FIELD_ARCH_VAL(38)
+ IDREG_FIELD_ARCH_VAL(39)
+ IDREG_FIELD_ARCH_VAL(40)
+ IDREG_FIELD_ARCH_VAL(41)
+ IDREG_FIELD_ARCH_VAL(42)
+ IDREG_FIELD_ARCH_VAL(43)
+ IDREG_FIELD_ARCH_VAL(44)
+ IDREG_FIELD_ARCH_VAL(45)
+ IDREG_FIELD_ARCH_VAL(46)
+ IDREG_FIELD_ARCH_VAL(47)
+ IDREG_FIELD_ARCH_VAL(48)
+ IDREG_FIELD_ARCH_VAL(49)
+ IDREG_FIELD_ARCH_VAL(50)
+ IDREG_FIELD_ARCH_VAL(51)
+ IDREG_FIELD_ARCH_VAL(52)
+ IDREG_FIELD_ARCH_VAL(53)
+ IDREG_FIELD_ARCH_VAL(54)
+ IDREG_FIELD_ARCH_VAL(55)
+ IDREG_FIELD_ARCH_VAL(56)
+ IDREG_FIELD_ARCH_VAL(57)
+ IDREG_FIELD_ARCH_VAL(58)
+ IDREG_FIELD_ARCH_VAL(59)
+ IDREG_FIELD_ARCH_VAL(60)
+ IDREG_FIELD_ARCH_VAL(61)
+ IDREG_FIELD_ARCH_VAL(62)
+ IDREG_FIELD_ARCH_VAL(63)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, BRPs)
+ IDREG_FIELD_START(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_ARCH_VAL(16)
+ IDREG_FIELD_ARCH_VAL(17)
+ IDREG_FIELD_ARCH_VAL(18)
+ IDREG_FIELD_ARCH_VAL(19)
+ IDREG_FIELD_ARCH_VAL(20)
+ IDREG_FIELD_ARCH_VAL(21)
+ IDREG_FIELD_ARCH_VAL(22)
+ IDREG_FIELD_ARCH_VAL(23)
+ IDREG_FIELD_ARCH_VAL(24)
+ IDREG_FIELD_ARCH_VAL(25)
+ IDREG_FIELD_ARCH_VAL(26)
+ IDREG_FIELD_ARCH_VAL(27)
+ IDREG_FIELD_ARCH_VAL(28)
+ IDREG_FIELD_ARCH_VAL(29)
+ IDREG_FIELD_ARCH_VAL(30)
+ IDREG_FIELD_ARCH_VAL(31)
+ IDREG_FIELD_END(ID_AA64DFR1_EL1, SYSPMUID)
IDREG_END(ID_AA64DFR1_EL1)
IDREG_START(ID_AA64DFR2_EL1)
- IDREG_FIELD(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
- IDREG_FIELD(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
- IDREG_FIELD(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
- IDREG_FIELD(ID_AA64DFR2_EL1, BWE, 4, 4)
- IDREG_FIELD(ID_AA64DFR2_EL1, STEP, 0, 4)
+ IDREG_FIELD_START(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR2_EL1, TRBE_EXC)
+ IDREG_FIELD_START(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR2_EL1, SPE_nVM)
+ IDREG_FIELD_START(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR2_EL1, SPE_EXC)
+ IDREG_FIELD_START(ID_AA64DFR2_EL1, BWE, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64DFR2_EL1, BWE)
+ IDREG_FIELD_START(ID_AA64DFR2_EL1, STEP, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64DFR2_EL1, STEP)
IDREG_END(ID_AA64DFR2_EL1)
IDREG_START(ID_AA64FPFR0_EL1)
- IDREG_FIELD(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
- IDREG_FIELD(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
- IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
- IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
- IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
- IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
- IDREG_FIELD(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
- IDREG_FIELD(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
- IDREG_FIELD(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
+ IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8CVT)
+ IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8FMA)
+ IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8DP4)
+ IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8DP2)
+ IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8MM8)
+ IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8MM4)
+ IDREG_FIELD_START(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64FPFR0_EL1, F16MM2)
+ IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8E4M3)
+ IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8E5M2)
IDREG_END(ID_AA64FPFR0_EL1)
IDREG_START(ID_AA64ISAR0_EL1)
- IDREG_FIELD(ID_AA64ISAR0_EL1, RNDR, 60, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, TLB, 56, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, TS, 52, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, FHM, 48, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, DP, 44, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, SM4, 40, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, SM3, 36, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, SHA3, 32, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, RDM, 28, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, Atomic, 20, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, CRC32, 16, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, SHA2, 12, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, SHA1, 8, 4)
- IDREG_FIELD(ID_AA64ISAR0_EL1, AES, 4, 4)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, RNDR, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, RNDR)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, TLB, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, TLB)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, TS, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, TS)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, FHM, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, FHM)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, DP, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, DP)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, SM4, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, SM4)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, SM3, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, SM3)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, SHA3, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, SHA3)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, RDM, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, RDM)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, Atomic, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, Atomic)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, CRC32, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, CRC32)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, SHA2, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, SHA2)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, SHA1, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, SHA1)
+ IDREG_FIELD_START(ID_AA64ISAR0_EL1, AES, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR0_EL1, AES)
IDREG_END(ID_AA64ISAR0_EL1)
IDREG_START(ID_AA64ISAR1_EL1)
- IDREG_FIELD(ID_AA64ISAR1_EL1, LS64, 60, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, XS, 56, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, I8MM, 52, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, DGH, 48, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, BF16, 44, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, SB, 36, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, GPI, 28, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, GPA, 24, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, FCMA, 16, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, API, 8, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, APA, 4, 4)
- IDREG_FIELD(ID_AA64ISAR1_EL1, DPB, 0, 4)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, LS64, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, LS64)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, XS, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, XS)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, I8MM, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, I8MM)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, DGH, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, DGH)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, BF16, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, BF16)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, SPECRES)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, SB, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, SB)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, FRINTTS)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, GPI, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, GPI)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, GPA, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, GPA)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, LRCPC)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, FCMA, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, FCMA)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, JSCVT)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, API, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, API)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, APA, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, APA)
+ IDREG_FIELD_START(ID_AA64ISAR1_EL1, DPB, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR1_EL1, DPB)
IDREG_END(ID_AA64ISAR1_EL1)
IDREG_START(ID_AA64ISAR2_EL1)
- IDREG_FIELD(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, LUT, 56, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, CSSC, 52, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, BC, 20, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, MOPS, 16, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, APA3, 12, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, GPA3, 8, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, RPRES, 4, 4)
- IDREG_FIELD(ID_AA64ISAR2_EL1, WFxT, 0, 4)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, ATS1A)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, LUT, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, LUT)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, CSSC, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, CSSC)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, RPRFM)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, PCDPHINT)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, PRFMSLC)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, SYSINSTR_128)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, SYSREG_128)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, CLRBHB)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, PAC_frac)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, BC, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, BC)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, MOPS, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, MOPS)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, APA3, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, APA3)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, GPA3, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, GPA3)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, RPRES, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, RPRES)
+ IDREG_FIELD_START(ID_AA64ISAR2_EL1, WFxT, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR2_EL1, WFxT)
IDREG_END(ID_AA64ISAR2_EL1)
IDREG_START(ID_AA64ISAR3_EL1)
- IDREG_FIELD(ID_AA64ISAR3_EL1, LSCP, 44, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, MTETC, 36, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, LSUI, 24, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, LSFE, 16, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, PACM, 12, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
- IDREG_FIELD(ID_AA64ISAR3_EL1, CPA, 0, 4)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSCP, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSCP)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSCSHINT)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, MTETC, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, MTETC)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, PAC_frac2)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, FPRCVT)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSUI, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSUI)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, OCCMO)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSFE, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSFE)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, PACM, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, PACM)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, TLBIW)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, FAMINMAX)
+ IDREG_FIELD_START(ID_AA64ISAR3_EL1, CPA, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ISAR3_EL1, CPA)
IDREG_END(ID_AA64ISAR3_EL1)
IDREG_START(ID_AA64MMFR0_EL1)
- IDREG_FIELD(ID_AA64MMFR0_EL1, ECV, 60, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, FGT, 56, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, ExS, 44, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4, 28, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64, 24, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16, 20, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
- IDREG_FIELD(ID_AA64MMFR0_EL1, PARange, 0, 4)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, ECV, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, ECV)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, FGT, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, FGT)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, ExS, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, ExS)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran4_2)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran64_2)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran16_2)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran4, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran4)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran64, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran64)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran16, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran16)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, BigEndEL0)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, SNSMem)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, BigEnd)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, ASIDBits)
+ IDREG_FIELD_START(ID_AA64MMFR0_EL1, PARange, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_END(ID_AA64MMFR0_EL1, PARange)
IDREG_END(ID_AA64MMFR0_EL1)
IDREG_START(ID_AA64MMFR1_EL1)
- IDREG_FIELD(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, CMOW, 56, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, AFP, 44, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, HCX, 40, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, ETS, 36, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, TWED, 32, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, XNX, 28, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, PAN, 20, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, LO, 16, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, HPDS, 12, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, VH, 8, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
- IDREG_FIELD(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, ECBHB)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, CMOW, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, CMOW)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, TIDCP1)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, nTLBPA)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, AFP, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, AFP)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, HCX, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, HCX)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, ETS, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, ETS)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, TWED, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, TWED)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, XNX, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, XNX)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, SpecSEI)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, PAN, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, PAN)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, LO, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, LO)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, HPDS, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, HPDS)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, VH, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, VH)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, VMIDBits)
+ IDREG_FIELD_START(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_END(ID_AA64MMFR1_EL1, HAFDBS)
IDREG_END(ID_AA64MMFR1_EL1)
IDREG_START(ID_AA64MMFR2_EL1)
- IDREG_FIELD(ID_AA64MMFR2_EL1, E0PD, 60, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, EVT, 56, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, BBM, 52, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, TTL, 48, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, FWB, 40, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, IDS, 36, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, AT, 32, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, ST, 28, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, NV, 24, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, VARange, 16, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, IESB, 12, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, LSM, 8, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, UAO, 4, 4)
- IDREG_FIELD(ID_AA64MMFR2_EL1, CnP, 0, 4)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, E0PD, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, E0PD)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, EVT, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, EVT)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, BBM, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, BBM)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, TTL, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, TTL)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, FWB, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, FWB)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, IDS, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, IDS)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, AT, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, AT)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, ST, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, ST)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, NV, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, NV)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, CCIDX)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, VARange, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, VARange)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, IESB, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, IESB)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, LSM, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, LSM)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, UAO, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, UAO)
+ IDREG_FIELD_START(ID_AA64MMFR2_EL1, CnP, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR2_EL1, CnP)
IDREG_END(ID_AA64MMFR2_EL1)
IDREG_START(ID_AA64MMFR3_EL1)
- IDREG_FIELD(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, ADERR, 56, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, SDERR, 52, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, ANERR, 44, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, SNERR, 40, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, D128_2, 36, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, D128, 32, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, MEC, 28, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, AIE, 24, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, S2POE, 20, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, S1POE, 16, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
- IDREG_FIELD(ID_AA64MMFR3_EL1, TCRX, 0, 4)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, Spec_FPACC)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, ADERR, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, ADERR)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, SDERR, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, SDERR)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, ANERR, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, ANERR)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, SNERR, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, SNERR)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, D128_2, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, D128_2)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, D128, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, D128)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, MEC, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, MEC)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, AIE, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, AIE)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, S2POE, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, S2POE)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, S1POE, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, S1POE)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, S2PIE)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, S1PIE)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, SCTLRX)
+ IDREG_FIELD_START(ID_AA64MMFR3_EL1, TCRX, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR3_EL1, TCRX)
IDREG_END(ID_AA64MMFR3_EL1)
IDREG_START(ID_AA64MMFR4_EL1)
- IDREG_FIELD(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, SCRX, 56, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, TEV, 52, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, TPS, 48, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, TLBID, 40, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, EAESR, 32, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, E2H0, 24, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, ASID2, 8, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, EIESB, 4, 4)
- IDREG_FIELD(ID_AA64MMFR4_EL1, PoPS, 0, 4)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, MTEFGT)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, SCRX, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, SCRX)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, TEV, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, TEV)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, TPS, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, TPS)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, SRMASK)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, TLBID, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, TLBID)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, E3DSE)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, EAESR, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, EAESR)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, RMEGDI)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, E2H0, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, E2H0)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, NV_frac)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, FGWTE3)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, HACDBS)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, ASID2, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, ASID2)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, EIESB, 4, 4)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, EIESB)
+ IDREG_FIELD_START(ID_AA64MMFR4_EL1, PoPS, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64MMFR4_EL1, PoPS)
IDREG_END(ID_AA64MMFR4_EL1)
IDREG_START(ID_AA64PFR0_EL1)
- IDREG_FIELD(ID_AA64PFR0_EL1, CSV3, 60, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, CSV2, 56, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, RME, 52, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, DIT, 48, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, AMU, 44, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, MPAM, 40, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, SEL2, 36, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, SVE, 32, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, RAS, 28, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, GIC, 24, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, FP, 16, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, EL3, 12, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, EL2, 8, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, EL1, 4, 4)
- IDREG_FIELD(ID_AA64PFR0_EL1, EL0, 0, 4)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, CSV3, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, CSV3)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, CSV2, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, CSV2)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, RME, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, RME)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, DIT, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, DIT)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, AMU, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, AMU)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, MPAM, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, MPAM)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, SEL2, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, SEL2)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, SVE, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, SVE)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, RAS, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, RAS)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, GIC, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, GIC)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, AdvSIMD)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, FP, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, FP)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, EL3, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, EL3)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, EL2, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, EL2)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, EL1, 4, 4)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, EL1)
+ IDREG_FIELD_START(ID_AA64PFR0_EL1, EL0, 0, 4)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR0_EL1, EL0)
IDREG_END(ID_AA64PFR0_EL1)
IDREG_START(ID_AA64PFR1_EL1)
- IDREG_FIELD(ID_AA64PFR1_EL1, PFAR, 60, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, DF2, 56, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, MTEX, 52, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, THE, 48, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, GCS, 44, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, NMI, 36, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, SME, 24, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, MTE, 8, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, SSBS, 4, 4)
- IDREG_FIELD(ID_AA64PFR1_EL1, BT, 0, 4)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, PFAR, 60, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, PFAR)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, DF2, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, DF2)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, MTEX, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, MTEX)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, THE, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, THE)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, GCS, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, GCS)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, MTE_frac)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, NMI, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, NMI)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, CSV2_frac)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, RNDR_trap)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, SME, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, SME)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, MPAM_frac)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, RAS_frac)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, MTE, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, MTE)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, SSBS, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, SSBS)
+ IDREG_FIELD_START(ID_AA64PFR1_EL1, BT, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR1_EL1, BT)
IDREG_END(ID_AA64PFR1_EL1)
IDREG_START(ID_AA64PFR2_EL1)
- IDREG_FIELD(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, VMTETC, 40, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, VMTE, 36, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, FPMR, 32, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, MPAM2, 28, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, FGDT, 24, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, UINJ, 16, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, GCIE, 12, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
- IDREG_FIELD(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, VMTETCL)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTETC, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, VMTETC)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTE, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, VMTE)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, FPMR, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, FPMR)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, MPAM2, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, MPAM2)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, FGDT, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, FGDT)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, MTEEIRG)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, UINJ, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, UINJ)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, GCIE, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, GCIE)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, MTEFAR)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, MTESTOREONLY)
+ IDREG_FIELD_START(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64PFR2_EL1, MTEPERM)
IDREG_END(ID_AA64PFR2_EL1)
IDREG_START(ID_AA64SMFR0_EL1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, FA64, 63, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, LUT6, 61, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, SMEver, 56, 4)
- IDREG_FIELD(ID_AA64SMFR0_EL1, I16I64, 52, 4)
- IDREG_FIELD(ID_AA64SMFR0_EL1, F64F64, 48, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, I16I32, 44, 4)
- IDREG_FIELD(ID_AA64SMFR0_EL1, B16B16, 43, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, F16F16, 42, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, F8F16, 41, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, F8F32, 40, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, I8I32, 36, 4)
- IDREG_FIELD(ID_AA64SMFR0_EL1, F16F32, 35, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, B16F32, 34, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, F32F32, 32, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, AES, 24, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, STMOP, 16, 1)
- IDREG_FIELD(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, FA64, 63, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, FA64)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, LUT6, 61, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, LUT6)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, LUTv2)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, SMEver, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, SMEver)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, I16I64, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, I16I64)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, F64F64, 48, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, F64F64)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, I16I32, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, I16I32)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, B16B16, 43, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, B16B16)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, F16F16, 42, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, F16F16)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, F8F16, 41, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, F8F16)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, F8F32, 40, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, F8F32)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, I8I32, 36, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, I8I32)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, F16F32, 35, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, F16F32)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, B16F32, 34, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, B16F32)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, BI32I32)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, F32F32, 32, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, F32F32)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8FMA)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8DP4)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8DP2)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, SBitPerm)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, AES, 24, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, AES)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, SFEXPA)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, STMOP, 16, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, STMOP)
+ IDREG_FIELD_START(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64SMFR0_EL1, SMOP4)
IDREG_END(ID_AA64SMFR0_EL1)
IDREG_START(ID_AA64ZFR0_EL1)
- IDREG_FIELD(ID_AA64ZFR0_EL1, F64MM, 56, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, F32MM, 52, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, F16MM, 48, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, I8MM, 44, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, SM4, 40, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, SHA3, 32, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, B16B16, 24, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, BF16, 20, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, AES, 4, 4)
- IDREG_FIELD(ID_AA64ZFR0_EL1, SVEver, 0, 4)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, F64MM, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, F64MM)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, F32MM, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, F32MM)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, F16MM, 48, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, F16MM)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, I8MM, 44, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, I8MM)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, SM4, 40, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, SM4)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, SHA3, 32, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, SHA3)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, B16B16, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, B16B16)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, BF16, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, BF16)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, BitPerm)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, EltPerm)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, AES, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, AES)
+ IDREG_FIELD_START(ID_AA64ZFR0_EL1, SVEver, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_END(ID_AA64ZFR0_EL1, SVEver)
IDREG_END(ID_AA64ZFR0_EL1)
IDREG_START(ID_AFR0_EL1)
IDREG_END(ID_AFR0_EL1)
IDREG_START(ID_DFR0_EL1)
- IDREG_FIELD(ID_DFR0_EL1, TraceFilt, 28, 4)
- IDREG_FIELD(ID_DFR0_EL1, PerfMon, 24, 4)
- IDREG_FIELD(ID_DFR0_EL1, MProfDbg, 20, 4)
- IDREG_FIELD(ID_DFR0_EL1, MMapTrc, 16, 4)
- IDREG_FIELD(ID_DFR0_EL1, CopTrc, 12, 4)
- IDREG_FIELD(ID_DFR0_EL1, MMapDbg, 8, 4)
+ IDREG_FIELD_START(ID_DFR0_EL1, TraceFilt, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_DFR0_EL1, TraceFilt)
+ IDREG_FIELD_START(ID_DFR0_EL1, PerfMon, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_DFR0_EL1, PerfMon)
+ IDREG_FIELD_START(ID_DFR0_EL1, MProfDbg, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_DFR0_EL1, MProfDbg)
+ IDREG_FIELD_START(ID_DFR0_EL1, MMapTrc, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_DFR0_EL1, MMapTrc)
+ IDREG_FIELD_START(ID_DFR0_EL1, CopTrc, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_DFR0_EL1, CopTrc)
+ IDREG_FIELD_START(ID_DFR0_EL1, MMapDbg, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_END(ID_DFR0_EL1, MMapDbg)
IDREG_FIELD(ID_DFR0_EL1, CopSDbg, 4, 4)
- IDREG_FIELD(ID_DFR0_EL1, CopDbg, 0, 4)
+ IDREG_FIELD_START(ID_DFR0_EL1, CopDbg, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_END(ID_DFR0_EL1, CopDbg)
IDREG_END(ID_DFR0_EL1)
IDREG_START(ID_DFR1_EL1)
- IDREG_FIELD(ID_DFR1_EL1, HPMN0, 4, 4)
- IDREG_FIELD(ID_DFR1_EL1, MTPMU, 0, 4)
+ IDREG_FIELD_START(ID_DFR1_EL1, HPMN0, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_DFR1_EL1, HPMN0)
+ IDREG_FIELD_START(ID_DFR1_EL1, MTPMU, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_DFR1_EL1, MTPMU)
IDREG_END(ID_DFR1_EL1)
IDREG_START(ID_ISAR0_EL1)
- IDREG_FIELD(ID_ISAR0_EL1, Divide, 24, 4)
- IDREG_FIELD(ID_ISAR0_EL1, Debug, 20, 4)
- IDREG_FIELD(ID_ISAR0_EL1, Coproc, 16, 4)
- IDREG_FIELD(ID_ISAR0_EL1, CmpBranch, 12, 4)
- IDREG_FIELD(ID_ISAR0_EL1, BitField, 8, 4)
- IDREG_FIELD(ID_ISAR0_EL1, BitCount, 4, 4)
- IDREG_FIELD(ID_ISAR0_EL1, Swap, 0, 4)
+ IDREG_FIELD_START(ID_ISAR0_EL1, Divide, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR0_EL1, Divide)
+ IDREG_FIELD_START(ID_ISAR0_EL1, Debug, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR0_EL1, Debug)
+ IDREG_FIELD_START(ID_ISAR0_EL1, Coproc, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_END(ID_ISAR0_EL1, Coproc)
+ IDREG_FIELD_START(ID_ISAR0_EL1, CmpBranch, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR0_EL1, CmpBranch)
+ IDREG_FIELD_START(ID_ISAR0_EL1, BitField, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR0_EL1, BitField)
+ IDREG_FIELD_START(ID_ISAR0_EL1, BitCount, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR0_EL1, BitCount)
+ IDREG_FIELD_START(ID_ISAR0_EL1, Swap, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR0_EL1, Swap)
IDREG_END(ID_ISAR0_EL1)
IDREG_START(ID_ISAR1_EL1)
- IDREG_FIELD(ID_ISAR1_EL1, Jazelle, 28, 4)
- IDREG_FIELD(ID_ISAR1_EL1, Interwork, 24, 4)
- IDREG_FIELD(ID_ISAR1_EL1, Immediate, 20, 4)
- IDREG_FIELD(ID_ISAR1_EL1, IfThen, 16, 4)
- IDREG_FIELD(ID_ISAR1_EL1, Extend, 12, 4)
- IDREG_FIELD(ID_ISAR1_EL1, Except_AR, 8, 4)
- IDREG_FIELD(ID_ISAR1_EL1, Except, 4, 4)
- IDREG_FIELD(ID_ISAR1_EL1, Endian, 0, 4)
+ IDREG_FIELD_START(ID_ISAR1_EL1, Jazelle, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR1_EL1, Jazelle)
+ IDREG_FIELD_START(ID_ISAR1_EL1, Interwork, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_ISAR1_EL1, Interwork)
+ IDREG_FIELD_START(ID_ISAR1_EL1, Immediate, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR1_EL1, Immediate)
+ IDREG_FIELD_START(ID_ISAR1_EL1, IfThen, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR1_EL1, IfThen)
+ IDREG_FIELD_START(ID_ISAR1_EL1, Extend, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR1_EL1, Extend)
+ IDREG_FIELD_START(ID_ISAR1_EL1, Except_AR, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR1_EL1, Except_AR)
+ IDREG_FIELD_START(ID_ISAR1_EL1, Except, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR1_EL1, Except)
+ IDREG_FIELD_START(ID_ISAR1_EL1, Endian, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR1_EL1, Endian)
IDREG_END(ID_ISAR1_EL1)
IDREG_START(ID_ISAR2_EL1)
- IDREG_FIELD(ID_ISAR2_EL1, Reversal, 28, 4)
- IDREG_FIELD(ID_ISAR2_EL1, PSR_AR, 24, 4)
- IDREG_FIELD(ID_ISAR2_EL1, MultU, 20, 4)
- IDREG_FIELD(ID_ISAR2_EL1, MultS, 16, 4)
- IDREG_FIELD(ID_ISAR2_EL1, Mult, 12, 4)
- IDREG_FIELD(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
- IDREG_FIELD(ID_ISAR2_EL1, MemHint, 4, 4)
- IDREG_FIELD(ID_ISAR2_EL1, LoadStore, 0, 4)
+ IDREG_FIELD_START(ID_ISAR2_EL1, Reversal, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR2_EL1, Reversal)
+ IDREG_FIELD_START(ID_ISAR2_EL1, PSR_AR, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR2_EL1, PSR_AR)
+ IDREG_FIELD_START(ID_ISAR2_EL1, MultU, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR2_EL1, MultU)
+ IDREG_FIELD_START(ID_ISAR2_EL1, MultS, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_ISAR2_EL1, MultS)
+ IDREG_FIELD_START(ID_ISAR2_EL1, Mult, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR2_EL1, Mult)
+ IDREG_FIELD_START(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR2_EL1, MultiAccessInt)
+ IDREG_FIELD_START(ID_ISAR2_EL1, MemHint, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_END(ID_ISAR2_EL1, MemHint)
+ IDREG_FIELD_START(ID_ISAR2_EL1, LoadStore, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR2_EL1, LoadStore)
IDREG_END(ID_ISAR2_EL1)
IDREG_START(ID_ISAR3_EL1)
- IDREG_FIELD(ID_ISAR3_EL1, T32EE, 28, 4)
- IDREG_FIELD(ID_ISAR3_EL1, TrueNOP, 24, 4)
- IDREG_FIELD(ID_ISAR3_EL1, T32Copy, 20, 4)
- IDREG_FIELD(ID_ISAR3_EL1, TabBranch, 16, 4)
- IDREG_FIELD(ID_ISAR3_EL1, SynchPrim, 12, 4)
- IDREG_FIELD(ID_ISAR3_EL1, SVC, 8, 4)
- IDREG_FIELD(ID_ISAR3_EL1, SIMD, 4, 4)
- IDREG_FIELD(ID_ISAR3_EL1, Saturate, 0, 4)
+ IDREG_FIELD_START(ID_ISAR3_EL1, T32EE, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR3_EL1, T32EE)
+ IDREG_FIELD_START(ID_ISAR3_EL1, TrueNOP, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR3_EL1, TrueNOP)
+ IDREG_FIELD_START(ID_ISAR3_EL1, T32Copy, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR3_EL1, T32Copy)
+ IDREG_FIELD_START(ID_ISAR3_EL1, TabBranch, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR3_EL1, TabBranch)
+ IDREG_FIELD_START(ID_ISAR3_EL1, SynchPrim, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR3_EL1, SynchPrim)
+ IDREG_FIELD_START(ID_ISAR3_EL1, SVC, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR3_EL1, SVC)
+ IDREG_FIELD_START(ID_ISAR3_EL1, SIMD, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_ISAR3_EL1, SIMD)
+ IDREG_FIELD_START(ID_ISAR3_EL1, Saturate, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR3_EL1, Saturate)
IDREG_END(ID_ISAR3_EL1)
IDREG_START(ID_ISAR4_EL1)
- IDREG_FIELD(ID_ISAR4_EL1, SWP_frac, 28, 4)
- IDREG_FIELD(ID_ISAR4_EL1, PSR_M, 24, 4)
- IDREG_FIELD(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
- IDREG_FIELD(ID_ISAR4_EL1, Barrier, 16, 4)
- IDREG_FIELD(ID_ISAR4_EL1, SMC, 12, 4)
- IDREG_FIELD(ID_ISAR4_EL1, Writeback, 8, 4)
- IDREG_FIELD(ID_ISAR4_EL1, WithShifts, 4, 4)
- IDREG_FIELD(ID_ISAR4_EL1, Unpriv, 0, 4)
+ IDREG_FIELD_START(ID_ISAR4_EL1, SWP_frac, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR4_EL1, SWP_frac)
+ IDREG_FIELD_START(ID_ISAR4_EL1, PSR_M, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR4_EL1, PSR_M)
+ IDREG_FIELD_START(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_ISAR4_EL1, SynchPrim_frac)
+ IDREG_FIELD_START(ID_ISAR4_EL1, Barrier, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR4_EL1, Barrier)
+ IDREG_FIELD_START(ID_ISAR4_EL1, SMC, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR4_EL1, SMC)
+ IDREG_FIELD_START(ID_ISAR4_EL1, Writeback, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR4_EL1, Writeback)
+ IDREG_FIELD_START(ID_ISAR4_EL1, WithShifts, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_END(ID_ISAR4_EL1, WithShifts)
+ IDREG_FIELD_START(ID_ISAR4_EL1, Unpriv, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR4_EL1, Unpriv)
IDREG_END(ID_ISAR4_EL1)
IDREG_START(ID_ISAR5_EL1)
- IDREG_FIELD(ID_ISAR5_EL1, VCMA, 28, 4)
- IDREG_FIELD(ID_ISAR5_EL1, RDM, 24, 4)
- IDREG_FIELD(ID_ISAR5_EL1, CRC32, 16, 4)
- IDREG_FIELD(ID_ISAR5_EL1, SHA2, 12, 4)
- IDREG_FIELD(ID_ISAR5_EL1, SHA1, 8, 4)
- IDREG_FIELD(ID_ISAR5_EL1, AES, 4, 4)
- IDREG_FIELD(ID_ISAR5_EL1, SEVL, 0, 4)
+ IDREG_FIELD_START(ID_ISAR5_EL1, VCMA, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR5_EL1, VCMA)
+ IDREG_FIELD_START(ID_ISAR5_EL1, RDM, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR5_EL1, RDM)
+ IDREG_FIELD_START(ID_ISAR5_EL1, CRC32, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR5_EL1, CRC32)
+ IDREG_FIELD_START(ID_ISAR5_EL1, SHA2, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR5_EL1, SHA2)
+ IDREG_FIELD_START(ID_ISAR5_EL1, SHA1, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR5_EL1, SHA1)
+ IDREG_FIELD_START(ID_ISAR5_EL1, AES, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR5_EL1, AES)
+ IDREG_FIELD_START(ID_ISAR5_EL1, SEVL, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR5_EL1, SEVL)
IDREG_END(ID_ISAR5_EL1)
IDREG_START(ID_ISAR6_EL1)
- IDREG_FIELD(ID_ISAR6_EL1, CLRBHB, 28, 4)
- IDREG_FIELD(ID_ISAR6_EL1, I8MM, 24, 4)
- IDREG_FIELD(ID_ISAR6_EL1, BF16, 20, 4)
- IDREG_FIELD(ID_ISAR6_EL1, SPECRES, 16, 4)
- IDREG_FIELD(ID_ISAR6_EL1, SB, 12, 4)
- IDREG_FIELD(ID_ISAR6_EL1, FHM, 8, 4)
- IDREG_FIELD(ID_ISAR6_EL1, DP, 4, 4)
- IDREG_FIELD(ID_ISAR6_EL1, JSCVT, 0, 4)
+ IDREG_FIELD_START(ID_ISAR6_EL1, CLRBHB, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR6_EL1, CLRBHB)
+ IDREG_FIELD_START(ID_ISAR6_EL1, I8MM, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR6_EL1, I8MM)
+ IDREG_FIELD_START(ID_ISAR6_EL1, BF16, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR6_EL1, BF16)
+ IDREG_FIELD_START(ID_ISAR6_EL1, SPECRES, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_ISAR6_EL1, SPECRES)
+ IDREG_FIELD_START(ID_ISAR6_EL1, SB, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR6_EL1, SB)
+ IDREG_FIELD_START(ID_ISAR6_EL1, FHM, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR6_EL1, FHM)
+ IDREG_FIELD_START(ID_ISAR6_EL1, DP, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR6_EL1, DP)
+ IDREG_FIELD_START(ID_ISAR6_EL1, JSCVT, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_ISAR6_EL1, JSCVT)
IDREG_END(ID_ISAR6_EL1)
IDREG_START(ID_MMFR0_EL1)
- IDREG_FIELD(ID_MMFR0_EL1, InnerShr, 28, 4)
- IDREG_FIELD(ID_MMFR0_EL1, FCSE, 24, 4)
- IDREG_FIELD(ID_MMFR0_EL1, AuxReg, 20, 4)
- IDREG_FIELD(ID_MMFR0_EL1, TCM, 16, 4)
- IDREG_FIELD(ID_MMFR0_EL1, ShareLvl, 12, 4)
- IDREG_FIELD(ID_MMFR0_EL1, OuterShr, 8, 4)
- IDREG_FIELD(ID_MMFR0_EL1, PMSA, 4, 4)
- IDREG_FIELD(ID_MMFR0_EL1, VMSA, 0, 4)
+ IDREG_FIELD_START(ID_MMFR0_EL1, InnerShr, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_MMFR0_EL1, InnerShr)
+ IDREG_FIELD_START(ID_MMFR0_EL1, FCSE, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR0_EL1, FCSE)
+ IDREG_FIELD_START(ID_MMFR0_EL1, AuxReg, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR0_EL1, AuxReg)
+ IDREG_FIELD_START(ID_MMFR0_EL1, TCM, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_MMFR0_EL1, TCM)
+ IDREG_FIELD_START(ID_MMFR0_EL1, ShareLvl, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR0_EL1, ShareLvl)
+ IDREG_FIELD_START(ID_MMFR0_EL1, OuterShr, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_MMFR0_EL1, OuterShr)
+ IDREG_FIELD_START(ID_MMFR0_EL1, PMSA, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_MMFR0_EL1, PMSA)
+ IDREG_FIELD_START(ID_MMFR0_EL1, VMSA, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_END(ID_MMFR0_EL1, VMSA)
IDREG_END(ID_MMFR0_EL1)
IDREG_START(ID_MMFR1_EL1)
- IDREG_FIELD(ID_MMFR1_EL1, BPred, 28, 4)
- IDREG_FIELD(ID_MMFR1_EL1, L1TstCln, 24, 4)
- IDREG_FIELD(ID_MMFR1_EL1, L1Uni, 20, 4)
- IDREG_FIELD(ID_MMFR1_EL1, L1Hvd, 16, 4)
- IDREG_FIELD(ID_MMFR1_EL1, L1UniSW, 12, 4)
- IDREG_FIELD(ID_MMFR1_EL1, L1HvdSW, 8, 4)
- IDREG_FIELD(ID_MMFR1_EL1, L1UniVA, 4, 4)
- IDREG_FIELD(ID_MMFR1_EL1, L1HvdVA, 0, 4)
+ IDREG_FIELD_START(ID_MMFR1_EL1, BPred, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_END(ID_MMFR1_EL1, BPred)
+ IDREG_FIELD_START(ID_MMFR1_EL1, L1TstCln, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR1_EL1, L1TstCln)
+ IDREG_FIELD_START(ID_MMFR1_EL1, L1Uni, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR1_EL1, L1Uni)
+ IDREG_FIELD_START(ID_MMFR1_EL1, L1Hvd, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_MMFR1_EL1, L1Hvd)
+ IDREG_FIELD_START(ID_MMFR1_EL1, L1UniSW, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_MMFR1_EL1, L1UniSW)
+ IDREG_FIELD_START(ID_MMFR1_EL1, L1HvdSW, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_MMFR1_EL1, L1HvdSW)
+ IDREG_FIELD_START(ID_MMFR1_EL1, L1UniVA, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR1_EL1, L1UniVA)
+ IDREG_FIELD_START(ID_MMFR1_EL1, L1HvdVA, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR1_EL1, L1HvdVA)
IDREG_END(ID_MMFR1_EL1)
IDREG_START(ID_MMFR2_EL1)
- IDREG_FIELD(ID_MMFR2_EL1, HWAccFlg, 28, 4)
- IDREG_FIELD(ID_MMFR2_EL1, WFIStall, 24, 4)
- IDREG_FIELD(ID_MMFR2_EL1, MemBarr, 20, 4)
- IDREG_FIELD(ID_MMFR2_EL1, UniTLB, 16, 4)
+ IDREG_FIELD_START(ID_MMFR2_EL1, HWAccFlg, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR2_EL1, HWAccFlg)
+ IDREG_FIELD_START(ID_MMFR2_EL1, WFIStall, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR2_EL1, WFIStall)
+ IDREG_FIELD_START(ID_MMFR2_EL1, MemBarr, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR2_EL1, MemBarr)
+ IDREG_FIELD_START(ID_MMFR2_EL1, UniTLB, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_END(ID_MMFR2_EL1, UniTLB)
IDREG_FIELD(ID_MMFR2_EL1, HvdTLB, 12, 4)
- IDREG_FIELD(ID_MMFR2_EL1, L1HvdRng, 8, 4)
- IDREG_FIELD(ID_MMFR2_EL1, L1HvdBG, 4, 4)
- IDREG_FIELD(ID_MMFR2_EL1, L1HvdFG, 0, 4)
+ IDREG_FIELD_START(ID_MMFR2_EL1, L1HvdRng, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR2_EL1, L1HvdRng)
+ IDREG_FIELD_START(ID_MMFR2_EL1, L1HvdBG, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR2_EL1, L1HvdBG)
+ IDREG_FIELD_START(ID_MMFR2_EL1, L1HvdFG, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR2_EL1, L1HvdFG)
IDREG_END(ID_MMFR2_EL1)
IDREG_START(ID_MMFR3_EL1)
- IDREG_FIELD(ID_MMFR3_EL1, Supersec, 28, 4)
- IDREG_FIELD(ID_MMFR3_EL1, CMemSz, 24, 4)
- IDREG_FIELD(ID_MMFR3_EL1, CohWalk, 20, 4)
- IDREG_FIELD(ID_MMFR3_EL1, PAN, 16, 4)
- IDREG_FIELD(ID_MMFR3_EL1, MaintBcst, 12, 4)
- IDREG_FIELD(ID_MMFR3_EL1, BPMaint, 8, 4)
- IDREG_FIELD(ID_MMFR3_EL1, CMaintSW, 4, 4)
- IDREG_FIELD(ID_MMFR3_EL1, CMaintVA, 0, 4)
+ IDREG_FIELD_START(ID_MMFR3_EL1, Supersec, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(ID_MMFR3_EL1, Supersec)
+ IDREG_FIELD_START(ID_MMFR3_EL1, CMemSz, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR3_EL1, CMemSz)
+ IDREG_FIELD_START(ID_MMFR3_EL1, CohWalk, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR3_EL1, CohWalk)
+ IDREG_FIELD_START(ID_MMFR3_EL1, PAN, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR3_EL1, PAN)
+ IDREG_FIELD_START(ID_MMFR3_EL1, MaintBcst, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR3_EL1, MaintBcst)
+ IDREG_FIELD_START(ID_MMFR3_EL1, BPMaint, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR3_EL1, BPMaint)
+ IDREG_FIELD_START(ID_MMFR3_EL1, CMaintSW, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR3_EL1, CMaintSW)
+ IDREG_FIELD_START(ID_MMFR3_EL1, CMaintVA, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR3_EL1, CMaintVA)
IDREG_END(ID_MMFR3_EL1)
IDREG_START(ID_MMFR4_EL1)
- IDREG_FIELD(ID_MMFR4_EL1, EVT, 28, 4)
- IDREG_FIELD(ID_MMFR4_EL1, CCIDX, 24, 4)
- IDREG_FIELD(ID_MMFR4_EL1, LSM, 20, 4)
- IDREG_FIELD(ID_MMFR4_EL1, HPDS, 16, 4)
- IDREG_FIELD(ID_MMFR4_EL1, CnP, 12, 4)
- IDREG_FIELD(ID_MMFR4_EL1, XNX, 8, 4)
- IDREG_FIELD(ID_MMFR4_EL1, AC2, 4, 4)
- IDREG_FIELD(ID_MMFR4_EL1, SpecSEI, 0, 4)
+ IDREG_FIELD_START(ID_MMFR4_EL1, EVT, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR4_EL1, EVT)
+ IDREG_FIELD_START(ID_MMFR4_EL1, CCIDX, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR4_EL1, CCIDX)
+ IDREG_FIELD_START(ID_MMFR4_EL1, LSM, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR4_EL1, LSM)
+ IDREG_FIELD_START(ID_MMFR4_EL1, HPDS, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_MMFR4_EL1, HPDS)
+ IDREG_FIELD_START(ID_MMFR4_EL1, CnP, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR4_EL1, CnP)
+ IDREG_FIELD_START(ID_MMFR4_EL1, XNX, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR4_EL1, XNX)
+ IDREG_FIELD_START(ID_MMFR4_EL1, AC2, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR4_EL1, AC2)
+ IDREG_FIELD_START(ID_MMFR4_EL1, SpecSEI, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR4_EL1, SpecSEI)
IDREG_END(ID_MMFR4_EL1)
IDREG_START(ID_MMFR5_EL1)
- IDREG_FIELD(ID_MMFR5_EL1, nTLBPA, 4, 4)
- IDREG_FIELD(ID_MMFR5_EL1, ETS, 0, 4)
+ IDREG_FIELD_START(ID_MMFR5_EL1, nTLBPA, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_MMFR5_EL1, nTLBPA)
+ IDREG_FIELD_START(ID_MMFR5_EL1, ETS, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_MMFR5_EL1, ETS)
IDREG_END(ID_MMFR5_EL1)
IDREG_START(ID_PFR0_EL1)
- IDREG_FIELD(ID_PFR0_EL1, RAS, 28, 4)
- IDREG_FIELD(ID_PFR0_EL1, DIT, 24, 4)
- IDREG_FIELD(ID_PFR0_EL1, AMU, 20, 4)
- IDREG_FIELD(ID_PFR0_EL1, CSV2, 16, 4)
- IDREG_FIELD(ID_PFR0_EL1, State3, 12, 4)
- IDREG_FIELD(ID_PFR0_EL1, State2, 8, 4)
- IDREG_FIELD(ID_PFR0_EL1, State1, 4, 4)
- IDREG_FIELD(ID_PFR0_EL1, State0, 0, 4)
+ IDREG_FIELD_START(ID_PFR0_EL1, RAS, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_PFR0_EL1, RAS)
+ IDREG_FIELD_START(ID_PFR0_EL1, DIT, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_PFR0_EL1, DIT)
+ IDREG_FIELD_START(ID_PFR0_EL1, AMU, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_PFR0_EL1, AMU)
+ IDREG_FIELD_START(ID_PFR0_EL1, CSV2, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_PFR0_EL1, CSV2)
+ IDREG_FIELD_START(ID_PFR0_EL1, State3, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_PFR0_EL1, State3)
+ IDREG_FIELD_START(ID_PFR0_EL1, State2, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_PFR0_EL1, State2)
+ IDREG_FIELD_START(ID_PFR0_EL1, State1, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_PFR0_EL1, State1)
+ IDREG_FIELD_START(ID_PFR0_EL1, State0, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_PFR0_EL1, State0)
IDREG_END(ID_PFR0_EL1)
IDREG_START(ID_PFR1_EL1)
- IDREG_FIELD(ID_PFR1_EL1, GIC, 28, 4)
- IDREG_FIELD(ID_PFR1_EL1, Virt_frac, 24, 4)
- IDREG_FIELD(ID_PFR1_EL1, Sec_frac, 20, 4)
- IDREG_FIELD(ID_PFR1_EL1, GenTimer, 16, 4)
- IDREG_FIELD(ID_PFR1_EL1, Virtualization, 12, 4)
- IDREG_FIELD(ID_PFR1_EL1, MProgMod, 8, 4)
- IDREG_FIELD(ID_PFR1_EL1, Security, 4, 4)
- IDREG_FIELD(ID_PFR1_EL1, ProgMod, 0, 4)
+ IDREG_FIELD_START(ID_PFR1_EL1, GIC, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(ID_PFR1_EL1, GIC)
+ IDREG_FIELD_START(ID_PFR1_EL1, Virt_frac, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_PFR1_EL1, Virt_frac)
+ IDREG_FIELD_START(ID_PFR1_EL1, Sec_frac, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_PFR1_EL1, Sec_frac)
+ IDREG_FIELD_START(ID_PFR1_EL1, GenTimer, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_PFR1_EL1, GenTimer)
+ IDREG_FIELD_START(ID_PFR1_EL1, Virtualization, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_PFR1_EL1, Virtualization)
+ IDREG_FIELD_START(ID_PFR1_EL1, MProgMod, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_PFR1_EL1, MProgMod)
+ IDREG_FIELD_START(ID_PFR1_EL1, Security, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(ID_PFR1_EL1, Security)
+ IDREG_FIELD_START(ID_PFR1_EL1, ProgMod, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_PFR1_EL1, ProgMod)
IDREG_END(ID_PFR1_EL1)
IDREG_START(ID_PFR2_EL1)
- IDREG_FIELD(ID_PFR2_EL1, RAS_frac, 8, 4)
- IDREG_FIELD(ID_PFR2_EL1, SSBS, 4, 4)
- IDREG_FIELD(ID_PFR2_EL1, CSV3, 0, 4)
+ IDREG_FIELD_START(ID_PFR2_EL1, RAS_frac, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_PFR2_EL1, RAS_frac)
+ IDREG_FIELD_START(ID_PFR2_EL1, SSBS, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_PFR2_EL1, SSBS)
+ IDREG_FIELD_START(ID_PFR2_EL1, CSV3, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(ID_PFR2_EL1, CSV3)
IDREG_END(ID_PFR2_EL1)
IDREG_START(MIDR_EL1)
- IDREG_FIELD(MIDR_EL1, Implementer, 24, 8)
+ IDREG_FIELD_START(MIDR_EL1, Implementer, 24, 8)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(65)
+ IDREG_FIELD_ARCH_VAL(66)
+ IDREG_FIELD_ARCH_VAL(67)
+ IDREG_FIELD_ARCH_VAL(68)
+ IDREG_FIELD_ARCH_VAL(70)
+ IDREG_FIELD_ARCH_VAL(73)
+ IDREG_FIELD_ARCH_VAL(77)
+ IDREG_FIELD_ARCH_VAL(78)
+ IDREG_FIELD_ARCH_VAL(80)
+ IDREG_FIELD_ARCH_VAL(81)
+ IDREG_FIELD_ARCH_VAL(86)
+ IDREG_FIELD_ARCH_VAL(105)
+ IDREG_FIELD_ARCH_VAL(192)
+ IDREG_FIELD_END(MIDR_EL1, Implementer)
IDREG_FIELD(MIDR_EL1, Variant, 20, 4)
- IDREG_FIELD(MIDR_EL1, Architecture, 16, 4)
+ IDREG_FIELD_START(MIDR_EL1, Architecture, 16, 4)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(MIDR_EL1, Architecture)
IDREG_FIELD(MIDR_EL1, PartNum, 4, 12)
IDREG_FIELD(MIDR_EL1, Revision, 0, 4)
IDREG_END(MIDR_EL1)
IDREG_START(MPIDR_EL1)
IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
- IDREG_FIELD(MPIDR_EL1, U, 30, 1)
- IDREG_FIELD(MPIDR_EL1, MT, 24, 1)
+ IDREG_FIELD_START(MPIDR_EL1, U, 30, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MPIDR_EL1, U)
+ IDREG_FIELD_START(MPIDR_EL1, MT, 24, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MPIDR_EL1, MT)
IDREG_FIELD(MPIDR_EL1, Aff2, 16, 8)
IDREG_FIELD(MPIDR_EL1, Aff1, 8, 8)
IDREG_FIELD(MPIDR_EL1, Aff0, 0, 8)
IDREG_END(MPIDR_EL1)
IDREG_START(MVFR0_EL1)
- IDREG_FIELD(MVFR0_EL1, FPRound, 28, 4)
- IDREG_FIELD(MVFR0_EL1, FPShVec, 24, 4)
- IDREG_FIELD(MVFR0_EL1, FPSqrt, 20, 4)
- IDREG_FIELD(MVFR0_EL1, FPDivide, 16, 4)
- IDREG_FIELD(MVFR0_EL1, FPTrap, 12, 4)
- IDREG_FIELD(MVFR0_EL1, FPDP, 8, 4)
- IDREG_FIELD(MVFR0_EL1, FPSP, 4, 4)
- IDREG_FIELD(MVFR0_EL1, SIMDReg, 0, 4)
+ IDREG_FIELD_START(MVFR0_EL1, FPRound, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR0_EL1, FPRound)
+ IDREG_FIELD_START(MVFR0_EL1, FPShVec, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR0_EL1, FPShVec)
+ IDREG_FIELD_START(MVFR0_EL1, FPSqrt, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR0_EL1, FPSqrt)
+ IDREG_FIELD_START(MVFR0_EL1, FPDivide, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR0_EL1, FPDivide)
+ IDREG_FIELD_START(MVFR0_EL1, FPTrap, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR0_EL1, FPTrap)
+ IDREG_FIELD_START(MVFR0_EL1, FPDP, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(MVFR0_EL1, FPDP)
+ IDREG_FIELD_START(MVFR0_EL1, FPSP, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(MVFR0_EL1, FPSP)
+ IDREG_FIELD_START(MVFR0_EL1, SIMDReg, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(MVFR0_EL1, SIMDReg)
IDREG_END(MVFR0_EL1)
IDREG_START(MVFR1_EL1)
- IDREG_FIELD(MVFR1_EL1, SIMDFMAC, 28, 4)
- IDREG_FIELD(MVFR1_EL1, FPHP, 24, 4)
- IDREG_FIELD(MVFR1_EL1, SIMDHP, 20, 4)
- IDREG_FIELD(MVFR1_EL1, SIMDSP, 16, 4)
- IDREG_FIELD(MVFR1_EL1, SIMDInt, 12, 4)
- IDREG_FIELD(MVFR1_EL1, SIMDLS, 8, 4)
- IDREG_FIELD(MVFR1_EL1, FPDNaN, 4, 4)
- IDREG_FIELD(MVFR1_EL1, FPFtZ, 0, 4)
+ IDREG_FIELD_START(MVFR1_EL1, SIMDFMAC, 28, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR1_EL1, SIMDFMAC)
+ IDREG_FIELD_START(MVFR1_EL1, FPHP, 24, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(MVFR1_EL1, FPHP)
+ IDREG_FIELD_START(MVFR1_EL1, SIMDHP, 20, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_END(MVFR1_EL1, SIMDHP)
+ IDREG_FIELD_START(MVFR1_EL1, SIMDSP, 16, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR1_EL1, SIMDSP)
+ IDREG_FIELD_START(MVFR1_EL1, SIMDInt, 12, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR1_EL1, SIMDInt)
+ IDREG_FIELD_START(MVFR1_EL1, SIMDLS, 8, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR1_EL1, SIMDLS)
+ IDREG_FIELD_START(MVFR1_EL1, FPDNaN, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR1_EL1, FPDNaN)
+ IDREG_FIELD_START(MVFR1_EL1, FPFtZ, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(MVFR1_EL1, FPFtZ)
IDREG_END(MVFR1_EL1)
IDREG_START(MVFR2_EL1)
- IDREG_FIELD(MVFR2_EL1, FPMisc, 4, 4)
- IDREG_FIELD(MVFR2_EL1, SIMDMisc, 0, 4)
+ IDREG_FIELD_START(MVFR2_EL1, FPMisc, 4, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_END(MVFR2_EL1, FPMisc)
+ IDREG_FIELD_START(MVFR2_EL1, SIMDMisc, 0, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(MVFR2_EL1, SIMDMisc)
IDREG_END(MVFR2_EL1)
IDREG_START(REVIDR_EL1)
IDREG_END(REVIDR_EL1)
IDREG_START(SMIDR_EL1)
- IDREG_FIELD(SMIDR_EL1, NSMC, 56, 4)
- IDREG_FIELD(SMIDR_EL1, HIP, 52, 4)
+ IDREG_FIELD_START(SMIDR_EL1, NSMC, 56, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(SMIDR_EL1, NSMC)
+ IDREG_FIELD_START(SMIDR_EL1, HIP, 52, 4)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_ARCH_VAL(4)
+ IDREG_FIELD_ARCH_VAL(5)
+ IDREG_FIELD_ARCH_VAL(6)
+ IDREG_FIELD_ARCH_VAL(7)
+ IDREG_FIELD_ARCH_VAL(8)
+ IDREG_FIELD_ARCH_VAL(9)
+ IDREG_FIELD_ARCH_VAL(10)
+ IDREG_FIELD_ARCH_VAL(11)
+ IDREG_FIELD_ARCH_VAL(12)
+ IDREG_FIELD_ARCH_VAL(13)
+ IDREG_FIELD_ARCH_VAL(14)
+ IDREG_FIELD_ARCH_VAL(15)
+ IDREG_FIELD_END(SMIDR_EL1, HIP)
IDREG_FIELD(SMIDR_EL1, Affinity2, 32, 20)
- IDREG_FIELD(SMIDR_EL1, Implementer, 24, 8)
+ IDREG_FIELD_START(SMIDR_EL1, Implementer, 24, 8)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(65)
+ IDREG_FIELD_ARCH_VAL(66)
+ IDREG_FIELD_ARCH_VAL(67)
+ IDREG_FIELD_ARCH_VAL(68)
+ IDREG_FIELD_ARCH_VAL(70)
+ IDREG_FIELD_ARCH_VAL(73)
+ IDREG_FIELD_ARCH_VAL(77)
+ IDREG_FIELD_ARCH_VAL(78)
+ IDREG_FIELD_ARCH_VAL(80)
+ IDREG_FIELD_ARCH_VAL(81)
+ IDREG_FIELD_ARCH_VAL(86)
+ IDREG_FIELD_ARCH_VAL(105)
+ IDREG_FIELD_ARCH_VAL(192)
+ IDREG_FIELD_END(SMIDR_EL1, Implementer)
IDREG_FIELD(SMIDR_EL1, Revision, 16, 8)
- IDREG_FIELD(SMIDR_EL1, SMPS, 15, 1)
- IDREG_FIELD(SMIDR_EL1, SH, 13, 2)
+ IDREG_FIELD_START(SMIDR_EL1, SMPS, 15, 1)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_END(SMIDR_EL1, SMPS)
+ IDREG_FIELD_START(SMIDR_EL1, SH, 13, 2)
+ IDREG_FIELD_ARCH_VAL(0)
+ IDREG_FIELD_ARCH_VAL(1)
+ IDREG_FIELD_ARCH_VAL(2)
+ IDREG_FIELD_ARCH_VAL(3)
+ IDREG_FIELD_END(SMIDR_EL1, SH)
IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
IDREG_END(SMIDR_EL1)
diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py
index 6f5edb88d2..96f8aa2d64 100644
--- a/scripts/update-aarch64-cpu-sysreg-properties.py
+++ b/scripts/update-aarch64-cpu-sysreg-properties.py
@@ -9,7 +9,12 @@
#
# IDREG_START(REG)
# IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
-# ...
+# or for fields with enum values
+# IDREG_FIELD_START(REG, FIELD, SHIFT, LENGTH)
+# IDREG_FIELD_ARCH_VAL(VALUE)
+# ../..
+# IDREG_FIELD_END(REG, FIELD)
+# ../..
# IDREG_END(REG)
#
# Copyright (C) 2026 Red Hat, Inc.
@@ -97,6 +102,59 @@ def collect_fields(item, bit_offset=0):
return fields
+def parse_raw_val(val_obj):
+ """Helper to unwrap int values from strings, ints, or nested dicts."""
+ if isinstance(val_obj, dict):
+ val_obj = val_obj.get("value")
+
+ if val_obj is None:
+ return None
+
+ raw_val_str = str(val_obj).strip().replace("'", "")
+ try:
+ return int(raw_val_str, 2)
+ except ValueError:
+ try:
+ return int(raw_val_str, 0)
+ except ValueError:
+ return None
+
+def extract_field_enums(field):
+ enums = []
+ if not isinstance(field, dict):
+ return enums
+
+ value_obj = field.get("value")
+ if not isinstance(value_obj, dict):
+ return enums
+
+ constraints = value_obj.get("constraints")
+ if not isinstance(constraints, dict):
+ return enums
+
+ val_entries = constraints.get("values", [])
+ if not isinstance(val_entries, list):
+ return enums
+
+ for val_entry in val_entries:
+ if not isinstance(val_entry, dict):
+ continue
+
+ entry_type = val_entry.get("_type")
+ if entry_type == "Values.Value":
+ int_val = parse_raw_val(val_entry.get("value"))
+ if int_val is not None:
+ enums.append({'value': int_val})
+
+ elif entry_type == "Values.ValueRange":
+ s = parse_raw_val(val_entry.get("start"))
+ e = parse_raw_val(val_entry.get("end"))
+
+ if s is not None and e is not None:
+ for v in range(s, e + 1):
+ enums.append({'value': v})
+
+ return enums
def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
with open(raw_json_path, 'r') as f:
@@ -128,16 +186,32 @@ def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
# Only keep the fields with the highest MSB
# needed fir CCSIDR_EL1
if name not in unique_fields or msb > unique_fields[name]['msb']:
- unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width}
+ # extract enum values if any
+ enums = extract_field_enums(val)
+ unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width, 'enums': enums}
# Sort decreasing lsbs
sorted_fields = sorted(unique_fields.items(),
key=lambda x: x[1]['lsb'], reverse=True)
for name, bits in sorted_fields:
- line = (f" IDREG_FIELD({reg_name}, "
- f"{name}, {bits['lsb']}, {bits['width']})\n")
+ enums_list = bits.get('enums', [])
+
+ if enums_list:
+ line = (f" IDREG_FIELD_START({reg_name}, "
+ f"{name}, {bits['lsb']}, {bits['width']})\n")
+ else:
+ line = (f" IDREG_FIELD({reg_name}, "
+ f"{name}, {bits['lsb']}, {bits['width']})\n")
final_output += line
+ # generate enum value or range if any
+ for enum_item in enums_list:
+ final_output += (f" IDREG_FIELD_ARCH_VAL({enum_item['value']})\n")
+
+ if enums_list:
+ line = (f" IDREG_FIELD_END({reg_name}, {name})\n")
+ final_output += line
+
final_output += f"IDREG_END({reg_name})\n"
final_output += "\n"
@@ -147,7 +221,11 @@ def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
f.write("/* IDREG_START(REG) */\n")
f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n")
+ f.write("/* or for fields with enum values */\n")
+ f.write("/* IDREG_FIELD_START(REG, FIELD, SHIFT, LENGTH) */\n")
+ f.write("/* IDREG_FIELD_ARCH_VAL(VALUE) */\n")
f.write("/* ... */\n")
+ f.write("/* IDREG_FIELD_END(REG, FIELD) */\n")
f.write("/* IDREG_END(REG) */\n\n")
f.write(final_output)
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 09/26] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (7 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 08/26] target/arm/cpu-idregs.h.inc: Generate enum values Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-25 12:16 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 10/26] target/arm/kvm: Retrieve writable ID reg map Eric Auger
` (16 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
From: Shaju Abraham <shaju.abraham@nutanix.com>
Include cpu-idregs.h.inc multiple times with different definitions for the
X-macros. This will generate tables for all Arm64 ID registers and their
fields. Additionally, initialize the tables with all architecturally defined
values. These tables will be consumed by the property layer in future
patches.
Note:
This triggers a minot checkpatch error but I prefer to keep the coma in
the macro.
ERROR: Macros with complex values should be enclosed in parenthesis
+#define IDREG_FIELD_ARCH_VAL(v) (v),
Co-authored-by: Khushit Shah <khushit.shah@nutanix.com>
Signed-off-by: Khushit Shah <khushit.shah@nutanix.com>
Signed-off-by: Shaju Abraham <shaju.abraham@nutanix.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
v7 -> v8
Adaptation after removal of struct ArmIdRegArchVal
v5 -> v6
- restored support of enum values
---
target/arm/cpu-idregs.c | 96 +++++++++++++++++++++++++++++++++++++++++
target/arm/meson.build | 1 +
2 files changed, 97 insertions(+)
create mode 100644 target/arm/cpu-idregs.c
diff --git a/target/arm/cpu-idregs.c b/target/arm/cpu-idregs.c
new file mode 100644
index 0000000000..199d593153
--- /dev/null
+++ b/target/arm/cpu-idregs.c
@@ -0,0 +1,96 @@
+/*
+ * ARM ID register field table.
+ *
+ * Builds the per-id-register field descriptor arrays and the global
+ * arm_idregs[] table.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "cpu-idregs.h"
+
+/*
+ * Generate an array of architecturely defined values for each field
+ * associated with enum values
+ */
+
+#define IDREG_START(reg)
+#define IDREG_END(reg)
+#define IDREG_FIELD(reg, field, shift, length)
+#define IDREG_FIELD_START(reg, field, shift, length) \
+ static const uint64_t reg##_##field##_arch_vals[] = {
+#define IDREG_FIELD_ARCH_VAL(v) (v),
+#define IDREG_FIELD_END(reg, field) \
+ };
+
+#include "cpu-idregs.h.inc"
+
+#undef IDREG_START
+#undef IDREG_END
+#undef IDREG_FIELD
+#undef IDREG_FIELD_START
+#undef IDREG_FIELD_END
+#undef IDREG_FIELD_ARCH_VAL
+
+/* generate an array of per-register ArmIdRegField[] descriptors */
+
+#define IDREG_START(reg) \
+ static ARM64SysRegField reg##_fields[] = {
+
+#define IDREG_END(reg) \
+ };
+
+#define IDREG_FIELD_START(reg, field, _shift, _length) \
+ { \
+ .name = #field, \
+ .index = reg##_IDX, \
+ .shift = (_shift), \
+ .length = (_length), \
+ .arch_vals = (uint64_t *)reg##_##field##_arch_vals, \
+ .arch_vals_count = ARRAY_SIZE(reg##_##field##_arch_vals), \
+ },
+
+#define IDREG_FIELD(reg, field, _shift, _length) \
+ { \
+ .name = #field, \
+ .index = reg##_IDX, \
+ .shift = (_shift), \
+ .length = (_length), \
+ },
+
+#define IDREG_FIELD_ARCH_VAL(v)
+
+#define IDREG_FIELD_END(reg, field)
+
+#include "cpu-idregs.h.inc"
+
+#undef IDREG_START
+#undef IDREG_END
+#undef IDREG_FIELD
+#undef IDREG_FIELD_START
+#undef IDREG_FIELD_END
+#undef IDREG_FIELD_ARCH_VAL
+
+/* generate an array of top level ID registers */
+
+#define IDREG_END(reg)
+#define IDREG_FIELD(reg, field, shift, length)
+#define IDREG_FIELD_START(reg, field, shift, length)
+#define IDREG_FIELD_ARCH_VAL(v)
+#define IDREG_FIELD_END(reg, field)
+
+#define IDREG_START(reg) \
+ [reg##_IDX] = { \
+ .name = #reg, \
+ .index = reg##_IDX, \
+ .fields = reg##_fields, \
+ .fields_count = ARRAY_SIZE(reg##_fields), \
+ },
+
+ARM64SysReg arm64_id_regs[NUM_ID_IDX] = {
+#include "cpu-idregs.h.inc"
+};
+
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 0369f96b4c..384d90c530 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -30,6 +30,7 @@ arm_common_user_system_ss.add(when: 'TARGET_AARCH64', if_true: files(
arm_common_system_ss.add(files(
'arm-qmp-cmds.c',
+ 'cpu-idregs.c',
))
arm_system_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c'))
arm_system_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 10/26] target/arm/kvm: Retrieve writable ID reg map
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (8 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 09/26] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-25 12:37 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 11/26] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0 Eric Auger
` (15 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
From: Cornelia Huck <cohuck@redhat.com>
Add an helper to retrieve the writable id reg bitmask.
then retrieve the writable_map array and dispatch it in the writable_map
fields of arm64_id_regs[] elements.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
v7 -> v8
- added kvm_enabled()
v5 -> v6
- use arm64_id_regs[].writable_map
- squashed 2 commits (helper + user)
- removed stub
---
target/arm/kvm.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index ed99be7fd8..c6eac41991 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -28,6 +28,7 @@
#include "kvm_arm.h"
#include "cpu.h"
#include "cpu-sysregs.h"
+#include "cpu-idregs.h"
#include "trace.h"
#include "internals.h"
#include "hw/pci/pci.h"
@@ -51,6 +52,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
static bool cap_has_mp_state;
static bool cap_has_inject_serror_esr;
static bool cap_has_inject_ext_dabt;
+static bool writable_map_dispatched;
/**
* ARMHostCPUFeatures: information about the host CPU (identified
@@ -273,6 +275,21 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
}
+static int kvm_feature_idx_to_idregs_idx(int kidx)
+{
+ int op1, crm, op2;
+ ARMSysRegs sysreg;
+
+ op1 = kidx / 64;
+ if (op1 == 2) {
+ op1 = 3;
+ }
+ crm = (kidx % 64) / 8;
+ op2 = kidx % 8;
+ sysreg = ENCODE_ID_REG(3, op1, 0, crm, op2);
+ return get_sysreg_idx(sysreg);
+}
+
static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{
/* Identify the feature bits corresponding to the host CPU, and
@@ -480,9 +497,53 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ahcf->features = features;
}
+static int kvm_arm_get_writable_id_regs(uint64_t *idregmap)
+{
+ int cap_writable_id_regs;
+ struct reg_mask_range range = {
+ .range = KVM_ARM_FEATURE_ID_RANGE,
+ .reserved = {0},
+ .addr = (uint64_t)idregmap,
+ };
+
+ cap_writable_id_regs =
+ kvm_check_extension(kvm_state, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES);
+
+ if (!cap_writable_id_regs ||
+ !(cap_writable_id_regs & (1 << KVM_ARM_FEATURE_ID_RANGE))) {
+ return -ENOSYS;
+ }
+
+ if (kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range)) {
+ return -errno;
+ }
+ return 0;
+}
+
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
{
CPUARMState *env = &cpu->env;
+ uint64_t *writable_map;
+
+ writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE);
+
+ if (kvm_enabled() && !writable_map_dispatched &&
+ !kvm_arm_get_writable_id_regs(writable_map)) {
+ for (int i = 0; i < KVM_ARM_FEATURE_ID_RANGE_SIZE; i++) {
+ uint64_t mask = writable_map[i];
+
+ if (mask) {
+ int idx = kvm_feature_idx_to_idregs_idx(i);
+
+ if (idx < 0 || idx > ARRAY_SIZE(arm64_id_regs)) {
+ continue;
+ }
+ arm64_id_regs[idx].writable_mask = mask;
+ }
+ }
+ writable_map_dispatched = true;
+ }
+ g_free(writable_map);
if (!arm_host_cpu_features.dtb_compatible) {
kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 11/26] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (9 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 10/26] target/arm/kvm: Retrieve writable ID reg map Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-25 12:46 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 12/26] arm/kvm: Initialize isar.idregs[] with all writable host ID regs Eric Auger
` (14 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
In KVM mode, virt_get_caches() currently gets a zero value for the
CLIDR_EL1 register. This is due to the fact CLIDR is never read from
host. This is a bug.
Soon we will initialize all writable isar.idreg[] from host and this
includes CLIDR_EL1. However we cannot directly fix the initialization,
first because it would change the way the guest is exposed caches in
DT/ACPI descriptions and because some host values would be rejected
by the current QEMU code, expecially in the case host has a unified
L1 cache which is currently not supported and triggers the following
errod: "Unified type is not implemented at level 1" error.
So this issue will be fixed separately.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
hw/arm/virt.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0871a35e11..6c87ac133a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -342,6 +342,10 @@ unsigned int virt_get_caches(const VirtMachineState *vms, CPUCoreCaches *caches)
ARMISARegisters *isar = &armcpu->isar;
uint32_t clidr = GET_IDREG(isar, CLIDR);
+ if (kvm_enabled()) {
+ clidr = 0;
+ }
+
for (int cache_level = 1; cache_level <= CLIDR_CTYPE_MAX_CACHE_LEVEL;
cache_level++) {
uint8_t ctype =
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 12/26] arm/kvm: Initialize isar.idregs[] with all writable host ID regs
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (10 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 11/26] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0 Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-25 13:27 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 13/26] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger
` (13 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
kvm_arm_get_host_cpu_features() already retrieves the values of some
host id registers to analyze the available vcpu features.
Eventually we want to be able to allow the user to change the value
of writable ID reg fields. So we need to store the initial value of all
writable ID regs into isar.idregs[].
Introduce a new get_host_cpu_idregs() helper that populates isar.idregs[]
and call it from kvm_arm_get_host_cpu_features.
This patch has no impact on cpreg values. isar.idregs[] is only
used as a temporary storage for register values to be updated in place
later. Also it does not handle the writeback of isar.idregs[] into cpreg
value list after user update. This will be handled separately.
Note the host values are retrieved from the scratch vcpu initialized with
all the available capabilities exposed by KVM, independently on the
final choice made by the suer.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
v8 -> v9:
- improve the commit msg. Only initialize in this patch and move the
write back to cpreg value list in a different patch.
- Do not hack CLIDR here. The correct way to fix that temporarily is to
do that in the machine instead.
v7 -> v8
- fix indent and added Khushit's R-b
v6 -> v7
- remove vcpu from prototypes (Khushit)
v5 -> v6
- do not check writable_map anymore
---
target/arm/kvm.c | 43 ++++++++++++++++++++++++++++++++++++++++-
target/arm/trace-events | 2 ++
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index c6eac41991..958b25e550 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -43,6 +43,7 @@
#include "hw/acpi/ghes.h"
#include "target/arm/gtimer.h"
#include "migration/blocker.h"
+#include "cpu-idregs.h"
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_INFO(DEVICE_CTRL),
@@ -290,7 +291,44 @@ static int kvm_feature_idx_to_idregs_idx(int kidx)
return get_sysreg_idx(sysreg);
}
-static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
+/*
+ * get_host_cpu_idregs: Read all the writable ID reg host values
+ *
+ * Need to be called once the writable mask has been populated
+ * Note we may want to read all the known id regs but some of them are not
+ * writable and return an error, hence the choice of reading only those which
+ * are writable. Those are also readable!
+ */
+static int get_host_cpu_idregs(int fd, ARMHostCPUFeatures *ahcf)
+{
+ int err = 0;
+ int i;
+
+ for (i = 0; i < NUM_ID_IDX; i++) {
+ ARM64SysReg *sysregdesc = &arm64_id_regs[i];
+ ARMSysRegs sysreg = id_register_sysreg[i];
+ uint64_t *reg;
+ int ret;
+
+ if (!sysregdesc->writable_mask) {
+ continue;
+ }
+
+ reg = &ahcf->isar.idregs[i];
+ ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg));
+ trace_get_host_cpu_idregs(sysregdesc->name, *reg);
+ if (ret) {
+ error_report("%s error reading value of host %s register (%m)",
+ __func__, sysregdesc->name);
+
+ err = ret;
+ }
+ }
+ return err;
+}
+
+static void
+kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{
/* Identify the feature bits corresponding to the host CPU, and
* fill out the ARMHostCPUClass fields accordingly. To do this
@@ -376,6 +414,9 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */
err = 0;
} else {
+ /* Make sure all writable ID reg values are initialized */
+ err |= get_host_cpu_idregs(fd, ahcf);
+
err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX);
err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR2_EL1_IDX);
err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX);
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 8502fb3265..c25d2a1191 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -13,6 +13,8 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
# kvm.c
kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
+get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
+kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%"PRIx64
# cpu.c
arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 13/26] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (11 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 12/26] arm/kvm: Initialize isar.idregs[] with all writable host ID regs Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-24 6:26 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter Eric Auger
` (12 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
This helper decode the ID reg writable mask, matches it against
ID reg fields defined in target/arm/cpu-idregs.h.inc and
for each writable named field, generates a uint64 property.
REVIDR_EL1 and AIDR_EL1 are writable but they do not expose any
field. They will be handled separately.
The setter and getter are not yet implemented
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
v7 -> v8
- scratch the '!' in the error_setg
- addapt to the removal of struct ArmIdRegArchVal
v5 -> v6
- for enum values, check against value value when setting the prop
- do not check writable_map flag anymore
v4 -> v5:
- free prop_name
- check cpu->writable_map as a preamble in kvm_arm_expose_idreg_properties
---
target/arm/kvm_arm.h | 10 +++++
target/arm/kvm.c | 93 +++++++++++++++++++++++++++++++++++++++++
target/arm/trace-events | 4 ++
3 files changed, 107 insertions(+)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index e7c40fb003..2b3474cc36 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -142,6 +142,16 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
*/
void kvm_arm_add_vcpu_properties(ARMCPU *cpu);
+typedef struct ARM64SysReg ARM64SysReg;
+/**
+ * kvm_arm_expose_idreg_properties:
+ * @cpu: The CPU object to generate the properties for
+ * @reg: registers from the host
+ *
+ * analyze the writable mask and generate properties for writable fields
+ */
+void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs);
+
/**
* kvm_arm_steal_time_finalize:
* @cpu: ARMCPU for which to finalize kvm-steal-time
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 958b25e550..341542279d 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -327,6 +327,99 @@ static int get_host_cpu_idregs(int fd, ARMHostCPUFeatures *ahcf)
return err;
}
+static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
+{
+ for (int f = 0; f < reg->fields_count; f++) {
+ struct ARM64SysRegField *field = ®->fields[f];
+ int upper = field->shift + field->length - 1;
+
+ if (i >= field->shift && i <= upper) {
+ return field;
+ }
+ }
+ return NULL;
+}
+
+static void set_sysreg_prop(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ error_setg(errp, "%s setter not yet implemented", name);
+}
+
+static void get_sysreg_prop(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ error_setg(errp, "%s getter not yet implemented", name);
+}
+
+/*
+ * decode_idreg_writemap: Generate props for writable fields
+ *
+ * @obj: CPU object
+ * @reg: description of the sysreg
+ */
+static int
+decode_idreg_writemap(Object *obj, ARM64SysReg *reg)
+{
+ uint64_t map = reg->writable_mask;
+ int i = ctz64(map);
+ int nb_sysreg_props = 0;
+
+ while (map) {
+ ARM64SysRegField *field = get_field(i, reg);
+ int lower, upper;
+ char *prop_name;
+ uint64_t field_mask;
+
+ if (!field) {
+ warn_report("%s bit %d of %s is writable but no named field "
+ "in target/arm/cpu-idregs.h.inc",
+ __func__, i, reg->name);
+ map = map & ~BIT_ULL(i);
+ i = ctz64(map);
+ continue;
+ }
+ lower = field->shift;
+ upper = field->shift + field->length - 1;
+ prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name);
+ trace_decode_idreg_writemap(field->name, lower, upper, prop_name);
+ object_property_add(obj, prop_name, "uint64",
+ get_sysreg_prop, set_sysreg_prop, NULL, field);
+ g_free(prop_name);
+ nb_sysreg_props++;
+
+ field_mask = MAKE_64BIT_MASK(lower, field->length);
+ map = map & ~field_mask;
+ i = ctz64(map);
+ }
+ trace_nb_sysreg_props(reg->name, nb_sysreg_props);
+ return 0;
+}
+
+/* analyze the writable mask and generate properties for writable fields */
+void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs)
+{
+ Object *obj = OBJECT(cpu);
+
+ for (int i = 0; i < NUM_ID_IDX; i++) {
+ ARM64SysReg *sysregdesc = ®s[i];
+
+ if (sysregdesc->writable_mask) {
+ /*
+ * special case REVIDR_EL1 and AIDR_EL1 which are writable but
+ * do not expose named fields. They will need to be handled
+ * separately
+ */
+ if (strcmp(sysregdesc->name, "REVIDR_EL1") &&
+ strcmp(sysregdesc->name, "AIDR_EL1")) {
+ decode_idreg_writemap(obj, sysregdesc);
+ }
+ }
+ }
+}
+
static void
kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{
diff --git a/target/arm/trace-events b/target/arm/trace-events
index c25d2a1191..d72ad6b671 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -15,6 +15,10 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%"PRIx64
+decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
+get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
+set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
+nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
# cpu.c
arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (12 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 13/26] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-28 9:28 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 15/26] target/arm/kvm: Pass an Error handle to kvm_arch_init_vcpu Eric Auger
` (11 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
When the setter is called, the final vcpu is not created yet.
Applying the override on vcpu.isar initialized with the max scratch
vcpu would not be correct because the final vcpu may have some features
turned off (for instance virtualization) while the scratch vcpu
features it. So we need to postpone the actual override until the
final vcpu has been initialized.
In terms of input value validation what can be done now is checking
against field length and arch enum value if any.
If this succeeds, the field value is added in the hash table to be
written later on once the final vcpu has been created
With regards to the getter, if the sysreg prop was set, we return the
set value, otherwise, we return the value in cpu->isar.idregs[].
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/cpu.h | 2 ++
target/arm/cpu.c | 5 ++--
target/arm/kvm.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e3f931dba2..9bbd42dd2b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -952,6 +952,8 @@ struct ArchCPU {
uint64_t *cpreg_vmstate_values;
int32_t cpreg_vmstate_array_len;
+ GHashTable *sysreg_props;
+
DynamicGDBFeatureInfo dyn_sysreg_feature;
DynamicGDBFeatureInfo dyn_svereg_feature;
DynamicGDBFeatureInfo dyn_smereg_feature;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 77aa78f00e..917f709cb4 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1236,8 +1236,8 @@ static void arm_cpu_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
- cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, g_free);
+ cpu->cp_regs = g_hash_table_new(g_direct_hash, g_direct_equal);
+ cpu->sysreg_props = g_hash_table_new(g_direct_hash, g_direct_equal);
QLIST_INIT(&cpu->pre_el_change_hooks);
QLIST_INIT(&cpu->el_change_hooks);
@@ -1725,6 +1725,7 @@ static void arm_cpu_finalizefn(Object *obj)
ARMCPRegMigTolerance *t, *n;
g_hash_table_destroy(cpu->cp_regs);
+ g_hash_table_destroy(cpu->sysreg_props);
QLIST_FOREACH_SAFE(hook, &cpu->pre_el_change_hooks, node, next) {
QLIST_REMOVE(hook, node);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 341542279d..cdc3779321 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -340,18 +340,79 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
return NULL;
}
+#define MAKE_IDREG_KEY(reg_idx, field_shift) \
+ (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
+
static void set_sysreg_prop(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
- error_setg(errp, "%s setter not yet implemented", name);
+ ARM64SysRegField *field = (ARM64SysRegField *)opaque;
+ ARMCPU *cpu = ARM_CPU(obj);
+ int index = field->index;
+ int lower = field->shift;
+ int length = field->length;
+ uint64_t key, value;
+
+ if (!visit_type_uint64(v, name, &value, errp)) {
+ return;
+ }
+
+ if (length < 64 && value > ((1 << length) - 1)) {
+ error_setg(errp,
+ "idreg %s set value (0x%lx) exceeds length of field (%d)!",
+ name, value, length);
+ return;
+ }
+
+ if (field->arch_vals) {
+ /* this field has some enum values */
+ for (int i = 0; i < field->arch_vals_count; i++) {
+ if (value == field->arch_vals[i]) {
+ goto valid;
+ }
+ }
+ error_setg(errp,
+ "idreg %s set value (0x%lx) does not match any "
+ "arch valid enum value", name, value);
+ return;
+ }
+
+valid:
+
+ key = MAKE_IDREG_KEY(index, lower);
+ g_hash_table_insert(cpu->sysreg_props, GUINT_TO_POINTER(key),
+ GUINT_TO_POINTER(value));
}
static void get_sysreg_prop(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
- error_setg(errp, "%s getter not yet implemented", name);
+ ARM64SysRegField *field = (ARM64SysRegField *)opaque;
+ ARMCPU *cpu = ARM_CPU(obj);
+ int index = field->index;
+ int lower = field->shift;
+ int length = field->length;
+ gpointer value_ptr;
+ uint64_t value;
+ uint64_t key = MAKE_IDREG_KEY(index, lower);
+ gboolean exists;
+
+ exists = g_hash_table_lookup_extended(cpu->sysreg_props,
+ GUINT_TO_POINTER(key), NULL,
+ &value_ptr);
+ if (exists) {
+ value = GPOINTER_TO_UINT(value_ptr);
+ } else {
+ uint64_t mask = MAKE_64BIT_MASK(lower, length);
+ uint64_t *idregs = cpu->isar.idregs;
+
+ value = (idregs[index] & mask) >> lower;
+ }
+
+ visit_type_uint64(v, name, &value, errp);
+ trace_get_sysreg_prop(name, value);
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 15/26] target/arm/kvm: Pass an Error handle to kvm_arch_init_vcpu
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (13 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu Eric Auger
` (10 subsequent siblings)
25 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
The 2 callers of kvm_arch_init_vcpu(), namely kvm_rebind_vcpus()
and kvm_init_vcpu() are passed an Error handle. So it is a pity
not using it in kvm_arch_init_vcpu(). Also some functions called
within kvm_arch_init_vcpu() could get benefit from it, especially
on ARM. This will happen in subsequent patches.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
include/system/kvm.h | 2 +-
accel/kvm/kvm-all.c | 15 +++++++--------
target/arm/kvm.c | 14 +++++++++-----
target/i386/kvm/kvm.c | 22 ++++++++++++----------
target/loongarch/kvm/kvm.c | 24 ++++++++----------------
target/ppc/kvm.c | 6 +++---
target/riscv/kvm/kvm-cpu.c | 3 ++-
target/s390x/kvm/kvm.c | 2 +-
8 files changed, 43 insertions(+), 45 deletions(-)
diff --git a/include/system/kvm.h b/include/system/kvm.h
index 714b8c7b01..cd94eb0323 100644
--- a/include/system/kvm.h
+++ b/include/system/kvm.h
@@ -358,7 +358,7 @@ int kvm_arch_get_default_type(MachineState *ms);
int kvm_arch_init(MachineState *ms, KVMState *s);
int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp);
-int kvm_arch_init_vcpu(CPUState *cpu);
+int kvm_arch_init_vcpu(CPUState *cpu, Error **errp);
int kvm_arch_destroy_vcpu(CPUState *cpu);
#ifdef TARGET_KVM_HAVE_RESET_PARKED_VCPU
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 83cbd120a8..a66d1d8c66 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -492,11 +492,11 @@ static int kvm_rebind_vcpus(Error **errp)
}
}
- ret = kvm_arch_init_vcpu(cpu);
+ ret = kvm_arch_init_vcpu(cpu, errp);
if (ret < 0) {
- error_setg_errno(errp, -ret,
- "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
- vcpu_id);
+ error_prepend(errp,
+ "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
+ vcpu_id);
}
close(cpu->kvm_vcpu_stats_fd);
@@ -739,11 +739,10 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
}
}
- ret = kvm_arch_init_vcpu(cpu);
+ ret = kvm_arch_init_vcpu(cpu, errp);
if (ret < 0) {
- error_setg_errno(errp, -ret,
- "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
- kvm_arch_vcpu_id(cpu));
+ error_prepend(errp, "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
+ kvm_arch_vcpu_id(cpu));
}
cpu->kvm_vcpu_stats_fd = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index cdc3779321..3ec2618cc1 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2215,7 +2215,7 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
int ret;
uint64_t mpidr;
@@ -2224,7 +2224,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
uint64_t psciver;
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
- error_report("KVM is not supported for this guest CPU type");
+ error_setg(errp, "KVM is not supported for this guest CPU type");
return -EINVAL;
}
@@ -2263,16 +2263,19 @@ int kvm_arch_init_vcpu(CPUState *cs)
/* Do KVM_ARM_VCPU_INIT ioctl */
ret = kvm_arm_vcpu_init(cpu);
if (ret) {
+ error_setg(errp, "failed kvm_arm_vcpu_init (%d)", ret);
return ret;
}
if (cpu_isar_feature(aa64_sve, cpu)) {
ret = kvm_arm_sve_set_vls(cpu);
if (ret) {
+ error_setg(errp, "failed kvm_arm_sve_set_vls (%d)", ret);
return ret;
}
ret = kvm_arm_vcpu_finalize(cpu, KVM_ARM_VCPU_SVE);
if (ret) {
+ error_setg(errp, "failed kvm_arm_vcpu_finalize (%d)", ret);
return ret;
}
}
@@ -2281,11 +2284,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
psciver = cpu->psci_version;
ret = kvm_set_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver);
if (ret) {
- error_report("KVM in this kernel does not support PSCI version %d.%d",
+ error_setg(errp, "KVM in this kernel does not support PSCI version %d.%d",
(int) PSCI_VERSION_MAJOR(psciver),
(int) PSCI_VERSION_MINOR(psciver));
- error_printf("Consider setting the kvm-psci-version property on the "
- "migration source.\n");
+ error_append_hint(errp, "Consider setting the kvm-psci-version property "
+ "on the migration source.\n");
return ret;
}
}
@@ -2307,6 +2310,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
*/
ret = kvm_get_one_reg(cs, ARM64_SYS_REG(ARM_CPU_ID_MPIDR), &mpidr);
if (ret) {
+ error_setg(errp, "failed retrieving PMIDR value");
return ret;
}
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 1eeadb99ad..41e99f6dcd 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2218,7 +2218,7 @@ static void kvm_init_pmu_info(struct kvm_cpuid2 *cpuid, X86CPU *cpu)
}
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
struct {
struct kvm_cpuid2 cpuid;
@@ -2240,12 +2240,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
int kvm_base = KVM_CPUID_SIGNATURE;
int max_nested_state_len;
int r;
- Error *local_err = NULL;
if (current_machine->cgs) {
r = x86_confidential_guest_check_features(
X86_CONFIDENTIAL_GUEST(current_machine->cgs), cs);
if (r < 0) {
+ error_setg(errp, "failed x86_confidential_guest_check_features (%d)", r);
return r;
}
}
@@ -2258,6 +2258,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
r = kvm_arch_set_tsc_khz(cs);
if (r < 0) {
+ error_setg(errp, "failed setting tsc_khz (%d)", r);
return r;
}
@@ -2285,14 +2286,14 @@ int kvm_arch_init_vcpu(CPUState *cs)
* can still proceed and check/expand Hyper-V enlightenments here so legacy
* behavior is preserved.
*/
- if (!kvm_hyperv_expand_features(cpu, &local_err)) {
- error_report_err(local_err);
+ if (!kvm_hyperv_expand_features(cpu, errp)) {
return -ENOSYS;
}
if (hyperv_enabled(cpu)) {
r = hyperv_init_vcpu(cpu);
if (r) {
+ error_setg(errp, "failed hyperv_init_vcpu (%d)", r);
return r;
}
@@ -2371,6 +2372,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
r = kvm_xen_init_vcpu(cs);
if (r) {
+ error_setg(errp, "failed kvm_xen_init_vcpu (%d)", r);
return r;
}
@@ -2419,12 +2421,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
ret = kvm_get_mce_cap_supported(cs->kvm_state, &mcg_cap, &banks);
if (ret < 0) {
- fprintf(stderr, "kvm_get_mce_cap_supported: %s", strerror(-ret));
+ error_setg(errp, "kvm_get_mce_cap_supported: %s", strerror(-ret));
return ret;
}
if (banks < (env->mcg_cap & MCG_CAP_BANKS_MASK)) {
- error_report("kvm: Unsupported MCE bank count (QEMU = %d, KVM = %d)",
+ error_setg(errp, "kvm: Unsupported MCE bank count (QEMU = %d, KVM = %d)",
(int)(env->mcg_cap & MCG_CAP_BANKS_MASK), banks);
return -ENOTSUP;
}
@@ -2432,7 +2434,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
unsupported_caps = env->mcg_cap & ~(mcg_cap | MCG_CAP_BANKS_MASK);
if (unsupported_caps) {
if (unsupported_caps & MCG_LMCE_P) {
- error_report("kvm: LMCE not supported");
+ error_setg(errp, "kvm: LMCE not supported");
return -ENOTSUP;
}
warn_report("Unsupported MCG_CAP bits: 0x%" PRIx64,
@@ -2442,7 +2444,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
env->mcg_cap &= mcg_cap | MCG_CAP_BANKS_MASK;
ret = kvm_vcpu_ioctl(cs, KVM_X86_SETUP_MCE, &env->mcg_cap);
if (ret < 0) {
- fprintf(stderr, "KVM_X86_SETUP_MCE: %s", strerror(-ret));
+ error_setg(errp, "KVM_X86_SETUP_MCE: %s", strerror(-ret));
return ret;
}
}
@@ -2470,9 +2472,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
error_setg(&invtsc_mig_blocker,
"State blocked by non-migratable CPU device"
" (invtsc flag)");
- r = migrate_add_blocker(&invtsc_mig_blocker, &local_err);
+ r = migrate_add_blocker(&invtsc_mig_blocker, errp);
if (r < 0) {
- error_report_err(local_err);
return r;
}
}
@@ -2501,6 +2502,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpuid_data.cpuid.padding = 0;
r = kvm_vcpu_ioctl(cs, KVM_SET_CPUID2, &cpuid_data);
if (r) {
+ error_setg(errp, "KVM_SET_CPUID2 failed (%m)");
goto fail;
}
kvm_init_xsave(env);
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 15082a01f8..9fca5f81f8 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -1239,11 +1239,10 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error *errp)
{
uint64_t val;
int ret;
- Error *local_err = NULL;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
cpu->vmsentry = qemu_add_vm_change_state_handler(
@@ -1253,45 +1252,38 @@ int kvm_arch_init_vcpu(CPUState *cs)
brk_insn = val;
}
- ret = kvm_cpu_check_lsx(cs, &local_err);
+ ret = kvm_cpu_check_lsx(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_lasx(cs, &local_err);
+ ret = kvm_cpu_check_lasx(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_lbt(cs, &local_err);
+ ret = kvm_cpu_check_lbt(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_pmu(cs, &local_err);
+ ret = kvm_cpu_check_pmu(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_pv_features(cs, &local_err);
+ ret = kvm_cpu_check_pv_features(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_ptw(cs, &local_err);
+ ret = kvm_cpu_check_ptw(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
- ret = kvm_cpu_check_msgint(cs, &local_err);
+ ret = kvm_cpu_check_msgint(cs, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 8e89a6c665..d90e904f90 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -484,7 +484,7 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *cenv = &cpu->env;
@@ -494,8 +494,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
ret = kvm_arch_sync_sregs(cpu);
if (ret) {
if (ret == -EINVAL) {
- error_report("Register sync failed... If you're using kvm-hv.ko,"
- " only \"-cpu host\" is possible");
+ error_setg(errp, "Register sync failed... If you're using kvm-hv.ko,"
+ " only \"-cpu host\" is possible");
}
return ret;
}
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 68e1501b21..d09048c522 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -1544,7 +1544,7 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
int ret = 0;
RISCVCPU *cpu = RISCV_CPU(cs);
@@ -1554,6 +1554,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (!object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST)) {
ret = kvm_vcpu_set_machine_ids(cpu, cs);
if (ret != 0) {
+ error_setg(errp, "failed setting machine id (%d)", ret);
return ret;
}
}
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index b34a912714..19b9540bdd 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -403,7 +403,7 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs)
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
unsigned int max_cpus = MACHINE(qdev_get_machine())->smp.max_cpus;
S390CPU *cpu = S390_CPU(cs);
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (14 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 15/26] target/arm/kvm: Pass an Error handle to kvm_arch_init_vcpu Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-28 10:44 ` Khushit Shah
2026-09-30 7:54 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props Eric Auger
` (9 subsequent siblings)
25 siblings, 2 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
SYSREG prop settings were recorded in a hashtable but they
are not yet injected on guest. Iterate over all set fields and
apply the new value through KVM_SET_ONE_REG. The new field
value overrides the current observable vcpu register value.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/kvm.c | 65 +++++++++++++++++++++++++++++++++++++++++
target/arm/trace-events | 1 +
2 files changed, 66 insertions(+)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 3ec2618cc1..ddf320d0e6 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -343,6 +343,9 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
#define MAKE_IDREG_KEY(reg_idx, field_shift) \
(((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
+#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
+#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
+
static void set_sysreg_prop(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
@@ -2215,6 +2218,63 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
return 0;
}
+static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
+{
+ uint64_t *idregs = cpu->isar.idregs;
+ gpointer key_ptr, value_ptr;
+ CPUState *cs = CPU(cpu);
+ GHashTableIter iter;
+
+ g_hash_table_iter_init(&iter, cpu->sysreg_props);
+
+ while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
+ uint64_t key = (uint64_t)key_ptr;
+ uint64_t value = (uint64_t)value_ptr;
+ uint32_t reg_idx = KEY_TO_REG_IDX(key);
+ uint8_t lower = KEY_TO_SHIFT(key);
+ ARM64SysReg *reg = &arm64_id_regs[reg_idx];
+ struct kvm_one_reg kvm_reg;
+ uint64_t current, old, mask;
+ uint64_t kvm_idx;
+ ARM64SysRegField *field = get_field(lower, reg);
+ int length = field->length;
+ uint64_t oldfv;
+ int ret;
+
+ mask = MAKE_64BIT_MASK(lower, length);
+ value = value << lower;
+
+ old = idregs[reg_idx];
+
+ kvm_idx = idregs_sysreg_to_kvm_reg(id_register_sysreg[reg_idx]);
+ ret = read_sys_reg64(cs->kvm_fd, ¤t, kvm_idx);
+ if (ret) {
+ error_setg(errp, "failed to read the current value of %s",
+ reg->name);
+ return ret;
+ }
+ oldfv = (current & mask) >> lower;
+
+ idregs[reg_idx] = current & ~mask;
+ idregs[reg_idx] |= value;
+
+ kvm_reg.id = kvm_idx;
+ kvm_reg.addr = (uintptr_t)&idregs[reg_idx];
+
+ ret = ioctl(cs->kvm_fd, KVM_SET_ONE_REG, &kvm_reg);
+ if (ret) {
+ error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s.%s "
+ "(previous is 0x%"PRIx64"): %m", idregs[reg_idx],
+ reg->name, field->name, oldfv);
+ return ret;
+ }
+
+ trace_apply_sysreg_prop(reg->name, field->name, old, current,
+ mask, value, idregs[reg_idx]);
+ }
+ return 0;
+}
+
int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
int ret;
@@ -2315,6 +2375,11 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
}
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
+ ret = kvm_arm_apply_sysreg_props(cpu, errp);
+ if (ret) {
+ return ret;
+ }
+
return kvm_arm_init_cpreg_list(cpu);
}
diff --git a/target/arm/trace-events b/target/arm/trace-events
index d72ad6b671..b4d2b45a7d 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -18,6 +18,7 @@ kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint6
decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
+apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
# cpu.c
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (15 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-28 12:53 ` Khushit Shah
2026-09-30 7:34 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 18/26] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger
` (8 subsequent siblings)
25 siblings, 2 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Since legacy composite options (such as SVE, virtualization, ...)
and new SYSREG props coexist, add some basic consistency checks.
Those checks are performed both in kvm_arch_init_vcpu() before
applying the SYSREG props at the end of the initialization chain.
Some ID reg fields corresponding to legacy composite option scope
are not writable. In that case we just check that the field has
not become writable.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/kvm.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 105 insertions(+)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index ddf320d0e6..f52c03745e 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -340,6 +340,107 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
return NULL;
}
+
+/**
+ * kvm_arm_vcpu_validate_sysreg:
+ *
+ * Validate a SYSREG field value is consistent with legacy composite options
+ * Some checks are not implemented because the corresponding sysreg field
+ * is not currently writable. In that case we make sure the field has not
+ * become writable, which would mean the user had the capability to set the
+ * corresponding property.
+ *
+ * return true if consistent. false if it is not, along with an error handle
+ */
+static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
+ uint64_t value, Error **errp)
+{
+ const char *fieldname = field->name;
+ ARM64SysReg *sysregdesc = &arm64_id_regs[field->index];
+ const char *regname = sysregdesc->name;
+ g_autofree char *propname = g_strdup_printf("SYSREG_%s_%s", regname, fieldname);
+
+ /* virtualization */
+ if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) {
+ /* consistency with machine virtualization property */
+ if (cpu->has_el2 && value == 0) {
+ error_setg(errp,
+ "Inconsistent -machine virtualization=on and "
+ "%s=0", propname);
+ return false;
+ } else if (!cpu->has_el2 && value > 0) {
+ error_setg(errp,
+ "Inconsistent -machine virtualization=off and "
+ "%s > 0", propname);
+ return false;
+ }
+ /* secure */
+ } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL3") && value > 0) {
+ /* consistency with machine secure property */
+ error_setg(errp, "%s is set but qemu is not ready to support it",
+ propname);
+ return false;
+ /* MTE */
+ } else if (!strcmp(propname, "SYSREG_ID_AA64PFR1_EL1_MTE")) {
+ error_setg(errp, "%s is now exposed but qemu is not ready to support it",
+ propname);
+ return false;
+ /* SVE */
+ } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_SVE")) {
+ error_setg(errp, "%s is now exposed but qemu is not ready to support it",
+ propname);
+ return false;
+ } else if (!strcmp(propname, "SYSREG_ID_AA64ZFR0_EL1_SVEver")) {
+ if (cpu_isar_feature(aa64_sve, cpu) && value == 0) {
+ error_setg(errp, "sve is set but %s is set to 0", propname);
+ return false;
+ } else if (!cpu_isar_feature(aa64_sve, cpu) && value > 0) {
+ error_setg(errp, "sve is not set but %s is greater than 0",
+ propname);
+ return false;
+ }
+ /* PAUTH */
+ } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_APA")) {
+ /* PAUTH QARMA5 address authentification */
+ error_setg(errp, "%s is now exposed but qemu is not ready to support it",
+ propname);
+ return false;
+ } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_API")) {
+ /* PAUTH Impl Defined address authentification */
+ error_setg(errp, "%s is now exposed but qemu is not ready to support it",
+ propname);
+ return false;
+ } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPA")) {
+ /* QARMA5 generic code authentification */
+ error_setg(errp, "%s is now exposed but qemu is not ready to support it",
+ propname);
+ return false;
+ } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPI")) {
+ /* QARMA5 generic code authentification */
+ error_setg(errp, "%s is now exposed but qemu is not ready to support it",
+ propname);
+ return false;
+ /* PMU */
+ } else if (!strcmp(propname, "SYSREG_ID_AA64DFR0_EL1_PMUVer")) {
+ if (cpu->has_pmu && value == 0) {
+ error_setg(errp, "%s is 0 whereas pmu is set", propname);
+ return false;
+ } else if (!cpu->has_pmu && value) {
+ error_setg(errp, "%s is non null whereas pmu is unset", propname);
+ return false;
+ }
+ /* aarch64 false */
+ } else if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
+ if ((!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL0") ||
+ !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL1") ||
+ !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) && value < 2)
+ error_setg(errp, "%s is < 2 while aarch64 is set to off",
+ propname);
+ return false;
+ }
+ return true;
+}
+
#define MAKE_IDREG_KEY(reg_idx, field_shift) \
(((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
@@ -2241,6 +2342,10 @@ static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
uint64_t oldfv;
int ret;
+ if (!kvm_arm_vcpu_validate_sysreg(cpu, field, value, errp)) {
+ return -1;
+ }
+
mask = MAKE_64BIT_MASK(lower, length);
value = value << lower;
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 18/26] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (16 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-28 13:26 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 19/26] target/arm/cpu-idregs.h.inc: Generate reserved fields Eric Auger
` (7 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
If the host supports KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES and
KVM_ARM_GET_REG_WRITABLE_MASKS ioctl successfully retrieved the mask
of writable fields for all ID regs, expose uint64 SYSREG properties
for all the writable ID reg fields exposed by the host kernel which
can be matched in target/arm/cpu-idregs.h.inc.
Properties are named SYSREG_<REG>_<FIELD> with REG and FIELD
being those used ARCHMRS Registers.json.
When such properties are set, they override the default field value
retrieved from the host and reinjected into KVM. Then the actual value
being applied at KVM depends on the register, ie. it can be sanitized.
In case the field value is rejected by KVM, the vpcu init fails.
Anyway there is a first attempt to write back this value into KVM.
Then legacy CPU options (virtualization, secure, ...) can still
override the previous value. So low level IDREG field properties
apply before the legacy ones.
An example of invocation is:
-cpu host,SYSREG_ID_AA64MMFR0_EL1_ECV=0x0
which sets ECV field of ID_AA64MMFR0_EL1 to 0 (enhanced counter
virtualization).
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
---
v5 -> v6:
- do not check writable_map anymore
v4 -> v5:
- get rid of ret local variable, dynamically allocate and free writable_map
here
---
target/arm/cpu64.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 4e8c472530..e04062e848 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -37,6 +37,7 @@
#include "hw/core/qdev-properties.h"
#include "internals.h"
#include "cpu-features.h"
+#include "cpu-idregs.h"
/* convert between <register>_IDX and SYS_<register> */
#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
@@ -807,6 +808,10 @@ void aarch64_host_initfn(Object *obj)
kvm_arm_set_cpreg_mig_tolerances(cpu);
kvm_arm_set_cpu_features_from_host(cpu);
aarch64_add_sve_properties(obj);
+
+ /* generate SYSREG properties according to writable masks */
+ kvm_arm_expose_idreg_properties(cpu, arm64_id_regs);
+
#elif defined(CONFIG_HVF)
hvf_arm_set_cpu_features_from_host(cpu);
#elif defined(CONFIG_WHPX)
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 19/26] target/arm/cpu-idregs.h.inc: Generate reserved fields
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (17 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 18/26] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 20/26] target/arm/kvm: Ignore and trace unexpected writable " Eric Auger
` (6 subsequent siblings)
25 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Extract reserved fields: RES0, RES1, RAZ, ...
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
v7 -> v8:
- fix WithShifts issue
---
target/arm/cpu-idregs.h.inc | 62 ++++++++++++++
.../update-aarch64-cpu-sysreg-properties.py | 83 +++++++++++++++----
2 files changed, 131 insertions(+), 14 deletions(-)
diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
index 10ddfdf43a..c7e93c48b7 100644
--- a/target/arm/cpu-idregs.h.inc
+++ b/target/arm/cpu-idregs.h.inc
@@ -15,6 +15,7 @@ IDREG_START(AIDR_EL1)
IDREG_END(AIDR_EL1)
IDREG_START(CLIDR_EL1)
+ IDREG_FIELD(CLIDR_EL1, RES0, 47, 17)
IDREG_FIELD(CLIDR_EL1, Ttype7, 45, 2)
IDREG_FIELD(CLIDR_EL1, Ttype6, 43, 2)
IDREG_FIELD(CLIDR_EL1, Ttype5, 41, 2)
@@ -45,7 +46,10 @@ IDREG_START(CLIDR_EL1)
IDREG_END(CLIDR_EL1)
IDREG_START(CTR_EL0)
+ IDREG_FIELD(CTR_EL0, RES0, 38, 26)
IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
+ IDREG_FIELD(CTR_EL0, RES1, 31, 1)
+ IDREG_FIELD(CTR_EL0, RES0, 30, 1)
IDREG_FIELD_START(CTR_EL0, DIC, 29, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -63,23 +67,28 @@ IDREG_START(CTR_EL0)
IDREG_FIELD_ARCH_VAL(2)
IDREG_FIELD_ARCH_VAL(3)
IDREG_FIELD_END(CTR_EL0, L1Ip)
+ IDREG_FIELD(CTR_EL0, RES0, 4, 10)
IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
IDREG_END(CTR_EL0)
IDREG_START(DCZID_EL0)
+ IDREG_FIELD(DCZID_EL0, RES0, 9, 55)
IDREG_FIELD(DCZID_EL0, TBS, 5, 4)
IDREG_FIELD(DCZID_EL0, DZP, 4, 1)
IDREG_FIELD(DCZID_EL0, BS, 0, 4)
IDREG_END(DCZID_EL0)
IDREG_START(GMID_EL1)
+ IDREG_FIELD(GMID_EL1, RES0, 4, 60)
IDREG_FIELD(GMID_EL1, BS, 0, 4)
IDREG_END(GMID_EL1)
IDREG_START(ID_AA64AFR0_EL1)
+ IDREG_FIELD(ID_AA64AFR0_EL1, RES0, 32, 32)
IDREG_END(ID_AA64AFR0_EL1)
IDREG_START(ID_AA64AFR1_EL1)
+ IDREG_FIELD(ID_AA64AFR1_EL1, RES0, 0, 64)
IDREG_END(ID_AA64AFR1_EL1)
IDREG_START(ID_AA64DFR0_EL1)
@@ -141,6 +150,7 @@ IDREG_START(ID_AA64DFR0_EL1)
IDREG_FIELD_ARCH_VAL(14)
IDREG_FIELD_ARCH_VAL(15)
IDREG_FIELD_END(ID_AA64DFR0_EL1, CTX_CMPs)
+ IDREG_FIELD(ID_AA64DFR0_EL1, RES0, 24, 4)
IDREG_FIELD_START(ID_AA64DFR0_EL1, WRPs, 20, 4)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_ARCH_VAL(2)
@@ -531,6 +541,7 @@ IDREG_START(ID_AA64DFR1_EL1)
IDREG_END(ID_AA64DFR1_EL1)
IDREG_START(ID_AA64DFR2_EL1)
+ IDREG_FIELD(ID_AA64DFR2_EL1, RES0, 28, 36)
IDREG_FIELD_START(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -543,6 +554,7 @@ IDREG_START(ID_AA64DFR2_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64DFR2_EL1, SPE_EXC)
+ IDREG_FIELD(ID_AA64DFR2_EL1, RES0, 8, 8)
IDREG_FIELD_START(ID_AA64DFR2_EL1, BWE, 4, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -555,6 +567,7 @@ IDREG_START(ID_AA64DFR2_EL1)
IDREG_END(ID_AA64DFR2_EL1)
IDREG_START(ID_AA64FPFR0_EL1)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -579,10 +592,13 @@ IDREG_START(ID_AA64FPFR0_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8MM4)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, RES0, 16, 10)
IDREG_FIELD_START(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64FPFR0_EL1, F16MM2)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, RES0, 8, 7)
+ IDREG_FIELD(ID_AA64FPFR0_EL1, RAZ, 2, 6)
IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -634,6 +650,7 @@ IDREG_START(ID_AA64ISAR0_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64ISAR0_EL1, RDM)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, RES0, 24, 4)
IDREG_FIELD_START(ID_AA64ISAR0_EL1, Atomic, 20, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(2)
@@ -657,6 +674,7 @@ IDREG_START(ID_AA64ISAR0_EL1)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_ARCH_VAL(2)
IDREG_FIELD_END(ID_AA64ISAR0_EL1, AES)
+ IDREG_FIELD(ID_AA64ISAR0_EL1, RES0, 0, 4)
IDREG_END(ID_AA64ISAR0_EL1)
IDREG_START(ID_AA64ISAR1_EL1)
@@ -820,6 +838,7 @@ IDREG_START(ID_AA64ISAR2_EL1)
IDREG_END(ID_AA64ISAR2_EL1)
IDREG_START(ID_AA64ISAR3_EL1)
+ IDREG_FIELD(ID_AA64ISAR3_EL1, RES0, 48, 16)
IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSCP, 44, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -883,6 +902,7 @@ IDREG_START(ID_AA64MMFR0_EL1)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_ARCH_VAL(2)
IDREG_FIELD_END(ID_AA64MMFR0_EL1, FGT)
+ IDREG_FIELD(ID_AA64MMFR0_EL1, RES0, 48, 8)
IDREG_FIELD_START(ID_AA64MMFR0_EL1, ExS, 44, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1035,6 +1055,7 @@ IDREG_START(ID_AA64MMFR2_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64MMFR2_EL1, TTL)
+ IDREG_FIELD(ID_AA64MMFR2_EL1, RES0, 44, 4)
IDREG_FIELD_START(ID_AA64MMFR2_EL1, FWB, 40, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1100,6 +1121,7 @@ IDREG_START(ID_AA64MMFR3_EL1)
IDREG_FIELD_ARCH_VAL(2)
IDREG_FIELD_ARCH_VAL(3)
IDREG_FIELD_END(ID_AA64MMFR3_EL1, SDERR)
+ IDREG_FIELD(ID_AA64MMFR3_EL1, RES0, 48, 4)
IDREG_FIELD_START(ID_AA64MMFR3_EL1, ANERR, 44, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1353,6 +1375,7 @@ IDREG_START(ID_AA64PFR1_EL1)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_ARCH_VAL(2)
IDREG_FIELD_END(ID_AA64PFR1_EL1, SME)
+ IDREG_FIELD(ID_AA64PFR1_EL1, RES0, 20, 4)
IDREG_FIELD_START(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1380,6 +1403,7 @@ IDREG_START(ID_AA64PFR1_EL1)
IDREG_END(ID_AA64PFR1_EL1)
IDREG_START(ID_AA64PFR2_EL1)
+ IDREG_FIELD(ID_AA64PFR2_EL1, RES0, 48, 16)
IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1439,6 +1463,7 @@ IDREG_START(ID_AA64SMFR0_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64SMFR0_EL1, FA64)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, RES0, 62, 1)
IDREG_FIELD_START(ID_AA64SMFR0_EL1, LUT6, 61, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1458,6 +1483,7 @@ IDREG_START(ID_AA64SMFR0_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(15)
IDREG_FIELD_END(ID_AA64SMFR0_EL1, I16I64)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, RES0, 49, 3)
IDREG_FIELD_START(ID_AA64SMFR0_EL1, F64F64, 48, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1502,6 +1528,7 @@ IDREG_START(ID_AA64SMFR0_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64SMFR0_EL1, F32F32)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, RES0, 31, 1)
IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1514,6 +1541,7 @@ IDREG_START(ID_AA64SMFR0_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8DP2)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, RES0, 26, 2)
IDREG_FIELD_START(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1526,10 +1554,12 @@ IDREG_START(ID_AA64SMFR0_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64SMFR0_EL1, SFEXPA)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, RES0, 17, 6)
IDREG_FIELD_START(ID_AA64SMFR0_EL1, STMOP, 16, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64SMFR0_EL1, STMOP)
+ IDREG_FIELD(ID_AA64SMFR0_EL1, RES0, 1, 15)
IDREG_FIELD_START(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1537,6 +1567,7 @@ IDREG_START(ID_AA64SMFR0_EL1)
IDREG_END(ID_AA64SMFR0_EL1)
IDREG_START(ID_AA64ZFR0_EL1)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, RES0, 60, 4)
IDREG_FIELD_START(ID_AA64ZFR0_EL1, F64MM, 56, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1557,10 +1588,12 @@ IDREG_START(ID_AA64ZFR0_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64ZFR0_EL1, SM4)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, RES0, 36, 4)
IDREG_FIELD_START(ID_AA64ZFR0_EL1, SHA3, 32, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64ZFR0_EL1, SHA3)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, RES0, 28, 4)
IDREG_FIELD_START(ID_AA64ZFR0_EL1, B16B16, 24, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1580,6 +1613,7 @@ IDREG_START(ID_AA64ZFR0_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_AA64ZFR0_EL1, EltPerm)
+ IDREG_FIELD(ID_AA64ZFR0_EL1, RES0, 8, 4)
IDREG_FIELD_START(ID_AA64ZFR0_EL1, AES, 4, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1596,9 +1630,11 @@ IDREG_START(ID_AA64ZFR0_EL1)
IDREG_END(ID_AA64ZFR0_EL1)
IDREG_START(ID_AFR0_EL1)
+ IDREG_FIELD(ID_AFR0_EL1, RES0, 0, 64)
IDREG_END(ID_AFR0_EL1)
IDREG_START(ID_DFR0_EL1)
+ IDREG_FIELD(ID_DFR0_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_DFR0_EL1, TraceFilt, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1650,6 +1686,7 @@ IDREG_START(ID_DFR0_EL1)
IDREG_END(ID_DFR0_EL1)
IDREG_START(ID_DFR1_EL1)
+ IDREG_FIELD(ID_DFR1_EL1, RES0, 8, 56)
IDREG_FIELD_START(ID_DFR1_EL1, HPMN0, 4, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1662,6 +1699,7 @@ IDREG_START(ID_DFR1_EL1)
IDREG_END(ID_DFR1_EL1)
IDREG_START(ID_ISAR0_EL1)
+ IDREG_FIELD(ID_ISAR0_EL1, RES0, 28, 36)
IDREG_FIELD_START(ID_ISAR0_EL1, Divide, 24, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1697,6 +1735,7 @@ IDREG_START(ID_ISAR0_EL1)
IDREG_END(ID_ISAR0_EL1)
IDREG_START(ID_ISAR1_EL1)
+ IDREG_FIELD(ID_ISAR1_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_ISAR1_EL1, Jazelle, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1735,6 +1774,7 @@ IDREG_START(ID_ISAR1_EL1)
IDREG_END(ID_ISAR1_EL1)
IDREG_START(ID_ISAR2_EL1)
+ IDREG_FIELD(ID_ISAR2_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_ISAR2_EL1, Reversal, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1780,6 +1820,7 @@ IDREG_START(ID_ISAR2_EL1)
IDREG_END(ID_ISAR2_EL1)
IDREG_START(ID_ISAR3_EL1)
+ IDREG_FIELD(ID_ISAR3_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_ISAR3_EL1, T32EE, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1817,6 +1858,7 @@ IDREG_START(ID_ISAR3_EL1)
IDREG_END(ID_ISAR3_EL1)
IDREG_START(ID_ISAR4_EL1)
+ IDREG_FIELD(ID_ISAR4_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_ISAR4_EL1, SWP_frac, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1855,6 +1897,7 @@ IDREG_START(ID_ISAR4_EL1)
IDREG_END(ID_ISAR4_EL1)
IDREG_START(ID_ISAR5_EL1)
+ IDREG_FIELD(ID_ISAR5_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_ISAR5_EL1, VCMA, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1863,6 +1906,7 @@ IDREG_START(ID_ISAR5_EL1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(ID_ISAR5_EL1, RDM)
+ IDREG_FIELD(ID_ISAR5_EL1, RES0, 20, 4)
IDREG_FIELD_START(ID_ISAR5_EL1, CRC32, 16, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1887,6 +1931,7 @@ IDREG_START(ID_ISAR5_EL1)
IDREG_END(ID_ISAR5_EL1)
IDREG_START(ID_ISAR6_EL1)
+ IDREG_FIELD(ID_ISAR6_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_ISAR6_EL1, CLRBHB, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1923,6 +1968,7 @@ IDREG_START(ID_ISAR6_EL1)
IDREG_END(ID_ISAR6_EL1)
IDREG_START(ID_MMFR0_EL1)
+ IDREG_FIELD(ID_MMFR0_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_MMFR0_EL1, InnerShr, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -1969,6 +2015,7 @@ IDREG_START(ID_MMFR0_EL1)
IDREG_END(ID_MMFR0_EL1)
IDREG_START(ID_MMFR1_EL1)
+ IDREG_FIELD(ID_MMFR1_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_MMFR1_EL1, BPred, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2017,6 +2064,7 @@ IDREG_START(ID_MMFR1_EL1)
IDREG_END(ID_MMFR1_EL1)
IDREG_START(ID_MMFR2_EL1)
+ IDREG_FIELD(ID_MMFR2_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_MMFR2_EL1, HWAccFlg, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2055,6 +2103,7 @@ IDREG_START(ID_MMFR2_EL1)
IDREG_END(ID_MMFR2_EL1)
IDREG_START(ID_MMFR3_EL1)
+ IDREG_FIELD(ID_MMFR3_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_MMFR3_EL1, Supersec, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(15)
@@ -2094,6 +2143,7 @@ IDREG_START(ID_MMFR3_EL1)
IDREG_END(ID_MMFR3_EL1)
IDREG_START(ID_MMFR4_EL1)
+ IDREG_FIELD(ID_MMFR4_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_MMFR4_EL1, EVT, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2131,6 +2181,7 @@ IDREG_START(ID_MMFR4_EL1)
IDREG_END(ID_MMFR4_EL1)
IDREG_START(ID_MMFR5_EL1)
+ IDREG_FIELD(ID_MMFR5_EL1, RES0, 8, 56)
IDREG_FIELD_START(ID_MMFR5_EL1, nTLBPA, 4, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2144,6 +2195,7 @@ IDREG_START(ID_MMFR5_EL1)
IDREG_END(ID_MMFR5_EL1)
IDREG_START(ID_PFR0_EL1)
+ IDREG_FIELD(ID_PFR0_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_PFR0_EL1, RAS, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2185,6 +2237,7 @@ IDREG_START(ID_PFR0_EL1)
IDREG_END(ID_PFR0_EL1)
IDREG_START(ID_PFR1_EL1)
+ IDREG_FIELD(ID_PFR1_EL1, RES0, 32, 32)
IDREG_FIELD_START(ID_PFR1_EL1, GIC, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2224,6 +2277,7 @@ IDREG_START(ID_PFR1_EL1)
IDREG_END(ID_PFR1_EL1)
IDREG_START(ID_PFR2_EL1)
+ IDREG_FIELD(ID_PFR2_EL1, RES0, 12, 52)
IDREG_FIELD_START(ID_PFR2_EL1, RAS_frac, 8, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2271,11 +2325,14 @@ IDREG_START(MIDR_EL1)
IDREG_END(MIDR_EL1)
IDREG_START(MPIDR_EL1)
+ IDREG_FIELD(MPIDR_EL1, RES0, 40, 24)
IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
+ IDREG_FIELD(MPIDR_EL1, RES1, 31, 1)
IDREG_FIELD_START(MPIDR_EL1, U, 30, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
IDREG_FIELD_END(MPIDR_EL1, U)
+ IDREG_FIELD(MPIDR_EL1, RES0, 25, 5)
IDREG_FIELD_START(MPIDR_EL1, MT, 24, 1)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2286,6 +2343,7 @@ IDREG_START(MPIDR_EL1)
IDREG_END(MPIDR_EL1)
IDREG_START(MVFR0_EL1)
+ IDREG_FIELD(MVFR0_EL1, RES0, 32, 32)
IDREG_FIELD_START(MVFR0_EL1, FPRound, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2324,6 +2382,7 @@ IDREG_START(MVFR0_EL1)
IDREG_END(MVFR0_EL1)
IDREG_START(MVFR1_EL1)
+ IDREG_FIELD(MVFR1_EL1, RES0, 32, 32)
IDREG_FIELD_START(MVFR1_EL1, SIMDFMAC, 28, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2362,6 +2421,7 @@ IDREG_START(MVFR1_EL1)
IDREG_END(MVFR1_EL1)
IDREG_START(MVFR2_EL1)
+ IDREG_FIELD(MVFR2_EL1, RES0, 8, 56)
IDREG_FIELD_START(MVFR2_EL1, FPMisc, 4, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2381,6 +2441,7 @@ IDREG_START(REVIDR_EL1)
IDREG_END(REVIDR_EL1)
IDREG_START(SMIDR_EL1)
+ IDREG_FIELD(SMIDR_EL1, RES0, 60, 4)
IDREG_FIELD_START(SMIDR_EL1, NSMC, 56, 4)
IDREG_FIELD_ARCH_VAL(0)
IDREG_FIELD_ARCH_VAL(1)
@@ -2445,6 +2506,7 @@ IDREG_START(SMIDR_EL1)
IDREG_FIELD_ARCH_VAL(2)
IDREG_FIELD_ARCH_VAL(3)
IDREG_FIELD_END(SMIDR_EL1, SH)
+ IDREG_FIELD(SMIDR_EL1, RES0, 12, 1)
IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
IDREG_END(SMIDR_EL1)
diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py
index 96f8aa2d64..0b4e4d3e0c 100644
--- a/scripts/update-aarch64-cpu-sysreg-properties.py
+++ b/scripts/update-aarch64-cpu-sysreg-properties.py
@@ -81,9 +81,13 @@ def collect_fields(item, bit_offset=0):
# Normal Field Types
leaf_types = ['Fields.Field', 'Fields.ConstantField',
- 'Fields.EnumeratedField', 'Fields.Bitfield']
+ 'Fields.EnumeratedField', 'Fields.Bitfield', 'Fields.Reserved']
if _type in leaf_types:
field_copy = item.copy()
+
+ if _type == 'Fields.Reserved' and not field_copy.get('name'):
+ field_copy['name'] = item.get('value', 'RES0')
+
if field_copy.get('rangeset'):
new_ranges = []
for r in field_copy['rangeset']:
@@ -96,7 +100,7 @@ def collect_fields(item, bit_offset=0):
return fields
# Traverse the hierarchy for other cases
- for key in ['fields', 'values', 'fieldsets']:
+ for key in ['fields', 'values', 'fieldsets', 'constants']:
for nested in item.get(key, []):
fields.extend(collect_fields(nested, bit_offset))
@@ -171,45 +175,96 @@ def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
final_output += f"IDREG_START({reg_name})\n"
- unique_fields = {}
+ fieldset_variants = []
+
for fieldset in register.get('fieldsets', []):
+ current_fieldset_fields = {}
candidates = collect_fields(fieldset)
+
for val in candidates:
- name = (val.get('name') or val.get('label', '')).strip()
- if not name or "RESERVED" in name.upper():
+ raw_name = val.get('name') or val.get('label') or val.get('value') or ''
+ name = raw_name.strip()
+ if not name:
continue
+
+ name_upper = name.upper()
+
+ # Check for architectural target states, including UNKNOWN remapping
+ base_reserved = None
+ for r_type in ["RES0", "RES1", "RAZ", "RAO", "WI", "UNKNOWN"]:
+ if r_type == name_upper:
+ base_reserved = "RES0" if r_type == "UNKNOWN" else r_type
+ break
+
+ is_valid_reserved = base_reserved is not None
+ if "RESERVED" in name_upper and not is_valid_reserved:
+ continue
+
+ # Force naming uniformity across padding blocks
+ if is_valid_reserved:
+ name = base_reserved
+
for r in val.get('rangeset', []):
lsb = int(r.get('start'))
width = r.get('width')
msb = lsb + int(width) - 1
- # Only keep the fields with the highest MSB
- # needed fir CCSIDR_EL1
- if name not in unique_fields or msb > unique_fields[name]['msb']:
- # extract enum values if any
+ if is_valid_reserved:
+ unique_key = f"{name}_{lsb}"
+ else:
+ unique_key = name
+
+ if unique_key not in current_fieldset_fields or \
+ msb > current_fieldset_fields[unique_key]['msb']:
enums = extract_field_enums(val)
- unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width, 'enums': enums}
+ current_fieldset_fields[unique_key] = {
+ 'raw_name': name,
+ 'lsb': lsb,
+ 'msb': msb,
+ 'width': width,
+ 'enums': enums
+ }
+
+ if current_fieldset_fields:
+ fieldset_variants.append(current_fieldset_fields)
+
+ best_fieldset = {}
+ max_total_width = -1
+
+ for variant in fieldset_variants:
+ total_width = sum(f['width'] for f in variant.values())
+ # prioritize layout variants with the highest MSB coverage
+ max_msb = max(f['msb'] for f in variant.values()) if variant else 0
+
+ # Combine width and max_msb into a fitness score tuple
+ if (total_width, max_msb) > (max_total_width, max_total_width):
+ max_total_width = total_width
+ best_fieldset = variant
+
+ unique_fields = best_fieldset
# Sort decreasing lsbs
sorted_fields = sorted(unique_fields.items(),
key=lambda x: x[1]['lsb'], reverse=True)
- for name, bits in sorted_fields:
+ for unique_key, bits in sorted_fields:
enums_list = bits.get('enums', [])
+ clean_name = bits.get('raw_name', unique_key)
+
if enums_list:
line = (f" IDREG_FIELD_START({reg_name}, "
- f"{name}, {bits['lsb']}, {bits['width']})\n")
+ f"{clean_name}, {bits['lsb']}, {bits['width']})\n")
else:
line = (f" IDREG_FIELD({reg_name}, "
- f"{name}, {bits['lsb']}, {bits['width']})\n")
+ f"{clean_name}, {bits['lsb']}, {bits['width']})\n")
final_output += line
# generate enum value or range if any
for enum_item in enums_list:
final_output += (f" IDREG_FIELD_ARCH_VAL({enum_item['value']})\n")
if enums_list:
- line = (f" IDREG_FIELD_END({reg_name}, {name})\n")
+ line = (f" IDREG_FIELD_END({reg_name}, {clean_name})\n")
final_output += line
final_output += f"IDREG_END({reg_name})\n"
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 20/26] target/arm/kvm: Ignore and trace unexpected writable reserved fields
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (18 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 19/26] target/arm/cpu-idregs.h.inc: Generate reserved fields Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 21/26] target/arm/kvm: add helper to test SYSREG props against a scratch vcpu Eric Auger
` (5 subsequent siblings)
25 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
KVM currently reports some bits as writable whereas they are
RES0 or RAZ. The code easily allows to do some sanity checking
for such inconsistencies. Let's add a trace event when this is
encountered and skip the field
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
v8 -> v9
- fix bug reported by Shameer (map &= ~MAKE_64BIT_MASK(lower,
field->length);)
---
target/arm/kvm.c | 10 ++++++++++
target/arm/trace-events | 1 +
2 files changed, 11 insertions(+)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index f52c03745e..537673177a 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -548,6 +548,16 @@ decode_idreg_writemap(Object *obj, ARM64SysReg *reg)
}
lower = field->shift;
upper = field->shift + field->length - 1;
+
+ /* Sanity check the field is not a reserved field */
+ if (strstr(field->name, "RES0") || strstr(field->name, "RES1") ||
+ strstr(field->name, "RAZ")) {
+ trace_unexpected_writable_reserved_field(reg->name, field->name,
+ lower, upper);
+ map &= ~MAKE_64BIT_MASK(lower, field->length);
+ i = ctz64(map);
+ continue;
+ }
prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name);
trace_decode_idreg_writemap(field->name, lower, upper, prop_name);
object_property_add(obj, prop_name, "uint64",
diff --git a/target/arm/trace-events b/target/arm/trace-events
index b4d2b45a7d..2a9cc67035 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -20,6 +20,7 @@ get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
+unexpected_writable_reserved_field(const char *reg_name, const char *field_name, int lower, int upper) "Unexpected writable reserved field: %s.%s [%d,%d], skip it ..."
# cpu.c
arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 21/26] target/arm/kvm: add helper to test SYSREG props against a scratch vcpu
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (19 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 20/26] target/arm/kvm: Ignore and trace unexpected writable " Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-28 13:34 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 22/26] target/arm/kvm: Add an error handle to kvm_arm_create_scratch_host_vcpu Eric Auger
` (4 subsequent siblings)
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Add kvm_idreg_write_scratch_vcpu helper that will be used
by qmp_query_cpu_model_expansion code to test SYSREG settings
against a scratch vcpu. Indeed when the expansion code is called
the actual vcpu has not been initialized so we use a scratch vcpu.
This latter has been initialized with features taken from
legacy compositive options (EL2, SVE, ...). So the trial is
very close to the final setup.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/kvm_arm.h | 4 ++++
target/arm/kvm-stub.c | 7 ++++++
target/arm/kvm.c | 51 +++++++++++++++++++++++++++++++++++++++++
target/arm/trace-events | 1 +
4 files changed, 63 insertions(+)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 2b3474cc36..bace69efed 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -14,6 +14,7 @@
#include "qapi/qapi-types-misc-arm.h"
#include "system/kvm.h"
#include "target/arm/cpu-qom.h"
+#include "cpu-idregs.h"
#define KVM_ARM_VGIC_V2 (1 << 0)
#define KVM_ARM_VGIC_V3 (1 << 1)
@@ -250,4 +251,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3);
*/
char *kvm_print_register_name(uint64_t regidx);
+bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
+ ARM64SysRegField *field, uint64_t newfv,
+ Error **errp);
#endif
diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
index 88cbe8d85c..8e6fae0a4d 100644
--- a/target/arm/kvm-stub.c
+++ b/target/arm/kvm-stub.c
@@ -119,3 +119,10 @@ char *kvm_print_register_name(uint64_t regidx)
{
g_assert_not_reached();
}
+
+bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
+ ARM64SysRegField *field, uint64_t newfv,
+ Error **errp)
+{
+ g_assert_not_reached();
+}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 537673177a..f7ca0e0250 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -447,6 +447,57 @@ static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
+bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
+ ARM64SysRegField *field, uint64_t newfv,
+ Error **errp)
+{
+ uint64_t mask, old_reg_val, new_reg_val, oldfv;
+ struct kvm_one_reg reg;
+ int lower = field->shift;
+ int length = field->length;
+ int index = field->index;
+ uint64_t kidx;
+ int ret;
+
+ mask = MAKE_64BIT_MASK(lower, length);
+
+ if (!kvm_arm_vcpu_validate_sysreg(cpu, field, newfv, errp)) {
+ return false;
+ };
+
+ kidx = idregs_sysreg_to_kvm_reg(id_register_sysreg[index]);
+ ret = read_sys_reg64(cpufd, &old_reg_val, kidx);
+ if (ret) {
+ error_setg(errp, "failed to read the scratch vcpu value for field %s %m",
+ field->name);
+ return false;
+ }
+ oldfv = (old_reg_val & mask) >> lower;
+
+ new_reg_val = old_reg_val & ~mask;
+ new_reg_val |= newfv << lower;
+
+ reg.id = kidx;
+ reg.addr = (uintptr_t)&new_reg_val;
+ ret = ioctl(cpufd, KVM_SET_ONE_REG, ®);
+ if (ret) {
+ error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s "
+ "(previous is 0x%"PRIx64"): %m", newfv, field->name, oldfv);
+ return false;
+ } else {
+ uint64_t check_val, actualfv;
+
+ ret = read_sys_reg64(cpufd, &check_val, kidx);
+ if (ret) {
+ error_setg(errp, "failed to read the new reg value: %m");
+ return false;
+ }
+ actualfv = (check_val & mask) >> lower;
+ trace_kvm_idreg_write_scratch_vcpu(field->name, oldfv, newfv, actualfv);
+ }
+ return true;
+}
+
static void set_sysreg_prop(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
diff --git a/target/arm/trace-events b/target/arm/trace-events
index 2a9cc67035..7a3f499a0e 100644
--- a/target/arm/trace-events
+++ b/target/arm/trace-events
@@ -21,6 +21,7 @@ set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_va
apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
unexpected_writable_reserved_field(const char *reg_name, const char *field_name, int lower, int upper) "Unexpected writable reserved field: %s.%s [%d,%d], skip it ..."
+kvm_idreg_write_scratch_vcpu(const char *name, uint64_t oldfv, uint64_t newfv, uint64_t actualfv) "successful dry-run for %s old=0x%"PRIx64" new=0x%"PRIx64" actual=0x%"PRIx64
# cpu.c
arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 22/26] target/arm/kvm: Add an error handle to kvm_arm_create_scratch_host_vcpu
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (20 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 21/26] target/arm/kvm: add helper to test SYSREG props against a scratch vcpu Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 23/26] target/arm/kvm: Introduce kvm_arm_vcpu_prepare_init_features helper Eric Auger
` (3 subsequent siblings)
25 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
This allows to report a precise error message if any error occurs.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/kvm_arm.h | 3 ++-
target/arm/kvm.c | 15 ++++++++++++---
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index bace69efed..185018e00c 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -106,6 +106,7 @@ struct kvm_vcpu_init;
* @init: filled in with the necessary values for creating a host
* vcpu. If NULL is provided, will not init the vCPU (though the cpufd
* will still be set up).
+ * @errp: Error handle
*
* Create a scratch vcpu in its own VM of the type preferred by the host
* kernel (as would be used for '-cpu host'), for purposes of probing it
@@ -115,7 +116,7 @@ struct kvm_vcpu_init;
* false on failure (and fdarray and init are not valid).
*/
bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
- struct kvm_vcpu_init *init);
+ struct kvm_vcpu_init *init, Error **errp);
/**
* kvm_arm_destroy_scratch_host_vcpu:
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index f7ca0e0250..43fb61bef4 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -107,13 +107,14 @@ static int kvm_arm_vcpu_finalize(ARMCPU *cpu, int feature)
}
bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
- struct kvm_vcpu_init *init)
+ struct kvm_vcpu_init *init, Error **errp)
{
int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
int max_vm_pa_size;
kvmfd = qemu_open_old("/dev/kvm", O_RDWR);
if (kvmfd < 0) {
+ error_setg(errp, "Failed opening /dev/kvm");
goto err;
}
max_vm_pa_size = ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_ARM_VM_IPA_SIZE);
@@ -124,6 +125,7 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
} while (vmfd == -1 && errno == EINTR);
if (vmfd < 0) {
+ error_setg(errp, "Failed creating the scratch VM");
goto err;
}
@@ -143,6 +145,7 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
if (cpufd < 0) {
+ error_setg(errp, "Failed creating the scratch VCPU");
goto err;
}
@@ -156,12 +159,14 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred);
if (ret < 0) {
+ error_setg(errp, "Failed getting the preferred target");
goto err;
}
init->target = preferred.target;
}
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
if (ret < 0) {
+ error_setg(errp, "Failed the init of the scratch vcpu");
goto err;
}
@@ -659,6 +664,7 @@ kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
bool el2_supported;
bool pmu_supported = false;
uint64_t features = 0;
+ Error *local_err = NULL;
int err;
ahcf->target = QEMU_KVM_ARM_TARGET_NONE;
@@ -706,7 +712,8 @@ kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
features |= 1ULL << ARM_FEATURE_PMU;
}
- if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) {
+ if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init, &local_err)) {
+ error_report_err(local_err);
return;
}
@@ -3093,8 +3100,10 @@ void arm_cpu_kvm_set_irq(void *arm_cpu, int irq, int level)
void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3)
{
int fdarray[3];
+ Error *err = NULL;
- if (!kvm_arm_create_scratch_host_vcpu(fdarray, NULL)) {
+ if (!kvm_arm_create_scratch_host_vcpu(fdarray, NULL, &err)) {
+ error_report_err(err);
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 23/26] target/arm/kvm: Introduce kvm_arm_vcpu_prepare_init_features helper
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (21 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 22/26] target/arm/kvm: Add an error handle to kvm_arm_create_scratch_host_vcpu Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 24/26] target/arm/kvm: Introduce kvm_arm_create_init_scratch_vcpu() Eric Auger
` (2 subsequent siblings)
25 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Factorize the code that initializes the kvm init features from the
cpu settings in a helper. Use it kvm_arch_init_vcpu(). Soon it will
be used by another function.
The only change in the code relates to the check of kvm_state. The
future caller won't have the VM created when calling the helper and
for this caller it is OK ignoring PSCI version setting.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/kvm.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 43fb61bef4..a459942a73 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2448,27 +2448,18 @@ static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
return 0;
}
-int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
+/* Determine init features for this CPU */
+static void kvm_arm_vcpu_prepare_init_features(ARMCPU *cpu)
{
- int ret;
- uint64_t mpidr;
- ARMCPU *cpu = ARM_CPU(cs);
+ CPUState *cs = CPU(cpu);
CPUARMState *env = &cpu->env;
- uint64_t psciver;
- if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
- error_setg(errp, "KVM is not supported for this guest CPU type");
- return -EINVAL;
- }
-
- qemu_add_vm_change_state_handler(kvm_arm_vm_state_change, cpu);
-
- /* Determine init features for this CPU */
memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
+
if (cs->start_powered_off) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
}
- if (cpu->psci_version != QEMU_PSCI_VERSION_0_1 &&
+ if (cpu->psci_version != QEMU_PSCI_VERSION_0_1 && cs->kvm_state &&
kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
/*
* Versions >= v0.2 are backward compatible with v0.2
@@ -2492,6 +2483,23 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
if (cpu->has_el2 && kvm_arm_el2_supported()) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_HAS_EL2;
}
+}
+
+int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
+{
+ int ret;
+ uint64_t mpidr;
+ ARMCPU *cpu = ARM_CPU(cs);
+ uint64_t psciver;
+
+ if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
+ error_setg(errp, "KVM is not supported for this guest CPU type");
+ return -EINVAL;
+ }
+
+ qemu_add_vm_change_state_handler(kvm_arm_vm_state_change, cpu);
+
+ kvm_arm_vcpu_prepare_init_features(cpu);
/* Do KVM_ARM_VCPU_INIT ioctl */
ret = kvm_arm_vcpu_init(cpu);
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 24/26] target/arm/kvm: Introduce kvm_arm_create_init_scratch_vcpu()
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (22 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 23/26] target/arm/kvm: Introduce kvm_arm_vcpu_prepare_init_features helper Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 25/26] arm-qmp-cmds: introspection for ID register props Eric Auger
2026-09-16 14:45 ` [PATCH v9 26/26] arm/cpu-features: document ID reg properties Eric Auger
25 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
Introduce kvm_arm_create_init_scratch_vcpu() that allows to create
and initialize a scratch vcpu from cpu settings. We want to use
this in arm-qmp-cmds code as well as kvm_arm_destroy_scratch_host_vcpu
so export them.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/kvm_arm.h | 11 +++++++++++
target/arm/kvm-stub.c | 10 ++++++++++
target/arm/kvm.c | 14 ++++++++++++++
3 files changed, 35 insertions(+)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 185018e00c..4ce58d6b0e 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -118,6 +118,17 @@ struct kvm_vcpu_init;
bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
struct kvm_vcpu_init *init, Error **errp);
+/**
+ * kvm_arm_create_init_scratch_vcpu:
+ * Create and initialize a scratch vcpu inheriting the features set
+ * on the vcpu
+ *
+ * Return the vcpu fd on success or -1 on failure with a corresponding
+ * Error handle
+ */
+int kvm_arm_create_init_scratch_vcpu(ARMCPU *cpu, Error **errp);
+
+
/**
* kvm_arm_destroy_scratch_host_vcpu:
* @fdarray: array of fds as set up by kvm_arm_create_scratch_host_vcpu
diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
index 8e6fae0a4d..dd2e94e45f 100644
--- a/target/arm/kvm-stub.c
+++ b/target/arm/kvm-stub.c
@@ -126,3 +126,13 @@ bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
{
g_assert_not_reached();
}
+
+int kvm_arm_create_init_scratch_vcpu(ARMCPU *cpu, Error **errp)
+{
+ g_assert_not_reached();
+}
+
+void kvm_arm_destroy_scratch_host_vcpu(int *fdarray)
+{
+ g_assert_not_reached();
+}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index a459942a73..800e5f3020 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2485,6 +2485,20 @@ static void kvm_arm_vcpu_prepare_init_features(ARMCPU *cpu)
}
}
+int kvm_arm_create_init_scratch_vcpu(ARMCPU *cpu, Error **errp)
+{
+ struct kvm_vcpu_init init = {.target = cpu->kvm_target, };
+ int fdarray[3];
+
+ kvm_arm_vcpu_prepare_init_features(cpu);
+ memcpy(init.features, cpu->kvm_init_features, sizeof(init.features));
+
+ if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init, errp)) {
+ return -1;
+ }
+ return fdarray[2];
+}
+
int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
{
int ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 25/26] arm-qmp-cmds: introspection for ID register props
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (23 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 24/26] target/arm/kvm: Introduce kvm_arm_create_init_scratch_vcpu() Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
2026-09-28 14:39 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 26/26] arm/cpu-features: document ID reg properties Eric Auger
25 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
From: Cornelia Huck <cohuck@redhat.com>
Enhance the current host model query-cpu-model-expansion with the
capability to return SYSREG_* options and also test possible
values.
If no SYSREG prop is set, query-cpu-model-expansion returns the
default host values for all SYSREG properties. They are extracted
from a scratch vcpu featuring all the KVM advertised capabilities.
Here is a qmp-shell example:
(QEMU) query-cpu-model-expansion type=full model={"name":"host"}
{"return": {"model": {"name": "host", "props": {"SYSREG_ID_AA64PFR0_EL1_EL3": 1,
"SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0, "SYSREG_CTR_EL0_L1Ip": 3,
"SYSREG_MIDR_EL1_PartNum": 3407, "SYSREG_CTR_EL0_DminLine": 4,
"SYSREG_ID_AA64MMFR0_EL1_PARange": 5, "SYSREG_ID_AA64MMFR1_EL1_ECBHB": 0
../..
It becomes also possible to test new SYSREG property values.
With Full expansion of the host model, the SYSREG props are tested
against a scratch vcpu. With static expansion, no check is performed
against KVM but only against qemu code (the value does not exceed the
field size and if the field is associated to enum values, the set
value belongs to the list of arch enum values.
Examples
(QEMU) query-cpu-model-expansion type=full model={"name":"host","props":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x13}}
{"error": {"class": "GenericError", "desc": "idreg SYSREG_ID_AA64ISAR0_EL1_DP set value (0x13) exceeds length of field (4)!"}}
(QEMU) query-cpu-model-expansion type=full model={"name":"host","props":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x2}}
{"error": {"class": "GenericError", "desc": "idreg SYSREG_ID_AA64ISAR0_EL1_DP set value (0x2) does not match any arch valid enum value!"}}
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
v8 -> v9:
- fix the leak reported by Khushit
- implement static mode for host
v7 -> v8:
- do not check if the prop exists (this is checked elsewhere with a
different error message)
- clarify that examples given in the commit msg are based on qmp-shell
v5 -> v6:
- add the write capability
---
target/arm/arm-qmp-cmds.c | 107 ++++++++++++++++++++++++++++++++++++--
1 file changed, 104 insertions(+), 3 deletions(-)
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 83ec95c290..b52ca67f83 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -21,6 +21,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "qemu/target-info.h"
#include "hw/core/boards.h"
#include "kvm_arm.h"
@@ -30,6 +31,7 @@
#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-misc-arm.h"
#include "qobject/qdict.h"
+#include "qobject/qnum.h"
#include "qom/qom-qobject.h"
#include "cpu.h"
@@ -83,15 +85,20 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
CpuModelInfo *model,
Error **errp)
{
+ bool use_scratch_vcpu = kvm_enabled() && type == CPU_MODEL_EXPANSION_TYPE_FULL;
CpuModelExpansionInfo *expansion_info;
+ ObjectPropertyIterator iter;
const QDict *qdict_in;
+ ObjectProperty *idregprop;
QDict *qdict_out;
ObjectClass *oc;
Object *obj;
const char *name;
+ int fdarray[3];
int i;
- if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
+ /* we support static expansion for host model only */
+ if (type != CPU_MODEL_EXPANSION_TYPE_FULL && strcmp(model->name, "host")) {
error_setg(errp, "The requested expansion type is not supported");
return NULL;
}
@@ -136,6 +143,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
if (model->props) {
Visitor *visitor;
Error *err = NULL;
+ int fd = -1;
visitor = qobject_input_visitor_new(model->props);
if (!visit_start_struct(visitor, "model.props", NULL, 0, errp)) {
@@ -146,6 +154,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
qdict_in = qobject_to(QDict, model->props);
i = 0;
+
+ /* Test legacy composite option settings */
while ((name = cpu_model_advertised_features[i++]) != NULL) {
if (qdict_get(qdict_in, name)) {
if (!object_property_set(obj, name, visitor, &err)) {
@@ -154,11 +164,85 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
}
}
+ if (!err) {
+ arm_cpu_finalize_features(ARM_CPU(obj), &err);
+ }
+
+ /**
+ * Test SYSREG option settings
+ * In full mode, build a scratch vcpu that reflects composite legacy
+ * options
+ */
+ if (use_scratch_vcpu) {
+ Error *local_err = NULL;
+ bool has_virt = object_property_get_bool(OBJECT(current_machine),
+ "virtualization",
+ &local_err);
+
+ if (local_err) {
+ error_free(local_err); /* the machine property does not exist */
+ } else {
+ if (!has_virt && object_property_find(obj, "has_el2")) {
+ object_property_set_bool(obj, "has_el2", false, NULL);
+ }
+ }
+ fd = kvm_arm_create_init_scratch_vcpu(ARM_CPU(obj), errp);
+ if (fd < 0) {
+ return NULL;
+ }
+ }
+
+ qdict_in = qobject_to(QDict, model->props);
+ for (const QDictEntry *entry = qdict_first(qdict_in);
+ entry != NULL; entry = qdict_next(qdict_in, entry)) {
+ const char *key = qdict_entry_key(entry);
+ QObject *val_obj = qdict_entry_value(entry);
+ ObjectProperty *prop;
+ Visitor *v;
+ bool success;
+ uint64_t val;
+
+ prop = object_property_find(obj, key);
+
+ if (!g_str_has_prefix(key, "SYSREG_")) {
+ continue;
+ }
+
+ /* consume the prop to avoid unexpected parameter */
+ if (!visit_type_uint64(visitor, key, &val, errp)) {
+ goto bail_out;
+ }
+
+ v = qobject_input_visitor_new(val_obj);
+
+ if (!object_property_set(obj, key, v, errp)) {
+ goto bail_out;
+ }
+
+ if (use_scratch_vcpu) {
+ ARM64SysRegField *field = (ARM64SysRegField *)prop->opaque;
+ uint64_t newfv;
+
+ if (!visit_type_uint64(v, name, &newfv, errp)) {
+ visit_free(v);
+ goto bail_out;
+ }
+ success = kvm_idreg_write_scratch_vcpu(ARM_CPU(obj), fd,
+ field, newfv, errp);
+ if (!success) {
+ visit_free(v);
+ goto bail_out;
+ }
+ }
+ visit_free(v);
+ }
+
if (!err) {
visit_check_struct(visitor, &err);
}
- if (!err) {
- arm_cpu_finalize_features(ARM_CPU(obj), &err);
+
+ if (use_scratch_vcpu) {
+ kvm_arm_destroy_scratch_host_vcpu(fdarray);
}
visit_end_struct(visitor, NULL);
visit_free(visitor);
@@ -190,6 +274,18 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
}
}
+ object_property_iter_init(&iter, obj);
+
+ while ((idregprop = object_property_iter_next(&iter))) {
+ QObject *value;
+
+ if (!g_str_has_prefix(idregprop->name, "SYSREG_")) {
+ continue;
+ }
+ value = object_property_get_qobject(obj, idregprop->name, &error_abort);
+ qdict_put_obj(qdict_out, idregprop->name, value);
+ }
+
if (!qdict_size(qdict_out)) {
qobject_unref(qdict_out);
} else {
@@ -199,6 +295,11 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
object_unref(obj);
return expansion_info;
+bail_out:
+ if (use_scratch_vcpu) {
+ kvm_arm_destroy_scratch_host_vcpu(fdarray);
+ }
+ return NULL;
}
static void arm_cpu_add_definition(gpointer data, gpointer user_data)
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* [PATCH v9 26/26] arm/cpu-features: document ID reg properties
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
` (24 preceding siblings ...)
2026-09-16 14:45 ` [PATCH v9 25/26] arm-qmp-cmds: introspection for ID register props Eric Auger
@ 2026-09-16 14:45 ` Eric Auger
25 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-16 14:45 UTC (permalink / raw)
To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, kvmarm,
peter.maydell, shaju.abraham, khushit.shah, yangjinqian1, cohuck,
richard.henderson, sebott, skolothumtho, philmd
Cc: maz, oliver.upton, pbonzini, armbru, berrange, abologna, jdenemar
From: Cornelia Huck <cohuck@redhat.com>
Add some documentation for how individual ID registers can be
configured with the host cpu model.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
docs/system/arm/cpu-features.rst | 100 ++++++++++++++++++++++++++++---
1 file changed, 92 insertions(+), 8 deletions(-)
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index 10b0eff27e..e298e3f503 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -2,7 +2,10 @@ Arm CPU Features
================
CPU features are optional features that a CPU of supporting type may
-choose to implement or not. In QEMU, optional CPU features have
+choose to implement or not. QEMU provides two different mechanisms
+to configure those features:
+
+1. For most CPU models, optional CPU features may have
corresponding boolean CPU proprieties that, when enabled, indicate
that the feature is implemented, and, conversely, when disabled,
indicate that it is not implemented. An example of an Arm CPU feature
@@ -31,6 +34,31 @@ running guests in AArch32.
CPU features that are inherently specific to KVM are
prefixed with "kvm-" and are described in "KVM VCPU Features".
+2. Additionally, the ``host`` CPU model on KVM allows to overwrite
+a subset of the ID register fields. Not all ID register fields are
+writable: this depends on host. For those which are writable, and for
+those only, the host model exposes SYSREG_<IDREG>_<FIELD> properties.
+IDREG and FIELD names are those used in the ARM Architecture Reference
+Manual.
+
+Values set with those properties override the initial values retrieved
+from the vcpu after legacy composite property settings (sve, pauth, ...)
+have applied, would it be at machine level of vcpu level.
+
+SYSREG_<IDREG>_<FIELD> properties are applied at the end of the chain
+and do not substitute to legacy composite options. In other words, if
+you want to use pauth, you still need to set pauth=on. Indeed legacy
+options do more than exposing a different value for ID registers. They
+may also interact with KVM to prepare the VCPU for this feature (for
+instance at VCPU init time). Whereas SYSREG_<IDREG>_<FIELD> properties
+only change the final value of the ID register. Inconsistent settings
+between legacy composite options (at machine level of cpu level) which
+impact vcpu and low level SYSREG_<IDREG>_<FIELD> are forbidden and are
+rejected at best. SYSREG_<IDREG>_<FIELD> properties are essentially used
+to tune the host vcpu model so that it allows migration between different
+hardware.
+
+
CPU Feature Probing
===================
@@ -126,13 +154,20 @@ A note about CPU models and KVM
Named CPU models generally do not work with KVM. There are a few cases
that do work, e.g. using the named CPU model ``cortex-a57`` with KVM on a
-seattle host, but mostly if KVM is enabled the ``host`` CPU type must be
-used. This means the guest is provided all the same CPU features as the
-host CPU type has. And, for this reason, the ``host`` CPU type should
-enable all CPU features that the host has by default. Indeed it's even
-a bit strange to allow disabling CPU features that the host has when using
-the ``host`` CPU type, but in the absence of CPU models it's the best we can
-do if we want to launch guests without all the host's CPU features enabled.
+seattle host, but mostly if KVM is enabled, the ``host`` CPU model must be
+used.
+
+Using the ``host`` type means the guest is provided all the same CPU
+features as the host CPU type has. And, for this reason, the ``host``
+CPU type should enable all CPU features that the host has by default.
+
+In case some features need to be hidden from the guest, and the host kernel
+supports it, the ``host`` model can be instructed to disable individual
+ID register values. This is especially useful for migration purposes.
+However, this interface will not allow configuring an arbitrary set of
+features; the ID registers must describe a subset of the host's features,
+and all differences to the host's configuration must actually be supported
+by the kernel to be deconfigured.
Enabling KVM also affects the ``query-cpu-model-expansion`` QMP command. The
affect is not only limited to specific features, as pointed out in example
@@ -169,6 +204,13 @@ disabling many SVE vector lengths would be quite verbose, the ``sve<N>`` CPU
properties have special semantics (see "SVE CPU Property Parsing
Semantics").
+Additionally, if supported by KVM on the host kernel, the ``host`` CPU model
+may be configured via individual ID register field properties, for example::
+
+ $ qemu-system-aarch64 -M virt -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0
+
+This forces ID_AA64ISAR0_EL1 DP field to 0.
+
KVM VCPU Features
=================
@@ -495,3 +537,45 @@ Legal values for ``S`` are 30, 34, 36, and 39; the default is 30.
As with ``x-rme``, the ``x-l0gptsz`` property may be renamed or
removed in some future QEMU release.
+
+Configuring CPU features via ID register fields
+===============================================
+
+Note that this is currently only supported under KVM, and with the
+``host`` CPU model.
+
+Querying available ID register fields
+-------------------------------------
+
+QEMU will create properties for all ID register fields that are
+reported as being writable by the kernel, and that are known to the
+QEMU instance. Therefore, the same QEMU binary may expose different
+properties when run under a different kernel.
+
+To find out all available writable ID register fields, use the
+``query-cpu-model-expansion`` QMP command::
+
+ (QEMU) query-cpu-model-expansion type=full model={"name":"host"}
+ {"return": {
+ "model": {"name": "host", "props": {
+ "SYSREG_ID_AA64PFR0_EL1_EL3": 1, "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0,
+ "SYSREG_CTR_EL0_L1Ip": 3, "SYSREG_CTR_EL0_DminLine": 4,
+ "SYSREG_ID_AA64MMFR0_EL1_BIGEND": 1, "SYSREG_ID_AA64MMFR1_EL1_ECBHB": 0,
+ "SYSREG_ID_AA64MMFR2_EL1_CnP": 1, "SYSREG_ID_DFR0_EL1_PerfMon": 4,
+ "SYSREG_ID_AA64PFR0_EL1_DIT": 0, "SYSREG_ID_AA64MMFR1_EL1_HAFDBS": 2,
+ "SYSREG_ID_AA64ISAR0_EL1_FHM": 0, "SYSREG_ID_AA64ISAR2_EL1_CSSC": 0,
+ "SYSREG_ID_AA64ISAR0_EL1_DP": 1, (...)
+ }}}}
+
+If a certain field in an ID register does not show up in this list, it
+is not writable with the specific host kernel.
+
+A note on compatibility
+-----------------------
+
+A common use case for providing a defined set of ID register values is
+to be able to present a fixed set of features to a guest, often referred
+to as "stable guest ABI". This may take the form of ironing out differences
+between two similar CPUs with the intention of being able to migrate
+between machines with those CPUs, or providing the same CPU across Linux
+kernel updates on the host.
--
2.53.0
^ permalink raw reply related [flat|nested] 82+ messages in thread
* Re: [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py
2026-09-16 14:45 ` [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
@ 2026-09-23 7:08 ` Khushit Shah
2026-09-23 14:22 ` Eric Auger
2026-09-24 10:24 ` Khushit Shah
1 sibling, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-23 7:08 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Introduce a script that takes as input the Registers.json file
> delivered in the AARCHMRS Features Model downloadable from the
> Arm Developer A-Profile Architecture Exploration Tools page:
> https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
> and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
> under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>).
>
> We only care about IDregs with opcodes satisfying:
> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> [CH: note correct op1 range, don't skip CCSIDR]
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> Message-ID: <20251208163751.611186-2-eric.auger@redhat.com>
Nit: unintended?
Also, now Cornelia’s comment does not apply… (we are actively skipping CCSIDR)
> ---
> scripts/update-aarch64-cpu-sysregs-header.py | 146 +++++++++++++++++++
> 1 file changed, 146 insertions(+)
> create mode 100755 scripts/update-aarch64-cpu-sysregs-header.py
>
> diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
> new file mode 100755
> index 0000000000..ef1471a197
> --- /dev/null
> +++ b/scripts/update-aarch64-cpu-sysregs-header.py
> @@ -0,0 +1,146 @@
> +#!/usr/bin/env python3
> +
> +# This script takes as input the Registers.json file delivered in
> +# the AARCHMRS Features Model downloadable from the Arm Developer
> +# A-Profile Architecture Exploration Tools page:
> +# https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
> +# and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
> +# under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
> +#
> +# Copyright (C) 2026 Red Hat, Inc.
> +#
> +# Authors: Eric Auger <eric.auger@redhat.com>
> +#
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +
> +
> +import json
> +import os
> +import sys
> +
> +def is_demux_register(r):
> + name = r.get('name', '')
> +
> + if name.startswith("CCSIDR"):
> + return True
> +
> + return False
> +
> +# Some regs have op code values like 000x, 001x. Anyway we don't need
> +# them. Besides some regs are undesired in the generated file such as
> +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
> +# are interested in and are tricky to decode as their system accessor
> +# refer to MPIDR_EL1/MIDR_EL1 respectively
> +
> +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
> + 'VMPIDR_EL2', 'VPIDR_EL2']
> +
> +# returns the int value of a given @opcode for a reg @encoding
> +def get_opcode(encoding, opcode):
> + fvalue = encoding.get(opcode)
> + if fvalue:
> + value = fvalue.get('value')
> + if isinstance(value, str):
> + value = value.strip("'")
> + value = int(value, 2)
> + return value
> + return -1
> +
> +def extract_idregs_from_registers_json(filename):
> + """
> + Load a Registers.json file and extract all ID registers, decode their
> + opcode and dump the information in target/arm/cpu-sysregs.h.inc
> +
> + Args:
> + filename (str): The path to the Registers.json
> + returns:
> + idregs: list of ID regs and their encoding
> + """
> + if not os.path.exists(filename):
> + print(f"Error: {filename} could not be found!")
> + return {}
> +
> + try:
> + with open(filename, 'r') as f:
> + register_data = json.load(f)
> +
> + except json.JSONDecodeError:
> + print(f"Could not decode json from '{filename}'!")
> + return {}
> + except Exception as e:
> + print(f"Unexpected error while reading {filename}: {e}")
> + return {}
> +
> + registers = [
> + r for r in register_data
> + if isinstance(r, dict)
> + and r.get('_type') == 'Register'
> + and not is_demux_register(r)
> + ]
> +
> + idregs = {}
> +
> + for register in registers:
> + reg_name = register.get('name')
> +
> + is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
> +
> + if reg_name and not is_skipped:
> + accessors = register.get('accessors', [])
> +
> + for accessor in accessors:
> + type = accessor.get('_type')
> + if type in ['Accessors.SystemAccessor']:
> + encoding_list = accessor.get('encoding')
> +
> + if isinstance(encoding_list, list) and encoding_list and \
> + isinstance(encoding_list[0], dict):
> + encoding_wrapper = encoding_list[0]
> + encoding_source = encoding_wrapper.get('encodings', \
> + encoding_wrapper)
> +
> + if isinstance(encoding_source, dict):
> + op0 = get_opcode(encoding_source, 'op0')
> + op1 = get_opcode(encoding_source, 'op1')
> + op2 = get_opcode(encoding_source, 'op2')
> + crn = get_opcode(encoding_source, 'CRn')
> + crm = get_opcode(encoding_source, 'CRm')
> + encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
> +
> + # ID regs are assumed within this scope
> + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
> + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
> + idregs[reg_name] = encoding_str
> +
> + return idregs
> +
> +if __name__ == "__main__":
> + # Single arg expected: the path to the Registers.json file
> + if len(sys.argv) < 2:
> + print("Usage: python scripts/update-aarch64-cpu-sysregs-header.py "
> + "<path_to_registers_json>")
> + sys.exit(1)
> + else:
> + json_file_path = sys.argv[1]
> +
> + extracted_registers = extract_idregs_from_registers_json(json_file_path)
> +
> + if extracted_registers:
> + output_list = extracted_registers.items()
> +
> + # Sort by register name
> + sorted_output = sorted(output_list, key=lambda item: item[0])
> +
> + # format lines as DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
> + final_output = ""
> + for reg_name, encoding in sorted_output:
> + reformatted_encoding = encoding.replace(" ", ", ")
> + final_output += f"DEF({reg_name}, {reformatted_encoding})\n"
> +
> + with open("target/arm/cpu-sysregs.h.inc", 'w') as f:
> + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
> + f.write("/* This file is autogenerated by ")
> + f.write("scripts/update-aarch64-cpu-sysregs-header.py */\n")
> + f.write("/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */\n\n")
> + f.write(final_output)
> + print("updated target/arm/cpu-sysregs.h.inc")
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 03/26] target/arm/cpu-sysregs.h.inc: Update with automatic generation
2026-09-16 14:45 ` [PATCH v9 03/26] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger
@ 2026-09-23 9:13 ` Khushit Shah
2026-09-23 14:31 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-23 9:13 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Generated definitions with scripts/update-aarch64-cpu-sysregs-header.py
> based on "AARCHMRS containing the JSON files for Arm A-profile
> architecture (2026-03)" Registers.json file.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
> ---
> target/arm/cpu-sysregs.h.inc | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
> index ec5a12b0f4..8b77c490d4 100644
> --- a/target/arm/cpu-sysregs.h.inc
> +++ b/target/arm/cpu-sysregs.h.inc
> @@ -1,11 +1,18 @@
> /* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +/* This file is autogenerated by scripts/update-aarch64-cpu-sysregs-header.py */
> +/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */
> +
> +DEF(AIDR_EL1, 3, 1, 0, 0, 7)
> DEF(CLIDR_EL1, 3, 1, 0, 0, 1)
> DEF(CTR_EL0, 3, 3, 0, 0, 1)
> DEF(DCZID_EL0, 3, 3, 0, 0, 7)
> +DEF(GMID_EL1, 3, 1, 0, 0, 4)
> DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4)
> DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5)
> DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0)
> DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1)
> +DEF(ID_AA64DFR2_EL1, 3, 0, 0, 5, 2)
> DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7)
> DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0)
> DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1)
> @@ -40,6 +47,10 @@ DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6)
> DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
> DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
> DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
> +DEF(MIDR_EL1, 3, 0, 0, 0, 0)
> +DEF(MPIDR_EL1, 3, 0, 0, 0, 5)
> 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(REVIDR_EL1, 3, 0, 0, 0, 6)
> +DEF(SMIDR_EL1, 3, 1, 0, 0, 6)
After this, we should probably refactor cpu->midr/revidr/mp_affinity into the idregs[]?
Warm Regards,
Khushit
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py
2026-09-23 7:08 ` Khushit Shah
@ 2026-09-23 14:22 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-23 14:22 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Khushit,
On 9/23/26 9:08 AM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Introduce a script that takes as input the Registers.json file
>> delivered in the AARCHMRS Features Model downloadable from the
>> Arm Developer A-Profile Architecture Exploration Tools page:
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
>> and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
>> under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>).
>>
>> We only care about IDregs with opcodes satisfying:
>> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> [CH: note correct op1 range, don't skip CCSIDR]
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> Message-ID: <20251208163751.611186-2-eric.auger@redhat.com>
> Nit: unintended?
> Also, now Cornelia’s comment does not apply… (we are actively skipping CCSIDR)
effectively those mentions can be removed now
Thanks
Eric
>
>> ---
>> scripts/update-aarch64-cpu-sysregs-header.py | 146 +++++++++++++++++++
>> 1 file changed, 146 insertions(+)
>> create mode 100755 scripts/update-aarch64-cpu-sysregs-header.py
>>
>> diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
>> new file mode 100755
>> index 0000000000..ef1471a197
>> --- /dev/null
>> +++ b/scripts/update-aarch64-cpu-sysregs-header.py
>> @@ -0,0 +1,146 @@
>> +#!/usr/bin/env python3
>> +
>> +# This script takes as input the Registers.json file delivered in
>> +# the AARCHMRS Features Model downloadable from the Arm Developer
>> +# A-Profile Architecture Exploration Tools page:
>> +# https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
>> +# and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
>> +# under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
>> +#
>> +# Copyright (C) 2026 Red Hat, Inc.
>> +#
>> +# Authors: Eric Auger <eric.auger@redhat.com>
>> +#
>> +# SPDX-License-Identifier: GPL-2.0-or-later
>> +
>> +
>> +import json
>> +import os
>> +import sys
>> +
>> +def is_demux_register(r):
>> + name = r.get('name', '')
>> +
>> + if name.startswith("CCSIDR"):
>> + return True
>> +
>> + return False
>> +
>> +# Some regs have op code values like 000x, 001x. Anyway we don't need
>> +# them. Besides some regs are undesired in the generated file such as
>> +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
>> +# are interested in and are tricky to decode as their system accessor
>> +# refer to MPIDR_EL1/MIDR_EL1 respectively
>> +
>> +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
>> + 'VMPIDR_EL2', 'VPIDR_EL2']
>> +
>> +# returns the int value of a given @opcode for a reg @encoding
>> +def get_opcode(encoding, opcode):
>> + fvalue = encoding.get(opcode)
>> + if fvalue:
>> + value = fvalue.get('value')
>> + if isinstance(value, str):
>> + value = value.strip("'")
>> + value = int(value, 2)
>> + return value
>> + return -1
>> +
>> +def extract_idregs_from_registers_json(filename):
>> + """
>> + Load a Registers.json file and extract all ID registers, decode their
>> + opcode and dump the information in target/arm/cpu-sysregs.h.inc
>> +
>> + Args:
>> + filename (str): The path to the Registers.json
>> + returns:
>> + idregs: list of ID regs and their encoding
>> + """
>> + if not os.path.exists(filename):
>> + print(f"Error: {filename} could not be found!")
>> + return {}
>> +
>> + try:
>> + with open(filename, 'r') as f:
>> + register_data = json.load(f)
>> +
>> + except json.JSONDecodeError:
>> + print(f"Could not decode json from '{filename}'!")
>> + return {}
>> + except Exception as e:
>> + print(f"Unexpected error while reading {filename}: {e}")
>> + return {}
>> +
>> + registers = [
>> + r for r in register_data
>> + if isinstance(r, dict)
>> + and r.get('_type') == 'Register'
>> + and not is_demux_register(r)
>> + ]
>> +
>> + idregs = {}
>> +
>> + for register in registers:
>> + reg_name = register.get('name')
>> +
>> + is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
>> +
>> + if reg_name and not is_skipped:
>> + accessors = register.get('accessors', [])
>> +
>> + for accessor in accessors:
>> + type = accessor.get('_type')
>> + if type in ['Accessors.SystemAccessor']:
>> + encoding_list = accessor.get('encoding')
>> +
>> + if isinstance(encoding_list, list) and encoding_list and \
>> + isinstance(encoding_list[0], dict):
>> + encoding_wrapper = encoding_list[0]
>> + encoding_source = encoding_wrapper.get('encodings', \
>> + encoding_wrapper)
>> +
>> + if isinstance(encoding_source, dict):
>> + op0 = get_opcode(encoding_source, 'op0')
>> + op1 = get_opcode(encoding_source, 'op1')
>> + op2 = get_opcode(encoding_source, 'op2')
>> + crn = get_opcode(encoding_source, 'CRn')
>> + crm = get_opcode(encoding_source, 'CRm')
>> + encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
>> +
>> + # ID regs are assumed within this scope
>> + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
>> + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
>> + idregs[reg_name] = encoding_str
>> +
>> + return idregs
>> +
>> +if __name__ == "__main__":
>> + # Single arg expected: the path to the Registers.json file
>> + if len(sys.argv) < 2:
>> + print("Usage: python scripts/update-aarch64-cpu-sysregs-header.py "
>> + "<path_to_registers_json>")
>> + sys.exit(1)
>> + else:
>> + json_file_path = sys.argv[1]
>> +
>> + extracted_registers = extract_idregs_from_registers_json(json_file_path)
>> +
>> + if extracted_registers:
>> + output_list = extracted_registers.items()
>> +
>> + # Sort by register name
>> + sorted_output = sorted(output_list, key=lambda item: item[0])
>> +
>> + # format lines as DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
>> + final_output = ""
>> + for reg_name, encoding in sorted_output:
>> + reformatted_encoding = encoding.replace(" ", ", ")
>> + final_output += f"DEF({reg_name}, {reformatted_encoding})\n"
>> +
>> + with open("target/arm/cpu-sysregs.h.inc", 'w') as f:
>> + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
>> + f.write("/* This file is autogenerated by ")
>> + f.write("scripts/update-aarch64-cpu-sysregs-header.py */\n")
>> + f.write("/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */\n\n")
>> + f.write(final_output)
>> + print("updated target/arm/cpu-sysregs.h.inc")
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 03/26] target/arm/cpu-sysregs.h.inc: Update with automatic generation
2026-09-23 9:13 ` Khushit Shah
@ 2026-09-23 14:31 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-23 14:31 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/23/26 11:13 AM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Generated definitions with scripts/update-aarch64-cpu-sysregs-header.py
>> based on "AARCHMRS containing the JSON files for Arm A-profile
>> architecture (2026-03)" Registers.json file.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
>> ---
>> target/arm/cpu-sysregs.h.inc | 11 +++++++++++
>> 1 file changed, 11 insertions(+)
>>
>> diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc
>> index ec5a12b0f4..8b77c490d4 100644
>> --- a/target/arm/cpu-sysregs.h.inc
>> +++ b/target/arm/cpu-sysregs.h.inc
>> @@ -1,11 +1,18 @@
>> /* SPDX-License-Identifier: GPL-2.0-or-later */
>> +
>> +/* This file is autogenerated by scripts/update-aarch64-cpu-sysregs-header.py */
>> +/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */
>> +
>> +DEF(AIDR_EL1, 3, 1, 0, 0, 7)
>> DEF(CLIDR_EL1, 3, 1, 0, 0, 1)
>> DEF(CTR_EL0, 3, 3, 0, 0, 1)
>> DEF(DCZID_EL0, 3, 3, 0, 0, 7)
>> +DEF(GMID_EL1, 3, 1, 0, 0, 4)
>> DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4)
>> DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5)
>> DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0)
>> DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1)
>> +DEF(ID_AA64DFR2_EL1, 3, 0, 0, 5, 2)
>> DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7)
>> DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0)
>> DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1)
>> @@ -40,6 +47,10 @@ DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6)
>> DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0)
>> DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1)
>> DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4)
>> +DEF(MIDR_EL1, 3, 0, 0, 0, 0)
>> +DEF(MPIDR_EL1, 3, 0, 0, 0, 5)
>> 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(REVIDR_EL1, 3, 0, 0, 0, 6)
>> +DEF(SMIDR_EL1, 3, 1, 0, 0, 6)
> After this, we should probably refactor cpu->midr/revidr/mp_affinity into the idregs[]?
Hum yes. We can now rely on MIDR, REVIDR and MPIDR storage in
isar.idregs[]. I will handle that in v10
Thanks
Eric
>
> Warm Regards,
> Khushit
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 13/26] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
2026-09-16 14:45 ` [PATCH v9 13/26] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger
@ 2026-09-24 6:26 ` Khushit Shah
2026-09-24 6:42 ` Eric Auger
2026-09-28 15:21 ` Eric Auger
0 siblings, 2 replies; 82+ messages in thread
From: Khushit Shah @ 2026-09-24 6:26 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> +
> +/*
> + * decode_idreg_writemap: Generate props for writable fields
> + *
> + * @obj: CPU object
> + * @reg: description of the sysreg
> + */
> +static int
> +decode_idreg_writemap(Object *obj, ARM64SysReg *reg)
> +{
> + uint64_t map = reg->writable_mask;
> + int i = ctz64(map);
> + int nb_sysreg_props = 0;
> +
> + while (map) {
> + ARM64SysRegField *field = get_field(i, reg);
> + int lower, upper;
> + char *prop_name;
> + uint64_t field_mask;
> +
> + if (!field) {
> + warn_report("%s bit %d of %s is writable but no named field "
> + "in target/arm/cpu-idregs.h.inc",
> + __func__, i, reg->name);
> + map = map & ~BIT_ULL(i);
> + i = ctz64(map);
> + continue;
> + }
> + lower = field->shift;
> + upper = field->shift + field->length - 1;
> + prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name);
> + trace_decode_idreg_writemap(field->name, lower, upper, prop_name);
> + object_property_add(obj, prop_name, "uint64",
> + get_sysreg_prop, set_sysreg_prop, NULL, field);
> + g_free(prop_name);
> + nb_sysreg_props++;
> +
> + field_mask = MAKE_64BIT_MASK(lower, field->length);
> + map = map & ~field_mask;
> + i = ctz64(map);
> + }
> + trace_nb_sysreg_props(reg->name, nb_sysreg_props);
> + return 0;
> +}
> +
We can try field based handling, it is more elegant.
- for each field, check if not RES and writable.
<Though I will argue that all fields should be present not just writable :)>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 13/26] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
2026-09-24 6:26 ` Khushit Shah
@ 2026-09-24 6:42 ` Eric Auger
2026-09-28 15:21 ` Eric Auger
1 sibling, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-24 6:42 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Khushit,
On 9/24/26 8:26 AM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> +
>> +/*
>> + * decode_idreg_writemap: Generate props for writable fields
>> + *
>> + * @obj: CPU object
>> + * @reg: description of the sysreg
>> + */
>> +static int
>> +decode_idreg_writemap(Object *obj, ARM64SysReg *reg)
>> +{
>> + uint64_t map = reg->writable_mask;
>> + int i = ctz64(map);
>> + int nb_sysreg_props = 0;
>> +
>> + while (map) {
>> + ARM64SysRegField *field = get_field(i, reg);
>> + int lower, upper;
>> + char *prop_name;
>> + uint64_t field_mask;
>> +
>> + if (!field) {
>> + warn_report("%s bit %d of %s is writable but no named field "
>> + "in target/arm/cpu-idregs.h.inc",
>> + __func__, i, reg->name);
>> + map = map & ~BIT_ULL(i);
>> + i = ctz64(map);
>> + continue;
>> + }
>> + lower = field->shift;
>> + upper = field->shift + field->length - 1;
>> + prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name);
>> + trace_decode_idreg_writemap(field->name, lower, upper, prop_name);
>> + object_property_add(obj, prop_name, "uint64",
>> + get_sysreg_prop, set_sysreg_prop, NULL, field);
>> + g_free(prop_name);
>> + nb_sysreg_props++;
>> +
>> + field_mask = MAKE_64BIT_MASK(lower, field->length);
>> + map = map & ~field_mask;
>> + i = ctz64(map);
>> + }
>> + trace_nb_sysreg_props(reg->name, nb_sysreg_props);
>> + return 0;
>> +}
>> +
> We can try field based handling, it is more elegant.
> - for each field, check if not RES and writable.
I guess you refer to what you did in
[RFC PATCH v4 02/25] target/arm: expose all non-res ID reg fields as
properties
ie. enumerate through all reg->fields[] array instead of parsing the
writable bitmask. Yes I agree your implementation is simpler.
We can still implement checks against writable masks if wanted.
>
> <Though I will argue that all fields should be present not just writable :)>
Let's discuss that separately. This function could be enhanced to
support both modes anyway.
Thanks
Eric
>
>
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 04/26] arm/cpu: Add infra to handle generated ID register definitions
2026-09-16 14:45 ` [PATCH v9 04/26] arm/cpu: Add infra to handle generated ID register definitions Eric Auger
@ 2026-09-24 10:01 ` Khushit Shah
0 siblings, 0 replies; 82+ messages in thread
From: Khushit Shah @ 2026-09-24 10:01 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Just few nits.
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Introduce an infrastructure to store the definition of all ID regs:
> This include their name, index and array of named fields.
…, and enum values if any.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> Co-authored-by: Khushit Shah <khushit.shah@nutanix.com>
> Signed-off-by: Khushit Shah <khushit.shah@nutanix.com>
>
> ---
> v7 -> v8:
> - remove typedef struct ArmIdRegArchVal
>
> v5 -> v6:
> - add ArmIdRegArchVal
> ---
> target/arm/cpu-idregs.h | 36 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
> create mode 100644 target/arm/cpu-idregs.h
>
> diff --git a/target/arm/cpu-idregs.h b/target/arm/cpu-idregs.h
> new file mode 100644
> index 0000000000..98c7a7518f
> --- /dev/null
> +++ b/target/arm/cpu-idregs.h
> @@ -0,0 +1,36 @@
> +/*
> + * handle ID registers and their fields
Maybe: ID registers and their field definitions? Or this is fine also.
Warm Regards,
Khushit
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +#ifndef TARGET_ARM_CPU_IDREGS_H
> +#define TARGET_ARM_CPU_IDREGS_H
> +
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "cpu.h"
> +#include "cpu-sysregs.h"
> +
> +typedef struct ARM64SysRegField {
> + const char *name; /* name of the field, for instance CTR_EL0_IDC */
> + ARMIDRegisterIdx index; /* parent register, e.g. CTR_EL0_IDX */
> + int shift; /* lsb of the field in the register */
> + int length; /* highest bit number */
> + uint64_t *arch_vals;
> + uint32_t arch_vals_count;
> +} ARM64SysRegField;
> +
> +typedef struct ARM64SysReg {
> + const char *name; /* name of the sysreg, for instance CTR_EL0 */
> + ARMIDRegisterIdx index; /* register index, e.g. CTR_EL0_IDX */
> + struct ARM64SysRegField *fields;
> + uint32_t fields_count;
> + uint64_t writable_mask;
> +} ARM64SysReg;
> +
> +/*
> + * List of exposed ID regs (automatically populated from AARCHMRS Registers.json)
> + */
> +extern ARM64SysReg arm64_id_regs[NUM_ID_IDX];
> +
> +#endif
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 05/26] scripts: Introduce scripts/aarch64_sysreg_helpers module
2026-09-16 14:45 ` [PATCH v9 05/26] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger
@ 2026-09-24 10:18 ` Khushit Shah
2026-09-24 10:23 ` Khushit Shah
2026-09-29 15:14 ` Eric Auger
0 siblings, 2 replies; 82+ messages in thread
From: Khushit Shah @ 2026-09-24 10:18 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Only few nits.
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> We plan to reuse get_opcode() and extract_idregs_from_registers_json()
> functions in another script. So let's move them into a module
Nit: fullstop.
>
> No functional change intended.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
> ---
> scripts/aarch64_sysreg_helpers.py | 121 +++++++++++++++++++
> scripts/update-aarch64-cpu-sysregs-header.py | 97 +--------------
> 2 files changed, 122 insertions(+), 96 deletions(-)
> create mode 100644 scripts/aarch64_sysreg_helpers.py
>
> diff --git a/scripts/aarch64_sysreg_helpers.py b/scripts/aarch64_sysreg_helpers.py
> new file mode 100644
> index 0000000000..24bbc5bb3d
> --- /dev/null
> +++ b/scripts/aarch64_sysreg_helpers.py
> @@ -0,0 +1,121 @@
> +#!/usr/bin/env python3
> +
> +# Helpers used in aarch64 sysreg definition generation
> +#
> +# Copyright (C) 2026 Red Hat, Inc.
> +#
> +# Authors: Eric Auger <eric.auger@redhat.com>
> +#
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +
> +
> +import json
> +import os
> +
> +def is_demux_register(r):
> + name = r.get('name', '')
> +
> + if name.startswith("CCSIDR"):
> + return True
> +
> + return False
> +
> +# Some regs have op code values like 000x, 001x. Anyway we don't need
> +# them. Besides some regs are undesired in the generated file such as
> +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
> +# are interested in and are tricky to decode as their system accessor
> +# refer to MPIDR_EL1/MIDR_EL1 respectively
> +
> +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
> + 'VMPIDR_EL2', 'VPIDR_EL2']
> +
> +# returns the int value of a given @opcode for a reg @encoding
> +def get_opcode(encoding, opcode):
> + fvalue = encoding.get(opcode)
> + if fvalue:
> + value = fvalue.get('value')
> + if isinstance(value, str):
> + value = value.strip("'")
> + value = int(value, 2)
> + return value
> + return -1
> +
> +def extract_idregs_from_registers_json(filename):
> + """
> + Load a Registers.json file and extract all ID registers, decode their
> + opcode and dump the information in target/arm/cpu-sysregs.h.inc
^^ does not apply now.
> +
> + Args:
> + filename (str): The path to the Registers.json
> + returns:
> + idregs: list of ID regs and their encoding
> + """
> + if not os.path.exists(filename):
> + print(f"Error: {filename} could not be found!")
> + return {}
> +
> + try:
> + with open(filename, 'r') as f:
> + register_data = json.load(f)
> +
> + except json.JSONDecodeError:
> + print(f"Could not decode json from '{filename}'!")
> + return {}
> + except Exception as e:
> + print(f"Unexpected error while reading {filename}: {e}")
> + return {}
> +
> + registers = [
> + r for r in register_data
> + if isinstance(r, dict)
> + and r.get('_type') == 'Register'
> + and not is_demux_register(r)
Can we put is_demux_register inside loop?
> + ]
> +
> + idregs = {}
> +
> + # Some regs have op code values like 000x, 001x. Anyway we don't need
> + # them. Besides some regs are undesired in the generated file such as
> + # VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
> + # are interested in and are tricky to decode as their system accessor
> + # refer to MPIDR_EL1/MIDR_EL1 respectively
> +
> + skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
> + 'VMPIDR_EL2', 'VPIDR_EL2’]
I see the op1 of VMPIDR_EL2/VPIDR_EL2 is 0b100, why are they needed in the skip-list, as they will anyway be skipped...
Warm Regards,
Khushit
> + for register in registers:
> + reg_name = register.get('name')
> +
> + is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
> +
> + if reg_name and not is_skipped:
> + accessors = register.get('accessors', [])
> +
> + for accessor in accessors:
> + type = accessor.get('_type')
> + if type in ['Accessors.SystemAccessor']:
> + encoding_list = accessor.get('encoding')
> +
> + if isinstance(encoding_list, list) and encoding_list and \
> + isinstance(encoding_list[0], dict):
> + encoding_wrapper = encoding_list[0]
> + encoding_source = encoding_wrapper.get('encodings', \
> + encoding_wrapper)
> +
> + if isinstance(encoding_source, dict):
> + op0 = get_opcode(encoding_source, 'op0')
> + op1 = get_opcode(encoding_source, 'op1')
> + op2 = get_opcode(encoding_source, 'op2')
> + crn = get_opcode(encoding_source, 'CRn')
> + crm = get_opcode(encoding_source, 'CRm')
> + encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
> +
> + # ID regs are assumed within this scope
> + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
> + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
> + idregs[reg_name] = encoding_str
> +
> + return idregs
> +
> +
> +
> diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
> index ef1471a197..43107264e9 100755
> --- a/scripts/update-aarch64-cpu-sysregs-header.py
> +++ b/scripts/update-aarch64-cpu-sysregs-header.py
> @@ -17,102 +17,7 @@
> import json
> import os
> import sys
> -
> -def is_demux_register(r):
> - name = r.get('name', '')
> -
> - if name.startswith("CCSIDR"):
> - return True
> -
> - return False
> -
> -# Some regs have op code values like 000x, 001x. Anyway we don't need
> -# them. Besides some regs are undesired in the generated file such as
> -# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
> -# are interested in and are tricky to decode as their system accessor
> -# refer to MPIDR_EL1/MIDR_EL1 respectively
> -
> -skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
> - 'VMPIDR_EL2', 'VPIDR_EL2']
> -
> -# returns the int value of a given @opcode for a reg @encoding
> -def get_opcode(encoding, opcode):
> - fvalue = encoding.get(opcode)
> - if fvalue:
> - value = fvalue.get('value')
> - if isinstance(value, str):
> - value = value.strip("'")
> - value = int(value, 2)
> - return value
> - return -1
> -
> -def extract_idregs_from_registers_json(filename):
> - """
> - Load a Registers.json file and extract all ID registers, decode their
> - opcode and dump the information in target/arm/cpu-sysregs.h.inc
> -
> - Args:
> - filename (str): The path to the Registers.json
> - returns:
> - idregs: list of ID regs and their encoding
> - """
> - if not os.path.exists(filename):
> - print(f"Error: {filename} could not be found!")
> - return {}
> -
> - try:
> - with open(filename, 'r') as f:
> - register_data = json.load(f)
> -
> - except json.JSONDecodeError:
> - print(f"Could not decode json from '{filename}'!")
> - return {}
> - except Exception as e:
> - print(f"Unexpected error while reading {filename}: {e}")
> - return {}
> -
> - registers = [
> - r for r in register_data
> - if isinstance(r, dict)
> - and r.get('_type') == 'Register'
> - and not is_demux_register(r)
> - ]
> -
> - idregs = {}
> -
> - for register in registers:
> - reg_name = register.get('name')
> -
> - is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
> -
> - if reg_name and not is_skipped:
> - accessors = register.get('accessors', [])
> -
> - for accessor in accessors:
> - type = accessor.get('_type')
> - if type in ['Accessors.SystemAccessor']:
> - encoding_list = accessor.get('encoding')
> -
> - if isinstance(encoding_list, list) and encoding_list and \
> - isinstance(encoding_list[0], dict):
> - encoding_wrapper = encoding_list[0]
> - encoding_source = encoding_wrapper.get('encodings', \
> - encoding_wrapper)
> -
> - if isinstance(encoding_source, dict):
> - op0 = get_opcode(encoding_source, 'op0')
> - op1 = get_opcode(encoding_source, 'op1')
> - op2 = get_opcode(encoding_source, 'op2')
> - crn = get_opcode(encoding_source, 'CRn')
> - crm = get_opcode(encoding_source, 'CRm')
> - encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
> -
> - # ID regs are assumed within this scope
> - if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
> - crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
> - idregs[reg_name] = encoding_str
> -
> - return idregs
> +from aarch64_sysreg_helpers import extract_idregs_from_registers_json
>
> if __name__ == "__main__":
> # Single arg expected: the path to the Registers.json file
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 05/26] scripts: Introduce scripts/aarch64_sysreg_helpers module
2026-09-24 10:18 ` Khushit Shah
@ 2026-09-24 10:23 ` Khushit Shah
2026-09-29 15:14 ` Eric Auger
1 sibling, 0 replies; 82+ messages in thread
From: Khushit Shah @ 2026-09-24 10:23 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 24 Sep 2026, at 3:48 PM, Khushit Shah <khushit.shah@nutanix.com> wrote:
>
>
> Only few nits.
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> We plan to reuse get_opcode() and extract_idregs_from_registers_json()
>> functions in another script. So let's move them into a module
> Nit: fullstop.
>
>>
>> No functional change intended.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
>> ---
>> scripts/aarch64_sysreg_helpers.py | 121 +++++++++++++++++++
>> scripts/update-aarch64-cpu-sysregs-header.py | 97 +--------------
>> 2 files changed, 122 insertions(+), 96 deletions(-)
>> create mode 100644 scripts/aarch64_sysreg_helpers.py
>>
>> diff --git a/scripts/aarch64_sysreg_helpers.py b/scripts/aarch64_sysreg_helpers.py
>> new file mode 100644
>> index 0000000000..24bbc5bb3d
>> --- /dev/null
>> +++ b/scripts/aarch64_sysreg_helpers.py
>> @@ -0,0 +1,121 @@
>> +#!/usr/bin/env python3
>> +
>> +# Helpers used in aarch64 sysreg definition generation
>> +#
>> +# Copyright (C) 2026 Red Hat, Inc.
>> +#
>> +# Authors: Eric Auger <eric.auger@redhat.com>
>> +#
>> +# SPDX-License-Identifier: GPL-2.0-or-later
>> +
>> +
>> +import json
>> +import os
>> +
>> +def is_demux_register(r):
>> + name = r.get('name', '')
>> +
>> + if name.startswith("CCSIDR"):
>> + return True
>> +
>> + return False
>> +
>> +# Some regs have op code values like 000x, 001x. Anyway we don't need
>> +# them. Besides some regs are undesired in the generated file such as
>> +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
>> +# are interested in and are tricky to decode as their system accessor
>> +# refer to MPIDR_EL1/MIDR_EL1 respectively
>> +
>> +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
>> + 'VMPIDR_EL2', 'VPIDR_EL2']
>> +
>> +# returns the int value of a given @opcode for a reg @encoding
>> +def get_opcode(encoding, opcode):
>> + fvalue = encoding.get(opcode)
>> + if fvalue:
>> + value = fvalue.get('value')
>> + if isinstance(value, str):
>> + value = value.strip("'")
>> + value = int(value, 2)
>> + return value
>> + return -1
>> +
>> +def extract_idregs_from_registers_json(filename):
>> + """
>> + Load a Registers.json file and extract all ID registers, decode their
>> + opcode and dump the information in target/arm/cpu-sysregs.h.inc
> ^^ does not apply now.
>> +
>> + Args:
>> + filename (str): The path to the Registers.json
>> + returns:
>> + idregs: list of ID regs and their encoding
>> + """
>> + if not os.path.exists(filename):
>> + print(f"Error: {filename} could not be found!")
>> + return {}
>> +
>> + try:
>> + with open(filename, 'r') as f:
>> + register_data = json.load(f)
>> +
>> + except json.JSONDecodeError:
>> + print(f"Could not decode json from '{filename}'!")
>> + return {}
>> + except Exception as e:
>> + print(f"Unexpected error while reading {filename}: {e}")
>> + return {}
>> +
>> + registers = [
>> + r for r in register_data
>> + if isinstance(r, dict)
>> + and r.get('_type') == 'Register'
>> + and not is_demux_register(r)
> Can we put is_demux_register inside loop?
>
>> + ]
>> +
>> + idregs = {}
>> +
>> + # Some regs have op code values like 000x, 001x. Anyway we don't need
>> + # them. Besides some regs are undesired in the generated file such as
>> + # VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
>> + # are interested in and are tricky to decode as their system accessor
>> + # refer to MPIDR_EL1/MIDR_EL1 respectively
>> +
>> + skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
>> + 'VMPIDR_EL2', 'VPIDR_EL2’]
> I see the op1 of VMPIDR_EL2/VPIDR_EL2 is 0b100, why are they needed in the skip-list, as they will anyway be skipped…
>
I notice I should comment this on [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py.
> Warm Regards,
> Khushit
>> + for register in registers:
>> + reg_name = register.get('name')
>> +
>> + is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
>> +
>> + if reg_name and not is_skipped:
>> + accessors = register.get('accessors', [])
>> +
>> + for accessor in accessors:
>> + type = accessor.get('_type')
>> + if type in ['Accessors.SystemAccessor']:
>> + encoding_list = accessor.get('encoding')
>> +
>> + if isinstance(encoding_list, list) and encoding_list and \
>> + isinstance(encoding_list[0], dict):
>> + encoding_wrapper = encoding_list[0]
>> + encoding_source = encoding_wrapper.get('encodings', \
>> + encoding_wrapper)
>> +
>> + if isinstance(encoding_source, dict):
>> + op0 = get_opcode(encoding_source, 'op0')
>> + op1 = get_opcode(encoding_source, 'op1')
>> + op2 = get_opcode(encoding_source, 'op2')
>> + crn = get_opcode(encoding_source, 'CRn')
>> + crm = get_opcode(encoding_source, 'CRm')
>> + encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
>> +
>> + # ID regs are assumed within this scope
>> + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
>> + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
>> + idregs[reg_name] = encoding_str
>> +
>> + return idregs
>> +
>> +
>> +
>> diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
>> index ef1471a197..43107264e9 100755
>> --- a/scripts/update-aarch64-cpu-sysregs-header.py
>> +++ b/scripts/update-aarch64-cpu-sysregs-header.py
>> @@ -17,102 +17,7 @@
>> import json
>> import os
>> import sys
>> -
>> -def is_demux_register(r):
>> - name = r.get('name', '')
>> -
>> - if name.startswith("CCSIDR"):
>> - return True
>> -
>> - return False
>> -
>> -# Some regs have op code values like 000x, 001x. Anyway we don't need
>> -# them. Besides some regs are undesired in the generated file such as
>> -# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
>> -# are interested in and are tricky to decode as their system accessor
>> -# refer to MPIDR_EL1/MIDR_EL1 respectively
>> -
>> -skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
>> - 'VMPIDR_EL2', 'VPIDR_EL2']
>> -
>> -# returns the int value of a given @opcode for a reg @encoding
>> -def get_opcode(encoding, opcode):
>> - fvalue = encoding.get(opcode)
>> - if fvalue:
>> - value = fvalue.get('value')
>> - if isinstance(value, str):
>> - value = value.strip("'")
>> - value = int(value, 2)
>> - return value
>> - return -1
>> -
>> -def extract_idregs_from_registers_json(filename):
>> - """
>> - Load a Registers.json file and extract all ID registers, decode their
>> - opcode and dump the information in target/arm/cpu-sysregs.h.inc
>> -
>> - Args:
>> - filename (str): The path to the Registers.json
>> - returns:
>> - idregs: list of ID regs and their encoding
>> - """
>> - if not os.path.exists(filename):
>> - print(f"Error: {filename} could not be found!")
>> - return {}
>> -
>> - try:
>> - with open(filename, 'r') as f:
>> - register_data = json.load(f)
>> -
>> - except json.JSONDecodeError:
>> - print(f"Could not decode json from '{filename}'!")
>> - return {}
>> - except Exception as e:
>> - print(f"Unexpected error while reading {filename}: {e}")
>> - return {}
>> -
>> - registers = [
>> - r for r in register_data
>> - if isinstance(r, dict)
>> - and r.get('_type') == 'Register'
>> - and not is_demux_register(r)
>> - ]
>> -
>> - idregs = {}
>> -
>> - for register in registers:
>> - reg_name = register.get('name')
>> -
>> - is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
>> -
>> - if reg_name and not is_skipped:
>> - accessors = register.get('accessors', [])
>> -
>> - for accessor in accessors:
>> - type = accessor.get('_type')
>> - if type in ['Accessors.SystemAccessor']:
>> - encoding_list = accessor.get('encoding')
>> -
>> - if isinstance(encoding_list, list) and encoding_list and \
>> - isinstance(encoding_list[0], dict):
>> - encoding_wrapper = encoding_list[0]
>> - encoding_source = encoding_wrapper.get('encodings', \
>> - encoding_wrapper)
>> -
>> - if isinstance(encoding_source, dict):
>> - op0 = get_opcode(encoding_source, 'op0')
>> - op1 = get_opcode(encoding_source, 'op1')
>> - op2 = get_opcode(encoding_source, 'op2')
>> - crn = get_opcode(encoding_source, 'CRn')
>> - crm = get_opcode(encoding_source, 'CRm')
>> - encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
>> -
>> - # ID regs are assumed within this scope
>> - if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
>> - crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
>> - idregs[reg_name] = encoding_str
>> -
>> - return idregs
>> +from aarch64_sysreg_helpers import extract_idregs_from_registers_json
>>
>> if __name__ == "__main__":
>> # Single arg expected: the path to the Registers.json file
>> --
>> 2.53.0
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py
2026-09-16 14:45 ` [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
2026-09-23 7:08 ` Khushit Shah
@ 2026-09-24 10:24 ` Khushit Shah
2026-09-29 12:31 ` Eric Auger
1 sibling, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-24 10:24 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Introduce a script that takes as input the Registers.json file
> delivered in the AARCHMRS Features Model downloadable from the
> Arm Developer A-Profile Architecture Exploration Tools page:
> https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
> and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
> under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>).
>
> We only care about IDregs with opcodes satisfying:
> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> [CH: note correct op1 range, don't skip CCSIDR]
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> Message-ID: <20251208163751.611186-2-eric.auger@redhat.com>
> ---
> scripts/update-aarch64-cpu-sysregs-header.py | 146 +++++++++++++++++++
> 1 file changed, 146 insertions(+)
> create mode 100755 scripts/update-aarch64-cpu-sysregs-header.py
>
> diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
> new file mode 100755
> index 0000000000..ef1471a197
> --- /dev/null
> +++ b/scripts/update-aarch64-cpu-sysregs-header.py
> @@ -0,0 +1,146 @@
> +#!/usr/bin/env python3
> +
> +# This script takes as input the Registers.json file delivered in
> +# the AARCHMRS Features Model downloadable from the Arm Developer
> +# A-Profile Architecture Exploration Tools page:
> +# https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
> +# and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
> +# under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
> +#
> +# Copyright (C) 2026 Red Hat, Inc.
> +#
> +# Authors: Eric Auger <eric.auger@redhat.com>
> +#
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +
> +
> +import json
> +import os
> +import sys
> +
> +def is_demux_register(r):
> + name = r.get('name', '')
> +
> + if name.startswith("CCSIDR"):
> + return True
> +
> + return False
> +
> +# Some regs have op code values like 000x, 001x. Anyway we don't need
> +# them. Besides some regs are undesired in the generated file such as
> +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
> +# are interested in and are tricky to decode as their system accessor
> +# refer to MPIDR_EL1/MIDR_EL1 respectively
> +
> +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
> + 'VMPIDR_EL2', 'VPIDR_EL2’]
I see VMPIDR_EL2/VPIDR_EL2 have op1=0100, they will automatically get skipped, why is this needed?
Warm Regards,
Khushit
> +# returns the int value of a given @opcode for a reg @encoding
> +def get_opcode(encoding, opcode):
> + fvalue = encoding.get(opcode)
> + if fvalue:
> + value = fvalue.get('value')
> + if isinstance(value, str):
> + value = value.strip("'")
> + value = int(value, 2)
> + return value
> + return -1
> +
> +def extract_idregs_from_registers_json(filename):
> + """
> + Load a Registers.json file and extract all ID registers, decode their
> + opcode and dump the information in target/arm/cpu-sysregs.h.inc
> +
> + Args:
> + filename (str): The path to the Registers.json
> + returns:
> + idregs: list of ID regs and their encoding
> + """
> + if not os.path.exists(filename):
> + print(f"Error: {filename} could not be found!")
> + return {}
> +
> + try:
> + with open(filename, 'r') as f:
> + register_data = json.load(f)
> +
> + except json.JSONDecodeError:
> + print(f"Could not decode json from '{filename}'!")
> + return {}
> + except Exception as e:
> + print(f"Unexpected error while reading {filename}: {e}")
> + return {}
> +
> + registers = [
> + r for r in register_data
> + if isinstance(r, dict)
> + and r.get('_type') == 'Register'
> + and not is_demux_register(r)
> + ]
> +
> + idregs = {}
> +
> + for register in registers:
> + reg_name = register.get('name')
> +
> + is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
> +
> + if reg_name and not is_skipped:
> + accessors = register.get('accessors', [])
> +
> + for accessor in accessors:
> + type = accessor.get('_type')
> + if type in ['Accessors.SystemAccessor']:
> + encoding_list = accessor.get('encoding')
> +
> + if isinstance(encoding_list, list) and encoding_list and \
> + isinstance(encoding_list[0], dict):
> + encoding_wrapper = encoding_list[0]
> + encoding_source = encoding_wrapper.get('encodings', \
> + encoding_wrapper)
> +
> + if isinstance(encoding_source, dict):
> + op0 = get_opcode(encoding_source, 'op0')
> + op1 = get_opcode(encoding_source, 'op1')
> + op2 = get_opcode(encoding_source, 'op2')
> + crn = get_opcode(encoding_source, 'CRn')
> + crm = get_opcode(encoding_source, 'CRm')
> + encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
> +
> + # ID regs are assumed within this scope
> + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
> + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
> + idregs[reg_name] = encoding_str
> +
> + return idregs
> +
> +if __name__ == "__main__":
> + # Single arg expected: the path to the Registers.json file
> + if len(sys.argv) < 2:
> + print("Usage: python scripts/update-aarch64-cpu-sysregs-header.py "
> + "<path_to_registers_json>")
> + sys.exit(1)
> + else:
> + json_file_path = sys.argv[1]
> +
> + extracted_registers = extract_idregs_from_registers_json(json_file_path)
> +
> + if extracted_registers:
> + output_list = extracted_registers.items()
> +
> + # Sort by register name
> + sorted_output = sorted(output_list, key=lambda item: item[0])
> +
> + # format lines as DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
> + final_output = ""
> + for reg_name, encoding in sorted_output:
> + reformatted_encoding = encoding.replace(" ", ", ")
> + final_output += f"DEF({reg_name}, {reformatted_encoding})\n"
> +
> + with open("target/arm/cpu-sysregs.h.inc", 'w') as f:
> + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
> + f.write("/* This file is autogenerated by ")
> + f.write("scripts/update-aarch64-cpu-sysregs-header.py */\n")
> + f.write("/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */\n\n")
> + f.write(final_output)
> + print("updated target/arm/cpu-sysregs.h.inc")
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 06/26] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py
2026-09-16 14:45 ` [PATCH v9 06/26] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger
@ 2026-09-25 9:29 ` Khushit Shah
2026-10-02 12:59 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-25 9:29 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Introduce a script that takes as input the Registers.json file
> delivered in the AARCHMRS Features Model downloadable from the
> Arm Developer A-Profile Architecture Exploration Tools page:
> https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=2NOLVUk59YPHssYi5AgGX0z_LkZPQXfTkiD33Ti_D8RYfowBwp7XuMOfw-dMDkDE&s=Qs3ro5t6_dDfdQDLUGX7pJ43SvM2axfOShUzqbv90EQ&e=
> and automates the generation of system register properties definitions.
>
> generates target/arm/cpu-idregs.h.inc containing definitions for
> feature ID registers.
>
> We only care about IDregs with opcodes satisfying:
> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>
> ---
>
> v5 -> v6
> - add ident
> ---
> .../update-aarch64-cpu-sysreg-properties.py | 166 ++++++++++++++++++
> 1 file changed, 166 insertions(+)
> create mode 100644 scripts/update-aarch64-cpu-sysreg-properties.py
>
> diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py
> new file mode 100644
> index 0000000000..6f5edb88d2
> --- /dev/null
> +++ b/scripts/update-aarch64-cpu-sysreg-properties.py
> @@ -0,0 +1,166 @@
> +#!/usr/bin/env python3
> +
> +# This script takes as input the Registers.json file delivered in
> +# the AARCHMRS Features Model downloadable from the Arm Developer
> +# A-Profile Architecture Exploration Tools page:
> +# https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=2NOLVUk59YPHssYi5AgGX0z_LkZPQXfTkiD33Ti_D8RYfowBwp7XuMOfw-dMDkDE&s=Qs3ro5t6_dDfdQDLUGX7pJ43SvM2axfOShUzqbv90EQ&e=
> +# and outputs target/arm/cpu-idregs.h.inc content.
> +# ID regs are defined using this pattern:
> +#
> +# IDREG_START(REG)
> +# IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
Nit: Add Enum Macro
> +# ...
> +# IDREG_END(REG)
> +#
> +# Copyright (C) 2026 Red Hat, Inc.
> +#
> +# Authors: Eric Auger <eric.auger@redhat.com>
> +#
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +
> +
> +import json
> +import os
> +import sys
> +from aarch64_sysreg_helpers import extract_idregs_from_registers_json
> +
> +def collect_fields(item, bit_offset=0):
> + """
> + Recursively finds all field-like objects, handling Fields.Array,
> + Fields.ArrayField, and ConditionalField structures.
> + Applies bit_offset from containers to child fields.
> + """
> + fields = []
> + if not isinstance(item, dict):
> + return fields
> +
> + _type = item.get('_type', '')
> +
> + # Array types (for example CLIDR_EL1 Ctype<n>, Ttype<n>)
> + if _type == 'Fields.Array':
> + name_template = item.get('name') or item.get('label', '')
> + index_info = item.get('indexes', [{}])[0]
> + start_idx = index_info.get('start', 0)
> + count = index_info.get('width', 0)
> +
> + full_range = item.get('rangeset', [{}])[0]
> + bit_start = full_range.get('start', 0) + bit_offset
> + elem_width = full_range.get('width', 0) // count if count else 0
> +
> + for i in range(count):
> + idx = start_idx + i
> + # Correctly handle indexed names like Ctype1, Ctype2
> + field_name = name_template.replace('<n>', str(idx))
> + fields.append({
> + 'name': field_name,
> + 'rangeset': [{
> + 'start': bit_start + (i * elem_width),
> + 'width': elem_width
> + }],
> + '_type': 'Fields.Field'
> + })
> + return fields
> +
> + # ConditionalFields
Can you please explain what are conditional fields and should we always include them?
> + elif _type == 'Fields.ConditionalField':
> + inner_offset = bit_offset
> + if item.get('rangeset'):
> + # Parent container defines the absolute start bit
> + inner_offset = item['rangeset'][0].get('start', bit_offset)
> +
> + for entry in item.get('fields', []):
> + inner = entry.get('field')
> + if inner:
> + fields.extend(collect_fields(inner, inner_offset))
> + return fields
> +
> + # Normal Field Types
> + leaf_types = ['Fields.Field', 'Fields.ConstantField',
> + 'Fields.EnumeratedField', 'Fields.Bitfield']
> + if _type in leaf_types:
> + field_copy = item.copy()
> + if field_copy.get('rangeset'):
> + new_ranges = []
> + for r in field_copy['rangeset']:
> + nr = r.copy()
> + # Apply the cumulative offset to the field's start bit
> + nr['start'] = r.get('start', 0) + bit_offset
> + new_ranges.append(nr)
> + field_copy['rangeset'] = new_ranges
> + fields.append(field_copy)
> + return fields
> +
> + # Traverse the hierarchy for other cases
> + for key in ['fields', 'values', 'fieldsets']:
> + for nested in item.get(key, []):
> + fields.extend(collect_fields(nested, bit_offset))
> +
> + return fields
> +
> +
> +def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
> + with open(raw_json_path, 'r') as f:
> + register_data = json.load(f)
> +
> + regs = {r.get('name'): r for r in register_data if r.get('_type') == 'Register'}
> +
> + final_output = ""
> +
> + for reg_name in id_reg_names:
> + register = regs.get(reg_name)
> + if not register:
we should error out here.
> + continue
> +
> + final_output += f"IDREG_START({reg_name})\n"
> +
> + unique_fields = {}
> + for fieldset in register.get('fieldsets', []):
> + candidates = collect_fields(fieldset)
> + for val in candidates:
> + name = (val.get('name') or val.get('label', '')).strip()
> + if not name or "RESERVED" in name.upper():
> + continue
> + for r in val.get('rangeset', []):
> + lsb = int(r.get('start'))
> + width = r.get('width')
> + msb = lsb + int(width) - 1
> +
> + # Only keep the fields with the highest MSB
> + # needed fir CCSIDR_EL1
does not apply now, we ignore CCSIDR_EL1
> + if name not in unique_fields or msb > unique_fields[name]['msb']:
> + unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width}
> +
> + # Sort decreasing lsbs
> + sorted_fields = sorted(unique_fields.items(),
> + key=lambda x: x[1]['lsb'], reverse=True)
> +
> + for name, bits in sorted_fields:
> + line = (f" IDREG_FIELD({reg_name}, "
> + f"{name}, {bits['lsb']}, {bits['width']})\n")
> + final_output += line
> + final_output += f"IDREG_END({reg_name})\n"
> + final_output += "\n"
> +
> + os.makedirs("target/arm", exist_ok=True)
> + with open("target/arm/cpu-idregs.h.inc", 'w') as f:
> + f.write("/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n\n")
> + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
> + f.write("/* IDREG_START(REG) */\n")
> + f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n”)
Same enum macro …
Warm Regards,
Khushit
> + f.write("/* ... */\n")
> + f.write("/* IDREG_END(REG) */\n\n")
> + f.write(final_output)
> +
> +if __name__ == "__main__":
> + if len(sys.argv) < 2:
> + print("Usage: python scripts/update-aarch64-cpu-sysreg-properties.py "
> + "<path_to_registers_json>")
> + else:
> + json_path = sys.argv[1]
> +
> + id_regs_dict = extract_idregs_from_registers_json(json_path)
> + sorted_names = sorted(id_regs_dict.keys())
> +
> + if sorted_names:
> + generate_sysreg_properties_from_registers_json(sorted_names, json_path)
> + print("Generated target/arm/cpu-idregs.h.inc")
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 07/26] target/arm/cpu-idregs.h.inc: generate with script
2026-09-16 14:45 ` [PATCH v9 07/26] target/arm/cpu-idregs.h.inc: generate with script Eric Auger
@ 2026-09-25 11:19 ` Khushit Shah
2026-09-29 16:55 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-25 11:19 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Generate ID reg definitions with the scripts/update-aarch64-cpu-sysreg-properties.py
> based on AARCHMRS_OPENSOURCE_A_profile_FAT-2026-03 Registers.json
>
> Each register and fields are described with this pattern:
>
> IDREG_START(REG)
> IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
> ...
> IDREG_END(REG)
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Suggested-by: Khushit Shah <khushit.shah@nutanix.com>
> Suggested-by: Shaju Abraham <shaju.abraham@nutanix.com>
> ---
> target/arm/cpu-idregs.h.inc | 607 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 607 insertions(+)
> create mode 100644 target/arm/cpu-idregs.h.inc
>
> diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
> new file mode 100644
> index 0000000000..c9745e2fb6
> --- /dev/null
> +++ b/target/arm/cpu-idregs.h.inc
> @@ -0,0 +1,607 @@
> +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
> +
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +/* IDREG_START(REG) */
> +/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */
> +/* ... */
> +/* IDREG_END(REG) */
> +
> +IDREG_START(AIDR_EL1)
> +IDREG_END(AIDR_EL1)
> +
> +IDREG_START(CLIDR_EL1)
> + IDREG_FIELD(CLIDR_EL1, Ttype7, 45, 2)
> + IDREG_FIELD(CLIDR_EL1, Ttype6, 43, 2)
> + IDREG_FIELD(CLIDR_EL1, Ttype5, 41, 2)
> + IDREG_FIELD(CLIDR_EL1, Ttype4, 39, 2)
> + IDREG_FIELD(CLIDR_EL1, Ttype3, 37, 2)
> + IDREG_FIELD(CLIDR_EL1, Ttype2, 35, 2)
> + IDREG_FIELD(CLIDR_EL1, Ttype1, 33, 2)
> + IDREG_FIELD(CLIDR_EL1, ICB, 30, 3)
> + IDREG_FIELD(CLIDR_EL1, LoUU, 27, 3)
> + IDREG_FIELD(CLIDR_EL1, LoC, 24, 3)
> + IDREG_FIELD(CLIDR_EL1, LoUIS, 21, 3)
> + IDREG_FIELD(CLIDR_EL1, Ctype7, 18, 3)
> + IDREG_FIELD(CLIDR_EL1, Ctype6, 15, 3)
> + IDREG_FIELD(CLIDR_EL1, Ctype5, 12, 3)
> + IDREG_FIELD(CLIDR_EL1, Ctype4, 9, 3)
> + IDREG_FIELD(CLIDR_EL1, Ctype3, 6, 3)
> + IDREG_FIELD(CLIDR_EL1, Ctype2, 3, 3)
> + IDREG_FIELD(CLIDR_EL1, Ctype1, 0, 3)
> +IDREG_END(CLIDR_EL1)
> +
> +IDREG_START(CTR_EL0)
> + IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
> + IDREG_FIELD(CTR_EL0, DIC, 29, 1)
> + IDREG_FIELD(CTR_EL0, IDC, 28, 1)
> + IDREG_FIELD(CTR_EL0, CWG, 24, 4)
> + IDREG_FIELD(CTR_EL0, ERG, 20, 4)
> + IDREG_FIELD(CTR_EL0, DminLine, 16, 4)
> + IDREG_FIELD(CTR_EL0, L1Ip, 14, 2)
> + IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
> +IDREG_END(CTR_EL0)
> +
> +IDREG_START(DCZID_EL0)
> + IDREG_FIELD(DCZID_EL0, TBS, 5, 4)
> + IDREG_FIELD(DCZID_EL0, DZP, 4, 1)
> + IDREG_FIELD(DCZID_EL0, BS, 0, 4)
> +IDREG_END(DCZID_EL0)
> +
> +IDREG_START(GMID_EL1)
> + IDREG_FIELD(GMID_EL1, BS, 0, 4)
> +IDREG_END(GMID_EL1)
> +
> +IDREG_START(ID_AA64AFR0_EL1)
> +IDREG_END(ID_AA64AFR0_EL1)
> +
> +IDREG_START(ID_AA64AFR1_EL1)
> +IDREG_END(ID_AA64AFR1_EL1)
> +
> +IDREG_START(ID_AA64DFR0_EL1)
> + IDREG_FIELD(ID_AA64DFR0_EL1, HPMN0, 60, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, BRBE, 52, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, MTPMU, 48, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, PMSVer, 32, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, WRPs, 20, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, PMSS, 16, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, BRPs, 12, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, PMUVer, 8, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceVer, 4, 4)
> + IDREG_FIELD(ID_AA64DFR0_EL1, DebugVer, 0, 4)
> +IDREG_END(ID_AA64DFR0_EL1)
> +
> +IDREG_START(ID_AA64DFR1_EL1)
> + IDREG_FIELD(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
> + IDREG_FIELD(ID_AA64DFR1_EL1, DPFZS, 52, 4)
> + IDREG_FIELD(ID_AA64DFR1_EL1, EBEP, 48, 4)
> + IDREG_FIELD(ID_AA64DFR1_EL1, ITE, 44, 4)
> + IDREG_FIELD(ID_AA64DFR1_EL1, ABLE, 40, 4)
> + IDREG_FIELD(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
> + IDREG_FIELD(ID_AA64DFR1_EL1, SPMU, 32, 4)
> + IDREG_FIELD(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
> + IDREG_FIELD(ID_AA64DFR1_EL1, WRPs, 16, 8)
> + IDREG_FIELD(ID_AA64DFR1_EL1, BRPs, 8, 8)
> + IDREG_FIELD(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
> +IDREG_END(ID_AA64DFR1_EL1)
> +
> +IDREG_START(ID_AA64DFR2_EL1)
> + IDREG_FIELD(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
> + IDREG_FIELD(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
> + IDREG_FIELD(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
> + IDREG_FIELD(ID_AA64DFR2_EL1, BWE, 4, 4)
> + IDREG_FIELD(ID_AA64DFR2_EL1, STEP, 0, 4)
> +IDREG_END(ID_AA64DFR2_EL1)
> +
> +IDREG_START(ID_AA64FPFR0_EL1)
> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
> + IDREG_FIELD(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
> +IDREG_END(ID_AA64FPFR0_EL1)
> +
> +IDREG_START(ID_AA64ISAR0_EL1)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, RNDR, 60, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, TLB, 56, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, TS, 52, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, FHM, 48, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, DP, 44, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, SM4, 40, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, SM3, 36, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA3, 32, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, RDM, 28, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, Atomic, 20, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, CRC32, 16, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA2, 12, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA1, 8, 4)
> + IDREG_FIELD(ID_AA64ISAR0_EL1, AES, 4, 4)
> +IDREG_END(ID_AA64ISAR0_EL1)
> +
> +IDREG_START(ID_AA64ISAR1_EL1)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, LS64, 60, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, XS, 56, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, I8MM, 52, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, DGH, 48, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, BF16, 44, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, SB, 36, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, GPI, 28, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, GPA, 24, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, FCMA, 16, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, API, 8, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, APA, 4, 4)
> + IDREG_FIELD(ID_AA64ISAR1_EL1, DPB, 0, 4)
> +IDREG_END(ID_AA64ISAR1_EL1)
> +
> +IDREG_START(ID_AA64ISAR2_EL1)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, LUT, 56, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, CSSC, 52, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, BC, 20, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, MOPS, 16, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, APA3, 12, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, GPA3, 8, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, RPRES, 4, 4)
> + IDREG_FIELD(ID_AA64ISAR2_EL1, WFxT, 0, 4)
> +IDREG_END(ID_AA64ISAR2_EL1)
> +
> +IDREG_START(ID_AA64ISAR3_EL1)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSCP, 44, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, MTETC, 36, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSUI, 24, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSFE, 16, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, PACM, 12, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
> + IDREG_FIELD(ID_AA64ISAR3_EL1, CPA, 0, 4)
> +IDREG_END(ID_AA64ISAR3_EL1)
> +
> +IDREG_START(ID_AA64MMFR0_EL1)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, ECV, 60, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, FGT, 56, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, ExS, 44, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4, 28, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64, 24, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16, 20, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
> + IDREG_FIELD(ID_AA64MMFR0_EL1, PARange, 0, 4)
> +IDREG_END(ID_AA64MMFR0_EL1)
> +
> +IDREG_START(ID_AA64MMFR1_EL1)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, CMOW, 56, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, AFP, 44, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, HCX, 40, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, ETS, 36, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, TWED, 32, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, XNX, 28, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, PAN, 20, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, LO, 16, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, HPDS, 12, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, VH, 8, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
> + IDREG_FIELD(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
> +IDREG_END(ID_AA64MMFR1_EL1)
> +
> +IDREG_START(ID_AA64MMFR2_EL1)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, E0PD, 60, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, EVT, 56, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, BBM, 52, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, TTL, 48, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, FWB, 40, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, IDS, 36, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, AT, 32, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, ST, 28, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, NV, 24, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, VARange, 16, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, IESB, 12, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, LSM, 8, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, UAO, 4, 4)
> + IDREG_FIELD(ID_AA64MMFR2_EL1, CnP, 0, 4)
> +IDREG_END(ID_AA64MMFR2_EL1)
> +
> +IDREG_START(ID_AA64MMFR3_EL1)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, ADERR, 56, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, SDERR, 52, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, ANERR, 44, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, SNERR, 40, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, D128_2, 36, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, D128, 32, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, MEC, 28, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, AIE, 24, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, S2POE, 20, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, S1POE, 16, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
> + IDREG_FIELD(ID_AA64MMFR3_EL1, TCRX, 0, 4)
> +IDREG_END(ID_AA64MMFR3_EL1)
> +
> +IDREG_START(ID_AA64MMFR4_EL1)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, SCRX, 56, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, TEV, 52, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, TPS, 48, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, TLBID, 40, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, EAESR, 32, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, E2H0, 24, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, ASID2, 8, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, EIESB, 4, 4)
> + IDREG_FIELD(ID_AA64MMFR4_EL1, PoPS, 0, 4)
> +IDREG_END(ID_AA64MMFR4_EL1)
> +
> +IDREG_START(ID_AA64PFR0_EL1)
> + IDREG_FIELD(ID_AA64PFR0_EL1, CSV3, 60, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, CSV2, 56, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, RME, 52, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, DIT, 48, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, AMU, 44, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, MPAM, 40, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, SEL2, 36, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, SVE, 32, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, RAS, 28, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, GIC, 24, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, FP, 16, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, EL3, 12, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, EL2, 8, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, EL1, 4, 4)
> + IDREG_FIELD(ID_AA64PFR0_EL1, EL0, 0, 4)
> +IDREG_END(ID_AA64PFR0_EL1)
> +
> +IDREG_START(ID_AA64PFR1_EL1)
> + IDREG_FIELD(ID_AA64PFR1_EL1, PFAR, 60, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, DF2, 56, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, MTEX, 52, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, THE, 48, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, GCS, 44, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, NMI, 36, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, SME, 24, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, MTE, 8, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, SSBS, 4, 4)
> + IDREG_FIELD(ID_AA64PFR1_EL1, BT, 0, 4)
> +IDREG_END(ID_AA64PFR1_EL1)
> +
> +IDREG_START(ID_AA64PFR2_EL1)
> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTETC, 40, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTE, 36, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, FPMR, 32, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, MPAM2, 28, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, FGDT, 24, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, UINJ, 16, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, GCIE, 12, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
> +IDREG_END(ID_AA64PFR2_EL1)
> +
> +IDREG_START(ID_AA64SMFR0_EL1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, FA64, 63, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, LUT6, 61, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, SMEver, 56, 4)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, I16I64, 52, 4)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, F64F64, 48, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, I16I32, 44, 4)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, B16B16, 43, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, F16F16, 42, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, F8F16, 41, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, F8F32, 40, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, I8I32, 36, 4)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, F16F32, 35, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, B16F32, 34, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, F32F32, 32, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, AES, 24, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, STMOP, 16, 1)
> + IDREG_FIELD(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
> +IDREG_END(ID_AA64SMFR0_EL1)
> +
> +IDREG_START(ID_AA64ZFR0_EL1)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, F64MM, 56, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, F32MM, 52, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, F16MM, 48, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, I8MM, 44, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, SM4, 40, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, SHA3, 32, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, B16B16, 24, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, BF16, 20, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, AES, 4, 4)
> + IDREG_FIELD(ID_AA64ZFR0_EL1, SVEver, 0, 4)
> +IDREG_END(ID_AA64ZFR0_EL1)
> +
> +IDREG_START(ID_AFR0_EL1)
> +IDREG_END(ID_AFR0_EL1)
> +
> +IDREG_START(ID_DFR0_EL1)
> + IDREG_FIELD(ID_DFR0_EL1, TraceFilt, 28, 4)
> + IDREG_FIELD(ID_DFR0_EL1, PerfMon, 24, 4)
> + IDREG_FIELD(ID_DFR0_EL1, MProfDbg, 20, 4)
> + IDREG_FIELD(ID_DFR0_EL1, MMapTrc, 16, 4)
> + IDREG_FIELD(ID_DFR0_EL1, CopTrc, 12, 4)
> + IDREG_FIELD(ID_DFR0_EL1, MMapDbg, 8, 4)
> + IDREG_FIELD(ID_DFR0_EL1, CopSDbg, 4, 4)
> + IDREG_FIELD(ID_DFR0_EL1, CopDbg, 0, 4)
> +IDREG_END(ID_DFR0_EL1)
> +
> +IDREG_START(ID_DFR1_EL1)
> + IDREG_FIELD(ID_DFR1_EL1, HPMN0, 4, 4)
> + IDREG_FIELD(ID_DFR1_EL1, MTPMU, 0, 4)
> +IDREG_END(ID_DFR1_EL1)
> +
> +IDREG_START(ID_ISAR0_EL1)
> + IDREG_FIELD(ID_ISAR0_EL1, Divide, 24, 4)
> + IDREG_FIELD(ID_ISAR0_EL1, Debug, 20, 4)
> + IDREG_FIELD(ID_ISAR0_EL1, Coproc, 16, 4)
> + IDREG_FIELD(ID_ISAR0_EL1, CmpBranch, 12, 4)
> + IDREG_FIELD(ID_ISAR0_EL1, BitField, 8, 4)
> + IDREG_FIELD(ID_ISAR0_EL1, BitCount, 4, 4)
> + IDREG_FIELD(ID_ISAR0_EL1, Swap, 0, 4)
> +IDREG_END(ID_ISAR0_EL1)
> +
> +IDREG_START(ID_ISAR1_EL1)
> + IDREG_FIELD(ID_ISAR1_EL1, Jazelle, 28, 4)
> + IDREG_FIELD(ID_ISAR1_EL1, Interwork, 24, 4)
> + IDREG_FIELD(ID_ISAR1_EL1, Immediate, 20, 4)
> + IDREG_FIELD(ID_ISAR1_EL1, IfThen, 16, 4)
> + IDREG_FIELD(ID_ISAR1_EL1, Extend, 12, 4)
> + IDREG_FIELD(ID_ISAR1_EL1, Except_AR, 8, 4)
> + IDREG_FIELD(ID_ISAR1_EL1, Except, 4, 4)
> + IDREG_FIELD(ID_ISAR1_EL1, Endian, 0, 4)
> +IDREG_END(ID_ISAR1_EL1)
> +
> +IDREG_START(ID_ISAR2_EL1)
> + IDREG_FIELD(ID_ISAR2_EL1, Reversal, 28, 4)
> + IDREG_FIELD(ID_ISAR2_EL1, PSR_AR, 24, 4)
> + IDREG_FIELD(ID_ISAR2_EL1, MultU, 20, 4)
> + IDREG_FIELD(ID_ISAR2_EL1, MultS, 16, 4)
> + IDREG_FIELD(ID_ISAR2_EL1, Mult, 12, 4)
> + IDREG_FIELD(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
> + IDREG_FIELD(ID_ISAR2_EL1, MemHint, 4, 4)
> + IDREG_FIELD(ID_ISAR2_EL1, LoadStore, 0, 4)
> +IDREG_END(ID_ISAR2_EL1)
> +
> +IDREG_START(ID_ISAR3_EL1)
> + IDREG_FIELD(ID_ISAR3_EL1, T32EE, 28, 4)
> + IDREG_FIELD(ID_ISAR3_EL1, TrueNOP, 24, 4)
> + IDREG_FIELD(ID_ISAR3_EL1, T32Copy, 20, 4)
> + IDREG_FIELD(ID_ISAR3_EL1, TabBranch, 16, 4)
> + IDREG_FIELD(ID_ISAR3_EL1, SynchPrim, 12, 4)
> + IDREG_FIELD(ID_ISAR3_EL1, SVC, 8, 4)
> + IDREG_FIELD(ID_ISAR3_EL1, SIMD, 4, 4)
> + IDREG_FIELD(ID_ISAR3_EL1, Saturate, 0, 4)
> +IDREG_END(ID_ISAR3_EL1)
> +
> +IDREG_START(ID_ISAR4_EL1)
> + IDREG_FIELD(ID_ISAR4_EL1, SWP_frac, 28, 4)
> + IDREG_FIELD(ID_ISAR4_EL1, PSR_M, 24, 4)
> + IDREG_FIELD(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
> + IDREG_FIELD(ID_ISAR4_EL1, Barrier, 16, 4)
> + IDREG_FIELD(ID_ISAR4_EL1, SMC, 12, 4)
> + IDREG_FIELD(ID_ISAR4_EL1, Writeback, 8, 4)
> + IDREG_FIELD(ID_ISAR4_EL1, WithShifts, 4, 4)
> + IDREG_FIELD(ID_ISAR4_EL1, Unpriv, 0, 4)
> +IDREG_END(ID_ISAR4_EL1)
> +
> +IDREG_START(ID_ISAR5_EL1)
> + IDREG_FIELD(ID_ISAR5_EL1, VCMA, 28, 4)
> + IDREG_FIELD(ID_ISAR5_EL1, RDM, 24, 4)
> + IDREG_FIELD(ID_ISAR5_EL1, CRC32, 16, 4)
> + IDREG_FIELD(ID_ISAR5_EL1, SHA2, 12, 4)
> + IDREG_FIELD(ID_ISAR5_EL1, SHA1, 8, 4)
> + IDREG_FIELD(ID_ISAR5_EL1, AES, 4, 4)
> + IDREG_FIELD(ID_ISAR5_EL1, SEVL, 0, 4)
> +IDREG_END(ID_ISAR5_EL1)
> +
> +IDREG_START(ID_ISAR6_EL1)
> + IDREG_FIELD(ID_ISAR6_EL1, CLRBHB, 28, 4)
> + IDREG_FIELD(ID_ISAR6_EL1, I8MM, 24, 4)
> + IDREG_FIELD(ID_ISAR6_EL1, BF16, 20, 4)
> + IDREG_FIELD(ID_ISAR6_EL1, SPECRES, 16, 4)
> + IDREG_FIELD(ID_ISAR6_EL1, SB, 12, 4)
> + IDREG_FIELD(ID_ISAR6_EL1, FHM, 8, 4)
> + IDREG_FIELD(ID_ISAR6_EL1, DP, 4, 4)
> + IDREG_FIELD(ID_ISAR6_EL1, JSCVT, 0, 4)
> +IDREG_END(ID_ISAR6_EL1)
> +
> +IDREG_START(ID_MMFR0_EL1)
> + IDREG_FIELD(ID_MMFR0_EL1, InnerShr, 28, 4)
> + IDREG_FIELD(ID_MMFR0_EL1, FCSE, 24, 4)
> + IDREG_FIELD(ID_MMFR0_EL1, AuxReg, 20, 4)
> + IDREG_FIELD(ID_MMFR0_EL1, TCM, 16, 4)
> + IDREG_FIELD(ID_MMFR0_EL1, ShareLvl, 12, 4)
> + IDREG_FIELD(ID_MMFR0_EL1, OuterShr, 8, 4)
> + IDREG_FIELD(ID_MMFR0_EL1, PMSA, 4, 4)
> + IDREG_FIELD(ID_MMFR0_EL1, VMSA, 0, 4)
> +IDREG_END(ID_MMFR0_EL1)
> +
> +IDREG_START(ID_MMFR1_EL1)
> + IDREG_FIELD(ID_MMFR1_EL1, BPred, 28, 4)
> + IDREG_FIELD(ID_MMFR1_EL1, L1TstCln, 24, 4)
> + IDREG_FIELD(ID_MMFR1_EL1, L1Uni, 20, 4)
> + IDREG_FIELD(ID_MMFR1_EL1, L1Hvd, 16, 4)
> + IDREG_FIELD(ID_MMFR1_EL1, L1UniSW, 12, 4)
> + IDREG_FIELD(ID_MMFR1_EL1, L1HvdSW, 8, 4)
> + IDREG_FIELD(ID_MMFR1_EL1, L1UniVA, 4, 4)
> + IDREG_FIELD(ID_MMFR1_EL1, L1HvdVA, 0, 4)
> +IDREG_END(ID_MMFR1_EL1)
> +
> +IDREG_START(ID_MMFR2_EL1)
> + IDREG_FIELD(ID_MMFR2_EL1, HWAccFlg, 28, 4)
> + IDREG_FIELD(ID_MMFR2_EL1, WFIStall, 24, 4)
> + IDREG_FIELD(ID_MMFR2_EL1, MemBarr, 20, 4)
> + IDREG_FIELD(ID_MMFR2_EL1, UniTLB, 16, 4)
> + IDREG_FIELD(ID_MMFR2_EL1, HvdTLB, 12, 4)
> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdRng, 8, 4)
> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdBG, 4, 4)
> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdFG, 0, 4)
> +IDREG_END(ID_MMFR2_EL1)
> +
> +IDREG_START(ID_MMFR3_EL1)
> + IDREG_FIELD(ID_MMFR3_EL1, Supersec, 28, 4)
> + IDREG_FIELD(ID_MMFR3_EL1, CMemSz, 24, 4)
> + IDREG_FIELD(ID_MMFR3_EL1, CohWalk, 20, 4)
> + IDREG_FIELD(ID_MMFR3_EL1, PAN, 16, 4)
> + IDREG_FIELD(ID_MMFR3_EL1, MaintBcst, 12, 4)
> + IDREG_FIELD(ID_MMFR3_EL1, BPMaint, 8, 4)
> + IDREG_FIELD(ID_MMFR3_EL1, CMaintSW, 4, 4)
> + IDREG_FIELD(ID_MMFR3_EL1, CMaintVA, 0, 4)
> +IDREG_END(ID_MMFR3_EL1)
> +
> +IDREG_START(ID_MMFR4_EL1)
> + IDREG_FIELD(ID_MMFR4_EL1, EVT, 28, 4)
> + IDREG_FIELD(ID_MMFR4_EL1, CCIDX, 24, 4)
> + IDREG_FIELD(ID_MMFR4_EL1, LSM, 20, 4)
> + IDREG_FIELD(ID_MMFR4_EL1, HPDS, 16, 4)
> + IDREG_FIELD(ID_MMFR4_EL1, CnP, 12, 4)
> + IDREG_FIELD(ID_MMFR4_EL1, XNX, 8, 4)
> + IDREG_FIELD(ID_MMFR4_EL1, AC2, 4, 4)
> + IDREG_FIELD(ID_MMFR4_EL1, SpecSEI, 0, 4)
> +IDREG_END(ID_MMFR4_EL1)
> +
> +IDREG_START(ID_MMFR5_EL1)
> + IDREG_FIELD(ID_MMFR5_EL1, nTLBPA, 4, 4)
> + IDREG_FIELD(ID_MMFR5_EL1, ETS, 0, 4)
> +IDREG_END(ID_MMFR5_EL1)
> +
> +IDREG_START(ID_PFR0_EL1)
> + IDREG_FIELD(ID_PFR0_EL1, RAS, 28, 4)
> + IDREG_FIELD(ID_PFR0_EL1, DIT, 24, 4)
> + IDREG_FIELD(ID_PFR0_EL1, AMU, 20, 4)
> + IDREG_FIELD(ID_PFR0_EL1, CSV2, 16, 4)
> + IDREG_FIELD(ID_PFR0_EL1, State3, 12, 4)
> + IDREG_FIELD(ID_PFR0_EL1, State2, 8, 4)
> + IDREG_FIELD(ID_PFR0_EL1, State1, 4, 4)
> + IDREG_FIELD(ID_PFR0_EL1, State0, 0, 4)
> +IDREG_END(ID_PFR0_EL1)
> +
> +IDREG_START(ID_PFR1_EL1)
> + IDREG_FIELD(ID_PFR1_EL1, GIC, 28, 4)
> + IDREG_FIELD(ID_PFR1_EL1, Virt_frac, 24, 4)
> + IDREG_FIELD(ID_PFR1_EL1, Sec_frac, 20, 4)
> + IDREG_FIELD(ID_PFR1_EL1, GenTimer, 16, 4)
> + IDREG_FIELD(ID_PFR1_EL1, Virtualization, 12, 4)
> + IDREG_FIELD(ID_PFR1_EL1, MProgMod, 8, 4)
> + IDREG_FIELD(ID_PFR1_EL1, Security, 4, 4)
> + IDREG_FIELD(ID_PFR1_EL1, ProgMod, 0, 4)
> +IDREG_END(ID_PFR1_EL1)
> +
> +IDREG_START(ID_PFR2_EL1)
> IDREG_FIELD(ID_PFR2_EL1, RAS_frac, 8, 4)
> + IDREG_FIELD(ID_PFR2_EL1, SSBS, 4, 4)
> + IDREG_FIELD(ID_PFR2_EL1, CSV3, 0, 4)
> +IDREG_END(ID_PFR2_EL1)
> +
> +IDREG_START(MIDR_EL1)
> + IDREG_FIELD(MIDR_EL1, Implementer, 24, 8)
> + IDREG_FIELD(MIDR_EL1, Variant, 20, 4)
> + IDREG_FIELD(MIDR_EL1, Architecture, 16, 4)
> + IDREG_FIELD(MIDR_EL1, PartNum, 4, 12)
> + IDREG_FIELD(MIDR_EL1, Revision, 0, 4)
> +IDREG_END(MIDR_EL1)
> +
> +IDREG_START(MPIDR_EL1)
> + IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
> + IDREG_FIELD(MPIDR_EL1, U, 30, 1)
> + IDREG_FIELD(MPIDR_EL1, MT, 24, 1)
> + IDREG_FIELD(MPIDR_EL1, Aff2, 16, 8)
> + IDREG_FIELD(MPIDR_EL1, Aff1, 8, 8)
> + IDREG_FIELD(MPIDR_EL1, Aff0, 0, 8)
> +IDREG_END(MPIDR_EL1)
> +
> +IDREG_START(MVFR0_EL1)
> + IDREG_FIELD(MVFR0_EL1, FPRound, 28, 4)
> + IDREG_FIELD(MVFR0_EL1, FPShVec, 24, 4)
> + IDREG_FIELD(MVFR0_EL1, FPSqrt, 20, 4)
> + IDREG_FIELD(MVFR0_EL1, FPDivide, 16, 4)
> + IDREG_FIELD(MVFR0_EL1, FPTrap, 12, 4)
> + IDREG_FIELD(MVFR0_EL1, FPDP, 8, 4)
> + IDREG_FIELD(MVFR0_EL1, FPSP, 4, 4)
> + IDREG_FIELD(MVFR0_EL1, SIMDReg, 0, 4)
> +IDREG_END(MVFR0_EL1)
> +
> +IDREG_START(MVFR1_EL1)
> + IDREG_FIELD(MVFR1_EL1, SIMDFMAC, 28, 4)
> + IDREG_FIELD(MVFR1_EL1, FPHP, 24, 4)
> + IDREG_FIELD(MVFR1_EL1, SIMDHP, 20, 4)
> + IDREG_FIELD(MVFR1_EL1, SIMDSP, 16, 4)
> + IDREG_FIELD(MVFR1_EL1, SIMDInt, 12, 4)
> + IDREG_FIELD(MVFR1_EL1, SIMDLS, 8, 4)
> + IDREG_FIELD(MVFR1_EL1, FPDNaN, 4, 4)
> + IDREG_FIELD(MVFR1_EL1, FPFtZ, 0, 4)
> +IDREG_END(MVFR1_EL1)
> +
> +IDREG_START(MVFR2_EL1)
> + IDREG_FIELD(MVFR2_EL1, FPMisc, 4, 4)
> + IDREG_FIELD(MVFR2_EL1, SIMDMisc, 0, 4)
> +IDREG_END(MVFR2_EL1)
> +
> +IDREG_START(REVIDR_EL1)
> +IDREG_END(REVIDR_EL1)
> +
> +IDREG_START(SMIDR_EL1)
> + IDREG_FIELD(SMIDR_EL1, NSMC, 56, 4)
> + IDREG_FIELD(SMIDR_EL1, HIP, 52, 4)
> + IDREG_FIELD(SMIDR_EL1, Affinity2, 32, 20)
> + IDREG_FIELD(SMIDR_EL1, Implementer, 24, 8)
> + IDREG_FIELD(SMIDR_EL1, Revision, 16, 8)
> + IDREG_FIELD(SMIDR_EL1, SMPS, 15, 1)
> + IDREG_FIELD(SMIDR_EL1, SH, 13, 2)
> + IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
> +IDREG_END(SMIDR_EL1)
> +
> --
> 2.53.0
>
what is the point of a separate patch for reserved fields?
[PATCH v9 19/26] target/arm/cpu-idregs.h.inc: Generate reserved fields
Can we squash these together?
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 08/26] target/arm/cpu-idregs.h.inc: Generate enum values
2026-09-16 14:45 ` [PATCH v9 08/26] target/arm/cpu-idregs.h.inc: Generate enum values Eric Auger
@ 2026-09-25 11:59 ` Khushit Shah
2026-10-02 16:05 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-25 11:59 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Modify the python script so that enum values are also
> extracted from Registers.json.
>
> If enum values are found, the field and its enum values are
> defined within IDREG_FIELD_START/END. Each enum value is
> defined with IDREG_FIELD_ARCH_VAL() macro.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>
> v7 -> v8:
> Properly handle ValueRange
> ---
> target/arm/cpu-idregs.h.inc | 2657 ++++++++++++++---
> .../update-aarch64-cpu-sysreg-properties.py | 86 +-
> 2 files changed, 2332 insertions(+), 411 deletions(-)
>
> diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
> index c9745e2fb6..10ddfdf43a 100644
> --- a/target/arm/cpu-idregs.h.inc
> +++ b/target/arm/cpu-idregs.h.inc
> @@ -4,7 +4,11 @@
>
> /* IDREG_START(REG) */
> /* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */
> +/* or for fields with enum values */
> +/* IDREG_FIELD_START(REG, FIELD, SHIFT, LENGTH) */
> +/* IDREG_FIELD_ARCH_VAL(VALUE) */
> /* ... */
> +/* IDREG_FIELD_END(REG, FIELD) */
> /* IDREG_END(REG) */
>
> IDREG_START(AIDR_EL1)
> @@ -18,7 +22,16 @@ IDREG_START(CLIDR_EL1)
> IDREG_FIELD(CLIDR_EL1, Ttype3, 37, 2)
> IDREG_FIELD(CLIDR_EL1, Ttype2, 35, 2)
> IDREG_FIELD(CLIDR_EL1, Ttype1, 33, 2)
> - IDREG_FIELD(CLIDR_EL1, ICB, 30, 3)
> + IDREG_FIELD_START(CLIDR_EL1, ICB, 30, 3)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_END(CLIDR_EL1, ICB)
> IDREG_FIELD(CLIDR_EL1, LoUU, 27, 3)
> IDREG_FIELD(CLIDR_EL1, LoC, 24, 3)
> IDREG_FIELD(CLIDR_EL1, LoUIS, 21, 3)
> @@ -33,12 +46,23 @@ IDREG_END(CLIDR_EL1)
>
> IDREG_START(CTR_EL0)
> IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
> - IDREG_FIELD(CTR_EL0, DIC, 29, 1)
> - IDREG_FIELD(CTR_EL0, IDC, 28, 1)
> + IDREG_FIELD_START(CTR_EL0, DIC, 29, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(CTR_EL0, DIC)
> + IDREG_FIELD_START(CTR_EL0, IDC, 28, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(CTR_EL0, IDC)
> IDREG_FIELD(CTR_EL0, CWG, 24, 4)
> IDREG_FIELD(CTR_EL0, ERG, 20, 4)
> IDREG_FIELD(CTR_EL0, DminLine, 16, 4)
> - IDREG_FIELD(CTR_EL0, L1Ip, 14, 2)
> + IDREG_FIELD_START(CTR_EL0, L1Ip, 14, 2)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(CTR_EL0, L1Ip)
> IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
> IDREG_END(CTR_EL0)
>
> @@ -59,549 +83,2368 @@ IDREG_START(ID_AA64AFR1_EL1)
> IDREG_END(ID_AA64AFR1_EL1)
>
> IDREG_START(ID_AA64DFR0_EL1)
> - IDREG_FIELD(ID_AA64DFR0_EL1, HPMN0, 60, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, BRBE, 52, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, MTPMU, 48, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, PMSVer, 32, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, WRPs, 20, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, PMSS, 16, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, BRPs, 12, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, PMUVer, 8, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, TraceVer, 4, 4)
> - IDREG_FIELD(ID_AA64DFR0_EL1, DebugVer, 0, 4)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, HPMN0, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, HPMN0)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, ExtTrcBuff)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, BRBE, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, BRBE)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, MTPMU, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, MTPMU)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, TraceBuffer)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, TraceFilt)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, DoubleLock)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, PMSVer, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, PMSVer)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, CTX_CMPs)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, WRPs, 20, 4)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, WRPs)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, PMSS, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, PMSS)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, BRPs, 12, 4)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, BRPs)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, PMUVer, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, PMUVer)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, TraceVer, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, TraceVer)
> + IDREG_FIELD_START(ID_AA64DFR0_EL1, DebugVer, 0, 4)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_END(ID_AA64DFR0_EL1, DebugVer)
> IDREG_END(ID_AA64DFR0_EL1)
>
> IDREG_START(ID_AA64DFR1_EL1)
> - IDREG_FIELD(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
> - IDREG_FIELD(ID_AA64DFR1_EL1, DPFZS, 52, 4)
> - IDREG_FIELD(ID_AA64DFR1_EL1, EBEP, 48, 4)
> - IDREG_FIELD(ID_AA64DFR1_EL1, ITE, 44, 4)
> - IDREG_FIELD(ID_AA64DFR1_EL1, ABLE, 40, 4)
> - IDREG_FIELD(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
> - IDREG_FIELD(ID_AA64DFR1_EL1, SPMU, 32, 4)
> - IDREG_FIELD(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
> - IDREG_FIELD(ID_AA64DFR1_EL1, WRPs, 16, 8)
> - IDREG_FIELD(ID_AA64DFR1_EL1, BRPs, 8, 8)
> - IDREG_FIELD(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_ARCH_VAL(16)
> + IDREG_FIELD_ARCH_VAL(17)
> + IDREG_FIELD_ARCH_VAL(18)
> + IDREG_FIELD_ARCH_VAL(19)
> + IDREG_FIELD_ARCH_VAL(20)
> + IDREG_FIELD_ARCH_VAL(21)
> + IDREG_FIELD_ARCH_VAL(22)
> + IDREG_FIELD_ARCH_VAL(23)
> + IDREG_FIELD_ARCH_VAL(24)
> + IDREG_FIELD_ARCH_VAL(25)
> + IDREG_FIELD_ARCH_VAL(26)
> + IDREG_FIELD_ARCH_VAL(27)
> + IDREG_FIELD_ARCH_VAL(28)
> + IDREG_FIELD_ARCH_VAL(29)
> + IDREG_FIELD_ARCH_VAL(30)
> + IDREG_FIELD_ARCH_VAL(31)
> + IDREG_FIELD_ARCH_VAL(32)
> + IDREG_FIELD_ARCH_VAL(33)
> + IDREG_FIELD_ARCH_VAL(34)
> + IDREG_FIELD_ARCH_VAL(35)
> + IDREG_FIELD_ARCH_VAL(36)
> + IDREG_FIELD_ARCH_VAL(37)
> + IDREG_FIELD_ARCH_VAL(38)
> + IDREG_FIELD_ARCH_VAL(39)
> + IDREG_FIELD_ARCH_VAL(40)
> + IDREG_FIELD_ARCH_VAL(41)
> + IDREG_FIELD_ARCH_VAL(42)
> + IDREG_FIELD_ARCH_VAL(43)
> + IDREG_FIELD_ARCH_VAL(44)
> + IDREG_FIELD_ARCH_VAL(45)
> + IDREG_FIELD_ARCH_VAL(46)
> + IDREG_FIELD_ARCH_VAL(47)
> + IDREG_FIELD_ARCH_VAL(48)
> + IDREG_FIELD_ARCH_VAL(49)
> + IDREG_FIELD_ARCH_VAL(50)
> + IDREG_FIELD_ARCH_VAL(51)
> + IDREG_FIELD_ARCH_VAL(52)
> + IDREG_FIELD_ARCH_VAL(53)
> + IDREG_FIELD_ARCH_VAL(54)
> + IDREG_FIELD_ARCH_VAL(55)
> + IDREG_FIELD_ARCH_VAL(56)
> + IDREG_FIELD_ARCH_VAL(57)
> + IDREG_FIELD_ARCH_VAL(58)
> + IDREG_FIELD_ARCH_VAL(59)
> + IDREG_FIELD_ARCH_VAL(60)
> + IDREG_FIELD_ARCH_VAL(61)
> + IDREG_FIELD_ARCH_VAL(62)
> + IDREG_FIELD_ARCH_VAL(63)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, ABL_CMPs)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, DPFZS, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, DPFZS)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, EBEP, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, EBEP)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, ITE, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, ITE)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, ABLE, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, ABLE)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, PMICNTR)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, SPMU, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, SPMU)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_ARCH_VAL(16)
> + IDREG_FIELD_ARCH_VAL(17)
> + IDREG_FIELD_ARCH_VAL(18)
> + IDREG_FIELD_ARCH_VAL(19)
> + IDREG_FIELD_ARCH_VAL(20)
> + IDREG_FIELD_ARCH_VAL(21)
> + IDREG_FIELD_ARCH_VAL(22)
> + IDREG_FIELD_ARCH_VAL(23)
> + IDREG_FIELD_ARCH_VAL(24)
> + IDREG_FIELD_ARCH_VAL(25)
> + IDREG_FIELD_ARCH_VAL(26)
> + IDREG_FIELD_ARCH_VAL(27)
> + IDREG_FIELD_ARCH_VAL(28)
> + IDREG_FIELD_ARCH_VAL(29)
> + IDREG_FIELD_ARCH_VAL(30)
> + IDREG_FIELD_ARCH_VAL(31)
> + IDREG_FIELD_ARCH_VAL(32)
> + IDREG_FIELD_ARCH_VAL(33)
> + IDREG_FIELD_ARCH_VAL(34)
> + IDREG_FIELD_ARCH_VAL(35)
> + IDREG_FIELD_ARCH_VAL(36)
> + IDREG_FIELD_ARCH_VAL(37)
> + IDREG_FIELD_ARCH_VAL(38)
> + IDREG_FIELD_ARCH_VAL(39)
> + IDREG_FIELD_ARCH_VAL(40)
> + IDREG_FIELD_ARCH_VAL(41)
> + IDREG_FIELD_ARCH_VAL(42)
> + IDREG_FIELD_ARCH_VAL(43)
> + IDREG_FIELD_ARCH_VAL(44)
> + IDREG_FIELD_ARCH_VAL(45)
> + IDREG_FIELD_ARCH_VAL(46)
> + IDREG_FIELD_ARCH_VAL(47)
> + IDREG_FIELD_ARCH_VAL(48)
> + IDREG_FIELD_ARCH_VAL(49)
> + IDREG_FIELD_ARCH_VAL(50)
> + IDREG_FIELD_ARCH_VAL(51)
> + IDREG_FIELD_ARCH_VAL(52)
> + IDREG_FIELD_ARCH_VAL(53)
> + IDREG_FIELD_ARCH_VAL(54)
> + IDREG_FIELD_ARCH_VAL(55)
> + IDREG_FIELD_ARCH_VAL(56)
> + IDREG_FIELD_ARCH_VAL(57)
> + IDREG_FIELD_ARCH_VAL(58)
> + IDREG_FIELD_ARCH_VAL(59)
> + IDREG_FIELD_ARCH_VAL(60)
> + IDREG_FIELD_ARCH_VAL(61)
> + IDREG_FIELD_ARCH_VAL(62)
> + IDREG_FIELD_ARCH_VAL(63)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, CTX_CMPs)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, WRPs, 16, 8)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_ARCH_VAL(16)
> + IDREG_FIELD_ARCH_VAL(17)
> + IDREG_FIELD_ARCH_VAL(18)
> + IDREG_FIELD_ARCH_VAL(19)
> + IDREG_FIELD_ARCH_VAL(20)
> + IDREG_FIELD_ARCH_VAL(21)
> + IDREG_FIELD_ARCH_VAL(22)
> + IDREG_FIELD_ARCH_VAL(23)
> + IDREG_FIELD_ARCH_VAL(24)
> + IDREG_FIELD_ARCH_VAL(25)
> + IDREG_FIELD_ARCH_VAL(26)
> + IDREG_FIELD_ARCH_VAL(27)
> + IDREG_FIELD_ARCH_VAL(28)
> + IDREG_FIELD_ARCH_VAL(29)
> + IDREG_FIELD_ARCH_VAL(30)
> + IDREG_FIELD_ARCH_VAL(31)
> + IDREG_FIELD_ARCH_VAL(32)
> + IDREG_FIELD_ARCH_VAL(33)
> + IDREG_FIELD_ARCH_VAL(34)
> + IDREG_FIELD_ARCH_VAL(35)
> + IDREG_FIELD_ARCH_VAL(36)
> + IDREG_FIELD_ARCH_VAL(37)
> + IDREG_FIELD_ARCH_VAL(38)
> + IDREG_FIELD_ARCH_VAL(39)
> + IDREG_FIELD_ARCH_VAL(40)
> + IDREG_FIELD_ARCH_VAL(41)
> + IDREG_FIELD_ARCH_VAL(42)
> + IDREG_FIELD_ARCH_VAL(43)
> + IDREG_FIELD_ARCH_VAL(44)
> + IDREG_FIELD_ARCH_VAL(45)
> + IDREG_FIELD_ARCH_VAL(46)
> + IDREG_FIELD_ARCH_VAL(47)
> + IDREG_FIELD_ARCH_VAL(48)
> + IDREG_FIELD_ARCH_VAL(49)
> + IDREG_FIELD_ARCH_VAL(50)
> + IDREG_FIELD_ARCH_VAL(51)
> + IDREG_FIELD_ARCH_VAL(52)
> + IDREG_FIELD_ARCH_VAL(53)
> + IDREG_FIELD_ARCH_VAL(54)
> + IDREG_FIELD_ARCH_VAL(55)
> + IDREG_FIELD_ARCH_VAL(56)
> + IDREG_FIELD_ARCH_VAL(57)
> + IDREG_FIELD_ARCH_VAL(58)
> + IDREG_FIELD_ARCH_VAL(59)
> + IDREG_FIELD_ARCH_VAL(60)
> + IDREG_FIELD_ARCH_VAL(61)
> + IDREG_FIELD_ARCH_VAL(62)
> + IDREG_FIELD_ARCH_VAL(63)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, WRPs)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, BRPs, 8, 8)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_ARCH_VAL(16)
> + IDREG_FIELD_ARCH_VAL(17)
> + IDREG_FIELD_ARCH_VAL(18)
> + IDREG_FIELD_ARCH_VAL(19)
> + IDREG_FIELD_ARCH_VAL(20)
> + IDREG_FIELD_ARCH_VAL(21)
> + IDREG_FIELD_ARCH_VAL(22)
> + IDREG_FIELD_ARCH_VAL(23)
> + IDREG_FIELD_ARCH_VAL(24)
> + IDREG_FIELD_ARCH_VAL(25)
> + IDREG_FIELD_ARCH_VAL(26)
> + IDREG_FIELD_ARCH_VAL(27)
> + IDREG_FIELD_ARCH_VAL(28)
> + IDREG_FIELD_ARCH_VAL(29)
> + IDREG_FIELD_ARCH_VAL(30)
> + IDREG_FIELD_ARCH_VAL(31)
> + IDREG_FIELD_ARCH_VAL(32)
> + IDREG_FIELD_ARCH_VAL(33)
> + IDREG_FIELD_ARCH_VAL(34)
> + IDREG_FIELD_ARCH_VAL(35)
> + IDREG_FIELD_ARCH_VAL(36)
> + IDREG_FIELD_ARCH_VAL(37)
> + IDREG_FIELD_ARCH_VAL(38)
> + IDREG_FIELD_ARCH_VAL(39)
> + IDREG_FIELD_ARCH_VAL(40)
> + IDREG_FIELD_ARCH_VAL(41)
> + IDREG_FIELD_ARCH_VAL(42)
> + IDREG_FIELD_ARCH_VAL(43)
> + IDREG_FIELD_ARCH_VAL(44)
> + IDREG_FIELD_ARCH_VAL(45)
> + IDREG_FIELD_ARCH_VAL(46)
> + IDREG_FIELD_ARCH_VAL(47)
> + IDREG_FIELD_ARCH_VAL(48)
> + IDREG_FIELD_ARCH_VAL(49)
> + IDREG_FIELD_ARCH_VAL(50)
> + IDREG_FIELD_ARCH_VAL(51)
> + IDREG_FIELD_ARCH_VAL(52)
> + IDREG_FIELD_ARCH_VAL(53)
> + IDREG_FIELD_ARCH_VAL(54)
> + IDREG_FIELD_ARCH_VAL(55)
> + IDREG_FIELD_ARCH_VAL(56)
> + IDREG_FIELD_ARCH_VAL(57)
> + IDREG_FIELD_ARCH_VAL(58)
> + IDREG_FIELD_ARCH_VAL(59)
> + IDREG_FIELD_ARCH_VAL(60)
> + IDREG_FIELD_ARCH_VAL(61)
> + IDREG_FIELD_ARCH_VAL(62)
> + IDREG_FIELD_ARCH_VAL(63)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, BRPs)
> + IDREG_FIELD_START(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_ARCH_VAL(16)
> + IDREG_FIELD_ARCH_VAL(17)
> + IDREG_FIELD_ARCH_VAL(18)
> + IDREG_FIELD_ARCH_VAL(19)
> + IDREG_FIELD_ARCH_VAL(20)
> + IDREG_FIELD_ARCH_VAL(21)
> + IDREG_FIELD_ARCH_VAL(22)
> + IDREG_FIELD_ARCH_VAL(23)
> + IDREG_FIELD_ARCH_VAL(24)
> + IDREG_FIELD_ARCH_VAL(25)
> + IDREG_FIELD_ARCH_VAL(26)
> + IDREG_FIELD_ARCH_VAL(27)
> + IDREG_FIELD_ARCH_VAL(28)
> + IDREG_FIELD_ARCH_VAL(29)
> + IDREG_FIELD_ARCH_VAL(30)
> + IDREG_FIELD_ARCH_VAL(31)
> + IDREG_FIELD_END(ID_AA64DFR1_EL1, SYSPMUID)
> IDREG_END(ID_AA64DFR1_EL1)
>
> IDREG_START(ID_AA64DFR2_EL1)
> - IDREG_FIELD(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
> - IDREG_FIELD(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
> - IDREG_FIELD(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
> - IDREG_FIELD(ID_AA64DFR2_EL1, BWE, 4, 4)
> - IDREG_FIELD(ID_AA64DFR2_EL1, STEP, 0, 4)
> + IDREG_FIELD_START(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR2_EL1, TRBE_EXC)
> + IDREG_FIELD_START(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR2_EL1, SPE_nVM)
> + IDREG_FIELD_START(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR2_EL1, SPE_EXC)
> + IDREG_FIELD_START(ID_AA64DFR2_EL1, BWE, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64DFR2_EL1, BWE)
> + IDREG_FIELD_START(ID_AA64DFR2_EL1, STEP, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64DFR2_EL1, STEP)
> IDREG_END(ID_AA64DFR2_EL1)
>
> IDREG_START(ID_AA64FPFR0_EL1)
> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
> - IDREG_FIELD(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8CVT)
> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8FMA)
> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8DP4)
> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8DP2)
> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8MM8)
> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8MM4)
> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F16MM2)
> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8E4M3)
> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8E5M2)
> IDREG_END(ID_AA64FPFR0_EL1)
>
> IDREG_START(ID_AA64ISAR0_EL1)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, RNDR, 60, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, TLB, 56, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, TS, 52, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, FHM, 48, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, DP, 44, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, SM4, 40, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, SM3, 36, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, SHA3, 32, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, RDM, 28, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, Atomic, 20, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, CRC32, 16, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, SHA2, 12, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, SHA1, 8, 4)
> - IDREG_FIELD(ID_AA64ISAR0_EL1, AES, 4, 4)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, RNDR, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, RNDR)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, TLB, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, TLB)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, TS, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, TS)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, FHM, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, FHM)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, DP, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, DP)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SM4, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SM4)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SM3, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SM3)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SHA3, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SHA3)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, RDM, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, RDM)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, Atomic, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, Atomic)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, CRC32, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, CRC32)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SHA2, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SHA2)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SHA1, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SHA1)
> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, AES, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, AES)
> IDREG_END(ID_AA64ISAR0_EL1)
>
> IDREG_START(ID_AA64ISAR1_EL1)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, LS64, 60, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, XS, 56, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, I8MM, 52, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, DGH, 48, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, BF16, 44, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, SB, 36, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, GPI, 28, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, GPA, 24, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, FCMA, 16, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, API, 8, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, APA, 4, 4)
> - IDREG_FIELD(ID_AA64ISAR1_EL1, DPB, 0, 4)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, LS64, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, LS64)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, XS, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, XS)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, I8MM, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, I8MM)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, DGH, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, DGH)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, BF16, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, BF16)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, SPECRES)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, SB, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, SB)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, FRINTTS)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, GPI, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, GPI)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, GPA, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, GPA)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, LRCPC)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, FCMA, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, FCMA)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, JSCVT)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, API, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, API)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, APA, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, APA)
> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, DPB, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, DPB)
> IDREG_END(ID_AA64ISAR1_EL1)
>
> IDREG_START(ID_AA64ISAR2_EL1)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, LUT, 56, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, CSSC, 52, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, BC, 20, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, MOPS, 16, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, APA3, 12, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, GPA3, 8, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, RPRES, 4, 4)
> - IDREG_FIELD(ID_AA64ISAR2_EL1, WFxT, 0, 4)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, ATS1A)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, LUT, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, LUT)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, CSSC, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, CSSC)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, RPRFM)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, PCDPHINT)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, PRFMSLC)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, SYSINSTR_128)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, SYSREG_128)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, CLRBHB)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, PAC_frac)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, BC, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, BC)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, MOPS, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, MOPS)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, APA3, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, APA3)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, GPA3, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, GPA3)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, RPRES, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, RPRES)
> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, WFxT, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, WFxT)
> IDREG_END(ID_AA64ISAR2_EL1)
>
> IDREG_START(ID_AA64ISAR3_EL1)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, LSCP, 44, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, MTETC, 36, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, LSUI, 24, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, LSFE, 16, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, PACM, 12, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
> - IDREG_FIELD(ID_AA64ISAR3_EL1, CPA, 0, 4)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSCP, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSCP)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSCSHINT)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, MTETC, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, MTETC)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, PAC_frac2)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, FPRCVT)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSUI, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSUI)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, OCCMO)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSFE, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSFE)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, PACM, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, PACM)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, TLBIW)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, FAMINMAX)
> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, CPA, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, CPA)
> IDREG_END(ID_AA64ISAR3_EL1)
>
> IDREG_START(ID_AA64MMFR0_EL1)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, ECV, 60, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, FGT, 56, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, ExS, 44, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4, 28, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64, 24, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16, 20, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
> - IDREG_FIELD(ID_AA64MMFR0_EL1, PARange, 0, 4)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, ECV, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, ECV)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, FGT, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, FGT)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, ExS, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, ExS)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran4_2)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran64_2)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran16_2)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran4, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran4)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran64, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran64)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran16, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran16)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, BigEndEL0)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, SNSMem)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, BigEnd)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, ASIDBits)
> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, PARange, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, PARange)
> IDREG_END(ID_AA64MMFR0_EL1)
>
> IDREG_START(ID_AA64MMFR1_EL1)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, CMOW, 56, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, AFP, 44, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, HCX, 40, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, ETS, 36, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, TWED, 32, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, XNX, 28, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, PAN, 20, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, LO, 16, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, HPDS, 12, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, VH, 8, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
> - IDREG_FIELD(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, ECBHB)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, CMOW, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, CMOW)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, TIDCP1)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, nTLBPA)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, AFP, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, AFP)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, HCX, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, HCX)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, ETS, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, ETS)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, TWED, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, TWED)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, XNX, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, XNX)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, SpecSEI)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, PAN, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, PAN)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, LO, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, LO)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, HPDS, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, HPDS)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, VH, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, VH)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, VMIDBits)
> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, HAFDBS)
> IDREG_END(ID_AA64MMFR1_EL1)
>
> IDREG_START(ID_AA64MMFR2_EL1)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, E0PD, 60, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, EVT, 56, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, BBM, 52, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, TTL, 48, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, FWB, 40, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, IDS, 36, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, AT, 32, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, ST, 28, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, NV, 24, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, VARange, 16, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, IESB, 12, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, LSM, 8, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, UAO, 4, 4)
> - IDREG_FIELD(ID_AA64MMFR2_EL1, CnP, 0, 4)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, E0PD, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, E0PD)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, EVT, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, EVT)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, BBM, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, BBM)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, TTL, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, TTL)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, FWB, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, FWB)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, IDS, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, IDS)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, AT, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, AT)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, ST, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, ST)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, NV, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, NV)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, CCIDX)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, VARange, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, VARange)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, IESB, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, IESB)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, LSM, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, LSM)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, UAO, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, UAO)
> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, CnP, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, CnP)
> IDREG_END(ID_AA64MMFR2_EL1)
>
> IDREG_START(ID_AA64MMFR3_EL1)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, ADERR, 56, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, SDERR, 52, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, ANERR, 44, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, SNERR, 40, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, D128_2, 36, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, D128, 32, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, MEC, 28, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, AIE, 24, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, S2POE, 20, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, S1POE, 16, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
> - IDREG_FIELD(ID_AA64MMFR3_EL1, TCRX, 0, 4)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, Spec_FPACC)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, ADERR, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, ADERR)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, SDERR, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, SDERR)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, ANERR, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, ANERR)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, SNERR, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, SNERR)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, D128_2, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, D128_2)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, D128, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, D128)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, MEC, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, MEC)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, AIE, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, AIE)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, S2POE, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, S2POE)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, S1POE, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, S1POE)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, S2PIE)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, S1PIE)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, SCTLRX)
> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, TCRX, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, TCRX)
> IDREG_END(ID_AA64MMFR3_EL1)
>
> IDREG_START(ID_AA64MMFR4_EL1)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, SCRX, 56, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, TEV, 52, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, TPS, 48, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, TLBID, 40, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, EAESR, 32, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, E2H0, 24, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, ASID2, 8, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, EIESB, 4, 4)
> - IDREG_FIELD(ID_AA64MMFR4_EL1, PoPS, 0, 4)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, MTEFGT)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, SCRX, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, SCRX)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, TEV, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, TEV)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, TPS, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, TPS)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, SRMASK)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, TLBID, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, TLBID)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, E3DSE)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, EAESR, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, EAESR)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, RMEGDI)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, E2H0, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, E2H0)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, NV_frac)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, FGWTE3)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, HACDBS)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, ASID2, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, ASID2)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, EIESB, 4, 4)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, EIESB)
> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, PoPS, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, PoPS)
> IDREG_END(ID_AA64MMFR4_EL1)
>
> IDREG_START(ID_AA64PFR0_EL1)
> - IDREG_FIELD(ID_AA64PFR0_EL1, CSV3, 60, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, CSV2, 56, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, RME, 52, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, DIT, 48, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, AMU, 44, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, MPAM, 40, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, SEL2, 36, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, SVE, 32, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, RAS, 28, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, GIC, 24, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, FP, 16, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, EL3, 12, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, EL2, 8, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, EL1, 4, 4)
> - IDREG_FIELD(ID_AA64PFR0_EL1, EL0, 0, 4)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, CSV3, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, CSV3)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, CSV2, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, CSV2)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, RME, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, RME)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, DIT, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, DIT)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, AMU, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, AMU)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, MPAM, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, MPAM)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, SEL2, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, SEL2)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, SVE, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, SVE)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, RAS, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, RAS)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, GIC, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, GIC)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, AdvSIMD)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, FP, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, FP)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, EL3, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, EL3)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, EL2, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, EL2)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, EL1, 4, 4)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, EL1)
> + IDREG_FIELD_START(ID_AA64PFR0_EL1, EL0, 0, 4)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR0_EL1, EL0)
> IDREG_END(ID_AA64PFR0_EL1)
>
> IDREG_START(ID_AA64PFR1_EL1)
> - IDREG_FIELD(ID_AA64PFR1_EL1, PFAR, 60, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, DF2, 56, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, MTEX, 52, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, THE, 48, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, GCS, 44, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, NMI, 36, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, SME, 24, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, MTE, 8, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, SSBS, 4, 4)
> - IDREG_FIELD(ID_AA64PFR1_EL1, BT, 0, 4)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, PFAR, 60, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, PFAR)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, DF2, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, DF2)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, MTEX, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, MTEX)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, THE, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, THE)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, GCS, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, GCS)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, MTE_frac)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, NMI, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, NMI)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, CSV2_frac)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, RNDR_trap)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, SME, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, SME)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, MPAM_frac)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, RAS_frac)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, MTE, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, MTE)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, SSBS, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, SSBS)
> + IDREG_FIELD_START(ID_AA64PFR1_EL1, BT, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR1_EL1, BT)
> IDREG_END(ID_AA64PFR1_EL1)
>
> IDREG_START(ID_AA64PFR2_EL1)
> - IDREG_FIELD(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, VMTETC, 40, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, VMTE, 36, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, FPMR, 32, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, MPAM2, 28, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, FGDT, 24, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, UINJ, 16, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, GCIE, 12, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
> - IDREG_FIELD(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, VMTETCL)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTETC, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, VMTETC)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTE, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, VMTE)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, FPMR, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, FPMR)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MPAM2, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MPAM2)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, FGDT, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, FGDT)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MTEEIRG)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, UINJ, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, UINJ)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, GCIE, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, GCIE)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MTEFAR)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MTESTOREONLY)
> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MTEPERM)
> IDREG_END(ID_AA64PFR2_EL1)
>
> IDREG_START(ID_AA64SMFR0_EL1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, FA64, 63, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, LUT6, 61, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, SMEver, 56, 4)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, I16I64, 52, 4)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, F64F64, 48, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, I16I32, 44, 4)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, B16B16, 43, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, F16F16, 42, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, F8F16, 41, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, F8F32, 40, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, I8I32, 36, 4)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, F16F32, 35, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, B16F32, 34, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, F32F32, 32, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, AES, 24, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, STMOP, 16, 1)
> - IDREG_FIELD(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, FA64, 63, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, FA64)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, LUT6, 61, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, LUT6)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, LUTv2)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SMEver, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SMEver)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, I16I64, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, I16I64)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F64F64, 48, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F64F64)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, I16I32, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, I16I32)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, B16B16, 43, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, B16B16)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F16F16, 42, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F16F16)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F8F16, 41, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F8F16)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F8F32, 40, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F8F32)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, I8I32, 36, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, I8I32)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F16F32, 35, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F16F32)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, B16F32, 34, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, B16F32)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, BI32I32)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F32F32, 32, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F32F32)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8FMA)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8DP4)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8DP2)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SBitPerm)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, AES, 24, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, AES)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SFEXPA)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, STMOP, 16, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, STMOP)
> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SMOP4)
> IDREG_END(ID_AA64SMFR0_EL1)
>
> IDREG_START(ID_AA64ZFR0_EL1)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, F64MM, 56, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, F32MM, 52, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, F16MM, 48, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, I8MM, 44, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, SM4, 40, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, SHA3, 32, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, B16B16, 24, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, BF16, 20, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, AES, 4, 4)
> - IDREG_FIELD(ID_AA64ZFR0_EL1, SVEver, 0, 4)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, F64MM, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, F64MM)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, F32MM, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, F32MM)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, F16MM, 48, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, F16MM)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, I8MM, 44, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, I8MM)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, SM4, 40, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, SM4)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, SHA3, 32, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, SHA3)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, B16B16, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, B16B16)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, BF16, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, BF16)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, BitPerm)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, EltPerm)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, AES, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, AES)
> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, SVEver, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, SVEver)
> IDREG_END(ID_AA64ZFR0_EL1)
>
> IDREG_START(ID_AFR0_EL1)
> IDREG_END(ID_AFR0_EL1)
>
> IDREG_START(ID_DFR0_EL1)
> - IDREG_FIELD(ID_DFR0_EL1, TraceFilt, 28, 4)
> - IDREG_FIELD(ID_DFR0_EL1, PerfMon, 24, 4)
> - IDREG_FIELD(ID_DFR0_EL1, MProfDbg, 20, 4)
> - IDREG_FIELD(ID_DFR0_EL1, MMapTrc, 16, 4)
> - IDREG_FIELD(ID_DFR0_EL1, CopTrc, 12, 4)
> - IDREG_FIELD(ID_DFR0_EL1, MMapDbg, 8, 4)
> + IDREG_FIELD_START(ID_DFR0_EL1, TraceFilt, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_DFR0_EL1, TraceFilt)
> + IDREG_FIELD_START(ID_DFR0_EL1, PerfMon, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_DFR0_EL1, PerfMon)
> + IDREG_FIELD_START(ID_DFR0_EL1, MProfDbg, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_DFR0_EL1, MProfDbg)
> + IDREG_FIELD_START(ID_DFR0_EL1, MMapTrc, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_DFR0_EL1, MMapTrc)
> + IDREG_FIELD_START(ID_DFR0_EL1, CopTrc, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_DFR0_EL1, CopTrc)
> + IDREG_FIELD_START(ID_DFR0_EL1, MMapDbg, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_END(ID_DFR0_EL1, MMapDbg)
> IDREG_FIELD(ID_DFR0_EL1, CopSDbg, 4, 4)
> - IDREG_FIELD(ID_DFR0_EL1, CopDbg, 0, 4)
> + IDREG_FIELD_START(ID_DFR0_EL1, CopDbg, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_END(ID_DFR0_EL1, CopDbg)
> IDREG_END(ID_DFR0_EL1)
>
> IDREG_START(ID_DFR1_EL1)
> - IDREG_FIELD(ID_DFR1_EL1, HPMN0, 4, 4)
> - IDREG_FIELD(ID_DFR1_EL1, MTPMU, 0, 4)
> + IDREG_FIELD_START(ID_DFR1_EL1, HPMN0, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_DFR1_EL1, HPMN0)
> + IDREG_FIELD_START(ID_DFR1_EL1, MTPMU, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_DFR1_EL1, MTPMU)
> IDREG_END(ID_DFR1_EL1)
>
> IDREG_START(ID_ISAR0_EL1)
> - IDREG_FIELD(ID_ISAR0_EL1, Divide, 24, 4)
> - IDREG_FIELD(ID_ISAR0_EL1, Debug, 20, 4)
> - IDREG_FIELD(ID_ISAR0_EL1, Coproc, 16, 4)
> - IDREG_FIELD(ID_ISAR0_EL1, CmpBranch, 12, 4)
> - IDREG_FIELD(ID_ISAR0_EL1, BitField, 8, 4)
> - IDREG_FIELD(ID_ISAR0_EL1, BitCount, 4, 4)
> - IDREG_FIELD(ID_ISAR0_EL1, Swap, 0, 4)
> + IDREG_FIELD_START(ID_ISAR0_EL1, Divide, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR0_EL1, Divide)
> + IDREG_FIELD_START(ID_ISAR0_EL1, Debug, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR0_EL1, Debug)
> + IDREG_FIELD_START(ID_ISAR0_EL1, Coproc, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_END(ID_ISAR0_EL1, Coproc)
> + IDREG_FIELD_START(ID_ISAR0_EL1, CmpBranch, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR0_EL1, CmpBranch)
> + IDREG_FIELD_START(ID_ISAR0_EL1, BitField, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR0_EL1, BitField)
> + IDREG_FIELD_START(ID_ISAR0_EL1, BitCount, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR0_EL1, BitCount)
> + IDREG_FIELD_START(ID_ISAR0_EL1, Swap, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR0_EL1, Swap)
> IDREG_END(ID_ISAR0_EL1)
>
> IDREG_START(ID_ISAR1_EL1)
> - IDREG_FIELD(ID_ISAR1_EL1, Jazelle, 28, 4)
> - IDREG_FIELD(ID_ISAR1_EL1, Interwork, 24, 4)
> - IDREG_FIELD(ID_ISAR1_EL1, Immediate, 20, 4)
> - IDREG_FIELD(ID_ISAR1_EL1, IfThen, 16, 4)
> - IDREG_FIELD(ID_ISAR1_EL1, Extend, 12, 4)
> - IDREG_FIELD(ID_ISAR1_EL1, Except_AR, 8, 4)
> - IDREG_FIELD(ID_ISAR1_EL1, Except, 4, 4)
> - IDREG_FIELD(ID_ISAR1_EL1, Endian, 0, 4)
> + IDREG_FIELD_START(ID_ISAR1_EL1, Jazelle, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR1_EL1, Jazelle)
> + IDREG_FIELD_START(ID_ISAR1_EL1, Interwork, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_ISAR1_EL1, Interwork)
> + IDREG_FIELD_START(ID_ISAR1_EL1, Immediate, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR1_EL1, Immediate)
> + IDREG_FIELD_START(ID_ISAR1_EL1, IfThen, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR1_EL1, IfThen)
> + IDREG_FIELD_START(ID_ISAR1_EL1, Extend, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR1_EL1, Extend)
> + IDREG_FIELD_START(ID_ISAR1_EL1, Except_AR, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR1_EL1, Except_AR)
> + IDREG_FIELD_START(ID_ISAR1_EL1, Except, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR1_EL1, Except)
> + IDREG_FIELD_START(ID_ISAR1_EL1, Endian, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR1_EL1, Endian)
> IDREG_END(ID_ISAR1_EL1)
>
> IDREG_START(ID_ISAR2_EL1)
> - IDREG_FIELD(ID_ISAR2_EL1, Reversal, 28, 4)
> - IDREG_FIELD(ID_ISAR2_EL1, PSR_AR, 24, 4)
> - IDREG_FIELD(ID_ISAR2_EL1, MultU, 20, 4)
> - IDREG_FIELD(ID_ISAR2_EL1, MultS, 16, 4)
> - IDREG_FIELD(ID_ISAR2_EL1, Mult, 12, 4)
> - IDREG_FIELD(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
> - IDREG_FIELD(ID_ISAR2_EL1, MemHint, 4, 4)
> - IDREG_FIELD(ID_ISAR2_EL1, LoadStore, 0, 4)
> + IDREG_FIELD_START(ID_ISAR2_EL1, Reversal, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR2_EL1, Reversal)
> + IDREG_FIELD_START(ID_ISAR2_EL1, PSR_AR, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR2_EL1, PSR_AR)
> + IDREG_FIELD_START(ID_ISAR2_EL1, MultU, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR2_EL1, MultU)
> + IDREG_FIELD_START(ID_ISAR2_EL1, MultS, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_ISAR2_EL1, MultS)
> + IDREG_FIELD_START(ID_ISAR2_EL1, Mult, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR2_EL1, Mult)
> + IDREG_FIELD_START(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR2_EL1, MultiAccessInt)
> + IDREG_FIELD_START(ID_ISAR2_EL1, MemHint, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_END(ID_ISAR2_EL1, MemHint)
> + IDREG_FIELD_START(ID_ISAR2_EL1, LoadStore, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR2_EL1, LoadStore)
> IDREG_END(ID_ISAR2_EL1)
>
> IDREG_START(ID_ISAR3_EL1)
> - IDREG_FIELD(ID_ISAR3_EL1, T32EE, 28, 4)
> - IDREG_FIELD(ID_ISAR3_EL1, TrueNOP, 24, 4)
> - IDREG_FIELD(ID_ISAR3_EL1, T32Copy, 20, 4)
> - IDREG_FIELD(ID_ISAR3_EL1, TabBranch, 16, 4)
> - IDREG_FIELD(ID_ISAR3_EL1, SynchPrim, 12, 4)
> - IDREG_FIELD(ID_ISAR3_EL1, SVC, 8, 4)
> - IDREG_FIELD(ID_ISAR3_EL1, SIMD, 4, 4)
> - IDREG_FIELD(ID_ISAR3_EL1, Saturate, 0, 4)
> + IDREG_FIELD_START(ID_ISAR3_EL1, T32EE, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR3_EL1, T32EE)
> + IDREG_FIELD_START(ID_ISAR3_EL1, TrueNOP, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR3_EL1, TrueNOP)
> + IDREG_FIELD_START(ID_ISAR3_EL1, T32Copy, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR3_EL1, T32Copy)
> + IDREG_FIELD_START(ID_ISAR3_EL1, TabBranch, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR3_EL1, TabBranch)
> + IDREG_FIELD_START(ID_ISAR3_EL1, SynchPrim, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR3_EL1, SynchPrim)
> + IDREG_FIELD_START(ID_ISAR3_EL1, SVC, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR3_EL1, SVC)
> + IDREG_FIELD_START(ID_ISAR3_EL1, SIMD, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_ISAR3_EL1, SIMD)
> + IDREG_FIELD_START(ID_ISAR3_EL1, Saturate, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR3_EL1, Saturate)
> IDREG_END(ID_ISAR3_EL1)
>
> IDREG_START(ID_ISAR4_EL1)
> - IDREG_FIELD(ID_ISAR4_EL1, SWP_frac, 28, 4)
> - IDREG_FIELD(ID_ISAR4_EL1, PSR_M, 24, 4)
> - IDREG_FIELD(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
> - IDREG_FIELD(ID_ISAR4_EL1, Barrier, 16, 4)
> - IDREG_FIELD(ID_ISAR4_EL1, SMC, 12, 4)
> - IDREG_FIELD(ID_ISAR4_EL1, Writeback, 8, 4)
> - IDREG_FIELD(ID_ISAR4_EL1, WithShifts, 4, 4)
> - IDREG_FIELD(ID_ISAR4_EL1, Unpriv, 0, 4)
> + IDREG_FIELD_START(ID_ISAR4_EL1, SWP_frac, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR4_EL1, SWP_frac)
> + IDREG_FIELD_START(ID_ISAR4_EL1, PSR_M, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR4_EL1, PSR_M)
> + IDREG_FIELD_START(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_ISAR4_EL1, SynchPrim_frac)
> + IDREG_FIELD_START(ID_ISAR4_EL1, Barrier, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR4_EL1, Barrier)
> + IDREG_FIELD_START(ID_ISAR4_EL1, SMC, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR4_EL1, SMC)
> + IDREG_FIELD_START(ID_ISAR4_EL1, Writeback, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR4_EL1, Writeback)
> + IDREG_FIELD_START(ID_ISAR4_EL1, WithShifts, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_END(ID_ISAR4_EL1, WithShifts)
> + IDREG_FIELD_START(ID_ISAR4_EL1, Unpriv, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR4_EL1, Unpriv)
> IDREG_END(ID_ISAR4_EL1)
>
> IDREG_START(ID_ISAR5_EL1)
> - IDREG_FIELD(ID_ISAR5_EL1, VCMA, 28, 4)
> - IDREG_FIELD(ID_ISAR5_EL1, RDM, 24, 4)
> - IDREG_FIELD(ID_ISAR5_EL1, CRC32, 16, 4)
> - IDREG_FIELD(ID_ISAR5_EL1, SHA2, 12, 4)
> - IDREG_FIELD(ID_ISAR5_EL1, SHA1, 8, 4)
> - IDREG_FIELD(ID_ISAR5_EL1, AES, 4, 4)
> - IDREG_FIELD(ID_ISAR5_EL1, SEVL, 0, 4)
> + IDREG_FIELD_START(ID_ISAR5_EL1, VCMA, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR5_EL1, VCMA)
> + IDREG_FIELD_START(ID_ISAR5_EL1, RDM, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR5_EL1, RDM)
> + IDREG_FIELD_START(ID_ISAR5_EL1, CRC32, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR5_EL1, CRC32)
> + IDREG_FIELD_START(ID_ISAR5_EL1, SHA2, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR5_EL1, SHA2)
> + IDREG_FIELD_START(ID_ISAR5_EL1, SHA1, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR5_EL1, SHA1)
> + IDREG_FIELD_START(ID_ISAR5_EL1, AES, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR5_EL1, AES)
> + IDREG_FIELD_START(ID_ISAR5_EL1, SEVL, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR5_EL1, SEVL)
> IDREG_END(ID_ISAR5_EL1)
>
> IDREG_START(ID_ISAR6_EL1)
> - IDREG_FIELD(ID_ISAR6_EL1, CLRBHB, 28, 4)
> - IDREG_FIELD(ID_ISAR6_EL1, I8MM, 24, 4)
> - IDREG_FIELD(ID_ISAR6_EL1, BF16, 20, 4)
> - IDREG_FIELD(ID_ISAR6_EL1, SPECRES, 16, 4)
> - IDREG_FIELD(ID_ISAR6_EL1, SB, 12, 4)
> - IDREG_FIELD(ID_ISAR6_EL1, FHM, 8, 4)
> - IDREG_FIELD(ID_ISAR6_EL1, DP, 4, 4)
> - IDREG_FIELD(ID_ISAR6_EL1, JSCVT, 0, 4)
> + IDREG_FIELD_START(ID_ISAR6_EL1, CLRBHB, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR6_EL1, CLRBHB)
> + IDREG_FIELD_START(ID_ISAR6_EL1, I8MM, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR6_EL1, I8MM)
> + IDREG_FIELD_START(ID_ISAR6_EL1, BF16, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR6_EL1, BF16)
> + IDREG_FIELD_START(ID_ISAR6_EL1, SPECRES, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_ISAR6_EL1, SPECRES)
> + IDREG_FIELD_START(ID_ISAR6_EL1, SB, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR6_EL1, SB)
> + IDREG_FIELD_START(ID_ISAR6_EL1, FHM, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR6_EL1, FHM)
> + IDREG_FIELD_START(ID_ISAR6_EL1, DP, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR6_EL1, DP)
> + IDREG_FIELD_START(ID_ISAR6_EL1, JSCVT, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_ISAR6_EL1, JSCVT)
> IDREG_END(ID_ISAR6_EL1)
>
> IDREG_START(ID_MMFR0_EL1)
> - IDREG_FIELD(ID_MMFR0_EL1, InnerShr, 28, 4)
> - IDREG_FIELD(ID_MMFR0_EL1, FCSE, 24, 4)
> - IDREG_FIELD(ID_MMFR0_EL1, AuxReg, 20, 4)
> - IDREG_FIELD(ID_MMFR0_EL1, TCM, 16, 4)
> - IDREG_FIELD(ID_MMFR0_EL1, ShareLvl, 12, 4)
> - IDREG_FIELD(ID_MMFR0_EL1, OuterShr, 8, 4)
> - IDREG_FIELD(ID_MMFR0_EL1, PMSA, 4, 4)
> - IDREG_FIELD(ID_MMFR0_EL1, VMSA, 0, 4)
> + IDREG_FIELD_START(ID_MMFR0_EL1, InnerShr, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_MMFR0_EL1, InnerShr)
> + IDREG_FIELD_START(ID_MMFR0_EL1, FCSE, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR0_EL1, FCSE)
> + IDREG_FIELD_START(ID_MMFR0_EL1, AuxReg, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR0_EL1, AuxReg)
> + IDREG_FIELD_START(ID_MMFR0_EL1, TCM, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_MMFR0_EL1, TCM)
> + IDREG_FIELD_START(ID_MMFR0_EL1, ShareLvl, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR0_EL1, ShareLvl)
> + IDREG_FIELD_START(ID_MMFR0_EL1, OuterShr, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_MMFR0_EL1, OuterShr)
> + IDREG_FIELD_START(ID_MMFR0_EL1, PMSA, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_MMFR0_EL1, PMSA)
> + IDREG_FIELD_START(ID_MMFR0_EL1, VMSA, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_END(ID_MMFR0_EL1, VMSA)
> IDREG_END(ID_MMFR0_EL1)
>
> IDREG_START(ID_MMFR1_EL1)
> - IDREG_FIELD(ID_MMFR1_EL1, BPred, 28, 4)
> - IDREG_FIELD(ID_MMFR1_EL1, L1TstCln, 24, 4)
> - IDREG_FIELD(ID_MMFR1_EL1, L1Uni, 20, 4)
> - IDREG_FIELD(ID_MMFR1_EL1, L1Hvd, 16, 4)
> - IDREG_FIELD(ID_MMFR1_EL1, L1UniSW, 12, 4)
> - IDREG_FIELD(ID_MMFR1_EL1, L1HvdSW, 8, 4)
> - IDREG_FIELD(ID_MMFR1_EL1, L1UniVA, 4, 4)
> - IDREG_FIELD(ID_MMFR1_EL1, L1HvdVA, 0, 4)
> + IDREG_FIELD_START(ID_MMFR1_EL1, BPred, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_END(ID_MMFR1_EL1, BPred)
> + IDREG_FIELD_START(ID_MMFR1_EL1, L1TstCln, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR1_EL1, L1TstCln)
> + IDREG_FIELD_START(ID_MMFR1_EL1, L1Uni, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR1_EL1, L1Uni)
> + IDREG_FIELD_START(ID_MMFR1_EL1, L1Hvd, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_MMFR1_EL1, L1Hvd)
> + IDREG_FIELD_START(ID_MMFR1_EL1, L1UniSW, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_MMFR1_EL1, L1UniSW)
> + IDREG_FIELD_START(ID_MMFR1_EL1, L1HvdSW, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_MMFR1_EL1, L1HvdSW)
> + IDREG_FIELD_START(ID_MMFR1_EL1, L1UniVA, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR1_EL1, L1UniVA)
> + IDREG_FIELD_START(ID_MMFR1_EL1, L1HvdVA, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR1_EL1, L1HvdVA)
> IDREG_END(ID_MMFR1_EL1)
>
> IDREG_START(ID_MMFR2_EL1)
> - IDREG_FIELD(ID_MMFR2_EL1, HWAccFlg, 28, 4)
> - IDREG_FIELD(ID_MMFR2_EL1, WFIStall, 24, 4)
> - IDREG_FIELD(ID_MMFR2_EL1, MemBarr, 20, 4)
> - IDREG_FIELD(ID_MMFR2_EL1, UniTLB, 16, 4)
> + IDREG_FIELD_START(ID_MMFR2_EL1, HWAccFlg, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR2_EL1, HWAccFlg)
> + IDREG_FIELD_START(ID_MMFR2_EL1, WFIStall, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR2_EL1, WFIStall)
> + IDREG_FIELD_START(ID_MMFR2_EL1, MemBarr, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR2_EL1, MemBarr)
> + IDREG_FIELD_START(ID_MMFR2_EL1, UniTLB, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_END(ID_MMFR2_EL1, UniTLB)
> IDREG_FIELD(ID_MMFR2_EL1, HvdTLB, 12, 4)
> - IDREG_FIELD(ID_MMFR2_EL1, L1HvdRng, 8, 4)
> - IDREG_FIELD(ID_MMFR2_EL1, L1HvdBG, 4, 4)
> - IDREG_FIELD(ID_MMFR2_EL1, L1HvdFG, 0, 4)
> + IDREG_FIELD_START(ID_MMFR2_EL1, L1HvdRng, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR2_EL1, L1HvdRng)
> + IDREG_FIELD_START(ID_MMFR2_EL1, L1HvdBG, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR2_EL1, L1HvdBG)
> + IDREG_FIELD_START(ID_MMFR2_EL1, L1HvdFG, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR2_EL1, L1HvdFG)
> IDREG_END(ID_MMFR2_EL1)
>
> IDREG_START(ID_MMFR3_EL1)
> - IDREG_FIELD(ID_MMFR3_EL1, Supersec, 28, 4)
> - IDREG_FIELD(ID_MMFR3_EL1, CMemSz, 24, 4)
> - IDREG_FIELD(ID_MMFR3_EL1, CohWalk, 20, 4)
> - IDREG_FIELD(ID_MMFR3_EL1, PAN, 16, 4)
> - IDREG_FIELD(ID_MMFR3_EL1, MaintBcst, 12, 4)
> - IDREG_FIELD(ID_MMFR3_EL1, BPMaint, 8, 4)
> - IDREG_FIELD(ID_MMFR3_EL1, CMaintSW, 4, 4)
> - IDREG_FIELD(ID_MMFR3_EL1, CMaintVA, 0, 4)
> + IDREG_FIELD_START(ID_MMFR3_EL1, Supersec, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(ID_MMFR3_EL1, Supersec)
> + IDREG_FIELD_START(ID_MMFR3_EL1, CMemSz, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR3_EL1, CMemSz)
> + IDREG_FIELD_START(ID_MMFR3_EL1, CohWalk, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR3_EL1, CohWalk)
> + IDREG_FIELD_START(ID_MMFR3_EL1, PAN, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR3_EL1, PAN)
> + IDREG_FIELD_START(ID_MMFR3_EL1, MaintBcst, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR3_EL1, MaintBcst)
> + IDREG_FIELD_START(ID_MMFR3_EL1, BPMaint, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR3_EL1, BPMaint)
> + IDREG_FIELD_START(ID_MMFR3_EL1, CMaintSW, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR3_EL1, CMaintSW)
> + IDREG_FIELD_START(ID_MMFR3_EL1, CMaintVA, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR3_EL1, CMaintVA)
> IDREG_END(ID_MMFR3_EL1)
>
> IDREG_START(ID_MMFR4_EL1)
> - IDREG_FIELD(ID_MMFR4_EL1, EVT, 28, 4)
> - IDREG_FIELD(ID_MMFR4_EL1, CCIDX, 24, 4)
> - IDREG_FIELD(ID_MMFR4_EL1, LSM, 20, 4)
> - IDREG_FIELD(ID_MMFR4_EL1, HPDS, 16, 4)
> - IDREG_FIELD(ID_MMFR4_EL1, CnP, 12, 4)
> - IDREG_FIELD(ID_MMFR4_EL1, XNX, 8, 4)
> - IDREG_FIELD(ID_MMFR4_EL1, AC2, 4, 4)
> - IDREG_FIELD(ID_MMFR4_EL1, SpecSEI, 0, 4)
> + IDREG_FIELD_START(ID_MMFR4_EL1, EVT, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR4_EL1, EVT)
> + IDREG_FIELD_START(ID_MMFR4_EL1, CCIDX, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR4_EL1, CCIDX)
> + IDREG_FIELD_START(ID_MMFR4_EL1, LSM, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR4_EL1, LSM)
> + IDREG_FIELD_START(ID_MMFR4_EL1, HPDS, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_MMFR4_EL1, HPDS)
> + IDREG_FIELD_START(ID_MMFR4_EL1, CnP, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR4_EL1, CnP)
> + IDREG_FIELD_START(ID_MMFR4_EL1, XNX, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR4_EL1, XNX)
> + IDREG_FIELD_START(ID_MMFR4_EL1, AC2, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR4_EL1, AC2)
> + IDREG_FIELD_START(ID_MMFR4_EL1, SpecSEI, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR4_EL1, SpecSEI)
> IDREG_END(ID_MMFR4_EL1)
>
> IDREG_START(ID_MMFR5_EL1)
> - IDREG_FIELD(ID_MMFR5_EL1, nTLBPA, 4, 4)
> - IDREG_FIELD(ID_MMFR5_EL1, ETS, 0, 4)
> + IDREG_FIELD_START(ID_MMFR5_EL1, nTLBPA, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_MMFR5_EL1, nTLBPA)
> + IDREG_FIELD_START(ID_MMFR5_EL1, ETS, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_MMFR5_EL1, ETS)
> IDREG_END(ID_MMFR5_EL1)
>
> IDREG_START(ID_PFR0_EL1)
> - IDREG_FIELD(ID_PFR0_EL1, RAS, 28, 4)
> - IDREG_FIELD(ID_PFR0_EL1, DIT, 24, 4)
> - IDREG_FIELD(ID_PFR0_EL1, AMU, 20, 4)
> - IDREG_FIELD(ID_PFR0_EL1, CSV2, 16, 4)
> - IDREG_FIELD(ID_PFR0_EL1, State3, 12, 4)
> - IDREG_FIELD(ID_PFR0_EL1, State2, 8, 4)
> - IDREG_FIELD(ID_PFR0_EL1, State1, 4, 4)
> - IDREG_FIELD(ID_PFR0_EL1, State0, 0, 4)
> + IDREG_FIELD_START(ID_PFR0_EL1, RAS, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_PFR0_EL1, RAS)
> + IDREG_FIELD_START(ID_PFR0_EL1, DIT, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_PFR0_EL1, DIT)
> + IDREG_FIELD_START(ID_PFR0_EL1, AMU, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_PFR0_EL1, AMU)
> + IDREG_FIELD_START(ID_PFR0_EL1, CSV2, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_PFR0_EL1, CSV2)
> + IDREG_FIELD_START(ID_PFR0_EL1, State3, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_PFR0_EL1, State3)
> + IDREG_FIELD_START(ID_PFR0_EL1, State2, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_PFR0_EL1, State2)
> + IDREG_FIELD_START(ID_PFR0_EL1, State1, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_PFR0_EL1, State1)
> + IDREG_FIELD_START(ID_PFR0_EL1, State0, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_PFR0_EL1, State0)
> IDREG_END(ID_PFR0_EL1)
>
> IDREG_START(ID_PFR1_EL1)
> - IDREG_FIELD(ID_PFR1_EL1, GIC, 28, 4)
> - IDREG_FIELD(ID_PFR1_EL1, Virt_frac, 24, 4)
> - IDREG_FIELD(ID_PFR1_EL1, Sec_frac, 20, 4)
> - IDREG_FIELD(ID_PFR1_EL1, GenTimer, 16, 4)
> - IDREG_FIELD(ID_PFR1_EL1, Virtualization, 12, 4)
> - IDREG_FIELD(ID_PFR1_EL1, MProgMod, 8, 4)
> - IDREG_FIELD(ID_PFR1_EL1, Security, 4, 4)
> - IDREG_FIELD(ID_PFR1_EL1, ProgMod, 0, 4)
> + IDREG_FIELD_START(ID_PFR1_EL1, GIC, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(ID_PFR1_EL1, GIC)
> + IDREG_FIELD_START(ID_PFR1_EL1, Virt_frac, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_PFR1_EL1, Virt_frac)
> + IDREG_FIELD_START(ID_PFR1_EL1, Sec_frac, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_PFR1_EL1, Sec_frac)
> + IDREG_FIELD_START(ID_PFR1_EL1, GenTimer, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_PFR1_EL1, GenTimer)
> + IDREG_FIELD_START(ID_PFR1_EL1, Virtualization, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_PFR1_EL1, Virtualization)
> + IDREG_FIELD_START(ID_PFR1_EL1, MProgMod, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_PFR1_EL1, MProgMod)
> + IDREG_FIELD_START(ID_PFR1_EL1, Security, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(ID_PFR1_EL1, Security)
> + IDREG_FIELD_START(ID_PFR1_EL1, ProgMod, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_PFR1_EL1, ProgMod)
> IDREG_END(ID_PFR1_EL1)
>
> IDREG_START(ID_PFR2_EL1)
> - IDREG_FIELD(ID_PFR2_EL1, RAS_frac, 8, 4)
> - IDREG_FIELD(ID_PFR2_EL1, SSBS, 4, 4)
> - IDREG_FIELD(ID_PFR2_EL1, CSV3, 0, 4)
> + IDREG_FIELD_START(ID_PFR2_EL1, RAS_frac, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_PFR2_EL1, RAS_frac)
> + IDREG_FIELD_START(ID_PFR2_EL1, SSBS, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_PFR2_EL1, SSBS)
> + IDREG_FIELD_START(ID_PFR2_EL1, CSV3, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(ID_PFR2_EL1, CSV3)
> IDREG_END(ID_PFR2_EL1)
>
> IDREG_START(MIDR_EL1)
> - IDREG_FIELD(MIDR_EL1, Implementer, 24, 8)
> + IDREG_FIELD_START(MIDR_EL1, Implementer, 24, 8)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(65)
> + IDREG_FIELD_ARCH_VAL(66)
> + IDREG_FIELD_ARCH_VAL(67)
> + IDREG_FIELD_ARCH_VAL(68)
> + IDREG_FIELD_ARCH_VAL(70)
> + IDREG_FIELD_ARCH_VAL(73)
> + IDREG_FIELD_ARCH_VAL(77)
> + IDREG_FIELD_ARCH_VAL(78)
> + IDREG_FIELD_ARCH_VAL(80)
> + IDREG_FIELD_ARCH_VAL(81)
> + IDREG_FIELD_ARCH_VAL(86)
> + IDREG_FIELD_ARCH_VAL(105)
> + IDREG_FIELD_ARCH_VAL(192)
> + IDREG_FIELD_END(MIDR_EL1, Implementer)
> IDREG_FIELD(MIDR_EL1, Variant, 20, 4)
> - IDREG_FIELD(MIDR_EL1, Architecture, 16, 4)
> + IDREG_FIELD_START(MIDR_EL1, Architecture, 16, 4)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(MIDR_EL1, Architecture)
> IDREG_FIELD(MIDR_EL1, PartNum, 4, 12)
> IDREG_FIELD(MIDR_EL1, Revision, 0, 4)
> IDREG_END(MIDR_EL1)
>
> IDREG_START(MPIDR_EL1)
> IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
> - IDREG_FIELD(MPIDR_EL1, U, 30, 1)
> - IDREG_FIELD(MPIDR_EL1, MT, 24, 1)
> + IDREG_FIELD_START(MPIDR_EL1, U, 30, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MPIDR_EL1, U)
> + IDREG_FIELD_START(MPIDR_EL1, MT, 24, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MPIDR_EL1, MT)
> IDREG_FIELD(MPIDR_EL1, Aff2, 16, 8)
> IDREG_FIELD(MPIDR_EL1, Aff1, 8, 8)
> IDREG_FIELD(MPIDR_EL1, Aff0, 0, 8)
> IDREG_END(MPIDR_EL1)
>
> IDREG_START(MVFR0_EL1)
> - IDREG_FIELD(MVFR0_EL1, FPRound, 28, 4)
> - IDREG_FIELD(MVFR0_EL1, FPShVec, 24, 4)
> - IDREG_FIELD(MVFR0_EL1, FPSqrt, 20, 4)
> - IDREG_FIELD(MVFR0_EL1, FPDivide, 16, 4)
> - IDREG_FIELD(MVFR0_EL1, FPTrap, 12, 4)
> - IDREG_FIELD(MVFR0_EL1, FPDP, 8, 4)
> - IDREG_FIELD(MVFR0_EL1, FPSP, 4, 4)
> - IDREG_FIELD(MVFR0_EL1, SIMDReg, 0, 4)
> + IDREG_FIELD_START(MVFR0_EL1, FPRound, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR0_EL1, FPRound)
> + IDREG_FIELD_START(MVFR0_EL1, FPShVec, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR0_EL1, FPShVec)
> + IDREG_FIELD_START(MVFR0_EL1, FPSqrt, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR0_EL1, FPSqrt)
> + IDREG_FIELD_START(MVFR0_EL1, FPDivide, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR0_EL1, FPDivide)
> + IDREG_FIELD_START(MVFR0_EL1, FPTrap, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR0_EL1, FPTrap)
> + IDREG_FIELD_START(MVFR0_EL1, FPDP, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(MVFR0_EL1, FPDP)
> + IDREG_FIELD_START(MVFR0_EL1, FPSP, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(MVFR0_EL1, FPSP)
> + IDREG_FIELD_START(MVFR0_EL1, SIMDReg, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(MVFR0_EL1, SIMDReg)
> IDREG_END(MVFR0_EL1)
>
> IDREG_START(MVFR1_EL1)
> - IDREG_FIELD(MVFR1_EL1, SIMDFMAC, 28, 4)
> - IDREG_FIELD(MVFR1_EL1, FPHP, 24, 4)
> - IDREG_FIELD(MVFR1_EL1, SIMDHP, 20, 4)
> - IDREG_FIELD(MVFR1_EL1, SIMDSP, 16, 4)
> - IDREG_FIELD(MVFR1_EL1, SIMDInt, 12, 4)
> - IDREG_FIELD(MVFR1_EL1, SIMDLS, 8, 4)
> - IDREG_FIELD(MVFR1_EL1, FPDNaN, 4, 4)
> - IDREG_FIELD(MVFR1_EL1, FPFtZ, 0, 4)
> + IDREG_FIELD_START(MVFR1_EL1, SIMDFMAC, 28, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR1_EL1, SIMDFMAC)
> + IDREG_FIELD_START(MVFR1_EL1, FPHP, 24, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(MVFR1_EL1, FPHP)
> + IDREG_FIELD_START(MVFR1_EL1, SIMDHP, 20, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_END(MVFR1_EL1, SIMDHP)
> + IDREG_FIELD_START(MVFR1_EL1, SIMDSP, 16, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR1_EL1, SIMDSP)
> + IDREG_FIELD_START(MVFR1_EL1, SIMDInt, 12, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR1_EL1, SIMDInt)
> + IDREG_FIELD_START(MVFR1_EL1, SIMDLS, 8, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR1_EL1, SIMDLS)
> + IDREG_FIELD_START(MVFR1_EL1, FPDNaN, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR1_EL1, FPDNaN)
> + IDREG_FIELD_START(MVFR1_EL1, FPFtZ, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(MVFR1_EL1, FPFtZ)
> IDREG_END(MVFR1_EL1)
>
> IDREG_START(MVFR2_EL1)
> - IDREG_FIELD(MVFR2_EL1, FPMisc, 4, 4)
> - IDREG_FIELD(MVFR2_EL1, SIMDMisc, 0, 4)
> + IDREG_FIELD_START(MVFR2_EL1, FPMisc, 4, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_END(MVFR2_EL1, FPMisc)
> + IDREG_FIELD_START(MVFR2_EL1, SIMDMisc, 0, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(MVFR2_EL1, SIMDMisc)
> IDREG_END(MVFR2_EL1)
>
> IDREG_START(REVIDR_EL1)
> IDREG_END(REVIDR_EL1)
>
> IDREG_START(SMIDR_EL1)
> - IDREG_FIELD(SMIDR_EL1, NSMC, 56, 4)
> - IDREG_FIELD(SMIDR_EL1, HIP, 52, 4)
> + IDREG_FIELD_START(SMIDR_EL1, NSMC, 56, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(SMIDR_EL1, NSMC)
> + IDREG_FIELD_START(SMIDR_EL1, HIP, 52, 4)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_ARCH_VAL(4)
> + IDREG_FIELD_ARCH_VAL(5)
> + IDREG_FIELD_ARCH_VAL(6)
> + IDREG_FIELD_ARCH_VAL(7)
> + IDREG_FIELD_ARCH_VAL(8)
> + IDREG_FIELD_ARCH_VAL(9)
> + IDREG_FIELD_ARCH_VAL(10)
> + IDREG_FIELD_ARCH_VAL(11)
> + IDREG_FIELD_ARCH_VAL(12)
> + IDREG_FIELD_ARCH_VAL(13)
> + IDREG_FIELD_ARCH_VAL(14)
> + IDREG_FIELD_ARCH_VAL(15)
> + IDREG_FIELD_END(SMIDR_EL1, HIP)
> IDREG_FIELD(SMIDR_EL1, Affinity2, 32, 20)
> - IDREG_FIELD(SMIDR_EL1, Implementer, 24, 8)
> + IDREG_FIELD_START(SMIDR_EL1, Implementer, 24, 8)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(65)
> + IDREG_FIELD_ARCH_VAL(66)
> + IDREG_FIELD_ARCH_VAL(67)
> + IDREG_FIELD_ARCH_VAL(68)
> + IDREG_FIELD_ARCH_VAL(70)
> + IDREG_FIELD_ARCH_VAL(73)
> + IDREG_FIELD_ARCH_VAL(77)
> + IDREG_FIELD_ARCH_VAL(78)
> + IDREG_FIELD_ARCH_VAL(80)
> + IDREG_FIELD_ARCH_VAL(81)
> + IDREG_FIELD_ARCH_VAL(86)
> + IDREG_FIELD_ARCH_VAL(105)
> + IDREG_FIELD_ARCH_VAL(192)
> + IDREG_FIELD_END(SMIDR_EL1, Implementer)
> IDREG_FIELD(SMIDR_EL1, Revision, 16, 8)
> - IDREG_FIELD(SMIDR_EL1, SMPS, 15, 1)
> - IDREG_FIELD(SMIDR_EL1, SH, 13, 2)
> + IDREG_FIELD_START(SMIDR_EL1, SMPS, 15, 1)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_END(SMIDR_EL1, SMPS)
> + IDREG_FIELD_START(SMIDR_EL1, SH, 13, 2)
> + IDREG_FIELD_ARCH_VAL(0)
> + IDREG_FIELD_ARCH_VAL(1)
> + IDREG_FIELD_ARCH_VAL(2)
> + IDREG_FIELD_ARCH_VAL(3)
> + IDREG_FIELD_END(SMIDR_EL1, SH)
> IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
> IDREG_END(SMIDR_EL1)
>
> diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py
> index 6f5edb88d2..96f8aa2d64 100644
> --- a/scripts/update-aarch64-cpu-sysreg-properties.py
> +++ b/scripts/update-aarch64-cpu-sysreg-properties.py
> @@ -9,7 +9,12 @@
> #
> # IDREG_START(REG)
> # IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
> -# ...
> +# or for fields with enum values
> +# IDREG_FIELD_START(REG, FIELD, SHIFT, LENGTH)
> +# IDREG_FIELD_ARCH_VAL(VALUE)
> +# ../..
> +# IDREG_FIELD_END(REG, FIELD)
> +# ../..
> # IDREG_END(REG)
> #
> # Copyright (C) 2026 Red Hat, Inc.
> @@ -97,6 +102,59 @@ def collect_fields(item, bit_offset=0):
>
> return fields
>
> +def parse_raw_val(val_obj):
> + """Helper to unwrap int values from strings, ints, or nested dicts."""
> + if isinstance(val_obj, dict):
> + val_obj = val_obj.get("value")
> +
> + if val_obj is None:
> + return None
> +
> + raw_val_str = str(val_obj).strip().replace("'", "")
> + try:
> + return int(raw_val_str, 2)
> + except ValueError:
> + try:
> + return int(raw_val_str, 0)
> + except ValueError:
> + return None
> +
> +def extract_field_enums(field):
> + enums = []
> + if not isinstance(field, dict):
> + return enums
> +
> + value_obj = field.get("value")
> + if not isinstance(value_obj, dict):
> + return enums
> +
> + constraints = value_obj.get("constraints")
> + if not isinstance(constraints, dict):
> + return enums
> +
> + val_entries = constraints.get("values", [])
> + if not isinstance(val_entries, list):
> + return enums
> +
> + for val_entry in val_entries:
> + if not isinstance(val_entry, dict):
> + continue
> +
> + entry_type = val_entry.get("_type")
> + if entry_type == "Values.Value":
> + int_val = parse_raw_val(val_entry.get("value"))
> + if int_val is not None:
> + enums.append({'value': int_val})
> +
> + elif entry_type == "Values.ValueRange":
> + s = parse_raw_val(val_entry.get("start"))
> + e = parse_raw_val(val_entry.get("end"))
> +
> + if s is not None and e is not None:
> + for v in range(s, e + 1):
> + enums.append({'value': v})
Hi Eric,
I think here ConditionalValue type is missing, TGran*, PARange and VARange are missing some values.
Warm Regards,
Khushit
> +
> + return enums
>
> def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
> with open(raw_json_path, 'r') as f:
> @@ -128,16 +186,32 @@ def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
> # Only keep the fields with the highest MSB
> # needed fir CCSIDR_EL1
> if name not in unique_fields or msb > unique_fields[name]['msb']:
> - unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width}
> + # extract enum values if any
> + enums = extract_field_enums(val)
> + unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width, 'enums': enums}
>
> # Sort decreasing lsbs
> sorted_fields = sorted(unique_fields.items(),
> key=lambda x: x[1]['lsb'], reverse=True)
>
> for name, bits in sorted_fields:
> - line = (f" IDREG_FIELD({reg_name}, "
> - f"{name}, {bits['lsb']}, {bits['width']})\n")
> + enums_list = bits.get('enums', [])
> +
> + if enums_list:
> + line = (f" IDREG_FIELD_START({reg_name}, "
> + f"{name}, {bits['lsb']}, {bits['width']})\n")
> + else:
> + line = (f" IDREG_FIELD({reg_name}, "
> + f"{name}, {bits['lsb']}, {bits['width']})\n")
> final_output += line
> + # generate enum value or range if any
> + for enum_item in enums_list:
> + final_output += (f" IDREG_FIELD_ARCH_VAL({enum_item['value']})\n")
> +
> + if enums_list:
> + line = (f" IDREG_FIELD_END({reg_name}, {name})\n")
> + final_output += line
> +
> final_output += f"IDREG_END({reg_name})\n"
> final_output += "\n"
>
> @@ -147,7 +221,11 @@ def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
> f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
> f.write("/* IDREG_START(REG) */\n")
> f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n")
> + f.write("/* or for fields with enum values */\n")
> + f.write("/* IDREG_FIELD_START(REG, FIELD, SHIFT, LENGTH) */\n")
> + f.write("/* IDREG_FIELD_ARCH_VAL(VALUE) */\n")
> f.write("/* ... */\n")
> + f.write("/* IDREG_FIELD_END(REG, FIELD) */\n")
> f.write("/* IDREG_END(REG) */\n\n")
> f.write(final_output)
>
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 09/26] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields
2026-09-16 14:45 ` [PATCH v9 09/26] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields Eric Auger
@ 2026-09-25 12:16 ` Khushit Shah
0 siblings, 0 replies; 82+ messages in thread
From: Khushit Shah @ 2026-09-25 12:16 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> From: Shaju Abraham <shaju.abraham@nutanix.com>
>
> Include cpu-idregs.h.inc multiple times with different definitions for the
> X-macros. This will generate tables for all Arm64 ID registers and their
> fields. Additionally, initialize the tables with all architecturally defined
> values. These tables will be consumed by the property layer in future
> patches.
>
> Note:
> This triggers a minot checkpatch error but I prefer to keep the coma in
> the macro.
> ERROR: Macros with complex values should be enclosed in parenthesis
> +#define IDREG_FIELD_ARCH_VAL(v) (v),
>
> Co-authored-by: Khushit Shah <khushit.shah@nutanix.com>
> Signed-off-by: Khushit Shah <khushit.shah@nutanix.com>
> Signed-off-by: Shaju Abraham <shaju.abraham@nutanix.com>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>
LGTM, only minor nits.
> ---
> v7 -> v8
> Adaptation after removal of struct ArmIdRegArchVal
>
> v5 -> v6
> - restored support of enum values
> ---
> target/arm/cpu-idregs.c | 96 +++++++++++++++++++++++++++++++++++++++++
> target/arm/meson.build | 1 +
> 2 files changed, 97 insertions(+)
> create mode 100644 target/arm/cpu-idregs.c
>
> diff --git a/target/arm/cpu-idregs.c b/target/arm/cpu-idregs.c
> new file mode 100644
> index 0000000000..199d593153
> --- /dev/null
> +++ b/target/arm/cpu-idregs.c
> @@ -0,0 +1,96 @@
> +/*
> + * ARM ID register field table.
> + *
> + * Builds the per-id-register field descriptor arrays and the global
> + * arm_idregs[] table.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +#include "cpu.h"
> +#include "cpu-idregs.h"
> +
> +/*
> + * Generate an array of architecturely defined values for each field
> + * associated with enum values
> + */
> +
> +#define IDREG_START(reg)
> +#define IDREG_END(reg)
> +#define IDREG_FIELD(reg, field, shift, length)
> +#define IDREG_FIELD_START(reg, field, shift, length) \
> + static const uint64_t reg##_##field##_arch_vals[] = {
> +#define IDREG_FIELD_ARCH_VAL(v) (v),
> +#define IDREG_FIELD_END(reg, field) \
> + };
> +
> +#include "cpu-idregs.h.inc"
> +
> +#undef IDREG_START
> +#undef IDREG_END
> +#undef IDREG_FIELD
> +#undef IDREG_FIELD_START
> +#undef IDREG_FIELD_END
> +#undef IDREG_FIELD_ARCH_VAL
> +
> +/* generate an array of per-register ArmIdRegField[] descriptors */
> +
> +#define IDREG_START(reg) \
> + static ARM64SysRegField reg##_fields[] = {
> +
> +#define IDREG_END(reg) \
> + };
> +
> +#define IDREG_FIELD_START(reg, field, _shift, _length) \
> + { \
Some \ are tabbed, and others are not.
> + .name = #field, \
> + .index = reg##_IDX, \
> + .shift = (_shift), \
> + .length = (_length), \
> + .arch_vals = (uint64_t *)reg##_##field##_arch_vals, \
> + .arch_vals_count = ARRAY_SIZE(reg##_##field##_arch_vals), \
> + },
> +
> +#define IDREG_FIELD(reg, field, _shift, _length) \
> + { \
> + .name = #field, \
> + .index = reg##_IDX, \
> + .shift = (_shift), \
> + .length = (_length), \
> + },
> +
> +#define IDREG_FIELD_ARCH_VAL(v)
> +
> +#define IDREG_FIELD_END(reg, field)
> +
> +#include "cpu-idregs.h.inc"
> +
> +#undef IDREG_START
> +#undef IDREG_END
> +#undef IDREG_FIELD
> +#undef IDREG_FIELD_START
> +#undef IDREG_FIELD_END
> +#undef IDREG_FIELD_ARCH_VAL
> +
> +/* generate an array of top level ID registers */
> +
> +#define IDREG_END(reg)
> +#define IDREG_FIELD(reg, field, shift, length)
> +#define IDREG_FIELD_START(reg, field, shift, length)
> +#define IDREG_FIELD_ARCH_VAL(v)
> +#define IDREG_FIELD_END(reg, field)
> +
> +#define IDREG_START(reg) \
> + [reg##_IDX] = { \
> + .name = #reg, \
> + .index = reg##_IDX, \
> + .fields = reg##_fields, \
> + .fields_count = ARRAY_SIZE(reg##_fields), \
.writable_mask = 0ULL, \?
> + },
> +
> +ARM64SysReg arm64_id_regs[NUM_ID_IDX] = {
> +#include "cpu-idregs.h.inc"
> +};
> +
> diff --git a/target/arm/meson.build b/target/arm/meson.build
> index 0369f96b4c..384d90c530 100644
> --- a/target/arm/meson.build
> +++ b/target/arm/meson.build
> @@ -30,6 +30,7 @@ arm_common_user_system_ss.add(when: 'TARGET_AARCH64', if_true: files(
>
> arm_common_system_ss.add(files(
> 'arm-qmp-cmds.c',
> + 'cpu-idregs.c',
> ))
> arm_system_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c'))
> arm_system_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 10/26] target/arm/kvm: Retrieve writable ID reg map
2026-09-16 14:45 ` [PATCH v9 10/26] target/arm/kvm: Retrieve writable ID reg map Eric Auger
@ 2026-09-25 12:37 ` Khushit Shah
2026-09-28 12:34 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-25 12:37 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> From: Cornelia Huck <cohuck@redhat.com>
>
> Add an helper to retrieve the writable id reg bitmask.
s/an/a
> then retrieve the writable_map array and dispatch it in the writable_map
s/writable_map/writable_mask
> fields of arm64_id_regs[] elements.
s/fields/field
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>
> ---
>
> v7 -> v8
> - added kvm_enabled()
>
> v5 -> v6
> - use arm64_id_regs[].writable_map
> - squashed 2 commits (helper + user)
> - removed stub
> ---
> target/arm/kvm.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 61 insertions(+)
>
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index ed99be7fd8..c6eac41991 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -28,6 +28,7 @@
> #include "kvm_arm.h"
> #include "cpu.h"
> #include "cpu-sysregs.h"
> +#include "cpu-idregs.h"
> #include "trace.h"
> #include "internals.h"
> #include "hw/pci/pci.h"
> @@ -51,6 +52,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
> static bool cap_has_mp_state;
> static bool cap_has_inject_serror_esr;
> static bool cap_has_inject_ext_dabt;
> +static bool writable_map_dispatched;
>
> /**
> * ARMHostCPUFeatures: information about the host CPU (identified
> @@ -273,6 +275,21 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
> return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
> }
>
> +static int kvm_feature_idx_to_idregs_idx(int kidx)
> +{
> + int op1, crm, op2;
> + ARMSysRegs sysreg;
> +
> + op1 = kidx / 64;
> + if (op1 == 2) {
> + op1 = 3;
> + }
> + crm = (kidx % 64) / 8;
> + op2 = kidx % 8;
> + sysreg = ENCODE_ID_REG(3, op1, 0, crm, op2);
> + return get_sysreg_idx(sysreg);
> +}
> +
> static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> {
> /* Identify the feature bits corresponding to the host CPU, and
> @@ -480,9 +497,53 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> ahcf->features = features;
> }
>
> +static int kvm_arm_get_writable_id_regs(uint64_t *idregmap)
> +{
> + int cap_writable_id_regs;
> + struct reg_mask_range range = {
> + .range = KVM_ARM_FEATURE_ID_RANGE,
> + .reserved = {0},
> + .addr = (uint64_t)idregmap,
> + };
> +
> + cap_writable_id_regs =
> + kvm_check_extension(kvm_state, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES);
> +
> + if (!cap_writable_id_regs ||
> + !(cap_writable_id_regs & (1 << KVM_ARM_FEATURE_ID_RANGE))) {
> + return -ENOSYS;
> + }
> +
> + if (kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range)) {
> + return -errno;
> + }
I think just doing return kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range) is enough.
> + return 0;
> +}
> +
> void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
> {
> CPUARMState *env = &cpu->env;
> + uint64_t *writable_map;
> +
> + writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE);
> +
> + if (kvm_enabled() && !writable_map_dispatched &&
> + !kvm_arm_get_writable_id_regs(writable_map)) {
> + for (int i = 0; i < KVM_ARM_FEATURE_ID_RANGE_SIZE; i++) {
> + uint64_t mask = writable_map[i];
> +
> + if (mask) {
> + int idx = kvm_feature_idx_to_idregs_idx(i);
> +
> + if (idx < 0 || idx > ARRAY_SIZE(arm64_id_regs)) {
Bug: >=
Also, this condition will never be true, as get_sysreg_idx() asserts out on an unknown ID register. Which probably
should not happen.
> + continue;
> + }
> + arm64_id_regs[idx].writable_mask = mask;
> + }
> + }
> + writable_map_dispatched = true;
What is the need of writable_map_dispatched, why can’t we use arm_host_cpu_features.dtb_compatible as below?
Warm Regards,
Khushit
> + }
> + g_free(writable_map);
>
> if (!arm_host_cpu_features.dtb_compatible) {
> kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 11/26] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0
2026-09-16 14:45 ` [PATCH v9 11/26] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0 Eric Auger
@ 2026-09-25 12:46 ` Khushit Shah
0 siblings, 0 replies; 82+ messages in thread
From: Khushit Shah @ 2026-09-25 12:46 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> In KVM mode, virt_get_caches() currently gets a zero value for the
> CLIDR_EL1 register. This is due to the fact CLIDR is never read from
> host. This is a bug.
>
> Soon we will initialize all writable isar.idreg[] from host and this
> includes CLIDR_EL1. However we cannot directly fix the initialization,
> first because it would change the way the guest is exposed caches in
> DT/ACPI descriptions and because some host values would be rejected
> by the current QEMU code, expecially in the case host has a unified
> L1 cache which is currently not supported and triggers the following
> errod: "Unified type is not implemented at level 1" error.
>
> So this issue will be fixed separately.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com <mailto:khushit.shah@nutanix.com>>
> ---
> hw/arm/virt.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 0871a35e11..6c87ac133a 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -342,6 +342,10 @@ unsigned int virt_get_caches(const VirtMachineState *vms, CPUCoreCaches *caches)
> ARMISARegisters *isar = &armcpu->isar;
> uint32_t clidr = GET_IDREG(isar, CLIDR);
>
Nit: add a small comment here explaining this.
> + if (kvm_enabled()) {
> + clidr = 0;
> + }
> +
> for (int cache_level = 1; cache_level <= CLIDR_CTYPE_MAX_CACHE_LEVEL;
> cache_level++) {
> uint8_t ctype =
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 12/26] arm/kvm: Initialize isar.idregs[] with all writable host ID regs
2026-09-16 14:45 ` [PATCH v9 12/26] arm/kvm: Initialize isar.idregs[] with all writable host ID regs Eric Auger
@ 2026-09-25 13:27 ` Khushit Shah
2026-09-28 17:34 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-25 13:27 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> kvm_arm_get_host_cpu_features() already retrieves the values of some
> host id registers to analyze the available vcpu features.
>
> Eventually we want to be able to allow the user to change the value
> of writable ID reg fields. So we need to store the initial value of all
> writable ID regs into isar.idregs[].
>
> Introduce a new get_host_cpu_idregs() helper that populates isar.idregs[]
> and call it from kvm_arm_get_host_cpu_features.
>
> This patch has no impact on cpreg values. isar.idregs[] is only
> used as a temporary storage for register values to be updated in place
> later. Also it does not handle the writeback of isar.idregs[] into cpreg
> value list after user update. This will be handled separately.
>
> Note the host values are retrieved from the scratch vcpu initialized with
> all the available capabilities exposed by KVM, independently on the
> final choice made by the suer.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Hi Eric,
As we discussed, in v10, there will be an option to also read all the ID registers, not only writable.
> ---
> v8 -> v9:
> - improve the commit msg. Only initialize in this patch and move the
> write back to cpreg value list in a different patch.
> - Do not hack CLIDR here. The correct way to fix that temporarily is to
> do that in the machine instead.
>
> v7 -> v8
> - fix indent and added Khushit's R-b
>
> v6 -> v7
> - remove vcpu from prototypes (Khushit)
>
> v5 -> v6
> - do not check writable_map anymore
> ---
> target/arm/kvm.c | 43 ++++++++++++++++++++++++++++++++++++++++-
> target/arm/trace-events | 2 ++
> 2 files changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index c6eac41991..958b25e550 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -43,6 +43,7 @@
> #include "hw/acpi/ghes.h"
> #include "target/arm/gtimer.h"
> #include "migration/blocker.h"
> +#include "cpu-idregs.h"
>
> const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
> KVM_CAP_INFO(DEVICE_CTRL),
> @@ -290,7 +291,44 @@ static int kvm_feature_idx_to_idregs_idx(int kidx)
> return get_sysreg_idx(sysreg);
> }
>
> -static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> +/*
> + * get_host_cpu_idregs: Read all the writable ID reg host values
> + *
> + * Need to be called once the writable mask has been populated
> + * Note we may want to read all the known id regs but some of them are not
> + * writable and return an error, hence the choice of reading only those which
> + * are writable. Those are also readable!
> + */
> +static int get_host_cpu_idregs(int fd, ARMHostCPUFeatures *ahcf)
> +{
> + int err = 0;
> + int i;
> +
> + for (i = 0; i < NUM_ID_IDX; i++) {
> + ARM64SysReg *sysregdesc = &arm64_id_regs[i];
> + ARMSysRegs sysreg = id_register_sysreg[i];
> + uint64_t *reg;
> + int ret;
> +
> + if (!sysregdesc->writable_mask) {
> + continue;
> + }
> +
> + reg = &ahcf->isar.idregs[i];
> + ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg));
> + trace_get_host_cpu_idregs(sysregdesc->name, *reg);
> + if (ret) {
> + error_report("%s error reading value of host %s register (%m)",
> + __func__, sysregdesc->name);
> +
> + err = ret;
> + }
> + }
> + return err;
> +}
> +
> +static void
> +kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> {
> /* Identify the feature bits corresponding to the host CPU, and
> * fill out the ARMHostCPUClass fields accordingly. To do this
> @@ -376,6 +414,9 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */
> err = 0;
> } else {
> + /* Make sure all writable ID reg values are initialized */
> + err |= get_host_cpu_idregs(fd, ahcf);
> +
Perhaps if we read “all” the ID registers, we should be able to get rid of all the manual reads below.
> err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX);
> err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR2_EL1_IDX);
> err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX);
> diff --git a/target/arm/trace-events b/target/arm/trace-events
> index 8502fb3265..c25d2a1191 100644
> --- a/target/arm/trace-events
> +++ b/target/arm/trace-events
> @@ -13,6 +13,8 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
>
> # kvm.c
> kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
> +get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
> +kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%”PRIx64
^^ leaked into this commit.
Warm Regards,
Khushit
>
> # cpu.c
> arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter
2026-09-16 14:45 ` [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter Eric Auger
@ 2026-09-28 9:28 ` Khushit Shah
2026-09-28 11:49 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-28 9:28 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> When the setter is called, the final vcpu is not created yet.
> Applying the override on vcpu.isar initialized with the max scratch
> vcpu would not be correct because the final vcpu may have some features
> turned off (for instance virtualization) while the scratch vcpu
> features it. So we need to postpone the actual override until the
> final vcpu has been initialized.
>
> In terms of input value validation what can be done now is checking
> against field length and arch enum value if any.
>
> If this succeeds, the field value is added in the hash table to be
> written later on once the final vcpu has been created
>
> With regards to the getter, if the sysreg prop was set, we return the
> set value, otherwise, we return the value in cpu->isar.idregs[].
>
Hi Eric,
Please mention that the cpreg override happens in later commits.
Signed-off-by: Khushit Shah <khushit.shah@nutanix.com <mailto:khushit.shah@nutanix.com>>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> target/arm/cpu.h | 2 ++
> target/arm/cpu.c | 5 ++--
> target/arm/kvm.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 68 insertions(+), 4 deletions(-)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index e3f931dba2..9bbd42dd2b 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -952,6 +952,8 @@ struct ArchCPU {
> uint64_t *cpreg_vmstate_values;
> int32_t cpreg_vmstate_array_len;
>
> + GHashTable *sysreg_props;
> +
> DynamicGDBFeatureInfo dyn_sysreg_feature;
> DynamicGDBFeatureInfo dyn_svereg_feature;
> DynamicGDBFeatureInfo dyn_smereg_feature;
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 77aa78f00e..917f709cb4 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1236,8 +1236,8 @@ static void arm_cpu_initfn(Object *obj)
> {
> ARMCPU *cpu = ARM_CPU(obj);
>
> - cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
> - NULL, g_free);
> + cpu->cp_regs = g_hash_table_new(g_direct_hash, g_direct_equal);
> + cpu->sysreg_props = g_hash_table_new(g_direct_hash, g_direct_equal);
>
> QLIST_INIT(&cpu->pre_el_change_hooks);
> QLIST_INIT(&cpu->el_change_hooks);
> @@ -1725,6 +1725,7 @@ static void arm_cpu_finalizefn(Object *obj)
> ARMCPRegMigTolerance *t, *n;
>
> g_hash_table_destroy(cpu->cp_regs);
> + g_hash_table_destroy(cpu->sysreg_props);
>
> QLIST_FOREACH_SAFE(hook, &cpu->pre_el_change_hooks, node, next) {
> QLIST_REMOVE(hook, node);
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 341542279d..cdc3779321 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -340,18 +340,79 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
> return NULL;
> }
>
> +#define MAKE_IDREG_KEY(reg_idx, field_shift) \
> + (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
> +
Maybe, IDREG_FIELD_KEY()?
Warm Regards,
Khushit
> static void set_sysreg_prop(Object *obj, Visitor *v,
> const char *name, void *opaque,
> Error **errp)
> {
> - error_setg(errp, "%s setter not yet implemented", name);
> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
> + ARMCPU *cpu = ARM_CPU(obj);
> + int index = field->index;
> + int lower = field->shift;
> + int length = field->length;
> + uint64_t key, value;
> +
> + if (!visit_type_uint64(v, name, &value, errp)) {
> + return;
> + }
> +
> + if (length < 64 && value > ((1 << length) - 1)) {
> + error_setg(errp,
> + "idreg %s set value (0x%lx) exceeds length of field (%d)!",
> + name, value, length);
> + return;
> + }
> +
> + if (field->arch_vals) {
> + /* this field has some enum values */
> + for (int i = 0; i < field->arch_vals_count; i++) {
> + if (value == field->arch_vals[i]) {
> + goto valid;
> + }
> + }
> + error_setg(errp,
> + "idreg %s set value (0x%lx) does not match any "
> + "arch valid enum value", name, value);
> + return;
> + }
> +
> +valid:
> +
> + key = MAKE_IDREG_KEY(index, lower);
> + g_hash_table_insert(cpu->sysreg_props, GUINT_TO_POINTER(key),
> + GUINT_TO_POINTER(value));
> }
>
> static void get_sysreg_prop(Object *obj, Visitor *v,
> const char *name, void *opaque,
> Error **errp)
> {
> - error_setg(errp, "%s getter not yet implemented", name);
> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
> + ARMCPU *cpu = ARM_CPU(obj);
> + int index = field->index;
> + int lower = field->shift;
> + int length = field->length;
> + gpointer value_ptr;
> + uint64_t value;
> + uint64_t key = MAKE_IDREG_KEY(index, lower);
> + gboolean exists;
> +
> + exists = g_hash_table_lookup_extended(cpu->sysreg_props,
> + GUINT_TO_POINTER(key), NULL,
> + &value_ptr);
> + if (exists) {
> + value = GPOINTER_TO_UINT(value_ptr);
> + } else {
> + uint64_t mask = MAKE_64BIT_MASK(lower, length);
> + uint64_t *idregs = cpu->isar.idregs;
> +
> + value = (idregs[index] & mask) >> lower;
> + }
> +
> + visit_type_uint64(v, name, &value, errp);
> + trace_get_sysreg_prop(name, value);
> }
>
> /*
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu
2026-09-16 14:45 ` [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu Eric Auger
@ 2026-09-28 10:44 ` Khushit Shah
2026-09-30 15:08 ` Eric Auger
2026-09-30 15:11 ` Eric Auger
2026-09-30 7:54 ` Khushit Shah
1 sibling, 2 replies; 82+ messages in thread
From: Khushit Shah @ 2026-09-28 10:44 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> SYSREG prop settings were recorded in a hashtable but they
> are not yet injected on guest. Iterate over all set fields and
> apply the new value through KVM_SET_ONE_REG. The new field
> value overrides the current observable vcpu register value.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
With this, I suppose, what named models will do is directly write to
ID register state, As it also defines state which affects vCPU init flags also.
> ---
> target/arm/kvm.c | 65 +++++++++++++++++++++++++++++++++++++++++
> target/arm/trace-events | 1 +
> 2 files changed, 66 insertions(+)
>
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 3ec2618cc1..ddf320d0e6 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -343,6 +343,9 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>
> +#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
> +#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
> +
> static void set_sysreg_prop(Object *obj, Visitor *v,
> const char *name, void *opaque,
> Error **errp)
> @@ -2215,6 +2218,63 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
> return 0;
> }
>
> +static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
> +{
> + uint64_t *idregs = cpu->isar.idregs;
> + gpointer key_ptr, value_ptr;
> + CPUState *cs = CPU(cpu);
> + GHashTableIter iter;
> +
> + g_hash_table_iter_init(&iter, cpu->sysreg_props);
> +
> + while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
> + uint64_t key = (uint64_t)key_ptr;
> + uint64_t value = (uint64_t)value_ptr;
> + uint32_t reg_idx = KEY_TO_REG_IDX(key);
> + uint8_t lower = KEY_TO_SHIFT(key);
> + ARM64SysReg *reg = &arm64_id_regs[reg_idx];
> + struct kvm_one_reg kvm_reg;
> + uint64_t current, old, mask;
> + uint64_t kvm_idx;
> + ARM64SysRegField *field = get_field(lower, reg);
> + int length = field->length;
> + uint64_t oldfv;
> + int ret;
> +
> + mask = MAKE_64BIT_MASK(lower, length);
> + value = value << lower;
> +
> + old = idregs[reg_idx];
> +
> + kvm_idx = idregs_sysreg_to_kvm_reg(id_register_sysreg[reg_idx]);
> + ret = read_sys_reg64(cs->kvm_fd, ¤t, kvm_idx);
> + if (ret) {
> + error_setg(errp, "failed to read the current value of %s",
> + reg->name);
> + return ret;
> + }
> + oldfv = (current & mask) >> lower;
> +
> + idregs[reg_idx] = current & ~mask;
> + idregs[reg_idx] |= value;
> + kvm_reg.id = kvm_idx;
> + kvm_reg.addr = (uintptr_t)&idregs[reg_idx];
> +
We can ignore this if value == old value
> + ret = ioctl(cs->kvm_fd, KVM_SET_ONE_REG, &kvm_reg);
> + if (ret) {
> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s.%s "
> + "(previous is 0x%"PRIx64"): %m", idregs[reg_idx],
> + reg->name, field->name, oldfv);
> + return ret;
> + }
> +
> + trace_apply_sysreg_prop(reg->name, field->name, old, current,
> + mask, value, idregs[reg_idx]);
> + }
> + return 0;
> +}
> +
> int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
> {
> int ret;
> @@ -2315,6 +2375,11 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
> }
> cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>
> + ret = kvm_arm_apply_sysreg_props(cpu, errp);
> + if (ret) {
> + return ret;
> + }
> +
This should also happen on vCPU reset.
Overall, I like this approach as if the user does not provide any property overrides, it should behave the same as older builds.
Warm Regards,
Khushit
> return kvm_arm_init_cpreg_list(cpu);
> }
>
> diff --git a/target/arm/trace-events b/target/arm/trace-events
> index d72ad6b671..b4d2b45a7d 100644
> --- a/target/arm/trace-events
> +++ b/target/arm/trace-events
> @@ -18,6 +18,7 @@ kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint6
> decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
> get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
> set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
> +apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
>
> # cpu.c
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter
2026-09-28 9:28 ` Khushit Shah
@ 2026-09-28 11:49 ` Eric Auger
2026-09-28 13:20 ` Khushit Shah
0 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-28 11:49 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Khushit,
On 9/28/26 11:28 AM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> When the setter is called, the final vcpu is not created yet.
>> Applying the override on vcpu.isar initialized with the max scratch
>> vcpu would not be correct because the final vcpu may have some features
>> turned off (for instance virtualization) while the scratch vcpu
>> features it. So we need to postpone the actual override until the
>> final vcpu has been initialized.
>>
>> In terms of input value validation what can be done now is checking
>> against field length and arch enum value if any.
>>
>> If this succeeds, the field value is added in the hash table to be
>> written later on once the final vcpu has been created
>>
>> With regards to the getter, if the sysreg prop was set, we return the
>> set value, otherwise, we return the value in cpu->isar.idregs[].
>>
> Hi Eric,
>
> Please mention that the cpreg override happens in later commits.
sure
>
> Signed-off-by: Khushit Shah <khushit.shah@nutanix.com <mailto:khushit.shah@nutanix.com>>
May I ask why?
Besides we need to be cautious about the fact that people who has signed
off the patches cannot review them ...
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> ---
>> target/arm/cpu.h | 2 ++
>> target/arm/cpu.c | 5 ++--
>> target/arm/kvm.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++--
>> 3 files changed, 68 insertions(+), 4 deletions(-)
>>
>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>> index e3f931dba2..9bbd42dd2b 100644
>> --- a/target/arm/cpu.h
>> +++ b/target/arm/cpu.h
>> @@ -952,6 +952,8 @@ struct ArchCPU {
>> uint64_t *cpreg_vmstate_values;
>> int32_t cpreg_vmstate_array_len;
>>
>> + GHashTable *sysreg_props;
>> +
>> DynamicGDBFeatureInfo dyn_sysreg_feature;
>> DynamicGDBFeatureInfo dyn_svereg_feature;
>> DynamicGDBFeatureInfo dyn_smereg_feature;
>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>> index 77aa78f00e..917f709cb4 100644
>> --- a/target/arm/cpu.c
>> +++ b/target/arm/cpu.c
>> @@ -1236,8 +1236,8 @@ static void arm_cpu_initfn(Object *obj)
>> {
>> ARMCPU *cpu = ARM_CPU(obj);
>>
>> - cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
>> - NULL, g_free);
>> + cpu->cp_regs = g_hash_table_new(g_direct_hash, g_direct_equal);
>> + cpu->sysreg_props = g_hash_table_new(g_direct_hash, g_direct_equal);
>>
>> QLIST_INIT(&cpu->pre_el_change_hooks);
>> QLIST_INIT(&cpu->el_change_hooks);
>> @@ -1725,6 +1725,7 @@ static void arm_cpu_finalizefn(Object *obj)
>> ARMCPRegMigTolerance *t, *n;
>>
>> g_hash_table_destroy(cpu->cp_regs);
>> + g_hash_table_destroy(cpu->sysreg_props);
>>
>> QLIST_FOREACH_SAFE(hook, &cpu->pre_el_change_hooks, node, next) {
>> QLIST_REMOVE(hook, node);
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 341542279d..cdc3779321 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -340,18 +340,79 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>> return NULL;
>> }
>>
>> +#define MAKE_IDREG_KEY(reg_idx, field_shift) \
>> + (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>> +
> Maybe, IDREG_FIELD_KEY()?
Yes
Eric
>
> Warm Regards,
> Khushit
>> static void set_sysreg_prop(Object *obj, Visitor *v,
>> const char *name, void *opaque,
>> Error **errp)
>> {
>> - error_setg(errp, "%s setter not yet implemented", name);
>> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
>> + ARMCPU *cpu = ARM_CPU(obj);
>> + int index = field->index;
>> + int lower = field->shift;
>> + int length = field->length;
>> + uint64_t key, value;
>> +
>> + if (!visit_type_uint64(v, name, &value, errp)) {
>> + return;
>> + }
>> +
>> + if (length < 64 && value > ((1 << length) - 1)) {
>> + error_setg(errp,
>> + "idreg %s set value (0x%lx) exceeds length of field (%d)!",
>> + name, value, length);
>> + return;
>> + }
>> +
>> + if (field->arch_vals) {
>> + /* this field has some enum values */
>> + for (int i = 0; i < field->arch_vals_count; i++) {
>> + if (value == field->arch_vals[i]) {
>> + goto valid;
>> + }
>> + }
>> + error_setg(errp,
>> + "idreg %s set value (0x%lx) does not match any "
>> + "arch valid enum value", name, value);
>> + return;
>> + }
>> +
>> +valid:
>> +
>> + key = MAKE_IDREG_KEY(index, lower);
>> + g_hash_table_insert(cpu->sysreg_props, GUINT_TO_POINTER(key),
>> + GUINT_TO_POINTER(value));
>> }
>>
>> static void get_sysreg_prop(Object *obj, Visitor *v,
>> const char *name, void *opaque,
>> Error **errp)
>> {
>> - error_setg(errp, "%s getter not yet implemented", name);
>> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
>> + ARMCPU *cpu = ARM_CPU(obj);
>> + int index = field->index;
>> + int lower = field->shift;
>> + int length = field->length;
>> + gpointer value_ptr;
>> + uint64_t value;
>> + uint64_t key = MAKE_IDREG_KEY(index, lower);
>> + gboolean exists;
>> +
>> + exists = g_hash_table_lookup_extended(cpu->sysreg_props,
>> + GUINT_TO_POINTER(key), NULL,
>> + &value_ptr);
>> + if (exists) {
>> + value = GPOINTER_TO_UINT(value_ptr);
>> + } else {
>> + uint64_t mask = MAKE_64BIT_MASK(lower, length);
>> + uint64_t *idregs = cpu->isar.idregs;
>> +
>> + value = (idregs[index] & mask) >> lower;
>> + }
>> +
>> + visit_type_uint64(v, name, &value, errp);
>> + trace_get_sysreg_prop(name, value);
>> }
>>
>> /*
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 10/26] target/arm/kvm: Retrieve writable ID reg map
2026-09-25 12:37 ` Khushit Shah
@ 2026-09-28 12:34 ` Eric Auger
2026-09-28 13:23 ` Khushit Shah
0 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-28 12:34 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi,
On 9/25/26 2:37 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> From: Cornelia Huck <cohuck@redhat.com>
>>
>> Add an helper to retrieve the writable id reg bitmask.
> s/an/a
>> then retrieve the writable_map array and dispatch it in the writable_map
> s/writable_map/writable_mask
>> fields of arm64_id_regs[] elements.
> s/fields/field
fixed
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>
>> ---
>>
>> v7 -> v8
>> - added kvm_enabled()
>>
>> v5 -> v6
>> - use arm64_id_regs[].writable_map
>> - squashed 2 commits (helper + user)
>> - removed stub
>> ---
>> target/arm/kvm.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 61 insertions(+)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index ed99be7fd8..c6eac41991 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -28,6 +28,7 @@
>> #include "kvm_arm.h"
>> #include "cpu.h"
>> #include "cpu-sysregs.h"
>> +#include "cpu-idregs.h"
>> #include "trace.h"
>> #include "internals.h"
>> #include "hw/pci/pci.h"
>> @@ -51,6 +52,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>> static bool cap_has_mp_state;
>> static bool cap_has_inject_serror_esr;
>> static bool cap_has_inject_ext_dabt;
>> +static bool writable_map_dispatched;
>>
>> /**
>> * ARMHostCPUFeatures: information about the host CPU (identified
>> @@ -273,6 +275,21 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
>> return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
>> }
>>
>> +static int kvm_feature_idx_to_idregs_idx(int kidx)
>> +{
>> + int op1, crm, op2;
>> + ARMSysRegs sysreg;
>> +
>> + op1 = kidx / 64;
>> + if (op1 == 2) {
>> + op1 = 3;
>> + }
>> + crm = (kidx % 64) / 8;
>> + op2 = kidx % 8;
>> + sysreg = ENCODE_ID_REG(3, op1, 0, crm, op2);
>> + return get_sysreg_idx(sysreg);
>> +}
>> +
>> static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>> {
>> /* Identify the feature bits corresponding to the host CPU, and
>> @@ -480,9 +497,53 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>> ahcf->features = features;
>> }
>>
>> +static int kvm_arm_get_writable_id_regs(uint64_t *idregmap)
>> +{
>> + int cap_writable_id_regs;
>> + struct reg_mask_range range = {
>> + .range = KVM_ARM_FEATURE_ID_RANGE,
>> + .reserved = {0},
>> + .addr = (uint64_t)idregmap,
>> + };
>> +
>> + cap_writable_id_regs =
>> + kvm_check_extension(kvm_state, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES);
>> +
>> + if (!cap_writable_id_regs ||
>> + !(cap_writable_id_regs & (1 << KVM_ARM_FEATURE_ID_RANGE))) {
>> + return -ENOSYS;
>> + }
>> +
>> + if (kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range)) {
>> + return -errno;
>> + }
> I think just doing return kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range) is enough.
sure
>> + return 0;
>> +}
>> +
>> void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
>> {
>> CPUARMState *env = &cpu->env;
>> + uint64_t *writable_map;
>> +
>> + writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE);
>> +
>> + if (kvm_enabled() && !writable_map_dispatched &&
>> + !kvm_arm_get_writable_id_regs(writable_map)) {
>> + for (int i = 0; i < KVM_ARM_FEATURE_ID_RANGE_SIZE; i++) {
>> + uint64_t mask = writable_map[i];
>> +
>> + if (mask) {
>> + int idx = kvm_feature_idx_to_idregs_idx(i);
>> +
>> + if (idx < 0 || idx > ARRAY_SIZE(arm64_id_regs)) {
> Bug: >=
> Also, this condition will never be true, as get_sysreg_idx() asserts out on an unknown ID register. Which probably
> should not happen.
removed
>
>> + continue;
>> + }
>> + arm64_id_regs[idx].writable_mask = mask;
>> + }
>> + }
>> + writable_map_dispatched = true;
> What is the need of writable_map_dispatched, why can’t we use arm_host_cpu_features.dtb_compatible as below?
Using a dtb related condition to decide whether we shall do the writable
mask dispatch looks far-fetched to me, although it would effectively work.
I would rather keep it as it and wait for other comments if any.
Thanks
Eric
>
> Warm Regards,
> Khushit
>> + }
>> + g_free(writable_map);
>>
>> if (!arm_host_cpu_features.dtb_compatible) {
>> kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props
2026-09-16 14:45 ` [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props Eric Auger
@ 2026-09-28 12:53 ` Khushit Shah
2026-09-29 12:13 ` Eric Auger
2026-09-30 7:34 ` Khushit Shah
1 sibling, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-28 12:53 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Eric,
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Since legacy composite options (such as SVE, virtualization, ...)
> and new SYSREG props coexist, add some basic consistency checks.
>
> Those checks are performed both in kvm_arch_init_vcpu() before
> applying the SYSREG props at the end of the initialization chain.
Where else?
> Some ID reg fields corresponding to legacy composite option scope
> are not writable. In that case we just check that the field has
> not become writable.
I don’t understand where the above happens in code.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> target/arm/kvm.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 105 insertions(+)
>
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index ddf320d0e6..f52c03745e 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -340,6 +340,107 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
> return NULL;
> }
>
> +
> +/**
> + * kvm_arm_vcpu_validate_sysreg:
> + *
> + * Validate a SYSREG field value is consistent with legacy composite options
> + * Some checks are not implemented because the corresponding sysreg field
> + * is not currently writable. In that case we make sure the field has not
> + * become writable, which would mean the user had the capability to set the
> + * corresponding property.
> + *
> + * return true if consistent. false if it is not, along with an error handle
> + */
> +static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
> + uint64_t value, Error **errp)
> +{
> + const char *fieldname = field->name;
> + ARM64SysReg *sysregdesc = &arm64_id_regs[field->index];
> + const char *regname = sysregdesc->name;
> + g_autofree char *propname = g_strdup_printf("SYSREG_%s_%s", regname, fieldname);
I don’t see a reason to build property name here.
> +
> + /* virtualization */
> + if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) {
> + /* consistency with machine virtualization property */
> + if (cpu->has_el2 && value == 0) {
> + error_setg(errp,
> + "Inconsistent -machine virtualization=on and "
> + "%s=0", propname);
> + return false;
> + } else if (!cpu->has_el2 && value > 0) {
> + error_setg(errp,
> + "Inconsistent -machine virtualization=off and "
> + "%s > 0", propname);
> + return false;
> + }
> + /* secure */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL3") && value > 0) {
> + /* consistency with machine secure property */
> + error_setg(errp, "%s is set but qemu is not ready to support it",
> + propname);
> + return false;
> + /* MTE */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR1_EL1_MTE")) {
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + /* SVE */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_SVE")) {
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ZFR0_EL1_SVEver")) {
> + if (cpu_isar_feature(aa64_sve, cpu) && value == 0) {
> + error_setg(errp, "sve is set but %s is set to 0", propname);
> + return false;
This is actually an valid configuration.
> + } else if (!cpu_isar_feature(aa64_sve, cpu) && value > 0) {
> + error_setg(errp, "sve is not set but %s is greater than 0",
> + propname);
> + return false;
> + }
> + /* PAUTH */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_APA")) {
> + /* PAUTH QARMA5 address authentification */
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_API")) {
> + /* PAUTH Impl Defined address authentification */
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPA")) {
> + /* QARMA5 generic code authentification */
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPI")) {
> + /* QARMA5 generic code authentification */
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + /* PMU */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64DFR0_EL1_PMUVer")) {
> + if (cpu->has_pmu && value == 0) {
> + error_setg(errp, "%s is 0 whereas pmu is set", propname);
> + return false;
> + } else if (!cpu->has_pmu && value) {
> + error_setg(errp, "%s is non null whereas pmu is unset", propname);
> + return false;
> + }
> + /* aarch64 false */
> + } else if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
> + if ((!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL0") ||
> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL1") ||
> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) && value < 2)
> + error_setg(errp, "%s is < 2 while aarch64 is set to off",
> + propname);
> + return false;
return should be covered in braces.
Warm Regards,
Khushit
> + }
> + return true;
> +}
> +
> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>
> @@ -2241,6 +2342,10 @@ static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
> uint64_t oldfv;
> int ret;
>
> + if (!kvm_arm_vcpu_validate_sysreg(cpu, field, value, errp)) {
> + return -1;
> + }
> +
> mask = MAKE_64BIT_MASK(lower, length);
> value = value << lower;
>
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter
2026-09-28 11:49 ` Eric Auger
@ 2026-09-28 13:20 ` Khushit Shah
2026-09-28 13:32 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-28 13:20 UTC (permalink / raw)
To: eric.auger@redhat.com
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 28 Sep 2026, at 5:19 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Hi Khushit,
>
> On 9/28/26 11:28 AM, Khushit Shah wrote:
>>
>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>
>>> !-------------------------------------------------------------------|
>>> CAUTION: External Email
>>>
>>> |-------------------------------------------------------------------!
>>>
>>> When the setter is called, the final vcpu is not created yet.
>>> Applying the override on vcpu.isar initialized with the max scratch
>>> vcpu would not be correct because the final vcpu may have some features
>>> turned off (for instance virtualization) while the scratch vcpu
>>> features it. So we need to postpone the actual override until the
>>> final vcpu has been initialized.
>>>
>>> In terms of input value validation what can be done now is checking
>>> against field length and arch enum value if any.
>>>
>>> If this succeeds, the field value is added in the hash table to be
>>> written later on once the final vcpu has been created
>>>
>>> With regards to the getter, if the sysreg prop was set, we return the
>>> set value, otherwise, we return the value in cpu->isar.idregs[].
>>>
>> Hi Eric,
>>
>> Please mention that the cpreg override happens in later commits.
> sure
>>
>> Signed-off-by: Khushit Shah <khushit.shah@nutanix.com <mailto:khushit.shah@nutanix.com>>
> May I ask why?
>
> Besides we need to be cautious about the fact that people who has signed
> off the patches cannot review them ...
Ohh sorry, I meant
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com <mailto:khushit.shah@nutanix.com>>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>> ---
>>> target/arm/cpu.h | 2 ++
>>> target/arm/cpu.c | 5 ++--
>>> target/arm/kvm.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++--
>>> 3 files changed, 68 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>>> index e3f931dba2..9bbd42dd2b 100644
>>> --- a/target/arm/cpu.h
>>> +++ b/target/arm/cpu.h
>>> @@ -952,6 +952,8 @@ struct ArchCPU {
>>> uint64_t *cpreg_vmstate_values;
>>> int32_t cpreg_vmstate_array_len;
>>>
>>> + GHashTable *sysreg_props;
>>> +
>>> DynamicGDBFeatureInfo dyn_sysreg_feature;
>>> DynamicGDBFeatureInfo dyn_svereg_feature;
>>> DynamicGDBFeatureInfo dyn_smereg_feature;
>>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>>> index 77aa78f00e..917f709cb4 100644
>>> --- a/target/arm/cpu.c
>>> +++ b/target/arm/cpu.c
>>> @@ -1236,8 +1236,8 @@ static void arm_cpu_initfn(Object *obj)
>>> {
>>> ARMCPU *cpu = ARM_CPU(obj);
>>>
>>> - cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
>>> - NULL, g_free);
>>> + cpu->cp_regs = g_hash_table_new(g_direct_hash, g_direct_equal);
>>> + cpu->sysreg_props = g_hash_table_new(g_direct_hash, g_direct_equal);
>>>
>>> QLIST_INIT(&cpu->pre_el_change_hooks);
>>> QLIST_INIT(&cpu->el_change_hooks);
>>> @@ -1725,6 +1725,7 @@ static void arm_cpu_finalizefn(Object *obj)
>>> ARMCPRegMigTolerance *t, *n;
>>>
>>> g_hash_table_destroy(cpu->cp_regs);
>>> + g_hash_table_destroy(cpu->sysreg_props);
>>>
>>> QLIST_FOREACH_SAFE(hook, &cpu->pre_el_change_hooks, node, next) {
>>> QLIST_REMOVE(hook, node);
>>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>>> index 341542279d..cdc3779321 100644
>>> --- a/target/arm/kvm.c
>>> +++ b/target/arm/kvm.c
>>> @@ -340,18 +340,79 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>>> return NULL;
>>> }
>>>
>>> +#define MAKE_IDREG_KEY(reg_idx, field_shift) \
>>> + (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>> +
>> Maybe, IDREG_FIELD_KEY()?
> Yes
>
> Eric
>>
>> Warm Regards,
>> Khushit
>>> static void set_sysreg_prop(Object *obj, Visitor *v,
>>> const char *name, void *opaque,
>>> Error **errp)
>>> {
>>> - error_setg(errp, "%s setter not yet implemented", name);
>>> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
>>> + ARMCPU *cpu = ARM_CPU(obj);
>>> + int index = field->index;
>>> + int lower = field->shift;
>>> + int length = field->length;
>>> + uint64_t key, value;
>>> +
>>> + if (!visit_type_uint64(v, name, &value, errp)) {
>>> + return;
>>> + }
>>> +
>>> + if (length < 64 && value > ((1 << length) - 1)) {
>>> + error_setg(errp,
>>> + "idreg %s set value (0x%lx) exceeds length of field (%d)!",
>>> + name, value, length);
>>> + return;
>>> + }
>>> +
>>> + if (field->arch_vals) {
>>> + /* this field has some enum values */
>>> + for (int i = 0; i < field->arch_vals_count; i++) {
>>> + if (value == field->arch_vals[i]) {
>>> + goto valid;
>>> + }
>>> + }
>>> + error_setg(errp,
>>> + "idreg %s set value (0x%lx) does not match any "
>>> + "arch valid enum value", name, value);
>>> + return;
>>> + }
>>> +
>>> +valid:
>>> +
>>> + key = MAKE_IDREG_KEY(index, lower);
>>> + g_hash_table_insert(cpu->sysreg_props, GUINT_TO_POINTER(key),
>>> + GUINT_TO_POINTER(value));
>>> }
>>>
>>> static void get_sysreg_prop(Object *obj, Visitor *v,
>>> const char *name, void *opaque,
>>> Error **errp)
>>> {
>>> - error_setg(errp, "%s getter not yet implemented", name);
>>> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
>>> + ARMCPU *cpu = ARM_CPU(obj);
>>> + int index = field->index;
>>> + int lower = field->shift;
>>> + int length = field->length;
>>> + gpointer value_ptr;
>>> + uint64_t value;
>>> + uint64_t key = MAKE_IDREG_KEY(index, lower);
>>> + gboolean exists;
>>> +
>>> + exists = g_hash_table_lookup_extended(cpu->sysreg_props,
>>> + GUINT_TO_POINTER(key), NULL,
>>> + &value_ptr);
>>> + if (exists) {
>>> + value = GPOINTER_TO_UINT(value_ptr);
>>> + } else {
>>> + uint64_t mask = MAKE_64BIT_MASK(lower, length);
>>> + uint64_t *idregs = cpu->isar.idregs;
>>> +
>>> + value = (idregs[index] & mask) >> lower;
>>> + }
>>> +
>>> + visit_type_uint64(v, name, &value, errp);
>>> + trace_get_sysreg_prop(name, value);
>>> }
>>>
>>> /*
>>> --
>>> 2.53.0
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 10/26] target/arm/kvm: Retrieve writable ID reg map
2026-09-28 12:34 ` Eric Auger
@ 2026-09-28 13:23 ` Khushit Shah
0 siblings, 0 replies; 82+ messages in thread
From: Khushit Shah @ 2026-09-28 13:23 UTC (permalink / raw)
To: eric.auger@redhat.com
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 28 Sep 2026, at 6:04 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> Using a dtb related condition to decide whether we shall do the writable
> mask dispatch looks far-fetched to me, although it would effectively work.
>
> I would rather keep it as it and wait for other comments if any.
>
Cool, I suggested because it is currently used to gate kvm_arm_get_host_cpu_features(&arm_host_cpu_features) just a few lines down.
Warm Regards,
Khushit
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 18/26] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
2026-09-16 14:45 ` [PATCH v9 18/26] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger
@ 2026-09-28 13:26 ` Khushit Shah
2026-09-28 13:35 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-28 13:26 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> If the host supports KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES and
> KVM_ARM_GET_REG_WRITABLE_MASKS ioctl successfully retrieved the mask
> of writable fields for all ID regs, expose uint64 SYSREG properties
> for all the writable ID reg fields exposed by the host kernel which
> can be matched in target/arm/cpu-idregs.h.inc.
>
> Properties are named SYSREG_<REG>_<FIELD> with REG and FIELD
> being those used ARCHMRS Registers.json.
>
> When such properties are set, they override the default field value
> retrieved from the host and reinjected into KVM. Then the actual value
> being applied at KVM depends on the register, ie. it can be sanitized.
> In case the field value is rejected by KVM, the vpcu init fails.
>
> Anyway there is a first attempt to write back this value into KVM.
>
> Then legacy CPU options (virtualization, secure, ...) can still
> override the previous value. So low level IDREG field properties
> apply before the legacy ones.
>
> An example of invocation is:
> -cpu host,SYSREG_ID_AA64MMFR0_EL1_ECV=0x0
> which sets ECV field of ID_AA64MMFR0_EL1 to 0 (enhanced counter
> virtualization).
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> Reviewed-by: Sebastian Ott <sebott@redhat.com>
>
Hi Eric,
The commit message needs an update :)
> ---
> v5 -> v6:
> - do not check writable_map anymore
>
> v4 -> v5:
> - get rid of ret local variable, dynamically allocate and free writable_map
> here
> ---
> target/arm/cpu64.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 4e8c472530..e04062e848 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -37,6 +37,7 @@
> #include "hw/core/qdev-properties.h"
> #include "internals.h"
> #include "cpu-features.h"
> +#include "cpu-idregs.h"
>
> /* convert between <register>_IDX and SYS_<register> */
> #define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
> @@ -807,6 +808,10 @@ void aarch64_host_initfn(Object *obj)
> kvm_arm_set_cpreg_mig_tolerances(cpu);
> kvm_arm_set_cpu_features_from_host(cpu);
> aarch64_add_sve_properties(obj);
> +
> + /* generate SYSREG properties according to writable masks */
> + kvm_arm_expose_idreg_properties(cpu, arm64_id_regs);
> +
> #elif defined(CONFIG_HVF)
> hvf_arm_set_cpu_features_from_host(cpu);
> #elif defined(CONFIG_WHPX)
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter
2026-09-28 13:20 ` Khushit Shah
@ 2026-09-28 13:32 ` Eric Auger
2026-09-28 13:42 ` Khushit Shah
0 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-28 13:32 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/28/26 3:20 PM, Khushit Shah wrote:
>
>> On 28 Sep 2026, at 5:19 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Hi Khushit,
>>
>> On 9/28/26 11:28 AM, Khushit Shah wrote:
>>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>>
>>>> !-------------------------------------------------------------------|
>>>> CAUTION: External Email
>>>>
>>>> |-------------------------------------------------------------------!
>>>>
>>>> When the setter is called, the final vcpu is not created yet.
>>>> Applying the override on vcpu.isar initialized with the max scratch
>>>> vcpu would not be correct because the final vcpu may have some features
>>>> turned off (for instance virtualization) while the scratch vcpu
>>>> features it. So we need to postpone the actual override until the
>>>> final vcpu has been initialized.
>>>>
>>>> In terms of input value validation what can be done now is checking
>>>> against field length and arch enum value if any.
>>>>
>>>> If this succeeds, the field value is added in the hash table to be
>>>> written later on once the final vcpu has been created
>>>>
>>>> With regards to the getter, if the sysreg prop was set, we return the
>>>> set value, otherwise, we return the value in cpu->isar.idregs[].
>>>>
>>> Hi Eric,
>>>
>>> Please mention that the cpreg override happens in later commits.
>> sure
>>> Signed-off-by: Khushit Shah <khushit.shah@nutanix.com <mailto:khushit.shah@nutanix.com>>
>> May I ask why?
>>
>> Besides we need to be cautious about the fact that people who has signed
>> off the patches cannot review them ...
> Ohh sorry, I meant
>
> Reviewed-by: Khushit Shah <khushit.shah@nutanix.com <mailto:khushit.shah@nutanix.com>>
ah ok thanks.
By the way do you mean:
Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
I don't know if yours is a correct R-b form but maybe?
Eric
>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>> ---
>>>> target/arm/cpu.h | 2 ++
>>>> target/arm/cpu.c | 5 ++--
>>>> target/arm/kvm.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++--
>>>> 3 files changed, 68 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>>>> index e3f931dba2..9bbd42dd2b 100644
>>>> --- a/target/arm/cpu.h
>>>> +++ b/target/arm/cpu.h
>>>> @@ -952,6 +952,8 @@ struct ArchCPU {
>>>> uint64_t *cpreg_vmstate_values;
>>>> int32_t cpreg_vmstate_array_len;
>>>>
>>>> + GHashTable *sysreg_props;
>>>> +
>>>> DynamicGDBFeatureInfo dyn_sysreg_feature;
>>>> DynamicGDBFeatureInfo dyn_svereg_feature;
>>>> DynamicGDBFeatureInfo dyn_smereg_feature;
>>>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>>>> index 77aa78f00e..917f709cb4 100644
>>>> --- a/target/arm/cpu.c
>>>> +++ b/target/arm/cpu.c
>>>> @@ -1236,8 +1236,8 @@ static void arm_cpu_initfn(Object *obj)
>>>> {
>>>> ARMCPU *cpu = ARM_CPU(obj);
>>>>
>>>> - cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
>>>> - NULL, g_free);
>>>> + cpu->cp_regs = g_hash_table_new(g_direct_hash, g_direct_equal);
>>>> + cpu->sysreg_props = g_hash_table_new(g_direct_hash, g_direct_equal);
>>>>
>>>> QLIST_INIT(&cpu->pre_el_change_hooks);
>>>> QLIST_INIT(&cpu->el_change_hooks);
>>>> @@ -1725,6 +1725,7 @@ static void arm_cpu_finalizefn(Object *obj)
>>>> ARMCPRegMigTolerance *t, *n;
>>>>
>>>> g_hash_table_destroy(cpu->cp_regs);
>>>> + g_hash_table_destroy(cpu->sysreg_props);
>>>>
>>>> QLIST_FOREACH_SAFE(hook, &cpu->pre_el_change_hooks, node, next) {
>>>> QLIST_REMOVE(hook, node);
>>>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>>>> index 341542279d..cdc3779321 100644
>>>> --- a/target/arm/kvm.c
>>>> +++ b/target/arm/kvm.c
>>>> @@ -340,18 +340,79 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>>>> return NULL;
>>>> }
>>>>
>>>> +#define MAKE_IDREG_KEY(reg_idx, field_shift) \
>>>> + (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>>> +
>>> Maybe, IDREG_FIELD_KEY()?
>> Yes
>>
>> Eric
>>> Warm Regards,
>>> Khushit
>>>> static void set_sysreg_prop(Object *obj, Visitor *v,
>>>> const char *name, void *opaque,
>>>> Error **errp)
>>>> {
>>>> - error_setg(errp, "%s setter not yet implemented", name);
>>>> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
>>>> + ARMCPU *cpu = ARM_CPU(obj);
>>>> + int index = field->index;
>>>> + int lower = field->shift;
>>>> + int length = field->length;
>>>> + uint64_t key, value;
>>>> +
>>>> + if (!visit_type_uint64(v, name, &value, errp)) {
>>>> + return;
>>>> + }
>>>> +
>>>> + if (length < 64 && value > ((1 << length) - 1)) {
>>>> + error_setg(errp,
>>>> + "idreg %s set value (0x%lx) exceeds length of field (%d)!",
>>>> + name, value, length);
>>>> + return;
>>>> + }
>>>> +
>>>> + if (field->arch_vals) {
>>>> + /* this field has some enum values */
>>>> + for (int i = 0; i < field->arch_vals_count; i++) {
>>>> + if (value == field->arch_vals[i]) {
>>>> + goto valid;
>>>> + }
>>>> + }
>>>> + error_setg(errp,
>>>> + "idreg %s set value (0x%lx) does not match any "
>>>> + "arch valid enum value", name, value);
>>>> + return;
>>>> + }
>>>> +
>>>> +valid:
>>>> +
>>>> + key = MAKE_IDREG_KEY(index, lower);
>>>> + g_hash_table_insert(cpu->sysreg_props, GUINT_TO_POINTER(key),
>>>> + GUINT_TO_POINTER(value));
>>>> }
>>>>
>>>> static void get_sysreg_prop(Object *obj, Visitor *v,
>>>> const char *name, void *opaque,
>>>> Error **errp)
>>>> {
>>>> - error_setg(errp, "%s getter not yet implemented", name);
>>>> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
>>>> + ARMCPU *cpu = ARM_CPU(obj);
>>>> + int index = field->index;
>>>> + int lower = field->shift;
>>>> + int length = field->length;
>>>> + gpointer value_ptr;
>>>> + uint64_t value;
>>>> + uint64_t key = MAKE_IDREG_KEY(index, lower);
>>>> + gboolean exists;
>>>> +
>>>> + exists = g_hash_table_lookup_extended(cpu->sysreg_props,
>>>> + GUINT_TO_POINTER(key), NULL,
>>>> + &value_ptr);
>>>> + if (exists) {
>>>> + value = GPOINTER_TO_UINT(value_ptr);
>>>> + } else {
>>>> + uint64_t mask = MAKE_64BIT_MASK(lower, length);
>>>> + uint64_t *idregs = cpu->isar.idregs;
>>>> +
>>>> + value = (idregs[index] & mask) >> lower;
>>>> + }
>>>> +
>>>> + visit_type_uint64(v, name, &value, errp);
>>>> + trace_get_sysreg_prop(name, value);
>>>> }
>>>>
>>>> /*
>>>> --
>>>> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 21/26] target/arm/kvm: add helper to test SYSREG props against a scratch vcpu
2026-09-16 14:45 ` [PATCH v9 21/26] target/arm/kvm: add helper to test SYSREG props against a scratch vcpu Eric Auger
@ 2026-09-28 13:34 ` Khushit Shah
2026-09-30 17:43 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-28 13:34 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Add kvm_idreg_write_scratch_vcpu helper that will be used
> by qmp_query_cpu_model_expansion code to test SYSREG settings
> against a scratch vcpu. Indeed when the expansion code is called
> the actual vcpu has not been initialized so we use a scratch vcpu.
> This latter has been initialized with features taken from
> legacy compositive options (EL2, SVE, ...). So the trial is
> very close to the final setup.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> target/arm/kvm_arm.h | 4 ++++
> target/arm/kvm-stub.c | 7 ++++++
> target/arm/kvm.c | 51 +++++++++++++++++++++++++++++++++++++++++
> target/arm/trace-events | 1 +
> 4 files changed, 63 insertions(+)
>
> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
> index 2b3474cc36..bace69efed 100644
> --- a/target/arm/kvm_arm.h
> +++ b/target/arm/kvm_arm.h
> @@ -14,6 +14,7 @@
> #include "qapi/qapi-types-misc-arm.h"
> #include "system/kvm.h"
> #include "target/arm/cpu-qom.h"
> +#include "cpu-idregs.h"
>
> #define KVM_ARM_VGIC_V2 (1 << 0)
> #define KVM_ARM_VGIC_V3 (1 << 1)
> @@ -250,4 +251,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3);
> */
> char *kvm_print_register_name(uint64_t regidx);
>
> +bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
> + ARM64SysRegField *field, uint64_t newfv,
> + Error **errp);
> #endif
> diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
> index 88cbe8d85c..8e6fae0a4d 100644
> --- a/target/arm/kvm-stub.c
> +++ b/target/arm/kvm-stub.c
> @@ -119,3 +119,10 @@ char *kvm_print_register_name(uint64_t regidx)
> {
> g_assert_not_reached();
> }
> +
> +bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
> + ARM64SysRegField *field, uint64_t newfv,
> + Error **errp)
> +{
> + g_assert_not_reached();
> +}
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 537673177a..f7ca0e0250 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -447,6 +447,57 @@ static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
> #define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
> #define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
>
> +bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
> + ARM64SysRegField *field, uint64_t newfv,
> + Error **errp)
> +{
> + uint64_t mask, old_reg_val, new_reg_val, oldfv;
> + struct kvm_one_reg reg;
> + int lower = field->shift;
> + int length = field->length;
> + int index = field->index;
> + uint64_t kidx;
> + int ret;
> +
> + mask = MAKE_64BIT_MASK(lower, length);
> +
> + if (!kvm_arm_vcpu_validate_sysreg(cpu, field, newfv, errp)) {
> + return false;
> + };
> +
> + kidx = idregs_sysreg_to_kvm_reg(id_register_sysreg[index]);
> + ret = read_sys_reg64(cpufd, &old_reg_val, kidx);
> + if (ret) {
> + error_setg(errp, "failed to read the scratch vcpu value for field %s %m",
> + field->name);
> + return false;
> + }
> + oldfv = (old_reg_val & mask) >> lower;
> +
> + new_reg_val = old_reg_val & ~mask;
> + new_reg_val |= newfv << lower;
> +
> + reg.id = kidx;
> + reg.addr = (uintptr_t)&new_reg_val;
> + ret = ioctl(cpufd, KVM_SET_ONE_REG, ®);
> + if (ret) {
> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s "
> + "(previous is 0x%"PRIx64"): %m", newfv, field->name, oldfv);
> + return false;
> + } else {
> + uint64_t check_val, actualfv;
> +
> + ret = read_sys_reg64(cpufd, &check_val, kidx);
> + if (ret) {
> + error_setg(errp, "failed to read the new reg value: %m");
> + return false;
> + }
> + actualfv = (check_val & mask) >> lower;
> + trace_kvm_idreg_write_scratch_vcpu(field->name, oldfv, newfv, actualfv);
> + }
> + return true;
> +}
> +
Hi Eric,
This looks similar to kvm_arm_apply_sysreg_props(), we maybe be able to abstract out kvm_arm_apply_sysreg_prop(),
which can then be used by both these functions.
> static void set_sysreg_prop(Object *obj, Visitor *v,
> const char *name, void *opaque,
> Error **errp)
> diff --git a/target/arm/trace-events b/target/arm/trace-events
> index 2a9cc67035..7a3f499a0e 100644
> --- a/target/arm/trace-events
> +++ b/target/arm/trace-events
> @@ -21,6 +21,7 @@ set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_va
> apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
> unexpected_writable_reserved_field(const char *reg_name, const char *field_name, int lower, int upper) "Unexpected writable reserved field: %s.%s [%d,%d], skip it ..."
> +kvm_idreg_write_scratch_vcpu(const char *name, uint64_t oldfv, uint64_t newfv, uint64_t actualfv) "successful dry-run for %s old=0x%"PRIx64" new=0x%"PRIx64" actual=0x%"PRIx64
>
> # cpu.c
> arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 18/26] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model
2026-09-28 13:26 ` Khushit Shah
@ 2026-09-28 13:35 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-28 13:35 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/28/26 3:26 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> If the host supports KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES and
>> KVM_ARM_GET_REG_WRITABLE_MASKS ioctl successfully retrieved the mask
>> of writable fields for all ID regs, expose uint64 SYSREG properties
>> for all the writable ID reg fields exposed by the host kernel which
>> can be matched in target/arm/cpu-idregs.h.inc.
>>
>> Properties are named SYSREG_<REG>_<FIELD> with REG and FIELD
>> being those used ARCHMRS Registers.json.
>>
>> When such properties are set, they override the default field value
>> retrieved from the host and reinjected into KVM. Then the actual value
>> being applied at KVM depends on the register, ie. it can be sanitized.
>> In case the field value is rejected by KVM, the vpcu init fails.
>>
>> Anyway there is a first attempt to write back this value into KVM.
>>
>> Then legacy CPU options (virtualization, secure, ...) can still
>> override the previous value. So low level IDREG field properties
>> apply before the legacy ones.
>>
>> An example of invocation is:
>> -cpu host,SYSREG_ID_AA64MMFR0_EL1_ECV=0x0
>> which sets ECV field of ID_AA64MMFR0_EL1 to 0 (enhanced counter
>> virtualization).
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> Reviewed-by: Sebastian Ott <sebott@redhat.com>
>>
> Hi Eric,
>
> The commit message needs an update :)
right! Thank you for spotting this
Eric
>
>> ---
>> v5 -> v6:
>> - do not check writable_map anymore
>>
>> v4 -> v5:
>> - get rid of ret local variable, dynamically allocate and free writable_map
>> here
>> ---
>> target/arm/cpu64.c | 5 +++++
>> 1 file changed, 5 insertions(+)
>>
>> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
>> index 4e8c472530..e04062e848 100644
>> --- a/target/arm/cpu64.c
>> +++ b/target/arm/cpu64.c
>> @@ -37,6 +37,7 @@
>> #include "hw/core/qdev-properties.h"
>> #include "internals.h"
>> #include "cpu-features.h"
>> +#include "cpu-idregs.h"
>>
>> /* convert between <register>_IDX and SYS_<register> */
>> #define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
>> @@ -807,6 +808,10 @@ void aarch64_host_initfn(Object *obj)
>> kvm_arm_set_cpreg_mig_tolerances(cpu);
>> kvm_arm_set_cpu_features_from_host(cpu);
>> aarch64_add_sve_properties(obj);
>> +
>> + /* generate SYSREG properties according to writable masks */
>> + kvm_arm_expose_idreg_properties(cpu, arm64_id_regs);
>> +
>> #elif defined(CONFIG_HVF)
>> hvf_arm_set_cpu_features_from_host(cpu);
>> #elif defined(CONFIG_WHPX)
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter
2026-09-28 13:32 ` Eric Auger
@ 2026-09-28 13:42 ` Khushit Shah
0 siblings, 0 replies; 82+ messages in thread
From: Khushit Shah @ 2026-09-28 13:42 UTC (permalink / raw)
To: eric.auger@redhat.com
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 28 Sep 2026, at 7:02 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
>
>
> On 9/28/26 3:20 PM, Khushit Shah wrote:
>>
>>> On 28 Sep 2026, at 5:19 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>
>>> !-------------------------------------------------------------------|
>>> CAUTION: External Email
>>>
>>> |-------------------------------------------------------------------!
>>>
>>> Hi Khushit,
>>>
>>> On 9/28/26 11:28 AM, Khushit Shah wrote:
>>>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>>>
>>>>> !-------------------------------------------------------------------|
>>>>> CAUTION: External Email
>>>>>
>>>>> |-------------------------------------------------------------------!
>>>>>
>>>>> When the setter is called, the final vcpu is not created yet.
>>>>> Applying the override on vcpu.isar initialized with the max scratch
>>>>> vcpu would not be correct because the final vcpu may have some features
>>>>> turned off (for instance virtualization) while the scratch vcpu
>>>>> features it. So we need to postpone the actual override until the
>>>>> final vcpu has been initialized.
>>>>>
>>>>> In terms of input value validation what can be done now is checking
>>>>> against field length and arch enum value if any.
>>>>>
>>>>> If this succeeds, the field value is added in the hash table to be
>>>>> written later on once the final vcpu has been created
>>>>>
>>>>> With regards to the getter, if the sysreg prop was set, we return the
>>>>> set value, otherwise, we return the value in cpu->isar.idregs[].
>>>>>
>>>> Hi Eric,
>>>>
>>>> Please mention that the cpreg override happens in later commits.
>>> sure
>>>> Signed-off-by: Khushit Shah <khushit.shah@nutanix.com <mailto:khushit.shah@nutanix.com>>
>>> May I ask why?
>>>
>>> Besides we need to be cautious about the fact that people who has signed
>>> off the patches cannot review them ...
>> Ohh sorry, I meant
>>
>> Reviewed-by: Khushit Shah <khushit.shah@nutanix.com <mailto:khushit.shah@nutanix.com>>
>
> ah ok thanks.
> By the way do you mean:
> Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
Yes, this looks correct :)
> I don't know if yours is a correct R-b form but maybe?
>
> Eric
>
>>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>>> ---
>>>>> target/arm/cpu.h | 2 ++
>>>>> target/arm/cpu.c | 5 ++--
>>>>> target/arm/kvm.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++--
>>>>> 3 files changed, 68 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>>>>> index e3f931dba2..9bbd42dd2b 100644
>>>>> --- a/target/arm/cpu.h
>>>>> +++ b/target/arm/cpu.h
>>>>> @@ -952,6 +952,8 @@ struct ArchCPU {
>>>>> uint64_t *cpreg_vmstate_values;
>>>>> int32_t cpreg_vmstate_array_len;
>>>>>
>>>>> + GHashTable *sysreg_props;
>>>>> +
>>>>> DynamicGDBFeatureInfo dyn_sysreg_feature;
>>>>> DynamicGDBFeatureInfo dyn_svereg_feature;
>>>>> DynamicGDBFeatureInfo dyn_smereg_feature;
>>>>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>>>>> index 77aa78f00e..917f709cb4 100644
>>>>> --- a/target/arm/cpu.c
>>>>> +++ b/target/arm/cpu.c
>>>>> @@ -1236,8 +1236,8 @@ static void arm_cpu_initfn(Object *obj)
>>>>> {
>>>>> ARMCPU *cpu = ARM_CPU(obj);
>>>>>
>>>>> - cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
>>>>> - NULL, g_free);
>>>>> + cpu->cp_regs = g_hash_table_new(g_direct_hash, g_direct_equal);
>>>>> + cpu->sysreg_props = g_hash_table_new(g_direct_hash, g_direct_equal);
>>>>>
>>>>> QLIST_INIT(&cpu->pre_el_change_hooks);
>>>>> QLIST_INIT(&cpu->el_change_hooks);
>>>>> @@ -1725,6 +1725,7 @@ static void arm_cpu_finalizefn(Object *obj)
>>>>> ARMCPRegMigTolerance *t, *n;
>>>>>
>>>>> g_hash_table_destroy(cpu->cp_regs);
>>>>> + g_hash_table_destroy(cpu->sysreg_props);
>>>>>
>>>>> QLIST_FOREACH_SAFE(hook, &cpu->pre_el_change_hooks, node, next) {
>>>>> QLIST_REMOVE(hook, node);
>>>>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>>>>> index 341542279d..cdc3779321 100644
>>>>> --- a/target/arm/kvm.c
>>>>> +++ b/target/arm/kvm.c
>>>>> @@ -340,18 +340,79 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>>>>> return NULL;
>>>>> }
>>>>>
>>>>> +#define MAKE_IDREG_KEY(reg_idx, field_shift) \
>>>>> + (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>>>> +
>>>> Maybe, IDREG_FIELD_KEY()?
>>> Yes
>>>
>>> Eric
>>>> Warm Regards,
>>>> Khushit
>>>>> static void set_sysreg_prop(Object *obj, Visitor *v,
>>>>> const char *name, void *opaque,
>>>>> Error **errp)
>>>>> {
>>>>> - error_setg(errp, "%s setter not yet implemented", name);
>>>>> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
>>>>> + ARMCPU *cpu = ARM_CPU(obj);
>>>>> + int index = field->index;
>>>>> + int lower = field->shift;
>>>>> + int length = field->length;
>>>>> + uint64_t key, value;
>>>>> +
>>>>> + if (!visit_type_uint64(v, name, &value, errp)) {
>>>>> + return;
>>>>> + }
>>>>> +
>>>>> + if (length < 64 && value > ((1 << length) - 1)) {
>>>>> + error_setg(errp,
>>>>> + "idreg %s set value (0x%lx) exceeds length of field (%d)!",
>>>>> + name, value, length);
>>>>> + return;
>>>>> + }
>>>>> +
>>>>> + if (field->arch_vals) {
>>>>> + /* this field has some enum values */
>>>>> + for (int i = 0; i < field->arch_vals_count; i++) {
>>>>> + if (value == field->arch_vals[i]) {
>>>>> + goto valid;
>>>>> + }
>>>>> + }
>>>>> + error_setg(errp,
>>>>> + "idreg %s set value (0x%lx) does not match any "
>>>>> + "arch valid enum value", name, value);
>>>>> + return;
>>>>> + }
>>>>> +
>>>>> +valid:
>>>>> +
>>>>> + key = MAKE_IDREG_KEY(index, lower);
>>>>> + g_hash_table_insert(cpu->sysreg_props, GUINT_TO_POINTER(key),
>>>>> + GUINT_TO_POINTER(value));
>>>>> }
>>>>>
>>>>> static void get_sysreg_prop(Object *obj, Visitor *v,
>>>>> const char *name, void *opaque,
>>>>> Error **errp)
>>>>> {
>>>>> - error_setg(errp, "%s getter not yet implemented", name);
>>>>> + ARM64SysRegField *field = (ARM64SysRegField *)opaque;
>>>>> + ARMCPU *cpu = ARM_CPU(obj);
>>>>> + int index = field->index;
>>>>> + int lower = field->shift;
>>>>> + int length = field->length;
>>>>> + gpointer value_ptr;
>>>>> + uint64_t value;
>>>>> + uint64_t key = MAKE_IDREG_KEY(index, lower);
>>>>> + gboolean exists;
>>>>> +
>>>>> + exists = g_hash_table_lookup_extended(cpu->sysreg_props,
>>>>> + GUINT_TO_POINTER(key), NULL,
>>>>> + &value_ptr);
>>>>> + if (exists) {
>>>>> + value = GPOINTER_TO_UINT(value_ptr);
>>>>> + } else {
>>>>> + uint64_t mask = MAKE_64BIT_MASK(lower, length);
>>>>> + uint64_t *idregs = cpu->isar.idregs;
>>>>> +
>>>>> + value = (idregs[index] & mask) >> lower;
>>>>> + }
>>>>> +
>>>>> + visit_type_uint64(v, name, &value, errp);
>>>>> + trace_get_sysreg_prop(name, value);
>>>>> }
>>>>>
>>>>> /*
>>>>> --
>>>>> 2.53.0
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 25/26] arm-qmp-cmds: introspection for ID register props
2026-09-16 14:45 ` [PATCH v9 25/26] arm-qmp-cmds: introspection for ID register props Eric Auger
@ 2026-09-28 14:39 ` Khushit Shah
2026-10-07 14:27 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-28 14:39 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> From: Cornelia Huck <cohuck@redhat.com>
>
> Enhance the current host model query-cpu-model-expansion with the
> capability to return SYSREG_* options and also test possible
> values.
>
> If no SYSREG prop is set, query-cpu-model-expansion returns the
> default host values for all SYSREG properties. They are extracted
> from a scratch vcpu featuring all the KVM advertised capabilities.
>
> Here is a qmp-shell example:
>
> (QEMU) query-cpu-model-expansion type=full model={"name":"host"}
> {"return": {"model": {"name": "host", "props": {"SYSREG_ID_AA64PFR0_EL1_EL3": 1,
> "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0, "SYSREG_CTR_EL0_L1Ip": 3,
> "SYSREG_MIDR_EL1_PartNum": 3407, "SYSREG_CTR_EL0_DminLine": 4,
> "SYSREG_ID_AA64MMFR0_EL1_PARange": 5, "SYSREG_ID_AA64MMFR1_EL1_ECBHB": 0
> ../..
>
> It becomes also possible to test new SYSREG property values.
>
> With Full expansion of the host model, the SYSREG props are tested
> against a scratch vcpu. With static expansion, no check is performed
> against KVM but only against qemu code (the value does not exceed the
> field size and if the field is associated to enum values, the set
> value belongs to the list of arch enum values.
>
> Examples
> (QEMU) query-cpu-model-expansion type=full model={"name":"host","props":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x13}}
> {"error": {"class": "GenericError", "desc": "idreg SYSREG_ID_AA64ISAR0_EL1_DP set value (0x13) exceeds length of field (4)!"}}
>
> (QEMU) query-cpu-model-expansion type=full model={"name":"host","props":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x2}}
> {"error": {"class": "GenericError", "desc": "idreg SYSREG_ID_AA64ISAR0_EL1_DP set value (0x2) does not match any arch valid enum value!"}}
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>
> ---
>
> v8 -> v9:
> - fix the leak reported by Khushit
> - implement static mode for host
>
> v7 -> v8:
> - do not check if the prop exists (this is checked elsewhere with a
> different error message)
> - clarify that examples given in the commit msg are based on qmp-shell
>
> v5 -> v6:
> - add the write capability
> ---
> target/arm/arm-qmp-cmds.c | 107 ++++++++++++++++++++++++++++++++++++--
> 1 file changed, 104 insertions(+), 3 deletions(-)
>
> diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
> index 83ec95c290..b52ca67f83 100644
> --- a/target/arm/arm-qmp-cmds.c
> +++ b/target/arm/arm-qmp-cmds.c
> @@ -21,6 +21,7 @@
> */
>
> #include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> #include "qemu/target-info.h"
> #include "hw/core/boards.h"
> #include "kvm_arm.h"
> @@ -30,6 +31,7 @@
> #include "qapi/qapi-commands-machine.h"
> #include "qapi/qapi-commands-misc-arm.h"
> #include "qobject/qdict.h"
> +#include "qobject/qnum.h"
> #include "qom/qom-qobject.h"
> #include "cpu.h"
>
> @@ -83,15 +85,20 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
> CpuModelInfo *model,
> Error **errp)
> {
> + bool use_scratch_vcpu = kvm_enabled() && type == CPU_MODEL_EXPANSION_TYPE_FULL;
> CpuModelExpansionInfo *expansion_info;
> + ObjectPropertyIterator iter;
> const QDict *qdict_in;
> + ObjectProperty *idregprop;
> QDict *qdict_out;
> ObjectClass *oc;
> Object *obj;
> const char *name;
> + int fdarray[3];
> int i;
>
> - if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
> + /* we support static expansion for host model only */
> + if (type != CPU_MODEL_EXPANSION_TYPE_FULL && strcmp(model->name, "host")) {
> error_setg(errp, "The requested expansion type is not supported");
> return NULL;
> }
> @@ -136,6 +143,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
> if (model->props) {
> Visitor *visitor;
> Error *err = NULL;
> + int fd = -1;
>
> visitor = qobject_input_visitor_new(model->props);
> if (!visit_start_struct(visitor, "model.props", NULL, 0, errp)) {
> @@ -146,6 +154,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>
> qdict_in = qobject_to(QDict, model->props);
> i = 0;
> +
> + /* Test legacy composite option settings */
> while ((name = cpu_model_advertised_features[i++]) != NULL) {
> if (qdict_get(qdict_in, name)) {
> if (!object_property_set(obj, name, visitor, &err)) {
> @@ -154,11 +164,85 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
> }
> }
>
> + if (!err) {
> + arm_cpu_finalize_features(ARM_CPU(obj), &err);
> + }
> +
> + /**
> + * Test SYSREG option settings
> + * In full mode, build a scratch vcpu that reflects composite legacy
> + * options
> + */
> + if (use_scratch_vcpu) {
> + Error *local_err = NULL;
> + bool has_virt = object_property_get_bool(OBJECT(current_machine),
> + "virtualization",
> + &local_err);
> +
> + if (local_err) {
Hi Eric,
Nit: indentation
> + error_free(local_err); /* the machine property does not exist */
> + } else {
> + if (!has_virt && object_property_find(obj, "has_el2")) {
> + object_property_set_bool(obj, "has_el2", false, NULL);
> + }
> + }
> + fd = kvm_arm_create_init_scratch_vcpu(ARM_CPU(obj), errp);
> + if (fd < 0) {
> + return NULL;
Leaks obj/visitor.
> + }
> + }
> +
> + qdict_in = qobject_to(QDict, model->props);
> + for (const QDictEntry *entry = qdict_first(qdict_in);
> + entry != NULL; entry = qdict_next(qdict_in, entry)) {
> + const char *key = qdict_entry_key(entry);
> + QObject *val_obj = qdict_entry_value(entry);
> + ObjectProperty *prop;
> + Visitor *v;
> + bool success;
> + uint64_t val;
> +
> + prop = object_property_find(obj, key);
> +
> + if (!g_str_has_prefix(key, "SYSREG_")) {
> + continue;
> + }
> +
> + /* consume the prop to avoid unexpected parameter */
> + if (!visit_type_uint64(visitor, key, &val, errp)) {
> + goto bail_out;
> + }
> +
> + v = qobject_input_visitor_new(val_obj);
> +
> + if (!object_property_set(obj, key, v, errp)) {
> + goto bail_out;
> + }
> +
> + if (use_scratch_vcpu) {
> + ARM64SysRegField *field = (ARM64SysRegField *)prop->opaque;
> + uint64_t newfv;
> +
> + if (!visit_type_uint64(v, name, &newfv, errp)) {
The name is not initialised in this scope… It carries value of last processed legacy prop
> + visit_free(v);
> + goto bail_out;
> + }
> + success = kvm_idreg_write_scratch_vcpu(ARM_CPU(obj), fd,
> + field, newfv, errp);
> + if (!success) {
> + visit_free(v);
> + goto bail_out;
> + }
> + }
> + visit_free(v);
> + }
> +
> if (!err) {
> visit_check_struct(visitor, &err);
> }
> - if (!err) {
> - arm_cpu_finalize_features(ARM_CPU(obj), &err);
> +
> + if (use_scratch_vcpu) {
> + kvm_arm_destroy_scratch_host_vcpu(fdarray);
> }
> visit_end_struct(visitor, NULL);
> visit_free(visitor);
> @@ -190,6 +274,18 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
> }
> }
>
> + object_property_iter_init(&iter, obj);
> +
> + while ((idregprop = object_property_iter_next(&iter))) {
> + QObject *value;
> +
> + if (!g_str_has_prefix(idregprop->name, "SYSREG_")) {
> + continue;
> + }
> + value = object_property_get_qobject(obj, idregprop->name, &error_abort);
> + qdict_put_obj(qdict_out, idregprop->name, value);
> + }
> +
> if (!qdict_size(qdict_out)) {
> qobject_unref(qdict_out);
> } else {
> @@ -199,6 +295,11 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
> object_unref(obj);
>
> return expansion_info;
> +bail_out:
Leaks obj.
> + if (use_scratch_vcpu) {
> + kvm_arm_destroy_scratch_host_vcpu(fdarray);
fdarray is actually never written to.
Warm Regards,
Khushit
> + }
> + return NULL;
> }
>
> static void arm_cpu_add_definition(gpointer data, gpointer user_data)
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 13/26] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties
2026-09-24 6:26 ` Khushit Shah
2026-09-24 6:42 ` Eric Auger
@ 2026-09-28 15:21 ` Eric Auger
1 sibling, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-28 15:21 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Khushit,
On 9/24/26 8:26 AM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> +
>> +/*
>> + * decode_idreg_writemap: Generate props for writable fields
>> + *
>> + * @obj: CPU object
>> + * @reg: description of the sysreg
>> + */
>> +static int
>> +decode_idreg_writemap(Object *obj, ARM64SysReg *reg)
>> +{
>> + uint64_t map = reg->writable_mask;
>> + int i = ctz64(map);
>> + int nb_sysreg_props = 0;
>> +
>> + while (map) {
>> + ARM64SysRegField *field = get_field(i, reg);
>> + int lower, upper;
>> + char *prop_name;
>> + uint64_t field_mask;
>> +
>> + if (!field) {
>> + warn_report("%s bit %d of %s is writable but no named field "
>> + "in target/arm/cpu-idregs.h.inc",
>> + __func__, i, reg->name);
>> + map = map & ~BIT_ULL(i);
>> + i = ctz64(map);
>> + continue;
>> + }
>> + lower = field->shift;
>> + upper = field->shift + field->length - 1;
>> + prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name);
>> + trace_decode_idreg_writemap(field->name, lower, upper, prop_name);
>> + object_property_add(obj, prop_name, "uint64",
>> + get_sysreg_prop, set_sysreg_prop, NULL, field);
>> + g_free(prop_name);
>> + nb_sysreg_props++;
>> +
>> + field_mask = MAKE_64BIT_MASK(lower, field->length);
>> + map = map & ~field_mask;
>> + i = ctz64(map);
>> + }
>> + trace_nb_sysreg_props(reg->name, nb_sysreg_props);
>> + return 0;
>> +}
>> +
> We can try field based handling, it is more elegant.
> - for each field, check if not RES and writable.
As discussed I now enumerate all the fields instead of decoding the
writbale bitmask. But I still do some sanity checks on the consumed
writable bitmask:
- check the field is fully writable
- check if, after enumerating all fields I still have some writable bits.
The above cases would highlight some inconsistencies between KVM outputs
and qemu architecture description. I think it is worth.
Thanks
Eric
>
> <Though I will argue that all fields should be present not just writable :)>
>
>
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 12/26] arm/kvm: Initialize isar.idregs[] with all writable host ID regs
2026-09-25 13:27 ` Khushit Shah
@ 2026-09-28 17:34 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-28 17:34 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/25/26 3:27 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> kvm_arm_get_host_cpu_features() already retrieves the values of some
>> host id registers to analyze the available vcpu features.
>>
>> Eventually we want to be able to allow the user to change the value
>> of writable ID reg fields. So we need to store the initial value of all
>> writable ID regs into isar.idregs[].
>>
>> Introduce a new get_host_cpu_idregs() helper that populates isar.idregs[]
>> and call it from kvm_arm_get_host_cpu_features.
>>
>> This patch has no impact on cpreg values. isar.idregs[] is only
>> used as a temporary storage for register values to be updated in place
>> later. Also it does not handle the writeback of isar.idregs[] into cpreg
>> value list after user update. This will be handled separately.
>>
>> Note the host values are retrieved from the scratch vcpu initialized with
>> all the available capabilities exposed by KVM, independently on the
>> final choice made by the suer.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> Hi Eric,
>
> As we discussed, in v10, there will be an option to also read all the ID registers, not only writable.
yes we can do that. reviewers may advocate the leave as is though as the
only call site in
this series will use writable mode.
>> ---
>> v8 -> v9:
>> - improve the commit msg. Only initialize in this patch and move the
>> write back to cpreg value list in a different patch.
>> - Do not hack CLIDR here. The correct way to fix that temporarily is to
>> do that in the machine instead.
>>
>> v7 -> v8
>> - fix indent and added Khushit's R-b
>>
>> v6 -> v7
>> - remove vcpu from prototypes (Khushit)
>>
>> v5 -> v6
>> - do not check writable_map anymore
>> ---
>> target/arm/kvm.c | 43 ++++++++++++++++++++++++++++++++++++++++-
>> target/arm/trace-events | 2 ++
>> 2 files changed, 44 insertions(+), 1 deletion(-)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index c6eac41991..958b25e550 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -43,6 +43,7 @@
>> #include "hw/acpi/ghes.h"
>> #include "target/arm/gtimer.h"
>> #include "migration/blocker.h"
>> +#include "cpu-idregs.h"
>>
>> const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>> KVM_CAP_INFO(DEVICE_CTRL),
>> @@ -290,7 +291,44 @@ static int kvm_feature_idx_to_idregs_idx(int kidx)
>> return get_sysreg_idx(sysreg);
>> }
>>
>> -static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>> +/*
>> + * get_host_cpu_idregs: Read all the writable ID reg host values
>> + *
>> + * Need to be called once the writable mask has been populated
>> + * Note we may want to read all the known id regs but some of them are not
>> + * writable and return an error, hence the choice of reading only those which
>> + * are writable. Those are also readable!
>> + */
>> +static int get_host_cpu_idregs(int fd, ARMHostCPUFeatures *ahcf)
>> +{
>> + int err = 0;
>> + int i;
>> +
>> + for (i = 0; i < NUM_ID_IDX; i++) {
>> + ARM64SysReg *sysregdesc = &arm64_id_regs[i];
>> + ARMSysRegs sysreg = id_register_sysreg[i];
>> + uint64_t *reg;
>> + int ret;
>> +
>> + if (!sysregdesc->writable_mask) {
>> + continue;
>> + }
>> +
>> + reg = &ahcf->isar.idregs[i];
>> + ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg));
>> + trace_get_host_cpu_idregs(sysregdesc->name, *reg);
>> + if (ret) {
>> + error_report("%s error reading value of host %s register (%m)",
>> + __func__, sysregdesc->name);
>> +
>> + err = ret;
>> + }
>> + }
>> + return err;
>> +}
>> +
>> +static void
>> +kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>> {
>> /* Identify the feature bits corresponding to the host CPU, and
>> * fill out the ARMHostCPUClass fields accordingly. To do this
>> @@ -376,6 +414,9 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>> SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */
>> err = 0;
>> } else {
>> + /* Make sure all writable ID reg values are initialized */
>> + err |= get_host_cpu_idregs(fd, ahcf);
>> +
> Perhaps if we read “all” the ID registers, we should be able to get rid of all the manual reads below.
Yes if all are read, we can remove this. But for now this is depends on
the host capabilities, better to
leave as is I think.
>
>> err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX);
>> err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR2_EL1_IDX);
>> err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX);
>> diff --git a/target/arm/trace-events b/target/arm/trace-events
>> index 8502fb3265..c25d2a1191 100644
>> --- a/target/arm/trace-events
>> +++ b/target/arm/trace-events
>> @@ -13,6 +13,8 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
>>
>> # kvm.c
>> kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
>> +get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64
>> +kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%”PRIx64
> ^^ leaked into this commit.
yup. Thanks!
Eric
>
> Warm Regards,
> Khushit
>
>> # cpu.c
>> arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props
2026-09-28 12:53 ` Khushit Shah
@ 2026-09-29 12:13 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-29 12:13 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Khushit,
On 9/28/26 2:53 PM, Khushit Shah wrote:
> Hi Eric,
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Since legacy composite options (such as SVE, virtualization, ...)
>> and new SYSREG props coexist, add some basic consistency checks.
>>
>> Those checks are performed both in kvm_arch_init_vcpu() before
>> applying the SYSREG props at the end of the initialization chain.
> Where else?
nowhere, I shall remove the 'both'
>
>> Some ID reg fields corresponding to legacy composite option scope
>> are not writable. In that case we just check that the field has
>> not become writable.
> I don’t understand where the above happens in code.
Everywhere you have:
+ error_setg(errp, "%s is now exposed but qemu is not ready to support it",
+ propname);
I modified the commit description with:
Some ID reg fields corresponding to legacy composite option scope
are not (yet) writable (EL3, MTE, SVE, ...). As such they are not
supposed to be exposed through SYSREG properties. However in the
hypothesis they would become writable, and thus would be exposed
and attempted to be set, we need to reject any setting because no
consistency check is implemented yet.
>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> ---
>> target/arm/kvm.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 105 insertions(+)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index ddf320d0e6..f52c03745e 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -340,6 +340,107 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>> return NULL;
>> }
>>
>> +
>> +/**
>> + * kvm_arm_vcpu_validate_sysreg:
>> + *
>> + * Validate a SYSREG field value is consistent with legacy composite options
>> + * Some checks are not implemented because the corresponding sysreg field
>> + * is not currently writable. In that case we make sure the field has not
>> + * become writable, which would mean the user had the capability to set the
>> + * corresponding property.
>> + *
>> + * return true if consistent. false if it is not, along with an error handle
>> + */
>> +static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
>> + uint64_t value, Error **errp)
>> +{
>> + const char *fieldname = field->name;
>> + ARM64SysReg *sysregdesc = &arm64_id_regs[field->index];
>> + const char *regname = sysregdesc->name;
>> + g_autofree char *propname = g_strdup_printf("SYSREG_%s_%s", regname, fieldname);
> I don’t see a reason to build property name here.
a field is fully discriminated by the reg name string/index + the field name string/index. So I imagined I could use the prop name directly which has both. Now I can also remove "SYSREG_" if this was you prefer?
>> +
>> + /* virtualization */
>> + if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) {
>> + /* consistency with machine virtualization property */
>> + if (cpu->has_el2 && value == 0) {
>> + error_setg(errp,
>> + "Inconsistent -machine virtualization=on and "
>> + "%s=0", propname);
>> + return false;
>> + } else if (!cpu->has_el2 && value > 0) {
>> + error_setg(errp,
>> + "Inconsistent -machine virtualization=off and "
>> + "%s > 0", propname);
>> + return false;
>> + }
>> + /* secure */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL3") && value > 0) {
>> + /* consistency with machine secure property */
>> + error_setg(errp, "%s is set but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + /* MTE */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR1_EL1_MTE")) {
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + /* SVE */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_SVE")) {
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ZFR0_EL1_SVEver")) {
>> + if (cpu_isar_feature(aa64_sve, cpu) && value == 0) {
>> + error_setg(errp, "sve is set but %s is set to 0", propname);
>> + return false;
> This is actually an valid configuration.
OK I removed that
Thanks!
Eric
>
>> + } else if (!cpu_isar_feature(aa64_sve, cpu) && value > 0) {
>> + error_setg(errp, "sve is not set but %s is greater than 0",
>> + propname);
>> + return false;
>> + }
>> + /* PAUTH */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_APA")) {
>> + /* PAUTH QARMA5 address authentification */
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_API")) {
>> + /* PAUTH Impl Defined address authentification */
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPA")) {
>> + /* QARMA5 generic code authentification */
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPI")) {
>> + /* QARMA5 generic code authentification */
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + /* PMU */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64DFR0_EL1_PMUVer")) {
>> + if (cpu->has_pmu && value == 0) {
>> + error_setg(errp, "%s is 0 whereas pmu is set", propname);
>> + return false;
>> + } else if (!cpu->has_pmu && value) {
>> + error_setg(errp, "%s is non null whereas pmu is unset", propname);
>> + return false;
>> + }
>> + /* aarch64 false */
>> + } else if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
>> + if ((!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL0") ||
>> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL1") ||
>> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) && value < 2)
>> + error_setg(errp, "%s is < 2 while aarch64 is set to off",
>> + propname);
>> + return false;
> return should be covered in braces.
>
> Warm Regards,
> Khushit
>> + }
>> + return true;
>> +}
>> +
>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>
>> @@ -2241,6 +2342,10 @@ static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>> uint64_t oldfv;
>> int ret;
>>
>> + if (!kvm_arm_vcpu_validate_sysreg(cpu, field, value, errp)) {
>> + return -1;
>> + }
>> +
>> mask = MAKE_64BIT_MASK(lower, length);
>> value = value << lower;
>>
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py
2026-09-24 10:24 ` Khushit Shah
@ 2026-09-29 12:31 ` Eric Auger
2026-09-29 14:28 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-29 12:31 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/24/26 12:24 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Introduce a script that takes as input the Registers.json file
>> delivered in the AARCHMRS Features Model downloadable from the
>> Arm Developer A-Profile Architecture Exploration Tools page:
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
>> and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
>> under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>).
>>
>> We only care about IDregs with opcodes satisfying:
>> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> [CH: note correct op1 range, don't skip CCSIDR]
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>> Message-ID: <20251208163751.611186-2-eric.auger@redhat.com>
>> ---
>> scripts/update-aarch64-cpu-sysregs-header.py | 146 +++++++++++++++++++
>> 1 file changed, 146 insertions(+)
>> create mode 100755 scripts/update-aarch64-cpu-sysregs-header.py
>>
>> diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
>> new file mode 100755
>> index 0000000000..ef1471a197
>> --- /dev/null
>> +++ b/scripts/update-aarch64-cpu-sysregs-header.py
>> @@ -0,0 +1,146 @@
>> +#!/usr/bin/env python3
>> +
>> +# This script takes as input the Registers.json file delivered in
>> +# the AARCHMRS Features Model downloadable from the Arm Developer
>> +# A-Profile Architecture Exploration Tools page:
>> +# https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
>> +# and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
>> +# under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
>> +#
>> +# Copyright (C) 2026 Red Hat, Inc.
>> +#
>> +# Authors: Eric Auger <eric.auger@redhat.com>
>> +#
>> +# SPDX-License-Identifier: GPL-2.0-or-later
>> +
>> +
>> +import json
>> +import os
>> +import sys
>> +
>> +def is_demux_register(r):
>> + name = r.get('name', '')
>> +
>> + if name.startswith("CCSIDR"):
>> + return True
>> +
>> + return False
>> +
>> +# Some regs have op code values like 000x, 001x. Anyway we don't need
>> +# them. Besides some regs are undesired in the generated file such as
>> +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
>> +# are interested in and are tricky to decode as their system accessor
>> +# refer to MPIDR_EL1/MIDR_EL1 respectively
>> +
>> +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
>> + 'VMPIDR_EL2', 'VPIDR_EL2’]
> I see VMPIDR_EL2/VPIDR_EL2 have op1=0100, they will automatically get skipped, why is this needed?
because op1=4 is outside of the IDreg range:
op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
Eric
>
> Warm Regards,
> Khushit
>> +# returns the int value of a given @opcode for a reg @encoding
>> +def get_opcode(encoding, opcode):
>> + fvalue = encoding.get(opcode)
>> + if fvalue:
>> + value = fvalue.get('value')
>> + if isinstance(value, str):
>> + value = value.strip("'")
>> + value = int(value, 2)
>> + return value
>> + return -1
>> +
>> +def extract_idregs_from_registers_json(filename):
>> + """
>> + Load a Registers.json file and extract all ID registers, decode their
>> + opcode and dump the information in target/arm/cpu-sysregs.h.inc
>> +
>> + Args:
>> + filename (str): The path to the Registers.json
>> + returns:
>> + idregs: list of ID regs and their encoding
>> + """
>> + if not os.path.exists(filename):
>> + print(f"Error: {filename} could not be found!")
>> + return {}
>> +
>> + try:
>> + with open(filename, 'r') as f:
>> + register_data = json.load(f)
>> +
>> + except json.JSONDecodeError:
>> + print(f"Could not decode json from '{filename}'!")
>> + return {}
>> + except Exception as e:
>> + print(f"Unexpected error while reading {filename}: {e}")
>> + return {}
>> +
>> + registers = [
>> + r for r in register_data
>> + if isinstance(r, dict)
>> + and r.get('_type') == 'Register'
>> + and not is_demux_register(r)
>> + ]
>> +
>> + idregs = {}
>> +
>> + for register in registers:
>> + reg_name = register.get('name')
>> +
>> + is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
>> +
>> + if reg_name and not is_skipped:
>> + accessors = register.get('accessors', [])
>> +
>> + for accessor in accessors:
>> + type = accessor.get('_type')
>> + if type in ['Accessors.SystemAccessor']:
>> + encoding_list = accessor.get('encoding')
>> +
>> + if isinstance(encoding_list, list) and encoding_list and \
>> + isinstance(encoding_list[0], dict):
>> + encoding_wrapper = encoding_list[0]
>> + encoding_source = encoding_wrapper.get('encodings', \
>> + encoding_wrapper)
>> +
>> + if isinstance(encoding_source, dict):
>> + op0 = get_opcode(encoding_source, 'op0')
>> + op1 = get_opcode(encoding_source, 'op1')
>> + op2 = get_opcode(encoding_source, 'op2')
>> + crn = get_opcode(encoding_source, 'CRn')
>> + crm = get_opcode(encoding_source, 'CRm')
>> + encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
>> +
>> + # ID regs are assumed within this scope
>> + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
>> + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
>> + idregs[reg_name] = encoding_str
>> +
>> + return idregs
>> +
>> +if __name__ == "__main__":
>> + # Single arg expected: the path to the Registers.json file
>> + if len(sys.argv) < 2:
>> + print("Usage: python scripts/update-aarch64-cpu-sysregs-header.py "
>> + "<path_to_registers_json>")
>> + sys.exit(1)
>> + else:
>> + json_file_path = sys.argv[1]
>> +
>> + extracted_registers = extract_idregs_from_registers_json(json_file_path)
>> +
>> + if extracted_registers:
>> + output_list = extracted_registers.items()
>> +
>> + # Sort by register name
>> + sorted_output = sorted(output_list, key=lambda item: item[0])
>> +
>> + # format lines as DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
>> + final_output = ""
>> + for reg_name, encoding in sorted_output:
>> + reformatted_encoding = encoding.replace(" ", ", ")
>> + final_output += f"DEF({reg_name}, {reformatted_encoding})\n"
>> +
>> + with open("target/arm/cpu-sysregs.h.inc", 'w') as f:
>> + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
>> + f.write("/* This file is autogenerated by ")
>> + f.write("scripts/update-aarch64-cpu-sysregs-header.py */\n")
>> + f.write("/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */\n\n")
>> + f.write(final_output)
>> + print("updated target/arm/cpu-sysregs.h.inc")
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py
2026-09-29 12:31 ` Eric Auger
@ 2026-09-29 14:28 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-29 14:28 UTC (permalink / raw)
To: eric.auger, Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/29/26 2:31 PM, Eric Auger wrote:
>
>
> On 9/24/26 12:24 PM, Khushit Shah wrote:
>>
>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>
>>> !-------------------------------------------------------------------|
>>> CAUTION: External Email
>>>
>>> |-------------------------------------------------------------------!
>>>
>>> Introduce a script that takes as input the Registers.json file
>>> delivered in the AARCHMRS Features Model downloadable from the
>>> Arm Developer A-Profile Architecture Exploration Tools page:
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
>>> and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
>>> under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>).
>>>
>>> We only care about IDregs with opcodes satisfying:
>>> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
>>>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>> [CH: note correct op1 range, don't skip CCSIDR]
>>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>> Message-ID: <20251208163751.611186-2-eric.auger@redhat.com>
>>> ---
>>> scripts/update-aarch64-cpu-sysregs-header.py | 146 +++++++++++++++++++
>>> 1 file changed, 146 insertions(+)
>>> create mode 100755 scripts/update-aarch64-cpu-sysregs-header.py
>>>
>>> diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
>>> new file mode 100755
>>> index 0000000000..ef1471a197
>>> --- /dev/null
>>> +++ b/scripts/update-aarch64-cpu-sysregs-header.py
>>> @@ -0,0 +1,146 @@
>>> +#!/usr/bin/env python3
>>> +
>>> +# This script takes as input the Registers.json file delivered in
>>> +# the AARCHMRS Features Model downloadable from the Arm Developer
>>> +# A-Profile Architecture Exploration Tools page:
>>> +# https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=SAaDSqqwmIC1nbrh-28kms6KiFYKvW8H_CIOKWgWjucuAn37j49gnNNnMIpoP_bK&s=sxOID-2FnhcQ56l1mmjKbXtXpcERk4oOXYiF3-6fenk&e=
>>> +# and outputs the list of ID regs in target/arm/cpu-sysregs.h.inc
>>> +# under the form of DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
>>> +#
>>> +# Copyright (C) 2026 Red Hat, Inc.
>>> +#
>>> +# Authors: Eric Auger <eric.auger@redhat.com>
>>> +#
>>> +# SPDX-License-Identifier: GPL-2.0-or-later
>>> +
>>> +
>>> +import json
>>> +import os
>>> +import sys
>>> +
>>> +def is_demux_register(r):
>>> + name = r.get('name', '')
>>> +
>>> + if name.startswith("CCSIDR"):
>>> + return True
>>> +
>>> + return False
>>> +
>>> +# Some regs have op code values like 000x, 001x. Anyway we don't need
>>> +# them. Besides some regs are undesired in the generated file such as
>>> +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
>>> +# are interested in and are tricky to decode as their system accessor
>>> +# refer to MPIDR_EL1/MIDR_EL1 respectively
>>> +
>>> +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
>>> + 'VMPIDR_EL2', 'VPIDR_EL2’]
>> I see VMPIDR_EL2/VPIDR_EL2 have op1=0100, they will automatically get skipped, why is this needed?
>
> because op1=4 is outside of the IDreg range:
> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
sorry I misunderstood the actual point. Althouth op1=4 I get them if I
don't explicitly put them in the skiplist.
What is output is:
> DEF(VMPIDR_EL2, 3, 0, 0, 0, 5)
> DEF(VPIDR_EL2, 3, 0, 0, 0, 0)
As mentionned in the above comment the reason we get them is among
accessors the script finds MPIDR_EL1/MIDR_EL1.
this is due to this specificity: "If EL2 is not implemented, reads of
this register return the value of the MPIDR_EL1/MIDR_EL1 and writes to
the register are ignored.". Since it is a very special case, I prefer to
skip them explicitly knowing that anyway they are outside of the
interest scope.
Eric
>
> Eric
>>
>> Warm Regards,
>> Khushit
>>> +# returns the int value of a given @opcode for a reg @encoding
>>> +def get_opcode(encoding, opcode):
>>> + fvalue = encoding.get(opcode)
>>> + if fvalue:
>>> + value = fvalue.get('value')
>>> + if isinstance(value, str):
>>> + value = value.strip("'")
>>> + value = int(value, 2)
>>> + return value
>>> + return -1
>>> +
>>> +def extract_idregs_from_registers_json(filename):
>>> + """
>>> + Load a Registers.json file and extract all ID registers, decode their
>>> + opcode and dump the information in target/arm/cpu-sysregs.h.inc
>>> +
>>> + Args:
>>> + filename (str): The path to the Registers.json
>>> + returns:
>>> + idregs: list of ID regs and their encoding
>>> + """
>>> + if not os.path.exists(filename):
>>> + print(f"Error: {filename} could not be found!")
>>> + return {}
>>> +
>>> + try:
>>> + with open(filename, 'r') as f:
>>> + register_data = json.load(f)
>>> +
>>> + except json.JSONDecodeError:
>>> + print(f"Could not decode json from '{filename}'!")
>>> + return {}
>>> + except Exception as e:
>>> + print(f"Unexpected error while reading {filename}: {e}")
>>> + return {}
>>> +
>>> + registers = [
>>> + r for r in register_data
>>> + if isinstance(r, dict)
>>> + and r.get('_type') == 'Register'
>>> + and not is_demux_register(r)
>>> + ]
>>> +
>>> + idregs = {}
>>> +
>>> + for register in registers:
>>> + reg_name = register.get('name')
>>> +
>>> + is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
>>> +
>>> + if reg_name and not is_skipped:
>>> + accessors = register.get('accessors', [])
>>> +
>>> + for accessor in accessors:
>>> + type = accessor.get('_type')
>>> + if type in ['Accessors.SystemAccessor']:
>>> + encoding_list = accessor.get('encoding')
>>> +
>>> + if isinstance(encoding_list, list) and encoding_list and \
>>> + isinstance(encoding_list[0], dict):
>>> + encoding_wrapper = encoding_list[0]
>>> + encoding_source = encoding_wrapper.get('encodings', \
>>> + encoding_wrapper)
>>> +
>>> + if isinstance(encoding_source, dict):
>>> + op0 = get_opcode(encoding_source, 'op0')
>>> + op1 = get_opcode(encoding_source, 'op1')
>>> + op2 = get_opcode(encoding_source, 'op2')
>>> + crn = get_opcode(encoding_source, 'CRn')
>>> + crm = get_opcode(encoding_source, 'CRm')
>>> + encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
>>> +
>>> + # ID regs are assumed within this scope
>>> + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
>>> + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
>>> + idregs[reg_name] = encoding_str
>>> +
>>> + return idregs
>>> +
>>> +if __name__ == "__main__":
>>> + # Single arg expected: the path to the Registers.json file
>>> + if len(sys.argv) < 2:
>>> + print("Usage: python scripts/update-aarch64-cpu-sysregs-header.py "
>>> + "<path_to_registers_json>")
>>> + sys.exit(1)
>>> + else:
>>> + json_file_path = sys.argv[1]
>>> +
>>> + extracted_registers = extract_idregs_from_registers_json(json_file_path)
>>> +
>>> + if extracted_registers:
>>> + output_list = extracted_registers.items()
>>> +
>>> + # Sort by register name
>>> + sorted_output = sorted(output_list, key=lambda item: item[0])
>>> +
>>> + # format lines as DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>)
>>> + final_output = ""
>>> + for reg_name, encoding in sorted_output:
>>> + reformatted_encoding = encoding.replace(" ", ", ")
>>> + final_output += f"DEF({reg_name}, {reformatted_encoding})\n"
>>> +
>>> + with open("target/arm/cpu-sysregs.h.inc", 'w') as f:
>>> + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
>>> + f.write("/* This file is autogenerated by ")
>>> + f.write("scripts/update-aarch64-cpu-sysregs-header.py */\n")
>>> + f.write("/* DEF(<name>, <op0>, <op1>, <crn>, <crm>, <op2>) */\n\n")
>>> + f.write(final_output)
>>> + print("updated target/arm/cpu-sysregs.h.inc")
>>> --
>>> 2.53.0
>>>
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 05/26] scripts: Introduce scripts/aarch64_sysreg_helpers module
2026-09-24 10:18 ` Khushit Shah
2026-09-24 10:23 ` Khushit Shah
@ 2026-09-29 15:14 ` Eric Auger
1 sibling, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-29 15:14 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Khushit,
On 9/24/26 12:18 PM, Khushit Shah wrote:
> Only few nits.
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> We plan to reuse get_opcode() and extract_idregs_from_registers_json()
>> functions in another script. So let's move them into a module
> Nit: fullstop.
yes
>
>> No functional change intended.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Reviewed-by: Khushit Shah <khushit.shah@nutanix.com>
>> ---
>> scripts/aarch64_sysreg_helpers.py | 121 +++++++++++++++++++
>> scripts/update-aarch64-cpu-sysregs-header.py | 97 +--------------
>> 2 files changed, 122 insertions(+), 96 deletions(-)
>> create mode 100644 scripts/aarch64_sysreg_helpers.py
>>
>> diff --git a/scripts/aarch64_sysreg_helpers.py b/scripts/aarch64_sysreg_helpers.py
>> new file mode 100644
>> index 0000000000..24bbc5bb3d
>> --- /dev/null
>> +++ b/scripts/aarch64_sysreg_helpers.py
>> @@ -0,0 +1,121 @@
>> +#!/usr/bin/env python3
>> +
>> +# Helpers used in aarch64 sysreg definition generation
>> +#
>> +# Copyright (C) 2026 Red Hat, Inc.
>> +#
>> +# Authors: Eric Auger <eric.auger@redhat.com>
>> +#
>> +# SPDX-License-Identifier: GPL-2.0-or-later
>> +
>> +
>> +import json
>> +import os
>> +
>> +def is_demux_register(r):
>> + name = r.get('name', '')
>> +
>> + if name.startswith("CCSIDR"):
>> + return True
>> +
>> + return False
>> +
>> +# Some regs have op code values like 000x, 001x. Anyway we don't need
>> +# them. Besides some regs are undesired in the generated file such as
>> +# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
>> +# are interested in and are tricky to decode as their system accessor
>> +# refer to MPIDR_EL1/MIDR_EL1 respectively
>> +
>> +skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
>> + 'VMPIDR_EL2', 'VPIDR_EL2']
>> +
>> +# returns the int value of a given @opcode for a reg @encoding
>> +def get_opcode(encoding, opcode):
>> + fvalue = encoding.get(opcode)
>> + if fvalue:
>> + value = fvalue.get('value')
>> + if isinstance(value, str):
>> + value = value.strip("'")
>> + value = int(value, 2)
>> + return value
>> + return -1
>> +
>> +def extract_idregs_from_registers_json(filename):
>> + """
>> + Load a Registers.json file and extract all ID registers, decode their
>> + opcode and dump the information in target/arm/cpu-sysregs.h.inc
> ^^ does not apply now.
indeed
>> +
>> + Args:
>> + filename (str): The path to the Registers.json
>> + returns:
>> + idregs: list of ID regs and their encoding
>> + """
>> + if not os.path.exists(filename):
>> + print(f"Error: {filename} could not be found!")
>> + return {}
>> +
>> + try:
>> + with open(filename, 'r') as f:
>> + register_data = json.load(f)
>> +
>> + except json.JSONDecodeError:
>> + print(f"Could not decode json from '{filename}'!")
>> + return {}
>> + except Exception as e:
>> + print(f"Unexpected error while reading {filename}: {e}")
>> + return {}
>> +
>> + registers = [
>> + r for r in register_data
>> + if isinstance(r, dict)
>> + and r.get('_type') == 'Register'
>> + and not is_demux_register(r)
> Can we put is_demux_register inside loop?
done
>
>> + ]
>> +
>> + idregs = {}
>> +
>> + # Some regs have op code values like 000x, 001x. Anyway we don't need
>> + # them. Besides some regs are undesired in the generated file such as
>> + # VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
>> + # are interested in and are tricky to decode as their system accessor
>> + # refer to MPIDR_EL1/MIDR_EL1 respectively
>> +
>> + skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
>> + 'VMPIDR_EL2', 'VPIDR_EL2’]
> I see the op1 of VMPIDR_EL2/VPIDR_EL2 is 0b100, why are they needed in the skip-list, as they will anyway be skipped...
see previous replies.
Note I have squashed the initial script + intro of the module + the
update because it is much simpler to maintain while staying functionaly
consistent.
Eric
>
> Warm Regards,
> Khushit
>> + for register in registers:
>> + reg_name = register.get('name')
>> +
>> + is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
>> +
>> + if reg_name and not is_skipped:
>> + accessors = register.get('accessors', [])
>> +
>> + for accessor in accessors:
>> + type = accessor.get('_type')
>> + if type in ['Accessors.SystemAccessor']:
>> + encoding_list = accessor.get('encoding')
>> +
>> + if isinstance(encoding_list, list) and encoding_list and \
>> + isinstance(encoding_list[0], dict):
>> + encoding_wrapper = encoding_list[0]
>> + encoding_source = encoding_wrapper.get('encodings', \
>> + encoding_wrapper)
>> +
>> + if isinstance(encoding_source, dict):
>> + op0 = get_opcode(encoding_source, 'op0')
>> + op1 = get_opcode(encoding_source, 'op1')
>> + op2 = get_opcode(encoding_source, 'op2')
>> + crn = get_opcode(encoding_source, 'CRn')
>> + crm = get_opcode(encoding_source, 'CRm')
>> + encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
>> +
>> + # ID regs are assumed within this scope
>> + if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
>> + crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
>> + idregs[reg_name] = encoding_str
>> +
>> + return idregs
>> +
>> +
>> +
>> diff --git a/scripts/update-aarch64-cpu-sysregs-header.py b/scripts/update-aarch64-cpu-sysregs-header.py
>> index ef1471a197..43107264e9 100755
>> --- a/scripts/update-aarch64-cpu-sysregs-header.py
>> +++ b/scripts/update-aarch64-cpu-sysregs-header.py
>> @@ -17,102 +17,7 @@
>> import json
>> import os
>> import sys
>> -
>> -def is_demux_register(r):
>> - name = r.get('name', '')
>> -
>> - if name.startswith("CCSIDR"):
>> - return True
>> -
>> - return False
>> -
>> -# Some regs have op code values like 000x, 001x. Anyway we don't need
>> -# them. Besides some regs are undesired in the generated file such as
>> -# VMPIDR_EL2 and VPIDR_EL2 which are outside of the IDreg scope we
>> -# are interested in and are tricky to decode as their system accessor
>> -# refer to MPIDR_EL1/MIDR_EL1 respectively
>> -
>> -skiplist = ['ALLINT', 'PM', 'S1_', 'S3_', 'SVCR', \
>> - 'VMPIDR_EL2', 'VPIDR_EL2']
>> -
>> -# returns the int value of a given @opcode for a reg @encoding
>> -def get_opcode(encoding, opcode):
>> - fvalue = encoding.get(opcode)
>> - if fvalue:
>> - value = fvalue.get('value')
>> - if isinstance(value, str):
>> - value = value.strip("'")
>> - value = int(value, 2)
>> - return value
>> - return -1
>> -
>> -def extract_idregs_from_registers_json(filename):
>> - """
>> - Load a Registers.json file and extract all ID registers, decode their
>> - opcode and dump the information in target/arm/cpu-sysregs.h.inc
>> -
>> - Args:
>> - filename (str): The path to the Registers.json
>> - returns:
>> - idregs: list of ID regs and their encoding
>> - """
>> - if not os.path.exists(filename):
>> - print(f"Error: {filename} could not be found!")
>> - return {}
>> -
>> - try:
>> - with open(filename, 'r') as f:
>> - register_data = json.load(f)
>> -
>> - except json.JSONDecodeError:
>> - print(f"Could not decode json from '{filename}'!")
>> - return {}
>> - except Exception as e:
>> - print(f"Unexpected error while reading {filename}: {e}")
>> - return {}
>> -
>> - registers = [
>> - r for r in register_data
>> - if isinstance(r, dict)
>> - and r.get('_type') == 'Register'
>> - and not is_demux_register(r)
>> - ]
>> -
>> - idregs = {}
>> -
>> - for register in registers:
>> - reg_name = register.get('name')
>> -
>> - is_skipped = any(term in (reg_name or "").upper() for term in skiplist)
>> -
>> - if reg_name and not is_skipped:
>> - accessors = register.get('accessors', [])
>> -
>> - for accessor in accessors:
>> - type = accessor.get('_type')
>> - if type in ['Accessors.SystemAccessor']:
>> - encoding_list = accessor.get('encoding')
>> -
>> - if isinstance(encoding_list, list) and encoding_list and \
>> - isinstance(encoding_list[0], dict):
>> - encoding_wrapper = encoding_list[0]
>> - encoding_source = encoding_wrapper.get('encodings', \
>> - encoding_wrapper)
>> -
>> - if isinstance(encoding_source, dict):
>> - op0 = get_opcode(encoding_source, 'op0')
>> - op1 = get_opcode(encoding_source, 'op1')
>> - op2 = get_opcode(encoding_source, 'op2')
>> - crn = get_opcode(encoding_source, 'CRn')
>> - crm = get_opcode(encoding_source, 'CRm')
>> - encoding_str=f"{op0} {op1} {crn} {crm} {op2}"
>> -
>> - # ID regs are assumed within this scope
>> - if op0 == 3 and (op1 == 0 or op1 == 1 or op1 == 3) and \
>> - crn == 0 and (crm >= 0 and crm <= 7) and (op2 >= 0 and op2 <= 7):
>> - idregs[reg_name] = encoding_str
>> -
>> - return idregs
>> +from aarch64_sysreg_helpers import extract_idregs_from_registers_json
>>
>> if __name__ == "__main__":
>> # Single arg expected: the path to the Registers.json file
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 07/26] target/arm/cpu-idregs.h.inc: generate with script
2026-09-25 11:19 ` Khushit Shah
@ 2026-09-29 16:55 ` Eric Auger
2026-09-30 5:40 ` Khushit Shah
0 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-29 16:55 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/25/26 1:19 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Generate ID reg definitions with the scripts/update-aarch64-cpu-sysreg-properties.py
>> based on AARCHMRS_OPENSOURCE_A_profile_FAT-2026-03 Registers.json
>>
>> Each register and fields are described with this pattern:
>>
>> IDREG_START(REG)
>> IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
>> ...
>> IDREG_END(REG)
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Suggested-by: Khushit Shah <khushit.shah@nutanix.com>
>> Suggested-by: Shaju Abraham <shaju.abraham@nutanix.com>
>> ---
>> target/arm/cpu-idregs.h.inc | 607 ++++++++++++++++++++++++++++++++++++
>> 1 file changed, 607 insertions(+)
>> create mode 100644 target/arm/cpu-idregs.h.inc
>>
>> diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
>> new file mode 100644
>> index 0000000000..c9745e2fb6
>> --- /dev/null
>> +++ b/target/arm/cpu-idregs.h.inc
>> @@ -0,0 +1,607 @@
>> +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
>> +
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +
>> +/* IDREG_START(REG) */
>> +/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */
>> +/* ... */
>> +/* IDREG_END(REG) */
>> +
>> +IDREG_START(AIDR_EL1)
>> +IDREG_END(AIDR_EL1)
>> +
>> +IDREG_START(CLIDR_EL1)
>> + IDREG_FIELD(CLIDR_EL1, Ttype7, 45, 2)
>> + IDREG_FIELD(CLIDR_EL1, Ttype6, 43, 2)
>> + IDREG_FIELD(CLIDR_EL1, Ttype5, 41, 2)
>> + IDREG_FIELD(CLIDR_EL1, Ttype4, 39, 2)
>> + IDREG_FIELD(CLIDR_EL1, Ttype3, 37, 2)
>> + IDREG_FIELD(CLIDR_EL1, Ttype2, 35, 2)
>> + IDREG_FIELD(CLIDR_EL1, Ttype1, 33, 2)
>> + IDREG_FIELD(CLIDR_EL1, ICB, 30, 3)
>> + IDREG_FIELD(CLIDR_EL1, LoUU, 27, 3)
>> + IDREG_FIELD(CLIDR_EL1, LoC, 24, 3)
>> + IDREG_FIELD(CLIDR_EL1, LoUIS, 21, 3)
>> + IDREG_FIELD(CLIDR_EL1, Ctype7, 18, 3)
>> + IDREG_FIELD(CLIDR_EL1, Ctype6, 15, 3)
>> + IDREG_FIELD(CLIDR_EL1, Ctype5, 12, 3)
>> + IDREG_FIELD(CLIDR_EL1, Ctype4, 9, 3)
>> + IDREG_FIELD(CLIDR_EL1, Ctype3, 6, 3)
>> + IDREG_FIELD(CLIDR_EL1, Ctype2, 3, 3)
>> + IDREG_FIELD(CLIDR_EL1, Ctype1, 0, 3)
>> +IDREG_END(CLIDR_EL1)
>> +
>> +IDREG_START(CTR_EL0)
>> + IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
>> + IDREG_FIELD(CTR_EL0, DIC, 29, 1)
>> + IDREG_FIELD(CTR_EL0, IDC, 28, 1)
>> + IDREG_FIELD(CTR_EL0, CWG, 24, 4)
>> + IDREG_FIELD(CTR_EL0, ERG, 20, 4)
>> + IDREG_FIELD(CTR_EL0, DminLine, 16, 4)
>> + IDREG_FIELD(CTR_EL0, L1Ip, 14, 2)
>> + IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
>> +IDREG_END(CTR_EL0)
>> +
>> +IDREG_START(DCZID_EL0)
>> + IDREG_FIELD(DCZID_EL0, TBS, 5, 4)
>> + IDREG_FIELD(DCZID_EL0, DZP, 4, 1)
>> + IDREG_FIELD(DCZID_EL0, BS, 0, 4)
>> +IDREG_END(DCZID_EL0)
>> +
>> +IDREG_START(GMID_EL1)
>> + IDREG_FIELD(GMID_EL1, BS, 0, 4)
>> +IDREG_END(GMID_EL1)
>> +
>> +IDREG_START(ID_AA64AFR0_EL1)
>> +IDREG_END(ID_AA64AFR0_EL1)
>> +
>> +IDREG_START(ID_AA64AFR1_EL1)
>> +IDREG_END(ID_AA64AFR1_EL1)
>> +
>> +IDREG_START(ID_AA64DFR0_EL1)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, HPMN0, 60, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, BRBE, 52, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, MTPMU, 48, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, PMSVer, 32, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, WRPs, 20, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, PMSS, 16, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, BRPs, 12, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, PMUVer, 8, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceVer, 4, 4)
>> + IDREG_FIELD(ID_AA64DFR0_EL1, DebugVer, 0, 4)
>> +IDREG_END(ID_AA64DFR0_EL1)
>> +
>> +IDREG_START(ID_AA64DFR1_EL1)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, DPFZS, 52, 4)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, EBEP, 48, 4)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, ITE, 44, 4)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, ABLE, 40, 4)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, SPMU, 32, 4)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, WRPs, 16, 8)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, BRPs, 8, 8)
>> + IDREG_FIELD(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
>> +IDREG_END(ID_AA64DFR1_EL1)
>> +
>> +IDREG_START(ID_AA64DFR2_EL1)
>> + IDREG_FIELD(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
>> + IDREG_FIELD(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
>> + IDREG_FIELD(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
>> + IDREG_FIELD(ID_AA64DFR2_EL1, BWE, 4, 4)
>> + IDREG_FIELD(ID_AA64DFR2_EL1, STEP, 0, 4)
>> +IDREG_END(ID_AA64DFR2_EL1)
>> +
>> +IDREG_START(ID_AA64FPFR0_EL1)
>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
>> +IDREG_END(ID_AA64FPFR0_EL1)
>> +
>> +IDREG_START(ID_AA64ISAR0_EL1)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, RNDR, 60, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, TLB, 56, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, TS, 52, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, FHM, 48, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, DP, 44, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SM4, 40, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SM3, 36, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA3, 32, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, RDM, 28, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, Atomic, 20, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, CRC32, 16, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA2, 12, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA1, 8, 4)
>> + IDREG_FIELD(ID_AA64ISAR0_EL1, AES, 4, 4)
>> +IDREG_END(ID_AA64ISAR0_EL1)
>> +
>> +IDREG_START(ID_AA64ISAR1_EL1)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, LS64, 60, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, XS, 56, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, I8MM, 52, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, DGH, 48, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, BF16, 44, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, SB, 36, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, GPI, 28, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, GPA, 24, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, FCMA, 16, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, API, 8, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, APA, 4, 4)
>> + IDREG_FIELD(ID_AA64ISAR1_EL1, DPB, 0, 4)
>> +IDREG_END(ID_AA64ISAR1_EL1)
>> +
>> +IDREG_START(ID_AA64ISAR2_EL1)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, LUT, 56, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, CSSC, 52, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, BC, 20, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, MOPS, 16, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, APA3, 12, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, GPA3, 8, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, RPRES, 4, 4)
>> + IDREG_FIELD(ID_AA64ISAR2_EL1, WFxT, 0, 4)
>> +IDREG_END(ID_AA64ISAR2_EL1)
>> +
>> +IDREG_START(ID_AA64ISAR3_EL1)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSCP, 44, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, MTETC, 36, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSUI, 24, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSFE, 16, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, PACM, 12, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
>> + IDREG_FIELD(ID_AA64ISAR3_EL1, CPA, 0, 4)
>> +IDREG_END(ID_AA64ISAR3_EL1)
>> +
>> +IDREG_START(ID_AA64MMFR0_EL1)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, ECV, 60, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, FGT, 56, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, ExS, 44, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4, 28, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64, 24, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16, 20, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
>> + IDREG_FIELD(ID_AA64MMFR0_EL1, PARange, 0, 4)
>> +IDREG_END(ID_AA64MMFR0_EL1)
>> +
>> +IDREG_START(ID_AA64MMFR1_EL1)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, CMOW, 56, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, AFP, 44, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, HCX, 40, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, ETS, 36, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, TWED, 32, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, XNX, 28, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, PAN, 20, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, LO, 16, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, HPDS, 12, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, VH, 8, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
>> + IDREG_FIELD(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
>> +IDREG_END(ID_AA64MMFR1_EL1)
>> +
>> +IDREG_START(ID_AA64MMFR2_EL1)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, E0PD, 60, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, EVT, 56, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, BBM, 52, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, TTL, 48, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, FWB, 40, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, IDS, 36, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, AT, 32, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, ST, 28, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, NV, 24, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, VARange, 16, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, IESB, 12, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, LSM, 8, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, UAO, 4, 4)
>> + IDREG_FIELD(ID_AA64MMFR2_EL1, CnP, 0, 4)
>> +IDREG_END(ID_AA64MMFR2_EL1)
>> +
>> +IDREG_START(ID_AA64MMFR3_EL1)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, ADERR, 56, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, SDERR, 52, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, ANERR, 44, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, SNERR, 40, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, D128_2, 36, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, D128, 32, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, MEC, 28, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, AIE, 24, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S2POE, 20, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S1POE, 16, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
>> + IDREG_FIELD(ID_AA64MMFR3_EL1, TCRX, 0, 4)
>> +IDREG_END(ID_AA64MMFR3_EL1)
>> +
>> +IDREG_START(ID_AA64MMFR4_EL1)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, SCRX, 56, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, TEV, 52, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, TPS, 48, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, TLBID, 40, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, EAESR, 32, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, E2H0, 24, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, ASID2, 8, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, EIESB, 4, 4)
>> + IDREG_FIELD(ID_AA64MMFR4_EL1, PoPS, 0, 4)
>> +IDREG_END(ID_AA64MMFR4_EL1)
>> +
>> +IDREG_START(ID_AA64PFR0_EL1)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, CSV3, 60, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, CSV2, 56, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, RME, 52, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, DIT, 48, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, AMU, 44, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, MPAM, 40, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, SEL2, 36, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, SVE, 32, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, RAS, 28, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, GIC, 24, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, FP, 16, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL3, 12, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL2, 8, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL1, 4, 4)
>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL0, 0, 4)
>> +IDREG_END(ID_AA64PFR0_EL1)
>> +
>> +IDREG_START(ID_AA64PFR1_EL1)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, PFAR, 60, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, DF2, 56, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, MTEX, 52, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, THE, 48, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, GCS, 44, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, NMI, 36, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, SME, 24, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, MTE, 8, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, SSBS, 4, 4)
>> + IDREG_FIELD(ID_AA64PFR1_EL1, BT, 0, 4)
>> +IDREG_END(ID_AA64PFR1_EL1)
>> +
>> +IDREG_START(ID_AA64PFR2_EL1)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTETC, 40, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTE, 36, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, FPMR, 32, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, MPAM2, 28, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, FGDT, 24, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, UINJ, 16, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, GCIE, 12, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
>> +IDREG_END(ID_AA64PFR2_EL1)
>> +
>> +IDREG_START(ID_AA64SMFR0_EL1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, FA64, 63, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, LUT6, 61, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SMEver, 56, 4)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, I16I64, 52, 4)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F64F64, 48, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, I16I32, 44, 4)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, B16B16, 43, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F16F16, 42, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F8F16, 41, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F8F32, 40, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, I8I32, 36, 4)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F16F32, 35, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, B16F32, 34, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F32F32, 32, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, AES, 24, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, STMOP, 16, 1)
>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
>> +IDREG_END(ID_AA64SMFR0_EL1)
>> +
>> +IDREG_START(ID_AA64ZFR0_EL1)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, F64MM, 56, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, F32MM, 52, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, F16MM, 48, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, I8MM, 44, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, SM4, 40, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, SHA3, 32, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, B16B16, 24, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, BF16, 20, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, AES, 4, 4)
>> + IDREG_FIELD(ID_AA64ZFR0_EL1, SVEver, 0, 4)
>> +IDREG_END(ID_AA64ZFR0_EL1)
>> +
>> +IDREG_START(ID_AFR0_EL1)
>> +IDREG_END(ID_AFR0_EL1)
>> +
>> +IDREG_START(ID_DFR0_EL1)
>> + IDREG_FIELD(ID_DFR0_EL1, TraceFilt, 28, 4)
>> + IDREG_FIELD(ID_DFR0_EL1, PerfMon, 24, 4)
>> + IDREG_FIELD(ID_DFR0_EL1, MProfDbg, 20, 4)
>> + IDREG_FIELD(ID_DFR0_EL1, MMapTrc, 16, 4)
>> + IDREG_FIELD(ID_DFR0_EL1, CopTrc, 12, 4)
>> + IDREG_FIELD(ID_DFR0_EL1, MMapDbg, 8, 4)
>> + IDREG_FIELD(ID_DFR0_EL1, CopSDbg, 4, 4)
>> + IDREG_FIELD(ID_DFR0_EL1, CopDbg, 0, 4)
>> +IDREG_END(ID_DFR0_EL1)
>> +
>> +IDREG_START(ID_DFR1_EL1)
>> + IDREG_FIELD(ID_DFR1_EL1, HPMN0, 4, 4)
>> + IDREG_FIELD(ID_DFR1_EL1, MTPMU, 0, 4)
>> +IDREG_END(ID_DFR1_EL1)
>> +
>> +IDREG_START(ID_ISAR0_EL1)
>> + IDREG_FIELD(ID_ISAR0_EL1, Divide, 24, 4)
>> + IDREG_FIELD(ID_ISAR0_EL1, Debug, 20, 4)
>> + IDREG_FIELD(ID_ISAR0_EL1, Coproc, 16, 4)
>> + IDREG_FIELD(ID_ISAR0_EL1, CmpBranch, 12, 4)
>> + IDREG_FIELD(ID_ISAR0_EL1, BitField, 8, 4)
>> + IDREG_FIELD(ID_ISAR0_EL1, BitCount, 4, 4)
>> + IDREG_FIELD(ID_ISAR0_EL1, Swap, 0, 4)
>> +IDREG_END(ID_ISAR0_EL1)
>> +
>> +IDREG_START(ID_ISAR1_EL1)
>> + IDREG_FIELD(ID_ISAR1_EL1, Jazelle, 28, 4)
>> + IDREG_FIELD(ID_ISAR1_EL1, Interwork, 24, 4)
>> + IDREG_FIELD(ID_ISAR1_EL1, Immediate, 20, 4)
>> + IDREG_FIELD(ID_ISAR1_EL1, IfThen, 16, 4)
>> + IDREG_FIELD(ID_ISAR1_EL1, Extend, 12, 4)
>> + IDREG_FIELD(ID_ISAR1_EL1, Except_AR, 8, 4)
>> + IDREG_FIELD(ID_ISAR1_EL1, Except, 4, 4)
>> + IDREG_FIELD(ID_ISAR1_EL1, Endian, 0, 4)
>> +IDREG_END(ID_ISAR1_EL1)
>> +
>> +IDREG_START(ID_ISAR2_EL1)
>> + IDREG_FIELD(ID_ISAR2_EL1, Reversal, 28, 4)
>> + IDREG_FIELD(ID_ISAR2_EL1, PSR_AR, 24, 4)
>> + IDREG_FIELD(ID_ISAR2_EL1, MultU, 20, 4)
>> + IDREG_FIELD(ID_ISAR2_EL1, MultS, 16, 4)
>> + IDREG_FIELD(ID_ISAR2_EL1, Mult, 12, 4)
>> + IDREG_FIELD(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
>> + IDREG_FIELD(ID_ISAR2_EL1, MemHint, 4, 4)
>> + IDREG_FIELD(ID_ISAR2_EL1, LoadStore, 0, 4)
>> +IDREG_END(ID_ISAR2_EL1)
>> +
>> +IDREG_START(ID_ISAR3_EL1)
>> + IDREG_FIELD(ID_ISAR3_EL1, T32EE, 28, 4)
>> + IDREG_FIELD(ID_ISAR3_EL1, TrueNOP, 24, 4)
>> + IDREG_FIELD(ID_ISAR3_EL1, T32Copy, 20, 4)
>> + IDREG_FIELD(ID_ISAR3_EL1, TabBranch, 16, 4)
>> + IDREG_FIELD(ID_ISAR3_EL1, SynchPrim, 12, 4)
>> + IDREG_FIELD(ID_ISAR3_EL1, SVC, 8, 4)
>> + IDREG_FIELD(ID_ISAR3_EL1, SIMD, 4, 4)
>> + IDREG_FIELD(ID_ISAR3_EL1, Saturate, 0, 4)
>> +IDREG_END(ID_ISAR3_EL1)
>> +
>> +IDREG_START(ID_ISAR4_EL1)
>> + IDREG_FIELD(ID_ISAR4_EL1, SWP_frac, 28, 4)
>> + IDREG_FIELD(ID_ISAR4_EL1, PSR_M, 24, 4)
>> + IDREG_FIELD(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
>> + IDREG_FIELD(ID_ISAR4_EL1, Barrier, 16, 4)
>> + IDREG_FIELD(ID_ISAR4_EL1, SMC, 12, 4)
>> + IDREG_FIELD(ID_ISAR4_EL1, Writeback, 8, 4)
>> + IDREG_FIELD(ID_ISAR4_EL1, WithShifts, 4, 4)
>> + IDREG_FIELD(ID_ISAR4_EL1, Unpriv, 0, 4)
>> +IDREG_END(ID_ISAR4_EL1)
>> +
>> +IDREG_START(ID_ISAR5_EL1)
>> + IDREG_FIELD(ID_ISAR5_EL1, VCMA, 28, 4)
>> + IDREG_FIELD(ID_ISAR5_EL1, RDM, 24, 4)
>> + IDREG_FIELD(ID_ISAR5_EL1, CRC32, 16, 4)
>> + IDREG_FIELD(ID_ISAR5_EL1, SHA2, 12, 4)
>> + IDREG_FIELD(ID_ISAR5_EL1, SHA1, 8, 4)
>> + IDREG_FIELD(ID_ISAR5_EL1, AES, 4, 4)
>> + IDREG_FIELD(ID_ISAR5_EL1, SEVL, 0, 4)
>> +IDREG_END(ID_ISAR5_EL1)
>> +
>> +IDREG_START(ID_ISAR6_EL1)
>> + IDREG_FIELD(ID_ISAR6_EL1, CLRBHB, 28, 4)
>> + IDREG_FIELD(ID_ISAR6_EL1, I8MM, 24, 4)
>> + IDREG_FIELD(ID_ISAR6_EL1, BF16, 20, 4)
>> + IDREG_FIELD(ID_ISAR6_EL1, SPECRES, 16, 4)
>> + IDREG_FIELD(ID_ISAR6_EL1, SB, 12, 4)
>> + IDREG_FIELD(ID_ISAR6_EL1, FHM, 8, 4)
>> + IDREG_FIELD(ID_ISAR6_EL1, DP, 4, 4)
>> + IDREG_FIELD(ID_ISAR6_EL1, JSCVT, 0, 4)
>> +IDREG_END(ID_ISAR6_EL1)
>> +
>> +IDREG_START(ID_MMFR0_EL1)
>> + IDREG_FIELD(ID_MMFR0_EL1, InnerShr, 28, 4)
>> + IDREG_FIELD(ID_MMFR0_EL1, FCSE, 24, 4)
>> + IDREG_FIELD(ID_MMFR0_EL1, AuxReg, 20, 4)
>> + IDREG_FIELD(ID_MMFR0_EL1, TCM, 16, 4)
>> + IDREG_FIELD(ID_MMFR0_EL1, ShareLvl, 12, 4)
>> + IDREG_FIELD(ID_MMFR0_EL1, OuterShr, 8, 4)
>> + IDREG_FIELD(ID_MMFR0_EL1, PMSA, 4, 4)
>> + IDREG_FIELD(ID_MMFR0_EL1, VMSA, 0, 4)
>> +IDREG_END(ID_MMFR0_EL1)
>> +
>> +IDREG_START(ID_MMFR1_EL1)
>> + IDREG_FIELD(ID_MMFR1_EL1, BPred, 28, 4)
>> + IDREG_FIELD(ID_MMFR1_EL1, L1TstCln, 24, 4)
>> + IDREG_FIELD(ID_MMFR1_EL1, L1Uni, 20, 4)
>> + IDREG_FIELD(ID_MMFR1_EL1, L1Hvd, 16, 4)
>> + IDREG_FIELD(ID_MMFR1_EL1, L1UniSW, 12, 4)
>> + IDREG_FIELD(ID_MMFR1_EL1, L1HvdSW, 8, 4)
>> + IDREG_FIELD(ID_MMFR1_EL1, L1UniVA, 4, 4)
>> + IDREG_FIELD(ID_MMFR1_EL1, L1HvdVA, 0, 4)
>> +IDREG_END(ID_MMFR1_EL1)
>> +
>> +IDREG_START(ID_MMFR2_EL1)
>> + IDREG_FIELD(ID_MMFR2_EL1, HWAccFlg, 28, 4)
>> + IDREG_FIELD(ID_MMFR2_EL1, WFIStall, 24, 4)
>> + IDREG_FIELD(ID_MMFR2_EL1, MemBarr, 20, 4)
>> + IDREG_FIELD(ID_MMFR2_EL1, UniTLB, 16, 4)
>> + IDREG_FIELD(ID_MMFR2_EL1, HvdTLB, 12, 4)
>> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdRng, 8, 4)
>> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdBG, 4, 4)
>> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdFG, 0, 4)
>> +IDREG_END(ID_MMFR2_EL1)
>> +
>> +IDREG_START(ID_MMFR3_EL1)
>> + IDREG_FIELD(ID_MMFR3_EL1, Supersec, 28, 4)
>> + IDREG_FIELD(ID_MMFR3_EL1, CMemSz, 24, 4)
>> + IDREG_FIELD(ID_MMFR3_EL1, CohWalk, 20, 4)
>> + IDREG_FIELD(ID_MMFR3_EL1, PAN, 16, 4)
>> + IDREG_FIELD(ID_MMFR3_EL1, MaintBcst, 12, 4)
>> + IDREG_FIELD(ID_MMFR3_EL1, BPMaint, 8, 4)
>> + IDREG_FIELD(ID_MMFR3_EL1, CMaintSW, 4, 4)
>> + IDREG_FIELD(ID_MMFR3_EL1, CMaintVA, 0, 4)
>> +IDREG_END(ID_MMFR3_EL1)
>> +
>> +IDREG_START(ID_MMFR4_EL1)
>> + IDREG_FIELD(ID_MMFR4_EL1, EVT, 28, 4)
>> + IDREG_FIELD(ID_MMFR4_EL1, CCIDX, 24, 4)
>> + IDREG_FIELD(ID_MMFR4_EL1, LSM, 20, 4)
>> + IDREG_FIELD(ID_MMFR4_EL1, HPDS, 16, 4)
>> + IDREG_FIELD(ID_MMFR4_EL1, CnP, 12, 4)
>> + IDREG_FIELD(ID_MMFR4_EL1, XNX, 8, 4)
>> + IDREG_FIELD(ID_MMFR4_EL1, AC2, 4, 4)
>> + IDREG_FIELD(ID_MMFR4_EL1, SpecSEI, 0, 4)
>> +IDREG_END(ID_MMFR4_EL1)
>> +
>> +IDREG_START(ID_MMFR5_EL1)
>> + IDREG_FIELD(ID_MMFR5_EL1, nTLBPA, 4, 4)
>> + IDREG_FIELD(ID_MMFR5_EL1, ETS, 0, 4)
>> +IDREG_END(ID_MMFR5_EL1)
>> +
>> +IDREG_START(ID_PFR0_EL1)
>> + IDREG_FIELD(ID_PFR0_EL1, RAS, 28, 4)
>> + IDREG_FIELD(ID_PFR0_EL1, DIT, 24, 4)
>> + IDREG_FIELD(ID_PFR0_EL1, AMU, 20, 4)
>> + IDREG_FIELD(ID_PFR0_EL1, CSV2, 16, 4)
>> + IDREG_FIELD(ID_PFR0_EL1, State3, 12, 4)
>> + IDREG_FIELD(ID_PFR0_EL1, State2, 8, 4)
>> + IDREG_FIELD(ID_PFR0_EL1, State1, 4, 4)
>> + IDREG_FIELD(ID_PFR0_EL1, State0, 0, 4)
>> +IDREG_END(ID_PFR0_EL1)
>> +
>> +IDREG_START(ID_PFR1_EL1)
>> + IDREG_FIELD(ID_PFR1_EL1, GIC, 28, 4)
>> + IDREG_FIELD(ID_PFR1_EL1, Virt_frac, 24, 4)
>> + IDREG_FIELD(ID_PFR1_EL1, Sec_frac, 20, 4)
>> + IDREG_FIELD(ID_PFR1_EL1, GenTimer, 16, 4)
>> + IDREG_FIELD(ID_PFR1_EL1, Virtualization, 12, 4)
>> + IDREG_FIELD(ID_PFR1_EL1, MProgMod, 8, 4)
>> + IDREG_FIELD(ID_PFR1_EL1, Security, 4, 4)
>> + IDREG_FIELD(ID_PFR1_EL1, ProgMod, 0, 4)
>> +IDREG_END(ID_PFR1_EL1)
>> +
>> +IDREG_START(ID_PFR2_EL1)
>> IDREG_FIELD(ID_PFR2_EL1, RAS_frac, 8, 4)
>> + IDREG_FIELD(ID_PFR2_EL1, SSBS, 4, 4)
>> + IDREG_FIELD(ID_PFR2_EL1, CSV3, 0, 4)
>> +IDREG_END(ID_PFR2_EL1)
>> +
>> +IDREG_START(MIDR_EL1)
>> + IDREG_FIELD(MIDR_EL1, Implementer, 24, 8)
>> + IDREG_FIELD(MIDR_EL1, Variant, 20, 4)
>> + IDREG_FIELD(MIDR_EL1, Architecture, 16, 4)
>> + IDREG_FIELD(MIDR_EL1, PartNum, 4, 12)
>> + IDREG_FIELD(MIDR_EL1, Revision, 0, 4)
>> +IDREG_END(MIDR_EL1)
>> +
>> +IDREG_START(MPIDR_EL1)
>> + IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
>> + IDREG_FIELD(MPIDR_EL1, U, 30, 1)
>> + IDREG_FIELD(MPIDR_EL1, MT, 24, 1)
>> + IDREG_FIELD(MPIDR_EL1, Aff2, 16, 8)
>> + IDREG_FIELD(MPIDR_EL1, Aff1, 8, 8)
>> + IDREG_FIELD(MPIDR_EL1, Aff0, 0, 8)
>> +IDREG_END(MPIDR_EL1)
>> +
>> +IDREG_START(MVFR0_EL1)
>> + IDREG_FIELD(MVFR0_EL1, FPRound, 28, 4)
>> + IDREG_FIELD(MVFR0_EL1, FPShVec, 24, 4)
>> + IDREG_FIELD(MVFR0_EL1, FPSqrt, 20, 4)
>> + IDREG_FIELD(MVFR0_EL1, FPDivide, 16, 4)
>> + IDREG_FIELD(MVFR0_EL1, FPTrap, 12, 4)
>> + IDREG_FIELD(MVFR0_EL1, FPDP, 8, 4)
>> + IDREG_FIELD(MVFR0_EL1, FPSP, 4, 4)
>> + IDREG_FIELD(MVFR0_EL1, SIMDReg, 0, 4)
>> +IDREG_END(MVFR0_EL1)
>> +
>> +IDREG_START(MVFR1_EL1)
>> + IDREG_FIELD(MVFR1_EL1, SIMDFMAC, 28, 4)
>> + IDREG_FIELD(MVFR1_EL1, FPHP, 24, 4)
>> + IDREG_FIELD(MVFR1_EL1, SIMDHP, 20, 4)
>> + IDREG_FIELD(MVFR1_EL1, SIMDSP, 16, 4)
>> + IDREG_FIELD(MVFR1_EL1, SIMDInt, 12, 4)
>> + IDREG_FIELD(MVFR1_EL1, SIMDLS, 8, 4)
>> + IDREG_FIELD(MVFR1_EL1, FPDNaN, 4, 4)
>> + IDREG_FIELD(MVFR1_EL1, FPFtZ, 0, 4)
>> +IDREG_END(MVFR1_EL1)
>> +
>> +IDREG_START(MVFR2_EL1)
>> + IDREG_FIELD(MVFR2_EL1, FPMisc, 4, 4)
>> + IDREG_FIELD(MVFR2_EL1, SIMDMisc, 0, 4)
>> +IDREG_END(MVFR2_EL1)
>> +
>> +IDREG_START(REVIDR_EL1)
>> +IDREG_END(REVIDR_EL1)
>> +
>> +IDREG_START(SMIDR_EL1)
>> + IDREG_FIELD(SMIDR_EL1, NSMC, 56, 4)
>> + IDREG_FIELD(SMIDR_EL1, HIP, 52, 4)
>> + IDREG_FIELD(SMIDR_EL1, Affinity2, 32, 20)
>> + IDREG_FIELD(SMIDR_EL1, Implementer, 24, 8)
>> + IDREG_FIELD(SMIDR_EL1, Revision, 16, 8)
>> + IDREG_FIELD(SMIDR_EL1, SMPS, 15, 1)
>> + IDREG_FIELD(SMIDR_EL1, SH, 13, 2)
>> + IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
>> +IDREG_END(SMIDR_EL1)
>> +
>> --
>> 2.53.0
>>
> what is the point of a separate patch for reserved fields?
> [PATCH v9 19/26] target/arm/cpu-idregs.h.inc: Generate reserved fields
> Can we squash these together?
Well I think the support of RES fields introduce quite a significant
complexity in scripts/update-aarch64-cpu-sysreg-properties.py,
especially because several RESx fields can be in the same reg, inducing
ordering issues which I should have better commented ;-) Also having it
incremental allows to easily diff the generated file.
So if you don't mind I prefer keeping it separate. I will endeavour to
add more comments too
Eric
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 07/26] target/arm/cpu-idregs.h.inc: generate with script
2026-09-29 16:55 ` Eric Auger
@ 2026-09-30 5:40 ` Khushit Shah
2026-09-30 6:34 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-30 5:40 UTC (permalink / raw)
To: eric.auger@redhat.com
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 29 Sep 2026, at 10:25 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
>
>
> On 9/25/26 1:19 PM, Khushit Shah wrote:
>>
>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>
>>> !-------------------------------------------------------------------|
>>> CAUTION: External Email
>>>
>>> |-------------------------------------------------------------------!
>>>
>>> Generate ID reg definitions with the scripts/update-aarch64-cpu-sysreg-properties.py
>>> based on AARCHMRS_OPENSOURCE_A_profile_FAT-2026-03 Registers.json
>>>
>>> Each register and fields are described with this pattern:
>>>
>>> IDREG_START(REG)
>>> IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
>>> ...
>>> IDREG_END(REG)
>>>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>> Suggested-by: Khushit Shah <khushit.shah@nutanix.com>
>>> Suggested-by: Shaju Abraham <shaju.abraham@nutanix.com>
>>> ---
>>> target/arm/cpu-idregs.h.inc | 607 ++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 607 insertions(+)
>>> create mode 100644 target/arm/cpu-idregs.h.inc
>>>
>>> diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
>>> new file mode 100644
>>> index 0000000000..c9745e2fb6
>>> --- /dev/null
>>> +++ b/target/arm/cpu-idregs.h.inc
>>> @@ -0,0 +1,607 @@
>>> +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
>>> +
>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>>> +
>>> +/* IDREG_START(REG) */
>>> +/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */
>>> +/* ... */
>>> +/* IDREG_END(REG) */
>>> +
>>> +IDREG_START(AIDR_EL1)
>>> +IDREG_END(AIDR_EL1)
>>> +
>>> +IDREG_START(CLIDR_EL1)
>>> + IDREG_FIELD(CLIDR_EL1, Ttype7, 45, 2)
>>> + IDREG_FIELD(CLIDR_EL1, Ttype6, 43, 2)
>>> + IDREG_FIELD(CLIDR_EL1, Ttype5, 41, 2)
>>> + IDREG_FIELD(CLIDR_EL1, Ttype4, 39, 2)
>>> + IDREG_FIELD(CLIDR_EL1, Ttype3, 37, 2)
>>> + IDREG_FIELD(CLIDR_EL1, Ttype2, 35, 2)
>>> + IDREG_FIELD(CLIDR_EL1, Ttype1, 33, 2)
>>> + IDREG_FIELD(CLIDR_EL1, ICB, 30, 3)
>>> + IDREG_FIELD(CLIDR_EL1, LoUU, 27, 3)
>>> + IDREG_FIELD(CLIDR_EL1, LoC, 24, 3)
>>> + IDREG_FIELD(CLIDR_EL1, LoUIS, 21, 3)
>>> + IDREG_FIELD(CLIDR_EL1, Ctype7, 18, 3)
>>> + IDREG_FIELD(CLIDR_EL1, Ctype6, 15, 3)
>>> + IDREG_FIELD(CLIDR_EL1, Ctype5, 12, 3)
>>> + IDREG_FIELD(CLIDR_EL1, Ctype4, 9, 3)
>>> + IDREG_FIELD(CLIDR_EL1, Ctype3, 6, 3)
>>> + IDREG_FIELD(CLIDR_EL1, Ctype2, 3, 3)
>>> + IDREG_FIELD(CLIDR_EL1, Ctype1, 0, 3)
>>> +IDREG_END(CLIDR_EL1)
>>> +
>>> +IDREG_START(CTR_EL0)
>>> + IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
>>> + IDREG_FIELD(CTR_EL0, DIC, 29, 1)
>>> + IDREG_FIELD(CTR_EL0, IDC, 28, 1)
>>> + IDREG_FIELD(CTR_EL0, CWG, 24, 4)
>>> + IDREG_FIELD(CTR_EL0, ERG, 20, 4)
>>> + IDREG_FIELD(CTR_EL0, DminLine, 16, 4)
>>> + IDREG_FIELD(CTR_EL0, L1Ip, 14, 2)
>>> + IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
>>> +IDREG_END(CTR_EL0)
>>> +
>>> +IDREG_START(DCZID_EL0)
>>> + IDREG_FIELD(DCZID_EL0, TBS, 5, 4)
>>> + IDREG_FIELD(DCZID_EL0, DZP, 4, 1)
>>> + IDREG_FIELD(DCZID_EL0, BS, 0, 4)
>>> +IDREG_END(DCZID_EL0)
>>> +
>>> +IDREG_START(GMID_EL1)
>>> + IDREG_FIELD(GMID_EL1, BS, 0, 4)
>>> +IDREG_END(GMID_EL1)
>>> +
>>> +IDREG_START(ID_AA64AFR0_EL1)
>>> +IDREG_END(ID_AA64AFR0_EL1)
>>> +
>>> +IDREG_START(ID_AA64AFR1_EL1)
>>> +IDREG_END(ID_AA64AFR1_EL1)
>>> +
>>> +IDREG_START(ID_AA64DFR0_EL1)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, HPMN0, 60, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, BRBE, 52, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, MTPMU, 48, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, PMSVer, 32, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, WRPs, 20, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, PMSS, 16, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, BRPs, 12, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, PMUVer, 8, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceVer, 4, 4)
>>> + IDREG_FIELD(ID_AA64DFR0_EL1, DebugVer, 0, 4)
>>> +IDREG_END(ID_AA64DFR0_EL1)
>>> +
>>> +IDREG_START(ID_AA64DFR1_EL1)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, DPFZS, 52, 4)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, EBEP, 48, 4)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, ITE, 44, 4)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, ABLE, 40, 4)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, SPMU, 32, 4)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, WRPs, 16, 8)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, BRPs, 8, 8)
>>> + IDREG_FIELD(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
>>> +IDREG_END(ID_AA64DFR1_EL1)
>>> +
>>> +IDREG_START(ID_AA64DFR2_EL1)
>>> + IDREG_FIELD(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
>>> + IDREG_FIELD(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
>>> + IDREG_FIELD(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
>>> + IDREG_FIELD(ID_AA64DFR2_EL1, BWE, 4, 4)
>>> + IDREG_FIELD(ID_AA64DFR2_EL1, STEP, 0, 4)
>>> +IDREG_END(ID_AA64DFR2_EL1)
>>> +
>>> +IDREG_START(ID_AA64FPFR0_EL1)
>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
>>> +IDREG_END(ID_AA64FPFR0_EL1)
>>> +
>>> +IDREG_START(ID_AA64ISAR0_EL1)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, RNDR, 60, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, TLB, 56, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, TS, 52, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, FHM, 48, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, DP, 44, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SM4, 40, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SM3, 36, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA3, 32, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, RDM, 28, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, Atomic, 20, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, CRC32, 16, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA2, 12, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA1, 8, 4)
>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, AES, 4, 4)
>>> +IDREG_END(ID_AA64ISAR0_EL1)
>>> +
>>> +IDREG_START(ID_AA64ISAR1_EL1)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, LS64, 60, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, XS, 56, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, I8MM, 52, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, DGH, 48, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, BF16, 44, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, SB, 36, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, GPI, 28, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, GPA, 24, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, FCMA, 16, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, API, 8, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, APA, 4, 4)
>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, DPB, 0, 4)
>>> +IDREG_END(ID_AA64ISAR1_EL1)
>>> +
>>> +IDREG_START(ID_AA64ISAR2_EL1)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, LUT, 56, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, CSSC, 52, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, BC, 20, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, MOPS, 16, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, APA3, 12, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, GPA3, 8, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, RPRES, 4, 4)
>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, WFxT, 0, 4)
>>> +IDREG_END(ID_AA64ISAR2_EL1)
>>> +
>>> +IDREG_START(ID_AA64ISAR3_EL1)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSCP, 44, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, MTETC, 36, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSUI, 24, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSFE, 16, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, PACM, 12, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, CPA, 0, 4)
>>> +IDREG_END(ID_AA64ISAR3_EL1)
>>> +
>>> +IDREG_START(ID_AA64MMFR0_EL1)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, ECV, 60, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, FGT, 56, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, ExS, 44, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4, 28, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64, 24, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16, 20, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, PARange, 0, 4)
>>> +IDREG_END(ID_AA64MMFR0_EL1)
>>> +
>>> +IDREG_START(ID_AA64MMFR1_EL1)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, CMOW, 56, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, AFP, 44, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, HCX, 40, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, ETS, 36, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, TWED, 32, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, XNX, 28, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, PAN, 20, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, LO, 16, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, HPDS, 12, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, VH, 8, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
>>> +IDREG_END(ID_AA64MMFR1_EL1)
>>> +
>>> +IDREG_START(ID_AA64MMFR2_EL1)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, E0PD, 60, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, EVT, 56, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, BBM, 52, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, TTL, 48, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, FWB, 40, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, IDS, 36, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, AT, 32, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, ST, 28, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, NV, 24, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, VARange, 16, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, IESB, 12, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, LSM, 8, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, UAO, 4, 4)
>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, CnP, 0, 4)
>>> +IDREG_END(ID_AA64MMFR2_EL1)
>>> +
>>> +IDREG_START(ID_AA64MMFR3_EL1)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, ADERR, 56, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, SDERR, 52, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, ANERR, 44, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, SNERR, 40, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, D128_2, 36, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, D128, 32, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, MEC, 28, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, AIE, 24, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S2POE, 20, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S1POE, 16, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, TCRX, 0, 4)
>>> +IDREG_END(ID_AA64MMFR3_EL1)
>>> +
>>> +IDREG_START(ID_AA64MMFR4_EL1)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, SCRX, 56, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, TEV, 52, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, TPS, 48, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, TLBID, 40, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, EAESR, 32, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, E2H0, 24, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, ASID2, 8, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, EIESB, 4, 4)
>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, PoPS, 0, 4)
>>> +IDREG_END(ID_AA64MMFR4_EL1)
>>> +
>>> +IDREG_START(ID_AA64PFR0_EL1)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, CSV3, 60, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, CSV2, 56, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, RME, 52, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, DIT, 48, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, AMU, 44, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, MPAM, 40, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, SEL2, 36, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, SVE, 32, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, RAS, 28, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, GIC, 24, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, FP, 16, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL3, 12, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL2, 8, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL1, 4, 4)
>>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL0, 0, 4)
>>> +IDREG_END(ID_AA64PFR0_EL1)
>>> +
>>> +IDREG_START(ID_AA64PFR1_EL1)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, PFAR, 60, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, DF2, 56, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, MTEX, 52, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, THE, 48, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, GCS, 44, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, NMI, 36, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, SME, 24, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, MTE, 8, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, SSBS, 4, 4)
>>> + IDREG_FIELD(ID_AA64PFR1_EL1, BT, 0, 4)
>>> +IDREG_END(ID_AA64PFR1_EL1)
>>> +
>>> +IDREG_START(ID_AA64PFR2_EL1)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTETC, 40, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTE, 36, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, FPMR, 32, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MPAM2, 28, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, FGDT, 24, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, UINJ, 16, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, GCIE, 12, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
>>> +IDREG_END(ID_AA64PFR2_EL1)
>>> +
>>> +IDREG_START(ID_AA64SMFR0_EL1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, FA64, 63, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, LUT6, 61, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SMEver, 56, 4)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, I16I64, 52, 4)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F64F64, 48, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, I16I32, 44, 4)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, B16B16, 43, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F16F16, 42, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F8F16, 41, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F8F32, 40, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, I8I32, 36, 4)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F16F32, 35, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, B16F32, 34, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F32F32, 32, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, AES, 24, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, STMOP, 16, 1)
>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
>>> +IDREG_END(ID_AA64SMFR0_EL1)
>>> +
>>> +IDREG_START(ID_AA64ZFR0_EL1)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, F64MM, 56, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, F32MM, 52, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, F16MM, 48, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, I8MM, 44, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, SM4, 40, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, SHA3, 32, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, B16B16, 24, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, BF16, 20, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, AES, 4, 4)
>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, SVEver, 0, 4)
>>> +IDREG_END(ID_AA64ZFR0_EL1)
>>> +
>>> +IDREG_START(ID_AFR0_EL1)
>>> +IDREG_END(ID_AFR0_EL1)
>>> +
>>> +IDREG_START(ID_DFR0_EL1)
>>> + IDREG_FIELD(ID_DFR0_EL1, TraceFilt, 28, 4)
>>> + IDREG_FIELD(ID_DFR0_EL1, PerfMon, 24, 4)
>>> + IDREG_FIELD(ID_DFR0_EL1, MProfDbg, 20, 4)
>>> + IDREG_FIELD(ID_DFR0_EL1, MMapTrc, 16, 4)
>>> + IDREG_FIELD(ID_DFR0_EL1, CopTrc, 12, 4)
>>> + IDREG_FIELD(ID_DFR0_EL1, MMapDbg, 8, 4)
>>> + IDREG_FIELD(ID_DFR0_EL1, CopSDbg, 4, 4)
>>> + IDREG_FIELD(ID_DFR0_EL1, CopDbg, 0, 4)
>>> +IDREG_END(ID_DFR0_EL1)
>>> +
>>> +IDREG_START(ID_DFR1_EL1)
>>> + IDREG_FIELD(ID_DFR1_EL1, HPMN0, 4, 4)
>>> + IDREG_FIELD(ID_DFR1_EL1, MTPMU, 0, 4)
>>> +IDREG_END(ID_DFR1_EL1)
>>> +
>>> +IDREG_START(ID_ISAR0_EL1)
>>> + IDREG_FIELD(ID_ISAR0_EL1, Divide, 24, 4)
>>> + IDREG_FIELD(ID_ISAR0_EL1, Debug, 20, 4)
>>> + IDREG_FIELD(ID_ISAR0_EL1, Coproc, 16, 4)
>>> + IDREG_FIELD(ID_ISAR0_EL1, CmpBranch, 12, 4)
>>> + IDREG_FIELD(ID_ISAR0_EL1, BitField, 8, 4)
>>> + IDREG_FIELD(ID_ISAR0_EL1, BitCount, 4, 4)
>>> + IDREG_FIELD(ID_ISAR0_EL1, Swap, 0, 4)
>>> +IDREG_END(ID_ISAR0_EL1)
>>> +
>>> +IDREG_START(ID_ISAR1_EL1)
>>> + IDREG_FIELD(ID_ISAR1_EL1, Jazelle, 28, 4)
>>> + IDREG_FIELD(ID_ISAR1_EL1, Interwork, 24, 4)
>>> + IDREG_FIELD(ID_ISAR1_EL1, Immediate, 20, 4)
>>> + IDREG_FIELD(ID_ISAR1_EL1, IfThen, 16, 4)
>>> + IDREG_FIELD(ID_ISAR1_EL1, Extend, 12, 4)
>>> + IDREG_FIELD(ID_ISAR1_EL1, Except_AR, 8, 4)
>>> + IDREG_FIELD(ID_ISAR1_EL1, Except, 4, 4)
>>> + IDREG_FIELD(ID_ISAR1_EL1, Endian, 0, 4)
>>> +IDREG_END(ID_ISAR1_EL1)
>>> +
>>> +IDREG_START(ID_ISAR2_EL1)
>>> + IDREG_FIELD(ID_ISAR2_EL1, Reversal, 28, 4)
>>> + IDREG_FIELD(ID_ISAR2_EL1, PSR_AR, 24, 4)
>>> + IDREG_FIELD(ID_ISAR2_EL1, MultU, 20, 4)
>>> + IDREG_FIELD(ID_ISAR2_EL1, MultS, 16, 4)
>>> + IDREG_FIELD(ID_ISAR2_EL1, Mult, 12, 4)
>>> + IDREG_FIELD(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
>>> + IDREG_FIELD(ID_ISAR2_EL1, MemHint, 4, 4)
>>> + IDREG_FIELD(ID_ISAR2_EL1, LoadStore, 0, 4)
>>> +IDREG_END(ID_ISAR2_EL1)
>>> +
>>> +IDREG_START(ID_ISAR3_EL1)
>>> + IDREG_FIELD(ID_ISAR3_EL1, T32EE, 28, 4)
>>> + IDREG_FIELD(ID_ISAR3_EL1, TrueNOP, 24, 4)
>>> + IDREG_FIELD(ID_ISAR3_EL1, T32Copy, 20, 4)
>>> + IDREG_FIELD(ID_ISAR3_EL1, TabBranch, 16, 4)
>>> + IDREG_FIELD(ID_ISAR3_EL1, SynchPrim, 12, 4)
>>> + IDREG_FIELD(ID_ISAR3_EL1, SVC, 8, 4)
>>> + IDREG_FIELD(ID_ISAR3_EL1, SIMD, 4, 4)
>>> + IDREG_FIELD(ID_ISAR3_EL1, Saturate, 0, 4)
>>> +IDREG_END(ID_ISAR3_EL1)
>>> +
>>> +IDREG_START(ID_ISAR4_EL1)
>>> + IDREG_FIELD(ID_ISAR4_EL1, SWP_frac, 28, 4)
>>> + IDREG_FIELD(ID_ISAR4_EL1, PSR_M, 24, 4)
>>> + IDREG_FIELD(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
>>> + IDREG_FIELD(ID_ISAR4_EL1, Barrier, 16, 4)
>>> + IDREG_FIELD(ID_ISAR4_EL1, SMC, 12, 4)
>>> + IDREG_FIELD(ID_ISAR4_EL1, Writeback, 8, 4)
>>> + IDREG_FIELD(ID_ISAR4_EL1, WithShifts, 4, 4)
>>> + IDREG_FIELD(ID_ISAR4_EL1, Unpriv, 0, 4)
>>> +IDREG_END(ID_ISAR4_EL1)
>>> +
>>> +IDREG_START(ID_ISAR5_EL1)
>>> + IDREG_FIELD(ID_ISAR5_EL1, VCMA, 28, 4)
>>> + IDREG_FIELD(ID_ISAR5_EL1, RDM, 24, 4)
>>> + IDREG_FIELD(ID_ISAR5_EL1, CRC32, 16, 4)
>>> + IDREG_FIELD(ID_ISAR5_EL1, SHA2, 12, 4)
>>> + IDREG_FIELD(ID_ISAR5_EL1, SHA1, 8, 4)
>>> + IDREG_FIELD(ID_ISAR5_EL1, AES, 4, 4)
>>> + IDREG_FIELD(ID_ISAR5_EL1, SEVL, 0, 4)
>>> +IDREG_END(ID_ISAR5_EL1)
>>> +
>>> +IDREG_START(ID_ISAR6_EL1)
>>> + IDREG_FIELD(ID_ISAR6_EL1, CLRBHB, 28, 4)
>>> + IDREG_FIELD(ID_ISAR6_EL1, I8MM, 24, 4)
>>> + IDREG_FIELD(ID_ISAR6_EL1, BF16, 20, 4)
>>> + IDREG_FIELD(ID_ISAR6_EL1, SPECRES, 16, 4)
>>> + IDREG_FIELD(ID_ISAR6_EL1, SB, 12, 4)
>>> + IDREG_FIELD(ID_ISAR6_EL1, FHM, 8, 4)
>>> + IDREG_FIELD(ID_ISAR6_EL1, DP, 4, 4)
>>> + IDREG_FIELD(ID_ISAR6_EL1, JSCVT, 0, 4)
>>> +IDREG_END(ID_ISAR6_EL1)
>>> +
>>> +IDREG_START(ID_MMFR0_EL1)
>>> + IDREG_FIELD(ID_MMFR0_EL1, InnerShr, 28, 4)
>>> + IDREG_FIELD(ID_MMFR0_EL1, FCSE, 24, 4)
>>> + IDREG_FIELD(ID_MMFR0_EL1, AuxReg, 20, 4)
>>> + IDREG_FIELD(ID_MMFR0_EL1, TCM, 16, 4)
>>> + IDREG_FIELD(ID_MMFR0_EL1, ShareLvl, 12, 4)
>>> + IDREG_FIELD(ID_MMFR0_EL1, OuterShr, 8, 4)
>>> + IDREG_FIELD(ID_MMFR0_EL1, PMSA, 4, 4)
>>> + IDREG_FIELD(ID_MMFR0_EL1, VMSA, 0, 4)
>>> +IDREG_END(ID_MMFR0_EL1)
>>> +
>>> +IDREG_START(ID_MMFR1_EL1)
>>> + IDREG_FIELD(ID_MMFR1_EL1, BPred, 28, 4)
>>> + IDREG_FIELD(ID_MMFR1_EL1, L1TstCln, 24, 4)
>>> + IDREG_FIELD(ID_MMFR1_EL1, L1Uni, 20, 4)
>>> + IDREG_FIELD(ID_MMFR1_EL1, L1Hvd, 16, 4)
>>> + IDREG_FIELD(ID_MMFR1_EL1, L1UniSW, 12, 4)
>>> + IDREG_FIELD(ID_MMFR1_EL1, L1HvdSW, 8, 4)
>>> + IDREG_FIELD(ID_MMFR1_EL1, L1UniVA, 4, 4)
>>> + IDREG_FIELD(ID_MMFR1_EL1, L1HvdVA, 0, 4)
>>> +IDREG_END(ID_MMFR1_EL1)
>>> +
>>> +IDREG_START(ID_MMFR2_EL1)
>>> + IDREG_FIELD(ID_MMFR2_EL1, HWAccFlg, 28, 4)
>>> + IDREG_FIELD(ID_MMFR2_EL1, WFIStall, 24, 4)
>>> + IDREG_FIELD(ID_MMFR2_EL1, MemBarr, 20, 4)
>>> + IDREG_FIELD(ID_MMFR2_EL1, UniTLB, 16, 4)
>>> + IDREG_FIELD(ID_MMFR2_EL1, HvdTLB, 12, 4)
>>> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdRng, 8, 4)
>>> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdBG, 4, 4)
>>> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdFG, 0, 4)
>>> +IDREG_END(ID_MMFR2_EL1)
>>> +
>>> +IDREG_START(ID_MMFR3_EL1)
>>> + IDREG_FIELD(ID_MMFR3_EL1, Supersec, 28, 4)
>>> + IDREG_FIELD(ID_MMFR3_EL1, CMemSz, 24, 4)
>>> + IDREG_FIELD(ID_MMFR3_EL1, CohWalk, 20, 4)
>>> + IDREG_FIELD(ID_MMFR3_EL1, PAN, 16, 4)
>>> + IDREG_FIELD(ID_MMFR3_EL1, MaintBcst, 12, 4)
>>> + IDREG_FIELD(ID_MMFR3_EL1, BPMaint, 8, 4)
>>> + IDREG_FIELD(ID_MMFR3_EL1, CMaintSW, 4, 4)
>>> + IDREG_FIELD(ID_MMFR3_EL1, CMaintVA, 0, 4)
>>> +IDREG_END(ID_MMFR3_EL1)
>>> +
>>> +IDREG_START(ID_MMFR4_EL1)
>>> + IDREG_FIELD(ID_MMFR4_EL1, EVT, 28, 4)
>>> + IDREG_FIELD(ID_MMFR4_EL1, CCIDX, 24, 4)
>>> + IDREG_FIELD(ID_MMFR4_EL1, LSM, 20, 4)
>>> + IDREG_FIELD(ID_MMFR4_EL1, HPDS, 16, 4)
>>> + IDREG_FIELD(ID_MMFR4_EL1, CnP, 12, 4)
>>> + IDREG_FIELD(ID_MMFR4_EL1, XNX, 8, 4)
>>> + IDREG_FIELD(ID_MMFR4_EL1, AC2, 4, 4)
>>> + IDREG_FIELD(ID_MMFR4_EL1, SpecSEI, 0, 4)
>>> +IDREG_END(ID_MMFR4_EL1)
>>> +
>>> +IDREG_START(ID_MMFR5_EL1)
>>> + IDREG_FIELD(ID_MMFR5_EL1, nTLBPA, 4, 4)
>>> + IDREG_FIELD(ID_MMFR5_EL1, ETS, 0, 4)
>>> +IDREG_END(ID_MMFR5_EL1)
>>> +
>>> +IDREG_START(ID_PFR0_EL1)
>>> + IDREG_FIELD(ID_PFR0_EL1, RAS, 28, 4)
>>> + IDREG_FIELD(ID_PFR0_EL1, DIT, 24, 4)
>>> + IDREG_FIELD(ID_PFR0_EL1, AMU, 20, 4)
>>> + IDREG_FIELD(ID_PFR0_EL1, CSV2, 16, 4)
>>> + IDREG_FIELD(ID_PFR0_EL1, State3, 12, 4)
>>> + IDREG_FIELD(ID_PFR0_EL1, State2, 8, 4)
>>> + IDREG_FIELD(ID_PFR0_EL1, State1, 4, 4)
>>> + IDREG_FIELD(ID_PFR0_EL1, State0, 0, 4)
>>> +IDREG_END(ID_PFR0_EL1)
>>> +
>>> +IDREG_START(ID_PFR1_EL1)
>>> + IDREG_FIELD(ID_PFR1_EL1, GIC, 28, 4)
>>> + IDREG_FIELD(ID_PFR1_EL1, Virt_frac, 24, 4)
>>> + IDREG_FIELD(ID_PFR1_EL1, Sec_frac, 20, 4)
>>> + IDREG_FIELD(ID_PFR1_EL1, GenTimer, 16, 4)
>>> + IDREG_FIELD(ID_PFR1_EL1, Virtualization, 12, 4)
>>> + IDREG_FIELD(ID_PFR1_EL1, MProgMod, 8, 4)
>>> + IDREG_FIELD(ID_PFR1_EL1, Security, 4, 4)
>>> + IDREG_FIELD(ID_PFR1_EL1, ProgMod, 0, 4)
>>> +IDREG_END(ID_PFR1_EL1)
>>> +
>>> +IDREG_START(ID_PFR2_EL1)
>>> IDREG_FIELD(ID_PFR2_EL1, RAS_frac, 8, 4)
>>> + IDREG_FIELD(ID_PFR2_EL1, SSBS, 4, 4)
>>> + IDREG_FIELD(ID_PFR2_EL1, CSV3, 0, 4)
>>> +IDREG_END(ID_PFR2_EL1)
>>> +
>>> +IDREG_START(MIDR_EL1)
>>> + IDREG_FIELD(MIDR_EL1, Implementer, 24, 8)
>>> + IDREG_FIELD(MIDR_EL1, Variant, 20, 4)
>>> + IDREG_FIELD(MIDR_EL1, Architecture, 16, 4)
>>> + IDREG_FIELD(MIDR_EL1, PartNum, 4, 12)
>>> + IDREG_FIELD(MIDR_EL1, Revision, 0, 4)
>>> +IDREG_END(MIDR_EL1)
>>> +
>>> +IDREG_START(MPIDR_EL1)
>>> + IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
>>> + IDREG_FIELD(MPIDR_EL1, U, 30, 1)
>>> + IDREG_FIELD(MPIDR_EL1, MT, 24, 1)
>>> + IDREG_FIELD(MPIDR_EL1, Aff2, 16, 8)
>>> + IDREG_FIELD(MPIDR_EL1, Aff1, 8, 8)
>>> + IDREG_FIELD(MPIDR_EL1, Aff0, 0, 8)
>>> +IDREG_END(MPIDR_EL1)
>>> +
>>> +IDREG_START(MVFR0_EL1)
>>> + IDREG_FIELD(MVFR0_EL1, FPRound, 28, 4)
>>> + IDREG_FIELD(MVFR0_EL1, FPShVec, 24, 4)
>>> + IDREG_FIELD(MVFR0_EL1, FPSqrt, 20, 4)
>>> + IDREG_FIELD(MVFR0_EL1, FPDivide, 16, 4)
>>> + IDREG_FIELD(MVFR0_EL1, FPTrap, 12, 4)
>>> + IDREG_FIELD(MVFR0_EL1, FPDP, 8, 4)
>>> + IDREG_FIELD(MVFR0_EL1, FPSP, 4, 4)
>>> + IDREG_FIELD(MVFR0_EL1, SIMDReg, 0, 4)
>>> +IDREG_END(MVFR0_EL1)
>>> +
>>> +IDREG_START(MVFR1_EL1)
>>> + IDREG_FIELD(MVFR1_EL1, SIMDFMAC, 28, 4)
>>> + IDREG_FIELD(MVFR1_EL1, FPHP, 24, 4)
>>> + IDREG_FIELD(MVFR1_EL1, SIMDHP, 20, 4)
>>> + IDREG_FIELD(MVFR1_EL1, SIMDSP, 16, 4)
>>> + IDREG_FIELD(MVFR1_EL1, SIMDInt, 12, 4)
>>> + IDREG_FIELD(MVFR1_EL1, SIMDLS, 8, 4)
>>> + IDREG_FIELD(MVFR1_EL1, FPDNaN, 4, 4)
>>> + IDREG_FIELD(MVFR1_EL1, FPFtZ, 0, 4)
>>> +IDREG_END(MVFR1_EL1)
>>> +
>>> +IDREG_START(MVFR2_EL1)
>>> + IDREG_FIELD(MVFR2_EL1, FPMisc, 4, 4)
>>> + IDREG_FIELD(MVFR2_EL1, SIMDMisc, 0, 4)
>>> +IDREG_END(MVFR2_EL1)
>>> +
>>> +IDREG_START(REVIDR_EL1)
>>> +IDREG_END(REVIDR_EL1)
>>> +
>>> +IDREG_START(SMIDR_EL1)
>>> + IDREG_FIELD(SMIDR_EL1, NSMC, 56, 4)
>>> + IDREG_FIELD(SMIDR_EL1, HIP, 52, 4)
>>> + IDREG_FIELD(SMIDR_EL1, Affinity2, 32, 20)
>>> + IDREG_FIELD(SMIDR_EL1, Implementer, 24, 8)
>>> + IDREG_FIELD(SMIDR_EL1, Revision, 16, 8)
>>> + IDREG_FIELD(SMIDR_EL1, SMPS, 15, 1)
>>> + IDREG_FIELD(SMIDR_EL1, SH, 13, 2)
>>> + IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
>>> +IDREG_END(SMIDR_EL1)
>>> +
>>> --
>>> 2.53.0
>>>
>> what is the point of a separate patch for reserved fields?
>> [PATCH v9 19/26] target/arm/cpu-idregs.h.inc: Generate reserved fields
>> Can we squash these together?
>
> Well I think the support of RES fields introduce quite a significant
> complexity in scripts/update-aarch64-cpu-sysreg-properties.py,
> especially because several RESx fields can be in the same reg, inducing
> ordering issues which I should have better commented ;-) Also having it
> incremental allows to easily diff the generated file.
>
> So if you don't mind I prefer keeping it separate. I will endeavour to
> add more comments too
>
Okay sure, can we move it closer to this commit if possible?
Thanks,
Khushit
> Eric
>>
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 07/26] target/arm/cpu-idregs.h.inc: generate with script
2026-09-30 5:40 ` Khushit Shah
@ 2026-09-30 6:34 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-30 6:34 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/30/26 7:40 AM, Khushit Shah wrote:
>
>> On 29 Sep 2026, at 10:25 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>>
>>
>> On 9/25/26 1:19 PM, Khushit Shah wrote:
>>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>>
>>>> !-------------------------------------------------------------------|
>>>> CAUTION: External Email
>>>>
>>>> |-------------------------------------------------------------------!
>>>>
>>>> Generate ID reg definitions with the scripts/update-aarch64-cpu-sysreg-properties.py
>>>> based on AARCHMRS_OPENSOURCE_A_profile_FAT-2026-03 Registers.json
>>>>
>>>> Each register and fields are described with this pattern:
>>>>
>>>> IDREG_START(REG)
>>>> IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
>>>> ...
>>>> IDREG_END(REG)
>>>>
>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>> Suggested-by: Khushit Shah <khushit.shah@nutanix.com>
>>>> Suggested-by: Shaju Abraham <shaju.abraham@nutanix.com>
>>>> ---
>>>> target/arm/cpu-idregs.h.inc | 607 ++++++++++++++++++++++++++++++++++++
>>>> 1 file changed, 607 insertions(+)
>>>> create mode 100644 target/arm/cpu-idregs.h.inc
>>>>
>>>> diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
>>>> new file mode 100644
>>>> index 0000000000..c9745e2fb6
>>>> --- /dev/null
>>>> +++ b/target/arm/cpu-idregs.h.inc
>>>> @@ -0,0 +1,607 @@
>>>> +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
>>>> +
>>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>>>> +
>>>> +/* IDREG_START(REG) */
>>>> +/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */
>>>> +/* ... */
>>>> +/* IDREG_END(REG) */
>>>> +
>>>> +IDREG_START(AIDR_EL1)
>>>> +IDREG_END(AIDR_EL1)
>>>> +
>>>> +IDREG_START(CLIDR_EL1)
>>>> + IDREG_FIELD(CLIDR_EL1, Ttype7, 45, 2)
>>>> + IDREG_FIELD(CLIDR_EL1, Ttype6, 43, 2)
>>>> + IDREG_FIELD(CLIDR_EL1, Ttype5, 41, 2)
>>>> + IDREG_FIELD(CLIDR_EL1, Ttype4, 39, 2)
>>>> + IDREG_FIELD(CLIDR_EL1, Ttype3, 37, 2)
>>>> + IDREG_FIELD(CLIDR_EL1, Ttype2, 35, 2)
>>>> + IDREG_FIELD(CLIDR_EL1, Ttype1, 33, 2)
>>>> + IDREG_FIELD(CLIDR_EL1, ICB, 30, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, LoUU, 27, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, LoC, 24, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, LoUIS, 21, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, Ctype7, 18, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, Ctype6, 15, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, Ctype5, 12, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, Ctype4, 9, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, Ctype3, 6, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, Ctype2, 3, 3)
>>>> + IDREG_FIELD(CLIDR_EL1, Ctype1, 0, 3)
>>>> +IDREG_END(CLIDR_EL1)
>>>> +
>>>> +IDREG_START(CTR_EL0)
>>>> + IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
>>>> + IDREG_FIELD(CTR_EL0, DIC, 29, 1)
>>>> + IDREG_FIELD(CTR_EL0, IDC, 28, 1)
>>>> + IDREG_FIELD(CTR_EL0, CWG, 24, 4)
>>>> + IDREG_FIELD(CTR_EL0, ERG, 20, 4)
>>>> + IDREG_FIELD(CTR_EL0, DminLine, 16, 4)
>>>> + IDREG_FIELD(CTR_EL0, L1Ip, 14, 2)
>>>> + IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
>>>> +IDREG_END(CTR_EL0)
>>>> +
>>>> +IDREG_START(DCZID_EL0)
>>>> + IDREG_FIELD(DCZID_EL0, TBS, 5, 4)
>>>> + IDREG_FIELD(DCZID_EL0, DZP, 4, 1)
>>>> + IDREG_FIELD(DCZID_EL0, BS, 0, 4)
>>>> +IDREG_END(DCZID_EL0)
>>>> +
>>>> +IDREG_START(GMID_EL1)
>>>> + IDREG_FIELD(GMID_EL1, BS, 0, 4)
>>>> +IDREG_END(GMID_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64AFR0_EL1)
>>>> +IDREG_END(ID_AA64AFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64AFR1_EL1)
>>>> +IDREG_END(ID_AA64AFR1_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64DFR0_EL1)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, HPMN0, 60, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, BRBE, 52, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, MTPMU, 48, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, PMSVer, 32, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, WRPs, 20, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, PMSS, 16, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, BRPs, 12, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, PMUVer, 8, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, TraceVer, 4, 4)
>>>> + IDREG_FIELD(ID_AA64DFR0_EL1, DebugVer, 0, 4)
>>>> +IDREG_END(ID_AA64DFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64DFR1_EL1)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, DPFZS, 52, 4)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, EBEP, 48, 4)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, ITE, 44, 4)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, ABLE, 40, 4)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, SPMU, 32, 4)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, WRPs, 16, 8)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, BRPs, 8, 8)
>>>> + IDREG_FIELD(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
>>>> +IDREG_END(ID_AA64DFR1_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64DFR2_EL1)
>>>> + IDREG_FIELD(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
>>>> + IDREG_FIELD(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
>>>> + IDREG_FIELD(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
>>>> + IDREG_FIELD(ID_AA64DFR2_EL1, BWE, 4, 4)
>>>> + IDREG_FIELD(ID_AA64DFR2_EL1, STEP, 0, 4)
>>>> +IDREG_END(ID_AA64DFR2_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64FPFR0_EL1)
>>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
>>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
>>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
>>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
>>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
>>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
>>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
>>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
>>>> + IDREG_FIELD(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
>>>> +IDREG_END(ID_AA64FPFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64ISAR0_EL1)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, RNDR, 60, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, TLB, 56, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, TS, 52, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, FHM, 48, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, DP, 44, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SM4, 40, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SM3, 36, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA3, 32, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, RDM, 28, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, Atomic, 20, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, CRC32, 16, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA2, 12, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, SHA1, 8, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR0_EL1, AES, 4, 4)
>>>> +IDREG_END(ID_AA64ISAR0_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64ISAR1_EL1)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, LS64, 60, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, XS, 56, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, I8MM, 52, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, DGH, 48, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, BF16, 44, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, SB, 36, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, GPI, 28, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, GPA, 24, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, FCMA, 16, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, API, 8, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, APA, 4, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR1_EL1, DPB, 0, 4)
>>>> +IDREG_END(ID_AA64ISAR1_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64ISAR2_EL1)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, LUT, 56, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, CSSC, 52, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, BC, 20, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, MOPS, 16, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, APA3, 12, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, GPA3, 8, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, RPRES, 4, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR2_EL1, WFxT, 0, 4)
>>>> +IDREG_END(ID_AA64ISAR2_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64ISAR3_EL1)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSCP, 44, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, MTETC, 36, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSUI, 24, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, LSFE, 16, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, PACM, 12, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
>>>> + IDREG_FIELD(ID_AA64ISAR3_EL1, CPA, 0, 4)
>>>> +IDREG_END(ID_AA64ISAR3_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64MMFR0_EL1)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, ECV, 60, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, FGT, 56, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, ExS, 44, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4, 28, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64, 24, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16, 20, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR0_EL1, PARange, 0, 4)
>>>> +IDREG_END(ID_AA64MMFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64MMFR1_EL1)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, CMOW, 56, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, AFP, 44, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, HCX, 40, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, ETS, 36, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, TWED, 32, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, XNX, 28, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, PAN, 20, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, LO, 16, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, HPDS, 12, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, VH, 8, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
>>>> +IDREG_END(ID_AA64MMFR1_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64MMFR2_EL1)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, E0PD, 60, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, EVT, 56, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, BBM, 52, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, TTL, 48, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, FWB, 40, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, IDS, 36, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, AT, 32, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, ST, 28, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, NV, 24, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, VARange, 16, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, IESB, 12, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, LSM, 8, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, UAO, 4, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR2_EL1, CnP, 0, 4)
>>>> +IDREG_END(ID_AA64MMFR2_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64MMFR3_EL1)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, ADERR, 56, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, SDERR, 52, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, ANERR, 44, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, SNERR, 40, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, D128_2, 36, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, D128, 32, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, MEC, 28, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, AIE, 24, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S2POE, 20, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S1POE, 16, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR3_EL1, TCRX, 0, 4)
>>>> +IDREG_END(ID_AA64MMFR3_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64MMFR4_EL1)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, SCRX, 56, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, TEV, 52, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, TPS, 48, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, TLBID, 40, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, EAESR, 32, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, E2H0, 24, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, ASID2, 8, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, EIESB, 4, 4)
>>>> + IDREG_FIELD(ID_AA64MMFR4_EL1, PoPS, 0, 4)
>>>> +IDREG_END(ID_AA64MMFR4_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64PFR0_EL1)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, CSV3, 60, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, CSV2, 56, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, RME, 52, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, DIT, 48, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, AMU, 44, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, MPAM, 40, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, SEL2, 36, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, SVE, 32, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, RAS, 28, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, GIC, 24, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, FP, 16, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL3, 12, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL2, 8, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL1, 4, 4)
>>>> + IDREG_FIELD(ID_AA64PFR0_EL1, EL0, 0, 4)
>>>> +IDREG_END(ID_AA64PFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64PFR1_EL1)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, PFAR, 60, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, DF2, 56, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, MTEX, 52, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, THE, 48, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, GCS, 44, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, NMI, 36, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, SME, 24, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, MTE, 8, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, SSBS, 4, 4)
>>>> + IDREG_FIELD(ID_AA64PFR1_EL1, BT, 0, 4)
>>>> +IDREG_END(ID_AA64PFR1_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64PFR2_EL1)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTETC, 40, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, VMTE, 36, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, FPMR, 32, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MPAM2, 28, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, FGDT, 24, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, UINJ, 16, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, GCIE, 12, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
>>>> + IDREG_FIELD(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
>>>> +IDREG_END(ID_AA64PFR2_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64SMFR0_EL1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, FA64, 63, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, LUT6, 61, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SMEver, 56, 4)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, I16I64, 52, 4)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F64F64, 48, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, I16I32, 44, 4)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, B16B16, 43, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F16F16, 42, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F8F16, 41, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F8F32, 40, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, I8I32, 36, 4)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F16F32, 35, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, B16F32, 34, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, F32F32, 32, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, AES, 24, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, STMOP, 16, 1)
>>>> + IDREG_FIELD(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
>>>> +IDREG_END(ID_AA64SMFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_AA64ZFR0_EL1)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, F64MM, 56, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, F32MM, 52, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, F16MM, 48, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, I8MM, 44, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, SM4, 40, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, SHA3, 32, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, B16B16, 24, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, BF16, 20, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, AES, 4, 4)
>>>> + IDREG_FIELD(ID_AA64ZFR0_EL1, SVEver, 0, 4)
>>>> +IDREG_END(ID_AA64ZFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_AFR0_EL1)
>>>> +IDREG_END(ID_AFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_DFR0_EL1)
>>>> + IDREG_FIELD(ID_DFR0_EL1, TraceFilt, 28, 4)
>>>> + IDREG_FIELD(ID_DFR0_EL1, PerfMon, 24, 4)
>>>> + IDREG_FIELD(ID_DFR0_EL1, MProfDbg, 20, 4)
>>>> + IDREG_FIELD(ID_DFR0_EL1, MMapTrc, 16, 4)
>>>> + IDREG_FIELD(ID_DFR0_EL1, CopTrc, 12, 4)
>>>> + IDREG_FIELD(ID_DFR0_EL1, MMapDbg, 8, 4)
>>>> + IDREG_FIELD(ID_DFR0_EL1, CopSDbg, 4, 4)
>>>> + IDREG_FIELD(ID_DFR0_EL1, CopDbg, 0, 4)
>>>> +IDREG_END(ID_DFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_DFR1_EL1)
>>>> + IDREG_FIELD(ID_DFR1_EL1, HPMN0, 4, 4)
>>>> + IDREG_FIELD(ID_DFR1_EL1, MTPMU, 0, 4)
>>>> +IDREG_END(ID_DFR1_EL1)
>>>> +
>>>> +IDREG_START(ID_ISAR0_EL1)
>>>> + IDREG_FIELD(ID_ISAR0_EL1, Divide, 24, 4)
>>>> + IDREG_FIELD(ID_ISAR0_EL1, Debug, 20, 4)
>>>> + IDREG_FIELD(ID_ISAR0_EL1, Coproc, 16, 4)
>>>> + IDREG_FIELD(ID_ISAR0_EL1, CmpBranch, 12, 4)
>>>> + IDREG_FIELD(ID_ISAR0_EL1, BitField, 8, 4)
>>>> + IDREG_FIELD(ID_ISAR0_EL1, BitCount, 4, 4)
>>>> + IDREG_FIELD(ID_ISAR0_EL1, Swap, 0, 4)
>>>> +IDREG_END(ID_ISAR0_EL1)
>>>> +
>>>> +IDREG_START(ID_ISAR1_EL1)
>>>> + IDREG_FIELD(ID_ISAR1_EL1, Jazelle, 28, 4)
>>>> + IDREG_FIELD(ID_ISAR1_EL1, Interwork, 24, 4)
>>>> + IDREG_FIELD(ID_ISAR1_EL1, Immediate, 20, 4)
>>>> + IDREG_FIELD(ID_ISAR1_EL1, IfThen, 16, 4)
>>>> + IDREG_FIELD(ID_ISAR1_EL1, Extend, 12, 4)
>>>> + IDREG_FIELD(ID_ISAR1_EL1, Except_AR, 8, 4)
>>>> + IDREG_FIELD(ID_ISAR1_EL1, Except, 4, 4)
>>>> + IDREG_FIELD(ID_ISAR1_EL1, Endian, 0, 4)
>>>> +IDREG_END(ID_ISAR1_EL1)
>>>> +
>>>> +IDREG_START(ID_ISAR2_EL1)
>>>> + IDREG_FIELD(ID_ISAR2_EL1, Reversal, 28, 4)
>>>> + IDREG_FIELD(ID_ISAR2_EL1, PSR_AR, 24, 4)
>>>> + IDREG_FIELD(ID_ISAR2_EL1, MultU, 20, 4)
>>>> + IDREG_FIELD(ID_ISAR2_EL1, MultS, 16, 4)
>>>> + IDREG_FIELD(ID_ISAR2_EL1, Mult, 12, 4)
>>>> + IDREG_FIELD(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
>>>> + IDREG_FIELD(ID_ISAR2_EL1, MemHint, 4, 4)
>>>> + IDREG_FIELD(ID_ISAR2_EL1, LoadStore, 0, 4)
>>>> +IDREG_END(ID_ISAR2_EL1)
>>>> +
>>>> +IDREG_START(ID_ISAR3_EL1)
>>>> + IDREG_FIELD(ID_ISAR3_EL1, T32EE, 28, 4)
>>>> + IDREG_FIELD(ID_ISAR3_EL1, TrueNOP, 24, 4)
>>>> + IDREG_FIELD(ID_ISAR3_EL1, T32Copy, 20, 4)
>>>> + IDREG_FIELD(ID_ISAR3_EL1, TabBranch, 16, 4)
>>>> + IDREG_FIELD(ID_ISAR3_EL1, SynchPrim, 12, 4)
>>>> + IDREG_FIELD(ID_ISAR3_EL1, SVC, 8, 4)
>>>> + IDREG_FIELD(ID_ISAR3_EL1, SIMD, 4, 4)
>>>> + IDREG_FIELD(ID_ISAR3_EL1, Saturate, 0, 4)
>>>> +IDREG_END(ID_ISAR3_EL1)
>>>> +
>>>> +IDREG_START(ID_ISAR4_EL1)
>>>> + IDREG_FIELD(ID_ISAR4_EL1, SWP_frac, 28, 4)
>>>> + IDREG_FIELD(ID_ISAR4_EL1, PSR_M, 24, 4)
>>>> + IDREG_FIELD(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
>>>> + IDREG_FIELD(ID_ISAR4_EL1, Barrier, 16, 4)
>>>> + IDREG_FIELD(ID_ISAR4_EL1, SMC, 12, 4)
>>>> + IDREG_FIELD(ID_ISAR4_EL1, Writeback, 8, 4)
>>>> + IDREG_FIELD(ID_ISAR4_EL1, WithShifts, 4, 4)
>>>> + IDREG_FIELD(ID_ISAR4_EL1, Unpriv, 0, 4)
>>>> +IDREG_END(ID_ISAR4_EL1)
>>>> +
>>>> +IDREG_START(ID_ISAR5_EL1)
>>>> + IDREG_FIELD(ID_ISAR5_EL1, VCMA, 28, 4)
>>>> + IDREG_FIELD(ID_ISAR5_EL1, RDM, 24, 4)
>>>> + IDREG_FIELD(ID_ISAR5_EL1, CRC32, 16, 4)
>>>> + IDREG_FIELD(ID_ISAR5_EL1, SHA2, 12, 4)
>>>> + IDREG_FIELD(ID_ISAR5_EL1, SHA1, 8, 4)
>>>> + IDREG_FIELD(ID_ISAR5_EL1, AES, 4, 4)
>>>> + IDREG_FIELD(ID_ISAR5_EL1, SEVL, 0, 4)
>>>> +IDREG_END(ID_ISAR5_EL1)
>>>> +
>>>> +IDREG_START(ID_ISAR6_EL1)
>>>> + IDREG_FIELD(ID_ISAR6_EL1, CLRBHB, 28, 4)
>>>> + IDREG_FIELD(ID_ISAR6_EL1, I8MM, 24, 4)
>>>> + IDREG_FIELD(ID_ISAR6_EL1, BF16, 20, 4)
>>>> + IDREG_FIELD(ID_ISAR6_EL1, SPECRES, 16, 4)
>>>> + IDREG_FIELD(ID_ISAR6_EL1, SB, 12, 4)
>>>> + IDREG_FIELD(ID_ISAR6_EL1, FHM, 8, 4)
>>>> + IDREG_FIELD(ID_ISAR6_EL1, DP, 4, 4)
>>>> + IDREG_FIELD(ID_ISAR6_EL1, JSCVT, 0, 4)
>>>> +IDREG_END(ID_ISAR6_EL1)
>>>> +
>>>> +IDREG_START(ID_MMFR0_EL1)
>>>> + IDREG_FIELD(ID_MMFR0_EL1, InnerShr, 28, 4)
>>>> + IDREG_FIELD(ID_MMFR0_EL1, FCSE, 24, 4)
>>>> + IDREG_FIELD(ID_MMFR0_EL1, AuxReg, 20, 4)
>>>> + IDREG_FIELD(ID_MMFR0_EL1, TCM, 16, 4)
>>>> + IDREG_FIELD(ID_MMFR0_EL1, ShareLvl, 12, 4)
>>>> + IDREG_FIELD(ID_MMFR0_EL1, OuterShr, 8, 4)
>>>> + IDREG_FIELD(ID_MMFR0_EL1, PMSA, 4, 4)
>>>> + IDREG_FIELD(ID_MMFR0_EL1, VMSA, 0, 4)
>>>> +IDREG_END(ID_MMFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_MMFR1_EL1)
>>>> + IDREG_FIELD(ID_MMFR1_EL1, BPred, 28, 4)
>>>> + IDREG_FIELD(ID_MMFR1_EL1, L1TstCln, 24, 4)
>>>> + IDREG_FIELD(ID_MMFR1_EL1, L1Uni, 20, 4)
>>>> + IDREG_FIELD(ID_MMFR1_EL1, L1Hvd, 16, 4)
>>>> + IDREG_FIELD(ID_MMFR1_EL1, L1UniSW, 12, 4)
>>>> + IDREG_FIELD(ID_MMFR1_EL1, L1HvdSW, 8, 4)
>>>> + IDREG_FIELD(ID_MMFR1_EL1, L1UniVA, 4, 4)
>>>> + IDREG_FIELD(ID_MMFR1_EL1, L1HvdVA, 0, 4)
>>>> +IDREG_END(ID_MMFR1_EL1)
>>>> +
>>>> +IDREG_START(ID_MMFR2_EL1)
>>>> + IDREG_FIELD(ID_MMFR2_EL1, HWAccFlg, 28, 4)
>>>> + IDREG_FIELD(ID_MMFR2_EL1, WFIStall, 24, 4)
>>>> + IDREG_FIELD(ID_MMFR2_EL1, MemBarr, 20, 4)
>>>> + IDREG_FIELD(ID_MMFR2_EL1, UniTLB, 16, 4)
>>>> + IDREG_FIELD(ID_MMFR2_EL1, HvdTLB, 12, 4)
>>>> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdRng, 8, 4)
>>>> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdBG, 4, 4)
>>>> + IDREG_FIELD(ID_MMFR2_EL1, L1HvdFG, 0, 4)
>>>> +IDREG_END(ID_MMFR2_EL1)
>>>> +
>>>> +IDREG_START(ID_MMFR3_EL1)
>>>> + IDREG_FIELD(ID_MMFR3_EL1, Supersec, 28, 4)
>>>> + IDREG_FIELD(ID_MMFR3_EL1, CMemSz, 24, 4)
>>>> + IDREG_FIELD(ID_MMFR3_EL1, CohWalk, 20, 4)
>>>> + IDREG_FIELD(ID_MMFR3_EL1, PAN, 16, 4)
>>>> + IDREG_FIELD(ID_MMFR3_EL1, MaintBcst, 12, 4)
>>>> + IDREG_FIELD(ID_MMFR3_EL1, BPMaint, 8, 4)
>>>> + IDREG_FIELD(ID_MMFR3_EL1, CMaintSW, 4, 4)
>>>> + IDREG_FIELD(ID_MMFR3_EL1, CMaintVA, 0, 4)
>>>> +IDREG_END(ID_MMFR3_EL1)
>>>> +
>>>> +IDREG_START(ID_MMFR4_EL1)
>>>> + IDREG_FIELD(ID_MMFR4_EL1, EVT, 28, 4)
>>>> + IDREG_FIELD(ID_MMFR4_EL1, CCIDX, 24, 4)
>>>> + IDREG_FIELD(ID_MMFR4_EL1, LSM, 20, 4)
>>>> + IDREG_FIELD(ID_MMFR4_EL1, HPDS, 16, 4)
>>>> + IDREG_FIELD(ID_MMFR4_EL1, CnP, 12, 4)
>>>> + IDREG_FIELD(ID_MMFR4_EL1, XNX, 8, 4)
>>>> + IDREG_FIELD(ID_MMFR4_EL1, AC2, 4, 4)
>>>> + IDREG_FIELD(ID_MMFR4_EL1, SpecSEI, 0, 4)
>>>> +IDREG_END(ID_MMFR4_EL1)
>>>> +
>>>> +IDREG_START(ID_MMFR5_EL1)
>>>> + IDREG_FIELD(ID_MMFR5_EL1, nTLBPA, 4, 4)
>>>> + IDREG_FIELD(ID_MMFR5_EL1, ETS, 0, 4)
>>>> +IDREG_END(ID_MMFR5_EL1)
>>>> +
>>>> +IDREG_START(ID_PFR0_EL1)
>>>> + IDREG_FIELD(ID_PFR0_EL1, RAS, 28, 4)
>>>> + IDREG_FIELD(ID_PFR0_EL1, DIT, 24, 4)
>>>> + IDREG_FIELD(ID_PFR0_EL1, AMU, 20, 4)
>>>> + IDREG_FIELD(ID_PFR0_EL1, CSV2, 16, 4)
>>>> + IDREG_FIELD(ID_PFR0_EL1, State3, 12, 4)
>>>> + IDREG_FIELD(ID_PFR0_EL1, State2, 8, 4)
>>>> + IDREG_FIELD(ID_PFR0_EL1, State1, 4, 4)
>>>> + IDREG_FIELD(ID_PFR0_EL1, State0, 0, 4)
>>>> +IDREG_END(ID_PFR0_EL1)
>>>> +
>>>> +IDREG_START(ID_PFR1_EL1)
>>>> + IDREG_FIELD(ID_PFR1_EL1, GIC, 28, 4)
>>>> + IDREG_FIELD(ID_PFR1_EL1, Virt_frac, 24, 4)
>>>> + IDREG_FIELD(ID_PFR1_EL1, Sec_frac, 20, 4)
>>>> + IDREG_FIELD(ID_PFR1_EL1, GenTimer, 16, 4)
>>>> + IDREG_FIELD(ID_PFR1_EL1, Virtualization, 12, 4)
>>>> + IDREG_FIELD(ID_PFR1_EL1, MProgMod, 8, 4)
>>>> + IDREG_FIELD(ID_PFR1_EL1, Security, 4, 4)
>>>> + IDREG_FIELD(ID_PFR1_EL1, ProgMod, 0, 4)
>>>> +IDREG_END(ID_PFR1_EL1)
>>>> +
>>>> +IDREG_START(ID_PFR2_EL1)
>>>> IDREG_FIELD(ID_PFR2_EL1, RAS_frac, 8, 4)
>>>> + IDREG_FIELD(ID_PFR2_EL1, SSBS, 4, 4)
>>>> + IDREG_FIELD(ID_PFR2_EL1, CSV3, 0, 4)
>>>> +IDREG_END(ID_PFR2_EL1)
>>>> +
>>>> +IDREG_START(MIDR_EL1)
>>>> + IDREG_FIELD(MIDR_EL1, Implementer, 24, 8)
>>>> + IDREG_FIELD(MIDR_EL1, Variant, 20, 4)
>>>> + IDREG_FIELD(MIDR_EL1, Architecture, 16, 4)
>>>> + IDREG_FIELD(MIDR_EL1, PartNum, 4, 12)
>>>> + IDREG_FIELD(MIDR_EL1, Revision, 0, 4)
>>>> +IDREG_END(MIDR_EL1)
>>>> +
>>>> +IDREG_START(MPIDR_EL1)
>>>> + IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
>>>> + IDREG_FIELD(MPIDR_EL1, U, 30, 1)
>>>> + IDREG_FIELD(MPIDR_EL1, MT, 24, 1)
>>>> + IDREG_FIELD(MPIDR_EL1, Aff2, 16, 8)
>>>> + IDREG_FIELD(MPIDR_EL1, Aff1, 8, 8)
>>>> + IDREG_FIELD(MPIDR_EL1, Aff0, 0, 8)
>>>> +IDREG_END(MPIDR_EL1)
>>>> +
>>>> +IDREG_START(MVFR0_EL1)
>>>> + IDREG_FIELD(MVFR0_EL1, FPRound, 28, 4)
>>>> + IDREG_FIELD(MVFR0_EL1, FPShVec, 24, 4)
>>>> + IDREG_FIELD(MVFR0_EL1, FPSqrt, 20, 4)
>>>> + IDREG_FIELD(MVFR0_EL1, FPDivide, 16, 4)
>>>> + IDREG_FIELD(MVFR0_EL1, FPTrap, 12, 4)
>>>> + IDREG_FIELD(MVFR0_EL1, FPDP, 8, 4)
>>>> + IDREG_FIELD(MVFR0_EL1, FPSP, 4, 4)
>>>> + IDREG_FIELD(MVFR0_EL1, SIMDReg, 0, 4)
>>>> +IDREG_END(MVFR0_EL1)
>>>> +
>>>> +IDREG_START(MVFR1_EL1)
>>>> + IDREG_FIELD(MVFR1_EL1, SIMDFMAC, 28, 4)
>>>> + IDREG_FIELD(MVFR1_EL1, FPHP, 24, 4)
>>>> + IDREG_FIELD(MVFR1_EL1, SIMDHP, 20, 4)
>>>> + IDREG_FIELD(MVFR1_EL1, SIMDSP, 16, 4)
>>>> + IDREG_FIELD(MVFR1_EL1, SIMDInt, 12, 4)
>>>> + IDREG_FIELD(MVFR1_EL1, SIMDLS, 8, 4)
>>>> + IDREG_FIELD(MVFR1_EL1, FPDNaN, 4, 4)
>>>> + IDREG_FIELD(MVFR1_EL1, FPFtZ, 0, 4)
>>>> +IDREG_END(MVFR1_EL1)
>>>> +
>>>> +IDREG_START(MVFR2_EL1)
>>>> + IDREG_FIELD(MVFR2_EL1, FPMisc, 4, 4)
>>>> + IDREG_FIELD(MVFR2_EL1, SIMDMisc, 0, 4)
>>>> +IDREG_END(MVFR2_EL1)
>>>> +
>>>> +IDREG_START(REVIDR_EL1)
>>>> +IDREG_END(REVIDR_EL1)
>>>> +
>>>> +IDREG_START(SMIDR_EL1)
>>>> + IDREG_FIELD(SMIDR_EL1, NSMC, 56, 4)
>>>> + IDREG_FIELD(SMIDR_EL1, HIP, 52, 4)
>>>> + IDREG_FIELD(SMIDR_EL1, Affinity2, 32, 20)
>>>> + IDREG_FIELD(SMIDR_EL1, Implementer, 24, 8)
>>>> + IDREG_FIELD(SMIDR_EL1, Revision, 16, 8)
>>>> + IDREG_FIELD(SMIDR_EL1, SMPS, 15, 1)
>>>> + IDREG_FIELD(SMIDR_EL1, SH, 13, 2)
>>>> + IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
>>>> +IDREG_END(SMIDR_EL1)
>>>> +
>>>> --
>>>> 2.53.0
>>>>
>>> what is the point of a separate patch for reserved fields?
>>> [PATCH v9 19/26] target/arm/cpu-idregs.h.inc: Generate reserved fields
>>> Can we squash these together?
>> Well I think the support of RES fields introduce quite a significant
>> complexity in scripts/update-aarch64-cpu-sysreg-properties.py,
>> especially because several RESx fields can be in the same reg, inducing
>> ordering issues which I should have better commented ;-) Also having it
>> incremental allows to easily diff the generated file.
>>
>> So if you don't mind I prefer keeping it separate. I will endeavour to
>> add more comments too
>>
> Okay sure, can we move it closer to this commit if possible?
sure
Eric
>
> Thanks,
> Khushit
>> Eric
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props
2026-09-16 14:45 ` [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props Eric Auger
2026-09-28 12:53 ` Khushit Shah
@ 2026-09-30 7:34 ` Khushit Shah
2026-10-08 7:48 ` Eric Auger
1 sibling, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-30 7:34 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Since legacy composite options (such as SVE, virtualization, ...)
> and new SYSREG props coexist, add some basic consistency checks.
>
> Those checks are performed both in kvm_arch_init_vcpu() before
> applying the SYSREG props at the end of the initialization chain.
>
> Some ID reg fields corresponding to legacy composite option scope
> are not writable. In that case we just check that the field has
> not become writable.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
Hi Eric,
Gave this another look. I suggest moving this to kvm_arm_expose_idreg_properties().
What I suggest specifically is:
- Have a list of ID register fields which conflicts with legacy props.
- in kvm_arm_expose_idreg_properties() (the new field based approach) never expose fields
which are part of the above list.
This way the same consistency logic you have will carry over to named models by just adding different
setters for the above field.
What are your thoughts on this?
Thanks,
Khushit
> —
> target/arm/kvm.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 105 insertions(+)
>
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index ddf320d0e6..f52c03745e 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -340,6 +340,107 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
> return NULL;
> }
>
> +
> +/**
> + * kvm_arm_vcpu_validate_sysreg:
> + *
> + * Validate a SYSREG field value is consistent with legacy composite options
> + * Some checks are not implemented because the corresponding sysreg field
> + * is not currently writable. In that case we make sure the field has not
> + * become writable, which would mean the user had the capability to set the
> + * corresponding property.
> + *
> + * return true if consistent. false if it is not, along with an error handle
> + */
> +static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
> + uint64_t value, Error **errp)
> +{
> + const char *fieldname = field->name;
> + ARM64SysReg *sysregdesc = &arm64_id_regs[field->index];
> + const char *regname = sysregdesc->name;
> + g_autofree char *propname = g_strdup_printf("SYSREG_%s_%s", regname, fieldname);
> +
> + /* virtualization */
> + if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) {
> + /* consistency with machine virtualization property */
> + if (cpu->has_el2 && value == 0) {
> + error_setg(errp,
> + "Inconsistent -machine virtualization=on and "
> + "%s=0", propname);
> + return false;
> + } else if (!cpu->has_el2 && value > 0) {
> + error_setg(errp,
> + "Inconsistent -machine virtualization=off and "
> + "%s > 0", propname);
> + return false;
> + }
> + /* secure */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL3") && value > 0) {
> + /* consistency with machine secure property */
> + error_setg(errp, "%s is set but qemu is not ready to support it",
> + propname);
> + return false;
> + /* MTE */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR1_EL1_MTE")) {
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + /* SVE */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_SVE")) {
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ZFR0_EL1_SVEver")) {
> + if (cpu_isar_feature(aa64_sve, cpu) && value == 0) {
> + error_setg(errp, "sve is set but %s is set to 0", propname);
> + return false;
> + } else if (!cpu_isar_feature(aa64_sve, cpu) && value > 0) {
> + error_setg(errp, "sve is not set but %s is greater than 0",
> + propname);
> + return false;
> + }
> + /* PAUTH */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_APA")) {
> + /* PAUTH QARMA5 address authentification */
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_API")) {
> + /* PAUTH Impl Defined address authentification */
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPA")) {
> + /* QARMA5 generic code authentification */
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPI")) {
> + /* QARMA5 generic code authentification */
> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> + propname);
> + return false;
> + /* PMU */
> + } else if (!strcmp(propname, "SYSREG_ID_AA64DFR0_EL1_PMUVer")) {
> + if (cpu->has_pmu && value == 0) {
> + error_setg(errp, "%s is 0 whereas pmu is set", propname);
> + return false;
> + } else if (!cpu->has_pmu && value) {
> + error_setg(errp, "%s is non null whereas pmu is unset", propname);
> + return false;
> + }
> + /* aarch64 false */
> + } else if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
> + if ((!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL0") ||
> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL1") ||
> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) && value < 2)
> + error_setg(errp, "%s is < 2 while aarch64 is set to off",
> + propname);
> + return false;
> + }
> + return true;
> +}
> +
> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>
> @@ -2241,6 +2342,10 @@ static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
> uint64_t oldfv;
> int ret;
>
> + if (!kvm_arm_vcpu_validate_sysreg(cpu, field, value, errp)) {
> + return -1;
> + }
> +
> mask = MAKE_64BIT_MASK(lower, length);
> value = value << lower;
>
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu
2026-09-16 14:45 ` [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu Eric Auger
2026-09-28 10:44 ` Khushit Shah
@ 2026-09-30 7:54 ` Khushit Shah
2026-10-08 7:52 ` Eric Auger
1 sibling, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-09-30 7:54 UTC (permalink / raw)
To: Eric Auger
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> SYSREG prop settings were recorded in a hashtable but they
> are not yet injected on guest. Iterate over all set fields and
> apply the new value through KVM_SET_ONE_REG. The new field
> value overrides the current observable vcpu register value.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> target/arm/kvm.c | 65 +++++++++++++++++++++++++++++++++++++++++
> target/arm/trace-events | 1 +
> 2 files changed, 66 insertions(+)
>
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 3ec2618cc1..ddf320d0e6 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -343,6 +343,9 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>
> +#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
> +#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
> +
> static void set_sysreg_prop(Object *obj, Visitor *v,
> const char *name, void *opaque,
> Error **errp)
> @@ -2215,6 +2218,63 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
> return 0;
> }
>
> +static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
> +{
> + uint64_t *idregs = cpu->isar.idregs;
> + gpointer key_ptr, value_ptr;
> + CPUState *cs = CPU(cpu);
> + GHashTableIter iter;
> +
> + g_hash_table_iter_init(&iter, cpu->sysreg_props);
> +
> + while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
> + uint64_t key = (uint64_t)key_ptr;
> + uint64_t value = (uint64_t)value_ptr;
> + uint32_t reg_idx = KEY_TO_REG_IDX(key);
> + uint8_t lower = KEY_TO_SHIFT(key);
> + ARM64SysReg *reg = &arm64_id_regs[reg_idx];
> + struct kvm_one_reg kvm_reg;
> + uint64_t current, old, mask;
> + uint64_t kvm_idx;
> + ARM64SysRegField *field = get_field(lower, reg);
> + int length = field->length;
> + uint64_t oldfv;
> + int ret;
> +
> + mask = MAKE_64BIT_MASK(lower, length);
> + value = value << lower;
> +
> + old = idregs[reg_idx];
> +
> + kvm_idx = idregs_sysreg_to_kvm_reg(id_register_sysreg[reg_idx]);
> + ret = read_sys_reg64(cs->kvm_fd, ¤t, kvm_idx);
> + if (ret) {
> + error_setg(errp, "failed to read the current value of %s",
> + reg->name);
> + return ret;
> + }
> + oldfv = (current & mask) >> lower;
> +
> + idregs[reg_idx] = current & ~mask;
> + idregs[reg_idx] |= value;
> +
> + kvm_reg.id = kvm_idx;
> + kvm_reg.addr = (uintptr_t)&idregs[reg_idx];
> +
> + ret = ioctl(cs->kvm_fd, KVM_SET_ONE_REG, &kvm_reg);
> + if (ret) {
> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s.%s "
> + "(previous is 0x%"PRIx64"): %m", idregs[reg_idx],
> + reg->name, field->name, oldfv);
> + return ret;
> + }
Hi Eric,
The above is the only KVM-related code here. Can we split this into
1. Apply SYSREG_ props callback which resides in cpu64.c?
2. The previous writeback to cpregs function that writes back ID registers to KVM?
The reason being the SYSREG_ props otherwise do not work with any other accelerator.
We are already trying to make the SYSREG_ getter/setter accel-agnostic.
The above method still has the nicety that -cpu host without any SYSREG_ prop should
behave the same as previous :)
Side note:
While we don’t target TCG support currently, I tried your v8 + named models on TCG
(quick hack; ~20 LOC), and SYSREG_ props/named models works almost out of the box
there (very minimal testing), which was cool.
Thanks,
Khushit
> +
> + trace_apply_sysreg_prop(reg->name, field->name, old, current,
> + mask, value, idregs[reg_idx]);
> + }
> + return 0;
> +}
> +
> int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
> {
> int ret;
> @@ -2315,6 +2375,11 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
> }
> cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>
> + ret = kvm_arm_apply_sysreg_props(cpu, errp);
> + if (ret) {
> + return ret;
> + }
> +
> return kvm_arm_init_cpreg_list(cpu);
> }
>
> diff --git a/target/arm/trace-events b/target/arm/trace-events
> index d72ad6b671..b4d2b45a7d 100644
> --- a/target/arm/trace-events
> +++ b/target/arm/trace-events
> @@ -18,6 +18,7 @@ kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint6
> decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
> get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
> set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
> +apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
>
> # cpu.c
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu
2026-09-28 10:44 ` Khushit Shah
@ 2026-09-30 15:08 ` Eric Auger
2026-10-08 9:56 ` Khushit Shah
2026-09-30 15:11 ` Eric Auger
1 sibling, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-09-30 15:08 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Khushit,
On 9/28/26 12:44 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> SYSREG prop settings were recorded in a hashtable but they
>> are not yet injected on guest. Iterate over all set fields and
>> apply the new value through KVM_SET_ONE_REG. The new field
>> value overrides the current observable vcpu register value.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> With this, I suppose, what named models will do is directly write to
> ID register state, As it also defines state which affects vCPU init flags also.
That's not what I had in mind. I thought you would apply the SYSREG
settings at the same time. As mentionned, I don't think those settings
are meant to substitute to legacy composite options that affect vcpu
init settings.
Besides the principle of this preparatory series is that the props for
writable ID reg fields are meant to be fully reusable for named vcpu
models. Only props for non writable fields should be specific to named
vcpu models as they do not make sense on host/max vcpu model
>
>> ---
>> target/arm/kvm.c | 65 +++++++++++++++++++++++++++++++++++++++++
>> target/arm/trace-events | 1 +
>> 2 files changed, 66 insertions(+)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 3ec2618cc1..ddf320d0e6 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -343,6 +343,9 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>
>> +#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
>> +#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
>> +
>> static void set_sysreg_prop(Object *obj, Visitor *v,
>> const char *name, void *opaque,
>> Error **errp)
>> @@ -2215,6 +2218,63 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
>> return 0;
>> }
>>
>> +static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>> +{
>> + uint64_t *idregs = cpu->isar.idregs;
>> + gpointer key_ptr, value_ptr;
>> + CPUState *cs = CPU(cpu);
>> + GHashTableIter iter;
>> +
>> + g_hash_table_iter_init(&iter, cpu->sysreg_props);
>> +
>> + while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
>> + uint64_t key = (uint64_t)key_ptr;
>> + uint64_t value = (uint64_t)value_ptr;
>> + uint32_t reg_idx = KEY_TO_REG_IDX(key);
>> + uint8_t lower = KEY_TO_SHIFT(key);
>> + ARM64SysReg *reg = &arm64_id_regs[reg_idx];
>> + struct kvm_one_reg kvm_reg;
>> + uint64_t current, old, mask;
>> + uint64_t kvm_idx;
>> + ARM64SysRegField *field = get_field(lower, reg);
>> + int length = field->length;
>> + uint64_t oldfv;
>> + int ret;
>> +
>> + mask = MAKE_64BIT_MASK(lower, length);
>> + value = value << lower;
>> +
>> + old = idregs[reg_idx];
>> +
>> + kvm_idx = idregs_sysreg_to_kvm_reg(id_register_sysreg[reg_idx]);
>> + ret = read_sys_reg64(cs->kvm_fd, ¤t, kvm_idx);
>> + if (ret) {
>> + error_setg(errp, "failed to read the current value of %s",
>> + reg->name);
>> + return ret;
>> + }
>> + oldfv = (current & mask) >> lower;
>> +
>> + idregs[reg_idx] = current & ~mask;
>> + idregs[reg_idx] |= value;
>> + kvm_reg.id = kvm_idx;
>> + kvm_reg.addr = (uintptr_t)&idregs[reg_idx];
>> +
> We can ignore this if value == old value
sure, modified
>
>> + ret = ioctl(cs->kvm_fd, KVM_SET_ONE_REG, &kvm_reg);
>> + if (ret) {
>> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s.%s "
>> + "(previous is 0x%"PRIx64"): %m", idregs[reg_idx],
>> + reg->name, field->name, oldfv);
>> + return ret;
>> + }
>> +
>> + trace_apply_sysreg_prop(reg->name, field->name, old, current,
>> + mask, value, idregs[reg_idx]);
>> + }
>> + return 0;
>> +}
>> +
>> int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>> {
>> int ret;
>> @@ -2315,6 +2375,11 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>> }
>> cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>>
>> + ret = kvm_arm_apply_sysreg_props(cpu, errp);
>> + if (ret) {
>> + return ret;
>> + }
>> +
> This should also happen on vCPU reset.
On which path is it needed? on qmp system_reset I can see that the
former values applied with SYSREG settings are kept.
Thanks
Eric
>
> Overall, I like this approach as if the user does not provide any property overrides, it should behave the same as older builds.
>
> Warm Regards,
> Khushit
>> return kvm_arm_init_cpreg_list(cpu);
>> }
>>
>> diff --git a/target/arm/trace-events b/target/arm/trace-events
>> index d72ad6b671..b4d2b45a7d 100644
>> --- a/target/arm/trace-events
>> +++ b/target/arm/trace-events
>> @@ -18,6 +18,7 @@ kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint6
>> decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
>> get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
>> set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
>> +apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
>> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
>>
>> # cpu.c
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu
2026-09-28 10:44 ` Khushit Shah
2026-09-30 15:08 ` Eric Auger
@ 2026-09-30 15:11 ` Eric Auger
1 sibling, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-30 15:11 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/28/26 12:44 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> SYSREG prop settings were recorded in a hashtable but they
>> are not yet injected on guest. Iterate over all set fields and
>> apply the new value through KVM_SET_ONE_REG. The new field
>> value overrides the current observable vcpu register value.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> With this, I suppose, what named models will do is directly write to
> ID register state, As it also defines state which affects vCPU init flags also.
>
>> ---
>> target/arm/kvm.c | 65 +++++++++++++++++++++++++++++++++++++++++
>> target/arm/trace-events | 1 +
>> 2 files changed, 66 insertions(+)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 3ec2618cc1..ddf320d0e6 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -343,6 +343,9 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>
>> +#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
>> +#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
>> +
>> static void set_sysreg_prop(Object *obj, Visitor *v,
>> const char *name, void *opaque,
>> Error **errp)
>> @@ -2215,6 +2218,63 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
>> return 0;
>> }
>>
>> +static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>> +{
>> + uint64_t *idregs = cpu->isar.idregs;
>> + gpointer key_ptr, value_ptr;
>> + CPUState *cs = CPU(cpu);
>> + GHashTableIter iter;
>> +
>> + g_hash_table_iter_init(&iter, cpu->sysreg_props);
>> +
>> + while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
>> + uint64_t key = (uint64_t)key_ptr;
>> + uint64_t value = (uint64_t)value_ptr;
>> + uint32_t reg_idx = KEY_TO_REG_IDX(key);
>> + uint8_t lower = KEY_TO_SHIFT(key);
>> + ARM64SysReg *reg = &arm64_id_regs[reg_idx];
>> + struct kvm_one_reg kvm_reg;
>> + uint64_t current, old, mask;
>> + uint64_t kvm_idx;
>> + ARM64SysRegField *field = get_field(lower, reg);
>> + int length = field->length;
>> + uint64_t oldfv;
>> + int ret;
>> +
>> + mask = MAKE_64BIT_MASK(lower, length);
>> + value = value << lower;
>> +
>> + old = idregs[reg_idx];
>> +
>> + kvm_idx = idregs_sysreg_to_kvm_reg(id_register_sysreg[reg_idx]);
>> + ret = read_sys_reg64(cs->kvm_fd, ¤t, kvm_idx);
>> + if (ret) {
>> + error_setg(errp, "failed to read the current value of %s",
>> + reg->name);
>> + return ret;
>> + }
>> + oldfv = (current & mask) >> lower;
>> +
>> + idregs[reg_idx] = current & ~mask;
>> + idregs[reg_idx] |= value;
>> + kvm_reg.id = kvm_idx;
>> + kvm_reg.addr = (uintptr_t)&idregs[reg_idx];
>> +
> We can ignore this if value == old value
>
>> + ret = ioctl(cs->kvm_fd, KVM_SET_ONE_REG, &kvm_reg);
>> + if (ret) {
>> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s.%s "
>> + "(previous is 0x%"PRIx64"): %m", idregs[reg_idx],
>> + reg->name, field->name, oldfv);
>> + return ret;
>> + }
>> +
>> + trace_apply_sysreg_prop(reg->name, field->name, old, current,
>> + mask, value, idregs[reg_idx]);
>> + }
>> + return 0;
>> +}
>> +
>> int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>> {
>> int ret;
>> @@ -2315,6 +2375,11 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>> }
>> cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>>
>> + ret = kvm_arm_apply_sysreg_props(cpu, errp);
>> + if (ret) {
>> + return ret;
>> + }
>> +
> This should also happen on vCPU reset.
>
> Overall, I like this approach as if the user does not provide any property overrides, it should behave the same as older builds.
to me the risky part if the initialization of all cpu->isar.idregs[]
from host which can have side effects like the CLDIR_EL1 story.
Eric
>
> Warm Regards,
> Khushit
>> return kvm_arm_init_cpreg_list(cpu);
>> }
>>
>> diff --git a/target/arm/trace-events b/target/arm/trace-events
>> index d72ad6b671..b4d2b45a7d 100644
>> --- a/target/arm/trace-events
>> +++ b/target/arm/trace-events
>> @@ -18,6 +18,7 @@ kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint6
>> decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
>> get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
>> set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
>> +apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
>> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
>>
>> # cpu.c
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 21/26] target/arm/kvm: add helper to test SYSREG props against a scratch vcpu
2026-09-28 13:34 ` Khushit Shah
@ 2026-09-30 17:43 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-09-30 17:43 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/28/26 3:34 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Add kvm_idreg_write_scratch_vcpu helper that will be used
>> by qmp_query_cpu_model_expansion code to test SYSREG settings
>> against a scratch vcpu. Indeed when the expansion code is called
>> the actual vcpu has not been initialized so we use a scratch vcpu.
>> This latter has been initialized with features taken from
>> legacy compositive options (EL2, SVE, ...). So the trial is
>> very close to the final setup.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> ---
>> target/arm/kvm_arm.h | 4 ++++
>> target/arm/kvm-stub.c | 7 ++++++
>> target/arm/kvm.c | 51 +++++++++++++++++++++++++++++++++++++++++
>> target/arm/trace-events | 1 +
>> 4 files changed, 63 insertions(+)
>>
>> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
>> index 2b3474cc36..bace69efed 100644
>> --- a/target/arm/kvm_arm.h
>> +++ b/target/arm/kvm_arm.h
>> @@ -14,6 +14,7 @@
>> #include "qapi/qapi-types-misc-arm.h"
>> #include "system/kvm.h"
>> #include "target/arm/cpu-qom.h"
>> +#include "cpu-idregs.h"
>>
>> #define KVM_ARM_VGIC_V2 (1 << 0)
>> #define KVM_ARM_VGIC_V3 (1 << 1)
>> @@ -250,4 +251,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3);
>> */
>> char *kvm_print_register_name(uint64_t regidx);
>>
>> +bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
>> + ARM64SysRegField *field, uint64_t newfv,
>> + Error **errp);
>> #endif
>> diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
>> index 88cbe8d85c..8e6fae0a4d 100644
>> --- a/target/arm/kvm-stub.c
>> +++ b/target/arm/kvm-stub.c
>> @@ -119,3 +119,10 @@ char *kvm_print_register_name(uint64_t regidx)
>> {
>> g_assert_not_reached();
>> }
>> +
>> +bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
>> + ARM64SysRegField *field, uint64_t newfv,
>> + Error **errp)
>> +{
>> + g_assert_not_reached();
>> +}
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 537673177a..f7ca0e0250 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -447,6 +447,57 @@ static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
>> #define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
>> #define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
>>
>> +bool kvm_idreg_write_scratch_vcpu(ARMCPU *cpu, int cpufd,
>> + ARM64SysRegField *field, uint64_t newfv,
>> + Error **errp)
>> +{
>> + uint64_t mask, old_reg_val, new_reg_val, oldfv;
>> + struct kvm_one_reg reg;
>> + int lower = field->shift;
>> + int length = field->length;
>> + int index = field->index;
>> + uint64_t kidx;
>> + int ret;
>> +
>> + mask = MAKE_64BIT_MASK(lower, length);
>> +
>> + if (!kvm_arm_vcpu_validate_sysreg(cpu, field, newfv, errp)) {
>> + return false;
>> + };
>> +
>> + kidx = idregs_sysreg_to_kvm_reg(id_register_sysreg[index]);
>> + ret = read_sys_reg64(cpufd, &old_reg_val, kidx);
>> + if (ret) {
>> + error_setg(errp, "failed to read the scratch vcpu value for field %s %m",
>> + field->name);
>> + return false;
>> + }
>> + oldfv = (old_reg_val & mask) >> lower;
>> +
>> + new_reg_val = old_reg_val & ~mask;
>> + new_reg_val |= newfv << lower;
>> +
>> + reg.id = kidx;
>> + reg.addr = (uintptr_t)&new_reg_val;
>> + ret = ioctl(cpufd, KVM_SET_ONE_REG, ®);
>> + if (ret) {
>> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s "
>> + "(previous is 0x%"PRIx64"): %m", newfv, field->name, oldfv);
>> + return false;
>> + } else {
>> + uint64_t check_val, actualfv;
>> +
>> + ret = read_sys_reg64(cpufd, &check_val, kidx);
>> + if (ret) {
>> + error_setg(errp, "failed to read the new reg value: %m");
>> + return false;
>> + }
>> + actualfv = (check_val & mask) >> lower;
>> + trace_kvm_idreg_write_scratch_vcpu(field->name, oldfv, newfv, actualfv);
>> + }
>> + return true;
>> +}
>> +
> Hi Eric,
>
> This looks similar to kvm_arm_apply_sysreg_props(), we maybe be able to abstract out kvm_arm_apply_sysreg_prop(),
> which can then be used by both these functions.
done in v10
Thanks!
Eric
>
>> static void set_sysreg_prop(Object *obj, Visitor *v,
>> const char *name, void *opaque,
>> Error **errp)
>> diff --git a/target/arm/trace-events b/target/arm/trace-events
>> index 2a9cc67035..7a3f499a0e 100644
>> --- a/target/arm/trace-events
>> +++ b/target/arm/trace-events
>> @@ -21,6 +21,7 @@ set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_va
>> apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
>> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
>> unexpected_writable_reserved_field(const char *reg_name, const char *field_name, int lower, int upper) "Unexpected writable reserved field: %s.%s [%d,%d], skip it ..."
>> +kvm_idreg_write_scratch_vcpu(const char *name, uint64_t oldfv, uint64_t newfv, uint64_t actualfv) "successful dry-run for %s old=0x%"PRIx64" new=0x%"PRIx64" actual=0x%"PRIx64
>>
>> # cpu.c
>> arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 06/26] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py
2026-09-25 9:29 ` Khushit Shah
@ 2026-10-02 12:59 ` Eric Auger
2026-10-05 5:37 ` Khushit Shah
0 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-10-02 12:59 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Khushit,
On 9/25/26 11:29 AM, Khushit Shah wrote:
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Introduce a script that takes as input the Registers.json file
>> delivered in the AARCHMRS Features Model downloadable from the
>> Arm Developer A-Profile Architecture Exploration Tools page:
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=2NOLVUk59YPHssYi5AgGX0z_LkZPQXfTkiD33Ti_D8RYfowBwp7XuMOfw-dMDkDE&s=Qs3ro5t6_dDfdQDLUGX7pJ43SvM2axfOShUzqbv90EQ&e=
>> and automates the generation of system register properties definitions.
>>
>> generates target/arm/cpu-idregs.h.inc containing definitions for
>> feature ID registers.
>>
>> We only care about IDregs with opcodes satisfying:
>> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>
>> ---
>>
>> v5 -> v6
>> - add ident
>> ---
>> .../update-aarch64-cpu-sysreg-properties.py | 166 ++++++++++++++++++
>> 1 file changed, 166 insertions(+)
>> create mode 100644 scripts/update-aarch64-cpu-sysreg-properties.py
>>
>> diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py
>> new file mode 100644
>> index 0000000000..6f5edb88d2
>> --- /dev/null
>> +++ b/scripts/update-aarch64-cpu-sysreg-properties.py
>> @@ -0,0 +1,166 @@
>> +#!/usr/bin/env python3
>> +
>> +# This script takes as input the Registers.json file delivered in
>> +# the AARCHMRS Features Model downloadable from the Arm Developer
>> +# A-Profile Architecture Exploration Tools page:
>> +# https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=2NOLVUk59YPHssYi5AgGX0z_LkZPQXfTkiD33Ti_D8RYfowBwp7XuMOfw-dMDkDE&s=Qs3ro5t6_dDfdQDLUGX7pJ43SvM2axfOShUzqbv90EQ&e=
>> +# and outputs target/arm/cpu-idregs.h.inc content.
>> +# ID regs are defined using this pattern:
>> +#
>> +# IDREG_START(REG)
>> +# IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
> Nit: Add Enum Macro
This is done later in "target/arm/cpu-idregs.h.inc: Generate enum values"
>> +# ...
>> +# IDREG_END(REG)
>> +#
>> +# Copyright (C) 2026 Red Hat, Inc.
>> +#
>> +# Authors: Eric Auger <eric.auger@redhat.com>
>> +#
>> +# SPDX-License-Identifier: GPL-2.0-or-later
>> +
>> +
>> +import json
>> +import os
>> +import sys
>> +from aarch64_sysreg_helpers import extract_idregs_from_registers_json
>> +
>> +def collect_fields(item, bit_offset=0):
>> + """
>> + Recursively finds all field-like objects, handling Fields.Array,
>> + Fields.ArrayField, and ConditionalField structures.
>> + Applies bit_offset from containers to child fields.
>> + """
>> + fields = []
>> + if not isinstance(item, dict):
>> + return fields
>> +
>> + _type = item.get('_type', '')
>> +
>> + # Array types (for example CLIDR_EL1 Ctype<n>, Ttype<n>)
>> + if _type == 'Fields.Array':
>> + name_template = item.get('name') or item.get('label', '')
>> + index_info = item.get('indexes', [{}])[0]
>> + start_idx = index_info.get('start', 0)
>> + count = index_info.get('width', 0)
>> +
>> + full_range = item.get('rangeset', [{}])[0]
>> + bit_start = full_range.get('start', 0) + bit_offset
>> + elem_width = full_range.get('width', 0) // count if count else 0
>> +
>> + for i in range(count):
>> + idx = start_idx + i
>> + # Correctly handle indexed names like Ctype1, Ctype2
>> + field_name = name_template.replace('<n>', str(idx))
>> + fields.append({
>> + 'name': field_name,
>> + 'rangeset': [{
>> + 'start': bit_start + (i * elem_width),
>> + 'width': elem_width
>> + }],
>> + '_type': 'Fields.Field'
>> + })
>> + return fields
>> +
>> + # ConditionalFields
> Can you please explain what are conditional fields and should we always include them?
If we don't you will miss plenty of named fields which depend on a
specific FEAT implementation.
Few examples:
< IDREG_FIELD_START(ID_AA64MMFR4_EL1, E2H0, 24, 4)
< IDREG_FIELD_START(ID_AA64SMFR0_EL1, SMEver, 56, 4)
< IDREG_FIELD_START(ID_AA64ZFR0_EL1, SVEver, 0, 4)
../..
All of those are defined in linux sysreg too
>
>> + elif _type == 'Fields.ConditionalField':
>> + inner_offset = bit_offset
>> + if item.get('rangeset'):
>> + # Parent container defines the absolute start bit
>> + inner_offset = item['rangeset'][0].get('start', bit_offset)
>> +
>> + for entry in item.get('fields', []):
>> + inner = entry.get('field')
>> + if inner:
>> + fields.extend(collect_fields(inner, inner_offset))
>> + return fields
>> +
>> + # Normal Field Types
>> + leaf_types = ['Fields.Field', 'Fields.ConstantField',
>> + 'Fields.EnumeratedField', 'Fields.Bitfield']
>> + if _type in leaf_types:
>> + field_copy = item.copy()
>> + if field_copy.get('rangeset'):
>> + new_ranges = []
>> + for r in field_copy['rangeset']:
>> + nr = r.copy()
>> + # Apply the cumulative offset to the field's start bit
>> + nr['start'] = r.get('start', 0) + bit_offset
>> + new_ranges.append(nr)
>> + field_copy['rangeset'] = new_ranges
>> + fields.append(field_copy)
>> + return fields
>> +
>> + # Traverse the hierarchy for other cases
>> + for key in ['fields', 'values', 'fieldsets']:
>> + for nested in item.get(key, []):
>> + fields.extend(collect_fields(nested, bit_offset))
>> +
>> + return fields
>> +
>> +
>> +def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
>> + with open(raw_json_path, 'r') as f:
>> + register_data = json.load(f)
>> +
>> + regs = {r.get('name'): r for r in register_data if r.get('_type') == 'Register'}
>> +
>> + final_output = ""
>> +
>> + for reg_name in id_reg_names:
>> + register = regs.get(reg_name)
>> + if not register:
> we should error out here.
agreed
>> + continue
>> +
>> + final_output += f"IDREG_START({reg_name})\n"
>> +
>> + unique_fields = {}
>> + for fieldset in register.get('fieldsets', []):
>> + candidates = collect_fields(fieldset)
>> + for val in candidates:
>> + name = (val.get('name') or val.get('label', '')).strip()
>> + if not name or "RESERVED" in name.upper():
>> + continue
>> + for r in val.get('rangeset', []):
>> + lsb = int(r.get('start'))
>> + width = r.get('width')
>> + msb = lsb + int(width) - 1
>> +
>> + # Only keep the fields with the highest MSB
>> + # needed fir CCSIDR_EL1
> does not apply now, we ignore CCSIDR_EL1
yeah but I feel it still makes sense to record the highest msb in case
different fieldsets exist for the same name (32b versus 64b for instance)
>> + if name not in unique_fields or msb > unique_fields[name]['msb']:
>> + unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width}
>> +
>> + # Sort decreasing lsbs
>> + sorted_fields = sorted(unique_fields.items(),
>> + key=lambda x: x[1]['lsb'], reverse=True)
>> +
>> + for name, bits in sorted_fields:
>> + line = (f" IDREG_FIELD({reg_name}, "
>> + f"{name}, {bits['lsb']}, {bits['width']})\n")
>> + final_output += line
>> + final_output += f"IDREG_END({reg_name})\n"
>> + final_output += "\n"
>> +
>> + os.makedirs("target/arm", exist_ok=True)
>> + with open("target/arm/cpu-idregs.h.inc", 'w') as f:
>> + f.write("/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n\n")
>> + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
>> + f.write("/* IDREG_START(REG) */\n")
>> + f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n”)
> Same enum macro …
see above
Thanks!
Eric
>
> Warm Regards,
> Khushit
>> + f.write("/* ... */\n")
>> + f.write("/* IDREG_END(REG) */\n\n")
>> + f.write(final_output)
>> +
>> +if __name__ == "__main__":
>> + if len(sys.argv) < 2:
>> + print("Usage: python scripts/update-aarch64-cpu-sysreg-properties.py "
>> + "<path_to_registers_json>")
>> + else:
>> + json_path = sys.argv[1]
>> +
>> + id_regs_dict = extract_idregs_from_registers_json(json_path)
>> + sorted_names = sorted(id_regs_dict.keys())
>> +
>> + if sorted_names:
>> + generate_sysreg_properties_from_registers_json(sorted_names, json_path)
>> + print("Generated target/arm/cpu-idregs.h.inc")
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 08/26] target/arm/cpu-idregs.h.inc: Generate enum values
2026-09-25 11:59 ` Khushit Shah
@ 2026-10-02 16:05 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-10-02 16:05 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/25/26 1:59 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Modify the python script so that enum values are also
>> extracted from Registers.json.
>>
>> If enum values are found, the field and its enum values are
>> defined within IDREG_FIELD_START/END. Each enum value is
>> defined with IDREG_FIELD_ARCH_VAL() macro.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>
>> v7 -> v8:
>> Properly handle ValueRange
>> ---
>> target/arm/cpu-idregs.h.inc | 2657 ++++++++++++++---
>> .../update-aarch64-cpu-sysreg-properties.py | 86 +-
>> 2 files changed, 2332 insertions(+), 411 deletions(-)
>>
>> diff --git a/target/arm/cpu-idregs.h.inc b/target/arm/cpu-idregs.h.inc
>> index c9745e2fb6..10ddfdf43a 100644
>> --- a/target/arm/cpu-idregs.h.inc
>> +++ b/target/arm/cpu-idregs.h.inc
>> @@ -4,7 +4,11 @@
>>
>> /* IDREG_START(REG) */
>> /* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */
>> +/* or for fields with enum values */
>> +/* IDREG_FIELD_START(REG, FIELD, SHIFT, LENGTH) */
>> +/* IDREG_FIELD_ARCH_VAL(VALUE) */
>> /* ... */
>> +/* IDREG_FIELD_END(REG, FIELD) */
>> /* IDREG_END(REG) */
>>
>> IDREG_START(AIDR_EL1)
>> @@ -18,7 +22,16 @@ IDREG_START(CLIDR_EL1)
>> IDREG_FIELD(CLIDR_EL1, Ttype3, 37, 2)
>> IDREG_FIELD(CLIDR_EL1, Ttype2, 35, 2)
>> IDREG_FIELD(CLIDR_EL1, Ttype1, 33, 2)
>> - IDREG_FIELD(CLIDR_EL1, ICB, 30, 3)
>> + IDREG_FIELD_START(CLIDR_EL1, ICB, 30, 3)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_END(CLIDR_EL1, ICB)
>> IDREG_FIELD(CLIDR_EL1, LoUU, 27, 3)
>> IDREG_FIELD(CLIDR_EL1, LoC, 24, 3)
>> IDREG_FIELD(CLIDR_EL1, LoUIS, 21, 3)
>> @@ -33,12 +46,23 @@ IDREG_END(CLIDR_EL1)
>>
>> IDREG_START(CTR_EL0)
>> IDREG_FIELD(CTR_EL0, TminLine, 32, 6)
>> - IDREG_FIELD(CTR_EL0, DIC, 29, 1)
>> - IDREG_FIELD(CTR_EL0, IDC, 28, 1)
>> + IDREG_FIELD_START(CTR_EL0, DIC, 29, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(CTR_EL0, DIC)
>> + IDREG_FIELD_START(CTR_EL0, IDC, 28, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(CTR_EL0, IDC)
>> IDREG_FIELD(CTR_EL0, CWG, 24, 4)
>> IDREG_FIELD(CTR_EL0, ERG, 20, 4)
>> IDREG_FIELD(CTR_EL0, DminLine, 16, 4)
>> - IDREG_FIELD(CTR_EL0, L1Ip, 14, 2)
>> + IDREG_FIELD_START(CTR_EL0, L1Ip, 14, 2)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(CTR_EL0, L1Ip)
>> IDREG_FIELD(CTR_EL0, IminLine, 0, 4)
>> IDREG_END(CTR_EL0)
>>
>> @@ -59,549 +83,2368 @@ IDREG_START(ID_AA64AFR1_EL1)
>> IDREG_END(ID_AA64AFR1_EL1)
>>
>> IDREG_START(ID_AA64DFR0_EL1)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, HPMN0, 60, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, BRBE, 52, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, MTPMU, 48, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, PMSVer, 32, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, WRPs, 20, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, PMSS, 16, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, BRPs, 12, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, PMUVer, 8, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, TraceVer, 4, 4)
>> - IDREG_FIELD(ID_AA64DFR0_EL1, DebugVer, 0, 4)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, HPMN0, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, HPMN0)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, ExtTrcBuff, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, ExtTrcBuff)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, BRBE, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, BRBE)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, MTPMU, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, MTPMU)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, TraceBuffer, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, TraceBuffer)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, TraceFilt, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, TraceFilt)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, DoubleLock, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, DoubleLock)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, PMSVer, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, PMSVer)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, CTX_CMPs, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, CTX_CMPs)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, WRPs, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, WRPs)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, PMSS, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, PMSS)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, BRPs, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, BRPs)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, PMUVer, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, PMUVer)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, TraceVer, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, TraceVer)
>> + IDREG_FIELD_START(ID_AA64DFR0_EL1, DebugVer, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_END(ID_AA64DFR0_EL1, DebugVer)
>> IDREG_END(ID_AA64DFR0_EL1)
>>
>> IDREG_START(ID_AA64DFR1_EL1)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, DPFZS, 52, 4)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, EBEP, 48, 4)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, ITE, 44, 4)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, ABLE, 40, 4)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, SPMU, 32, 4)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, WRPs, 16, 8)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, BRPs, 8, 8)
>> - IDREG_FIELD(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, ABL_CMPs, 56, 8)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_ARCH_VAL(16)
>> + IDREG_FIELD_ARCH_VAL(17)
>> + IDREG_FIELD_ARCH_VAL(18)
>> + IDREG_FIELD_ARCH_VAL(19)
>> + IDREG_FIELD_ARCH_VAL(20)
>> + IDREG_FIELD_ARCH_VAL(21)
>> + IDREG_FIELD_ARCH_VAL(22)
>> + IDREG_FIELD_ARCH_VAL(23)
>> + IDREG_FIELD_ARCH_VAL(24)
>> + IDREG_FIELD_ARCH_VAL(25)
>> + IDREG_FIELD_ARCH_VAL(26)
>> + IDREG_FIELD_ARCH_VAL(27)
>> + IDREG_FIELD_ARCH_VAL(28)
>> + IDREG_FIELD_ARCH_VAL(29)
>> + IDREG_FIELD_ARCH_VAL(30)
>> + IDREG_FIELD_ARCH_VAL(31)
>> + IDREG_FIELD_ARCH_VAL(32)
>> + IDREG_FIELD_ARCH_VAL(33)
>> + IDREG_FIELD_ARCH_VAL(34)
>> + IDREG_FIELD_ARCH_VAL(35)
>> + IDREG_FIELD_ARCH_VAL(36)
>> + IDREG_FIELD_ARCH_VAL(37)
>> + IDREG_FIELD_ARCH_VAL(38)
>> + IDREG_FIELD_ARCH_VAL(39)
>> + IDREG_FIELD_ARCH_VAL(40)
>> + IDREG_FIELD_ARCH_VAL(41)
>> + IDREG_FIELD_ARCH_VAL(42)
>> + IDREG_FIELD_ARCH_VAL(43)
>> + IDREG_FIELD_ARCH_VAL(44)
>> + IDREG_FIELD_ARCH_VAL(45)
>> + IDREG_FIELD_ARCH_VAL(46)
>> + IDREG_FIELD_ARCH_VAL(47)
>> + IDREG_FIELD_ARCH_VAL(48)
>> + IDREG_FIELD_ARCH_VAL(49)
>> + IDREG_FIELD_ARCH_VAL(50)
>> + IDREG_FIELD_ARCH_VAL(51)
>> + IDREG_FIELD_ARCH_VAL(52)
>> + IDREG_FIELD_ARCH_VAL(53)
>> + IDREG_FIELD_ARCH_VAL(54)
>> + IDREG_FIELD_ARCH_VAL(55)
>> + IDREG_FIELD_ARCH_VAL(56)
>> + IDREG_FIELD_ARCH_VAL(57)
>> + IDREG_FIELD_ARCH_VAL(58)
>> + IDREG_FIELD_ARCH_VAL(59)
>> + IDREG_FIELD_ARCH_VAL(60)
>> + IDREG_FIELD_ARCH_VAL(61)
>> + IDREG_FIELD_ARCH_VAL(62)
>> + IDREG_FIELD_ARCH_VAL(63)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, ABL_CMPs)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, DPFZS, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, DPFZS)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, EBEP, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, EBEP)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, ITE, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, ITE)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, ABLE, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, ABLE)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, PMICNTR, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, PMICNTR)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, SPMU, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, SPMU)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, CTX_CMPs, 24, 8)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_ARCH_VAL(16)
>> + IDREG_FIELD_ARCH_VAL(17)
>> + IDREG_FIELD_ARCH_VAL(18)
>> + IDREG_FIELD_ARCH_VAL(19)
>> + IDREG_FIELD_ARCH_VAL(20)
>> + IDREG_FIELD_ARCH_VAL(21)
>> + IDREG_FIELD_ARCH_VAL(22)
>> + IDREG_FIELD_ARCH_VAL(23)
>> + IDREG_FIELD_ARCH_VAL(24)
>> + IDREG_FIELD_ARCH_VAL(25)
>> + IDREG_FIELD_ARCH_VAL(26)
>> + IDREG_FIELD_ARCH_VAL(27)
>> + IDREG_FIELD_ARCH_VAL(28)
>> + IDREG_FIELD_ARCH_VAL(29)
>> + IDREG_FIELD_ARCH_VAL(30)
>> + IDREG_FIELD_ARCH_VAL(31)
>> + IDREG_FIELD_ARCH_VAL(32)
>> + IDREG_FIELD_ARCH_VAL(33)
>> + IDREG_FIELD_ARCH_VAL(34)
>> + IDREG_FIELD_ARCH_VAL(35)
>> + IDREG_FIELD_ARCH_VAL(36)
>> + IDREG_FIELD_ARCH_VAL(37)
>> + IDREG_FIELD_ARCH_VAL(38)
>> + IDREG_FIELD_ARCH_VAL(39)
>> + IDREG_FIELD_ARCH_VAL(40)
>> + IDREG_FIELD_ARCH_VAL(41)
>> + IDREG_FIELD_ARCH_VAL(42)
>> + IDREG_FIELD_ARCH_VAL(43)
>> + IDREG_FIELD_ARCH_VAL(44)
>> + IDREG_FIELD_ARCH_VAL(45)
>> + IDREG_FIELD_ARCH_VAL(46)
>> + IDREG_FIELD_ARCH_VAL(47)
>> + IDREG_FIELD_ARCH_VAL(48)
>> + IDREG_FIELD_ARCH_VAL(49)
>> + IDREG_FIELD_ARCH_VAL(50)
>> + IDREG_FIELD_ARCH_VAL(51)
>> + IDREG_FIELD_ARCH_VAL(52)
>> + IDREG_FIELD_ARCH_VAL(53)
>> + IDREG_FIELD_ARCH_VAL(54)
>> + IDREG_FIELD_ARCH_VAL(55)
>> + IDREG_FIELD_ARCH_VAL(56)
>> + IDREG_FIELD_ARCH_VAL(57)
>> + IDREG_FIELD_ARCH_VAL(58)
>> + IDREG_FIELD_ARCH_VAL(59)
>> + IDREG_FIELD_ARCH_VAL(60)
>> + IDREG_FIELD_ARCH_VAL(61)
>> + IDREG_FIELD_ARCH_VAL(62)
>> + IDREG_FIELD_ARCH_VAL(63)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, CTX_CMPs)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, WRPs, 16, 8)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_ARCH_VAL(16)
>> + IDREG_FIELD_ARCH_VAL(17)
>> + IDREG_FIELD_ARCH_VAL(18)
>> + IDREG_FIELD_ARCH_VAL(19)
>> + IDREG_FIELD_ARCH_VAL(20)
>> + IDREG_FIELD_ARCH_VAL(21)
>> + IDREG_FIELD_ARCH_VAL(22)
>> + IDREG_FIELD_ARCH_VAL(23)
>> + IDREG_FIELD_ARCH_VAL(24)
>> + IDREG_FIELD_ARCH_VAL(25)
>> + IDREG_FIELD_ARCH_VAL(26)
>> + IDREG_FIELD_ARCH_VAL(27)
>> + IDREG_FIELD_ARCH_VAL(28)
>> + IDREG_FIELD_ARCH_VAL(29)
>> + IDREG_FIELD_ARCH_VAL(30)
>> + IDREG_FIELD_ARCH_VAL(31)
>> + IDREG_FIELD_ARCH_VAL(32)
>> + IDREG_FIELD_ARCH_VAL(33)
>> + IDREG_FIELD_ARCH_VAL(34)
>> + IDREG_FIELD_ARCH_VAL(35)
>> + IDREG_FIELD_ARCH_VAL(36)
>> + IDREG_FIELD_ARCH_VAL(37)
>> + IDREG_FIELD_ARCH_VAL(38)
>> + IDREG_FIELD_ARCH_VAL(39)
>> + IDREG_FIELD_ARCH_VAL(40)
>> + IDREG_FIELD_ARCH_VAL(41)
>> + IDREG_FIELD_ARCH_VAL(42)
>> + IDREG_FIELD_ARCH_VAL(43)
>> + IDREG_FIELD_ARCH_VAL(44)
>> + IDREG_FIELD_ARCH_VAL(45)
>> + IDREG_FIELD_ARCH_VAL(46)
>> + IDREG_FIELD_ARCH_VAL(47)
>> + IDREG_FIELD_ARCH_VAL(48)
>> + IDREG_FIELD_ARCH_VAL(49)
>> + IDREG_FIELD_ARCH_VAL(50)
>> + IDREG_FIELD_ARCH_VAL(51)
>> + IDREG_FIELD_ARCH_VAL(52)
>> + IDREG_FIELD_ARCH_VAL(53)
>> + IDREG_FIELD_ARCH_VAL(54)
>> + IDREG_FIELD_ARCH_VAL(55)
>> + IDREG_FIELD_ARCH_VAL(56)
>> + IDREG_FIELD_ARCH_VAL(57)
>> + IDREG_FIELD_ARCH_VAL(58)
>> + IDREG_FIELD_ARCH_VAL(59)
>> + IDREG_FIELD_ARCH_VAL(60)
>> + IDREG_FIELD_ARCH_VAL(61)
>> + IDREG_FIELD_ARCH_VAL(62)
>> + IDREG_FIELD_ARCH_VAL(63)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, WRPs)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, BRPs, 8, 8)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_ARCH_VAL(16)
>> + IDREG_FIELD_ARCH_VAL(17)
>> + IDREG_FIELD_ARCH_VAL(18)
>> + IDREG_FIELD_ARCH_VAL(19)
>> + IDREG_FIELD_ARCH_VAL(20)
>> + IDREG_FIELD_ARCH_VAL(21)
>> + IDREG_FIELD_ARCH_VAL(22)
>> + IDREG_FIELD_ARCH_VAL(23)
>> + IDREG_FIELD_ARCH_VAL(24)
>> + IDREG_FIELD_ARCH_VAL(25)
>> + IDREG_FIELD_ARCH_VAL(26)
>> + IDREG_FIELD_ARCH_VAL(27)
>> + IDREG_FIELD_ARCH_VAL(28)
>> + IDREG_FIELD_ARCH_VAL(29)
>> + IDREG_FIELD_ARCH_VAL(30)
>> + IDREG_FIELD_ARCH_VAL(31)
>> + IDREG_FIELD_ARCH_VAL(32)
>> + IDREG_FIELD_ARCH_VAL(33)
>> + IDREG_FIELD_ARCH_VAL(34)
>> + IDREG_FIELD_ARCH_VAL(35)
>> + IDREG_FIELD_ARCH_VAL(36)
>> + IDREG_FIELD_ARCH_VAL(37)
>> + IDREG_FIELD_ARCH_VAL(38)
>> + IDREG_FIELD_ARCH_VAL(39)
>> + IDREG_FIELD_ARCH_VAL(40)
>> + IDREG_FIELD_ARCH_VAL(41)
>> + IDREG_FIELD_ARCH_VAL(42)
>> + IDREG_FIELD_ARCH_VAL(43)
>> + IDREG_FIELD_ARCH_VAL(44)
>> + IDREG_FIELD_ARCH_VAL(45)
>> + IDREG_FIELD_ARCH_VAL(46)
>> + IDREG_FIELD_ARCH_VAL(47)
>> + IDREG_FIELD_ARCH_VAL(48)
>> + IDREG_FIELD_ARCH_VAL(49)
>> + IDREG_FIELD_ARCH_VAL(50)
>> + IDREG_FIELD_ARCH_VAL(51)
>> + IDREG_FIELD_ARCH_VAL(52)
>> + IDREG_FIELD_ARCH_VAL(53)
>> + IDREG_FIELD_ARCH_VAL(54)
>> + IDREG_FIELD_ARCH_VAL(55)
>> + IDREG_FIELD_ARCH_VAL(56)
>> + IDREG_FIELD_ARCH_VAL(57)
>> + IDREG_FIELD_ARCH_VAL(58)
>> + IDREG_FIELD_ARCH_VAL(59)
>> + IDREG_FIELD_ARCH_VAL(60)
>> + IDREG_FIELD_ARCH_VAL(61)
>> + IDREG_FIELD_ARCH_VAL(62)
>> + IDREG_FIELD_ARCH_VAL(63)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, BRPs)
>> + IDREG_FIELD_START(ID_AA64DFR1_EL1, SYSPMUID, 0, 8)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_ARCH_VAL(16)
>> + IDREG_FIELD_ARCH_VAL(17)
>> + IDREG_FIELD_ARCH_VAL(18)
>> + IDREG_FIELD_ARCH_VAL(19)
>> + IDREG_FIELD_ARCH_VAL(20)
>> + IDREG_FIELD_ARCH_VAL(21)
>> + IDREG_FIELD_ARCH_VAL(22)
>> + IDREG_FIELD_ARCH_VAL(23)
>> + IDREG_FIELD_ARCH_VAL(24)
>> + IDREG_FIELD_ARCH_VAL(25)
>> + IDREG_FIELD_ARCH_VAL(26)
>> + IDREG_FIELD_ARCH_VAL(27)
>> + IDREG_FIELD_ARCH_VAL(28)
>> + IDREG_FIELD_ARCH_VAL(29)
>> + IDREG_FIELD_ARCH_VAL(30)
>> + IDREG_FIELD_ARCH_VAL(31)
>> + IDREG_FIELD_END(ID_AA64DFR1_EL1, SYSPMUID)
>> IDREG_END(ID_AA64DFR1_EL1)
>>
>> IDREG_START(ID_AA64DFR2_EL1)
>> - IDREG_FIELD(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
>> - IDREG_FIELD(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
>> - IDREG_FIELD(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
>> - IDREG_FIELD(ID_AA64DFR2_EL1, BWE, 4, 4)
>> - IDREG_FIELD(ID_AA64DFR2_EL1, STEP, 0, 4)
>> + IDREG_FIELD_START(ID_AA64DFR2_EL1, TRBE_EXC, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR2_EL1, TRBE_EXC)
>> + IDREG_FIELD_START(ID_AA64DFR2_EL1, SPE_nVM, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR2_EL1, SPE_nVM)
>> + IDREG_FIELD_START(ID_AA64DFR2_EL1, SPE_EXC, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR2_EL1, SPE_EXC)
>> + IDREG_FIELD_START(ID_AA64DFR2_EL1, BWE, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64DFR2_EL1, BWE)
>> + IDREG_FIELD_START(ID_AA64DFR2_EL1, STEP, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64DFR2_EL1, STEP)
>> IDREG_END(ID_AA64DFR2_EL1)
>>
>> IDREG_START(ID_AA64FPFR0_EL1)
>> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
>> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
>> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
>> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
>> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
>> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
>> - IDREG_FIELD(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
>> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
>> - IDREG_FIELD(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
>> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8CVT, 31, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8CVT)
>> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8FMA, 30, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8FMA)
>> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8DP4, 29, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8DP4)
>> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8DP2, 28, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8DP2)
>> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8MM8, 27, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8MM8)
>> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8MM4, 26, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8MM4)
>> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F16MM2, 15, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F16MM2)
>> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8E4M3, 1, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8E4M3)
>> + IDREG_FIELD_START(ID_AA64FPFR0_EL1, F8E5M2, 0, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64FPFR0_EL1, F8E5M2)
>> IDREG_END(ID_AA64FPFR0_EL1)
>>
>> IDREG_START(ID_AA64ISAR0_EL1)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, RNDR, 60, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, TLB, 56, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, TS, 52, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, FHM, 48, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, DP, 44, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, SM4, 40, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, SM3, 36, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, SHA3, 32, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, RDM, 28, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, Atomic, 20, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, CRC32, 16, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, SHA2, 12, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, SHA1, 8, 4)
>> - IDREG_FIELD(ID_AA64ISAR0_EL1, AES, 4, 4)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, RNDR, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, RNDR)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, TLB, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, TLB)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, TS, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, TS)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, FHM, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, FHM)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, DP, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, DP)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SM4, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SM4)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SM3, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SM3)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SHA3, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SHA3)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, RDM, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, RDM)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, Atomic, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, Atomic)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, CRC32, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, CRC32)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SHA2, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SHA2)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, SHA1, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, SHA1)
>> + IDREG_FIELD_START(ID_AA64ISAR0_EL1, AES, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR0_EL1, AES)
>> IDREG_END(ID_AA64ISAR0_EL1)
>>
>> IDREG_START(ID_AA64ISAR1_EL1)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, LS64, 60, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, XS, 56, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, I8MM, 52, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, DGH, 48, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, BF16, 44, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, SB, 36, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, GPI, 28, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, GPA, 24, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, FCMA, 16, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, API, 8, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, APA, 4, 4)
>> - IDREG_FIELD(ID_AA64ISAR1_EL1, DPB, 0, 4)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, LS64, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, LS64)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, XS, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, XS)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, I8MM, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, I8MM)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, DGH, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, DGH)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, BF16, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, BF16)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, SPECRES, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, SPECRES)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, SB, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, SB)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, FRINTTS, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, FRINTTS)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, GPI, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, GPI)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, GPA, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, GPA)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, LRCPC, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, LRCPC)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, FCMA, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, FCMA)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, JSCVT, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, JSCVT)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, API, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, API)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, APA, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, APA)
>> + IDREG_FIELD_START(ID_AA64ISAR1_EL1, DPB, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR1_EL1, DPB)
>> IDREG_END(ID_AA64ISAR1_EL1)
>>
>> IDREG_START(ID_AA64ISAR2_EL1)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, LUT, 56, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, CSSC, 52, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, BC, 20, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, MOPS, 16, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, APA3, 12, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, GPA3, 8, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, RPRES, 4, 4)
>> - IDREG_FIELD(ID_AA64ISAR2_EL1, WFxT, 0, 4)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, ATS1A, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, ATS1A)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, LUT, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, LUT)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, CSSC, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, CSSC)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, RPRFM, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, RPRFM)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, PCDPHINT, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, PCDPHINT)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, PRFMSLC, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, PRFMSLC)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, SYSINSTR_128, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, SYSINSTR_128)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, SYSREG_128, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, SYSREG_128)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, CLRBHB, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, CLRBHB)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, PAC_frac, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, PAC_frac)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, BC, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, BC)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, MOPS, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, MOPS)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, APA3, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, APA3)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, GPA3, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, GPA3)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, RPRES, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, RPRES)
>> + IDREG_FIELD_START(ID_AA64ISAR2_EL1, WFxT, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR2_EL1, WFxT)
>> IDREG_END(ID_AA64ISAR2_EL1)
>>
>> IDREG_START(ID_AA64ISAR3_EL1)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, LSCP, 44, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, MTETC, 36, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, LSUI, 24, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, LSFE, 16, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, PACM, 12, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
>> - IDREG_FIELD(ID_AA64ISAR3_EL1, CPA, 0, 4)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSCP, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSCP)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSCSHINT, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSCSHINT)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, MTETC, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, MTETC)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, PAC_frac2, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, PAC_frac2)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, FPRCVT, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, FPRCVT)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSUI, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSUI)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, OCCMO, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, OCCMO)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, LSFE, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, LSFE)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, PACM, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, PACM)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, TLBIW, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, TLBIW)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, FAMINMAX, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, FAMINMAX)
>> + IDREG_FIELD_START(ID_AA64ISAR3_EL1, CPA, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ISAR3_EL1, CPA)
>> IDREG_END(ID_AA64ISAR3_EL1)
>>
>> IDREG_START(ID_AA64MMFR0_EL1)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, ECV, 60, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, FGT, 56, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, ExS, 44, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran4, 28, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran64, 24, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, TGran16, 20, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
>> - IDREG_FIELD(ID_AA64MMFR0_EL1, PARange, 0, 4)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, ECV, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, ECV)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, FGT, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, FGT)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, ExS, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, ExS)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran4_2, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran4_2)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran64_2, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran64_2)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran16_2, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran16_2)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran4, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran4)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran64, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran64)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, TGran16, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, TGran16)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, BigEndEL0, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, BigEndEL0)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, SNSMem, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, SNSMem)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, BigEnd, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, BigEnd)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, ASIDBits, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, ASIDBits)
>> + IDREG_FIELD_START(ID_AA64MMFR0_EL1, PARange, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_END(ID_AA64MMFR0_EL1, PARange)
>> IDREG_END(ID_AA64MMFR0_EL1)
>>
>> IDREG_START(ID_AA64MMFR1_EL1)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, CMOW, 56, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, AFP, 44, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, HCX, 40, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, ETS, 36, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, TWED, 32, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, XNX, 28, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, PAN, 20, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, LO, 16, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, HPDS, 12, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, VH, 8, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
>> - IDREG_FIELD(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, ECBHB, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, ECBHB)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, CMOW, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, CMOW)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, TIDCP1, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, TIDCP1)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, nTLBPA, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, nTLBPA)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, AFP, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, AFP)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, HCX, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, HCX)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, ETS, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, ETS)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, TWED, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, TWED)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, XNX, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, XNX)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, SpecSEI, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, SpecSEI)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, PAN, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, PAN)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, LO, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, LO)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, HPDS, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, HPDS)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, VH, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, VH)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, VMIDBits, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, VMIDBits)
>> + IDREG_FIELD_START(ID_AA64MMFR1_EL1, HAFDBS, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_END(ID_AA64MMFR1_EL1, HAFDBS)
>> IDREG_END(ID_AA64MMFR1_EL1)
>>
>> IDREG_START(ID_AA64MMFR2_EL1)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, E0PD, 60, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, EVT, 56, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, BBM, 52, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, TTL, 48, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, FWB, 40, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, IDS, 36, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, AT, 32, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, ST, 28, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, NV, 24, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, VARange, 16, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, IESB, 12, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, LSM, 8, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, UAO, 4, 4)
>> - IDREG_FIELD(ID_AA64MMFR2_EL1, CnP, 0, 4)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, E0PD, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, E0PD)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, EVT, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, EVT)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, BBM, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, BBM)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, TTL, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, TTL)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, FWB, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, FWB)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, IDS, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, IDS)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, AT, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, AT)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, ST, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, ST)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, NV, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, NV)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, CCIDX, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, CCIDX)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, VARange, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, VARange)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, IESB, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, IESB)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, LSM, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, LSM)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, UAO, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, UAO)
>> + IDREG_FIELD_START(ID_AA64MMFR2_EL1, CnP, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR2_EL1, CnP)
>> IDREG_END(ID_AA64MMFR2_EL1)
>>
>> IDREG_START(ID_AA64MMFR3_EL1)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, ADERR, 56, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, SDERR, 52, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, ANERR, 44, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, SNERR, 40, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, D128_2, 36, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, D128, 32, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, MEC, 28, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, AIE, 24, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, S2POE, 20, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, S1POE, 16, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
>> - IDREG_FIELD(ID_AA64MMFR3_EL1, TCRX, 0, 4)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, Spec_FPACC, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, Spec_FPACC)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, ADERR, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, ADERR)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, SDERR, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, SDERR)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, ANERR, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, ANERR)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, SNERR, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, SNERR)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, D128_2, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, D128_2)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, D128, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, D128)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, MEC, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, MEC)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, AIE, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, AIE)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, S2POE, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, S2POE)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, S1POE, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, S1POE)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, S2PIE, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, S2PIE)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, S1PIE, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, S1PIE)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, SCTLRX, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, SCTLRX)
>> + IDREG_FIELD_START(ID_AA64MMFR3_EL1, TCRX, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR3_EL1, TCRX)
>> IDREG_END(ID_AA64MMFR3_EL1)
>>
>> IDREG_START(ID_AA64MMFR4_EL1)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, SCRX, 56, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, TEV, 52, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, TPS, 48, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, TLBID, 40, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, EAESR, 32, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, E2H0, 24, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, ASID2, 8, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, EIESB, 4, 4)
>> - IDREG_FIELD(ID_AA64MMFR4_EL1, PoPS, 0, 4)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, MTEFGT, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, MTEFGT)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, SCRX, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, SCRX)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, TEV, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, TEV)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, TPS, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, TPS)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, SRMASK, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, SRMASK)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, TLBID, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, TLBID)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, E3DSE, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, E3DSE)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, EAESR, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, EAESR)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, RMEGDI, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, RMEGDI)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, E2H0, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, E2H0)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, NV_frac, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, NV_frac)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, FGWTE3, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, FGWTE3)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, HACDBS, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, HACDBS)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, ASID2, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, ASID2)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, EIESB, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, EIESB)
>> + IDREG_FIELD_START(ID_AA64MMFR4_EL1, PoPS, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64MMFR4_EL1, PoPS)
>> IDREG_END(ID_AA64MMFR4_EL1)
>>
>> IDREG_START(ID_AA64PFR0_EL1)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, CSV3, 60, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, CSV2, 56, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, RME, 52, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, DIT, 48, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, AMU, 44, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, MPAM, 40, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, SEL2, 36, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, SVE, 32, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, RAS, 28, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, GIC, 24, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, FP, 16, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, EL3, 12, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, EL2, 8, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, EL1, 4, 4)
>> - IDREG_FIELD(ID_AA64PFR0_EL1, EL0, 0, 4)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, CSV3, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, CSV3)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, CSV2, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, CSV2)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, RME, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, RME)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, DIT, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, DIT)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, AMU, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, AMU)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, MPAM, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, MPAM)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, SEL2, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, SEL2)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, SVE, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, SVE)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, RAS, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, RAS)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, GIC, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, GIC)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, AdvSIMD, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, AdvSIMD)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, FP, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, FP)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, EL3, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, EL3)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, EL2, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, EL2)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, EL1, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, EL1)
>> + IDREG_FIELD_START(ID_AA64PFR0_EL1, EL0, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR0_EL1, EL0)
>> IDREG_END(ID_AA64PFR0_EL1)
>>
>> IDREG_START(ID_AA64PFR1_EL1)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, PFAR, 60, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, DF2, 56, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, MTEX, 52, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, THE, 48, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, GCS, 44, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, NMI, 36, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, SME, 24, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, MTE, 8, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, SSBS, 4, 4)
>> - IDREG_FIELD(ID_AA64PFR1_EL1, BT, 0, 4)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, PFAR, 60, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, PFAR)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, DF2, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, DF2)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, MTEX, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, MTEX)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, THE, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, THE)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, GCS, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, GCS)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, MTE_frac, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, MTE_frac)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, NMI, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, NMI)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, CSV2_frac, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, CSV2_frac)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, RNDR_trap, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, RNDR_trap)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, SME, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, SME)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, MPAM_frac, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, MPAM_frac)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, RAS_frac, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, RAS_frac)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, MTE, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, MTE)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, SSBS, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, SSBS)
>> + IDREG_FIELD_START(ID_AA64PFR1_EL1, BT, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR1_EL1, BT)
>> IDREG_END(ID_AA64PFR1_EL1)
>>
>> IDREG_START(ID_AA64PFR2_EL1)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, VMTETC, 40, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, VMTE, 36, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, FPMR, 32, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, MPAM2, 28, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, FGDT, 24, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, UINJ, 16, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, GCIE, 12, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
>> - IDREG_FIELD(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTETCL, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, VMTETCL)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTETC, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, VMTETC)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, VMTE, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, VMTE)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, FPMR, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, FPMR)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MPAM2, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MPAM2)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, FGDT, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, FGDT)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MTEEIRG, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MTEEIRG)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, UINJ, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, UINJ)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, GCIE, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, GCIE)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MTEFAR, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MTEFAR)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MTESTOREONLY, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MTESTOREONLY)
>> + IDREG_FIELD_START(ID_AA64PFR2_EL1, MTEPERM, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64PFR2_EL1, MTEPERM)
>> IDREG_END(ID_AA64PFR2_EL1)
>>
>> IDREG_START(ID_AA64SMFR0_EL1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, FA64, 63, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, LUT6, 61, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, SMEver, 56, 4)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, I16I64, 52, 4)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, F64F64, 48, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, I16I32, 44, 4)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, B16B16, 43, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, F16F16, 42, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, F8F16, 41, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, F8F32, 40, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, I8I32, 36, 4)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, F16F32, 35, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, B16F32, 34, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, F32F32, 32, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, AES, 24, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, STMOP, 16, 1)
>> - IDREG_FIELD(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, FA64, 63, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, FA64)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, LUT6, 61, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, LUT6)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, LUTv2, 60, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, LUTv2)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SMEver, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SMEver)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, I16I64, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, I16I64)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F64F64, 48, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F64F64)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, I16I32, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, I16I32)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, B16B16, 43, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, B16B16)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F16F16, 42, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F16F16)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F8F16, 41, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F8F16)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F8F32, 40, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F8F32)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, I8I32, 36, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, I8I32)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F16F32, 35, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F16F32)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, B16F32, 34, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, B16F32)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, BI32I32, 33, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, BI32I32)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, F32F32, 32, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, F32F32)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8FMA, 30, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8FMA)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8DP4, 29, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8DP4)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SF8DP2, 28, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SF8DP2)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SBitPerm, 25, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SBitPerm)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, AES, 24, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, AES)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SFEXPA, 23, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SFEXPA)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, STMOP, 16, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, STMOP)
>> + IDREG_FIELD_START(ID_AA64SMFR0_EL1, SMOP4, 0, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64SMFR0_EL1, SMOP4)
>> IDREG_END(ID_AA64SMFR0_EL1)
>>
>> IDREG_START(ID_AA64ZFR0_EL1)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, F64MM, 56, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, F32MM, 52, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, F16MM, 48, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, I8MM, 44, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, SM4, 40, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, SHA3, 32, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, B16B16, 24, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, BF16, 20, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, AES, 4, 4)
>> - IDREG_FIELD(ID_AA64ZFR0_EL1, SVEver, 0, 4)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, F64MM, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, F64MM)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, F32MM, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, F32MM)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, F16MM, 48, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, F16MM)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, I8MM, 44, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, I8MM)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, SM4, 40, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, SM4)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, SHA3, 32, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, SHA3)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, B16B16, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, B16B16)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, BF16, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, BF16)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, BitPerm, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, BitPerm)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, EltPerm, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, EltPerm)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, AES, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, AES)
>> + IDREG_FIELD_START(ID_AA64ZFR0_EL1, SVEver, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_END(ID_AA64ZFR0_EL1, SVEver)
>> IDREG_END(ID_AA64ZFR0_EL1)
>>
>> IDREG_START(ID_AFR0_EL1)
>> IDREG_END(ID_AFR0_EL1)
>>
>> IDREG_START(ID_DFR0_EL1)
>> - IDREG_FIELD(ID_DFR0_EL1, TraceFilt, 28, 4)
>> - IDREG_FIELD(ID_DFR0_EL1, PerfMon, 24, 4)
>> - IDREG_FIELD(ID_DFR0_EL1, MProfDbg, 20, 4)
>> - IDREG_FIELD(ID_DFR0_EL1, MMapTrc, 16, 4)
>> - IDREG_FIELD(ID_DFR0_EL1, CopTrc, 12, 4)
>> - IDREG_FIELD(ID_DFR0_EL1, MMapDbg, 8, 4)
>> + IDREG_FIELD_START(ID_DFR0_EL1, TraceFilt, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_DFR0_EL1, TraceFilt)
>> + IDREG_FIELD_START(ID_DFR0_EL1, PerfMon, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_DFR0_EL1, PerfMon)
>> + IDREG_FIELD_START(ID_DFR0_EL1, MProfDbg, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_DFR0_EL1, MProfDbg)
>> + IDREG_FIELD_START(ID_DFR0_EL1, MMapTrc, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_DFR0_EL1, MMapTrc)
>> + IDREG_FIELD_START(ID_DFR0_EL1, CopTrc, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_DFR0_EL1, CopTrc)
>> + IDREG_FIELD_START(ID_DFR0_EL1, MMapDbg, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_END(ID_DFR0_EL1, MMapDbg)
>> IDREG_FIELD(ID_DFR0_EL1, CopSDbg, 4, 4)
>> - IDREG_FIELD(ID_DFR0_EL1, CopDbg, 0, 4)
>> + IDREG_FIELD_START(ID_DFR0_EL1, CopDbg, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_END(ID_DFR0_EL1, CopDbg)
>> IDREG_END(ID_DFR0_EL1)
>>
>> IDREG_START(ID_DFR1_EL1)
>> - IDREG_FIELD(ID_DFR1_EL1, HPMN0, 4, 4)
>> - IDREG_FIELD(ID_DFR1_EL1, MTPMU, 0, 4)
>> + IDREG_FIELD_START(ID_DFR1_EL1, HPMN0, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_DFR1_EL1, HPMN0)
>> + IDREG_FIELD_START(ID_DFR1_EL1, MTPMU, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_DFR1_EL1, MTPMU)
>> IDREG_END(ID_DFR1_EL1)
>>
>> IDREG_START(ID_ISAR0_EL1)
>> - IDREG_FIELD(ID_ISAR0_EL1, Divide, 24, 4)
>> - IDREG_FIELD(ID_ISAR0_EL1, Debug, 20, 4)
>> - IDREG_FIELD(ID_ISAR0_EL1, Coproc, 16, 4)
>> - IDREG_FIELD(ID_ISAR0_EL1, CmpBranch, 12, 4)
>> - IDREG_FIELD(ID_ISAR0_EL1, BitField, 8, 4)
>> - IDREG_FIELD(ID_ISAR0_EL1, BitCount, 4, 4)
>> - IDREG_FIELD(ID_ISAR0_EL1, Swap, 0, 4)
>> + IDREG_FIELD_START(ID_ISAR0_EL1, Divide, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR0_EL1, Divide)
>> + IDREG_FIELD_START(ID_ISAR0_EL1, Debug, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR0_EL1, Debug)
>> + IDREG_FIELD_START(ID_ISAR0_EL1, Coproc, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_END(ID_ISAR0_EL1, Coproc)
>> + IDREG_FIELD_START(ID_ISAR0_EL1, CmpBranch, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR0_EL1, CmpBranch)
>> + IDREG_FIELD_START(ID_ISAR0_EL1, BitField, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR0_EL1, BitField)
>> + IDREG_FIELD_START(ID_ISAR0_EL1, BitCount, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR0_EL1, BitCount)
>> + IDREG_FIELD_START(ID_ISAR0_EL1, Swap, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR0_EL1, Swap)
>> IDREG_END(ID_ISAR0_EL1)
>>
>> IDREG_START(ID_ISAR1_EL1)
>> - IDREG_FIELD(ID_ISAR1_EL1, Jazelle, 28, 4)
>> - IDREG_FIELD(ID_ISAR1_EL1, Interwork, 24, 4)
>> - IDREG_FIELD(ID_ISAR1_EL1, Immediate, 20, 4)
>> - IDREG_FIELD(ID_ISAR1_EL1, IfThen, 16, 4)
>> - IDREG_FIELD(ID_ISAR1_EL1, Extend, 12, 4)
>> - IDREG_FIELD(ID_ISAR1_EL1, Except_AR, 8, 4)
>> - IDREG_FIELD(ID_ISAR1_EL1, Except, 4, 4)
>> - IDREG_FIELD(ID_ISAR1_EL1, Endian, 0, 4)
>> + IDREG_FIELD_START(ID_ISAR1_EL1, Jazelle, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR1_EL1, Jazelle)
>> + IDREG_FIELD_START(ID_ISAR1_EL1, Interwork, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_ISAR1_EL1, Interwork)
>> + IDREG_FIELD_START(ID_ISAR1_EL1, Immediate, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR1_EL1, Immediate)
>> + IDREG_FIELD_START(ID_ISAR1_EL1, IfThen, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR1_EL1, IfThen)
>> + IDREG_FIELD_START(ID_ISAR1_EL1, Extend, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR1_EL1, Extend)
>> + IDREG_FIELD_START(ID_ISAR1_EL1, Except_AR, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR1_EL1, Except_AR)
>> + IDREG_FIELD_START(ID_ISAR1_EL1, Except, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR1_EL1, Except)
>> + IDREG_FIELD_START(ID_ISAR1_EL1, Endian, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR1_EL1, Endian)
>> IDREG_END(ID_ISAR1_EL1)
>>
>> IDREG_START(ID_ISAR2_EL1)
>> - IDREG_FIELD(ID_ISAR2_EL1, Reversal, 28, 4)
>> - IDREG_FIELD(ID_ISAR2_EL1, PSR_AR, 24, 4)
>> - IDREG_FIELD(ID_ISAR2_EL1, MultU, 20, 4)
>> - IDREG_FIELD(ID_ISAR2_EL1, MultS, 16, 4)
>> - IDREG_FIELD(ID_ISAR2_EL1, Mult, 12, 4)
>> - IDREG_FIELD(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
>> - IDREG_FIELD(ID_ISAR2_EL1, MemHint, 4, 4)
>> - IDREG_FIELD(ID_ISAR2_EL1, LoadStore, 0, 4)
>> + IDREG_FIELD_START(ID_ISAR2_EL1, Reversal, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR2_EL1, Reversal)
>> + IDREG_FIELD_START(ID_ISAR2_EL1, PSR_AR, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR2_EL1, PSR_AR)
>> + IDREG_FIELD_START(ID_ISAR2_EL1, MultU, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR2_EL1, MultU)
>> + IDREG_FIELD_START(ID_ISAR2_EL1, MultS, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_ISAR2_EL1, MultS)
>> + IDREG_FIELD_START(ID_ISAR2_EL1, Mult, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR2_EL1, Mult)
>> + IDREG_FIELD_START(ID_ISAR2_EL1, MultiAccessInt, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR2_EL1, MultiAccessInt)
>> + IDREG_FIELD_START(ID_ISAR2_EL1, MemHint, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_END(ID_ISAR2_EL1, MemHint)
>> + IDREG_FIELD_START(ID_ISAR2_EL1, LoadStore, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR2_EL1, LoadStore)
>> IDREG_END(ID_ISAR2_EL1)
>>
>> IDREG_START(ID_ISAR3_EL1)
>> - IDREG_FIELD(ID_ISAR3_EL1, T32EE, 28, 4)
>> - IDREG_FIELD(ID_ISAR3_EL1, TrueNOP, 24, 4)
>> - IDREG_FIELD(ID_ISAR3_EL1, T32Copy, 20, 4)
>> - IDREG_FIELD(ID_ISAR3_EL1, TabBranch, 16, 4)
>> - IDREG_FIELD(ID_ISAR3_EL1, SynchPrim, 12, 4)
>> - IDREG_FIELD(ID_ISAR3_EL1, SVC, 8, 4)
>> - IDREG_FIELD(ID_ISAR3_EL1, SIMD, 4, 4)
>> - IDREG_FIELD(ID_ISAR3_EL1, Saturate, 0, 4)
>> + IDREG_FIELD_START(ID_ISAR3_EL1, T32EE, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR3_EL1, T32EE)
>> + IDREG_FIELD_START(ID_ISAR3_EL1, TrueNOP, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR3_EL1, TrueNOP)
>> + IDREG_FIELD_START(ID_ISAR3_EL1, T32Copy, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR3_EL1, T32Copy)
>> + IDREG_FIELD_START(ID_ISAR3_EL1, TabBranch, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR3_EL1, TabBranch)
>> + IDREG_FIELD_START(ID_ISAR3_EL1, SynchPrim, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR3_EL1, SynchPrim)
>> + IDREG_FIELD_START(ID_ISAR3_EL1, SVC, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR3_EL1, SVC)
>> + IDREG_FIELD_START(ID_ISAR3_EL1, SIMD, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_ISAR3_EL1, SIMD)
>> + IDREG_FIELD_START(ID_ISAR3_EL1, Saturate, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR3_EL1, Saturate)
>> IDREG_END(ID_ISAR3_EL1)
>>
>> IDREG_START(ID_ISAR4_EL1)
>> - IDREG_FIELD(ID_ISAR4_EL1, SWP_frac, 28, 4)
>> - IDREG_FIELD(ID_ISAR4_EL1, PSR_M, 24, 4)
>> - IDREG_FIELD(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
>> - IDREG_FIELD(ID_ISAR4_EL1, Barrier, 16, 4)
>> - IDREG_FIELD(ID_ISAR4_EL1, SMC, 12, 4)
>> - IDREG_FIELD(ID_ISAR4_EL1, Writeback, 8, 4)
>> - IDREG_FIELD(ID_ISAR4_EL1, WithShifts, 4, 4)
>> - IDREG_FIELD(ID_ISAR4_EL1, Unpriv, 0, 4)
>> + IDREG_FIELD_START(ID_ISAR4_EL1, SWP_frac, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR4_EL1, SWP_frac)
>> + IDREG_FIELD_START(ID_ISAR4_EL1, PSR_M, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR4_EL1, PSR_M)
>> + IDREG_FIELD_START(ID_ISAR4_EL1, SynchPrim_frac, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_ISAR4_EL1, SynchPrim_frac)
>> + IDREG_FIELD_START(ID_ISAR4_EL1, Barrier, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR4_EL1, Barrier)
>> + IDREG_FIELD_START(ID_ISAR4_EL1, SMC, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR4_EL1, SMC)
>> + IDREG_FIELD_START(ID_ISAR4_EL1, Writeback, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR4_EL1, Writeback)
>> + IDREG_FIELD_START(ID_ISAR4_EL1, WithShifts, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_END(ID_ISAR4_EL1, WithShifts)
>> + IDREG_FIELD_START(ID_ISAR4_EL1, Unpriv, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR4_EL1, Unpriv)
>> IDREG_END(ID_ISAR4_EL1)
>>
>> IDREG_START(ID_ISAR5_EL1)
>> - IDREG_FIELD(ID_ISAR5_EL1, VCMA, 28, 4)
>> - IDREG_FIELD(ID_ISAR5_EL1, RDM, 24, 4)
>> - IDREG_FIELD(ID_ISAR5_EL1, CRC32, 16, 4)
>> - IDREG_FIELD(ID_ISAR5_EL1, SHA2, 12, 4)
>> - IDREG_FIELD(ID_ISAR5_EL1, SHA1, 8, 4)
>> - IDREG_FIELD(ID_ISAR5_EL1, AES, 4, 4)
>> - IDREG_FIELD(ID_ISAR5_EL1, SEVL, 0, 4)
>> + IDREG_FIELD_START(ID_ISAR5_EL1, VCMA, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR5_EL1, VCMA)
>> + IDREG_FIELD_START(ID_ISAR5_EL1, RDM, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR5_EL1, RDM)
>> + IDREG_FIELD_START(ID_ISAR5_EL1, CRC32, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR5_EL1, CRC32)
>> + IDREG_FIELD_START(ID_ISAR5_EL1, SHA2, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR5_EL1, SHA2)
>> + IDREG_FIELD_START(ID_ISAR5_EL1, SHA1, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR5_EL1, SHA1)
>> + IDREG_FIELD_START(ID_ISAR5_EL1, AES, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR5_EL1, AES)
>> + IDREG_FIELD_START(ID_ISAR5_EL1, SEVL, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR5_EL1, SEVL)
>> IDREG_END(ID_ISAR5_EL1)
>>
>> IDREG_START(ID_ISAR6_EL1)
>> - IDREG_FIELD(ID_ISAR6_EL1, CLRBHB, 28, 4)
>> - IDREG_FIELD(ID_ISAR6_EL1, I8MM, 24, 4)
>> - IDREG_FIELD(ID_ISAR6_EL1, BF16, 20, 4)
>> - IDREG_FIELD(ID_ISAR6_EL1, SPECRES, 16, 4)
>> - IDREG_FIELD(ID_ISAR6_EL1, SB, 12, 4)
>> - IDREG_FIELD(ID_ISAR6_EL1, FHM, 8, 4)
>> - IDREG_FIELD(ID_ISAR6_EL1, DP, 4, 4)
>> - IDREG_FIELD(ID_ISAR6_EL1, JSCVT, 0, 4)
>> + IDREG_FIELD_START(ID_ISAR6_EL1, CLRBHB, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR6_EL1, CLRBHB)
>> + IDREG_FIELD_START(ID_ISAR6_EL1, I8MM, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR6_EL1, I8MM)
>> + IDREG_FIELD_START(ID_ISAR6_EL1, BF16, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR6_EL1, BF16)
>> + IDREG_FIELD_START(ID_ISAR6_EL1, SPECRES, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_ISAR6_EL1, SPECRES)
>> + IDREG_FIELD_START(ID_ISAR6_EL1, SB, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR6_EL1, SB)
>> + IDREG_FIELD_START(ID_ISAR6_EL1, FHM, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR6_EL1, FHM)
>> + IDREG_FIELD_START(ID_ISAR6_EL1, DP, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR6_EL1, DP)
>> + IDREG_FIELD_START(ID_ISAR6_EL1, JSCVT, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_ISAR6_EL1, JSCVT)
>> IDREG_END(ID_ISAR6_EL1)
>>
>> IDREG_START(ID_MMFR0_EL1)
>> - IDREG_FIELD(ID_MMFR0_EL1, InnerShr, 28, 4)
>> - IDREG_FIELD(ID_MMFR0_EL1, FCSE, 24, 4)
>> - IDREG_FIELD(ID_MMFR0_EL1, AuxReg, 20, 4)
>> - IDREG_FIELD(ID_MMFR0_EL1, TCM, 16, 4)
>> - IDREG_FIELD(ID_MMFR0_EL1, ShareLvl, 12, 4)
>> - IDREG_FIELD(ID_MMFR0_EL1, OuterShr, 8, 4)
>> - IDREG_FIELD(ID_MMFR0_EL1, PMSA, 4, 4)
>> - IDREG_FIELD(ID_MMFR0_EL1, VMSA, 0, 4)
>> + IDREG_FIELD_START(ID_MMFR0_EL1, InnerShr, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_MMFR0_EL1, InnerShr)
>> + IDREG_FIELD_START(ID_MMFR0_EL1, FCSE, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR0_EL1, FCSE)
>> + IDREG_FIELD_START(ID_MMFR0_EL1, AuxReg, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR0_EL1, AuxReg)
>> + IDREG_FIELD_START(ID_MMFR0_EL1, TCM, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_MMFR0_EL1, TCM)
>> + IDREG_FIELD_START(ID_MMFR0_EL1, ShareLvl, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR0_EL1, ShareLvl)
>> + IDREG_FIELD_START(ID_MMFR0_EL1, OuterShr, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_MMFR0_EL1, OuterShr)
>> + IDREG_FIELD_START(ID_MMFR0_EL1, PMSA, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_MMFR0_EL1, PMSA)
>> + IDREG_FIELD_START(ID_MMFR0_EL1, VMSA, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_END(ID_MMFR0_EL1, VMSA)
>> IDREG_END(ID_MMFR0_EL1)
>>
>> IDREG_START(ID_MMFR1_EL1)
>> - IDREG_FIELD(ID_MMFR1_EL1, BPred, 28, 4)
>> - IDREG_FIELD(ID_MMFR1_EL1, L1TstCln, 24, 4)
>> - IDREG_FIELD(ID_MMFR1_EL1, L1Uni, 20, 4)
>> - IDREG_FIELD(ID_MMFR1_EL1, L1Hvd, 16, 4)
>> - IDREG_FIELD(ID_MMFR1_EL1, L1UniSW, 12, 4)
>> - IDREG_FIELD(ID_MMFR1_EL1, L1HvdSW, 8, 4)
>> - IDREG_FIELD(ID_MMFR1_EL1, L1UniVA, 4, 4)
>> - IDREG_FIELD(ID_MMFR1_EL1, L1HvdVA, 0, 4)
>> + IDREG_FIELD_START(ID_MMFR1_EL1, BPred, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_END(ID_MMFR1_EL1, BPred)
>> + IDREG_FIELD_START(ID_MMFR1_EL1, L1TstCln, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR1_EL1, L1TstCln)
>> + IDREG_FIELD_START(ID_MMFR1_EL1, L1Uni, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR1_EL1, L1Uni)
>> + IDREG_FIELD_START(ID_MMFR1_EL1, L1Hvd, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_MMFR1_EL1, L1Hvd)
>> + IDREG_FIELD_START(ID_MMFR1_EL1, L1UniSW, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_MMFR1_EL1, L1UniSW)
>> + IDREG_FIELD_START(ID_MMFR1_EL1, L1HvdSW, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_MMFR1_EL1, L1HvdSW)
>> + IDREG_FIELD_START(ID_MMFR1_EL1, L1UniVA, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR1_EL1, L1UniVA)
>> + IDREG_FIELD_START(ID_MMFR1_EL1, L1HvdVA, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR1_EL1, L1HvdVA)
>> IDREG_END(ID_MMFR1_EL1)
>>
>> IDREG_START(ID_MMFR2_EL1)
>> - IDREG_FIELD(ID_MMFR2_EL1, HWAccFlg, 28, 4)
>> - IDREG_FIELD(ID_MMFR2_EL1, WFIStall, 24, 4)
>> - IDREG_FIELD(ID_MMFR2_EL1, MemBarr, 20, 4)
>> - IDREG_FIELD(ID_MMFR2_EL1, UniTLB, 16, 4)
>> + IDREG_FIELD_START(ID_MMFR2_EL1, HWAccFlg, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR2_EL1, HWAccFlg)
>> + IDREG_FIELD_START(ID_MMFR2_EL1, WFIStall, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR2_EL1, WFIStall)
>> + IDREG_FIELD_START(ID_MMFR2_EL1, MemBarr, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR2_EL1, MemBarr)
>> + IDREG_FIELD_START(ID_MMFR2_EL1, UniTLB, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_END(ID_MMFR2_EL1, UniTLB)
>> IDREG_FIELD(ID_MMFR2_EL1, HvdTLB, 12, 4)
>> - IDREG_FIELD(ID_MMFR2_EL1, L1HvdRng, 8, 4)
>> - IDREG_FIELD(ID_MMFR2_EL1, L1HvdBG, 4, 4)
>> - IDREG_FIELD(ID_MMFR2_EL1, L1HvdFG, 0, 4)
>> + IDREG_FIELD_START(ID_MMFR2_EL1, L1HvdRng, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR2_EL1, L1HvdRng)
>> + IDREG_FIELD_START(ID_MMFR2_EL1, L1HvdBG, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR2_EL1, L1HvdBG)
>> + IDREG_FIELD_START(ID_MMFR2_EL1, L1HvdFG, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR2_EL1, L1HvdFG)
>> IDREG_END(ID_MMFR2_EL1)
>>
>> IDREG_START(ID_MMFR3_EL1)
>> - IDREG_FIELD(ID_MMFR3_EL1, Supersec, 28, 4)
>> - IDREG_FIELD(ID_MMFR3_EL1, CMemSz, 24, 4)
>> - IDREG_FIELD(ID_MMFR3_EL1, CohWalk, 20, 4)
>> - IDREG_FIELD(ID_MMFR3_EL1, PAN, 16, 4)
>> - IDREG_FIELD(ID_MMFR3_EL1, MaintBcst, 12, 4)
>> - IDREG_FIELD(ID_MMFR3_EL1, BPMaint, 8, 4)
>> - IDREG_FIELD(ID_MMFR3_EL1, CMaintSW, 4, 4)
>> - IDREG_FIELD(ID_MMFR3_EL1, CMaintVA, 0, 4)
>> + IDREG_FIELD_START(ID_MMFR3_EL1, Supersec, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(ID_MMFR3_EL1, Supersec)
>> + IDREG_FIELD_START(ID_MMFR3_EL1, CMemSz, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR3_EL1, CMemSz)
>> + IDREG_FIELD_START(ID_MMFR3_EL1, CohWalk, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR3_EL1, CohWalk)
>> + IDREG_FIELD_START(ID_MMFR3_EL1, PAN, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR3_EL1, PAN)
>> + IDREG_FIELD_START(ID_MMFR3_EL1, MaintBcst, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR3_EL1, MaintBcst)
>> + IDREG_FIELD_START(ID_MMFR3_EL1, BPMaint, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR3_EL1, BPMaint)
>> + IDREG_FIELD_START(ID_MMFR3_EL1, CMaintSW, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR3_EL1, CMaintSW)
>> + IDREG_FIELD_START(ID_MMFR3_EL1, CMaintVA, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR3_EL1, CMaintVA)
>> IDREG_END(ID_MMFR3_EL1)
>>
>> IDREG_START(ID_MMFR4_EL1)
>> - IDREG_FIELD(ID_MMFR4_EL1, EVT, 28, 4)
>> - IDREG_FIELD(ID_MMFR4_EL1, CCIDX, 24, 4)
>> - IDREG_FIELD(ID_MMFR4_EL1, LSM, 20, 4)
>> - IDREG_FIELD(ID_MMFR4_EL1, HPDS, 16, 4)
>> - IDREG_FIELD(ID_MMFR4_EL1, CnP, 12, 4)
>> - IDREG_FIELD(ID_MMFR4_EL1, XNX, 8, 4)
>> - IDREG_FIELD(ID_MMFR4_EL1, AC2, 4, 4)
>> - IDREG_FIELD(ID_MMFR4_EL1, SpecSEI, 0, 4)
>> + IDREG_FIELD_START(ID_MMFR4_EL1, EVT, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR4_EL1, EVT)
>> + IDREG_FIELD_START(ID_MMFR4_EL1, CCIDX, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR4_EL1, CCIDX)
>> + IDREG_FIELD_START(ID_MMFR4_EL1, LSM, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR4_EL1, LSM)
>> + IDREG_FIELD_START(ID_MMFR4_EL1, HPDS, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_MMFR4_EL1, HPDS)
>> + IDREG_FIELD_START(ID_MMFR4_EL1, CnP, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR4_EL1, CnP)
>> + IDREG_FIELD_START(ID_MMFR4_EL1, XNX, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR4_EL1, XNX)
>> + IDREG_FIELD_START(ID_MMFR4_EL1, AC2, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR4_EL1, AC2)
>> + IDREG_FIELD_START(ID_MMFR4_EL1, SpecSEI, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR4_EL1, SpecSEI)
>> IDREG_END(ID_MMFR4_EL1)
>>
>> IDREG_START(ID_MMFR5_EL1)
>> - IDREG_FIELD(ID_MMFR5_EL1, nTLBPA, 4, 4)
>> - IDREG_FIELD(ID_MMFR5_EL1, ETS, 0, 4)
>> + IDREG_FIELD_START(ID_MMFR5_EL1, nTLBPA, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_MMFR5_EL1, nTLBPA)
>> + IDREG_FIELD_START(ID_MMFR5_EL1, ETS, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_MMFR5_EL1, ETS)
>> IDREG_END(ID_MMFR5_EL1)
>>
>> IDREG_START(ID_PFR0_EL1)
>> - IDREG_FIELD(ID_PFR0_EL1, RAS, 28, 4)
>> - IDREG_FIELD(ID_PFR0_EL1, DIT, 24, 4)
>> - IDREG_FIELD(ID_PFR0_EL1, AMU, 20, 4)
>> - IDREG_FIELD(ID_PFR0_EL1, CSV2, 16, 4)
>> - IDREG_FIELD(ID_PFR0_EL1, State3, 12, 4)
>> - IDREG_FIELD(ID_PFR0_EL1, State2, 8, 4)
>> - IDREG_FIELD(ID_PFR0_EL1, State1, 4, 4)
>> - IDREG_FIELD(ID_PFR0_EL1, State0, 0, 4)
>> + IDREG_FIELD_START(ID_PFR0_EL1, RAS, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_PFR0_EL1, RAS)
>> + IDREG_FIELD_START(ID_PFR0_EL1, DIT, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_PFR0_EL1, DIT)
>> + IDREG_FIELD_START(ID_PFR0_EL1, AMU, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_PFR0_EL1, AMU)
>> + IDREG_FIELD_START(ID_PFR0_EL1, CSV2, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_PFR0_EL1, CSV2)
>> + IDREG_FIELD_START(ID_PFR0_EL1, State3, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_PFR0_EL1, State3)
>> + IDREG_FIELD_START(ID_PFR0_EL1, State2, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_PFR0_EL1, State2)
>> + IDREG_FIELD_START(ID_PFR0_EL1, State1, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_PFR0_EL1, State1)
>> + IDREG_FIELD_START(ID_PFR0_EL1, State0, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_PFR0_EL1, State0)
>> IDREG_END(ID_PFR0_EL1)
>>
>> IDREG_START(ID_PFR1_EL1)
>> - IDREG_FIELD(ID_PFR1_EL1, GIC, 28, 4)
>> - IDREG_FIELD(ID_PFR1_EL1, Virt_frac, 24, 4)
>> - IDREG_FIELD(ID_PFR1_EL1, Sec_frac, 20, 4)
>> - IDREG_FIELD(ID_PFR1_EL1, GenTimer, 16, 4)
>> - IDREG_FIELD(ID_PFR1_EL1, Virtualization, 12, 4)
>> - IDREG_FIELD(ID_PFR1_EL1, MProgMod, 8, 4)
>> - IDREG_FIELD(ID_PFR1_EL1, Security, 4, 4)
>> - IDREG_FIELD(ID_PFR1_EL1, ProgMod, 0, 4)
>> + IDREG_FIELD_START(ID_PFR1_EL1, GIC, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(ID_PFR1_EL1, GIC)
>> + IDREG_FIELD_START(ID_PFR1_EL1, Virt_frac, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_PFR1_EL1, Virt_frac)
>> + IDREG_FIELD_START(ID_PFR1_EL1, Sec_frac, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_PFR1_EL1, Sec_frac)
>> + IDREG_FIELD_START(ID_PFR1_EL1, GenTimer, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_PFR1_EL1, GenTimer)
>> + IDREG_FIELD_START(ID_PFR1_EL1, Virtualization, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_PFR1_EL1, Virtualization)
>> + IDREG_FIELD_START(ID_PFR1_EL1, MProgMod, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_PFR1_EL1, MProgMod)
>> + IDREG_FIELD_START(ID_PFR1_EL1, Security, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(ID_PFR1_EL1, Security)
>> + IDREG_FIELD_START(ID_PFR1_EL1, ProgMod, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_PFR1_EL1, ProgMod)
>> IDREG_END(ID_PFR1_EL1)
>>
>> IDREG_START(ID_PFR2_EL1)
>> - IDREG_FIELD(ID_PFR2_EL1, RAS_frac, 8, 4)
>> - IDREG_FIELD(ID_PFR2_EL1, SSBS, 4, 4)
>> - IDREG_FIELD(ID_PFR2_EL1, CSV3, 0, 4)
>> + IDREG_FIELD_START(ID_PFR2_EL1, RAS_frac, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_PFR2_EL1, RAS_frac)
>> + IDREG_FIELD_START(ID_PFR2_EL1, SSBS, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_PFR2_EL1, SSBS)
>> + IDREG_FIELD_START(ID_PFR2_EL1, CSV3, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(ID_PFR2_EL1, CSV3)
>> IDREG_END(ID_PFR2_EL1)
>>
>> IDREG_START(MIDR_EL1)
>> - IDREG_FIELD(MIDR_EL1, Implementer, 24, 8)
>> + IDREG_FIELD_START(MIDR_EL1, Implementer, 24, 8)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(65)
>> + IDREG_FIELD_ARCH_VAL(66)
>> + IDREG_FIELD_ARCH_VAL(67)
>> + IDREG_FIELD_ARCH_VAL(68)
>> + IDREG_FIELD_ARCH_VAL(70)
>> + IDREG_FIELD_ARCH_VAL(73)
>> + IDREG_FIELD_ARCH_VAL(77)
>> + IDREG_FIELD_ARCH_VAL(78)
>> + IDREG_FIELD_ARCH_VAL(80)
>> + IDREG_FIELD_ARCH_VAL(81)
>> + IDREG_FIELD_ARCH_VAL(86)
>> + IDREG_FIELD_ARCH_VAL(105)
>> + IDREG_FIELD_ARCH_VAL(192)
>> + IDREG_FIELD_END(MIDR_EL1, Implementer)
>> IDREG_FIELD(MIDR_EL1, Variant, 20, 4)
>> - IDREG_FIELD(MIDR_EL1, Architecture, 16, 4)
>> + IDREG_FIELD_START(MIDR_EL1, Architecture, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(MIDR_EL1, Architecture)
>> IDREG_FIELD(MIDR_EL1, PartNum, 4, 12)
>> IDREG_FIELD(MIDR_EL1, Revision, 0, 4)
>> IDREG_END(MIDR_EL1)
>>
>> IDREG_START(MPIDR_EL1)
>> IDREG_FIELD(MPIDR_EL1, Aff3, 32, 8)
>> - IDREG_FIELD(MPIDR_EL1, U, 30, 1)
>> - IDREG_FIELD(MPIDR_EL1, MT, 24, 1)
>> + IDREG_FIELD_START(MPIDR_EL1, U, 30, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MPIDR_EL1, U)
>> + IDREG_FIELD_START(MPIDR_EL1, MT, 24, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MPIDR_EL1, MT)
>> IDREG_FIELD(MPIDR_EL1, Aff2, 16, 8)
>> IDREG_FIELD(MPIDR_EL1, Aff1, 8, 8)
>> IDREG_FIELD(MPIDR_EL1, Aff0, 0, 8)
>> IDREG_END(MPIDR_EL1)
>>
>> IDREG_START(MVFR0_EL1)
>> - IDREG_FIELD(MVFR0_EL1, FPRound, 28, 4)
>> - IDREG_FIELD(MVFR0_EL1, FPShVec, 24, 4)
>> - IDREG_FIELD(MVFR0_EL1, FPSqrt, 20, 4)
>> - IDREG_FIELD(MVFR0_EL1, FPDivide, 16, 4)
>> - IDREG_FIELD(MVFR0_EL1, FPTrap, 12, 4)
>> - IDREG_FIELD(MVFR0_EL1, FPDP, 8, 4)
>> - IDREG_FIELD(MVFR0_EL1, FPSP, 4, 4)
>> - IDREG_FIELD(MVFR0_EL1, SIMDReg, 0, 4)
>> + IDREG_FIELD_START(MVFR0_EL1, FPRound, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR0_EL1, FPRound)
>> + IDREG_FIELD_START(MVFR0_EL1, FPShVec, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR0_EL1, FPShVec)
>> + IDREG_FIELD_START(MVFR0_EL1, FPSqrt, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR0_EL1, FPSqrt)
>> + IDREG_FIELD_START(MVFR0_EL1, FPDivide, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR0_EL1, FPDivide)
>> + IDREG_FIELD_START(MVFR0_EL1, FPTrap, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR0_EL1, FPTrap)
>> + IDREG_FIELD_START(MVFR0_EL1, FPDP, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(MVFR0_EL1, FPDP)
>> + IDREG_FIELD_START(MVFR0_EL1, FPSP, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(MVFR0_EL1, FPSP)
>> + IDREG_FIELD_START(MVFR0_EL1, SIMDReg, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(MVFR0_EL1, SIMDReg)
>> IDREG_END(MVFR0_EL1)
>>
>> IDREG_START(MVFR1_EL1)
>> - IDREG_FIELD(MVFR1_EL1, SIMDFMAC, 28, 4)
>> - IDREG_FIELD(MVFR1_EL1, FPHP, 24, 4)
>> - IDREG_FIELD(MVFR1_EL1, SIMDHP, 20, 4)
>> - IDREG_FIELD(MVFR1_EL1, SIMDSP, 16, 4)
>> - IDREG_FIELD(MVFR1_EL1, SIMDInt, 12, 4)
>> - IDREG_FIELD(MVFR1_EL1, SIMDLS, 8, 4)
>> - IDREG_FIELD(MVFR1_EL1, FPDNaN, 4, 4)
>> - IDREG_FIELD(MVFR1_EL1, FPFtZ, 0, 4)
>> + IDREG_FIELD_START(MVFR1_EL1, SIMDFMAC, 28, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR1_EL1, SIMDFMAC)
>> + IDREG_FIELD_START(MVFR1_EL1, FPHP, 24, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(MVFR1_EL1, FPHP)
>> + IDREG_FIELD_START(MVFR1_EL1, SIMDHP, 20, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_END(MVFR1_EL1, SIMDHP)
>> + IDREG_FIELD_START(MVFR1_EL1, SIMDSP, 16, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR1_EL1, SIMDSP)
>> + IDREG_FIELD_START(MVFR1_EL1, SIMDInt, 12, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR1_EL1, SIMDInt)
>> + IDREG_FIELD_START(MVFR1_EL1, SIMDLS, 8, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR1_EL1, SIMDLS)
>> + IDREG_FIELD_START(MVFR1_EL1, FPDNaN, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR1_EL1, FPDNaN)
>> + IDREG_FIELD_START(MVFR1_EL1, FPFtZ, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(MVFR1_EL1, FPFtZ)
>> IDREG_END(MVFR1_EL1)
>>
>> IDREG_START(MVFR2_EL1)
>> - IDREG_FIELD(MVFR2_EL1, FPMisc, 4, 4)
>> - IDREG_FIELD(MVFR2_EL1, SIMDMisc, 0, 4)
>> + IDREG_FIELD_START(MVFR2_EL1, FPMisc, 4, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_END(MVFR2_EL1, FPMisc)
>> + IDREG_FIELD_START(MVFR2_EL1, SIMDMisc, 0, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(MVFR2_EL1, SIMDMisc)
>> IDREG_END(MVFR2_EL1)
>>
>> IDREG_START(REVIDR_EL1)
>> IDREG_END(REVIDR_EL1)
>>
>> IDREG_START(SMIDR_EL1)
>> - IDREG_FIELD(SMIDR_EL1, NSMC, 56, 4)
>> - IDREG_FIELD(SMIDR_EL1, HIP, 52, 4)
>> + IDREG_FIELD_START(SMIDR_EL1, NSMC, 56, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(SMIDR_EL1, NSMC)
>> + IDREG_FIELD_START(SMIDR_EL1, HIP, 52, 4)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_ARCH_VAL(4)
>> + IDREG_FIELD_ARCH_VAL(5)
>> + IDREG_FIELD_ARCH_VAL(6)
>> + IDREG_FIELD_ARCH_VAL(7)
>> + IDREG_FIELD_ARCH_VAL(8)
>> + IDREG_FIELD_ARCH_VAL(9)
>> + IDREG_FIELD_ARCH_VAL(10)
>> + IDREG_FIELD_ARCH_VAL(11)
>> + IDREG_FIELD_ARCH_VAL(12)
>> + IDREG_FIELD_ARCH_VAL(13)
>> + IDREG_FIELD_ARCH_VAL(14)
>> + IDREG_FIELD_ARCH_VAL(15)
>> + IDREG_FIELD_END(SMIDR_EL1, HIP)
>> IDREG_FIELD(SMIDR_EL1, Affinity2, 32, 20)
>> - IDREG_FIELD(SMIDR_EL1, Implementer, 24, 8)
>> + IDREG_FIELD_START(SMIDR_EL1, Implementer, 24, 8)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(65)
>> + IDREG_FIELD_ARCH_VAL(66)
>> + IDREG_FIELD_ARCH_VAL(67)
>> + IDREG_FIELD_ARCH_VAL(68)
>> + IDREG_FIELD_ARCH_VAL(70)
>> + IDREG_FIELD_ARCH_VAL(73)
>> + IDREG_FIELD_ARCH_VAL(77)
>> + IDREG_FIELD_ARCH_VAL(78)
>> + IDREG_FIELD_ARCH_VAL(80)
>> + IDREG_FIELD_ARCH_VAL(81)
>> + IDREG_FIELD_ARCH_VAL(86)
>> + IDREG_FIELD_ARCH_VAL(105)
>> + IDREG_FIELD_ARCH_VAL(192)
>> + IDREG_FIELD_END(SMIDR_EL1, Implementer)
>> IDREG_FIELD(SMIDR_EL1, Revision, 16, 8)
>> - IDREG_FIELD(SMIDR_EL1, SMPS, 15, 1)
>> - IDREG_FIELD(SMIDR_EL1, SH, 13, 2)
>> + IDREG_FIELD_START(SMIDR_EL1, SMPS, 15, 1)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_END(SMIDR_EL1, SMPS)
>> + IDREG_FIELD_START(SMIDR_EL1, SH, 13, 2)
>> + IDREG_FIELD_ARCH_VAL(0)
>> + IDREG_FIELD_ARCH_VAL(1)
>> + IDREG_FIELD_ARCH_VAL(2)
>> + IDREG_FIELD_ARCH_VAL(3)
>> + IDREG_FIELD_END(SMIDR_EL1, SH)
>> IDREG_FIELD(SMIDR_EL1, Affinity, 0, 12)
>> IDREG_END(SMIDR_EL1)
>>
>> diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py
>> index 6f5edb88d2..96f8aa2d64 100644
>> --- a/scripts/update-aarch64-cpu-sysreg-properties.py
>> +++ b/scripts/update-aarch64-cpu-sysreg-properties.py
>> @@ -9,7 +9,12 @@
>> #
>> # IDREG_START(REG)
>> # IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
>> -# ...
>> +# or for fields with enum values
>> +# IDREG_FIELD_START(REG, FIELD, SHIFT, LENGTH)
>> +# IDREG_FIELD_ARCH_VAL(VALUE)
>> +# ../..
>> +# IDREG_FIELD_END(REG, FIELD)
>> +# ../..
>> # IDREG_END(REG)
>> #
>> # Copyright (C) 2026 Red Hat, Inc.
>> @@ -97,6 +102,59 @@ def collect_fields(item, bit_offset=0):
>>
>> return fields
>>
>> +def parse_raw_val(val_obj):
>> + """Helper to unwrap int values from strings, ints, or nested dicts."""
>> + if isinstance(val_obj, dict):
>> + val_obj = val_obj.get("value")
>> +
>> + if val_obj is None:
>> + return None
>> +
>> + raw_val_str = str(val_obj).strip().replace("'", "")
>> + try:
>> + return int(raw_val_str, 2)
>> + except ValueError:
>> + try:
>> + return int(raw_val_str, 0)
>> + except ValueError:
>> + return None
>> +
>> +def extract_field_enums(field):
>> + enums = []
>> + if not isinstance(field, dict):
>> + return enums
>> +
>> + value_obj = field.get("value")
>> + if not isinstance(value_obj, dict):
>> + return enums
>> +
>> + constraints = value_obj.get("constraints")
>> + if not isinstance(constraints, dict):
>> + return enums
>> +
>> + val_entries = constraints.get("values", [])
>> + if not isinstance(val_entries, list):
>> + return enums
>> +
>> + for val_entry in val_entries:
>> + if not isinstance(val_entry, dict):
>> + continue
>> +
>> + entry_type = val_entry.get("_type")
>> + if entry_type == "Values.Value":
>> + int_val = parse_raw_val(val_entry.get("value"))
>> + if int_val is not None:
>> + enums.append({'value': int_val})
>> +
>> + elif entry_type == "Values.ValueRange":
>> + s = parse_raw_val(val_entry.get("start"))
>> + e = parse_raw_val(val_entry.get("end"))
>> +
>> + if s is not None and e is not None:
>> + for v in range(s, e + 1):
>> + enums.append({'value': v})
> Hi Eric,
>
> I think here ConditionalValue type is missing, TGran*, PARange and VARange are missing some values.
That's totally right! wil be fixed in v10
Eric
>
> Warm Regards,
> Khushit
>> +
>> + return enums
>>
>> def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
>> with open(raw_json_path, 'r') as f:
>> @@ -128,16 +186,32 @@ def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
>> # Only keep the fields with the highest MSB
>> # needed fir CCSIDR_EL1
>> if name not in unique_fields or msb > unique_fields[name]['msb']:
>> - unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width}
>> + # extract enum values if any
>> + enums = extract_field_enums(val)
>> + unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width, 'enums': enums}
>>
>> # Sort decreasing lsbs
>> sorted_fields = sorted(unique_fields.items(),
>> key=lambda x: x[1]['lsb'], reverse=True)
>>
>> for name, bits in sorted_fields:
>> - line = (f" IDREG_FIELD({reg_name}, "
>> - f"{name}, {bits['lsb']}, {bits['width']})\n")
>> + enums_list = bits.get('enums', [])
>> +
>> + if enums_list:
>> + line = (f" IDREG_FIELD_START({reg_name}, "
>> + f"{name}, {bits['lsb']}, {bits['width']})\n")
>> + else:
>> + line = (f" IDREG_FIELD({reg_name}, "
>> + f"{name}, {bits['lsb']}, {bits['width']})\n")
>> final_output += line
>> + # generate enum value or range if any
>> + for enum_item in enums_list:
>> + final_output += (f" IDREG_FIELD_ARCH_VAL({enum_item['value']})\n")
>> +
>> + if enums_list:
>> + line = (f" IDREG_FIELD_END({reg_name}, {name})\n")
>> + final_output += line
>> +
>> final_output += f"IDREG_END({reg_name})\n"
>> final_output += "\n"
>>
>> @@ -147,7 +221,11 @@ def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
>> f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
>> f.write("/* IDREG_START(REG) */\n")
>> f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n")
>> + f.write("/* or for fields with enum values */\n")
>> + f.write("/* IDREG_FIELD_START(REG, FIELD, SHIFT, LENGTH) */\n")
>> + f.write("/* IDREG_FIELD_ARCH_VAL(VALUE) */\n")
>> f.write("/* ... */\n")
>> + f.write("/* IDREG_FIELD_END(REG, FIELD) */\n")
>> f.write("/* IDREG_END(REG) */\n\n")
>> f.write(final_output)
>>
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 06/26] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py
2026-10-02 12:59 ` Eric Auger
@ 2026-10-05 5:37 ` Khushit Shah
0 siblings, 0 replies; 82+ messages in thread
From: Khushit Shah @ 2026-10-05 5:37 UTC (permalink / raw)
To: eric.auger@redhat.com
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 2 Oct 2026, at 6:29 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Hi Khushit,
>
> On 9/25/26 11:29 AM, Khushit Shah wrote:
>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>
>>> !-------------------------------------------------------------------|
>>> CAUTION: External Email
>>>
>>> |-------------------------------------------------------------------!
>>>
>>> Introduce a script that takes as input the Registers.json file
>>> delivered in the AARCHMRS Features Model downloadable from the
>>> Arm Developer A-Profile Architecture Exploration Tools page:
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=2NOLVUk59YPHssYi5AgGX0z_LkZPQXfTkiD33Ti_D8RYfowBwp7XuMOfw-dMDkDE&s=Qs3ro5t6_dDfdQDLUGX7pJ43SvM2axfOShUzqbv90EQ&e=
>>> and automates the generation of system register properties definitions.
>>>
>>> generates target/arm/cpu-idregs.h.inc containing definitions for
>>> feature ID registers.
>>>
>>> We only care about IDregs with opcodes satisfying:
>>> op0 = 3, op1 = {0,1,3}, crn = 0, crm within [0, 7], op2 within [0, 7]
>>>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>
>>> ---
>>>
>>> v5 -> v6
>>> - add ident
>>> ---
>>> .../update-aarch64-cpu-sysreg-properties.py | 166 ++++++++++++++++++
>>> 1 file changed, 166 insertions(+)
>>> create mode 100644 scripts/update-aarch64-cpu-sysreg-properties.py
>>>
>>> diff --git a/scripts/update-aarch64-cpu-sysreg-properties.py b/scripts/update-aarch64-cpu-sysreg-properties.py
>>> new file mode 100644
>>> index 0000000000..6f5edb88d2
>>> --- /dev/null
>>> +++ b/scripts/update-aarch64-cpu-sysreg-properties.py
>>> @@ -0,0 +1,166 @@
>>> +#!/usr/bin/env python3
>>> +
>>> +# This script takes as input the Registers.json file delivered in
>>> +# the AARCHMRS Features Model downloadable from the Arm Developer
>>> +# A-Profile Architecture Exploration Tools page:
>>> +# https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.arm.com_Architectures_A-2DProfile-2520Architecture-23Downloads&d=DwIDAg&c=s883GpUCOChKOHiocYtGcg&r=PGWMyignA0NiDmTlyP7vOTHozBws_VN86yrVmSMkBp0&m=2NOLVUk59YPHssYi5AgGX0z_LkZPQXfTkiD33Ti_D8RYfowBwp7XuMOfw-dMDkDE&s=Qs3ro5t6_dDfdQDLUGX7pJ43SvM2axfOShUzqbv90EQ&e=
>>> +# and outputs target/arm/cpu-idregs.h.inc content.
>>> +# ID regs are defined using this pattern:
>>> +#
>>> +# IDREG_START(REG)
>>> +# IDREG_FIELD(REG, FIELD, SHIFT, LENGTH)
>> Nit: Add Enum Macro
> This is done later in "target/arm/cpu-idregs.h.inc: Generate enum values"
>>> +# ...
>>> +# IDREG_END(REG)
>>> +#
>>> +# Copyright (C) 2026 Red Hat, Inc.
>>> +#
>>> +# Authors: Eric Auger <eric.auger@redhat.com>
>>> +#
>>> +# SPDX-License-Identifier: GPL-2.0-or-later
>>> +
>>> +
>>> +import json
>>> +import os
>>> +import sys
>>> +from aarch64_sysreg_helpers import extract_idregs_from_registers_json
>>> +
>>> +def collect_fields(item, bit_offset=0):
>>> + """
>>> + Recursively finds all field-like objects, handling Fields.Array,
>>> + Fields.ArrayField, and ConditionalField structures.
>>> + Applies bit_offset from containers to child fields.
>>> + """
>>> + fields = []
>>> + if not isinstance(item, dict):
>>> + return fields
>>> +
>>> + _type = item.get('_type', '')
>>> +
>>> + # Array types (for example CLIDR_EL1 Ctype<n>, Ttype<n>)
>>> + if _type == 'Fields.Array':
>>> + name_template = item.get('name') or item.get('label', '')
>>> + index_info = item.get('indexes', [{}])[0]
>>> + start_idx = index_info.get('start', 0)
>>> + count = index_info.get('width', 0)
>>> +
>>> + full_range = item.get('rangeset', [{}])[0]
>>> + bit_start = full_range.get('start', 0) + bit_offset
>>> + elem_width = full_range.get('width', 0) // count if count else 0
>>> +
>>> + for i in range(count):
>>> + idx = start_idx + i
>>> + # Correctly handle indexed names like Ctype1, Ctype2
>>> + field_name = name_template.replace('<n>', str(idx))
>>> + fields.append({
>>> + 'name': field_name,
>>> + 'rangeset': [{
>>> + 'start': bit_start + (i * elem_width),
>>> + 'width': elem_width
>>> + }],
>>> + '_type': 'Fields.Field'
>>> + })
>>> + return fields
>>> +
>>> + # ConditionalFields
>> Can you please explain what are conditional fields and should we always include them?
> If we don't you will miss plenty of named fields which depend on a
> specific FEAT implementation.
> Few examples:
> < IDREG_FIELD_START(ID_AA64MMFR4_EL1, E2H0, 24, 4)
> < IDREG_FIELD_START(ID_AA64SMFR0_EL1, SMEver, 56, 4)
> < IDREG_FIELD_START(ID_AA64ZFR0_EL1, SVEver, 0, 4)
> ../..
>
> All of those are defined in linux sysreg too
Ohh okay, makes sense.
>>
>>> + elif _type == 'Fields.ConditionalField':
>>> + inner_offset = bit_offset
>>> + if item.get('rangeset'):
>>> + # Parent container defines the absolute start bit
>>> + inner_offset = item['rangeset'][0].get('start', bit_offset)
>>> +
>>> + for entry in item.get('fields', []):
>>> + inner = entry.get('field')
>>> + if inner:
>>> + fields.extend(collect_fields(inner, inner_offset))
>>> + return fields
>>> +
>>> + # Normal Field Types
>>> + leaf_types = ['Fields.Field', 'Fields.ConstantField',
>>> + 'Fields.EnumeratedField', 'Fields.Bitfield']
>>> + if _type in leaf_types:
>>> + field_copy = item.copy()
>>> + if field_copy.get('rangeset'):
>>> + new_ranges = []
>>> + for r in field_copy['rangeset']:
>>> + nr = r.copy()
>>> + # Apply the cumulative offset to the field's start bit
>>> + nr['start'] = r.get('start', 0) + bit_offset
>>> + new_ranges.append(nr)
>>> + field_copy['rangeset'] = new_ranges
>>> + fields.append(field_copy)
>>> + return fields
>>> +
>>> + # Traverse the hierarchy for other cases
>>> + for key in ['fields', 'values', 'fieldsets']:
>>> + for nested in item.get(key, []):
>>> + fields.extend(collect_fields(nested, bit_offset))
>>> +
>>> + return fields
>>> +
>>> +
>>> +def generate_sysreg_properties_from_registers_json(id_reg_names, raw_json_path):
>>> + with open(raw_json_path, 'r') as f:
>>> + register_data = json.load(f)
>>> +
>>> + regs = {r.get('name'): r for r in register_data if r.get('_type') == 'Register'}
>>> +
>>> + final_output = ""
>>> +
>>> + for reg_name in id_reg_names:
>>> + register = regs.get(reg_name)
>>> + if not register:
>> we should error out here.
> agreed
>>> + continue
>>> +
>>> + final_output += f"IDREG_START({reg_name})\n"
>>> +
>>> + unique_fields = {}
>>> + for fieldset in register.get('fieldsets', []):
>>> + candidates = collect_fields(fieldset)
>>> + for val in candidates:
>>> + name = (val.get('name') or val.get('label', '')).strip()
>>> + if not name or "RESERVED" in name.upper():
>>> + continue
>>> + for r in val.get('rangeset', []):
>>> + lsb = int(r.get('start'))
>>> + width = r.get('width')
>>> + msb = lsb + int(width) - 1
>>> +
>>> + # Only keep the fields with the highest MSB
>>> + # needed fir CCSIDR_EL1
>> does not apply now, we ignore CCSIDR_EL1
> yeah but I feel it still makes sense to record the highest msb in case
> different fieldsets exist for the same name (32b versus 64b for instance)
Noted
Thanks!
Khushit
>>> + if name not in unique_fields or msb > unique_fields[name]['msb']:
>>> + unique_fields[name] = {'lsb': lsb, 'msb': msb, 'width': width}
>>> +
>>> + # Sort decreasing lsbs
>>> + sorted_fields = sorted(unique_fields.items(),
>>> + key=lambda x: x[1]['lsb'], reverse=True)
>>> +
>>> + for name, bits in sorted_fields:
>>> + line = (f" IDREG_FIELD({reg_name}, "
>>> + f"{name}, {bits['lsb']}, {bits['width']})\n")
>>> + final_output += line
>>> + final_output += f"IDREG_END({reg_name})\n"
>>> + final_output += "\n"
>>> +
>>> + os.makedirs("target/arm", exist_ok=True)
>>> + with open("target/arm/cpu-idregs.h.inc", 'w') as f:
>>> + f.write("/* AUTOMATICALLY GENERATED, DO NOT MODIFY */\n\n")
>>> + f.write("/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n")
>>> + f.write("/* IDREG_START(REG) */\n")
>>> + f.write("/* IDREG_FIELD(REG, FIELD, SHIFT, LENGTH) */\n”)
>> Same enum macro …
> see above
>
> Thanks!
>
> Eric
>>
>> Warm Regards,
>> Khushit
>>> + f.write("/* ... */\n")
>>> + f.write("/* IDREG_END(REG) */\n\n")
>>> + f.write(final_output)
>>> +
>>> +if __name__ == "__main__":
>>> + if len(sys.argv) < 2:
>>> + print("Usage: python scripts/update-aarch64-cpu-sysreg-properties.py "
>>> + "<path_to_registers_json>")
>>> + else:
>>> + json_path = sys.argv[1]
>>> +
>>> + id_regs_dict = extract_idregs_from_registers_json(json_path)
>>> + sorted_names = sorted(id_regs_dict.keys())
>>> +
>>> + if sorted_names:
>>> + generate_sysreg_properties_from_registers_json(sorted_names, json_path)
>>> + print("Generated target/arm/cpu-idregs.h.inc")
>>> --
>>> 2.53.0
>>>
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 25/26] arm-qmp-cmds: introspection for ID register props
2026-09-28 14:39 ` Khushit Shah
@ 2026-10-07 14:27 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-10-07 14:27 UTC (permalink / raw)
To: qemu-devel
Hi Khushit,
On 9/28/26 4:39 PM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> From: Cornelia Huck <cohuck@redhat.com>
>>
>> Enhance the current host model query-cpu-model-expansion with the
>> capability to return SYSREG_* options and also test possible
>> values.
>>
>> If no SYSREG prop is set, query-cpu-model-expansion returns the
>> default host values for all SYSREG properties. They are extracted
>> from a scratch vcpu featuring all the KVM advertised capabilities.
>>
>> Here is a qmp-shell example:
>>
>> (QEMU) query-cpu-model-expansion type=full model={"name":"host"}
>> {"return": {"model": {"name": "host", "props": {"SYSREG_ID_AA64PFR0_EL1_EL3": 1,
>> "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0, "SYSREG_CTR_EL0_L1Ip": 3,
>> "SYSREG_MIDR_EL1_PartNum": 3407, "SYSREG_CTR_EL0_DminLine": 4,
>> "SYSREG_ID_AA64MMFR0_EL1_PARange": 5, "SYSREG_ID_AA64MMFR1_EL1_ECBHB": 0
>> ../..
>>
>> It becomes also possible to test new SYSREG property values.
>>
>> With Full expansion of the host model, the SYSREG props are tested
>> against a scratch vcpu. With static expansion, no check is performed
>> against KVM but only against qemu code (the value does not exceed the
>> field size and if the field is associated to enum values, the set
>> value belongs to the list of arch enum values.
>>
>> Examples
>> (QEMU) query-cpu-model-expansion type=full model={"name":"host","props":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x13}}
>> {"error": {"class": "GenericError", "desc": "idreg SYSREG_ID_AA64ISAR0_EL1_DP set value (0x13) exceeds length of field (4)!"}}
>>
>> (QEMU) query-cpu-model-expansion type=full model={"name":"host","props":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x2}}
>> {"error": {"class": "GenericError", "desc": "idreg SYSREG_ID_AA64ISAR0_EL1_DP set value (0x2) does not match any arch valid enum value!"}}
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
>>
>> ---
>>
>> v8 -> v9:
>> - fix the leak reported by Khushit
>> - implement static mode for host
>>
>> v7 -> v8:
>> - do not check if the prop exists (this is checked elsewhere with a
>> different error message)
>> - clarify that examples given in the commit msg are based on qmp-shell
>>
>> v5 -> v6:
>> - add the write capability
>> ---
>> target/arm/arm-qmp-cmds.c | 107 ++++++++++++++++++++++++++++++++++++--
>> 1 file changed, 104 insertions(+), 3 deletions(-)
>>
>> diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
>> index 83ec95c290..b52ca67f83 100644
>> --- a/target/arm/arm-qmp-cmds.c
>> +++ b/target/arm/arm-qmp-cmds.c
>> @@ -21,6 +21,7 @@
>> */
>>
>> #include "qemu/osdep.h"
>> +#include "qemu/error-report.h"
>> #include "qemu/target-info.h"
>> #include "hw/core/boards.h"
>> #include "kvm_arm.h"
>> @@ -30,6 +31,7 @@
>> #include "qapi/qapi-commands-machine.h"
>> #include "qapi/qapi-commands-misc-arm.h"
>> #include "qobject/qdict.h"
>> +#include "qobject/qnum.h"
>> #include "qom/qom-qobject.h"
>> #include "cpu.h"
>>
>> @@ -83,15 +85,20 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>> CpuModelInfo *model,
>> Error **errp)
>> {
>> + bool use_scratch_vcpu = kvm_enabled() && type == CPU_MODEL_EXPANSION_TYPE_FULL;
>> CpuModelExpansionInfo *expansion_info;
>> + ObjectPropertyIterator iter;
>> const QDict *qdict_in;
>> + ObjectProperty *idregprop;
>> QDict *qdict_out;
>> ObjectClass *oc;
>> Object *obj;
>> const char *name;
>> + int fdarray[3];
>> int i;
>>
>> - if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
>> + /* we support static expansion for host model only */
>> + if (type != CPU_MODEL_EXPANSION_TYPE_FULL && strcmp(model->name, "host")) {
>> error_setg(errp, "The requested expansion type is not supported");
>> return NULL;
>> }
>> @@ -136,6 +143,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>> if (model->props) {
>> Visitor *visitor;
>> Error *err = NULL;
>> + int fd = -1;
>>
>> visitor = qobject_input_visitor_new(model->props);
>> if (!visit_start_struct(visitor, "model.props", NULL, 0, errp)) {
>> @@ -146,6 +154,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>>
>> qdict_in = qobject_to(QDict, model->props);
>> i = 0;
>> +
>> + /* Test legacy composite option settings */
>> while ((name = cpu_model_advertised_features[i++]) != NULL) {
>> if (qdict_get(qdict_in, name)) {
>> if (!object_property_set(obj, name, visitor, &err)) {
>> @@ -154,11 +164,85 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>> }
>> }
>>
>> + if (!err) {
>> + arm_cpu_finalize_features(ARM_CPU(obj), &err);
>> + }
>> +
>> + /**
>> + * Test SYSREG option settings
>> + * In full mode, build a scratch vcpu that reflects composite legacy
>> + * options
>> + */
>> + if (use_scratch_vcpu) {
>> + Error *local_err = NULL;
>> + bool has_virt = object_property_get_bool(OBJECT(current_machine),
>> + "virtualization",
>> + &local_err);
>> +
>> + if (local_err) {
> Hi Eric,
>
> Nit: indentation
sure
>> + error_free(local_err); /* the machine property does not exist */
>> + } else {
>> + if (!has_virt && object_property_find(obj, "has_el2")) {
>> + object_property_set_bool(obj, "has_el2", false, NULL);
>> + }
>> + }
>> + fd = kvm_arm_create_init_scratch_vcpu(ARM_CPU(obj), errp);
>> + if (fd < 0) {
>> + return NULL;
> Leaks obj/visitor.
Right, I fully revisited the error path
>> + }
>> + }
>> +
>> + qdict_in = qobject_to(QDict, model->props);
>> + for (const QDictEntry *entry = qdict_first(qdict_in);
>> + entry != NULL; entry = qdict_next(qdict_in, entry)) {
>> + const char *key = qdict_entry_key(entry);
>> + QObject *val_obj = qdict_entry_value(entry);
>> + ObjectProperty *prop;
>> + Visitor *v;
>> + bool success;
>> + uint64_t val;
>> +
>> + prop = object_property_find(obj, key);
>> +
>> + if (!g_str_has_prefix(key, "SYSREG_")) {
>> + continue;
>> + }
>> +
>> + /* consume the prop to avoid unexpected parameter */
>> + if (!visit_type_uint64(visitor, key, &val, errp)) {
>> + goto bail_out;
>> + }
>> +
>> + v = qobject_input_visitor_new(val_obj);
>> +
>> + if (!object_property_set(obj, key, v, errp)) {
>> + goto bail_out;
>> + }
>> +
>> + if (use_scratch_vcpu) {
>> + ARM64SysRegField *field = (ARM64SysRegField *)prop->opaque;
>> + uint64_t newfv;
>> +
>> + if (!visit_type_uint64(v, name, &newfv, errp)) {
> The name is not initialised in this scope… It carries value of last processed legacy prop
damned. now fixed with reusing previously retrieved val
>> + visit_free(v);
>> + goto bail_out;
>> + }
>> + success = kvm_idreg_write_scratch_vcpu(ARM_CPU(obj), fd,
>> + field, newfv, errp);
>> + if (!success) {
>> + visit_free(v);
>> + goto bail_out;
>> + }
>> + }
>> + visit_free(v);
>> + }
>> +
>> if (!err) {
>> visit_check_struct(visitor, &err);
>> }
>> - if (!err) {
>> - arm_cpu_finalize_features(ARM_CPU(obj), &err);
>> +
>> + if (use_scratch_vcpu) {
>> + kvm_arm_destroy_scratch_host_vcpu(fdarray);
>> }
>> visit_end_struct(visitor, NULL);
>> visit_free(visitor);
>> @@ -190,6 +274,18 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>> }
>> }
>>
>> + object_property_iter_init(&iter, obj);
>> +
>> + while ((idregprop = object_property_iter_next(&iter))) {
>> + QObject *value;
>> +
>> + if (!g_str_has_prefix(idregprop->name, "SYSREG_")) {
>> + continue;
>> + }
>> + value = object_property_get_qobject(obj, idregprop->name, &error_abort);
>> + qdict_put_obj(qdict_out, idregprop->name, value);
>> + }
>> +
>> if (!qdict_size(qdict_out)) {
>> qobject_unref(qdict_out);
>> } else {
>> @@ -199,6 +295,11 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>> object_unref(obj);
>>
>> return expansion_info;
>> +bail_out:
> Leaks obj.
>> + if (use_scratch_vcpu) {
>> + kvm_arm_destroy_scratch_host_vcpu(fdarray);
> fdarray is actually never written to.
also fixed by passing the fdarray as arg of
kvm_arm_create_init_scratch_vcpu()
Thanks!
Eric
>
> Warm Regards,
> Khushit
>> + }
>> + return NULL;
>> }
>>
>> static void arm_cpu_add_definition(gpointer data, gpointer user_data)
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props
2026-09-30 7:34 ` Khushit Shah
@ 2026-10-08 7:48 ` Eric Auger
2026-10-08 9:36 ` Khushit Shah
0 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-10-08 7:48 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
Hi Khushit,
On 9/30/26 9:34 AM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Since legacy composite options (such as SVE, virtualization, ...)
>> and new SYSREG props coexist, add some basic consistency checks.
>>
>> Those checks are performed both in kvm_arch_init_vcpu() before
>> applying the SYSREG props at the end of the initialization chain.
>>
>> Some ID reg fields corresponding to legacy composite option scope
>> are not writable. In that case we just check that the field has
>> not become writable.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> Hi Eric,
>
> Gave this another look. I suggest moving this to kvm_arm_expose_idreg_properties().
> What I suggest specifically is:
> - Have a list of ID register fields which conflicts with legacy props.
this depends on the definition of "conflict". For instance does
PMUVer conflicts with has_pmu?
Nevertheless your suggested approach could work for props below which in case they show up would trigger
error_setg(errp, "%s is now exposed but qemu is not ready to support it",
propname);
Thanks
Eric
> - in kvm_arm_expose_idreg_properties() (the new field based approach) never expose fields
> which are part of the above list.
>
> This way the same consistency logic you have will carry over to named models by just adding different
> setters for the above field.
>
> What are your thoughts on this?
>
> Thanks,
> Khushit
>> —
>> target/arm/kvm.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 105 insertions(+)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index ddf320d0e6..f52c03745e 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -340,6 +340,107 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>> return NULL;
>> }
>>
>> +
>> +/**
>> + * kvm_arm_vcpu_validate_sysreg:
>> + *
>> + * Validate a SYSREG field value is consistent with legacy composite options
>> + * Some checks are not implemented because the corresponding sysreg field
>> + * is not currently writable. In that case we make sure the field has not
>> + * become writable, which would mean the user had the capability to set the
>> + * corresponding property.
>> + *
>> + * return true if consistent. false if it is not, along with an error handle
>> + */
>> +static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
>> + uint64_t value, Error **errp)
>> +{
>> + const char *fieldname = field->name;
>> + ARM64SysReg *sysregdesc = &arm64_id_regs[field->index];
>> + const char *regname = sysregdesc->name;
>> + g_autofree char *propname = g_strdup_printf("SYSREG_%s_%s", regname, fieldname);
>> +
>> + /* virtualization */
>> + if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) {
>> + /* consistency with machine virtualization property */
>> + if (cpu->has_el2 && value == 0) {
>> + error_setg(errp,
>> + "Inconsistent -machine virtualization=on and "
>> + "%s=0", propname);
>> + return false;
>> + } else if (!cpu->has_el2 && value > 0) {
>> + error_setg(errp,
>> + "Inconsistent -machine virtualization=off and "
>> + "%s > 0", propname);
>> + return false;
>> + }
>> + /* secure */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL3") && value > 0) {
>> + /* consistency with machine secure property */
>> + error_setg(errp, "%s is set but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + /* MTE */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR1_EL1_MTE")) {
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + /* SVE */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_SVE")) {
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ZFR0_EL1_SVEver")) {
>> + if (cpu_isar_feature(aa64_sve, cpu) && value == 0) {
>> + error_setg(errp, "sve is set but %s is set to 0", propname);
>> + return false;
>> + } else if (!cpu_isar_feature(aa64_sve, cpu) && value > 0) {
>> + error_setg(errp, "sve is not set but %s is greater than 0",
>> + propname);
>> + return false;
>> + }
>> + /* PAUTH */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_APA")) {
>> + /* PAUTH QARMA5 address authentification */
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_API")) {
>> + /* PAUTH Impl Defined address authentification */
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPA")) {
>> + /* QARMA5 generic code authentification */
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPI")) {
>> + /* QARMA5 generic code authentification */
>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> + propname);
>> + return false;
>> + /* PMU */
>> + } else if (!strcmp(propname, "SYSREG_ID_AA64DFR0_EL1_PMUVer")) {
>> + if (cpu->has_pmu && value == 0) {
>> + error_setg(errp, "%s is 0 whereas pmu is set", propname);
>> + return false;
>> + } else if (!cpu->has_pmu && value) {
>> + error_setg(errp, "%s is non null whereas pmu is unset", propname);
>> + return false;
>> + }
>> + /* aarch64 false */
>> + } else if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
>> + if ((!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL0") ||
>> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL1") ||
>> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) && value < 2)
>> + error_setg(errp, "%s is < 2 while aarch64 is set to off",
>> + propname);
>> + return false;
>> + }
>> + return true;
>> +}
>> +
>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>
>> @@ -2241,6 +2342,10 @@ static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>> uint64_t oldfv;
>> int ret;
>>
>> + if (!kvm_arm_vcpu_validate_sysreg(cpu, field, value, errp)) {
>> + return -1;
>> + }
>> +
>> mask = MAKE_64BIT_MASK(lower, length);
>> value = value << lower;
>>
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu
2026-09-30 7:54 ` Khushit Shah
@ 2026-10-08 7:52 ` Eric Auger
2026-10-08 9:45 ` Khushit Shah
0 siblings, 1 reply; 82+ messages in thread
From: Eric Auger @ 2026-10-08 7:52 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 9/30/26 9:54 AM, Khushit Shah wrote:
>
>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> SYSREG prop settings were recorded in a hashtable but they
>> are not yet injected on guest. Iterate over all set fields and
>> apply the new value through KVM_SET_ONE_REG. The new field
>> value overrides the current observable vcpu register value.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> ---
>> target/arm/kvm.c | 65 +++++++++++++++++++++++++++++++++++++++++
>> target/arm/trace-events | 1 +
>> 2 files changed, 66 insertions(+)
>>
>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>> index 3ec2618cc1..ddf320d0e6 100644
>> --- a/target/arm/kvm.c
>> +++ b/target/arm/kvm.c
>> @@ -343,6 +343,9 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>
>> +#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
>> +#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
>> +
>> static void set_sysreg_prop(Object *obj, Visitor *v,
>> const char *name, void *opaque,
>> Error **errp)
>> @@ -2215,6 +2218,63 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
>> return 0;
>> }
>>
>> +static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>> +{
>> + uint64_t *idregs = cpu->isar.idregs;
>> + gpointer key_ptr, value_ptr;
>> + CPUState *cs = CPU(cpu);
>> + GHashTableIter iter;
>> +
>> + g_hash_table_iter_init(&iter, cpu->sysreg_props);
>> +
>> + while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
>> + uint64_t key = (uint64_t)key_ptr;
>> + uint64_t value = (uint64_t)value_ptr;
>> + uint32_t reg_idx = KEY_TO_REG_IDX(key);
>> + uint8_t lower = KEY_TO_SHIFT(key);
>> + ARM64SysReg *reg = &arm64_id_regs[reg_idx];
>> + struct kvm_one_reg kvm_reg;
>> + uint64_t current, old, mask;
>> + uint64_t kvm_idx;
>> + ARM64SysRegField *field = get_field(lower, reg);
>> + int length = field->length;
>> + uint64_t oldfv;
>> + int ret;
>> +
>> + mask = MAKE_64BIT_MASK(lower, length);
>> + value = value << lower;
>> +
>> + old = idregs[reg_idx];
>> +
>> + kvm_idx = idregs_sysreg_to_kvm_reg(id_register_sysreg[reg_idx]);
>> + ret = read_sys_reg64(cs->kvm_fd, ¤t, kvm_idx);
>> + if (ret) {
>> + error_setg(errp, "failed to read the current value of %s",
>> + reg->name);
>> + return ret;
>> + }
>> + oldfv = (current & mask) >> lower;
>> +
>> + idregs[reg_idx] = current & ~mask;
>> + idregs[reg_idx] |= value;
>> +
>> + kvm_reg.id = kvm_idx;
>> + kvm_reg.addr = (uintptr_t)&idregs[reg_idx];
>> +
>> + ret = ioctl(cs->kvm_fd, KVM_SET_ONE_REG, &kvm_reg);
>> + if (ret) {
>> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s.%s "
>> + "(previous is 0x%"PRIx64"): %m", idregs[reg_idx],
>> + reg->name, field->name, oldfv);
>> + return ret;
>> + }
> Hi Eric,
>
> The above is the only KVM-related code here. Can we split this into
> 1. Apply SYSREG_ props callback which resides in cpu64.c?
> 2. The previous writeback to cpregs function that writes back ID registers to KVM?
the problem is the previous method was copying all the idregs that
changed back to cpregs. But those idregs were populated from the "max"
vcpu which in some cases led to inconsistency with the final vcpu
setting. The setter now registers the new field value in a hash table.
Maybe we can just rely on an arch callback to apply them on the guest
Thanks
Eric
>
> The reason being the SYSREG_ props otherwise do not work with any other accelerator.
> We are already trying to make the SYSREG_ getter/setter accel-agnostic.
>
> The above method still has the nicety that -cpu host without any SYSREG_ prop should
> behave the same as previous :)
>
> Side note:
> While we don’t target TCG support currently, I tried your v8 + named models on TCG
> (quick hack; ~20 LOC), and SYSREG_ props/named models works almost out of the box
> there (very minimal testing), which was cool.
>
> Thanks,
> Khushit
>
>> +
>> + trace_apply_sysreg_prop(reg->name, field->name, old, current,
>> + mask, value, idregs[reg_idx]);
>> + }
>> + return 0;
>> +}
>> +
>> int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>> {
>> int ret;
>> @@ -2315,6 +2375,11 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>> }
>> cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>>
>> + ret = kvm_arm_apply_sysreg_props(cpu, errp);
>> + if (ret) {
>> + return ret;
>> + }
>> +
>> return kvm_arm_init_cpreg_list(cpu);
>> }
>>
>> diff --git a/target/arm/trace-events b/target/arm/trace-events
>> index d72ad6b671..b4d2b45a7d 100644
>> --- a/target/arm/trace-events
>> +++ b/target/arm/trace-events
>> @@ -18,6 +18,7 @@ kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint6
>> decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
>> get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
>> set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
>> +apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
>> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
>>
>> # cpu.c
>> --
>> 2.53.0
>>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props
2026-10-08 7:48 ` Eric Auger
@ 2026-10-08 9:36 ` Khushit Shah
2026-10-08 16:36 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-10-08 9:36 UTC (permalink / raw)
To: eric.auger@redhat.com
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 8 Oct 2026, at 1:18 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Hi Khushit,
>
> On 9/30/26 9:34 AM, Khushit Shah wrote:
>>
>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>
>>> !-------------------------------------------------------------------|
>>> CAUTION: External Email
>>>
>>> |-------------------------------------------------------------------!
>>>
>>> Since legacy composite options (such as SVE, virtualization, ...)
>>> and new SYSREG props coexist, add some basic consistency checks.
>>>
>>> Those checks are performed both in kvm_arch_init_vcpu() before
>>> applying the SYSREG props at the end of the initialization chain.
>>>
>>> Some ID reg fields corresponding to legacy composite option scope
>>> are not writable. In that case we just check that the field has
>>> not become writable.
>>>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> Hi Eric,
>>
>> Gave this another look. I suggest moving this to kvm_arm_expose_idreg_properties().
>> What I suggest specifically is:
>> - Have a list of ID register fields which conflicts with legacy props.
> this depends on the definition of "conflict". For instance does
>
> PMUVer conflicts with has_pmu?
>
Yes, PMUVer = 0 is inconsistent with has_pmu=true
> Nevertheless your suggested approach could work for props below which in case they show up would trigger
> error_setg(errp, "%s is now exposed but qemu is not ready to support it",
> propname);
I was thinking of not exposing these props because we know it conflicts. So instead of checking the set props in kvm_arm_vcpu_validate_sysreg, we never expose conflicts in kvm_arm_expose_idreg_properties
I am suggesting this way because for named CPU models, we will have to handle this conflicts differently.
I hope this makes sense.
Thanks,
Khushit
>
> Thanks
>
> Eric
>
>> - in kvm_arm_expose_idreg_properties() (the new field based approach) never expose fields
>> which are part of the above list.
>>
>> This way the same consistency logic you have will carry over to named models by just adding different
>> setters for the above field.
>>
>> What are your thoughts on this?
>>
>> Thanks,
>> Khushit
>>> —
>>> target/arm/kvm.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 105 insertions(+)
>>>
>>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>>> index ddf320d0e6..f52c03745e 100644
>>> --- a/target/arm/kvm.c
>>> +++ b/target/arm/kvm.c
>>> @@ -340,6 +340,107 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>>> return NULL;
>>> }
>>>
>>> +
>>> +/**
>>> + * kvm_arm_vcpu_validate_sysreg:
>>> + *
>>> + * Validate a SYSREG field value is consistent with legacy composite options
>>> + * Some checks are not implemented because the corresponding sysreg field
>>> + * is not currently writable. In that case we make sure the field has not
>>> + * become writable, which would mean the user had the capability to set the
>>> + * corresponding property.
>>> + *
>>> + * return true if consistent. false if it is not, along with an error handle
>>> + */
>>> +static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
>>> + uint64_t value, Error **errp)
>>> +{
>>> + const char *fieldname = field->name;
>>> + ARM64SysReg *sysregdesc = &arm64_id_regs[field->index];
>>> + const char *regname = sysregdesc->name;
>>> + g_autofree char *propname = g_strdup_printf("SYSREG_%s_%s", regname, fieldname);
>>> +
>>> + /* virtualization */
>>> + if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) {
>>> + /* consistency with machine virtualization property */
>>> + if (cpu->has_el2 && value == 0) {
>>> + error_setg(errp,
>>> + "Inconsistent -machine virtualization=on and "
>>> + "%s=0", propname);
>>> + return false;
>>> + } else if (!cpu->has_el2 && value > 0) {
>>> + error_setg(errp,
>>> + "Inconsistent -machine virtualization=off and "
>>> + "%s > 0", propname);
>>> + return false;
>>> + }
>>> + /* secure */
>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL3") && value > 0) {
>>> + /* consistency with machine secure property */
>>> + error_setg(errp, "%s is set but qemu is not ready to support it",
>>> + propname);
>>> + return false;
>>> + /* MTE */
>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR1_EL1_MTE")) {
>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>> + propname);
>>> + return false;
>>> + /* SVE */
>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_SVE")) {
>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>> + propname);
>>> + return false;
>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ZFR0_EL1_SVEver")) {
>>> + if (cpu_isar_feature(aa64_sve, cpu) && value == 0) {
>>> + error_setg(errp, "sve is set but %s is set to 0", propname);
>>> + return false;
>>> + } else if (!cpu_isar_feature(aa64_sve, cpu) && value > 0) {
>>> + error_setg(errp, "sve is not set but %s is greater than 0",
>>> + propname);
>>> + return false;
>>> + }
>>> + /* PAUTH */
>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_APA")) {
>>> + /* PAUTH QARMA5 address authentification */
>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>> + propname);
>>> + return false;
>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_API")) {
>>> + /* PAUTH Impl Defined address authentification */
>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>> + propname);
>>> + return false;
>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPA")) {
>>> + /* QARMA5 generic code authentification */
>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>> + propname);
>>> + return false;
>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPI")) {
>>> + /* QARMA5 generic code authentification */
>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>> + propname);
>>> + return false;
>>> + /* PMU */
>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64DFR0_EL1_PMUVer")) {
>>> + if (cpu->has_pmu && value == 0) {
>>> + error_setg(errp, "%s is 0 whereas pmu is set", propname);
>>> + return false;
>>> + } else if (!cpu->has_pmu && value) {
>>> + error_setg(errp, "%s is non null whereas pmu is unset", propname);
>>> + return false;
>>> + }
>>> + /* aarch64 false */
>>> + } else if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
>>> + if ((!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL0") ||
>>> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL1") ||
>>> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) && value < 2)
>>> + error_setg(errp, "%s is < 2 while aarch64 is set to off",
>>> + propname);
>>> + return false;
>>> + }
>>> + return true;
>>> +}
>>> +
>>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>>
>>> @@ -2241,6 +2342,10 @@ static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>>> uint64_t oldfv;
>>> int ret;
>>>
>>> + if (!kvm_arm_vcpu_validate_sysreg(cpu, field, value, errp)) {
>>> + return -1;
>>> + }
>>> +
>>> mask = MAKE_64BIT_MASK(lower, length);
>>> value = value << lower;
>>>
>>> --
>>> 2.53.0
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu
2026-10-08 7:52 ` Eric Auger
@ 2026-10-08 9:45 ` Khushit Shah
2026-10-09 10:02 ` Eric Auger
0 siblings, 1 reply; 82+ messages in thread
From: Khushit Shah @ 2026-10-08 9:45 UTC (permalink / raw)
To: eric.auger@redhat.com
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 8 Oct 2026, at 1:22 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
>
>
> On 9/30/26 9:54 AM, Khushit Shah wrote:
>>
>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>
>>> !-------------------------------------------------------------------|
>>> CAUTION: External Email
>>>
>>> |-------------------------------------------------------------------!
>>>
>>> SYSREG prop settings were recorded in a hashtable but they
>>> are not yet injected on guest. Iterate over all set fields and
>>> apply the new value through KVM_SET_ONE_REG. The new field
>>> value overrides the current observable vcpu register value.
>>>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>> ---
>>> target/arm/kvm.c | 65 +++++++++++++++++++++++++++++++++++++++++
>>> target/arm/trace-events | 1 +
>>> 2 files changed, 66 insertions(+)
>>>
>>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>>> index 3ec2618cc1..ddf320d0e6 100644
>>> --- a/target/arm/kvm.c
>>> +++ b/target/arm/kvm.c
>>> @@ -343,6 +343,9 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>>
>>> +#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
>>> +#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
>>> +
>>> static void set_sysreg_prop(Object *obj, Visitor *v,
>>> const char *name, void *opaque,
>>> Error **errp)
>>> @@ -2215,6 +2218,63 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
>>> return 0;
>>> }
>>>
>>> +static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>>> +{
>>> + uint64_t *idregs = cpu->isar.idregs;
>>> + gpointer key_ptr, value_ptr;
>>> + CPUState *cs = CPU(cpu);
>>> + GHashTableIter iter;
>>> +
>>> + g_hash_table_iter_init(&iter, cpu->sysreg_props);
>>> +
>>> + while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
>>> + uint64_t key = (uint64_t)key_ptr;
>>> + uint64_t value = (uint64_t)value_ptr;
>>> + uint32_t reg_idx = KEY_TO_REG_IDX(key);
>>> + uint8_t lower = KEY_TO_SHIFT(key);
>>> + ARM64SysReg *reg = &arm64_id_regs[reg_idx];
>>> + struct kvm_one_reg kvm_reg;
>>> + uint64_t current, old, mask;
>>> + uint64_t kvm_idx;
>>> + ARM64SysRegField *field = get_field(lower, reg);
>>> + int length = field->length;
>>> + uint64_t oldfv;
>>> + int ret;
>>> +
>>> + mask = MAKE_64BIT_MASK(lower, length);
>>> + value = value << lower;
>>> +
>>> + old = idregs[reg_idx];
>>> +
>>> + kvm_idx = idregs_sysreg_to_kvm_reg(id_register_sysreg[reg_idx]);
>>> + ret = read_sys_reg64(cs->kvm_fd, ¤t, kvm_idx);
>>> + if (ret) {
>>> + error_setg(errp, "failed to read the current value of %s",
>>> + reg->name);
>>> + return ret;
>>> + }
>>> + oldfv = (current & mask) >> lower;
>>> +
>>> + idregs[reg_idx] = current & ~mask;
>>> + idregs[reg_idx] |= value;
>>> +
>>> + kvm_reg.id = kvm_idx;
>>> + kvm_reg.addr = (uintptr_t)&idregs[reg_idx];
>>> +
>>> + ret = ioctl(cs->kvm_fd, KVM_SET_ONE_REG, &kvm_reg);
>>> + if (ret) {
>>> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s.%s "
>>> + "(previous is 0x%"PRIx64"): %m", idregs[reg_idx],
>>> + reg->name, field->name, oldfv);
>>> + return ret;
>>> + }
>> Hi Eric,
>>
>> The above is the only KVM-related code here. Can we split this into
>> 1. Apply SYSREG_ props callback which resides in cpu64.c?
>> 2. The previous writeback to cpregs function that writes back ID registers to KVM?
>
> the problem is the previous method was copying all the idregs that
> changed back to cpregs. But those idregs were populated from the "max"
> vcpu which in some cases led to inconsistency with the final vcpu
> setting. The setter now registers the new field value in a hash table.
> Maybe we can just rely on an arch callback to apply them on the guest
>
Yes, this is what I am suggesting.
What I was thinking is a KVM-specific code (kvm_arch_init_vcpu) will call callback to cpu64.c to set the property values after the vCPUs are init, and after the callback finishes, the values are written back to cpregs.
With this the inconsistency problem does not arise as we will only call the callback after we properly setup the vCPU.
FWIU, you are suggesting the same thing?
Thanks,
Khushit
> Thanks
>
> Eric
>>
>> The reason being the SYSREG_ props otherwise do not work with any other accelerator.
>> We are already trying to make the SYSREG_ getter/setter accel-agnostic.
>>
>> The above method still has the nicety that -cpu host without any SYSREG_ prop should
>> behave the same as previous :)
>>
>> Side note:
>> While we don’t target TCG support currently, I tried your v8 + named models on TCG
>> (quick hack; ~20 LOC), and SYSREG_ props/named models works almost out of the box
>> there (very minimal testing), which was cool.
>>
>> Thanks,
>> Khushit
>>
>>> +
>>> + trace_apply_sysreg_prop(reg->name, field->name, old, current,
>>> + mask, value, idregs[reg_idx]);
>>> + }
>>> + return 0;
>>> +}
>>> +
>>> int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>>> {
>>> int ret;
>>> @@ -2315,6 +2375,11 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>>> }
>>> cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>>>
>>> + ret = kvm_arm_apply_sysreg_props(cpu, errp);
>>> + if (ret) {
>>> + return ret;
>>> + }
>>> +
>>> return kvm_arm_init_cpreg_list(cpu);
>>> }
>>>
>>> diff --git a/target/arm/trace-events b/target/arm/trace-events
>>> index d72ad6b671..b4d2b45a7d 100644
>>> --- a/target/arm/trace-events
>>> +++ b/target/arm/trace-events
>>> @@ -18,6 +18,7 @@ kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint6
>>> decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
>>> get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
>>> set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
>>> +apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
>>> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
>>>
>>> # cpu.c
>>> --
>>> 2.53.0
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu
2026-09-30 15:08 ` Eric Auger
@ 2026-10-08 9:56 ` Khushit Shah
0 siblings, 0 replies; 82+ messages in thread
From: Khushit Shah @ 2026-10-08 9:56 UTC (permalink / raw)
To: eric.auger@redhat.com
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
> On 30 Sep 2026, at 8:38 PM, Eric Auger <eric.auger@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> CAUTION: External Email
>
> |-------------------------------------------------------------------!
>
> Hi Khushit,
>
> On 9/28/26 12:44 PM, Khushit Shah wrote:
>>
>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>
>>> !-------------------------------------------------------------------|
>>> CAUTION: External Email
>>>
>>> |-------------------------------------------------------------------!
>>>
>>> SYSREG prop settings were recorded in a hashtable but they
>>> are not yet injected on guest. Iterate over all set fields and
>>> apply the new value through KVM_SET_ONE_REG. The new field
>>> value overrides the current observable vcpu register value.
>>>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> With this, I suppose, what named models will do is directly write to
>> ID register state, As it also defines state which affects vCPU init flags also.
> That's not what I had in mind. I thought you would apply the SYSREG
> settings at the same time. As mentionned, I don't think those settings
> are meant to substitute to legacy composite options that affect vcpu
> init settings.
> Besides the principle of this preparatory series is that the props for
> writable ID reg fields are meant to be fully reusable for named vcpu
> models. Only props for non writable fields should be specific to named
> vcpu models as they do not make sense on host/max vcpu model
Hi Eric,
Sorry, missed this mail. Yes yes, we want to reuse all the existing infra for
named CPU models. Only the fields that conflicts with legacy options needs
special handling in named CPU models.
>>
>>> ---
>>> target/arm/kvm.c | 65 +++++++++++++++++++++++++++++++++++++++++
>>> target/arm/trace-events | 1 +
>>> 2 files changed, 66 insertions(+)
>>>
>>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>>> index 3ec2618cc1..ddf320d0e6 100644
>>> --- a/target/arm/kvm.c
>>> +++ b/target/arm/kvm.c
>>> @@ -343,6 +343,9 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>>
>>> +#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
>>> +#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
>>> +
>>> static void set_sysreg_prop(Object *obj, Visitor *v,
>>> const char *name, void *opaque,
>>> Error **errp)
>>> @@ -2215,6 +2218,63 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
>>> return 0;
>>> }
>>>
>>> +static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>>> +{
>>> + uint64_t *idregs = cpu->isar.idregs;
>>> + gpointer key_ptr, value_ptr;
>>> + CPUState *cs = CPU(cpu);
>>> + GHashTableIter iter;
>>> +
>>> + g_hash_table_iter_init(&iter, cpu->sysreg_props);
>>> +
>>> + while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
>>> + uint64_t key = (uint64_t)key_ptr;
>>> + uint64_t value = (uint64_t)value_ptr;
>>> + uint32_t reg_idx = KEY_TO_REG_IDX(key);
>>> + uint8_t lower = KEY_TO_SHIFT(key);
>>> + ARM64SysReg *reg = &arm64_id_regs[reg_idx];
>>> + struct kvm_one_reg kvm_reg;
>>> + uint64_t current, old, mask;
>>> + uint64_t kvm_idx;
>>> + ARM64SysRegField *field = get_field(lower, reg);
>>> + int length = field->length;
>>> + uint64_t oldfv;
>>> + int ret;
>>> +
>>> + mask = MAKE_64BIT_MASK(lower, length);
>>> + value = value << lower;
>>> +
>>> + old = idregs[reg_idx];
>>> +
>>> + kvm_idx = idregs_sysreg_to_kvm_reg(id_register_sysreg[reg_idx]);
>>> + ret = read_sys_reg64(cs->kvm_fd, ¤t, kvm_idx);
>>> + if (ret) {
>>> + error_setg(errp, "failed to read the current value of %s",
>>> + reg->name);
>>> + return ret;
>>> + }
>>> + oldfv = (current & mask) >> lower;
>>> +
>>> + idregs[reg_idx] = current & ~mask;
>>> + idregs[reg_idx] |= value;
>>> + kvm_reg.id = kvm_idx;
>>> + kvm_reg.addr = (uintptr_t)&idregs[reg_idx];
>>> +
>> We can ignore this if value == old value
> sure, modified
>>
>>> + ret = ioctl(cs->kvm_fd, KVM_SET_ONE_REG, &kvm_reg);
>>> + if (ret) {
>>> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s.%s "
>>> + "(previous is 0x%"PRIx64"): %m", idregs[reg_idx],
>>> + reg->name, field->name, oldfv);
>>> + return ret;
>>> + }
>>> +
>>> + trace_apply_sysreg_prop(reg->name, field->name, old, current,
>>> + mask, value, idregs[reg_idx]);
>>> + }
>>> + return 0;
>>> +}
>>> +
>>> int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>>> {
>>> int ret;
>>> @@ -2315,6 +2375,11 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>>> }
>>> cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>>>
>>> + ret = kvm_arm_apply_sysreg_props(cpu, errp);
>>> + if (ret) {
>>> + return ret;
>>> + }
>>> +
>> This should also happen on vCPU reset.
> On which path is it needed? on qmp system_reset I can see that the
> former values applied with SYSREG settings are kept.
>
Should kvm_arm_reset_vcpu() also be updated?
Thanks,
Khushit
> Thanks
>
> Eric
>>
>> Overall, I like this approach as if the user does not provide any property overrides, it should behave the same as older builds.
>>
>> Warm Regards,
>> Khushit
>>> return kvm_arm_init_cpreg_list(cpu);
>>> }
>>>
>>> diff --git a/target/arm/trace-events b/target/arm/trace-events
>>> index d72ad6b671..b4d2b45a7d 100644
>>> --- a/target/arm/trace-events
>>> +++ b/target/arm/trace-events
>>> @@ -18,6 +18,7 @@ kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint6
>>> decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
>>> get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
>>> set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
>>> +apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
>>> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
>>>
>>> # cpu.c
>>> --
>>> 2.53.0
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props
2026-10-08 9:36 ` Khushit Shah
@ 2026-10-08 16:36 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-10-08 16:36 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 10/8/26 11:36 AM, Khushit Shah wrote:
>
>> On 8 Oct 2026, at 1:18 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Hi Khushit,
>>
>> On 9/30/26 9:34 AM, Khushit Shah wrote:
>>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>>
>>>> !-------------------------------------------------------------------|
>>>> CAUTION: External Email
>>>>
>>>> |-------------------------------------------------------------------!
>>>>
>>>> Since legacy composite options (such as SVE, virtualization, ...)
>>>> and new SYSREG props coexist, add some basic consistency checks.
>>>>
>>>> Those checks are performed both in kvm_arch_init_vcpu() before
>>>> applying the SYSREG props at the end of the initialization chain.
>>>>
>>>> Some ID reg fields corresponding to legacy composite option scope
>>>> are not writable. In that case we just check that the field has
>>>> not become writable.
>>>>
>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>> Hi Eric,
>>>
>>> Gave this another look. I suggest moving this to kvm_arm_expose_idreg_properties().
>>> What I suggest specifically is:
>>> - Have a list of ID register fields which conflicts with legacy props.
>> this depends on the definition of "conflict". For instance does
>>
>> PMUVer conflicts with has_pmu?
>>
> Yes, PMUVer = 0 is inconsistent with has_pmu=true
>
>> Nevertheless your suggested approach could work for props below which in case they show up would trigger
>> error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>> propname);
> I was thinking of not exposing these props because we know it conflicts. So instead of checking the set props in kvm_arm_vcpu_validate_sysreg, we never expose conflicts in kvm_arm_expose_idreg_properties
>
> I am suggesting this way because for named CPU models, we will have to handle this conflicts differently.
I am afraid this a bit aggressive as a defensive approach. I like the
idea for fields that are not yet writable. We can easily switch to a
skiplist on property generation. For others for which some valid
combinations exist I would keep the existing check. But let's see how it
goes with named vcpu models. If it appears this extra complexity is not
needed we can simplify that if needed.
Thanks
Eric
>
>
> I hope this makes sense.
>
>
> Thanks,
> Khushit
>
>> Thanks
>>
>> Eric
>>
>>> - in kvm_arm_expose_idreg_properties() (the new field based approach) never expose fields
>>> which are part of the above list.
>>>
>>> This way the same consistency logic you have will carry over to named models by just adding different
>>> setters for the above field.
>>>
>>> What are your thoughts on this?
>>>
>>> Thanks,
>>> Khushit
>>>> —
>>>> target/arm/kvm.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++
>>>> 1 file changed, 105 insertions(+)
>>>>
>>>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>>>> index ddf320d0e6..f52c03745e 100644
>>>> --- a/target/arm/kvm.c
>>>> +++ b/target/arm/kvm.c
>>>> @@ -340,6 +340,107 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>>>> return NULL;
>>>> }
>>>>
>>>> +
>>>> +/**
>>>> + * kvm_arm_vcpu_validate_sysreg:
>>>> + *
>>>> + * Validate a SYSREG field value is consistent with legacy composite options
>>>> + * Some checks are not implemented because the corresponding sysreg field
>>>> + * is not currently writable. In that case we make sure the field has not
>>>> + * become writable, which would mean the user had the capability to set the
>>>> + * corresponding property.
>>>> + *
>>>> + * return true if consistent. false if it is not, along with an error handle
>>>> + */
>>>> +static bool kvm_arm_vcpu_validate_sysreg(ARMCPU *cpu, ARM64SysRegField *field,
>>>> + uint64_t value, Error **errp)
>>>> +{
>>>> + const char *fieldname = field->name;
>>>> + ARM64SysReg *sysregdesc = &arm64_id_regs[field->index];
>>>> + const char *regname = sysregdesc->name;
>>>> + g_autofree char *propname = g_strdup_printf("SYSREG_%s_%s", regname, fieldname);
>>>> +
>>>> + /* virtualization */
>>>> + if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) {
>>>> + /* consistency with machine virtualization property */
>>>> + if (cpu->has_el2 && value == 0) {
>>>> + error_setg(errp,
>>>> + "Inconsistent -machine virtualization=on and "
>>>> + "%s=0", propname);
>>>> + return false;
>>>> + } else if (!cpu->has_el2 && value > 0) {
>>>> + error_setg(errp,
>>>> + "Inconsistent -machine virtualization=off and "
>>>> + "%s > 0", propname);
>>>> + return false;
>>>> + }
>>>> + /* secure */
>>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL3") && value > 0) {
>>>> + /* consistency with machine secure property */
>>>> + error_setg(errp, "%s is set but qemu is not ready to support it",
>>>> + propname);
>>>> + return false;
>>>> + /* MTE */
>>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR1_EL1_MTE")) {
>>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>>> + propname);
>>>> + return false;
>>>> + /* SVE */
>>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_SVE")) {
>>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>>> + propname);
>>>> + return false;
>>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ZFR0_EL1_SVEver")) {
>>>> + if (cpu_isar_feature(aa64_sve, cpu) && value == 0) {
>>>> + error_setg(errp, "sve is set but %s is set to 0", propname);
>>>> + return false;
>>>> + } else if (!cpu_isar_feature(aa64_sve, cpu) && value > 0) {
>>>> + error_setg(errp, "sve is not set but %s is greater than 0",
>>>> + propname);
>>>> + return false;
>>>> + }
>>>> + /* PAUTH */
>>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_APA")) {
>>>> + /* PAUTH QARMA5 address authentification */
>>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>>> + propname);
>>>> + return false;
>>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_API")) {
>>>> + /* PAUTH Impl Defined address authentification */
>>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>>> + propname);
>>>> + return false;
>>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPA")) {
>>>> + /* QARMA5 generic code authentification */
>>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>>> + propname);
>>>> + return false;
>>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64ISAR1_EL1_GPI")) {
>>>> + /* QARMA5 generic code authentification */
>>>> + error_setg(errp, "%s is now exposed but qemu is not ready to support it",
>>>> + propname);
>>>> + return false;
>>>> + /* PMU */
>>>> + } else if (!strcmp(propname, "SYSREG_ID_AA64DFR0_EL1_PMUVer")) {
>>>> + if (cpu->has_pmu && value == 0) {
>>>> + error_setg(errp, "%s is 0 whereas pmu is set", propname);
>>>> + return false;
>>>> + } else if (!cpu->has_pmu && value) {
>>>> + error_setg(errp, "%s is non null whereas pmu is unset", propname);
>>>> + return false;
>>>> + }
>>>> + /* aarch64 false */
>>>> + } else if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
>>>> + if ((!strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL0") ||
>>>> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL1") ||
>>>> + !strcmp(propname, "SYSREG_ID_AA64PFR0_EL1_EL2")) && value < 2)
>>>> + error_setg(errp, "%s is < 2 while aarch64 is set to off",
>>>> + propname);
>>>> + return false;
>>>> + }
>>>> + return true;
>>>> +}
>>>> +
>>>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>>>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>>>
>>>> @@ -2241,6 +2342,10 @@ static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>>>> uint64_t oldfv;
>>>> int ret;
>>>>
>>>> + if (!kvm_arm_vcpu_validate_sysreg(cpu, field, value, errp)) {
>>>> + return -1;
>>>> + }
>>>> +
>>>> mask = MAKE_64BIT_MASK(lower, length);
>>>> value = value << lower;
>>>>
>>>> --
>>>> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
* Re: [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu
2026-10-08 9:45 ` Khushit Shah
@ 2026-10-09 10:02 ` Eric Auger
0 siblings, 0 replies; 82+ messages in thread
From: Eric Auger @ 2026-10-09 10:02 UTC (permalink / raw)
To: Khushit Shah
Cc: eric.auger.pro@gmail.com, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, kvmarm@lists.linux.dev,
peter.maydell@linaro.org, Shaju Abraham, yangjinqian1@huawei.com,
cohuck@redhat.com, richard.henderson@linaro.org,
sebott@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, maz@kernel.org, oliver.upton@linux.dev,
pbonzini@redhat.com, armbru@redhat.com, berrange@redhat.com,
abologna@redhat.com, jdenemar@redhat.com
On 10/8/26 11:45 AM, Khushit Shah wrote:
>
>> On 8 Oct 2026, at 1:22 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>
>> !-------------------------------------------------------------------|
>> CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>>
>>
>> On 9/30/26 9:54 AM, Khushit Shah wrote:
>>>> On 16 Sep 2026, at 8:15 PM, Eric Auger <eric.auger@redhat.com> wrote:
>>>>
>>>> !-------------------------------------------------------------------|
>>>> CAUTION: External Email
>>>>
>>>> |-------------------------------------------------------------------!
>>>>
>>>> SYSREG prop settings were recorded in a hashtable but they
>>>> are not yet injected on guest. Iterate over all set fields and
>>>> apply the new value through KVM_SET_ONE_REG. The new field
>>>> value overrides the current observable vcpu register value.
>>>>
>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>> ---
>>>> target/arm/kvm.c | 65 +++++++++++++++++++++++++++++++++++++++++
>>>> target/arm/trace-events | 1 +
>>>> 2 files changed, 66 insertions(+)
>>>>
>>>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>>>> index 3ec2618cc1..ddf320d0e6 100644
>>>> --- a/target/arm/kvm.c
>>>> +++ b/target/arm/kvm.c
>>>> @@ -343,6 +343,9 @@ static ARM64SysRegField *get_field(int i, ARM64SysReg *reg)
>>>> #define MAKE_IDREG_KEY(reg_idx, field_shift) \
>>>> (((uint64_t)(reg_idx) << 8) | ((uint64_t)(field_shift) & 0xFF))
>>>>
>>>> +#define KEY_TO_REG_IDX(key) ((uint32_t)(((uint64_t)(key)) >> 8))
>>>> +#define KEY_TO_SHIFT(key) ((uint8_t)(((uint64_t)(key)) & 0xFF))
>>>> +
>>>> static void set_sysreg_prop(Object *obj, Visitor *v,
>>>> const char *name, void *opaque,
>>>> Error **errp)
>>>> @@ -2215,6 +2218,63 @@ int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
>>>> return 0;
>>>> }
>>>>
>>>> +static int kvm_arm_apply_sysreg_props(ARMCPU *cpu, Error **errp)
>>>> +{
>>>> + uint64_t *idregs = cpu->isar.idregs;
>>>> + gpointer key_ptr, value_ptr;
>>>> + CPUState *cs = CPU(cpu);
>>>> + GHashTableIter iter;
>>>> +
>>>> + g_hash_table_iter_init(&iter, cpu->sysreg_props);
>>>> +
>>>> + while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
>>>> + uint64_t key = (uint64_t)key_ptr;
>>>> + uint64_t value = (uint64_t)value_ptr;
>>>> + uint32_t reg_idx = KEY_TO_REG_IDX(key);
>>>> + uint8_t lower = KEY_TO_SHIFT(key);
>>>> + ARM64SysReg *reg = &arm64_id_regs[reg_idx];
>>>> + struct kvm_one_reg kvm_reg;
>>>> + uint64_t current, old, mask;
>>>> + uint64_t kvm_idx;
>>>> + ARM64SysRegField *field = get_field(lower, reg);
>>>> + int length = field->length;
>>>> + uint64_t oldfv;
>>>> + int ret;
>>>> +
>>>> + mask = MAKE_64BIT_MASK(lower, length);
>>>> + value = value << lower;
>>>> +
>>>> + old = idregs[reg_idx];
>>>> +
>>>> + kvm_idx = idregs_sysreg_to_kvm_reg(id_register_sysreg[reg_idx]);
>>>> + ret = read_sys_reg64(cs->kvm_fd, ¤t, kvm_idx);
>>>> + if (ret) {
>>>> + error_setg(errp, "failed to read the current value of %s",
>>>> + reg->name);
>>>> + return ret;
>>>> + }
>>>> + oldfv = (current & mask) >> lower;
>>>> +
>>>> + idregs[reg_idx] = current & ~mask;
>>>> + idregs[reg_idx] |= value;
>>>> +
>>>> + kvm_reg.id = kvm_idx;
>>>> + kvm_reg.addr = (uintptr_t)&idregs[reg_idx];
>>>> +
>>>> + ret = ioctl(cs->kvm_fd, KVM_SET_ONE_REG, &kvm_reg);
>>>> + if (ret) {
>>>> + error_setg(errp, "failed to apply new value 0x%"PRIx64" for field %s.%s "
>>>> + "(previous is 0x%"PRIx64"): %m", idregs[reg_idx],
>>>> + reg->name, field->name, oldfv);
>>>> + return ret;
>>>> + }
>>> Hi Eric,
>>>
>>> The above is the only KVM-related code here. Can we split this into
>>> 1. Apply SYSREG_ props callback which resides in cpu64.c?
>>> 2. The previous writeback to cpregs function that writes back ID registers to KVM?
>> the problem is the previous method was copying all the idregs that
>> changed back to cpregs. But those idregs were populated from the "max"
>> vcpu which in some cases led to inconsistency with the final vcpu
>> setting. The setter now registers the new field value in a hash table.
>> Maybe we can just rely on an arch callback to apply them on the guest
>>
> Yes, this is what I am suggesting.
>
> What I was thinking is a KVM-specific code (kvm_arch_init_vcpu) will call callback to cpu64.c to set the property values after the vCPUs are init, and after the callback finishes, the values are written back to cpregs.
>
> With this the inconsistency problem does not arise as we will only call the callback after we properly setup the vCPU.
I have moved most of the code in cpu64, ie. hash table lookup and
cpu->isar.idregs[] update on success. The functional uses an
acceleration specific callback to apply the field value on guest vcpu.
However the arch agnostic function is still called in kvm so that the
kvmlist is synced to cpregs afterwards.
Let's see in v10 if it matches your expectations
Thanks
Eric
>
> FWIU, you are suggesting the same thing?
>
> Thanks,
> Khushit
>> Thanks
>>
>> Eric
>>> The reason being the SYSREG_ props otherwise do not work with any other accelerator.
>>> We are already trying to make the SYSREG_ getter/setter accel-agnostic.
>>>
>>> The above method still has the nicety that -cpu host without any SYSREG_ prop should
>>> behave the same as previous :)
>>>
>>> Side note:
>>> While we don’t target TCG support currently, I tried your v8 + named models on TCG
>>> (quick hack; ~20 LOC), and SYSREG_ props/named models works almost out of the box
>>> there (very minimal testing), which was cool.
>>>
>>> Thanks,
>>> Khushit
>>>
>>>> +
>>>> + trace_apply_sysreg_prop(reg->name, field->name, old, current,
>>>> + mask, value, idregs[reg_idx]);
>>>> + }
>>>> + return 0;
>>>> +}
>>>> +
>>>> int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>>>> {
>>>> int ret;
>>>> @@ -2315,6 +2375,11 @@ int kvm_arch_init_vcpu(CPUState *cs, Error **errp)
>>>> }
>>>> cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
>>>>
>>>> + ret = kvm_arm_apply_sysreg_props(cpu, errp);
>>>> + if (ret) {
>>>> + return ret;
>>>> + }
>>>> +
>>>> return kvm_arm_init_cpreg_list(cpu);
>>>> }
>>>>
>>>> diff --git a/target/arm/trace-events b/target/arm/trace-events
>>>> index d72ad6b671..b4d2b45a7d 100644
>>>> --- a/target/arm/trace-events
>>>> +++ b/target/arm/trace-events
>>>> @@ -18,6 +18,7 @@ kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint6
>>>> decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)"
>>>> get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64
>>>> set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64
>>>> +apply_sysreg_prop(const char *reg_name, const char *field_name, uint64_t old, uint64_t current, uint64_t mask, uint64_t field_value, uint64_t new) "%s.%s old=0x%"PRIx64" current=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new=0x%"PRIx64
>>>> nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties"
>>>>
>>>> # cpu.c
>>>> --
>>>> 2.53.0
>
^ permalink raw reply [flat|nested] 82+ messages in thread
end of thread, other threads:[~2026-10-09 10:03 UTC | newest]
Thread overview: 82+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-16 14:45 [PATCH v9 00/26] kvm/arm: Introduce a customizable aarch64 KVM host model Eric Auger
2026-09-16 14:45 ` [PATCH v9 01/26] scripts: introduce scripts/update-aarch64-cpu-sysregs-header.py Eric Auger
2026-09-23 7:08 ` Khushit Shah
2026-09-23 14:22 ` Eric Auger
2026-09-24 10:24 ` Khushit Shah
2026-09-29 12:31 ` Eric Auger
2026-09-29 14:28 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 02/26] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
2026-09-16 14:45 ` [PATCH v9 03/26] target/arm/cpu-sysregs.h.inc: Update with automatic generation Eric Auger
2026-09-23 9:13 ` Khushit Shah
2026-09-23 14:31 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 04/26] arm/cpu: Add infra to handle generated ID register definitions Eric Auger
2026-09-24 10:01 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 05/26] scripts: Introduce scripts/aarch64_sysreg_helpers module Eric Auger
2026-09-24 10:18 ` Khushit Shah
2026-09-24 10:23 ` Khushit Shah
2026-09-29 15:14 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 06/26] scripts: Introduce scripts/update-aarch64-cpu-sysreg-properties.py Eric Auger
2026-09-25 9:29 ` Khushit Shah
2026-10-02 12:59 ` Eric Auger
2026-10-05 5:37 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 07/26] target/arm/cpu-idregs.h.inc: generate with script Eric Auger
2026-09-25 11:19 ` Khushit Shah
2026-09-29 16:55 ` Eric Auger
2026-09-30 5:40 ` Khushit Shah
2026-09-30 6:34 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 08/26] target/arm/cpu-idregs.h.inc: Generate enum values Eric Auger
2026-09-25 11:59 ` Khushit Shah
2026-10-02 16:05 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 09/26] target/arm/cpu_idregs: generate tables for Arm64 ID registers and fields Eric Auger
2026-09-25 12:16 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 10/26] target/arm/kvm: Retrieve writable ID reg map Eric Auger
2026-09-25 12:37 ` Khushit Shah
2026-09-28 12:34 ` Eric Auger
2026-09-28 13:23 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 11/26] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0 Eric Auger
2026-09-25 12:46 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 12/26] arm/kvm: Initialize isar.idregs[] with all writable host ID regs Eric Auger
2026-09-25 13:27 ` Khushit Shah
2026-09-28 17:34 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 13/26] target/arm/kvm: Introduce kvm_arm_expose_idreg_properties Eric Auger
2026-09-24 6:26 ` Khushit Shah
2026-09-24 6:42 ` Eric Auger
2026-09-28 15:21 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 14/26] target/arm/kvm: Implement SYSREG property setter and getter Eric Auger
2026-09-28 9:28 ` Khushit Shah
2026-09-28 11:49 ` Eric Auger
2026-09-28 13:20 ` Khushit Shah
2026-09-28 13:32 ` Eric Auger
2026-09-28 13:42 ` Khushit Shah
2026-09-16 14:45 ` [PATCH v9 15/26] target/arm/kvm: Pass an Error handle to kvm_arch_init_vcpu Eric Auger
2026-09-16 14:45 ` [PATCH v9 16/26] target/arm/kvm: Apply SYSREG props to the final vcpu Eric Auger
2026-09-28 10:44 ` Khushit Shah
2026-09-30 15:08 ` Eric Auger
2026-10-08 9:56 ` Khushit Shah
2026-09-30 15:11 ` Eric Auger
2026-09-30 7:54 ` Khushit Shah
2026-10-08 7:52 ` Eric Auger
2026-10-08 9:45 ` Khushit Shah
2026-10-09 10:02 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 17/26] target/arm/kvm: Add consistency checking for SYSREG props Eric Auger
2026-09-28 12:53 ` Khushit Shah
2026-09-29 12:13 ` Eric Auger
2026-09-30 7:34 ` Khushit Shah
2026-10-08 7:48 ` Eric Auger
2026-10-08 9:36 ` Khushit Shah
2026-10-08 16:36 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 18/26] target/arm/cpu: Expose writable ID reg field properties on the kvm host vcpu model Eric Auger
2026-09-28 13:26 ` Khushit Shah
2026-09-28 13:35 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 19/26] target/arm/cpu-idregs.h.inc: Generate reserved fields Eric Auger
2026-09-16 14:45 ` [PATCH v9 20/26] target/arm/kvm: Ignore and trace unexpected writable " Eric Auger
2026-09-16 14:45 ` [PATCH v9 21/26] target/arm/kvm: add helper to test SYSREG props against a scratch vcpu Eric Auger
2026-09-28 13:34 ` Khushit Shah
2026-09-30 17:43 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 22/26] target/arm/kvm: Add an error handle to kvm_arm_create_scratch_host_vcpu Eric Auger
2026-09-16 14:45 ` [PATCH v9 23/26] target/arm/kvm: Introduce kvm_arm_vcpu_prepare_init_features helper Eric Auger
2026-09-16 14:45 ` [PATCH v9 24/26] target/arm/kvm: Introduce kvm_arm_create_init_scratch_vcpu() Eric Auger
2026-09-16 14:45 ` [PATCH v9 25/26] arm-qmp-cmds: introspection for ID register props Eric Auger
2026-09-28 14:39 ` Khushit Shah
2026-10-07 14:27 ` Eric Auger
2026-09-16 14:45 ` [PATCH v9 26/26] arm/cpu-features: document ID reg properties Eric Auger
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.