76 changes: 34 additions & 42 deletions docs/system/arm/cpu-features.rst
Expand Up @@ -177,56 +177,48 @@ are named with the prefix "kvm-". KVM VCPU features may be probed,
enabled, and disabled in the same way as other CPU features. Below is
the list of KVM VCPU features and their descriptions.

kvm-no-adjvtime By default kvm-no-adjvtime is disabled. This
means that by default the virtual time
adjustment is enabled (vtime is not *not*
adjusted).

When virtual time adjustment is enabled each
time the VM transitions back to running state
the VCPU's virtual counter is updated to ensure
stopped time is not counted. This avoids time
jumps surprising guest OSes and applications,
as long as they use the virtual counter for
timekeeping. However it has the side effect of
the virtual and physical counters diverging.
All timekeeping based on the virtual counter
will appear to lag behind any timekeeping that
does not subtract VM stopped time. The guest
may resynchronize its virtual counter with
other time sources as needed.

Enable kvm-no-adjvtime to disable virtual time
adjustment, also restoring the legacy (pre-5.0)
behavior.

kvm-steal-time Since v5.2, kvm-steal-time is enabled by
default when KVM is enabled, the feature is
supported, and the guest is 64-bit.

When kvm-steal-time is enabled a 64-bit guest
can account for time its CPUs were not running
due to the host not scheduling the corresponding
VCPU threads. The accounting statistics may
influence the guest scheduler behavior and/or be
exposed to the guest userspace.
``kvm-no-adjvtime``
By default kvm-no-adjvtime is disabled. This means that by default
the virtual time adjustment is enabled (vtime is not *not* adjusted).

When virtual time adjustment is enabled each time the VM transitions
back to running state the VCPU's virtual counter is updated to
ensure stopped time is not counted. This avoids time jumps
surprising guest OSes and applications, as long as they use the
virtual counter for timekeeping. However it has the side effect of
the virtual and physical counters diverging. All timekeeping based
on the virtual counter will appear to lag behind any timekeeping
that does not subtract VM stopped time. The guest may resynchronize
its virtual counter with other time sources as needed.

Enable kvm-no-adjvtime to disable virtual time adjustment, also
restoring the legacy (pre-5.0) behavior.

``kvm-steal-time``
Since v5.2, kvm-steal-time is enabled by default when KVM is
enabled, the feature is supported, and the guest is 64-bit.

When kvm-steal-time is enabled a 64-bit guest can account for time
its CPUs were not running due to the host not scheduling the
corresponding VCPU threads. The accounting statistics may influence
the guest scheduler behavior and/or be exposed to the guest
userspace.

TCG VCPU Features
=================

TCG VCPU features are CPU features that are specific to TCG.
Below is the list of TCG VCPU features and their descriptions.

pauth-impdef When ``FEAT_Pauth`` is enabled, either the
*impdef* (Implementation Defined) algorithm
is enabled or the *architected* QARMA algorithm
is enabled. By default the impdef algorithm
is disabled, and QARMA is enabled.
``pauth-impdef``
When ``FEAT_Pauth`` is enabled, either the *impdef* (Implementation
Defined) algorithm is enabled or the *architected* QARMA algorithm
is enabled. By default the impdef algorithm is disabled, and QARMA
is enabled.

The architected QARMA algorithm has good
cryptographic properties, but can be quite slow
to emulate. The impdef algorithm used by QEMU
is non-cryptographic but significantly faster.
The architected QARMA algorithm has good cryptographic properties,
but can be quite slow to emulate. The impdef algorithm used by QEMU
is non-cryptographic but significantly faster.

SVE CPU Properties
==================
Expand Down
6 changes: 4 additions & 2 deletions hw/char/cadence_uart.c
Expand Up @@ -450,13 +450,15 @@ static MemTxResult uart_write(void *opaque, hwaddr offset,
}
break;
case R_BRGR: /* Baud rate generator */
value &= 0xffff;
if (value >= 0x01) {
s->r[offset] = value & 0xFFFF;
s->r[offset] = value;
}
break;
case R_BDIV: /* Baud rate divider */
value &= 0xff;
if (value >= 0x04) {
s->r[offset] = value & 0xFF;
s->r[offset] = value;
}
break;
default:
Expand Down
19 changes: 17 additions & 2 deletions hw/usb/imx-usb-phy.c
Expand Up @@ -13,6 +13,7 @@
#include "qemu/osdep.h"
#include "hw/usb/imx-usb-phy.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"

