target-arm queue:

* Fix physical address resolution for Stage2
  * pl011: refactoring, implement reset method
  * Support GICv3 with hvf acceleration
  * sbsa-ref: remove cortex-a76 from list of supported cpus
  * Correct syndrome for ATS12NSO* traps at Secure EL1
  * Fix priority of HSTR_EL2 traps vs UNDEFs
  * Implement FEAT_FGT for '-cpu max'
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmPdGisZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3iTND/4qnI00PcqPhdZAD083admx
 Tn+7OaTd8aaWHDMvbnV3fNsvAEt//j8DdzeBGDLbgfhBuOCPB8z7oDSr7oqczmys
 Yjnh25o6IDUYtMnKR+dBwFKGvAqWwM4UdEllkHJvvM+QpnlH7iu9lCkgYr6PvBYA
 h4ajfZ5J7C2OmFJZqsKa2Ot3mveFxos1QzgWSmsWNGTJiZTOCiD7AvuCnEsBBaVP
 pESY+5eGjVmjv6ocHxcHG4LA456bHAf6JiCgKqgwowRBlJenpsnNgKleIN4gQA/J
 wtfLALNe6FkTV9tzK/MgtO1qOhxkUHrnTrYTtTLmk4H1VryFdDvomYB34zBIgfMY
 l1LmMba6UCoxtck13D5jv1xkE56o7Z3kqrhyOvP+aHFdi+dvYQ/z+b8pqUeYeSiu
 EbVWa/270JwVdbBT08vfW33Ci9n7fxZtRCrvj2viMgOiQOKwXYEb5AVxM9TRZSKC
 Y+1m5frW2HQ+KNvjEyHdMJ8q4nFhaS5Bq2A2RMaQCV2QBuBJvFkGL3ul6M0lw/eq
 cAZDKN6H/8N2l2DPcPHUy6RMiqUPSnemvFI814ElKeHGa1V1c7Iw9C4lWAV5Ue5E
 gotHC1ros89xV0Eg0gaB9UgX8TgbQUfc3g1g6YUvTCfQdvxL0H1rY+wUWU1h1V2r
 VdhxI95gUkgmoVnk8KnwIw==
 =hk0j
 -----END PGP SIGNATURE-----

