Skip to content

Commit

Permalink
Merge tag 'pull-target-arm-20220509' of https://git.linaro.org/people…
Browse files Browse the repository at this point in the history
…/pmaydell/qemu-arm into staging

target-arm queue:
 * MAINTAINERS/.mailmap: update email for Leif Lindholm
 * hw/arm: add version information to sbsa-ref machine DT
 * Enable new features for -cpu max:
   FEAT_Debugv8p2, FEAT_Debugv8p4, FEAT_RAS (minimal version only),
   FEAT_IESB, FEAT_CSV2, FEAT_CSV2_2, FEAT_CSV3, FEAT_DGH
 * Emulate Cortex-A76
 * Emulate Neoverse-N1
 * Fix the virt board default NUMA topology

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmJ5AbsZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vyFEACZZ6tRVJYB6YpIzI7rho9x
# hVQIMTc4D5lmVetJnbLdLazifIy60oIOtSKV3Y3oj5DLMcsf6NITrPaFPWNRX3Nm
# mcbTCT5FGj8i7b1CkpEylLwvRQbIaoz2GnJPckdYelxxAq1uJNog3fmoG8nVtJ1F
# HfXVCVkZGQyiyr6Y2/zn3vpdp9n6/4RymN8ugizkcgIRII87DKV+DNDalw613JG4
# 5xxBOGkYzo5DZM8TgL8Ylmb5Jy9XY0EN1xpkyHFOg6gi0B3UZTxHq5SvK6NFoZLJ
# ogyhmMh6IjEfhUIDCtWG9VCoPyWpOXAFoh7D7akFVB4g2SIvBvcuGzFxCAsh5q3K
# s+9CgNX1SZpJQkT1jLjQlNzoUhh8lNc7QvhPWVrbAj3scc+1xVnS5MJsokEV21Cx
# /bp3mFwCL+Q4gjsMKx1nKSvxLv8xlxRtIilmlfj+wvpkenIfIwHYjbvItJTlAy1L
# +arx8fqImNQorxO6oMjOuAlSbNnDKup5qvwGghyu/qz/YEnGQVzN6gI324Km081L
# 1u31H/B3C2rj3qMsYMp5yOqgprXi1D5c6wfYIpLD/C4UfHgIlRiprawZPDM7fAhX
# vxhUhhj3e9OgkbC9yqd6SUR2Uk3YaQlp319LyoZa3VKSvjBTciFsMXXnIV1UitYp
# BGtz8+FypPVkYH7zQB9c7Q==
# =ey1m
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 09 May 2022 04:57:47 AM PDT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]

