1
Arm pullreq for the 2.12 codefreeze...
1
Big pullreq this week, though none of the new features are
2
particularly earthshaking. Most of the bulk is from code cleanup
3
patches from me or rth.
2
4
3
thanks
5
thanks
4
-- PMM
6
-- PMM
5
7
6
The following changes since commit b39b61e410022f96ceb53d4381d25cba5126ac44:
8
The following changes since commit b651b80822fa8cb66ca30087ac7fbc75507ae5d2:
7
9
8
memory: fix flatview_access_valid RCU read lock/unlock imbalance (2018-03-09 15:55:20 +0000)
10
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.0-pull-request' into staging (2020-02-20 17:35:42 +0000)
9
11
10
are available in the Git repository at:
12
are available in the Git repository at:
11
13
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180309
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200221
13
15
14
for you to fetch changes up to 076a0fc32a73a9b960e0f73f04a531bc1bd94308:
16
for you to fetch changes up to 270a679b3f950d7c4c600f324aab8bff292d0971:
15
17
16
MAINTAINERS: Add entries for SD (SDHCI, SDBus, SDCard) (2018-03-09 17:09:45 +0000)
18
target/arm: Add missing checks for fpsp_v2 (2020-02-21 12:54:25 +0000)
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
target-arm queue:
21
target-arm queue:
20
* i.MX: Add i.MX7 SOC implementation and i.MX7 Sabre board
22
* aspeed/scu: Implement chip ID register
21
* Report the correct core count in A53 L2CTLR on the ZynqMP board
23
* hw/misc/iotkit-secctl: Fix writing to 'PPC Interrupt Clear' register
22
* linux-user: preliminary SVE support work (signal handling)
24
* mainstone: Make providing flash images non-mandatory
23
* hw/arm/boot: fix memory leak in case of error loading ELF file
25
* z2: Make providing flash images non-mandatory
24
* hw/arm/boot: avoid reading off end of buffer if passed very
26
* Fix failures to flush SVE high bits after AdvSIMD INS/ZIP/UZP/TRN/TBL/TBX/EXT
25
small image file
27
* Minor performance improvement: spend less time recalculating hflags values
26
* hw/arm: Use more CONFIG switches for the object files
28
* Code cleanup to isar_feature function tests
27
* target/arm: Add "-cpu max" support
29
* Implement ARMv8.1-PMU and ARMv8.4-PMU extensions
28
* hw/arm/virt: Support -machine gic-version=max
30
* Bugfix: correct handling of PMCR_EL0.LC bit
29
* hw/sd: improve debug tracing
31
* Bugfix: correct definition of PMCRDP
30
* hw/sd: sdcard: Add the Tuning Command (CMD 19)
32
* Correctly implement ACTLR2, HACTLR2
31
* MAINTAINERS: add Philippe as odd-fixes maintainer for SD
33
* allwinner: Wire up USB ports
34
* Vectorize emulation of USHL, SSHL, PMUL*
35
* xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd
36
* sh4: Fix PCI ISA IO memory subregion
37
* Code cleanup to use more isar_feature tests and fewer ARM_FEATURE_* tests
32
38
33
----------------------------------------------------------------
39
----------------------------------------------------------------
34
Alistair Francis (2):
40
Francisco Iglesias (1):
35
target/arm: Add a core count property
41
xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd
36
hw/arm: Set the core count for Xilinx's ZynqMP
37
42
38
Andrey Smirnov (3):
43
Guenter Roeck (6):
39
pci: Add support for Designware IP block
44
mainstone: Make providing flash images non-mandatory
40
i.MX: Add i.MX7 SOC implementation.
45
z2: Make providing flash images non-mandatory
41
Implement support for i.MX7 Sabre board
46
hw: usb: hcd-ohci: Move OHCISysBusState and TYPE_SYSBUS_OHCI to include file
47
hcd-ehci: Introduce "companion-enable" sysbus property
48
arm: allwinner: Wire up USB ports
49
sh4: Fix PCI ISA IO memory subregion
42
50
43
Marc-André Lureau (2):
51
Joel Stanley (2):
44
arm: fix load ELF error leak
52
aspeed/scu: Create separate write callbacks
45
arm: avoid heap-buffer-overflow in load_aarch64_image
53
aspeed/scu: Implement chip ID register
46
54
47
Peter Maydell (6):
55
Peter Maydell (21):
48
target/arm: Query host CPU features on-demand at instance init
56
target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers
49
target/arm: Move definition of 'host' cpu type into cpu.c
57
target/arm: Check aa32_pan in take_aarch32_exception(), not aa64_pan
50
target/arm: Add "-cpu max" support
58
target/arm: Add isar_feature_any_fp16 and document naming/usage conventions
51
target/arm: Make 'any' CPU just an alias for 'max'
59
target/arm: Define and use any_predinv isar_feature test
52
hw/arm/virt: Add "max" to the list of CPU types "virt" supports
60
target/arm: Factor out PMU register definitions
53
hw/arm/virt: Support -machine gic-version=max
61
target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1
62
target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field
63
target/arm: Define an aa32_pmu_8_1 isar feature test function
64
target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
65
target/arm: Stop assuming DBGDIDR always exists
66
target/arm: Move DBGDIDR into ARMISARegisters
67
target/arm: Read debug-related ID registers from KVM
68
target/arm: Implement ARMv8.1-PMU extension
69
target/arm: Implement ARMv8.4-PMU extension
70
target/arm: Provide ARMv8.4-PMU in '-cpu max'
71
target/arm: Correct definition of PMCRDP
72
target/arm: Correct handling of PMCR_EL0.LC bit
73
target/arm: Test correct register in aa32_pan and aa32_ats1e1 checks
74
target/arm: Use isar_feature function for testing AA32HPD feature
75
target/arm: Use FIELD_EX32 for testing 32-bit fields
76
target/arm: Correctly implement ACTLR2, HACTLR2
54
77
55
Philippe Mathieu-Daudé (6):
78
Philippe Mathieu-Daudé (1):
56
sdcard: Do not trace CMD55, except when we already expect an ACMD
79
hw/misc/iotkit-secctl: Fix writing to 'PPC Interrupt Clear' register
57
sdcard: Display command name when tracing CMD/ACMD
58
sdcard: Display which protocol is used when tracing (SD or SPI)
59
sdcard: Add the Tuning Command (CMD19)
60
sdhci: Fix a typo in comment
61
MAINTAINERS: Add entries for SD (SDHCI, SDBus, SDCard)
62
80
63
Richard Henderson (5):
81
Richard Henderson (21):
64
linux-user: Implement aarch64 PR_SVE_SET/GET_VL
82
target/arm: Flush high bits of sve register after AdvSIMD EXT
65
aarch64-linux-user: Split out helpers for guest signal handling
83
target/arm: Flush high bits of sve register after AdvSIMD TBL/TBX
66
aarch64-linux-user: Remove struct target_aux_context
84
target/arm: Flush high bits of sve register after AdvSIMD ZIP/UZP/TRN
67
aarch64-linux-user: Add support for EXTRA signal frame records
85
target/arm: Flush high bits of sve register after AdvSIMD INS
68
aarch64-linux-user: Add support for SVE signal frame records
86
target/arm: Use bit 55 explicitly for pauth
87
target/arm: Fix select for aa64_va_parameters_both
88
target/arm: Remove ttbr1_valid check from get_phys_addr_lpae
89
target/arm: Split out aa64_va_parameter_tbi, aa64_va_parameter_tbid
90
target/arm: Vectorize USHL and SSHL
91
target/arm: Convert PMUL.8 to gvec
92
target/arm: Convert PMULL.64 to gvec
93
target/arm: Convert PMULL.8 to gvec
94
target/arm: Rename isar_feature_aa32_simd_r32
95
target/arm: Use isar_feature_aa32_simd_r32 more places
96
target/arm: Set MVFR0.FPSP for ARMv5 cpus
97
target/arm: Add isar_feature_aa32_simd_r16
98
target/arm: Rename isar_feature_aa32_fpdp_v2
99
target/arm: Add isar_feature_aa32_{fpsp_v2, fpsp_v3, fpdp_v3}
100
target/arm: Perform fpdp_v2 check first
101
target/arm: Replace ARM_FEATURE_VFP3 checks with fp{sp, dp}_v3
102
target/arm: Add missing checks for fpsp_v2
69
103
70
Thomas Huth (1):
104
hw/usb/hcd-ohci.h | 16 ++
71
hw/arm: Use more CONFIG switches for the object files
105
include/hw/arm/allwinner-a10.h | 6 +
106
target/arm/cpu.h | 173 ++++++++++++---
107
target/arm/helper-sve.h | 2 +
108
target/arm/helper.h | 21 +-
109
target/arm/internals.h | 47 +++-
110
target/arm/translate.h | 6 +
111
hw/arm/allwinner-a10.c | 43 ++++
112
hw/arm/mainstone.c | 11 +-
113
hw/arm/z2.c | 6 -
114
hw/intc/armv7m_nvic.c | 30 +--
115
hw/misc/aspeed_scu.c | 93 ++++++--
116
hw/misc/iotkit-secctl.c | 2 +-
117
hw/sh4/sh_pci.c | 11 +-
118
hw/ssi/xilinx_spips.c | 2 +-
119
hw/usb/hcd-ehci-sysbus.c | 2 +
120
hw/usb/hcd-ohci.c | 15 --
121
linux-user/arm/signal.c | 4 +-
122
linux-user/elfload.c | 4 +-
123
target/arm/arch_dump.c | 11 +-
124
target/arm/cpu.c | 175 +++++++--------
125
target/arm/cpu64.c | 58 +++--
126
target/arm/debug_helper.c | 6 +-
127
target/arm/helper.c | 472 +++++++++++++++++++++++------------------
128
target/arm/kvm32.c | 25 +++
129
target/arm/kvm64.c | 46 ++++
130
target/arm/m_helper.c | 11 +-
131
target/arm/machine.c | 3 +-
132
target/arm/neon_helper.c | 117 ----------
133
target/arm/pauth_helper.c | 3 +-
134
target/arm/translate-a64.c | 92 ++++----
135
target/arm/translate-vfp.inc.c | 263 ++++++++++++++---------
136
target/arm/translate.c | 356 ++++++++++++++++++++++++++-----
137
target/arm/vec_helper.c | 211 ++++++++++++++++++
138
target/arm/vfp_helper.c | 2 +-
139
35 files changed, 1564 insertions(+), 781 deletions(-)
72
140
73
hw/arm/Makefile.objs | 31 +-
74
hw/pci-host/Makefile.objs | 2 +
75
hw/sd/Makefile.objs | 2 +-
76
hw/sd/sdmmc-internal.h | 24 ++
77
include/hw/arm/fsl-imx7.h | 222 +++++++++++
78
include/hw/pci-host/designware.h | 102 +++++
79
include/hw/pci/pci_ids.h | 2 +
80
linux-user/aarch64/target_syscall.h | 3 +
81
target/arm/cpu-qom.h | 2 +
82
target/arm/cpu.h | 11 +
83
target/arm/kvm_arm.h | 35 +-
84
hw/arm/boot.c | 4 +-
85
hw/arm/fsl-imx7.c | 582 ++++++++++++++++++++++++++++
86
hw/arm/mcimx7d-sabre.c | 90 +++++
87
hw/arm/virt.c | 30 +-
88
hw/arm/xlnx-zynqmp.c | 2 +
89
hw/pci-host/designware.c | 754 ++++++++++++++++++++++++++++++++++++
90
hw/sd/sd.c | 55 ++-
91
hw/sd/sdhci.c | 4 +-
92
hw/sd/sdmmc-internal.c | 72 ++++
93
linux-user/signal.c | 415 ++++++++++++++++----
94
linux-user/syscall.c | 27 ++
95
target/arm/cpu.c | 103 ++++-
96
target/arm/cpu64.c | 113 ++++--
97
target/arm/kvm.c | 53 +--
98
target/arm/kvm32.c | 8 +-
99
target/arm/kvm64.c | 8 +-
100
MAINTAINERS | 8 +
101
default-configs/arm-softmmu.mak | 9 +
102
hw/sd/trace-events | 8 +-
103
30 files changed, 2583 insertions(+), 198 deletions(-)
104
create mode 100644 include/hw/arm/fsl-imx7.h
105
create mode 100644 include/hw/pci-host/designware.h
106
create mode 100644 hw/arm/fsl-imx7.c
107
create mode 100644 hw/arm/mcimx7d-sabre.c
108
create mode 100644 hw/pci-host/designware.c
109
create mode 100644 hw/sd/sdmmc-internal.c
110
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
Implement code needed to set up emulation of MCIMX7SABRE board from
3
This splits the common write callback into separate ast2400 and ast2500
4
NXP. For more info about the HW see:
4
implementations. This makes it clearer when implementing differing
5
behaviour.
5
6
6
https://www.nxp.com/support/developer-resources/hardware-development-tools/sabre-development-system/sabre-board-for-smart-devices-based-on-the-i.mx-7dual-applications-processors:MCIMX7SABRE
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
8
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Cc: Jason Wang <jasowang@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200121013302.43839-2-joel@jms.id.au
11
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
12
Cc: Michael S. Tsirkin <mst@redhat.com>
13
Cc: qemu-devel@nongnu.org
14
Cc: qemu-arm@nongnu.org
15
Cc: yurovsky@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
13
---
20
hw/arm/Makefile.objs | 2 +-
14
hw/misc/aspeed_scu.c | 80 +++++++++++++++++++++++++++++++-------------
21
hw/arm/mcimx7d-sabre.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 57 insertions(+), 23 deletions(-)
22
2 files changed, 91 insertions(+), 1 deletion(-)
23
create mode 100644 hw/arm/mcimx7d-sabre.c
24
16
25
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
17
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
26
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/Makefile.objs
19
--- a/hw/misc/aspeed_scu.c
28
+++ b/hw/arm/Makefile.objs
20
+++ b/hw/misc/aspeed_scu.c
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2.o
21
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
30
obj-$(CONFIG_MPS2) += mps2-tz.o
22
return s->regs[reg];
31
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
23
}
32
obj-$(CONFIG_IOTKIT) += iotkit.o
24
33
-obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
25
-static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
34
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
26
- unsigned size)
35
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
27
+static void aspeed_ast2400_scu_write(void *opaque, hwaddr offset,
36
new file mode 100644
28
+ uint64_t data, unsigned size)
37
index XXXXXXX..XXXXXXX
29
+{
38
--- /dev/null
30
+ AspeedSCUState *s = ASPEED_SCU(opaque);
39
+++ b/hw/arm/mcimx7d-sabre.c
31
+ int reg = TO_REG(offset);
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * Copyright (c) 2018, Impinj, Inc.
43
+ *
44
+ * MCIMX7D_SABRE Board System emulation.
45
+ *
46
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
47
+ *
48
+ * This code is licensed under the GPL, version 2 or later.
49
+ * See the file `COPYING' in the top level directory.
50
+ *
51
+ * It (partially) emulates a mcimx7d_sabre board, with a Freescale
52
+ * i.MX7 SoC
53
+ */
54
+
32
+
55
+#include "qemu/osdep.h"
33
+ if (reg >= ASPEED_SCU_NR_REGS) {
56
+#include "qapi/error.h"
34
+ qemu_log_mask(LOG_GUEST_ERROR,
57
+#include "qemu-common.h"
35
+ "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
58
+#include "hw/arm/fsl-imx7.h"
36
+ __func__, offset);
59
+#include "hw/boards.h"
37
+ return;
60
+#include "sysemu/sysemu.h"
61
+#include "sysemu/device_tree.h"
62
+#include "qemu/error-report.h"
63
+#include "sysemu/qtest.h"
64
+#include "net/net.h"
65
+
66
+typedef struct {
67
+ FslIMX7State soc;
68
+ MemoryRegion ram;
69
+} MCIMX7Sabre;
70
+
71
+static void mcimx7d_sabre_init(MachineState *machine)
72
+{
73
+ static struct arm_boot_info boot_info;
74
+ MCIMX7Sabre *s = g_new0(MCIMX7Sabre, 1);
75
+ Object *soc;
76
+ int i;
77
+
78
+ if (machine->ram_size > FSL_IMX7_MMDC_SIZE) {
79
+ error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
80
+ machine->ram_size, FSL_IMX7_MMDC_SIZE);
81
+ exit(1);
82
+ }
38
+ }
83
+
39
+
84
+ boot_info = (struct arm_boot_info) {
40
+ if (reg > PROT_KEY && reg < CPU2_BASE_SEG1 &&
85
+ .loader_start = FSL_IMX7_MMDC_ADDR,
41
+ !s->regs[PROT_KEY]) {
86
+ .board_id = -1,
42
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
87
+ .ram_size = machine->ram_size,
88
+ .kernel_filename = machine->kernel_filename,
89
+ .kernel_cmdline = machine->kernel_cmdline,
90
+ .initrd_filename = machine->initrd_filename,
91
+ .nb_cpus = smp_cpus,
92
+ };
93
+
94
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX7);
95
+ soc = OBJECT(&s->soc);
96
+ object_property_add_child(OBJECT(machine), "soc", soc, &error_fatal);
97
+ object_property_set_bool(soc, true, "realized", &error_fatal);
98
+
99
+ memory_region_allocate_system_memory(&s->ram, NULL, "mcimx7d-sabre.ram",
100
+ machine->ram_size);
101
+ memory_region_add_subregion(get_system_memory(),
102
+ FSL_IMX7_MMDC_ADDR, &s->ram);
103
+
104
+ for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
105
+ BusState *bus;
106
+ DeviceState *carddev;
107
+ DriveInfo *di;
108
+ BlockBackend *blk;
109
+
110
+ di = drive_get_next(IF_SD);
111
+ blk = di ? blk_by_legacy_dinfo(di) : NULL;
112
+ bus = qdev_get_child_bus(DEVICE(&s->soc.usdhc[i]), "sd-bus");
113
+ carddev = qdev_create(bus, TYPE_SD_CARD);
114
+ qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
115
+ object_property_set_bool(OBJECT(carddev), true,
116
+ "realized", &error_fatal);
117
+ }
43
+ }
118
+
44
+
119
+ if (!qtest_enabled()) {
45
+ trace_aspeed_scu_write(offset, size, data);
120
+ arm_load_kernel(&s->soc.cpu[0], &boot_info);
46
+
47
+ switch (reg) {
48
+ case PROT_KEY:
49
+ s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
50
+ return;
51
+ case SILICON_REV:
52
+ case FREQ_CNTR_EVAL:
53
+ case VGA_SCRATCH1 ... VGA_SCRATCH8:
54
+ case RNG_DATA:
55
+ case FREE_CNTR4:
56
+ case FREE_CNTR4_EXT:
57
+ qemu_log_mask(LOG_GUEST_ERROR,
58
+ "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
59
+ __func__, offset);
60
+ return;
121
+ }
61
+ }
62
+
63
+ s->regs[reg] = data;
122
+}
64
+}
123
+
65
+
124
+static void mcimx7d_sabre_machine_init(MachineClass *mc)
66
+static void aspeed_ast2500_scu_write(void *opaque, hwaddr offset,
125
+{
67
+ uint64_t data, unsigned size)
126
+ mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex A7)";
68
{
127
+ mc->init = mcimx7d_sabre_init;
69
AspeedSCUState *s = ASPEED_SCU(opaque);
128
+ mc->max_cpus = FSL_IMX7_NUM_CPUS;
70
int reg = TO_REG(offset);
129
+}
71
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
130
+DEFINE_MACHINE("mcimx7d-sabre", mcimx7d_sabre_machine_init)
72
case PROT_KEY:
73
s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
74
return;
75
- case CLK_SEL:
76
- s->regs[reg] = data;
77
- break;
78
case HW_STRAP1:
79
- if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
80
- s->regs[HW_STRAP1] |= data;
81
- return;
82
- }
83
- /* Jump to assignment below */
84
- break;
85
+ s->regs[HW_STRAP1] |= data;
86
+ return;
87
case SILICON_REV:
88
- if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
89
- s->regs[HW_STRAP1] &= ~data;
90
- } else {
91
- qemu_log_mask(LOG_GUEST_ERROR,
92
- "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
93
- __func__, offset);
94
- }
95
- /* Avoid assignment below, we've handled everything */
96
+ s->regs[HW_STRAP1] &= ~data;
97
return;
98
case FREQ_CNTR_EVAL:
99
case VGA_SCRATCH1 ... VGA_SCRATCH8:
100
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
101
s->regs[reg] = data;
102
}
103
104
-static const MemoryRegionOps aspeed_scu_ops = {
105
+static const MemoryRegionOps aspeed_ast2400_scu_ops = {
106
.read = aspeed_scu_read,
107
- .write = aspeed_scu_write,
108
+ .write = aspeed_ast2400_scu_write,
109
+ .endianness = DEVICE_LITTLE_ENDIAN,
110
+ .valid.min_access_size = 4,
111
+ .valid.max_access_size = 4,
112
+ .valid.unaligned = false,
113
+};
114
+
115
+static const MemoryRegionOps aspeed_ast2500_scu_ops = {
116
+ .read = aspeed_scu_read,
117
+ .write = aspeed_ast2500_scu_write,
118
.endianness = DEVICE_LITTLE_ENDIAN,
119
.valid.min_access_size = 4,
120
.valid.max_access_size = 4,
121
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data)
122
asc->calc_hpll = aspeed_2400_scu_calc_hpll;
123
asc->apb_divider = 2;
124
asc->nr_regs = ASPEED_SCU_NR_REGS;
125
- asc->ops = &aspeed_scu_ops;
126
+ asc->ops = &aspeed_ast2400_scu_ops;
127
}
128
129
static const TypeInfo aspeed_2400_scu_info = {
130
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data)
131
asc->calc_hpll = aspeed_2500_scu_calc_hpll;
132
asc->apb_divider = 4;
133
asc->nr_regs = ASPEED_SCU_NR_REGS;
134
- asc->ops = &aspeed_scu_ops;
135
+ asc->ops = &aspeed_ast2500_scu_ops;
136
}
137
138
static const TypeInfo aspeed_2500_scu_info = {
131
--
139
--
132
2.16.2
140
2.20.1
133
141
134
142
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
This returns a fixed but non-zero value for the chip id.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20200121013302.43839-3-joel@jms.id.au
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/aspeed_scu.c | 13 +++++++++++++
13
1 file changed, 13 insertions(+)
14
15
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_scu.c
18
+++ b/hw/misc/aspeed_scu.c
19
@@ -XXX,XX +XXX,XX @@
20
#define CPU2_BASE_SEG4 TO_REG(0x110)
21
#define CPU2_BASE_SEG5 TO_REG(0x114)
22
#define CPU2_CACHE_CTRL TO_REG(0x118)
23
+#define CHIP_ID0 TO_REG(0x150)
24
+#define CHIP_ID1 TO_REG(0x154)
25
#define UART_HPLL_CLK TO_REG(0x160)
26
#define PCIE_CTRL TO_REG(0x180)
27
#define BMC_MMIO_CTRL TO_REG(0x184)
28
@@ -XXX,XX +XXX,XX @@
29
#define AST2600_HW_STRAP2_PROT TO_REG(0x518)
30
#define AST2600_RNG_CTRL TO_REG(0x524)
31
#define AST2600_RNG_DATA TO_REG(0x540)
32
+#define AST2600_CHIP_ID0 TO_REG(0x5B0)
33
+#define AST2600_CHIP_ID1 TO_REG(0x5B4)
34
35
#define AST2600_CLK TO_REG(0x40)
36
37
@@ -XXX,XX +XXX,XX @@ static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
38
[CPU2_BASE_SEG1] = 0x80000000U,
39
[CPU2_BASE_SEG4] = 0x1E600000U,
40
[CPU2_BASE_SEG5] = 0xC0000000U,
41
+ [CHIP_ID0] = 0x1234ABCDU,
42
+ [CHIP_ID1] = 0x88884444U,
43
[UART_HPLL_CLK] = 0x00001903U,
44
[PCIE_CTRL] = 0x0000007BU,
45
[BMC_DEV_ID] = 0x00002402U
46
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2500_scu_write(void *opaque, hwaddr offset,
47
case RNG_DATA:
48
case FREE_CNTR4:
49
case FREE_CNTR4_EXT:
50
+ case CHIP_ID0:
51
+ case CHIP_ID1:
52
qemu_log_mask(LOG_GUEST_ERROR,
53
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
54
__func__, offset);
55
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
56
case AST2600_RNG_DATA:
57
case AST2600_SILICON_REV:
58
case AST2600_SILICON_REV2:
59
+ case AST2600_CHIP_ID0:
60
+ case AST2600_CHIP_ID1:
61
/* Add read only registers here */
62
qemu_log_mask(LOG_GUEST_ERROR,
63
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
64
@@ -XXX,XX +XXX,XX @@ static const uint32_t ast2600_a0_resets[ASPEED_AST2600_SCU_NR_REGS] = {
65
[AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
66
[AST2600_SDRAM_HANDSHAKE] = 0x00000040, /* SoC completed DRAM init */
67
[AST2600_HPLL_PARAM] = 0x1000405F,
68
+ [AST2600_CHIP_ID0] = 0x1234ABCD,
69
+ [AST2600_CHIP_ID1] = 0x88884444,
70
+
71
};
72
73
static void aspeed_ast2600_scu_reset(DeviceState *dev)
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
After spending months studying all the different SD Specifications
3
Fix warning reported by Clang static code analyzer:
4
from the SD Association, voluntarily add myself as maintainer
5
for the SD code.
6
4
5
CC hw/misc/iotkit-secctl.o
6
hw/misc/iotkit-secctl.c:343:9: warning: Value stored to 'value' is never read
7
value &= 0x00f000f3;
8
^ ~~~~~~~~~~
9
10
Fixes: b3717c23e1c
11
Reported-by: Clang Static Analyzer
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20200217132922.24607-1-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20180309153654.13518-9-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
16
---
12
MAINTAINERS | 8 ++++++++
17
hw/misc/iotkit-secctl.c | 2 +-
13
1 file changed, 8 insertions(+)
18
1 file changed, 1 insertion(+), 1 deletion(-)
14
19
15
diff --git a/MAINTAINERS b/MAINTAINERS
20
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
22
--- a/hw/misc/iotkit-secctl.c
18
+++ b/MAINTAINERS
23
+++ b/hw/misc/iotkit-secctl.c
19
@@ -XXX,XX +XXX,XX @@ M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
24
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
20
S: Maintained
25
qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
21
F: hw/ssi/xilinx_*
26
break;
22
27
case A_SECPPCINTCLR:
23
+SD (Secure Card)
28
- value &= 0x00f000f3;
24
+M: Philippe Mathieu-Daudé <f4bug@amsat.org>
29
+ s->secppcintstat &= ~(value & 0x00f000f3);
25
+S: Odd Fixes
30
foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
26
+F: include/hw/sd/sd*
31
break;
27
+F: hw/sd/core.c
32
case A_SECPPCINTEN:
28
+F: hw/sd/sd*
29
+F: tests/sd*
30
+
31
USB
32
M: Gerd Hoffmann <kraxel@redhat.com>
33
S: Maintained
34
--
33
--
35
2.16.2
34
2.20.1
36
35
37
36
diff view generated by jsdifflib
New patch
1
From: Guenter Roeck <linux@roeck-us.net>
1
2
3
Up to now, the mainstone machine only boots if two flash images are
4
provided. This is not really necessary; the machine can boot from initrd
5
or from SD without it. At the same time, having to provide dummy flash
6
images is a nuisance and does not add any real value. Make it optional.
7
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20200217210824.18513-1-linux@roeck-us.net
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/mainstone.c | 11 +----------
14
1 file changed, 1 insertion(+), 10 deletions(-)
15
16
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mainstone.c
19
+++ b/hw/arm/mainstone.c
20
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
21
/* There are two 32MiB flash devices on the board */
22
for (i = 0; i < 2; i ++) {
23
dinfo = drive_get(IF_PFLASH, 0, i);
24
- if (!dinfo) {
25
- if (qtest_enabled()) {
26
- break;
27
- }
28
- error_report("Two flash images must be given with the "
29
- "'pflash' parameter");
30
- exit(1);
31
- }
32
-
33
if (!pflash_cfi01_register(mainstone_flash_base[i],
34
i ? "mainstone.flash1" : "mainstone.flash0",
35
MAINSTONE_FLASH,
36
- blk_by_legacy_dinfo(dinfo),
37
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
38
sector_len, 4, 0, 0, 0, 0, be)) {
39
error_report("Error registering flash memory");
40
exit(1);
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
New patch
1
From: Guenter Roeck <linux@roeck-us.net>
1
2
3
Up to now, the z2 machine only boots if a flash image is provided.
4
This is not really necessary; the machine can boot from initrd or from
5
SD without it. At the same time, having to provide dummy flash images
6
is a nuisance and does not add any real value. Make it optional.
7
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20200217210903.18602-1-linux@roeck-us.net
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/z2.c | 6 ------
14
1 file changed, 6 deletions(-)
15
16
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/z2.c
19
+++ b/hw/arm/z2.c
20
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
21
be = 0;
22
#endif
23
dinfo = drive_get(IF_PFLASH, 0, 0);
24
- if (!dinfo && !qtest_enabled()) {
25
- error_report("Flash image must be given with the "
26
- "'pflash' parameter");
27
- exit(1);
28
- }
29
-
30
if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
31
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
32
sector_len, 4, 0, 0, 0, 0, be)) {
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Writes to AdvSIMD registers flush the bits above 128.
4
5
Buglink: https://bugs.launchpad.net/bugs/1863247
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214194643.23317-2-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_ext(DisasContext *s, uint32_t insn)
19
tcg_temp_free_i64(tcg_resl);
20
write_vec_element(s, tcg_resh, rd, 1, MO_64);
21
tcg_temp_free_i64(tcg_resh);
22
+ clear_vec_high(s, true, rd);
23
}
24
25
/* TBL/TBX
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Writes to AdvSIMD registers flush the bits above 128.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200214194643.23317-3-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
18
tcg_temp_free_i64(tcg_resl);
19
write_vec_element(s, tcg_resh, rd, 1, MO_64);
20
tcg_temp_free_i64(tcg_resh);
21
+ clear_vec_high(s, true, rd);
22
}
23
24
/* ZIP/UZP/TRN
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
1
From: Marc-André Lureau <marcandre.lureau@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Spotted by ASAN:
3
Writes to AdvSIMD registers flush the bits above 128.
4
QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 tests/boot-serial-test
5
4
6
Direct leak of 48 byte(s) in 1 object(s) allocated from:
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
#0 0x7ff8a9b0ca38 in __interceptor_calloc (/lib64/libasan.so.4+0xdea38)
6
Message-id: 20200214194643.23317-4-richard.henderson@linaro.org
8
#1 0x7ff8a8ea7f75 in g_malloc0 ../glib/gmem.c:124
9
#2 0x55fef3d99129 in error_setv /home/elmarco/src/qemu/util/error.c:59
10
#3 0x55fef3d99738 in error_setg_internal /home/elmarco/src/qemu/util/error.c:95
11
#4 0x55fef323acb2 in load_elf_hdr /home/elmarco/src/qemu/hw/core/loader.c:393
12
#5 0x55fef2d15776 in arm_load_elf /home/elmarco/src/qemu/hw/arm/boot.c:830
13
#6 0x55fef2d16d39 in arm_load_kernel_notify /home/elmarco/src/qemu/hw/arm/boot.c:1022
14
#7 0x55fef3dc634d in notifier_list_notify /home/elmarco/src/qemu/util/notify.c:40
15
#8 0x55fef2fc3182 in qemu_run_machine_init_done_notifiers /home/elmarco/src/qemu/vl.c:2716
16
#9 0x55fef2fcbbd1 in main /home/elmarco/src/qemu/vl.c:4679
17
#10 0x7ff89dfed009 in __libc_start_main (/lib64/libc.so.6+0x21009)
18
19
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
9
---
23
hw/arm/boot.c | 1 +
10
target/arm/translate-a64.c | 1 +
24
1 file changed, 1 insertion(+)
11
1 file changed, 1 insertion(+)
25
12
26
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
27
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/boot.c
15
--- a/target/arm/translate-a64.c
29
+++ b/hw/arm/boot.c
16
+++ b/target/arm/translate-a64.c
30
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
31
18
tcg_temp_free_i64(tcg_resl);
32
load_elf_hdr(info->kernel_filename, &elf_header, &elf_is64, &err);
19
write_vec_element(s, tcg_resh, rd, 1, MO_64);
33
if (err) {
20
tcg_temp_free_i64(tcg_resh);
34
+ error_free(err);
21
+ clear_vec_high(s, true, rd);
35
return ret;
22
}
36
}
23
37
24
/*
38
--
25
--
39
2.16.2
26
2.20.1
40
27
41
28
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Writes to AdvSIMD registers flush the bits above 128.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200214194643.23317-5-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 6 ++++++
11
1 file changed, 6 insertions(+)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void handle_simd_inse(DisasContext *s, int rd, int rn,
18
write_vec_element(s, tmp, rd, dst_index, size);
19
20
tcg_temp_free_i64(tmp);
21
+
22
+ /* INS is considered a 128-bit write for SVE. */
23
+ clear_vec_high(s, true, rd);
24
}
25
26
27
@@ -XXX,XX +XXX,XX @@ static void handle_simd_insg(DisasContext *s, int rd, int rn, int imm5)
28
29
idx = extract32(imm5, 1 + size, 4 - size);
30
write_vec_element(s, cpu_reg(s, rn), rd, idx, size);
31
+
32
+ /* INS is considered a 128-bit write for SVE. */
33
+ clear_vec_high(s, true, rd);
34
}
35
36
/*
37
--
38
2.20.1
39
40
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The psuedocode in aarch64/functions/pac/auth/Auth and
4
aarch64/functions/pac/strip/Strip always uses bit 55 for
5
extfield and do not consider if the current regime has 2 ranges.
6
7
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20200216194343.21331-2-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/pauth_helper.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/pauth_helper.c
19
+++ b/target/arm/pauth_helper.c
20
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
21
22
static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
23
{
24
- uint64_t extfield = -param.select;
25
+ /* Note that bit 55 is used whether or not the regime has 2 ranges. */
26
+ uint64_t extfield = sextract64(ptr, 55, 1);
27
int bot_pac_bit = 64 - param.tsz;
28
int top_pac_bit = 64 - 8 * param.tbi;
29
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Select should always be 0 for a regime with one range.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200216194343.21331-3-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 46 +++++++++++++++++++++++----------------------
11
1 file changed, 24 insertions(+), 22 deletions(-)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
18
bool tbi, tbid, epd, hpd, using16k, using64k;
19
int select, tsz;
20
21
- /*
22
- * Bit 55 is always between the two regions, and is canonical for
23
- * determining if address tagging is enabled.
24
- */
25
- select = extract64(va, 55, 1);
26
-
27
if (!regime_has_2_ranges(mmu_idx)) {
28
+ select = 0;
29
tsz = extract32(tcr, 0, 6);
30
using64k = extract32(tcr, 14, 1);
31
using16k = extract32(tcr, 15, 1);
32
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
33
tbid = extract32(tcr, 29, 1);
34
}
35
epd = false;
36
- } else if (!select) {
37
- tsz = extract32(tcr, 0, 6);
38
- epd = extract32(tcr, 7, 1);
39
- using64k = extract32(tcr, 14, 1);
40
- using16k = extract32(tcr, 15, 1);
41
- tbi = extract64(tcr, 37, 1);
42
- hpd = extract64(tcr, 41, 1);
43
- tbid = extract64(tcr, 51, 1);
44
} else {
45
- int tg = extract32(tcr, 30, 2);
46
- using16k = tg == 1;
47
- using64k = tg == 3;
48
- tsz = extract32(tcr, 16, 6);
49
- epd = extract32(tcr, 23, 1);
50
- tbi = extract64(tcr, 38, 1);
51
- hpd = extract64(tcr, 42, 1);
52
- tbid = extract64(tcr, 52, 1);
53
+ /*
54
+ * Bit 55 is always between the two regions, and is canonical for
55
+ * determining if address tagging is enabled.
56
+ */
57
+ select = extract64(va, 55, 1);
58
+ if (!select) {
59
+ tsz = extract32(tcr, 0, 6);
60
+ epd = extract32(tcr, 7, 1);
61
+ using64k = extract32(tcr, 14, 1);
62
+ using16k = extract32(tcr, 15, 1);
63
+ tbi = extract64(tcr, 37, 1);
64
+ hpd = extract64(tcr, 41, 1);
65
+ tbid = extract64(tcr, 51, 1);
66
+ } else {
67
+ int tg = extract32(tcr, 30, 2);
68
+ using16k = tg == 1;
69
+ using64k = tg == 3;
70
+ tsz = extract32(tcr, 16, 6);
71
+ epd = extract32(tcr, 23, 1);
72
+ tbi = extract64(tcr, 38, 1);
73
+ hpd = extract64(tcr, 42, 1);
74
+ tbid = extract64(tcr, 52, 1);
75
+ }
76
}
77
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
78
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
79
--
80
2.20.1
81
82
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Now that aa64_va_parameters_both sets select based on the number
4
of ranges in the regime, the ttbr1_valid check is redundant.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200216194343.21331-4-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.c | 6 +-----
12
1 file changed, 1 insertion(+), 5 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
19
TCR *tcr = regime_tcr(env, mmu_idx);
20
int ap, ns, xn, pxn;
21
uint32_t el = regime_el(env, mmu_idx);
22
- bool ttbr1_valid;
23
uint64_t descaddrmask;
24
bool aarch64 = arm_el_is_aa64(env, el);
25
bool guarded = false;
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
27
param = aa64_va_parameters(env, address, mmu_idx,
28
access_type != MMU_INST_FETCH);
29
level = 0;
30
- ttbr1_valid = regime_has_2_ranges(mmu_idx);
31
addrsize = 64 - 8 * param.tbi;
32
inputsize = 64 - param.tsz;
33
} else {
34
param = aa32_va_parameters(env, address, mmu_idx);
35
level = 1;
36
- /* There is no TTBR1 for EL2 */
37
- ttbr1_valid = (el != 2);
38
addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
39
inputsize = addrsize - param.tsz;
40
}
41
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
42
if (inputsize < addrsize) {
43
target_ulong top_bits = sextract64(address, inputsize,
44
addrsize - inputsize);
45
- if (-top_bits != param.select || (param.select && !ttbr1_valid)) {
46
+ if (-top_bits != param.select) {
47
/* The gap between the two regions is a Translation fault */
48
fault_type = ARMFault_Translation;
49
goto do_fault;
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Split out helpers from target_setup_frame and target_restore_sigframe
3
For the purpose of rebuild_hflags_a64, we do not need to compute
4
for dealing with general registers, fpsimd registers, and the end record.
4
all of the va parameters, only tbi. Moreover, we can compute them
5
in a form that is more useful to storing in hflags.
5
6
6
When we add support for sve registers, the relative positions of
7
This eliminates the need for aa64_va_parameter_both, so fold that
7
these will change.
8
in to aa64_va_parameter. The remaining calls to aa64_va_parameter
9
are in get_phys_addr_lpae and in pauth_helper.c.
10
11
This reduces the total cpu consumption of aa64_va_parameter in a
12
kernel boot plus a kvm guest kernel boot from 3% to 0.5%.
8
13
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180303143823.27055-3-richard.henderson@linaro.org
16
Message-id: 20200216194343.21331-5-richard.henderson@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
18
---
15
linux-user/signal.c | 120 ++++++++++++++++++++++++++++++----------------------
19
target/arm/internals.h | 3 --
16
1 file changed, 69 insertions(+), 51 deletions(-)
20
target/arm/helper.c | 68 +++++++++++++++++++++++-------------------
21
2 files changed, 37 insertions(+), 34 deletions(-)
17
22
18
diff --git a/linux-user/signal.c b/linux-user/signal.c
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/signal.c
25
--- a/target/arm/internals.h
21
+++ b/linux-user/signal.c
26
+++ b/target/arm/internals.h
22
@@ -XXX,XX +XXX,XX @@ struct target_rt_sigframe {
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
23
uint32_t tramp[2];
28
unsigned tsz : 8;
24
};
29
unsigned select : 1;
25
30
bool tbi : 1;
26
-static int target_setup_sigframe(struct target_rt_sigframe *sf,
31
- bool tbid : 1;
27
- CPUARMState *env, target_sigset_t *set)
32
bool epd : 1;
28
+static void target_setup_general_frame(struct target_rt_sigframe *sf,
33
bool hpd : 1;
29
+ CPUARMState *env, target_sigset_t *set)
34
bool using16k : 1;
30
{
35
bool using64k : 1;
31
int i;
36
} ARMVAParameters;
32
- struct target_aux_context *aux =
37
33
- (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
38
-ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
34
39
- ARMMMUIdx mmu_idx);
35
- /* set up the stack frame for unwinding */
40
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
36
- __put_user(env->xregs[29], &sf->fp);
41
ARMMMUIdx mmu_idx, bool data);
37
- __put_user(env->xregs[30], &sf->lr);
42
38
+ __put_user(0, &sf->uc.tuc_flags);
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
+ __put_user(0, &sf->uc.tuc_link);
44
index XXXXXXX..XXXXXXX 100644
40
+
45
--- a/target/arm/helper.c
41
+ __put_user(target_sigaltstack_used.ss_sp, &sf->uc.tuc_stack.ss_sp);
46
+++ b/target/arm/helper.c
42
+ __put_user(sas_ss_flags(env->xregs[31]), &sf->uc.tuc_stack.ss_flags);
47
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
43
+ __put_user(target_sigaltstack_used.ss_size, &sf->uc.tuc_stack.ss_size);
48
}
44
49
#endif /* !CONFIG_USER_ONLY */
45
for (i = 0; i < 31; i++) {
50
46
__put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
51
-ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
47
@@ -XXX,XX +XXX,XX @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
52
- ARMMMUIdx mmu_idx)
48
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
53
+static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
49
__put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
54
+{
50
}
55
+ if (regime_has_2_ranges(mmu_idx)) {
56
+ return extract64(tcr, 37, 2);
57
+ } else if (mmu_idx == ARMMMUIdx_Stage2) {
58
+ return 0; /* VTCR_EL2 */
59
+ } else {
60
+ return extract32(tcr, 20, 1);
61
+ }
51
+}
62
+}
52
+
63
+
53
+static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
64
+static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
54
+ CPUARMState *env)
55
+{
65
+{
56
+ int i;
66
+ if (regime_has_2_ranges(mmu_idx)) {
57
+
67
+ return extract64(tcr, 51, 2);
58
+ __put_user(TARGET_FPSIMD_MAGIC, &fpsimd->head.magic);
68
+ } else if (mmu_idx == ARMMMUIdx_Stage2) {
59
+ __put_user(sizeof(struct target_fpsimd_context), &fpsimd->head.size);
69
+ return 0; /* VTCR_EL2 */
60
+ __put_user(vfp_get_fpsr(env), &fpsimd->fpsr);
70
+ } else {
61
+ __put_user(vfp_get_fpcr(env), &fpsimd->fpcr);
71
+ return extract32(tcr, 29, 1);
62
72
+ }
63
for (i = 0; i < 32; i++) {
64
uint64_t *q = aa64_vfp_qreg(env, i);
65
#ifdef TARGET_WORDS_BIGENDIAN
66
- __put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
67
- __put_user(q[1], &aux->fpsimd.vregs[i * 2]);
68
+ __put_user(q[0], &fpsimd->vregs[i * 2 + 1]);
69
+ __put_user(q[1], &fpsimd->vregs[i * 2]);
70
#else
71
- __put_user(q[0], &aux->fpsimd.vregs[i * 2]);
72
- __put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
73
+ __put_user(q[0], &fpsimd->vregs[i * 2]);
74
+ __put_user(q[1], &fpsimd->vregs[i * 2 + 1]);
75
#endif
76
}
77
- __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
78
- __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
79
- __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
80
- __put_user(sizeof(struct target_fpsimd_context),
81
- &aux->fpsimd.head.size);
82
-
83
- /* set the "end" magic */
84
- __put_user(0, &aux->end.magic);
85
- __put_user(0, &aux->end.size);
86
-
87
- return 0;
88
}
89
90
-static int target_restore_sigframe(CPUARMState *env,
91
- struct target_rt_sigframe *sf)
92
+static void target_setup_end_record(struct target_aarch64_ctx *end)
93
+{
94
+ __put_user(0, &end->magic);
95
+ __put_user(0, &end->size);
96
+}
73
+}
97
+
74
+
98
+static void target_restore_general_frame(CPUARMState *env,
75
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
99
+ struct target_rt_sigframe *sf)
76
+ ARMMMUIdx mmu_idx, bool data)
100
{
77
{
101
sigset_t set;
78
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
102
- int i;
79
- bool tbi, tbid, epd, hpd, using16k, using64k;
103
- struct target_aux_context *aux =
80
- int select, tsz;
104
- (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
81
+ bool epd, hpd, using16k, using64k;
105
- uint32_t magic, size, fpsr, fpcr;
82
+ int select, tsz, tbi;
106
uint64_t pstate;
83
107
+ int i;
84
if (!regime_has_2_ranges(mmu_idx)) {
108
85
select = 0;
109
target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
86
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
110
set_sigmask(&set);
87
using16k = extract32(tcr, 15, 1);
111
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
88
if (mmu_idx == ARMMMUIdx_Stage2) {
112
__get_user(env->pc, &sf->uc.tuc_mcontext.pc);
89
/* VTCR_EL2 */
113
__get_user(pstate, &sf->uc.tuc_mcontext.pstate);
90
- tbi = tbid = hpd = false;
114
pstate_write(env, pstate);
91
+ hpd = false;
115
+}
92
} else {
116
93
- tbi = extract32(tcr, 20, 1);
117
- __get_user(magic, &aux->fpsimd.head.magic);
94
hpd = extract32(tcr, 24, 1);
118
- __get_user(size, &aux->fpsimd.head.size);
95
- tbid = extract32(tcr, 29, 1);
119
+static void target_restore_fpsimd_record(CPUARMState *env,
96
}
120
+ struct target_fpsimd_context *fpsimd)
97
epd = false;
121
+{
98
} else {
122
+ uint32_t fpsr, fpcr;
99
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
123
+ int i;
100
epd = extract32(tcr, 7, 1);
124
101
using64k = extract32(tcr, 14, 1);
125
- if (magic != TARGET_FPSIMD_MAGIC
102
using16k = extract32(tcr, 15, 1);
126
- || size != sizeof(struct target_fpsimd_context)) {
103
- tbi = extract64(tcr, 37, 1);
127
- return 1;
104
hpd = extract64(tcr, 41, 1);
105
- tbid = extract64(tcr, 51, 1);
106
} else {
107
int tg = extract32(tcr, 30, 2);
108
using16k = tg == 1;
109
using64k = tg == 3;
110
tsz = extract32(tcr, 16, 6);
111
epd = extract32(tcr, 23, 1);
112
- tbi = extract64(tcr, 38, 1);
113
hpd = extract64(tcr, 42, 1);
114
- tbid = extract64(tcr, 52, 1);
115
}
116
}
117
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
118
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
119
120
+ /* Present TBI as a composite with TBID. */
121
+ tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
122
+ if (!data) {
123
+ tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
124
+ }
125
+ tbi = (tbi >> select) & 1;
126
+
127
return (ARMVAParameters) {
128
.tsz = tsz,
129
.select = select,
130
.tbi = tbi,
131
- .tbid = tbid,
132
.epd = epd,
133
.hpd = hpd,
134
.using16k = using16k,
135
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
136
};
137
}
138
139
-ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
140
- ARMMMUIdx mmu_idx, bool data)
141
-{
142
- ARMVAParameters ret = aa64_va_parameters_both(env, va, mmu_idx);
143
-
144
- /* Present TBI as a composite with TBID. */
145
- ret.tbi &= (data || !ret.tbid);
146
- return ret;
147
-}
148
-
149
#ifndef CONFIG_USER_ONLY
150
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
151
ARMMMUIdx mmu_idx)
152
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
153
{
154
uint32_t flags = rebuild_hflags_aprofile(env);
155
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
156
- ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
157
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
158
uint64_t sctlr;
159
int tbii, tbid;
160
161
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
162
163
/* Get control bits for tagged addresses. */
164
- if (regime_has_2_ranges(mmu_idx)) {
165
- ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
166
- tbid = (p1.tbi << 1) | p0.tbi;
167
- tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
168
- } else {
169
- tbid = p0.tbi;
170
- tbii = tbid & !p0.tbid;
128
- }
171
- }
129
+ __get_user(fpsr, &fpsimd->fpsr);
172
+ tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
130
+ vfp_set_fpsr(env, fpsr);
173
+ tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
131
+ __get_user(fpcr, &fpsimd->fpcr);
174
132
+ vfp_set_fpcr(env, fpcr);
175
flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
133
176
flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
134
for (i = 0; i < 32; i++) {
135
uint64_t *q = aa64_vfp_qreg(env, i);
136
#ifdef TARGET_WORDS_BIGENDIAN
137
- __get_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
138
- __get_user(q[1], &aux->fpsimd.vregs[i * 2]);
139
+ __get_user(q[0], &fpsimd->vregs[i * 2 + 1]);
140
+ __get_user(q[1], &fpsimd->vregs[i * 2]);
141
#else
142
- __get_user(q[0], &aux->fpsimd.vregs[i * 2]);
143
- __get_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
144
+ __get_user(q[0], &fpsimd->vregs[i * 2]);
145
+ __get_user(q[1], &fpsimd->vregs[i * 2 + 1]);
146
#endif
147
}
148
- __get_user(fpsr, &aux->fpsimd.fpsr);
149
- vfp_set_fpsr(env, fpsr);
150
- __get_user(fpcr, &aux->fpsimd.fpcr);
151
- vfp_set_fpcr(env, fpcr);
152
+}
153
154
+static int target_restore_sigframe(CPUARMState *env,
155
+ struct target_rt_sigframe *sf)
156
+{
157
+ struct target_aux_context *aux
158
+ = (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
159
+ uint32_t magic, size;
160
+
161
+ target_restore_general_frame(env, sf);
162
+
163
+ __get_user(magic, &aux->fpsimd.head.magic);
164
+ __get_user(size, &aux->fpsimd.head.size);
165
+ if (magic == TARGET_FPSIMD_MAGIC
166
+ && size == sizeof(struct target_fpsimd_context)) {
167
+ target_restore_fpsimd_record(env, &aux->fpsimd);
168
+ } else {
169
+ return 1;
170
+ }
171
return 0;
172
}
173
174
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
175
CPUARMState *env)
176
{
177
struct target_rt_sigframe *frame;
178
+ struct target_aux_context *aux;
179
abi_ulong frame_addr, return_addr;
180
181
frame_addr = get_sigframe(ka, env);
182
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
183
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
184
goto give_sigsegv;
185
}
186
+ aux = (struct target_aux_context *)frame->uc.tuc_mcontext.__reserved;
187
188
- __put_user(0, &frame->uc.tuc_flags);
189
- __put_user(0, &frame->uc.tuc_link);
190
+ target_setup_general_frame(frame, env, set);
191
+ target_setup_fpsimd_record(&aux->fpsimd, env);
192
+ target_setup_end_record(&aux->end);
193
194
- __put_user(target_sigaltstack_used.ss_sp,
195
- &frame->uc.tuc_stack.ss_sp);
196
- __put_user(sas_ss_flags(env->xregs[31]),
197
- &frame->uc.tuc_stack.ss_flags);
198
- __put_user(target_sigaltstack_used.ss_size,
199
- &frame->uc.tuc_stack.ss_size);
200
- target_setup_sigframe(frame, env, set);
201
if (ka->sa_flags & TARGET_SA_RESTORER) {
202
return_addr = ka->sa_restorer;
203
} else {
204
--
177
--
205
2.16.2
178
2.20.1
206
179
207
180
diff view generated by jsdifflib
New patch
1
Enforce a convention that an isar_feature function that tests a
2
32-bit ID register always has _aa32_ in its name, and one that
3
tests a 64-bit ID register always has _aa64_ in its name.
4
We already follow this except for three cases: thumb_div,
5
arm_div and jazelle, which all need _aa32_ adding.
1
6
7
(As noted in the comment, isar_feature_aa32_fp16_arith()
8
is an exception in that it currently tests ID_AA64PFR0_EL1,
9
but will switch to MVFR1 once we've properly implemented
10
FP16 for AArch32.)
11
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20200214175116.9164-2-peter.maydell@linaro.org
16
---
17
target/arm/cpu.h | 13 ++++++++++---
18
target/arm/internals.h | 2 +-
19
linux-user/elfload.c | 4 ++--
20
target/arm/cpu.c | 6 ++++--
21
target/arm/helper.c | 2 +-
22
target/arm/translate.c | 6 +++---
23
6 files changed, 21 insertions(+), 12 deletions(-)
24
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
30
/* Shared between translate-sve.c and sve_helper.c. */
31
extern const uint64_t pred_esz_masks[4];
32
33
+/*
34
+ * Naming convention for isar_feature functions:
35
+ * Functions which test 32-bit ID registers should have _aa32_ in
36
+ * their name. Functions which test 64-bit ID registers should have
37
+ * _aa64_ in their name.
38
+ */
39
+
40
/*
41
* 32-bit feature tests via id registers.
42
*/
43
-static inline bool isar_feature_thumb_div(const ARMISARegisters *id)
44
+static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
45
{
46
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
47
}
48
49
-static inline bool isar_feature_arm_div(const ARMISARegisters *id)
50
+static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
51
{
52
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
53
}
54
55
-static inline bool isar_feature_jazelle(const ARMISARegisters *id)
56
+static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
57
{
58
return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
59
}
60
diff --git a/target/arm/internals.h b/target/arm/internals.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/internals.h
63
+++ b/target/arm/internals.h
64
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
65
if ((features >> ARM_FEATURE_THUMB2) & 1) {
66
valid |= CPSR_IT;
67
}
68
- if (isar_feature_jazelle(id)) {
69
+ if (isar_feature_aa32_jazelle(id)) {
70
valid |= CPSR_J;
71
}
72
if (isar_feature_aa32_pan(id)) {
73
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/linux-user/elfload.c
76
+++ b/linux-user/elfload.c
77
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
78
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
79
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
80
GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
81
- GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
82
- GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
83
+ GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
84
+ GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
85
/* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
86
* Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
87
* ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
88
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/cpu.c
91
+++ b/target/arm/cpu.c
92
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
93
* Presence of EL2 itself is ARM_FEATURE_EL2, and of the
94
* Security Extensions is ARM_FEATURE_EL3.
95
*/
96
- assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(arm_div, cpu));
97
+ assert(!tcg_enabled() || no_aa32 ||
98
+ cpu_isar_feature(aa32_arm_div, cpu));
99
set_feature(env, ARM_FEATURE_LPAE);
100
set_feature(env, ARM_FEATURE_V7);
101
}
102
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
103
if (arm_feature(env, ARM_FEATURE_V6)) {
104
set_feature(env, ARM_FEATURE_V5);
105
if (!arm_feature(env, ARM_FEATURE_M)) {
106
- assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(jazelle, cpu));
107
+ assert(!tcg_enabled() || no_aa32 ||
108
+ cpu_isar_feature(aa32_jazelle, cpu));
109
set_feature(env, ARM_FEATURE_AUXCR);
110
}
111
}
112
diff --git a/target/arm/helper.c b/target/arm/helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/helper.c
115
+++ b/target/arm/helper.c
116
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
117
if (arm_feature(env, ARM_FEATURE_LPAE)) {
118
define_arm_cp_regs(cpu, lpae_cp_reginfo);
119
}
120
- if (cpu_isar_feature(jazelle, cpu)) {
121
+ if (cpu_isar_feature(aa32_jazelle, cpu)) {
122
define_arm_cp_regs(cpu, jazelle_regs);
123
}
124
/* Slightly awkwardly, the OMAP and StrongARM cores need all of
125
diff --git a/target/arm/translate.c b/target/arm/translate.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/translate.c
128
+++ b/target/arm/translate.c
129
@@ -XXX,XX +XXX,XX @@
130
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
131
/* currently all emulated v5 cores are also v5TE, so don't bother */
132
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
133
-#define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
134
+#define ENABLE_ARCH_5J dc_isar_feature(aa32_jazelle, s)
135
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
136
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
137
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
138
@@ -XXX,XX +XXX,XX @@ static bool op_div(DisasContext *s, arg_rrr *a, bool u)
139
TCGv_i32 t1, t2;
140
141
if (s->thumb
142
- ? !dc_isar_feature(thumb_div, s)
143
- : !dc_isar_feature(arm_div, s)) {
144
+ ? !dc_isar_feature(aa32_thumb_div, s)
145
+ : !dc_isar_feature(aa32_arm_div, s)) {
146
return false;
147
}
148
149
--
150
2.20.1
151
152
diff view generated by jsdifflib
1
Allow the virt board to support '-cpu max' in the same way
1
In take_aarch32_exception(), we know we are dealing with a CPU that
2
it already handles '-cpu host'.
2
has AArch32, so the right isar_feature test is aa32_pan, not aa64_pan.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180308130626.12393-6-peter.maydell@linaro.org
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20200214175116.9164-3-peter.maydell@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
---
7
---
9
hw/arm/virt.c | 1 +
8
target/arm/helper.c | 2 +-
10
1 file changed, 1 insertion(+)
9
1 file changed, 1 insertion(+), 1 deletion(-)
11
10
12
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/virt.c
13
--- a/target/arm/helper.c
15
+++ b/hw/arm/virt.c
14
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
15
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
17
ARM_CPU_TYPE_NAME("cortex-a53"),
16
env->elr_el[2] = env->regs[15];
18
ARM_CPU_TYPE_NAME("cortex-a57"),
17
} else {
19
ARM_CPU_TYPE_NAME("host"),
18
/* CPSR.PAN is normally preserved preserved unless... */
20
+ ARM_CPU_TYPE_NAME("max"),
19
- if (cpu_isar_feature(aa64_pan, env_archcpu(env))) {
21
};
20
+ if (cpu_isar_feature(aa32_pan, env_archcpu(env))) {
22
21
switch (new_el) {
23
static bool cpu_type_valid(const char *cpu)
22
case 3:
23
if (!arm_is_secure_below_el3(env)) {
24
--
24
--
25
2.16.2
25
2.20.1
26
26
27
27
diff view generated by jsdifflib
New patch
1
Our current usage of the isar_feature feature tests almost always
2
uses an _aa32_ test when the code path is known to be AArch32
3
specific and an _aa64_ test when the code path is known to be
4
AArch64 specific. There is just one exception: in the vfp_set_fpscr
5
helper we check aa64_fp16 to determine whether the FZ16 bit in
6
the FP(S)CR exists, but this code is also used for AArch32.
7
There are other places in future where we're likely to want
8
a general "does this feature exist for either AArch32 or
9
AArch64" check (typically where architecturally the feature exists
10
for both CPU states if it exists at all, but the CPU might be
11
AArch32-only or AArch64-only, and so only have one set of ID
12
registers).
1
13
14
Introduce a new category of isar_feature_* functions:
15
isar_feature_any_foo() should be tested when what we want to
16
know is "does this feature exist for either AArch32 or AArch64",
17
and always returns the logical OR of isar_feature_aa32_foo()
18
and isar_feature_aa64_foo().
19
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Message-id: 20200214175116.9164-4-peter.maydell@linaro.org
24
---
25
target/arm/cpu.h | 19 ++++++++++++++++++-
26
target/arm/vfp_helper.c | 2 +-
27
2 files changed, 19 insertions(+), 2 deletions(-)
28
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
33
@@ -XXX,XX +XXX,XX @@ extern const uint64_t pred_esz_masks[4];
34
* Naming convention for isar_feature functions:
35
* Functions which test 32-bit ID registers should have _aa32_ in
36
* their name. Functions which test 64-bit ID registers should have
37
- * _aa64_ in their name.
38
+ * _aa64_ in their name. These must only be used in code where we
39
+ * know for certain that the CPU has AArch32 or AArch64 respectively
40
+ * or where the correct answer for a CPU which doesn't implement that
41
+ * CPU state is "false" (eg when generating A32 or A64 code, if adding
42
+ * system registers that are specific to that CPU state, for "should
43
+ * we let this system register bit be set" tests where the 32-bit
44
+ * flavour of the register doesn't have the bit, and so on).
45
+ * Functions which simply ask "does this feature exist at all" have
46
+ * _any_ in their name, and always return the logical OR of the _aa64_
47
+ * and the _aa32_ function.
48
*/
49
50
/*
51
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
52
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
53
}
54
55
+/*
56
+ * Feature tests for "does this exist in either 32-bit or 64-bit?"
57
+ */
58
+static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
59
+{
60
+ return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
61
+}
62
+
63
/*
64
* Forward to the above feature tests given an ARMCPU pointer.
65
*/
66
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/vfp_helper.c
69
+++ b/target/arm/vfp_helper.c
70
@@ -XXX,XX +XXX,XX @@ uint32_t vfp_get_fpscr(CPUARMState *env)
71
void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
72
{
73
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
74
- if (!cpu_isar_feature(aa64_fp16, env_archcpu(env))) {
75
+ if (!cpu_isar_feature(any_fp16, env_archcpu(env))) {
76
val &= ~FPCR_FZ16;
77
}
78
79
--
80
2.20.1
81
82
diff view generated by jsdifflib
New patch
1
Instead of open-coding "ARM_FEATURE_AARCH64 ? aa64_predinv: aa32_predinv",
2
define and use an any_predinv isar_feature test function.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200214175116.9164-5-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 5 +++++
10
target/arm/helper.c | 9 +--------
11
2 files changed, 6 insertions(+), 8 deletions(-)
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
18
return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
19
}
20
21
+static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
22
+{
23
+ return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
24
+}
25
+
26
/*
27
* Forward to the above feature tests given an ARMCPU pointer.
28
*/
29
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/helper.c
32
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
34
#endif /*CONFIG_USER_ONLY*/
35
#endif
36
37
- /*
38
- * While all v8.0 cpus support aarch64, QEMU does have configurations
39
- * that do not set ID_AA64ISAR1, e.g. user-only qemu-arm -cpu max,
40
- * which will set ID_ISAR6.
41
- */
42
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
43
- ? cpu_isar_feature(aa64_predinv, cpu)
44
- : cpu_isar_feature(aa32_predinv, cpu)) {
45
+ if (cpu_isar_feature(any_predinv, cpu)) {
46
define_arm_cp_regs(cpu, predinv_reginfo);
47
}
48
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
New patch
1
1
Pull the code that defines the various PMU registers out
2
into its own function, matching the pattern we have
3
already for the debug registers.
4
5
Apart from one style fix to a multi-line comment, this
6
is purely movement of code with no changes to it.
7
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20200214175116.9164-6-peter.maydell@linaro.org
12
---
13
target/arm/helper.c | 158 +++++++++++++++++++++++---------------------
14
1 file changed, 82 insertions(+), 76 deletions(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
21
}
22
}
23
24
+static void define_pmu_regs(ARMCPU *cpu)
25
+{
26
+ /*
27
+ * v7 performance monitor control register: same implementor
28
+ * field as main ID register, and we implement four counters in
29
+ * addition to the cycle count register.
30
+ */
31
+ unsigned int i, pmcrn = 4;
32
+ ARMCPRegInfo pmcr = {
33
+ .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
34
+ .access = PL0_RW,
35
+ .type = ARM_CP_IO | ARM_CP_ALIAS,
36
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
37
+ .accessfn = pmreg_access, .writefn = pmcr_write,
38
+ .raw_writefn = raw_write,
39
+ };
40
+ ARMCPRegInfo pmcr64 = {
41
+ .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
42
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
43
+ .access = PL0_RW, .accessfn = pmreg_access,
44
+ .type = ARM_CP_IO,
45
+ .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
46
+ .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
47
+ .writefn = pmcr_write, .raw_writefn = raw_write,
48
+ };
49
+ define_one_arm_cp_reg(cpu, &pmcr);
50
+ define_one_arm_cp_reg(cpu, &pmcr64);
51
+ for (i = 0; i < pmcrn; i++) {
52
+ char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
53
+ char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
54
+ char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
55
+ char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
56
+ ARMCPRegInfo pmev_regs[] = {
57
+ { .name = pmevcntr_name, .cp = 15, .crn = 14,
58
+ .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
59
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
60
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
61
+ .accessfn = pmreg_access },
62
+ { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
63
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
64
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
65
+ .type = ARM_CP_IO,
66
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
67
+ .raw_readfn = pmevcntr_rawread,
68
+ .raw_writefn = pmevcntr_rawwrite },
69
+ { .name = pmevtyper_name, .cp = 15, .crn = 14,
70
+ .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
71
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
72
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
73
+ .accessfn = pmreg_access },
74
+ { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
75
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
76
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
77
+ .type = ARM_CP_IO,
78
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
79
+ .raw_writefn = pmevtyper_rawwrite },
80
+ REGINFO_SENTINEL
81
+ };
82
+ define_arm_cp_regs(cpu, pmev_regs);
83
+ g_free(pmevcntr_name);
84
+ g_free(pmevcntr_el0_name);
85
+ g_free(pmevtyper_name);
86
+ g_free(pmevtyper_el0_name);
87
+ }
88
+ if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
89
+ FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
90
+ ARMCPRegInfo v81_pmu_regs[] = {
91
+ { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
92
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
93
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
94
+ .resetvalue = extract64(cpu->pmceid0, 32, 32) },
95
+ { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
96
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
97
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
98
+ .resetvalue = extract64(cpu->pmceid1, 32, 32) },
99
+ REGINFO_SENTINEL
100
+ };
101
+ define_arm_cp_regs(cpu, v81_pmu_regs);
102
+ }
103
+}
104
+
105
/* We don't know until after realize whether there's a GICv3
106
* attached, and that is what registers the gicv3 sysregs.
107
* So we have to fill in the GIC fields in ID_PFR/ID_PFR1_EL1/ID_AA64PFR0_EL1
108
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
109
define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
110
}
111
if (arm_feature(env, ARM_FEATURE_V7)) {
112
- /* v7 performance monitor control register: same implementor
113
- * field as main ID register, and we implement four counters in
114
- * addition to the cycle count register.
115
- */
116
- unsigned int i, pmcrn = 4;
117
- ARMCPRegInfo pmcr = {
118
- .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
119
- .access = PL0_RW,
120
- .type = ARM_CP_IO | ARM_CP_ALIAS,
121
- .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
122
- .accessfn = pmreg_access, .writefn = pmcr_write,
123
- .raw_writefn = raw_write,
124
- };
125
- ARMCPRegInfo pmcr64 = {
126
- .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
127
- .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
128
- .access = PL0_RW, .accessfn = pmreg_access,
129
- .type = ARM_CP_IO,
130
- .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
131
- .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
132
- .writefn = pmcr_write, .raw_writefn = raw_write,
133
- };
134
- define_one_arm_cp_reg(cpu, &pmcr);
135
- define_one_arm_cp_reg(cpu, &pmcr64);
136
- for (i = 0; i < pmcrn; i++) {
137
- char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
138
- char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
139
- char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
140
- char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
141
- ARMCPRegInfo pmev_regs[] = {
142
- { .name = pmevcntr_name, .cp = 15, .crn = 14,
143
- .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
144
- .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
145
- .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
146
- .accessfn = pmreg_access },
147
- { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
148
- .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
149
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
150
- .type = ARM_CP_IO,
151
- .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
152
- .raw_readfn = pmevcntr_rawread,
153
- .raw_writefn = pmevcntr_rawwrite },
154
- { .name = pmevtyper_name, .cp = 15, .crn = 14,
155
- .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
156
- .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
157
- .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
158
- .accessfn = pmreg_access },
159
- { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
160
- .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
161
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
162
- .type = ARM_CP_IO,
163
- .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
164
- .raw_writefn = pmevtyper_rawwrite },
165
- REGINFO_SENTINEL
166
- };
167
- define_arm_cp_regs(cpu, pmev_regs);
168
- g_free(pmevcntr_name);
169
- g_free(pmevcntr_el0_name);
170
- g_free(pmevtyper_name);
171
- g_free(pmevtyper_el0_name);
172
- }
173
ARMCPRegInfo clidr = {
174
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
175
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
176
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
177
define_one_arm_cp_reg(cpu, &clidr);
178
define_arm_cp_regs(cpu, v7_cp_reginfo);
179
define_debug_regs(cpu);
180
+ define_pmu_regs(cpu);
181
} else {
182
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
183
}
184
- if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
185
- FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
186
- ARMCPRegInfo v81_pmu_regs[] = {
187
- { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
188
- .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
189
- .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
190
- .resetvalue = extract64(cpu->pmceid0, 32, 32) },
191
- { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
192
- .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
193
- .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
194
- .resetvalue = extract64(cpu->pmceid1, 32, 32) },
195
- REGINFO_SENTINEL
196
- };
197
- define_arm_cp_regs(cpu, v81_pmu_regs);
198
- }
199
if (arm_feature(env, ARM_FEATURE_V8)) {
200
/* AArch64 ID registers, which all have impdef reset values.
201
* Note that within the ID register ranges the unused slots
202
--
203
2.20.1
204
205
diff view generated by jsdifflib
New patch
1
Add FIELD() definitions for the ID_AA64DFR0_EL1 and use them
2
where we currently have hard-coded bit values.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200214175116.9164-7-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 10 ++++++++++
10
target/arm/cpu.c | 2 +-
11
target/arm/helper.c | 6 +++---
12
3 files changed, 14 insertions(+), 4 deletions(-)
13
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64MMFR2, BBM, 52, 4)
19
FIELD(ID_AA64MMFR2, EVT, 56, 4)
20
FIELD(ID_AA64MMFR2, E0PD, 60, 4)
21
22
+FIELD(ID_AA64DFR0, DEBUGVER, 0, 4)
23
+FIELD(ID_AA64DFR0, TRACEVER, 4, 4)
24
+FIELD(ID_AA64DFR0, PMUVER, 8, 4)
25
+FIELD(ID_AA64DFR0, BRPS, 12, 4)
26
+FIELD(ID_AA64DFR0, WRPS, 20, 4)
27
+FIELD(ID_AA64DFR0, CTX_CMPS, 28, 4)
28
+FIELD(ID_AA64DFR0, PMSVER, 32, 4)
29
+FIELD(ID_AA64DFR0, DOUBLELOCK, 36, 4)
30
+FIELD(ID_AA64DFR0, TRACEFILT, 40, 4)
31
+
32
FIELD(ID_DFR0, COPDBG, 0, 4)
33
FIELD(ID_DFR0, COPSDBG, 4, 4)
34
FIELD(ID_DFR0, MMAPDBG, 8, 4)
35
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.c
38
+++ b/target/arm/cpu.c
39
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
40
cpu);
41
#endif
42
} else {
43
- cpu->id_aa64dfr0 &= ~0xf00;
44
+ cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
45
cpu->id_dfr0 &= ~(0xf << 24);
46
cpu->pmceid0 = 0;
47
cpu->pmceid1 = 0;
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/helper.c
51
+++ b/target/arm/helper.c
52
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
53
* check that if they both exist then they agree.
54
*/
55
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
56
- assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps);
57
- assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps);
58
- assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps);
59
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
60
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
61
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
62
}
63
64
define_one_arm_cp_reg(cpu, &dbgdidr);
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
New patch
1
We already define FIELD macros for ID_DFR0, so use them in the
2
one place where we're doing direct bit value manipulation.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200214175116.9164-8-peter.maydell@linaro.org
8
---
9
target/arm/cpu.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
17
#endif
18
} else {
19
cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
20
- cpu->id_dfr0 &= ~(0xf << 24);
21
+ cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
22
cpu->pmceid0 = 0;
23
cpu->pmceid1 = 0;
24
}
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
New patch
1
1
Instead of open-coding a check on the ID_DFR0 PerfMon ID register
2
field, create a standardly-named isar_feature for "does AArch32 have
3
a v8.1 PMUv3" and use it.
4
5
This entails moving the id_dfr0 field into the ARMISARegisters struct.
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200214175116.9164-9-peter.maydell@linaro.org
10
---
11
target/arm/cpu.h | 9 ++++++++-
12
hw/intc/armv7m_nvic.c | 2 +-
13
target/arm/cpu.c | 28 ++++++++++++++--------------
14
target/arm/cpu64.c | 6 +++---
15
target/arm/helper.c | 5 ++---
16
5 files changed, 28 insertions(+), 22 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
23
uint32_t mvfr0;
24
uint32_t mvfr1;
25
uint32_t mvfr2;
26
+ uint32_t id_dfr0;
27
uint64_t id_aa64isar0;
28
uint64_t id_aa64isar1;
29
uint64_t id_aa64pfr0;
30
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
31
uint32_t reset_sctlr;
32
uint32_t id_pfr0;
33
uint32_t id_pfr1;
34
- uint32_t id_dfr0;
35
uint64_t pmceid0;
36
uint64_t pmceid1;
37
uint32_t id_afr0;
38
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
39
return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
40
}
41
42
+static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
43
+{
44
+ /* 0xf means "non-standard IMPDEF PMU" */
45
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
46
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
47
+}
48
+
49
/*
50
* 64-bit feature tests via id registers.
51
*/
52
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/intc/armv7m_nvic.c
55
+++ b/hw/intc/armv7m_nvic.c
56
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
57
case 0xd44: /* PFR1. */
58
return cpu->id_pfr1;
59
case 0xd48: /* DFR0. */
60
- return cpu->id_dfr0;
61
+ return cpu->isar.id_dfr0;
62
case 0xd4c: /* AFR0. */
63
return cpu->id_afr0;
64
case 0xd50: /* MMFR0. */
65
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/cpu.c
68
+++ b/target/arm/cpu.c
69
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
70
#endif
71
} else {
72
cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
73
- cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
74
+ cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
75
cpu->pmceid0 = 0;
76
cpu->pmceid1 = 0;
77
}
78
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
79
cpu->reset_sctlr = 0x00050078;
80
cpu->id_pfr0 = 0x111;
81
cpu->id_pfr1 = 0x1;
82
- cpu->id_dfr0 = 0x2;
83
+ cpu->isar.id_dfr0 = 0x2;
84
cpu->id_afr0 = 0x3;
85
cpu->id_mmfr0 = 0x01130003;
86
cpu->id_mmfr1 = 0x10030302;
87
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
88
cpu->reset_sctlr = 0x00050078;
89
cpu->id_pfr0 = 0x111;
90
cpu->id_pfr1 = 0x1;
91
- cpu->id_dfr0 = 0x2;
92
+ cpu->isar.id_dfr0 = 0x2;
93
cpu->id_afr0 = 0x3;
94
cpu->id_mmfr0 = 0x01130003;
95
cpu->id_mmfr1 = 0x10030302;
96
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
97
cpu->reset_sctlr = 0x00050078;
98
cpu->id_pfr0 = 0x111;
99
cpu->id_pfr1 = 0x11;
100
- cpu->id_dfr0 = 0x33;
101
+ cpu->isar.id_dfr0 = 0x33;
102
cpu->id_afr0 = 0;
103
cpu->id_mmfr0 = 0x01130003;
104
cpu->id_mmfr1 = 0x10030302;
105
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
106
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
107
cpu->id_pfr0 = 0x111;
108
cpu->id_pfr1 = 0x1;
109
- cpu->id_dfr0 = 0;
110
+ cpu->isar.id_dfr0 = 0;
111
cpu->id_afr0 = 0x2;
112
cpu->id_mmfr0 = 0x01100103;
113
cpu->id_mmfr1 = 0x10020302;
114
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
115
cpu->pmsav7_dregion = 8;
116
cpu->id_pfr0 = 0x00000030;
117
cpu->id_pfr1 = 0x00000200;
118
- cpu->id_dfr0 = 0x00100000;
119
+ cpu->isar.id_dfr0 = 0x00100000;
120
cpu->id_afr0 = 0x00000000;
121
cpu->id_mmfr0 = 0x00000030;
122
cpu->id_mmfr1 = 0x00000000;
123
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
124
cpu->isar.mvfr2 = 0x00000000;
125
cpu->id_pfr0 = 0x00000030;
126
cpu->id_pfr1 = 0x00000200;
127
- cpu->id_dfr0 = 0x00100000;
128
+ cpu->isar.id_dfr0 = 0x00100000;
129
cpu->id_afr0 = 0x00000000;
130
cpu->id_mmfr0 = 0x00000030;
131
cpu->id_mmfr1 = 0x00000000;
132
@@ -XXX,XX +XXX,XX @@ static void cortex_m7_initfn(Object *obj)
133
cpu->isar.mvfr2 = 0x00000040;
134
cpu->id_pfr0 = 0x00000030;
135
cpu->id_pfr1 = 0x00000200;
136
- cpu->id_dfr0 = 0x00100000;
137
+ cpu->isar.id_dfr0 = 0x00100000;
138
cpu->id_afr0 = 0x00000000;
139
cpu->id_mmfr0 = 0x00100030;
140
cpu->id_mmfr1 = 0x00000000;
141
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
142
cpu->isar.mvfr2 = 0x00000040;
143
cpu->id_pfr0 = 0x00000030;
144
cpu->id_pfr1 = 0x00000210;
145
- cpu->id_dfr0 = 0x00200000;
146
+ cpu->isar.id_dfr0 = 0x00200000;
147
cpu->id_afr0 = 0x00000000;
148
cpu->id_mmfr0 = 0x00101F40;
149
cpu->id_mmfr1 = 0x00000000;
150
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
151
cpu->midr = 0x411fc153; /* r1p3 */
152
cpu->id_pfr0 = 0x0131;
153
cpu->id_pfr1 = 0x001;
154
- cpu->id_dfr0 = 0x010400;
155
+ cpu->isar.id_dfr0 = 0x010400;
156
cpu->id_afr0 = 0x0;
157
cpu->id_mmfr0 = 0x0210030;
158
cpu->id_mmfr1 = 0x00000000;
159
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
160
cpu->reset_sctlr = 0x00c50078;
161
cpu->id_pfr0 = 0x1031;
162
cpu->id_pfr1 = 0x11;
163
- cpu->id_dfr0 = 0x400;
164
+ cpu->isar.id_dfr0 = 0x400;
165
cpu->id_afr0 = 0;
166
cpu->id_mmfr0 = 0x31100003;
167
cpu->id_mmfr1 = 0x20000000;
168
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
169
cpu->reset_sctlr = 0x00c50078;
170
cpu->id_pfr0 = 0x1031;
171
cpu->id_pfr1 = 0x11;
172
- cpu->id_dfr0 = 0x000;
173
+ cpu->isar.id_dfr0 = 0x000;
174
cpu->id_afr0 = 0;
175
cpu->id_mmfr0 = 0x00100103;
176
cpu->id_mmfr1 = 0x20000000;
177
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
178
cpu->reset_sctlr = 0x00c50078;
179
cpu->id_pfr0 = 0x00001131;
180
cpu->id_pfr1 = 0x00011011;
181
- cpu->id_dfr0 = 0x02010555;
182
+ cpu->isar.id_dfr0 = 0x02010555;
183
cpu->id_afr0 = 0x00000000;
184
cpu->id_mmfr0 = 0x10101105;
185
cpu->id_mmfr1 = 0x40000000;
186
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
187
cpu->reset_sctlr = 0x00c50078;
188
cpu->id_pfr0 = 0x00001131;
189
cpu->id_pfr1 = 0x00011011;
190
- cpu->id_dfr0 = 0x02010555;
191
+ cpu->isar.id_dfr0 = 0x02010555;
192
cpu->id_afr0 = 0x00000000;
193
cpu->id_mmfr0 = 0x10201105;
194
cpu->id_mmfr1 = 0x20000000;
195
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/target/arm/cpu64.c
198
+++ b/target/arm/cpu64.c
199
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
200
cpu->reset_sctlr = 0x00c50838;
201
cpu->id_pfr0 = 0x00000131;
202
cpu->id_pfr1 = 0x00011011;
203
- cpu->id_dfr0 = 0x03010066;
204
+ cpu->isar.id_dfr0 = 0x03010066;
205
cpu->id_afr0 = 0x00000000;
206
cpu->id_mmfr0 = 0x10101105;
207
cpu->id_mmfr1 = 0x40000000;
208
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
209
cpu->reset_sctlr = 0x00c50838;
210
cpu->id_pfr0 = 0x00000131;
211
cpu->id_pfr1 = 0x00011011;
212
- cpu->id_dfr0 = 0x03010066;
213
+ cpu->isar.id_dfr0 = 0x03010066;
214
cpu->id_afr0 = 0x00000000;
215
cpu->id_mmfr0 = 0x10101105;
216
cpu->id_mmfr1 = 0x40000000;
217
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
218
cpu->reset_sctlr = 0x00c50838;
219
cpu->id_pfr0 = 0x00000131;
220
cpu->id_pfr1 = 0x00011011;
221
- cpu->id_dfr0 = 0x03010066;
222
+ cpu->isar.id_dfr0 = 0x03010066;
223
cpu->id_afr0 = 0x00000000;
224
cpu->id_mmfr0 = 0x10201105;
225
cpu->id_mmfr1 = 0x40000000;
226
diff --git a/target/arm/helper.c b/target/arm/helper.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/arm/helper.c
229
+++ b/target/arm/helper.c
230
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
231
g_free(pmevtyper_name);
232
g_free(pmevtyper_el0_name);
233
}
234
- if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
235
- FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
236
+ if (cpu_isar_feature(aa32_pmu_8_1, cpu)) {
237
ARMCPRegInfo v81_pmu_regs[] = {
238
{ .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
239
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
240
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
241
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
242
.access = PL1_R, .type = ARM_CP_CONST,
243
.accessfn = access_aa32_tid3,
244
- .resetvalue = cpu->id_dfr0 },
245
+ .resetvalue = cpu->isar.id_dfr0 },
246
{ .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
247
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
248
.access = PL1_R, .type = ARM_CP_CONST,
249
--
250
2.20.1
251
252
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
Add the 64-bit version of the "is this a v8.1 PMUv3?"
2
ID register check function, and the _any_ version that
3
checks for either AArch32 or AArch64 support. We'll use
4
this in a later commit.
2
5
3
The cortex A53 TRM specifies that bits 24 and 25 of the L2CTLR register
6
We don't (yet) do any isar_feature checks on ID_AA64DFR1_EL1,
4
specify the number of cores in the processor, not the total number of
7
but we move id_aa64dfr1 into the ARMISARegisters struct with
5
cores in the system. To report this correctly on machines with multiple
8
id_aa64dfr0, for consistency.
6
CPU clusters (ARM's big.LITTLE or Xilinx's ZynqMP) we need to allow
7
the machine to overwrite this value. To do this let's add an optional
8
property.
9
9
10
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: ef01d95c0759e88f47f22d11b14c91512a658b4f.1520018138.git.alistair.francis@xilinx.com
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20200214175116.9164-10-peter.maydell@linaro.org
14
---
14
---
15
target/arm/cpu.h | 5 +++++
15
target/arm/cpu.h | 15 +++++++++++++--
16
target/arm/cpu.c | 6 ++++++
16
target/arm/cpu.c | 3 ++-
17
target/arm/cpu64.c | 6 ++++--
17
target/arm/cpu64.c | 6 +++---
18
3 files changed, 15 insertions(+), 2 deletions(-)
18
target/arm/helper.c | 12 +++++++-----
19
4 files changed, 25 insertions(+), 11 deletions(-)
19
20
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
23
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
25
/* Uniprocessor system with MP extensions */
26
uint64_t id_aa64mmfr0;
26
bool mp_is_up;
27
uint64_t id_aa64mmfr1;
27
28
uint64_t id_aa64mmfr2;
28
+ /* Specify the number of cores in this CPU cluster. Used for the L2CTLR
29
+ uint64_t id_aa64dfr0;
29
+ * register.
30
+ uint64_t id_aa64dfr1;
30
+ */
31
} isar;
31
+ int32_t core_count;
32
uint32_t midr;
33
uint32_t revidr;
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
35
uint32_t id_mmfr2;
36
uint32_t id_mmfr3;
37
uint32_t id_mmfr4;
38
- uint64_t id_aa64dfr0;
39
- uint64_t id_aa64dfr1;
40
uint64_t id_aa64afr0;
41
uint64_t id_aa64afr1;
42
uint32_t dbgdidr;
43
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
44
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
45
}
46
47
+static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
48
+{
49
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
50
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
51
+}
32
+
52
+
33
/* The instance init functions for implementation-specific subclasses
53
/*
34
* set these fields to specify the implementation-dependent values of
54
* Feature tests for "does this exist in either 32-bit or 64-bit?"
35
* various constant registers and reset values of non-constant
55
*/
56
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
57
return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
58
}
59
60
+static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
61
+{
62
+ return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
63
+}
64
+
65
/*
66
* Forward to the above feature tests given an ARMCPU pointer.
67
*/
36
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
68
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
37
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu.c
70
--- a/target/arm/cpu.c
39
+++ b/target/arm/cpu.c
71
+++ b/target/arm/cpu.c
40
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
72
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
41
cs->num_ases = 1;
73
cpu);
42
}
43
cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory);
44
+
45
+ /* No core_count specified, default to smp_cpus. */
46
+ if (cpu->core_count == -1) {
47
+ cpu->core_count = smp_cpus;
48
+ }
49
#endif
74
#endif
50
75
} else {
51
qemu_init_vcpu(cs);
76
- cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
52
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_properties[] = {
77
+ cpu->isar.id_aa64dfr0 =
53
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
78
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
54
mp_affinity, ARM64_AFFINITY_INVALID),
79
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
55
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
80
cpu->pmceid0 = 0;
56
+ DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
81
cpu->pmceid1 = 0;
57
DEFINE_PROP_END_OF_LIST()
58
};
59
60
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
82
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
61
index XXXXXXX..XXXXXXX 100644
83
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/cpu64.c
84
--- a/target/arm/cpu64.c
63
+++ b/target/arm/cpu64.c
85
+++ b/target/arm/cpu64.c
64
@@ -XXX,XX +XXX,XX @@ static inline void unset_feature(CPUARMState *env, int feature)
86
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
65
#ifndef CONFIG_USER_ONLY
87
cpu->isar.id_isar5 = 0x00011121;
66
static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
88
cpu->isar.id_isar6 = 0;
67
{
89
cpu->isar.id_aa64pfr0 = 0x00002222;
68
- /* Number of processors is in [25:24]; otherwise we RAZ */
90
- cpu->id_aa64dfr0 = 0x10305106;
69
- return (smp_cpus - 1) << 24;
91
+ cpu->isar.id_aa64dfr0 = 0x10305106;
70
+ ARMCPU *cpu = arm_env_get_cpu(env);
92
cpu->isar.id_aa64isar0 = 0x00011120;
71
+
93
cpu->isar.id_aa64mmfr0 = 0x00001124;
72
+ /* Number of cores is in [25:24]; otherwise we RAZ */
94
cpu->dbgdidr = 0x3516d000;
73
+ return (cpu->core_count - 1) << 24;
95
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
74
}
96
cpu->isar.id_isar5 = 0x00011121;
75
#endif
97
cpu->isar.id_isar6 = 0;
76
98
cpu->isar.id_aa64pfr0 = 0x00002222;
99
- cpu->id_aa64dfr0 = 0x10305106;
100
+ cpu->isar.id_aa64dfr0 = 0x10305106;
101
cpu->isar.id_aa64isar0 = 0x00011120;
102
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
103
cpu->dbgdidr = 0x3516d000;
104
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
105
cpu->isar.id_isar4 = 0x00011142;
106
cpu->isar.id_isar5 = 0x00011121;
107
cpu->isar.id_aa64pfr0 = 0x00002222;
108
- cpu->id_aa64dfr0 = 0x10305106;
109
+ cpu->isar.id_aa64dfr0 = 0x10305106;
110
cpu->isar.id_aa64isar0 = 0x00011120;
111
cpu->isar.id_aa64mmfr0 = 0x00001124;
112
cpu->dbgdidr = 0x3516d000;
113
diff --git a/target/arm/helper.c b/target/arm/helper.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/helper.c
116
+++ b/target/arm/helper.c
117
@@ -XXX,XX +XXX,XX @@
118
#include "hw/semihosting/semihost.h"
119
#include "sysemu/cpus.h"
120
#include "sysemu/kvm.h"
121
+#include "sysemu/tcg.h"
122
#include "qemu/range.h"
123
#include "qapi/qapi-commands-machine-target.h"
124
#include "qapi/error.h"
125
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
126
* check that if they both exist then they agree.
127
*/
128
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
129
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
130
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
131
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
132
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
133
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
134
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
135
+ == ctx_cmps);
136
}
137
138
define_one_arm_cp_reg(cpu, &dbgdidr);
139
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
140
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
141
.access = PL1_R, .type = ARM_CP_CONST,
142
.accessfn = access_aa64_tid3,
143
- .resetvalue = cpu->id_aa64dfr0 },
144
+ .resetvalue = cpu->isar.id_aa64dfr0 },
145
{ .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
146
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
147
.access = PL1_R, .type = ARM_CP_CONST,
148
.accessfn = access_aa64_tid3,
149
- .resetvalue = cpu->id_aa64dfr1 },
150
+ .resetvalue = cpu->isar.id_aa64dfr1 },
151
{ .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
152
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
153
.access = PL1_R, .type = ARM_CP_CONST,
77
--
154
--
78
2.16.2
155
2.20.1
79
156
80
157
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The AArch32 DBGDIDR defines properties like the number of
2
breakpoints, watchpoints and context-matching comparators. On an
3
AArch64 CPU, the register may not even exist if AArch32 is not
4
supported at EL1.
2
5
3
The SDBus will reuse these functions, so we put them in a new source file.
6
Currently we hard-code use of DBGDIDR to identify the number of
7
breakpoints etc; this works for all our TCG CPUs, but will break if
8
we ever add an AArch64-only CPU. We also have an assert() that the
9
AArch32 and AArch64 registers match, which currently works only by
10
luck for KVM because we don't populate either of these ID registers
11
from the KVM vCPU and so they are both zero.
4
12
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Clean this up so we have functions for finding the number
6
Message-id: 20180309153654.13518-3-f4bug@amsat.org
14
of breakpoints, watchpoints and context comparators which look
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
in the appropriate ID register.
8
[PMM: slight wordsmithing of comments, added note that string
16
9
returned does not need to be freed]
17
This allows us to drop the "check that AArch64 and AArch32 agree
18
on the number of breakpoints etc" asserts:
19
* we no longer look at the AArch32 versions unless that's the
20
right place to be looking
21
* it's valid to have a CPU (eg AArch64-only) where they don't match
22
* we shouldn't have been asserting the validity of ID registers
23
in a codepath used with KVM anyway
24
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20200214175116.9164-11-peter.maydell@linaro.org
11
---
28
---
12
hw/sd/Makefile.objs | 2 +-
29
target/arm/cpu.h | 7 +++++++
13
hw/sd/sdmmc-internal.h | 24 +++++++++++++++++
30
target/arm/internals.h | 42 +++++++++++++++++++++++++++++++++++++++
14
hw/sd/sd.c | 13 +++++----
31
target/arm/debug_helper.c | 6 +++---
15
hw/sd/sdmmc-internal.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
32
target/arm/helper.c | 21 +++++---------------
16
hw/sd/trace-events | 8 +++---
33
4 files changed, 57 insertions(+), 19 deletions(-)
17
5 files changed, 109 insertions(+), 10 deletions(-)
18
create mode 100644 hw/sd/sdmmc-internal.c
19
34
20
diff --git a/hw/sd/Makefile.objs b/hw/sd/Makefile.objs
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/sd/Makefile.objs
37
--- a/target/arm/cpu.h
23
+++ b/hw/sd/Makefile.objs
38
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@ FIELD(ID_DFR0, MPROFDBG, 20, 4)
25
common-obj-$(CONFIG_PL181) += pl181.o
40
FIELD(ID_DFR0, PERFMON, 24, 4)
26
common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
41
FIELD(ID_DFR0, TRACEFILT, 28, 4)
27
-common-obj-$(CONFIG_SD) += sd.o core.o
42
28
+common-obj-$(CONFIG_SD) += sd.o core.o sdmmc-internal.o
43
+FIELD(DBGDIDR, SE_IMP, 12, 1)
29
common-obj-$(CONFIG_SDHCI) += sdhci.o
44
+FIELD(DBGDIDR, NSUHD_IMP, 14, 1)
30
45
+FIELD(DBGDIDR, VERSION, 16, 4)
31
obj-$(CONFIG_MILKYMIST) += milkymist-memcard.o
46
+FIELD(DBGDIDR, CTX_CMPS, 20, 4)
32
diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h
47
+FIELD(DBGDIDR, BRPS, 24, 4)
48
+FIELD(DBGDIDR, WRPS, 28, 4)
49
+
50
FIELD(MVFR0, SIMDREG, 0, 4)
51
FIELD(MVFR0, FPSP, 4, 4)
52
FIELD(MVFR0, FPDP, 8, 4)
53
diff --git a/target/arm/internals.h b/target/arm/internals.h
33
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/sd/sdmmc-internal.h
55
--- a/target/arm/internals.h
35
+++ b/hw/sd/sdmmc-internal.h
56
+++ b/target/arm/internals.h
36
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_debug_exception_fsr(CPUARMState *env)
37
58
}
38
#define SDMMC_CMD_MAX 64
59
}
39
60
40
+/**
61
+/**
41
+ * sd_cmd_name:
62
+ * arm_num_brps: Return number of implemented breakpoints.
42
+ * @cmd: A SD "normal" command, up to SDMMC_CMD_MAX.
63
+ * Note that the ID register BRPS field is "number of bps - 1",
43
+ *
64
+ * and we return the actual number of breakpoints.
44
+ * Returns a human-readable name describing the command.
45
+ * The return value is always a static string which does not need
46
+ * to be freed after use.
47
+ *
48
+ * Returns: The command name of @cmd or "UNKNOWN_CMD".
49
+ */
65
+ */
50
+const char *sd_cmd_name(uint8_t cmd);
66
+static inline int arm_num_brps(ARMCPU *cpu)
67
+{
68
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
69
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
70
+ } else {
71
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, BRPS) + 1;
72
+ }
73
+}
51
+
74
+
52
+/**
75
+/**
53
+ * sd_acmd_name:
76
+ * arm_num_wrps: Return number of implemented watchpoints.
54
+ * @cmd: A SD "Application-Specific" command, up to SDMMC_CMD_MAX.
77
+ * Note that the ID register WRPS field is "number of wps - 1",
55
+ *
78
+ * and we return the actual number of watchpoints.
56
+ * Returns a human-readable name describing the application command.
57
+ * The return value is always a static string which does not need
58
+ * to be freed after use.
59
+ *
60
+ * Returns: The application command name of @cmd or "UNKNOWN_ACMD".
61
+ */
79
+ */
62
+const char *sd_acmd_name(uint8_t cmd);
80
+static inline int arm_num_wrps(ARMCPU *cpu)
63
+
64
#endif
65
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/sd/sd.c
68
+++ b/hw/sd/sd.c
69
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
70
* However there is no ACMD55, so we want to trace this particular case.
71
*/
72
if (req.cmd != 55 || sd->expecting_acmd) {
73
- trace_sdcard_normal_command(req.cmd, req.arg,
74
- sd_state_name(sd->state));
75
+ trace_sdcard_normal_command(sd_cmd_name(req.cmd), req.cmd,
76
+ req.arg, sd_state_name(sd->state));
77
}
78
79
/* Not interpreting this as an app command */
80
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
81
static sd_rsp_type_t sd_app_command(SDState *sd,
82
SDRequest req)
83
{
84
- trace_sdcard_app_command(req.cmd, req.arg);
85
+ trace_sdcard_app_command(sd_acmd_name(req.cmd),
86
+ req.cmd, req.arg, sd_state_name(sd->state));
87
sd->card_status |= APP_CMD;
88
switch (req.cmd) {
89
case 6:    /* ACMD6: SET_BUS_WIDTH */
90
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
91
if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
92
return;
93
94
- trace_sdcard_write_data(sd->current_cmd, value);
95
+ trace_sdcard_write_data(sd_acmd_name(sd->current_cmd),
96
+ sd->current_cmd, value);
97
switch (sd->current_cmd) {
98
case 24:    /* CMD24: WRITE_SINGLE_BLOCK */
99
sd->data[sd->data_offset ++] = value;
100
@@ -XXX,XX +XXX,XX @@ uint8_t sd_read_data(SDState *sd)
101
102
io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len;
103
104
- trace_sdcard_read_data(sd->current_cmd, io_len);
105
+ trace_sdcard_read_data(sd_acmd_name(sd->current_cmd),
106
+ sd->current_cmd, io_len);
107
switch (sd->current_cmd) {
108
case 6:    /* CMD6: SWITCH_FUNCTION */
109
ret = sd->data[sd->data_offset ++];
110
diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
111
new file mode 100644
112
index XXXXXXX..XXXXXXX
113
--- /dev/null
114
+++ b/hw/sd/sdmmc-internal.c
115
@@ -XXX,XX +XXX,XX @@
116
+/*
117
+ * SD/MMC cards common helpers
118
+ *
119
+ * Copyright (c) 2018 Philippe Mathieu-Daudé <f4bug@amsat.org>
120
+ *
121
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
122
+ * See the COPYING file in the top-level directory.
123
+ * SPDX-License-Identifier: GPL-2.0-or-later
124
+ */
125
+
126
+#include "qemu/osdep.h"
127
+#include "sdmmc-internal.h"
128
+
129
+const char *sd_cmd_name(uint8_t cmd)
130
+{
81
+{
131
+ static const char *cmd_abbrev[SDMMC_CMD_MAX] = {
82
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
132
+ [0] = "GO_IDLE_STATE",
83
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
133
+ [2] = "ALL_SEND_CID", [3] = "SEND_RELATIVE_ADDR",
84
+ } else {
134
+ [4] = "SET_DSR", [5] = "IO_SEND_OP_COND",
85
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, WRPS) + 1;
135
+ [6] = "SWITCH_FUNC", [7] = "SELECT/DESELECT_CARD",
86
+ }
136
+ [8] = "SEND_IF_COND", [9] = "SEND_CSD",
137
+ [10] = "SEND_CID", [11] = "VOLTAGE_SWITCH",
138
+ [12] = "STOP_TRANSMISSION", [13] = "SEND_STATUS",
139
+ [15] = "GO_INACTIVE_STATE",
140
+ [16] = "SET_BLOCKLEN", [17] = "READ_SINGLE_BLOCK",
141
+ [18] = "READ_MULTIPLE_BLOCK", [19] = "SEND_TUNING_BLOCK",
142
+ [20] = "SPEED_CLASS_CONTROL", [21] = "DPS_spec",
143
+ [23] = "SET_BLOCK_COUNT",
144
+ [24] = "WRITE_BLOCK", [25] = "WRITE_MULTIPLE_BLOCK",
145
+ [26] = "MANUF_RSVD", [27] = "PROGRAM_CSD",
146
+ [28] = "SET_WRITE_PROT", [29] = "CLR_WRITE_PROT",
147
+ [30] = "SEND_WRITE_PROT",
148
+ [32] = "ERASE_WR_BLK_START", [33] = "ERASE_WR_BLK_END",
149
+ [34] = "SW_FUNC_RSVD", [35] = "SW_FUNC_RSVD",
150
+ [36] = "SW_FUNC_RSVD", [37] = "SW_FUNC_RSVD",
151
+ [38] = "ERASE",
152
+ [40] = "DPS_spec",
153
+ [42] = "LOCK_UNLOCK", [43] = "Q_MANAGEMENT",
154
+ [44] = "Q_TASK_INFO_A", [45] = "Q_TASK_INFO_B",
155
+ [46] = "Q_RD_TASK", [47] = "Q_WR_TASK",
156
+ [48] = "READ_EXTR_SINGLE", [49] = "WRITE_EXTR_SINGLE",
157
+ [50] = "SW_FUNC_RSVD",
158
+ [52] = "IO_RW_DIRECT", [53] = "IO_RW_EXTENDED",
159
+ [54] = "SDIO_RSVD", [55] = "APP_CMD",
160
+ [56] = "GEN_CMD", [57] = "SW_FUNC_RSVD",
161
+ [58] = "READ_EXTR_MULTI", [59] = "WRITE_EXTR_MULTI",
162
+ [60] = "MANUF_RSVD", [61] = "MANUF_RSVD",
163
+ [62] = "MANUF_RSVD", [63] = "MANUF_RSVD",
164
+ };
165
+ return cmd_abbrev[cmd] ? cmd_abbrev[cmd] : "UNKNOWN_CMD";
166
+}
87
+}
167
+
88
+
168
+const char *sd_acmd_name(uint8_t cmd)
89
+/**
90
+ * arm_num_ctx_cmps: Return number of implemented context comparators.
91
+ * Note that the ID register CTX_CMPS field is "number of cmps - 1",
92
+ * and we return the actual number of comparators.
93
+ */
94
+static inline int arm_num_ctx_cmps(ARMCPU *cpu)
169
+{
95
+{
170
+ static const char *acmd_abbrev[SDMMC_CMD_MAX] = {
96
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
171
+ [6] = "SET_BUS_WIDTH",
97
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
172
+ [13] = "SD_STATUS",
98
+ } else {
173
+ [14] = "DPS_spec", [15] = "DPS_spec",
99
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, CTX_CMPS) + 1;
174
+ [16] = "DPS_spec",
100
+ }
175
+ [18] = "SECU_spec",
101
+}
176
+ [22] = "SEND_NUM_WR_BLOCKS", [23] = "SET_WR_BLK_ERASE_COUNT",
177
+ [41] = "SD_SEND_OP_COND",
178
+ [42] = "SET_CLR_CARD_DETECT",
179
+ [51] = "SEND_SCR",
180
+ [52] = "SECU_spec", [53] = "SECU_spec",
181
+ [54] = "SECU_spec",
182
+ [56] = "SECU_spec", [57] = "SECU_spec",
183
+ [58] = "SECU_spec", [59] = "SECU_spec",
184
+ };
185
+
102
+
186
+ return acmd_abbrev[cmd] ? acmd_abbrev[cmd] : "UNKNOWN_ACMD";
103
/* Note make_memop_idx reserves 4 bits for mmu_idx, and MO_BSWAP is bit 3.
187
+}
104
* Thus a TCGMemOpIdx, without any MO_ALIGN bits, fits in 8 bits.
188
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
105
*/
106
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
189
index XXXXXXX..XXXXXXX 100644
107
index XXXXXXX..XXXXXXX 100644
190
--- a/hw/sd/trace-events
108
--- a/target/arm/debug_helper.c
191
+++ b/hw/sd/trace-events
109
+++ b/target/arm/debug_helper.c
192
@@ -XXX,XX +XXX,XX @@ sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of
110
@@ -XXX,XX +XXX,XX @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
193
sdhci_capareg(const char *desc, uint16_t val) "%s: %u"
111
{
194
112
CPUARMState *env = &cpu->env;
195
# hw/sd/sd.c
113
uint64_t bcr = env->cp15.dbgbcr[lbn];
196
-sdcard_normal_command(uint8_t cmd, uint32_t arg, const char *state) "CMD%d arg 0x%08x (state %s)"
114
- int brps = extract32(cpu->dbgdidr, 24, 4);
197
-sdcard_app_command(uint8_t acmd, uint32_t arg) "ACMD%d arg 0x%08x"
115
- int ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
198
+sdcard_normal_command(const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%20s/ CMD%02d arg 0x%08x (state %s)"
116
+ int brps = arm_num_brps(cpu);
199
+sdcard_app_command(const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%23s/ACMD%02d arg 0x%08x (state %s)"
117
+ int ctx_cmps = arm_num_ctx_cmps(cpu);
200
sdcard_response(const char *rspdesc, int rsplen) "%s (sz:%d)"
118
int bt;
201
sdcard_powerup(void) ""
119
uint32_t contextidr;
202
sdcard_inquiry_cmd41(void) ""
120
uint64_t hcr_el2;
203
@@ -XXX,XX +XXX,XX @@ sdcard_lock(void) ""
121
@@ -XXX,XX +XXX,XX @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
204
sdcard_unlock(void) ""
122
* case DBGWCR<n>_EL1.LBN must indicate that breakpoint).
205
sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
123
* We choose the former.
206
sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
124
*/
207
-sdcard_write_data(uint8_t cmd, uint8_t value) "CMD%02d value 0x%02x"
125
- if (lbn > brps || lbn < (brps - ctx_cmps)) {
208
-sdcard_read_data(uint8_t cmd, int length) "CMD%02d len %d"
126
+ if (lbn >= brps || lbn < (brps - ctx_cmps)) {
209
+sdcard_write_data(const char *cmd_desc, uint8_t cmd, uint8_t value) "%20s/ CMD%02d value 0x%02x"
127
return false;
210
+sdcard_read_data(const char *cmd_desc, uint8_t cmd, int length) "%20s/ CMD%02d len %d"
128
}
211
sdcard_set_voltage(uint16_t millivolts) "%u mV"
129
212
130
diff --git a/target/arm/helper.c b/target/arm/helper.c
213
# hw/sd/milkymist-memcard.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/helper.c
133
+++ b/target/arm/helper.c
134
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
135
};
136
137
/* Note that all these register fields hold "number of Xs minus 1". */
138
- brps = extract32(cpu->dbgdidr, 24, 4);
139
- wrps = extract32(cpu->dbgdidr, 28, 4);
140
- ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
141
+ brps = arm_num_brps(cpu);
142
+ wrps = arm_num_wrps(cpu);
143
+ ctx_cmps = arm_num_ctx_cmps(cpu);
144
145
assert(ctx_cmps <= brps);
146
147
- /* The DBGDIDR and ID_AA64DFR0_EL1 define various properties
148
- * of the debug registers such as number of breakpoints;
149
- * check that if they both exist then they agree.
150
- */
151
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
152
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
153
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
154
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
155
- == ctx_cmps);
156
- }
157
-
158
define_one_arm_cp_reg(cpu, &dbgdidr);
159
define_arm_cp_regs(cpu, debug_cp_reginfo);
160
161
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
162
define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
163
}
164
165
- for (i = 0; i < brps + 1; i++) {
166
+ for (i = 0; i < brps; i++) {
167
ARMCPRegInfo dbgregs[] = {
168
{ .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
169
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
170
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
171
define_arm_cp_regs(cpu, dbgregs);
172
}
173
174
- for (i = 0; i < wrps + 1; i++) {
175
+ for (i = 0; i < wrps; i++) {
176
ARMCPRegInfo dbgregs[] = {
177
{ .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
178
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
214
--
179
--
215
2.16.2
180
2.20.1
216
181
217
182
diff view generated by jsdifflib
1
Add support for "-cpu max" for ARM guests. This CPU type behaves
1
We're going to want to read the DBGDIDR register from KVM in
2
like "-cpu host" when KVM is enabled, and like a system CPU with
2
a subsequent commit, which means it needs to be in the
3
the maximum possible feature set otherwise. (Note that this means
3
ARMISARegisters sub-struct. Move it.
4
it won't be migratable across versions, as we will likely add
5
features to it in future.)
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180308130626.12393-4-peter.maydell@linaro.org
7
Message-id: 20200214175116.9164-12-peter.maydell@linaro.org
10
---
8
---
11
target/arm/cpu-qom.h | 2 ++
9
target/arm/cpu.h | 2 +-
12
target/arm/cpu.c | 24 ++++++++++++++++++++++++
10
target/arm/internals.h | 6 +++---
13
target/arm/cpu64.c | 21 +++++++++++++++++++++
11
target/arm/cpu.c | 8 ++++----
14
3 files changed, 47 insertions(+)
12
target/arm/cpu64.c | 6 +++---
13
target/arm/helper.c | 2 +-
14
5 files changed, 12 insertions(+), 12 deletions(-)
15
15
16
diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu-qom.h
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu-qom.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ struct arm_boot_info;
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
#define ARM_CPU_GET_CLASS(obj) \
21
uint32_t mvfr1;
22
OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU)
22
uint32_t mvfr2;
23
23
uint32_t id_dfr0;
24
+#define TYPE_ARM_MAX_CPU "max-" TYPE_ARM_CPU
24
+ uint32_t dbgdidr;
25
+
25
uint64_t id_aa64isar0;
26
/**
26
uint64_t id_aa64isar1;
27
* ARMCPUClass:
27
uint64_t id_aa64pfr0;
28
* @parent_realize: The parent class' realize handler.
28
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
29
uint32_t id_mmfr4;
30
uint64_t id_aa64afr0;
31
uint64_t id_aa64afr1;
32
- uint32_t dbgdidr;
33
uint32_t clidr;
34
uint64_t mp_affinity; /* MP ID without feature bits */
35
/* The elements of this array are the CCSIDR values for each cache,
36
diff --git a/target/arm/internals.h b/target/arm/internals.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/internals.h
39
+++ b/target/arm/internals.h
40
@@ -XXX,XX +XXX,XX @@ static inline int arm_num_brps(ARMCPU *cpu)
41
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
42
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
43
} else {
44
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, BRPS) + 1;
45
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1;
46
}
47
}
48
49
@@ -XXX,XX +XXX,XX @@ static inline int arm_num_wrps(ARMCPU *cpu)
50
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
51
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
52
} else {
53
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, WRPS) + 1;
54
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1;
55
}
56
}
57
58
@@ -XXX,XX +XXX,XX @@ static inline int arm_num_ctx_cmps(ARMCPU *cpu)
59
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
60
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
61
} else {
62
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, CTX_CMPS) + 1;
63
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1;
64
}
65
}
66
29
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
67
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
30
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.c
69
--- a/target/arm/cpu.c
32
+++ b/target/arm/cpu.c
70
+++ b/target/arm/cpu.c
33
@@ -XXX,XX +XXX,XX @@ static void pxa270c5_initfn(Object *obj)
71
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
34
cpu->reset_sctlr = 0x00000078;
72
cpu->isar.id_isar2 = 0x21232031;
35
}
73
cpu->isar.id_isar3 = 0x11112131;
36
74
cpu->isar.id_isar4 = 0x00111142;
37
+#ifndef TARGET_AARCH64
75
- cpu->dbgdidr = 0x15141000;
38
+/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
76
+ cpu->isar.dbgdidr = 0x15141000;
39
+ * otherwise, a CPU with as many features enabled as our emulation supports.
77
cpu->clidr = (1 << 27) | (2 << 24) | 3;
40
+ * The version of '-cpu max' for qemu-system-aarch64 is defined in cpu64.c;
78
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
41
+ * this only needs to handle 32 bits.
79
cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
42
+ */
80
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
43
+static void arm_max_initfn(Object *obj)
81
cpu->isar.id_isar2 = 0x21232041;
44
+{
82
cpu->isar.id_isar3 = 0x11112131;
45
+ ARMCPU *cpu = ARM_CPU(obj);
83
cpu->isar.id_isar4 = 0x00111142;
46
+
84
- cpu->dbgdidr = 0x35141000;
47
+ if (kvm_enabled()) {
85
+ cpu->isar.dbgdidr = 0x35141000;
48
+ kvm_arm_set_cpu_features_from_host(cpu);
86
cpu->clidr = (1 << 27) | (1 << 24) | 3;
49
+ } else {
87
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
50
+ cortex_a15_initfn(obj);
88
cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */
51
+ /* In future we might add feature bits here even if the
89
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
52
+ * real-world A15 doesn't implement them.
90
cpu->isar.id_isar2 = 0x21232041;
53
+ */
91
cpu->isar.id_isar3 = 0x11112131;
54
+ }
92
cpu->isar.id_isar4 = 0x10011142;
55
+}
93
- cpu->dbgdidr = 0x3515f005;
56
+#endif
94
+ cpu->isar.dbgdidr = 0x3515f005;
57
+
95
cpu->clidr = 0x0a200023;
58
#ifdef CONFIG_USER_ONLY
96
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
59
static void arm_any_initfn(Object *obj)
97
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
60
{
98
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
99
cpu->isar.id_isar2 = 0x21232041;
62
{ .name = "pxa270-b1", .initfn = pxa270b1_initfn },
100
cpu->isar.id_isar3 = 0x11112131;
63
{ .name = "pxa270-c0", .initfn = pxa270c0_initfn },
101
cpu->isar.id_isar4 = 0x10011142;
64
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
102
- cpu->dbgdidr = 0x3515f021;
65
+#ifndef TARGET_AARCH64
103
+ cpu->isar.dbgdidr = 0x3515f021;
66
+ { .name = "max", .initfn = arm_max_initfn },
104
cpu->clidr = 0x0a200023;
67
+#endif
105
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
68
#ifdef CONFIG_USER_ONLY
106
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
69
{ .name = "any", .initfn = arm_any_initfn },
70
#endif
71
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
107
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
72
index XXXXXXX..XXXXXXX 100644
108
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/cpu64.c
109
--- a/target/arm/cpu64.c
74
+++ b/target/arm/cpu64.c
110
+++ b/target/arm/cpu64.c
75
@@ -XXX,XX +XXX,XX @@
111
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
76
#include "hw/arm/arm.h"
112
cpu->isar.id_aa64dfr0 = 0x10305106;
77
#include "sysemu/sysemu.h"
113
cpu->isar.id_aa64isar0 = 0x00011120;
78
#include "sysemu/kvm.h"
114
cpu->isar.id_aa64mmfr0 = 0x00001124;
79
+#include "kvm_arm.h"
115
- cpu->dbgdidr = 0x3516d000;
80
116
+ cpu->isar.dbgdidr = 0x3516d000;
81
static inline void set_feature(CPUARMState *env, int feature)
117
cpu->clidr = 0x0a200023;
82
{
118
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
119
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
83
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
120
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
84
define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
121
cpu->isar.id_aa64dfr0 = 0x10305106;
85
}
122
cpu->isar.id_aa64isar0 = 0x00011120;
86
123
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
87
+/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
124
- cpu->dbgdidr = 0x3516d000;
88
+ * otherwise, a CPU with as many features enabled as our emulation supports.
125
+ cpu->isar.dbgdidr = 0x3516d000;
89
+ * The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
126
cpu->clidr = 0x0a200023;
90
+ * this only needs to handle 64 bits.
127
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
91
+ */
128
cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
92
+static void aarch64_max_initfn(Object *obj)
129
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
93
+{
130
cpu->isar.id_aa64dfr0 = 0x10305106;
94
+ ARMCPU *cpu = ARM_CPU(obj);
131
cpu->isar.id_aa64isar0 = 0x00011120;
95
+
132
cpu->isar.id_aa64mmfr0 = 0x00001124;
96
+ if (kvm_enabled()) {
133
- cpu->dbgdidr = 0x3516d000;
97
+ kvm_arm_set_cpu_features_from_host(cpu);
134
+ cpu->isar.dbgdidr = 0x3516d000;
98
+ } else {
135
cpu->clidr = 0x0a200023;
99
+ aarch64_a57_initfn(obj);
136
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
100
+ /* In future we might add feature bits here even if the
137
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
101
+ * real-world A57 doesn't implement them.
138
diff --git a/target/arm/helper.c b/target/arm/helper.c
102
+ */
139
index XXXXXXX..XXXXXXX 100644
103
+ }
140
--- a/target/arm/helper.c
104
+}
141
+++ b/target/arm/helper.c
105
+
142
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
106
#ifdef CONFIG_USER_ONLY
143
ARMCPRegInfo dbgdidr = {
107
static void aarch64_any_initfn(Object *obj)
144
.name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
108
{
145
.access = PL0_R, .accessfn = access_tda,
109
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCPUInfo {
146
- .type = ARM_CP_CONST, .resetvalue = cpu->dbgdidr,
110
static const ARMCPUInfo aarch64_cpus[] = {
147
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
111
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
148
};
112
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
149
113
+ { .name = "max", .initfn = aarch64_max_initfn },
150
/* Note that all these register fields hold "number of Xs minus 1". */
114
#ifdef CONFIG_USER_ONLY
115
{ .name = "any", .initfn = aarch64_any_initfn },
116
#endif
117
--
151
--
118
2.16.2
152
2.20.1
119
153
120
154
diff view generated by jsdifflib
1
Currently we query the host CPU features in the class init function
1
Now we have isar_feature test functions that look at fields in the
2
for the TYPE_ARM_HOST_CPU class, so that we can later copy them
2
ID_AA64DFR0_EL1 and ID_DFR0 ID registers, add the code that reads
3
from the class object into the instance object in the object
3
these register values from KVM so that the checks behave correctly
4
instance init function. This is awkward for implementing "-cpu max",
4
when we're using KVM.
5
which should work like "-cpu host" for KVM but like "cpu with all
6
implemented features" for TCG.
7
5
8
Move the place where we store the information about the host CPU from
6
No isar_feature function tests ID_AA64DFR1_EL1 or DBGDIDR yet, but we
9
a class object to static variables in kvm.c, and then in the instance
7
add it to maintain the invariant that every field in the
10
init function call a new kvm_arm_set_cpu_features_from_host()
8
ARMISARegisters struct is populated for a KVM CPU and can be relied
11
function which will query the host kernel if necessary and then
9
on. This requirement isn't actually written down yet, so add a note
12
fill in the CPU instance fields.
10
to the relevant comment.
13
14
This allows us to drop the special class struct and class init
15
function for TYPE_ARM_HOST_CPU entirely.
16
17
We can't delay the probe until realize, because the ARM
18
instance_post_init hook needs to look at the feature bits we
19
set, so we need to do it in the initfn. This is safe because
20
the probing doesn't affect the actual VM state (it creates a
21
separate scratch VM to do its testing), but the probe might fail.
22
Because we can't report errors in retrieving the host features
23
in the initfn, we check this belatedly in the realize function
24
(the intervening code will be able to cope with the relevant
25
fields in the CPU structure being zero).
26
11
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 20200214175116.9164-13-peter.maydell@linaro.org
30
Message-id: 20180308130626.12393-2-peter.maydell@linaro.org
31
---
15
---
32
target/arm/cpu.h | 5 +++++
16
target/arm/cpu.h | 5 +++++
33
target/arm/kvm_arm.h | 35 ++++++++++++++++++++++++-----------
17
target/arm/kvm32.c | 8 ++++++++
34
target/arm/cpu.c | 13 +++++++++++++
18
target/arm/kvm64.c | 36 ++++++++++++++++++++++++++++++++++++
35
target/arm/kvm.c | 36 +++++++++++++++++++-----------------
19
3 files changed, 49 insertions(+)
36
target/arm/kvm32.c | 8 ++++----
37
target/arm/kvm64.c | 8 ++++----
38
6 files changed, 69 insertions(+), 36 deletions(-)
39
20
40
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
41
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpu.h
23
--- a/target/arm/cpu.h
43
+++ b/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
44
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
45
/* Uniprocessor system with MP extensions */
26
* prefix means a constant register.
46
bool mp_is_up;
27
* Some of these registers are split out into a substructure that
47
28
* is shared with the translators to control the ISA.
48
+ /* True if we tried kvm_arm_host_cpu_features() during CPU instance_init
29
+ *
49
+ * and the probe failed (so we need to report the error in realize)
30
+ * Note that if you add an ID register to the ARMISARegisters struct
50
+ */
31
+ * you need to also update the 32-bit and 64-bit versions of the
51
+ bool host_cpu_probe_failed;
32
+ * kvm_arm_get_host_cpu_features() function to correctly populate the
52
+
33
+ * field by reading the value from the KVM vCPU.
53
/* Specify the number of cores in this CPU cluster. Used for the L2CTLR
54
* register.
55
*/
34
*/
56
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
35
struct ARMISARegisters {
57
index XXXXXXX..XXXXXXX 100644
36
uint32_t id_isar0;
58
--- a/target/arm/kvm_arm.h
59
+++ b/target/arm/kvm_arm.h
60
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
61
void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
62
63
#define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU
64
-#define ARM_HOST_CPU_CLASS(klass) \
65
- OBJECT_CLASS_CHECK(ARMHostCPUClass, (klass), TYPE_ARM_HOST_CPU)
66
-#define ARM_HOST_CPU_GET_CLASS(obj) \
67
- OBJECT_GET_CLASS(ARMHostCPUClass, (obj), TYPE_ARM_HOST_CPU)
68
-
69
-typedef struct ARMHostCPUClass {
70
- /*< private >*/
71
- ARMCPUClass parent_class;
72
- /*< public >*/
73
74
+/**
75
+ * ARMHostCPUFeatures: information about the host CPU (identified
76
+ * by asking the host kernel)
77
+ */
78
+typedef struct ARMHostCPUFeatures {
79
uint64_t features;
80
uint32_t target;
81
const char *dtb_compatible;
82
-} ARMHostCPUClass;
83
+} ARMHostCPUFeatures;
84
85
/**
86
* kvm_arm_get_host_cpu_features:
87
@@ -XXX,XX +XXX,XX @@ typedef struct ARMHostCPUClass {
88
* Probe the capabilities of the host kernel's preferred CPU and fill
89
* in the ARMHostCPUClass struct accordingly.
90
*/
91
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc);
92
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
93
94
+/**
95
+ * kvm_arm_set_cpu_features_from_host:
96
+ * @cpu: ARMCPU to set the features for
97
+ *
98
+ * Set up the ARMCPU struct fields up to match the information probed
99
+ * from the host CPU.
100
+ */
101
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
102
103
/**
104
* kvm_arm_sync_mpstate_to_kvm
105
@@ -XXX,XX +XXX,XX @@ void kvm_arm_pmu_init(CPUState *cs);
106
107
#else
108
109
+static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
110
+{
111
+ /* This should never actually be called in the "not KVM" case,
112
+ * but set up the fields to indicate an error anyway.
113
+ */
114
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
115
+ cpu->host_cpu_probe_failed = true;
116
+}
117
+
118
static inline int kvm_arm_vgic_probe(void)
119
{
120
return 0;
121
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/target/arm/cpu.c
124
+++ b/target/arm/cpu.c
125
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
126
int pagebits;
127
Error *local_err = NULL;
128
129
+ /* If we needed to query the host kernel for the CPU features
130
+ * then it's possible that might have failed in the initfn, but
131
+ * this is the first point where we can report it.
132
+ */
133
+ if (cpu->host_cpu_probe_failed) {
134
+ if (!kvm_enabled()) {
135
+ error_setg(errp, "The 'host' CPU type can only be used with KVM");
136
+ } else {
137
+ error_setg(errp, "Failed to retrieve host CPU features");
138
+ }
139
+ return;
140
+ }
141
+
142
cpu_exec_realizefn(cs, &local_err);
143
if (local_err != NULL) {
144
error_propagate(errp, local_err);
145
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/kvm.c
148
+++ b/target/arm/kvm.c
149
@@ -XXX,XX +XXX,XX @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
150
151
static bool cap_has_mp_state;
152
153
+static ARMHostCPUFeatures arm_host_cpu_features;
154
+
155
int kvm_arm_vcpu_init(CPUState *cs)
156
{
157
ARMCPU *cpu = ARM_CPU(cs);
158
@@ -XXX,XX +XXX,XX @@ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray)
159
}
160
}
161
162
-static void kvm_arm_host_cpu_class_init(ObjectClass *oc, void *data)
163
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
164
{
165
- ARMHostCPUClass *ahcc = ARM_HOST_CPU_CLASS(oc);
166
+ CPUARMState *env = &cpu->env;
167
168
- /* All we really need to set up for the 'host' CPU
169
- * is the feature bits -- we rely on the fact that the
170
- * various ID register values in ARMCPU are only used for
171
- * TCG CPUs.
172
- */
173
- if (!kvm_arm_get_host_cpu_features(ahcc)) {
174
- fprintf(stderr, "Failed to retrieve host CPU features!\n");
175
- abort();
176
+ if (!arm_host_cpu_features.dtb_compatible) {
177
+ if (!kvm_enabled() ||
178
+ !kvm_arm_get_host_cpu_features(&arm_host_cpu_features)) {
179
+ /* We can't report this error yet, so flag that we need to
180
+ * in arm_cpu_realizefn().
181
+ */
182
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
183
+ cpu->host_cpu_probe_failed = true;
184
+ return;
185
+ }
186
}
187
+
188
+ cpu->kvm_target = arm_host_cpu_features.target;
189
+ cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
190
+ env->features = arm_host_cpu_features.features;
191
}
192
193
static void kvm_arm_host_cpu_initfn(Object *obj)
194
{
195
- ARMHostCPUClass *ahcc = ARM_HOST_CPU_GET_CLASS(obj);
196
ARMCPU *cpu = ARM_CPU(obj);
197
- CPUARMState *env = &cpu->env;
198
199
- cpu->kvm_target = ahcc->target;
200
- cpu->dtb_compatible = ahcc->dtb_compatible;
201
- env->features = ahcc->features;
202
+ kvm_arm_set_cpu_features_from_host(cpu);
203
}
204
205
static const TypeInfo host_arm_cpu_type_info = {
206
@@ -XXX,XX +XXX,XX @@ static const TypeInfo host_arm_cpu_type_info = {
207
.parent = TYPE_ARM_CPU,
208
#endif
209
.instance_init = kvm_arm_host_cpu_initfn,
210
- .class_init = kvm_arm_host_cpu_class_init,
211
- .class_size = sizeof(ARMHostCPUClass),
212
};
213
214
int kvm_arch_init(MachineState *ms, KVMState *s)
215
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
37
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
216
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
217
--- a/target/arm/kvm32.c
39
--- a/target/arm/kvm32.c
218
+++ b/target/arm/kvm32.c
40
+++ b/target/arm/kvm32.c
219
@@ -XXX,XX +XXX,XX @@ static inline void set_feature(uint64_t *features, int feature)
41
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
220
*features |= 1ULL << feature;
42
ahcf->isar.id_isar6 = 0;
221
}
222
223
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
224
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
225
{
226
/* Identify the feature bits corresponding to the host CPU, and
227
* fill out the ARMHostCPUClass fields accordingly. To do this
228
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
229
return false;
230
}
43
}
231
44
232
- ahcc->target = init.target;
45
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
233
+ ahcf->target = init.target;
46
+ ARM_CP15_REG32(0, 0, 1, 2));
234
47
+
235
/* This is not strictly blessed by the device tree binding docs yet,
48
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0,
236
* but in practice the kernel does not care about this string so
49
KVM_REG_ARM | KVM_REG_SIZE_U32 |
237
* there is no point maintaining an KVM_ARM_TARGET_* -> string table.
50
KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0);
51
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
52
* Fortunately there is not yet anything in there that affects migration.
238
*/
53
*/
239
- ahcc->dtb_compatible = "arm,arm-v7";
54
240
+ ahcf->dtb_compatible = "arm,arm-v7";
55
+ /*
241
56
+ * There is no way to read DBGDIDR, because currently 32-bit KVM
242
for (i = 0; i < ARRAY_SIZE(idregs); i++) {
57
+ * doesn't implement debug at all. Leave it at zero.
243
ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &idregs[i]);
58
+ */
244
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
59
+
245
set_feature(&features, ARM_FEATURE_VFP4);
60
kvm_arm_destroy_scratch_host_vcpu(fdarray);
246
}
61
247
62
if (err < 0) {
248
- ahcc->features = features;
249
+ ahcf->features = features;
250
251
return true;
252
}
253
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
63
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
254
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
255
--- a/target/arm/kvm64.c
65
--- a/target/arm/kvm64.c
256
+++ b/target/arm/kvm64.c
66
+++ b/target/arm/kvm64.c
257
@@ -XXX,XX +XXX,XX @@ static inline void unset_feature(uint64_t *features, int feature)
67
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
258
*features &= ~(1ULL << feature);
68
} else {
259
}
69
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1,
260
70
ARM64_SYS_REG(3, 0, 0, 4, 1));
261
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
71
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0,
262
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
72
+ ARM64_SYS_REG(3, 0, 0, 5, 0));
263
{
73
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1,
264
/* Identify the feature bits corresponding to the host CPU, and
74
+ ARM64_SYS_REG(3, 0, 0, 5, 1));
265
* fill out the ARMHostCPUClass fields accordingly. To do this
75
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0,
266
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
76
ARM64_SYS_REG(3, 0, 0, 6, 0));
267
return false;
77
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
78
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
79
* than skipping the reads and leaving 0, as we must avoid
80
* considering the values in every case.
81
*/
82
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
83
+ ARM64_SYS_REG(3, 0, 0, 1, 2));
84
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
85
ARM64_SYS_REG(3, 0, 0, 2, 0));
86
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
87
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
88
ARM64_SYS_REG(3, 0, 0, 3, 1));
89
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2,
90
ARM64_SYS_REG(3, 0, 0, 3, 2));
91
+
92
+ /*
93
+ * DBGDIDR is a bit complicated because the kernel doesn't
94
+ * provide an accessor for it in 64-bit mode, which is what this
95
+ * scratch VM is in, and there's no architected "64-bit sysreg
96
+ * which reads the same as the 32-bit register" the way there is
97
+ * for other ID registers. Instead we synthesize a value from the
98
+ * AArch64 ID_AA64DFR0, the same way the kernel code in
99
+ * arch/arm64/kvm/sys_regs.c:trap_dbgidr() does.
100
+ * We only do this if the CPU supports AArch32 at EL1.
101
+ */
102
+ if (FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL1) >= 2) {
103
+ int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS);
104
+ int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS);
105
+ int ctx_cmps =
106
+ FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS);
107
+ int version = 6; /* ARMv8 debug architecture */
108
+ bool has_el3 =
109
+ !!FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL3);
110
+ uint32_t dbgdidr = 0;
111
+
112
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps);
113
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, BRPS, brps);
114
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, CTX_CMPS, ctx_cmps);
115
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, VERSION, version);
116
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, NSUHD_IMP, has_el3);
117
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, SE_IMP, has_el3);
118
+ dbgdidr |= (1 << 15); /* RES1 bit */
119
+ ahcf->isar.dbgdidr = dbgdidr;
120
+ }
268
}
121
}
269
122
270
- ahcc->target = init.target;
123
sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 0;
271
- ahcc->dtb_compatible = "arm,arm-v8";
272
+ ahcf->target = init.target;
273
+ ahcf->dtb_compatible = "arm,arm-v8";
274
275
kvm_arm_destroy_scratch_host_vcpu(fdarray);
276
277
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
278
set_feature(&features, ARM_FEATURE_AARCH64);
279
set_feature(&features, ARM_FEATURE_PMU);
280
281
- ahcc->features = features;
282
+ ahcf->features = features;
283
284
return true;
285
}
286
--
124
--
287
2.16.2
125
2.20.1
288
126
289
127
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
The ARMv8.1-PMU extension requires:
2
* the evtCount field in PMETYPER<n>_EL0 is 16 bits, not 10
3
* MDCR_EL2.HPMD allows event counting to be disabled at EL2
4
* two new required events, STALL_FRONTEND and STALL_BACKEND
5
* ID register bits in ID_AA64DFR0_EL1 and ID_DFR0
2
6
3
The following interfaces are partially or fully emulated:
7
We already implement the 16-bit evtCount field and the
8
HPMD bit, so all that is missing is the two new events:
9
STALL_FRONTEND
10
"counts every cycle counted by the CPU_CYCLES event on which no
11
operation was issued because there are no operations available
12
to issue to this PE from the frontend"
13
STALL_BACKEND
14
"counts every cycle counted by the CPU_CYCLES event on which no
15
operation was issued because the backend is unable to accept
16
any available operations from the frontend"
4
17
5
* up to 2 Cortex A9 cores (SMP works with PSCI)
18
QEMU never stalls in this sense, so our implementation is trivial:
6
* A7 MPCORE (identical to A15 MPCORE)
19
always return a zero count.
7
* 4 GPTs modules
8
* 7 GPIO controllers
9
* 2 IOMUXC controllers
10
* 1 CCM module
11
* 1 SVNS module
12
* 1 SRC module
13
* 1 GPCv2 controller
14
* 4 eCSPI controllers
15
* 4 I2C controllers
16
* 7 i.MX UART controllers
17
* 2 FlexCAN controllers
18
* 2 Ethernet controllers (FEC)
19
* 3 SD controllers (USDHC)
20
* 4 WDT modules
21
* 1 SDMA module
22
* 1 GPR module
23
* 2 USBMISC modules
24
* 2 ADC modules
25
* 1 PCIe controller
26
20
27
Tested to boot and work with upstream Linux (4.13+) guest.
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Message-id: 20200214175116.9164-14-peter.maydell@linaro.org
24
---
25
target/arm/helper.c | 32 ++++++++++++++++++++++++++++++--
26
1 file changed, 30 insertions(+), 2 deletions(-)
28
27
29
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
31
[PMM: folded a couple of long lines]
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
34
hw/arm/Makefile.objs | 1 +
35
include/hw/arm/fsl-imx7.h | 222 +++++++++++++++
36
hw/arm/fsl-imx7.c | 582 ++++++++++++++++++++++++++++++++++++++++
37
default-configs/arm-softmmu.mak | 1 +
38
4 files changed, 806 insertions(+)
39
create mode 100644 include/hw/arm/fsl-imx7.h
40
create mode 100644 hw/arm/fsl-imx7.c
41
42
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
43
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/Makefile.objs
30
--- a/target/arm/helper.c
45
+++ b/hw/arm/Makefile.objs
31
+++ b/target/arm/helper.c
46
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2.o
32
@@ -XXX,XX +XXX,XX @@ static int64_t instructions_ns_per(uint64_t icount)
47
obj-$(CONFIG_MPS2) += mps2-tz.o
33
}
48
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
34
#endif
49
obj-$(CONFIG_IOTKIT) += iotkit.o
35
50
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
36
+static bool pmu_8_1_events_supported(CPUARMState *env)
51
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
52
new file mode 100644
53
index XXXXXXX..XXXXXXX
54
--- /dev/null
55
+++ b/include/hw/arm/fsl-imx7.h
56
@@ -XXX,XX +XXX,XX @@
57
+/*
58
+ * Copyright (c) 2018, Impinj, Inc.
59
+ *
60
+ * i.MX7 SoC definitions
61
+ *
62
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
63
+ *
64
+ * This program is free software; you can redistribute it and/or modify
65
+ * it under the terms of the GNU General Public License as published by
66
+ * the Free Software Foundation; either version 2 of the License, or
67
+ * (at your option) any later version.
68
+ *
69
+ * This program is distributed in the hope that it will be useful,
70
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
71
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72
+ * GNU General Public License for more details.
73
+ */
74
+
75
+#ifndef FSL_IMX7_H
76
+#define FSL_IMX7_H
77
+
78
+#include "hw/arm/arm.h"
79
+#include "hw/cpu/a15mpcore.h"
80
+#include "hw/intc/imx_gpcv2.h"
81
+#include "hw/misc/imx7_ccm.h"
82
+#include "hw/misc/imx7_snvs.h"
83
+#include "hw/misc/imx7_gpr.h"
84
+#include "hw/misc/imx6_src.h"
85
+#include "hw/misc/imx2_wdt.h"
86
+#include "hw/gpio/imx_gpio.h"
87
+#include "hw/char/imx_serial.h"
88
+#include "hw/timer/imx_gpt.h"
89
+#include "hw/timer/imx_epit.h"
90
+#include "hw/i2c/imx_i2c.h"
91
+#include "hw/gpio/imx_gpio.h"
92
+#include "hw/sd/sdhci.h"
93
+#include "hw/ssi/imx_spi.h"
94
+#include "hw/net/imx_fec.h"
95
+#include "hw/pci-host/designware.h"
96
+#include "hw/usb/chipidea.h"
97
+#include "exec/memory.h"
98
+#include "cpu.h"
99
+
100
+#define TYPE_FSL_IMX7 "fsl,imx7"
101
+#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7)
102
+
103
+enum FslIMX7Configuration {
104
+ FSL_IMX7_NUM_CPUS = 2,
105
+ FSL_IMX7_NUM_UARTS = 7,
106
+ FSL_IMX7_NUM_ETHS = 2,
107
+ FSL_IMX7_ETH_NUM_TX_RINGS = 3,
108
+ FSL_IMX7_NUM_USDHCS = 3,
109
+ FSL_IMX7_NUM_WDTS = 4,
110
+ FSL_IMX7_NUM_GPTS = 4,
111
+ FSL_IMX7_NUM_IOMUXCS = 2,
112
+ FSL_IMX7_NUM_GPIOS = 7,
113
+ FSL_IMX7_NUM_I2CS = 4,
114
+ FSL_IMX7_NUM_ECSPIS = 4,
115
+ FSL_IMX7_NUM_USBS = 3,
116
+ FSL_IMX7_NUM_ADCS = 2,
117
+};
118
+
119
+typedef struct FslIMX7State {
120
+ /*< private >*/
121
+ DeviceState parent_obj;
122
+
123
+ /*< public >*/
124
+ ARMCPU cpu[FSL_IMX7_NUM_CPUS];
125
+ A15MPPrivState a7mpcore;
126
+ IMXGPTState gpt[FSL_IMX7_NUM_GPTS];
127
+ IMXGPIOState gpio[FSL_IMX7_NUM_GPIOS];
128
+ IMX7CCMState ccm;
129
+ IMX7AnalogState analog;
130
+ IMX7SNVSState snvs;
131
+ IMXGPCv2State gpcv2;
132
+ IMXSPIState spi[FSL_IMX7_NUM_ECSPIS];
133
+ IMXI2CState i2c[FSL_IMX7_NUM_I2CS];
134
+ IMXSerialState uart[FSL_IMX7_NUM_UARTS];
135
+ IMXFECState eth[FSL_IMX7_NUM_ETHS];
136
+ SDHCIState usdhc[FSL_IMX7_NUM_USDHCS];
137
+ IMX2WdtState wdt[FSL_IMX7_NUM_WDTS];
138
+ IMX7GPRState gpr;
139
+ ChipideaState usb[FSL_IMX7_NUM_USBS];
140
+ DesignwarePCIEHost pcie;
141
+} FslIMX7State;
142
+
143
+enum FslIMX7MemoryMap {
144
+ FSL_IMX7_MMDC_ADDR = 0x80000000,
145
+ FSL_IMX7_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL,
146
+
147
+ FSL_IMX7_GPIO1_ADDR = 0x30200000,
148
+ FSL_IMX7_GPIO2_ADDR = 0x30210000,
149
+ FSL_IMX7_GPIO3_ADDR = 0x30220000,
150
+ FSL_IMX7_GPIO4_ADDR = 0x30230000,
151
+ FSL_IMX7_GPIO5_ADDR = 0x30240000,
152
+ FSL_IMX7_GPIO6_ADDR = 0x30250000,
153
+ FSL_IMX7_GPIO7_ADDR = 0x30260000,
154
+
155
+ FSL_IMX7_IOMUXC_LPSR_GPR_ADDR = 0x30270000,
156
+
157
+ FSL_IMX7_WDOG1_ADDR = 0x30280000,
158
+ FSL_IMX7_WDOG2_ADDR = 0x30290000,
159
+ FSL_IMX7_WDOG3_ADDR = 0x302A0000,
160
+ FSL_IMX7_WDOG4_ADDR = 0x302B0000,
161
+
162
+ FSL_IMX7_IOMUXC_LPSR_ADDR = 0x302C0000,
163
+
164
+ FSL_IMX7_GPT1_ADDR = 0x302D0000,
165
+ FSL_IMX7_GPT2_ADDR = 0x302E0000,
166
+ FSL_IMX7_GPT3_ADDR = 0x302F0000,
167
+ FSL_IMX7_GPT4_ADDR = 0x30300000,
168
+
169
+ FSL_IMX7_IOMUXC_ADDR = 0x30330000,
170
+ FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000,
171
+ FSL_IMX7_IOMUXCn_SIZE = 0x1000,
172
+
173
+ FSL_IMX7_ANALOG_ADDR = 0x30360000,
174
+ FSL_IMX7_SNVS_ADDR = 0x30370000,
175
+ FSL_IMX7_CCM_ADDR = 0x30380000,
176
+
177
+ FSL_IMX7_SRC_ADDR = 0x30390000,
178
+ FSL_IMX7_SRC_SIZE = 0x1000,
179
+
180
+ FSL_IMX7_ADC1_ADDR = 0x30610000,
181
+ FSL_IMX7_ADC2_ADDR = 0x30620000,
182
+ FSL_IMX7_ADCn_SIZE = 0x1000,
183
+
184
+ FSL_IMX7_GPC_ADDR = 0x303A0000,
185
+
186
+ FSL_IMX7_I2C1_ADDR = 0x30A20000,
187
+ FSL_IMX7_I2C2_ADDR = 0x30A30000,
188
+ FSL_IMX7_I2C3_ADDR = 0x30A40000,
189
+ FSL_IMX7_I2C4_ADDR = 0x30A50000,
190
+
191
+ FSL_IMX7_ECSPI1_ADDR = 0x30820000,
192
+ FSL_IMX7_ECSPI2_ADDR = 0x30830000,
193
+ FSL_IMX7_ECSPI3_ADDR = 0x30840000,
194
+ FSL_IMX7_ECSPI4_ADDR = 0x30630000,
195
+
196
+ FSL_IMX7_LCDIF_ADDR = 0x30730000,
197
+ FSL_IMX7_LCDIF_SIZE = 0x1000,
198
+
199
+ FSL_IMX7_UART1_ADDR = 0x30860000,
200
+ /*
201
+ * Some versions of the reference manual claim that UART2 is @
202
+ * 0x30870000, but experiments with HW + DT files in upstream
203
+ * Linux kernel show that not to be true and that block is
204
+ * acutally located @ 0x30890000
205
+ */
206
+ FSL_IMX7_UART2_ADDR = 0x30890000,
207
+ FSL_IMX7_UART3_ADDR = 0x30880000,
208
+ FSL_IMX7_UART4_ADDR = 0x30A60000,
209
+ FSL_IMX7_UART5_ADDR = 0x30A70000,
210
+ FSL_IMX7_UART6_ADDR = 0x30A80000,
211
+ FSL_IMX7_UART7_ADDR = 0x30A90000,
212
+
213
+ FSL_IMX7_ENET1_ADDR = 0x30BE0000,
214
+ FSL_IMX7_ENET2_ADDR = 0x30BF0000,
215
+
216
+ FSL_IMX7_USB1_ADDR = 0x30B10000,
217
+ FSL_IMX7_USBMISC1_ADDR = 0x30B10200,
218
+ FSL_IMX7_USB2_ADDR = 0x30B20000,
219
+ FSL_IMX7_USBMISC2_ADDR = 0x30B20200,
220
+ FSL_IMX7_USB3_ADDR = 0x30B30000,
221
+ FSL_IMX7_USBMISC3_ADDR = 0x30B30200,
222
+ FSL_IMX7_USBMISCn_SIZE = 0x200,
223
+
224
+ FSL_IMX7_USDHC1_ADDR = 0x30B40000,
225
+ FSL_IMX7_USDHC2_ADDR = 0x30B50000,
226
+ FSL_IMX7_USDHC3_ADDR = 0x30B60000,
227
+
228
+ FSL_IMX7_SDMA_ADDR = 0x30BD0000,
229
+ FSL_IMX7_SDMA_SIZE = 0x1000,
230
+
231
+ FSL_IMX7_A7MPCORE_ADDR = 0x31000000,
232
+ FSL_IMX7_A7MPCORE_DAP_ADDR = 0x30000000,
233
+
234
+ FSL_IMX7_PCIE_REG_ADDR = 0x33800000,
235
+ FSL_IMX7_PCIE_REG_SIZE = 16 * 1024,
236
+
237
+ FSL_IMX7_GPR_ADDR = 0x30340000,
238
+};
239
+
240
+enum FslIMX7IRQs {
241
+ FSL_IMX7_USDHC1_IRQ = 22,
242
+ FSL_IMX7_USDHC2_IRQ = 23,
243
+ FSL_IMX7_USDHC3_IRQ = 24,
244
+
245
+ FSL_IMX7_UART1_IRQ = 26,
246
+ FSL_IMX7_UART2_IRQ = 27,
247
+ FSL_IMX7_UART3_IRQ = 28,
248
+ FSL_IMX7_UART4_IRQ = 29,
249
+ FSL_IMX7_UART5_IRQ = 30,
250
+ FSL_IMX7_UART6_IRQ = 16,
251
+
252
+ FSL_IMX7_ECSPI1_IRQ = 31,
253
+ FSL_IMX7_ECSPI2_IRQ = 32,
254
+ FSL_IMX7_ECSPI3_IRQ = 33,
255
+ FSL_IMX7_ECSPI4_IRQ = 34,
256
+
257
+ FSL_IMX7_I2C1_IRQ = 35,
258
+ FSL_IMX7_I2C2_IRQ = 36,
259
+ FSL_IMX7_I2C3_IRQ = 37,
260
+ FSL_IMX7_I2C4_IRQ = 38,
261
+
262
+ FSL_IMX7_USB1_IRQ = 43,
263
+ FSL_IMX7_USB2_IRQ = 42,
264
+ FSL_IMX7_USB3_IRQ = 40,
265
+
266
+ FSL_IMX7_PCI_INTA_IRQ = 122,
267
+ FSL_IMX7_PCI_INTB_IRQ = 123,
268
+ FSL_IMX7_PCI_INTC_IRQ = 124,
269
+ FSL_IMX7_PCI_INTD_IRQ = 125,
270
+
271
+ FSL_IMX7_UART7_IRQ = 126,
272
+
273
+#define FSL_IMX7_ENET_IRQ(i, n) ((n) + ((i) ? 100 : 118))
274
+
275
+ FSL_IMX7_MAX_IRQ = 128,
276
+};
277
+
278
+#endif /* FSL_IMX7_H */
279
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
280
new file mode 100644
281
index XXXXXXX..XXXXXXX
282
--- /dev/null
283
+++ b/hw/arm/fsl-imx7.c
284
@@ -XXX,XX +XXX,XX @@
285
+/*
286
+ * Copyright (c) 2018, Impinj, Inc.
287
+ *
288
+ * i.MX7 SoC definitions
289
+ *
290
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
291
+ *
292
+ * Based on hw/arm/fsl-imx6.c
293
+ *
294
+ * This program is free software; you can redistribute it and/or modify
295
+ * it under the terms of the GNU General Public License as published by
296
+ * the Free Software Foundation; either version 2 of the License, or
297
+ * (at your option) any later version.
298
+ *
299
+ * This program is distributed in the hope that it will be useful,
300
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
301
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
302
+ * GNU General Public License for more details.
303
+ */
304
+
305
+#include "qemu/osdep.h"
306
+#include "qapi/error.h"
307
+#include "qemu-common.h"
308
+#include "hw/arm/fsl-imx7.h"
309
+#include "hw/misc/unimp.h"
310
+#include "sysemu/sysemu.h"
311
+#include "qemu/error-report.h"
312
+
313
+#define NAME_SIZE 20
314
+
315
+static void fsl_imx7_init(Object *obj)
316
+{
37
+{
317
+ BusState *sysbus = sysbus_get_default();
38
+ /* For events which are supported in any v8.1 PMU */
318
+ FslIMX7State *s = FSL_IMX7(obj);
39
+ return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
319
+ char name[NAME_SIZE];
320
+ int i;
321
+
322
+ if (smp_cpus > FSL_IMX7_NUM_CPUS) {
323
+ error_report("%s: Only %d CPUs are supported (%d requested)",
324
+ TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus);
325
+ exit(1);
326
+ }
327
+
328
+ for (i = 0; i < smp_cpus; i++) {
329
+ object_initialize(&s->cpu[i], sizeof(s->cpu[i]),
330
+ ARM_CPU_TYPE_NAME("cortex-a7"));
331
+ snprintf(name, NAME_SIZE, "cpu%d", i);
332
+ object_property_add_child(obj, name, OBJECT(&s->cpu[i]),
333
+ &error_fatal);
334
+ }
335
+
336
+ /*
337
+ * A7MPCORE
338
+ */
339
+ object_initialize(&s->a7mpcore, sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
340
+ qdev_set_parent_bus(DEVICE(&s->a7mpcore), sysbus);
341
+ object_property_add_child(obj, "a7mpcore",
342
+ OBJECT(&s->a7mpcore), &error_fatal);
343
+
344
+ /*
345
+ * GPIOs 1 to 7
346
+ */
347
+ for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
348
+ object_initialize(&s->gpio[i], sizeof(s->gpio[i]),
349
+ TYPE_IMX_GPIO);
350
+ qdev_set_parent_bus(DEVICE(&s->gpio[i]), sysbus);
351
+ snprintf(name, NAME_SIZE, "gpio%d", i);
352
+ object_property_add_child(obj, name,
353
+ OBJECT(&s->gpio[i]), &error_fatal);
354
+ }
355
+
356
+ /*
357
+ * GPT1, 2, 3, 4
358
+ */
359
+ for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
360
+ object_initialize(&s->gpt[i], sizeof(s->gpt[i]), TYPE_IMX7_GPT);
361
+ qdev_set_parent_bus(DEVICE(&s->gpt[i]), sysbus);
362
+ snprintf(name, NAME_SIZE, "gpt%d", i);
363
+ object_property_add_child(obj, name, OBJECT(&s->gpt[i]),
364
+ &error_fatal);
365
+ }
366
+
367
+ /*
368
+ * CCM
369
+ */
370
+ object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX7_CCM);
371
+ qdev_set_parent_bus(DEVICE(&s->ccm), sysbus);
372
+ object_property_add_child(obj, "ccm", OBJECT(&s->ccm), &error_fatal);
373
+
374
+ /*
375
+ * Analog
376
+ */
377
+ object_initialize(&s->analog, sizeof(s->analog), TYPE_IMX7_ANALOG);
378
+ qdev_set_parent_bus(DEVICE(&s->analog), sysbus);
379
+ object_property_add_child(obj, "analog", OBJECT(&s->analog), &error_fatal);
380
+
381
+ /*
382
+ * GPCv2
383
+ */
384
+ object_initialize(&s->gpcv2, sizeof(s->gpcv2), TYPE_IMX_GPCV2);
385
+ qdev_set_parent_bus(DEVICE(&s->gpcv2), sysbus);
386
+ object_property_add_child(obj, "gpcv2", OBJECT(&s->gpcv2), &error_fatal);
387
+
388
+ for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
389
+ object_initialize(&s->spi[i], sizeof(s->spi[i]), TYPE_IMX_SPI);
390
+ qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
391
+ snprintf(name, NAME_SIZE, "spi%d", i + 1);
392
+ object_property_add_child(obj, name, OBJECT(&s->spi[i]), NULL);
393
+ }
394
+
395
+
396
+ for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
397
+ object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
398
+ qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
399
+ snprintf(name, NAME_SIZE, "i2c%d", i + 1);
400
+ object_property_add_child(obj, name, OBJECT(&s->i2c[i]), NULL);
401
+ }
402
+
403
+ /*
404
+ * UART
405
+ */
406
+ for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
407
+ object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
408
+ qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus);
409
+ snprintf(name, NAME_SIZE, "uart%d", i);
410
+ object_property_add_child(obj, name, OBJECT(&s->uart[i]),
411
+ &error_fatal);
412
+ }
413
+
414
+ /*
415
+ * Ethernet
416
+ */
417
+ for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
418
+ object_initialize(&s->eth[i], sizeof(s->eth[i]), TYPE_IMX_ENET);
419
+ qdev_set_parent_bus(DEVICE(&s->eth[i]), sysbus);
420
+ snprintf(name, NAME_SIZE, "eth%d", i);
421
+ object_property_add_child(obj, name, OBJECT(&s->eth[i]),
422
+ &error_fatal);
423
+ }
424
+
425
+ /*
426
+ * SDHCI
427
+ */
428
+ for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
429
+ object_initialize(&s->usdhc[i], sizeof(s->usdhc[i]),
430
+ TYPE_IMX_USDHC);
431
+ qdev_set_parent_bus(DEVICE(&s->usdhc[i]), sysbus);
432
+ snprintf(name, NAME_SIZE, "usdhc%d", i);
433
+ object_property_add_child(obj, name, OBJECT(&s->usdhc[i]),
434
+ &error_fatal);
435
+ }
436
+
437
+ /*
438
+ * SNVS
439
+ */
440
+ object_initialize(&s->snvs, sizeof(s->snvs), TYPE_IMX7_SNVS);
441
+ qdev_set_parent_bus(DEVICE(&s->snvs), sysbus);
442
+ object_property_add_child(obj, "snvs", OBJECT(&s->snvs), &error_fatal);
443
+
444
+ /*
445
+ * Watchdog
446
+ */
447
+ for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
448
+ object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_IMX2_WDT);
449
+ qdev_set_parent_bus(DEVICE(&s->wdt[i]), sysbus);
450
+ snprintf(name, NAME_SIZE, "wdt%d", i);
451
+ object_property_add_child(obj, name, OBJECT(&s->wdt[i]),
452
+ &error_fatal);
453
+ }
454
+
455
+ /*
456
+ * GPR
457
+ */
458
+ object_initialize(&s->gpr, sizeof(s->gpr), TYPE_IMX7_GPR);
459
+ qdev_set_parent_bus(DEVICE(&s->gpr), sysbus);
460
+ object_property_add_child(obj, "gpr", OBJECT(&s->gpr), &error_fatal);
461
+
462
+ object_initialize(&s->pcie, sizeof(s->pcie), TYPE_DESIGNWARE_PCIE_HOST);
463
+ qdev_set_parent_bus(DEVICE(&s->pcie), sysbus);
464
+ object_property_add_child(obj, "pcie", OBJECT(&s->pcie), &error_fatal);
465
+
466
+ for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
467
+ object_initialize(&s->usb[i],
468
+ sizeof(s->usb[i]), TYPE_CHIPIDEA);
469
+ qdev_set_parent_bus(DEVICE(&s->usb[i]), sysbus);
470
+ snprintf(name, NAME_SIZE, "usb%d", i);
471
+ object_property_add_child(obj, name,
472
+ OBJECT(&s->usb[i]), &error_fatal);
473
+ }
474
+}
40
+}
475
+
41
+
476
+static void fsl_imx7_realize(DeviceState *dev, Error **errp)
42
+static uint64_t zero_event_get_count(CPUARMState *env)
477
+{
43
+{
478
+ FslIMX7State *s = FSL_IMX7(dev);
44
+ /* For events which on QEMU never fire, so their count is always zero */
479
+ Object *o;
45
+ return 0;
480
+ int i;
481
+ qemu_irq irq;
482
+ char name[NAME_SIZE];
483
+
484
+ for (i = 0; i < smp_cpus; i++) {
485
+ o = OBJECT(&s->cpu[i]);
486
+
487
+ object_property_set_int(o, QEMU_PSCI_CONDUIT_SMC,
488
+ "psci-conduit", &error_abort);
489
+
490
+ /* On uniprocessor, the CBAR is set to 0 */
491
+ if (smp_cpus > 1) {
492
+ object_property_set_int(o, FSL_IMX7_A7MPCORE_ADDR,
493
+ "reset-cbar", &error_abort);
494
+ }
495
+
496
+ if (i) {
497
+ /* Secondary CPUs start in PSCI powered-down state */
498
+ object_property_set_bool(o, true,
499
+ "start-powered-off", &error_abort);
500
+ }
501
+
502
+ object_property_set_bool(o, true, "realized", &error_abort);
503
+ }
504
+
505
+ /*
506
+ * A7MPCORE
507
+ */
508
+ object_property_set_int(OBJECT(&s->a7mpcore), smp_cpus, "num-cpu",
509
+ &error_abort);
510
+ object_property_set_int(OBJECT(&s->a7mpcore),
511
+ FSL_IMX7_MAX_IRQ + GIC_INTERNAL,
512
+ "num-irq", &error_abort);
513
+
514
+ object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
515
+ &error_abort);
516
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX7_A7MPCORE_ADDR);
517
+
518
+ for (i = 0; i < smp_cpus; i++) {
519
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
520
+ DeviceState *d = DEVICE(qemu_get_cpu(i));
521
+
522
+ irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
523
+ sysbus_connect_irq(sbd, i, irq);
524
+ irq = qdev_get_gpio_in(d, ARM_CPU_FIQ);
525
+ sysbus_connect_irq(sbd, i + smp_cpus, irq);
526
+ }
527
+
528
+ /*
529
+ * A7MPCORE DAP
530
+ */
531
+ create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
532
+ 0x100000);
533
+
534
+ /*
535
+ * GPT1, 2, 3, 4
536
+ */
537
+ for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
538
+ static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
539
+ FSL_IMX7_GPT1_ADDR,
540
+ FSL_IMX7_GPT2_ADDR,
541
+ FSL_IMX7_GPT3_ADDR,
542
+ FSL_IMX7_GPT4_ADDR,
543
+ };
544
+
545
+ s->gpt[i].ccm = IMX_CCM(&s->ccm);
546
+ object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized",
547
+ &error_abort);
548
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]);
549
+ }
550
+
551
+ for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
552
+ static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
553
+ FSL_IMX7_GPIO1_ADDR,
554
+ FSL_IMX7_GPIO2_ADDR,
555
+ FSL_IMX7_GPIO3_ADDR,
556
+ FSL_IMX7_GPIO4_ADDR,
557
+ FSL_IMX7_GPIO5_ADDR,
558
+ FSL_IMX7_GPIO6_ADDR,
559
+ FSL_IMX7_GPIO7_ADDR,
560
+ };
561
+
562
+ object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized",
563
+ &error_abort);
564
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, FSL_IMX7_GPIOn_ADDR[i]);
565
+ }
566
+
567
+ /*
568
+ * IOMUXC and IOMUXC_LPSR
569
+ */
570
+ for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
571
+ static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
572
+ FSL_IMX7_IOMUXC_ADDR,
573
+ FSL_IMX7_IOMUXC_LPSR_ADDR,
574
+ };
575
+
576
+ snprintf(name, NAME_SIZE, "iomuxc%d", i);
577
+ create_unimplemented_device(name, FSL_IMX7_IOMUXCn_ADDR[i],
578
+ FSL_IMX7_IOMUXCn_SIZE);
579
+ }
580
+
581
+ /*
582
+ * CCM
583
+ */
584
+ object_property_set_bool(OBJECT(&s->ccm), true, "realized", &error_abort);
585
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX7_CCM_ADDR);
586
+
587
+ /*
588
+ * Analog
589
+ */
590
+ object_property_set_bool(OBJECT(&s->analog), true, "realized",
591
+ &error_abort);
592
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->analog), 0, FSL_IMX7_ANALOG_ADDR);
593
+
594
+ /*
595
+ * GPCv2
596
+ */
597
+ object_property_set_bool(OBJECT(&s->gpcv2), true,
598
+ "realized", &error_abort);
599
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX7_GPC_ADDR);
600
+
601
+ /* Initialize all ECSPI */
602
+ for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
603
+ static const hwaddr FSL_IMX7_SPIn_ADDR[FSL_IMX7_NUM_ECSPIS] = {
604
+ FSL_IMX7_ECSPI1_ADDR,
605
+ FSL_IMX7_ECSPI2_ADDR,
606
+ FSL_IMX7_ECSPI3_ADDR,
607
+ FSL_IMX7_ECSPI4_ADDR,
608
+ };
609
+
610
+ static const hwaddr FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
611
+ FSL_IMX7_ECSPI1_IRQ,
612
+ FSL_IMX7_ECSPI2_IRQ,
613
+ FSL_IMX7_ECSPI3_IRQ,
614
+ FSL_IMX7_ECSPI4_IRQ,
615
+ };
616
+
617
+ /* Initialize the SPI */
618
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
619
+ &error_abort);
620
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
621
+ FSL_IMX7_SPIn_ADDR[i]);
622
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
623
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
624
+ FSL_IMX7_SPIn_IRQ[i]));
625
+ }
626
+
627
+ for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
628
+ static const hwaddr FSL_IMX7_I2Cn_ADDR[FSL_IMX7_NUM_I2CS] = {
629
+ FSL_IMX7_I2C1_ADDR,
630
+ FSL_IMX7_I2C2_ADDR,
631
+ FSL_IMX7_I2C3_ADDR,
632
+ FSL_IMX7_I2C4_ADDR,
633
+ };
634
+
635
+ static const hwaddr FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
636
+ FSL_IMX7_I2C1_IRQ,
637
+ FSL_IMX7_I2C2_IRQ,
638
+ FSL_IMX7_I2C3_IRQ,
639
+ FSL_IMX7_I2C4_IRQ,
640
+ };
641
+
642
+ object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized",
643
+ &error_abort);
644
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX7_I2Cn_ADDR[i]);
645
+
646
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
647
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
648
+ FSL_IMX7_I2Cn_IRQ[i]));
649
+ }
650
+
651
+ /*
652
+ * UART
653
+ */
654
+ for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
655
+ static const hwaddr FSL_IMX7_UARTn_ADDR[FSL_IMX7_NUM_UARTS] = {
656
+ FSL_IMX7_UART1_ADDR,
657
+ FSL_IMX7_UART2_ADDR,
658
+ FSL_IMX7_UART3_ADDR,
659
+ FSL_IMX7_UART4_ADDR,
660
+ FSL_IMX7_UART5_ADDR,
661
+ FSL_IMX7_UART6_ADDR,
662
+ FSL_IMX7_UART7_ADDR,
663
+ };
664
+
665
+ static const int FSL_IMX7_UARTn_IRQ[FSL_IMX7_NUM_UARTS] = {
666
+ FSL_IMX7_UART1_IRQ,
667
+ FSL_IMX7_UART2_IRQ,
668
+ FSL_IMX7_UART3_IRQ,
669
+ FSL_IMX7_UART4_IRQ,
670
+ FSL_IMX7_UART5_IRQ,
671
+ FSL_IMX7_UART6_IRQ,
672
+ FSL_IMX7_UART7_IRQ,
673
+ };
674
+
675
+
676
+ if (i < MAX_SERIAL_PORTS) {
677
+ qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hds[i]);
678
+ }
679
+
680
+ object_property_set_bool(OBJECT(&s->uart[i]), true, "realized",
681
+ &error_abort);
682
+
683
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, FSL_IMX7_UARTn_ADDR[i]);
684
+
685
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_UARTn_IRQ[i]);
686
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, irq);
687
+ }
688
+
689
+ /*
690
+ * Ethernet
691
+ */
692
+ for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
693
+ static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
694
+ FSL_IMX7_ENET1_ADDR,
695
+ FSL_IMX7_ENET2_ADDR,
696
+ };
697
+
698
+ object_property_set_uint(OBJECT(&s->eth[i]), FSL_IMX7_ETH_NUM_TX_RINGS,
699
+ "tx-ring-num", &error_abort);
700
+ qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
701
+ object_property_set_bool(OBJECT(&s->eth[i]), true, "realized",
702
+ &error_abort);
703
+
704
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, FSL_IMX7_ENETn_ADDR[i]);
705
+
706
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 0));
707
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, irq);
708
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 3));
709
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, irq);
710
+ }
711
+
712
+ /*
713
+ * USDHC
714
+ */
715
+ for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
716
+ static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
717
+ FSL_IMX7_USDHC1_ADDR,
718
+ FSL_IMX7_USDHC2_ADDR,
719
+ FSL_IMX7_USDHC3_ADDR,
720
+ };
721
+
722
+ static const int FSL_IMX7_USDHCn_IRQ[FSL_IMX7_NUM_USDHCS] = {
723
+ FSL_IMX7_USDHC1_IRQ,
724
+ FSL_IMX7_USDHC2_IRQ,
725
+ FSL_IMX7_USDHC3_IRQ,
726
+ };
727
+
728
+ object_property_set_bool(OBJECT(&s->usdhc[i]), true, "realized",
729
+ &error_abort);
730
+
731
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
732
+ FSL_IMX7_USDHCn_ADDR[i]);
733
+
734
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USDHCn_IRQ[i]);
735
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, irq);
736
+ }
737
+
738
+ /*
739
+ * SNVS
740
+ */
741
+ object_property_set_bool(OBJECT(&s->snvs), true, "realized", &error_abort);
742
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_ADDR);
743
+
744
+ /*
745
+ * SRC
746
+ */
747
+ create_unimplemented_device("sdma", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
748
+
749
+ /*
750
+ * Watchdog
751
+ */
752
+ for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
753
+ static const hwaddr FSL_IMX7_WDOGn_ADDR[FSL_IMX7_NUM_WDTS] = {
754
+ FSL_IMX7_WDOG1_ADDR,
755
+ FSL_IMX7_WDOG2_ADDR,
756
+ FSL_IMX7_WDOG3_ADDR,
757
+ FSL_IMX7_WDOG4_ADDR,
758
+ };
759
+
760
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
761
+ &error_abort);
762
+
763
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX7_WDOGn_ADDR[i]);
764
+ }
765
+
766
+ /*
767
+ * SDMA
768
+ */
769
+ create_unimplemented_device("sdma", FSL_IMX7_SDMA_ADDR, FSL_IMX7_SDMA_SIZE);
770
+
771
+
772
+ object_property_set_bool(OBJECT(&s->gpr), true, "realized",
773
+ &error_abort);
774
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_GPR_ADDR);
775
+
776
+ object_property_set_bool(OBJECT(&s->pcie), true,
777
+ "realized", &error_abort);
778
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
779
+
780
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ);
781
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
782
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ);
783
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
784
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ);
785
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
786
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ);
787
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
788
+
789
+
790
+ for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
791
+ static const hwaddr FSL_IMX7_USBMISCn_ADDR[FSL_IMX7_NUM_USBS] = {
792
+ FSL_IMX7_USBMISC1_ADDR,
793
+ FSL_IMX7_USBMISC2_ADDR,
794
+ FSL_IMX7_USBMISC3_ADDR,
795
+ };
796
+
797
+ static const hwaddr FSL_IMX7_USBn_ADDR[FSL_IMX7_NUM_USBS] = {
798
+ FSL_IMX7_USB1_ADDR,
799
+ FSL_IMX7_USB2_ADDR,
800
+ FSL_IMX7_USB3_ADDR,
801
+ };
802
+
803
+ static const hwaddr FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
804
+ FSL_IMX7_USB1_IRQ,
805
+ FSL_IMX7_USB2_IRQ,
806
+ FSL_IMX7_USB3_IRQ,
807
+ };
808
+
809
+ object_property_set_bool(OBJECT(&s->usb[i]), true, "realized",
810
+ &error_abort);
811
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
812
+ FSL_IMX7_USBn_ADDR[i]);
813
+
814
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USBn_IRQ[i]);
815
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0, irq);
816
+
817
+ snprintf(name, NAME_SIZE, "usbmisc%d", i);
818
+ create_unimplemented_device(name, FSL_IMX7_USBMISCn_ADDR[i],
819
+ FSL_IMX7_USBMISCn_SIZE);
820
+ }
821
+
822
+ /*
823
+ * ADCs
824
+ */
825
+ for (i = 0; i < FSL_IMX7_NUM_ADCS; i++) {
826
+ static const hwaddr FSL_IMX7_ADCn_ADDR[FSL_IMX7_NUM_ADCS] = {
827
+ FSL_IMX7_ADC1_ADDR,
828
+ FSL_IMX7_ADC2_ADDR,
829
+ };
830
+
831
+ snprintf(name, NAME_SIZE, "adc%d", i);
832
+ create_unimplemented_device(name, FSL_IMX7_ADCn_ADDR[i],
833
+ FSL_IMX7_ADCn_SIZE);
834
+ }
835
+
836
+ /*
837
+ * LCD
838
+ */
839
+ create_unimplemented_device("lcdif", FSL_IMX7_LCDIF_ADDR,
840
+ FSL_IMX7_LCDIF_SIZE);
841
+}
46
+}
842
+
47
+
843
+static void fsl_imx7_class_init(ObjectClass *oc, void *data)
48
+static int64_t zero_event_ns_per(uint64_t cycles)
844
+{
49
+{
845
+ DeviceClass *dc = DEVICE_CLASS(oc);
50
+ /* An event which never fires can never overflow */
846
+
51
+ return -1;
847
+ dc->realize = fsl_imx7_realize;
848
+
849
+ /* Reason: Uses serial_hds and nd_table in realize() directly */
850
+ dc->user_creatable = false;
851
+ dc->desc = "i.MX7 SOC";
852
+}
52
+}
853
+
53
+
854
+static const TypeInfo fsl_imx7_type_info = {
54
static const pm_event pm_events[] = {
855
+ .name = TYPE_FSL_IMX7,
55
{ .number = 0x000, /* SW_INCR */
856
+ .parent = TYPE_DEVICE,
56
.supported = event_always_supported,
857
+ .instance_size = sizeof(FslIMX7State),
57
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
858
+ .instance_init = fsl_imx7_init,
58
.supported = event_always_supported,
859
+ .class_init = fsl_imx7_class_init,
59
.get_count = cycles_get_count,
860
+};
60
.ns_per_count = cycles_ns_per,
861
+
61
- }
862
+static void fsl_imx7_register_types(void)
62
+ },
863
+{
63
#endif
864
+ type_register_static(&fsl_imx7_type_info);
64
+ { .number = 0x023, /* STALL_FRONTEND */
865
+}
65
+ .supported = pmu_8_1_events_supported,
866
+type_init(fsl_imx7_register_types)
66
+ .get_count = zero_event_get_count,
867
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
67
+ .ns_per_count = zero_event_ns_per,
868
index XXXXXXX..XXXXXXX 100644
68
+ },
869
--- a/default-configs/arm-softmmu.mak
69
+ { .number = 0x024, /* STALL_BACKEND */
870
+++ b/default-configs/arm-softmmu.mak
70
+ .supported = pmu_8_1_events_supported,
871
@@ -XXX,XX +XXX,XX @@ CONFIG_ALLWINNER_A10=y
71
+ .get_count = zero_event_get_count,
872
CONFIG_FSL_IMX6=y
72
+ .ns_per_count = zero_event_ns_per,
873
CONFIG_FSL_IMX31=y
73
+ },
874
CONFIG_FSL_IMX25=y
74
};
875
+CONFIG_FSL_IMX7=y
75
876
76
/*
877
CONFIG_IMX_I2C=y
77
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
78
* should first be updated to something sparse instead of the current
79
* supported_event_map[] array.
80
*/
81
-#define MAX_EVENT_ID 0x11
82
+#define MAX_EVENT_ID 0x24
83
#define UNSUPPORTED_EVENT UINT16_MAX
84
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
878
85
879
--
86
--
880
2.16.2
87
2.20.1
881
88
882
89
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
The ARMv8.4-PMU extension adds:
2
* one new required event, STALL
3
* one new system register PMMIR_EL1
2
4
3
Add code needed to get a functional PCI subsytem when using in
5
(There are also some more L1-cache related events, but since
4
conjunction with upstream Linux guest (4.13+). Tested to work against
6
we don't implement any cache we don't provide these, in the
5
"e1000e" (network adapter, using MSI interrupts) as well as
7
same way we don't provide the base-PMUv3 cache events.)
6
"usb-ehci" (USB controller, using legacy PCI interrupts).
7
8
8
Based on "i.MX6 Applications Processor Reference Manual" (Document
9
The STALL event "counts every attributable cycle on which no
9
Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
10
attributable instruction or operation was sent for execution on this
10
kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)
11
PE". QEMU doesn't stall in this sense, so this is another
12
always-reads-zero event.
11
13
12
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
14
The PMMIR_EL1 register is a read-only register providing
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
implementation-specific information about the PMU; currently it has
16
only one field, SLOTS, which defines behaviour of the STALL_SLOT PMU
17
event. Since QEMU doesn't implement the STALL_SLOT event, we can
18
validly make the register read zero.
19
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20200214175116.9164-15-peter.maydell@linaro.org
15
---
23
---
16
hw/pci-host/Makefile.objs | 2 +
24
target/arm/cpu.h | 18 ++++++++++++++++++
17
include/hw/pci-host/designware.h | 102 ++++++
25
target/arm/helper.c | 22 +++++++++++++++++++++-
18
include/hw/pci/pci_ids.h | 2 +
26
2 files changed, 39 insertions(+), 1 deletion(-)
19
hw/pci-host/designware.c | 754 +++++++++++++++++++++++++++++++++++++++
20
default-configs/arm-softmmu.mak | 1 +
21
5 files changed, 861 insertions(+)
22
create mode 100644 include/hw/pci-host/designware.h
23
create mode 100644 hw/pci-host/designware.c
24
27
25
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/pci-host/Makefile.objs
30
--- a/target/arm/cpu.h
28
+++ b/hw/pci-host/Makefile.objs
31
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PCI_PIIX) += piix.o
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
30
common-obj-$(CONFIG_PCI_Q35) += q35.o
33
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
31
common-obj-$(CONFIG_PCI_GENERIC) += gpex.o
34
}
32
common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o
35
33
+
36
+static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id)
34
+common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o
35
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/include/hw/pci-host/designware.h
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * Copyright (c) 2017, Impinj, Inc.
43
+ *
44
+ * Designware PCIe IP block emulation
45
+ *
46
+ * This library is free software; you can redistribute it and/or
47
+ * modify it under the terms of the GNU Lesser General Public
48
+ * License as published by the Free Software Foundation; either
49
+ * version 2 of the License, or (at your option) any later version.
50
+ *
51
+ * This library is distributed in the hope that it will be useful,
52
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
53
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
54
+ * Lesser General Public License for more details.
55
+ *
56
+ * You should have received a copy of the GNU Lesser General Public
57
+ * License along with this library; if not, see
58
+ * <http://www.gnu.org/licenses/>.
59
+ */
60
+
61
+#ifndef DESIGNWARE_H
62
+#define DESIGNWARE_H
63
+
64
+#include "hw/hw.h"
65
+#include "hw/sysbus.h"
66
+#include "hw/pci/pci.h"
67
+#include "hw/pci/pci_bus.h"
68
+#include "hw/pci/pcie_host.h"
69
+#include "hw/pci/pci_bridge.h"
70
+
71
+#define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host"
72
+#define DESIGNWARE_PCIE_HOST(obj) \
73
+ OBJECT_CHECK(DesignwarePCIEHost, (obj), TYPE_DESIGNWARE_PCIE_HOST)
74
+
75
+#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
76
+#define DESIGNWARE_PCIE_ROOT(obj) \
77
+ OBJECT_CHECK(DesignwarePCIERoot, (obj), TYPE_DESIGNWARE_PCIE_ROOT)
78
+
79
+struct DesignwarePCIERoot;
80
+typedef struct DesignwarePCIERoot DesignwarePCIERoot;
81
+
82
+typedef struct DesignwarePCIEViewport {
83
+ DesignwarePCIERoot *root;
84
+
85
+ MemoryRegion cfg;
86
+ MemoryRegion mem;
87
+
88
+ uint64_t base;
89
+ uint64_t target;
90
+ uint32_t limit;
91
+ uint32_t cr[2];
92
+
93
+ bool inbound;
94
+} DesignwarePCIEViewport;
95
+
96
+typedef struct DesignwarePCIEMSIBank {
97
+ uint32_t enable;
98
+ uint32_t mask;
99
+ uint32_t status;
100
+} DesignwarePCIEMSIBank;
101
+
102
+typedef struct DesignwarePCIEMSI {
103
+ uint64_t base;
104
+ MemoryRegion iomem;
105
+
106
+#define DESIGNWARE_PCIE_NUM_MSI_BANKS 1
107
+
108
+ DesignwarePCIEMSIBank intr[DESIGNWARE_PCIE_NUM_MSI_BANKS];
109
+} DesignwarePCIEMSI;
110
+
111
+struct DesignwarePCIERoot {
112
+ PCIBridge parent_obj;
113
+
114
+ uint32_t atu_viewport;
115
+
116
+#define DESIGNWARE_PCIE_VIEWPORT_OUTBOUND 0
117
+#define DESIGNWARE_PCIE_VIEWPORT_INBOUND 1
118
+#define DESIGNWARE_PCIE_NUM_VIEWPORTS 4
119
+
120
+ DesignwarePCIEViewport viewports[2][DESIGNWARE_PCIE_NUM_VIEWPORTS];
121
+ DesignwarePCIEMSI msi;
122
+};
123
+
124
+typedef struct DesignwarePCIEHost {
125
+ PCIHostState parent_obj;
126
+
127
+ DesignwarePCIERoot root;
128
+
129
+ struct {
130
+ AddressSpace address_space;
131
+ MemoryRegion address_space_root;
132
+
133
+ MemoryRegion memory;
134
+ MemoryRegion io;
135
+
136
+ qemu_irq irqs[4];
137
+ } pci;
138
+
139
+ MemoryRegion mmio;
140
+} DesignwarePCIEHost;
141
+
142
+#endif /* DESIGNWARE_H */
143
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
144
index XXXXXXX..XXXXXXX 100644
145
--- a/include/hw/pci/pci_ids.h
146
+++ b/include/hw/pci/pci_ids.h
147
@@ -XXX,XX +XXX,XX @@
148
#define PCI_VENDOR_ID_VMWARE 0x15ad
149
#define PCI_DEVICE_ID_VMWARE_PVRDMA 0x0820
150
151
+#define PCI_VENDOR_ID_SYNOPSYS 0x16C3
152
+
153
#endif
154
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
155
new file mode 100644
156
index XXXXXXX..XXXXXXX
157
--- /dev/null
158
+++ b/hw/pci-host/designware.c
159
@@ -XXX,XX +XXX,XX @@
160
+/*
161
+ * Copyright (c) 2018, Impinj, Inc.
162
+ *
163
+ * Designware PCIe IP block emulation
164
+ *
165
+ * This library is free software; you can redistribute it and/or
166
+ * modify it under the terms of the GNU Lesser General Public
167
+ * License as published by the Free Software Foundation; either
168
+ * version 2 of the License, or (at your option) any later version.
169
+ *
170
+ * This library is distributed in the hope that it will be useful,
171
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
172
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
173
+ * Lesser General Public License for more details.
174
+ *
175
+ * You should have received a copy of the GNU Lesser General Public
176
+ * License along with this library; if not, see
177
+ * <http://www.gnu.org/licenses/>.
178
+ */
179
+
180
+#include "qemu/osdep.h"
181
+#include "qapi/error.h"
182
+#include "hw/pci/msi.h"
183
+#include "hw/pci/pci_bridge.h"
184
+#include "hw/pci/pci_host.h"
185
+#include "hw/pci/pcie_port.h"
186
+#include "hw/pci-host/designware.h"
187
+
188
+#define DESIGNWARE_PCIE_PORT_LINK_CONTROL 0x710
189
+#define DESIGNWARE_PCIE_PHY_DEBUG_R1 0x72C
190
+#define DESIGNWARE_PCIE_PHY_DEBUG_R1_XMLH_LINK_UP BIT(4)
191
+#define DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
192
+#define DESIGNWARE_PCIE_PORT_LOGIC_SPEED_CHANGE BIT(17)
193
+#define DESIGNWARE_PCIE_MSI_ADDR_LO 0x820
194
+#define DESIGNWARE_PCIE_MSI_ADDR_HI 0x824
195
+#define DESIGNWARE_PCIE_MSI_INTR0_ENABLE 0x828
196
+#define DESIGNWARE_PCIE_MSI_INTR0_MASK 0x82C
197
+#define DESIGNWARE_PCIE_MSI_INTR0_STATUS 0x830
198
+#define DESIGNWARE_PCIE_ATU_VIEWPORT 0x900
199
+#define DESIGNWARE_PCIE_ATU_REGION_INBOUND BIT(31)
200
+#define DESIGNWARE_PCIE_ATU_CR1 0x904
201
+#define DESIGNWARE_PCIE_ATU_TYPE_MEM (0x0 << 0)
202
+#define DESIGNWARE_PCIE_ATU_CR2 0x908
203
+#define DESIGNWARE_PCIE_ATU_ENABLE BIT(31)
204
+#define DESIGNWARE_PCIE_ATU_LOWER_BASE 0x90C
205
+#define DESIGNWARE_PCIE_ATU_UPPER_BASE 0x910
206
+#define DESIGNWARE_PCIE_ATU_LIMIT 0x914
207
+#define DESIGNWARE_PCIE_ATU_LOWER_TARGET 0x918
208
+#define DESIGNWARE_PCIE_ATU_BUS(x) (((x) >> 24) & 0xff)
209
+#define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff)
210
+#define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C
211
+
212
+static DesignwarePCIEHost *
213
+designware_pcie_root_to_host(DesignwarePCIERoot *root)
214
+{
37
+{
215
+ BusState *bus = qdev_get_parent_bus(DEVICE(root));
38
+ /* 0xf means "non-standard IMPDEF PMU" */
216
+ return DESIGNWARE_PCIE_HOST(bus->parent);
39
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
40
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
217
+}
41
+}
218
+
42
+
219
+static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
43
/*
220
+ uint64_t val, unsigned len)
44
* 64-bit feature tests via id registers.
45
*/
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
47
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
48
}
49
50
+static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
221
+{
51
+{
222
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(opaque);
52
+ return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
223
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
53
+ FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
224
+
225
+ root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable;
226
+
227
+ if (root->msi.intr[0].status & ~root->msi.intr[0].mask) {
228
+ qemu_set_irq(host->pci.irqs[0], 1);
229
+ }
230
+}
54
+}
231
+
55
+
232
+static const MemoryRegionOps designware_pci_host_msi_ops = {
56
/*
233
+ .write = designware_pcie_root_msi_write,
57
* Feature tests for "does this exist in either 32-bit or 64-bit?"
234
+ .endianness = DEVICE_LITTLE_ENDIAN,
58
*/
235
+ .valid = {
59
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
236
+ .min_access_size = 4,
60
return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
237
+ .max_access_size = 4,
61
}
238
+ },
62
239
+};
63
+static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
240
+
241
+static void designware_pcie_root_update_msi_mapping(DesignwarePCIERoot *root)
242
+
243
+{
64
+{
244
+ MemoryRegion *mem = &root->msi.iomem;
65
+ return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
245
+ const uint64_t base = root->msi.base;
246
+ const bool enable = root->msi.intr[0].enable;
247
+
248
+ memory_region_set_address(mem, base);
249
+ memory_region_set_enabled(mem, enable);
250
+}
66
+}
251
+
67
+
252
+static DesignwarePCIEViewport *
68
/*
253
+designware_pcie_root_get_current_viewport(DesignwarePCIERoot *root)
69
* Forward to the above feature tests given an ARMCPU pointer.
70
*/
71
diff --git a/target/arm/helper.c b/target/arm/helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/helper.c
74
+++ b/target/arm/helper.c
75
@@ -XXX,XX +XXX,XX @@ static bool pmu_8_1_events_supported(CPUARMState *env)
76
return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
77
}
78
79
+static bool pmu_8_4_events_supported(CPUARMState *env)
254
+{
80
+{
255
+ const unsigned int idx = root->atu_viewport & 0xF;
81
+ /* For events which are supported in any v8.1 PMU */
256
+ const unsigned int dir =
82
+ return cpu_isar_feature(any_pmu_8_4, env_archcpu(env));
257
+ !!(root->atu_viewport & DESIGNWARE_PCIE_ATU_REGION_INBOUND);
258
+ return &root->viewports[dir][idx];
259
+}
83
+}
260
+
84
+
261
+static uint32_t
85
static uint64_t zero_event_get_count(CPUARMState *env)
262
+designware_pcie_root_config_read(PCIDevice *d, uint32_t address, int len)
86
{
263
+{
87
/* For events which on QEMU never fire, so their count is always zero */
264
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(d);
88
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
265
+ DesignwarePCIEViewport *viewport =
89
.get_count = zero_event_get_count,
266
+ designware_pcie_root_get_current_viewport(root);
90
.ns_per_count = zero_event_ns_per,
267
+
91
},
268
+ uint32_t val;
92
+ { .number = 0x03c, /* STALL */
269
+
93
+ .supported = pmu_8_4_events_supported,
270
+ switch (address) {
94
+ .get_count = zero_event_get_count,
271
+ case DESIGNWARE_PCIE_PORT_LINK_CONTROL:
95
+ .ns_per_count = zero_event_ns_per,
272
+ /*
96
+ },
273
+ * Linux guest uses this register only to configure number of
97
};
274
+ * PCIE lane (which in our case is irrelevant) and doesn't
98
275
+ * really care about the value it reads from this register
99
/*
276
+ */
100
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
277
+ val = 0xDEADBEEF;
101
* should first be updated to something sparse instead of the current
278
+ break;
102
* supported_event_map[] array.
279
+
103
*/
280
+ case DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL:
104
-#define MAX_EVENT_ID 0x24
281
+ /*
105
+#define MAX_EVENT_ID 0x3c
282
+ * To make sure that any code in guest waiting for speed
106
#define UNSUPPORTED_EVENT UINT16_MAX
283
+ * change does not time out we always report
107
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
284
+ * PORT_LOGIC_SPEED_CHANGE as set
108
285
+ */
109
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
286
+ val = DESIGNWARE_PCIE_PORT_LOGIC_SPEED_CHANGE;
110
};
287
+ break;
111
define_arm_cp_regs(cpu, v81_pmu_regs);
288
+
112
}
289
+ case DESIGNWARE_PCIE_MSI_ADDR_LO:
113
+ if (cpu_isar_feature(any_pmu_8_4, cpu)) {
290
+ val = root->msi.base;
114
+ static const ARMCPRegInfo v84_pmmir = {
291
+ break;
115
+ .name = "PMMIR_EL1", .state = ARM_CP_STATE_BOTH,
292
+
116
+ .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 6,
293
+ case DESIGNWARE_PCIE_MSI_ADDR_HI:
117
+ .access = PL1_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
294
+ val = root->msi.base >> 32;
118
+ .resetvalue = 0
295
+ break;
119
+ };
296
+
120
+ define_one_arm_cp_reg(cpu, &v84_pmmir);
297
+ case DESIGNWARE_PCIE_MSI_INTR0_ENABLE:
298
+ val = root->msi.intr[0].enable;
299
+ break;
300
+
301
+ case DESIGNWARE_PCIE_MSI_INTR0_MASK:
302
+ val = root->msi.intr[0].mask;
303
+ break;
304
+
305
+ case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
306
+ val = root->msi.intr[0].status;
307
+ break;
308
+
309
+ case DESIGNWARE_PCIE_PHY_DEBUG_R1:
310
+ val = DESIGNWARE_PCIE_PHY_DEBUG_R1_XMLH_LINK_UP;
311
+ break;
312
+
313
+ case DESIGNWARE_PCIE_ATU_VIEWPORT:
314
+ val = root->atu_viewport;
315
+ break;
316
+
317
+ case DESIGNWARE_PCIE_ATU_LOWER_BASE:
318
+ val = viewport->base;
319
+ break;
320
+
321
+ case DESIGNWARE_PCIE_ATU_UPPER_BASE:
322
+ val = viewport->base >> 32;
323
+ break;
324
+
325
+ case DESIGNWARE_PCIE_ATU_LOWER_TARGET:
326
+ val = viewport->target;
327
+ break;
328
+
329
+ case DESIGNWARE_PCIE_ATU_UPPER_TARGET:
330
+ val = viewport->target >> 32;
331
+ break;
332
+
333
+ case DESIGNWARE_PCIE_ATU_LIMIT:
334
+ val = viewport->limit;
335
+ break;
336
+
337
+ case DESIGNWARE_PCIE_ATU_CR1:
338
+ case DESIGNWARE_PCIE_ATU_CR2: /* FALLTHROUGH */
339
+ val = viewport->cr[(address - DESIGNWARE_PCIE_ATU_CR1) /
340
+ sizeof(uint32_t)];
341
+ break;
342
+
343
+ default:
344
+ val = pci_default_read_config(d, address, len);
345
+ break;
346
+ }
121
+ }
347
+
122
}
348
+ return val;
123
349
+}
124
/* We don't know until after realize whether there's a GICv3
350
+
351
+static uint64_t designware_pcie_root_data_access(void *opaque, hwaddr addr,
352
+ uint64_t *val, unsigned len)
353
+{
354
+ DesignwarePCIEViewport *viewport = opaque;
355
+ DesignwarePCIERoot *root = viewport->root;
356
+
357
+ const uint8_t busnum = DESIGNWARE_PCIE_ATU_BUS(viewport->target);
358
+ const uint8_t devfn = DESIGNWARE_PCIE_ATU_DEVFN(viewport->target);
359
+ PCIBus *pcibus = pci_get_bus(PCI_DEVICE(root));
360
+ PCIDevice *pcidev = pci_find_device(pcibus, busnum, devfn);
361
+
362
+ if (pcidev) {
363
+ addr &= pci_config_size(pcidev) - 1;
364
+
365
+ if (val) {
366
+ pci_host_config_write_common(pcidev, addr,
367
+ pci_config_size(pcidev),
368
+ *val, len);
369
+ } else {
370
+ return pci_host_config_read_common(pcidev, addr,
371
+ pci_config_size(pcidev),
372
+ len);
373
+ }
374
+ }
375
+
376
+ return UINT64_MAX;
377
+}
378
+
379
+static uint64_t designware_pcie_root_data_read(void *opaque, hwaddr addr,
380
+ unsigned len)
381
+{
382
+ return designware_pcie_root_data_access(opaque, addr, NULL, len);
383
+}
384
+
385
+static void designware_pcie_root_data_write(void *opaque, hwaddr addr,
386
+ uint64_t val, unsigned len)
387
+{
388
+ designware_pcie_root_data_access(opaque, addr, &val, len);
389
+}
390
+
391
+static const MemoryRegionOps designware_pci_host_conf_ops = {
392
+ .read = designware_pcie_root_data_read,
393
+ .write = designware_pcie_root_data_write,
394
+ .endianness = DEVICE_LITTLE_ENDIAN,
395
+ .valid = {
396
+ .min_access_size = 1,
397
+ .max_access_size = 4,
398
+ },
399
+};
400
+
401
+static void designware_pcie_update_viewport(DesignwarePCIERoot *root,
402
+ DesignwarePCIEViewport *viewport)
403
+{
404
+ const uint64_t target = viewport->target;
405
+ const uint64_t base = viewport->base;
406
+ const uint64_t size = (uint64_t)viewport->limit - base + 1;
407
+ const bool enabled = viewport->cr[1] & DESIGNWARE_PCIE_ATU_ENABLE;
408
+
409
+ MemoryRegion *current, *other;
410
+
411
+ if (viewport->cr[0] == DESIGNWARE_PCIE_ATU_TYPE_MEM) {
412
+ current = &viewport->mem;
413
+ other = &viewport->cfg;
414
+ memory_region_set_alias_offset(current, target);
415
+ } else {
416
+ current = &viewport->cfg;
417
+ other = &viewport->mem;
418
+ }
419
+
420
+ /*
421
+ * An outbound viewport can be reconfigure from being MEM to CFG,
422
+ * to account for that we disable the "other" memory region that
423
+ * becomes unused due to that fact.
424
+ */
425
+ memory_region_set_enabled(other, false);
426
+ if (enabled) {
427
+ memory_region_set_size(current, size);
428
+ memory_region_set_address(current, base);
429
+ }
430
+ memory_region_set_enabled(current, enabled);
431
+}
432
+
433
+static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
434
+ uint32_t val, int len)
435
+{
436
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(d);
437
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
438
+ DesignwarePCIEViewport *viewport =
439
+ designware_pcie_root_get_current_viewport(root);
440
+
441
+ switch (address) {
442
+ case DESIGNWARE_PCIE_PORT_LINK_CONTROL:
443
+ case DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL:
444
+ case DESIGNWARE_PCIE_PHY_DEBUG_R1:
445
+ /* No-op */
446
+ break;
447
+
448
+ case DESIGNWARE_PCIE_MSI_ADDR_LO:
449
+ root->msi.base &= 0xFFFFFFFF00000000ULL;
450
+ root->msi.base |= val;
451
+ break;
452
+
453
+ case DESIGNWARE_PCIE_MSI_ADDR_HI:
454
+ root->msi.base &= 0x00000000FFFFFFFFULL;
455
+ root->msi.base |= (uint64_t)val << 32;
456
+ break;
457
+
458
+ case DESIGNWARE_PCIE_MSI_INTR0_ENABLE: {
459
+ const bool update_msi_mapping = !root->msi.intr[0].enable ^ !!val;
460
+
461
+ root->msi.intr[0].enable = val;
462
+
463
+ if (update_msi_mapping) {
464
+ designware_pcie_root_update_msi_mapping(root);
465
+ }
466
+ break;
467
+ }
468
+
469
+ case DESIGNWARE_PCIE_MSI_INTR0_MASK:
470
+ root->msi.intr[0].mask = val;
471
+ break;
472
+
473
+ case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
474
+ root->msi.intr[0].status ^= val;
475
+ if (!root->msi.intr[0].status) {
476
+ qemu_set_irq(host->pci.irqs[0], 0);
477
+ }
478
+ break;
479
+
480
+ case DESIGNWARE_PCIE_ATU_VIEWPORT:
481
+ root->atu_viewport = val;
482
+ break;
483
+
484
+ case DESIGNWARE_PCIE_ATU_LOWER_BASE:
485
+ viewport->base &= 0xFFFFFFFF00000000ULL;
486
+ viewport->base |= val;
487
+ break;
488
+
489
+ case DESIGNWARE_PCIE_ATU_UPPER_BASE:
490
+ viewport->base &= 0x00000000FFFFFFFFULL;
491
+ viewport->base |= (uint64_t)val << 32;
492
+ break;
493
+
494
+ case DESIGNWARE_PCIE_ATU_LOWER_TARGET:
495
+ viewport->target &= 0xFFFFFFFF00000000ULL;
496
+ viewport->target |= val;
497
+ break;
498
+
499
+ case DESIGNWARE_PCIE_ATU_UPPER_TARGET:
500
+ viewport->target &= 0x00000000FFFFFFFFULL;
501
+ viewport->target |= val;
502
+ break;
503
+
504
+ case DESIGNWARE_PCIE_ATU_LIMIT:
505
+ viewport->limit = val;
506
+ break;
507
+
508
+ case DESIGNWARE_PCIE_ATU_CR1:
509
+ viewport->cr[0] = val;
510
+ break;
511
+ case DESIGNWARE_PCIE_ATU_CR2:
512
+ viewport->cr[1] = val;
513
+ designware_pcie_update_viewport(root, viewport);
514
+ break;
515
+
516
+ default:
517
+ pci_bridge_write_config(d, address, val, len);
518
+ break;
519
+ }
520
+}
521
+
522
+static char *designware_pcie_viewport_name(const char *direction,
523
+ unsigned int i,
524
+ const char *type)
525
+{
526
+ return g_strdup_printf("PCI %s Viewport %u [%s]",
527
+ direction, i, type);
528
+}
529
+
530
+static void designware_pcie_root_realize(PCIDevice *dev, Error **errp)
531
+{
532
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(dev);
533
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
534
+ MemoryRegion *address_space = &host->pci.memory;
535
+ PCIBridge *br = PCI_BRIDGE(dev);
536
+ DesignwarePCIEViewport *viewport;
537
+ /*
538
+ * Dummy values used for initial configuration of MemoryRegions
539
+ * that belong to a given viewport
540
+ */
541
+ const hwaddr dummy_offset = 0;
542
+ const uint64_t dummy_size = 4;
543
+ size_t i;
544
+
545
+ br->bus_name = "dw-pcie";
546
+
547
+ pci_set_word(dev->config + PCI_COMMAND,
548
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
549
+
550
+ pci_config_set_interrupt_pin(dev->config, 1);
551
+ pci_bridge_initfn(dev, TYPE_PCIE_BUS);
552
+
553
+ pcie_port_init_reg(dev);
554
+
555
+ pcie_cap_init(dev, 0x70, PCI_EXP_TYPE_ROOT_PORT,
556
+ 0, &error_fatal);
557
+
558
+ msi_nonbroken = true;
559
+ msi_init(dev, 0x50, 32, true, true, &error_fatal);
560
+
561
+ for (i = 0; i < DESIGNWARE_PCIE_NUM_VIEWPORTS; i++) {
562
+ MemoryRegion *source, *destination, *mem;
563
+ const char *direction;
564
+ char *name;
565
+
566
+ viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][i];
567
+ viewport->inbound = true;
568
+ viewport->base = 0x0000000000000000ULL;
569
+ viewport->target = 0x0000000000000000ULL;
570
+ viewport->limit = UINT32_MAX;
571
+ viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM;
572
+
573
+ source = &host->pci.address_space_root;
574
+ destination = get_system_memory();
575
+ direction = "Inbound";
576
+
577
+ /*
578
+ * Configure MemoryRegion implementing PCI -> CPU memory
579
+ * access
580
+ */
581
+ mem = &viewport->mem;
582
+ name = designware_pcie_viewport_name(direction, i, "MEM");
583
+ memory_region_init_alias(mem, OBJECT(root), name, destination,
584
+ dummy_offset, dummy_size);
585
+ memory_region_add_subregion_overlap(source, dummy_offset, mem, -1);
586
+ memory_region_set_enabled(mem, false);
587
+ g_free(name);
588
+
589
+ viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_OUTBOUND][i];
590
+ viewport->root = root;
591
+ viewport->inbound = false;
592
+ viewport->base = 0x0000000000000000ULL;
593
+ viewport->target = 0x0000000000000000ULL;
594
+ viewport->limit = UINT32_MAX;
595
+ viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM;
596
+
597
+ destination = &host->pci.memory;
598
+ direction = "Outbound";
599
+ source = get_system_memory();
600
+
601
+ /*
602
+ * Configure MemoryRegion implementing CPU -> PCI memory
603
+ * access
604
+ */
605
+ mem = &viewport->mem;
606
+ name = designware_pcie_viewport_name(direction, i, "MEM");
607
+ memory_region_init_alias(mem, OBJECT(root), name, destination,
608
+ dummy_offset, dummy_size);
609
+ memory_region_add_subregion(source, dummy_offset, mem);
610
+ memory_region_set_enabled(mem, false);
611
+ g_free(name);
612
+
613
+ /*
614
+ * Configure MemoryRegion implementing access to configuration
615
+ * space
616
+ */
617
+ mem = &viewport->cfg;
618
+ name = designware_pcie_viewport_name(direction, i, "CFG");
619
+ memory_region_init_io(&viewport->cfg, OBJECT(root),
620
+ &designware_pci_host_conf_ops,
621
+ viewport, name, dummy_size);
622
+ memory_region_add_subregion(source, dummy_offset, mem);
623
+ memory_region_set_enabled(mem, false);
624
+ g_free(name);
625
+ }
626
+
627
+ /*
628
+ * If no inbound iATU windows are configured, HW defaults to
629
+ * letting inbound TLPs to pass in. We emulate that by exlicitly
630
+ * configuring first inbound window to cover all of target's
631
+ * address space.
632
+ *
633
+ * NOTE: This will not work correctly for the case when first
634
+ * configured inbound window is window 0
635
+ */
636
+ viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][0];
637
+ viewport->cr[1] = DESIGNWARE_PCIE_ATU_ENABLE;
638
+ designware_pcie_update_viewport(root, viewport);
639
+
640
+ memory_region_init_io(&root->msi.iomem, OBJECT(root),
641
+ &designware_pci_host_msi_ops,
642
+ root, "pcie-msi", 0x4);
643
+ /*
644
+ * We initially place MSI interrupt I/O region a adress 0 and
645
+ * disable it. It'll be later moved to correct offset and enabled
646
+ * in designware_pcie_root_update_msi_mapping() as a part of
647
+ * initialization done by guest OS
648
+ */
649
+ memory_region_add_subregion(address_space, dummy_offset, &root->msi.iomem);
650
+ memory_region_set_enabled(&root->msi.iomem, false);
651
+}
652
+
653
+static void designware_pcie_set_irq(void *opaque, int irq_num, int level)
654
+{
655
+ DesignwarePCIEHost *host = DESIGNWARE_PCIE_HOST(opaque);
656
+
657
+ qemu_set_irq(host->pci.irqs[irq_num], level);
658
+}
659
+
660
+static const char *
661
+designware_pcie_host_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus)
662
+{
663
+ return "0000:00";
664
+}
665
+
666
+static const VMStateDescription vmstate_designware_pcie_msi_bank = {
667
+ .name = "designware-pcie-msi-bank",
668
+ .version_id = 1,
669
+ .minimum_version_id = 1,
670
+ .fields = (VMStateField[]) {
671
+ VMSTATE_UINT32(enable, DesignwarePCIEMSIBank),
672
+ VMSTATE_UINT32(mask, DesignwarePCIEMSIBank),
673
+ VMSTATE_UINT32(status, DesignwarePCIEMSIBank),
674
+ VMSTATE_END_OF_LIST()
675
+ }
676
+};
677
+
678
+static const VMStateDescription vmstate_designware_pcie_msi = {
679
+ .name = "designware-pcie-msi",
680
+ .version_id = 1,
681
+ .minimum_version_id = 1,
682
+ .fields = (VMStateField[]) {
683
+ VMSTATE_UINT64(base, DesignwarePCIEMSI),
684
+ VMSTATE_STRUCT_ARRAY(intr,
685
+ DesignwarePCIEMSI,
686
+ DESIGNWARE_PCIE_NUM_MSI_BANKS,
687
+ 1,
688
+ vmstate_designware_pcie_msi_bank,
689
+ DesignwarePCIEMSIBank),
690
+ VMSTATE_END_OF_LIST()
691
+ }
692
+};
693
+
694
+static const VMStateDescription vmstate_designware_pcie_viewport = {
695
+ .name = "designware-pcie-viewport",
696
+ .version_id = 1,
697
+ .minimum_version_id = 1,
698
+ .fields = (VMStateField[]) {
699
+ VMSTATE_UINT64(base, DesignwarePCIEViewport),
700
+ VMSTATE_UINT64(target, DesignwarePCIEViewport),
701
+ VMSTATE_UINT32(limit, DesignwarePCIEViewport),
702
+ VMSTATE_UINT32_ARRAY(cr, DesignwarePCIEViewport, 2),
703
+ VMSTATE_END_OF_LIST()
704
+ }
705
+};
706
+
707
+static const VMStateDescription vmstate_designware_pcie_root = {
708
+ .name = "designware-pcie-root",
709
+ .version_id = 1,
710
+ .minimum_version_id = 1,
711
+ .fields = (VMStateField[]) {
712
+ VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
713
+ VMSTATE_UINT32(atu_viewport, DesignwarePCIERoot),
714
+ VMSTATE_STRUCT_2DARRAY(viewports,
715
+ DesignwarePCIERoot,
716
+ 2,
717
+ DESIGNWARE_PCIE_NUM_VIEWPORTS,
718
+ 1,
719
+ vmstate_designware_pcie_viewport,
720
+ DesignwarePCIEViewport),
721
+ VMSTATE_STRUCT(msi,
722
+ DesignwarePCIERoot,
723
+ 1,
724
+ vmstate_designware_pcie_msi,
725
+ DesignwarePCIEMSI),
726
+ VMSTATE_END_OF_LIST()
727
+ }
728
+};
729
+
730
+static void designware_pcie_root_class_init(ObjectClass *klass, void *data)
731
+{
732
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
733
+ DeviceClass *dc = DEVICE_CLASS(klass);
734
+
735
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
736
+
737
+ k->vendor_id = PCI_VENDOR_ID_SYNOPSYS;
738
+ k->device_id = 0xABCD;
739
+ k->revision = 0;
740
+ k->class_id = PCI_CLASS_BRIDGE_PCI;
741
+ k->is_bridge = true;
742
+ k->exit = pci_bridge_exitfn;
743
+ k->realize = designware_pcie_root_realize;
744
+ k->config_read = designware_pcie_root_config_read;
745
+ k->config_write = designware_pcie_root_config_write;
746
+
747
+ dc->reset = pci_bridge_reset;
748
+ /*
749
+ * PCI-facing part of the host bridge, not usable without the
750
+ * host-facing part, which can't be device_add'ed, yet.
751
+ */
752
+ dc->user_creatable = false;
753
+ dc->vmsd = &vmstate_designware_pcie_root;
754
+}
755
+
756
+static uint64_t designware_pcie_host_mmio_read(void *opaque, hwaddr addr,
757
+ unsigned int size)
758
+{
759
+ PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
760
+ PCIDevice *device = pci_find_device(pci->bus, 0, 0);
761
+
762
+ return pci_host_config_read_common(device,
763
+ addr,
764
+ pci_config_size(device),
765
+ size);
766
+}
767
+
768
+static void designware_pcie_host_mmio_write(void *opaque, hwaddr addr,
769
+ uint64_t val, unsigned int size)
770
+{
771
+ PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
772
+ PCIDevice *device = pci_find_device(pci->bus, 0, 0);
773
+
774
+ return pci_host_config_write_common(device,
775
+ addr,
776
+ pci_config_size(device),
777
+ val, size);
778
+}
779
+
780
+static const MemoryRegionOps designware_pci_mmio_ops = {
781
+ .read = designware_pcie_host_mmio_read,
782
+ .write = designware_pcie_host_mmio_write,
783
+ .endianness = DEVICE_LITTLE_ENDIAN,
784
+ .impl = {
785
+ /*
786
+ * Our device would not work correctly if the guest was doing
787
+ * unaligned access. This might not be a limitation on the real
788
+ * device but in practice there is no reason for a guest to access
789
+ * this device unaligned.
790
+ */
791
+ .min_access_size = 4,
792
+ .max_access_size = 4,
793
+ .unaligned = false,
794
+ },
795
+};
796
+
797
+static AddressSpace *designware_pcie_host_set_iommu(PCIBus *bus, void *opaque,
798
+ int devfn)
799
+{
800
+ DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(opaque);
801
+
802
+ return &s->pci.address_space;
803
+}
804
+
805
+static void designware_pcie_host_realize(DeviceState *dev, Error **errp)
806
+{
807
+ PCIHostState *pci = PCI_HOST_BRIDGE(dev);
808
+ DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(dev);
809
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
810
+ size_t i;
811
+
812
+ for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) {
813
+ sysbus_init_irq(sbd, &s->pci.irqs[i]);
814
+ }
815
+
816
+ memory_region_init_io(&s->mmio,
817
+ OBJECT(s),
818
+ &designware_pci_mmio_ops,
819
+ s,
820
+ "pcie.reg", 4 * 1024);
821
+ sysbus_init_mmio(sbd, &s->mmio);
822
+
823
+ memory_region_init(&s->pci.io, OBJECT(s), "pcie-pio", 16);
824
+ memory_region_init(&s->pci.memory, OBJECT(s),
825
+ "pcie-bus-memory",
826
+ UINT64_MAX);
827
+
828
+ pci->bus = pci_register_root_bus(dev, "pcie",
829
+ designware_pcie_set_irq,
830
+ pci_swizzle_map_irq_fn,
831
+ s,
832
+ &s->pci.memory,
833
+ &s->pci.io,
834
+ 0, 4,
835
+ TYPE_PCIE_BUS);
836
+
837
+ memory_region_init(&s->pci.address_space_root,
838
+ OBJECT(s),
839
+ "pcie-bus-address-space-root",
840
+ UINT64_MAX);
841
+ memory_region_add_subregion(&s->pci.address_space_root,
842
+ 0x0, &s->pci.memory);
843
+ address_space_init(&s->pci.address_space,
844
+ &s->pci.address_space_root,
845
+ "pcie-bus-address-space");
846
+ pci_setup_iommu(pci->bus, designware_pcie_host_set_iommu, s);
847
+
848
+ qdev_set_parent_bus(DEVICE(&s->root), BUS(pci->bus));
849
+ qdev_init_nofail(DEVICE(&s->root));
850
+}
851
+
852
+static const VMStateDescription vmstate_designware_pcie_host = {
853
+ .name = "designware-pcie-host",
854
+ .version_id = 1,
855
+ .minimum_version_id = 1,
856
+ .fields = (VMStateField[]) {
857
+ VMSTATE_STRUCT(root,
858
+ DesignwarePCIEHost,
859
+ 1,
860
+ vmstate_designware_pcie_root,
861
+ DesignwarePCIERoot),
862
+ VMSTATE_END_OF_LIST()
863
+ }
864
+};
865
+
866
+static void designware_pcie_host_class_init(ObjectClass *klass, void *data)
867
+{
868
+ DeviceClass *dc = DEVICE_CLASS(klass);
869
+ PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
870
+
871
+ hc->root_bus_path = designware_pcie_host_root_bus_path;
872
+ dc->realize = designware_pcie_host_realize;
873
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
874
+ dc->fw_name = "pci";
875
+ dc->vmsd = &vmstate_designware_pcie_host;
876
+}
877
+
878
+static void designware_pcie_host_init(Object *obj)
879
+{
880
+ DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(obj);
881
+ DesignwarePCIERoot *root = &s->root;
882
+
883
+ object_initialize(root, sizeof(*root), TYPE_DESIGNWARE_PCIE_ROOT);
884
+ object_property_add_child(obj, "root", OBJECT(root), NULL);
885
+ qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
886
+ qdev_prop_set_bit(DEVICE(root), "multifunction", false);
887
+}
888
+
889
+static const TypeInfo designware_pcie_root_info = {
890
+ .name = TYPE_DESIGNWARE_PCIE_ROOT,
891
+ .parent = TYPE_PCI_BRIDGE,
892
+ .instance_size = sizeof(DesignwarePCIERoot),
893
+ .class_init = designware_pcie_root_class_init,
894
+ .interfaces = (InterfaceInfo[]) {
895
+ { INTERFACE_PCIE_DEVICE },
896
+ { }
897
+ },
898
+};
899
+
900
+static const TypeInfo designware_pcie_host_info = {
901
+ .name = TYPE_DESIGNWARE_PCIE_HOST,
902
+ .parent = TYPE_PCI_HOST_BRIDGE,
903
+ .instance_size = sizeof(DesignwarePCIEHost),
904
+ .instance_init = designware_pcie_host_init,
905
+ .class_init = designware_pcie_host_class_init,
906
+};
907
+
908
+static void designware_pcie_register(void)
909
+{
910
+ type_register_static(&designware_pcie_root_info);
911
+ type_register_static(&designware_pcie_host_info);
912
+}
913
+type_init(designware_pcie_register)
914
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
915
index XXXXXXX..XXXXXXX 100644
916
--- a/default-configs/arm-softmmu.mak
917
+++ b/default-configs/arm-softmmu.mak
918
@@ -XXX,XX +XXX,XX @@ CONFIG_GPIO_KEY=y
919
CONFIG_MSF2=y
920
CONFIG_FW_CFG_DMA=y
921
CONFIG_XILINX_AXI=y
922
+CONFIG_PCI_DESIGNWARE=y
923
--
125
--
924
2.16.2
126
2.20.1
925
127
926
128
diff view generated by jsdifflib
New patch
1
Set the ID register bits to provide ARMv8.4-PMU (and implicitly
2
also ARMv8.1-PMU) in the 'max' CPU.
1
3
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20200214175116.9164-16-peter.maydell@linaro.org
7
---
8
target/arm/cpu64.c | 8 ++++++++
9
1 file changed, 8 insertions(+)
10
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
14
+++ b/target/arm/cpu64.c
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
16
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
17
cpu->id_mmfr3 = u;
18
19
+ u = cpu->isar.id_aa64dfr0;
20
+ u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
21
+ cpu->isar.id_aa64dfr0 = u;
22
+
23
+ u = cpu->isar.id_dfr0;
24
+ u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
25
+ cpu->isar.id_dfr0 = u;
26
+
27
/*
28
* FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
29
* so do not set MVFR1.FPHP. Strictly speaking this is not legal,
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
New patch
1
The PMCR_EL0.DP bit is bit 5, which is 0x20, not 0x10. 0x10 is 'X'.
2
Correct our #define of PMCRDP and add the missing PMCRX.
1
3
4
We do have the correct behaviour for handling the DP bit being
5
set, so this fixes a guest-visible bug.
6
7
Fixes: 033614c47de
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20200214175116.9164-17-peter.maydell@linaro.org
12
---
13
target/arm/helper.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
21
#define PMCRN_MASK 0xf800
22
#define PMCRN_SHIFT 11
23
#define PMCRLC 0x40
24
-#define PMCRDP 0x10
25
+#define PMCRDP 0x20
26
+#define PMCRX 0x10
27
#define PMCRD 0x8
28
#define PMCRC 0x4
29
#define PMCRP 0x2
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The LC bit in the PMCR_EL0 register is supposed to be:
2
* read/write
3
* RES1 on an AArch64-only implementation
4
* an architecturally UNKNOWN value on reset
5
(and use of LC==0 by software is deprecated).
2
6
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
We were implementing it incorrectly as read-only always zero,
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
though we do have all the code needed to test it and behave
5
Message-id: 20180309153654.13518-8-f4bug@amsat.org
9
accordingly.
10
11
Instead make it a read-write bit which resets to 1 always, which
12
satisfies all the architectural requirements above.
13
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20200214175116.9164-18-peter.maydell@linaro.org
7
---
18
---
8
hw/sd/sdhci.c | 4 ++--
19
target/arm/helper.c | 13 +++++++++----
9
1 file changed, 2 insertions(+), 2 deletions(-)
20
1 file changed, 9 insertions(+), 4 deletions(-)
10
21
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
24
--- a/target/arm/helper.c
14
+++ b/hw/sd/sdhci.c
25
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static void sdhci_read_block_from_card(SDHCIState *s)
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
16
for (index = 0; index < blk_size; index++) {
27
#define PMCRC 0x4
17
data = sdbus_read_data(&s->sdbus);
28
#define PMCRP 0x2
18
if (!FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
29
#define PMCRE 0x1
19
- /* Device is not in tunning */
30
+/*
20
+ /* Device is not in tuning */
31
+ * Mask of PMCR bits writeable by guest (not including WO bits like C, P,
21
s->fifo_buffer[index] = data;
32
+ * which can be written as 1 to trigger behaviour but which stay RAZ).
33
+ */
34
+#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
35
36
#define PMXEVTYPER_P 0x80000000
37
#define PMXEVTYPER_U 0x40000000
38
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
22
}
39
}
23
}
40
}
24
41
25
if (FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
42
- /* only the DP, X, D and E bits are writable */
26
- /* Device is in tunning */
43
- env->cp15.c9_pmcr &= ~0x39;
27
+ /* Device is in tuning */
44
- env->cp15.c9_pmcr |= (value & 0x39);
28
s->hostctl2 &= ~R_SDHC_HOSTCTL2_EXECUTE_TUNING_MASK;
45
+ env->cp15.c9_pmcr &= ~PMCR_WRITEABLE_MASK;
29
s->hostctl2 |= R_SDHC_HOSTCTL2_SAMPLING_CLKSEL_MASK;
46
+ env->cp15.c9_pmcr |= (value & PMCR_WRITEABLE_MASK);
30
s->prnsts &= ~(SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ |
47
48
pmu_op_finish(env);
49
}
50
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
51
.access = PL0_RW, .accessfn = pmreg_access,
52
.type = ARM_CP_IO,
53
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
54
- .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
55
+ .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
56
+ PMCRLC,
57
.writefn = pmcr_write, .raw_writefn = raw_write,
58
};
59
define_one_arm_cp_reg(cpu, &pmcr);
31
--
60
--
32
2.16.2
61
2.20.1
33
62
34
63
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The isar_feature_aa32_pan and isar_feature_aa32_ats1e1 functions
2
are supposed to be testing fields in ID_MMFR3; but a cut-and-paste
3
error meant we were looking at MVFR0 instead.
2
4
3
As an implementation choice, widening VL has zeroed the
5
Fix the functions to look at the right register; this requires
4
previously inaccessible portion of the sve registers.
6
us to move at least id_mmfr3 to the ARMISARegisters struct; we
7
choose to move all the ID_MMFRn registers for consistency.
5
8
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Fixes: 3d6ad6bb466f
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Acked-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180303143823.27055-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200214175116.9164-19-peter.maydell@linaro.org
11
---
13
---
12
linux-user/aarch64/target_syscall.h | 3 +++
14
target/arm/cpu.h | 14 +++---
13
target/arm/cpu.h | 1 +
15
hw/intc/armv7m_nvic.c | 8 ++--
14
linux-user/syscall.c | 27 ++++++++++++++++++++++++
16
target/arm/cpu.c | 104 +++++++++++++++++++++---------------------
15
target/arm/cpu64.c | 41 +++++++++++++++++++++++++++++++++++++
17
target/arm/cpu64.c | 28 ++++++------
16
4 files changed, 72 insertions(+)
18
target/arm/helper.c | 12 ++---
19
target/arm/kvm32.c | 17 +++++++
20
target/arm/kvm64.c | 10 ++++
21
7 files changed, 110 insertions(+), 83 deletions(-)
17
22
18
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/aarch64/target_syscall.h
21
+++ b/linux-user/aarch64/target_syscall.h
22
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
23
#define TARGET_MLOCKALL_MCL_CURRENT 1
24
#define TARGET_MLOCKALL_MCL_FUTURE 2
25
26
+#define TARGET_PR_SVE_SET_VL 50
27
+#define TARGET_PR_SVE_GET_VL 51
28
+
29
#endif /* AARCH64_TARGET_SYSCALL_H */
30
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.h
25
--- a/target/arm/cpu.h
33
+++ b/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
34
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
27
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
35
#ifdef TARGET_AARCH64
28
uint32_t id_isar4;
36
int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
29
uint32_t id_isar5;
37
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
30
uint32_t id_isar6;
38
+void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
31
+ uint32_t id_mmfr0;
39
#endif
32
+ uint32_t id_mmfr1;
40
33
+ uint32_t id_mmfr2;
41
target_ulong do_arm_semihosting(CPUARMState *env);
34
+ uint32_t id_mmfr3;
42
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
35
+ uint32_t id_mmfr4;
43
index XXXXXXX..XXXXXXX 100644
36
uint32_t mvfr0;
44
--- a/linux-user/syscall.c
37
uint32_t mvfr1;
45
+++ b/linux-user/syscall.c
38
uint32_t mvfr2;
46
@@ -XXX,XX +XXX,XX @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
39
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
47
break;
40
uint64_t pmceid0;
41
uint64_t pmceid1;
42
uint32_t id_afr0;
43
- uint32_t id_mmfr0;
44
- uint32_t id_mmfr1;
45
- uint32_t id_mmfr2;
46
- uint32_t id_mmfr3;
47
- uint32_t id_mmfr4;
48
uint64_t id_aa64afr0;
49
uint64_t id_aa64afr1;
50
uint32_t clidr;
51
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
52
53
static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
54
{
55
- return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) != 0;
56
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0;
57
}
58
59
static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
60
{
61
- return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
62
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2;
63
}
64
65
static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
66
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/intc/armv7m_nvic.c
69
+++ b/hw/intc/armv7m_nvic.c
70
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
71
case 0xd4c: /* AFR0. */
72
return cpu->id_afr0;
73
case 0xd50: /* MMFR0. */
74
- return cpu->id_mmfr0;
75
+ return cpu->isar.id_mmfr0;
76
case 0xd54: /* MMFR1. */
77
- return cpu->id_mmfr1;
78
+ return cpu->isar.id_mmfr1;
79
case 0xd58: /* MMFR2. */
80
- return cpu->id_mmfr2;
81
+ return cpu->isar.id_mmfr2;
82
case 0xd5c: /* MMFR3. */
83
- return cpu->id_mmfr3;
84
+ return cpu->isar.id_mmfr3;
85
case 0xd60: /* ISAR0. */
86
return cpu->isar.id_isar0;
87
case 0xd64: /* ISAR1. */
88
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/cpu.c
91
+++ b/target/arm/cpu.c
92
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
93
cpu->id_pfr1 = 0x1;
94
cpu->isar.id_dfr0 = 0x2;
95
cpu->id_afr0 = 0x3;
96
- cpu->id_mmfr0 = 0x01130003;
97
- cpu->id_mmfr1 = 0x10030302;
98
- cpu->id_mmfr2 = 0x01222110;
99
+ cpu->isar.id_mmfr0 = 0x01130003;
100
+ cpu->isar.id_mmfr1 = 0x10030302;
101
+ cpu->isar.id_mmfr2 = 0x01222110;
102
cpu->isar.id_isar0 = 0x00140011;
103
cpu->isar.id_isar1 = 0x12002111;
104
cpu->isar.id_isar2 = 0x11231111;
105
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
106
cpu->id_pfr1 = 0x1;
107
cpu->isar.id_dfr0 = 0x2;
108
cpu->id_afr0 = 0x3;
109
- cpu->id_mmfr0 = 0x01130003;
110
- cpu->id_mmfr1 = 0x10030302;
111
- cpu->id_mmfr2 = 0x01222110;
112
+ cpu->isar.id_mmfr0 = 0x01130003;
113
+ cpu->isar.id_mmfr1 = 0x10030302;
114
+ cpu->isar.id_mmfr2 = 0x01222110;
115
cpu->isar.id_isar0 = 0x00140011;
116
cpu->isar.id_isar1 = 0x12002111;
117
cpu->isar.id_isar2 = 0x11231111;
118
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
119
cpu->id_pfr1 = 0x11;
120
cpu->isar.id_dfr0 = 0x33;
121
cpu->id_afr0 = 0;
122
- cpu->id_mmfr0 = 0x01130003;
123
- cpu->id_mmfr1 = 0x10030302;
124
- cpu->id_mmfr2 = 0x01222100;
125
+ cpu->isar.id_mmfr0 = 0x01130003;
126
+ cpu->isar.id_mmfr1 = 0x10030302;
127
+ cpu->isar.id_mmfr2 = 0x01222100;
128
cpu->isar.id_isar0 = 0x0140011;
129
cpu->isar.id_isar1 = 0x12002111;
130
cpu->isar.id_isar2 = 0x11231121;
131
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
132
cpu->id_pfr1 = 0x1;
133
cpu->isar.id_dfr0 = 0;
134
cpu->id_afr0 = 0x2;
135
- cpu->id_mmfr0 = 0x01100103;
136
- cpu->id_mmfr1 = 0x10020302;
137
- cpu->id_mmfr2 = 0x01222000;
138
+ cpu->isar.id_mmfr0 = 0x01100103;
139
+ cpu->isar.id_mmfr1 = 0x10020302;
140
+ cpu->isar.id_mmfr2 = 0x01222000;
141
cpu->isar.id_isar0 = 0x00100011;
142
cpu->isar.id_isar1 = 0x12002111;
143
cpu->isar.id_isar2 = 0x11221011;
144
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
145
cpu->id_pfr1 = 0x00000200;
146
cpu->isar.id_dfr0 = 0x00100000;
147
cpu->id_afr0 = 0x00000000;
148
- cpu->id_mmfr0 = 0x00000030;
149
- cpu->id_mmfr1 = 0x00000000;
150
- cpu->id_mmfr2 = 0x00000000;
151
- cpu->id_mmfr3 = 0x00000000;
152
+ cpu->isar.id_mmfr0 = 0x00000030;
153
+ cpu->isar.id_mmfr1 = 0x00000000;
154
+ cpu->isar.id_mmfr2 = 0x00000000;
155
+ cpu->isar.id_mmfr3 = 0x00000000;
156
cpu->isar.id_isar0 = 0x01141110;
157
cpu->isar.id_isar1 = 0x02111000;
158
cpu->isar.id_isar2 = 0x21112231;
159
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
160
cpu->id_pfr1 = 0x00000200;
161
cpu->isar.id_dfr0 = 0x00100000;
162
cpu->id_afr0 = 0x00000000;
163
- cpu->id_mmfr0 = 0x00000030;
164
- cpu->id_mmfr1 = 0x00000000;
165
- cpu->id_mmfr2 = 0x00000000;
166
- cpu->id_mmfr3 = 0x00000000;
167
+ cpu->isar.id_mmfr0 = 0x00000030;
168
+ cpu->isar.id_mmfr1 = 0x00000000;
169
+ cpu->isar.id_mmfr2 = 0x00000000;
170
+ cpu->isar.id_mmfr3 = 0x00000000;
171
cpu->isar.id_isar0 = 0x01141110;
172
cpu->isar.id_isar1 = 0x02111000;
173
cpu->isar.id_isar2 = 0x21112231;
174
@@ -XXX,XX +XXX,XX @@ static void cortex_m7_initfn(Object *obj)
175
cpu->id_pfr1 = 0x00000200;
176
cpu->isar.id_dfr0 = 0x00100000;
177
cpu->id_afr0 = 0x00000000;
178
- cpu->id_mmfr0 = 0x00100030;
179
- cpu->id_mmfr1 = 0x00000000;
180
- cpu->id_mmfr2 = 0x01000000;
181
- cpu->id_mmfr3 = 0x00000000;
182
+ cpu->isar.id_mmfr0 = 0x00100030;
183
+ cpu->isar.id_mmfr1 = 0x00000000;
184
+ cpu->isar.id_mmfr2 = 0x01000000;
185
+ cpu->isar.id_mmfr3 = 0x00000000;
186
cpu->isar.id_isar0 = 0x01101110;
187
cpu->isar.id_isar1 = 0x02112000;
188
cpu->isar.id_isar2 = 0x20232231;
189
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
190
cpu->id_pfr1 = 0x00000210;
191
cpu->isar.id_dfr0 = 0x00200000;
192
cpu->id_afr0 = 0x00000000;
193
- cpu->id_mmfr0 = 0x00101F40;
194
- cpu->id_mmfr1 = 0x00000000;
195
- cpu->id_mmfr2 = 0x01000000;
196
- cpu->id_mmfr3 = 0x00000000;
197
+ cpu->isar.id_mmfr0 = 0x00101F40;
198
+ cpu->isar.id_mmfr1 = 0x00000000;
199
+ cpu->isar.id_mmfr2 = 0x01000000;
200
+ cpu->isar.id_mmfr3 = 0x00000000;
201
cpu->isar.id_isar0 = 0x01101110;
202
cpu->isar.id_isar1 = 0x02212000;
203
cpu->isar.id_isar2 = 0x20232232;
204
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
205
cpu->id_pfr1 = 0x001;
206
cpu->isar.id_dfr0 = 0x010400;
207
cpu->id_afr0 = 0x0;
208
- cpu->id_mmfr0 = 0x0210030;
209
- cpu->id_mmfr1 = 0x00000000;
210
- cpu->id_mmfr2 = 0x01200000;
211
- cpu->id_mmfr3 = 0x0211;
212
+ cpu->isar.id_mmfr0 = 0x0210030;
213
+ cpu->isar.id_mmfr1 = 0x00000000;
214
+ cpu->isar.id_mmfr2 = 0x01200000;
215
+ cpu->isar.id_mmfr3 = 0x0211;
216
cpu->isar.id_isar0 = 0x02101111;
217
cpu->isar.id_isar1 = 0x13112111;
218
cpu->isar.id_isar2 = 0x21232141;
219
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
220
cpu->id_pfr1 = 0x11;
221
cpu->isar.id_dfr0 = 0x400;
222
cpu->id_afr0 = 0;
223
- cpu->id_mmfr0 = 0x31100003;
224
- cpu->id_mmfr1 = 0x20000000;
225
- cpu->id_mmfr2 = 0x01202000;
226
- cpu->id_mmfr3 = 0x11;
227
+ cpu->isar.id_mmfr0 = 0x31100003;
228
+ cpu->isar.id_mmfr1 = 0x20000000;
229
+ cpu->isar.id_mmfr2 = 0x01202000;
230
+ cpu->isar.id_mmfr3 = 0x11;
231
cpu->isar.id_isar0 = 0x00101111;
232
cpu->isar.id_isar1 = 0x12112111;
233
cpu->isar.id_isar2 = 0x21232031;
234
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
235
cpu->id_pfr1 = 0x11;
236
cpu->isar.id_dfr0 = 0x000;
237
cpu->id_afr0 = 0;
238
- cpu->id_mmfr0 = 0x00100103;
239
- cpu->id_mmfr1 = 0x20000000;
240
- cpu->id_mmfr2 = 0x01230000;
241
- cpu->id_mmfr3 = 0x00002111;
242
+ cpu->isar.id_mmfr0 = 0x00100103;
243
+ cpu->isar.id_mmfr1 = 0x20000000;
244
+ cpu->isar.id_mmfr2 = 0x01230000;
245
+ cpu->isar.id_mmfr3 = 0x00002111;
246
cpu->isar.id_isar0 = 0x00101111;
247
cpu->isar.id_isar1 = 0x13112111;
248
cpu->isar.id_isar2 = 0x21232041;
249
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
250
cpu->id_pfr1 = 0x00011011;
251
cpu->isar.id_dfr0 = 0x02010555;
252
cpu->id_afr0 = 0x00000000;
253
- cpu->id_mmfr0 = 0x10101105;
254
- cpu->id_mmfr1 = 0x40000000;
255
- cpu->id_mmfr2 = 0x01240000;
256
- cpu->id_mmfr3 = 0x02102211;
257
+ cpu->isar.id_mmfr0 = 0x10101105;
258
+ cpu->isar.id_mmfr1 = 0x40000000;
259
+ cpu->isar.id_mmfr2 = 0x01240000;
260
+ cpu->isar.id_mmfr3 = 0x02102211;
261
/* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
262
* table 4-41 gives 0x02101110, which includes the arm div insns.
263
*/
264
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
265
cpu->id_pfr1 = 0x00011011;
266
cpu->isar.id_dfr0 = 0x02010555;
267
cpu->id_afr0 = 0x00000000;
268
- cpu->id_mmfr0 = 0x10201105;
269
- cpu->id_mmfr1 = 0x20000000;
270
- cpu->id_mmfr2 = 0x01240000;
271
- cpu->id_mmfr3 = 0x02102211;
272
+ cpu->isar.id_mmfr0 = 0x10201105;
273
+ cpu->isar.id_mmfr1 = 0x20000000;
274
+ cpu->isar.id_mmfr2 = 0x01240000;
275
+ cpu->isar.id_mmfr3 = 0x02102211;
276
cpu->isar.id_isar0 = 0x02101110;
277
cpu->isar.id_isar1 = 0x13112111;
278
cpu->isar.id_isar2 = 0x21232041;
279
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
280
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
281
cpu->isar.mvfr2 = t;
282
283
- t = cpu->id_mmfr3;
284
+ t = cpu->isar.id_mmfr3;
285
t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
286
- cpu->id_mmfr3 = t;
287
+ cpu->isar.id_mmfr3 = t;
288
289
- t = cpu->id_mmfr4;
290
+ t = cpu->isar.id_mmfr4;
291
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
292
- cpu->id_mmfr4 = t;
293
+ cpu->isar.id_mmfr4 = t;
48
}
294
}
49
#endif
295
#endif
50
+#ifdef TARGET_AARCH64
296
}
51
+ case TARGET_PR_SVE_SET_VL:
52
+ /* We cannot support either PR_SVE_SET_VL_ONEXEC
53
+ or PR_SVE_VL_INHERIT. Therefore, anything above
54
+ ARM_MAX_VQ results in EINVAL. */
55
+ ret = -TARGET_EINVAL;
56
+ if (arm_feature(cpu_env, ARM_FEATURE_SVE)
57
+ && arg2 >= 0 && arg2 <= ARM_MAX_VQ * 16 && !(arg2 & 15)) {
58
+ CPUARMState *env = cpu_env;
59
+ int old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
60
+ int vq = MAX(arg2 / 16, 1);
61
+
62
+ if (vq < old_vq) {
63
+ aarch64_sve_narrow_vq(env, vq);
64
+ }
65
+ env->vfp.zcr_el[1] = vq - 1;
66
+ ret = vq * 16;
67
+ }
68
+ break;
69
+ case TARGET_PR_SVE_GET_VL:
70
+ ret = -TARGET_EINVAL;
71
+ if (arm_feature(cpu_env, ARM_FEATURE_SVE)) {
72
+ CPUARMState *env = cpu_env;
73
+ ret = ((env->vfp.zcr_el[1] & 0xf) + 1) * 16;
74
+ }
75
+ break;
76
+#endif /* AARCH64 */
77
case PR_GET_SECCOMP:
78
case PR_SET_SECCOMP:
79
/* Disable seccomp to prevent the target disabling syscalls we
80
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
297
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
81
index XXXXXXX..XXXXXXX 100644
298
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/cpu64.c
299
--- a/target/arm/cpu64.c
83
+++ b/target/arm/cpu64.c
300
+++ b/target/arm/cpu64.c
84
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_register_types(void)
301
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
85
}
302
cpu->id_pfr1 = 0x00011011;
86
303
cpu->isar.id_dfr0 = 0x03010066;
87
type_init(aarch64_cpu_register_types)
304
cpu->id_afr0 = 0x00000000;
88
+
305
- cpu->id_mmfr0 = 0x10101105;
89
+/* The manual says that when SVE is enabled and VQ is widened the
306
- cpu->id_mmfr1 = 0x40000000;
90
+ * implementation is allowed to zero the previously inaccessible
307
- cpu->id_mmfr2 = 0x01260000;
91
+ * portion of the registers. The corollary to that is that when
308
- cpu->id_mmfr3 = 0x02102211;
92
+ * SVE is enabled and VQ is narrowed we are also allowed to zero
309
+ cpu->isar.id_mmfr0 = 0x10101105;
93
+ * the now inaccessible portion of the registers.
310
+ cpu->isar.id_mmfr1 = 0x40000000;
94
+ *
311
+ cpu->isar.id_mmfr2 = 0x01260000;
95
+ * The intent of this is that no predicate bit beyond VQ is ever set.
312
+ cpu->isar.id_mmfr3 = 0x02102211;
96
+ * Which means that some operations on predicate registers themselves
313
cpu->isar.id_isar0 = 0x02101110;
97
+ * may operate on full uint64_t or even unrolled across the maximum
314
cpu->isar.id_isar1 = 0x13112111;
98
+ * uint64_t[4]. Performing 4 bits of host arithmetic unconditionally
315
cpu->isar.id_isar2 = 0x21232042;
99
+ * may well be cheaper than conditionals to restrict the operation
316
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
100
+ * to the relevant portion of a uint16_t[16].
317
cpu->id_pfr1 = 0x00011011;
101
+ *
318
cpu->isar.id_dfr0 = 0x03010066;
102
+ * TODO: Need to call this for changes to the real system registers
319
cpu->id_afr0 = 0x00000000;
103
+ * and EL state changes.
320
- cpu->id_mmfr0 = 0x10101105;
104
+ */
321
- cpu->id_mmfr1 = 0x40000000;
105
+void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
322
- cpu->id_mmfr2 = 0x01260000;
106
+{
323
- cpu->id_mmfr3 = 0x02102211;
107
+ int i, j;
324
+ cpu->isar.id_mmfr0 = 0x10101105;
108
+ uint64_t pmask;
325
+ cpu->isar.id_mmfr1 = 0x40000000;
109
+
326
+ cpu->isar.id_mmfr2 = 0x01260000;
110
+ assert(vq >= 1 && vq <= ARM_MAX_VQ);
327
+ cpu->isar.id_mmfr3 = 0x02102211;
111
+
328
cpu->isar.id_isar0 = 0x02101110;
112
+ /* Zap the high bits of the zregs. */
329
cpu->isar.id_isar1 = 0x13112111;
113
+ for (i = 0; i < 32; i++) {
330
cpu->isar.id_isar2 = 0x21232042;
114
+ memset(&env->vfp.zregs[i].d[2 * vq], 0, 16 * (ARM_MAX_VQ - vq));
331
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
332
cpu->id_pfr1 = 0x00011011;
333
cpu->isar.id_dfr0 = 0x03010066;
334
cpu->id_afr0 = 0x00000000;
335
- cpu->id_mmfr0 = 0x10201105;
336
- cpu->id_mmfr1 = 0x40000000;
337
- cpu->id_mmfr2 = 0x01260000;
338
- cpu->id_mmfr3 = 0x02102211;
339
+ cpu->isar.id_mmfr0 = 0x10201105;
340
+ cpu->isar.id_mmfr1 = 0x40000000;
341
+ cpu->isar.id_mmfr2 = 0x01260000;
342
+ cpu->isar.id_mmfr3 = 0x02102211;
343
cpu->isar.id_isar0 = 0x02101110;
344
cpu->isar.id_isar1 = 0x13112111;
345
cpu->isar.id_isar2 = 0x21232042;
346
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
347
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
348
cpu->isar.id_isar6 = u;
349
350
- u = cpu->id_mmfr3;
351
+ u = cpu->isar.id_mmfr3;
352
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
353
- cpu->id_mmfr3 = u;
354
+ cpu->isar.id_mmfr3 = u;
355
356
u = cpu->isar.id_aa64dfr0;
357
u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
358
diff --git a/target/arm/helper.c b/target/arm/helper.c
359
index XXXXXXX..XXXXXXX 100644
360
--- a/target/arm/helper.c
361
+++ b/target/arm/helper.c
362
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
363
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
364
.access = PL1_R, .type = ARM_CP_CONST,
365
.accessfn = access_aa32_tid3,
366
- .resetvalue = cpu->id_mmfr0 },
367
+ .resetvalue = cpu->isar.id_mmfr0 },
368
{ .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
369
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
370
.access = PL1_R, .type = ARM_CP_CONST,
371
.accessfn = access_aa32_tid3,
372
- .resetvalue = cpu->id_mmfr1 },
373
+ .resetvalue = cpu->isar.id_mmfr1 },
374
{ .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
375
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
376
.access = PL1_R, .type = ARM_CP_CONST,
377
.accessfn = access_aa32_tid3,
378
- .resetvalue = cpu->id_mmfr2 },
379
+ .resetvalue = cpu->isar.id_mmfr2 },
380
{ .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
381
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
382
.access = PL1_R, .type = ARM_CP_CONST,
383
.accessfn = access_aa32_tid3,
384
- .resetvalue = cpu->id_mmfr3 },
385
+ .resetvalue = cpu->isar.id_mmfr3 },
386
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
387
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
388
.access = PL1_R, .type = ARM_CP_CONST,
389
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
390
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
391
.access = PL1_R, .type = ARM_CP_CONST,
392
.accessfn = access_aa32_tid3,
393
- .resetvalue = cpu->id_mmfr4 },
394
+ .resetvalue = cpu->isar.id_mmfr4 },
395
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
396
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
397
.access = PL1_R, .type = ARM_CP_CONST,
398
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
399
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
400
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
401
/* TTCBR2 is introduced with ARMv8.2-A32HPD. */
402
- if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) {
403
+ if (FIELD_EX32(cpu->isar.id_mmfr4, ID_MMFR4, HPDS) != 0) {
404
define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
405
}
406
}
407
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
408
index XXXXXXX..XXXXXXX 100644
409
--- a/target/arm/kvm32.c
410
+++ b/target/arm/kvm32.c
411
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
412
* Fortunately there is not yet anything in there that affects migration.
413
*/
414
415
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
416
+ ARM_CP15_REG32(0, 0, 1, 4));
417
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
418
+ ARM_CP15_REG32(0, 0, 1, 5));
419
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
420
+ ARM_CP15_REG32(0, 0, 1, 6));
421
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
422
+ ARM_CP15_REG32(0, 0, 1, 7));
423
+ if (read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
424
+ ARM_CP15_REG32(0, 0, 2, 6))) {
425
+ /*
426
+ * Older kernels don't support reading ID_MMFR4 (a new in v8
427
+ * register); assume it's zero.
428
+ */
429
+ ahcf->isar.id_mmfr4 = 0;
115
+ }
430
+ }
116
+
431
+
117
+ /* Zap the high bits of the pregs and ffr. */
432
/*
118
+ pmask = 0;
433
* There is no way to read DBGDIDR, because currently 32-bit KVM
119
+ if (vq & 3) {
434
* doesn't implement debug at all. Leave it at zero.
120
+ pmask = ~(-1ULL << (16 * (vq & 3)));
435
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
121
+ }
436
index XXXXXXX..XXXXXXX 100644
122
+ for (j = vq / 4; j < ARM_MAX_VQ / 4; j++) {
437
--- a/target/arm/kvm64.c
123
+ for (i = 0; i < 17; ++i) {
438
+++ b/target/arm/kvm64.c
124
+ env->vfp.pregs[i].p[j] &= pmask;
439
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
125
+ }
440
*/
126
+ pmask = 0;
441
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
127
+ }
442
ARM64_SYS_REG(3, 0, 0, 1, 2));
128
+}
443
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
444
+ ARM64_SYS_REG(3, 0, 0, 1, 4));
445
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
446
+ ARM64_SYS_REG(3, 0, 0, 1, 5));
447
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
448
+ ARM64_SYS_REG(3, 0, 0, 1, 6));
449
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
450
+ ARM64_SYS_REG(3, 0, 0, 1, 7));
451
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
452
ARM64_SYS_REG(3, 0, 0, 2, 0));
453
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
454
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
455
ARM64_SYS_REG(3, 0, 0, 2, 4));
456
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5,
457
ARM64_SYS_REG(3, 0, 0, 2, 5));
458
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
459
+ ARM64_SYS_REG(3, 0, 0, 2, 6));
460
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6,
461
ARM64_SYS_REG(3, 0, 0, 2, 7));
462
129
--
463
--
130
2.16.2
464
2.20.1
131
465
132
466
diff view generated by jsdifflib
1
Add support for passing 'max' to -machine gic-version. By analogy
1
Now we have moved ID_MMFR4 into the ARMISARegisters struct, we
2
with the -cpu max option, this picks the "best available" GIC version
2
can define and use an isar_feature for the presence of the
3
whether you're using KVM or TCG, so it behaves like 'host' when
3
ARMv8.2-AA32HPD feature, rather than open-coding the test.
4
using KVM, and gives you GICv3 when using TCG.
5
4
6
Also like '-cpu host', using -machine gic-version=max' means there
5
While we're here, correct a comment typo which missed an 'A'
7
is no guarantee of migration compatibility between QEMU versions;
6
from the feature name.
8
in future 'max' might mean '4'.
9
7
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180308130626.12393-7-peter.maydell@linaro.org
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20200214175116.9164-20-peter.maydell@linaro.org
13
---
11
---
14
hw/arm/virt.c | 29 +++++++++++++++++++----------
12
target/arm/cpu.h | 5 +++++
15
1 file changed, 19 insertions(+), 10 deletions(-)
13
target/arm/helper.c | 4 ++--
14
2 files changed, 7 insertions(+), 2 deletions(-)
16
15
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
18
--- a/target/arm/cpu.h
20
+++ b/hw/arm/virt.c
19
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id)
22
/* We can probe only here because during property set
21
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
23
* KVM is not available yet
22
}
24
*/
23
25
- if (!vms->gic_version) {
24
+static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
26
+ if (vms->gic_version <= 0) {
25
+{
27
+ /* "host" or "max" */
26
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
28
if (!kvm_enabled()) {
27
+}
29
- error_report("gic-version=host requires KVM");
28
+
30
- exit(1);
29
/*
31
- }
30
* 64-bit feature tests via id registers.
32
-
31
*/
33
- vms->gic_version = kvm_arm_vgic_probe();
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
- if (!vms->gic_version) {
33
index XXXXXXX..XXXXXXX 100644
35
- error_report("Unable to determine GIC version supported by host");
34
--- a/target/arm/helper.c
36
- exit(1);
35
+++ b/target/arm/helper.c
37
+ if (vms->gic_version == 0) {
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
38
+ error_report("gic-version=host requires KVM");
37
} else {
39
+ exit(1);
38
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
40
+ } else {
39
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
41
+ /* "max": currently means 3 for TCG */
40
- /* TTCBR2 is introduced with ARMv8.2-A32HPD. */
42
+ vms->gic_version = 3;
41
- if (FIELD_EX32(cpu->isar.id_mmfr4, ID_MMFR4, HPDS) != 0) {
43
+ }
42
+ /* TTCBR2 is introduced with ARMv8.2-AA32HPD. */
44
+ } else {
43
+ if (cpu_isar_feature(aa32_hpd, cpu)) {
45
+ vms->gic_version = kvm_arm_vgic_probe();
44
define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
46
+ if (!vms->gic_version) {
47
+ error_report(
48
+ "Unable to determine GIC version supported by host");
49
+ exit(1);
50
+ }
51
}
45
}
52
}
46
}
53
54
@@ -XXX,XX +XXX,XX @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
55
vms->gic_version = 2;
56
} else if (!strcmp(value, "host")) {
57
vms->gic_version = 0; /* Will probe later */
58
+ } else if (!strcmp(value, "max")) {
59
+ vms->gic_version = -1; /* Will probe later */
60
} else {
61
error_setg(errp, "Invalid gic-version value");
62
- error_append_hint(errp, "Valid values are 3, 2, host.\n");
63
+ error_append_hint(errp, "Valid values are 3, 2, host, max.\n");
64
}
65
}
66
67
--
47
--
68
2.16.2
48
2.20.1
69
49
70
50
diff view generated by jsdifflib
1
Move the definition of the 'host' cpu type into cpu.c, where all the
1
Cut-and-paste errors mean we're using FIELD_EX64() to extract fields from
2
other CPU types are defined. We can do this now we've decoupled it
2
some 32-bit ID register fields. Use FIELD_EX32() instead. (This makes
3
from the KVM-specific host feature probing. This means we now create
3
no difference in behaviour, it's just more consistent.)
4
the type unconditionally (assuming we were built with KVM support at
5
all), but if you try to use it without -enable-kvm this will end
6
up in the "host cpu probe failed and KVM not enabled" path in
7
arm_cpu_realizefn(), for an appropriate error message.
8
4
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20200214175116.9164-21-peter.maydell@linaro.org
12
Message-id: 20180308130626.12393-3-peter.maydell@linaro.org
13
---
8
---
14
target/arm/cpu.c | 24 ++++++++++++++++++++++++
9
target/arm/cpu.h | 18 +++++++++---------
15
target/arm/kvm.c | 19 -------------------
10
1 file changed, 9 insertions(+), 9 deletions(-)
16
2 files changed, 24 insertions(+), 19 deletions(-)
17
11
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
14
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.c
15
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
23
#endif
17
static inline bool isar_feature_aa32_fp_d32(const ARMISARegisters *id)
18
{
19
/* Return true if D16-D31 are implemented */
20
- return FIELD_EX64(id->mvfr0, MVFR0, SIMDREG) >= 2;
21
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) >= 2;
24
}
22
}
25
23
26
+#ifdef CONFIG_KVM
24
static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
27
+static void arm_host_initfn(Object *obj)
28
+{
29
+ ARMCPU *cpu = ARM_CPU(obj);
30
+
31
+ kvm_arm_set_cpu_features_from_host(cpu);
32
+}
33
+
34
+static const TypeInfo host_arm_cpu_type_info = {
35
+ .name = TYPE_ARM_HOST_CPU,
36
+#ifdef TARGET_AARCH64
37
+ .parent = TYPE_AARCH64_CPU,
38
+#else
39
+ .parent = TYPE_ARM_CPU,
40
+#endif
41
+ .instance_init = arm_host_initfn,
42
+};
43
+
44
+#endif
45
+
46
static void cpu_register(const ARMCPUInfo *info)
47
{
25
{
48
TypeInfo type_info = {
26
- return FIELD_EX64(id->mvfr0, MVFR0, FPSHVEC) > 0;
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
27
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
50
cpu_register(info);
51
info++;
52
}
53
+
54
+#ifdef CONFIG_KVM
55
+ type_register_static(&host_arm_cpu_type_info);
56
+#endif
57
}
28
}
58
29
59
type_init(arm_cpu_register_types)
30
static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
60
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
31
{
61
index XXXXXXX..XXXXXXX 100644
32
/* Return true if CPU supports double precision floating point */
62
--- a/target/arm/kvm.c
33
- return FIELD_EX64(id->mvfr0, MVFR0, FPDP) > 0;
63
+++ b/target/arm/kvm.c
34
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
64
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
65
env->features = arm_host_cpu_features.features;
66
}
35
}
67
36
68
-static void kvm_arm_host_cpu_initfn(Object *obj)
37
/*
69
-{
38
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
70
- ARMCPU *cpu = ARM_CPU(obj);
39
*/
71
-
40
static inline bool isar_feature_aa32_fp16_spconv(const ARMISARegisters *id)
72
- kvm_arm_set_cpu_features_from_host(cpu);
73
-}
74
-
75
-static const TypeInfo host_arm_cpu_type_info = {
76
- .name = TYPE_ARM_HOST_CPU,
77
-#ifdef TARGET_AARCH64
78
- .parent = TYPE_AARCH64_CPU,
79
-#else
80
- .parent = TYPE_ARM_CPU,
81
-#endif
82
- .instance_init = kvm_arm_host_cpu_initfn,
83
-};
84
-
85
int kvm_arch_init(MachineState *ms, KVMState *s)
86
{
41
{
87
/* For ARM interrupt delivery is always asynchronous,
42
- return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 0;
88
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
43
+ return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 0;
89
90
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
91
92
- type_register_static(&host_arm_cpu_type_info);
93
-
94
return 0;
95
}
44
}
96
45
46
static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
47
{
48
- return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 1;
49
+ return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 1;
50
}
51
52
static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
53
{
54
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 1;
55
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 1;
56
}
57
58
static inline bool isar_feature_aa32_vcvt_dr(const ARMISARegisters *id)
59
{
60
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 2;
61
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 2;
62
}
63
64
static inline bool isar_feature_aa32_vrint(const ARMISARegisters *id)
65
{
66
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 3;
67
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 3;
68
}
69
70
static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
71
{
72
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4;
73
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 4;
74
}
75
76
static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
97
--
77
--
98
2.16.2
78
2.20.1
99
79
100
80
diff view generated by jsdifflib
1
Now we have a working '-cpu max', the linux-user-only
1
The ACTLR2 and HACTLR2 AArch32 system registers didn't exist in ARMv7
2
'any' CPU is pretty much the same thing, so implement it
2
or the original ARMv8. They were later added as optional registers,
3
that way.
3
whose presence is signaled by the ID_MMFR4.AC2 field. From ARMv8.2
4
they are mandatory (ie ID_MMFR4.AC2 must be non-zero).
4
5
5
For the moment we don't add any of the extra feature bits
6
We implemented HACTLR2 in commit 0e0456ab8895a5e85, but we
6
to the system-emulation "max", because we don't set the
7
incorrectly made it exist for all v8 CPUs, and we didn't implement
7
ID register bits we would need to to advertise those
8
ACTLR2 at all.
8
features as present.
9
9
10
Sort this out by implementing both registers only when they are
11
supposed to exist, and setting the ID_MMFR4 bit for -cpu max.
12
13
Note that this removes HACTLR2 from our Cortex-A53, -A47 and -A72
14
CPU models; this is correct, because those CPUs do not implement
15
this register.
16
17
Fixes: 0e0456ab8895a5e85
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180308130626.12393-5-peter.maydell@linaro.org
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Message-id: 20200214175116.9164-22-peter.maydell@linaro.org
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
---
21
---
15
target/arm/cpu.c | 52 +++++++++++++++++++++++++----------------------
22
target/arm/cpu.h | 5 +++++
16
target/arm/cpu64.c | 59 ++++++++++++++++++++++++++----------------------------
23
target/arm/cpu.c | 1 +
17
2 files changed, 56 insertions(+), 55 deletions(-)
24
target/arm/cpu64.c | 4 ++++
25
target/arm/helper.c | 32 +++++++++++++++++++++++---------
26
4 files changed, 33 insertions(+), 9 deletions(-)
18
27
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
33
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
34
}
35
36
+static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
37
+{
38
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
39
+}
40
+
41
/*
42
* 64-bit feature tests via id registers.
43
*/
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
46
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
24
ObjectClass *oc;
25
char *typename;
26
char **cpuname;
27
+ const char *cpunamestr;
28
29
cpuname = g_strsplit(cpu_model, ",", 1);
30
- typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpuname[0]);
31
+ cpunamestr = cpuname[0];
32
+#ifdef CONFIG_USER_ONLY
33
+ /* For backwards compatibility usermode emulation allows "-cpu any",
34
+ * which has the same semantics as "-cpu max".
35
+ */
36
+ if (!strcmp(cpunamestr, "any")) {
37
+ cpunamestr = "max";
38
+ }
39
+#endif
40
+ typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpunamestr);
41
oc = object_class_by_name(typename);
42
g_strfreev(cpuname);
43
g_free(typename);
44
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
48
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
45
kvm_arm_set_cpu_features_from_host(cpu);
49
46
} else {
50
t = cpu->isar.id_mmfr4;
47
cortex_a15_initfn(obj);
51
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
48
- /* In future we might add feature bits here even if the
52
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
49
- * real-world A15 doesn't implement them.
53
cpu->isar.id_mmfr4 = t;
50
- */
54
}
51
- }
52
-}
53
-#endif
54
-
55
#ifdef CONFIG_USER_ONLY
56
-static void arm_any_initfn(Object *obj)
57
-{
58
- ARMCPU *cpu = ARM_CPU(obj);
59
- set_feature(&cpu->env, ARM_FEATURE_V8);
60
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
61
- set_feature(&cpu->env, ARM_FEATURE_NEON);
62
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
63
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
64
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
65
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
66
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
67
- set_feature(&cpu->env, ARM_FEATURE_CRC);
68
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
69
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
70
- cpu->midr = 0xffffffff;
71
+ /* We don't set these in system emulation mode for the moment,
72
+ * since we don't correctly set the ID registers to advertise them,
73
+ */
74
+ set_feature(&cpu->env, ARM_FEATURE_V8);
75
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
76
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
77
+ set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
78
+ set_feature(&cpu->env, ARM_FEATURE_V8_AES);
79
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
80
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
81
+ set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
82
+ set_feature(&cpu->env, ARM_FEATURE_CRC);
83
+ set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
84
+ set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
85
+#endif
86
+ }
87
}
88
#endif
55
#endif
89
90
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
91
{ .name = "max", .initfn = arm_max_initfn },
92
#endif
93
#ifdef CONFIG_USER_ONLY
94
- { .name = "any", .initfn = arm_any_initfn },
95
+ { .name = "any", .initfn = arm_max_initfn },
96
#endif
97
#endif
98
{ .name = NULL }
99
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
56
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
100
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/cpu64.c
58
--- a/target/arm/cpu64.c
102
+++ b/target/arm/cpu64.c
59
+++ b/target/arm/cpu64.c
103
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
60
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
104
kvm_arm_set_cpu_features_from_host(cpu);
61
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
105
} else {
62
cpu->isar.id_mmfr3 = u;
106
aarch64_a57_initfn(obj);
63
107
- /* In future we might add feature bits here even if the
64
+ u = cpu->isar.id_mmfr4;
108
- * real-world A57 doesn't implement them.
65
+ u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
109
+#ifdef CONFIG_USER_ONLY
66
+ cpu->isar.id_mmfr4 = u;
110
+ /* We don't set these in system emulation mode for the moment,
67
+
111
+ * since we don't correctly set the ID registers to advertise them,
68
u = cpu->isar.id_aa64dfr0;
112
+ * and in some cases they're only available in AArch64 and not AArch32,
69
u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
113
+ * whereas the architecture requires them to be present in both if
70
cpu->isar.id_aa64dfr0 = u;
114
+ * present in either.
71
diff --git a/target/arm/helper.c b/target/arm/helper.c
115
*/
72
index XXXXXXX..XXXXXXX 100644
116
+ set_feature(&cpu->env, ARM_FEATURE_V8);
73
--- a/target/arm/helper.c
117
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
74
+++ b/target/arm/helper.c
118
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
75
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
119
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
76
};
120
+ set_feature(&cpu->env, ARM_FEATURE_V8_AES);
77
#endif
121
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
78
122
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
79
+/*
123
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
80
+ * ACTLR2 and HACTLR2 map to ACTLR_EL1[63:32] and
124
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
81
+ * ACTLR_EL2[63:32]. They exist only if the ID_MMFR4.AC2 field
125
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
82
+ * is non-zero, which is never for ARMv7, optionally in ARMv8
126
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
83
+ * and mandatorily for ARMv8.2 and up.
127
+ set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
84
+ * ACTLR2 is banked for S and NS if EL3 is AArch32. Since QEMU's
128
+ set_feature(&cpu->env, ARM_FEATURE_CRC);
85
+ * implementation is RAZ/WI we can ignore this detail, as we
129
+ set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
86
+ * do for ACTLR.
130
+ set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
87
+ */
131
+ set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
88
+static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
132
+ /* For usermode -cpu max we can use a larger and more efficient DCZ
89
+ { .name = "ACTLR2", .state = ARM_CP_STATE_AA32,
133
+ * blocksize since we don't have to follow what the hardware does.
90
+ .cp = 15, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 3,
134
+ */
91
+ .access = PL1_RW, .type = ARM_CP_CONST,
135
+ cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
92
+ .resetvalue = 0 },
136
+ cpu->dcz_blocksize = 7; /* 512 bytes */
93
+ { .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
137
+#endif
94
+ .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
95
+ .access = PL2_RW, .type = ARM_CP_CONST,
96
+ .resetvalue = 0 },
97
+ REGINFO_SENTINEL
98
+};
99
+
100
void register_cp_regs_for_features(ARMCPU *cpu)
101
{
102
/* Register all the coprocessor registers based on feature bits */
103
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
104
REGINFO_SENTINEL
105
};
106
define_arm_cp_regs(cpu, auxcr_reginfo);
107
- if (arm_feature(env, ARM_FEATURE_V8)) {
108
- /* HACTLR2 maps to ACTLR_EL2[63:32] and is not in ARMv7 */
109
- ARMCPRegInfo hactlr2_reginfo = {
110
- .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
111
- .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
112
- .access = PL2_RW, .type = ARM_CP_CONST,
113
- .resetvalue = 0
114
- };
115
- define_one_arm_cp_reg(cpu, &hactlr2_reginfo);
116
+ if (cpu_isar_feature(aa32_ac2, cpu)) {
117
+ define_arm_cp_regs(cpu, actlr2_hactlr2_reginfo);
118
}
138
}
119
}
139
}
140
141
-#ifdef CONFIG_USER_ONLY
142
-static void aarch64_any_initfn(Object *obj)
143
-{
144
- ARMCPU *cpu = ARM_CPU(obj);
145
-
146
- set_feature(&cpu->env, ARM_FEATURE_V8);
147
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
148
- set_feature(&cpu->env, ARM_FEATURE_NEON);
149
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
150
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
151
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
152
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
153
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
154
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
155
- set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
156
- set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
157
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
158
- set_feature(&cpu->env, ARM_FEATURE_CRC);
159
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
160
- set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
161
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
162
- cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
163
- cpu->dcz_blocksize = 7; /* 512 bytes */
164
-}
165
-#endif
166
-
167
typedef struct ARMCPUInfo {
168
const char *name;
169
void (*initfn)(Object *obj);
170
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
171
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
172
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
173
{ .name = "max", .initfn = aarch64_max_initfn },
174
-#ifdef CONFIG_USER_ONLY
175
- { .name = "any", .initfn = aarch64_any_initfn },
176
-#endif
177
{ .name = NULL }
178
};
179
120
180
--
121
--
181
2.16.2
122
2.20.1
182
123
183
124
diff view generated by jsdifflib
New patch
1
From: Guenter Roeck <linux@roeck-us.net>
1
2
3
We need to be able to use OHCISysBusState outside hcd-ohci.c, so move it
4
to its include file.
5
6
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Message-id: 20200217204812.9857-2-linux@roeck-us.net
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/usb/hcd-ohci.h | 16 ++++++++++++++++
13
hw/usb/hcd-ohci.c | 15 ---------------
14
2 files changed, 16 insertions(+), 15 deletions(-)
15
16
diff --git a/hw/usb/hcd-ohci.h b/hw/usb/hcd-ohci.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/usb/hcd-ohci.h
19
+++ b/hw/usb/hcd-ohci.h
20
@@ -XXX,XX +XXX,XX @@
21
#define HCD_OHCI_H
22
23
#include "sysemu/dma.h"
24
+#include "hw/usb.h"
25
26
/* Number of Downstream Ports on the root hub: */
27
#define OHCI_MAX_PORTS 15
28
@@ -XXX,XX +XXX,XX @@ typedef struct OHCIState {
29
void (*ohci_die)(struct OHCIState *ohci);
30
} OHCIState;
31
32
+#define TYPE_SYSBUS_OHCI "sysbus-ohci"
33
+#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
34
+
35
+typedef struct {
36
+ /*< private >*/
37
+ SysBusDevice parent_obj;
38
+ /*< public >*/
39
+
40
+ OHCIState ohci;
41
+ char *masterbus;
42
+ uint32_t num_ports;
43
+ uint32_t firstport;
44
+ dma_addr_t dma_offset;
45
+} OHCISysBusState;
46
+
47
extern const VMStateDescription vmstate_ohci_state;
48
49
void usb_ohci_init(OHCIState *ohci, DeviceState *dev, uint32_t num_ports,
50
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/usb/hcd-ohci.c
53
+++ b/hw/usb/hcd-ohci.c
54
@@ -XXX,XX +XXX,XX @@ void ohci_sysbus_die(struct OHCIState *ohci)
55
ohci_bus_stop(ohci);
56
}
57
58
-#define TYPE_SYSBUS_OHCI "sysbus-ohci"
59
-#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
60
-
61
-typedef struct {
62
- /*< private >*/
63
- SysBusDevice parent_obj;
64
- /*< public >*/
65
-
66
- OHCIState ohci;
67
- char *masterbus;
68
- uint32_t num_ports;
69
- uint32_t firstport;
70
- dma_addr_t dma_offset;
71
-} OHCISysBusState;
72
-
73
static void ohci_realize_pxa(DeviceState *dev, Error **errp)
74
{
75
OHCISysBusState *s = SYSBUS_OHCI(dev);
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Set the ARM CPU core count property for the A53's attached to the Xilnx
3
We'll use this property in a follow-up patch to insantiate an EHCI
4
ZynqMP machine.
4
bus with companion support.
5
5
6
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
6
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: fe0dd90b85ac73f9fc9548c253bededa70a07006.1520018138.git.alistair.francis@xilinx.com
8
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Message-id: 20200217204812.9857-3-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
hw/arm/xlnx-zynqmp.c | 2 ++
12
hw/usb/hcd-ehci-sysbus.c | 2 ++
12
1 file changed, 2 insertions(+)
13
1 file changed, 2 insertions(+)
13
14
14
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
15
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-zynqmp.c
17
--- a/hw/usb/hcd-ehci-sysbus.c
17
+++ b/hw/arm/xlnx-zynqmp.c
18
+++ b/hw/usb/hcd-ehci-sysbus.c
18
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_ehci_sysbus = {
19
s->virt, "has_el2", NULL);
20
20
object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR,
21
static Property ehci_sysbus_properties[] = {
21
"reset-cbar", &error_abort);
22
DEFINE_PROP_UINT32("maxframes", EHCISysBusState, ehci.maxframes, 128),
22
+ object_property_set_int(OBJECT(&s->apu_cpu[i]), num_apus,
23
+ DEFINE_PROP_BOOL("companion-enable", EHCISysBusState, ehci.companion_enable,
23
+ "core-count", &error_abort);
24
+ false),
24
object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized",
25
DEFINE_PROP_END_OF_LIST(),
25
&err);
26
};
26
if (err) {
27
27
--
28
--
28
2.16.2
29
2.20.1
29
30
30
31
diff view generated by jsdifflib
New patch
1
From: Guenter Roeck <linux@roeck-us.net>
1
2
3
Instantiate EHCI and OHCI controllers on Allwinner A10. OHCI ports are
4
modeled as companions of the respective EHCI ports.
5
6
With this patch applied, USB controllers are discovered and instantiated
7
when booting the cubieboard machine with a recent Linux kernel.
8
9
ehci-platform 1c14000.usb: EHCI Host Controller
10
ehci-platform 1c14000.usb: new USB bus registered, assigned bus number 1
11
ehci-platform 1c14000.usb: irq 26, io mem 0x01c14000
12
ehci-platform 1c14000.usb: USB 2.0 started, EHCI 1.00
13
ehci-platform 1c1c000.usb: EHCI Host Controller
14
ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 2
15
ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
16
ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00
17
ohci-platform 1c14400.usb: Generic Platform OHCI controller
18
ohci-platform 1c14400.usb: new USB bus registered, assigned bus number 3
19
ohci-platform 1c14400.usb: irq 27, io mem 0x01c14400
20
ohci-platform 1c1c400.usb: Generic Platform OHCI controller
21
ohci-platform 1c1c400.usb: new USB bus registered, assigned bus number 4
22
ohci-platform 1c1c400.usb: irq 32, io mem 0x01c1c400
23
usb 2-1: new high-speed USB device number 2 using ehci-platform
24
usb-storage 2-1:1.0: USB Mass Storage device detected
25
scsi host1: usb-storage 2-1:1.0
26
usb 3-1: new full-speed USB device number 2 using ohci-platform
27
input: QEMU QEMU USB Mouse as /devices/platform/soc/1c14400.usb/usb3/3-1/3-1:1.0/0003:0627:0001.0001/input/input0
28
29
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
30
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
31
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
32
Message-id: 20200217204812.9857-4-linux@roeck-us.net
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
---
35
include/hw/arm/allwinner-a10.h | 6 +++++
36
hw/arm/allwinner-a10.c | 43 ++++++++++++++++++++++++++++++++++
37
2 files changed, 49 insertions(+)
38
39
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/arm/allwinner-a10.h
42
+++ b/include/hw/arm/allwinner-a10.h
43
@@ -XXX,XX +XXX,XX @@
44
#include "hw/intc/allwinner-a10-pic.h"
45
#include "hw/net/allwinner_emac.h"
46
#include "hw/ide/ahci.h"
47
+#include "hw/usb/hcd-ohci.h"
48
+#include "hw/usb/hcd-ehci.h"
49
50
#include "target/arm/cpu.h"
51
52
53
#define AW_A10_SDRAM_BASE 0x40000000
54
55
+#define AW_A10_NUM_USB 2
56
+
57
#define TYPE_AW_A10 "allwinner-a10"
58
#define AW_A10(obj) OBJECT_CHECK(AwA10State, (obj), TYPE_AW_A10)
59
60
@@ -XXX,XX +XXX,XX @@ typedef struct AwA10State {
61
AwEmacState emac;
62
AllwinnerAHCIState sata;
63
MemoryRegion sram_a;
64
+ EHCISysBusState ehci[AW_A10_NUM_USB];
65
+ OHCISysBusState ohci[AW_A10_NUM_USB];
66
} AwA10State;
67
68
#endif
69
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/arm/allwinner-a10.c
72
+++ b/hw/arm/allwinner-a10.c
73
@@ -XXX,XX +XXX,XX @@
74
#include "hw/arm/allwinner-a10.h"
75
#include "hw/misc/unimp.h"
76
#include "sysemu/sysemu.h"
77
+#include "hw/boards.h"
78
+#include "hw/usb/hcd-ohci.h"
79
80
#define AW_A10_PIC_REG_BASE 0x01c20400
81
#define AW_A10_PIT_REG_BASE 0x01c20c00
82
#define AW_A10_UART0_REG_BASE 0x01c28000
83
#define AW_A10_EMAC_BASE 0x01c0b000
84
+#define AW_A10_EHCI_BASE 0x01c14000
85
+#define AW_A10_OHCI_BASE 0x01c14400
86
#define AW_A10_SATA_BASE 0x01c18000
87
88
static void aw_a10_init(Object *obj)
89
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
90
91
sysbus_init_child_obj(obj, "sata", &s->sata, sizeof(s->sata),
92
TYPE_ALLWINNER_AHCI);
93
+
94
+ if (machine_usb(current_machine)) {
95
+ int i;
96
+
97
+ for (i = 0; i < AW_A10_NUM_USB; i++) {
98
+ sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]),
99
+ sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI);
100
+ sysbus_init_child_obj(obj, "ohci[*]", OBJECT(&s->ohci[i]),
101
+ sizeof(s->ohci[i]), TYPE_SYSBUS_OHCI);
102
+ }
103
+ }
104
}
105
106
static void aw_a10_realize(DeviceState *dev, Error **errp)
107
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
108
serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2,
109
qdev_get_gpio_in(dev, 1),
110
115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
111
+
112
+ if (machine_usb(current_machine)) {
113
+ int i;
114
+
115
+ for (i = 0; i < AW_A10_NUM_USB; i++) {
116
+ char bus[16];
117
+
118
+ sprintf(bus, "usb-bus.%d", i);
119
+
120
+ object_property_set_bool(OBJECT(&s->ehci[i]), true,
121
+ "companion-enable", &error_fatal);
122
+ object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized",
123
+ &error_fatal);
124
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
125
+ AW_A10_EHCI_BASE + i * 0x8000);
126
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
127
+ qdev_get_gpio_in(dev, 39 + i));
128
+
129
+ object_property_set_str(OBJECT(&s->ohci[i]), bus, "masterbus",
130
+ &error_fatal);
131
+ object_property_set_bool(OBJECT(&s->ohci[i]), true, "realized",
132
+ &error_fatal);
133
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ohci[i]), 0,
134
+ AW_A10_OHCI_BASE + i * 0x8000);
135
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci[i]), 0,
136
+ qdev_get_gpio_in(dev, 64 + i));
137
+ }
138
+ }
139
}
140
141
static void aw_a10_class_init(ObjectClass *oc, void *data)
142
--
143
2.20.1
144
145
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This changes the qemu signal frame layout to be more like the kernel's,
3
These instructions shift left or right depending on the sign
4
in that the various records are dynamically allocated rather than fixed
4
of the input, and 7 bits are significant to the shift. This
5
in place by a structure.
5
requires several masks and selects in addition to the actual
6
shifts to form the complete answer.
6
7
7
For now, all of the allocation is out of uc.tuc_mcontext.__reserved,
8
That said, the operation is still a small improvement even for
8
so the allocation is actually trivial. That will change with SVE support.
9
two 64-bit elements -- 13 vector operations instead of 2 * 7
10
integer operations.
9
11
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20180303143823.27055-4-richard.henderson@linaro.org
14
Message-id: 20200216214232.4230-2-richard.henderson@linaro.org
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
---
16
linux-user/signal.c | 89 ++++++++++++++++++++++++++++++++++++-----------------
17
target/arm/helper.h | 11 +-
17
1 file changed, 61 insertions(+), 28 deletions(-)
18
target/arm/translate.h | 6 +
19
target/arm/neon_helper.c | 33 ----
20
target/arm/translate-a64.c | 18 +--
21
target/arm/translate.c | 299 +++++++++++++++++++++++++++++++++++--
22
target/arm/vec_helper.c | 88 +++++++++++
23
6 files changed, 389 insertions(+), 66 deletions(-)
18
24
19
diff --git a/linux-user/signal.c b/linux-user/signal.c
25
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
21
--- a/linux-user/signal.c
27
--- a/target/arm/helper.h
22
+++ b/linux-user/signal.c
28
+++ b/target/arm/helper.h
23
@@ -XXX,XX +XXX,XX @@ struct target_fpsimd_context {
29
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_abd_s16, i32, i32, i32)
24
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
30
DEF_HELPER_2(neon_abd_u32, i32, i32, i32)
31
DEF_HELPER_2(neon_abd_s32, i32, i32, i32)
32
33
-DEF_HELPER_2(neon_shl_u8, i32, i32, i32)
34
-DEF_HELPER_2(neon_shl_s8, i32, i32, i32)
35
DEF_HELPER_2(neon_shl_u16, i32, i32, i32)
36
DEF_HELPER_2(neon_shl_s16, i32, i32, i32)
37
-DEF_HELPER_2(neon_shl_u32, i32, i32, i32)
38
-DEF_HELPER_2(neon_shl_s32, i32, i32, i32)
39
-DEF_HELPER_2(neon_shl_u64, i64, i64, i64)
40
-DEF_HELPER_2(neon_shl_s64, i64, i64, i64)
41
DEF_HELPER_2(neon_rshl_u8, i32, i32, i32)
42
DEF_HELPER_2(neon_rshl_s8, i32, i32, i32)
43
DEF_HELPER_2(neon_rshl_u16, i32, i32, i32)
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(frint64_s, TCG_CALL_NO_RWG, f32, f32, ptr)
45
DEF_HELPER_FLAGS_2(frint32_d, TCG_CALL_NO_RWG, f64, f64, ptr)
46
DEF_HELPER_FLAGS_2(frint64_d, TCG_CALL_NO_RWG, f64, f64, ptr)
47
48
+DEF_HELPER_FLAGS_4(gvec_sshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
+DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
52
+
53
#ifdef TARGET_AARCH64
54
#include "helper-a64.h"
55
#include "helper-sve.h"
56
diff --git a/target/arm/translate.h b/target/arm/translate.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate.h
59
+++ b/target/arm/translate.h
60
@@ -XXX,XX +XXX,XX @@ uint64_t vfp_expand_imm(int size, uint8_t imm8);
61
extern const GVecGen3 mla_op[4];
62
extern const GVecGen3 mls_op[4];
63
extern const GVecGen3 cmtst_op[4];
64
+extern const GVecGen3 sshl_op[4];
65
+extern const GVecGen3 ushl_op[4];
66
extern const GVecGen2i ssra_op[4];
67
extern const GVecGen2i usra_op[4];
68
extern const GVecGen2i sri_op[4];
69
@@ -XXX,XX +XXX,XX @@ extern const GVecGen4 sqadd_op[4];
70
extern const GVecGen4 uqsub_op[4];
71
extern const GVecGen4 sqsub_op[4];
72
void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
73
+void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
74
+void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
75
+void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
76
+void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
77
78
/*
79
* Forward to the isar_feature_* tests given a DisasContext pointer.
80
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/neon_helper.c
83
+++ b/target/arm/neon_helper.c
84
@@ -XXX,XX +XXX,XX @@ NEON_VOP(abd_u32, neon_u32, 1)
85
} else { \
86
dest = src1 << tmp; \
87
}} while (0)
88
-NEON_VOP(shl_u8, neon_u8, 4)
89
NEON_VOP(shl_u16, neon_u16, 2)
90
-NEON_VOP(shl_u32, neon_u32, 1)
91
#undef NEON_FN
92
93
-uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
94
-{
95
- int8_t shift = (int8_t)shiftop;
96
- if (shift >= 64 || shift <= -64) {
97
- val = 0;
98
- } else if (shift < 0) {
99
- val >>= -shift;
100
- } else {
101
- val <<= shift;
102
- }
103
- return val;
104
-}
105
-
106
#define NEON_FN(dest, src1, src2) do { \
107
int8_t tmp; \
108
tmp = (int8_t)src2; \
109
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
110
} else { \
111
dest = src1 << tmp; \
112
}} while (0)
113
-NEON_VOP(shl_s8, neon_s8, 4)
114
NEON_VOP(shl_s16, neon_s16, 2)
115
-NEON_VOP(shl_s32, neon_s32, 1)
116
#undef NEON_FN
117
118
-uint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop)
119
-{
120
- int8_t shift = (int8_t)shiftop;
121
- int64_t val = valop;
122
- if (shift >= 64) {
123
- val = 0;
124
- } else if (shift <= -64) {
125
- val >>= 63;
126
- } else if (shift < 0) {
127
- val >>= -shift;
128
- } else {
129
- val <<= shift;
130
- }
131
- return val;
132
-}
133
-
134
#define NEON_FN(dest, src1, src2) do { \
135
int8_t tmp; \
136
tmp = (int8_t)src2; \
137
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/arm/translate-a64.c
140
+++ b/target/arm/translate-a64.c
141
@@ -XXX,XX +XXX,XX @@ static void handle_3same_64(DisasContext *s, int opcode, bool u,
142
break;
143
case 0x8: /* SSHL, USHL */
144
if (u) {
145
- gen_helper_neon_shl_u64(tcg_rd, tcg_rn, tcg_rm);
146
+ gen_ushl_i64(tcg_rd, tcg_rn, tcg_rm);
147
} else {
148
- gen_helper_neon_shl_s64(tcg_rd, tcg_rn, tcg_rm);
149
+ gen_sshl_i64(tcg_rd, tcg_rn, tcg_rm);
150
}
151
break;
152
case 0x9: /* SQSHL, UQSHL */
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
154
is_q ? 16 : 8, vec_full_reg_size(s),
155
(u ? uqsub_op : sqsub_op) + size);
156
return;
157
+ case 0x08: /* SSHL, USHL */
158
+ gen_gvec_op3(s, is_q, rd, rn, rm,
159
+ u ? &ushl_op[size] : &sshl_op[size]);
160
+ return;
161
case 0x0c: /* SMAX, UMAX */
162
if (u) {
163
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
164
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
165
genfn = fns[size][u];
166
break;
167
}
168
- case 0x8: /* SSHL, USHL */
169
- {
170
- static NeonGenTwoOpFn * const fns[3][2] = {
171
- { gen_helper_neon_shl_s8, gen_helper_neon_shl_u8 },
172
- { gen_helper_neon_shl_s16, gen_helper_neon_shl_u16 },
173
- { gen_helper_neon_shl_s32, gen_helper_neon_shl_u32 },
174
- };
175
- genfn = fns[size][u];
176
- break;
177
- }
178
case 0x9: /* SQSHL, UQSHL */
179
{
180
static NeonGenTwoOpEnvFn * const fns[3][2] = {
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/arm/translate.c
184
+++ b/target/arm/translate.c
185
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
186
if (u) {
187
switch (size) {
188
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
189
- case 2: gen_helper_neon_shl_u32(var, var, shift); break;
190
+ case 2: gen_ushl_i32(var, var, shift); break;
191
default: abort();
192
}
193
} else {
194
switch (size) {
195
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
196
- case 2: gen_helper_neon_shl_s32(var, var, shift); break;
197
+ case 2: gen_sshl_i32(var, var, shift); break;
198
default: abort();
199
}
200
}
201
@@ -XXX,XX +XXX,XX @@ const GVecGen3 cmtst_op[4] = {
202
.vece = MO_64 },
25
};
203
};
26
204
27
-/*
205
+void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
28
- * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
206
+{
29
- * user space as it will change with the addition of new context. User space
207
+ TCGv_i32 lval = tcg_temp_new_i32();
30
- * should check the magic/size information.
208
+ TCGv_i32 rval = tcg_temp_new_i32();
31
- */
209
+ TCGv_i32 lsh = tcg_temp_new_i32();
32
-struct target_aux_context {
210
+ TCGv_i32 rsh = tcg_temp_new_i32();
33
- struct target_fpsimd_context fpsimd;
211
+ TCGv_i32 zero = tcg_const_i32(0);
34
- /* additional context to be added before "end" */
212
+ TCGv_i32 max = tcg_const_i32(32);
35
- struct target_aarch64_ctx end;
213
+
36
-};
214
+ /*
37
-
215
+ * Rely on the TCG guarantee that out of range shifts produce
38
struct target_rt_sigframe {
216
+ * unspecified results, not undefined behaviour (i.e. no trap).
39
struct target_siginfo info;
217
+ * Discard out-of-range results after the fact.
40
struct target_ucontext uc;
218
+ */
219
+ tcg_gen_ext8s_i32(lsh, shift);
220
+ tcg_gen_neg_i32(rsh, lsh);
221
+ tcg_gen_shl_i32(lval, src, lsh);
222
+ tcg_gen_shr_i32(rval, src, rsh);
223
+ tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
224
+ tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
225
+
226
+ tcg_temp_free_i32(lval);
227
+ tcg_temp_free_i32(rval);
228
+ tcg_temp_free_i32(lsh);
229
+ tcg_temp_free_i32(rsh);
230
+ tcg_temp_free_i32(zero);
231
+ tcg_temp_free_i32(max);
232
+}
233
+
234
+void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
235
+{
236
+ TCGv_i64 lval = tcg_temp_new_i64();
237
+ TCGv_i64 rval = tcg_temp_new_i64();
238
+ TCGv_i64 lsh = tcg_temp_new_i64();
239
+ TCGv_i64 rsh = tcg_temp_new_i64();
240
+ TCGv_i64 zero = tcg_const_i64(0);
241
+ TCGv_i64 max = tcg_const_i64(64);
242
+
243
+ /*
244
+ * Rely on the TCG guarantee that out of range shifts produce
245
+ * unspecified results, not undefined behaviour (i.e. no trap).
246
+ * Discard out-of-range results after the fact.
247
+ */
248
+ tcg_gen_ext8s_i64(lsh, shift);
249
+ tcg_gen_neg_i64(rsh, lsh);
250
+ tcg_gen_shl_i64(lval, src, lsh);
251
+ tcg_gen_shr_i64(rval, src, rsh);
252
+ tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
253
+ tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
254
+
255
+ tcg_temp_free_i64(lval);
256
+ tcg_temp_free_i64(rval);
257
+ tcg_temp_free_i64(lsh);
258
+ tcg_temp_free_i64(rsh);
259
+ tcg_temp_free_i64(zero);
260
+ tcg_temp_free_i64(max);
261
+}
262
+
263
+static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
264
+ TCGv_vec src, TCGv_vec shift)
265
+{
266
+ TCGv_vec lval = tcg_temp_new_vec_matching(dst);
267
+ TCGv_vec rval = tcg_temp_new_vec_matching(dst);
268
+ TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
269
+ TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
270
+ TCGv_vec msk, max;
271
+
272
+ tcg_gen_neg_vec(vece, rsh, shift);
273
+ if (vece == MO_8) {
274
+ tcg_gen_mov_vec(lsh, shift);
275
+ } else {
276
+ msk = tcg_temp_new_vec_matching(dst);
277
+ tcg_gen_dupi_vec(vece, msk, 0xff);
278
+ tcg_gen_and_vec(vece, lsh, shift, msk);
279
+ tcg_gen_and_vec(vece, rsh, rsh, msk);
280
+ tcg_temp_free_vec(msk);
281
+ }
282
+
283
+ /*
284
+ * Rely on the TCG guarantee that out of range shifts produce
285
+ * unspecified results, not undefined behaviour (i.e. no trap).
286
+ * Discard out-of-range results after the fact.
287
+ */
288
+ tcg_gen_shlv_vec(vece, lval, src, lsh);
289
+ tcg_gen_shrv_vec(vece, rval, src, rsh);
290
+
291
+ max = tcg_temp_new_vec_matching(dst);
292
+ tcg_gen_dupi_vec(vece, max, 8 << vece);
293
+
294
+ /*
295
+ * The choice of LT (signed) and GEU (unsigned) are biased toward
296
+ * the instructions of the x86_64 host. For MO_8, the whole byte
297
+ * is significant so we must use an unsigned compare; otherwise we
298
+ * have already masked to a byte and so a signed compare works.
299
+ * Other tcg hosts have a full set of comparisons and do not care.
300
+ */
301
+ if (vece == MO_8) {
302
+ tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
303
+ tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
304
+ tcg_gen_andc_vec(vece, lval, lval, lsh);
305
+ tcg_gen_andc_vec(vece, rval, rval, rsh);
306
+ } else {
307
+ tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
308
+ tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
309
+ tcg_gen_and_vec(vece, lval, lval, lsh);
310
+ tcg_gen_and_vec(vece, rval, rval, rsh);
311
+ }
312
+ tcg_gen_or_vec(vece, dst, lval, rval);
313
+
314
+ tcg_temp_free_vec(max);
315
+ tcg_temp_free_vec(lval);
316
+ tcg_temp_free_vec(rval);
317
+ tcg_temp_free_vec(lsh);
318
+ tcg_temp_free_vec(rsh);
319
+}
320
+
321
+static const TCGOpcode ushl_list[] = {
322
+ INDEX_op_neg_vec, INDEX_op_shlv_vec,
323
+ INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
41
+};
324
+};
42
+
325
+
43
+struct target_rt_frame_record {
326
+const GVecGen3 ushl_op[4] = {
44
uint64_t fp;
327
+ { .fniv = gen_ushl_vec,
45
uint64_t lr;
328
+ .fno = gen_helper_gvec_ushl_b,
46
uint32_t tramp[2];
329
+ .opt_opc = ushl_list,
47
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
330
+ .vece = MO_8 },
48
static int target_restore_sigframe(CPUARMState *env,
331
+ { .fniv = gen_ushl_vec,
49
struct target_rt_sigframe *sf)
332
+ .fno = gen_helper_gvec_ushl_h,
333
+ .opt_opc = ushl_list,
334
+ .vece = MO_16 },
335
+ { .fni4 = gen_ushl_i32,
336
+ .fniv = gen_ushl_vec,
337
+ .opt_opc = ushl_list,
338
+ .vece = MO_32 },
339
+ { .fni8 = gen_ushl_i64,
340
+ .fniv = gen_ushl_vec,
341
+ .opt_opc = ushl_list,
342
+ .vece = MO_64 },
343
+};
344
+
345
+void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
346
+{
347
+ TCGv_i32 lval = tcg_temp_new_i32();
348
+ TCGv_i32 rval = tcg_temp_new_i32();
349
+ TCGv_i32 lsh = tcg_temp_new_i32();
350
+ TCGv_i32 rsh = tcg_temp_new_i32();
351
+ TCGv_i32 zero = tcg_const_i32(0);
352
+ TCGv_i32 max = tcg_const_i32(31);
353
+
354
+ /*
355
+ * Rely on the TCG guarantee that out of range shifts produce
356
+ * unspecified results, not undefined behaviour (i.e. no trap).
357
+ * Discard out-of-range results after the fact.
358
+ */
359
+ tcg_gen_ext8s_i32(lsh, shift);
360
+ tcg_gen_neg_i32(rsh, lsh);
361
+ tcg_gen_shl_i32(lval, src, lsh);
362
+ tcg_gen_umin_i32(rsh, rsh, max);
363
+ tcg_gen_sar_i32(rval, src, rsh);
364
+ tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
365
+ tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
366
+
367
+ tcg_temp_free_i32(lval);
368
+ tcg_temp_free_i32(rval);
369
+ tcg_temp_free_i32(lsh);
370
+ tcg_temp_free_i32(rsh);
371
+ tcg_temp_free_i32(zero);
372
+ tcg_temp_free_i32(max);
373
+}
374
+
375
+void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
376
+{
377
+ TCGv_i64 lval = tcg_temp_new_i64();
378
+ TCGv_i64 rval = tcg_temp_new_i64();
379
+ TCGv_i64 lsh = tcg_temp_new_i64();
380
+ TCGv_i64 rsh = tcg_temp_new_i64();
381
+ TCGv_i64 zero = tcg_const_i64(0);
382
+ TCGv_i64 max = tcg_const_i64(63);
383
+
384
+ /*
385
+ * Rely on the TCG guarantee that out of range shifts produce
386
+ * unspecified results, not undefined behaviour (i.e. no trap).
387
+ * Discard out-of-range results after the fact.
388
+ */
389
+ tcg_gen_ext8s_i64(lsh, shift);
390
+ tcg_gen_neg_i64(rsh, lsh);
391
+ tcg_gen_shl_i64(lval, src, lsh);
392
+ tcg_gen_umin_i64(rsh, rsh, max);
393
+ tcg_gen_sar_i64(rval, src, rsh);
394
+ tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
395
+ tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
396
+
397
+ tcg_temp_free_i64(lval);
398
+ tcg_temp_free_i64(rval);
399
+ tcg_temp_free_i64(lsh);
400
+ tcg_temp_free_i64(rsh);
401
+ tcg_temp_free_i64(zero);
402
+ tcg_temp_free_i64(max);
403
+}
404
+
405
+static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
406
+ TCGv_vec src, TCGv_vec shift)
407
+{
408
+ TCGv_vec lval = tcg_temp_new_vec_matching(dst);
409
+ TCGv_vec rval = tcg_temp_new_vec_matching(dst);
410
+ TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
411
+ TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
412
+ TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
413
+
414
+ /*
415
+ * Rely on the TCG guarantee that out of range shifts produce
416
+ * unspecified results, not undefined behaviour (i.e. no trap).
417
+ * Discard out-of-range results after the fact.
418
+ */
419
+ tcg_gen_neg_vec(vece, rsh, shift);
420
+ if (vece == MO_8) {
421
+ tcg_gen_mov_vec(lsh, shift);
422
+ } else {
423
+ tcg_gen_dupi_vec(vece, tmp, 0xff);
424
+ tcg_gen_and_vec(vece, lsh, shift, tmp);
425
+ tcg_gen_and_vec(vece, rsh, rsh, tmp);
426
+ }
427
+
428
+ /* Bound rsh so out of bound right shift gets -1. */
429
+ tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
430
+ tcg_gen_umin_vec(vece, rsh, rsh, tmp);
431
+ tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
432
+
433
+ tcg_gen_shlv_vec(vece, lval, src, lsh);
434
+ tcg_gen_sarv_vec(vece, rval, src, rsh);
435
+
436
+ /* Select in-bound left shift. */
437
+ tcg_gen_andc_vec(vece, lval, lval, tmp);
438
+
439
+ /* Select between left and right shift. */
440
+ if (vece == MO_8) {
441
+ tcg_gen_dupi_vec(vece, tmp, 0);
442
+ tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
443
+ } else {
444
+ tcg_gen_dupi_vec(vece, tmp, 0x80);
445
+ tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
446
+ }
447
+
448
+ tcg_temp_free_vec(lval);
449
+ tcg_temp_free_vec(rval);
450
+ tcg_temp_free_vec(lsh);
451
+ tcg_temp_free_vec(rsh);
452
+ tcg_temp_free_vec(tmp);
453
+}
454
+
455
+static const TCGOpcode sshl_list[] = {
456
+ INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
457
+ INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
458
+};
459
+
460
+const GVecGen3 sshl_op[4] = {
461
+ { .fniv = gen_sshl_vec,
462
+ .fno = gen_helper_gvec_sshl_b,
463
+ .opt_opc = sshl_list,
464
+ .vece = MO_8 },
465
+ { .fniv = gen_sshl_vec,
466
+ .fno = gen_helper_gvec_sshl_h,
467
+ .opt_opc = sshl_list,
468
+ .vece = MO_16 },
469
+ { .fni4 = gen_sshl_i32,
470
+ .fniv = gen_sshl_vec,
471
+ .opt_opc = sshl_list,
472
+ .vece = MO_32 },
473
+ { .fni8 = gen_sshl_i64,
474
+ .fniv = gen_sshl_vec,
475
+ .opt_opc = sshl_list,
476
+ .vece = MO_64 },
477
+};
478
+
479
static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
480
TCGv_vec a, TCGv_vec b)
50
{
481
{
51
- struct target_aux_context *aux
482
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
52
- = (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
483
vec_size, vec_size);
53
- uint32_t magic, size;
484
}
54
+ struct target_aarch64_ctx *ctx;
485
return 0;
55
+ struct target_fpsimd_context *fpsimd = NULL;
486
+
56
487
+ case NEON_3R_VSHL:
57
target_restore_general_frame(env, sf);
488
+ /* Note the operation is vshl vd,vm,vn */
58
489
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
59
- __get_user(magic, &aux->fpsimd.head.magic);
490
+ u ? &ushl_op[size] : &sshl_op[size]);
60
- __get_user(size, &aux->fpsimd.head.size);
491
+ return 0;
61
- if (magic == TARGET_FPSIMD_MAGIC
492
}
62
- && size == sizeof(struct target_fpsimd_context)) {
493
63
- target_restore_fpsimd_record(env, &aux->fpsimd);
494
if (size == 3) {
64
- } else {
495
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
+ ctx = (struct target_aarch64_ctx *)sf->uc.tuc_mcontext.__reserved;
496
neon_load_reg64(cpu_V0, rn + pass);
66
+ while (ctx) {
497
neon_load_reg64(cpu_V1, rm + pass);
67
+ uint32_t magic, size;
498
switch (op) {
68
+
499
- case NEON_3R_VSHL:
69
+ __get_user(magic, &ctx->magic);
500
- if (u) {
70
+ __get_user(size, &ctx->size);
501
- gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
71
+ switch (magic) {
502
- } else {
72
+ case 0:
503
- gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
73
+ if (size != 0) {
504
- }
74
+ return 1;
505
- break;
506
case NEON_3R_VQSHL:
507
if (u) {
508
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
509
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
510
}
511
pairwise = 0;
512
switch (op) {
513
- case NEON_3R_VSHL:
514
case NEON_3R_VQSHL:
515
case NEON_3R_VRSHL:
516
case NEON_3R_VQRSHL:
517
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
518
case NEON_3R_VHSUB:
519
GEN_NEON_INTEGER_OP(hsub);
520
break;
521
- case NEON_3R_VSHL:
522
- GEN_NEON_INTEGER_OP(shl);
523
- break;
524
case NEON_3R_VQSHL:
525
GEN_NEON_INTEGER_OP_ENV(qshl);
526
break;
527
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
528
}
529
} else {
530
if (input_unsigned) {
531
- gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
532
+ gen_ushl_i64(cpu_V0, in, tmp64);
533
} else {
534
- gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
535
+ gen_sshl_i64(cpu_V0, in, tmp64);
536
}
537
}
538
tmp = tcg_temp_new_i32();
539
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
540
index XXXXXXX..XXXXXXX 100644
541
--- a/target/arm/vec_helper.c
542
+++ b/target/arm/vec_helper.c
543
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm,
544
do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status, desc,
545
get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
546
}
547
+
548
+void HELPER(gvec_sshl_b)(void *vd, void *vn, void *vm, uint32_t desc)
549
+{
550
+ intptr_t i, opr_sz = simd_oprsz(desc);
551
+ int8_t *d = vd, *n = vn, *m = vm;
552
+
553
+ for (i = 0; i < opr_sz; ++i) {
554
+ int8_t mm = m[i];
555
+ int8_t nn = n[i];
556
+ int8_t res = 0;
557
+ if (mm >= 0) {
558
+ if (mm < 8) {
559
+ res = nn << mm;
75
+ }
560
+ }
76
+ ctx = NULL;
561
+ } else {
77
+ continue;
562
+ res = nn >> (mm > -8 ? -mm : 7);
78
+
563
+ }
79
+ case TARGET_FPSIMD_MAGIC:
564
+ d[i] = res;
80
+ if (fpsimd || size != sizeof(struct target_fpsimd_context)) {
565
+ }
81
+ return 1;
566
+ clear_tail(d, opr_sz, simd_maxsz(desc));
567
+}
568
+
569
+void HELPER(gvec_sshl_h)(void *vd, void *vn, void *vm, uint32_t desc)
570
+{
571
+ intptr_t i, opr_sz = simd_oprsz(desc);
572
+ int16_t *d = vd, *n = vn, *m = vm;
573
+
574
+ for (i = 0; i < opr_sz / 2; ++i) {
575
+ int8_t mm = m[i]; /* only 8 bits of shift are significant */
576
+ int16_t nn = n[i];
577
+ int16_t res = 0;
578
+ if (mm >= 0) {
579
+ if (mm < 16) {
580
+ res = nn << mm;
82
+ }
581
+ }
83
+ fpsimd = (struct target_fpsimd_context *)ctx;
582
+ } else {
84
+ break;
583
+ res = nn >> (mm > -16 ? -mm : 15);
85
+
86
+ default:
87
+ /* Unknown record -- we certainly didn't generate it.
88
+ * Did we in fact get out of sync?
89
+ */
90
+ return 1;
91
+ }
584
+ }
92
+ ctx = (void *)ctx + size;
585
+ d[i] = res;
93
+ }
586
+ }
94
+
587
+ clear_tail(d, opr_sz, simd_maxsz(desc));
95
+ /* Require FPSIMD always. */
588
+}
96
+ if (!fpsimd) {
589
+
97
return 1;
590
+void HELPER(gvec_ushl_b)(void *vd, void *vn, void *vm, uint32_t desc)
98
}
591
+{
99
+ target_restore_fpsimd_record(env, fpsimd);
592
+ intptr_t i, opr_sz = simd_oprsz(desc);
100
+
593
+ uint8_t *d = vd, *n = vn, *m = vm;
101
return 0;
594
+
102
}
595
+ for (i = 0; i < opr_sz; ++i) {
103
596
+ int8_t mm = m[i];
104
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
597
+ uint8_t nn = n[i];
105
target_siginfo_t *info, target_sigset_t *set,
598
+ uint8_t res = 0;
106
CPUARMState *env)
599
+ if (mm >= 0) {
107
{
600
+ if (mm < 8) {
108
+ int size = offsetof(struct target_rt_sigframe, uc.tuc_mcontext.__reserved);
601
+ res = nn << mm;
109
+ int fpsimd_ofs, end1_ofs, fr_ofs;
602
+ }
110
struct target_rt_sigframe *frame;
603
+ } else {
111
- struct target_aux_context *aux;
604
+ if (mm > -8) {
112
+ struct target_rt_frame_record *fr;
605
+ res = nn >> -mm;
113
abi_ulong frame_addr, return_addr;
606
+ }
114
607
+ }
115
+ fpsimd_ofs = size;
608
+ d[i] = res;
116
+ size += sizeof(struct target_fpsimd_context);
609
+ }
117
+ end1_ofs = size;
610
+ clear_tail(d, opr_sz, simd_maxsz(desc));
118
+ size += sizeof(struct target_aarch64_ctx);
611
+}
119
+ fr_ofs = size;
612
+
120
+ size += sizeof(struct target_rt_frame_record);
613
+void HELPER(gvec_ushl_h)(void *vd, void *vn, void *vm, uint32_t desc)
121
+
614
+{
122
frame_addr = get_sigframe(ka, env);
615
+ intptr_t i, opr_sz = simd_oprsz(desc);
123
trace_user_setup_frame(env, frame_addr);
616
+ uint16_t *d = vd, *n = vn, *m = vm;
124
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
617
+
125
goto give_sigsegv;
618
+ for (i = 0; i < opr_sz / 2; ++i) {
126
}
619
+ int8_t mm = m[i]; /* only 8 bits of shift are significant */
127
- aux = (struct target_aux_context *)frame->uc.tuc_mcontext.__reserved;
620
+ uint16_t nn = n[i];
128
621
+ uint16_t res = 0;
129
target_setup_general_frame(frame, env, set);
622
+ if (mm >= 0) {
130
- target_setup_fpsimd_record(&aux->fpsimd, env);
623
+ if (mm < 16) {
131
- target_setup_end_record(&aux->end);
624
+ res = nn << mm;
132
+ target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
625
+ }
133
+ target_setup_end_record((void *)frame + end1_ofs);
626
+ } else {
134
+
627
+ if (mm > -16) {
135
+ /* Set up the stack frame for unwinding. */
628
+ res = nn >> -mm;
136
+ fr = (void *)frame + fr_ofs;
629
+ }
137
+ __put_user(env->xregs[29], &fr->fp);
630
+ }
138
+ __put_user(env->xregs[30], &fr->lr);
631
+ d[i] = res;
139
632
+ }
140
if (ka->sa_flags & TARGET_SA_RESTORER) {
633
+ clear_tail(d, opr_sz, simd_maxsz(desc));
141
return_addr = ka->sa_restorer;
634
+}
142
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
143
* Since these are instructions they need to be put as little-endian
144
* regardless of target default or current CPU endianness.
145
*/
146
- __put_user_e(0xd2801168, &frame->tramp[0], le);
147
- __put_user_e(0xd4000001, &frame->tramp[1], le);
148
- return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
149
+ __put_user_e(0xd2801168, &fr->tramp[0], le);
150
+ __put_user_e(0xd4000001, &fr->tramp[1], le);
151
+ return_addr = frame_addr + fr_ofs
152
+ + offsetof(struct target_rt_frame_record, tramp);
153
}
154
env->xregs[0] = usig;
155
env->xregs[31] = frame_addr;
156
- env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
157
+ env->xregs[29] = frame_addr + fr_ofs;
158
env->pc = ka->_sa_handler;
159
env->xregs[30] = return_addr;
160
if (info) {
161
--
635
--
162
2.16.2
636
2.20.1
163
637
164
638
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The gvec form will be needed for implementing SVE2.
4
5
Extend the implementation to operate on uint64_t instead of uint32_t.
6
Use a counted inner loop instead of terminating when op1 goes to zero,
7
looking toward the required implementation for ARMv8.4-DIT.
8
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200216214232.4230-3-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/helper.h | 3 ++-
16
target/arm/neon_helper.c | 22 ----------------------
17
target/arm/translate-a64.c | 10 +++-------
18
target/arm/translate.c | 11 ++++-------
19
target/arm/vec_helper.c | 30 ++++++++++++++++++++++++++++++
20
5 files changed, 39 insertions(+), 37 deletions(-)
21
22
diff --git a/target/arm/helper.h b/target/arm/helper.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.h
25
+++ b/target/arm/helper.h
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
27
DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
28
DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
29
DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
30
-DEF_HELPER_2(neon_mul_p8, i32, i32, i32)
31
DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
32
33
DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
38
+DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
+
40
#ifdef TARGET_AARCH64
41
#include "helper-a64.h"
42
#include "helper-sve.h"
43
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/neon_helper.c
46
+++ b/target/arm/neon_helper.c
47
@@ -XXX,XX +XXX,XX @@ NEON_VOP(mul_u16, neon_u16, 2)
48
49
/* Polynomial multiplication is like integer multiplication except the
50
partial products are XORed, not added. */
51
-uint32_t HELPER(neon_mul_p8)(uint32_t op1, uint32_t op2)
52
-{
53
- uint32_t mask;
54
- uint32_t result;
55
- result = 0;
56
- while (op1) {
57
- mask = 0;
58
- if (op1 & 1)
59
- mask |= 0xff;
60
- if (op1 & (1 << 8))
61
- mask |= (0xff << 8);
62
- if (op1 & (1 << 16))
63
- mask |= (0xff << 16);
64
- if (op1 & (1 << 24))
65
- mask |= (0xff << 24);
66
- result ^= op2 & mask;
67
- op1 = (op1 >> 1) & 0x7f7f7f7f;
68
- op2 = (op2 << 1) & 0xfefefefe;
69
- }
70
- return result;
71
-}
72
-
73
uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
74
{
75
uint64_t result = 0;
76
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-a64.c
79
+++ b/target/arm/translate-a64.c
80
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
81
case 0x13: /* MUL, PMUL */
82
if (!u) { /* MUL */
83
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_mul, size);
84
- return;
85
+ } else { /* PMUL */
86
+ gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0, gen_helper_gvec_pmul_b);
87
}
88
- break;
89
+ return;
90
case 0x12: /* MLA, MLS */
91
if (u) {
92
gen_gvec_op3(s, is_q, rd, rn, rm, &mls_op[size]);
93
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
94
genfn = fns[size][u];
95
break;
96
}
97
- case 0x13: /* MUL, PMUL */
98
- assert(u); /* PMUL */
99
- assert(size == 0);
100
- genfn = gen_helper_neon_mul_p8;
101
- break;
102
case 0x16: /* SQDMULH, SQRDMULH */
103
{
104
static NeonGenTwoOpEnvFn * const fns[2][2] = {
105
diff --git a/target/arm/translate.c b/target/arm/translate.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/translate.c
108
+++ b/target/arm/translate.c
109
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
110
111
case NEON_3R_VMUL: /* VMUL */
112
if (u) {
113
- /* Polynomial case allows only P8 and is handled below. */
114
+ /* Polynomial case allows only P8. */
115
if (size != 0) {
116
return 1;
117
}
118
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
119
+ 0, gen_helper_gvec_pmul_b);
120
} else {
121
tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
122
vec_size, vec_size);
123
- return 0;
124
}
125
- break;
126
+ return 0;
127
128
case NEON_3R_VML: /* VMLA, VMLS */
129
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
130
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
131
tmp2 = neon_load_reg(rd, pass);
132
gen_neon_add(size, tmp, tmp2);
133
break;
134
- case NEON_3R_VMUL:
135
- /* VMUL.P8; other cases already eliminated. */
136
- gen_helper_neon_mul_p8(tmp, tmp, tmp2);
137
- break;
138
case NEON_3R_VPMAX:
139
GEN_NEON_INTEGER_OP(pmax);
140
break;
141
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/target/arm/vec_helper.c
144
+++ b/target/arm/vec_helper.c
145
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_ushl_h)(void *vd, void *vn, void *vm, uint32_t desc)
146
}
147
clear_tail(d, opr_sz, simd_maxsz(desc));
148
}
149
+
150
+/*
151
+ * 8x8->8 polynomial multiply.
152
+ *
153
+ * Polynomial multiplication is like integer multiplication except the
154
+ * partial products are XORed, not added.
155
+ *
156
+ * TODO: expose this as a generic vector operation, as it is a common
157
+ * crypto building block.
158
+ */
159
+void HELPER(gvec_pmul_b)(void *vd, void *vn, void *vm, uint32_t desc)
160
+{
161
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
162
+ uint64_t *d = vd, *n = vn, *m = vm;
163
+
164
+ for (i = 0; i < opr_sz / 8; ++i) {
165
+ uint64_t nn = n[i];
166
+ uint64_t mm = m[i];
167
+ uint64_t rr = 0;
168
+
169
+ for (j = 0; j < 8; ++j) {
170
+ uint64_t mask = (nn & 0x0101010101010101ull) * 0xff;
171
+ rr ^= mm & mask;
172
+ mm = (mm << 1) & 0xfefefefefefefefeull;
173
+ nn >>= 1;
174
+ }
175
+ d[i] = rr;
176
+ }
177
+ clear_tail(d, opr_sz, simd_maxsz(desc));
178
+}
179
--
180
2.20.1
181
182
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The gvec form will be needed for implementing SVE2.
4
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200216214232.4230-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.h | 4 +---
12
target/arm/neon_helper.c | 30 ------------------------------
13
target/arm/translate-a64.c | 28 +++-------------------------
14
target/arm/translate.c | 16 ++--------------
15
target/arm/vec_helper.c | 33 +++++++++++++++++++++++++++++++++
16
5 files changed, 39 insertions(+), 72 deletions(-)
17
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
21
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
23
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
24
DEF_HELPER_2(dc_zva, void, env, i64)
25
26
-DEF_HELPER_FLAGS_2(neon_pmull_64_lo, TCG_CALL_NO_RWG_SE, i64, i64, i64)
27
-DEF_HELPER_FLAGS_2(neon_pmull_64_hi, TCG_CALL_NO_RWG_SE, i64, i64, i64)
28
-
29
DEF_HELPER_FLAGS_5(gvec_qrdmlah_s16, TCG_CALL_NO_RWG,
30
void, ptr, ptr, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s16, TCG_CALL_NO_RWG,
32
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
35
DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
38
#ifdef TARGET_AARCH64
39
#include "helper-a64.h"
40
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/neon_helper.c
43
+++ b/target/arm/neon_helper.c
44
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_zip16)(void *vd, void *vm)
45
rm[0] = m0;
46
rd[0] = d0;
47
}
48
-
49
-/* Helper function for 64 bit polynomial multiply case:
50
- * perform PolynomialMult(op1, op2) and return either the top or
51
- * bottom half of the 128 bit result.
52
- */
53
-uint64_t HELPER(neon_pmull_64_lo)(uint64_t op1, uint64_t op2)
54
-{
55
- int bitnum;
56
- uint64_t res = 0;
57
-
58
- for (bitnum = 0; bitnum < 64; bitnum++) {
59
- if (op1 & (1ULL << bitnum)) {
60
- res ^= op2 << bitnum;
61
- }
62
- }
63
- return res;
64
-}
65
-uint64_t HELPER(neon_pmull_64_hi)(uint64_t op1, uint64_t op2)
66
-{
67
- int bitnum;
68
- uint64_t res = 0;
69
-
70
- /* bit 0 of op1 can't influence the high 64 bits at all */
71
- for (bitnum = 1; bitnum < 64; bitnum++) {
72
- if (op1 & (1ULL << bitnum)) {
73
- res ^= op2 >> (64 - bitnum);
74
- }
75
- }
76
- return res;
77
-}
78
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/translate-a64.c
81
+++ b/target/arm/translate-a64.c
82
@@ -XXX,XX +XXX,XX @@ static void handle_3rd_narrowing(DisasContext *s, int is_q, int is_u, int size,
83
clear_vec_high(s, is_q, rd);
84
}
85
86
-static void handle_pmull_64(DisasContext *s, int is_q, int rd, int rn, int rm)
87
-{
88
- /* PMULL of 64 x 64 -> 128 is an odd special case because it
89
- * is the only three-reg-diff instruction which produces a
90
- * 128-bit wide result from a single operation. However since
91
- * it's possible to calculate the two halves more or less
92
- * separately we just use two helper calls.
93
- */
94
- TCGv_i64 tcg_op1 = tcg_temp_new_i64();
95
- TCGv_i64 tcg_op2 = tcg_temp_new_i64();
96
- TCGv_i64 tcg_res = tcg_temp_new_i64();
97
-
98
- read_vec_element(s, tcg_op1, rn, is_q, MO_64);
99
- read_vec_element(s, tcg_op2, rm, is_q, MO_64);
100
- gen_helper_neon_pmull_64_lo(tcg_res, tcg_op1, tcg_op2);
101
- write_vec_element(s, tcg_res, rd, 0, MO_64);
102
- gen_helper_neon_pmull_64_hi(tcg_res, tcg_op1, tcg_op2);
103
- write_vec_element(s, tcg_res, rd, 1, MO_64);
104
-
105
- tcg_temp_free_i64(tcg_op1);
106
- tcg_temp_free_i64(tcg_op2);
107
- tcg_temp_free_i64(tcg_res);
108
-}
109
-
110
/* AdvSIMD three different
111
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
112
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
113
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
114
if (!fp_access_check(s)) {
115
return;
116
}
117
- handle_pmull_64(s, is_q, rd, rn, rm);
118
+ /* The Q field specifies lo/hi half input for this insn. */
119
+ gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
120
+ gen_helper_gvec_pmull_q);
121
return;
122
}
123
goto is_widening;
124
diff --git a/target/arm/translate.c b/target/arm/translate.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/target/arm/translate.c
127
+++ b/target/arm/translate.c
128
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
129
* outside the loop below as it only performs a single pass.
130
*/
131
if (op == 14 && size == 2) {
132
- TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
133
-
134
if (!dc_isar_feature(aa32_pmull, s)) {
135
return 1;
136
}
137
- tcg_rn = tcg_temp_new_i64();
138
- tcg_rm = tcg_temp_new_i64();
139
- tcg_rd = tcg_temp_new_i64();
140
- neon_load_reg64(tcg_rn, rn);
141
- neon_load_reg64(tcg_rm, rm);
142
- gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
143
- neon_store_reg64(tcg_rd, rd);
144
- gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
145
- neon_store_reg64(tcg_rd, rd + 1);
146
- tcg_temp_free_i64(tcg_rn);
147
- tcg_temp_free_i64(tcg_rm);
148
- tcg_temp_free_i64(tcg_rd);
149
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
150
+ 0, gen_helper_gvec_pmull_q);
151
return 0;
152
}
153
154
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/target/arm/vec_helper.c
157
+++ b/target/arm/vec_helper.c
158
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_pmul_b)(void *vd, void *vn, void *vm, uint32_t desc)
159
}
160
clear_tail(d, opr_sz, simd_maxsz(desc));
161
}
162
+
163
+/*
164
+ * 64x64->128 polynomial multiply.
165
+ * Because of the lanes are not accessed in strict columns,
166
+ * this probably cannot be turned into a generic helper.
167
+ */
168
+void HELPER(gvec_pmull_q)(void *vd, void *vn, void *vm, uint32_t desc)
169
+{
170
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
171
+ intptr_t hi = simd_data(desc);
172
+ uint64_t *d = vd, *n = vn, *m = vm;
173
+
174
+ for (i = 0; i < opr_sz / 8; i += 2) {
175
+ uint64_t nn = n[i + hi];
176
+ uint64_t mm = m[i + hi];
177
+ uint64_t rhi = 0;
178
+ uint64_t rlo = 0;
179
+
180
+ /* Bit 0 can only influence the low 64-bit result. */
181
+ if (nn & 1) {
182
+ rlo = mm;
183
+ }
184
+
185
+ for (j = 1; j < 64; ++j) {
186
+ uint64_t mask = -((nn >> j) & 1);
187
+ rlo ^= (mm << j) & mask;
188
+ rhi ^= (mm >> (64 - j)) & mask;
189
+ }
190
+ d[i] = rlo;
191
+ d[i + 1] = rhi;
192
+ }
193
+ clear_tail(d, opr_sz, simd_maxsz(desc));
194
+}
195
--
196
2.20.1
197
198
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
We still need two different helpers, since NEON and SVE2 get the
4
inputs from different locations within the source vector. However,
5
we can convert both to the same internal form for computation.
6
7
The sve2 helper is not used yet, but adding it with this patch
8
helps illustrate why the neon changes are helpful.
9
10
Tested-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200216214232.4230-5-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/helper-sve.h | 2 ++
17
target/arm/helper.h | 3 +-
18
target/arm/neon_helper.c | 32 --------------------
19
target/arm/translate-a64.c | 27 +++++++++++------
20
target/arm/translate.c | 26 ++++++++---------
21
target/arm/vec_helper.c | 60 ++++++++++++++++++++++++++++++++++++++
22
6 files changed, 95 insertions(+), 55 deletions(-)
23
24
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper-sve.h
27
+++ b/target/arm/helper-sve.h
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_stdd_le_zd, TCG_CALL_NO_WG,
29
void, env, ptr, ptr, ptr, tl, i32)
30
DEF_HELPER_FLAGS_6(sve_stdd_be_zd, TCG_CALL_NO_WG,
31
void, env, ptr, ptr, ptr, tl, i32)
32
+
33
+DEF_HELPER_FLAGS_4(sve2_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
diff --git a/target/arm/helper.h b/target/arm/helper.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/helper.h
37
+++ b/target/arm/helper.h
38
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
39
DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
40
DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
41
DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
42
-DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
43
44
DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
45
DEF_HELPER_2(neon_tst_u16, i32, i32, i32)
46
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
47
DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
48
DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
50
+DEF_HELPER_FLAGS_4(neon_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
51
+
52
#ifdef TARGET_AARCH64
53
#include "helper-a64.h"
54
#include "helper-sve.h"
55
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/neon_helper.c
58
+++ b/target/arm/neon_helper.c
59
@@ -XXX,XX +XXX,XX @@ NEON_VOP(mul_u8, neon_u8, 4)
60
NEON_VOP(mul_u16, neon_u16, 2)
61
#undef NEON_FN
62
63
-/* Polynomial multiplication is like integer multiplication except the
64
- partial products are XORed, not added. */
65
-uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
66
-{
67
- uint64_t result = 0;
68
- uint64_t mask;
69
- uint64_t op2ex = op2;
70
- op2ex = (op2ex & 0xff) |
71
- ((op2ex & 0xff00) << 8) |
72
- ((op2ex & 0xff0000) << 16) |
73
- ((op2ex & 0xff000000) << 24);
74
- while (op1) {
75
- mask = 0;
76
- if (op1 & 1) {
77
- mask |= 0xffff;
78
- }
79
- if (op1 & (1 << 8)) {
80
- mask |= (0xffffU << 16);
81
- }
82
- if (op1 & (1 << 16)) {
83
- mask |= (0xffffULL << 32);
84
- }
85
- if (op1 & (1 << 24)) {
86
- mask |= (0xffffULL << 48);
87
- }
88
- result ^= op2ex & mask;
89
- op1 = (op1 >> 1) & 0x7f7f7f7f;
90
- op2ex <<= 1;
91
- }
92
- return result;
93
-}
94
-
95
#define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
96
NEON_VOP(tst_u8, neon_u8, 4)
97
NEON_VOP(tst_u16, neon_u16, 2)
98
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate-a64.c
101
+++ b/target/arm/translate-a64.c
102
@@ -XXX,XX +XXX,XX @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
103
gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
104
tcg_passres, tcg_passres);
105
break;
106
- case 14: /* PMULL */
107
- assert(size == 0);
108
- gen_helper_neon_mull_p8(tcg_passres, tcg_op1, tcg_op2);
109
- break;
110
default:
111
g_assert_not_reached();
112
}
113
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
114
handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm);
115
break;
116
case 14: /* PMULL, PMULL2 */
117
- if (is_u || size == 1 || size == 2) {
118
+ if (is_u) {
119
unallocated_encoding(s);
120
return;
121
}
122
- if (size == 3) {
123
+ switch (size) {
124
+ case 0: /* PMULL.P8 */
125
+ if (!fp_access_check(s)) {
126
+ return;
127
+ }
128
+ /* The Q field specifies lo/hi half input for this insn. */
129
+ gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
130
+ gen_helper_neon_pmull_h);
131
+ break;
132
+
133
+ case 3: /* PMULL.P64 */
134
if (!dc_isar_feature(aa64_pmull, s)) {
135
unallocated_encoding(s);
136
return;
137
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
138
/* The Q field specifies lo/hi half input for this insn. */
139
gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
140
gen_helper_gvec_pmull_q);
141
- return;
142
+ break;
143
+
144
+ default:
145
+ unallocated_encoding(s);
146
+ break;
147
}
148
- goto is_widening;
149
+ return;
150
case 9: /* SQDMLAL, SQDMLAL2 */
151
case 11: /* SQDMLSL, SQDMLSL2 */
152
case 13: /* SQDMULL, SQDMULL2 */
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
154
unallocated_encoding(s);
155
return;
156
}
157
- is_widening:
158
if (!fp_access_check(s)) {
159
return;
160
}
161
diff --git a/target/arm/translate.c b/target/arm/translate.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/translate.c
164
+++ b/target/arm/translate.c
165
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
166
return 1;
167
}
168
169
- /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
170
- * outside the loop below as it only performs a single pass.
171
- */
172
- if (op == 14 && size == 2) {
173
- if (!dc_isar_feature(aa32_pmull, s)) {
174
- return 1;
175
+ /* Handle polynomial VMULL in a single pass. */
176
+ if (op == 14) {
177
+ if (size == 0) {
178
+ /* VMULL.P8 */
179
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
180
+ 0, gen_helper_neon_pmull_h);
181
+ } else {
182
+ /* VMULL.P64 */
183
+ if (!dc_isar_feature(aa32_pmull, s)) {
184
+ return 1;
185
+ }
186
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
187
+ 0, gen_helper_gvec_pmull_q);
188
}
189
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
190
- 0, gen_helper_gvec_pmull_q);
191
return 0;
192
}
193
194
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
195
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
196
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
197
break;
198
- case 14: /* Polynomial VMULL */
199
- gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
200
- tcg_temp_free_i32(tmp2);
201
- tcg_temp_free_i32(tmp);
202
- break;
203
default: /* 15 is RESERVED: caught earlier */
204
abort();
205
}
206
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/arm/vec_helper.c
209
+++ b/target/arm/vec_helper.c
210
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_pmull_q)(void *vd, void *vn, void *vm, uint32_t desc)
211
}
212
clear_tail(d, opr_sz, simd_maxsz(desc));
213
}
214
+
215
+/*
216
+ * 8x8->16 polynomial multiply.
217
+ *
218
+ * The byte inputs are expanded to (or extracted from) half-words.
219
+ * Note that neon and sve2 get the inputs from different positions.
220
+ * This allows 4 bytes to be processed in parallel with uint64_t.
221
+ */
222
+
223
+static uint64_t expand_byte_to_half(uint64_t x)
224
+{
225
+ return (x & 0x000000ff)
226
+ | ((x & 0x0000ff00) << 8)
227
+ | ((x & 0x00ff0000) << 16)
228
+ | ((x & 0xff000000) << 24);
229
+}
230
+
231
+static uint64_t pmull_h(uint64_t op1, uint64_t op2)
232
+{
233
+ uint64_t result = 0;
234
+ int i;
235
+
236
+ for (i = 0; i < 8; ++i) {
237
+ uint64_t mask = (op1 & 0x0001000100010001ull) * 0xffff;
238
+ result ^= op2 & mask;
239
+ op1 >>= 1;
240
+ op2 <<= 1;
241
+ }
242
+ return result;
243
+}
244
+
245
+void HELPER(neon_pmull_h)(void *vd, void *vn, void *vm, uint32_t desc)
246
+{
247
+ int hi = simd_data(desc);
248
+ uint64_t *d = vd, *n = vn, *m = vm;
249
+ uint64_t nn = n[hi], mm = m[hi];
250
+
251
+ d[0] = pmull_h(expand_byte_to_half(nn), expand_byte_to_half(mm));
252
+ nn >>= 32;
253
+ mm >>= 32;
254
+ d[1] = pmull_h(expand_byte_to_half(nn), expand_byte_to_half(mm));
255
+
256
+ clear_tail(d, 16, simd_maxsz(desc));
257
+}
258
+
259
+#ifdef TARGET_AARCH64
260
+void HELPER(sve2_pmull_h)(void *vd, void *vn, void *vm, uint32_t desc)
261
+{
262
+ int shift = simd_data(desc) * 8;
263
+ intptr_t i, opr_sz = simd_oprsz(desc);
264
+ uint64_t *d = vd, *n = vn, *m = vm;
265
+
266
+ for (i = 0; i < opr_sz / 8; ++i) {
267
+ uint64_t nn = (n[i] >> shift) & 0x00ff00ff00ff00ffull;
268
+ uint64_t mm = (m[i] >> shift) & 0x00ff00ff00ff00ffull;
269
+
270
+ d[i] = pmull_h(nn, mm);
271
+ }
272
+}
273
+#endif
274
--
275
2.20.1
276
277
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Correct the number of dummy cycles required by the FAST_READ_4 command (to
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
be eight, one dummy byte).
5
Message-id: 20180309153654.13518-4-f4bug@amsat.org
5
6
Fixes: ef06ca3946 ("xilinx_spips: Add support for RX discard and RX drain")
7
Suggested-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20200218113350.6090-1-frasse.iglesias@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
hw/sd/sd.c | 14 ++++++++++----
13
hw/ssi/xilinx_spips.c | 2 +-
9
hw/sd/trace-events | 8 ++++----
14
1 file changed, 1 insertion(+), 1 deletion(-)
10
2 files changed, 14 insertions(+), 8 deletions(-)
11
15
12
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
16
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sd.c
18
--- a/hw/ssi/xilinx_spips.c
15
+++ b/hw/sd/sd.c
19
+++ b/hw/ssi/xilinx_spips.c
16
@@ -XXX,XX +XXX,XX @@ struct SDState {
20
@@ -XXX,XX +XXX,XX @@ static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
17
qemu_irq readonly_cb;
21
case FAST_READ:
18
qemu_irq inserted_cb;
22
case DOR:
19
QEMUTimer *ocr_power_timer;
23
case QOR:
20
+ const char *proto_name;
24
+ case FAST_READ_4:
21
bool enable;
25
case DOR_4:
22
uint8_t dat_lines;
26
case QOR_4:
23
bool cmd_line;
27
return 1;
24
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
28
case DIOR:
25
* However there is no ACMD55, so we want to trace this particular case.
29
- case FAST_READ_4:
26
*/
30
case DIOR_4:
27
if (req.cmd != 55 || sd->expecting_acmd) {
31
return 2;
28
- trace_sdcard_normal_command(sd_cmd_name(req.cmd), req.cmd,
32
case QIOR:
29
+ trace_sdcard_normal_command(sd->proto_name,
30
+ sd_cmd_name(req.cmd), req.cmd,
31
req.arg, sd_state_name(sd->state));
32
}
33
34
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
35
static sd_rsp_type_t sd_app_command(SDState *sd,
36
SDRequest req)
37
{
38
- trace_sdcard_app_command(sd_acmd_name(req.cmd),
39
+ trace_sdcard_app_command(sd->proto_name, sd_acmd_name(req.cmd),
40
req.cmd, req.arg, sd_state_name(sd->state));
41
sd->card_status |= APP_CMD;
42
switch (req.cmd) {
43
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
44
if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
45
return;
46
47
- trace_sdcard_write_data(sd_acmd_name(sd->current_cmd),
48
+ trace_sdcard_write_data(sd->proto_name,
49
+ sd_acmd_name(sd->current_cmd),
50
sd->current_cmd, value);
51
switch (sd->current_cmd) {
52
case 24:    /* CMD24: WRITE_SINGLE_BLOCK */
53
@@ -XXX,XX +XXX,XX @@ uint8_t sd_read_data(SDState *sd)
54
55
io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len;
56
57
- trace_sdcard_read_data(sd_acmd_name(sd->current_cmd),
58
+ trace_sdcard_read_data(sd->proto_name,
59
+ sd_acmd_name(sd->current_cmd),
60
sd->current_cmd, io_len);
61
switch (sd->current_cmd) {
62
case 6:    /* CMD6: SWITCH_FUNCTION */
63
@@ -XXX,XX +XXX,XX @@ static void sd_realize(DeviceState *dev, Error **errp)
64
SDState *sd = SD_CARD(dev);
65
int ret;
66
67
+ sd->proto_name = sd->spi ? "SPI" : "SD";
68
+
69
if (sd->blk && blk_is_read_only(sd->blk)) {
70
error_setg(errp, "Cannot use read-only drive as SD card");
71
return;
72
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/sd/trace-events
75
+++ b/hw/sd/trace-events
76
@@ -XXX,XX +XXX,XX @@ sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of
77
sdhci_capareg(const char *desc, uint16_t val) "%s: %u"
78
79
# hw/sd/sd.c
80
-sdcard_normal_command(const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%20s/ CMD%02d arg 0x%08x (state %s)"
81
-sdcard_app_command(const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%23s/ACMD%02d arg 0x%08x (state %s)"
82
+sdcard_normal_command(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%s %20s/ CMD%02d arg 0x%08x (state %s)"
83
+sdcard_app_command(const char *proto, const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%s %23s/ACMD%02d arg 0x%08x (state %s)"
84
sdcard_response(const char *rspdesc, int rsplen) "%s (sz:%d)"
85
sdcard_powerup(void) ""
86
sdcard_inquiry_cmd41(void) ""
87
@@ -XXX,XX +XXX,XX @@ sdcard_lock(void) ""
88
sdcard_unlock(void) ""
89
sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
90
sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
91
-sdcard_write_data(const char *cmd_desc, uint8_t cmd, uint8_t value) "%20s/ CMD%02d value 0x%02x"
92
-sdcard_read_data(const char *cmd_desc, uint8_t cmd, int length) "%20s/ CMD%02d len %d"
93
+sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint8_t value) "%s %20s/ CMD%02d value 0x%02x"
94
+sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, int length) "%s %20s/ CMD%02d len %d"
95
sdcard_set_voltage(uint16_t millivolts) "%u mV"
96
97
# hw/sd/milkymist-memcard.c
98
--
33
--
99
2.16.2
34
2.20.1
100
35
101
36
diff view generated by jsdifflib
1
From: Marc-André Lureau <marcandre.lureau@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
Spotted by ASAN:
3
Booting the r2d machine from flash fails because flash is not discovered.
4
Looking at the flattened memory tree, we see the following.
4
5
5
elmarco@boraha:~/src/qemu/build (master *%)$ QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 tests/boot-serial-test
6
FlatView #1
6
/aarch64/boot-serial/virt: ** (process:19740): DEBUG: 18:39:30.275: foo /tmp/qtest-boot-serial-cXaS94D
7
AS "memory", root: system
7
=================================================================
8
AS "cpu-memory-0", root: system
8
==19740==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000069648 at pc 0x7f1d2201cc54 bp 0x7fff331f6a40 sp 0x7fff331f61e8
9
AS "sh_pci_host", root: bus master container
9
READ of size 4 at 0x603000069648 thread T0
10
Root memory region: system
10
#0 0x7f1d2201cc53 (/lib64/libasan.so.4+0xafc53)
11
0000000000000000-000000000000ffff (prio 0, i/o): io
11
#1 0x55bc86685ee3 in load_aarch64_image /home/elmarco/src/qemu/hw/arm/boot.c:894
12
0000000000010000-0000000000ffffff (prio 0, i/o): r2d.flash @0000000000010000
12
#2 0x55bc86687217 in arm_load_kernel_notify /home/elmarco/src/qemu/hw/arm/boot.c:1047
13
#3 0x55bc877363b5 in notifier_list_notify /home/elmarco/src/qemu/util/notify.c:40
14
#4 0x55bc869331ea in qemu_run_machine_init_done_notifiers /home/elmarco/src/qemu/vl.c:2716
15
#5 0x55bc8693bc39 in main /home/elmarco/src/qemu/vl.c:4679
16
#6 0x7f1d1652c009 in __libc_start_main (/lib64/libc.so.6+0x21009)
17
#7 0x55bc86255cc9 in _start (/home/elmarco/src/qemu/build/aarch64-softmmu/qemu-system-aarch64+0x1ae5cc9)
18
13
19
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
14
The overlapping memory region is sh_pci.isa, ie the ISA I/O region bridge.
15
This region is initially assigned to address 0xfe240000, but overwritten
16
with a write into the PCIIOBR register. This write is expected to adjust
17
the PCI memory window, but not to change the region's base adddress.
18
19
Peter Maydell provided the following detailed explanation.
20
21
"Section 22.3.7 and in particular figure 22.3 (of "SSH7751R user's manual:
22
hardware") are clear about how this is supposed to work: there is a window
23
at 0xfe240000 in the system register space for PCI I/O space. When the CPU
24
makes an access into that area, the PCI controller calculates the PCI
25
address to use by combining bits 0..17 of the system address with the
26
bits 31..18 value that the guest has put into the PCIIOBR. That is, writing
27
to the PCIIOBR changes which section of the IO address space is visible in
28
the 0xfe240000 window. Instead what QEMU's implementation does is move the
29
window to whatever value the guest writes to the PCIIOBR register -- so if
30
the guest writes 0 we put the window at 0 in system address space."
31
32
Fix the problem by calling memory_region_set_alias_offset() instead of
33
removing and re-adding the PCI ISA subregion on writes into PCIIOBR.
34
At the same time, in sh_pci_device_realize(), don't set iobr since
35
it is overwritten later anyway. Instead, pass the base address to
36
memory_region_add_subregion() directly.
37
38
Many thanks to Peter Maydell for the detailed problem analysis, and for
39
providing suggestions on how to fix the problem.
40
41
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
42
Message-id: 20200218201050.15273-1-linux@roeck-us.net
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
45
---
23
hw/arm/boot.c | 3 ++-
46
hw/sh4/sh_pci.c | 11 +++--------
24
1 file changed, 2 insertions(+), 1 deletion(-)
47
1 file changed, 3 insertions(+), 8 deletions(-)
25
48
26
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
49
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
27
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/boot.c
51
--- a/hw/sh4/sh_pci.c
29
+++ b/hw/arm/boot.c
52
+++ b/hw/sh4/sh_pci.c
30
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
53
@@ -XXX,XX +XXX,XX @@ static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val,
31
}
54
pcic->mbr = val & 0xff000001;
32
55
break;
33
/* check the arm64 magic header value -- very old kernels may not have it */
56
case 0x1c8:
34
- if (memcmp(buffer + ARM64_MAGIC_OFFSET, "ARM\x64", 4) == 0) {
57
- if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) {
35
+ if (size > ARM64_MAGIC_OFFSET + 4 &&
58
- memory_region_del_subregion(get_system_memory(), &pcic->isa);
36
+ memcmp(buffer + ARM64_MAGIC_OFFSET, "ARM\x64", 4) == 0) {
59
- pcic->iobr = val & 0xfffc0001;
37
uint64_t hdrvals[2];
60
- memory_region_add_subregion(get_system_memory(),
38
61
- pcic->iobr & 0xfffc0000, &pcic->isa);
39
/* The arm64 Image header has text_offset and image_size fields at 8 and
62
- }
63
+ pcic->iobr = val & 0xfffc0001;
64
+ memory_region_set_alias_offset(&pcic->isa, val & 0xfffc0000);
65
break;
66
case 0x220:
67
pci_data_write(phb->bus, pcic->par, val, 4);
68
@@ -XXX,XX +XXX,XX @@ static void sh_pci_device_realize(DeviceState *dev, Error **errp)
69
get_system_io(), 0, 0x40000);
70
sysbus_init_mmio(sbd, &s->memconfig_p4);
71
sysbus_init_mmio(sbd, &s->memconfig_a7);
72
- s->iobr = 0xfe240000;
73
- memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
74
+ memory_region_add_subregion(get_system_memory(), 0xfe240000, &s->isa);
75
76
s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
77
}
40
--
78
--
41
2.16.2
79
2.20.1
42
80
43
81
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
The old name, isar_feature_aa32_fp_d32, does not reflect
4
the MVFR0 field name, SIMDReg.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20200214181547.21408-3-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
[PMM: wrapped one long line]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu.h | 2 +-
14
target/arm/translate-vfp.inc.c | 53 +++++++++++++++++-----------------
15
2 files changed, 28 insertions(+), 27 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
22
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
23
}
24
25
-static inline bool isar_feature_aa32_fp_d32(const ARMISARegisters *id)
26
+static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
27
{
28
/* Return true if D16-D31 are implemented */
29
return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) >= 2;
30
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-vfp.inc.c
33
+++ b/target/arm/translate-vfp.inc.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
35
}
36
37
/* UNDEF accesses to D16-D31 if they don't exist */
38
- if (dp && !dc_isar_feature(aa32_fp_d32, s) &&
39
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
40
((a->vm | a->vn | a->vd) & 0x10)) {
41
return false;
42
}
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
44
}
45
46
/* UNDEF accesses to D16-D31 if they don't exist */
47
- if (dp && !dc_isar_feature(aa32_fp_d32, s) &&
48
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
49
((a->vm | a->vn | a->vd) & 0x10)) {
50
return false;
51
}
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
53
}
54
55
/* UNDEF accesses to D16-D31 if they don't exist */
56
- if (dp && !dc_isar_feature(aa32_fp_d32, s) &&
57
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
58
((a->vm | a->vd) & 0x10)) {
59
return false;
60
}
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
62
}
63
64
/* UNDEF accesses to D16-D31 if they don't exist */
65
- if (dp && !dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
66
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
67
return false;
68
}
69
70
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
71
uint32_t offset;
72
73
/* UNDEF accesses to D16-D31 if they don't exist */
74
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vn & 0x10)) {
75
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
76
return false;
77
}
78
79
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
80
uint32_t offset;
81
82
/* UNDEF accesses to D16-D31 if they don't exist */
83
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vn & 0x10)) {
84
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
85
return false;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
89
}
90
91
/* UNDEF accesses to D16-D31 if they don't exist */
92
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vn & 0x10)) {
93
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
94
return false;
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
98
*/
99
100
/* UNDEF accesses to D16-D31 if they don't exist */
101
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
102
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
103
return false;
104
}
105
106
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
107
TCGv_i64 tmp;
108
109
/* UNDEF accesses to D16-D31 if they don't exist */
110
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
111
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
112
return false;
113
}
114
115
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
116
}
117
118
/* UNDEF accesses to D16-D31 if they don't exist */
119
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd + n) > 16) {
120
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd + n) > 16) {
121
return false;
122
}
123
124
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
125
TCGv_ptr fpst;
126
127
/* UNDEF accesses to D16-D31 if they don't exist */
128
- if (!dc_isar_feature(aa32_fp_d32, s) && ((vd | vn | vm) & 0x10)) {
129
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
130
return false;
131
}
132
133
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
134
TCGv_i64 f0, fd;
135
136
/* UNDEF accesses to D16-D31 if they don't exist */
137
- if (!dc_isar_feature(aa32_fp_d32, s) && ((vd | vm) & 0x10)) {
138
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
139
return false;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
143
}
144
145
/* UNDEF accesses to D16-D31 if they don't exist. */
146
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vn | a->vm) & 0x10)) {
147
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
148
+ ((a->vd | a->vn | a->vm) & 0x10)) {
149
return false;
150
}
151
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
153
vd = a->vd;
154
155
/* UNDEF accesses to D16-D31 if they don't exist. */
156
- if (!dc_isar_feature(aa32_fp_d32, s) && (vd & 0x10)) {
157
+ if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
158
return false;
159
}
160
161
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
162
}
163
164
/* UNDEF accesses to D16-D31 if they don't exist. */
165
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
166
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
167
return false;
168
}
169
170
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
171
}
172
173
/* UNDEF accesses to D16-D31 if they don't exist. */
174
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
175
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
176
return false;
177
}
178
179
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
180
}
181
182
/* UNDEF accesses to D16-D31 if they don't exist. */
183
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
184
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
185
return false;
186
}
187
188
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
189
}
190
191
/* UNDEF accesses to D16-D31 if they don't exist. */
192
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
193
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
194
return false;
195
}
196
197
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
198
}
199
200
/* UNDEF accesses to D16-D31 if they don't exist. */
201
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
202
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
203
return false;
204
}
205
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
207
}
208
209
/* UNDEF accesses to D16-D31 if they don't exist. */
210
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
211
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
212
return false;
213
}
214
215
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
216
TCGv_i32 vm;
217
218
/* UNDEF accesses to D16-D31 if they don't exist. */
219
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
220
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
221
return false;
222
}
223
224
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
225
TCGv_i32 vd;
226
227
/* UNDEF accesses to D16-D31 if they don't exist. */
228
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
229
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
230
return false;
231
}
232
233
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
234
TCGv_ptr fpst;
235
236
/* UNDEF accesses to D16-D31 if they don't exist. */
237
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
238
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
239
return false;
240
}
241
242
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
243
}
244
245
/* UNDEF accesses to D16-D31 if they don't exist. */
246
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
247
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
248
return false;
249
}
250
251
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
252
}
253
254
/* UNDEF accesses to D16-D31 if they don't exist. */
255
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
256
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
257
return false;
258
}
259
260
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
261
TCGv_ptr fpst;
262
263
/* UNDEF accesses to D16-D31 if they don't exist. */
264
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
265
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
266
return false;
267
}
268
269
--
270
2.20.1
271
272
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
A lot of ARM object files are linked into the executable unconditionally,
3
Many uses of ARM_FEATURE_VFP3 are testing for the number of simd
4
even though we have corresponding CONFIG switches like CONFIG_PXA2XX or
4
registers implemented. Use the proper test vs MVFR0.SIMDReg.
5
CONFIG_OMAP. We should make sure to use these switches in the Makefile so
6
that the users can disable certain unwanted boards and devices more easily.
7
While we're at it, also add some new switches for the boards that do not
8
have a CONFIG option yet.
9
5
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 1520266949-29817-1-git-send-email-thuth@redhat.com
7
Message-id: 20200214181547.21408-4-richard.henderson@linaro.org
8
[PMM: fix typo in commit message]
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
11
---
16
hw/arm/Makefile.objs | 30 +++++++++++++++++++++---------
12
target/arm/cpu.c | 9 ++++-----
17
default-configs/arm-softmmu.mak | 7 +++++++
13
target/arm/helper.c | 13 ++++++-------
18
2 files changed, 28 insertions(+), 9 deletions(-)
14
target/arm/translate.c | 2 +-
15
3 files changed, 11 insertions(+), 13 deletions(-)
19
16
20
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/Makefile.objs
19
--- a/target/arm/cpu.c
23
+++ b/hw/arm/Makefile.objs
20
+++ b/target/arm/cpu.c
24
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
25
-obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
22
26
-obj-$(CONFIG_DIGIC) += digic_boards.o
23
if (flags & CPU_DUMP_FPU) {
27
-obj-y += integratorcp.o mainstone.o musicpal.o nseries.o
24
int numvfpregs = 0;
28
-obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
25
- if (arm_feature(env, ARM_FEATURE_VFP)) {
29
-obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
26
- numvfpregs += 16;
30
+obj-y += boot.o virt.o sysbus-fdt.o
27
- }
31
obj-$(CONFIG_ACPI) += virt-acpi-build.o
28
- if (arm_feature(env, ARM_FEATURE_VFP3)) {
32
-obj-y += netduino2.o
29
- numvfpregs += 16;
33
-obj-y += sysbus-fdt.o
30
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
34
+obj-$(CONFIG_DIGIC) += digic_boards.o
31
+ numvfpregs = 32;
35
+obj-$(CONFIG_EXYNOS4) += exynos4_boards.o
32
+ } else if (arm_feature(env, ARM_FEATURE_VFP)) {
36
+obj-$(CONFIG_HIGHBANK) += highbank.o
33
+ numvfpregs = 16;
37
+obj-$(CONFIG_INTEGRATOR) += integratorcp.o
34
}
38
+obj-$(CONFIG_MAINSTONE) += mainstone.o
35
for (i = 0; i < numvfpregs; i++) {
39
+obj-$(CONFIG_MUSICPAL) += musicpal.o
36
uint64_t v = *aa32_vfp_dreg(env, i);
40
+obj-$(CONFIG_NETDUINO2) += netduino2.o
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
+obj-$(CONFIG_NSERIES) += nseries.o
42
+obj-$(CONFIG_OMAP) += omap_sx1.o palm.o
43
+obj-$(CONFIG_PXA2XX) += gumstix.o spitz.o tosa.o z2.o
44
+obj-$(CONFIG_REALVIEW) += realview.o
45
+obj-$(CONFIG_STELLARIS) += stellaris.o
46
+obj-$(CONFIG_STRONGARM) += collie.o
47
+obj-$(CONFIG_VERSATILE) += vexpress.o versatilepb.o
48
+obj-$(CONFIG_ZYNQ) += xilinx_zynq.o
49
50
-obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
51
+obj-$(CONFIG_ARM_V7M) += armv7m.o
52
+obj-$(CONFIG_EXYNOS4) += exynos4210.o
53
+obj-$(CONFIG_PXA2XX) += pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
54
obj-$(CONFIG_DIGIC) += digic.o
55
-obj-y += omap1.o omap2.o strongarm.o
56
+obj-$(CONFIG_OMAP) += omap1.o omap2.o
57
+obj-$(CONFIG_STRONGARM) += strongarm.o
58
obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
59
obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
60
obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
61
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
62
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
63
--- a/default-configs/arm-softmmu.mak
39
--- a/target/arm/helper.c
64
+++ b/default-configs/arm-softmmu.mak
40
+++ b/target/arm/helper.c
65
@@ -XXX,XX +XXX,XX @@ CONFIG_A9MPCORE=y
41
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode);
66
CONFIG_A15MPCORE=y
42
67
43
static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
68
CONFIG_ARM_V7M=y
44
{
69
+CONFIG_NETDUINO2=y
45
- int nregs;
70
46
+ ARMCPU *cpu = env_archcpu(env);
71
CONFIG_ARM_GIC=y
47
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
72
CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
48
73
@@ -XXX,XX +XXX,XX @@ CONFIG_TZ_PPC=y
49
/* VFP data registers are always little-endian. */
74
CONFIG_IOTKIT=y
50
- nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
75
CONFIG_IOTKIT_SECCTL=y
51
if (reg < nregs) {
76
52
stq_le_p(buf, *aa32_vfp_dreg(env, reg));
77
+CONFIG_VERSATILE=y
53
return 8;
78
CONFIG_VERSATILE_PCI=y
54
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
79
CONFIG_VERSATILE_I2C=y
55
80
56
static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
81
@@ -XXX,XX +XXX,XX @@ CONFIG_VFIO_XGMAC=y
57
{
82
CONFIG_VFIO_AMD_XGBE=y
58
- int nregs;
83
59
+ ARMCPU *cpu = env_archcpu(env);
84
CONFIG_SDHCI=y
60
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
85
+CONFIG_INTEGRATOR=y
61
86
CONFIG_INTEGRATOR_DEBUG=y
62
- nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
87
63
if (reg < nregs) {
88
CONFIG_ALLWINNER_A10_PIT=y
64
*aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
89
@@ -XXX,XX +XXX,XX @@ CONFIG_MSF2=y
65
return 8;
90
CONFIG_FW_CFG_DMA=y
66
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
91
CONFIG_XILINX_AXI=y
67
/* VFPv3 and upwards with NEON implement 32 double precision
92
CONFIG_PCI_DESIGNWARE=y
68
* registers (D0-D31).
93
+
69
*/
94
+CONFIG_STRONGARM=y
70
- if (!arm_feature(env, ARM_FEATURE_NEON) ||
95
+CONFIG_HIGHBANK=y
71
- !arm_feature(env, ARM_FEATURE_VFP3)) {
96
+CONFIG_MUSICPAL=y
72
+ if (!cpu_isar_feature(aa32_simd_r32, env_archcpu(env))) {
73
/* D32DIS [30] is RAO/WI if D16-31 are not implemented. */
74
value |= (1 << 30);
75
}
76
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
77
} else if (arm_feature(env, ARM_FEATURE_NEON)) {
78
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
79
51, "arm-neon.xml", 0);
80
- } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
81
+ } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
82
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
83
35, "arm-vfp3.xml", 0);
84
} else if (arm_feature(env, ARM_FEATURE_VFP)) {
85
diff --git a/target/arm/translate.c b/target/arm/translate.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/translate.c
88
+++ b/target/arm/translate.c
89
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
90
#define VFP_SREG(insn, bigbit, smallbit) \
91
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
92
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
93
- if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
94
+ if (dc_isar_feature(aa32_simd_r32, s)) { \
95
reg = (((insn) >> (bigbit)) & 0x0f) \
96
| (((insn) >> ((smallbit) - 4)) & 0x10); \
97
} else { \
97
--
98
--
98
2.16.2
99
2.20.1
99
100
100
101
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
We are going to convert FEATURE tests to ISAR tests,
4
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
4
so FPSP needs to be set for these cpus, like we have
5
Message-id: 20180309153654.13518-2-f4bug@amsat.org
5
already for FPDP.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200214181547.21408-5-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
hw/sd/sd.c | 11 ++++++++---
12
target/arm/cpu.c | 10 ++++++----
10
1 file changed, 8 insertions(+), 3 deletions(-)
13
1 file changed, 6 insertions(+), 4 deletions(-)
11
14
12
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sd.c
17
--- a/target/arm/cpu.c
15
+++ b/hw/sd/sd.c
18
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sd_lock_command(SDState *sd)
19
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
17
sd->card_status &= ~CARD_IS_LOCKED;
20
*/
21
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
22
/*
23
- * Similarly, we need to set MVFR0 fields to enable double precision
24
- * and short vector support even though ARMv5 doesn't have this register.
25
+ * Similarly, we need to set MVFR0 fields to enable vfp and short vector
26
+ * support even though ARMv5 doesn't have this register.
27
*/
28
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
29
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
30
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
18
}
31
}
19
32
20
-static sd_rsp_type_t sd_normal_command(SDState *sd,
33
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
21
- SDRequest req)
34
*/
22
+static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
35
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
23
{
36
/*
24
uint32_t rca = 0x0000;
37
- * Similarly, we need to set MVFR0 fields to enable double precision
25
uint64_t addr = (sd->ocr & (1 << 30)) ? (uint64_t) req.arg << 9 : req.arg;
38
- * and short vector support even though ARMv5 doesn't have this register.
26
39
+ * Similarly, we need to set MVFR0 fields to enable vfp and short vector
27
- trace_sdcard_normal_command(req.cmd, req.arg, sd_state_name(sd->state));
40
+ * support even though ARMv5 doesn't have this register.
28
+ /* CMD55 precedes an ACMD, so we are not interested in tracing it.
41
*/
29
+ * However there is no ACMD55, so we want to trace this particular case.
42
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
30
+ */
43
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
31
+ if (req.cmd != 55 || sd->expecting_acmd) {
44
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
32
+ trace_sdcard_normal_command(req.cmd, req.arg,
45
33
+ sd_state_name(sd->state));
46
{
34
+ }
35
36
/* Not interpreting this as an app command */
37
sd->card_status &= ~APP_CMD;
38
--
47
--
39
2.16.2
48
2.20.1
40
49
41
50
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The EXTRA record allows for additional space to be allocated
3
Use this in the places that were checking ARM_FEATURE_VFP, and
4
beyon what is currently reserved. Add code to emit and read
4
are obviously testing for the existance of the register set
5
this record type.
5
as opposed to testing for some particular instruction extension.
6
7
Nothing uses extra space yet.
8
6
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180303143823.27055-5-richard.henderson@linaro.org
8
Message-id: 20200214181547.21408-6-richard.henderson@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
linux-user/signal.c | 74 +++++++++++++++++++++++++++++++++++++++++++++--------
12
target/arm/cpu.h | 6 ++++++
16
1 file changed, 63 insertions(+), 11 deletions(-)
13
hw/intc/armv7m_nvic.c | 20 ++++++++++----------
17
14
linux-user/arm/signal.c | 4 ++--
18
diff --git a/linux-user/signal.c b/linux-user/signal.c
15
target/arm/arch_dump.c | 11 ++++++-----
19
index XXXXXXX..XXXXXXX 100644
16
target/arm/cpu.c | 8 ++++----
20
--- a/linux-user/signal.c
17
target/arm/helper.c | 4 ++--
21
+++ b/linux-user/signal.c
18
target/arm/m_helper.c | 11 ++++++-----
22
@@ -XXX,XX +XXX,XX @@ struct target_fpsimd_context {
19
target/arm/machine.c | 3 +--
23
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
20
8 files changed, 37 insertions(+), 30 deletions(-)
24
};
21
25
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
+#define TARGET_EXTRA_MAGIC 0x45585401
23
index XXXXXXX..XXXXXXX 100644
27
+
24
--- a/target/arm/cpu.h
28
+struct target_extra_context {
25
+++ b/target/arm/cpu.h
29
+ struct target_aarch64_ctx head;
26
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
30
+ uint64_t datap; /* 16-byte aligned pointer to extra space cast to __u64 */
27
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
31
+ uint32_t size; /* size in bytes of the extra space */
32
+ uint32_t reserved[3];
33
+};
34
+
35
struct target_rt_sigframe {
36
struct target_siginfo info;
37
struct target_ucontext uc;
38
@@ -XXX,XX +XXX,XX @@ static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
39
}
40
}
28
}
41
29
42
+static void target_setup_extra_record(struct target_extra_context *extra,
30
+static inline bool isar_feature_aa32_simd_r16(const ARMISARegisters *id)
43
+ uint64_t datap, uint32_t extra_size)
44
+{
31
+{
45
+ __put_user(TARGET_EXTRA_MAGIC, &extra->head.magic);
32
+ /* Return true if D0-D15 are implemented */
46
+ __put_user(sizeof(struct target_extra_context), &extra->head.size);
33
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) > 0;
47
+ __put_user(datap, &extra->datap);
48
+ __put_user(extra_size, &extra->size);
49
+}
34
+}
50
+
35
+
51
static void target_setup_end_record(struct target_aarch64_ctx *end)
36
static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
52
{
37
{
53
__put_user(0, &end->magic);
38
/* Return true if D16-D31 are implemented */
54
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
55
static int target_restore_sigframe(CPUARMState *env,
40
index XXXXXXX..XXXXXXX 100644
56
struct target_rt_sigframe *sf)
41
--- a/hw/intc/armv7m_nvic.c
42
+++ b/hw/intc/armv7m_nvic.c
43
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
44
case 0xd84: /* CSSELR */
45
return cpu->env.v7m.csselr[attrs.secure];
46
case 0xd88: /* CPACR */
47
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
48
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
49
return 0;
50
}
51
return cpu->env.v7m.cpacr[attrs.secure];
52
case 0xd8c: /* NSACR */
53
- if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
54
+ if (!attrs.secure || !cpu_isar_feature(aa32_simd_r16, cpu)) {
55
return 0;
56
}
57
return cpu->env.v7m.nsacr;
58
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
59
}
60
return cpu->env.v7m.sfar;
61
case 0xf34: /* FPCCR */
62
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
63
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
64
return 0;
65
}
66
if (attrs.secure) {
67
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
68
return value;
69
}
70
case 0xf38: /* FPCAR */
71
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
72
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
73
return 0;
74
}
75
return cpu->env.v7m.fpcar[attrs.secure];
76
case 0xf3c: /* FPDSCR */
77
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
78
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
79
return 0;
80
}
81
return cpu->env.v7m.fpdscr[attrs.secure];
82
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
83
}
84
break;
85
case 0xd88: /* CPACR */
86
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
87
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
88
/* We implement only the Floating Point extension's CP10/CP11 */
89
cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
90
}
91
break;
92
case 0xd8c: /* NSACR */
93
- if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
94
+ if (attrs.secure && cpu_isar_feature(aa32_simd_r16, cpu)) {
95
/* We implement only the Floating Point extension's CP10/CP11 */
96
cpu->env.v7m.nsacr = value & (3 << 10);
97
}
98
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
99
break;
100
}
101
case 0xf34: /* FPCCR */
102
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
103
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
104
/* Not all bits here are banked. */
105
uint32_t fpccr_s;
106
107
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
108
}
109
break;
110
case 0xf38: /* FPCAR */
111
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
112
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
113
value &= ~7;
114
cpu->env.v7m.fpcar[attrs.secure] = value;
115
}
116
break;
117
case 0xf3c: /* FPDSCR */
118
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
119
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
120
value &= 0x07c00000;
121
cpu->env.v7m.fpdscr[attrs.secure] = value;
122
}
123
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/linux-user/arm/signal.c
126
+++ b/linux-user/arm/signal.c
127
@@ -XXX,XX +XXX,XX @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
128
setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
129
/* Save coprocessor signal frame. */
130
regspace = uc->tuc_regspace;
131
- if (arm_feature(env, ARM_FEATURE_VFP)) {
132
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
133
regspace = setup_sigframe_v2_vfp(regspace, env);
134
}
135
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
136
@@ -XXX,XX +XXX,XX @@ static int do_sigframe_return_v2(CPUARMState *env,
137
138
/* Restore coprocessor signal frame */
139
regspace = uc->tuc_regspace;
140
- if (arm_feature(env, ARM_FEATURE_VFP)) {
141
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
142
regspace = restore_sigframe_v2_vfp(env, regspace);
143
if (!regspace) {
144
return 1;
145
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/arch_dump.c
148
+++ b/target/arm/arch_dump.c
149
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
150
int cpuid, void *opaque)
57
{
151
{
58
- struct target_aarch64_ctx *ctx;
152
struct arm_note note;
59
+ struct target_aarch64_ctx *ctx, *extra = NULL;
153
- CPUARMState *env = &ARM_CPU(cs)->env;
60
struct target_fpsimd_context *fpsimd = NULL;
154
+ ARMCPU *cpu = ARM_CPU(cs);
61
+ uint64_t extra_datap = 0;
155
+ CPUARMState *env = &cpu->env;
62
+ bool used_extra = false;
156
DumpState *s = opaque;
63
+ bool err = false;
157
- int ret, i, fpvalid = !!arm_feature(env, ARM_FEATURE_VFP);
64
158
+ int ret, i;
65
target_restore_general_frame(env, sf);
159
+ bool fpvalid = cpu_isar_feature(aa32_simd_r16, cpu);
66
160
67
ctx = (struct target_aarch64_ctx *)sf->uc.tuc_mcontext.__reserved;
161
arm_note_init(&note, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus));
68
while (ctx) {
162
69
- uint32_t magic, size;
163
@@ -XXX,XX +XXX,XX @@ int cpu_get_dump_info(ArchDumpInfo *info,
70
+ uint32_t magic, size, extra_size;
164
ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
71
165
{
72
__get_user(magic, &ctx->magic);
166
ARMCPU *cpu = ARM_CPU(first_cpu);
73
__get_user(size, &ctx->size);
167
- CPUARMState *env = &cpu->env;
74
switch (magic) {
168
size_t note_size;
75
case 0:
169
76
if (size != 0) {
170
if (class == ELFCLASS64) {
77
- return 1;
171
@@ -XXX,XX +XXX,XX @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
78
+ err = true;
172
note_size += AARCH64_PRFPREG_NOTE_SIZE;
79
+ goto exit;
173
#ifdef TARGET_AARCH64
80
+ }
174
if (cpu_isar_feature(aa64_sve, cpu)) {
81
+ if (used_extra) {
175
- note_size += AARCH64_SVE_NOTE_SIZE(env);
82
+ ctx = NULL;
176
+ note_size += AARCH64_SVE_NOTE_SIZE(&cpu->env);
83
+ } else {
177
}
84
+ ctx = extra;
178
#endif
85
+ used_extra = true;
179
} else {
86
}
180
note_size = ARM_PRSTATUS_NOTE_SIZE;
87
- ctx = NULL;
181
- if (arm_feature(env, ARM_FEATURE_VFP)) {
88
continue;
182
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
89
183
note_size += ARM_VFP_NOTE_SIZE;
90
case TARGET_FPSIMD_MAGIC:
184
}
91
if (fpsimd || size != sizeof(struct target_fpsimd_context)) {
185
}
92
- return 1;
186
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
93
+ err = true;
187
index XXXXXXX..XXXXXXX 100644
94
+ goto exit;
188
--- a/target/arm/cpu.c
95
}
189
+++ b/target/arm/cpu.c
96
fpsimd = (struct target_fpsimd_context *)ctx;
190
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
97
break;
191
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
98
192
}
99
+ case TARGET_EXTRA_MAGIC:
193
100
+ if (extra || size != sizeof(struct target_extra_context)) {
194
- if (arm_feature(env, ARM_FEATURE_VFP)) {
101
+ err = true;
195
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
102
+ goto exit;
196
env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
103
+ }
197
env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
104
+ __get_user(extra_datap,
198
R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
105
+ &((struct target_extra_context *)ctx)->datap);
199
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
106
+ __get_user(extra_size,
200
int numvfpregs = 0;
107
+ &((struct target_extra_context *)ctx)->size);
201
if (cpu_isar_feature(aa32_simd_r32, cpu)) {
108
+ extra = lock_user(VERIFY_READ, extra_datap, extra_size, 0);
202
numvfpregs = 32;
109
+ break;
203
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
110
+
204
+ } else if (cpu_isar_feature(aa32_simd_r16, cpu)) {
111
default:
205
numvfpregs = 16;
112
/* Unknown record -- we certainly didn't generate it.
206
}
113
* Did we in fact get out of sync?
207
for (i = 0; i < numvfpregs; i++) {
208
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
209
* KVM does not currently allow us to lie to the guest about its
210
* ID/feature registers, so the guest always sees what the host has.
211
*/
212
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
213
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
214
cpu->has_vfp = true;
215
if (!kvm_enabled()) {
216
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
217
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
218
* We rely on no XScale CPU having VFP so we can use the same bits in the
219
* TB flags field for VECSTRIDE and XSCALE_CPAR.
220
*/
221
- assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
222
+ assert(!(cpu_isar_feature(aa32_simd_r16, cpu) &&
223
arm_feature(env, ARM_FEATURE_XSCALE)));
224
225
if (arm_feature(env, ARM_FEATURE_V7) &&
226
diff --git a/target/arm/helper.c b/target/arm/helper.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/arm/helper.c
229
+++ b/target/arm/helper.c
230
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
* ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP.
232
* TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell.
233
*/
234
- if (arm_feature(env, ARM_FEATURE_VFP)) {
235
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
236
/* VFP coprocessor: cp10 & cp11 [23:20] */
237
mask |= (1 << 31) | (1 << 30) | (0xf << 20);
238
239
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
240
} else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
241
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
242
35, "arm-vfp3.xml", 0);
243
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
244
+ } else if (cpu_isar_feature(aa32_simd_r16, cpu)) {
245
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
246
19, "arm-vfp.xml", 0);
247
}
248
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
249
index XXXXXXX..XXXXXXX 100644
250
--- a/target/arm/m_helper.c
251
+++ b/target/arm/m_helper.c
252
@@ -XXX,XX +XXX,XX @@ static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
253
*/
254
uint32_t sig = 0xfefa125a;
255
256
- if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
257
+ if (!cpu_isar_feature(aa32_simd_r16, env_archcpu(env))
258
+ || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
259
sig |= 1;
260
}
261
return sig;
262
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
263
264
if (dotailchain) {
265
/* Sanitize LR FType and PREFIX bits */
266
- if (!arm_feature(env, ARM_FEATURE_VFP)) {
267
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
268
lr |= R_V7M_EXCRET_FTYPE_MASK;
269
}
270
lr = deposit32(lr, 24, 8, 0xff);
271
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
272
273
ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
274
275
- if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
276
+ if (!ftype && !cpu_isar_feature(aa32_simd_r16, cpu)) {
277
qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
278
"exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
279
"if FPU not present\n",
280
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
281
* SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
282
* RES0 if the FPU is not present, and is stored in the S bank
114
*/
283
*/
115
- return 1;
284
- if (arm_feature(env, ARM_FEATURE_VFP) &&
116
+ err = true;
285
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env)) &&
117
+ goto exit;
286
extract32(env->v7m.nsacr, 10, 1)) {
118
}
287
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
119
ctx = (void *)ctx + size;
288
env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
120
}
289
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
121
290
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
122
/* Require FPSIMD always. */
291
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
123
- if (!fpsimd) {
292
}
124
- return 1;
293
- if (arm_feature(env, ARM_FEATURE_VFP)) {
125
+ if (fpsimd) {
294
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
126
+ target_restore_fpsimd_record(env, fpsimd);
295
/*
127
+ } else {
296
* SFPA is RAZ/WI from NS or if no FPU.
128
+ err = true;
297
* FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
129
}
298
diff --git a/target/arm/machine.c b/target/arm/machine.c
130
- target_restore_fpsimd_record(env, fpsimd);
299
index XXXXXXX..XXXXXXX 100644
131
300
--- a/target/arm/machine.c
132
- return 0;
301
+++ b/target/arm/machine.c
133
+ exit:
302
@@ -XXX,XX +XXX,XX @@
134
+ unlock_user(extra, extra_datap, 0);
303
static bool vfp_needed(void *opaque)
135
+ return err;
304
{
305
ARMCPU *cpu = opaque;
306
- CPUARMState *env = &cpu->env;
307
308
- return arm_feature(env, ARM_FEATURE_VFP);
309
+ return cpu_isar_feature(aa32_simd_r16, cpu);
136
}
310
}
137
311
138
static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
312
static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
139
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
140
CPUARMState *env)
141
{
142
int size = offsetof(struct target_rt_sigframe, uc.tuc_mcontext.__reserved);
143
- int fpsimd_ofs, end1_ofs, fr_ofs;
144
+ int fpsimd_ofs, end1_ofs, fr_ofs, end2_ofs = 0;
145
+ int extra_ofs = 0, extra_base = 0, extra_size = 0;
146
struct target_rt_sigframe *frame;
147
struct target_rt_frame_record *fr;
148
abi_ulong frame_addr, return_addr;
149
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
150
151
target_setup_general_frame(frame, env, set);
152
target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
153
+ if (extra_ofs) {
154
+ target_setup_extra_record((void *)frame + extra_ofs,
155
+ frame_addr + extra_base, extra_size);
156
+ }
157
target_setup_end_record((void *)frame + end1_ofs);
158
+ if (end2_ofs) {
159
+ target_setup_end_record((void *)frame + end2_ofs);
160
+ }
161
162
/* Set up the stack frame for unwinding. */
163
fr = (void *)frame + fr_ofs;
164
--
313
--
165
2.16.2
314
2.20.1
166
315
167
316
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
The old name, isar_feature_aa32_fpdp, does not reflect
4
that the test includes VFPv2. We will introduce further
5
feature tests for VFPv3.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20200214181547.21408-7-richard.henderson@linaro.org
10
[PMM: fixed grammar in commit message]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/cpu.h | 4 ++--
15
target/arm/translate-vfp.inc.c | 40 +++++++++++++++++-----------------
16
2 files changed, 22 insertions(+), 22 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
23
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
24
}
25
26
-static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
27
+static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
28
{
29
- /* Return true if CPU supports double precision floating point */
30
+ /* Return true if CPU supports double precision floating point, VFPv2 */
31
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
32
}
33
34
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-vfp.inc.c
37
+++ b/target/arm/translate-vfp.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
39
return false;
40
}
41
42
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
43
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
44
return false;
45
}
46
47
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
48
return false;
49
}
50
51
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
52
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
53
return false;
54
}
55
56
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
57
return false;
58
}
59
60
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
61
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
62
return false;
63
}
64
65
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
66
return false;
67
}
68
69
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
70
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
71
return false;
72
}
73
74
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
75
return false;
76
}
77
78
- if (!dc_isar_feature(aa32_fpdp, s)) {
79
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
80
return false;
81
}
82
83
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
84
return false;
85
}
86
87
- if (!dc_isar_feature(aa32_fpdp, s)) {
88
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
89
return false;
90
}
91
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
93
return false;
94
}
95
96
- if (!dc_isar_feature(aa32_fpdp, s)) {
97
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
98
return false;
99
}
100
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
102
return false;
103
}
104
105
- if (!dc_isar_feature(aa32_fpdp, s)) {
106
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
107
return false;
108
}
109
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
111
return false;
112
}
113
114
- if (!dc_isar_feature(aa32_fpdp, s)) {
115
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
116
return false;
117
}
118
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
120
return false;
121
}
122
123
- if (!dc_isar_feature(aa32_fpdp, s)) {
124
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
125
return false;
126
}
127
128
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
129
return false;
130
}
131
132
- if (!dc_isar_feature(aa32_fpdp, s)) {
133
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
134
return false;
135
}
136
137
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
138
return false;
139
}
140
141
- if (!dc_isar_feature(aa32_fpdp, s)) {
142
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
143
return false;
144
}
145
146
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
147
return false;
148
}
149
150
- if (!dc_isar_feature(aa32_fpdp, s)) {
151
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
152
return false;
153
}
154
155
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
156
return false;
157
}
158
159
- if (!dc_isar_feature(aa32_fpdp, s)) {
160
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
161
return false;
162
}
163
164
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
165
return false;
166
}
167
168
- if (!dc_isar_feature(aa32_fpdp, s)) {
169
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
170
return false;
171
}
172
173
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
174
return false;
175
}
176
177
- if (!dc_isar_feature(aa32_fpdp, s)) {
178
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
179
return false;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
183
return false;
184
}
185
186
- if (!dc_isar_feature(aa32_fpdp, s)) {
187
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
188
return false;
189
}
190
191
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
192
return false;
193
}
194
195
- if (!dc_isar_feature(aa32_fpdp, s)) {
196
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
197
return false;
198
}
199
200
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
201
return false;
202
}
203
204
- if (!dc_isar_feature(aa32_fpdp, s)) {
205
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
206
return false;
207
}
208
209
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
210
return false;
211
}
212
213
- if (!dc_isar_feature(aa32_fpdp, s)) {
214
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
215
return false;
216
}
217
218
--
219
2.20.1
220
221
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Depending on the currently selected size of the SVE vector registers,
3
We will shortly use these to test for VFPv2 and VFPv3
4
we can either store the data within the "standard" allocation, or we
4
in different situations.
5
may beedn to allocate additional space with an EXTRA record.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180303143823.27055-6-richard.henderson@linaro.org
7
Message-id: 20200214181547.21408-8-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
linux-user/signal.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++-----
11
target/arm/cpu.h | 18 ++++++++++++++++++
13
1 file changed, 192 insertions(+), 18 deletions(-)
12
1 file changed, 18 insertions(+)
14
13
15
diff --git a/linux-user/signal.c b/linux-user/signal.c
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/signal.c
16
--- a/target/arm/cpu.h
18
+++ b/linux-user/signal.c
17
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ struct target_extra_context {
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
20
uint32_t reserved[3];
19
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
21
};
22
23
+#define TARGET_SVE_MAGIC 0x53564501
24
+
25
+struct target_sve_context {
26
+ struct target_aarch64_ctx head;
27
+ uint16_t vl;
28
+ uint16_t reserved[3];
29
+ /* The actual SVE data immediately follows. It is layed out
30
+ * according to TARGET_SVE_SIG_{Z,P}REG_OFFSET, based off of
31
+ * the original struct pointer.
32
+ */
33
+};
34
+
35
+#define TARGET_SVE_VQ_BYTES 16
36
+
37
+#define TARGET_SVE_SIG_ZREG_SIZE(VQ) ((VQ) * TARGET_SVE_VQ_BYTES)
38
+#define TARGET_SVE_SIG_PREG_SIZE(VQ) ((VQ) * (TARGET_SVE_VQ_BYTES / 8))
39
+
40
+#define TARGET_SVE_SIG_REGS_OFFSET \
41
+ QEMU_ALIGN_UP(sizeof(struct target_sve_context), TARGET_SVE_VQ_BYTES)
42
+#define TARGET_SVE_SIG_ZREG_OFFSET(VQ, N) \
43
+ (TARGET_SVE_SIG_REGS_OFFSET + TARGET_SVE_SIG_ZREG_SIZE(VQ) * (N))
44
+#define TARGET_SVE_SIG_PREG_OFFSET(VQ, N) \
45
+ (TARGET_SVE_SIG_ZREG_OFFSET(VQ, 32) + TARGET_SVE_SIG_PREG_SIZE(VQ) * (N))
46
+#define TARGET_SVE_SIG_FFR_OFFSET(VQ) \
47
+ (TARGET_SVE_SIG_PREG_OFFSET(VQ, 16))
48
+#define TARGET_SVE_SIG_CONTEXT_SIZE(VQ) \
49
+ (TARGET_SVE_SIG_PREG_OFFSET(VQ, 17))
50
+
51
struct target_rt_sigframe {
52
struct target_siginfo info;
53
struct target_ucontext uc;
54
@@ -XXX,XX +XXX,XX @@ static void target_setup_end_record(struct target_aarch64_ctx *end)
55
__put_user(0, &end->size);
56
}
20
}
57
21
58
+static void target_setup_sve_record(struct target_sve_context *sve,
22
+static inline bool isar_feature_aa32_fpsp_v2(const ARMISARegisters *id)
59
+ CPUARMState *env, int vq, int size)
60
+{
23
+{
61
+ int i, j;
24
+ /* Return true if CPU supports single precision floating point, VFPv2 */
62
+
25
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) > 0;
63
+ __put_user(TARGET_SVE_MAGIC, &sve->head.magic);
64
+ __put_user(size, &sve->head.size);
65
+ __put_user(vq * TARGET_SVE_VQ_BYTES, &sve->vl);
66
+
67
+ /* Note that SVE regs are stored as a byte stream, with each byte element
68
+ * at a subsequent address. This corresponds to a little-endian store
69
+ * of our 64-bit hunks.
70
+ */
71
+ for (i = 0; i < 32; ++i) {
72
+ uint64_t *z = (void *)sve + TARGET_SVE_SIG_ZREG_OFFSET(vq, i);
73
+ for (j = 0; j < vq * 2; ++j) {
74
+ __put_user_e(env->vfp.zregs[i].d[j], z + j, le);
75
+ }
76
+ }
77
+ for (i = 0; i <= 16; ++i) {
78
+ uint16_t *p = (void *)sve + TARGET_SVE_SIG_PREG_OFFSET(vq, i);
79
+ for (j = 0; j < vq; ++j) {
80
+ uint64_t r = env->vfp.pregs[i].p[j >> 2];
81
+ __put_user_e(r >> ((j & 3) * 16), p + j, le);
82
+ }
83
+ }
84
+}
26
+}
85
+
27
+
86
static void target_restore_general_frame(CPUARMState *env,
28
+static inline bool isar_feature_aa32_fpsp_v3(const ARMISARegisters *id)
87
struct target_rt_sigframe *sf)
88
{
89
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
90
}
91
}
92
93
+static void target_restore_sve_record(CPUARMState *env,
94
+ struct target_sve_context *sve, int vq)
95
+{
29
+{
96
+ int i, j;
30
+ /* Return true if CPU supports single precision floating point, VFPv3 */
97
+
31
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) >= 2;
98
+ /* Note that SVE regs are stored as a byte stream, with each byte element
99
+ * at a subsequent address. This corresponds to a little-endian load
100
+ * of our 64-bit hunks.
101
+ */
102
+ for (i = 0; i < 32; ++i) {
103
+ uint64_t *z = (void *)sve + TARGET_SVE_SIG_ZREG_OFFSET(vq, i);
104
+ for (j = 0; j < vq * 2; ++j) {
105
+ __get_user_e(env->vfp.zregs[i].d[j], z + j, le);
106
+ }
107
+ }
108
+ for (i = 0; i <= 16; ++i) {
109
+ uint16_t *p = (void *)sve + TARGET_SVE_SIG_PREG_OFFSET(vq, i);
110
+ for (j = 0; j < vq; ++j) {
111
+ uint16_t r;
112
+ __get_user_e(r, p + j, le);
113
+ if (j & 3) {
114
+ env->vfp.pregs[i].p[j >> 2] |= (uint64_t)r << ((j & 3) * 16);
115
+ } else {
116
+ env->vfp.pregs[i].p[j >> 2] = r;
117
+ }
118
+ }
119
+ }
120
+}
32
+}
121
+
33
+
122
static int target_restore_sigframe(CPUARMState *env,
34
static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
123
struct target_rt_sigframe *sf)
124
{
35
{
125
struct target_aarch64_ctx *ctx, *extra = NULL;
36
/* Return true if CPU supports double precision floating point, VFPv2 */
126
struct target_fpsimd_context *fpsimd = NULL;
37
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
127
+ struct target_sve_context *sve = NULL;
128
uint64_t extra_datap = 0;
129
bool used_extra = false;
130
bool err = false;
131
+ int vq = 0, sve_size = 0;
132
133
target_restore_general_frame(env, sf);
134
135
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
136
fpsimd = (struct target_fpsimd_context *)ctx;
137
break;
138
139
+ case TARGET_SVE_MAGIC:
140
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
141
+ vq = (env->vfp.zcr_el[1] & 0xf) + 1;
142
+ sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
143
+ if (!sve && size == sve_size) {
144
+ sve = (struct target_sve_context *)ctx;
145
+ break;
146
+ }
147
+ }
148
+ err = true;
149
+ goto exit;
150
+
151
case TARGET_EXTRA_MAGIC:
152
if (extra || size != sizeof(struct target_extra_context)) {
153
err = true;
154
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
155
err = true;
156
}
157
158
+ /* SVE data, if present, overwrites FPSIMD data. */
159
+ if (sve) {
160
+ target_restore_sve_record(env, sve, vq);
161
+ }
162
+
163
exit:
164
unlock_user(extra, extra_datap, 0);
165
return err;
166
}
38
}
167
39
168
-static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
40
+static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
169
+static abi_ulong get_sigframe(struct target_sigaction *ka,
170
+ CPUARMState *env, int size)
171
{
172
abi_ulong sp;
173
174
@@ -XXX,XX +XXX,XX @@ static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
175
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
176
}
177
178
- sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
179
+ sp = (sp - size) & ~15;
180
181
return sp;
182
}
183
184
+typedef struct {
185
+ int total_size;
186
+ int extra_base;
187
+ int extra_size;
188
+ int std_end_ofs;
189
+ int extra_ofs;
190
+ int extra_end_ofs;
191
+} target_sigframe_layout;
192
+
193
+static int alloc_sigframe_space(int this_size, target_sigframe_layout *l)
194
+{
41
+{
195
+ /* Make sure there will always be space for the end marker. */
42
+ /* Return true if CPU supports double precision floating point, VFPv3 */
196
+ const int std_size = sizeof(struct target_rt_sigframe)
43
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
197
+ - sizeof(struct target_aarch64_ctx);
198
+ int this_loc = l->total_size;
199
+
200
+ if (l->extra_base) {
201
+ /* Once we have begun an extra space, all allocations go there. */
202
+ l->extra_size += this_size;
203
+ } else if (this_size + this_loc > std_size) {
204
+ /* This allocation does not fit in the standard space. */
205
+ /* Allocate the extra record. */
206
+ l->extra_ofs = this_loc;
207
+ l->total_size += sizeof(struct target_extra_context);
208
+
209
+ /* Allocate the standard end record. */
210
+ l->std_end_ofs = l->total_size;
211
+ l->total_size += sizeof(struct target_aarch64_ctx);
212
+
213
+ /* Allocate the requested record. */
214
+ l->extra_base = this_loc = l->total_size;
215
+ l->extra_size = this_size;
216
+ }
217
+ l->total_size += this_size;
218
+
219
+ return this_loc;
220
+}
44
+}
221
+
45
+
222
static void target_setup_frame(int usig, struct target_sigaction *ka,
46
/*
223
target_siginfo_t *info, target_sigset_t *set,
47
* We always set the FP and SIMD FP16 fields to indicate identical
224
CPUARMState *env)
48
* levels of support (assuming SIMD is implemented at all), so
225
{
226
- int size = offsetof(struct target_rt_sigframe, uc.tuc_mcontext.__reserved);
227
- int fpsimd_ofs, end1_ofs, fr_ofs, end2_ofs = 0;
228
- int extra_ofs = 0, extra_base = 0, extra_size = 0;
229
+ target_sigframe_layout layout = {
230
+ /* Begin with the size pointing to the reserved space. */
231
+ .total_size = offsetof(struct target_rt_sigframe,
232
+ uc.tuc_mcontext.__reserved),
233
+ };
234
+ int fpsimd_ofs, fr_ofs, sve_ofs = 0, vq = 0, sve_size = 0;
235
struct target_rt_sigframe *frame;
236
struct target_rt_frame_record *fr;
237
abi_ulong frame_addr, return_addr;
238
239
- fpsimd_ofs = size;
240
- size += sizeof(struct target_fpsimd_context);
241
- end1_ofs = size;
242
- size += sizeof(struct target_aarch64_ctx);
243
- fr_ofs = size;
244
- size += sizeof(struct target_rt_frame_record);
245
+ /* FPSIMD record is always in the standard space. */
246
+ fpsimd_ofs = alloc_sigframe_space(sizeof(struct target_fpsimd_context),
247
+ &layout);
248
249
- frame_addr = get_sigframe(ka, env);
250
+ /* SVE state needs saving only if it exists. */
251
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
252
+ vq = (env->vfp.zcr_el[1] & 0xf) + 1;
253
+ sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
254
+ sve_ofs = alloc_sigframe_space(sve_size, &layout);
255
+ }
256
+
257
+ if (layout.extra_ofs) {
258
+ /* Reserve space for the extra end marker. The standard end marker
259
+ * will have been allocated when we allocated the extra record.
260
+ */
261
+ layout.extra_end_ofs
262
+ = alloc_sigframe_space(sizeof(struct target_aarch64_ctx), &layout);
263
+ } else {
264
+ /* Reserve space for the standard end marker.
265
+ * Do not use alloc_sigframe_space because we cheat
266
+ * std_size therein to reserve space for this.
267
+ */
268
+ layout.std_end_ofs = layout.total_size;
269
+ layout.total_size += sizeof(struct target_aarch64_ctx);
270
+ }
271
+
272
+ /* Reserve space for the return code. On a real system this would
273
+ * be within the VDSO. So, despite the name this is not a "real"
274
+ * record within the frame.
275
+ */
276
+ fr_ofs = layout.total_size;
277
+ layout.total_size += sizeof(struct target_rt_frame_record);
278
+
279
+ frame_addr = get_sigframe(ka, env, layout.total_size);
280
trace_user_setup_frame(env, frame_addr);
281
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
282
goto give_sigsegv;
283
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
284
285
target_setup_general_frame(frame, env, set);
286
target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
287
- if (extra_ofs) {
288
- target_setup_extra_record((void *)frame + extra_ofs,
289
- frame_addr + extra_base, extra_size);
290
+ target_setup_end_record((void *)frame + layout.std_end_ofs);
291
+ if (layout.extra_ofs) {
292
+ target_setup_extra_record((void *)frame + layout.extra_ofs,
293
+ frame_addr + layout.extra_base,
294
+ layout.extra_size);
295
+ target_setup_end_record((void *)frame + layout.extra_end_ofs);
296
}
297
- target_setup_end_record((void *)frame + end1_ofs);
298
- if (end2_ofs) {
299
- target_setup_end_record((void *)frame + end2_ofs);
300
+ if (sve_ofs) {
301
+ target_setup_sve_record((void *)frame + sve_ofs, env, vq, sve_size);
302
}
303
304
/* Set up the stack frame for unwinding. */
305
--
49
--
306
2.16.2
50
2.20.1
307
51
308
52
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Shuffle the order of the checks so that we test the ISA
4
before we test anything else, such as the register arguments.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214181547.21408-9-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-vfp.inc.c | 144 ++++++++++++++++-----------------
12
1 file changed, 72 insertions(+), 72 deletions(-)
13
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-vfp.inc.c
17
+++ b/target/arm/translate-vfp.inc.c
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
19
return false;
20
}
21
22
- /* UNDEF accesses to D16-D31 if they don't exist */
23
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
24
- ((a->vm | a->vn | a->vd) & 0x10)) {
25
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
26
return false;
27
}
28
29
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
30
+ /* UNDEF accesses to D16-D31 if they don't exist */
31
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
32
+ ((a->vm | a->vn | a->vd) & 0x10)) {
33
return false;
34
}
35
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
37
return false;
38
}
39
40
- /* UNDEF accesses to D16-D31 if they don't exist */
41
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
42
- ((a->vm | a->vn | a->vd) & 0x10)) {
43
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
44
return false;
45
}
46
47
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
50
+ ((a->vm | a->vn | a->vd) & 0x10)) {
51
return false;
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
55
return false;
56
}
57
58
- /* UNDEF accesses to D16-D31 if they don't exist */
59
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
60
- ((a->vm | a->vd) & 0x10)) {
61
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
62
return false;
63
}
64
65
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
66
+ /* UNDEF accesses to D16-D31 if they don't exist */
67
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
68
+ ((a->vm | a->vd) & 0x10)) {
69
return false;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
73
return false;
74
}
75
76
- /* UNDEF accesses to D16-D31 if they don't exist */
77
- if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
78
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
79
return false;
80
}
81
82
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
83
+ /* UNDEF accesses to D16-D31 if they don't exist */
84
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
85
return false;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
89
TCGv_i64 f0, f1, fd;
90
TCGv_ptr fpst;
91
92
- /* UNDEF accesses to D16-D31 if they don't exist */
93
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
94
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
95
return false;
96
}
97
98
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
99
+ /* UNDEF accesses to D16-D31 if they don't exist */
100
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
101
return false;
102
}
103
104
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
105
int veclen = s->vec_len;
106
TCGv_i64 f0, fd;
107
108
- /* UNDEF accesses to D16-D31 if they don't exist */
109
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
110
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
111
return false;
112
}
113
114
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
115
+ /* UNDEF accesses to D16-D31 if they don't exist */
116
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
117
return false;
118
}
119
120
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
121
return false;
122
}
123
124
- /* UNDEF accesses to D16-D31 if they don't exist. */
125
- if (!dc_isar_feature(aa32_simd_r32, s) &&
126
- ((a->vd | a->vn | a->vm) & 0x10)) {
127
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
128
return false;
129
}
130
131
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
132
+ /* UNDEF accesses to D16-D31 if they don't exist. */
133
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
134
+ ((a->vd | a->vn | a->vm) & 0x10)) {
135
return false;
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
139
140
vd = a->vd;
141
142
- /* UNDEF accesses to D16-D31 if they don't exist. */
143
- if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
144
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
145
return false;
146
}
147
148
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
149
+ /* UNDEF accesses to D16-D31 if they don't exist. */
150
+ if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
151
return false;
152
}
153
154
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
155
{
156
TCGv_i64 vd, vm;
157
158
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
159
+ return false;
160
+ }
161
+
162
/* Vm/M bits must be zero for the Z variant */
163
if (a->z && a->vm != 0) {
164
return false;
165
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
166
return false;
167
}
168
169
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
170
- return false;
171
- }
172
-
173
if (!vfp_access_check(s)) {
174
return true;
175
}
176
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
177
TCGv_i32 tmp;
178
TCGv_i64 vd;
179
180
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
181
+ return false;
182
+ }
183
+
184
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
185
return false;
186
}
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
188
return false;
189
}
190
191
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
192
- return false;
193
- }
194
-
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
199
TCGv_i32 tmp;
200
TCGv_i64 vm;
201
202
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
203
+ return false;
204
+ }
205
+
206
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
207
return false;
208
}
209
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
210
return false;
211
}
212
213
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
214
- return false;
215
- }
216
-
217
if (!vfp_access_check(s)) {
218
return true;
219
}
220
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
221
TCGv_ptr fpst;
222
TCGv_i64 tmp;
223
224
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
225
+ return false;
226
+ }
227
+
228
if (!dc_isar_feature(aa32_vrint, s)) {
229
return false;
230
}
231
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
232
return false;
233
}
234
235
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
236
- return false;
237
- }
238
-
239
if (!vfp_access_check(s)) {
240
return true;
241
}
242
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
243
TCGv_i64 tmp;
244
TCGv_i32 tcg_rmode;
245
246
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
247
+ return false;
248
+ }
249
+
250
if (!dc_isar_feature(aa32_vrint, s)) {
251
return false;
252
}
253
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
254
return false;
255
}
256
257
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
258
- return false;
259
- }
260
-
261
if (!vfp_access_check(s)) {
262
return true;
263
}
264
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
265
TCGv_ptr fpst;
266
TCGv_i64 tmp;
267
268
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
269
+ return false;
270
+ }
271
+
272
if (!dc_isar_feature(aa32_vrint, s)) {
273
return false;
274
}
275
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
276
return false;
277
}
278
279
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
280
- return false;
281
- }
282
-
283
if (!vfp_access_check(s)) {
284
return true;
285
}
286
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
287
TCGv_i64 vd;
288
TCGv_i32 vm;
289
290
- /* UNDEF accesses to D16-D31 if they don't exist. */
291
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
292
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
293
return false;
294
}
295
296
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
297
+ /* UNDEF accesses to D16-D31 if they don't exist. */
298
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
299
return false;
300
}
301
302
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
303
TCGv_i64 vm;
304
TCGv_i32 vd;
305
306
- /* UNDEF accesses to D16-D31 if they don't exist. */
307
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
308
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
309
return false;
310
}
311
312
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
313
+ /* UNDEF accesses to D16-D31 if they don't exist. */
314
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
315
return false;
316
}
317
318
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
319
TCGv_i64 vd;
320
TCGv_ptr fpst;
321
322
- /* UNDEF accesses to D16-D31 if they don't exist. */
323
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
324
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
325
return false;
326
}
327
328
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
329
+ /* UNDEF accesses to D16-D31 if they don't exist. */
330
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
331
return false;
332
}
333
334
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
335
TCGv_i32 vd;
336
TCGv_i64 vm;
337
338
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
339
+ return false;
340
+ }
341
+
342
if (!dc_isar_feature(aa32_jscvt, s)) {
343
return false;
344
}
345
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
346
return false;
347
}
348
349
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
350
- return false;
351
- }
352
-
353
if (!vfp_access_check(s)) {
354
return true;
355
}
356
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
357
TCGv_ptr fpst;
358
int frac_bits;
359
360
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
361
+ return false;
362
+ }
363
+
364
if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
365
return false;
366
}
367
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
368
return false;
369
}
370
371
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
372
- return false;
373
- }
374
-
375
if (!vfp_access_check(s)) {
376
return true;
377
}
378
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
379
TCGv_i64 vm;
380
TCGv_ptr fpst;
381
382
- /* UNDEF accesses to D16-D31 if they don't exist. */
383
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
384
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
385
return false;
386
}
387
388
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
389
+ /* UNDEF accesses to D16-D31 if they don't exist. */
390
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
391
return false;
392
}
393
394
--
395
2.20.1
396
397
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
From the "Physical Layer Simplified Specification Version 3.01":
3
Sort this check to the start of a trans_* function.
4
Merge this with any existing test for fpdp_v2.
4
5
5
A known data block ("Tuning block") can be used to tune sampling
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
point for tuning required hosts. [...]
7
Message-id: 20200214181547.21408-10-richard.henderson@linaro.org
7
This procedure gives the system optimal timing for each specific
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
host and card combination and compensates for static delays in
9
the timing budget including process, voltage and different PCB
10
loads and skews. [...]
11
Data block, carried by DAT[3:0], contains a pattern for tuning
12
sampling position to receive data on the CMD and DAT[3:0] line.
13
14
[based on a patch from Alistair Francis <alistair.francis@xilinx.com>
15
from qemu/xilinx tag xilinx-v2015.2]
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
18
Message-id: 20180309153654.13518-5-f4bug@amsat.org
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
hw/sd/sd.c | 29 +++++++++++++++++++++++++++++
11
target/arm/translate-vfp.inc.c | 24 ++++++++----------------
22
1 file changed, 29 insertions(+)
12
1 file changed, 8 insertions(+), 16 deletions(-)
23
13
24
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/sd/sd.c
16
--- a/target/arm/translate-vfp.inc.c
27
+++ b/hw/sd/sd.c
17
+++ b/target/arm/translate-vfp.inc.c
28
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
19
* VFPv2 allows access to FPSID from userspace; VFPv3 restricts
20
* all ID registers to privileged access only.
21
*/
22
- if (IS_USER(s) && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
23
+ if (IS_USER(s) && dc_isar_feature(aa32_fpsp_v3, s)) {
24
return false;
25
}
26
ignore_vfp_enabled = true;
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
28
case ARM_VFP_FPINST:
29
case ARM_VFP_FPINST2:
30
/* Not present in VFPv3 */
31
- if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
32
+ if (IS_USER(s) || dc_isar_feature(aa32_fpsp_v3, s)) {
33
return false;
29
}
34
}
30
break;
35
break;
31
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
32
+ case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
37
33
+ if (sd->state == sd_transfer_state) {
38
vd = a->vd;
34
+ sd->state = sd_sendingdata_state;
39
35
+ sd->data_offset = 0;
40
- if (!dc_isar_feature(aa32_fpshvec, s) &&
36
+ return sd_r1;
41
- (veclen != 0 || s->vec_stride != 0)) {
37
+ }
42
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
38
+ break;
43
return false;
39
+
40
case 23: /* CMD23: SET_BLOCK_COUNT */
41
switch (sd->state) {
42
case sd_transfer_state:
43
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
44
}
44
}
45
}
45
46
46
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
47
+#define SD_TUNING_BLOCK_SIZE 64
47
+ if (!dc_isar_feature(aa32_fpshvec, s) &&
48
+
48
+ (veclen != 0 || s->vec_stride != 0)) {
49
+static const uint8_t sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
49
return false;
50
+ /* See: Physical Layer Simplified Specification Version 3.01, Table 4-2 */
50
}
51
+ 0xff, 0x0f, 0xff, 0x00, 0x0f, 0xfc, 0xc3, 0xcc,
51
52
+ 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
53
+ 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
53
54
+ 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
54
vd = a->vd;
55
+ 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
55
56
+ 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
56
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
57
+ 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
57
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
58
+ 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
58
return false;
59
+};
59
}
60
+
60
61
uint8_t sd_read_data(SDState *sd)
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
62
{
62
return false;
63
/* TODO: Append CRCs */
63
}
64
@@ -XXX,XX +XXX,XX @@ uint8_t sd_read_data(SDState *sd)
64
65
}
65
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
66
break;
66
- return false;
67
67
- }
68
+ case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
68
-
69
+ if (sd->data_offset >= SD_TUNING_BLOCK_SIZE - 1) {
69
if (!vfp_access_check(s)) {
70
+ sd->state = sd_transfer_state;
70
return true;
71
+ }
71
}
72
+ ret = sd_tuning_block_pattern[sd->data_offset++];
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
73
+ break;
73
TCGv_ptr fpst;
74
+
74
int frac_bits;
75
case 22:    /* ACMD22: SEND_NUM_WR_BLOCKS */
75
76
ret = sd->data[sd->data_offset ++];
76
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
77
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
78
return false;
79
}
80
81
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
82
TCGv_ptr fpst;
83
int frac_bits;
84
85
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
86
- return false;
87
- }
88
-
89
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
90
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
91
return false;
92
}
77
93
78
--
94
--
79
2.16.2
95
2.20.1
80
96
81
97
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
We will eventually remove the early ARM_FEATURE_VFP test,
4
so add a proper test for each trans_* that does not already
5
have another ISA test.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200214181547.21408-11-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-vfp.inc.c | 78 ++++++++++++++++++++++++++++++----
13
1 file changed, 69 insertions(+), 9 deletions(-)
14
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/translate-vfp.inc.c
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
20
int pass;
21
uint32_t offset;
22
23
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
24
+ if (a->size == 2
25
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
26
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
27
+ return false;
28
+ }
29
+
30
/* UNDEF accesses to D16-D31 if they don't exist */
31
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
32
return false;
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
34
pass = extract32(offset, 2, 1);
35
offset = extract32(offset, 0, 2) * 8;
36
37
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
38
- return false;
39
- }
40
-
41
if (!vfp_access_check(s)) {
42
return true;
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
45
int pass;
46
uint32_t offset;
47
48
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
49
+ if (a->size == 2
50
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
51
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
52
+ return false;
53
+ }
54
+
55
/* UNDEF accesses to D16-D31 if they don't exist */
56
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
57
return false;
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
59
pass = extract32(offset, 2, 1);
60
offset = extract32(offset, 0, 2) * 8;
61
62
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
63
- return false;
64
- }
65
-
66
if (!vfp_access_check(s)) {
67
return true;
68
}
69
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
70
TCGv_i32 tmp;
71
bool ignore_vfp_enabled = false;
72
73
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
74
+ return false;
75
+ }
76
+
77
if (arm_dc_feature(s, ARM_FEATURE_M)) {
78
/*
79
* The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
81
{
82
TCGv_i32 tmp;
83
84
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
85
+ return false;
86
+ }
87
+
88
if (!vfp_access_check(s)) {
89
return true;
90
}
91
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
92
{
93
TCGv_i32 tmp;
94
95
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
96
+ return false;
97
+ }
98
+
99
/*
100
* VMOV between two general-purpose registers and two single precision
101
* floating point registers
102
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
103
104
/*
105
* VMOV between two general-purpose registers and one double precision
106
- * floating point register
107
+ * floating point register. Note that this does not require support
108
+ * for double precision arithmetic.
109
*/
110
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
111
+ return false;
112
+ }
113
114
/* UNDEF accesses to D16-D31 if they don't exist */
115
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
116
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
117
uint32_t offset;
118
TCGv_i32 addr, tmp;
119
120
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
121
+ return false;
122
+ }
123
+
124
if (!vfp_access_check(s)) {
125
return true;
126
}
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
128
TCGv_i32 addr;
129
TCGv_i64 tmp;
130
131
+ /* Note that this does not require support for double arithmetic. */
132
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
133
+ return false;
134
+ }
135
+
136
/* UNDEF accesses to D16-D31 if they don't exist */
137
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
138
return false;
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
140
TCGv_i32 addr, tmp;
141
int i, n;
142
143
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
144
+ return false;
145
+ }
146
+
147
n = a->imm;
148
149
if (n == 0 || (a->vd + n) > 32) {
150
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
151
TCGv_i64 tmp;
152
int i, n;
153
154
+ /* Note that this does not require support for double arithmetic. */
155
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
156
+ return false;
157
+ }
158
+
159
n = a->imm >> 1;
160
161
if (n == 0 || (a->vd + n) > 32 || n > 16) {
162
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
163
TCGv_i32 f0, f1, fd;
164
TCGv_ptr fpst;
165
166
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
167
+ return false;
168
+ }
169
+
170
if (!dc_isar_feature(aa32_fpshvec, s) &&
171
(veclen != 0 || s->vec_stride != 0)) {
172
return false;
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
174
int veclen = s->vec_len;
175
TCGv_i32 f0, fd;
176
177
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
178
+ return false;
179
+ }
180
+
181
if (!dc_isar_feature(aa32_fpshvec, s) &&
182
(veclen != 0 || s->vec_stride != 0)) {
183
return false;
184
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
185
{
186
TCGv_i32 vd, vm;
187
188
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
189
+ return false;
190
+ }
191
+
192
/* Vm/M bits must be zero for the Z variant */
193
if (a->z && a->vm != 0) {
194
return false;
195
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
196
TCGv_i32 vm;
197
TCGv_ptr fpst;
198
199
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
200
+ return false;
201
+ }
202
+
203
if (!vfp_access_check(s)) {
204
return true;
205
}
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
207
TCGv_i32 vm;
208
TCGv_ptr fpst;
209
210
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
211
+ return false;
212
+ }
213
+
214
if (!vfp_access_check(s)) {
215
return true;
216
}
217
--
218
2.20.1
219
220
diff view generated by jsdifflib