Merge tag 'pull-target-arm-20230203' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * Fix physical address resolution for Stage2
 * pl011: refactoring, implement reset method
 * Support GICv3 with hvf acceleration
 * sbsa-ref: remove cortex-a76 from list of supported cpus
 * Correct syndrome for ATS12NSO* traps at Secure EL1
 * Fix priority of HSTR_EL2 traps vs UNDEFs
 * Implement FEAT_FGT for '-cpu max'

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmPdGisZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3iTND/4qnI00PcqPhdZAD083admx
# Tn+7OaTd8aaWHDMvbnV3fNsvAEt//j8DdzeBGDLbgfhBuOCPB8z7oDSr7oqczmys
# Yjnh25o6IDUYtMnKR+dBwFKGvAqWwM4UdEllkHJvvM+QpnlH7iu9lCkgYr6PvBYA
# h4ajfZ5J7C2OmFJZqsKa2Ot3mveFxos1QzgWSmsWNGTJiZTOCiD7AvuCnEsBBaVP
# pESY+5eGjVmjv6ocHxcHG4LA456bHAf6JiCgKqgwowRBlJenpsnNgKleIN4gQA/J
# wtfLALNe6FkTV9tzK/MgtO1qOhxkUHrnTrYTtTLmk4H1VryFdDvomYB34zBIgfMY
# l1LmMba6UCoxtck13D5jv1xkE56o7Z3kqrhyOvP+aHFdi+dvYQ/z+b8pqUeYeSiu
# EbVWa/270JwVdbBT08vfW33Ci9n7fxZtRCrvj2viMgOiQOKwXYEb5AVxM9TRZSKC
# Y+1m5frW2HQ+KNvjEyHdMJ8q4nFhaS5Bq2A2RMaQCV2QBuBJvFkGL3ul6M0lw/eq
# cAZDKN6H/8N2l2DPcPHUy6RMiqUPSnemvFI814ElKeHGa1V1c7Iw9C4lWAV5Ue5E
# gotHC1ros89xV0Eg0gaB9UgX8TgbQUfc3g1g6YUvTCfQdvxL0H1rY+wUWU1h1V2r
# VdhxI95gUkgmoVnk8KnwIw==
# =hk0j
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 03 Feb 2023 14:28:59 GMT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* tag 'pull-target-arm-20230203' of https://git.linaro.org/people/pmaydell/qemu-arm: (33 commits)
  target/arm: Enable FEAT_FGT on '-cpu max'
  target/arm: Implement MDCR_EL2.TDCC and MDCR_EL3.TDCC traps
  target/arm: Implement the HFGITR_EL2.SVC_EL0 and SVC_EL1 traps
  target/arm: Implement the HFGITR_EL2.ERET trap
  target/arm: Mark up sysregs for HFGITR bits 48..63
  target/arm: Mark up sysregs for HFGITR bits 18..47
  target/arm: Mark up sysregs for HFGITR bits 12..17
  target/arm: Mark up sysregs for HFGITR bits 0..11
  target/arm: Mark up sysregs for HDFGRTR bits 12..63
  target/arm: Mark up sysregs for HDFGRTR bits 0..11
  target/arm: Mark up sysregs for HFGRTR bits 36..63
  target/arm: Mark up sysregs for HFGRTR bits 24..35
  target/arm: Mark up sysregs for HFGRTR bits 12..23
  target/arm: Mark up sysregs for HFGRTR bits 0..11
  target/arm: Implement FGT trapping infrastructure
  target/arm: Define the FEAT_FGT registers
  target/arm: Disable HSTR_EL2 traps if EL2 is not enabled
  target/arm: Make HSTR_EL2 traps take priority over UNDEF-at-EL1
  target/arm: All UNDEF-at-EL0 traps take priority over HSTR_EL2 traps
  target/arm: Move do_coproc_insn() syndrome calculation earlier
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2023-02-03 15:33:05 +00:00
commit 0730eab4d3
21 changed files with 1340 additions and 189 deletions

View file

