1
arm queue: big stuff here is my MVE codegen optimisation,
1
Hi; here's the first target-arm pullreq for the 7.0 cycle.
2
and Alex's Apple Silicon hvf support.
3
2
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit 7adb961995a3744f51396502b33ad04a56a317c3:
6
The following changes since commit 76b56fdfc9fa43ec6e5986aee33f108c6c6a511e:
7
7
8
Merge remote-tracking branch 'remotes/dgilbert-gitlab/tags/pull-virtiofs-20210916' into staging (2021-09-19 18:53:29 +0100)
8
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2021-12-14 12:46:18 -0800)
9
9
10
are available in the Git repository at:
10
are available in the Git repository at:
11
11
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210920
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211215
13
13
14
for you to fetch changes up to 1dc5a60bfe406bc1122d68cbdefda38d23134b27:
14
for you to fetch changes up to aed176558806674d030a8305d989d4e6a5073359:
15
15
16
target/arm: Optimize MVE 1op-immediate insns (2021-09-20 14:18:01 +0100)
16
tests/acpi: add expected blob for VIOT test on virt machine (2021-12-15 10:35:26 +0000)
17
17
18
----------------------------------------------------------------
18
----------------------------------------------------------------
19
target-arm queue:
19
target-arm queue:
20
* Optimize codegen for MVE when predication not active
20
* ITS: error reporting cleanup
21
* hvf: Add Apple Silicon support
21
* aspeed: improve documentation
22
* hw/intc: Set GIC maintenance interrupt level to only 0 or 1
22
* Fix STM32F2XX USART data register readout
23
* Fix mishandling of MVE FPSCR.LTPSIZE reset for usermode emulator
23
* allow emulated GICv3 to be disabled in non-TCG builds
24
* elf2dmp: Fix coverity nits
24
* fix exception priority for singlestep, misaligned PC, bp, etc
25
* Correct calculation of tlb range invalidate length
26
* npcm7xx_emc: fix missing queue_flush
27
* virt: Add VIOT ACPI table for virtio-iommu
28
* target/i386: Use assert() to sanity-check b1 in SSE decode
29
* Don't include qemu-common unnecessarily
25
30
26
----------------------------------------------------------------
31
----------------------------------------------------------------
27
Alexander Graf (7):
32
Alex Bennée (1):
28
arm: Move PMC register definitions to internals.h
33
hw/intc: clean-up error reporting for failed ITS cmd
29
hvf: Add execute to dirty log permission bitmap
30
hvf: Introduce hvf_arch_init() callback
31
hvf: Add Apple Silicon support
32
hvf: arm: Implement PSCI handling
33
arm: Add Hypervisor.framework build target
34
hvf: arm: Add rudimentary PMC support
35
34
36
Peter Collingbourne (1):
35
Jean-Philippe Brucker (8):
37
arm/hvf: Add a WFI handler
36
hw/arm/virt-acpi-build: Add VIOT table for virtio-iommu
37
hw/arm/virt: Remove device tree restriction for virtio-iommu
38
hw/arm/virt: Reject instantiation of multiple IOMMUs
39
hw/arm/virt: Use object_property_set instead of qdev_prop_set
40
tests/acpi: allow updates of VIOT expected data files
41
tests/acpi: add test case for VIOT
42
tests/acpi: add expected blobs for VIOT test on q35 machine
43
tests/acpi: add expected blob for VIOT test on virt machine
38
44
39
Peter Maydell (18):
45
Joel Stanley (4):
40
elf2dmp: Check curl_easy_setopt() return value
46
docs: aspeed: Add new boards
41
elf2dmp: Fail cleanly if PDB file specifies zero block_size
47
docs: aspeed: Update OpenBMC image URL
42
target/arm: Don't skip M-profile reset entirely in user mode
48
docs: aspeed: Give an example of booting a kernel
43
target/arm: Always clear exclusive monitor on reset
49
docs: aspeed: ADC is now modelled
44
target/arm: Consolidate ifdef blocks in reset
45
hvf: arm: Implement -cpu host
46
target/arm: Avoid goto_tb if we're trying to exit to the main loop
47
target/arm: Enforce that FPDSCR.LTPSIZE is 4 on inbound migration
48
target/arm: Add TB flag for "MVE insns not predicated"
49
target/arm: Optimize MVE logic ops
50
target/arm: Optimize MVE arithmetic ops
51
target/arm: Optimize MVE VNEG, VABS
52
target/arm: Optimize MVE VDUP
53
target/arm: Optimize MVE VMVN
54
target/arm: Optimize MVE VSHL, VSHR immediate forms
55
target/arm: Optimize MVE VSHLL and VMOVL
56
target/arm: Optimize MVE VSLI and VSRI
57
target/arm: Optimize MVE 1op-immediate insns
58
50
59
Shashi Mallela (1):
51
Olivier Hériveaux (1):
60
hw/intc: Set GIC maintenance interrupt level to only 0 or 1
52
Fix STM32F2XX USART data register readout
61
53
62
meson.build | 8 +
54
Patrick Venture (1):
63
include/sysemu/hvf_int.h | 12 +-
55
hw/net: npcm7xx_emc fix missing queue_flush
64
target/arm/cpu.h | 6 +-
65
target/arm/hvf_arm.h | 18 +
66
target/arm/internals.h | 44 ++
67
target/arm/kvm_arm.h | 2 -
68
target/arm/translate.h | 2 +
69
accel/hvf/hvf-accel-ops.c | 21 +-
70
contrib/elf2dmp/download.c | 22 +-
71
contrib/elf2dmp/pdb.c | 4 +
72
hw/intc/arm_gicv3_cpuif.c | 5 +-
73
target/arm/cpu.c | 56 +-
74
target/arm/helper.c | 77 ++-
75
target/arm/hvf/hvf.c | 1278 +++++++++++++++++++++++++++++++++++++++++
76
target/arm/machine.c | 13 +
77
target/arm/translate-m-nocp.c | 8 +-
78
target/arm/translate-mve.c | 310 +++++++---
79
target/arm/translate-vfp.c | 33 +-
80
target/arm/translate.c | 42 +-
81
target/i386/hvf/hvf.c | 10 +
82
MAINTAINERS | 5 +
83
target/arm/hvf/meson.build | 3 +
84
target/arm/hvf/trace-events | 11 +
85
target/arm/meson.build | 2 +
86
24 files changed, 1824 insertions(+), 168 deletions(-)
87
create mode 100644 target/arm/hvf_arm.h
88
create mode 100644 target/arm/hvf/hvf.c
89
create mode 100644 target/arm/hvf/meson.build
90
create mode 100644 target/arm/hvf/trace-events
91
56
57
Peter Maydell (6):
58
target/i386: Use assert() to sanity-check b1 in SSE decode
59
include/hw/i386: Don't include qemu-common.h in .h files
60
target/hexagon/cpu.h: don't include qemu-common.h
61
target/rx/cpu.h: Don't include qemu-common.h
62
hw/arm: Don't include qemu-common.h unnecessarily
63
target/arm: Correct calculation of tlb range invalidate length
64
65
Philippe Mathieu-Daudé (2):
66
hw/intc/arm_gicv3: Extract gicv3_set_gicv3state from arm_gicv3_cpuif.c
67
hw/intc/arm_gicv3: Introduce CONFIG_ARM_GIC_TCG Kconfig selector
68
69
Richard Henderson (10):
70
target/arm: Hoist pc_next to a local variable in aarch64_tr_translate_insn
71
target/arm: Hoist pc_next to a local variable in arm_tr_translate_insn
72
target/arm: Hoist pc_next to a local variable in thumb_tr_translate_insn
73
target/arm: Split arm_pre_translate_insn
74
target/arm: Advance pc for arch single-step exception
75
target/arm: Split compute_fsr_fsc out of arm_deliver_fault
76
target/arm: Take an exception if PC is misaligned
77
target/arm: Assert thumb pc is aligned
78
target/arm: Suppress bp for exceptions with more priority
79
tests/tcg: Add arm and aarch64 pc alignment tests
80
81
docs/system/arm/aspeed.rst | 26 ++++++++++++----
82
include/hw/i386/microvm.h | 1 -
83
include/hw/i386/x86.h | 1 -
84
target/arm/helper.h | 1 +
85
target/arm/syndrome.h | 5 +++
86
target/hexagon/cpu.h | 1 -
87
target/rx/cpu.h | 1 -
88
hw/arm/boot.c | 1 -
89
hw/arm/digic_boards.c | 1 -
90
hw/arm/highbank.c | 1 -
91
hw/arm/npcm7xx_boards.c | 1 -
92
hw/arm/sbsa-ref.c | 1 -
93
hw/arm/stm32f405_soc.c | 1 -
94
hw/arm/vexpress.c | 1 -
95
hw/arm/virt-acpi-build.c | 7 +++++
96
hw/arm/virt.c | 21 ++++++-------
97
hw/char/stm32f2xx_usart.c | 3 +-
98
hw/intc/arm_gicv3.c | 2 +-
99
hw/intc/arm_gicv3_cpuif.c | 10 +-----
100
hw/intc/arm_gicv3_cpuif_common.c | 22 +++++++++++++
101
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++--------
102
hw/net/npcm7xx_emc.c | 18 +++++------
103
hw/virtio/virtio-iommu-pci.c | 12 ++------
104
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++------------
105
linux-user/hexagon/cpu_loop.c | 1 +
106
target/arm/debug_helper.c | 23 ++++++++++++++
107
target/arm/gdbstub.c | 9 ++++--
108
target/arm/helper.c | 6 ++--
109
target/arm/machine.c | 10 ++++++
110
target/arm/tlb_helper.c | 63 ++++++++++++++++++++++++++++----------
111
target/arm/translate-a64.c | 23 ++++++++++++--
112
target/arm/translate.c | 58 ++++++++++++++++++++++++++---------
113
target/i386/tcg/translate.c | 12 ++------
114
tests/qtest/bios-tables-test.c | 38 +++++++++++++++++++++++
115
tests/tcg/aarch64/pcalign-a64.c | 37 ++++++++++++++++++++++
116
tests/tcg/arm/pcalign-a32.c | 46 ++++++++++++++++++++++++++++
117
hw/arm/Kconfig | 1 +
118
hw/intc/Kconfig | 5 +++
119
hw/intc/meson.build | 11 ++++---
120
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
121
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
122
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
123
tests/tcg/aarch64/Makefile.target | 4 +--
124
tests/tcg/arm/Makefile.target | 4 +++
125
44 files changed, 429 insertions(+), 145 deletions(-)
126
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
127
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
128
create mode 100644 tests/tcg/arm/pcalign-a32.c
129
create mode 100644 tests/data/acpi/q35/DSDT.viot
130
create mode 100644 tests/data/acpi/q35/VIOT.viot
131
create mode 100644 tests/data/acpi/virt/VIOT
132
diff view generated by jsdifflib
1
Optimize the MVE VSHLL insns by using TCG vector ops when possible.
1
From: Alex Bennée <alex.bennee@linaro.org>
2
This includes the VMOVL insn, which we handle in mve.decode as "VSHLL
3
with zero shift count".
4
2
3
While trying to debug a GIC ITS failure I saw some guest errors that
4
had poor formatting as well as leaving me confused as to what failed.
5
As most of the checks aren't possible without a valid dte split that
6
check apart and then check the other conditions in steps. This avoids
7
us relying on undefined data.
8
9
I still get a failure with the current kvm-unit-tests but at least I
10
know (partially) why now:
11
12
Exception return from AArch64 EL1 to AArch64 EL1 PC 0x40080588
13
PASS: gicv3: its-trigger: inv/invall: dev2/eventid=20 now triggers an LPI
14
ITS: MAPD devid=2 size = 0x8 itt=0x40430000 valid=0
15
INT dev_id=2 event_id=20
16
process_its_cmd: invalid command attributes: invalid dte: 0 for 2 (MEM_TX: 0)
17
PASS: gicv3: its-trigger: mapd valid=false: no LPI after device unmap
18
SUMMARY: 6 tests, 1 unexpected failures
19
20
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20211112170454.3158925-1-alex.bennee@linaro.org
23
Cc: Shashi Mallela <shashi.mallela@linaro.org>
24
Cc: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210913095440.13462-11-peter.maydell@linaro.org
8
---
26
---
9
target/arm/translate-mve.c | 67 +++++++++++++++++++++++++++++++++-----
27
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++++++++++++++------------
10
1 file changed, 59 insertions(+), 8 deletions(-)
28
1 file changed, 27 insertions(+), 12 deletions(-)
11
29
12
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
30
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
13
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-mve.c
32
--- a/hw/intc/arm_gicv3_its.c
15
+++ b/target/arm/translate-mve.c
33
+++ b/hw/intc/arm_gicv3_its.c
16
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SCALAR(VQSHL_U_scalar, vqshli_u)
34
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
17
DO_2SHIFT_SCALAR(VQRSHL_S_scalar, vqrshli_s)
35
if (res != MEMTX_OK) {
18
DO_2SHIFT_SCALAR(VQRSHL_U_scalar, vqrshli_u)
36
return result;
19
37
}
20
-#define DO_VSHLL(INSN, FN) \
38
+ } else {
21
- static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
39
+ qemu_log_mask(LOG_GUEST_ERROR,
22
- { \
40
+ "%s: invalid command attributes: "
23
- static MVEGenTwoOpShiftFn * const fns[] = { \
41
+ "invalid dte: %"PRIx64" for %d (MEM_TX: %d)\n",
24
- gen_helper_mve_##FN##b, \
42
+ __func__, dte, devid, res);
25
- gen_helper_mve_##FN##h, \
43
+ return result;
26
- }; \
27
- return do_2shift(s, a, fns[a->size], false); \
28
+#define DO_VSHLL(INSN, FN) \
29
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
30
+ { \
31
+ static MVEGenTwoOpShiftFn * const fns[] = { \
32
+ gen_helper_mve_##FN##b, \
33
+ gen_helper_mve_##FN##h, \
34
+ }; \
35
+ return do_2shift_vec(s, a, fns[a->size], false, do_gvec_##FN); \
36
}
44
}
37
45
38
+/*
46
- if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
39
+ * For the VSHLL vector helpers, the vece is the size of the input
47
- !cte_valid || (eventid > max_eventid)) {
40
+ * (ie MO_8 or MO_16); the helpers want to work in the output size.
41
+ * The shift count can be 0..<input size>, inclusive. (0 is VMOVL.)
42
+ */
43
+static void do_gvec_vshllbs(unsigned vece, uint32_t dofs, uint32_t aofs,
44
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
45
+{
46
+ unsigned ovece = vece + 1;
47
+ unsigned ibits = vece == MO_8 ? 8 : 16;
48
+ tcg_gen_gvec_shli(ovece, dofs, aofs, ibits, oprsz, maxsz);
49
+ tcg_gen_gvec_sari(ovece, dofs, dofs, ibits - shift, oprsz, maxsz);
50
+}
51
+
48
+
52
+static void do_gvec_vshllbu(unsigned vece, uint32_t dofs, uint32_t aofs,
49
+ /*
53
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
50
+ * In this implementation, in case of guest errors we ignore the
54
+{
51
+ * command and move onto the next command in the queue.
55
+ unsigned ovece = vece + 1;
52
+ */
56
+ tcg_gen_gvec_andi(ovece, dofs, aofs,
53
+ if (devid > s->dt.maxids.max_devids) {
57
+ ovece == MO_16 ? 0xff : 0xffff, oprsz, maxsz);
54
qemu_log_mask(LOG_GUEST_ERROR,
58
+ tcg_gen_gvec_shli(ovece, dofs, dofs, shift, oprsz, maxsz);
55
- "%s: invalid command attributes "
59
+}
56
- "devid %d or eventid %d or invalid dte %d or"
57
- "invalid cte %d or invalid ite %d\n",
58
- __func__, devid, eventid, dte_valid, cte_valid,
59
- ite_valid);
60
- /*
61
- * in this implementation, in case of error
62
- * we ignore this command and move onto the next
63
- * command in the queue
64
- */
65
+ "%s: invalid command attributes: devid %d>%d",
66
+ __func__, devid, s->dt.maxids.max_devids);
60
+
67
+
61
+static void do_gvec_vshllts(unsigned vece, uint32_t dofs, uint32_t aofs,
68
+ } else if (!dte_valid || !ite_valid || !cte_valid) {
62
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
69
+ qemu_log_mask(LOG_GUEST_ERROR,
63
+{
70
+ "%s: invalid command attributes: "
64
+ unsigned ovece = vece + 1;
71
+ "dte: %s, ite: %s, cte: %s\n",
65
+ unsigned ibits = vece == MO_8 ? 8 : 16;
72
+ __func__,
66
+ if (shift == 0) {
73
+ dte_valid ? "valid" : "invalid",
67
+ tcg_gen_gvec_sari(ovece, dofs, aofs, ibits, oprsz, maxsz);
74
+ ite_valid ? "valid" : "invalid",
68
+ } else {
75
+ cte_valid ? "valid" : "invalid");
69
+ tcg_gen_gvec_andi(ovece, dofs, aofs,
76
+ } else if (eventid > max_eventid) {
70
+ ovece == MO_16 ? 0xff00 : 0xffff0000, oprsz, maxsz);
77
+ qemu_log_mask(LOG_GUEST_ERROR,
71
+ tcg_gen_gvec_sari(ovece, dofs, dofs, ibits - shift, oprsz, maxsz);
78
+ "%s: invalid command attributes: eventid %d > %d\n",
72
+ }
79
+ __func__, eventid, max_eventid);
73
+}
80
} else {
74
+
81
/*
75
+static void do_gvec_vshlltu(unsigned vece, uint32_t dofs, uint32_t aofs,
82
* Current implementation only supports rdbase == procnum
76
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
77
+{
78
+ unsigned ovece = vece + 1;
79
+ unsigned ibits = vece == MO_8 ? 8 : 16;
80
+ if (shift == 0) {
81
+ tcg_gen_gvec_shri(ovece, dofs, aofs, ibits, oprsz, maxsz);
82
+ } else {
83
+ tcg_gen_gvec_andi(ovece, dofs, aofs,
84
+ ovece == MO_16 ? 0xff00 : 0xffff0000, oprsz, maxsz);
85
+ tcg_gen_gvec_shri(ovece, dofs, dofs, ibits - shift, oprsz, maxsz);
86
+ }
87
+}
88
+
89
DO_VSHLL(VSHLL_BS, vshllbs)
90
DO_VSHLL(VSHLL_BU, vshllbu)
91
DO_VSHLL(VSHLL_TS, vshllts)
92
--
83
--
93
2.20.1
84
2.25.1
94
85
95
86
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
Add X11, FP5280G2, G220A, Rainier and Fuji. Mention that Swift will be
4
removed in v7.0.
5
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20211117065752.330632-2-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 7 ++++++-
12
1 file changed, 6 insertions(+), 1 deletion(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ AST2400 SoC based machines :
19
20
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
21
- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
22
+- ``supermicrox11-bmc`` Supermicro X11 BMC
23
24
AST2500 SoC based machines :
25
26
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
27
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
28
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
29
- ``sonorapass-bmc`` OCP SonoraPass BMC
30
-- ``swift-bmc`` OpenPOWER Swift BMC POWER9
31
+- ``swift-bmc`` OpenPOWER Swift BMC POWER9 (to be removed in v7.0)
32
+- ``fp5280g2-bmc`` Inspur FP5280G2 BMC
33
+- ``g220a-bmc`` Bytedance G220A BMC
34
35
AST2600 SoC based machines :
36
37
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
38
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
39
+- ``rainier-bmc`` IBM Rainier POWER10 BMC
40
+- ``fuji-bmc`` Facebook Fuji BMC
41
42
Supported devices
43
-----------------
44
--
45
2.25.1
46
47
diff view generated by jsdifflib
1
Coverity points out that we aren't checking the return value
1
From: Joel Stanley <joel@jms.id.au>
2
from curl_easy_setopt().
3
2
4
Fixes: Coverity CID 1458895
3
This is the latest URL for the OpenBMC CI. The old URL still works, but
5
Inspired-by: Peter Maydell <peter.maydell@linaro.org>
4
redirects.
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
7
Reviewed-by: Viktor Prutyanov <viktor.prutyanov@phystech.edu>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Tested-by: Viktor Prutyanov <viktor.prutyanov@phystech.edu>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
9
Message-id: 20210910170656.366592-2-philmd@redhat.com
8
Message-id: 20211117065752.330632-3-joel@jms.id.au
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
contrib/elf2dmp/download.c | 22 ++++++++++------------
11
docs/system/arm/aspeed.rst | 2 +-
13
1 file changed, 10 insertions(+), 12 deletions(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
13
15
diff --git a/contrib/elf2dmp/download.c b/contrib/elf2dmp/download.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/contrib/elf2dmp/download.c
16
--- a/docs/system/arm/aspeed.rst
18
+++ b/contrib/elf2dmp/download.c
17
+++ b/docs/system/arm/aspeed.rst
19
@@ -XXX,XX +XXX,XX @@ int download_url(const char *name, const char *url)
18
@@ -XXX,XX +XXX,XX @@ The Aspeed machines can be started using the ``-kernel`` option to
20
goto out_curl;
19
load a Linux kernel or from a firmware. Images can be downloaded from
21
}
20
the OpenBMC jenkins :
22
21
23
- curl_easy_setopt(curl, CURLOPT_URL, url);
22
- https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/distro=ubuntu,label=docker-builder
24
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
23
+ https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
25
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
24
26
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
25
or directly from the OpenBMC GitHub release repository :
27
- curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
28
-
29
- if (curl_easy_perform(curl) != CURLE_OK) {
30
- err = 1;
31
- fclose(file);
32
+ if (curl_easy_setopt(curl, CURLOPT_URL, url) != CURLE_OK
33
+ || curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL) != CURLE_OK
34
+ || curl_easy_setopt(curl, CURLOPT_WRITEDATA, file) != CURLE_OK
35
+ || curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1) != CURLE_OK
36
+ || curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0) != CURLE_OK
37
+ || curl_easy_perform(curl) != CURLE_OK) {
38
unlink(name);
39
- goto out_curl;
40
+ fclose(file);
41
+ err = 1;
42
+ } else {
43
+ err = fclose(file);
44
}
45
46
- err = fclose(file);
47
-
48
out_curl:
49
curl_easy_cleanup(curl);
50
26
51
--
27
--
52
2.20.1
28
2.25.1
53
29
54
30
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
A common use case for the ASPEED machine is to boot a Linux kernel.
4
Provide a full example command line.
5
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20211117065752.330632-4-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 15 ++++++++++++---
12
1 file changed, 12 insertions(+), 3 deletions(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ Missing devices
19
Boot options
20
------------
21
22
-The Aspeed machines can be started using the ``-kernel`` option to
23
-load a Linux kernel or from a firmware. Images can be downloaded from
24
-the OpenBMC jenkins :
25
+The Aspeed machines can be started using the ``-kernel`` and ``-dtb`` options
26
+to load a Linux kernel or from a firmware. Images can be downloaded from the
27
+OpenBMC jenkins :
28
29
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
30
31
@@ -XXX,XX +XXX,XX @@ or directly from the OpenBMC GitHub release repository :
32
33
https://github.com/openbmc/openbmc/releases
34
35
+To boot a kernel directly from a Linux build tree:
36
+
37
+.. code-block:: bash
38
+
39
+ $ qemu-system-arm -M ast2600-evb -nographic \
40
+ -kernel arch/arm/boot/zImage \
41
+ -dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \
42
+ -initrd rootfs.cpio
43
+
44
The image should be attached as an MTD drive. Run :
45
46
.. code-block:: bash
47
--
48
2.25.1
49
50
diff view generated by jsdifflib
1
Optimize the MVE VMVN insn by using TCG vector ops when possible.
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
Move it to the supported list.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Message-id: 20211117065752.330632-5-joel@jms.id.au
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210913095440.13462-9-peter.maydell@linaro.org
6
---
8
---
7
target/arm/translate-mve.c | 2 +-
9
docs/system/arm/aspeed.rst | 2 +-
8
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
9
11
10
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
12
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
11
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/translate-mve.c
14
--- a/docs/system/arm/aspeed.rst
13
+++ b/target/arm/translate-mve.c
15
+++ b/docs/system/arm/aspeed.rst
14
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_1op *a)
16
@@ -XXX,XX +XXX,XX @@ Supported devices
15
17
* Front LEDs (PCA9552 on I2C bus)
16
static bool trans_VMVN(DisasContext *s, arg_1op *a)
18
* LPC Peripheral Controller (a subset of subdevices are supported)
17
{
19
* Hash/Crypto Engine (HACE) - Hash support only. TODO: HMAC and RSA
18
- return do_1op(s, a, gen_helper_mve_vmvn);
20
+ * ADC
19
+ return do_1op_vec(s, a, gen_helper_mve_vmvn, tcg_gen_gvec_not);
21
20
}
22
21
23
Missing devices
22
static bool trans_VABS_fp(DisasContext *s, arg_1op *a)
24
---------------
25
26
* Coprocessor support
27
- * ADC (out of tree implementation)
28
* PWM and Fan Controller
29
* Slave GPIO Controller
30
* Super I/O Controller
23
--
31
--
24
2.20.1
32
2.25.1
25
33
26
34
diff view generated by jsdifflib
New patch
1
From: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
1
2
3
Fix issue where the data register may be overwritten by next character
4
reception before being read and returned.
5
6
Signed-off-by: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20211128120723.4053-1-olivier.heriveaux@ledger.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/char/stm32f2xx_usart.c | 3 ++-
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/char/stm32f2xx_usart.c
18
+++ b/hw/char/stm32f2xx_usart.c
19
@@ -XXX,XX +XXX,XX @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
20
return retvalue;
21
case USART_DR:
22
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
23
+ retvalue = s->usart_dr & 0x3FF;
24
s->usart_sr &= ~USART_SR_RXNE;
25
qemu_chr_fe_accept_input(&s->chr);
26
qemu_set_irq(s->irq, 0);
27
- return s->usart_dr & 0x3FF;
28
+ return retvalue;
29
case USART_BRR:
30
return s->usart_brr;
31
case USART_CR1:
32
--
33
2.25.1
34
35
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
With Apple Silicon available to the masses, it's a good time to add support
3
gicv3_set_gicv3state() is used by arm_gicv3_common.c in
4
for driving its virtualization extensions from QEMU.
4
arm_gicv3_common_realize(). Since we want to restrict
5
arm_gicv3_cpuif.c to TCG, extract gicv3_set_gicv3state()
6
to a new file. Add this file to the meson 'specific'
7
source set, since it needs access to "cpu.h".
5
8
6
This patch adds all necessary architecture specific code to get basic VMs
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
working, including save/restore.
8
9
Known limitations:
10
11
- WFI handling is missing (follows in later patch)
12
- No watchpoint/breakpoint support
13
14
Signed-off-by: Alexander Graf <agraf@csgraf.de>
15
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
16
Reviewed-by: Sergio Lopez <slp@redhat.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20210916155404.86958-5-agraf@csgraf.de
11
Message-id: 20211115223619.2599282-2-philmd@redhat.com
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
13
---
21
meson.build | 1 +
14
hw/intc/arm_gicv3_cpuif.c | 10 +---------
22
include/sysemu/hvf_int.h | 10 +-
15
hw/intc/arm_gicv3_cpuif_common.c | 22 ++++++++++++++++++++++
23
accel/hvf/hvf-accel-ops.c | 9 +
16
hw/intc/meson.build | 1 +
24
target/arm/hvf/hvf.c | 794 ++++++++++++++++++++++++++++++++++++
17
3 files changed, 24 insertions(+), 9 deletions(-)
25
target/i386/hvf/hvf.c | 5 +
18
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
26
MAINTAINERS | 5 +
27
target/arm/hvf/trace-events | 10 +
28
7 files changed, 833 insertions(+), 1 deletion(-)
29
create mode 100644 target/arm/hvf/hvf.c
30
create mode 100644 target/arm/hvf/trace-events
31
19
32
diff --git a/meson.build b/meson.build
20
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
33
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
34
--- a/meson.build
22
--- a/hw/intc/arm_gicv3_cpuif.c
35
+++ b/meson.build
23
+++ b/hw/intc/arm_gicv3_cpuif.c
36
@@ -XXX,XX +XXX,XX @@ if have_system or have_user
37
'accel/tcg',
38
'hw/core',
39
'target/arm',
40
+ 'target/arm/hvf',
41
'target/hppa',
42
'target/i386',
43
'target/i386/kvm',
44
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/sysemu/hvf_int.h
47
+++ b/include/sysemu/hvf_int.h
48
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
49
#ifndef HVF_INT_H
25
/*
50
#define HVF_INT_H
26
- * ARM Generic Interrupt Controller v3
51
27
+ * ARM Generic Interrupt Controller v3 (emulation)
52
+#ifdef __aarch64__
28
*
53
+#include <Hypervisor/Hypervisor.h>
29
* Copyright (c) 2016 Linaro Limited
54
+#else
30
* Written by Peter Maydell
55
#include <Hypervisor/hv.h>
56
+#endif
57
58
/* hvf_slot flags */
59
#define HVF_SLOT_LOG (1 << 0)
60
@@ -XXX,XX +XXX,XX @@ struct HVFState {
61
int num_slots;
62
63
hvf_vcpu_caps *hvf_caps;
64
+ uint64_t vtimer_offset;
65
};
66
extern HVFState *hvf_state;
67
68
struct hvf_vcpu_state {
69
- int fd;
70
+ uint64_t fd;
71
+ void *exit;
72
+ bool vtimer_masked;
73
};
74
75
void assert_hvf_ok(hv_return_t ret);
76
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *);
77
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
78
int hvf_put_registers(CPUState *);
79
int hvf_get_registers(CPUState *);
80
+void hvf_kick_vcpu_thread(CPUState *cpu);
81
82
#endif
83
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/accel/hvf/hvf-accel-ops.c
86
+++ b/accel/hvf/hvf-accel-ops.c
87
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
88
32
#include "hw/irq.h"
89
HVFState *hvf_state;
33
#include "cpu.h"
90
34
91
+#ifdef __aarch64__
35
-void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
92
+#define HV_VM_DEFAULT NULL
36
-{
93
+#endif
37
- ARMCPU *arm_cpu = ARM_CPU(cpu);
94
+
38
- CPUARMState *env = &arm_cpu->env;
95
/* Memory slots */
39
-
96
40
- env->gicv3state = (void *)s;
97
hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
41
-};
98
@@ -XXX,XX +XXX,XX @@ static int hvf_init_vcpu(CPUState *cpu)
42
-
99
pthread_sigmask(SIG_BLOCK, NULL, &set);
43
static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
100
sigdelset(&set, SIG_IPI);
44
{
101
45
return env->gicv3state;
102
+#ifdef __aarch64__
46
diff --git a/hw/intc/arm_gicv3_cpuif_common.c b/hw/intc/arm_gicv3_cpuif_common.c
103
+ r = hv_vcpu_create(&cpu->hvf->fd, (hv_vcpu_exit_t **)&cpu->hvf->exit, NULL);
104
+#else
105
r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf->fd, HV_VCPU_DEFAULT);
106
+#endif
107
cpu->vcpu_dirty = 1;
108
assert_hvf_ok(r);
109
110
@@ -XXX,XX +XXX,XX @@ static void hvf_accel_ops_class_init(ObjectClass *oc, void *data)
111
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
112
113
ops->create_vcpu_thread = hvf_start_vcpu_thread;
114
+ ops->kick_vcpu_thread = hvf_kick_vcpu_thread;
115
116
ops->synchronize_post_reset = hvf_cpu_synchronize_post_reset;
117
ops->synchronize_post_init = hvf_cpu_synchronize_post_init;
118
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
119
new file mode 100644
47
new file mode 100644
120
index XXXXXXX..XXXXXXX
48
index XXXXXXX..XXXXXXX
121
--- /dev/null
49
--- /dev/null
122
+++ b/target/arm/hvf/hvf.c
50
+++ b/hw/intc/arm_gicv3_cpuif_common.c
123
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
52
+/* SPDX-License-Identifier: GPL-2.0-or-later */
124
+/*
53
+/*
125
+ * QEMU Hypervisor.framework support for Apple Silicon
54
+ * ARM Generic Interrupt Controller v3
126
+
127
+ * Copyright 2020 Alexander Graf <agraf@csgraf.de>
128
+ *
55
+ *
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
56
+ * Copyright (c) 2016 Linaro Limited
130
+ * See the COPYING file in the top-level directory.
57
+ * Written by Peter Maydell
131
+ *
58
+ *
59
+ * This code is licensed under the GPL, version 2 or (at your option)
60
+ * any later version.
132
+ */
61
+ */
133
+
62
+
134
+#include "qemu/osdep.h"
63
+#include "qemu/osdep.h"
135
+#include "qemu-common.h"
64
+#include "gicv3_internal.h"
136
+#include "qemu/error-report.h"
65
+#include "cpu.h"
137
+
66
+
138
+#include "sysemu/runstate.h"
67
+void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
139
+#include "sysemu/hvf.h"
140
+#include "sysemu/hvf_int.h"
141
+#include "sysemu/hw_accel.h"
142
+
143
+#include <mach/mach_time.h>
144
+
145
+#include "exec/address-spaces.h"
146
+#include "hw/irq.h"
147
+#include "qemu/main-loop.h"
148
+#include "sysemu/cpus.h"
149
+#include "target/arm/cpu.h"
150
+#include "target/arm/internals.h"
151
+#include "trace/trace-target_arm_hvf.h"
152
+#include "migration/vmstate.h"
153
+
154
+#define HVF_SYSREG(crn, crm, op0, op1, op2) \
155
+ ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2)
156
+#define PL1_WRITE_MASK 0x4
157
+
158
+#define SYSREG(op0, op1, crn, crm, op2) \
159
+ ((op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (crm << 1))
160
+#define SYSREG_MASK SYSREG(0x3, 0x7, 0xf, 0xf, 0x7)
161
+#define SYSREG_OSLAR_EL1 SYSREG(2, 0, 1, 0, 4)
162
+#define SYSREG_OSLSR_EL1 SYSREG(2, 0, 1, 1, 4)
163
+#define SYSREG_OSDLR_EL1 SYSREG(2, 0, 1, 3, 4)
164
+#define SYSREG_CNTPCT_EL0 SYSREG(3, 3, 14, 0, 1)
165
+
166
+#define WFX_IS_WFE (1 << 0)
167
+
168
+#define TMR_CTL_ENABLE (1 << 0)
169
+#define TMR_CTL_IMASK (1 << 1)
170
+#define TMR_CTL_ISTATUS (1 << 2)
171
+
172
+typedef struct HVFVTimer {
173
+ /* Vtimer value during migration and paused state */
174
+ uint64_t vtimer_val;
175
+} HVFVTimer;
176
+
177
+static HVFVTimer vtimer;
178
+
179
+struct hvf_reg_match {
180
+ int reg;
181
+ uint64_t offset;
182
+};
183
+
184
+static const struct hvf_reg_match hvf_reg_match[] = {
185
+ { HV_REG_X0, offsetof(CPUARMState, xregs[0]) },
186
+ { HV_REG_X1, offsetof(CPUARMState, xregs[1]) },
187
+ { HV_REG_X2, offsetof(CPUARMState, xregs[2]) },
188
+ { HV_REG_X3, offsetof(CPUARMState, xregs[3]) },
189
+ { HV_REG_X4, offsetof(CPUARMState, xregs[4]) },
190
+ { HV_REG_X5, offsetof(CPUARMState, xregs[5]) },
191
+ { HV_REG_X6, offsetof(CPUARMState, xregs[6]) },
192
+ { HV_REG_X7, offsetof(CPUARMState, xregs[7]) },
193
+ { HV_REG_X8, offsetof(CPUARMState, xregs[8]) },
194
+ { HV_REG_X9, offsetof(CPUARMState, xregs[9]) },
195
+ { HV_REG_X10, offsetof(CPUARMState, xregs[10]) },
196
+ { HV_REG_X11, offsetof(CPUARMState, xregs[11]) },
197
+ { HV_REG_X12, offsetof(CPUARMState, xregs[12]) },
198
+ { HV_REG_X13, offsetof(CPUARMState, xregs[13]) },
199
+ { HV_REG_X14, offsetof(CPUARMState, xregs[14]) },
200
+ { HV_REG_X15, offsetof(CPUARMState, xregs[15]) },
201
+ { HV_REG_X16, offsetof(CPUARMState, xregs[16]) },
202
+ { HV_REG_X17, offsetof(CPUARMState, xregs[17]) },
203
+ { HV_REG_X18, offsetof(CPUARMState, xregs[18]) },
204
+ { HV_REG_X19, offsetof(CPUARMState, xregs[19]) },
205
+ { HV_REG_X20, offsetof(CPUARMState, xregs[20]) },
206
+ { HV_REG_X21, offsetof(CPUARMState, xregs[21]) },
207
+ { HV_REG_X22, offsetof(CPUARMState, xregs[22]) },
208
+ { HV_REG_X23, offsetof(CPUARMState, xregs[23]) },
209
+ { HV_REG_X24, offsetof(CPUARMState, xregs[24]) },
210
+ { HV_REG_X25, offsetof(CPUARMState, xregs[25]) },
211
+ { HV_REG_X26, offsetof(CPUARMState, xregs[26]) },
212
+ { HV_REG_X27, offsetof(CPUARMState, xregs[27]) },
213
+ { HV_REG_X28, offsetof(CPUARMState, xregs[28]) },
214
+ { HV_REG_X29, offsetof(CPUARMState, xregs[29]) },
215
+ { HV_REG_X30, offsetof(CPUARMState, xregs[30]) },
216
+ { HV_REG_PC, offsetof(CPUARMState, pc) },
217
+};
218
+
219
+static const struct hvf_reg_match hvf_fpreg_match[] = {
220
+ { HV_SIMD_FP_REG_Q0, offsetof(CPUARMState, vfp.zregs[0]) },
221
+ { HV_SIMD_FP_REG_Q1, offsetof(CPUARMState, vfp.zregs[1]) },
222
+ { HV_SIMD_FP_REG_Q2, offsetof(CPUARMState, vfp.zregs[2]) },
223
+ { HV_SIMD_FP_REG_Q3, offsetof(CPUARMState, vfp.zregs[3]) },
224
+ { HV_SIMD_FP_REG_Q4, offsetof(CPUARMState, vfp.zregs[4]) },
225
+ { HV_SIMD_FP_REG_Q5, offsetof(CPUARMState, vfp.zregs[5]) },
226
+ { HV_SIMD_FP_REG_Q6, offsetof(CPUARMState, vfp.zregs[6]) },
227
+ { HV_SIMD_FP_REG_Q7, offsetof(CPUARMState, vfp.zregs[7]) },
228
+ { HV_SIMD_FP_REG_Q8, offsetof(CPUARMState, vfp.zregs[8]) },
229
+ { HV_SIMD_FP_REG_Q9, offsetof(CPUARMState, vfp.zregs[9]) },
230
+ { HV_SIMD_FP_REG_Q10, offsetof(CPUARMState, vfp.zregs[10]) },
231
+ { HV_SIMD_FP_REG_Q11, offsetof(CPUARMState, vfp.zregs[11]) },
232
+ { HV_SIMD_FP_REG_Q12, offsetof(CPUARMState, vfp.zregs[12]) },
233
+ { HV_SIMD_FP_REG_Q13, offsetof(CPUARMState, vfp.zregs[13]) },
234
+ { HV_SIMD_FP_REG_Q14, offsetof(CPUARMState, vfp.zregs[14]) },
235
+ { HV_SIMD_FP_REG_Q15, offsetof(CPUARMState, vfp.zregs[15]) },
236
+ { HV_SIMD_FP_REG_Q16, offsetof(CPUARMState, vfp.zregs[16]) },
237
+ { HV_SIMD_FP_REG_Q17, offsetof(CPUARMState, vfp.zregs[17]) },
238
+ { HV_SIMD_FP_REG_Q18, offsetof(CPUARMState, vfp.zregs[18]) },
239
+ { HV_SIMD_FP_REG_Q19, offsetof(CPUARMState, vfp.zregs[19]) },
240
+ { HV_SIMD_FP_REG_Q20, offsetof(CPUARMState, vfp.zregs[20]) },
241
+ { HV_SIMD_FP_REG_Q21, offsetof(CPUARMState, vfp.zregs[21]) },
242
+ { HV_SIMD_FP_REG_Q22, offsetof(CPUARMState, vfp.zregs[22]) },
243
+ { HV_SIMD_FP_REG_Q23, offsetof(CPUARMState, vfp.zregs[23]) },
244
+ { HV_SIMD_FP_REG_Q24, offsetof(CPUARMState, vfp.zregs[24]) },
245
+ { HV_SIMD_FP_REG_Q25, offsetof(CPUARMState, vfp.zregs[25]) },
246
+ { HV_SIMD_FP_REG_Q26, offsetof(CPUARMState, vfp.zregs[26]) },
247
+ { HV_SIMD_FP_REG_Q27, offsetof(CPUARMState, vfp.zregs[27]) },
248
+ { HV_SIMD_FP_REG_Q28, offsetof(CPUARMState, vfp.zregs[28]) },
249
+ { HV_SIMD_FP_REG_Q29, offsetof(CPUARMState, vfp.zregs[29]) },
250
+ { HV_SIMD_FP_REG_Q30, offsetof(CPUARMState, vfp.zregs[30]) },
251
+ { HV_SIMD_FP_REG_Q31, offsetof(CPUARMState, vfp.zregs[31]) },
252
+};
253
+
254
+struct hvf_sreg_match {
255
+ int reg;
256
+ uint32_t key;
257
+ uint32_t cp_idx;
258
+};
259
+
260
+static struct hvf_sreg_match hvf_sreg_match[] = {
261
+ { HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 4) },
262
+ { HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 5) },
263
+ { HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 6) },
264
+ { HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 7) },
265
+
266
+ { HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 4) },
267
+ { HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 5) },
268
+ { HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 6) },
269
+ { HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 7) },
270
+
271
+ { HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 4) },
272
+ { HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 5) },
273
+ { HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 6) },
274
+ { HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 7) },
275
+
276
+ { HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 4) },
277
+ { HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 5) },
278
+ { HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 6) },
279
+ { HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 7) },
280
+
281
+ { HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 4) },
282
+ { HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 5) },
283
+ { HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 6) },
284
+ { HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 7) },
285
+
286
+ { HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 4) },
287
+ { HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 5) },
288
+ { HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 6) },
289
+ { HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 7) },
290
+
291
+ { HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 4) },
292
+ { HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 5) },
293
+ { HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 6) },
294
+ { HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 7) },
295
+
296
+ { HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 4) },
297
+ { HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 5) },
298
+ { HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 6) },
299
+ { HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 7) },
300
+
301
+ { HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 4) },
302
+ { HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 5) },
303
+ { HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 6) },
304
+ { HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 7) },
305
+
306
+ { HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 4) },
307
+ { HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 5) },
308
+ { HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 6) },
309
+ { HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 7) },
310
+
311
+ { HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 4) },
312
+ { HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 5) },
313
+ { HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 6) },
314
+ { HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 7) },
315
+
316
+ { HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 4) },
317
+ { HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 5) },
318
+ { HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 6) },
319
+ { HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 7) },
320
+
321
+ { HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 4) },
322
+ { HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 5) },
323
+ { HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 6) },
324
+ { HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 7) },
325
+
326
+ { HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 4) },
327
+ { HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 5) },
328
+ { HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 6) },
329
+ { HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 7) },
330
+
331
+ { HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 4) },
332
+ { HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 5) },
333
+ { HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 6) },
334
+ { HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 7) },
335
+
336
+ { HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 4) },
337
+ { HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 5) },
338
+ { HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 6) },
339
+ { HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 7) },
340
+
341
+#ifdef SYNC_NO_RAW_REGS
342
+ /*
343
+ * The registers below are manually synced on init because they are
344
+ * marked as NO_RAW. We still list them to make number space sync easier.
345
+ */
346
+ { HV_SYS_REG_MDCCINT_EL1, HVF_SYSREG(0, 2, 2, 0, 0) },
347
+ { HV_SYS_REG_MIDR_EL1, HVF_SYSREG(0, 0, 3, 0, 0) },
348
+ { HV_SYS_REG_MPIDR_EL1, HVF_SYSREG(0, 0, 3, 0, 5) },
349
+ { HV_SYS_REG_ID_AA64PFR0_EL1, HVF_SYSREG(0, 4, 3, 0, 0) },
350
+#endif
351
+ { HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 2) },
352
+ { HV_SYS_REG_ID_AA64DFR0_EL1, HVF_SYSREG(0, 5, 3, 0, 0) },
353
+ { HV_SYS_REG_ID_AA64DFR1_EL1, HVF_SYSREG(0, 5, 3, 0, 1) },
354
+ { HV_SYS_REG_ID_AA64ISAR0_EL1, HVF_SYSREG(0, 6, 3, 0, 0) },
355
+ { HV_SYS_REG_ID_AA64ISAR1_EL1, HVF_SYSREG(0, 6, 3, 0, 1) },
356
+#ifdef SYNC_NO_MMFR0
357
+ /* We keep the hardware MMFR0 around. HW limits are there anyway */
358
+ { HV_SYS_REG_ID_AA64MMFR0_EL1, HVF_SYSREG(0, 7, 3, 0, 0) },
359
+#endif
360
+ { HV_SYS_REG_ID_AA64MMFR1_EL1, HVF_SYSREG(0, 7, 3, 0, 1) },
361
+ { HV_SYS_REG_ID_AA64MMFR2_EL1, HVF_SYSREG(0, 7, 3, 0, 2) },
362
+
363
+ { HV_SYS_REG_MDSCR_EL1, HVF_SYSREG(0, 2, 2, 0, 2) },
364
+ { HV_SYS_REG_SCTLR_EL1, HVF_SYSREG(1, 0, 3, 0, 0) },
365
+ { HV_SYS_REG_CPACR_EL1, HVF_SYSREG(1, 0, 3, 0, 2) },
366
+ { HV_SYS_REG_TTBR0_EL1, HVF_SYSREG(2, 0, 3, 0, 0) },
367
+ { HV_SYS_REG_TTBR1_EL1, HVF_SYSREG(2, 0, 3, 0, 1) },
368
+ { HV_SYS_REG_TCR_EL1, HVF_SYSREG(2, 0, 3, 0, 2) },
369
+
370
+ { HV_SYS_REG_APIAKEYLO_EL1, HVF_SYSREG(2, 1, 3, 0, 0) },
371
+ { HV_SYS_REG_APIAKEYHI_EL1, HVF_SYSREG(2, 1, 3, 0, 1) },
372
+ { HV_SYS_REG_APIBKEYLO_EL1, HVF_SYSREG(2, 1, 3, 0, 2) },
373
+ { HV_SYS_REG_APIBKEYHI_EL1, HVF_SYSREG(2, 1, 3, 0, 3) },
374
+ { HV_SYS_REG_APDAKEYLO_EL1, HVF_SYSREG(2, 2, 3, 0, 0) },
375
+ { HV_SYS_REG_APDAKEYHI_EL1, HVF_SYSREG(2, 2, 3, 0, 1) },
376
+ { HV_SYS_REG_APDBKEYLO_EL1, HVF_SYSREG(2, 2, 3, 0, 2) },
377
+ { HV_SYS_REG_APDBKEYHI_EL1, HVF_SYSREG(2, 2, 3, 0, 3) },
378
+ { HV_SYS_REG_APGAKEYLO_EL1, HVF_SYSREG(2, 3, 3, 0, 0) },
379
+ { HV_SYS_REG_APGAKEYHI_EL1, HVF_SYSREG(2, 3, 3, 0, 1) },
380
+
381
+ { HV_SYS_REG_SPSR_EL1, HVF_SYSREG(4, 0, 3, 0, 0) },
382
+ { HV_SYS_REG_ELR_EL1, HVF_SYSREG(4, 0, 3, 0, 1) },
383
+ { HV_SYS_REG_SP_EL0, HVF_SYSREG(4, 1, 3, 0, 0) },
384
+ { HV_SYS_REG_AFSR0_EL1, HVF_SYSREG(5, 1, 3, 0, 0) },
385
+ { HV_SYS_REG_AFSR1_EL1, HVF_SYSREG(5, 1, 3, 0, 1) },
386
+ { HV_SYS_REG_ESR_EL1, HVF_SYSREG(5, 2, 3, 0, 0) },
387
+ { HV_SYS_REG_FAR_EL1, HVF_SYSREG(6, 0, 3, 0, 0) },
388
+ { HV_SYS_REG_PAR_EL1, HVF_SYSREG(7, 4, 3, 0, 0) },
389
+ { HV_SYS_REG_MAIR_EL1, HVF_SYSREG(10, 2, 3, 0, 0) },
390
+ { HV_SYS_REG_AMAIR_EL1, HVF_SYSREG(10, 3, 3, 0, 0) },
391
+ { HV_SYS_REG_VBAR_EL1, HVF_SYSREG(12, 0, 3, 0, 0) },
392
+ { HV_SYS_REG_CONTEXTIDR_EL1, HVF_SYSREG(13, 0, 3, 0, 1) },
393
+ { HV_SYS_REG_TPIDR_EL1, HVF_SYSREG(13, 0, 3, 0, 4) },
394
+ { HV_SYS_REG_CNTKCTL_EL1, HVF_SYSREG(14, 1, 3, 0, 0) },
395
+ { HV_SYS_REG_CSSELR_EL1, HVF_SYSREG(0, 0, 3, 2, 0) },
396
+ { HV_SYS_REG_TPIDR_EL0, HVF_SYSREG(13, 0, 3, 3, 2) },
397
+ { HV_SYS_REG_TPIDRRO_EL0, HVF_SYSREG(13, 0, 3, 3, 3) },
398
+ { HV_SYS_REG_CNTV_CTL_EL0, HVF_SYSREG(14, 3, 3, 3, 1) },
399
+ { HV_SYS_REG_CNTV_CVAL_EL0, HVF_SYSREG(14, 3, 3, 3, 2) },
400
+ { HV_SYS_REG_SP_EL1, HVF_SYSREG(4, 1, 3, 4, 0) },
401
+};
402
+
403
+int hvf_get_registers(CPUState *cpu)
404
+{
405
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
406
+ CPUARMState *env = &arm_cpu->env;
407
+ hv_return_t ret;
408
+ uint64_t val;
409
+ hv_simd_fp_uchar16_t fpval;
410
+ int i;
411
+
412
+ for (i = 0; i < ARRAY_SIZE(hvf_reg_match); i++) {
413
+ ret = hv_vcpu_get_reg(cpu->hvf->fd, hvf_reg_match[i].reg, &val);
414
+ *(uint64_t *)((void *)env + hvf_reg_match[i].offset) = val;
415
+ assert_hvf_ok(ret);
416
+ }
417
+
418
+ for (i = 0; i < ARRAY_SIZE(hvf_fpreg_match); i++) {
419
+ ret = hv_vcpu_get_simd_fp_reg(cpu->hvf->fd, hvf_fpreg_match[i].reg,
420
+ &fpval);
421
+ memcpy((void *)env + hvf_fpreg_match[i].offset, &fpval, sizeof(fpval));
422
+ assert_hvf_ok(ret);
423
+ }
424
+
425
+ val = 0;
426
+ ret = hv_vcpu_get_reg(cpu->hvf->fd, HV_REG_FPCR, &val);
427
+ assert_hvf_ok(ret);
428
+ vfp_set_fpcr(env, val);
429
+
430
+ val = 0;
431
+ ret = hv_vcpu_get_reg(cpu->hvf->fd, HV_REG_FPSR, &val);
432
+ assert_hvf_ok(ret);
433
+ vfp_set_fpsr(env, val);
434
+
435
+ ret = hv_vcpu_get_reg(cpu->hvf->fd, HV_REG_CPSR, &val);
436
+ assert_hvf_ok(ret);
437
+ pstate_write(env, val);
438
+
439
+ for (i = 0; i < ARRAY_SIZE(hvf_sreg_match); i++) {
440
+ if (hvf_sreg_match[i].cp_idx == -1) {
441
+ continue;
442
+ }
443
+
444
+ ret = hv_vcpu_get_sys_reg(cpu->hvf->fd, hvf_sreg_match[i].reg, &val);
445
+ assert_hvf_ok(ret);
446
+
447
+ arm_cpu->cpreg_values[hvf_sreg_match[i].cp_idx] = val;
448
+ }
449
+ assert(write_list_to_cpustate(arm_cpu));
450
+
451
+ aarch64_restore_sp(env, arm_current_el(env));
452
+
453
+ return 0;
454
+}
455
+
456
+int hvf_put_registers(CPUState *cpu)
457
+{
458
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
459
+ CPUARMState *env = &arm_cpu->env;
460
+ hv_return_t ret;
461
+ uint64_t val;
462
+ hv_simd_fp_uchar16_t fpval;
463
+ int i;
464
+
465
+ for (i = 0; i < ARRAY_SIZE(hvf_reg_match); i++) {
466
+ val = *(uint64_t *)((void *)env + hvf_reg_match[i].offset);
467
+ ret = hv_vcpu_set_reg(cpu->hvf->fd, hvf_reg_match[i].reg, val);
468
+ assert_hvf_ok(ret);
469
+ }
470
+
471
+ for (i = 0; i < ARRAY_SIZE(hvf_fpreg_match); i++) {
472
+ memcpy(&fpval, (void *)env + hvf_fpreg_match[i].offset, sizeof(fpval));
473
+ ret = hv_vcpu_set_simd_fp_reg(cpu->hvf->fd, hvf_fpreg_match[i].reg,
474
+ fpval);
475
+ assert_hvf_ok(ret);
476
+ }
477
+
478
+ ret = hv_vcpu_set_reg(cpu->hvf->fd, HV_REG_FPCR, vfp_get_fpcr(env));
479
+ assert_hvf_ok(ret);
480
+
481
+ ret = hv_vcpu_set_reg(cpu->hvf->fd, HV_REG_FPSR, vfp_get_fpsr(env));
482
+ assert_hvf_ok(ret);
483
+
484
+ ret = hv_vcpu_set_reg(cpu->hvf->fd, HV_REG_CPSR, pstate_read(env));
485
+ assert_hvf_ok(ret);
486
+
487
+ aarch64_save_sp(env, arm_current_el(env));
488
+
489
+ assert(write_cpustate_to_list(arm_cpu, false));
490
+ for (i = 0; i < ARRAY_SIZE(hvf_sreg_match); i++) {
491
+ if (hvf_sreg_match[i].cp_idx == -1) {
492
+ continue;
493
+ }
494
+
495
+ val = arm_cpu->cpreg_values[hvf_sreg_match[i].cp_idx];
496
+ ret = hv_vcpu_set_sys_reg(cpu->hvf->fd, hvf_sreg_match[i].reg, val);
497
+ assert_hvf_ok(ret);
498
+ }
499
+
500
+ ret = hv_vcpu_set_vtimer_offset(cpu->hvf->fd, hvf_state->vtimer_offset);
501
+ assert_hvf_ok(ret);
502
+
503
+ return 0;
504
+}
505
+
506
+static void flush_cpu_state(CPUState *cpu)
507
+{
508
+ if (cpu->vcpu_dirty) {
509
+ hvf_put_registers(cpu);
510
+ cpu->vcpu_dirty = false;
511
+ }
512
+}
513
+
514
+static void hvf_set_reg(CPUState *cpu, int rt, uint64_t val)
515
+{
516
+ hv_return_t r;
517
+
518
+ flush_cpu_state(cpu);
519
+
520
+ if (rt < 31) {
521
+ r = hv_vcpu_set_reg(cpu->hvf->fd, HV_REG_X0 + rt, val);
522
+ assert_hvf_ok(r);
523
+ }
524
+}
525
+
526
+static uint64_t hvf_get_reg(CPUState *cpu, int rt)
527
+{
528
+ uint64_t val = 0;
529
+ hv_return_t r;
530
+
531
+ flush_cpu_state(cpu);
532
+
533
+ if (rt < 31) {
534
+ r = hv_vcpu_get_reg(cpu->hvf->fd, HV_REG_X0 + rt, &val);
535
+ assert_hvf_ok(r);
536
+ }
537
+
538
+ return val;
539
+}
540
+
541
+void hvf_arch_vcpu_destroy(CPUState *cpu)
542
+{
543
+}
544
+
545
+int hvf_arch_init_vcpu(CPUState *cpu)
546
+{
547
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
548
+ CPUARMState *env = &arm_cpu->env;
549
+ uint32_t sregs_match_len = ARRAY_SIZE(hvf_sreg_match);
550
+ uint32_t sregs_cnt = 0;
551
+ uint64_t pfr;
552
+ hv_return_t ret;
553
+ int i;
554
+
555
+ env->aarch64 = 1;
556
+ asm volatile("mrs %0, cntfrq_el0" : "=r"(arm_cpu->gt_cntfrq_hz));
557
+
558
+ /* Allocate enough space for our sysreg sync */
559
+ arm_cpu->cpreg_indexes = g_renew(uint64_t, arm_cpu->cpreg_indexes,
560
+ sregs_match_len);
561
+ arm_cpu->cpreg_values = g_renew(uint64_t, arm_cpu->cpreg_values,
562
+ sregs_match_len);
563
+ arm_cpu->cpreg_vmstate_indexes = g_renew(uint64_t,
564
+ arm_cpu->cpreg_vmstate_indexes,
565
+ sregs_match_len);
566
+ arm_cpu->cpreg_vmstate_values = g_renew(uint64_t,
567
+ arm_cpu->cpreg_vmstate_values,
568
+ sregs_match_len);
569
+
570
+ memset(arm_cpu->cpreg_values, 0, sregs_match_len * sizeof(uint64_t));
571
+
572
+ /* Populate cp list for all known sysregs */
573
+ for (i = 0; i < sregs_match_len; i++) {
574
+ const ARMCPRegInfo *ri;
575
+ uint32_t key = hvf_sreg_match[i].key;
576
+
577
+ ri = get_arm_cp_reginfo(arm_cpu->cp_regs, key);
578
+ if (ri) {
579
+ assert(!(ri->type & ARM_CP_NO_RAW));
580
+ hvf_sreg_match[i].cp_idx = sregs_cnt;
581
+ arm_cpu->cpreg_indexes[sregs_cnt++] = cpreg_to_kvm_id(key);
582
+ } else {
583
+ hvf_sreg_match[i].cp_idx = -1;
584
+ }
585
+ }
586
+ arm_cpu->cpreg_array_len = sregs_cnt;
587
+ arm_cpu->cpreg_vmstate_array_len = sregs_cnt;
588
+
589
+ assert(write_cpustate_to_list(arm_cpu, false));
590
+
591
+ /* Set CP_NO_RAW system registers on init */
592
+ ret = hv_vcpu_set_sys_reg(cpu->hvf->fd, HV_SYS_REG_MIDR_EL1,
593
+ arm_cpu->midr);
594
+ assert_hvf_ok(ret);
595
+
596
+ ret = hv_vcpu_set_sys_reg(cpu->hvf->fd, HV_SYS_REG_MPIDR_EL1,
597
+ arm_cpu->mp_affinity);
598
+ assert_hvf_ok(ret);
599
+
600
+ ret = hv_vcpu_get_sys_reg(cpu->hvf->fd, HV_SYS_REG_ID_AA64PFR0_EL1, &pfr);
601
+ assert_hvf_ok(ret);
602
+ pfr |= env->gicv3state ? (1 << 24) : 0;
603
+ ret = hv_vcpu_set_sys_reg(cpu->hvf->fd, HV_SYS_REG_ID_AA64PFR0_EL1, pfr);
604
+ assert_hvf_ok(ret);
605
+
606
+ /* We're limited to underlying hardware caps, override internal versions */
607
+ ret = hv_vcpu_get_sys_reg(cpu->hvf->fd, HV_SYS_REG_ID_AA64MMFR0_EL1,
608
+ &arm_cpu->isar.id_aa64mmfr0);
609
+ assert_hvf_ok(ret);
610
+
611
+ return 0;
612
+}
613
+
614
+void hvf_kick_vcpu_thread(CPUState *cpu)
615
+{
616
+ hv_vcpus_exit(&cpu->hvf->fd, 1);
617
+}
618
+
619
+static void hvf_raise_exception(CPUState *cpu, uint32_t excp,
620
+ uint32_t syndrome)
621
+{
68
+{
622
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
69
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
623
+ CPUARMState *env = &arm_cpu->env;
70
+ CPUARMState *env = &arm_cpu->env;
624
+
71
+
625
+ cpu->exception_index = excp;
72
+ env->gicv3state = (void *)s;
626
+ env->exception.target_el = 1;
627
+ env->exception.syndrome = syndrome;
628
+
629
+ arm_cpu_do_interrupt(cpu);
630
+}
631
+
632
+static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
633
+{
634
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
635
+ CPUARMState *env = &arm_cpu->env;
636
+ uint64_t val = 0;
637
+
638
+ switch (reg) {
639
+ case SYSREG_CNTPCT_EL0:
640
+ val = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
641
+ gt_cntfrq_period_ns(arm_cpu);
642
+ break;
643
+ case SYSREG_OSLSR_EL1:
644
+ val = env->cp15.oslsr_el1;
645
+ break;
646
+ case SYSREG_OSDLR_EL1:
647
+ /* Dummy register */
648
+ break;
649
+ default:
650
+ cpu_synchronize_state(cpu);
651
+ trace_hvf_unhandled_sysreg_read(env->pc, reg,
652
+ (reg >> 20) & 0x3,
653
+ (reg >> 14) & 0x7,
654
+ (reg >> 10) & 0xf,
655
+ (reg >> 1) & 0xf,
656
+ (reg >> 17) & 0x7);
657
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
658
+ return 1;
659
+ }
660
+
661
+ trace_hvf_sysreg_read(reg,
662
+ (reg >> 20) & 0x3,
663
+ (reg >> 14) & 0x7,
664
+ (reg >> 10) & 0xf,
665
+ (reg >> 1) & 0xf,
666
+ (reg >> 17) & 0x7,
667
+ val);
668
+ hvf_set_reg(cpu, rt, val);
669
+
670
+ return 0;
671
+}
672
+
673
+static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
674
+{
675
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
676
+ CPUARMState *env = &arm_cpu->env;
677
+
678
+ trace_hvf_sysreg_write(reg,
679
+ (reg >> 20) & 0x3,
680
+ (reg >> 14) & 0x7,
681
+ (reg >> 10) & 0xf,
682
+ (reg >> 1) & 0xf,
683
+ (reg >> 17) & 0x7,
684
+ val);
685
+
686
+ switch (reg) {
687
+ case SYSREG_OSLAR_EL1:
688
+ env->cp15.oslsr_el1 = val & 1;
689
+ break;
690
+ case SYSREG_OSDLR_EL1:
691
+ /* Dummy register */
692
+ break;
693
+ default:
694
+ cpu_synchronize_state(cpu);
695
+ trace_hvf_unhandled_sysreg_write(env->pc, reg,
696
+ (reg >> 20) & 0x3,
697
+ (reg >> 14) & 0x7,
698
+ (reg >> 10) & 0xf,
699
+ (reg >> 1) & 0xf,
700
+ (reg >> 17) & 0x7);
701
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
702
+ return 1;
703
+ }
704
+
705
+ return 0;
706
+}
707
+
708
+static int hvf_inject_interrupts(CPUState *cpu)
709
+{
710
+ if (cpu->interrupt_request & CPU_INTERRUPT_FIQ) {
711
+ trace_hvf_inject_fiq();
712
+ hv_vcpu_set_pending_interrupt(cpu->hvf->fd, HV_INTERRUPT_TYPE_FIQ,
713
+ true);
714
+ }
715
+
716
+ if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
717
+ trace_hvf_inject_irq();
718
+ hv_vcpu_set_pending_interrupt(cpu->hvf->fd, HV_INTERRUPT_TYPE_IRQ,
719
+ true);
720
+ }
721
+
722
+ return 0;
723
+}
724
+
725
+static uint64_t hvf_vtimer_val_raw(void)
726
+{
727
+ /*
728
+ * mach_absolute_time() returns the vtimer value without the VM
729
+ * offset that we define. Add our own offset on top.
730
+ */
731
+ return mach_absolute_time() - hvf_state->vtimer_offset;
732
+}
733
+
734
+static void hvf_sync_vtimer(CPUState *cpu)
735
+{
736
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
737
+ hv_return_t r;
738
+ uint64_t ctl;
739
+ bool irq_state;
740
+
741
+ if (!cpu->hvf->vtimer_masked) {
742
+ /* We will get notified on vtimer changes by hvf, nothing to do */
743
+ return;
744
+ }
745
+
746
+ r = hv_vcpu_get_sys_reg(cpu->hvf->fd, HV_SYS_REG_CNTV_CTL_EL0, &ctl);
747
+ assert_hvf_ok(r);
748
+
749
+ irq_state = (ctl & (TMR_CTL_ENABLE | TMR_CTL_IMASK | TMR_CTL_ISTATUS)) ==
750
+ (TMR_CTL_ENABLE | TMR_CTL_ISTATUS);
751
+ qemu_set_irq(arm_cpu->gt_timer_outputs[GTIMER_VIRT], irq_state);
752
+
753
+ if (!irq_state) {
754
+ /* Timer no longer asserting, we can unmask it */
755
+ hv_vcpu_set_vtimer_mask(cpu->hvf->fd, false);
756
+ cpu->hvf->vtimer_masked = false;
757
+ }
758
+}
759
+
760
+int hvf_vcpu_exec(CPUState *cpu)
761
+{
762
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
763
+ CPUARMState *env = &arm_cpu->env;
764
+ hv_vcpu_exit_t *hvf_exit = cpu->hvf->exit;
765
+ hv_return_t r;
766
+ bool advance_pc = false;
767
+
768
+ if (hvf_inject_interrupts(cpu)) {
769
+ return EXCP_INTERRUPT;
770
+ }
771
+
772
+ if (cpu->halted) {
773
+ return EXCP_HLT;
774
+ }
775
+
776
+ flush_cpu_state(cpu);
777
+
778
+ qemu_mutex_unlock_iothread();
779
+ assert_hvf_ok(hv_vcpu_run(cpu->hvf->fd));
780
+
781
+ /* handle VMEXIT */
782
+ uint64_t exit_reason = hvf_exit->reason;
783
+ uint64_t syndrome = hvf_exit->exception.syndrome;
784
+ uint32_t ec = syn_get_ec(syndrome);
785
+
786
+ qemu_mutex_lock_iothread();
787
+ switch (exit_reason) {
788
+ case HV_EXIT_REASON_EXCEPTION:
789
+ /* This is the main one, handle below. */
790
+ break;
791
+ case HV_EXIT_REASON_VTIMER_ACTIVATED:
792
+ qemu_set_irq(arm_cpu->gt_timer_outputs[GTIMER_VIRT], 1);
793
+ cpu->hvf->vtimer_masked = true;
794
+ return 0;
795
+ case HV_EXIT_REASON_CANCELED:
796
+ /* we got kicked, no exit to process */
797
+ return 0;
798
+ default:
799
+ assert(0);
800
+ }
801
+
802
+ hvf_sync_vtimer(cpu);
803
+
804
+ switch (ec) {
805
+ case EC_DATAABORT: {
806
+ bool isv = syndrome & ARM_EL_ISV;
807
+ bool iswrite = (syndrome >> 6) & 1;
808
+ bool s1ptw = (syndrome >> 7) & 1;
809
+ uint32_t sas = (syndrome >> 22) & 3;
810
+ uint32_t len = 1 << sas;
811
+ uint32_t srt = (syndrome >> 16) & 0x1f;
812
+ uint64_t val = 0;
813
+
814
+ trace_hvf_data_abort(env->pc, hvf_exit->exception.virtual_address,
815
+ hvf_exit->exception.physical_address, isv,
816
+ iswrite, s1ptw, len, srt);
817
+
818
+ assert(isv);
819
+
820
+ if (iswrite) {
821
+ val = hvf_get_reg(cpu, srt);
822
+ address_space_write(&address_space_memory,
823
+ hvf_exit->exception.physical_address,
824
+ MEMTXATTRS_UNSPECIFIED, &val, len);
825
+ } else {
826
+ address_space_read(&address_space_memory,
827
+ hvf_exit->exception.physical_address,
828
+ MEMTXATTRS_UNSPECIFIED, &val, len);
829
+ hvf_set_reg(cpu, srt, val);
830
+ }
831
+
832
+ advance_pc = true;
833
+ break;
834
+ }
835
+ case EC_SYSTEMREGISTERTRAP: {
836
+ bool isread = (syndrome >> 0) & 1;
837
+ uint32_t rt = (syndrome >> 5) & 0x1f;
838
+ uint32_t reg = syndrome & SYSREG_MASK;
839
+ uint64_t val;
840
+ int ret = 0;
841
+
842
+ if (isread) {
843
+ ret = hvf_sysreg_read(cpu, reg, rt);
844
+ } else {
845
+ val = hvf_get_reg(cpu, rt);
846
+ ret = hvf_sysreg_write(cpu, reg, val);
847
+ }
848
+
849
+ advance_pc = !ret;
850
+ break;
851
+ }
852
+ case EC_WFX_TRAP:
853
+ advance_pc = true;
854
+ break;
855
+ case EC_AA64_HVC:
856
+ cpu_synchronize_state(cpu);
857
+ trace_hvf_unknown_hvc(env->xregs[0]);
858
+ /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
859
+ env->xregs[0] = -1;
860
+ break;
861
+ case EC_AA64_SMC:
862
+ cpu_synchronize_state(cpu);
863
+ trace_hvf_unknown_smc(env->xregs[0]);
864
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
865
+ break;
866
+ default:
867
+ cpu_synchronize_state(cpu);
868
+ trace_hvf_exit(syndrome, ec, env->pc);
869
+ error_report("0x%llx: unhandled exception ec=0x%x", env->pc, ec);
870
+ }
871
+
872
+ if (advance_pc) {
873
+ uint64_t pc;
874
+
875
+ flush_cpu_state(cpu);
876
+
877
+ r = hv_vcpu_get_reg(cpu->hvf->fd, HV_REG_PC, &pc);
878
+ assert_hvf_ok(r);
879
+ pc += 4;
880
+ r = hv_vcpu_set_reg(cpu->hvf->fd, HV_REG_PC, pc);
881
+ assert_hvf_ok(r);
882
+ }
883
+
884
+ return 0;
885
+}
886
+
887
+static const VMStateDescription vmstate_hvf_vtimer = {
888
+ .name = "hvf-vtimer",
889
+ .version_id = 1,
890
+ .minimum_version_id = 1,
891
+ .fields = (VMStateField[]) {
892
+ VMSTATE_UINT64(vtimer_val, HVFVTimer),
893
+ VMSTATE_END_OF_LIST()
894
+ },
895
+};
73
+};
896
+
74
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
897
+static void hvf_vm_state_change(void *opaque, bool running, RunState state)
898
+{
899
+ HVFVTimer *s = opaque;
900
+
901
+ if (running) {
902
+ /* Update vtimer offset on all CPUs */
903
+ hvf_state->vtimer_offset = mach_absolute_time() - s->vtimer_val;
904
+ cpu_synchronize_all_states();
905
+ } else {
906
+ /* Remember vtimer value on every pause */
907
+ s->vtimer_val = hvf_vtimer_val_raw();
908
+ }
909
+}
910
+
911
+int hvf_arch_init(void)
912
+{
913
+ hvf_state->vtimer_offset = mach_absolute_time();
914
+ vmstate_register(NULL, 0, &vmstate_hvf_vtimer, &vtimer);
915
+ qemu_add_vm_change_state_handler(hvf_vm_state_change, &vtimer);
916
+ return 0;
917
+}
918
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
919
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
920
--- a/target/i386/hvf/hvf.c
76
--- a/hw/intc/meson.build
921
+++ b/target/i386/hvf/hvf.c
77
+++ b/hw/intc/meson.build
922
@@ -XXX,XX +XXX,XX @@ static inline bool apic_bus_freq_is_known(CPUX86State *env)
78
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
923
return env->apic_bus_freq != 0;
79
924
}
80
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
925
81
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
926
+void hvf_kick_vcpu_thread(CPUState *cpu)
82
+specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
927
+{
83
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
928
+ cpus_kick_thread(cpu);
84
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
929
+}
85
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
930
+
931
int hvf_arch_init(void)
932
{
933
return 0;
934
diff --git a/MAINTAINERS b/MAINTAINERS
935
index XXXXXXX..XXXXXXX 100644
936
--- a/MAINTAINERS
937
+++ b/MAINTAINERS
938
@@ -XXX,XX +XXX,XX @@ F: accel/accel-*.c
939
F: accel/Makefile.objs
940
F: accel/stubs/Makefile.objs
941
942
+Apple Silicon HVF CPUs
943
+M: Alexander Graf <agraf@csgraf.de>
944
+S: Maintained
945
+F: target/arm/hvf/
946
+
947
X86 HVF CPUs
948
M: Cameron Esfahani <dirty@apple.com>
949
M: Roman Bolshakov <r.bolshakov@yadro.com>
950
diff --git a/target/arm/hvf/trace-events b/target/arm/hvf/trace-events
951
new file mode 100644
952
index XXXXXXX..XXXXXXX
953
--- /dev/null
954
+++ b/target/arm/hvf/trace-events
955
@@ -XXX,XX +XXX,XX @@
956
+hvf_unhandled_sysreg_read(uint64_t pc, uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2) "unhandled sysreg read at pc=0x%"PRIx64": 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d)"
957
+hvf_unhandled_sysreg_write(uint64_t pc, uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2) "unhandled sysreg write at pc=0x%"PRIx64": 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d)"
958
+hvf_inject_fiq(void) "injecting FIQ"
959
+hvf_inject_irq(void) "injecting IRQ"
960
+hvf_data_abort(uint64_t pc, uint64_t va, uint64_t pa, bool isv, bool iswrite, bool s1ptw, uint32_t len, uint32_t srt) "data abort: [pc=0x%"PRIx64" va=0x%016"PRIx64" pa=0x%016"PRIx64" isv=%d iswrite=%d s1ptw=%d len=%d srt=%d]"
961
+hvf_sysreg_read(uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2, uint64_t val) "sysreg read 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d) = 0x%016"PRIx64
962
+hvf_sysreg_write(uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2, uint64_t val) "sysreg write 0x%08x (op0=%d op1=%d crn=%d crm=%d op2=%d, val=0x%016"PRIx64")"
963
+hvf_unknown_hvc(uint64_t x0) "unknown HVC! 0x%016"PRIx64
964
+hvf_unknown_smc(uint64_t x0) "unknown SMC! 0x%016"PRIx64
965
+hvf_exit(uint64_t syndrome, uint32_t ec, uint64_t pc) "exit: 0x%"PRIx64" [ec=0x%x pc=0x%"PRIx64"]"
966
--
86
--
967
2.20.1
87
2.25.1
968
88
969
89
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
The TYPE_ARM_GICV3 device is an emulated one. When using
4
KVM, it is recommended to use the TYPE_KVM_ARM_GICV3 device
5
(which uses in-kernel support).
6
7
When using --with-devices-FOO, it is possible to build a
8
binary with a specific set of devices. When this binary is
9
restricted to KVM accelerator, the TYPE_ARM_GICV3 device is
10
irrelevant, and it is desirable to remove it from the binary.
11
12
Therefore introduce the CONFIG_ARM_GIC_TCG Kconfig selector
13
which select the files required to have the TYPE_ARM_GICV3
14
device, but also allowing to de-select this device.
15
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20211115223619.2599282-3-philmd@redhat.com
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
hw/intc/arm_gicv3.c | 2 +-
22
hw/intc/Kconfig | 5 +++++
23
hw/intc/meson.build | 10 ++++++----
24
3 files changed, 12 insertions(+), 5 deletions(-)
25
26
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/arm_gicv3.c
29
+++ b/hw/intc/arm_gicv3.c
30
@@ -XXX,XX +XXX,XX @@
31
/*
32
- * ARM Generic Interrupt Controller v3
33
+ * ARM Generic Interrupt Controller v3 (emulation)
34
*
35
* Copyright (c) 2015 Huawei.
36
* Copyright (c) 2016 Linaro Limited
37
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/intc/Kconfig
40
+++ b/hw/intc/Kconfig
41
@@ -XXX,XX +XXX,XX @@ config APIC
42
select MSI_NONBROKEN
43
select I8259
44
45
+config ARM_GIC_TCG
46
+ bool
47
+ default y
48
+ depends on ARM_GIC && TCG
49
+
50
config ARM_GIC_KVM
51
bool
52
default y
53
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/intc/meson.build
56
+++ b/hw/intc/meson.build
57
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARM_GIC', if_true: files(
58
'arm_gic.c',
59
'arm_gic_common.c',
60
'arm_gicv2m.c',
61
- 'arm_gicv3.c',
62
'arm_gicv3_common.c',
63
- 'arm_gicv3_dist.c',
64
'arm_gicv3_its_common.c',
65
- 'arm_gicv3_redist.c',
66
+))
67
+softmmu_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files(
68
+ 'arm_gicv3.c',
69
+ 'arm_gicv3_dist.c',
70
'arm_gicv3_its.c',
71
+ 'arm_gicv3_redist.c',
72
))
73
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
74
softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
75
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
76
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
77
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
78
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
79
-specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
80
+specific_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files('arm_gicv3_cpuif.c'))
81
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
82
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
83
specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
84
--
85
2.25.1
86
87
diff view generated by jsdifflib
1
Optimize the MVE VDUP insns by using TCG vector ops when possible.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210913095440.13462-8-peter.maydell@linaro.org
6
---
6
---
7
target/arm/translate-mve.c | 12 ++++++++----
7
target/arm/translate-a64.c | 7 ++++---
8
1 file changed, 8 insertions(+), 4 deletions(-)
8
1 file changed, 4 insertions(+), 3 deletions(-)
9
9
10
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
10
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/translate-mve.c
12
--- a/target/arm/translate-a64.c
13
+++ b/target/arm/translate-mve.c
13
+++ b/target/arm/translate-a64.c
14
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
14
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
15
return true;
15
{
16
DisasContext *s = container_of(dcbase, DisasContext, base);
17
CPUARMState *env = cpu->env_ptr;
18
+ uint64_t pc = s->base.pc_next;
19
uint32_t insn;
20
21
if (s->ss_active && !s->pstate_ss) {
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
23
return;
16
}
24
}
17
25
18
- qd = mve_qreg_ptr(a->qd);
26
- s->pc_curr = s->base.pc_next;
19
rt = load_reg(s, a->rt);
27
- insn = arm_ldl_code(env, &s->base, s->base.pc_next, s->sctlr_b);
20
- tcg_gen_dup_i32(a->size, rt, rt);
28
+ s->pc_curr = pc;
21
- gen_helper_mve_vdup(cpu_env, qd, rt);
29
+ insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
22
- tcg_temp_free_ptr(qd);
30
s->insn = insn;
23
+ if (mve_no_predication(s)) {
31
- s->base.pc_next += 4;
24
+ tcg_gen_gvec_dup_i32(a->size, mve_qreg_offset(a->qd), 16, 16, rt);
32
+ s->base.pc_next = pc + 4;
25
+ } else {
33
26
+ qd = mve_qreg_ptr(a->qd);
34
s->fp_access_checked = false;
27
+ tcg_gen_dup_i32(a->size, rt, rt);
35
s->sve_access_checked = false;
28
+ gen_helper_mve_vdup(cpu_env, qd, rt);
29
+ tcg_temp_free_ptr(qd);
30
+ }
31
tcg_temp_free_i32(rt);
32
mve_update_eci(s);
33
return true;
34
--
36
--
35
2.20.1
37
2.25.1
36
38
37
39
diff view generated by jsdifflib
1
Our current codegen for MVE always calls out to helper functions,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
because some byte lanes might be predicated. The common case is that
3
in fact there is no predication active and all lanes should be
4
updated together, so we can produce better code by detecting that and
5
using the TCG generic vector infrastructure.
6
2
7
Add a TB flag that is set when we can guarantee that there is no
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
active MVE predication, and a bool in the DisasContext. Subsequent
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
patches will use this flag to generate improved code for some
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
instructions.
6
---
7
target/arm/translate.c | 9 +++++----
8
1 file changed, 5 insertions(+), 4 deletions(-)
11
9
12
In most cases when the predication state changes we simply end the TB
13
after that instruction. For the code called from vfp_access_check()
14
that handles lazy state preservation and creating a new FP context,
15
we can usually avoid having to try to end the TB because luckily the
16
new value of the flag following the register changes in those
17
sequences doesn't depend on any runtime decisions. We do have to end
18
the TB if the guest has enabled lazy FP state preservation but not
19
automatic state preservation, but this is an odd corner case that is
20
not going to be common in real-world code.
21
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 20210913095440.13462-4-peter.maydell@linaro.org
25
---
26
target/arm/cpu.h | 4 +++-
27
target/arm/translate.h | 2 ++
28
target/arm/helper.c | 33 +++++++++++++++++++++++++++++++++
29
target/arm/translate-m-nocp.c | 8 +++++++-
30
target/arm/translate-mve.c | 13 ++++++++++++-
31
target/arm/translate-vfp.c | 33 +++++++++++++++++++++++++++------
32
target/arm/translate.c | 8 ++++++++
33
7 files changed, 92 insertions(+), 9 deletions(-)
34
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
38
+++ b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
40
* | TBFLAG_AM32 | +-----+----------+
41
* | | |TBFLAG_M32|
42
* +-------------+----------------+----------+
43
- * 31 23 5 4 0
44
+ * 31 23 6 5 0
45
*
46
* Unless otherwise noted, these bits are cached in env->hflags.
47
*/
48
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_M32, LSPACT, 2, 1) /* Not cached. */
49
FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 3, 1) /* Not cached. */
50
/* Set if FPCCR.S does not match current security state */
51
FIELD(TBFLAG_M32, FPCCR_S_WRONG, 4, 1) /* Not cached. */
52
+/* Set if MVE insns are definitely not predicated by VPR or LTPSIZE */
53
+FIELD(TBFLAG_M32, MVE_NO_PRED, 5, 1) /* Not cached. */
54
55
/*
56
* Bit usage when in AArch64 state
57
diff --git a/target/arm/translate.h b/target/arm/translate.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/translate.h
60
+++ b/target/arm/translate.h
61
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
62
bool align_mem;
63
/* True if PSTATE.IL is set */
64
bool pstate_il;
65
+ /* True if MVE insns are definitely not predicated by VPR or LTPSIZE */
66
+ bool mve_no_pred;
67
/*
68
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
69
* < 0, set by the current instruction.
70
diff --git a/target/arm/helper.c b/target/arm/helper.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/helper.c
73
+++ b/target/arm/helper.c
74
@@ -XXX,XX +XXX,XX @@ static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
75
#endif
76
}
77
78
+static bool mve_no_pred(CPUARMState *env)
79
+{
80
+ /*
81
+ * Return true if there is definitely no predication of MVE
82
+ * instructions by VPR or LTPSIZE. (Returning false even if there
83
+ * isn't any predication is OK; generated code will just be
84
+ * a little worse.)
85
+ * If the CPU does not implement MVE then this TB flag is always 0.
86
+ *
87
+ * NOTE: if you change this logic, the "recalculate s->mve_no_pred"
88
+ * logic in gen_update_fp_context() needs to be updated to match.
89
+ *
90
+ * We do not include the effect of the ECI bits here -- they are
91
+ * tracked in other TB flags. This simplifies the logic for
92
+ * "when did we emit code that changes the MVE_NO_PRED TB flag
93
+ * and thus need to end the TB?".
94
+ */
95
+ if (cpu_isar_feature(aa32_mve, env_archcpu(env))) {
96
+ return false;
97
+ }
98
+ if (env->v7m.vpr) {
99
+ return false;
100
+ }
101
+ if (env->v7m.ltpsize < 4) {
102
+ return false;
103
+ }
104
+ return true;
105
+}
106
+
107
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
108
target_ulong *cs_base, uint32_t *pflags)
109
{
110
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
111
if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
112
DP_TBFLAG_M32(flags, LSPACT, 1);
113
}
114
+
115
+ if (mve_no_pred(env)) {
116
+ DP_TBFLAG_M32(flags, MVE_NO_PRED, 1);
117
+ }
118
} else {
119
/*
120
* Note that XSCALE_CPAR shares bits with VECSTRIDE.
121
diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/target/arm/translate-m-nocp.c
124
+++ b/target/arm/translate-m-nocp.c
125
@@ -XXX,XX +XXX,XX @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
126
127
clear_eci_state(s);
128
129
- /* End the TB, because we have updated FP control bits */
130
+ /*
131
+ * End the TB, because we have updated FP control bits,
132
+ * and possibly VPR or LTPSIZE.
133
+ */
134
s->base.is_jmp = DISAS_UPDATE_EXIT;
135
return true;
136
}
137
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
138
store_cpu_field(control, v7m.control[M_REG_S]);
139
tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
140
gen_helper_vfp_set_fpscr(cpu_env, tmp);
141
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
142
tcg_temp_free_i32(tmp);
143
tcg_temp_free_i32(sfpa);
144
break;
145
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
146
}
147
tmp = loadfn(s, opaque, true);
148
store_cpu_field(tmp, v7m.vpr);
149
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
150
break;
151
case ARM_VFP_P0:
152
{
153
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
154
tcg_gen_deposit_i32(vpr, vpr, tmp,
155
R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH);
156
store_cpu_field(vpr, v7m.vpr);
157
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
158
tcg_temp_free_i32(tmp);
159
break;
160
}
161
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/translate-mve.c
164
+++ b/target/arm/translate-mve.c
165
@@ -XXX,XX +XXX,XX @@ DO_LOGIC(VORR, gen_helper_mve_vorr)
166
DO_LOGIC(VORN, gen_helper_mve_vorn)
167
DO_LOGIC(VEOR, gen_helper_mve_veor)
168
169
-DO_LOGIC(VPSEL, gen_helper_mve_vpsel)
170
+static bool trans_VPSEL(DisasContext *s, arg_2op *a)
171
+{
172
+ /* This insn updates predication bits */
173
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
174
+ return do_2op(s, a, gen_helper_mve_vpsel);
175
+}
176
177
#define DO_2OP(INSN, FN) \
178
static bool trans_##INSN(DisasContext *s, arg_2op *a) \
179
@@ -XXX,XX +XXX,XX @@ static bool trans_VPNOT(DisasContext *s, arg_VPNOT *a)
180
}
181
182
gen_helper_mve_vpnot(cpu_env);
183
+ /* This insn updates predication bits */
184
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
185
mve_update_eci(s);
186
return true;
187
}
188
@@ -XXX,XX +XXX,XX @@ static bool do_vcmp(DisasContext *s, arg_vcmp *a, MVEGenCmpFn *fn)
189
/* VPT */
190
gen_vpst(s, a->mask);
191
}
192
+ /* This insn updates predication bits */
193
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
194
mve_update_eci(s);
195
return true;
196
}
197
@@ -XXX,XX +XXX,XX @@ static bool do_vcmp_scalar(DisasContext *s, arg_vcmp_scalar *a,
198
/* VPT */
199
gen_vpst(s, a->mask);
200
}
201
+ /* This insn updates predication bits */
202
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
203
mve_update_eci(s);
204
return true;
205
}
206
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/arm/translate-vfp.c
209
+++ b/target/arm/translate-vfp.c
210
@@ -XXX,XX +XXX,XX @@ static inline long vfp_f16_offset(unsigned reg, bool top)
211
* Generate code for M-profile lazy FP state preservation if needed;
212
* this corresponds to the pseudocode PreserveFPState() function.
213
*/
214
-static void gen_preserve_fp_state(DisasContext *s)
215
+static void gen_preserve_fp_state(DisasContext *s, bool skip_context_update)
216
{
217
if (s->v7m_lspact) {
218
/*
219
@@ -XXX,XX +XXX,XX @@ static void gen_preserve_fp_state(DisasContext *s)
220
* any further FP insns in this TB.
221
*/
222
s->v7m_lspact = false;
223
+ /*
224
+ * The helper might have zeroed VPR, so we do not know the
225
+ * correct value for the MVE_NO_PRED TB flag any more.
226
+ * If we're about to create a new fp context then that
227
+ * will precisely determine the MVE_NO_PRED value (see
228
+ * gen_update_fp_context()). Otherwise, we must:
229
+ * - set s->mve_no_pred to false, so this instruction
230
+ * is generated to use helper functions
231
+ * - end the TB now, without chaining to the next TB
232
+ */
233
+ if (skip_context_update || !s->v7m_new_fp_ctxt_needed) {
234
+ s->mve_no_pred = false;
235
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
236
+ }
237
}
238
}
239
240
@@ -XXX,XX +XXX,XX @@ static void gen_update_fp_context(DisasContext *s)
241
TCGv_i32 z32 = tcg_const_i32(0);
242
store_cpu_field(z32, v7m.vpr);
243
}
244
-
245
/*
246
- * We don't need to arrange to end the TB, because the only
247
- * parts of FPSCR which we cache in the TB flags are the VECLEN
248
- * and VECSTRIDE, and those don't exist for M-profile.
249
+ * We just updated the FPSCR and VPR. Some of this state is cached
250
+ * in the MVE_NO_PRED TB flag. We want to avoid having to end the
251
+ * TB here, which means we need the new value of the MVE_NO_PRED
252
+ * flag to be exactly known here and the same for all executions.
253
+ * Luckily FPDSCR.LTPSIZE is always constant 4 and the VPR is
254
+ * always set to 0, so the new MVE_NO_PRED flag is always 1
255
+ * if and only if we have MVE.
256
+ *
257
+ * (The other FPSCR state cached in TB flags is VECLEN and VECSTRIDE,
258
+ * but those do not exist for M-profile, so are not relevant here.)
259
*/
260
+ s->mve_no_pred = dc_isar_feature(aa32_mve, s);
261
262
if (s->v8m_secure) {
263
bits |= R_V7M_CONTROL_SFPA_MASK;
264
@@ -XXX,XX +XXX,XX @@ bool vfp_access_check_m(DisasContext *s, bool skip_context_update)
265
/* Handle M-profile lazy FP state mechanics */
266
267
/* Trigger lazy-state preservation if necessary */
268
- gen_preserve_fp_state(s);
269
+ gen_preserve_fp_state(s, skip_context_update);
270
271
if (!skip_context_update) {
272
/* Update ownership of FP context and create new FP context if needed */
273
diff --git a/target/arm/translate.c b/target/arm/translate.c
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
274
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
275
--- a/target/arm/translate.c
12
--- a/target/arm/translate.c
276
+++ b/target/arm/translate.c
13
+++ b/target/arm/translate.c
277
@@ -XXX,XX +XXX,XX @@ static bool trans_DLS(DisasContext *s, arg_DLS *a)
14
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
278
/* DLSTP: set FPSCR.LTPSIZE */
15
{
279
tmp = tcg_const_i32(a->size);
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
280
store_cpu_field(tmp, v7m.ltpsize);
17
CPUARMState *env = cpu->env_ptr;
281
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
18
+ uint32_t pc = dc->base.pc_next;
19
unsigned int insn;
20
21
if (arm_pre_translate_insn(dc)) {
22
- dc->base.pc_next += 4;
23
+ dc->base.pc_next = pc + 4;
24
return;
282
}
25
}
283
return true;
26
284
}
27
- dc->pc_curr = dc->base.pc_next;
285
@@ -XXX,XX +XXX,XX @@ static bool trans_WLS(DisasContext *s, arg_WLS *a)
28
- insn = arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
286
assert(ok);
29
+ dc->pc_curr = pc;
287
tmp = tcg_const_i32(a->size);
30
+ insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
288
store_cpu_field(tmp, v7m.ltpsize);
31
dc->insn = insn;
289
+ /*
32
- dc->base.pc_next += 4;
290
+ * LTPSIZE updated, but MVE_NO_PRED will always be the same thing (0)
33
+ dc->base.pc_next = pc + 4;
291
+ * when we take this upcoming exit from this TB, so gen_jmp_tb() is OK.
34
disas_arm_insn(dc, insn);
292
+ */
35
293
}
36
arm_post_translate_insn(dc);
294
gen_jmp_tb(s, s->base.pc_next, 1);
295
296
@@ -XXX,XX +XXX,XX @@ static bool trans_VCTP(DisasContext *s, arg_VCTP *a)
297
gen_helper_mve_vctp(cpu_env, masklen);
298
tcg_temp_free_i32(masklen);
299
tcg_temp_free_i32(rn_shifted);
300
+ /* This insn updates predication bits */
301
+ s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
302
mve_update_eci(s);
303
return true;
304
}
305
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
306
dc->v7m_new_fp_ctxt_needed =
307
EX_TBFLAG_M32(tb_flags, NEW_FP_CTXT_NEEDED);
308
dc->v7m_lspact = EX_TBFLAG_M32(tb_flags, LSPACT);
309
+ dc->mve_no_pred = EX_TBFLAG_M32(tb_flags, MVE_NO_PRED);
310
} else {
311
dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
312
dc->sctlr_b = EX_TBFLAG_A32(tb_flags, SCTLR__B);
313
--
37
--
314
2.20.1
38
2.25.1
315
39
316
40
diff view generated by jsdifflib
1
Currently gen_jmp_tb() assumes that if it is called then the jump it
1
From: Richard Henderson <richard.henderson@linaro.org>
2
is handling is the only reason that we might be trying to end the TB,
3
so it will use goto_tb if it can. This is usually the case: mostly
4
"we did something that means we must end the TB" happens on a
5
non-branch instruction. However, there are cases where we decide
6
early in handling an instruction that we need to end the TB and
7
return to the main loop, and then the insn is a complex one that
8
involves gen_jmp_tb(). For instance, for M-profile FP instructions,
9
in gen_preserve_fp_state() which is called from vfp_access_check() we
10
want to force an exit to the main loop if lazy state preservation is
11
active and we are in icount mode.
12
2
13
Make gen_jmp_tb() look at the current value of is_jmp, and only use
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
goto_tb if the previous is_jmp was DISAS_NEXT or DISAS_TOO_MANY.
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20210913095440.13462-2-peter.maydell@linaro.org
19
---
6
---
20
target/arm/translate.c | 34 +++++++++++++++++++++++++++++++++-
7
target/arm/translate.c | 16 ++++++++--------
21
1 file changed, 33 insertions(+), 1 deletion(-)
8
1 file changed, 8 insertions(+), 8 deletions(-)
22
9
23
diff --git a/target/arm/translate.c b/target/arm/translate.c
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate.c
12
--- a/target/arm/translate.c
26
+++ b/target/arm/translate.c
13
+++ b/target/arm/translate.c
27
@@ -XXX,XX +XXX,XX @@ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
14
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
28
/* An indirect jump so that we still trigger the debug exception. */
15
{
29
gen_set_pc_im(s, dest);
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
30
s->base.is_jmp = DISAS_JUMP;
17
CPUARMState *env = cpu->env_ptr;
31
- } else {
18
+ uint32_t pc = dc->base.pc_next;
32
+ return;
19
uint32_t insn;
33
+ }
20
bool is_16bit;
34
+ switch (s->base.is_jmp) {
21
35
+ case DISAS_NEXT:
22
if (arm_pre_translate_insn(dc)) {
36
+ case DISAS_TOO_MANY:
23
- dc->base.pc_next += 2;
37
+ case DISAS_NORETURN:
24
+ dc->base.pc_next = pc + 2;
38
+ /*
25
return;
39
+ * The normal case: just go to the destination TB.
40
+ * NB: NORETURN happens if we generate code like
41
+ * gen_brcondi(l);
42
+ * gen_jmp();
43
+ * gen_set_label(l);
44
+ * gen_jmp();
45
+ * on the second call to gen_jmp().
46
+ */
47
gen_goto_tb(s, tbno, dest);
48
+ break;
49
+ case DISAS_UPDATE_NOCHAIN:
50
+ case DISAS_UPDATE_EXIT:
51
+ /*
52
+ * We already decided we're leaving the TB for some other reason.
53
+ * Avoid using goto_tb so we really do exit back to the main loop
54
+ * and don't chain to another TB.
55
+ */
56
+ gen_set_pc_im(s, dest);
57
+ gen_goto_ptr();
58
+ s->base.is_jmp = DISAS_NORETURN;
59
+ break;
60
+ default:
61
+ /*
62
+ * We shouldn't be emitting code for a jump and also have
63
+ * is_jmp set to one of the special cases like DISAS_SWI.
64
+ */
65
+ g_assert_not_reached();
66
}
26
}
67
}
27
68
28
- dc->pc_curr = dc->base.pc_next;
29
- insn = arm_lduw_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
30
+ dc->pc_curr = pc;
31
+ insn = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
32
is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
33
- dc->base.pc_next += 2;
34
+ pc += 2;
35
if (!is_16bit) {
36
- uint32_t insn2 = arm_lduw_code(env, &dc->base, dc->base.pc_next,
37
- dc->sctlr_b);
38
-
39
+ uint32_t insn2 = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
40
insn = insn << 16 | insn2;
41
- dc->base.pc_next += 2;
42
+ pc += 2;
43
}
44
+ dc->base.pc_next = pc;
45
dc->insn = insn;
46
47
if (dc->pstate_il) {
69
--
48
--
70
2.20.1
49
2.25.1
71
50
72
51
diff view generated by jsdifflib
1
When not predicating, implement the MVE bitwise logical insns
1
From: Richard Henderson <richard.henderson@linaro.org>
2
directly using TCG vector operations.
3
2
3
Create arm_check_ss_active and arm_check_kernelpage.
4
5
Reverse the order of the tests. While it doesn't matter in practice,
6
because only user-only has a kernel page and user-only never sets
7
ss_active, ss_active has priority over execution exceptions and it
8
is best to keep them in the proper order.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210913095440.13462-5-peter.maydell@linaro.org
8
---
13
---
9
target/arm/translate-mve.c | 51 +++++++++++++++++++++++++++-----------
14
target/arm/translate.c | 10 +++++++---
10
1 file changed, 36 insertions(+), 15 deletions(-)
15
1 file changed, 7 insertions(+), 3 deletions(-)
11
16
12
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-mve.c
19
--- a/target/arm/translate.c
15
+++ b/target/arm/translate-mve.c
20
+++ b/target/arm/translate.c
16
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr mve_qreg_ptr(unsigned reg)
21
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
17
return ret;
22
dc->insn_start = tcg_last_op();
18
}
23
}
19
24
20
+static bool mve_no_predication(DisasContext *s)
25
-static bool arm_pre_translate_insn(DisasContext *dc)
21
+{
26
+static bool arm_check_kernelpage(DisasContext *dc)
22
+ /*
23
+ * Return true if we are executing the entire MVE instruction
24
+ * with no predication or partial-execution, and so we can safely
25
+ * use an inline TCG vector implementation.
26
+ */
27
+ return s->eci == 0 && s->mve_no_pred;
28
+}
29
+
30
static bool mve_check_qreg_bank(DisasContext *s, int qmask)
31
{
27
{
32
/*
28
#ifdef CONFIG_USER_ONLY
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VNEG_fp(DisasContext *s, arg_1op *a)
29
/* Intercept jump to the magic kernel page. */
34
return do_1op(s, a, fns[a->size]);
30
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
35
}
36
37
-static bool do_2op(DisasContext *s, arg_2op *a, MVEGenTwoOpFn fn)
38
+static bool do_2op_vec(DisasContext *s, arg_2op *a, MVEGenTwoOpFn fn,
39
+ GVecGen3Fn *vecfn)
40
{
41
TCGv_ptr qd, qn, qm;
42
43
@@ -XXX,XX +XXX,XX @@ static bool do_2op(DisasContext *s, arg_2op *a, MVEGenTwoOpFn fn)
44
return true;
31
return true;
45
}
32
}
46
33
#endif
47
- qd = mve_qreg_ptr(a->qd);
34
+ return false;
48
- qn = mve_qreg_ptr(a->qn);
35
+}
49
- qm = mve_qreg_ptr(a->qm);
36
50
- fn(cpu_env, qd, qn, qm);
37
+static bool arm_check_ss_active(DisasContext *dc)
51
- tcg_temp_free_ptr(qd);
52
- tcg_temp_free_ptr(qn);
53
- tcg_temp_free_ptr(qm);
54
+ if (vecfn && mve_no_predication(s)) {
55
+ vecfn(a->size, mve_qreg_offset(a->qd), mve_qreg_offset(a->qn),
56
+ mve_qreg_offset(a->qm), 16, 16);
57
+ } else {
58
+ qd = mve_qreg_ptr(a->qd);
59
+ qn = mve_qreg_ptr(a->qn);
60
+ qm = mve_qreg_ptr(a->qm);
61
+ fn(cpu_env, qd, qn, qm);
62
+ tcg_temp_free_ptr(qd);
63
+ tcg_temp_free_ptr(qn);
64
+ tcg_temp_free_ptr(qm);
65
+ }
66
mve_update_eci(s);
67
return true;
68
}
69
70
-#define DO_LOGIC(INSN, HELPER) \
71
+static bool do_2op(DisasContext *s, arg_2op *a, MVEGenTwoOpFn *fn)
72
+{
38
+{
73
+ return do_2op_vec(s, a, fn, NULL);
39
if (dc->ss_active && !dc->pstate_ss) {
74
+}
40
/* Singlestep state is Active-pending.
75
+
41
* If we're in this state at the start of a TB then either
76
+#define DO_LOGIC(INSN, HELPER, VECFN) \
42
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
77
static bool trans_##INSN(DisasContext *s, arg_2op *a) \
43
uint32_t pc = dc->base.pc_next;
78
{ \
44
unsigned int insn;
79
- return do_2op(s, a, HELPER); \
45
80
+ return do_2op_vec(s, a, HELPER, VECFN); \
46
- if (arm_pre_translate_insn(dc)) {
47
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
48
dc->base.pc_next = pc + 4;
49
return;
81
}
50
}
82
51
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
83
-DO_LOGIC(VAND, gen_helper_mve_vand)
52
uint32_t insn;
84
-DO_LOGIC(VBIC, gen_helper_mve_vbic)
53
bool is_16bit;
85
-DO_LOGIC(VORR, gen_helper_mve_vorr)
54
86
-DO_LOGIC(VORN, gen_helper_mve_vorn)
55
- if (arm_pre_translate_insn(dc)) {
87
-DO_LOGIC(VEOR, gen_helper_mve_veor)
56
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
88
+DO_LOGIC(VAND, gen_helper_mve_vand, tcg_gen_gvec_and)
57
dc->base.pc_next = pc + 2;
89
+DO_LOGIC(VBIC, gen_helper_mve_vbic, tcg_gen_gvec_andc)
58
return;
90
+DO_LOGIC(VORR, gen_helper_mve_vorr, tcg_gen_gvec_or)
59
}
91
+DO_LOGIC(VORN, gen_helper_mve_vorn, tcg_gen_gvec_orc)
92
+DO_LOGIC(VEOR, gen_helper_mve_veor, tcg_gen_gvec_xor)
93
94
static bool trans_VPSEL(DisasContext *s, arg_2op *a)
95
{
96
--
60
--
97
2.20.1
61
2.25.1
98
62
99
63
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
During sbsa acs level 3 testing, it is seen that the GIC maintenance
3
The size of the code covered by a TranslationBlock cannot be 0;
4
interrupts are not triggered and the related test cases fail. This
4
this is checked via assert in tb_gen_code.
5
is because we were incorrectly passing the value of the MISR register
6
(from maintenance_interrupt_state()) to qemu_set_irq() as the level
7
argument, whereas the device on the other end of this irq line
8
expects a 0/1 value.
9
5
10
Fix the logic to pass a 0/1 level indication, rather than a
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
0/not-0 value.
12
13
Fixes: c5fc89b36c0 ("hw/intc/arm_gicv3: Implement gicv3_cpuif_virt_update()")
14
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20210915205809.59068-1-shashi.mallela@linaro.org
17
[PMM: tweaked commit message; collapsed nested if()s into one]
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
9
---
21
hw/intc/arm_gicv3_cpuif.c | 5 +++--
10
target/arm/translate-a64.c | 1 +
22
1 file changed, 3 insertions(+), 2 deletions(-)
11
1 file changed, 1 insertion(+)
23
12
24
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/arm_gicv3_cpuif.c
15
--- a/target/arm/translate-a64.c
27
+++ b/hw/intc/arm_gicv3_cpuif.c
16
+++ b/target/arm/translate-a64.c
28
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
29
}
18
assert(s->base.num_insns == 1);
19
gen_swstep_exception(s, 0, 0);
20
s->base.is_jmp = DISAS_NORETURN;
21
+ s->base.pc_next = pc + 4;
22
return;
30
}
23
}
31
24
32
- if (cs->ich_hcr_el2 & ICH_HCR_EL2_EN) {
33
- maintlevel = maintenance_interrupt_state(cs);
34
+ if ((cs->ich_hcr_el2 & ICH_HCR_EL2_EN) &&
35
+ maintenance_interrupt_state(cs) != 0) {
36
+ maintlevel = 1;
37
}
38
39
trace_gicv3_cpuif_virt_set_irqs(gicv3_redist_affid(cs), fiqlevel,
40
--
25
--
41
2.20.1
26
2.25.1
42
27
43
28
diff view generated by jsdifflib
1
Optimize the MVE VNEG and VABS insns by using TCG
1
From: Richard Henderson <richard.henderson@linaro.org>
2
vector ops when possible.
3
2
3
We will reuse this section of arm_deliver_fault for
4
raising pc alignment faults.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210913095440.13462-7-peter.maydell@linaro.org
8
---
9
---
9
target/arm/translate-mve.c | 32 ++++++++++++++++++++++----------
10
target/arm/tlb_helper.c | 45 +++++++++++++++++++++++++----------------
10
1 file changed, 22 insertions(+), 10 deletions(-)
11
1 file changed, 28 insertions(+), 17 deletions(-)
11
12
12
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
13
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-mve.c
15
--- a/target/arm/tlb_helper.c
15
+++ b/target/arm/translate-mve.c
16
+++ b/target/arm/tlb_helper.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
17
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
17
return true;
18
return syn;
18
}
19
}
19
20
20
-static bool do_1op(DisasContext *s, arg_1op *a, MVEGenOneOpFn fn)
21
-static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
21
+static bool do_1op_vec(DisasContext *s, arg_1op *a, MVEGenOneOpFn fn,
22
- MMUAccessType access_type,
22
+ GVecGen2Fn vecfn)
23
- int mmu_idx, ARMMMUFaultInfo *fi)
24
+static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
25
+ int target_el, int mmu_idx, uint32_t *ret_fsc)
23
{
26
{
24
TCGv_ptr qd, qm;
27
- CPUARMState *env = &cpu->env;
25
28
- int target_el;
26
@@ -XXX,XX +XXX,XX @@ static bool do_1op(DisasContext *s, arg_1op *a, MVEGenOneOpFn fn)
29
- bool same_el;
27
return true;
30
- uint32_t syn, exc, fsr, fsc;
31
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
32
-
33
- target_el = exception_target_el(env);
34
- if (fi->stage2) {
35
- target_el = 2;
36
- env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
37
- if (arm_is_secure_below_el3(env) && fi->s1ns) {
38
- env->cp15.hpfar_el2 |= HPFAR_NS;
39
- }
40
- }
41
- same_el = (arm_current_el(env) == target_el);
42
+ uint32_t fsr, fsc;
43
44
if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
45
arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
46
@@ -XXX,XX +XXX,XX @@ static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
47
fsc = 0x3f;
28
}
48
}
29
49
30
- qd = mve_qreg_ptr(a->qd);
50
+ *ret_fsc = fsc;
31
- qm = mve_qreg_ptr(a->qm);
51
+ return fsr;
32
- fn(cpu_env, qd, qm);
33
- tcg_temp_free_ptr(qd);
34
- tcg_temp_free_ptr(qm);
35
+ if (vecfn && mve_no_predication(s)) {
36
+ vecfn(a->size, mve_qreg_offset(a->qd), mve_qreg_offset(a->qm), 16, 16);
37
+ } else {
38
+ qd = mve_qreg_ptr(a->qd);
39
+ qm = mve_qreg_ptr(a->qm);
40
+ fn(cpu_env, qd, qm);
41
+ tcg_temp_free_ptr(qd);
42
+ tcg_temp_free_ptr(qm);
43
+ }
44
mve_update_eci(s);
45
return true;
46
}
47
48
-#define DO_1OP(INSN, FN) \
49
+static bool do_1op(DisasContext *s, arg_1op *a, MVEGenOneOpFn fn)
50
+{
51
+ return do_1op_vec(s, a, fn, NULL);
52
+}
52
+}
53
+
53
+
54
+#define DO_1OP_VEC(INSN, FN, VECFN) \
54
+static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
55
static bool trans_##INSN(DisasContext *s, arg_1op *a) \
55
+ MMUAccessType access_type,
56
{ \
56
+ int mmu_idx, ARMMMUFaultInfo *fi)
57
static MVEGenOneOpFn * const fns[] = { \
57
+{
58
@@ -XXX,XX +XXX,XX @@ static bool do_1op(DisasContext *s, arg_1op *a, MVEGenOneOpFn fn)
58
+ CPUARMState *env = &cpu->env;
59
gen_helper_mve_##FN##w, \
59
+ int target_el;
60
NULL, \
60
+ bool same_el;
61
}; \
61
+ uint32_t syn, exc, fsr, fsc;
62
- return do_1op(s, a, fns[a->size]); \
63
+ return do_1op_vec(s, a, fns[a->size], VECFN); \
64
}
65
66
+#define DO_1OP(INSN, FN) DO_1OP_VEC(INSN, FN, NULL)
67
+
62
+
68
DO_1OP(VCLZ, vclz)
63
+ target_el = exception_target_el(env);
69
DO_1OP(VCLS, vcls)
64
+ if (fi->stage2) {
70
-DO_1OP(VABS, vabs)
65
+ target_el = 2;
71
-DO_1OP(VNEG, vneg)
66
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
72
+DO_1OP_VEC(VABS, vabs, tcg_gen_gvec_abs)
67
+ if (arm_is_secure_below_el3(env) && fi->s1ns) {
73
+DO_1OP_VEC(VNEG, vneg, tcg_gen_gvec_neg)
68
+ env->cp15.hpfar_el2 |= HPFAR_NS;
74
DO_1OP(VQABS, vqabs)
69
+ }
75
DO_1OP(VQNEG, vqneg)
70
+ }
76
DO_1OP(VMAXA, vmaxa)
71
+ same_el = (arm_current_el(env) == target_el);
72
+
73
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
74
+
75
if (access_type == MMU_INST_FETCH) {
76
syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
77
exc = EXCP_PREFETCH_ABORT;
77
--
78
--
78
2.20.1
79
2.25.1
79
80
80
81
diff view generated by jsdifflib
1
From: Peter Collingbourne <pcc@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Sleep on WFI until the VTIMER is due but allow ourselves to be woken
3
For A64, any input to an indirect branch can cause this.
4
up on IPI.
4
5
5
For A32, many indirect branch paths force the branch to be aligned,
6
In this implementation IPI is blocked on the CPU thread at startup and
6
but BXWritePC does not. This includes the BX instruction but also
7
pselect() is used to atomically unblock the signal and begin sleeping.
7
other interworking changes to PC. Prior to v8, this case is UNDEFINED.
8
The signal is sent unconditionally so there's no need to worry about
8
With v8, this is CONSTRAINED UNPREDICTABLE and may either raise an
9
races between actually sleeping and the "we think we're sleeping"
9
exception or force align the PC.
10
state. It may lead to an extra wakeup but that's better than missing
10
11
it entirely.
11
We choose to raise an exception because we have the infrastructure,
12
12
it makes the generated code for gen_bx simpler, and it has the
13
Signed-off-by: Peter Collingbourne <pcc@google.com>
13
possibility of catching more guest bugs.
14
Signed-off-by: Alexander Graf <agraf@csgraf.de>
14
15
Acked-by: Roman Bolshakov <r.bolshakov@yadro.com>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Sergio Lopez <slp@redhat.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20210916155404.86958-6-agraf@csgraf.de
18
[agraf: Remove unused 'set' variable, always advance PC on WFX trap,
19
support vm stop / continue operations and cntv offsets]
20
Signed-off-by: Alexander Graf <agraf@csgraf.de>
21
Acked-by: Roman Bolshakov <r.bolshakov@yadro.com>
22
Reviewed-by: Sergio Lopez <slp@redhat.com>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
18
---
25
include/sysemu/hvf_int.h | 1 +
19
target/arm/helper.h | 1 +
26
accel/hvf/hvf-accel-ops.c | 5 +--
20
target/arm/syndrome.h | 5 ++++
27
target/arm/hvf/hvf.c | 79 +++++++++++++++++++++++++++++++++++++++
21
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++++++---------------
28
3 files changed, 82 insertions(+), 3 deletions(-)
22
target/arm/tlb_helper.c | 18 ++++++++++++++
29
23
target/arm/translate-a64.c | 15 ++++++++++++
30
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
24
target/arm/translate.c | 22 ++++++++++++++++-
31
index XXXXXXX..XXXXXXX 100644
25
6 files changed, 87 insertions(+), 20 deletions(-)
32
--- a/include/sysemu/hvf_int.h
26
33
+++ b/include/sysemu/hvf_int.h
27
diff --git a/target/arm/helper.h b/target/arm/helper.h
34
@@ -XXX,XX +XXX,XX @@ struct hvf_vcpu_state {
28
index XXXXXXX..XXXXXXX 100644
35
uint64_t fd;
29
--- a/target/arm/helper.h
36
void *exit;
30
+++ b/target/arm/helper.h
37
bool vtimer_masked;
31
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
38
+ sigset_t unblock_ipi_mask;
32
DEF_HELPER_2(exception_internal, void, env, i32)
39
};
33
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
40
34
DEF_HELPER_2(exception_bkpt_insn, void, env, i32)
41
void assert_hvf_ok(hv_return_t ret);
35
+DEF_HELPER_2(exception_pc_alignment, noreturn, env, tl)
42
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
36
DEF_HELPER_1(setend, void, env)
43
index XXXXXXX..XXXXXXX 100644
37
DEF_HELPER_2(wfi, void, env, i32)
44
--- a/accel/hvf/hvf-accel-ops.c
38
DEF_HELPER_1(wfe, void, env)
45
+++ b/accel/hvf/hvf-accel-ops.c
39
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
46
@@ -XXX,XX +XXX,XX @@ static int hvf_init_vcpu(CPUState *cpu)
40
index XXXXXXX..XXXXXXX 100644
47
cpu->hvf = g_malloc0(sizeof(*cpu->hvf));
41
--- a/target/arm/syndrome.h
48
42
+++ b/target/arm/syndrome.h
49
/* init cpu signals */
43
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_illegalstate(void)
50
- sigset_t set;
44
return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
51
struct sigaction sigact;
45
}
52
46
53
memset(&sigact, 0, sizeof(sigact));
47
+static inline uint32_t syn_pcalignment(void)
54
sigact.sa_handler = dummy_signal;
48
+{
55
sigaction(SIG_IPI, &sigact, NULL);
49
+ return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
56
50
+}
57
- pthread_sigmask(SIG_BLOCK, NULL, &set);
51
+
58
- sigdelset(&set, SIG_IPI);
52
#endif /* TARGET_ARM_SYNDROME_H */
59
+ pthread_sigmask(SIG_BLOCK, NULL, &cpu->hvf->unblock_ipi_mask);
53
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
60
+ sigdelset(&cpu->hvf->unblock_ipi_mask, SIG_IPI);
54
index XXXXXXX..XXXXXXX 100644
61
55
--- a/linux-user/aarch64/cpu_loop.c
62
#ifdef __aarch64__
56
+++ b/linux-user/aarch64/cpu_loop.c
63
r = hv_vcpu_create(&cpu->hvf->fd, (hv_vcpu_exit_t **)&cpu->hvf->exit, NULL);
57
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
64
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
58
break;
65
index XXXXXXX..XXXXXXX 100644
59
case EXCP_PREFETCH_ABORT:
66
--- a/target/arm/hvf/hvf.c
60
case EXCP_DATA_ABORT:
67
+++ b/target/arm/hvf/hvf.c
61
- /* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
62
ec = syn_get_ec(env->exception.syndrome);
63
- assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
64
-
65
- /* Both EC have the same format for FSC, or close enough. */
66
- fsc = extract32(env->exception.syndrome, 0, 6);
67
- switch (fsc) {
68
- case 0x04 ... 0x07: /* Translation fault, level {0-3} */
69
- si_signo = TARGET_SIGSEGV;
70
- si_code = TARGET_SEGV_MAPERR;
71
+ switch (ec) {
72
+ case EC_DATAABORT:
73
+ case EC_INSNABORT:
74
+ /* Both EC have the same format for FSC, or close enough. */
75
+ fsc = extract32(env->exception.syndrome, 0, 6);
76
+ switch (fsc) {
77
+ case 0x04 ... 0x07: /* Translation fault, level {0-3} */
78
+ si_signo = TARGET_SIGSEGV;
79
+ si_code = TARGET_SEGV_MAPERR;
80
+ break;
81
+ case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
82
+ case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
83
+ si_signo = TARGET_SIGSEGV;
84
+ si_code = TARGET_SEGV_ACCERR;
85
+ break;
86
+ case 0x11: /* Synchronous Tag Check Fault */
87
+ si_signo = TARGET_SIGSEGV;
88
+ si_code = TARGET_SEGV_MTESERR;
89
+ break;
90
+ case 0x21: /* Alignment fault */
91
+ si_signo = TARGET_SIGBUS;
92
+ si_code = TARGET_BUS_ADRALN;
93
+ break;
94
+ default:
95
+ g_assert_not_reached();
96
+ }
97
break;
98
- case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
99
- case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
100
- si_signo = TARGET_SIGSEGV;
101
- si_code = TARGET_SEGV_ACCERR;
102
- break;
103
- case 0x11: /* Synchronous Tag Check Fault */
104
- si_signo = TARGET_SIGSEGV;
105
- si_code = TARGET_SEGV_MTESERR;
106
- break;
107
- case 0x21: /* Alignment fault */
108
+ case EC_PCALIGNMENT:
109
si_signo = TARGET_SIGBUS;
110
si_code = TARGET_BUS_ADRALN;
111
break;
112
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/tlb_helper.c
115
+++ b/target/arm/tlb_helper.c
68
@@ -XXX,XX +XXX,XX @@
116
@@ -XXX,XX +XXX,XX @@
69
* QEMU Hypervisor.framework support for Apple Silicon
117
#include "cpu.h"
70
118
#include "internals.h"
71
* Copyright 2020 Alexander Graf <agraf@csgraf.de>
119
#include "exec/exec-all.h"
72
+ * Copyright 2020 Google LLC
120
+#include "exec/helper-proto.h"
73
*
121
74
* This work is licensed under the terms of the GNU GPL, version 2 or later.
122
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
75
* See the COPYING file in the top-level directory.
123
unsigned int target_el,
76
@@ -XXX,XX +XXX,XX @@ int hvf_arch_init_vcpu(CPUState *cpu)
124
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
77
125
arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
78
void hvf_kick_vcpu_thread(CPUState *cpu)
79
{
80
+ cpus_kick_thread(cpu);
81
hv_vcpus_exit(&cpu->hvf->fd, 1);
82
}
126
}
83
127
84
@@ -XXX,XX +XXX,XX @@ static uint64_t hvf_vtimer_val_raw(void)
128
+void helper_exception_pc_alignment(CPUARMState *env, target_ulong pc)
85
return mach_absolute_time() - hvf_state->vtimer_offset;
86
}
87
88
+static uint64_t hvf_vtimer_val(void)
89
+{
129
+{
90
+ if (!runstate_is_running()) {
130
+ ARMMMUFaultInfo fi = { .type = ARMFault_Alignment };
91
+ /* VM is paused, the vtimer value is in vtimer.vtimer_val */
131
+ int target_el = exception_target_el(env);
92
+ return vtimer.vtimer_val;
132
+ int mmu_idx = cpu_mmu_index(env, true);
93
+ }
133
+ uint32_t fsc;
94
+
134
+
95
+ return hvf_vtimer_val_raw();
135
+ env->exception.vaddress = pc;
136
+
137
+ /*
138
+ * Note that the fsc is not applicable to this exception,
139
+ * since any syndrome is pcalignment not insn_abort.
140
+ */
141
+ env->exception.fsr = compute_fsr_fsc(env, &fi, target_el, mmu_idx, &fsc);
142
+ raise_exception(env, EXCP_PREFETCH_ABORT, syn_pcalignment(), target_el);
96
+}
143
+}
97
+
144
+
98
+static void hvf_wait_for_ipi(CPUState *cpu, struct timespec *ts)
145
#if !defined(CONFIG_USER_ONLY)
99
+{
146
100
+ /*
147
/*
101
+ * Use pselect to sleep so that other threads can IPI us while we're
148
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
102
+ * sleeping.
149
index XXXXXXX..XXXXXXX 100644
103
+ */
150
--- a/target/arm/translate-a64.c
104
+ qatomic_mb_set(&cpu->thread_kicked, false);
151
+++ b/target/arm/translate-a64.c
105
+ qemu_mutex_unlock_iothread();
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
106
+ pselect(0, 0, 0, 0, ts, &cpu->hvf->unblock_ipi_mask);
153
uint64_t pc = s->base.pc_next;
107
+ qemu_mutex_lock_iothread();
154
uint32_t insn;
108
+}
155
109
+
156
+ /* Singlestep exceptions have the highest priority. */
110
+static void hvf_wfi(CPUState *cpu)
157
if (s->ss_active && !s->pstate_ss) {
111
+{
158
/* Singlestep state is Active-pending.
112
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
159
* If we're in this state at the start of a TB then either
113
+ struct timespec ts;
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
114
+ hv_return_t r;
161
return;
115
+ uint64_t ctl;
162
}
116
+ uint64_t cval;
163
117
+ int64_t ticks_to_sleep;
164
+ if (pc & 3) {
118
+ uint64_t seconds;
165
+ /*
119
+ uint64_t nanos;
166
+ * PC alignment fault. This has priority over the instruction abort
120
+ uint32_t cntfrq;
167
+ * that we would receive from a translation fault via arm_ldl_code.
121
+
168
+ * This should only be possible after an indirect branch, at the
122
+ if (cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIQ)) {
169
+ * start of the TB.
123
+ /* Interrupt pending, no need to wait */
170
+ */
171
+ assert(s->base.num_insns == 1);
172
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
173
+ s->base.is_jmp = DISAS_NORETURN;
174
+ s->base.pc_next = QEMU_ALIGN_UP(pc, 4);
124
+ return;
175
+ return;
125
+ }
176
+ }
126
+
177
+
127
+ r = hv_vcpu_get_sys_reg(cpu->hvf->fd, HV_SYS_REG_CNTV_CTL_EL0, &ctl);
178
s->pc_curr = pc;
128
+ assert_hvf_ok(r);
179
insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
129
+
180
s->insn = insn;
130
+ if (!(ctl & 1) || (ctl & 2)) {
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
131
+ /* Timer disabled or masked, just wait for an IPI. */
182
index XXXXXXX..XXXXXXX 100644
132
+ hvf_wait_for_ipi(cpu, NULL);
183
--- a/target/arm/translate.c
184
+++ b/target/arm/translate.c
185
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
186
uint32_t pc = dc->base.pc_next;
187
unsigned int insn;
188
189
- if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
190
+ /* Singlestep exceptions have the highest priority. */
191
+ if (arm_check_ss_active(dc)) {
192
+ dc->base.pc_next = pc + 4;
133
+ return;
193
+ return;
134
+ }
194
+ }
135
+
195
+
136
+ r = hv_vcpu_get_sys_reg(cpu->hvf->fd, HV_SYS_REG_CNTV_CVAL_EL0, &cval);
196
+ if (pc & 3) {
137
+ assert_hvf_ok(r);
197
+ /*
138
+
198
+ * PC alignment fault. This has priority over the instruction abort
139
+ ticks_to_sleep = cval - hvf_vtimer_val();
199
+ * that we would receive from a translation fault via arm_ldl_code
140
+ if (ticks_to_sleep < 0) {
200
+ * (or the execution of the kernelpage entrypoint). This should only
201
+ * be possible after an indirect branch, at the start of the TB.
202
+ */
203
+ assert(dc->base.num_insns == 1);
204
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
205
+ dc->base.is_jmp = DISAS_NORETURN;
206
+ dc->base.pc_next = QEMU_ALIGN_UP(pc, 4);
141
+ return;
207
+ return;
142
+ }
208
+ }
143
+
209
+
144
+ cntfrq = gt_cntfrq_period_ns(arm_cpu);
210
+ if (arm_check_kernelpage(dc)) {
145
+ seconds = muldiv64(ticks_to_sleep, cntfrq, NANOSECONDS_PER_SECOND);
211
dc->base.pc_next = pc + 4;
146
+ ticks_to_sleep -= muldiv64(seconds, NANOSECONDS_PER_SECOND, cntfrq);
212
return;
147
+ nanos = ticks_to_sleep * cntfrq;
148
+
149
+ /*
150
+ * Don't sleep for less than the time a context switch would take,
151
+ * so that we can satisfy fast timer requests on the same CPU.
152
+ * Measurements on M1 show the sweet spot to be ~2ms.
153
+ */
154
+ if (!seconds && nanos < (2 * SCALE_MS)) {
155
+ return;
156
+ }
157
+
158
+ ts = (struct timespec) { seconds, nanos };
159
+ hvf_wait_for_ipi(cpu, &ts);
160
+}
161
+
162
static void hvf_sync_vtimer(CPUState *cpu)
163
{
164
ARMCPU *arm_cpu = ARM_CPU(cpu);
165
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
166
}
213
}
167
case EC_WFX_TRAP:
168
advance_pc = true;
169
+ if (!(syndrome & WFX_IS_WFE)) {
170
+ hvf_wfi(cpu);
171
+ }
172
break;
173
case EC_AA64_HVC:
174
cpu_synchronize_state(cpu);
175
--
214
--
176
2.20.1
215
2.25.1
177
216
178
217
diff view generated by jsdifflib
1
Architecturally, for an M-profile CPU with the LOB feature the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
LTPSIZE field in FPDSCR is always constant 4. QEMU's implementation
3
enforces this everywhere, except that we don't check that it is true
4
in incoming migration data.
5
2
6
We're going to add come in gen_update_fp_context() which relies on
3
Misaligned thumb PC is architecturally impossible.
7
the "always 4" property. Since this is TCG-only, we don't actually
4
Assert is better than proceeding, in case we've missed
8
need to be robust to bogus incoming migration data, and the effect of
5
something somewhere.
9
it being wrong would be wrong code generation rather than a QEMU
10
crash; but if it did ever happen somehow it would be very difficult
11
to track down the cause. Add a check so that we fail the inbound
12
migration if the FPDSCR.LTPSIZE value is incorrect.
13
6
7
Expand a comment about aligning the pc in gdbstub.
8
Fail an incoming migrate if a thumb pc is misaligned.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210913095440.13462-3-peter.maydell@linaro.org
17
---
13
---
18
target/arm/machine.c | 13 +++++++++++++
14
target/arm/gdbstub.c | 9 +++++++--
19
1 file changed, 13 insertions(+)
15
target/arm/machine.c | 10 ++++++++++
16
target/arm/translate.c | 3 +++
17
3 files changed, 20 insertions(+), 2 deletions(-)
20
18
19
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/gdbstub.c
22
+++ b/target/arm/gdbstub.c
23
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
24
25
tmp = ldl_p(mem_buf);
26
27
- /* Mask out low bit of PC to workaround gdb bugs. This will probably
28
- cause problems if we ever implement the Jazelle DBX extensions. */
29
+ /*
30
+ * Mask out low bits of PC to workaround gdb bugs.
31
+ * This avoids an assert in thumb_tr_translate_insn, because it is
32
+ * architecturally impossible to misalign the pc.
33
+ * This will probably cause problems if we ever implement the
34
+ * Jazelle DBX extensions.
35
+ */
36
if (n == 15) {
37
tmp &= ~1;
38
}
21
diff --git a/target/arm/machine.c b/target/arm/machine.c
39
diff --git a/target/arm/machine.c b/target/arm/machine.c
22
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/machine.c
41
--- a/target/arm/machine.c
24
+++ b/target/arm/machine.c
42
+++ b/target/arm/machine.c
25
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
43
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
26
hw_breakpoint_update_all(cpu);
44
return -1;
27
hw_watchpoint_update_all(cpu);
45
}
28
46
}
47
+
29
+ /*
48
+ /*
30
+ * TCG gen_update_fp_context() relies on the invariant that
49
+ * Misaligned thumb pc is architecturally impossible.
31
+ * FPDSCR.LTPSIZE is constant 4 for M-profile with the LOB extension;
50
+ * We have an assert in thumb_tr_translate_insn to verify this.
32
+ * forbid bogus incoming data with some other value.
51
+ * Fail an incoming migrate to avoid this assert.
33
+ */
52
+ */
34
+ if (arm_feature(env, ARM_FEATURE_M) && cpu_isar_feature(aa32_lob, cpu)) {
53
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
35
+ if (extract32(env->v7m.fpdscr[M_REG_NS],
54
+ return -1;
36
+ FPCR_LTPSIZE_SHIFT, FPCR_LTPSIZE_LENGTH) != 4 ||
37
+ extract32(env->v7m.fpdscr[M_REG_S],
38
+ FPCR_LTPSIZE_SHIFT, FPCR_LTPSIZE_LENGTH) != 4) {
39
+ return -1;
40
+ }
41
+ }
55
+ }
56
+
42
if (!kvm_enabled()) {
57
if (!kvm_enabled()) {
43
pmu_op_finish(&cpu->env);
58
pmu_op_finish(&cpu->env);
44
}
59
}
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
65
uint32_t insn;
66
bool is_16bit;
67
68
+ /* Misaligned thumb PC is architecturally impossible. */
69
+ assert((dc->base.pc_next & 1) == 0);
70
+
71
if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
72
dc->base.pc_next = pc + 2;
73
return;
45
--
74
--
46
2.20.1
75
2.25.1
47
76
48
77
diff view generated by jsdifflib
1
Now that we have working system register sync, we push more target CPU
1
From: Richard Henderson <richard.henderson@linaro.org>
2
properties into the virtual machine. That might be useful in some
3
situations, but is not the typical case that users want.
4
2
5
So let's add a -cpu host option that allows them to explicitly pass all
3
Both single-step and pc alignment faults have priority over
6
CPU capabilities of their host CPU into the guest.
4
breakpoint exceptions.
7
5
8
Signed-off-by: Alexander Graf <agraf@csgraf.de>
9
Acked-by: Roman Bolshakov <r.bolshakov@yadro.com>
10
Reviewed-by: Sergio Lopez <slp@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20210916155404.86958-7-agraf@csgraf.de
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
[PMM: drop unnecessary #include line from .h file]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
target/arm/cpu.h | 2 +
10
target/arm/debug_helper.c | 23 +++++++++++++++++++++++
17
target/arm/hvf_arm.h | 18 +++++++++
11
1 file changed, 23 insertions(+)
18
target/arm/kvm_arm.h | 2 -
19
target/arm/cpu.c | 13 ++++--
20
target/arm/hvf/hvf.c | 95 ++++++++++++++++++++++++++++++++++++++++++++
21
5 files changed, 124 insertions(+), 6 deletions(-)
22
create mode 100644 target/arm/hvf_arm.h
23
12
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.h
15
--- a/target/arm/debug_helper.c
27
+++ b/target/arm/cpu.h
16
+++ b/target/arm/debug_helper.c
28
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
17
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
29
#define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX)
30
#define CPU_RESOLVING_TYPE TYPE_ARM_CPU
31
32
+#define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU
33
+
34
#define cpu_signal_handler cpu_arm_signal_handler
35
#define cpu_list arm_cpu_list
36
37
diff --git a/target/arm/hvf_arm.h b/target/arm/hvf_arm.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/target/arm/hvf_arm.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * QEMU Hypervisor.framework (HVF) support -- ARM specifics
45
+ *
46
+ * Copyright (c) 2021 Alexander Graf
47
+ *
48
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
49
+ * See the COPYING file in the top-level directory.
50
+ *
51
+ */
52
+
53
+#ifndef QEMU_HVF_ARM_H
54
+#define QEMU_HVF_ARM_H
55
+
56
+#include "cpu.h"
57
+
58
+void hvf_arm_set_cpu_features_from_host(struct ARMCPU *cpu);
59
+
60
+#endif
61
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/kvm_arm.h
64
+++ b/target/arm/kvm_arm.h
65
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
66
*/
67
void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
68
69
-#define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU
70
-
71
/**
72
* ARMHostCPUFeatures: information about the host CPU (identified
73
* by asking the host kernel)
74
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/cpu.c
77
+++ b/target/arm/cpu.c
78
@@ -XXX,XX +XXX,XX @@
79
#include "sysemu/tcg.h"
80
#include "sysemu/hw_accel.h"
81
#include "kvm_arm.h"
82
+#include "hvf_arm.h"
83
#include "disas/capstone.h"
84
#include "fpu/softfloat.h"
85
86
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
87
* this is the first point where we can report it.
88
*/
89
if (cpu->host_cpu_probe_failed) {
90
- if (!kvm_enabled()) {
91
- error_setg(errp, "The 'host' CPU type can only be used with KVM");
92
+ if (!kvm_enabled() && !hvf_enabled()) {
93
+ error_setg(errp, "The 'host' CPU type can only be used with KVM or HVF");
94
} else {
95
error_setg(errp, "Failed to retrieve host CPU features");
96
}
97
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
98
#endif /* CONFIG_TCG */
99
}
100
101
-#ifdef CONFIG_KVM
102
+#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
103
static void arm_host_initfn(Object *obj)
104
{
18
{
105
ARMCPU *cpu = ARM_CPU(obj);
19
ARMCPU *cpu = ARM_CPU(cs);
106
20
CPUARMState *env = &cpu->env;
107
+#ifdef CONFIG_KVM
21
+ target_ulong pc;
108
kvm_arm_set_cpu_features_from_host(cpu);
22
int n;
109
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
23
110
aarch64_add_sve_properties(obj);
24
/*
25
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
26
return false;
111
}
27
}
112
+#else
28
113
+ hvf_arm_set_cpu_features_from_host(cpu);
29
+ /*
114
+#endif
30
+ * Single-step exceptions have priority over breakpoint exceptions.
115
arm_cpu_post_init(obj);
31
+ * If single-step state is active-pending, suppress the bp.
116
}
32
+ */
117
33
+ if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
118
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
119
{
120
type_register_static(&arm_cpu_type_info);
121
122
-#ifdef CONFIG_KVM
123
+#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
124
type_register_static(&host_arm_cpu_type_info);
125
#endif
126
}
127
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
128
index XXXXXXX..XXXXXXX 100644
129
--- a/target/arm/hvf/hvf.c
130
+++ b/target/arm/hvf/hvf.c
131
@@ -XXX,XX +XXX,XX @@
132
#include "sysemu/hvf.h"
133
#include "sysemu/hvf_int.h"
134
#include "sysemu/hw_accel.h"
135
+#include "hvf_arm.h"
136
137
#include <mach/mach_time.h>
138
139
@@ -XXX,XX +XXX,XX @@ typedef struct HVFVTimer {
140
141
static HVFVTimer vtimer;
142
143
+typedef struct ARMHostCPUFeatures {
144
+ ARMISARegisters isar;
145
+ uint64_t features;
146
+ uint64_t midr;
147
+ uint32_t reset_sctlr;
148
+ const char *dtb_compatible;
149
+} ARMHostCPUFeatures;
150
+
151
+static ARMHostCPUFeatures arm_host_cpu_features;
152
+
153
struct hvf_reg_match {
154
int reg;
155
uint64_t offset;
156
@@ -XXX,XX +XXX,XX @@ static uint64_t hvf_get_reg(CPUState *cpu, int rt)
157
return val;
158
}
159
160
+static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
161
+{
162
+ ARMISARegisters host_isar = {};
163
+ const struct isar_regs {
164
+ int reg;
165
+ uint64_t *val;
166
+ } regs[] = {
167
+ { HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.id_aa64pfr0 },
168
+ { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.id_aa64pfr1 },
169
+ { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.id_aa64dfr0 },
170
+ { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.id_aa64dfr1 },
171
+ { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.id_aa64isar0 },
172
+ { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.id_aa64isar1 },
173
+ { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 },
174
+ { HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 },
175
+ { HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.id_aa64mmfr2 },
176
+ };
177
+ hv_vcpu_t fd;
178
+ hv_return_t r = HV_SUCCESS;
179
+ hv_vcpu_exit_t *exit;
180
+ int i;
181
+
182
+ ahcf->dtb_compatible = "arm,arm-v8";
183
+ ahcf->features = (1ULL << ARM_FEATURE_V8) |
184
+ (1ULL << ARM_FEATURE_NEON) |
185
+ (1ULL << ARM_FEATURE_AARCH64) |
186
+ (1ULL << ARM_FEATURE_PMU) |
187
+ (1ULL << ARM_FEATURE_GENERIC_TIMER);
188
+
189
+ /* We set up a small vcpu to extract host registers */
190
+
191
+ if (hv_vcpu_create(&fd, &exit, NULL) != HV_SUCCESS) {
192
+ return false;
34
+ return false;
193
+ }
35
+ }
194
+
36
+
195
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
196
+ r |= hv_vcpu_get_sys_reg(fd, regs[i].reg, regs[i].val);
197
+ }
198
+ r |= hv_vcpu_get_sys_reg(fd, HV_SYS_REG_MIDR_EL1, &ahcf->midr);
199
+ r |= hv_vcpu_destroy(fd);
200
+
201
+ ahcf->isar = host_isar;
202
+
203
+ /*
37
+ /*
204
+ * A scratch vCPU returns SCTLR 0, so let's fill our default with the M1
38
+ * PC alignment faults have priority over breakpoint exceptions.
205
+ * boot SCTLR from https://github.com/AsahiLinux/m1n1/issues/97
206
+ */
39
+ */
207
+ ahcf->reset_sctlr = 0x30100180;
40
+ pc = is_a64(env) ? env->pc : env->regs[15];
208
+ /*
41
+ if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
209
+ * SPAN is disabled by default when SCTLR.SPAN=1. To improve compatibility,
210
+ * let's disable it on boot and then allow guest software to turn it on by
211
+ * setting it to 0.
212
+ */
213
+ ahcf->reset_sctlr |= 0x00800000;
214
+
215
+ /* Make sure we don't advertise AArch32 support for EL0/EL1 */
216
+ if ((host_isar.id_aa64pfr0 & 0xff) != 0x11) {
217
+ return false;
42
+ return false;
218
+ }
43
+ }
219
+
44
+
220
+ return r == HV_SUCCESS;
45
+ /*
221
+}
46
+ * Instruction aborts have priority over breakpoint exceptions.
47
+ * TODO: We would need to look up the page for PC and verify that
48
+ * it is present and executable.
49
+ */
222
+
50
+
223
+void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu)
51
for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
224
+{
52
if (bp_wp_matches(cpu, n, false)) {
225
+ if (!arm_host_cpu_features.dtb_compatible) {
53
return true;
226
+ if (!hvf_enabled() ||
227
+ !hvf_arm_get_host_cpu_features(&arm_host_cpu_features)) {
228
+ /*
229
+ * We can't report this error yet, so flag that we need to
230
+ * in arm_cpu_realizefn().
231
+ */
232
+ cpu->host_cpu_probe_failed = true;
233
+ return;
234
+ }
235
+ }
236
+
237
+ cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
238
+ cpu->isar = arm_host_cpu_features.isar;
239
+ cpu->env.features = arm_host_cpu_features.features;
240
+ cpu->midr = arm_host_cpu_features.midr;
241
+ cpu->reset_sctlr = arm_host_cpu_features.reset_sctlr;
242
+}
243
+
244
void hvf_arch_vcpu_destroy(CPUState *cpu)
245
{
246
}
247
--
54
--
248
2.20.1
55
2.25.1
249
56
250
57
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We can expose cycle counters on the PMU easily. To be as compatible as
4
possible, let's do so, but make sure we don't expose any other architectural
5
counters that we can not model yet.
6
7
This allows OSs to work that require PMU support.
8
9
Signed-off-by: Alexander Graf <agraf@csgraf.de>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20210916155404.86958-10-agraf@csgraf.de
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
6
---
14
target/arm/hvf/hvf.c | 179 +++++++++++++++++++++++++++++++++++++++++++
7
tests/tcg/aarch64/pcalign-a64.c | 37 +++++++++++++++++++++++++
15
1 file changed, 179 insertions(+)
8
tests/tcg/arm/pcalign-a32.c | 46 +++++++++++++++++++++++++++++++
9
tests/tcg/aarch64/Makefile.target | 4 +--
10
tests/tcg/arm/Makefile.target | 4 +++
11
4 files changed, 89 insertions(+), 2 deletions(-)
12
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
13
create mode 100644 tests/tcg/arm/pcalign-a32.c
16
14
17
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
15
diff --git a/tests/tcg/aarch64/pcalign-a64.c b/tests/tcg/aarch64/pcalign-a64.c
18
index XXXXXXX..XXXXXXX 100644
16
new file mode 100644
19
--- a/target/arm/hvf/hvf.c
17
index XXXXXXX..XXXXXXX
20
+++ b/target/arm/hvf/hvf.c
18
--- /dev/null
19
+++ b/tests/tcg/aarch64/pcalign-a64.c
21
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
22
#define SYSREG_OSLSR_EL1 SYSREG(2, 0, 1, 1, 4)
21
+/* Test PC misalignment exception */
23
#define SYSREG_OSDLR_EL1 SYSREG(2, 0, 1, 3, 4)
22
+
24
#define SYSREG_CNTPCT_EL0 SYSREG(3, 3, 14, 0, 1)
23
+#include <assert.h>
25
+#define SYSREG_PMCR_EL0 SYSREG(3, 3, 9, 12, 0)
24
+#include <signal.h>
26
+#define SYSREG_PMUSERENR_EL0 SYSREG(3, 3, 9, 14, 0)
25
+#include <stdlib.h>
27
+#define SYSREG_PMCNTENSET_EL0 SYSREG(3, 3, 9, 12, 1)
26
+#include <stdio.h>
28
+#define SYSREG_PMCNTENCLR_EL0 SYSREG(3, 3, 9, 12, 2)
27
+
29
+#define SYSREG_PMINTENCLR_EL1 SYSREG(3, 0, 9, 14, 2)
28
+static void *expected;
30
+#define SYSREG_PMOVSCLR_EL0 SYSREG(3, 3, 9, 12, 3)
29
+
31
+#define SYSREG_PMSWINC_EL0 SYSREG(3, 3, 9, 12, 4)
30
+static void sigbus(int sig, siginfo_t *info, void *vuc)
32
+#define SYSREG_PMSELR_EL0 SYSREG(3, 3, 9, 12, 5)
33
+#define SYSREG_PMCEID0_EL0 SYSREG(3, 3, 9, 12, 6)
34
+#define SYSREG_PMCEID1_EL0 SYSREG(3, 3, 9, 12, 7)
35
+#define SYSREG_PMCCNTR_EL0 SYSREG(3, 3, 9, 13, 0)
36
+#define SYSREG_PMCCFILTR_EL0 SYSREG(3, 3, 14, 15, 7)
37
38
#define WFX_IS_WFE (1 << 0)
39
40
@@ -XXX,XX +XXX,XX @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
41
val = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
42
gt_cntfrq_period_ns(arm_cpu);
43
break;
44
+ case SYSREG_PMCR_EL0:
45
+ val = env->cp15.c9_pmcr;
46
+ break;
47
+ case SYSREG_PMCCNTR_EL0:
48
+ pmu_op_start(env);
49
+ val = env->cp15.c15_ccnt;
50
+ pmu_op_finish(env);
51
+ break;
52
+ case SYSREG_PMCNTENCLR_EL0:
53
+ val = env->cp15.c9_pmcnten;
54
+ break;
55
+ case SYSREG_PMOVSCLR_EL0:
56
+ val = env->cp15.c9_pmovsr;
57
+ break;
58
+ case SYSREG_PMSELR_EL0:
59
+ val = env->cp15.c9_pmselr;
60
+ break;
61
+ case SYSREG_PMINTENCLR_EL1:
62
+ val = env->cp15.c9_pminten;
63
+ break;
64
+ case SYSREG_PMCCFILTR_EL0:
65
+ val = env->cp15.pmccfiltr_el0;
66
+ break;
67
+ case SYSREG_PMCNTENSET_EL0:
68
+ val = env->cp15.c9_pmcnten;
69
+ break;
70
+ case SYSREG_PMUSERENR_EL0:
71
+ val = env->cp15.c9_pmuserenr;
72
+ break;
73
+ case SYSREG_PMCEID0_EL0:
74
+ case SYSREG_PMCEID1_EL0:
75
+ /* We can't really count anything yet, declare all events invalid */
76
+ val = 0;
77
+ break;
78
case SYSREG_OSLSR_EL1:
79
val = env->cp15.oslsr_el1;
80
break;
81
@@ -XXX,XX +XXX,XX @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
82
return 0;
83
}
84
85
+static void pmu_update_irq(CPUARMState *env)
86
+{
31
+{
87
+ ARMCPU *cpu = env_archcpu(env);
32
+ assert(info->si_code == BUS_ADRALN);
88
+ qemu_set_irq(cpu->pmu_interrupt, (env->cp15.c9_pmcr & PMCRE) &&
33
+ assert(info->si_addr == expected);
89
+ (env->cp15.c9_pminten & env->cp15.c9_pmovsr));
34
+ exit(EXIT_SUCCESS);
90
+}
35
+}
91
+
36
+
92
+static bool pmu_event_supported(uint16_t number)
37
+int main()
93
+{
38
+{
94
+ return false;
39
+ void *tmp;
40
+
41
+ struct sigaction sa = {
42
+ .sa_sigaction = sigbus,
43
+ .sa_flags = SA_SIGINFO
44
+ };
45
+
46
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
47
+ perror("sigaction");
48
+ return EXIT_FAILURE;
49
+ }
50
+
51
+ asm volatile("adr %0, 1f + 1\n\t"
52
+ "str %0, %1\n\t"
53
+ "br %0\n"
54
+ "1:"
55
+ : "=&r"(tmp), "=m"(expected));
56
+ abort();
57
+}
58
diff --git a/tests/tcg/arm/pcalign-a32.c b/tests/tcg/arm/pcalign-a32.c
59
new file mode 100644
60
index XXXXXXX..XXXXXXX
61
--- /dev/null
62
+++ b/tests/tcg/arm/pcalign-a32.c
63
@@ -XXX,XX +XXX,XX @@
64
+/* Test PC misalignment exception */
65
+
66
+#ifdef __thumb__
67
+#error "This test must be compiled for ARM"
68
+#endif
69
+
70
+#include <assert.h>
71
+#include <signal.h>
72
+#include <stdlib.h>
73
+#include <stdio.h>
74
+
75
+static void *expected;
76
+
77
+static void sigbus(int sig, siginfo_t *info, void *vuc)
78
+{
79
+ assert(info->si_code == BUS_ADRALN);
80
+ assert(info->si_addr == expected);
81
+ exit(EXIT_SUCCESS);
95
+}
82
+}
96
+
83
+
97
+/* Returns true if the counter (pass 31 for PMCCNTR) should count events using
84
+int main()
98
+ * the current EL, security state, and register configuration.
99
+ */
100
+static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
101
+{
85
+{
102
+ uint64_t filter;
86
+ void *tmp;
103
+ bool enabled, filtered = true;
104
+ int el = arm_current_el(env);
105
+
87
+
106
+ enabled = (env->cp15.c9_pmcr & PMCRE) &&
88
+ struct sigaction sa = {
107
+ (env->cp15.c9_pmcnten & (1 << counter));
89
+ .sa_sigaction = sigbus,
90
+ .sa_flags = SA_SIGINFO
91
+ };
108
+
92
+
109
+ if (counter == 31) {
93
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
110
+ filter = env->cp15.pmccfiltr_el0;
94
+ perror("sigaction");
111
+ } else {
95
+ return EXIT_FAILURE;
112
+ filter = env->cp15.c14_pmevtyper[counter];
113
+ }
96
+ }
114
+
97
+
115
+ if (el == 0) {
98
+ asm volatile("adr %0, 1f + 2\n\t"
116
+ filtered = filter & PMXEVTYPER_U;
99
+ "str %0, %1\n\t"
117
+ } else if (el == 1) {
100
+ "bx %0\n"
118
+ filtered = filter & PMXEVTYPER_P;
101
+ "1:"
119
+ }
102
+ : "=&r"(tmp), "=m"(expected));
120
+
103
+
121
+ if (counter != 31) {
104
+ /*
122
+ /*
105
+ * From v8, it is CONSTRAINED UNPREDICTABLE whether BXWritePC aligns
123
+ * If not checking PMCCNTR, ensure the counter is setup to an event we
106
+ * the address or not. If so, we can legitimately fall through.
124
+ * support
107
+ */
125
+ */
108
+ return EXIT_SUCCESS;
126
+ uint16_t event = filter & PMXEVTYPER_EVTCOUNT;
109
+}
127
+ if (!pmu_event_supported(event)) {
110
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
128
+ return false;
111
index XXXXXXX..XXXXXXX 100644
129
+ }
112
--- a/tests/tcg/aarch64/Makefile.target
130
+ }
113
+++ b/tests/tcg/aarch64/Makefile.target
114
@@ -XXX,XX +XXX,XX @@ VPATH         += $(ARM_SRC)
115
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
116
VPATH         += $(AARCH64_SRC)
117
118
-# Float-convert Tests
119
-AARCH64_TESTS=fcvt
120
+# Base architecture tests
121
+AARCH64_TESTS=fcvt pcalign-a64
122
123
fcvt: LDFLAGS+=-lm
124
125
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
126
index XXXXXXX..XXXXXXX 100644
127
--- a/tests/tcg/arm/Makefile.target
128
+++ b/tests/tcg/arm/Makefile.target
129
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
130
    $(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
131
    $(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
132
133
+# PC alignment test
134
+ARM_TESTS += pcalign-a32
135
+pcalign-a32: CFLAGS+=-marm
131
+
136
+
132
+ return enabled && !filtered;
137
ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
133
+}
138
134
+
139
# Semihosting smoke test for linux-user
135
+static void pmswinc_write(CPUARMState *env, uint64_t value)
136
+{
137
+ unsigned int i;
138
+ for (i = 0; i < pmu_num_counters(env); i++) {
139
+ /* Increment a counter's count iff: */
140
+ if ((value & (1 << i)) && /* counter's bit is set */
141
+ /* counter is enabled and not filtered */
142
+ pmu_counter_enabled(env, i) &&
143
+ /* counter is SW_INCR */
144
+ (env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
145
+ /*
146
+ * Detect if this write causes an overflow since we can't predict
147
+ * PMSWINC overflows like we can for other events
148
+ */
149
+ uint32_t new_pmswinc = env->cp15.c14_pmevcntr[i] + 1;
150
+
151
+ if (env->cp15.c14_pmevcntr[i] & ~new_pmswinc & INT32_MIN) {
152
+ env->cp15.c9_pmovsr |= (1 << i);
153
+ pmu_update_irq(env);
154
+ }
155
+
156
+ env->cp15.c14_pmevcntr[i] = new_pmswinc;
157
+ }
158
+ }
159
+}
160
+
161
static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
162
{
163
ARMCPU *arm_cpu = ARM_CPU(cpu);
164
@@ -XXX,XX +XXX,XX @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
165
val);
166
167
switch (reg) {
168
+ case SYSREG_PMCCNTR_EL0:
169
+ pmu_op_start(env);
170
+ env->cp15.c15_ccnt = val;
171
+ pmu_op_finish(env);
172
+ break;
173
+ case SYSREG_PMCR_EL0:
174
+ pmu_op_start(env);
175
+
176
+ if (val & PMCRC) {
177
+ /* The counter has been reset */
178
+ env->cp15.c15_ccnt = 0;
179
+ }
180
+
181
+ if (val & PMCRP) {
182
+ unsigned int i;
183
+ for (i = 0; i < pmu_num_counters(env); i++) {
184
+ env->cp15.c14_pmevcntr[i] = 0;
185
+ }
186
+ }
187
+
188
+ env->cp15.c9_pmcr &= ~PMCR_WRITEABLE_MASK;
189
+ env->cp15.c9_pmcr |= (val & PMCR_WRITEABLE_MASK);
190
+
191
+ pmu_op_finish(env);
192
+ break;
193
+ case SYSREG_PMUSERENR_EL0:
194
+ env->cp15.c9_pmuserenr = val & 0xf;
195
+ break;
196
+ case SYSREG_PMCNTENSET_EL0:
197
+ env->cp15.c9_pmcnten |= (val & pmu_counter_mask(env));
198
+ break;
199
+ case SYSREG_PMCNTENCLR_EL0:
200
+ env->cp15.c9_pmcnten &= ~(val & pmu_counter_mask(env));
201
+ break;
202
+ case SYSREG_PMINTENCLR_EL1:
203
+ pmu_op_start(env);
204
+ env->cp15.c9_pminten |= val;
205
+ pmu_op_finish(env);
206
+ break;
207
+ case SYSREG_PMOVSCLR_EL0:
208
+ pmu_op_start(env);
209
+ env->cp15.c9_pmovsr &= ~val;
210
+ pmu_op_finish(env);
211
+ break;
212
+ case SYSREG_PMSWINC_EL0:
213
+ pmu_op_start(env);
214
+ pmswinc_write(env, val);
215
+ pmu_op_finish(env);
216
+ break;
217
+ case SYSREG_PMSELR_EL0:
218
+ env->cp15.c9_pmselr = val & 0x1f;
219
+ break;
220
+ case SYSREG_PMCCFILTR_EL0:
221
+ pmu_op_start(env);
222
+ env->cp15.pmccfiltr_el0 = val & PMCCFILTR_EL0;
223
+ pmu_op_finish(env);
224
+ break;
225
case SYSREG_OSLAR_EL1:
226
env->cp15.oslsr_el1 = val & 1;
227
break;
228
--
140
--
229
2.20.1
141
2.25.1
230
142
231
143
diff view generated by jsdifflib
1
Currently all of the M-profile specific code in arm_cpu_reset() is
1
In the SSE decode function gen_sse(), we combine a byte
2
inside a !defined(CONFIG_USER_ONLY) ifdef block. This is
2
'b' and a value 'b1' which can be [0..3], and switch on them:
3
unintentional: it happened because originally the only
3
b |= (b1 << 8);
4
M-profile-specific handling was the setup of the initial SP and PC
4
switch (b) {
5
from the vector table, which is system-emulation only. But then we
5
...
6
added a lot of other M-profile setup to the same "if (ARM_FEATURE_M)"
6
default:
7
code block without noticing that it was all inside a not-user-mode
7
unknown_op:
8
ifdef. This has generally been harmless, but with the addition of
8
gen_unknown_opcode(env, s);
9
v8.1M low-overhead-loop support we ran into a problem: the reset of
9
return;
10
FPSCR.LTPSIZE to 4 was only being done for system emulation mode, so
10
}
11
if a user-mode guest tried to execute the LE instruction it would
12
incorrectly take a UsageFault.
13
11
14
Adjust the ifdefs so only the really system-emulation specific parts
12
In three cases inside this switch, we were then also checking for
15
are covered. Because this means we now run some reset code that sets
13
"if (b1 >= 2) { goto unknown_op; }".
16
up initial values in the FPCCR and similar FPU related registers,
14
However, this can never happen, because the 'case' values in each place
17
explicitly set up the registers controlling FPU context handling in
15
are 0x0nn or 0x1nn and the switch will have directed the b1 == (2, 3)
18
user-emulation mode so that the FPU works by design and not by
16
cases to the default already.
19
chance.
20
17
21
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/613
18
This check was added in commit c045af25a52e9 in 2010; the added code
22
Cc: qemu-stable@nongnu.org
19
was unnecessary then as well, and was apparently intended only to
20
ensure that we never accidentally ended up indexing off the end
21
of an sse_op_table with only 2 entries as a result of future bugs
22
in the decode logic.
23
24
Change the checks to assert() instead, and make sure they're always
25
immediately before the array access they are protecting.
26
27
Fixes: Coverity CID 1460207
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20210914120725.24992-2-peter.maydell@linaro.org
26
---
30
---
27
target/arm/cpu.c | 19 +++++++++++++++++++
31
target/i386/tcg/translate.c | 12 +++---------
28
1 file changed, 19 insertions(+)
32
1 file changed, 3 insertions(+), 9 deletions(-)
29
33
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
34
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
31
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.c
36
--- a/target/i386/tcg/translate.c
33
+++ b/target/arm/cpu.c
37
+++ b/target/i386/tcg/translate.c
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
38
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
35
env->uncached_cpsr = ARM_CPU_MODE_SVC;
39
case 0x171: /* shift xmm, im */
36
}
40
case 0x172:
37
env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
41
case 0x173:
38
+#endif
42
- if (b1 >= 2) {
39
43
- goto unknown_op;
40
if (arm_feature(env, ARM_FEATURE_M)) {
44
- }
41
+#ifndef CONFIG_USER_ONLY
45
val = x86_ldub_code(env, s);
42
uint32_t initial_msp; /* Loaded from 0x0 */
46
if (is_xmm) {
43
uint32_t initial_pc; /* Loaded from 0x4 */
47
tcg_gen_movi_tl(s->T0, val);
44
uint8_t *rom;
48
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
45
uint32_t vecbase;
49
offsetof(CPUX86State, mmx_t0.MMX_L(1)));
46
+#endif
50
op1_offset = offsetof(CPUX86State,mmx_t0);
47
51
}
48
if (cpu_isar_feature(aa32_lob, cpu)) {
52
+ assert(b1 < 2);
49
/*
53
sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
50
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
54
(((modrm >> 3)) & 7)][b1];
51
env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
55
if (!sse_fn_epp) {
52
R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
56
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
53
}
57
rm = modrm & 7;
54
+
58
reg = ((modrm >> 3) & 7) | REX_R(s);
55
+#ifndef CONFIG_USER_ONLY
59
mod = (modrm >> 6) & 3;
56
/* Unlike A/R profile, M profile defines the reset LR value */
60
- if (b1 >= 2) {
57
env->regs[14] = 0xffffffff;
61
- goto unknown_op;
58
62
- }
59
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
63
60
env->regs[13] = initial_msp & 0xFFFFFFFC;
64
+ assert(b1 < 2);
61
env->regs[15] = initial_pc & ~1;
65
sse_fn_epp = sse_op_table6[b].op[b1];
62
env->thumb = initial_pc & 1;
66
if (!sse_fn_epp) {
63
+#else
67
goto unknown_op;
64
+ /*
68
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
65
+ * For user mode we run non-secure and with access to the FPU.
69
rm = modrm & 7;
66
+ * The FPU context is active (ie does not need further setup)
70
reg = ((modrm >> 3) & 7) | REX_R(s);
67
+ * and is owned by non-secure.
71
mod = (modrm >> 6) & 3;
68
+ */
72
- if (b1 >= 2) {
69
+ env->v7m.secure = false;
73
- goto unknown_op;
70
+ env->v7m.nsacr = 0xcff;
74
- }
71
+ env->v7m.cpacr[M_REG_NS] = 0xf0ffff;
75
72
+ env->v7m.fpccr[M_REG_S] &=
76
+ assert(b1 < 2);
73
+ ~(R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK);
77
sse_fn_eppi = sse_op_table7[b].op[b1];
74
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
78
if (!sse_fn_eppi) {
75
+#endif
79
goto unknown_op;
76
}
77
78
+#ifndef CONFIG_USER_ONLY
79
/* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently
80
* executing as AArch32 then check if highvecs are enabled and
81
* adjust the PC accordingly.
82
--
80
--
83
2.20.1
81
2.25.1
84
82
85
83
diff view generated by jsdifflib
1
Optimize the MVE 1op-immediate insns (VORR, VBIC, VMOV) to
1
The qemu-common.h header is not supposed to be included from any
2
use TCG vector ops when possible.
2
other header files, only from .c files (as documented in a comment at
3
the start of it).
4
5
include/hw/i386/x86.h and include/hw/i386/microvm.h break this rule.
6
In fact, the include is not required at all, so we can just drop it
7
from both files.
3
8
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210913095440.13462-13-peter.maydell@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20211129200510.1233037-2-peter.maydell@linaro.org
7
---
13
---
8
target/arm/translate-mve.c | 26 +++++++++++++++++++++-----
14
include/hw/i386/microvm.h | 1 -
9
1 file changed, 21 insertions(+), 5 deletions(-)
15
include/hw/i386/x86.h | 1 -
16
2 files changed, 2 deletions(-)
10
17
11
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
18
diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-mve.c
20
--- a/include/hw/i386/microvm.h
14
+++ b/target/arm/translate-mve.c
21
+++ b/include/hw/i386/microvm.h
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
22
@@ -XXX,XX +XXX,XX @@
16
return true;
23
#ifndef HW_I386_MICROVM_H
17
}
24
#define HW_I386_MICROVM_H
18
25
19
-static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
26
-#include "qemu-common.h"
20
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn,
27
#include "exec/hwaddr.h"
21
+ GVecGen2iFn *vecfn)
28
#include "qemu/notify.h"
22
{
29
23
TCGv_ptr qd;
30
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
24
uint64_t imm;
31
index XXXXXXX..XXXXXXX 100644
25
@@ -XXX,XX +XXX,XX @@ static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
32
--- a/include/hw/i386/x86.h
26
33
+++ b/include/hw/i386/x86.h
27
imm = asimd_imm_const(a->imm, a->cmode, a->op);
34
@@ -XXX,XX +XXX,XX @@
28
35
#ifndef HW_I386_X86_H
29
- qd = mve_qreg_ptr(a->qd);
36
#define HW_I386_X86_H
30
- fn(cpu_env, qd, tcg_constant_i64(imm));
37
31
- tcg_temp_free_ptr(qd);
38
-#include "qemu-common.h"
32
+ if (vecfn && mve_no_predication(s)) {
39
#include "exec/hwaddr.h"
33
+ vecfn(MO_64, mve_qreg_offset(a->qd), mve_qreg_offset(a->qd),
40
#include "qemu/notify.h"
34
+ imm, 16, 16);
41
35
+ } else {
36
+ qd = mve_qreg_ptr(a->qd);
37
+ fn(cpu_env, qd, tcg_constant_i64(imm));
38
+ tcg_temp_free_ptr(qd);
39
+ }
40
mve_update_eci(s);
41
return true;
42
}
43
44
+static void gen_gvec_vmovi(unsigned vece, uint32_t dofs, uint32_t aofs,
45
+ int64_t c, uint32_t oprsz, uint32_t maxsz)
46
+{
47
+ tcg_gen_gvec_dup_imm(vece, dofs, oprsz, maxsz, c);
48
+}
49
+
50
static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
51
{
52
/* Handle decode of cmode/op here between VORR/VBIC/VMOV */
53
MVEGenOneOpImmFn *fn;
54
+ GVecGen2iFn *vecfn;
55
56
if ((a->cmode & 1) && a->cmode < 12) {
57
if (a->op) {
58
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
59
* so the VBIC becomes a logical AND operation.
60
*/
61
fn = gen_helper_mve_vandi;
62
+ vecfn = tcg_gen_gvec_andi;
63
} else {
64
fn = gen_helper_mve_vorri;
65
+ vecfn = tcg_gen_gvec_ori;
66
}
67
} else {
68
/* There is one unallocated cmode/op combination in this space */
69
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
70
}
71
/* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
72
fn = gen_helper_mve_vmovi;
73
+ vecfn = gen_gvec_vmovi;
74
}
75
- return do_1imm(s, a, fn);
76
+ return do_1imm(s, a, fn, vecfn);
77
}
78
79
static bool do_2shift_vec(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
80
--
42
--
81
2.20.1
43
2.25.1
82
44
83
45
diff view generated by jsdifflib
1
Optimize the MVE shift-and-insert insns by using TCG
1
The qemu-common.h header is not supposed to be included from any
2
vector ops when possible.
2
other header files, only from .c files (as documented in a comment at
3
the start of it).
4
5
Move the include to linux-user/hexagon/cpu_loop.c, which needs it for
6
the declaration of cpu_exec_step_atomic().
3
7
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210913095440.13462-12-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Message-id: 20211129200510.1233037-3-peter.maydell@linaro.org
7
---
13
---
8
target/arm/translate-mve.c | 4 ++--
14
target/hexagon/cpu.h | 1 -
9
1 file changed, 2 insertions(+), 2 deletions(-)
15
linux-user/hexagon/cpu_loop.c | 1 +
16
2 files changed, 1 insertion(+), 1 deletion(-)
10
17
11
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
18
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-mve.c
20
--- a/target/hexagon/cpu.h
14
+++ b/target/arm/translate-mve.c
21
+++ b/target/hexagon/cpu.h
15
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_VEC(VSHRI_U, vshli_u, true, do_gvec_shri_u)
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUHexagonState CPUHexagonState;
16
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
23
17
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
24
#include "fpu/softfloat-types.h"
18
25
19
-DO_2SHIFT(VSRI, vsri, false)
26
-#include "qemu-common.h"
20
-DO_2SHIFT(VSLI, vsli, false)
27
#include "exec/cpu-defs.h"
21
+DO_2SHIFT_VEC(VSRI, vsri, false, gen_gvec_sri)
28
#include "hex_regs.h"
22
+DO_2SHIFT_VEC(VSLI, vsli, false, gen_gvec_sli)
29
#include "mmvec/mmvec.h"
23
30
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
24
#define DO_2SHIFT_FP(INSN, FN) \
31
index XXXXXXX..XXXXXXX 100644
25
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
32
--- a/linux-user/hexagon/cpu_loop.c
33
+++ b/linux-user/hexagon/cpu_loop.c
34
@@ -XXX,XX +XXX,XX @@
35
*/
36
37
#include "qemu/osdep.h"
38
+#include "qemu-common.h"
39
#include "qemu.h"
40
#include "user-internals.h"
41
#include "cpu_loop-common.h"
26
--
42
--
27
2.20.1
43
2.25.1
28
44
29
45
diff view generated by jsdifflib
1
Optimize the MVE VSHL and VSHR immediate forms by using TCG vector
1
The qemu-common.h header is not supposed to be included from any
2
ops when possible.
2
other header files, only from .c files (as documented in a comment at
3
the start of it).
4
5
Nothing actually relies on target/rx/cpu.h including it, so we can
6
just drop the include.
3
7
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210913095440.13462-10-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
13
Message-id: 20211129200510.1233037-4-peter.maydell@linaro.org
7
---
14
---
8
target/arm/translate-mve.c | 83 +++++++++++++++++++++++++++++---------
15
target/rx/cpu.h | 1 -
9
1 file changed, 63 insertions(+), 20 deletions(-)
16
1 file changed, 1 deletion(-)
10
17
11
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
18
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-mve.c
20
--- a/target/rx/cpu.h
14
+++ b/target/arm/translate-mve.c
21
+++ b/target/rx/cpu.h
15
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
22
@@ -XXX,XX +XXX,XX @@
16
return do_1imm(s, a, fn);
23
#define RX_CPU_H
17
}
24
18
25
#include "qemu/bitops.h"
19
-static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
26
-#include "qemu-common.h"
20
- bool negateshift)
27
#include "hw/registerfields.h"
21
+static bool do_2shift_vec(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
28
#include "cpu-qom.h"
22
+ bool negateshift, GVecGen2iFn vecfn)
23
{
24
TCGv_ptr qd, qm;
25
int shift = a->shift;
26
@@ -XXX,XX +XXX,XX @@ static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
27
shift = -shift;
28
}
29
30
- qd = mve_qreg_ptr(a->qd);
31
- qm = mve_qreg_ptr(a->qm);
32
- fn(cpu_env, qd, qm, tcg_constant_i32(shift));
33
- tcg_temp_free_ptr(qd);
34
- tcg_temp_free_ptr(qm);
35
+ if (vecfn && mve_no_predication(s)) {
36
+ vecfn(a->size, mve_qreg_offset(a->qd), mve_qreg_offset(a->qm),
37
+ shift, 16, 16);
38
+ } else {
39
+ qd = mve_qreg_ptr(a->qd);
40
+ qm = mve_qreg_ptr(a->qm);
41
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
42
+ tcg_temp_free_ptr(qd);
43
+ tcg_temp_free_ptr(qm);
44
+ }
45
mve_update_eci(s);
46
return true;
47
}
48
49
-#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
50
- static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
51
- { \
52
- static MVEGenTwoOpShiftFn * const fns[] = { \
53
- gen_helper_mve_##FN##b, \
54
- gen_helper_mve_##FN##h, \
55
- gen_helper_mve_##FN##w, \
56
- NULL, \
57
- }; \
58
- return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
59
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
60
+ bool negateshift)
61
+{
62
+ return do_2shift_vec(s, a, fn, negateshift, NULL);
63
+}
64
+
65
+#define DO_2SHIFT_VEC(INSN, FN, NEGATESHIFT, VECFN) \
66
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
67
+ { \
68
+ static MVEGenTwoOpShiftFn * const fns[] = { \
69
+ gen_helper_mve_##FN##b, \
70
+ gen_helper_mve_##FN##h, \
71
+ gen_helper_mve_##FN##w, \
72
+ NULL, \
73
+ }; \
74
+ return do_2shift_vec(s, a, fns[a->size], NEGATESHIFT, VECFN); \
75
}
76
77
-DO_2SHIFT(VSHLI, vshli_u, false)
78
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
79
+ DO_2SHIFT_VEC(INSN, FN, NEGATESHIFT, NULL)
80
+
81
+static void do_gvec_shri_s(unsigned vece, uint32_t dofs, uint32_t aofs,
82
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
83
+{
84
+ /*
85
+ * We get here with a negated shift count, and we must handle
86
+ * shifts by the element size, which tcg_gen_gvec_sari() does not do.
87
+ */
88
+ shift = -shift;
89
+ if (shift == (8 << vece)) {
90
+ shift--;
91
+ }
92
+ tcg_gen_gvec_sari(vece, dofs, aofs, shift, oprsz, maxsz);
93
+}
94
+
95
+static void do_gvec_shri_u(unsigned vece, uint32_t dofs, uint32_t aofs,
96
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
97
+{
98
+ /*
99
+ * We get here with a negated shift count, and we must handle
100
+ * shifts by the element size, which tcg_gen_gvec_shri() does not do.
101
+ */
102
+ shift = -shift;
103
+ if (shift == (8 << vece)) {
104
+ tcg_gen_gvec_dup_imm(vece, dofs, oprsz, maxsz, 0);
105
+ } else {
106
+ tcg_gen_gvec_shri(vece, dofs, aofs, shift, oprsz, maxsz);
107
+ }
108
+}
109
+
110
+DO_2SHIFT_VEC(VSHLI, vshli_u, false, tcg_gen_gvec_shli)
111
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
112
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
113
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
114
/* These right shifts use a left-shift helper with negated shift count */
115
-DO_2SHIFT(VSHRI_S, vshli_s, true)
116
-DO_2SHIFT(VSHRI_U, vshli_u, true)
117
+DO_2SHIFT_VEC(VSHRI_S, vshli_s, true, do_gvec_shri_s)
118
+DO_2SHIFT_VEC(VSHRI_U, vshli_u, true, do_gvec_shri_u)
119
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
120
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
121
29
122
--
30
--
123
2.20.1
31
2.25.1
124
32
125
33
diff view generated by jsdifflib
1
Move an ifndef CONFIG_USER_ONLY code block up in arm_cpu_reset() so
1
A lot of C files in hw/arm include qemu-common.h when they don't
2
it can be merged with another earlier one.
2
need anything from it. Drop the include lines.
3
4
omap1.c, pxa2xx.c and strongarm.c retain the include because they
5
use it for the prototype of qemu_get_timedate().
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210914120725.24992-4-peter.maydell@linaro.org
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
11
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
12
Message-id: 20211129200510.1233037-5-peter.maydell@linaro.org
7
---
13
---
8
target/arm/cpu.c | 22 ++++++++++------------
14
hw/arm/boot.c | 1 -
9
1 file changed, 10 insertions(+), 12 deletions(-)
15
hw/arm/digic_boards.c | 1 -
16
hw/arm/highbank.c | 1 -
17
hw/arm/npcm7xx_boards.c | 1 -
18
hw/arm/sbsa-ref.c | 1 -
19
hw/arm/stm32f405_soc.c | 1 -
20
hw/arm/vexpress.c | 1 -
21
hw/arm/virt.c | 1 -
22
8 files changed, 8 deletions(-)
10
23
11
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
24
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
12
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.c
26
--- a/hw/arm/boot.c
14
+++ b/target/arm/cpu.c
27
+++ b/hw/arm/boot.c
15
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
28
@@ -XXX,XX +XXX,XX @@
16
env->uncached_cpsr = ARM_CPU_MODE_SVC;
29
*/
17
}
30
18
env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
31
#include "qemu/osdep.h"
19
+
32
-#include "qemu-common.h"
20
+ /* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently
33
#include "qemu/datadir.h"
21
+ * executing as AArch32 then check if highvecs are enabled and
34
#include "qemu/error-report.h"
22
+ * adjust the PC accordingly.
35
#include "qapi/error.h"
23
+ */
36
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
24
+ if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
37
index XXXXXXX..XXXXXXX 100644
25
+ env->regs[15] = 0xFFFF0000;
38
--- a/hw/arm/digic_boards.c
26
+ }
39
+++ b/hw/arm/digic_boards.c
27
+
40
@@ -XXX,XX +XXX,XX @@
28
+ env->vfp.xregs[ARM_VFP_FPEXC] = 0;
41
29
#endif
42
#include "qemu/osdep.h"
30
43
#include "qapi/error.h"
31
if (arm_feature(env, ARM_FEATURE_M)) {
44
-#include "qemu-common.h"
32
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
45
#include "qemu/datadir.h"
33
#endif
46
#include "hw/boards.h"
34
}
47
#include "qemu/error-report.h"
35
48
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
36
-#ifndef CONFIG_USER_ONLY
49
index XXXXXXX..XXXXXXX 100644
37
- /* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently
50
--- a/hw/arm/highbank.c
38
- * executing as AArch32 then check if highvecs are enabled and
51
+++ b/hw/arm/highbank.c
39
- * adjust the PC accordingly.
52
@@ -XXX,XX +XXX,XX @@
40
- */
53
*/
41
- if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
54
42
- env->regs[15] = 0xFFFF0000;
55
#include "qemu/osdep.h"
43
- }
56
-#include "qemu-common.h"
44
-
57
#include "qemu/datadir.h"
45
- env->vfp.xregs[ARM_VFP_FPEXC] = 0;
58
#include "qapi/error.h"
46
-#endif
59
#include "hw/sysbus.h"
47
-
60
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
48
/* M profile requires that reset clears the exclusive monitor;
61
index XXXXXXX..XXXXXXX 100644
49
* A profile does not, but clearing it makes more sense than having it
62
--- a/hw/arm/npcm7xx_boards.c
50
* set with an exclusive access on address zero.
63
+++ b/hw/arm/npcm7xx_boards.c
64
@@ -XXX,XX +XXX,XX @@
65
#include "hw/qdev-core.h"
66
#include "hw/qdev-properties.h"
67
#include "qapi/error.h"
68
-#include "qemu-common.h"
69
#include "qemu/datadir.h"
70
#include "qemu/units.h"
71
#include "sysemu/blockdev.h"
72
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/arm/sbsa-ref.c
75
+++ b/hw/arm/sbsa-ref.c
76
@@ -XXX,XX +XXX,XX @@
77
*/
78
79
#include "qemu/osdep.h"
80
-#include "qemu-common.h"
81
#include "qemu/datadir.h"
82
#include "qapi/error.h"
83
#include "qemu/error-report.h"
84
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/stm32f405_soc.c
87
+++ b/hw/arm/stm32f405_soc.c
88
@@ -XXX,XX +XXX,XX @@
89
90
#include "qemu/osdep.h"
91
#include "qapi/error.h"
92
-#include "qemu-common.h"
93
#include "exec/address-spaces.h"
94
#include "sysemu/sysemu.h"
95
#include "hw/arm/stm32f405_soc.h"
96
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/hw/arm/vexpress.c
99
+++ b/hw/arm/vexpress.c
100
@@ -XXX,XX +XXX,XX @@
101
102
#include "qemu/osdep.h"
103
#include "qapi/error.h"
104
-#include "qemu-common.h"
105
#include "qemu/datadir.h"
106
#include "cpu.h"
107
#include "hw/sysbus.h"
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
112
@@ -XXX,XX +XXX,XX @@
113
*/
114
115
#include "qemu/osdep.h"
116
-#include "qemu-common.h"
117
#include "qemu/datadir.h"
118
#include "qemu/units.h"
119
#include "qemu/option.h"
51
--
120
--
52
2.20.1
121
2.25.1
53
122
54
123
diff view generated by jsdifflib
1
There's no particular reason why the exclusive monitor should
1
The calculation of the length of TLB range invalidate operations
2
be only cleared on reset in system emulation mode. It doesn't
2
in tlbi_aa64_range_get_length() is incorrect in two ways:
3
hurt if it isn't cleared in user mode, but we might as well
3
* the NUM field is 5 bits, but we read only 4 bits
4
reduce the amount of code we have that's inside an ifdef.
4
* we miscalculate the page_shift value, because of an
5
off-by-one error:
6
TG 0b00 is invalid
7
TG 0b01 is 4K granule size == 4096 == 2^12
8
TG 0b10 is 16K granule size == 16384 == 2^14
9
TG 0b11 is 64K granule size == 65536 == 2^16
10
so page_shift should be (TG - 1) * 2 + 12
5
11
12
Thanks to the bug report submitter Cha HyunSoo for identifying
13
both these errors.
14
15
Fixes: 84940ed82552d3c ("target/arm: Add support for FEAT_TLBIRANGE")
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210914120725.24992-3-peter.maydell@linaro.org
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20211130173257.1274194-1-peter.maydell@linaro.org
9
---
22
---
10
target/arm/cpu.c | 6 +++---
23
target/arm/helper.c | 6 +++---
11
1 file changed, 3 insertions(+), 3 deletions(-)
24
1 file changed, 3 insertions(+), 3 deletions(-)
12
25
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.c
28
--- a/target/arm/helper.c
16
+++ b/target/arm/cpu.c
29
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
30
@@ -XXX,XX +XXX,XX @@ static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
18
env->regs[15] = 0xFFFF0000;
31
uint64_t exponent;
32
uint64_t length;
33
34
- num = extract64(value, 39, 4);
35
+ num = extract64(value, 39, 5);
36
scale = extract64(value, 44, 2);
37
page_size_granule = extract64(value, 46, 2);
38
39
- page_shift = page_size_granule * 2 + 12;
40
-
41
if (page_size_granule == 0) {
42
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
43
page_size_granule);
44
return 0;
19
}
45
}
20
46
21
+ env->vfp.xregs[ARM_VFP_FPEXC] = 0;
47
+ page_shift = (page_size_granule - 1) * 2 + 12;
22
+#endif
23
+
48
+
24
/* M profile requires that reset clears the exclusive monitor;
49
exponent = (5 * scale) + 1;
25
* A profile does not, but clearing it makes more sense than having it
50
length = (num + 1) << (exponent + page_shift);
26
* set with an exclusive access on address zero.
51
27
*/
28
arm_clear_exclusive(env);
29
30
- env->vfp.xregs[ARM_VFP_FPEXC] = 0;
31
-#endif
32
-
33
if (arm_feature(env, ARM_FEATURE_PMSA)) {
34
if (cpu->pmsav7_dregion > 0) {
35
if (arm_feature(env, ARM_FEATURE_V8)) {
36
--
52
--
37
2.20.1
53
2.25.1
38
54
39
55
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Patrick Venture <venture@google.com>
2
2
3
We will need to install a migration helper for the ARM hvf backend.
3
The rx_active boolean change to true should always trigger a try_read
4
Let's introduce an arch callback for the overall hvf init chain to
4
call that flushes the queue.
5
do so.
6
5
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Signed-off-by: Patrick Venture <venture@google.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210916155404.86958-4-agraf@csgraf.de
8
Message-id: 20211203221002.1719306-1-venture@google.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
include/sysemu/hvf_int.h | 1 +
11
hw/net/npcm7xx_emc.c | 18 ++++++++----------
13
accel/hvf/hvf-accel-ops.c | 3 ++-
12
1 file changed, 8 insertions(+), 10 deletions(-)
14
target/i386/hvf/hvf.c | 5 +++++
15
3 files changed, 8 insertions(+), 1 deletion(-)
16
13
17
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
14
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/sysemu/hvf_int.h
16
--- a/hw/net/npcm7xx_emc.c
20
+++ b/include/sysemu/hvf_int.h
17
+++ b/hw/net/npcm7xx_emc.c
21
@@ -XXX,XX +XXX,XX @@ struct hvf_vcpu_state {
18
@@ -XXX,XX +XXX,XX @@ static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
22
};
19
emc_set_mista(emc, mista_flag);
23
24
void assert_hvf_ok(hv_return_t ret);
25
+int hvf_arch_init(void);
26
int hvf_arch_init_vcpu(CPUState *cpu);
27
void hvf_arch_vcpu_destroy(CPUState *cpu);
28
int hvf_vcpu_exec(CPUState *);
29
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/accel/hvf/hvf-accel-ops.c
32
+++ b/accel/hvf/hvf-accel-ops.c
33
@@ -XXX,XX +XXX,XX @@ static int hvf_accel_init(MachineState *ms)
34
35
hvf_state = s;
36
memory_listener_register(&hvf_memory_listener, &address_space_memory);
37
- return 0;
38
+
39
+ return hvf_arch_init();
40
}
20
}
41
21
42
static void hvf_accel_class_init(ObjectClass *oc, void *data)
22
+static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc)
43
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/i386/hvf/hvf.c
46
+++ b/target/i386/hvf/hvf.c
47
@@ -XXX,XX +XXX,XX @@ static inline bool apic_bus_freq_is_known(CPUX86State *env)
48
return env->apic_bus_freq != 0;
49
}
50
51
+int hvf_arch_init(void)
52
+{
23
+{
53
+ return 0;
24
+ emc->rx_active = true;
25
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
54
+}
26
+}
55
+
27
+
56
int hvf_arch_init_vcpu(CPUState *cpu)
28
static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
29
const NPCM7xxEMCTxDesc *tx_desc,
30
uint32_t desc_addr)
31
@@ -XXX,XX +XXX,XX @@ static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
32
return len;
33
}
34
35
-static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
36
-{
37
- if (emc_can_receive(qemu_get_queue(emc->nic))) {
38
- qemu_flush_queued_packets(qemu_get_queue(emc->nic));
39
- }
40
-}
41
-
42
static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
57
{
43
{
58
X86CPU *x86cpu = X86_CPU(cpu);
44
NPCM7xxEMCState *emc = opaque;
45
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
46
emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
47
}
48
if (value & REG_MCMDR_RXON) {
49
- emc->rx_active = true;
50
+ emc_enable_rx_and_flush(emc);
51
} else {
52
emc_halt_rx(emc, 0);
53
}
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
55
break;
56
case REG_RSDR:
57
if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
58
- emc->rx_active = true;
59
- emc_try_receive_next_packet(emc);
60
+ emc_enable_rx_and_flush(emc);
61
}
62
break;
63
case REG_MIIDA:
59
--
64
--
60
2.20.1
65
2.25.1
61
66
62
67
diff view generated by jsdifflib
1
Coverity points out that if the PDB file we're trying to read
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
has a header specifying a block_size of zero then we will
3
end up trying to divide by zero in pdb_ds_read_file().
4
Check for this and fail cleanly instead.
5
2
6
Fixes: Coverity CID 1458869
3
When a virtio-iommu is instantiated, describe it using the ACPI VIOT
4
table.
5
6
Acked-by: Igor Mammedov <imammedo@redhat.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
Message-id: 20211210170415.583179-2-jean-philippe@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Viktor Prutyanov <viktor.prutyanov@phystech.edu>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Tested-by: Viktor Prutyanov <viktor.prutyanov@phystech.edu>
11
Message-id: 20210910170656.366592-3-philmd@redhat.com
12
Message-Id: <20210901143910.17112-3-peter.maydell@linaro.org>
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
---
11
---
15
contrib/elf2dmp/pdb.c | 4 ++++
12
hw/arm/virt-acpi-build.c | 7 +++++++
16
1 file changed, 4 insertions(+)
13
hw/arm/Kconfig | 1 +
14
2 files changed, 8 insertions(+)
17
15
18
diff --git a/contrib/elf2dmp/pdb.c b/contrib/elf2dmp/pdb.c
16
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/contrib/elf2dmp/pdb.c
18
--- a/hw/arm/virt-acpi-build.c
21
+++ b/contrib/elf2dmp/pdb.c
19
+++ b/hw/arm/virt-acpi-build.c
22
@@ -XXX,XX +XXX,XX @@ out_symbols:
20
@@ -XXX,XX +XXX,XX @@
23
21
#include "kvm_arm.h"
24
static int pdb_reader_ds_init(struct pdb_reader *r, PDB_DS_HEADER *hdr)
22
#include "migration/vmstate.h"
25
{
23
#include "hw/acpi/ghes.h"
26
+ if (hdr->block_size == 0) {
24
+#include "hw/acpi/viot.h"
27
+ return 1;
25
26
#define ARM_SPI_BASE 32
27
28
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
29
}
30
#endif
31
32
+ if (vms->iommu == VIRT_IOMMU_VIRTIO) {
33
+ acpi_add_table(table_offsets, tables_blob);
34
+ build_viot(ms, tables_blob, tables->linker, vms->virtio_iommu_bdf,
35
+ vms->oem_id, vms->oem_table_id);
28
+ }
36
+ }
29
+
37
+
30
memset(r->file_used, 0, sizeof(r->file_used));
38
/* XSDT is pointed to by RSDP */
31
r->ds.header = hdr;
39
xsdt = tables_blob->len;
32
r->ds.toc = pdb_ds_read(hdr, (uint32_t *)((uint8_t *)hdr +
40
build_xsdt(tables_blob, tables->linker, table_offsets, vms->oem_id,
41
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/Kconfig
44
+++ b/hw/arm/Kconfig
45
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
46
select DIMM
47
select ACPI_HW_REDUCED
48
select ACPI_APEI
49
+ select ACPI_VIOT
50
51
config CHEETAH
52
bool
33
--
53
--
34
2.20.1
54
2.25.1
35
55
36
56
diff view generated by jsdifflib
1
Optimize MVE arithmetic ops when we have a TCG
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
vector operation we can use.
3
2
3
virtio-iommu is now supported with ACPI VIOT as well as device tree.
4
Remove the restriction that prevents from instantiating a virtio-iommu
5
device under ACPI.
6
7
Acked-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Message-id: 20211210170415.583179-3-jean-philippe@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210913095440.13462-6-peter.maydell@linaro.org
8
---
12
---
9
target/arm/translate-mve.c | 20 +++++++++++---------
13
hw/arm/virt.c | 10 ++--------
10
1 file changed, 11 insertions(+), 9 deletions(-)
14
hw/virtio/virtio-iommu-pci.c | 12 ++----------
15
2 files changed, 4 insertions(+), 18 deletions(-)
11
16
12
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-mve.c
19
--- a/hw/arm/virt.c
15
+++ b/target/arm/translate-mve.c
20
+++ b/hw/arm/virt.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_VPSEL(DisasContext *s, arg_2op *a)
21
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
17
return do_2op(s, a, gen_helper_mve_vpsel);
22
MachineClass *mc = MACHINE_GET_CLASS(machine);
23
24
if (device_is_dynamic_sysbus(mc, dev) ||
25
- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
26
+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
27
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
28
return HOTPLUG_HANDLER(machine);
29
}
30
- if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
31
- VirtMachineState *vms = VIRT_MACHINE(machine);
32
-
33
- if (!vms->bootinfo.firmware_loaded || !virt_is_acpi_enabled(vms)) {
34
- return HOTPLUG_HANDLER(machine);
35
- }
36
- }
37
return NULL;
18
}
38
}
19
39
20
-#define DO_2OP(INSN, FN) \
40
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
21
+#define DO_2OP_VEC(INSN, FN, VECFN) \
41
index XXXXXXX..XXXXXXX 100644
22
static bool trans_##INSN(DisasContext *s, arg_2op *a) \
42
--- a/hw/virtio/virtio-iommu-pci.c
23
{ \
43
+++ b/hw/virtio/virtio-iommu-pci.c
24
static MVEGenTwoOpFn * const fns[] = { \
44
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
25
@@ -XXX,XX +XXX,XX @@ static bool trans_VPSEL(DisasContext *s, arg_2op *a)
45
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
26
gen_helper_mve_##FN##w, \
46
27
NULL, \
47
if (!qdev_get_machine_hotplug_handler(DEVICE(vpci_dev))) {
28
}; \
48
- MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
29
- return do_2op(s, a, fns[a->size]); \
49
-
30
+ return do_2op_vec(s, a, fns[a->size], VECFN); \
50
- error_setg(errp,
51
- "%s machine fails to create iommu-map device tree bindings",
52
- mc->name);
53
- error_append_hint(errp,
54
- "Check your machine implements a hotplug handler "
55
- "for the virtio-iommu-pci device\n");
56
- error_append_hint(errp, "Check the guest is booted without FW or with "
57
- "-no-acpi\n");
58
+ error_setg(errp, "Check your machine implements a hotplug handler "
59
+ "for the virtio-iommu-pci device");
60
return;
31
}
61
}
32
62
for (int i = 0; i < s->nb_reserved_regions; i++) {
33
-DO_2OP(VADD, vadd)
34
-DO_2OP(VSUB, vsub)
35
-DO_2OP(VMUL, vmul)
36
+#define DO_2OP(INSN, FN) DO_2OP_VEC(INSN, FN, NULL)
37
+
38
+DO_2OP_VEC(VADD, vadd, tcg_gen_gvec_add)
39
+DO_2OP_VEC(VSUB, vsub, tcg_gen_gvec_sub)
40
+DO_2OP_VEC(VMUL, vmul, tcg_gen_gvec_mul)
41
DO_2OP(VMULH_S, vmulhs)
42
DO_2OP(VMULH_U, vmulhu)
43
DO_2OP(VRMULH_S, vrmulhs)
44
DO_2OP(VRMULH_U, vrmulhu)
45
-DO_2OP(VMAX_S, vmaxs)
46
-DO_2OP(VMAX_U, vmaxu)
47
-DO_2OP(VMIN_S, vmins)
48
-DO_2OP(VMIN_U, vminu)
49
+DO_2OP_VEC(VMAX_S, vmaxs, tcg_gen_gvec_smax)
50
+DO_2OP_VEC(VMAX_U, vmaxu, tcg_gen_gvec_umax)
51
+DO_2OP_VEC(VMIN_S, vmins, tcg_gen_gvec_smin)
52
+DO_2OP_VEC(VMIN_U, vminu, tcg_gen_gvec_umin)
53
DO_2OP(VABD_S, vabds)
54
DO_2OP(VABD_U, vabdu)
55
DO_2OP(VHADD_S, vhadds)
56
--
63
--
57
2.20.1
64
2.25.1
58
65
59
66
diff view generated by jsdifflib
New patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
1
2
3
We do not support instantiating multiple IOMMUs. Before adding a
4
virtio-iommu, check that no other IOMMU is present. This will detect
5
both "iommu=smmuv3" machine parameter and another virtio-iommu instance.
6
7
Fixes: 70e89132c9 ("hw/arm/virt: Add the virtio-iommu device tree mappings")
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-4-jean-philippe@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/virt.c | 5 +++++
15
1 file changed, 5 insertions(+)
16
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
20
+++ b/hw/arm/virt.c
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
22
hwaddr db_start = 0, db_end = 0;
23
char *resv_prop_str;
24
25
+ if (vms->iommu != VIRT_IOMMU_NONE) {
26
+ error_setg(errp, "virt machine does not support multiple IOMMUs");
27
+ return;
28
+ }
29
+
30
switch (vms->msi_controller) {
31
case VIRT_MSI_CTRL_NONE:
32
return;
33
--
34
2.25.1
35
36
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Hvf's permission bitmap during and after dirty logging does not include
3
To propagate errors to the caller of the pre_plug callback, use the
4
the HV_MEMORY_EXEC permission. At least on Apple Silicon, this leads to
4
object_poperty_set*() functions directly instead of the qdev_prop_set*()
5
instruction faults once dirty logging was enabled.
5
helpers.
6
6
7
Add the bit to make it work properly.
7
Suggested-by: Igor Mammedov <imammedo@redhat.com>
8
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Alexander Graf <agraf@csgraf.de>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20210916155404.86958-3-agraf@csgraf.de
11
Message-id: 20211210170415.583179-5-jean-philippe@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
accel/hvf/hvf-accel-ops.c | 4 ++--
14
hw/arm/virt.c | 5 +++--
15
1 file changed, 2 insertions(+), 2 deletions(-)
15
1 file changed, 3 insertions(+), 2 deletions(-)
16
16
17
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/accel/hvf/hvf-accel-ops.c
19
--- a/hw/arm/virt.c
20
+++ b/accel/hvf/hvf-accel-ops.c
20
+++ b/hw/arm/virt.c
21
@@ -XXX,XX +XXX,XX @@ static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
22
if (on) {
22
db_start, db_end,
23
slot->flags |= HVF_SLOT_LOG;
23
VIRTIO_IOMMU_RESV_MEM_T_MSI);
24
hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
24
25
- HV_MEMORY_READ);
25
- qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
26
+ HV_MEMORY_READ | HV_MEMORY_EXEC);
26
- qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
27
/* stop tracking region*/
27
+ object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
28
} else {
28
+ object_property_set_str(OBJECT(dev), "reserved-regions[0]",
29
slot->flags &= ~HVF_SLOT_LOG;
29
+ resv_prop_str, errp);
30
hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
30
g_free(resv_prop_str);
31
- HV_MEMORY_READ | HV_MEMORY_WRITE);
32
+ HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
33
}
31
}
34
}
32
}
35
36
--
33
--
37
2.20.1
34
2.25.1
38
35
39
36
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Now that we have all logic in place that we need to handle Hypervisor.framework
3
Create empty data files and allow updates for the upcoming VIOT tests.
4
on Apple Silicon systems, let's add CONFIG_HVF for aarch64 as well so that we
5
can build it.
6
4
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
5
Acked-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com> (x86 only)
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20211210170415.583179-6-jean-philippe@linaro.org
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
Message-id: 20210916155404.86958-9-agraf@csgraf.de
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
meson.build | 7 +++++++
11
tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
16
target/arm/hvf/meson.build | 3 +++
12
tests/data/acpi/q35/DSDT.viot | 0
17
target/arm/meson.build | 2 ++
13
tests/data/acpi/q35/VIOT.viot | 0
18
3 files changed, 12 insertions(+)
14
tests/data/acpi/virt/VIOT | 0
19
create mode 100644 target/arm/hvf/meson.build
15
4 files changed, 3 insertions(+)
16
create mode 100644 tests/data/acpi/q35/DSDT.viot
17
create mode 100644 tests/data/acpi/q35/VIOT.viot
18
create mode 100644 tests/data/acpi/virt/VIOT
20
19
21
diff --git a/meson.build b/meson.build
20
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
22
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
23
--- a/meson.build
22
--- a/tests/qtest/bios-tables-test-allowed-diff.h
24
+++ b/meson.build
23
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
25
@@ -XXX,XX +XXX,XX @@ else
24
@@ -1 +1,4 @@
26
endif
25
/* List of comma-separated changed AML files to ignore */
27
26
+"tests/data/acpi/virt/VIOT",
28
accelerator_targets = { 'CONFIG_KVM': kvm_targets }
27
+"tests/data/acpi/q35/DSDT.viot",
29
+
28
+"tests/data/acpi/q35/VIOT.viot",
30
+if cpu in ['aarch64']
29
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
31
+ accelerator_targets += {
32
+ 'CONFIG_HVF': ['aarch64-softmmu']
33
+ }
34
+endif
35
+
36
if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
37
# i386 emulator provides xenpv machine type for multiple architectures
38
accelerator_targets += {
39
diff --git a/target/arm/hvf/meson.build b/target/arm/hvf/meson.build
40
new file mode 100644
30
new file mode 100644
41
index XXXXXXX..XXXXXXX
31
index XXXXXXX..XXXXXXX
42
--- /dev/null
32
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
43
+++ b/target/arm/hvf/meson.build
33
new file mode 100644
44
@@ -XXX,XX +XXX,XX @@
34
index XXXXXXX..XXXXXXX
45
+arm_softmmu_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files(
35
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
46
+ 'hvf.c',
36
new file mode 100644
47
+))
37
index XXXXXXX..XXXXXXX
48
diff --git a/target/arm/meson.build b/target/arm/meson.build
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/meson.build
51
+++ b/target/arm/meson.build
52
@@ -XXX,XX +XXX,XX @@ arm_softmmu_ss.add(files(
53
'psci.c',
54
))
55
56
+subdir('hvf')
57
+
58
target_arch += {'arm': arm_ss}
59
target_softmmu_arch += {'arm': arm_softmmu_ss}
60
--
38
--
61
2.20.1
39
2.25.1
62
40
63
41
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
We need to handle PSCI calls. Most of the TCG code works for us,
3
Add two test cases for VIOT, one on the q35 machine and the other on
4
but we can simplify it to only handle aa64 mode and we need to
4
virt. To test complex topologies the q35 test has two PCIe buses that
5
handle SUSPEND differently.
5
bypass the IOMMU (and are therefore not described by VIOT), and two
6
buses that are translated by virtio-iommu.
6
7
7
This patch takes the TCG code as template and duplicates it in HVF.
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
To tell the guest that we support PSCI 0.2 now, update the check in
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
arm_cpu_initfn() as well.
11
Message-id: 20211210170415.583179-7-jean-philippe@linaro.org
11
12
Signed-off-by: Alexander Graf <agraf@csgraf.de>
13
Reviewed-by: Sergio Lopez <slp@redhat.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20210916155404.86958-8-agraf@csgraf.de
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
13
---
18
target/arm/cpu.c | 4 +-
14
tests/qtest/bios-tables-test.c | 38 ++++++++++++++++++++++++++++++++++
19
target/arm/hvf/hvf.c | 141 ++++++++++++++++++++++++++++++++++--
15
1 file changed, 38 insertions(+)
20
target/arm/hvf/trace-events | 1 +
21
3 files changed, 139 insertions(+), 7 deletions(-)
22
16
23
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
24
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.c
19
--- a/tests/qtest/bios-tables-test.c
26
+++ b/target/arm/cpu.c
20
+++ b/tests/qtest/bios-tables-test.c
27
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static void test_acpi_virt_tcg(void)
28
cpu->psci_version = 1; /* By default assume PSCI v0.1 */
22
free_test_data(&data);
29
cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
30
31
- if (tcg_enabled()) {
32
- cpu->psci_version = 2; /* TCG implements PSCI 0.2 */
33
+ if (tcg_enabled() || hvf_enabled()) {
34
+ cpu->psci_version = 2; /* TCG and HVF implement PSCI 0.2 */
35
}
36
}
23
}
37
24
38
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
25
+static void test_acpi_q35_viot(void)
39
index XXXXXXX..XXXXXXX 100644
26
+{
40
--- a/target/arm/hvf/hvf.c
27
+ test_data data = {
41
+++ b/target/arm/hvf/hvf.c
28
+ .machine = MACHINE_Q35,
42
@@ -XXX,XX +XXX,XX @@
29
+ .variant = ".viot",
43
#include "hw/irq.h"
30
+ };
44
#include "qemu/main-loop.h"
45
#include "sysemu/cpus.h"
46
+#include "arm-powerctl.h"
47
#include "target/arm/cpu.h"
48
#include "target/arm/internals.h"
49
#include "trace/trace-target_arm_hvf.h"
50
@@ -XXX,XX +XXX,XX @@
51
#define TMR_CTL_IMASK (1 << 1)
52
#define TMR_CTL_ISTATUS (1 << 2)
53
54
+static void hvf_wfi(CPUState *cpu);
55
+
31
+
56
typedef struct HVFVTimer {
32
+ /*
57
/* Vtimer value during migration and paused state */
33
+ * To keep things interesting, two buses bypass the IOMMU.
58
uint64_t vtimer_val;
34
+ * VIOT should only describes the other two buses.
59
@@ -XXX,XX +XXX,XX @@ static void hvf_raise_exception(CPUState *cpu, uint32_t excp,
35
+ */
60
arm_cpu_do_interrupt(cpu);
36
+ test_acpi_one("-machine default_bus_bypass_iommu=on "
61
}
37
+ "-device virtio-iommu-pci "
62
38
+ "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 "
63
+static void hvf_psci_cpu_off(ARMCPU *arm_cpu)
39
+ "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on "
64
+{
40
+ "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0",
65
+ int32_t ret = arm_set_cpu_off(arm_cpu->mp_affinity);
41
+ &data);
66
+ assert(ret == QEMU_ARM_POWERCTL_RET_SUCCESS);
42
+ free_test_data(&data);
67
+}
43
+}
68
+
44
+
69
+/*
45
+static void test_acpi_virt_viot(void)
70
+ * Handle a PSCI call.
71
+ *
72
+ * Returns 0 on success
73
+ * -1 when the PSCI call is unknown,
74
+ */
75
+static bool hvf_handle_psci_call(CPUState *cpu)
76
+{
46
+{
77
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
47
+ test_data data = {
78
+ CPUARMState *env = &arm_cpu->env;
48
+ .machine = "virt",
79
+ uint64_t param[4] = {
49
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
80
+ env->xregs[0],
50
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
81
+ env->xregs[1],
51
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
82
+ env->xregs[2],
52
+ .ram_start = 0x40000000ULL,
83
+ env->xregs[3]
53
+ .scan_len = 128ULL * 1024 * 1024,
84
+ };
54
+ };
85
+ uint64_t context_id, mpidr;
86
+ bool target_aarch64 = true;
87
+ CPUState *target_cpu_state;
88
+ ARMCPU *target_cpu;
89
+ target_ulong entry;
90
+ int target_el = 1;
91
+ int32_t ret = 0;
92
+
55
+
93
+ trace_hvf_psci_call(param[0], param[1], param[2], param[3],
56
+ test_acpi_one("-cpu cortex-a57 "
94
+ arm_cpu->mp_affinity);
57
+ "-device virtio-iommu-pci", &data);
95
+
58
+ free_test_data(&data);
96
+ switch (param[0]) {
97
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
98
+ ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
99
+ break;
100
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
101
+ ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
102
+ break;
103
+ case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
104
+ case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
105
+ mpidr = param[1];
106
+
107
+ switch (param[2]) {
108
+ case 0:
109
+ target_cpu_state = arm_get_cpu_by_id(mpidr);
110
+ if (!target_cpu_state) {
111
+ ret = QEMU_PSCI_RET_INVALID_PARAMS;
112
+ break;
113
+ }
114
+ target_cpu = ARM_CPU(target_cpu_state);
115
+
116
+ ret = target_cpu->power_state;
117
+ break;
118
+ default:
119
+ /* Everything above affinity level 0 is always on. */
120
+ ret = 0;
121
+ }
122
+ break;
123
+ case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
124
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
125
+ /*
126
+ * QEMU reset and shutdown are async requests, but PSCI
127
+ * mandates that we never return from the reset/shutdown
128
+ * call, so power the CPU off now so it doesn't execute
129
+ * anything further.
130
+ */
131
+ hvf_psci_cpu_off(arm_cpu);
132
+ break;
133
+ case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
134
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
135
+ hvf_psci_cpu_off(arm_cpu);
136
+ break;
137
+ case QEMU_PSCI_0_1_FN_CPU_ON:
138
+ case QEMU_PSCI_0_2_FN_CPU_ON:
139
+ case QEMU_PSCI_0_2_FN64_CPU_ON:
140
+ mpidr = param[1];
141
+ entry = param[2];
142
+ context_id = param[3];
143
+ ret = arm_set_cpu_on(mpidr, entry, context_id,
144
+ target_el, target_aarch64);
145
+ break;
146
+ case QEMU_PSCI_0_1_FN_CPU_OFF:
147
+ case QEMU_PSCI_0_2_FN_CPU_OFF:
148
+ hvf_psci_cpu_off(arm_cpu);
149
+ break;
150
+ case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
151
+ case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
152
+ case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
153
+ /* Affinity levels are not supported in QEMU */
154
+ if (param[1] & 0xfffe0000) {
155
+ ret = QEMU_PSCI_RET_INVALID_PARAMS;
156
+ break;
157
+ }
158
+ /* Powerdown is not supported, we always go into WFI */
159
+ env->xregs[0] = 0;
160
+ hvf_wfi(cpu);
161
+ break;
162
+ case QEMU_PSCI_0_1_FN_MIGRATE:
163
+ case QEMU_PSCI_0_2_FN_MIGRATE:
164
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
165
+ break;
166
+ default:
167
+ return false;
168
+ }
169
+
170
+ env->xregs[0] = ret;
171
+ return true;
172
+}
59
+}
173
+
60
+
174
static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
61
static void test_oem_fields(test_data *data)
175
{
62
{
176
ARMCPU *arm_cpu = ARM_CPU(cpu);
63
int i;
177
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
64
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
178
break;
65
qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic);
179
case EC_AA64_HVC:
66
qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
180
cpu_synchronize_state(cpu);
67
}
181
- trace_hvf_unknown_hvc(env->xregs[0]);
68
+ qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
182
- /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
69
} else if (strcmp(arch, "aarch64") == 0) {
183
- env->xregs[0] = -1;
70
if (has_tcg) {
184
+ if (arm_cpu->psci_conduit == QEMU_PSCI_CONDUIT_HVC) {
71
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
185
+ if (!hvf_handle_psci_call(cpu)) {
72
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
186
+ trace_hvf_unknown_hvc(env->xregs[0]);
73
qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
187
+ /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
74
qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
188
+ env->xregs[0] = -1;
75
qtest_add_func("acpi/virt/oem-fields", test_acpi_oem_fields_virt);
189
+ }
76
+ qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
190
+ } else {
77
}
191
+ trace_hvf_unknown_hvc(env->xregs[0]);
78
}
192
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
79
ret = g_test_run();
193
+ }
194
break;
195
case EC_AA64_SMC:
196
cpu_synchronize_state(cpu);
197
- trace_hvf_unknown_smc(env->xregs[0]);
198
- hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
199
+ if (arm_cpu->psci_conduit == QEMU_PSCI_CONDUIT_SMC) {
200
+ advance_pc = true;
201
+
202
+ if (!hvf_handle_psci_call(cpu)) {
203
+ trace_hvf_unknown_smc(env->xregs[0]);
204
+ /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
205
+ env->xregs[0] = -1;
206
+ }
207
+ } else {
208
+ trace_hvf_unknown_smc(env->xregs[0]);
209
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
210
+ }
211
break;
212
default:
213
cpu_synchronize_state(cpu);
214
diff --git a/target/arm/hvf/trace-events b/target/arm/hvf/trace-events
215
index XXXXXXX..XXXXXXX 100644
216
--- a/target/arm/hvf/trace-events
217
+++ b/target/arm/hvf/trace-events
218
@@ -XXX,XX +XXX,XX @@ hvf_sysreg_write(uint32_t reg, uint32_t op0, uint32_t op1, uint32_t crn, uint32_
219
hvf_unknown_hvc(uint64_t x0) "unknown HVC! 0x%016"PRIx64
220
hvf_unknown_smc(uint64_t x0) "unknown SMC! 0x%016"PRIx64
221
hvf_exit(uint64_t syndrome, uint32_t ec, uint64_t pc) "exit: 0x%"PRIx64" [ec=0x%x pc=0x%"PRIx64"]"
222
+hvf_psci_call(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint32_t cpuid) "PSCI Call x0=0x%016"PRIx64" x1=0x%016"PRIx64" x2=0x%016"PRIx64" x3=0x%016"PRIx64" cpu=0x%x"
223
--
80
--
224
2.20.1
81
2.25.1
225
82
226
83
diff view generated by jsdifflib
New patch
1
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
3
Add expected blobs of the VIOT and DSDT table for the VIOT test on the
4
q35 machine.
5
6
Since the test instantiates a virtio device and two PCIe expander
7
bridges, DSDT.viot has more blocks than the base DSDT.
8
9
The VIOT table generated for the q35 test is:
10
11
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
12
[004h 0004 4] Table Length : 00000070
13
[008h 0008 1] Revision : 00
14
[009h 0009 1] Checksum : 3D
15
[00Ah 0010 6] Oem ID : "BOCHS "
16
[010h 0016 8] Oem Table ID : "BXPC "
17
[018h 0024 4] Oem Revision : 00000001
18
[01Ch 0028 4] Asl Compiler ID : "BXPC"
19
[020h 0032 4] Asl Compiler Revision : 00000001
20
21
[024h 0036 2] Node count : 0003
22
[026h 0038 2] Node offset : 0030
23
[028h 0040 8] Reserved : 0000000000000000
24
25
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
26
[031h 0049 1] Reserved : 00
27
[032h 0050 2] Length : 0010
28
29
[034h 0052 2] PCI Segment : 0000
30
[036h 0054 2] PCI BDF number : 0010
31
[038h 0056 8] Reserved : 0000000000000000
32
33
[040h 0064 1] Type : 01 [PCI Range]
34
[041h 0065 1] Reserved : 00
35
[042h 0066 2] Length : 0018
36
37
[044h 0068 4] Endpoint start : 00003000
38
[048h 0072 2] PCI Segment start : 0000
39
[04Ah 0074 2] PCI Segment end : 0000
40
[04Ch 0076 2] PCI BDF start : 3000
41
[04Eh 0078 2] PCI BDF end : 30FF
42
[050h 0080 2] Output node : 0030
43
[052h 0082 6] Reserved : 000000000000
44
45
[058h 0088 1] Type : 01 [PCI Range]
46
[059h 0089 1] Reserved : 00
47
[05Ah 0090 2] Length : 0018
48
49
[05Ch 0092 4] Endpoint start : 00001000
50
[060h 0096 2] PCI Segment start : 0000
51
[062h 0098 2] PCI Segment end : 0000
52
[064h 0100 2] PCI BDF start : 1000
53
[066h 0102 2] PCI BDF end : 10FF
54
[068h 0104 2] Output node : 0030
55
[06Ah 0106 6] Reserved : 000000000000
56
57
And the DSDT diff is:
58
59
@@ -XXX,XX +XXX,XX @@
60
*
61
* Disassembling to symbolic ASL+ operators
62
*
63
- * Disassembly of tests/data/acpi/q35/DSDT, Fri Dec 10 15:03:08 2021
64
+ * Disassembly of /tmp/aml-H9Y5D1, Fri Dec 10 15:02:27 2021
65
*
66
* Original Table Header:
67
* Signature "DSDT"
68
- * Length 0x00002061 (8289)
69
+ * Length 0x000024B6 (9398)
70
* Revision 0x01 **** 32-bit table (V1), no 64-bit math support
71
- * Checksum 0xFA
72
+ * Checksum 0xA7
73
* OEM ID "BOCHS "
74
* OEM Table ID "BXPC "
75
* OEM Revision 0x00000001 (1)
76
@@ -XXX,XX +XXX,XX @@
77
}
78
}
79
80
+ Scope (\_SB)
81
+ {
82
+ Device (PC30)
83
+ {
84
+ Name (_UID, 0x30) // _UID: Unique ID
85
+ Name (_BBN, 0x30) // _BBN: BIOS Bus Number
86
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
87
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
88
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
89
+ {
90
+ CreateDWordField (Arg3, Zero, CDW1)
91
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
92
+ {
93
+ CreateDWordField (Arg3, 0x04, CDW2)
94
+ CreateDWordField (Arg3, 0x08, CDW3)
95
+ Local0 = CDW3 /* \_SB_.PC30._OSC.CDW3 */
96
+ Local0 &= 0x1F
97
+ If ((Arg1 != One))
98
+ {
99
+ CDW1 |= 0x08
100
+ }
101
+
102
+ If ((CDW3 != Local0))
103
+ {
104
+ CDW1 |= 0x10
105
+ }
106
+
107
+ CDW3 = Local0
108
+ }
109
+ Else
110
+ {
111
+ CDW1 |= 0x04
112
+ }
113
+
114
+ Return (Arg3)
115
+ }
116
+
117
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
118
+ {
119
+ Local0 = Package (0x80){}
120
+ Local1 = Zero
121
+ While ((Local1 < 0x80))
122
+ {
123
+ Local2 = (Local1 >> 0x02)
124
+ Local3 = ((Local1 + Local2) & 0x03)
125
+ If ((Local3 == Zero))
126
+ {
127
+ Local4 = Package (0x04)
128
+ {
129
+ Zero,
130
+ Zero,
131
+ LNKD,
132
+ Zero
133
+ }
134
+ }
135
+
136
+ If ((Local3 == One))
137
+ {
138
+ Local4 = Package (0x04)
139
+ {
140
+ Zero,
141
+ Zero,
142
+ LNKA,
143
+ Zero
144
+ }
145
+ }
146
+
147
+ If ((Local3 == 0x02))
148
+ {
149
+ Local4 = Package (0x04)
150
+ {
151
+ Zero,
152
+ Zero,
153
+ LNKB,
154
+ Zero
155
+ }
156
+ }
157
+
158
+ If ((Local3 == 0x03))
159
+ {
160
+ Local4 = Package (0x04)
161
+ {
162
+ Zero,
163
+ Zero,
164
+ LNKC,
165
+ Zero
166
+ }
167
+ }
168
+
169
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
170
+ Local4 [One] = (Local1 & 0x03)
171
+ Local0 [Local1] = Local4
172
+ Local1++
173
+ }
174
+
175
+ Return (Local0)
176
+ }
177
+
178
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
179
+ {
180
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
181
+ 0x0000, // Granularity
182
+ 0x0030, // Range Minimum
183
+ 0x0030, // Range Maximum
184
+ 0x0000, // Translation Offset
185
+ 0x0001, // Length
186
+ ,, )
187
+ })
188
+ }
189
+ }
190
+
191
+ Scope (\_SB)
192
+ {
193
+ Device (PC20)
194
+ {
195
+ Name (_UID, 0x20) // _UID: Unique ID
196
+ Name (_BBN, 0x20) // _BBN: BIOS Bus Number
197
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
198
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
199
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
200
+ {
201
+ CreateDWordField (Arg3, Zero, CDW1)
202
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
203
+ {
204
+ CreateDWordField (Arg3, 0x04, CDW2)
205
+ CreateDWordField (Arg3, 0x08, CDW3)
206
+ Local0 = CDW3 /* \_SB_.PC20._OSC.CDW3 */
207
+ Local0 &= 0x1F
208
+ If ((Arg1 != One))
209
+ {
210
+ CDW1 |= 0x08
211
+ }
212
+
213
+ If ((CDW3 != Local0))
214
+ {
215
+ CDW1 |= 0x10
216
+ }
217
+
218
+ CDW3 = Local0
219
+ }
220
+ Else
221
+ {
222
+ CDW1 |= 0x04
223
+ }
224
+
225
+ Return (Arg3)
226
+ }
227
+
228
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
229
+ {
230
+ Local0 = Package (0x80){}
231
+ Local1 = Zero
232
+ While ((Local1 < 0x80))
233
+ {
234
+ Local2 = (Local1 >> 0x02)
235
+ Local3 = ((Local1 + Local2) & 0x03)
236
+ If ((Local3 == Zero))
237
+ {
238
+ Local4 = Package (0x04)
239
+ {
240
+ Zero,
241
+ Zero,
242
+ LNKD,
243
+ Zero
244
+ }
245
+ }
246
+
247
+ If ((Local3 == One))
248
+ {
249
+ Local4 = Package (0x04)
250
+ {
251
+ Zero,
252
+ Zero,
253
+ LNKA,
254
+ Zero
255
+ }
256
+ }
257
+
258
+ If ((Local3 == 0x02))
259
+ {
260
+ Local4 = Package (0x04)
261
+ {
262
+ Zero,
263
+ Zero,
264
+ LNKB,
265
+ Zero
266
+ }
267
+ }
268
+
269
+ If ((Local3 == 0x03))
270
+ {
271
+ Local4 = Package (0x04)
272
+ {
273
+ Zero,
274
+ Zero,
275
+ LNKC,
276
+ Zero
277
+ }
278
+ }
279
+
280
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
281
+ Local4 [One] = (Local1 & 0x03)
282
+ Local0 [Local1] = Local4
283
+ Local1++
284
+ }
285
+
286
+ Return (Local0)
287
+ }
288
+
289
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
290
+ {
291
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
292
+ 0x0000, // Granularity
293
+ 0x0020, // Range Minimum
294
+ 0x0020, // Range Maximum
295
+ 0x0000, // Translation Offset
296
+ 0x0001, // Length
297
+ ,, )
298
+ })
299
+ }
300
+ }
301
+
302
+ Scope (\_SB)
303
+ {
304
+ Device (PC10)
305
+ {
306
+ Name (_UID, 0x10) // _UID: Unique ID
307
+ Name (_BBN, 0x10) // _BBN: BIOS Bus Number
308
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
309
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
310
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
311
+ {
312
+ CreateDWordField (Arg3, Zero, CDW1)
313
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
314
+ {
315
+ CreateDWordField (Arg3, 0x04, CDW2)
316
+ CreateDWordField (Arg3, 0x08, CDW3)
317
+ Local0 = CDW3 /* \_SB_.PC10._OSC.CDW3 */
318
+ Local0 &= 0x1F
319
+ If ((Arg1 != One))
320
+ {
321
+ CDW1 |= 0x08
322
+ }
323
+
324
+ If ((CDW3 != Local0))
325
+ {
326
+ CDW1 |= 0x10
327
+ }
328
+
329
+ CDW3 = Local0
330
+ }
331
+ Else
332
+ {
333
+ CDW1 |= 0x04
334
+ }
335
+
336
+ Return (Arg3)
337
+ }
338
+
339
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
340
+ {
341
+ Local0 = Package (0x80){}
342
+ Local1 = Zero
343
+ While ((Local1 < 0x80))
344
+ {
345
+ Local2 = (Local1 >> 0x02)
346
+ Local3 = ((Local1 + Local2) & 0x03)
347
+ If ((Local3 == Zero))
348
+ {
349
+ Local4 = Package (0x04)
350
+ {
351
+ Zero,
352
+ Zero,
353
+ LNKD,
354
+ Zero
355
+ }
356
+ }
357
+
358
+ If ((Local3 == One))
359
+ {
360
+ Local4 = Package (0x04)
361
+ {
362
+ Zero,
363
+ Zero,
364
+ LNKA,
365
+ Zero
366
+ }
367
+ }
368
+
369
+ If ((Local3 == 0x02))
370
+ {
371
+ Local4 = Package (0x04)
372
+ {
373
+ Zero,
374
+ Zero,
375
+ LNKB,
376
+ Zero
377
+ }
378
+ }
379
+
380
+ If ((Local3 == 0x03))
381
+ {
382
+ Local4 = Package (0x04)
383
+ {
384
+ Zero,
385
+ Zero,
386
+ LNKC,
387
+ Zero
388
+ }
389
+ }
390
+
391
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
392
+ Local4 [One] = (Local1 & 0x03)
393
+ Local0 [Local1] = Local4
394
+ Local1++
395
+ }
396
+
397
+ Return (Local0)
398
+ }
399
+
400
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
401
+ {
402
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
403
+ 0x0000, // Granularity
404
+ 0x0010, // Range Minimum
405
+ 0x0010, // Range Maximum
406
+ 0x0000, // Translation Offset
407
+ 0x0001, // Length
408
+ ,, )
409
+ })
410
+ }
411
+ }
412
+
413
Scope (\_SB.PCI0)
414
{
415
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
416
@@ -XXX,XX +XXX,XX @@
417
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
418
0x0000, // Granularity
419
0x0000, // Range Minimum
420
- 0x00FF, // Range Maximum
421
+ 0x000F, // Range Maximum
422
0x0000, // Translation Offset
423
- 0x0100, // Length
424
+ 0x0010, // Length
425
,, )
426
IO (Decode16,
427
0x0CF8, // Range Minimum
428
@@ -XXX,XX +XXX,XX @@
429
}
430
}
431
432
+ Device (S10)
433
+ {
434
+ Name (_ADR, 0x00020000) // _ADR: Address
435
+ }
436
+
437
+ Device (S18)
438
+ {
439
+ Name (_ADR, 0x00030000) // _ADR: Address
440
+ }
441
+
442
+ Device (S20)
443
+ {
444
+ Name (_ADR, 0x00040000) // _ADR: Address
445
+ }
446
+
447
+ Device (S28)
448
+ {
449
+ Name (_ADR, 0x00050000) // _ADR: Address
450
+ }
451
+
452
Method (PCNT, 0, NotSerialized)
453
{
454
}
455
456
Reviewed-by: Eric Auger <eric.auger@redhat.com>
457
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
458
Message-id: 20211210170415.583179-8-jean-philippe@linaro.org
459
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
460
---
461
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
462
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
463
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
464
3 files changed, 2 deletions(-)
465
466
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
467
index XXXXXXX..XXXXXXX 100644
468
--- a/tests/qtest/bios-tables-test-allowed-diff.h
469
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
470
@@ -XXX,XX +XXX,XX @@
471
/* List of comma-separated changed AML files to ignore */
472
"tests/data/acpi/virt/VIOT",
473
-"tests/data/acpi/q35/DSDT.viot",
474
-"tests/data/acpi/q35/VIOT.viot",
475
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
476
index XXXXXXX..XXXXXXX 100644
477
GIT binary patch
478
literal 9398
479
zcmeHNO>7&-8J*>iv|O&FB}G~Oi$yp||57BBoWHhc5OS9yDTx$CQgH$r;8Idr*-4Q_
480
z5(9Az1F`}niVsB-)<KW7p`g9Br(A2Gm-gmc1N78GFS!;)e2V(MnH_0{q<{#yMgn&C
481
zn|*J-d9yqFhO_H6z19~`FlPL*u<DkZ*}|)JH;X@mF-FI<cPg<fti9tEN*yB^i5czN
482
zNq&q?!OZ;BE3B7{KWzJ-`Tn~f`9?Qj8~2^N8{Oc8J%57{==w%rS#;nOCp*nTr@iZ1
483
zb+?i;JLQUJ=O0?8*>S~D)a>NF1~WVB6^~_B#yhJ`H+JU@=6aXs`?Yv)J2h=N?drcS
484
zeLZ*n<<Bm^n}6`jfBx#u8&(W}1?)}iF9o#mZ~E2+zwdn7yK3AbIzKnxpZ>JRPm3~#
485
z&ICS{+_OayRW-l=Mtk=~uaS3o8z<_udd|(wqg`&JnVPfCe>BUOO`Su3e>pff_^UW%
486
z&JE^NO`)=Amg~iqRB1pPscP?(>#ZuY8GHCmlEvD$9g3%4Db~Dfz2SATnddvrR-Oe^
487
z;s;dJec!hnzi)ri^I6YN9vtkm{^TdUF8h7gX8-<Qe4p)GQ=)AtYx2VcwdLVAEXEjG
488
z^Mj|UHPqkj-LsWuzQem1>F3atdZn=zv3$#RmZzSHN+6-yyU#8cJb=YDilX&sl}vNm
489
znkgAR^O<3kj4if>{ly5fwRfMWuC5=lrlvKPX~i#654Cp}R_d*JS$9laZ$ra6)<ns8
490
zFZy28G%xP(nit&F>LDi%G<tIc=TY=gl$jSD&Uv!Yat~XR46h%rI$!}a%!|xG7u8Zn
491
zeY8_|n=K>xz_v_W8VX$W-Fg-qFWcT}7MCyz{%%{ia7hZ>Law-k6NOr}VI&_48U=2l
492
zwqDKFE8eTwwozDdms#e?x?5a|v>&JF;2_v0L~z5n%BYU^52<*cWuD4|GYUm@1+?))
493
zte^45>Rz)t*<T5V#={r>@t@{%?^i#W{i=HAZ*Dc9y59Va-+#P!jrGs;u38a{fLr`N
494
zvT@rUu>DljxJ?^&Z?-?vyJn3C>3D=qux{Y*bs5|5n)Qmi$TD^Zdn4GU$ocJS2Hh-<
495
z`xPI^^+v0nUVdjMos8k`WGl7hA`{03ju%<lrgAHSpd^DRf-*}_#Ly0mB!LSfVgWcQ
496
z&T$@~G9)JI=hz5m0vkrel+Xy{Oh7pkAu-V!j*W7rY(bO}Q$nMH2`FbGB&N)QaV4<4
497
zo)~9JXiP9=;}NPl<C@MmXG&;XFlFNrsyfFsonxFSp<}vEgsRSQP3O3#b6nSnP}ON_
498
zI!#Tdsp~|j>ckUB>FI=~GokB5sOq#dotCE4(sd$KbtW~PNlj-`*NIToiD#j5J#9^=
499
zt?NXn>YUJYPG~wObe#xQos*i*NloXZt`niEb4t@WrRki~bs|)CI+{*L)9L6s5vn><
500
zn$DD_Go|Z9sOn5>I@6lYw5}7Os&iV?Ij!lO)^#FOb!If38BJ$K*NIToIiu;E(R9w}
501
zIuWWmPiZ<&X*y5oIuWWmF_XaEC!a&Jn$B5WCqh-{X-(&8P3LJ{Cqh-{8P3dyPr@^t
502
zSqL9?X9Uwd3W@23*s~h*tj0X6GZCuHa~kuU#yqDp5vt7d8uPryJg+kms?5hU=3^T3
503
zF`bD}WnSP+=`t5MQ$FJ_2&Q~+BP6E0f^%BVIW6a$o)e+SX~IDBih-7z6{O~7YTy`&
504
zLjy&Cv?7QikV#>n0>>@MV8oK`Gmun34-FKdlm-J8SZSaNlnhir4-FI{S|bfqV8e)V
505
zss<{chX#reE#g=hsKAC%sF6d-Km}BWs!kZFsFpKfpbC@>6rprQGEjt4Ck#|zITHq|
506
zK*>M_l;<P^MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=xY&!axO<
507
zGhv_#lnhirIg<<&q0|Wj6<E%MfhtfkPyyvkGEjt4Ck#|zITHq|K*>M_lrzad5lWpf
508
zP=V!47^ngz0~JutBm+e#b;3XemNQ|X3X}{~Ksl2P6rt1!0~J`#gn=qhGEf2KOfpb}
509
zQYQ>lU^x>8szAv=1(Y+%KoLrvFi?TzOc<yFB?A>u&LjgxD0RX>1(q{mpbC@>R6seC
510
z3>2Z%2?G^a&V+#~P%=;f<xDbAgi<FARA4z12C6{GKn0XD$v_cGoiI>=<xCi;0wn_#
511
zP|hR+MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=rz^3{+q_69%e4
512
z$v_2^Gs!>^N}VuJf#pmXr~)Me6;RG314Srx!axxz28u{EP=u<1B2)}iVZuNaCK;&0
513
zBm-5LFi?dF167!0pbC==RAItE6($T+VUmF=Ofpb~2?JG_Fi?d_2C6X0Kouqo6p_5T
514
zFi=FeV!SiSKoR0H$dH(_Z(*Q_WZ%L-5y`$K14StNmJAdjmWs}HV4<vU_xO+1efmLq
515
zZ;W>N_U)fP6Qy6Nw5mbt9Y(#emWSi66=>tq#xoh#Ue=0qyhxi8ZOUe5y0V7VfPUhp
516
zwX=;ymc+i5%sg9Ja~lZ&8oAV@mHc>&CHP9v4R(jhtT?un;O4e9#pno)Xkh7OWgK&a
517
zyj=3Iv0OuoK_;5rOr5f(Kb~ZXDBO+V`OWYo#_C08imwChQxnjdd?wZLDou8aj;$SD
518
zGDYiA3<$Tu<JnHL(KPOChi#zrR32t83}naR$+ym4P_h?z_5#|cW-nw$XD_sOtE62l
519
zrD3@*)NVyiklt0&yF9%+klsBey&I<Y2E<!f(E8TuJte)z(|ZHyy<^gQVfx}=`q&B5
520
z7nSryp1wGczIaUfVwiq$Fn#<4=@*ssi#+|}K>EdF(l3VTOM~ghPLRH&q%ZOGrGfON
521
zW73zx^yR_y<0nX8R??Sw`tm^f@-gYlNFSp|*<gA{q?Zp5Oe-+l#rmyYmKozi9y=P>
522
zVReJU*h=ZuVXiS$ohTbw-O#v9>(yZbGE|)?8(H1ZIKvV!jWa0>vy!3eMA^vdhQ>`s
523
zuMSg{q3T50$m)j1!HixV<}X9liL#N^4c*tL^y)CF8LCc{jjV3yKAqL8!%SzWI#H%q
524
z=bSrQ&)%JCRttF5g4Zf`6l?y@>PzD7MA^D>wBlcH6r1ucwJ<p0O%rZ?JzIY3-QdmZ
525
zzs|n>`a5r3e|z)wcUaqS>nqFQ-8x}eCF4u`OWUxqst-@1rSmUs%WmKP5e0dcb?e2N
526
z;Z|x*!);VwF|Yuhqs^khqOM!@u*jY!WYldISF(V6`BoNd&6Qfk3>X#SuD^7J>p_D=
527
zBPa51y^_n#=cpOt#Zf$ya$Ae9Mfz56n|<i!a=ELS@)%a{^NIH3SDuN<R~sah1km#P
528
zU@?*f%<rG=4W1wgfi;C?_n|W@%lm$&8YfvNOJodIg&IcIpIJQRHr<+ej11GQ6)&eF
529
z2Lam*jIH}#y0>KnY%4JQfOYS$*uU%f#@$U6`N8I3N-lV?5ErFCdv~xDmu2(wexld4
530
z4v^;aVAT2k6GJ^m*FD(Wqc(Qg^)6a<?}h$zLoj}4;PP!+(O{@!a1y-hoAhF_7!z+6
531
zslpAmNtYbjHrw-~#SPVk_FUf>-Obg6yV`8o$8_`PyJe_;bY5_EMBfBfWU!Q=*9HsG
532
z%_Cda{@_Krr!oHVhv9+y+T5qR8zZ2aZ>5r!$*|f$^U%yBUYfR&B!+EYy_PwL!BeUi
533
zJH^}r3r9Q+B)X@Z)fk=P13w&7x#wBtXTZ)g>WITPg5r&pQc!nmyrmk#S(>>b9xnNr
534
zx_b#v9Xv-Y><Wb%?S^0Xe&<)bbKl_=Z|3C$tf|F<bYzE*mfHB;uC)`q-?buaBe?l?
535
zcLTpK*k<49Z32`K?|nSBMFqxTK^_IE-li2fEGdK~(ZdoKBl6ab4a;Hler#`xvEXJG
536
zb?<E%EZExfX>jcOVhS*0rS~RS1dA#xhkv@Nct@#q?LyeKS<$uFec!bw>{@uu$gZ6a
537
zyVen1i{1BKd%~`D7|m$;U0a<I*3I7%^N%N%lGYdU_GS!gaR8T$NA@GzFi~z`l7hdl
538
zarZy6590|88pi(1zq;V(>38zM0sT&<zX;R5$1w3;`_JMG`;&I&0Y23DMx1%@(w(R9
539
z4M$j;D5J+Gy%fijRQsctzFKf&cv|BAz#YLq3CZJWDdtL4u1u1|mkdcUp7|sxJC+?Y
540
z_@@s`v3j}Q7*z>6X~cwUxUL8G1KT)_XTp!KAbs;vCp{K3&~_X@+ew=-D}v`2MbFV0
541
zQsVsL=rXi-pI*G|iiz;VTCutgUs)hDzV1+4?8KcoP3xROf<M%qC6lgVdpFt4<-|uM
542
z=#rl_b1#YjSIl6Toj2z_hOZcKupkdE(LozC(fN=FY(x|sk)ym|;Rq2E1xJWD%Z!ol
543
Gu>S+TT-130
544
545
literal 0
546
HcmV?d00001
547
548
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
549
index XXXXXXX..XXXXXXX 100644
550
GIT binary patch
551
literal 112
552
zcmWIZ^baXu00LVle`k+i1*eDrX9XZ&1PX!JAex!M0Hgv8m>C3sGzdcgBZCA3T-xBj
553
Q0Zb)W9Hva*zW_`e0M!8s0RR91
554
555
literal 0
556
HcmV?d00001
557
558
--
559
2.25.1
560
561
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
We will need PMC register definitions in accel specific code later.
3
The VIOT blob contains the following:
4
Move all constant definitions to common arm headers so we can reuse
5
them.
6
4
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
5
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
[004h 0004 4] Table Length : 00000058
9
Message-id: 20210916155404.86958-2-agraf@csgraf.de
7
[008h 0008 1] Revision : 00
8
[009h 0009 1] Checksum : 66
9
[00Ah 0010 6] Oem ID : "BOCHS "
10
[010h 0016 8] Oem Table ID : "BXPC "
11
[018h 0024 4] Oem Revision : 00000001
12
[01Ch 0028 4] Asl Compiler ID : "BXPC"
13
[020h 0032 4] Asl Compiler Revision : 00000001
14
15
[024h 0036 2] Node count : 0002
16
[026h 0038 2] Node offset : 0030
17
[028h 0040 8] Reserved : 0000000000000000
18
19
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
20
[031h 0049 1] Reserved : 00
21
[032h 0050 2] Length : 0010
22
23
[034h 0052 2] PCI Segment : 0000
24
[036h 0054 2] PCI BDF number : 0008
25
[038h 0056 8] Reserved : 0000000000000000
26
27
[040h 0064 1] Type : 01 [PCI Range]
28
[041h 0065 1] Reserved : 00
29
[042h 0066 2] Length : 0018
30
31
[044h 0068 4] Endpoint start : 00000000
32
[048h 0072 2] PCI Segment start : 0000
33
[04Ah 0074 2] PCI Segment end : 0000
34
[04Ch 0076 2] PCI BDF start : 0000
35
[04Eh 0078 2] PCI BDF end : 00FF
36
[050h 0080 2] Output node : 0030
37
[052h 0082 6] Reserved : 000000000000
38
39
Acked-by: Ani Sinha <ani@anisinha.ca>
40
Reviewed-by: Eric Auger <eric.auger@redhat.com>
41
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
42
Message-id: 20211210170415.583179-9-jean-philippe@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
44
---
12
target/arm/internals.h | 44 ++++++++++++++++++++++++++++++++++++++++++
45
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
13
target/arm/helper.c | 44 ------------------------------------------
46
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
14
2 files changed, 44 insertions(+), 44 deletions(-)
47
2 files changed, 1 deletion(-)
15
48
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
49
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
17
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
51
--- a/tests/qtest/bios-tables-test-allowed-diff.h
19
+++ b/target/arm/internals.h
52
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
20
@@ -XXX,XX +XXX,XX @@ enum MVEECIState {
53
@@ -1,2 +1 @@
21
/* All other values reserved */
54
/* List of comma-separated changed AML files to ignore */
22
};
55
-"tests/data/acpi/virt/VIOT",
23
56
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
24
+/* Definitions for the PMU registers */
25
+#define PMCRN_MASK 0xf800
26
+#define PMCRN_SHIFT 11
27
+#define PMCRLC 0x40
28
+#define PMCRDP 0x20
29
+#define PMCRX 0x10
30
+#define PMCRD 0x8
31
+#define PMCRC 0x4
32
+#define PMCRP 0x2
33
+#define PMCRE 0x1
34
+/*
35
+ * Mask of PMCR bits writeable by guest (not including WO bits like C, P,
36
+ * which can be written as 1 to trigger behaviour but which stay RAZ).
37
+ */
38
+#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
39
+
40
+#define PMXEVTYPER_P 0x80000000
41
+#define PMXEVTYPER_U 0x40000000
42
+#define PMXEVTYPER_NSK 0x20000000
43
+#define PMXEVTYPER_NSU 0x10000000
44
+#define PMXEVTYPER_NSH 0x08000000
45
+#define PMXEVTYPER_M 0x04000000
46
+#define PMXEVTYPER_MT 0x02000000
47
+#define PMXEVTYPER_EVTCOUNT 0x0000ffff
48
+#define PMXEVTYPER_MASK (PMXEVTYPER_P | PMXEVTYPER_U | PMXEVTYPER_NSK | \
49
+ PMXEVTYPER_NSU | PMXEVTYPER_NSH | \
50
+ PMXEVTYPER_M | PMXEVTYPER_MT | \
51
+ PMXEVTYPER_EVTCOUNT)
52
+
53
+#define PMCCFILTR 0xf8000000
54
+#define PMCCFILTR_M PMXEVTYPER_M
55
+#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M)
56
+
57
+static inline uint32_t pmu_num_counters(CPUARMState *env)
58
+{
59
+ return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
60
+}
61
+
62
+/* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
63
+static inline uint64_t pmu_counter_mask(CPUARMState *env)
64
+{
65
+ return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
66
+}
67
+
68
#endif
69
diff --git a/target/arm/helper.c b/target/arm/helper.c
70
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/helper.c
58
GIT binary patch
72
+++ b/target/arm/helper.c
59
literal 88
73
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
60
zcmWIZ^bd((0D?3pe`k+i1*eDrX9XZ&1PX!JAexE60Hgv8m>C3sGzXN&z`)2L0cSHX
74
REGINFO_SENTINEL
61
I{D-Rq0Q5fy0RR91
75
};
62
76
63
literal 0
77
-/* Definitions for the PMU registers */
64
HcmV?d00001
78
-#define PMCRN_MASK 0xf800
65
79
-#define PMCRN_SHIFT 11
80
-#define PMCRLC 0x40
81
-#define PMCRDP 0x20
82
-#define PMCRX 0x10
83
-#define PMCRD 0x8
84
-#define PMCRC 0x4
85
-#define PMCRP 0x2
86
-#define PMCRE 0x1
87
-/*
88
- * Mask of PMCR bits writeable by guest (not including WO bits like C, P,
89
- * which can be written as 1 to trigger behaviour but which stay RAZ).
90
- */
91
-#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
92
-
93
-#define PMXEVTYPER_P 0x80000000
94
-#define PMXEVTYPER_U 0x40000000
95
-#define PMXEVTYPER_NSK 0x20000000
96
-#define PMXEVTYPER_NSU 0x10000000
97
-#define PMXEVTYPER_NSH 0x08000000
98
-#define PMXEVTYPER_M 0x04000000
99
-#define PMXEVTYPER_MT 0x02000000
100
-#define PMXEVTYPER_EVTCOUNT 0x0000ffff
101
-#define PMXEVTYPER_MASK (PMXEVTYPER_P | PMXEVTYPER_U | PMXEVTYPER_NSK | \
102
- PMXEVTYPER_NSU | PMXEVTYPER_NSH | \
103
- PMXEVTYPER_M | PMXEVTYPER_MT | \
104
- PMXEVTYPER_EVTCOUNT)
105
-
106
-#define PMCCFILTR 0xf8000000
107
-#define PMCCFILTR_M PMXEVTYPER_M
108
-#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M)
109
-
110
-static inline uint32_t pmu_num_counters(CPUARMState *env)
111
-{
112
- return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
113
-}
114
-
115
-/* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
116
-static inline uint64_t pmu_counter_mask(CPUARMState *env)
117
-{
118
- return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
119
-}
120
-
121
typedef struct pm_event {
122
uint16_t number; /* PMEVTYPER.evtCount is 16 bits wide */
123
/* If the event is supported on this CPU (used to generate PMCEID[01]) */
124
--
66
--
125
2.20.1
67
2.25.1
126
68
127
69
diff view generated by jsdifflib