* tag 'pull-target-arm-20220509' of https://git.linaro.org/people/pmaydell/qemu-arm: (32 commits)
  hw/acpi/aml-build: Use existing CPU topology to build PPTT table
  hw/arm/virt: Fix CPU's default NUMA node ID
  qtest/numa-test: Correct CPU and NUMA association in aarch64_numa_cpu()
  hw/arm/virt: Consider SMP configuration in CPU topology
  qtest/numa-test: Specify CPU topology in aarch64_numa_cpu()
  qapi/machine.json: Add cluster-id
  hw/arm: add versioning to sbsa-ref machine DT
  target/arm: Define neoverse-n1
  target/arm: Define cortex-a76
  target/arm: Enable FEAT_DGH for -cpu max
  target/arm: Enable FEAT_CSV3 for -cpu max
  target/arm: Enable FEAT_CSV2_2 for -cpu max
  target/arm: Enable FEAT_CSV2 for -cpu max
  target/arm: Enable FEAT_IESB for -cpu max
  target/arm: Enable FEAT_RAS for -cpu max
  target/arm: Implement ESB instruction
  target/arm: Implement virtual SError exceptions
  target/arm: Enable SCR and HCR bits for RAS
  target/arm: Add minimal RAS registers
  target/arm: Enable FEAT_Debugv8p4 for -cpu max
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed May 9, 2022
2 parents 7e31419 + ae9141d commit b0c3c60
Show file tree
Hide file tree
Showing 25 changed files with 1,068 additions and 562 deletions.
3 changes: 2 additions & 1 deletion .mailmap
Expand Up @@ -62,7 +62,8 @@ Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
Leif Lindholm <leif@nuviainc.com> <leif.lindholm@linaro.org>
Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org>
Paul Burton <paulburton@kernel.org> <paul.burton@mips.com>
Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com>
Expand Down
2 changes: 1 addition & 1 deletion MAINTAINERS
Expand Up @@ -886,7 +886,7 @@ F: include/hw/ssi/imx_spi.h
SBSA-REF
M: Radoslaw Biernacki <rad@semihalf.com>
M: Peter Maydell <peter.maydell@linaro.org>
R: Leif Lindholm <leif@nuviainc.com>
R: Leif Lindholm <quic_llindhol@quicinc.com>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/arm/sbsa-ref.c
Expand Down
10 changes: 10 additions & 0 deletions docs/system/arm/emulation.rst
Expand Up @@ -12,8 +12,16 @@ the following architecture extensions:
- FEAT_BBM at level 2 (Translation table break-before-make levels)
- FEAT_BF16 (AArch64 BFloat16 instructions)
- FEAT_BTI (Branch Target Identification)
- FEAT_CSV2 (Cache speculation variant 2)
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
- FEAT_CSV3 (Cache speculation variant 3)
- FEAT_DGH (Data gathering hint)
- FEAT_DIT (Data Independent Timing instructions)
- FEAT_DPB (DC CVAP instruction)
- FEAT_Debugv8p2 (Debug changes for v8.2)
- FEAT_Debugv8p4 (Debug changes for v8.4)
- FEAT_DotProd (Advanced SIMD dot product instructions)
- FEAT_FCMA (Floating-point complex number instructions)
- FEAT_FHM (Floating-point half-precision multiplication instructions)
Expand All @@ -23,6 +31,7 @@ the following architecture extensions:
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
- FEAT_HPDS (Hierarchical permission disables)
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
- FEAT_IESB (Implicit error synchronization event)
- FEAT_JSCVT (JavaScript conversion instructions)
- FEAT_LOR (Limited ordering regions)
- FEAT_LPA (Large Physical Address space)
Expand All @@ -40,6 +49,7 @@ the following architecture extensions:
- FEAT_PMULL (PMULL, PMULL2 instructions)
- FEAT_PMUv3p1 (PMU Extensions v3.1)
- FEAT_PMUv3p4 (PMU Extensions v3.4)
- FEAT_RAS (Reliability, availability, and serviceability)
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
- FEAT_RNG (Random number generator)
- FEAT_SB (Speculation Barrier)
Expand Down
2 changes: 2 additions & 0 deletions docs/system/arm/virt.rst
Expand Up @@ -55,8 +55,10 @@ Supported guest CPU types:
- ``cortex-a53`` (64-bit)
- ``cortex-a57`` (64-bit)
- ``cortex-a72`` (64-bit)
- ``cortex-a76`` (64-bit)
- ``a64fx`` (64-bit)
- ``host`` (with KVM only)
- ``neoverse-n1`` (64-bit)
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)

Note that the default is ``cortex-a15``, so for an AArch64 guest you must
Expand Down
111 changes: 48 additions & 63 deletions hw/acpi/aml-build.c
Expand Up @@ -2002,86 +2002,71 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
const char *oem_id, const char *oem_table_id)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
GQueue *list = g_queue_new();
guint pptt_start = table_data->len;
guint parent_offset;
guint length, i;
int uid = 0;
int socket;
CPUArchIdList *cpus = ms->possible_cpus;
int64_t socket_id = -1, cluster_id = -1, core_id = -1;
uint32_t socket_offset = 0, cluster_offset = 0, core_offset = 0;
uint32_t pptt_start = table_data->len;
int n;
AcpiTable table = { .sig = "PPTT", .rev = 2,
.oem_id = oem_id, .oem_table_id = oem_table_id };

