1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
1
Last pullreq before 6.0 softfreeze: a few minor feature patches,
2
some bugfixes, some cleanups.
2
3
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit 6f34661b6c97a37a5efc27d31c037ddeda4547e2:
6
7
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
8
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-branch-for-6.0-pull-request' into staging (2021-03-11 18:55:27 +0000)
8
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
10
9
11
are available in the Git repository at:
10
are available in the Git repository at:
12
11
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210312-1
14
13
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
14
for you to fetch changes up to 41f09f2e9f09e4dd386d84174a6dcb5136af17ca:
16
15
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
16
hw/display/pxa2xx: Inline template header (2021-03-12 13:26:08 +0000)
18
17
19
----------------------------------------------------------------
18
----------------------------------------------------------------
20
target-arm queue:
19
target-arm queue:
21
* Start of conversion of Neon insns to decodetree
20
* versal: Support XRAMs and XRAM controller
22
* versal board: support SD and RTC
21
* smmu: Various minor bug fixes
23
* Implement ARMv8.2-TTS2UXN
22
* SVE emulation: fix bugs handling odd vector lengths
24
* Make VQDMULL undefined when U=1
23
* allwinner-sun8i-emac: traverse transmit queue using TX_CUR_DESC register value
25
* Some minor code cleanups
24
* tests/acceptance: fix orangepi-pc acceptance tests
25
* hw/timer/sse-timer: Propagate eventual error in sse_timer_realize()
26
* hw/arm/virt: KVM: The IPA lower bound is 32
27
* npcm7xx: support MFT module
28
* pl110, pxa2xx_lcd: tidy up template headers
26
29
27
----------------------------------------------------------------
30
----------------------------------------------------------------
28
Edgar E. Iglesias (11):
31
Andrew Jones (2):
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
32
accel: kvm: Fix kvm_type invocation
30
hw/arm: versal: Move misplaced comment
33
hw/arm/virt: KVM: The IPA lower bound is 32
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
32
hw/arm: versal: Embed the UARTs into the SoC type
33
hw/arm: versal: Embed the GEMs into the SoC type
34
hw/arm: versal: Embed the ADMAs into the SoC type
35
hw/arm: versal: Embed the APUs into the SoC type
36
hw/arm: versal: Add support for SD
37
hw/arm: versal: Add support for the RTC
38
hw/arm: versal-virt: Add support for SD
39
hw/arm: versal-virt: Add support for the RTC
40
34
41
Fredrik Strupe (1):
35
Edgar E. Iglesias (2):
42
target/arm: Make VQDMULL undefined when U=1
36
hw/misc: versal: Add a model of the XRAM controller
37
hw/arm: versal: Add support for the XRAMs
43
38
44
Peter Maydell (25):
39
Eric Auger (7):
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
40
intel_iommu: Fix mask may be uninitialized in vtd_context_device_invalidate
46
target/arm: Use enum constant in get_phys_addr_lpae() call
41
dma: Introduce dma_aligned_pow2_mask()
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
42
virtio-iommu: Handle non power of 2 range invalidations
48
target/arm: Implement ARMv8.2-TTS2UXN
43
hw/arm/smmu-common: Fix smmu_iotlb_inv_iova when asid is not set
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
44
hw/arm/smmuv3: Enforce invalidation on a power of two range
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
45
hw/arm/smmuv3: Fix SMMU_CMD_CFGI_STE_RANGE handling
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
46
hw/arm/smmuv3: Uniformize sid traces
52
target/arm: Add stubs for AArch32 Neon decodetree
53
target/arm: Convert VCMLA (vector) to decodetree
54
target/arm: Convert VCADD (vector) to decodetree
55
target/arm: Convert V[US]DOT (vector) to decodetree
56
target/arm: Convert VFM[AS]L (vector) to decodetree
57
target/arm: Convert VCMLA (scalar) to decodetree
58
target/arm: Convert V[US]DOT (scalar) to decodetree
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
60
target/arm: Convert Neon load/store multiple structures to decodetree
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
62
target/arm: Convert Neon 'load/store single structure' to decodetree
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
69
target/arm: Move gen_ function typedefs to translate.h
70
47
71
Philippe Mathieu-Daudé (2):
48
Hao Wu (5):
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
49
hw/misc: Add GPIOs for duty in NPCM7xx PWM
73
target/arm: Use uint64_t for midr field in CPU state struct
50
hw/misc: Add NPCM7XX MFT Module
51
hw/arm: Add MFT device to NPCM7xx Soc
52
hw/arm: Connect PWM fans in NPCM7XX boards
53
tests/qtest: Test PWM fan RPM using MFT in PWM test
74
54
75
include/hw/arm/xlnx-versal.h | 31 +-
55
Niek Linnenbank (5):
76
target/arm/cpu-param.h | 2 +-
56
hw/net/allwinner-sun8i-emac: traverse transmit queue using TX_CUR_DESC register value
77
target/arm/cpu.h | 38 ++-
57
tests/acceptance/boot_linux_console: remove Armbian 19.11.3 bionic test for orangepi-pc machine
78
target/arm/translate-a64.h | 9 -
58
tests/acceptance/boot_linux_console: change URL for test_arm_orangepi_bionic_20_08
79
target/arm/translate.h | 26 ++
59
tests/acceptance: update sunxi kernel from armbian to 5.10.16
80
target/arm/neon-dp.decode | 86 +++++
60
tests/acceptance: drop ARMBIAN_ARTIFACTS_CACHED condition for orangepi-pc, cubieboard tests
81
target/arm/neon-ls.decode | 52 +++
82
target/arm/neon-shared.decode | 66 ++++
83
hw/arm/mps2-tz.c | 2 +-
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
85
hw/arm/xlnx-versal.c | 115 +++++--
86
target/arm/cpu.c | 3 +-
87
target/arm/cpu64.c | 8 +-
88
target/arm/helper.c | 183 ++++------
89
target/arm/translate-a64.c | 17 -
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
91
target/arm/translate-vfp.inc.c | 6 -
92
target/arm/translate.c | 716 +++-------------------------------------
93
target/arm/Makefile.objs | 18 +
94
19 files changed, 1302 insertions(+), 864 deletions(-)
95
create mode 100644 target/arm/neon-dp.decode
96
create mode 100644 target/arm/neon-ls.decode
97
create mode 100644 target/arm/neon-shared.decode
98
create mode 100644 target/arm/translate-neon.inc.c
99
61
62
Peter Maydell (9):
63
hw/display/pl110: Remove dead code for non-32-bpp surfaces
64
hw/display/pl110: Pull included-once parts of template header into pl110.c
65
hw/display/pl110: Remove use of BITS from pl110_template.h
66
hw/display/pxa2xx_lcd: Remove dead code for non-32-bpp surfaces
67
hw/display/pxa2xx_lcd: Remove dest_width state field
68
hw/display/pxa2xx: Remove use of BITS in pxa2xx_template.h
69
hw/display/pxa2xx: Apply brace-related coding style fixes to template header
70
hw/display/pxa2xx: Apply whitespace-only coding style fixes to template header
71
hw/display/pxa2xx: Inline template header
72
73
Philippe Mathieu-Daudé (1):
74
hw/timer/sse-timer: Propagate eventual error in sse_timer_realize()
75
76
Richard Henderson (8):
77
target/arm: Fix sve_uzp_p vs odd vector lengths
78
target/arm: Fix sve_zip_p vs odd vector lengths
79
target/arm: Fix sve_punpk_p vs odd vector lengths
80
target/arm: Update find_last_active for PREDDESC
81
target/arm: Update BRKA, BRKB, BRKN for PREDDESC
82
target/arm: Update CNTP for PREDDESC
83
target/arm: Update WHILE for PREDDESC
84
target/arm: Update sve reduction vs simd_desc
85
86
docs/system/arm/nuvoton.rst | 2 +-
87
docs/system/arm/xlnx-versal-virt.rst | 1 +
88
hw/arm/smmu-internal.h | 5 +
89
hw/display/pl110_template.h | 120 +-------
90
hw/display/pxa2xx_template.h | 447 ---------------------------
91
include/hw/arm/npcm7xx.h | 13 +-
92
include/hw/arm/xlnx-versal.h | 13 +
93
include/hw/boards.h | 1 +
94
include/hw/misc/npcm7xx_mft.h | 70 +++++
95
include/hw/misc/npcm7xx_pwm.h | 4 +-
96
include/hw/misc/xlnx-versal-xramc.h | 97 ++++++
97
include/sysemu/dma.h | 12 +
98
target/arm/kvm_arm.h | 6 +-
99
accel/kvm/kvm-all.c | 2 +
100
hw/arm/npcm7xx.c | 45 ++-
101
hw/arm/npcm7xx_boards.c | 99 ++++++
102
hw/arm/smmu-common.c | 32 +-
103
hw/arm/smmuv3.c | 58 ++--
104
hw/arm/virt.c | 23 +-
105
hw/arm/xlnx-versal.c | 36 +++
106
hw/display/pl110.c | 123 +++++---
107
hw/display/pxa2xx_lcd.c | 520 ++++++++++++++++++++++++++-----
108
hw/i386/intel_iommu.c | 32 +-
109
hw/misc/npcm7xx_mft.c | 540 +++++++++++++++++++++++++++++++++
110
hw/misc/npcm7xx_pwm.c | 4 +
111
hw/misc/xlnx-versal-xramc.c | 253 +++++++++++++++
112
hw/net/allwinner-sun8i-emac.c | 62 ++--
113
hw/timer/sse-timer.c | 1 +
114
hw/virtio/virtio-iommu.c | 19 +-
115
softmmu/dma-helpers.c | 26 ++
116
target/arm/kvm.c | 4 +-
117
target/arm/sve_helper.c | 107 ++++---
118
target/arm/translate-sve.c | 26 +-
119
tests/qtest/npcm7xx_pwm-test.c | 205 ++++++++++++-
120
hw/arm/trace-events | 24 +-
121
hw/misc/meson.build | 2 +
122
hw/misc/trace-events | 8 +
123
tests/acceptance/boot_linux_console.py | 120 +++-----
124
tests/acceptance/replay_kernel.py | 10 +-
125
39 files changed, 2235 insertions(+), 937 deletions(-)
126
delete mode 100644 hw/display/pxa2xx_template.h
127
create mode 100644 include/hw/misc/npcm7xx_mft.h
128
create mode 100644 include/hw/misc/xlnx-versal-xramc.h
129
create mode 100644 hw/misc/npcm7xx_mft.c
130
create mode 100644 hw/misc/xlnx-versal-xramc.c
131
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Remove inclusion of arm_gicv3_common.h, this already gets
3
Add a model of the Xilinx Versal Accelerator RAM (XRAM).
4
included via xlnx-versal.h.
4
This is mainly a stub to make firmware happy. The size of
5
the RAMs can be probed. The interrupt mask logic is
6
modelled but none of the interrups will ever be raised
7
unless injected.
5
8
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210308224637.2949533-2-edgar.iglesias@gmail.com
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/arm/xlnx-versal.c | 1 -
14
include/hw/misc/xlnx-versal-xramc.h | 97 +++++++++++
13
1 file changed, 1 deletion(-)
15
hw/misc/xlnx-versal-xramc.c | 253 ++++++++++++++++++++++++++++
14
16
hw/misc/meson.build | 1 +
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
17
3 files changed, 351 insertions(+)
18
create mode 100644 include/hw/misc/xlnx-versal-xramc.h
19
create mode 100644 hw/misc/xlnx-versal-xramc.c
20
21
diff --git a/include/hw/misc/xlnx-versal-xramc.h b/include/hw/misc/xlnx-versal-xramc.h
22
new file mode 100644
23
index XXXXXXX..XXXXXXX
24
--- /dev/null
25
+++ b/include/hw/misc/xlnx-versal-xramc.h
26
@@ -XXX,XX +XXX,XX @@
27
+/*
28
+ * QEMU model of the Xilinx XRAM Controller.
29
+ *
30
+ * Copyright (c) 2021 Xilinx Inc.
31
+ * SPDX-License-Identifier: GPL-2.0-or-later
32
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
33
+ */
34
+
35
+#ifndef XLNX_VERSAL_XRAMC_H
36
+#define XLNX_VERSAL_XRAMC_H
37
+
38
+#include "hw/sysbus.h"
39
+#include "hw/register.h"
40
+
41
+#define TYPE_XLNX_XRAM_CTRL "xlnx.versal-xramc"
42
+
43
+#define XLNX_XRAM_CTRL(obj) \
44
+ OBJECT_CHECK(XlnxXramCtrl, (obj), TYPE_XLNX_XRAM_CTRL)
45
+
46
+REG32(XRAM_ERR_CTRL, 0x0)
47
+ FIELD(XRAM_ERR_CTRL, UE_RES, 3, 1)
48
+ FIELD(XRAM_ERR_CTRL, PWR_ERR_RES, 2, 1)
49
+ FIELD(XRAM_ERR_CTRL, PZ_ERR_RES, 1, 1)
50
+ FIELD(XRAM_ERR_CTRL, APB_ERR_RES, 0, 1)
51
+REG32(XRAM_ISR, 0x4)
52
+ FIELD(XRAM_ISR, INV_APB, 0, 1)
53
+REG32(XRAM_IMR, 0x8)
54
+ FIELD(XRAM_IMR, INV_APB, 0, 1)
55
+REG32(XRAM_IEN, 0xc)
56
+ FIELD(XRAM_IEN, INV_APB, 0, 1)
57
+REG32(XRAM_IDS, 0x10)
58
+ FIELD(XRAM_IDS, INV_APB, 0, 1)
59
+REG32(XRAM_ECC_CNTL, 0x14)
60
+ FIELD(XRAM_ECC_CNTL, FI_MODE, 2, 1)
61
+ FIELD(XRAM_ECC_CNTL, DET_ONLY, 1, 1)
62
+ FIELD(XRAM_ECC_CNTL, ECC_ON_OFF, 0, 1)
63
+REG32(XRAM_CLR_EXE, 0x18)
64
+ FIELD(XRAM_CLR_EXE, MON_7, 7, 1)
65
+ FIELD(XRAM_CLR_EXE, MON_6, 6, 1)
66
+ FIELD(XRAM_CLR_EXE, MON_5, 5, 1)
67
+ FIELD(XRAM_CLR_EXE, MON_4, 4, 1)
68
+ FIELD(XRAM_CLR_EXE, MON_3, 3, 1)
69
+ FIELD(XRAM_CLR_EXE, MON_2, 2, 1)
70
+ FIELD(XRAM_CLR_EXE, MON_1, 1, 1)
71
+ FIELD(XRAM_CLR_EXE, MON_0, 0, 1)
72
+REG32(XRAM_CE_FFA, 0x1c)
73
+ FIELD(XRAM_CE_FFA, ADDR, 0, 20)
74
+REG32(XRAM_CE_FFD0, 0x20)
75
+REG32(XRAM_CE_FFD1, 0x24)
76
+REG32(XRAM_CE_FFD2, 0x28)
77
+REG32(XRAM_CE_FFD3, 0x2c)
78
+REG32(XRAM_CE_FFE, 0x30)
79
+ FIELD(XRAM_CE_FFE, SYNDROME, 0, 16)
80
+REG32(XRAM_UE_FFA, 0x34)
81
+ FIELD(XRAM_UE_FFA, ADDR, 0, 20)
82
+REG32(XRAM_UE_FFD0, 0x38)
83
+REG32(XRAM_UE_FFD1, 0x3c)
84
+REG32(XRAM_UE_FFD2, 0x40)
85
+REG32(XRAM_UE_FFD3, 0x44)
86
+REG32(XRAM_UE_FFE, 0x48)
87
+ FIELD(XRAM_UE_FFE, SYNDROME, 0, 16)
88
+REG32(XRAM_FI_D0, 0x4c)
89
+REG32(XRAM_FI_D1, 0x50)
90
+REG32(XRAM_FI_D2, 0x54)
91
+REG32(XRAM_FI_D3, 0x58)
92
+REG32(XRAM_FI_SY, 0x5c)
93
+ FIELD(XRAM_FI_SY, DATA, 0, 16)
94
+REG32(XRAM_RMW_UE_FFA, 0x70)
95
+ FIELD(XRAM_RMW_UE_FFA, ADDR, 0, 20)
96
+REG32(XRAM_FI_CNTR, 0x74)
97
+ FIELD(XRAM_FI_CNTR, COUNT, 0, 24)
98
+REG32(XRAM_IMP, 0x80)
99
+ FIELD(XRAM_IMP, SIZE, 0, 4)
100
+REG32(XRAM_PRDY_DBG, 0x84)
101
+ FIELD(XRAM_PRDY_DBG, ISLAND3, 12, 4)
102
+ FIELD(XRAM_PRDY_DBG, ISLAND2, 8, 4)
103
+ FIELD(XRAM_PRDY_DBG, ISLAND1, 4, 4)
104
+ FIELD(XRAM_PRDY_DBG, ISLAND0, 0, 4)
105
+REG32(XRAM_SAFETY_CHK, 0xff8)
106
+
107
+#define XRAM_CTRL_R_MAX (R_XRAM_SAFETY_CHK + 1)
108
+
109
+typedef struct XlnxXramCtrl {
110
+ SysBusDevice parent_obj;
111
+ MemoryRegion ram;
112
+ qemu_irq irq;
113
+
114
+ struct {
115
+ uint64_t size;
116
+ unsigned int encoded_size;
117
+ } cfg;
118
+
119
+ RegisterInfoArray *reg_array;
120
+ uint32_t regs[XRAM_CTRL_R_MAX];
121
+ RegisterInfo regs_info[XRAM_CTRL_R_MAX];
122
+} XlnxXramCtrl;
123
+#endif
124
diff --git a/hw/misc/xlnx-versal-xramc.c b/hw/misc/xlnx-versal-xramc.c
125
new file mode 100644
126
index XXXXXXX..XXXXXXX
127
--- /dev/null
128
+++ b/hw/misc/xlnx-versal-xramc.c
129
@@ -XXX,XX +XXX,XX @@
130
+/*
131
+ * QEMU model of the Xilinx XRAM Controller.
132
+ *
133
+ * Copyright (c) 2021 Xilinx Inc.
134
+ * SPDX-License-Identifier: GPL-2.0-or-later
135
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
136
+ */
137
+
138
+#include "qemu/osdep.h"
139
+#include "qemu/units.h"
140
+#include "qapi/error.h"
141
+#include "migration/vmstate.h"
142
+#include "hw/sysbus.h"
143
+#include "hw/register.h"
144
+#include "hw/qdev-properties.h"
145
+#include "hw/irq.h"
146
+#include "hw/misc/xlnx-versal-xramc.h"
147
+
148
+#ifndef XLNX_XRAM_CTRL_ERR_DEBUG
149
+#define XLNX_XRAM_CTRL_ERR_DEBUG 0
150
+#endif
151
+
152
+static void xram_update_irq(XlnxXramCtrl *s)
153
+{
154
+ bool pending = s->regs[R_XRAM_ISR] & ~s->regs[R_XRAM_IMR];
155
+ qemu_set_irq(s->irq, pending);
156
+}
157
+
158
+static void xram_isr_postw(RegisterInfo *reg, uint64_t val64)
159
+{
160
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
161
+ xram_update_irq(s);
162
+}
163
+
164
+static uint64_t xram_ien_prew(RegisterInfo *reg, uint64_t val64)
165
+{
166
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
167
+ uint32_t val = val64;
168
+
169
+ s->regs[R_XRAM_IMR] &= ~val;
170
+ xram_update_irq(s);
171
+ return 0;
172
+}
173
+
174
+static uint64_t xram_ids_prew(RegisterInfo *reg, uint64_t val64)
175
+{
176
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
177
+ uint32_t val = val64;
178
+
179
+ s->regs[R_XRAM_IMR] |= val;
180
+ xram_update_irq(s);
181
+ return 0;
182
+}
183
+
184
+static const RegisterAccessInfo xram_ctrl_regs_info[] = {
185
+ { .name = "XRAM_ERR_CTRL", .addr = A_XRAM_ERR_CTRL,
186
+ .reset = 0xf,
187
+ .rsvd = 0xfffffff0,
188
+ },{ .name = "XRAM_ISR", .addr = A_XRAM_ISR,
189
+ .rsvd = 0xfffff800,
190
+ .w1c = 0x7ff,
191
+ .post_write = xram_isr_postw,
192
+ },{ .name = "XRAM_IMR", .addr = A_XRAM_IMR,
193
+ .reset = 0x7ff,
194
+ .rsvd = 0xfffff800,
195
+ .ro = 0x7ff,
196
+ },{ .name = "XRAM_IEN", .addr = A_XRAM_IEN,
197
+ .rsvd = 0xfffff800,
198
+ .pre_write = xram_ien_prew,
199
+ },{ .name = "XRAM_IDS", .addr = A_XRAM_IDS,
200
+ .rsvd = 0xfffff800,
201
+ .pre_write = xram_ids_prew,
202
+ },{ .name = "XRAM_ECC_CNTL", .addr = A_XRAM_ECC_CNTL,
203
+ .rsvd = 0xfffffff8,
204
+ },{ .name = "XRAM_CLR_EXE", .addr = A_XRAM_CLR_EXE,
205
+ .rsvd = 0xffffff00,
206
+ },{ .name = "XRAM_CE_FFA", .addr = A_XRAM_CE_FFA,
207
+ .rsvd = 0xfff00000,
208
+ .ro = 0xfffff,
209
+ },{ .name = "XRAM_CE_FFD0", .addr = A_XRAM_CE_FFD0,
210
+ .ro = 0xffffffff,
211
+ },{ .name = "XRAM_CE_FFD1", .addr = A_XRAM_CE_FFD1,
212
+ .ro = 0xffffffff,
213
+ },{ .name = "XRAM_CE_FFD2", .addr = A_XRAM_CE_FFD2,
214
+ .ro = 0xffffffff,
215
+ },{ .name = "XRAM_CE_FFD3", .addr = A_XRAM_CE_FFD3,
216
+ .ro = 0xffffffff,
217
+ },{ .name = "XRAM_CE_FFE", .addr = A_XRAM_CE_FFE,
218
+ .rsvd = 0xffff0000,
219
+ .ro = 0xffff,
220
+ },{ .name = "XRAM_UE_FFA", .addr = A_XRAM_UE_FFA,
221
+ .rsvd = 0xfff00000,
222
+ .ro = 0xfffff,
223
+ },{ .name = "XRAM_UE_FFD0", .addr = A_XRAM_UE_FFD0,
224
+ .ro = 0xffffffff,
225
+ },{ .name = "XRAM_UE_FFD1", .addr = A_XRAM_UE_FFD1,
226
+ .ro = 0xffffffff,
227
+ },{ .name = "XRAM_UE_FFD2", .addr = A_XRAM_UE_FFD2,
228
+ .ro = 0xffffffff,
229
+ },{ .name = "XRAM_UE_FFD3", .addr = A_XRAM_UE_FFD3,
230
+ .ro = 0xffffffff,
231
+ },{ .name = "XRAM_UE_FFE", .addr = A_XRAM_UE_FFE,
232
+ .rsvd = 0xffff0000,
233
+ .ro = 0xffff,
234
+ },{ .name = "XRAM_FI_D0", .addr = A_XRAM_FI_D0,
235
+ },{ .name = "XRAM_FI_D1", .addr = A_XRAM_FI_D1,
236
+ },{ .name = "XRAM_FI_D2", .addr = A_XRAM_FI_D2,
237
+ },{ .name = "XRAM_FI_D3", .addr = A_XRAM_FI_D3,
238
+ },{ .name = "XRAM_FI_SY", .addr = A_XRAM_FI_SY,
239
+ .rsvd = 0xffff0000,
240
+ },{ .name = "XRAM_RMW_UE_FFA", .addr = A_XRAM_RMW_UE_FFA,
241
+ .rsvd = 0xfff00000,
242
+ .ro = 0xfffff,
243
+ },{ .name = "XRAM_FI_CNTR", .addr = A_XRAM_FI_CNTR,
244
+ .rsvd = 0xff000000,
245
+ },{ .name = "XRAM_IMP", .addr = A_XRAM_IMP,
246
+ .reset = 0x4,
247
+ .rsvd = 0xfffffff0,
248
+ .ro = 0xf,
249
+ },{ .name = "XRAM_PRDY_DBG", .addr = A_XRAM_PRDY_DBG,
250
+ .reset = 0xffff,
251
+ .rsvd = 0xffff0000,
252
+ .ro = 0xffff,
253
+ },{ .name = "XRAM_SAFETY_CHK", .addr = A_XRAM_SAFETY_CHK,
254
+ }
255
+};
256
+
257
+static void xram_ctrl_reset_enter(Object *obj, ResetType type)
258
+{
259
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
260
+ unsigned int i;
261
+
262
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
263
+ register_reset(&s->regs_info[i]);
264
+ }
265
+
266
+ ARRAY_FIELD_DP32(s->regs, XRAM_IMP, SIZE, s->cfg.encoded_size);
267
+}
268
+
269
+static void xram_ctrl_reset_hold(Object *obj)
270
+{
271
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
272
+
273
+ xram_update_irq(s);
274
+}
275
+
276
+static const MemoryRegionOps xram_ctrl_ops = {
277
+ .read = register_read_memory,
278
+ .write = register_write_memory,
279
+ .endianness = DEVICE_LITTLE_ENDIAN,
280
+ .valid = {
281
+ .min_access_size = 4,
282
+ .max_access_size = 4,
283
+ },
284
+};
285
+
286
+static void xram_ctrl_realize(DeviceState *dev, Error **errp)
287
+{
288
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
289
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(dev);
290
+
291
+ switch (s->cfg.size) {
292
+ case 64 * KiB:
293
+ s->cfg.encoded_size = 0;
294
+ break;
295
+ case 128 * KiB:
296
+ s->cfg.encoded_size = 1;
297
+ break;
298
+ case 256 * KiB:
299
+ s->cfg.encoded_size = 2;
300
+ break;
301
+ case 512 * KiB:
302
+ s->cfg.encoded_size = 3;
303
+ break;
304
+ case 1 * MiB:
305
+ s->cfg.encoded_size = 4;
306
+ break;
307
+ default:
308
+ error_setg(errp, "Unsupported XRAM size %" PRId64, s->cfg.size);
309
+ return;
310
+ }
311
+
312
+ memory_region_init_ram(&s->ram, OBJECT(s),
313
+ object_get_canonical_path_component(OBJECT(s)),
314
+ s->cfg.size, &error_fatal);
315
+ sysbus_init_mmio(sbd, &s->ram);
316
+}
317
+
318
+static void xram_ctrl_init(Object *obj)
319
+{
320
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
321
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
322
+
323
+ s->reg_array =
324
+ register_init_block32(DEVICE(obj), xram_ctrl_regs_info,
325
+ ARRAY_SIZE(xram_ctrl_regs_info),
326
+ s->regs_info, s->regs,
327
+ &xram_ctrl_ops,
328
+ XLNX_XRAM_CTRL_ERR_DEBUG,
329
+ XRAM_CTRL_R_MAX * 4);
330
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
331
+ sysbus_init_irq(sbd, &s->irq);
332
+}
333
+
334
+static void xram_ctrl_finalize(Object *obj)
335
+{
336
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
337
+ register_finalize_block(s->reg_array);
338
+}
339
+
340
+static const VMStateDescription vmstate_xram_ctrl = {
341
+ .name = TYPE_XLNX_XRAM_CTRL,
342
+ .version_id = 1,
343
+ .minimum_version_id = 1,
344
+ .fields = (VMStateField[]) {
345
+ VMSTATE_UINT32_ARRAY(regs, XlnxXramCtrl, XRAM_CTRL_R_MAX),
346
+ VMSTATE_END_OF_LIST(),
347
+ }
348
+};
349
+
350
+static Property xram_ctrl_properties[] = {
351
+ DEFINE_PROP_UINT64("size", XlnxXramCtrl, cfg.size, 1 * MiB),
352
+ DEFINE_PROP_END_OF_LIST(),
353
+};
354
+
355
+static void xram_ctrl_class_init(ObjectClass *klass, void *data)
356
+{
357
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
358
+ DeviceClass *dc = DEVICE_CLASS(klass);
359
+
360
+ dc->realize = xram_ctrl_realize;
361
+ dc->vmsd = &vmstate_xram_ctrl;
362
+ device_class_set_props(dc, xram_ctrl_properties);
363
+
364
+ rc->phases.enter = xram_ctrl_reset_enter;
365
+ rc->phases.hold = xram_ctrl_reset_hold;
366
+}
367
+
368
+static const TypeInfo xram_ctrl_info = {
369
+ .name = TYPE_XLNX_XRAM_CTRL,
370
+ .parent = TYPE_SYS_BUS_DEVICE,
371
+ .instance_size = sizeof(XlnxXramCtrl),
372
+ .class_init = xram_ctrl_class_init,
373
+ .instance_init = xram_ctrl_init,
374
+ .instance_finalize = xram_ctrl_finalize,
375
+};
376
+
377
+static void xram_ctrl_register_types(void)
378
+{
379
+ type_register_static(&xram_ctrl_info);
380
+}
381
+
382
+type_init(xram_ctrl_register_types)
383
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
16
index XXXXXXX..XXXXXXX 100644
384
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
385
--- a/hw/misc/meson.build
18
+++ b/hw/arm/xlnx-versal.c
386
+++ b/hw/misc/meson.build
19
@@ -XXX,XX +XXX,XX @@
387
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
20
#include "hw/arm/boot.h"
388
))
21
#include "kvm_arm.h"
389
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
22
#include "hw/misc/unimp.h"
390
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
23
-#include "hw/intc/arm_gicv3_common.h"
391
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-xramc.c'))
24
#include "hw/arm/xlnx-versal.h"
392
softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: files('stm32f2xx_syscfg.c'))
25
#include "hw/char/pl011.h"
393
softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: files('stm32f4xx_syscfg.c'))
26
394
softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: files('stm32f4xx_exti.c'))
27
--
395
--
28
2.20.1
396
2.20.1
29
397
30
398
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Add support for SD.
3
Connect the support for the Versal Accelerator RAMs (XRAMs).
4
4
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210308224637.2949533-3-edgar.iglesias@gmail.com
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
11
docs/system/arm/xlnx-versal-virt.rst | 1 +
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
12
include/hw/arm/xlnx-versal.h | 13 ++++++++++
14
2 files changed, 43 insertions(+)
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++
14
3 files changed, 50 insertions(+)
15
15
16
diff --git a/docs/system/arm/xlnx-versal-virt.rst b/docs/system/arm/xlnx-versal-virt.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/xlnx-versal-virt.rst
19
+++ b/docs/system/arm/xlnx-versal-virt.rst
20
@@ -XXX,XX +XXX,XX @@ Implemented devices:
21
- 8 ADMA (Xilinx zDMA) channels
22
- 2 SD Controllers
23
- OCM (256KB of On Chip Memory)
24
+- XRAM (4MB of on chip Accelerator RAM)
25
- DDR memory
26
27
QEMU does not yet model any other devices, including the PL and the AI Engine.
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
28
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
30
--- a/include/hw/arm/xlnx-versal.h
19
+++ b/include/hw/arm/xlnx-versal.h
31
+++ b/include/hw/arm/xlnx-versal.h
20
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
21
33
22
#include "hw/sysbus.h"
34
#include "hw/sysbus.h"
23
#include "hw/arm/boot.h"
35
#include "hw/arm/boot.h"
24
+#include "hw/sd/sdhci.h"
36
+#include "hw/or-irq.h"
37
#include "hw/sd/sdhci.h"
25
#include "hw/intc/arm_gicv3.h"
38
#include "hw/intc/arm_gicv3.h"
26
#include "hw/char/pl011.h"
39
#include "hw/char/pl011.h"
27
#include "hw/dma/xlnx-zdma.h"
28
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@
29
#define XLNX_VERSAL_NR_UARTS 2
41
#include "hw/rtc/xlnx-zynqmp-rtc.h"
42
#include "qom/object.h"
43
#include "hw/usb/xlnx-usb-subsystem.h"
44
+#include "hw/misc/xlnx-versal-xramc.h"
45
46
#define TYPE_XLNX_VERSAL "xlnx-versal"
47
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
48
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
30
#define XLNX_VERSAL_NR_GEMS 2
49
#define XLNX_VERSAL_NR_GEMS 2
31
#define XLNX_VERSAL_NR_ADMAS 8
50
#define XLNX_VERSAL_NR_ADMAS 8
32
+#define XLNX_VERSAL_NR_SDS 2
51
#define XLNX_VERSAL_NR_SDS 2
52
+#define XLNX_VERSAL_NR_XRAM 4
33
#define XLNX_VERSAL_NR_IRQS 192
53
#define XLNX_VERSAL_NR_IRQS 192
34
54
35
typedef struct Versal {
55
struct Versal {
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
56
@@ -XXX,XX +XXX,XX @@ struct Versal {
57
XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
58
VersalUsb2 usb;
37
} iou;
59
} iou;
60
+
61
+ struct {
62
+ qemu_or_irq irq_orgate;
63
+ XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
64
+ } xram;
38
} lpd;
65
} lpd;
39
66
40
+ /* The Platform Management Controller subsystem. */
67
/* The Platform Management Controller subsystem. */
41
+ struct {
68
@@ -XXX,XX +XXX,XX @@ struct Versal {
42
+ struct {
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
44
+ } iou;
45
+ } pmc;
46
+
47
struct {
48
MemoryRegion *mr_ddr;
49
uint32_t psci_conduit;
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
51
#define VERSAL_GEM1_IRQ_0 58
69
#define VERSAL_GEM1_IRQ_0 58
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
70
#define VERSAL_GEM1_WAKE_IRQ_0 59
53
#define VERSAL_ADMA_IRQ_0 60
71
#define VERSAL_ADMA_IRQ_0 60
54
+#define VERSAL_SD0_IRQ_0 126
72
+#define VERSAL_XRAM_IRQ_0 79
55
73
#define VERSAL_RTC_APB_ERR_IRQ 121
56
/* Architecturally reserved IRQs suitable for virtualization. */
74
#define VERSAL_SD0_IRQ_0 126
57
#define VERSAL_RSVD_IRQ_FIRST 111
75
#define VERSAL_RTC_ALARM_IRQ 142
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
76
@@ -XXX,XX +XXX,XX @@ struct Versal {
59
#define MM_FPD_CRF 0xfd1a0000U
77
#define MM_OCM 0xfffc0000U
60
#define MM_FPD_CRF_SIZE 0x140000
78
#define MM_OCM_SIZE 0x40000
61
79
62
+#define MM_PMC_SD0 0xf1040000U
80
+#define MM_XRAM 0xfe800000
63
+#define MM_PMC_SD0_SIZE 0x10000
81
+#define MM_XRAMC 0xff8e0000
64
#define MM_PMC_CRP 0xf1260000U
82
+#define MM_XRAMC_SIZE 0x10000
65
#define MM_PMC_CRP_SIZE 0x10000
83
+
66
#endif
84
#define MM_USB2_CTRL_REGS 0xFF9D0000
85
#define MM_USB2_CTRL_REGS_SIZE 0x10000
86
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
87
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
68
index XXXXXXX..XXXXXXX 100644
88
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/xlnx-versal.c
89
--- a/hw/arm/xlnx-versal.c
70
+++ b/hw/arm/xlnx-versal.c
90
+++ b/hw/arm/xlnx-versal.c
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
91
@@ -XXX,XX +XXX,XX @@
72
}
92
*/
93
94
#include "qemu/osdep.h"
95
+#include "qemu/units.h"
96
#include "qapi/error.h"
97
#include "qemu/log.h"
98
#include "qemu/module.h"
99
@@ -XXX,XX +XXX,XX @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
100
sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
73
}
101
}
74
102
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
103
+static void versal_create_xrams(Versal *s, qemu_irq *pic)
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
77
+{
104
+{
105
+ int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl);
106
+ DeviceState *orgate;
78
+ int i;
107
+ int i;
79
+
108
+
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
109
+ /* XRAM IRQs get ORed into a single line. */
81
+ DeviceState *dev;
110
+ object_initialize_child(OBJECT(s), "xram-irq-orgate",
111
+ &s->lpd.xram.irq_orgate, TYPE_OR_IRQ);
112
+ orgate = DEVICE(&s->lpd.xram.irq_orgate);
113
+ object_property_set_int(OBJECT(orgate),
114
+ "num-lines", nr_xrams, &error_fatal);
115
+ qdev_realize(orgate, NULL, &error_fatal);
116
+ qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]);
117
+
118
+ for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) {
119
+ SysBusDevice *sbd;
82
+ MemoryRegion *mr;
120
+ MemoryRegion *mr;
83
+
121
+
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
122
+ object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i],
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
123
+ TYPE_XLNX_XRAM_CTRL);
86
+ TYPE_SYSBUS_SDHCI);
124
+ sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]);
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
125
+ sysbus_realize(sbd, &error_fatal);
88
+
126
+
89
+ object_property_set_uint(OBJECT(dev),
127
+ mr = sysbus_mmio_get_region(sbd, 0);
90
+ 3, "sd-spec-version", &error_fatal);
128
+ memory_region_add_subregion(&s->mr_ps,
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
129
+ MM_XRAMC + i * MM_XRAMC_SIZE, mr);
92
+ &error_fatal);
130
+ mr = sysbus_mmio_get_region(sbd, 1);
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
131
+ memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr);
94
+ qdev_init_nofail(dev);
95
+
132
+
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
133
+ sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i));
97
+ memory_region_add_subregion(&s->mr_ps,
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
99
+
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
102
+ }
134
+ }
103
+}
135
+}
104
+
136
+
105
/* This takes the board allocated linear DDR memory and creates aliases
137
/* This takes the board allocated linear DDR memory and creates aliases
106
* for each split DDR range/aperture on the Versal address map.
138
* for each split DDR range/aperture on the Versal address map.
107
*/
139
*/
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
140
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
109
versal_create_uarts(s, pic);
110
versal_create_gems(s, pic);
111
versal_create_admas(s, pic);
141
versal_create_admas(s, pic);
112
+ versal_create_sds(s, pic);
142
versal_create_sds(s, pic);
143
versal_create_rtc(s, pic);
144
+ versal_create_xrams(s, pic);
113
versal_map_ddr(s);
145
versal_map_ddr(s);
114
versal_unimp(s);
146
versal_unimp(s);
115
147
116
--
148
--
117
2.20.1
149
2.20.1
118
150
119
151
diff view generated by jsdifflib
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
1
From: Eric Auger <eric.auger@redhat.com>
2
to decodetree.
3
2
3
With -Werror=maybe-uninitialized configuration we get
4
../hw/i386/intel_iommu.c: In function ‘vtd_context_device_invalidate’:
5
../hw/i386/intel_iommu.c:1888:10: error: ‘mask’ may be used
6
uninitialized in this function [-Werror=maybe-uninitialized]
7
1888 | mask = ~mask;
8
| ~~~~~^~~~~~~
9
10
Add a g_assert_not_reached() to avoid the error.
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Xu <peterx@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20210309102742.30442-2-eric.auger@redhat.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
7
---
17
---
8
target/arm/neon-dp.decode | 6 ++++++
18
hw/i386/intel_iommu.c | 2 ++
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
19
1 file changed, 2 insertions(+)
10
target/arm/translate.c | 14 ++------------
11
3 files changed, 23 insertions(+), 12 deletions(-)
12
20
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
21
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
23
--- a/hw/i386/intel_iommu.c
16
+++ b/target/arm/neon-dp.decode
24
+++ b/hw/i386/intel_iommu.c
17
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
26
case 3:
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
mask = 7; /* Mask bit 2:0 in the SID field */
20
28
break;
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
29
+ default:
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
30
+ g_assert_not_reached();
23
+
31
}
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
32
mask = ~mask;
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
33
26
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
33
+
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
43
}
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
45
+
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
49
+ uint32_t oprsz, uint32_t maxsz) \
50
+ { \
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
53
+ } \
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
55
+
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
}
66
return 1;
67
68
- case NEON_3R_VQADD:
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
70
- rn_ofs, rm_ofs, vec_size, vec_size,
71
- (u ? uqadd_op : sqadd_op) + size);
72
- return 0;
73
-
74
- case NEON_3R_VQSUB:
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
76
- rn_ofs, rm_ofs, vec_size, vec_size,
77
- (u ? uqsub_op : sqsub_op) + size);
78
- return 0;
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
92
--
34
--
93
2.20.1
35
2.20.1
94
36
95
37
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
Note that we don't need the neon_3r_sizes[op] check here because all
3
Currently get_naturally_aligned_size() is used by the intel iommu
4
size values are OK for VADD and VSUB; we'll add this when we convert
4
to compute the maximum invalidation range based on @size which is
5
the first insn that has size restrictions.
5
a power of 2 while being aligned with the @start address and less
6
than the maximum range defined by @gaw.
6
7
7
For this we need one of the GVecGen*Fn typedefs currently in
8
This helper is also useful for other iommu devices (virtio-iommu,
8
translate-a64.h; move them all to translate.h as a block so they
9
SMMUv3) to make sure IOMMU UNMAP notifiers only are called with
9
are visible to the 32-bit decoder.
10
power of 2 range sizes.
10
11
12
Let's move this latter into dma-helpers.c and rename it into
13
dma_aligned_pow2_mask(). Also rewrite the helper so that it
14
accomodates UINT64_MAX values for the size mask and max mask.
15
It now returns a mask instead of a size. Change the caller.
16
17
Signed-off-by: Eric Auger <eric.auger@redhat.com>
18
Reviewed-by: Peter Xu <peterx@redhat.com>
19
Message-id: 20210309102742.30442-3-eric.auger@redhat.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
14
---
21
---
15
target/arm/translate-a64.h | 9 --------
22
include/sysemu/dma.h | 12 ++++++++++++
16
target/arm/translate.h | 9 ++++++++
23
hw/i386/intel_iommu.c | 30 +++++++-----------------------
17
target/arm/neon-dp.decode | 17 +++++++++++++++
24
softmmu/dma-helpers.c | 26 ++++++++++++++++++++++++++
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
25
3 files changed, 45 insertions(+), 23 deletions(-)
19
target/arm/translate.c | 14 ++++--------
20
5 files changed, 68 insertions(+), 19 deletions(-)
21
26
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
27
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
23
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate-a64.h
29
--- a/include/sysemu/dma.h
25
+++ b/target/arm/translate-a64.h
30
+++ b/include/sysemu/dma.h
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
31
@@ -XXX,XX +XXX,XX @@ uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
27
32
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
28
bool disas_sve(DisasContext *, uint32_t);
33
QEMUSGList *sg, enum BlockAcctType type);
29
34
30
-/* Note that the gvec expanders operate on offsets + sizes. */
35
+/**
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
36
+ * dma_aligned_pow2_mask: Return the address bit mask of the largest
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
37
+ * power of 2 size less or equal than @end - @start + 1, aligned with @start,
33
- uint32_t, uint32_t);
38
+ * and bounded by 1 << @max_addr_bits bits.
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
39
+ *
35
- uint32_t, uint32_t, uint32_t);
40
+ * @start: range start address
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
41
+ * @end: range end address (greater than @start)
37
- uint32_t, uint32_t, uint32_t);
42
+ * @max_addr_bits: max address bits (<= 64)
43
+ */
44
+uint64_t dma_aligned_pow2_mask(uint64_t start, uint64_t end,
45
+ int max_addr_bits);
46
+
47
#endif
48
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/i386/intel_iommu.c
51
+++ b/hw/i386/intel_iommu.c
52
@@ -XXX,XX +XXX,XX @@
53
#include "hw/i386/x86-iommu.h"
54
#include "hw/pci-host/q35.h"
55
#include "sysemu/kvm.h"
56
+#include "sysemu/dma.h"
57
#include "sysemu/sysemu.h"
58
#include "hw/i386/apic_internal.h"
59
#include "kvm/kvm_i386.h"
60
@@ -XXX,XX +XXX,XX @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
61
return vtd_dev_as;
62
}
63
64
-static uint64_t get_naturally_aligned_size(uint64_t start,
65
- uint64_t size, int gaw)
66
-{
67
- uint64_t max_mask = 1ULL << gaw;
68
- uint64_t alignment = start ? start & -start : max_mask;
38
-
69
-
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
70
- alignment = MIN(alignment, max_mask);
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
71
- size = MIN(size, max_mask);
72
-
73
- if (alignment <= size) {
74
- /* Increase the alignment of start */
75
- return alignment;
76
- } else {
77
- /* Find the largest page mask from size */
78
- return 1ULL << (63 - clz64(size));
79
- }
80
-}
81
-
82
/* Unmap the whole range in the notifier's scope. */
83
static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
84
{
85
@@ -XXX,XX +XXX,XX @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
86
87
while (remain >= VTD_PAGE_SIZE) {
88
IOMMUTLBEvent event;
89
- uint64_t mask = get_naturally_aligned_size(start, remain, s->aw_bits);
90
+ uint64_t mask = dma_aligned_pow2_mask(start, end, s->aw_bits);
91
+ uint64_t size = mask + 1;
92
93
- assert(mask);
94
+ assert(size);
95
96
event.type = IOMMU_NOTIFIER_UNMAP;
97
event.entry.iova = start;
98
- event.entry.addr_mask = mask - 1;
99
+ event.entry.addr_mask = mask;
100
event.entry.target_as = &address_space_memory;
101
event.entry.perm = IOMMU_NONE;
102
/* This field is meaningless for unmap */
103
@@ -XXX,XX +XXX,XX @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
104
105
memory_region_notify_iommu_one(n, &event);
106
107
- start += mask;
108
- remain -= mask;
109
+ start += size;
110
+ remain -= size;
111
}
112
113
assert(!remain);
114
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
41
index XXXXXXX..XXXXXXX 100644
115
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate.h
116
--- a/softmmu/dma-helpers.c
43
+++ b/target/arm/translate.h
117
+++ b/softmmu/dma-helpers.c
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
118
@@ -XXX,XX +XXX,XX @@ void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
45
#define dc_isar_feature(name, ctx) \
119
{
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
120
block_acct_start(blk_get_stats(blk), cookie, sg->size, type);
47
48
+/* Note that the gvec expanders operate on offsets + sizes. */
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
51
+ uint32_t, uint32_t);
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
53
+ uint32_t, uint32_t, uint32_t);
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
55
+ uint32_t, uint32_t, uint32_t);
56
+
57
#endif /* TARGET_ARM_TRANSLATE_H */
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/neon-dp.decode
61
+++ b/target/arm/neon-dp.decode
62
@@ -XXX,XX +XXX,XX @@
63
#
64
# This file is processed by scripts/decodetree.py
65
#
66
+# VFP/Neon register fields; same as vfp.decode
67
+%vm_dp 5:1 0:4
68
+%vn_dp 7:1 16:4
69
+%vd_dp 22:1 12:4
70
71
# Encodings for Neon data processing instructions where the T32 encoding
72
# is a simple transformation of the A32 encoding.
73
@@ -XXX,XX +XXX,XX @@
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
75
# This file works on the A32 encoding only; calling code for T32 has to
76
# transform the insn into the A32 version first.
77
+
78
+######################################################################
79
+# 3-reg-same grouping:
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
81
+######################################################################
82
+
83
+&3same vm vn vd q size
84
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
87
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
97
}
121
}
98
+
122
+
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
123
+uint64_t dma_aligned_pow2_mask(uint64_t start, uint64_t end, int max_addr_bits)
100
+{
124
+{
101
+ int vec_size = a->q ? 16 : 8;
125
+ uint64_t max_mask = UINT64_MAX, addr_mask = end - start;
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
126
+ uint64_t alignment_mask, size_mask;
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
105
+
127
+
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
128
+ if (max_addr_bits != 64) {
107
+ return false;
129
+ max_mask = (1ULL << max_addr_bits) - 1;
108
+ }
130
+ }
109
+
131
+
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
132
+ alignment_mask = start ? (start & -start) - 1 : max_mask;
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
133
+ alignment_mask = MIN(alignment_mask, max_mask);
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
134
+ size_mask = MIN(addr_mask, max_mask);
113
+ return false;
135
+
136
+ if (alignment_mask <= size_mask) {
137
+ /* Increase the alignment of start */
138
+ return alignment_mask;
139
+ } else {
140
+ /* Find the largest page mask from size */
141
+ if (addr_mask == UINT64_MAX) {
142
+ return UINT64_MAX;
143
+ }
144
+ return (1ULL << (63 - clz64(addr_mask + 1))) - 1;
114
+ }
145
+ }
115
+
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
117
+ return false;
118
+ }
119
+
120
+ if (!vfp_access_check(s)) {
121
+ return true;
122
+ }
123
+
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
125
+ return true;
126
+}
146
+}
127
+
147
+
128
+#define DO_3SAME(INSN, FUNC) \
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
130
+ { \
131
+ return do_3same(s, a, FUNC); \
132
+ }
133
+
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate.c
139
+++ b/target/arm/translate.c
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
141
}
142
return 0;
143
144
- case NEON_3R_VADD_VSUB:
145
- if (u) {
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
147
- vec_size, vec_size);
148
- } else {
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
150
- vec_size, vec_size);
151
- }
152
- return 0;
153
-
154
case NEON_3R_VQADD:
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
156
rn_ofs, rm_ofs, vec_size, vec_size,
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
159
u ? &ushl_op[size] : &sshl_op[size]);
160
return 0;
161
+
162
+ case NEON_3R_VADD_VSUB:
163
+ /* Already handled by decodetree */
164
+ return 1;
165
}
166
167
if (size == 3) {
168
--
148
--
169
2.20.1
149
2.20.1
170
150
171
151
diff view generated by jsdifflib
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
1
From: Eric Auger <eric.auger@redhat.com>
2
to decodetree. These are the last ones in the group so we can remove
3
all the legacy decode for the group.
4
2
5
Note that in disas_thumb2_insn() the parts of this encoding space
3
Unmap notifiers work with an address mask assuming an
6
where the decodetree decoder returns false will correctly be directed
4
invalidation range of a power of 2. Nothing mandates this
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
5
in the VIRTIO-IOMMU spec.
8
into disas_coproc_insn() by mistake.
9
6
7
So in case the range is not a power of 2, split it into
8
several invalidations.
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Peter Xu <peterx@redhat.com>
12
Message-id: 20210309102742.30442-4-eric.auger@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
13
---
14
---
14
target/arm/neon-shared.decode | 7 +++
15
hw/virtio/virtio-iommu.c | 19 ++++++++++++++++---
15
target/arm/translate-neon.inc.c | 32 ++++++++++
16
1 file changed, 16 insertions(+), 3 deletions(-)
16
target/arm/translate.c | 107 +-------------------------------
17
3 files changed, 40 insertions(+), 106 deletions(-)
18
17
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
18
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
20
--- a/hw/virtio/virtio-iommu.c
22
+++ b/target/arm/neon-shared.decode
21
+++ b/hw/virtio/virtio-iommu.c
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
22
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
24
23
hwaddr virt_end)
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
24
{
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
25
IOMMUTLBEvent event;
27
+
26
+ uint64_t delta = virt_end - virt_start;
28
+%vfml_scalar_q0_rm 0:3 5:1
27
29
+%vfml_scalar_q1_index 5:1 3:1
28
if (!(mr->iommu_notify_flags & IOMMU_NOTIFIER_UNMAP)) {
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
29
return;
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
30
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
31
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
32
event.type = IOMMU_NOTIFIER_UNMAP;
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
event.entry.target_as = &address_space_memory;
35
index XXXXXXX..XXXXXXX 100644
34
- event.entry.addr_mask = virt_end - virt_start;
36
--- a/target/arm/translate-neon.inc.c
35
- event.entry.iova = virt_start;
37
+++ b/target/arm/translate-neon.inc.c
36
event.entry.perm = IOMMU_NONE;
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
37
event.entry.translated_addr = 0;
39
tcg_temp_free_ptr(fpst);
38
+ event.entry.addr_mask = delta;
40
return true;
39
+ event.entry.iova = virt_start;
41
}
40
42
+
41
- memory_region_notify_iommu(mr, 0, event);
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
42
+ if (delta == UINT64_MAX) {
44
+{
43
+ memory_region_notify_iommu(mr, 0, event);
45
+ int opr_sz;
46
+
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
48
+ return false;
49
+ }
44
+ }
50
+
45
+
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
46
+
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
47
+ while (virt_start != virt_end + 1) {
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
48
+ uint64_t mask = dma_aligned_pow2_mask(virt_start, virt_end, 64);
54
+ return false;
49
+
50
+ event.entry.addr_mask = mask;
51
+ event.entry.iova = virt_start;
52
+ memory_region_notify_iommu(mr, 0, event);
53
+ virt_start += mask + 1;
55
+ }
54
+ }
56
+
57
+ if (a->vd & a->q) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
73
+}
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/translate.c
77
+++ b/target/arm/translate.c
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
79
}
55
}
80
56
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
57
static gboolean virtio_iommu_notify_unmap_cb(gpointer key, gpointer value,
82
-#define VFP_SREG(insn, bigbit, smallbit) \
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
86
reg = (((insn) >> (bigbit)) & 0x0f) \
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
88
reg = ((insn) >> (bigbit)) & 0x0f; \
89
}} while (0)
90
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
97
98
static void gen_neon_dup_low16(TCGv_i32 var)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
100
return 0;
101
}
102
103
-/* Advanced SIMD two registers and a scalar extension.
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
108
- *
109
- */
110
-
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
112
-{
113
- gen_helper_gvec_3 *fn_gvec = NULL;
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
115
- int rd, rn, rm, opr_sz, data;
116
- int off_rn, off_rm;
117
- bool is_long = false, q = extract32(insn, 6, 1);
118
- bool ptr_is_env = false;
119
-
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
122
- int is_s = extract32(insn, 20, 1);
123
- int vm20 = extract32(insn, 0, 3);
124
- int vm3 = extract32(insn, 3, 1);
125
- int m = extract32(insn, 5, 1);
126
- int index;
127
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
129
- return 1;
130
- }
131
- if (q) {
132
- rm = vm20;
133
- index = m * 2 + vm3;
134
- } else {
135
- rm = vm20 * 2 + m;
136
- index = vm3;
137
- }
138
- is_long = true;
139
- data = (index << 2) | is_s; /* is_2 == 0 */
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
141
- ptr_is_env = true;
142
- } else {
143
- return 1;
144
- }
145
-
146
- VFP_DREG_D(rd, insn);
147
- if (rd & q) {
148
- return 1;
149
- }
150
- if (q || !is_long) {
151
- VFP_DREG_N(rn, insn);
152
- if (rn & q & !is_long) {
153
- return 1;
154
- }
155
- off_rn = vfp_reg_offset(1, rn);
156
- off_rm = vfp_reg_offset(1, rm);
157
- } else {
158
- rn = VFP_SREG_N(insn);
159
- off_rn = vfp_reg_offset(0, rn);
160
- off_rm = vfp_reg_offset(0, rm);
161
- }
162
- if (s->fp_excp_el) {
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
165
- return 0;
166
- }
167
- if (!s->vfp_enabled) {
168
- return 1;
169
- }
170
-
171
- opr_sz = (1 + q) * 8;
172
- if (fn_gvec_ptr) {
173
- TCGv_ptr ptr;
174
- if (ptr_is_env) {
175
- ptr = cpu_env;
176
- } else {
177
- ptr = get_fpstatus_ptr(1);
178
- }
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
181
- if (!ptr_is_env) {
182
- tcg_temp_free_ptr(ptr);
183
- }
184
- } else {
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
186
- opr_sz, opr_sz, data, fn_gvec);
187
- }
188
- return 0;
189
-}
190
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
192
{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
195
}
196
}
197
}
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
201
- goto illegal_op;
202
- }
203
- return;
204
}
205
goto illegal_op;
206
}
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
208
}
209
break;
210
}
211
- if ((insn & 0xff000a00) == 0xfe000800
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
213
- /* The Thumb2 and ARM encodings are identical. */
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
215
- goto illegal_op;
216
- }
217
- } else if (((insn >> 24) & 3) == 3) {
218
+ if (((insn >> 24) & 3) == 3) {
219
/* Translate into the equivalent ARM encoding. */
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
221
if (disas_neon_data_insn(s, insn)) {
222
--
58
--
223
2.20.1
59
2.20.1
224
60
225
61
diff view generated by jsdifflib
1
From: Fredrik Strupe <fredrik@strupe.net>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
3
If the asid is not set, do not attempt to locate the key directly
4
U=1 is unallocated.
4
as all inserted keys have a valid asid.
5
5
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
6
Use g_hash_table_foreach_remove instead.
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
7
8
Signed-off-by: Eric Auger <eric.auger@redhat.com>
9
Message-id: 20210309102742.30442-5-eric.auger@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@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.c | 2 +-
13
hw/arm/smmu-common.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/hw/arm/smmu-common.c
17
+++ b/target/arm/translate.c
19
+++ b/hw/arm/smmu-common.c
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@ inline void
19
{0, 0, 0, 0}, /* VMLSL */
21
smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
20
{0, 0, 0, 9}, /* VQDMLSL */
22
uint8_t tg, uint64_t num_pages, uint8_t ttl)
21
{0, 0, 0, 0}, /* Integer VMULL */
23
{
22
- {0, 0, 0, 1}, /* VQDMULL */
24
- if (ttl && (num_pages == 1)) {
23
+ {0, 0, 0, 9}, /* VQDMULL */
25
+ if (ttl && (num_pages == 1) && (asid >= 0)) {
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
26
SMMUIOTLBKey key = smmu_get_iotlb_key(asid, iova, tg, ttl);
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
27
26
};
28
g_hash_table_remove(s->iotlb, &key);
27
--
29
--
28
2.20.1
30
2.20.1
29
31
30
32
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
Embed the APUs into the SoC type.
3
As of today, the driver can invalidate a number of pages that is
4
not a power of 2. However IOTLB unmap notifications and internal
5
IOTLB invalidations work with masks leading to erroneous
6
invalidations.
4
7
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
In case the range is not a power of 2, split invalidations into
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
power of 2 invalidations.
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
When looking for a single page entry in the vSMMU internal IOTLB,
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
12
let's make sure that if the entry is not found using a
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
13
g_hash_table_remove() we iterate over all the entries to find a
14
potential range that overlaps it.
15
16
Signed-off-by: Eric Auger <eric.auger@redhat.com>
17
Message-id: 20210309102742.30442-6-eric.auger@redhat.com
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
20
---
13
include/hw/arm/xlnx-versal.h | 2 +-
21
hw/arm/smmu-common.c | 30 ++++++++++++++++++------------
14
hw/arm/xlnx-versal-virt.c | 4 ++--
22
hw/arm/smmuv3.c | 24 ++++++++++++++++++++----
15
hw/arm/xlnx-versal.c | 19 +++++--------------
23
2 files changed, 38 insertions(+), 16 deletions(-)
16
3 files changed, 8 insertions(+), 17 deletions(-)
17
24
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
25
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
19
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/xlnx-versal.h
27
--- a/hw/arm/smmu-common.c
21
+++ b/include/hw/arm/xlnx-versal.h
28
+++ b/hw/arm/smmu-common.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
29
@@ -XXX,XX +XXX,XX @@ inline void
23
struct {
30
smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
24
struct {
31
uint8_t tg, uint64_t num_pages, uint8_t ttl)
25
MemoryRegion mr;
32
{
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
33
+ /* if tg is not set we use 4KB range invalidation */
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
34
+ uint8_t granule = tg ? tg * 2 + 10 : 12;
28
GICv3State gic;
35
+
29
} apu;
36
if (ttl && (num_pages == 1) && (asid >= 0)) {
30
} fpd;
37
SMMUIOTLBKey key = smmu_get_iotlb_key(asid, iova, tg, ttl);
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
38
39
- g_hash_table_remove(s->iotlb, &key);
40
- } else {
41
- /* if tg is not set we use 4KB range invalidation */
42
- uint8_t granule = tg ? tg * 2 + 10 : 12;
43
-
44
- SMMUIOTLBPageInvInfo info = {
45
- .asid = asid, .iova = iova,
46
- .mask = (num_pages * 1 << granule) - 1};
47
-
48
- g_hash_table_foreach_remove(s->iotlb,
49
- smmu_hash_remove_by_asid_iova,
50
- &info);
51
+ if (g_hash_table_remove(s->iotlb, &key)) {
52
+ return;
53
+ }
54
+ /*
55
+ * if the entry is not found, let's see if it does not
56
+ * belong to a larger IOTLB entry
57
+ */
58
}
59
+
60
+ SMMUIOTLBPageInvInfo info = {
61
+ .asid = asid, .iova = iova,
62
+ .mask = (num_pages * 1 << granule) - 1};
63
+
64
+ g_hash_table_foreach_remove(s->iotlb,
65
+ smmu_hash_remove_by_asid_iova,
66
+ &info);
67
}
68
69
inline void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
70
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
32
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/xlnx-versal-virt.c
72
--- a/hw/arm/smmuv3.c
34
+++ b/hw/arm/xlnx-versal-virt.c
73
+++ b/hw/arm/smmuv3.c
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
74
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
36
s->binfo.get_dtb = versal_virt_get_dtb;
75
uint16_t vmid = CMD_VMID(cmd);
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
76
bool leaf = CMD_LEAF(cmd);
38
if (machine->kernel_filename) {
77
uint8_t tg = CMD_TG(cmd);
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
78
- hwaddr num_pages = 1;
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
79
+ uint64_t first_page = 0, last_page;
41
} else {
80
+ uint64_t num_pages = 1;
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
81
int asid = -1;
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
82
44
&s->binfo);
83
if (tg) {
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
84
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
46
* Offset things by 4K. */
85
if (type == SMMU_CMD_TLBI_NH_VA) {
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
86
asid = CMD_ASID(cmd);
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/xlnx-versal.c
50
+++ b/hw/arm/xlnx-versal.c
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
52
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
54
Object *obj;
55
- char *name;
56
-
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
58
- if (!obj) {
59
- error_report("Unable to create apu.cpu[%d] of type %s",
60
- i, XLNX_VERSAL_ACPU_TYPE);
61
- exit(EXIT_FAILURE);
62
- }
63
-
64
- name = g_strdup_printf("apu-cpu[%d]", i);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
66
- g_free(name);
67
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
72
object_property_set_int(obj, s->cfg.psci_conduit,
73
"psci-conduit", &error_abort);
74
if (i) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
77
&error_abort);
78
object_property_set_bool(obj, true, "realized", &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
87
}
88
- trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
89
- smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
90
- smmu_iotlb_inv_iova(s, asid, addr, tg, num_pages, ttl);
91
+
92
+ /* Split invalidations into ^2 range invalidations */
93
+ last_page = num_pages - 1;
94
+ while (num_pages) {
95
+ uint8_t granule = tg * 2 + 10;
96
+ uint64_t mask, count;
97
+
98
+ mask = dma_aligned_pow2_mask(first_page, last_page, 64 - granule);
99
+ count = mask + 1;
100
+
101
+ trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, count, ttl, leaf);
102
+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, count);
103
+ smmu_iotlb_inv_iova(s, asid, addr, tg, count, ttl);
104
+
105
+ num_pages -= count;
106
+ first_page += count;
107
+ addr += count * BIT_ULL(granule);
108
+ }
81
}
109
}
82
110
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
111
static int smmuv3_cmdq_consume(SMMUv3State *s)
84
}
85
86
for (i = 0; i < nr_apu_cpus; i++) {
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
90
qemu_irq maint_irq;
91
int ti;
92
--
112
--
93
2.20.1
113
2.20.1
94
114
95
115
diff view generated by jsdifflib
1
Convert the Neon "load single structure to all lanes" insns to
1
From: Eric Auger <eric.auger@redhat.com>
2
decodetree.
3
2
3
If the whole SID range (32b) is invalidated (SMMU_CMD_CFGI_ALL),
4
@end overflows and we fail to handle the command properly.
5
6
Once this gets fixed, the current code really is awkward in the
7
sense it loops over the whole range instead of removing the
8
currently cached configs through a hash table lookup.
9
10
Fix both the overflow and the lookup.
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20210309102742.30442-7-eric.auger@redhat.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
7
---
16
---
8
target/arm/neon-ls.decode | 5 +++
17
hw/arm/smmu-internal.h | 5 +++++
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
18
hw/arm/smmuv3.c | 34 ++++++++++++++++++++--------------
10
target/arm/translate.c | 55 +------------------------
19
2 files changed, 25 insertions(+), 14 deletions(-)
11
3 files changed, 80 insertions(+), 53 deletions(-)
12
20
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
21
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-ls.decode
23
--- a/hw/arm/smmu-internal.h
16
+++ b/target/arm/neon-ls.decode
24
+++ b/hw/arm/smmu-internal.h
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBPageInvInfo {
26
uint64_t mask;
27
} SMMUIOTLBPageInvInfo;
28
29
+typedef struct SMMUSIDRange {
30
+ uint32_t start;
31
+ uint32_t end;
32
+} SMMUSIDRange;
33
+
34
#endif
35
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/smmuv3.c
38
+++ b/hw/arm/smmuv3.c
17
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@
18
40
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
41
#include "hw/arm/smmuv3.h"
20
vd=%vd_dp
42
#include "smmuv3-internal.h"
43
+#include "smmu-internal.h"
44
45
/**
46
* smmuv3_trigger_irq - pulse @irq if enabled and update
47
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
48
}
49
}
50
51
+static gboolean
52
+smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data)
53
+{
54
+ SMMUDevice *sdev = (SMMUDevice *)key;
55
+ uint32_t sid = smmu_get_sid(sdev);
56
+ SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
21
+
57
+
22
+# Neon load single element to all lanes
58
+ if (sid < sid_range->start || sid > sid_range->end) {
23
+
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
25
+ vd=%vd_dp
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-neon.inc.c
29
+++ b/target/arm/translate-neon.inc.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
32
return true;
33
}
34
+
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
36
+{
37
+ /* Neon load single structure to all lanes */
38
+ int reg, stride, vec_size;
39
+ int vd = a->vd;
40
+ int size = a->size;
41
+ int nregs = a->n + 1;
42
+ TCGv_i32 addr, tmp;
43
+
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
45
+ return false;
59
+ return false;
46
+ }
60
+ }
47
+
61
+ trace_smmuv3_config_cache_inv(sid);
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if (size == 3) {
54
+ if (nregs != 4 || a->a == 0) {
55
+ return false;
56
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
58
+ size = 2;
59
+ }
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
61
+ return false;
62
+ }
63
+ if (nregs == 3 && a->a == 1) {
64
+ return false;
65
+ }
66
+
67
+ if (!vfp_access_check(s)) {
68
+ return true;
69
+ }
70
+
71
+ /*
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
74
+ */
75
+ stride = a->t ? 2 : 1;
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
77
+
78
+ tmp = tcg_temp_new_i32();
79
+ addr = tcg_temp_new_i32();
80
+ load_reg_var(s, addr, a->rn);
81
+ for (reg = 0; reg < nregs; reg++) {
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
98
+ vd += stride;
99
+ }
100
+ tcg_temp_free_i32(tmp);
101
+ tcg_temp_free_i32(addr);
102
+
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
104
+
105
+ return true;
62
+ return true;
106
+}
63
+}
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
+
108
index XXXXXXX..XXXXXXX 100644
65
static int smmuv3_cmdq_consume(SMMUv3State *s)
109
--- a/target/arm/translate.c
66
{
110
+++ b/target/arm/translate.c
67
SMMUState *bs = ARM_SMMU(s);
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
68
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
112
int size;
69
}
113
int reg;
70
case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
114
int load;
71
{
115
- int vec_size;
72
- uint32_t start = CMD_SID(&cmd), end, i;
116
TCGv_i32 addr;
73
+ uint32_t start = CMD_SID(&cmd);
117
TCGv_i32 tmp;
74
uint8_t range = CMD_STE_RANGE(&cmd);
118
75
+ uint64_t end = start + (1ULL << (range + 1)) - 1;
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
76
+ SMMUSIDRange sid_range = {start, end};
120
} else {
77
121
size = (insn >> 10) & 3;
78
if (CMD_SSEC(&cmd)) {
122
if (size == 3) {
79
cmd_error = SMMU_CERROR_ILL;
123
- /* Load single element to all lanes. */
80
break;
124
- int a = (insn >> 4) & 1;
81
}
125
- if (!load) {
82
-
126
- return 1;
83
- end = start + (1 << (range + 1)) - 1;
84
trace_smmuv3_cmdq_cfgi_ste_range(start, end);
85
-
86
- for (i = start; i <= end; i++) {
87
- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, i);
88
- SMMUDevice *sdev;
89
-
90
- if (!mr) {
91
- continue;
92
- }
93
- sdev = container_of(mr, SMMUDevice, iommu);
94
- smmuv3_flush_config(sdev);
127
- }
95
- }
128
- size = (insn >> 6) & 3;
96
+ g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
129
- nregs = ((insn >> 8) & 3) + 1;
97
+ &sid_range);
130
-
98
break;
131
- if (size == 3) {
99
}
132
- if (nregs != 4 || a == 0) {
100
case SMMU_CMD_CFGI_CD:
133
- return 1;
134
- }
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
136
- size = 2;
137
- }
138
- if (nregs == 1 && a == 1 && size == 0) {
139
- return 1;
140
- }
141
- if (nregs == 3 && a == 1) {
142
- return 1;
143
- }
144
- addr = tcg_temp_new_i32();
145
- load_reg_var(s, addr, rn);
146
-
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
149
- */
150
- stride = (insn & (1 << 5)) ? 2 : 1;
151
- vec_size = nregs == 1 ? stride * 8 : 8;
152
-
153
- tmp = tcg_temp_new_i32();
154
- for (reg = 0; reg < nregs; reg++) {
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
156
- s->be_data | size);
157
- if ((rd & 1) && vec_size == 16) {
158
- /* We cannot write 16 bytes at once because the
159
- * destination is unaligned.
160
- */
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
162
- 8, 8, tmp);
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
164
- neon_reg_offset(rd, 0), 8, 8);
165
- } else {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
167
- vec_size, vec_size, tmp);
168
- }
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
180
--
101
--
181
2.20.1
102
2.20.1
182
103
183
104
diff view generated by jsdifflib
1
Convert the Neon comparison ops in the 3-reg-same grouping
1
From: Eric Auger <eric.auger@redhat.com>
2
to decodetree.
3
2
3
Convert all sid printouts to sid=0x%x.
4
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20210309102742.30442-8-eric.auger@redhat.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
7
---
9
---
8
target/arm/neon-dp.decode | 8 ++++++++
10
hw/arm/trace-events | 24 ++++++++++++------------
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
11
1 file changed, 12 insertions(+), 12 deletions(-)
10
target/arm/translate.c | 23 +++--------------------
11
3 files changed, 33 insertions(+), 20 deletions(-)
12
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
15
--- a/hw/arm/trace-events
16
+++ b/target/arm/neon-dp.decode
16
+++ b/hw/arm/trace-events
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
17
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
18
smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
19
smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
20
20
smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
21
-smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
22
-smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "SID:0x%x features:0x%x, sid_split:0x%x"
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
23
+smmuv3_record_event(const char *type, uint32_t sid) "%s sid=0x%x"
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
24
+smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "sid=0x%x features:0x%x, sid_split:0x%x"
25
+
25
smmuv3_find_ste_2lvl(uint64_t strtab_base, uint64_t l1ptr, int l1_ste_offset, uint64_t l2ptr, int l2_ste_offset, int max_l2_ste) "strtab_base:0x%"PRIx64" l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_ste:%d"
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
26
smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
27
-smmuv3_translate_disable(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d bypass (smmu disabled) iova:0x%"PRIx64" is_write=%d"
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
28
-smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d STE bypass iova:0x%"PRIx64" is_write=%d"
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
29
-smmuv3_translate_abort(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d abort on iova:0x%"PRIx64" is_write=%d"
30
30
-smmuv3_translate_success(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=%d iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
31
+smmuv3_translate_disable(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=0x%x bypass (smmu disabled) iova:0x%"PRIx64" is_write=%d"
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
32
+smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=0x%x STE bypass iova:0x%"PRIx64" is_write=%d"
33
+
33
+smmuv3_translate_abort(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=0x%x abort on iova:0x%"PRIx64" is_write=%d"
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
34
+smmuv3_translate_success(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=0x%x iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
35
smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
smmuv3_decode_cd(uint32_t oas) "oas=%d"
37
index XXXXXXX..XXXXXXX 100644
37
smmuv3_decode_cd_tt(int i, uint32_t tsz, uint64_t ttb, uint32_t granule_sz, bool had) "TT[%d]:tsz:%d ttb:0x%"PRIx64" granule_sz:%d had:%d"
38
--- a/target/arm/translate-neon.inc.c
38
-smmuv3_cmdq_cfgi_ste(int streamid) "streamid =%d"
39
+++ b/target/arm/translate-neon.inc.c
39
+smmuv3_cmdq_cfgi_ste(int streamid) "streamid= 0x%x"
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
40
smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=0x%x - end=0x%x"
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
41
-smmuv3_cmdq_cfgi_cd(uint32_t sid) "streamid = %d"
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
42
-smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid %d (hits=%d, misses=%d, hit rate=%d)"
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
43
-smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid %d (hits=%d, misses=%d, hit rate=%d)"
44
+
44
-smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid =%d asid =%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d"
45
+#define DO_3SAME_CMP(INSN, COND) \
45
+smmuv3_cmdq_cfgi_cd(uint32_t sid) "sid=0x%x"
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
46
+smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
47
+smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
48
+ uint32_t oprsz, uint32_t maxsz) \
48
+smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid=%d asid=%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d"
49
+ { \
49
smmuv3_cmdq_tlbi_nh(void) ""
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
50
smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d"
51
+ } \
51
-smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid %d"
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
52
+smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
53
+
53
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
54
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
55
smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
59
+
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
62
+{
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
64
+}
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
u ? &mls_op[size] : &mla_op[size]);
72
return 0;
73
74
- case NEON_3R_VTST_VCEQ:
75
- if (u) { /* VCEQ */
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
77
- vec_size, vec_size);
78
- } else { /* VTST */
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
80
- vec_size, vec_size, &cmtst_op[size]);
81
- }
82
- return 0;
83
-
84
- case NEON_3R_VCGT:
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
87
- return 0;
88
-
89
- case NEON_3R_VCGE:
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
92
- return 0;
93
-
94
case NEON_3R_VSHL:
95
/* Note the operation is vshl vd,vm,vn */
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
case NEON_3R_LOGIC:
99
case NEON_3R_VMAX:
100
case NEON_3R_VMIN:
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
107
--
56
--
108
2.20.1
57
2.20.1
109
58
110
59
diff view generated by jsdifflib
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
3
call it in S1_ptw_translate().
4
2
3
Missed out on compressing the second half of a predicate
4
with length vl % 512 > 256.
5
6
Adjust all of the x + (y << s) to x | (y << s) as a
7
general style fix. Drop the extract64 because the input
8
uint64_t are known to be already zero-extended from the
9
current size of the predicate.
10
11
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210309155305.11301-2-richard.henderson@linaro.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
9
---
16
---
10
target/arm/helper.c | 5 +++--
17
target/arm/sve_helper.c | 30 +++++++++++++++++++++---------
11
1 file changed, 3 insertions(+), 2 deletions(-)
18
1 file changed, 21 insertions(+), 9 deletions(-)
12
19
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
22
--- a/target/arm/sve_helper.c
16
+++ b/target/arm/helper.c
23
+++ b/target/arm/sve_helper.c
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
24
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
18
pcacheattrs = &cacheattrs;
25
if (oprsz <= 8) {
26
l = compress_bits(n[0] >> odd, esz);
27
h = compress_bits(m[0] >> odd, esz);
28
- d[0] = extract64(l + (h << (4 * oprsz)), 0, 8 * oprsz);
29
+ d[0] = l | (h << (4 * oprsz));
30
} else {
31
ARMPredicateReg tmp_m;
32
intptr_t oprsz_16 = oprsz / 16;
33
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
34
h = n[2 * i + 1];
35
l = compress_bits(l >> odd, esz);
36
h = compress_bits(h >> odd, esz);
37
- d[i] = l + (h << 32);
38
+ d[i] = l | (h << 32);
19
}
39
}
20
40
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
41
- /* For VL which is not a power of 2, the results from M do not
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
42
- align nicely with the uint64_t for D. Put the aligned results
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
43
- from M into TMP_M and then copy it into place afterward. */
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
44
+ /*
25
+ pcacheattrs);
45
+ * For VL which is not a multiple of 512, the results from M do not
26
if (ret) {
46
+ * align nicely with the uint64_t for D. Put the aligned results
27
assert(fi->type != ARMFault_None);
47
+ * from M into TMP_M and then copy it into place afterward.
28
fi->s2addr = addr;
48
+ */
49
if (oprsz & 15) {
50
- d[i] = compress_bits(n[2 * i] >> odd, esz);
51
+ int final_shift = (oprsz & 15) * 2;
52
+
53
+ l = n[2 * i + 0];
54
+ h = n[2 * i + 1];
55
+ l = compress_bits(l >> odd, esz);
56
+ h = compress_bits(h >> odd, esz);
57
+ d[i] = l | (h << final_shift);
58
59
for (i = 0; i < oprsz_16; i++) {
60
l = m[2 * i + 0];
61
h = m[2 * i + 1];
62
l = compress_bits(l >> odd, esz);
63
h = compress_bits(h >> odd, esz);
64
- tmp_m.p[i] = l + (h << 32);
65
+ tmp_m.p[i] = l | (h << 32);
66
}
67
- tmp_m.p[i] = compress_bits(m[2 * i] >> odd, esz);
68
+ l = m[2 * i + 0];
69
+ h = m[2 * i + 1];
70
+ l = compress_bits(l >> odd, esz);
71
+ h = compress_bits(h >> odd, esz);
72
+ tmp_m.p[i] = l | (h << final_shift);
73
74
swap_memmove(vd + oprsz / 2, &tmp_m, oprsz / 2);
75
} else {
76
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
77
h = m[2 * i + 1];
78
l = compress_bits(l >> odd, esz);
79
h = compress_bits(h >> odd, esz);
80
- d[oprsz_16 + i] = l + (h << 32);
81
+ d[oprsz_16 + i] = l | (h << 32);
82
}
83
}
84
}
29
--
85
--
30
2.20.1
86
2.20.1
31
87
32
88
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Wrote too much with low-half zip (zip1) with vl % 512 != 0.
4
5
Adjust all of the x + (y << s) to x | (y << s) as a style fix.
6
7
We only ever have exact overlap between D, M, and N. Therefore
8
we only need a single temporary, and we do not need to check for
9
partial overlap.
10
11
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210309155305.11301-3-richard.henderson@linaro.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
6
---
16
---
7
target/arm/neon-dp.decode | 5 +++++
17
target/arm/sve_helper.c | 25 ++++++++++++++-----------
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
18
1 file changed, 14 insertions(+), 11 deletions(-)
9
target/arm/translate.c | 21 ++-------------------
10
3 files changed, 21 insertions(+), 19 deletions(-)
11
19
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
20
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
13
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
22
--- a/target/arm/sve_helper.c
15
+++ b/target/arm/neon-dp.decode
23
+++ b/target/arm/sve_helper.c
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
24
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
25
intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
26
int esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
19
27
intptr_t high = FIELD_EX32(pred_desc, PREDDESC, DATA);
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
28
+ int esize = 1 << esz;
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
29
uint64_t *d = vd;
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
30
intptr_t i;
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
31
24
+
32
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
33
mm = extract64(mm, high * half, half);
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
34
nn = expand_bits(nn, esz);
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
mm = expand_bits(mm, esz);
28
index XXXXXXX..XXXXXXX 100644
36
- d[0] = nn + (mm << (1 << esz));
29
--- a/target/arm/translate-neon.inc.c
37
+ d[0] = nn | (mm << esize);
30
+++ b/target/arm/translate-neon.inc.c
38
} else {
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
39
- ARMPredicateReg tmp_n, tmp_m;
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
40
+ ARMPredicateReg tmp;
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
41
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
42
/* We produce output faster than we consume input.
35
+
43
Therefore we must be mindful of possible overlap. */
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
44
- if ((vn - vd) < (uintptr_t)oprsz) {
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
45
- vn = memcpy(&tmp_n, vn, oprsz);
38
+ { \
46
- }
39
+ if (a->size == 3) { \
47
- if ((vm - vd) < (uintptr_t)oprsz) {
40
+ return false; \
48
- vm = memcpy(&tmp_m, vm, oprsz);
41
+ } \
49
+ if (vd == vn) {
42
+ return do_3same(s, a, FUNC); \
50
+ vn = memcpy(&tmp, vn, oprsz);
43
+ }
51
+ if (vd == vm) {
44
+
52
+ vm = vn;
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
53
+ }
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
54
+ } else if (vd == vm) {
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
55
+ vm = memcpy(&tmp, vm, oprsz);
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
55
return 0;
56
57
- case NEON_3R_VMAX:
58
- if (u) {
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
60
- vec_size, vec_size);
61
- } else {
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
63
- vec_size, vec_size);
64
- }
65
- return 0;
66
- case NEON_3R_VMIN:
67
- if (u) {
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- } else {
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
72
- vec_size, vec_size);
73
- }
74
- return 0;
75
-
76
case NEON_3R_VSHL:
77
/* Note the operation is vshl vd,vm,vn */
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
80
81
case NEON_3R_VADD_VSUB:
82
case NEON_3R_LOGIC:
83
+ case NEON_3R_VMAX:
84
+ case NEON_3R_VMIN:
85
/* Already handled by decodetree */
86
return 1;
87
}
56
}
57
if (high) {
58
high = oprsz >> 1;
59
}
60
61
- if ((high & 3) == 0) {
62
+ if ((oprsz & 7) == 0) {
63
uint32_t *n = vn, *m = vm;
64
high >>= 2;
65
66
- for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
67
+ for (i = 0; i < oprsz / 8; i++) {
68
uint64_t nn = n[H4(high + i)];
69
uint64_t mm = m[H4(high + i)];
70
71
nn = expand_bits(nn, esz);
72
mm = expand_bits(mm, esz);
73
- d[i] = nn + (mm << (1 << esz));
74
+ d[i] = nn | (mm << esize);
75
}
76
} else {
77
uint8_t *n = vn, *m = vm;
78
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
79
80
nn = expand_bits(nn, esz);
81
mm = expand_bits(mm, esz);
82
- d16[H2(i)] = nn + (mm << (1 << esz));
83
+ d16[H2(i)] = nn | (mm << esize);
84
}
85
}
86
}
88
--
87
--
89
2.20.1
88
2.20.1
90
89
91
90
diff view generated by jsdifflib
1
We were accidentally permitting decode of Thumb Neon insns even if
1
From: Richard Henderson <richard.henderson@linaro.org>
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
3
check was being done before the call to disas_neon_data_insn() and
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
5
Thumb decoder. Push the feature bit check down into the called
6
functions so it is done for both Arm and Thumb encodings.
7
2
3
Wrote too much with punpk1 with vl % 512 != 0.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210309155305.11301-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
12
---
10
---
13
target/arm/translate.c | 16 ++++++++--------
11
target/arm/sve_helper.c | 4 ++--
14
1 file changed, 8 insertions(+), 8 deletions(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
15
13
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
16
--- a/target/arm/sve_helper.c
19
+++ b/target/arm/translate.c
17
+++ b/target/arm/sve_helper.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
18
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_punpk_p)(void *vd, void *vn, uint32_t pred_desc)
21
TCGv_i32 tmp2;
19
high = oprsz >> 1;
22
TCGv_i64 tmp64;
23
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
25
+ return 1;
26
+ }
27
+
28
/* FIXME: this access check should not take precedence over UNDEF
29
* for invalid encodings; we will generate incorrect syndrome information
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
TCGv_ptr ptr1, ptr2, ptr3;
33
TCGv_i64 tmp64;
34
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
+ return 1;
37
+ }
38
+
39
/* FIXME: this access check should not take precedence over UNDEF
40
* for invalid encodings; we will generate incorrect syndrome information
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
43
44
if (((insn >> 25) & 7) == 1) {
45
/* NEON Data processing. */
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
- goto illegal_op;
48
- }
49
-
50
if (disas_neon_data_insn(s, insn)) {
51
goto illegal_op;
52
}
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
}
20
}
55
if ((insn & 0x0f100000) == 0x04000000) {
21
56
/* NEON load/store. */
22
- if ((high & 3) == 0) {
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
23
+ if ((oprsz & 7) == 0) {
58
- goto illegal_op;
24
uint32_t *n = vn;
59
- }
25
high >>= 2;
60
-
26
61
if (disas_neon_ls_insn(s, insn)) {
27
- for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
62
goto illegal_op;
28
+ for (i = 0; i < oprsz / 8; i++) {
29
uint64_t nn = n[H4(high + i)];
30
d[i] = expand_bits(nn, 0);
63
}
31
}
64
--
32
--
65
2.20.1
33
2.20.1
66
34
67
35
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for the RTC.
3
Since b64ee454a4a0, all predicate operations should be
4
using these field macros for predicates.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20210309155305.11301-5-richard.henderson@linaro.org
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
11
target/arm/sve_helper.c | 6 +++---
12
1 file changed, 22 insertions(+)
12
target/arm/translate-sve.c | 7 +++----
13
2 files changed, 6 insertions(+), 7 deletions(-)
13
14
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
17
--- a/target/arm/sve_helper.c
17
+++ b/hw/arm/xlnx-versal-virt.c
18
+++ b/target/arm/sve_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
19
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_compact_d)(void *vd, void *vn, void *vg, uint32_t desc)
19
}
20
*/
21
int32_t HELPER(sve_last_active_element)(void *vg, uint32_t pred_desc)
22
{
23
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
24
- intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
25
+ intptr_t words = DIV_ROUND_UP(FIELD_EX32(pred_desc, PREDDESC, OPRSZ), 8);
26
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
27
28
- return last_active_element(vg, DIV_ROUND_UP(oprsz, 8), esz);
29
+ return last_active_element(vg, words, esz);
20
}
30
}
21
31
22
+static void fdt_add_rtc_node(VersalVirt *s)
32
void HELPER(sve_splice)(void *vd, void *vn, void *vm, void *vg, uint32_t desc)
23
+{
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
24
+ const char compat[] = "xlnx,zynqmp-rtc";
34
index XXXXXXX..XXXXXXX 100644
25
+ const char interrupt_names[] = "alarm\0sec";
35
--- a/target/arm/translate-sve.c
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
36
+++ b/target/arm/translate-sve.c
27
+
37
@@ -XXX,XX +XXX,XX @@ static void find_last_active(DisasContext *s, TCGv_i32 ret, int esz, int pg)
28
+ qemu_fdt_add_subnode(s->fdt, name);
38
*/
29
+
39
TCGv_ptr t_p = tcg_temp_new_ptr();
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
40
TCGv_i32 t_desc;
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
41
- unsigned vsz = pred_full_reg_size(s);
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
42
- unsigned desc;
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
43
+ unsigned desc = 0;
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
44
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
45
- desc = vsz - 2;
36
+ interrupt_names, sizeof(interrupt_names));
46
- desc = deposit32(desc, SIMD_DATA_SHIFT, 2, esz);
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
47
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, pred_full_reg_size(s));
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
48
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, esz);
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
49
40
+ g_free(name);
50
tcg_gen_addi_ptr(t_p, cpu_env, pred_full_reg_offset(s, pg));
41
+}
51
t_desc = tcg_const_i32(desc);
42
+
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
44
{
45
Error *err = NULL;
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
47
fdt_add_timer_nodes(s);
48
fdt_add_zdma_nodes(s);
49
fdt_add_sd_nodes(s);
50
+ fdt_add_rtc_node(s);
51
fdt_add_cpu_nodes(s, psci_conduit);
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
54
--
52
--
55
2.20.1
53
2.20.1
56
54
57
55
diff view generated by jsdifflib
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
1
From: Richard Henderson <richard.henderson@linaro.org>
2
translation table descriptors from just bit [54] to bits [54:53],
3
allowing stage 2 to control execution permissions separately for EL0
4
and EL1. Implement the new semantics of the XN field and enable
5
the feature for our 'max' CPU.
6
2
3
Since b64ee454a4a0, all predicate operations should be
4
using these field macros for predicates.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210309155305.11301-6-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
11
---
10
---
12
target/arm/cpu.h | 15 +++++++++++++++
11
target/arm/sve_helper.c | 30 ++++++++++++++----------------
13
target/arm/cpu.c | 1 +
12
target/arm/translate-sve.c | 4 ++--
14
target/arm/cpu64.c | 2 ++
13
2 files changed, 16 insertions(+), 18 deletions(-)
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
16
4 files changed, 49 insertions(+), 6 deletions(-)
17
14
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
17
--- a/target/arm/sve_helper.c
21
+++ b/target/arm/cpu.h
18
+++ b/target/arm/sve_helper.c
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@ static uint32_t do_zero(ARMPredicateReg *d, intptr_t oprsz)
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
20
void HELPER(sve_brkpa)(void *vd, void *vn, void *vm, void *vg,
21
uint32_t pred_desc)
22
{
23
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
24
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
25
if (last_active_pred(vn, vg, oprsz)) {
26
compute_brk_z(vd, vm, vg, oprsz, true);
27
} else {
28
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_brkpa)(void *vd, void *vn, void *vm, void *vg,
29
uint32_t HELPER(sve_brkpas)(void *vd, void *vn, void *vm, void *vg,
30
uint32_t pred_desc)
31
{
32
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
33
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
34
if (last_active_pred(vn, vg, oprsz)) {
35
return compute_brks_z(vd, vm, vg, oprsz, true);
36
} else {
37
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkpas)(void *vd, void *vn, void *vm, void *vg,
38
void HELPER(sve_brkpb)(void *vd, void *vn, void *vm, void *vg,
39
uint32_t pred_desc)
40
{
41
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
42
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
43
if (last_active_pred(vn, vg, oprsz)) {
44
compute_brk_z(vd, vm, vg, oprsz, false);
45
} else {
46
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_brkpb)(void *vd, void *vn, void *vm, void *vg,
47
uint32_t HELPER(sve_brkpbs)(void *vd, void *vn, void *vm, void *vg,
48
uint32_t pred_desc)
49
{
50
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
51
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
52
if (last_active_pred(vn, vg, oprsz)) {
53
return compute_brks_z(vd, vm, vg, oprsz, false);
54
} else {
55
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkpbs)(void *vd, void *vn, void *vm, void *vg,
56
57
void HELPER(sve_brka_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
58
{
59
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
60
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
61
compute_brk_z(vd, vn, vg, oprsz, true);
24
}
62
}
25
63
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
64
uint32_t HELPER(sve_brkas_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
27
+{
65
{
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
66
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
29
+}
67
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
30
+
68
return compute_brks_z(vd, vn, vg, oprsz, true);
31
/*
32
* 64-bit feature tests via id registers.
33
*/
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
36
}
69
}
37
70
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
71
void HELPER(sve_brkb_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
39
+{
72
{
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
73
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
41
+}
74
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
42
+
75
compute_brk_z(vd, vn, vg, oprsz, false);
43
/*
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
45
*/
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
48
}
76
}
49
77
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
78
uint32_t HELPER(sve_brkbs_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
51
+{
79
{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
80
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
53
+}
81
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
54
+
82
return compute_brks_z(vd, vn, vg, oprsz, false);
55
/*
83
}
56
* Forward to the above feature tests given an ARMCPU pointer.
84
57
*/
85
void HELPER(sve_brka_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
86
{
87
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
88
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
89
compute_brk_m(vd, vn, vg, oprsz, true);
90
}
91
92
uint32_t HELPER(sve_brkas_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
93
{
94
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
95
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
96
return compute_brks_m(vd, vn, vg, oprsz, true);
97
}
98
99
void HELPER(sve_brkb_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
100
{
101
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
102
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
103
compute_brk_m(vd, vn, vg, oprsz, false);
104
}
105
106
uint32_t HELPER(sve_brkbs_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
107
{
108
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
109
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
110
return compute_brks_m(vd, vn, vg, oprsz, false);
111
}
112
113
void HELPER(sve_brkn)(void *vd, void *vn, void *vg, uint32_t pred_desc)
114
{
115
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
116
-
117
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
118
if (!last_active_pred(vn, vg, oprsz)) {
119
do_zero(vd, oprsz);
120
}
121
@@ -XXX,XX +XXX,XX @@ static uint32_t predtest_ones(ARMPredicateReg *d, intptr_t oprsz,
122
123
uint32_t HELPER(sve_brkns)(void *vd, void *vn, void *vg, uint32_t pred_desc)
124
{
125
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
126
-
127
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
128
if (last_active_pred(vn, vg, oprsz)) {
129
return predtest_ones(vd, oprsz, -1);
130
} else {
131
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
59
index XXXXXXX..XXXXXXX 100644
132
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/cpu.c
133
--- a/target/arm/translate-sve.c
61
+++ b/target/arm/cpu.c
134
+++ b/target/arm/translate-sve.c
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
135
@@ -XXX,XX +XXX,XX @@ static bool do_brk3(DisasContext *s, arg_rprr_s *a,
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
136
TCGv_ptr n = tcg_temp_new_ptr();
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
137
TCGv_ptr m = tcg_temp_new_ptr();
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
138
TCGv_ptr g = tcg_temp_new_ptr();
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
139
- TCGv_i32 t = tcg_const_i32(vsz - 2);
67
cpu->isar.id_mmfr4 = t;
140
+ TCGv_i32 t = tcg_const_i32(FIELD_DP32(0, PREDDESC, OPRSZ, vsz));
68
}
141
69
#endif
142
tcg_gen_addi_ptr(d, cpu_env, pred_full_reg_offset(s, a->rd));
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
143
tcg_gen_addi_ptr(n, cpu_env, pred_full_reg_offset(s, a->rn));
71
index XXXXXXX..XXXXXXX 100644
144
@@ -XXX,XX +XXX,XX @@ static bool do_brk2(DisasContext *s, arg_rpr_s *a,
72
--- a/target/arm/cpu64.c
145
TCGv_ptr d = tcg_temp_new_ptr();
73
+++ b/target/arm/cpu64.c
146
TCGv_ptr n = tcg_temp_new_ptr();
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
147
TCGv_ptr g = tcg_temp_new_ptr();
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
148
- TCGv_i32 t = tcg_const_i32(vsz - 2);
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
149
+ TCGv_i32 t = tcg_const_i32(FIELD_DP32(0, PREDDESC, OPRSZ, vsz));
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
150
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
151
tcg_gen_addi_ptr(d, cpu_env, pred_full_reg_offset(s, a->rd));
79
cpu->isar.id_aa64mmfr1 = t;
152
tcg_gen_addi_ptr(n, cpu_env, pred_full_reg_offset(s, a->rn));
80
81
t = cpu->isar.id_aa64mmfr2;
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
87
cpu->isar.id_mmfr4 = u;
88
89
u = cpu->isar.id_aa64dfr0;
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
93
+++ b/target/arm/helper.c
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
95
*
96
* @env: CPUARMState
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
98
- * @xn: XN (execute-never) bit
99
+ * @xn: XN (execute-never) bits
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
101
*/
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
104
{
105
int prot = 0;
106
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
108
if (s2ap & 2) {
109
prot |= PAGE_WRITE;
110
}
111
- if (!xn) {
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
113
+
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
115
+ switch (xn) {
116
+ case 0:
117
prot |= PAGE_EXEC;
118
+ break;
119
+ case 1:
120
+ if (s1_is_el0) {
121
+ prot |= PAGE_EXEC;
122
+ }
123
+ break;
124
+ case 2:
125
+ break;
126
+ case 3:
127
+ if (!s1_is_el0) {
128
+ prot |= PAGE_EXEC;
129
+ }
130
+ break;
131
+ default:
132
+ g_assert_not_reached();
133
+ }
134
+ } else {
135
+ if (!extract32(xn, 1, 1)) {
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
137
+ prot |= PAGE_EXEC;
138
+ }
139
}
140
}
141
return prot;
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
143
}
144
145
ap = extract32(attrs, 4, 2);
146
- xn = extract32(attrs, 12, 1);
147
148
if (mmu_idx == ARMMMUIdx_Stage2) {
149
ns = true;
150
- *prot = get_S2prot(env, ap, xn);
151
+ xn = extract32(attrs, 11, 2);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
158
}
159
--
153
--
160
2.20.1
154
2.20.1
161
155
162
156
diff view generated by jsdifflib
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
Note that for the logic ops the 'size' field forms part of their
3
decode and the actual operations are always bitwise.
4
2
3
Since b64ee454a4a0, all predicate operations should be
4
using these field macros for predicates.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210309155305.11301-7-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
8
---
10
---
9
target/arm/neon-dp.decode | 12 +++++++++++
11
target/arm/sve_helper.c | 6 +++---
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
12
target/arm/translate-sve.c | 6 +++---
11
target/arm/translate.c | 38 +--------------------------------
13
2 files changed, 6 insertions(+), 6 deletions(-)
12
3 files changed, 32 insertions(+), 37 deletions(-)
13
14
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
17
--- a/target/arm/sve_helper.c
17
+++ b/target/arm/neon-dp.decode
18
+++ b/target/arm/sve_helper.c
18
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkns)(void *vd, void *vn, void *vg, uint32_t pred_desc)
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
20
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
21
uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
21
22
{
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
23
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
24
- intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
24
+
25
+ intptr_t words = DIV_ROUND_UP(FIELD_EX32(pred_desc, PREDDESC, OPRSZ), 8);
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
26
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
27
uint64_t *n = vn, *g = vg, sum = 0, mask = pred_esz_masks[esz];
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
28
intptr_t i;
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
29
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
30
- for (i = 0; i < DIV_ROUND_UP(oprsz, 8); ++i) {
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
31
+ for (i = 0; i < words; ++i) {
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
32
uint64_t t = n[i] & g[i] & mask;
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
33
sum += ctpop64(t);
33
+
34
}
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
35
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
37
--- a/target/arm/translate-sve.c
39
+++ b/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-sve.c
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
39
@@ -XXX,XX +XXX,XX @@ static void do_cntp(DisasContext *s, TCGv_i64 val, int esz, int pn, int pg)
41
40
} else {
42
DO_3SAME(VADD, tcg_gen_gvec_add)
41
TCGv_ptr t_pn = tcg_temp_new_ptr();
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
42
TCGv_ptr t_pg = tcg_temp_new_ptr();
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
43
- unsigned desc;
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
44
+ unsigned desc = 0;
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
45
TCGv_i32 t_desc;
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
46
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
47
- desc = psz - 2;
49
+
48
- desc = deposit32(desc, SIMD_DATA_SHIFT, 2, esz);
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
49
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, psz);
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
50
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, esz);
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
51
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
52
tcg_gen_addi_ptr(t_pn, cpu_env, pred_full_reg_offset(s, pn));
54
+ uint32_t oprsz, uint32_t maxsz) \
53
tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
55
+ { \
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
57
+ } \
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
59
+
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.c
66
+++ b/target/arm/translate.c
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
}
69
return 1;
70
71
- case NEON_3R_LOGIC: /* Logic ops. */
72
- switch ((u << 2) | size) {
73
- case 0: /* VAND */
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
75
- vec_size, vec_size);
76
- break;
77
- case 1: /* VBIC */
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
119
--
54
--
120
2.20.1
55
2.20.1
121
56
122
57
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Embed the ADMAs into the SoC type.
3
Since b64ee454a4a0, all predicate operations should be
4
using these field macros for predicates.
4
5
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20210309155305.11301-8-richard.henderson@linaro.org
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
11
target/arm/sve_helper.c | 4 ++--
14
hw/arm/xlnx-versal.c | 14 +++++++-------
12
target/arm/translate-sve.c | 7 ++++---
15
2 files changed, 9 insertions(+), 8 deletions(-)
13
2 files changed, 6 insertions(+), 5 deletions(-)
16
14
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
17
--- a/target/arm/sve_helper.c
20
+++ b/include/hw/arm/xlnx-versal.h
18
+++ b/target/arm/sve_helper.c
21
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
22
#include "hw/arm/boot.h"
20
23
#include "hw/intc/arm_gicv3.h"
21
uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
24
#include "hw/char/pl011.h"
22
{
25
+#include "hw/dma/xlnx-zdma.h"
23
- uintptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
26
#include "hw/net/cadence_gem.h"
24
- intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
27
25
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
26
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
27
uint64_t esz_mask = pred_esz_masks[esz];
30
struct {
28
ARMPredicateReg *d = vd;
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
29
uint32_t flags;
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
30
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
35
} iou;
36
} lpd;
37
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
32
--- a/target/arm/translate-sve.c
41
+++ b/hw/arm/xlnx-versal.c
33
+++ b/target/arm/translate-sve.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
34
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
43
DeviceState *dev;
35
TCGv_i64 op0, op1, t0, t1, tmax;
44
MemoryRegion *mr;
36
TCGv_i32 t2, t3;
45
37
TCGv_ptr ptr;
46
- dev = qdev_create(NULL, "xlnx.zdma");
38
- unsigned desc, vsz = vec_full_reg_size(s);
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
39
+ unsigned vsz = vec_full_reg_size(s);
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
40
+ unsigned desc = 0;
49
- &error_abort);
41
TCGCond cond;
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
42
51
+ sysbus_init_child_obj(OBJECT(s), name,
43
if (!sve_access_check(s)) {
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
44
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
53
+ TYPE_XLNX_ZDMA);
45
/* Scale elements to bits. */
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
46
tcg_gen_shli_i32(t2, t2, a->esz);
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
47
56
qdev_init_nofail(dev);
48
- desc = (vsz / 8) - 2;
57
49
- desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
50
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz / 8);
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
51
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz);
60
memory_region_add_subregion(&s->mr_ps,
52
t3 = tcg_const_i32(desc);
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
53
62
54
ptr = tcg_temp_new_ptr();
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
65
g_free(name);
66
}
67
}
68
--
55
--
69
2.20.1
56
2.20.1
70
57
71
58
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
3
With the reduction operations, we intentionally increase maxsz to
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
4
the next power of 2, so as to fill out the reduction tree correctly.
5
uint32_t.
5
Since e2e7168a214b, oprsz must equal maxsz, with exceptions for small
6
vectors, so this triggers an assertion for vector sizes > 32 that are
7
not themselves a power of 2.
6
8
7
This fixes an error when compiling with -Werror=conversion
9
Pass the power-of-two value in the simd_data field instead.
8
because we were manipulating the register value using a
9
local uint64_t variable:
10
10
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
12
Message-id: 20210309155305.11301-9-richard.henderson@linaro.org
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
15
---
27
target/arm/cpu.h | 2 +-
16
target/arm/sve_helper.c | 2 +-
28
target/arm/cpu.c | 2 +-
17
target/arm/translate-sve.c | 2 +-
29
2 files changed, 2 insertions(+), 2 deletions(-)
18
2 files changed, 2 insertions(+), 2 deletions(-)
30
19
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
32
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
22
--- a/target/arm/sve_helper.c
34
+++ b/target/arm/cpu.h
23
+++ b/target/arm/sve_helper.c
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
24
@@ -XXX,XX +XXX,XX @@ static TYPE NAME##_reduce(TYPE *data, float_status *status, uintptr_t n) \
36
uint64_t id_aa64dfr0;
25
} \
37
uint64_t id_aa64dfr1;
26
uint64_t HELPER(NAME)(void *vn, void *vg, void *vs, uint32_t desc) \
38
} isar;
27
{ \
39
- uint32_t midr;
28
- uintptr_t i, oprsz = simd_oprsz(desc), maxsz = simd_maxsz(desc); \
40
+ uint64_t midr;
29
+ uintptr_t i, oprsz = simd_oprsz(desc), maxsz = simd_data(desc); \
41
uint32_t revidr;
30
TYPE data[sizeof(ARMVectorReg) / sizeof(TYPE)]; \
42
uint32_t reset_fpsid;
31
for (i = 0; i < oprsz; ) { \
43
uint32_t ctr;
32
uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
45
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
35
--- a/target/arm/translate-sve.c
47
+++ b/target/arm/cpu.c
36
+++ b/target/arm/translate-sve.c
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
37
@@ -XXX,XX +XXX,XX @@ static void do_reduce(DisasContext *s, arg_rpr_esz *a,
49
static Property arm_cpu_properties[] = {
38
{
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
39
unsigned vsz = vec_full_reg_size(s);
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
40
unsigned p2vsz = pow2ceil(vsz);
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
41
- TCGv_i32 t_desc = tcg_const_i32(simd_desc(vsz, p2vsz, 0));
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
42
+ TCGv_i32 t_desc = tcg_const_i32(simd_desc(vsz, vsz, p2vsz));
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
43
TCGv_ptr t_zn, t_pg, status;
55
mp_affinity, ARM64_AFFINITY_INVALID),
44
TCGv_i64 temp;
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
45
57
--
46
--
58
2.20.1
47
2.20.1
59
48
60
49
diff view generated by jsdifflib
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
3-reg-same grouping to decodetree.
3
2
3
Currently the emulated EMAC for sun8i always traverses the transmit queue
4
from the head when transferring packets. It searches for a list of consecutive
5
descriptors whichs are flagged as ready for processing and transmits their payloads
6
accordingly. The controller stops processing once it finds a descriptor that is not
7
marked ready.
8
9
While the above behaviour works in most situations, it is not the same as the actual
10
EMAC in hardware. Actual hardware uses the TX_CUR_DESC register value to keep track
11
of the last position in the transmit queue and continues processing from that position
12
when software triggers the start of DMA processing. The currently emulated behaviour can
13
lead to packet loss on transmit when software fills the transmit queue with ready
14
descriptors that overlap the tail of the circular list.
15
16
This commit modifies the emulated EMAC for sun8i such that it processes
17
the transmit queue using the TX_CUR_DESC register in the same way as hardware.
18
19
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210310195820.21950-2-nieklinnenbank@gmail.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
7
---
23
---
8
target/arm/neon-dp.decode | 9 +++++++
24
hw/net/allwinner-sun8i-emac.c | 62 +++++++++++++++++++----------------
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
25
1 file changed, 34 insertions(+), 28 deletions(-)
10
target/arm/translate.c | 28 +++------------------
11
3 files changed, 56 insertions(+), 25 deletions(-)
12
26
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
27
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
14
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
29
--- a/hw/net/allwinner-sun8i-emac.c
16
+++ b/target/arm/neon-dp.decode
30
+++ b/hw/net/allwinner-sun8i-emac.c
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
31
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_update_irq(AwSun8iEmacState *s)
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
32
qemu_set_irq(s->irq, (s->int_sta & s->int_en) != 0);
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
33
}
20
34
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
35
-static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
36
- FrameDescriptor *desc,
23
+
37
- size_t min_size)
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
38
+static bool allwinner_sun8i_emac_desc_owned(FrameDescriptor *desc,
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
39
+ size_t min_buf_size)
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
40
{
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
41
- uint32_t paddr = desc->next;
28
42
-
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
43
- dma_memory_read(&s->dma_as, paddr, desc, sizeof(*desc));
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
44
-
31
+
45
- if ((desc->status & DESC_STATUS_CTL) &&
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
46
- (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
47
- return paddr;
34
+
48
- } else {
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
49
- return 0;
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
50
- }
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
51
+ return (desc->status & DESC_STATUS_CTL) && (min_buf_size == 0 ||
38
index XXXXXXX..XXXXXXX 100644
52
+ (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_buf_size);
39
--- a/target/arm/translate-neon.inc.c
53
}
40
+++ b/target/arm/translate-neon.inc.c
54
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
55
-static uint32_t allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
56
- FrameDescriptor *desc,
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
57
- uint32_t start_addr,
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
58
- size_t min_size)
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
59
+static void allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
46
60
+ FrameDescriptor *desc,
47
#define DO_3SAME_CMP(INSN, COND) \
61
+ uint32_t phys_addr)
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
53
+
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
56
+{
62
+{
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
63
+ dma_memory_read(&s->dma_as, phys_addr, desc, sizeof(*desc));
58
+ 0, gen_helper_gvec_pmul_b);
59
+}
64
+}
60
+
65
+
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
66
+static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
67
+ FrameDescriptor *desc)
62
+{
68
+{
63
+ if (a->size != 0) {
69
+ const uint32_t nxt = desc->next;
64
+ return false;
70
+ allwinner_sun8i_emac_get_desc(s, desc, nxt);
65
+ }
71
+ return nxt;
66
+ return do_3same(s, a, gen_VMUL_p_3s);
67
+}
72
+}
68
+
73
+
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
74
+static uint32_t allwinner_sun8i_emac_find_desc(AwSun8iEmacState *s,
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
75
+ FrameDescriptor *desc,
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
76
+ uint32_t start_addr,
72
+ uint32_t oprsz, uint32_t maxsz) \
77
+ size_t min_size)
73
+ { \
78
{
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
79
uint32_t desc_addr = start_addr;
75
+ oprsz, maxsz, &OPARRAY[vece]); \
80
76
+ } \
81
/* Note that the list is a cycle. Last entry points back to the head. */
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
82
while (desc_addr != 0) {
78
+
83
- dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc));
79
+
84
+ allwinner_sun8i_emac_get_desc(s, desc, desc_addr);
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
85
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
86
- if ((desc->status & DESC_STATUS_CTL) &&
82
+
87
- (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
88
+ if (allwinner_sun8i_emac_desc_owned(desc, min_size)) {
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
89
return desc_addr;
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
90
} else if (desc->next == start_addr) {
86
+ uint32_t oprsz, uint32_t maxsz) \
91
break;
87
+ { \
92
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sun8i_emac_rx_desc(AwSun8iEmacState *s,
88
+ /* Note the operation is vshl vd,vm,vn */ \
93
FrameDescriptor *desc,
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
94
size_t min_size)
90
+ oprsz, maxsz, &OPARRAY[vece]); \
95
{
91
+ } \
96
- return allwinner_sun8i_emac_get_desc(s, desc, s->rx_desc_curr, min_size);
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
97
+ return allwinner_sun8i_emac_find_desc(s, desc, s->rx_desc_curr, min_size);
93
+
98
}
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
99
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
100
static uint32_t allwinner_sun8i_emac_tx_desc(AwSun8iEmacState *s,
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
101
- FrameDescriptor *desc,
97
index XXXXXXX..XXXXXXX 100644
102
- size_t min_size)
98
--- a/target/arm/translate.c
103
+ FrameDescriptor *desc)
99
+++ b/target/arm/translate.c
104
{
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
105
- return allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_head, min_size);
101
}
106
+ allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_curr);
102
return 1;
107
+ return s->tx_desc_curr;
103
108
}
104
- case NEON_3R_VMUL: /* VMUL */
109
105
- if (u) {
110
static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s,
106
- /* Polynomial case allows only P8. */
111
@@ -XXX,XX +XXX,XX @@ static ssize_t allwinner_sun8i_emac_receive(NetClientState *nc,
107
- if (size != 0) {
112
bytes_left -= desc_bytes;
108
- return 1;
113
109
- }
114
/* Move to the next descriptor */
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
115
- s->rx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 64);
111
- 0, gen_helper_gvec_pmul_b);
116
+ s->rx_desc_curr = allwinner_sun8i_emac_find_desc(s, &desc, desc.next,
112
- } else {
117
+ AW_SUN8I_EMAC_MIN_PKT_SZ);
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
118
if (!s->rx_desc_curr) {
114
- vec_size, vec_size);
119
/* Not enough buffer space available */
115
- }
120
s->int_sta |= INT_STA_RX_BUF_UA;
116
- return 0;
121
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
117
-
122
size_t transmitted = 0;
118
- case NEON_3R_VML: /* VMLA, VMLS */
123
static uint8_t packet_buf[2048];
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
124
120
- u ? &mls_op[size] : &mla_op[size]);
125
- s->tx_desc_curr = allwinner_sun8i_emac_tx_desc(s, &desc, 0);
121
- return 0;
126
+ s->tx_desc_curr = allwinner_sun8i_emac_tx_desc(s, &desc);
122
-
127
123
- case NEON_3R_VSHL:
128
/* Read all transmit descriptors */
124
- /* Note the operation is vshl vd,vm,vn */
129
- while (s->tx_desc_curr != 0) {
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
130
+ while (allwinner_sun8i_emac_desc_owned(&desc, 0)) {
126
- u ? &ushl_op[size] : &sshl_op[size]);
131
127
- return 0;
132
/* Read from physical memory into packet buffer */
128
-
133
bytes = desc.status2 & DESC_STATUS2_BUF_SIZE_MASK;
129
case NEON_3R_VADD_VSUB:
134
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
130
case NEON_3R_LOGIC:
135
packet_bytes = 0;
131
case NEON_3R_VMAX:
136
transmitted++;
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
case NEON_3R_VCGE:
134
case NEON_3R_VQADD:
135
case NEON_3R_VQSUB:
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
137
}
138
- s->tx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 0);
139
+ s->tx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc);
140
}
141
142
/* Raise transmit completed interrupt */
142
--
143
--
143
2.20.1
144
2.20.1
144
145
145
146
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
2
3
Embed the GEMs into the SoC type.
3
The image for Armbian 19.11.3 bionic has been removed from the armbian server.
4
Without the image as input the test arm_orangepi_bionic_19_11 cannot run.
4
5
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
This commit removes the test completely and merges the code of the generic function
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
do_test_arm_orangepi_uboot_armbian back with the 20.08 test.
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
11
Message-id: 20210310195820.21950-3-nieklinnenbank@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
14
tests/acceptance/boot_linux_console.py | 72 ++++++++------------------
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
15
1 file changed, 23 insertions(+), 49 deletions(-)
15
2 files changed, 10 insertions(+), 8 deletions(-)
16
16
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
19
--- a/tests/acceptance/boot_linux_console.py
20
+++ b/include/hw/arm/xlnx-versal.h
20
+++ b/tests/acceptance/boot_linux_console.py
21
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
22
#include "hw/arm/boot.h"
22
# Wait for VM to shut down gracefully
23
#include "hw/intc/arm_gicv3.h"
23
self.vm.wait()
24
#include "hw/char/pl011.h"
24
25
+#include "hw/net/cadence_gem.h"
25
- def do_test_arm_orangepi_uboot_armbian(self, image_path):
26
26
+ @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
+ 'Test artifacts fetched from unreliable apt.armbian.com')
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
28
+ @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
29
+ def test_arm_orangepi_bionic_20_08(self):
30
30
+ """
31
struct {
31
+ :avocado: tags=arch:arm
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
32
+ :avocado: tags=machine:orangepi-pc
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
33
+ :avocado: tags=device:sd
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
34
+ """
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
35
+
36
} iou;
36
+ # This test download a 275 MiB compressed image and expand it
37
} lpd;
37
+ # to 1036 MiB, but the underlying filesystem is 1552 MiB...
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
38
+ # As we expand it to 2 GiB we are safe.
39
index XXXXXXX..XXXXXXX 100644
39
+
40
--- a/hw/arm/xlnx-versal.c
40
+ image_url = ('https://dl.armbian.com/orangepipc/archive/'
41
+++ b/hw/arm/xlnx-versal.c
41
+ 'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
42
+ image_hash = ('b4d6775f5673486329e45a0586bf06b6'
43
DeviceState *dev;
43
+ 'dbe792199fd182ac6b9c7bb6c7d3e6dd')
44
MemoryRegion *mr;
44
+ image_path_xz = self.fetch_asset(image_url, asset_hash=image_hash,
45
45
+ algorithm='sha256')
46
- dev = qdev_create(NULL, "cadence_gem");
46
+ image_path = archive.extract(image_path_xz, self.workdir)
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
47
+ image_pow2ceil_expand(image_path)
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
48
+
49
+ sysbus_init_child_obj(OBJECT(s), name,
49
self.vm.set_console()
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
50
self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw',
51
+ TYPE_CADENCE_GEM);
51
'-nic', 'user',
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
52
@@ -XXX,XX +XXX,XX @@ def do_test_arm_orangepi_uboot_armbian(self, image_path):
53
if (nd->used) {
53
'to <orangepipc>')
54
qemu_check_nic_model(nd, "cadence_gem");
54
self.wait_for_console_pattern('Starting Load Kernel Modules...')
55
qdev_set_nic_properties(dev, nd);
55
56
}
56
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
57
- 'Test artifacts fetched from unreliable apt.armbian.com')
58
+ object_property_set_int(OBJECT(dev),
58
- @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
59
2, "num-priority-queues",
59
- @skipUnless(P7ZIP_AVAILABLE, '7z not installed')
60
&error_abort);
60
- def test_arm_orangepi_bionic_19_11(self):
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
61
- """
62
+ object_property_set_link(OBJECT(dev),
62
- :avocado: tags=arch:arm
63
OBJECT(&s->mr_ps), "dma",
63
- :avocado: tags=machine:orangepi-pc
64
&error_abort);
64
- :avocado: tags=device:sd
65
qdev_init_nofail(dev);
65
- """
66
66
-
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
67
- # This test download a 196MB compressed image and expand it to 1GB
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
68
- image_url = ('https://dl.armbian.com/orangepipc/archive/'
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
69
- 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.7z')
70
70
- image_hash = '196a8ffb72b0123d92cea4a070894813d305c71e'
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
71
- image_path_7z = self.fetch_asset(image_url, asset_hash=image_hash)
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
72
- image_name = 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img'
73
g_free(name);
73
- image_path = os.path.join(self.workdir, image_name)
74
}
74
- process.run("7z e -o%s %s" % (self.workdir, image_path_7z))
75
}
75
- image_pow2ceil_expand(image_path)
76
-
77
- self.do_test_arm_orangepi_uboot_armbian(image_path)
78
-
79
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
80
- 'Test artifacts fetched from unreliable apt.armbian.com')
81
- @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
82
- def test_arm_orangepi_bionic_20_08(self):
83
- """
84
- :avocado: tags=arch:arm
85
- :avocado: tags=machine:orangepi-pc
86
- :avocado: tags=device:sd
87
- """
88
-
89
- # This test download a 275 MiB compressed image and expand it
90
- # to 1036 MiB, but the underlying filesystem is 1552 MiB...
91
- # As we expand it to 2 GiB we are safe.
92
-
93
- image_url = ('https://dl.armbian.com/orangepipc/archive/'
94
- 'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
95
- image_hash = ('b4d6775f5673486329e45a0586bf06b6'
96
- 'dbe792199fd182ac6b9c7bb6c7d3e6dd')
97
- image_path_xz = self.fetch_asset(image_url, asset_hash=image_hash,
98
- algorithm='sha256')
99
- image_path = archive.extract(image_path_xz, self.workdir)
100
- image_pow2ceil_expand(image_path)
101
-
102
- self.do_test_arm_orangepi_uboot_armbian(image_path)
103
-
104
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
105
def test_arm_orangepi_uboot_netbsd9(self):
106
"""
76
--
107
--
77
2.20.1
108
2.20.1
78
109
79
110
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
2
3
Move misplaced comment.
3
Update the download URL of the Armbian 20.08 Bionic image for
4
test_arm_orangepi_bionic_20_08 of the orangepi-pc machine.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
The archive.armbian.com URL contains more images and should keep stable
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
for a longer period of time than dl.armbian.com.
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.com
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
13
Message-id: 20210310195820.21950-4-nieklinnenbank@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
hw/arm/xlnx-versal.c | 2 +-
16
tests/acceptance/boot_linux_console.py | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 1 insertion(+), 1 deletion(-)
14
18
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
19
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
21
--- a/tests/acceptance/boot_linux_console.py
18
+++ b/hw/arm/xlnx-versal.c
22
+++ b/tests/acceptance/boot_linux_console.py
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
23
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_bionic_20_08(self):
20
24
# to 1036 MiB, but the underlying filesystem is 1552 MiB...
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
25
# As we expand it to 2 GiB we are safe.
22
if (!obj) {
26
23
- /* Secondary CPUs start in PSCI powered-down state */
27
- image_url = ('https://dl.armbian.com/orangepipc/archive/'
24
error_report("Unable to create apu.cpu[%d] of type %s",
28
+ image_url = ('https://archive.armbian.com/orangepipc/archive/'
25
i, XLNX_VERSAL_ACPU_TYPE);
29
'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
26
exit(EXIT_FAILURE);
30
image_hash = ('b4d6775f5673486329e45a0586bf06b6'
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
31
'dbe792199fd182ac6b9c7bb6c7d3e6dd')
28
object_property_set_int(obj, s->cfg.psci_conduit,
29
"psci-conduit", &error_abort);
30
if (i) {
31
+ /* Secondary CPUs start in PSCI powered-down state */
32
object_property_set_bool(obj, true,
33
"start-powered-off", &error_abort);
34
}
35
--
32
--
36
2.20.1
33
2.20.1
37
34
38
35
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
2
3
Embed the UARTs into the SoC type.
3
The linux kernel 4.20.7 binary for sunxi has been removed from apt.armbian.com:
4
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
$ ARMBIAN_ARTIFACTS_CACHED=yes AVOCADO_ALLOW_LARGE_STORAGE=yes avocado --show=app,console run -t machine:orangepi-pc tests/acceptance/boot_linux_console.py
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Fetching asset from tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
...
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
(1/6) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
CANCEL: Missing asset https://apt.armbian.com/pool/main/l/linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb (0.55 s)
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.com
10
11
This commit updates the sunxi kernel to 5.10.16 for the acceptance
12
tests of the orangepi-pc and cubieboard machines.
13
14
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
15
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
16
Message-id: 20210310195820.21950-5-nieklinnenbank@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
18
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
19
tests/acceptance/boot_linux_console.py | 40 +++++++++++++-------------
14
hw/arm/xlnx-versal.c | 12 ++++++------
20
tests/acceptance/replay_kernel.py | 8 +++---
15
2 files changed, 8 insertions(+), 7 deletions(-)
21
2 files changed, 24 insertions(+), 24 deletions(-)
16
22
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
23
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
18
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
25
--- a/tests/acceptance/boot_linux_console.py
20
+++ b/include/hw/arm/xlnx-versal.h
26
+++ b/tests/acceptance/boot_linux_console.py
21
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
22
#include "hw/sysbus.h"
28
:avocado: tags=machine:cubieboard
23
#include "hw/arm/boot.h"
29
"""
24
#include "hw/intc/arm_gicv3.h"
30
deb_url = ('https://apt.armbian.com/pool/main/l/'
25
+#include "hw/char/pl011.h"
31
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
26
32
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
33
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
34
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
35
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
30
MemoryRegion mr_ocm;
36
kernel_path = self.extract_from_deb(deb_path,
31
37
- '/boot/vmlinuz-4.20.7-sunxi')
32
struct {
38
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
39
+ '/boot/vmlinuz-5.10.16-sunxi')
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
40
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
41
dtb_path = self.extract_from_deb(deb_path, dtb_path)
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
42
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
37
} iou;
43
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
44
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self):
45
:avocado: tags=machine:cubieboard
46
"""
47
deb_url = ('https://apt.armbian.com/pool/main/l/'
48
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
49
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
50
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
51
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
52
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
53
kernel_path = self.extract_from_deb(deb_path,
54
- '/boot/vmlinuz-4.20.7-sunxi')
55
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
56
+ '/boot/vmlinuz-5.10.16-sunxi')
57
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
58
dtb_path = self.extract_from_deb(deb_path, dtb_path)
59
rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
60
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
61
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi(self):
62
:avocado: tags=machine:orangepi-pc
63
"""
64
deb_url = ('https://apt.armbian.com/pool/main/l/'
65
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
66
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
67
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
68
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
69
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
70
kernel_path = self.extract_from_deb(deb_path,
71
- '/boot/vmlinuz-4.20.7-sunxi')
72
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
73
+ '/boot/vmlinuz-5.10.16-sunxi')
74
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
75
dtb_path = self.extract_from_deb(deb_path, dtb_path)
76
77
self.vm.set_console()
78
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_initrd(self):
79
:avocado: tags=machine:orangepi-pc
80
"""
81
deb_url = ('https://apt.armbian.com/pool/main/l/'
82
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
83
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
84
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
85
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
86
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
87
kernel_path = self.extract_from_deb(deb_path,
88
- '/boot/vmlinuz-4.20.7-sunxi')
89
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
90
+ '/boot/vmlinuz-5.10.16-sunxi')
91
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
92
dtb_path = self.extract_from_deb(deb_path, dtb_path)
93
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
94
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
95
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
96
:avocado: tags=device:sd
97
"""
98
deb_url = ('https://apt.armbian.com/pool/main/l/'
99
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
100
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
101
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
102
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
103
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
104
kernel_path = self.extract_from_deb(deb_path,
105
- '/boot/vmlinuz-4.20.7-sunxi')
106
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
107
+ '/boot/vmlinuz-5.10.16-sunxi')
108
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
109
dtb_path = self.extract_from_deb(deb_path, dtb_path)
110
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
111
'kci-2019.02/armel/base/rootfs.ext2.xz')
112
diff --git a/tests/acceptance/replay_kernel.py b/tests/acceptance/replay_kernel.py
39
index XXXXXXX..XXXXXXX 100644
113
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
114
--- a/tests/acceptance/replay_kernel.py
41
+++ b/hw/arm/xlnx-versal.c
115
+++ b/tests/acceptance/replay_kernel.py
42
@@ -XXX,XX +XXX,XX @@
116
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
43
#include "kvm_arm.h"
117
:avocado: tags=machine:cubieboard
44
#include "hw/misc/unimp.h"
118
"""
45
#include "hw/arm/xlnx-versal.h"
119
deb_url = ('https://apt.armbian.com/pool/main/l/'
46
-#include "hw/char/pl011.h"
120
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
47
121
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
122
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
49
#define GEM_REVISION 0x40070106
123
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
124
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
51
DeviceState *dev;
125
kernel_path = self.extract_from_deb(deb_path,
52
MemoryRegion *mr;
126
- '/boot/vmlinuz-4.20.7-sunxi')
53
127
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
54
- dev = qdev_create(NULL, TYPE_PL011);
128
+ '/boot/vmlinuz-5.10.16-sunxi')
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
129
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
56
+ sysbus_init_child_obj(OBJECT(s), name,
130
dtb_path = self.extract_from_deb(deb_path, dtb_path)
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
131
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
58
+ TYPE_PL011);
132
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
62
qdev_init_nofail(dev);
63
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
67
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
70
g_free(name);
71
}
72
}
73
--
133
--
74
2.20.1
134
2.20.1
75
135
76
136
diff view generated by jsdifflib
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
registers. The intended pattern is that for 64-bit ID registers we
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
6
this 64-bit ID register would end up always zero. Luckily at the
7
moment that's what they should be anyway, so this bug has no visible
8
effects.
9
2
10
Use the right-sized variable.
3
Previously the ARMBIAN_ARTIFACTS_CACHED pre-condition was added to allow running
4
tests that have already existing armbian.com artifacts stored in the local avocado cache,
5
but do not have working URLs to download a fresh copy.
11
6
12
Fixes: 3bec78447a958d481991
7
At this time of writing the URLs for artifacts on the armbian.com server are updated and working.
8
Any future broken URLs will result in a skipped acceptance test, for example:
9
10
(1/5) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
11
CANCEL: Missing asset https://apt.armbian.com/pool/main/l/linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb (0.53 s)
12
13
This commits removes the ARMBIAN_ARTIFACTS_CACHED pre-condition such that
14
the acceptance tests for the orangepi-pc and cubieboard machines can run.
15
16
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
18
Message-id: 20210310195820.21950-6-nieklinnenbank@gmail.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
17
---
20
---
18
target/arm/cpu64.c | 6 +++---
21
tests/acceptance/boot_linux_console.py | 12 ------------
19
1 file changed, 3 insertions(+), 3 deletions(-)
22
tests/acceptance/replay_kernel.py | 2 --
23
2 files changed, 14 deletions(-)
20
24
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
25
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
22
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu64.c
27
--- a/tests/acceptance/boot_linux_console.py
24
+++ b/target/arm/cpu64.c
28
+++ b/tests/acceptance/boot_linux_console.py
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
29
@@ -XXX,XX +XXX,XX @@ def test_arm_exynos4210_initrd(self):
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
30
self.wait_for_console_pattern('Boot successful.')
27
cpu->isar.id_mmfr4 = u;
31
# TODO user command, for now the uart is stuck
28
32
29
- u = cpu->isar.id_aa64dfr0;
33
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
34
- 'Test artifacts fetched from unreliable apt.armbian.com')
31
- cpu->isar.id_aa64dfr0 = u;
35
def test_arm_cubieboard_initrd(self):
32
+ t = cpu->isar.id_aa64dfr0;
36
"""
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
37
:avocado: tags=arch:arm
34
+ cpu->isar.id_aa64dfr0 = t;
38
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
35
39
'system-control@1c00000')
36
u = cpu->isar.id_dfr0;
40
# cubieboard's reboot is not functioning; omit reboot test.
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
41
42
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
43
- 'Test artifacts fetched from unreliable apt.armbian.com')
44
def test_arm_cubieboard_sata(self):
45
"""
46
:avocado: tags=arch:arm
47
@@ -XXX,XX +XXX,XX @@ def test_arm_quanta_gsj_initrd(self):
48
self.wait_for_console_pattern(
49
'Give root password for system maintenance')
50
51
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
52
- 'Test artifacts fetched from unreliable apt.armbian.com')
53
def test_arm_orangepi(self):
54
"""
55
:avocado: tags=arch:arm
56
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi(self):
57
console_pattern = 'Kernel command line: %s' % kernel_command_line
58
self.wait_for_console_pattern(console_pattern)
59
60
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
61
- 'Test artifacts fetched from unreliable apt.armbian.com')
62
def test_arm_orangepi_initrd(self):
63
"""
64
:avocado: tags=arch:arm
65
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_initrd(self):
66
# Wait for VM to shut down gracefully
67
self.vm.wait()
68
69
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
70
- 'Test artifacts fetched from unreliable apt.armbian.com')
71
def test_arm_orangepi_sd(self):
72
"""
73
:avocado: tags=arch:arm
74
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
75
# Wait for VM to shut down gracefully
76
self.vm.wait()
77
78
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
79
- 'Test artifacts fetched from unreliable apt.armbian.com')
80
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
81
def test_arm_orangepi_bionic_20_08(self):
82
"""
83
diff --git a/tests/acceptance/replay_kernel.py b/tests/acceptance/replay_kernel.py
84
index XXXXXXX..XXXXXXX 100644
85
--- a/tests/acceptance/replay_kernel.py
86
+++ b/tests/acceptance/replay_kernel.py
87
@@ -XXX,XX +XXX,XX @@ def test_arm_virt(self):
88
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=1)
89
90
@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
91
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
92
- 'Test artifacts fetched from unreliable apt.armbian.com')
93
def test_arm_cubieboard_initrd(self):
94
"""
95
:avocado: tags=arch:arm
38
--
96
--
39
2.20.1
97
2.20.1
40
98
41
99
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
By using the TYPE_* definitions for devices, we can:
3
If the SSECounter link is absent, we set an error message
4
- quickly find where devices are used with 'git-grep'
4
in sse_timer_realize() but forgot to propagate this error.
5
- easily rename a device (one-line change).
5
Add the missing 'return'.
6
6
7
Fixes: CID 1450755 (Null pointer dereferences)
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
9
Message-id: 20210312001845.1562670-1-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
hw/arm/mps2-tz.c | 2 +-
13
hw/timer/sse-timer.c | 1 +
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+)
14
15
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
diff --git a/hw/timer/sse-timer.c b/hw/timer/sse-timer.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
18
--- a/hw/timer/sse-timer.c
18
+++ b/hw/arm/mps2-tz.c
19
+++ b/hw/timer/sse-timer.c
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
20
@@ -XXX,XX +XXX,XX @@ static void sse_timer_realize(DeviceState *dev, Error **errp)
20
exit(EXIT_FAILURE);
21
22
if (!s->counter) {
23
error_setg(errp, "counter property was not set");
24
+ return;
21
}
25
}
22
26
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
27
s->counter_notifier.notify = sse_timer_counter_callback;
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
25
sizeof(mms->iotkit), mmc->armsse_type);
26
iotkitdev = DEVICE(&mms->iotkit);
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
28
--
28
--
29
2.20.1
29
2.20.1
30
30
31
31
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
Fix typo xlnx-ve -> xlnx-versal.
3
Prior to commit f2ce39b4f067 a MachineClass kvm_type method
4
only needed to be registered to ensure it would be executed.
5
With commit f2ce39b4f067 a kvm-type machine property must also
6
be specified. hw/arm/virt relies on the kvm_type method to pass
7
its selected IPA limit to KVM, but this is not exposed as a
8
machine property. Restore the previous functionality of invoking
9
kvm_type when it's present.
4
10
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Fixes: f2ce39b4f067 ("vl: make qemu_get_machine_opts static")
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
14
Message-id: 20210310135218.255205-2-drjones@redhat.com
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
16
---
12
hw/arm/xlnx-versal-virt.c | 2 +-
17
include/hw/boards.h | 1 +
13
1 file changed, 1 insertion(+), 1 deletion(-)
18
accel/kvm/kvm-all.c | 2 ++
19
2 files changed, 3 insertions(+)
14
20
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
21
diff --git a/include/hw/boards.h b/include/hw/boards.h
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
23
--- a/include/hw/boards.h
18
+++ b/hw/arm/xlnx-versal-virt.c
24
+++ b/include/hw/boards.h
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
25
@@ -XXX,XX +XXX,XX @@ typedef struct {
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
26
* @kvm_type:
27
* Return the type of KVM corresponding to the kvm-type string option or
28
* computed based on other criteria such as the host kernel capabilities.
29
+ * kvm-type may be NULL if it is not needed.
30
* @numa_mem_supported:
31
* true if '--numa node.mem' option is supported and false otherwise
32
* @smp_parse:
33
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/accel/kvm/kvm-all.c
36
+++ b/accel/kvm/kvm-all.c
37
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
38
"kvm-type",
39
&error_abort);
40
type = mc->kvm_type(ms, kvm_type);
41
+ } else if (mc->kvm_type) {
42
+ type = mc->kvm_type(ms, NULL);
21
}
43
}
22
44
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
45
do {
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
27
"ddr", &error_abort);
28
--
46
--
29
2.20.1
47
2.20.1
30
48
31
49
diff view generated by jsdifflib
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
1
From: Andrew Jones <drjones@redhat.com>
2
insn in the legacy decoder for the 3same_ext group, so we can
3
delete the legacy decoder function for the group entirely.
4
2
5
Note that in disas_thumb2_insn() the parts of this encoding space
3
The virt machine already checks KVM_CAP_ARM_VM_IPA_SIZE to get the
6
where the decodetree decoder returns false will correctly be directed
4
upper bound of the IPA size. If that bound is lower than the highest
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
5
possible GPA for the machine, then QEMU will error out. However, the
8
into disas_coproc_insn() by mistake.
6
IPA is set to 40 when the highest GPA is less than or equal to 40,
7
even when KVM may support an IPA limit as low as 32. This means KVM
8
may fail the VM creation unnecessarily. Additionally, 40 is selected
9
with the value 0, which means use the default, and that gets around
10
a check in some versions of KVM, causing a difficult to debug fail.
11
Always use the IPA size that corresponds to the highest possible GPA,
12
unless it's lower than 32, in which case use 32. Also, we must still
13
use 0 when KVM only supports the legacy fixed 40 bit IPA.
9
14
15
Suggested-by: Marc Zyngier <maz@kernel.org>
16
Signed-off-by: Andrew Jones <drjones@redhat.com>
17
Reviewed-by: Eric Auger <eric.auger@redhat.com>
18
Reviewed-by: Marc Zyngier <maz@kernel.org>
19
Message-id: 20210310135218.255205-3-drjones@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
13
---
21
---
14
target/arm/neon-shared.decode | 6 +++
22
target/arm/kvm_arm.h | 6 ++++--
15
target/arm/translate-neon.inc.c | 31 +++++++++++
23
hw/arm/virt.c | 23 ++++++++++++++++-------
16
target/arm/translate.c | 92 +--------------------------------
24
target/arm/kvm.c | 4 +++-
17
3 files changed, 38 insertions(+), 91 deletions(-)
25
3 files changed, 23 insertions(+), 10 deletions(-)
18
26
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
27
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
20
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
29
--- a/target/arm/kvm_arm.h
22
+++ b/target/arm/neon-shared.decode
30
+++ b/target/arm/kvm_arm.h
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
31
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_sve_supported(void);
24
# VUDOT and VSDOT
32
/**
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
33
* kvm_arm_get_max_vm_ipa_size:
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
34
* @ms: Machine state handle
35
+ * @fixed_ipa: True when the IPA limit is fixed at 40. This is the case
36
+ * for legacy KVM.
37
*
38
* Returns the number of bits in the IPA address space supported by KVM
39
*/
40
-int kvm_arm_get_max_vm_ipa_size(MachineState *ms);
41
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa);
42
43
/**
44
* kvm_arm_sync_mpstate_to_kvm:
45
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_add_vcpu_properties(Object *obj)
46
g_assert_not_reached();
47
}
48
49
-static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
50
+static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
51
{
52
g_assert_not_reached();
53
}
54
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/virt.c
57
+++ b/hw/arm/virt.c
58
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
59
static int virt_kvm_type(MachineState *ms, const char *type_str)
60
{
61
VirtMachineState *vms = VIRT_MACHINE(ms);
62
- int max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms);
63
- int requested_pa_size;
64
+ int max_vm_pa_size, requested_pa_size;
65
+ bool fixed_ipa;
27
+
66
+
28
+# VFM[AS]L
67
+ max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms, &fixed_ipa);
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
68
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
69
/* we freeze the memory map to compute the highest gpa */
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
70
virt_set_memmap(vms);
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
71
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
72
requested_pa_size = 64 - clz64(vms->highest_gpa);
34
index XXXXXXX..XXXXXXX 100644
73
35
--- a/target/arm/translate-neon.inc.c
74
+ /*
36
+++ b/target/arm/translate-neon.inc.c
75
+ * KVM requires the IPA size to be at least 32 bits.
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
76
+ */
38
opr_sz, opr_sz, 0, fn_gvec);
77
+ if (requested_pa_size < 32) {
39
return true;
78
+ requested_pa_size = 32;
40
}
41
+
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
43
+{
44
+ int opr_sz;
45
+
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
47
+ return false;
48
+ }
79
+ }
49
+
80
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
81
if (requested_pa_size > max_vm_pa_size) {
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
82
error_report("-m and ,maxmem option values "
52
+ (a->vd & 0x10)) {
83
"require an IPA range (%d bits) larger than "
53
+ return false;
84
"the one supported by the host (%d bits)",
54
+ }
85
requested_pa_size, max_vm_pa_size);
86
- exit(1);
87
+ exit(1);
88
}
89
/*
90
- * By default we return 0 which corresponds to an implicit legacy
91
- * 40b IPA setting. Otherwise we return the actual requested PA
92
- * logsize
93
+ * We return the requested PA log size, unless KVM only supports
94
+ * the implicit legacy 40b IPA setting, in which case the kvm_type
95
+ * must be 0.
96
*/
97
- return requested_pa_size > 40 ? requested_pa_size : 0;
98
+ return fixed_ipa ? 0 : requested_pa_size;
99
}
100
101
static void virt_machine_class_init(ObjectClass *oc, void *data)
102
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/kvm.c
105
+++ b/target/arm/kvm.c
106
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_pmu_supported(void)
107
return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
108
}
109
110
-int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
111
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
112
{
113
KVMState *s = KVM_STATE(ms->accelerator);
114
int ret;
115
116
ret = kvm_check_extension(s, KVM_CAP_ARM_VM_IPA_SIZE);
117
+ *fixed_ipa = ret <= 0;
55
+
118
+
56
+ if (a->vd & a->q) {
119
return ret > 0 ? ret : 40;
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
return 0;
78
}
120
}
79
121
80
-/* Advanced SIMD three registers of the same length extension.
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
85
- */
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
87
-{
88
- gen_helper_gvec_3 *fn_gvec = NULL;
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
90
- int rd, rn, rm, opr_sz;
91
- int data = 0;
92
- int off_rn, off_rm;
93
- bool is_long = false, q = extract32(insn, 6, 1);
94
- bool ptr_is_env = false;
95
-
96
- if ((insn & 0xff300f10) == 0xfc200810) {
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
98
- int is_s = extract32(insn, 23, 1);
99
- if (!dc_isar_feature(aa32_fhm, s)) {
100
- return 1;
101
- }
102
- is_long = true;
103
- data = is_s; /* is_2 == 0 */
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
105
- ptr_is_env = true;
106
- } else {
107
- return 1;
108
- }
109
-
110
- VFP_DREG_D(rd, insn);
111
- if (rd & q) {
112
- return 1;
113
- }
114
- if (q || !is_long) {
115
- VFP_DREG_N(rn, insn);
116
- VFP_DREG_M(rm, insn);
117
- if ((rn | rm) & q & !is_long) {
118
- return 1;
119
- }
120
- off_rn = vfp_reg_offset(1, rn);
121
- off_rm = vfp_reg_offset(1, rm);
122
- } else {
123
- rn = VFP_SREG_N(insn);
124
- rm = VFP_SREG_M(insn);
125
- off_rn = vfp_reg_offset(0, rn);
126
- off_rm = vfp_reg_offset(0, rm);
127
- }
128
-
129
- if (s->fp_excp_el) {
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
132
- return 0;
133
- }
134
- if (!s->vfp_enabled) {
135
- return 1;
136
- }
137
-
138
- opr_sz = (1 + q) * 8;
139
- if (fn_gvec_ptr) {
140
- TCGv_ptr ptr;
141
- if (ptr_is_env) {
142
- ptr = cpu_env;
143
- } else {
144
- ptr = get_fpstatus_ptr(1);
145
- }
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
148
- if (!ptr_is_env) {
149
- tcg_temp_free_ptr(ptr);
150
- }
151
- } else {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
153
- opr_sz, opr_sz, data, fn_gvec);
154
- }
155
- return 0;
156
-}
157
-
158
/* Advanced SIMD two registers and a scalar extension.
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
162
}
163
}
164
}
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
167
- if (disas_neon_insn_3same_ext(s, insn)) {
168
- goto illegal_op;
169
- }
170
- return;
171
} else if ((insn & 0x0f000a00) == 0x0e000800
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
174
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
175
}
176
break;
177
}
178
- if ((insn & 0xfe000a00) == 0xfc000800
179
+ if ((insn & 0xff000a00) == 0xfe000800
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
181
/* The Thumb2 and ARM encodings are identical. */
182
- if (disas_neon_insn_3same_ext(s, insn)) {
183
- goto illegal_op;
184
- }
185
- } else if ((insn & 0xff000a00) == 0xfe000800
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
187
- /* The Thumb2 and ARM encodings are identical. */
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
189
goto illegal_op;
190
}
191
--
122
--
192
2.20.1
123
2.20.1
193
124
194
125
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
Add support for SD.
3
This patch adds GPIOs in NPCM7xx PWM module for its duty values.
4
The purpose of this is to connect it to the MFT module to provide
5
an input for measuring a PWM fan's RPM. Each PWM module has
6
NPCM7XX_PWM_PER_MODULE of GPIOs, each one corresponds to
7
one PWM instance and can connect to multiple fan instances in MFT.
4
8
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Doug Evans <dje@google.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20210311180855.149764-2-wuhaotsh@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
16
include/hw/misc/npcm7xx_pwm.h | 4 +++-
12
1 file changed, 46 insertions(+)
17
hw/misc/npcm7xx_pwm.c | 4 ++++
18
2 files changed, 7 insertions(+), 1 deletion(-)
13
19
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
20
diff --git a/include/hw/misc/npcm7xx_pwm.h b/include/hw/misc/npcm7xx_pwm.h
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
22
--- a/include/hw/misc/npcm7xx_pwm.h
17
+++ b/hw/arm/xlnx-versal-virt.c
23
+++ b/include/hw/misc/npcm7xx_pwm.h
18
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxPWM {
19
#include "hw/arm/sysbus-fdt.h"
25
* @iomem: Memory region through which registers are accessed.
20
#include "hw/arm/fdt.h"
26
* @clock: The PWM clock.
21
#include "cpu.h"
27
* @pwm: The PWM channels owned by this module.
22
+#include "hw/qdev-properties.h"
28
+ * @duty_gpio_out: The duty cycle of each PWM channels as a output GPIO.
23
#include "hw/arm/xlnx-versal.h"
29
* @ppr: The prescaler register.
24
30
* @csr: The clock selector register.
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
31
* @pcr: The control register.
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
32
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxPWMState {
33
MemoryRegion iomem;
34
35
Clock *clock;
36
- NPCM7xxPWM pwm[NPCM7XX_PWM_PER_MODULE];
37
+ NPCM7xxPWM pwm[NPCM7XX_PWM_PER_MODULE];
38
+ qemu_irq duty_gpio_out[NPCM7XX_PWM_PER_MODULE];
39
40
uint32_t ppr;
41
uint32_t csr;
42
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/misc/npcm7xx_pwm.c
45
+++ b/hw/misc/npcm7xx_pwm.c
46
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_update_duty(NPCM7xxPWM *p)
47
trace_npcm7xx_pwm_update_duty(DEVICE(p->module)->canonical_path,
48
p->index, p->duty, duty);
49
p->duty = duty;
50
+ qemu_set_irq(p->module->duty_gpio_out[p->index], p->duty);
27
}
51
}
28
}
52
}
29
53
30
+static void fdt_add_sd_nodes(VersalVirt *s)
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_init(Object *obj)
31
+{
55
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
56
int i;
33
+ const char compat[] = "arasan,sdhci-8.9a";
57
34
+ int i;
58
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->pwm) != NPCM7XX_PWM_PER_MODULE);
35
+
59
for (i = 0; i < NPCM7XX_PWM_PER_MODULE; i++) {
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
60
NPCM7xxPWM *p = &s->pwm[i];
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
61
p->module = s;
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
62
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_init(Object *obj)
39
+
63
object_property_add_uint32_ptr(obj, "duty[*]",
40
+ qemu_fdt_add_subnode(s->fdt, name);
64
&s->pwm[i].duty, OBJ_PROP_FLAG_READ);
41
+
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
45
+ clocknames, sizeof(clocknames));
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
52
+ g_free(name);
53
+ }
54
+}
55
+
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
57
{
58
Error *err = NULL;
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
60
}
65
}
66
+ qdev_init_gpio_out_named(DEVICE(s), s->duty_gpio_out,
67
+ "duty-gpio-out", NPCM7XX_PWM_PER_MODULE);
61
}
68
}
62
69
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
70
static const VMStateDescription vmstate_npcm7xx_pwm = {
64
+{
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
66
+ DeviceState *card;
67
+
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
70
+ &error_fatal);
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
73
+}
74
+
75
static void versal_virt_init(MachineState *machine)
76
{
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
79
+ int i;
80
81
/*
82
* If the user provides an Operating System to be loaded, we expect them
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
84
fdt_add_gic_nodes(s);
85
fdt_add_timer_nodes(s);
86
fdt_add_zdma_nodes(s);
87
+ fdt_add_sd_nodes(s);
88
fdt_add_cpu_nodes(s, psci_conduit);
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
92
memory_region_add_subregion_overlap(get_system_memory(),
93
0, &s->soc.fpd.apu.mr, 0);
94
95
+ /* Plugin SD cards. */
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
98
+ }
99
+
100
s->binfo.ram_size = machine->ram_size;
101
s->binfo.loader_start = 0x0;
102
s->binfo.get_dtb = versal_virt_get_dtb;
103
--
71
--
104
2.20.1
72
2.20.1
105
73
106
74
diff view generated by jsdifflib
1
Add the infrastructure for building and invoking a decodetree decoder
1
From: Hao Wu <wuhaotsh@google.com>
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
nothing, so we always fall back to the existing hand-written decode.
4
2
5
We follow the same pattern we did for the VFP decodetree conversion
3
This patch implements Multi Function Timer (MFT) module for NPCM7XX.
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
4
This module is mainly used to configure PWM fans. It has just enough
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
5
functionality to make the PWM fan kernel module work.
8
which we #include into translate.c.
9
6
10
In order to share the decode files between A32 and T32, we
7
The module takes two input, the max_rpm of a fan (modifiable via QMP)
11
split Neon into 3 parts:
8
and duty cycle (a GPIO from the PWM module.) The actual measured RPM
12
* data-processing
9
is equal to max_rpm * duty_cycle / NPCM7XX_PWM_MAX_DUTY. The RPM is
13
* load-store
10
measured as a counter compared to a prescaled input clock. The kernel
14
* 'shared' encodings
11
driver reads this counter and report to user space.
15
12
16
The first two groups of instructions have similar but not identical
13
Refs:
17
A32 and T32 encodings, so we need to manually transform the T32
14
https://github.com/torvalds/linux/blob/master/drivers/hwmon/npcm750-pwm-fan.c
18
encoding into the A32 one before calling the decoder; the third group
19
covers the Neon instructions which are identical in A32 and T32.
20
15
16
Reviewed-by: Doug Evans <dje@google.com>
17
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
18
Signed-off-by: Hao Wu <wuhaotsh@google.com>
19
Message-id: 20210311180855.149764-3-wuhaotsh@google.com
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
24
---
22
---
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
23
include/hw/misc/npcm7xx_mft.h | 70 +++++
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
24
hw/misc/npcm7xx_mft.c | 540 ++++++++++++++++++++++++++++++++++
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
25
hw/misc/meson.build | 1 +
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
26
hw/misc/trace-events | 8 +
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
27
4 files changed, 619 insertions(+)
30
target/arm/Makefile.objs | 18 +++++++++++++++++
28
create mode 100644 include/hw/misc/npcm7xx_mft.h
31
6 files changed, 169 insertions(+), 2 deletions(-)
29
create mode 100644 hw/misc/npcm7xx_mft.c
32
create mode 100644 target/arm/neon-dp.decode
33
create mode 100644 target/arm/neon-ls.decode
34
create mode 100644 target/arm/neon-shared.decode
35
create mode 100644 target/arm/translate-neon.inc.c
36
30
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
31
diff --git a/include/hw/misc/npcm7xx_mft.h b/include/hw/misc/npcm7xx_mft.h
38
new file mode 100644
32
new file mode 100644
39
index XXXXXXX..XXXXXXX
33
index XXXXXXX..XXXXXXX
40
--- /dev/null
34
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
35
+++ b/include/hw/misc/npcm7xx_mft.h
42
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
37
+/*
44
+#
38
+ * Nuvoton NPCM7xx MFT Module
45
+# Copyright (c) 2020 Linaro, Ltd
39
+ *
46
+#
40
+ * Copyright 2021 Google LLC
47
+# This library is free software; you can redistribute it and/or
41
+ *
48
+# modify it under the terms of the GNU Lesser General Public
42
+ * This program is free software; you can redistribute it and/or modify it
49
+# License as published by the Free Software Foundation; either
43
+ * under the terms of the GNU General Public License as published by the
50
+# version 2 of the License, or (at your option) any later version.
44
+ * Free Software Foundation; either version 2 of the License, or
51
+#
45
+ * (at your option) any later version.
52
+# This library is distributed in the hope that it will be useful,
46
+ *
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
47
+ * This program is distributed in the hope that it will be useful, but WITHOUT
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
48
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
55
+# Lesser General Public License for more details.
49
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
56
+#
50
+ * for more details.
57
+# You should have received a copy of the GNU Lesser General Public
51
+ */
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
52
+#ifndef NPCM7XX_MFT_H
59
+
53
+#define NPCM7XX_MFT_H
60
+#
54
+
61
+# This file is processed by scripts/decodetree.py
55
+#include "exec/memory.h"
62
+#
56
+#include "hw/clock.h"
63
+
57
+#include "hw/irq.h"
64
+# Encodings for Neon data processing instructions where the T32 encoding
58
+#include "hw/sysbus.h"
65
+# is a simple transformation of the A32 encoding.
59
+#include "qom/object.h"
66
+# More specifically, this file covers instructions where the A32 encoding is
60
+
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
61
+/* Max Fan input number. */
68
+# and the T32 encoding is
62
+#define NPCM7XX_MFT_MAX_FAN_INPUT 19
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
63
+
70
+# This file works on the A32 encoding only; calling code for T32 has to
64
+/*
71
+# transform the insn into the A32 version first.
65
+ * Number of registers in one MFT module. Don't change this without increasing
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
66
+ * the version_id in vmstate.
67
+ */
68
+#define NPCM7XX_MFT_NR_REGS (0x20 / sizeof(uint16_t))
69
+
70
+/*
71
+ * The MFT can take up to 4 inputs: A0, B0, A1, B1. It can measure one A and one
72
+ * B simultaneously. NPCM7XX_MFT_INASEL and NPCM7XX_MFT_INBSEL are used to
73
+ * select which A or B input are used.
74
+ */
75
+#define NPCM7XX_MFT_FANIN_COUNT 4
76
+
77
+/**
78
+ * struct NPCM7xxMFTState - Multi Functional Tachometer device state.
79
+ * @parent: System bus device.
80
+ * @iomem: Memory region through which registers are accessed.
81
+ * @clock_in: The input clock for MFT from CLK module.
82
+ * @clock_{1,2}: The counter clocks for NPCM7XX_MFT_CNT{1,2}
83
+ * @irq: The IRQ for this MFT state.
84
+ * @regs: The MMIO registers.
85
+ * @max_rpm: The maximum rpm for fans. Order: A0, B0, A1, B1.
86
+ * @duty: The duty cycles for fans, relative to NPCM7XX_PWM_MAX_DUTY.
87
+ */
88
+typedef struct NPCM7xxMFTState {
89
+ SysBusDevice parent;
90
+
91
+ MemoryRegion iomem;
92
+
93
+ Clock *clock_in;
94
+ Clock *clock_1, *clock_2;
95
+ qemu_irq irq;
96
+ uint16_t regs[NPCM7XX_MFT_NR_REGS];
97
+
98
+ uint32_t max_rpm[NPCM7XX_MFT_FANIN_COUNT];
99
+ uint32_t duty[NPCM7XX_MFT_FANIN_COUNT];
100
+} NPCM7xxMFTState;
101
+
102
+#define TYPE_NPCM7XX_MFT "npcm7xx-mft"
103
+#define NPCM7XX_MFT(obj) \
104
+ OBJECT_CHECK(NPCM7xxMFTState, (obj), TYPE_NPCM7XX_MFT)
105
+
106
+#endif /* NPCM7XX_MFT_H */
107
diff --git a/hw/misc/npcm7xx_mft.c b/hw/misc/npcm7xx_mft.c
73
new file mode 100644
108
new file mode 100644
74
index XXXXXXX..XXXXXXX
109
index XXXXXXX..XXXXXXX
75
--- /dev/null
110
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
111
+++ b/hw/misc/npcm7xx_mft.c
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
112
@@ -XXX,XX +XXX,XX @@
146
+/*
113
+/*
147
+ * ARM translation: AArch32 Neon instructions
114
+ * Nuvoton NPCM7xx MFT Module
148
+ *
115
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
116
+ * Copyright 2021 Google LLC
150
+ * Copyright (c) 2005-2007 CodeSourcery
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
152
+ * Copyright (c) 2020 Linaro, Ltd.
153
+ *
117
+ *
154
+ * This library is free software; you can redistribute it and/or
118
+ * This program is free software; you can redistribute it and/or modify it
155
+ * modify it under the terms of the GNU Lesser General Public
119
+ * under the terms of the GNU General Public License as published by the
156
+ * License as published by the Free Software Foundation; either
120
+ * Free Software Foundation; either version 2 of the License, or
157
+ * version 2 of the License, or (at your option) any later version.
121
+ * (at your option) any later version.
158
+ *
122
+ *
159
+ * This library is distributed in the hope that it will be useful,
123
+ * This program is distributed in the hope that it will be useful, but WITHOUT
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
162
+ * Lesser General Public License for more details.
126
+ * for more details.
163
+ *
127
+ */
164
+ * You should have received a copy of the GNU Lesser General Public
128
+
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+#include "qemu/osdep.h"
166
+ */
130
+#include "hw/irq.h"
131
+#include "hw/qdev-clock.h"
132
+#include "hw/qdev-properties.h"
133
+#include "hw/misc/npcm7xx_mft.h"
134
+#include "hw/misc/npcm7xx_pwm.h"
135
+#include "hw/registerfields.h"
136
+#include "migration/vmstate.h"
137
+#include "qapi/error.h"
138
+#include "qapi/visitor.h"
139
+#include "qemu/bitops.h"
140
+#include "qemu/error-report.h"
141
+#include "qemu/log.h"
142
+#include "qemu/module.h"
143
+#include "qemu/timer.h"
144
+#include "qemu/units.h"
145
+#include "trace.h"
167
+
146
+
168
+/*
147
+/*
169
+ * This file is intended to be included from translate.c; it uses
148
+ * Some of the registers can only accessed via 16-bit ops and some can only
170
+ * some macros and definitions provided by that file.
149
+ * be accessed via 8-bit ops. However we mark all of them using REG16 to
171
+ * It might be possible to convert it to a standalone .c file eventually.
150
+ * simplify implementation. npcm7xx_mft_check_mem_op checks the access length
172
+ */
151
+ * of memory operations.
173
+
152
+ */
174
+/* Include the generated Neon decoder */
153
+REG16(NPCM7XX_MFT_CNT1, 0x00);
175
+#include "decode-neon-dp.inc.c"
154
+REG16(NPCM7XX_MFT_CRA, 0x02);
176
+#include "decode-neon-ls.inc.c"
155
+REG16(NPCM7XX_MFT_CRB, 0x04);
177
+#include "decode-neon-shared.inc.c"
156
+REG16(NPCM7XX_MFT_CNT2, 0x06);
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
157
+REG16(NPCM7XX_MFT_PRSC, 0x08);
158
+REG16(NPCM7XX_MFT_CKC, 0x0a);
159
+REG16(NPCM7XX_MFT_MCTRL, 0x0c);
160
+REG16(NPCM7XX_MFT_ICTRL, 0x0e);
161
+REG16(NPCM7XX_MFT_ICLR, 0x10);
162
+REG16(NPCM7XX_MFT_IEN, 0x12);
163
+REG16(NPCM7XX_MFT_CPA, 0x14);
164
+REG16(NPCM7XX_MFT_CPB, 0x16);
165
+REG16(NPCM7XX_MFT_CPCFG, 0x18);
166
+REG16(NPCM7XX_MFT_INASEL, 0x1a);
167
+REG16(NPCM7XX_MFT_INBSEL, 0x1c);
168
+
169
+/* Register Fields */
170
+#define NPCM7XX_MFT_CKC_C2CSEL BIT(3)
171
+#define NPCM7XX_MFT_CKC_C1CSEL BIT(0)
172
+
173
+#define NPCM7XX_MFT_MCTRL_TBEN BIT(6)
174
+#define NPCM7XX_MFT_MCTRL_TAEN BIT(5)
175
+#define NPCM7XX_MFT_MCTRL_TBEDG BIT(4)
176
+#define NPCM7XX_MFT_MCTRL_TAEDG BIT(3)
177
+#define NPCM7XX_MFT_MCTRL_MODE5 BIT(2)
178
+
179
+#define NPCM7XX_MFT_ICTRL_TFPND BIT(5)
180
+#define NPCM7XX_MFT_ICTRL_TEPND BIT(4)
181
+#define NPCM7XX_MFT_ICTRL_TDPND BIT(3)
182
+#define NPCM7XX_MFT_ICTRL_TCPND BIT(2)
183
+#define NPCM7XX_MFT_ICTRL_TBPND BIT(1)
184
+#define NPCM7XX_MFT_ICTRL_TAPND BIT(0)
185
+
186
+#define NPCM7XX_MFT_ICLR_TFCLR BIT(5)
187
+#define NPCM7XX_MFT_ICLR_TECLR BIT(4)
188
+#define NPCM7XX_MFT_ICLR_TDCLR BIT(3)
189
+#define NPCM7XX_MFT_ICLR_TCCLR BIT(2)
190
+#define NPCM7XX_MFT_ICLR_TBCLR BIT(1)
191
+#define NPCM7XX_MFT_ICLR_TACLR BIT(0)
192
+
193
+#define NPCM7XX_MFT_IEN_TFIEN BIT(5)
194
+#define NPCM7XX_MFT_IEN_TEIEN BIT(4)
195
+#define NPCM7XX_MFT_IEN_TDIEN BIT(3)
196
+#define NPCM7XX_MFT_IEN_TCIEN BIT(2)
197
+#define NPCM7XX_MFT_IEN_TBIEN BIT(1)
198
+#define NPCM7XX_MFT_IEN_TAIEN BIT(0)
199
+
200
+#define NPCM7XX_MFT_CPCFG_GET_B(rv) extract8((rv), 4, 4)
201
+#define NPCM7XX_MFT_CPCFG_GET_A(rv) extract8((rv), 0, 4)
202
+#define NPCM7XX_MFT_CPCFG_HIEN BIT(3)
203
+#define NPCM7XX_MFT_CPCFG_EQEN BIT(2)
204
+#define NPCM7XX_MFT_CPCFG_LOEN BIT(1)
205
+#define NPCM7XX_MFT_CPCFG_CPSEL BIT(0)
206
+
207
+#define NPCM7XX_MFT_INASEL_SELA BIT(0)
208
+#define NPCM7XX_MFT_INBSEL_SELB BIT(0)
209
+
210
+/* Max CNT values of the module. The CNT value is a countdown from it. */
211
+#define NPCM7XX_MFT_MAX_CNT 0xFFFF
212
+
213
+/* Each fan revolution should generated 2 pulses */
214
+#define NPCM7XX_MFT_PULSE_PER_REVOLUTION 2
215
+
216
+typedef enum NPCM7xxMFTCaptureState {
217
+ /* capture succeeded with a valid CNT value. */
218
+ NPCM7XX_CAPTURE_SUCCEED,
219
+ /* capture stopped prematurely due to reaching CPCFG condition. */
220
+ NPCM7XX_CAPTURE_COMPARE_HIT,
221
+ /* capture fails since it reaches underflow condition for CNT. */
222
+ NPCM7XX_CAPTURE_UNDERFLOW,
223
+} NPCM7xxMFTCaptureState;
224
+
225
+static void npcm7xx_mft_reset(NPCM7xxMFTState *s)
226
+{
227
+ int i;
228
+
229
+ /* Only registers PRSC ~ INBSEL need to be reset. */
230
+ for (i = R_NPCM7XX_MFT_PRSC; i <= R_NPCM7XX_MFT_INBSEL; ++i) {
231
+ s->regs[i] = 0;
232
+ }
233
+}
234
+
235
+static void npcm7xx_mft_clear_interrupt(NPCM7xxMFTState *s, uint8_t iclr)
236
+{
237
+ /*
238
+ * Clear bits in ICTRL where corresponding bits in iclr is 1.
239
+ * Both iclr and ictrl are 8-bit regs. (See npcm7xx_mft_check_mem_op)
240
+ */
241
+ s->regs[R_NPCM7XX_MFT_ICTRL] &= ~iclr;
242
+}
243
+
244
+/*
245
+ * If the CPCFG's condition should be triggered during count down from
246
+ * NPCM7XX_MFT_MAX_CNT to src if compared to tgt, return the count when
247
+ * the condition is triggered.
248
+ * Otherwise return -1.
249
+ * Since tgt is uint16_t it must always <= NPCM7XX_MFT_MAX_CNT.
250
+ */
251
+static int npcm7xx_mft_compare(int32_t src, uint16_t tgt, uint8_t cpcfg)
252
+{
253
+ if (cpcfg & NPCM7XX_MFT_CPCFG_HIEN) {
254
+ return NPCM7XX_MFT_MAX_CNT;
255
+ }
256
+ if ((cpcfg & NPCM7XX_MFT_CPCFG_EQEN) && (src <= tgt)) {
257
+ return tgt;
258
+ }
259
+ if ((cpcfg & NPCM7XX_MFT_CPCFG_LOEN) && (tgt > 0) && (src < tgt)) {
260
+ return tgt - 1;
261
+ }
262
+
263
+ return -1;
264
+}
265
+
266
+/* Compute CNT according to corresponding fan's RPM. */
267
+static NPCM7xxMFTCaptureState npcm7xx_mft_compute_cnt(
268
+ Clock *clock, uint32_t max_rpm, uint32_t duty, uint16_t tgt,
269
+ uint8_t cpcfg, uint16_t *cnt)
270
+{
271
+ uint32_t rpm = (uint64_t)max_rpm * (uint64_t)duty / NPCM7XX_PWM_MAX_DUTY;
272
+ int32_t count;
273
+ int stopped;
274
+ NPCM7xxMFTCaptureState state;
275
+
276
+ if (rpm == 0) {
277
+ /*
278
+ * If RPM = 0, capture won't happen. CNT will continue count down.
279
+ * So it's effective equivalent to have a cnt > NPCM7XX_MFT_MAX_CNT
280
+ */
281
+ count = NPCM7XX_MFT_MAX_CNT + 1;
282
+ } else {
283
+ /*
284
+ * RPM = revolution/min. The time for one revlution (in ns) is
285
+ * MINUTE_TO_NANOSECOND / RPM.
286
+ */
287
+ count = clock_ns_to_ticks(clock, (60 * NANOSECONDS_PER_SECOND) /
288
+ (rpm * NPCM7XX_MFT_PULSE_PER_REVOLUTION));
289
+ }
290
+
291
+ if (count > NPCM7XX_MFT_MAX_CNT) {
292
+ count = -1;
293
+ } else {
294
+ /* The CNT is a countdown value from NPCM7XX_MFT_MAX_CNT. */
295
+ count = NPCM7XX_MFT_MAX_CNT - count;
296
+ }
297
+ stopped = npcm7xx_mft_compare(count, tgt, cpcfg);
298
+ if (stopped == -1) {
299
+ if (count == -1) {
300
+ /* Underflow */
301
+ state = NPCM7XX_CAPTURE_UNDERFLOW;
302
+ } else {
303
+ state = NPCM7XX_CAPTURE_SUCCEED;
304
+ }
305
+ } else {
306
+ count = stopped;
307
+ state = NPCM7XX_CAPTURE_COMPARE_HIT;
308
+ }
309
+
310
+ if (count != -1) {
311
+ *cnt = count;
312
+ }
313
+ trace_npcm7xx_mft_rpm(clock->canonical_path, clock_get_hz(clock),
314
+ state, count, rpm, duty);
315
+ return state;
316
+}
317
+
318
+/*
319
+ * Capture Fan RPM and update CNT and CR registers accordingly.
320
+ * Raise IRQ if certain contidions are met in IEN.
321
+ */
322
+static void npcm7xx_mft_capture(NPCM7xxMFTState *s)
323
+{
324
+ int irq_level = 0;
325
+ NPCM7xxMFTCaptureState state;
326
+ int sel;
327
+ uint8_t cpcfg;
328
+
329
+ /*
330
+ * If not mode 5, the behavior is undefined. We just do nothing in this
331
+ * case.
332
+ */
333
+ if (!(s->regs[R_NPCM7XX_MFT_MCTRL] & NPCM7XX_MFT_MCTRL_MODE5)) {
334
+ return;
335
+ }
336
+
337
+ /* Capture input A. */
338
+ if (s->regs[R_NPCM7XX_MFT_MCTRL] & NPCM7XX_MFT_MCTRL_TAEN &&
339
+ s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C1CSEL) {
340
+ sel = s->regs[R_NPCM7XX_MFT_INASEL] & NPCM7XX_MFT_INASEL_SELA;
341
+ cpcfg = NPCM7XX_MFT_CPCFG_GET_A(s->regs[R_NPCM7XX_MFT_CPCFG]);
342
+ state = npcm7xx_mft_compute_cnt(s->clock_1,
343
+ sel ? s->max_rpm[2] : s->max_rpm[0],
344
+ sel ? s->duty[2] : s->duty[0],
345
+ s->regs[R_NPCM7XX_MFT_CPA],
346
+ cpcfg,
347
+ &s->regs[R_NPCM7XX_MFT_CNT1]);
348
+ switch (state) {
349
+ case NPCM7XX_CAPTURE_SUCCEED:
350
+ /* Interrupt on input capture on TAn transition - TAPND */
351
+ s->regs[R_NPCM7XX_MFT_CRA] = s->regs[R_NPCM7XX_MFT_CNT1];
352
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TAPND;
353
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TAIEN) {
354
+ irq_level = 1;
355
+ }
356
+ break;
357
+
358
+ case NPCM7XX_CAPTURE_COMPARE_HIT:
359
+ /* Compare Hit - TEPND */
360
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TEPND;
361
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TEIEN) {
362
+ irq_level = 1;
363
+ }
364
+ break;
365
+
366
+ case NPCM7XX_CAPTURE_UNDERFLOW:
367
+ /* Underflow - TCPND */
368
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TCPND;
369
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TCIEN) {
370
+ irq_level = 1;
371
+ }
372
+ break;
373
+
374
+ default:
375
+ g_assert_not_reached();
376
+ }
377
+ }
378
+
379
+ /* Capture input B. */
380
+ if (s->regs[R_NPCM7XX_MFT_MCTRL] & NPCM7XX_MFT_MCTRL_TBEN &&
381
+ s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C2CSEL) {
382
+ sel = s->regs[R_NPCM7XX_MFT_INBSEL] & NPCM7XX_MFT_INBSEL_SELB;
383
+ cpcfg = NPCM7XX_MFT_CPCFG_GET_B(s->regs[R_NPCM7XX_MFT_CPCFG]);
384
+ state = npcm7xx_mft_compute_cnt(s->clock_2,
385
+ sel ? s->max_rpm[3] : s->max_rpm[1],
386
+ sel ? s->duty[3] : s->duty[1],
387
+ s->regs[R_NPCM7XX_MFT_CPB],
388
+ cpcfg,
389
+ &s->regs[R_NPCM7XX_MFT_CNT2]);
390
+ switch (state) {
391
+ case NPCM7XX_CAPTURE_SUCCEED:
392
+ /* Interrupt on input capture on TBn transition - TBPND */
393
+ s->regs[R_NPCM7XX_MFT_CRB] = s->regs[R_NPCM7XX_MFT_CNT2];
394
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TBPND;
395
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TBIEN) {
396
+ irq_level = 1;
397
+ }
398
+ break;
399
+
400
+ case NPCM7XX_CAPTURE_COMPARE_HIT:
401
+ /* Compare Hit - TFPND */
402
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TFPND;
403
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TFIEN) {
404
+ irq_level = 1;
405
+ }
406
+ break;
407
+
408
+ case NPCM7XX_CAPTURE_UNDERFLOW:
409
+ /* Underflow - TDPND */
410
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TDPND;
411
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TDIEN) {
412
+ irq_level = 1;
413
+ }
414
+ break;
415
+
416
+ default:
417
+ g_assert_not_reached();
418
+ }
419
+ }
420
+
421
+ trace_npcm7xx_mft_capture(DEVICE(s)->canonical_path, irq_level);
422
+ qemu_set_irq(s->irq, irq_level);
423
+}
424
+
425
+/* Update clock for counters. */
426
+static void npcm7xx_mft_update_clock(void *opaque, ClockEvent event)
427
+{
428
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
429
+ uint64_t prescaled_clock_period;
430
+
431
+ prescaled_clock_period = clock_get(s->clock_in) *
432
+ (s->regs[R_NPCM7XX_MFT_PRSC] + 1ULL);
433
+ trace_npcm7xx_mft_update_clock(s->clock_in->canonical_path,
434
+ s->regs[R_NPCM7XX_MFT_CKC],
435
+ clock_get(s->clock_in),
436
+ prescaled_clock_period);
437
+ /* Update clock 1 */
438
+ if (s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C1CSEL) {
439
+ /* Clock is prescaled. */
440
+ clock_update(s->clock_1, prescaled_clock_period);
441
+ } else {
442
+ /* Clock stopped. */
443
+ clock_update(s->clock_1, 0);
444
+ }
445
+ /* Update clock 2 */
446
+ if (s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C2CSEL) {
447
+ /* Clock is prescaled. */
448
+ clock_update(s->clock_2, prescaled_clock_period);
449
+ } else {
450
+ /* Clock stopped. */
451
+ clock_update(s->clock_2, 0);
452
+ }
453
+
454
+ npcm7xx_mft_capture(s);
455
+}
456
+
457
+static uint64_t npcm7xx_mft_read(void *opaque, hwaddr offset, unsigned size)
458
+{
459
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
460
+ uint16_t value = 0;
461
+
462
+ switch (offset) {
463
+ case A_NPCM7XX_MFT_ICLR:
464
+ qemu_log_mask(LOG_GUEST_ERROR,
465
+ "%s: register @ 0x%04" HWADDR_PRIx " is write-only\n",
466
+ __func__, offset);
467
+ break;
468
+
469
+ default:
470
+ value = s->regs[offset / 2];
471
+ }
472
+
473
+ trace_npcm7xx_mft_read(DEVICE(s)->canonical_path, offset, value);
474
+ return value;
475
+}
476
+
477
+static void npcm7xx_mft_write(void *opaque, hwaddr offset,
478
+ uint64_t v, unsigned size)
479
+{
480
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
481
+
482
+ trace_npcm7xx_mft_write(DEVICE(s)->canonical_path, offset, v);
483
+ switch (offset) {
484
+ case A_NPCM7XX_MFT_ICLR:
485
+ npcm7xx_mft_clear_interrupt(s, v);
486
+ break;
487
+
488
+ case A_NPCM7XX_MFT_CKC:
489
+ case A_NPCM7XX_MFT_PRSC:
490
+ s->regs[offset / 2] = v;
491
+ npcm7xx_mft_update_clock(s, ClockUpdate);
492
+ break;
493
+
494
+ default:
495
+ s->regs[offset / 2] = v;
496
+ npcm7xx_mft_capture(s);
497
+ break;
498
+ }
499
+}
500
+
501
+static bool npcm7xx_mft_check_mem_op(void *opaque, hwaddr offset,
502
+ unsigned size, bool is_write,
503
+ MemTxAttrs attrs)
504
+{
505
+ switch (offset) {
506
+ /* 16-bit registers. Must be accessed with 16-bit read/write.*/
507
+ case A_NPCM7XX_MFT_CNT1:
508
+ case A_NPCM7XX_MFT_CRA:
509
+ case A_NPCM7XX_MFT_CRB:
510
+ case A_NPCM7XX_MFT_CNT2:
511
+ case A_NPCM7XX_MFT_CPA:
512
+ case A_NPCM7XX_MFT_CPB:
513
+ return size == 2;
514
+
515
+ /* 8-bit registers. Must be accessed with 8-bit read/write.*/
516
+ case A_NPCM7XX_MFT_PRSC:
517
+ case A_NPCM7XX_MFT_CKC:
518
+ case A_NPCM7XX_MFT_MCTRL:
519
+ case A_NPCM7XX_MFT_ICTRL:
520
+ case A_NPCM7XX_MFT_ICLR:
521
+ case A_NPCM7XX_MFT_IEN:
522
+ case A_NPCM7XX_MFT_CPCFG:
523
+ case A_NPCM7XX_MFT_INASEL:
524
+ case A_NPCM7XX_MFT_INBSEL:
525
+ return size == 1;
526
+
527
+ default:
528
+ /* Invalid registers. */
529
+ return false;
530
+ }
531
+}
532
+
533
+static void npcm7xx_mft_get_max_rpm(Object *obj, Visitor *v, const char *name,
534
+ void *opaque, Error **errp)
535
+{
536
+ visit_type_uint32(v, name, (uint32_t *)opaque, errp);
537
+}
538
+
539
+static void npcm7xx_mft_set_max_rpm(Object *obj, Visitor *v, const char *name,
540
+ void *opaque, Error **errp)
541
+{
542
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
543
+ uint32_t *max_rpm = opaque;
544
+ uint32_t value;
545
+
546
+ if (!visit_type_uint32(v, name, &value, errp)) {
547
+ return;
548
+ }
549
+
550
+ *max_rpm = value;
551
+ npcm7xx_mft_capture(s);
552
+}
553
+
554
+static void npcm7xx_mft_duty_handler(void *opaque, int n, int value)
555
+{
556
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
557
+
558
+ trace_npcm7xx_mft_set_duty(DEVICE(s)->canonical_path, n, value);
559
+ s->duty[n] = value;
560
+ npcm7xx_mft_capture(s);
561
+}
562
+
563
+static const struct MemoryRegionOps npcm7xx_mft_ops = {
564
+ .read = npcm7xx_mft_read,
565
+ .write = npcm7xx_mft_write,
566
+ .endianness = DEVICE_LITTLE_ENDIAN,
567
+ .valid = {
568
+ .min_access_size = 1,
569
+ .max_access_size = 2,
570
+ .unaligned = false,
571
+ .accepts = npcm7xx_mft_check_mem_op,
572
+ },
573
+};
574
+
575
+static void npcm7xx_mft_enter_reset(Object *obj, ResetType type)
576
+{
577
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
578
+
579
+ npcm7xx_mft_reset(s);
580
+}
581
+
582
+static void npcm7xx_mft_hold_reset(Object *obj)
583
+{
584
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
585
+
586
+ qemu_irq_lower(s->irq);
587
+}
588
+
589
+static void npcm7xx_mft_init(Object *obj)
590
+{
591
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
592
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
593
+ DeviceState *dev = DEVICE(obj);
594
+
595
+ memory_region_init_io(&s->iomem, obj, &npcm7xx_mft_ops, s,
596
+ TYPE_NPCM7XX_MFT, 4 * KiB);
597
+ sysbus_init_mmio(sbd, &s->iomem);
598
+ sysbus_init_irq(sbd, &s->irq);
599
+ s->clock_in = qdev_init_clock_in(dev, "clock-in", npcm7xx_mft_update_clock,
600
+ s, ClockUpdate);
601
+ s->clock_1 = qdev_init_clock_out(dev, "clock1");
602
+ s->clock_2 = qdev_init_clock_out(dev, "clock2");
603
+
604
+ for (int i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) {
605
+ object_property_add(obj, "max_rpm[*]", "uint32",
606
+ npcm7xx_mft_get_max_rpm,
607
+ npcm7xx_mft_set_max_rpm,
608
+ NULL, &s->max_rpm[i]);
609
+ }
610
+ qdev_init_gpio_in_named(dev, npcm7xx_mft_duty_handler, "duty",
611
+ NPCM7XX_MFT_FANIN_COUNT);
612
+}
613
+
614
+static const VMStateDescription vmstate_npcm7xx_mft = {
615
+ .name = "npcm7xx-mft-module",
616
+ .version_id = 0,
617
+ .minimum_version_id = 0,
618
+ .fields = (VMStateField[]) {
619
+ VMSTATE_CLOCK(clock_in, NPCM7xxMFTState),
620
+ VMSTATE_CLOCK(clock_1, NPCM7xxMFTState),
621
+ VMSTATE_CLOCK(clock_2, NPCM7xxMFTState),
622
+ VMSTATE_UINT16_ARRAY(regs, NPCM7xxMFTState, NPCM7XX_MFT_NR_REGS),
623
+ VMSTATE_UINT32_ARRAY(max_rpm, NPCM7xxMFTState, NPCM7XX_MFT_FANIN_COUNT),
624
+ VMSTATE_UINT32_ARRAY(duty, NPCM7xxMFTState, NPCM7XX_MFT_FANIN_COUNT),
625
+ VMSTATE_END_OF_LIST(),
626
+ },
627
+};
628
+
629
+static void npcm7xx_mft_class_init(ObjectClass *klass, void *data)
630
+{
631
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
632
+ DeviceClass *dc = DEVICE_CLASS(klass);
633
+
634
+ dc->desc = "NPCM7xx MFT Controller";
635
+ dc->vmsd = &vmstate_npcm7xx_mft;
636
+ rc->phases.enter = npcm7xx_mft_enter_reset;
637
+ rc->phases.hold = npcm7xx_mft_hold_reset;
638
+}
639
+
640
+static const TypeInfo npcm7xx_mft_info = {
641
+ .name = TYPE_NPCM7XX_MFT,
642
+ .parent = TYPE_SYS_BUS_DEVICE,
643
+ .instance_size = sizeof(NPCM7xxMFTState),
644
+ .class_init = npcm7xx_mft_class_init,
645
+ .instance_init = npcm7xx_mft_init,
646
+};
647
+
648
+static void npcm7xx_mft_register_type(void)
649
+{
650
+ type_register_static(&npcm7xx_mft_info);
651
+}
652
+type_init(npcm7xx_mft_register_type);
653
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
179
index XXXXXXX..XXXXXXX 100644
654
index XXXXXXX..XXXXXXX 100644
180
--- a/target/arm/translate.c
655
--- a/hw/misc/meson.build
181
+++ b/target/arm/translate.c
656
+++ b/hw/misc/meson.build
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
657
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c'))
183
658
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
184
#define ARM_CP_RW_BIT (1 << 20)
659
'npcm7xx_clk.c',
185
660
'npcm7xx_gcr.c',
186
-/* Include the VFP decoder */
661
+ 'npcm7xx_mft.c',
187
+/* Include the VFP and Neon decoders */
662
'npcm7xx_pwm.c',
188
#include "translate-vfp.inc.c"
663
'npcm7xx_rng.c',
189
+#include "translate-neon.inc.c"
664
))
190
665
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
192
{
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
194
/* Unconditional instructions. */
195
/* TODO: Perhaps merge these into one decodetree output file. */
196
if (disas_a32_uncond(s, insn) ||
197
- disas_vfp_uncond(s, insn)) {
198
+ disas_vfp_uncond(s, insn) ||
199
+ disas_neon_dp(s, insn) ||
200
+ disas_neon_ls(s, insn) ||
201
+ disas_neon_shared(s, insn)) {
202
return;
203
}
204
/* fall back to legacy decoder */
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
206
ARCH(6T2);
207
}
208
209
+ if ((insn & 0xef000000) == 0xef000000) {
210
+ /*
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
212
+ * transform into
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
214
+ */
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
217
+
218
+ if (disas_neon_dp(s, a32_insn)) {
219
+ return;
220
+ }
221
+ }
222
+
223
+ if ((insn & 0xff100000) == 0xf9000000) {
224
+ /*
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
226
+ * transform into
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
228
+ */
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
230
+
231
+ if (disas_neon_ls(s, a32_insn)) {
232
+ return;
233
+ }
234
+ }
235
+
236
/*
237
* TODO: Perhaps merge these into one decodetree output file.
238
* Note disas_vfp is written for a32 with cond field in the
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
240
*/
241
if (disas_t32(s, insn) ||
242
disas_vfp_uncond(s, insn) ||
243
+ disas_neon_shared(s, insn) ||
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
245
return;
246
}
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
248
index XXXXXXX..XXXXXXX 100644
666
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/Makefile.objs
667
--- a/hw/misc/trace-events
250
+++ b/target/arm/Makefile.objs
668
+++ b/hw/misc/trace-events
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
669
@@ -XXX,XX +XXX,XX @@ npcm7xx_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " valu
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
670
npcm7xx_gcr_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
253
     "GEN", $(TARGET_DIR)$@)
671
npcm7xx_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
254
672
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
673
+# npcm7xx_mft.c
256
+    $(call quiet-command,\
674
+npcm7xx_mft_read(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
675
+npcm7xx_mft_write(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
258
+     "GEN", $(TARGET_DIR)$@)
676
+npcm7xx_mft_rpm(const char *clock, uint32_t clock_hz, int state, int32_t cnt, uint32_t rpm, uint32_t duty) " fan clk: %s clock_hz: %" PRIu32 ", state: %d, cnt: %" PRIi32 ", rpm: %" PRIu32 ", duty: %" PRIu32
259
+
677
+npcm7xx_mft_capture(const char *name, int irq_level) "%s: level: %d"
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
678
+npcm7xx_mft_update_clock(const char *name, uint16_t sel, uint64_t clock_period, uint64_t prescaled_clock_period) "%s: sel: 0x%02" PRIx16 ", period: %" PRIu64 ", prescaled: %" PRIu64
261
+    $(call quiet-command,\
679
+npcm7xx_mft_set_duty(const char *name, int n, int value) "%s[%d]: %d"
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
680
+
263
+     "GEN", $(TARGET_DIR)$@)
681
# npcm7xx_rng.c
264
+
682
npcm7xx_rng_read(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
683
npcm7xx_rng_write(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
266
+    $(call quiet-command,\
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
268
+     "GEN", $(TARGET_DIR)$@)
269
+
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
271
    $(call quiet-command,\
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
274
     "GEN", $(TARGET_DIR)$@)
275
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
282
target/arm/translate.o: target/arm/decode-a32.inc.c
283
--
684
--
284
2.20.1
685
2.20.1
285
686
286
687
diff view generated by jsdifflib
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
1
From: Hao Wu <wuhaotsh@google.com>
2
to decodetree.
3
2
3
This patch adds the recently implemented MFT device to the NPCM7XX
4
SoC file.
5
6
Reviewed-by: Doug Evans <dje@google.com>
7
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
8
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
Message-id: 20210311180855.149764-4-wuhaotsh@google.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
7
---
12
---
8
target/arm/neon-shared.decode | 3 +++
13
docs/system/arm/nuvoton.rst | 2 +-
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
14
include/hw/arm/npcm7xx.h | 2 ++
10
target/arm/translate.c | 13 +-----------
15
hw/arm/npcm7xx.c | 45 ++++++++++++++++++++++++++++++-------
11
3 files changed, 39 insertions(+), 12 deletions(-)
16
3 files changed, 40 insertions(+), 9 deletions(-)
12
17
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
18
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
20
--- a/docs/system/arm/nuvoton.rst
16
+++ b/target/arm/neon-shared.decode
21
+++ b/docs/system/arm/nuvoton.rst
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
22
@@ -XXX,XX +XXX,XX @@ Supported devices
18
vn=%vn_dp vd=%vd_dp size=0
23
* Pulse Width Modulation (PWM)
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
24
* SMBus controller (SMBF)
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
25
* Ethernet controller (EMC)
26
+ * Tachometer
27
28
Missing devices
29
---------------
30
@@ -XXX,XX +XXX,XX @@ Missing devices
31
* Peripheral SPI controller (PSPI)
32
* SD/MMC host
33
* PECI interface
34
- * Tachometer
35
* PCI and PCIe root complex and bridges
36
* VDM and MCTP support
37
* Serial I/O expansion
38
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/hw/arm/npcm7xx.h
41
+++ b/include/hw/arm/npcm7xx.h
42
@@ -XXX,XX +XXX,XX @@
43
#include "hw/mem/npcm7xx_mc.h"
44
#include "hw/misc/npcm7xx_clk.h"
45
#include "hw/misc/npcm7xx_gcr.h"
46
+#include "hw/misc/npcm7xx_mft.h"
47
#include "hw/misc/npcm7xx_pwm.h"
48
#include "hw/misc/npcm7xx_rng.h"
49
#include "hw/net/npcm7xx_emc.h"
50
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
51
NPCM7xxTimerCtrlState tim[3];
52
NPCM7xxADCState adc;
53
NPCM7xxPWMState pwm[2];
54
+ NPCM7xxMFTState mft[8];
55
NPCM7xxOTPState key_storage;
56
NPCM7xxOTPState fuse_array;
57
NPCM7xxMCState mc;
58
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/npcm7xx.c
61
+++ b/hw/arm/npcm7xx.c
62
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
63
NPCM7XX_SMBUS15_IRQ,
64
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
65
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
66
+ NPCM7XX_MFT0_IRQ = 96, /* MFT module 0 */
67
+ NPCM7XX_MFT1_IRQ, /* MFT module 1 */
68
+ NPCM7XX_MFT2_IRQ, /* MFT module 2 */
69
+ NPCM7XX_MFT3_IRQ, /* MFT module 3 */
70
+ NPCM7XX_MFT4_IRQ, /* MFT module 4 */
71
+ NPCM7XX_MFT5_IRQ, /* MFT module 5 */
72
+ NPCM7XX_MFT6_IRQ, /* MFT module 6 */
73
+ NPCM7XX_MFT7_IRQ, /* MFT module 7 */
74
NPCM7XX_EMC2RX_IRQ = 114,
75
NPCM7XX_EMC2TX_IRQ,
76
NPCM7XX_GPIO0_IRQ = 116,
77
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_pwm_addr[] = {
78
0xf0104000,
79
};
80
81
+/* Register base address for each MFT Module */
82
+static const hwaddr npcm7xx_mft_addr[] = {
83
+ 0xf0180000,
84
+ 0xf0181000,
85
+ 0xf0182000,
86
+ 0xf0183000,
87
+ 0xf0184000,
88
+ 0xf0185000,
89
+ 0xf0186000,
90
+ 0xf0187000,
91
+};
21
+
92
+
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
93
/* Direct memory-mapped access to each SMBus Module. */
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
94
static const hwaddr npcm7xx_smbus_addr[] = {
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
95
0xf0080000,
25
index XXXXXXX..XXXXXXX 100644
96
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
26
--- a/target/arm/translate-neon.inc.c
97
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
27
+++ b/target/arm/translate-neon.inc.c
98
}
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
99
29
tcg_temp_free_ptr(fpst);
100
+ for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
30
return true;
101
+ object_initialize_child(obj, "mft[*]", &s->mft[i], TYPE_NPCM7XX_MFT);
31
}
32
+
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
34
+{
35
+ gen_helper_gvec_3 *fn_gvec;
36
+ int opr_sz;
37
+ TCGv_ptr fpst;
38
+
39
+ if (!dc_isar_feature(aa32_dp, s)) {
40
+ return false;
41
+ }
102
+ }
42
+
103
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
104
for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
105
object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
45
+ ((a->vd | a->vn) & 0x10)) {
106
}
46
+ return false;
107
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
108
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
109
}
110
111
+ /* MFT Modules. Cannot fail. */
112
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_mft_addr) != ARRAY_SIZE(s->mft));
113
+ for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
114
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->mft[i]);
115
+
116
+ qdev_connect_clock_in(DEVICE(&s->mft[i]), "clock-in",
117
+ qdev_get_clock_out(DEVICE(&s->clk),
118
+ "apb4-clock"));
119
+ sysbus_realize(sbd, &error_abort);
120
+ sysbus_mmio_map(sbd, 0, npcm7xx_mft_addr[i]);
121
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, NPCM7XX_MFT0_IRQ + i));
47
+ }
122
+ }
48
+
123
+
49
+ if ((a->vd | a->vn) & a->q) {
124
/*
50
+ return false;
125
* EMC Modules. Cannot fail.
51
+ }
126
* The mapping of the device to its netdev backend works as follows:
52
+
127
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
53
+ if (!vfp_access_check(s)) {
128
create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
54
+ return true;
129
create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
55
+ }
130
create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
56
+
131
- create_unimplemented_device("npcm7xx.mft[0]", 0xf0180000, 4 * KiB);
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
132
- create_unimplemented_device("npcm7xx.mft[1]", 0xf0181000, 4 * KiB);
58
+ opr_sz = (1 + a->q) * 8;
133
- create_unimplemented_device("npcm7xx.mft[2]", 0xf0182000, 4 * KiB);
59
+ fpst = get_fpstatus_ptr(1);
134
- create_unimplemented_device("npcm7xx.mft[3]", 0xf0183000, 4 * KiB);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
135
- create_unimplemented_device("npcm7xx.mft[4]", 0xf0184000, 4 * KiB);
61
+ vfp_reg_offset(1, a->vn),
136
- create_unimplemented_device("npcm7xx.mft[5]", 0xf0185000, 4 * KiB);
62
+ vfp_reg_offset(1, a->rm),
137
- create_unimplemented_device("npcm7xx.mft[6]", 0xf0186000, 4 * KiB);
63
+ opr_sz, opr_sz, a->index, fn_gvec);
138
- create_unimplemented_device("npcm7xx.mft[7]", 0xf0187000, 4 * KiB);
64
+ tcg_temp_free_ptr(fpst);
139
create_unimplemented_device("npcm7xx.pspi1", 0xf0200000, 4 * KiB);
65
+ return true;
140
create_unimplemented_device("npcm7xx.pspi2", 0xf0201000, 4 * KiB);
66
+}
141
create_unimplemented_device("npcm7xx.ahbpci", 0xf0400000, 1 * MiB);
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/translate.c
70
+++ b/target/arm/translate.c
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
72
bool is_long = false, q = extract32(insn, 6, 1);
73
bool ptr_is_env = false;
74
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
77
- int u = extract32(insn, 4, 1);
78
-
79
- if (!dc_isar_feature(aa32_dp, s)) {
80
- return 1;
81
- }
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
83
- /* rm is just Vm, and index is M. */
84
- data = extract32(insn, 5, 1); /* index */
85
- rm = extract32(insn, 0, 4);
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
91
--
142
--
92
2.20.1
143
2.20.1
93
144
94
145
diff view generated by jsdifflib
1
Convert the VCADD (vector) insns to decodetree.
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
This patch adds fan_splitters (split IRQs) in NPCM7XX boards. Each fan
4
splitter corresponds to 1 PWM output and can connect to multiple fan
5
inputs (MFT devices).
6
In NPCM7XX boards(NPCM750 EVB and Quanta GSJ boards), we initializes
7
these splitters and connect them to their corresponding modules
8
according their specific device trees.
9
10
Reviewed-by: Doug Evans <dje@google.com>
11
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
12
Signed-off-by: Hao Wu <wuhaotsh@google.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20210311180855.149764-5-wuhaotsh@google.com
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
6
---
16
---
7
target/arm/neon-shared.decode | 3 +++
17
include/hw/arm/npcm7xx.h | 11 ++++-
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
18
hw/arm/npcm7xx_boards.c | 99 ++++++++++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 11 +---------
19
2 files changed, 109 insertions(+), 1 deletion(-)
10
3 files changed, 41 insertions(+), 10 deletions(-)
20
11
21
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
23
--- a/include/hw/arm/npcm7xx.h
15
+++ b/target/arm/neon-shared.decode
24
+++ b/include/hw/arm/npcm7xx.h
16
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
17
26
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
27
#include "hw/boards.h"
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
28
#include "hw/adc/npcm7xx_adc.h"
20
+
29
+#include "hw/core/split-irq.h"
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
30
#include "hw/cpu/a9mpcore.h"
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
31
#include "hw/gpio/npcm7xx_gpio.h"
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
32
#include "hw/i2c/npcm7xx_smbus.h"
33
@@ -XXX,XX +XXX,XX @@
34
#define NPCM7XX_GIC_CPU_IF_ADDR (0xf03fe100) /* GIC within A9 */
35
#define NPCM7XX_BOARD_SETUP_ADDR (0xffff1000) /* Boot ROM */
36
37
+#define NPCM7XX_NR_PWM_MODULES 2
38
+
39
typedef struct NPCM7xxMachine {
40
MachineState parent;
41
+ /*
42
+ * PWM fan splitter. each splitter connects to one PWM output and
43
+ * multiple MFT inputs.
44
+ */
45
+ SplitIRQ fan_splitter[NPCM7XX_NR_PWM_MODULES *
46
+ NPCM7XX_PWM_PER_MODULE];
47
} NPCM7xxMachine;
48
49
#define TYPE_NPCM7XX_MACHINE MACHINE_TYPE_NAME("npcm7xx")
50
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
51
NPCM7xxCLKState clk;
52
NPCM7xxTimerCtrlState tim[3];
53
NPCM7xxADCState adc;
54
- NPCM7xxPWMState pwm[2];
55
+ NPCM7xxPWMState pwm[NPCM7XX_NR_PWM_MODULES];
56
NPCM7xxMFTState mft[8];
57
NPCM7xxOTPState key_storage;
58
NPCM7xxOTPState fuse_array;
59
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
24
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-neon.inc.c
61
--- a/hw/arm/npcm7xx_boards.c
26
+++ b/target/arm/translate-neon.inc.c
62
+++ b/hw/arm/npcm7xx_boards.c
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
63
@@ -XXX,XX +XXX,XX @@
28
tcg_temp_free_ptr(fpst);
64
#include "hw/core/cpu.h"
29
return true;
65
#include "hw/i2c/smbus_eeprom.h"
30
}
66
#include "hw/loader.h"
31
+
67
+#include "hw/qdev-core.h"
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
68
#include "hw/qdev-properties.h"
33
+{
69
#include "qapi/error.h"
34
+ int opr_sz;
70
#include "qemu-common.h"
35
+ TCGv_ptr fpst;
71
@@ -XXX,XX +XXX,XX @@ static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
72
i2c_slave_realize_and_unref(i2c_dev, i2c_bus, &error_abort);
37
+
73
}
38
+ if (!dc_isar_feature(aa32_vcma, s)
74
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
75
+static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
40
+ return false;
76
+ NPCM7xxState *soc, const int *fan_counts)
77
+{
78
+ SplitIRQ *splitters = machine->fan_splitter;
79
+
80
+ /*
81
+ * PWM 0~3 belong to module 0 output 0~3.
82
+ * PWM 4~7 belong to module 1 output 0~3.
83
+ */
84
+ for (int i = 0; i < NPCM7XX_NR_PWM_MODULES; ++i) {
85
+ for (int j = 0; j < NPCM7XX_PWM_PER_MODULE; ++j) {
86
+ int splitter_no = i * NPCM7XX_PWM_PER_MODULE + j;
87
+ DeviceState *splitter;
88
+
89
+ if (fan_counts[splitter_no] < 1) {
90
+ continue;
91
+ }
92
+ object_initialize_child(OBJECT(machine), "fan-splitter[*]",
93
+ &splitters[splitter_no], TYPE_SPLIT_IRQ);
94
+ splitter = DEVICE(&splitters[splitter_no]);
95
+ qdev_prop_set_uint16(splitter, "num-lines",
96
+ fan_counts[splitter_no]);
97
+ qdev_realize(splitter, NULL, &error_abort);
98
+ qdev_connect_gpio_out_named(DEVICE(&soc->pwm[i]), "duty-gpio-out",
99
+ j, qdev_get_gpio_in(splitter, 0));
100
+ }
41
+ }
101
+ }
42
+
102
+}
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
103
+
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
104
+static void npcm7xx_connect_pwm_fan(NPCM7xxState *soc, SplitIRQ *splitter,
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
105
+ int fan_no, int output_no)
46
+ return false;
106
+{
107
+ DeviceState *fan;
108
+ int fan_input;
109
+ qemu_irq fan_duty_gpio;
110
+
111
+ g_assert(fan_no >= 0 && fan_no <= NPCM7XX_MFT_MAX_FAN_INPUT);
112
+ /*
113
+ * Fan 0~1 belong to module 0 input 0~1.
114
+ * Fan 2~3 belong to module 1 input 0~1.
115
+ * ...
116
+ * Fan 14~15 belong to module 7 input 0~1.
117
+ * Fan 16~17 belong to module 0 input 2~3.
118
+ * Fan 18~19 belong to module 1 input 2~3.
119
+ */
120
+ if (fan_no < 16) {
121
+ fan = DEVICE(&soc->mft[fan_no / 2]);
122
+ fan_input = fan_no % 2;
123
+ } else {
124
+ fan = DEVICE(&soc->mft[(fan_no - 16) / 2]);
125
+ fan_input = fan_no % 2 + 2;
47
+ }
126
+ }
48
+
127
+
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
128
+ /* Connect the Fan to PWM module */
50
+ return false;
129
+ fan_duty_gpio = qdev_get_gpio_in_named(fan, "duty", fan_input);
51
+ }
130
+ qdev_connect_gpio_out(DEVICE(splitter), output_no, fan_duty_gpio);
52
+
131
+}
53
+ if (!vfp_access_check(s)) {
132
+
54
+ return true;
133
static void npcm750_evb_i2c_init(NPCM7xxState *soc)
55
+ }
134
{
56
+
135
/* lm75 temperature sensor on SVB, tmp105 is compatible */
57
+ opr_sz = (1 + a->q) * 8;
136
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_i2c_init(NPCM7xxState *soc)
58
+ fpst = get_fpstatus_ptr(1);
137
i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
138
}
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
139
61
+ vfp_reg_offset(1, a->vn),
140
+static void npcm750_evb_fan_init(NPCM7xxMachine *machine, NPCM7xxState *soc)
62
+ vfp_reg_offset(1, a->vm),
141
+{
63
+ fpst, opr_sz, opr_sz, a->rot,
142
+ SplitIRQ *splitter = machine->fan_splitter;
64
+ fn_gvec_ptr);
143
+ static const int fan_counts[] = {2, 2, 2, 2, 2, 2, 2, 2};
65
+ tcg_temp_free_ptr(fpst);
144
+
66
+ return true;
145
+ npcm7xx_init_pwm_splitter(machine, soc, fan_counts);
67
+}
146
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x00, 0);
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
147
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x01, 1);
69
index XXXXXXX..XXXXXXX 100644
148
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x02, 0);
70
--- a/target/arm/translate.c
149
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x03, 1);
71
+++ b/target/arm/translate.c
150
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x04, 0);
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
151
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x05, 1);
73
bool is_long = false, q = extract32(insn, 6, 1);
152
+ npcm7xx_connect_pwm_fan(soc, &splitter[3], 0x06, 0);
74
bool ptr_is_env = false;
153
+ npcm7xx_connect_pwm_fan(soc, &splitter[3], 0x07, 1);
75
154
+ npcm7xx_connect_pwm_fan(soc, &splitter[4], 0x08, 0);
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
155
+ npcm7xx_connect_pwm_fan(soc, &splitter[4], 0x09, 1);
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
156
+ npcm7xx_connect_pwm_fan(soc, &splitter[5], 0x0a, 0);
78
- int size = extract32(insn, 20, 1);
157
+ npcm7xx_connect_pwm_fan(soc, &splitter[5], 0x0b, 1);
79
- data = extract32(insn, 24, 1); /* rot */
158
+ npcm7xx_connect_pwm_fan(soc, &splitter[6], 0x0c, 0);
80
- if (!dc_isar_feature(aa32_vcma, s)
159
+ npcm7xx_connect_pwm_fan(soc, &splitter[6], 0x0d, 1);
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
160
+ npcm7xx_connect_pwm_fan(soc, &splitter[7], 0x0e, 0);
82
- return 1;
161
+ npcm7xx_connect_pwm_fan(soc, &splitter[7], 0x0f, 1);
83
- }
162
+}
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
163
+
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
164
static void quanta_gsj_i2c_init(NPCM7xxState *soc)
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
165
{
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
166
/* GSJ machine have 4 max31725 temperature sensors, tmp105 is compatible. */
88
bool u = extract32(insn, 4, 1);
167
@@ -XXX,XX +XXX,XX @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
89
if (!dc_isar_feature(aa32_dp, s)) {
168
/* TODO: Add additional i2c devices. */
169
}
170
171
+static void quanta_gsj_fan_init(NPCM7xxMachine *machine, NPCM7xxState *soc)
172
+{
173
+ SplitIRQ *splitter = machine->fan_splitter;
174
+ static const int fan_counts[] = {2, 2, 2, 0, 0, 0, 0, 0};
175
+
176
+ npcm7xx_init_pwm_splitter(machine, soc, fan_counts);
177
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x00, 0);
178
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x01, 1);
179
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x02, 0);
180
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x03, 1);
181
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x04, 0);
182
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x05, 1);
183
+}
184
+
185
static void npcm750_evb_init(MachineState *machine)
186
{
187
NPCM7xxState *soc;
188
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_init(MachineState *machine)
189
npcm7xx_load_bootrom(machine, soc);
190
npcm7xx_connect_flash(&soc->fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
191
npcm750_evb_i2c_init(soc);
192
+ npcm750_evb_fan_init(NPCM7XX_MACHINE(machine), soc);
193
npcm7xx_load_kernel(machine, soc);
194
}
195
196
@@ -XXX,XX +XXX,XX @@ static void quanta_gsj_init(MachineState *machine)
197
npcm7xx_connect_flash(&soc->fiu[0], 0, "mx25l25635e",
198
drive_get(IF_MTD, 0, 0));
199
quanta_gsj_i2c_init(soc);
200
+ quanta_gsj_fan_init(NPCM7XX_MACHINE(machine), soc);
201
npcm7xx_load_kernel(machine, soc);
202
}
203
90
--
204
--
91
2.20.1
205
2.20.1
92
206
93
207
diff view generated by jsdifflib
1
Convert the V[US]DOT (vector) insns to decodetree.
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
This patch adds testing of PWM fan RPMs in the existing npcm7xx pwm
4
test. It tests whether the MFT module can measure correct fan values
5
for a PWM fan in NPCM7XX boards.
6
7
Reviewed-by: Doug Evans <dje@google.com>
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
9
Signed-off-by: Hao Wu <wuhaotsh@google.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20210311180855.149764-6-wuhaotsh@google.com
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
6
---
13
---
7
target/arm/neon-shared.decode | 4 ++++
14
tests/qtest/npcm7xx_pwm-test.c | 205 ++++++++++++++++++++++++++++++++-
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
15
1 file changed, 199 insertions(+), 6 deletions(-)
9
target/arm/translate.c | 9 +--------
16
10
3 files changed, 37 insertions(+), 8 deletions(-)
17
diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
19
--- a/tests/qtest/npcm7xx_pwm-test.c
15
+++ b/target/arm/neon-shared.decode
20
+++ b/tests/qtest/npcm7xx_pwm-test.c
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
21
@@ -XXX,XX +XXX,XX @@
17
22
#define PLL_FBDV(rv) extract32((rv), 16, 12)
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
23
#define PLL_OTDV1(rv) extract32((rv), 8, 3)
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
#define PLL_OTDV2(rv) extract32((rv), 13, 3)
20
+
25
+#define APB4CKDIV(rv) extract32((rv), 30, 2)
21
+# VUDOT and VSDOT
26
#define APB3CKDIV(rv) extract32((rv), 28, 2)
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
27
#define CLK2CKDIV(rv) extract32((rv), 0, 1)
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
28
#define CLK4CKDIV(rv) extract32((rv), 26, 2)
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
29
@@ -XXX,XX +XXX,XX @@
25
index XXXXXXX..XXXXXXX 100644
30
26
--- a/target/arm/translate-neon.inc.c
31
#define MAX_DUTY 1000000
27
+++ b/target/arm/translate-neon.inc.c
32
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
33
+/* MFT (PWM fan) related */
29
tcg_temp_free_ptr(fpst);
34
+#define MFT_BA(n) (0xf0180000 + ((n) * 0x1000))
30
return true;
35
+#define MFT_IRQ(n) (96 + (n))
31
}
36
+#define MFT_CNT1 0x00
32
+
37
+#define MFT_CRA 0x02
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
38
+#define MFT_CRB 0x04
34
+{
39
+#define MFT_CNT2 0x06
35
+ int opr_sz;
40
+#define MFT_PRSC 0x08
36
+ gen_helper_gvec_3 *fn_gvec;
41
+#define MFT_CKC 0x0a
37
+
42
+#define MFT_MCTRL 0x0c
38
+ if (!dc_isar_feature(aa32_dp, s)) {
43
+#define MFT_ICTRL 0x0e
39
+ return false;
44
+#define MFT_ICLR 0x10
45
+#define MFT_IEN 0x12
46
+#define MFT_CPA 0x14
47
+#define MFT_CPB 0x16
48
+#define MFT_CPCFG 0x18
49
+#define MFT_INASEL 0x1a
50
+#define MFT_INBSEL 0x1c
51
+
52
+#define MFT_MCTRL_ALL 0x64
53
+#define MFT_ICLR_ALL 0x3f
54
+#define MFT_IEN_ALL 0x3f
55
+#define MFT_CPCFG_EQ_MODE 0x44
56
+
57
+#define MFT_CKC_C2CSEL BIT(3)
58
+#define MFT_CKC_C1CSEL BIT(0)
59
+
60
+#define MFT_ICTRL_TFPND BIT(5)
61
+#define MFT_ICTRL_TEPND BIT(4)
62
+#define MFT_ICTRL_TDPND BIT(3)
63
+#define MFT_ICTRL_TCPND BIT(2)
64
+#define MFT_ICTRL_TBPND BIT(1)
65
+#define MFT_ICTRL_TAPND BIT(0)
66
+
67
+#define MFT_MAX_CNT 0xffff
68
+#define MFT_TIMEOUT 0x5000
69
+
70
+#define DEFAULT_RPM 19800
71
+#define DEFAULT_PRSC 255
72
+#define MFT_PULSE_PER_REVOLUTION 2
73
+
74
+#define MAX_ERROR 1
75
+
76
typedef struct PWMModule {
77
int irq;
78
uint64_t base_addr;
79
@@ -XXX,XX +XXX,XX @@ static uint64_t pwm_get_duty(QTestState *qts, int module_index, int pwm_index)
80
return pwm_qom_get(qts, path, name);
81
}
82
83
+static void mft_qom_set(QTestState *qts, int index, const char *name,
84
+ uint32_t value)
85
+{
86
+ QDict *response;
87
+ char *path = g_strdup_printf("/machine/soc/mft[%d]", index);
88
+
89
+ g_test_message("Setting properties %s of mft[%d] with value %u",
90
+ name, index, value);
91
+ response = qtest_qmp(qts, "{ 'execute': 'qom-set',"
92
+ " 'arguments': { 'path': %s, "
93
+ " 'property': %s, 'value': %u}}",
94
+ path, name, value);
95
+ /* The qom set message returns successfully. */
96
+ g_assert_true(qdict_haskey(response, "return"));
97
+}
98
+
99
static uint32_t get_pll(uint32_t con)
100
{
101
return REF_HZ * PLL_FBDV(con) / (PLL_INDV(con) * PLL_OTDV1(con)
102
* PLL_OTDV2(con));
103
}
104
105
-static uint64_t read_pclk(QTestState *qts)
106
+static uint64_t read_pclk(QTestState *qts, bool mft)
107
{
108
uint64_t freq = REF_HZ;
109
uint32_t clksel = qtest_readl(qts, CLK_BA + CLKSEL);
110
uint32_t pllcon;
111
uint32_t clkdiv1 = qtest_readl(qts, CLK_BA + CLKDIV1);
112
uint32_t clkdiv2 = qtest_readl(qts, CLK_BA + CLKDIV2);
113
+ uint32_t apbdiv = mft ? APB4CKDIV(clkdiv2) : APB3CKDIV(clkdiv2);
114
115
switch (CPUCKSEL(clksel)) {
116
case 0:
117
@@ -XXX,XX +XXX,XX @@ static uint64_t read_pclk(QTestState *qts)
118
g_assert_not_reached();
119
}
120
121
- freq >>= (CLK2CKDIV(clkdiv1) + CLK4CKDIV(clkdiv1) + APB3CKDIV(clkdiv2));
122
+ freq >>= (CLK2CKDIV(clkdiv1) + CLK4CKDIV(clkdiv1) + apbdiv);
123
124
return freq;
125
}
126
@@ -XXX,XX +XXX,XX @@ static uint32_t pwm_selector(uint32_t csr)
127
static uint64_t pwm_compute_freq(QTestState *qts, uint32_t ppr, uint32_t csr,
128
uint32_t cnr)
129
{
130
- return read_pclk(qts) / ((ppr + 1) * pwm_selector(csr) * (cnr + 1));
131
+ return read_pclk(qts, false) / ((ppr + 1) * pwm_selector(csr) * (cnr + 1));
132
}
133
134
static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
135
@@ -XXX,XX +XXX,XX @@ static void pwm_write(QTestState *qts, const TestData *td, unsigned offset,
136
qtest_writel(qts, td->module->base_addr + offset, value);
137
}
138
139
+static uint8_t mft_readb(QTestState *qts, int index, unsigned offset)
140
+{
141
+ return qtest_readb(qts, MFT_BA(index) + offset);
142
+}
143
+
144
+static uint16_t mft_readw(QTestState *qts, int index, unsigned offset)
145
+{
146
+ return qtest_readw(qts, MFT_BA(index) + offset);
147
+}
148
+
149
+static void mft_writeb(QTestState *qts, int index, unsigned offset,
150
+ uint8_t value)
151
+{
152
+ qtest_writeb(qts, MFT_BA(index) + offset, value);
153
+}
154
+
155
+static void mft_writew(QTestState *qts, int index, unsigned offset,
156
+ uint16_t value)
157
+{
158
+ return qtest_writew(qts, MFT_BA(index) + offset, value);
159
+}
160
+
161
static uint32_t pwm_read_ppr(QTestState *qts, const TestData *td)
162
{
163
return extract32(pwm_read(qts, td, PPR), ppr_base[pwm_index(td->pwm)], 8);
164
@@ -XXX,XX +XXX,XX @@ static void pwm_write_cmr(QTestState *qts, const TestData *td, uint32_t value)
165
pwm_write(qts, td, td->pwm->cmr_offset, value);
166
}
167
168
+static int mft_compute_index(const TestData *td)
169
+{
170
+ int index = pwm_module_index(td->module) * ARRAY_SIZE(pwm_list) +
171
+ pwm_index(td->pwm);
172
+
173
+ g_assert_cmpint(index, <,
174
+ ARRAY_SIZE(pwm_module_list) * ARRAY_SIZE(pwm_list));
175
+
176
+ return index;
177
+}
178
+
179
+static void mft_reset_counters(QTestState *qts, int index)
180
+{
181
+ mft_writew(qts, index, MFT_CNT1, MFT_MAX_CNT);
182
+ mft_writew(qts, index, MFT_CNT2, MFT_MAX_CNT);
183
+ mft_writew(qts, index, MFT_CRA, MFT_MAX_CNT);
184
+ mft_writew(qts, index, MFT_CRB, MFT_MAX_CNT);
185
+ mft_writew(qts, index, MFT_CPA, MFT_MAX_CNT - MFT_TIMEOUT);
186
+ mft_writew(qts, index, MFT_CPB, MFT_MAX_CNT - MFT_TIMEOUT);
187
+}
188
+
189
+static void mft_init(QTestState *qts, const TestData *td)
190
+{
191
+ int index = mft_compute_index(td);
192
+
193
+ /* Enable everything */
194
+ mft_writeb(qts, index, MFT_CKC, 0);
195
+ mft_writeb(qts, index, MFT_ICLR, MFT_ICLR_ALL);
196
+ mft_writeb(qts, index, MFT_MCTRL, MFT_MCTRL_ALL);
197
+ mft_writeb(qts, index, MFT_IEN, MFT_IEN_ALL);
198
+ mft_writeb(qts, index, MFT_INASEL, 0);
199
+ mft_writeb(qts, index, MFT_INBSEL, 0);
200
+
201
+ /* Set cpcfg to use EQ mode, same as kernel driver */
202
+ mft_writeb(qts, index, MFT_CPCFG, MFT_CPCFG_EQ_MODE);
203
+
204
+ /* Write default counters, timeout and prescaler */
205
+ mft_reset_counters(qts, index);
206
+ mft_writeb(qts, index, MFT_PRSC, DEFAULT_PRSC);
207
+
208
+ /* Write default max rpm via QMP */
209
+ mft_qom_set(qts, index, "max_rpm[0]", DEFAULT_RPM);
210
+ mft_qom_set(qts, index, "max_rpm[1]", DEFAULT_RPM);
211
+}
212
+
213
+static int32_t mft_compute_cnt(uint32_t rpm, uint64_t clk)
214
+{
215
+ uint64_t cnt;
216
+
217
+ if (rpm == 0) {
218
+ return -1;
40
+ }
219
+ }
41
+
220
+
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
221
+ cnt = clk * 60 / ((DEFAULT_PRSC + 1) * rpm * MFT_PULSE_PER_REVOLUTION);
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
222
+ if (cnt >= MFT_TIMEOUT) {
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
223
+ return -1;
45
+ return false;
46
+ }
224
+ }
47
+
225
+ return MFT_MAX_CNT - cnt;
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
226
+}
49
+ return false;
227
+
228
+static void mft_verify_rpm(QTestState *qts, const TestData *td, uint64_t duty)
229
+{
230
+ int index = mft_compute_index(td);
231
+ uint16_t cnt, cr;
232
+ uint32_t rpm = DEFAULT_RPM * duty / MAX_DUTY;
233
+ uint64_t clk = read_pclk(qts, true);
234
+ int32_t expected_cnt = mft_compute_cnt(rpm, clk);
235
+
236
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
237
+ g_test_message(
238
+ "verifying rpm for mft[%d]: clk: %lu, duty: %lu, rpm: %u, cnt: %d",
239
+ index, clk, duty, rpm, expected_cnt);
240
+
241
+ /* Verify rpm for fan A */
242
+ /* Stop capture */
243
+ mft_writeb(qts, index, MFT_CKC, 0);
244
+ mft_writeb(qts, index, MFT_ICLR, MFT_ICLR_ALL);
245
+ mft_reset_counters(qts, index);
246
+ g_assert_cmphex(mft_readw(qts, index, MFT_CNT1), ==, MFT_MAX_CNT);
247
+ g_assert_cmphex(mft_readw(qts, index, MFT_CRA), ==, MFT_MAX_CNT);
248
+ g_assert_cmphex(mft_readw(qts, index, MFT_CPA), ==,
249
+ MFT_MAX_CNT - MFT_TIMEOUT);
250
+ /* Start capture */
251
+ mft_writeb(qts, index, MFT_CKC, MFT_CKC_C1CSEL);
252
+ g_assert_true(qtest_get_irq(qts, MFT_IRQ(index)));
253
+ if (expected_cnt == -1) {
254
+ g_assert_cmphex(mft_readb(qts, index, MFT_ICTRL), ==, MFT_ICTRL_TEPND);
255
+ } else {
256
+ g_assert_cmphex(mft_readb(qts, index, MFT_ICTRL), ==, MFT_ICTRL_TAPND);
257
+ cnt = mft_readw(qts, index, MFT_CNT1);
258
+ /*
259
+ * Due to error in clock measurement and rounding, we might have a small
260
+ * error in measuring RPM.
261
+ */
262
+ g_assert_cmphex(cnt + MAX_ERROR, >=, expected_cnt);
263
+ g_assert_cmphex(cnt, <=, expected_cnt + MAX_ERROR);
264
+ cr = mft_readw(qts, index, MFT_CRA);
265
+ g_assert_cmphex(cnt, ==, cr);
50
+ }
266
+ }
51
+
267
+
52
+ if (!vfp_access_check(s)) {
268
+ /* Verify rpm for fan B */
53
+ return true;
269
+
54
+ }
270
+ qtest_irq_intercept_out(qts, "/machine/soc/a9mpcore/gic");
55
+
271
+}
56
+ opr_sz = (1 + a->q) * 8;
272
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
273
/* Check pwm registers can be reset to default value */
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
274
static void test_init(gconstpointer test_data)
59
+ vfp_reg_offset(1, a->vn),
275
{
60
+ vfp_reg_offset(1, a->vm),
276
const TestData *td = test_data;
61
+ opr_sz, opr_sz, 0, fn_gvec);
277
- QTestState *qts = qtest_init("-machine quanta-gsj");
62
+ return true;
278
+ QTestState *qts = qtest_init("-machine npcm750-evb");
63
+}
279
int module = pwm_module_index(td->module);
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
280
int pwm = pwm_index(td->pwm);
65
index XXXXXXX..XXXXXXX 100644
281
66
--- a/target/arm/translate.c
282
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
67
+++ b/target/arm/translate.c
283
static void test_oneshot(gconstpointer test_data)
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
284
{
69
bool is_long = false, q = extract32(insn, 6, 1);
285
const TestData *td = test_data;
70
bool ptr_is_env = false;
286
- QTestState *qts = qtest_init("-machine quanta-gsj");
71
287
+ QTestState *qts = qtest_init("-machine npcm750-evb");
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
288
int module = pwm_module_index(td->module);
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
289
int pwm = pwm_index(td->pwm);
74
- bool u = extract32(insn, 4, 1);
290
uint32_t ppr, csr, pcr;
75
- if (!dc_isar_feature(aa32_dp, s)) {
291
@@ -XXX,XX +XXX,XX @@ static void test_oneshot(gconstpointer test_data)
76
- return 1;
292
static void test_toggle(gconstpointer test_data)
77
- }
293
{
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
294
const TestData *td = test_data;
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
295
- QTestState *qts = qtest_init("-machine quanta-gsj");
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
296
+ QTestState *qts = qtest_init("-machine npcm750-evb");
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
297
int module = pwm_module_index(td->module);
82
int is_s = extract32(insn, 23, 1);
298
int pwm = pwm_index(td->pwm);
83
if (!dc_isar_feature(aa32_fhm, s)) {
299
uint32_t ppr, csr, pcr, cnr, cmr;
300
int i, j, k, l;
301
uint64_t expected_freq, expected_duty;
302
303
+ mft_init(qts, td);
304
+
305
pcr = CH_EN | CH_MOD;
306
for (i = 0; i < ARRAY_SIZE(ppr_list); ++i) {
307
ppr = ppr_list[i];
308
@@ -XXX,XX +XXX,XX @@ static void test_toggle(gconstpointer test_data)
309
==, expected_freq);
310
}
311
312
+ /* Test MFT's RPM is correct. */
313
+ mft_verify_rpm(qts, td, expected_duty);
314
+
315
/* Test inverted mode */
316
expected_duty = pwm_compute_duty(cnr, cmr, true);
317
pwm_write_pcr(qts, td, pcr | CH_INV);
84
--
318
--
85
2.20.1
319
2.20.1
86
320
87
321
diff view generated by jsdifflib
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
1
For a long time now the UI layer has guaranteed that the console
2
whether the stage 1 access is for EL0 or not, because whether
2
surface is always 32 bits per pixel. Remove the legacy dead
3
exec permission is given can depend on whether this is an EL0
3
code from the pl110 display device which was handling the
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
4
possibility that the console surface was some other format.
5
the call sites can pass this information in.
6
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
8
add one so we have a place to put the documentation of the
9
semantics of the new s1_is_el0 argument.
10
5
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210211141515.8755-2-peter.maydell@linaro.org
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
15
---
9
---
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
10
hw/display/pl110.c | 53 +++++++---------------------------------------
17
1 file changed, 28 insertions(+), 1 deletion(-)
11
1 file changed, 8 insertions(+), 45 deletions(-)
18
12
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
15
--- a/hw/display/pl110.c
22
+++ b/target/arm/helper.c
16
+++ b/hw/display/pl110.c
23
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
24
18
pl111_id
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
19
};
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
20
27
+ bool s1_is_el0,
21
-#define BITS 8
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
22
-#include "pl110_template.h"
29
target_ulong *page_size_ptr,
23
-#define BITS 15
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
24
-#include "pl110_template.h"
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
25
-#define BITS 16
26
-#include "pl110_template.h"
27
-#define BITS 24
28
-#include "pl110_template.h"
29
#define BITS 32
30
#include "pl110_template.h"
31
32
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
33
PL110State *s = (PL110State *)opaque;
34
SysBusDevice *sbd;
35
DisplaySurface *surface = qemu_console_surface(s->con);
36
- drawfn* fntable;
37
drawfn fn;
38
- int dest_width;
39
int src_width;
40
int bpp_offset;
41
int first;
42
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
43
44
sbd = SYS_BUS_DEVICE(s);
45
46
- switch (surface_bits_per_pixel(surface)) {
47
- case 0:
48
- return;
49
- case 8:
50
- fntable = pl110_draw_fn_8;
51
- dest_width = 1;
52
- break;
53
- case 15:
54
- fntable = pl110_draw_fn_15;
55
- dest_width = 2;
56
- break;
57
- case 16:
58
- fntable = pl110_draw_fn_16;
59
- dest_width = 2;
60
- break;
61
- case 24:
62
- fntable = pl110_draw_fn_24;
63
- dest_width = 3;
64
- break;
65
- case 32:
66
- fntable = pl110_draw_fn_32;
67
- dest_width = 4;
68
- break;
69
- default:
70
- fprintf(stderr, "pl110: Bad color depth\n");
71
- exit(1);
72
- }
73
if (s->cr & PL110_CR_BGR)
74
bpp_offset = 0;
75
else
76
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
32
}
77
}
33
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
35
+ false,
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
37
pcacheattrs);
38
if (ret) {
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
40
};
41
}
42
43
+/**
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
45
+ *
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
48
+ * information on why the translation aborted, in the format of a long-format
49
+ * DFSR/IFSR fault register, with the following caveats:
50
+ * * the WnR bit is never set (the caller must do this).
51
+ *
52
+ * @env: CPUARMState
53
+ * @address: virtual address to get physical address for
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
55
+ * @mmu_idx: MMU index indicating required translation regime
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
60
+ * @attrs: set to the memory transaction attributes to use
61
+ * @prot: set to the permissions for the page containing phys_ptr
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
63
+ * @fi: set to fault info if the translation fails
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
65
+ */
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
68
+ bool s1_is_el0,
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
70
target_ulong *page_size_ptr,
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
73
74
/* S1 is done. Now do S2 translation. */
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
76
+ mmu_idx == ARMMMUIdx_E10_0,
77
phys_ptr, attrs, &s2_prot,
78
page_size, fi,
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
81
}
78
}
82
79
83
if (regime_using_lpae_format(env, mmu_idx)) {
80
- if (s->cr & PL110_CR_BEBO)
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
81
- fn = fntable[s->bpp + 8 + bpp_offset];
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
82
- else if (s->cr & PL110_CR_BEPO)
86
phys_ptr, attrs, prot, page_size,
83
- fn = fntable[s->bpp + 16 + bpp_offset];
87
fi, cacheattrs);
84
- else
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
85
- fn = fntable[s->bpp + bpp_offset];
86
+ if (s->cr & PL110_CR_BEBO) {
87
+ fn = pl110_draw_fn_32[s->bpp + 8 + bpp_offset];
88
+ } else if (s->cr & PL110_CR_BEPO) {
89
+ fn = pl110_draw_fn_32[s->bpp + 16 + bpp_offset];
90
+ } else {
91
+ fn = pl110_draw_fn_32[s->bpp + bpp_offset];
92
+ }
93
94
src_width = s->cols;
95
switch (s->bpp) {
96
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
97
src_width <<= 2;
98
break;
99
}
100
- dest_width *= s->cols;
101
first = 0;
102
if (s->invalidate) {
103
framebuffer_update_memory_section(&s->fbsection,
104
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
105
106
framebuffer_update_display(surface, &s->fbsection,
107
s->cols, s->rows,
108
- src_width, dest_width, 0,
109
+ src_width, s->cols * 4, 0,
110
s->invalidate,
111
fn, s->palette,
112
&first, &last);
89
--
113
--
90
2.20.1
114
2.20.1
91
115
92
116
diff view generated by jsdifflib
1
Convert the Neon "load/store multiple structures" insns to decodetree.
1
The pl110_template.h header has a doubly-nested multiple-include pattern:
2
* pl110.c includes it once for each host bit depth (now always 32)
3
* every time it is included, it includes itself 6 times, to account
4
for multiple guest device pixel and byte orders
5
6
Now we only have to deal with 32-bit host bit depths, we can move the
7
code corresponding to the outer layer of this double-nesting to be
8
directly in pl110.c and reduce the template header to a single layer
9
of nesting.
2
10
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
13
Message-id: 20210211141515.8755-3-peter.maydell@linaro.org
6
---
14
---
7
target/arm/neon-ls.decode | 7 ++
15
hw/display/pl110_template.h | 100 +-----------------------------------
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
16
hw/display/pl110.c | 79 ++++++++++++++++++++++++++++
9
target/arm/translate.c | 91 +----------------------
17
2 files changed, 80 insertions(+), 99 deletions(-)
10
3 files changed, 133 insertions(+), 89 deletions(-)
18
11
19
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
13
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-ls.decode
21
--- a/hw/display/pl110_template.h
15
+++ b/target/arm/neon-ls.decode
22
+++ b/hw/display/pl110_template.h
16
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
24
*/
18
# This file works on the A32 encoding only; calling code for T32 has to
25
19
# transform the insn into the A32 version first.
26
#ifndef ORDER
20
+
27
-
21
+%vd_dp 22:1 12:4
28
-#if BITS == 8
22
+
29
-#define COPY_PIXEL(to, from) *(to++) = from
23
+# Neon load/store multiple structures
30
-#elif BITS == 15 || BITS == 16
24
+
31
-#define COPY_PIXEL(to, from) do { *(uint16_t *)to = from; to += 2; } while (0)
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
32
-#elif BITS == 24
26
+ vd=%vd_dp
33
-#define COPY_PIXEL(to, from) \
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
- do { \
35
- *(to++) = from; \
36
- *(to++) = (from) >> 8; \
37
- *(to++) = (from) >> 16; \
38
- } while (0)
39
-#elif BITS == 32
40
-#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
41
-#else
42
-#error unknown bit depth
43
+#error "pl110_template.h is only for inclusion by pl110.c"
44
#endif
45
46
-#undef RGB
47
-#define BORDER bgr
48
-#define ORDER 0
49
-#include "pl110_template.h"
50
-#define ORDER 1
51
-#include "pl110_template.h"
52
-#define ORDER 2
53
-#include "pl110_template.h"
54
-#undef BORDER
55
-#define RGB
56
-#define BORDER rgb
57
-#define ORDER 0
58
-#include "pl110_template.h"
59
-#define ORDER 1
60
-#include "pl110_template.h"
61
-#define ORDER 2
62
-#include "pl110_template.h"
63
-#undef BORDER
64
-
65
-static drawfn glue(pl110_draw_fn_,BITS)[48] =
66
-{
67
- glue(pl110_draw_line1_lblp_bgr,BITS),
68
- glue(pl110_draw_line2_lblp_bgr,BITS),
69
- glue(pl110_draw_line4_lblp_bgr,BITS),
70
- glue(pl110_draw_line8_lblp_bgr,BITS),
71
- glue(pl110_draw_line16_555_lblp_bgr,BITS),
72
- glue(pl110_draw_line32_lblp_bgr,BITS),
73
- glue(pl110_draw_line16_lblp_bgr,BITS),
74
- glue(pl110_draw_line12_lblp_bgr,BITS),
75
-
76
- glue(pl110_draw_line1_bbbp_bgr,BITS),
77
- glue(pl110_draw_line2_bbbp_bgr,BITS),
78
- glue(pl110_draw_line4_bbbp_bgr,BITS),
79
- glue(pl110_draw_line8_bbbp_bgr,BITS),
80
- glue(pl110_draw_line16_555_bbbp_bgr,BITS),
81
- glue(pl110_draw_line32_bbbp_bgr,BITS),
82
- glue(pl110_draw_line16_bbbp_bgr,BITS),
83
- glue(pl110_draw_line12_bbbp_bgr,BITS),
84
-
85
- glue(pl110_draw_line1_lbbp_bgr,BITS),
86
- glue(pl110_draw_line2_lbbp_bgr,BITS),
87
- glue(pl110_draw_line4_lbbp_bgr,BITS),
88
- glue(pl110_draw_line8_lbbp_bgr,BITS),
89
- glue(pl110_draw_line16_555_lbbp_bgr,BITS),
90
- glue(pl110_draw_line32_lbbp_bgr,BITS),
91
- glue(pl110_draw_line16_lbbp_bgr,BITS),
92
- glue(pl110_draw_line12_lbbp_bgr,BITS),
93
-
94
- glue(pl110_draw_line1_lblp_rgb,BITS),
95
- glue(pl110_draw_line2_lblp_rgb,BITS),
96
- glue(pl110_draw_line4_lblp_rgb,BITS),
97
- glue(pl110_draw_line8_lblp_rgb,BITS),
98
- glue(pl110_draw_line16_555_lblp_rgb,BITS),
99
- glue(pl110_draw_line32_lblp_rgb,BITS),
100
- glue(pl110_draw_line16_lblp_rgb,BITS),
101
- glue(pl110_draw_line12_lblp_rgb,BITS),
102
-
103
- glue(pl110_draw_line1_bbbp_rgb,BITS),
104
- glue(pl110_draw_line2_bbbp_rgb,BITS),
105
- glue(pl110_draw_line4_bbbp_rgb,BITS),
106
- glue(pl110_draw_line8_bbbp_rgb,BITS),
107
- glue(pl110_draw_line16_555_bbbp_rgb,BITS),
108
- glue(pl110_draw_line32_bbbp_rgb,BITS),
109
- glue(pl110_draw_line16_bbbp_rgb,BITS),
110
- glue(pl110_draw_line12_bbbp_rgb,BITS),
111
-
112
- glue(pl110_draw_line1_lbbp_rgb,BITS),
113
- glue(pl110_draw_line2_lbbp_rgb,BITS),
114
- glue(pl110_draw_line4_lbbp_rgb,BITS),
115
- glue(pl110_draw_line8_lbbp_rgb,BITS),
116
- glue(pl110_draw_line16_555_lbbp_rgb,BITS),
117
- glue(pl110_draw_line32_lbbp_rgb,BITS),
118
- glue(pl110_draw_line16_lbbp_rgb,BITS),
119
- glue(pl110_draw_line12_lbbp_rgb,BITS),
120
-};
121
-
122
-#undef BITS
123
-#undef COPY_PIXEL
124
-
125
-#else
126
-
127
#if ORDER == 0
128
#define NAME glue(glue(lblp_, BORDER), BITS)
129
#ifdef HOST_WORDS_BIGENDIAN
130
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_
131
#undef NAME
132
#undef SWAP_WORDS
133
#undef ORDER
134
-
135
-#endif
136
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
28
index XXXXXXX..XXXXXXX 100644
137
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
138
--- a/hw/display/pl110.c
30
+++ b/target/arm/translate-neon.inc.c
139
+++ b/hw/display/pl110.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
140
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
32
gen_helper_gvec_fmlal_idx_a32);
141
};
33
return true;
142
34
}
143
#define BITS 32
35
+
144
+#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
36
+static struct {
145
+
37
+ int nregs;
146
+#undef RGB
38
+ int interleave;
147
+#define BORDER bgr
39
+ int spacing;
148
+#define ORDER 0
40
+} const neon_ls_element_type[11] = {
149
#include "pl110_template.h"
41
+ {1, 4, 1},
150
+#define ORDER 1
42
+ {1, 4, 2},
151
+#include "pl110_template.h"
43
+ {4, 1, 1},
152
+#define ORDER 2
44
+ {2, 2, 2},
153
+#include "pl110_template.h"
45
+ {1, 3, 1},
154
+#undef BORDER
46
+ {1, 3, 2},
155
+#define RGB
47
+ {3, 1, 1},
156
+#define BORDER rgb
48
+ {1, 1, 1},
157
+#define ORDER 0
49
+ {1, 2, 1},
158
+#include "pl110_template.h"
50
+ {1, 2, 2},
159
+#define ORDER 1
51
+ {2, 1, 1}
160
+#include "pl110_template.h"
161
+#define ORDER 2
162
+#include "pl110_template.h"
163
+#undef BORDER
164
+
165
+static drawfn pl110_draw_fn_32[48] = {
166
+ pl110_draw_line1_lblp_bgr32,
167
+ pl110_draw_line2_lblp_bgr32,
168
+ pl110_draw_line4_lblp_bgr32,
169
+ pl110_draw_line8_lblp_bgr32,
170
+ pl110_draw_line16_555_lblp_bgr32,
171
+ pl110_draw_line32_lblp_bgr32,
172
+ pl110_draw_line16_lblp_bgr32,
173
+ pl110_draw_line12_lblp_bgr32,
174
+
175
+ pl110_draw_line1_bbbp_bgr32,
176
+ pl110_draw_line2_bbbp_bgr32,
177
+ pl110_draw_line4_bbbp_bgr32,
178
+ pl110_draw_line8_bbbp_bgr32,
179
+ pl110_draw_line16_555_bbbp_bgr32,
180
+ pl110_draw_line32_bbbp_bgr32,
181
+ pl110_draw_line16_bbbp_bgr32,
182
+ pl110_draw_line12_bbbp_bgr32,
183
+
184
+ pl110_draw_line1_lbbp_bgr32,
185
+ pl110_draw_line2_lbbp_bgr32,
186
+ pl110_draw_line4_lbbp_bgr32,
187
+ pl110_draw_line8_lbbp_bgr32,
188
+ pl110_draw_line16_555_lbbp_bgr32,
189
+ pl110_draw_line32_lbbp_bgr32,
190
+ pl110_draw_line16_lbbp_bgr32,
191
+ pl110_draw_line12_lbbp_bgr32,
192
+
193
+ pl110_draw_line1_lblp_rgb32,
194
+ pl110_draw_line2_lblp_rgb32,
195
+ pl110_draw_line4_lblp_rgb32,
196
+ pl110_draw_line8_lblp_rgb32,
197
+ pl110_draw_line16_555_lblp_rgb32,
198
+ pl110_draw_line32_lblp_rgb32,
199
+ pl110_draw_line16_lblp_rgb32,
200
+ pl110_draw_line12_lblp_rgb32,
201
+
202
+ pl110_draw_line1_bbbp_rgb32,
203
+ pl110_draw_line2_bbbp_rgb32,
204
+ pl110_draw_line4_bbbp_rgb32,
205
+ pl110_draw_line8_bbbp_rgb32,
206
+ pl110_draw_line16_555_bbbp_rgb32,
207
+ pl110_draw_line32_bbbp_rgb32,
208
+ pl110_draw_line16_bbbp_rgb32,
209
+ pl110_draw_line12_bbbp_rgb32,
210
+
211
+ pl110_draw_line1_lbbp_rgb32,
212
+ pl110_draw_line2_lbbp_rgb32,
213
+ pl110_draw_line4_lbbp_rgb32,
214
+ pl110_draw_line8_lbbp_rgb32,
215
+ pl110_draw_line16_555_lbbp_rgb32,
216
+ pl110_draw_line32_lbbp_rgb32,
217
+ pl110_draw_line16_lbbp_rgb32,
218
+ pl110_draw_line12_lbbp_rgb32,
52
+};
219
+};
53
+
220
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
221
+#undef BITS
55
+ int stride)
222
+#undef COPY_PIXEL
56
+{
223
+
57
+ if (rm != 15) {
224
58
+ TCGv_i32 base;
225
static int pl110_enabled(PL110State *s)
59
+
60
+ base = load_reg(s, rn);
61
+ if (rm == 13) {
62
+ tcg_gen_addi_i32(base, base, stride);
63
+ } else {
64
+ TCGv_i32 index;
65
+ index = load_reg(s, rm);
66
+ tcg_gen_add_i32(base, base, index);
67
+ tcg_temp_free_i32(index);
68
+ }
69
+ store_reg(s, rn, base);
70
+ }
71
+}
72
+
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
74
+{
75
+ /* Neon load/store multiple structures */
76
+ int nregs, interleave, spacing, reg, n;
77
+ MemOp endian = s->be_data;
78
+ int mmu_idx = get_mem_index(s);
79
+ int size = a->size;
80
+ TCGv_i64 tmp64;
81
+ TCGv_i32 addr, tmp;
82
+
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
84
+ return false;
85
+ }
86
+
87
+ /* UNDEF accesses to D16-D31 if they don't exist */
88
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
89
+ return false;
90
+ }
91
+ if (a->itype > 10) {
92
+ return false;
93
+ }
94
+ /* Catch UNDEF cases for bad values of align field */
95
+ switch (a->itype & 0xc) {
96
+ case 4:
97
+ if (a->align >= 2) {
98
+ return false;
99
+ }
100
+ break;
101
+ case 8:
102
+ if (a->align == 3) {
103
+ return false;
104
+ }
105
+ break;
106
+ default:
107
+ break;
108
+ }
109
+ nregs = neon_ls_element_type[a->itype].nregs;
110
+ interleave = neon_ls_element_type[a->itype].interleave;
111
+ spacing = neon_ls_element_type[a->itype].spacing;
112
+ if (size == 3 && (interleave | spacing) != 1) {
113
+ return false;
114
+ }
115
+
116
+ if (!vfp_access_check(s)) {
117
+ return true;
118
+ }
119
+
120
+ /* For our purposes, bytes are always little-endian. */
121
+ if (size == 0) {
122
+ endian = MO_LE;
123
+ }
124
+ /*
125
+ * Consecutive little-endian elements from a single register
126
+ * can be promoted to a larger little-endian operation.
127
+ */
128
+ if (interleave == 1 && endian == MO_LE) {
129
+ size = 3;
130
+ }
131
+ tmp64 = tcg_temp_new_i64();
132
+ addr = tcg_temp_new_i32();
133
+ tmp = tcg_const_i32(1 << size);
134
+ load_reg_var(s, addr, a->rn);
135
+ for (reg = 0; reg < nregs; reg++) {
136
+ for (n = 0; n < 8 >> size; n++) {
137
+ int xs;
138
+ for (xs = 0; xs < interleave; xs++) {
139
+ int tt = a->vd + reg + spacing * xs;
140
+
141
+ if (a->l) {
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
143
+ neon_store_element64(tt, n, size, tmp64);
144
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
147
+ }
148
+ tcg_gen_add_i32(addr, addr, tmp);
149
+ }
150
+ }
151
+ }
152
+ tcg_temp_free_i32(addr);
153
+ tcg_temp_free_i32(tmp);
154
+ tcg_temp_free_i64(tmp64);
155
+
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
157
+ return true;
158
+}
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 void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
164
}
165
166
167
-static struct {
168
- int nregs;
169
- int interleave;
170
- int spacing;
171
-} const neon_ls_element_type[11] = {
172
- {1, 4, 1},
173
- {1, 4, 2},
174
- {4, 1, 1},
175
- {2, 2, 2},
176
- {1, 3, 1},
177
- {1, 3, 2},
178
- {3, 1, 1},
179
- {1, 1, 1},
180
- {1, 2, 1},
181
- {1, 2, 2},
182
- {2, 1, 1}
183
-};
184
-
185
/* Translate a NEON load/store element instruction. Return nonzero if the
186
instruction is invalid. */
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
188
{
226
{
189
int rd, rn, rm;
190
- int op;
191
int nregs;
192
- int interleave;
193
- int spacing;
194
int stride;
195
int size;
196
int reg;
197
int load;
198
- int n;
199
int vec_size;
200
- int mmu_idx;
201
- MemOp endian;
202
TCGv_i32 addr;
203
TCGv_i32 tmp;
204
- TCGv_i32 tmp2;
205
- TCGv_i64 tmp64;
206
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
208
return 1;
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
210
rn = (insn >> 16) & 0xf;
211
rm = insn & 0xf;
212
load = (insn & (1 << 21)) != 0;
213
- endian = s->be_data;
214
- mmu_idx = get_mem_index(s);
215
if ((insn & (1 << 23)) == 0) {
216
- /* Load store all elements. */
217
- op = (insn >> 8) & 0xf;
218
- size = (insn >> 6) & 3;
219
- if (op > 10)
220
- return 1;
221
- /* Catch UNDEF cases for bad values of align field */
222
- switch (op & 0xc) {
223
- case 4:
224
- if (((insn >> 5) & 1) == 1) {
225
- return 1;
226
- }
227
- break;
228
- case 8:
229
- if (((insn >> 4) & 3) == 3) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- break;
235
- }
236
- nregs = neon_ls_element_type[op].nregs;
237
- interleave = neon_ls_element_type[op].interleave;
238
- spacing = neon_ls_element_type[op].spacing;
239
- if (size == 3 && (interleave | spacing) != 1) {
240
- return 1;
241
- }
242
- /* For our purposes, bytes are always little-endian. */
243
- if (size == 0) {
244
- endian = MO_LE;
245
- }
246
- /* Consecutive little-endian elements from a single register
247
- * can be promoted to a larger little-endian operation.
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
261
-
262
- if (load) {
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
264
- neon_store_element64(tt, n, size, tmp64);
265
- } else {
266
- neon_load_element64(tmp64, tt, n, size);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
268
- }
269
- tcg_gen_add_i32(addr, addr, tmp2);
270
- }
271
- }
272
- }
273
- tcg_temp_free_i32(addr);
274
- tcg_temp_free_i32(tmp2);
275
- tcg_temp_free_i64(tmp64);
276
- stride = nregs * interleave * 8;
277
+ /* Load store all elements -- handled already by decodetree */
278
+ return 1;
279
} else {
280
size = (insn >> 10) & 3;
281
if (size == 3) {
282
--
227
--
283
2.20.1
228
2.20.1
284
229
285
230
diff view generated by jsdifflib
1
We're going to want at least some of the NeonGen* typedefs
1
BITS is always 32, so remove all uses of it from the template header,
2
for the refactored 32-bit Neon decoder, so move them all
2
by dropping the trailing '32' from the draw function names and
3
to translate.h since it makes more sense to keep them in
3
not constructing the name of rgb_to_pixel32() via the glue() macro.
4
one group.
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
7
Message-id: 20210211141515.8755-4-peter.maydell@linaro.org
9
---
8
---
10
target/arm/translate.h | 17 +++++++++++++++++
9
hw/display/pl110_template.h | 20 +++----
11
target/arm/translate-a64.c | 17 -----------------
10
hw/display/pl110.c | 113 ++++++++++++++++++------------------
12
2 files changed, 17 insertions(+), 17 deletions(-)
11
2 files changed, 65 insertions(+), 68 deletions(-)
13
12
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
13
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
15
--- a/hw/display/pl110_template.h
17
+++ b/target/arm/translate.h
16
+++ b/hw/display/pl110_template.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
17
@@ -XXX,XX +XXX,XX @@
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
18
#endif
20
uint32_t, uint32_t, uint32_t);
19
21
20
#if ORDER == 0
22
+/* Function prototype for gen_ functions for calling Neon helpers */
21
-#define NAME glue(glue(lblp_, BORDER), BITS)
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
22
+#define NAME glue(lblp_, BORDER)
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
23
#ifdef HOST_WORDS_BIGENDIAN
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
24
#define SWAP_WORDS 1
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
25
#endif
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
26
#elif ORDER == 1
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
27
-#define NAME glue(glue(bbbp_, BORDER), BITS)
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
28
+#define NAME glue(bbbp_, BORDER)
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
29
#ifndef HOST_WORDS_BIGENDIAN
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
30
#define SWAP_WORDS 1
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
31
#endif
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
32
#else
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
33
#define SWAP_PIXELS 1
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
34
-#define NAME glue(glue(lbbp_, BORDER), BITS)
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
35
+#define NAME glue(lbbp_, BORDER)
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
36
#ifdef HOST_WORDS_BIGENDIAN
38
+
37
#define SWAP_WORDS 1
39
#endif /* TARGET_ARM_TRANSLATE_H */
38
#endif
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
39
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_
40
MSB = (data & 0x1f) << 3;
41
data >>= 5;
42
#endif
43
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
44
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
45
LSB = (data & 0x1f) << 3;
46
data >>= 5;
47
g = (data & 0x3f) << 2;
48
data >>= 6;
49
MSB = (data & 0x1f) << 3;
50
data >>= 5;
51
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
52
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
53
#undef MSB
54
#undef LSB
55
width -= 2;
56
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_
57
g = (data >> 16) & 0xff;
58
MSB = (data >> 8) & 0xff;
59
#endif
60
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
61
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
62
#undef MSB
63
#undef LSB
64
width--;
65
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const ui
66
data >>= 5;
67
MSB = (data & 0x1f) << 3;
68
data >>= 5;
69
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
70
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
71
LSB = (data & 0x1f) << 3;
72
data >>= 5;
73
g = (data & 0x1f) << 3;
74
data >>= 5;
75
MSB = (data & 0x1f) << 3;
76
data >>= 6;
77
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
78
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
79
#undef MSB
80
#undef LSB
81
width -= 2;
82
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_
83
data >>= 4;
84
MSB = (data & 0xf) << 4;
85
data >>= 8;
86
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
87
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
88
LSB = (data & 0xf) << 4;
89
data >>= 4;
90
g = (data & 0xf) << 4;
91
data >>= 4;
92
MSB = (data & 0xf) << 4;
93
data >>= 8;
94
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
95
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
96
#undef MSB
97
#undef LSB
98
width -= 2;
99
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
41
index XXXXXXX..XXXXXXX 100644
100
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-a64.c
101
--- a/hw/display/pl110.c
43
+++ b/target/arm/translate-a64.c
102
+++ b/hw/display/pl110.c
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
103
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
45
AArch64DecodeFn *disas_fn;
104
pl111_id
46
} AArch64DecodeTable;
105
};
47
106
48
-/* Function prototype for gen_ functions for calling Neon helpers */
107
-#define BITS 32
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
108
#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
109
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
110
#undef RGB
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
111
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
112
#include "pl110_template.h"
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
113
#undef BORDER
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
114
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
115
-static drawfn pl110_draw_fn_32[48] = {
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
116
- pl110_draw_line1_lblp_bgr32,
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
117
- pl110_draw_line2_lblp_bgr32,
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
118
- pl110_draw_line4_lblp_bgr32,
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
119
- pl110_draw_line8_lblp_bgr32,
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
120
- pl110_draw_line16_555_lblp_bgr32,
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
121
- pl110_draw_line32_lblp_bgr32,
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
122
- pl110_draw_line16_lblp_bgr32,
64
-
123
- pl110_draw_line12_lblp_bgr32,
65
/* initialize TCG globals. */
124
-
66
void a64_translate_init(void)
125
- pl110_draw_line1_bbbp_bgr32,
126
- pl110_draw_line2_bbbp_bgr32,
127
- pl110_draw_line4_bbbp_bgr32,
128
- pl110_draw_line8_bbbp_bgr32,
129
- pl110_draw_line16_555_bbbp_bgr32,
130
- pl110_draw_line32_bbbp_bgr32,
131
- pl110_draw_line16_bbbp_bgr32,
132
- pl110_draw_line12_bbbp_bgr32,
133
-
134
- pl110_draw_line1_lbbp_bgr32,
135
- pl110_draw_line2_lbbp_bgr32,
136
- pl110_draw_line4_lbbp_bgr32,
137
- pl110_draw_line8_lbbp_bgr32,
138
- pl110_draw_line16_555_lbbp_bgr32,
139
- pl110_draw_line32_lbbp_bgr32,
140
- pl110_draw_line16_lbbp_bgr32,
141
- pl110_draw_line12_lbbp_bgr32,
142
-
143
- pl110_draw_line1_lblp_rgb32,
144
- pl110_draw_line2_lblp_rgb32,
145
- pl110_draw_line4_lblp_rgb32,
146
- pl110_draw_line8_lblp_rgb32,
147
- pl110_draw_line16_555_lblp_rgb32,
148
- pl110_draw_line32_lblp_rgb32,
149
- pl110_draw_line16_lblp_rgb32,
150
- pl110_draw_line12_lblp_rgb32,
151
-
152
- pl110_draw_line1_bbbp_rgb32,
153
- pl110_draw_line2_bbbp_rgb32,
154
- pl110_draw_line4_bbbp_rgb32,
155
- pl110_draw_line8_bbbp_rgb32,
156
- pl110_draw_line16_555_bbbp_rgb32,
157
- pl110_draw_line32_bbbp_rgb32,
158
- pl110_draw_line16_bbbp_rgb32,
159
- pl110_draw_line12_bbbp_rgb32,
160
-
161
- pl110_draw_line1_lbbp_rgb32,
162
- pl110_draw_line2_lbbp_rgb32,
163
- pl110_draw_line4_lbbp_rgb32,
164
- pl110_draw_line8_lbbp_rgb32,
165
- pl110_draw_line16_555_lbbp_rgb32,
166
- pl110_draw_line32_lbbp_rgb32,
167
- pl110_draw_line16_lbbp_rgb32,
168
- pl110_draw_line12_lbbp_rgb32,
169
-};
170
-
171
-#undef BITS
172
#undef COPY_PIXEL
173
174
+static drawfn pl110_draw_fn_32[48] = {
175
+ pl110_draw_line1_lblp_bgr,
176
+ pl110_draw_line2_lblp_bgr,
177
+ pl110_draw_line4_lblp_bgr,
178
+ pl110_draw_line8_lblp_bgr,
179
+ pl110_draw_line16_555_lblp_bgr,
180
+ pl110_draw_line32_lblp_bgr,
181
+ pl110_draw_line16_lblp_bgr,
182
+ pl110_draw_line12_lblp_bgr,
183
+
184
+ pl110_draw_line1_bbbp_bgr,
185
+ pl110_draw_line2_bbbp_bgr,
186
+ pl110_draw_line4_bbbp_bgr,
187
+ pl110_draw_line8_bbbp_bgr,
188
+ pl110_draw_line16_555_bbbp_bgr,
189
+ pl110_draw_line32_bbbp_bgr,
190
+ pl110_draw_line16_bbbp_bgr,
191
+ pl110_draw_line12_bbbp_bgr,
192
+
193
+ pl110_draw_line1_lbbp_bgr,
194
+ pl110_draw_line2_lbbp_bgr,
195
+ pl110_draw_line4_lbbp_bgr,
196
+ pl110_draw_line8_lbbp_bgr,
197
+ pl110_draw_line16_555_lbbp_bgr,
198
+ pl110_draw_line32_lbbp_bgr,
199
+ pl110_draw_line16_lbbp_bgr,
200
+ pl110_draw_line12_lbbp_bgr,
201
+
202
+ pl110_draw_line1_lblp_rgb,
203
+ pl110_draw_line2_lblp_rgb,
204
+ pl110_draw_line4_lblp_rgb,
205
+ pl110_draw_line8_lblp_rgb,
206
+ pl110_draw_line16_555_lblp_rgb,
207
+ pl110_draw_line32_lblp_rgb,
208
+ pl110_draw_line16_lblp_rgb,
209
+ pl110_draw_line12_lblp_rgb,
210
+
211
+ pl110_draw_line1_bbbp_rgb,
212
+ pl110_draw_line2_bbbp_rgb,
213
+ pl110_draw_line4_bbbp_rgb,
214
+ pl110_draw_line8_bbbp_rgb,
215
+ pl110_draw_line16_555_bbbp_rgb,
216
+ pl110_draw_line32_bbbp_rgb,
217
+ pl110_draw_line16_bbbp_rgb,
218
+ pl110_draw_line12_bbbp_rgb,
219
+
220
+ pl110_draw_line1_lbbp_rgb,
221
+ pl110_draw_line2_lbbp_rgb,
222
+ pl110_draw_line4_lbbp_rgb,
223
+ pl110_draw_line8_lbbp_rgb,
224
+ pl110_draw_line16_555_lbbp_rgb,
225
+ pl110_draw_line32_lbbp_rgb,
226
+ pl110_draw_line16_lbbp_rgb,
227
+ pl110_draw_line12_lbbp_rgb,
228
+};
229
230
static int pl110_enabled(PL110State *s)
67
{
231
{
68
--
232
--
69
2.20.1
233
2.20.1
70
234
71
235
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
For a long time now the UI layer has guaranteed that the console
2
surface is always 32 bits per pixel. Remove the legacy dead code
3
from the pxa2xx_lcd display device which was handling the possibility
4
that the console surface was some other format.
2
5
3
hw/arm: versal: Add support for the RTC.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
8
Message-id: 20210211141515.8755-5-peter.maydell@linaro.org
9
---
10
hw/display/pxa2xx_lcd.c | 79 +++++++++--------------------------------
11
1 file changed, 17 insertions(+), 62 deletions(-)
4
12
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
14
2 files changed, 29 insertions(+)
15
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
15
--- a/hw/display/pxa2xx_lcd.c
19
+++ b/include/hw/arm/xlnx-versal.h
16
+++ b/hw/display/pxa2xx_lcd.c
20
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ struct PXA2xxLCDState {
21
#include "hw/char/pl011.h"
18
22
#include "hw/dma/xlnx-zdma.h"
19
int invalidated;
23
#include "hw/net/cadence_gem.h"
20
QemuConsole *con;
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
21
- drawfn *line_fn[2];
25
22
int dest_width;
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
23
int xres, yres;
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
24
int pal_for;
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
25
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
29
struct {
26
#define LDCMD_SOFINT    (1 << 22)
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
27
#define LDCMD_PAL    (1 << 26)
31
} iou;
28
29
+#define BITS 32
30
+#include "pxa2xx_template.h"
32
+
31
+
33
+ XlnxZynqMPRTC rtc;
32
/* Route internal interrupt lines to the global IC */
34
} pmc;
33
static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
35
34
{
36
struct {
35
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
38
#define VERSAL_GEM1_IRQ_0 58
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
40
#define VERSAL_ADMA_IRQ_0 60
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
42
#define VERSAL_SD0_IRQ_0 126
43
+#define VERSAL_RTC_ALARM_IRQ 142
44
+#define VERSAL_RTC_SECONDS_IRQ 143
45
46
/* Architecturally reserved IRQs suitable for virtualization. */
47
#define VERSAL_RSVD_IRQ_FIRST 111
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
49
#define MM_PMC_SD0_SIZE 0x10000
50
#define MM_PMC_CRP 0xf1260000U
51
#define MM_PMC_CRP_SIZE 0x10000
52
+#define MM_PMC_RTC 0xf12a0000
53
+#define MM_PMC_RTC_SIZE 0x10000
54
#endif
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/xlnx-versal.c
58
+++ b/hw/arm/xlnx-versal.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
60
}
36
}
61
}
37
}
62
38
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
39
+static inline drawfn pxa2xx_drawfn(PXA2xxLCDState *s)
64
+{
40
+{
65
+ SysBusDevice *sbd;
41
+ if (s->transp) {
66
+ MemoryRegion *mr;
42
+ return pxa2xx_draw_fn_32t[s->bpp];
67
+
43
+ } else {
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
44
+ return pxa2xx_draw_fn_32[s->bpp];
69
+ TYPE_XLNX_ZYNQMP_RTC);
45
+ }
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
71
+ qdev_init_nofail(DEVICE(sbd));
72
+
73
+ mr = sysbus_mmio_get_region(sbd, 0);
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
75
+
76
+ /*
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
78
+ * supports them.
79
+ */
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
81
+}
46
+}
82
+
47
+
83
/* This takes the board allocated linear DDR memory and creates aliases
48
static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
84
* for each split DDR range/aperture on the Versal address map.
49
hwaddr addr, int *miny, int *maxy)
85
*/
50
{
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
51
DisplaySurface *surface = qemu_console_surface(s->con);
87
versal_create_gems(s, pic);
52
int src_width, dest_width;
88
versal_create_admas(s, pic);
53
- drawfn fn = NULL;
89
versal_create_sds(s, pic);
54
- if (s->dest_width)
90
+ versal_create_rtc(s, pic);
55
- fn = s->line_fn[s->transp][s->bpp];
91
versal_map_ddr(s);
56
+ drawfn fn = pxa2xx_drawfn(s);
92
versal_unimp(s);
57
if (!fn)
58
return;
59
60
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
61
{
62
DisplaySurface *surface = qemu_console_surface(s->con);
63
int src_width, dest_width;
64
- drawfn fn = NULL;
65
- if (s->dest_width)
66
- fn = s->line_fn[s->transp][s->bpp];
67
+ drawfn fn = pxa2xx_drawfn(s);
68
if (!fn)
69
return;
70
71
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
72
{
73
DisplaySurface *surface = qemu_console_surface(s->con);
74
int src_width, dest_width;
75
- drawfn fn = NULL;
76
- if (s->dest_width) {
77
- fn = s->line_fn[s->transp][s->bpp];
78
- }
79
+ drawfn fn = pxa2xx_drawfn(s);
80
if (!fn) {
81
return;
82
}
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
84
{
85
DisplaySurface *surface = qemu_console_surface(s->con);
86
int src_width, dest_width;
87
- drawfn fn = NULL;
88
- if (s->dest_width) {
89
- fn = s->line_fn[s->transp][s->bpp];
90
- }
91
+ drawfn fn = pxa2xx_drawfn(s);
92
if (!fn) {
93
return;
94
}
95
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pxa2xx_lcdc = {
96
}
97
};
98
99
-#define BITS 8
100
-#include "pxa2xx_template.h"
101
-#define BITS 15
102
-#include "pxa2xx_template.h"
103
-#define BITS 16
104
-#include "pxa2xx_template.h"
105
-#define BITS 24
106
-#include "pxa2xx_template.h"
107
-#define BITS 32
108
-#include "pxa2xx_template.h"
109
-
110
static const GraphicHwOps pxa2xx_ops = {
111
.invalidate = pxa2xx_invalidate_display,
112
.gfx_update = pxa2xx_update_display,
113
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
114
hwaddr base, qemu_irq irq)
115
{
116
PXA2xxLCDState *s;
117
- DisplaySurface *surface;
118
119
s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState));
120
s->invalidated = 1;
121
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
122
memory_region_add_subregion(sysmem, base, &s->iomem);
123
124
s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
125
- surface = qemu_console_surface(s->con);
126
-
127
- switch (surface_bits_per_pixel(surface)) {
128
- case 0:
129
- s->dest_width = 0;
130
- break;
131
- case 8:
132
- s->line_fn[0] = pxa2xx_draw_fn_8;
133
- s->line_fn[1] = pxa2xx_draw_fn_8t;
134
- s->dest_width = 1;
135
- break;
136
- case 15:
137
- s->line_fn[0] = pxa2xx_draw_fn_15;
138
- s->line_fn[1] = pxa2xx_draw_fn_15t;
139
- s->dest_width = 2;
140
- break;
141
- case 16:
142
- s->line_fn[0] = pxa2xx_draw_fn_16;
143
- s->line_fn[1] = pxa2xx_draw_fn_16t;
144
- s->dest_width = 2;
145
- break;
146
- case 24:
147
- s->line_fn[0] = pxa2xx_draw_fn_24;
148
- s->line_fn[1] = pxa2xx_draw_fn_24t;
149
- s->dest_width = 3;
150
- break;
151
- case 32:
152
- s->line_fn[0] = pxa2xx_draw_fn_32;
153
- s->line_fn[1] = pxa2xx_draw_fn_32t;
154
- s->dest_width = 4;
155
- break;
156
- default:
157
- fprintf(stderr, "%s: Bad color depth\n", __func__);
158
- exit(1);
159
- }
160
+ s->dest_width = 4;
161
162
vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
93
163
94
--
164
--
95
2.20.1
165
2.20.1
96
166
97
167
diff view generated by jsdifflib
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
1
Since the dest_width is now always 4 because the output surface is
2
32bpp, we can replace the dest_width state field with a constant.
2
3
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
6
Message-id: 20210211141515.8755-6-peter.maydell@linaro.org
6
---
7
---
7
target/arm/neon-shared.decode | 5 +++++
8
hw/display/pxa2xx_lcd.c | 20 +++++++++++---------
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
9
1 file changed, 11 insertions(+), 9 deletions(-)
9
target/arm/translate.c | 26 +--------------------
10
3 files changed, 46 insertions(+), 25 deletions(-)
11
10
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
11
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
13
--- a/hw/display/pxa2xx_lcd.c
15
+++ b/target/arm/neon-shared.decode
14
+++ b/hw/display/pxa2xx_lcd.c
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
15
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
16
#define LDCMD_SOFINT    (1 << 22)
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
17
#define LDCMD_PAL    (1 << 26)
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
18
19
+/* Size of a pixel in the QEMU UI output surface, in bytes */
20
+#define DEST_PIXEL_WIDTH 4
20
+
21
+
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
22
#define BITS 32
22
+ vn=%vn_dp vd=%vd_dp size=0
23
#include "pxa2xx_template.h"
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
24
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
25
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
else if (s->bpp > pxa_lcdc_8bpp)
26
index XXXXXXX..XXXXXXX 100644
27
src_width *= 2;
27
--- a/target/arm/translate-neon.inc.c
28
28
+++ b/target/arm/translate-neon.inc.c
29
- dest_width = s->xres * s->dest_width;
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
30
+ dest_width = s->xres * DEST_PIXEL_WIDTH;
30
gen_helper_gvec_fmlal_a32);
31
*miny = 0;
31
return true;
32
if (s->invalidated) {
33
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
34
addr, s->yres, src_width);
35
}
36
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
37
- src_width, dest_width, s->dest_width,
38
+ src_width, dest_width, DEST_PIXEL_WIDTH,
39
s->invalidated,
40
fn, s->dma_ch[0].palette, miny, maxy);
32
}
41
}
33
+
42
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
43
else if (s->bpp > pxa_lcdc_8bpp)
35
+{
44
src_width *= 2;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
45
37
+ int opr_sz;
46
- dest_width = s->yres * s->dest_width;
38
+ TCGv_ptr fpst;
47
+ dest_width = s->yres * DEST_PIXEL_WIDTH;
39
+
48
*miny = 0;
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
49
if (s->invalidated) {
41
+ return false;
50
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
42
+ }
51
addr, s->yres, src_width);
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
52
}
44
+ return false;
53
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
45
+ }
54
- src_width, s->dest_width, -dest_width,
46
+
55
+ src_width, DEST_PIXEL_WIDTH, -dest_width,
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
56
s->invalidated,
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
57
fn, s->dma_ch[0].palette,
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
58
miny, maxy);
50
+ return false;
59
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
51
+ }
60
src_width *= 2;
52
+
61
}
53
+ if ((a->vd | a->vn) & a->q) {
62
54
+ return false;
63
- dest_width = s->xres * s->dest_width;
55
+ }
64
+ dest_width = s->xres * DEST_PIXEL_WIDTH;
56
+
65
*miny = 0;
57
+ if (!vfp_access_check(s)) {
66
if (s->invalidated) {
58
+ return true;
67
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
59
+ }
68
addr, s->yres, src_width);
60
+
69
}
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
70
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
62
+ : gen_helper_gvec_fcmlah_idx);
71
- src_width, -dest_width, -s->dest_width,
63
+ opr_sz = (1 + a->q) * 8;
72
+ src_width, -dest_width, -DEST_PIXEL_WIDTH,
64
+ fpst = get_fpstatus_ptr(1);
73
s->invalidated,
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
74
fn, s->dma_ch[0].palette, miny, maxy);
66
+ vfp_reg_offset(1, a->vn),
75
}
67
+ vfp_reg_offset(1, a->vm),
76
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
68
+ fpst, opr_sz, opr_sz,
77
src_width *= 2;
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
78
}
70
+ tcg_temp_free_ptr(fpst);
79
71
+ return true;
80
- dest_width = s->yres * s->dest_width;
72
+}
81
+ dest_width = s->yres * DEST_PIXEL_WIDTH;
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
82
*miny = 0;
74
index XXXXXXX..XXXXXXX 100644
83
if (s->invalidated) {
75
--- a/target/arm/translate.c
84
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
76
+++ b/target/arm/translate.c
85
addr, s->yres, src_width);
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
86
}
78
bool is_long = false, q = extract32(insn, 6, 1);
87
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
79
bool ptr_is_env = false;
88
- src_width, -s->dest_width, dest_width,
80
89
+ src_width, -DEST_PIXEL_WIDTH, dest_width,
81
- if ((insn & 0xff000f10) == 0xfe000800) {
90
s->invalidated,
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
91
fn, s->dma_ch[0].palette,
83
- int rot = extract32(insn, 20, 2);
92
miny, maxy);
84
- int size = extract32(insn, 23, 1);
93
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
85
- int index;
94
memory_region_add_subregion(sysmem, base, &s->iomem);
86
-
95
87
- if (!dc_isar_feature(aa32_vcma, s)) {
96
s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
88
- return 1;
97
- s->dest_width = 4;
89
- }
98
90
- if (size == 0) {
99
vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
92
- return 1;
93
- }
94
- /* For fp16, rm is just Vm, and index is M. */
95
- rm = extract32(insn, 0, 4);
96
- index = extract32(insn, 5, 1);
97
- } else {
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
99
- VFP_DREG_M(rm, insn);
100
- index = 0;
101
- }
102
- data = (index << 2) | rot;
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
104
- : gen_helper_gvec_fcmlah_idx);
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
108
int u = extract32(insn, 4, 1);
109
100
110
--
101
--
111
2.20.1
102
2.20.1
112
103
113
104
diff view generated by jsdifflib
1
Convert the Neon "load/store single structure to one lane" insns to
1
Now that BITS is always 32, expand out all its uses in the template
2
decodetree.
2
header, including removing now-useless uses of the glue() macro.
3
4
As this is the last set of insns in the neon load/store group,
5
we can remove the whole disas_neon_ls_insn() function.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
6
Message-id: 20210211141515.8755-7-peter.maydell@linaro.org
10
---
7
---
11
target/arm/neon-ls.decode | 11 +++
8
hw/display/pxa2xx_template.h | 110 ++++++++++++++---------------------
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
9
1 file changed, 45 insertions(+), 65 deletions(-)
13
target/arm/translate.c | 147 --------------------------------
14
3 files changed, 100 insertions(+), 147 deletions(-)
15
10
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
11
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
13
--- a/hw/display/pxa2xx_template.h
19
+++ b/target/arm/neon-ls.decode
14
+++ b/hw/display/pxa2xx_template.h
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
21
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
23
vd=%vd_dp
24
+
25
+# Neon load/store single structure to one lane
26
+%imm1_5_p1 5:1 !function=plus1
27
+%imm1_6_p1 6:1 !function=plus1
28
+
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
30
+ vd=%vd_dp size=0 stride=1
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@
40
* It might be possible to convert it to a standalone .c file eventually.
41
*/
16
*/
42
17
43
+static inline int plus1(DisasContext *s, int x)
18
# define SKIP_PIXEL(to)        to += deststep
44
+{
19
-#if BITS == 8
45
+ return x + 1;
20
-# define COPY_PIXEL(to, from) do { *to = from; SKIP_PIXEL(to); } while (0)
46
+}
21
-#elif BITS == 15 || BITS == 16
47
+
22
-# define COPY_PIXEL(to, from) \
48
/* Include the generated Neon decoder */
23
- do { \
49
#include "decode-neon-dp.inc.c"
24
- *(uint16_t *) to = from; \
50
#include "decode-neon-ls.inc.c"
25
- SKIP_PIXEL(to); \
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
26
- } while (0)
52
27
-#elif BITS == 24
53
return true;
28
-# define COPY_PIXEL(to, from) \
54
}
29
- do { \
55
+
30
- *(uint16_t *) to = from; \
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
31
- *(to + 2) = (from) >> 16; \
57
+{
32
- SKIP_PIXEL(to); \
58
+ /* Neon load/store single structure to one lane */
33
- } while (0)
59
+ int reg;
34
-#elif BITS == 32
60
+ int nregs = a->n + 1;
35
# define COPY_PIXEL(to, from) \
61
+ int vd = a->vd;
36
do { \
62
+ TCGv_i32 addr, tmp;
37
*(uint32_t *) to = from; \
63
+
38
SKIP_PIXEL(to); \
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
39
} while (0)
65
+ return false;
40
-#else
66
+ }
41
-# error unknown bit depth
67
+
42
-#endif
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
43
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
44
#ifdef HOST_WORDS_BIGENDIAN
70
+ return false;
45
# define SWAP_WORDS    1
71
+ }
46
@@ -XXX,XX +XXX,XX @@
72
+
47
#define FN_2(x)        FN(x + 1) FN(x)
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
48
#define FN_4(x)        FN_2(x + 2) FN_2(x)
74
+ switch (nregs) {
49
75
+ case 1:
50
-static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
76
+ if (((a->align & (1 << a->size)) != 0) ||
51
+static void pxa2xx_draw_line2(void *opaque,
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
52
uint8_t *dest, const uint8_t *src, int width, int deststep)
78
+ return false;
53
{
79
+ }
54
uint32_t *palette = opaque;
80
+ break;
55
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
81
+ case 3:
56
}
82
+ if ((a->align & 1) != 0) {
57
}
83
+ return false;
58
84
+ }
59
-static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
85
+ /* fall through */
60
+static void pxa2xx_draw_line4(void *opaque,
86
+ case 2:
61
uint8_t *dest, const uint8_t *src, int width, int deststep)
87
+ if (a->size == 2 && (a->align & 2) != 0) {
62
{
88
+ return false;
63
uint32_t *palette = opaque;
89
+ }
64
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
90
+ break;
65
}
91
+ case 4:
66
}
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
67
93
+ return false;
68
-static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
94
+ }
69
+static void pxa2xx_draw_line8(void *opaque,
95
+ break;
70
uint8_t *dest, const uint8_t *src, int width, int deststep)
96
+ default:
71
{
97
+ abort();
72
uint32_t *palette = opaque;
98
+ }
73
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
74
}
100
+ /*
75
}
101
+ * Attempts to write off the end of the register file are
76
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
77
-static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
103
+ * access off the end of the array that holds the register data.
78
+static void pxa2xx_draw_line16(void *opaque,
104
+ */
79
uint8_t *dest, const uint8_t *src, int width, int deststep)
105
+ return false;
80
{
106
+ }
81
uint32_t data;
107
+
82
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
108
+ if (!vfp_access_check(s)) {
83
data >>= 6;
109
+ return true;
84
r = (data & 0x1f) << 3;
110
+ }
85
data >>= 5;
111
+
86
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
112
+ tmp = tcg_temp_new_i32();
87
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
113
+ addr = tcg_temp_new_i32();
88
b = (data & 0x1f) << 3;
114
+ load_reg_var(s, addr, a->rn);
89
data >>= 5;
115
+ /*
90
g = (data & 0x3f) << 2;
116
+ * TODO: if we implemented alignment exceptions, we should check
91
data >>= 6;
117
+ * addr against the alignment encoded in a->align here.
92
r = (data & 0x1f) << 3;
118
+ */
93
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
119
+ for (reg = 0; reg < nregs; reg++) {
94
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
120
+ if (a->l) {
95
width -= 2;
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
96
src += 4;
122
+ s->be_data | a->size);
97
}
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
98
}
124
+ } else { /* Store */
99
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
100
-static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
101
+static void pxa2xx_draw_line16t(void *opaque,
127
+ s->be_data | a->size);
102
uint8_t *dest, const uint8_t *src, int width, int deststep)
128
+ }
103
{
129
+ vd += a->stride;
104
uint32_t data;
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
105
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
131
+ }
106
if (data & 1)
132
+ tcg_temp_free_i32(addr);
107
SKIP_PIXEL(dest);
133
+ tcg_temp_free_i32(tmp);
108
else
134
+
109
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
110
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
136
+
111
data >>= 1;
137
+ return true;
112
b = (data & 0x1f) << 3;
138
+}
113
data >>= 5;
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
114
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
140
index XXXXXXX..XXXXXXX 100644
115
if (data & 1)
141
--- a/target/arm/translate.c
116
SKIP_PIXEL(dest);
142
+++ b/target/arm/translate.c
117
else
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
118
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
144
tcg_temp_free_i32(rd);
119
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
145
}
120
width -= 2;
146
121
src += 4;
147
-
122
}
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
123
}
149
- instruction is invalid. */
124
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
125
-static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
151
-{
126
+static void pxa2xx_draw_line18(void *opaque,
152
- int rd, rn, rm;
127
uint8_t *dest, const uint8_t *src, int width, int deststep)
153
- int nregs;
128
{
154
- int stride;
129
uint32_t data;
155
- int size;
130
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
156
- int reg;
131
g = (data & 0x3f) << 2;
157
- int load;
132
data >>= 6;
158
- TCGv_i32 addr;
133
r = (data & 0x3f) << 2;
159
- TCGv_i32 tmp;
134
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
160
-
135
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
136
width -= 1;
162
- return 1;
137
src += 4;
163
- }
138
}
164
-
139
}
165
- /* FIXME: this access check should not take precedence over UNDEF
140
166
- * for invalid encodings; we will generate incorrect syndrome information
141
/* The wicked packed format */
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
142
-static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
168
- */
143
+static void pxa2xx_draw_line18p(void *opaque,
169
- if (s->fp_excp_el) {
144
uint8_t *dest, const uint8_t *src, int width, int deststep)
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
145
{
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
146
uint32_t data[3];
172
- return 0;
147
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
173
- }
148
data[0] >>= 6;
174
-
149
r = (data[0] & 0x3f) << 2;
175
- if (!s->vfp_enabled)
150
data[0] >>= 12;
176
- return 1;
151
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
177
- VFP_DREG_D(rd, insn);
152
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
178
- rn = (insn >> 16) & 0xf;
153
b = (data[0] & 0x3f) << 2;
179
- rm = insn & 0xf;
154
data[0] >>= 6;
180
- load = (insn & (1 << 21)) != 0;
155
g = ((data[1] & 0xf) << 4) | (data[0] << 2);
181
- if ((insn & (1 << 23)) == 0) {
156
data[1] >>= 4;
182
- /* Load store all elements -- handled already by decodetree */
157
r = (data[1] & 0x3f) << 2;
183
- return 1;
158
data[1] >>= 12;
184
- } else {
159
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
185
- size = (insn >> 10) & 3;
160
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
186
- if (size == 3) {
161
b = (data[1] & 0x3f) << 2;
187
- /* Load single element to all lanes -- handled by decodetree */
162
data[1] >>= 6;
188
- return 1;
163
g = (data[1] & 0x3f) << 2;
189
- } else {
164
data[1] >>= 6;
190
- /* Single element. */
165
r = ((data[2] & 0x3) << 6) | (data[1] << 2);
191
- int idx = (insn >> 4) & 0xf;
166
data[2] >>= 8;
192
- int reg_idx;
167
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
193
- switch (size) {
168
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
194
- case 0:
169
b = (data[2] & 0x3f) << 2;
195
- reg_idx = (insn >> 5) & 7;
170
data[2] >>= 6;
196
- stride = 1;
171
g = (data[2] & 0x3f) << 2;
197
- break;
172
data[2] >>= 6;
198
- case 1:
173
r = data[2] << 2;
199
- reg_idx = (insn >> 6) & 3;
174
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
200
- stride = (insn & (1 << 5)) ? 2 : 1;
175
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
201
- break;
176
width -= 4;
202
- case 2:
177
}
203
- reg_idx = (insn >> 7) & 1;
178
}
204
- stride = (insn & (1 << 6)) ? 2 : 1;
179
205
- break;
180
-static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
206
- default:
181
+static void pxa2xx_draw_line19(void *opaque,
207
- abort();
182
uint8_t *dest, const uint8_t *src, int width, int deststep)
208
- }
183
{
209
- nregs = ((insn >> 8) & 3) + 1;
184
uint32_t data;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
185
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
211
- switch (nregs) {
186
if (data & 1)
212
- case 1:
187
SKIP_PIXEL(dest);
213
- if (((idx & (1 << size)) != 0) ||
188
else
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
189
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
215
- return 1;
190
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
216
- }
191
width -= 1;
217
- break;
192
src += 4;
218
- case 3:
193
}
219
- if ((idx & 1) != 0) {
194
}
220
- return 1;
195
221
- }
196
/* The wicked packed format */
222
- /* fall through */
197
-static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
223
- case 2:
198
+static void pxa2xx_draw_line19p(void *opaque,
224
- if (size == 2 && (idx & 2) != 0) {
199
uint8_t *dest, const uint8_t *src, int width, int deststep)
225
- return 1;
200
{
226
- }
201
uint32_t data[3];
227
- break;
202
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
228
- case 4:
203
if (data[0] & 1)
229
- if ((size == 2) && ((idx & 3) == 3)) {
204
SKIP_PIXEL(dest);
230
- return 1;
205
else
231
- }
206
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
232
- break;
207
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
233
- default:
208
data[0] >>= 6;
234
- abort();
209
b = (data[0] & 0x3f) << 2;
235
- }
210
data[0] >>= 6;
236
- if ((rd + stride * (nregs - 1)) > 31) {
211
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
237
- /* Attempts to write off the end of the register file
212
if (data[1] & 1)
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
213
SKIP_PIXEL(dest);
239
- * the neon_load_reg() would write off the end of the array.
214
else
240
- */
215
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
241
- return 1;
216
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
242
- }
217
data[1] >>= 6;
243
- tmp = tcg_temp_new_i32();
218
b = (data[1] & 0x3f) << 2;
244
- addr = tcg_temp_new_i32();
219
data[1] >>= 6;
245
- load_reg_var(s, addr, rn);
220
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
246
- for (reg = 0; reg < nregs; reg++) {
221
if (data[2] & 1)
247
- if (load) {
222
SKIP_PIXEL(dest);
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
223
else
249
- s->be_data | size);
224
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
250
- neon_store_element(rd, reg_idx, size, tmp);
225
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
251
- } else { /* Store */
226
data[2] >>= 6;
252
- neon_load_element(tmp, rd, reg_idx, size);
227
b = (data[2] & 0x3f) << 2;
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
228
data[2] >>= 6;
254
- s->be_data | size);
229
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
255
- }
230
if (data[2] & 1)
256
- rd += stride;
231
SKIP_PIXEL(dest);
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
232
else
258
- }
233
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
259
- tcg_temp_free_i32(addr);
234
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
260
- tcg_temp_free_i32(tmp);
235
width -= 4;
261
- stride = nregs * (1 << size);
236
}
262
- }
237
}
263
- }
238
264
- if (rm != 15) {
239
-static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
265
- TCGv_i32 base;
240
+static void pxa2xx_draw_line24(void *opaque,
266
-
241
uint8_t *dest, const uint8_t *src, int width, int deststep)
267
- base = load_reg(s, rn);
242
{
268
- if (rm == 13) {
243
uint32_t data;
269
- tcg_gen_addi_i32(base, base, stride);
244
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
270
- } else {
245
g = data & 0xff;
271
- TCGv_i32 index;
246
data >>= 8;
272
- index = load_reg(s, rm);
247
r = data & 0xff;
273
- tcg_gen_add_i32(base, base, index);
248
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
274
- tcg_temp_free_i32(index);
249
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
275
- }
250
width -= 1;
276
- store_reg(s, rn, base);
251
src += 4;
277
- }
252
}
278
- return 0;
253
}
279
-}
254
280
-
255
-static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
256
+static void pxa2xx_draw_line24t(void *opaque,
282
{
257
uint8_t *dest, const uint8_t *src, int width, int deststep)
283
switch (size) {
258
{
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
259
uint32_t data;
285
}
260
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
286
return;
261
if (data & 1)
287
}
262
SKIP_PIXEL(dest);
288
- if ((insn & 0x0f100000) == 0x04000000) {
263
else
289
- /* NEON load/store. */
264
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
290
- if (disas_neon_ls_insn(s, insn)) {
265
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
291
- goto illegal_op;
266
width -= 1;
292
- }
267
src += 4;
293
- return;
268
}
294
- }
269
}
295
if ((insn & 0x0e000f00) == 0x0c000100) {
270
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
271
-static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
297
/* iWMMXt register transfer. */
272
+static void pxa2xx_draw_line25(void *opaque,
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
273
uint8_t *dest, const uint8_t *src, int width, int deststep)
299
}
274
{
300
break;
275
uint32_t data;
301
case 12:
276
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
302
- if ((insn & 0x01100000) == 0x01000000) {
277
if (data & 1)
303
- if (disas_neon_ls_insn(s, insn)) {
278
SKIP_PIXEL(dest);
304
- goto illegal_op;
279
else
305
- }
280
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
306
- break;
281
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
307
- }
282
width -= 1;
308
goto illegal_op;
283
src += 4;
309
default:
284
}
310
illegal_op:
285
}
286
287
/* Overlay planes disabled, no transparency */
288
-static drawfn glue(pxa2xx_draw_fn_, BITS)[16] =
289
+static drawfn pxa2xx_draw_fn_32[16] =
290
{
291
[0 ... 0xf] = NULL,
292
- [pxa_lcdc_2bpp] = glue(pxa2xx_draw_line2_, BITS),
293
- [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
294
- [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
295
- [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16_, BITS),
296
- [pxa_lcdc_18bpp] = glue(pxa2xx_draw_line18_, BITS),
297
- [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS),
298
- [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24_, BITS),
299
+ [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
300
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
301
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
302
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
303
+ [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
304
+ [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
305
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
306
};
307
308
/* Overlay planes enabled, transparency used */
309
-static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] =
310
+static drawfn pxa2xx_draw_fn_32t[16] =
311
{
312
[0 ... 0xf] = NULL,
313
- [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
314
- [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
315
- [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16t_, BITS),
316
- [pxa_lcdc_19bpp] = glue(pxa2xx_draw_line19_, BITS),
317
- [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS),
318
- [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24t_, BITS),
319
- [pxa_lcdc_25bpp] = glue(pxa2xx_draw_line25_, BITS),
320
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
321
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
322
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
323
+ [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
324
+ [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
325
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
326
+ [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
327
};
328
329
-#undef BITS
330
#undef COPY_PIXEL
331
#undef SKIP_PIXEL
332
311
--
333
--
312
2.20.1
334
2.20.1
313
335
314
336
diff view generated by jsdifflib
1
Somewhere along theline we accidentally added a duplicate
1
We're about to move code from the template header into pxa2xx_lcd.c.
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
2
Before doing that, make coding style fixes so checkpatch doesn't
3
(probably an artifact of a patchseries rebase). Remove it.
3
complain about the patch which moves the code. This commit fixes
4
missing braces in the SKIP_PIXEL() macro definition and in if()
5
statements.
4
6
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210211141515.8755-8-peter.maydell@linaro.org
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
9
---
10
---
10
target/arm/translate-vfp.inc.c | 6 ------
11
hw/display/pxa2xx_template.h | 47 +++++++++++++++++++++---------------
11
1 file changed, 6 deletions(-)
12
1 file changed, 28 insertions(+), 19 deletions(-)
12
13
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
14
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.inc.c
16
--- a/hw/display/pxa2xx_template.h
16
+++ b/target/arm/translate-vfp.inc.c
17
+++ b/hw/display/pxa2xx_template.h
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
18
@@ -XXX,XX +XXX,XX @@
18
return false;
19
* Framebuffer format conversion routines.
20
*/
21
22
-# define SKIP_PIXEL(to)        to += deststep
23
+# define SKIP_PIXEL(to) do { to += deststep; } while (0)
24
# define COPY_PIXEL(to, from) \
25
do { \
26
*(uint32_t *) to = from; \
27
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16t(void *opaque,
28
data >>= 5;
29
r = (data & 0x1f) << 3;
30
data >>= 5;
31
- if (data & 1)
32
+ if (data & 1) {
33
SKIP_PIXEL(dest);
34
- else
35
+ } else {
36
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
37
+ }
38
data >>= 1;
39
b = (data & 0x1f) << 3;
40
data >>= 5;
41
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16t(void *opaque,
42
data >>= 5;
43
r = (data & 0x1f) << 3;
44
data >>= 5;
45
- if (data & 1)
46
+ if (data & 1) {
47
SKIP_PIXEL(dest);
48
- else
49
+ } else {
50
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
51
+ }
52
width -= 2;
53
src += 4;
19
}
54
}
20
55
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19(void *opaque,
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
56
data >>= 6;
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
57
r = (data & 0x3f) << 2;
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
58
data >>= 6;
24
- return false;
59
- if (data & 1)
25
- }
60
+ if (data & 1) {
26
-
61
SKIP_PIXEL(dest);
27
if (!vfp_access_check(s)) {
62
- else
28
return true;
63
+ } else {
64
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
65
+ }
66
width -= 1;
67
src += 4;
68
}
69
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
70
data[0] >>= 6;
71
r = (data[0] & 0x3f) << 2;
72
data[0] >>= 6;
73
- if (data[0] & 1)
74
+ if (data[0] & 1) {
75
SKIP_PIXEL(dest);
76
- else
77
+ } else {
78
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
79
+ }
80
data[0] >>= 6;
81
b = (data[0] & 0x3f) << 2;
82
data[0] >>= 6;
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
84
data[1] >>= 4;
85
r = (data[1] & 0x3f) << 2;
86
data[1] >>= 6;
87
- if (data[1] & 1)
88
+ if (data[1] & 1) {
89
SKIP_PIXEL(dest);
90
- else
91
+ } else {
92
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
93
+ }
94
data[1] >>= 6;
95
b = (data[1] & 0x3f) << 2;
96
data[1] >>= 6;
97
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
98
data[1] >>= 6;
99
r = ((data[2] & 0x3) << 6) | (data[1] << 2);
100
data[2] >>= 2;
101
- if (data[2] & 1)
102
+ if (data[2] & 1) {
103
SKIP_PIXEL(dest);
104
- else
105
+ } else {
106
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
107
+ }
108
data[2] >>= 6;
109
b = (data[2] & 0x3f) << 2;
110
data[2] >>= 6;
111
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
112
data[2] >>= 6;
113
r = data[2] << 2;
114
data[2] >>= 6;
115
- if (data[2] & 1)
116
+ if (data[2] & 1) {
117
SKIP_PIXEL(dest);
118
- else
119
+ } else {
120
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
121
+ }
122
width -= 4;
123
}
124
}
125
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line24t(void *opaque,
126
data >>= 8;
127
r = data & 0xff;
128
data >>= 8;
129
- if (data & 1)
130
+ if (data & 1) {
131
SKIP_PIXEL(dest);
132
- else
133
+ } else {
134
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
135
+ }
136
width -= 1;
137
src += 4;
138
}
139
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line25(void *opaque,
140
data >>= 8;
141
r = data & 0xff;
142
data >>= 8;
143
- if (data & 1)
144
+ if (data & 1) {
145
SKIP_PIXEL(dest);
146
- else
147
+ } else {
148
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
149
+ }
150
width -= 1;
151
src += 4;
29
}
152
}
30
--
153
--
31
2.20.1
154
2.20.1
32
155
33
156
diff view generated by jsdifflib
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
1
We're about to move code from the template header into pxa2xx_lcd.c.
2
TLB. However we never actually use the TLB -- all stage 2 lookups
2
Before doing that, make coding style fixes so checkpatch doesn't
3
are done by direct calls to get_phys_addr_lpae() followed by a
3
complain about the patch which moves the code. This commit is
4
physical address load via address_space_ld*().
4
whitespace changes only:
5
5
* avoid hard-coded tabs
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
6
* fix ident on function prototypes
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
7
* no newline before open brace on array definitions
8
MMU indexes.
9
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
12
permission bits to the stage 2 descriptors which define execute
13
permission separatel for EL0 and EL1; supporting that while keeping
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
16
lot of extra complication given we aren't even using the QEMU TLB.
17
18
In the process of updating the comment on our MMU index use,
19
fix a couple of other minor errors:
20
* NS EL2 EL2&0 was missing from the list in the comment
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
22
above 8
23
8
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210211141515.8755-9-peter.maydell@linaro.org
27
Message-id: 20200330210400.11724-2-peter.maydell@linaro.org
28
---
12
---
29
target/arm/cpu-param.h | 2 +-
13
hw/display/pxa2xx_template.h | 66 +++++++++++++++++-------------------
30
target/arm/cpu.h | 21 +++++---
14
1 file changed, 32 insertions(+), 34 deletions(-)
31
target/arm/helper.c | 112 ++++-------------------------------------
15
32
3 files changed, 27 insertions(+), 108 deletions(-)
16
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
33
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
35
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
18
--- a/hw/display/pxa2xx_template.h
37
+++ b/target/arm/cpu-param.h
19
+++ b/hw/display/pxa2xx_template.h
38
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
39
# define TARGET_PAGE_BITS_MIN 10
21
} while (0)
22
23
#ifdef HOST_WORDS_BIGENDIAN
24
-# define SWAP_WORDS    1
25
+# define SWAP_WORDS 1
40
#endif
26
#endif
41
27
42
-#define NB_MMU_MODES 12
28
-#define FN_2(x)        FN(x + 1) FN(x)
43
+#define NB_MMU_MODES 11
29
-#define FN_4(x)        FN_2(x + 2) FN_2(x)
44
30
+#define FN_2(x) FN(x + 1) FN(x)
45
#endif
31
+#define FN_4(x) FN_2(x + 2) FN_2(x)
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
47
index XXXXXXX..XXXXXXX 100644
33
-static void pxa2xx_draw_line2(void *opaque,
48
--- a/target/arm/cpu.h
34
- uint8_t *dest, const uint8_t *src, int width, int deststep)
49
+++ b/target/arm/cpu.h
35
+static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
36
+ int width, int deststep)
51
* handling via the TLB. The only way to do a stage 1 translation without
37
{
52
* the immediate stage 2 translation is via the ATS or AT system insns,
38
uint32_t *palette = opaque;
53
* which can be slow-pathed and always do a page table walk.
39
uint32_t data;
54
+ * The only use of stage 2 translations is either as part of an s1+2
40
while (width > 0) {
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
41
data = *(uint32_t *) src;
56
+ * and in both those cases we don't use the TLB.
42
-#define FN(x)        COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
43
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
58
* translation regimes, because they map reasonably well to each other
44
#ifdef SWAP_WORDS
59
* and they can't both be active at the same time.
45
FN_4(12)
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
46
FN_4(8)
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
47
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line2(void *opaque,
62
* NS EL1 EL1&0 stage 1+2 +PAN
48
}
63
* NS EL0 EL2&0
49
}
64
+ * NS EL2 EL2&0
50
65
* NS EL2 EL2&0 +PAN
51
-static void pxa2xx_draw_line4(void *opaque,
66
* NS EL2 (aka NS PL2)
52
- uint8_t *dest, const uint8_t *src, int width, int deststep)
67
* S EL0 EL1&0 (aka S PL0)
53
+static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
54
+ int width, int deststep)
69
* S EL1 EL1&0 +PAN
55
{
70
* S EL3 (aka S PL1)
56
uint32_t *palette = opaque;
71
- * NS EL1&0 stage 2
57
uint32_t data;
72
*
58
while (width > 0) {
73
- * for a total of 12 different mmu_idx.
59
data = *(uint32_t *) src;
74
+ * for a total of 11 different mmu_idx.
60
-#define FN(x)        COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
75
*
61
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
62
#ifdef SWAP_WORDS
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
63
FN_2(6)
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
64
FN_2(4)
79
* are not quite the same -- different CPU types (most notably M profile
65
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line4(void *opaque,
80
* vs A/R profile) would like to use MMU indexes with different semantics,
66
}
81
* but since we don't ever need to use all of those in a single CPU we
67
}
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
68
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
69
-static void pxa2xx_draw_line8(void *opaque,
84
+ * modes + total number of M profile MMU modes". The lower bits of
70
- uint8_t *dest, const uint8_t *src, int width, int deststep)
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
71
+static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
86
* the same for any particular CPU.
72
+ int width, int deststep)
87
* Variables of type ARMMUIdx are always full values, and the core
73
{
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
74
uint32_t *palette = opaque;
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
75
uint32_t data;
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
76
while (width > 0) {
91
77
data = *(uint32_t *) src;
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
78
-#define FN(x)        COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
93
-
79
+#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
94
/*
80
#ifdef SWAP_WORDS
95
* These are not allocated TLBs and are used only for AT system
81
FN(24)
96
* instructions or for the first stage of an S12 page table walk.
82
FN(16)
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line8(void *opaque,
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
84
}
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
85
}
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
86
101
+ /*
87
-static void pxa2xx_draw_line16(void *opaque,
102
+ * Not allocated a TLB: used only for second stage of an S12 page
88
- uint8_t *dest, const uint8_t *src, int width, int deststep)
103
+ * table walk, or for descriptor loads during first stage of an S1
89
+static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
104
+ * page table walk. Note that if we ever want to have a TLB for this
90
+ int width, int deststep)
105
+ * then various TLB flush insns which currently are no-ops or flush
91
{
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
92
uint32_t data;
107
+ */
93
unsigned int r, g, b;
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
94
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16(void *opaque,
109
95
}
110
/*
96
}
111
* M-profile.
97
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
98
-static void pxa2xx_draw_line16t(void *opaque,
113
TO_CORE_BIT(SE10_1),
99
- uint8_t *dest, const uint8_t *src, int width, int deststep)
114
TO_CORE_BIT(SE10_1_PAN),
100
+static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
115
TO_CORE_BIT(SE3),
101
+ int width, int deststep)
116
- TO_CORE_BIT(Stage2),
102
{
117
103
uint32_t data;
118
TO_CORE_BIT(MUser),
104
unsigned int r, g, b;
119
TO_CORE_BIT(MPriv),
105
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16t(void *opaque,
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
106
}
121
index XXXXXXX..XXXXXXX 100644
107
}
122
--- a/target/arm/helper.c
108
123
+++ b/target/arm/helper.c
109
-static void pxa2xx_draw_line18(void *opaque,
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
110
- uint8_t *dest, const uint8_t *src, int width, int deststep)
125
tlb_flush_by_mmuidx(cs,
111
+static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
126
ARMMMUIdxBit_E10_1 |
112
+ int width, int deststep)
127
ARMMMUIdxBit_E10_1_PAN |
113
{
128
- ARMMMUIdxBit_E10_0 |
114
uint32_t data;
129
- ARMMMUIdxBit_Stage2);
115
unsigned int r, g, b;
130
+ ARMMMUIdxBit_E10_0);
116
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line18(void *opaque,
131
}
117
}
132
118
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
119
/* The wicked packed format */
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
120
-static void pxa2xx_draw_line18p(void *opaque,
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
121
- uint8_t *dest, const uint8_t *src, int width, int deststep)
136
ARMMMUIdxBit_E10_1 |
122
+static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
137
ARMMMUIdxBit_E10_1_PAN |
123
+ int width, int deststep)
138
- ARMMMUIdxBit_E10_0 |
124
{
139
- ARMMMUIdxBit_Stage2);
125
uint32_t data[3];
140
+ ARMMMUIdxBit_E10_0);
126
unsigned int r, g, b;
141
}
127
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line18p(void *opaque,
142
128
}
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
129
}
144
- uint64_t value)
130
131
-static void pxa2xx_draw_line19(void *opaque,
132
- uint8_t *dest, const uint8_t *src, int width, int deststep)
133
+static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
134
+ int width, int deststep)
135
{
136
uint32_t data;
137
unsigned int r, g, b;
138
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19(void *opaque,
139
}
140
141
/* The wicked packed format */
142
-static void pxa2xx_draw_line19p(void *opaque,
143
- uint8_t *dest, const uint8_t *src, int width, int deststep)
144
+static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
145
+ int width, int deststep)
146
{
147
uint32_t data[3];
148
unsigned int r, g, b;
149
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
150
}
151
}
152
153
-static void pxa2xx_draw_line24(void *opaque,
154
- uint8_t *dest, const uint8_t *src, int width, int deststep)
155
+static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
156
+ int width, int deststep)
157
{
158
uint32_t data;
159
unsigned int r, g, b;
160
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line24(void *opaque,
161
}
162
}
163
164
-static void pxa2xx_draw_line24t(void *opaque,
165
- uint8_t *dest, const uint8_t *src, int width, int deststep)
166
+static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
167
+ int width, int deststep)
168
{
169
uint32_t data;
170
unsigned int r, g, b;
171
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line24t(void *opaque,
172
}
173
}
174
175
-static void pxa2xx_draw_line25(void *opaque,
176
- uint8_t *dest, const uint8_t *src, int width, int deststep)
177
+static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
178
+ int width, int deststep)
179
{
180
uint32_t data;
181
unsigned int r, g, b;
182
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line25(void *opaque,
183
}
184
185
/* Overlay planes disabled, no transparency */
186
-static drawfn pxa2xx_draw_fn_32[16] =
145
-{
187
-{
146
- /* Invalidate by IPA. This has to invalidate any structures that
188
+static drawfn pxa2xx_draw_fn_32[16] = {
147
- * contain only stage 2 translation information, but does not need
189
[0 ... 0xf] = NULL,
148
- * to apply to structures that contain combined stage 1 and stage 2
190
[pxa_lcdc_2bpp] = pxa2xx_draw_line2,
149
- * translation information.
191
[pxa_lcdc_4bpp] = pxa2xx_draw_line4,
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
192
@@ -XXX,XX +XXX,XX @@ static drawfn pxa2xx_draw_fn_32[16] =
151
- */
193
};
152
- CPUState *cs = env_cpu(env);
194
153
- uint64_t pageaddr;
195
/* Overlay planes enabled, transparency used */
154
-
196
-static drawfn pxa2xx_draw_fn_32t[16] =
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
156
- return;
157
- }
158
-
159
- pageaddr = sextract64(value << 12, 0, 40);
160
-
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
162
-}
163
-
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
165
- uint64_t value)
166
-{
197
-{
167
- CPUState *cs = env_cpu(env);
198
+static drawfn pxa2xx_draw_fn_32t[16] = {
168
- uint64_t pageaddr;
199
[0 ... 0xf] = NULL,
169
-
200
[pxa_lcdc_4bpp] = pxa2xx_draw_line4,
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
201
[pxa_lcdc_8bpp] = pxa2xx_draw_line8,
171
- return;
172
- }
173
-
174
- pageaddr = sextract64(value << 12, 0, 40);
175
-
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
177
- ARMMMUIdxBit_Stage2);
178
-}
179
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
191
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
193
return ARMMMUIdxBit_SE10_1 |
194
ARMMMUIdxBit_SE10_1_PAN |
195
ARMMMUIdxBit_SE10_0;
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
197
- return ARMMMUIdxBit_E10_1 |
198
- ARMMMUIdxBit_E10_1_PAN |
199
- ARMMMUIdxBit_E10_0 |
200
- ARMMMUIdxBit_Stage2;
201
} else {
202
return ARMMMUIdxBit_E10_1 |
203
ARMMMUIdxBit_E10_1_PAN |
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
ARMMMUIdxBit_SE3);
206
}
207
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
210
-{
211
- /* Invalidate by IPA. This has to invalidate any structures that
212
- * contain only stage 2 translation information, but does not need
213
- * to apply to structures that contain combined stage 1 and stage 2
214
- * translation information.
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
216
- */
217
- ARMCPU *cpu = env_archcpu(env);
218
- CPUState *cs = CPU(cpu);
219
- uint64_t pageaddr;
220
-
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
222
- return;
223
- }
224
-
225
- pageaddr = sextract64(value << 12, 0, 48);
226
-
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
228
-}
229
-
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
- uint64_t value)
232
-{
233
- CPUState *cs = env_cpu(env);
234
- uint64_t pageaddr;
235
-
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
237
- return;
238
- }
239
-
240
- pageaddr = sextract64(value << 12, 0, 48);
241
-
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
243
- ARMMMUIdxBit_Stage2);
244
-}
245
-
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
247
bool isread)
248
{
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
250
.writefn = tlbi_aa64_vae1_write },
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
254
- .writefn = tlbi_aa64_ipas2e1is_write },
255
+ .access = PL2_W, .type = ARM_CP_NOP },
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
259
- .writefn = tlbi_aa64_ipas2e1is_write },
260
+ .access = PL2_W, .type = ARM_CP_NOP },
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
265
.writefn = tlbi_aa64_alle1is_write },
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
269
- .writefn = tlbi_aa64_ipas2e1_write },
270
+ .access = PL2_W, .type = ARM_CP_NOP },
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
274
- .writefn = tlbi_aa64_ipas2e1_write },
275
+ .access = PL2_W, .type = ARM_CP_NOP },
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
280
.writefn = tlbimva_hyp_is_write },
281
{ .name = "TLBIIPAS2",
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
284
- .writefn = tlbiipas2_write },
285
+ .type = ARM_CP_NOP, .access = PL2_W },
286
{ .name = "TLBIIPAS2IS",
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
289
- .writefn = tlbiipas2_is_write },
290
+ .type = ARM_CP_NOP, .access = PL2_W },
291
{ .name = "TLBIIPAS2L",
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
294
- .writefn = tlbiipas2_write },
295
+ .type = ARM_CP_NOP, .access = PL2_W },
296
{ .name = "TLBIIPAS2LIS",
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
299
- .writefn = tlbiipas2_is_write },
300
+ .type = ARM_CP_NOP, .access = PL2_W },
301
/* 32 bit cache operations */
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
304
--
202
--
305
2.20.1
203
2.20.1
306
204
307
205
diff view generated by jsdifflib
1
Convert the VCMLA (vector) insns in the 3same extension group to
1
The template header is now included only once; just inline its contents
2
decodetree.
2
in hw/display/pxa2xx_lcd.c.
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
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
6
Message-id: 20210211141515.8755-10-peter.maydell@linaro.org
7
---
7
---
8
target/arm/neon-shared.decode | 11 ++++++++++
8
hw/display/pxa2xx_template.h | 434 -----------------------------------
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
9
hw/display/pxa2xx_lcd.c | 427 +++++++++++++++++++++++++++++++++-
10
target/arm/translate.c | 11 +---------
10
2 files changed, 425 insertions(+), 436 deletions(-)
11
3 files changed, 49 insertions(+), 10 deletions(-)
11
delete mode 100644 hw/display/pxa2xx_template.h
12
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
14
deleted file mode 100644
15
index XXXXXXX..XXXXXXX
16
--- a/hw/display/pxa2xx_template.h
17
+++ /dev/null
18
@@ -XXX,XX +XXX,XX @@
19
-/*
20
- * Intel XScale PXA255/270 LCDC emulation.
21
- *
22
- * Copyright (c) 2006 Openedhand Ltd.
23
- * Written by Andrzej Zaborowski <balrog@zabor.org>
24
- *
25
- * This code is licensed under the GPLv2.
26
- *
27
- * Framebuffer format conversion routines.
28
- */
29
-
30
-# define SKIP_PIXEL(to) do { to += deststep; } while (0)
31
-# define COPY_PIXEL(to, from) \
32
- do { \
33
- *(uint32_t *) to = from; \
34
- SKIP_PIXEL(to); \
35
- } while (0)
36
-
37
-#ifdef HOST_WORDS_BIGENDIAN
38
-# define SWAP_WORDS 1
39
-#endif
40
-
41
-#define FN_2(x) FN(x + 1) FN(x)
42
-#define FN_4(x) FN_2(x + 2) FN_2(x)
43
-
44
-static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
45
- int width, int deststep)
46
-{
47
- uint32_t *palette = opaque;
48
- uint32_t data;
49
- while (width > 0) {
50
- data = *(uint32_t *) src;
51
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
52
-#ifdef SWAP_WORDS
53
- FN_4(12)
54
- FN_4(8)
55
- FN_4(4)
56
- FN_4(0)
57
-#else
58
- FN_4(0)
59
- FN_4(4)
60
- FN_4(8)
61
- FN_4(12)
62
-#endif
63
-#undef FN
64
- width -= 16;
65
- src += 4;
66
- }
67
-}
68
-
69
-static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
70
- int width, int deststep)
71
-{
72
- uint32_t *palette = opaque;
73
- uint32_t data;
74
- while (width > 0) {
75
- data = *(uint32_t *) src;
76
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
77
-#ifdef SWAP_WORDS
78
- FN_2(6)
79
- FN_2(4)
80
- FN_2(2)
81
- FN_2(0)
82
-#else
83
- FN_2(0)
84
- FN_2(2)
85
- FN_2(4)
86
- FN_2(6)
87
-#endif
88
-#undef FN
89
- width -= 8;
90
- src += 4;
91
- }
92
-}
93
-
94
-static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
95
- int width, int deststep)
96
-{
97
- uint32_t *palette = opaque;
98
- uint32_t data;
99
- while (width > 0) {
100
- data = *(uint32_t *) src;
101
-#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
102
-#ifdef SWAP_WORDS
103
- FN(24)
104
- FN(16)
105
- FN(8)
106
- FN(0)
107
-#else
108
- FN(0)
109
- FN(8)
110
- FN(16)
111
- FN(24)
112
-#endif
113
-#undef FN
114
- width -= 4;
115
- src += 4;
116
- }
117
-}
118
-
119
-static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
120
- int width, int deststep)
121
-{
122
- uint32_t data;
123
- unsigned int r, g, b;
124
- while (width > 0) {
125
- data = *(uint32_t *) src;
126
-#ifdef SWAP_WORDS
127
- data = bswap32(data);
128
-#endif
129
- b = (data & 0x1f) << 3;
130
- data >>= 5;
131
- g = (data & 0x3f) << 2;
132
- data >>= 6;
133
- r = (data & 0x1f) << 3;
134
- data >>= 5;
135
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
136
- b = (data & 0x1f) << 3;
137
- data >>= 5;
138
- g = (data & 0x3f) << 2;
139
- data >>= 6;
140
- r = (data & 0x1f) << 3;
141
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
142
- width -= 2;
143
- src += 4;
144
- }
145
-}
146
-
147
-static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
148
- int width, int deststep)
149
-{
150
- uint32_t data;
151
- unsigned int r, g, b;
152
- while (width > 0) {
153
- data = *(uint32_t *) src;
154
-#ifdef SWAP_WORDS
155
- data = bswap32(data);
156
-#endif
157
- b = (data & 0x1f) << 3;
158
- data >>= 5;
159
- g = (data & 0x1f) << 3;
160
- data >>= 5;
161
- r = (data & 0x1f) << 3;
162
- data >>= 5;
163
- if (data & 1) {
164
- SKIP_PIXEL(dest);
165
- } else {
166
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
167
- }
168
- data >>= 1;
169
- b = (data & 0x1f) << 3;
170
- data >>= 5;
171
- g = (data & 0x1f) << 3;
172
- data >>= 5;
173
- r = (data & 0x1f) << 3;
174
- data >>= 5;
175
- if (data & 1) {
176
- SKIP_PIXEL(dest);
177
- } else {
178
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
179
- }
180
- width -= 2;
181
- src += 4;
182
- }
183
-}
184
-
185
-static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
186
- int width, int deststep)
187
-{
188
- uint32_t data;
189
- unsigned int r, g, b;
190
- while (width > 0) {
191
- data = *(uint32_t *) src;
192
-#ifdef SWAP_WORDS
193
- data = bswap32(data);
194
-#endif
195
- b = (data & 0x3f) << 2;
196
- data >>= 6;
197
- g = (data & 0x3f) << 2;
198
- data >>= 6;
199
- r = (data & 0x3f) << 2;
200
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
201
- width -= 1;
202
- src += 4;
203
- }
204
-}
205
-
206
-/* The wicked packed format */
207
-static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
208
- int width, int deststep)
209
-{
210
- uint32_t data[3];
211
- unsigned int r, g, b;
212
- while (width > 0) {
213
- data[0] = *(uint32_t *) src;
214
- src += 4;
215
- data[1] = *(uint32_t *) src;
216
- src += 4;
217
- data[2] = *(uint32_t *) src;
218
- src += 4;
219
-#ifdef SWAP_WORDS
220
- data[0] = bswap32(data[0]);
221
- data[1] = bswap32(data[1]);
222
- data[2] = bswap32(data[2]);
223
-#endif
224
- b = (data[0] & 0x3f) << 2;
225
- data[0] >>= 6;
226
- g = (data[0] & 0x3f) << 2;
227
- data[0] >>= 6;
228
- r = (data[0] & 0x3f) << 2;
229
- data[0] >>= 12;
230
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
231
- b = (data[0] & 0x3f) << 2;
232
- data[0] >>= 6;
233
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
234
- data[1] >>= 4;
235
- r = (data[1] & 0x3f) << 2;
236
- data[1] >>= 12;
237
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
238
- b = (data[1] & 0x3f) << 2;
239
- data[1] >>= 6;
240
- g = (data[1] & 0x3f) << 2;
241
- data[1] >>= 6;
242
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
243
- data[2] >>= 8;
244
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
245
- b = (data[2] & 0x3f) << 2;
246
- data[2] >>= 6;
247
- g = (data[2] & 0x3f) << 2;
248
- data[2] >>= 6;
249
- r = data[2] << 2;
250
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
251
- width -= 4;
252
- }
253
-}
254
-
255
-static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
256
- int width, int deststep)
257
-{
258
- uint32_t data;
259
- unsigned int r, g, b;
260
- while (width > 0) {
261
- data = *(uint32_t *) src;
262
-#ifdef SWAP_WORDS
263
- data = bswap32(data);
264
-#endif
265
- b = (data & 0x3f) << 2;
266
- data >>= 6;
267
- g = (data & 0x3f) << 2;
268
- data >>= 6;
269
- r = (data & 0x3f) << 2;
270
- data >>= 6;
271
- if (data & 1) {
272
- SKIP_PIXEL(dest);
273
- } else {
274
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
275
- }
276
- width -= 1;
277
- src += 4;
278
- }
279
-}
280
-
281
-/* The wicked packed format */
282
-static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
283
- int width, int deststep)
284
-{
285
- uint32_t data[3];
286
- unsigned int r, g, b;
287
- while (width > 0) {
288
- data[0] = *(uint32_t *) src;
289
- src += 4;
290
- data[1] = *(uint32_t *) src;
291
- src += 4;
292
- data[2] = *(uint32_t *) src;
293
- src += 4;
294
-# ifdef SWAP_WORDS
295
- data[0] = bswap32(data[0]);
296
- data[1] = bswap32(data[1]);
297
- data[2] = bswap32(data[2]);
298
-# endif
299
- b = (data[0] & 0x3f) << 2;
300
- data[0] >>= 6;
301
- g = (data[0] & 0x3f) << 2;
302
- data[0] >>= 6;
303
- r = (data[0] & 0x3f) << 2;
304
- data[0] >>= 6;
305
- if (data[0] & 1) {
306
- SKIP_PIXEL(dest);
307
- } else {
308
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
309
- }
310
- data[0] >>= 6;
311
- b = (data[0] & 0x3f) << 2;
312
- data[0] >>= 6;
313
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
314
- data[1] >>= 4;
315
- r = (data[1] & 0x3f) << 2;
316
- data[1] >>= 6;
317
- if (data[1] & 1) {
318
- SKIP_PIXEL(dest);
319
- } else {
320
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
321
- }
322
- data[1] >>= 6;
323
- b = (data[1] & 0x3f) << 2;
324
- data[1] >>= 6;
325
- g = (data[1] & 0x3f) << 2;
326
- data[1] >>= 6;
327
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
328
- data[2] >>= 2;
329
- if (data[2] & 1) {
330
- SKIP_PIXEL(dest);
331
- } else {
332
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
333
- }
334
- data[2] >>= 6;
335
- b = (data[2] & 0x3f) << 2;
336
- data[2] >>= 6;
337
- g = (data[2] & 0x3f) << 2;
338
- data[2] >>= 6;
339
- r = data[2] << 2;
340
- data[2] >>= 6;
341
- if (data[2] & 1) {
342
- SKIP_PIXEL(dest);
343
- } else {
344
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
345
- }
346
- width -= 4;
347
- }
348
-}
349
-
350
-static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
351
- int width, int deststep)
352
-{
353
- uint32_t data;
354
- unsigned int r, g, b;
355
- while (width > 0) {
356
- data = *(uint32_t *) src;
357
-#ifdef SWAP_WORDS
358
- data = bswap32(data);
359
-#endif
360
- b = data & 0xff;
361
- data >>= 8;
362
- g = data & 0xff;
363
- data >>= 8;
364
- r = data & 0xff;
365
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
366
- width -= 1;
367
- src += 4;
368
- }
369
-}
370
-
371
-static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
372
- int width, int deststep)
373
-{
374
- uint32_t data;
375
- unsigned int r, g, b;
376
- while (width > 0) {
377
- data = *(uint32_t *) src;
378
-#ifdef SWAP_WORDS
379
- data = bswap32(data);
380
-#endif
381
- b = (data & 0x7f) << 1;
382
- data >>= 7;
383
- g = data & 0xff;
384
- data >>= 8;
385
- r = data & 0xff;
386
- data >>= 8;
387
- if (data & 1) {
388
- SKIP_PIXEL(dest);
389
- } else {
390
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
391
- }
392
- width -= 1;
393
- src += 4;
394
- }
395
-}
396
-
397
-static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
398
- int width, int deststep)
399
-{
400
- uint32_t data;
401
- unsigned int r, g, b;
402
- while (width > 0) {
403
- data = *(uint32_t *) src;
404
-#ifdef SWAP_WORDS
405
- data = bswap32(data);
406
-#endif
407
- b = data & 0xff;
408
- data >>= 8;
409
- g = data & 0xff;
410
- data >>= 8;
411
- r = data & 0xff;
412
- data >>= 8;
413
- if (data & 1) {
414
- SKIP_PIXEL(dest);
415
- } else {
416
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
417
- }
418
- width -= 1;
419
- src += 4;
420
- }
421
-}
422
-
423
-/* Overlay planes disabled, no transparency */
424
-static drawfn pxa2xx_draw_fn_32[16] = {
425
- [0 ... 0xf] = NULL,
426
- [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
427
- [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
428
- [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
429
- [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
430
- [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
431
- [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
432
- [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
433
-};
434
-
435
-/* Overlay planes enabled, transparency used */
436
-static drawfn pxa2xx_draw_fn_32t[16] = {
437
- [0 ... 0xf] = NULL,
438
- [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
439
- [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
440
- [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
441
- [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
442
- [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
443
- [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
444
- [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
445
-};
446
-
447
-#undef COPY_PIXEL
448
-#undef SKIP_PIXEL
449
-
450
-#ifdef SWAP_WORDS
451
-# undef SWAP_WORDS
452
-#endif
453
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
14
index XXXXXXX..XXXXXXX 100644
454
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
455
--- a/hw/display/pxa2xx_lcd.c
16
+++ b/target/arm/neon-shared.decode
456
+++ b/hw/display/pxa2xx_lcd.c
17
@@ -XXX,XX +XXX,XX @@
457
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
18
# More specifically, this covers:
458
/* Size of a pixel in the QEMU UI output surface, in bytes */
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
459
#define DEST_PIXEL_WIDTH 4
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
460
21
+
461
-#define BITS 32
22
+# VFP/Neon register fields; same as vfp.decode
462
-#include "pxa2xx_template.h"
23
+%vm_dp 5:1 0:4
463
+/* Line drawing code to handle the various possible guest pixel formats */
24
+%vm_sp 0:4 5:1
464
+
25
+%vn_dp 7:1 16:4
465
+# define SKIP_PIXEL(to) do { to += deststep; } while (0)
26
+%vn_sp 16:4 7:1
466
+# define COPY_PIXEL(to, from) \
27
+%vd_dp 22:1 12:4
467
+ do { \
28
+%vd_sp 12:4 22:1
468
+ *(uint32_t *) to = from; \
29
+
469
+ SKIP_PIXEL(to); \
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
470
+ } while (0)
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
471
+
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
472
+#ifdef HOST_WORDS_BIGENDIAN
33
index XXXXXXX..XXXXXXX 100644
473
+# define SWAP_WORDS 1
34
--- a/target/arm/translate-neon.inc.c
474
+#endif
35
+++ b/target/arm/translate-neon.inc.c
475
+
36
@@ -XXX,XX +XXX,XX @@
476
+#define FN_2(x) FN(x + 1) FN(x)
37
#include "decode-neon-dp.inc.c"
477
+#define FN_4(x) FN_2(x + 2) FN_2(x)
38
#include "decode-neon-ls.inc.c"
478
+
39
#include "decode-neon-shared.inc.c"
479
+static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
40
+
480
+ int width, int deststep)
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
481
+{
42
+{
482
+ uint32_t *palette = opaque;
43
+ int opr_sz;
483
+ uint32_t data;
44
+ TCGv_ptr fpst;
484
+ while (width > 0) {
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
485
+ data = *(uint32_t *) src;
46
+
486
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
47
+ if (!dc_isar_feature(aa32_vcma, s)
487
+#ifdef SWAP_WORDS
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
488
+ FN_4(12)
49
+ return false;
489
+ FN_4(8)
50
+ }
490
+ FN_4(4)
51
+
491
+ FN_4(0)
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
492
+#else
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
493
+ FN_4(0)
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
494
+ FN_4(4)
55
+ return false;
495
+ FN_4(8)
56
+ }
496
+ FN_4(12)
57
+
497
+#endif
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
498
+#undef FN
59
+ return false;
499
+ width -= 16;
60
+ }
500
+ src += 4;
61
+
501
+ }
62
+ if (!vfp_access_check(s)) {
502
+}
63
+ return true;
503
+
64
+ }
504
+static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
65
+
505
+ int width, int deststep)
66
+ opr_sz = (1 + a->q) * 8;
506
+{
67
+ fpst = get_fpstatus_ptr(1);
507
+ uint32_t *palette = opaque;
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
508
+ uint32_t data;
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
509
+ while (width > 0) {
70
+ vfp_reg_offset(1, a->vn),
510
+ data = *(uint32_t *) src;
71
+ vfp_reg_offset(1, a->vm),
511
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
72
+ fpst, opr_sz, opr_sz, a->rot,
512
+#ifdef SWAP_WORDS
73
+ fn_gvec_ptr);
513
+ FN_2(6)
74
+ tcg_temp_free_ptr(fpst);
514
+ FN_2(4)
75
+ return true;
515
+ FN_2(2)
76
+}
516
+ FN_2(0)
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
517
+#else
78
index XXXXXXX..XXXXXXX 100644
518
+ FN_2(0)
79
--- a/target/arm/translate.c
519
+ FN_2(2)
80
+++ b/target/arm/translate.c
520
+ FN_2(4)
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
521
+ FN_2(6)
82
bool is_long = false, q = extract32(insn, 6, 1);
522
+#endif
83
bool ptr_is_env = false;
523
+#undef FN
84
524
+ width -= 8;
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
525
+ src += 4;
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
526
+ }
87
- int size = extract32(insn, 20, 1);
527
+}
88
- data = extract32(insn, 23, 2); /* rot */
528
+
89
- if (!dc_isar_feature(aa32_vcma, s)
529
+static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
530
+ int width, int deststep)
91
- return 1;
531
+{
92
- }
532
+ uint32_t *palette = opaque;
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
533
+ uint32_t data;
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
534
+ while (width > 0) {
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
535
+ data = *(uint32_t *) src;
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
536
+#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
97
int size = extract32(insn, 20, 1);
537
+#ifdef SWAP_WORDS
98
data = extract32(insn, 24, 1); /* rot */
538
+ FN(24)
539
+ FN(16)
540
+ FN(8)
541
+ FN(0)
542
+#else
543
+ FN(0)
544
+ FN(8)
545
+ FN(16)
546
+ FN(24)
547
+#endif
548
+#undef FN
549
+ width -= 4;
550
+ src += 4;
551
+ }
552
+}
553
+
554
+static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
555
+ int width, int deststep)
556
+{
557
+ uint32_t data;
558
+ unsigned int r, g, b;
559
+ while (width > 0) {
560
+ data = *(uint32_t *) src;
561
+#ifdef SWAP_WORDS
562
+ data = bswap32(data);
563
+#endif
564
+ b = (data & 0x1f) << 3;
565
+ data >>= 5;
566
+ g = (data & 0x3f) << 2;
567
+ data >>= 6;
568
+ r = (data & 0x1f) << 3;
569
+ data >>= 5;
570
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
571
+ b = (data & 0x1f) << 3;
572
+ data >>= 5;
573
+ g = (data & 0x3f) << 2;
574
+ data >>= 6;
575
+ r = (data & 0x1f) << 3;
576
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
577
+ width -= 2;
578
+ src += 4;
579
+ }
580
+}
581
+
582
+static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
583
+ int width, int deststep)
584
+{
585
+ uint32_t data;
586
+ unsigned int r, g, b;
587
+ while (width > 0) {
588
+ data = *(uint32_t *) src;
589
+#ifdef SWAP_WORDS
590
+ data = bswap32(data);
591
+#endif
592
+ b = (data & 0x1f) << 3;
593
+ data >>= 5;
594
+ g = (data & 0x1f) << 3;
595
+ data >>= 5;
596
+ r = (data & 0x1f) << 3;
597
+ data >>= 5;
598
+ if (data & 1) {
599
+ SKIP_PIXEL(dest);
600
+ } else {
601
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
602
+ }
603
+ data >>= 1;
604
+ b = (data & 0x1f) << 3;
605
+ data >>= 5;
606
+ g = (data & 0x1f) << 3;
607
+ data >>= 5;
608
+ r = (data & 0x1f) << 3;
609
+ data >>= 5;
610
+ if (data & 1) {
611
+ SKIP_PIXEL(dest);
612
+ } else {
613
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
614
+ }
615
+ width -= 2;
616
+ src += 4;
617
+ }
618
+}
619
+
620
+static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
621
+ int width, int deststep)
622
+{
623
+ uint32_t data;
624
+ unsigned int r, g, b;
625
+ while (width > 0) {
626
+ data = *(uint32_t *) src;
627
+#ifdef SWAP_WORDS
628
+ data = bswap32(data);
629
+#endif
630
+ b = (data & 0x3f) << 2;
631
+ data >>= 6;
632
+ g = (data & 0x3f) << 2;
633
+ data >>= 6;
634
+ r = (data & 0x3f) << 2;
635
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
636
+ width -= 1;
637
+ src += 4;
638
+ }
639
+}
640
+
641
+/* The wicked packed format */
642
+static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
643
+ int width, int deststep)
644
+{
645
+ uint32_t data[3];
646
+ unsigned int r, g, b;
647
+ while (width > 0) {
648
+ data[0] = *(uint32_t *) src;
649
+ src += 4;
650
+ data[1] = *(uint32_t *) src;
651
+ src += 4;
652
+ data[2] = *(uint32_t *) src;
653
+ src += 4;
654
+#ifdef SWAP_WORDS
655
+ data[0] = bswap32(data[0]);
656
+ data[1] = bswap32(data[1]);
657
+ data[2] = bswap32(data[2]);
658
+#endif
659
+ b = (data[0] & 0x3f) << 2;
660
+ data[0] >>= 6;
661
+ g = (data[0] & 0x3f) << 2;
662
+ data[0] >>= 6;
663
+ r = (data[0] & 0x3f) << 2;
664
+ data[0] >>= 12;
665
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
666
+ b = (data[0] & 0x3f) << 2;
667
+ data[0] >>= 6;
668
+ g = ((data[1] & 0xf) << 4) | (data[0] << 2);
669
+ data[1] >>= 4;
670
+ r = (data[1] & 0x3f) << 2;
671
+ data[1] >>= 12;
672
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
673
+ b = (data[1] & 0x3f) << 2;
674
+ data[1] >>= 6;
675
+ g = (data[1] & 0x3f) << 2;
676
+ data[1] >>= 6;
677
+ r = ((data[2] & 0x3) << 6) | (data[1] << 2);
678
+ data[2] >>= 8;
679
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
680
+ b = (data[2] & 0x3f) << 2;
681
+ data[2] >>= 6;
682
+ g = (data[2] & 0x3f) << 2;
683
+ data[2] >>= 6;
684
+ r = data[2] << 2;
685
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
686
+ width -= 4;
687
+ }
688
+}
689
+
690
+static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
691
+ int width, int deststep)
692
+{
693
+ uint32_t data;
694
+ unsigned int r, g, b;
695
+ while (width > 0) {
696
+ data = *(uint32_t *) src;
697
+#ifdef SWAP_WORDS
698
+ data = bswap32(data);
699
+#endif
700
+ b = (data & 0x3f) << 2;
701
+ data >>= 6;
702
+ g = (data & 0x3f) << 2;
703
+ data >>= 6;
704
+ r = (data & 0x3f) << 2;
705
+ data >>= 6;
706
+ if (data & 1) {
707
+ SKIP_PIXEL(dest);
708
+ } else {
709
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
710
+ }
711
+ width -= 1;
712
+ src += 4;
713
+ }
714
+}
715
+
716
+/* The wicked packed format */
717
+static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
718
+ int width, int deststep)
719
+{
720
+ uint32_t data[3];
721
+ unsigned int r, g, b;
722
+ while (width > 0) {
723
+ data[0] = *(uint32_t *) src;
724
+ src += 4;
725
+ data[1] = *(uint32_t *) src;
726
+ src += 4;
727
+ data[2] = *(uint32_t *) src;
728
+ src += 4;
729
+# ifdef SWAP_WORDS
730
+ data[0] = bswap32(data[0]);
731
+ data[1] = bswap32(data[1]);
732
+ data[2] = bswap32(data[2]);
733
+# endif
734
+ b = (data[0] & 0x3f) << 2;
735
+ data[0] >>= 6;
736
+ g = (data[0] & 0x3f) << 2;
737
+ data[0] >>= 6;
738
+ r = (data[0] & 0x3f) << 2;
739
+ data[0] >>= 6;
740
+ if (data[0] & 1) {
741
+ SKIP_PIXEL(dest);
742
+ } else {
743
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
744
+ }
745
+ data[0] >>= 6;
746
+ b = (data[0] & 0x3f) << 2;
747
+ data[0] >>= 6;
748
+ g = ((data[1] & 0xf) << 4) | (data[0] << 2);
749
+ data[1] >>= 4;
750
+ r = (data[1] & 0x3f) << 2;
751
+ data[1] >>= 6;
752
+ if (data[1] & 1) {
753
+ SKIP_PIXEL(dest);
754
+ } else {
755
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
756
+ }
757
+ data[1] >>= 6;
758
+ b = (data[1] & 0x3f) << 2;
759
+ data[1] >>= 6;
760
+ g = (data[1] & 0x3f) << 2;
761
+ data[1] >>= 6;
762
+ r = ((data[2] & 0x3) << 6) | (data[1] << 2);
763
+ data[2] >>= 2;
764
+ if (data[2] & 1) {
765
+ SKIP_PIXEL(dest);
766
+ } else {
767
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
768
+ }
769
+ data[2] >>= 6;
770
+ b = (data[2] & 0x3f) << 2;
771
+ data[2] >>= 6;
772
+ g = (data[2] & 0x3f) << 2;
773
+ data[2] >>= 6;
774
+ r = data[2] << 2;
775
+ data[2] >>= 6;
776
+ if (data[2] & 1) {
777
+ SKIP_PIXEL(dest);
778
+ } else {
779
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
780
+ }
781
+ width -= 4;
782
+ }
783
+}
784
+
785
+static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
786
+ int width, int deststep)
787
+{
788
+ uint32_t data;
789
+ unsigned int r, g, b;
790
+ while (width > 0) {
791
+ data = *(uint32_t *) src;
792
+#ifdef SWAP_WORDS
793
+ data = bswap32(data);
794
+#endif
795
+ b = data & 0xff;
796
+ data >>= 8;
797
+ g = data & 0xff;
798
+ data >>= 8;
799
+ r = data & 0xff;
800
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
801
+ width -= 1;
802
+ src += 4;
803
+ }
804
+}
805
+
806
+static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
807
+ int width, int deststep)
808
+{
809
+ uint32_t data;
810
+ unsigned int r, g, b;
811
+ while (width > 0) {
812
+ data = *(uint32_t *) src;
813
+#ifdef SWAP_WORDS
814
+ data = bswap32(data);
815
+#endif
816
+ b = (data & 0x7f) << 1;
817
+ data >>= 7;
818
+ g = data & 0xff;
819
+ data >>= 8;
820
+ r = data & 0xff;
821
+ data >>= 8;
822
+ if (data & 1) {
823
+ SKIP_PIXEL(dest);
824
+ } else {
825
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
826
+ }
827
+ width -= 1;
828
+ src += 4;
829
+ }
830
+}
831
+
832
+static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
833
+ int width, int deststep)
834
+{
835
+ uint32_t data;
836
+ unsigned int r, g, b;
837
+ while (width > 0) {
838
+ data = *(uint32_t *) src;
839
+#ifdef SWAP_WORDS
840
+ data = bswap32(data);
841
+#endif
842
+ b = data & 0xff;
843
+ data >>= 8;
844
+ g = data & 0xff;
845
+ data >>= 8;
846
+ r = data & 0xff;
847
+ data >>= 8;
848
+ if (data & 1) {
849
+ SKIP_PIXEL(dest);
850
+ } else {
851
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
852
+ }
853
+ width -= 1;
854
+ src += 4;
855
+ }
856
+}
857
+
858
+/* Overlay planes disabled, no transparency */
859
+static drawfn pxa2xx_draw_fn_32[16] = {
860
+ [0 ... 0xf] = NULL,
861
+ [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
862
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
863
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
864
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
865
+ [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
866
+ [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
867
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
868
+};
869
+
870
+/* Overlay planes enabled, transparency used */
871
+static drawfn pxa2xx_draw_fn_32t[16] = {
872
+ [0 ... 0xf] = NULL,
873
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
874
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
875
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
876
+ [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
877
+ [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
878
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
879
+ [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
880
+};
881
+
882
+#undef COPY_PIXEL
883
+#undef SKIP_PIXEL
884
+
885
+#ifdef SWAP_WORDS
886
+# undef SWAP_WORDS
887
+#endif
888
889
/* Route internal interrupt lines to the global IC */
890
static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
99
--
891
--
100
2.20.1
892
2.20.1
101
893
102
894
diff view generated by jsdifflib