@ -29,6 +29,7 @@
#include "exec/hwaddr.h"
#include "kvm_arm.h"
#include "hw/arm/boot.h"
#include "hw/arm/smmuv3.h"
#include "hw/block/flash.h"
#include "hw/boards.h"
#include "hw/ide/internal.h"
@ -145,7 +146,6 @@ static const int sbsa_ref_irqmap[] = {
static const char * const valid_cpus[] = {
ARM_CPU_TYPE_NAME("cortex-a57"),
ARM_CPU_TYPE_NAME("cortex-a72"),
ARM_CPU_TYPE_NAME("cortex-a76"),
ARM_CPU_TYPE_NAME("neoverse-n1"),
ARM_CPU_TYPE_NAME("max"),
};
@ -574,7 +574,7 @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
DeviceState *dev;
int i;
dev = qdev_new("arm-smmuv3");
dev = qdev_new(TYPE_ARM_SMMUV3);
object_property_set_link(OBJECT(dev), "primary-bus", OBJECT(bus),
&error_abort);

View file

@ -47,8 +47,10 @@
#include "sysemu/numa.h"
#include "sysemu/runstate.h"
#include "sysemu/tpm.h"
#include "sysemu/tcg.h"
#include "sysemu/kvm.h"
#include "sysemu/hvf.h"
#include "sysemu/qtest.h"
#include "hw/loader.h"
#include "qapi/error.h"
#include "qemu/bitops.h"
@ -1343,7 +1345,7 @@ static void create_smmu(const VirtMachineState *vms,
return;
}
dev = qdev_new("arm-smmuv3");
dev = qdev_new(TYPE_ARM_SMMUV3);
object_property_set_link(OBJECT(dev), "primary-bus", OBJECT(bus),
&error_abort);
@ -1820,6 +1822,84 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
}
}
static VirtGICType finalize_gic_version_do(const char *accel_name,
VirtGICType gic_version,
int gics_supported,
unsigned int max_cpus)
{
/* Convert host/max/nosel to GIC version number */
switch (gic_version) {
case VIRT_GIC_VERSION_HOST:
if (!kvm_enabled()) {
error_report("gic-version=host requires KVM");
exit(1);
}
/* For KVM, gic-version=host means gic-version=max */
return finalize_gic_version_do(accel_name, VIRT_GIC_VERSION_MAX,
gics_supported, max_cpus);
case VIRT_GIC_VERSION_MAX:
if (gics_supported & VIRT_GIC_VERSION_4_MASK) {
gic_version = VIRT_GIC_VERSION_4;
} else if (gics_supported & VIRT_GIC_VERSION_3_MASK) {
gic_version = VIRT_GIC_VERSION_3;
} else {
gic_version = VIRT_GIC_VERSION_2;
}
break;
case VIRT_GIC_VERSION_NOSEL:
if ((gics_supported & VIRT_GIC_VERSION_2_MASK) &&
max_cpus <= GIC_NCPU) {
gic_version = VIRT_GIC_VERSION_2;
} else if (gics_supported & VIRT_GIC_VERSION_3_MASK) {
/*
* in case the host does not support v2 emulation or
* the end-user requested more than 8 VCPUs we now default
* to v3. In any case defaulting to v2 would be broken.
*/
gic_version = VIRT_GIC_VERSION_3;
} else if (max_cpus > GIC_NCPU) {
error_report("%s only supports GICv2 emulation but more than 8 "
"vcpus are requested", accel_name);
exit(1);
}
break;
case VIRT_GIC_VERSION_2:
case VIRT_GIC_VERSION_3:
case VIRT_GIC_VERSION_4:
break;
}
/* Check chosen version is effectively supported */
switch (gic_version) {
case VIRT_GIC_VERSION_2:
if (!(gics_supported & VIRT_GIC_VERSION_2_MASK)) {
error_report("%s does not support GICv2 emulation", accel_name);
exit(1);
}
break;
case VIRT_GIC_VERSION_3:
if (!(gics_supported & VIRT_GIC_VERSION_3_MASK)) {
error_report("%s does not support GICv3 emulation", accel_name);
exit(1);
}
break;
case VIRT_GIC_VERSION_4:
if (!(gics_supported & VIRT_GIC_VERSION_4_MASK)) {
error_report("%s does not support GICv4 emulation, is virtualization=on?",
accel_name);
exit(1);
}
break;
default:
error_report("logic error in finalize_gic_version");
exit(1);
break;
}
return gic_version;
}
/*
* finalize_gic_version - Determines the final gic_version
* according to the gic-version property
@ -1828,118 +1908,49 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
*/
static void finalize_gic_version(VirtMachineState *vms)
{
const char *accel_name = current_accel_name();
unsigned int max_cpus = MACHINE(vms)->smp.max_cpus;
int gics_supported = 0;
if (kvm_enabled()) {
int probe_bitmap;
/* Determine which GIC versions the current environment supports */
if (kvm_enabled() && kvm_irqchip_in_kernel()) {
int probe_bitmap = kvm_arm_vgic_probe();
if (!kvm_irqchip_in_kernel()) {
switch (vms->gic_version) {
case VIRT_GIC_VERSION_HOST:
warn_report(
"gic-version=host not relevant with kernel-irqchip=off "
"as only userspace GICv2 is supported. Using v2 ...");
return;
case VIRT_GIC_VERSION_MAX:
case VIRT_GIC_VERSION_NOSEL:
vms->gic_version = VIRT_GIC_VERSION_2;
return;
case VIRT_GIC_VERSION_2:
return;
case VIRT_GIC_VERSION_3:
error_report(
"gic-version=3 is not supported with kernel-irqchip=off");
exit(1);
case VIRT_GIC_VERSION_4:
error_report(
"gic-version=4 is not supported with kernel-irqchip=off");
exit(1);
}
}
probe_bitmap = kvm_arm_vgic_probe();
if (!probe_bitmap) {
error_report("Unable to determine GIC version supported by host");
exit(1);
}
switch (vms->gic_version) {
case VIRT_GIC_VERSION_HOST:
case VIRT_GIC_VERSION_MAX:
if (probe_bitmap & KVM_ARM_VGIC_V3) {
vms->gic_version = VIRT_GIC_VERSION_3;
} else {
vms->gic_version = VIRT_GIC_VERSION_2;
}
return;
case VIRT_GIC_VERSION_NOSEL:
if ((probe_bitmap & KVM_ARM_VGIC_V2) && max_cpus <= GIC_NCPU) {
vms->gic_version = VIRT_GIC_VERSION_2;
} else if (probe_bitmap & KVM_ARM_VGIC_V3) {
/*
* in case the host does not support v2 in-kernel emulation or
* the end-user requested more than 8 VCPUs we now default
* to v3. In any case defaulting to v2 would be broken.
*/
vms->gic_version = VIRT_GIC_VERSION_3;
} else if (max_cpus > GIC_NCPU) {
error_report("host only supports in-kernel GICv2 emulation "
"but more than 8 vcpus are requested");
exit(1);
}
break;
case VIRT_GIC_VERSION_2:
case VIRT_GIC_VERSION_3:
break;
case VIRT_GIC_VERSION_4:
error_report("gic-version=4 is not supported with KVM");
exit(1);
if (probe_bitmap & KVM_ARM_VGIC_V2) {
gics_supported |= VIRT_GIC_VERSION_2_MASK;
}
/* Check chosen version is effectively supported by the host */
if (vms->gic_version == VIRT_GIC_VERSION_2 &&
!(probe_bitmap & KVM_ARM_VGIC_V2)) {
error_report("host does not support in-kernel GICv2 emulation");
exit(1);
} else if (vms->gic_version == VIRT_GIC_VERSION_3 &&
!(probe_bitmap & KVM_ARM_VGIC_V3)) {
error_report("host does not support in-kernel GICv3 emulation");
exit(1);
if (probe_bitmap & KVM_ARM_VGIC_V3) {
gics_supported |= VIRT_GIC_VERSION_3_MASK;
}
return;
}
/* TCG mode */
switch (vms->gic_version) {
case VIRT_GIC_VERSION_NOSEL:
vms->gic_version = VIRT_GIC_VERSION_2;
break;
case VIRT_GIC_VERSION_MAX:
} else if (kvm_enabled() && !kvm_irqchip_in_kernel()) {
/* KVM w/o kernel irqchip can only deal with GICv2 */
gics_supported |= VIRT_GIC_VERSION_2_MASK;
accel_name = "KVM with kernel-irqchip=off";
} else if (tcg_enabled() || hvf_enabled() || qtest_enabled()) {
gics_supported |= VIRT_GIC_VERSION_2_MASK;
if (module_object_class_by_name("arm-gicv3")) {
/* CONFIG_ARM_GICV3_TCG was set */
gics_supported |= VIRT_GIC_VERSION_3_MASK;
if (vms->virt) {
/* GICv4 only makes sense if CPU has EL2 */
vms->gic_version = VIRT_GIC_VERSION_4;
} else {
vms->gic_version = VIRT_GIC_VERSION_3;
gics_supported |= VIRT_GIC_VERSION_4_MASK;
}
} else {
vms->gic_version = VIRT_GIC_VERSION_2;
}
break;
case VIRT_GIC_VERSION_HOST:
error_report("gic-version=host requires KVM");
} else {
error_report("Unsupported accelerator, can not determine GIC support");
exit(1);
case VIRT_GIC_VERSION_4:
if (!vms->virt) {
error_report("gic-version=4 requires virtualization enabled");
exit(1);
}
break;
case VIRT_GIC_VERSION_2:
case VIRT_GIC_VERSION_3:
break;
}
/*
* Then convert helpers like host/max to concrete GIC versions and ensure
* the desired version is supported
*/
vms->gic_version = finalize_gic_version_do(accel_name, vms->gic_version,
gics_supported, max_cpus);
}
/*

View file

@ -81,6 +81,27 @@ static void pl011_update(PL011State *s)
}
}
static bool pl011_is_fifo_enabled(PL011State *s)
{
return (s->lcr & 0x10) != 0;
}
static inline unsigned pl011_get_fifo_depth(PL011State *s)
{
/* Note: FIFO depth is expected to be power-of-2 */
return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1;
}
static inline void pl011_reset_fifo(PL011State *s)
{
s->read_count = 0;
s->read_pos = 0;
/* Reset FIFO flags */
s->flags &= ~(PL011_FLAG_RXFF | PL011_FLAG_TXFF);
s->flags |= PL011_FLAG_RXFE | PL011_FLAG_TXFE;
}
static uint64_t pl011_read(void *opaque, hwaddr offset,
unsigned size)
{
@ -94,8 +115,7 @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
c = s->read_fifo[s->read_pos];
if (s->read_count > 0) {
s->read_count--;
if (++s->read_pos == 16)
s->read_pos = 0;
s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
}
if (s->read_count == 0) {
s->flags |= PL011_FLAG_RXFE;
@ -229,8 +249,7 @@ static void pl011_write(void *opaque, hwaddr offset,
case 11: /* UARTLCR_H */
/* Reset the FIFO state on FIFO enable or disable */
if ((s->lcr ^ value) & 0x10) {
s->read_count = 0;
s->read_pos = 0;
pl011_reset_fifo(s);
}
if ((s->lcr ^ value) & 0x1) {
int break_enable = value & 0x1;
@ -273,11 +292,7 @@ static int pl011_can_receive(void *opaque)
PL011State *s = (PL011State *)opaque;
int r;
if (s->lcr & 0x10) {
r = s->read_count < 16;
} else {
r = s->read_count < 1;
}
r = s->read_count < pl011_get_fifo_depth(s);
trace_pl011_can_receive(s->lcr, s->read_count, r);
return r;
}
@ -286,15 +301,15 @@ static void pl011_put_fifo(void *opaque, uint32_t value)
{
PL011State *s = (PL011State *)opaque;
int slot;
unsigned pipe_depth;
slot = s->read_pos + s->read_count;
if (slot >= 16)
slot -= 16;
pipe_depth = pl011_get_fifo_depth(s);
slot = (s->read_pos + s->read_count) & (pipe_depth - 1);
s->read_fifo[slot] = value;
s->read_count++;
s->flags &= ~PL011_FLAG_RXFE;
trace_pl011_put_fifo(value, s->read_count);
if (!(s->lcr & 0x10) || s->read_count == 16) {
if (s->read_count == pipe_depth) {
trace_pl011_put_fifo_full();
s->flags |= PL011_FLAG_RXFF;
}
@ -346,10 +361,35 @@ static const VMStateDescription vmstate_pl011_clock = {
}
};
static int pl011_post_load(void *opaque, int version_id)
{
PL011State* s = opaque;
/* Sanity-check input state */
if (s->read_pos >= ARRAY_SIZE(s->read_fifo) ||
s->read_count > ARRAY_SIZE(s->read_fifo)) {
return -1;
}
if (!pl011_is_fifo_enabled(s) && s->read_count > 0 && s->read_pos > 0) {
/*
* Older versions of PL011 didn't ensure that the single
* character in the FIFO in FIFO-disabled mode is in
* element 0 of the array; convert to follow the current
* code's assumptions.
*/
s->read_fifo[0] = s->read_fifo[s->read_pos];
s->read_pos = 0;
}
return 0;
}
static const VMStateDescription vmstate_pl011 = {
.name = "pl011",
.version_id = 2,
.minimum_version_id = 2,
.post_load = pl011_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32(readbuff, PL011State),
VMSTATE_UINT32(flags, PL011State),
@ -359,7 +399,7 @@ static const VMStateDescription vmstate_pl011 = {
VMSTATE_UINT32(dmacr, PL011State),
VMSTATE_UINT32(int_enabled, PL011State),
VMSTATE_UINT32(int_level, PL011State),
VMSTATE_UINT32_ARRAY(read_fifo, PL011State, 16),
VMSTATE_UINT32_ARRAY(read_fifo, PL011State, PL011_FIFO_DEPTH),
VMSTATE_UINT32(ilpr, PL011State),
VMSTATE_UINT32(ibrd, PL011State),
VMSTATE_UINT32(fbrd, PL011State),
@ -396,11 +436,6 @@ static void pl011_init(Object *obj)
s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
ClockUpdate);
s->read_trigger = 1;
s->ifl = 0x12;
s->cr = 0x300;
s->flags = 0x90;
s->id = pl011_id_arm;
}
@ -412,11 +447,31 @@ static void pl011_realize(DeviceState *dev, Error **errp)
pl011_event, NULL, s, NULL, true);
}
static void pl011_reset(DeviceState *dev)
{
PL011State *s = PL011(dev);
s->lcr = 0;
s->rsr = 0;
s->dmacr = 0;
s->int_enabled = 0;
s->int_level = 0;
s->ilpr = 0;
s->ibrd = 0;
s->fbrd = 0;
s->read_trigger = 1;
s->ifl = 0x12;
s->cr = 0x300;
s->flags = 0;
pl011_reset_fifo(s);
}
static void pl011_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
dc->realize = pl011_realize;
dc->reset = pl011_reset;
dc->vmsd = &vmstate_pl011;
device_class_set_props(dc, pl011_properties);
}

View file

@ -21,6 +21,8 @@
#include "hw/irq.h"
#include "cpu.h"
#include "target/arm/cpregs.h"
#include "sysemu/tcg.h"
#include "sysemu/qtest.h"
/*
* Special case return value from hppvi_index(); must be larger than
@ -2376,6 +2378,7 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 6,
.type = ARM_CP_IO | ARM_CP_NO_RAW,
.access = PL1_RW, .accessfn = gicv3_fiq_access,
.fgt = FGT_ICC_IGRPENN_EL1,
.readfn = icc_igrpen_read,
.writefn = icc_igrpen_write,
},
@ -2384,6 +2387,7 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 7,
.type = ARM_CP_IO | ARM_CP_NO_RAW,
.access = PL1_RW, .accessfn = gicv3_irq_access,
.fgt = FGT_ICC_IGRPENN_EL1,
.readfn = icc_igrpen_read,
.writefn = icc_igrpen_write,
},
@ -2810,6 +2814,8 @@ void gicv3_init_cpuif(GICv3State *s)
* which case we'd get the wrong value.
* So instead we define the regs with no ri->opaque info, and
* get back to the GICv3CPUState from the CPUARMState.
*
* These CP regs callbacks can be called from either TCG or HVF code.
*/
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
@ -2905,6 +2911,16 @@ void gicv3_init_cpuif(GICv3State *s)
define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo);
}
}
arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
if (tcg_enabled() || qtest_enabled()) {
/*
* We can only trap EL changes with TCG. However the GIC interrupt
* state only changes on EL changes involving EL2 or EL3, so for
* the non-TCG case this is OK, as EL2 and EL3 can't exist.
*/
arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
} else {
assert(!arm_feature(&cpu->env, ARM_FEATURE_EL2));
assert(!arm_feature(&cpu->env, ARM_FEATURE_EL3));
}
}
}