acpi_table_begin(&table, table_data);

for (socket = 0; socket < ms->smp.sockets; socket++) {
g_queue_push_tail(list,
GUINT_TO_POINTER(table_data->len - pptt_start));
build_processor_hierarchy_node(
table_data,
/*
* Physical package - represents the boundary
* of a physical package
*/
(1 << 0),
0, socket, NULL, 0);
}

if (mc->smp_props.clusters_supported) {
length = g_queue_get_length(list);
for (i = 0; i < length; i++) {
int cluster;

parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
for (cluster = 0; cluster < ms->smp.clusters; cluster++) {
g_queue_push_tail(list,
GUINT_TO_POINTER(table_data->len - pptt_start));
build_processor_hierarchy_node(
table_data,
(0 << 0), /* not a physical package */
parent_offset, cluster, NULL, 0);
}
/*
* This works with the assumption that cpus[n].props.*_id has been
* sorted from top to down levels in mc->possible_cpu_arch_ids().
* Otherwise, the unexpected and duplicated containers will be
* created.
*/
for (n = 0; n < cpus->len; n++) {
if (cpus->cpus[n].props.socket_id != socket_id) {
assert(cpus->cpus[n].props.socket_id > socket_id);
socket_id = cpus->cpus[n].props.socket_id;
cluster_id = -1;
core_id = -1;
socket_offset = table_data->len - pptt_start;
build_processor_hierarchy_node(table_data,
(1 << 0), /* Physical package */
0, socket_id, NULL, 0);
}
}

length = g_queue_get_length(list);
for (i = 0; i < length; i++) {
int core;

parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
for (core = 0; core < ms->smp.cores; core++) {
if (ms->smp.threads > 1) {
g_queue_push_tail(list,
GUINT_TO_POINTER(table_data->len - pptt_start));
build_processor_hierarchy_node(
table_data,
(0 << 0), /* not a physical package */
parent_offset, core, NULL, 0);
} else {
build_processor_hierarchy_node(
table_data,
(1 << 1) | /* ACPI Processor ID valid */
(1 << 3), /* Node is a Leaf */
parent_offset, uid++, NULL, 0);
if (mc->smp_props.clusters_supported) {
if (cpus->cpus[n].props.cluster_id != cluster_id) {
assert(cpus->cpus[n].props.cluster_id > cluster_id);
cluster_id = cpus->cpus[n].props.cluster_id;
core_id = -1;
cluster_offset = table_data->len - pptt_start;
build_processor_hierarchy_node(table_data,
(0 << 0), /* Not a physical package */
socket_offset, cluster_id, NULL, 0);
}
} else {
cluster_offset = socket_offset;
}
}

length = g_queue_get_length(list);
for (i = 0; i < length; i++) {
int thread;
if (ms->smp.threads == 1) {
build_processor_hierarchy_node(table_data,
(1 << 1) | /* ACPI Processor ID valid */
(1 << 3), /* Node is a Leaf */
cluster_offset, n, NULL, 0);
} else {
if (cpus->cpus[n].props.core_id != core_id) {
assert(cpus->cpus[n].props.core_id > core_id);
core_id = cpus->cpus[n].props.core_id;
core_offset = table_data->len - pptt_start;
build_processor_hierarchy_node(table_data,
(0 << 0), /* Not a physical package */
cluster_offset, core_id, NULL, 0);
}

parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
for (thread = 0; thread < ms->smp.threads; thread++) {
build_processor_hierarchy_node(
table_data,
build_processor_hierarchy_node(table_data,
(1 << 1) | /* ACPI Processor ID valid */
(1 << 2) | /* Processor is a Thread */
(1 << 3), /* Node is a Leaf */
parent_offset, uid++, NULL, 0);
core_offset, n, NULL, 0);
}
}

g_queue_free(list);
acpi_table_end(linker, &table);
}

Expand Down
16 changes: 16 additions & 0 deletions hw/arm/sbsa-ref.c
Expand Up @@ -145,6 +145,8 @@ 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"),
};

Expand Down Expand Up @@ -190,6 +192,20 @@ static void create_fdt(SBSAMachineState *sms)
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);

/*
* This versioning scheme is for informing platform fw only. It is neither:
* - A QEMU versioned machine type; a given version of QEMU will emulate
* a given version of the platform.
* - A reflection of level of SBSA (now SystemReady SR) support provided.
*
* machine-version-major: updated when changes breaking fw compatibility
* are introduced.
* machine-version-minor: updated when features are added that don't break
* fw compatibility.
*/
qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 0);

if (ms->numa_state->have_numa_distance) {
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
uint32_t *matrix = g_malloc0(size);
Expand Down
21 changes: 19 additions & 2 deletions hw/arm/virt.c
Expand Up @@ -202,7 +202,9 @@ static const char *valid_cpus[] = {
ARM_CPU_TYPE_NAME("cortex-a53"),
ARM_CPU_TYPE_NAME("cortex-a57"),
ARM_CPU_TYPE_NAME("cortex-a72"),
ARM_CPU_TYPE_NAME("cortex-a76"),
ARM_CPU_TYPE_NAME("a64fx"),
ARM_CPU_TYPE_NAME("neoverse-n1"),
ARM_CPU_TYPE_NAME("host"),
ARM_CPU_TYPE_NAME("max"),
};
Expand Down Expand Up @@ -2552,14 +2554,17 @@ virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)

static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
{
return idx % ms->numa_state->num_nodes;
int64_t socket_id = ms->possible_cpus->cpus[idx].props.socket_id;

return socket_id % ms->numa_state->num_nodes;
}

static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
{
int n;
unsigned int max_cpus = ms->smp.max_cpus;
VirtMachineState *vms = VIRT_MACHINE(ms);
MachineClass *mc = MACHINE_GET_CLASS(vms);

if (ms->possible_cpus) {
assert(ms->possible_cpus->len == max_cpus);
Expand All @@ -2573,8 +2578,20 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
ms->possible_cpus->cpus[n].type = ms->cpu_type;
ms->possible_cpus->cpus[n].arch_id =
virt_cpu_mp_affinity(vms, n);

assert(!mc->smp_props.dies_supported);
ms->possible_cpus->cpus[n].props.has_socket_id = true;
ms->possible_cpus->cpus[n].props.socket_id =
n / (ms->smp.clusters * ms->smp.cores * ms->smp.threads);
ms->possible_cpus->cpus[n].props.has_cluster_id = true;
ms->possible_cpus->cpus[n].props.cluster_id =
(n / (ms->smp.cores * ms->smp.threads)) % ms->smp.clusters;
ms->possible_cpus->cpus[n].props.has_core_id = true;
ms->possible_cpus->cpus[n].props.core_id =
(n / ms->smp.threads) % ms->smp.cores;
ms->possible_cpus->cpus[n].props.has_thread_id = true;
ms->possible_cpus->cpus[n].props.thread_id = n;
ms->possible_cpus->cpus[n].props.thread_id =
n % ms->smp.threads;
}
return ms->possible_cpus;
}
Expand Down
4 changes: 4 additions & 0 deletions hw/core/machine-hmp-cmds.c
Expand Up @@ -77,6 +77,10 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
if (c->has_die_id) {
monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id);
}
if (c->has_cluster_id) {
monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n",
c->cluster_id);
}
if (c->has_core_id) {
monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id);
}
Expand Down
16 changes: 16 additions & 0 deletions hw/core/machine.c
Expand Up @@ -682,6 +682,11 @@ void machine_set_cpu_numa_node(MachineState *machine,
return;
}

