1
The following changes since commit 4c41341af76cfc85b5a6c0f87de4838672ab9f89:
1
Hi; here's the first target-arm pullreq for the 7.0 cycle.
2
2
3
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20201020' into staging (2020-10-20 11:20:36 +0100)
3
thanks
4
-- PMM
5
6
The following changes since commit 76b56fdfc9fa43ec6e5986aee33f108c6c6a511e:
7
8
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2021-12-14 12:46:18 -0800)
4
9
5
are available in the Git repository at:
10
are available in the Git repository at:
6
11
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201020
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211215
8
13
9
for you to fetch changes up to 6358890cb939192f6169fdf7664d903bf9b1d338:
14
for you to fetch changes up to aed176558806674d030a8305d989d4e6a5073359:
10
15
11
tests/tcg/aarch64: Add bti smoke tests (2020-10-20 16:12:02 +0100)
16
tests/acpi: add expected blob for VIOT test on virt machine (2021-12-15 10:35:26 +0000)
12
17
13
----------------------------------------------------------------
18
----------------------------------------------------------------
14
target-arm queue:
19
target-arm queue:
15
* Fix AArch32 SMLAD incorrect setting of Q bit
20
* ITS: error reporting cleanup
16
* AArch32 VCVT fixed-point to float is always round-to-nearest
21
* aspeed: improve documentation
17
* strongarm: Fix 'time to transmit a char' unit comment
22
* Fix STM32F2XX USART data register readout
18
* Restrict APEI tables generation to the 'virt' machine
23
* allow emulated GICv3 to be disabled in non-TCG builds
19
* bcm2835: minor code cleanups
24
* fix exception priority for singlestep, misaligned PC, bp, etc
20
* correctly flush TLBs when TBI is enabled
25
* Correct calculation of tlb range invalidate length
21
* tests/qtest: Add npcm7xx timer test
26
* npcm7xx_emc: fix missing queue_flush
22
* loads-stores.rst: add footnote that clarifies GETPC usage
27
* virt: Add VIOT ACPI table for virtio-iommu
23
* Fix reported EL for mte_check_fail
28
* target/i386: Use assert() to sanity-check b1 in SSE decode
24
* Ignore HCR_EL2.ATA when {E2H,TGE} != 11
29
* Don't include qemu-common unnecessarily
25
* microbit_i2c: Fix coredump when dump-vmstate
26
* nseries: Fix loading kernel image on n8x0 machines
27
* Implement v8.1M low-overhead-loops
28
* linux-user: Support AArch64 BTI
29
30
30
----------------------------------------------------------------
31
----------------------------------------------------------------
31
Emanuele Giuseppe Esposito (1):
32
Alex Bennée (1):
32
loads-stores.rst: add footnote that clarifies GETPC usage
33
hw/intc: clean-up error reporting for failed ITS cmd
33
34
34
Havard Skinnemoen (1):
35
Jean-Philippe Brucker (8):
35
tests/qtest: Add npcm7xx timer test
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
36
44
37
Peng Liang (1):
45
Joel Stanley (4):
38
microbit_i2c: Fix coredump when dump-vmstate
46
docs: aspeed: Add new boards
47
docs: aspeed: Update OpenBMC image URL
48
docs: aspeed: Give an example of booting a kernel
49
docs: aspeed: ADC is now modelled
39
50
40
Peter Maydell (12):
51
Olivier Hériveaux (1):
41
target/arm: Fix SMLAD incorrect setting of Q bit
52
Fix STM32F2XX USART data register readout
42
target/arm: AArch32 VCVT fixed-point to float is always round-to-nearest
43
decodetree: Fix codegen for non-overlapping group inside overlapping group
44
target/arm: Implement v8.1M NOCP handling
45
target/arm: Implement v8.1M conditional-select insns
46
target/arm: Make the t32 insn[25:23]=111 group non-overlapping
47
target/arm: Don't allow BLX imm for M-profile
48
target/arm: Implement v8.1M branch-future insns (as NOPs)
49
target/arm: Implement v8.1M low-overhead-loop instructions
50
target/arm: Fix has_vfp/has_neon ID reg squashing for M-profile
51
target/arm: Allow M-profile CPUs with FP16 to set FPSCR.FP16
52
target/arm: Implement FPSCR.LTPSIZE for M-profile LOB extension
53
53
54
Philippe Mathieu-Daudé (10):
54
Patrick Venture (1):
55
hw/arm/strongarm: Fix 'time to transmit a char' unit comment
55
hw/net: npcm7xx_emc fix missing queue_flush
56
hw/arm: Restrict APEI tables generation to the 'virt' machine
57
hw/timer/bcm2835: Introduce BCM2835_SYSTIMER_COUNT definition
58
hw/timer/bcm2835: Rename variable holding CTRL_STATUS register
59
hw/timer/bcm2835: Support the timer COMPARE registers
60
hw/arm/bcm2835_peripherals: Correctly wire the SYS_timer IRQs
61
hw/intc/bcm2835_ic: Trace GPU/CPU IRQ handlers
62
hw/intc/bcm2836_control: Use IRQ definitions instead of magic numbers
63
hw/arm/nseries: Fix loading kernel image on n8x0 machines
64
linux-user/elfload: Avoid leaking interp_name using GLib memory API
65
56
66
Richard Henderson (16):
57
Peter Maydell (6):
67
accel/tcg: Add tlb_flush_page_bits_by_mmuidx*
58
target/i386: Use assert() to sanity-check b1 in SSE decode
68
target/arm: Use tlb_flush_page_bits_by_mmuidx*
59
include/hw/i386: Don't include qemu-common.h in .h files
69
target/arm: Remove redundant mmu_idx lookup
60
target/hexagon/cpu.h: don't include qemu-common.h
70
target/arm: Fix reported EL for mte_check_fail
61
target/rx/cpu.h: Don't include qemu-common.h
71
target/arm: Ignore HCR_EL2.ATA when {E2H,TGE} != 11
62
hw/arm: Don't include qemu-common.h unnecessarily
72
linux-user/aarch64: Reset btype for signals
63
target/arm: Correct calculation of tlb range invalidate length
73
linux-user: Set PAGE_TARGET_1 for TARGET_PROT_BTI
74
include/elf: Add defines related to GNU property notes for AArch64
75
linux-user/elfload: Fix coding style in load_elf_image
76
linux-user/elfload: Adjust iteration over phdr
77
linux-user/elfload: Move PT_INTERP detection to first loop
78
linux-user/elfload: Use Error for load_elf_image
79
linux-user/elfload: Use Error for load_elf_interp
80
linux-user/elfload: Parse NT_GNU_PROPERTY_TYPE_0 notes
81
linux-user/elfload: Parse GNU_PROPERTY_AARCH64_FEATURE_1_AND
82
tests/tcg/aarch64: Add bti smoke tests
83
64
84
docs/devel/loads-stores.rst | 8 +-
65
Philippe Mathieu-Daudé (2):
85
default-configs/devices/arm-softmmu.mak | 1 -
66
hw/intc/arm_gicv3: Extract gicv3_set_gicv3state from arm_gicv3_cpuif.c
86
include/elf.h | 22 ++
67
hw/intc/arm_gicv3: Introduce CONFIG_ARM_GIC_TCG Kconfig selector
87
include/exec/cpu-all.h | 2 +
88
include/exec/exec-all.h | 36 ++
89
include/hw/timer/bcm2835_systmr.h | 17 +-
90
linux-user/qemu.h | 4 +
91
linux-user/syscall_defs.h | 4 +
92
target/arm/cpu.h | 13 +
93
target/arm/helper.h | 13 +
94
target/arm/internals.h | 9 +-
95
target/arm/m-nocp.decode | 10 +-
96
target/arm/t32.decode | 50 ++-
97
accel/tcg/cputlb.c | 275 +++++++++++++++-
98
hw/arm/bcm2835_peripherals.c | 13 +-
99
hw/arm/nseries.c | 1 +
100
hw/arm/strongarm.c | 2 +-
101
hw/i2c/microbit_i2c.c | 1 +
102
hw/intc/bcm2835_ic.c | 4 +-
103
hw/intc/bcm2836_control.c | 8 +-
104
hw/timer/bcm2835_systmr.c | 57 ++--
105
linux-user/aarch64/signal.c | 10 +-
106
linux-user/elfload.c | 326 ++++++++++++++----
107
linux-user/mmap.c | 16 +
108
target/arm/cpu.c | 38 ++-
109
target/arm/helper.c | 55 +++-
110
target/arm/mte_helper.c | 13 +-
111
target/arm/translate-a64.c | 6 +-
112
target/arm/translate.c | 239 +++++++++++++-
113
target/arm/vfp_helper.c | 76 +++--
114
tests/qtest/npcm7xx_timer-test.c | 562 ++++++++++++++++++++++++++++++++
115
tests/tcg/aarch64/bti-1.c | 62 ++++
116
tests/tcg/aarch64/bti-2.c | 108 ++++++
117
tests/tcg/aarch64/bti-crt.inc.c | 51 +++
118
hw/arm/Kconfig | 1 +
119
hw/intc/trace-events | 4 +
120
hw/timer/trace-events | 6 +-
121
scripts/decodetree.py | 2 +-
122
target/arm/translate-vfp.c.inc | 41 ++-
123
tests/qtest/meson.build | 1 +
124
tests/tcg/aarch64/Makefile.target | 10 +
125
tests/tcg/configure.sh | 4 +
126
42 files changed, 1973 insertions(+), 208 deletions(-)
127
create mode 100644 tests/qtest/npcm7xx_timer-test.c
128
create mode 100644 tests/tcg/aarch64/bti-1.c
129
create mode 100644 tests/tcg/aarch64/bti-2.c
130
create mode 100644 tests/tcg/aarch64/bti-crt.inc.c
131
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
Deleted patch
1
The SMLAD instruction is supposed to:
2
* signed multiply Rn[15:0] * Rm[15:0]
3
* signed multiply Rn[31:16] * Rm[31:16]
4
* perform a signed addition of the products and Ra
5
* set Rd to the low 32 bits of the theoretical
6
infinite-precision result
7
* set the Q flag if the sign-extension of Rd
8
would differ from the infinite-precision result
9
(ie on overflow)
10
1
11
Our current implementation doesn't quite do this, though: it performs
12
an addition of the products setting Q on overflow, and then it adds
13
Ra, again possibly setting Q. This sometimes incorrectly sets Q when
14
the architecturally mandated only-check-for-overflow-once algorithm
15
does not. For instance:
16
r1 = 0x80008000; r2 = 0x80008000; r3 = 0xffffffff
17
smlad r0, r1, r2, r3
18
This is (-32768 * -32768) + (-32768 * -32768) - 1
19
20
The products are both 0x4000_0000, so when added together as 32-bit
21
signed numbers they overflow (and QEMU sets Q), but because the
22
addition of Ra == -1 brings the total back down to 0x7fff_ffff
23
there is no overflow for the complete operation and setting Q is
24
incorrect.
25
26
Fix this edge case by resorting to 64-bit arithmetic for the
27
case where we need to add three values together.
28
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Message-id: 20201009144712.11187-1-peter.maydell@linaro.org
32
---
33
target/arm/translate.c | 58 ++++++++++++++++++++++++++++++++++--------
34
1 file changed, 48 insertions(+), 10 deletions(-)
35
36
diff --git a/target/arm/translate.c b/target/arm/translate.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate.c
39
+++ b/target/arm/translate.c
40
@@ -XXX,XX +XXX,XX @@ static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
41
gen_smul_dual(t1, t2);
42
43
if (sub) {
44
- /* This subtraction cannot overflow. */
45
+ /*
46
+ * This subtraction cannot overflow, so we can do a simple
47
+ * 32-bit subtraction and then a possible 32-bit saturating
48
+ * addition of Ra.
49
+ */
50
tcg_gen_sub_i32(t1, t1, t2);
51
+ tcg_temp_free_i32(t2);
52
+
53
+ if (a->ra != 15) {
54
+ t2 = load_reg(s, a->ra);
55
+ gen_helper_add_setq(t1, cpu_env, t1, t2);
56
+ tcg_temp_free_i32(t2);
57
+ }
58
+ } else if (a->ra == 15) {
59
+ /* Single saturation-checking addition */
60
+ gen_helper_add_setq(t1, cpu_env, t1, t2);
61
+ tcg_temp_free_i32(t2);
62
} else {
63
/*
64
- * This addition cannot overflow 32 bits; however it may
65
- * overflow considered as a signed operation, in which case
66
- * we must set the Q flag.
67
+ * We need to add the products and Ra together and then
68
+ * determine whether the final result overflowed. Doing
69
+ * this as two separate add-and-check-overflow steps incorrectly
70
+ * sets Q for cases like (-32768 * -32768) + (-32768 * -32768) + -1.
71
+ * Do all the arithmetic at 64-bits and then check for overflow.
72
*/
73
- gen_helper_add_setq(t1, cpu_env, t1, t2);
74
- }
75
- tcg_temp_free_i32(t2);
76
+ TCGv_i64 p64, q64;
77
+ TCGv_i32 t3, qf, one;
78
79
- if (a->ra != 15) {
80
- t2 = load_reg(s, a->ra);
81
- gen_helper_add_setq(t1, cpu_env, t1, t2);
82
+ p64 = tcg_temp_new_i64();
83
+ q64 = tcg_temp_new_i64();
84
+ tcg_gen_ext_i32_i64(p64, t1);
85
+ tcg_gen_ext_i32_i64(q64, t2);
86
+ tcg_gen_add_i64(p64, p64, q64);
87
+ load_reg_var(s, t2, a->ra);
88
+ tcg_gen_ext_i32_i64(q64, t2);
89
+ tcg_gen_add_i64(p64, p64, q64);
90
+ tcg_temp_free_i64(q64);
91
+
92
+ tcg_gen_extr_i64_i32(t1, t2, p64);
93
+ tcg_temp_free_i64(p64);
94
+ /*
95
+ * t1 is the low half of the result which goes into Rd.
96
+ * We have overflow and must set Q if the high half (t2)
97
+ * is different from the sign-extension of t1.
98
+ */
99
+ t3 = tcg_temp_new_i32();
100
+ tcg_gen_sari_i32(t3, t1, 31);
101
+ qf = load_cpu_field(QF);
102
+ one = tcg_const_i32(1);
103
+ tcg_gen_movcond_i32(TCG_COND_NE, qf, t2, t3, one, qf);
104
+ store_cpu_field(qf, QF);
105
+ tcg_temp_free_i32(one);
106
+ tcg_temp_free_i32(t3);
107
tcg_temp_free_i32(t2);
108
}
109
store_reg(s, a->rd, t1);
110
--
111
2.20.1
112
113
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Fix an unlikely memory leak in load_elf_image().
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.
4
8
5
Fixes: bf858897b7 ("linux-user: Re-use load_elf_image for the main binary.")
9
I still get a failure with the current kvm-unit-tests but at least I
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
know (partially) why now:
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
8
Message-id: 20201016184207.786698-5-richard.henderson@linaro.org
12
Exception return from AArch64 EL1 to AArch64 EL1 PC 0x40080588
9
Message-Id: <20201003174944.1972444-1-f4bug@amsat.org>
13
PASS: gicv3: its-trigger: inv/invall: dev2/eventid=20 now triggers an LPI
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
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>
11
Reviewed-by: Peter Maydell <peter.maydell@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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
26
---
14
linux-user/elfload.c | 8 ++++----
27
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++++++++++++++------------
15
1 file changed, 4 insertions(+), 4 deletions(-)
28
1 file changed, 27 insertions(+), 12 deletions(-)
16
29
17
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
30
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
18
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
19
--- a/linux-user/elfload.c
32
--- a/hw/intc/arm_gicv3_its.c
20
+++ b/linux-user/elfload.c
33
+++ b/hw/intc/arm_gicv3_its.c
21
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
34
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
22
info->brk = vaddr_em;
35
if (res != MEMTX_OK) {
23
}
36
return result;
24
} else if (eppnt->p_type == PT_INTERP && pinterp_name) {
37
}
25
- char *interp_name;
38
+ } else {
26
+ g_autofree char *interp_name = NULL;
39
+ qemu_log_mask(LOG_GUEST_ERROR,
27
40
+ "%s: invalid command attributes: "
28
if (*pinterp_name) {
41
+ "invalid dte: %"PRIx64" for %d (MEM_TX: %d)\n",
29
errmsg = "Multiple PT_INTERP entries";
42
+ __func__, dte, devid, res);
30
goto exit_errmsg;
43
+ return result;
31
}
32
- interp_name = malloc(eppnt->p_filesz);
33
+ interp_name = g_malloc(eppnt->p_filesz);
34
if (!interp_name) {
35
goto exit_perror;
36
}
37
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
38
errmsg = "Invalid PT_INTERP entry";
39
goto exit_errmsg;
40
}
41
- *pinterp_name = interp_name;
42
+ *pinterp_name = g_steal_pointer(&interp_name);
43
#ifdef TARGET_MIPS
44
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
45
Mips_elf_abiflags_v0 abiflags;
46
@@ -XXX,XX +XXX,XX @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
47
if (elf_interpreter) {
48
info->load_bias = interp_info.load_bias;
49
info->entry = interp_info.entry;
50
- free(elf_interpreter);
51
+ g_free(elf_interpreter);
52
}
44
}
53
45
54
#ifdef USE_ELF_CORE_DUMP
46
- if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
47
- !cte_valid || (eventid > max_eventid)) {
48
+
49
+ /*
50
+ * In this implementation, in case of guest errors we ignore the
51
+ * command and move onto the next command in the queue.
52
+ */
53
+ if (devid > s->dt.maxids.max_devids) {
54
qemu_log_mask(LOG_GUEST_ERROR,
55
- "%s: invalid command attributes "
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);
67
+
68
+ } else if (!dte_valid || !ite_valid || !cte_valid) {
69
+ qemu_log_mask(LOG_GUEST_ERROR,
70
+ "%s: invalid command attributes: "
71
+ "dte: %s, ite: %s, cte: %s\n",
72
+ __func__,
73
+ dte_valid ? "valid" : "invalid",
74
+ ite_valid ? "valid" : "invalid",
75
+ cte_valid ? "valid" : "invalid");
76
+ } else if (eventid > max_eventid) {
77
+ qemu_log_mask(LOG_GUEST_ERROR,
78
+ "%s: invalid command attributes: eventid %d > %d\n",
79
+ __func__, eventid, max_eventid);
80
} else {
81
/*
82
* Current implementation only supports rdbase == procnum
55
--
83
--
56
2.20.1
84
2.25.1
57
85
58
86
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
This is a bit clearer than open-coding some of this
3
Add X11, FP5280G2, G220A, Rainier and Fuji. Mention that Swift will be
4
with a bare c string.
4
removed in v7.0.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20201016184207.786698-9-richard.henderson@linaro.org
8
Message-id: 20211117065752.330632-2-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
linux-user/elfload.c | 37 ++++++++++++++++++++-----------------
11
docs/system/arm/aspeed.rst | 7 ++++++-
12
1 file changed, 20 insertions(+), 17 deletions(-)
12
1 file changed, 6 insertions(+), 1 deletion(-)
13
13
14
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/elfload.c
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/linux-user/elfload.c
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ AST2400 SoC based machines :
19
#include "qemu/guest-random.h"
19
20
#include "qemu/units.h"
20
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
21
#include "qemu/selfmap.h"
21
- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
22
+#include "qapi/error.h"
22
+- ``supermicrox11-bmc`` Supermicro X11 BMC
23
23
24
#ifdef _ARCH_PPC64
24
AST2500 SoC based machines :
25
#undef ARCH_DLINFO
25
26
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
26
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
27
struct elf_phdr *phdr;
27
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
28
abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
28
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
29
int i, retval;
29
- ``sonorapass-bmc`` OCP SonoraPass BMC
30
- const char *errmsg;
30
-- ``swift-bmc`` OpenPOWER Swift BMC POWER9
31
+ Error *err = NULL;
31
+- ``swift-bmc`` OpenPOWER Swift BMC POWER9 (to be removed in v7.0)
32
32
+- ``fp5280g2-bmc`` Inspur FP5280G2 BMC
33
/* First of all, some simple consistency checks */
33
+- ``g220a-bmc`` Bytedance G220A BMC
34
- errmsg = "Invalid ELF image for this architecture";
34
35
if (!elf_check_ident(ehdr)) {
35
AST2600 SoC based machines :
36
+ error_setg(&err, "Invalid ELF image for this architecture");
36
37
goto exit_errmsg;
37
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
38
}
38
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
39
bswap_ehdr(ehdr);
39
+- ``rainier-bmc`` IBM Rainier POWER10 BMC
40
if (!elf_check_ehdr(ehdr)) {
40
+- ``fuji-bmc`` Facebook Fuji BMC
41
+ error_setg(&err, "Invalid ELF image for this architecture");
41
42
goto exit_errmsg;
42
Supported devices
43
}
43
-----------------
44
45
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
46
g_autofree char *interp_name = NULL;
47
48
if (*pinterp_name) {
49
- errmsg = "Multiple PT_INTERP entries";
50
+ error_setg(&err, "Multiple PT_INTERP entries");
51
goto exit_errmsg;
52
}
53
+
54
interp_name = g_malloc(eppnt->p_filesz);
55
- if (!interp_name) {
56
- goto exit_perror;
57
- }
58
59
if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
60
memcpy(interp_name, bprm_buf + eppnt->p_offset,
61
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
62
retval = pread(image_fd, interp_name, eppnt->p_filesz,
63
eppnt->p_offset);
64
if (retval != eppnt->p_filesz) {
65
- goto exit_perror;
66
+ goto exit_read;
67
}
68
}
69
if (interp_name[eppnt->p_filesz - 1] != 0) {
70
- errmsg = "Invalid PT_INTERP entry";
71
+ error_setg(&err, "Invalid PT_INTERP entry");
72
goto exit_errmsg;
73
}
74
*pinterp_name = g_steal_pointer(&interp_name);
75
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
76
(ehdr->e_type == ET_EXEC ? MAP_FIXED : 0),
77
-1, 0);
78
if (load_addr == -1) {
79
- goto exit_perror;
80
+ goto exit_mmap;
81
}
82
load_bias = load_addr - loaddr;
83
84
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
85
image_fd, eppnt->p_offset - vaddr_po);
86
87
if (error == -1) {
88
- goto exit_perror;
89
+ goto exit_mmap;
90
}
91
}
92
93
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
94
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
95
Mips_elf_abiflags_v0 abiflags;
96
if (eppnt->p_filesz < sizeof(Mips_elf_abiflags_v0)) {
97
- errmsg = "Invalid PT_MIPS_ABIFLAGS entry";
98
+ error_setg(&err, "Invalid PT_MIPS_ABIFLAGS entry");
99
goto exit_errmsg;
100
}
101
if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
102
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
103
retval = pread(image_fd, &abiflags, sizeof(Mips_elf_abiflags_v0),
104
eppnt->p_offset);
105
if (retval != sizeof(Mips_elf_abiflags_v0)) {
106
- goto exit_perror;
107
+ goto exit_read;
108
}
109
}
110
bswap_mips_abiflags(&abiflags);
111
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
112
113
exit_read:
114
if (retval >= 0) {
115
- errmsg = "Incomplete read of file header";
116
- goto exit_errmsg;
117
+ error_setg(&err, "Incomplete read of file header");
118
+ } else {
119
+ error_setg_errno(&err, errno, "Error reading file header");
120
}
121
- exit_perror:
122
- errmsg = strerror(errno);
123
+ goto exit_errmsg;
124
+ exit_mmap:
125
+ error_setg_errno(&err, errno, "Error mapping file");
126
+ goto exit_errmsg;
127
exit_errmsg:
128
- fprintf(stderr, "%s: %s\n", image_name, errmsg);
129
+ error_reportf_err(err, "%s: ", image_name);
130
exit(-1);
131
}
132
133
--
44
--
134
2.20.1
45
2.25.1
135
46
136
47
diff view generated by jsdifflib
1
For nested groups like:
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
{
3
This is the latest URL for the OpenBMC CI. The old URL still works, but
4
[
4
redirects.
5
pattern 1
6
pattern 2
7
]
8
pattern 3
9
}
10
5
11
the intended behaviour is that patterns 1 and 2 must not
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
overlap with each other; if the insn matches neither then
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
13
we fall through to pattern 3 as the next thing in the
8
Message-id: 20211117065752.330632-3-joel@jms.id.au
14
outer overlapping group.
15
16
Currently we generate incorrect code for this situation,
17
because in the code path for a failed match inside the
18
inner non-overlapping group we generate a "return" statement,
19
which causes decode to stop entirely rather than continuing
20
to the next thing in the outer group.
21
22
Generate a "break" instead, so that decode flow behaves
23
as required for this nested group case.
24
25
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Message-id: 20201019151301.2046-2-peter.maydell@linaro.org
29
---
10
---
30
scripts/decodetree.py | 2 +-
11
docs/system/arm/aspeed.rst | 2 +-
31
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
32
13
33
diff --git a/scripts/decodetree.py b/scripts/decodetree.py
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
34
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
35
--- a/scripts/decodetree.py
16
--- a/docs/system/arm/aspeed.rst
36
+++ b/scripts/decodetree.py
17
+++ b/docs/system/arm/aspeed.rst
37
@@ -XXX,XX +XXX,XX @@ class Tree:
18
@@ -XXX,XX +XXX,XX @@ The Aspeed machines can be started using the ``-kernel`` option to
38
output(ind, ' /* ',
19
load a Linux kernel or from a firmware. Images can be downloaded from
39
str_match_bits(innerbits, innermask), ' */\n')
20
the OpenBMC jenkins :
40
s.output_code(i + 4, extracted, innerbits, innermask)
21
41
- output(ind, ' return false;\n')
22
- https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/distro=ubuntu,label=docker-builder
42
+ output(ind, ' break;\n')
23
+ https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
43
output(ind, '}\n')
24
44
# end Tree
25
or directly from the OpenBMC GitHub release repository :
45
26
46
--
27
--
47
2.20.1
28
2.25.1
48
29
49
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
Fixing this now will clarify following patches.
3
A common use case for the ASPEED machine is to boot a Linux kernel.
4
Provide a full example command line.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Message-id: 20201016184207.786698-6-richard.henderson@linaro.org
8
Message-id: 20211117065752.330632-4-joel@jms.id.au
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
linux-user/elfload.c | 12 +++++++++---
11
docs/system/arm/aspeed.rst | 15 ++++++++++++---
11
1 file changed, 9 insertions(+), 3 deletions(-)
12
1 file changed, 12 insertions(+), 3 deletions(-)
12
13
13
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/elfload.c
16
--- a/docs/system/arm/aspeed.rst
16
+++ b/linux-user/elfload.c
17
+++ b/docs/system/arm/aspeed.rst
17
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
18
@@ -XXX,XX +XXX,XX @@ Missing devices
18
abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em, vaddr_len;
19
Boot options
19
int elf_prot = 0;
20
------------
20
21
21
- if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
22
-The Aspeed machines can be started using the ``-kernel`` option to
22
- if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
23
-load a Linux kernel or from a firmware. Images can be downloaded from
23
- if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
24
-the OpenBMC jenkins :
24
+ if (eppnt->p_flags & PF_R) {
25
+The Aspeed machines can be started using the ``-kernel`` and ``-dtb`` options
25
+ elf_prot |= PROT_READ;
26
+to load a Linux kernel or from a firmware. Images can be downloaded from the
26
+ }
27
+OpenBMC jenkins :
27
+ if (eppnt->p_flags & PF_W) {
28
28
+ elf_prot |= PROT_WRITE;
29
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
29
+ }
30
30
+ if (eppnt->p_flags & PF_X) {
31
@@ -XXX,XX +XXX,XX @@ or directly from the OpenBMC GitHub release repository :
31
+ elf_prot |= PROT_EXEC;
32
32
+ }
33
https://github.com/openbmc/openbmc/releases
33
34
34
vaddr = load_bias + eppnt->p_vaddr;
35
+To boot a kernel directly from a Linux build tree:
35
vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr);
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
36
--
47
--
37
2.20.1
48
2.25.1
38
49
39
50
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
The time to transmit a char is expressed in nanoseconds, not in ticks.
3
Move it to the supported list.
4
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Message-id: 20201014213601.205222-1-f4bug@amsat.org
6
Message-id: 20211117065752.330632-5-joel@jms.id.au
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
hw/arm/strongarm.c | 2 +-
9
docs/system/arm/aspeed.rst | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
12
11
13
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
12
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/strongarm.c
14
--- a/docs/system/arm/aspeed.rst
16
+++ b/hw/arm/strongarm.c
15
+++ b/docs/system/arm/aspeed.rst
17
@@ -XXX,XX +XXX,XX @@ struct StrongARMUARTState {
16
@@ -XXX,XX +XXX,XX @@ Supported devices
18
uint8_t rx_start;
17
* Front LEDs (PCA9552 on I2C bus)
19
uint8_t rx_len;
18
* LPC Peripheral Controller (a subset of subdevices are supported)
20
19
* Hash/Crypto Engine (HACE) - Hash support only. TODO: HMAC and RSA
21
- uint64_t char_transmit_time; /* time to transmit a char in ticks*/
20
+ * ADC
22
+ uint64_t char_transmit_time; /* time to transmit a char in nanoseconds */
21
23
bool wait_break_end;
22
24
QEMUTimer *rx_timeout_timer;
23
Missing devices
25
QEMUTimer *tx_timer;
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
26
--
31
--
27
2.20.1
32
2.25.1
28
33
29
34
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
2
2
3
These are all of the defines required to parse
3
Fix issue where the data register may be overwritten by next character
4
GNU_PROPERTY_AARCH64_FEATURE_1_AND, copied from binutils.
4
reception before being read and returned.
5
Other missing defines related to other GNU program headers
6
and notes are elided for now.
7
5
6
Signed-off-by: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20201016184207.786698-4-richard.henderson@linaro.org
9
Message-id: 20211128120723.4053-1-olivier.heriveaux@ledger.fr
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
include/elf.h | 22 ++++++++++++++++++++++
12
hw/char/stm32f2xx_usart.c | 3 ++-
14
1 file changed, 22 insertions(+)
13
1 file changed, 2 insertions(+), 1 deletion(-)
15
14
16
diff --git a/include/elf.h b/include/elf.h
15
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/elf.h
17
--- a/hw/char/stm32f2xx_usart.c
19
+++ b/include/elf.h
18
+++ b/hw/char/stm32f2xx_usart.c
20
@@ -XXX,XX +XXX,XX @@ typedef int64_t Elf64_Sxword;
19
@@ -XXX,XX +XXX,XX @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
21
#define PT_NOTE 4
20
return retvalue;
22
#define PT_SHLIB 5
21
case USART_DR:
23
#define PT_PHDR 6
22
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
24
+#define PT_LOOS 0x60000000
23
+ retvalue = s->usart_dr & 0x3FF;
25
+#define PT_HIOS 0x6fffffff
24
s->usart_sr &= ~USART_SR_RXNE;
26
#define PT_LOPROC 0x70000000
25
qemu_chr_fe_accept_input(&s->chr);
27
#define PT_HIPROC 0x7fffffff
26
qemu_set_irq(s->irq, 0);
28
27
- return s->usart_dr & 0x3FF;
29
+#define PT_GNU_PROPERTY (PT_LOOS + 0x474e553)
28
+ return retvalue;
30
+
29
case USART_BRR:
31
#define PT_MIPS_REGINFO 0x70000000
30
return s->usart_brr;
32
#define PT_MIPS_RTPROC 0x70000001
31
case USART_CR1:
33
#define PT_MIPS_OPTIONS 0x70000002
34
@@ -XXX,XX +XXX,XX @@ typedef struct elf64_shdr {
35
#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
36
#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension regs */
37
38
+/* Defined note types for GNU systems. */
39
+
40
+#define NT_GNU_PROPERTY_TYPE_0 5 /* Program property */
41
+
42
+/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */
43
+
44
+#define GNU_PROPERTY_STACK_SIZE 1
45
+#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
46
+
47
+#define GNU_PROPERTY_LOPROC 0xc0000000
48
+#define GNU_PROPERTY_HIPROC 0xdfffffff
49
+#define GNU_PROPERTY_LOUSER 0xe0000000
50
+#define GNU_PROPERTY_HIUSER 0xffffffff
51
+
52
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
53
+#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1u << 0)
54
+#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1u << 1)
55
+
56
/*
57
* Physical entry point into the kernel.
58
*
59
--
32
--
60
2.20.1
33
2.25.1
61
34
62
35
diff view generated by jsdifflib
1
From: Havard Skinnemoen <hskinnemoen@google.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This test exercises the various modes of the npcm7xx timer. In
3
gicv3_set_gicv3state() is used by arm_gicv3_common.c in
4
particular, it triggers the bug found by the fuzzer, as reported here:
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
https://lists.gnu.org/archive/html/qemu-devel/2020-09/msg02992.html
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
It also found several other bugs, especially related to interrupt
11
Message-id: 20211115223619.2599282-2-philmd@redhat.com
9
handling.
10
11
The test exercises all the timers in all the timer modules, which
12
expands to 180 test cases in total.
13
14
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
15
Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com>
16
Message-id: 20201008232154.94221-2-hskinnemoen@google.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
13
---
19
tests/qtest/npcm7xx_timer-test.c | 562 +++++++++++++++++++++++++++++++
14
hw/intc/arm_gicv3_cpuif.c | 10 +---------
20
tests/qtest/meson.build | 1 +
15
hw/intc/arm_gicv3_cpuif_common.c | 22 ++++++++++++++++++++++
21
2 files changed, 563 insertions(+)
16
hw/intc/meson.build | 1 +
22
create mode 100644 tests/qtest/npcm7xx_timer-test.c
17
3 files changed, 24 insertions(+), 9 deletions(-)
18
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
23
19
24
diff --git a/tests/qtest/npcm7xx_timer-test.c b/tests/qtest/npcm7xx_timer-test.c
20
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/arm_gicv3_cpuif.c
23
+++ b/hw/intc/arm_gicv3_cpuif.c
24
@@ -XXX,XX +XXX,XX @@
25
/*
26
- * ARM Generic Interrupt Controller v3
27
+ * ARM Generic Interrupt Controller v3 (emulation)
28
*
29
* Copyright (c) 2016 Linaro Limited
30
* Written by Peter Maydell
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/irq.h"
33
#include "cpu.h"
34
35
-void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
36
-{
37
- ARMCPU *arm_cpu = ARM_CPU(cpu);
38
- CPUARMState *env = &arm_cpu->env;
39
-
40
- env->gicv3state = (void *)s;
41
-};
42
-
43
static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
44
{
45
return env->gicv3state;
46
diff --git a/hw/intc/arm_gicv3_cpuif_common.c b/hw/intc/arm_gicv3_cpuif_common.c
25
new file mode 100644
47
new file mode 100644
26
index XXXXXXX..XXXXXXX
48
index XXXXXXX..XXXXXXX
27
--- /dev/null
49
--- /dev/null
28
+++ b/tests/qtest/npcm7xx_timer-test.c
50
+++ b/hw/intc/arm_gicv3_cpuif_common.c
29
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
52
+/* SPDX-License-Identifier: GPL-2.0-or-later */
30
+/*
53
+/*
31
+ * QTest testcase for the Nuvoton NPCM7xx Timer
54
+ * ARM Generic Interrupt Controller v3
32
+ *
55
+ *
33
+ * Copyright 2020 Google LLC
56
+ * Copyright (c) 2016 Linaro Limited
57
+ * Written by Peter Maydell
34
+ *
58
+ *
35
+ * This program is free software; you can redistribute it and/or modify it
59
+ * This code is licensed under the GPL, version 2 or (at your option)
36
+ * under the terms of the GNU General Public License as published by the
60
+ * any later version.
37
+ * Free Software Foundation; either version 2 of the License, or
38
+ * (at your option) any later version.
39
+ *
40
+ * This program is distributed in the hope that it will be useful, but WITHOUT
41
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
42
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
43
+ * for more details.
44
+ */
61
+ */
45
+
62
+
46
+#include "qemu/osdep.h"
63
+#include "qemu/osdep.h"
47
+#include "qemu/timer.h"
64
+#include "gicv3_internal.h"
48
+#include "libqtest-single.h"
65
+#include "cpu.h"
49
+
66
+
50
+#define TIM_REF_HZ (25000000)
67
+void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
68
+{
69
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
70
+ CPUARMState *env = &arm_cpu->env;
51
+
71
+
52
+/* Bits in TCSRx */
72
+ env->gicv3state = (void *)s;
53
+#define CEN BIT(30)
54
+#define IE BIT(29)
55
+#define MODE_ONESHOT (0 << 27)
56
+#define MODE_PERIODIC (1 << 27)
57
+#define CRST BIT(26)
58
+#define CACT BIT(25)
59
+#define PRESCALE(x) (x)
60
+
61
+/* Registers shared between all timers in a module. */
62
+#define TISR 0x18
63
+#define WTCR 0x1c
64
+# define WTCLK(x) ((x) << 10)
65
+
66
+/* Power-on default; used to re-initialize timers before each test. */
67
+#define TCSR_DEFAULT PRESCALE(5)
68
+
69
+/* Register offsets for a timer within a timer block. */
70
+typedef struct Timer {
71
+ unsigned int tcsr_offset;
72
+ unsigned int ticr_offset;
73
+ unsigned int tdr_offset;
74
+} Timer;
75
+
76
+/* A timer block containing 5 timers. */
77
+typedef struct TimerBlock {
78
+ int irq_base;
79
+ uint64_t base_addr;
80
+} TimerBlock;
81
+
82
+/* Testdata for testing a particular timer within a timer block. */
83
+typedef struct TestData {
84
+ const TimerBlock *tim;
85
+ const Timer *timer;
86
+} TestData;
87
+
88
+const TimerBlock timer_block[] = {
89
+ {
90
+ .irq_base = 32,
91
+ .base_addr = 0xf0008000,
92
+ },
93
+ {
94
+ .irq_base = 37,
95
+ .base_addr = 0xf0009000,
96
+ },
97
+ {
98
+ .irq_base = 42,
99
+ .base_addr = 0xf000a000,
100
+ },
101
+};
73
+};
102
+
74
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
103
+const Timer timer[] = {
104
+ {
105
+ .tcsr_offset = 0x00,
106
+ .ticr_offset = 0x08,
107
+ .tdr_offset = 0x10,
108
+ }, {
109
+ .tcsr_offset = 0x04,
110
+ .ticr_offset = 0x0c,
111
+ .tdr_offset = 0x14,
112
+ }, {
113
+ .tcsr_offset = 0x20,
114
+ .ticr_offset = 0x28,
115
+ .tdr_offset = 0x30,
116
+ }, {
117
+ .tcsr_offset = 0x24,
118
+ .ticr_offset = 0x2c,
119
+ .tdr_offset = 0x34,
120
+ }, {
121
+ .tcsr_offset = 0x40,
122
+ .ticr_offset = 0x48,
123
+ .tdr_offset = 0x50,
124
+ },
125
+};
126
+
127
+/* Returns the index of the timer block. */
128
+static int tim_index(const TimerBlock *tim)
129
+{
130
+ ptrdiff_t diff = tim - timer_block;
131
+
132
+ g_assert(diff >= 0 && diff < ARRAY_SIZE(timer_block));
133
+
134
+ return diff;
135
+}
136
+
137
+/* Returns the index of a timer within a timer block. */
138
+static int timer_index(const Timer *t)
139
+{
140
+ ptrdiff_t diff = t - timer;
141
+
142
+ g_assert(diff >= 0 && diff < ARRAY_SIZE(timer));
143
+
144
+ return diff;
145
+}
146
+
147
+/* Returns the irq line for a given timer. */
148
+static int tim_timer_irq(const TestData *td)
149
+{
150
+ return td->tim->irq_base + timer_index(td->timer);
151
+}
152
+
153
+/* Register read/write accessors. */
154
+
155
+static void tim_write(const TestData *td,
156
+ unsigned int offset, uint32_t value)
157
+{
158
+ writel(td->tim->base_addr + offset, value);
159
+}
160
+
161
+static uint32_t tim_read(const TestData *td, unsigned int offset)
162
+{
163
+ return readl(td->tim->base_addr + offset);
164
+}
165
+
166
+static void tim_write_tcsr(const TestData *td, uint32_t value)
167
+{
168
+ tim_write(td, td->timer->tcsr_offset, value);
169
+}
170
+
171
+static uint32_t tim_read_tcsr(const TestData *td)
172
+{
173
+ return tim_read(td, td->timer->tcsr_offset);
174
+}
175
+
176
+static void tim_write_ticr(const TestData *td, uint32_t value)
177
+{
178
+ tim_write(td, td->timer->ticr_offset, value);
179
+}
180
+
181
+static uint32_t tim_read_ticr(const TestData *td)
182
+{
183
+ return tim_read(td, td->timer->ticr_offset);
184
+}
185
+
186
+static uint32_t tim_read_tdr(const TestData *td)
187
+{
188
+ return tim_read(td, td->timer->tdr_offset);
189
+}
190
+
191
+/* Returns the number of nanoseconds to count the given number of cycles. */
192
+static int64_t tim_calculate_step(uint32_t count, uint32_t prescale)
193
+{
194
+ return (1000000000LL / TIM_REF_HZ) * count * (prescale + 1);
195
+}
196
+
197
+/* Returns a bitmask corresponding to the timer under test. */
198
+static uint32_t tim_timer_bit(const TestData *td)
199
+{
200
+ return BIT(timer_index(td->timer));
201
+}
202
+
203
+/* Resets all timers to power-on defaults. */
204
+static void tim_reset(const TestData *td)
205
+{
206
+ int i, j;
207
+
208
+ /* Reset all the timers, in case a previous test left a timer running. */
209
+ for (i = 0; i < ARRAY_SIZE(timer_block); i++) {
210
+ for (j = 0; j < ARRAY_SIZE(timer); j++) {
211
+ writel(timer_block[i].base_addr + timer[j].tcsr_offset,
212
+ CRST | TCSR_DEFAULT);
213
+ }
214
+ writel(timer_block[i].base_addr + TISR, -1);
215
+ }
216
+}
217
+
218
+/* Verifies the reset state of a timer. */
219
+static void test_reset(gconstpointer test_data)
220
+{
221
+ const TestData *td = test_data;
222
+
223
+ tim_reset(td);
224
+
225
+ g_assert_cmphex(tim_read_tcsr(td), ==, TCSR_DEFAULT);
226
+ g_assert_cmphex(tim_read_ticr(td), ==, 0);
227
+ g_assert_cmphex(tim_read_tdr(td), ==, 0);
228
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
229
+ g_assert_cmphex(tim_read(td, WTCR), ==, WTCLK(1));
230
+}
231
+
232
+/* Verifies that CRST wins if both CEN and CRST are set. */
233
+static void test_reset_overrides_enable(gconstpointer test_data)
234
+{
235
+ const TestData *td = test_data;
236
+
237
+ tim_reset(td);
238
+
239
+ /* CRST should force CEN to 0 */
240
+ tim_write_tcsr(td, CEN | CRST | TCSR_DEFAULT);
241
+
242
+ g_assert_cmphex(tim_read_tcsr(td), ==, TCSR_DEFAULT);
243
+ g_assert_cmphex(tim_read_tdr(td), ==, 0);
244
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
245
+}
246
+
247
+/* Verifies the behavior when CEN is set and then cleared. */
248
+static void test_oneshot_enable_then_disable(gconstpointer test_data)
249
+{
250
+ const TestData *td = test_data;
251
+
252
+ tim_reset(td);
253
+
254
+ /* Enable the timer with zero initial count, then disable it again. */
255
+ tim_write_tcsr(td, CEN | TCSR_DEFAULT);
256
+ tim_write_tcsr(td, TCSR_DEFAULT);
257
+
258
+ g_assert_cmphex(tim_read_tcsr(td), ==, TCSR_DEFAULT);
259
+ g_assert_cmphex(tim_read_tdr(td), ==, 0);
260
+ /* Timer interrupt flag should be set, but interrupts are not enabled. */
261
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
262
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
263
+}
264
+
265
+/* Verifies that a one-shot timer fires when expected with prescaler 5. */
266
+static void test_oneshot_ps5(gconstpointer test_data)
267
+{
268
+ const TestData *td = test_data;
269
+ unsigned int count = 256;
270
+ unsigned int ps = 5;
271
+
272
+ tim_reset(td);
273
+
274
+ tim_write_ticr(td, count);
275
+ tim_write_tcsr(td, CEN | PRESCALE(ps));
276
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
277
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
278
+
279
+ clock_step(tim_calculate_step(count, ps) - 1);
280
+
281
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
282
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
283
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
284
+
285
+ clock_step(1);
286
+
287
+ g_assert_cmphex(tim_read_tcsr(td), ==, PRESCALE(ps));
288
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
289
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
290
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
291
+
292
+ /* Clear the interrupt flag. */
293
+ tim_write(td, TISR, tim_timer_bit(td));
294
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
295
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
296
+
297
+ /* Verify that this isn't a periodic timer. */
298
+ clock_step(2 * tim_calculate_step(count, ps));
299
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
300
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
301
+}
302
+
303
+/* Verifies that a one-shot timer fires when expected with prescaler 0. */
304
+static void test_oneshot_ps0(gconstpointer test_data)
305
+{
306
+ const TestData *td = test_data;
307
+ unsigned int count = 1;
308
+ unsigned int ps = 0;
309
+
310
+ tim_reset(td);
311
+
312
+ tim_write_ticr(td, count);
313
+ tim_write_tcsr(td, CEN | PRESCALE(ps));
314
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
315
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
316
+
317
+ clock_step(tim_calculate_step(count, ps) - 1);
318
+
319
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
320
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
321
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
322
+
323
+ clock_step(1);
324
+
325
+ g_assert_cmphex(tim_read_tcsr(td), ==, PRESCALE(ps));
326
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
327
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
328
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
329
+}
330
+
331
+/* Verifies that a one-shot timer fires when expected with highest prescaler. */
332
+static void test_oneshot_ps255(gconstpointer test_data)
333
+{
334
+ const TestData *td = test_data;
335
+ unsigned int count = (1U << 24) - 1;
336
+ unsigned int ps = 255;
337
+
338
+ tim_reset(td);
339
+
340
+ tim_write_ticr(td, count);
341
+ tim_write_tcsr(td, CEN | PRESCALE(ps));
342
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
343
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
344
+
345
+ clock_step(tim_calculate_step(count, ps) - 1);
346
+
347
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
348
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
349
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
350
+
351
+ clock_step(1);
352
+
353
+ g_assert_cmphex(tim_read_tcsr(td), ==, PRESCALE(ps));
354
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
355
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
356
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
357
+}
358
+
359
+/* Verifies that a oneshot timer fires an interrupt when expected. */
360
+static void test_oneshot_interrupt(gconstpointer test_data)
361
+{
362
+ const TestData *td = test_data;
363
+ unsigned int count = 256;
364
+ unsigned int ps = 7;
365
+
366
+ tim_reset(td);
367
+
368
+ tim_write_ticr(td, count);
369
+ tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
370
+
371
+ clock_step_next();
372
+
373
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
374
+ g_assert_true(qtest_get_irq(global_qtest, tim_timer_irq(td)));
375
+}
376
+
377
+/*
378
+ * Verifies that the timer can be paused and later resumed, and it still fires
379
+ * at the right moment.
380
+ */
381
+static void test_pause_resume(gconstpointer test_data)
382
+{
383
+ const TestData *td = test_data;
384
+ unsigned int count = 256;
385
+ unsigned int ps = 1;
386
+
387
+ tim_reset(td);
388
+
389
+ tim_write_ticr(td, count);
390
+ tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
391
+
392
+ /* Pause the timer halfway to expiration. */
393
+ clock_step(tim_calculate_step(count / 2, ps));
394
+ tim_write_tcsr(td, IE | MODE_ONESHOT | PRESCALE(ps));
395
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
396
+
397
+ /* Counter should not advance during the following step. */
398
+ clock_step(2 * tim_calculate_step(count, ps));
399
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
400
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
401
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
402
+
403
+ /* Resume the timer and run _almost_ to expiration. */
404
+ tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
405
+ clock_step(tim_calculate_step(count / 2, ps) - 1);
406
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
407
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
408
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
409
+
410
+ /* Now, run the rest of the way and verify that the interrupt fires. */
411
+ clock_step(1);
412
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
413
+ g_assert_true(qtest_get_irq(global_qtest, tim_timer_irq(td)));
414
+}
415
+
416
+/* Verifies that the prescaler can be changed while the timer is runnin. */
417
+static void test_prescaler_change(gconstpointer test_data)
418
+{
419
+ const TestData *td = test_data;
420
+ unsigned int count = 256;
421
+ unsigned int ps = 5;
422
+
423
+ tim_reset(td);
424
+
425
+ tim_write_ticr(td, count);
426
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
427
+
428
+ /* Run a quarter of the way, and change the prescaler. */
429
+ clock_step(tim_calculate_step(count / 4, ps));
430
+ g_assert_cmpuint(tim_read_tdr(td), ==, 3 * count / 4);
431
+ ps = 2;
432
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
433
+ /* The counter must not change. */
434
+ g_assert_cmpuint(tim_read_tdr(td), ==, 3 * count / 4);
435
+
436
+ /* Run another quarter of the way, and change the prescaler again. */
437
+ clock_step(tim_calculate_step(count / 4, ps));
438
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
439
+ ps = 8;
440
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
441
+ /* The counter must not change. */
442
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
443
+
444
+ /* Run another quarter of the way, and change the prescaler again. */
445
+ clock_step(tim_calculate_step(count / 4, ps));
446
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 4);
447
+ ps = 0;
448
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
449
+ /* The counter must not change. */
450
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 4);
451
+
452
+ /* Run almost to expiration, and verify the timer didn't fire yet. */
453
+ clock_step(tim_calculate_step(count / 4, ps) - 1);
454
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
455
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
456
+
457
+ /* Now, run the rest of the way and verify that the timer fires. */
458
+ clock_step(1);
459
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
460
+}
461
+
462
+/* Verifies that a periodic timer automatically restarts after expiration. */
463
+static void test_periodic_no_interrupt(gconstpointer test_data)
464
+{
465
+ const TestData *td = test_data;
466
+ unsigned int count = 2;
467
+ unsigned int ps = 3;
468
+ int i;
469
+
470
+ tim_reset(td);
471
+
472
+ tim_write_ticr(td, count);
473
+ tim_write_tcsr(td, CEN | MODE_PERIODIC | PRESCALE(ps));
474
+
475
+ for (i = 0; i < 4; i++) {
476
+ clock_step_next();
477
+
478
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
479
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
480
+
481
+ tim_write(td, TISR, tim_timer_bit(td));
482
+
483
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
484
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
485
+ }
486
+}
487
+
488
+/* Verifies that a periodict timer fires an interrupt every time it expires. */
489
+static void test_periodic_interrupt(gconstpointer test_data)
490
+{
491
+ const TestData *td = test_data;
492
+ unsigned int count = 65535;
493
+ unsigned int ps = 2;
494
+ int i;
495
+
496
+ tim_reset(td);
497
+
498
+ tim_write_ticr(td, count);
499
+ tim_write_tcsr(td, CEN | IE | MODE_PERIODIC | PRESCALE(ps));
500
+
501
+ for (i = 0; i < 4; i++) {
502
+ clock_step_next();
503
+
504
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
505
+ g_assert_true(qtest_get_irq(global_qtest, tim_timer_irq(td)));
506
+
507
+ tim_write(td, TISR, tim_timer_bit(td));
508
+
509
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
510
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
511
+ }
512
+}
513
+
514
+/*
515
+ * Verifies that the timer behaves correctly when disabled right before and
516
+ * exactly when it's supposed to expire.
517
+ */
518
+static void test_disable_on_expiration(gconstpointer test_data)
519
+{
520
+ const TestData *td = test_data;
521
+ unsigned int count = 8;
522
+ unsigned int ps = 255;
523
+
524
+ tim_reset(td);
525
+
526
+ tim_write_ticr(td, count);
527
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
528
+
529
+ clock_step(tim_calculate_step(count, ps) - 1);
530
+
531
+ tim_write_tcsr(td, MODE_ONESHOT | PRESCALE(ps));
532
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
533
+ clock_step(1);
534
+ tim_write_tcsr(td, MODE_ONESHOT | PRESCALE(ps));
535
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
536
+}
537
+
538
+/*
539
+ * Constructs a name that includes the timer block, timer and testcase name,
540
+ * and adds the test to the test suite.
541
+ */
542
+static void tim_add_test(const char *name, const TestData *td, GTestDataFunc fn)
543
+{
544
+ g_autofree char *full_name;
545
+
546
+ full_name = g_strdup_printf("npcm7xx_timer/tim[%d]/timer[%d]/%s",
547
+ tim_index(td->tim), timer_index(td->timer),
548
+ name);
549
+ qtest_add_data_func(full_name, td, fn);
550
+}
551
+
552
+/* Convenience macro for adding a test with a predictable function name. */
553
+#define add_test(name, td) tim_add_test(#name, td, test_##name)
554
+
555
+int main(int argc, char **argv)
556
+{
557
+ TestData testdata[ARRAY_SIZE(timer_block) * ARRAY_SIZE(timer)];
558
+ int ret;
559
+ int i, j;
560
+
561
+ g_test_init(&argc, &argv, NULL);
562
+ g_test_set_nonfatal_assertions();
563
+
564
+ for (i = 0; i < ARRAY_SIZE(timer_block); i++) {
565
+ for (j = 0; j < ARRAY_SIZE(timer); j++) {
566
+ TestData *td = &testdata[i * ARRAY_SIZE(timer) + j];
567
+ td->tim = &timer_block[i];
568
+ td->timer = &timer[j];
569
+
570
+ add_test(reset, td);
571
+ add_test(reset_overrides_enable, td);
572
+ add_test(oneshot_enable_then_disable, td);
573
+ add_test(oneshot_ps5, td);
574
+ add_test(oneshot_ps0, td);
575
+ add_test(oneshot_ps255, td);
576
+ add_test(oneshot_interrupt, td);
577
+ add_test(pause_resume, td);
578
+ add_test(prescaler_change, td);
579
+ add_test(periodic_no_interrupt, td);
580
+ add_test(periodic_interrupt, td);
581
+ add_test(disable_on_expiration, td);
582
+ }
583
+ }
584
+
585
+ qtest_start("-machine npcm750-evb");
586
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/a9mpcore/gic");
587
+ ret = g_test_run();
588
+ qtest_end();
589
+
590
+ return ret;
591
+}
592
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
593
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
594
--- a/tests/qtest/meson.build
76
--- a/hw/intc/meson.build
595
+++ b/tests/qtest/meson.build
77
+++ b/hw/intc/meson.build
596
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
78
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
597
['arm-cpu-features',
79
598
'microbit-test',
80
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
599
'm25p80-test',
81
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
600
+ 'npcm7xx_timer-test',
82
+specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
601
'test-arm-mptimer',
83
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
602
'boot-serial-test',
84
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
603
'hexloader-test']
85
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
604
--
86
--
605
2.20.1
87
2.25.1
606
88
607
89
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Commit 7998beb9c2e removed the ram_size initialization in the
3
The TYPE_ARM_GICV3 device is an emulated one. When using
4
arm_boot_info structure, however it is used by arm_load_kernel().
4
KVM, it is recommended to use the TYPE_KVM_ARM_GICV3 device
5
(which uses in-kernel support).
5
6
6
Initialize the field to fix:
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.
7
11
8
$ qemu-system-arm -M n800 -append 'console=ttyS1' \
12
Therefore introduce the CONFIG_ARM_GIC_TCG Kconfig selector
9
-kernel meego-arm-n8x0-1.0.80.20100712.1431-vmlinuz-2.6.35~rc4-129.1-n8x0
13
which select the files required to have the TYPE_ARM_GICV3
10
qemu-system-arm: kernel 'meego-arm-n8x0-1.0.80.20100712.1431-vmlinuz-2.6.35~rc4-129.1-n8x0' is too large to fit in RAM (kernel size 1964608, RAM size 0)
14
device, but also allowing to de-select this device.
11
15
12
Noticed while running the test introduced in commit 050a82f0c5b
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
("tests/acceptance: Add a test for the N800 and N810 arm machines").
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
18
Message-id: 20211115223619.2599282-3-philmd@redhat.com
15
Fixes: 7998beb9c2e ("arm/nseries: use memdev for RAM")
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Tested-by: Thomas Huth <thuth@redhat.com>
19
Message-id: 20201019095148.1602119-1-f4bug@amsat.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
20
---
22
hw/arm/nseries.c | 1 +
21
hw/intc/arm_gicv3.c | 2 +-
23
1 file changed, 1 insertion(+)
22
hw/intc/Kconfig | 5 +++++
23
hw/intc/meson.build | 10 ++++++----
24
3 files changed, 12 insertions(+), 5 deletions(-)
24
25
25
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
26
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
26
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/nseries.c
28
--- a/hw/intc/arm_gicv3.c
28
+++ b/hw/arm/nseries.c
29
+++ b/hw/intc/arm_gicv3.c
29
@@ -XXX,XX +XXX,XX @@ static void n8x0_init(MachineState *machine,
30
@@ -XXX,XX +XXX,XX @@
30
g_free(sz);
31
/*
31
exit(EXIT_FAILURE);
32
- * ARM Generic Interrupt Controller v3
32
}
33
+ * ARM Generic Interrupt Controller v3 (emulation)
33
+ binfo->ram_size = machine->ram_size;
34
*
34
35
* Copyright (c) 2015 Huawei.
35
memory_region_add_subregion(get_system_memory(), OMAP2_Q2_BASE,
36
* Copyright (c) 2016 Linaro Limited
36
machine->ram);
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'))
37
--
84
--
38
2.20.1
85
2.25.1
39
86
40
87
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Transform the prot bit to a qemu internal page bit, and save
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
it in the page tables.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201016184207.786698-3-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
6
---
11
include/exec/cpu-all.h | 2 ++
7
target/arm/translate-a64.c | 7 ++++---
12
linux-user/syscall_defs.h | 4 ++++
8
1 file changed, 4 insertions(+), 3 deletions(-)
13
target/arm/cpu.h | 5 +++++
14
linux-user/mmap.c | 16 ++++++++++++++++
15
target/arm/translate-a64.c | 6 +++---
16
5 files changed, 30 insertions(+), 3 deletions(-)
17
9
18
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/exec/cpu-all.h
21
+++ b/include/exec/cpu-all.h
22
@@ -XXX,XX +XXX,XX @@ extern intptr_t qemu_host_page_mask;
23
/* FIXME: Code that sets/uses this is broken and needs to go away. */
24
#define PAGE_RESERVED 0x0020
25
#endif
26
+/* Target-specific bits that will be used via page_get_flags(). */
27
+#define PAGE_TARGET_1 0x0080
28
29
#if defined(CONFIG_USER_ONLY)
30
void page_dump(FILE *f);
31
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/linux-user/syscall_defs.h
34
+++ b/linux-user/syscall_defs.h
35
@@ -XXX,XX +XXX,XX @@ struct target_winsize {
36
#define TARGET_PROT_SEM 0x08
37
#endif
38
39
+#ifdef TARGET_AARCH64
40
+#define TARGET_PROT_BTI 0x10
41
+#endif
42
+
43
/* Common */
44
#define TARGET_MAP_SHARED    0x01        /* Share changes */
45
#define TARGET_MAP_PRIVATE    0x02        /* Changes are private */
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
50
@@ -XXX,XX +XXX,XX @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x)
51
#define arm_tlb_bti_gp(x) (typecheck_memtxattrs(x)->target_tlb_bit0)
52
#define arm_tlb_mte_tagged(x) (typecheck_memtxattrs(x)->target_tlb_bit1)
53
54
+/*
55
+ * AArch64 usage of the PAGE_TARGET_* bits for linux-user.
56
+ */
57
+#define PAGE_BTI PAGE_TARGET_1
58
+
59
/*
60
* Naming convention for isar_feature functions:
61
* Functions which test 32-bit ID registers should have _aa32_ in
62
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/linux-user/mmap.c
65
+++ b/linux-user/mmap.c
66
@@ -XXX,XX +XXX,XX @@ static int validate_prot_to_pageflags(int *host_prot, int prot)
67
*host_prot = (prot & (PROT_READ | PROT_WRITE))
68
| (prot & PROT_EXEC ? PROT_READ : 0);
69
70
+#ifdef TARGET_AARCH64
71
+ /*
72
+ * The PROT_BTI bit is only accepted if the cpu supports the feature.
73
+ * Since this is the unusual case, don't bother checking unless
74
+ * the bit has been requested. If set and valid, record the bit
75
+ * within QEMU's page_flags.
76
+ */
77
+ if (prot & TARGET_PROT_BTI) {
78
+ ARMCPU *cpu = ARM_CPU(thread_cpu);
79
+ if (cpu_isar_feature(aa64_bti, cpu)) {
80
+ valid |= TARGET_PROT_BTI;
81
+ page_flags |= PAGE_BTI;
82
+ }
83
+ }
84
+#endif
85
+
86
return prot & ~valid ? 0 : page_flags;
87
}
88
89
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
10
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
90
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/translate-a64.c
12
--- a/target/arm/translate-a64.c
92
+++ b/target/arm/translate-a64.c
13
+++ b/target/arm/translate-a64.c
93
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
14
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
94
*/
95
static bool is_guarded_page(CPUARMState *env, DisasContext *s)
96
{
15
{
97
-#ifdef CONFIG_USER_ONLY
16
DisasContext *s = container_of(dcbase, DisasContext, base);
98
- return false; /* FIXME */
17
CPUARMState *env = cpu->env_ptr;
99
-#else
18
+ uint64_t pc = s->base.pc_next;
100
uint64_t addr = s->base.pc_first;
19
uint32_t insn;
101
+#ifdef CONFIG_USER_ONLY
20
102
+ return page_get_flags(addr) & PAGE_BTI;
21
if (s->ss_active && !s->pstate_ss) {
103
+#else
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
104
int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx);
23
return;
105
unsigned int index = tlb_index(env, mmu_idx, addr);
24
}
106
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
25
26
- s->pc_curr = s->base.pc_next;
27
- insn = arm_ldl_code(env, &s->base, s->base.pc_next, s->sctlr_b);
28
+ s->pc_curr = pc;
29
+ insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
30
s->insn = insn;
31
- s->base.pc_next += 4;
32
+ s->base.pc_next = pc + 4;
33
34
s->fp_access_checked = false;
35
s->sve_access_checked = false;
107
--
36
--
108
2.20.1
37
2.25.1
109
38
110
39
diff view generated by jsdifflib
1
The BLX immediate insn in the Thumb encoding always performs
1
From: Richard Henderson <richard.henderson@linaro.org>
2
a switch from Thumb to Arm state. This would be totally useless
3
in M-profile which has no Arm decoder, and so the instruction
4
does not exist at all there. Make the encoding UNDEF for M-profile.
5
2
6
(This part of the encoding space is used for the branch-future
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
and low-overhead-loop insns in v8.1M.)
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20201019151301.2046-6-peter.maydell@linaro.org
12
---
6
---
13
target/arm/translate.c | 8 ++++++++
7
target/arm/translate.c | 9 +++++----
14
1 file changed, 8 insertions(+)
8
1 file changed, 5 insertions(+), 4 deletions(-)
15
9
16
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
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
12
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
13
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
14
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
21
{
15
{
22
TCGv_i32 tmp;
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
23
17
CPUARMState *env = cpu->env_ptr;
24
+ /*
18
+ uint32_t pc = dc->base.pc_next;
25
+ * BLX <imm> would be useless on M-profile; the encoding space
19
unsigned int insn;
26
+ * is used for other insns from v8.1M onward, and UNDEFs before that.
20
27
+ */
21
if (arm_pre_translate_insn(dc)) {
28
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
22
- dc->base.pc_next += 4;
29
+ return false;
23
+ dc->base.pc_next = pc + 4;
30
+ }
24
return;
31
+
25
}
32
/* For A32, ARM_FEATURE_V5 is checked near the start of the uncond block. */
26
33
if (s->thumb && (a->imm & 2)) {
27
- dc->pc_curr = dc->base.pc_next;
34
return false;
28
- insn = arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
29
+ dc->pc_curr = pc;
30
+ insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
31
dc->insn = insn;
32
- dc->base.pc_next += 4;
33
+ dc->base.pc_next = pc + 4;
34
disas_arm_insn(dc, insn);
35
36
arm_post_translate_insn(dc);
35
--
37
--
36
2.20.1
38
2.25.1
37
39
38
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For BTI, we need to know if the executable is static or dynamic,
4
which means looking for PT_INTERP earlier.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201016184207.786698-8-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
6
---
11
linux-user/elfload.c | 60 +++++++++++++++++++++++---------------------
7
target/arm/translate.c | 16 ++++++++--------
12
1 file changed, 31 insertions(+), 29 deletions(-)
8
1 file changed, 8 insertions(+), 8 deletions(-)
13
9
14
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/elfload.c
12
--- a/target/arm/translate.c
17
+++ b/linux-user/elfload.c
13
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
14
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
19
15
{
20
mmap_lock();
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
21
17
CPUARMState *env = cpu->env_ptr;
22
- /* Find the maximum size of the image and allocate an appropriate
18
+ uint32_t pc = dc->base.pc_next;
23
- amount of memory to handle that. */
19
uint32_t insn;
24
+ /*
20
bool is_16bit;
25
+ * Find the maximum size of the image and allocate an appropriate
21
26
+ * amount of memory to handle that. Locate the interpreter, if any.
22
if (arm_pre_translate_insn(dc)) {
27
+ */
23
- dc->base.pc_next += 2;
28
loaddr = -1, hiaddr = 0;
24
+ dc->base.pc_next = pc + 2;
29
info->alignment = 0;
25
return;
30
for (i = 0; i < ehdr->e_phnum; ++i) {
31
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
32
}
33
++info->nsegs;
34
info->alignment |= eppnt->p_align;
35
+ } else if (eppnt->p_type == PT_INTERP && pinterp_name) {
36
+ g_autofree char *interp_name = NULL;
37
+
38
+ if (*pinterp_name) {
39
+ errmsg = "Multiple PT_INTERP entries";
40
+ goto exit_errmsg;
41
+ }
42
+ interp_name = g_malloc(eppnt->p_filesz);
43
+ if (!interp_name) {
44
+ goto exit_perror;
45
+ }
46
+
47
+ if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
48
+ memcpy(interp_name, bprm_buf + eppnt->p_offset,
49
+ eppnt->p_filesz);
50
+ } else {
51
+ retval = pread(image_fd, interp_name, eppnt->p_filesz,
52
+ eppnt->p_offset);
53
+ if (retval != eppnt->p_filesz) {
54
+ goto exit_perror;
55
+ }
56
+ }
57
+ if (interp_name[eppnt->p_filesz - 1] != 0) {
58
+ errmsg = "Invalid PT_INTERP entry";
59
+ goto exit_errmsg;
60
+ }
61
+ *pinterp_name = g_steal_pointer(&interp_name);
62
}
63
}
26
}
64
27
65
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
28
- dc->pc_curr = dc->base.pc_next;
66
if (vaddr_em > info->brk) {
29
- insn = arm_lduw_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
67
info->brk = vaddr_em;
30
+ dc->pc_curr = pc;
68
}
31
+ insn = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
69
- } else if (eppnt->p_type == PT_INTERP && pinterp_name) {
32
is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
70
- g_autofree char *interp_name = NULL;
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);
71
-
38
-
72
- if (*pinterp_name) {
39
+ uint32_t insn2 = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
73
- errmsg = "Multiple PT_INTERP entries";
40
insn = insn << 16 | insn2;
74
- goto exit_errmsg;
41
- dc->base.pc_next += 2;
75
- }
42
+ pc += 2;
76
- interp_name = g_malloc(eppnt->p_filesz);
43
}
77
- if (!interp_name) {
44
+ dc->base.pc_next = pc;
78
- goto exit_perror;
45
dc->insn = insn;
79
- }
46
80
-
47
if (dc->pstate_il) {
81
- if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
82
- memcpy(interp_name, bprm_buf + eppnt->p_offset,
83
- eppnt->p_filesz);
84
- } else {
85
- retval = pread(image_fd, interp_name, eppnt->p_filesz,
86
- eppnt->p_offset);
87
- if (retval != eppnt->p_filesz) {
88
- goto exit_perror;
89
- }
90
- }
91
- if (interp_name[eppnt->p_filesz - 1] != 0) {
92
- errmsg = "Invalid PT_INTERP entry";
93
- goto exit_errmsg;
94
- }
95
- *pinterp_name = g_steal_pointer(&interp_name);
96
#ifdef TARGET_MIPS
97
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
98
Mips_elf_abiflags_v0 abiflags;
99
--
48
--
100
2.20.1
49
2.25.1
101
50
102
51
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use the new generic support for NT_GNU_PROPERTY_TYPE_0.
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.
4
9
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201016184207.786698-12-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
linux-user/elfload.c | 48 ++++++++++++++++++++++++++++++++++++++++++--
14
target/arm/translate.c | 10 +++++++---
11
1 file changed, 46 insertions(+), 2 deletions(-)
15
1 file changed, 7 insertions(+), 3 deletions(-)
12
16
13
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/elfload.c
19
--- a/target/arm/translate.c
16
+++ b/linux-user/elfload.c
20
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
21
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
18
22
dc->insn_start = tcg_last_op();
19
#include "elf.h"
23
}
20
24
21
+/* We must delay the following stanzas until after "elf.h". */
25
-static bool arm_pre_translate_insn(DisasContext *dc)
22
+#if defined(TARGET_AARCH64)
26
+static bool arm_check_kernelpage(DisasContext *dc)
23
+
27
{
24
+static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
28
#ifdef CONFIG_USER_ONLY
25
+ const uint32_t *data,
29
/* Intercept jump to the magic kernel page. */
26
+ struct image_info *info,
30
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
27
+ Error **errp)
31
return true;
32
}
33
#endif
34
+ return false;
35
+}
36
37
+static bool arm_check_ss_active(DisasContext *dc)
28
+{
38
+{
29
+ if (pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
39
if (dc->ss_active && !dc->pstate_ss) {
30
+ if (pr_datasz != sizeof(uint32_t)) {
40
/* Singlestep state is Active-pending.
31
+ error_setg(errp, "Ill-formed GNU_PROPERTY_AARCH64_FEATURE_1_AND");
41
* If we're in this state at the start of a TB then either
32
+ return false;
42
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
33
+ }
43
uint32_t pc = dc->base.pc_next;
34
+ /* We will extract GNU_PROPERTY_AARCH64_FEATURE_1_BTI later. */
44
unsigned int insn;
35
+ info->note_flags = *data;
45
36
+ }
46
- if (arm_pre_translate_insn(dc)) {
37
+ return true;
47
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
38
+}
48
dc->base.pc_next = pc + 4;
39
+#define ARCH_USE_GNU_PROPERTY 1
49
return;
40
+
50
}
41
+#else
51
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
42
+
52
uint32_t insn;
43
static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
53
bool is_16bit;
44
const uint32_t *data,
54
45
struct image_info *info,
55
- if (arm_pre_translate_insn(dc)) {
46
@@ -XXX,XX +XXX,XX @@ static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
56
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
47
}
57
dc->base.pc_next = pc + 2;
48
#define ARCH_USE_GNU_PROPERTY 0
58
return;
49
59
}
50
+#endif
51
+
52
struct exec
53
{
54
unsigned int a_info; /* Use macros N_MAGIC, etc for access */
55
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
56
struct elfhdr *ehdr = (struct elfhdr *)bprm_buf;
57
struct elf_phdr *phdr;
58
abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
59
- int i, retval;
60
+ int i, retval, prot_exec;
61
Error *err = NULL;
62
63
/* First of all, some simple consistency checks */
64
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
65
info->brk = 0;
66
info->elf_flags = ehdr->e_flags;
67
68
+ prot_exec = PROT_EXEC;
69
+#ifdef TARGET_AARCH64
70
+ /*
71
+ * If the BTI feature is present, this indicates that the executable
72
+ * pages of the startup binary should be mapped with PROT_BTI, so that
73
+ * branch targets are enforced.
74
+ *
75
+ * The startup binary is either the interpreter or the static executable.
76
+ * The interpreter is responsible for all pages of a dynamic executable.
77
+ *
78
+ * Elf notes are backward compatible to older cpus.
79
+ * Do not enable BTI unless it is supported.
80
+ */
81
+ if ((info->note_flags & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
82
+ && (pinterp_name == NULL || *pinterp_name == 0)
83
+ && cpu_isar_feature(aa64_bti, ARM_CPU(thread_cpu))) {
84
+ prot_exec |= TARGET_PROT_BTI;
85
+ }
86
+#endif
87
+
88
for (i = 0; i < ehdr->e_phnum; i++) {
89
struct elf_phdr *eppnt = phdr + i;
90
if (eppnt->p_type == PT_LOAD) {
91
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
92
elf_prot |= PROT_WRITE;
93
}
94
if (eppnt->p_flags & PF_X) {
95
- elf_prot |= PROT_EXEC;
96
+ elf_prot |= prot_exec;
97
}
98
99
vaddr = load_bias + eppnt->p_vaddr;
100
--
60
--
101
2.20.1
61
2.25.1
102
62
103
63
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The second loop uses a loop induction variable, and the first
3
The size of the code covered by a TranslationBlock cannot be 0;
4
does not. Transform the first to match the second, to simplify
4
this is checked via assert in tb_gen_code.
5
a following patch moving code between them.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20201016184207.786698-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
linux-user/elfload.c | 9 +++++----
10
target/arm/translate-a64.c | 1 +
13
1 file changed, 5 insertions(+), 4 deletions(-)
11
1 file changed, 1 insertion(+)
14
12
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
15
--- a/target/arm/translate-a64.c
18
+++ b/linux-user/elfload.c
16
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
20
loaddr = -1, hiaddr = 0;
18
assert(s->base.num_insns == 1);
21
info->alignment = 0;
19
gen_swstep_exception(s, 0, 0);
22
for (i = 0; i < ehdr->e_phnum; ++i) {
20
s->base.is_jmp = DISAS_NORETURN;
23
- if (phdr[i].p_type == PT_LOAD) {
21
+ s->base.pc_next = pc + 4;
24
- abi_ulong a = phdr[i].p_vaddr - phdr[i].p_offset;
22
return;
25
+ struct elf_phdr *eppnt = phdr + i;
26
+ if (eppnt->p_type == PT_LOAD) {
27
+ abi_ulong a = eppnt->p_vaddr - eppnt->p_offset;
28
if (a < loaddr) {
29
loaddr = a;
30
}
31
- a = phdr[i].p_vaddr + phdr[i].p_memsz;
32
+ a = eppnt->p_vaddr + eppnt->p_memsz;
33
if (a > hiaddr) {
34
hiaddr = a;
35
}
36
++info->nsegs;
37
- info->alignment |= phdr[i].p_align;
38
+ info->alignment |= eppnt->p_align;
39
}
40
}
23
}
41
24
42
--
25
--
43
2.20.1
26
2.25.1
44
27
45
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is slightly clearer than just using strerror, though
3
We will reuse this section of arm_deliver_fault for
4
the different forms produced by error_setg_file_open and
4
raising pc alignment faults.
5
error_setg_errno isn't entirely convenient.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20201016184207.786698-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
linux-user/elfload.c | 15 ++++++++-------
10
target/arm/tlb_helper.c | 45 +++++++++++++++++++++++++----------------
13
1 file changed, 8 insertions(+), 7 deletions(-)
11
1 file changed, 28 insertions(+), 17 deletions(-)
14
12
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
13
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
15
--- a/target/arm/tlb_helper.c
18
+++ b/linux-user/elfload.c
16
+++ b/target/arm/tlb_helper.c
19
@@ -XXX,XX +XXX,XX @@ static void load_elf_interp(const char *filename, struct image_info *info,
17
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
20
char bprm_buf[BPRM_BUF_SIZE])
18
return syn;
19
}
20
21
-static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
22
- MMUAccessType access_type,
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)
21
{
26
{
22
int fd, retval;
27
- CPUARMState *env = &cpu->env;
23
+ Error *err = NULL;
28
- int target_el;
24
29
- bool same_el;
25
fd = open(path(filename), O_RDONLY);
30
- uint32_t syn, exc, fsr, fsc;
26
if (fd < 0) {
31
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
27
- goto exit_perror;
32
-
28
+ error_setg_file_open(&err, errno, filename);
33
- target_el = exception_target_el(env);
29
+ error_report_err(err);
34
- if (fi->stage2) {
30
+ exit(-1);
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;
31
}
48
}
32
49
33
retval = read(fd, bprm_buf, BPRM_BUF_SIZE);
50
+ *ret_fsc = fsc;
34
if (retval < 0) {
51
+ return fsr;
35
- goto exit_perror;
52
+}
36
+ error_setg_errno(&err, errno, "Error reading file header");
37
+ error_reportf_err(err, "%s: ", filename);
38
+ exit(-1);
39
}
40
+
53
+
41
if (retval < BPRM_BUF_SIZE) {
54
+static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
42
memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval);
55
+ MMUAccessType access_type,
43
}
56
+ int mmu_idx, ARMMMUFaultInfo *fi)
44
57
+{
45
load_elf_image(filename, fd, info, NULL, bprm_buf);
58
+ CPUARMState *env = &cpu->env;
46
- return;
59
+ int target_el;
47
-
60
+ bool same_el;
48
- exit_perror:
61
+ uint32_t syn, exc, fsr, fsc;
49
- fprintf(stderr, "%s: %s\n", filename, strerror(errno));
62
+
50
- exit(-1);
63
+ target_el = exception_target_el(env);
51
}
64
+ if (fi->stage2) {
52
65
+ target_el = 2;
53
static int symfind(const void *s0, const void *s1)
66
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
67
+ if (arm_is_secure_below_el3(env) && fi->s1ns) {
68
+ env->cp15.hpfar_el2 |= HPFAR_NS;
69
+ }
70
+ }
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;
54
--
78
--
55
2.20.1
79
2.25.1
56
80
57
81
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
On ARM, the Top Byte Ignore feature means that only 56 bits of
3
For A64, any input to an indirect branch can cause this.
4
the address are significant in the virtual address. We are
4
5
required to give the entire 64-bit address to FAR_ELx on fault,
5
For A32, many indirect branch paths force the branch to be aligned,
6
which means that we do not "clean" the top byte early in TCG.
6
but BXWritePC does not. This includes the BX instruction but also
7
7
other interworking changes to PC. Prior to v8, this case is UNDEFINED.
8
This new interface allows us to flush all 256 possible aliases
8
With v8, this is CONSTRAINED UNPREDICTABLE and may either raise an
9
for a given page, currently missed by tlb_flush_page*.
9
exception or force align the PC.
10
11
We choose to raise an exception because we have the infrastructure,
12
it makes the generated code for gen_bx simpler, and it has the
13
possibility of catching more guest bugs.
10
14
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20201016210754.818257-2-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
18
---
17
include/exec/exec-all.h | 36 ++++++
19
target/arm/helper.h | 1 +
18
accel/tcg/cputlb.c | 275 ++++++++++++++++++++++++++++++++++++++--
20
target/arm/syndrome.h | 5 ++++
19
2 files changed, 302 insertions(+), 9 deletions(-)
21
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++++++---------------
20
22
target/arm/tlb_helper.c | 18 ++++++++++++++
21
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
23
target/arm/translate-a64.c | 15 ++++++++++++
22
index XXXXXXX..XXXXXXX 100644
24
target/arm/translate.c | 22 ++++++++++++++++-
23
--- a/include/exec/exec-all.h
25
6 files changed, 87 insertions(+), 20 deletions(-)
24
+++ b/include/exec/exec-all.h
26
25
@@ -XXX,XX +XXX,XX @@ void tlb_flush_by_mmuidx_all_cpus(CPUState *cpu, uint16_t idxmap);
27
diff --git a/target/arm/helper.h b/target/arm/helper.h
26
* depend on when the guests translation ends the TB.
28
index XXXXXXX..XXXXXXX 100644
27
*/
29
--- a/target/arm/helper.h
28
void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu, uint16_t idxmap);
30
+++ b/target/arm/helper.h
29
+
31
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
30
+/**
32
DEF_HELPER_2(exception_internal, void, env, i32)
31
+ * tlb_flush_page_bits_by_mmuidx
33
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
32
+ * @cpu: CPU whose TLB should be flushed
34
DEF_HELPER_2(exception_bkpt_insn, void, env, i32)
33
+ * @addr: virtual address of page to be flushed
35
+DEF_HELPER_2(exception_pc_alignment, noreturn, env, tl)
34
+ * @idxmap: bitmap of mmu indexes to flush
36
DEF_HELPER_1(setend, void, env)
35
+ * @bits: number of significant bits in address
37
DEF_HELPER_2(wfi, void, env, i32)
36
+ *
38
DEF_HELPER_1(wfe, void, env)
37
+ * Similar to tlb_flush_page_mask, but with a bitmap of indexes.
39
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
38
+ */
40
index XXXXXXX..XXXXXXX 100644
39
+void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
41
--- a/target/arm/syndrome.h
40
+ uint16_t idxmap, unsigned bits);
42
+++ b/target/arm/syndrome.h
41
+
43
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_illegalstate(void)
42
+/* Similarly, with broadcast and syncing. */
44
return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
43
+void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *cpu, target_ulong addr,
44
+ uint16_t idxmap, unsigned bits);
45
+void tlb_flush_page_bits_by_mmuidx_all_cpus_synced
46
+ (CPUState *cpu, target_ulong addr, uint16_t idxmap, unsigned bits);
47
+
48
/**
49
* tlb_set_page_with_attrs:
50
* @cpu: CPU to add this TLB entry for
51
@@ -XXX,XX +XXX,XX @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
52
uint16_t idxmap)
53
{
54
}
45
}
55
+static inline void tlb_flush_page_bits_by_mmuidx(CPUState *cpu,
46
56
+ target_ulong addr,
47
+static inline uint32_t syn_pcalignment(void)
57
+ uint16_t idxmap,
58
+ unsigned bits)
59
+{
48
+{
49
+ return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
60
+}
50
+}
61
+static inline void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *cpu,
51
+
62
+ target_ulong addr,
52
#endif /* TARGET_ARM_SYNDROME_H */
63
+ uint16_t idxmap,
53
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
64
+ unsigned bits)
54
index XXXXXXX..XXXXXXX 100644
55
--- a/linux-user/aarch64/cpu_loop.c
56
+++ b/linux-user/aarch64/cpu_loop.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
58
break;
59
case EXCP_PREFETCH_ABORT:
60
case EXCP_DATA_ABORT:
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
116
@@ -XXX,XX +XXX,XX @@
117
#include "cpu.h"
118
#include "internals.h"
119
#include "exec/exec-all.h"
120
+#include "exec/helper-proto.h"
121
122
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
123
unsigned int target_el,
124
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
125
arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
126
}
127
128
+void helper_exception_pc_alignment(CPUARMState *env, target_ulong pc)
65
+{
129
+{
130
+ ARMMMUFaultInfo fi = { .type = ARMFault_Alignment };
131
+ int target_el = exception_target_el(env);
132
+ int mmu_idx = cpu_mmu_index(env, true);
133
+ uint32_t fsc;
134
+
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);
66
+}
143
+}
67
+static inline void
144
+
68
+tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *cpu, target_ulong addr,
145
#if !defined(CONFIG_USER_ONLY)
69
+ uint16_t idxmap, unsigned bits)
146
70
+{
147
/*
71
+}
148
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
72
#endif
149
index XXXXXXX..XXXXXXX 100644
73
/**
150
--- a/target/arm/translate-a64.c
74
* probe_access:
151
+++ b/target/arm/translate-a64.c
75
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
76
index XXXXXXX..XXXXXXX 100644
153
uint64_t pc = s->base.pc_next;
77
--- a/accel/tcg/cputlb.c
154
uint32_t insn;
78
+++ b/accel/tcg/cputlb.c
155
79
@@ -XXX,XX +XXX,XX @@ void tlb_flush_all_cpus_synced(CPUState *src_cpu)
156
+ /* Singlestep exceptions have the highest priority. */
80
tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, ALL_MMUIDX_BITS);
157
if (s->ss_active && !s->pstate_ss) {
81
}
158
/* Singlestep state is Active-pending.
82
159
* If we're in this state at the start of a TB then either
83
+static bool tlb_hit_page_mask_anyprot(CPUTLBEntry *tlb_entry,
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
84
+ target_ulong page, target_ulong mask)
161
return;
85
+{
86
+ page &= mask;
87
+ mask &= TARGET_PAGE_MASK | TLB_INVALID_MASK;
88
+
89
+ return (page == (tlb_entry->addr_read & mask) ||
90
+ page == (tlb_addr_write(tlb_entry) & mask) ||
91
+ page == (tlb_entry->addr_code & mask));
92
+}
93
+
94
static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tlb_entry,
95
target_ulong page)
96
{
97
- return tlb_hit_page(tlb_entry->addr_read, page) ||
98
- tlb_hit_page(tlb_addr_write(tlb_entry), page) ||
99
- tlb_hit_page(tlb_entry->addr_code, page);
100
+ return tlb_hit_page_mask_anyprot(tlb_entry, page, -1);
101
}
102
103
/**
104
@@ -XXX,XX +XXX,XX @@ static inline bool tlb_entry_is_empty(const CPUTLBEntry *te)
105
}
106
107
/* Called with tlb_c.lock held */
108
-static inline bool tlb_flush_entry_locked(CPUTLBEntry *tlb_entry,
109
- target_ulong page)
110
+static bool tlb_flush_entry_mask_locked(CPUTLBEntry *tlb_entry,
111
+ target_ulong page,
112
+ target_ulong mask)
113
{
114
- if (tlb_hit_page_anyprot(tlb_entry, page)) {
115
+ if (tlb_hit_page_mask_anyprot(tlb_entry, page, mask)) {
116
memset(tlb_entry, -1, sizeof(*tlb_entry));
117
return true;
118
}
162
}
119
return false;
163
120
}
164
+ if (pc & 3) {
121
165
+ /*
122
+static inline bool tlb_flush_entry_locked(CPUTLBEntry *tlb_entry,
166
+ * PC alignment fault. This has priority over the instruction abort
123
+ target_ulong page)
167
+ * that we would receive from a translation fault via arm_ldl_code.
124
+{
168
+ * This should only be possible after an indirect branch, at the
125
+ return tlb_flush_entry_mask_locked(tlb_entry, page, -1);
169
+ * start of the TB.
126
+}
170
+ */
127
+
171
+ assert(s->base.num_insns == 1);
128
/* Called with tlb_c.lock held */
172
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
129
-static inline void tlb_flush_vtlb_page_locked(CPUArchState *env, int mmu_idx,
173
+ s->base.is_jmp = DISAS_NORETURN;
130
- target_ulong page)
174
+ s->base.pc_next = QEMU_ALIGN_UP(pc, 4);
131
+static void tlb_flush_vtlb_page_mask_locked(CPUArchState *env, int mmu_idx,
132
+ target_ulong page,
133
+ target_ulong mask)
134
{
135
CPUTLBDesc *d = &env_tlb(env)->d[mmu_idx];
136
int k;
137
138
assert_cpu_is_self(env_cpu(env));
139
for (k = 0; k < CPU_VTLB_SIZE; k++) {
140
- if (tlb_flush_entry_locked(&d->vtable[k], page)) {
141
+ if (tlb_flush_entry_mask_locked(&d->vtable[k], page, mask)) {
142
tlb_n_used_entries_dec(env, mmu_idx);
143
}
144
}
145
}
146
147
+static inline void tlb_flush_vtlb_page_locked(CPUArchState *env, int mmu_idx,
148
+ target_ulong page)
149
+{
150
+ tlb_flush_vtlb_page_mask_locked(env, mmu_idx, page, -1);
151
+}
152
+
153
static void tlb_flush_page_locked(CPUArchState *env, int midx,
154
target_ulong page)
155
{
156
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_all_cpus_synced(CPUState *src, target_ulong addr)
157
tlb_flush_page_by_mmuidx_all_cpus_synced(src, addr, ALL_MMUIDX_BITS);
158
}
159
160
+static void tlb_flush_page_bits_locked(CPUArchState *env, int midx,
161
+ target_ulong page, unsigned bits)
162
+{
163
+ CPUTLBDesc *d = &env_tlb(env)->d[midx];
164
+ CPUTLBDescFast *f = &env_tlb(env)->f[midx];
165
+ target_ulong mask = MAKE_64BIT_MASK(0, bits);
166
+
167
+ /*
168
+ * If @bits is smaller than the tlb size, there may be multiple entries
169
+ * within the TLB; otherwise all addresses that match under @mask hit
170
+ * the same TLB entry.
171
+ *
172
+ * TODO: Perhaps allow bits to be a few bits less than the size.
173
+ * For now, just flush the entire TLB.
174
+ */
175
+ if (mask < f->mask) {
176
+ tlb_debug("forcing full flush midx %d ("
177
+ TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
178
+ midx, page, mask);
179
+ tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
180
+ return;
175
+ return;
181
+ }
176
+ }
182
+
177
+
183
+ /* Check if we need to flush due to large pages. */
178
s->pc_curr = pc;
184
+ if ((page & d->large_page_mask) == d->large_page_addr) {
179
insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
185
+ tlb_debug("forcing full flush midx %d ("
180
s->insn = insn;
186
+ TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
187
+ midx, d->large_page_addr, d->large_page_mask);
182
index XXXXXXX..XXXXXXX 100644
188
+ tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
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;
189
+ return;
193
+ return;
190
+ }
194
+ }
191
+
195
+
192
+ if (tlb_flush_entry_mask_locked(tlb_entry(env, midx, page), page, mask)) {
196
+ if (pc & 3) {
193
+ tlb_n_used_entries_dec(env, midx);
197
+ /*
194
+ }
198
+ * PC alignment fault. This has priority over the instruction abort
195
+ tlb_flush_vtlb_page_mask_locked(env, midx, page, mask);
199
+ * that we would receive from a translation fault via arm_ldl_code
196
+}
200
+ * (or the execution of the kernelpage entrypoint). This should only
197
+
201
+ * be possible after an indirect branch, at the start of the TB.
198
+typedef struct {
202
+ */
199
+ target_ulong addr;
203
+ assert(dc->base.num_insns == 1);
200
+ uint16_t idxmap;
204
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
201
+ uint16_t bits;
205
+ dc->base.is_jmp = DISAS_NORETURN;
202
+} TLBFlushPageBitsByMMUIdxData;
206
+ dc->base.pc_next = QEMU_ALIGN_UP(pc, 4);
203
+
204
+static void
205
+tlb_flush_page_bits_by_mmuidx_async_0(CPUState *cpu,
206
+ TLBFlushPageBitsByMMUIdxData d)
207
+{
208
+ CPUArchState *env = cpu->env_ptr;
209
+ int mmu_idx;
210
+
211
+ assert_cpu_is_self(cpu);
212
+
213
+ tlb_debug("page addr:" TARGET_FMT_lx "/%u mmu_map:0x%x\n",
214
+ d.addr, d.bits, d.idxmap);
215
+
216
+ qemu_spin_lock(&env_tlb(env)->c.lock);
217
+ for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
218
+ if ((d.idxmap >> mmu_idx) & 1) {
219
+ tlb_flush_page_bits_locked(env, mmu_idx, d.addr, d.bits);
220
+ }
221
+ }
222
+ qemu_spin_unlock(&env_tlb(env)->c.lock);
223
+
224
+ tb_flush_jmp_cache(cpu, d.addr);
225
+}
226
+
227
+static bool encode_pbm_to_runon(run_on_cpu_data *out,
228
+ TLBFlushPageBitsByMMUIdxData d)
229
+{
230
+ /* We need 6 bits to hold to hold @bits up to 63. */
231
+ if (d.idxmap <= MAKE_64BIT_MASK(0, TARGET_PAGE_BITS - 6)) {
232
+ *out = RUN_ON_CPU_TARGET_PTR(d.addr | (d.idxmap << 6) | d.bits);
233
+ return true;
234
+ }
235
+ return false;
236
+}
237
+
238
+static TLBFlushPageBitsByMMUIdxData
239
+decode_runon_to_pbm(run_on_cpu_data data)
240
+{
241
+ target_ulong addr_map_bits = (target_ulong) data.target_ptr;
242
+ return (TLBFlushPageBitsByMMUIdxData){
243
+ .addr = addr_map_bits & TARGET_PAGE_MASK,
244
+ .idxmap = (addr_map_bits & ~TARGET_PAGE_MASK) >> 6,
245
+ .bits = addr_map_bits & 0x3f
246
+ };
247
+}
248
+
249
+static void tlb_flush_page_bits_by_mmuidx_async_1(CPUState *cpu,
250
+ run_on_cpu_data runon)
251
+{
252
+ tlb_flush_page_bits_by_mmuidx_async_0(cpu, decode_runon_to_pbm(runon));
253
+}
254
+
255
+static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
256
+ run_on_cpu_data data)
257
+{
258
+ TLBFlushPageBitsByMMUIdxData *d = data.host_ptr;
259
+ tlb_flush_page_bits_by_mmuidx_async_0(cpu, *d);
260
+ g_free(d);
261
+}
262
+
263
+void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
264
+ uint16_t idxmap, unsigned bits)
265
+{
266
+ TLBFlushPageBitsByMMUIdxData d;
267
+ run_on_cpu_data runon;
268
+
269
+ /* If all bits are significant, this devolves to tlb_flush_page. */
270
+ if (bits >= TARGET_LONG_BITS) {
271
+ tlb_flush_page_by_mmuidx(cpu, addr, idxmap);
272
+ return;
207
+ return;
273
+ }
208
+ }
274
+ /* If no page bits are significant, this devolves to tlb_flush. */
209
+
275
+ if (bits < TARGET_PAGE_BITS) {
210
+ if (arm_check_kernelpage(dc)) {
276
+ tlb_flush_by_mmuidx(cpu, idxmap);
211
dc->base.pc_next = pc + 4;
277
+ return;
212
return;
278
+ }
213
}
279
+
280
+ /* This should already be page aligned */
281
+ d.addr = addr & TARGET_PAGE_MASK;
282
+ d.idxmap = idxmap;
283
+ d.bits = bits;
284
+
285
+ if (qemu_cpu_is_self(cpu)) {
286
+ tlb_flush_page_bits_by_mmuidx_async_0(cpu, d);
287
+ } else if (encode_pbm_to_runon(&runon, d)) {
288
+ async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
289
+ } else {
290
+ TLBFlushPageBitsByMMUIdxData *p
291
+ = g_new(TLBFlushPageBitsByMMUIdxData, 1);
292
+
293
+ /* Otherwise allocate a structure, freed by the worker. */
294
+ *p = d;
295
+ async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_2,
296
+ RUN_ON_CPU_HOST_PTR(p));
297
+ }
298
+}
299
+
300
+void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
301
+ target_ulong addr,
302
+ uint16_t idxmap,
303
+ unsigned bits)
304
+{
305
+ TLBFlushPageBitsByMMUIdxData d;
306
+ run_on_cpu_data runon;
307
+
308
+ /* If all bits are significant, this devolves to tlb_flush_page. */
309
+ if (bits >= TARGET_LONG_BITS) {
310
+ tlb_flush_page_by_mmuidx_all_cpus(src_cpu, addr, idxmap);
311
+ return;
312
+ }
313
+ /* If no page bits are significant, this devolves to tlb_flush. */
314
+ if (bits < TARGET_PAGE_BITS) {
315
+ tlb_flush_by_mmuidx_all_cpus(src_cpu, idxmap);
316
+ return;
317
+ }
318
+
319
+ /* This should already be page aligned */
320
+ d.addr = addr & TARGET_PAGE_MASK;
321
+ d.idxmap = idxmap;
322
+ d.bits = bits;
323
+
324
+ if (encode_pbm_to_runon(&runon, d)) {
325
+ flush_all_helper(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
326
+ } else {
327
+ CPUState *dst_cpu;
328
+ TLBFlushPageBitsByMMUIdxData *p;
329
+
330
+ /* Allocate a separate data block for each destination cpu. */
331
+ CPU_FOREACH(dst_cpu) {
332
+ if (dst_cpu != src_cpu) {
333
+ p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
334
+ *p = d;
335
+ async_run_on_cpu(dst_cpu,
336
+ tlb_flush_page_bits_by_mmuidx_async_2,
337
+ RUN_ON_CPU_HOST_PTR(p));
338
+ }
339
+ }
340
+ }
341
+
342
+ tlb_flush_page_bits_by_mmuidx_async_0(src_cpu, d);
343
+}
344
+
345
+void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
346
+ target_ulong addr,
347
+ uint16_t idxmap,
348
+ unsigned bits)
349
+{
350
+ TLBFlushPageBitsByMMUIdxData d;
351
+ run_on_cpu_data runon;
352
+
353
+ /* If all bits are significant, this devolves to tlb_flush_page. */
354
+ if (bits >= TARGET_LONG_BITS) {
355
+ tlb_flush_page_by_mmuidx_all_cpus_synced(src_cpu, addr, idxmap);
356
+ return;
357
+ }
358
+ /* If no page bits are significant, this devolves to tlb_flush. */
359
+ if (bits < TARGET_PAGE_BITS) {
360
+ tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, idxmap);
361
+ return;
362
+ }
363
+
364
+ /* This should already be page aligned */
365
+ d.addr = addr & TARGET_PAGE_MASK;
366
+ d.idxmap = idxmap;
367
+ d.bits = bits;
368
+
369
+ if (encode_pbm_to_runon(&runon, d)) {
370
+ flush_all_helper(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
371
+ async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1,
372
+ runon);
373
+ } else {
374
+ CPUState *dst_cpu;
375
+ TLBFlushPageBitsByMMUIdxData *p;
376
+
377
+ /* Allocate a separate data block for each destination cpu. */
378
+ CPU_FOREACH(dst_cpu) {
379
+ if (dst_cpu != src_cpu) {
380
+ p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
381
+ *p = d;
382
+ async_run_on_cpu(dst_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
383
+ RUN_ON_CPU_HOST_PTR(p));
384
+ }
385
+ }
386
+
387
+ p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
388
+ *p = d;
389
+ async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
390
+ RUN_ON_CPU_HOST_PTR(p));
391
+ }
392
+}
393
+
394
/* update the TLBs so that writes to code in the virtual page 'addr'
395
can be detected */
396
void tlb_protect_code(ram_addr_t ram_addr)
397
--
214
--
398
2.20.1
215
2.25.1
399
216
400
217
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The kernel sets btype for the signal handler as if for a call.
3
Misaligned thumb PC is architecturally impossible.
4
Assert is better than proceeding, in case we've missed
5
something somewhere.
6
7
Expand a comment about aligning the pc in gdbstub.
8
Fail an incoming migrate if a thumb pc is misaligned.
4
9
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201016184207.786698-2-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
linux-user/aarch64/signal.c | 10 ++++++++--
14
target/arm/gdbstub.c | 9 +++++++--
11
1 file changed, 8 insertions(+), 2 deletions(-)
15
target/arm/machine.c | 10 ++++++++++
16
target/arm/translate.c | 3 +++
17
3 files changed, 20 insertions(+), 2 deletions(-)
12
18
13
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
19
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/aarch64/signal.c
21
--- a/target/arm/gdbstub.c
16
+++ b/linux-user/aarch64/signal.c
22
+++ b/target/arm/gdbstub.c
17
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
23
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
18
+ offsetof(struct target_rt_frame_record, tramp);
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;
19
}
38
}
20
env->xregs[0] = usig;
39
diff --git a/target/arm/machine.c b/target/arm/machine.c
21
- env->xregs[31] = frame_addr;
40
index XXXXXXX..XXXXXXX 100644
22
env->xregs[29] = frame_addr + fr_ofs;
41
--- a/target/arm/machine.c
23
- env->pc = ka->_sa_handler;
42
+++ b/target/arm/machine.c
24
env->xregs[30] = return_addr;
43
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
25
+ env->xregs[31] = frame_addr;
44
return -1;
26
+ env->pc = ka->_sa_handler;
45
}
46
}
27
+
47
+
28
+ /* Invoke the signal handler as if by indirect call. */
48
+ /*
29
+ if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
49
+ * Misaligned thumb pc is architecturally impossible.
30
+ env->btype = 2;
50
+ * We have an assert in thumb_tr_translate_insn to verify this.
51
+ * Fail an incoming migrate to avoid this assert.
52
+ */
53
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
54
+ return -1;
31
+ }
55
+ }
32
+
56
+
33
if (info) {
57
if (!kvm_enabled()) {
34
tswap_siginfo(&frame->info, info);
58
pmu_op_finish(&cpu->env);
35
env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
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;
36
--
74
--
37
2.20.1
75
2.25.1
38
76
39
77
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is generic support, with the code disabled for all targets.
3
Both single-step and pc alignment faults have priority over
4
breakpoint exceptions.
4
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201016184207.786698-11-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
linux-user/qemu.h | 4 ++
10
target/arm/debug_helper.c | 23 +++++++++++++++++++++++
11
linux-user/elfload.c | 157 +++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 23 insertions(+)
12
2 files changed, 161 insertions(+)
13
12
14
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
13
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/qemu.h
15
--- a/target/arm/debug_helper.c
17
+++ b/linux-user/qemu.h
16
+++ b/target/arm/debug_helper.c
18
@@ -XXX,XX +XXX,XX @@ struct image_info {
17
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
19
abi_ulong interpreter_loadmap_addr;
20
abi_ulong interpreter_pt_dynamic_addr;
21
struct image_info *other_info;
22
+
23
+ /* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */
24
+ uint32_t note_flags;
25
+
26
#ifdef TARGET_MIPS
27
int fp_abi;
28
int interp_fp_abi;
29
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/linux-user/elfload.c
32
+++ b/linux-user/elfload.c
33
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
34
35
#include "elf.h"
36
37
+static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
38
+ const uint32_t *data,
39
+ struct image_info *info,
40
+ Error **errp)
41
+{
42
+ g_assert_not_reached();
43
+}
44
+#define ARCH_USE_GNU_PROPERTY 0
45
+
46
struct exec
47
{
18
{
48
unsigned int a_info; /* Use macros N_MAGIC, etc for access */
19
ARMCPU *cpu = ARM_CPU(cs);
49
@@ -XXX,XX +XXX,XX @@ void probe_guest_base(const char *image_name, abi_ulong guest_loaddr,
20
CPUARMState *env = &cpu->env;
50
"@ 0x%" PRIx64 "\n", (uint64_t)guest_base);
21
+ target_ulong pc;
51
}
22
int n;
52
23
53
+enum {
24
/*
54
+ /* The string "GNU\0" as a magic number. */
25
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
55
+ GNU0_MAGIC = const_le32('G' | 'N' << 8 | 'U' << 16),
26
return false;
56
+ NOTE_DATA_SZ = 1 * KiB,
27
}
57
+ NOTE_NAME_SZ = 4,
28
58
+ ELF_GNU_PROPERTY_ALIGN = ELF_CLASS == ELFCLASS32 ? 4 : 8,
29
+ /*
59
+};
30
+ * Single-step exceptions have priority over breakpoint exceptions.
60
+
31
+ * If single-step state is active-pending, suppress the bp.
61
+/*
32
+ */
62
+ * Process a single gnu_property entry.
33
+ if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
63
+ * Return false for error.
64
+ */
65
+static bool parse_elf_property(const uint32_t *data, int *off, int datasz,
66
+ struct image_info *info, bool have_prev_type,
67
+ uint32_t *prev_type, Error **errp)
68
+{
69
+ uint32_t pr_type, pr_datasz, step;
70
+
71
+ if (*off > datasz || !QEMU_IS_ALIGNED(*off, ELF_GNU_PROPERTY_ALIGN)) {
72
+ goto error_data;
73
+ }
74
+ datasz -= *off;
75
+ data += *off / sizeof(uint32_t);
76
+
77
+ if (datasz < 2 * sizeof(uint32_t)) {
78
+ goto error_data;
79
+ }
80
+ pr_type = data[0];
81
+ pr_datasz = data[1];
82
+ data += 2;
83
+ datasz -= 2 * sizeof(uint32_t);
84
+ step = ROUND_UP(pr_datasz, ELF_GNU_PROPERTY_ALIGN);
85
+ if (step > datasz) {
86
+ goto error_data;
87
+ }
88
+
89
+ /* Properties are supposed to be unique and sorted on pr_type. */
90
+ if (have_prev_type && pr_type <= *prev_type) {
91
+ if (pr_type == *prev_type) {
92
+ error_setg(errp, "Duplicate property in PT_GNU_PROPERTY");
93
+ } else {
94
+ error_setg(errp, "Unsorted property in PT_GNU_PROPERTY");
95
+ }
96
+ return false;
97
+ }
98
+ *prev_type = pr_type;
99
+
100
+ if (!arch_parse_elf_property(pr_type, pr_datasz, data, info, errp)) {
101
+ return false;
34
+ return false;
102
+ }
35
+ }
103
+
36
+
104
+ *off += 2 * sizeof(uint32_t) + step;
37
+ /*
105
+ return true;
38
+ * PC alignment faults have priority over breakpoint exceptions.
106
+
39
+ */
107
+ error_data:
40
+ pc = is_a64(env) ? env->pc : env->regs[15];
108
+ error_setg(errp, "Ill-formed property in PT_GNU_PROPERTY");
41
+ if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
109
+ return false;
110
+}
111
+
112
+/* Process NT_GNU_PROPERTY_TYPE_0. */
113
+static bool parse_elf_properties(int image_fd,
114
+ struct image_info *info,
115
+ const struct elf_phdr *phdr,
116
+ char bprm_buf[BPRM_BUF_SIZE],
117
+ Error **errp)
118
+{
119
+ union {
120
+ struct elf_note nhdr;
121
+ uint32_t data[NOTE_DATA_SZ / sizeof(uint32_t)];
122
+ } note;
123
+
124
+ int n, off, datasz;
125
+ bool have_prev_type;
126
+ uint32_t prev_type;
127
+
128
+ /* Unless the arch requires properties, ignore them. */
129
+ if (!ARCH_USE_GNU_PROPERTY) {
130
+ return true;
131
+ }
132
+
133
+ /* If the properties are crazy large, that's too bad. */
134
+ n = phdr->p_filesz;
135
+ if (n > sizeof(note)) {
136
+ error_setg(errp, "PT_GNU_PROPERTY too large");
137
+ return false;
138
+ }
139
+ if (n < sizeof(note.nhdr)) {
140
+ error_setg(errp, "PT_GNU_PROPERTY too small");
141
+ return false;
42
+ return false;
142
+ }
43
+ }
143
+
44
+
144
+ if (phdr->p_offset + n <= BPRM_BUF_SIZE) {
45
+ /*
145
+ memcpy(&note, bprm_buf + phdr->p_offset, n);
46
+ * Instruction aborts have priority over breakpoint exceptions.
146
+ } else {
47
+ * TODO: We would need to look up the page for PC and verify that
147
+ ssize_t len = pread(image_fd, &note, n, phdr->p_offset);
48
+ * it is present and executable.
148
+ if (len != n) {
49
+ */
149
+ error_setg_errno(errp, errno, "Error reading file header");
150
+ return false;
151
+ }
152
+ }
153
+
50
+
154
+ /*
51
for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
155
+ * The contents of a valid PT_GNU_PROPERTY is a sequence
52
if (bp_wp_matches(cpu, n, false)) {
156
+ * of uint32_t -- swap them all now.
53
return true;
157
+ */
158
+#ifdef BSWAP_NEEDED
159
+ for (int i = 0; i < n / 4; i++) {
160
+ bswap32s(note.data + i);
161
+ }
162
+#endif
163
+
164
+ /*
165
+ * Note that nhdr is 3 words, and that the "name" described by namesz
166
+ * immediately follows nhdr and is thus at the 4th word. Further, all
167
+ * of the inputs to the kernel's round_up are multiples of 4.
168
+ */
169
+ if (note.nhdr.n_type != NT_GNU_PROPERTY_TYPE_0 ||
170
+ note.nhdr.n_namesz != NOTE_NAME_SZ ||
171
+ note.data[3] != GNU0_MAGIC) {
172
+ error_setg(errp, "Invalid note in PT_GNU_PROPERTY");
173
+ return false;
174
+ }
175
+ off = sizeof(note.nhdr) + NOTE_NAME_SZ;
176
+
177
+ datasz = note.nhdr.n_descsz + off;
178
+ if (datasz > n) {
179
+ error_setg(errp, "Invalid note size in PT_GNU_PROPERTY");
180
+ return false;
181
+ }
182
+
183
+ have_prev_type = false;
184
+ prev_type = 0;
185
+ while (1) {
186
+ if (off == datasz) {
187
+ return true; /* end, exit ok */
188
+ }
189
+ if (!parse_elf_property(note.data, &off, datasz, info,
190
+ have_prev_type, &prev_type, errp)) {
191
+ return false;
192
+ }
193
+ have_prev_type = true;
194
+ }
195
+}
196
+
197
/* Load an ELF image into the address space.
198
199
IMAGE_NAME is the filename of the image, to use in error messages.
200
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
201
goto exit_errmsg;
202
}
203
*pinterp_name = g_steal_pointer(&interp_name);
204
+ } else if (eppnt->p_type == PT_GNU_PROPERTY) {
205
+ if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) {
206
+ goto exit_errmsg;
207
+ }
208
}
209
}
210
211
--
54
--
212
2.20.1
55
2.25.1
213
56
214
57
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The note test requires gcc 10 for -mbranch-protection=standard.
4
The mmap test uses PROT_BTI and does not require special compiler support.
5
6
Acked-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20201016184207.786698-13-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
6
---
12
tests/tcg/aarch64/bti-1.c | 62 +++++++++++++++++
7
tests/tcg/aarch64/pcalign-a64.c | 37 +++++++++++++++++++++++++
13
tests/tcg/aarch64/bti-2.c | 108 ++++++++++++++++++++++++++++++
8
tests/tcg/arm/pcalign-a32.c | 46 +++++++++++++++++++++++++++++++
14
tests/tcg/aarch64/bti-crt.inc.c | 51 ++++++++++++++
9
tests/tcg/aarch64/Makefile.target | 4 +--
15
tests/tcg/aarch64/Makefile.target | 10 +++
10
tests/tcg/arm/Makefile.target | 4 +++
16
tests/tcg/configure.sh | 4 ++
11
4 files changed, 89 insertions(+), 2 deletions(-)
17
5 files changed, 235 insertions(+)
12
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
18
create mode 100644 tests/tcg/aarch64/bti-1.c
13
create mode 100644 tests/tcg/arm/pcalign-a32.c
19
create mode 100644 tests/tcg/aarch64/bti-2.c
20
create mode 100644 tests/tcg/aarch64/bti-crt.inc.c
21
14
22
diff --git a/tests/tcg/aarch64/bti-1.c b/tests/tcg/aarch64/bti-1.c
15
diff --git a/tests/tcg/aarch64/pcalign-a64.c b/tests/tcg/aarch64/pcalign-a64.c
23
new file mode 100644
16
new file mode 100644
24
index XXXXXXX..XXXXXXX
17
index XXXXXXX..XXXXXXX
25
--- /dev/null
18
--- /dev/null
26
+++ b/tests/tcg/aarch64/bti-1.c
19
+++ b/tests/tcg/aarch64/pcalign-a64.c
27
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
28
+/*
21
+/* Test PC misalignment exception */
29
+ * Branch target identification, basic notskip cases.
30
+ */
31
+
22
+
32
+#include "bti-crt.inc.c"
23
+#include <assert.h>
24
+#include <signal.h>
25
+#include <stdlib.h>
26
+#include <stdio.h>
33
+
27
+
34
+static void skip2_sigill(int sig, siginfo_t *info, ucontext_t *uc)
28
+static void *expected;
29
+
30
+static void sigbus(int sig, siginfo_t *info, void *vuc)
35
+{
31
+{
36
+ uc->uc_mcontext.pc += 8;
32
+ assert(info->si_code == BUS_ADRALN);
37
+ uc->uc_mcontext.pstate = 1;
33
+ assert(info->si_addr == expected);
34
+ exit(EXIT_SUCCESS);
38
+}
35
+}
39
+
40
+#define NOP "nop"
41
+#define BTI_N "hint #32"
42
+#define BTI_C "hint #34"
43
+#define BTI_J "hint #36"
44
+#define BTI_JC "hint #38"
45
+
46
+#define BTYPE_1(DEST) \
47
+ asm("mov %0,#1; adr x16, 1f; br x16; 1: " DEST "; mov %0,#0" \
48
+ : "=r"(skipped) : : "x16")
49
+
50
+#define BTYPE_2(DEST) \
51
+ asm("mov %0,#1; adr x16, 1f; blr x16; 1: " DEST "; mov %0,#0" \
52
+ : "=r"(skipped) : : "x16", "x30")
53
+
54
+#define BTYPE_3(DEST) \
55
+ asm("mov %0,#1; adr x15, 1f; br x15; 1: " DEST "; mov %0,#0" \
56
+ : "=r"(skipped) : : "x15")
57
+
58
+#define TEST(WHICH, DEST, EXPECT) \
59
+ do { WHICH(DEST); fail += skipped ^ EXPECT; } while (0)
60
+
61
+
36
+
62
+int main()
37
+int main()
63
+{
38
+{
64
+ int fail = 0;
39
+ void *tmp;
65
+ int skipped;
66
+
40
+
67
+ /* Signal-like with SA_SIGINFO. */
41
+ struct sigaction sa = {
68
+ signal_info(SIGILL, skip2_sigill);
42
+ .sa_sigaction = sigbus,
43
+ .sa_flags = SA_SIGINFO
44
+ };
69
+
45
+
70
+ TEST(BTYPE_1, NOP, 1);
46
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
71
+ TEST(BTYPE_1, BTI_N, 1);
47
+ perror("sigaction");
72
+ TEST(BTYPE_1, BTI_C, 0);
48
+ return EXIT_FAILURE;
73
+ TEST(BTYPE_1, BTI_J, 0);
49
+ }
74
+ TEST(BTYPE_1, BTI_JC, 0);
75
+
50
+
76
+ TEST(BTYPE_2, NOP, 1);
51
+ asm volatile("adr %0, 1f + 1\n\t"
77
+ TEST(BTYPE_2, BTI_N, 1);
52
+ "str %0, %1\n\t"
78
+ TEST(BTYPE_2, BTI_C, 0);
53
+ "br %0\n"
79
+ TEST(BTYPE_2, BTI_J, 1);
54
+ "1:"
80
+ TEST(BTYPE_2, BTI_JC, 0);
55
+ : "=&r"(tmp), "=m"(expected));
81
+
56
+ abort();
82
+ TEST(BTYPE_3, NOP, 1);
83
+ TEST(BTYPE_3, BTI_N, 1);
84
+ TEST(BTYPE_3, BTI_C, 1);
85
+ TEST(BTYPE_3, BTI_J, 0);
86
+ TEST(BTYPE_3, BTI_JC, 0);
87
+
88
+ return fail;
89
+}
57
+}
90
diff --git a/tests/tcg/aarch64/bti-2.c b/tests/tcg/aarch64/bti-2.c
58
diff --git a/tests/tcg/arm/pcalign-a32.c b/tests/tcg/arm/pcalign-a32.c
91
new file mode 100644
59
new file mode 100644
92
index XXXXXXX..XXXXXXX
60
index XXXXXXX..XXXXXXX
93
--- /dev/null
61
--- /dev/null
94
+++ b/tests/tcg/aarch64/bti-2.c
62
+++ b/tests/tcg/arm/pcalign-a32.c
95
@@ -XXX,XX +XXX,XX @@
63
@@ -XXX,XX +XXX,XX @@
96
+/*
64
+/* Test PC misalignment exception */
97
+ * Branch target identification, basic notskip cases.
98
+ */
99
+
65
+
100
+#include <stdio.h>
66
+#ifdef __thumb__
101
+#include <signal.h>
67
+#error "This test must be compiled for ARM"
102
+#include <string.h>
103
+#include <unistd.h>
104
+#include <sys/mman.h>
105
+
106
+#ifndef PROT_BTI
107
+#define PROT_BTI 0x10
108
+#endif
68
+#endif
109
+
69
+
110
+static void skip2_sigill(int sig, siginfo_t *info, void *vuc)
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)
111
+{
78
+{
112
+ ucontext_t *uc = vuc;
79
+ assert(info->si_code == BUS_ADRALN);
113
+ uc->uc_mcontext.pc += 8;
80
+ assert(info->si_addr == expected);
114
+ uc->uc_mcontext.pstate = 1;
81
+ exit(EXIT_SUCCESS);
115
+}
82
+}
116
+
117
+#define NOP "nop"
118
+#define BTI_N "hint #32"
119
+#define BTI_C "hint #34"
120
+#define BTI_J "hint #36"
121
+#define BTI_JC "hint #38"
122
+
123
+#define BTYPE_1(DEST) \
124
+ "mov x1, #1\n\t" \
125
+ "adr x16, 1f\n\t" \
126
+ "br x16\n" \
127
+"1: " DEST "\n\t" \
128
+ "mov x1, #0"
129
+
130
+#define BTYPE_2(DEST) \
131
+ "mov x1, #1\n\t" \
132
+ "adr x16, 1f\n\t" \
133
+ "blr x16\n" \
134
+"1: " DEST "\n\t" \
135
+ "mov x1, #0"
136
+
137
+#define BTYPE_3(DEST) \
138
+ "mov x1, #1\n\t" \
139
+ "adr x15, 1f\n\t" \
140
+ "br x15\n" \
141
+"1: " DEST "\n\t" \
142
+ "mov x1, #0"
143
+
144
+#define TEST(WHICH, DEST, EXPECT) \
145
+ WHICH(DEST) "\n" \
146
+ ".if " #EXPECT "\n\t" \
147
+ "eor x1, x1," #EXPECT "\n" \
148
+ ".endif\n\t" \
149
+ "add x0, x0, x1\n\t"
150
+
151
+extern char test_begin[], test_end[];
152
+
153
+asm("\n"
154
+"test_begin:\n\t"
155
+ BTI_C "\n\t"
156
+ "mov x2, x30\n\t"
157
+ "mov x0, #0\n\t"
158
+
159
+ TEST(BTYPE_1, NOP, 1)
160
+ TEST(BTYPE_1, BTI_N, 1)
161
+ TEST(BTYPE_1, BTI_C, 0)
162
+ TEST(BTYPE_1, BTI_J, 0)
163
+ TEST(BTYPE_1, BTI_JC, 0)
164
+
165
+ TEST(BTYPE_2, NOP, 1)
166
+ TEST(BTYPE_2, BTI_N, 1)
167
+ TEST(BTYPE_2, BTI_C, 0)
168
+ TEST(BTYPE_2, BTI_J, 1)
169
+ TEST(BTYPE_2, BTI_JC, 0)
170
+
171
+ TEST(BTYPE_3, NOP, 1)
172
+ TEST(BTYPE_3, BTI_N, 1)
173
+ TEST(BTYPE_3, BTI_C, 1)
174
+ TEST(BTYPE_3, BTI_J, 0)
175
+ TEST(BTYPE_3, BTI_JC, 0)
176
+
177
+ "ret x2\n"
178
+"test_end:"
179
+);
180
+
83
+
181
+int main()
84
+int main()
182
+{
85
+{
183
+ struct sigaction sa;
86
+ void *tmp;
184
+
87
+
185
+ void *p = mmap(0, getpagesize(),
88
+ struct sigaction sa = {
186
+ PROT_EXEC | PROT_READ | PROT_WRITE | PROT_BTI,
89
+ .sa_sigaction = sigbus,
187
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
90
+ .sa_flags = SA_SIGINFO
188
+ if (p == MAP_FAILED) {
91
+ };
189
+ perror("mmap");
92
+
190
+ return 1;
93
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
94
+ perror("sigaction");
95
+ return EXIT_FAILURE;
191
+ }
96
+ }
192
+
97
+
193
+ memset(&sa, 0, sizeof(sa));
98
+ asm volatile("adr %0, 1f + 2\n\t"
194
+ sa.sa_sigaction = skip2_sigill;
99
+ "str %0, %1\n\t"
195
+ sa.sa_flags = SA_SIGINFO;
100
+ "bx %0\n"
196
+ if (sigaction(SIGILL, &sa, NULL) < 0) {
101
+ "1:"
197
+ perror("sigaction");
102
+ : "=&r"(tmp), "=m"(expected));
198
+ return 1;
199
+ }
200
+
103
+
201
+ memcpy(p, test_begin, test_end - test_begin);
104
+ /*
202
+ return ((int (*)(void))p)();
105
+ * From v8, it is CONSTRAINED UNPREDICTABLE whether BXWritePC aligns
203
+}
106
+ * the address or not. If so, we can legitimately fall through.
204
diff --git a/tests/tcg/aarch64/bti-crt.inc.c b/tests/tcg/aarch64/bti-crt.inc.c
107
+ */
205
new file mode 100644
108
+ return EXIT_SUCCESS;
206
index XXXXXXX..XXXXXXX
207
--- /dev/null
208
+++ b/tests/tcg/aarch64/bti-crt.inc.c
209
@@ -XXX,XX +XXX,XX @@
210
+/*
211
+ * Minimal user-environment for testing BTI.
212
+ *
213
+ * Normal libc is not (yet) built with BTI support enabled,
214
+ * and so could generate a BTI TRAP before ever reaching main.
215
+ */
216
+
217
+#include <stdlib.h>
218
+#include <signal.h>
219
+#include <ucontext.h>
220
+#include <asm/unistd.h>
221
+
222
+int main(void);
223
+
224
+void _start(void)
225
+{
226
+ exit(main());
227
+}
228
+
229
+void exit(int ret)
230
+{
231
+ register int x0 __asm__("x0") = ret;
232
+ register int x8 __asm__("x8") = __NR_exit;
233
+
234
+ asm volatile("svc #0" : : "r"(x0), "r"(x8));
235
+ __builtin_unreachable();
236
+}
237
+
238
+/*
239
+ * Irritatingly, the user API struct sigaction does not match the
240
+ * kernel API struct sigaction. So for simplicity, isolate the
241
+ * kernel ABI here, and make this act like signal.
242
+ */
243
+void signal_info(int sig, void (*fn)(int, siginfo_t *, ucontext_t *))
244
+{
245
+ struct kernel_sigaction {
246
+ void (*handler)(int, siginfo_t *, ucontext_t *);
247
+ unsigned long flags;
248
+ unsigned long restorer;
249
+ unsigned long mask;
250
+ } sa = { fn, SA_SIGINFO, 0, 0 };
251
+
252
+ register int x0 __asm__("x0") = sig;
253
+ register void *x1 __asm__("x1") = &sa;
254
+ register void *x2 __asm__("x2") = 0;
255
+ register int x3 __asm__("x3") = sizeof(unsigned long);
256
+ register int x8 __asm__("x8") = __NR_rt_sigaction;
257
+
258
+ asm volatile("svc #0"
259
+ : : "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x8) : "memory");
260
+}
109
+}
261
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
110
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
262
index XXXXXXX..XXXXXXX 100644
111
index XXXXXXX..XXXXXXX 100644
263
--- a/tests/tcg/aarch64/Makefile.target
112
--- a/tests/tcg/aarch64/Makefile.target
264
+++ b/tests/tcg/aarch64/Makefile.target
113
+++ b/tests/tcg/aarch64/Makefile.target
265
@@ -XXX,XX +XXX,XX @@ run-pauth-%: QEMU_OPTS += -cpu max
114
@@ -XXX,XX +XXX,XX @@ VPATH         += $(ARM_SRC)
266
run-plugin-pauth-%: QEMU_OPTS += -cpu max
115
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
267
endif
116
VPATH         += $(AARCH64_SRC)
268
117
269
+# BTI Tests
118
-# Float-convert Tests
270
+# bti-1 tests the elf notes, so we require special compiler support.
119
-AARCH64_TESTS=fcvt
271
+ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_BTI),)
120
+# Base architecture tests
272
+AARCH64_TESTS += bti-1
121
+AARCH64_TESTS=fcvt pcalign-a64
273
+bti-1: CFLAGS += -mbranch-protection=standard
122
274
+bti-1: LDFLAGS += -nostdlib
123
fcvt: LDFLAGS+=-lm
275
+endif
124
276
+# bti-2 tests PROT_BTI, so no special compiler support required.
125
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
277
+AARCH64_TESTS += bti-2
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
278
+
136
+
137
ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
138
279
# Semihosting smoke test for linux-user
139
# Semihosting smoke test for linux-user
280
AARCH64_TESTS += semihosting
281
run-semihosting: semihosting
282
diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
283
index XXXXXXX..XXXXXXX 100755
284
--- a/tests/tcg/configure.sh
285
+++ b/tests/tcg/configure.sh
286
@@ -XXX,XX +XXX,XX @@ for target in $target_list; do
287
-march=armv8.3-a -o $TMPE $TMPC; then
288
echo "CROSS_CC_HAS_ARMV8_3=y" >> $config_target_mak
289
fi
290
+ if do_compiler "$target_compiler" $target_compiler_cflags \
291
+ -mbranch-protection=standard -o $TMPE $TMPC; then
292
+ echo "CROSS_CC_HAS_ARMV8_BTI=y" >> $config_target_mak
293
+ fi
294
;;
295
esac
296
297
--
140
--
298
2.20.1
141
2.25.1
299
142
300
143
diff view generated by jsdifflib
1
If the M-profile low-overhead-branch extension is implemented, FPSCR
1
In the SSE decode function gen_sse(), we combine a byte
2
bits [18:16] are a new field LTPSIZE. If MVE is not implemented
2
'b' and a value 'b1' which can be [0..3], and switch on them:
3
(currently always true for us) then this field always reads as 4 and
3
b |= (b1 << 8);
4
ignores writes.
4
switch (b) {
5
...
6
default:
7
unknown_op:
8
gen_unknown_opcode(env, s);
9
return;
10
}
5
11
6
These bits used to be the vector-length field for the old
12
In three cases inside this switch, we were then also checking for
7
short-vector extension, so we need to take care that they are not
13
"if (b1 >= 2) { goto unknown_op; }".
8
misinterpreted as setting vec_len. We do this with a rearrangement
14
However, this can never happen, because the 'case' values in each place
9
of the vfp_set_fpscr() code that deals with vec_len, vec_stride
15
are 0x0nn or 0x1nn and the switch will have directed the b1 == (2, 3)
10
and also the QC bit; this obviates the need for the M-profile
16
cases to the default already.
11
only masking step that we used to have at the start of the function.
12
17
13
We provide a new field in CPUState for LTPSIZE, even though this
18
This check was added in commit c045af25a52e9 in 2010; the added code
14
will always be 4, in preparation for MVE, so we don't have to
19
was unnecessary then as well, and was apparently intended only to
15
come back later and split it out of the vfp.xregs[FPSCR] value.
20
ensure that we never accidentally ended up indexing off the end
16
(This state struct field will be saved and restored as part of
21
of an sse_op_table with only 2 entries as a result of future bugs
17
the FPSCR value via the vmstate_fpscr in machine.c.)
22
in the decode logic.
18
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
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20201019151301.2046-11-peter.maydell@linaro.org
22
---
30
---
23
target/arm/cpu.h | 1 +
31
target/i386/tcg/translate.c | 12 +++---------
24
target/arm/cpu.c | 9 +++++++++
32
1 file changed, 3 insertions(+), 9 deletions(-)
25
target/arm/vfp_helper.c | 6 ++++++
26
3 files changed, 16 insertions(+)
27
33
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
34
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
29
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
36
--- a/target/i386/tcg/translate.c
31
+++ b/target/arm/cpu.h
37
+++ b/target/i386/tcg/translate.c
32
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
38
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
33
uint32_t fpdscr[M_REG_NUM_BANKS];
39
case 0x171: /* shift xmm, im */
34
uint32_t cpacr[M_REG_NUM_BANKS];
40
case 0x172:
35
uint32_t nsacr;
41
case 0x173:
36
+ int ltpsize;
42
- if (b1 >= 2) {
37
} v7m;
43
- goto unknown_op;
38
44
- }
39
/* Information associated with an exception about to be taken:
45
val = x86_ldub_code(env, s);
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
if (is_xmm) {
41
index XXXXXXX..XXXXXXX 100644
47
tcg_gen_movi_tl(s->T0, val);
42
--- a/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
43
+++ b/target/arm/cpu.c
49
offsetof(CPUX86State, mmx_t0.MMX_L(1)));
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
50
op1_offset = offsetof(CPUX86State,mmx_t0);
45
uint8_t *rom;
51
}
46
uint32_t vecbase;
52
+ assert(b1 < 2);
47
53
sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
48
+ if (cpu_isar_feature(aa32_lob, cpu)) {
54
(((modrm >> 3)) & 7)][b1];
49
+ /*
55
if (!sse_fn_epp) {
50
+ * LTPSIZE is constant 4 if MVE not implemented, and resets
56
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
51
+ * to an UNKNOWN value if MVE is implemented. We choose to
57
rm = modrm & 7;
52
+ * always reset to 4.
58
reg = ((modrm >> 3) & 7) | REX_R(s);
53
+ */
59
mod = (modrm >> 6) & 3;
54
+ env->v7m.ltpsize = 4;
60
- if (b1 >= 2) {
55
+ }
61
- goto unknown_op;
56
+
62
- }
57
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
63
58
env->v7m.secure = true;
64
+ assert(b1 < 2);
59
} else {
65
sse_fn_epp = sse_op_table6[b].op[b1];
60
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
66
if (!sse_fn_epp) {
61
index XXXXXXX..XXXXXXX 100644
67
goto unknown_op;
62
--- a/target/arm/vfp_helper.c
68
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
63
+++ b/target/arm/vfp_helper.c
69
rm = modrm & 7;
64
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
70
reg = ((modrm >> 3) & 7) | REX_R(s);
65
| (env->vfp.vec_len << 16)
71
mod = (modrm >> 6) & 3;
66
| (env->vfp.vec_stride << 20);
72
- if (b1 >= 2) {
67
73
- goto unknown_op;
68
+ /*
74
- }
69
+ * M-profile LTPSIZE overlaps A-profile Stride; whichever of the
75
70
+ * two is not applicable to this CPU will always be zero.
76
+ assert(b1 < 2);
71
+ */
77
sse_fn_eppi = sse_op_table7[b].op[b1];
72
+ fpscr |= env->v7m.ltpsize << 16;
78
if (!sse_fn_eppi) {
73
+
79
goto unknown_op;
74
fpscr |= vfp_get_fpscr_from_host(env);
75
76
i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
77
--
80
--
78
2.20.1
81
2.25.1
79
82
80
83
diff view generated by jsdifflib
1
M-profile CPUs with half-precision floating point support should
1
The qemu-common.h header is not supposed to be included from any
2
be able to write to FPSCR.FZ16, but an M-profile specific masking
2
other header files, only from .c files (as documented in a comment at
3
of the value at the top of vfp_set_fpscr() currently prevents that.
3
the start of it).
4
This is not yet an active bug because we have no M-profile
5
FP16 CPUs, but needs to be fixed before we can add any.
6
4
7
The bits that the masking is effectively preventing from being
5
include/hw/i386/x86.h and include/hw/i386/microvm.h break this rule.
8
set are the A-profile only short-vector Len and Stride fields,
6
In fact, the include is not required at all, so we can just drop it
9
plus the Neon QC bit. Rearrange the order of the function so
7
from both files.
10
that those fields are handled earlier and only under a suitable
11
guard; this allows us to drop the M-profile specific masking,
12
making FZ16 writeable.
13
14
This change also makes the QC bit correctly RAZ/WI for older
15
no-Neon A-profile cores.
16
17
This refactoring also paves the way for the low-overhead-branch
18
LTPSIZE field, which uses some of the bits that are used for
19
A-profile Stride and Len.
20
8
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20201019151301.2046-10-peter.maydell@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20211129200510.1233037-2-peter.maydell@linaro.org
24
---
13
---
25
target/arm/vfp_helper.c | 47 ++++++++++++++++++++++++-----------------
14
include/hw/i386/microvm.h | 1 -
26
1 file changed, 28 insertions(+), 19 deletions(-)
15
include/hw/i386/x86.h | 1 -
16
2 files changed, 2 deletions(-)
27
17
28
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
18
diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
29
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/vfp_helper.c
20
--- a/include/hw/i386/microvm.h
31
+++ b/target/arm/vfp_helper.c
21
+++ b/include/hw/i386/microvm.h
32
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
22
@@ -XXX,XX +XXX,XX @@
33
val &= ~FPCR_FZ16;
23
#ifndef HW_I386_MICROVM_H
34
}
24
#define HW_I386_MICROVM_H
35
25
36
- if (arm_feature(env, ARM_FEATURE_M)) {
26
-#include "qemu-common.h"
37
+ vfp_set_fpscr_to_host(env, val);
27
#include "exec/hwaddr.h"
38
+
28
#include "qemu/notify.h"
39
+ if (!arm_feature(env, ARM_FEATURE_M)) {
29
40
/*
30
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
41
- * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
31
index XXXXXXX..XXXXXXX 100644
42
- * and also for the trapped-exception-handling bits IxE.
32
--- a/include/hw/i386/x86.h
43
+ * Short-vector length and stride; on M-profile these bits
33
+++ b/include/hw/i386/x86.h
44
+ * are used for different purposes.
34
@@ -XXX,XX +XXX,XX @@
45
+ * We can't make this conditional be "if MVFR0.FPShVec != 0",
35
#ifndef HW_I386_X86_H
46
+ * because in v7A no-short-vector-support cores still had to
36
#define HW_I386_X86_H
47
+ * allow Stride/Len to be written with the only effect that
37
48
+ * some insns are required to UNDEF if the guest sets them.
38
-#include "qemu-common.h"
49
+ *
39
#include "exec/hwaddr.h"
50
+ * TODO: if M-profile MVE implemented, set LTPSIZE.
40
#include "qemu/notify.h"
51
*/
41
52
- val &= 0xf7c0009f;
53
+ env->vfp.vec_len = extract32(val, 16, 3);
54
+ env->vfp.vec_stride = extract32(val, 20, 2);
55
}
56
57
- vfp_set_fpscr_to_host(env, val);
58
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
59
+ /*
60
+ * The bit we set within fpscr_q is arbitrary; the register as a
61
+ * whole being zero/non-zero is what counts.
62
+ * TODO: M-profile MVE also has a QC bit.
63
+ */
64
+ env->vfp.qc[0] = val & FPCR_QC;
65
+ env->vfp.qc[1] = 0;
66
+ env->vfp.qc[2] = 0;
67
+ env->vfp.qc[3] = 0;
68
+ }
69
70
/*
71
* We don't implement trapped exception handling, so the
72
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
73
*
74
- * If we exclude the exception flags, IOC|DZC|OFC|UFC|IXC|IDC
75
- * (which are stored in fp_status), and the other RES0 bits
76
- * in between, then we clear all of the low 16 bits.
77
+ * The exception flags IOC|DZC|OFC|UFC|IXC|IDC are stored in
78
+ * fp_status; QC, Len and Stride are stored separately earlier.
79
+ * Clear out all of those and the RES0 bits: only NZCV, AHP, DN,
80
+ * FZ, RMode and FZ16 are kept in vfp.xregs[FPSCR].
81
*/
82
env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
83
- env->vfp.vec_len = (val >> 16) & 7;
84
- env->vfp.vec_stride = (val >> 20) & 3;
85
-
86
- /*
87
- * The bit we set within fpscr_q is arbitrary; the register as a
88
- * whole being zero/non-zero is what counts.
89
- */
90
- env->vfp.qc[0] = val & FPCR_QC;
91
- env->vfp.qc[1] = 0;
92
- env->vfp.qc[2] = 0;
93
- env->vfp.qc[3] = 0;
94
}
95
96
void vfp_set_fpscr(CPUARMState *env, uint32_t val)
97
--
42
--
98
2.20.1
43
2.25.1
99
44
100
45
diff view generated by jsdifflib
1
v8.1M's "low-overhead-loop" extension has three instructions
1
The qemu-common.h header is not supposed to be included from any
2
for looping:
2
other header files, only from .c files (as documented in a comment at
3
* DLS (start of a do-loop)
3
the start of it).
4
* WLS (start of a while-loop)
5
* LE (end of a loop)
6
4
7
The loop-start instructions are both simple operations to start a
5
Move the include to linux-user/hexagon/cpu_loop.c, which needs it for
8
loop whose iteration count (if any) is in LR. The loop-end
6
the declaration of cpu_exec_step_atomic().
9
instruction handles "decrement iteration count and jump back to loop
10
start"; it also caches the information about the branch back to the
11
start of the loop to improve performance of the branch on subsequent
12
iterations.
13
14
As with the branch-future instructions, the architecture permits an
15
implementation to discard the LO_BRANCH_INFO cache at any time, and
16
QEMU takes the IMPDEF option to never set it in the first place
17
(equivalent to discarding it immediately), because for us a "real"
18
implementation would be unnecessary complexity.
19
20
(This implementation only provides the simple looping constructs; the
21
vector extension MVE (Helium) adds some extra variants to handle
22
looping across vectors. We'll add those later when we implement
23
MVE.)
24
7
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20201019151301.2046-8-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
28
---
13
---
29
target/arm/t32.decode | 8 ++++
14
target/hexagon/cpu.h | 1 -
30
target/arm/translate.c | 93 +++++++++++++++++++++++++++++++++++++++++-
15
linux-user/hexagon/cpu_loop.c | 1 +
31
2 files changed, 99 insertions(+), 2 deletions(-)
16
2 files changed, 1 insertion(+), 1 deletion(-)
32
17
33
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
18
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
34
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/t32.decode
20
--- a/target/hexagon/cpu.h
36
+++ b/target/arm/t32.decode
21
+++ b/target/hexagon/cpu.h
37
@@ -XXX,XX +XXX,XX @@ BL 1111 0. .......... 11.1 ............ @branch24
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUHexagonState CPUHexagonState;
38
BF 1111 0 boff:4 10 ----- 1110 - ---------- 1 # BF
23
39
BF 1111 0 boff:4 11 ----- 1110 0 0000000000 1 # BFX, BFLX
24
#include "fpu/softfloat-types.h"
40
]
25
41
+ [
26
-#include "qemu-common.h"
42
+ # LE and WLS immediate
27
#include "exec/cpu-defs.h"
43
+ %lob_imm 1:10 11:1 !function=times_2
28
#include "hex_regs.h"
44
+
29
#include "mmvec/mmvec.h"
45
+ DLS 1111 0 0000 100 rn:4 1110 0000 0000 0001
30
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
46
+ WLS 1111 0 0000 100 rn:4 1100 . .......... 1 imm=%lob_imm
47
+ LE 1111 0 0000 0 f:1 0 1111 1100 . .......... 1 imm=%lob_imm
48
+ ]
49
}
50
diff --git a/target/arm/translate.c b/target/arm/translate.c
51
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate.c
32
--- a/linux-user/hexagon/cpu_loop.c
53
+++ b/target/arm/translate.c
33
+++ b/linux-user/hexagon/cpu_loop.c
54
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
34
@@ -XXX,XX +XXX,XX @@
55
s->base.is_jmp = DISAS_NORETURN;
35
*/
56
}
36
57
37
#include "qemu/osdep.h"
58
-static inline void gen_jmp (DisasContext *s, uint32_t dest)
38
+#include "qemu-common.h"
59
+/* Jump, specifying which TB number to use if we gen_goto_tb() */
39
#include "qemu.h"
60
+static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
40
#include "user-internals.h"
61
{
41
#include "cpu_loop-common.h"
62
if (unlikely(is_singlestepping(s))) {
63
/* An indirect jump so that we still trigger the debug exception. */
64
gen_set_pc_im(s, dest);
65
s->base.is_jmp = DISAS_JUMP;
66
} else {
67
- gen_goto_tb(s, 0, dest);
68
+ gen_goto_tb(s, tbno, dest);
69
}
70
}
71
72
+static inline void gen_jmp(DisasContext *s, uint32_t dest)
73
+{
74
+ gen_jmp_tb(s, dest, 0);
75
+}
76
+
77
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
78
{
79
if (x)
80
@@ -XXX,XX +XXX,XX @@ static bool trans_BF(DisasContext *s, arg_BF *a)
81
return true;
82
}
83
84
+static bool trans_DLS(DisasContext *s, arg_DLS *a)
85
+{
86
+ /* M-profile low-overhead loop start */
87
+ TCGv_i32 tmp;
88
+
89
+ if (!dc_isar_feature(aa32_lob, s)) {
90
+ return false;
91
+ }
92
+ if (a->rn == 13 || a->rn == 15) {
93
+ /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
94
+ return false;
95
+ }
96
+
97
+ /* Not a while loop, no tail predication: just set LR to the count */
98
+ tmp = load_reg(s, a->rn);
99
+ store_reg(s, 14, tmp);
100
+ return true;
101
+}
102
+
103
+static bool trans_WLS(DisasContext *s, arg_WLS *a)
104
+{
105
+ /* M-profile low-overhead while-loop start */
106
+ TCGv_i32 tmp;
107
+ TCGLabel *nextlabel;
108
+
109
+ if (!dc_isar_feature(aa32_lob, s)) {
110
+ return false;
111
+ }
112
+ if (a->rn == 13 || a->rn == 15) {
113
+ /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
114
+ return false;
115
+ }
116
+ if (s->condexec_mask) {
117
+ /*
118
+ * WLS in an IT block is CONSTRAINED UNPREDICTABLE;
119
+ * we choose to UNDEF, because otherwise our use of
120
+ * gen_goto_tb(1) would clash with the use of TB exit 1
121
+ * in the dc->condjmp condition-failed codepath in
122
+ * arm_tr_tb_stop() and we'd get an assertion.
123
+ */
124
+ return false;
125
+ }
126
+ nextlabel = gen_new_label();
127
+ tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel);
128
+ tmp = load_reg(s, a->rn);
129
+ store_reg(s, 14, tmp);
130
+ gen_jmp_tb(s, s->base.pc_next, 1);
131
+
132
+ gen_set_label(nextlabel);
133
+ gen_jmp(s, read_pc(s) + a->imm);
134
+ return true;
135
+}
136
+
137
+static bool trans_LE(DisasContext *s, arg_LE *a)
138
+{
139
+ /*
140
+ * M-profile low-overhead loop end. The architecture permits an
141
+ * implementation to discard the LO_BRANCH_INFO cache at any time,
142
+ * and we take the IMPDEF option to never set it in the first place
143
+ * (equivalent to always discarding it immediately), because for QEMU
144
+ * a "real" implementation would be complicated and wouldn't execute
145
+ * any faster.
146
+ */
147
+ TCGv_i32 tmp;
148
+
149
+ if (!dc_isar_feature(aa32_lob, s)) {
150
+ return false;
151
+ }
152
+
153
+ if (!a->f) {
154
+ /* Not loop-forever. If LR <= 1 this is the last loop: do nothing. */
155
+ arm_gen_condlabel(s);
156
+ tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, s->condlabel);
157
+ /* Decrement LR */
158
+ tmp = load_reg(s, 14);
159
+ tcg_gen_addi_i32(tmp, tmp, -1);
160
+ store_reg(s, 14, tmp);
161
+ }
162
+ /* Jump back to the loop start */
163
+ gen_jmp(s, read_pc(s) - a->imm);
164
+ return true;
165
+}
166
+
167
static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
168
{
169
TCGv_i32 addr, tmp;
170
--
42
--
171
2.20.1
43
2.25.1
172
44
173
45
diff view generated by jsdifflib
1
From v8.1M, disabled-coprocessor handling changes slightly:
1
The qemu-common.h header is not supposed to be included from any
2
* coprocessors 8, 9, 14 and 15 are also governed by the
2
other header files, only from .c files (as documented in a comment at
3
cp10 enable bit, like cp11
3
the start of it).
4
* an extra range of instruction patterns is considered
5
to be inside the coprocessor space
6
4
7
We previously marked these up with TODO comments; implement the
5
Nothing actually relies on target/rx/cpu.h including it, so we can
8
correct behaviour.
6
just drop the include.
9
10
Unfortunately there is no ID register field which indicates this
11
behaviour. We could in theory test an unrelated ID register which
12
indicates guaranteed-to-be-in-v8.1M behaviour like ID_ISAR0.CmpBranch
13
>= 3 (low-overhead-loops), but it seems better to simply define a new
14
ARM_FEATURE_V8_1M feature flag and use it for this and other
15
new-in-v8.1M behaviour that isn't identifiable from the ID registers.
16
7
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20201019151301.2046-3-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
20
---
14
---
21
target/arm/cpu.h | 1 +
15
target/rx/cpu.h | 1 -
22
target/arm/m-nocp.decode | 10 ++++++----
16
1 file changed, 1 deletion(-)
23
target/arm/translate-vfp.c.inc | 17 +++++++++++++++--
24
3 files changed, 22 insertions(+), 6 deletions(-)
25
17
26
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
27
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.h
20
--- a/target/rx/cpu.h
29
+++ b/target/arm/cpu.h
21
+++ b/target/rx/cpu.h
30
@@ -XXX,XX +XXX,XX @@ enum arm_features {
31
ARM_FEATURE_VBAR, /* has cp15 VBAR */
32
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
33
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
34
+ ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
35
};
36
37
static inline int arm_feature(CPUARMState *env, int feature)
38
diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/m-nocp.decode
41
+++ b/target/arm/m-nocp.decode
42
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
43
# If the coprocessor is not present or disabled then we will generate
23
#define RX_CPU_H
44
# the NOCP exception; otherwise we let the insn through to the main decode.
24
45
25
#include "qemu/bitops.h"
46
+&nocp cp
26
-#include "qemu-common.h"
47
+
27
#include "hw/registerfields.h"
48
{
28
#include "cpu-qom.h"
49
# Special cases which do not take an early NOCP: VLLDM and VLSTM
29
50
VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 0000 0000
51
# TODO: VSCCLRM (new in v8.1M) is similar:
52
#VSCCLRM 1110 1100 1-01 1111 ---- 1011 ---- ---0
53
54
- NOCP 111- 1110 ---- ---- ---- cp:4 ---- ----
55
- NOCP 111- 110- ---- ---- ---- cp:4 ---- ----
56
- # TODO: From v8.1M onwards we will also want this range to NOCP
57
- #NOCP_8_1 111- 1111 ---- ---- ---- ---- ---- ---- cp=10
58
+ NOCP 111- 1110 ---- ---- ---- cp:4 ---- ---- &nocp
59
+ NOCP 111- 110- ---- ---- ---- cp:4 ---- ---- &nocp
60
+ # From v8.1M onwards this range will also NOCP:
61
+ NOCP_8_1 111- 1111 ---- ---- ---- ---- ---- ---- &nocp cp=10
62
}
63
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate-vfp.c.inc
66
+++ b/target/arm/translate-vfp.c.inc
67
@@ -XXX,XX +XXX,XX @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
68
return true;
69
}
70
71
-static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
72
+static bool trans_NOCP(DisasContext *s, arg_nocp *a)
73
{
74
/*
75
* Handle M-profile early check for disabled coprocessor:
76
@@ -XXX,XX +XXX,XX @@ static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
77
if (a->cp == 11) {
78
a->cp = 10;
79
}
80
- /* TODO: in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
81
+ if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
82
+ (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
83
+ /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
84
+ a->cp = 10;
85
+ }
86
87
if (a->cp != 10) {
88
gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
89
@@ -XXX,XX +XXX,XX @@ static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
90
return false;
91
}
92
93
+static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
94
+{
95
+ /* This range needs a coprocessor check for v8.1M and later only */
96
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
97
+ return false;
98
+ }
99
+ return trans_NOCP(s, a);
100
+}
101
+
102
static bool trans_VINS(DisasContext *s, arg_VINS *a)
103
{
104
TCGv_i32 rd, rm;
105
--
30
--
106
2.20.1
31
2.25.1
107
32
108
33
diff view generated by jsdifflib
1
For AArch32, unlike the VCVT of integer to float, which honours the
1
A lot of C files in hw/arm include qemu-common.h when they don't
2
rounding mode specified by the FPSCR, VCVT of fixed-point to float is
2
need anything from it. Drop the include lines.
3
always round-to-nearest. (AArch64 fixed-point-to-float conversions
4
always honour the FPCR rounding mode.)
5
3
6
Implement this by providing _round_to_nearest versions of the
4
omap1.c, pxa2xx.c and strongarm.c retain the include because they
7
relevant helpers which set the rounding mode temporarily when making
5
use it for the prototype of qemu_get_timedate().
8
the call to the underlying softfloat function.
9
10
We only need to change the VFP VCVT instructions, because the
11
standard- FPSCR value used by the Neon VCVT is always set to
12
round-to-nearest, so we don't need to do the extra work of saving
13
and restoring the rounding mode.
14
6
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20201013103532.13391-1-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
18
---
13
---
19
target/arm/helper.h | 13 +++++++++++++
14
hw/arm/boot.c | 1 -
20
target/arm/vfp_helper.c | 23 ++++++++++++++++++++++-
15
hw/arm/digic_boards.c | 1 -
21
target/arm/translate-vfp.c.inc | 24 ++++++++++++------------
16
hw/arm/highbank.c | 1 -
22
3 files changed, 47 insertions(+), 13 deletions(-)
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(-)
23
23
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
24
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
25
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
26
--- a/hw/arm/boot.c
27
+++ b/target/arm/helper.h
27
+++ b/hw/arm/boot.c
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
28
@@ -XXX,XX +XXX,XX @@
29
DEF_HELPER_3(vfp_sqtoh, f16, i64, i32, ptr)
29
*/
30
DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr)
30
31
31
#include "qemu/osdep.h"
32
+DEF_HELPER_3(vfp_shtos_round_to_nearest, f32, i32, i32, ptr)
32
-#include "qemu-common.h"
33
+DEF_HELPER_3(vfp_sltos_round_to_nearest, f32, i32, i32, ptr)
33
#include "qemu/datadir.h"
34
+DEF_HELPER_3(vfp_uhtos_round_to_nearest, f32, i32, i32, ptr)
34
#include "qemu/error-report.h"
35
+DEF_HELPER_3(vfp_ultos_round_to_nearest, f32, i32, i32, ptr)
35
#include "qapi/error.h"
36
+DEF_HELPER_3(vfp_shtod_round_to_nearest, f64, i64, i32, ptr)
36
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
37
+DEF_HELPER_3(vfp_sltod_round_to_nearest, f64, i64, i32, ptr)
38
+DEF_HELPER_3(vfp_uhtod_round_to_nearest, f64, i64, i32, ptr)
39
+DEF_HELPER_3(vfp_ultod_round_to_nearest, f64, i64, i32, ptr)
40
+DEF_HELPER_3(vfp_shtoh_round_to_nearest, f16, i32, i32, ptr)
41
+DEF_HELPER_3(vfp_uhtoh_round_to_nearest, f16, i32, i32, ptr)
42
+DEF_HELPER_3(vfp_sltoh_round_to_nearest, f16, i32, i32, ptr)
43
+DEF_HELPER_3(vfp_ultoh_round_to_nearest, f16, i32, i32, ptr)
44
+
45
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
46
47
DEF_HELPER_FLAGS_3(vfp_fcvt_f16_to_f32, TCG_CALL_NO_RWG, f32, f16, ptr, i32)
48
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
49
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/vfp_helper.c
38
--- a/hw/arm/digic_boards.c
51
+++ b/target/arm/vfp_helper.c
39
+++ b/hw/arm/digic_boards.c
52
@@ -XXX,XX +XXX,XX @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
40
@@ -XXX,XX +XXX,XX @@
53
return float64_to_float32(x, &env->vfp.fp_status);
41
54
}
42
#include "qemu/osdep.h"
55
43
#include "qapi/error.h"
56
-/* VFP3 fixed point conversion. */
44
-#include "qemu-common.h"
57
+/*
45
#include "qemu/datadir.h"
58
+ * VFP3 fixed point conversion. The AArch32 versions of fix-to-float
46
#include "hw/boards.h"
59
+ * must always round-to-nearest; the AArch64 ones honour the FPSCR
47
#include "qemu/error-report.h"
60
+ * rounding mode. (For AArch32 Neon the standard-FPSCR is set to
48
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
61
+ * round-to-nearest so either helper will work.) AArch32 float-to-fix
62
+ * must round-to-zero.
63
+ */
64
#define VFP_CONV_FIX_FLOAT(name, p, fsz, ftype, isz, itype) \
65
ftype HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
66
void *fpstp) \
67
{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); }
68
69
+#define VFP_CONV_FIX_FLOAT_ROUND(name, p, fsz, ftype, isz, itype) \
70
+ ftype HELPER(vfp_##name##to##p##_round_to_nearest)(uint##isz##_t x, \
71
+ uint32_t shift, \
72
+ void *fpstp) \
73
+ { \
74
+ ftype ret; \
75
+ float_status *fpst = fpstp; \
76
+ FloatRoundMode oldmode = fpst->float_rounding_mode; \
77
+ fpst->float_rounding_mode = float_round_nearest_even; \
78
+ ret = itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); \
79
+ fpst->float_rounding_mode = oldmode; \
80
+ return ret; \
81
+ }
82
+
83
#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, ftype, isz, itype, ROUND, suff) \
84
uint##isz##_t HELPER(vfp_to##name##p##suff)(ftype x, uint32_t shift, \
85
void *fpst) \
86
@@ -XXX,XX +XXX,XX @@ uint##isz##_t HELPER(vfp_to##name##p##suff)(ftype x, uint32_t shift, \
87
88
#define VFP_CONV_FIX(name, p, fsz, ftype, isz, itype) \
89
VFP_CONV_FIX_FLOAT(name, p, fsz, ftype, isz, itype) \
90
+VFP_CONV_FIX_FLOAT_ROUND(name, p, fsz, ftype, isz, itype) \
91
VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, ftype, isz, itype, \
92
float_round_to_zero, _round_to_zero) \
93
VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, ftype, isz, itype, \
94
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
95
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/translate-vfp.c.inc
50
--- a/hw/arm/highbank.c
97
+++ b/target/arm/translate-vfp.c.inc
51
+++ b/hw/arm/highbank.c
98
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
52
@@ -XXX,XX +XXX,XX @@
99
/* Switch on op:U:sx bits */
53
*/
100
switch (a->opc) {
54
101
case 0:
55
#include "qemu/osdep.h"
102
- gen_helper_vfp_shtoh(vd, vd, shift, fpst);
56
-#include "qemu-common.h"
103
+ gen_helper_vfp_shtoh_round_to_nearest(vd, vd, shift, fpst);
57
#include "qemu/datadir.h"
104
break;
58
#include "qapi/error.h"
105
case 1:
59
#include "hw/sysbus.h"
106
- gen_helper_vfp_sltoh(vd, vd, shift, fpst);
60
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
107
+ gen_helper_vfp_sltoh_round_to_nearest(vd, vd, shift, fpst);
61
index XXXXXXX..XXXXXXX 100644
108
break;
62
--- a/hw/arm/npcm7xx_boards.c
109
case 2:
63
+++ b/hw/arm/npcm7xx_boards.c
110
- gen_helper_vfp_uhtoh(vd, vd, shift, fpst);
64
@@ -XXX,XX +XXX,XX @@
111
+ gen_helper_vfp_uhtoh_round_to_nearest(vd, vd, shift, fpst);
65
#include "hw/qdev-core.h"
112
break;
66
#include "hw/qdev-properties.h"
113
case 3:
67
#include "qapi/error.h"
114
- gen_helper_vfp_ultoh(vd, vd, shift, fpst);
68
-#include "qemu-common.h"
115
+ gen_helper_vfp_ultoh_round_to_nearest(vd, vd, shift, fpst);
69
#include "qemu/datadir.h"
116
break;
70
#include "qemu/units.h"
117
case 4:
71
#include "sysemu/blockdev.h"
118
gen_helper_vfp_toshh_round_to_zero(vd, vd, shift, fpst);
72
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
73
index XXXXXXX..XXXXXXX 100644
120
/* Switch on op:U:sx bits */
74
--- a/hw/arm/sbsa-ref.c
121
switch (a->opc) {
75
+++ b/hw/arm/sbsa-ref.c
122
case 0:
76
@@ -XXX,XX +XXX,XX @@
123
- gen_helper_vfp_shtos(vd, vd, shift, fpst);
77
*/
124
+ gen_helper_vfp_shtos_round_to_nearest(vd, vd, shift, fpst);
78
125
break;
79
#include "qemu/osdep.h"
126
case 1:
80
-#include "qemu-common.h"
127
- gen_helper_vfp_sltos(vd, vd, shift, fpst);
81
#include "qemu/datadir.h"
128
+ gen_helper_vfp_sltos_round_to_nearest(vd, vd, shift, fpst);
82
#include "qapi/error.h"
129
break;
83
#include "qemu/error-report.h"
130
case 2:
84
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
131
- gen_helper_vfp_uhtos(vd, vd, shift, fpst);
85
index XXXXXXX..XXXXXXX 100644
132
+ gen_helper_vfp_uhtos_round_to_nearest(vd, vd, shift, fpst);
86
--- a/hw/arm/stm32f405_soc.c
133
break;
87
+++ b/hw/arm/stm32f405_soc.c
134
case 3:
88
@@ -XXX,XX +XXX,XX @@
135
- gen_helper_vfp_ultos(vd, vd, shift, fpst);
89
136
+ gen_helper_vfp_ultos_round_to_nearest(vd, vd, shift, fpst);
90
#include "qemu/osdep.h"
137
break;
91
#include "qapi/error.h"
138
case 4:
92
-#include "qemu-common.h"
139
gen_helper_vfp_toshs_round_to_zero(vd, vd, shift, fpst);
93
#include "exec/address-spaces.h"
140
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
94
#include "sysemu/sysemu.h"
141
/* Switch on op:U:sx bits */
95
#include "hw/arm/stm32f405_soc.h"
142
switch (a->opc) {
96
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
143
case 0:
97
index XXXXXXX..XXXXXXX 100644
144
- gen_helper_vfp_shtod(vd, vd, shift, fpst);
98
--- a/hw/arm/vexpress.c
145
+ gen_helper_vfp_shtod_round_to_nearest(vd, vd, shift, fpst);
99
+++ b/hw/arm/vexpress.c
146
break;
100
@@ -XXX,XX +XXX,XX @@
147
case 1:
101
148
- gen_helper_vfp_sltod(vd, vd, shift, fpst);
102
#include "qemu/osdep.h"
149
+ gen_helper_vfp_sltod_round_to_nearest(vd, vd, shift, fpst);
103
#include "qapi/error.h"
150
break;
104
-#include "qemu-common.h"
151
case 2:
105
#include "qemu/datadir.h"
152
- gen_helper_vfp_uhtod(vd, vd, shift, fpst);
106
#include "cpu.h"
153
+ gen_helper_vfp_uhtod_round_to_nearest(vd, vd, shift, fpst);
107
#include "hw/sysbus.h"
154
break;
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
155
case 3:
109
index XXXXXXX..XXXXXXX 100644
156
- gen_helper_vfp_ultod(vd, vd, shift, fpst);
110
--- a/hw/arm/virt.c
157
+ gen_helper_vfp_ultod_round_to_nearest(vd, vd, shift, fpst);
111
+++ b/hw/arm/virt.c
158
break;
112
@@ -XXX,XX +XXX,XX @@
159
case 4:
113
*/
160
gen_helper_vfp_toshd_round_to_zero(vd, vd, shift, fpst);
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"
161
--
120
--
162
2.20.1
121
2.25.1
163
122
164
123
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The calculation of the length of TLB range invalidate operations
2
in tlbi_aa64_range_get_length() is incorrect in two ways:
3
* the NUM field is 5 bits, but we read only 4 bits
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
2
11
3
Unlike many other bits in HCR_EL2, the description for this
12
Thanks to the bug report submitter Cha HyunSoo for identifying
4
bit does not contain the phrase "if ... this field behaves
13
both these errors.
5
as 0 for all purposes other than", so do not squash the bit
6
in arm_hcr_el2_eff.
7
14
8
Instead, replicate the E2H+TGE test in the two places that
15
Fixes: 84940ed82552d3c ("target/arm: Add support for FEAT_TLBIRANGE")
9
require it.
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@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
22
---
23
target/arm/helper.c | 6 +++---
24
1 file changed, 3 insertions(+), 3 deletions(-)
10
25
11
Reported-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
14
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
15
Message-id: 20201008162155.161886-4-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/internals.h | 9 +++++----
19
target/arm/helper.c | 9 +++++----
20
2 files changed, 10 insertions(+), 8 deletions(-)
21
22
diff --git a/target/arm/internals.h b/target/arm/internals.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/internals.h
25
+++ b/target/arm/internals.h
26
@@ -XXX,XX +XXX,XX @@ static inline bool allocation_tag_access_enabled(CPUARMState *env, int el,
27
&& !(env->cp15.scr_el3 & SCR_ATA)) {
28
return false;
29
}
30
- if (el < 2
31
- && arm_feature(env, ARM_FEATURE_EL2)
32
- && !(arm_hcr_el2_eff(env) & HCR_ATA)) {
33
- return false;
34
+ if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
35
+ uint64_t hcr = arm_hcr_el2_eff(env);
36
+ if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
37
+ return false;
38
+ }
39
}
40
sctlr &= (el == 0 ? SCTLR_ATA0 : SCTLR_ATA);
41
return sctlr != 0;
42
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
43
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper.c
28
--- a/target/arm/helper.c
45
+++ b/target/arm/helper.c
29
+++ b/target/arm/helper.c
46
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
30
@@ -XXX,XX +XXX,XX @@ static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
47
{
31
uint64_t exponent;
48
int el = arm_current_el(env);
32
uint64_t length;
49
33
50
- if (el < 2 &&
34
- num = extract64(value, 39, 4);
51
- arm_feature(env, ARM_FEATURE_EL2) &&
35
+ num = extract64(value, 39, 5);
52
- !(arm_hcr_el2_eff(env) & HCR_ATA)) {
36
scale = extract64(value, 44, 2);
53
- return CP_ACCESS_TRAP_EL2;
37
page_size_granule = extract64(value, 46, 2);
54
+ if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
38
55
+ uint64_t hcr = arm_hcr_el2_eff(env);
39
- page_shift = page_size_granule * 2 + 12;
56
+ if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
40
-
57
+ return CP_ACCESS_TRAP_EL2;
41
if (page_size_granule == 0) {
58
+ }
42
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
43
page_size_granule);
44
return 0;
59
}
45
}
60
if (el < 3 &&
46
61
arm_feature(env, ARM_FEATURE_EL3) &&
47
+ page_shift = (page_size_granule - 1) * 2 + 12;
48
+
49
exponent = (5 * scale) + 1;
50
length = (num + 1) << (exponent + page_shift);
51
62
--
52
--
63
2.20.1
53
2.25.1
64
54
65
55
diff view generated by jsdifflib
1
v8.1M implements a new 'branch future' feature, which is a
1
From: Patrick Venture <venture@google.com>
2
set of instructions that request the CPU to perform a branch
3
"in the future", when it reaches a particular execution address.
4
In hardware, the expected implementation is that the information
5
about the branch location and destination is cached and then
6
acted upon when execution reaches the specified address.
7
However the architecture permits an implementation to discard
8
this cached information at any point, and so guest code must
9
always include a normal branch insn at the branch point as
10
a fallback. In particular, an implementation is specifically
11
permitted to treat all BF insns as NOPs (which is equivalent
12
to discarding the cached information immediately).
13
2
14
For QEMU, implementing this caching of branch information
3
The rx_active boolean change to true should always trigger a try_read
15
would be complicated and would not improve the speed of
4
call that flushes the queue.
16
execution at all, so we make the IMPDEF choice to implement
17
all BF insns as NOPs.
18
5
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20211203221002.1719306-1-venture@google.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Message-id: 20201019151301.2046-7-peter.maydell@linaro.org
22
---
10
---
23
target/arm/cpu.h | 6 ++++++
11
hw/net/npcm7xx_emc.c | 18 ++++++++----------
24
target/arm/t32.decode | 13 ++++++++++++-
12
1 file changed, 8 insertions(+), 10 deletions(-)
25
target/arm/translate.c | 20 ++++++++++++++++++++
26
3 files changed, 38 insertions(+), 1 deletion(-)
27
13
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
29
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
16
--- a/hw/net/npcm7xx_emc.c
31
+++ b/target/arm/cpu.h
17
+++ b/hw/net/npcm7xx_emc.c
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
18
@@ -XXX,XX +XXX,XX @@ static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
33
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
19
emc_set_mista(emc, mista_flag);
34
}
20
}
35
21
36
+static inline bool isar_feature_aa32_lob(const ARMISARegisters *id)
22
+static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc)
37
+{
23
+{
38
+ /* (M-profile) low-overhead loops and branch future */
24
+ emc->rx_active = true;
39
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3;
25
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
40
+}
26
+}
41
+
27
+
42
static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
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)
43
{
43
{
44
return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
44
NPCM7xxEMCState *emc = opaque;
45
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
45
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
46
index XXXXXXX..XXXXXXX 100644
46
emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
47
--- a/target/arm/t32.decode
47
}
48
+++ b/target/arm/t32.decode
48
if (value & REG_MCMDR_RXON) {
49
@@ -XXX,XX +XXX,XX @@ MRC 1110 1110 ... 1 .... .... .... ... 1 .... @mcr
49
- emc->rx_active = true;
50
50
+ emc_enable_rx_and_flush(emc);
51
B 1111 0. .......... 10.1 ............ @branch24
51
} else {
52
BL 1111 0. .......... 11.1 ............ @branch24
52
emc_halt_rx(emc, 0);
53
-BLX_i 1111 0. .......... 11.0 ............ @branch24
53
}
54
+{
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
55
+ # BLX_i is non-M-profile only
55
break;
56
+ BLX_i 1111 0. .......... 11.0 ............ @branch24
56
case REG_RSDR:
57
+ # M-profile only: loop and branch insns
57
if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
58
+ [
58
- emc->rx_active = true;
59
+ # All these BF insns have boff != 0b0000; we NOP them all
59
- emc_try_receive_next_packet(emc);
60
+ BF 1111 0 boff:4 ------- 1100 - ---------- 1 # BFL
60
+ emc_enable_rx_and_flush(emc);
61
+ BF 1111 0 boff:4 0 ------ 1110 - ---------- 1 # BFCSEL
61
}
62
+ BF 1111 0 boff:4 10 ----- 1110 - ---------- 1 # BF
62
break;
63
+ BF 1111 0 boff:4 11 ----- 1110 0 0000000000 1 # BFX, BFLX
63
case REG_MIIDA:
64
+ ]
65
+}
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
71
return true;
72
}
73
74
+static bool trans_BF(DisasContext *s, arg_BF *a)
75
+{
76
+ /*
77
+ * M-profile branch future insns. The architecture permits an
78
+ * implementation to implement these as NOPs (equivalent to
79
+ * discarding the LO_BRANCH_INFO cache immediately), and we
80
+ * take that IMPDEF option because for QEMU a "real" implementation
81
+ * would be complicated and wouldn't execute any faster.
82
+ */
83
+ if (!dc_isar_feature(aa32_lob, s)) {
84
+ return false;
85
+ }
86
+ if (a->boff == 0) {
87
+ /* SEE "Related encodings" (loop insns) */
88
+ return false;
89
+ }
90
+ /* Handle as NOP */
91
+ return true;
92
+}
93
+
94
static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
95
{
96
TCGv_i32 addr, tmp;
97
--
64
--
98
2.20.1
65
2.25.1
99
66
100
67
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
While APEI is a generic ACPI feature (usable by X86 and ARM64), only
3
When a virtio-iommu is instantiated, describe it using the ACPI VIOT
4
the 'virt' machine uses it, by enabling the RAS Virtualization. See
4
table.
5
commit 2afa8c8519: "hw/arm/virt: Introduce a RAS machine option").
6
5
7
Restrict the APEI tables generation code to the single user: the virt
6
Acked-by: Igor Mammedov <imammedo@redhat.com>
8
machine. If another machine wants to use it, it simply has to 'select
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
ACPI_APEI' in its Kconfig.
8
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
9
Message-id: 20211210170415.583179-2-jean-philippe@linaro.org
11
Fixes: aa16508f1d ("ACPI: Build related register address fields via hardware error fw_cfg blob")
12
Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
Reviewed-by: Dongjiu Geng <gengdongjiu@huawei.com>
14
Acked-by: Laszlo Ersek <lersek@redhat.com>
15
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Message-id: 20201008161414.2672569-1-philmd@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
11
---
20
default-configs/devices/arm-softmmu.mak | 1 -
12
hw/arm/virt-acpi-build.c | 7 +++++++
21
hw/arm/Kconfig | 1 +
13
hw/arm/Kconfig | 1 +
22
2 files changed, 1 insertion(+), 1 deletion(-)
14
2 files changed, 8 insertions(+)
23
15
24
diff --git a/default-configs/devices/arm-softmmu.mak b/default-configs/devices/arm-softmmu.mak
16
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/default-configs/devices/arm-softmmu.mak
18
--- a/hw/arm/virt-acpi-build.c
27
+++ b/default-configs/devices/arm-softmmu.mak
19
+++ b/hw/arm/virt-acpi-build.c
28
@@ -XXX,XX +XXX,XX @@ CONFIG_FSL_IMX7=y
20
@@ -XXX,XX +XXX,XX @@
29
CONFIG_FSL_IMX6UL=y
21
#include "kvm_arm.h"
30
CONFIG_SEMIHOSTING=y
22
#include "migration/vmstate.h"
31
CONFIG_ALLWINNER_H3=y
23
#include "hw/acpi/ghes.h"
32
-CONFIG_ACPI_APEI=y
24
+#include "hw/acpi/viot.h"
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);
36
+ }
37
+
38
/* XSDT is pointed to by RSDP */
39
xsdt = tables_blob->len;
40
build_xsdt(tables_blob, tables->linker, table_offsets, vms->oem_id,
33
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
41
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
34
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/Kconfig
43
--- a/hw/arm/Kconfig
36
+++ b/hw/arm/Kconfig
44
+++ b/hw/arm/Kconfig
37
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
45
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
38
select ACPI_MEMORY_HOTPLUG
46
select DIMM
39
select ACPI_HW_REDUCED
47
select ACPI_HW_REDUCED
40
select ACPI_NVDIMM
48
select ACPI_APEI
41
+ select ACPI_APEI
49
+ select ACPI_VIOT
42
50
43
config CHEETAH
51
config CHEETAH
44
bool
52
bool
45
--
53
--
46
2.20.1
54
2.25.1
47
55
48
56
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Use the BCM2835_SYSTIMER_COUNT definition instead of the
4
magic '4' value.
5
6
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20201010203709.3116542-2-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/timer/bcm2835_systmr.h | 4 +++-
13
hw/timer/bcm2835_systmr.c | 3 ++-
14
2 files changed, 5 insertions(+), 2 deletions(-)
15
16
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/timer/bcm2835_systmr.h
19
+++ b/include/hw/timer/bcm2835_systmr.h
20
@@ -XXX,XX +XXX,XX @@
21
#define TYPE_BCM2835_SYSTIMER "bcm2835-sys-timer"
22
OBJECT_DECLARE_SIMPLE_TYPE(BCM2835SystemTimerState, BCM2835_SYSTIMER)
23
24
+#define BCM2835_SYSTIMER_COUNT 4
25
+
26
struct BCM2835SystemTimerState {
27
/*< private >*/
28
SysBusDevice parent_obj;
29
@@ -XXX,XX +XXX,XX @@ struct BCM2835SystemTimerState {
30
31
struct {
32
uint32_t status;
33
- uint32_t compare[4];
34
+ uint32_t compare[BCM2835_SYSTIMER_COUNT];
35
} reg;
36
};
37
38
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/timer/bcm2835_systmr.c
41
+++ b/hw/timer/bcm2835_systmr.c
42
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription bcm2835_systmr_vmstate = {
43
.minimum_version_id = 1,
44
.fields = (VMStateField[]) {
45
VMSTATE_UINT32(reg.status, BCM2835SystemTimerState),
46
- VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState, 4),
47
+ VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState,
48
+ BCM2835_SYSTIMER_COUNT),
49
VMSTATE_END_OF_LIST()
50
}
51
};
52
--
53
2.20.1
54
55
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
The IRQ values are defined few lines earlier, use them instead of
3
virtio-iommu is now supported with ACPI VIOT as well as device tree.
4
the magic numbers.
4
Remove the restriction that prevents from instantiating a virtio-iommu
5
device under ACPI.
5
6
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Acked-by: Igor Mammedov <imammedo@redhat.com>
7
Message-id: 20201017180731.1165871-3-f4bug@amsat.org
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Message-id: 20211210170415.583179-3-jean-philippe@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
hw/intc/bcm2836_control.c | 8 ++++----
13
hw/arm/virt.c | 10 ++--------
12
1 file changed, 4 insertions(+), 4 deletions(-)
14
hw/virtio/virtio-iommu-pci.c | 12 ++----------
15
2 files changed, 4 insertions(+), 18 deletions(-)
13
16
14
diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/bcm2836_control.c
19
--- a/hw/arm/virt.c
17
+++ b/hw/intc/bcm2836_control.c
20
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@ static void bcm2836_control_set_local_irq(void *opaque, int core, int local_irq,
21
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
19
22
MachineClass *mc = MACHINE_GET_CLASS(machine);
20
static void bcm2836_control_set_local_irq0(void *opaque, int core, int level)
23
21
{
24
if (device_is_dynamic_sysbus(mc, dev) ||
22
- bcm2836_control_set_local_irq(opaque, core, 0, level);
25
- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
23
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPSIRQ, level);
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;
24
}
38
}
25
39
26
static void bcm2836_control_set_local_irq1(void *opaque, int core, int level)
40
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
27
{
41
index XXXXXXX..XXXXXXX 100644
28
- bcm2836_control_set_local_irq(opaque, core, 1, level);
42
--- a/hw/virtio/virtio-iommu-pci.c
29
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPNSIRQ, level);
43
+++ b/hw/virtio/virtio-iommu-pci.c
30
}
44
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
31
45
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
32
static void bcm2836_control_set_local_irq2(void *opaque, int core, int level)
46
33
{
47
if (!qdev_get_machine_hotplug_handler(DEVICE(vpci_dev))) {
34
- bcm2836_control_set_local_irq(opaque, core, 2, level);
48
- MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
35
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTHPIRQ, level);
49
-
36
}
50
- error_setg(errp,
37
51
- "%s machine fails to create iommu-map device tree bindings",
38
static void bcm2836_control_set_local_irq3(void *opaque, int core, int level)
52
- mc->name);
39
{
53
- error_append_hint(errp,
40
- bcm2836_control_set_local_irq(opaque, core, 3, level);
54
- "Check your machine implements a hotplug handler "
41
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTVIRQ, level);
55
- "for the virtio-iommu-pci device\n");
42
}
56
- error_append_hint(errp, "Check the guest is booted without FW or with "
43
57
- "-no-acpi\n");
44
static void bcm2836_control_set_gpu_irq(void *opaque, int irq, int level)
58
+ error_setg(errp, "Check your machine implements a hotplug handler "
59
+ "for the virtio-iommu-pci device");
60
return;
61
}
62
for (int i = 0; i < s->nb_reserved_regions; i++) {
45
--
63
--
46
2.20.1
64
2.25.1
47
65
48
66
diff view generated by jsdifflib
1
From: Peng Liang <liangpeng10@huawei.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
VMStateDescription.fields should be end with VMSTATE_END_OF_LIST().
3
We do not support instantiating multiple IOMMUs. Before adding a
4
However, microbit_i2c_vmstate doesn't follow it. Let's change it.
4
virtio-iommu, check that no other IOMMU is present. This will detect
5
both "iommu=smmuv3" machine parameter and another virtio-iommu instance.
5
6
6
Fixes: 9d68bf564e ("arm: Stub out NRF51 TWI magnetometer/accelerometer detection")
7
Fixes: 70e89132c9 ("hw/arm/virt: Add the virtio-iommu device tree mappings")
7
Reported-by: Euler Robot <euler.robot@huawei.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Message-id: 20201019093401.2993833-1-liangpeng10@huawei.com
11
Message-id: 20211210170415.583179-4-jean-philippe@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
hw/i2c/microbit_i2c.c | 1 +
14
hw/arm/virt.c | 5 +++++
14
1 file changed, 1 insertion(+)
15
1 file changed, 5 insertions(+)
15
16
16
diff --git a/hw/i2c/microbit_i2c.c b/hw/i2c/microbit_i2c.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/i2c/microbit_i2c.c
19
--- a/hw/arm/virt.c
19
+++ b/hw/i2c/microbit_i2c.c
20
+++ b/hw/arm/virt.c
20
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription microbit_i2c_vmstate = {
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
21
.fields = (VMStateField[]) {
22
hwaddr db_start = 0, db_end = 0;
22
VMSTATE_UINT32_ARRAY(regs, MicrobitI2CState, MICROBIT_I2C_NREGS),
23
char *resv_prop_str;
23
VMSTATE_UINT32(read_idx, MicrobitI2CState),
24
24
+ VMSTATE_END_OF_LIST()
25
+ if (vms->iommu != VIRT_IOMMU_NONE) {
25
},
26
+ error_setg(errp, "virt machine does not support multiple IOMMUs");
26
};
27
+ return;
27
28
+ }
29
+
30
switch (vms->msi_controller) {
31
case VIRT_MSI_CTRL_NONE:
32
return;
28
--
33
--
29
2.20.1
34
2.25.1
30
35
31
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
The reporting in AArch64.TagCheckFail only depends on PSTATE.EL,
3
To propagate errors to the caller of the pre_plug callback, use the
4
and not the AccType of the operation. There are two guest
4
object_poperty_set*() functions directly instead of the qdev_prop_set*()
5
visible problems that affect LDTR and STTR because of this:
5
helpers.
6
6
7
(1) Selecting TCF0 vs TCF1 to decide on reporting,
7
Suggested-by: Igor Mammedov <imammedo@redhat.com>
8
(2) Report "data abort same el" not "data abort lower el".
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Reported-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20211210170415.583179-5-jean-philippe@linaro.org
12
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
13
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
14
Message-id: 20201008162155.161886-3-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
13
---
17
target/arm/mte_helper.c | 10 +++-------
14
hw/arm/virt.c | 5 +++--
18
1 file changed, 3 insertions(+), 7 deletions(-)
15
1 file changed, 3 insertions(+), 2 deletions(-)
19
16
20
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/mte_helper.c
19
--- a/hw/arm/virt.c
23
+++ b/target/arm/mte_helper.c
20
+++ b/hw/arm/virt.c
24
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
25
reg_el = regime_el(env, arm_mmu_idx);
22
db_start, db_end,
26
sctlr = env->cp15.sctlr_el[reg_el];
23
VIRTIO_IOMMU_RESV_MEM_T_MSI);
27
24
28
- switch (arm_mmu_idx) {
25
- qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
29
- case ARMMMUIdx_E10_0:
26
- qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
30
- case ARMMMUIdx_E20_0:
27
+ object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
31
- el = 0;
28
+ object_property_set_str(OBJECT(dev), "reserved-regions[0]",
32
+ el = arm_current_el(env);
29
+ resv_prop_str, errp);
33
+ if (el == 0) {
30
g_free(resv_prop_str);
34
tcf = extract64(sctlr, 38, 2);
35
- break;
36
- default:
37
- el = reg_el;
38
+ } else {
39
tcf = extract64(sctlr, 40, 2);
40
}
31
}
41
32
}
42
--
33
--
43
2.20.1
34
2.25.1
44
35
45
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
We already have the full ARMMMUIdx as computed from the
3
Create empty data files and allow updates for the upcoming VIOT tests.
4
function parameter.
5
4
6
For the purpose of regime_has_2_ranges, we can ignore any
5
Acked-by: Igor Mammedov <imammedo@redhat.com>
7
difference between AccType_Normal and AccType_Unpriv, which
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
would be the only difference between the passed mmu_idx
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
and arm_mmu_idx_el.
8
Message-id: 20211210170415.583179-6-jean-philippe@linaro.org
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
14
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
15
Message-id: 20201008162155.161886-2-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
target/arm/mte_helper.c | 3 +--
11
tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
19
1 file changed, 1 insertion(+), 2 deletions(-)
12
tests/data/acpi/q35/DSDT.viot | 0
13
tests/data/acpi/q35/VIOT.viot | 0
14
tests/data/acpi/virt/VIOT | 0
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/target/arm/mte_helper.c b/target/arm/mte_helper.c
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/target/arm/mte_helper.c
22
--- a/tests/qtest/bios-tables-test-allowed-diff.h
24
+++ b/target/arm/mte_helper.c
23
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
25
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
24
@@ -1 +1,4 @@
26
25
/* List of comma-separated changed AML files to ignore */
27
case 2:
26
+"tests/data/acpi/virt/VIOT",
28
/* Tag check fail causes asynchronous flag set. */
27
+"tests/data/acpi/q35/DSDT.viot",
29
- mmu_idx = arm_mmu_idx_el(env, el);
28
+"tests/data/acpi/q35/VIOT.viot",
30
- if (regime_has_2_ranges(mmu_idx)) {
29
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
31
+ if (regime_has_2_ranges(arm_mmu_idx)) {
30
new file mode 100644
32
select = extract64(dirty_ptr, 55, 1);
31
index XXXXXXX..XXXXXXX
33
} else {
32
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
34
select = 0;
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
35
--
38
--
36
2.20.1
39
2.25.1
37
40
38
41
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
When TBI is enabled in a given regime, 56 bits of the address
3
Add two test cases for VIOT, one on the q35 machine and the other on
4
are significant and we need to clear out any other matching
4
virt. To test complex topologies the q35 test has two PCIe buses that
5
virtual addresses with differing tags.
5
bypass the IOMMU (and are therefore not described by VIOT), and two
6
buses that are translated by virtio-iommu.
6
7
7
The other uses of tlb_flush_page (without mmuidx) in this file
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
are only used by aarch32 mode.
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Fixes: 38d931687fa1
11
Message-id: 20211210170415.583179-7-jean-philippe@linaro.org
11
Reported-by: Jordan Frank <jordanfrank@fb.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20201016210754.818257-3-richard.henderson@linaro.org
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/helper.c | 46 ++++++++++++++++++++++++++++++++++++++-------
14
tests/qtest/bios-tables-test.c | 38 ++++++++++++++++++++++++++++++++++
19
1 file changed, 39 insertions(+), 7 deletions(-)
15
1 file changed, 38 insertions(+)
20
16
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
19
--- a/tests/qtest/bios-tables-test.c
24
+++ b/target/arm/helper.c
20
+++ b/tests/qtest/bios-tables-test.c
25
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
21
@@ -XXX,XX +XXX,XX @@ static void test_acpi_virt_tcg(void)
26
#endif
22
free_test_data(&data);
27
28
static void switch_mode(CPUARMState *env, int mode);
29
+static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
30
31
static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
32
{
33
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbmask(CPUARMState *env)
34
}
35
}
23
}
36
24
37
+/* Return 56 if TBI is enabled, 64 otherwise. */
25
+static void test_acpi_q35_viot(void)
38
+static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
39
+ uint64_t addr)
40
+{
26
+{
41
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
27
+ test_data data = {
42
+ int tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
28
+ .machine = MACHINE_Q35,
43
+ int select = extract64(addr, 55, 1);
29
+ .variant = ".viot",
30
+ };
44
+
31
+
45
+ return (tbi >> select) & 1 ? 56 : 64;
32
+ /*
33
+ * To keep things interesting, two buses bypass the IOMMU.
34
+ * VIOT should only describes the other two buses.
35
+ */
36
+ test_acpi_one("-machine default_bus_bypass_iommu=on "
37
+ "-device virtio-iommu-pci "
38
+ "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 "
39
+ "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on "
40
+ "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0",
41
+ &data);
42
+ free_test_data(&data);
46
+}
43
+}
47
+
44
+
48
+static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
45
+static void test_acpi_virt_viot(void)
49
+{
46
+{
50
+ ARMMMUIdx mmu_idx;
47
+ test_data data = {
48
+ .machine = "virt",
49
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
50
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
51
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
52
+ .ram_start = 0x40000000ULL,
53
+ .scan_len = 128ULL * 1024 * 1024,
54
+ };
51
+
55
+
52
+ /* Only the regime of the mmu_idx below is significant. */
56
+ test_acpi_one("-cpu cortex-a57 "
53
+ if (arm_is_secure_below_el3(env)) {
57
+ "-device virtio-iommu-pci", &data);
54
+ mmu_idx = ARMMMUIdx_SE10_0;
58
+ free_test_data(&data);
55
+ } else if ((env->cp15.hcr_el2 & (HCR_E2H | HCR_TGE))
56
+ == (HCR_E2H | HCR_TGE)) {
57
+ mmu_idx = ARMMMUIdx_E20_0;
58
+ } else {
59
+ mmu_idx = ARMMMUIdx_E10_0;
60
+ }
61
+ return tlbbits_for_regime(env, mmu_idx, addr);
62
+}
59
+}
63
+
60
+
64
static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
61
static void test_oem_fields(test_data *data)
65
uint64_t value)
66
{
62
{
67
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
63
int i;
68
CPUState *cs = env_cpu(env);
64
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
69
int mask = vae1_tlbmask(env);
65
qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic);
70
uint64_t pageaddr = sextract64(value << 12, 0, 56);
66
qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
71
+ int bits = vae1_tlbbits(env, pageaddr);
67
}
72
68
+ qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
73
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask);
69
} else if (strcmp(arch, "aarch64") == 0) {
74
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
70
if (has_tcg) {
75
}
71
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
76
72
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
77
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
73
qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
78
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
74
qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
79
CPUState *cs = env_cpu(env);
75
qtest_add_func("acpi/virt/oem-fields", test_acpi_oem_fields_virt);
80
int mask = vae1_tlbmask(env);
76
+ qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
81
uint64_t pageaddr = sextract64(value << 12, 0, 56);
77
}
82
+ int bits = vae1_tlbbits(env, pageaddr);
83
84
if (tlb_force_broadcast(env)) {
85
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask);
86
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
87
} else {
88
- tlb_flush_page_by_mmuidx(cs, pageaddr, mask);
89
+ tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits);
90
}
78
}
91
}
79
ret = g_test_run();
92
93
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
94
{
95
CPUState *cs = env_cpu(env);
96
uint64_t pageaddr = sextract64(value << 12, 0, 56);
97
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
98
99
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
100
- ARMMMUIdxBit_E2);
101
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
102
+ ARMMMUIdxBit_E2, bits);
103
}
104
105
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
106
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
107
{
108
CPUState *cs = env_cpu(env);
109
uint64_t pageaddr = sextract64(value << 12, 0, 56);
110
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_SE3, pageaddr);
111
112
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
113
- ARMMMUIdxBit_SE3);
114
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
115
+ ARMMMUIdxBit_SE3, bits);
116
}
117
118
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
119
--
80
--
120
2.20.1
81
2.25.1
121
82
122
83
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Add trace events for GPU and CPU IRQs.
3
Add expected blobs of the VIOT and DSDT table for the VIOT test on the
4
4
q35 machine.
5
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
5
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Since the test instantiates a virtio device and two PCIe expander
7
Message-id: 20201017180731.1165871-2-f4bug@amsat.org
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
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
459
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
460
---
10
hw/intc/bcm2835_ic.c | 4 +++-
461
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
11
hw/intc/trace-events | 4 ++++
462
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
12
2 files changed, 7 insertions(+), 1 deletion(-)
463
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
13
464
3 files changed, 2 deletions(-)
14
diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c
465
466
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
15
index XXXXXXX..XXXXXXX 100644
467
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/bcm2835_ic.c
468
--- a/tests/qtest/bios-tables-test-allowed-diff.h
17
+++ b/hw/intc/bcm2835_ic.c
469
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
18
@@ -XXX,XX +XXX,XX @@
470
@@ -XXX,XX +XXX,XX @@
19
#include "migration/vmstate.h"
471
/* List of comma-separated changed AML files to ignore */
20
#include "qemu/log.h"
472
"tests/data/acpi/virt/VIOT",
21
#include "qemu/module.h"
473
-"tests/data/acpi/q35/DSDT.viot",
22
+#include "trace.h"
474
-"tests/data/acpi/q35/VIOT.viot",
23
475
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
24
#define GPU_IRQS 64
25
#define ARM_IRQS 8
26
@@ -XXX,XX +XXX,XX @@ static void bcm2835_ic_update(BCM2835ICState *s)
27
set = (s->gpu_irq_level & s->gpu_irq_enable)
28
|| (s->arm_irq_level & s->arm_irq_enable);
29
qemu_set_irq(s->irq, set);
30
-
31
}
32
33
static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
34
@@ -XXX,XX +XXX,XX @@ static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
35
BCM2835ICState *s = opaque;
36
37
assert(irq >= 0 && irq < 64);
38
+ trace_bcm2835_ic_set_gpu_irq(irq, level);
39
s->gpu_irq_level = deposit64(s->gpu_irq_level, irq, 1, level != 0);
40
bcm2835_ic_update(s);
41
}
42
@@ -XXX,XX +XXX,XX @@ static void bcm2835_ic_set_arm_irq(void *opaque, int irq, int level)
43
BCM2835ICState *s = opaque;
44
45
assert(irq >= 0 && irq < 8);
46
+ trace_bcm2835_ic_set_cpu_irq(irq, level);
47
s->arm_irq_level = deposit32(s->arm_irq_level, irq, 1, level != 0);
48
bcm2835_ic_update(s);
49
}
50
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
51
index XXXXXXX..XXXXXXX 100644
476
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/intc/trace-events
477
GIT binary patch
53
+++ b/hw/intc/trace-events
478
literal 9398
54
@@ -XXX,XX +XXX,XX @@ nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg wri
479
zcmeHNO>7&-8J*>iv|O&FB}G~Oi$yp||57BBoWHhc5OS9yDTx$CQgH$r;8Idr*-4Q_
55
heathrow_write(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
480
z5(9Az1F`}niVsB-)<KW7p`g9Br(A2Gm-gmc1N78GFS!;)e2V(MnH_0{q<{#yMgn&C
56
heathrow_read(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
481
zn|*J-d9yqFhO_H6z19~`FlPL*u<DkZ*}|)JH;X@mF-FI<cPg<fti9tEN*yB^i5czN
57
heathrow_set_irq(int num, int level) "set_irq: num=0x%02x level=%d"
482
zNq&q?!OZ;BE3B7{KWzJ-`Tn~f`9?Qj8~2^N8{Oc8J%57{==w%rS#;nOCp*nTr@iZ1
58
+
483
zb+?i;JLQUJ=O0?8*>S~D)a>NF1~WVB6^~_B#yhJ`H+JU@=6aXs`?Yv)J2h=N?drcS
59
+# bcm2835_ic.c
484
zeLZ*n<<Bm^n}6`jfBx#u8&(W}1?)}iF9o#mZ~E2+zwdn7yK3AbIzKnxpZ>JRPm3~#
60
+bcm2835_ic_set_gpu_irq(int irq, int level) "GPU irq #%d level %d"
485
z&ICS{+_OayRW-l=Mtk=~uaS3o8z<_udd|(wqg`&JnVPfCe>BUOO`Su3e>pff_^UW%
61
+bcm2835_ic_set_cpu_irq(int irq, int level) "CPU irq #%d level %d"
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
62
--
558
--
63
2.20.1
559
2.25.1
64
560
65
561
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
The variable holding the CTRL_STATUS register is misnamed
3
The VIOT blob contains the following:
4
'status'. Rename it 'ctrl_status' to make it more obvious
5
this register is also used to control the peripheral.
6
4
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
5
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
[004h 0004 4] Table Length : 00000058
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
[008h 0008 1] Revision : 00
10
Message-id: 20201010203709.3116542-3-f4bug@amsat.org
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
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
44
---
13
include/hw/timer/bcm2835_systmr.h | 2 +-
45
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
14
hw/timer/bcm2835_systmr.c | 8 ++++----
46
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
15
2 files changed, 5 insertions(+), 5 deletions(-)
47
2 files changed, 1 deletion(-)
16
48
17
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
49
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
18
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/timer/bcm2835_systmr.h
51
--- a/tests/qtest/bios-tables-test-allowed-diff.h
20
+++ b/include/hw/timer/bcm2835_systmr.h
52
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
21
@@ -XXX,XX +XXX,XX @@ struct BCM2835SystemTimerState {
53
@@ -1,2 +1 @@
22
qemu_irq irq;
54
/* List of comma-separated changed AML files to ignore */
23
55
-"tests/data/acpi/virt/VIOT",
24
struct {
56
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
25
- uint32_t status;
26
+ uint32_t ctrl_status;
27
uint32_t compare[BCM2835_SYSTIMER_COUNT];
28
} reg;
29
};
30
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
31
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/timer/bcm2835_systmr.c
58
GIT binary patch
33
+++ b/hw/timer/bcm2835_systmr.c
59
literal 88
34
@@ -XXX,XX +XXX,XX @@ REG32(COMPARE3, 0x18)
60
zcmWIZ^bd((0D?3pe`k+i1*eDrX9XZ&1PX!JAexE60Hgv8m>C3sGzXN&z`)2L0cSHX
35
61
I{D-Rq0Q5fy0RR91
36
static void bcm2835_systmr_update_irq(BCM2835SystemTimerState *s)
62
37
{
63
literal 0
38
- bool enable = !!s->reg.status;
64
HcmV?d00001
39
+ bool enable = !!s->reg.ctrl_status;
65
40
41
trace_bcm2835_systmr_irq(enable);
42
qemu_set_irq(s->irq, enable);
43
@@ -XXX,XX +XXX,XX @@ static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
44
45
switch (offset) {
46
case A_CTRL_STATUS:
47
- r = s->reg.status;
48
+ r = s->reg.ctrl_status;
49
break;
50
case A_COMPARE0 ... A_COMPARE3:
51
r = s->reg.compare[(offset - A_COMPARE0) >> 2];
52
@@ -XXX,XX +XXX,XX @@ static void bcm2835_systmr_write(void *opaque, hwaddr offset,
53
trace_bcm2835_systmr_write(offset, value);
54
switch (offset) {
55
case A_CTRL_STATUS:
56
- s->reg.status &= ~value; /* Ack */
57
+ s->reg.ctrl_status &= ~value; /* Ack */
58
bcm2835_systmr_update_irq(s);
59
break;
60
case A_COMPARE0 ... A_COMPARE3:
61
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription bcm2835_systmr_vmstate = {
62
.version_id = 1,
63
.minimum_version_id = 1,
64
.fields = (VMStateField[]) {
65
- VMSTATE_UINT32(reg.status, BCM2835SystemTimerState),
66
+ VMSTATE_UINT32(reg.ctrl_status, BCM2835SystemTimerState),
67
VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState,
68
BCM2835_SYSTIMER_COUNT),
69
VMSTATE_END_OF_LIST()
70
--
66
--
71
2.20.1
67
2.25.1
72
68
73
69
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
This peripheral has 1 free-running timer and 4 compare registers.
4
5
Only the free-running timer is implemented. Add support the
6
COMPARE registers (each register is wired to an IRQ).
7
8
Reference: "BCM2835 ARM Peripherals" datasheet [*]
9
chapter 12 "System Timer":
10
11
The System Timer peripheral provides four 32-bit timer channels
12
and a single 64-bit free running counter. Each channel has an
13
output compare register, which is compared against the 32 least
14
significant bits of the free running counter values. When the
15
two values match, the system timer peripheral generates a signal
16
to indicate a match for the appropriate channel. The match signal
17
is then fed into the interrupt controller.
18
19
This peripheral is used since Linux 3.7, commit ee4af5696720
20
("ARM: bcm2835: add system timer").
21
22
[*] https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
23
24
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Reviewed-by: Luc Michel <luc@lmichel.fr>
26
Message-id: 20201010203709.3116542-4-f4bug@amsat.org
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
---
29
include/hw/timer/bcm2835_systmr.h | 11 +++++--
30
hw/timer/bcm2835_systmr.c | 48 ++++++++++++++++++++-----------
31
hw/timer/trace-events | 6 ++--
32
3 files changed, 44 insertions(+), 21 deletions(-)
33
34
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/timer/bcm2835_systmr.h
37
+++ b/include/hw/timer/bcm2835_systmr.h
38
@@ -XXX,XX +XXX,XX @@
39
40
#include "hw/sysbus.h"
41
#include "hw/irq.h"
42
+#include "qemu/timer.h"
43
#include "qom/object.h"
44
45
#define TYPE_BCM2835_SYSTIMER "bcm2835-sys-timer"
46
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(BCM2835SystemTimerState, BCM2835_SYSTIMER)
47
48
#define BCM2835_SYSTIMER_COUNT 4
49
50
+typedef struct {
51
+ unsigned id;
52
+ QEMUTimer timer;
53
+ qemu_irq irq;
54
+ BCM2835SystemTimerState *state;
55
+} BCM2835SystemTimerCompare;
56
+
57
struct BCM2835SystemTimerState {
58
/*< private >*/
59
SysBusDevice parent_obj;
60
61
/*< public >*/
62
MemoryRegion iomem;
63
- qemu_irq irq;
64
-
65
struct {
66
uint32_t ctrl_status;
67
uint32_t compare[BCM2835_SYSTIMER_COUNT];
68
} reg;
69
+ BCM2835SystemTimerCompare tmr[BCM2835_SYSTIMER_COUNT];
70
};
71
72
#endif
73
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/timer/bcm2835_systmr.c
76
+++ b/hw/timer/bcm2835_systmr.c
77
@@ -XXX,XX +XXX,XX @@ REG32(COMPARE1, 0x10)
78
REG32(COMPARE2, 0x14)
79
REG32(COMPARE3, 0x18)
80
81
-static void bcm2835_systmr_update_irq(BCM2835SystemTimerState *s)
82
+static void bcm2835_systmr_timer_expire(void *opaque)
83
{
84
- bool enable = !!s->reg.ctrl_status;
85
+ BCM2835SystemTimerCompare *tmr = opaque;
86
87
- trace_bcm2835_systmr_irq(enable);
88
- qemu_set_irq(s->irq, enable);
89
-}
90
-
91
-static void bcm2835_systmr_update_compare(BCM2835SystemTimerState *s,
92
- unsigned timer_index)
93
-{
94
- /* TODO fow now, since neither Linux nor U-boot use these timers. */
95
- qemu_log_mask(LOG_UNIMP, "COMPARE register %u not implemented\n",
96
- timer_index);
97
+ trace_bcm2835_systmr_timer_expired(tmr->id);
98
+ tmr->state->reg.ctrl_status |= 1 << tmr->id;
99
+ qemu_set_irq(tmr->irq, 1);
100
}
101
102
static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
103
@@ -XXX,XX +XXX,XX @@ static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
104
}
105
106
static void bcm2835_systmr_write(void *opaque, hwaddr offset,
107
- uint64_t value, unsigned size)
108
+ uint64_t value64, unsigned size)
109
{
110
BCM2835SystemTimerState *s = BCM2835_SYSTIMER(opaque);
111
+ int index;
112
+ uint32_t value = value64;
113
+ uint32_t triggers_delay_us;
114
+ uint64_t now;
115
116
trace_bcm2835_systmr_write(offset, value);
117
switch (offset) {
118
case A_CTRL_STATUS:
119
s->reg.ctrl_status &= ~value; /* Ack */
120
- bcm2835_systmr_update_irq(s);
121
+ for (index = 0; index < ARRAY_SIZE(s->tmr); index++) {
122
+ if (extract32(value, index, 1)) {
123
+ trace_bcm2835_systmr_irq_ack(index);
124
+ qemu_set_irq(s->tmr[index].irq, 0);
125
+ }
126
+ }
127
break;
128
case A_COMPARE0 ... A_COMPARE3:
129
- s->reg.compare[(offset - A_COMPARE0) >> 2] = value;
130
- bcm2835_systmr_update_compare(s, (offset - A_COMPARE0) >> 2);
131
+ index = (offset - A_COMPARE0) >> 2;
132
+ s->reg.compare[index] = value;
133
+ now = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
134
+ /* Compare lower 32-bits of the free-running counter. */
135
+ triggers_delay_us = value - now;
136
+ trace_bcm2835_systmr_run(index, triggers_delay_us);
137
+ timer_mod(&s->tmr[index].timer, now + triggers_delay_us);
138
break;
139
case A_COUNTER_LOW:
140
case A_COUNTER_HIGH:
141
@@ -XXX,XX +XXX,XX @@ static void bcm2835_systmr_realize(DeviceState *dev, Error **errp)
142
memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_systmr_ops,
143
s, "bcm2835-sys-timer", 0x20);
144
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
145
- sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
146
+
147
+ for (size_t i = 0; i < ARRAY_SIZE(s->tmr); i++) {
148
+ s->tmr[i].id = i;
149
+ s->tmr[i].state = s;
150
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->tmr[i].irq);
151
+ timer_init_us(&s->tmr[i].timer, QEMU_CLOCK_VIRTUAL,
152
+ bcm2835_systmr_timer_expire, &s->tmr[i]);
153
+ }
154
}
155
156
static const VMStateDescription bcm2835_systmr_vmstate = {
157
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
158
index XXXXXXX..XXXXXXX 100644
159
--- a/hw/timer/trace-events
160
+++ b/hw/timer/trace-events
161
@@ -XXX,XX +XXX,XX @@ nrf51_timer_write(uint8_t timer_id, uint64_t addr, uint32_t value, unsigned size
162
nrf51_timer_set_count(uint8_t timer_id, uint8_t counter_id, uint32_t value) "timer %u counter %u count 0x%" PRIx32
163
164
# bcm2835_systmr.c
165
-bcm2835_systmr_irq(bool enable) "timer irq state %u"
166
+bcm2835_systmr_timer_expired(unsigned id) "timer #%u expired"
167
+bcm2835_systmr_irq_ack(unsigned id) "timer #%u acked"
168
bcm2835_systmr_read(uint64_t offset, uint64_t data) "timer read: offset 0x%" PRIx64 " data 0x%" PRIx64
169
-bcm2835_systmr_write(uint64_t offset, uint64_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx64
170
+bcm2835_systmr_write(uint64_t offset, uint32_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx32
171
+bcm2835_systmr_run(unsigned id, uint64_t delay_us) "timer #%u expiring in %"PRIu64" us"
172
173
# avr_timer16.c
174
avr_timer16_read(uint8_t addr, uint8_t value) "timer16 read addr:%u value:%u"
175
--
176
2.20.1
177
178
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
The SYS_timer is not directly wired to the ARM core, but to the
4
SoC (peripheral) interrupt controller.
5
6
Fixes: 0e5bbd74064 ("hw/arm/bcm2835_peripherals: Use the SYS_timer")
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20201010203709.3116542-5-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/bcm2835_peripherals.c | 13 +++++++++++--
14
1 file changed, 11 insertions(+), 2 deletions(-)
15
16
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/bcm2835_peripherals.c
19
+++ b/hw/arm/bcm2835_peripherals.c
20
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
21
memory_region_add_subregion(&s->peri_mr, ST_OFFSET,
22
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systmr), 0));
23
sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 0,
24
- qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
25
- INTERRUPT_ARM_TIMER));
26
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
27
+ INTERRUPT_TIMER0));
28
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 1,
29
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
30
+ INTERRUPT_TIMER1));
31
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 2,
32
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
33
+ INTERRUPT_TIMER2));
34
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 3,
35
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
36
+ INTERRUPT_TIMER3));
37
38
/* UART0 */
39
qdev_prop_set_chr(DEVICE(&s->uart0), "chardev", serial_hd(0));
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
2
1
3
Current documentation is not too clear on the GETPC usage.
4
In particular, when used outside the top level helper function
5
it causes unexpected behavior.
6
7
Signed-off-by: Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
8
Message-id: 20201015095147.1691-1-e.emanuelegiuseppe@gmail.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
docs/devel/loads-stores.rst | 8 +++++++-
13
1 file changed, 7 insertions(+), 1 deletion(-)
14
15
diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst
16
index XXXXXXX..XXXXXXX 100644
17
--- a/docs/devel/loads-stores.rst
18
+++ b/docs/devel/loads-stores.rst
19
@@ -XXX,XX +XXX,XX @@ guest CPU state in case of a guest CPU exception. This is passed
20
to ``cpu_restore_state()``. Therefore the value should either be 0,
21
to indicate that the guest CPU state is already synchronized, or
22
the result of ``GETPC()`` from the top level ``HELPER(foo)``
23
-function, which is a return address into the generated code.
24
+function, which is a return address into the generated code [#gpc]_.
25
+
26
+.. [#gpc] Note that ``GETPC()`` should be used with great care: calling
27
+ it in other functions that are *not* the top level
28
+ ``HELPER(foo)`` will cause unexpected behavior. Instead, the
29
+ value of ``GETPC()`` should be read from the helper and passed
30
+ if needed to the functions that the helper calls.
31
32
Function names follow the pattern:
33
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
v8.1M brings four new insns to M-profile:
2
* CSEL : Rd = cond ? Rn : Rm
3
* CSINC : Rd = cond ? Rn : Rm+1
4
* CSINV : Rd = cond ? Rn : ~Rm
5
* CSNEG : Rd = cond ? Rn : -Rm
6
1
7
Implement these.
8
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20201019151301.2046-4-peter.maydell@linaro.org
12
---
13
target/arm/t32.decode | 3 +++
14
target/arm/translate.c | 60 ++++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 63 insertions(+)
16
17
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/t32.decode
20
+++ b/target/arm/t32.decode
21
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
22
}
23
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
24
25
+# v8.1M CSEL and friends
26
+CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
27
+
28
# Data-processing (register-shifted register)
29
30
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
31
diff --git a/target/arm/translate.c b/target/arm/translate.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate.c
34
+++ b/target/arm/translate.c
35
@@ -XXX,XX +XXX,XX @@ static bool trans_IT(DisasContext *s, arg_IT *a)
36
return true;
37
}
38
39
+/* v8.1M CSEL/CSINC/CSNEG/CSINV */
40
+static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
41
+{
42
+ TCGv_i32 rn, rm, zero;
43
+ DisasCompare c;
44
+
45
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
46
+ return false;
47
+ }
48
+
49
+ if (a->rm == 13) {
50
+ /* SEE "Related encodings" (MVE shifts) */
51
+ return false;
52
+ }
53
+
54
+ if (a->rd == 13 || a->rd == 15 || a->rn == 13 || a->fcond >= 14) {
55
+ /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
56
+ return false;
57
+ }
58
+
59
+ /* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
60
+ if (a->rn == 15) {
61
+ rn = tcg_const_i32(0);
62
+ } else {
63
+ rn = load_reg(s, a->rn);
64
+ }
65
+ if (a->rm == 15) {
66
+ rm = tcg_const_i32(0);
67
+ } else {
68
+ rm = load_reg(s, a->rm);
69
+ }
70
+
71
+ switch (a->op) {
72
+ case 0: /* CSEL */
73
+ break;
74
+ case 1: /* CSINC */
75
+ tcg_gen_addi_i32(rm, rm, 1);
76
+ break;
77
+ case 2: /* CSINV */
78
+ tcg_gen_not_i32(rm, rm);
79
+ break;
80
+ case 3: /* CSNEG */
81
+ tcg_gen_neg_i32(rm, rm);
82
+ break;
83
+ default:
84
+ g_assert_not_reached();
85
+ }
86
+
87
+ arm_test_cc(&c, a->fcond);
88
+ zero = tcg_const_i32(0);
89
+ tcg_gen_movcond_i32(c.cond, rn, c.value, zero, rn, rm);
90
+ arm_free_cc(&c);
91
+ tcg_temp_free_i32(zero);
92
+
93
+ store_reg(s, a->rd, rn);
94
+ tcg_temp_free_i32(rm);
95
+
96
+ return true;
97
+}
98
+
99
/*
100
* Legacy decoder.
101
*/
102
--
103
2.20.1
104
105
diff view generated by jsdifflib
Deleted patch
1
The t32 decode has a group which represents a set of insns
2
which overlap with B_cond_thumb because they have [25:23]=111
3
(which is an invalid condition code field for the branch insn).
4
This group is currently defined using the {} overlap-OK syntax,
5
but it is almost entirely non-overlapping patterns. Switch
6
it over to use a non-overlapping group.
7
1
8
For this to be valid syntactically, CPS must move into the same
9
overlapping-group as the hint insns (CPS vs hints was the
10
only actual use of the overlap facility for the group).
11
12
The non-overlapping subgroup for CLREX/DSB/DMB/ISB/SB is no longer
13
necessary and so we can remove it (promoting those insns to
14
be members of the parent group).
15
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20201019151301.2046-5-peter.maydell@linaro.org
19
---
20
target/arm/t32.decode | 26 ++++++++++++--------------
21
1 file changed, 12 insertions(+), 14 deletions(-)
22
23
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/t32.decode
26
+++ b/target/arm/t32.decode
27
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
28
{
29
# Group insn[25:23] = 111, which is cond=111x for the branch below,
30
# or unconditional, which would be illegal for the branch.
31
- {
32
- # Hints
33
+ [
34
+ # Hints, and CPS
35
{
36
YIELD 1111 0011 1010 1111 1000 0000 0000 0001
37
WFE 1111 0011 1010 1111 1000 0000 0000 0010
38
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
39
# The canonical nop ends in 0000 0000, but the whole rest
40
# of the space is "reserved hint, behaves as nop".
41
NOP 1111 0011 1010 1111 1000 0000 ---- ----
42
+
43
+ # If imod == '00' && M == '0' then SEE "Hint instructions", above.
44
+ CPS 1111 0011 1010 1111 1000 0 imod:2 M:1 A:1 I:1 F:1 mode:5 \
45
+ &cps
46
}
47
48
- # If imod == '00' && M == '0' then SEE "Hint instructions", above.
49
- CPS 1111 0011 1010 1111 1000 0 imod:2 M:1 A:1 I:1 F:1 mode:5 \
50
- &cps
51
-
52
# Miscellaneous control
53
- [
54
- CLREX 1111 0011 1011 1111 1000 1111 0010 1111
55
- DSB 1111 0011 1011 1111 1000 1111 0100 ----
56
- DMB 1111 0011 1011 1111 1000 1111 0101 ----
57
- ISB 1111 0011 1011 1111 1000 1111 0110 ----
58
- SB 1111 0011 1011 1111 1000 1111 0111 0000
59
- ]
60
+ CLREX 1111 0011 1011 1111 1000 1111 0010 1111
61
+ DSB 1111 0011 1011 1111 1000 1111 0100 ----
62
+ DMB 1111 0011 1011 1111 1000 1111 0101 ----
63
+ ISB 1111 0011 1011 1111 1000 1111 0110 ----
64
+ SB 1111 0011 1011 1111 1000 1111 0111 0000
65
66
# Note that the v7m insn overlaps both the normal and banked insn.
67
{
68
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
69
HVC 1111 0111 1110 .... 1000 .... .... .... \
70
&i imm=%imm16_16_0
71
UDF 1111 0111 1111 ---- 1010 ---- ---- ----
72
- }
73
+ ]
74
B_cond_thumb 1111 0. cond:4 ...... 10.0 ............ &ci imm=%imm21
75
}
76
77
--
78
2.20.1
79
80
diff view generated by jsdifflib
Deleted patch
1
In arm_cpu_realizefn(), if the CPU has VFP or Neon disabled then we
2
squash the ID register fields so that we don't advertise it to the
3
guest. This code was written for A-profile and needs some tweaks to
4
work correctly on M-profile:
5
1
6
* A-profile only fields should not be zeroed on M-profile:
7
- MVFR0.FPSHVEC,FPTRAP
8
- MVFR1.SIMDLS,SIMDINT,SIMDSP,SIMDHP
9
- MVFR2.SIMDMISC
10
* M-profile only fields should be zeroed on M-profile:
11
- MVFR1.FP16
12
13
In particular, because MVFR1.SIMDHP on A-profile is the same field as
14
MVFR1.FP16 on M-profile this code was incorrectly disabling FP16
15
support on an M-profile CPU (where has_neon is always false). This
16
isn't a visible bug yet because we don't have any M-profile CPUs with
17
FP16 support, but the change is necessary before we introduce any.
18
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Message-id: 20201019151301.2046-9-peter.maydell@linaro.org
22
---
23
target/arm/cpu.c | 29 ++++++++++++++++++-----------
24
1 file changed, 18 insertions(+), 11 deletions(-)
25
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.c
29
+++ b/target/arm/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
31
u = cpu->isar.mvfr0;
32
u = FIELD_DP32(u, MVFR0, FPSP, 0);
33
u = FIELD_DP32(u, MVFR0, FPDP, 0);
34
- u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
35
u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0);
36
u = FIELD_DP32(u, MVFR0, FPSQRT, 0);
37
- u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
38
u = FIELD_DP32(u, MVFR0, FPROUND, 0);
39
+ if (!arm_feature(env, ARM_FEATURE_M)) {
40
+ u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
41
+ u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
42
+ }
43
cpu->isar.mvfr0 = u;
44
45
u = cpu->isar.mvfr1;
46
u = FIELD_DP32(u, MVFR1, FPFTZ, 0);
47
u = FIELD_DP32(u, MVFR1, FPDNAN, 0);
48
u = FIELD_DP32(u, MVFR1, FPHP, 0);
49
+ if (arm_feature(env, ARM_FEATURE_M)) {
50
+ u = FIELD_DP32(u, MVFR1, FP16, 0);
51
+ }
52
cpu->isar.mvfr1 = u;
53
54
u = cpu->isar.mvfr2;
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
56
u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
57
cpu->isar.id_isar6 = u;
58
59
- u = cpu->isar.mvfr1;
60
- u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
61
- u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
62
- u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
63
- u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
64
- cpu->isar.mvfr1 = u;
65
+ if (!arm_feature(env, ARM_FEATURE_M)) {
66
+ u = cpu->isar.mvfr1;
67
+ u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
68
+ u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
69
+ u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
70
+ u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
71
+ cpu->isar.mvfr1 = u;
72
73
- u = cpu->isar.mvfr2;
74
- u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
75
- cpu->isar.mvfr2 = u;
76
+ u = cpu->isar.mvfr2;
77
+ u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
78
+ cpu->isar.mvfr2 = u;
79
+ }
80
}
81
82
if (!cpu->has_neon && !cpu->has_vfp) {
83
--
84
2.20.1
85
86
diff view generated by jsdifflib