1
Probably the last arm pullreq before softfreeze...
1
Hi; here's an arm pullreq. The big bits here are Fabiano's
2
CONFIG_TCG=n patches and my set that deprecate -singlestep;
3
other than that there's a collection of smaller bugfixes.
2
4
3
The following changes since commit 58560ad254fbda71d4daa6622d71683190070ee2:
5
thanks
6
-- PMM
4
7
5
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.2-20191024' into staging (2019-10-24 16:22:58 +0100)
8
The following changes since commit 7c18f2d663521f1b31b821a13358ce38075eaf7d:
9
10
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2023-04-29 23:07:17 +0100)
6
11
7
are available in the Git repository at:
12
are available in the Git repository at:
8
13
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191024
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230502-1
10
15
11
for you to fetch changes up to a01a4a3e85ae8f6fe21adbedc80f7013faabdcf4:
16
for you to fetch changes up to 0ab99e4252f21550f2c16f859cbcdd3cced9f8bf:
12
17
13
hw/arm/highbank: Use AddressSpace when using write_secondary_boot() (2019-10-24 17:16:30 +0100)
18
hw/net/allwinner-sun8i-emac: Correctly byteswap descriptor fields (2023-05-02 13:10:42 +0100)
14
19
15
----------------------------------------------------------------
20
----------------------------------------------------------------
16
target-arm queue:
21
* Support building Arm targets with CONFIG_TCG=no (ie KVM only)
17
* raspi boards: some cleanup
22
* hw/net: npcm7xx_emc: set MAC in register space
18
* raspi: implement the bcm2835 system timer device
23
* hw/arm/bcm2835_property: Implement "get command line" message
19
* raspi: implement a dummy thermal sensor
24
* Deprecate the '-singlestep' command line option in favour of
20
* KVM: support providing SVE to the guest
25
'-one-insn-per-tb' and '-accel one-insn-per-tb=on'
21
* misc devices: switch to ptimer transaction API
26
* Deprecate 'singlestep' member of QMP StatusInfo struct
22
* cache TB flag state to improve performance of cpu_get_tb_cpu_state
27
* docs/about/deprecated.rst: Add "since 7.1" tag to dtb-kaslr-seed deprecation
23
* aspeed: Add an AST2600 eval board
28
* hw/net/msf2-emac: Don't modify descriptor in-place in emac_store_desc()
29
* raspi, aspeed: Write bootloader code correctly on big-endian hosts
30
* hw/intc/allwinner-a10-pic: Fix bug on big-endian hosts
31
* Fix bug in A32 ERET on big-endian hosts that caused guest crash
32
* hw/sd/allwinner-sdhost: Correctly byteswap descriptor fields
33
* hw/net/allwinner-sun8i-emac: Correctly byteswap descriptor fields
24
34
25
----------------------------------------------------------------
35
----------------------------------------------------------------
26
Andrew Jones (9):
36
Claudio Fontana (1):
27
target/arm/monitor: Introduce qmp_query_cpu_model_expansion
37
target/arm: move cpu_tcg to tcg/cpu32.c
28
tests: arm: Introduce cpu feature tests
29
target/arm: Allow SVE to be disabled via a CPU property
30
target/arm/cpu64: max cpu: Introduce sve<N> properties
31
target/arm/kvm64: Add kvm_arch_get/put_sve
32
target/arm/kvm64: max cpu: Enable SVE when available
33
target/arm/kvm: scratch vcpu: Preserve input kvm_vcpu_init features
34
target/arm/cpu64: max cpu: Support sve properties with KVM
35
target/arm/kvm: host cpu: Add support for sve<N> properties
36
38
37
Cédric Le Goater (2):
39
Cédric Le Goater (2):
38
hw/gpio: Fix property accessors of the AST2600 GPIO 1.8V model
40
hw/arm/boot: Make write_bootloader() public as arm_write_bootloader()
39
aspeed: Add an AST2600 eval board
41
hw/arm/aspeed: Use arm_write_bootloader() to write the bootloader
40
42
41
Peter Maydell (8):
43
Daniel Bertalan (1):
42
hw/net/fsl_etsec/etsec.c: Switch to transaction-based ptimer API
44
hw/arm/bcm2835_property: Implement "get command line" message
43
hw/timer/xilinx_timer.c: Switch to transaction-based ptimer API
44
hw/dma/xilinx_axidma.c: Switch to transaction-based ptimer API
45
hw/timer/slavio_timer: Remove useless check for NULL t->timer
46
hw/timer/slavio_timer.c: Switch to transaction-based ptimer API
47
hw/timer/grlib_gptimer.c: Switch to transaction-based ptimer API
48
hw/m68k/mcf5206.c: Switch to transaction-based ptimer API
49
hw/watchdog/milkymist-sysctl.c: Switch to transaction-based ptimer API
50
45
51
Philippe Mathieu-Daudé (8):
46
Fabiano Rosas (11):
52
hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor
47
target/arm: Move cortex sysregs into a separate file
53
hw/arm/bcm2835_peripherals: Use the thermal sensor block
48
target/arm: Remove dead code from cpu_max_set_sve_max_vq
54
hw/timer/bcm2835: Add the BCM2835 SYS_timer
49
target/arm: Extract TCG -cpu max code into a function
55
hw/arm/bcm2835_peripherals: Use the SYS_timer
50
target/arm: Do not expose all -cpu max features to qtests
56
hw/arm/bcm2836: Make the SoC code modular
51
target/arm: Move 64-bit TCG CPUs into tcg/
57
hw/arm/bcm2836: Rename cpus[] as cpu[].core
52
tests/qtest: Adjust and document query-cpu-model-expansion test for arm
58
hw/arm/raspi: Use AddressSpace when using arm_boot::write_secondary_boot
53
tests/qtest: Fix tests when no KVM or TCG are present
59
hw/arm/highbank: Use AddressSpace when using write_secondary_boot()
54
tests/avocado: Pass parameters to migration test
55
arm/Kconfig: Always select SEMIHOSTING when TCG is present
56
arm/Kconfig: Do not build TCG-only boards on a KVM-only build
57
tests/qtest: Restrict tpm-tis-i2c-test to CONFIG_TCG
60
58
61
Richard Henderson (24):
59
Patrick Venture (1):
62
target/arm: Split out rebuild_hflags_common
60
hw/net: npcm7xx_emc: set MAC in register space
63
target/arm: Split out rebuild_hflags_a64
64
target/arm: Split out rebuild_hflags_common_32
65
target/arm: Split arm_cpu_data_is_big_endian
66
target/arm: Split out rebuild_hflags_m32
67
target/arm: Reduce tests vs M-profile in cpu_get_tb_cpu_state
68
target/arm: Split out rebuild_hflags_a32
69
target/arm: Split out rebuild_hflags_aprofile
70
target/arm: Hoist XSCALE_CPAR, VECLEN, VECSTRIDE in cpu_get_tb_cpu_state
71
target/arm: Simplify set of PSTATE_SS in cpu_get_tb_cpu_state
72
target/arm: Hoist computation of TBFLAG_A32.VFPEN
73
target/arm: Add arm_rebuild_hflags
74
target/arm: Split out arm_mmu_idx_el
75
target/arm: Hoist store to cs_base in cpu_get_tb_cpu_state
76
target/arm: Add HELPER(rebuild_hflags_{a32, a64, m32})
77
target/arm: Rebuild hflags at EL changes
78
target/arm: Rebuild hflags at MSR writes
79
target/arm: Rebuild hflags at CPSR writes
80
target/arm: Rebuild hflags at Xscale SCTLR writes
81
target/arm: Rebuild hflags for M-profile
82
target/arm: Rebuild hflags for M-profile NVIC
83
linux-user/aarch64: Rebuild hflags for TARGET_WORDS_BIGENDIAN
84
linux-user/arm: Rebuild hflags for TARGET_WORDS_BIGENDIAN
85
target/arm: Rely on hflags correct in cpu_get_tb_cpu_state
86
61
87
hw/misc/Makefile.objs | 1 +
62
Peter Maydell (18):
88
hw/timer/Makefile.objs | 1 +
63
make one-insn-per-tb an accel option
89
tests/Makefile.include | 5 +-
64
softmmu: Don't use 'singlestep' global in QMP and HMP commands
90
qapi/machine-target.json | 6 +-
65
accel/tcg: Use one_insn_per_tb global instead of old singlestep global
91
hw/net/fsl_etsec/etsec.h | 1 -
66
linux-user: Add '-one-insn-per-tb' option equivalent to '-singlestep'
92
include/hw/arm/aspeed.h | 1 +
67
bsd-user: Add '-one-insn-per-tb' option equivalent to '-singlestep'
93
include/hw/arm/bcm2835_peripherals.h | 5 +-
68
Document that -singlestep command line option is deprecated
94
include/hw/arm/bcm2836.h | 4 +-
69
accel/tcg: Report one-insn-per-tb in 'info jit', not 'info status'
95
include/hw/arm/raspi_platform.h | 1 +
70
hmp: Add 'one-insn-per-tb' command equivalent to 'singlestep'
96
include/hw/misc/bcm2835_thermal.h | 27 ++
71
qapi/run-state.json: Fix missing newline at end of file
97
include/hw/timer/bcm2835_systmr.h | 33 +++
72
qmp: Deprecate 'singlestep' member of StatusInfo
98
include/qemu/bitops.h | 1 +
73
docs/about/deprecated.rst: Add "since 7.1" tag to dtb-kaslr-seed deprecation
99
target/arm/cpu.h | 105 +++++--
74
hw/net/msf2-emac: Don't modify descriptor in-place in emac_store_desc()
100
target/arm/helper.h | 4 +
75
hw/arm/raspi: Use arm_write_bootloader() to write boot code
101
target/arm/internals.h | 9 +
76
hw/intc/allwinner-a10-pic: Don't use set_bit()/clear_bit()
102
target/arm/kvm_arm.h | 39 +++
77
target/arm: Define and use new load_cpu_field_low32()
103
hw/arm/aspeed.c | 23 ++
78
target/arm: Add compile time asserts to load/store_cpu_field macros
104
hw/arm/bcm2835_peripherals.c | 30 +-
79
hw/sd/allwinner-sdhost: Correctly byteswap descriptor fields
105
hw/arm/bcm2836.c | 44 +--
80
hw/net/allwinner-sun8i-emac: Correctly byteswap descriptor fields
106
hw/arm/highbank.c | 3 +-
107
hw/arm/raspi.c | 14 +-
108
hw/dma/xilinx_axidma.c | 9 +-
109
hw/gpio/aspeed_gpio.c | 8 +-
110
hw/intc/armv7m_nvic.c | 22 +-
111
hw/m68k/mcf5206.c | 15 +-
112
hw/misc/bcm2835_thermal.c | 135 +++++++++
113
hw/net/fsl_etsec/etsec.c | 9 +-
114
hw/timer/bcm2835_systmr.c | 163 +++++++++++
115
hw/timer/grlib_gptimer.c | 28 +-
116
hw/timer/milkymist-sysctl.c | 25 +-
117
hw/timer/slavio_timer.c | 32 ++-
118
hw/timer/xilinx_timer.c | 13 +-
119
linux-user/aarch64/cpu_loop.c | 1 +
120
linux-user/arm/cpu_loop.c | 1 +
121
linux-user/syscall.c | 1 +
122
target/arm/cpu.c | 26 +-
123
target/arm/cpu64.c | 364 +++++++++++++++++++++--
124
target/arm/helper-a64.c | 3 +
125
target/arm/helper.c | 403 +++++++++++++++++---------
126
target/arm/kvm.c | 25 +-
127
target/arm/kvm32.c | 6 +-
128
target/arm/kvm64.c | 325 ++++++++++++++++++---
129
target/arm/m_helper.c | 6 +
130
target/arm/machine.c | 1 +
131
target/arm/monitor.c | 158 ++++++++++
132
target/arm/op_helper.c | 4 +
133
target/arm/translate-a64.c | 13 +-
134
target/arm/translate.c | 33 ++-
135
tests/arm-cpu-features.c | 540 +++++++++++++++++++++++++++++++++++
136
docs/arm-cpu-features.rst | 317 ++++++++++++++++++++
137
hw/timer/trace-events | 5 +
138
51 files changed, 2725 insertions(+), 323 deletions(-)
139
create mode 100644 include/hw/misc/bcm2835_thermal.h
140
create mode 100644 include/hw/timer/bcm2835_systmr.h
141
create mode 100644 hw/misc/bcm2835_thermal.c
142
create mode 100644 hw/timer/bcm2835_systmr.c
143
create mode 100644 tests/arm-cpu-features.c
144
create mode 100644 docs/arm-cpu-features.rst
145
81
82
Philippe Mathieu-Daudé (1):
83
gitlab-ci: Check building KVM-only aarch64 target
84
85
docs/about/deprecated.rst | 43 +-
86
docs/user/main.rst | 14 +-
87
configs/devices/aarch64-softmmu/default.mak | 4 -
88
configs/devices/arm-softmmu/default.mak | 39 --
89
qapi/run-state.json | 16 +-
90
accel/tcg/internal.h | 2 +
91
include/exec/cpu-common.h | 2 -
92
include/hw/arm/boot.h | 49 ++
93
include/hw/misc/bcm2835_property.h | 1 +
94
include/monitor/hmp.h | 2 +-
95
target/arm/cpregs.h | 6 +
96
target/arm/internals.h | 10 +-
97
target/arm/translate-a32.h | 24 +-
98
accel/tcg/cpu-exec.c | 2 +-
99
accel/tcg/monitor.c | 14 +
100
accel/tcg/tcg-all.c | 23 +
101
bsd-user/main.c | 14 +-
102
hw/arm/aspeed.c | 38 +-
103
hw/arm/bcm2835_peripherals.c | 2 +
104
hw/arm/bcm2836.c | 2 +
105
hw/arm/boot.c | 35 +-
106
hw/arm/raspi.c | 66 +-
107
hw/arm/virt.c | 6 +-
108
hw/intc/allwinner-a10-pic.c | 7 +-
109
hw/misc/bcm2835_property.c | 13 +-
110
hw/net/allwinner-sun8i-emac.c | 22 +-
111
hw/net/msf2-emac.c | 16 +-
112
hw/net/npcm7xx_emc.c | 32 +-
113
hw/sd/allwinner-sdhost.c | 31 +-
114
linux-user/main.c | 18 +-
115
softmmu/globals.c | 1 -
116
softmmu/runstate-hmp-cmds.c | 25 +-
117
softmmu/runstate.c | 10 +-
118
softmmu/vl.c | 17 +-
119
target/arm/cortex-regs.c | 69 ++
120
target/arm/cpu64.c | 702 +-------------------
121
target/arm/{cpu_tcg.c => tcg/cpu32.c} | 72 +-
122
target/arm/tcg/cpu64.c | 723 +++++++++++++++++++++
123
target/arm/tcg/translate.c | 4 +-
124
tests/qtest/arm-cpu-features.c | 20 +-
125
tests/qtest/bios-tables-test.c | 11 +-
126
tests/qtest/boot-serial-test.c | 5 +
127
tests/qtest/migration-test.c | 9 +-
128
tests/qtest/pxe-test.c | 8 +-
129
tests/qtest/test-hmp.c | 1 +
130
tests/qtest/vmgenid-test.c | 9 +-
131
.gitlab-ci.d/crossbuilds.yml | 11 +
132
.../custom-runners/ubuntu-22.04-aarch64.yml | 4 -
133
hmp-commands.hx | 25 +-
134
hw/arm/Kconfig | 43 +-
135
qemu-options.hx | 12 +-
136
target/arm/Kconfig | 7 +
137
target/arm/meson.build | 2 +-
138
target/arm/tcg/meson.build | 2 +
139
tcg/tci/README | 2 +-
140
tests/avocado/migration.py | 83 ++-
141
tests/qtest/meson.build | 3 +-
142
57 files changed, 1449 insertions(+), 984 deletions(-)
143
create mode 100644 target/arm/cortex-regs.c
144
rename target/arm/{cpu_tcg.c => tcg/cpu32.c} (93%)
145
create mode 100644 target/arm/tcg/cpu64.c
146
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The property names of AST2600 GPIO 1.8V model are one character bigger
4
than the names of the other ASPEED GPIO model. Increase the string
5
buffer size by one and be more strict on the expected pattern of the
6
property name.
7
8
This fixes the QOM test of the ast2600-evb machine under :
9
10
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
11
Target: x86_64-apple-darwin17.7.0
12
Thread model: posix
13
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
14
15
Cc: Rashmica Gupta <rashmica.g@gmail.com>
16
Fixes: 36d737ee82b2 ("hw/gpio: Add in AST2600 specific implementation")
17
Signed-off-by: Cédric Le Goater <clg@kaod.org>
18
Message-id: 20191023130455.1347-2-clg@kaod.org
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
hw/gpio/aspeed_gpio.c | 8 ++++----
23
1 file changed, 4 insertions(+), 4 deletions(-)
24
25
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/gpio/aspeed_gpio.c
28
+++ b/hw/gpio/aspeed_gpio.c
29
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_get_pin(Object *obj, Visitor *v, const char *name,
30
{
31
int pin = 0xfff;
32
bool level = true;
33
- char group[3];
34
+ char group[4];
35
AspeedGPIOState *s = ASPEED_GPIO(obj);
36
int set_idx, group_idx = 0;
37
38
if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
39
/* 1.8V gpio */
40
- if (sscanf(name, "gpio%3s%1d", group, &pin) != 2) {
41
+ if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) {
42
error_setg(errp, "%s: error reading %s", __func__, name);
43
return;
44
}
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
46
Error *local_err = NULL;
47
bool level;
48
int pin = 0xfff;
49
- char group[3];
50
+ char group[4];
51
AspeedGPIOState *s = ASPEED_GPIO(obj);
52
int set_idx, group_idx = 0;
53
54
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
55
}
56
if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
57
/* 1.8V gpio */
58
- if (sscanf(name, "gpio%3s%1d", group, &pin) != 2) {
59
+ if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) {
60
error_setg(errp, "%s: error reading %s", __func__, name);
61
return;
62
}
63
--
64
2.20.1
65
66
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Add the 64-bit free running timer. Do not model the COMPARE register
3
The file cpu_tcg.c is about to be moved into the tcg/ directory, so
4
(no IRQ generated).
4
move the register definitions into a new file.
5
This timer is used by Linux kernel and recently U-Boot:
5
6
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clocksource/bcm2835_timer.c?h=v3.7
6
Also move the function declaration to the more appropriate cpregs.h.
7
https://github.com/u-boot/u-boot/blob/v2019.07/include/configs/rpi.h#L19
7
8
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Datasheet used:
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
11
Message-id: 20230426180013.14814-2-farosas@suse.de
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-id: 20191019234715.25750-4-f4bug@amsat.org
15
[PMM: squashed in switch to using memset in reset]
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
13
---
18
hw/timer/Makefile.objs | 1 +
14
target/arm/cpregs.h | 6 ++++
19
include/hw/timer/bcm2835_systmr.h | 33 ++++++
15
target/arm/internals.h | 6 ----
20
hw/timer/bcm2835_systmr.c | 163 ++++++++++++++++++++++++++++++
16
target/arm/cortex-regs.c | 69 ++++++++++++++++++++++++++++++++++++++++
21
hw/timer/trace-events | 5 +
17
target/arm/cpu64.c | 1 +
22
4 files changed, 202 insertions(+)
18
target/arm/cpu_tcg.c | 59 ----------------------------------
23
create mode 100644 include/hw/timer/bcm2835_systmr.h
19
target/arm/meson.build | 1 +
24
create mode 100644 hw/timer/bcm2835_systmr.c
20
6 files changed, 77 insertions(+), 65 deletions(-)
25
21
create mode 100644 target/arm/cortex-regs.c
26
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
22
27
index XXXXXXX..XXXXXXX 100644
23
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
28
--- a/hw/timer/Makefile.objs
24
index XXXXXXX..XXXXXXX 100644
29
+++ b/hw/timer/Makefile.objs
25
--- a/target/arm/cpregs.h
30
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
26
+++ b/target/arm/cpregs.h
31
common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
27
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpreg_in_idspace(const ARMCPRegInfo *ri)
32
common-obj-$(CONFIG_CMSDK_APB_DUALTIMER) += cmsdk-apb-dualtimer.o
28
ri->crn, ri->crm);
33
common-obj-$(CONFIG_MSF2) += mss-timer.o
29
}
34
+common-obj-$(CONFIG_RASPI) += bcm2835_systmr.o
30
35
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
31
+#ifdef CONFIG_USER_ONLY
32
+static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
33
+#else
34
+void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
35
+#endif
36
+
37
#endif /* TARGET_ARM_CPREGS_H */
38
diff --git a/target/arm/internals.h b/target/arm/internals.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/internals.h
41
+++ b/target/arm/internals.h
42
@@ -XXX,XX +XXX,XX @@ uint32_t arm_v7m_mrs_control(CPUARMState *env, uint32_t secure);
43
uint32_t *arm_v7m_get_sp_ptr(CPUARMState *env, bool secure,
44
bool threadmode, bool spsel);
45
46
-#ifdef CONFIG_USER_ONLY
47
-static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
48
-#else
49
-void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
50
-#endif
51
-
52
bool el_is_in_host(CPUARMState *env, int el);
53
54
void aa32_max_features(ARMCPU *cpu);
55
diff --git a/target/arm/cortex-regs.c b/target/arm/cortex-regs.c
36
new file mode 100644
56
new file mode 100644
37
index XXXXXXX..XXXXXXX
57
index XXXXXXX..XXXXXXX
38
--- /dev/null
58
--- /dev/null
39
+++ b/include/hw/timer/bcm2835_systmr.h
59
+++ b/target/arm/cortex-regs.c
40
@@ -XXX,XX +XXX,XX @@
60
@@ -XXX,XX +XXX,XX @@
41
+/*
61
+/*
42
+ * BCM2835 SYS timer emulation
62
+ * ARM Cortex-A registers
43
+ *
63
+ *
44
+ * Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
64
+ * This code is licensed under the GNU GPL v2 or later.
45
+ *
65
+ *
46
+ * SPDX-License-Identifier: GPL-2.0-or-later
66
+ * SPDX-License-Identifier: GPL-2.0-or-later
47
+ */
67
+ */
48
+
68
+
49
+#ifndef BCM2835_SYSTIMER_H
69
+#include "qemu/osdep.h"
50
+#define BCM2835_SYSTIMER_H
70
+#include "cpu.h"
51
+
71
+#include "cpregs.h"
52
+#include "hw/sysbus.h"
72
+
53
+#include "hw/irq.h"
73
+
54
+
74
+static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
55
+#define TYPE_BCM2835_SYSTIMER "bcm2835-sys-timer"
75
+{
56
+#define BCM2835_SYSTIMER(obj) \
76
+ ARMCPU *cpu = env_archcpu(env);
57
+ OBJECT_CHECK(BCM2835SystemTimerState, (obj), TYPE_BCM2835_SYSTIMER)
77
+
58
+
78
+ /* Number of cores is in [25:24]; otherwise we RAZ */
59
+typedef struct {
79
+ return (cpu->core_count - 1) << 24;
60
+ /*< private >*/
80
+}
61
+ SysBusDevice parent_obj;
81
+
62
+
82
+static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
63
+ /*< public >*/
83
+ { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
64
+ MemoryRegion iomem;
84
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
65
+ qemu_irq irq;
85
+ .access = PL1_RW, .readfn = l2ctlr_read,
66
+
86
+ .writefn = arm_cp_write_ignore },
67
+ struct {
87
+ { .name = "L2CTLR",
68
+ uint32_t status;
88
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
69
+ uint32_t compare[4];
89
+ .access = PL1_RW, .readfn = l2ctlr_read,
70
+ } reg;
90
+ .writefn = arm_cp_write_ignore },
71
+} BCM2835SystemTimerState;
91
+ { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
72
+
92
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
73
+#endif
93
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
74
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
94
+ { .name = "L2ECTLR",
75
new file mode 100644
95
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
76
index XXXXXXX..XXXXXXX
96
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
77
--- /dev/null
97
+ { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
78
+++ b/hw/timer/bcm2835_systmr.c
98
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
99
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
100
+ { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
101
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
102
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
103
+ { .name = "CPUACTLR",
104
+ .cp = 15, .opc1 = 0, .crm = 15,
105
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
106
+ { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
107
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
108
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
109
+ { .name = "CPUECTLR",
110
+ .cp = 15, .opc1 = 1, .crm = 15,
111
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
112
+ { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
113
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
114
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
115
+ { .name = "CPUMERRSR",
116
+ .cp = 15, .opc1 = 2, .crm = 15,
117
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
118
+ { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
119
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
120
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
121
+ { .name = "L2MERRSR",
122
+ .cp = 15, .opc1 = 3, .crm = 15,
123
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
124
+};
125
+
126
+void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu)
127
+{
128
+ define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
129
+}
130
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/cpu64.c
133
+++ b/target/arm/cpu64.c
79
@@ -XXX,XX +XXX,XX @@
134
@@ -XXX,XX +XXX,XX @@
80
+/*
135
#include "qapi/visitor.h"
81
+ * BCM2835 SYS timer emulation
136
#include "hw/qdev-properties.h"
82
+ *
137
#include "internals.h"
83
+ * Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
138
+#include "cpregs.h"
84
+ *
139
85
+ * SPDX-License-Identifier: GPL-2.0-or-later
140
static void aarch64_a35_initfn(Object *obj)
86
+ *
141
{
87
+ * Datasheet: BCM2835 ARM Peripherals (C6357-M-1398)
142
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
88
+ * https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
143
index XXXXXXX..XXXXXXX 100644
89
+ *
144
--- a/target/arm/cpu_tcg.c
90
+ * Only the free running 64-bit counter is implemented.
145
+++ b/target/arm/cpu_tcg.c
91
+ * The 4 COMPARE registers and the interruption are not implemented.
146
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
92
+ */
147
cpu->isar.id_dfr0 = t;
93
+
148
}
94
+#include "qemu/osdep.h"
149
95
+#include "qemu/log.h"
150
-#ifndef CONFIG_USER_ONLY
96
+#include "qemu/timer.h"
151
-static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
97
+#include "hw/timer/bcm2835_systmr.h"
152
-{
98
+#include "hw/registerfields.h"
153
- ARMCPU *cpu = env_archcpu(env);
99
+#include "migration/vmstate.h"
154
-
100
+#include "trace.h"
155
- /* Number of cores is in [25:24]; otherwise we RAZ */
101
+
156
- return (cpu->core_count - 1) << 24;
102
+REG32(CTRL_STATUS, 0x00)
157
-}
103
+REG32(COUNTER_LOW, 0x04)
158
-
104
+REG32(COUNTER_HIGH, 0x08)
159
-static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
105
+REG32(COMPARE0, 0x0c)
160
- { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
106
+REG32(COMPARE1, 0x10)
161
- .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
107
+REG32(COMPARE2, 0x14)
162
- .access = PL1_RW, .readfn = l2ctlr_read,
108
+REG32(COMPARE3, 0x18)
163
- .writefn = arm_cp_write_ignore },
109
+
164
- { .name = "L2CTLR",
110
+static void bcm2835_systmr_update_irq(BCM2835SystemTimerState *s)
165
- .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
111
+{
166
- .access = PL1_RW, .readfn = l2ctlr_read,
112
+ bool enable = !!s->reg.status;
167
- .writefn = arm_cp_write_ignore },
113
+
168
- { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
114
+ trace_bcm2835_systmr_irq(enable);
169
- .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
115
+ qemu_set_irq(s->irq, enable);
170
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
116
+}
171
- { .name = "L2ECTLR",
117
+
172
- .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
118
+static void bcm2835_systmr_update_compare(BCM2835SystemTimerState *s,
173
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
119
+ unsigned timer_index)
174
- { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
120
+{
175
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
121
+ /* TODO fow now, since neither Linux nor U-boot use these timers. */
176
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
122
+ qemu_log_mask(LOG_UNIMP, "COMPARE register %u not implemented\n",
177
- { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
123
+ timer_index);
178
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
124
+}
179
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
125
+
180
- { .name = "CPUACTLR",
126
+static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
181
- .cp = 15, .opc1 = 0, .crm = 15,
127
+ unsigned size)
182
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
128
+{
183
- { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
129
+ BCM2835SystemTimerState *s = BCM2835_SYSTIMER(opaque);
184
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
130
+ uint64_t r = 0;
185
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
131
+
186
- { .name = "CPUECTLR",
132
+ switch (offset) {
187
- .cp = 15, .opc1 = 1, .crm = 15,
133
+ case A_CTRL_STATUS:
188
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
134
+ r = s->reg.status;
189
- { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
135
+ break;
190
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
136
+ case A_COMPARE0 ... A_COMPARE3:
191
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
137
+ r = s->reg.compare[(offset - A_COMPARE0) >> 2];
192
- { .name = "CPUMERRSR",
138
+ break;
193
- .cp = 15, .opc1 = 2, .crm = 15,
139
+ case A_COUNTER_LOW:
194
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
140
+ case A_COUNTER_HIGH:
195
- { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
141
+ /* Free running counter at 1MHz */
196
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
142
+ r = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
197
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
143
+ r >>= 8 * (offset - A_COUNTER_LOW);
198
- { .name = "L2MERRSR",
144
+ r &= UINT32_MAX;
199
- .cp = 15, .opc1 = 3, .crm = 15,
145
+ break;
200
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
146
+ default:
201
-};
147
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: bad offset 0x%" HWADDR_PRIx "\n",
202
-
148
+ __func__, offset);
203
-void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu)
149
+ break;
204
-{
150
+ }
205
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
151
+ trace_bcm2835_systmr_read(offset, r);
206
-}
152
+
207
-#endif /* !CONFIG_USER_ONLY */
153
+ return r;
208
-
154
+}
209
/* CPU models. These are not needed for the AArch64 linux-user build. */
155
+
210
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
156
+static void bcm2835_systmr_write(void *opaque, hwaddr offset,
211
157
+ uint64_t value, unsigned size)
212
diff --git a/target/arm/meson.build b/target/arm/meson.build
158
+{
213
index XXXXXXX..XXXXXXX 100644
159
+ BCM2835SystemTimerState *s = BCM2835_SYSTIMER(opaque);
214
--- a/target/arm/meson.build
160
+
215
+++ b/target/arm/meson.build
161
+ trace_bcm2835_systmr_write(offset, value);
216
@@ -XXX,XX +XXX,XX @@ arm_softmmu_ss.add(files(
162
+ switch (offset) {
217
'arch_dump.c',
163
+ case A_CTRL_STATUS:
218
'arm-powerctl.c',
164
+ s->reg.status &= ~value; /* Ack */
219
'arm-qmp-cmds.c',
165
+ bcm2835_systmr_update_irq(s);
220
+ 'cortex-regs.c',
166
+ break;
221
'machine.c',
167
+ case A_COMPARE0 ... A_COMPARE3:
222
'ptw.c',
168
+ s->reg.compare[(offset - A_COMPARE0) >> 2] = value;
223
))
169
+ bcm2835_systmr_update_compare(s, (offset - A_COMPARE0) >> 2);
170
+ break;
171
+ case A_COUNTER_LOW:
172
+ case A_COUNTER_HIGH:
173
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: read-only ofs 0x%" HWADDR_PRIx "\n",
174
+ __func__, offset);
175
+ break;
176
+ default:
177
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: bad offset 0x%" HWADDR_PRIx "\n",
178
+ __func__, offset);
179
+ break;
180
+ }
181
+}
182
+
183
+static const MemoryRegionOps bcm2835_systmr_ops = {
184
+ .read = bcm2835_systmr_read,
185
+ .write = bcm2835_systmr_write,
186
+ .endianness = DEVICE_LITTLE_ENDIAN,
187
+ .impl = {
188
+ .min_access_size = 4,
189
+ .max_access_size = 4,
190
+ },
191
+};
192
+
193
+static void bcm2835_systmr_reset(DeviceState *dev)
194
+{
195
+ BCM2835SystemTimerState *s = BCM2835_SYSTIMER(dev);
196
+
197
+ memset(&s->reg, 0, sizeof(s->reg));
198
+}
199
+
200
+static void bcm2835_systmr_realize(DeviceState *dev, Error **errp)
201
+{
202
+ BCM2835SystemTimerState *s = BCM2835_SYSTIMER(dev);
203
+
204
+ memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_systmr_ops,
205
+ s, "bcm2835-sys-timer", 0x20);
206
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
207
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
208
+}
209
+
210
+static const VMStateDescription bcm2835_systmr_vmstate = {
211
+ .name = "bcm2835_sys_timer",
212
+ .version_id = 1,
213
+ .minimum_version_id = 1,
214
+ .fields = (VMStateField[]) {
215
+ VMSTATE_UINT32(reg.status, BCM2835SystemTimerState),
216
+ VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState, 4),
217
+ VMSTATE_END_OF_LIST()
218
+ }
219
+};
220
+
221
+static void bcm2835_systmr_class_init(ObjectClass *klass, void *data)
222
+{
223
+ DeviceClass *dc = DEVICE_CLASS(klass);
224
+
225
+ dc->realize = bcm2835_systmr_realize;
226
+ dc->reset = bcm2835_systmr_reset;
227
+ dc->vmsd = &bcm2835_systmr_vmstate;
228
+}
229
+
230
+static const TypeInfo bcm2835_systmr_info = {
231
+ .name = TYPE_BCM2835_SYSTIMER,
232
+ .parent = TYPE_SYS_BUS_DEVICE,
233
+ .instance_size = sizeof(BCM2835SystemTimerState),
234
+ .class_init = bcm2835_systmr_class_init,
235
+};
236
+
237
+static void bcm2835_systmr_register_types(void)
238
+{
239
+ type_register_static(&bcm2835_systmr_info);
240
+}
241
+
242
+type_init(bcm2835_systmr_register_types);
243
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
244
index XXXXXXX..XXXXXXX 100644
245
--- a/hw/timer/trace-events
246
+++ b/hw/timer/trace-events
247
@@ -XXX,XX +XXX,XX @@ pl031_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
248
pl031_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
249
pl031_alarm_raised(void) "alarm raised"
250
pl031_set_alarm(uint32_t ticks) "alarm set for %u ticks"
251
+
252
+# bcm2835_systmr.c
253
+bcm2835_systmr_irq(bool enable) "timer irq state %u"
254
+bcm2835_systmr_read(uint64_t offset, uint64_t data) "timer read: offset 0x%" PRIx64 " data 0x%" PRIx64
255
+bcm2835_systmr_write(uint64_t offset, uint64_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx64
256
--
224
--
257
2.20.1
225
2.34.1
258
226
259
227
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Enable SVE in the KVM guest when the 'max' cpu type is configured
3
The sve-max-vq property has been removed from the -cpu max used with
4
and KVM supports it. KVM SVE requires use of the new finalize
4
KVM, so code under kvm_enabled in cpu_max_set_sve_max_vq is not
5
vcpu ioctl, so we add that now too. For starters SVE can only be
5
reachable.
6
turned on or off, getting all vector lengths the host CPU supports
7
when on. We'll add the other SVE CPU properties in later patches.
8
6
9
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Fixes: 0baa21be49 ("target/arm: Make KVM -cpu max exactly like -cpu host")
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Fabiano Rosas <farosas@suse.de>
12
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
11
Message-id: 20230426180013.14814-3-farosas@suse.de
13
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
14
Message-id: 20191024121808.9612-7-drjones@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
13
---
17
target/arm/kvm_arm.h | 27 +++++++++++++++++++++++++++
14
target/arm/cpu64.c | 6 ------
18
target/arm/cpu64.c | 17 ++++++++++++++---
15
1 file changed, 6 deletions(-)
19
target/arm/kvm.c | 5 +++++
20
target/arm/kvm64.c | 20 +++++++++++++++++++-
21
tests/arm-cpu-features.c | 4 ++++
22
5 files changed, 69 insertions(+), 4 deletions(-)
23
16
24
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/kvm_arm.h
27
+++ b/target/arm/kvm_arm.h
28
@@ -XXX,XX +XXX,XX @@
29
*/
30
int kvm_arm_vcpu_init(CPUState *cs);
31
32
+/**
33
+ * kvm_arm_vcpu_finalize
34
+ * @cs: CPUState
35
+ * @feature: int
36
+ *
37
+ * Finalizes the configuration of the specified VCPU feature by
38
+ * invoking the KVM_ARM_VCPU_FINALIZE ioctl. Features requiring
39
+ * this are documented in the "KVM_ARM_VCPU_FINALIZE" section of
40
+ * KVM's API documentation.
41
+ *
42
+ * Returns: 0 if success else < 0 error code
43
+ */
44
+int kvm_arm_vcpu_finalize(CPUState *cs, int feature);
45
+
46
/**
47
* kvm_arm_register_device:
48
* @mr: memory region for this device
49
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_aarch32_supported(CPUState *cs);
50
*/
51
bool kvm_arm_pmu_supported(CPUState *cs);
52
53
+/**
54
+ * bool kvm_arm_sve_supported:
55
+ * @cs: CPUState
56
+ *
57
+ * Returns true if the KVM VCPU can enable SVE and false otherwise.
58
+ */
59
+bool kvm_arm_sve_supported(CPUState *cs);
60
+
61
/**
62
* kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
63
* IPA address space supported by KVM
64
@@ -XXX,XX +XXX,XX @@ static inline bool kvm_arm_pmu_supported(CPUState *cs)
65
return false;
66
}
67
68
+static inline bool kvm_arm_sve_supported(CPUState *cs)
69
+{
70
+ return false;
71
+}
72
+
73
static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
74
{
75
return -ENOENT;
76
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
17
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
77
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/cpu64.c
19
--- a/target/arm/cpu64.c
79
+++ b/target/arm/cpu64.c
20
+++ b/target/arm/cpu64.c
80
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
21
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
81
return;
22
return;
82
}
23
}
83
24
84
+ if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
25
- if (kvm_enabled() && !kvm_arm_sve_supported()) {
85
+ error_setg(errp, "'sve' feature not supported by KVM on this host");
26
- error_setg(errp, "cannot set sve-max-vq");
86
+ return;
27
- error_append_hint(errp, "SVE not supported by KVM on this host\n");
87
+ }
28
- return;
88
+
29
- }
89
t = cpu->isar.id_aa64pfr0;
30
-
90
t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
31
if (max_vq == 0 || max_vq > ARM_MAX_VQ) {
91
cpu->isar.id_aa64pfr0 = t;
32
error_setg(errp, "unsupported SVE vector length");
92
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
33
error_append_hint(errp, "Valid sve-max-vq in range [1-%d]\n",
93
{
94
ARMCPU *cpu = ARM_CPU(obj);
95
uint32_t vq;
96
+ uint64_t t;
97
98
if (kvm_enabled()) {
99
kvm_arm_set_cpu_features_from_host(cpu);
100
+ if (kvm_arm_sve_supported(CPU(cpu))) {
101
+ t = cpu->isar.id_aa64pfr0;
102
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
103
+ cpu->isar.id_aa64pfr0 = t;
104
+ }
105
} else {
106
- uint64_t t;
107
uint32_t u;
108
aarch64_a57_initfn(obj);
109
110
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
111
112
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
113
cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
114
- object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
115
- cpu_arm_set_sve, NULL, NULL, &error_fatal);
116
117
for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
118
char name[8];
119
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
120
cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
121
}
122
}
123
+
124
+ object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
125
+ cpu_arm_set_sve, NULL, NULL, &error_fatal);
126
}
127
128
struct ARMCPUInfo {
129
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/target/arm/kvm.c
132
+++ b/target/arm/kvm.c
133
@@ -XXX,XX +XXX,XX @@ int kvm_arm_vcpu_init(CPUState *cs)
134
return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
135
}
136
137
+int kvm_arm_vcpu_finalize(CPUState *cs, int feature)
138
+{
139
+ return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_FINALIZE, &feature);
140
+}
141
+
142
void kvm_arm_init_serror_injection(CPUState *cs)
143
{
144
cap_has_inject_serror_esr = kvm_check_extension(cs->kvm_state,
145
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/kvm64.c
148
+++ b/target/arm/kvm64.c
149
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_aarch32_supported(CPUState *cpu)
150
return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
151
}
152
153
+bool kvm_arm_sve_supported(CPUState *cpu)
154
+{
155
+ KVMState *s = KVM_STATE(current_machine->accelerator);
156
+
157
+ return kvm_check_extension(s, KVM_CAP_ARM_SVE);
158
+}
159
+
160
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
161
162
int kvm_arch_init_vcpu(CPUState *cs)
163
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
164
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
165
}
166
if (!kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
167
- cpu->has_pmu = false;
168
+ cpu->has_pmu = false;
169
}
170
if (cpu->has_pmu) {
171
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
172
} else {
173
unset_feature(&env->features, ARM_FEATURE_PMU);
174
}
175
+ if (cpu_isar_feature(aa64_sve, cpu)) {
176
+ assert(kvm_arm_sve_supported(cs));
177
+ cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
178
+ }
179
180
/* Do KVM_ARM_VCPU_INIT ioctl */
181
ret = kvm_arm_vcpu_init(cs);
182
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
183
return ret;
184
}
185
186
+ if (cpu_isar_feature(aa64_sve, cpu)) {
187
+ ret = kvm_arm_vcpu_finalize(cs, KVM_ARM_VCPU_SVE);
188
+ if (ret) {
189
+ return ret;
190
+ }
191
+ }
192
+
193
/*
194
* When KVM is in use, PSCI is emulated in-kernel and not by qemu.
195
* Currently KVM has its own idea about MPIDR assignment, so we
196
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/tests/arm-cpu-features.c
199
+++ b/tests/arm-cpu-features.c
200
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
201
assert_has_feature(qts, "host", "aarch64");
202
assert_has_feature(qts, "host", "pmu");
203
204
+ assert_has_feature(qts, "max", "sve");
205
+
206
assert_error(qts, "cortex-a15",
207
"We cannot guarantee the CPU type 'cortex-a15' works "
208
"with KVM on this host", NULL);
209
} else {
210
assert_has_not_feature(qts, "host", "aarch64");
211
assert_has_not_feature(qts, "host", "pmu");
212
+
213
+ assert_has_not_feature(qts, "max", "sve");
214
}
215
216
qtest_quit(qts);
217
--
34
--
218
2.20.1
35
2.34.1
219
36
220
37
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Since 97a28b0eeac14 ("target/arm: Allow VFP and Neon to be disabled via
3
Introduce aarch64_max_tcg_initfn that contains the TCG-only part of
4
a CPU property") we can disable the 'max' cpu model's VFP and neon
4
-cpu max configuration. We'll need that to be able to restrict this
5
features, but there's no way to disable SVE. Add the 'sve=on|off'
5
code to a TCG-only config in the next patches.
6
property to give it that flexibility. We also rename
7
cpu_max_get/set_sve_vq to cpu_max_get/set_sve_max_vq in order for them
8
to follow the typical *_get/set_<property-name> pattern.
9
6
10
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
13
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
10
Message-id: 20230426180013.14814-4-farosas@suse.de
14
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
15
Message-id: 20191024121808.9612-4-drjones@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
12
---
18
target/arm/cpu.c | 3 ++-
13
target/arm/cpu64.c | 32 ++++++++++++++++++--------------
19
target/arm/cpu64.c | 52 ++++++++++++++++++++++++++++++++++------
14
1 file changed, 18 insertions(+), 14 deletions(-)
20
target/arm/monitor.c | 2 +-
21
tests/arm-cpu-features.c | 1 +
22
4 files changed, 49 insertions(+), 9 deletions(-)
23
15
24
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.c
27
+++ b/target/arm/cpu.c
28
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
29
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
30
env->cp15.cptr_el[3] |= CPTR_EZ;
31
/* with maximum vector length */
32
- env->vfp.zcr_el[1] = cpu->sve_max_vq - 1;
33
+ env->vfp.zcr_el[1] = cpu_isar_feature(aa64_sve, cpu) ?
34
+ cpu->sve_max_vq - 1 : 0;
35
env->vfp.zcr_el[2] = env->vfp.zcr_el[1];
36
env->vfp.zcr_el[3] = env->vfp.zcr_el[1];
37
/*
38
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
16
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
39
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/cpu64.c
18
--- a/target/arm/cpu64.c
41
+++ b/target/arm/cpu64.c
19
+++ b/target/arm/cpu64.c
42
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static void aarch64_host_initfn(Object *obj)
43
define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
21
#endif
44
}
22
}
45
23
46
-static void cpu_max_get_sve_vq(Object *obj, Visitor *v, const char *name,
24
-/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
47
- void *opaque, Error **errp)
25
- * otherwise, a CPU with as many features enabled as our emulation supports.
48
+static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
26
- * The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
49
+ void *opaque, Error **errp)
27
+/*
28
+ * -cpu max: a CPU with as many features enabled as our emulation supports.
29
+ * The version of '-cpu max' for qemu-system-arm is defined in cpu_tcg.c;
30
* this only needs to handle 64 bits.
31
*/
32
-static void aarch64_max_initfn(Object *obj)
33
+static void aarch64_max_tcg_initfn(Object *obj)
50
{
34
{
51
ARMCPU *cpu = ARM_CPU(obj);
35
ARMCPU *cpu = ARM_CPU(obj);
52
- visit_type_uint32(v, name, &cpu->sve_max_vq, errp);
36
uint64_t t;
53
+ uint32_t value;
37
uint32_t u;
54
+
38
55
+ /* All vector lengths are disabled when SVE is off. */
39
- if (kvm_enabled() || hvf_enabled()) {
56
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
40
- /* With KVM or HVF, '-cpu max' is identical to '-cpu host' */
57
+ value = 0;
41
- aarch64_host_initfn(obj);
58
+ } else {
42
- return;
59
+ value = cpu->sve_max_vq;
43
- }
60
+ }
44
-
61
+ visit_type_uint32(v, name, &value, errp);
45
- /* '-cpu max' for TCG: we currently do this as "A57 with extra things" */
46
-
47
- aarch64_a57_initfn(obj);
48
-
49
/*
50
* Reset MIDR so the guest doesn't mistake our 'max' CPU type for a real
51
* one and try to apply errata workarounds or use impdef features we
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
53
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
62
}
54
}
63
55
64
-static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
56
+static void aarch64_max_initfn(Object *obj)
65
- void *opaque, Error **errp)
66
+static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
67
+ void *opaque, Error **errp)
68
{
69
ARMCPU *cpu = ARM_CPU(obj);
70
Error *err = NULL;
71
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
72
error_propagate(errp, err);
73
}
74
75
+static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name,
76
+ void *opaque, Error **errp)
77
+{
57
+{
78
+ ARMCPU *cpu = ARM_CPU(obj);
58
+ if (kvm_enabled() || hvf_enabled()) {
79
+ bool value = cpu_isar_feature(aa64_sve, cpu);
59
+ /* With KVM or HVF, '-cpu max' is identical to '-cpu host' */
80
+
60
+ aarch64_host_initfn(obj);
81
+ visit_type_bool(v, name, &value, errp);
82
+}
83
+
84
+static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
85
+ void *opaque, Error **errp)
86
+{
87
+ ARMCPU *cpu = ARM_CPU(obj);
88
+ Error *err = NULL;
89
+ bool value;
90
+ uint64_t t;
91
+
92
+ visit_type_bool(v, name, &value, &err);
93
+ if (err) {
94
+ error_propagate(errp, err);
95
+ return;
61
+ return;
96
+ }
62
+ }
97
+
63
+
98
+ t = cpu->isar.id_aa64pfr0;
64
+ /* '-cpu max' for TCG: we currently do this as "A57 with extra things" */
99
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
65
+
100
+ cpu->isar.id_aa64pfr0 = t;
66
+ aarch64_a57_initfn(obj);
67
+ aarch64_max_tcg_initfn(obj);
101
+}
68
+}
102
+
69
+
103
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
70
static const ARMCPUInfo aarch64_cpus[] = {
104
* otherwise, a CPU with as many features enabled as our emulation supports.
71
{ .name = "cortex-a35", .initfn = aarch64_a35_initfn },
105
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
72
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
106
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
107
#endif
108
109
cpu->sve_max_vq = ARM_MAX_VQ;
110
- object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_vq,
111
- cpu_max_set_sve_vq, NULL, NULL, &error_fatal);
112
+ object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
113
+ cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
114
+ object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
115
+ cpu_arm_set_sve, NULL, NULL, &error_fatal);
116
}
117
}
118
119
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/monitor.c
122
+++ b/target/arm/monitor.c
123
@@ -XXX,XX +XXX,XX @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
124
* then the order that considers those dependencies must be used.
125
*/
126
static const char *cpu_model_advertised_features[] = {
127
- "aarch64", "pmu",
128
+ "aarch64", "pmu", "sve",
129
NULL
130
};
131
132
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/tests/arm-cpu-features.c
135
+++ b/tests/arm-cpu-features.c
136
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
137
138
if (g_str_equal(qtest_get_arch(), "aarch64")) {
139
assert_has_feature(qts, "max", "aarch64");
140
+ assert_has_feature(qts, "max", "sve");
141
assert_has_feature(qts, "cortex-a57", "pmu");
142
assert_has_feature(qts, "cortex-a57", "aarch64");
143
144
--
73
--
145
2.20.1
74
2.34.1
146
75
147
76
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Extend the SVE vq map initialization and validation with KVM's
3
We're about to move the TCG-only -cpu max configuration code under
4
supported vector lengths when KVM is enabled. In order to determine
4
CONFIG_TCG. To be able to do that we need to make sure the qtests
5
and select supported lengths we add two new KVM functions for getting
5
still have some cpu configured even when no other accelerator is
6
and setting the KVM_REG_ARM64_SVE_VLS pseudo-register.
6
available.
7
7
8
This patch has been co-authored with Richard Henderson, who reworked
8
Delineate now what is used with TCG-only and what is also used with
9
the target/arm/cpu64.c changes in order to push all the validation and
9
qtests to make the subsequent patches cleaner.
10
auto-enabling/disabling steps into the finalizer, resulting in a nice
11
LOC reduction.
12
10
13
Signed-off-by: Andrew Jones <drjones@redhat.com>
11
Signed-off-by: Fabiano Rosas <farosas@suse.de>
14
Reviewed-by: Eric Auger <eric.auger@redhat.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Message-id: 20191024121808.9612-9-drjones@redhat.com
14
Message-id: 20230426180013.14814-5-farosas@suse.de
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
16
---
20
target/arm/kvm_arm.h | 12 +++
17
target/arm/cpu64.c | 12 +++++++++---
21
target/arm/cpu64.c | 176 ++++++++++++++++++++++++++++----------
18
1 file changed, 9 insertions(+), 3 deletions(-)
22
target/arm/kvm64.c | 100 +++++++++++++++++++++-
23
tests/arm-cpu-features.c | 106 ++++++++++++++++++++++-
24
docs/arm-cpu-features.rst | 45 +++++++---
25
5 files changed, 381 insertions(+), 58 deletions(-)
26
19
27
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/kvm_arm.h
30
+++ b/target/arm/kvm_arm.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct ARMHostCPUFeatures {
32
*/
33
bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
34
35
+/**
36
+ * kvm_arm_sve_get_vls:
37
+ * @cs: CPUState
38
+ * @map: bitmap to fill in
39
+ *
40
+ * Get all the SVE vector lengths supported by the KVM host, setting
41
+ * the bits corresponding to their length in quadwords minus one
42
+ * (vq - 1) in @map up to ARM_MAX_VQ.
43
+ */
44
+void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map);
45
+
46
/**
47
* kvm_arm_set_cpu_features_from_host:
48
* @cpu: ARMCPU to set the features for
49
@@ -XXX,XX +XXX,XX @@ static inline int kvm_arm_vgic_probe(void)
50
static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) {}
51
static inline void kvm_arm_pmu_init(CPUState *cs) {}
52
53
+static inline void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map) {}
54
#endif
55
56
static inline const char *gic_class_name(void)
57
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
20
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
58
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/cpu64.c
22
--- a/target/arm/cpu64.c
60
+++ b/target/arm/cpu64.c
23
+++ b/target/arm/cpu64.c
61
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
24
@@ -XXX,XX +XXX,XX @@
62
* any of the above. Finally, if SVE is not disabled, then at least one
25
#include "qemu/module.h"
63
* vector length must be enabled.
26
#include "sysemu/kvm.h"
64
*/
27
#include "sysemu/hvf.h"
65
+ DECLARE_BITMAP(kvm_supported, ARM_MAX_VQ);
28
+#include "sysemu/qtest.h"
66
DECLARE_BITMAP(tmp, ARM_MAX_VQ);
29
+#include "sysemu/tcg.h"
67
uint32_t vq, max_vq = 0;
30
#include "kvm_arm.h"
68
31
#include "hvf_arm.h"
69
+ /* Collect the set of vector lengths supported by KVM. */
32
#include "qapi/visitor.h"
70
+ bitmap_zero(kvm_supported, ARM_MAX_VQ);
33
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
71
+ if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) {
72
+ kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
73
+ } else if (kvm_enabled()) {
74
+ assert(!cpu_isar_feature(aa64_sve, cpu));
75
+ }
76
+
77
/*
78
* Process explicit sve<N> properties.
79
* From the properties, sve_vq_map<N> implies sve_vq_init<N>.
80
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
81
return;
82
}
83
84
- /* Propagate enabled bits down through required powers-of-two. */
85
- for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
86
- if (!test_bit(vq - 1, cpu->sve_vq_init)) {
87
- set_bit(vq - 1, cpu->sve_vq_map);
88
+ if (kvm_enabled()) {
89
+ /*
90
+ * For KVM we have to automatically enable all supported unitialized
91
+ * lengths, even when the smaller lengths are not all powers-of-two.
92
+ */
93
+ bitmap_andnot(tmp, kvm_supported, cpu->sve_vq_init, max_vq);
94
+ bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq);
95
+ } else {
96
+ /* Propagate enabled bits down through required powers-of-two. */
97
+ for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
98
+ if (!test_bit(vq - 1, cpu->sve_vq_init)) {
99
+ set_bit(vq - 1, cpu->sve_vq_map);
100
+ }
101
}
102
}
103
} else if (cpu->sve_max_vq == 0) {
104
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
105
return;
106
}
107
108
- /* Disabling a power-of-two disables all larger lengths. */
109
- if (test_bit(0, cpu->sve_vq_init)) {
110
- error_setg(errp, "cannot disable sve128");
111
- error_append_hint(errp, "Disabling sve128 results in all vector "
112
- "lengths being disabled.\n");
113
- error_append_hint(errp, "With SVE enabled, at least one vector "
114
- "length must be enabled.\n");
115
- return;
116
- }
117
- for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
118
- if (test_bit(vq - 1, cpu->sve_vq_init)) {
119
- break;
120
+ if (kvm_enabled()) {
121
+ /* Disabling a supported length disables all larger lengths. */
122
+ for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
123
+ if (test_bit(vq - 1, cpu->sve_vq_init) &&
124
+ test_bit(vq - 1, kvm_supported)) {
125
+ break;
126
+ }
127
}
128
+ max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
129
+ bitmap_andnot(cpu->sve_vq_map, kvm_supported,
130
+ cpu->sve_vq_init, max_vq);
131
+ if (max_vq == 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) {
132
+ error_setg(errp, "cannot disable sve%d", vq * 128);
133
+ error_append_hint(errp, "Disabling sve%d results in all "
134
+ "vector lengths being disabled.\n",
135
+ vq * 128);
136
+ error_append_hint(errp, "With SVE enabled, at least one "
137
+ "vector length must be enabled.\n");
138
+ return;
139
+ }
140
+ } else {
141
+ /* Disabling a power-of-two disables all larger lengths. */
142
+ if (test_bit(0, cpu->sve_vq_init)) {
143
+ error_setg(errp, "cannot disable sve128");
144
+ error_append_hint(errp, "Disabling sve128 results in all "
145
+ "vector lengths being disabled.\n");
146
+ error_append_hint(errp, "With SVE enabled, at least one "
147
+ "vector length must be enabled.\n");
148
+ return;
149
+ }
150
+ for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
151
+ if (test_bit(vq - 1, cpu->sve_vq_init)) {
152
+ break;
153
+ }
154
+ }
155
+ max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
156
+ bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
157
}
158
- max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
159
160
- bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
161
max_vq = find_last_bit(cpu->sve_vq_map, max_vq) + 1;
162
}
163
164
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
165
assert(max_vq != 0);
166
bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq);
167
168
- /* Ensure all required powers-of-two are enabled. */
169
- for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
170
- if (!test_bit(vq - 1, cpu->sve_vq_map)) {
171
- error_setg(errp, "cannot disable sve%d", vq * 128);
172
- error_append_hint(errp, "sve%d is required as it "
173
- "is a power-of-two length smaller than "
174
- "the maximum, sve%d\n",
175
- vq * 128, max_vq * 128);
176
+ if (kvm_enabled()) {
177
+ /* Ensure the set of lengths matches what KVM supports. */
178
+ bitmap_xor(tmp, cpu->sve_vq_map, kvm_supported, max_vq);
179
+ if (!bitmap_empty(tmp, max_vq)) {
180
+ vq = find_last_bit(tmp, max_vq) + 1;
181
+ if (test_bit(vq - 1, cpu->sve_vq_map)) {
182
+ if (cpu->sve_max_vq) {
183
+ error_setg(errp, "cannot set sve-max-vq=%d",
184
+ cpu->sve_max_vq);
185
+ error_append_hint(errp, "This KVM host does not support "
186
+ "the vector length %d-bits.\n",
187
+ vq * 128);
188
+ error_append_hint(errp, "It may not be possible to use "
189
+ "sve-max-vq with this KVM host. Try "
190
+ "using only sve<N> properties.\n");
191
+ } else {
192
+ error_setg(errp, "cannot enable sve%d", vq * 128);
193
+ error_append_hint(errp, "This KVM host does not support "
194
+ "the vector length %d-bits.\n",
195
+ vq * 128);
196
+ }
197
+ } else {
198
+ error_setg(errp, "cannot disable sve%d", vq * 128);
199
+ error_append_hint(errp, "The KVM host requires all "
200
+ "supported vector lengths smaller "
201
+ "than %d bits to also be enabled.\n",
202
+ max_vq * 128);
203
+ }
204
return;
205
}
206
+ } else {
207
+ /* Ensure all required powers-of-two are enabled. */
208
+ for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
209
+ if (!test_bit(vq - 1, cpu->sve_vq_map)) {
210
+ error_setg(errp, "cannot disable sve%d", vq * 128);
211
+ error_append_hint(errp, "sve%d is required as it "
212
+ "is a power-of-two length smaller than "
213
+ "the maximum, sve%d\n",
214
+ vq * 128, max_vq * 128);
215
+ return;
216
+ }
217
+ }
218
}
219
220
/*
221
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
222
{
223
ARMCPU *cpu = ARM_CPU(obj);
224
Error *err = NULL;
225
+ uint32_t max_vq;
226
227
- visit_type_uint32(v, name, &cpu->sve_max_vq, &err);
228
-
229
- if (!err && (cpu->sve_max_vq == 0 || cpu->sve_max_vq > ARM_MAX_VQ)) {
230
- error_setg(&err, "unsupported SVE vector length");
231
- error_append_hint(&err, "Valid sve-max-vq in range [1-%d]\n",
232
- ARM_MAX_VQ);
233
+ visit_type_uint32(v, name, &max_vq, &err);
234
+ if (err) {
235
+ error_propagate(errp, err);
236
+ return;
237
}
238
- error_propagate(errp, err);
239
+
240
+ if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
241
+ error_setg(errp, "cannot set sve-max-vq");
242
+ error_append_hint(errp, "SVE not supported by KVM on this host\n");
243
+ return;
244
+ }
245
+
246
+ if (max_vq == 0 || max_vq > ARM_MAX_VQ) {
247
+ error_setg(errp, "unsupported SVE vector length");
248
+ error_append_hint(errp, "Valid sve-max-vq in range [1-%d]\n",
249
+ ARM_MAX_VQ);
250
+ return;
251
+ }
252
+
253
+ cpu->sve_max_vq = max_vq;
254
}
255
256
static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
257
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
258
return;
34
return;
259
}
35
}
260
36
261
+ if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
37
- /* '-cpu max' for TCG: we currently do this as "A57 with extra things" */
262
+ error_setg(errp, "cannot enable %s", name);
38
+ if (tcg_enabled() || qtest_enabled()) {
263
+ error_append_hint(errp, "SVE not supported by KVM on this host\n");
39
+ aarch64_a57_initfn(obj);
264
+ return;
265
+ }
40
+ }
266
+
41
267
if (value) {
42
- aarch64_a57_initfn(obj);
268
set_bit(vq - 1, cpu->sve_vq_map);
43
- aarch64_max_tcg_initfn(obj);
269
} else {
44
+ /* '-cpu max' for TCG: we currently do this as "A57 with extra things" */
270
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
45
+ if (tcg_enabled()) {
271
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
46
+ aarch64_max_tcg_initfn(obj);
272
cpu->dcz_blocksize = 7; /* 512 bytes */
273
#endif
274
-
275
- object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
276
- cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
277
-
278
- for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
279
- char name[8];
280
- sprintf(name, "sve%d", vq * 128);
281
- object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
282
- cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
283
- }
284
}
285
286
object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
287
cpu_arm_set_sve, NULL, NULL, &error_fatal);
288
+ object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
289
+ cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
290
+
291
+ for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
292
+ char name[8];
293
+ sprintf(name, "sve%d", vq * 128);
294
+ object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
295
+ cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
296
+ }
47
+ }
297
}
48
}
298
49
299
struct ARMCPUInfo {
50
static const ARMCPUInfo aarch64_cpus[] = {
300
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
301
index XXXXXXX..XXXXXXX 100644
302
--- a/target/arm/kvm64.c
303
+++ b/target/arm/kvm64.c
304
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_sve_supported(CPUState *cpu)
305
return kvm_check_extension(s, KVM_CAP_ARM_SVE);
306
}
307
308
+QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
309
+
310
+void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map)
311
+{
312
+ /* Only call this function if kvm_arm_sve_supported() returns true. */
313
+ static uint64_t vls[KVM_ARM64_SVE_VLS_WORDS];
314
+ static bool probed;
315
+ uint32_t vq = 0;
316
+ int i, j;
317
+
318
+ bitmap_clear(map, 0, ARM_MAX_VQ);
319
+
320
+ /*
321
+ * KVM ensures all host CPUs support the same set of vector lengths.
322
+ * So we only need to create the scratch VCPUs once and then cache
323
+ * the results.
324
+ */
325
+ if (!probed) {
326
+ struct kvm_vcpu_init init = {
327
+ .target = -1,
328
+ .features[0] = (1 << KVM_ARM_VCPU_SVE),
329
+ };
330
+ struct kvm_one_reg reg = {
331
+ .id = KVM_REG_ARM64_SVE_VLS,
332
+ .addr = (uint64_t)&vls[0],
333
+ };
334
+ int fdarray[3], ret;
335
+
336
+ probed = true;
337
+
338
+ if (!kvm_arm_create_scratch_host_vcpu(NULL, fdarray, &init)) {
339
+ error_report("failed to create scratch VCPU with SVE enabled");
340
+ abort();
341
+ }
342
+ ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &reg);
343
+ kvm_arm_destroy_scratch_host_vcpu(fdarray);
344
+ if (ret) {
345
+ error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s",
346
+ strerror(errno));
347
+ abort();
348
+ }
349
+
350
+ for (i = KVM_ARM64_SVE_VLS_WORDS - 1; i >= 0; --i) {
351
+ if (vls[i]) {
352
+ vq = 64 - clz64(vls[i]) + i * 64;
353
+ break;
354
+ }
355
+ }
356
+ if (vq > ARM_MAX_VQ) {
357
+ warn_report("KVM supports vector lengths larger than "
358
+ "QEMU can enable");
359
+ }
360
+ }
361
+
362
+ for (i = 0; i < KVM_ARM64_SVE_VLS_WORDS; ++i) {
363
+ if (!vls[i]) {
364
+ continue;
365
+ }
366
+ for (j = 1; j <= 64; ++j) {
367
+ vq = j + i * 64;
368
+ if (vq > ARM_MAX_VQ) {
369
+ return;
370
+ }
371
+ if (vls[i] & (1UL << (j - 1))) {
372
+ set_bit(vq - 1, map);
373
+ }
374
+ }
375
+ }
376
+}
377
+
378
+static int kvm_arm_sve_set_vls(CPUState *cs)
379
+{
380
+ uint64_t vls[KVM_ARM64_SVE_VLS_WORDS] = {0};
381
+ struct kvm_one_reg reg = {
382
+ .id = KVM_REG_ARM64_SVE_VLS,
383
+ .addr = (uint64_t)&vls[0],
384
+ };
385
+ ARMCPU *cpu = ARM_CPU(cs);
386
+ uint32_t vq;
387
+ int i, j;
388
+
389
+ assert(cpu->sve_max_vq <= KVM_ARM64_SVE_VQ_MAX);
390
+
391
+ for (vq = 1; vq <= cpu->sve_max_vq; ++vq) {
392
+ if (test_bit(vq - 1, cpu->sve_vq_map)) {
393
+ i = (vq - 1) / 64;
394
+ j = (vq - 1) % 64;
395
+ vls[i] |= 1UL << j;
396
+ }
397
+ }
398
+
399
+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
400
+}
401
+
402
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
403
404
int kvm_arch_init_vcpu(CPUState *cs)
405
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
406
407
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
408
!object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
409
- fprintf(stderr, "KVM is not supported for this guest CPU type\n");
410
+ error_report("KVM is not supported for this guest CPU type");
411
return -EINVAL;
412
}
413
414
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
415
}
416
417
if (cpu_isar_feature(aa64_sve, cpu)) {
418
+ ret = kvm_arm_sve_set_vls(cs);
419
+ if (ret) {
420
+ return ret;
421
+ }
422
ret = kvm_arm_vcpu_finalize(cs, KVM_ARM_VCPU_SVE);
423
if (ret) {
424
return ret;
425
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
426
index XXXXXXX..XXXXXXX 100644
427
--- a/tests/arm-cpu-features.c
428
+++ b/tests/arm-cpu-features.c
429
@@ -XXX,XX +XXX,XX @@ static QDict *resp_get_props(QDict *resp)
430
return qdict;
431
}
432
433
+static bool resp_get_feature(QDict *resp, const char *feature)
434
+{
435
+ QDict *props;
436
+
437
+ g_assert(resp);
438
+ g_assert(resp_has_props(resp));
439
+ props = resp_get_props(resp);
440
+ g_assert(qdict_get(props, feature));
441
+ return qdict_get_bool(props, feature);
442
+}
443
+
444
#define assert_has_feature(qts, cpu_type, feature) \
445
({ \
446
QDict *_resp = do_query_no_props(qts, cpu_type); \
447
@@ -XXX,XX +XXX,XX @@ static void sve_tests_sve_off(const void *data)
448
qtest_quit(qts);
449
}
450
451
+static void sve_tests_sve_off_kvm(const void *data)
452
+{
453
+ QTestState *qts;
454
+
455
+ qts = qtest_init(MACHINE "-accel kvm -cpu max,sve=off");
456
+
457
+ /*
458
+ * We don't know if this host supports SVE so we don't
459
+ * attempt to test enabling anything. We only test that
460
+ * everything is disabled (as it should be with sve=off)
461
+ * and that using sve<N>=off to explicitly disable vector
462
+ * lengths is OK too.
463
+ */
464
+ assert_sve_vls(qts, "max", 0, NULL);
465
+ assert_sve_vls(qts, "max", 0, "{ 'sve128': false }");
466
+
467
+ qtest_quit(qts);
468
+}
469
+
470
static void test_query_cpu_model_expansion(const void *data)
471
{
472
QTestState *qts;
473
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
474
qts = qtest_init(MACHINE "-accel kvm -cpu host");
475
476
if (g_str_equal(qtest_get_arch(), "aarch64")) {
477
+ bool kvm_supports_sve;
478
+ char max_name[8], name[8];
479
+ uint32_t max_vq, vq;
480
+ uint64_t vls;
481
+ QDict *resp;
482
+ char *error;
483
+
484
assert_has_feature(qts, "host", "aarch64");
485
assert_has_feature(qts, "host", "pmu");
486
487
- assert_has_feature(qts, "max", "sve");
488
-
489
assert_error(qts, "cortex-a15",
490
"We cannot guarantee the CPU type 'cortex-a15' works "
491
"with KVM on this host", NULL);
492
+
493
+ assert_has_feature(qts, "max", "sve");
494
+ resp = do_query_no_props(qts, "max");
495
+ kvm_supports_sve = resp_get_feature(resp, "sve");
496
+ vls = resp_get_sve_vls(resp);
497
+ qobject_unref(resp);
498
+
499
+ if (kvm_supports_sve) {
500
+ g_assert(vls != 0);
501
+ max_vq = 64 - __builtin_clzll(vls);
502
+ sprintf(max_name, "sve%d", max_vq * 128);
503
+
504
+ /* Enabling a supported length is of course fine. */
505
+ assert_sve_vls(qts, "max", vls, "{ %s: true }", max_name);
506
+
507
+ /* Get the next supported length smaller than max-vq. */
508
+ vq = 64 - __builtin_clzll(vls & ~BIT_ULL(max_vq - 1));
509
+ if (vq) {
510
+ /*
511
+ * We have at least one length smaller than max-vq,
512
+ * so we can disable max-vq.
513
+ */
514
+ assert_sve_vls(qts, "max", (vls & ~BIT_ULL(max_vq - 1)),
515
+ "{ %s: false }", max_name);
516
+
517
+ /*
518
+ * Smaller, supported vector lengths cannot be disabled
519
+ * unless all larger, supported vector lengths are also
520
+ * disabled.
521
+ */
522
+ sprintf(name, "sve%d", vq * 128);
523
+ error = g_strdup_printf("cannot disable %s", name);
524
+ assert_error(qts, "max", error,
525
+ "{ %s: true, %s: false }",
526
+ max_name, name);
527
+ g_free(error);
528
+ }
529
+
530
+ /*
531
+ * The smallest, supported vector length is required, because
532
+ * we need at least one vector length enabled.
533
+ */
534
+ vq = __builtin_ffsll(vls);
535
+ sprintf(name, "sve%d", vq * 128);
536
+ error = g_strdup_printf("cannot disable %s", name);
537
+ assert_error(qts, "max", error, "{ %s: false }", name);
538
+ g_free(error);
539
+
540
+ /* Get an unsupported length. */
541
+ for (vq = 1; vq <= max_vq; ++vq) {
542
+ if (!(vls & BIT_ULL(vq - 1))) {
543
+ break;
544
+ }
545
+ }
546
+ if (vq <= SVE_MAX_VQ) {
547
+ sprintf(name, "sve%d", vq * 128);
548
+ error = g_strdup_printf("cannot enable %s", name);
549
+ assert_error(qts, "max", error, "{ %s: true }", name);
550
+ g_free(error);
551
+ }
552
+ } else {
553
+ g_assert(vls == 0);
554
+ }
555
} else {
556
assert_has_not_feature(qts, "host", "aarch64");
557
assert_has_not_feature(qts, "host", "pmu");
558
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
559
if (kvm_available) {
560
qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
561
NULL, test_query_cpu_model_expansion_kvm);
562
+ if (g_str_equal(qtest_get_arch(), "aarch64")) {
563
+ qtest_add_data_func("/arm/kvm/query-cpu-model-expansion/sve-off",
564
+ NULL, sve_tests_sve_off_kvm);
565
+ }
566
}
567
568
return g_test_run();
569
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
570
index XXXXXXX..XXXXXXX 100644
571
--- a/docs/arm-cpu-features.rst
572
+++ b/docs/arm-cpu-features.rst
573
@@ -XXX,XX +XXX,XX @@ SVE CPU Property Dependencies and Constraints
574
575
1) At least one vector length must be enabled when `sve` is enabled.
576
577
- 2) If a vector length `N` is enabled, then all power-of-two vector
578
- lengths smaller than `N` must also be enabled. E.g. if `sve512`
579
- is enabled, then the 128-bit and 256-bit vector lengths must also
580
- be enabled.
581
+ 2) If a vector length `N` is enabled, then, when KVM is enabled, all
582
+ smaller, host supported vector lengths must also be enabled. If
583
+ KVM is not enabled, then only all the smaller, power-of-two vector
584
+ lengths must be enabled. E.g. with KVM if the host supports all
585
+ vector lengths up to 512-bits (128, 256, 384, 512), then if `sve512`
586
+ is enabled, the 128-bit vector length, 256-bit vector length, and
587
+ 384-bit vector length must also be enabled. Without KVM, the 384-bit
588
+ vector length would not be required.
589
+
590
+ 3) If KVM is enabled then only vector lengths that the host CPU type
591
+ support may be enabled. If SVE is not supported by the host, then
592
+ no `sve*` properties may be enabled.
593
594
SVE CPU Property Parsing Semantics
595
----------------------------------
596
@@ -XXX,XX +XXX,XX @@ SVE CPU Property Parsing Semantics
597
an error is generated.
598
599
2) If SVE is enabled (`sve=on`), but no `sve<N>` CPU properties are
600
- provided, then all supported vector lengths are enabled, including
601
- the non-power-of-two lengths.
602
+ provided, then all supported vector lengths are enabled, which when
603
+ KVM is not in use means including the non-power-of-two lengths, and,
604
+ when KVM is in use, it means all vector lengths supported by the host
605
+ processor.
606
607
3) If SVE is enabled, then an error is generated when attempting to
608
disable the last enabled vector length (see constraint (1) of "SVE
609
@@ -XXX,XX +XXX,XX @@ SVE CPU Property Parsing Semantics
610
has been explicitly disabled, then an error is generated (see
611
constraint (2) of "SVE CPU Property Dependencies and Constraints").
612
613
- 5) If one or more `sve<N>` CPU properties are set `off`, but no `sve<N>`,
614
+ 5) When KVM is enabled, if the host does not support SVE, then an error
615
+ is generated when attempting to enable any `sve*` properties (see
616
+ constraint (3) of "SVE CPU Property Dependencies and Constraints").
617
+
618
+ 6) When KVM is enabled, if the host does support SVE, then an error is
619
+ generated when attempting to enable any vector lengths not supported
620
+ by the host (see constraint (3) of "SVE CPU Property Dependencies and
621
+ Constraints").
622
+
623
+ 7) If one or more `sve<N>` CPU properties are set `off`, but no `sve<N>`,
624
CPU properties are set `on`, then the specified vector lengths are
625
disabled but the default for any unspecified lengths remains enabled.
626
- Disabling a power-of-two vector length also disables all vector
627
- lengths larger than the power-of-two length (see constraint (2) of
628
- "SVE CPU Property Dependencies and Constraints").
629
+ When KVM is not enabled, disabling a power-of-two vector length also
630
+ disables all vector lengths larger than the power-of-two length.
631
+ When KVM is enabled, then disabling any supported vector length also
632
+ disables all larger vector lengths (see constraint (2) of "SVE CPU
633
+ Property Dependencies and Constraints").
634
635
- 6) If one or more `sve<N>` CPU properties are set to `on`, then they
636
+ 8) If one or more `sve<N>` CPU properties are set to `on`, then they
637
are enabled and all unspecified lengths default to disabled, except
638
for the required lengths per constraint (2) of "SVE CPU Property
639
Dependencies and Constraints", which will even be auto-enabled if
640
they were not explicitly enabled.
641
642
- 7) If SVE was disabled (`sve=off`), allowing all vector lengths to be
643
+ 9) If SVE was disabled (`sve=off`), allowing all vector lengths to be
644
explicitly disabled (i.e. avoiding the error specified in (3) of
645
"SVE CPU Property Parsing Semantics"), then if later an `sve=on` is
646
provided an error will be generated. To avoid this error, one must
647
--
51
--
648
2.20.1
52
2.34.1
649
53
650
54
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Allow cpu 'host' to enable SVE when it's available, unless the
3
Move the 64-bit CPUs that are TCG-only:
4
user chooses to disable it with the added 'sve=off' cpu property.
4
- cortex-a35
5
Also give the user the ability to select vector lengths with the
5
- cortex-a55
6
sve<N> properties. We don't adopt 'max' cpu's other sve property,
6
- cortex-a72
7
sve-max-vq, because that property is difficult to use with KVM.
7
- cortex-a76
8
That property assumes all vector lengths in the range from 1 up
8
- a64fx
9
to and including the specified maximum length are supported, but
9
- neoverse-n1
10
there may be optional lengths not supported by the host in that
11
range. With KVM one must be more specific when enabling vector
12
lengths.
13
10
14
Signed-off-by: Andrew Jones <drjones@redhat.com>
11
Keep the CPUs that can be used with KVM:
15
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
- cortex-a57
13
- cortex-a53
14
- max
15
- host
16
17
Signed-off-by: Fabiano Rosas <farosas@suse.de>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
19
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Message-id: 20191024121808.9612-10-drjones@redhat.com
20
Message-id: 20230426180013.14814-6-farosas@suse.de
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
22
---
21
target/arm/cpu.h | 2 ++
23
target/arm/internals.h | 4 +
22
target/arm/cpu.c | 3 +++
24
hw/arm/virt.c | 6 +-
23
target/arm/cpu64.c | 33 +++++++++++++++++----------------
25
target/arm/cpu64.c | 687 +-----------------------------
24
target/arm/kvm64.c | 14 +++++++++++++-
26
target/arm/{ => tcg}/cpu64.c | 782 +----------------------------------
25
tests/arm-cpu-features.c | 23 +++++++++++------------
27
target/arm/tcg/meson.build | 1 +
26
docs/arm-cpu-features.rst | 19 ++++++++++++-------
28
5 files changed, 14 insertions(+), 1466 deletions(-)
27
6 files changed, 58 insertions(+), 36 deletions(-)
29
copy target/arm/{ => tcg}/cpu64.c (51%)
28
30
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
diff --git a/target/arm/internals.h b/target/arm/internals.h
30
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
33
--- a/target/arm/internals.h
32
+++ b/target/arm/cpu.h
34
+++ b/target/arm/internals.h
33
@@ -XXX,XX +XXX,XX @@ int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
35
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
34
void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
36
void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp);
35
void aarch64_sve_change_el(CPUARMState *env, int old_el,
37
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
36
int new_el, bool el0_a64);
38
void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
39
+void aarch64_max_tcg_initfn(Object *obj);
40
+void aarch64_add_pauth_properties(Object *obj);
37
+void aarch64_add_sve_properties(Object *obj);
41
+void aarch64_add_sve_properties(Object *obj);
38
#else
42
+void aarch64_add_sme_properties(Object *obj);
39
static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
40
static inline void aarch64_sve_change_el(CPUARMState *env, int o,
41
int n, bool a)
42
{ }
43
+static inline void aarch64_add_sve_properties(Object *obj) { }
44
#endif
43
#endif
45
44
46
#if !defined(CONFIG_TCG)
45
/* Read the CONTROL register as the MRS instruction would. */
47
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
48
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/cpu.c
48
--- a/hw/arm/virt.c
50
+++ b/target/arm/cpu.c
49
+++ b/hw/arm/virt.c
51
@@ -XXX,XX +XXX,XX @@ static void arm_host_initfn(Object *obj)
50
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
52
ARMCPU *cpu = ARM_CPU(obj);
51
ARM_CPU_TYPE_NAME("cortex-a7"),
53
52
#endif
54
kvm_arm_set_cpu_features_from_host(cpu);
53
ARM_CPU_TYPE_NAME("cortex-a15"),
55
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
54
+#ifdef CONFIG_TCG
56
+ aarch64_add_sve_properties(obj);
55
ARM_CPU_TYPE_NAME("cortex-a35"),
57
+ }
56
- ARM_CPU_TYPE_NAME("cortex-a53"),
58
arm_cpu_post_init(obj);
57
ARM_CPU_TYPE_NAME("cortex-a55"),
59
}
58
- ARM_CPU_TYPE_NAME("cortex-a57"),
60
59
ARM_CPU_TYPE_NAME("cortex-a72"),
60
ARM_CPU_TYPE_NAME("cortex-a76"),
61
ARM_CPU_TYPE_NAME("a64fx"),
62
ARM_CPU_TYPE_NAME("neoverse-n1"),
63
+#endif
64
+ ARM_CPU_TYPE_NAME("cortex-a53"),
65
+ ARM_CPU_TYPE_NAME("cortex-a57"),
66
ARM_CPU_TYPE_NAME("host"),
67
ARM_CPU_TYPE_NAME("max"),
68
};
61
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
69
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
62
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/cpu64.c
71
--- a/target/arm/cpu64.c
64
+++ b/target/arm/cpu64.c
72
+++ b/target/arm/cpu64.c
65
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
73
@@ -XXX,XX +XXX,XX @@
66
cpu->isar.id_aa64pfr0 = t;
74
#include "internals.h"
75
#include "cpregs.h"
76
77
-static void aarch64_a35_initfn(Object *obj)
78
-{
79
- ARMCPU *cpu = ARM_CPU(obj);
80
-
81
- cpu->dtb_compatible = "arm,cortex-a35";
82
- set_feature(&cpu->env, ARM_FEATURE_V8);
83
- set_feature(&cpu->env, ARM_FEATURE_NEON);
84
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
85
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
86
- set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
87
- set_feature(&cpu->env, ARM_FEATURE_EL2);
88
- set_feature(&cpu->env, ARM_FEATURE_EL3);
89
- set_feature(&cpu->env, ARM_FEATURE_PMU);
90
-
91
- /* From B2.2 AArch64 identification registers. */
92
- cpu->midr = 0x411fd040;
93
- cpu->revidr = 0;
94
- cpu->ctr = 0x84448004;
95
- cpu->isar.id_pfr0 = 0x00000131;
96
- cpu->isar.id_pfr1 = 0x00011011;
97
- cpu->isar.id_dfr0 = 0x03010066;
98
- cpu->id_afr0 = 0;
99
- cpu->isar.id_mmfr0 = 0x10201105;
100
- cpu->isar.id_mmfr1 = 0x40000000;
101
- cpu->isar.id_mmfr2 = 0x01260000;
102
- cpu->isar.id_mmfr3 = 0x02102211;
103
- cpu->isar.id_isar0 = 0x02101110;
104
- cpu->isar.id_isar1 = 0x13112111;
105
- cpu->isar.id_isar2 = 0x21232042;
106
- cpu->isar.id_isar3 = 0x01112131;
107
- cpu->isar.id_isar4 = 0x00011142;
108
- cpu->isar.id_isar5 = 0x00011121;
109
- cpu->isar.id_aa64pfr0 = 0x00002222;
110
- cpu->isar.id_aa64pfr1 = 0;
111
- cpu->isar.id_aa64dfr0 = 0x10305106;
112
- cpu->isar.id_aa64dfr1 = 0;
113
- cpu->isar.id_aa64isar0 = 0x00011120;
114
- cpu->isar.id_aa64isar1 = 0;
115
- cpu->isar.id_aa64mmfr0 = 0x00101122;
116
- cpu->isar.id_aa64mmfr1 = 0;
117
- cpu->clidr = 0x0a200023;
118
- cpu->dcz_blocksize = 4;
119
-
120
- /* From B2.4 AArch64 Virtual Memory control registers */
121
- cpu->reset_sctlr = 0x00c50838;
122
-
123
- /* From B2.10 AArch64 performance monitor registers */
124
- cpu->isar.reset_pmcr_el0 = 0x410a3000;
125
-
126
- /* From B2.29 Cache ID registers */
127
- cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
128
- cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
129
- cpu->ccsidr[2] = 0x703fe03a; /* 512KB L2 cache */
130
-
131
- /* From B3.5 VGIC Type register */
132
- cpu->gic_num_lrs = 4;
133
- cpu->gic_vpribits = 5;
134
- cpu->gic_vprebits = 5;
135
- cpu->gic_pribits = 5;
136
-
137
- /* From C6.4 Debug ID Register */
138
- cpu->isar.dbgdidr = 0x3516d000;
139
- /* From C6.5 Debug Device ID Register */
140
- cpu->isar.dbgdevid = 0x00110f13;
141
- /* From C6.6 Debug Device ID Register 1 */
142
- cpu->isar.dbgdevid1 = 0x2;
143
-
144
- /* From Cortex-A35 SIMD and Floating-point Support r1p0 */
145
- /* From 3.2 AArch32 register summary */
146
- cpu->reset_fpsid = 0x41034043;
147
-
148
- /* From 2.2 AArch64 register summary */
149
- cpu->isar.mvfr0 = 0x10110222;
150
- cpu->isar.mvfr1 = 0x12111111;
151
- cpu->isar.mvfr2 = 0x00000043;
152
-
153
- /* These values are the same with A53/A57/A72. */
154
- define_cortex_a72_a57_a53_cp_reginfo(cpu);
155
-}
156
-
157
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
158
{
159
/*
160
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
161
cpu->sve_vq.map = vq_map;
67
}
162
}
68
163
164
-static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
165
- void *opaque, Error **errp)
166
-{
167
- ARMCPU *cpu = ARM_CPU(obj);
168
- uint32_t value;
169
-
170
- /* All vector lengths are disabled when SVE is off. */
171
- if (!cpu_isar_feature(aa64_sve, cpu)) {
172
- value = 0;
173
- } else {
174
- value = cpu->sve_max_vq;
175
- }
176
- visit_type_uint32(v, name, &value, errp);
177
-}
178
-
179
-static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
180
- void *opaque, Error **errp)
181
-{
182
- ARMCPU *cpu = ARM_CPU(obj);
183
- uint32_t max_vq;
184
-
185
- if (!visit_type_uint32(v, name, &max_vq, errp)) {
186
- return;
187
- }
188
-
189
- if (max_vq == 0 || max_vq > ARM_MAX_VQ) {
190
- error_setg(errp, "unsupported SVE vector length");
191
- error_append_hint(errp, "Valid sve-max-vq in range [1-%d]\n",
192
- ARM_MAX_VQ);
193
- return;
194
- }
195
-
196
- cpu->sve_max_vq = max_vq;
197
-}
198
-
199
/*
200
* Note that cpu_arm_{get,set}_vq cannot use the simpler
201
* object_property_add_bool interface because they make use of the
202
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_get_default_vec_len(Object *obj, Visitor *v,
203
}
204
#endif
205
206
-static void aarch64_add_sve_properties(Object *obj)
69
+void aarch64_add_sve_properties(Object *obj)
207
+void aarch64_add_sve_properties(Object *obj)
70
+{
208
{
71
+ uint32_t vq;
209
ARMCPU *cpu = ARM_CPU(obj);
72
+
210
uint32_t vq;
73
+ object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
211
@@ -XXX,XX +XXX,XX @@ static void aarch64_add_sve_properties(Object *obj)
74
+ cpu_arm_set_sve, NULL, NULL, &error_fatal);
212
#endif
75
+
213
}
76
+ for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
214
77
+ char name[8];
215
-static void aarch64_add_sme_properties(Object *obj)
78
+ sprintf(name, "sve%d", vq * 128);
216
+void aarch64_add_sme_properties(Object *obj)
79
+ object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
217
{
80
+ cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
218
ARMCPU *cpu = ARM_CPU(obj);
81
+ }
219
uint32_t vq;
82
+}
220
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_pauth_property =
83
+
221
static Property arm_cpu_pauth_impdef_property =
84
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
222
DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
85
* otherwise, a CPU with as many features enabled as our emulation supports.
223
86
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
224
-static void aarch64_add_pauth_properties(Object *obj)
87
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
225
+void aarch64_add_pauth_properties(Object *obj)
226
{
227
ARMCPU *cpu = ARM_CPU(obj);
228
229
@@ -XXX,XX +XXX,XX @@ static void aarch64_add_pauth_properties(Object *obj)
230
}
231
}
232
233
-static Property arm_cpu_lpa2_property =
234
- DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
235
-
236
void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
237
{
238
uint64_t t;
239
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
240
define_cortex_a72_a57_a53_cp_reginfo(cpu);
241
}
242
243
-static void aarch64_a55_initfn(Object *obj)
244
-{
245
- ARMCPU *cpu = ARM_CPU(obj);
246
-
247
- cpu->dtb_compatible = "arm,cortex-a55";
248
- set_feature(&cpu->env, ARM_FEATURE_V8);
249
- set_feature(&cpu->env, ARM_FEATURE_NEON);
250
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
251
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
252
- set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
253
- set_feature(&cpu->env, ARM_FEATURE_EL2);
254
- set_feature(&cpu->env, ARM_FEATURE_EL3);
255
- set_feature(&cpu->env, ARM_FEATURE_PMU);
256
-
257
- /* Ordered by B2.4 AArch64 registers by functional group */
258
- cpu->clidr = 0x82000023;
259
- cpu->ctr = 0x84448004; /* L1Ip = VIPT */
260
- cpu->dcz_blocksize = 4; /* 64 bytes */
261
- cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
262
- cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
263
- cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
264
- cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
265
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
266
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
267
- cpu->isar.id_aa64pfr0 = 0x0000000010112222ull;
268
- cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
269
- cpu->id_afr0 = 0x00000000;
270
- cpu->isar.id_dfr0 = 0x04010088;
271
- cpu->isar.id_isar0 = 0x02101110;
272
- cpu->isar.id_isar1 = 0x13112111;
273
- cpu->isar.id_isar2 = 0x21232042;
274
- cpu->isar.id_isar3 = 0x01112131;
275
- cpu->isar.id_isar4 = 0x00011142;
276
- cpu->isar.id_isar5 = 0x01011121;
277
- cpu->isar.id_isar6 = 0x00000010;
278
- cpu->isar.id_mmfr0 = 0x10201105;
279
- cpu->isar.id_mmfr1 = 0x40000000;
280
- cpu->isar.id_mmfr2 = 0x01260000;
281
- cpu->isar.id_mmfr3 = 0x02122211;
282
- cpu->isar.id_mmfr4 = 0x00021110;
283
- cpu->isar.id_pfr0 = 0x10010131;
284
- cpu->isar.id_pfr1 = 0x00011011;
285
- cpu->isar.id_pfr2 = 0x00000011;
286
- cpu->midr = 0x412FD050; /* r2p0 */
287
- cpu->revidr = 0;
288
-
289
- /* From B2.23 CCSIDR_EL1 */
290
- cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
291
- cpu->ccsidr[1] = 0x200fe01a; /* 32KB L1 icache */
292
- cpu->ccsidr[2] = 0x703fe07a; /* 512KB L2 cache */
293
-
294
- /* From B2.96 SCTLR_EL3 */
295
- cpu->reset_sctlr = 0x30c50838;
296
-
297
- /* From B4.45 ICH_VTR_EL2 */
298
- cpu->gic_num_lrs = 4;
299
- cpu->gic_vpribits = 5;
300
- cpu->gic_vprebits = 5;
301
- cpu->gic_pribits = 5;
302
-
303
- cpu->isar.mvfr0 = 0x10110222;
304
- cpu->isar.mvfr1 = 0x13211111;
305
- cpu->isar.mvfr2 = 0x00000043;
306
-
307
- /* From D5.4 AArch64 PMU register summary */
308
- cpu->isar.reset_pmcr_el0 = 0x410b3000;
309
-}
310
-
311
-static void aarch64_a72_initfn(Object *obj)
312
-{
313
- ARMCPU *cpu = ARM_CPU(obj);
314
-
315
- cpu->dtb_compatible = "arm,cortex-a72";
316
- set_feature(&cpu->env, ARM_FEATURE_V8);
317
- set_feature(&cpu->env, ARM_FEATURE_NEON);
318
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
319
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
320
- set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
321
- set_feature(&cpu->env, ARM_FEATURE_EL2);
322
- set_feature(&cpu->env, ARM_FEATURE_EL3);
323
- set_feature(&cpu->env, ARM_FEATURE_PMU);
324
- cpu->midr = 0x410fd083;
325
- cpu->revidr = 0x00000000;
326
- cpu->reset_fpsid = 0x41034080;
327
- cpu->isar.mvfr0 = 0x10110222;
328
- cpu->isar.mvfr1 = 0x12111111;
329
- cpu->isar.mvfr2 = 0x00000043;
330
- cpu->ctr = 0x8444c004;
331
- cpu->reset_sctlr = 0x00c50838;
332
- cpu->isar.id_pfr0 = 0x00000131;
333
- cpu->isar.id_pfr1 = 0x00011011;
334
- cpu->isar.id_dfr0 = 0x03010066;
335
- cpu->id_afr0 = 0x00000000;
336
- cpu->isar.id_mmfr0 = 0x10201105;
337
- cpu->isar.id_mmfr1 = 0x40000000;
338
- cpu->isar.id_mmfr2 = 0x01260000;
339
- cpu->isar.id_mmfr3 = 0x02102211;
340
- cpu->isar.id_isar0 = 0x02101110;
341
- cpu->isar.id_isar1 = 0x13112111;
342
- cpu->isar.id_isar2 = 0x21232042;
343
- cpu->isar.id_isar3 = 0x01112131;
344
- cpu->isar.id_isar4 = 0x00011142;
345
- cpu->isar.id_isar5 = 0x00011121;
346
- cpu->isar.id_aa64pfr0 = 0x00002222;
347
- cpu->isar.id_aa64dfr0 = 0x10305106;
348
- cpu->isar.id_aa64isar0 = 0x00011120;
349
- cpu->isar.id_aa64mmfr0 = 0x00001124;
350
- cpu->isar.dbgdidr = 0x3516d000;
351
- cpu->isar.dbgdevid = 0x01110f13;
352
- cpu->isar.dbgdevid1 = 0x2;
353
- cpu->isar.reset_pmcr_el0 = 0x41023000;
354
- cpu->clidr = 0x0a200023;
355
- cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
356
- cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
357
- cpu->ccsidr[2] = 0x707fe07a; /* 1MB L2 cache */
358
- cpu->dcz_blocksize = 4; /* 64 bytes */
359
- cpu->gic_num_lrs = 4;
360
- cpu->gic_vpribits = 5;
361
- cpu->gic_vprebits = 5;
362
- cpu->gic_pribits = 5;
363
- define_cortex_a72_a57_a53_cp_reginfo(cpu);
364
-}
365
-
366
-static void aarch64_a76_initfn(Object *obj)
367
-{
368
- ARMCPU *cpu = ARM_CPU(obj);
369
-
370
- cpu->dtb_compatible = "arm,cortex-a76";
371
- set_feature(&cpu->env, ARM_FEATURE_V8);
372
- set_feature(&cpu->env, ARM_FEATURE_NEON);
373
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
374
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
375
- set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
376
- set_feature(&cpu->env, ARM_FEATURE_EL2);
377
- set_feature(&cpu->env, ARM_FEATURE_EL3);
378
- set_feature(&cpu->env, ARM_FEATURE_PMU);
379
-
380
- /* Ordered by B2.4 AArch64 registers by functional group */
381
- cpu->clidr = 0x82000023;
382
- cpu->ctr = 0x8444C004;
383
- cpu->dcz_blocksize = 4;
384
- cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
385
- cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
386
- cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
387
- cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
388
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
389
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
390
- cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
391
- cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
392
- cpu->id_afr0 = 0x00000000;
393
- cpu->isar.id_dfr0 = 0x04010088;
394
- cpu->isar.id_isar0 = 0x02101110;
395
- cpu->isar.id_isar1 = 0x13112111;
396
- cpu->isar.id_isar2 = 0x21232042;
397
- cpu->isar.id_isar3 = 0x01112131;
398
- cpu->isar.id_isar4 = 0x00010142;
399
- cpu->isar.id_isar5 = 0x01011121;
400
- cpu->isar.id_isar6 = 0x00000010;
401
- cpu->isar.id_mmfr0 = 0x10201105;
402
- cpu->isar.id_mmfr1 = 0x40000000;
403
- cpu->isar.id_mmfr2 = 0x01260000;
404
- cpu->isar.id_mmfr3 = 0x02122211;
405
- cpu->isar.id_mmfr4 = 0x00021110;
406
- cpu->isar.id_pfr0 = 0x10010131;
407
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
408
- cpu->isar.id_pfr2 = 0x00000011;
409
- cpu->midr = 0x414fd0b1; /* r4p1 */
410
- cpu->revidr = 0;
411
-
412
- /* From B2.18 CCSIDR_EL1 */
413
- cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
414
- cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */
415
- cpu->ccsidr[2] = 0x707fe03a; /* 512KB L2 cache */
416
-
417
- /* From B2.93 SCTLR_EL3 */
418
- cpu->reset_sctlr = 0x30c50838;
419
-
420
- /* From B4.23 ICH_VTR_EL2 */
421
- cpu->gic_num_lrs = 4;
422
- cpu->gic_vpribits = 5;
423
- cpu->gic_vprebits = 5;
424
- cpu->gic_pribits = 5;
425
-
426
- /* From B5.1 AdvSIMD AArch64 register summary */
427
- cpu->isar.mvfr0 = 0x10110222;
428
- cpu->isar.mvfr1 = 0x13211111;
429
- cpu->isar.mvfr2 = 0x00000043;
430
-
431
- /* From D5.1 AArch64 PMU register summary */
432
- cpu->isar.reset_pmcr_el0 = 0x410b3000;
433
-}
434
-
435
-static void aarch64_a64fx_initfn(Object *obj)
436
-{
437
- ARMCPU *cpu = ARM_CPU(obj);
438
-
439
- cpu->dtb_compatible = "arm,a64fx";
440
- set_feature(&cpu->env, ARM_FEATURE_V8);
441
- set_feature(&cpu->env, ARM_FEATURE_NEON);
442
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
443
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
444
- set_feature(&cpu->env, ARM_FEATURE_EL2);
445
- set_feature(&cpu->env, ARM_FEATURE_EL3);
446
- set_feature(&cpu->env, ARM_FEATURE_PMU);
447
- cpu->midr = 0x461f0010;
448
- cpu->revidr = 0x00000000;
449
- cpu->ctr = 0x86668006;
450
- cpu->reset_sctlr = 0x30000180;
451
- cpu->isar.id_aa64pfr0 = 0x0000000101111111; /* No RAS Extensions */
452
- cpu->isar.id_aa64pfr1 = 0x0000000000000000;
453
- cpu->isar.id_aa64dfr0 = 0x0000000010305408;
454
- cpu->isar.id_aa64dfr1 = 0x0000000000000000;
455
- cpu->id_aa64afr0 = 0x0000000000000000;
456
- cpu->id_aa64afr1 = 0x0000000000000000;
457
- cpu->isar.id_aa64mmfr0 = 0x0000000000001122;
458
- cpu->isar.id_aa64mmfr1 = 0x0000000011212100;
459
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011;
460
- cpu->isar.id_aa64isar0 = 0x0000000010211120;
461
- cpu->isar.id_aa64isar1 = 0x0000000000010001;
462
- cpu->isar.id_aa64zfr0 = 0x0000000000000000;
463
- cpu->clidr = 0x0000000080000023;
464
- cpu->ccsidr[0] = 0x7007e01c; /* 64KB L1 dcache */
465
- cpu->ccsidr[1] = 0x2007e01c; /* 64KB L1 icache */
466
- cpu->ccsidr[2] = 0x70ffe07c; /* 8MB L2 cache */
467
- cpu->dcz_blocksize = 6; /* 256 bytes */
468
- cpu->gic_num_lrs = 4;
469
- cpu->gic_vpribits = 5;
470
- cpu->gic_vprebits = 5;
471
- cpu->gic_pribits = 5;
472
-
473
- /* The A64FX supports only 128, 256 and 512 bit vector lengths */
474
- aarch64_add_sve_properties(obj);
475
- cpu->sve_vq.supported = (1 << 0) /* 128bit */
476
- | (1 << 1) /* 256bit */
477
- | (1 << 3); /* 512bit */
478
-
479
- cpu->isar.reset_pmcr_el0 = 0x46014040;
480
-
481
- /* TODO: Add A64FX specific HPC extension registers */
482
-}
483
-
484
-static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
485
- { .name = "ATCR_EL1", .state = ARM_CP_STATE_AA64,
486
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 7, .opc2 = 0,
487
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
488
- { .name = "ATCR_EL2", .state = ARM_CP_STATE_AA64,
489
- .opc0 = 3, .opc1 = 4, .crn = 15, .crm = 7, .opc2 = 0,
490
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
491
- { .name = "ATCR_EL3", .state = ARM_CP_STATE_AA64,
492
- .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 7, .opc2 = 0,
493
- .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
494
- { .name = "ATCR_EL12", .state = ARM_CP_STATE_AA64,
495
- .opc0 = 3, .opc1 = 5, .crn = 15, .crm = 7, .opc2 = 0,
496
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
497
- { .name = "AVTCR_EL2", .state = ARM_CP_STATE_AA64,
498
- .opc0 = 3, .opc1 = 4, .crn = 15, .crm = 7, .opc2 = 1,
499
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
500
- { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
501
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 0,
502
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
503
- { .name = "CPUACTLR2_EL1", .state = ARM_CP_STATE_AA64,
504
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 1,
505
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
506
- { .name = "CPUACTLR3_EL1", .state = ARM_CP_STATE_AA64,
507
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 2,
508
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
509
- /*
510
- * Report CPUCFR_EL1.SCU as 1, as we do not implement the DSU
511
- * (and in particular its system registers).
512
- */
513
- { .name = "CPUCFR_EL1", .state = ARM_CP_STATE_AA64,
514
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
515
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 4 },
516
- { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
517
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 4,
518
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0x961563010 },
519
- { .name = "CPUPCR_EL3", .state = ARM_CP_STATE_AA64,
520
- .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 1,
521
- .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
522
- { .name = "CPUPMR_EL3", .state = ARM_CP_STATE_AA64,
523
- .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 3,
524
- .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
525
- { .name = "CPUPOR_EL3", .state = ARM_CP_STATE_AA64,
526
- .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 2,
527
- .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
528
- { .name = "CPUPSELR_EL3", .state = ARM_CP_STATE_AA64,
529
- .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 0,
530
- .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
531
- { .name = "CPUPWRCTLR_EL1", .state = ARM_CP_STATE_AA64,
532
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
533
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
534
- { .name = "ERXPFGCDN_EL1", .state = ARM_CP_STATE_AA64,
535
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 2,
536
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
537
- { .name = "ERXPFGCTL_EL1", .state = ARM_CP_STATE_AA64,
538
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 1,
539
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
540
- { .name = "ERXPFGF_EL1", .state = ARM_CP_STATE_AA64,
541
- .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
542
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
543
-};
544
-
545
-static void define_neoverse_n1_cp_reginfo(ARMCPU *cpu)
546
-{
547
- define_arm_cp_regs(cpu, neoverse_n1_cp_reginfo);
548
-}
549
-
550
-static void aarch64_neoverse_n1_initfn(Object *obj)
551
-{
552
- ARMCPU *cpu = ARM_CPU(obj);
553
-
554
- cpu->dtb_compatible = "arm,neoverse-n1";
555
- set_feature(&cpu->env, ARM_FEATURE_V8);
556
- set_feature(&cpu->env, ARM_FEATURE_NEON);
557
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
558
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
559
- set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
560
- set_feature(&cpu->env, ARM_FEATURE_EL2);
561
- set_feature(&cpu->env, ARM_FEATURE_EL3);
562
- set_feature(&cpu->env, ARM_FEATURE_PMU);
563
-
564
- /* Ordered by B2.4 AArch64 registers by functional group */
565
- cpu->clidr = 0x82000023;
566
- cpu->ctr = 0x8444c004;
567
- cpu->dcz_blocksize = 4;
568
- cpu->isar.id_aa64dfr0 = 0x0000000110305408ull;
569
- cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
570
- cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
571
- cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
572
- cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
573
- cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
574
- cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
575
- cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
576
- cpu->id_afr0 = 0x00000000;
577
- cpu->isar.id_dfr0 = 0x04010088;
578
- cpu->isar.id_isar0 = 0x02101110;
579
- cpu->isar.id_isar1 = 0x13112111;
580
- cpu->isar.id_isar2 = 0x21232042;
581
- cpu->isar.id_isar3 = 0x01112131;
582
- cpu->isar.id_isar4 = 0x00010142;
583
- cpu->isar.id_isar5 = 0x01011121;
584
- cpu->isar.id_isar6 = 0x00000010;
585
- cpu->isar.id_mmfr0 = 0x10201105;
586
- cpu->isar.id_mmfr1 = 0x40000000;
587
- cpu->isar.id_mmfr2 = 0x01260000;
588
- cpu->isar.id_mmfr3 = 0x02122211;
589
- cpu->isar.id_mmfr4 = 0x00021110;
590
- cpu->isar.id_pfr0 = 0x10010131;
591
- cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
592
- cpu->isar.id_pfr2 = 0x00000011;
593
- cpu->midr = 0x414fd0c1; /* r4p1 */
594
- cpu->revidr = 0;
595
-
596
- /* From B2.23 CCSIDR_EL1 */
597
- cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
598
- cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */
599
- cpu->ccsidr[2] = 0x70ffe03a; /* 1MB L2 cache */
600
-
601
- /* From B2.98 SCTLR_EL3 */
602
- cpu->reset_sctlr = 0x30c50838;
603
-
604
- /* From B4.23 ICH_VTR_EL2 */
605
- cpu->gic_num_lrs = 4;
606
- cpu->gic_vpribits = 5;
607
- cpu->gic_vprebits = 5;
608
- cpu->gic_pribits = 5;
609
-
610
- /* From B5.1 AdvSIMD AArch64 register summary */
611
- cpu->isar.mvfr0 = 0x10110222;
612
- cpu->isar.mvfr1 = 0x13211111;
613
- cpu->isar.mvfr2 = 0x00000043;
614
-
615
- /* From D5.1 AArch64 PMU register summary */
616
- cpu->isar.reset_pmcr_el0 = 0x410c3000;
617
-
618
- define_neoverse_n1_cp_reginfo(cpu);
619
-}
620
-
621
static void aarch64_host_initfn(Object *obj)
622
{
623
#if defined(CONFIG_KVM)
624
@@ -XXX,XX +XXX,XX @@ static void aarch64_host_initfn(Object *obj)
625
#endif
626
}
627
628
-/*
629
- * -cpu max: a CPU with as many features enabled as our emulation supports.
630
- * The version of '-cpu max' for qemu-system-arm is defined in cpu_tcg.c;
631
- * this only needs to handle 64 bits.
632
- */
633
-static void aarch64_max_tcg_initfn(Object *obj)
634
-{
635
- ARMCPU *cpu = ARM_CPU(obj);
636
- uint64_t t;
637
- uint32_t u;
638
-
639
- /*
640
- * Reset MIDR so the guest doesn't mistake our 'max' CPU type for a real
641
- * one and try to apply errata workarounds or use impdef features we
642
- * don't provide.
643
- * An IMPLEMENTER field of 0 means "reserved for software use";
644
- * ARCHITECTURE must be 0xf indicating "v7 or later, check ID registers
645
- * to see which features are present";
646
- * the VARIANT, PARTNUM and REVISION fields are all implementation
647
- * defined and we choose to define PARTNUM just in case guest
648
- * code needs to distinguish this QEMU CPU from other software
649
- * implementations, though this shouldn't be needed.
650
- */
651
- t = FIELD_DP64(0, MIDR_EL1, IMPLEMENTER, 0);
652
- t = FIELD_DP64(t, MIDR_EL1, ARCHITECTURE, 0xf);
653
- t = FIELD_DP64(t, MIDR_EL1, PARTNUM, 'Q');
654
- t = FIELD_DP64(t, MIDR_EL1, VARIANT, 0);
655
- t = FIELD_DP64(t, MIDR_EL1, REVISION, 0);
656
- cpu->midr = t;
657
-
658
- /*
659
- * We're going to set FEAT_S2FWB, which mandates that CLIDR_EL1.{LoUU,LoUIS}
660
- * are zero.
661
- */
662
- u = cpu->clidr;
663
- u = FIELD_DP32(u, CLIDR_EL1, LOUIS, 0);
664
- u = FIELD_DP32(u, CLIDR_EL1, LOUU, 0);
665
- cpu->clidr = u;
666
-
667
- t = cpu->isar.id_aa64isar0;
668
- t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
669
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
670
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
671
- t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
672
- t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); /* FEAT_LSE */
673
- t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); /* FEAT_RDM */
674
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); /* FEAT_SHA3 */
675
- t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1); /* FEAT_SM3 */
676
- t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1); /* FEAT_SM4 */
677
- t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1); /* FEAT_DotProd */
678
- t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1); /* FEAT_FHM */
679
- t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* FEAT_FlagM2 */
680
- t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
681
- t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */
682
- cpu->isar.id_aa64isar0 = t;
683
-
684
- t = cpu->isar.id_aa64isar1;
685
- t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
686
- t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); /* FEAT_JSCVT */
687
- t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); /* FEAT_FCMA */
688
- t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* FEAT_LRCPC2 */
689
- t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1); /* FEAT_FRINTTS */
690
- t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1); /* FEAT_SB */
691
- t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); /* FEAT_SPECRES */
692
- t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */
693
- t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */
694
- t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
695
- cpu->isar.id_aa64isar1 = t;
696
-
697
- t = cpu->isar.id_aa64pfr0;
698
- t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
699
- t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */
700
- t = FIELD_DP64(t, ID_AA64PFR0, RAS, 2); /* FEAT_RASv1p1 + FEAT_DoubleFault */
701
- t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
702
- t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
703
- t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
704
- t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
705
- t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
706
- cpu->isar.id_aa64pfr0 = t;
707
-
708
- t = cpu->isar.id_aa64pfr1;
709
- t = FIELD_DP64(t, ID_AA64PFR1, BT, 1); /* FEAT_BTI */
710
- t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); /* FEAT_SSBS2 */
711
- /*
712
- * Begin with full support for MTE. This will be downgraded to MTE=0
713
- * during realize if the board provides no tag memory, much like
714
- * we do for EL2 with the virtualization=on property.
715
- */
716
- t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
717
- t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0); /* FEAT_RASv1p1 + FEAT_DoubleFault */
718
- t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */
719
- t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
720
- cpu->isar.id_aa64pfr1 = t;
721
-
722
- t = cpu->isar.id_aa64mmfr0;
723
- t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
724
- t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */
725
- t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
726
- t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
727
- t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
728
- t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */
729
- cpu->isar.id_aa64mmfr0 = t;
730
-
731
- t = cpu->isar.id_aa64mmfr1;
732
- t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */
733
- t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
734
- t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
735
- t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
736
- t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
737
- t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 3); /* FEAT_PAN3 */
738
- t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
739
- t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1); /* FEAT_ETS */
740
- t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */
741
- cpu->isar.id_aa64mmfr1 = t;
742
-
743
- t = cpu->isar.id_aa64mmfr2;
744
- t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */
745
- t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
746
- t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
747
- t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
748
- t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
749
- t = FIELD_DP64(t, ID_AA64MMFR2, IDS, 1); /* FEAT_IDST */
750
- t = FIELD_DP64(t, ID_AA64MMFR2, FWB, 1); /* FEAT_S2FWB */
751
- t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
752
- t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
753
- t = FIELD_DP64(t, ID_AA64MMFR2, EVT, 2); /* FEAT_EVT */
754
- t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */
755
- cpu->isar.id_aa64mmfr2 = t;
756
-
757
- t = cpu->isar.id_aa64zfr0;
758
- t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
759
- t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */
760
- t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); /* FEAT_SVE_BitPerm */
761
- t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1); /* FEAT_BF16 */
762
- t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1); /* FEAT_SVE_SHA3 */
763
- t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1); /* FEAT_SVE_SM4 */
764
- t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); /* FEAT_I8MM */
765
- t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); /* FEAT_F32MM */
766
- t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */
767
- cpu->isar.id_aa64zfr0 = t;
768
-
769
- t = cpu->isar.id_aa64dfr0;
770
- t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */
771
- t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 6); /* FEAT_PMUv3p5 */
772
- cpu->isar.id_aa64dfr0 = t;
773
-
774
- t = cpu->isar.id_aa64smfr0;
775
- t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1); /* FEAT_SME */
776
- t = FIELD_DP64(t, ID_AA64SMFR0, B16F32, 1); /* FEAT_SME */
777
- t = FIELD_DP64(t, ID_AA64SMFR0, F16F32, 1); /* FEAT_SME */
778
- t = FIELD_DP64(t, ID_AA64SMFR0, I8I32, 0xf); /* FEAT_SME */
779
- t = FIELD_DP64(t, ID_AA64SMFR0, F64F64, 1); /* FEAT_SME_F64F64 */
780
- t = FIELD_DP64(t, ID_AA64SMFR0, I16I64, 0xf); /* FEAT_SME_I16I64 */
781
- t = FIELD_DP64(t, ID_AA64SMFR0, FA64, 1); /* FEAT_SME_FA64 */
782
- cpu->isar.id_aa64smfr0 = t;
783
-
784
- /* Replicate the same data to the 32-bit id registers. */
785
- aa32_max_features(cpu);
786
-
787
-#ifdef CONFIG_USER_ONLY
788
- /*
789
- * For usermode -cpu max we can use a larger and more efficient DCZ
790
- * blocksize since we don't have to follow what the hardware does.
791
- */
792
- cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
793
- cpu->dcz_blocksize = 7; /* 512 bytes */
794
-#endif
795
-
796
- cpu->sve_vq.supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
797
- cpu->sme_vq.supported = SVE_VQ_POW2_MAP;
798
-
799
- aarch64_add_pauth_properties(obj);
800
- aarch64_add_sve_properties(obj);
801
- aarch64_add_sme_properties(obj);
802
- object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
803
- cpu_max_set_sve_max_vq, NULL, NULL);
804
- qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
805
-}
806
-
88
static void aarch64_max_initfn(Object *obj)
807
static void aarch64_max_initfn(Object *obj)
89
{
808
{
90
ARMCPU *cpu = ARM_CPU(obj);
809
if (kvm_enabled() || hvf_enabled()) {
810
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
811
}
812
813
static const ARMCPUInfo aarch64_cpus[] = {
814
- { .name = "cortex-a35", .initfn = aarch64_a35_initfn },
815
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
816
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
817
- { .name = "cortex-a55", .initfn = aarch64_a55_initfn },
818
- { .name = "cortex-a72", .initfn = aarch64_a72_initfn },
819
- { .name = "cortex-a76", .initfn = aarch64_a76_initfn },
820
- { .name = "a64fx", .initfn = aarch64_a64fx_initfn },
821
- { .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
822
{ .name = "max", .initfn = aarch64_max_initfn },
823
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
824
{ .name = "host", .initfn = aarch64_host_initfn },
825
diff --git a/target/arm/cpu64.c b/target/arm/tcg/cpu64.c
826
similarity index 51%
827
copy from target/arm/cpu64.c
828
copy to target/arm/tcg/cpu64.c
829
index XXXXXXX..XXXXXXX 100644
830
--- a/target/arm/cpu64.c
831
+++ b/target/arm/tcg/cpu64.c
832
@@ -XXX,XX +XXX,XX @@
833
/*
834
- * QEMU AArch64 CPU
835
+ * QEMU AArch64 TCG CPUs
836
*
837
* Copyright (c) 2013 Linaro Ltd
838
*
839
@@ -XXX,XX +XXX,XX @@
840
#include "qemu/osdep.h"
841
#include "qapi/error.h"
842
#include "cpu.h"
843
-#include "cpregs.h"
844
#include "qemu/module.h"
845
-#include "sysemu/kvm.h"
846
-#include "sysemu/hvf.h"
847
-#include "sysemu/qtest.h"
848
-#include "sysemu/tcg.h"
849
-#include "kvm_arm.h"
850
-#include "hvf_arm.h"
851
#include "qapi/visitor.h"
852
#include "hw/qdev-properties.h"
853
#include "internals.h"
854
@@ -XXX,XX +XXX,XX @@ static void aarch64_a35_initfn(Object *obj)
855
define_cortex_a72_a57_a53_cp_reginfo(cpu);
856
}
857
858
-void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
859
-{
860
- /*
861
- * If any vector lengths are explicitly enabled with sve<N> properties,
862
- * then all other lengths are implicitly disabled. If sve-max-vq is
863
- * specified then it is the same as explicitly enabling all lengths
864
- * up to and including the specified maximum, which means all larger
865
- * lengths will be implicitly disabled. If no sve<N> properties
866
- * are enabled and sve-max-vq is not specified, then all lengths not
867
- * explicitly disabled will be enabled. Additionally, all power-of-two
868
- * vector lengths less than the maximum enabled length will be
869
- * automatically enabled and all vector lengths larger than the largest
870
- * disabled power-of-two vector length will be automatically disabled.
871
- * Errors are generated if the user provided input that interferes with
872
- * any of the above. Finally, if SVE is not disabled, then at least one
873
- * vector length must be enabled.
874
- */
875
- uint32_t vq_map = cpu->sve_vq.map;
876
- uint32_t vq_init = cpu->sve_vq.init;
877
- uint32_t vq_supported;
878
- uint32_t vq_mask = 0;
879
- uint32_t tmp, vq, max_vq = 0;
880
-
881
- /*
882
- * CPU models specify a set of supported vector lengths which are
883
- * enabled by default. Attempting to enable any vector length not set
884
- * in the supported bitmap results in an error. When KVM is enabled we
885
- * fetch the supported bitmap from the host.
886
- */
887
- if (kvm_enabled()) {
888
- if (kvm_arm_sve_supported()) {
889
- cpu->sve_vq.supported = kvm_arm_sve_get_vls(CPU(cpu));
890
- vq_supported = cpu->sve_vq.supported;
891
- } else {
892
- assert(!cpu_isar_feature(aa64_sve, cpu));
893
- vq_supported = 0;
894
- }
895
- } else {
896
- vq_supported = cpu->sve_vq.supported;
897
- }
898
-
899
- /*
900
- * Process explicit sve<N> properties.
901
- * From the properties, sve_vq_map<N> implies sve_vq_init<N>.
902
- * Check first for any sve<N> enabled.
903
- */
904
- if (vq_map != 0) {
905
- max_vq = 32 - clz32(vq_map);
906
- vq_mask = MAKE_64BIT_MASK(0, max_vq);
907
-
908
- if (cpu->sve_max_vq && max_vq > cpu->sve_max_vq) {
909
- error_setg(errp, "cannot enable sve%d", max_vq * 128);
910
- error_append_hint(errp, "sve%d is larger than the maximum vector "
911
- "length, sve-max-vq=%d (%d bits)\n",
912
- max_vq * 128, cpu->sve_max_vq,
913
- cpu->sve_max_vq * 128);
914
- return;
915
- }
916
-
917
- if (kvm_enabled()) {
918
- /*
919
- * For KVM we have to automatically enable all supported unitialized
920
- * lengths, even when the smaller lengths are not all powers-of-two.
921
- */
922
- vq_map |= vq_supported & ~vq_init & vq_mask;
923
- } else {
924
- /* Propagate enabled bits down through required powers-of-two. */
925
- vq_map |= SVE_VQ_POW2_MAP & ~vq_init & vq_mask;
926
- }
927
- } else if (cpu->sve_max_vq == 0) {
928
- /*
929
- * No explicit bits enabled, and no implicit bits from sve-max-vq.
930
- */
931
- if (!cpu_isar_feature(aa64_sve, cpu)) {
932
- /* SVE is disabled and so are all vector lengths. Good. */
933
- return;
934
- }
935
-
936
- if (kvm_enabled()) {
937
- /* Disabling a supported length disables all larger lengths. */
938
- tmp = vq_init & vq_supported;
939
- } else {
940
- /* Disabling a power-of-two disables all larger lengths. */
941
- tmp = vq_init & SVE_VQ_POW2_MAP;
942
- }
943
- vq = ctz32(tmp) + 1;
944
-
945
- max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
946
- vq_mask = MAKE_64BIT_MASK(0, max_vq);
947
- vq_map = vq_supported & ~vq_init & vq_mask;
948
-
949
- if (max_vq == 0 || vq_map == 0) {
950
- error_setg(errp, "cannot disable sve%d", vq * 128);
951
- error_append_hint(errp, "Disabling sve%d results in all "
952
- "vector lengths being disabled.\n",
953
- vq * 128);
954
- error_append_hint(errp, "With SVE enabled, at least one "
955
- "vector length must be enabled.\n");
956
- return;
957
- }
958
-
959
- max_vq = 32 - clz32(vq_map);
960
- vq_mask = MAKE_64BIT_MASK(0, max_vq);
961
- }
962
-
963
- /*
964
- * Process the sve-max-vq property.
965
- * Note that we know from the above that no bit above
966
- * sve-max-vq is currently set.
967
- */
968
- if (cpu->sve_max_vq != 0) {
969
- max_vq = cpu->sve_max_vq;
970
- vq_mask = MAKE_64BIT_MASK(0, max_vq);
971
-
972
- if (vq_init & ~vq_map & (1 << (max_vq - 1))) {
973
- error_setg(errp, "cannot disable sve%d", max_vq * 128);
974
- error_append_hint(errp, "The maximum vector length must be "
975
- "enabled, sve-max-vq=%d (%d bits)\n",
976
- max_vq, max_vq * 128);
977
- return;
978
- }
979
-
980
- /* Set all bits not explicitly set within sve-max-vq. */
981
- vq_map |= ~vq_init & vq_mask;
982
- }
983
-
984
- /*
985
- * We should know what max-vq is now. Also, as we're done
986
- * manipulating sve-vq-map, we ensure any bits above max-vq
987
- * are clear, just in case anybody looks.
988
- */
989
- assert(max_vq != 0);
990
- assert(vq_mask != 0);
991
- vq_map &= vq_mask;
992
-
993
- /* Ensure the set of lengths matches what is supported. */
994
- tmp = vq_map ^ (vq_supported & vq_mask);
995
- if (tmp) {
996
- vq = 32 - clz32(tmp);
997
- if (vq_map & (1 << (vq - 1))) {
998
- if (cpu->sve_max_vq) {
999
- error_setg(errp, "cannot set sve-max-vq=%d", cpu->sve_max_vq);
1000
- error_append_hint(errp, "This CPU does not support "
1001
- "the vector length %d-bits.\n", vq * 128);
1002
- error_append_hint(errp, "It may not be possible to use "
1003
- "sve-max-vq with this CPU. Try "
1004
- "using only sve<N> properties.\n");
1005
- } else {
1006
- error_setg(errp, "cannot enable sve%d", vq * 128);
1007
- if (vq_supported) {
1008
- error_append_hint(errp, "This CPU does not support "
1009
- "the vector length %d-bits.\n", vq * 128);
1010
- } else {
1011
- error_append_hint(errp, "SVE not supported by KVM "
1012
- "on this host\n");
1013
- }
1014
- }
1015
- return;
1016
- } else {
1017
- if (kvm_enabled()) {
1018
- error_setg(errp, "cannot disable sve%d", vq * 128);
1019
- error_append_hint(errp, "The KVM host requires all "
1020
- "supported vector lengths smaller "
1021
- "than %d bits to also be enabled.\n",
1022
- max_vq * 128);
1023
- return;
1024
- } else {
1025
- /* Ensure all required powers-of-two are enabled. */
1026
- tmp = SVE_VQ_POW2_MAP & vq_mask & ~vq_map;
1027
- if (tmp) {
1028
- vq = 32 - clz32(tmp);
1029
- error_setg(errp, "cannot disable sve%d", vq * 128);
1030
- error_append_hint(errp, "sve%d is required as it "
1031
- "is a power-of-two length smaller "
1032
- "than the maximum, sve%d\n",
1033
- vq * 128, max_vq * 128);
1034
- return;
1035
- }
1036
- }
1037
- }
1038
- }
1039
-
1040
- /*
1041
- * Now that we validated all our vector lengths, the only question
1042
- * left to answer is if we even want SVE at all.
1043
- */
1044
- if (!cpu_isar_feature(aa64_sve, cpu)) {
1045
- error_setg(errp, "cannot enable sve%d", max_vq * 128);
1046
- error_append_hint(errp, "SVE must be enabled to enable vector "
1047
- "lengths.\n");
1048
- error_append_hint(errp, "Add sve=on to the CPU property list.\n");
1049
- return;
1050
- }
1051
-
1052
- /* From now on sve_max_vq is the actual maximum supported length. */
1053
- cpu->sve_max_vq = max_vq;
1054
- cpu->sve_vq.map = vq_map;
1055
-}
1056
-
1057
static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
1058
void *opaque, Error **errp)
1059
{
1060
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
1061
cpu->sve_max_vq = max_vq;
1062
}
1063
1064
-/*
1065
- * Note that cpu_arm_{get,set}_vq cannot use the simpler
1066
- * object_property_add_bool interface because they make use of the
1067
- * contents of "name" to determine which bit on which to operate.
1068
- */
1069
-static void cpu_arm_get_vq(Object *obj, Visitor *v, const char *name,
1070
- void *opaque, Error **errp)
1071
-{
1072
- ARMCPU *cpu = ARM_CPU(obj);
1073
- ARMVQMap *vq_map = opaque;
1074
- uint32_t vq = atoi(&name[3]) / 128;
1075
- bool sve = vq_map == &cpu->sve_vq;
1076
- bool value;
1077
-
1078
- /* All vector lengths are disabled when feature is off. */
1079
- if (sve
1080
- ? !cpu_isar_feature(aa64_sve, cpu)
1081
- : !cpu_isar_feature(aa64_sme, cpu)) {
1082
- value = false;
1083
- } else {
1084
- value = extract32(vq_map->map, vq - 1, 1);
1085
- }
1086
- visit_type_bool(v, name, &value, errp);
1087
-}
1088
-
1089
-static void cpu_arm_set_vq(Object *obj, Visitor *v, const char *name,
1090
- void *opaque, Error **errp)
1091
-{
1092
- ARMVQMap *vq_map = opaque;
1093
- uint32_t vq = atoi(&name[3]) / 128;
1094
- bool value;
1095
-
1096
- if (!visit_type_bool(v, name, &value, errp)) {
1097
- return;
1098
- }
1099
-
1100
- vq_map->map = deposit32(vq_map->map, vq - 1, 1, value);
1101
- vq_map->init |= 1 << (vq - 1);
1102
-}
1103
-
1104
-static bool cpu_arm_get_sve(Object *obj, Error **errp)
1105
-{
1106
- ARMCPU *cpu = ARM_CPU(obj);
1107
- return cpu_isar_feature(aa64_sve, cpu);
1108
-}
1109
-
1110
-static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
1111
-{
1112
- ARMCPU *cpu = ARM_CPU(obj);
1113
- uint64_t t;
1114
-
1115
- if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
1116
- error_setg(errp, "'sve' feature not supported by KVM on this host");
1117
- return;
1118
- }
1119
-
1120
- t = cpu->isar.id_aa64pfr0;
1121
- t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
1122
- cpu->isar.id_aa64pfr0 = t;
1123
-}
1124
-
1125
-void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
1126
-{
1127
- uint32_t vq_map = cpu->sme_vq.map;
1128
- uint32_t vq_init = cpu->sme_vq.init;
1129
- uint32_t vq_supported = cpu->sme_vq.supported;
91
- uint32_t vq;
1130
- uint32_t vq;
1131
-
1132
- if (vq_map == 0) {
1133
- if (!cpu_isar_feature(aa64_sme, cpu)) {
1134
- cpu->isar.id_aa64smfr0 = 0;
1135
- return;
1136
- }
1137
-
1138
- /* TODO: KVM will require limitations via SMCR_EL2. */
1139
- vq_map = vq_supported & ~vq_init;
1140
-
1141
- if (vq_map == 0) {
1142
- vq = ctz32(vq_supported) + 1;
1143
- error_setg(errp, "cannot disable sme%d", vq * 128);
1144
- error_append_hint(errp, "All SME vector lengths are disabled.\n");
1145
- error_append_hint(errp, "With SME enabled, at least one "
1146
- "vector length must be enabled.\n");
1147
- return;
1148
- }
1149
- } else {
1150
- if (!cpu_isar_feature(aa64_sme, cpu)) {
1151
- vq = 32 - clz32(vq_map);
1152
- error_setg(errp, "cannot enable sme%d", vq * 128);
1153
- error_append_hint(errp, "SME must be enabled to enable "
1154
- "vector lengths.\n");
1155
- error_append_hint(errp, "Add sme=on to the CPU property list.\n");
1156
- return;
1157
- }
1158
- /* TODO: KVM will require limitations via SMCR_EL2. */
1159
- }
1160
-
1161
- cpu->sme_vq.map = vq_map;
1162
-}
1163
-
1164
-static bool cpu_arm_get_sme(Object *obj, Error **errp)
1165
-{
1166
- ARMCPU *cpu = ARM_CPU(obj);
1167
- return cpu_isar_feature(aa64_sme, cpu);
1168
-}
1169
-
1170
-static void cpu_arm_set_sme(Object *obj, bool value, Error **errp)
1171
-{
1172
- ARMCPU *cpu = ARM_CPU(obj);
92
- uint64_t t;
1173
- uint64_t t;
93
1174
-
94
if (kvm_enabled()) {
1175
- t = cpu->isar.id_aa64pfr1;
95
kvm_arm_set_cpu_features_from_host(cpu);
1176
- t = FIELD_DP64(t, ID_AA64PFR1, SME, value);
96
- if (kvm_arm_sve_supported(CPU(cpu))) {
1177
- cpu->isar.id_aa64pfr1 = t;
97
- t = cpu->isar.id_aa64pfr0;
1178
-}
98
- t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
1179
-
99
- cpu->isar.id_aa64pfr0 = t;
1180
-static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp)
1181
-{
1182
- ARMCPU *cpu = ARM_CPU(obj);
1183
- return cpu_isar_feature(aa64_sme, cpu) &&
1184
- cpu_isar_feature(aa64_sme_fa64, cpu);
1185
-}
1186
-
1187
-static void cpu_arm_set_sme_fa64(Object *obj, bool value, Error **errp)
1188
-{
1189
- ARMCPU *cpu = ARM_CPU(obj);
1190
- uint64_t t;
1191
-
1192
- t = cpu->isar.id_aa64smfr0;
1193
- t = FIELD_DP64(t, ID_AA64SMFR0, FA64, value);
1194
- cpu->isar.id_aa64smfr0 = t;
1195
-}
1196
-
1197
-#ifdef CONFIG_USER_ONLY
1198
-/* Mirror linux /proc/sys/abi/{sve,sme}_default_vector_length. */
1199
-static void cpu_arm_set_default_vec_len(Object *obj, Visitor *v,
1200
- const char *name, void *opaque,
1201
- Error **errp)
1202
-{
1203
- uint32_t *ptr_default_vq = opaque;
1204
- int32_t default_len, default_vq, remainder;
1205
-
1206
- if (!visit_type_int32(v, name, &default_len, errp)) {
1207
- return;
1208
- }
1209
-
1210
- /* Undocumented, but the kernel allows -1 to indicate "maximum". */
1211
- if (default_len == -1) {
1212
- *ptr_default_vq = ARM_MAX_VQ;
1213
- return;
1214
- }
1215
-
1216
- default_vq = default_len / 16;
1217
- remainder = default_len % 16;
1218
-
1219
- /*
1220
- * Note that the 512 max comes from include/uapi/asm/sve_context.h
1221
- * and is the maximum architectural width of ZCR_ELx.LEN.
1222
- */
1223
- if (remainder || default_vq < 1 || default_vq > 512) {
1224
- ARMCPU *cpu = ARM_CPU(obj);
1225
- const char *which =
1226
- (ptr_default_vq == &cpu->sve_default_vq ? "sve" : "sme");
1227
-
1228
- error_setg(errp, "cannot set %s-default-vector-length", which);
1229
- if (remainder) {
1230
- error_append_hint(errp, "Vector length not a multiple of 16\n");
1231
- } else if (default_vq < 1) {
1232
- error_append_hint(errp, "Vector length smaller than 16\n");
1233
- } else {
1234
- error_append_hint(errp, "Vector length larger than %d\n",
1235
- 512 * 16);
100
- }
1236
- }
101
} else {
1237
- return;
102
+ uint64_t t;
1238
- }
103
uint32_t u;
1239
-
104
aarch64_a57_initfn(obj);
1240
- *ptr_default_vq = default_vq;
105
1241
-}
106
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
1242
-
107
#endif
1243
-static void cpu_arm_get_default_vec_len(Object *obj, Visitor *v,
108
}
1244
- const char *name, void *opaque,
109
1245
- Error **errp)
110
- object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
1246
-{
111
- cpu_arm_set_sve, NULL, NULL, &error_fatal);
1247
- uint32_t *ptr_default_vq = opaque;
112
+ aarch64_add_sve_properties(obj);
1248
- int32_t value = *ptr_default_vq * 16;
113
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
1249
-
114
cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
1250
- visit_type_int32(v, name, &value, errp);
1251
-}
1252
-#endif
1253
-
1254
-static void aarch64_add_sve_properties(Object *obj)
1255
-{
1256
- ARMCPU *cpu = ARM_CPU(obj);
1257
- uint32_t vq;
1258
-
1259
- object_property_add_bool(obj, "sve", cpu_arm_get_sve, cpu_arm_set_sve);
115
-
1260
-
116
- for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
1261
- for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
117
- char name[8];
1262
- char name[8];
118
- sprintf(name, "sve%d", vq * 128);
1263
- sprintf(name, "sve%d", vq * 128);
119
- object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
1264
- object_property_add(obj, name, "bool", cpu_arm_get_vq,
120
- cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
1265
- cpu_arm_set_vq, NULL, &cpu->sve_vq);
121
- }
1266
- }
1267
-
1268
-#ifdef CONFIG_USER_ONLY
1269
- /* Mirror linux /proc/sys/abi/sve_default_vector_length. */
1270
- object_property_add(obj, "sve-default-vector-length", "int32",
1271
- cpu_arm_get_default_vec_len,
1272
- cpu_arm_set_default_vec_len, NULL,
1273
- &cpu->sve_default_vq);
1274
-#endif
1275
-}
1276
-
1277
-static void aarch64_add_sme_properties(Object *obj)
1278
-{
1279
- ARMCPU *cpu = ARM_CPU(obj);
1280
- uint32_t vq;
1281
-
1282
- object_property_add_bool(obj, "sme", cpu_arm_get_sme, cpu_arm_set_sme);
1283
- object_property_add_bool(obj, "sme_fa64", cpu_arm_get_sme_fa64,
1284
- cpu_arm_set_sme_fa64);
1285
-
1286
- for (vq = 1; vq <= ARM_MAX_VQ; vq <<= 1) {
1287
- char name[8];
1288
- sprintf(name, "sme%d", vq * 128);
1289
- object_property_add(obj, name, "bool", cpu_arm_get_vq,
1290
- cpu_arm_set_vq, NULL, &cpu->sme_vq);
1291
- }
1292
-
1293
-#ifdef CONFIG_USER_ONLY
1294
- /* Mirror linux /proc/sys/abi/sme_default_vector_length. */
1295
- object_property_add(obj, "sme-default-vector-length", "int32",
1296
- cpu_arm_get_default_vec_len,
1297
- cpu_arm_set_default_vec_len, NULL,
1298
- &cpu->sme_default_vq);
1299
-#endif
1300
-}
1301
-
1302
-void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
1303
-{
1304
- int arch_val = 0, impdef_val = 0;
1305
- uint64_t t;
1306
-
1307
- /* Exit early if PAuth is enabled, and fall through to disable it */
1308
- if ((kvm_enabled() || hvf_enabled()) && cpu->prop_pauth) {
1309
- if (!cpu_isar_feature(aa64_pauth, cpu)) {
1310
- error_setg(errp, "'pauth' feature not supported by %s on this host",
1311
- kvm_enabled() ? "KVM" : "hvf");
1312
- }
1313
-
1314
- return;
1315
- }
1316
-
1317
- /* TODO: Handle HaveEnhancedPAC, HaveEnhancedPAC2, HaveFPAC. */
1318
- if (cpu->prop_pauth) {
1319
- if (cpu->prop_pauth_impdef) {
1320
- impdef_val = 1;
1321
- } else {
1322
- arch_val = 1;
1323
- }
1324
- } else if (cpu->prop_pauth_impdef) {
1325
- error_setg(errp, "cannot enable pauth-impdef without pauth");
1326
- error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
1327
- }
1328
-
1329
- t = cpu->isar.id_aa64isar1;
1330
- t = FIELD_DP64(t, ID_AA64ISAR1, APA, arch_val);
1331
- t = FIELD_DP64(t, ID_AA64ISAR1, GPA, arch_val);
1332
- t = FIELD_DP64(t, ID_AA64ISAR1, API, impdef_val);
1333
- t = FIELD_DP64(t, ID_AA64ISAR1, GPI, impdef_val);
1334
- cpu->isar.id_aa64isar1 = t;
1335
-}
1336
-
1337
-static Property arm_cpu_pauth_property =
1338
- DEFINE_PROP_BOOL("pauth", ARMCPU, prop_pauth, true);
1339
-static Property arm_cpu_pauth_impdef_property =
1340
- DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
1341
-
1342
-static void aarch64_add_pauth_properties(Object *obj)
1343
-{
1344
- ARMCPU *cpu = ARM_CPU(obj);
1345
-
1346
- /* Default to PAUTH on, with the architected algorithm on TCG. */
1347
- qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_property);
1348
- if (kvm_enabled() || hvf_enabled()) {
1349
- /*
1350
- * Mirror PAuth support from the probed sysregs back into the
1351
- * property for KVM or hvf. Is it just a bit backward? Yes it is!
1352
- * Note that prop_pauth is true whether the host CPU supports the
1353
- * architected QARMA5 algorithm or the IMPDEF one. We don't
1354
- * provide the separate pauth-impdef property for KVM or hvf,
1355
- * only for TCG.
1356
- */
1357
- cpu->prop_pauth = cpu_isar_feature(aa64_pauth, cpu);
1358
- } else {
1359
- qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_impdef_property);
1360
- }
1361
-}
1362
-
1363
static Property arm_cpu_lpa2_property =
1364
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
1365
1366
-void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
1367
-{
1368
- uint64_t t;
1369
-
1370
- /*
1371
- * We only install the property for tcg -cpu max; this is the
1372
- * only situation in which the cpu field can be true.
1373
- */
1374
- if (!cpu->prop_lpa2) {
1375
- return;
1376
- }
1377
-
1378
- t = cpu->isar.id_aa64mmfr0;
1379
- t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2); /* 16k pages w/ LPA2 */
1380
- t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1); /* 4k pages w/ LPA2 */
1381
- t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3); /* 16k stage2 w/ LPA2 */
1382
- t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3); /* 4k stage2 w/ LPA2 */
1383
- cpu->isar.id_aa64mmfr0 = t;
1384
-}
1385
-
1386
-static void aarch64_a57_initfn(Object *obj)
1387
-{
1388
- ARMCPU *cpu = ARM_CPU(obj);
1389
-
1390
- cpu->dtb_compatible = "arm,cortex-a57";
1391
- set_feature(&cpu->env, ARM_FEATURE_V8);
1392
- set_feature(&cpu->env, ARM_FEATURE_NEON);
1393
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
1394
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
1395
- set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
1396
- set_feature(&cpu->env, ARM_FEATURE_EL2);
1397
- set_feature(&cpu->env, ARM_FEATURE_EL3);
1398
- set_feature(&cpu->env, ARM_FEATURE_PMU);
1399
- cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57;
1400
- cpu->midr = 0x411fd070;
1401
- cpu->revidr = 0x00000000;
1402
- cpu->reset_fpsid = 0x41034070;
1403
- cpu->isar.mvfr0 = 0x10110222;
1404
- cpu->isar.mvfr1 = 0x12111111;
1405
- cpu->isar.mvfr2 = 0x00000043;
1406
- cpu->ctr = 0x8444c004;
1407
- cpu->reset_sctlr = 0x00c50838;
1408
- cpu->isar.id_pfr0 = 0x00000131;
1409
- cpu->isar.id_pfr1 = 0x00011011;
1410
- cpu->isar.id_dfr0 = 0x03010066;
1411
- cpu->id_afr0 = 0x00000000;
1412
- cpu->isar.id_mmfr0 = 0x10101105;
1413
- cpu->isar.id_mmfr1 = 0x40000000;
1414
- cpu->isar.id_mmfr2 = 0x01260000;
1415
- cpu->isar.id_mmfr3 = 0x02102211;
1416
- cpu->isar.id_isar0 = 0x02101110;
1417
- cpu->isar.id_isar1 = 0x13112111;
1418
- cpu->isar.id_isar2 = 0x21232042;
1419
- cpu->isar.id_isar3 = 0x01112131;
1420
- cpu->isar.id_isar4 = 0x00011142;
1421
- cpu->isar.id_isar5 = 0x00011121;
1422
- cpu->isar.id_isar6 = 0;
1423
- cpu->isar.id_aa64pfr0 = 0x00002222;
1424
- cpu->isar.id_aa64dfr0 = 0x10305106;
1425
- cpu->isar.id_aa64isar0 = 0x00011120;
1426
- cpu->isar.id_aa64mmfr0 = 0x00001124;
1427
- cpu->isar.dbgdidr = 0x3516d000;
1428
- cpu->isar.dbgdevid = 0x01110f13;
1429
- cpu->isar.dbgdevid1 = 0x2;
1430
- cpu->isar.reset_pmcr_el0 = 0x41013000;
1431
- cpu->clidr = 0x0a200023;
1432
- cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
1433
- cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
1434
- cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
1435
- cpu->dcz_blocksize = 4; /* 64 bytes */
1436
- cpu->gic_num_lrs = 4;
1437
- cpu->gic_vpribits = 5;
1438
- cpu->gic_vprebits = 5;
1439
- cpu->gic_pribits = 5;
1440
- define_cortex_a72_a57_a53_cp_reginfo(cpu);
1441
-}
1442
-
1443
-static void aarch64_a53_initfn(Object *obj)
1444
-{
1445
- ARMCPU *cpu = ARM_CPU(obj);
1446
-
1447
- cpu->dtb_compatible = "arm,cortex-a53";
1448
- set_feature(&cpu->env, ARM_FEATURE_V8);
1449
- set_feature(&cpu->env, ARM_FEATURE_NEON);
1450
- set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
1451
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
1452
- set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
1453
- set_feature(&cpu->env, ARM_FEATURE_EL2);
1454
- set_feature(&cpu->env, ARM_FEATURE_EL3);
1455
- set_feature(&cpu->env, ARM_FEATURE_PMU);
1456
- cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A53;
1457
- cpu->midr = 0x410fd034;
1458
- cpu->revidr = 0x00000000;
1459
- cpu->reset_fpsid = 0x41034070;
1460
- cpu->isar.mvfr0 = 0x10110222;
1461
- cpu->isar.mvfr1 = 0x12111111;
1462
- cpu->isar.mvfr2 = 0x00000043;
1463
- cpu->ctr = 0x84448004; /* L1Ip = VIPT */
1464
- cpu->reset_sctlr = 0x00c50838;
1465
- cpu->isar.id_pfr0 = 0x00000131;
1466
- cpu->isar.id_pfr1 = 0x00011011;
1467
- cpu->isar.id_dfr0 = 0x03010066;
1468
- cpu->id_afr0 = 0x00000000;
1469
- cpu->isar.id_mmfr0 = 0x10101105;
1470
- cpu->isar.id_mmfr1 = 0x40000000;
1471
- cpu->isar.id_mmfr2 = 0x01260000;
1472
- cpu->isar.id_mmfr3 = 0x02102211;
1473
- cpu->isar.id_isar0 = 0x02101110;
1474
- cpu->isar.id_isar1 = 0x13112111;
1475
- cpu->isar.id_isar2 = 0x21232042;
1476
- cpu->isar.id_isar3 = 0x01112131;
1477
- cpu->isar.id_isar4 = 0x00011142;
1478
- cpu->isar.id_isar5 = 0x00011121;
1479
- cpu->isar.id_isar6 = 0;
1480
- cpu->isar.id_aa64pfr0 = 0x00002222;
1481
- cpu->isar.id_aa64dfr0 = 0x10305106;
1482
- cpu->isar.id_aa64isar0 = 0x00011120;
1483
- cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
1484
- cpu->isar.dbgdidr = 0x3516d000;
1485
- cpu->isar.dbgdevid = 0x00110f13;
1486
- cpu->isar.dbgdevid1 = 0x1;
1487
- cpu->isar.reset_pmcr_el0 = 0x41033000;
1488
- cpu->clidr = 0x0a200023;
1489
- cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
1490
- cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
1491
- cpu->ccsidr[2] = 0x707fe07a; /* 1024KB L2 cache */
1492
- cpu->dcz_blocksize = 4; /* 64 bytes */
1493
- cpu->gic_num_lrs = 4;
1494
- cpu->gic_vpribits = 5;
1495
- cpu->gic_vprebits = 5;
1496
- cpu->gic_pribits = 5;
1497
- define_cortex_a72_a57_a53_cp_reginfo(cpu);
1498
-}
1499
-
1500
static void aarch64_a55_initfn(Object *obj)
1501
{
1502
ARMCPU *cpu = ARM_CPU(obj);
1503
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n1_initfn(Object *obj)
1504
define_neoverse_n1_cp_reginfo(cpu);
122
}
1505
}
123
1506
124
struct ARMCPUInfo {
1507
-static void aarch64_host_initfn(Object *obj)
125
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
1508
-{
1509
-#if defined(CONFIG_KVM)
1510
- ARMCPU *cpu = ARM_CPU(obj);
1511
- kvm_arm_set_cpu_features_from_host(cpu);
1512
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
1513
- aarch64_add_sve_properties(obj);
1514
- aarch64_add_pauth_properties(obj);
1515
- }
1516
-#elif defined(CONFIG_HVF)
1517
- ARMCPU *cpu = ARM_CPU(obj);
1518
- hvf_arm_set_cpu_features_from_host(cpu);
1519
- aarch64_add_pauth_properties(obj);
1520
-#else
1521
- g_assert_not_reached();
1522
-#endif
1523
-}
1524
-
1525
/*
1526
* -cpu max: a CPU with as many features enabled as our emulation supports.
1527
* The version of '-cpu max' for qemu-system-arm is defined in cpu_tcg.c;
1528
* this only needs to handle 64 bits.
1529
*/
1530
-static void aarch64_max_tcg_initfn(Object *obj)
1531
+void aarch64_max_tcg_initfn(Object *obj)
1532
{
1533
ARMCPU *cpu = ARM_CPU(obj);
1534
uint64_t t;
1535
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_tcg_initfn(Object *obj)
1536
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
1537
}
1538
1539
-static void aarch64_max_initfn(Object *obj)
1540
-{
1541
- if (kvm_enabled() || hvf_enabled()) {
1542
- /* With KVM or HVF, '-cpu max' is identical to '-cpu host' */
1543
- aarch64_host_initfn(obj);
1544
- return;
1545
- }
1546
-
1547
- if (tcg_enabled() || qtest_enabled()) {
1548
- aarch64_a57_initfn(obj);
1549
- }
1550
-
1551
- /* '-cpu max' for TCG: we currently do this as "A57 with extra things" */
1552
- if (tcg_enabled()) {
1553
- aarch64_max_tcg_initfn(obj);
1554
- }
1555
-}
1556
-
1557
static const ARMCPUInfo aarch64_cpus[] = {
1558
{ .name = "cortex-a35", .initfn = aarch64_a35_initfn },
1559
- { .name = "cortex-a57", .initfn = aarch64_a57_initfn },
1560
- { .name = "cortex-a53", .initfn = aarch64_a53_initfn },
1561
{ .name = "cortex-a55", .initfn = aarch64_a55_initfn },
1562
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
1563
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
1564
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
1565
{ .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
1566
- { .name = "max", .initfn = aarch64_max_initfn },
1567
-#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
1568
- { .name = "host", .initfn = aarch64_host_initfn },
1569
-#endif
1570
-};
1571
-
1572
-static bool aarch64_cpu_get_aarch64(Object *obj, Error **errp)
1573
-{
1574
- ARMCPU *cpu = ARM_CPU(obj);
1575
-
1576
- return arm_feature(&cpu->env, ARM_FEATURE_AARCH64);
1577
-}
1578
-
1579
-static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
1580
-{
1581
- ARMCPU *cpu = ARM_CPU(obj);
1582
-
1583
- /* At this time, this property is only allowed if KVM is enabled. This
1584
- * restriction allows us to avoid fixing up functionality that assumes a
1585
- * uniform execution state like do_interrupt.
1586
- */
1587
- if (value == false) {
1588
- if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
1589
- error_setg(errp, "'aarch64' feature cannot be disabled "
1590
- "unless KVM is enabled and 32-bit EL1 "
1591
- "is supported");
1592
- return;
1593
- }
1594
- unset_feature(&cpu->env, ARM_FEATURE_AARCH64);
1595
- } else {
1596
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
1597
- }
1598
-}
1599
-
1600
-static void aarch64_cpu_finalizefn(Object *obj)
1601
-{
1602
-}
1603
-
1604
-static gchar *aarch64_gdb_arch_name(CPUState *cs)
1605
-{
1606
- return g_strdup("aarch64");
1607
-}
1608
-
1609
-static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
1610
-{
1611
- CPUClass *cc = CPU_CLASS(oc);
1612
-
1613
- cc->gdb_read_register = aarch64_cpu_gdb_read_register;
1614
- cc->gdb_write_register = aarch64_cpu_gdb_write_register;
1615
- cc->gdb_num_core_regs = 34;
1616
- cc->gdb_core_xml_file = "aarch64-core.xml";
1617
- cc->gdb_arch_name = aarch64_gdb_arch_name;
1618
-
1619
- object_class_property_add_bool(oc, "aarch64", aarch64_cpu_get_aarch64,
1620
- aarch64_cpu_set_aarch64);
1621
- object_class_property_set_description(oc, "aarch64",
1622
- "Set on/off to enable/disable aarch64 "
1623
- "execution state ");
1624
-}
1625
-
1626
-static void aarch64_cpu_instance_init(Object *obj)
1627
-{
1628
- ARMCPUClass *acc = ARM_CPU_GET_CLASS(obj);
1629
-
1630
- acc->info->initfn(obj);
1631
- arm_cpu_post_init(obj);
1632
-}
1633
-
1634
-static void cpu_register_class_init(ObjectClass *oc, void *data)
1635
-{
1636
- ARMCPUClass *acc = ARM_CPU_CLASS(oc);
1637
-
1638
- acc->info = data;
1639
-}
1640
-
1641
-void aarch64_cpu_register(const ARMCPUInfo *info)
1642
-{
1643
- TypeInfo type_info = {
1644
- .parent = TYPE_AARCH64_CPU,
1645
- .instance_size = sizeof(ARMCPU),
1646
- .instance_init = aarch64_cpu_instance_init,
1647
- .class_size = sizeof(ARMCPUClass),
1648
- .class_init = info->class_init ?: cpu_register_class_init,
1649
- .class_data = (void *)info,
1650
- };
1651
-
1652
- type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
1653
- type_register(&type_info);
1654
- g_free((void *)type_info.name);
1655
-}
1656
-
1657
-static const TypeInfo aarch64_cpu_type_info = {
1658
- .name = TYPE_AARCH64_CPU,
1659
- .parent = TYPE_ARM_CPU,
1660
- .instance_size = sizeof(ARMCPU),
1661
- .instance_finalize = aarch64_cpu_finalizefn,
1662
- .abstract = true,
1663
- .class_size = sizeof(AArch64CPUClass),
1664
- .class_init = aarch64_cpu_class_init,
1665
};
1666
1667
static void aarch64_cpu_register_types(void)
1668
{
1669
size_t i;
1670
1671
- type_register_static(&aarch64_cpu_type_info);
1672
-
1673
for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
1674
aarch64_cpu_register(&aarch64_cpus[i]);
1675
}
1676
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
126
index XXXXXXX..XXXXXXX 100644
1677
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/kvm64.c
1678
--- a/target/arm/tcg/meson.build
128
+++ b/target/arm/kvm64.c
1679
+++ b/target/arm/tcg/meson.build
129
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
1680
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
130
* and then query that CPU for the relevant ID registers.
1681
))
131
*/
1682
132
int fdarray[3];
1683
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
133
+ bool sve_supported;
1684
+ 'cpu64.c',
134
uint64_t features = 0;
1685
'translate-a64.c',
135
+ uint64_t t;
1686
'translate-sve.c',
136
int err;
1687
'translate-sme.c',
137
138
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
139
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
140
ARM64_SYS_REG(3, 0, 0, 3, 2));
141
}
142
143
+ sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 0;
144
+
145
kvm_arm_destroy_scratch_host_vcpu(fdarray);
146
147
if (err < 0) {
148
return false;
149
}
150
151
- /* We can assume any KVM supporting CPU is at least a v8
152
+ /* Add feature bits that can't appear until after VCPU init. */
153
+ if (sve_supported) {
154
+ t = ahcf->isar.id_aa64pfr0;
155
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
156
+ ahcf->isar.id_aa64pfr0 = t;
157
+ }
158
+
159
+ /*
160
+ * We can assume any KVM supporting CPU is at least a v8
161
* with VFPv4+Neon; this in turn implies most of the other
162
* feature bits.
163
*/
164
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/tests/arm-cpu-features.c
167
+++ b/tests/arm-cpu-features.c
168
@@ -XXX,XX +XXX,XX @@ static void sve_tests_sve_off_kvm(const void *data)
169
{
170
QTestState *qts;
171
172
- qts = qtest_init(MACHINE "-accel kvm -cpu max,sve=off");
173
+ qts = qtest_init(MACHINE "-accel kvm -cpu host,sve=off");
174
175
/*
176
* We don't know if this host supports SVE so we don't
177
@@ -XXX,XX +XXX,XX @@ static void sve_tests_sve_off_kvm(const void *data)
178
* and that using sve<N>=off to explicitly disable vector
179
* lengths is OK too.
180
*/
181
- assert_sve_vls(qts, "max", 0, NULL);
182
- assert_sve_vls(qts, "max", 0, "{ 'sve128': false }");
183
+ assert_sve_vls(qts, "host", 0, NULL);
184
+ assert_sve_vls(qts, "host", 0, "{ 'sve128': false }");
185
186
qtest_quit(qts);
187
}
188
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
189
"We cannot guarantee the CPU type 'cortex-a15' works "
190
"with KVM on this host", NULL);
191
192
- assert_has_feature(qts, "max", "sve");
193
- resp = do_query_no_props(qts, "max");
194
+ assert_has_feature(qts, "host", "sve");
195
+ resp = do_query_no_props(qts, "host");
196
kvm_supports_sve = resp_get_feature(resp, "sve");
197
vls = resp_get_sve_vls(resp);
198
qobject_unref(resp);
199
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
200
sprintf(max_name, "sve%d", max_vq * 128);
201
202
/* Enabling a supported length is of course fine. */
203
- assert_sve_vls(qts, "max", vls, "{ %s: true }", max_name);
204
+ assert_sve_vls(qts, "host", vls, "{ %s: true }", max_name);
205
206
/* Get the next supported length smaller than max-vq. */
207
vq = 64 - __builtin_clzll(vls & ~BIT_ULL(max_vq - 1));
208
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
209
* We have at least one length smaller than max-vq,
210
* so we can disable max-vq.
211
*/
212
- assert_sve_vls(qts, "max", (vls & ~BIT_ULL(max_vq - 1)),
213
+ assert_sve_vls(qts, "host", (vls & ~BIT_ULL(max_vq - 1)),
214
"{ %s: false }", max_name);
215
216
/*
217
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
218
*/
219
sprintf(name, "sve%d", vq * 128);
220
error = g_strdup_printf("cannot disable %s", name);
221
- assert_error(qts, "max", error,
222
+ assert_error(qts, "host", error,
223
"{ %s: true, %s: false }",
224
max_name, name);
225
g_free(error);
226
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
227
vq = __builtin_ffsll(vls);
228
sprintf(name, "sve%d", vq * 128);
229
error = g_strdup_printf("cannot disable %s", name);
230
- assert_error(qts, "max", error, "{ %s: false }", name);
231
+ assert_error(qts, "host", error, "{ %s: false }", name);
232
g_free(error);
233
234
/* Get an unsupported length. */
235
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
236
if (vq <= SVE_MAX_VQ) {
237
sprintf(name, "sve%d", vq * 128);
238
error = g_strdup_printf("cannot enable %s", name);
239
- assert_error(qts, "max", error, "{ %s: true }", name);
240
+ assert_error(qts, "host", error, "{ %s: true }", name);
241
g_free(error);
242
}
243
} else {
244
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
245
} else {
246
assert_has_not_feature(qts, "host", "aarch64");
247
assert_has_not_feature(qts, "host", "pmu");
248
-
249
- assert_has_not_feature(qts, "max", "sve");
250
+ assert_has_not_feature(qts, "host", "sve");
251
}
252
253
qtest_quit(qts);
254
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
255
index XXXXXXX..XXXXXXX 100644
256
--- a/docs/arm-cpu-features.rst
257
+++ b/docs/arm-cpu-features.rst
258
@@ -XXX,XX +XXX,XX @@ SVE CPU Property Examples
259
260
$ qemu-system-aarch64 -M virt -cpu max
261
262
- 3) Only enable the 128-bit vector length::
263
+ 3) When KVM is enabled, implicitly enable all host CPU supported vector
264
+ lengths with the `host` CPU type::
265
+
266
+ $ qemu-system-aarch64 -M virt,accel=kvm -cpu host
267
+
268
+ 4) Only enable the 128-bit vector length::
269
270
$ qemu-system-aarch64 -M virt -cpu max,sve128=on
271
272
- 4) Disable the 512-bit vector length and all larger vector lengths,
273
+ 5) Disable the 512-bit vector length and all larger vector lengths,
274
since 512 is a power-of-two. This results in all the smaller,
275
uninitialized lengths (128, 256, and 384) defaulting to enabled::
276
277
$ qemu-system-aarch64 -M virt -cpu max,sve512=off
278
279
- 5) Enable the 128-bit, 256-bit, and 512-bit vector lengths::
280
+ 6) Enable the 128-bit, 256-bit, and 512-bit vector lengths::
281
282
$ qemu-system-aarch64 -M virt -cpu max,sve128=on,sve256=on,sve512=on
283
284
- 6) The same as (5), but since the 128-bit and 256-bit vector
285
+ 7) The same as (6), but since the 128-bit and 256-bit vector
286
lengths are required for the 512-bit vector length to be enabled,
287
then allow them to be auto-enabled::
288
289
$ qemu-system-aarch64 -M virt -cpu max,sve512=on
290
291
- 7) Do the same as (6), but by first disabling SVE and then re-enabling it::
292
+ 8) Do the same as (7), but by first disabling SVE and then re-enabling it::
293
294
$ qemu-system-aarch64 -M virt -cpu max,sve=off,sve512=on,sve=on
295
296
- 8) Force errors regarding the last vector length::
297
+ 9) Force errors regarding the last vector length::
298
299
$ qemu-system-aarch64 -M virt -cpu max,sve128=off
300
$ qemu-system-aarch64 -M virt -cpu max,sve=off,sve128=off,sve=on
301
@@ -XXX,XX +XXX,XX @@ The examples in "SVE CPU Property Examples" exhibit many ways to select
302
vector lengths which developers may find useful in order to avoid overly
303
verbose command lines. However, the recommended way to select vector
304
lengths is to explicitly enable each desired length. Therefore only
305
-example's (1), (3), and (5) exhibit recommended uses of the properties.
306
+example's (1), (4), and (6) exhibit recommended uses of the properties.
307
308
--
1688
--
309
2.20.1
1689
2.34.1
310
1690
311
1691
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Continue setting, but not relying upon, env->hflags.
3
We're about to move the 32-bit CPUs under CONFIG_TCG, so adjust the
4
query-cpu-model-expansion test to check against the cortex-a7, which
5
is already under CONFIG_TCG. That allows the next patch to contain
6
only code movement. (All the test cares about is that the CPU type
7
it's checking is one which definitely doesn't work under KVM.)
4
8
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
While here add comments clarifying what we're testing.
6
Message-id: 20191023150057.25731-24-richard.henderson@linaro.org
10
11
Signed-off-by: Fabiano Rosas <farosas@suse.de>
12
Acked-by: Thomas Huth <thuth@redhat.com>
13
Message-id: 20230426180013.14814-7-farosas@suse.de
14
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
17
---
10
linux-user/arm/cpu_loop.c | 1 +
18
tests/qtest/arm-cpu-features.c | 20 +++++++++++++++++---
11
1 file changed, 1 insertion(+)
19
1 file changed, 17 insertions(+), 3 deletions(-)
12
20
13
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
21
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/arm/cpu_loop.c
23
--- a/tests/qtest/arm-cpu-features.c
16
+++ b/linux-user/arm/cpu_loop.c
24
+++ b/tests/qtest/arm-cpu-features.c
17
@@ -XXX,XX +XXX,XX @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
25
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
18
} else {
26
QDict *resp;
19
env->cp15.sctlr_el[1] |= SCTLR_B;
27
char *error;
20
}
28
21
+ arm_rebuild_hflags(env);
29
- assert_error(qts, "cortex-a15",
22
#endif
30
- "We cannot guarantee the CPU type 'cortex-a15' works "
23
31
- "with KVM on this host", NULL);
24
ts->stack_base = info->start_stack;
32
+ /*
33
+ * When using KVM, only the 'host' and 'max' CPU models are
34
+ * supported. Test that we're emitting a suitable error for
35
+ * unsupported CPU models.
36
+ */
37
+ if (qtest_has_accel("tcg")) {
38
+ assert_error(qts, "cortex-a7",
39
+ "We cannot guarantee the CPU type 'cortex-a7' works "
40
+ "with KVM on this host", NULL);
41
+ } else {
42
+ /*
43
+ * With a KVM-only build the 32-bit CPUs are not present.
44
+ */
45
+ assert_error(qts, "cortex-a7",
46
+ "The CPU type 'cortex-a7' is not a "
47
+ "recognized ARM CPU type", NULL);
48
+ }
49
50
assert_has_feature_enabled(qts, "host", "aarch64");
51
25
--
52
--
26
2.20.1
53
2.34.1
27
54
28
55
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Claudio Fontana <cfontana@suse.de>
2
2
3
Continue setting, but not relying upon, env->hflags.
3
move the module containing cpu models definitions
4
for 32bit TCG-only CPUs to tcg/ and rename it for clarity.
4
5
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Claudio Fontana <cfontana@suse.de>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Fabiano Rosas <farosas@suse.de>
7
Message-id: 20191023150057.25731-21-richard.henderson@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Acked-by: Thomas Huth <thuth@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20230426180013.14814-8-farosas@suse.de
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
target/arm/m_helper.c | 6 ++++++
14
hw/arm/virt.c | 2 --
11
target/arm/translate.c | 5 ++++-
15
target/arm/{cpu_tcg.c => tcg/cpu32.c} | 13 +++----------
12
2 files changed, 10 insertions(+), 1 deletion(-)
16
target/arm/tcg/cpu64.c | 2 +-
17
target/arm/meson.build | 1 -
18
target/arm/tcg/meson.build | 1 +
19
5 files changed, 5 insertions(+), 14 deletions(-)
20
rename target/arm/{cpu_tcg.c => tcg/cpu32.c} (99%)
13
21
14
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
22
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/m_helper.c
24
--- a/hw/arm/virt.c
17
+++ b/target/arm/m_helper.c
25
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
26
@@ -XXX,XX +XXX,XX @@ static const int a15irqmap[] = {
19
switch_v7m_security_state(env, dest & 1);
27
static const char *valid_cpus[] = {
20
env->thumb = 1;
28
#ifdef CONFIG_TCG
21
env->regs[15] = dest & ~1;
29
ARM_CPU_TYPE_NAME("cortex-a7"),
22
+ arm_rebuild_hflags(env);
30
-#endif
31
ARM_CPU_TYPE_NAME("cortex-a15"),
32
-#ifdef CONFIG_TCG
33
ARM_CPU_TYPE_NAME("cortex-a35"),
34
ARM_CPU_TYPE_NAME("cortex-a55"),
35
ARM_CPU_TYPE_NAME("cortex-a72"),
36
diff --git a/target/arm/cpu_tcg.c b/target/arm/tcg/cpu32.c
37
similarity index 99%
38
rename from target/arm/cpu_tcg.c
39
rename to target/arm/tcg/cpu32.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/cpu_tcg.c
42
+++ b/target/arm/tcg/cpu32.c
43
@@ -XXX,XX +XXX,XX @@
44
/*
45
- * QEMU ARM TCG CPUs.
46
+ * QEMU ARM TCG-only CPUs.
47
*
48
* Copyright (c) 2012 SUSE LINUX Products GmbH
49
*
50
@@ -XXX,XX +XXX,XX @@
51
52
#include "qemu/osdep.h"
53
#include "cpu.h"
54
-#ifdef CONFIG_TCG
55
#include "hw/core/tcg-cpu-ops.h"
56
-#endif /* CONFIG_TCG */
57
#include "internals.h"
58
#include "target/arm/idau.h"
59
#if !defined(CONFIG_USER_ONLY)
60
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
61
/* CPU models. These are not needed for the AArch64 linux-user build. */
62
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
63
64
-#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
65
+#if !defined(CONFIG_USER_ONLY)
66
static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
67
{
68
CPUClass *cc = CPU_GET_CLASS(cs);
69
@@ -XXX,XX +XXX,XX @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
70
}
71
return ret;
23
}
72
}
24
73
-#endif /* !CONFIG_USER_ONLY && CONFIG_TCG */
25
void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
74
+#endif /* !CONFIG_USER_ONLY */
26
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
75
27
switch_v7m_security_state(env, 0);
76
static void arm926_initfn(Object *obj)
28
env->thumb = 1;
77
{
29
env->regs[15] = dest;
78
@@ -XXX,XX +XXX,XX @@ static void pxa270c5_initfn(Object *obj)
30
+ arm_rebuild_hflags(env);
79
cpu->reset_sctlr = 0x00000078;
31
}
80
}
32
81
33
static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
82
-#ifdef CONFIG_TCG
34
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
83
static const struct TCGCPUOps arm_v7m_tcg_ops = {
35
env->regs[14] = lr;
84
.initialize = arm_translate_init,
36
env->regs[15] = addr & 0xfffffffe;
85
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
37
env->thumb = addr & 1;
86
@@ -XXX,XX +XXX,XX @@ static const struct TCGCPUOps arm_v7m_tcg_ops = {
38
+ arm_rebuild_hflags(env);
87
.debug_check_breakpoint = arm_debug_check_breakpoint,
88
#endif /* !CONFIG_USER_ONLY */
89
};
90
-#endif /* CONFIG_TCG */
91
92
static void arm_v7m_class_init(ObjectClass *oc, void *data)
93
{
94
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
95
CPUClass *cc = CPU_CLASS(oc);
96
97
acc->info = data;
98
-#ifdef CONFIG_TCG
99
cc->tcg_ops = &arm_v7m_tcg_ops;
100
-#endif /* CONFIG_TCG */
101
-
102
cc->gdb_core_xml_file = "arm-m-profile.xml";
39
}
103
}
40
104
41
static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
105
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
43
44
/* Otherwise, we have a successful exception exit. */
45
arm_clear_exclusive(env);
46
+ arm_rebuild_hflags(env);
47
qemu_log_mask(CPU_LOG_INT, "...successful exception return\n");
48
}
49
50
@@ -XXX,XX +XXX,XX @@ static bool do_v7m_function_return(ARMCPU *cpu)
51
xpsr_write(env, 0, XPSR_IT);
52
env->thumb = newpc & 1;
53
env->regs[15] = newpc & ~1;
54
+ arm_rebuild_hflags(env);
55
56
qemu_log_mask(CPU_LOG_INT, "...function return successful\n");
57
return true;
58
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
59
switch_v7m_security_state(env, true);
60
xpsr_write(env, 0, XPSR_IT);
61
env->regs[15] += 4;
62
+ arm_rebuild_hflags(env);
63
return true;
64
65
gen_invep:
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
106
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
107
--- a/target/arm/tcg/cpu64.c
69
+++ b/target/arm/translate.c
108
+++ b/target/arm/tcg/cpu64.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
109
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n1_initfn(Object *obj)
71
110
72
static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
111
/*
73
{
112
* -cpu max: a CPU with as many features enabled as our emulation supports.
74
- TCGv_i32 addr, reg;
113
- * The version of '-cpu max' for qemu-system-arm is defined in cpu_tcg.c;
75
+ TCGv_i32 addr, reg, el;
114
+ * The version of '-cpu max' for qemu-system-arm is defined in cpu32.c;
76
115
* this only needs to handle 64 bits.
77
if (!arm_dc_feature(s, ARM_FEATURE_M)) {
116
*/
78
return false;
117
void aarch64_max_tcg_initfn(Object *obj)
79
@@ -XXX,XX +XXX,XX @@ static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
118
diff --git a/target/arm/meson.build b/target/arm/meson.build
80
gen_helper_v7m_msr(cpu_env, addr, reg);
119
index XXXXXXX..XXXXXXX 100644
81
tcg_temp_free_i32(addr);
120
--- a/target/arm/meson.build
82
tcg_temp_free_i32(reg);
121
+++ b/target/arm/meson.build
83
+ el = tcg_const_i32(s->current_el);
122
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
84
+ gen_helper_rebuild_hflags_m32(cpu_env, el);
123
'gdbstub.c',
85
+ tcg_temp_free_i32(el);
124
'helper.c',
86
gen_lookup_tb(s);
125
'vfp_helper.c',
87
return true;
126
- 'cpu_tcg.c',
88
}
127
))
128
arm_ss.add(zlib)
129
130
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/tcg/meson.build
133
+++ b/target/arm/tcg/meson.build
134
@@ -XXX,XX +XXX,XX @@ gen = [
135
arm_ss.add(gen)
136
137
arm_ss.add(files(
138
+ 'cpu32.c',
139
'translate.c',
140
'translate-m-nocp.c',
141
'translate-mve.c',
89
--
142
--
90
2.20.1
143
2.34.1
91
144
92
145
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
These are the SVE equivalents to kvm_arch_get/put_fpsimd. Note, the
3
It is possible to have a build with both TCG and KVM disabled due to
4
swabbing is different than it is for fpsmid because the vector format
4
Xen requiring the i386 and x86_64 binaries to be present in an aarch64
5
is a little-endian stream of words.
5
host.
6
6
7
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
If we build with --disable-tcg on the aarch64 host, we will end-up
8
with a QEMU binary (x86) that does not support TCG nor KVM.
9
10
Skip tests that crash or hang in the above scenario. Do not include
11
any test cases if TCG and KVM are missing.
12
13
Make sure that calls to qtest_has_accel are placed after g_test_init
14
in similar fashion to commit ae4b01b349 ("tests: Ensure TAP version is
15
printed before other messages") to avoid TAP parsing errors.
16
17
Reviewed-by: Juan Quintela <quintela@redhat.com>
18
Reviewed-by: Thomas Huth <thuth@redhat.com>
19
Signed-off-by: Fabiano Rosas <farosas@suse.de>
20
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
23
Message-id: 20230426180013.14814-9-farosas@suse.de
11
Message-id: 20191024121808.9612-6-drjones@redhat.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
25
---
14
target/arm/kvm64.c | 185 ++++++++++++++++++++++++++++++++++++++-------
26
tests/qtest/bios-tables-test.c | 11 +++++++++--
15
1 file changed, 156 insertions(+), 29 deletions(-)
27
tests/qtest/boot-serial-test.c | 5 +++++
28
tests/qtest/migration-test.c | 9 ++++++++-
29
tests/qtest/pxe-test.c | 8 +++++++-
30
tests/qtest/vmgenid-test.c | 9 +++++++--
31
5 files changed, 36 insertions(+), 6 deletions(-)
16
32
17
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
33
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
18
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/kvm64.c
35
--- a/tests/qtest/bios-tables-test.c
20
+++ b/target/arm/kvm64.c
36
+++ b/tests/qtest/bios-tables-test.c
21
@@ -XXX,XX +XXX,XX @@ int kvm_arch_destroy_vcpu(CPUState *cs)
37
@@ -XXX,XX +XXX,XX @@ static void test_acpi_virt_oem_fields(void)
22
bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
38
int main(int argc, char *argv[])
23
{
39
{
24
/* Return true if the regidx is a register we should synchronize
40
const char *arch = qtest_get_arch();
25
- * via the cpreg_tuples array (ie is not a core reg we sync by
41
- const bool has_kvm = qtest_has_accel("kvm");
26
- * hand in kvm_arch_get/put_registers())
42
- const bool has_tcg = qtest_has_accel("tcg");
27
+ * via the cpreg_tuples array (ie is not a core or sve reg that
43
+ bool has_kvm, has_tcg;
28
+ * we sync by hand in kvm_arch_get/put_registers())
44
char *v_env = getenv("V");
29
*/
45
int ret;
30
switch (regidx & KVM_REG_ARM_COPROC_MASK) {
46
31
case KVM_REG_ARM_CORE:
47
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
32
+ case KVM_REG_ARM64_SVE:
48
33
return false;
49
g_test_init(&argc, &argv, NULL);
34
default:
50
35
return true;
51
+ has_kvm = qtest_has_accel("kvm");
36
@@ -XXX,XX +XXX,XX @@ int kvm_arm_cpreg_level(uint64_t regidx)
52
+ has_tcg = qtest_has_accel("tcg");
37
38
static int kvm_arch_put_fpsimd(CPUState *cs)
39
{
40
- ARMCPU *cpu = ARM_CPU(cs);
41
- CPUARMState *env = &cpu->env;
42
+ CPUARMState *env = &ARM_CPU(cs)->env;
43
struct kvm_one_reg reg;
44
- uint32_t fpr;
45
int i, ret;
46
47
for (i = 0; i < 32; i++) {
48
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_fpsimd(CPUState *cs)
49
}
50
}
51
52
- reg.addr = (uintptr_t)(&fpr);
53
- fpr = vfp_get_fpsr(env);
54
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
55
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
56
- if (ret) {
57
- return ret;
58
+ return 0;
59
+}
60
+
53
+
61
+/*
54
+ if (!has_tcg && !has_kvm) {
62
+ * SVE registers are encoded in KVM's memory in an endianness-invariant format.
55
+ g_test_skip("No KVM or TCG accelerator available");
63
+ * The byte at offset i from the start of the in-memory representation contains
56
+ return 0;
64
+ * the bits [(7 + 8 * i) : (8 * i)] of the register value. As this means the
65
+ * lowest offsets are stored in the lowest memory addresses, then that nearly
66
+ * matches QEMU's representation, which is to use an array of host-endian
67
+ * uint64_t's, where the lower offsets are at the lower indices. To complete
68
+ * the translation we just need to byte swap the uint64_t's on big-endian hosts.
69
+ */
70
+static uint64_t *sve_bswap64(uint64_t *dst, uint64_t *src, int nr)
71
+{
72
+#ifdef HOST_WORDS_BIGENDIAN
73
+ int i;
74
+
75
+ for (i = 0; i < nr; ++i) {
76
+ dst[i] = bswap64(src[i]);
77
}
78
79
- reg.addr = (uintptr_t)(&fpr);
80
- fpr = vfp_get_fpcr(env);
81
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
82
+ return dst;
83
+#else
84
+ return src;
85
+#endif
86
+}
87
+
88
+/*
89
+ * KVM SVE registers come in slices where ZREGs have a slice size of 2048 bits
90
+ * and PREGS and the FFR have a slice size of 256 bits. However we simply hard
91
+ * code the slice index to zero for now as it's unlikely we'll need more than
92
+ * one slice for quite some time.
93
+ */
94
+static int kvm_arch_put_sve(CPUState *cs)
95
+{
96
+ ARMCPU *cpu = ARM_CPU(cs);
97
+ CPUARMState *env = &cpu->env;
98
+ uint64_t tmp[ARM_MAX_VQ * 2];
99
+ uint64_t *r;
100
+ struct kvm_one_reg reg;
101
+ int n, ret;
102
+
103
+ for (n = 0; n < KVM_ARM64_SVE_NUM_ZREGS; ++n) {
104
+ r = sve_bswap64(tmp, &env->vfp.zregs[n].d[0], cpu->sve_max_vq * 2);
105
+ reg.addr = (uintptr_t)r;
106
+ reg.id = KVM_REG_ARM64_SVE_ZREG(n, 0);
107
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
108
+ if (ret) {
109
+ return ret;
110
+ }
111
+ }
57
+ }
112
+
58
+
113
+ for (n = 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) {
59
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
114
+ r = sve_bswap64(tmp, r = &env->vfp.pregs[n].p[0],
60
ret = boot_sector_init(disk);
115
+ DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
61
if (ret) {
116
+ reg.addr = (uintptr_t)r;
62
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
117
+ reg.id = KVM_REG_ARM64_SVE_PREG(n, 0);
63
index XXXXXXX..XXXXXXX 100644
118
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
64
--- a/tests/qtest/boot-serial-test.c
119
+ if (ret) {
65
+++ b/tests/qtest/boot-serial-test.c
120
+ return ret;
66
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
121
+ }
67
68
g_test_init(&argc, &argv, NULL);
69
70
+ if (!qtest_has_accel("tcg") && !qtest_has_accel("kvm")) {
71
+ g_test_skip("No KVM or TCG accelerator available");
72
+ return 0;
122
+ }
73
+ }
123
+
74
+
124
+ r = sve_bswap64(tmp, &env->vfp.pregs[FFR_PRED_NUM].p[0],
75
for (i = 0; tests[i].arch != NULL; i++) {
125
+ DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
76
if (g_str_equal(arch, tests[i].arch) &&
126
+ reg.addr = (uintptr_t)r;
77
qtest_has_machine(tests[i].machine)) {
127
+ reg.id = KVM_REG_ARM64_SVE_FFR(0);
78
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
128
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
79
index XXXXXXX..XXXXXXX 100644
129
if (ret) {
80
--- a/tests/qtest/migration-test.c
130
return ret;
81
+++ b/tests/qtest/migration-test.c
131
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
82
@@ -XXX,XX +XXX,XX @@ static bool kvm_dirty_ring_supported(void)
83
84
int main(int argc, char **argv)
132
{
85
{
133
struct kvm_one_reg reg;
86
- bool has_kvm;
134
uint64_t val;
87
+ bool has_kvm, has_tcg;
135
+ uint32_t fpr;
88
bool has_uffd;
136
int i, ret;
89
const char *arch;
137
unsigned int el;
90
g_autoptr(GError) err = NULL;
138
91
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
139
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
92
g_test_init(&argc, &argv, NULL);
140
}
93
141
}
94
has_kvm = qtest_has_accel("kvm");
142
95
+ has_tcg = qtest_has_accel("tcg");
143
- ret = kvm_arch_put_fpsimd(cs);
96
+
144
+ if (cpu_isar_feature(aa64_sve, cpu)) {
97
+ if (!has_tcg && !has_kvm) {
145
+ ret = kvm_arch_put_sve(cs);
98
+ g_test_skip("No KVM or TCG accelerator available");
146
+ } else {
99
+ return 0;
147
+ ret = kvm_arch_put_fpsimd(cs);
148
+ }
149
+ if (ret) {
150
+ return ret;
151
+ }
100
+ }
152
+
101
+
153
+ reg.addr = (uintptr_t)(&fpr);
102
has_uffd = ufd_version_check();
154
+ fpr = vfp_get_fpsr(env);
103
arch = qtest_get_arch();
155
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
104
156
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
105
diff --git a/tests/qtest/pxe-test.c b/tests/qtest/pxe-test.c
157
+ if (ret) {
106
index XXXXXXX..XXXXXXX 100644
158
+ return ret;
107
--- a/tests/qtest/pxe-test.c
108
+++ b/tests/qtest/pxe-test.c
109
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
110
int ret;
111
const char *arch = qtest_get_arch();
112
113
+ g_test_init(&argc, &argv, NULL);
114
+
115
+ if (!qtest_has_accel("tcg") && !qtest_has_accel("kvm")) {
116
+ g_test_skip("No KVM or TCG accelerator available");
117
+ return 0;
159
+ }
118
+ }
160
+
119
+
161
+ reg.addr = (uintptr_t)(&fpr);
120
ret = boot_sector_init(disk);
162
+ fpr = vfp_get_fpcr(env);
121
if(ret)
163
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
122
return ret;
164
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
123
124
- g_test_init(&argc, &argv, NULL);
125
126
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
127
test_batch(x86_tests, false);
128
diff --git a/tests/qtest/vmgenid-test.c b/tests/qtest/vmgenid-test.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/tests/qtest/vmgenid-test.c
131
+++ b/tests/qtest/vmgenid-test.c
132
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
133
{
134
int ret;
135
136
+ g_test_init(&argc, &argv, NULL);
137
+
138
+ if (!qtest_has_accel("tcg") && !qtest_has_accel("kvm")) {
139
+ g_test_skip("No KVM or TCG accelerator available");
140
+ return 0;
141
+ }
142
+
143
ret = boot_sector_init(disk);
165
if (ret) {
144
if (ret) {
166
return ret;
145
return ret;
167
}
146
}
168
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
147
169
148
- g_test_init(&argc, &argv, NULL);
170
static int kvm_arch_get_fpsimd(CPUState *cs)
149
-
171
{
150
qtest_add_func("/vmgenid/vmgenid/set-guid",
172
- ARMCPU *cpu = ARM_CPU(cs);
151
vmgenid_set_guid_test);
173
- CPUARMState *env = &cpu->env;
152
qtest_add_func("/vmgenid/vmgenid/set-guid-auto",
174
+ CPUARMState *env = &ARM_CPU(cs)->env;
175
struct kvm_one_reg reg;
176
- uint32_t fpr;
177
int i, ret;
178
179
for (i = 0; i < 32; i++) {
180
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_fpsimd(CPUState *cs)
181
}
182
}
183
184
- reg.addr = (uintptr_t)(&fpr);
185
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
186
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
187
- if (ret) {
188
- return ret;
189
- }
190
- vfp_set_fpsr(env, fpr);
191
+ return 0;
192
+}
193
194
- reg.addr = (uintptr_t)(&fpr);
195
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
196
+/*
197
+ * KVM SVE registers come in slices where ZREGs have a slice size of 2048 bits
198
+ * and PREGS and the FFR have a slice size of 256 bits. However we simply hard
199
+ * code the slice index to zero for now as it's unlikely we'll need more than
200
+ * one slice for quite some time.
201
+ */
202
+static int kvm_arch_get_sve(CPUState *cs)
203
+{
204
+ ARMCPU *cpu = ARM_CPU(cs);
205
+ CPUARMState *env = &cpu->env;
206
+ struct kvm_one_reg reg;
207
+ uint64_t *r;
208
+ int n, ret;
209
+
210
+ for (n = 0; n < KVM_ARM64_SVE_NUM_ZREGS; ++n) {
211
+ r = &env->vfp.zregs[n].d[0];
212
+ reg.addr = (uintptr_t)r;
213
+ reg.id = KVM_REG_ARM64_SVE_ZREG(n, 0);
214
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
215
+ if (ret) {
216
+ return ret;
217
+ }
218
+ sve_bswap64(r, r, cpu->sve_max_vq * 2);
219
+ }
220
+
221
+ for (n = 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) {
222
+ r = &env->vfp.pregs[n].p[0];
223
+ reg.addr = (uintptr_t)r;
224
+ reg.id = KVM_REG_ARM64_SVE_PREG(n, 0);
225
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
226
+ if (ret) {
227
+ return ret;
228
+ }
229
+ sve_bswap64(r, r, DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
230
+ }
231
+
232
+ r = &env->vfp.pregs[FFR_PRED_NUM].p[0];
233
+ reg.addr = (uintptr_t)r;
234
+ reg.id = KVM_REG_ARM64_SVE_FFR(0);
235
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
236
if (ret) {
237
return ret;
238
}
239
- vfp_set_fpcr(env, fpr);
240
+ sve_bswap64(r, r, DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
241
242
return 0;
243
}
244
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
245
struct kvm_one_reg reg;
246
uint64_t val;
247
unsigned int el;
248
+ uint32_t fpr;
249
int i, ret;
250
251
ARMCPU *cpu = ARM_CPU(cs);
252
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
253
env->spsr = env->banked_spsr[i];
254
}
255
256
- ret = kvm_arch_get_fpsimd(cs);
257
+ if (cpu_isar_feature(aa64_sve, cpu)) {
258
+ ret = kvm_arch_get_sve(cs);
259
+ } else {
260
+ ret = kvm_arch_get_fpsimd(cs);
261
+ }
262
if (ret) {
263
return ret;
264
}
265
266
+ reg.addr = (uintptr_t)(&fpr);
267
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
268
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
269
+ if (ret) {
270
+ return ret;
271
+ }
272
+ vfp_set_fpsr(env, fpr);
273
+
274
+ reg.addr = (uintptr_t)(&fpr);
275
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
276
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
277
+ if (ret) {
278
+ return ret;
279
+ }
280
+ vfp_set_fpcr(env, fpr);
281
+
282
ret = kvm_get_vcpu_events(cpu);
283
if (ret) {
284
return ret;
285
--
153
--
286
2.20.1
154
2.34.1
287
155
288
156
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
As we are going to add more core-specific fields, add a 'cpu'
3
The migration tests are currently broken for an aarch64 host because
4
structure and move the ARMCPU field there as 'core'.
4
the tests pass no 'machine' and 'cpu' options on the QEMU command
5
line.
5
6
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Add a separate class to each architecture so that we can specify
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
'machine' and 'cpu' options instead of relying on defaults.
8
Message-id: 20191019234715.25750-7-f4bug@amsat.org
9
10
Add a skip decorator to keep the current behavior of only running
11
migration tests when the qemu target matches the host architecture.
12
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Signed-off-by: Fabiano Rosas <farosas@suse.de>
15
Message-id: 20230426180013.14814-10-farosas@suse.de
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
include/hw/arm/bcm2836.h | 4 +++-
18
tests/avocado/migration.py | 83 +++++++++++++++++++++++++++++++++++---
12
hw/arm/bcm2836.c | 26 ++++++++++++++------------
19
1 file changed, 78 insertions(+), 5 deletions(-)
13
2 files changed, 17 insertions(+), 13 deletions(-)
14
20
15
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
21
diff --git a/tests/avocado/migration.py b/tests/avocado/migration.py
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/bcm2836.h
23
--- a/tests/avocado/migration.py
18
+++ b/include/hw/arm/bcm2836.h
24
+++ b/tests/avocado/migration.py
19
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XState {
25
@@ -XXX,XX +XXX,XX @@
20
char *cpu_type;
26
21
uint32_t enabled_cpus;
27
22
28
import tempfile
23
- ARMCPU cpus[BCM283X_NCPUS];
29
+import os
24
+ struct {
30
+
25
+ ARMCPU core;
31
from avocado_qemu import QemuSystemTest
26
+ } cpu[BCM283X_NCPUS];
32
from avocado import skipUnless
27
BCM2836ControlState control;
33
28
BCM2835PeripheralState peripherals;
34
@@ -XXX,XX +XXX,XX @@
29
} BCM283XState;
35
from avocado.utils.path import find_command
30
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
36
31
index XXXXXXX..XXXXXXX 100644
37
32
--- a/hw/arm/bcm2836.c
38
-class Migration(QemuSystemTest):
33
+++ b/hw/arm/bcm2836.c
39
+class MigrationTest(QemuSystemTest):
34
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
40
"""
35
int n;
41
:avocado: tags=migration
36
42
"""
37
for (n = 0; n < BCM283X_NCPUS; n++) {
43
@@ -XXX,XX +XXX,XX @@ def _get_free_port(self):
38
- object_initialize_child(obj, "cpu[*]", &s->cpus[n], sizeof(s->cpus[n]),
44
self.cancel('Failed to find a free port')
39
- info->cpu_type, &error_abort, NULL);
45
return port
40
+ object_initialize_child(obj, "cpu[*]", &s->cpu[n].core,
46
41
+ sizeof(s->cpu[n].core), info->cpu_type,
47
-
42
+ &error_abort, NULL);
48
- def test_migration_with_tcp_localhost(self):
43
}
49
+ def migration_with_tcp_localhost(self):
44
50
dest_uri = 'tcp:localhost:%u' % self._get_free_port()
45
sysbus_init_child_obj(obj, "control", &s->control, sizeof(s->control),
51
self.do_migrate(dest_uri)
46
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
52
47
53
- def test_migration_with_unix(self):
48
for (n = 0; n < BCM283X_NCPUS; n++) {
54
+ def migration_with_unix(self):
49
/* TODO: this should be converted to a property of ARM_CPU */
55
with tempfile.TemporaryDirectory(prefix='socket_') as socket_path:
50
- s->cpus[n].mp_affinity = (info->clusterid << 8) | n;
56
dest_uri = 'unix:%s/qemu-test.sock' % socket_path
51
+ s->cpu[n].core.mp_affinity = (info->clusterid << 8) | n;
57
self.do_migrate(dest_uri)
52
58
53
/* set periphbase/CBAR value for CPU-local registers */
59
@skipUnless(find_command('nc', default=False), "'nc' command not found")
54
- object_property_set_int(OBJECT(&s->cpus[n]),
60
- def test_migration_with_exec(self):
55
+ object_property_set_int(OBJECT(&s->cpu[n].core),
61
+ def migration_with_exec(self):
56
info->peri_base,
62
"""The test works for both netcat-traditional and netcat-openbsd packages."""
57
"reset-cbar", &err);
63
free_port = self._get_free_port()
58
if (err) {
64
dest_uri = 'exec:nc -l localhost %u' % free_port
59
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
65
src_uri = 'exec:nc localhost %u' % free_port
60
}
66
self.do_migrate(dest_uri, src_uri)
61
67
+
62
/* start powered off if not enabled */
68
+
63
- object_property_set_bool(OBJECT(&s->cpus[n]), n >= s->enabled_cpus,
69
+@skipUnless('aarch64' in os.uname()[4], "host != target")
64
+ object_property_set_bool(OBJECT(&s->cpu[n].core), n >= s->enabled_cpus,
70
+class Aarch64(MigrationTest):
65
"start-powered-off", &err);
71
+ """
66
if (err) {
72
+ :avocado: tags=arch:aarch64
67
error_propagate(errp, err);
73
+ :avocado: tags=machine:virt
68
return;
74
+ :avocado: tags=cpu:max
69
}
75
+ """
70
76
+
71
- object_property_set_bool(OBJECT(&s->cpus[n]), true, "realized", &err);
77
+ def test_migration_with_tcp_localhost(self):
72
+ object_property_set_bool(OBJECT(&s->cpu[n].core), true,
78
+ self.migration_with_tcp_localhost()
73
+ "realized", &err);
79
+
74
if (err) {
80
+ def test_migration_with_unix(self):
75
error_propagate(errp, err);
81
+ self.migration_with_unix()
76
return;
82
+
77
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
83
+ def test_migration_with_exec(self):
78
84
+ self.migration_with_exec()
79
/* Connect irq/fiq outputs from the interrupt controller. */
85
+
80
qdev_connect_gpio_out_named(DEVICE(&s->control), "irq", n,
86
+
81
- qdev_get_gpio_in(DEVICE(&s->cpus[n]), ARM_CPU_IRQ));
87
+@skipUnless('x86_64' in os.uname()[4], "host != target")
82
+ qdev_get_gpio_in(DEVICE(&s->cpu[n].core), ARM_CPU_IRQ));
88
+class X86_64(MigrationTest):
83
qdev_connect_gpio_out_named(DEVICE(&s->control), "fiq", n,
89
+ """
84
- qdev_get_gpio_in(DEVICE(&s->cpus[n]), ARM_CPU_FIQ));
90
+ :avocado: tags=arch:x86_64
85
+ qdev_get_gpio_in(DEVICE(&s->cpu[n].core), ARM_CPU_FIQ));
91
+ :avocado: tags=machine:pc
86
92
+ :avocado: tags=cpu:qemu64
87
/* Connect timers from the CPU to the interrupt controller */
93
+ """
88
- qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_PHYS,
94
+
89
+ qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_PHYS,
95
+ def test_migration_with_tcp_localhost(self):
90
qdev_get_gpio_in_named(DEVICE(&s->control), "cntpnsirq", n));
96
+ self.migration_with_tcp_localhost()
91
- qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_VIRT,
97
+
92
+ qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_VIRT,
98
+ def test_migration_with_unix(self):
93
qdev_get_gpio_in_named(DEVICE(&s->control), "cntvirq", n));
99
+ self.migration_with_unix()
94
- qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_HYP,
100
+
95
+ qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_HYP,
101
+ def test_migration_with_exec(self):
96
qdev_get_gpio_in_named(DEVICE(&s->control), "cnthpirq", n));
102
+ self.migration_with_exec()
97
- qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_SEC,
103
+
98
+ qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_SEC,
104
+
99
qdev_get_gpio_in_named(DEVICE(&s->control), "cntpsirq", n));
105
+@skipUnless('ppc64le' in os.uname()[4], "host != target")
100
}
106
+class PPC64(MigrationTest):
101
}
107
+ """
108
+ :avocado: tags=arch:ppc64
109
+ :avocado: tags=machine:pseries
110
+ :avocado: tags=cpu:power9_v2.0
111
+ """
112
+
113
+ def test_migration_with_tcp_localhost(self):
114
+ self.migration_with_tcp_localhost()
115
+
116
+ def test_migration_with_unix(self):
117
+ self.migration_with_unix()
118
+
119
+ def test_migration_with_exec(self):
120
+ self.migration_with_exec()
121
+
122
+
123
+@skipUnless('s390x' in os.uname()[4], "host != target")
124
+class S390X(MigrationTest):
125
+ """
126
+ :avocado: tags=arch:s390x
127
+ :avocado: tags=machine:s390-ccw-virtio
128
+ :avocado: tags=cpu:qemu
129
+ """
130
+
131
+ def test_migration_with_tcp_localhost(self):
132
+ self.migration_with_tcp_localhost()
133
+
134
+ def test_migration_with_unix(self):
135
+ self.migration_with_unix()
136
+
137
+ def test_migration_with_exec(self):
138
+ self.migration_with_exec()
102
--
139
--
103
2.20.1
140
2.34.1
104
141
105
142
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
This file creates the BCM2836/BCM2837 blocks.
3
We are about to enable the build without TCG, so CONFIG_SEMIHOSTING
4
The biggest differences with the BCM2838 we are going to add, are
4
and CONFIG_ARM_COMPATIBLE_SEMIHOSTING cannot be unconditionally set in
5
the base addresses of the interrupt controller and the peripherals.
5
default.mak anymore. So reflect the change in a Kconfig.
6
Add these addresses in the BCM283XInfo structure to make this
7
block more modular. Remove the MCORE_OFFSET offset as it is
8
not useful and rather confusing.
9
6
10
Reviewed-by: Esteban Bosse <estebanbosse@gmail.com>
7
Instead of using semihosting/Kconfig, use a target-specific file, so
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
that the change doesn't affect other architectures which might
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
implement semihosting in a way compatible with KVM.
13
Message-id: 20191019234715.25750-6-f4bug@amsat.org
10
11
The selection from ARM_v7M needs to be removed to avoid a cycle during
12
parsing.
13
14
Signed-off-by: Fabiano Rosas <farosas@suse.de>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20230426180013.14814-11-farosas@suse.de
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
18
---
16
hw/arm/bcm2836.c | 18 +++++++++---------
19
configs/devices/arm-softmmu/default.mak | 2 --
17
1 file changed, 9 insertions(+), 9 deletions(-)
20
hw/arm/Kconfig | 1 -
21
target/arm/Kconfig | 7 +++++++
22
3 files changed, 7 insertions(+), 3 deletions(-)
18
23
19
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
24
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/bcm2836.c
26
--- a/configs/devices/arm-softmmu/default.mak
22
+++ b/hw/arm/bcm2836.c
27
+++ b/configs/devices/arm-softmmu/default.mak
23
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ CONFIG_MICROBIT=y
24
#include "hw/arm/raspi_platform.h"
29
CONFIG_FSL_IMX25=y
25
#include "hw/sysbus.h"
30
CONFIG_FSL_IMX7=y
26
31
CONFIG_FSL_IMX6UL=y
27
-/* Peripheral base address seen by the CPU */
32
-CONFIG_SEMIHOSTING=y
28
-#define BCM2836_PERI_BASE 0x3F000000
33
-CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
29
-
34
CONFIG_ALLWINNER_H3=y
30
-/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
35
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
31
-#define BCM2836_CONTROL_BASE 0x40000000
36
index XXXXXXX..XXXXXXX 100644
32
-
37
--- a/hw/arm/Kconfig
33
struct BCM283XInfo {
38
+++ b/hw/arm/Kconfig
34
const char *name;
39
@@ -XXX,XX +XXX,XX @@ config ARM_V7M
35
const char *cpu_type;
40
# currently v7M must be included in a TCG build due to translate.c
36
+ hwaddr peri_base; /* Peripheral base address seen by the CPU */
41
default y if TCG && (ARM || AARCH64)
37
+ hwaddr ctrl_base; /* Interrupt controller and mailboxes etc. */
42
select PTIMER
38
int clusterid;
43
- select ARM_COMPATIBLE_SEMIHOSTING
39
};
44
40
45
config ALLWINNER_A10
41
@@ -XXX,XX +XXX,XX @@ static const BCM283XInfo bcm283x_socs[] = {
46
bool
42
{
47
diff --git a/target/arm/Kconfig b/target/arm/Kconfig
43
.name = TYPE_BCM2836,
48
index XXXXXXX..XXXXXXX 100644
44
.cpu_type = ARM_CPU_TYPE_NAME("cortex-a7"),
49
--- a/target/arm/Kconfig
45
+ .peri_base = 0x3f000000,
50
+++ b/target/arm/Kconfig
46
+ .ctrl_base = 0x40000000,
51
@@ -XXX,XX +XXX,XX @@ config ARM
47
.clusterid = 0xf,
52
config AARCH64
48
},
53
bool
49
#ifdef TARGET_AARCH64
54
select ARM
50
{
55
+
51
.name = TYPE_BCM2837,
56
+# This config exists just so we can make SEMIHOSTING default when TCG
52
.cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
57
+# is selected without also changing it for other architectures.
53
+ .peri_base = 0x3f000000,
58
+config ARM_SEMIHOSTING
54
+ .ctrl_base = 0x40000000,
59
+ bool
55
.clusterid = 0x0,
60
+ default y if TCG && ARM
56
},
61
+ select ARM_COMPATIBLE_SEMIHOSTING
57
#endif
58
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
59
}
60
61
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
62
- BCM2836_PERI_BASE, 1);
63
+ info->peri_base, 1);
64
65
/* bcm2836 interrupt controller (and mailboxes, etc.) */
66
object_property_set_bool(OBJECT(&s->control), true, "realized", &err);
67
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
68
return;
69
}
70
71
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->control), 0, BCM2836_CONTROL_BASE);
72
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->control), 0, info->ctrl_base);
73
74
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
75
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-irq", 0));
76
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
77
78
/* set periphbase/CBAR value for CPU-local registers */
79
object_property_set_int(OBJECT(&s->cpus[n]),
80
- BCM2836_PERI_BASE + MSYNC_OFFSET,
81
+ info->peri_base,
82
"reset-cbar", &err);
83
if (err) {
84
error_propagate(errp, err);
85
--
62
--
86
2.20.1
63
2.34.1
87
88
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Continue setting, but not relying upon, env->hflags.
3
Move all the CONFIG_FOO=y from default.mak into "default y if TCG"
4
4
statements in Kconfig. That way they won't be selected when
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
CONFIG_TCG=n.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
7
Message-id: 20191023150057.25731-18-richard.henderson@linaro.org
7
I'm leaving CONFIG_ARM_VIRT in default.mak because it allows us to
8
keep the two default.mak files not empty and keep aarch64-default.mak
9
including arm-default.mak. That way we don't surprise anyone that's
10
used to altering these files.
11
12
With this change we can start building with --disable-tcg.
13
14
Signed-off-by: Fabiano Rosas <farosas@suse.de>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20230426180013.14814-12-farosas@suse.de
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
18
---
10
target/arm/translate-a64.c | 13 +++++++++++--
19
configs/devices/aarch64-softmmu/default.mak | 4 --
11
target/arm/translate.c | 28 +++++++++++++++++++++++-----
20
configs/devices/arm-softmmu/default.mak | 37 ------------------
12
2 files changed, 34 insertions(+), 7 deletions(-)
21
hw/arm/Kconfig | 42 ++++++++++++++++++++-
13
22
3 files changed, 41 insertions(+), 42 deletions(-)
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
23
24
diff --git a/configs/devices/aarch64-softmmu/default.mak b/configs/devices/aarch64-softmmu/default.mak
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
26
--- a/configs/devices/aarch64-softmmu/default.mak
17
+++ b/target/arm/translate-a64.c
27
+++ b/configs/devices/aarch64-softmmu/default.mak
18
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
28
@@ -XXX,XX +XXX,XX @@
19
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
29
20
/* I/O operations must end the TB here (whether read or write) */
30
# We support all the 32 bit boards so need all their config
21
s->base.is_jmp = DISAS_UPDATE;
31
include ../arm-softmmu/default.mak
22
- } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
32
-
23
- /* We default to ending the TB on a coprocessor register write,
33
-CONFIG_XLNX_ZYNQMP_ARM=y
24
+ }
34
-CONFIG_XLNX_VERSAL=y
25
+ if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
35
-CONFIG_SBSA_REF=y
26
+ /*
36
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
27
+ * A write to any coprocessor regiser that ends a TB
28
+ * must rebuild the hflags for the next TB.
29
+ */
30
+ TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
31
+ gen_helper_rebuild_hflags_a64(cpu_env, tcg_el);
32
+ tcg_temp_free_i32(tcg_el);
33
+ /*
34
+ * We default to ending the TB on a coprocessor register write,
35
* but allow this to be suppressed by the register definition
36
* (usually only necessary to work around guest bugs).
37
*/
38
diff --git a/target/arm/translate.c b/target/arm/translate.c
39
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate.c
38
--- a/configs/devices/arm-softmmu/default.mak
41
+++ b/target/arm/translate.c
39
+++ b/configs/devices/arm-softmmu/default.mak
42
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
40
@@ -XXX,XX +XXX,XX @@
43
ri = get_arm_cp_reginfo(s->cp_regs,
41
# CONFIG_TEST_DEVICES=n
44
ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
42
45
if (ri) {
43
CONFIG_ARM_VIRT=y
46
+ bool need_exit_tb;
44
-CONFIG_CUBIEBOARD=y
47
+
45
-CONFIG_EXYNOS4=y
48
/* Check access permissions */
46
-CONFIG_HIGHBANK=y
49
if (!cp_access_ok(s->current_el, ri, isread)) {
47
-CONFIG_INTEGRATOR=y
50
return 1;
48
-CONFIG_FSL_IMX31=y
51
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
49
-CONFIG_MUSICPAL=y
52
}
50
-CONFIG_MUSCA=y
53
}
51
-CONFIG_CHEETAH=y
54
52
-CONFIG_SX1=y
55
- if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
53
-CONFIG_NSERIES=y
56
- /* I/O operations must end the TB here (whether read or write) */
54
-CONFIG_STELLARIS=y
57
- gen_lookup_tb(s);
55
-CONFIG_STM32VLDISCOVERY=y
58
- } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
56
-CONFIG_REALVIEW=y
59
- /* We default to ending the TB on a coprocessor register write,
57
-CONFIG_VERSATILE=y
60
+ /* I/O operations must end the TB here (whether read or write) */
58
-CONFIG_VEXPRESS=y
61
+ need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
59
-CONFIG_ZYNQ=y
62
+ (ri->type & ARM_CP_IO));
60
-CONFIG_MAINSTONE=y
63
+
61
-CONFIG_GUMSTIX=y
64
+ if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
62
-CONFIG_SPITZ=y
65
+ /*
63
-CONFIG_TOSA=y
66
+ * A write to any coprocessor regiser that ends a TB
64
-CONFIG_Z2=y
67
+ * must rebuild the hflags for the next TB.
65
-CONFIG_NPCM7XX=y
68
+ */
66
-CONFIG_COLLIE=y
69
+ TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
67
-CONFIG_ASPEED_SOC=y
70
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
68
-CONFIG_NETDUINO2=y
71
+ gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
69
-CONFIG_NETDUINOPLUS2=y
72
+ } else {
70
-CONFIG_OLIMEX_STM32_H405=y
73
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
71
-CONFIG_MPS2=y
74
+ }
72
-CONFIG_RASPI=y
75
+ tcg_temp_free_i32(tcg_el);
73
-CONFIG_DIGIC=y
76
+ /*
74
-CONFIG_SABRELITE=y
77
+ * We default to ending the TB on a coprocessor register write,
75
-CONFIG_EMCRAFT_SF2=y
78
* but allow this to be suppressed by the register definition
76
-CONFIG_MICROBIT=y
79
* (usually only necessary to work around guest bugs).
77
-CONFIG_FSL_IMX25=y
80
*/
78
-CONFIG_FSL_IMX7=y
81
+ need_exit_tb = true;
79
-CONFIG_FSL_IMX6UL=y
82
+ }
80
-CONFIG_ALLWINNER_H3=y
83
+ if (need_exit_tb) {
81
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
84
gen_lookup_tb(s);
82
index XXXXXXX..XXXXXXX 100644
85
}
83
--- a/hw/arm/Kconfig
84
+++ b/hw/arm/Kconfig
85
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
86
87
config CHEETAH
88
bool
89
+ default y if TCG && ARM
90
select OMAP
91
select TSC210X
92
93
config CUBIEBOARD
94
bool
95
+ default y if TCG && ARM
96
select ALLWINNER_A10
97
98
config DIGIC
99
bool
100
+ default y if TCG && ARM
101
select PTIMER
102
select PFLASH_CFI02
103
104
config EXYNOS4
105
bool
106
+ default y if TCG && ARM
107
imply I2C_DEVICES
108
select A9MPCORE
109
select I2C
110
@@ -XXX,XX +XXX,XX @@ config EXYNOS4
111
112
config HIGHBANK
113
bool
114
+ default y if TCG && ARM
115
select A9MPCORE
116
select A15MPCORE
117
select AHCI
118
@@ -XXX,XX +XXX,XX @@ config HIGHBANK
119
120
config INTEGRATOR
121
bool
122
+ default y if TCG && ARM
123
select ARM_TIMER
124
select INTEGRATOR_DEBUG
125
select PL011 # UART
126
@@ -XXX,XX +XXX,XX @@ config INTEGRATOR
127
128
config MAINSTONE
129
bool
130
+ default y if TCG && ARM
131
select PXA2XX
132
select PFLASH_CFI01
133
select SMC91C111
134
135
config MUSCA
136
bool
137
+ default y if TCG && ARM
138
select ARMSSE
139
select PL011
140
select PL031
141
@@ -XXX,XX +XXX,XX @@ config MARVELL_88W8618
142
143
config MUSICPAL
144
bool
145
+ default y if TCG && ARM
146
select OR_IRQ
147
select BITBANG_I2C
148
select MARVELL_88W8618
149
@@ -XXX,XX +XXX,XX @@ config MUSICPAL
150
151
config NETDUINO2
152
bool
153
+ default y if TCG && ARM
154
select STM32F205_SOC
155
156
config NETDUINOPLUS2
157
bool
158
+ default y if TCG && ARM
159
select STM32F405_SOC
160
161
config OLIMEX_STM32_H405
162
bool
163
+ default y if TCG && ARM
164
select STM32F405_SOC
165
166
config NSERIES
167
bool
168
+ default y if TCG && ARM
169
select OMAP
170
select TMP105 # temperature sensor
171
select BLIZZARD # LCD/TV controller
172
@@ -XXX,XX +XXX,XX @@ config PXA2XX
173
174
config GUMSTIX
175
bool
176
+ default y if TCG && ARM
177
select PFLASH_CFI01
178
select SMC91C111
179
select PXA2XX
180
181
config TOSA
182
bool
183
+ default y if TCG && ARM
184
select ZAURUS # scoop
185
select MICRODRIVE
186
select PXA2XX
187
@@ -XXX,XX +XXX,XX @@ config TOSA
188
189
config SPITZ
190
bool
191
+ default y if TCG && ARM
192
select ADS7846 # touch-screen controller
193
select MAX111X # A/D converter
194
select WM8750 # audio codec
195
@@ -XXX,XX +XXX,XX @@ config SPITZ
196
197
config Z2
198
bool
199
+ default y if TCG && ARM
200
select PFLASH_CFI01
201
select WM8750
202
select PL011 # UART
203
@@ -XXX,XX +XXX,XX @@ config Z2
204
205
config REALVIEW
206
bool
207
+ default y if TCG && ARM
208
imply PCI_DEVICES
209
imply PCI_TESTDEV
210
imply I2C_DEVICES
211
@@ -XXX,XX +XXX,XX @@ config REALVIEW
212
213
config SBSA_REF
214
bool
215
+ default y if TCG && AARCH64
216
imply PCI_DEVICES
217
select AHCI
218
select ARM_SMMUV3
219
@@ -XXX,XX +XXX,XX @@ config SBSA_REF
220
221
config SABRELITE
222
bool
223
+ default y if TCG && ARM
224
select FSL_IMX6
225
select SSI_M25P80
226
227
config STELLARIS
228
bool
229
+ default y if TCG && ARM
230
imply I2C_DEVICES
231
select ARM_V7M
232
select CMSDK_APB_WATCHDOG
233
@@ -XXX,XX +XXX,XX @@ config STELLARIS
234
235
config STM32VLDISCOVERY
236
bool
237
+ default y if TCG && ARM
238
select STM32F100_SOC
239
240
config STRONGARM
241
@@ -XXX,XX +XXX,XX @@ config STRONGARM
242
243
config COLLIE
244
bool
245
+ default y if TCG && ARM
246
select PFLASH_CFI01
247
select ZAURUS # scoop
248
select STRONGARM
249
250
config SX1
251
bool
252
+ default y if TCG && ARM
253
select OMAP
254
255
config VERSATILE
256
bool
257
+ default y if TCG && ARM
258
select ARM_TIMER # sp804
259
select PFLASH_CFI01
260
select LSI_SCSI_PCI
261
@@ -XXX,XX +XXX,XX @@ config VERSATILE
262
263
config VEXPRESS
264
bool
265
+ default y if TCG && ARM
266
select A9MPCORE
267
select A15MPCORE
268
select ARM_MPTIMER
269
@@ -XXX,XX +XXX,XX @@ config VEXPRESS
270
271
config ZYNQ
272
bool
273
+ default y if TCG && ARM
274
select A9MPCORE
275
select CADENCE # UART
276
select PFLASH_CFI02
277
@@ -XXX,XX +XXX,XX @@ config ZYNQ
278
config ARM_V7M
279
bool
280
# currently v7M must be included in a TCG build due to translate.c
281
- default y if TCG && (ARM || AARCH64)
282
+ default y if TCG && ARM
283
select PTIMER
284
285
config ALLWINNER_A10
286
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
287
288
config ALLWINNER_H3
289
bool
290
+ default y if TCG && ARM
291
select ALLWINNER_A10_PIT
292
select ALLWINNER_SUN8I_EMAC
293
select ALLWINNER_I2C
294
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_H3
295
296
config RASPI
297
bool
298
+ default y if TCG && ARM
299
select FRAMEBUFFER
300
select PL011 # UART
301
select SDHCI
302
@@ -XXX,XX +XXX,XX @@ config STM32F405_SOC
303
304
config XLNX_ZYNQMP_ARM
305
bool
306
+ default y if TCG && AARCH64
307
select AHCI
308
select ARM_GIC
309
select CADENCE
310
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP_ARM
311
312
config XLNX_VERSAL
313
bool
314
+ default y if TCG && AARCH64
315
select ARM_GIC
316
select PL011
317
select CADENCE
318
@@ -XXX,XX +XXX,XX @@ config XLNX_VERSAL
319
320
config NPCM7XX
321
bool
322
+ default y if TCG && ARM
323
select A9MPCORE
324
select ADM1272
325
select ARM_GIC
326
@@ -XXX,XX +XXX,XX @@ config NPCM7XX
327
328
config FSL_IMX25
329
bool
330
+ default y if TCG && ARM
331
imply I2C_DEVICES
332
select IMX
333
select IMX_FEC
334
@@ -XXX,XX +XXX,XX @@ config FSL_IMX25
335
336
config FSL_IMX31
337
bool
338
+ default y if TCG && ARM
339
imply I2C_DEVICES
340
select SERIAL
341
select IMX
342
@@ -XXX,XX +XXX,XX @@ config FSL_IMX6
343
344
config ASPEED_SOC
345
bool
346
+ default y if TCG && ARM
347
select DS1338
348
select FTGMAC100
349
select I2C
350
@@ -XXX,XX +XXX,XX @@ config ASPEED_SOC
351
352
config MPS2
353
bool
354
+ default y if TCG && ARM
355
imply I2C_DEVICES
356
select ARMSSE
357
select LAN9118
358
@@ -XXX,XX +XXX,XX @@ config MPS2
359
360
config FSL_IMX7
361
bool
362
+ default y if TCG && ARM
363
imply PCI_DEVICES
364
imply TEST_DEVICES
365
imply I2C_DEVICES
366
@@ -XXX,XX +XXX,XX @@ config ARM_SMMUV3
367
368
config FSL_IMX6UL
369
bool
370
+ default y if TCG && ARM
371
imply I2C_DEVICES
372
select A15MPCORE
373
select IMX
374
@@ -XXX,XX +XXX,XX @@ config FSL_IMX6UL
375
376
config MICROBIT
377
bool
378
+ default y if TCG && ARM
379
select NRF51_SOC
380
381
config NRF51_SOC
382
@@ -XXX,XX +XXX,XX @@ config NRF51_SOC
383
384
config EMCRAFT_SF2
385
bool
386
+ default y if TCG && ARM
387
select MSF2
388
select SSI_M25P80
86
389
87
--
390
--
88
2.20.1
391
2.34.1
89
90
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
write_secondary_boot() is used in SMP configurations where the
3
The test set -accel tcg, so restrict it to when TCG is present.
4
CPU address space might not be the main System Bus.
5
The rom_add_blob_fixed_as() function allow us to specify an
6
address space. Use it to write each boot blob in the corresponding
7
CPU address space.
8
4
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
11
Message-id: 20191019234715.25750-15-f4bug@amsat.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230426180013.14814-13-farosas@suse.de
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
hw/arm/highbank.c | 3 ++-
11
tests/qtest/meson.build | 3 ++-
15
1 file changed, 2 insertions(+), 1 deletion(-)
12
1 file changed, 2 insertions(+), 1 deletion(-)
16
13
17
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
14
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/highbank.c
16
--- a/tests/qtest/meson.build
20
+++ b/hw/arm/highbank.c
17
+++ b/tests/qtest/meson.build
21
@@ -XXX,XX +XXX,XX @@ static void hb_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
18
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
22
for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
19
['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \
23
smpboot[n] = tswap32(smpboot[n]);
20
(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
24
}
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
25
- rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot), SMP_BOOT_ADDR);
22
- (config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
26
+ rom_add_blob_fixed_as("smpboot", smpboot, sizeof(smpboot), SMP_BOOT_ADDR,
23
+ (config_all.has_key('CONFIG_TCG') and \
27
+ arm_boot_address_space(cpu, info));
24
+ config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
28
}
25
['arm-cpu-features',
29
26
'numa-test',
30
static void hb_reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
27
'boot-serial-test',
31
--
28
--
32
2.20.1
29
2.34.1
33
34
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Connect the recently added SYS_timer.
3
Add a manual new job to cross-build the aarch64 target with
4
Now U-Boot does not hang anymore polling a free running counter
4
only the KVM accelerator enabled (in particular, no TCG).
5
stuck at 0.
6
This timer is also used by the Linux kernel thermal subsystem.
7
5
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Re-enable running the similar job on the project Aarch64
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
custom runner.
10
Message-id: 20191019234715.25750-5-f4bug@amsat.org
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Fabiano Rosas <farosas@suse.de>
11
Reviewed-by: Thomas Huth <thuth@redhat.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20230426180013.14814-14-farosas@suse.de
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
15
---
13
include/hw/arm/bcm2835_peripherals.h | 3 ++-
16
.gitlab-ci.d/crossbuilds.yml | 11 +++++++++++
14
hw/arm/bcm2835_peripherals.c | 17 ++++++++++++++++-
17
.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml | 4 ----
15
2 files changed, 18 insertions(+), 2 deletions(-)
18
2 files changed, 11 insertions(+), 4 deletions(-)
16
19
17
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
20
diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/bcm2835_peripherals.h
22
--- a/.gitlab-ci.d/crossbuilds.yml
20
+++ b/include/hw/arm/bcm2835_peripherals.h
23
+++ b/.gitlab-ci.d/crossbuilds.yml
21
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ cross-arm64-xen-only:
22
#include "hw/sd/sdhci.h"
25
IMAGE: debian-arm64-cross
23
#include "hw/sd/bcm2835_sdhost.h"
26
ACCEL: xen
24
#include "hw/gpio/bcm2835_gpio.h"
27
EXTRA_CONFIGURE_OPTS: --disable-tcg --disable-kvm
25
+#include "hw/timer/bcm2835_systmr.h"
28
+
26
#include "hw/misc/unimp.h"
29
+# Similar job is run by qemu-project's custom runner by default
27
30
+cross-arm64-kvm-only:
28
#define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals"
31
+ extends: .cross_accel_build_job
29
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2835PeripheralState {
32
+ needs:
30
MemoryRegion ram_alias[4];
33
+ job: arm64-debian-cross-container
31
qemu_irq irq, fiq;
34
+ variables:
32
35
+ QEMU_JOB_OPTIONAL: 1
33
- UnimplementedDeviceState systmr;
36
+ IMAGE: debian-arm64-cross
34
+ BCM2835SystemTimerState systmr;
37
+ ACCEL: kvm
35
UnimplementedDeviceState armtmr;
38
+ EXTRA_CONFIGURE_OPTS: --disable-tcg --disable-xen --without-default-devices
36
UnimplementedDeviceState cprman;
39
diff --git a/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml b/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml
37
UnimplementedDeviceState a2w;
38
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
39
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/bcm2835_peripherals.c
41
--- a/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml
41
+++ b/hw/arm/bcm2835_peripherals.c
42
+++ b/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml
42
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
43
@@ -XXX,XX +XXX,XX @@ ubuntu-22.04-aarch64-notcg:
43
/* Interrupt Controller */
44
- aarch64
44
sysbus_init_child_obj(obj, "ic", &s->ic, sizeof(s->ic), TYPE_BCM2835_IC);
45
rules:
45
46
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/'
46
+ /* SYS Timer */
47
- when: manual
47
+ sysbus_init_child_obj(obj, "systimer", &s->systmr, sizeof(s->systmr),
48
- allow_failure: true
48
+ TYPE_BCM2835_SYSTIMER);
49
- if: "$AARCH64_RUNNER_AVAILABLE"
49
+
50
- when: manual
50
/* UART0 */
51
- allow_failure: true
51
sysbus_init_child_obj(obj, "uart0", &s->uart0, sizeof(s->uart0),
52
script:
52
TYPE_PL011);
53
- mkdir build
53
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
54
- cd build
54
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->ic), 0));
55
sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(&s->ic));
56
57
+ /* Sys Timer */
58
+ object_property_set_bool(OBJECT(&s->systmr), true, "realized", &err);
59
+ if (err) {
60
+ error_propagate(errp, err);
61
+ return;
62
+ }
63
+ memory_region_add_subregion(&s->peri_mr, ST_OFFSET,
64
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systmr), 0));
65
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 0,
66
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
67
+ INTERRUPT_ARM_TIMER));
68
+
69
/* UART0 */
70
qdev_prop_set_chr(DEVICE(&s->uart0), "chardev", serial_hd(0));
71
object_property_set_bool(OBJECT(&s->uart0), true, "realized", &err);
72
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
73
}
74
75
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
76
- create_unimp(s, &s->systmr, "bcm2835-systimer", ST_OFFSET, 0x20);
77
create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000);
78
create_unimp(s, &s->a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000);
79
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
80
--
55
--
81
2.20.1
56
2.34.1
82
57
83
58
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
Continue setting, but not relying upon, env->hflags.
3
The MAC address set from Qemu wasn't being saved into the register space.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Hao Wu <wuhaotsh@google.com>
6
Message-id: 20191023150057.25731-20-richard.henderson@linaro.org
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
[PMM: moved variable declaration to top of function]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
target/arm/helper.c | 10 ++++++++++
12
hw/net/npcm7xx_emc.c | 32 +++++++++++++++++++++++++-------
10
1 file changed, 10 insertions(+)
13
1 file changed, 25 insertions(+), 7 deletions(-)
11
14
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
17
--- a/hw/net/npcm7xx_emc.c
15
+++ b/target/arm/helper.c
18
+++ b/hw/net/npcm7xx_emc.c
16
@@ -XXX,XX +XXX,XX @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
19
@@ -XXX,XX +XXX,XX @@ static const char *emc_reg_name(int regno)
17
/* ??? Lots of these bits are not implemented. */
20
18
/* This may enable/disable the MMU, so do a TLB flush. */
21
static void emc_reset(NPCM7xxEMCState *emc)
19
tlb_flush(CPU(cpu));
22
{
23
+ uint32_t value;
20
+
24
+
21
+ if (ri->type & ARM_CP_SUPPRESS_TB_END) {
25
trace_npcm7xx_emc_reset(emc->emc_num);
22
+ /*
26
23
+ * Normally we would always end the TB on an SCTLR write; see the
27
memset(&emc->regs[0], 0, sizeof(emc->regs));
24
+ * comment in ARMCPRegInfo sctlr initialization below for why Xscale
28
@@ -XXX,XX +XXX,XX @@ static void emc_reset(NPCM7xxEMCState *emc)
25
+ * is special. Setting ARM_CP_SUPPRESS_TB_END also stops the rebuild
29
26
+ * of hflags from the translator, so do it here.
30
emc->tx_active = false;
27
+ */
31
emc->rx_active = false;
28
+ arm_rebuild_hflags(env);
32
+
29
+ }
33
+ /* Set the MAC address in the register space. */
34
+ value = (emc->conf.macaddr.a[0] << 24) |
35
+ (emc->conf.macaddr.a[1] << 16) |
36
+ (emc->conf.macaddr.a[2] << 8) |
37
+ emc->conf.macaddr.a[3];
38
+ emc->regs[REG_CAMM_BASE] = value;
39
+
40
+ value = (emc->conf.macaddr.a[4] << 24) | (emc->conf.macaddr.a[5] << 16);
41
+ emc->regs[REG_CAML_BASE] = value;
30
}
42
}
31
43
32
static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri,
44
static void npcm7xx_emc_reset(DeviceState *dev)
45
@@ -XXX,XX +XXX,XX @@ static bool emc_receive_filter1(NPCM7xxEMCState *emc, const uint8_t *buf,
46
}
47
case ETH_PKT_UCAST: {
48
bool matches;
49
+ uint32_t value;
50
+ struct MACAddr mac;
51
if (emc->regs[REG_CAMCMR] & REG_CAMCMR_AUP) {
52
return true;
53
}
54
+
55
+ value = emc->regs[REG_CAMM_BASE];
56
+ mac.a[0] = value >> 24;
57
+ mac.a[1] = value >> 16;
58
+ mac.a[2] = value >> 8;
59
+ mac.a[3] = value >> 0;
60
+ value = emc->regs[REG_CAML_BASE];
61
+ mac.a[4] = value >> 24;
62
+ mac.a[5] = value >> 16;
63
+
64
matches = ((emc->regs[REG_CAMCMR] & REG_CAMCMR_ECMP) &&
65
/* We only support one CAM register, CAM0. */
66
(emc->regs[REG_CAMEN] & (1 << 0)) &&
67
- memcmp(buf, emc->conf.macaddr.a, ETH_ALEN) == 0);
68
+ memcmp(buf, mac.a, ETH_ALEN) == 0);
69
if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
70
*fail_reason = "MACADDR matched, comparison complemented";
71
return !matches;
72
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
73
break;
74
case REG_CAMM_BASE + 0:
75
emc->regs[reg] = value;
76
- emc->conf.macaddr.a[0] = value >> 24;
77
- emc->conf.macaddr.a[1] = value >> 16;
78
- emc->conf.macaddr.a[2] = value >> 8;
79
- emc->conf.macaddr.a[3] = value >> 0;
80
break;
81
case REG_CAML_BASE + 0:
82
emc->regs[reg] = value;
83
- emc->conf.macaddr.a[4] = value >> 24;
84
- emc->conf.macaddr.a[5] = value >> 16;
85
break;
86
case REG_MCMDR: {
87
uint32_t prev;
33
--
88
--
34
2.20.1
89
2.34.1
35
90
36
91
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Daniel Bertalan <dani@danielbertalan.dev>
2
2
3
Map the thermal sensor in the BCM2835 block.
3
This query copies the kernel command line into the message buffer. It
4
was previously stubbed out to return empty, this commit makes it reflect
5
the arguments specified with `-append`.
4
6
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
I observed the following peculiarities on my Pi 3B+:
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
- If the buffer is shorter than the string, the response header gives
7
Message-id: 20191019234715.25750-3-f4bug@amsat.org
9
the full length, but no data is actually copied.
10
- No NUL terminator is added: even if the buffer is long enough to fit
11
one, the buffer's original contents are preserved past the string's
12
end.
13
- The VC firmware adds the following extra parameters beside the
14
user-supplied ones (via /boot/cmdline.txt): `video`, `vc_mem.mem_base`
15
and `vc_mem.mem_size`. This is currently not implemented in qemu.
16
17
Signed-off-by: Daniel Bertalan <dani@danielbertalan.dev>
18
Message-id: 20230425103250.56653-1-dani@danielbertalan.dev
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
[PMM: added comment about NUL and short-buffer behaviour]
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
22
---
10
include/hw/arm/bcm2835_peripherals.h | 2 ++
23
include/hw/misc/bcm2835_property.h | 1 +
11
include/hw/arm/raspi_platform.h | 1 +
24
hw/arm/bcm2835_peripherals.c | 2 ++
12
hw/arm/bcm2835_peripherals.c | 13 +++++++++++++
25
hw/arm/bcm2836.c | 2 ++
13
3 files changed, 16 insertions(+)
26
hw/arm/raspi.c | 2 ++
27
hw/misc/bcm2835_property.c | 13 ++++++++++++-
28
5 files changed, 19 insertions(+), 1 deletion(-)
14
29
15
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
30
diff --git a/include/hw/misc/bcm2835_property.h b/include/hw/misc/bcm2835_property.h
16
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/bcm2835_peripherals.h
32
--- a/include/hw/misc/bcm2835_property.h
18
+++ b/include/hw/arm/bcm2835_peripherals.h
33
+++ b/include/hw/misc/bcm2835_property.h
19
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@ struct BCM2835PropertyState {
20
#include "hw/misc/bcm2835_property.h"
35
MACAddr macaddr;
21
#include "hw/misc/bcm2835_rng.h"
36
uint32_t board_rev;
22
#include "hw/misc/bcm2835_mbox.h"
37
uint32_t addr;
23
+#include "hw/misc/bcm2835_thermal.h"
38
+ char *command_line;
24
#include "hw/sd/sdhci.h"
39
bool pending;
25
#include "hw/sd/bcm2835_sdhost.h"
40
};
26
#include "hw/gpio/bcm2835_gpio.h"
41
27
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2835PeripheralState {
28
SDHCIState sdhci;
29
BCM2835SDHostState sdhost;
30
BCM2835GpioState gpio;
31
+ Bcm2835ThermalState thermal;
32
UnimplementedDeviceState i2s;
33
UnimplementedDeviceState spi[1];
34
UnimplementedDeviceState i2c[3];
35
diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/arm/raspi_platform.h
38
+++ b/include/hw/arm/raspi_platform.h
39
@@ -XXX,XX +XXX,XX @@
40
#define SPI0_OFFSET 0x204000
41
#define BSC0_OFFSET 0x205000 /* BSC0 I2C/TWI */
42
#define OTP_OFFSET 0x20f000
43
+#define THERMAL_OFFSET 0x212000
44
#define BSC_SL_OFFSET 0x214000 /* SPI slave */
45
#define AUX_OFFSET 0x215000 /* AUX: UART1/SPI1/SPI2 */
46
#define EMMC1_OFFSET 0x300000
47
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
42
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
48
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/bcm2835_peripherals.c
44
--- a/hw/arm/bcm2835_peripherals.c
50
+++ b/hw/arm/bcm2835_peripherals.c
45
+++ b/hw/arm/bcm2835_peripherals.c
51
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
46
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
52
object_property_add_const_link(OBJECT(&s->dma), "dma-mr",
47
TYPE_BCM2835_PROPERTY);
53
OBJECT(&s->gpu_bus_mr), &error_abort);
48
object_property_add_alias(obj, "board-rev", OBJECT(&s->property),
54
49
"board-rev");
55
+ /* Thermal */
50
+ object_property_add_alias(obj, "command-line", OBJECT(&s->property),
56
+ sysbus_init_child_obj(obj, "thermal", &s->thermal, sizeof(s->thermal),
51
+ "command-line");
57
+ TYPE_BCM2835_THERMAL);
52
58
+
53
object_property_add_const_link(OBJECT(&s->property), "fb",
59
/* GPIO */
54
OBJECT(&s->fb));
60
sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
55
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
61
TYPE_BCM2835_GPIO);
56
index XXXXXXX..XXXXXXX 100644
62
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
57
--- a/hw/arm/bcm2836.c
63
INTERRUPT_DMA0 + n));
58
+++ b/hw/arm/bcm2836.c
64
}
59
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
65
60
TYPE_BCM2835_PERIPHERALS);
66
+ /* THERMAL */
61
object_property_add_alias(obj, "board-rev", OBJECT(&s->peripherals),
67
+ object_property_set_bool(OBJECT(&s->thermal), true, "realized", &err);
62
"board-rev");
68
+ if (err) {
63
+ object_property_add_alias(obj, "command-line", OBJECT(&s->peripherals),
69
+ error_propagate(errp, err);
64
+ "command-line");
70
+ return;
65
object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
71
+ }
66
"vcram-size");
72
+ memory_region_add_subregion(&s->peri_mr, THERMAL_OFFSET,
67
}
73
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->thermal), 0));
68
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
74
+
69
index XXXXXXX..XXXXXXX 100644
75
/* GPIO */
70
--- a/hw/arm/raspi.c
76
object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
71
+++ b/hw/arm/raspi.c
77
if (err) {
72
@@ -XXX,XX +XXX,XX @@ static void raspi_machine_init(MachineState *machine)
73
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(machine->ram));
74
object_property_set_int(OBJECT(&s->soc), "board-rev", board_rev,
75
&error_abort);
76
+ object_property_set_str(OBJECT(&s->soc), "command-line",
77
+ machine->kernel_cmdline, &error_abort);
78
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
79
80
/* Create and plug in the SD cards */
81
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/misc/bcm2835_property.c
84
+++ b/hw/misc/bcm2835_property.c
85
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
86
break;
87
88
case 0x00050001: /* Get command line */
89
- resplen = 0;
90
+ /*
91
+ * We follow the firmware behaviour: no NUL terminator is
92
+ * written to the buffer, and if the buffer is too short
93
+ * we report the required length in the response header
94
+ * and copy nothing to the buffer.
95
+ */
96
+ resplen = strlen(s->command_line);
97
+ if (bufsize >= resplen)
98
+ address_space_write(&s->dma_as, value + 12,
99
+ MEMTXATTRS_UNSPECIFIED, s->command_line,
100
+ resplen);
101
break;
102
103
default:
104
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_realize(DeviceState *dev, Error **errp)
105
106
static Property bcm2835_property_props[] = {
107
DEFINE_PROP_UINT32("board-rev", BCM2835PropertyState, board_rev, 0),
108
+ DEFINE_PROP_STRING("command-line", BCM2835PropertyState, command_line),
109
DEFINE_PROP_END_OF_LIST()
110
};
111
78
--
112
--
79
2.20.1
113
2.34.1
80
81
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
This commit adds 'one-insn-per-tb' as a property on the TCG
2
2
accelerator object, so you can enable it with
3
Create a function to compute the values of the TBFLAG_ANY bits
3
-accel tcg,one-insn-per-tb=on
4
that will be cached, and are used by A-profile.
4
5
5
It has the same behaviour as the existing '-singlestep' command line
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
option. We use a different name because 'singlestep' has always been
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
a confusing choice, because it doesn't have anything to do with
8
Message-id: 20191023150057.25731-9-richard.henderson@linaro.org
8
single-stepping the CPU. What it does do is force TCG emulation to
9
put one guest instruction in each TB, which can be useful in some
10
situations (such as analysing debug logs).
11
12
The existing '-singlestep' commandline options are decoupled from the
13
global 'singlestep' variable and instead now are syntactic sugar for
14
setting the accel property. (These can then go away after a
15
deprecation period.)
16
17
The global variable remains for the moment as:
18
* what the TCG code looks at to change its behaviour
19
* what HMP and QMP use to query and set the behaviour
20
21
In the following commits we'll clean those up to not directly
22
look at the global variable.
23
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20230417164041.684562-2-peter.maydell@linaro.org
10
---
27
---
11
target/arm/helper.c | 20 ++++++++++++--------
28
accel/tcg/tcg-all.c | 21 +++++++++++++++++++++
12
1 file changed, 12 insertions(+), 8 deletions(-)
29
bsd-user/main.c | 8 ++++++--
13
30
linux-user/main.c | 8 ++++++--
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
softmmu/vl.c | 17 +++++++++++++++--
15
index XXXXXXX..XXXXXXX 100644
32
qemu-options.hx | 7 +++++++
16
--- a/target/arm/helper.c
33
5 files changed, 55 insertions(+), 6 deletions(-)
17
+++ b/target/arm/helper.c
34
18
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
35
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
19
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
36
index XXXXXXX..XXXXXXX 100644
37
--- a/accel/tcg/tcg-all.c
38
+++ b/accel/tcg/tcg-all.c
39
@@ -XXX,XX +XXX,XX @@ struct TCGState {
40
AccelState parent_obj;
41
42
bool mttcg_enabled;
43
+ bool one_insn_per_tb;
44
int splitwx_enabled;
45
unsigned long tb_size;
46
};
47
@@ -XXX,XX +XXX,XX @@ static void tcg_set_splitwx(Object *obj, bool value, Error **errp)
48
s->splitwx_enabled = value;
20
}
49
}
21
50
22
+static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
51
+static bool tcg_get_one_insn_per_tb(Object *obj, Error **errp)
23
+{
52
+{
24
+ int flags = 0;
53
+ TCGState *s = TCG_STATE(obj);
25
+
54
+ return s->one_insn_per_tb;
26
+ flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL,
27
+ arm_debug_target_el(env));
28
+ return flags;
29
+}
55
+}
30
+
56
+
31
static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
57
+static void tcg_set_one_insn_per_tb(Object *obj, bool value, Error **errp)
32
ARMMMUIdx mmu_idx)
58
+{
59
+ TCGState *s = TCG_STATE(obj);
60
+ s->one_insn_per_tb = value;
61
+ /* For the moment, set the global also: this changes the behaviour */
62
+ singlestep = value;
63
+}
64
+
65
static int tcg_gdbstub_supported_sstep_flags(void)
33
{
66
{
34
- return rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
67
/*
35
+ uint32_t flags = rebuild_hflags_aprofile(env);
68
@@ -XXX,XX +XXX,XX @@ static void tcg_accel_class_init(ObjectClass *oc, void *data)
36
+ return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
69
tcg_get_splitwx, tcg_set_splitwx);
70
object_class_property_set_description(oc, "split-wx",
71
"Map jit pages into separate RW and RX regions");
72
+
73
+ object_class_property_add_bool(oc, "one-insn-per-tb",
74
+ tcg_get_one_insn_per_tb,
75
+ tcg_set_one_insn_per_tb);
76
+ object_class_property_set_description(oc, "one-insn-per-tb",
77
+ "Only put one guest insn in each translation block");
37
}
78
}
38
79
39
static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
80
static const TypeInfo tcg_accel_type = {
40
ARMMMUIdx mmu_idx)
81
diff --git a/bsd-user/main.c b/bsd-user/main.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/bsd-user/main.c
84
+++ b/bsd-user/main.c
85
@@ -XXX,XX +XXX,XX @@
86
#include "target_arch_cpu.h"
87
88
int singlestep;
89
+static bool opt_one_insn_per_tb;
90
uintptr_t guest_base;
91
bool have_guest_base;
92
/*
93
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
94
} else if (!strcmp(r, "seed")) {
95
seed_optarg = optarg;
96
} else if (!strcmp(r, "singlestep")) {
97
- singlestep = 1;
98
+ opt_one_insn_per_tb = true;
99
} else if (!strcmp(r, "strace")) {
100
do_strace = 1;
101
} else if (!strcmp(r, "trace")) {
102
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
103
104
/* init tcg before creating CPUs and to get qemu_host_page_size */
105
{
106
- AccelClass *ac = ACCEL_GET_CLASS(current_accel());
107
+ AccelState *accel = current_accel();
108
+ AccelClass *ac = ACCEL_GET_CLASS(accel);
109
110
accel_init_interfaces(ac);
111
+ object_property_set_bool(OBJECT(accel), "one-insn-per-tb",
112
+ opt_one_insn_per_tb, &error_abort);
113
ac->init_machine(NULL);
114
}
115
cpu = cpu_create(cpu_type);
116
diff --git a/linux-user/main.c b/linux-user/main.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/linux-user/main.c
119
+++ b/linux-user/main.c
120
@@ -XXX,XX +XXX,XX @@ char *exec_path;
121
char real_exec_path[PATH_MAX];
122
123
int singlestep;
124
+static bool opt_one_insn_per_tb;
125
static const char *argv0;
126
static const char *gdbstub;
127
static envlist_t *envlist;
128
@@ -XXX,XX +XXX,XX @@ static void handle_arg_reserved_va(const char *arg)
129
130
static void handle_arg_singlestep(const char *arg)
41
{
131
{
42
+ uint32_t flags = rebuild_hflags_aprofile(env);
132
- singlestep = 1;
43
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
133
+ opt_one_insn_per_tb = true;
44
ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
134
}
45
- uint32_t flags = 0;
135
46
uint64_t sctlr;
136
static void handle_arg_strace(const char *arg)
47
int tbii, tbid;
137
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
48
138
49
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
139
/* init tcg before creating CPUs and to get qemu_host_page_size */
50
}
140
{
141
- AccelClass *ac = ACCEL_GET_CLASS(current_accel());
142
+ AccelState *accel = current_accel();
143
+ AccelClass *ac = ACCEL_GET_CLASS(accel);
144
145
accel_init_interfaces(ac);
146
+ object_property_set_bool(OBJECT(accel), "one-insn-per-tb",
147
+ opt_one_insn_per_tb, &error_abort);
148
ac->init_machine(NULL);
51
}
149
}
52
150
cpu = cpu_create(cpu_type);
53
- if (!arm_feature(env, ARM_FEATURE_M)) {
151
diff --git a/softmmu/vl.c b/softmmu/vl.c
54
- int target_el = arm_debug_target_el(env);
152
index XXXXXXX..XXXXXXX 100644
153
--- a/softmmu/vl.c
154
+++ b/softmmu/vl.c
155
@@ -XXX,XX +XXX,XX @@ static const char *log_file;
156
static bool list_data_dirs;
157
static const char *qtest_chrdev;
158
static const char *qtest_log;
159
+static bool opt_one_insn_per_tb;
160
161
static int has_defaults = 1;
162
static int default_serial = 1;
163
@@ -XXX,XX +XXX,XX @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
164
qemu_opt_foreach(opts, accelerator_set_property,
165
accel,
166
&error_fatal);
55
-
167
-
56
- flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL, target_el);
168
+ /*
57
- }
169
+ * If legacy -singlestep option is set, honour it for TCG and
58
-
170
+ * silently ignore for any other accelerator (which is how this
59
*pflags = flags;
171
+ * option has always behaved).
60
*cs_base = 0;
172
+ */
61
}
173
+ if (opt_one_insn_per_tb) {
174
+ /*
175
+ * This will always succeed for TCG, and we want to ignore
176
+ * the error from trying to set a nonexistent property
177
+ * on any other accelerator.
178
+ */
179
+ object_property_set_bool(OBJECT(accel), "one-insn-per-tb", true, NULL);
180
+ }
181
ret = accel_init_machine(accel, current_machine);
182
if (ret < 0) {
183
if (!qtest_with_kvm || ret != -ENOENT) {
184
@@ -XXX,XX +XXX,XX @@ void qemu_init(int argc, char **argv)
185
qdict_put_str(machine_opts_dict, "firmware", optarg);
186
break;
187
case QEMU_OPTION_singlestep:
188
- singlestep = 1;
189
+ opt_one_insn_per_tb = true;
190
break;
191
case QEMU_OPTION_S:
192
autostart = 0;
193
diff --git a/qemu-options.hx b/qemu-options.hx
194
index XXXXXXX..XXXXXXX 100644
195
--- a/qemu-options.hx
196
+++ b/qemu-options.hx
197
@@ -XXX,XX +XXX,XX @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
198
" igd-passthru=on|off (enable Xen integrated Intel graphics passthrough, default=off)\n"
199
" kernel-irqchip=on|off|split controls accelerated irqchip support (default=on)\n"
200
" kvm-shadow-mem=size of KVM shadow MMU in bytes\n"
201
+ " one-insn-per-tb=on|off (one guest instruction per TCG translation block)\n"
202
" split-wx=on|off (enable TCG split w^x mapping)\n"
203
" tb-size=n (TCG translation block cache size)\n"
204
" dirty-ring-size=n (KVM dirty ring GFN count, default 0)\n"
205
@@ -XXX,XX +XXX,XX @@ SRST
206
``kvm-shadow-mem=size``
207
Defines the size of the KVM shadow MMU.
208
209
+ ``one-insn-per-tb=on|off``
210
+ Makes the TCG accelerator put only one guest instruction into
211
+ each translation block. This slows down emulation a lot, but
212
+ can be useful in some situations, such as when trying to analyse
213
+ the logs produced by the ``-d`` option.
214
+
215
``split-wx=on|off``
216
Controls the use of split w^x mapping for the TCG code generation
217
buffer. Some operating systems require this to be enabled, and in
62
--
218
--
63
2.20.1
219
2.34.1
64
65
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
The HMP 'singlestep' command, the QMP 'query-status' command and the
2
HMP 'info status' command (which is just wrapping the QMP command
3
implementation) look at the 'singlestep' global variable. Make them
4
access the new TCG accelerator 'one-insn-per-tb' property instead.
2
5
3
Now that Arm CPUs have advertised features lets add tests to ensure
6
This leaves the HMP and QMP command/field names and output strings
4
we maintain their expected availability with and without KVM.
7
unchanged; we will clean that up later.
5
8
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20191024121808.9612-3-drjones@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20230417164041.684562-3-peter.maydell@linaro.org
10
---
13
---
11
tests/Makefile.include | 5 +-
14
softmmu/runstate-hmp-cmds.c | 18 ++++++++++++++++--
12
tests/arm-cpu-features.c | 240 +++++++++++++++++++++++++++++++++++++++
15
softmmu/runstate.c | 10 +++++++++-
13
2 files changed, 244 insertions(+), 1 deletion(-)
16
2 files changed, 25 insertions(+), 3 deletions(-)
14
create mode 100644 tests/arm-cpu-features.c
15
17
16
diff --git a/tests/Makefile.include b/tests/Makefile.include
18
diff --git a/softmmu/runstate-hmp-cmds.c b/softmmu/runstate-hmp-cmds.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/Makefile.include
20
--- a/softmmu/runstate-hmp-cmds.c
19
+++ b/tests/Makefile.include
21
+++ b/softmmu/runstate-hmp-cmds.c
20
@@ -XXX,XX +XXX,XX @@ check-qtest-sparc64-$(CONFIG_ISA_TESTDEV) = tests/endianness-test$(EXESUF)
21
check-qtest-sparc64-y += tests/prom-env-test$(EXESUF)
22
check-qtest-sparc64-y += tests/boot-serial-test$(EXESUF)
23
24
+check-qtest-arm-y += tests/arm-cpu-features$(EXESUF)
25
check-qtest-arm-y += tests/microbit-test$(EXESUF)
26
check-qtest-arm-y += tests/m25p80-test$(EXESUF)
27
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
28
@@ -XXX,XX +XXX,XX @@ check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
29
check-qtest-arm-y += tests/hexloader-test$(EXESUF)
30
check-qtest-arm-$(CONFIG_PFLASH_CFI02) += tests/pflash-cfi02-test$(EXESUF)
31
32
-check-qtest-aarch64-y = tests/numa-test$(EXESUF)
33
+check-qtest-aarch64-y += tests/arm-cpu-features$(EXESUF)
34
+check-qtest-aarch64-y += tests/numa-test$(EXESUF)
35
check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF)
36
check-qtest-aarch64-y += tests/migration-test$(EXESUF)
37
# TODO: once aarch64 TCG is fixed on ARM 32 bit host, make test unconditional
38
@@ -XXX,XX +XXX,XX @@ tests/test-qapi-util$(EXESUF): tests/test-qapi-util.o $(test-util-obj-y)
39
tests/numa-test$(EXESUF): tests/numa-test.o
40
tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o tests/boot-sector.o tests/acpi-utils.o
41
tests/cdrom-test$(EXESUF): tests/cdrom-test.o tests/boot-sector.o $(libqos-obj-y)
42
+tests/arm-cpu-features$(EXESUF): tests/arm-cpu-features.o
43
44
tests/migration/stress$(EXESUF): tests/migration/stress.o
45
    $(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ,"LINK","$(TARGET_DIR)$@")
46
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
47
new file mode 100644
48
index XXXXXXX..XXXXXXX
49
--- /dev/null
50
+++ b/tests/arm-cpu-features.c
51
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
52
+/*
23
#include "qapi/error.h"
53
+ * Arm CPU feature test cases
24
#include "qapi/qapi-commands-run-state.h"
54
+ *
25
#include "qapi/qmp/qdict.h"
55
+ * Copyright (c) 2019 Red Hat Inc.
26
+#include "qemu/accel.h"
56
+ * Authors:
27
57
+ * Andrew Jones <drjones@redhat.com>
28
void hmp_info_status(Monitor *mon, const QDict *qdict)
58
+ *
29
{
59
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
30
@@ -XXX,XX +XXX,XX @@ void hmp_info_status(Monitor *mon, const QDict *qdict)
60
+ * See the COPYING file in the top-level directory.
31
void hmp_singlestep(Monitor *mon, const QDict *qdict)
61
+ */
32
{
62
+#include "qemu/osdep.h"
33
const char *option = qdict_get_try_str(qdict, "option");
63
+#include "libqtest.h"
34
+ AccelState *accel = current_accel();
64
+#include "qapi/qmp/qdict.h"
35
+ bool newval;
65
+#include "qapi/qmp/qjson.h"
66
+
36
+
67
+#define MACHINE "-machine virt,gic-version=max "
37
+ if (!object_property_find(OBJECT(accel), "one-insn-per-tb")) {
68
+#define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \
38
+ monitor_printf(mon,
69
+ "'arguments': { 'type': 'full', "
39
+ "This accelerator does not support setting one-insn-per-tb\n");
70
+#define QUERY_TAIL "}}"
40
+ return;
71
+
72
+static QDict *do_query_no_props(QTestState *qts, const char *cpu_type)
73
+{
74
+ return qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s }"
75
+ QUERY_TAIL, cpu_type);
76
+}
77
+
78
+static QDict *do_query(QTestState *qts, const char *cpu_type,
79
+ const char *fmt, ...)
80
+{
81
+ QDict *resp;
82
+
83
+ if (fmt) {
84
+ QDict *args;
85
+ va_list ap;
86
+
87
+ va_start(ap, fmt);
88
+ args = qdict_from_vjsonf_nofail(fmt, ap);
89
+ va_end(ap);
90
+
91
+ resp = qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s, "
92
+ "'props': %p }"
93
+ QUERY_TAIL, cpu_type, args);
94
+ } else {
95
+ resp = do_query_no_props(qts, cpu_type);
96
+ }
41
+ }
97
+
42
+
98
+ return resp;
43
if (!option || !strcmp(option, "on")) {
99
+}
44
- singlestep = 1;
100
+
45
+ newval = true;
101
+static const char *resp_get_error(QDict *resp)
46
} else if (!strcmp(option, "off")) {
102
+{
47
- singlestep = 0;
103
+ QDict *qdict;
48
+ newval = false;
104
+
49
} else {
105
+ g_assert(resp);
50
monitor_printf(mon, "unexpected option %s\n", option);
106
+
51
+ return;
107
+ qdict = qdict_get_qdict(resp, "error");
52
}
108
+ if (qdict) {
53
+ /* If the property exists then setting it can never fail */
109
+ return qdict_get_str(qdict, "desc");
54
+ object_property_set_bool(OBJECT(accel), "one-insn-per-tb",
110
+ }
55
+ newval, &error_abort);
111
+ return NULL;
56
}
112
+}
57
113
+
58
void hmp_watchdog_action(Monitor *mon, const QDict *qdict)
114
+#define assert_error(qts, cpu_type, expected_error, fmt, ...) \
59
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
115
+({ \
60
index XXXXXXX..XXXXXXX 100644
116
+ QDict *_resp; \
61
--- a/softmmu/runstate.c
117
+ const char *_error; \
62
+++ b/softmmu/runstate.c
118
+ \
63
@@ -XXX,XX +XXX,XX @@
119
+ _resp = do_query(qts, cpu_type, fmt, ##__VA_ARGS__); \
64
#include "qapi/error.h"
120
+ g_assert(_resp); \
65
#include "qapi/qapi-commands-run-state.h"
121
+ _error = resp_get_error(_resp); \
66
#include "qapi/qapi-events-run-state.h"
122
+ g_assert(_error); \
67
+#include "qemu/accel.h"
123
+ g_assert(g_str_equal(_error, expected_error)); \
68
#include "qemu/error-report.h"
124
+ qobject_unref(_resp); \
69
#include "qemu/job.h"
125
+})
70
#include "qemu/log.h"
126
+
71
@@ -XXX,XX +XXX,XX @@ bool runstate_needs_reset(void)
127
+static bool resp_has_props(QDict *resp)
72
StatusInfo *qmp_query_status(Error **errp)
128
+{
73
{
129
+ QDict *qdict;
74
StatusInfo *info = g_malloc0(sizeof(*info));
130
+
75
+ AccelState *accel = current_accel();
131
+ g_assert(resp);
76
132
+
77
+ /*
133
+ if (!qdict_haskey(resp, "return")) {
78
+ * We ignore errors, which will happen if the accelerator
134
+ return false;
79
+ * is not TCG. "singlestep" is meaningless for other accelerators,
135
+ }
80
+ * so we will set the StatusInfo field to false for those.
136
+ qdict = qdict_get_qdict(resp, "return");
81
+ */
137
+
82
+ info->singlestep = object_property_get_bool(OBJECT(accel),
138
+ if (!qdict_haskey(qdict, "model")) {
83
+ "one-insn-per-tb", NULL);
139
+ return false;
84
info->running = runstate_is_running();
140
+ }
85
- info->singlestep = singlestep;
141
+ qdict = qdict_get_qdict(qdict, "model");
86
info->status = current_run_state;
142
+
87
143
+ return qdict_haskey(qdict, "props");
88
return info;
144
+}
145
+
146
+static QDict *resp_get_props(QDict *resp)
147
+{
148
+ QDict *qdict;
149
+
150
+ g_assert(resp);
151
+ g_assert(resp_has_props(resp));
152
+
153
+ qdict = qdict_get_qdict(resp, "return");
154
+ qdict = qdict_get_qdict(qdict, "model");
155
+ qdict = qdict_get_qdict(qdict, "props");
156
+ return qdict;
157
+}
158
+
159
+#define assert_has_feature(qts, cpu_type, feature) \
160
+({ \
161
+ QDict *_resp = do_query_no_props(qts, cpu_type); \
162
+ g_assert(_resp); \
163
+ g_assert(resp_has_props(_resp)); \
164
+ g_assert(qdict_get(resp_get_props(_resp), feature)); \
165
+ qobject_unref(_resp); \
166
+})
167
+
168
+#define assert_has_not_feature(qts, cpu_type, feature) \
169
+({ \
170
+ QDict *_resp = do_query_no_props(qts, cpu_type); \
171
+ g_assert(_resp); \
172
+ g_assert(!resp_has_props(_resp) || \
173
+ !qdict_get(resp_get_props(_resp), feature)); \
174
+ qobject_unref(_resp); \
175
+})
176
+
177
+static void assert_type_full(QTestState *qts)
178
+{
179
+ const char *error;
180
+ QDict *resp;
181
+
182
+ resp = qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', "
183
+ "'arguments': { 'type': 'static', "
184
+ "'model': { 'name': 'foo' }}}");
185
+ g_assert(resp);
186
+ error = resp_get_error(resp);
187
+ g_assert(error);
188
+ g_assert(g_str_equal(error,
189
+ "The requested expansion type is not supported"));
190
+ qobject_unref(resp);
191
+}
192
+
193
+static void assert_bad_props(QTestState *qts, const char *cpu_type)
194
+{
195
+ const char *error;
196
+ QDict *resp;
197
+
198
+ resp = qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', "
199
+ "'arguments': { 'type': 'full', "
200
+ "'model': { 'name': %s, "
201
+ "'props': false }}}",
202
+ cpu_type);
203
+ g_assert(resp);
204
+ error = resp_get_error(resp);
205
+ g_assert(error);
206
+ g_assert(g_str_equal(error,
207
+ "Invalid parameter type for 'props', expected: dict"));
208
+ qobject_unref(resp);
209
+}
210
+
211
+static void test_query_cpu_model_expansion(const void *data)
212
+{
213
+ QTestState *qts;
214
+
215
+ qts = qtest_init(MACHINE "-cpu max");
216
+
217
+ /* Test common query-cpu-model-expansion input validation */
218
+ assert_type_full(qts);
219
+ assert_bad_props(qts, "max");
220
+ assert_error(qts, "foo", "The CPU type 'foo' is not a recognized "
221
+ "ARM CPU type", NULL);
222
+ assert_error(qts, "max", "Parameter 'not-a-prop' is unexpected",
223
+ "{ 'not-a-prop': false }");
224
+ assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
225
+
226
+ /* Test expected feature presence/absence for some cpu types */
227
+ assert_has_feature(qts, "max", "pmu");
228
+ assert_has_feature(qts, "cortex-a15", "pmu");
229
+ assert_has_not_feature(qts, "cortex-a15", "aarch64");
230
+
231
+ if (g_str_equal(qtest_get_arch(), "aarch64")) {
232
+ assert_has_feature(qts, "max", "aarch64");
233
+ assert_has_feature(qts, "cortex-a57", "pmu");
234
+ assert_has_feature(qts, "cortex-a57", "aarch64");
235
+
236
+ /* Test that features that depend on KVM generate errors without. */
237
+ assert_error(qts, "max",
238
+ "'aarch64' feature cannot be disabled "
239
+ "unless KVM is enabled and 32-bit EL1 "
240
+ "is supported",
241
+ "{ 'aarch64': false }");
242
+ }
243
+
244
+ qtest_quit(qts);
245
+}
246
+
247
+static void test_query_cpu_model_expansion_kvm(const void *data)
248
+{
249
+ QTestState *qts;
250
+
251
+ qts = qtest_init(MACHINE "-accel kvm -cpu host");
252
+
253
+ if (g_str_equal(qtest_get_arch(), "aarch64")) {
254
+ assert_has_feature(qts, "host", "aarch64");
255
+ assert_has_feature(qts, "host", "pmu");
256
+
257
+ assert_error(qts, "cortex-a15",
258
+ "We cannot guarantee the CPU type 'cortex-a15' works "
259
+ "with KVM on this host", NULL);
260
+ } else {
261
+ assert_has_not_feature(qts, "host", "aarch64");
262
+ assert_has_not_feature(qts, "host", "pmu");
263
+ }
264
+
265
+ qtest_quit(qts);
266
+}
267
+
268
+int main(int argc, char **argv)
269
+{
270
+ bool kvm_available = false;
271
+
272
+ if (!access("/dev/kvm", R_OK | W_OK)) {
273
+#if defined(HOST_AARCH64)
274
+ kvm_available = g_str_equal(qtest_get_arch(), "aarch64");
275
+#elif defined(HOST_ARM)
276
+ kvm_available = g_str_equal(qtest_get_arch(), "arm");
277
+#endif
278
+ }
279
+
280
+ g_test_init(&argc, &argv, NULL);
281
+
282
+ qtest_add_data_func("/arm/query-cpu-model-expansion",
283
+ NULL, test_query_cpu_model_expansion);
284
+
285
+ if (kvm_available) {
286
+ qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
287
+ NULL, test_query_cpu_model_expansion_kvm);
288
+ }
289
+
290
+ return g_test_run();
291
+}
292
--
89
--
293
2.20.1
90
2.34.1
294
91
295
92
diff view generated by jsdifflib
1
Switch the fsl_etsec code away from bottom-half based ptimers to
1
The only place left that looks at the old 'singlestep' global
2
the new transaction-based ptimer API. This just requires adding
2
variable is the TCG curr_cflags() function. Replace the old global
3
begin/commit calls around the various places that modify the ptimer
3
with a new 'one_insn_per_tb' which is defined in tcg-all.c and
4
state, and using the new ptimer_init() function to create the timer.
4
declared in accel/tcg/internal.h. This keeps it restricted to the
5
TCG code, unlike 'singlestep' which was available to every file in
6
the system and defined in multiple different places for softmmu vs
7
linux-user vs bsd-user.
8
9
While we're making this change, use qatomic_read() and qatomic_set()
10
on the accesses to the new global, because TCG will read it without
11
holding a lock.
5
12
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20230417164041.684562-4-peter.maydell@linaro.org
10
Message-id: 20191017132122.4402-2-peter.maydell@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
17
---
13
hw/net/fsl_etsec/etsec.h | 1 -
18
accel/tcg/internal.h | 2 ++
14
hw/net/fsl_etsec/etsec.c | 9 +++++----
19
include/exec/cpu-common.h | 2 --
15
2 files changed, 5 insertions(+), 5 deletions(-)
20
accel/tcg/cpu-exec.c | 2 +-
21
accel/tcg/tcg-all.c | 6 ++++--
22
bsd-user/main.c | 1 -
23
linux-user/main.c | 1 -
24
softmmu/globals.c | 1 -
25
7 files changed, 7 insertions(+), 8 deletions(-)
16
26
17
diff --git a/hw/net/fsl_etsec/etsec.h b/hw/net/fsl_etsec/etsec.h
27
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
18
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/net/fsl_etsec/etsec.h
29
--- a/accel/tcg/internal.h
20
+++ b/hw/net/fsl_etsec/etsec.h
30
+++ b/accel/tcg/internal.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct eTSEC {
31
@@ -XXX,XX +XXX,XX @@ static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
22
uint16_t phy_control;
32
extern int64_t max_delay;
23
33
extern int64_t max_advance;
24
/* Polling */
34
25
- QEMUBH *bh;
35
+extern bool one_insn_per_tb;
26
struct ptimer_state *ptimer;
36
+
27
37
#endif /* ACCEL_TCG_INTERNAL_H */
28
/* Whether we should flush the rx queue when buffer becomes available. */
38
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
29
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
30
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/net/fsl_etsec/etsec.c
40
--- a/include/exec/cpu-common.h
32
+++ b/hw/net/fsl_etsec/etsec.c
41
+++ b/include/exec/cpu-common.h
42
@@ -XXX,XX +XXX,XX @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
43
void *ptr, size_t len, bool is_write);
44
45
/* vl.c */
46
-extern int singlestep;
47
-
48
void list_cpus(void);
49
50
#endif /* CPU_COMMON_H */
51
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/accel/tcg/cpu-exec.c
54
+++ b/accel/tcg/cpu-exec.c
55
@@ -XXX,XX +XXX,XX @@ uint32_t curr_cflags(CPUState *cpu)
56
*/
57
if (unlikely(cpu->singlestep_enabled)) {
58
cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR | CF_SINGLE_STEP | 1;
59
- } else if (singlestep) {
60
+ } else if (qatomic_read(&one_insn_per_tb)) {
61
cflags |= CF_NO_GOTO_TB | 1;
62
} else if (qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
63
cflags |= CF_NO_GOTO_TB;
64
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/accel/tcg/tcg-all.c
67
+++ b/accel/tcg/tcg-all.c
33
@@ -XXX,XX +XXX,XX @@
68
@@ -XXX,XX +XXX,XX @@
34
#include "etsec.h"
69
#include "qapi/error.h"
35
#include "registers.h"
70
#include "qemu/error-report.h"
36
#include "qemu/log.h"
71
#include "qemu/accel.h"
37
-#include "qemu/main-loop.h"
72
+#include "qemu/atomic.h"
38
#include "qemu/module.h"
73
#include "qapi/qapi-builtin-visit.h"
39
74
#include "qemu/units.h"
40
/* #define HEX_DUMP */
75
#if !defined(CONFIG_USER_ONLY)
41
@@ -XXX,XX +XXX,XX @@ static void write_dmactrl(eTSEC *etsec,
76
@@ -XXX,XX +XXX,XX @@ static void tcg_accel_instance_init(Object *obj)
42
43
if (!(value & DMACTRL_WOP)) {
44
/* Start polling */
45
+ ptimer_transaction_begin(etsec->ptimer);
46
ptimer_stop(etsec->ptimer);
47
ptimer_set_count(etsec->ptimer, 1);
48
ptimer_run(etsec->ptimer, 1);
49
+ ptimer_transaction_commit(etsec->ptimer);
50
}
51
}
77
}
52
78
53
@@ -XXX,XX +XXX,XX @@ static void etsec_realize(DeviceState *dev, Error **errp)
79
bool mttcg_enabled;
54
object_get_typename(OBJECT(dev)), dev->id, etsec);
80
+bool one_insn_per_tb;
55
qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);
81
56
82
static int tcg_init_machine(MachineState *ms)
57
-
83
{
58
- etsec->bh = qemu_bh_new(etsec_timer_hit, etsec);
84
@@ -XXX,XX +XXX,XX @@ static void tcg_set_one_insn_per_tb(Object *obj, bool value, Error **errp)
59
- etsec->ptimer = ptimer_init_with_bh(etsec->bh, PTIMER_POLICY_DEFAULT);
85
{
60
+ etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_DEFAULT);
86
TCGState *s = TCG_STATE(obj);
61
+ ptimer_transaction_begin(etsec->ptimer);
87
s->one_insn_per_tb = value;
62
ptimer_set_freq(etsec->ptimer, 100);
88
- /* For the moment, set the global also: this changes the behaviour */
63
+ ptimer_transaction_commit(etsec->ptimer);
89
- singlestep = value;
90
+ /* Set the global also: this changes the behaviour */
91
+ qatomic_set(&one_insn_per_tb, value);
64
}
92
}
65
93
66
static void etsec_instance_init(Object *obj)
94
static int tcg_gdbstub_supported_sstep_flags(void)
95
diff --git a/bsd-user/main.c b/bsd-user/main.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/bsd-user/main.c
98
+++ b/bsd-user/main.c
99
@@ -XXX,XX +XXX,XX @@
100
#include "host-os.h"
101
#include "target_arch_cpu.h"
102
103
-int singlestep;
104
static bool opt_one_insn_per_tb;
105
uintptr_t guest_base;
106
bool have_guest_base;
107
diff --git a/linux-user/main.c b/linux-user/main.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/linux-user/main.c
110
+++ b/linux-user/main.c
111
@@ -XXX,XX +XXX,XX @@
112
char *exec_path;
113
char real_exec_path[PATH_MAX];
114
115
-int singlestep;
116
static bool opt_one_insn_per_tb;
117
static const char *argv0;
118
static const char *gdbstub;
119
diff --git a/softmmu/globals.c b/softmmu/globals.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/softmmu/globals.c
122
+++ b/softmmu/globals.c
123
@@ -XXX,XX +XXX,XX @@ int vga_interface_type = VGA_NONE;
124
bool vga_interface_created;
125
Chardev *parallel_hds[MAX_PARALLEL_PORTS];
126
int win2k_install_hack;
127
-int singlestep;
128
int fd_bootchk = 1;
129
int graphic_rotate;
130
QEMUOptionRom option_rom[MAX_OPTION_ROMS];
67
--
131
--
68
2.20.1
132
2.34.1
69
133
70
134
diff view generated by jsdifflib
1
Switch the xilinx_axidma code away from bottom-half based ptimers to
1
The '-singlestep' option is confusing, because it doesn't actually
2
the new transaction-based ptimer API. This just requires adding
2
have anything to do with single-stepping the CPU. What it does do
3
begin/commit calls around the various places that modify the ptimer
3
is force TCG emulation to put one guest instruction in each TB,
4
state, and using the new ptimer_init() function to create the timer.
4
which can be useful in some situations.
5
6
Create a new command line argument -one-insn-per-tb, so we can
7
document that -singlestep is just a deprecated synonym for it,
8
and eventually perhaps drop it.
5
9
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Warner Losh <imp@bsdimp.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20191017132122.4402-4-peter.maydell@linaro.org
14
Message-id: 20230417164041.684562-5-peter.maydell@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
15
---
13
hw/dma/xilinx_axidma.c | 9 +++++----
16
docs/user/main.rst | 7 ++++++-
14
1 file changed, 5 insertions(+), 4 deletions(-)
17
linux-user/main.c | 9 ++++++---
18
2 files changed, 12 insertions(+), 4 deletions(-)
15
19
16
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
20
diff --git a/docs/user/main.rst b/docs/user/main.rst
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/dma/xilinx_axidma.c
22
--- a/docs/user/main.rst
19
+++ b/hw/dma/xilinx_axidma.c
23
+++ b/docs/user/main.rst
20
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ Debug options:
21
#include "hw/ptimer.h"
25
``-g port``
22
#include "hw/qdev-properties.h"
26
Wait gdb connection to port
23
#include "qemu/log.h"
27
24
-#include "qemu/main-loop.h"
28
+``-one-insn-per-tb``
25
#include "qemu/module.h"
29
+ Run the emulation with one guest instruction per translation block.
26
30
+ This slows down emulation a lot, but can be useful in some situations,
27
#include "hw/stream.h"
31
+ such as when trying to analyse the logs produced by the ``-d`` option.
28
@@ -XXX,XX +XXX,XX @@ enum {
32
+
29
};
33
``-singlestep``
30
34
- Run the emulation in single step mode.
31
struct Stream {
35
+ This is a deprecated synonym for the ``-one-insn-per-tb`` option.
32
- QEMUBH *bh;
36
33
ptimer_state *ptimer;
37
Environment variables:
34
qemu_irq irq;
38
35
39
diff --git a/linux-user/main.c b/linux-user/main.c
36
@@ -XXX,XX +XXX,XX @@ static void stream_complete(struct Stream *s)
40
index XXXXXXX..XXXXXXX 100644
37
unsigned int comp_delay;
41
--- a/linux-user/main.c
38
42
+++ b/linux-user/main.c
39
/* Start the delayed timer. */
43
@@ -XXX,XX +XXX,XX @@ static void handle_arg_reserved_va(const char *arg)
40
+ ptimer_transaction_begin(s->ptimer);
44
reserved_va = val ? val - 1 : 0;
41
comp_delay = s->regs[R_DMACR] >> 24;
42
if (comp_delay) {
43
ptimer_stop(s->ptimer);
44
@@ -XXX,XX +XXX,XX @@ static void stream_complete(struct Stream *s)
45
s->regs[R_DMASR] |= DMASR_IOC_IRQ;
46
stream_reload_complete_cnt(s);
47
}
48
+ ptimer_transaction_commit(s->ptimer);
49
}
45
}
50
46
51
static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
47
-static void handle_arg_singlestep(const char *arg)
52
@@ -XXX,XX +XXX,XX @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
48
+static void handle_arg_one_insn_per_tb(const char *arg)
53
struct Stream *st = &s->streams[i];
49
{
54
50
opt_one_insn_per_tb = true;
55
st->nr = i;
51
}
56
- st->bh = qemu_bh_new(timer_hit, st);
52
@@ -XXX,XX +XXX,XX @@ static const struct qemu_argument arg_table[] = {
57
- st->ptimer = ptimer_init_with_bh(st->bh, PTIMER_POLICY_DEFAULT);
53
"logfile", "write logs to 'logfile' (default stderr)"},
58
+ st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_DEFAULT);
54
{"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
59
+ ptimer_transaction_begin(st->ptimer);
55
"pagesize", "set the host page size to 'pagesize'"},
60
ptimer_set_freq(st->ptimer, s->freqhz);
56
- {"singlestep", "QEMU_SINGLESTEP", false, handle_arg_singlestep,
61
+ ptimer_transaction_commit(st->ptimer);
57
- "", "run in singlestep mode"},
62
}
58
+ {"one-insn-per-tb",
63
return;
59
+ "QEMU_ONE_INSN_PER_TB", false, handle_arg_one_insn_per_tb,
64
60
+ "", "run with one guest instruction per emulated TB"},
61
+ {"singlestep", "QEMU_SINGLESTEP", false, handle_arg_one_insn_per_tb,
62
+ "", "deprecated synonym for -one-insn-per-tb"},
63
{"strace", "QEMU_STRACE", false, handle_arg_strace,
64
"", "log system calls"},
65
{"seed", "QEMU_RAND_SEED", true, handle_arg_seed,
65
--
66
--
66
2.20.1
67
2.34.1
67
68
68
69
diff view generated by jsdifflib
1
Switch the milkymist-sysctl code away from bottom-half based
1
The '-singlestep' option is confusing, because it doesn't actually
2
ptimers to the new transaction-based ptimer API. This just requires
2
have anything to do with single-stepping the CPU. What it does do
3
adding begin/commit calls around the various places that modify the
3
is force TCG emulation to put one guest instruction in each TB,
4
ptimer state, and using the new ptimer_init() function to create the
4
which can be useful in some situations.
5
timer.
5
6
Create a new command line argument -one-insn-per-tb, so we can
7
document that -singlestep is just a deprecated synonym for it,
8
and eventually perhaps drop it.
6
9
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Warner Losh <imp@bsdimp.com>
9
Message-id: 20191021141040.11007-1-peter.maydell@linaro.org
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-id: 20230417164041.684562-6-peter.maydell@linaro.org
10
---
15
---
11
hw/timer/milkymist-sysctl.c | 25 ++++++++++++++++++-------
16
docs/user/main.rst | 7 ++++++-
12
1 file changed, 18 insertions(+), 7 deletions(-)
17
bsd-user/main.c | 5 +++--
18
2 files changed, 9 insertions(+), 3 deletions(-)
13
19
14
diff --git a/hw/timer/milkymist-sysctl.c b/hw/timer/milkymist-sysctl.c
20
diff --git a/docs/user/main.rst b/docs/user/main.rst
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/timer/milkymist-sysctl.c
22
--- a/docs/user/main.rst
17
+++ b/hw/timer/milkymist-sysctl.c
23
+++ b/docs/user/main.rst
18
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ Debug options:
19
#include "hw/ptimer.h"
25
``-p pagesize``
20
#include "hw/qdev-properties.h"
26
Act as if the host page size was 'pagesize' bytes
21
#include "qemu/error-report.h"
27
22
-#include "qemu/main-loop.h"
28
+``-one-insn-per-tb``
23
#include "qemu/module.h"
29
+ Run the emulation with one guest instruction per translation block.
24
30
+ This slows down emulation a lot, but can be useful in some situations,
25
enum {
31
+ such as when trying to analyse the logs produced by the ``-d`` option.
26
@@ -XXX,XX +XXX,XX @@ struct MilkymistSysctlState {
32
+
27
33
``-singlestep``
28
MemoryRegion regs_region;
34
- Run the emulation in single step mode.
29
35
+ This is a deprecated synonym for the ``-one-insn-per-tb`` option.
30
- QEMUBH *bh0;
36
diff --git a/bsd-user/main.c b/bsd-user/main.c
31
- QEMUBH *bh1;
37
index XXXXXXX..XXXXXXX 100644
32
ptimer_state *ptimer0;
38
--- a/bsd-user/main.c
33
ptimer_state *ptimer1;
39
+++ b/bsd-user/main.c
34
40
@@ -XXX,XX +XXX,XX @@ static void usage(void)
35
@@ -XXX,XX +XXX,XX @@ static void sysctl_write(void *opaque, hwaddr addr, uint64_t value,
41
"-d item1[,...] enable logging of specified items\n"
36
s->regs[addr] = value;
42
" (use '-d help' for a list of log items)\n"
37
break;
43
"-D logfile write logs to 'logfile' (default stderr)\n"
38
case R_TIMER0_COMPARE:
44
- "-singlestep always run in singlestep mode\n"
39
+ ptimer_transaction_begin(s->ptimer0);
45
+ "-one-insn-per-tb run with one guest instruction per emulated TB\n"
40
ptimer_set_limit(s->ptimer0, value, 0);
46
+ "-singlestep deprecated synonym for -one-insn-per-tb\n"
41
s->regs[addr] = value;
47
"-strace log system calls\n"
42
+ ptimer_transaction_commit(s->ptimer0);
48
"-trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
43
break;
49
" specify tracing options\n"
44
case R_TIMER1_COMPARE:
50
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
45
+ ptimer_transaction_begin(s->ptimer1);
51
(void) envlist_unsetenv(envlist, "LD_PRELOAD");
46
ptimer_set_limit(s->ptimer1, value, 0);
52
} else if (!strcmp(r, "seed")) {
47
s->regs[addr] = value;
53
seed_optarg = optarg;
48
+ ptimer_transaction_commit(s->ptimer1);
54
- } else if (!strcmp(r, "singlestep")) {
49
break;
55
+ } else if (!strcmp(r, "singlestep") || !strcmp(r, "one-insn-per-tb")) {
50
case R_TIMER0_CONTROL:
56
opt_one_insn_per_tb = true;
51
+ ptimer_transaction_begin(s->ptimer0);
57
} else if (!strcmp(r, "strace")) {
52
s->regs[addr] = value;
58
do_strace = 1;
53
if (s->regs[R_TIMER0_CONTROL] & CTRL_ENABLE) {
54
trace_milkymist_sysctl_start_timer0();
55
@@ -XXX,XX +XXX,XX @@ static void sysctl_write(void *opaque, hwaddr addr, uint64_t value,
56
trace_milkymist_sysctl_stop_timer0();
57
ptimer_stop(s->ptimer0);
58
}
59
+ ptimer_transaction_commit(s->ptimer0);
60
break;
61
case R_TIMER1_CONTROL:
62
+ ptimer_transaction_begin(s->ptimer1);
63
s->regs[addr] = value;
64
if (s->regs[R_TIMER1_CONTROL] & CTRL_ENABLE) {
65
trace_milkymist_sysctl_start_timer1();
66
@@ -XXX,XX +XXX,XX @@ static void sysctl_write(void *opaque, hwaddr addr, uint64_t value,
67
trace_milkymist_sysctl_stop_timer1();
68
ptimer_stop(s->ptimer1);
69
}
70
+ ptimer_transaction_commit(s->ptimer1);
71
break;
72
case R_ICAP:
73
sysctl_icap_write(s, value);
74
@@ -XXX,XX +XXX,XX @@ static void milkymist_sysctl_reset(DeviceState *d)
75
s->regs[i] = 0;
76
}
77
78
+ ptimer_transaction_begin(s->ptimer0);
79
ptimer_stop(s->ptimer0);
80
+ ptimer_transaction_commit(s->ptimer0);
81
+ ptimer_transaction_begin(s->ptimer1);
82
ptimer_stop(s->ptimer1);
83
+ ptimer_transaction_commit(s->ptimer1);
84
85
/* defaults */
86
s->regs[R_ICAP] = ICAP_READY;
87
@@ -XXX,XX +XXX,XX @@ static void milkymist_sysctl_realize(DeviceState *dev, Error **errp)
88
{
89
MilkymistSysctlState *s = MILKYMIST_SYSCTL(dev);
90
91
- s->bh0 = qemu_bh_new(timer0_hit, s);
92
- s->bh1 = qemu_bh_new(timer1_hit, s);
93
- s->ptimer0 = ptimer_init_with_bh(s->bh0, PTIMER_POLICY_DEFAULT);
94
- s->ptimer1 = ptimer_init_with_bh(s->bh1, PTIMER_POLICY_DEFAULT);
95
+ s->ptimer0 = ptimer_init(timer0_hit, s, PTIMER_POLICY_DEFAULT);
96
+ s->ptimer1 = ptimer_init(timer1_hit, s, PTIMER_POLICY_DEFAULT);
97
98
+ ptimer_transaction_begin(s->ptimer0);
99
ptimer_set_freq(s->ptimer0, s->freq_hz);
100
+ ptimer_transaction_commit(s->ptimer0);
101
+ ptimer_transaction_begin(s->ptimer1);
102
ptimer_set_freq(s->ptimer1, s->freq_hz);
103
+ ptimer_transaction_commit(s->ptimer1);
104
}
105
106
static const VMStateDescription vmstate_milkymist_sysctl = {
107
--
59
--
108
2.20.1
60
2.34.1
109
61
110
62
diff view generated by jsdifflib
1
Switch the grlib_gptimer code away from bottom-half based ptimers to
1
Document that the -singlestep command line option is now
2
the new transaction-based ptimer API. This just requires adding
2
deprecated, as it is replaced by either the TCG accelerator
3
begin/commit calls around the various places that modify the ptimer
3
property 'one-insn-per-tb' for system emulation or the new
4
state, and using the new ptimer_init() function to create the timer.
4
'-one-insn-per-tb' option for usermode emulation, and remove
5
the only use of the deprecated syntax from a README.
5
6
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20191021134357.14266-3-peter.maydell@linaro.org
10
Message-id: 20230417164041.684562-7-peter.maydell@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/timer/grlib_gptimer.c | 28 ++++++++++++++++++++++++----
12
docs/about/deprecated.rst | 16 ++++++++++++++++
13
1 file changed, 24 insertions(+), 4 deletions(-)
13
qemu-options.hx | 5 +++--
14
tcg/tci/README | 2 +-
15
3 files changed, 20 insertions(+), 3 deletions(-)
14
16
15
diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c
17
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/timer/grlib_gptimer.c
19
--- a/docs/about/deprecated.rst
18
+++ b/hw/timer/grlib_gptimer.c
20
+++ b/docs/about/deprecated.rst
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ Use ``-machine acpi=off`` instead.
20
#include "hw/irq.h"
22
The HAXM project has been retired (see https://github.com/intel/haxm#status).
21
#include "hw/ptimer.h"
23
Use "whpx" (on Windows) or "hvf" (on macOS) instead.
22
#include "hw/qdev-properties.h"
24
23
-#include "qemu/main-loop.h"
25
+``-singlestep`` (since 8.1)
24
#include "qemu/module.h"
26
+'''''''''''''''''''''''''''
25
26
#include "trace.h"
27
@@ -XXX,XX +XXX,XX @@ typedef struct GPTimer GPTimer;
28
typedef struct GPTimerUnit GPTimerUnit;
29
30
struct GPTimer {
31
- QEMUBH *bh;
32
struct ptimer_state *ptimer;
33
34
qemu_irq irq;
35
@@ -XXX,XX +XXX,XX @@ struct GPTimerUnit {
36
uint32_t config;
37
};
38
39
+static void grlib_gptimer_tx_begin(GPTimer *timer)
40
+{
41
+ ptimer_transaction_begin(timer->ptimer);
42
+}
43
+
27
+
44
+static void grlib_gptimer_tx_commit(GPTimer *timer)
28
+The ``-singlestep`` option has been turned into an accelerator property,
45
+{
29
+and given a name that better reflects what it actually does.
46
+ ptimer_transaction_commit(timer->ptimer);
30
+Use ``-accel tcg,one-insn-per-tb=on`` instead.
47
+}
48
+
31
+
49
+/* Must be called within grlib_gptimer_tx_begin/commit block */
32
+User-mode emulator command line arguments
50
static void grlib_gptimer_enable(GPTimer *timer)
33
+-----------------------------------------
51
{
34
+
52
assert(timer != NULL);
35
+``-singlestep`` (since 8.1)
53
@@ -XXX,XX +XXX,XX @@ static void grlib_gptimer_enable(GPTimer *timer)
36
+'''''''''''''''''''''''''''
54
ptimer_run(timer->ptimer, 1);
37
+
55
}
38
+The ``-singlestep`` option has been given a name that better reflects
56
39
+what it actually does. For both linux-user and bsd-user, use the
57
+/* Must be called within grlib_gptimer_tx_begin/commit block */
40
+new ``-one-insn-per-tb`` option instead.
58
static void grlib_gptimer_restart(GPTimer *timer)
41
59
{
42
QEMU Machine Protocol (QMP) commands
60
assert(timer != NULL);
43
------------------------------------
61
@@ -XXX,XX +XXX,XX @@ static void grlib_gptimer_set_scaler(GPTimerUnit *unit, uint32_t scaler)
44
diff --git a/qemu-options.hx b/qemu-options.hx
62
trace_grlib_gptimer_set_scaler(scaler, value);
45
index XXXXXXX..XXXXXXX 100644
63
46
--- a/qemu-options.hx
64
for (i = 0; i < unit->nr_timers; i++) {
47
+++ b/qemu-options.hx
65
+ ptimer_transaction_begin(unit->timers[i].ptimer);
48
@@ -XXX,XX +XXX,XX @@ SRST
66
ptimer_set_freq(unit->timers[i].ptimer, value);
49
ERST
67
+ ptimer_transaction_commit(unit->timers[i].ptimer);
50
68
}
51
DEF("singlestep", 0, QEMU_OPTION_singlestep, \
69
}
52
- "-singlestep always run in singlestep mode\n", QEMU_ARCH_ALL)
70
53
+ "-singlestep deprecated synonym for -accel tcg,one-insn-per-tb=on\n", QEMU_ARCH_ALL)
71
@@ -XXX,XX +XXX,XX @@ static void grlib_gptimer_write(void *opaque, hwaddr addr,
54
SRST
72
switch (timer_addr) {
55
``-singlestep``
73
case COUNTER_OFFSET:
56
- Run the emulation in single step mode.
74
trace_grlib_gptimer_writel(id, addr, value);
57
+ This is a deprecated synonym for the TCG accelerator property
75
+ grlib_gptimer_tx_begin(&unit->timers[id]);
58
+ ``one-insn-per-tb``.
76
unit->timers[id].counter = value;
59
ERST
77
grlib_gptimer_enable(&unit->timers[id]);
60
78
+ grlib_gptimer_tx_commit(&unit->timers[id]);
61
DEF("preconfig", 0, QEMU_OPTION_preconfig, \
79
return;
62
diff --git a/tcg/tci/README b/tcg/tci/README
80
63
index XXXXXXX..XXXXXXX 100644
81
case COUNTER_RELOAD_OFFSET:
64
--- a/tcg/tci/README
82
@@ -XXX,XX +XXX,XX @@ static void grlib_gptimer_write(void *opaque, hwaddr addr,
65
+++ b/tcg/tci/README
83
/* gptimer_restart calls gptimer_enable, so if "enable" and "load"
66
@@ -XXX,XX +XXX,XX @@ The only difference from running QEMU with TCI to running without TCI
84
bits are present, we just have to call restart. */
67
should be speed. Especially during development of TCI, it was very
85
68
useful to compare runs with and without TCI. Create /tmp/qemu.log by
86
+ grlib_gptimer_tx_begin(&unit->timers[id]);
69
87
if (value & GPTIMER_LOAD) {
70
- qemu-system-i386 -d in_asm,op_opt,cpu -D /tmp/qemu.log -singlestep
88
grlib_gptimer_restart(&unit->timers[id]);
71
+ qemu-system-i386 -d in_asm,op_opt,cpu -D /tmp/qemu.log -accel tcg,one-insn-per-tb=on
89
} else if (value & GPTIMER_ENABLE) {
72
90
@@ -XXX,XX +XXX,XX @@ static void grlib_gptimer_write(void *opaque, hwaddr addr,
73
once with interpreter and once without interpreter and compare the resulting
91
value &= ~(GPTIMER_LOAD & GPTIMER_DEBUG_HALT);
74
qemu.log files. This is also useful to see the effects of additional
92
93
unit->timers[id].config = value;
94
+ grlib_gptimer_tx_commit(&unit->timers[id]);
95
return;
96
97
default:
98
@@ -XXX,XX +XXX,XX @@ static void grlib_gptimer_reset(DeviceState *d)
99
timer->counter = 0;
100
timer->reload = 0;
101
timer->config = 0;
102
+ ptimer_transaction_begin(timer->ptimer);
103
ptimer_stop(timer->ptimer);
104
ptimer_set_count(timer->ptimer, 0);
105
ptimer_set_freq(timer->ptimer, unit->freq_hz);
106
+ ptimer_transaction_commit(timer->ptimer);
107
}
108
}
109
110
@@ -XXX,XX +XXX,XX @@ static void grlib_gptimer_realize(DeviceState *dev, Error **errp)
111
GPTimer *timer = &unit->timers[i];
112
113
timer->unit = unit;
114
- timer->bh = qemu_bh_new(grlib_gptimer_hit, timer);
115
- timer->ptimer = ptimer_init_with_bh(timer->bh, PTIMER_POLICY_DEFAULT);
116
+ timer->ptimer = ptimer_init(grlib_gptimer_hit, timer,
117
+ PTIMER_POLICY_DEFAULT);
118
timer->id = i;
119
120
/* One IRQ line for each timer */
121
sysbus_init_irq(sbd, &timer->irq);
122
123
+ ptimer_transaction_begin(timer->ptimer);
124
ptimer_set_freq(timer->ptimer, unit->freq_hz);
125
+ ptimer_transaction_commit(timer->ptimer);
126
}
127
128
memory_region_init_io(&unit->iomem, OBJECT(unit), &grlib_gptimer_ops,
129
--
75
--
130
2.20.1
76
2.34.1
131
77
132
78
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
Currently we report whether the TCG accelerator is in
2
'one-insn-per-tb' mode in the 'info status' output. This is a pretty
3
minor piece of TCG specific information, and we want to deprecate the
4
'singlestep' field of the associated QMP command. Move the
5
'one-insn-per-tb' reporting to 'info jit'.
2
6
3
Add support for the query-cpu-model-expansion QMP command to Arm. We
7
We don't need a deprecate-and-drop period for this because the
4
do this selectively, only exposing CPU properties which represent
8
HMP interface has no stability guarantees.
5
optional CPU features which the user may want to enable/disable.
6
Additionally we restrict the list of queryable cpu models to 'max',
7
'host', or the current type when KVM is in use. And, finally, we only
8
implement expansion type 'full', as Arm does not yet have a "base"
9
CPU type. More details and example queries are described in a new
10
document (docs/arm-cpu-features.rst).
11
9
12
Note, certainly more features may be added to the list of advertised
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
features, e.g. 'vfp' and 'neon'. The only requirement is that we can
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
detect invalid configurations and emit failures at QMP query time.
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
For 'vfp' and 'neon' this will require some refactoring to share a
13
Message-id: 20230417164041.684562-8-peter.maydell@linaro.org
16
validation function between the QMP query and the CPU realize
14
---
17
functions.
15
accel/tcg/monitor.c | 14 ++++++++++++++
16
softmmu/runstate-hmp-cmds.c | 5 ++---
17
2 files changed, 16 insertions(+), 3 deletions(-)
18
18
19
Signed-off-by: Andrew Jones <drjones@redhat.com>
19
diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Eric Auger <eric.auger@redhat.com>
22
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
23
Message-id: 20191024121808.9612-2-drjones@redhat.com
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
26
qapi/machine-target.json | 6 +-
27
target/arm/monitor.c | 146 ++++++++++++++++++++++++++++++++++++++
28
docs/arm-cpu-features.rst | 137 +++++++++++++++++++++++++++++++++++
29
3 files changed, 286 insertions(+), 3 deletions(-)
30
create mode 100644 docs/arm-cpu-features.rst
31
32
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
33
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
34
--- a/qapi/machine-target.json
21
--- a/accel/tcg/monitor.c
35
+++ b/qapi/machine-target.json
22
+++ b/accel/tcg/monitor.c
36
@@ -XXX,XX +XXX,XX @@
37
##
38
{ 'struct': 'CpuModelExpansionInfo',
39
'data': { 'model': 'CpuModelInfo' },
40
- 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
41
+ 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_ARM)' }
42
43
##
44
# @query-cpu-model-expansion:
45
@@ -XXX,XX +XXX,XX @@
46
# query-cpu-model-expansion while using these is not advised.
47
#
48
# Some architectures may not support all expansion types. s390x supports
49
-# "full" and "static".
50
+# "full" and "static". Arm only supports "full".
51
#
52
# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is
53
# not supported, if the model cannot be expanded, if the model contains
54
@@ -XXX,XX +XXX,XX @@
55
'data': { 'type': 'CpuModelExpansionType',
56
'model': 'CpuModelInfo' },
57
'returns': 'CpuModelExpansionInfo',
58
- 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
59
+ 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_ARM)' }
60
61
##
62
# @CpuDefinitionInfo:
63
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/monitor.c
66
+++ b/target/arm/monitor.c
67
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
68
*/
24
*/
69
25
70
#include "qemu/osdep.h"
26
#include "qemu/osdep.h"
71
+#include "hw/boards.h"
27
+#include "qemu/accel.h"
72
#include "kvm_arm.h"
28
#include "qapi/error.h"
73
+#include "qapi/error.h"
29
#include "qapi/type-helpers.h"
74
+#include "qapi/visitor.h"
30
#include "qapi/qapi-commands-machine.h"
75
+#include "qapi/qobject-input-visitor.h"
31
@@ -XXX,XX +XXX,XX @@ static void dump_drift_info(GString *buf)
76
+#include "qapi/qapi-commands-machine-target.h"
32
}
77
#include "qapi/qapi-commands-misc-target.h"
33
}
78
+#include "qapi/qmp/qerror.h"
34
79
+#include "qapi/qmp/qdict.h"
35
+static void dump_accel_info(GString *buf)
80
+#include "qom/qom-qobject.h"
36
+{
81
37
+ AccelState *accel = current_accel();
82
static GICCapability *gic_cap_new(int version)
38
+ bool one_insn_per_tb = object_property_get_bool(OBJECT(accel),
39
+ "one-insn-per-tb",
40
+ &error_fatal);
41
+
42
+ g_string_append_printf(buf, "Accelerator settings:\n");
43
+ g_string_append_printf(buf, "one-insn-per-tb: %s\n\n",
44
+ one_insn_per_tb ? "on" : "off");
45
+}
46
+
47
HumanReadableText *qmp_x_query_jit(Error **errp)
83
{
48
{
84
@@ -XXX,XX +XXX,XX @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
49
g_autoptr(GString) buf = g_string_new("");
85
50
@@ -XXX,XX +XXX,XX @@ HumanReadableText *qmp_x_query_jit(Error **errp)
86
return head;
51
return NULL;
87
}
52
}
88
+
53
89
+/*
54
+ dump_accel_info(buf);
90
+ * These are cpu model features we want to advertise. The order here
55
dump_exec_info(buf);
91
+ * matters as this is the order in which qmp_query_cpu_model_expansion
56
dump_drift_info(buf);
92
+ * will attempt to set them. If there are dependencies between features,
57
93
+ * then the order that considers those dependencies must be used.
58
diff --git a/softmmu/runstate-hmp-cmds.c b/softmmu/runstate-hmp-cmds.c
94
+ */
59
index XXXXXXX..XXXXXXX 100644
95
+static const char *cpu_model_advertised_features[] = {
60
--- a/softmmu/runstate-hmp-cmds.c
96
+ "aarch64", "pmu",
61
+++ b/softmmu/runstate-hmp-cmds.c
97
+ NULL
62
@@ -XXX,XX +XXX,XX @@ void hmp_info_status(Monitor *mon, const QDict *qdict)
98
+};
63
99
+
64
info = qmp_query_status(NULL);
100
+CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
65
101
+ CpuModelInfo *model,
66
- monitor_printf(mon, "VM status: %s%s",
102
+ Error **errp)
67
- info->running ? "running" : "paused",
103
+{
68
- info->singlestep ? " (single step mode)" : "");
104
+ CpuModelExpansionInfo *expansion_info;
69
+ monitor_printf(mon, "VM status: %s",
105
+ const QDict *qdict_in = NULL;
70
+ info->running ? "running" : "paused");
106
+ QDict *qdict_out;
71
107
+ ObjectClass *oc;
72
if (!info->running && info->status != RUN_STATE_PAUSED) {
108
+ Object *obj;
73
monitor_printf(mon, " (%s)", RunState_str(info->status));
109
+ const char *name;
110
+ int i;
111
+
112
+ if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
113
+ error_setg(errp, "The requested expansion type is not supported");
114
+ return NULL;
115
+ }
116
+
117
+ if (!kvm_enabled() && !strcmp(model->name, "host")) {
118
+ error_setg(errp, "The CPU type '%s' requires KVM", model->name);
119
+ return NULL;
120
+ }
121
+
122
+ oc = cpu_class_by_name(TYPE_ARM_CPU, model->name);
123
+ if (!oc) {
124
+ error_setg(errp, "The CPU type '%s' is not a recognized ARM CPU type",
125
+ model->name);
126
+ return NULL;
127
+ }
128
+
129
+ if (kvm_enabled()) {
130
+ const char *cpu_type = current_machine->cpu_type;
131
+ int len = strlen(cpu_type) - strlen(ARM_CPU_TYPE_SUFFIX);
132
+ bool supported = false;
133
+
134
+ if (!strcmp(model->name, "host") || !strcmp(model->name, "max")) {
135
+ /* These are kvmarm's recommended cpu types */
136
+ supported = true;
137
+ } else if (strlen(model->name) == len &&
138
+ !strncmp(model->name, cpu_type, len)) {
139
+ /* KVM is enabled and we're using this type, so it works. */
140
+ supported = true;
141
+ }
142
+ if (!supported) {
143
+ error_setg(errp, "We cannot guarantee the CPU type '%s' works "
144
+ "with KVM on this host", model->name);
145
+ return NULL;
146
+ }
147
+ }
148
+
149
+ if (model->props) {
150
+ qdict_in = qobject_to(QDict, model->props);
151
+ if (!qdict_in) {
152
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
153
+ return NULL;
154
+ }
155
+ }
156
+
157
+ obj = object_new(object_class_get_name(oc));
158
+
159
+ if (qdict_in) {
160
+ Visitor *visitor;
161
+ Error *err = NULL;
162
+
163
+ visitor = qobject_input_visitor_new(model->props);
164
+ visit_start_struct(visitor, NULL, NULL, 0, &err);
165
+ if (err) {
166
+ visit_free(visitor);
167
+ object_unref(obj);
168
+ error_propagate(errp, err);
169
+ return NULL;
170
+ }
171
+
172
+ i = 0;
173
+ while ((name = cpu_model_advertised_features[i++]) != NULL) {
174
+ if (qdict_get(qdict_in, name)) {
175
+ object_property_set(obj, visitor, name, &err);
176
+ if (err) {
177
+ break;
178
+ }
179
+ }
180
+ }
181
+
182
+ if (!err) {
183
+ visit_check_struct(visitor, &err);
184
+ }
185
+ visit_end_struct(visitor, NULL);
186
+ visit_free(visitor);
187
+ if (err) {
188
+ object_unref(obj);
189
+ error_propagate(errp, err);
190
+ return NULL;
191
+ }
192
+ }
193
+
194
+ expansion_info = g_new0(CpuModelExpansionInfo, 1);
195
+ expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
196
+ expansion_info->model->name = g_strdup(model->name);
197
+
198
+ qdict_out = qdict_new();
199
+
200
+ i = 0;
201
+ while ((name = cpu_model_advertised_features[i++]) != NULL) {
202
+ ObjectProperty *prop = object_property_find(obj, name, NULL);
203
+ if (prop) {
204
+ Error *err = NULL;
205
+ QObject *value;
206
+
207
+ assert(prop->get);
208
+ value = object_property_get_qobject(obj, name, &err);
209
+ assert(!err);
210
+
211
+ qdict_put_obj(qdict_out, name, value);
212
+ }
213
+ }
214
+
215
+ if (!qdict_size(qdict_out)) {
216
+ qobject_unref(qdict_out);
217
+ } else {
218
+ expansion_info->model->props = QOBJECT(qdict_out);
219
+ expansion_info->model->has_props = true;
220
+ }
221
+
222
+ object_unref(obj);
223
+
224
+ return expansion_info;
225
+}
226
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
227
new file mode 100644
228
index XXXXXXX..XXXXXXX
229
--- /dev/null
230
+++ b/docs/arm-cpu-features.rst
231
@@ -XXX,XX +XXX,XX @@
232
+================
233
+ARM CPU Features
234
+================
235
+
236
+Examples of probing and using ARM CPU features
237
+
238
+Introduction
239
+============
240
+
241
+CPU features are optional features that a CPU of supporting type may
242
+choose to implement or not. In QEMU, optional CPU features have
243
+corresponding boolean CPU proprieties that, when enabled, indicate
244
+that the feature is implemented, and, conversely, when disabled,
245
+indicate that it is not implemented. An example of an ARM CPU feature
246
+is the Performance Monitoring Unit (PMU). CPU types such as the
247
+Cortex-A15 and the Cortex-A57, which respectively implement ARM
248
+architecture reference manuals ARMv7-A and ARMv8-A, may both optionally
249
+implement PMUs. For example, if a user wants to use a Cortex-A15 without
250
+a PMU, then the `-cpu` parameter should contain `pmu=off` on the QEMU
251
+command line, i.e. `-cpu cortex-a15,pmu=off`.
252
+
253
+As not all CPU types support all optional CPU features, then whether or
254
+not a CPU property exists depends on the CPU type. For example, CPUs
255
+that implement the ARMv8-A architecture reference manual may optionally
256
+support the AArch32 CPU feature, which may be enabled by disabling the
257
+`aarch64` CPU property. A CPU type such as the Cortex-A15, which does
258
+not implement ARMv8-A, will not have the `aarch64` CPU property.
259
+
260
+QEMU's support may be limited for some CPU features, only partially
261
+supporting the feature or only supporting the feature under certain
262
+configurations. For example, the `aarch64` CPU feature, which, when
263
+disabled, enables the optional AArch32 CPU feature, is only supported
264
+when using the KVM accelerator and when running on a host CPU type that
265
+supports the feature.
266
+
267
+CPU Feature Probing
268
+===================
269
+
270
+Determining which CPU features are available and functional for a given
271
+CPU type is possible with the `query-cpu-model-expansion` QMP command.
272
+Below are some examples where `scripts/qmp/qmp-shell` (see the top comment
273
+block in the script for usage) is used to issue the QMP commands.
274
+
275
+(1) Determine which CPU features are available for the `max` CPU type
276
+ (Note, we started QEMU with qemu-system-aarch64, so `max` is
277
+ implementing the ARMv8-A reference manual in this case)::
278
+
279
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max"}
280
+ { "return": {
281
+ "model": { "name": "max", "props": {
282
+ "pmu": true, "aarch64": true
283
+ }}}}
284
+
285
+We see that the `max` CPU type has the `pmu` and `aarch64` CPU features.
286
+We also see that the CPU features are enabled, as they are all `true`.
287
+
288
+(2) Let's try to disable the PMU::
289
+
290
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"pmu":false}}
291
+ { "return": {
292
+ "model": { "name": "max", "props": {
293
+ "pmu": false, "aarch64": true
294
+ }}}}
295
+
296
+We see it worked, as `pmu` is now `false`.
297
+
298
+(3) Let's try to disable `aarch64`, which enables the AArch32 CPU feature::
299
+
300
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"aarch64":false}}
301
+ {"error": {
302
+ "class": "GenericError", "desc":
303
+ "'aarch64' feature cannot be disabled unless KVM is enabled and 32-bit EL1 is supported"
304
+ }}
305
+
306
+It looks like this feature is limited to a configuration we do not
307
+currently have.
308
+
309
+(4) Let's try probing CPU features for the Cortex-A15 CPU type::
310
+
311
+ (QEMU) query-cpu-model-expansion type=full model={"name":"cortex-a15"}
312
+ {"return": {"model": {"name": "cortex-a15", "props": {"pmu": true}}}}
313
+
314
+Only the `pmu` CPU feature is available.
315
+
316
+A note about CPU feature dependencies
317
+-------------------------------------
318
+
319
+It's possible for features to have dependencies on other features. I.e.
320
+it may be possible to change one feature at a time without error, but
321
+when attempting to change all features at once an error could occur
322
+depending on the order they are processed. It's also possible changing
323
+all at once doesn't generate an error, because a feature's dependencies
324
+are satisfied with other features, but the same feature cannot be changed
325
+independently without error. For these reasons callers should always
326
+attempt to make their desired changes all at once in order to ensure the
327
+collection is valid.
328
+
329
+A note about CPU models and KVM
330
+-------------------------------
331
+
332
+Named CPU models generally do not work with KVM. There are a few cases
333
+that do work, e.g. using the named CPU model `cortex-a57` with KVM on a
334
+seattle host, but mostly if KVM is enabled the `host` CPU type must be
335
+used. This means the guest is provided all the same CPU features as the
336
+host CPU type has. And, for this reason, the `host` CPU type should
337
+enable all CPU features that the host has by default. Indeed it's even
338
+a bit strange to allow disabling CPU features that the host has when using
339
+the `host` CPU type, but in the absence of CPU models it's the best we can
340
+do if we want to launch guests without all the host's CPU features enabled.
341
+
342
+Enabling KVM also affects the `query-cpu-model-expansion` QMP command. The
343
+affect is not only limited to specific features, as pointed out in example
344
+(3) of "CPU Feature Probing", but also to which CPU types may be expanded.
345
+When KVM is enabled, only the `max`, `host`, and current CPU type may be
346
+expanded. This restriction is necessary as it's not possible to know all
347
+CPU types that may work with KVM, but it does impose a small risk of users
348
+experiencing unexpected errors. For example on a seattle, as mentioned
349
+above, the `cortex-a57` CPU type is also valid when KVM is enabled.
350
+Therefore a user could use the `host` CPU type for the current type, but
351
+then attempt to query `cortex-a57`, however that query will fail with our
352
+restrictions. This shouldn't be an issue though as management layers and
353
+users have been preferring the `host` CPU type for use with KVM for quite
354
+some time. Additionally, if the KVM-enabled QEMU instance running on a
355
+seattle host is using the `cortex-a57` CPU type, then querying `cortex-a57`
356
+will work.
357
+
358
+Using CPU Features
359
+==================
360
+
361
+After determining which CPU features are available and supported for a
362
+given CPU type, then they may be selectively enabled or disabled on the
363
+QEMU command line with that CPU type::
364
+
365
+ $ qemu-system-aarch64 -M virt -cpu max,pmu=off
366
+
367
+The example above disables the PMU for the `max` CPU type.
368
+
369
--
74
--
370
2.20.1
75
2.34.1
371
76
372
77
diff view generated by jsdifflib
1
Switch the mcf5206 code away from bottom-half based ptimers to
1
The 'singlestep' HMP command is confusing, because it doesn't
2
the new transaction-based ptimer API. This just requires adding
2
actually have anything to do with single-stepping the CPU. What it
3
begin/commit calls around the various places that modify the ptimer
3
does do is force TCG emulation to put one guest instruction in each
4
state, and using the new ptimer_init() function to create the timer.
4
TB, which can be useful in some situations.
5
6
Create a new HMP command 'one-insn-per-tb', so we can document that
7
'singlestep' is just a deprecated synonym for it, and eventually
8
perhaps drop it.
9
10
We aren't obliged to do deprecate-and-drop for HMP commands,
11
but it's easy enough to do so, so we do.
5
12
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
14
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
8
Message-id: 20191021140600.10725-1-peter.maydell@linaro.org
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Message-id: 20230417164041.684562-9-peter.maydell@linaro.org
9
---
18
---
10
hw/m68k/mcf5206.c | 15 +++++++++------
19
docs/about/deprecated.rst | 9 +++++++++
11
1 file changed, 9 insertions(+), 6 deletions(-)
20
include/monitor/hmp.h | 2 +-
21
softmmu/runstate-hmp-cmds.c | 2 +-
22
tests/qtest/test-hmp.c | 1 +
23
hmp-commands.hx | 25 +++++++++++++++++++++----
24
5 files changed, 33 insertions(+), 6 deletions(-)
12
25
13
diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c
26
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
14
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/m68k/mcf5206.c
28
--- a/docs/about/deprecated.rst
16
+++ b/hw/m68k/mcf5206.c
29
+++ b/docs/about/deprecated.rst
17
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ accepted incorrect commands will return an error. Users should make sure that
18
31
all arguments passed to ``device_add`` are consistent with the documented
19
#include "qemu/osdep.h"
32
property types.
20
#include "qemu/error-report.h"
33
21
-#include "qemu/main-loop.h"
34
+Human Monitor Protocol (HMP) commands
22
#include "cpu.h"
35
+-------------------------------------
23
#include "hw/hw.h"
36
+
24
#include "hw/irq.h"
37
+``singlestep`` (since 8.1)
25
@@ -XXX,XX +XXX,XX @@ static void m5206_timer_recalibrate(m5206_timer_state *s)
38
+''''''''''''''''''''''''''
26
int prescale;
39
+
27
int mode;
40
+The ``singlestep`` command has been replaced by the ``one-insn-per-tb``
28
41
+command, which has the same behaviour but a less misleading name.
29
+ ptimer_transaction_begin(s->timer);
42
+
30
ptimer_stop(s->timer);
43
Host Architectures
31
44
------------------
32
- if ((s->tmr & TMR_RST) == 0)
45
33
- return;
46
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
34
+ if ((s->tmr & TMR_RST) == 0) {
47
index XXXXXXX..XXXXXXX 100644
35
+ goto exit;
48
--- a/include/monitor/hmp.h
36
+ }
49
+++ b/include/monitor/hmp.h
37
50
@@ -XXX,XX +XXX,XX @@ void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
38
prescale = (s->tmr >> 8) + 1;
51
void hmp_human_readable_text_helper(Monitor *mon,
39
mode = (s->tmr >> 1) & 3;
52
HumanReadableText *(*qmp_handler)(Error **));
40
@@ -XXX,XX +XXX,XX @@ static void m5206_timer_recalibrate(m5206_timer_state *s)
53
void hmp_info_stats(Monitor *mon, const QDict *qdict);
41
ptimer_set_limit(s->timer, s->trr, 0);
54
-void hmp_singlestep(Monitor *mon, const QDict *qdict);
42
55
+void hmp_one_insn_per_tb(Monitor *mon, const QDict *qdict);
43
ptimer_run(s->timer, 0);
56
void hmp_watchdog_action(Monitor *mon, const QDict *qdict);
44
+exit:
57
void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict);
45
+ ptimer_transaction_commit(s->timer);
58
void hmp_info_capture(Monitor *mon, const QDict *qdict);
59
diff --git a/softmmu/runstate-hmp-cmds.c b/softmmu/runstate-hmp-cmds.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/softmmu/runstate-hmp-cmds.c
62
+++ b/softmmu/runstate-hmp-cmds.c
63
@@ -XXX,XX +XXX,XX @@ void hmp_info_status(Monitor *mon, const QDict *qdict)
64
qapi_free_StatusInfo(info);
46
}
65
}
47
66
48
static void m5206_timer_trigger(void *opaque)
67
-void hmp_singlestep(Monitor *mon, const QDict *qdict)
49
@@ -XXX,XX +XXX,XX @@ static void m5206_timer_write(m5206_timer_state *s, uint32_t addr, uint32_t val)
68
+void hmp_one_insn_per_tb(Monitor *mon, const QDict *qdict)
50
s->tcr = val;
51
break;
52
case 0xc:
53
+ ptimer_transaction_begin(s->timer);
54
ptimer_set_count(s->timer, val);
55
+ ptimer_transaction_commit(s->timer);
56
break;
57
case 0x11:
58
s->ter &= ~val;
59
@@ -XXX,XX +XXX,XX @@ static void m5206_timer_write(m5206_timer_state *s, uint32_t addr, uint32_t val)
60
static m5206_timer_state *m5206_timer_init(qemu_irq irq)
61
{
69
{
62
m5206_timer_state *s;
70
const char *option = qdict_get_try_str(qdict, "option");
63
- QEMUBH *bh;
71
AccelState *accel = current_accel();
64
72
diff --git a/tests/qtest/test-hmp.c b/tests/qtest/test-hmp.c
65
s = g_new0(m5206_timer_state, 1);
73
index XXXXXXX..XXXXXXX 100644
66
- bh = qemu_bh_new(m5206_timer_trigger, s);
74
--- a/tests/qtest/test-hmp.c
67
- s->timer = ptimer_init_with_bh(bh, PTIMER_POLICY_DEFAULT);
75
+++ b/tests/qtest/test-hmp.c
68
+ s->timer = ptimer_init(m5206_timer_trigger, s, PTIMER_POLICY_DEFAULT);
76
@@ -XXX,XX +XXX,XX @@ static const char *hmp_cmds[] = {
69
s->irq = irq;
77
"o /w 0 0x1234",
70
m5206_timer_reset(s);
78
"object_add memory-backend-ram,id=mem1,size=256M",
71
return s;
79
"object_del mem1",
80
+ "one-insn-per-tb on",
81
"pmemsave 0 4096 \"/dev/null\"",
82
"p $pc + 8",
83
"qom-list /",
84
diff --git a/hmp-commands.hx b/hmp-commands.hx
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hmp-commands.hx
87
+++ b/hmp-commands.hx
88
@@ -XXX,XX +XXX,XX @@ SRST
89
only *tag* as parameter.
90
ERST
91
92
+ {
93
+ .name = "one-insn-per-tb",
94
+ .args_type = "option:s?",
95
+ .params = "[on|off]",
96
+ .help = "run emulation with one guest instruction per translation block",
97
+ .cmd = hmp_one_insn_per_tb,
98
+ },
99
+
100
+SRST
101
+``one-insn-per-tb [off]``
102
+ Run the emulation with one guest instruction per translation block.
103
+ This slows down emulation a lot, but can be useful in some situations,
104
+ such as when trying to analyse the logs produced by the ``-d`` option.
105
+ This only has an effect when using TCG, not with KVM or other accelerators.
106
+
107
+ If called with option off, the emulation returns to normal mode.
108
+ERST
109
+
110
{
111
.name = "singlestep",
112
.args_type = "option:s?",
113
.params = "[on|off]",
114
- .help = "run emulation in singlestep mode or switch to normal mode",
115
- .cmd = hmp_singlestep,
116
+ .help = "deprecated synonym for one-insn-per-tb",
117
+ .cmd = hmp_one_insn_per_tb,
118
},
119
120
SRST
121
``singlestep [off]``
122
- Run the emulation in single step mode.
123
- If called with option off, the emulation returns to normal mode.
124
+ This is a deprecated synonym for the one-insn-per-tb command.
125
ERST
126
127
{
72
--
128
--
73
2.20.1
129
2.34.1
74
130
75
131
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The run-state.json file is missing a trailing newline; add it.
2
2
3
By performing this store early, we avoid having to save and restore
4
the register holding the address around any function calls.
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191023150057.25731-15-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20230417164041.684562-10-peter.maydell@linaro.org
10
---
7
---
11
target/arm/helper.c | 2 +-
8
qapi/run-state.json | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
9
1 file changed, 1 insertion(+), 1 deletion(-)
13
10
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/qapi/run-state.json b/qapi/run-state.json
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
13
--- a/qapi/run-state.json
17
+++ b/target/arm/helper.c
14
+++ b/qapi/run-state.json
18
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
15
@@ -XXX,XX +XXX,XX @@
19
{
16
# Since: 7.2
20
uint32_t flags, pstate_for_ss;
17
##
21
18
{ 'enum': 'NotifyVmexitOption',
22
+ *cs_base = 0;
19
- 'data': [ 'run', 'internal-error', 'disable' ] }
23
flags = rebuild_hflags_internal(env);
20
\ No newline at end of file
24
21
+ 'data': [ 'run', 'internal-error', 'disable' ] }
25
if (is_a64(env)) {
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
27
}
28
29
*pflags = flags;
30
- *cs_base = 0;
31
}
32
33
#ifdef TARGET_AARCH64
34
--
22
--
35
2.20.1
23
2.34.1
36
24
37
25
diff view generated by jsdifflib
1
Switch the slavio_timer code away from bottom-half based ptimers to
1
The 'singlestep' member of StatusInfo has never done what the QMP
2
the new transaction-based ptimer API. This just requires adding
2
documentation claims it does. What it actually reports is whether
3
begin/commit calls around the various places that modify the ptimer
3
TCG is working in "one guest instruction per translation block" mode.
4
state, and using the new ptimer_init() function to create the timer.
4
5
We no longer need this field for the HMP 'info status' command, as
6
we've moved that information to 'info jit'. It seems unlikely that
7
anybody is monitoring the state of this obscure TCG setting via QMP,
8
especially since QMP provides no means for changing the setting. So
9
simply deprecate the field, without providing any replacement.
10
11
Until we do eventually delete the member, correct the misstatements
12
in the QAPI documentation about it.
13
14
If we do find that there are users for this, then the most likely way
15
we would provide replacement access to the information would be to
16
put the accelerator QOM object at a well-known path such as
17
/machine/accel, which could then be used with the existing qom-set
18
and qom-get commands.
5
19
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20191021134357.14266-4-peter.maydell@linaro.org
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Markus Armbruster <armbru@redhat.com>
24
Message-id: 20230417164041.684562-11-peter.maydell@linaro.org
11
---
25
---
12
hw/timer/slavio_timer.c | 20 ++++++++++++++++----
26
docs/about/deprecated.rst | 14 ++++++++++++++
13
1 file changed, 16 insertions(+), 4 deletions(-)
27
qapi/run-state.json | 14 +++++++++++---
28
2 files changed, 25 insertions(+), 3 deletions(-)
14
29
15
diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c
30
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
16
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/timer/slavio_timer.c
32
--- a/docs/about/deprecated.rst
18
+++ b/hw/timer/slavio_timer.c
33
+++ b/docs/about/deprecated.rst
34
@@ -XXX,XX +XXX,XX @@ accepted incorrect commands will return an error. Users should make sure that
35
all arguments passed to ``device_add`` are consistent with the documented
36
property types.
37
38
+``StatusInfo`` member ``singlestep`` (since 8.1)
39
+''''''''''''''''''''''''''''''''''''''''''''''''
40
+
41
+The ``singlestep`` member of the ``StatusInfo`` returned from the
42
+``query-status`` command is deprecated. This member has a confusing
43
+name and it never did what the documentation claimed or what its name
44
+suggests. We do not believe that anybody is actually using the
45
+information provided in this member.
46
+
47
+The information it reports is whether the TCG JIT is in "one
48
+instruction per translated block" mode (which can be set on the
49
+command line or via the HMP, but not via QMP). The information remains
50
+available via the HMP 'info jit' command.
51
+
52
Human Monitor Protocol (HMP) commands
53
-------------------------------------
54
55
diff --git a/qapi/run-state.json b/qapi/run-state.json
56
index XXXXXXX..XXXXXXX 100644
57
--- a/qapi/run-state.json
58
+++ b/qapi/run-state.json
19
@@ -XXX,XX +XXX,XX @@
59
@@ -XXX,XX +XXX,XX @@
20
#include "hw/sysbus.h"
60
#
21
#include "migration/vmstate.h"
61
# @running: true if all VCPUs are runnable, false if not runnable
22
#include "trace.h"
62
#
23
-#include "qemu/main-loop.h"
63
-# @singlestep: true if VCPUs are in single-step mode
24
#include "qemu/module.h"
64
+# @singlestep: true if using TCG with one guest instruction
25
65
+# per translation block
26
/*
66
#
27
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
67
# @status: the virtual machine @RunState
28
saddr = addr >> 2;
68
#
29
switch (saddr) {
69
+# Features:
30
case TIMER_LIMIT:
70
+# @deprecated: Member 'singlestep' is deprecated (with no replacement).
31
+ ptimer_transaction_begin(t->timer);
71
+#
32
if (slavio_timer_is_user(tc)) {
72
# Since: 0.14
33
uint64_t count;
73
#
34
74
-# Notes: @singlestep is enabled through the GDB stub
35
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
75
+# Notes: @singlestep is enabled on the command line with
36
ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 1);
76
+# '-accel tcg,one-insn-per-tb=on', or with the HMP
37
}
77
+# 'one-insn-per-tb' command.
38
}
78
##
39
+ ptimer_transaction_commit(t->timer);
79
{ 'struct': 'StatusInfo',
40
break;
80
- 'data': {'running': 'bool', 'singlestep': 'bool', 'status': 'RunState'} }
41
case TIMER_COUNTER:
81
+ 'data': {'running': 'bool',
42
if (slavio_timer_is_user(tc)) {
82
+ 'singlestep': { 'type': 'bool', 'features': [ 'deprecated' ]},
43
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
83
+ 'status': 'RunState'} }
44
t->reached = 0;
84
45
count = ((uint64_t)t->counthigh) << 32 | t->count;
85
##
46
trace_slavio_timer_mem_writel_limit(timer_index, count);
86
# @query-status:
47
+ ptimer_transaction_begin(t->timer);
48
ptimer_set_count(t->timer, LIMIT_TO_PERIODS(t->limit - count));
49
+ ptimer_transaction_commit(t->timer);
50
} else {
51
trace_slavio_timer_mem_writel_counter_invalid();
52
}
53
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
54
case TIMER_COUNTER_NORST:
55
// set limit without resetting counter
56
t->limit = val & TIMER_MAX_COUNT32;
57
+ ptimer_transaction_begin(t->timer);
58
if (t->limit == 0) { /* free-run */
59
ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 0);
60
} else {
61
ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 0);
62
}
63
+ ptimer_transaction_commit(t->timer);
64
break;
65
case TIMER_STATUS:
66
+ ptimer_transaction_begin(t->timer);
67
if (slavio_timer_is_user(tc)) {
68
// start/stop user counter
69
if (val & 1) {
70
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
71
}
72
}
73
t->run = val & 1;
74
+ ptimer_transaction_commit(t->timer);
75
break;
76
case TIMER_MODE:
77
if (timer_index == 0) {
78
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
79
unsigned int processor = 1 << i;
80
CPUTimerState *curr_timer = &s->cputimer[i + 1];
81
82
+ ptimer_transaction_begin(curr_timer->timer);
83
// check for a change in timer mode for this processor
84
if ((val & processor) != (s->cputimer_mode & processor)) {
85
if (val & processor) { // counter -> user timer
86
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
87
trace_slavio_timer_mem_writel_mode_counter(timer_index);
88
}
89
}
90
+ ptimer_transaction_commit(curr_timer->timer);
91
}
92
} else {
93
trace_slavio_timer_mem_writel_mode_invalid();
94
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_reset(DeviceState *d)
95
curr_timer->count = 0;
96
curr_timer->reached = 0;
97
if (i <= s->num_cpus) {
98
+ ptimer_transaction_begin(curr_timer->timer);
99
ptimer_set_limit(curr_timer->timer,
100
LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
101
ptimer_run(curr_timer->timer, 0);
102
curr_timer->run = 1;
103
+ ptimer_transaction_commit(curr_timer->timer);
104
}
105
}
106
s->cputimer_mode = 0;
107
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_init(Object *obj)
108
{
109
SLAVIO_TIMERState *s = SLAVIO_TIMER(obj);
110
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
111
- QEMUBH *bh;
112
unsigned int i;
113
TimerContext *tc;
114
115
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_init(Object *obj)
116
tc->s = s;
117
tc->timer_index = i;
118
119
- bh = qemu_bh_new(slavio_timer_irq, tc);
120
- s->cputimer[i].timer = ptimer_init_with_bh(bh, PTIMER_POLICY_DEFAULT);
121
+ s->cputimer[i].timer = ptimer_init(slavio_timer_irq, tc,
122
+ PTIMER_POLICY_DEFAULT);
123
+ ptimer_transaction_begin(s->cputimer[i].timer);
124
ptimer_set_period(s->cputimer[i].timer, TIMER_PERIOD);
125
+ ptimer_transaction_commit(s->cputimer[i].timer);
126
127
size = i == 0 ? SYS_TIMER_SIZE : CPU_TIMER_SIZE;
128
snprintf(timer_name, sizeof(timer_name), "timer-%i", i);
129
--
87
--
130
2.20.1
88
2.34.1
131
89
132
90
diff view generated by jsdifflib
1
In the slavio timer devcie, the ptimer TimerContext::timer is
1
In commit 5242876f37ca we deprecated the dtb-kaslr-seed property of
2
always created by slavio_timer_init(), so there's no need to
2
the virt board, but forgot the "since n.n" tag in the documentation
3
check it for NULL; remove the single unneeded NULL check.
3
of this in deprecated.rst.
4
4
5
This will be useful to avoid compiler/Coverity errors when
5
This deprecation note first appeared in the 7.1 release, so
6
a subsequent change adds a use of t->timer before the location
6
retrospectively add the correct "since 7.1" annotation to it.
7
we currently do the NULL check.
8
7
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 20191021134357.14266-2-peter.maydell@linaro.org
11
Message-id: 20230420122256.1023709-1-peter.maydell@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
12
---
15
hw/timer/slavio_timer.c | 12 +++++-------
13
docs/about/deprecated.rst | 4 ++--
16
1 file changed, 5 insertions(+), 7 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
17
15
18
diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c
16
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/timer/slavio_timer.c
18
--- a/docs/about/deprecated.rst
21
+++ b/hw/timer/slavio_timer.c
19
+++ b/docs/about/deprecated.rst
22
@@ -XXX,XX +XXX,XX @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr,
20
@@ -XXX,XX +XXX,XX @@ Use the more generic event ``DEVICE_UNPLUG_GUEST_ERROR`` instead.
23
// set limit, reset counter
21
System emulator machines
24
qemu_irq_lower(t->irq);
22
------------------------
25
t->limit = val & TIMER_MAX_COUNT32;
23
26
- if (t->timer) {
24
-Arm ``virt`` machine ``dtb-kaslr-seed`` property
27
- if (t->limit == 0) { /* free-run */
25
-''''''''''''''''''''''''''''''''''''''''''''''''
28
- ptimer_set_limit(t->timer,
26
+Arm ``virt`` machine ``dtb-kaslr-seed`` property (since 7.1)
29
- LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
27
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
30
- } else {
28
31
- ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 1);
29
The ``dtb-kaslr-seed`` property on the ``virt`` board has been
32
- }
30
deprecated; use the new name ``dtb-randomness`` instead. The new name
33
+ if (t->limit == 0) { /* free-run */
34
+ ptimer_set_limit(t->timer,
35
+ LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
36
+ } else {
37
+ ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 1);
38
}
39
}
40
break;
41
--
31
--
42
2.20.1
32
2.34.1
43
33
44
34
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The msf2-emac ethernet controller has functions emac_load_desc() and
2
emac_store_desc() which read and write the in-memory descriptor
3
blocks and handle conversion between guest and host endianness.
2
4
3
Begin setting, but not relying upon, env->hflags.
5
As currently written, emac_store_desc() does the endianness
6
conversion in-place; this means that it effectively consumes the
7
input EmacDesc struct, because on a big-endian host the fields will
8
be overwritten with the little-endian versions of their values.
9
Unfortunately, in all the callsites the code continues to access
10
fields in the EmacDesc struct after it has called emac_store_desc()
11
-- specifically, it looks at the d.next field.
4
12
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
The effect of this is that on a big-endian host networking doesn't
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
work because the address of the next descriptor is corrupted.
7
Message-id: 20191023150057.25731-17-richard.henderson@linaro.org
15
16
We could fix this by making the callsite avoid using the struct; but
17
it's more robust to have emac_store_desc() leave its input alone.
18
19
(emac_load_desc() also does an in-place conversion, but here this is
20
fine, because the function is supposed to be initializing the
21
struct.)
22
23
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Thomas Huth <thuth@redhat.com>
26
Message-id: 20230424151919.1333299-1-peter.maydell@linaro.org
9
---
27
---
10
linux-user/syscall.c | 1 +
28
hw/net/msf2-emac.c | 16 ++++++++++------
11
target/arm/cpu.c | 1 +
29
1 file changed, 10 insertions(+), 6 deletions(-)
12
target/arm/helper-a64.c | 3 +++
13
target/arm/helper.c | 2 ++
14
target/arm/machine.c | 1 +
15
target/arm/op_helper.c | 1 +
16
6 files changed, 9 insertions(+)
17
30
18
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
31
diff --git a/hw/net/msf2-emac.c b/hw/net/msf2-emac.c
19
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/syscall.c
33
--- a/hw/net/msf2-emac.c
21
+++ b/linux-user/syscall.c
34
+++ b/hw/net/msf2-emac.c
22
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
35
@@ -XXX,XX +XXX,XX @@ static void emac_load_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
23
aarch64_sve_narrow_vq(env, vq);
36
d->next = le32_to_cpu(d->next);
24
}
25
env->vfp.zcr_el[1] = vq - 1;
26
+ arm_rebuild_hflags(env);
27
ret = vq * 16;
28
}
29
return ret;
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.c
33
+++ b/target/arm/cpu.c
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
35
36
hw_breakpoint_update_all(cpu);
37
hw_watchpoint_update_all(cpu);
38
+ arm_rebuild_hflags(env);
39
}
37
}
40
38
41
bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
39
-static void emac_store_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
42
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
40
+static void emac_store_desc(MSF2EmacState *s, const EmacDesc *d, hwaddr desc)
43
index XXXXXXX..XXXXXXX 100644
41
{
44
--- a/target/arm/helper-a64.c
42
- /* Convert from host endianness into LE. */
45
+++ b/target/arm/helper-a64.c
43
- d->pktaddr = cpu_to_le32(d->pktaddr);
46
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
44
- d->pktsize = cpu_to_le32(d->pktsize);
47
} else {
45
- d->next = cpu_to_le32(d->next);
48
env->regs[15] = new_pc & ~0x3;
46
+ EmacDesc outd;
49
}
47
+ /*
50
+ helper_rebuild_hflags_a32(env, new_el);
48
+ * Convert from host endianness into LE. We use a local struct because
51
qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
49
+ * calling code may still want to look at the fields afterwards.
52
"AArch32 EL%d PC 0x%" PRIx32 "\n",
50
+ */
53
cur_el, new_el, env->regs[15]);
51
+ outd.pktaddr = cpu_to_le32(d->pktaddr);
54
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
52
+ outd.pktsize = cpu_to_le32(d->pktsize);
55
}
53
+ outd.next = cpu_to_le32(d->next);
56
aarch64_restore_sp(env, new_el);
54
57
env->pc = new_pc;
55
- address_space_write(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
58
+ helper_rebuild_hflags_a64(env, new_el);
56
+ address_space_write(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, &outd, sizeof outd);
59
qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
60
"AArch64 EL%d PC 0x%" PRIx64 "\n",
61
cur_el, new_el, env->pc);
62
}
63
+
64
/*
65
* Note that cur_el can never be 0. If new_el is 0, then
66
* el0_a64 is return_to_aa64, else el0_a64 is ignored.
67
diff --git a/target/arm/helper.c b/target/arm/helper.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/helper.c
70
+++ b/target/arm/helper.c
71
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
72
env->regs[14] = env->regs[15] + offset;
73
}
74
env->regs[15] = newpc;
75
+ arm_rebuild_hflags(env);
76
}
57
}
77
58
78
static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
59
static void msf2_dma_tx(MSF2EmacState *s)
79
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
80
pstate_write(env, PSTATE_DAIF | new_mode);
81
env->aarch64 = 1;
82
aarch64_restore_sp(env, new_el);
83
+ helper_rebuild_hflags_a64(env, new_el);
84
85
env->pc = addr;
86
87
diff --git a/target/arm/machine.c b/target/arm/machine.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/machine.c
90
+++ b/target/arm/machine.c
91
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
92
if (!kvm_enabled()) {
93
pmu_op_finish(&cpu->env);
94
}
95
+ arm_rebuild_hflags(&cpu->env);
96
97
return 0;
98
}
99
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/op_helper.c
102
+++ b/target/arm/op_helper.c
103
@@ -XXX,XX +XXX,XX @@ void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
104
* state. Do the masking now.
105
*/
106
env->regs[15] &= (env->thumb ? ~1 : ~3);
107
+ arm_rebuild_hflags(env);
108
109
qemu_mutex_lock_iothread();
110
arm_call_el_change_hook(env_archcpu(env));
111
--
60
--
112
2.20.1
61
2.34.1
113
114
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
Create a function to compute the values of the TBFLAG_A32 bits
3
The arm boot.c code includes a utility function write_bootloader()
4
that will be cached, and are used by all profiles.
4
which assists in writing a boot-code fragment into guest memory,
5
including handling endianness and fixing it up with entry point
6
addresses and similar things. This is useful not just for the boot.c
7
code but also in board model code, so rename it to
8
arm_write_bootloader() and make it globally visible.
5
9
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Since we are making it public, make its API a little neater: move the
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
AddressSpace* argument to be next to the hwaddr argument, and allow
8
Message-id: 20191023150057.25731-4-richard.henderson@linaro.org
12
the fixupcontext array to be const, since we never modify it in this
13
function.
14
15
Cc: qemu-stable@nongnu.org
16
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
Tested-by: Cédric Le Goater <clg@kaod.org>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20230424152717.1333930-2-peter.maydell@linaro.org
21
[PMM: Split out from another patch by Cédric, added doc comment]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
23
---
11
target/arm/helper.c | 16 +++++++++++-----
24
include/hw/arm/boot.h | 49 +++++++++++++++++++++++++++++++++++++++++++
12
1 file changed, 11 insertions(+), 5 deletions(-)
25
hw/arm/boot.c | 35 +++++++------------------------
26
2 files changed, 57 insertions(+), 27 deletions(-)
13
27
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
15
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
30
--- a/include/hw/arm/boot.h
17
+++ b/target/arm/helper.c
31
+++ b/include/hw/arm/boot.h
18
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
32
@@ -XXX,XX +XXX,XX @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
19
return flags;
33
const struct arm_boot_info *info,
34
hwaddr mvbar_addr);
35
36
+typedef enum {
37
+ FIXUP_NONE = 0, /* do nothing */
38
+ FIXUP_TERMINATOR, /* end of insns */
39
+ FIXUP_BOARDID, /* overwrite with board ID number */
40
+ FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
41
+ FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */
42
+ FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */
43
+ FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
44
+ FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
45
+ FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
46
+ FIXUP_BOOTREG, /* overwrite with boot register address */
47
+ FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
48
+ FIXUP_MAX,
49
+} FixupType;
50
+
51
+typedef struct ARMInsnFixup {
52
+ uint32_t insn;
53
+ FixupType fixup;
54
+} ARMInsnFixup;
55
+
56
+/**
57
+ * arm_write_bootloader - write a bootloader to guest memory
58
+ * @name: name of the bootloader blob
59
+ * @as: AddressSpace to write the bootloader
60
+ * @addr: guest address to write it
61
+ * @insns: the blob to be loaded
62
+ * @fixupcontext: context to be used for any fixups in @insns
63
+ *
64
+ * Write a bootloader to guest memory at address @addr in the address
65
+ * space @as. @name is the name to use for the resulting ROM blob, so
66
+ * it should be unique in the system and reasonably identifiable for debugging.
67
+ *
68
+ * @insns must be an array of ARMInsnFixup structs, each of which has
69
+ * one 32-bit value to be written to the guest memory, and a fixup to be
70
+ * applied to the value. FIXUP_NONE (do nothing) is value 0, so effectively
71
+ * the fixup is optional when writing a struct initializer.
72
+ * The final entry in the array must be { 0, FIXUP_TERMINATOR }.
73
+ *
74
+ * All other supported fixup types have the semantics "ignore insn
75
+ * and instead use the value from the array element @fixupcontext[fixup]".
76
+ * The caller should therefore provide @fixupcontext as an array of
77
+ * size FIXUP_MAX whose elements have been initialized for at least
78
+ * the entries that @insns refers to.
79
+ */
80
+void arm_write_bootloader(const char *name,
81
+ AddressSpace *as, hwaddr addr,
82
+ const ARMInsnFixup *insns,
83
+ const uint32_t *fixupcontext);
84
+
85
#endif /* HW_ARM_BOOT_H */
86
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/arm/boot.c
89
+++ b/hw/arm/boot.c
90
@@ -XXX,XX +XXX,XX @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu,
91
return cpu_get_address_space(cs, asidx);
20
}
92
}
21
93
22
+static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
94
-typedef enum {
23
+ ARMMMUIdx mmu_idx, uint32_t flags)
95
- FIXUP_NONE = 0, /* do nothing */
24
+{
96
- FIXUP_TERMINATOR, /* end of insns */
25
+ flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
97
- FIXUP_BOARDID, /* overwrite with board ID number */
26
+ flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
98
- FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
27
+
99
- FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */
28
+ return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
100
- FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */
29
+}
101
- FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
30
+
102
- FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
31
static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
103
- FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
32
ARMMMUIdx mmu_idx)
104
- FIXUP_BOOTREG, /* overwrite with boot register address */
105
- FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
106
- FIXUP_MAX,
107
-} FixupType;
108
-
109
-typedef struct ARMInsnFixup {
110
- uint32_t insn;
111
- FixupType fixup;
112
-} ARMInsnFixup;
113
-
114
static const ARMInsnFixup bootloader_aarch64[] = {
115
{ 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
116
{ 0xaa1f03e1 }, /* mov x1, xzr */
117
@@ -XXX,XX +XXX,XX @@ static const ARMInsnFixup smpboot[] = {
118
{ 0, FIXUP_TERMINATOR }
119
};
120
121
-static void write_bootloader(const char *name, hwaddr addr,
122
- const ARMInsnFixup *insns, uint32_t *fixupcontext,
123
- AddressSpace *as)
124
+void arm_write_bootloader(const char *name,
125
+ AddressSpace *as, hwaddr addr,
126
+ const ARMInsnFixup *insns,
127
+ const uint32_t *fixupcontext)
33
{
128
{
34
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
129
/* Fix up the specified bootloader fragment and write it into
35
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
130
* guest memory using rom_add_blob_fixed(). fixupcontext is
36
int current_el = arm_current_el(env);
131
@@ -XXX,XX +XXX,XX @@ static void default_write_secondary(ARMCPU *cpu,
37
int fp_el = fp_exception_el(env, current_el);
132
fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
38
- uint32_t flags = 0;
39
+ uint32_t flags;
40
41
if (is_a64(env)) {
42
*pc = env->pc;
43
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
44
}
45
} else {
46
*pc = env->regs[15];
47
+ flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
48
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
49
flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_len);
50
flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, env->vfp.vec_stride);
51
flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
52
- flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
53
- flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
54
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
55
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
56
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
58
flags = FIELD_DP32(flags, TBFLAG_A32,
59
XSCALE_CPAR, env->cp15.c15_cpar);
60
}
61
-
62
- flags = rebuild_hflags_common(env, fp_el, mmu_idx, flags);
63
}
133
}
64
134
65
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
135
- write_bootloader("smpboot", info->smp_loader_start,
136
- smpboot, fixupcontext, as);
137
+ arm_write_bootloader("smpboot", as, info->smp_loader_start,
138
+ smpboot, fixupcontext);
139
}
140
141
void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
142
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
143
fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
144
fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
145
146
- write_bootloader("bootloader", info->loader_start,
147
- primary_loader, fixupcontext, as);
148
+ arm_write_bootloader("bootloader", as, info->loader_start,
149
+ primary_loader, fixupcontext);
150
151
if (info->write_board_setup) {
152
info->write_board_setup(cpu, info);
66
--
153
--
67
2.20.1
154
2.34.1
68
155
69
156
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
When writing the secondary-CPU stub boot loader code to the guest,
4
use arm_write_bootloader() instead of directly calling
5
rom_add_blob_fixed(). This fixes a bug on big-endian hosts, because
6
arm_write_bootloader() will correctly byte-swap the host-byte-order
7
array values into the guest-byte-order to write into the guest
8
memory.
9
10
Cc: qemu-stable@nongnu.org
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
4
Reviewed-by: Joel Stanley <joel@jms.id.au>
12
Tested-by: Cédric Le Goater <clg@kaod.org>
5
Message-id: 20191023130455.1347-3-clg@kaod.org
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20230424152717.1333930-3-peter.maydell@linaro.org
16
[PMM: Moved the "make arm_write_bootloader() function public" part
17
to its own patch; updated commit message to note that this fixes
18
an actual bug; adjust to the API changes noted in previous commit]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
20
---
8
include/hw/arm/aspeed.h | 1 +
21
hw/arm/aspeed.c | 38 ++++++++++++++++++++------------------
9
hw/arm/aspeed.c | 23 +++++++++++++++++++++++
22
1 file changed, 20 insertions(+), 18 deletions(-)
10
2 files changed, 24 insertions(+)
11
23
12
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/aspeed.h
15
+++ b/include/hw/arm/aspeed.h
16
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedBoardConfig {
17
const char *desc;
18
const char *soc_name;
19
uint32_t hw_strap1;
20
+ uint32_t hw_strap2;
21
const char *fmc_model;
22
const char *spi_model;
23
uint32_t num_cs;
24
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
24
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
25
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/aspeed.c
26
--- a/hw/arm/aspeed.c
27
+++ b/hw/arm/aspeed.c
27
+++ b/hw/arm/aspeed.c
28
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
28
@@ -XXX,XX +XXX,XX @@ struct AspeedMachineState {
29
/* Witherspoon hardware value: 0xF10AD216 (but use romulus definition) */
29
static void aspeed_write_smpboot(ARMCPU *cpu,
30
#define WITHERSPOON_BMC_HW_STRAP1 ROMULUS_BMC_HW_STRAP1
30
const struct arm_boot_info *info)
31
31
{
32
+/* AST2600 evb hardware value */
32
- static const uint32_t poll_mailbox_ready[] = {
33
+#define AST2600_EVB_HW_STRAP1 0x000000C0
33
+ AddressSpace *as = arm_boot_address_space(cpu, info);
34
+#define AST2600_EVB_HW_STRAP2 0x00000003
34
+ static const ARMInsnFixup poll_mailbox_ready[] = {
35
+
35
/*
36
/*
36
* r2 = per-cpu go sign value
37
* The max ram region is for firmwares that scan the address space
37
* r1 = AST_SMP_MBOX_FIELD_ENTRY
38
* with load/store to guess how much RAM the SoC has.
38
* r0 = AST_SMP_MBOX_FIELD_GOSIGN
39
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
39
*/
40
&error_abort);
40
- 0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5 */
41
object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
41
- 0xe21000ff, /* ands r0, r0, #255 */
42
&error_abort);
42
- 0xe59f201c, /* ldr r2, [pc, #28] */
43
+ object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap2, "hw-strap2",
43
- 0xe1822000, /* orr r2, r2, r0 */
44
+ &error_abort);
44
+ { 0xee100fb0 }, /* mrc p15, 0, r0, c0, c0, 5 */
45
object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs",
45
+ { 0xe21000ff }, /* ands r0, r0, #255 */
46
&error_abort);
46
+ { 0xe59f201c }, /* ldr r2, [pc, #28] */
47
object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus",
47
+ { 0xe1822000 }, /* orr r2, r2, r0 */
48
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
48
49
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32);
49
- 0xe59f1018, /* ldr r1, [pc, #24] */
50
- 0xe59f0018, /* ldr r0, [pc, #24] */
51
+ { 0xe59f1018 }, /* ldr r1, [pc, #24] */
52
+ { 0xe59f0018 }, /* ldr r0, [pc, #24] */
53
54
- 0xe320f002, /* wfe */
55
- 0xe5904000, /* ldr r4, [r0] */
56
- 0xe1520004, /* cmp r2, r4 */
57
- 0x1afffffb, /* bne <wfe> */
58
- 0xe591f000, /* ldr pc, [r1] */
59
- AST_SMP_MBOX_GOSIGN,
60
- AST_SMP_MBOX_FIELD_ENTRY,
61
- AST_SMP_MBOX_FIELD_GOSIGN,
62
+ { 0xe320f002 }, /* wfe */
63
+ { 0xe5904000 }, /* ldr r4, [r0] */
64
+ { 0xe1520004 }, /* cmp r2, r4 */
65
+ { 0x1afffffb }, /* bne <wfe> */
66
+ { 0xe591f000 }, /* ldr pc, [r1] */
67
+ { AST_SMP_MBOX_GOSIGN },
68
+ { AST_SMP_MBOX_FIELD_ENTRY },
69
+ { AST_SMP_MBOX_FIELD_GOSIGN },
70
+ { 0, FIXUP_TERMINATOR }
71
};
72
+ static const uint32_t fixupcontext[FIXUP_MAX] = { 0 };
73
74
- rom_add_blob_fixed("aspeed.smpboot", poll_mailbox_ready,
75
- sizeof(poll_mailbox_ready),
76
- info->smp_loader_start);
77
+ arm_write_bootloader("aspeed.smpboot", as, info->smp_loader_start,
78
+ poll_mailbox_ready, fixupcontext);
50
}
79
}
51
80
52
+static void ast2600_evb_i2c_init(AspeedBoardState *bmc)
81
static void aspeed_reset_secondary(ARMCPU *cpu,
53
+{
54
+ /* Start with some devices on our I2C busses */
55
+ ast2500_evb_i2c_init(bmc);
56
+}
57
+
58
static void romulus_bmc_i2c_init(AspeedBoardState *bmc)
59
{
60
AspeedSoCState *soc = &bmc->soc;
61
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
62
.num_cs = 2,
63
.i2c_init = witherspoon_bmc_i2c_init,
64
.ram = 512 * MiB,
65
+ }, {
66
+ .name = MACHINE_TYPE_NAME("ast2600-evb"),
67
+ .desc = "Aspeed AST2600 EVB (Cortex A7)",
68
+ .soc_name = "ast2600-a0",
69
+ .hw_strap1 = AST2600_EVB_HW_STRAP1,
70
+ .hw_strap2 = AST2600_EVB_HW_STRAP2,
71
+ .fmc_model = "w25q512jv",
72
+ .spi_model = "mx66u51235f",
73
+ .num_cs = 1,
74
+ .i2c_init = ast2600_evb_i2c_init,
75
+ .ram = 1 * GiB,
76
},
77
};
78
79
--
82
--
80
2.20.1
83
2.34.1
81
84
82
85
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Create a function to compute the values of the TBFLAG_ANY bits
4
that will be cached. For now, the env->hflags variable is not
5
used, and the results are fed back to cpu_get_tb_cpu_state.
6
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20191023150057.25731-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 29 ++++++++++++++++++-----------
13
target/arm/helper.c | 26 +++++++++++++++++++-------
14
2 files changed, 37 insertions(+), 18 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
21
uint32_t pstate;
22
uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */
23
24
+ /* Cached TBFLAGS state. See below for which bits are included. */
25
+ uint32_t hflags;
26
+
27
/* Frequently accessed CPSR bits are stored separately for efficiency.
28
This contains all the other bits. Use cpsr_{read,write} to access
29
the whole CPSR. */
30
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
31
32
#include "exec/cpu-all.h"
33
34
-/* Bit usage in the TB flags field: bit 31 indicates whether we are
35
+/*
36
+ * Bit usage in the TB flags field: bit 31 indicates whether we are
37
* in 32 or 64 bit mode. The meaning of the other bits depends on that.
38
* We put flags which are shared between 32 and 64 bit mode at the top
39
* of the word, and flags which apply to only one mode at the bottom.
40
+ *
41
+ * Unless otherwise noted, these bits are cached in env->hflags.
42
*/
43
FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
44
FIELD(TBFLAG_ANY, MMUIDX, 28, 3)
45
FIELD(TBFLAG_ANY, SS_ACTIVE, 27, 1)
46
-FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1)
47
+FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1) /* Not cached. */
48
/* Target EL if we take a floating-point-disabled exception */
49
FIELD(TBFLAG_ANY, FPEXC_EL, 24, 2)
50
FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
51
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
52
FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 21, 2)
53
54
/* Bit usage when in AArch32 state: */
55
-FIELD(TBFLAG_A32, THUMB, 0, 1)
56
-FIELD(TBFLAG_A32, VECLEN, 1, 3)
57
-FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
58
+FIELD(TBFLAG_A32, THUMB, 0, 1) /* Not cached. */
59
+FIELD(TBFLAG_A32, VECLEN, 1, 3) /* Not cached. */
60
+FIELD(TBFLAG_A32, VECSTRIDE, 4, 2) /* Not cached. */
61
/*
62
* We store the bottom two bits of the CPAR as TB flags and handle
63
* checks on the other bits at runtime. This shares the same bits as
64
* VECSTRIDE, which is OK as no XScale CPU has VFP.
65
+ * Not cached, because VECLEN+VECSTRIDE are not cached.
66
*/
67
FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
68
/*
69
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
70
* the same thing as the current security state of the processor!
71
*/
72
FIELD(TBFLAG_A32, NS, 6, 1)
73
-FIELD(TBFLAG_A32, VFPEN, 7, 1)
74
-FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
75
+FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Not cached. */
76
+FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */
77
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
78
/* For M profile only, set if FPCCR.LSPACT is set */
79
-FIELD(TBFLAG_A32, LSPACT, 18, 1)
80
+FIELD(TBFLAG_A32, LSPACT, 18, 1) /* Not cached. */
81
/* For M profile only, set if we must create a new FP context */
82
-FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
83
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1) /* Not cached. */
84
/* For M profile only, set if FPCCR.S does not match current security state */
85
-FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
86
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1) /* Not cached. */
87
/* For M profile only, Handler (ie not Thread) mode */
88
FIELD(TBFLAG_A32, HANDLER, 21, 1)
89
/* For M profile only, whether we should generate stack-limit checks */
90
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
91
FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
92
FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
93
FIELD(TBFLAG_A64, BT, 9, 1)
94
-FIELD(TBFLAG_A64, BTYPE, 10, 2)
95
+FIELD(TBFLAG_A64, BTYPE, 10, 2) /* Not cached. */
96
FIELD(TBFLAG_A64, TBID, 12, 2)
97
98
static inline bool bswap_code(bool sctlr_b)
99
diff --git a/target/arm/helper.c b/target/arm/helper.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/helper.c
102
+++ b/target/arm/helper.c
103
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
104
}
105
#endif
106
107
+static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
108
+ ARMMMUIdx mmu_idx, uint32_t flags)
109
+{
110
+ flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
111
+ flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
112
+ arm_to_core_mmu_idx(mmu_idx));
113
+
114
+ if (arm_cpu_data_is_big_endian(env)) {
115
+ flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
116
+ }
117
+ if (arm_singlestep_active(env)) {
118
+ flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
119
+ }
120
+ return flags;
121
+}
122
+
123
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
124
target_ulong *cs_base, uint32_t *pflags)
125
{
126
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
127
}
128
}
129
130
- flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
131
+ flags = rebuild_hflags_common(env, fp_el, mmu_idx, flags);
132
133
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
134
* states defined in the ARM ARM for software singlestep:
135
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
136
* 0 x Inactive (the TB flag for SS is always 0)
137
* 1 0 Active-pending
138
* 1 1 Active-not-pending
139
+ * SS_ACTIVE is set in hflags; PSTATE_SS is computed every TB.
140
*/
141
- if (arm_singlestep_active(env)) {
142
- flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
143
+ if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE)) {
144
if (is_a64(env)) {
145
if (env->pstate & PSTATE_SS) {
146
flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
147
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
148
}
149
}
150
}
151
- if (arm_cpu_data_is_big_endian(env)) {
152
- flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
153
- }
154
- flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
155
156
if (arm_v7m_is_handler_mode(env)) {
157
flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
158
--
159
2.20.1
160
161
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Create a function to compute the values of the TBFLAG_A64 bits
4
that will be cached. For now, the env->hflags variable is not
5
used, and the results are fed back to cpu_get_tb_cpu_state.
6
7
Note that not all BTI related flags are cached, so we have to
8
test the BTI feature twice -- once for those bits moved out to
9
rebuild_hflags_a64 and once for those bits that remain in
10
cpu_get_tb_cpu_state.
11
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191023150057.25731-3-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/helper.c | 131 +++++++++++++++++++++++---------------------
18
1 file changed, 69 insertions(+), 62 deletions(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
25
return flags;
26
}
27
28
+static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
29
+ ARMMMUIdx mmu_idx)
30
+{
31
+ ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
32
+ ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
33
+ uint32_t flags = 0;
34
+ uint64_t sctlr;
35
+ int tbii, tbid;
36
+
37
+ flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
38
+
39
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
40
+ if (regime_el(env, stage1) < 2) {
41
+ ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
42
+ tbid = (p1.tbi << 1) | p0.tbi;
43
+ tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
44
+ } else {
45
+ tbid = p0.tbi;
46
+ tbii = tbid & !p0.tbid;
47
+ }
48
+
49
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
50
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
51
+
52
+ if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
53
+ int sve_el = sve_exception_el(env, el);
54
+ uint32_t zcr_len;
55
+
56
+ /*
57
+ * If SVE is disabled, but FP is enabled,
58
+ * then the effective len is 0.
59
+ */
60
+ if (sve_el != 0 && fp_el == 0) {
61
+ zcr_len = 0;
62
+ } else {
63
+ zcr_len = sve_zcr_len_for_el(env, el);
64
+ }
65
+ flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
66
+ flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
67
+ }
68
+
69
+ sctlr = arm_sctlr(env, el);
70
+
71
+ if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
72
+ /*
73
+ * In order to save space in flags, we record only whether
74
+ * pauth is "inactive", meaning all insns are implemented as
75
+ * a nop, or "active" when some action must be performed.
76
+ * The decision of which action to take is left to a helper.
77
+ */
78
+ if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
79
+ flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
80
+ }
81
+ }
82
+
83
+ if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
84
+ /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
85
+ if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
86
+ flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1);
87
+ }
88
+ }
89
+
90
+ return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
91
+}
92
+
93
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
94
target_ulong *cs_base, uint32_t *pflags)
95
{
96
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
97
uint32_t flags = 0;
98
99
if (is_a64(env)) {
100
- ARMCPU *cpu = env_archcpu(env);
101
- uint64_t sctlr;
102
-
103
*pc = env->pc;
104
- flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
105
-
106
- /* Get control bits for tagged addresses. */
107
- {
108
- ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
109
- ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
110
- int tbii, tbid;
111
-
112
- /* FIXME: ARMv8.1-VHE S2 translation regime. */
113
- if (regime_el(env, stage1) < 2) {
114
- ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
115
- tbid = (p1.tbi << 1) | p0.tbi;
116
- tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
117
- } else {
118
- tbid = p0.tbi;
119
- tbii = tbid & !p0.tbid;
120
- }
121
-
122
- flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
123
- flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
124
- }
125
-
126
- if (cpu_isar_feature(aa64_sve, cpu)) {
127
- int sve_el = sve_exception_el(env, current_el);
128
- uint32_t zcr_len;
129
-
130
- /* If SVE is disabled, but FP is enabled,
131
- * then the effective len is 0.
132
- */
133
- if (sve_el != 0 && fp_el == 0) {
134
- zcr_len = 0;
135
- } else {
136
- zcr_len = sve_zcr_len_for_el(env, current_el);
137
- }
138
- flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
139
- flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
140
- }
141
-
142
- sctlr = arm_sctlr(env, current_el);
143
-
144
- if (cpu_isar_feature(aa64_pauth, cpu)) {
145
- /*
146
- * In order to save space in flags, we record only whether
147
- * pauth is "inactive", meaning all insns are implemented as
148
- * a nop, or "active" when some action must be performed.
149
- * The decision of which action to take is left to a helper.
150
- */
151
- if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
152
- flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
153
- }
154
- }
155
-
156
- if (cpu_isar_feature(aa64_bti, cpu)) {
157
- /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
158
- if (sctlr & (current_el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
159
- flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1);
160
- }
161
+ flags = rebuild_hflags_a64(env, current_el, fp_el, mmu_idx);
162
+ if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
163
flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
164
}
165
} else {
166
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
167
flags = FIELD_DP32(flags, TBFLAG_A32,
168
XSCALE_CPAR, env->cp15.c15_cpar);
169
}
170
- }
171
172
- flags = rebuild_hflags_common(env, fp_el, mmu_idx, flags);
173
+ flags = rebuild_hflags_common(env, fp_el, mmu_idx, flags);
174
+ }
175
176
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
177
* states defined in the ARM ARM for software singlestep:
178
--
179
2.20.1
180
181
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Set TBFLAG_ANY.BE_DATA in rebuild_hflags_common_32 and
4
rebuild_hflags_a64 instead of rebuild_hflags_common, where we do
5
not need to re-test is_a64() nor re-compute the various inputs.
6
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20191023150057.25731-5-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 49 +++++++++++++++++++++++++++------------------
13
target/arm/helper.c | 16 +++++++++++----
14
2 files changed, 42 insertions(+), 23 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline uint64_t arm_sctlr(CPUARMState *env, int el)
21
}
22
}
23
24
+static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
25
+ bool sctlr_b)
26
+{
27
+#ifdef CONFIG_USER_ONLY
28
+ /*
29
+ * In system mode, BE32 is modelled in line with the
30
+ * architecture (as word-invariant big-endianness), where loads
31
+ * and stores are done little endian but from addresses which
32
+ * are adjusted by XORing with the appropriate constant. So the
33
+ * endianness to use for the raw data access is not affected by
34
+ * SCTLR.B.
35
+ * In user mode, however, we model BE32 as byte-invariant
36
+ * big-endianness (because user-only code cannot tell the
37
+ * difference), and so we need to use a data access endianness
38
+ * that depends on SCTLR.B.
39
+ */
40
+ if (sctlr_b) {
41
+ return true;
42
+ }
43
+#endif
44
+ /* In 32bit endianness is determined by looking at CPSR's E bit */
45
+ return env->uncached_cpsr & CPSR_E;
46
+}
47
+
48
+static inline bool arm_cpu_data_is_big_endian_a64(int el, uint64_t sctlr)
49
+{
50
+ return sctlr & (el ? SCTLR_EE : SCTLR_E0E);
51
+}
52
53
/* Return true if the processor is in big-endian mode. */
54
static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
55
{
56
- /* In 32bit endianness is determined by looking at CPSR's E bit */
57
if (!is_a64(env)) {
58
- return
59
-#ifdef CONFIG_USER_ONLY
60
- /* In system mode, BE32 is modelled in line with the
61
- * architecture (as word-invariant big-endianness), where loads
62
- * and stores are done little endian but from addresses which
63
- * are adjusted by XORing with the appropriate constant. So the
64
- * endianness to use for the raw data access is not affected by
65
- * SCTLR.B.
66
- * In user mode, however, we model BE32 as byte-invariant
67
- * big-endianness (because user-only code cannot tell the
68
- * difference), and so we need to use a data access endianness
69
- * that depends on SCTLR.B.
70
- */
71
- arm_sctlr_b(env) ||
72
-#endif
73
- ((env->uncached_cpsr & CPSR_E) ? 1 : 0);
74
+ return arm_cpu_data_is_big_endian_a32(env, arm_sctlr_b(env));
75
} else {
76
int cur_el = arm_current_el(env);
77
uint64_t sctlr = arm_sctlr(env, cur_el);
78
-
79
- return (sctlr & (cur_el ? SCTLR_EE : SCTLR_E0E)) != 0;
80
+ return arm_cpu_data_is_big_endian_a64(cur_el, sctlr);
81
}
82
}
83
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
89
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
90
arm_to_core_mmu_idx(mmu_idx));
91
92
- if (arm_cpu_data_is_big_endian(env)) {
93
- flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
94
- }
95
if (arm_singlestep_active(env)) {
96
flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
97
}
98
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
99
static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
100
ARMMMUIdx mmu_idx, uint32_t flags)
101
{
102
- flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
103
+ bool sctlr_b = arm_sctlr_b(env);
104
+
105
+ if (sctlr_b) {
106
+ flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, 1);
107
+ }
108
+ if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
109
+ flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
110
+ }
111
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
112
113
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
114
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
115
116
sctlr = arm_sctlr(env, el);
117
118
+ if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
119
+ flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
120
+ }
121
+
122
if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
123
/*
124
* In order to save space in flags, we record only whether
125
--
126
2.20.1
127
128
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Create a function to compute the values of the TBFLAG_A32 bits
4
that will be cached, and are used by M-profile.
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191023150057.25731-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.c | 45 ++++++++++++++++++++++++++++++---------------
12
1 file changed, 30 insertions(+), 15 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 uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
19
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
20
}
21
22
+static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
23
+ ARMMMUIdx mmu_idx)
24
+{
25
+ uint32_t flags = 0;
26
+
27
+ if (arm_v7m_is_handler_mode(env)) {
28
+ flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
29
+ }
30
+
31
+ /*
32
+ * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN
33
+ * is suppressing them because the requested execution priority
34
+ * is less than 0.
35
+ */
36
+ if (arm_feature(env, ARM_FEATURE_V8) &&
37
+ !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
38
+ (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
39
+ flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
40
+ }
41
+
42
+ return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
43
+}
44
+
45
static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
46
ARMMMUIdx mmu_idx)
47
{
48
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
49
}
50
} else {
51
*pc = env->regs[15];
52
- flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
53
+
54
+ if (arm_feature(env, ARM_FEATURE_M)) {
55
+ flags = rebuild_hflags_m32(env, fp_el, mmu_idx);
56
+ } else {
57
+ flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
58
+ }
59
+
60
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
61
flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_len);
62
flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, env->vfp.vec_stride);
63
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
64
}
65
}
66
67
- if (arm_v7m_is_handler_mode(env)) {
68
- flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
69
- }
70
-
71
- /* v8M always applies stack limit checks unless CCR.STKOFHFNMIGN is
72
- * suppressing them because the requested execution priority is less than 0.
73
- */
74
- if (arm_feature(env, ARM_FEATURE_V8) &&
75
- arm_feature(env, ARM_FEATURE_M) &&
76
- !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
77
- (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
78
- flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
79
- }
80
-
81
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
82
FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
83
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
84
--
85
2.20.1
86
87
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Hoist the computation of some TBFLAG_A32 bits that only apply to
4
M-profile under a single test for ARM_FEATURE_M.
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191023150057.25731-7-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.c | 49 +++++++++++++++++++++------------------------
12
1 file changed, 23 insertions(+), 26 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 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
19
20
if (arm_feature(env, ARM_FEATURE_M)) {
21
flags = rebuild_hflags_m32(env, fp_el, mmu_idx);
22
+
23
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
24
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
25
+ != env->v7m.secure) {
26
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
27
+ }
28
+
29
+ if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
30
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
31
+ (env->v7m.secure &&
32
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
33
+ /*
34
+ * ASPEN is set, but FPCA/SFPA indicate that there is no
35
+ * active FP context; we must create a new FP context before
36
+ * executing any FP insn.
37
+ */
38
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
39
+ }
40
+
41
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
42
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
43
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
44
+ }
45
} else {
46
flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
47
}
48
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
49
}
50
}
51
52
- if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
53
- FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
54
- flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
55
- }
56
-
57
- if (arm_feature(env, ARM_FEATURE_M) &&
58
- (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
59
- (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
60
- (env->v7m.secure &&
61
- !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
62
- /*
63
- * ASPEN is set, but FPCA/SFPA indicate that there is no active
64
- * FP context; we must create a new FP context before executing
65
- * any FP insn.
66
- */
67
- flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
68
- }
69
-
70
- if (arm_feature(env, ARM_FEATURE_M)) {
71
- bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
72
-
73
- if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
74
- flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
75
- }
76
- }
77
-
78
if (!arm_feature(env, ARM_FEATURE_M)) {
79
int target_el = arm_debug_target_el(env);
80
81
--
82
2.20.1
83
84
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Currently a trivial wrapper for rebuild_hflags_common_32.
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20191023150057.25731-8-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 8 +++++++-
11
1 file changed, 7 insertions(+), 1 deletion(-)
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 @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
18
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
19
}
20
21
+static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
22
+ ARMMMUIdx mmu_idx)
23
+{
24
+ return rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
25
+}
26
+
27
static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
28
ARMMMUIdx mmu_idx)
29
{
30
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
31
flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
32
}
33
} else {
34
- flags = rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
35
+ flags = rebuild_hflags_a32(env, fp_el, mmu_idx);
36
}
37
38
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
39
--
40
2.20.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We do not need to compute any of these values for M-profile.
4
Further, XSCALE_CPAR overlaps VECSTRIDE so obviously the two
5
sets must be mutually exclusive.
6
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20191023150057.25731-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper.c | 21 ++++++++++++++-------
13
1 file changed, 14 insertions(+), 7 deletions(-)
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
20
}
21
} else {
22
flags = rebuild_hflags_a32(env, fp_el, mmu_idx);
23
+
24
+ /*
25
+ * Note that XSCALE_CPAR shares bits with VECSTRIDE.
26
+ * Note that VECLEN+VECSTRIDE are RES0 for M-profile.
27
+ */
28
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
29
+ flags = FIELD_DP32(flags, TBFLAG_A32,
30
+ XSCALE_CPAR, env->cp15.c15_cpar);
31
+ } else {
32
+ flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN,
33
+ env->vfp.vec_len);
34
+ flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
35
+ env->vfp.vec_stride);
36
+ }
37
}
38
39
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
40
- flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_len);
41
- flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, env->vfp.vec_stride);
42
flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
43
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
44
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
45
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
46
}
47
- /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
48
- if (arm_feature(env, ARM_FEATURE_XSCALE)) {
49
- flags = FIELD_DP32(flags, TBFLAG_A32,
50
- XSCALE_CPAR, env->cp15.c15_cpar);
51
- }
52
}
53
54
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
55
--
56
2.20.1
57
58
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Hoist the variable load for PSTATE into the existing test vs is_a64.
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20191023150057.25731-11-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 20 ++++++++------------
11
1 file changed, 8 insertions(+), 12 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 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
18
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
19
int current_el = arm_current_el(env);
20
int fp_el = fp_exception_el(env, current_el);
21
- uint32_t flags;
22
+ uint32_t flags, pstate_for_ss;
23
24
if (is_a64(env)) {
25
*pc = env->pc;
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
27
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
28
flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
29
}
30
+ pstate_for_ss = env->pstate;
31
} else {
32
*pc = env->regs[15];
33
34
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
35
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
36
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
37
}
38
+ pstate_for_ss = env->uncached_cpsr;
39
}
40
41
- /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
42
+ /*
43
+ * The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
44
* states defined in the ARM ARM for software singlestep:
45
* SS_ACTIVE PSTATE.SS State
46
* 0 x Inactive (the TB flag for SS is always 0)
47
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
48
* 1 1 Active-not-pending
49
* SS_ACTIVE is set in hflags; PSTATE_SS is computed every TB.
50
*/
51
- if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE)) {
52
- if (is_a64(env)) {
53
- if (env->pstate & PSTATE_SS) {
54
- flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
55
- }
56
- } else {
57
- if (env->uncached_cpsr & PSTATE_SS) {
58
- flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
59
- }
60
- }
61
+ if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
62
+ (pstate_for_ss & PSTATE_SS)) {
63
+ flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
64
}
65
66
*pflags = flags;
67
--
68
2.20.1
69
70
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
There are 3 conditions that each enable this flag. M-profile always
4
enables; A-profile with EL1 as AA64 always enables. Both of these
5
conditions can easily be cached. The final condition relies on the
6
FPEXC register which we are not prepared to cache.
7
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20191023150057.25731-12-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu.h | 2 +-
14
target/arm/helper.c | 14 ++++++++++----
15
2 files changed, 11 insertions(+), 5 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 @@ FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
22
* the same thing as the current security state of the processor!
23
*/
24
FIELD(TBFLAG_A32, NS, 6, 1)
25
-FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Not cached. */
26
+FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
27
FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */
28
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
29
/* For M profile only, set if FPCCR.LSPACT is set */
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
33
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
35
{
36
uint32_t flags = 0;
37
38
+ /* v8M always enables the fpu. */
39
+ flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
40
+
41
if (arm_v7m_is_handler_mode(env)) {
42
flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
43
}
44
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
45
ARMMMUIdx mmu_idx)
46
{
47
uint32_t flags = rebuild_hflags_aprofile(env);
48
+
49
+ if (arm_el_is_aa64(env, 1)) {
50
+ flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
51
+ }
52
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
53
}
54
55
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
56
flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
57
env->vfp.vec_stride);
58
}
59
+ if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
61
+ }
62
}
63
64
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
65
flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
66
- if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
67
- || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
68
- flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
69
- }
70
pstate_for_ss = env->uncached_cpsr;
71
}
72
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This function assumes nothing about the current state of the cpu,
4
and writes the computed value to env->hflags.
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191023150057.25731-13-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 6 ++++++
12
target/arm/helper.c | 30 ++++++++++++++++++++++--------
13
2 files changed, 28 insertions(+), 8 deletions(-)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
20
void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, void
21
*opaque);
22
23
+/**
24
+ * arm_rebuild_hflags:
25
+ * Rebuild the cached TBFLAGS for arbitrary changed processor state.
26
+ */
27
+void arm_rebuild_hflags(CPUARMState *env);
28
+
29
/**
30
* aa32_vfp_dreg:
31
* Return a pointer to the Dn register within env in 32-bit mode.
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
37
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
38
}
39
40
+static uint32_t rebuild_hflags_internal(CPUARMState *env)
41
+{
42
+ int el = arm_current_el(env);
43
+ int fp_el = fp_exception_el(env, el);
44
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
45
+
46
+ if (is_a64(env)) {
47
+ return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
48
+ } else if (arm_feature(env, ARM_FEATURE_M)) {
49
+ return rebuild_hflags_m32(env, fp_el, mmu_idx);
50
+ } else {
51
+ return rebuild_hflags_a32(env, fp_el, mmu_idx);
52
+ }
53
+}
54
+
55
+void arm_rebuild_hflags(CPUARMState *env)
56
+{
57
+ env->hflags = rebuild_hflags_internal(env);
58
+}
59
+
60
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
61
target_ulong *cs_base, uint32_t *pflags)
62
{
63
- ARMMMUIdx mmu_idx = arm_mmu_idx(env);
64
- int current_el = arm_current_el(env);
65
- int fp_el = fp_exception_el(env, current_el);
66
uint32_t flags, pstate_for_ss;
67
68
+ flags = rebuild_hflags_internal(env);
69
+
70
if (is_a64(env)) {
71
*pc = env->pc;
72
- flags = rebuild_hflags_a64(env, current_el, fp_el, mmu_idx);
73
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
74
flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
75
}
76
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
77
*pc = env->regs[15];
78
79
if (arm_feature(env, ARM_FEATURE_M)) {
80
- flags = rebuild_hflags_m32(env, fp_el, mmu_idx);
81
-
82
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
83
FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
84
!= env->v7m.secure) {
85
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
86
flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
87
}
88
} else {
89
- flags = rebuild_hflags_a32(env, fp_el, mmu_idx);
90
-
91
/*
92
* Note that XSCALE_CPAR shares bits with VECSTRIDE.
93
* Note that VECLEN+VECSTRIDE are RES0 for M-profile.
94
--
95
2.20.1
96
97
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Avoid calling arm_current_el() twice.
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191023150057.25731-14-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 9 +++++++++
12
target/arm/helper.c | 12 +++++++-----
13
2 files changed, 16 insertions(+), 5 deletions(-)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_virq(ARMCPU *cpu);
20
*/
21
void arm_cpu_update_vfiq(ARMCPU *cpu);
22
23
+/**
24
+ * arm_mmu_idx_el:
25
+ * @env: The cpu environment
26
+ * @el: The EL to use.
27
+ *
28
+ * Return the full ARMMMUIdx for the translation regime for EL.
29
+ */
30
+ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el);
31
+
32
/**
33
* arm_mmu_idx:
34
* @env: The cpu environment
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
40
}
41
#endif
42
43
-ARMMMUIdx arm_mmu_idx(CPUARMState *env)
44
+ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
45
{
46
- int el;
47
-
48
if (arm_feature(env, ARM_FEATURE_M)) {
49
return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
50
}
51
52
- el = arm_current_el(env);
53
if (el < 2 && arm_is_secure_below_el3(env)) {
54
return ARMMMUIdx_S1SE0 + el;
55
} else {
56
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
57
}
58
}
59
60
+ARMMMUIdx arm_mmu_idx(CPUARMState *env)
61
+{
62
+ return arm_mmu_idx_el(env, arm_current_el(env));
63
+}
64
+
65
int cpu_mmu_index(CPUARMState *env, bool ifetch)
66
{
67
return arm_to_core_mmu_idx(arm_mmu_idx(env));
68
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_internal(CPUARMState *env)
69
{
70
int el = arm_current_el(env);
71
int fp_el = fp_exception_el(env, el);
72
- ARMMMUIdx mmu_idx = arm_mmu_idx(env);
73
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
74
75
if (is_a64(env)) {
76
return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
77
--
78
2.20.1
79
80
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
When writing the secondary-CPU stub boot loader code to the guest,
2
use arm_write_bootloader() instead of directly calling
3
rom_add_blob_fixed(). This fixes a bug on big-endian hosts, because
4
arm_write_bootloader() will correctly byte-swap the host-byte-order
5
array values into the guest-byte-order to write into the guest
6
memory.
2
7
3
write_secondary_boot() is used in SMP configurations where the
8
Cc: qemu-stable@nongnu.org
4
CPU address space might not be the main System Bus.
5
The rom_add_blob_fixed_as() function allow us to specify an
6
address space. Use it to write each boot blob in the corresponding
7
CPU address space.
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 20191019234715.25750-11-f4bug@amsat.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20230424152717.1333930-4-peter.maydell@linaro.org
13
---
13
---
14
hw/arm/raspi.c | 14 ++++++++------
14
hw/arm/raspi.c | 64 +++++++++++++++++++++++++++-----------------------
15
1 file changed, 8 insertions(+), 6 deletions(-)
15
1 file changed, 34 insertions(+), 30 deletions(-)
16
16
17
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
17
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/raspi.c
19
--- a/hw/arm/raspi.c
20
+++ b/hw/arm/raspi.c
20
+++ b/hw/arm/raspi.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "qemu/units.h"
23
#include "qemu/cutils.h"
24
#include "qapi/error.h"
25
+#include "hw/arm/boot.h"
26
#include "hw/arm/bcm2836.h"
27
#include "hw/registerfields.h"
28
#include "qemu/error-report.h"
29
@@ -XXX,XX +XXX,XX @@ static const char *board_type(uint32_t board_rev)
30
31
static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
32
{
33
- static const uint32_t smpboot[] = {
34
- 0xe1a0e00f, /* mov lr, pc */
35
- 0xe3a0fe00 + (BOARDSETUP_ADDR >> 4), /* mov pc, BOARDSETUP_ADDR */
36
- 0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5;get core ID */
37
- 0xe7e10050, /* ubfx r0, r0, #0, #2 ;extract LSB */
38
- 0xe59f5014, /* ldr r5, =0x400000CC ;load mbox base */
39
- 0xe320f001, /* 1: yield */
40
- 0xe7953200, /* ldr r3, [r5, r0, lsl #4] ;read mbox for our core*/
41
- 0xe3530000, /* cmp r3, #0 ;spin while zero */
42
- 0x0afffffb, /* beq 1b */
43
- 0xe7853200, /* str r3, [r5, r0, lsl #4] ;clear mbox */
44
- 0xe12fff13, /* bx r3 ;jump to target */
45
- 0x400000cc, /* (constant: mailbox 3 read/clear base) */
46
+ static const ARMInsnFixup smpboot[] = {
47
+ { 0xe1a0e00f }, /* mov lr, pc */
48
+ { 0xe3a0fe00 + (BOARDSETUP_ADDR >> 4) }, /* mov pc, BOARDSETUP_ADDR */
49
+ { 0xee100fb0 }, /* mrc p15, 0, r0, c0, c0, 5;get core ID */
50
+ { 0xe7e10050 }, /* ubfx r0, r0, #0, #2 ;extract LSB */
51
+ { 0xe59f5014 }, /* ldr r5, =0x400000CC ;load mbox base */
52
+ { 0xe320f001 }, /* 1: yield */
53
+ { 0xe7953200 }, /* ldr r3, [r5, r0, lsl #4] ;read mbox for our core */
54
+ { 0xe3530000 }, /* cmp r3, #0 ;spin while zero */
55
+ { 0x0afffffb }, /* beq 1b */
56
+ { 0xe7853200 }, /* str r3, [r5, r0, lsl #4] ;clear mbox */
57
+ { 0xe12fff13 }, /* bx r3 ;jump to target */
58
+ { 0x400000cc }, /* (constant: mailbox 3 read/clear base) */
59
+ { 0, FIXUP_TERMINATOR }
60
};
61
+ static const uint32_t fixupcontext[FIXUP_MAX] = { 0 };
62
63
/* check that we don't overrun board setup vectors */
64
QEMU_BUILD_BUG_ON(SMPBOOT_ADDR + sizeof(smpboot) > MVBAR_ADDR);
21
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
65
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
22
QEMU_BUILD_BUG_ON((BOARDSETUP_ADDR & 0xf) != 0
66
QEMU_BUILD_BUG_ON((BOARDSETUP_ADDR & 0xf) != 0
23
|| (BOARDSETUP_ADDR >> 4) >= 0x100);
67
|| (BOARDSETUP_ADDR >> 4) >= 0x100);
24
68
25
- rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
69
- rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
26
- info->smp_loader_start);
70
- info->smp_loader_start,
27
+ rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
71
- arm_boot_address_space(cpu, info));
28
+ info->smp_loader_start,
72
+ arm_write_bootloader("raspi_smpboot", arm_boot_address_space(cpu, info),
29
+ arm_boot_address_space(cpu, info));
73
+ info->smp_loader_start, smpboot, fixupcontext);
30
}
74
}
31
75
32
static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
76
static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
33
{
34
+ AddressSpace *as = arm_boot_address_space(cpu, info);
35
/* Unlike the AArch32 version we don't need to call the board setup hook.
36
* The mechanism for doing the spin-table is also entirely different.
37
* We must have four 64-bit fields at absolute addresses
38
@@ -XXX,XX +XXX,XX @@ static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
77
@@ -XXX,XX +XXX,XX @@ static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
78
* the primary CPU goes into the kernel. We put these variables inside
79
* a rom blob, so that the reset for ROM contents zeroes them for us.
80
*/
81
- static const uint32_t smpboot[] = {
82
- 0xd2801b05, /* mov x5, 0xd8 */
83
- 0xd53800a6, /* mrs x6, mpidr_el1 */
84
- 0x924004c6, /* and x6, x6, #0x3 */
85
- 0xd503205f, /* spin: wfe */
86
- 0xf86678a4, /* ldr x4, [x5,x6,lsl #3] */
87
- 0xb4ffffc4, /* cbz x4, spin */
88
- 0xd2800000, /* mov x0, #0x0 */
89
- 0xd2800001, /* mov x1, #0x0 */
90
- 0xd2800002, /* mov x2, #0x0 */
91
- 0xd2800003, /* mov x3, #0x0 */
92
- 0xd61f0080, /* br x4 */
93
+ static const ARMInsnFixup smpboot[] = {
94
+ { 0xd2801b05 }, /* mov x5, 0xd8 */
95
+ { 0xd53800a6 }, /* mrs x6, mpidr_el1 */
96
+ { 0x924004c6 }, /* and x6, x6, #0x3 */
97
+ { 0xd503205f }, /* spin: wfe */
98
+ { 0xf86678a4 }, /* ldr x4, [x5,x6,lsl #3] */
99
+ { 0xb4ffffc4 }, /* cbz x4, spin */
100
+ { 0xd2800000 }, /* mov x0, #0x0 */
101
+ { 0xd2800001 }, /* mov x1, #0x0 */
102
+ { 0xd2800002 }, /* mov x2, #0x0 */
103
+ { 0xd2800003 }, /* mov x3, #0x0 */
104
+ { 0xd61f0080 }, /* br x4 */
105
+ { 0, FIXUP_TERMINATOR }
106
};
107
+ static const uint32_t fixupcontext[FIXUP_MAX] = { 0 };
108
109
static const uint64_t spintables[] = {
39
0, 0, 0, 0
110
0, 0, 0, 0
40
};
111
};
41
112
42
- rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
113
- rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
43
- info->smp_loader_start);
114
- info->smp_loader_start, as);
44
- rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
115
+ arm_write_bootloader("raspi_smpboot", as, info->smp_loader_start,
45
- SPINTABLE_ADDR);
116
+ smpboot, fixupcontext);
46
+ rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
117
rom_add_blob_fixed_as("raspi_spintables", spintables, sizeof(spintables),
47
+ info->smp_loader_start, as);
118
SPINTABLE_ADDR, as);
48
+ rom_add_blob_fixed_as("raspi_spintables", spintables, sizeof(spintables),
49
+ SPINTABLE_ADDR, as);
50
}
119
}
51
52
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
53
--
120
--
54
2.20.1
121
2.34.1
55
122
56
123
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The Allwinner PIC model uses set_bit() and clear_bit() to update the
2
values in its irq_pending[] array when an interrupt arrives. However
3
it is using these functions wrongly: they work on an array of type
4
'long', and it is passing an array of type 'uint32_t'. Because the
5
code manually figures out the right array element, this works on
6
little-endian hosts and on 32-bit big-endian hosts, where bits 0..31
7
in a 'long' are in the same place as they are in a 'uint32_t'.
8
However it breaks on 64-bit big-endian hosts.
2
9
3
Continue setting, but not relying upon, env->hflags.
10
Remove the use of set_bit() and clear_bit() in favour of using
11
deposit32() on the array element. This fixes a bug where on
12
big-endian 64-bit hosts the guest kernel would hang early on in
13
bootup.
4
14
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
15
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20191023150057.25731-22-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Thomas Huth <thuth@redhat.com>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
19
Message-id: 20230424152833.1334136-1-peter.maydell@linaro.org
9
---
20
---
10
hw/intc/armv7m_nvic.c | 22 +++++++++++++---------
21
hw/intc/allwinner-a10-pic.c | 7 ++-----
11
1 file changed, 13 insertions(+), 9 deletions(-)
22
1 file changed, 2 insertions(+), 5 deletions(-)
12
23
13
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
24
diff --git a/hw/intc/allwinner-a10-pic.c b/hw/intc/allwinner-a10-pic.c
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/armv7m_nvic.c
26
--- a/hw/intc/allwinner-a10-pic.c
16
+++ b/hw/intc/armv7m_nvic.c
27
+++ b/hw/intc/allwinner-a10-pic.c
17
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
28
@@ -XXX,XX +XXX,XX @@ static void aw_a10_pic_update(AwA10PICState *s)
18
}
29
static void aw_a10_pic_set_irq(void *opaque, int irq, int level)
19
}
30
{
20
nvic_irq_update(s);
31
AwA10PICState *s = opaque;
21
- return MEMTX_OK;
32
+ uint32_t *pending_reg = &s->irq_pending[irq / 32];
22
+ goto exit_ok;
33
23
case 0x200 ... 0x23f: /* NVIC Set pend */
34
- if (level) {
24
/* the special logic in armv7m_nvic_set_pending()
35
- set_bit(irq % 32, (void *)&s->irq_pending[irq / 32]);
25
* is not needed since IRQs are never escalated
36
- } else {
26
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
37
- clear_bit(irq % 32, (void *)&s->irq_pending[irq / 32]);
27
}
38
- }
28
}
39
+ *pending_reg = deposit32(*pending_reg, irq % 32, 1, level);
29
nvic_irq_update(s);
40
aw_a10_pic_update(s);
30
- return MEMTX_OK;
31
+ goto exit_ok;
32
case 0x300 ... 0x33f: /* NVIC Active */
33
- return MEMTX_OK; /* R/O */
34
+ goto exit_ok; /* R/O */
35
case 0x400 ... 0x5ef: /* NVIC Priority */
36
startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
37
38
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
39
}
40
}
41
nvic_irq_update(s);
42
- return MEMTX_OK;
43
+ goto exit_ok;
44
case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
45
if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
46
- return MEMTX_OK;
47
+ goto exit_ok;
48
}
49
/* fall through */
50
case 0xd1c ... 0xd23: /* System Handler Priority (SHPR2, SHPR3) */
51
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
52
set_prio(s, hdlidx, sbank, newprio);
53
}
54
nvic_irq_update(s);
55
- return MEMTX_OK;
56
+ goto exit_ok;
57
case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
58
if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
59
- return MEMTX_OK;
60
+ goto exit_ok;
61
}
62
/* All bits are W1C, so construct 32 bit value with 0s in
63
* the parts not written by the access size
64
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
65
*/
66
s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
67
}
68
- return MEMTX_OK;
69
+ goto exit_ok;
70
}
71
if (size == 4) {
72
nvic_writel(s, offset, value, attrs);
73
- return MEMTX_OK;
74
+ goto exit_ok;
75
}
76
qemu_log_mask(LOG_GUEST_ERROR,
77
"NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
78
/* This is UNPREDICTABLE; treat as RAZ/WI */
79
+
80
+ exit_ok:
81
+ /* Ensure any changes made are reflected in the cached hflags. */
82
+ arm_rebuild_hflags(&s->cpu->env);
83
return MEMTX_OK;
84
}
41
}
85
42
86
--
43
--
87
2.20.1
44
2.34.1
88
45
89
46
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
In several places in the 32-bit Arm translate.c, we try to use
2
load_cpu_field() to load from a CPUARMState field into a TCGv_i32
3
where the field is actually 64-bit. This works on little-endian
4
hosts, but gives the wrong half of the register on big-endian.
2
5
3
We will soon implement the SYS_timer. This timer is used by Linux
6
Add a new load_cpu_field_low32() which loads the low 32 bits
4
in the thermal subsystem, so once available, the subsystem will be
7
of a 64-bit field into a TCGv_i32. The new macro includes a
5
enabled and poll the temperature sensors. We need to provide the
8
compile-time check against accidentally using it on a field
6
minimum required to keep Linux booting.
9
of the wrong size. Use it to fix the two places in the code
10
where we were using load_cpu_field() on a 64-bit field.
7
11
8
Add a dummy thermal sensor returning ~25°C based on:
12
This fixes a bug where on big-endian hosts the guest would
9
https://github.com/raspberrypi/linux/blob/rpi-5.3.y/drivers/thermal/broadcom/bcm2835_thermal.c
13
crash after executing an ERET instruction, and a more corner
14
case one where some UNDEFs for attempted accesses to MSR
15
banked registers from Secure EL1 might go to the wrong EL.
10
16
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Cc: qemu-stable@nongnu.org
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 20191019234715.25750-2-f4bug@amsat.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20230424153909.1419369-2-peter.maydell@linaro.org
15
---
21
---
16
hw/misc/Makefile.objs | 1 +
22
target/arm/translate-a32.h | 7 +++++++
17
include/hw/misc/bcm2835_thermal.h | 27 ++++++
23
target/arm/tcg/translate.c | 4 ++--
18
hw/misc/bcm2835_thermal.c | 135 ++++++++++++++++++++++++++++++
24
2 files changed, 9 insertions(+), 2 deletions(-)
19
3 files changed, 163 insertions(+)
20
create mode 100644 include/hw/misc/bcm2835_thermal.h
21
create mode 100644 hw/misc/bcm2835_thermal.c
22
25
23
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
26
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
24
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/misc/Makefile.objs
28
--- a/target/arm/translate-a32.h
26
+++ b/hw/misc/Makefile.objs
29
+++ b/target/arm/translate-a32.h
27
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_OMAP) += omap_tap.o
30
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_cpu_offset(int offset)
28
common-obj-$(CONFIG_RASPI) += bcm2835_mbox.o
31
29
common-obj-$(CONFIG_RASPI) += bcm2835_property.o
32
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
30
common-obj-$(CONFIG_RASPI) += bcm2835_rng.o
33
31
+common-obj-$(CONFIG_RASPI) += bcm2835_thermal.o
34
+/* Load from the low half of a 64-bit field to a TCGv_i32 */
32
common-obj-$(CONFIG_SLAVIO) += slavio_misc.o
35
+#define load_cpu_field_low32(name) \
33
common-obj-$(CONFIG_ZYNQ) += zynq_slcr.o
36
+ ({ \
34
common-obj-$(CONFIG_ZYNQ) += zynq-xadc.o
37
+ QEMU_BUILD_BUG_ON(sizeof_field(CPUARMState, name) != 8); \
35
diff --git a/include/hw/misc/bcm2835_thermal.h b/include/hw/misc/bcm2835_thermal.h
38
+ load_cpu_offset(offsetoflow32(CPUARMState, name)); \
36
new file mode 100644
39
+ })
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/include/hw/misc/bcm2835_thermal.h
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * BCM2835 dummy thermal sensor
43
+ *
44
+ * Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
45
+ *
46
+ * SPDX-License-Identifier: GPL-2.0-or-later
47
+ */
48
+
40
+
49
+#ifndef HW_MISC_BCM2835_THERMAL_H
41
void store_cpu_offset(TCGv_i32 var, int offset, int size);
50
+#define HW_MISC_BCM2835_THERMAL_H
42
51
+
43
#define store_cpu_field(var, name) \
52
+#include "hw/sysbus.h"
44
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
53
+
45
index XXXXXXX..XXXXXXX 100644
54
+#define TYPE_BCM2835_THERMAL "bcm2835-thermal"
46
--- a/target/arm/tcg/translate.c
55
+
47
+++ b/target/arm/tcg/translate.c
56
+#define BCM2835_THERMAL(obj) \
48
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
57
+ OBJECT_CHECK(Bcm2835ThermalState, (obj), TYPE_BCM2835_THERMAL)
49
if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
58
+
50
dc_isar_feature(aa64_sel2, s)) {
59
+typedef struct {
51
/* Target EL is EL<3 minus SCR_EL3.EEL2> */
60
+ /*< private >*/
52
- tcg_el = load_cpu_field(cp15.scr_el3);
61
+ SysBusDevice parent_obj;
53
+ tcg_el = load_cpu_field_low32(cp15.scr_el3);
62
+ /*< public >*/
54
tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
63
+ MemoryRegion iomem;
55
tcg_gen_addi_i32(tcg_el, tcg_el, 3);
64
+ uint32_t ctl;
56
} else {
65
+} Bcm2835ThermalState;
57
@@ -XXX,XX +XXX,XX @@ static bool trans_ERET(DisasContext *s, arg_ERET *a)
66
+
58
}
67
+#endif
59
if (s->current_el == 2) {
68
diff --git a/hw/misc/bcm2835_thermal.c b/hw/misc/bcm2835_thermal.c
60
/* ERET from Hyp uses ELR_Hyp, not LR */
69
new file mode 100644
61
- tmp = load_cpu_field(elr_el[2]);
70
index XXXXXXX..XXXXXXX
62
+ tmp = load_cpu_field_low32(elr_el[2]);
71
--- /dev/null
63
} else {
72
+++ b/hw/misc/bcm2835_thermal.c
64
tmp = load_reg(s, 14);
73
@@ -XXX,XX +XXX,XX @@
65
}
74
+/*
75
+ * BCM2835 dummy thermal sensor
76
+ *
77
+ * Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
78
+ *
79
+ * SPDX-License-Identifier: GPL-2.0-or-later
80
+ */
81
+
82
+#include "qemu/osdep.h"
83
+#include "qemu/log.h"
84
+#include "qapi/error.h"
85
+#include "hw/misc/bcm2835_thermal.h"
86
+#include "hw/registerfields.h"
87
+#include "migration/vmstate.h"
88
+
89
+REG32(CTL, 0)
90
+FIELD(CTL, POWER_DOWN, 0, 1)
91
+FIELD(CTL, RESET, 1, 1)
92
+FIELD(CTL, BANDGAP_CTRL, 2, 3)
93
+FIELD(CTL, INTERRUPT_ENABLE, 5, 1)
94
+FIELD(CTL, DIRECT, 6, 1)
95
+FIELD(CTL, INTERRUPT_CLEAR, 7, 1)
96
+FIELD(CTL, HOLD, 8, 10)
97
+FIELD(CTL, RESET_DELAY, 18, 8)
98
+FIELD(CTL, REGULATOR_ENABLE, 26, 1)
99
+
100
+REG32(STAT, 4)
101
+FIELD(STAT, DATA, 0, 10)
102
+FIELD(STAT, VALID, 10, 1)
103
+FIELD(STAT, INTERRUPT, 11, 1)
104
+
105
+#define THERMAL_OFFSET_C 412
106
+#define THERMAL_COEFF (-0.538f)
107
+
108
+static uint16_t bcm2835_thermal_temp2adc(int temp_C)
109
+{
110
+ return (temp_C - THERMAL_OFFSET_C) / THERMAL_COEFF;
111
+}
112
+
113
+static uint64_t bcm2835_thermal_read(void *opaque, hwaddr addr, unsigned size)
114
+{
115
+ Bcm2835ThermalState *s = BCM2835_THERMAL(opaque);
116
+ uint32_t val = 0;
117
+
118
+ switch (addr) {
119
+ case A_CTL:
120
+ val = s->ctl;
121
+ break;
122
+ case A_STAT:
123
+ /* Temperature is constantly 25°C. */
124
+ val = FIELD_DP32(bcm2835_thermal_temp2adc(25), STAT, VALID, true);
125
+ break;
126
+ default:
127
+ /* MemoryRegionOps are aligned, so this can not happen. */
128
+ g_assert_not_reached();
129
+ }
130
+ return val;
131
+}
132
+
133
+static void bcm2835_thermal_write(void *opaque, hwaddr addr,
134
+ uint64_t value, unsigned size)
135
+{
136
+ Bcm2835ThermalState *s = BCM2835_THERMAL(opaque);
137
+
138
+ switch (addr) {
139
+ case A_CTL:
140
+ s->ctl = value;
141
+ break;
142
+ case A_STAT:
143
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: write 0x%" PRIx64
144
+ " to 0x%" HWADDR_PRIx "\n",
145
+ __func__, value, addr);
146
+ break;
147
+ default:
148
+ /* MemoryRegionOps are aligned, so this can not happen. */
149
+ g_assert_not_reached();
150
+ }
151
+}
152
+
153
+static const MemoryRegionOps bcm2835_thermal_ops = {
154
+ .read = bcm2835_thermal_read,
155
+ .write = bcm2835_thermal_write,
156
+ .impl.max_access_size = 4,
157
+ .valid.min_access_size = 4,
158
+ .endianness = DEVICE_NATIVE_ENDIAN,
159
+};
160
+
161
+static void bcm2835_thermal_reset(DeviceState *dev)
162
+{
163
+ Bcm2835ThermalState *s = BCM2835_THERMAL(dev);
164
+
165
+ s->ctl = 0;
166
+}
167
+
168
+static void bcm2835_thermal_realize(DeviceState *dev, Error **errp)
169
+{
170
+ Bcm2835ThermalState *s = BCM2835_THERMAL(dev);
171
+
172
+ memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_thermal_ops,
173
+ s, TYPE_BCM2835_THERMAL, 8);
174
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
175
+}
176
+
177
+static const VMStateDescription bcm2835_thermal_vmstate = {
178
+ .name = "bcm2835_thermal",
179
+ .version_id = 1,
180
+ .minimum_version_id = 1,
181
+ .fields = (VMStateField[]) {
182
+ VMSTATE_UINT32(ctl, Bcm2835ThermalState),
183
+ VMSTATE_END_OF_LIST()
184
+ }
185
+};
186
+
187
+static void bcm2835_thermal_class_init(ObjectClass *klass, void *data)
188
+{
189
+ DeviceClass *dc = DEVICE_CLASS(klass);
190
+
191
+ dc->realize = bcm2835_thermal_realize;
192
+ dc->reset = bcm2835_thermal_reset;
193
+ dc->vmsd = &bcm2835_thermal_vmstate;
194
+}
195
+
196
+static const TypeInfo bcm2835_thermal_info = {
197
+ .name = TYPE_BCM2835_THERMAL,
198
+ .parent = TYPE_SYS_BUS_DEVICE,
199
+ .instance_size = sizeof(Bcm2835ThermalState),
200
+ .class_init = bcm2835_thermal_class_init,
201
+};
202
+
203
+static void bcm2835_thermal_register_types(void)
204
+{
205
+ type_register_static(&bcm2835_thermal_info);
206
+}
207
+
208
+type_init(bcm2835_thermal_register_types)
209
--
66
--
210
2.20.1
67
2.34.1
211
212
diff view generated by jsdifflib
1
Switch the xilinx_timer code away from bottom-half based ptimers to
1
Add some compile-time asserts to the load_cpu_field() and store_cpu_field()
2
the new transaction-based ptimer API. This just requires adding
2
macros that the struct field being accessed is the expected size. This
3
begin/commit calls around the various places that modify the ptimer
3
lets us catch cases where we incorrectly tried to do a 32-bit load
4
state, and using the new ptimer_init() function to create the timer.
4
from a 64-bit struct field.
5
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20230424153909.1419369-3-peter.maydell@linaro.org
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20191017132122.4402-3-peter.maydell@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
hw/timer/xilinx_timer.c | 13 ++++++++-----
10
target/arm/translate-a32.h | 17 +++++++++++++----
14
1 file changed, 8 insertions(+), 5 deletions(-)
11
1 file changed, 13 insertions(+), 4 deletions(-)
15
12
16
diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/timer/xilinx_timer.c
15
--- a/target/arm/translate-a32.h
19
+++ b/hw/timer/xilinx_timer.c
16
+++ b/target/arm/translate-a32.h
20
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_cpu_offset(int offset)
21
#include "hw/ptimer.h"
18
return tmp;
22
#include "hw/qdev-properties.h"
23
#include "qemu/log.h"
24
-#include "qemu/main-loop.h"
25
#include "qemu/module.h"
26
27
#define D(x)
28
@@ -XXX,XX +XXX,XX @@
29
30
struct xlx_timer
31
{
32
- QEMUBH *bh;
33
ptimer_state *ptimer;
34
void *parent;
35
int nr; /* for debug. */
36
@@ -XXX,XX +XXX,XX @@ timer_read(void *opaque, hwaddr addr, unsigned int size)
37
return r;
38
}
19
}
39
20
40
+/* Must be called inside ptimer transaction block */
21
-#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
41
static void timer_enable(struct xlx_timer *xt)
22
+/* Load from a 32-bit field to a TCGv_i32 */
42
{
23
+#define load_cpu_field(name) \
43
uint64_t count;
24
+ ({ \
44
@@ -XXX,XX +XXX,XX @@ timer_write(void *opaque, hwaddr addr,
25
+ QEMU_BUILD_BUG_ON(sizeof_field(CPUARMState, name) != 4); \
45
value &= ~TCSR_TINT;
26
+ load_cpu_offset(offsetof(CPUARMState, name)); \
46
27
+ })
47
xt->regs[addr] = value & 0x7ff;
28
48
- if (value & TCSR_ENT)
29
/* Load from the low half of a 64-bit field to a TCGv_i32 */
49
+ if (value & TCSR_ENT) {
30
#define load_cpu_field_low32(name) \
50
+ ptimer_transaction_begin(xt->ptimer);
31
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_cpu_offset(int offset)
51
timer_enable(xt);
32
52
+ ptimer_transaction_commit(xt->ptimer);
33
void store_cpu_offset(TCGv_i32 var, int offset, int size);
53
+ }
34
54
break;
35
-#define store_cpu_field(var, name) \
55
36
- store_cpu_offset(var, offsetof(CPUARMState, name), \
56
default:
37
- sizeof_field(CPUARMState, name))
57
@@ -XXX,XX +XXX,XX @@ static void xilinx_timer_realize(DeviceState *dev, Error **errp)
38
+#define store_cpu_field(val, name) \
58
39
+ ({ \
59
xt->parent = t;
40
+ QEMU_BUILD_BUG_ON(sizeof_field(CPUARMState, name) != 4 \
60
xt->nr = i;
41
+ && sizeof_field(CPUARMState, name) != 1); \
61
- xt->bh = qemu_bh_new(timer_hit, xt);
42
+ store_cpu_offset(val, offsetof(CPUARMState, name), \
62
- xt->ptimer = ptimer_init_with_bh(xt->bh, PTIMER_POLICY_DEFAULT);
43
+ sizeof_field(CPUARMState, name)); \
63
+ xt->ptimer = ptimer_init(timer_hit, xt, PTIMER_POLICY_DEFAULT);
44
+ })
64
+ ptimer_transaction_begin(xt->ptimer);
45
65
ptimer_set_freq(xt->ptimer, t->freq_hz);
46
#define store_cpu_field_constant(val, name) \
66
+ ptimer_transaction_commit(xt->ptimer);
47
store_cpu_field(tcg_constant_i32(val), name)
67
}
68
69
memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, "xlnx.xps-timer",
70
--
48
--
71
2.20.1
49
2.34.1
72
73
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In allwinner_sdhost_process_desc() we just read directly from
2
guest memory into a host TransferDescriptor struct and back.
3
This only works on little-endian hosts. Abstract the reading
4
and writing of descriptors into functions that handle the
5
byte-swapping so that TransferDescriptor structs as seen by
6
the rest of the code are always in host-order.
2
7
3
This functions are given the mode and el state of the cpu
8
This fixes a failure of one of the avocado tests on s390.
4
and writes the computed value to env->hflags.
5
9
10
Cc: qemu-stable@nongnu.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20191023150057.25731-16-richard.henderson@linaro.org
15
Message-id: 20230424165053.1428857-2-peter.maydell@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
target/arm/helper.h | 4 ++++
17
hw/sd/allwinner-sdhost.c | 31 ++++++++++++++++++++++++++-----
12
target/arm/helper.c | 24 ++++++++++++++++++++++++
18
1 file changed, 26 insertions(+), 5 deletions(-)
13
2 files changed, 28 insertions(+)
14
19
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
diff --git a/hw/sd/allwinner-sdhost.c b/hw/sd/allwinner-sdhost.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
22
--- a/hw/sd/allwinner-sdhost.c
18
+++ b/target/arm/helper.h
23
+++ b/hw/sd/allwinner-sdhost.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(msr_banked, void, env, i32, i32, i32)
24
@@ -XXX,XX +XXX,XX @@ static void allwinner_sdhost_auto_stop(AwSdHostState *s)
20
DEF_HELPER_2(get_user_reg, i32, env, i32)
25
}
21
DEF_HELPER_3(set_user_reg, void, env, i32, i32)
22
23
+DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
24
+DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
25
+DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
26
+
27
DEF_HELPER_1(vfp_get_fpscr, i32, env)
28
DEF_HELPER_2(vfp_set_fpscr, void, env, i32)
29
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
33
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ void arm_rebuild_hflags(CPUARMState *env)
35
env->hflags = rebuild_hflags_internal(env);
36
}
26
}
37
27
38
+void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
28
+static void read_descriptor(AwSdHostState *s, hwaddr desc_addr,
29
+ TransferDescriptor *desc)
39
+{
30
+{
40
+ int fp_el = fp_exception_el(env, el);
31
+ uint32_t desc_words[4];
41
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
32
+ dma_memory_read(&s->dma_as, desc_addr, &desc_words, sizeof(desc_words),
42
+
33
+ MEMTXATTRS_UNSPECIFIED);
43
+ env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
34
+ desc->status = le32_to_cpu(desc_words[0]);
35
+ desc->size = le32_to_cpu(desc_words[1]);
36
+ desc->addr = le32_to_cpu(desc_words[2]);
37
+ desc->next = le32_to_cpu(desc_words[3]);
44
+}
38
+}
45
+
39
+
46
+void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
40
+static void write_descriptor(AwSdHostState *s, hwaddr desc_addr,
41
+ const TransferDescriptor *desc)
47
+{
42
+{
48
+ int fp_el = fp_exception_el(env, el);
43
+ uint32_t desc_words[4];
49
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
44
+ desc_words[0] = cpu_to_le32(desc->status);
50
+
45
+ desc_words[1] = cpu_to_le32(desc->size);
51
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
46
+ desc_words[2] = cpu_to_le32(desc->addr);
47
+ desc_words[3] = cpu_to_le32(desc->next);
48
+ dma_memory_write(&s->dma_as, desc_addr, &desc_words, sizeof(desc_words),
49
+ MEMTXATTRS_UNSPECIFIED);
52
+}
50
+}
53
+
51
+
54
+void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
52
static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
55
+{
53
hwaddr desc_addr,
56
+ int fp_el = fp_exception_el(env, el);
54
TransferDescriptor *desc,
57
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
55
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
58
+
56
uint32_t num_bytes = max_bytes;
59
+ env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx);
57
uint8_t buf[1024];
60
+}
58
61
+
59
- /* Read descriptor */
62
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
60
- dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc),
63
target_ulong *cs_base, uint32_t *pflags)
61
- MEMTXATTRS_UNSPECIFIED);
64
{
62
+ read_descriptor(s, desc_addr, desc);
63
if (desc->size == 0) {
64
desc->size = klass->max_desc_size;
65
} else if (desc->size > klass->max_desc_size) {
66
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
67
68
/* Clear hold flag and flush descriptor */
69
desc->status &= ~DESC_STATUS_HOLD;
70
- dma_memory_write(&s->dma_as, desc_addr, desc, sizeof(*desc),
71
- MEMTXATTRS_UNSPECIFIED);
72
+ write_descriptor(s, desc_addr, desc);
73
74
return num_done;
75
}
65
--
76
--
66
2.20.1
77
2.34.1
67
78
68
79
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Continue setting, but not relying upon, env->hflags.
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20191023150057.25731-19-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/op_helper.c | 3 +++
11
1 file changed, 3 insertions(+)
12
13
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/op_helper.c
16
+++ b/target/arm/op_helper.c
17
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
18
void HELPER(setend)(CPUARMState *env)
19
{
20
env->uncached_cpsr ^= CPSR_E;
21
+ arm_rebuild_hflags(env);
22
}
23
24
/* Function checks whether WFx (WFI/WFE) instructions are set up to be trapped.
25
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(cpsr_read)(CPUARMState *env)
26
void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
27
{
28
cpsr_write(env, val, mask, CPSRWriteByInstr);
29
+ /* TODO: Not all cpsr bits are relevant to hflags. */
30
+ arm_rebuild_hflags(env);
31
}
32
33
/* Write the CPSR for a 32-bit exception return */
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Continue setting, but not relying upon, env->hflags.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20191023150057.25731-23-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
linux-user/aarch64/cpu_loop.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/aarch64/cpu_loop.c
16
+++ b/linux-user/aarch64/cpu_loop.c
17
@@ -XXX,XX +XXX,XX @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
18
for (i = 1; i < 4; ++i) {
19
env->cp15.sctlr_el[i] |= SCTLR_EE;
20
}
21
+ arm_rebuild_hflags(env);
22
#endif
23
24
if (cpu_isar_feature(aa64_pauth, cpu)) {
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This is the payoff.
4
5
From perf record -g data of ubuntu 18 boot and shutdown:
6
7
BEFORE:
8
9
- 23.02% 2.82% qemu-system-aar [.] helper_lookup_tb_ptr
10
- 20.22% helper_lookup_tb_ptr
11
+ 10.05% tb_htable_lookup
12
- 9.13% cpu_get_tb_cpu_state
13
3.20% aa64_va_parameters_both
14
0.55% fp_exception_el
15
16
- 11.66% 4.74% qemu-system-aar [.] cpu_get_tb_cpu_state
17
- 6.96% cpu_get_tb_cpu_state
18
3.63% aa64_va_parameters_both
19
0.60% fp_exception_el
20
0.53% sve_exception_el
21
22
AFTER:
23
24
- 16.40% 3.40% qemu-system-aar [.] helper_lookup_tb_ptr
25
- 13.03% helper_lookup_tb_ptr
26
+ 11.19% tb_htable_lookup
27
0.55% cpu_get_tb_cpu_state
28
29
0.98% 0.71% qemu-system-aar [.] cpu_get_tb_cpu_state
30
31
0.87% 0.24% qemu-system-aar [.] rebuild_hflags_a64
32
33
Before, helper_lookup_tb_ptr is the second hottest function in the
34
application, consuming almost a quarter of the runtime. Within the
35
entire execution, cpu_get_tb_cpu_state consumes about 12%.
36
37
After, helper_lookup_tb_ptr has dropped to the fourth hottest function,
38
with consumption dropping to a sixth of the runtime. Within the
39
entire execution, cpu_get_tb_cpu_state has dropped below 1%, and the
40
supporting function to rebuild hflags also consumes about 1%.
41
42
Assertions are retained for --enable-debug-tcg.
43
44
Tested-by: Alex Bennée <alex.bennee@linaro.org>
45
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
46
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
47
Message-id: 20191023150057.25731-25-richard.henderson@linaro.org
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
49
---
50
target/arm/helper.c | 9 ++++++---
51
1 file changed, 6 insertions(+), 3 deletions(-)
52
53
diff --git a/target/arm/helper.c b/target/arm/helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/helper.c
56
+++ b/target/arm/helper.c
57
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
58
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
59
target_ulong *cs_base, uint32_t *pflags)
60
{
61
- uint32_t flags, pstate_for_ss;
62
+ uint32_t flags = env->hflags;
63
+ uint32_t pstate_for_ss;
64
65
*cs_base = 0;
66
- flags = rebuild_hflags_internal(env);
67
+#ifdef CONFIG_DEBUG_TCG
68
+ assert(flags == rebuild_hflags_internal(env));
69
+#endif
70
71
- if (is_a64(env)) {
72
+ if (FIELD_EX32(flags, TBFLAG_ANY, AARCH64_STATE)) {
73
*pc = env->pc;
74
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
75
flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
In allwinner-sun8i-emac we just read directly from guest memory into
2
a host FrameDescriptor struct and back. This only works on
3
little-endian hosts. Reading and writing of descriptors is already
4
abstracted into functions; make those functions also handle the
5
byte-swapping so that TransferDescriptor structs as seen by the rest
6
of the code are always in host-order, and fix two places that were
7
doing ad-hoc descriptor reading without using the functions.
2
8
3
Introduce cpu properties to give fine control over SVE vector lengths.
9
Cc: qemu-stable@nongnu.org
4
We introduce a property for each valid length up to the current
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
maximum supported, which is 2048-bits. The properties are named, e.g.
11
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
sve128, sve256, sve384, sve512, ..., where the number is the number of
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
bits. See the updates to docs/arm-cpu-features.rst for a description
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
of the semantics and for example uses.
14
Message-id: 20230424165053.1428857-3-peter.maydell@linaro.org
15
---
16
hw/net/allwinner-sun8i-emac.c | 22 +++++++++++++++-------
17
1 file changed, 15 insertions(+), 7 deletions(-)
9
18
10
Note, as sve-max-vq is still present and we'd like to be able to
19
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
11
support qmp_query_cpu_model_expansion with guests launched with e.g.
12
-cpu max,sve-max-vq=8 on their command lines, then we do allow
13
sve-max-vq and sve<N> properties to be provided at the same time, but
14
this is not recommended, and is why sve-max-vq is not mentioned in the
15
document. If sve-max-vq is provided then it enables all lengths smaller
16
than and including the max and disables all lengths larger. It also has
17
the side-effect that no larger lengths may be enabled and that the max
18
itself cannot be disabled. Smaller non-power-of-two lengths may,
19
however, be disabled, e.g. -cpu max,sve-max-vq=4,sve384=off provides a
20
guest the vector lengths 128, 256, and 512 bits.
21
22
This patch has been co-authored with Richard Henderson, who reworked
23
the target/arm/cpu64.c changes in order to push all the validation and
24
auto-enabling/disabling steps into the finalizer, resulting in a nice
25
LOC reduction.
26
27
Signed-off-by: Andrew Jones <drjones@redhat.com>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Eric Auger <eric.auger@redhat.com>
30
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
31
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
32
Message-id: 20191024121808.9612-5-drjones@redhat.com
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
---
35
include/qemu/bitops.h | 1 +
36
target/arm/cpu.h | 19 ++++
37
target/arm/cpu.c | 19 ++++
38
target/arm/cpu64.c | 192 ++++++++++++++++++++++++++++++++++++-
39
target/arm/helper.c | 10 +-
40
target/arm/monitor.c | 12 +++
41
tests/arm-cpu-features.c | 194 ++++++++++++++++++++++++++++++++++++++
42
docs/arm-cpu-features.rst | 168 +++++++++++++++++++++++++++++++--
43
8 files changed, 606 insertions(+), 9 deletions(-)
44
45
diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
46
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
47
--- a/include/qemu/bitops.h
21
--- a/hw/net/allwinner-sun8i-emac.c
48
+++ b/include/qemu/bitops.h
22
+++ b/hw/net/allwinner-sun8i-emac.c
49
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
50
#define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE)
24
FrameDescriptor *desc,
51
25
uint32_t phys_addr)
52
#define BIT(nr) (1UL << (nr))
26
{
53
+#define BIT_ULL(nr) (1ULL << (nr))
27
- dma_memory_read(&s->dma_as, phys_addr, desc, sizeof(*desc),
54
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
28
+ uint32_t desc_words[4];
55
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
29
+ dma_memory_read(&s->dma_as, phys_addr, &desc_words, sizeof(desc_words),
56
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
30
MEMTXATTRS_UNSPECIFIED);
57
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
+ desc->status = le32_to_cpu(desc_words[0]);
58
index XXXXXXX..XXXXXXX 100644
32
+ desc->status2 = le32_to_cpu(desc_words[1]);
59
--- a/target/arm/cpu.h
33
+ desc->addr = le32_to_cpu(desc_words[2]);
60
+++ b/target/arm/cpu.h
34
+ desc->next = le32_to_cpu(desc_words[3]);
61
@@ -XXX,XX +XXX,XX @@ typedef struct {
62
63
#ifdef TARGET_AARCH64
64
# define ARM_MAX_VQ 16
65
+void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
66
+uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq);
67
#else
68
# define ARM_MAX_VQ 1
69
+static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
70
+static inline uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq)
71
+{ return 0; }
72
#endif
73
74
typedef struct ARMVectorReg {
75
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
76
77
/* Used to set the maximum vector length the cpu will support. */
78
uint32_t sve_max_vq;
79
+
80
+ /*
81
+ * In sve_vq_map each set bit is a supported vector length of
82
+ * (bit-number + 1) * 16 bytes, i.e. each bit number + 1 is the vector
83
+ * length in quadwords.
84
+ *
85
+ * While processing properties during initialization, corresponding
86
+ * sve_vq_init bits are set for bits in sve_vq_map that have been
87
+ * set by properties.
88
+ */
89
+ DECLARE_BITMAP(sve_vq_map, ARM_MAX_VQ);
90
+ DECLARE_BITMAP(sve_vq_init, ARM_MAX_VQ);
91
};
92
93
void arm_cpu_post_init(Object *obj);
94
@@ -XXX,XX +XXX,XX @@ static inline int arm_feature(CPUARMState *env, int feature)
95
return (env->features & (1ULL << feature)) != 0;
96
}
35
}
97
36
98
+void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp);
37
static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
99
+
38
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sun8i_emac_tx_desc(AwSun8iEmacState *s,
100
#if !defined(CONFIG_USER_ONLY)
101
/* Return true if exception levels below EL3 are in secure state,
102
* or would be following an exception return to that level.
103
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/cpu.c
106
+++ b/target/arm/cpu.c
107
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_finalizefn(Object *obj)
108
#endif
109
}
39
}
110
40
111
+void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
41
static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s,
112
+{
42
- FrameDescriptor *desc,
113
+ Error *local_err = NULL;
43
+ const FrameDescriptor *desc,
114
+
44
uint32_t phys_addr)
115
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
116
+ arm_cpu_sve_finalize(cpu, &local_err);
117
+ if (local_err != NULL) {
118
+ error_propagate(errp, local_err);
119
+ return;
120
+ }
121
+ }
122
+}
123
+
124
static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
125
{
45
{
126
CPUState *cs = CPU(dev);
46
- dma_memory_write(&s->dma_as, phys_addr, desc, sizeof(*desc),
127
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
47
+ uint32_t desc_words[4];
128
return;
48
+ desc_words[0] = cpu_to_le32(desc->status);
129
}
49
+ desc_words[1] = cpu_to_le32(desc->status2);
130
50
+ desc_words[2] = cpu_to_le32(desc->addr);
131
+ arm_cpu_finalize_features(cpu, &local_err);
51
+ desc_words[3] = cpu_to_le32(desc->next);
132
+ if (local_err != NULL) {
52
+ dma_memory_write(&s->dma_as, phys_addr, &desc_words, sizeof(desc_words),
133
+ error_propagate(errp, local_err);
53
MEMTXATTRS_UNSPECIFIED);
134
+ return;
135
+ }
136
+
137
if (arm_feature(env, ARM_FEATURE_AARCH64) &&
138
cpu->has_vfp != cpu->has_neon) {
139
/*
140
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/target/arm/cpu64.c
143
+++ b/target/arm/cpu64.c
144
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
145
define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
146
}
54
}
147
55
148
+void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
56
@@ -XXX,XX +XXX,XX @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
149
+{
57
break;
150
+ /*
58
case REG_TX_CUR_BUF: /* Transmit Current Buffer */
151
+ * If any vector lengths are explicitly enabled with sve<N> properties,
59
if (s->tx_desc_curr != 0) {
152
+ * then all other lengths are implicitly disabled. If sve-max-vq is
60
- dma_memory_read(&s->dma_as, s->tx_desc_curr, &desc, sizeof(desc),
153
+ * specified then it is the same as explicitly enabling all lengths
61
- MEMTXATTRS_UNSPECIFIED);
154
+ * up to and including the specified maximum, which means all larger
62
+ allwinner_sun8i_emac_get_desc(s, &desc, s->tx_desc_curr);
155
+ * lengths will be implicitly disabled. If no sve<N> properties
63
value = desc.addr;
156
+ * are enabled and sve-max-vq is not specified, then all lengths not
64
} else {
157
+ * explicitly disabled will be enabled. Additionally, all power-of-two
65
value = 0;
158
+ * vector lengths less than the maximum enabled length will be
66
@@ -XXX,XX +XXX,XX @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
159
+ * automatically enabled and all vector lengths larger than the largest
67
break;
160
+ * disabled power-of-two vector length will be automatically disabled.
68
case REG_RX_CUR_BUF: /* Receive Current Buffer */
161
+ * Errors are generated if the user provided input that interferes with
69
if (s->rx_desc_curr != 0) {
162
+ * any of the above. Finally, if SVE is not disabled, then at least one
70
- dma_memory_read(&s->dma_as, s->rx_desc_curr, &desc, sizeof(desc),
163
+ * vector length must be enabled.
71
- MEMTXATTRS_UNSPECIFIED);
164
+ */
72
+ allwinner_sun8i_emac_get_desc(s, &desc, s->rx_desc_curr);
165
+ DECLARE_BITMAP(tmp, ARM_MAX_VQ);
73
value = desc.addr;
166
+ uint32_t vq, max_vq = 0;
74
} else {
167
+
75
value = 0;
168
+ /*
169
+ * Process explicit sve<N> properties.
170
+ * From the properties, sve_vq_map<N> implies sve_vq_init<N>.
171
+ * Check first for any sve<N> enabled.
172
+ */
173
+ if (!bitmap_empty(cpu->sve_vq_map, ARM_MAX_VQ)) {
174
+ max_vq = find_last_bit(cpu->sve_vq_map, ARM_MAX_VQ) + 1;
175
+
176
+ if (cpu->sve_max_vq && max_vq > cpu->sve_max_vq) {
177
+ error_setg(errp, "cannot enable sve%d", max_vq * 128);
178
+ error_append_hint(errp, "sve%d is larger than the maximum vector "
179
+ "length, sve-max-vq=%d (%d bits)\n",
180
+ max_vq * 128, cpu->sve_max_vq,
181
+ cpu->sve_max_vq * 128);
182
+ return;
183
+ }
184
+
185
+ /* Propagate enabled bits down through required powers-of-two. */
186
+ for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
187
+ if (!test_bit(vq - 1, cpu->sve_vq_init)) {
188
+ set_bit(vq - 1, cpu->sve_vq_map);
189
+ }
190
+ }
191
+ } else if (cpu->sve_max_vq == 0) {
192
+ /*
193
+ * No explicit bits enabled, and no implicit bits from sve-max-vq.
194
+ */
195
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
196
+ /* SVE is disabled and so are all vector lengths. Good. */
197
+ return;
198
+ }
199
+
200
+ /* Disabling a power-of-two disables all larger lengths. */
201
+ if (test_bit(0, cpu->sve_vq_init)) {
202
+ error_setg(errp, "cannot disable sve128");
203
+ error_append_hint(errp, "Disabling sve128 results in all vector "
204
+ "lengths being disabled.\n");
205
+ error_append_hint(errp, "With SVE enabled, at least one vector "
206
+ "length must be enabled.\n");
207
+ return;
208
+ }
209
+ for (vq = 2; vq <= ARM_MAX_VQ; vq <<= 1) {
210
+ if (test_bit(vq - 1, cpu->sve_vq_init)) {
211
+ break;
212
+ }
213
+ }
214
+ max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
215
+
216
+ bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq);
217
+ max_vq = find_last_bit(cpu->sve_vq_map, max_vq) + 1;
218
+ }
219
+
220
+ /*
221
+ * Process the sve-max-vq property.
222
+ * Note that we know from the above that no bit above
223
+ * sve-max-vq is currently set.
224
+ */
225
+ if (cpu->sve_max_vq != 0) {
226
+ max_vq = cpu->sve_max_vq;
227
+
228
+ if (!test_bit(max_vq - 1, cpu->sve_vq_map) &&
229
+ test_bit(max_vq - 1, cpu->sve_vq_init)) {
230
+ error_setg(errp, "cannot disable sve%d", max_vq * 128);
231
+ error_append_hint(errp, "The maximum vector length must be "
232
+ "enabled, sve-max-vq=%d (%d bits)\n",
233
+ max_vq, max_vq * 128);
234
+ return;
235
+ }
236
+
237
+ /* Set all bits not explicitly set within sve-max-vq. */
238
+ bitmap_complement(tmp, cpu->sve_vq_init, max_vq);
239
+ bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq);
240
+ }
241
+
242
+ /*
243
+ * We should know what max-vq is now. Also, as we're done
244
+ * manipulating sve-vq-map, we ensure any bits above max-vq
245
+ * are clear, just in case anybody looks.
246
+ */
247
+ assert(max_vq != 0);
248
+ bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq);
249
+
250
+ /* Ensure all required powers-of-two are enabled. */
251
+ for (vq = pow2floor(max_vq); vq >= 1; vq >>= 1) {
252
+ if (!test_bit(vq - 1, cpu->sve_vq_map)) {
253
+ error_setg(errp, "cannot disable sve%d", vq * 128);
254
+ error_append_hint(errp, "sve%d is required as it "
255
+ "is a power-of-two length smaller than "
256
+ "the maximum, sve%d\n",
257
+ vq * 128, max_vq * 128);
258
+ return;
259
+ }
260
+ }
261
+
262
+ /*
263
+ * Now that we validated all our vector lengths, the only question
264
+ * left to answer is if we even want SVE at all.
265
+ */
266
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
267
+ error_setg(errp, "cannot enable sve%d", max_vq * 128);
268
+ error_append_hint(errp, "SVE must be enabled to enable vector "
269
+ "lengths.\n");
270
+ error_append_hint(errp, "Add sve=on to the CPU property list.\n");
271
+ return;
272
+ }
273
+
274
+ /* From now on sve_max_vq is the actual maximum supported length. */
275
+ cpu->sve_max_vq = max_vq;
276
+}
277
+
278
+uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq)
279
+{
280
+ uint32_t bitnum;
281
+
282
+ /*
283
+ * We allow vq == ARM_MAX_VQ + 1 to be input because the caller may want
284
+ * to find the maximum vq enabled, which may be ARM_MAX_VQ, but this
285
+ * function always returns the next smaller than the input.
286
+ */
287
+ assert(vq && vq <= ARM_MAX_VQ + 1);
288
+
289
+ bitnum = find_last_bit(cpu->sve_vq_map, vq - 1);
290
+ return bitnum == vq - 1 ? 0 : bitnum + 1;
291
+}
292
+
293
static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
294
void *opaque, Error **errp)
295
{
296
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
297
error_propagate(errp, err);
298
}
299
300
+static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
301
+ void *opaque, Error **errp)
302
+{
303
+ ARMCPU *cpu = ARM_CPU(obj);
304
+ uint32_t vq = atoi(&name[3]) / 128;
305
+ bool value;
306
+
307
+ /* All vector lengths are disabled when SVE is off. */
308
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
309
+ value = false;
310
+ } else {
311
+ value = test_bit(vq - 1, cpu->sve_vq_map);
312
+ }
313
+ visit_type_bool(v, name, &value, errp);
314
+}
315
+
316
+static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
317
+ void *opaque, Error **errp)
318
+{
319
+ ARMCPU *cpu = ARM_CPU(obj);
320
+ uint32_t vq = atoi(&name[3]) / 128;
321
+ Error *err = NULL;
322
+ bool value;
323
+
324
+ visit_type_bool(v, name, &value, &err);
325
+ if (err) {
326
+ error_propagate(errp, err);
327
+ return;
328
+ }
329
+
330
+ if (value) {
331
+ set_bit(vq - 1, cpu->sve_vq_map);
332
+ } else {
333
+ clear_bit(vq - 1, cpu->sve_vq_map);
334
+ }
335
+ set_bit(vq - 1, cpu->sve_vq_init);
336
+}
337
+
338
static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name,
339
void *opaque, Error **errp)
340
{
341
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
342
static void aarch64_max_initfn(Object *obj)
343
{
344
ARMCPU *cpu = ARM_CPU(obj);
345
+ uint32_t vq;
346
347
if (kvm_enabled()) {
348
kvm_arm_set_cpu_features_from_host(cpu);
349
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
350
cpu->dcz_blocksize = 7; /* 512 bytes */
351
#endif
352
353
- cpu->sve_max_vq = ARM_MAX_VQ;
354
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
355
cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
356
object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
357
cpu_arm_set_sve, NULL, NULL, &error_fatal);
358
+
359
+ for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
360
+ char name[8];
361
+ sprintf(name, "sve%d", vq * 128);
362
+ object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
363
+ cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
364
+ }
365
}
366
}
367
368
diff --git a/target/arm/helper.c b/target/arm/helper.c
369
index XXXXXXX..XXXXXXX 100644
370
--- a/target/arm/helper.c
371
+++ b/target/arm/helper.c
372
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
373
return 0;
374
}
375
376
+static uint32_t sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len)
377
+{
378
+ uint32_t start_vq = (start_len & 0xf) + 1;
379
+
380
+ return arm_cpu_vq_map_next_smaller(cpu, start_vq + 1) - 1;
381
+}
382
+
383
/*
384
* Given that SVE is enabled, return the vector length for EL.
385
*/
386
@@ -XXX,XX +XXX,XX @@ uint32_t sve_zcr_len_for_el(CPUARMState *env, int el)
387
if (arm_feature(env, ARM_FEATURE_EL3)) {
388
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
389
}
390
- return zcr_len;
391
+
392
+ return sve_zcr_get_valid_len(cpu, zcr_len);
393
}
394
395
static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
396
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
397
index XXXXXXX..XXXXXXX 100644
398
--- a/target/arm/monitor.c
399
+++ b/target/arm/monitor.c
400
@@ -XXX,XX +XXX,XX @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
401
return head;
402
}
403
404
+QEMU_BUILD_BUG_ON(ARM_MAX_VQ > 16);
405
+
406
/*
407
* These are cpu model features we want to advertise. The order here
408
* matters as this is the order in which qmp_query_cpu_model_expansion
409
@@ -XXX,XX +XXX,XX @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
410
*/
411
static const char *cpu_model_advertised_features[] = {
412
"aarch64", "pmu", "sve",
413
+ "sve128", "sve256", "sve384", "sve512",
414
+ "sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280",
415
+ "sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048",
416
NULL
417
};
418
419
@@ -XXX,XX +XXX,XX @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
420
if (!err) {
421
visit_check_struct(visitor, &err);
422
}
423
+ if (!err) {
424
+ arm_cpu_finalize_features(ARM_CPU(obj), &err);
425
+ }
426
visit_end_struct(visitor, NULL);
427
visit_free(visitor);
428
if (err) {
429
@@ -XXX,XX +XXX,XX @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
430
error_propagate(errp, err);
431
return NULL;
432
}
433
+ } else {
434
+ Error *err = NULL;
435
+ arm_cpu_finalize_features(ARM_CPU(obj), &err);
436
+ assert(err == NULL);
437
}
438
439
expansion_info = g_new0(CpuModelExpansionInfo, 1);
440
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
441
index XXXXXXX..XXXXXXX 100644
442
--- a/tests/arm-cpu-features.c
443
+++ b/tests/arm-cpu-features.c
444
@@ -XXX,XX +XXX,XX @@
445
* See the COPYING file in the top-level directory.
446
*/
447
#include "qemu/osdep.h"
448
+#include "qemu/bitops.h"
449
#include "libqtest.h"
450
#include "qapi/qmp/qdict.h"
451
#include "qapi/qmp/qjson.h"
452
453
+/*
454
+ * We expect the SVE max-vq to be 16. Also it must be <= 64
455
+ * for our test code, otherwise 'vls' can't just be a uint64_t.
456
+ */
457
+#define SVE_MAX_VQ 16
458
+
459
#define MACHINE "-machine virt,gic-version=max "
460
#define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \
461
"'arguments': { 'type': 'full', "
462
@@ -XXX,XX +XXX,XX @@ static void assert_bad_props(QTestState *qts, const char *cpu_type)
463
qobject_unref(resp);
464
}
465
466
+static uint64_t resp_get_sve_vls(QDict *resp)
467
+{
468
+ QDict *props;
469
+ const QDictEntry *e;
470
+ uint64_t vls = 0;
471
+ int n = 0;
472
+
473
+ g_assert(resp);
474
+ g_assert(resp_has_props(resp));
475
+
476
+ props = resp_get_props(resp);
477
+
478
+ for (e = qdict_first(props); e; e = qdict_next(props, e)) {
479
+ if (strlen(e->key) > 3 && !strncmp(e->key, "sve", 3) &&
480
+ g_ascii_isdigit(e->key[3])) {
481
+ char *endptr;
482
+ int bits;
483
+
484
+ bits = g_ascii_strtoll(&e->key[3], &endptr, 10);
485
+ if (!bits || *endptr != '\0') {
486
+ continue;
487
+ }
488
+
489
+ if (qdict_get_bool(props, e->key)) {
490
+ vls |= BIT_ULL((bits / 128) - 1);
491
+ }
492
+ ++n;
493
+ }
494
+ }
495
+
496
+ g_assert(n == SVE_MAX_VQ);
497
+
498
+ return vls;
499
+}
500
+
501
+#define assert_sve_vls(qts, cpu_type, expected_vls, fmt, ...) \
502
+({ \
503
+ QDict *_resp = do_query(qts, cpu_type, fmt, ##__VA_ARGS__); \
504
+ g_assert(_resp); \
505
+ g_assert(resp_has_props(_resp)); \
506
+ g_assert(resp_get_sve_vls(_resp) == expected_vls); \
507
+ qobject_unref(_resp); \
508
+})
509
+
510
+static void sve_tests_default(QTestState *qts, const char *cpu_type)
511
+{
512
+ /*
513
+ * With no sve-max-vq or sve<N> properties on the command line
514
+ * the default is to have all vector lengths enabled. This also
515
+ * tests that 'sve' is 'on' by default.
516
+ */
517
+ assert_sve_vls(qts, cpu_type, BIT_ULL(SVE_MAX_VQ) - 1, NULL);
518
+
519
+ /* With SVE off, all vector lengths should also be off. */
520
+ assert_sve_vls(qts, cpu_type, 0, "{ 'sve': false }");
521
+
522
+ /* With SVE on, we must have at least one vector length enabled. */
523
+ assert_error(qts, cpu_type, "cannot disable sve128", "{ 'sve128': false }");
524
+
525
+ /* Basic enable/disable tests. */
526
+ assert_sve_vls(qts, cpu_type, 0x7, "{ 'sve384': true }");
527
+ assert_sve_vls(qts, cpu_type, ((BIT_ULL(SVE_MAX_VQ) - 1) & ~BIT_ULL(2)),
528
+ "{ 'sve384': false }");
529
+
530
+ /*
531
+ * ---------------------------------------------------------------------
532
+ * power-of-two(vq) all-power- can can
533
+ * of-two(< vq) enable disable
534
+ * ---------------------------------------------------------------------
535
+ * vq < max_vq no MUST* yes yes
536
+ * vq < max_vq yes MUST* yes no
537
+ * ---------------------------------------------------------------------
538
+ * vq == max_vq n/a MUST* yes** yes**
539
+ * ---------------------------------------------------------------------
540
+ * vq > max_vq n/a no no yes
541
+ * vq > max_vq n/a yes yes yes
542
+ * ---------------------------------------------------------------------
543
+ *
544
+ * [*] "MUST" means this requirement must already be satisfied,
545
+ * otherwise 'max_vq' couldn't itself be enabled.
546
+ *
547
+ * [**] Not testable with the QMP interface, only with the command line.
548
+ */
549
+
550
+ /* max_vq := 8 */
551
+ assert_sve_vls(qts, cpu_type, 0x8b, "{ 'sve1024': true }");
552
+
553
+ /* max_vq := 8, vq < max_vq, !power-of-two(vq) */
554
+ assert_sve_vls(qts, cpu_type, 0x8f,
555
+ "{ 'sve1024': true, 'sve384': true }");
556
+ assert_sve_vls(qts, cpu_type, 0x8b,
557
+ "{ 'sve1024': true, 'sve384': false }");
558
+
559
+ /* max_vq := 8, vq < max_vq, power-of-two(vq) */
560
+ assert_sve_vls(qts, cpu_type, 0x8b,
561
+ "{ 'sve1024': true, 'sve256': true }");
562
+ assert_error(qts, cpu_type, "cannot disable sve256",
563
+ "{ 'sve1024': true, 'sve256': false }");
564
+
565
+ /* max_vq := 3, vq > max_vq, !all-power-of-two(< vq) */
566
+ assert_error(qts, cpu_type, "cannot disable sve512",
567
+ "{ 'sve384': true, 'sve512': false, 'sve640': true }");
568
+
569
+ /*
570
+ * We can disable power-of-two vector lengths when all larger lengths
571
+ * are also disabled. We only need to disable the power-of-two length,
572
+ * as all non-enabled larger lengths will then be auto-disabled.
573
+ */
574
+ assert_sve_vls(qts, cpu_type, 0x7, "{ 'sve512': false }");
575
+
576
+ /* max_vq := 3, vq > max_vq, all-power-of-two(< vq) */
577
+ assert_sve_vls(qts, cpu_type, 0x1f,
578
+ "{ 'sve384': true, 'sve512': true, 'sve640': true }");
579
+ assert_sve_vls(qts, cpu_type, 0xf,
580
+ "{ 'sve384': true, 'sve512': true, 'sve640': false }");
581
+}
582
+
583
+static void sve_tests_sve_max_vq_8(const void *data)
584
+{
585
+ QTestState *qts;
586
+
587
+ qts = qtest_init(MACHINE "-cpu max,sve-max-vq=8");
588
+
589
+ assert_sve_vls(qts, "max", BIT_ULL(8) - 1, NULL);
590
+
591
+ /*
592
+ * Disabling the max-vq set by sve-max-vq is not allowed, but
593
+ * of course enabling it is OK.
594
+ */
595
+ assert_error(qts, "max", "cannot disable sve1024", "{ 'sve1024': false }");
596
+ assert_sve_vls(qts, "max", 0xff, "{ 'sve1024': true }");
597
+
598
+ /*
599
+ * Enabling anything larger than max-vq set by sve-max-vq is not
600
+ * allowed, but of course disabling everything larger is OK.
601
+ */
602
+ assert_error(qts, "max", "cannot enable sve1152", "{ 'sve1152': true }");
603
+ assert_sve_vls(qts, "max", 0xff, "{ 'sve1152': false }");
604
+
605
+ /*
606
+ * We can enable/disable non power-of-two lengths smaller than the
607
+ * max-vq set by sve-max-vq, but, while we can enable power-of-two
608
+ * lengths, we can't disable them.
609
+ */
610
+ assert_sve_vls(qts, "max", 0xff, "{ 'sve384': true }");
611
+ assert_sve_vls(qts, "max", 0xfb, "{ 'sve384': false }");
612
+ assert_sve_vls(qts, "max", 0xff, "{ 'sve256': true }");
613
+ assert_error(qts, "max", "cannot disable sve256", "{ 'sve256': false }");
614
+
615
+ qtest_quit(qts);
616
+}
617
+
618
+static void sve_tests_sve_off(const void *data)
619
+{
620
+ QTestState *qts;
621
+
622
+ qts = qtest_init(MACHINE "-cpu max,sve=off");
623
+
624
+ /* SVE is off, so the map should be empty. */
625
+ assert_sve_vls(qts, "max", 0, NULL);
626
+
627
+ /* The map stays empty even if we turn lengths off. */
628
+ assert_sve_vls(qts, "max", 0, "{ 'sve128': false }");
629
+
630
+ /* It's an error to enable lengths when SVE is off. */
631
+ assert_error(qts, "max", "cannot enable sve128", "{ 'sve128': true }");
632
+
633
+ /* With SVE re-enabled we should get all vector lengths enabled. */
634
+ assert_sve_vls(qts, "max", BIT_ULL(SVE_MAX_VQ) - 1, "{ 'sve': true }");
635
+
636
+ /* Or enable SVE with just specific vector lengths. */
637
+ assert_sve_vls(qts, "max", 0x3,
638
+ "{ 'sve': true, 'sve128': true, 'sve256': true }");
639
+
640
+ qtest_quit(qts);
641
+}
642
+
643
static void test_query_cpu_model_expansion(const void *data)
644
{
645
QTestState *qts;
646
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
647
if (g_str_equal(qtest_get_arch(), "aarch64")) {
648
assert_has_feature(qts, "max", "aarch64");
649
assert_has_feature(qts, "max", "sve");
650
+ assert_has_feature(qts, "max", "sve128");
651
assert_has_feature(qts, "cortex-a57", "pmu");
652
assert_has_feature(qts, "cortex-a57", "aarch64");
653
654
+ sve_tests_default(qts, "max");
655
+
656
/* Test that features that depend on KVM generate errors without. */
657
assert_error(qts, "max",
658
"'aarch64' feature cannot be disabled "
659
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
660
qtest_add_data_func("/arm/query-cpu-model-expansion",
661
NULL, test_query_cpu_model_expansion);
662
663
+ if (g_str_equal(qtest_get_arch(), "aarch64")) {
664
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq-8",
665
+ NULL, sve_tests_sve_max_vq_8);
666
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
667
+ NULL, sve_tests_sve_off);
668
+ }
669
+
670
if (kvm_available) {
671
qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
672
NULL, test_query_cpu_model_expansion_kvm);
673
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
674
index XXXXXXX..XXXXXXX 100644
675
--- a/docs/arm-cpu-features.rst
676
+++ b/docs/arm-cpu-features.rst
677
@@ -XXX,XX +XXX,XX @@ block in the script for usage) is used to issue the QMP commands.
678
(QEMU) query-cpu-model-expansion type=full model={"name":"max"}
679
{ "return": {
680
"model": { "name": "max", "props": {
681
- "pmu": true, "aarch64": true
682
+ "sve1664": true, "pmu": true, "sve1792": true, "sve1920": true,
683
+ "sve128": true, "aarch64": true, "sve1024": true, "sve": true,
684
+ "sve640": true, "sve768": true, "sve1408": true, "sve256": true,
685
+ "sve1152": true, "sve512": true, "sve384": true, "sve1536": true,
686
+ "sve896": true, "sve1280": true, "sve2048": true
687
}}}}
688
689
-We see that the `max` CPU type has the `pmu` and `aarch64` CPU features.
690
-We also see that the CPU features are enabled, as they are all `true`.
691
+We see that the `max` CPU type has the `pmu`, `aarch64`, `sve`, and many
692
+`sve<N>` CPU features. We also see that all the CPU features are
693
+enabled, as they are all `true`. (The `sve<N>` CPU features are all
694
+optional SVE vector lengths (see "SVE CPU Properties"). While with TCG
695
+all SVE vector lengths can be supported, when KVM is in use it's more
696
+likely that only a few lengths will be supported, if SVE is supported at
697
+all.)
698
699
(2) Let's try to disable the PMU::
700
701
(QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"pmu":false}}
702
{ "return": {
703
"model": { "name": "max", "props": {
704
- "pmu": false, "aarch64": true
705
+ "sve1664": true, "pmu": false, "sve1792": true, "sve1920": true,
706
+ "sve128": true, "aarch64": true, "sve1024": true, "sve": true,
707
+ "sve640": true, "sve768": true, "sve1408": true, "sve256": true,
708
+ "sve1152": true, "sve512": true, "sve384": true, "sve1536": true,
709
+ "sve896": true, "sve1280": true, "sve2048": true
710
}}}}
711
712
We see it worked, as `pmu` is now `false`.
713
@@ -XXX,XX +XXX,XX @@ We see it worked, as `pmu` is now `false`.
714
It looks like this feature is limited to a configuration we do not
715
currently have.
716
717
-(4) Let's try probing CPU features for the Cortex-A15 CPU type::
718
+(4) Let's disable `sve` and see what happens to all the optional SVE
719
+ vector lengths::
720
+
721
+ (QEMU) query-cpu-model-expansion type=full model={"name":"max","props":{"sve":false}}
722
+ { "return": {
723
+ "model": { "name": "max", "props": {
724
+ "sve1664": false, "pmu": true, "sve1792": false, "sve1920": false,
725
+ "sve128": false, "aarch64": true, "sve1024": false, "sve": false,
726
+ "sve640": false, "sve768": false, "sve1408": false, "sve256": false,
727
+ "sve1152": false, "sve512": false, "sve384": false, "sve1536": false,
728
+ "sve896": false, "sve1280": false, "sve2048": false
729
+ }}}}
730
+
731
+As expected they are now all `false`.
732
+
733
+(5) Let's try probing CPU features for the Cortex-A15 CPU type::
734
735
(QEMU) query-cpu-model-expansion type=full model={"name":"cortex-a15"}
736
{"return": {"model": {"name": "cortex-a15", "props": {"pmu": true}}}}
737
@@ -XXX,XX +XXX,XX @@ After determining which CPU features are available and supported for a
738
given CPU type, then they may be selectively enabled or disabled on the
739
QEMU command line with that CPU type::
740
741
- $ qemu-system-aarch64 -M virt -cpu max,pmu=off
742
+ $ qemu-system-aarch64 -M virt -cpu max,pmu=off,sve=on,sve128=on,sve256=on
743
744
-The example above disables the PMU for the `max` CPU type.
745
+The example above disables the PMU and enables the first two SVE vector
746
+lengths for the `max` CPU type. Note, the `sve=on` isn't actually
747
+necessary, because, as we observed above with our probe of the `max` CPU
748
+type, `sve` is already on by default. Also, based on our probe of
749
+defaults, it would seem we need to disable many SVE vector lengths, rather
750
+than only enabling the two we want. This isn't the case, because, as
751
+disabling many SVE vector lengths would be quite verbose, the `sve<N>` CPU
752
+properties have special semantics (see "SVE CPU Property Parsing
753
+Semantics").
754
+
755
+SVE CPU Properties
756
+==================
757
+
758
+There are two types of SVE CPU properties: `sve` and `sve<N>`. The first
759
+is used to enable or disable the entire SVE feature, just as the `pmu`
760
+CPU property completely enables or disables the PMU. The second type
761
+is used to enable or disable specific vector lengths, where `N` is the
762
+number of bits of the length. The `sve<N>` CPU properties have special
763
+dependencies and constraints, see "SVE CPU Property Dependencies and
764
+Constraints" below. Additionally, as we want all supported vector lengths
765
+to be enabled by default, then, in order to avoid overly verbose command
766
+lines (command lines full of `sve<N>=off`, for all `N` not wanted), we
767
+provide the parsing semantics listed in "SVE CPU Property Parsing
768
+Semantics".
769
+
770
+SVE CPU Property Dependencies and Constraints
771
+---------------------------------------------
772
+
773
+ 1) At least one vector length must be enabled when `sve` is enabled.
774
+
775
+ 2) If a vector length `N` is enabled, then all power-of-two vector
776
+ lengths smaller than `N` must also be enabled. E.g. if `sve512`
777
+ is enabled, then the 128-bit and 256-bit vector lengths must also
778
+ be enabled.
779
+
780
+SVE CPU Property Parsing Semantics
781
+----------------------------------
782
+
783
+ 1) If SVE is disabled (`sve=off`), then which SVE vector lengths
784
+ are enabled or disabled is irrelevant to the guest, as the entire
785
+ SVE feature is disabled and that disables all vector lengths for
786
+ the guest. However QEMU will still track any `sve<N>` CPU
787
+ properties provided by the user. If later an `sve=on` is provided,
788
+ then the guest will get only the enabled lengths. If no `sve=on`
789
+ is provided and there are explicitly enabled vector lengths, then
790
+ an error is generated.
791
+
792
+ 2) If SVE is enabled (`sve=on`), but no `sve<N>` CPU properties are
793
+ provided, then all supported vector lengths are enabled, including
794
+ the non-power-of-two lengths.
795
+
796
+ 3) If SVE is enabled, then an error is generated when attempting to
797
+ disable the last enabled vector length (see constraint (1) of "SVE
798
+ CPU Property Dependencies and Constraints").
799
+
800
+ 4) If one or more vector lengths have been explicitly enabled and at
801
+ at least one of the dependency lengths of the maximum enabled length
802
+ has been explicitly disabled, then an error is generated (see
803
+ constraint (2) of "SVE CPU Property Dependencies and Constraints").
804
+
805
+ 5) If one or more `sve<N>` CPU properties are set `off`, but no `sve<N>`,
806
+ CPU properties are set `on`, then the specified vector lengths are
807
+ disabled but the default for any unspecified lengths remains enabled.
808
+ Disabling a power-of-two vector length also disables all vector
809
+ lengths larger than the power-of-two length (see constraint (2) of
810
+ "SVE CPU Property Dependencies and Constraints").
811
+
812
+ 6) If one or more `sve<N>` CPU properties are set to `on`, then they
813
+ are enabled and all unspecified lengths default to disabled, except
814
+ for the required lengths per constraint (2) of "SVE CPU Property
815
+ Dependencies and Constraints", which will even be auto-enabled if
816
+ they were not explicitly enabled.
817
+
818
+ 7) If SVE was disabled (`sve=off`), allowing all vector lengths to be
819
+ explicitly disabled (i.e. avoiding the error specified in (3) of
820
+ "SVE CPU Property Parsing Semantics"), then if later an `sve=on` is
821
+ provided an error will be generated. To avoid this error, one must
822
+ enable at least one vector length prior to enabling SVE.
823
+
824
+SVE CPU Property Examples
825
+-------------------------
826
+
827
+ 1) Disable SVE::
828
+
829
+ $ qemu-system-aarch64 -M virt -cpu max,sve=off
830
+
831
+ 2) Implicitly enable all vector lengths for the `max` CPU type::
832
+
833
+ $ qemu-system-aarch64 -M virt -cpu max
834
+
835
+ 3) Only enable the 128-bit vector length::
836
+
837
+ $ qemu-system-aarch64 -M virt -cpu max,sve128=on
838
+
839
+ 4) Disable the 512-bit vector length and all larger vector lengths,
840
+ since 512 is a power-of-two. This results in all the smaller,
841
+ uninitialized lengths (128, 256, and 384) defaulting to enabled::
842
+
843
+ $ qemu-system-aarch64 -M virt -cpu max,sve512=off
844
+
845
+ 5) Enable the 128-bit, 256-bit, and 512-bit vector lengths::
846
+
847
+ $ qemu-system-aarch64 -M virt -cpu max,sve128=on,sve256=on,sve512=on
848
+
849
+ 6) The same as (5), but since the 128-bit and 256-bit vector
850
+ lengths are required for the 512-bit vector length to be enabled,
851
+ then allow them to be auto-enabled::
852
+
853
+ $ qemu-system-aarch64 -M virt -cpu max,sve512=on
854
+
855
+ 7) Do the same as (6), but by first disabling SVE and then re-enabling it::
856
+
857
+ $ qemu-system-aarch64 -M virt -cpu max,sve=off,sve512=on,sve=on
858
+
859
+ 8) Force errors regarding the last vector length::
860
+
861
+ $ qemu-system-aarch64 -M virt -cpu max,sve128=off
862
+ $ qemu-system-aarch64 -M virt -cpu max,sve=off,sve128=off,sve=on
863
+
864
+SVE CPU Property Recommendations
865
+--------------------------------
866
+
867
+The examples in "SVE CPU Property Examples" exhibit many ways to select
868
+vector lengths which developers may find useful in order to avoid overly
869
+verbose command lines. However, the recommended way to select vector
870
+lengths is to explicitly enable each desired length. Therefore only
871
+example's (1), (3), and (5) exhibit recommended uses of the properties.
872
873
--
76
--
874
2.20.1
77
2.34.1
875
78
876
79
diff view generated by jsdifflib
Deleted patch
1
From: Andrew Jones <drjones@redhat.com>
2
1
3
kvm_arm_create_scratch_host_vcpu() takes a struct kvm_vcpu_init
4
parameter. Rather than just using it as an output parameter to
5
pass back the preferred target, use it also as an input parameter,
6
allowing a caller to pass a selected target if they wish and to
7
also pass cpu features. If the caller doesn't want to select a
8
target they can pass -1 for the target which indicates they want
9
to use the preferred target and have it passed back like before.
10
11
Signed-off-by: Andrew Jones <drjones@redhat.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
14
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
15
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
16
Message-id: 20191024121808.9612-8-drjones@redhat.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
target/arm/kvm.c | 20 +++++++++++++++-----
20
target/arm/kvm32.c | 6 +++++-
21
target/arm/kvm64.c | 6 +++++-
22
3 files changed, 25 insertions(+), 7 deletions(-)
23
24
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/kvm.c
27
+++ b/target/arm/kvm.c
28
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
29
int *fdarray,
30
struct kvm_vcpu_init *init)
31
{
32
- int ret, kvmfd = -1, vmfd = -1, cpufd = -1;
33
+ int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
34
35
kvmfd = qemu_open("/dev/kvm", O_RDWR);
36
if (kvmfd < 0) {
37
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
38
goto finish;
39
}
40
41
- ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, init);
42
+ if (init->target == -1) {
43
+ struct kvm_vcpu_init preferred;
44
+
45
+ ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred);
46
+ if (!ret) {
47
+ init->target = preferred.target;
48
+ }
49
+ }
50
if (ret >= 0) {
51
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
52
if (ret < 0) {
53
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
54
* creating one kind of guest CPU which is its preferred
55
* CPU type.
56
*/
57
+ struct kvm_vcpu_init try;
58
+
59
while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) {
60
- init->target = *cpus_to_try++;
61
- memset(init->features, 0, sizeof(init->features));
62
- ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
63
+ try.target = *cpus_to_try++;
64
+ memcpy(try.features, init->features, sizeof(init->features));
65
+ ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, &try);
66
if (ret >= 0) {
67
break;
68
}
69
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
70
if (ret < 0) {
71
goto err;
72
}
73
+ init->target = try.target;
74
} else {
75
/* Treat a NULL cpus_to_try argument the same as an empty
76
* list, which means we will fail the call since this must
77
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/kvm32.c
80
+++ b/target/arm/kvm32.c
81
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
82
QEMU_KVM_ARM_TARGET_CORTEX_A15,
83
QEMU_KVM_ARM_TARGET_NONE
84
};
85
- struct kvm_vcpu_init init;
86
+ /*
87
+ * target = -1 informs kvm_arm_create_scratch_host_vcpu()
88
+ * to use the preferred target
89
+ */
90
+ struct kvm_vcpu_init init = { .target = -1, };
91
92
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
93
return false;
94
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/kvm64.c
97
+++ b/target/arm/kvm64.c
98
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
99
KVM_ARM_TARGET_CORTEX_A57,
100
QEMU_KVM_ARM_TARGET_NONE
101
};
102
- struct kvm_vcpu_init init;
103
+ /*
104
+ * target = -1 informs kvm_arm_create_scratch_host_vcpu()
105
+ * to use the preferred target
106
+ */
107
+ struct kvm_vcpu_init init = { .target = -1, };
108
109
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
110
return false;
111
--
112
2.20.1
113
114
diff view generated by jsdifflib