if (props->has_cluster_id && !slot->props.has_cluster_id) {
error_setg(errp, "cluster-id is not supported");
return;
}

if (props->has_socket_id && !slot->props.has_socket_id) {
error_setg(errp, "socket-id is not supported");
return;
Expand All @@ -701,6 +706,11 @@ void machine_set_cpu_numa_node(MachineState *machine,
continue;
}

if (props->has_cluster_id &&
props->cluster_id != slot->props.cluster_id) {
continue;
}

if (props->has_die_id && props->die_id != slot->props.die_id) {
continue;
}
Expand Down Expand Up @@ -995,6 +1005,12 @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
}
g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id);
}
if (cpu->props.has_cluster_id) {
if (s->len) {
g_string_append_printf(s, ", ");
}
g_string_append_printf(s, "cluster-id: %"PRId64, cpu->props.cluster_id);
}
if (cpu->props.has_core_id) {
if (s->len) {
g_string_append_printf(s, ", ");
Expand Down
6 changes: 4 additions & 2 deletions qapi/machine.json
Expand Up @@ -868,10 +868,11 @@
# @node-id: NUMA node ID the CPU belongs to
# @socket-id: socket number within node/board the CPU belongs to
# @die-id: die number within socket the CPU belongs to (since 4.1)
# @core-id: core number within die the CPU belongs to
# @cluster-id: cluster number within die the CPU belongs to (since 7.1)
# @core-id: core number within cluster the CPU belongs to
# @thread-id: thread number within core the CPU belongs to
#
# Note: currently there are 5 properties that could be present
# Note: currently there are 6 properties that could be present
# but management should be prepared to pass through other
# properties with device_add command to allow for future
# interface extension. This also requires the filed names to be kept in
Expand All @@ -883,6 +884,7 @@
'data': { '*node-id': 'int',
'*socket-id': 'int',
'*die-id': 'int',
'*cluster-id': 'int',
'*core-id': 'int',
'*thread-id': 'int'
}
Expand Down
16 changes: 10 additions & 6 deletions target/arm/a32.decode
Expand Up @@ -187,13 +187,17 @@ SMULTT .... 0001 0110 .... 0000 .... 1110 .... @rd0mn

{
{
YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
WFE ---- 0011 0010 0000 1111 ---- 0000 0010
WFI ---- 0011 0010 0000 1111 ---- 0000 0011
[
YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
WFE ---- 0011 0010 0000 1111 ---- 0000 0010
WFI ---- 0011 0010 0000 1111 ---- 0000 0011

# TODO: Implement SEV, SEVL; may help SMP performance.
# SEV ---- 0011 0010 0000 1111 ---- 0000 0100
# SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
# TODO: Implement SEV, SEVL; may help SMP performance.
# SEV ---- 0011 0010 0000 1111 ---- 0000 0100
# SEVL ---- 0011 0010 0000 1111 ---- 0000 0101

ESB ---- 0011 0010 0000 1111 ---- 0001 0000
]

# The canonical nop ends in 00000000, but the whole of the
# rest of the space executes as nop if otherwise unsupported.
Expand Down
11 changes: 11 additions & 0 deletions target/arm/cpregs.h
Expand Up @@ -102,6 +102,17 @@ enum {
ARM_CP_SVE = 1 << 14,
/* Flag: Do not expose in gdb sysreg xml. */
ARM_CP_NO_GDB = 1 << 15,
/*
* Flags: If EL3 but not EL2...
* - UNDEF: discard the cpreg,
* - KEEP: retain the cpreg as is,
* - C_NZ: set const on the cpreg, but retain resetvalue,
* - else: set const on the cpreg, zero resetvalue, aka RES0.
* See rule RJFFP in section D1.1.3 of DDI0487H.a.
*/
ARM_CP_EL3_NO_EL2_UNDEF = 1 << 16,
ARM_CP_EL3_NO_EL2_KEEP = 1 << 17,
ARM_CP_EL3_NO_EL2_C_NZ = 1 << 18,
};

/*
Expand Down

0 comments on commit b0c3c60

Please sign in to comment.