static const VMStateDescription vmstate_imx_usbphy = {
Expand Down Expand Up @@ -90,7 +91,15 @@ static uint64_t imx_usbphy_read(void *opaque, hwaddr offset, unsigned size)
value = s->usbphy[index - 3];
break;
default:
value = s->usbphy[index];
if (index < USBPHY_MAX) {
value = s->usbphy[index];
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Read from non-existing USB PHY register 0x%"
HWADDR_PRIx "\n",
__func__, offset);
value = 0;
}
break;
}
return (uint64_t)value;
Expand Down Expand Up @@ -168,7 +177,13 @@ static void imx_usbphy_write(void *opaque, hwaddr offset, uint64_t value,
s->usbphy[index - 3] ^= value;
break;
default:
/* Other registers are read-only */
/* Other registers are read-only or do not exist */
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Write to %s USB PHY register 0x%"
HWADDR_PRIx "\n",
__func__,
index >= USBPHY_MAX ? "non-existing" : "read-only",
offset);
break;
}
}
Expand Down
69 changes: 69 additions & 0 deletions target/arm/cpu64.c
Expand Up @@ -21,6 +21,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "cpu.h"
#include "cpregs.h"
#include "qemu/module.h"
#include "sysemu/kvm.h"
#include "sysemu/hvf.h"
Expand Down Expand Up @@ -1027,6 +1028,72 @@ static void aarch64_a64fx_initfn(Object *obj)
/* TODO: Add A64FX specific HPC extension registers */
}

static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
{ .name = "ATCR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 7, .opc2 = 0,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "ATCR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 15, .crm = 7, .opc2 = 0,
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "ATCR_EL3", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 7, .opc2 = 0,
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "ATCR_EL12", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 5, .crn = 15, .crm = 7, .opc2 = 0,
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "AVTCR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 15, .crm = 7, .opc2 = 1,
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 0,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "CPUACTLR2_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 1,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "CPUACTLR3_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 2,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
/*
* Report CPUCFR_EL1.SCU as 1, as we do not implement the DSU
* (and in particular its system registers).
*/
{ .name = "CPUCFR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 4 },
{ .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 4,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0x961563010 },
{ .name = "CPUPCR_EL3", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 1,
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "CPUPMR_EL3", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 3,
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "CPUPOR_EL3", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 2,
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "CPUPSELR_EL3", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 0,
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "CPUPWRCTLR_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "ERXPFGCDN_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 2,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "ERXPFGCTL_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 1,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "ERXPFGF_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
};

static void define_neoverse_n1_cp_reginfo(ARMCPU *cpu)
{
define_arm_cp_regs(cpu, neoverse_n1_cp_reginfo);
}

static void aarch64_neoverse_n1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
Expand Down Expand Up @@ -1094,6 +1161,8 @@ static void aarch64_neoverse_n1_initfn(Object *obj)

/* From D5.1 AArch64 PMU register summary */
cpu->isar.reset_pmcr_el0 = 0x410c3000;

define_neoverse_n1_cp_reginfo(cpu);
}

static void aarch64_host_initfn(Object *obj)
Expand Down
7 changes: 7 additions & 0 deletions target/arm/gdbstub.c
Expand Up @@ -520,11 +520,18 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
aarch64_gdb_set_fpu_reg,
34, "aarch64-fpu.xml", 0);
}
#if 0
/*
* GDB versions 9 through 12 have a bug which means they will
* crash if they see this XML from QEMU; disable it for the 8.0
* release, pending a better solution.
*/
if (isar_feature_aa64_pauth(&cpu->isar)) {
gdb_register_coprocessor(cs, aarch64_gdb_get_pauth_reg,
aarch64_gdb_set_pauth_reg,
4, "aarch64-pauth.xml", 0);
}
#endif
#endif
} else {
if (arm_feature(env, ARM_FEATURE_NEON)) {
Expand Down