1
Arm queue -- I have more stuff pending but I prefer to push
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
this first lot out and keep the pull below 50 patches.
3
Most of this is Alex's FP16 support work.
4
2
5
-- PMM
3
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2024-02-14 15:45:52 +0000)
6
7
8
The following changes since commit 6697439794f72b3501ee16bb95d16854f9981421:
9
10
Merge remote-tracking branch 'remotes/kraxel/tags/usb-20180227-pull-request' into staging (2018-02-27 17:50:46 +0000)
11
4
12
are available in the Git repository at:
5
are available in the Git repository at:
13
6
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180301
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
15
8
16
for you to fetch changes up to c22e580c2ad1cccef582e1490e732f254d4ac064:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
17
10
18
MAINTAINERS: Update my email address (2018-03-01 11:13:59 +0000)
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
target-arm queue:
14
target-arm queue:
22
* update MAINTAINERS for Alistair's new email address
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
23
* add Arm v8.2 FP16 arithmetic extension for linux-user
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
24
* implement display connector emulation for vexpress board
17
* Fix some errors in SVE/SME handling of MTE tags
25
* xilinx_spips: Enable only two slaves when reading/writing with stripe
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
26
* xilinx_spips: Use 8 dummy cycles with the QIOR/QIOR4 commands
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
27
* hw: register: Run post_write hook on reset
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
23
* Don't assert on vmload/vmsave of M-profile CPUs
24
* hw/arm/smmuv3: add support for stage 1 access fault
25
* hw/arm/stellaris: QOM cleanups
26
* Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
27
* Improve Cortex_R52 IMPDEF sysreg modelling
28
* Allow access to SPSR_hyp from hyp mode
29
* New board model mps3-an536 (Cortex-R52)
28
30
29
----------------------------------------------------------------
31
----------------------------------------------------------------
30
Alex Bennée (31):
32
Luc Michel (1):
31
include/exec/helper-head.h: support f16 in helper calls
33
hw/arm/smmuv3: add support for stage 1 access fault
32
target/arm/cpu64: introduce ARM_V8_FP16 feature bit
33
target/arm/cpu.h: update comment for half-precision values
34
target/arm/cpu.h: add additional float_status flags
35
target/arm/helper: pass explicit fpst to set_rmode
36
arm/translate-a64: implement half-precision F(MIN|MAX)(V|NMV)
37
arm/translate-a64: handle_3same_64 comment fix
38
arm/translate-a64: initial decode for simd_three_reg_same_fp16
39
arm/translate-a64: add FP16 FADD/FABD/FSUB/FMUL/FDIV to simd_three_reg_same_fp16
40
arm/translate-a64: add FP16 F[A]C[EQ/GE/GT] to simd_three_reg_same_fp16
41
arm/translate-a64: add FP16 FMULA/X/S to simd_three_reg_same_fp16
42
arm/translate-a64: add FP16 FR[ECP/SQRT]S to simd_three_reg_same_fp16
43
arm/translate-a64: add FP16 pairwise ops simd_three_reg_same_fp16
44
arm/translate-a64: add FP16 FMULX/MLS/FMLA to simd_indexed
45
arm/translate-a64: add FP16 x2 ops for simd_indexed
46
arm/translate-a64: initial decode for simd_two_reg_misc_fp16
47
arm/translate-a64: add FP16 FPRINTx to simd_two_reg_misc_fp16
48
arm/translate-a64: add FCVTxx to simd_two_reg_misc_fp16
49
arm/translate-a64: add FP16 FCMxx (zero) to simd_two_reg_misc_fp16
50
arm/translate-a64: add FP16 SCVTF/UCVFT to simd_two_reg_misc_fp16
51
arm/translate-a64: add FP16 FNEG/FABS to simd_two_reg_misc_fp16
52
arm/helper.c: re-factor recpe and add recepe_f16
53
arm/translate-a64: add FP16 FRECPE
54
arm/translate-a64: add FP16 FRCPX to simd_two_reg_misc_fp16
55
arm/translate-a64: add FP16 FSQRT to simd_two_reg_misc_fp16
56
arm/helper.c: re-factor rsqrte and add rsqrte_f16
57
arm/translate-a64: add FP16 FRSQRTE to simd_two_reg_misc_fp16
58
arm/translate-a64: add FP16 FMOV to simd_mod_imm
59
arm/translate-a64: add all FP16 ops in simd_scalar_pairwise
60
arm/translate-a64: implement simd_scalar_three_reg_same_fp16
61
arm/translate-a64: add all single op FP16 to handle_fp_1src_half
62
34
63
Alistair Francis (2):
35
Nabih Estefan (1):
64
hw: register: Run post_write hook on reset
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
65
MAINTAINERS: Update my email address
66
37
67
Corey Minyard (2):
38
Peter Maydell (22):
68
i2c: Fix some brace style issues
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
69
i2c: Move the bus class to i2c.h
40
hw/block/tc58128: Don't emit deprecation warning under qtest
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
44
tests/qtest/bios-tables-tests: Update virt golden reference
45
hw/arm/npcm7xx: Call qemu_configure_nic_device() for GMAC modules
46
tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
47
target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
48
target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
49
target/arm: The Cortex-R52 has a read-only CBAR
50
target/arm: Add Cortex-R52 IMPDEF sysregs
51
target/arm: Allow access to SPSR_hyp from hyp mode
52
hw/misc/mps2-scc: Fix condition for CFG3 register
53
hw/misc/mps2-scc: Factor out which-board conditionals
54
hw/misc/mps2-scc: Make changes needed for AN536 FPGA image
55
hw/arm/mps3r: Initial skeleton for mps3-an536 board
56
hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM
57
hw/arm/mps3r: Add UARTs
58
hw/arm/mps3r: Add GPIO, watchdog, dual-timer, I2C devices
59
hw/arm/mps3r: Add remaining devices
60
docs: Add documentation for the mps3-an536 board
70
61
71
Francisco Iglesias (2):
62
Philippe Mathieu-Daudé (5):
72
xilinx_spips: Enable only two slaves when reading/writing with stripe
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
73
xilinx_spips: Use 8 dummy cycles with the QIOR/QIOR4 commands
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
66
hw/arm/stellaris: Add missing QOM 'machine' parent
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
74
68
75
Linus Walleij (3):
69
Richard Henderson (6):
76
hw/i2c-ddc: Do not fail writes
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
77
hw/sii9022: Add support for Silicon Image SII9022
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
78
arm/vexpress: Add proper display connector emulation
72
target/arm: Adjust and validate mtedesc sizem1
73
target/arm: Split out make_svemte_desc
74
target/arm: Handle mte in do_ldrq, do_ldro
75
target/arm: Fix SVE/SME gross MTE suppression checks
79
76
80
Peter Maydell (2):
77
MAINTAINERS | 3 +-
81
target/arm: Enable ARM_V8_FP16 feature bit for the AArch64 "any" CPU
78
docs/system/arm/mps2.rst | 37 +-
82
linux-user: Report AArch64 FP16 support via hwcap bits
79
configs/devices/arm-softmmu/default.mak | 1 +
80
hw/arm/smmuv3-internal.h | 1 +
81
include/hw/arm/smmu-common.h | 1 +
82
include/hw/arm/virt.h | 2 +
83
include/hw/misc/mps2-scc.h | 1 +
84
linux-user/aarch64/target_prctl.h | 29 +-
85
target/arm/internals.h | 2 +-
86
target/arm/tcg/translate-a64.h | 2 +
87
hw/arm/mps3r.c | 640 ++++++++++++++++++++++++++++++++
88
hw/arm/npcm7xx.c | 1 +
89
hw/arm/smmu-common.c | 11 +
90
hw/arm/smmuv3.c | 1 +
91
hw/arm/stellaris.c | 47 ++-
92
hw/arm/virt-acpi-build.c | 20 +-
93
hw/arm/virt.c | 60 ++-
94
hw/arm/xilinx_zynq.c | 2 +
95
hw/block/tc58128.c | 4 +-
96
hw/misc/mps2-scc.c | 138 ++++++-
97
hw/pci-host/raven.c | 1 +
98
target/arm/helper.c | 14 +-
99
target/arm/tcg/cpu32.c | 109 ++++++
100
target/arm/tcg/op_helper.c | 43 ++-
101
target/arm/tcg/sme_helper.c | 8 +-
102
target/arm/tcg/sve_helper.c | 12 +-
103
target/arm/tcg/translate-sme.c | 15 +-
104
target/arm/tcg/translate-sve.c | 83 +++--
105
target/arm/tcg/translate.c | 19 +-
106
tests/qtest/npcm7xx_emc-test.c | 5 +-
107
tests/qtest/npcm_gmac-test.c | 84 +----
108
hw/arm/Kconfig | 5 +
109
hw/arm/meson.build | 1 +
110
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
111
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
112
tests/qtest/meson.build | 4 +-
113
36 files changed, 1184 insertions(+), 222 deletions(-)
114
create mode 100644 hw/arm/mps3r.c
83
115
84
hw/display/Makefile.objs | 1 +
85
include/exec/helper-head.h | 3 +
86
include/fpu/softfloat.h | 18 +-
87
include/hw/i2c/i2c.h | 23 +-
88
include/hw/register.h | 6 +-
89
target/arm/cpu.h | 34 +-
90
target/arm/helper-a64.h | 33 +
91
target/arm/helper.h | 14 +-
92
hw/arm/vexpress.c | 6 +-
93
hw/core/register.c | 8 +
94
hw/display/sii9022.c | 191 ++++++
95
hw/i2c/core.c | 18 -
96
hw/i2c/i2c-ddc.c | 4 +-
97
hw/ssi/xilinx_spips.c | 43 +-
98
linux-user/elfload.c | 2 +
99
target/arm/cpu64.c | 1 +
100
target/arm/helper-a64.c | 269 +++++++++
101
target/arm/helper.c | 481 ++++++++-------
102
target/arm/translate-a64.c | 1266 +++++++++++++++++++++++++++++++++------
103
target/arm/translate.c | 12 +-
104
MAINTAINERS | 12 +-
105
default-configs/arm-softmmu.mak | 2 +
106
hw/display/trace-events | 5 +
107
23 files changed, 1981 insertions(+), 471 deletions(-)
108
create mode 100644 hw/display/sii9022.c
109
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
I only needed to do a little light re-factoring to support the
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
half-precision helpers.
4
connect FIQ output of the GIC CPU interfaces to the CPU.
5
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
8
Message-id: 20180227143852.11175-30-alex.bennee@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/translate-a64.c | 80 +++++++++++++++++++++++++++++++---------------
11
hw/arm/xilinx_zynq.c | 2 ++
12
1 file changed, 54 insertions(+), 26 deletions(-)
12
1 file changed, 2 insertions(+)
13
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
16
--- a/hw/arm/xilinx_zynq.c
17
+++ b/target/arm/translate-a64.c
17
+++ b/hw/arm/xilinx_zynq.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
19
case 0xf: /* FMAXP */
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
20
case 0x2c: /* FMINNMP */
20
sysbus_connect_irq(busdev, 0,
21
case 0x2f: /* FMINP */
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
22
- /* FP op, size[0] is 32 or 64 bit */
22
+ sysbus_connect_irq(busdev, 1,
23
+ /* FP op, size[0] is 32 or 64 bit*/
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
24
if (!u) {
24
25
- unallocated_encoding(s);
25
for (n = 0; n < 64; n++) {
26
- return;
26
pic[n] = qdev_get_gpio_in(dev, n);
27
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
28
+ unallocated_encoding(s);
29
+ return;
30
+ } else {
31
+ size = MO_16;
32
+ }
33
+ } else {
34
+ size = extract32(size, 0, 1) ? MO_64 : MO_32;
35
}
36
+
37
if (!fp_access_check(s)) {
38
return;
39
}
40
41
- size = extract32(size, 0, 1) ? 3 : 2;
42
- fpst = get_fpstatus_ptr(false);
43
+ fpst = get_fpstatus_ptr(size == MO_16);
44
break;
45
default:
46
unallocated_encoding(s);
47
return;
48
}
49
50
- if (size == 3) {
51
+ if (size == MO_64) {
52
TCGv_i64 tcg_op1 = tcg_temp_new_i64();
53
TCGv_i64 tcg_op2 = tcg_temp_new_i64();
54
TCGv_i64 tcg_res = tcg_temp_new_i64();
55
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
56
TCGv_i32 tcg_op2 = tcg_temp_new_i32();
57
TCGv_i32 tcg_res = tcg_temp_new_i32();
58
59
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_32);
60
- read_vec_element_i32(s, tcg_op2, rn, 1, MO_32);
61
+ read_vec_element_i32(s, tcg_op1, rn, 0, size);
62
+ read_vec_element_i32(s, tcg_op2, rn, 1, size);
63
64
- switch (opcode) {
65
- case 0xc: /* FMAXNMP */
66
- gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
67
- break;
68
- case 0xd: /* FADDP */
69
- gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
70
- break;
71
- case 0xf: /* FMAXP */
72
- gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
73
- break;
74
- case 0x2c: /* FMINNMP */
75
- gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst);
76
- break;
77
- case 0x2f: /* FMINP */
78
- gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
79
- break;
80
- default:
81
- g_assert_not_reached();
82
+ if (size == MO_16) {
83
+ switch (opcode) {
84
+ case 0xc: /* FMAXNMP */
85
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
86
+ break;
87
+ case 0xd: /* FADDP */
88
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
89
+ break;
90
+ case 0xf: /* FMAXP */
91
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
92
+ break;
93
+ case 0x2c: /* FMINNMP */
94
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
95
+ break;
96
+ case 0x2f: /* FMINP */
97
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
98
+ break;
99
+ default:
100
+ g_assert_not_reached();
101
+ }
102
+ } else {
103
+ switch (opcode) {
104
+ case 0xc: /* FMAXNMP */
105
+ gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
106
+ break;
107
+ case 0xd: /* FADDP */
108
+ gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
109
+ break;
110
+ case 0xf: /* FMAXP */
111
+ gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
112
+ break;
113
+ case 0x2c: /* FMINNMP */
114
+ gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst);
115
+ break;
116
+ case 0x2f: /* FMINP */
117
+ gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
118
+ break;
119
+ default:
120
+ g_assert_not_reached();
121
+ }
122
}
123
124
write_fp_sreg(s, rd, tcg_res);
125
--
27
--
126
2.16.2
28
2.34.1
127
29
128
30
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
I re-use the existing handle_2misc_fcmp_zero handler and tweak it
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
slightly to deal with the half-precision case.
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
5
6
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
8
Message-id: 20180227143852.11175-20-alex.bennee@linaro.org
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/translate-a64.c | 80 +++++++++++++++++++++++++++++++++-------------
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
12
1 file changed, 57 insertions(+), 23 deletions(-)
15
1 file changed, 17 insertions(+), 12 deletions(-)
13
16
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
19
--- a/linux-user/aarch64/target_prctl.h
17
+++ b/target/arm/translate-a64.c
20
+++ b/linux-user/aarch64/target_prctl.h
18
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
19
bool is_scalar, bool is_u, bool is_q,
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
20
int size, int rn, int rd)
23
21
{
24
if (cpu_isar_feature(aa64_mte, cpu)) {
22
- bool is_double = (size == 3);
25
- switch (arg2 & PR_MTE_TCF_MASK) {
23
+ bool is_double = (size == MO_64);
26
- case PR_MTE_TCF_NONE:
24
TCGv_ptr fpst;
27
- case PR_MTE_TCF_SYNC:
25
28
- case PR_MTE_TCF_ASYNC:
26
if (!fp_access_check(s)) {
27
return;
28
}
29
30
- fpst = get_fpstatus_ptr(false);
31
+ fpst = get_fpstatus_ptr(size == MO_16);
32
33
if (is_double) {
34
TCGv_i64 tcg_op = tcg_temp_new_i64();
35
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
36
bool swap = false;
37
int pass, maxpasses;
38
39
- switch (opcode) {
40
- case 0x2e: /* FCMLT (zero) */
41
- swap = true;
42
- /* fall through */
43
- case 0x2c: /* FCMGT (zero) */
44
- genfn = gen_helper_neon_cgt_f32;
45
- break;
46
- case 0x2d: /* FCMEQ (zero) */
47
- genfn = gen_helper_neon_ceq_f32;
48
- break;
49
- case 0x6d: /* FCMLE (zero) */
50
- swap = true;
51
- /* fall through */
52
- case 0x6c: /* FCMGE (zero) */
53
- genfn = gen_helper_neon_cge_f32;
54
- break;
29
- break;
55
- default:
30
- default:
56
- g_assert_not_reached();
31
- return -EINVAL;
57
+ if (size == MO_16) {
32
- }
58
+ switch (opcode) {
33
-
59
+ case 0x2e: /* FCMLT (zero) */
34
/*
60
+ swap = true;
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
61
+ /* fall through */
36
- * Note that the syscall values are consistent with hw.
62
+ case 0x2c: /* FCMGT (zero) */
37
+ *
63
+ genfn = gen_helper_advsimd_cgt_f16;
38
+ * The kernel has a per-cpu configuration for the sysadmin,
64
+ break;
39
+ * /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
65
+ case 0x2d: /* FCMEQ (zero) */
40
+ * which qemu does not implement.
66
+ genfn = gen_helper_advsimd_ceq_f16;
41
+ *
67
+ break;
42
+ * Because there is no performance difference between the modes, and
68
+ case 0x6d: /* FCMLE (zero) */
43
+ * because SYNC is most useful for debugging MTE errors, choose SYNC
69
+ swap = true;
44
+ * as the preferred mode. With this preference, and the way the API
70
+ /* fall through */
45
+ * uses only two bits, there is no way for the program to select
71
+ case 0x6c: /* FCMGE (zero) */
46
+ * ASYMM mode.
72
+ genfn = gen_helper_advsimd_cge_f16;
47
*/
73
+ break;
48
- env->cp15.sctlr_el[1] =
74
+ default:
49
- deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
75
+ g_assert_not_reached();
50
+ unsigned tcf = 0;
76
+ }
51
+ if (arg2 & PR_MTE_TCF_SYNC) {
77
+ } else {
52
+ tcf = 1;
78
+ switch (opcode) {
53
+ } else if (arg2 & PR_MTE_TCF_ASYNC) {
79
+ case 0x2e: /* FCMLT (zero) */
54
+ tcf = 2;
80
+ swap = true;
55
+ }
81
+ /* fall through */
56
+ env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
82
+ case 0x2c: /* FCMGT (zero) */
57
83
+ genfn = gen_helper_neon_cgt_f32;
58
/*
84
+ break;
59
* Write PR_MTE_TAG to GCR_EL1[Exclude].
85
+ case 0x2d: /* FCMEQ (zero) */
86
+ genfn = gen_helper_neon_ceq_f32;
87
+ break;
88
+ case 0x6d: /* FCMLE (zero) */
89
+ swap = true;
90
+ /* fall through */
91
+ case 0x6c: /* FCMGE (zero) */
92
+ genfn = gen_helper_neon_cge_f32;
93
+ break;
94
+ default:
95
+ g_assert_not_reached();
96
+ }
97
}
98
99
if (is_scalar) {
100
maxpasses = 1;
101
} else {
102
- maxpasses = is_q ? 4 : 2;
103
+ int vector_size = 8 << is_q;
104
+ maxpasses = vector_size >> size;
105
}
106
107
for (pass = 0; pass < maxpasses; pass++) {
108
- read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
109
+ read_vec_element_i32(s, tcg_op, rn, pass, size);
110
if (swap) {
111
genfn(tcg_res, tcg_zero, tcg_op, fpst);
112
} else {
113
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
114
if (is_scalar) {
115
write_fp_sreg(s, rd, tcg_res);
116
} else {
117
- write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
118
+ write_vec_element_i32(s, tcg_res, rd, pass, size);
119
}
120
}
121
tcg_temp_free_i32(tcg_res);
122
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
123
fpop = deposit32(opcode, 5, 1, a);
124
fpop = deposit32(fpop, 6, 1, u);
125
126
+ rd = extract32(insn, 0, 5);
127
+ rn = extract32(insn, 5, 5);
128
+
129
switch (fpop) {
130
+ break;
131
+ case 0x2c: /* FCMGT (zero) */
132
+ case 0x2d: /* FCMEQ (zero) */
133
+ case 0x2e: /* FCMLT (zero) */
134
+ case 0x6c: /* FCMGE (zero) */
135
+ case 0x6d: /* FCMLE (zero) */
136
+ handle_2misc_fcmp_zero(s, fpop, is_scalar, 0, is_q, MO_16, rn, rd);
137
+ return;
138
case 0x18: /* FRINTN */
139
need_rmode = true;
140
only_in_vector = true;
141
--
60
--
142
2.16.2
61
2.34.1
143
144
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
A bunch of the vectorised bitwise operations just operate on larger
3
The field is encoded as [0-3], which is convenient for
4
chunks at a time. We can do the same for the new half-precision
4
indexing our array of function pointers, but the true
5
operations by introducing some TWOHALFOP helpers which work on each
5
value is [1-4]. Adjust before calling do_mem_zpa.
6
half of a pair of half-precision operations at once.
7
6
8
Hopefully all this hoop jumping will get simpler once we have
7
Add an assert, and move the comment re passing ZT to
9
generically vectorised helpers here.
8
the helper back next to the relevant code.
10
9
11
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Cc: qemu-stable@nongnu.org
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Fixes: 206adacfb8d ("target/arm: Add mte helpers for sve scalar + int loads")
13
Message-id: 20180227143852.11175-16-alex.bennee@linaro.org
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
17
---
16
target/arm/helper-a64.h | 10 ++++++++++
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
17
target/arm/helper-a64.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
19
1 file changed, 8 insertions(+), 8 deletions(-)
18
target/arm/translate-a64.c | 26 +++++++++++++++++++++-----
19
3 files changed, 76 insertions(+), 6 deletions(-)
20
20
21
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
22
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper-a64.h
23
--- a/target/arm/tcg/translate-sve.c
24
+++ b/target/arm/helper-a64.h
24
+++ b/target/arm/tcg/translate-sve.c
25
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_acge_f16, i32, f16, f16, ptr)
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
26
DEF_HELPER_3(advsimd_acgt_f16, i32, f16, f16, ptr)
26
TCGv_ptr t_pg;
27
DEF_HELPER_3(advsimd_mulxh, f16, f16, f16, ptr)
27
int desc = 0;
28
DEF_HELPER_4(advsimd_muladdh, f16, f16, f16, f16, ptr)
28
29
+DEF_HELPER_3(advsimd_add2h, i32, i32, i32, ptr)
29
- /*
30
+DEF_HELPER_3(advsimd_sub2h, i32, i32, i32, ptr)
30
- * For e.g. LD4, there are not enough arguments to pass all 4
31
+DEF_HELPER_3(advsimd_mul2h, i32, i32, i32, ptr)
31
- * registers as pointers, so encode the regno into the data field.
32
+DEF_HELPER_3(advsimd_div2h, i32, i32, i32, ptr)
32
- * For consistency, do this even for LD1.
33
+DEF_HELPER_3(advsimd_max2h, i32, i32, i32, ptr)
33
- */
34
+DEF_HELPER_3(advsimd_min2h, i32, i32, i32, ptr)
34
+ assert(mte_n >= 1 && mte_n <= 4);
35
+DEF_HELPER_3(advsimd_maxnum2h, i32, i32, i32, ptr)
35
if (s->mte_active[0]) {
36
+DEF_HELPER_3(advsimd_minnum2h, i32, i32, i32, ptr)
36
int msz = dtype_msz(dtype);
37
+DEF_HELPER_3(advsimd_mulx2h, i32, i32, i32, ptr)
37
38
+DEF_HELPER_4(advsimd_muladd2h, i32, i32, i32, i32, ptr)
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
39
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
39
addr = clean_data_tbi(s, addr);
40
index XXXXXXX..XXXXXXX 100644
40
}
41
--- a/target/arm/helper-a64.c
41
42
+++ b/target/arm/helper-a64.c
42
+ /*
43
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(max)
43
+ * For e.g. LD4, there are not enough arguments to pass all 4
44
ADVSIMD_HALFOP(minnum)
44
+ * registers as pointers, so encode the regno into the data field.
45
ADVSIMD_HALFOP(maxnum)
45
+ * For consistency, do this even for LD1.
46
46
+ */
47
+#define ADVSIMD_TWOHALFOP(name) \
47
desc = simd_desc(vsz, vsz, zt | desc);
48
+uint32_t ADVSIMD_HELPER(name, 2h)(uint32_t two_a, uint32_t two_b, void *fpstp) \
48
t_pg = tcg_temp_new_ptr();
49
+{ \
49
50
+ float16 a1, a2, b1, b2; \
50
@@ -XXX,XX +XXX,XX @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
51
+ uint32_t r1, r2; \
51
* accessible via the instruction encoding.
52
+ float_status *fpst = fpstp; \
52
*/
53
+ a1 = extract32(two_a, 0, 16); \
53
assert(fn != NULL);
54
+ a2 = extract32(two_a, 16, 16); \
54
- do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn);
55
+ b1 = extract32(two_b, 0, 16); \
55
+ do_mem_zpa(s, zt, pg, addr, dtype, nreg + 1, false, fn);
56
+ b2 = extract32(two_b, 16, 16); \
57
+ r1 = float16_ ## name(a1, b1, fpst); \
58
+ r2 = float16_ ## name(a2, b2, fpst); \
59
+ return deposit32(r1, 16, 16, r2); \
60
+}
61
+
62
+ADVSIMD_TWOHALFOP(add)
63
+ADVSIMD_TWOHALFOP(sub)
64
+ADVSIMD_TWOHALFOP(mul)
65
+ADVSIMD_TWOHALFOP(div)
66
+ADVSIMD_TWOHALFOP(min)
67
+ADVSIMD_TWOHALFOP(max)
68
+ADVSIMD_TWOHALFOP(minnum)
69
+ADVSIMD_TWOHALFOP(maxnum)
70
+
71
/* Data processing - scalar floating-point and advanced SIMD */
72
-float16 HELPER(advsimd_mulxh)(float16 a, float16 b, void *fpstp)
73
+static float16 float16_mulx(float16 a, float16 b, void *fpstp)
74
{
75
float_status *fpst = fpstp;
76
77
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_mulxh)(float16 a, float16 b, void *fpstp)
78
return float16_mul(a, b, fpst);
79
}
56
}
80
57
81
+ADVSIMD_HALFOP(mulx)
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
82
+ADVSIMD_TWOHALFOP(mulx)
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
83
+
60
if (nreg == 0) {
84
/* fused multiply-accumulate */
61
/* ST1 */
85
float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
86
{
63
- nreg = 1;
87
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
64
} else {
88
return float16_muladd(a, b, c, 0, fpst);
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
66
assert(msz == esz);
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
68
}
69
assert(fn != NULL);
70
- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn);
71
+ do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn);
89
}
72
}
90
73
91
+uint32_t HELPER(advsimd_muladd2h)(uint32_t two_a, uint32_t two_b,
74
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
92
+ uint32_t two_c, void *fpstp)
93
+{
94
+ float_status *fpst = fpstp;
95
+ float16 a1, a2, b1, b2, c1, c2;
96
+ uint32_t r1, r2;
97
+ a1 = extract32(two_a, 0, 16);
98
+ a2 = extract32(two_a, 16, 16);
99
+ b1 = extract32(two_b, 0, 16);
100
+ b2 = extract32(two_b, 16, 16);
101
+ c1 = extract32(two_c, 0, 16);
102
+ c2 = extract32(two_c, 16, 16);
103
+ r1 = float16_muladd(a1, b1, c1, 0, fpst);
104
+ r2 = float16_muladd(a2, b2, c2, 0, fpst);
105
+ return deposit32(r1, 16, 16, r2);
106
+}
107
+
108
/*
109
* Floating point comparisons produce an integer result. Softfloat
110
* routines return float_relation types which we convert to the 0/-1
111
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate-a64.c
114
+++ b/target/arm/translate-a64.c
115
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
116
* multiply-add */
117
tcg_gen_xori_i32(tcg_op, tcg_op, 0x80008000);
118
}
119
- gen_helper_advsimd_muladdh(tcg_res, tcg_op, tcg_idx,
120
- tcg_res, fpst);
121
+ if (is_scalar) {
122
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op, tcg_idx,
123
+ tcg_res, fpst);
124
+ } else {
125
+ gen_helper_advsimd_muladd2h(tcg_res, tcg_op, tcg_idx,
126
+ tcg_res, fpst);
127
+ }
128
break;
129
case 2:
130
if (opcode == 0x5) {
131
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
132
switch (size) {
133
case 1:
134
if (u) {
135
- gen_helper_advsimd_mulxh(tcg_res, tcg_op, tcg_idx,
136
- fpst);
137
+ if (is_scalar) {
138
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op,
139
+ tcg_idx, fpst);
140
+ } else {
141
+ gen_helper_advsimd_mulx2h(tcg_res, tcg_op,
142
+ tcg_idx, fpst);
143
+ }
144
} else {
145
- g_assert_not_reached();
146
+ if (is_scalar) {
147
+ gen_helper_advsimd_mulh(tcg_res, tcg_op,
148
+ tcg_idx, fpst);
149
+ } else {
150
+ gen_helper_advsimd_mul2h(tcg_res, tcg_op,
151
+ tcg_idx, fpst);
152
+ }
153
}
154
break;
155
case 2:
156
--
75
--
157
2.16.2
76
2.34.1
158
159
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Only one half-precision instruction has been added to this group.
3
When we added SVE_MTEDESC_SHIFT, we effectively limited the
4
maximum size of MTEDESC. Adjust SIZEM1 to consume the remaining
5
bits (32 - 10 - 5 - 12 == 5). Assert that the data to be stored
6
fits within the field (expecting 8 * 4 - 1 == 31, exact fit).
4
7
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180227143852.11175-29-alex.bennee@linaro.org
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
target/arm/translate-a64.c | 35 +++++++++++++++++++++++++----------
15
target/arm/internals.h | 2 +-
11
1 file changed, 25 insertions(+), 10 deletions(-)
16
target/arm/tcg/translate-sve.c | 7 ++++---
17
2 files changed, 5 insertions(+), 4 deletions(-)
12
18
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
21
--- a/target/arm/internals.h
16
+++ b/target/arm/translate-a64.c
22
+++ b/target/arm/internals.h
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_copy(DisasContext *s, uint32_t insn)
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
18
* MVNI - move inverted (shifted) imm into register
24
FIELD(MTEDESC, TCMA, 6, 2)
19
* ORR - bitwise OR of (shifted) imm with register
25
FIELD(MTEDESC, WRITE, 8, 1)
20
* BIC - bitwise clear of (shifted) imm with register
26
FIELD(MTEDESC, ALIGN, 9, 3)
21
+ * With ARMv8.2 we also have:
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
22
+ * FMOV half-precision
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
23
*/
29
24
static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/tcg/translate-sve.c
35
+++ b/target/arm/tcg/translate-sve.c
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
25
{
37
{
26
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
38
unsigned vsz = vec_full_reg_size(s);
27
uint64_t imm = 0;
39
TCGv_ptr t_pg;
28
40
+ uint32_t sizem1;
29
if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
41
int desc = 0;
30
- unallocated_encoding(s);
42
31
- return;
43
assert(mte_n >= 1 && mte_n <= 4);
32
+ /* Check for FMOV (vector, immediate) - half-precision */
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
33
+ if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
34
+ unallocated_encoding(s);
46
if (s->mte_active[0]) {
35
+ return;
47
- int msz = dtype_msz(dtype);
36
+ }
48
-
37
}
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
38
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
39
if (!fp_access_check(s)) {
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
40
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
41
imm |= 0x4000000000000000ULL;
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
42
}
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
43
} else {
55
desc <<= SVE_MTEDESC_SHIFT;
44
- imm = (abcdefgh & 0x3f) << 19;
56
} else {
45
- if (abcdefgh & 0x80) {
57
addr = clean_data_tbi(s, addr);
46
- imm |= 0x80000000;
47
- }
48
- if (abcdefgh & 0x40) {
49
- imm |= 0x3e000000;
50
+ if (o2) {
51
+ /* FMOV (vector, immediate) - half-precision */
52
+ imm = vfp_expand_imm(MO_16, abcdefgh);
53
+ /* now duplicate across the lanes */
54
+ imm = bitfield_replicate(imm, 16);
55
} else {
56
- imm |= 0x40000000;
57
+ imm = (abcdefgh & 0x3f) << 19;
58
+ if (abcdefgh & 0x80) {
59
+ imm |= 0x80000000;
60
+ }
61
+ if (abcdefgh & 0x40) {
62
+ imm |= 0x3e000000;
63
+ } else {
64
+ imm |= 0x40000000;
65
+ }
66
+ imm |= (imm << 32);
67
}
68
- imm |= (imm << 32);
69
}
70
}
71
break;
72
+ default:
73
+ fprintf(stderr, "%s: cmode_3_1: %x\n", __func__, cmode_3_1);
74
+ g_assert_not_reached();
75
}
76
77
if (cmode_3_1 != 7 && is_neg) {
78
--
58
--
79
2.16.2
59
2.34.1
80
81
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This covers all the floating point convert operations.
3
Share code that creates mtedesc and embeds within simd_desc.
4
4
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180227143852.11175-19-alex.bennee@linaro.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/helper-a64.h | 2 ++
12
target/arm/tcg/translate-a64.h | 2 ++
11
target/arm/helper-a64.c | 32 +++++++++++++++++
13
target/arm/tcg/translate-sme.c | 15 +++--------
12
target/arm/translate-a64.c | 85 +++++++++++++++++++++++++++++++++++++++++++++-
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
13
3 files changed, 118 insertions(+), 1 deletion(-)
15
3 files changed, 31 insertions(+), 33 deletions(-)
14
16
15
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.h
19
--- a/target/arm/tcg/translate-a64.h
18
+++ b/target/arm/helper-a64.h
20
+++ b/target/arm/tcg/translate-a64.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_mulx2h, i32, i32, i32, ptr)
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
20
DEF_HELPER_4(advsimd_muladd2h, i32, i32, i32, i32, ptr)
22
bool sve_access_check(DisasContext *s);
21
DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr)
23
bool sme_enabled_check(DisasContext *s);
22
DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
23
+DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
24
+DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
26
+ uint32_t msz, bool is_write, uint32_t data);
25
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
27
28
/* This function corresponds to CheckStreamingSVEEnabled. */
29
static inline bool sme_sm_enabled_check(DisasContext *s)
30
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
26
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper-a64.c
32
--- a/target/arm/tcg/translate-sme.c
28
+++ b/target/arm/helper-a64.c
33
+++ b/target/arm/tcg/translate-sme.c
29
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
30
35
31
return ret;
36
TCGv_ptr t_za, t_pg;
32
}
37
TCGv_i64 addr;
38
- int svl, desc = 0;
39
+ uint32_t desc;
40
bool be = s->be_data == MO_BE;
41
bool mte = s->mte_active[0];
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
44
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
45
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
46
47
- if (mte) {
48
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
49
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
50
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
51
- desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
52
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
53
- desc <<= SVE_MTEDESC_SHIFT;
54
- } else {
55
+ if (!mte) {
56
addr = clean_data_tbi(s, addr);
57
}
58
- svl = streaming_vec_reg_size(s);
59
- desc = simd_desc(svl, svl, desc);
33
+
60
+
34
+/*
61
+ desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
35
+ * Half-precision floating point conversion functions
62
36
+ *
63
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
37
+ * There are a multitude of conversion functions with various
64
tcg_constant_i32(desc));
38
+ * different rounding modes. This is dealt with by the calling code
65
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
39
+ * setting the mode appropriately before calling the helper.
66
index XXXXXXX..XXXXXXX 100644
40
+ */
67
--- a/target/arm/tcg/translate-sve.c
68
+++ b/target/arm/tcg/translate-sve.c
69
@@ -XXX,XX +XXX,XX @@ static const uint8_t dtype_esz[16] = {
70
3, 2, 1, 3
71
};
72
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
74
- int dtype, uint32_t mte_n, bool is_write,
75
- gen_helper_gvec_mem *fn)
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
77
+ uint32_t msz, bool is_write, uint32_t data)
78
{
79
- unsigned vsz = vec_full_reg_size(s);
80
- TCGv_ptr t_pg;
81
uint32_t sizem1;
82
- int desc = 0;
83
+ uint32_t desc = 0;
84
85
- assert(mte_n >= 1 && mte_n <= 4);
86
- sizem1 = (mte_n << dtype_msz(dtype)) - 1;
87
+ /* Assert all of the data fits, with or without MTE enabled. */
88
+ assert(nregs >= 1 && nregs <= 4);
89
+ sizem1 = (nregs << msz) - 1;
90
assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
91
+ assert(data < 1u << SVE_MTEDESC_SHIFT);
41
+
92
+
42
+uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
93
if (s->mte_active[0]) {
43
+{
94
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
44
+ float_status *fpst = fpstp;
95
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
45
+
96
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
46
+ /* Invalid if we are passed a NaN */
97
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
47
+ if (float16_is_any_nan(a)) {
98
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
48
+ float_raise(float_flag_invalid, fpst);
99
desc <<= SVE_MTEDESC_SHIFT;
49
+ return 0;
100
- } else {
50
+ }
101
+ }
51
+ return float16_to_int16(a, fpst);
102
+ return simd_desc(vsz, vsz, desc | data);
52
+}
103
+}
53
+
104
+
54
+uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
105
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
106
+ int dtype, uint32_t nregs, bool is_write,
107
+ gen_helper_gvec_mem *fn)
55
+{
108
+{
56
+ float_status *fpst = fpstp;
109
+ TCGv_ptr t_pg;
110
+ uint32_t desc;
57
+
111
+
58
+ /* Invalid if we are passed a NaN */
112
+ if (!s->mte_active[0]) {
59
+ if (float16_is_any_nan(a)) {
113
addr = clean_data_tbi(s, addr);
60
+ float_raise(float_flag_invalid, fpst);
61
+ return 0;
62
+ }
63
+ return float16_to_uint16(a, fpst);
64
+}
65
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/translate-a64.c
68
+++ b/target/arm/translate-a64.c
69
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
70
only_in_vector = true;
71
/* current rounding mode */
72
break;
73
+ case 0x1a: /* FCVTNS */
74
+ need_rmode = true;
75
+ rmode = FPROUNDING_TIEEVEN;
76
+ break;
77
+ case 0x1b: /* FCVTMS */
78
+ need_rmode = true;
79
+ rmode = FPROUNDING_NEGINF;
80
+ break;
81
+ case 0x1c: /* FCVTAS */
82
+ need_rmode = true;
83
+ rmode = FPROUNDING_TIEAWAY;
84
+ break;
85
+ case 0x3a: /* FCVTPS */
86
+ need_rmode = true;
87
+ rmode = FPROUNDING_POSINF;
88
+ break;
89
+ case 0x3b: /* FCVTZS */
90
+ need_rmode = true;
91
+ rmode = FPROUNDING_ZERO;
92
+ break;
93
+ case 0x5a: /* FCVTNU */
94
+ need_rmode = true;
95
+ rmode = FPROUNDING_TIEEVEN;
96
+ break;
97
+ case 0x5b: /* FCVTMU */
98
+ need_rmode = true;
99
+ rmode = FPROUNDING_NEGINF;
100
+ break;
101
+ case 0x5c: /* FCVTAU */
102
+ need_rmode = true;
103
+ rmode = FPROUNDING_TIEAWAY;
104
+ break;
105
+ case 0x7a: /* FCVTPU */
106
+ need_rmode = true;
107
+ rmode = FPROUNDING_POSINF;
108
+ break;
109
+ case 0x7b: /* FCVTZU */
110
+ need_rmode = true;
111
+ rmode = FPROUNDING_ZERO;
112
+ break;
113
default:
114
fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
115
g_assert_not_reached();
116
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
117
}
114
}
118
115
119
if (is_scalar) {
116
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
120
- /* no operations yet */
117
* registers as pointers, so encode the regno into the data field.
121
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
118
* For consistency, do this even for LD1.
122
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
119
*/
120
- desc = simd_desc(vsz, vsz, zt | desc);
121
+ desc = make_svemte_desc(s, vec_full_reg_size(s), nregs,
122
+ dtype_msz(dtype), is_write, zt);
123
t_pg = tcg_temp_new_ptr();
124
125
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
126
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
127
int scale, TCGv_i64 scalar, int msz, bool is_write,
128
gen_helper_gvec_mem_scatter *fn)
129
{
130
- unsigned vsz = vec_full_reg_size(s);
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
134
- int desc = 0;
135
-
136
- if (s->mte_active[0]) {
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
142
- desc <<= SVE_MTEDESC_SHIFT;
143
- }
144
- desc = simd_desc(vsz, vsz, desc | scale);
145
+ uint32_t desc;
146
147
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
148
tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm));
149
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
123
+
150
+
124
+ read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
125
+
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
126
+ switch (fpop) {
153
}
127
+ case 0x1a: /* FCVTNS */
154
128
+ case 0x1b: /* FCVTMS */
129
+ case 0x1c: /* FCVTAS */
130
+ case 0x3a: /* FCVTPS */
131
+ case 0x3b: /* FCVTZS */
132
+ gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
133
+ break;
134
+ case 0x5a: /* FCVTNU */
135
+ case 0x5b: /* FCVTMU */
136
+ case 0x5c: /* FCVTAU */
137
+ case 0x7a: /* FCVTPU */
138
+ case 0x7b: /* FCVTZU */
139
+ gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus);
140
+ break;
141
+ default:
142
+ g_assert_not_reached();
143
+ }
144
+
145
+ /* limit any sign extension going on */
146
+ tcg_gen_andi_i32(tcg_res, tcg_res, 0xffff);
147
+ write_fp_sreg(s, rd, tcg_res);
148
+
149
+ tcg_temp_free_i32(tcg_res);
150
+ tcg_temp_free_i32(tcg_op);
151
} else {
152
for (pass = 0; pass < (is_q ? 8 : 4); pass++) {
153
TCGv_i32 tcg_op = tcg_temp_new_i32();
154
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
155
read_vec_element_i32(s, tcg_op, rn, pass, MO_16);
156
157
switch (fpop) {
158
+ case 0x1a: /* FCVTNS */
159
+ case 0x1b: /* FCVTMS */
160
+ case 0x1c: /* FCVTAS */
161
+ case 0x3a: /* FCVTPS */
162
+ case 0x3b: /* FCVTZS */
163
+ gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
164
+ break;
165
+ case 0x5a: /* FCVTNU */
166
+ case 0x5b: /* FCVTMU */
167
+ case 0x5c: /* FCVTAU */
168
+ case 0x7a: /* FCVTPU */
169
+ case 0x7b: /* FCVTZU */
170
+ gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus);
171
+ break;
172
case 0x18: /* FRINTN */
173
case 0x19: /* FRINTM */
174
case 0x38: /* FRINTP */
175
--
155
--
176
2.16.2
156
2.34.1
177
178
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This includes FMAXNMP, FADDP, FMAXP, FMINNMP, FMINP.
3
These functions "use the standard load helpers", but
4
fail to clean_data_tbi or populate mtedesc.
4
5
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180227143852.11175-14-alex.bennee@linaro.org
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
target/arm/translate-a64.c | 208 +++++++++++++++++++++++++++++----------------
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
11
1 file changed, 133 insertions(+), 75 deletions(-)
14
1 file changed, 13 insertions(+), 2 deletions(-)
12
15
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
18
--- a/target/arm/tcg/translate-sve.c
16
+++ b/target/arm/translate-a64.c
19
+++ b/target/arm/tcg/translate-sve.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
18
int datasize, elements;
21
unsigned vsz = vec_full_reg_size(s);
19
int pass;
22
TCGv_ptr t_pg;
20
TCGv_ptr fpst;
23
int poff;
21
+ bool pairwise = false;
24
+ uint32_t desc;
22
25
23
if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
26
/* Load the first quadword using the normal predicated load helpers. */
24
unallocated_encoding(s);
27
+ if (!s->mte_active[0]) {
25
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
28
+ addr = clean_data_tbi(s, addr);
26
datasize = is_q ? 128 : 64;
27
elements = datasize / 16;
28
29
+ switch (fpopcode) {
30
+ case 0x10: /* FMAXNMP */
31
+ case 0x12: /* FADDP */
32
+ case 0x16: /* FMAXP */
33
+ case 0x18: /* FMINNMP */
34
+ case 0x1e: /* FMINP */
35
+ pairwise = true;
36
+ break;
37
+ }
29
+ }
38
+
30
+
39
fpst = get_fpstatus_ptr(true);
31
poff = pred_full_reg_offset(s, pg);
40
32
if (vsz > 16) {
41
- for (pass = 0; pass < elements; pass++) {
33
/*
42
+ if (pairwise) {
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
43
+ int maxpass = is_q ? 8 : 4;
35
44
TCGv_i32 tcg_op1 = tcg_temp_new_i32();
36
gen_helper_gvec_mem *fn
45
TCGv_i32 tcg_op2 = tcg_temp_new_i32();
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
46
- TCGv_i32 tcg_res = tcg_temp_new_i32();
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
47
+ TCGv_i32 tcg_res[8];
39
+ desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
48
40
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
49
- read_vec_element_i32(s, tcg_op1, rn, pass, MO_16);
41
50
- read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);
42
/* Replicate that first quadword. */
51
+ for (pass = 0; pass < maxpass; pass++) {
43
if (vsz > 16) {
52
+ int passreg = pass < (maxpass / 2) ? rn : rm;
44
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
53
+ int passelt = (pass << 1) & (maxpass - 1);
45
unsigned vsz_r32;
54
46
TCGv_ptr t_pg;
55
- switch (fpopcode) {
47
int poff, doff;
56
- case 0x0: /* FMAXNM */
48
+ uint32_t desc;
57
- gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
49
58
- break;
50
if (vsz < 32) {
59
- case 0x1: /* FMLA */
51
/*
60
- read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
52
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
61
- gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
62
- fpst);
63
- break;
64
- case 0x2: /* FADD */
65
- gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
66
- break;
67
- case 0x3: /* FMULX */
68
- gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
69
- break;
70
- case 0x4: /* FCMEQ */
71
- gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
72
- break;
73
- case 0x6: /* FMAX */
74
- gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
75
- break;
76
- case 0x7: /* FRECPS */
77
- gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
78
- break;
79
- case 0x8: /* FMINNM */
80
- gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
81
- break;
82
- case 0x9: /* FMLS */
83
- /* As usual for ARM, separate negation for fused multiply-add */
84
- tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
85
- read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
86
- gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
87
- fpst);
88
- break;
89
- case 0xa: /* FSUB */
90
- gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
91
- break;
92
- case 0xe: /* FMIN */
93
- gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
94
- break;
95
- case 0xf: /* FRSQRTS */
96
- gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
97
- break;
98
- case 0x13: /* FMUL */
99
- gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
100
- break;
101
- case 0x14: /* FCMGE */
102
- gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
103
- break;
104
- case 0x15: /* FACGE */
105
- gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
106
- break;
107
- case 0x17: /* FDIV */
108
- gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
109
- break;
110
- case 0x1a: /* FABD */
111
- gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
112
- tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
113
- break;
114
- case 0x1c: /* FCMGT */
115
- gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
116
- break;
117
- case 0x1d: /* FACGT */
118
- gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
119
- break;
120
- default:
121
- fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
122
- __func__, insn, fpopcode, s->pc);
123
- g_assert_not_reached();
124
+ read_vec_element_i32(s, tcg_op1, passreg, passelt, MO_16);
125
+ read_vec_element_i32(s, tcg_op2, passreg, passelt + 1, MO_16);
126
+ tcg_res[pass] = tcg_temp_new_i32();
127
+
128
+ switch (fpopcode) {
129
+ case 0x10: /* FMAXNMP */
130
+ gen_helper_advsimd_maxnumh(tcg_res[pass], tcg_op1, tcg_op2,
131
+ fpst);
132
+ break;
133
+ case 0x12: /* FADDP */
134
+ gen_helper_advsimd_addh(tcg_res[pass], tcg_op1, tcg_op2, fpst);
135
+ break;
136
+ case 0x16: /* FMAXP */
137
+ gen_helper_advsimd_maxh(tcg_res[pass], tcg_op1, tcg_op2, fpst);
138
+ break;
139
+ case 0x18: /* FMINNMP */
140
+ gen_helper_advsimd_minnumh(tcg_res[pass], tcg_op1, tcg_op2,
141
+ fpst);
142
+ break;
143
+ case 0x1e: /* FMINP */
144
+ gen_helper_advsimd_minh(tcg_res[pass], tcg_op1, tcg_op2, fpst);
145
+ break;
146
+ default:
147
+ g_assert_not_reached();
148
+ }
149
+ }
150
+
151
+ for (pass = 0; pass < maxpass; pass++) {
152
+ write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_16);
153
+ tcg_temp_free_i32(tcg_res[pass]);
154
}
155
156
- write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
157
- tcg_temp_free_i32(tcg_res);
158
tcg_temp_free_i32(tcg_op1);
159
tcg_temp_free_i32(tcg_op2);
160
+
161
+ } else {
162
+ for (pass = 0; pass < elements; pass++) {
163
+ TCGv_i32 tcg_op1 = tcg_temp_new_i32();
164
+ TCGv_i32 tcg_op2 = tcg_temp_new_i32();
165
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
166
+
167
+ read_vec_element_i32(s, tcg_op1, rn, pass, MO_16);
168
+ read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);
169
+
170
+ switch (fpopcode) {
171
+ case 0x0: /* FMAXNM */
172
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
173
+ break;
174
+ case 0x1: /* FMLA */
175
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
176
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
177
+ fpst);
178
+ break;
179
+ case 0x2: /* FADD */
180
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
181
+ break;
182
+ case 0x3: /* FMULX */
183
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
184
+ break;
185
+ case 0x4: /* FCMEQ */
186
+ gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
187
+ break;
188
+ case 0x6: /* FMAX */
189
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
190
+ break;
191
+ case 0x7: /* FRECPS */
192
+ gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
193
+ break;
194
+ case 0x8: /* FMINNM */
195
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
196
+ break;
197
+ case 0x9: /* FMLS */
198
+ /* As usual for ARM, separate negation for fused multiply-add */
199
+ tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
200
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
201
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
202
+ fpst);
203
+ break;
204
+ case 0xa: /* FSUB */
205
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
206
+ break;
207
+ case 0xe: /* FMIN */
208
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
209
+ break;
210
+ case 0xf: /* FRSQRTS */
211
+ gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
212
+ break;
213
+ case 0x13: /* FMUL */
214
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
215
+ break;
216
+ case 0x14: /* FCMGE */
217
+ gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
218
+ break;
219
+ case 0x15: /* FACGE */
220
+ gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
221
+ break;
222
+ case 0x17: /* FDIV */
223
+ gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
224
+ break;
225
+ case 0x1a: /* FABD */
226
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
227
+ tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
228
+ break;
229
+ case 0x1c: /* FCMGT */
230
+ gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
231
+ break;
232
+ case 0x1d: /* FACGT */
233
+ gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
234
+ break;
235
+ default:
236
+ fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
237
+ __func__, insn, fpopcode, s->pc);
238
+ g_assert_not_reached();
239
+ }
240
+
241
+ write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
242
+ tcg_temp_free_i32(tcg_res);
243
+ tcg_temp_free_i32(tcg_op1);
244
+ tcg_temp_free_i32(tcg_op2);
245
+ }
246
}
53
}
247
54
248
tcg_temp_free_ptr(fpst);
55
/* Load the first octaword using the normal predicated load helpers. */
56
+ if (!s->mte_active[0]) {
57
+ addr = clean_data_tbi(s, addr);
58
+ }
59
60
poff = pred_full_reg_offset(s, pg);
61
if (vsz > 32) {
62
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
63
64
gen_helper_gvec_mem *fn
65
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
66
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt)));
67
+ desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
68
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
69
70
/*
71
* Replicate that first octaword.
249
--
72
--
250
2.16.2
73
2.34.1
251
252
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
It looks like the ARM ARM has simplified the pseudo code for the
3
The TBI and TCMA bits are located within mtedesc, not desc.
4
calculation which is done on a fixed point 9 bit integer maths. So
5
while adding f16 we can also clean this up to be a little less heavy
6
on the floating point and just return the fractional part and leave
7
the calle's to do the final packing of the result.
8
4
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
5
Cc: qemu-stable@nongnu.org
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180227143852.11175-23-alex.bennee@linaro.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
target/arm/helper.h | 1 +
12
target/arm/tcg/sme_helper.c | 8 ++++----
15
target/arm/helper.c | 226 +++++++++++++++++++++++++++++-----------------------
13
target/arm/tcg/sve_helper.c | 12 ++++++------
16
2 files changed, 129 insertions(+), 98 deletions(-)
14
2 files changed, 10 insertions(+), 10 deletions(-)
17
15
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
18
--- a/target/arm/tcg/sme_helper.c
21
+++ b/target/arm/helper.h
19
+++ b/target/arm/tcg/sme_helper.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
23
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
24
DEF_HELPER_3(recps_f32, f32, f32, f32, env)
22
25
DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
23
/* Perform gross MTE suppression early. */
26
+DEF_HELPER_FLAGS_2(recpe_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
24
- if (!tbi_check(desc, bit55) ||
27
DEF_HELPER_FLAGS_2(recpe_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
28
DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
26
+ if (!tbi_check(mtedesc, bit55) ||
29
DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
mtedesc = 0;
29
}
30
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
33
34
/* Perform gross MTE suppression early. */
35
- if (!tbi_check(desc, bit55) ||
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
37
+ if (!tbi_check(mtedesc, bit55) ||
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
39
mtedesc = 0;
40
}
41
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
31
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
44
--- a/target/arm/tcg/sve_helper.c
33
+++ b/target/arm/helper.c
45
+++ b/target/arm/tcg/sve_helper.c
34
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
35
* int->float conversions at run-time. */
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
36
#define float64_256 make_float64(0x4070000000000000LL)
48
37
#define float64_512 make_float64(0x4080000000000000LL)
49
/* Perform gross MTE suppression early. */
38
+#define float16_maxnorm make_float16(0x7bff)
50
- if (!tbi_check(desc, bit55) ||
39
#define float32_maxnorm make_float32(0x7f7fffff)
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
40
#define float64_maxnorm make_float64(0x7fefffffffffffffLL)
52
+ if (!tbi_check(mtedesc, bit55) ||
41
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
42
/* Reciprocal functions
54
mtedesc = 0;
43
*
44
* The algorithm that must be used to calculate the estimate
45
- * is specified by the ARM ARM, see FPRecipEstimate()
46
+ * is specified by the ARM ARM, see FPRecipEstimate()/RecipEstimate
47
*/
48
49
-static float64 recip_estimate(float64 a, float_status *real_fp_status)
50
+/* See RecipEstimate()
51
+ *
52
+ * input is a 9 bit fixed point number
53
+ * input range 256 .. 511 for a number from 0.5 <= x < 1.0.
54
+ * result range 256 .. 511 for a number from 1.0 to 511/256.
55
+ */
56
+
57
+static int recip_estimate(int input)
58
{
59
- /* These calculations mustn't set any fp exception flags,
60
- * so we use a local copy of the fp_status.
61
- */
62
- float_status dummy_status = *real_fp_status;
63
- float_status *s = &dummy_status;
64
- /* q = (int)(a * 512.0) */
65
- float64 q = float64_mul(float64_512, a, s);
66
- int64_t q_int = float64_to_int64_round_to_zero(q, s);
67
-
68
- /* r = 1.0 / (((double)q + 0.5) / 512.0) */
69
- q = int64_to_float64(q_int, s);
70
- q = float64_add(q, float64_half, s);
71
- q = float64_div(q, float64_512, s);
72
- q = float64_div(float64_one, q, s);
73
-
74
- /* s = (int)(256.0 * r + 0.5) */
75
- q = float64_mul(q, float64_256, s);
76
- q = float64_add(q, float64_half, s);
77
- q_int = float64_to_int64_round_to_zero(q, s);
78
-
79
- /* return (double)s / 256.0 */
80
- return float64_div(int64_to_float64(q_int, s), float64_256, s);
81
+ int a, b, r;
82
+ assert(256 <= input && input < 512);
83
+ a = (input * 2) + 1;
84
+ b = (1 << 19) / a;
85
+ r = (b + 1) >> 1;
86
+ assert(256 <= r && r < 512);
87
+ return r;
88
}
89
90
-/* Common wrapper to call recip_estimate */
91
-static float64 call_recip_estimate(float64 num, int off, float_status *fpst)
92
-{
93
- uint64_t val64 = float64_val(num);
94
- uint64_t frac = extract64(val64, 0, 52);
95
- int64_t exp = extract64(val64, 52, 11);
96
- uint64_t sbit;
97
- float64 scaled, estimate;
98
+/*
99
+ * Common wrapper to call recip_estimate
100
+ *
101
+ * The parameters are exponent and 64 bit fraction (without implicit
102
+ * bit) where the binary point is nominally at bit 52. Returns a
103
+ * float64 which can then be rounded to the appropriate size by the
104
+ * callee.
105
+ */
106
107
- /* Generate the scaled number for the estimate function */
108
- if (exp == 0) {
109
+static uint64_t call_recip_estimate(int *exp, int exp_off, uint64_t frac)
110
+{
111
+ uint32_t scaled, estimate;
112
+ uint64_t result_frac;
113
+ int result_exp;
114
+
115
+ /* Handle sub-normals */
116
+ if (*exp == 0) {
117
if (extract64(frac, 51, 1) == 0) {
118
- exp = -1;
119
- frac = extract64(frac, 0, 50) << 2;
120
+ *exp = -1;
121
+ frac <<= 2;
122
} else {
123
- frac = extract64(frac, 0, 51) << 1;
124
+ frac <<= 1;
125
}
126
}
55
}
127
56
128
- /* scaled = '0' : '01111111110' : fraction<51:44> : Zeros(44); */
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
129
- scaled = make_float64((0x3feULL << 52)
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
130
- | extract64(frac, 44, 8) << 44);
59
131
+ /* scaled = UInt('1':fraction<51:44>) */
60
/* Perform gross MTE suppression early. */
132
+ scaled = deposit32(1 << 8, 0, 8, extract64(frac, 44, 8));
61
- if (!tbi_check(desc, bit55) ||
133
+ estimate = recip_estimate(scaled);
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
134
63
+ if (!tbi_check(mtedesc, bit55) ||
135
- estimate = recip_estimate(scaled, fpst);
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
136
-
65
mtedesc = 0;
137
- /* Build new result */
138
- val64 = float64_val(estimate);
139
- sbit = 0x8000000000000000ULL & val64;
140
- exp = off - exp;
141
- frac = extract64(val64, 0, 52);
142
-
143
- if (exp == 0) {
144
- frac = 1ULL << 51 | extract64(frac, 1, 51);
145
- } else if (exp == -1) {
146
- frac = 1ULL << 50 | extract64(frac, 2, 50);
147
- exp = 0;
148
+ result_exp = exp_off - *exp;
149
+ result_frac = deposit64(0, 44, 8, estimate);
150
+ if (result_exp == 0) {
151
+ result_frac = deposit64(result_frac >> 1, 51, 1, 1);
152
+ } else if (result_exp == -1) {
153
+ result_frac = deposit64(result_frac >> 2, 50, 2, 1);
154
+ result_exp = 0;
155
}
66
}
156
67
157
- return make_float64(sbit | (exp << 52) | frac);
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
158
+ *exp = result_exp;
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
159
+
70
160
+ return result_frac;
71
/* Perform gross MTE suppression early. */
161
}
72
- if (!tbi_check(desc, bit55) ||
162
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
163
static bool round_to_inf(float_status *fpst, bool sign_bit)
74
+ if (!tbi_check(mtedesc, bit55) ||
164
@@ -XXX,XX +XXX,XX @@ static bool round_to_inf(float_status *fpst, bool sign_bit)
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
165
g_assert_not_reached();
76
mtedesc = 0;
166
}
167
168
+float16 HELPER(recpe_f16)(float16 input, void *fpstp)
169
+{
170
+ float_status *fpst = fpstp;
171
+ float16 f16 = float16_squash_input_denormal(input, fpst);
172
+ uint32_t f16_val = float16_val(f16);
173
+ uint32_t f16_sign = float16_is_neg(f16);
174
+ int f16_exp = extract32(f16_val, 10, 5);
175
+ uint32_t f16_frac = extract32(f16_val, 0, 10);
176
+ uint64_t f64_frac;
177
+
178
+ if (float16_is_any_nan(f16)) {
179
+ float16 nan = f16;
180
+ if (float16_is_signaling_nan(f16, fpst)) {
181
+ float_raise(float_flag_invalid, fpst);
182
+ nan = float16_maybe_silence_nan(f16, fpst);
183
+ }
184
+ if (fpst->default_nan_mode) {
185
+ nan = float16_default_nan(fpst);
186
+ }
187
+ return nan;
188
+ } else if (float16_is_infinity(f16)) {
189
+ return float16_set_sign(float16_zero, float16_is_neg(f16));
190
+ } else if (float16_is_zero(f16)) {
191
+ float_raise(float_flag_divbyzero, fpst);
192
+ return float16_set_sign(float16_infinity, float16_is_neg(f16));
193
+ } else if (float16_abs(f16) < (1 << 8)) {
194
+ /* Abs(value) < 2.0^-16 */
195
+ float_raise(float_flag_overflow | float_flag_inexact, fpst);
196
+ if (round_to_inf(fpst, f16_sign)) {
197
+ return float16_set_sign(float16_infinity, f16_sign);
198
+ } else {
199
+ return float16_set_sign(float16_maxnorm, f16_sign);
200
+ }
201
+ } else if (f16_exp >= 29 && fpst->flush_to_zero) {
202
+ float_raise(float_flag_underflow, fpst);
203
+ return float16_set_sign(float16_zero, float16_is_neg(f16));
204
+ }
205
+
206
+ f64_frac = call_recip_estimate(&f16_exp, 29,
207
+ ((uint64_t) f16_frac) << (52 - 10));
208
+
209
+ /* result = sign : result_exp<4:0> : fraction<51:42> */
210
+ f16_val = deposit32(0, 15, 1, f16_sign);
211
+ f16_val = deposit32(f16_val, 10, 5, f16_exp);
212
+ f16_val = deposit32(f16_val, 0, 10, extract64(f64_frac, 52 - 10, 10));
213
+ return make_float16(f16_val);
214
+}
215
+
216
float32 HELPER(recpe_f32)(float32 input, void *fpstp)
217
{
218
float_status *fpst = fpstp;
219
float32 f32 = float32_squash_input_denormal(input, fpst);
220
uint32_t f32_val = float32_val(f32);
221
- uint32_t f32_sbit = 0x80000000ULL & f32_val;
222
- int32_t f32_exp = extract32(f32_val, 23, 8);
223
+ bool f32_sign = float32_is_neg(f32);
224
+ int f32_exp = extract32(f32_val, 23, 8);
225
uint32_t f32_frac = extract32(f32_val, 0, 23);
226
- float64 f64, r64;
227
- uint64_t r64_val;
228
- int64_t r64_exp;
229
- uint64_t r64_frac;
230
+ uint64_t f64_frac;
231
232
if (float32_is_any_nan(f32)) {
233
float32 nan = f32;
234
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
235
} else if (float32_is_zero(f32)) {
236
float_raise(float_flag_divbyzero, fpst);
237
return float32_set_sign(float32_infinity, float32_is_neg(f32));
238
- } else if ((f32_val & ~(1ULL << 31)) < (1ULL << 21)) {
239
+ } else if (float32_abs(f32) < (1ULL << 21)) {
240
/* Abs(value) < 2.0^-128 */
241
float_raise(float_flag_overflow | float_flag_inexact, fpst);
242
- if (round_to_inf(fpst, f32_sbit)) {
243
- return float32_set_sign(float32_infinity, float32_is_neg(f32));
244
+ if (round_to_inf(fpst, f32_sign)) {
245
+ return float32_set_sign(float32_infinity, f32_sign);
246
} else {
247
- return float32_set_sign(float32_maxnorm, float32_is_neg(f32));
248
+ return float32_set_sign(float32_maxnorm, f32_sign);
249
}
250
} else if (f32_exp >= 253 && fpst->flush_to_zero) {
251
float_raise(float_flag_underflow, fpst);
252
return float32_set_sign(float32_zero, float32_is_neg(f32));
253
}
77
}
254
78
255
+ f64_frac = call_recip_estimate(&f32_exp, 253,
256
+ ((uint64_t) f32_frac) << (52 - 23));
257
258
- f64 = make_float64(((int64_t)(f32_exp) << 52) | (int64_t)(f32_frac) << 29);
259
- r64 = call_recip_estimate(f64, 253, fpst);
260
- r64_val = float64_val(r64);
261
- r64_exp = extract64(r64_val, 52, 11);
262
- r64_frac = extract64(r64_val, 0, 52);
263
-
264
- /* result = sign : result_exp<7:0> : fraction<51:29>; */
265
- return make_float32(f32_sbit |
266
- (r64_exp & 0xff) << 23 |
267
- extract64(r64_frac, 29, 24));
268
+ /* result = sign : result_exp<7:0> : fraction<51:29> */
269
+ f32_val = deposit32(0, 31, 1, f32_sign);
270
+ f32_val = deposit32(f32_val, 23, 8, f32_exp);
271
+ f32_val = deposit32(f32_val, 0, 23, extract64(f64_frac, 52 - 23, 23));
272
+ return make_float32(f32_val);
273
}
274
275
float64 HELPER(recpe_f64)(float64 input, void *fpstp)
276
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
277
float_status *fpst = fpstp;
278
float64 f64 = float64_squash_input_denormal(input, fpst);
279
uint64_t f64_val = float64_val(f64);
280
- uint64_t f64_sbit = 0x8000000000000000ULL & f64_val;
281
- int64_t f64_exp = extract64(f64_val, 52, 11);
282
- float64 r64;
283
- uint64_t r64_val;
284
- int64_t r64_exp;
285
- uint64_t r64_frac;
286
+ bool f64_sign = float64_is_neg(f64);
287
+ int f64_exp = extract64(f64_val, 52, 11);
288
+ uint64_t f64_frac = extract64(f64_val, 0, 52);
289
290
/* Deal with any special cases */
291
if (float64_is_any_nan(f64)) {
292
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
293
} else if ((f64_val & ~(1ULL << 63)) < (1ULL << 50)) {
294
/* Abs(value) < 2.0^-1024 */
295
float_raise(float_flag_overflow | float_flag_inexact, fpst);
296
- if (round_to_inf(fpst, f64_sbit)) {
297
- return float64_set_sign(float64_infinity, float64_is_neg(f64));
298
+ if (round_to_inf(fpst, f64_sign)) {
299
+ return float64_set_sign(float64_infinity, f64_sign);
300
} else {
301
- return float64_set_sign(float64_maxnorm, float64_is_neg(f64));
302
+ return float64_set_sign(float64_maxnorm, f64_sign);
303
}
304
} else if (f64_exp >= 2045 && fpst->flush_to_zero) {
305
float_raise(float_flag_underflow, fpst);
306
return float64_set_sign(float64_zero, float64_is_neg(f64));
307
}
308
309
- r64 = call_recip_estimate(f64, 2045, fpst);
310
- r64_val = float64_val(r64);
311
- r64_exp = extract64(r64_val, 52, 11);
312
- r64_frac = extract64(r64_val, 0, 52);
313
+ f64_frac = call_recip_estimate(&f64_exp, 2045, f64_frac);
314
315
- /* result = sign : result_exp<10:0> : fraction<51:0> */
316
- return make_float64(f64_sbit |
317
- ((r64_exp & 0x7ff) << 52) |
318
- r64_frac);
319
+ /* result = sign : result_exp<10:0> : fraction<51:0>; */
320
+ f64_val = deposit64(0, 63, 1, f64_sign);
321
+ f64_val = deposit64(f64_val, 52, 11, f64_exp);
322
+ f64_val = deposit64(f64_val, 0, 52, f64_frac);
323
+ return make_float64(f64_val);
324
}
325
326
/* The algorithm that must be used to calculate the estimate
327
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
328
329
uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
330
{
331
- float_status *s = fpstp;
332
- float64 f64;
333
+ /* float_status *s = fpstp; */
334
+ int input, estimate;
335
336
if ((a & 0x80000000) == 0) {
337
return 0xffffffff;
338
}
339
340
- f64 = make_float64((0x3feULL << 52)
341
- | ((int64_t)(a & 0x7fffffff) << 21));
342
+ input = extract32(a, 23, 9);
343
+ estimate = recip_estimate(input);
344
345
- f64 = recip_estimate(f64, s);
346
-
347
- return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
348
+ return deposit32(0, (32 - 9), 9, estimate);
349
}
350
351
uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp)
352
--
79
--
353
2.16.2
80
2.34.1
354
355
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The raven_io_ops MemoryRegionOps is the only one in the source tree
2
which sets .valid.unaligned to indicate that it should support
3
unaligned accesses and which does not also set .impl.unaligned to
4
indicate that its read and write functions can do the unaligned
5
handling themselves. This is a problem, because at the moment the
6
core memory system does not implement the support for handling
7
unaligned accesses by doing a series of aligned accesses and
8
combining them (system/memory.c:access_with_adjusted_size() has a
9
TODO comment noting this).
2
10
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
with the case of being passed an unaligned address, so we can fix the
5
Message-id: 20180227143852.11175-3-alex.bennee@linaro.org
13
missing unaligned access support by setting .impl.unaligned in the
6
[PMM: postpone actually enabling feature until end of the
14
MemoryRegionOps struct.
7
patch series]
15
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Tested-by: Cédric Le Goater <clg@redhat.com>
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
9
---
21
---
10
target/arm/cpu.h | 1 +
22
hw/pci-host/raven.c | 1 +
11
1 file changed, 1 insertion(+)
23
1 file changed, 1 insertion(+)
12
24
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
14
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
27
--- a/hw/pci-host/raven.c
16
+++ b/target/arm/cpu.h
28
+++ b/hw/pci-host/raven.c
17
@@ -XXX,XX +XXX,XX @@ enum arm_features {
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
18
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
30
.write = raven_io_write,
19
ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
31
.endianness = DEVICE_LITTLE_ENDIAN,
20
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
32
.impl.max_access_size = 4,
21
+ ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
33
+ .impl.unaligned = true,
34
.valid.unaligned = true,
22
};
35
};
23
36
24
static inline int arm_feature(CPUARMState *env, int feature)
25
--
37
--
26
2.16.2
38
2.34.1
27
39
28
40
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Suppress the deprecation warning when we're running under qtest,
2
to avoid "make check" including warning messages in its output.
2
3
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180227143852.11175-28-alex.bennee@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
7
---
7
---
8
target/arm/translate-a64.c | 7 +++++++
8
hw/block/tc58128.c | 4 +++-
9
1 file changed, 7 insertions(+)
9
1 file changed, 3 insertions(+), 1 deletion(-)
10
10
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
13
--- a/hw/block/tc58128.c
14
+++ b/target/arm/translate-a64.c
14
+++ b/hw/block/tc58128.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
16
case 0x6f: /* FNEG */
16
17
need_fpst = false;
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
18
break;
18
{
19
+ case 0x7d: /* FRSQRTE */
19
- warn_report_once("The TC58128 flash device is deprecated");
20
case 0x7f: /* FSQRT (vector) */
20
+ if (!qtest_enabled()) {
21
break;
21
+ warn_report_once("The TC58128 flash device is deprecated");
22
default:
22
+ }
23
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
23
init_dev(&tc58128_devs[0], zone1);
24
case 0x6f: /* FNEG */
24
init_dev(&tc58128_devs[1], zone2);
25
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
25
return sh7750_register_io_device(s, &tc58128);
26
break;
27
+ case 0x7d: /* FRSQRTE */
28
+ gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus);
29
+ break;
30
default:
31
g_assert_not_reached();
32
}
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
34
case 0x6f: /* FNEG */
35
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
36
break;
37
+ case 0x7d: /* FRSQRTE */
38
+ gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus);
39
+ break;
40
case 0x7f: /* FSQRT */
41
gen_helper_sqrt_f16(tcg_res, tcg_op, tcg_fpstatus);
42
break;
43
--
26
--
44
2.16.2
27
2.34.1
45
28
46
29
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
We deliberately don't include qtests_npcm7xx in qtests_aarch64,
2
because we already get the coverage of those tests via qtests_arm,
3
and we don't want to use extra CI minutes testing them twice.
2
4
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
that change.
5
Message-id: 20180227143852.11175-26-alex.bennee@linaro.org
7
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
7
---
12
---
8
target/arm/helper-a64.h | 1 +
13
tests/qtest/meson.build | 1 -
9
target/arm/helper-a64.c | 13 +++++++++++++
14
1 file changed, 1 deletion(-)
10
target/arm/translate-a64.c | 5 +++++
11
3 files changed, 19 insertions(+)
12
15
13
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-a64.h
18
--- a/tests/qtest/meson.build
16
+++ b/target/arm/helper-a64.h
19
+++ b/tests/qtest/meson.build
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr)
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
18
DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
19
DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
22
(config_all_accel.has_key('CONFIG_TCG') and \
20
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
21
+DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
22
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
25
['arm-cpu-features',
23
index XXXXXXX..XXXXXXX 100644
26
'numa-test',
24
--- a/target/arm/helper-a64.c
27
'boot-serial-test',
25
+++ b/target/arm/helper-a64.c
26
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
27
}
28
return float16_to_uint16(a, fpst);
29
}
30
+
31
+/*
32
+ * Square Root and Reciprocal square root
33
+ */
34
+
35
+float16 HELPER(sqrt_f16)(float16 a, void *fpstp)
36
+{
37
+ float_status *s = fpstp;
38
+
39
+ return float16_sqrt(a, s);
40
+}
41
+
42
+
43
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/translate-a64.c
46
+++ b/target/arm/translate-a64.c
47
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
48
case 0x6f: /* FNEG */
49
need_fpst = false;
50
break;
51
+ case 0x7f: /* FSQRT (vector) */
52
+ break;
53
default:
54
fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
55
g_assert_not_reached();
56
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
57
case 0x6f: /* FNEG */
58
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
59
break;
60
+ case 0x7f: /* FSQRT */
61
+ gen_helper_sqrt_f16(tcg_res, tcg_op, tcg_fpstatus);
62
+ break;
63
default:
64
g_assert_not_reached();
65
}
66
--
28
--
67
2.16.2
29
2.34.1
68
30
69
31
diff view generated by jsdifflib
1
Set the appropriate Linux hwcap bits to tell the guest binary if we
1
Allow changes to the virt GTDT -- we are going to add the IRQ
2
have implemented half-precision floating point support.
2
entry for a new timer to it.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
6
Message-id: 20240122143537.233498-2-peter.maydell@linaro.org
6
---
7
---
7
linux-user/elfload.c | 2 ++
8
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
8
1 file changed, 2 insertions(+)
9
1 file changed, 2 insertions(+)
9
10
10
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
11
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/linux-user/elfload.c
13
--- a/tests/qtest/bios-tables-test-allowed-diff.h
13
+++ b/linux-user/elfload.c
14
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
14
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
15
@@ -1 +1,3 @@
15
GET_FEATURE(ARM_FEATURE_V8_SM3, ARM_HWCAP_A64_SM3);
16
/* List of comma-separated changed AML files to ignore */
16
GET_FEATURE(ARM_FEATURE_V8_SM4, ARM_HWCAP_A64_SM4);
17
+"tests/data/acpi/virt/FACP",
17
GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
18
+"tests/data/acpi/virt/GTDT",
18
+ GET_FEATURE(ARM_FEATURE_V8_FP16,
19
+ ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
20
#undef GET_FEATURE
21
22
return hwcaps;
23
--
19
--
24
2.16.2
20
2.34.1
25
26
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
2
2
non-secure EL2 virtual timer. We implemented the timer itself in the
3
Ensure that the post write hook is called during reset. This allows us
3
CPU model, but never wired up its IRQ line to the GIC.
4
to rely on the post write functions instead of having to call them from
4
5
the reset() function.
5
Wire up the IRQ line (this is always safe whether the CPU has the
6
6
interrupt or not, since it always creates the outbound IRQ line).
7
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
9
Message-id: d131e24b911653a945e46ca2d8f90f572469e1dd.1517856214.git.alistair.francis@xilinx.com
9
The DTB binding is documented in the kernel's
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
and the ACPI table entries are documented in the ACPI specification
12
version 6.3 or later.
13
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
FADT table rev to show that we might be using 6.3 features.
16
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
versions prior to edk2-stable202311, for users who use the virt board
19
with 'virtualization=on' to enable EL2 emulation and are booting an
20
EDK2 guest BIOS, if that EDK2 has assertions enabled. The effect is
21
that EDK2 will assert on bootup:
22
23
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
24
25
If you see that assertion you should do one of:
26
* update your EDK2 binaries to edk2-stable202311 or newer
27
* use the 'virt-8.2' versioned machine type
28
* not use 'virtualization=on'
29
30
(The versions shipped with QEMU itself have the fix.)
31
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
11
---
35
---
12
include/hw/register.h | 6 +++---
36
include/hw/arm/virt.h | 2 ++
13
hw/core/register.c | 8 ++++++++
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
14
2 files changed, 11 insertions(+), 3 deletions(-)
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
15
39
3 files changed, 67 insertions(+), 15 deletions(-)
16
diff --git a/include/hw/register.h b/include/hw/register.h
40
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
17
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/register.h
43
--- a/include/hw/arm/virt.h
19
+++ b/include/hw/register.h
44
+++ b/include/hw/arm/virt.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct RegisterInfoArray RegisterInfoArray;
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
21
* immediately before the actual write. The returned value is what is written,
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
22
* giving the handler a chance to modify the written value.
47
bool no_cpu_topology;
23
* @post_write: Post write callback. Passed the written value. Most write side
48
bool no_tcg_lpa2;
24
- * effects should be implemented here.
49
+ bool no_ns_el2_virt_timer_irq;
25
+ * effects should be implemented here. This is called during device reset.
50
};
26
*
51
27
* @post_read: Post read callback. Passes the value that is about to be returned
52
struct VirtMachineState {
28
* for a read. The return value from this function is what is ultimately read,
53
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
29
@@ -XXX,XX +XXX,XX @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
54
PCIBus *bus;
30
bool debug);
55
char *oem_id;
31
56
char *oem_table_id;
32
/**
57
+ bool ns_el2_virt_timer_irq;
33
- * reset a register
58
};
34
- * @reg: register to reset
59
35
+ * Resets a register. This will also call the post_write hook if it exists.
60
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
36
+ * @reg: The register to reset.
61
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/virt-acpi-build.c
64
+++ b/hw/arm/virt-acpi-build.c
65
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
}
67
68
/*
69
- * ACPI spec, Revision 5.1
70
- * 5.2.24 Generic Timer Description Table (GTDT)
71
+ * ACPI spec, Revision 6.5
72
+ * 5.2.25 Generic Timer Description Table (GTDT)
37
*/
73
*/
38
74
static void
39
void register_reset(RegisterInfo *reg);
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
40
diff --git a/hw/core/register.c b/hw/core/register.c
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
78
1 : /* Interrupt is Edge triggered */
79
0; /* Interrupt is Level triggered */
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
82
.oem_table_id = vms->oem_table_id };
83
84
acpi_table_begin(&table, table_data);
85
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
86
build_append_int_noprefix(table_data, 0, 4);
87
/* Platform Timer Offset */
88
build_append_int_noprefix(table_data, 0, 4);
89
-
90
+ if (vms->ns_el2_virt_timer_irq) {
91
+ /* Virtual EL2 Timer GSIV */
92
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
93
+ /* Virtual EL2 Timer Flags */
94
+ build_append_int_noprefix(table_data, irqflags, 4);
95
+ } else {
96
+ build_append_int_noprefix(table_data, 0, 4);
97
+ build_append_int_noprefix(table_data, 0, 4);
98
+ }
99
acpi_table_end(linker, &table);
100
}
101
102
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
103
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
104
VirtMachineState *vms, unsigned dsdt_tbl_offset)
105
{
106
- /* ACPI v6.0 */
107
+ /* ACPI v6.3 */
108
AcpiFadtData fadt = {
109
.rev = 6,
110
- .minor_ver = 0,
111
+ .minor_ver = 3,
112
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
113
.xdsdt_tbl_offset = &dsdt_tbl_offset,
114
};
115
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
41
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/core/register.c
117
--- a/hw/arm/virt.c
43
+++ b/hw/core/register.c
118
+++ b/hw/arm/virt.c
44
@@ -XXX,XX +XXX,XX @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
45
120
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
46
void register_reset(RegisterInfo *reg)
121
}
122
123
+/*
124
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
125
+ * but we don't want to advertise it to the guest in the dtb or ACPI
126
+ * table unless it's really going to do something.
127
+ */
128
+static bool ns_el2_virt_timer_present(void)
129
+{
130
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
131
+ CPUARMState *env = &cpu->env;
132
+
133
+ return arm_feature(env, ARM_FEATURE_AARCH64) &&
134
+ arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
135
+}
136
+
137
static void create_fdt(VirtMachineState *vms)
47
{
138
{
48
+ const RegisterAccessInfo *ac;
139
MachineState *ms = MACHINE(vms);
49
+
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
50
g_assert(reg);
141
"arm,armv7-timer");
51
52
if (!reg->data || !reg->access) {
53
return;
54
}
142
}
55
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
56
+ ac = reg->access;
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
57
+
145
- GIC_FDT_IRQ_TYPE_PPI,
58
register_write_val(reg, reg->access->reset);
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
59
+
147
- GIC_FDT_IRQ_TYPE_PPI,
60
+ if (ac->post_write) {
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
61
+ ac->post_write(reg, reg->access->reset);
149
- GIC_FDT_IRQ_TYPE_PPI,
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
151
- GIC_FDT_IRQ_TYPE_PPI,
152
- INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
153
+ if (vms->ns_el2_virt_timer_irq) {
154
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
155
+ GIC_FDT_IRQ_TYPE_PPI,
156
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
157
+ GIC_FDT_IRQ_TYPE_PPI,
158
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
159
+ GIC_FDT_IRQ_TYPE_PPI,
160
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
161
+ GIC_FDT_IRQ_TYPE_PPI,
162
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
163
+ GIC_FDT_IRQ_TYPE_PPI,
164
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
165
+ } else {
166
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
167
+ GIC_FDT_IRQ_TYPE_PPI,
168
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
169
+ GIC_FDT_IRQ_TYPE_PPI,
170
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
171
+ GIC_FDT_IRQ_TYPE_PPI,
172
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
173
+ GIC_FDT_IRQ_TYPE_PPI,
174
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
62
+ }
175
+ }
63
}
176
}
64
177
65
void register_init(RegisterInfo *reg)
178
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
180
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
181
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
182
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
183
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
184
};
185
186
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
187
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
188
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
189
object_unref(cpuobj);
190
}
191
+
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
194
+ !vmc->no_ns_el2_virt_timer_irq;
195
+
196
fdt_add_timer_nodes(vms);
197
fdt_add_cpu_nodes(vms);
198
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
200
201
static void virt_machine_8_2_options(MachineClass *mc)
202
{
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
204
+
205
virt_machine_9_0_options(mc);
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
207
+ /*
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
210
+ * guest BIOS binaries.)
211
+ */
212
+ vmc->no_ns_el2_virt_timer_irq = true;
213
}
214
DEFINE_VIRT_MACHINE(8, 2)
215
66
--
216
--
67
2.16.2
217
2.34.1
68
69
diff view generated by jsdifflib
Deleted patch
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
1
3
Assert only the lower cs on bus 0 and upper cs on bus 1 when both buses and
4
chip selects are enabled (e.g reading/writing with stripe).
5
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
8
Tested-by: Alistair Francis <alistair.francis@xilinx.com>
9
Message-id: 20180223232233.31482-2-frasse.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/ssi/xilinx_spips.c | 41 +++++++++++++++++++++++++++++++++++++----
13
1 file changed, 37 insertions(+), 4 deletions(-)
14
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
+++ b/hw/ssi/xilinx_spips.c
19
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs(XilinxSPIPS *s, int field)
20
{
21
int i;
22
23
- for (i = 0; i < s->num_cs; i++) {
24
+ for (i = 0; i < s->num_cs * s->num_busses; i++) {
25
bool old_state = s->cs_lines_state[i];
26
bool new_state = field & (1 << i);
27
28
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs(XilinxSPIPS *s, int field)
29
}
30
qemu_set_irq(s->cs_lines[i], !new_state);
31
}
32
- if (!(field & ((1 << s->num_cs) - 1))) {
33
+ if (!(field & ((1 << (s->num_cs * s->num_busses)) - 1))) {
34
s->snoop_state = SNOOP_CHECKING;
35
s->cmd_dummies = 0;
36
s->link_state = 1;
37
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_update_cs_lines(XlnxZynqMPQSPIPS *s)
38
{
39
if (s->regs[R_GQSPI_GF_SNAPSHOT]) {
40
int field = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, CHIP_SELECT);
41
- xilinx_spips_update_cs(XILINX_SPIPS(s), field);
42
+ bool upper_cs_sel = field & (1 << 1);
43
+ bool lower_cs_sel = field & 1;
44
+ bool bus0_enabled;
45
+ bool bus1_enabled;
46
+ uint8_t buses;
47
+ int cs = 0;
48
+
49
+ buses = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT);
50
+ bus0_enabled = buses & 1;
51
+ bus1_enabled = buses & (1 << 1);
52
+
53
+ if (bus0_enabled && bus1_enabled) {
54
+ if (lower_cs_sel) {
55
+ cs |= 1;
56
+ }
57
+ if (upper_cs_sel) {
58
+ cs |= 1 << 3;
59
+ }
60
+ } else if (bus0_enabled) {
61
+ if (lower_cs_sel) {
62
+ cs |= 1;
63
+ }
64
+ if (upper_cs_sel) {
65
+ cs |= 1 << 1;
66
+ }
67
+ } else if (bus1_enabled) {
68
+ if (lower_cs_sel) {
69
+ cs |= 1 << 2;
70
+ }
71
+ if (upper_cs_sel) {
72
+ cs |= 1 << 3;
73
+ }
74
+ }
75
+ xilinx_spips_update_cs(XILINX_SPIPS(s), cs);
76
}
77
}
78
79
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
80
if (num_effective_busses(s) == 2) {
81
/* Single bit chip-select for qspi */
82
field &= 0x1;
83
- field |= field << 1;
84
+ field |= field << 3;
85
/* Dual stack U-Page */
86
} else if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM &&
87
s->regs[R_LQSPI_STS] & LQSPI_CFG_U_PAGE) {
88
--
89
2.16.2
90
91
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Update the virt golden reference files to say that the FACP is ACPI
2
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
Now we have added f16 during the re-factoring we can simply call the
3
virtual EL2 timer.
4
helper.
4
5
5
Diffs from iasl:
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
@@ -XXX,XX +XXX,XX @@
8
Message-id: 20180227143852.11175-24-alex.bennee@linaro.org
8
/*
9
* Intel ACPI Component Architecture
10
* AML/ASL+ Disassembler version 20200925 (64-bit version)
11
* Copyright (c) 2000 - 2020 Intel Corporation
12
*
13
- * Disassembly of tests/data/acpi/virt/FACP, Mon Jan 22 13:48:40 2024
14
+ * Disassembly of /tmp/aml-W8RZH2, Mon Jan 22 13:48:40 2024
15
*
16
* ACPI Data Table [FACP]
17
*
18
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
19
*/
20
21
[000h 0000 4] Signature : "FACP" [Fixed ACPI Description Table (FADT)]
22
[004h 0004 4] Table Length : 00000114
23
[008h 0008 1] Revision : 06
24
-[009h 0009 1] Checksum : 15
25
+[009h 0009 1] Checksum : 12
26
[00Ah 0010 6] Oem ID : "BOCHS "
27
[010h 0016 8] Oem Table ID : "BXPC "
28
[018h 0024 4] Oem Revision : 00000001
29
[01Ch 0028 4] Asl Compiler ID : "BXPC"
30
[020h 0032 4] Asl Compiler Revision : 00000001
31
32
[024h 0036 4] FACS Address : 00000000
33
[028h 0040 4] DSDT Address : 00000000
34
[02Ch 0044 1] Model : 00
35
[02Dh 0045 1] PM Profile : 00 [Unspecified]
36
[02Eh 0046 2] SCI Interrupt : 0000
37
[030h 0048 4] SMI Command Port : 00000000
38
[034h 0052 1] ACPI Enable Value : 00
39
[035h 0053 1] ACPI Disable Value : 00
40
[036h 0054 1] S4BIOS Command : 00
41
[037h 0055 1] P-State Control : 00
42
@@ -XXX,XX +XXX,XX @@
43
Use APIC Physical Destination Mode (V4) : 0
44
Hardware Reduced (V5) : 1
45
Low Power S0 Idle (V5) : 0
46
47
[074h 0116 12] Reset Register : [Generic Address Structure]
48
[074h 0116 1] Space ID : 00 [SystemMemory]
49
[075h 0117 1] Bit Width : 00
50
[076h 0118 1] Bit Offset : 00
51
[077h 0119 1] Encoded Access Width : 00 [Undefined/Legacy]
52
[078h 0120 8] Address : 0000000000000000
53
54
[080h 0128 1] Value to cause reset : 00
55
[081h 0129 2] ARM Flags (decoded below) : 0003
56
PSCI Compliant : 1
57
Must use HVC for PSCI : 1
58
59
-[083h 0131 1] FADT Minor Revision : 00
60
+[083h 0131 1] FADT Minor Revision : 03
61
[084h 0132 8] FACS Address : 0000000000000000
62
[08Ch 0140 8] DSDT Address : 0000000000000000
63
[094h 0148 12] PM1A Event Block : [Generic Address Structure]
64
[094h 0148 1] Space ID : 00 [SystemMemory]
65
[095h 0149 1] Bit Width : 00
66
[096h 0150 1] Bit Offset : 00
67
[097h 0151 1] Encoded Access Width : 00 [Undefined/Legacy]
68
[098h 0152 8] Address : 0000000000000000
69
70
[0A0h 0160 12] PM1B Event Block : [Generic Address Structure]
71
[0A0h 0160 1] Space ID : 00 [SystemMemory]
72
[0A1h 0161 1] Bit Width : 00
73
[0A2h 0162 1] Bit Offset : 00
74
[0A3h 0163 1] Encoded Access Width : 00 [Undefined/Legacy]
75
[0A4h 0164 8] Address : 0000000000000000
76
77
@@ -XXX,XX +XXX,XX @@
78
[0F5h 0245 1] Bit Width : 00
79
[0F6h 0246 1] Bit Offset : 00
80
[0F7h 0247 1] Encoded Access Width : 00 [Undefined/Legacy]
81
[0F8h 0248 8] Address : 0000000000000000
82
83
[100h 0256 12] Sleep Status Register : [Generic Address Structure]
84
[100h 0256 1] Space ID : 00 [SystemMemory]
85
[101h 0257 1] Bit Width : 00
86
[102h 0258 1] Bit Offset : 00
87
[103h 0259 1] Encoded Access Width : 00 [Undefined/Legacy]
88
[104h 0260 8] Address : 0000000000000000
89
90
[10Ch 0268 8] Hypervisor ID : 00000000554D4551
91
92
Raw Table Data: Length 276 (0x114)
93
94
- 0000: 46 41 43 50 14 01 00 00 06 15 42 4F 43 48 53 20 // FACP......BOCHS
95
+ 0000: 46 41 43 50 14 01 00 00 06 12 42 4F 43 48 53 20 // FACP......BOCHS
96
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
97
0020: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
98
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
99
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
100
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
101
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
102
0070: 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
103
- 0080: 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
104
+ 0080: 00 03 00 03 00 00 00 00 00 00 00 00 00 00 00 00 // ................
105
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
106
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
107
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
108
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
109
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
110
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
111
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
112
0100: 00 00 00 00 00 00 00 00 00 00 00 00 51 45 4D 55 // ............QEMU
113
0110: 00 00 00 00 // ....
114
115
@@ -XXX,XX +XXX,XX @@
116
/*
117
* Intel ACPI Component Architecture
118
* AML/ASL+ Disassembler version 20200925 (64-bit version)
119
* Copyright (c) 2000 - 2020 Intel Corporation
120
*
121
- * Disassembly of tests/data/acpi/virt/GTDT, Mon Jan 22 13:48:40 2024
122
+ * Disassembly of /tmp/aml-XDSZH2, Mon Jan 22 13:48:40 2024
123
*
124
* ACPI Data Table [GTDT]
125
*
126
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
127
*/
128
129
[000h 0000 4] Signature : "GTDT" [Generic Timer Description Table]
130
-[004h 0004 4] Table Length : 00000060
131
-[008h 0008 1] Revision : 02
132
-[009h 0009 1] Checksum : 9C
133
+[004h 0004 4] Table Length : 00000068
134
+[008h 0008 1] Revision : 03
135
+[009h 0009 1] Checksum : 93
136
[00Ah 0010 6] Oem ID : "BOCHS "
137
[010h 0016 8] Oem Table ID : "BXPC "
138
[018h 0024 4] Oem Revision : 00000001
139
[01Ch 0028 4] Asl Compiler ID : "BXPC"
140
[020h 0032 4] Asl Compiler Revision : 00000001
141
142
[024h 0036 8] Counter Block Address : FFFFFFFFFFFFFFFF
143
[02Ch 0044 4] Reserved : 00000000
144
145
[030h 0048 4] Secure EL1 Interrupt : 0000001D
146
[034h 0052 4] EL1 Flags (decoded below) : 00000000
147
Trigger Mode : 0
148
Polarity : 0
149
Always On : 0
150
151
[038h 0056 4] Non-Secure EL1 Interrupt : 0000001E
152
@@ -XXX,XX +XXX,XX @@
153
154
[040h 0064 4] Virtual Timer Interrupt : 0000001B
155
[044h 0068 4] VT Flags (decoded below) : 00000000
156
Trigger Mode : 0
157
Polarity : 0
158
Always On : 0
159
160
[048h 0072 4] Non-Secure EL2 Interrupt : 0000001A
161
[04Ch 0076 4] NEL2 Flags (decoded below) : 00000000
162
Trigger Mode : 0
163
Polarity : 0
164
Always On : 0
165
[050h 0080 8] Counter Read Block Address : FFFFFFFFFFFFFFFF
166
167
[058h 0088 4] Platform Timer Count : 00000000
168
[05Ch 0092 4] Platform Timer Offset : 00000000
169
+[060h 0096 4] Virtual EL2 Timer GSIV : 00000000
170
+[064h 0100 4] Virtual EL2 Timer Flags : 00000000
171
172
-Raw Table Data: Length 96 (0x60)
173
+Raw Table Data: Length 104 (0x68)
174
175
- 0000: 47 54 44 54 60 00 00 00 02 9C 42 4F 43 48 53 20 // GTDT`.....BOCHS
176
+ 0000: 47 54 44 54 68 00 00 00 03 93 42 4F 43 48 53 20 // GTDTh.....BOCHS
177
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
178
0020: 01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 // ................
179
0030: 1D 00 00 00 00 00 00 00 1E 00 00 00 04 00 00 00 // ................
180
0040: 1B 00 00 00 00 00 00 00 1A 00 00 00 00 00 00 00 // ................
181
0050: FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 // ................
182
+ 0060: 00 00 00 00 00 00 00 00 // ........
183
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
10
---
187
---
11
target/arm/translate-a64.c | 8 ++++++++
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
12
1 file changed, 8 insertions(+)
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
13
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
191
3 files changed, 2 deletions(-)
192
193
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
194
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
17
+++ b/target/arm/translate-a64.c
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
197
@@ -1,3 +1 @@
19
case 0x6d: /* FCMLE (zero) */
198
/* List of comma-separated changed AML files to ignore */
20
handle_2misc_fcmp_zero(s, fpop, is_scalar, 0, is_q, MO_16, rn, rd);
199
-"tests/data/acpi/virt/FACP",
21
return;
200
-"tests/data/acpi/virt/GTDT",
22
+ case 0x3d: /* FRECPE */
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
23
+ break;
202
index XXXXXXX..XXXXXXX 100644
24
case 0x18: /* FRINTN */
203
GIT binary patch
25
need_rmode = true;
204
delta 25
26
only_in_vector = true;
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
27
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
206
28
case 0x3b: /* FCVTZS */
207
delta 28
29
gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
30
break;
209
31
+ case 0x3d: /* FRECPE */
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
32
+ gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus);
211
index XXXXXXX..XXXXXXX 100644
33
+ break;
212
GIT binary patch
34
case 0x5a: /* FCVTNU */
213
delta 25
35
case 0x5b: /* FCVTMU */
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
36
case 0x5c: /* FCVTAU */
215
37
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
216
delta 16
38
case 0x3b: /* FCVTZS */
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
39
gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
218
40
break;
41
+ case 0x3d: /* FRECPE */
42
+ gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus);
43
+ break;
44
case 0x5a: /* FCVTNU */
45
case 0x5b: /* FCVTMU */
46
case 0x5c: /* FCVTAU */
47
--
219
--
48
2.16.2
220
2.34.1
49
50
diff view generated by jsdifflib
1
Now we have implemented FP16 we can enable it for the "any" CPU.
1
The patchset adding the GMAC ethernet to this SoC crossed in the
2
mail with the patchset cleaning up the NIC handling. When we
3
create the GMAC modules we must call qemu_configure_nic_device()
4
so that the user has the opportunity to use the -nic commandline
5
option to create a network backend and connect it to the GMACs.
2
6
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Add the missing call.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
5
[PMM: split out from an earlier patch in the series]
9
Fixes: 21e5326a7c ("hw/arm: Add GMAC devices to NPCM7XX SoC")
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
12
Message-id: 20240206171231.396392-2-peter.maydell@linaro.org
7
---
13
---
8
target/arm/cpu64.c | 1 +
14
hw/arm/npcm7xx.c | 1 +
9
1 file changed, 1 insertion(+)
15
1 file changed, 1 insertion(+)
10
16
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
17
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
19
--- a/hw/arm/npcm7xx.c
14
+++ b/target/arm/cpu64.c
20
+++ b/hw/arm/npcm7xx.c
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_any_initfn(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
16
set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
22
for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
17
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
23
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
18
set_feature(&cpu->env, ARM_FEATURE_CRC);
24
19
+ set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
25
+ qemu_configure_nic_device(DEVICE(sbd), false, NULL);
20
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
26
/*
21
cpu->dcz_blocksize = 7; /* 512 bytes */
27
* The device exists regardless of whether it's connected to a QEMU
22
}
28
* netdev backend. So always instantiate it even if there is no
23
--
29
--
24
2.16.2
30
2.34.1
25
26
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Currently QEMU will warn if there is a NIC on the board that
2
is not connected to a backend. By default the '-nic user' will
3
get used for all NICs, but if you manually connect a specific
4
NIC to a specific backend, then the other NICs on the board
5
have no backend and will be warned about:
2
6
3
Neither of these operations alter the floating point status registers
7
qemu-system-arm: warning: nic npcm7xx-emc.1 has no peer
4
so we can do a pure bitwise operation, either squashing any sign
8
qemu-system-arm: warning: nic npcm-gmac.0 has no peer
5
bit (ABS) or inverting it (NEG).
9
qemu-system-arm: warning: nic npcm-gmac.1 has no peer
6
10
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
11
So suppress those warnings by manually connecting every NIC
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
on the board to some backend.
9
Message-id: 20180227143852.11175-22-alex.bennee@linaro.org
13
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
11
---
18
---
12
target/arm/translate-a64.c | 16 +++++++++++++++-
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
13
1 file changed, 15 insertions(+), 1 deletion(-)
20
1 file changed, 4 insertions(+), 1 deletion(-)
14
21
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
24
--- a/tests/qtest/npcm7xx_emc-test.c
18
+++ b/target/arm/translate-a64.c
25
+++ b/tests/qtest/npcm7xx_emc-test.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
20
TCGv_i32 tcg_rmode = NULL;
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
21
TCGv_ptr tcg_fpstatus = NULL;
28
* in the 'model' field to specify the device to match.
22
bool need_rmode = false;
29
*/
23
+ bool need_fpst = true;
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
24
int rmode;
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
25
32
+ "-nic user,model=npcm7xx-emc "
26
if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
33
+ "-nic user,model=npcm-gmac "
27
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
34
+ "-nic user,model=npcm-gmac",
28
need_rmode = true;
35
test_sockets[1], module_num);
29
rmode = FPROUNDING_ZERO;
36
30
break;
37
g_test_queue_destroy(packet_test_clear, test_sockets);
31
+ case 0x2f: /* FABS */
32
+ case 0x6f: /* FNEG */
33
+ need_fpst = false;
34
+ break;
35
default:
36
fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
37
g_assert_not_reached();
38
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
39
return;
40
}
41
42
- if (need_rmode) {
43
+ if (need_rmode || need_fpst) {
44
tcg_fpstatus = get_fpstatus_ptr(true);
45
}
46
47
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
48
case 0x7b: /* FCVTZU */
49
gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus);
50
break;
51
+ case 0x6f: /* FNEG */
52
+ tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
53
+ break;
54
default:
55
g_assert_not_reached();
56
}
57
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
58
case 0x59: /* FRINTX */
59
gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, tcg_fpstatus);
60
break;
61
+ case 0x2f: /* FABS */
62
+ tcg_gen_andi_i32(tcg_res, tcg_op, 0x7fff);
63
+ break;
64
+ case 0x6f: /* FNEG */
65
+ tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
66
+ break;
67
default:
68
g_assert_not_reached();
69
}
70
--
38
--
71
2.16.2
39
2.34.1
72
73
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
CPU, and in fact if you try to do it we will assert:
2
3
3
As the rounding mode is now split between FP16 and the rest of
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
4
floating point we need to be explicit when tweaking it. Instead of
5
(assertion=0x5555565a8c70 "!arm_feature(env, ARM_FEATURE_M)", file=0x5555565a6e5c "../../target/arm/helper.c", line=12600, function=0x5555565a9560 <__PRETTY_FUNCTION__.0> "arm_security_space_below_el3") at ./assert/assert.c:101
5
passing the CPU env we now pass the appropriate fpst pointer directly.
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
6
9
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
11
from the migration pre/post hooks in machine.c); this should always
12
return false because these CPUs don't set ARM_FEATURE_PMU.
13
14
Avoid the assertion by not calling arm_mdcr_el2_eff() before we
15
have done the early return for "PMU not present".
16
17
This fixes an assertion failure if you try to do a loadvm or
18
savevm for an M-profile board.
19
20
Cc: qemu-stable@nongnu.org
21
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2155
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180227143852.11175-6-alex.bennee@linaro.org
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
26
---
12
target/arm/helper.h | 2 +-
27
target/arm/helper.c | 12 ++++++++++--
13
target/arm/helper.c | 4 ++--
28
1 file changed, 10 insertions(+), 2 deletions(-)
14
target/arm/translate-a64.c | 26 +++++++++++++-------------
15
target/arm/translate.c | 12 ++++++------
16
4 files changed, 22 insertions(+), 22 deletions(-)
17
29
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
21
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr)
23
DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
24
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
25
26
-DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, env)
27
+DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
28
DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
29
30
DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
32
--- a/target/arm/helper.c
34
+++ b/target/arm/helper.c
33
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
36
/* Set the current fp rounding mode and return the old one.
35
bool enabled, prohibited = false, filtered;
37
* The argument is a softfloat float_round_ value.
36
bool secure = arm_is_secure(env);
38
*/
37
int el = arm_current_el(env);
39
-uint32_t HELPER(set_rmode)(uint32_t rmode, CPUARMState *env)
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
40
+uint32_t HELPER(set_rmode)(uint32_t rmode, void *fpstp)
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
41
{
40
+ uint64_t mdcr_el2;
42
- float_status *fp_status = &env->vfp.fp_status;
41
+ uint8_t hpmn;
43
+ float_status *fp_status = fpstp;
42
44
43
+ /*
45
uint32_t prev_rmode = get_float_rounding_mode(fp_status);
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
46
set_float_rounding_mode(rmode, fp_status);
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
47
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
46
+ * must be before we read that value.
48
index XXXXXXX..XXXXXXX 100644
47
+ */
49
--- a/target/arm/translate-a64.c
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
50
+++ b/target/arm/translate-a64.c
49
return false;
51
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
52
{
53
TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
54
55
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
56
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
57
gen_helper_rints(tcg_res, tcg_op, fpst);
58
59
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
60
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
61
tcg_temp_free_i32(tcg_rmode);
62
break;
63
}
50
}
64
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
51
65
{
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
66
TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
67
54
+
68
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
69
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
56
(counter < hpmn || counter == 31)) {
70
gen_helper_rintd(tcg_res, tcg_op, fpst);
57
e = env->cp15.c9_pmcr & PMCRE;
71
72
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
73
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
74
tcg_temp_free_i32(tcg_rmode);
75
break;
76
}
77
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
78
79
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
80
81
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
82
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
83
84
if (is_double) {
85
TCGv_i64 tcg_double = read_fp_dreg(s, rn);
86
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
87
tcg_temp_free_i32(tcg_single);
88
}
89
90
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
91
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
92
tcg_temp_free_i32(tcg_rmode);
93
94
if (!sf) {
95
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
96
assert(!(is_scalar && is_q));
97
98
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(FPROUNDING_ZERO));
99
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
100
tcg_fpstatus = get_fpstatus_ptr(false);
101
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
102
tcg_shift = tcg_const_i32(fracbits);
103
104
if (is_double) {
105
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
106
107
tcg_temp_free_ptr(tcg_fpstatus);
108
tcg_temp_free_i32(tcg_shift);
109
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
110
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
111
tcg_temp_free_i32(tcg_rmode);
112
}
113
114
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
115
116
if (is_fcvt) {
117
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
118
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
119
tcg_fpstatus = get_fpstatus_ptr(false);
120
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
121
} else {
122
tcg_rmode = NULL;
123
tcg_fpstatus = NULL;
124
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
125
}
126
127
if (is_fcvt) {
128
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
129
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
130
tcg_temp_free_i32(tcg_rmode);
131
tcg_temp_free_ptr(tcg_fpstatus);
132
}
133
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
134
return;
135
}
136
137
- if (need_fpstatus) {
138
+ if (need_fpstatus || need_rmode) {
139
tcg_fpstatus = get_fpstatus_ptr(false);
140
} else {
141
tcg_fpstatus = NULL;
142
}
143
if (need_rmode) {
144
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
145
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
146
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
147
} else {
148
tcg_rmode = NULL;
149
}
150
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
151
clear_vec_high(s, is_q, rd);
152
153
if (need_rmode) {
154
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
155
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
156
tcg_temp_free_i32(tcg_rmode);
157
}
158
if (need_fpstatus) {
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
162
+++ b/target/arm/translate.c
163
@@ -XXX,XX +XXX,XX @@ static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
164
TCGv_i32 tcg_rmode;
165
166
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
167
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
168
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
169
170
if (dp) {
171
TCGv_i64 tcg_op;
172
@@ -XXX,XX +XXX,XX @@ static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
173
tcg_temp_free_i32(tcg_res);
174
}
175
176
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
177
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
178
tcg_temp_free_i32(tcg_rmode);
179
180
tcg_temp_free_ptr(fpst);
181
@@ -XXX,XX +XXX,XX @@ static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
182
tcg_shift = tcg_const_i32(0);
183
184
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
185
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
186
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
187
188
if (dp) {
189
TCGv_i64 tcg_double, tcg_res;
190
@@ -XXX,XX +XXX,XX @@ static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
191
tcg_temp_free_i32(tcg_single);
192
}
193
194
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
195
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
196
tcg_temp_free_i32(tcg_rmode);
197
198
tcg_temp_free_i32(tcg_shift);
199
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
200
TCGv_ptr fpst = get_fpstatus_ptr(0);
201
TCGv_i32 tcg_rmode;
202
tcg_rmode = tcg_const_i32(float_round_to_zero);
203
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
204
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
205
if (dp) {
206
gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
207
} else {
208
gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
209
}
210
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
211
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
212
tcg_temp_free_i32(tcg_rmode);
213
tcg_temp_free_ptr(fpst);
214
break;
215
--
58
--
216
2.16.2
59
2.34.1
217
60
218
61
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Nabih Estefan <nabihestefan@google.com>
2
2
3
As some of the constants here will also be needed
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
elsewhere (specifically for the upcoming SVE support) we move them out
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
5
to softfloat.h.
6
5
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Change-Id: Iabd0fba14910c3f1e883c4a9521350f3db9ffab8
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-Off-By: Nabih Estefan <nabihestefan@google.com>
9
Message-id: 20180227143852.11175-13-alex.bennee@linaro.org
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
9
Message-id: 20240208194759.2858582-2-nabihestefan@google.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: commit message tweaks]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/fpu/softfloat.h | 18 +++++++++++++-----
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
13
target/arm/helper-a64.h | 2 ++
15
tests/qtest/meson.build | 3 +-
14
target/arm/helper-a64.c | 34 ++++++++++++++++++++++++++++++++++
16
2 files changed, 4 insertions(+), 83 deletions(-)
15
target/arm/translate-a64.c | 6 ++++++
16
4 files changed, 55 insertions(+), 5 deletions(-)
17
17
18
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/fpu/softfloat.h
20
--- a/tests/qtest/npcm_gmac-test.c
21
+++ b/include/fpu/softfloat.h
21
+++ b/tests/qtest/npcm_gmac-test.c
22
@@ -XXX,XX +XXX,XX @@ static inline float16 float16_set_sign(float16 a, int sign)
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
23
const GMACModule *module;
24
} TestData;
25
26
-/* Values extracted from hw/arm/npcm8xx.c */
27
+/* Values extracted from hw/arm/npcm7xx.c */
28
static const GMACModule gmac_module_list[] = {
29
{
30
.irq = 14,
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
32
.irq = 15,
33
.base_addr = 0xf0804000
34
},
35
- {
36
- .irq = 16,
37
- .base_addr = 0xf0806000
38
- },
39
- {
40
- .irq = 17,
41
- .base_addr = 0xf0808000
42
- }
43
};
44
45
/* Returns the index of the GMAC module. */
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
47
return qtest_readl(qts, mod->base_addr + regno);
23
}
48
}
24
49
25
#define float16_zero make_float16(0)
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
26
-#define float16_one make_float16(0x3c00)
51
- NPCMRegister regno)
27
#define float16_half make_float16(0x3800)
52
-{
28
+#define float16_one make_float16(0x3c00)
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
29
+#define float16_one_point_five make_float16(0x3e00)
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
30
+#define float16_two make_float16(0x4000)
55
- uint32_t read_offset = regno & 0x1ff;
31
+#define float16_three make_float16(0x4200)
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
32
#define float16_infinity make_float16(0x7c00)
57
-}
33
58
-
34
/*----------------------------------------------------------------------------
59
/* Check that GMAC registers are reset to default value */
35
@@ -XXX,XX +XXX,XX @@ static inline float32 float32_set_sign(float32 a, int sign)
60
static void test_init(gconstpointer test_data)
61
{
62
const TestData *td = test_data;
63
const GMACModule *mod = td->module;
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
66
67
#define CHECK_REG32(regno, value) \
68
do { \
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
70
} while (0)
71
72
-#define CHECK_REG_PCS(regno, value) \
73
- do { \
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
76
-
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
83
84
- /* TODO Add registers PCS */
85
- if (mod->base_addr == 0xf0802000) {
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
89
-
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
91
- CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
92
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
93
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
94
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
95
- CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
96
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
97
- CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
98
-
99
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
100
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
101
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
102
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
103
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
104
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
105
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
106
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
107
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
108
-
109
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
110
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
111
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
112
- CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
113
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
114
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
115
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
116
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
117
- CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
118
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
119
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
120
- CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
121
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
122
- CHECK_REG_PCS(NPCM_PCS_VR_MII_RX_LSTS, 0);
123
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x00a);
124
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x007f);
125
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x0001);
126
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0);
127
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_STS, 0);
128
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0100);
129
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x1100);
130
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x000e);
131
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0100);
132
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0032);
133
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x0001);
134
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0);
135
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x0019);
136
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0);
137
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0);
138
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_CTRL2, 0);
139
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 0);
140
- }
141
-
142
qtest_quit(qts);
36
}
143
}
37
144
38
#define float32_zero make_float32(0)
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
39
-#define float32_one make_float32(0x3f800000)
40
#define float32_half make_float32(0x3f000000)
41
+#define float32_one make_float32(0x3f800000)
42
+#define float32_one_point_five make_float32(0x3fc00000)
43
+#define float32_two make_float32(0x40000000)
44
+#define float32_three make_float32(0x40400000)
45
#define float32_infinity make_float32(0x7f800000)
46
47
-
48
/*----------------------------------------------------------------------------
49
| The pattern for a default generated single-precision NaN.
50
*----------------------------------------------------------------------------*/
51
@@ -XXX,XX +XXX,XX @@ static inline float64 float64_set_sign(float64 a, int sign)
52
}
53
54
#define float64_zero make_float64(0)
55
-#define float64_one make_float64(0x3ff0000000000000LL)
56
-#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
57
#define float64_half make_float64(0x3fe0000000000000LL)
58
+#define float64_one make_float64(0x3ff0000000000000LL)
59
+#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
60
+#define float64_two make_float64(0x4000000000000000ULL)
61
+#define float64_three make_float64(0x4008000000000000ULL)
62
+#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
63
#define float64_infinity make_float64(0x7ff0000000000000LL)
64
65
/*----------------------------------------------------------------------------
66
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
67
index XXXXXXX..XXXXXXX 100644
146
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/helper-a64.h
147
--- a/tests/qtest/meson.build
69
+++ b/target/arm/helper-a64.h
148
+++ b/tests/qtest/meson.build
70
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
71
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
150
'npcm7xx_sdhci-test',
72
DEF_HELPER_FLAGS_3(neon_cge_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
151
'npcm7xx_smbus-test',
73
DEF_HELPER_FLAGS_3(neon_cgt_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
152
'npcm7xx_timer-test',
74
+DEF_HELPER_FLAGS_3(recpsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
153
- 'npcm7xx_watchdog_timer-test'] + \
75
DEF_HELPER_FLAGS_3(recpsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
154
+ 'npcm7xx_watchdog_timer-test',
76
DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
155
+ 'npcm_gmac-test'] + \
77
+DEF_HELPER_FLAGS_3(rsqrtsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
78
DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
157
qtests_aspeed = \
79
DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
158
['aspeed_hace-test',
80
DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64)
81
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/helper-a64.c
84
+++ b/target/arm/helper-a64.c
85
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
86
* versions, these do a fully fused multiply-add or
87
* multiply-add-and-halve.
88
*/
89
+#define float16_two make_float16(0x4000)
90
+#define float16_three make_float16(0x4200)
91
+#define float16_one_point_five make_float16(0x3e00)
92
+
93
#define float32_two make_float32(0x40000000)
94
#define float32_three make_float32(0x40400000)
95
#define float32_one_point_five make_float32(0x3fc00000)
96
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
97
#define float64_three make_float64(0x4008000000000000ULL)
98
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
99
100
+float16 HELPER(recpsf_f16)(float16 a, float16 b, void *fpstp)
101
+{
102
+ float_status *fpst = fpstp;
103
+
104
+ a = float16_squash_input_denormal(a, fpst);
105
+ b = float16_squash_input_denormal(b, fpst);
106
+
107
+ a = float16_chs(a);
108
+ if ((float16_is_infinity(a) && float16_is_zero(b)) ||
109
+ (float16_is_infinity(b) && float16_is_zero(a))) {
110
+ return float16_two;
111
+ }
112
+ return float16_muladd(a, b, float16_two, 0, fpst);
113
+}
114
+
115
float32 HELPER(recpsf_f32)(float32 a, float32 b, void *fpstp)
116
{
117
float_status *fpst = fpstp;
118
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
119
return float64_muladd(a, b, float64_two, 0, fpst);
120
}
121
122
+float16 HELPER(rsqrtsf_f16)(float16 a, float16 b, void *fpstp)
123
+{
124
+ float_status *fpst = fpstp;
125
+
126
+ a = float16_squash_input_denormal(a, fpst);
127
+ b = float16_squash_input_denormal(b, fpst);
128
+
129
+ a = float16_chs(a);
130
+ if ((float16_is_infinity(a) && float16_is_zero(b)) ||
131
+ (float16_is_infinity(b) && float16_is_zero(a))) {
132
+ return float16_one_point_five;
133
+ }
134
+ return float16_muladd(a, b, float16_three, float_muladd_halve_result, fpst);
135
+}
136
+
137
float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, void *fpstp)
138
{
139
float_status *fpst = fpstp;
140
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/target/arm/translate-a64.c
143
+++ b/target/arm/translate-a64.c
144
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
145
case 0x6: /* FMAX */
146
gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
147
break;
148
+ case 0x7: /* FRECPS */
149
+ gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
150
+ break;
151
case 0x8: /* FMINNM */
152
gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
153
break;
154
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
155
case 0xe: /* FMIN */
156
gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
157
break;
158
+ case 0xf: /* FRSQRTS */
159
+ gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
160
+ break;
161
case 0x13: /* FMUL */
162
gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
163
break;
164
--
159
--
165
2.16.2
160
2.34.1
166
167
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
I've re-factored the handle_simd_intfp_conv helper to properly handle
3
An access fault is raised when the Access Flag is not set in the
4
half-precision as well as call plain conversion helpers when we are
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
not doing fixed point conversion.
5
descriptor. This was already implemented for stage 2. Implement it for
6
stage 1 as well.
6
7
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
9
Message-id: 20180227143852.11175-21-alex.bennee@linaro.org
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Tested-by: Mostafa Saleh <smostafa@google.com>
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
[PMM: tweaked comment text]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
target/arm/helper.h | 10 ++++
16
hw/arm/smmuv3-internal.h | 1 +
13
target/arm/helper.c | 4 ++
17
include/hw/arm/smmu-common.h | 1 +
14
target/arm/translate-a64.c | 122 ++++++++++++++++++++++++++++++++++-----------
18
hw/arm/smmu-common.c | 11 +++++++++++
15
3 files changed, 108 insertions(+), 28 deletions(-)
19
hw/arm/smmuv3.c | 1 +
20
4 files changed, 14 insertions(+)
16
21
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
24
--- a/hw/arm/smmuv3-internal.h
20
+++ b/target/arm/helper.h
25
+++ b/hw/arm/smmuv3-internal.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
22
DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
23
DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
24
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
25
+DEF_HELPER_2(vfp_uitoh, f16, i32, ptr)
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
26
DEF_HELPER_2(vfp_uitos, f32, i32, ptr)
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
27
DEF_HELPER_2(vfp_uitod, f64, i32, ptr)
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
28
+DEF_HELPER_2(vfp_sitoh, f16, i32, ptr)
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
29
DEF_HELPER_2(vfp_sitos, f32, i32, ptr)
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
30
DEF_HELPER_2(vfp_sitod, f64, i32, ptr)
31
32
+DEF_HELPER_2(vfp_touih, i32, f16, ptr)
33
DEF_HELPER_2(vfp_touis, i32, f32, ptr)
34
DEF_HELPER_2(vfp_touid, i32, f64, ptr)
35
+DEF_HELPER_2(vfp_touizh, i32, f16, ptr)
36
DEF_HELPER_2(vfp_touizs, i32, f32, ptr)
37
DEF_HELPER_2(vfp_touizd, i32, f64, ptr)
38
+DEF_HELPER_2(vfp_tosih, i32, f16, ptr)
39
DEF_HELPER_2(vfp_tosis, i32, f32, ptr)
40
DEF_HELPER_2(vfp_tosid, i32, f64, ptr)
41
+DEF_HELPER_2(vfp_tosizh, i32, f16, ptr)
42
DEF_HELPER_2(vfp_tosizs, i32, f32, ptr)
43
DEF_HELPER_2(vfp_tosizd, i32, f64, ptr)
44
45
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_toshd_round_to_zero, i64, f64, i32, ptr)
46
DEF_HELPER_3(vfp_tosld_round_to_zero, i64, f64, i32, ptr)
47
DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
48
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
49
+DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr)
50
+DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr)
51
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
52
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
53
DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
54
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_sqtod, f64, i64, i32, ptr)
55
DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr)
56
DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
57
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
58
+DEF_HELPER_3(vfp_sltoh, f16, i32, i32, ptr)
59
+DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
60
61
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
62
DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
64
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
36
--- a/include/hw/arm/smmu-common.h
66
+++ b/target/arm/helper.c
37
+++ b/include/hw/arm/smmu-common.h
67
@@ -XXX,XX +XXX,XX @@ CONV_ITOF(vfp_##name##to##p, fsz, sign) \
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
68
CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
39
bool disabled; /* smmu is disabled */
69
CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
40
bool bypassed; /* translation is bypassed */
70
41
bool aborted; /* translation is aborted */
71
+FLOAT_CONVS(si, h, 16, )
42
+ bool affd; /* AF fault disable */
72
FLOAT_CONVS(si, s, 32, )
43
uint32_t iotlb_hits; /* counts IOTLB hits */
73
FLOAT_CONVS(si, d, 64, )
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
74
+FLOAT_CONVS(ui, h, 16, u)
45
/* Used by stage-1 only. */
75
FLOAT_CONVS(ui, s, 32, u)
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
76
FLOAT_CONVS(ui, d, 64, u)
77
78
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(sq, s, 32, 64, int64)
79
VFP_CONV_FIX(uh, s, 32, 32, uint16)
80
VFP_CONV_FIX(ul, s, 32, 32, uint32)
81
VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
82
+VFP_CONV_FIX_A64(sl, h, 16, 32, int32)
83
+VFP_CONV_FIX_A64(ul, h, 16, 32, uint32)
84
#undef VFP_CONV_FIX
85
#undef VFP_CONV_FIX_FLOAT
86
#undef VFP_CONV_FLOAT_FIX_ROUND
87
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
88
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/translate-a64.c
48
--- a/hw/arm/smmu-common.c
90
+++ b/target/arm/translate-a64.c
49
+++ b/hw/arm/smmu-common.c
91
@@ -XXX,XX +XXX,XX @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
92
int elements, int is_signed,
51
pte_addr, pte, iova, gpa,
93
int fracbits, int size)
52
block_size >> 20);
94
{
95
- bool is_double = size == 3 ? true : false;
96
- TCGv_ptr tcg_fpst = get_fpstatus_ptr(false);
97
- TCGv_i32 tcg_shift = tcg_const_i32(fracbits);
98
- TCGv_i64 tcg_int = tcg_temp_new_i64();
99
+ TCGv_ptr tcg_fpst = get_fpstatus_ptr(size == MO_16);
100
+ TCGv_i32 tcg_shift = NULL;
101
+
102
TCGMemOp mop = size | (is_signed ? MO_SIGN : 0);
103
int pass;
104
105
- for (pass = 0; pass < elements; pass++) {
106
- read_vec_element(s, tcg_int, rn, pass, mop);
107
+ if (fracbits || size == MO_64) {
108
+ tcg_shift = tcg_const_i32(fracbits);
109
+ }
110
+
111
+ if (size == MO_64) {
112
+ TCGv_i64 tcg_int64 = tcg_temp_new_i64();
113
+ TCGv_i64 tcg_double = tcg_temp_new_i64();
114
+
115
+ for (pass = 0; pass < elements; pass++) {
116
+ read_vec_element(s, tcg_int64, rn, pass, mop);
117
118
- if (is_double) {
119
- TCGv_i64 tcg_double = tcg_temp_new_i64();
120
if (is_signed) {
121
- gen_helper_vfp_sqtod(tcg_double, tcg_int,
122
+ gen_helper_vfp_sqtod(tcg_double, tcg_int64,
123
tcg_shift, tcg_fpst);
124
} else {
125
- gen_helper_vfp_uqtod(tcg_double, tcg_int,
126
+ gen_helper_vfp_uqtod(tcg_double, tcg_int64,
127
tcg_shift, tcg_fpst);
128
}
129
if (elements == 1) {
130
@@ -XXX,XX +XXX,XX @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
131
} else {
132
write_vec_element(s, tcg_double, rd, pass, MO_64);
133
}
134
- tcg_temp_free_i64(tcg_double);
135
- } else {
136
- TCGv_i32 tcg_single = tcg_temp_new_i32();
137
- if (is_signed) {
138
- gen_helper_vfp_sqtos(tcg_single, tcg_int,
139
- tcg_shift, tcg_fpst);
140
- } else {
141
- gen_helper_vfp_uqtos(tcg_single, tcg_int,
142
- tcg_shift, tcg_fpst);
143
- }
144
- if (elements == 1) {
145
- write_fp_sreg(s, rd, tcg_single);
146
- } else {
147
- write_vec_element_i32(s, tcg_single, rd, pass, MO_32);
148
- }
149
- tcg_temp_free_i32(tcg_single);
150
}
53
}
151
+
54
+
152
+ tcg_temp_free_i64(tcg_int64);
55
+ /*
153
+ tcg_temp_free_i64(tcg_double);
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
154
+
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
155
+ } else {
58
+ * An Access flag fault takes priority over a Permission fault.
156
+ TCGv_i32 tcg_int32 = tcg_temp_new_i32();
59
+ */
157
+ TCGv_i32 tcg_float = tcg_temp_new_i32();
60
+ if (!PTE_AF(pte) && !cfg->affd) {
158
+
61
+ info->type = SMMU_PTW_ERR_ACCESS;
159
+ for (pass = 0; pass < elements; pass++) {
62
+ goto error;
160
+ read_vec_element_i32(s, tcg_int32, rn, pass, mop);
161
+
162
+ switch (size) {
163
+ case MO_32:
164
+ if (fracbits) {
165
+ if (is_signed) {
166
+ gen_helper_vfp_sltos(tcg_float, tcg_int32,
167
+ tcg_shift, tcg_fpst);
168
+ } else {
169
+ gen_helper_vfp_ultos(tcg_float, tcg_int32,
170
+ tcg_shift, tcg_fpst);
171
+ }
172
+ } else {
173
+ if (is_signed) {
174
+ gen_helper_vfp_sitos(tcg_float, tcg_int32, tcg_fpst);
175
+ } else {
176
+ gen_helper_vfp_uitos(tcg_float, tcg_int32, tcg_fpst);
177
+ }
178
+ }
179
+ break;
180
+ case MO_16:
181
+ if (fracbits) {
182
+ if (is_signed) {
183
+ gen_helper_vfp_sltoh(tcg_float, tcg_int32,
184
+ tcg_shift, tcg_fpst);
185
+ } else {
186
+ gen_helper_vfp_ultoh(tcg_float, tcg_int32,
187
+ tcg_shift, tcg_fpst);
188
+ }
189
+ } else {
190
+ if (is_signed) {
191
+ gen_helper_vfp_sitoh(tcg_float, tcg_int32, tcg_fpst);
192
+ } else {
193
+ gen_helper_vfp_uitoh(tcg_float, tcg_int32, tcg_fpst);
194
+ }
195
+ }
196
+ break;
197
+ default:
198
+ g_assert_not_reached();
199
+ }
200
+
201
+ if (elements == 1) {
202
+ write_fp_sreg(s, rd, tcg_float);
203
+ } else {
204
+ write_vec_element_i32(s, tcg_float, rd, pass, size);
205
+ }
206
+ }
63
+ }
207
+
64
+
208
+ tcg_temp_free_i32(tcg_int32);
65
ap = PTE_AP(pte);
209
+ tcg_temp_free_i32(tcg_float);
66
if (is_permission_fault(ap, perm)) {
210
}
67
info->type = SMMU_PTW_ERR_PERMISSION;
211
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
212
- tcg_temp_free_i64(tcg_int);
69
index XXXXXXX..XXXXXXX 100644
213
tcg_temp_free_ptr(tcg_fpst);
70
--- a/hw/arm/smmuv3.c
214
- tcg_temp_free_i32(tcg_shift);
71
+++ b/hw/arm/smmuv3.c
215
+ if (tcg_shift) {
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
216
+ tcg_temp_free_i32(tcg_shift);
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
217
+ }
74
cfg->tbi = CD_TBI(cd);
218
75
cfg->asid = CD_ASID(cd);
219
clear_vec_high(s, elements << size == 16, rd);
76
+ cfg->affd = CD_AFFD(cd);
220
}
77
221
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
78
trace_smmuv3_decode_cd(cfg->oas);
222
rn = extract32(insn, 5, 5);
79
223
224
switch (fpop) {
225
+ case 0x1d: /* SCVTF */
226
+ case 0x5d: /* UCVTF */
227
+ {
228
+ int elements;
229
+
230
+ if (is_scalar) {
231
+ elements = 1;
232
+ } else {
233
+ elements = (is_q ? 8 : 4);
234
+ }
235
+
236
+ if (!fp_access_check(s)) {
237
+ return;
238
+ }
239
+ handle_simd_intfp_conv(s, rd, rn, elements, !u, 0, MO_16);
240
+ return;
241
+ }
242
break;
243
case 0x2c: /* FCMGT (zero) */
244
case 0x2d: /* FCMEQ (zero) */
245
--
80
--
246
2.16.2
81
2.34.1
247
248
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This actually covers two different sections of the encoding table:
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Advanced SIMD scalar two-register miscellaneous FP16
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
6
Advanced SIMD two-register miscellaneous (FP16)
7
8
The difference between the two is covered by a combination of Q (bit
9
30) and S (bit 28). Notably the FRINTx instructions are only
10
available in the vector form.
11
12
This is just the decode skeleton which will be filled out by later
13
patches.
14
15
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20180227143852.11175-17-alex.bennee@linaro.org
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
7
---
20
target/arm/translate-a64.c | 40 ++++++++++++++++++++++++++++++++++++++++
8
hw/arm/stellaris.c | 6 ++++--
21
1 file changed, 40 insertions(+)
9
1 file changed, 4 insertions(+), 2 deletions(-)
22
10
23
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
24
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-a64.c
13
--- a/hw/arm/stellaris.c
26
+++ b/target/arm/translate-a64.c
14
+++ b/hw/arm/stellaris.c
27
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
28
}
16
}
29
}
17
}
30
18
31
+/* AdvSIMD [scalar] two register miscellaneous (FP16)
19
-static void stellaris_adc_reset(StellarisADCState *s)
32
+ *
20
+static void stellaris_adc_reset_hold(Object *obj)
33
+ * 31 30 29 28 27 24 23 22 21 17 16 12 11 10 9 5 4 0
21
{
34
+ * +---+---+---+---+---------+---+-------------+--------+-----+------+------+
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
35
+ * | 0 | Q | U | S | 1 1 1 0 | a | 1 1 1 1 0 0 | opcode | 1 0 | Rn | Rd |
23
int n;
36
+ * +---+---+---+---+---------+---+-------------+--------+-----+------+------+
24
37
+ * mask: 1000 1111 0111 1110 0000 1100 0000 0000 0x8f7e 0c00
25
for (n = 0; n < 4; n++) {
38
+ * val: 0000 1110 0111 1000 0000 1000 0000 0000 0x0e78 0800
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
39
+ *
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
40
+ * This actually covers two groups where scalar access is governed by
28
"adc", 0x1000);
41
+ * bit 28. A bunch of the instructions (float to integral) only exist
29
sysbus_init_mmio(sbd, &s->iomem);
42
+ * in the vector form and are un-allocated for the scalar decode. Also
30
- stellaris_adc_reset(s);
43
+ * in the scalar decode Q is always 1.
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
44
+ */
32
}
45
+static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
33
46
+{
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
47
+ int fpop, opcode, a;
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
48
+
36
{
49
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
37
DeviceClass *dc = DEVICE_CLASS(klass);
50
+ unallocated_encoding(s);
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
51
+ return;
39
52
+ }
40
+ rc->phases.hold = stellaris_adc_reset_hold;
53
+
41
dc->vmsd = &vmstate_stellaris_adc;
54
+ if (!fp_access_check(s)) {
42
}
55
+ return;
56
+ }
57
+
58
+ opcode = extract32(insn, 12, 4);
59
+ a = extract32(insn, 23, 1);
60
+ fpop = deposit32(opcode, 5, 1, a);
61
+
62
+ switch (fpop) {
63
+ default:
64
+ fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
65
+ g_assert_not_reached();
66
+ }
67
+
68
+}
69
+
70
/* AdvSIMD scalar x indexed element
71
* 31 30 29 28 24 23 22 21 20 19 16 15 12 11 10 9 5 4 0
72
* +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
73
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
74
{ 0xce800000, 0xffe00000, disas_crypto_xar },
75
{ 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
76
{ 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
77
+ { 0x0e780800, 0x8f7e0c00, disas_simd_two_reg_misc_fp16 },
78
{ 0x00000000, 0x00000000, NULL }
79
};
80
43
81
--
44
--
82
2.16.2
45
2.34.1
83
46
84
47
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Much like recpe the ARM ARM has simplified the pseudo code for the
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
4
calculation which is done on a fixed point 9 bit integer maths. So
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
while adding f16 we can also clean this up to be a little less heavy
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
6
on the floating point and just return the fractional part and leave
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
the calle's to do the final packing of the result.
8
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180227143852.11175-27-alex.bennee@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
8
---
14
target/arm/helper.h | 1 +
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
15
target/arm/helper.c | 221 ++++++++++++++++++++++++----------------------------
10
1 file changed, 22 insertions(+), 4 deletions(-)
16
2 files changed, 104 insertions(+), 118 deletions(-)
17
11
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
14
--- a/hw/arm/stellaris.c
21
+++ b/target/arm/helper.h
15
+++ b/hw/arm/stellaris.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
23
DEF_HELPER_FLAGS_2(recpe_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
24
DEF_HELPER_FLAGS_2(recpe_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
18
}
25
DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
19
26
+DEF_HELPER_FLAGS_2(rsqrte_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
20
-/* I2C controller. */
27
DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
21
+/*
28
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
22
+ * I2C controller.
29
DEF_HELPER_2(recpe_u32, i32, i32, ptr)
23
+ * ??? For now we only implement the master interface.
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
+ */
31
index XXXXXXX..XXXXXXX 100644
25
32
--- a/target/arm/helper.c
26
#define TYPE_STELLARIS_I2C "stellaris-i2c"
33
+++ b/target/arm/helper.c
27
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
34
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
35
/* The algorithm that must be used to calculate the estimate
29
stellaris_i2c_update(s);
36
* is specified by the ARM ARM.
30
}
37
*/
31
38
-static float64 recip_sqrt_estimate(float64 a, float_status *real_fp_status)
32
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
33
+static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
34
{
35
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
39
+
36
+
40
+static int do_recip_sqrt_estimate(int a)
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
41
{
38
i2c_end_transfer(s->bus);
42
- /* These calculations mustn't set any fp exception flags,
43
- * so we use a local copy of the fp_status.
44
- */
45
- float_status dummy_status = *real_fp_status;
46
- float_status *s = &dummy_status;
47
- float64 q;
48
- int64_t q_int;
49
+ int b, estimate;
50
51
- if (float64_lt(a, float64_half, s)) {
52
- /* range 0.25 <= a < 0.5 */
53
-
54
- /* a in units of 1/512 rounded down */
55
- /* q0 = (int)(a * 512.0); */
56
- q = float64_mul(float64_512, a, s);
57
- q_int = float64_to_int64_round_to_zero(q, s);
58
-
59
- /* reciprocal root r */
60
- /* r = 1.0 / sqrt(((double)q0 + 0.5) / 512.0); */
61
- q = int64_to_float64(q_int, s);
62
- q = float64_add(q, float64_half, s);
63
- q = float64_div(q, float64_512, s);
64
- q = float64_sqrt(q, s);
65
- q = float64_div(float64_one, q, s);
66
+ assert(128 <= a && a < 512);
67
+ if (a < 256) {
68
+ a = a * 2 + 1;
69
} else {
70
- /* range 0.5 <= a < 1.0 */
71
-
72
- /* a in units of 1/256 rounded down */
73
- /* q1 = (int)(a * 256.0); */
74
- q = float64_mul(float64_256, a, s);
75
- int64_t q_int = float64_to_int64_round_to_zero(q, s);
76
-
77
- /* reciprocal root r */
78
- /* r = 1.0 /sqrt(((double)q1 + 0.5) / 256); */
79
- q = int64_to_float64(q_int, s);
80
- q = float64_add(q, float64_half, s);
81
- q = float64_div(q, float64_256, s);
82
- q = float64_sqrt(q, s);
83
- q = float64_div(float64_one, q, s);
84
+ a = (a >> 1) << 1;
85
+ a = (a + 1) * 2;
86
}
87
- /* r in units of 1/256 rounded to nearest */
88
- /* s = (int)(256.0 * r + 0.5); */
89
+ b = 512;
90
+ while (a * (b + 1) * (b + 1) < (1 << 28)) {
91
+ b += 1;
92
+ }
93
+ estimate = (b + 1) / 2;
94
+ assert(256 <= estimate && estimate < 512);
95
96
- q = float64_mul(q, float64_256,s );
97
- q = float64_add(q, float64_half, s);
98
- q_int = float64_to_int64_round_to_zero(q, s);
99
+ return estimate;
100
+}
101
102
- /* return (double)s / 256.0;*/
103
- return float64_div(int64_to_float64(q_int, s), float64_256, s);
104
+
105
+static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
106
+{
107
+ int estimate;
108
+ uint32_t scaled;
109
+
110
+ if (*exp == 0) {
111
+ while (extract64(frac, 51, 1) == 0) {
112
+ frac = frac << 1;
113
+ *exp -= 1;
114
+ }
115
+ frac = extract64(frac, 0, 51) << 1;
116
+ }
117
+
118
+ if (*exp & 1) {
119
+ /* scaled = UInt('01':fraction<51:45>) */
120
+ scaled = deposit32(1 << 7, 0, 7, extract64(frac, 45, 7));
121
+ } else {
122
+ /* scaled = UInt('1':fraction<51:44>) */
123
+ scaled = deposit32(1 << 8, 0, 8, extract64(frac, 44, 8));
124
+ }
125
+ estimate = do_recip_sqrt_estimate(scaled);
126
+
127
+ *exp = (exp_off - *exp) / 2;
128
+ return extract64(estimate, 0, 8) << 44;
129
+}
39
+}
130
+
40
+
131
+float16 HELPER(rsqrte_f16)(float16 input, void *fpstp)
41
+static void stellaris_i2c_reset_hold(Object *obj)
132
+{
42
+{
133
+ float_status *s = fpstp;
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
134
+ float16 f16 = float16_squash_input_denormal(input, s);
44
135
+ uint16_t val = float16_val(f16);
45
s->msa = 0;
136
+ bool f16_sign = float16_is_neg(f16);
46
s->mcs = 0;
137
+ int f16_exp = extract32(val, 10, 5);
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
138
+ uint16_t f16_frac = extract32(val, 0, 10);
48
s->mimr = 0;
139
+ uint64_t f64_frac;
49
s->mris = 0;
50
s->mcr = 0;
51
+}
140
+
52
+
141
+ if (float16_is_any_nan(f16)) {
53
+static void stellaris_i2c_reset_exit(Object *obj)
142
+ float16 nan = f16;
54
+{
143
+ if (float16_is_signaling_nan(f16, s)) {
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
144
+ float_raise(float_flag_invalid, s);
145
+ nan = float16_maybe_silence_nan(f16, s);
146
+ }
147
+ if (s->default_nan_mode) {
148
+ nan = float16_default_nan(s);
149
+ }
150
+ return nan;
151
+ } else if (float16_is_zero(f16)) {
152
+ float_raise(float_flag_divbyzero, s);
153
+ return float16_set_sign(float16_infinity, f16_sign);
154
+ } else if (f16_sign) {
155
+ float_raise(float_flag_invalid, s);
156
+ return float16_default_nan(s);
157
+ } else if (float16_is_infinity(f16)) {
158
+ return float16_zero;
159
+ }
160
+
56
+
161
+ /* Scale and normalize to a double-precision value between 0.25 and 1.0,
57
stellaris_i2c_update(s);
162
+ * preserving the parity of the exponent. */
163
+
164
+ f64_frac = ((uint64_t) f16_frac) << (52 - 10);
165
+
166
+ f64_frac = recip_sqrt_estimate(&f16_exp, 44, f64_frac);
167
+
168
+ /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(2) */
169
+ val = deposit32(0, 15, 1, f16_sign);
170
+ val = deposit32(val, 10, 5, f16_exp);
171
+ val = deposit32(val, 2, 8, extract64(f64_frac, 52 - 8, 8));
172
+ return make_float16(val);
173
}
58
}
174
59
175
float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
176
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
177
float_status *s = fpstp;
62
"i2c", 0x1000);
178
float32 f32 = float32_squash_input_denormal(input, s);
63
sysbus_init_mmio(sbd, &s->iomem);
179
uint32_t val = float32_val(f32);
64
- /* ??? For now we only implement the master interface. */
180
- uint32_t f32_sbit = 0x80000000 & val;
65
- stellaris_i2c_reset(s);
181
- int32_t f32_exp = extract32(val, 23, 8);
182
+ uint32_t f32_sign = float32_is_neg(f32);
183
+ int f32_exp = extract32(val, 23, 8);
184
uint32_t f32_frac = extract32(val, 0, 23);
185
uint64_t f64_frac;
186
- uint64_t val64;
187
- int result_exp;
188
- float64 f64;
189
190
if (float32_is_any_nan(f32)) {
191
float32 nan = f32;
192
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
193
* preserving the parity of the exponent. */
194
195
f64_frac = ((uint64_t) f32_frac) << 29;
196
- if (f32_exp == 0) {
197
- while (extract64(f64_frac, 51, 1) == 0) {
198
- f64_frac = f64_frac << 1;
199
- f32_exp = f32_exp-1;
200
- }
201
- f64_frac = extract64(f64_frac, 0, 51) << 1;
202
- }
203
204
- if (extract64(f32_exp, 0, 1) == 0) {
205
- f64 = make_float64(((uint64_t) f32_sbit) << 32
206
- | (0x3feULL << 52)
207
- | f64_frac);
208
- } else {
209
- f64 = make_float64(((uint64_t) f32_sbit) << 32
210
- | (0x3fdULL << 52)
211
- | f64_frac);
212
- }
213
+ f64_frac = recip_sqrt_estimate(&f32_exp, 380, f64_frac);
214
215
- result_exp = (380 - f32_exp) / 2;
216
-
217
- f64 = recip_sqrt_estimate(f64, s);
218
-
219
- val64 = float64_val(f64);
220
-
221
- val = ((result_exp & 0xff) << 23)
222
- | ((val64 >> 29) & 0x7fffff);
223
+ /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(15) */
224
+ val = deposit32(0, 31, 1, f32_sign);
225
+ val = deposit32(val, 23, 8, f32_exp);
226
+ val = deposit32(val, 15, 8, extract64(f64_frac, 52 - 8, 8));
227
return make_float32(val);
228
}
66
}
229
67
230
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
68
/* Analogue to Digital Converter. This is only partially implemented,
231
float_status *s = fpstp;
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
232
float64 f64 = float64_squash_input_denormal(input, s);
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
233
uint64_t val = float64_val(f64);
71
{
234
- uint64_t f64_sbit = 0x8000000000000000ULL & val;
72
DeviceClass *dc = DEVICE_CLASS(klass);
235
- int64_t f64_exp = extract64(val, 52, 11);
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
236
+ bool f64_sign = float64_is_neg(f64);
74
237
+ int f64_exp = extract64(val, 52, 11);
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
238
uint64_t f64_frac = extract64(val, 0, 52);
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
239
- int64_t result_exp;
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
240
- uint64_t result_frac;
78
dc->vmsd = &vmstate_stellaris_i2c;
241
242
if (float64_is_any_nan(f64)) {
243
float64 nan = f64;
244
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
245
return float64_zero;
246
}
247
248
- /* Scale and normalize to a double-precision value between 0.25 and 1.0,
249
- * preserving the parity of the exponent. */
250
+ f64_frac = recip_sqrt_estimate(&f64_exp, 3068, f64_frac);
251
252
- if (f64_exp == 0) {
253
- while (extract64(f64_frac, 51, 1) == 0) {
254
- f64_frac = f64_frac << 1;
255
- f64_exp = f64_exp - 1;
256
- }
257
- f64_frac = extract64(f64_frac, 0, 51) << 1;
258
- }
259
-
260
- if (extract64(f64_exp, 0, 1) == 0) {
261
- f64 = make_float64(f64_sbit
262
- | (0x3feULL << 52)
263
- | f64_frac);
264
- } else {
265
- f64 = make_float64(f64_sbit
266
- | (0x3fdULL << 52)
267
- | f64_frac);
268
- }
269
-
270
- result_exp = (3068 - f64_exp) / 2;
271
-
272
- f64 = recip_sqrt_estimate(f64, s);
273
-
274
- result_frac = extract64(float64_val(f64), 0, 52);
275
-
276
- return make_float64(f64_sbit |
277
- ((result_exp & 0x7ff) << 52) |
278
- result_frac);
279
+ /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(44) */
280
+ val = deposit64(0, 61, 1, f64_sign);
281
+ val = deposit64(val, 52, 11, f64_exp);
282
+ val = deposit64(val, 44, 8, extract64(f64_frac, 52 - 8, 8));
283
+ return make_float64(val);
284
}
79
}
285
80
286
uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
287
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
288
289
uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp)
290
{
291
- float_status *fpst = fpstp;
292
- float64 f64;
293
+ int estimate;
294
295
if ((a & 0xc0000000) == 0) {
296
return 0xffffffff;
297
}
298
299
- if (a & 0x80000000) {
300
- f64 = make_float64((0x3feULL << 52)
301
- | ((uint64_t)(a & 0x7fffffff) << 21));
302
- } else { /* bits 31-30 == '01' */
303
- f64 = make_float64((0x3fdULL << 52)
304
- | ((uint64_t)(a & 0x3fffffff) << 22));
305
- }
306
+ estimate = do_recip_sqrt_estimate(extract32(a, 23, 9));
307
308
- f64 = recip_sqrt_estimate(f64, fpst);
309
-
310
- return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
311
+ return deposit32(0, 23, 9, estimate);
312
}
313
314
/* VFPv4 fused multiply-accumulate */
315
--
81
--
316
2.16.2
82
2.34.1
317
83
318
84
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This includes FMOV, FABS, FNEG, FSQRT and FRINT[NPMZAXI]. We re-use
3
QDev objects created with qdev_new() need to manually add
4
existing helpers to achieve this.
4
their parent relationship with object_property_add_child().
5
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
This commit plug the devices which aren't part of the SoC;
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
they will be plugged into a SoC container in the next one.
8
Message-id: 20180227143852.11175-32-alex.bennee@linaro.org
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/translate-a64.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++
14
hw/arm/stellaris.c | 4 ++++
12
1 file changed, 71 insertions(+)
15
1 file changed, 4 insertions(+)
13
16
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
19
--- a/hw/arm/stellaris.c
17
+++ b/target/arm/translate-a64.c
20
+++ b/hw/arm/stellaris.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
19
tcg_temp_free_i64(t_true);
22
&error_fatal);
20
}
23
21
24
ssddev = qdev_new("ssd0323");
22
+/* Floating-point data-processing (1 source) - half precision */
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
23
+static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
26
qdev_prop_set_uint8(ssddev, "cs", 1);
24
+{
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
25
+ TCGv_ptr fpst = NULL;
28
26
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
27
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
30
+ object_property_add_child(OBJECT(ms), "splitter",
28
+
31
+ OBJECT(gpio_d_splitter));
29
+ read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
30
+
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
31
+ switch (opcode) {
34
qdev_connect_gpio_out(
32
+ case 0x0: /* FMOV */
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
33
+ tcg_gen_mov_i32(tcg_res, tcg_op);
36
DeviceState *gpad;
34
+ break;
37
35
+ case 0x1: /* FABS */
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
36
+ tcg_gen_andi_i32(tcg_res, tcg_op, 0x7fff);
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
37
+ break;
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
38
+ case 0x2: /* FNEG */
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
39
+ tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
40
+ break;
41
+ case 0x3: /* FSQRT */
42
+ gen_helper_sqrt_f16(tcg_res, tcg_op, cpu_env);
43
+ break;
44
+ case 0x8: /* FRINTN */
45
+ case 0x9: /* FRINTP */
46
+ case 0xa: /* FRINTM */
47
+ case 0xb: /* FRINTZ */
48
+ case 0xc: /* FRINTA */
49
+ {
50
+ TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
51
+ fpst = get_fpstatus_ptr(true);
52
+
53
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
54
+ gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst);
55
+
56
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
57
+ tcg_temp_free_i32(tcg_rmode);
58
+ break;
59
+ }
60
+ case 0xe: /* FRINTX */
61
+ fpst = get_fpstatus_ptr(true);
62
+ gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, fpst);
63
+ break;
64
+ case 0xf: /* FRINTI */
65
+ fpst = get_fpstatus_ptr(true);
66
+ gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst);
67
+ break;
68
+ default:
69
+ abort();
70
+ }
71
+
72
+ write_fp_sreg(s, rd, tcg_res);
73
+
74
+ if (fpst) {
75
+ tcg_temp_free_ptr(fpst);
76
+ }
77
+ tcg_temp_free_i32(tcg_op);
78
+ tcg_temp_free_i32(tcg_res);
79
+}
80
+
81
/* Floating-point data-processing (1 source) - single precision */
82
static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
83
{
84
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
85
86
handle_fp_1src_double(s, opcode, rd, rn);
87
break;
88
+ case 3:
89
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
90
+ unallocated_encoding(s);
91
+ return;
92
+ }
93
+
94
+ if (!fp_access_check(s)) {
95
+ return;
96
+ }
97
+
98
+ handle_fp_1src_half(s, opcode, rd, rn);
99
+ break;
100
default:
101
unallocated_encoding(s);
102
}
42
}
103
--
43
--
104
2.16.2
44
2.34.1
105
45
106
46
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The helpers use the new re-factored muladd support in SoftFloat for
3
QDev objects created with qdev_new() need to manually add
4
the float16 work.
4
their parent relationship with object_property_add_child().
5
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Since we don't model the SoC, just use a QOM container.
7
Message-id: 20180227143852.11175-15-alex.bennee@linaro.org
7
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20240213155214.13619-5-philmd@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
target/arm/translate-a64.c | 82 +++++++++++++++++++++++++++++++++++++---------
13
hw/arm/stellaris.c | 11 ++++++++++-
12
1 file changed, 66 insertions(+), 16 deletions(-)
14
1 file changed, 10 insertions(+), 1 deletion(-)
13
15
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
18
--- a/hw/arm/stellaris.c
17
+++ b/target/arm/translate-a64.c
19
+++ b/hw/arm/stellaris.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
19
int rd = extract32(insn, 0, 5);
21
* 400fe000 system control
20
bool is_long = false;
22
*/
21
bool is_fp = false;
23
22
+ bool is_fp16 = false;
24
+ Object *soc_container;
23
int index;
25
DeviceState *gpio_dev[7], *nvic;
24
TCGv_ptr fpst;
26
qemu_irq gpio_in[7][8];
25
27
qemu_irq gpio_out[7][8];
26
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
27
}
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
28
/* fall through */
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
29
case 0x9: /* FMUL, FMULX */
31
30
- if (!extract32(size, 1, 1)) {
32
+ soc_container = object_new("container");
31
+ if (size == 1) {
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
32
unallocated_encoding(s);
34
+
33
return;
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
34
}
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
35
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
37
&error_fatal);
36
}
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
37
39
* need its sysclk output.
38
if (is_fp) {
40
*/
39
- /* low bit of size indicates single/double */
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
40
- size = extract32(size, 0, 1) ? 3 : 2;
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
41
- if (size == 2) {
43
42
+ /* convert insn encoded size to TCGMemOp size */
44
/*
43
+ switch (size) {
45
* Most devices come preprogrammed with a MAC address in the user data.
44
+ case 2: /* single precision */
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
45
+ size = MO_32;
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
46
index = h << 1 | l;
48
47
- } else {
49
nvic = qdev_new(TYPE_ARMV7M);
48
+ rm |= (m << 4);
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
49
+ break;
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
50
+ case 3: /* double precision */
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
51
+ size = MO_64;
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
52
if (l || !is_q) {
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
53
unallocated_encoding(s);
55
54
return;
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
55
}
57
sbd = SYS_BUS_DEVICE(dev);
56
index = h;
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
57
+ rm |= (m << 4);
59
qdev_connect_clock_in(dev, "clk",
58
+ break;
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
59
+ case 0: /* half precision */
61
sysbus_realize_and_unref(sbd, &error_fatal);
60
+ size = MO_16;
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
61
+ index = h << 2 | l << 1 | m;
63
62
+ is_fp16 = true;
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
63
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
64
+ break;
66
-
65
+ }
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
66
+ /* fallthru */
68
qdev_connect_clock_in(dev, "WDOGCLK",
67
+ default: /* unallocated */
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
68
+ unallocated_encoding(s);
70
69
+ return;
71
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
70
}
72
SysBusDevice *sbd;
71
- rm |= (m << 4);
73
72
} else {
74
dev = qdev_new("pl011_luminary");
73
switch (size) {
75
+ object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
74
case 1:
76
sbd = SYS_BUS_DEVICE(dev);
75
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
77
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
76
}
78
sysbus_realize_and_unref(sbd, &error_fatal);
77
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
78
if (is_fp) {
80
DeviceState *enet;
79
- fpst = get_fpstatus_ptr(false);
81
80
+ fpst = get_fpstatus_ptr(is_fp16);
82
enet = qdev_new("stellaris_enet");
81
} else {
83
+ object_property_add_child(soc_container, "enet", OBJECT(enet));
82
fpst = NULL;
84
if (nd) {
83
}
85
qdev_set_nic_properties(enet, nd);
84
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
86
} else {
85
break;
86
}
87
case 0x5: /* FMLS */
88
- /* As usual for ARM, separate negation for fused multiply-add */
89
- gen_helper_vfp_negs(tcg_op, tcg_op);
90
- /* fall through */
91
case 0x1: /* FMLA */
92
- read_vec_element_i32(s, tcg_res, rd, pass, MO_32);
93
- gen_helper_vfp_muladds(tcg_res, tcg_op, tcg_idx, tcg_res, fpst);
94
+ read_vec_element_i32(s, tcg_res, rd, pass,
95
+ is_scalar ? size : MO_32);
96
+ switch (size) {
97
+ case 1:
98
+ if (opcode == 0x5) {
99
+ /* As usual for ARM, separate negation for fused
100
+ * multiply-add */
101
+ tcg_gen_xori_i32(tcg_op, tcg_op, 0x80008000);
102
+ }
103
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op, tcg_idx,
104
+ tcg_res, fpst);
105
+ break;
106
+ case 2:
107
+ if (opcode == 0x5) {
108
+ /* As usual for ARM, separate negation for
109
+ * fused multiply-add */
110
+ tcg_gen_xori_i32(tcg_op, tcg_op, 0x80000000);
111
+ }
112
+ gen_helper_vfp_muladds(tcg_res, tcg_op, tcg_idx,
113
+ tcg_res, fpst);
114
+ break;
115
+ default:
116
+ g_assert_not_reached();
117
+ }
118
break;
119
case 0x9: /* FMUL, FMULX */
120
- if (u) {
121
- gen_helper_vfp_mulxs(tcg_res, tcg_op, tcg_idx, fpst);
122
- } else {
123
- gen_helper_vfp_muls(tcg_res, tcg_op, tcg_idx, fpst);
124
+ switch (size) {
125
+ case 1:
126
+ if (u) {
127
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op, tcg_idx,
128
+ fpst);
129
+ } else {
130
+ g_assert_not_reached();
131
+ }
132
+ break;
133
+ case 2:
134
+ if (u) {
135
+ gen_helper_vfp_mulxs(tcg_res, tcg_op, tcg_idx, fpst);
136
+ } else {
137
+ gen_helper_vfp_muls(tcg_res, tcg_op, tcg_idx, fpst);
138
+ }
139
+ break;
140
+ default:
141
+ g_assert_not_reached();
142
}
143
break;
144
case 0xc: /* SQDMULH */
145
--
87
--
146
2.16.2
88
2.34.1
147
89
148
90
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
We support two different encodings for the AArch32 IMPDEF
2
CBAR register -- older cores like the Cortex A9, A7, A15
3
have this at 4, c15, c0, 0; newer cores like the
4
Cortex A35, A53, A57 and A72 have it at 1 c15 c0 0.
2
5
3
Half-precision flush to zero behaviour is controlled by a separate
6
When we implemented this we picked which encoding to
4
FZ16 bit in the FPCR. To handle this we pass a pointer to
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
5
fp_status_fp16 when working on half-precision operations. The value of
8
However this isn't right for three cases:
6
the presented FPCR is calculated from an amalgam of the two when read.
9
* the qemu-system-arm 'max' CPU, which is supposed to be
10
a variant on a Cortex-A57; it ought to use the same
11
encoding the A57 does and which the AArch64 'max'
12
exposes to AArch32 guest code
13
* the Cortex-R52, which is AArch32-only but has the CBAR
14
at the newer encoding (and where we incorrectly are
15
not yet setting ARM_FEATURE_CBAR_RO anyway)
16
* any possible future support for other v8 AArch32
17
only CPUs, or for supporting "boot the CPU into
18
AArch32 mode" on our existing cores like the A57 etc
7
19
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
20
Make the decision of the encoding be based on whether
21
the CPU implements the ARM_FEATURE_V8 flag instead.
22
23
This changes the behaviour only for the qemu-system-arm
24
'-cpu max'. We don't expect anybody to be relying on the
25
old behaviour because:
26
* it's not what the real hardware Cortex-A57 does
27
(and that's what our ID register claims we are)
28
* we don't implement the memory-mapped GICv3 support
29
which is the only thing that exists at the peripheral
30
base address pointed to by the register
31
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180227143852.11175-5-alex.bennee@linaro.org
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
35
---
13
target/arm/cpu.h | 32 ++++++++++++++++++++++------
36
target/arm/helper.c | 2 +-
14
target/arm/helper.c | 26 ++++++++++++++++++-----
37
1 file changed, 1 insertion(+), 1 deletion(-)
15
target/arm/translate-a64.c | 53 +++++++++++++++++++++++++---------------------
16
3 files changed, 75 insertions(+), 36 deletions(-)
17
38
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
23
/* scratch space when Tn are not sufficient. */
24
uint32_t scratch[8];
25
26
- /* fp_status is the "normal" fp status. standard_fp_status retains
27
- * values corresponding to the ARM "Standard FPSCR Value", ie
28
- * default-NaN, flush-to-zero, round-to-nearest and is used by
29
- * any operations (generally Neon) which the architecture defines
30
- * as controlled by the standard FPSCR value rather than the FPSCR.
31
+ /* There are a number of distinct float control structures:
32
+ *
33
+ * fp_status: is the "normal" fp status.
34
+ * fp_status_fp16: used for half-precision calculations
35
+ * standard_fp_status : the ARM "Standard FPSCR Value"
36
+ *
37
+ * Half-precision operations are governed by a separate
38
+ * flush-to-zero control bit in FPSCR:FZ16. We pass a separate
39
+ * status structure to control this.
40
+ *
41
+ * The "Standard FPSCR", ie default-NaN, flush-to-zero,
42
+ * round-to-nearest and is used by any operations (generally
43
+ * Neon) which the architecture defines as controlled by the
44
+ * standard FPSCR value rather than the FPSCR.
45
*
46
* To avoid having to transfer exception bits around, we simply
47
* say that the FPSCR cumulative exception flags are the logical
48
- * OR of the flags in the two fp statuses. This relies on the
49
+ * OR of the flags in the three fp statuses. This relies on the
50
* only thing which needs to read the exception flags being
51
* an explicit FPSCR read.
52
*/
53
float_status fp_status;
54
+ float_status fp_status_f16;
55
float_status standard_fp_status;
56
57
/* ZCR_EL[1-3] */
58
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
59
uint32_t vfp_get_fpscr(CPUARMState *env);
60
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
61
62
-/* For A64 the FPSCR is split into two logically distinct registers,
63
+/* FPCR, Floating Point Control Register
64
+ * FPSR, Floating Poiht Status Register
65
+ *
66
+ * For A64 the FPSCR is split into two logically distinct registers,
67
* FPCR and FPSR. However since they still use non-overlapping bits
68
* we store the underlying state in fpscr and just mask on read/write.
69
*/
70
#define FPSR_MASK 0xf800009f
71
#define FPCR_MASK 0x07f79f00
72
+
73
+#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
74
+#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
75
+#define FPCR_DN (1 << 25) /* Default NaN enable bit */
76
+
77
static inline uint32_t vfp_get_fpsr(CPUARMState *env)
78
{
79
return vfp_get_fpscr(env) & FPSR_MASK;
80
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
81
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/helper.c
41
--- a/target/arm/helper.c
83
+++ b/target/arm/helper.c
42
+++ b/target/arm/helper.c
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
85
| (env->vfp.vec_stride << 20);
44
* AArch64 cores we might need to add a specific feature flag
86
i = get_float_exception_flags(&env->vfp.fp_status);
45
* to indicate cores with "flavour 2" CBAR.
87
i |= get_float_exception_flags(&env->vfp.standard_fp_status);
46
*/
88
+ i |= get_float_exception_flags(&env->vfp.fp_status_f16);
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
89
fpscr |= vfp_exceptbits_from_host(i);
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
90
return fpscr;
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
91
}
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
92
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
51
| extract64(cpu->reset_cbar, 32, 12);
93
break;
94
}
95
set_float_rounding_mode(i, &env->vfp.fp_status);
96
+ set_float_rounding_mode(i, &env->vfp.fp_status_f16);
97
}
98
- if (changed & (1 << 24)) {
99
- set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
100
- set_flush_inputs_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
101
+ if (changed & FPCR_FZ16) {
102
+ bool ftz_enabled = val & FPCR_FZ16;
103
+ set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
104
+ set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
105
+ }
106
+ if (changed & FPCR_FZ) {
107
+ bool ftz_enabled = val & FPCR_FZ;
108
+ set_flush_to_zero(ftz_enabled, &env->vfp.fp_status);
109
+ set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status);
110
+ }
111
+ if (changed & FPCR_DN) {
112
+ bool dnan_enabled = val & FPCR_DN;
113
+ set_default_nan_mode(dnan_enabled, &env->vfp.fp_status);
114
+ set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16);
115
}
116
- if (changed & (1 << 25))
117
- set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status);
118
119
+ /* The exception flags are ORed together when we read fpscr so we
120
+ * only need to preserve the current state in one of our
121
+ * float_status values.
122
+ */
123
i = vfp_exceptbits_to_host(val);
124
set_float_exception_flags(i, &env->vfp.fp_status);
125
+ set_float_exception_flags(0, &env->vfp.fp_status_f16);
126
set_float_exception_flags(0, &env->vfp.standard_fp_status);
127
}
128
129
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/target/arm/translate-a64.c
132
+++ b/target/arm/translate-a64.c
133
@@ -XXX,XX +XXX,XX @@ static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
134
tcg_temp_free_i64(tmp);
135
}
136
137
-static TCGv_ptr get_fpstatus_ptr(void)
138
+static TCGv_ptr get_fpstatus_ptr(bool is_f16)
139
{
140
TCGv_ptr statusptr = tcg_temp_new_ptr();
141
int offset;
142
143
- /* In A64 all instructions (both FP and Neon) use the FPCR;
144
- * there is no equivalent of the A32 Neon "standard FPSCR value"
145
- * and all operations use vfp.fp_status.
146
+ /* In A64 all instructions (both FP and Neon) use the FPCR; there
147
+ * is no equivalent of the A32 Neon "standard FPSCR value".
148
+ * However half-precision operations operate under a different
149
+ * FZ16 flag and use vfp.fp_status_f16 instead of vfp.fp_status.
150
*/
151
- offset = offsetof(CPUARMState, vfp.fp_status);
152
+ if (is_f16) {
153
+ offset = offsetof(CPUARMState, vfp.fp_status_f16);
154
+ } else {
155
+ offset = offsetof(CPUARMState, vfp.fp_status);
156
+ }
157
tcg_gen_addi_ptr(statusptr, cpu_env, offset);
158
return statusptr;
159
}
160
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
161
bool cmp_with_zero, bool signal_all_nans)
162
{
163
TCGv_i64 tcg_flags = tcg_temp_new_i64();
164
- TCGv_ptr fpst = get_fpstatus_ptr();
165
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
166
167
if (is_double) {
168
TCGv_i64 tcg_vn, tcg_vm;
169
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
170
TCGv_i32 tcg_op;
171
TCGv_i32 tcg_res;
172
173
- fpst = get_fpstatus_ptr();
174
+ fpst = get_fpstatus_ptr(false);
175
tcg_op = read_fp_sreg(s, rn);
176
tcg_res = tcg_temp_new_i32();
177
178
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
179
return;
180
}
181
182
- fpst = get_fpstatus_ptr();
183
+ fpst = get_fpstatus_ptr(false);
184
tcg_op = read_fp_dreg(s, rn);
185
tcg_res = tcg_temp_new_i64();
186
187
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_single(DisasContext *s, int opcode,
188
TCGv_ptr fpst;
189
190
tcg_res = tcg_temp_new_i32();
191
- fpst = get_fpstatus_ptr();
192
+ fpst = get_fpstatus_ptr(false);
193
tcg_op1 = read_fp_sreg(s, rn);
194
tcg_op2 = read_fp_sreg(s, rm);
195
196
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_double(DisasContext *s, int opcode,
197
TCGv_ptr fpst;
198
199
tcg_res = tcg_temp_new_i64();
200
- fpst = get_fpstatus_ptr();
201
+ fpst = get_fpstatus_ptr(false);
202
tcg_op1 = read_fp_dreg(s, rn);
203
tcg_op2 = read_fp_dreg(s, rm);
204
205
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
206
{
207
TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
208
TCGv_i32 tcg_res = tcg_temp_new_i32();
209
- TCGv_ptr fpst = get_fpstatus_ptr();
210
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
211
212
tcg_op1 = read_fp_sreg(s, rn);
213
tcg_op2 = read_fp_sreg(s, rm);
214
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
215
{
216
TCGv_i64 tcg_op1, tcg_op2, tcg_op3;
217
TCGv_i64 tcg_res = tcg_temp_new_i64();
218
- TCGv_ptr fpst = get_fpstatus_ptr();
219
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
220
221
tcg_op1 = read_fp_dreg(s, rn);
222
tcg_op2 = read_fp_dreg(s, rm);
223
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
224
TCGv_ptr tcg_fpstatus;
225
TCGv_i32 tcg_shift;
226
227
- tcg_fpstatus = get_fpstatus_ptr();
228
+ tcg_fpstatus = get_fpstatus_ptr(false);
229
230
tcg_shift = tcg_const_i32(64 - scale);
231
232
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
233
TCGv_i32 tcg_elt1 = tcg_temp_new_i32();
234
TCGv_i32 tcg_elt2 = tcg_temp_new_i32();
235
TCGv_i32 tcg_elt3 = tcg_temp_new_i32();
236
- TCGv_ptr fpst = get_fpstatus_ptr();
237
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
238
239
assert(esize == 32);
240
assert(elements == 4);
241
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
242
}
243
244
size = extract32(size, 0, 1) ? 3 : 2;
245
- fpst = get_fpstatus_ptr();
246
+ fpst = get_fpstatus_ptr(false);
247
break;
248
default:
249
unallocated_encoding(s);
250
@@ -XXX,XX +XXX,XX @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
251
int fracbits, int size)
252
{
253
bool is_double = size == 3 ? true : false;
254
- TCGv_ptr tcg_fpst = get_fpstatus_ptr();
255
+ TCGv_ptr tcg_fpst = get_fpstatus_ptr(false);
256
TCGv_i32 tcg_shift = tcg_const_i32(fracbits);
257
TCGv_i64 tcg_int = tcg_temp_new_i64();
258
TCGMemOp mop = size | (is_signed ? MO_SIGN : 0);
259
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
260
261
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(FPROUNDING_ZERO));
262
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
263
- tcg_fpstatus = get_fpstatus_ptr();
264
+ tcg_fpstatus = get_fpstatus_ptr(false);
265
tcg_shift = tcg_const_i32(fracbits);
266
267
if (is_double) {
268
@@ -XXX,XX +XXX,XX @@ static void handle_3same_float(DisasContext *s, int size, int elements,
269
int fpopcode, int rd, int rn, int rm)
270
{
271
int pass;
272
- TCGv_ptr fpst = get_fpstatus_ptr();
273
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
274
275
for (pass = 0; pass < elements; pass++) {
276
if (size) {
277
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
278
return;
279
}
280
281
- fpst = get_fpstatus_ptr();
282
+ fpst = get_fpstatus_ptr(false);
283
284
if (is_double) {
285
TCGv_i64 tcg_op = tcg_temp_new_i64();
286
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode,
287
int size, int rn, int rd)
288
{
289
bool is_double = (size == 3);
290
- TCGv_ptr fpst = get_fpstatus_ptr();
291
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
292
293
if (is_double) {
294
TCGv_i64 tcg_op = tcg_temp_new_i64();
295
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
296
if (is_fcvt) {
297
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
298
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
299
- tcg_fpstatus = get_fpstatus_ptr();
300
+ tcg_fpstatus = get_fpstatus_ptr(false);
301
} else {
302
tcg_rmode = NULL;
303
tcg_fpstatus = NULL;
304
@@ -XXX,XX +XXX,XX @@ static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
305
306
/* Floating point operations need fpst */
307
if (opcode >= 0x58) {
308
- fpst = get_fpstatus_ptr();
309
+ fpst = get_fpstatus_ptr(false);
310
} else {
311
fpst = NULL;
312
}
313
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
314
}
315
316
if (need_fpstatus) {
317
- tcg_fpstatus = get_fpstatus_ptr();
318
+ tcg_fpstatus = get_fpstatus_ptr(false);
319
} else {
320
tcg_fpstatus = NULL;
321
}
322
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
323
}
324
325
if (is_fp) {
326
- fpst = get_fpstatus_ptr();
327
+ fpst = get_fpstatus_ptr(false);
328
} else {
329
fpst = NULL;
330
}
331
--
52
--
332
2.16.2
53
2.34.1
333
334
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The Cortex-R52 implements the Configuration Base Address Register
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
type, so that our implementation provides the register and the
4
associated qdev property.
2
5
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180227143852.11175-4-alex.bennee@linaro.org
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/cpu.h | 1 +
10
target/arm/tcg/cpu32.c | 1 +
9
1 file changed, 1 insertion(+)
11
1 file changed, 1 insertion(+)
10
12
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
15
--- a/target/arm/tcg/cpu32.c
14
+++ b/target/arm/cpu.h
16
+++ b/target/arm/tcg/cpu32.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct {
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
16
* Qn = regs[n].d[1]:regs[n].d[0]
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
17
* Dn = regs[n].d[0]
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
18
* Sn = regs[n].d[0] bits 31..0
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
19
+ * Hn = regs[n].d[0] bits 15..0
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
20
*
22
cpu->midr = 0x411fd133; /* r1p3 */
21
* This corresponds to the architecturally defined mapping between
23
cpu->revidr = 0x00000000;
22
* the two execution states, and means we do not need to explicitly
24
cpu->reset_fpsid = 0x41034023;
23
--
25
--
24
2.16.2
26
2.34.1
25
26
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
2
also by enabling the AUXCR feature which defines the ACTLR
3
and HACTLR registers. As is our usual practice, we make these
4
simple reads-as-zero stubs for now.
2
5
3
This covers the encoding group:
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
9
---
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 108 insertions(+)
4
12
5
Advanced SIMD scalar three same FP16
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
6
7
As all the helpers are already there it is simply a case of calling the
8
existing helpers in the scalar context.
9
10
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20180227143852.11175-31-alex.bennee@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/translate-a64.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++
16
1 file changed, 99 insertions(+)
17
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
15
--- a/target/arm/tcg/cpu32.c
21
+++ b/target/arm/translate-a64.c
16
+++ b/target/arm/tcg/cpu32.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
23
tcg_temp_free_i64(tcg_rd);
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
24
}
19
}
25
20
26
+/* AdvSIMD scalar three same FP16
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
27
+ * 31 30 29 28 24 23 22 21 20 16 15 14 13 11 10 9 5 4 0
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
28
+ * +-----+---+-----------+---+-----+------+-----+--------+---+----+----+
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
29
+ * | 0 1 | U | 1 1 1 1 0 | a | 1 0 | Rm | 0 0 | opcode | 1 | Rn | Rd |
24
+ { .name = "IMP_ATCMREGIONR",
30
+ * +-----+---+-----------+---+-----+------+-----+--------+---+----+----+
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
31
+ * v: 0101 1110 0100 0000 0000 0100 0000 0000 => 5e400400
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
32
+ * m: 1101 1111 0110 0000 1100 0100 0000 0000 => df60c400
27
+ { .name = "IMP_BTCMREGIONR",
33
+ */
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
34
+static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
35
+ uint32_t insn)
30
+ { .name = "IMP_CTCMREGIONR",
36
+{
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
37
+ int rd = extract32(insn, 0, 5);
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
38
+ int rn = extract32(insn, 5, 5);
33
+ { .name = "IMP_CSCTLR",
39
+ int opcode = extract32(insn, 11, 3);
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
40
+ int rm = extract32(insn, 16, 5);
35
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
41
+ bool u = extract32(insn, 29, 1);
36
+ { .name = "IMP_BPCTLR",
42
+ bool a = extract32(insn, 23, 1);
37
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
43
+ int fpopcode = opcode | (a << 3) | (u << 4);
38
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
44
+ TCGv_ptr fpst;
39
+ { .name = "IMP_MEMPROTCLR",
45
+ TCGv_i32 tcg_op1;
40
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2,
46
+ TCGv_i32 tcg_op2;
41
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
47
+ TCGv_i32 tcg_res;
42
+ { .name = "IMP_SLAVEPCTLR",
48
+
43
+ .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0,
49
+ switch (fpopcode) {
44
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
50
+ case 0x03: /* FMULX */
45
+ { .name = "IMP_PERIPHREGIONR",
51
+ case 0x04: /* FCMEQ (reg) */
46
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
52
+ case 0x07: /* FRECPS */
47
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
53
+ case 0x0f: /* FRSQRTS */
48
+ { .name = "IMP_FLASHIFREGIONR",
54
+ case 0x14: /* FCMGE (reg) */
49
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1,
55
+ case 0x15: /* FACGE */
50
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
56
+ case 0x1a: /* FABD */
51
+ { .name = "IMP_BUILDOPTR",
57
+ case 0x1c: /* FCMGT (reg) */
52
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
58
+ case 0x1d: /* FACGT */
53
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
59
+ break;
54
+ { .name = "IMP_PINOPTR",
60
+ default:
55
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
61
+ unallocated_encoding(s);
56
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
62
+ return;
57
+ { .name = "IMP_QOSR",
63
+ }
58
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1,
64
+
59
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
65
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
60
+ { .name = "IMP_BUSTIMEOUTR",
66
+ unallocated_encoding(s);
61
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2,
67
+ }
62
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
68
+
63
+ { .name = "IMP_INTMONR",
69
+ if (!fp_access_check(s)) {
64
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 4,
70
+ return;
65
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
71
+ }
66
+ { .name = "IMP_ICERR0",
72
+
67
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 0,
73
+ fpst = get_fpstatus_ptr(true);
68
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
74
+
69
+ { .name = "IMP_ICERR1",
75
+ tcg_op1 = tcg_temp_new_i32();
70
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 1,
76
+ tcg_op2 = tcg_temp_new_i32();
71
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
77
+ tcg_res = tcg_temp_new_i32();
72
+ { .name = "IMP_DCERR0",
78
+
73
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 0,
79
+ read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
74
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
80
+ read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
75
+ { .name = "IMP_DCERR1",
81
+
76
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 1,
82
+ switch (fpopcode) {
77
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
83
+ case 0x03: /* FMULX */
78
+ { .name = "IMP_TCMERR0",
84
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
79
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 0,
85
+ break;
80
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
86
+ case 0x04: /* FCMEQ (reg) */
81
+ { .name = "IMP_TCMERR1",
87
+ gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
82
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 1,
88
+ break;
83
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
89
+ case 0x07: /* FRECPS */
84
+ { .name = "IMP_TCMSYNDR0",
90
+ gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
85
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 2,
91
+ break;
86
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
92
+ case 0x0f: /* FRSQRTS */
87
+ { .name = "IMP_TCMSYNDR1",
93
+ gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
88
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 3,
94
+ break;
89
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
95
+ case 0x14: /* FCMGE (reg) */
90
+ { .name = "IMP_FLASHERR0",
96
+ gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
91
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 0,
97
+ break;
92
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
98
+ case 0x15: /* FACGE */
93
+ { .name = "IMP_FLASHERR1",
99
+ gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
94
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 1,
100
+ break;
95
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
101
+ case 0x1a: /* FABD */
96
+ { .name = "IMP_CDBGDR0",
102
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
97
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 0,
103
+ tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
98
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
104
+ break;
99
+ { .name = "IMP_CBDGBR1",
105
+ case 0x1c: /* FCMGT (reg) */
100
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 1,
106
+ gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
101
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
107
+ break;
102
+ { .name = "IMP_TESTR0",
108
+ case 0x1d: /* FACGT */
103
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 0,
109
+ gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
104
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
110
+ break;
105
+ { .name = "IMP_TESTR1",
111
+ default:
106
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 1,
112
+ g_assert_not_reached();
107
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
113
+ }
108
+ { .name = "IMP_CDBGDCI",
114
+
109
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 15, .opc2 = 0,
115
+ write_fp_sreg(s, rd, tcg_res);
110
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
111
+ { .name = "IMP_CDBGDCT",
112
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 0,
113
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
114
+ { .name = "IMP_CDBGICT",
115
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 1,
116
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
117
+ { .name = "IMP_CDBGDCD",
118
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 0,
119
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
120
+ { .name = "IMP_CDBGICD",
121
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 1,
122
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
123
+};
116
+
124
+
117
+
125
+
118
+ tcg_temp_free_i32(tcg_res);
126
static void cortex_r52_initfn(Object *obj)
119
+ tcg_temp_free_i32(tcg_op1);
127
{
120
+ tcg_temp_free_i32(tcg_op2);
128
ARMCPU *cpu = ARM_CPU(obj);
121
+ tcg_temp_free_ptr(fpst);
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
122
+}
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
134
cpu->midr = 0x411fd133; /* r1p3 */
135
cpu->revidr = 0x00000000;
136
cpu->reset_fpsid = 0x41034023;
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
138
139
cpu->pmsav7_dregion = 16;
140
cpu->pmsav8r_hdregion = 16;
123
+
141
+
124
static void handle_2misc_64(DisasContext *s, int opcode, bool u,
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
125
TCGv_i64 tcg_rd, TCGv_i64 tcg_rn,
143
}
126
TCGv_i32 tcg_rmode, TCGv_ptr tcg_fpstatus)
144
127
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
145
static void cortex_r5f_initfn(Object *obj)
128
{ 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
129
{ 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
130
{ 0x0e780800, 0x8f7e0c00, disas_simd_two_reg_misc_fp16 },
131
+ { 0x5e400400, 0xdf60c400, disas_simd_scalar_three_reg_same_fp16 },
132
{ 0x00000000, 0x00000000, NULL }
133
};
134
135
--
146
--
136
2.16.2
147
2.34.1
137
138
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Architecturally, the AArch32 MSR/MRS to/from banked register
2
instructions are UNPREDICTABLE for attempts to access a banked
3
register that the guest could access in a more direct way (e.g.
4
using this insn to access r8_fiq when already in FIQ mode). QEMU has
5
chosen to UNDEF on all of these.
2
6
3
This implements the half-precision variants of the across vector
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
4
reduction operations. This involves a re-factor of the reduction code
8
out that real hardware permits this, with the same effect as if the
5
which more closely matches the ARM ARM order (and handles 8 element
9
guest had directly written to SPSR. Further, there is some
6
reductions).
10
guest code out there that assumes it can do this, because it
11
happens to work on hardware: an example Cortex-R52 startup code
12
fragment uses this, and it got copied into various other places,
13
including Zephyr. Zephyr was fixed to not use this:
14
https://github.com/zephyrproject-rtos/zephyr/issues/47330
15
but other examples are still out there, like the selftest
16
binary for the MPS3-AN536.
7
17
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
18
For convenience of being able to run guest code, permit
19
this UNPREDICTABLE access instead of UNDEFing it.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180227143852.11175-7-alex.bennee@linaro.org
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
24
---
13
target/arm/helper-a64.h | 4 ++
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
14
target/arm/helper-a64.c | 18 ++++++
26
target/arm/tcg/translate.c | 19 +++++++++++------
15
target/arm/translate-a64.c | 140 ++++++++++++++++++++++++++++-----------------
27
2 files changed, 43 insertions(+), 19 deletions(-)
16
3 files changed, 109 insertions(+), 53 deletions(-)
17
28
18
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
19
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-a64.h
31
--- a/target/arm/tcg/op_helper.c
21
+++ b/target/arm/helper-a64.h
32
+++ b/target/arm/tcg/op_helper.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(paired_cmpxchg64_le_parallel, TCG_CALL_NO_WG,
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
23
DEF_HELPER_FLAGS_4(paired_cmpxchg64_be, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
34
*/
24
DEF_HELPER_FLAGS_4(paired_cmpxchg64_be_parallel, TCG_CALL_NO_WG,
35
int curmode = env->uncached_cpsr & CPSR_M;
25
i64, env, i64, i64, i64)
36
26
+DEF_HELPER_FLAGS_3(advsimd_maxh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
37
- if (regno == 17) {
27
+DEF_HELPER_FLAGS_3(advsimd_minh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
28
+DEF_HELPER_FLAGS_3(advsimd_maxnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
29
+DEF_HELPER_FLAGS_3(advsimd_minnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
40
- goto undef;
30
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
31
index XXXXXXX..XXXXXXX 100644
42
+ /*
32
--- a/target/arm/helper-a64.c
43
+ * Handle Hyp target regs first because some are special cases
33
+++ b/target/arm/helper-a64.c
44
+ * which don't want the usual "not accessible from tgtmode" check.
34
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be_parallel)(CPUARMState *env, uint64_t addr,
45
+ */
35
{
46
+ switch (regno) {
36
return do_paired_cmpxchg64_be(env, addr, new_lo, new_hi, true, GETPC());
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
37
}
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
38
+
49
+ goto undef;
39
+/*
50
+ }
40
+ * AdvSIMD half-precision
41
+ */
42
+
43
+#define ADVSIMD_HELPER(name, suffix) HELPER(glue(glue(advsimd_, name), suffix))
44
+
45
+#define ADVSIMD_HALFOP(name) \
46
+float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
47
+{ \
48
+ float_status *fpst = fpstp; \
49
+ return float16_ ## name(a, b, fpst); \
50
+}
51
+
52
+ADVSIMD_HALFOP(min)
53
+ADVSIMD_HALFOP(max)
54
+ADVSIMD_HALFOP(minnum)
55
+ADVSIMD_HALFOP(maxnum)
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
61
tcg_temp_free_i64(tcg_resh);
62
}
63
64
-static void do_minmaxop(DisasContext *s, TCGv_i32 tcg_elt1, TCGv_i32 tcg_elt2,
65
- int opc, bool is_min, TCGv_ptr fpst)
66
+/*
67
+ * do_reduction_op helper
68
+ *
69
+ * This mirrors the Reduce() pseudocode in the ARM ARM. It is
70
+ * important for correct NaN propagation that we do these
71
+ * operations in exactly the order specified by the pseudocode.
72
+ *
73
+ * This is a recursive function, TCG temps should be freed by the
74
+ * calling function once it is done with the values.
75
+ */
76
+static TCGv_i32 do_reduction_op(DisasContext *s, int fpopcode, int rn,
77
+ int esize, int size, int vmap, TCGv_ptr fpst)
78
{
79
- /* Helper function for disas_simd_across_lanes: do a single precision
80
- * min/max operation on the specified two inputs,
81
- * and return the result in tcg_elt1.
82
- */
83
- if (opc == 0xc) {
84
- if (is_min) {
85
- gen_helper_vfp_minnums(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
86
- } else {
87
- gen_helper_vfp_maxnums(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
88
- }
89
+ if (esize == size) {
90
+ int element;
91
+ TCGMemOp msize = esize == 16 ? MO_16 : MO_32;
92
+ TCGv_i32 tcg_elem;
93
+
94
+ /* We should have one register left here */
95
+ assert(ctpop8(vmap) == 1);
96
+ element = ctz32(vmap);
97
+ assert(element < 8);
98
+
99
+ tcg_elem = tcg_temp_new_i32();
100
+ read_vec_element_i32(s, tcg_elem, rn, element, msize);
101
+ return tcg_elem;
102
} else {
103
- assert(opc == 0xf);
104
- if (is_min) {
105
- gen_helper_vfp_mins(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
106
- } else {
107
- gen_helper_vfp_maxs(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
108
+ int bits = size / 2;
109
+ int shift = ctpop8(vmap) / 2;
110
+ int vmap_lo = (vmap >> shift) & vmap;
111
+ int vmap_hi = (vmap & ~vmap_lo);
112
+ TCGv_i32 tcg_hi, tcg_lo, tcg_res;
113
+
114
+ tcg_hi = do_reduction_op(s, fpopcode, rn, esize, bits, vmap_hi, fpst);
115
+ tcg_lo = do_reduction_op(s, fpopcode, rn, esize, bits, vmap_lo, fpst);
116
+ tcg_res = tcg_temp_new_i32();
117
+
118
+ switch (fpopcode) {
119
+ case 0x0c: /* fmaxnmv half-precision */
120
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_lo, tcg_hi, fpst);
121
+ break;
51
+ break;
122
+ case 0x0f: /* fmaxv half-precision */
52
+ case 13:
123
+ gen_helper_advsimd_maxh(tcg_res, tcg_lo, tcg_hi, fpst);
53
+ if (curmode != ARM_CPU_MODE_MON) {
124
+ break;
54
+ goto undef;
125
+ case 0x1c: /* fminnmv half-precision */
55
+ }
126
+ gen_helper_advsimd_minnumh(tcg_res, tcg_lo, tcg_hi, fpst);
127
+ break;
128
+ case 0x1f: /* fminv half-precision */
129
+ gen_helper_advsimd_minh(tcg_res, tcg_lo, tcg_hi, fpst);
130
+ break;
131
+ case 0x2c: /* fmaxnmv */
132
+ gen_helper_vfp_maxnums(tcg_res, tcg_lo, tcg_hi, fpst);
133
+ break;
134
+ case 0x2f: /* fmaxv */
135
+ gen_helper_vfp_maxs(tcg_res, tcg_lo, tcg_hi, fpst);
136
+ break;
137
+ case 0x3c: /* fminnmv */
138
+ gen_helper_vfp_minnums(tcg_res, tcg_lo, tcg_hi, fpst);
139
+ break;
140
+ case 0x3f: /* fminv */
141
+ gen_helper_vfp_mins(tcg_res, tcg_lo, tcg_hi, fpst);
142
+ break;
56
+ break;
143
+ default:
57
+ default:
144
+ g_assert_not_reached();
58
+ g_assert_not_reached();
145
}
59
}
146
+
60
return;
147
+ tcg_temp_free_i32(tcg_hi);
148
+ tcg_temp_free_i32(tcg_lo);
149
+ return tcg_res;
150
}
61
}
151
}
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
152
63
}
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
64
}
154
break;
65
155
case 0xc: /* FMAXNMV, FMINNMV */
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
156
case 0xf: /* FMAXV, FMINV */
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
157
- if (!is_u || !is_q || extract32(size, 0, 1)) {
68
- if (curmode != ARM_CPU_MODE_MON) {
158
- unallocated_encoding(s);
69
- goto undef;
159
- return;
160
- }
70
- }
161
- /* Bit 1 of size field encodes min vs max, and actual size is always
71
- }
162
- * 32 bits: adjust the size variable so following code can rely on it
72
-
163
+ /* Bit 1 of size field encodes min vs max and the actual size
73
return;
164
+ * depends on the encoding of the U bit. If not set (and FP16
74
165
+ * enabled) then we do half-precision float instead of single
75
undef:
166
+ * precision.
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
167
*/
77
168
is_min = extract32(size, 1, 1);
78
switch (regno) {
169
is_fp = true;
79
case 16: /* SPSRs */
170
- size = 2;
80
- env->banked_spsr[bank_number(tgtmode)] = value;
171
+ if (!is_u && arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
172
+ size = 1;
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
173
+ } else if (!is_u || !is_q || extract32(size, 0, 1)) {
83
+ env->spsr = value;
174
+ unallocated_encoding(s);
175
+ return;
176
+ } else {
84
+ } else {
177
+ size = 2;
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
178
+ }
86
+ }
179
break;
87
break;
180
default:
88
case 17: /* ELR_Hyp */
181
unallocated_encoding(s);
89
env->elr_el[2] = value;
182
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
90
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
183
91
92
switch (regno) {
93
case 16: /* SPSRs */
94
- return env->banked_spsr[bank_number(tgtmode)];
95
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
96
+ /* Only happens for SPSR_Hyp access in Hyp mode */
97
+ return env->spsr;
98
+ } else {
99
+ return env->banked_spsr[bank_number(tgtmode)];
100
+ }
101
case 17: /* ELR_Hyp */
102
return env->elr_el[2];
103
case 13:
104
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/tcg/translate.c
107
+++ b/target/arm/tcg/translate.c
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
109
break;
110
case ARM_CPU_MODE_HYP:
111
/*
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
114
- * can be accessed also from Hyp mode, so forbid accesses from
115
- * EL0 or EL1.
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
117
+ * can forbid accesses from EL2 or below.
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
119
+ * accesses from EL0 or EL1.
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
122
+ * mode. However there is some real-world code that will do
123
+ * it because at least some hardware happens to permit the
124
+ * access. (Notably a standard Cortex-R52 startup code fragment
125
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
126
+ * this (incorrect) guest code to run.
127
*/
128
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
129
- (s->current_el < 3 && *regno != 17)) {
130
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
131
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
132
goto undef;
184
}
133
}
185
} else {
134
break;
186
- /* Floating point ops which work on 32 bit (single) intermediates.
187
+ /* Floating point vector reduction ops which work across 32
188
+ * bit (single) or 16 bit (half-precision) intermediates.
189
* Note that correct NaN propagation requires that we do these
190
* operations in exactly the order specified by the pseudocode.
191
*/
192
- TCGv_i32 tcg_elt1 = tcg_temp_new_i32();
193
- TCGv_i32 tcg_elt2 = tcg_temp_new_i32();
194
- TCGv_i32 tcg_elt3 = tcg_temp_new_i32();
195
- TCGv_ptr fpst = get_fpstatus_ptr(false);
196
-
197
- assert(esize == 32);
198
- assert(elements == 4);
199
-
200
- read_vec_element(s, tcg_elt, rn, 0, MO_32);
201
- tcg_gen_extrl_i64_i32(tcg_elt1, tcg_elt);
202
- read_vec_element(s, tcg_elt, rn, 1, MO_32);
203
- tcg_gen_extrl_i64_i32(tcg_elt2, tcg_elt);
204
-
205
- do_minmaxop(s, tcg_elt1, tcg_elt2, opcode, is_min, fpst);
206
-
207
- read_vec_element(s, tcg_elt, rn, 2, MO_32);
208
- tcg_gen_extrl_i64_i32(tcg_elt2, tcg_elt);
209
- read_vec_element(s, tcg_elt, rn, 3, MO_32);
210
- tcg_gen_extrl_i64_i32(tcg_elt3, tcg_elt);
211
-
212
- do_minmaxop(s, tcg_elt2, tcg_elt3, opcode, is_min, fpst);
213
-
214
- do_minmaxop(s, tcg_elt1, tcg_elt2, opcode, is_min, fpst);
215
-
216
- tcg_gen_extu_i32_i64(tcg_res, tcg_elt1);
217
- tcg_temp_free_i32(tcg_elt1);
218
- tcg_temp_free_i32(tcg_elt2);
219
- tcg_temp_free_i32(tcg_elt3);
220
+ TCGv_ptr fpst = get_fpstatus_ptr(size == MO_16);
221
+ int fpopcode = opcode | is_min << 4 | is_u << 5;
222
+ int vmap = (1 << elements) - 1;
223
+ TCGv_i32 tcg_res32 = do_reduction_op(s, fpopcode, rn, esize,
224
+ (is_q ? 128 : 64), vmap, fpst);
225
+ tcg_gen_extu_i32_i64(tcg_res, tcg_res32);
226
+ tcg_temp_free_i32(tcg_res32);
227
tcg_temp_free_ptr(fpst);
228
}
229
230
--
135
--
231
2.16.2
136
2.34.1
232
233
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
We currently guard the CFG3 register read with
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
which is clearly wrong as it is never true.
2
4
3
Use 8 dummy cycles (4 dummy bytes) with the QIOR/QIOR4 commands in legacy mode
5
This register is present on all board types except AN524
4
for matching what is expected by Micron (Numonyx) flashes (the default target
6
and AN527; correct the condition.
5
flash type of the QSPI).
6
7
7
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
8
Tested-by: Alistair Francis <alistair.francis@xilinx.com>
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
10
Message-id: 20180223232233.31482-3-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
12
---
13
---
13
hw/ssi/xilinx_spips.c | 2 +-
14
hw/misc/mps2-scc.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
16
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/xilinx_spips.c
19
--- a/hw/misc/mps2-scc.c
19
+++ b/hw/ssi/xilinx_spips.c
20
+++ b/hw/misc/mps2-scc.c
20
@@ -XXX,XX +XXX,XX @@ static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
21
return 2;
22
r = s->cfg2;
22
case QIOR:
23
break;
23
case QIOR_4:
24
case A_CFG3:
24
- return 5;
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
25
+ return 4;
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
26
default:
27
/* CFG3 reserved on AN524 */
27
return -1;
28
goto bad_offset;
28
}
29
}
29
--
30
--
30
2.16.2
31
2.34.1
31
32
32
33
diff view generated by jsdifflib
Deleted patch
1
From: Corey Minyard <cminyard@mvista.com>
2
1
3
Signed-off-by: Corey Minyard <cminyard@mvista.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
6
Message-id: 20180227104903.21353-2-linus.walleij@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
include/hw/i2c/i2c.h | 6 ++----
10
hw/i2c/core.c | 3 +--
11
2 files changed, 3 insertions(+), 6 deletions(-)
12
13
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/i2c/i2c.h
16
+++ b/include/hw/i2c/i2c.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct I2CSlave I2CSlave;
18
#define I2C_SLAVE_GET_CLASS(obj) \
19
OBJECT_GET_CLASS(I2CSlaveClass, (obj), TYPE_I2C_SLAVE)
20
21
-typedef struct I2CSlaveClass
22
-{
23
+typedef struct I2CSlaveClass {
24
DeviceClass parent_class;
25
26
/* Callbacks provided by the device. */
27
@@ -XXX,XX +XXX,XX @@ typedef struct I2CSlaveClass
28
int (*event)(I2CSlave *s, enum i2c_event event);
29
} I2CSlaveClass;
30
31
-struct I2CSlave
32
-{
33
+struct I2CSlave {
34
DeviceState qdev;
35
36
/* Remaining fields for internal use by the I2C code. */
37
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/i2c/core.c
40
+++ b/hw/i2c/core.c
41
@@ -XXX,XX +XXX,XX @@ struct I2CNode {
42
43
#define I2C_BROADCAST 0x00
44
45
-struct I2CBus
46
-{
47
+struct I2CBus {
48
BusState qbus;
49
QLIST_HEAD(, I2CNode) current_devs;
50
uint8_t saved_address;
51
--
52
2.16.2
53
54
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The MPS SCC device has a lot of different flavours for the various
2
different MPS FPGA images, which look mostly similar but have
3
differences in how particular registers are handled. Currently we
4
deal with this with a lot of open-coded checks on scc_partno(), but
5
as we add more board types this is getting a bit hard to read.
2
6
3
These use the generic float16_compare functionality which in turn uses
7
Factor out the conditions into some functions which we can
4
the common float_compare code from the softfloat re-factor.
8
give more descriptive names to.
5
9
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180227143852.11175-11-alex.bennee@linaro.org
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/helper-a64.h | 5 +++++
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
12
target/arm/helper-a64.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++
16
1 file changed, 31 insertions(+), 14 deletions(-)
13
target/arm/translate-a64.c | 15 ++++++++++++++
14
3 files changed, 69 insertions(+)
15
17
16
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-a64.h
20
--- a/hw/misc/mps2-scc.c
19
+++ b/target/arm/helper-a64.h
21
+++ b/hw/misc/mps2-scc.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_addh, f16, f16, f16, ptr)
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
21
DEF_HELPER_3(advsimd_subh, f16, f16, f16, ptr)
23
return extract32(s->id, 4, 8);
22
DEF_HELPER_3(advsimd_mulh, f16, f16, f16, ptr)
24
}
23
DEF_HELPER_3(advsimd_divh, f16, f16, f16, ptr)
25
24
+DEF_HELPER_3(advsimd_ceq_f16, i32, f16, f16, ptr)
26
+/* Is CFG_REG2 present? */
25
+DEF_HELPER_3(advsimd_cge_f16, i32, f16, f16, ptr)
27
+static bool have_cfg2(MPS2SCC *s)
26
+DEF_HELPER_3(advsimd_cgt_f16, i32, f16, f16, ptr)
27
+DEF_HELPER_3(advsimd_acge_f16, i32, f16, f16, ptr)
28
+DEF_HELPER_3(advsimd_acgt_f16, i32, f16, f16, ptr)
29
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/helper-a64.c
32
+++ b/target/arm/helper-a64.c
33
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(min)
34
ADVSIMD_HALFOP(max)
35
ADVSIMD_HALFOP(minnum)
36
ADVSIMD_HALFOP(maxnum)
37
+
38
+/*
39
+ * Floating point comparisons produce an integer result. Softfloat
40
+ * routines return float_relation types which we convert to the 0/-1
41
+ * Neon requires.
42
+ */
43
+
44
+#define ADVSIMD_CMPRES(test) (test) ? 0xffff : 0
45
+
46
+uint32_t HELPER(advsimd_ceq_f16)(float16 a, float16 b, void *fpstp)
47
+{
28
+{
48
+ float_status *fpst = fpstp;
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
49
+ int compare = float16_compare_quiet(a, b, fpst);
50
+ return ADVSIMD_CMPRES(compare == float_relation_equal);
51
+}
30
+}
52
+
31
+
53
+uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
32
+/* Is CFG_REG3 present? */
33
+static bool have_cfg3(MPS2SCC *s)
54
+{
34
+{
55
+ float_status *fpst = fpstp;
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
56
+ int compare = float16_compare(a, b, fpst);
57
+ return ADVSIMD_CMPRES(compare == float_relation_greater ||
58
+ compare == float_relation_equal);
59
+}
36
+}
60
+
37
+
61
+uint32_t HELPER(advsimd_cgt_f16)(float16 a, float16 b, void *fpstp)
38
+/* Is CFG_REG5 present? */
39
+static bool have_cfg5(MPS2SCC *s)
62
+{
40
+{
63
+ float_status *fpst = fpstp;
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
64
+ int compare = float16_compare(a, b, fpst);
65
+ return ADVSIMD_CMPRES(compare == float_relation_greater);
66
+}
42
+}
67
+
43
+
68
+uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
44
+/* Is CFG_REG6 present? */
45
+static bool have_cfg6(MPS2SCC *s)
69
+{
46
+{
70
+ float_status *fpst = fpstp;
47
+ return scc_partno(s) == 0x524;
71
+ float16 f0 = float16_abs(a);
72
+ float16 f1 = float16_abs(b);
73
+ int compare = float16_compare(f0, f1, fpst);
74
+ return ADVSIMD_CMPRES(compare == float_relation_greater ||
75
+ compare == float_relation_equal);
76
+}
48
+}
77
+
49
+
78
+uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
79
+{
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
80
+ float_status *fpst = fpstp;
52
*/
81
+ float16 f0 = float16_abs(a);
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
82
+ float16 f1 = float16_abs(b);
54
r = s->cfg1;
83
+ int compare = float16_compare(f0, f1, fpst);
55
break;
84
+ return ADVSIMD_CMPRES(compare == float_relation_greater);
56
case A_CFG2:
85
+}
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
86
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
58
- /* CFG2 reserved on other boards */
87
index XXXXXXX..XXXXXXX 100644
59
+ if (!have_cfg2(s)) {
88
--- a/target/arm/translate-a64.c
60
goto bad_offset;
89
+++ b/target/arm/translate-a64.c
61
}
90
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
62
r = s->cfg2;
91
case 0x2: /* FADD */
63
break;
92
gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
64
case A_CFG3:
93
break;
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
94
+ case 0x4: /* FCMEQ */
66
- /* CFG3 reserved on AN524 */
95
+ gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
67
+ if (!have_cfg3(s)) {
96
+ break;
68
goto bad_offset;
97
case 0x6: /* FMAX */
69
}
98
gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
70
/* These are user-settable DIP switches on the board. We don't
99
break;
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
100
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
72
r = s->cfg4;
101
case 0x13: /* FMUL */
73
break;
102
gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
74
case A_CFG5:
103
break;
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
104
+ case 0x14: /* FCMGE */
76
- /* CFG5 reserved on other boards */
105
+ gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
77
+ if (!have_cfg5(s)) {
106
+ break;
78
goto bad_offset;
107
+ case 0x15: /* FACGE */
79
}
108
+ gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
80
r = s->cfg5;
109
+ break;
81
break;
110
case 0x17: /* FDIV */
82
case A_CFG6:
111
gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
83
- if (scc_partno(s) != 0x524) {
112
break;
84
- /* CFG6 reserved on other boards */
113
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
85
+ if (!have_cfg6(s)) {
114
gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
86
goto bad_offset;
115
tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
87
}
116
break;
88
r = s->cfg6;
117
+ case 0x1c: /* FCMGT */
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
118
+ gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
90
}
119
+ break;
91
break;
120
+ case 0x1d: /* FACGT */
92
case A_CFG2:
121
+ gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
122
+ break;
94
- /* CFG2 reserved on other boards */
123
default:
95
+ if (!have_cfg2(s)) {
124
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
96
goto bad_offset;
125
__func__, insn, fpopcode, s->pc);
97
}
98
/* AN524: QSPI Select signal */
99
s->cfg2 = value;
100
break;
101
case A_CFG5:
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
103
- /* CFG5 reserved on other boards */
104
+ if (!have_cfg5(s)) {
105
goto bad_offset;
106
}
107
/* AN524: ACLK frequency in Hz */
108
s->cfg5 = value;
109
break;
110
case A_CFG6:
111
- if (scc_partno(s) != 0x524) {
112
- /* CFG6 reserved on other boards */
113
+ if (!have_cfg6(s)) {
114
goto bad_offset;
115
}
116
/* AN524: Clock divider for BRAM */
126
--
117
--
127
2.16.2
118
2.34.1
128
119
129
120
diff view generated by jsdifflib
1
From: Linus Walleij <linus.walleij@linaro.org>
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
2
minor differences in the behaviour of the CFG registers depending on
3
This adds support for emulating the Silicon Image SII9022 DVI/HDMI
3
the image. In many cases we don't really care about the functionality
4
bridge. It's not very clever right now, it just acknowledges
4
controlled by these registers and a reads-as-written or similar
5
the switch into DDC I2C mode and back. Combining this with the
5
behaviour is sufficient for the moment.
6
existing DDC I2C emulation gives the right behavior on the Versatile
6
7
Express emulation passing through the QEMU EDID to the emulated
7
For the AN536 the required behaviour is:
8
platform.
8
9
9
* A_CFG0 has CPU reset and halt bits
10
Cc: Peter Maydell <peter.maydell@linaro.org>
10
- implement as reads-as-written for the moment
11
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
11
* A_CFG1 has flash or ATCM address 0 remap handling
12
Message-id: 20180227104903.21353-5-linus.walleij@linaro.org
12
- QEMU doesn't model this; implement as reads-as-written
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
* A_CFG2 has QSPI select (like AN524)
14
[PMM: explictly reset ddc_req/ddc_skip_finish/ddc]
14
- implemented (no behaviour, as with AN524)
15
* A_CFG3 is MCC_MSB_ADDR "additional MCC addressing bits"
16
- QEMU doesn't care about these, so use the existing
17
RAZ behaviour for convenience
18
* A_CFG4 is board rev (like all other images)
19
- no change needed
20
* A_CFG5 is ACLK frq in hz (like AN524)
21
- implemented as reads-as-written, as for other boards
22
* A_CFG6 is core 0 vector table base address
23
- implemented as reads-as-written for the moment
24
* A_CFG7 is core 1 vector table base address
25
- implemented as reads-as-written for the moment
26
27
Make the changes necessary for this; leave TODO comments where
28
appropriate to indicate where we might want to come back and
29
implement things like CPU reset.
30
31
The other aspects of the device specific to this FPGA image (like the
32
values of the board ID and similar registers) will be set via the
33
device's qdev properties.
34
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
16
---
39
---
17
hw/display/Makefile.objs | 1 +
40
include/hw/misc/mps2-scc.h | 1 +
18
hw/display/sii9022.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
19
hw/display/trace-events | 5 ++
42
2 files changed, 92 insertions(+), 10 deletions(-)
20
3 files changed, 197 insertions(+)
43
21
create mode 100644 hw/display/sii9022.c
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
22
23
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
24
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/display/Makefile.objs
46
--- a/include/hw/misc/mps2-scc.h
26
+++ b/hw/display/Makefile.objs
47
+++ b/include/hw/misc/mps2-scc.h
27
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
28
common-obj-$(CONFIG_G364FB) += g364fb.o
49
uint32_t cfg4;
29
common-obj-$(CONFIG_JAZZ_LED) += jazz_led.o
50
uint32_t cfg5;
30
common-obj-$(CONFIG_PL110) += pl110.o
51
uint32_t cfg6;
31
+common-obj-$(CONFIG_SII9022) += sii9022.o
52
+ uint32_t cfg7;
32
common-obj-$(CONFIG_SSD0303) += ssd0303.o
53
uint32_t cfgdata_rtn;
33
common-obj-$(CONFIG_SSD0323) += ssd0323.o
54
uint32_t cfgdata_out;
34
common-obj-$(CONFIG_XEN) += xenfb.o
55
uint32_t cfgctrl;
35
diff --git a/hw/display/sii9022.c b/hw/display/sii9022.c
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
36
new file mode 100644
57
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX
58
--- a/hw/misc/mps2-scc.c
38
--- /dev/null
59
+++ b/hw/misc/mps2-scc.c
39
+++ b/hw/display/sii9022.c
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
40
@@ -XXX,XX +XXX,XX @@
61
REG32(CFG4, 0x10)
41
+/*
62
REG32(CFG5, 0x14)
42
+ * Silicon Image SiI9022
63
REG32(CFG6, 0x18)
43
+ *
64
+REG32(CFG7, 0x1c)
44
+ * This is a pretty hollow emulation: all we do is acknowledge that we
65
REG32(CFGDATA_RTN, 0xa0)
45
+ * exist (chip ID) and confirm that we get switched over into DDC mode
66
REG32(CFGDATA_OUT, 0xa4)
46
+ * so the emulated host can proceed to read out EDID data. All subsequent
67
REG32(CFGCTRL, 0xa8)
47
+ * set-up of connectors etc will be acknowledged and ignored.
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
48
+ *
69
/* Is CFG_REG2 present? */
49
+ * Copyright (C) 2018 Linus Walleij
70
static bool have_cfg2(MPS2SCC *s)
50
+ *
71
{
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
52
+ * See the COPYING file in the top-level directory.
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
53
+ * SPDX-License-Identifier: GPL-2.0-or-later
74
+ scc_partno(s) == 0x536;
54
+ */
75
}
55
+
76
56
+#include "qemu/osdep.h"
77
/* Is CFG_REG3 present? */
57
+#include "qemu-common.h"
78
static bool have_cfg3(MPS2SCC *s)
58
+#include "hw/i2c/i2c.h"
79
{
59
+#include "hw/i2c/i2c-ddc.h"
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
60
+#include "trace.h"
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
61
+
82
+ scc_partno(s) != 0x536;
62
+#define SII9022_SYS_CTRL_DATA 0x1a
83
}
63
+#define SII9022_SYS_CTRL_PWR_DWN 0x10
84
64
+#define SII9022_SYS_CTRL_AV_MUTE 0x08
85
/* Is CFG_REG5 present? */
65
+#define SII9022_SYS_CTRL_DDC_BUS_REQ 0x04
86
static bool have_cfg5(MPS2SCC *s)
66
+#define SII9022_SYS_CTRL_DDC_BUS_GRTD 0x02
87
{
67
+#define SII9022_SYS_CTRL_OUTPUT_MODE 0x01
88
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
68
+#define SII9022_SYS_CTRL_OUTPUT_HDMI 1
89
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
69
+#define SII9022_SYS_CTRL_OUTPUT_DVI 0
90
+ scc_partno(s) == 0x536;
70
+#define SII9022_REG_CHIPID 0x1b
91
}
71
+#define SII9022_INT_ENABLE 0x3c
92
72
+#define SII9022_INT_STATUS 0x3d
93
/* Is CFG_REG6 present? */
73
+#define SII9022_INT_STATUS_HOTPLUG 0x01;
94
static bool have_cfg6(MPS2SCC *s)
74
+#define SII9022_INT_STATUS_PLUGGED 0x04;
95
{
75
+
96
- return scc_partno(s) == 0x524;
76
+#define TYPE_SII9022 "sii9022"
97
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
77
+#define SII9022(obj) OBJECT_CHECK(sii9022_state, (obj), TYPE_SII9022)
98
+}
78
+
99
+
79
+typedef struct sii9022_state {
100
+/* Is CFG_REG7 present? */
80
+ I2CSlave parent_obj;
101
+static bool have_cfg7(MPS2SCC *s)
81
+ uint8_t ptr;
102
+{
82
+ bool addr_byte;
103
+ return scc_partno(s) == 0x536;
83
+ bool ddc_req;
104
+}
84
+ bool ddc_skip_finish;
105
+
85
+ bool ddc;
106
+/* Does CFG_REG0 drive the 'remap' GPIO output? */
86
+} sii9022_state;
107
+static bool cfg0_is_remap(MPS2SCC *s)
87
+
108
+{
88
+static const VMStateDescription vmstate_sii9022 = {
109
+ return scc_partno(s) != 0x536;
89
+ .name = "sii9022",
110
+}
111
+
112
+/* Is CFG_REG1 driving a set of LEDs? */
113
+static bool cfg1_is_leds(MPS2SCC *s)
114
+{
115
+ return scc_partno(s) != 0x536;
116
}
117
118
/* Handle a write via the SYS_CFG channel to the specified function/device.
119
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
120
if (!have_cfg3(s)) {
121
goto bad_offset;
122
}
123
- /* These are user-settable DIP switches on the board. We don't
124
+ /*
125
+ * These are user-settable DIP switches on the board. We don't
126
* model that, so just return zeroes.
127
+ *
128
+ * TODO: for AN536 this is MCC_MSB_ADDR "additional MCC addressing
129
+ * bits". These change which part of the DDR4 the motherboard
130
+ * configuration controller can see in its memory map (see the
131
+ * appnote section 2.4). QEMU doesn't model the MCC at all, so these
132
+ * bits are not interesting to us; read-as-zero is as good as anything
133
+ * else.
134
*/
135
r = 0;
136
break;
137
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
138
}
139
r = s->cfg6;
140
break;
141
+ case A_CFG7:
142
+ if (!have_cfg7(s)) {
143
+ goto bad_offset;
144
+ }
145
+ r = s->cfg7;
146
+ break;
147
case A_CFGDATA_RTN:
148
r = s->cfgdata_rtn;
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
151
* we always reflect bit 0 in the 'remap' GPIO output line,
152
* and let the board wire it up or not as it chooses.
153
* TODO on some boards bit 1 is CPU_WAIT.
154
+ *
155
+ * TODO: on the AN536 this register controls reset and halt
156
+ * for both CPUs. For the moment we don't implement this, so the
157
+ * register just reads as written.
158
*/
159
s->cfg0 = value;
160
- qemu_set_irq(s->remap, s->cfg0 & 1);
161
+ if (cfg0_is_remap(s)) {
162
+ qemu_set_irq(s->remap, s->cfg0 & 1);
163
+ }
164
break;
165
case A_CFG1:
166
s->cfg1 = value;
167
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
168
- led_set_state(s->led[i], extract32(value, i, 1));
169
+ /*
170
+ * On most boards this register drives LEDs.
171
+ *
172
+ * TODO: for AN536 this controls whether flash and ATCM are
173
+ * enabled or disabled on reset. QEMU doesn't model this, and
174
+ * always wires up RAM in the ATCM area and ROM in the flash area.
175
+ */
176
+ if (cfg1_is_leds(s)) {
177
+ for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
178
+ led_set_state(s->led[i], extract32(value, i, 1));
179
+ }
180
}
181
break;
182
case A_CFG2:
183
if (!have_cfg2(s)) {
184
goto bad_offset;
185
}
186
- /* AN524: QSPI Select signal */
187
+ /* AN524, AN536: QSPI Select signal */
188
s->cfg2 = value;
189
break;
190
case A_CFG5:
191
if (!have_cfg5(s)) {
192
goto bad_offset;
193
}
194
- /* AN524: ACLK frequency in Hz */
195
+ /* AN524, AN536: ACLK frequency in Hz */
196
s->cfg5 = value;
197
break;
198
case A_CFG6:
199
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
200
goto bad_offset;
201
}
202
/* AN524: Clock divider for BRAM */
203
+ /* AN536: Core 0 vector table base address */
204
+ s->cfg6 = value;
205
+ break;
206
+ case A_CFG7:
207
+ if (!have_cfg7(s)) {
208
+ goto bad_offset;
209
+ }
210
+ /* AN536: Core 1 vector table base address */
211
s->cfg6 = value;
212
break;
213
case A_CFGDATA_OUT:
214
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_finalize(Object *obj)
215
g_free(s->oscclk_reset);
216
}
217
218
+static bool cfg7_needed(void *opaque)
219
+{
220
+ MPS2SCC *s = opaque;
221
+
222
+ return have_cfg7(s);
223
+}
224
+
225
+static const VMStateDescription vmstate_cfg7 = {
226
+ .name = "mps2-scc/cfg7",
90
+ .version_id = 1,
227
+ .version_id = 1,
91
+ .minimum_version_id = 1,
228
+ .minimum_version_id = 1,
92
+ .fields = (VMStateField[]) {
229
+ .needed = cfg7_needed,
93
+ VMSTATE_I2C_SLAVE(parent_obj, sii9022_state),
230
+ .fields = (const VMStateField[]) {
94
+ VMSTATE_UINT8(ptr, sii9022_state),
231
+ VMSTATE_UINT32(cfg7, MPS2SCC),
95
+ VMSTATE_BOOL(addr_byte, sii9022_state),
96
+ VMSTATE_BOOL(ddc_req, sii9022_state),
97
+ VMSTATE_BOOL(ddc_skip_finish, sii9022_state),
98
+ VMSTATE_BOOL(ddc, sii9022_state),
99
+ VMSTATE_END_OF_LIST()
232
+ VMSTATE_END_OF_LIST()
100
+ }
233
+ }
101
+};
234
+};
102
+
235
+
103
+static int sii9022_event(I2CSlave *i2c, enum i2c_event event)
236
static const VMStateDescription mps2_scc_vmstate = {
104
+{
237
.name = "mps2-scc",
105
+ sii9022_state *s = SII9022(i2c);
238
.version_id = 3,
106
+
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
107
+ switch (event) {
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
108
+ case I2C_START_SEND:
241
0, vmstate_info_uint32, uint32_t),
109
+ s->addr_byte = true;
242
VMSTATE_END_OF_LIST()
110
+ break;
243
+ },
111
+ case I2C_START_RECV:
244
+ .subsections = (const VMStateDescription * const []) {
112
+ break;
245
+ &vmstate_cfg7,
113
+ case I2C_FINISH:
246
+ NULL
114
+ break;
247
}
115
+ case I2C_NACK:
248
};
116
+ break;
249
117
+ }
118
+
119
+ return 0;
120
+}
121
+
122
+static int sii9022_rx(I2CSlave *i2c)
123
+{
124
+ sii9022_state *s = SII9022(i2c);
125
+ uint8_t res = 0x00;
126
+
127
+ switch (s->ptr) {
128
+ case SII9022_SYS_CTRL_DATA:
129
+ if (s->ddc_req) {
130
+ /* Acknowledge DDC bus request */
131
+ res = SII9022_SYS_CTRL_DDC_BUS_GRTD | SII9022_SYS_CTRL_DDC_BUS_REQ;
132
+ }
133
+ break;
134
+ case SII9022_REG_CHIPID:
135
+ res = 0xb0;
136
+ break;
137
+ case SII9022_INT_STATUS:
138
+ /* Something is cold-plugged in, no interrupts */
139
+ res = SII9022_INT_STATUS_PLUGGED;
140
+ break;
141
+ default:
142
+ break;
143
+ }
144
+
145
+ trace_sii9022_read_reg(s->ptr, res);
146
+ s->ptr++;
147
+
148
+ return res;
149
+}
150
+
151
+static int sii9022_tx(I2CSlave *i2c, uint8_t data)
152
+{
153
+ sii9022_state *s = SII9022(i2c);
154
+
155
+ if (s->addr_byte) {
156
+ s->ptr = data;
157
+ s->addr_byte = false;
158
+ return 0;
159
+ }
160
+
161
+ switch (s->ptr) {
162
+ case SII9022_SYS_CTRL_DATA:
163
+ if (data & SII9022_SYS_CTRL_DDC_BUS_REQ) {
164
+ s->ddc_req = true;
165
+ if (data & SII9022_SYS_CTRL_DDC_BUS_GRTD) {
166
+ s->ddc = true;
167
+ /* Skip this finish since we just switched to DDC */
168
+ s->ddc_skip_finish = true;
169
+ trace_sii9022_switch_mode("DDC");
170
+ }
171
+ } else {
172
+ s->ddc_req = false;
173
+ s->ddc = false;
174
+ trace_sii9022_switch_mode("normal");
175
+ }
176
+ break;
177
+ default:
178
+ break;
179
+ }
180
+
181
+ trace_sii9022_write_reg(s->ptr, data);
182
+ s->ptr++;
183
+
184
+ return 0;
185
+}
186
+
187
+static void sii9022_reset(DeviceState *dev)
188
+{
189
+ sii9022_state *s = SII9022(dev);
190
+
191
+ s->ptr = 0;
192
+ s->addr_byte = false;
193
+ s->ddc_req = false;
194
+ s->ddc_skip_finish = false;
195
+ s->ddc = false;
196
+}
197
+
198
+static void sii9022_realize(DeviceState *dev, Error **errp)
199
+{
200
+ I2CBus *bus;
201
+
202
+ bus = I2C_BUS(qdev_get_parent_bus(dev));
203
+ i2c_create_slave(bus, TYPE_I2CDDC, 0x50);
204
+}
205
+
206
+static void sii9022_class_init(ObjectClass *klass, void *data)
207
+{
208
+ DeviceClass *dc = DEVICE_CLASS(klass);
209
+ I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
210
+
211
+ k->event = sii9022_event;
212
+ k->recv = sii9022_rx;
213
+ k->send = sii9022_tx;
214
+ dc->reset = sii9022_reset;
215
+ dc->realize = sii9022_realize;
216
+ dc->vmsd = &vmstate_sii9022;
217
+}
218
+
219
+static const TypeInfo sii9022_info = {
220
+ .name = TYPE_SII9022,
221
+ .parent = TYPE_I2C_SLAVE,
222
+ .instance_size = sizeof(sii9022_state),
223
+ .class_init = sii9022_class_init,
224
+};
225
+
226
+static void sii9022_register_types(void)
227
+{
228
+ type_register_static(&sii9022_info);
229
+}
230
+
231
+type_init(sii9022_register_types)
232
diff --git a/hw/display/trace-events b/hw/display/trace-events
233
index XXXXXXX..XXXXXXX 100644
234
--- a/hw/display/trace-events
235
+++ b/hw/display/trace-events
236
@@ -XXX,XX +XXX,XX @@ vga_cirrus_read_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x"
237
vga_cirrus_write_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x"
238
vga_cirrus_read_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x"
239
vga_cirrus_write_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x"
240
+
241
+# hw/display/sii9022.c
242
+sii9022_read_reg(uint8_t addr, uint8_t val) "addr 0x%02x, val 0x%02x"
243
+sii9022_write_reg(uint8_t addr, uint8_t val) "addr 0x%02x, val 0x%02x"
244
+sii9022_switch_mode(const char *mode) "mode: %s"
245
--
250
--
246
2.16.2
251
2.34.1
247
252
248
253
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
The AN536 is another FPGA image for the MPS3 development board. Unlike
2
2
the existing FPGA images we already model, this board uses a Cortex-R
3
I am leaving Xilinx, so to avoid having an email address that bounces
3
family CPU, and it does not use any equivalent to the M-profile
4
update my maintainer address to point to my personal email address.
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
5
It's therefore more convenient for us to model it as a completely
6
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
6
separate C file.
7
Signed-off-by: Alistair Francis <alistair@alistair23.me>
7
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
This commit adds the basic skeleton of the board model, and the
9
Message-id: 7bb690382e3370aa1c1e047a84e36603c787ec0e.1519749987.git.alistair.francis@xilinx.com
9
code to create all the RAM and ROM. We assume that we're probably
10
going to want to add more images in future, so use the same
11
base class/subclass setup that mps2-tz.c uses, even though at
12
the moment there's only a single subclass.
13
14
Following commits will add the CPUs and the peripherals.
15
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Message-id: 20240206132931.38376-9-peter.maydell@linaro.org
11
---
19
---
12
MAINTAINERS | 12 ++++++------
20
MAINTAINERS | 3 +-
13
1 file changed, 6 insertions(+), 6 deletions(-)
21
configs/devices/arm-softmmu/default.mak | 1 +
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
23
hw/arm/Kconfig | 5 +
24
hw/arm/meson.build | 1 +
25
5 files changed, 248 insertions(+), 1 deletion(-)
26
create mode 100644 hw/arm/mps3r.c
14
27
15
diff --git a/MAINTAINERS b/MAINTAINERS
28
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
30
--- a/MAINTAINERS
18
+++ b/MAINTAINERS
31
+++ b/MAINTAINERS
19
@@ -XXX,XX +XXX,XX @@ F: hw/misc/arm_sysctl.c
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
20
33
F: hw/pci-host/designware.c
21
Xilinx Zynq
34
F: include/hw/pci-host/designware.h
22
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
35
23
-M: Alistair Francis <alistair.francis@xilinx.com>
36
-MPS2
24
+M: Alistair Francis <alistair@alistair23.me>
37
+MPS2 / MPS3
38
M: Peter Maydell <peter.maydell@linaro.org>
25
L: qemu-arm@nongnu.org
39
L: qemu-arm@nongnu.org
26
S: Maintained
40
S: Maintained
27
F: hw/*/xilinx_*
41
F: hw/arm/mps2.c
28
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/zynq*
42
F: hw/arm/mps2-tz.c
29
X: hw/ssi/xilinx_*
43
+F: hw/arm/mps3r.c
30
44
F: hw/misc/mps2-*.c
31
Xilinx ZynqMP
45
F: include/hw/misc/mps2-*.h
32
-M: Alistair Francis <alistair.francis@xilinx.com>
46
F: hw/arm/armsse.c
33
+M: Alistair Francis <alistair@alistair23.me>
47
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
34
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
48
index XXXXXXX..XXXXXXX 100644
35
L: qemu-arm@nongnu.org
49
--- a/configs/devices/arm-softmmu/default.mak
36
S: Maintained
50
+++ b/configs/devices/arm-softmmu/default.mak
37
@@ -XXX,XX +XXX,XX @@ T: git git://github.com/bonzini/qemu.git scsi-next
51
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
38
52
# CONFIG_INTEGRATOR=n
39
SSI
53
# CONFIG_FSL_IMX31=n
40
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
54
# CONFIG_MUSICPAL=n
41
-M: Alistair Francis <alistair.francis@xilinx.com>
55
+# CONFIG_MPS3R=n
42
+M: Alistair Francis <alistair@alistair23.me>
56
# CONFIG_MUSCA=n
43
S: Maintained
57
# CONFIG_CHEETAH=n
44
F: hw/ssi/*
58
# CONFIG_SX1=n
45
F: hw/block/m25p80.c
59
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
46
@@ -XXX,XX +XXX,XX @@ X: hw/ssi/xilinx_*
60
new file mode 100644
47
F: tests/m25p80-test.c
61
index XXXXXXX..XXXXXXX
48
62
--- /dev/null
49
Xilinx SPI
63
+++ b/hw/arm/mps3r.c
50
-M: Alistair Francis <alistair.francis@xilinx.com>
64
@@ -XXX,XX +XXX,XX @@
51
+M: Alistair Francis <alistair@alistair23.me>
65
+/*
52
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
53
S: Maintained
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
54
F: hw/ssi/xilinx_*
68
+ *
55
@@ -XXX,XX +XXX,XX @@ S: Maintained
69
+ * Copyright (c) 2017 Linaro Limited
56
F: hw/net/eepro100.c
70
+ * Written by Peter Maydell
57
71
+ *
58
Generic Loader
72
+ * This program is free software; you can redistribute it and/or modify
59
-M: Alistair Francis <alistair.francis@xilinx.com>
73
+ * it under the terms of the GNU General Public License version 2 or
60
+M: Alistair Francis <alistair@alistair23.me>
74
+ * (at your option) any later version.
61
S: Maintained
75
+ */
62
F: hw/core/generic-loader.c
76
+
63
F: include/hw/core/generic-loader.h
77
+/*
64
@@ -XXX,XX +XXX,XX @@ F: tests/qmp-test.c
78
+ * The MPS3 is an FPGA based dev board. This file handles FPGA images
65
T: git git://repo.or.cz/qemu/armbru.git qapi-next
79
+ * which use the Cortex-R CPUs. We model these separately from the
66
80
+ * M-profile images, because on M-profile the FPGA image is based on
67
Register API
81
+ * a "Subsystem for Embedded" which is similar to an SoC, whereas
68
-M: Alistair Francis <alistair.francis@xilinx.com>
82
+ * the R-profile FPGA images don't have that abstraction layer.
69
+M: Alistair Francis <alistair@alistair23.me>
83
+ *
70
S: Maintained
84
+ * We model the following FPGA images here:
71
F: hw/core/register.c
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
72
F: include/hw/register.h
86
+ *
87
+ * Application Note AN536:
88
+ * https://developer.arm.com/documentation/dai0536/latest/
89
+ */
90
+
91
+#include "qemu/osdep.h"
92
+#include "qemu/units.h"
93
+#include "qapi/error.h"
94
+#include "exec/address-spaces.h"
95
+#include "cpu.h"
96
+#include "hw/boards.h"
97
+#include "hw/arm/boot.h"
98
+
99
+/* Define the layout of RAM and ROM in a board */
100
+typedef struct RAMInfo {
101
+ const char *name;
102
+ hwaddr base;
103
+ hwaddr size;
104
+ int mrindex; /* index into rams[]; -1 for the system RAM block */
105
+ int flags;
106
+} RAMInfo;
107
+
108
+/*
109
+ * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit
110
+ * emulation of that much guest RAM, so artificially make it smaller.
111
+ */
112
+#if HOST_LONG_BITS == 32
113
+#define MPS3_DDR_SIZE (1 * GiB)
114
+#else
115
+#define MPS3_DDR_SIZE (3 * GiB)
116
+#endif
117
+
118
+/*
119
+ * Flag values:
120
+ * IS_MAIN: this is the main machine RAM
121
+ * IS_ROM: this area is read-only
122
+ */
123
+#define IS_MAIN 1
124
+#define IS_ROM 2
125
+
126
+#define MPS3R_RAM_MAX 9
127
+
128
+typedef enum MPS3RFPGAType {
129
+ FPGA_AN536,
130
+} MPS3RFPGAType;
131
+
132
+struct MPS3RMachineClass {
133
+ MachineClass parent;
134
+ MPS3RFPGAType fpga_type;
135
+ const RAMInfo *raminfo;
136
+};
137
+
138
+struct MPS3RMachineState {
139
+ MachineState parent;
140
+ MemoryRegion ram[MPS3R_RAM_MAX];
141
+};
142
+
143
+#define TYPE_MPS3R_MACHINE "mps3r"
144
+#define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536")
145
+
146
+OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
147
+
148
+static const RAMInfo an536_raminfo[] = {
149
+ {
150
+ .name = "ATCM",
151
+ .base = 0x00000000,
152
+ .size = 0x00008000,
153
+ .mrindex = 0,
154
+ }, {
155
+ /* We model the QSPI flash as simple ROM for now */
156
+ .name = "QSPI",
157
+ .base = 0x08000000,
158
+ .size = 0x00800000,
159
+ .flags = IS_ROM,
160
+ .mrindex = 1,
161
+ }, {
162
+ .name = "BRAM",
163
+ .base = 0x10000000,
164
+ .size = 0x00080000,
165
+ .mrindex = 2,
166
+ }, {
167
+ .name = "DDR",
168
+ .base = 0x20000000,
169
+ .size = MPS3_DDR_SIZE,
170
+ .mrindex = -1,
171
+ }, {
172
+ .name = "ATCM0",
173
+ .base = 0xee000000,
174
+ .size = 0x00008000,
175
+ .mrindex = 3,
176
+ }, {
177
+ .name = "BTCM0",
178
+ .base = 0xee100000,
179
+ .size = 0x00008000,
180
+ .mrindex = 4,
181
+ }, {
182
+ .name = "CTCM0",
183
+ .base = 0xee200000,
184
+ .size = 0x00008000,
185
+ .mrindex = 5,
186
+ }, {
187
+ .name = "ATCM1",
188
+ .base = 0xee400000,
189
+ .size = 0x00008000,
190
+ .mrindex = 6,
191
+ }, {
192
+ .name = "BTCM1",
193
+ .base = 0xee500000,
194
+ .size = 0x00008000,
195
+ .mrindex = 7,
196
+ }, {
197
+ .name = "CTCM1",
198
+ .base = 0xee600000,
199
+ .size = 0x00008000,
200
+ .mrindex = 8,
201
+ }, {
202
+ .name = NULL,
203
+ }
204
+};
205
+
206
+static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
207
+ const RAMInfo *raminfo)
208
+{
209
+ /* Return an initialized MemoryRegion for the RAMInfo. */
210
+ MemoryRegion *ram;
211
+
212
+ if (raminfo->mrindex < 0) {
213
+ /* Means this RAMInfo is for QEMU's "system memory" */
214
+ MachineState *machine = MACHINE(mms);
215
+ assert(!(raminfo->flags & IS_ROM));
216
+ return machine->ram;
217
+ }
218
+
219
+ assert(raminfo->mrindex < MPS3R_RAM_MAX);
220
+ ram = &mms->ram[raminfo->mrindex];
221
+
222
+ memory_region_init_ram(ram, NULL, raminfo->name,
223
+ raminfo->size, &error_fatal);
224
+ if (raminfo->flags & IS_ROM) {
225
+ memory_region_set_readonly(ram, true);
226
+ }
227
+ return ram;
228
+}
229
+
230
+static void mps3r_common_init(MachineState *machine)
231
+{
232
+ MPS3RMachineState *mms = MPS3R_MACHINE(machine);
233
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
234
+ MemoryRegion *sysmem = get_system_memory();
235
+
236
+ for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
237
+ MemoryRegion *mr = mr_for_raminfo(mms, ri);
238
+ memory_region_add_subregion(sysmem, ri->base, mr);
239
+ }
240
+}
241
+
242
+static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
243
+{
244
+ /*
245
+ * Set mc->default_ram_size and default_ram_id from the
246
+ * information in mmc->raminfo.
247
+ */
248
+ MachineClass *mc = MACHINE_CLASS(mmc);
249
+ const RAMInfo *p;
250
+
251
+ for (p = mmc->raminfo; p->name; p++) {
252
+ if (p->mrindex < 0) {
253
+ /* Found the entry for "system memory" */
254
+ mc->default_ram_size = p->size;
255
+ mc->default_ram_id = p->name;
256
+ return;
257
+ }
258
+ }
259
+ g_assert_not_reached();
260
+}
261
+
262
+static void mps3r_class_init(ObjectClass *oc, void *data)
263
+{
264
+ MachineClass *mc = MACHINE_CLASS(oc);
265
+
266
+ mc->init = mps3r_common_init;
267
+}
268
+
269
+static void mps3r_an536_class_init(ObjectClass *oc, void *data)
270
+{
271
+ MachineClass *mc = MACHINE_CLASS(oc);
272
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc);
273
+ static const char * const valid_cpu_types[] = {
274
+ ARM_CPU_TYPE_NAME("cortex-r52"),
275
+ NULL
276
+ };
277
+
278
+ mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
279
+ mc->default_cpus = 2;
280
+ mc->min_cpus = mc->default_cpus;
281
+ mc->max_cpus = mc->default_cpus;
282
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
283
+ mc->valid_cpu_types = valid_cpu_types;
284
+ mmc->raminfo = an536_raminfo;
285
+ mps3r_set_default_ram_info(mmc);
286
+}
287
+
288
+static const TypeInfo mps3r_machine_types[] = {
289
+ {
290
+ .name = TYPE_MPS3R_MACHINE,
291
+ .parent = TYPE_MACHINE,
292
+ .abstract = true,
293
+ .instance_size = sizeof(MPS3RMachineState),
294
+ .class_size = sizeof(MPS3RMachineClass),
295
+ .class_init = mps3r_class_init,
296
+ }, {
297
+ .name = TYPE_MPS3R_AN536_MACHINE,
298
+ .parent = TYPE_MPS3R_MACHINE,
299
+ .class_init = mps3r_an536_class_init,
300
+ },
301
+};
302
+
303
+DEFINE_TYPES(mps3r_machine_types);
304
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
305
index XXXXXXX..XXXXXXX 100644
306
--- a/hw/arm/Kconfig
307
+++ b/hw/arm/Kconfig
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
309
select PFLASH_CFI01
310
select SMC91C111
311
312
+config MPS3R
313
+ bool
314
+ default y
315
+ depends on TCG && ARM
316
+
317
config MUSCA
318
bool
319
default y
320
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
321
index XXXXXXX..XXXXXXX 100644
322
--- a/hw/arm/meson.build
323
+++ b/hw/arm/meson.build
324
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
325
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
326
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
327
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
328
+arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
329
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
330
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
331
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
73
--
332
--
74
2.16.2
333
2.34.1
75
334
76
335
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
the mps3-an536 board.
2
3
3
We go with the localised helper.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
6
---
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
8
1 file changed, 177 insertions(+), 3 deletions(-)
4
9
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180227143852.11175-25-alex.bennee@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper-a64.h | 1 +
11
target/arm/helper-a64.c | 29 +++++++++++++++++++++++++++++
12
target/arm/translate-a64.c | 4 ++++
13
3 files changed, 34 insertions(+)
14
15
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.h
12
--- a/hw/arm/mps3r.c
18
+++ b/target/arm/helper-a64.h
13
+++ b/hw/arm/mps3r.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64)
14
@@ -XXX,XX +XXX,XX @@
20
DEF_HELPER_FLAGS_1(neon_addlp_u16, TCG_CALL_NO_RWG_SE, i64, i64)
15
#include "qemu/osdep.h"
21
DEF_HELPER_FLAGS_2(frecpx_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
16
#include "qemu/units.h"
22
DEF_HELPER_FLAGS_2(frecpx_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
17
#include "qapi/error.h"
23
+DEF_HELPER_FLAGS_2(frecpx_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
18
+#include "qapi/qmp/qlist.h"
24
DEF_HELPER_FLAGS_2(fcvtx_f64_to_f32, TCG_CALL_NO_RWG, f32, f64, env)
19
#include "exec/address-spaces.h"
25
DEF_HELPER_FLAGS_3(crc32_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32)
20
#include "cpu.h"
26
DEF_HELPER_FLAGS_3(crc32c_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32)
21
#include "hw/boards.h"
27
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
22
+#include "hw/qdev-properties.h"
28
index XXXXXXX..XXXXXXX 100644
23
#include "hw/arm/boot.h"
29
--- a/target/arm/helper-a64.c
24
+#include "hw/arm/bsa.h"
30
+++ b/target/arm/helper-a64.c
25
+#include "hw/intc/arm_gicv3.h"
31
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_u16)(uint64_t a)
26
27
/* Define the layout of RAM and ROM in a board */
28
typedef struct RAMInfo {
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
30
#define IS_ROM 2
31
32
#define MPS3R_RAM_MAX 9
33
+#define MPS3R_CPU_MAX 2
34
+
35
+#define PERIPHBASE 0xf0000000
36
+#define NUM_SPIS 96
37
38
typedef enum MPS3RFPGAType {
39
FPGA_AN536,
40
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineClass {
41
MachineClass parent;
42
MPS3RFPGAType fpga_type;
43
const RAMInfo *raminfo;
44
+ hwaddr loader_start;
45
};
46
47
struct MPS3RMachineState {
48
MachineState parent;
49
+ struct arm_boot_info bootinfo;
50
MemoryRegion ram[MPS3R_RAM_MAX];
51
+ Object *cpu[MPS3R_CPU_MAX];
52
+ MemoryRegion cpu_sysmem[MPS3R_CPU_MAX];
53
+ MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
54
+ MemoryRegion cpu_ram[MPS3R_CPU_MAX];
55
+ GICv3State gic;
56
};
57
58
#define TYPE_MPS3R_MACHINE "mps3r"
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
60
return ram;
32
}
61
}
33
62
34
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
63
+/*
35
+float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
64
+ * There is no defined secondary boot protocol for Linux for the AN536,
65
+ * because real hardware has a restriction that atomic operations between
66
+ * the two CPUs do not function correctly, and so true SMP is not
67
+ * possible. Therefore for cases where the user is directly booting
68
+ * a kernel, we treat the system as essentially uniprocessor, and
69
+ * put the secondary CPU into power-off state (as if the user on the
70
+ * real hardware had configured the secondary to be halted via the
71
+ * SCC config registers).
72
+ *
73
+ * Note that the default secondary boot code would not work here anyway
74
+ * as it assumes a GICv2, and we have a GICv3.
75
+ */
76
+static void mps3r_write_secondary_boot(ARMCPU *cpu,
77
+ const struct arm_boot_info *info)
36
+{
78
+{
37
+ float_status *fpst = fpstp;
79
+ /*
38
+ uint16_t val16, sbit;
80
+ * Power the secondary CPU off. This means we don't need to write any
39
+ int16_t exp;
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
40
+
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
41
+ if (float16_is_any_nan(a)) {
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
42
+ float16 nan = a;
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
43
+ if (float16_is_signaling_nan(a, fpst)) {
85
+ */
44
+ float_raise(float_flag_invalid, fpst);
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
45
+ nan = float16_maybe_silence_nan(a, fpst);
87
+ if (cs != first_cpu) {
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
89
+ &error_abort);
46
+ }
90
+ }
47
+ if (fpst->default_nan_mode) {
48
+ nan = float16_default_nan(fpst);
49
+ }
50
+ return nan;
51
+ }
52
+
53
+ val16 = float16_val(a);
54
+ sbit = 0x8000 & val16;
55
+ exp = extract32(val16, 10, 5);
56
+
57
+ if (exp == 0) {
58
+ return make_float16(deposit32(sbit, 10, 5, 0x1e));
59
+ } else {
60
+ return make_float16(deposit32(sbit, 10, 5, ~exp));
61
+ }
91
+ }
62
+}
92
+}
63
+
93
+
64
float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
95
+ const struct arm_boot_info *info)
96
+{
97
+ /* We don't need to do anything here because the CPU will be off */
98
+}
99
+
100
+static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
101
+{
102
+ MachineState *machine = MACHINE(mms);
103
+ DeviceState *gicdev;
104
+ QList *redist_region_count;
105
+
106
+ object_initialize_child(OBJECT(mms), "gic", &mms->gic, TYPE_ARM_GICV3);
107
+ gicdev = DEVICE(&mms->gic);
108
+ qdev_prop_set_uint32(gicdev, "num-cpu", machine->smp.cpus);
109
+ qdev_prop_set_uint32(gicdev, "num-irq", NUM_SPIS + GIC_INTERNAL);
110
+ redist_region_count = qlist_new();
111
+ qlist_append_int(redist_region_count, machine->smp.cpus);
112
+ qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
113
+ object_property_set_link(OBJECT(&mms->gic), "sysmem",
114
+ OBJECT(sysmem), &error_fatal);
115
+ sysbus_realize(SYS_BUS_DEVICE(&mms->gic), &error_fatal);
116
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 0, PERIPHBASE);
117
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 1, PERIPHBASE + 0x100000);
118
+ /*
119
+ * Wire the outputs from each CPU's generic timer and the GICv3
120
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
121
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
122
+ */
123
+ for (int i = 0; i < machine->smp.cpus; i++) {
124
+ DeviceState *cpudev = DEVICE(mms->cpu[i]);
125
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&mms->gic);
126
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
127
+ int irq;
128
+ /*
129
+ * Mapping from the output timer irq lines from the CPU to the
130
+ * GIC PPI inputs used for this board. This isn't a BSA board,
131
+ * but it uses the standard convention for the PPI numbers.
132
+ */
133
+ const int timer_irq[] = {
134
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
135
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
136
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
137
+ };
138
+
139
+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
140
+ qdev_connect_gpio_out(cpudev, irq,
141
+ qdev_get_gpio_in(gicdev,
142
+ intidbase + timer_irq[irq]));
143
+ }
144
+
145
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
146
+ qdev_get_gpio_in(gicdev,
147
+ intidbase + ARCH_GIC_MAINT_IRQ));
148
+
149
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
150
+ qdev_get_gpio_in(gicdev,
151
+ intidbase + VIRTUAL_PMU_IRQ));
152
+
153
+ sysbus_connect_irq(gicsbd, i,
154
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
155
+ sysbus_connect_irq(gicsbd, i + machine->smp.cpus,
156
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
157
+ sysbus_connect_irq(gicsbd, i + 2 * machine->smp.cpus,
158
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
159
+ sysbus_connect_irq(gicsbd, i + 3 * machine->smp.cpus,
160
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
161
+ }
162
+}
163
+
164
static void mps3r_common_init(MachineState *machine)
65
{
165
{
66
float_status *fpst = fpstp;
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
67
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
68
index XXXXXXX..XXXXXXX 100644
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
69
--- a/target/arm/translate-a64.c
169
memory_region_add_subregion(sysmem, ri->base, mr);
70
+++ b/target/arm/translate-a64.c
170
}
71
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
171
+
72
handle_2misc_fcmp_zero(s, fpop, is_scalar, 0, is_q, MO_16, rn, rd);
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
73
return;
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
74
case 0x3d: /* FRECPE */
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
75
+ case 0x3f: /* FRECPX */
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
76
break;
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
77
case 0x18: /* FRINTN */
177
+
78
need_rmode = true;
178
+ /*
79
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
179
+ * Each CPU has some private RAM/peripherals, so create the container
80
case 0x3d: /* FRECPE */
180
+ * which will house those, with the whole-machine system memory being
81
gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus);
181
+ * used where there's no CPU-specific device. Note that we need the
82
break;
182
+ * sysmem_alias aliases because we can't put one MR (the original
83
+ case 0x3f: /* FRECPX */
183
+ * 'sysmem') into more than one other MR.
84
+ gen_helper_frecpx_f16(tcg_res, tcg_op, tcg_fpstatus);
184
+ */
85
+ break;
185
+ memory_region_init(&mms->cpu_sysmem[i], OBJECT(machine),
86
case 0x5a: /* FCVTNU */
186
+ sysmem_name, UINT64_MAX);
87
case 0x5b: /* FCVTMU */
187
+ memory_region_init_alias(&mms->sysmem_alias[i], OBJECT(machine),
88
case 0x5c: /* FCVTAU */
188
+ alias_name, sysmem, 0, UINT64_MAX);
189
+ memory_region_add_subregion_overlap(&mms->cpu_sysmem[i], 0,
190
+ &mms->sysmem_alias[i], -1);
191
+
192
+ mms->cpu[i] = object_new(machine->cpu_type);
193
+ object_property_set_link(mms->cpu[i], "memory",
194
+ OBJECT(&mms->cpu_sysmem[i]), &error_abort);
195
+ object_property_set_int(mms->cpu[i], "reset-cbar",
196
+ PERIPHBASE, &error_abort);
197
+ qdev_realize(DEVICE(mms->cpu[i]), NULL, &error_fatal);
198
+ object_unref(mms->cpu[i]);
199
+
200
+ /* Per-CPU RAM */
201
+ memory_region_init_ram(&mms->cpu_ram[i], NULL, ramname,
202
+ 0x1000, &error_fatal);
203
+ memory_region_add_subregion(&mms->cpu_sysmem[i], 0xe7c01000,
204
+ &mms->cpu_ram[i]);
205
+ }
206
+
207
+ create_gic(mms, sysmem);
208
+
209
+ mms->bootinfo.ram_size = machine->ram_size;
210
+ mms->bootinfo.board_id = -1;
211
+ mms->bootinfo.loader_start = mmc->loader_start;
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
215
}
216
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
219
/* Found the entry for "system memory" */
220
mc->default_ram_size = p->size;
221
mc->default_ram_id = p->name;
222
+ mmc->loader_start = p->base;
223
return;
224
}
225
}
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
227
};
228
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
230
- mc->default_cpus = 2;
231
- mc->min_cpus = mc->default_cpus;
232
- mc->max_cpus = mc->default_cpus;
233
+ /*
234
+ * In the real FPGA image there are always two cores, but the standard
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
236
+ * that the second core is held in reset and halted. Many images built for
237
+ * the board do not expect the second core to run at startup (especially
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
240
+ *
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
242
+ * with the default being -smp 1. This seems a more intuitive UI for
243
+ * QEMU users than, for instance, having a machine property to allow
244
+ * the user to set the initial value of the SYSCON 0x000 register.
245
+ */
246
+ mc->default_cpus = 1;
247
+ mc->min_cpus = 1;
248
+ mc->max_cpus = 2;
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
250
mc->valid_cpu_types = valid_cpu_types;
251
mmc->raminfo = an536_raminfo;
89
--
252
--
90
2.16.2
253
2.34.1
91
92
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
This board has a lot of UARTs: there is one UART per CPU in the
2
per-CPU peripheral part of the address map, whose interrupts are
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
4
normal part of the peripheral space, whose interrupts are shared
5
peripheral interrupts.
2
6
3
This is the initial decode skeleton for the Advanced SIMD three same
7
Connect and wire them all up; this involves some OR gates where
4
instruction group.
8
multiple overflow interrupts are wired into one GIC input.
5
9
6
The fprintf is purely to aid debugging as the additional instructions
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
are added. It will be removed once the group is complete.
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
13
---
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 94 insertions(+)
8
16
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180227143852.11175-9-alex.bennee@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/translate-a64.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 73 insertions(+)
16
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-a64.c
19
--- a/hw/arm/mps3r.c
20
+++ b/target/arm/translate-a64.c
20
+++ b/hw/arm/mps3r.c
21
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@
22
#include "qapi/qmp/qlist.h"
23
#include "exec/address-spaces.h"
24
#include "cpu.h"
25
+#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
+#include "hw/or-irq.h"
28
#include "hw/qdev-properties.h"
29
#include "hw/arm/boot.h"
30
#include "hw/arm/bsa.h"
31
+#include "hw/char/cmsdk-apb-uart.h"
32
#include "hw/intc/arm_gicv3.h"
33
34
/* Define the layout of RAM and ROM in a board */
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
36
37
#define MPS3R_RAM_MAX 9
38
#define MPS3R_CPU_MAX 2
39
+#define MPS3R_UART_MAX 4 /* shared UART count */
40
41
#define PERIPHBASE 0xf0000000
42
#define NUM_SPIS 96
43
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
44
MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
45
MemoryRegion cpu_ram[MPS3R_CPU_MAX];
46
GICv3State gic;
47
+ /* per-CPU UARTs followed by the shared UARTs */
48
+ CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
49
+ OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
50
+ OrIRQState uart_oflow;
51
};
52
53
#define TYPE_MPS3R_MACHINE "mps3r"
54
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
55
56
OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
57
58
+/*
59
+ * Main clock frequency CLK in Hz (50MHz). In the image there are also
60
+ * ACLK, MCLK, GPUCLK and PERIPHCLK at the same frequency; for our
61
+ * model we just roll them all into one.
62
+ */
63
+#define CLK_FRQ 50000000
64
+
65
static const RAMInfo an536_raminfo[] = {
66
{
67
.name = "ATCM",
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
22
}
69
}
23
}
70
}
24
71
25
+/*
72
+/*
26
+ * Advanced SIMD three same (ARMv8.2 FP16 variants)
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
27
+ *
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
28
+ * 31 30 29 28 24 23 22 21 20 16 15 14 13 11 10 9 5 4 0
29
+ * +---+---+---+-----------+---------+------+-----+--------+---+------+------+
30
+ * | 0 | Q | U | 0 1 1 1 0 | a | 1 0 | Rm | 0 0 | opcode | 1 | Rn | Rd |
31
+ * +---+---+---+-----------+---------+------+-----+--------+---+------+------+
32
+ *
33
+ * This includes FMULX, FCMEQ (register), FRECPS, FRSQRTS, FCMGE
34
+ * (register), FACGE, FABD, FCMGT (register) and FACGT.
35
+ *
36
+ */
75
+ */
37
+static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
79
+ qemu_irq combirq)
38
+{
80
+{
39
+ int opcode, fpopcode;
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
40
+ int is_q, u, a, rm, rn, rd;
82
+ SysBusDevice *sbd;
41
+ int datasize, elements;
42
+ int pass;
43
+ TCGv_ptr fpst;
44
+
83
+
45
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
46
+ unallocated_encoding(s);
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
47
+ return;
86
+ TYPE_CMSDK_APB_UART);
48
+ }
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
49
+
88
+ qdev_prop_set_chr(DEVICE(&mms->uart[uartno]), "chardev", serial_hd(uartno));
50
+ if (!fp_access_check(s)) {
89
+ sbd = SYS_BUS_DEVICE(&mms->uart[uartno]);
51
+ return;
90
+ sysbus_realize(sbd, &error_fatal);
52
+ }
91
+ memory_region_add_subregion(mem, baseaddr,
53
+
92
+ sysbus_mmio_get_region(sbd, 0));
54
+ /* For these floating point ops, the U, a and opcode bits
93
+ sysbus_connect_irq(sbd, 0, txirq);
55
+ * together indicate the operation.
94
+ sysbus_connect_irq(sbd, 1, rxirq);
56
+ */
95
+ sysbus_connect_irq(sbd, 2, txoverirq);
57
+ opcode = extract32(insn, 11, 3);
96
+ sysbus_connect_irq(sbd, 3, rxoverirq);
58
+ u = extract32(insn, 29, 1);
97
+ sysbus_connect_irq(sbd, 4, combirq);
59
+ a = extract32(insn, 23, 1);
60
+ is_q = extract32(insn, 30, 1);
61
+ rm = extract32(insn, 16, 5);
62
+ rn = extract32(insn, 5, 5);
63
+ rd = extract32(insn, 0, 5);
64
+
65
+ fpopcode = opcode | (a << 3) | (u << 4);
66
+ datasize = is_q ? 128 : 64;
67
+ elements = datasize / 16;
68
+
69
+ fpst = get_fpstatus_ptr(true);
70
+
71
+ for (pass = 0; pass < elements; pass++) {
72
+ TCGv_i32 tcg_op1 = tcg_temp_new_i32();
73
+ TCGv_i32 tcg_op2 = tcg_temp_new_i32();
74
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
75
+
76
+ read_vec_element_i32(s, tcg_op1, rn, pass, MO_16);
77
+ read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);
78
+
79
+ switch (fpopcode) {
80
+ default:
81
+ fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
82
+ __func__, insn, fpopcode, s->pc);
83
+ g_assert_not_reached();
84
+ }
85
+
86
+ write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
87
+ tcg_temp_free_i32(tcg_res);
88
+ tcg_temp_free_i32(tcg_op1);
89
+ tcg_temp_free_i32(tcg_op2);
90
+ }
91
+
92
+ tcg_temp_free_ptr(fpst);
93
+
94
+ clear_vec_high(s, is_q, rd);
95
+}
98
+}
96
+
99
+
97
static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q,
100
static void mps3r_common_init(MachineState *machine)
98
int size, int rn, int rd)
99
{
101
{
100
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
101
{ 0xce000000, 0xff808000, disas_crypto_four_reg },
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
102
{ 0xce800000, 0xffe00000, disas_crypto_xar },
104
MemoryRegion *sysmem = get_system_memory();
103
{ 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
105
+ DeviceState *gicdev;
104
+ { 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
106
105
{ 0x00000000, 0x00000000, NULL }
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
106
};
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
107
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
110
}
111
112
create_gic(mms, sysmem);
113
+ gicdev = DEVICE(&mms->gic);
114
+
115
+ /*
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
118
+ */
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
122
+ DeviceState *orgate;
123
+
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
126
+ TYPE_OR_IRQ);
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
129
+ qdev_realize(orgate, NULL, &error_fatal);
130
+ qdev_connect_gpio_out(orgate, 0,
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
132
+
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
139
+ }
140
+ /*
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
142
+ * together into IRQ 17
143
+ */
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
147
+ MPS3R_UART_MAX * 2);
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
150
+ qdev_get_gpio_in(gicdev, 17));
151
+
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
155
+
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
157
+ qdev_get_gpio_in(gicdev, txirq),
158
+ qdev_get_gpio_in(gicdev, rxirq),
159
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2),
160
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2 + 1),
161
+ qdev_get_gpio_in(gicdev, combirq));
162
+ }
163
164
mms->bootinfo.ram_size = machine->ram_size;
165
mms->bootinfo.board_id = -1;
108
--
166
--
109
2.16.2
167
2.34.1
110
168
111
169
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
2
board. These are all simple devices that just need to be created and
3
wired up.
2
4
3
This adds the full range of half-precision floating point to integral
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
instructions.
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
8
---
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 59 insertions(+)
5
11
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180227143852.11175-18-alex.bennee@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper-a64.h | 2 +
12
target/arm/helper-a64.c | 22 ++++++++
13
target/arm/translate-a64.c | 123 +++++++++++++++++++++++++++++++++++++++++++--
14
3 files changed, 142 insertions(+), 5 deletions(-)
15
16
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-a64.h
14
--- a/hw/arm/mps3r.c
19
+++ b/target/arm/helper-a64.h
15
+++ b/hw/arm/mps3r.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_maxnum2h, i32, i32, i32, ptr)
16
@@ -XXX,XX +XXX,XX @@
21
DEF_HELPER_3(advsimd_minnum2h, i32, i32, i32, ptr)
17
#include "sysemu/sysemu.h"
22
DEF_HELPER_3(advsimd_mulx2h, i32, i32, i32, ptr)
18
#include "hw/boards.h"
23
DEF_HELPER_4(advsimd_muladd2h, i32, i32, i32, i32, ptr)
19
#include "hw/or-irq.h"
24
+DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr)
20
+#include "hw/qdev-clock.h"
25
+DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
21
#include "hw/qdev-properties.h"
26
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
22
#include "hw/arm/boot.h"
27
index XXXXXXX..XXXXXXX 100644
23
#include "hw/arm/bsa.h"
28
--- a/target/arm/helper-a64.c
24
#include "hw/char/cmsdk-apb-uart.h"
29
+++ b/target/arm/helper-a64.c
25
+#include "hw/i2c/arm_sbcon_i2c.h"
30
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
26
#include "hw/intc/arm_gicv3.h"
31
int compare = float16_compare(f0, f1, fpst);
27
+#include "hw/misc/unimp.h"
32
return ADVSIMD_CMPRES(compare == float_relation_greater);
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
33
}
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
31
/* Define the layout of RAM and ROM in a board */
32
typedef struct RAMInfo {
33
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
34
CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
35
OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
36
OrIRQState uart_oflow;
37
+ CMSDKAPBWatchdog watchdog;
38
+ CMSDKAPBDualTimer dualtimer;
39
+ ArmSbconI2CState i2c[5];
40
+ Clock *clk;
41
};
42
43
#define TYPE_MPS3R_MACHINE "mps3r"
44
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
45
MemoryRegion *sysmem = get_system_memory();
46
DeviceState *gicdev;
47
48
+ mms->clk = clock_new(OBJECT(machine), "CLK");
49
+ clock_set_hz(mms->clk, CLK_FRQ);
34
+
50
+
35
+/* round to integral */
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
36
+float16 HELPER(advsimd_rinth_exact)(float16 x, void *fp_status)
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
37
+{
53
memory_region_add_subregion(sysmem, ri->base, mr);
38
+ return float16_round_to_int(x, fp_status);
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
39
+}
55
qdev_get_gpio_in(gicdev, combirq));
40
+
56
}
41
+float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
57
42
+{
58
+ for (int i = 0; i < 4; i++) {
43
+ int old_flags = get_float_exception_flags(fp_status), new_flags;
59
+ /* CMSDK GPIO controllers */
44
+ float16 ret;
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
45
+
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
46
+ ret = float16_round_to_int(x, fp_status);
47
+
48
+ /* Suppress any inexact exceptions the conversion produced */
49
+ if (!(old_flags & float_flag_inexact)) {
50
+ new_flags = get_float_exception_flags(fp_status);
51
+ set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status);
52
+ }
62
+ }
53
+
63
+
54
+ return ret;
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
55
+}
65
+ TYPE_CMSDK_APB_WATCHDOG);
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
57
index XXXXXXX..XXXXXXX 100644
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
58
--- a/target/arm/translate-a64.c
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
59
+++ b/target/arm/translate-a64.c
69
+ qdev_get_gpio_in(gicdev, 0));
60
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
70
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0xe0100000);
61
*/
62
static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
63
{
64
- int fpop, opcode, a;
65
+ int fpop, opcode, a, u;
66
+ int rn, rd;
67
+ bool is_q;
68
+ bool is_scalar;
69
+ bool only_in_vector = false;
70
+
71
+
71
+ int pass;
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
72
+ TCGv_i32 tcg_rmode = NULL;
73
+ TYPE_CMSDK_APB_DUALTIMER);
73
+ TCGv_ptr tcg_fpstatus = NULL;
74
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->clk);
74
+ bool need_rmode = false;
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
75
+ int rmode;
76
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
76
77
+ qdev_get_gpio_in(gicdev, 3));
77
if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 1,
78
unallocated_encoding(s);
79
+ qdev_get_gpio_in(gicdev, 1));
79
return;
80
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 2,
80
}
81
+ qdev_get_gpio_in(gicdev, 2));
81
82
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0xe0101000);
82
- if (!fp_access_check(s)) {
83
- return;
84
- }
85
+ rd = extract32(insn, 0, 5);
86
+ rn = extract32(insn, 5, 5);
87
88
- opcode = extract32(insn, 12, 4);
89
a = extract32(insn, 23, 1);
90
+ u = extract32(insn, 29, 1);
91
+ is_scalar = extract32(insn, 28, 1);
92
+ is_q = extract32(insn, 30, 1);
93
+
83
+
94
+ opcode = extract32(insn, 12, 5);
84
+ for (int i = 0; i < ARRAY_SIZE(mms->i2c); i++) {
95
fpop = deposit32(opcode, 5, 1, a);
85
+ static const hwaddr i2cbase[] = {0xe0102000, /* Touch */
96
+ fpop = deposit32(fpop, 6, 1, u);
86
+ 0xe0103000, /* Audio */
97
87
+ 0xe0107000, /* Shield0 */
98
switch (fpop) {
88
+ 0xe0108000, /* Shield1 */
99
+ case 0x18: /* FRINTN */
89
+ 0xe0109000}; /* DDR4 EEPROM */
100
+ need_rmode = true;
90
+ g_autofree char *s = g_strdup_printf("i2c%d", i);
101
+ only_in_vector = true;
102
+ rmode = FPROUNDING_TIEEVEN;
103
+ break;
104
+ case 0x19: /* FRINTM */
105
+ need_rmode = true;
106
+ only_in_vector = true;
107
+ rmode = FPROUNDING_NEGINF;
108
+ break;
109
+ case 0x38: /* FRINTP */
110
+ need_rmode = true;
111
+ only_in_vector = true;
112
+ rmode = FPROUNDING_POSINF;
113
+ break;
114
+ case 0x39: /* FRINTZ */
115
+ need_rmode = true;
116
+ only_in_vector = true;
117
+ rmode = FPROUNDING_ZERO;
118
+ break;
119
+ case 0x58: /* FRINTA */
120
+ need_rmode = true;
121
+ only_in_vector = true;
122
+ rmode = FPROUNDING_TIEAWAY;
123
+ break;
124
+ case 0x59: /* FRINTX */
125
+ case 0x79: /* FRINTI */
126
+ only_in_vector = true;
127
+ /* current rounding mode */
128
+ break;
129
default:
130
fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
131
g_assert_not_reached();
132
}
133
134
+
91
+
135
+ /* Check additional constraints for the scalar encoding */
92
+ object_initialize_child(OBJECT(mms), s, &mms->i2c[i],
136
+ if (is_scalar) {
93
+ TYPE_ARM_SBCON_I2C);
137
+ if (!is_q) {
94
+ sysbus_realize(SYS_BUS_DEVICE(&mms->i2c[i]), &error_fatal);
138
+ unallocated_encoding(s);
95
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->i2c[i]), 0, i2cbase[i]);
139
+ return;
96
+ if (i != 2 && i != 3) {
140
+ }
97
+ /*
141
+ /* FRINTxx is only in the vector form */
98
+ * internal-only bus: mark it full to avoid user-created
142
+ if (only_in_vector) {
99
+ * i2c devices being plugged into it.
143
+ unallocated_encoding(s);
100
+ */
144
+ return;
101
+ qbus_mark_full(qdev_get_child_bus(DEVICE(&mms->i2c[i]), "i2c"));
145
+ }
102
+ }
146
+ }
103
+ }
147
+
104
+
148
+ if (!fp_access_check(s)) {
105
mms->bootinfo.ram_size = machine->ram_size;
149
+ return;
106
mms->bootinfo.board_id = -1;
150
+ }
107
mms->bootinfo.loader_start = mmc->loader_start;
151
+
152
+ if (need_rmode) {
153
+ tcg_fpstatus = get_fpstatus_ptr(true);
154
+ }
155
+
156
+ if (need_rmode) {
157
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
158
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
159
+ }
160
+
161
+ if (is_scalar) {
162
+ /* no operations yet */
163
+ } else {
164
+ for (pass = 0; pass < (is_q ? 8 : 4); pass++) {
165
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
166
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
167
+
168
+ read_vec_element_i32(s, tcg_op, rn, pass, MO_16);
169
+
170
+ switch (fpop) {
171
+ case 0x18: /* FRINTN */
172
+ case 0x19: /* FRINTM */
173
+ case 0x38: /* FRINTP */
174
+ case 0x39: /* FRINTZ */
175
+ case 0x58: /* FRINTA */
176
+ case 0x79: /* FRINTI */
177
+ gen_helper_advsimd_rinth(tcg_res, tcg_op, tcg_fpstatus);
178
+ break;
179
+ case 0x59: /* FRINTX */
180
+ gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, tcg_fpstatus);
181
+ break;
182
+ default:
183
+ g_assert_not_reached();
184
+ }
185
+
186
+ write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
187
+
188
+ tcg_temp_free_i32(tcg_res);
189
+ tcg_temp_free_i32(tcg_op);
190
+ }
191
+
192
+ clear_vec_high(s, is_q, rd);
193
+ }
194
+
195
+ if (tcg_rmode) {
196
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
197
+ tcg_temp_free_i32(tcg_rmode);
198
+ }
199
+
200
+ if (tcg_fpstatus) {
201
+ tcg_temp_free_ptr(tcg_fpstatus);
202
+ }
203
}
204
205
/* AdvSIMD scalar x indexed element
206
--
108
--
207
2.16.2
109
2.34.1
208
110
209
111
diff view generated by jsdifflib
1
From: Corey Minyard <cminyard@mvista.com>
1
Add the remaining devices (or unimplemented-device stubs) for
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
QSPI write-config block, and ethernet.
2
4
3
Some devices need access to it.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
8
---
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 74 insertions(+)
4
11
5
Signed-off-by: Corey Minyard <cminyard@mvista.com>
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
8
Message-id: 20180227104903.21353-3-linus.walleij@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/i2c/i2c.h | 17 +++++++++++++++++
12
hw/i2c/core.c | 17 -----------------
13
2 files changed, 17 insertions(+), 17 deletions(-)
14
15
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/i2c/i2c.h
14
--- a/hw/arm/mps3r.c
18
+++ b/include/hw/i2c/i2c.h
15
+++ b/hw/arm/mps3r.c
19
@@ -XXX,XX +XXX,XX @@ struct I2CSlave {
16
@@ -XXX,XX +XXX,XX @@
20
uint8_t address;
17
#include "hw/char/cmsdk-apb-uart.h"
18
#include "hw/i2c/arm_sbcon_i2c.h"
19
#include "hw/intc/arm_gicv3.h"
20
+#include "hw/misc/mps2-scc.h"
21
+#include "hw/misc/mps2-fpgaio.h"
22
#include "hw/misc/unimp.h"
23
+#include "hw/net/lan9118.h"
24
+#include "hw/rtc/pl031.h"
25
+#include "hw/ssi/pl022.h"
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
30
CMSDKAPBWatchdog watchdog;
31
CMSDKAPBDualTimer dualtimer;
32
ArmSbconI2CState i2c[5];
33
+ PL022State spi[3];
34
+ MPS2SCC scc;
35
+ MPS2FPGAIO fpgaio;
36
+ UnimplementedDeviceState i2s_audio;
37
+ PL031State rtc;
38
Clock *clk;
21
};
39
};
22
40
23
+#define TYPE_I2C_BUS "i2c-bus"
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
24
+#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
42
}
25
+
43
};
26
+typedef struct I2CNode I2CNode;
44
27
+
45
+static const int an536_oscclk[] = {
28
+struct I2CNode {
46
+ 24000000, /* 24MHz reference for RTC and timers */
29
+ I2CSlave *elt;
47
+ 50000000, /* 50MHz ACLK */
30
+ QLIST_ENTRY(I2CNode) next;
48
+ 50000000, /* 50MHz MCLK */
49
+ 50000000, /* 50MHz GPUCLK */
50
+ 24576000, /* 24.576MHz AUDCLK */
51
+ 23750000, /* 23.75MHz HDLCDCLK */
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
31
+};
53
+};
32
+
54
+
33
+struct I2CBus {
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
34
+ BusState qbus;
56
const RAMInfo *raminfo)
35
+ QLIST_HEAD(, I2CNode) current_devs;
57
{
36
+ uint8_t saved_address;
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
37
+ bool broadcast;
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
38
+};
60
MemoryRegion *sysmem = get_system_memory();
61
DeviceState *gicdev;
62
+ QList *oscclk;
63
64
mms->clk = clock_new(OBJECT(machine), "CLK");
65
clock_set_hz(mms->clk, CLK_FRQ);
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
67
}
68
}
69
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
39
+
73
+
40
I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
41
void i2c_set_slave_address(I2CSlave *dev, uint8_t address);
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
42
int i2c_bus_busy(I2CBus *bus);
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
43
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
44
index XXXXXXX..XXXXXXX 100644
78
+ qdev_get_gpio_in(gicdev, 22 + i));
45
--- a/hw/i2c/core.c
79
+ }
46
+++ b/hw/i2c/core.c
80
+
47
@@ -XXX,XX +XXX,XX @@
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
48
#include "qemu/osdep.h"
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
49
#include "hw/i2c/i2c.h"
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
50
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
51
-typedef struct I2CNode I2CNode;
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
52
-
86
+ oscclk = qlist_new();
53
-struct I2CNode {
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
54
- I2CSlave *elt;
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
55
- QLIST_ENTRY(I2CNode) next;
89
+ }
56
-};
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
57
-
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
58
#define I2C_BROADCAST 0x00
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
59
93
+
60
-struct I2CBus {
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
61
- BusState qbus;
95
+
62
- QLIST_HEAD(, I2CNode) current_devs;
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
63
- uint8_t saved_address;
97
+ TYPE_MPS2_FPGAIO);
64
- bool broadcast;
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
65
-};
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
66
-
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
67
static Property i2c_props[] = {
101
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-dbgctrl", false);
68
DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
102
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
69
DEFINE_PROP_END_OF_LIST(),
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0xe0202000);
70
};
104
+
71
105
+ create_unimplemented_device("clcd", 0xe0209000, 0x1000);
72
-#define TYPE_I2C_BUS "i2c-bus"
106
+
73
-#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
107
+ object_initialize_child(OBJECT(mms), "rtc", &mms->rtc, TYPE_PL031);
74
-
108
+ sysbus_realize(SYS_BUS_DEVICE(&mms->rtc), &error_fatal);
75
static const TypeInfo i2c_bus_info = {
109
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->rtc), 0, 0xe020a000);
76
.name = TYPE_I2C_BUS,
110
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->rtc), 0,
77
.parent = TYPE_BUS,
111
+ qdev_get_gpio_in(gicdev, 4));
112
+
113
+ /*
114
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
115
+ * except that it doesn't support the checksum-offload feature.
116
+ */
117
+ lan9118_init(0xe0300000,
118
+ qdev_get_gpio_in(gicdev, 18));
119
+
120
+ create_unimplemented_device("usb", 0xe0301000, 0x1000);
121
+ create_unimplemented_device("qspi-write-config", 0xe0600000, 0x1000);
122
+
123
mms->bootinfo.ram_size = machine->ram_size;
124
mms->bootinfo.board_id = -1;
125
mms->bootinfo.loader_start = mmc->loader_start;
78
--
126
--
79
2.16.2
127
2.34.1
80
128
81
129
diff view generated by jsdifflib
Deleted patch
1
From: Linus Walleij <linus.walleij@linaro.org>
2
1
3
The tx function of the DDC I2C slave emulation was returning 1
4
on all writes resulting in NACK in the I2C bus. Changing it to
5
0 makes the DDC I2C work fine with bit-banged I2C such as the
6
versatile I2C.
7
8
I guess it was not affecting whatever I2C controller this was
9
used with until now, but with the Versatile I2C it surely
10
does not work.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
14
Message-id: 20180227104903.21353-4-linus.walleij@linaro.org
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/i2c/i2c-ddc.c | 4 ++--
19
1 file changed, 2 insertions(+), 2 deletions(-)
20
21
diff --git a/hw/i2c/i2c-ddc.c b/hw/i2c/i2c-ddc.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/i2c/i2c-ddc.c
24
+++ b/hw/i2c/i2c-ddc.c
25
@@ -XXX,XX +XXX,XX @@ static int i2c_ddc_tx(I2CSlave *i2c, uint8_t data)
26
s->reg = data;
27
s->firstbyte = false;
28
DPRINTF("[EDID] Written new pointer: %u\n", data);
29
- return 1;
30
+ return 0;
31
}
32
33
/* Ignore all writes */
34
s->reg++;
35
- return 1;
36
+ return 0;
37
}
38
39
static void i2c_ddc_init(Object *obj)
40
--
41
2.16.2
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Linus Walleij <linus.walleij@linaro.org>
2
1
3
This adds the SiI9022 (and implicitly EDID I2C) device to the ARM
4
Versatile Express machine, and selects the two I2C devices necessary
5
in the arm-softmmu.mak configuration so everything will build
6
smoothly.
7
8
I am implementing proper handling of the graphics in the Linux
9
kernel and adding proper emulation of SiI9022 and EDID makes the
10
driver probe as nicely as before, retrieving the resolutions
11
supported by the "QEMU monitor" and overall just working nice.
12
13
Cc: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
15
Message-id: 20180227104903.21353-6-linus.walleij@linaro.org
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
hw/arm/vexpress.c | 6 +++++-
21
default-configs/arm-softmmu.mak | 2 ++
22
2 files changed, 7 insertions(+), 1 deletion(-)
23
24
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/vexpress.c
27
+++ b/hw/arm/vexpress.c
28
@@ -XXX,XX +XXX,XX @@
29
#include "hw/arm/arm.h"
30
#include "hw/arm/primecell.h"
31
#include "hw/devices.h"
32
+#include "hw/i2c/i2c.h"
33
#include "net/net.h"
34
#include "sysemu/sysemu.h"
35
#include "hw/boards.h"
36
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
37
uint32_t sys_id;
38
DriveInfo *dinfo;
39
pflash_t *pflash0;
40
+ I2CBus *i2c;
41
ram_addr_t vram_size, sram_size;
42
MemoryRegion *sysmem = get_system_memory();
43
MemoryRegion *vram = g_new(MemoryRegion, 1);
44
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
45
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
46
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
47
48
- /* VE_SERIALDVI: not modelled */
49
+ dev = sysbus_create_simple("versatile_i2c", map[VE_SERIALDVI], NULL);
50
+ i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
51
+ i2c_create_slave(i2c, "sii9022", 0x39);
52
53
sysbus_create_simple("pl031", map[VE_RTC], pic[4]); /* RTC */
54
55
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
56
index XXXXXXX..XXXXXXX 100644
57
--- a/default-configs/arm-softmmu.mak
58
+++ b/default-configs/arm-softmmu.mak
59
@@ -XXX,XX +XXX,XX @@ CONFIG_STELLARIS_INPUT=y
60
CONFIG_STELLARIS_ENET=y
61
CONFIG_SSD0303=y
62
CONFIG_SSD0323=y
63
+CONFIG_DDC=y
64
+CONFIG_SII9022=y
65
CONFIG_ADS7846=y
66
CONFIG_MAX111X=y
67
CONFIG_SSI=y
68
--
69
2.16.2
70
71
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
This allows us to explicitly pass float16 to helpers rather than
4
assuming uint32_t and dealing with the result. Of course they will be
5
passed in i32 sized registers by default.
6
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180227143852.11175-2-alex.bennee@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/exec/helper-head.h | 3 +++
13
1 file changed, 3 insertions(+)
14
15
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/exec/helper-head.h
18
+++ b/include/exec/helper-head.h
19
@@ -XXX,XX +XXX,XX @@
20
#define dh_alias_int i32
21
#define dh_alias_i64 i64
22
#define dh_alias_s64 i64
23
+#define dh_alias_f16 i32
24
#define dh_alias_f32 i32
25
#define dh_alias_f64 i64
26
#define dh_alias_ptr ptr
27
@@ -XXX,XX +XXX,XX @@
28
#define dh_ctype_int int
29
#define dh_ctype_i64 uint64_t
30
#define dh_ctype_s64 int64_t
31
+#define dh_ctype_f16 float16
32
#define dh_ctype_f32 float32
33
#define dh_ctype_f64 float64
34
#define dh_ctype_ptr void *
35
@@ -XXX,XX +XXX,XX @@
36
#define dh_is_signed_s32 1
37
#define dh_is_signed_i64 0
38
#define dh_is_signed_s64 1
39
+#define dh_is_signed_f16 0
40
#define dh_is_signed_f32 0
41
#define dh_is_signed_f64 0
42
#define dh_is_signed_tl 0
43
--
44
2.16.2
45
46
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
We do implement all the opcodes.
4
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180227143852.11175-8-alex.bennee@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 3 +--
11
1 file changed, 1 insertion(+), 2 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void handle_3same_64(DisasContext *s, int opcode, bool u,
18
/* Handle 64x64->64 opcodes which are shared between the scalar
19
* and vector 3-same groups. We cover every opcode where size == 3
20
* is valid in either the three-reg-same (integer, not pairwise)
21
- * or scalar-three-reg-same groups. (Some opcodes are not yet
22
- * implemented.)
23
+ * or scalar-three-reg-same groups.
24
*/
25
TCGCond cond;
26
27
--
28
2.16.2
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
The fprintf is only there for debugging as the skeleton is added to,
4
it will be removed once the skeleton is complete.
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180227143852.11175-10-alex.bennee@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper-a64.h | 4 ++++
12
target/arm/helper-a64.c | 4 ++++
13
target/arm/translate-a64.c | 28 ++++++++++++++++++++++++++++
14
3 files changed, 36 insertions(+)
15
16
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-a64.h
19
+++ b/target/arm/helper-a64.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(advsimd_maxh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
21
DEF_HELPER_FLAGS_3(advsimd_minh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
22
DEF_HELPER_FLAGS_3(advsimd_maxnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
23
DEF_HELPER_FLAGS_3(advsimd_minnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
24
+DEF_HELPER_3(advsimd_addh, f16, f16, f16, ptr)
25
+DEF_HELPER_3(advsimd_subh, f16, f16, f16, ptr)
26
+DEF_HELPER_3(advsimd_mulh, f16, f16, f16, ptr)
27
+DEF_HELPER_3(advsimd_divh, f16, f16, f16, ptr)
28
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper-a64.c
31
+++ b/target/arm/helper-a64.c
32
@@ -XXX,XX +XXX,XX @@ float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
33
return float16_ ## name(a, b, fpst); \
34
}
35
36
+ADVSIMD_HALFOP(add)
37
+ADVSIMD_HALFOP(sub)
38
+ADVSIMD_HALFOP(mul)
39
+ADVSIMD_HALFOP(div)
40
ADVSIMD_HALFOP(min)
41
ADVSIMD_HALFOP(max)
42
ADVSIMD_HALFOP(minnum)
43
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/translate-a64.c
46
+++ b/target/arm/translate-a64.c
47
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
48
read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);
49
50
switch (fpopcode) {
51
+ case 0x0: /* FMAXNM */
52
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
53
+ break;
54
+ case 0x2: /* FADD */
55
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
56
+ break;
57
+ case 0x6: /* FMAX */
58
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
59
+ break;
60
+ case 0x8: /* FMINNM */
61
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
62
+ break;
63
+ case 0xa: /* FSUB */
64
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
65
+ break;
66
+ case 0xe: /* FMIN */
67
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
68
+ break;
69
+ case 0x13: /* FMUL */
70
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
71
+ break;
72
+ case 0x17: /* FDIV */
73
+ gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
74
+ break;
75
+ case 0x1a: /* FABD */
76
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
77
+ tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
78
+ break;
79
default:
80
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
81
__func__, insn, fpopcode, s->pc);
82
--
83
2.16.2
84
85
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Add documentation for the mps3-an536 board type.
2
2
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180227143852.11175-12-alex.bennee@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
7
---
6
---
8
target/arm/helper-a64.h | 2 ++
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
9
target/arm/helper-a64.c | 24 ++++++++++++++++++++++++
8
1 file changed, 34 insertions(+), 3 deletions(-)
10
target/arm/translate-a64.c | 15 +++++++++++++++
11
3 files changed, 41 insertions(+)
12
9
13
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-a64.h
12
--- a/docs/system/arm/mps2.rst
16
+++ b/target/arm/helper-a64.h
13
+++ b/docs/system/arm/mps2.rst
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_cge_f16, i32, f16, f16, ptr)
14
@@ -XXX,XX +XXX,XX @@
18
DEF_HELPER_3(advsimd_cgt_f16, i32, f16, f16, ptr)
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
19
DEF_HELPER_3(advsimd_acge_f16, i32, f16, f16, ptr)
16
-=========================================================================================================================================================
20
DEF_HELPER_3(advsimd_acgt_f16, i32, f16, f16, ptr)
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
21
+DEF_HELPER_3(advsimd_mulxh, f16, f16, f16, ptr)
18
+=========================================================================================================================================================================
22
+DEF_HELPER_4(advsimd_muladdh, f16, f16, f16, f16, ptr)
19
23
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
20
-These board models all use Arm M-profile CPUs.
24
index XXXXXXX..XXXXXXX 100644
21
+These board models use Arm M-profile or R-profile CPUs.
25
--- a/target/arm/helper-a64.c
22
26
+++ b/target/arm/helper-a64.c
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
27
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(max)
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
28
ADVSIMD_HALFOP(minnum)
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
29
ADVSIMD_HALFOP(maxnum)
26
30
27
QEMU models the following FPGA images:
31
+/* Data processing - scalar floating-point and advanced SIMD */
28
32
+float16 HELPER(advsimd_mulxh)(float16 a, float16 b, void *fpstp)
29
+FPGA images using M-profile CPUs:
33
+{
34
+ float_status *fpst = fpstp;
35
+
30
+
36
+ a = float16_squash_input_denormal(a, fpst);
31
``mps2-an385``
37
+ b = float16_squash_input_denormal(b, fpst);
32
Cortex-M3 as documented in Arm Application Note AN385
33
``mps2-an386``
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
35
``mps3-an547``
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
37
38
+FPGA images using R-profile CPUs:
38
+
39
+
39
+ if ((float16_is_zero(a) && float16_is_infinity(b)) ||
40
+``mps3-an536``
40
+ (float16_is_infinity(a) && float16_is_zero(b))) {
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
41
+ /* 2.0 with the sign bit set to sign(A) XOR sign(B) */
42
+ return make_float16((1U << 14) |
43
+ ((float16_val(a) ^ float16_val(b)) & (1U << 15)));
44
+ }
45
+ return float16_mul(a, b, fpst);
46
+}
47
+
42
+
48
+/* fused multiply-accumulate */
43
Differences between QEMU and real hardware:
49
+float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
44
50
+{
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
51
+ float_status *fpst = fpstp;
46
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
52
+ return float16_muladd(a, b, c, 0, fpst);
47
flash, but only as simple ROM, so attempting to rewrite the flash
53
+}
48
from the guest will fail
49
- QEMU does not model the USB controller in MPS3 boards
50
+- AN536 does not support runtime control of CPU reset and halt via
51
+ the SCC CFG_REG0 register.
52
+- AN536 does not support enabling or disabling the flash and ATCM
53
+ interfaces via the SCC CFG_REG1 register.
54
+- AN536 does not support setting of the initial vector table
55
+ base address via the SCC CFG_REG6 and CFG_REG7 register config,
56
+ and does not provide a mechanism for specifying these values at
57
+ startup, so all guest images must be built to start from TCM
58
+ (i.e. to expect the interrupt vector base at 0 from reset).
59
+- AN536 defaults to only creating a single CPU; this is the equivalent
60
+ of the way the real FPGA image usually runs with the second Cortex-R52
61
+ held in halt via the initial SCC CFG_REG0 register setting. You can
62
+ create the second CPU with ``-smp 2``; both CPUs will then start
63
+ execution immediately on startup.
54
+
64
+
55
/*
65
+Note that for the AN536 the first UART is accessible only by
56
* Floating point comparisons produce an integer result. Softfloat
66
+CPU0, and the second UART is accessible only by CPU1. The
57
* routines return float_relation types which we convert to the 0/-1
67
+first UART accessible shared between both CPUs is the third
58
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
68
+UART. Guest software might therefore be built to use either
59
index XXXXXXX..XXXXXXX 100644
69
+the first UART or the third UART; if you don't see any output
60
--- a/target/arm/translate-a64.c
70
+from the UART you are looking at, try one of the others.
61
+++ b/target/arm/translate-a64.c
71
+(Even if the AN536 machine is started with a single CPU and so
62
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
72
+no "CPU1-only UART", the UART numbering remains the same,
63
case 0x0: /* FMAXNM */
73
+with the third UART being the first of the shared ones.)
64
gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
74
65
break;
75
Machine-specific options
66
+ case 0x1: /* FMLA */
76
""""""""""""""""""""""""
67
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
68
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
69
+ fpst);
70
+ break;
71
case 0x2: /* FADD */
72
gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
73
break;
74
+ case 0x3: /* FMULX */
75
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
76
+ break;
77
case 0x4: /* FCMEQ */
78
gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
79
break;
80
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
81
case 0x8: /* FMINNM */
82
gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
83
break;
84
+ case 0x9: /* FMLS */
85
+ /* As usual for ARM, separate negation for fused multiply-add */
86
+ tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
87
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
88
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
89
+ fpst);
90
+ break;
91
case 0xa: /* FSUB */
92
gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
93
break;
94
--
77
--
95
2.16.2
78
2.34.1
96
79
97
80
diff view generated by jsdifflib